123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545 |
- #include "pch.h"
- //////////////////////////////////////////////////////////////////////////////
- //
- // TeleportPane
- //
- //////////////////////////////////////////////////////////////////////////////
- class TeleportPane :
- public IItemEvent::Sink,
- public EventTargetContainer<TeleportPane>,
- public TrekClientEventSink
- {
- protected:
- TRef<ButtonPane> m_pbuttonTeleport;
- TRef<ButtonPane> m_pbuttonBack;
- TRef<ButtonBarPane> m_pbuttonbarDestinations;
- TRef<ListPane> m_plistPaneDestinations;
- TRef<IItemEvent::Source> m_peventDestinations;
- TRef<IItemEvent::Sink> m_psinkDestinations;
- TVector<int> m_viColumns;
- TRef<TListListWrapper<ImodelIGC*> > m_plistDestinations;
- enum
- {
- sortName,
- sortType,
- sortSector,
- } m_sortDestination;
- public:
- class DestinationPainter : public ItemPainter
- {
- const TVector<int>& m_viColumns;
- public:
- DestinationPainter(const TVector<int>& viColumns)
- : m_viColumns(viColumns) {};
- int GetXSize()
- {
- return m_viColumns[3];
- }
- int GetYSize()
- {
- return 14;
- }
- void Paint(ItemID pitemArg, Surface* psurface, bool bSelected, bool bFocus)
- {
- ImodelIGC* pDestination = (ImodelIGC*)pitemArg;
- IshipIGC* pship = NULL;
- IstationIGC* pstation = NULL;
- if (pDestination == NULL || trekClient.MyMission() == NULL)
- return;
- if (pDestination->GetObjectType() == OT_ship)
- {
- CastTo(pship, pDestination);
- }
- else
- {
- assert(pDestination->GetObjectType() == OT_station);
- CastTo(pstation, pDestination);
- }
- // draw the selection bar
- if (bSelected) {
- psurface->FillRect(
- WinRect(0, 0, GetXSize(), GetYSize()),
- Color::Red()
- );
- }
- TRef<IEngineFont> pfont;
- // show the place we currently are in bold
- if (pship && pship == trekClient.GetShip()->GetParentShip()
- || pstation && pstation == trekClient.GetShip()->GetStation())
- {
- pfont = TrekResources::SmallBoldFont();
- }
- else
- {
- pfont = TrekResources::SmallFont();
- }
-
- Color color;
- if (CanKeepCurrentShip(pDestination))
- {
- color = Color::White();
- }
- else
- {
- color = 0.75f * Color::White();
- }
- // draw the name
- psurface->DrawString(
- pfont,
- color,
- WinPoint(0, 0),
- pship ? pship->GetName() : pstation->GetName()
- );
- // draw the ship type (if any)
- if (pship)
- {
- psurface->DrawString(
- pfont,
- color,
- WinPoint(m_viColumns[0], 0),
- HullName(pDestination)
- );
- }
-
- // draw the cluster
- psurface->DrawString(
- pfont,
- color,
- WinPoint(m_viColumns[1] + 2, 0),
- SectorName(pDestination)
- );
- // draw the total number of turrets (if appropriate)
- if (pship && NumTurrets(pship))
- {
- int nNumTurrets = NumTurrets(pship);
- if (nNumTurrets != 0)
- {
- psurface->DrawString(
- pfont,
- color,
- WinPoint(m_viColumns[2] + 2, 0),
- ZString((int)MannedTurrets(pship)) + ZString("/") + ZString(nNumTurrets)
- );
- }
- }
- }
- };
- public:
- TeleportPane(Modeler* pmodeler)
- : m_peventDestinations(NULL), m_sortDestination(sortName)
- {
- TRef<IObject> pobjColumns;
- // a team pane is meaningless without a team
- if (trekClient.MyMission() == NULL)
- return;
- // Load the members from MDL
- TRef<INameSpace> pns = pmodeler->GetNameSpace("teleportpane");
- CastTo(m_pbuttonTeleport, pns->FindMember("teleportTeleportButtonPane"));
- CastTo(m_pbuttonBack, pns->FindMember("teleportBackButtonPane"));
- CastTo(m_plistPaneDestinations, (Pane*)pns->FindMember("teleportPaneDestinationListPane"));
- CastTo(pobjColumns, pns->FindMember("teleportPaneDestinationColumns"));
- CastTo(m_pbuttonbarDestinations, pns->FindMember("teleportPaneDestinationListHeader"));
- //
- // Buttons
- //
- AddEventTarget(OnButtonTeleport, m_pbuttonTeleport->GetEventSource());
- AddEventTarget(OnButtonBack, m_pbuttonBack->GetEventSource());
- AddEventTarget(OnButtonBar, m_pbuttonbarDestinations->GetEventSource());
- //
- // The Destination list
- //
- ParseIntVector(pobjColumns, m_viColumns);
- m_plistPaneDestinations->SetItemPainter(new DestinationPainter(m_viColumns));
- m_peventDestinations = m_plistPaneDestinations->GetSelectionEventSource();
- if (m_psinkDestinations)
- m_peventDestinations->RemoveSink(m_psinkDestinations);
- m_peventDestinations->AddSink(m_psinkDestinations = new IItemEvent::Delegate(this));
- AddEventTarget(OnButtonTeleport, m_plistPaneDestinations->GetDoubleClickEventSource());
- RebuildList();
- }
- ~TeleportPane()
- {
- if (m_peventDestinations)
- {
- m_peventDestinations->RemoveSink(m_psinkDestinations);
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Event handlers
- //
- //////////////////////////////////////////////////////////////////////////////
- bool OnEvent(IItemEvent::Source *pevent, ItemID pitem)
- {
- if (pevent == m_peventDestinations) {
- OnSelectDestination(pitem);
- }
- return true;
- }
- void OnShipStatusChange(PlayerInfo* pPlayer)
- {
- // this might have been someone buying a ship with turrets.
- RebuildList();
- }
- void OnAddPlayer(MissionInfo* pMissionInfo, SideID sideID, PlayerInfo* pPlayerInfo)
- {
- // this might become someone in our list.
- RebuildList();
- }
- void OnDelPlayer(MissionInfo* pMissionInfo, SideID sideID, PlayerInfo* pPlayerInfo, QuitSideReason reason, const char* szMessageParam)
- {
- // this might be someone in our list.
- RebuildList(pPlayerInfo->GetShip());
- }
- void OnStationCaptured(StationID stationID, SideID sideID)
- {
- // this might be or have been one of our stations
- RebuildList();
- }
- void OnTechTreeChanged(SideID sideID)
- {
- if (sideID == trekClient.GetSideID())
- {
- RebuildList();
- }
- }
- void OnModelTerminated(ImodelIGC* pmodel)
- {
- // this might a station being destroyed
- if (pmodel->GetSide() == trekClient.GetSide())
- RebuildList(pmodel);
- }
- void OnDiscoveredStation(IstationIGC* pstation)
- {
- // this might be a new station we have built
- if (pstation->GetSide() == trekClient.GetSide())
- RebuildList();
- }
- bool OnSelectDestination(ItemID pitem)
- {
- return true;
- }
- void OnBoardFailed(IshipIGC* pshipRequestedParent)
- {
- if (trekClient.GetShip()->GetCluster() == NULL)
- {
- if (pshipRequestedParent
- && MannedTurrets(pshipRequestedParent) < NumTurrets(pshipRequestedParent))
- {
- TRef<IMessageBox> pmsgBox = CreateMessageBox(
- "Teleportation canceled - no turret positions were open.");
- trekClient.PlaySoundEffect(noTurretsSound);
- GetWindow()->GetPopupContainer()->OpenPopup(pmsgBox, false);
- }
- else
- {
- TRef<IMessageBox> pmsgBox = CreateMessageBox("Teleportation failed.");
- GetWindow()->GetPopupContainer()->OpenPopup(pmsgBox, false);
- }
- }
- }
- bool OnButtonTeleport()
- {
- ImodelIGC* pDestination = (ImodelIGC*)(m_plistPaneDestinations->GetSelection());
- IstationIGC* pstation = NULL;
- if (pDestination == NULL || trekClient.MyMission() == NULL
- || trekClient.GetShip()->GetCluster() != NULL)
- return true;
- if (pDestination->GetObjectType() == OT_ship)
- {
- // if this is a ship, try boarding it.
- IshipIGC* pship;
- CastTo(pship, pDestination);
- if (trekClient.GetShip()->GetParentShip() != NULL)
- {
- trekClient.DisembarkAndBoard(pship);
- }
- else
- {
- trekClient.BoardShip(pship);
- }
- trekClient.PlaySoundEffect(personalJumpSound);
- }
- else
- {
- // try teleporting to that station
- IstationIGC* pstation;
- CastTo(pstation, pDestination);
- if (trekClient.GetShip()->GetParentShip() != NULL)
- {
- // if they are already there, just get off of the ship
- if (pstation == trekClient.GetShip()->GetParentShip()->GetStation())
- {
- trekClient.BoardShip(NULL);
- }
- else
- {
- trekClient.DisembarkAndTeleport(pstation);
- }
- }
- else
- {
- if (pstation != trekClient.GetShip()->GetStation())
- {
- trekClient.SetMessageType(BaseClient::c_mtGuaranteed);
- BEGIN_PFM_CREATE(trekClient.m_fm, pfmDocked, C, DOCKED)
- END_PFM_CREATE
- pfmDocked->stationID = pstation->GetObjectID();
- trekClient.StartLockDown(
- "Teleporting to " + ZString(pstation->GetName()) + "....",
- BaseClient::lockdownTeleporting);
- }
- }
- }
- // dismiss the teleport pane.
- GetWindow()->TurnOffOverlayFlags(ofTeleportPane);
- return true;
- }
- bool OnButtonBack()
- {
- GetWindow()->TurnOffOverlayFlags(ofTeleportPane);
- return true;
- }
- bool OnButtonBar(int iButton)
- {
- return true;
- }
- static bool CanBoard(IshipIGC* pship)
- {
- PlayerInfo* pPlayer = (PlayerInfo*)pship->GetPrivateData();
- if (pship != trekClient.GetShip()
- && pship->GetSide() == trekClient.GetSide()
- && pPlayer->LastSeenState() == c_ssDocked
- && pship->GetPilotType() >= c_ptPlayer)
- {
- HullID hid = pPlayer->LastSeenShipType();
- assert (hid != NA);
- IhullTypeIGC* pht = trekClient.m_pCoreIGC->GetHullType(hid);
- assert (pht);
- if ((trekClient.GetShip()->GetPilotType() == c_ptCheatPlayer) ||
- (pht->GetMaxFixedWeapons() != pht->GetMaxWeapons()))
- {
- return true;
- }
- }
- return false;
- }
- void RebuildList(ImodelIGC* pmodelExclude = NULL)
- {
- TRef<TListListWrapper<ImodelIGC*> > plistNew = new TListListWrapper<ImodelIGC*>();
- IsideIGC* pside = trekClient.GetSide();
- if (pside && trekClient.GetSideID() != SIDE_TEAMLOBBY)
- {
- for (ShipLinkIGC* pshiplink = pside->GetShips()->first();
- (pshiplink != NULL);
- pshiplink = pshiplink->next())
- {
- IshipIGC* pship = pshiplink->data();
-
- if (pship != pmodelExclude && CanBoard(pship))
- {
- plistNew->PushEnd(pship);
- }
- }
- for (StationLinkIGC* pstationlink = pside->GetStations()->first();
- (pstationlink != NULL);
- pstationlink = pstationlink->next())
- {
- IstationIGC* pstation = pstationlink->data();
-
- if (pstation != pmodelExclude
- && pstation->GetBaseStationType()->HasCapability(c_sabmRestart))
- {
- plistNew->PushEnd(pstation);
- }
- }
- }
- m_plistDestinations = plistNew;
- m_plistPaneDestinations->SetList(m_plistDestinations);
- }
- static ZString HullName(ImodelIGC* pmodel)
- {
- if (pmodel->GetObjectType() == OT_ship)
- {
- PlayerInfo* pPlayer = (PlayerInfo*)((IshipIGC*)pmodel)->GetPrivateData();
- IhullTypeIGC* phull = trekClient.GetCore()->GetHullType(pPlayer->LastSeenShipType());
-
- if (phull == NULL)
- return "<bug>";
- else
- return phull->GetName();
- }
- else
- {
- return "";
- }
- }
- static bool CanKeepCurrentShip(ImodelIGC* pmodel)
- {
- if (pmodel->GetObjectType() == OT_ship)
- {
- // they can keep their ship only if they don't have one or are in a lifepod
- return trekClient.GetShip()->GetParentShip() != NULL
- || trekClient.GetShip()->GetBaseHullType()->HasCapability(c_habmLifepod);
- }
- else
- {
- IstationIGC* pstation;
- CastTo(pstation, pmodel);
- IhullTypeIGC* pht = trekClient.GetShip()->GetBaseHullType();
- // they can keep their current ship if they are already in this station or
- // if the station can build the hull which they currently have.
- return trekClient.GetShip()->GetStation() == pstation
- || pht && pstation->CanBuy(pht);
- }
- }
- static ZString SectorName(ImodelIGC* pmodel)
- {
- IclusterIGC* psector;
- if (pmodel->GetObjectType() == OT_ship)
- {
- PlayerInfo* pplayer = (PlayerInfo*)((IshipIGC*)pmodel)->GetPrivateData();
- psector = trekClient.GetCore()->GetCluster(pplayer->LastSeenSector());
- }
- else
- {
- psector = pmodel->GetCluster();
- }
- if (psector == NULL)
- return "unknown";
- else
- return psector->GetName();
- }
- static int MannedTurrets(IshipIGC* pshipParent)
- {
- // loop through all of the ships on that side and count the ones
- // that are turrets of this.
- int cMannedTurrets = 0;
-
- const ShipListIGC* shipList = pshipParent->GetSide()->GetShips();
- for (const ShipLinkIGC* lShip = shipList->first(); lShip; lShip = lShip->next())
- {
- IshipIGC* pship = lShip->data();
- PlayerInfo* pplayer = (PlayerInfo*)pship->GetPrivateData();
- if (pplayer->LastSeenState() == c_ssTurret)
- {
- PlayerInfo* pplayerParent = trekClient.FindPlayer(pplayer->LastSeenParent());
- if (pplayerParent && pplayerParent->GetShip() == pshipParent)
- cMannedTurrets++;
- }
- }
- return cMannedTurrets;
- }
- static int NumTurrets(IshipIGC* pship)
- {
- PlayerInfo* pPlayer = (PlayerInfo*)pship->GetPrivateData();
- const IhullTypeIGC* pHullType = trekClient.GetCore()->GetHullType(pPlayer->LastSeenShipType());
-
- // if we have a real ship...
- if (pHullType)
- return pHullType->GetMaxWeapons() - pHullType->GetMaxFixedWeapons();
- else
- return 0;
- }
- };
- //////////////////////////////////////////////////////////////////////////////
- //
- // Constructor
- //
- //////////////////////////////////////////////////////////////////////////////
- TRef<IObject> CreateTeleportPane(Modeler* pmodeler)
- {
- return (IItemEvent::Sink*)new TeleportPane(pmodeler);
- }
|