#ifndef _FSMISSION_H_
#define _FSMISSION_H_
#include "pch.h"
inline unsigned char SideMask(SideID sid)
{
assert (sid >= 0);
return (unsigned char)(0x01 << sid);
}
inline unsigned char SideMask(IsideIGC* pside)
{
assert (pside);
return SideMask(pside->GetObjectID());
}
class CFSMission;
class CFSPlayer;
class CFSSide;
class CAdminGame;
class CAdditionalAGCParamData;
typedef Slist_utl<CFSMission*> ListFSMission;
typedef Slink_utl<CFSMission*> LinkFSMission;
struct JoinRequest
{
CFSPlayer * pfsPlayer;
IsideIGC * pSide;
};
typedef Slist_utl<JoinRequest*> ListJoinReq;
typedef Slink_utl<JoinRequest*> LinkJoinReq;
class IMissionSite : IObject
{
public:
virtual void Create(CFSMission * pfsMission) {}
virtual void Destroy(CFSMission * pfsMission) {}
};
class OldPlayerInfo
{
public:
OldPlayerInfo(void)
:
pso(true),
sideID(NA),
pclusterLifepod(NULL)
{
}
~OldPlayerInfo(void)
{
}
PlayerScoreObject pso;
int characterID;
SideID sideID; char name[c_cbName];
IclusterIGC* pclusterLifepod;
Vector positionLifepod;
unsigned char bannedSideMask;
SideID lastSide;
};
typedef Slist_utl<OldPlayerInfo> OldPlayerList;
typedef Slink_utl<OldPlayerInfo> OldPlayerLink;
typedef int BallotType;
#define BALLOT_RESIGN 1
#define BALLOT_OFFERDRAW 2
#define BALLOT_ACCEPTDRAW 3
#define BALLOT_MUTINY 4
class Ballot
{
public:
virtual bool Update(const Time& now);
virtual void Cancel();
virtual void CastVote(CFSPlayer* pfsPlayer, bool bVote);
BallotID GetBallotID();
BallotType GetType(); virtual ~Ballot() {};
protected:
void Init(CFSPlayer* pfsInitiator, const ZString& pzProposal, const ZString& strBallotText);
void Init(CFSSide* pfsideInitiator, const ZString& pzProposal, const ZString& strBallotText);
ZString GetTallyString();
virtual void OnPassed();
virtual void OnFailed();
bool HasPassed();
bool AllVotesAreIn();
CFSMission* m_pmission;
ChatTarget m_chattarget;
ObjectID m_groupID;
CFMRecipient* m_pgroup;
ZString m_strProposal;
int m_cInFavor[c_cSidesMax];
int m_cOpposed[c_cSidesMax];
int m_cAbstaining[c_cSidesMax];
TVector<ShipID, DefaultEquals> m_vShips;
BallotID m_ballotID;
static BallotID s_ballotIDNext;
Time m_timeExpiration;
bool m_bCanceled;
bool m_bHideToLeader;
BallotType m_type;
};
typedef TList<Ballot*> BallotList;
class MutinyBallot : public Ballot
{
IsideIGC* m_pside;
ShipID m_idInitiatorShip;
public:
MutinyBallot(CFSPlayer* pfsInitiator);
virtual void OnPassed();
};
class ResignBallot : public Ballot
{
IsideIGC* m_pside;
public:
ResignBallot(CFSPlayer* pfsInitiator);
virtual void OnPassed();
};
class OfferDrawBallot : public Ballot
{
CFSSide* m_pfside;
public:
OfferDrawBallot(CFSPlayer* pfsInitiator);
virtual void OnPassed();
};
class AcceptDrawBallot : public Ballot
{
public:
AcceptDrawBallot(CFSSide* pfsideInitiator);
virtual void OnPassed();
};
class CFSMission
{
public:
CFSMission(
const MissionParams& misparms,
char * szDesc,
IMissionSite * psiteMission,
IIgcSite * psiteIGC,
CAdditionalAGCParamData * paagcParamData,
const char* pszStoryText
);
virtual ~CFSMission();
static const ListFSMission * GetMissions()
{
return &s_list;
}
static CFSMission * GetMission(DWORD dwCookie);
static CFSMission * GetMissionFromIGCMissionID(DWORD dwIGCMissionID);
MissionID GetMissionID()
{
return m_pMission->GetMissionID();
}
DWORD GetCookie()
{
return m_misdef.dwCookie;
}
void SetCookie(DWORD dwCookie)
{
m_misdef.dwCookie = dwCookie;
SetLobbyIsDirty();
}
void SetLobbyIsDirty();
bool GetLobbyIsDirty()
{
return m_fLobbyDirty;
}
void UpdateLobby(Time now);
ImissionIGC * GetIGCMission()
{
return m_pMission;
}
IIgcSite* GetSite()
{
return m_psiteIGC;
}
const FMD_S_MISSIONDEF * GetMissionDef()
{
return &m_misdef;
}
void QueueLobbyMissionInfo();
STAGE GetStage()
{
return m_misdef.stage;
}
void SetStage(STAGE stage);
void SetSideName(SideID sid, const char* szName);
void SetSideSquad(SideID sid, SquadID squadID);
CFSPlayer * GetLeader(SideID sid);
void SetLeader(CFSPlayer * pfsPlayer);
void SetLeaderID(SideID sideID, ShipID shipID);
CFSPlayer * GetOwner()
{
if (m_misdef.iSideMissionOwner == NA)
return NULL;
else
return GetLeader(m_misdef.iSideMissionOwner);
}
void AddPlayerToMission(CFSPlayer * pfsPlayer);
void RemovePlayerFromMission(CFSPlayer * pfsPlayer, QuitSideReason reason, const char* szMessageParam = NULL);
void AddPlayerToSide(CFSPlayer * pfsPlayer, IsideIGC * pside);
void RemovePlayerFromSide(CFSPlayer * pfsPlayer, QuitSideReason reason, const char* szMessageParam = NULL);
bool RemovePlayerByName(const char* szCharacterName, QuitSideReason reason, const char* szMessageParam = NULL);
bool RemovePlayerByCDKey(const char* szCDKey, QuitSideReason reason, const char* szMessageParam = NULL);
int GetCountOfPlayers(IsideIGC * pside, bool bCountGhosts);
int GetSideRankSum(IsideIGC * pside, bool bCountGhosts); int GetRankThreshold(); bool HasPlayers(IsideIGC * pside, bool bCountGhosts);
IstationIGC * GetBase(IsideIGC * pside);
int GetCountSides()
{
assert(m_pMission->GetSides()->n() == m_misdef.misparms.nTeams);
return m_misdef.misparms.nTeams;
}
void RecordGameResults();
void RecordTeamResults(IsideIGC* pside);
void RecordPlayerResults(const char* pszName, PlayerScoreObject* ppso, SideID sid);
void QueueGameoverMessage();
IsideIGC* CheckForVictoryByStationBuild(IsideIGC* pside);
IsideIGC* CheckForVictoryByStationCapture(IsideIGC* pside, IsideIGC* psideOld);
IsideIGC* CheckForVictoryByStationKill(IstationIGC* pstationKilled, IsideIGC* psideOld);
IsideIGC* CheckForVictoryByKills(IsideIGC* pside);
IsideIGC* CheckForVictoryByInactiveSides(bool& bAllSidesInactive);
IsideIGC* CheckForVictoryByFlags(IsideIGC* pside, SideID sidFlag);
void GameOver(IsideIGC* psideWin,
const char* pszReason);
void SetMissionParams(const MissionParams & misparms);
void StartCountdown(float fCountdownLength);
void DelayCountdown(float fDelayLength);
void StartGame();
bool FAllReady();
DelPositionReqReason CheckPositionRequest(CFSPlayer * pfsPlayer, IsideIGC * pside);
void RequestPosition(CFSPlayer * pfsPlayer, IsideIGC * pside, bool bRejoin);
void VacateStation(IstationIGC * pstation);
void SetAutoAccept(IsideIGC * pside, bool fAccept);
bool GetAutoAccept(IsideIGC * pside)
{
return !!m_misdef.rgfAutoAccept[pside->GetObjectID()];
}
void SetLockLobby(bool bLock);
void SetLockSides(bool bLock);
void SetMaxTeamImbalance(int imbalance); bool GetLockSides();
void FlushSides(); void RandomizeSides();
void SetSideCiv(IsideIGC * pside, IcivilizationIGC * pciv);
void SetSideActive(SideID sideid, bool bActive); bool GetSideActive(SideID sideid); bool GetAllowEmptyTeams() { return m_misdef.misparms.bAllowEmptyTeams;} void SetAllowEmptyTeams(bool bValue) { m_misdef.misparms.bAllowEmptyTeams = bValue;} void DeactivateSide(IsideIGC * pside);
void GiveSideMoney(IsideIGC * pside, Money money);
void SetForceReady(SideID iSide, bool fForceReady);
bool GetForceReady(SideID iSide)
{
assert(iSide > NA);
return !!m_misdef.rgfForceReady[iSide];
}
bool GetReady(SideID iSide)
{
assert(iSide > NA);
return !!m_misdef.rgfReady[iSide];
}
void PlayerReadyChange(CFSPlayer * pfsPlayer);
bool RejectSideJoinRequests(IsideIGC * pSide);
bool RemoveJoinRequest(CFSPlayer * pfsPlayer, IsideIGC * psideDest);
SideID PickNewSide(CFSPlayer* pfsPlayer, bool bAllowTeamLobby, unsigned char bannedSideMask);
void DoTick(Time timeNow);
void CreateCluster(IclusterIGC * pIclusterIGC);
void DeleteCluster(IclusterIGC * pIclusterIGC);
const std::vector<CFSCluster*> * GetFSClusters()
{
return &m_pFSClusters;
}
void CreateSide(IsideIGC * pIsideIGC);
void DeleteSide(IsideIGC * pIsideIGC);
const std::vector<CFSSide*> * GetFSSides()
{
return &m_pFSSides;
}
CFMGroup * GetGroupRealSides()
{
return m_pgrpSidesReal;
}
CFMGroup * GetGroupLobbySide()
{
CFSSide * pfsside = CFSSide::FromIGC(m_pMission->GetSide(SIDE_TEAMLOBBY));
return pfsside ? pfsside->GetGroup() : NULL;
}
CFMGroup * GetGroupMission()
{
return m_pgrpMission;
}
DWORD IncrementFrame(void)
{
return m_nFrame++;
}
void SaveAsOldPlayer(CFSPlayer* pfsplayer, bool bBooted);
static const DWORD c_sbtPlayer;
static const DWORD c_sbtLeader;
SYSTEMTIME * GetStartTime() { return &m_stStartTime;} float GetGameDuration() {return m_flGameDuration;}
OldPlayerLink* GetOldPlayerLink(const char* name)
{
for (OldPlayerLink* popl = m_oldPlayers.first(); (popl != NULL); popl = popl->next())
{
if (_stricmp(popl->data().name, name) == 0)
return popl;
}
return NULL;
}
bool ShouldDelete() { return m_bShouldDelete; }
bool GetScoresCount()
{
return m_misdef.misparms.bScoresCount;
}
void AddInvitation(SideID sid, char * szPlayerName);
bool RequiresInvitation()
{
return m_nInvitationListID != 0;
}
bool IsInvited(CFSPlayer * pPlayer);
bool IsSquadGame()
{
return m_misdef.misparms.bSquadGame;
}
const ZString& GetDetailsFiles()
{
return m_strDetailsFiles;
}
void SetDetailsFiles(const ZString& strDetailsFiles)
{
m_strDetailsFiles = strDetailsFiles;
SetLobbyIsDirty();
}
void AddBallot(Ballot * pBallot);
void TallyVote(CFSPlayer* pfsPlayer, BallotID ballotID, bool bVote);
bool HasBallots(BallotType iType); void MakeOverrideTechBits(); TechTreeBitMask * m_pttbmAltered; TechTreeBitMask * m_pttbmNewSetting; IsideIGC* GetSideWon(void) const { return m_psideWon; }
const char* GetStoryText() const {return m_strStoryText;}
private:
void InitSide(SideID sid);
void MaintainSquadLeadership(SideID sid);
void ProcessGameOver();
void CheckForSideAllReady(IsideIGC * pside);
void SetReady(SideID iSide, bool fReady);
void AddJoinRequest(CFSPlayer * pfsPlayer, IsideIGC * pside);
void CreateDPGroups(IclusterIGC * pcluster);
void SendLobbyMissionInfo(CFSPlayer * pfsPlayer);
void SendMissionInfo(CFSPlayer * pfsPlayer, IsideIGC* pside);
void DoPayday(void);
void DoPayday(IsideIGC* pside);
void NotifyPlayerBoot(CFSPlayer * pfsPlayer, IsideIGC * pSide);
void Vacate();
static ListFSMission s_list;
static int s_iMissionID;
FMD_S_MISSIONDEF m_misdef; ImissionIGC * m_pMission; Time m_timeNextPayday;
int m_rgMoney[c_cSidesMax];
TRef<IsideIGC> m_psideWon; const char* m_pszReason;
IMissionSite * m_psiteMission;
ListJoinReq m_listJoinReq;
IIgcSite* m_psiteIGC;
std::vector<CFSSide*> m_pFSSides; std::vector<CFSCluster*> m_pFSClusters; CFMGroup * m_pgrpSidesReal; CFMGroup * m_pgrpMission; Time m_timeLastLobbyMissionInfo;
bool m_fLobbyDirty;
bool m_bShouldDelete;
SYSTEMTIME m_stStartTime; DWORD m_nFrame;
OldPlayerList m_oldPlayers;
int m_nInvitationListID;
ZString m_strDetailsFiles;
BallotList m_ballots;
float m_flGameDuration;
ZString m_strStoryText;
bool m_bDraw;
};
#endif