Files
firestorm/Gameleap/code/mw4/Code/MW4/hudchat.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

1177 lines
33 KiB
C++

#include "MW4Headers.hpp"
//상훈 앞
#include "MWMission.hpp"
#include "VehicleInterface.hpp"
#include "Vehicle.hpp"
#include "Narc.hpp"
#include "MWGUIManager.hpp"
#include "MWGame.hpp"
#include "gameinfo.hpp"
#include "AI_Statistics.hpp"
#include "AI_UserConstants.hpp"
#include "GameTypes.h"
#include "MWObject.hpp"
#include "MWPlayer.hpp"
#include <Adept\Mission.hpp>
#include <Adept\Map.hpp>
#include "navpoint.hpp"
#include "ai_groups.hpp"
#include "ai.hpp"
#include "lancemate.hpp"
#include "mech.hpp"
#include "mechlabheaders.h"
#include "bucket.hpp"
//상훈 뒤
#include "hudcomp.hpp"
#include "HUDChat.hpp"
#include "hudcomm.hpp"
#include "HUDscore.hpp"
#include "mwguimanager.hpp"
#include "mwapplication.hpp"
#include "..\missionlang\resource.h"
//상훈짱 begin
#include <windows.h>
#include <ddraw.h>
#include <d3d.h>
#include <GameOS\render.hpp>
#include "ctcls.h"
#include "ctcl.h"
extern Scalar g_fLastStartTime;
extern Adept::ReplicatorID g_LastTarget;
//상훈짱 end
extern "C" char* _stdcall CharPrevA(const char* lpszStart, const char* lpszCurrent);
#define CharPrev CharPrevA
using namespace MechWarrior4;
const int MAX_CHAT_LINES = 10;
HUDChat::HUDChat()
{
Location (Point3D (0,0,0.9f));
Color (0,125,0,250);
m_CurrentChat = NULL;
curChatDisplay = new HUDText (false);
curChatDisplay->Color (255,255,255,255);
curChatDisplay->Justification (HUDText::LEFT_ALIGN);
curChatDisplay->Wrap (true);
curChatDisplay->SetSize (HUDText::SMALL_SIZE);
m_CursorTime = 0;
m_CursorBlink = true;
m_CursorPos = NULL;
m_TeamChat = false;
m_LargeSize = false;
m_ChatLen = NULL;
}
HUDChat::~HUDChat()
{
delete curChatDisplay;
KillData ();
}
void HUDChat::KillData (void)
{
stlport::list<ChatData>::iterator iter;
for (iter = m_Messages.begin ();iter != m_Messages.end ();iter++)
delete iter->text;
m_Messages.clear ();
m_CurrentChat = NULL;
}
void HUDChat::AddChat (const char *mesg,BYTE from, BYTE type, BYTE player_sent_to)
{
HUDText *text;
char srctext[MAX_HUD_TEXT];
MWApplication *app;
app = MWApplication::GetInstance ();
srctext[0] = 0;
Connection *connection = Network::GetInstance()->GetConnection(from);
if (connection)
{
if (type == MWApplication::DeadBroadcast)
Str_Copy (srctext,app->GetLocString (IDS_DEADCHAT),MAX_HUD_TEXT);
else if (type == MWApplication::TeamAliveBroadcast)
Str_Copy (srctext,app->GetLocString (IDS_TEAMCHAT),MAX_HUD_TEXT);
else if (type == MWApplication::TeamDeadBroadcast)
{
Str_Copy (srctext,app->GetLocString (IDS_DEADCHAT),MAX_HUD_TEXT);
Str_Cat (srctext,app->GetLocString (IDS_TEAMCHAT),MAX_HUD_TEXT);
}
else if (type == MWApplication::ObserverBroadcast)
Str_Copy (srctext,app->GetLocString (IDS_OBSERVERCHAT),MAX_HUD_TEXT);
Str_Cat(srctext, connection->GetConnectionName(), MAX_HUD_TEXT);
}
text = new HUDText ();
switch (type)
{
case MWApplication::SystemBroadcast:
text->Color (230,230,50,250);
srctext[0] = 0;
// Str_Copy (srctext,app->GetLocString (IDS_SYSTEMMESSAGEHEADER),MAX_HUD_TEXT);
break;
case MWApplication::AliveBroadcast:
text->Color (0,191,0,250);
break;
case MWApplication::ObserverBroadcast:
case MWApplication::DeadBroadcast:
text->Color (122,153,122,250);
break;
case MWApplication::TeamAliveBroadcast:
text->Color (0,243,0,250);
break;
case MWApplication::TeamDeadBroadcast:
text->Color (122,205,122,250);
break;
case MWApplication::PrivateBroadcast:
text->Color (191,48,48,250);
break;
#if defined(LAB_ONLY)
case MWApplication::LobbyBroadcast:
case MWApplication::LobbyTeamBroadcast:
PAUSE (("Lobby chat got into the hud chat system"));
break;
#endif
}
char buffer[MAX_HUD_TEXT];
text->Justification (HUDText::LEFT_ALIGN);
text->Wrap (true);
text->SetSize (HUDText::SMALL_SIZE);
if (srctext[0] != 0)
{
sprintf (buffer,"%s: %s",srctext,mesg);
text->UpdateText (buffer,false);
}
else
text->UpdateText (mesg,false);
m_Messages.insert (m_Messages.begin (),ChatData (text,from,type,player_sent_to));
}
void HUDChat::Reset (void)
{
// KillData ();
comm = Cast_Object (HUDComm *, MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_COMM));
//mr_device의 맵 데이타를 로드한다.
if(hsh_mrdev_initialized){
extern char AssetsDirectory1[MAX_PATH];
const Map__GameModel *model = Map::GetInstance ()->GetGameModel ();
char temp[256];
sprintf(temp, "%s\\hsh\\%s-1.bmp", AssetsDirectory1,model->m_HudMap);
DrawBitmapToSurface(mr_device.pDDSMapTexture,0,0,temp);
mr_device.map_loaded=true;
}
}
void HUDChat::Update (Stuff::Time till)
{
if (m_CursorTime == 0)
m_CursorTime = till;
while (m_CursorTime <= till)
{
m_CursorBlink = !m_CursorBlink;
m_CursorTime += 1.0/6.0;
}
inherited::Update (till);
}
extern "C" unsigned int __stdcall GetACP(void); // defined in winnls.h
static const DWORD SH_DamageColor[6]={0xFFFFFFFF,0xFFCCCCCC,0xFF999999,0xFF666666,0xFF333333,0xFF000000};
static const DWORD SH_DamageColor2[6]={0xFF64E164,0xFFE1E100,0xFFFF9600,0xFFFF3200,0xFF7f1900,0xFF000000};
static const float sm1_texture[][4]=
{
{217+85, 74,(217+39)+85,( 74+97)},//left leg
{171+85, 74,(171+39)+85,( 74+97)},//right leg
{229+85,195,(229+25)+85,(195+61)},//left arm
{171+85, 9,(171+25)+85,( 9+61)},//right arm
{194+85, 2,(194+19)+85,( 2+51)},//right torso
{209+85,187,(209+19)+85,(187+51)},//left torso
{187+85,193,(187+21)+85,(193+61)},//center torso
{0,0,0,0}, //blank rear?
{187+85,171,(187+21)+85,(171+21)},//head
{0,0,0,0}, //special1
{0,0,0,0} //special2
};
static const float sm1_offset[][2]={
{29*2,35*2}, //leftleg
{ 6*2,35*2}, //rightleg
{43*2,11*2}, //leftarm
{ 0*2,11*2}, //rightarm
{12*2, 7*2}, //righttorso
{33*2, 7*2}, //lefttorso
{22*2,10*2}, //centertorso
{ 0*2, 0*2}, //blank rear?
{22*2, 0*2}, //head
{ 0*2, 0*2}, //special1
{ 0*2, 0*2}, //special2
};
//number: 0,1,2,3 lancemate의 순서..
//part: 해당 lancemate mech의 part
//color:해당 part의 color
void RenderAux1SmallMech(int num,int part,int color)
{
//각각의 offset에 따라서 그린다.
if(sm1_texture[part][2]!=0){
mfd_device.DrawTexture(
sm1_offset[part][0]+190+num*160,
sm1_offset[part][1]+50,
color,
sm1_texture[part][0],
sm1_texture[part][1],
sm1_texture[part][2],
sm1_texture[part][3]
);
}
}
//80,240,400,560
static RECT aux1freeframes[]={
{ 80-25, 75, 80+25, 75+25},
{ 80-25,130, 80+25,130+25},
{240-25, 75,240+25, 75+25},
{240-25,130,240+25,130+25},
{400-25, 75,400+25, 75+25},
{400-25,130,400+25,130+25},
{560-25, 75,560+25, 75+25},
{560-25,130,560+25,130+25},
{ 80-25,345, 80+25,345+25},
{ 80-25,400, 80+25,400+25},
{240-25,345,240+25,345+25},
{240-25,400,240+25,400+25},
{400-25,345,400+25,345+25},
{400-25,400,400+25,400+25},
{560-25,345,560+25,345+25},
{560-25,400,560+25,400+25},
};
static POINT aux1free_textcoord[]={
{ 80, 75},
{ 80,130},
{240, 75},
{240,130},
{400, 75},
{400,130},
{560, 75},
{560,130},
{ 80,345},
{ 80,400},
{240,345},
{240,400},
{400,345},
{400,400},
{560,345},
{560,400},
};
// MSL 5.02 Comm MFD
static POINT aux1free_textcoord2[]={
{ 80, 20},
{240, 20},
{400, 20},
{560, 20},
{ 80,460},
{240,460},
{400,460},
{560,460},
};
static char mfd_text_comm1[8][32]={
"TEAM ALL","","","",
"ALL","ALL OTHERS","AFFIRMATIVE","NEGATIVE"
};
// MSL 5.02 Comm MFD
static char mfd_text_comm3[8][32]={
"","","","",
"","","","ALL",
};
enum {TEAMORDER_NONE, TEAM_MODE, FREEFORALL_MODE, TEAM_MESSAGE1, TEAM_MESSAGE2};
extern int g_nTeamOrderMode;
extern int g_TeamOrderCount;
extern int g_TeamOrderOthers;
extern SMechInfo g_aMechInfos[16];
static float coords[][4]={
{ 29, 43, 49, 91},
{ 6, 43, 26, 92},
{ 43, 11, 56, 42},
{ 0, 11, 12, 42},
{ 12, 7, 22, 33},
{ 33, 7, 43, 33},
{ 22, 10, 33, 41},
{ 0, 0, 0, 0},
{ 22, 0, 33, 10},
{ 0, 0, 0, 0},
{ 0, 0, 0, 0},
};
DWORD GetMechTeamColor(int nTeam)
{
if ((nTeam < 0) || (8 <= nTeam)) {
// no team or cameraship...
return 0x00FFFFFF;
} else {
//
static DWORD g_dwaColors[8] = {
0x000000FF, // blue
0x00FF0000, // red
0x00FFFF00, // yellow
0x0000FF00, // green
0x00FF00FF, // violet
0x0000FFFF, // cyan
0x00FFC000, // orange
0x00C0C0C0, // gray
};
return g_dwaColors[nTeam];
}
}
DWORD MakeBrightColor(DWORD c,DWORD v)
{
DWORD r=((c>>16)&0xFF) +v;
DWORD g=((c>>8)&0xFF) +v;
DWORD b=((c)&0xFF)+v;
if(r>0xFF)r=0xFF;
if(g>0xFF)g=0xFF;
if(b>0xFF)b=0xFF;
return (r<<16) + (g<<8) + b;
}
Mech* GetTargetMech(Mech* pMech)
{
if (pMech) {
return pMech->m_Others[0].Get();
}
return NULL;
}
void HUDChat::DrawImplementation(void)
{
if(!hsh_initialized){
#ifdef _DEBUG
{
int mech_count=MWApplication::GetInstance()->GetMechInfos(2, g_aMechInfos, g_TeamOrderOthers);
}
#endif
if(!hsh_mrdev_initialized){
#ifdef _DEBUG
Point3D loc,size;
bool drawCurrent=false;
MWApplication *app = MWApplication::GetInstance ();
loc = Location ();
Verify (comm);
loc.y = comm->BottomY ();
if (comm->LancemateSelected ())
return;
if (m_LargeSize)
Size (Point3D (232,MAX_CHAT_LINES*15.0f*2,0.9f));
else
Size (Point3D (232,MAX_CHAT_LINES*15.0f,0.9f));
size = Size ();
DWORD bcolor = BrighterColor (Color ());
DrawRect (loc,size,MakeColor (5,15,5,200));
DrawFrame (loc,size,bcolor);
loc.y += 2;
loc.x += 2;
size.x -= 4;
Point3D r,s,rNext;
r.z = 0.0f;
DWORD chatx,chaty;
stlport::list<ChatData>::iterator iter;
r.x = loc.x;
r.y = loc.y + size.y;
if (m_CurrentChat)
{
char buf[MAX_HUD_TEXT*2];
Verify (m_CursorPos);
char temp;
int posx,posy;
if (m_TeamChat)
{
Str_Copy (buf,app->GetLocString (IDS_CHATHEADER2),MAX_HUD_TEXT*2);
}
else
{
Str_Copy (buf,app->GetLocString (IDS_CHATHEADER1),MAX_HUD_TEXT*2);
}
int nHeaderLen = strlen(buf);
Str_Cat (buf,m_CurrentChat,MAX_HUD_TEXT*2);
curChatDisplay->UpdateText (buf,false);
drawCurrent = true;
extern DWORD g_bDisableImeCompletely;
if (g_bDisableImeCompletely) {
curChatDisplay->TopLeft (loc.x,loc.y);
curChatDisplay->BottomRight (r.x+size.x-2,r.y+size.y-2);
}
else {
// Fix for #8264 (XPack #231). The cause was because of incorrect string width.
// Clipping rectangle must be set before HUDText::DrawSize is called.
// HUDText::DrawSize calculates string width with selected clipping rectangle
// and caches it along with gos_DBCS object.
curChatDisplay->TopLeft (0, 0);
curChatDisplay->BottomRight (10000, 10000);
}
curChatDisplay->DrawSize (chatx,chaty);
r.y = loc.y + size.y - chaty;
if (g_bDisableImeCompletely)
{
curChatDisplay->Draw (r);
if (m_CursorBlink)
{
int ts;
ts = (int) curChatDisplay->Size ();
DWORD linecolor = MakeColor (255,255,255,255);
DWORD a,b;
curChatDisplay->EndPos (a,b);
posx = a+(int) r.x;
posy = b+(int) r.y - 2;
DrawLine (posx,posy,posx,posy-ts,linecolor);
}
}
else
{
// Trim the string if it overflows the window - keep the chat string single line
// this is to avoid problems in word wrapping
static int IsKoreanCP = -1;
if (IsKoreanCP == -1)
IsKoreanCP = (GetACP() == 949 ? 1 : 0);
bool bClipped = false;
int iRightEnd = int(r.x + size.x - 2);
while (true)
{
DWORD cx, cy;
curChatDisplay->DrawSize( cx, cy );
if (cx <= iRightEnd) {
if (*m_CursorPos > *m_ChatLen)
*m_CursorPos = *m_ChatLen;
break;
}
bClipped = true;
char* pszPrev = CharPrev(buf, buf + nHeaderLen + *m_ChatLen);
*m_ChatLen = pszPrev - buf - nHeaderLen;
*pszPrev = 0;
m_CurrentChat[*m_ChatLen] = 0;
curChatDisplay->UpdateText (buf,false,false);
}
if (IsKoreanCP && bClipped && *m_CursorPos == *m_ChatLen)
gos_FinalizeStringIME();
temp = buf[nHeaderLen + *m_CursorPos];
buf[nHeaderLen + *m_CursorPos] = 0;
curChatDisplay->UpdateText (buf,false,false);
curChatDisplay->DrawSize (chatx,chaty);
curChatDisplay->Draw (r);
DWORD a,b;
curChatDisplay->EndPos (a,b,false);
int iFontX = (int)r.x, iFontY = (int)r.y;
AdjustCoords(iFontX, iFontY);
iFontX += (int)a;
curChatDisplay->EndPos (a,b);
posx = a+(int) r.x;
posy = int(loc.y + size.y - chaty); // assumption - single line chat
if (m_CursorBlink && gos_GetMachineInformation(gos_Info_GetIMECaretStatus))
{
int ts;
ts = (int) curChatDisplay->Size ();
DWORD linecolor = MakeColor (255,255,255,255);
DrawLine (posx,posy,posx,posy-ts,linecolor);
}
rNext.x = (float)posx;
rNext.y = (float)posy;
rNext.z = 0;
buf[nHeaderLen + *m_CursorPos] = temp;
curChatDisplay->UpdateText(buf + nHeaderLen + *m_CursorPos,false,false);
curChatDisplay->DrawSize (chatx,chaty);
gos_TextSetPosition(iFontX, iFontY);
curChatDisplay->Draw (rNext, false);
// if (gos_GetMachineInformation(gos_Info_GetIMEStatus))
{
int left = int(loc.x);
int top = int(loc.y);
int right = int(loc.x+size.x-2);
int bottom = int(loc.y+size.y-2);
AdjustCoords(left, top, right, bottom);
gos_TextSetRegion(left, top, right, bottom);
extern float FontSize;
float oldFontSize = FontSize;
float fDummy = 0.0f;
FontSize = (float)curChatDisplay->Size ();
AdjustCoords(FontSize, fDummy);
FontSize *= -1.333f;
AdjustCoords(posx, posy);
gos_PositionIME(posx, posy);
FontSize = oldFontSize;
}
}
}
for (iter = m_Messages.begin ();iter != m_Messages.end ();iter++)
{
iter->text->TopLeft (loc.x,loc.y);
iter->text->BottomRight (loc.x+size.x-2,loc.y+size.y-2);
iter->text->DrawSize (chatx,chaty);
r.y -= chaty;
iter->text->Draw (r);
if (r.y < loc.y)
{
iter++;
break;
}
}
int i = 0;
while ((iter != m_Messages.end ()) && (i != 15)) // save last ten chats
{
i++;
iter++;
}
while (iter != m_Messages.end ())
{
delete iter->text;
iter->text = NULL;
iter = m_Messages.erase (iter);
}
#endif
}else {
#ifdef _DEBUG
bool draw_mr=true;
#else
bool draw_mr=CTCL_GetType()==_ECTCL_CameraShip;
#endif
if(draw_mr){
//미션 리뷰 내용을 그린다.
//_______________________________________________________________________________________________________
//
// Mech상태 및 메시지
//_______________________________________________________________________________________________________
if(!mr_device.map_loaded){
comm = Cast_Object (HUDComm *, MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_COMM));
//mr_device의 맵 데이타를 로드한다.
extern char AssetsDirectory1[MAX_PATH];
const Map__GameModel *model = Map::GetInstance ()->GetGameModel ();
char temp[256];
sprintf(temp, "%s\\hsh\\%s-1.bmp", AssetsDirectory1,model->m_HudMap);
DrawBitmapToSurface(mr_device.pDDSMapTexture,0,0,temp);
mr_device.map_loaded=true;
}
Mech* pFocusMech=g_aMechInfos[0].m_pMech;
Entity* pET = VehicleInterface::GetInstance()-> observingEntity.GetCurrent();
if (pET && pET->IsDerivedFrom(Mech::DefaultData))
pFocusMech = Cast_Object(Mech*, pET);
Mech* pTargetMech=GetTargetMech(pFocusMech);
mr_device.pD3DDevice->SetTexture(0,0);
//Draw Default Background;
//mr_device.DrawMFDDefaultBackAux1(g_nTeamOrderMode);
int mech_count=0;
PMechInfo pMechInfos = &g_aMechInfos[0];
{
//현재 다른 메크들의 이름 /Kill/Death를 그린다.
mech_count=MWApplication::GetInstance()->GetMechInfos(2, g_aMechInfos, g_TeamOrderOthers);
g_TeamOrderCount=mech_count;
if (mech_count > 8) // jcem
mech_count = 8;
int i,j;
const char * callsign="";
char score[16] ={0};
char kill_death[16] ={0};
HUDScore *hud = NULL;
MWGUIManager *manager = MWGUIManager::GetInstance ();
if (manager){
if (manager->Component(MWGUIManager::HUD_SCORE)){
hud = Cast_Object (HUDScore *,manager->Component(MWGUIManager::HUD_SCORE));
}
}
for(i=0;i<mech_count;i++) {
int row=i/4,col=i%4;
int x=col*80+360;
int y=row*140+20;
Mech* pMech = pMechInfos->m_pMech;
mr_device.pD3DDevice->SetTexture(0,mr_device.pDDSTexture);
//메크의 Damage 상태를 그린다.
for (j=0;j<11;j++){
if (j==7 || j==9 || j==10)
continue;
int dv=pMech ->damageArray[j];//damage value
if ( (0<=dv) && (dv<=5)){
int off=(j<=1)?-8:0;
mr_device.DrawTexture(coords[j][0]+x-30,coords[j][1]+y+off,SH_DamageColor2[dv],
coords[j][0],coords[j][1],coords[j][2],coords[j][3]);
}
}
//메크의 Callsign/Score/Kills/Deaths를 그린다.
int nScore = 0, nKills = 0, nDeaths = 0;
callsign=pMechInfos->m_pcszName;
if (hud) {
nScore = hud->GetScore4Player(*pMechInfos, nKills, nDeaths);
}
wsprintf(score,"Score:%d",nScore);
wsprintf(kill_death,"%d/%d",nKills,nDeaths);
//DrawCallSign..
mr_device.pFont[1].DrawText((float)(x),(float)(y+90),0xFFFFFFFF,callsign,TEXTALIGN_ORG);
mr_device.pFont[1].DrawText((float)(x),(float)(y+90+15),0xFFFFFFFF,score,TEXTALIGN_ORG);
mr_device.pFont[1].DrawText((float)(x),(float)(y+90+30),0xFFFFFFFF,kill_death,TEXTALIGN_ORG);
if(pFocusMech== pMech ){
mr_device.pD3DDevice->SetTexture(0,0);
///focused mech
mr_device.DrawThickFrame(x-40,y-4,x+40,y+140-10,2,0xFFFFFF00); // in yellow
} else if(pFocusMech== pMech ){
mr_device.pD3DDevice->SetTexture(0,0);
///target of focused mech
mr_device.DrawThickFrame(x-40,y-4,x+40,y+140-10,2,0xFFFF0000); // in red
}
pMechInfos++;
}
//채팅장의 내용을 그린다.
stlport::list<ChatData>::iterator iter;
int cy=300+30;//chat_y
for (iter = m_Messages.begin ();iter != m_Messages.end ();iter++){
mr_device.pFont[3].DrawText(10,(float)cy,0xFFFFFFFF,iter->text->hsh_get_m_Text(),0);
cy+=16;
if (cy>(480-40-16)){
iter++;
break;
}
}
i = 0;
while ((iter != m_Messages.end ()) && (i != 15)){
i++;
iter++;
}
while (iter != m_Messages.end ()){
delete iter->text;
iter->text = NULL;
iter = m_Messages.erase (iter);
}
}
//_______________________________________________________________________________________________________
//
// Map
//_______________________________________________________________________________________________________
Check_Object(this);
int i;
// Secondary Maps
//맵과 맵 경계선을 그린다. (게임중에 변하지 않으므로 한번만 그린다.)
//DrawMapBoundary();//다른 버전 구현할 것...
mr_device.pD3DDevice->SetRenderState(D3DRENDERSTATE_CLIPPING ,TRUE);
mr_device.pD3DDevice->SetTexture(0,mr_device.pDDSMapTexture);
mr_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
mr_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
mr_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );
mr_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER ,D3DTFG_LINEAR);
mr_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER ,D3DTFG_LINEAR);
//setup state bits
//int state[12];
//MechWarrior4::VehicleInterface* p = MechWarrior4::VehicleInterface::GetInstance();
//미션 리뷰에서는 현재 메크가 중심에 표시되므로 맵이 스크롤 되어 표시된다.
float MR_MSF=4.0f;//Mission Review - Map Scale Factor
const float ViewSize=300.0f;//Mission Review - Map Size
const float ViewLMargin=10;
const float ViewTMargin=10;
const float ViewHC=ViewSize/2+ViewLMargin;
const float ViewVC=ViewSize/2+ViewTMargin;
D3DVIEWPORT7 viewport={ViewLMargin,ViewTMargin,ViewSize,ViewSize,0.0f,1.0f};
mr_device.pD3DDevice->SetViewport(&viewport);
///////////////////// MAP 시작 //////////////////////
//Focus Mech를 설정하는 루틴을 넣어야한다.
Scalar multx,multz;
multx = MR_MSF*ViewSize/(MW4AI::MaxX - MW4AI::MinX);
multz = MR_MSF*ViewSize/(MW4AI::MaxZ - MW4AI::MinZ);
Stuff::Point3D pos_focus;
pos_focus = pFocusMech->GetLocalToWorld();
pos_focus.y = pos_focus.z;
pos_focus.x = pos_focus.x*multx;
pos_focus.y = pos_focus.y*multz;
Scalar l,r,t,b;
l=pos_focus.x-MR_MSF*ViewSize/2+ViewHC;
t=pos_focus.y-MR_MSF*ViewSize/2+ViewVC;
r=pos_focus.x+MR_MSF*ViewSize/2+ViewHC;
b=pos_focus.y+MR_MSF*ViewSize/2+ViewVC;
mr_device.DrawTexture(l,t,r,b,0xFFFFFFFF,0,0,256,256);
mr_device.pD3DDevice->SetTexture(0,mr_device.pDDSTexture);
//맵상에 메크들들 그리기.텍스트 먼저..
for(i=0,pMechInfos = &g_aMechInfos[0];i<mech_count;i++,pMechInfos++){
Mech* pMech = pMechInfos->m_pMech;
//메크의 위치를 구할 것..
Stuff::Point3D pos;
pos = pMech->GetLocalToWorld();
pos.y = pos.z;
pos.x = pos.x*multx;
pos.y = pos.y*multz;
const char *callsign=pMechInfos->m_pcszName;
int fontindex;
DWORD color;
if (pFocusMech==pMech) {
fontindex = 3;
color = 0xFFFFFF00;
} else if (pTargetMech==pMech) {
//if this mech is target of focused mech then
fontindex = 1;
color = 0xFFFF0000;
} else {
fontindex = 1;
color = 0xFFFFFFFF;
}
mr_device.pFont[fontindex].DrawText(
(int)(pos_focus.x -pos.x+ViewHC),
(int)(pos_focus.y -pos.y+ViewVC+8),
0xFF000000,callsign,TEXTALIGN_HCENTER|TEXTALIGN_TOP);
mr_device.pFont[fontindex].DrawText(
(int)(pos_focus.x -pos.x+ViewHC-1),
(int)(pos_focus.y -pos.y+ViewVC+8-1),
color,callsign,TEXTALIGN_HCENTER|TEXTALIGN_TOP);
}
//아이콘 그리기.
for(i=0,pMechInfos = &g_aMechInfos[0];i<mech_count;i++,pMechInfos++){
Mech* pMech = pMechInfos->m_pMech;
//메크의 위치를 구할 것..
Stuff::Point3D pos;
UnitVector3D vec;
pMech->GetLocalToWorld ().GetLocalForwardInWorld (&vec);
YawPitchRange ypr (vec);
ypr.yaw -= Pi;
pos = pMech->GetLocalToWorld();
pos.y = pos.z;
pos.x = pos.x*multx;
pos.y = pos.y*multz;
DWORD mechcolor=GetMechTeamColor(pMechInfos->m_nTeam);
mechcolor=MakeBrightColor(mechcolor,80);
mechcolor|=0xFF000000;
/*
// jcem : MR Mech Image
// This block may draw focused mech but there is no actual image on mr_texture.bmp & mr_texturea.bmp
// & surrounding brackets too!!!
if(pFocusMech==pMech){
mr_device.DrawTextureRotate(82, 0, 98, 12, 90, 6,
pos_focus.x -pos.x+ViewHC+1,
pos_focus.y -pos.y+ViewVC+1,Pi - ypr.yaw,0xFFFFFFFF);
mr_device.DrawTextureRotate(82, 0, 98, 12, 90, 6,
pos_focus.x -pos.x+ViewHC-1,
pos_focus.y -pos.y+ViewVC-1,Pi - ypr.yaw,0xFFFFFFFF);
mr_device.DrawTextureRotate(82, 0, 98, 12, 90, 6,
pos_focus.x -pos.x+ViewHC,
pos_focus.y -pos.y+ViewVC,Pi - ypr.yaw,mechcolor);
}else
*/
{
mr_device.DrawTextureRotate(65,0,79,10,72,5,
pos_focus.x -pos.x+ViewHC,
pos_focus.y -pos.y+ViewVC,Pi - ypr.yaw,mechcolor);
}
/*
if(pTargetMech==pMech){
//if this mech is target of focused mech then
mr_device.DrawTexture(
(int)(pos_focus.x -pos.x+ViewHC-9),
(int)(pos_focus.y -pos.y+ViewVC-9),
0xFFFF8000,66,48,84,66);
}
*/
}
mr_device.pD3DDevice->SetRenderState(D3DRENDERSTATE_CLIPPING ,FALSE);
D3DVIEWPORT7 viewport2={0,0,640,480,0.0f,1.0f};
mr_device.pD3DDevice->SetViewport(&viewport2);
///////////////////// MAP 끝 //////////////////////
//_______________________________________________________________________________________________________
//
// Progress
//_______________________________________________________________________________________________________
//미션 시간 그리기...hudtimer.cpp에 DrawImplementation에서 따온것임..
MWMission *mwmiss = Cast_Object (MWMission *,Mission::GetInstance ());
Verify (mwmiss);
Stuff::Scalar cur_time=mwmiss->GetMissionTime();//-mwmiss->GetMissionTime();
Stuff::Scalar total_time=mwmiss->GetMissionDuration ();
const int bar_width = 520;
int progress=0;
if(total_time>0){
progress=(int)(bar_width *cur_time/total_time);
}
mr_device.pD3DDevice->SetTexture(0,0);
mr_device.DrawQuad(100,454,100+progress+6,464,0xFFCCCCCC);
mr_device.pD3DDevice->SetTexture(0,mr_device.pDDSTexture);
mr_device.DrawTexture(progress+100,450,0xCCFFFFFF,66,17,79,40);
}//draw_mr
}//hsh_mrdev_initialized
}else if(mfd_device.BeginChannel(0)){
mfd_device.pD3DDevice->SetTexture(0,0);
stlport::vector<MWObject *> lance;
MW4AI::Groups::GetLancemates (lance);
//Draw Default Background;
mfd_device.DrawMFDDefaultBackAux1(g_nTeamOrderMode);
if(g_nTeamOrderMode==TEAM_MODE){
int i,j;
int size=3;
//메크들의 상태를 그린다.
PMechInfo pMechInfos = &g_aMechInfos[1];
size=MWApplication::GetInstance()->GetMechInfos(0, g_aMechInfos, g_TeamOrderOthers);
size--;
g_TeamOrderCount=size;
if (size > 3) // jcem
size = 3;
for(i=1;i<4;i++)mfd_text_comm1[i][0]=0;
mfd_device.pD3DDevice->SetTexture(0,mfd_device.pDDSTexture);
//enable Alpha
mfd_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
mfd_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
mfd_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );
for (i=0;i<size;i++) {
Mech* mech = pMechInfos->m_pMech;
//Fill CallSign Texts
strcpy(mfd_text_comm1[i+1],pMechInfos->m_pcszName);
BOOL bShow = TRUE;
if (g_pCurTOC && ((g_pCurTOC->m_nFrom == pMechInfos->connectionID) && mech->isPlayerVehicle)) {
Scalar fT = (Scalar)gos_GetElapsedTime();
fT -= g_fLastStartTime;
fT /= (Scalar)1.0;
fT -= floor(fT);
if (fT >= 0.5) {
bShow = FALSE;
}
}
if (bShow) {
for (j=0;j<11;j++){
if (j==7 || j==9 || j==10)
continue;
int dv=mech->damageArray[j];//damage value
if (( dv <= 5) && (dv>=0)){
RenderAux1SmallMech(i,j, SH_DamageColor[dv]);
}
}
}
pMechInfos++;
}
mfd_device.DrawMFDBackText(mfd_text_comm1);
//채팅장의 내용을 그린다.
stlport::list<ChatData>::iterator iter;
int cy=240;//chat_y
for (iter = m_Messages.begin ();iter != m_Messages.end ();iter++){
// MSL 5.02 Comm MFD Font Change
mfd_device.pFont[0].DrawText(10,(float)cy,0xFFFFFFFF,iter->text->hsh_get_m_Text(),0);
cy+=22;
if (cy>(440-22)){
iter++;
break;
}
}
i = 0;
while ((iter != m_Messages.end ()) && (i != 15)){
i++;
iter++;
}
while (iter != m_Messages.end ()){
delete iter->text;
iter->text = NULL;
iter = m_Messages.erase (iter);
}
}else if(g_nTeamOrderMode==FREEFORALL_MODE){
//현재 다른 메크들의 이름 /Kill/Death를 그린다.
int size=0;
PMechInfo pMechInfos = &g_aMechInfos[1];
size=MWApplication::GetInstance()->GetMechInfos(2, g_aMechInfos, g_TeamOrderOthers);
size--;
g_TeamOrderCount=size;
if (size > 7) // jcem
size = 7;
int i;
//번호를 먼저 지운다.
// MSL 5.03 Comm MFD
for(i=0;i<7;i++)mfd_text_comm3[i][0]=0;
//번호를 채워 넣는다.
// MSL 5.03 Comm MFD
for(i=0;i<size;i++)itoa(i+1,mfd_text_comm3[i],10);
// MSL 5.03 Comm MFD
mfd_device.DrawMFDBackText(mfd_text_comm3);
mfd_device.DrawThickFrameList(size*2,aux1freeframes,2,0xFFFFFFFF);
POINT* p=aux1free_textcoord;
POINT* p2=aux1free_textcoord2;
RECT * r=aux1freeframes;
int x,y;
MWMission *mwmiss = Cast_Object (MWMission *,Mission::GetInstance ());
Verify (mwmiss);
const MechWarrior4::CBucketManager& bm = *mwmiss->m_BucketManager;
const char * callsign="";
char kills[16]={0};
char deaths[16]={0};
HUDScore *hud = NULL;
MWGUIManager *manager = MWGUIManager::GetInstance ();
if (manager)
{
if (manager->Component(MWGUIManager::HUD_SCORE))
{
hud = Cast_Object (HUDScore *,manager->Component(MWGUIManager::HUD_SCORE));
}
}
for(i=0;i<size;i++) {
//Mech* pMech = pMechInfos->m_pMech;
int nScore = 0, nKills = 0, nDeaths = 0;
callsign=pMechInfos->m_pcszName;
nScore = bm.RelativeGetScore4Player(g_aMechInfos[0], *pMechInfos, nKills, nDeaths);
//itoa(nScore,score,10);
itoa(nKills,kills,10);
itoa(nDeaths,deaths,10);
//DrawCallSign..
SIZE size;
mfd_device.pFont[2].GetTextExtent(callsign,&size);
if(size.cx<160){
mfd_device.pFont[2].DrawText((float)p2->x,(float)p2->y,0xFFFFFFFF,callsign,TEXTALIGN_ORG);
}else{
mfd_device.pFont[3].GetTextExtent(callsign,&size);
if(size.cx<160){
mfd_device.pFont[3].DrawText((float)p2->x,(float)p2->y,0xFFFFFFFF,callsign,TEXTALIGN_ORG);
}else{
mfd_device.pFont[1].GetTextExtent(callsign,&size);
if(size.cx<160){
mfd_device.pFont[1].DrawText((float)p2->x,(float)p2->y,0xFFFFFFFF,callsign,TEXTALIGN_ORG);
}else{
//최소크기 폰트도.. 넘어선다...
//2line으로 만든다.
char callsign2[128];
strcpy(callsign2,callsign);
int len2=strlen(callsign)/2;
char save=callsign2[len2];
callsign2[len2]=0;
mfd_device.pFont[1].DrawText((float)p2->x,(float)p2->y,0XFFFFFFFF,callsign2,TEXTALIGN_CENTER|TEXTALIGN_BOTTOM);
callsign2[len2]=save;
mfd_device.pFont[1].DrawText((float)p2->x,(float)p2->y,0XFFFFFFFF,callsign2+len2,TEXTALIGN_CENTER|TEXTALIGN_TOP);
}
}
}
p2++;
//Draw "Kill"
// MSL 5.02 Comm MFD
mfd_device.pFont[2].DrawText((float)p->x,(float)p->y,0xFFFFFFFF,"YOUR DEATHS",TEXTALIGN_BOTTOM|TEXTALIGN_CENTER);
p++;
//Draw "Death"
// MSL 5.02 Comm MFD
mfd_device.pFont[2].DrawText((float)p->x,(float)p->y,0xFFFFFFFF,"YOUR KILLS",TEXTALIGN_BOTTOM|TEXTALIGN_CENTER);
p++;
//Draw Kill
x=(r->left+r->right)/2;
y=(r->top+r->bottom)/2;
// MSL 5.02 Comm MFD
char minus[16]="";
// if (nKills == 0)
// {
sprintf(minus, "%d", nKills);
// }
// else
// {
// sprintf(minus, "-%d", nKills);
// }
mfd_device.pFont[0].DrawText((float)x,(float)y,0xFFFFFFFF,minus,TEXTALIGN_ORG);
r++;
//Draw Death
x=(r->left+r->right)/2;
y=(r->top+r->bottom)/2;
// MSL 5.02 Comm MFD
char plus[16]="";
// if (nDeaths == 0)
// {
sprintf(plus, "%d", nDeaths);
// }
// else
// {
// sprintf(plus, "+%d", nDeaths);
// }
mfd_device.pFont[0].DrawText((float)x,(float)y,0xFFFFFFFF,plus,TEXTALIGN_ORG);
r++;
pMechInfos++;
}
//채팅장의 내용을 그린다.
stlport::list<ChatData>::iterator iter;
int cy=180;//chat_y
for (iter = m_Messages.begin ();iter != m_Messages.end ();iter++){
// MSL 5.02 Comm MFD Font Change
mfd_device.pFont[0].DrawText(10,(float)cy,0xFFFFFFFF,iter->text->hsh_get_m_Text(),0);
cy+=22;
if (cy>(300-22)){
iter++;
break;
}
}
i = 0;
while ((iter != m_Messages.end ()) && (i != 15)){
i++;
iter++;
}
while (iter != m_Messages.end ()){
delete iter->text;
iter->text = NULL;
iter = m_Messages.erase (iter);
}
/*
//MWMission.cpp에서 가져온것인
MWMission *mwmiss = Cast_Object (MWMission *,Mission::GetInstance ());
int death=0,kill=0;//,score
if(MWPlayer::GetInstance()){
Check_Object(MWPlayer::GetInstance());
if(MWPlayer::GetInstance()->vehicle){
ScoreObject *score_object = mwmiss->GetScoreMember(MWPlayer::GetInstance()->vehicle->GetReplicatorID());
if(score_object){
death=score_object->GetDeaths();
kill=score_object->GetKills();
//score=score_object->
}
}
}
*/
}else if(g_nTeamOrderMode==TEAM_MESSAGE1){
;//do nothing
}else if(g_nTeamOrderMode==TEAM_MESSAGE2){
;//do nothing
}
//상훈 뒤
mfd_device.EndChannel();
} else {
}//hsh_initialized
}