#include "pch.h"
#include "consoledata.h"
#include "trekctrls.h"
#include "loadout.h"
#include "trekmdl.h"
#include "training.h"
#include "badwords.h"
const int c_iRecipientOther = -1;
const int c_iRecipientMe = 0;
const int c_iRecipientSector = 1;
const int c_iRecipientTeam = 2;
const int c_iRecipientAll = 3;
const int c_iRecipientWing0 = 4; const int c_badMatch = 100000;
const float c_minRectangleSize = 5.0f;
static bool inline LegalRectangle(const Point& p1, const Point& p2)
{
return (fabs(p1.X() - p2.X()) > c_minRectangleSize) ||
(fabs(p1.Y() - p2.Y()) > c_minRectangleSize);
}
const int c_maskMouseLeftDown = 0x01;
const int c_maskMouseRightDown = 0x02;
class ConsoleDataImpl;
class ConsolePickImage : public Image
{
private:
MouseResult m_mouseresult;
TRef<ConsoleDataImpl> m_pconsoleData;
TRef<Viewport> m_pviewport;
public:
ConsolePickImage(Viewport* pviewport,
ConsoleDataImpl* pconsoleData
);
void SetHitTest(MouseResult mr);
MouseResult HitTest(IInputProvider* pprovider, const Point& point, bool bCaptured);
MouseResult Button(IInputProvider* pprovider, const Point& point, int button, bool bCaptured, bool bInside, bool bDown);
void MouseMove(IInputProvider* pprovider, const Point& point, bool bCaptured, bool bInside);
void MouseEnter(IInputProvider* pprovider, const Point& point);
void MouseLeave(IInputProvider* pprovider);
};
struct ChatSubject
{
ChatTarget m_ctRecipient;
ObjectID m_oidRecipient;
TRef<IbaseIGC> m_pbaseRecipient;
ShipListIGC m_shipsSubject;
ChatSubject(ChatTarget ct)
:
m_ctRecipient(ct),
m_oidRecipient(NA),
m_pbaseRecipient(NULL)
{
}
~ChatSubject(void)
{
PurgeSubjects();
}
void PurgeSubjects(void)
{
ShipLinkIGC* psl;
while (psl = m_shipsSubject.first()) {
psl->data()->Release();
delete psl;
}
}
void AddSubject(IshipIGC* pship)
{
if (!m_shipsSubject.find(pship))
{
pship->AddRef();
if (pship == trekClient.GetShip())
m_shipsSubject.first(pship);
else
m_shipsSubject.last(pship);
}
}
void DeleteSubject(IshipIGC* pship)
{
ShipLinkIGC* psl = m_shipsSubject.find(pship);
if (psl)
{
pship->Release();
delete psl;
}
}
void ToggleSubject(IshipIGC* pship)
{
ShipLinkIGC* psl = m_shipsSubject.find(pship);
if (psl)
{
if (m_shipsSubject.n() > 1)
{
pship->Release();
delete psl;
}
}
else
{
pship->AddRef();
if (pship == trekClient.GetShip())
m_shipsSubject.first(pship);
else
m_shipsSubject.last(pship);
}
if (m_shipsSubject.n() == 1)
{
m_ctRecipient = CHAT_INDIVIDUAL;
m_pbaseRecipient = m_shipsSubject.first()->data();
m_oidRecipient = m_pbaseRecipient->GetObjectID();
}
else
{
assert (m_shipsSubject.n() != 0);
m_ctRecipient = CHAT_GROUP;
m_pbaseRecipient = NULL;
m_oidRecipient = NA;
}
}
bool LegalCommand(CommandID cid)
{
bool bLegal;
ShipLinkIGC* psl;
for (psl = m_shipsSubject.first();
((psl != NULL) && !psl->data()->LegalCommand(cid)); psl = psl->next())
{
}
bLegal = psl != NULL;
return bLegal;
}
bool LegalCommand(CommandID cid, ImodelIGC* pmodelTarget)
{
bool bLegal;
ShipLinkIGC* psl;
for (psl = m_shipsSubject.first();
((psl != NULL) && !psl->data()->LegalCommand(cid, pmodelTarget)); psl = psl->next())
{
}
bLegal = psl != NULL;
return bLegal;
}
bool ContainsLayer(void)
{
bool bLegal;
ShipLinkIGC* psl;
for (psl = m_shipsSubject.first();
((psl != NULL) && (psl->data()->GetPilotType() != c_ptLayer)); psl = psl->next())
{
}
bLegal = psl != NULL;
return bLegal;
}
bool ContainsOnlyBuilders(void)
{
bool bLegal;
ShipLinkIGC* psl;
psl = m_shipsSubject.first();
if (psl == NULL)
return false;
while ((psl != NULL) && (psl->data()->GetPilotType() == c_ptBuilder))
{
psl = psl->next();
}
bLegal = psl == NULL;
return bLegal;
}
void Reset(bool bStart = false)
{
if (m_ctRecipient == CHAT_GROUP)
{
ShipLinkIGC* pslNext;
for (ShipLinkIGC* psl = m_shipsSubject.first(); (psl != NULL); psl = pslNext)
{
pslNext = psl->next();
if (psl->data()->GetMission() == NULL)
delete psl;
}
if (m_shipsSubject.n() == 1)
{
m_ctRecipient = CHAT_INDIVIDUAL;
m_pbaseRecipient = m_shipsSubject.first()->data();
m_oidRecipient = m_pbaseRecipient->GetObjectID();
}
else if (m_shipsSubject.n() == 0)
{
m_ctRecipient = CHAT_TEAM;
m_pbaseRecipient = NULL;
m_oidRecipient = NA;
}
}
else
SetRecipient(m_ctRecipient, m_oidRecipient, m_pbaseRecipient);
if (bStart && (m_ctRecipient == CHAT_INDIVIDUAL))
{
IshipIGC* pship = (IshipIGC*)((IbaseIGC*)m_pbaseRecipient);
assert (pship);
if ((pship == trekClient.GetShip()) ||
(pship->GetPilotType() < c_ptPlayer))
{
SetRecipient(CHAT_TEAM, NA, NULL);
}
}
}
void SetRecipient(ChatTarget ct,
ObjectID oidRecipient,
IbaseIGC* pbaseRecipient,
const ShipListIGC* pships = NULL)
{
PurgeSubjects();
if ((ct != CHAT_NOSELECTION) && (ct != CHAT_ADMIN))
{
if (ct == CHAT_GROUP)
{
for (ShipLinkIGC* psl = pships->first(); (psl != NULL); psl = psl->next())
{
if (psl->data()->GetMission())
AddSubject(psl->data());
}
if (m_shipsSubject.n() == 1)
{
ct = CHAT_INDIVIDUAL;
pbaseRecipient = m_shipsSubject.first()->data();
oidRecipient = pbaseRecipient->GetObjectID();
}
else if (m_shipsSubject.n() == 0)
{
ct = CHAT_TEAM;
pbaseRecipient = NULL;
oidRecipient = NA;
}
}
else if (ct == CHAT_INDIVIDUAL)
{
if (pbaseRecipient->GetMission() != NULL)
AddSubject((IshipIGC*)pbaseRecipient);
else
{
ct = CHAT_TEAM;
pbaseRecipient = NULL;
oidRecipient = NA;
}
}
else if (ct == CHAT_SHIP)
{
pbaseRecipient = NULL;
oidRecipient = NA;
IshipIGC* pship = trekClient.GetShip()->GetSourceShip();
const ShipListIGC* pships = pship->GetChildShips();
if (pships->n() == 0)
{
ct = CHAT_TEAM;
}
else
{
AddSubject(pship);
for (ShipLinkIGC* psl = pships->first(); (psl != NULL); psl = psl->next())
AddSubject(psl->data());
}
}
if ((ct != CHAT_GROUP) && (ct != CHAT_INDIVIDUAL) && (ct != CHAT_SHIP))
{
IsideIGC* psideFriendly = trekClient.GetShip()->GetSide();
WingID wid;
const ShipListIGC* pships = psideFriendly->GetShips();
switch (ct)
{
case CHAT_TEAM:
{
pbaseRecipient = psideFriendly;
assert (pbaseRecipient);
oidRecipient = pbaseRecipient->GetObjectID();
}
break;
case CHAT_FRIENDLY_SECTOR:
{
if (!pbaseRecipient)
{
assert(oidRecipient == NA);
pbaseRecipient = trekClient.GetChatCluster();
assert (pbaseRecipient);
if (!pbaseRecipient)
{
ct = CHAT_TEAM;
oidRecipient = NA;
}
else
oidRecipient = pbaseRecipient->GetObjectID();
}
else
{
assert(oidRecipient == pbaseRecipient->GetObjectID());
}
}
break;
case CHAT_WING:
{
wid = trekClient.GetShip()->GetWingID();
if (oidRecipient == wid)
oidRecipient = NA;
else if (oidRecipient != NA)
wid = oidRecipient;
}
break;
case CHAT_EVERYONE:
{
pships = trekClient.m_pCoreIGC->GetShips();
}
break;
default:
assert (false);
}
for (ShipLinkIGC* psl = pships->first(); (psl != NULL); psl = psl->next())
{
IshipIGC* pship = psl->data();
bool bSubject = false;
switch (ct)
{
case CHAT_EVERYONE:
{
bSubject = true;
}
break;
case CHAT_ADMIN:
case CHAT_LEADERS:
{
bSubject = false; }
break;
case CHAT_TEAM:
{
assert (pship->GetSide() == pbaseRecipient);
bSubject = true;
}
break;
case CHAT_FRIENDLY_SECTOR:
{
assert (pship->GetSide() == psideFriendly);
PlayerInfo* ppi = (PlayerInfo*)(pship->GetPrivateData());
if (ppi)
bSubject = (ppi->LastSeenSector() == oidRecipient);
}
break;
case CHAT_WING:
{
assert (pship->GetSide() == psideFriendly);
bSubject = (pship->GetWingID() == wid);
}
break;
default:
{
assert (false);
}
}
if (bSubject)
AddSubject(pship);
}
}
}
m_ctRecipient = ct;
m_oidRecipient = oidRecipient;
m_pbaseRecipient = pbaseRecipient;
}
ChatSubject& operator = (const ChatSubject& chs)
{
SetRecipient(chs.m_ctRecipient, chs.m_oidRecipient, chs.m_pbaseRecipient, &chs.m_shipsSubject);
return *this;
}
};
class ConsoleDataImpl :
public ConsoleData,
EventTargetContainer<ConsoleDataImpl>,
TrekClientEventSink
{
friend class ConsoleImageImpl;
private:
TRef<INameSpace> m_pns;
TRef<INameSpace> m_pnsDisplays;
TRef<EventSourceImpl> m_peventSourceEveryFrame;
TRef<ModifiableNumber> m_pnumberOverlayFlags;
TRef<ModelData> m_pmodelDataMe;
TRef<ModelData> m_pmodelDataMyStation;
TRef<ModelData> m_pmodelDataTarget;
TRef<ModifiableNumber> m_pnumberAutopilotOn;
TRef<ModifiableNumber> m_pnumberDetected;
TRef<ModifiableNumber> m_pnumberExperience;
TRef<ModifiableNumber> m_pnumberTargetExperience;
TRef<ModifiableNumber> m_pnumberLivesOn;
TRef<ModifiableNumber> m_pnumberKillsOn;
TRef<ModifiableNumber> m_pnumberTargetInRangeFlag;
TRef<ModifiableNumber> m_pnumberGotFlag;
TRef<ModifiableNumber> m_pnumberGotArtifact;
TRef<ModifiableNumber> m_pnumberSignature;
enum ComposeState
{
c_csNotComposing = 0,
c_csComposeMouseCommand = 1,
c_csComposeChat = 2,
c_csComposeCommand = 3,
c_csComposeShell = 4,
c_csComposeQuick = 5
};
ComposeState m_csComposeState;
bool m_bRecipientVisible;
ChatSubject m_chsCommand;
ChatSubject m_chsChat;
ChatSubject m_chsQuick;
ChatSubject* m_pchsCurrent;
CommandID m_cidVerb;
TRef<ImodelIGC> m_pmodelTarget;
ZString m_strTypedText;
bool m_bMouseIn;
TRef<ModifiableNumber> m_pnumberComposeState;
TRef<ModifiableNumber> m_pnumberCommandID;
TRef<ModifiableString> m_pstringChatRecipient;
TRef<ModifiableString> m_pstringChatText;
TRef<ModifiableNumber> m_pnumberBoardState;
Vector m_positionStart;
Vector m_positionStop;
TRef<ModifiableNumber> m_pnumberRadarMode;
TRef<ModifiableNumber> m_pnumberMoney;
TRef<ModifiableString> m_pstringSectorName;
TRef<ModifiableString> m_pstringAcceptedOrder;
TRef<ModifiableString> m_pstringQueuedOrder;
TRef<ModifiableString> m_pstringTipText0; TRef<ModifiableString> m_pstringTipText1; TRef<ModifiableString> m_pstringTipText2; TRef<ModifiableString> m_pstringCriticalTipText0;
TRef<ModifiableString> m_pstringCriticalTipText1;
TRef<ModifiableString> m_pstringCriticalTipText2;
TRef<ModifiableString> m_pstringCriticalTipText3;
Time m_timeLastTipSet0; Time m_timeLastTipSet1; Time m_timeLastTipSet2; Time m_timeLastCriticalTipSet0;
Time m_timeLastCriticalTipSet1;
Time m_timeLastCriticalTipSet2;
Time m_timeLastCriticalTipSet3;
bool m_fTargetChanged;
float m_rPreviousMissileLock;
TRef<ModifiableString> m_pstringCurrentVote;
TRef<ModifiableNumber> m_pnumberHasVote;
Point m_pointMouseStart;
Point m_pointMouseStop;
int m_maskMouseState;
TRef<ModifiableColorValue> m_pcolorTargetSide;
OverlayMask m_omRecipientsVisible;
TRef<ButtonBarPane> m_pbuttonbarRecipients;
TRef<ButtonBarPane> m_pbuttonbarVerbs;
TRef<ComboPane> m_pcomboWing;
TRef<ModifiableNumber> m_pnumberLives;
TRef<ModifiableNumber> m_pnumberKills;
public:
ConsoleDataImpl(Viewport* pviewport, const char* pszFileName) :
m_csComposeState(c_csNotComposing),
m_rPreviousMissileLock(0.0f),
m_fTargetChanged(false),
m_timeLastTipSet0(Time::Now()), m_timeLastTipSet1(Time::Now()), m_timeLastTipSet2(Time::Now()), m_timeLastCriticalTipSet0(Time::Now()),
m_timeLastCriticalTipSet1(Time::Now()),
m_timeLastCriticalTipSet2(Time::Now()),
m_timeLastCriticalTipSet3(Time::Now()),
m_maskMouseState(0),
m_bMouseIn(false),
m_chsQuick(CHAT_NOSELECTION),
m_chsCommand(CHAT_NOSELECTION),
m_chsChat(CHAT_TEAM),
m_pchsCurrent(&m_chsCommand)
{
m_pns =
GetModeler()->CreateNameSpace(
"console",
GetModeler()->GetNameSpace("gamepanes")
);
m_pns->AddMember("OnEveryFrame", m_peventSourceEveryFrame = new EventSourceImpl());
ModelData::ExportAccessors(m_pns);
PartWrapper::ExportAccessors(m_pns);
m_pns->AddMember("OverlayFlags", m_pnumberOverlayFlags = new ModifiableNumber(0.0f));
m_pns->AddMember("Me", m_pmodelDataMe = new ModelData());
m_pns->AddMember("OnMeChange", m_pmodelDataMe->GetOnChangeEventSource());
m_pns->AddMember("MyStation", m_pmodelDataMyStation = new ModelData());
m_pns->AddMember("Target", m_pmodelDataTarget = new ModelData(NULL));
m_pns->AddMember("OnTargetChange", m_pmodelDataTarget->GetOnChangeEventSource());
m_pns->AddMember("targetSideColor", m_pcolorTargetSide = new ModifiableColorValue(Color::White()));
m_pns->AddMember("AutopilotOn", m_pnumberAutopilotOn = new ModifiableNumber(0));
m_pns->AddMember("LivesOn", m_pnumberLivesOn = new ModifiableNumber(0));
m_pns->AddMember("KillsOn", m_pnumberKillsOn = new ModifiableNumber(0));
m_pns->AddMember("BoardState", m_pnumberBoardState = new ModifiableNumber(0));
m_pns->AddMember("Detected", m_pnumberDetected = new ModifiableNumber(0));
m_pns->AddMember("Experience", m_pnumberExperience = new ModifiableNumber(0));
m_pns->AddMember("TargetExperience", m_pnumberTargetExperience = new ModifiableNumber(0));
m_pns->AddMember("TargetInRangeFlag", m_pnumberTargetInRangeFlag = new ModifiableNumber(0));
m_pns->AddMember("GotFlag", m_pnumberGotFlag = new ModifiableNumber(0));
m_pns->AddMember("GotArtifact", m_pnumberGotArtifact = new ModifiableNumber(0));
m_pns->AddMember("Signature", m_pnumberSignature = new ModifiableNumber(0));
m_pns->AddMember("ComposeState", m_pnumberComposeState = new ModifiableNumber(c_csNotComposing));
m_pns->AddMember("CommandVerb", m_pnumberCommandID = new ModifiableNumber(c_csNotComposing));
m_pns->AddMember("ChatRecipient", m_pstringChatRecipient = new ModifiableString(""));
m_pns->AddMember("ChatText", m_pstringChatText = new ModifiableString(""));
m_pns->AddMember("RadarMode", m_pnumberRadarMode = new ModifiableNumber(0));
m_pns->AddMember("Money", m_pnumberMoney = new ModifiableNumber(0));
m_pns->AddMember("SectorName", m_pstringSectorName = new ModifiableString(""));
m_pns->AddMember("AcceptedOrder", m_pstringAcceptedOrder = new ModifiableString(""));
m_pns->AddMember("QueuedOrder", m_pstringQueuedOrder = new ModifiableString(""));
m_pns->AddMember("TipText", m_pstringTipText0 = new ModifiableString("")); m_pns->AddMember("TipText1", m_pstringTipText1 = new ModifiableString("")); m_pns->AddMember("TipText2", m_pstringTipText2 = new ModifiableString("")); m_pns->AddMember("CriticalTipText0", m_pstringCriticalTipText0 = new ModifiableString(""));
m_pns->AddMember("CriticalTipText1", m_pstringCriticalTipText1 = new ModifiableString(""));
m_pns->AddMember("CriticalTipText2", m_pstringCriticalTipText2 = new ModifiableString(""));
m_pns->AddMember("CriticalTipText3", m_pstringCriticalTipText3 = new ModifiableString(""));
m_pns->AddMember("CurrentVote", m_pstringCurrentVote = new ModifiableString(""));
m_pns->AddMember("HasVote", m_pnumberHasVote = new ModifiableNumber(0));
m_pns->AddMember("Lives", m_pnumberLives = new ModifiableNumber(0));
m_pns->AddMember("Kills", m_pnumberKills = new ModifiableNumber(0));
m_pnsDisplays = GetModeler()->GetNameSpace(pszFileName);
m_omRecipientsVisible = OverlayMask(m_pnsDisplays->FindNumber("RecipientsVisibleOM", 0.0f));
CastTo(m_pbuttonbarRecipients, m_pnsDisplays->FindMember("RecipientsBB"));
AddEventTarget(&ConsoleDataImpl::OnRecipientButton, m_pbuttonbarRecipients->GetEventSource());
CastTo(m_pbuttonbarVerbs, m_pnsDisplays->FindMember("VerbsBB"));
AddEventTarget(&ConsoleDataImpl::OnVerbButton, m_pbuttonbarVerbs->GetEventSource());
CastTo(m_pcomboWing, m_pnsDisplays->FindMember("WingCombo"));
for (WingID wingID = 0; wingID < c_widMax; wingID++)
{
m_pcomboWing->AddItem(c_pszWingName[wingID],
wingID);
}
AddEventTarget(&ConsoleDataImpl::OnWingCombo, m_pcomboWing->GetEventSource());
}
~ConsoleDataImpl()
{
GetModeler()->UnloadNameSpace("console");
GetModeler()->UnloadNameSpace("teampane");
GetModeler()->UnloadNameSpace("teleportpane");
}
const TRef<INameSpace>& GetNameSpace(void) const
{
return m_pnsDisplays;
}
void Update(Time now)
{
IshipIGC* pshipParent = trekClient.GetShip()->GetParentShip();
m_pmodelDataMe->SetModel(trekClient.GetShip()->GetSourceShip());
m_pmodelDataMyStation->SetModel(trekClient.GetShip()->GetStation());
m_peventSourceEveryFrame->Trigger();
m_pnumberRadarMode->SetValue((float)GetWindow()->GetRadarMode());
m_pnumberMoney->SetValue((float)trekClient.GetMoney());
m_pnumberAutopilotOn->SetValue(trekClient.autoPilot() ? 1.0f : 0.0f);
if (!pshipParent)
m_pnumberBoardState->SetValue(0);
else if (trekClient.GetShip()->GetTurretID() == NA)
m_pnumberBoardState->SetValue(1);
else
m_pnumberBoardState->SetValue(2);
{
PlayerInfo* ppi = (PlayerInfo*)(trekClient.GetShip()->GetPrivateData());
m_pnumberDetected->SetValue((ppi && !ppi->GetDetected()) ? 0.0f : 1.0f);
m_pnumberLives->SetValue(trekClient.m_pCoreIGC->GetMissionParams()->iLives - ppi->MissionDeaths());
m_pnumberKills->SetValue(ppi->MissionKills());
if ((trekClient.m_pCoreIGC->GetMissionParams()->iLives - ppi->MissionDeaths()) >= 10)
m_pnumberLivesOn->SetValue(0.0f);
else
m_pnumberLivesOn->SetValue(1.0f);
if (trekClient.m_pCoreIGC->GetMissionParams()->IsDeathMatchGame())
m_pnumberKillsOn->SetValue(1.0f);
else
m_pnumberKillsOn->SetValue(0.0f);
}
{
float experience = trekClient.GetShip()->GetExperienceMultiplier();
m_pnumberExperience->SetValue(100.0f * (experience - 1.0f));
}
{
ImodelIGC* pmodelTarget = m_pmodelDataTarget->GetModel();
if (pmodelTarget && pmodelTarget->GetObjectType() == OT_ship)
{
m_pnumberTargetExperience->SetValue(
100.0f * (((IshipIGC*)pmodelTarget)->GetExperienceMultiplier() - 1.0f));
}
else
{
m_pnumberTargetExperience->SetValue(0);
}
}
{
IshipIGC* pship = trekClient.GetShip()->GetSourceShip();
switch (pship->GetFlag())
{
case SIDE_TEAMLOBBY:
m_pnumberGotFlag->SetValue(0.0f);
m_pnumberGotArtifact->SetValue(1.0f);
break;
case NA:
m_pnumberGotFlag->SetValue(0.0f);
m_pnumberGotArtifact->SetValue(0.0f);
break;
default:
m_pnumberGotFlag->SetValue(1.0f);
m_pnumberGotArtifact->SetValue(0.0f);
}
m_pnumberSignature->SetValue(100.0f * pship->GetSignature() /
pship->GetSide()->GetGlobalAttributeSet().GetAttribute(c_gaSignature));
}
{
IclusterIGC* pcluster = trekClient.GetCluster();
if (pcluster)
m_pstringSectorName->SetValue(pcluster->GetName());
}
{
static char bfr[100];
CommandID cid = trekClient.GetShip()->GetCommandID(c_cmdAccepted);
if (cid != c_cidNone)
{
strcpy(bfr, c_cdAllCommands[cid].szVerb);
ImodelIGC* pmodel = trekClient.GetShip()->GetCommandTarget(c_cmdAccepted);
if (pmodel)
{
int l = strlen(bfr);
bfr[l] = ' ';
strcpy(bfr + l + 1, GetModelName(pmodel));
}
}
else
bfr[0] = '\0';
m_pstringAcceptedOrder->SetValue(bfr);
}
{
static char bfr[100];
CommandID cid = trekClient.GetShip()->GetCommandID(c_cmdQueued);
if (cid != c_cidNone)
{
strcpy(bfr, c_cdAllCommands[cid].szVerb);
ImodelIGC* pmodel = trekClient.GetShip()->GetCommandTarget(c_cmdQueued);
if (pmodel)
{
int l = strlen(bfr);
bfr[l] = ' ';
strcpy(bfr + l + 1, GetModelName(pmodel));
}
}
else
bfr[0] = '\0';
m_pstringQueuedOrder->SetValue(bfr);
}
float fTipTextDuration = Training::IsTraining () ? 30.0f : 7.5f;
if (now - m_timeLastCriticalTipSet0 >= fTipTextDuration)
{
m_pstringCriticalTipText0->SetValue("");
m_timeLastCriticalTipSet0 = now + 3600.0f;
}
if (now - m_timeLastCriticalTipSet1 >= fTipTextDuration)
{
m_pstringCriticalTipText1->SetValue("");
m_timeLastCriticalTipSet1 = now + 3600.0f;
}
if (now - m_timeLastCriticalTipSet2 >= fTipTextDuration)
{
m_pstringCriticalTipText2->SetValue("");
m_timeLastCriticalTipSet2 = now + 3600.0f;
}
if (now - m_timeLastCriticalTipSet3 >= fTipTextDuration)
{
m_pstringCriticalTipText3->SetValue("");
m_timeLastCriticalTipSet3 = now + 3600.0f;
}
float rMissileLock = 0.0f;
ImagazineIGC* magazine = (ImagazineIGC*)(trekClient.GetShip()->GetMountedPart(ET_Magazine, 0));
if (magazine)
rMissileLock = magazine->GetLock();
if (rMissileLock > 0.0f && rMissileLock < 1.0f &&
!(m_rPreviousMissileLock > 0.0f && m_rPreviousMissileLock < 1.0f))
trekClient.PostText(false, "Partial missile lock - center the target on screen to improve the lock.");
else if (rMissileLock == 1.0f && m_rPreviousMissileLock != 1.0f)
trekClient.PostText(false, "%s", (const char*)(ZString("Missile lock acquired - press [Ctrl]-[Space] to fire a ")
+ magazine->GetMissileType()->GetName() + " missile at the target."));
else if (rMissileLock == 0.0f && m_rPreviousMissileLock != 0.0f && !m_fTargetChanged)
trekClient.PostText(false, "Missile lock lost.");
m_rPreviousMissileLock = rMissileLock;
m_fTargetChanged = false;
BallotInfo* pballotinfo = trekClient.GetCurrentBallot();
m_pnumberHasVote->SetValue(pballotinfo ? 1.0f : 0.0f);
m_pstringCurrentVote->SetValue(pballotinfo ? ZString(pballotinfo->GetBallotText()) : ZString());
}
void SetInRange(bool bInRange)
{
m_pnumberTargetInRangeFlag->SetValue(bInRange ? 1.0f : 0.0f);
}
void SetTarget(ImodelIGC* pmodel)
{
if (m_pmodelDataTarget->GetModel() != pmodel)
{
m_fTargetChanged = true;
m_pmodelDataTarget->SetModel(pmodel);
}
}
void SetOverlayFlags(OverlayMask om)
{
m_pnumberOverlayFlags->SetValue((float)om);
bool bNew = (om & m_omRecipientsVisible) != 0;
if (bNew != m_bRecipientVisible)
{
m_chsCommand.SetRecipient(CHAT_INDIVIDUAL, trekClient.GetShipID(), trekClient.GetShip());
AdjustVerbs(&m_chsCommand);
}
m_bRecipientVisible = bNew;
}
OverlayMask GetOverlayFlags(void) const
{
return (OverlayMask)(m_pnumberOverlayFlags->GetValue());
}
void OnSwitchViewMode()
{
GetWindow()->SetCursor(AWF_CURSOR_DEFAULT);
m_maskMouseState = 0;
if (m_csComposeState == c_csComposeMouseCommand)
QuitComposing();
}
void SetTipText(const ZString& strHelp)
{
m_timeLastTipSet2 = m_timeLastTipSet1; m_timeLastTipSet1 = m_timeLastTipSet0; m_timeLastTipSet0 = Time::Now(); m_pstringTipText2->SetValue(m_pstringTipText1->GetValue()); m_pstringTipText1->SetValue(m_pstringTipText0->GetValue()); m_pstringTipText0->SetValue(strHelp); }
void SetCriticalTipText(const ZString& strHelp)
{
if (!Training::IsTraining())
{
m_pstringCriticalTipText3->SetValue(m_pstringCriticalTipText2->GetValue());
m_pstringCriticalTipText2->SetValue(m_pstringCriticalTipText1->GetValue());
m_pstringCriticalTipText1->SetValue(m_pstringCriticalTipText0->GetValue());
m_timeLastCriticalTipSet3 = m_timeLastCriticalTipSet2;
m_timeLastCriticalTipSet2 = m_timeLastCriticalTipSet1;
m_timeLastCriticalTipSet1 = m_timeLastCriticalTipSet0;
}
m_pstringCriticalTipText0->SetValue(strHelp);
m_timeLastCriticalTipSet0 = Time::Now();
static IEngineFont* pfont = GetModeler()->GetNameSpace("font")->FindFont("medBoldVerdana");
if (pfont->GetMaxTextLength(strHelp, 620, true) < strHelp.GetLength())
SetCriticalTipText("");
}
void SetComposeState(ComposeState cs)
{
{
IclusterIGC* pcluster = trekClient.GetCluster();
if (pcluster)
{
for (ModelLinkIGC* pml = pcluster->GetPickableModels()->first(); (pml != NULL); pml = pml->next())
{
ImodelIGC* pmodel = pml->data();
ThingSite* pts = pmodel->GetThingSite();
if (pts)
{
pts->SetMask(0);
}
}
}
}
m_csComposeState = cs;
m_pnumberComposeState->SetValue((float)(int)cs);
}
void SetVerb(CommandID cidVerb)
{
m_cidVerb = cidVerb;
m_pnumberCommandID->SetValue((float)(int)cidVerb);
}
ComposeState GetComposeState()
{
return m_csComposeState;
}
void OnMoneyChange(PlayerInfo* pPlayerInfo)
{
}
void OnDelPlayer(MissionInfo *pMissionDef, SideID sideID, PlayerInfo *pPlayerInfo, QuitSideReason reason, const char* szMessageParam)
{
if (!Training::IsTraining())
{
if (pPlayerInfo == trekClient.GetPlayerInfo())
{
GetWindow()->screen(ScreenIDTeamScreen);
}
else if (m_csComposeState != c_csNotComposing)
{
}
}
}
bool OnBackButton()
{
if (!Training::IsTraining () && !trekClient.GetShip()->IsGhost())
GetWindow()->SetViewMode(trekClient.flyingF() ? TrekWindow::vmCombat : TrekWindow::vmHangar);
return true;
}
bool OnRecipientButton(int nColumn)
{
if (m_csComposeState != c_csComposeShell)
{
ChatTarget ct;
ObjectID oid;
IbaseIGC* pbase;
switch (nColumn)
{
case c_iRecipientMe:
ct = CHAT_INDIVIDUAL;
pbase = trekClient.GetShip();
oid = NA;
break;
case c_iRecipientTeam:
ct = CHAT_TEAM;
pbase = NULL;
oid = NA;
break;
case c_iRecipientSector:
ct = CHAT_FRIENDLY_SECTOR;
pbase = NULL;
oid = NA;
break;
case c_iRecipientAll:
ct = CHAT_EVERYONE;
pbase = NULL;
oid = NA;
break;
default:
ct = CHAT_WING;
pbase = NULL;
oid = nColumn - c_iRecipientWing0;
}
if (m_csComposeState == c_csNotComposing)
StartComposing(c_csComposeChat, &m_chsChat);
m_pchsCurrent->SetRecipient(ct, oid, pbase);
UpdateComposedChat();
}
return true;
}
bool OnWingCombo(int index)
{
OnRecipientButton(c_iRecipientWing0 + index);
return true;
}
bool OnVerbButton(int nColumn)
{
if (m_csComposeState != c_csComposeShell)
{
trekClient.PlaySoundEffect(chatKeySound);
if (m_csComposeState == c_csNotComposing)
StartComposing(c_csComposeCommand, &m_chsCommand);
else
SetComposeState(c_csComposeCommand);
SetVerb(CommandID(nColumn + c_cidAttack));
UpdateComposedChat();
}
return true;
}
void UpdateComposedChat()
{
AdjustVerbs(m_pchsCurrent);
if (m_csComposeState != c_csNotComposing)
{
GetWindow()->SetCommandAsteroid(0);
if (m_csComposeState != c_csComposeMouseCommand)
{
ZString displayedChat = m_strTypedText + "|";
if (m_csComposeState == c_csComposeCommand)
{
if (m_pmodelTarget)
{
char bfr[c_cbName];
int lenText = m_strTypedText.GetLength();
strcpy(bfr, (m_pmodelTarget == trekClient.GetShip()) &&
(lenText <= 2) &&
(_strnicmp(m_strTypedText, "me", lenText) == 0)
? "me"
: GetModelName(m_pmodelTarget));
int lenName = strlen(bfr);
if (lenText < lenName)
{
for (int i = lenText; (i < lenName); i++)
bfr[i] = toupper(bfr[i]);
displayedChat += &bfr[lenText];
}
}
}
m_pstringChatText->SetValue(displayedChat);
}
if (m_csComposeState != c_csComposeShell)
{
static const char* pszEveryone = "All";
static const char* pszLeaders = "Leaders";
static const char* pszShip = "ship";
static const char* pszGroup = "Group";
static const char* pszAdmin = "Admin";
static const char* pszNone = "None";
const char* pszRecipient;
switch (m_pchsCurrent->m_ctRecipient)
{
case CHAT_NOSELECTION:
pszRecipient = pszNone;
break;
case CHAT_EVERYONE:
pszRecipient = pszEveryone;
break;
case CHAT_GROUP:
pszRecipient = pszGroup;
{
AsteroidAbilityBitMask aabm = c_aabmBuildable;
for (ShipLinkIGC* psl = m_pchsCurrent->m_shipsSubject.first(); (psl != NULL); psl = psl->next())
{
IshipIGC* pship = psl->data();
if (pship->GetPilotType() == c_ptBuilder)
{
aabm |= pship->GetOrdersABM();
}
}
GetWindow()->SetCommandAsteroid(aabm);
}
break;
case CHAT_LEADERS:
pszRecipient = pszLeaders;
break;
case CHAT_SHIP:
pszRecipient = pszShip;
break;
case CHAT_TEAM:
{
IsideIGC* pside = m_pchsCurrent->m_pbaseRecipient == NULL
? trekClient.GetShip()->GetSide()
: (IsideIGC*)((IbaseIGC*)m_pchsCurrent->m_pbaseRecipient);
pszRecipient = pside->GetName();
}
break;
case CHAT_INDIVIDUAL:
{
assert (m_pchsCurrent->m_pbaseRecipient != NULL);
IshipIGC* pship = (IshipIGC*)((IbaseIGC*)m_pchsCurrent->m_pbaseRecipient);
pszRecipient = pship->GetName();
if (pship->GetPilotType() == c_ptBuilder)
{
GetWindow()->SetCommandAsteroid(pship->GetOrdersABM());
}
}
break;
case CHAT_ADMIN:
{
pszRecipient = pszAdmin;
}
break;
case CHAT_WING:
{
pszRecipient = c_pszWingName[m_pchsCurrent->m_oidRecipient == NA
? trekClient.GetShip()->GetWingID()
: m_pchsCurrent->m_oidRecipient];
}
break;
case CHAT_ALL_SECTOR:
{
}
case CHAT_FRIENDLY_SECTOR:
{
IclusterIGC* pcluster;
if (m_pchsCurrent->m_pbaseRecipient == NULL)
{
pcluster = trekClient.GetChatCluster();
assert (pcluster != NULL);
if (pcluster)
pszRecipient = pcluster->GetName();
else
pszRecipient = "<unknown>";
}
else
pszRecipient = ((IclusterIGC*)((IbaseIGC*)m_pchsCurrent->m_pbaseRecipient))->GetName();
}
}
m_pstringChatRecipient->SetValue(CensorBadWords (pszRecipient));
}
}
}
void OnAddPlayer(MissionInfo *pMissionDef, SideID sideID, PlayerInfo *pPlayerInfo)
{
}
void SendChatInternal(const char* pszText,
int idSonicChat,
CommandID cid,
ImodelIGC* pmodel)
{
m_pchsCurrent->Reset();
if ((m_pchsCurrent->m_shipsSubject.n() != 0) || (m_pchsCurrent->m_ctRecipient == CHAT_ADMIN))
{
ObjectType otTarget = NA;
ObjectID oidTarget = NA;
if (pmodel)
{
if (pmodel->GetMission())
{
otTarget = pmodel->GetObjectType();
oidTarget = pmodel->GetObjectID();
}
else
pmodel = NULL; }
if (m_pchsCurrent->m_ctRecipient == CHAT_GROUP)
{
ChatTarget ct = CHAT_GROUP;
for (ShipLinkIGC* psl = m_pchsCurrent->m_shipsSubject.first(); (psl != NULL); psl = psl->next())
{
IshipIGC* pship = psl->data();
trekClient.SendChat(
trekClient.GetShip(),
ct,
pship->GetObjectID(),
idSonicChat,
pszText,
cid,
otTarget,
oidTarget,
pmodel
);
ct = CHAT_GROUP_NOECHO;
}
}
else
{
trekClient.SendChat(
trekClient.GetShip(),
m_pchsCurrent->m_ctRecipient,
m_pchsCurrent->m_oidRecipient,
idSonicChat,
pszText,
cid,
otTarget,
oidTarget,
pmodel
);
}
}
}
void StartQuickChat(ChatTarget ctRecipient,
ObjectID oidRecipient,
IbaseIGC* pbaseRecipient)
{
if (m_csComposeState == c_csNotComposing)
{
if (ctRecipient != CHAT_NOSELECTION)
{
m_chsQuick.SetRecipient(ctRecipient, oidRecipient, pbaseRecipient);
StartComposing(c_csComposeQuick, &m_chsQuick);
}
else
StartComposing(c_csComposeQuick, &m_chsChat);
}
else
{
assert (m_pchsCurrent);
if (ctRecipient != CHAT_NOSELECTION)
m_pchsCurrent->SetRecipient(ctRecipient, oidRecipient, pbaseRecipient);
SetComposeState(c_csComposeQuick);
}
UpdateComposedChat();
}
void SendQuickChat(int idSonicChat, int ttMask, CommandID cid, AbilityBitMask aabm)
{
if (cid == c_cidMyAccepted)
cid = trekClient.GetShip()->GetCommandID(c_cmdAccepted);
ImodelIGC* pmodel;
if (cid != c_cidNone)
{
assert (ttMask);
switch (ttMask)
{
case c_ttMyAccepted:
case c_ttMyQueued:
case c_ttMyTarget:
assert (char(c_ttMyAccepted) == c_cmdAccepted);
assert (char(c_ttMyQueued) == c_cmdQueued);
assert (char(c_ttMyTarget) == c_cmdCurrent);
pmodel = trekClient.GetShip()->GetCommandTarget(char(ttMask));
break;
case c_ttWorstEnemy:
{
DamageTrack* pdt = trekClient.GetShip()->GetDamageTrack();
assert (pdt);
DamageBucketLink* pdbl = pdt->GetDamageBuckets()->first();
pmodel = pdbl ? pdbl->data()->model() : NULL;
}
break;
case c_ttMe:
pmodel = trekClient.GetShip();
break;
default:
pmodel = trekClient.GetShip()->GetCommandTarget(c_cmdCurrent);
if ((!pmodel) ||
(pmodel == trekClient.GetShip()) ||
(!FindableModel(pmodel, trekClient.GetShip()->GetSide(), ttMask, aabm)) ||
(!trekClient.GetShip()->CanSee(pmodel)))
{
pmodel = FindTarget(trekClient.GetShip(), ttMask, NULL, NULL, NULL, NULL, aabm);
}
}
if (pmodel == NULL)
cid = c_cidNone;
}
else
pmodel = NULL;
SendChatInternal(NULL,
idSonicChat,
cid,
pmodel);
QuitComposing();
}
void SendChat()
{
if (m_csComposeState == c_csComposeChat)
{
assert (m_strTypedText.GetLength() != 0);
SendChatInternal(m_strTypedText,
NA,
c_cidNone,
NULL);
}
else if (m_csComposeState == c_csComposeShell)
{
trekClient.ParseShellCommand(m_strTypedText);
}
else
{
SendChatInternal(
NULL,
NA,
m_cidVerb,
m_pmodelTarget
);
}
QuitComposing();
}
void AdjustVerbs(ChatSubject* pchs)
{
if (m_bRecipientVisible)
{
for (CommandID i = c_cidAttack; (i < c_cidMax); i++)
m_pbuttonbarVerbs->SetEnabled(i - c_cidAttack, pchs->LegalCommand(i));
}
}
void QuitComposing()
{
SetComposeState(c_csNotComposing);
SetChatObject(NULL);
m_pchsCurrent = &m_chsCommand;
AdjustVerbs(&m_chsCommand);
GetWindow()->SetCommandAsteroid(0);
}
void StartComposing(ComposeState cs, ChatSubject* pchsTarget)
{
assert (cs != c_csNotComposing);
assert (m_csComposeState == c_csNotComposing);
pchsTarget->Reset(cs == c_csComposeChat);
m_pchsCurrent = pchsTarget;
SetChatObject(NULL);
m_strTypedText.SetEmpty();
SetComposeState(cs);
}
IshipIGC* PickShip(IclusterIGC* pcluster, const Point& pointPick)
{
IshipIGC* pshipMin = NULL;
float distanceMin = FLT_MAX;
Rect rectImage = GetWindow()->GetViewport()->GetViewRect()->GetValue();
Point point = pointPick - rectImage.Center();
for (ShipLinkIGC* psl = pcluster->GetShips()->first(); (psl != NULL); psl = psl->next())
{
IshipIGC* pship = psl->data();
if (pship->GetVisibleF())
{
ThingSite* psite = pship->GetThingSite();
if (psite)
{
const Point& pxy = psite->GetScreenPosition();
float r = psite->GetScreenRadius();
if ((pxy.X() + r >= point.X()) && (pxy.X() - r <= point.X()) &&
(pxy.Y() + r >= point.Y()) && (pxy.Y() - r <= point.Y()))
{
float dx = pxy.X() - point.X();
float dy = pxy.Y() - point.Y();
float d = dx*dx + dy*dy;
if (d <= distanceMin)
{
pshipMin = pship;
distanceMin = d;
}
}
}
}
}
return pshipMin;
}
void UpdatePick3D()
{
m_positionStop.x = m_positionStart.x;
m_positionStop.y = m_positionStart.y;
Camera* pcamera = GetWindow()->GetCamera();
const Orientation& o = pcamera->GetOrientation();
const Vector& b = o.GetBackward();
if ((b.z > 0.9f) || (b.z < -0.9f))
{
m_positionStop.z = 0.0f;
}
else
{
Rect rectImage = GetWindow()->GetViewport()->GetViewRect()->GetValue();
float halfwidth = (0.5f * rectImage.XSize());
const Vector& positionCamera = pcamera->GetPosition();
{
Point pointStop = m_pointMouseStop - rectImage.Center();
Vector directionStop = pcamera->TransformImageToDirection(pointStop / halfwidth);
float px = m_positionStart.x - positionCamera.x;
float py = m_positionStart.y - positionCamera.y;
m_positionStop.z = (px * directionStop.x * directionStop.z +
py * directionStop.y * directionStop.z) /
(directionStop.x * directionStop.x + directionStop.y * directionStop.y) + positionCamera.z;
}
}
}
void PickCluster(IclusterIGC* pcluster, int button)
{
if (m_csComposeState == c_csNotComposing)
{
StartComposing(c_csComposeChat, &m_chsChat);
m_pchsCurrent->SetRecipient(CHAT_FRIENDLY_SECTOR, pcluster->GetObjectID(), pcluster);
UpdateComposedChat();
}
else
{
if (m_csComposeState != c_csComposeCommand)
m_csComposeState = c_csComposeCommand;
if ((m_pchsCurrent->m_ctRecipient == CHAT_INDIVIDUAL) && m_pchsCurrent->m_pbaseRecipient->GetMission())
{
IshipIGC* pship = (IshipIGC*)(IbaseIGC*)(m_pchsCurrent->m_pbaseRecipient);
if (pship->GetPilotType() == c_ptBuilder)
{
AbilityBitMask abmOrders = pship->GetOrdersABM();
if (abmOrders != c_aabmBuildable)
{
ImodelIGC* pmodel = FindTarget(pship,
c_ttNeutral | c_ttAsteroid | c_ttLeastTargeted,
NULL, pcluster, &(Vector::GetZero()), NULL,
abmOrders);
if (pmodel)
{
SetVerb(c_cidBuild);
SetChatObject(pmodel);
SendChat();
return;
}
}
}
}
SetVerb(c_cidGoto);
DataBuoyIGC db;
db.position = Vector(0, 0, 0);
db.clusterID = pcluster->GetObjectID();
db.type = c_buoyCluster;
IbuoyIGC* b = (IbuoyIGC*)(trekClient.m_pCoreIGC->CreateObject(trekClient.m_now, OT_buoy, &db, sizeof(db)));
assert (b);
SetChatObject(b);
SendChat();
b->Release();
}
}
void PickShip(IshipIGC* pship)
{
assert(pship);
if (m_csComposeState == c_csNotComposing)
{
StartComposing(c_csComposeMouseCommand, &m_chsCommand);
}
m_pchsCurrent->SetRecipient(CHAT_INDIVIDUAL, pship->GetObjectID(), pship);
UpdateComposedChat();
}
bool IsComposingCommand()
{
return (m_csComposeState == c_csComposeMouseCommand || m_csComposeState == c_csComposeCommand);
}
IbaseIGC* GetPickedObject (void)
{
return m_pchsCurrent->m_pbaseRecipient;
}
ImodelIGC* ResolvePick(IclusterIGC* pcluster, const Point& pointPick, int button)
{
CommandID cid = (m_csComposeState == c_csComposeCommand) ? m_cidVerb : c_cidDefault;
ChatSubject* pchs = (m_csComposeState == c_csNotComposing) ? &m_chsCommand : m_pchsCurrent;
Rect rectImage = GetWindow()->GetViewport()->GetViewRect()->GetValue();
Point point = pointPick - rectImage.Center();
ImodelIGC* pmodelMin = NULL;
float distanceMin = FLT_MAX;
for (ModelLinkIGC* pml = pcluster->GetPickableModels()->first(); (pml != NULL); pml = pml->next())
{
ImodelIGC* pmodel = pml->data();
if (pmodel->GetVisibleF())
{
bool bLegal;
if (button != 1)
bLegal = (pmodel->GetObjectType() == OT_ship) &&
(pmodel->GetSide() == trekClient.GetSide());
else
bLegal = false;
if ((button != 0) && (!bLegal))
bLegal = pchs->LegalCommand(cid, pmodel);
if (bLegal)
{
ThingSite* psite = pmodel->GetThingSite();
if (psite)
{
const Point& pxy = psite->GetScreenPosition();
float r = psite->GetScreenRadius();
if ((pxy.X() + r >= point.X()) && (pxy.X() - r <= point.X()) &&
(pxy.Y() + r >= point.Y()) && (pxy.Y() - r <= point.Y()))
{
float dx = pxy.X() - point.X();
float dy = pxy.Y() - point.Y();
float d = dx*dx + dy*dy;
if (d <= distanceMin)
{
pmodelMin = pmodel;
distanceMin = d;
}
}
}
}
}
}
return pmodelMin;
}
void PickObject(IclusterIGC* pcluster, const Point& pointPick, int button)
{
ImodelIGC* pmodelMin = ResolvePick(pcluster, pointPick, button);
bool goToObject = true;
if ( ( ( m_pointMouseStart.X() - m_pointMouseStop.X() ) * ( m_pointMouseStart.X() - m_pointMouseStop.X() ) )+
( ( m_pointMouseStart.Y() - m_pointMouseStop.Y() ) * ( m_pointMouseStart.Y() - m_pointMouseStop.Y() ) ) > 6000 )
goToObject = false;
if (pmodelMin && goToObject) {
if (m_csComposeState != c_csComposeCommand)
{
if (m_csComposeState == c_csNotComposing)
StartComposing(c_csComposeMouseCommand, &m_chsCommand);
else
m_csComposeState = c_csComposeCommand;
SetVerb(c_cidDefault);
}
SetChatObject(pmodelMin);
SendChat();
}
else if (m_bRecipientVisible)
{
if ((m_csComposeState != c_csComposeCommand) ||
(m_cidVerb == c_cidGoto) ||
((m_cidVerb == c_cidBuild) && m_pchsCurrent->ContainsLayer()))
{
if (m_csComposeState != c_csComposeCommand)
{
if (m_csComposeState == c_csNotComposing)
StartComposing(c_csComposeMouseCommand, &m_chsCommand);
else
m_csComposeState = c_csComposeCommand;
SetVerb(c_cidDefault);
}
DataBuoyIGC db;
UpdatePick3D();
db.position = m_positionStop;
db.clusterID = trekClient.GetCluster()->GetObjectID();
db.type = c_buoyWaypoint;
IbuoyIGC* b = (IbuoyIGC*)(trekClient.m_pCoreIGC->CreateObject(trekClient.m_now, OT_buoy, &db, sizeof(db)));
assert (b);
SetChatObject(b);
SendChat();
b->Release();
}
}
else if (button == 0)
{
QuitComposing();
}
}
MouseResult Button(IInputProvider* pprovider, const Point& point, int button, bool bCaptured, bool bInside, bool bDown)
{
MouseResult rc = MouseResultHit();
IclusterIGC* pcluster = trekClient.GetCluster();
if (pcluster && (m_csComposeState != c_csComposeShell))
{
if (bDown)
{
rc = MouseResultCapture();
m_pointMouseStart = m_pointMouseStop = point;
{
Camera* pcamera = GetWindow()->GetCamera();
Rect rectImage = GetWindow()->GetViewport()->GetViewRect()->GetValue();
float halfwidth = (0.5f * rectImage.XSize());
const Vector& positionCamera = pcamera->GetPosition();
{
Point pointStart = m_pointMouseStart - rectImage.Center();
Vector directionStart = pcamera->TransformImageToDirection(pointStart / halfwidth);
float t = positionCamera.z / directionStart.z;
m_positionStart = positionCamera - t * directionStart;
}
}
if (button)
m_maskMouseState |= c_maskMouseRightDown;
else
m_maskMouseState |= c_maskMouseLeftDown;
}
else if ((m_maskMouseState & (c_maskMouseLeftDown << button)) != 0)
{
if (button)
{
m_maskMouseState &= ~c_maskMouseRightDown;
PickObject(pcluster, point, 1);
}
else
{
m_maskMouseState &= ~c_maskMouseLeftDown;
if (m_csComposeState == c_csComposeCommand)
PickObject(pcluster, point, 0);
else if (LegalRectangle(m_pointMouseStart, m_pointMouseStop))
{
ShipListIGC ships;
float xMin;
float xMax;
if (m_pointMouseStart.X() < m_pointMouseStop.X())
{
xMin = m_pointMouseStart.X();
xMax = m_pointMouseStop.X();
}
else
{
xMin = m_pointMouseStop.X();
xMax = m_pointMouseStart.X();
}
float yMin;
float yMax;
if (m_pointMouseStart.Y() < m_pointMouseStop.Y())
{
yMin = m_pointMouseStart.Y();
yMax = m_pointMouseStop.Y();
}
else
{
yMin = m_pointMouseStop.Y();
yMax = m_pointMouseStart.Y();
}
Rect rectImage = GetWindow()->GetViewport()->GetViewRect()->GetValue();
Point pointCenter = rectImage.Center();
xMin -= pointCenter.X();
xMax -= pointCenter.X();
yMin -= pointCenter.Y();
yMax -= pointCenter.Y();
IsideIGC* pside = trekClient.GetShip()->GetSide();
for (ShipLinkIGC* psl = pcluster->GetShips()->first(); (psl != NULL); psl = psl->next())
{
IshipIGC* pship = psl->data();
if ((pship->GetSide() == pside) && pship->GetVisibleF())
{
ThingSite* psite = pship->GetThingSite();
if (psite)
{
const Point& pxy = psite->GetScreenPosition();
float r = psite->GetScreenRadius();
if ((pxy.X() + r >= xMin) && (pxy.X() - r <= xMax) &&
(pxy.Y() + r >= yMin) && (pxy.Y() - r <= yMax))
{
ships.last(pship);
}
}
}
}
if (ships.n() != 0)
{
if (m_csComposeState == c_csNotComposing)
StartComposing(c_csComposeMouseCommand, &m_chsCommand);
m_pchsCurrent->SetRecipient(CHAT_GROUP, NA, NULL, &ships);
UpdateComposedChat();
}
else
{
m_pchsCurrent->SetRecipient(CHAT_NOSELECTION, NA, NULL);
QuitComposing();
}
}
else
{
IshipIGC* pship = PickShip(pcluster, point);
if (pship)
{
if (m_csComposeState == c_csNotComposing)
{
StartComposing(c_csComposeMouseCommand, &m_chsCommand);
m_pchsCurrent->SetRecipient(CHAT_INDIVIDUAL, pship->GetObjectID(), pship);
}
else if (GetKeyState(VK_SHIFT) & 0x8000)
{
m_pchsCurrent->ToggleSubject(pship);
}
else
{
m_pchsCurrent->SetRecipient(CHAT_INDIVIDUAL, pship->GetObjectID(), pship);
}
UpdateComposedChat();
}
else
{
QuitComposing();
}
}
}
if (!m_maskMouseState)
rc = MouseResultRelease();
}
}
return rc;
}
void MouseMove(IInputProvider* pprovider, const Point& point, bool bCaptured, bool bInside)
{
m_pointMouseStop = point;
}
void MouseEnter(IInputProvider* pprovider, const Point& point)
{
m_bMouseIn = true;
}
void MouseLeave(IInputProvider* pprovider)
{
GetWindow()->SetCursor(AWF_CURSOR_DEFAULT);
m_bMouseIn = false;
}
void RenderDropLine(Context* pcontext)
{
if ((((m_csComposeState != c_csComposeCommand) && (m_maskMouseState & c_maskMouseRightDown)) ||
((m_csComposeState == c_csComposeCommand) && m_maskMouseState &&
((m_cidVerb == c_cidGoto) || ((m_cidVerb == c_cidBuild) && m_pchsCurrent->ContainsLayer())))) &&
LegalRectangle(m_pointMouseStart, m_pointMouseStop))
{
UpdatePick3D();
TVector<VertexL> vertices;
TVector<WORD> indices;
const Color& color = m_positionStop.Z() > 0.0 ? CommandGeo::s_colorDropLineUp : CommandGeo::s_colorDropLineDown;
indices.PushEnd(0);
vertices.PushEnd(VertexL(m_positionStart.X(),
m_positionStart.Y(),
m_positionStart.Z(),
color.R(),
color.G(),
color.B(),
1,
0,
0));
indices.PushEnd(1);
vertices.PushEnd(VertexL(m_positionStop.X(),
m_positionStop.Y(),
m_positionStop.Z(),
color.R(),
color.G(),
color.B(),
1,
0,
0));
pcontext->DrawLines(vertices, indices);
}
}
bool DrawSelectionBox(void) const
{
return (m_maskMouseState & c_maskMouseLeftDown) && (m_csComposeState != c_csComposeCommand) &&
LegalRectangle(m_pointMouseStart, m_pointMouseStop);
}
void Render(Context* pcontext)
{
if (m_bMouseIn)
{
IclusterIGC* pcluster = trekClient.GetCluster();
if (pcluster)
{
if (DrawSelectionBox())
{
pcontext->DrawRectangle(Rect(m_pointMouseStart, m_pointMouseStop), Color::White());
}
const char* pszCursor = AWF_CURSOR_DEFAULT;
{
ImodelIGC* pmodelPick = ResolvePick(pcluster, m_pointMouseStop, -1);
if (pmodelPick)
{
IsideIGC* psidePick = pmodelPick->GetSide();
bool bFriendly = (psidePick == trekClient.GetSide());
if (bFriendly && (pmodelPick->GetObjectType() == OT_ship))
{
pszCursor = AWF_CURSOR_SELECT;
}
else
{
CommandID cid;
if (m_csComposeState == c_csComposeCommand)
{
assert (m_pchsCurrent->LegalCommand(m_cidVerb, pmodelPick));
cid = m_cidVerb;
}
else if (m_pchsCurrent->m_ctRecipient == CHAT_INDIVIDUAL)
{
IshipIGC* pship = (IshipIGC*)(IbaseIGC*)(m_pchsCurrent->m_pbaseRecipient);
cid = pship->GetDefaultOrder(pmodelPick);
}
else
cid = c_cidDefault;
if (cid >= c_cidDefault)
pszCursor = c_cdAllCommands[cid].szVerb;
else
pszCursor = AWF_CURSOR_DEFAULT;
}
}
}
GetWindow()->SetCursor(pszCursor);
}
}
}
bool IsTakingKeystrokes()
{
return (m_csComposeState > c_csComposeMouseCommand);
}
const ShipListIGC* GetSubjects(void) const
{
return (m_csComposeState != c_csNotComposing) &&
(m_csComposeState != c_csComposeShell)
? &(m_pchsCurrent->m_shipsSubject)
: NULL;
}
bool OnChar(const KeyState& ks)
{
if (m_csComposeState > c_csComposeMouseCommand)
{
trekClient.PlaySoundEffect(chatKeySound);
if (ks.bControl && (m_csComposeState != c_csComposeCommand) && m_strTypedText.IsEmpty())
{
for (CommandID cid = c_cidAttack; (cid < c_cidMax); cid++)
{
if (ks.vk == (c_cdAllCommands[cid].szVerb[0] - 96))
{
SetComposeState(c_csComposeCommand);
SetVerb(cid);
SetChatObject(NULL);
UpdateComposedChat();
break;
}
}
}
else
{
switch (ks.vk)
{
case VK_RETURN:
if (m_strTypedText.IsEmpty())
{
QuitComposing();
}
else
{
SendChat();
}
break;
case VK_ESCAPE:
if (m_csComposeState == c_csComposeCommand)
{
m_strTypedText.SetEmpty();
SetComposeState(c_csComposeChat);
UpdateComposedChat();
}
else
QuitComposing();
break;
case VK_BACK:
OnBackspace();
break;
case VK_TAB:
OnTab();
break;
case '~':
case '`':
QuitComposing();
GetWindow()->OpenMainQuickChatMenu();
break;
case '!':
{
if ((m_csComposeState == c_csComposeChat) && m_strTypedText.IsEmpty())
{
m_strTypedText = ZString("!");
SetComposeState(c_csComposeShell);
UpdateComposedChat();
break;
}
}
default:
OnPrintable(ks.vk);
UpdateComposedChat();
break;
}
}
}
return true;
}
void StartChat()
{
trekClient.PlaySoundEffect(chatKeySound);
if (m_csComposeState == c_csNotComposing)
StartComposing(c_csComposeChat, &m_chsChat);
else
SetComposeState(c_csComposeChat);
UpdateComposedChat();
}
int MatchName(const char* pszText, const char* pszName)
{
assert (*pszText != '\0');
while (true)
{
if (*pszText == '\0')
{
return strlen(pszName);
}
else if (tolower(*pszText) != tolower(*pszName))
{
return c_badMatch;
}
pszText++;
pszName++;
}
}
void SetChatObject(ImodelIGC* pmodel)
{
if (m_pmodelTarget && (m_pmodelTarget->GetObjectType() == OT_buoy))
((IbuoyIGC*)(ImodelIGC*)m_pmodelTarget)->ReleaseConsumer();
m_pmodelTarget = pmodel;
if (pmodel && (pmodel->GetObjectType() == OT_buoy))
((IbuoyIGC*)pmodel)->AddConsumer();
}
void MatchTarget(void)
{
SetChatObject(NULL);
const char* pszText = m_strTypedText;
if (*pszText == '\0')
return;
ImodelIGC* pmodelBest;
int scoreBest = c_badMatch; {
for (ShipLinkIGC* psl = trekClient.m_pCoreIGC->GetShips()->first();
(psl != NULL);
psl = psl->next())
{
IshipIGC* pship = psl->data();
if (m_pchsCurrent->LegalCommand(m_cidVerb, pship))
{
int score = MatchName(pszText, pship->GetName());
if (score < scoreBest)
{
pmodelBest = pship;
scoreBest = score;
}
}
}
}
if (scoreBest > 0)
{
for (StationLinkIGC* psl = trekClient.m_pCoreIGC->GetStations()->first();
(psl != NULL);
psl = psl->next())
{
IstationIGC* pstation = psl->data();
if (m_pchsCurrent->LegalCommand(m_cidVerb, pstation))
{
int score = MatchName(pszText, pstation->GetName());
if (score < scoreBest)
{
pmodelBest = pstation;
scoreBest = score;
}
}
}
if (scoreBest > 0)
{
IclusterIGC* pcluster = trekClient.GetCluster();
if (pcluster)
{
for (ModelLinkIGC* pml = pcluster->GetPickableModels()->first();
(pml != NULL);
pml = pml->next())
{
ImodelIGC* pmodel = pml->data();
if (m_pchsCurrent->LegalCommand(m_cidVerb, pmodel))
{
int score = MatchName(pszText, GetModelName(pmodel));
if (score < scoreBest)
{
pmodelBest = pmodel;
scoreBest = score;
}
}
}
}
if (scoreBest > 0)
{
if (m_pchsCurrent->LegalCommand(m_cidVerb, trekClient.GetShip()))
{
int score = MatchName(pszText, "me");
if (score < scoreBest)
{
pmodelBest = trekClient.GetShip();
scoreBest = score;
}
}
if (scoreBest > 0)
{
IclusterIGC* pcluster = NULL;
for (ClusterLinkIGC* pcl = trekClient.m_pCoreIGC->GetClusters()->first();
(pcl != NULL);
pcl = pcl->next())
{
IclusterIGC* pc = pcl->data();
int score = MatchName(pszText, pc->GetName());
if (score < scoreBest)
{
pcluster = pc;
scoreBest = score;
}
}
if (pcluster)
{
DataBuoyIGC db;
db.position = Vector(0, 0, 0);
db.clusterID = pcluster->GetObjectID();
db.type = c_buoyCluster;
pmodelBest = (IbuoyIGC*)(trekClient.m_pCoreIGC->CreateObject(trekClient.m_now, OT_buoy, &db, sizeof(db)));
assert (pmodelBest);
pmodelBest->Release();
}
}
}
}
}
if (scoreBest != c_badMatch)
SetChatObject(pmodelBest);
}
void OnBackspace()
{
assert (m_csComposeState > c_csComposeMouseCommand);
if (m_strTypedText.GetLength() != 0)
{
if ((m_csComposeState == c_csComposeShell) && (m_strTypedText.GetLength() == 1))
{
m_strTypedText.SetEmpty();
SetComposeState(c_csComposeChat);
}
else
{
m_strTypedText = m_strTypedText.LeftOf(1);
if (m_csComposeState == c_csComposeCommand)
MatchTarget();
}
UpdateComposedChat();
}
else if (m_csComposeState == c_csComposeCommand)
{
SetComposeState(c_csComposeChat);
SetChatObject(NULL);
}
}
void CycleChatTarget(void)
{
if (m_csComposeState != c_csNotComposing)
{
switch (m_pchsCurrent->m_ctRecipient)
{
case CHAT_WING:
{
if (m_csComposeState != c_csComposeChat)
{
m_pchsCurrent->SetRecipient(CHAT_INDIVIDUAL, NA, trekClient.GetShip());
break;
}
}
case CHAT_INDIVIDUAL:
{
if (trekClient.GetShip()->GetSourceShip()->GetChildShips()->n() != 0)
{
m_pchsCurrent->SetRecipient(CHAT_SHIP, NA, NULL);
break;
}
}
case CHAT_SHIP:
{
m_pchsCurrent->SetRecipient(CHAT_FRIENDLY_SECTOR, NA, NULL);
if (m_pchsCurrent->m_shipsSubject.n() != 0)
break;
}
case CHAT_FRIENDLY_SECTOR:
{
m_pchsCurrent->SetRecipient(CHAT_TEAM, NA, NULL);
}
break;
case CHAT_TEAM:
{
m_pchsCurrent->SetRecipient(CHAT_EVERYONE, NA, NULL);
}
break;
default:
{
m_pchsCurrent->SetRecipient(CHAT_WING, NA, NULL);
}
}
}
}
void OnTab()
{
assert (m_csComposeState > c_csComposeMouseCommand);
const char* pcc = m_strTypedText;
if ((*pcc == '\0') || (*pcc == ' '))
{
CycleChatTarget();
}
else
{
if (MatchName(pcc, "admin") == 0)
{
SetChatObject(NULL);
m_strTypedText.SetEmpty();
m_pchsCurrent->SetRecipient(CHAT_ADMIN, NA, NULL);
}
else
{
int scoreBest = c_badMatch;
ChatTarget ct = CHAT_NOSELECTION;
ObjectID oidRecipient;
IbaseIGC* pbaseRecipient;
{
for (WingID i = 0;
(i < c_widMax);
i++)
{
int score = MatchName(pcc, c_pszWingName[i]);
if (score < scoreBest)
{
scoreBest = score;
ct = CHAT_WING;
oidRecipient = i;
pbaseRecipient = NULL;
}
}
}
if (scoreBest > 0)
{
for (ClusterLinkIGC* pcl = trekClient.m_pCoreIGC->GetClusters()->first();
(pcl != NULL);
pcl = pcl->next())
{
IclusterIGC* pcluster = pcl->data();
int score = MatchName(pcc, pcluster->GetName());
if (score < scoreBest)
{
scoreBest = score;
ct = CHAT_FRIENDLY_SECTOR;
oidRecipient = pcluster->GetObjectID();
pbaseRecipient = pcluster;
}
}
if (scoreBest > 0)
{
IsideIGC* pside = trekClient.GetSide();
int score = MatchName(pcc, pside->GetName());
if (score < scoreBest)
{
scoreBest = score;
ct = CHAT_TEAM;
oidRecipient = pside->GetObjectID();
pbaseRecipient = pside;
}
if (scoreBest > 0)
{
int score = MatchName(pcc, "me");
if (score < scoreBest)
{
scoreBest = score;
ct = CHAT_INDIVIDUAL;
oidRecipient = trekClient.GetShipID();
pbaseRecipient = trekClient.GetShip();
}
if (scoreBest > 0)
{
int score = MatchName(pcc, "all");
if (score < scoreBest)
{
scoreBest = score;
ct = CHAT_EVERYONE;
oidRecipient = NA;
pbaseRecipient = NULL;
}
if (scoreBest > 0)
{
if (trekClient.GetShip()->GetSourceShip()->GetChildShips()->n() != 0)
{
int score = MatchName(pcc, "ship");
if (score < scoreBest)
{
scoreBest = score;
ct = CHAT_SHIP;
oidRecipient = NA;
pbaseRecipient = NULL;
}
}
if (scoreBest > 0)
{
IsideIGC* pside = trekClient.GetSide();
for (ShipLinkIGC* psl = pside->GetShips()->first();
(psl != NULL);
psl = psl->next())
{
IshipIGC* pship = psl->data();
int score = MatchName(pcc, pship->GetName());
if (score < scoreBest)
{
scoreBest = score;
ct = CHAT_INDIVIDUAL;
oidRecipient = pship->GetObjectID();
pbaseRecipient = pship;
}
}
if (scoreBest > 0)
{
IsideIGC* psideMine = trekClient.GetSide();
for (ShipLinkIGC* psl = trekClient.m_pCoreIGC->GetShips()->first();
(psl != NULL);
psl = psl->next())
{
IshipIGC* pship = psl->data();
if ((pship->GetSide() != psideMine)&& (pship->GetPilotType()== c_ptPlayer ))
{
int score = MatchName(pcc, pship->GetName());
if ((ct == CHAT_INDIVIDUAL)
? (score == 0)
: (score < scoreBest))
{
scoreBest = score;
ct = CHAT_INDIVIDUAL;
oidRecipient = pship->GetObjectID();
pbaseRecipient = pship;
}
}
}
}
if (scoreBest > 0)
{
for (CommandID cid = c_cidAttack; (cid < c_cidMax); cid++)
{
if (MatchName(pcc, c_cdAllCommands[cid].szVerb) == 0)
{
SetComposeState(c_csComposeCommand);
SetVerb(cid);
SetChatObject(NULL);
m_strTypedText.SetEmpty();
UpdateComposedChat();
return;
}
}
}
}
}
}
}
}
}
if (scoreBest != c_badMatch)
{
SetChatObject(NULL);
m_strTypedText.SetEmpty();
m_pchsCurrent->SetRecipient(ct, oidRecipient, pbaseRecipient);
}
else
{
CycleChatTarget();
}
}
}
UpdateComposedChat();
}
void OnPrintable(char ch)
{
assert (m_csComposeState > c_csComposeMouseCommand);
if (m_strTypedText.GetLength() < 255)
{
m_strTypedText += ZString(ch, 1);
}
if (m_csComposeState == c_csComposeCommand)
{
MatchTarget();
}
}
};
class DisplayImage : public WrapImage, public IEventSink
{
protected:
TRef<TransformImage> m_pTransformImage;
TRef<AnimatedTranslateTransform2> m_pTransform;
TRef<IEventSink> m_peventSinkOffScreen;
bool m_bVisible;
bool m_bUndetectable;
OverlayMask m_omVisible;
protected:
Number* GetTime()
{
return Number::Cast(GetChild(1));
}
public:
DisplayImage(
Number* ptime,
RectValue* prect,
Image* pimage,
int side,
const Point& ptOffScreen,
const Point& ptOnScreen,
float dtimeSlide,
OverlayMask omVisible,
bool bUndetectable
) :
WrapImage(Image::GetEmpty(), ptime),
m_bVisible(false),
m_omVisible(omVisible),
m_bUndetectable(bUndetectable)
{
m_peventSinkOffScreen = IEventSink::CreateDelegate(this);
m_pTransformImage = new TransformImage(
pimage,
m_pTransform =
AnimatedTranslateTransform2::Create(
ptime,
prect,
side,
ptOffScreen,
ptOnScreen,
dtimeSlide
)
);
m_pTransform->AddSink(m_peventSinkOffScreen);
}
~DisplayImage(void)
{
m_pTransform->RemoveSink(m_peventSinkOffScreen);
}
void SetOverlayFlags(OverlayMask om)
{
Show( (om & m_omVisible) != 0);
}
void Show(bool bVisible)
{
if (m_bVisible != bVisible)
{
if (bVisible)
{
SetImage(m_pTransformImage);
m_pTransform->MoveEnd();
}
else
{
m_pTransform->MoveStart();
}
m_bVisible = bVisible;
}
}
bool OnEvent(IEventSource* pevent)
{
SetImage(Image::GetEmpty());
return true;
}
MouseResult HitTest(IInputProvider* pprovider, const Point& point, bool bCaptured)
{
MouseResult result = WrapImage::HitTest(pprovider, point, bCaptured);
if (!m_bVisible || m_bUndetectable) {
result.Clear(MouseResultHit());
}
return result;
}
};
ConsolePickImage::ConsolePickImage(Viewport* pviewport,
ConsoleDataImpl* pconsoleData
)
:
Image(),
m_pviewport(pviewport),
m_pconsoleData(pconsoleData),
m_mouseresult(MouseResultHit())
{
assert (m_pconsoleData);
}
void ConsolePickImage::SetHitTest(MouseResult mr)
{
m_mouseresult = mr;
}
MouseResult ConsolePickImage::HitTest(IInputProvider* pprovider, const Point& point, bool bCaptured)
{
return m_mouseresult;
}
MouseResult ConsolePickImage::Button(IInputProvider* pprovider, const Point& point, int button, bool bCaptured, bool bInside, bool bDown)
{
return m_pconsoleData->Button(pprovider, point, button, bCaptured, bInside, bDown);
}
void ConsolePickImage::MouseMove(IInputProvider* pprovider, const Point& point, bool bCaptured, bool bInside)
{
m_pconsoleData->MouseMove(pprovider, point, bCaptured, bInside);
}
void ConsolePickImage::MouseEnter(IInputProvider* pprovider, const Point& point)
{
m_pconsoleData->MouseEnter(pprovider, point);
}
void ConsolePickImage::MouseLeave(IInputProvider* pprovider)
{
m_pconsoleData->MouseLeave(pprovider);
}
class ConsoleImageImpl : public ConsoleImage
{
private:
TRef<ConsoleDataImpl> m_pconsoleData;
TVector<TRef<DisplayImage> > m_vpdisplayImages;
TRef<GroupImage> m_pgroupDisplays;
TRef<IObject> m_pobjectTeamPane;
TRef<IObject> m_pobjectExpandedTeamPane;
TRef<IObject> m_pobjectTeleportPane;
TRef<GameStateContainer> m_pgsc;
TRef<ComboPane> m_pcomboCluster;
TRef<ButtonPane> m_pbuttonBack;
TRef<ConsolePickImage> m_pickimage;
char m_szFileName[c_cbFileName];
public:
ConsoleImageImpl(Engine* pengine, Viewport* pviewport) :
ConsoleImage(pengine, pviewport)
{
m_szFileName[0] = '\0';
SetDisplayMDL("dialog");
}
~ConsoleImageImpl(void)
{
GetWindow()->SetChatListPane(NULL);
}
void StartChat()
{
m_pconsoleData->StartChat();
}
void StartQuickChat(ChatTarget ctRecipient,
ObjectID oidRecipient,
IbaseIGC* pbaseRecipient)
{
m_pconsoleData->StartQuickChat(ctRecipient, oidRecipient, pbaseRecipient);
}
void SendQuickChat(int idSonicChat, int ttMask, CommandID cid, AbilityBitMask aabm)
{
m_pconsoleData->SendQuickChat(idSonicChat, ttMask, cid, aabm);
}
void QuitComposing(void)
{
m_pconsoleData->QuitComposing();
}
void RenderDropLine(Context* pcontext)
{
if (m_pconsoleData)
m_pconsoleData->RenderDropLine(pcontext);
}
bool DrawSelectionBox(void) const
{
return m_pconsoleData ? m_pconsoleData->DrawSelectionBox() : false;
}
void Render(Context* pcontext)
{
pcontext->PushState();
ConsoleImage::Render(pcontext);
pcontext->PopState();
if (m_pconsoleData)
m_pconsoleData->Render(pcontext);
}
void Update(Time now)
{
m_pconsoleData->Update(now);
}
void SetOverlayFlags(OverlayMask om)
{
if (GetOverlayFlags() != om)
{
trekClient.PlaySoundEffect(paneSlideSound);
switch (GetWindow()->GetViewMode())
{
case TrekWindow::vmHangar:
case TrekWindow::vmLoadout:
case TrekWindow::vmOverride:
m_pickimage->SetHitTest(MouseResult());
break;
default:
m_pickimage->SetHitTest(MouseResultHit());
break;
}
}
for (short i = 0; i < m_vpdisplayImages.GetCount(); i++)
m_vpdisplayImages[i]->SetOverlayFlags(om);
m_pconsoleData->SetOverlayFlags(om);
}
OverlayMask GetOverlayFlags(void) const
{
return m_pconsoleData ? m_pconsoleData->GetOverlayFlags() : 0;
}
void OnSwitchViewMode()
{
m_pconsoleData->OnSwitchViewMode();
}
ConsoleData* GetConsoleData()
{
return m_pconsoleData;
}
bool IsComposing()
{
return m_pconsoleData->IsTakingKeystrokes();
}
bool OnChar(const KeyState& ks)
{
return m_pconsoleData->OnChar(ks);
}
const ShipListIGC* GetSubjects(void) const
{
return m_pconsoleData->GetSubjects();
}
void CycleChatTarget(void)
{
m_pconsoleData->CycleChatTarget();
m_pconsoleData->UpdateComposedChat();
}
void SetInRange(bool bInRange)
{
m_pconsoleData->SetInRange(bInRange);
}
void SetDisplayMDL(const char* pszFileName)
{
if (strcmp(pszFileName, m_szFileName) == 0)
return;
assert (strlen(pszFileName) < c_cbFileName);
strcpy(m_szFileName, pszFileName);
OverlayMask om = GetOverlayFlags();
m_pconsoleData = NULL;
m_vpdisplayImages = NULL;
m_pgroupDisplays = NULL;
m_pobjectTeamPane = NULL;
m_pobjectExpandedTeamPane = NULL;
m_pobjectTeleportPane = NULL;
m_pcomboCluster = NULL;
m_pbuttonBack = NULL;
m_pickimage = NULL;
m_pgroupDisplays = new GroupImage();
m_pconsoleData = new ConsoleDataImpl(this->GetViewport(), pszFileName);
TRef<INameSpace> pnsDisplays = m_pconsoleData->GetNameSpace();
CastTo(m_pgsc, pnsDisplays->FindMember("gameStateContainer"));
CastTo(m_pbuttonBack, pnsDisplays->FindMember("backButtonPane"));
#if _MSC_VER >= 1310
m_pconsoleData->AddEventTarget(&ConsoleDataImpl::OnBackButton, m_pbuttonBack->GetEventSource());
#else
m_pconsoleData->AddEventTarget(m_pconsoleData->OnBackButton, m_pbuttonBack->GetEventSource());
#endif
IObjectList* plistDisplays; CastTo(plistDisplays, pnsDisplays->FindMember("dialogs"));
plistDisplays->GetFirst();
while (plistDisplays->GetCurrent() != NULL)
{
TRef<IObjectPair> ppair; CastTo(ppair, plistDisplays->GetCurrent());
TRef<Image> pimage; CastTo(pimage, (Value*)ppair->GetNth(0));
int side = (int)GetNumber(ppair->GetNth(1));
TRef<PointValue> ppointOffScreen = PointValue::Cast(ppair->GetNth(2));
TRef<PointValue> ppointOnScreen = PointValue::Cast(ppair->GetNth(3));
float dtimeSlide = GetNumber(ppair->GetNth(4));
OverlayMask cmVisible = (OverlayMask)GetNumber(ppair->GetNth(5));
TRef<Boolean> pbooleanUndetectable = Boolean::Cast(ppair->GetLastNth(6));
CreateDisplayImage(
pimage,
side,
ppointOffScreen->GetValue(),
ppointOnScreen->GetValue(),
dtimeSlide,
cmVisible,
pbooleanUndetectable->GetValue()
);
plistDisplays->GetNext();
}
m_pobjectTeleportPane = CreateTeleportPane(GetModeler());
m_pobjectTeamPane = CreateTeamPane(GetModeler());
m_pobjectExpandedTeamPane = CreateExpandedTeamPane(GetModeler(), m_pobjectTeamPane);
SetImage(m_pgroupDisplays);
SetOverlayFlags(om);
m_pickimage = new ConsolePickImage(this->GetViewport(), m_pconsoleData);
m_pgroupDisplays->AddImage(m_pickimage);
ChatListPane* pchatListPane;
CastTo(pchatListPane, (Pane*)pnsDisplays->FindMember("chatListPane"));
GetWindow()->SetChatListPane(pchatListPane);
GetModeler()->UnloadNameSpace(pszFileName);
}
private:
TRef<GameStateContainer> GetGameStateContainer()
{
return m_pgsc;
}
TRef<Value> CreateDisplayImage(
Image* pimage,
int side,
const Point& ptOffScreen,
const Point& ptOnScreen,
float dtimeSlide,
OverlayMask omVisible,
bool bUndetectable
) {
TRef<DisplayImage> pdisplayImage =
new DisplayImage(
GetWindow()->GetTime(),
GetWindow()->GetScreenRectValue(),
pimage,
side,
ptOffScreen,
ptOnScreen,
dtimeSlide,
omVisible,
bUndetectable
);
m_vpdisplayImages.PushEnd(pdisplayImage);
m_pgroupDisplays->AddImage(pdisplayImage);
return pdisplayImage;
}
};
TRef<ConsoleImage> ConsoleImage::Create(Engine* pengine, Viewport* pviewport)
{
return new ConsoleImageImpl(pengine, pviewport);
}
void AddChildren(Pane* ppaneParent, ObjectStack& stack)
{
TRef<IObjectList> plist; CastTo(plist, (IObject*)stack.Pop());
plist->GetFirst();
while (plist->GetCurrent() != NULL) {
IObjectPair* ppair; CastTo(ppair, plist->GetCurrent());
TRef<Pane> ppaneChild; CastTo(ppaneChild, ppair->GetFirst() );
TRef<PointValue> ppointChild; CastTo(ppointChild, ppair->GetSecond() );
ppaneParent->InsertAtBottom(ppaneChild);
ppaneChild->SetOffset(
WinPoint(
(int)ppointChild->GetValue().X(),
(int)ppointChild->GetValue().Y()
)
);
plist->GetNext();
}
}