/*------------------------------------------------------------------------- * wintrek\ZoneSquad.cpp * * Implementation of IZoneSquad and IZonePlayer * * These two classes are in the same file because are closely related. * * Owner: * * Copyright 1986-2000 Microsoft Corporation, All Rights Reserved *-----------------------------------------------------------------------*/ #include "pch.h" class CZonePlayerImpl; class CZonePlayerImpl: public IZonePlayer { public: CZonePlayerImpl(const char *szName, int nID) : m_nID(nID), m_rank(IMemberBase::RANK_UNKNOWN) { strncpy(m_szName, szName, sizeof(m_szName)-1); } void Randomize() // fill in random data for testing { #ifdef DEBUG static i = 0; m_rank = (Rank) (i % 3 + 1); switch (i % 3) { case 0: strcpy (m_szName, "John Doe"); break; case 1: strcpy (m_szName, "Susan Wilson"); break; case 2: strcpy (m_szName, "Bill Smith"); break; } ++i; #endif } char * GetName() { return m_szName; } void SetName(PCC szName) { strcpy(m_szName, szName); } int GetID() { return m_nID; } void SetID(int nID) { m_nID = nID; } char * GetLastPlayedDate(IZoneSquad & squad); void SetLastPlayedDate(IZoneSquad & squad, PCC szLastPlayedDate); Rank GetRank() { return m_rank; } void SetRank(Rank rank) { m_rank = rank; } float GetHours(IZoneSquad & squad); void SetHours(IZoneSquad & squad, float fHours); Position GetPosition(IZoneSquad & squad); void SetPosition(IZoneSquad & squad, Position pos); // setting to leader should only be done from IZoneSquad::SetOwner() DetailedStatus GetStatus(IZoneSquad & squad); bool IsMemberOf(IZoneSquad & squad) // is this player a member of pSquad { DetailedStatus status = GetStatus(squad); if (status == DSTAT_MEMBER || status == DSTAT_ASL || status == DSTAT_LEADER) return true; return false; } bool IsPendingFor(IZoneSquad & squad) { return GetStatus(squad) == DSTAT_PENDING; } private: char m_szName[40]; int m_nID; Rank m_rank; }; /* The spec called for the screen to know how many hours a player has been with a particular squad, so I made CMembership. It turns out that the database isn't going to support this, but I'm using CMembership for remembering position. */ class CMembership: public IObject { TRef m_pPlayer; IZonePlayer::DetailedStatus m_dstatus; char m_szLastPlayedDate[9]; // float m_fHours; public: CMembership() : // m_fHours(0), m_pPlayer(NULL), m_dstatus(IZonePlayer::DSTAT_NO_ASSOCIATION) { strcpy(m_szLastPlayedDate, " "); } // void SetHours(float fHours) { asset(0);/*m_fHours = fHours; */} // float GetHours() { assert(0); return 0;/*return m_fHours; */} IZonePlayer::Position GetPosition() { return IZonePlayer::Position(m_dstatus - ((int)IZonePlayer::DSTAT_MEMBER - (int)IZonePlayer::POS_MEMBER)); } void SetPosition(IZonePlayer::Position pos) { m_dstatus = IZonePlayer::DetailedStatus(pos + (IZonePlayer::DSTAT_MEMBER - IZonePlayer::POS_MEMBER)); } IMemberBase::DetailedStatus GetStatus() { return m_dstatus; } char * GetLastPlayedDate() { return m_szLastPlayedDate; } void SetLastPlayedDate(PCC szLastPlayedDate) { strncpy (m_szLastPlayedDate, szLastPlayedDate, sizeof(m_szLastPlayedDate)); } void SetStatus(IMemberBase::DetailedStatus detailedstatus) { m_dstatus = detailedstatus; } TRef GetPlayer() { return m_pPlayer; } void SetPlayer(TRef pPlayer) { m_pPlayer = pPlayer; } }; class CZoneSquadImpl: public IZoneSquad { public: char *GetName() { return m_szName; } void SetName(PCC szName) { strcpy(m_szName, szName); } char *GetDescription() { return m_szDescription; } void SetDescription(PCC szDescription) { strcpy(m_szDescription, szDescription); } int GetID() { return m_nID; } void SetID(int nID) { m_nID = nID; } int GetCreationID() { return m_nCreationID; } void SetCreationID(int nCreationID) { m_nCreationID = nCreationID; } char *GetURL() { return m_szURL; } void SetURL(PCC szURL) { strcpy(m_szURL, szURL); } char *GetInceptionDate() { return m_szInceptionDate; } void SetInceptionDate(char *szInceptionDate) { strcpy(m_szInceptionDate, szInceptionDate); } TRef GetOwner() { return m_pOwner; } void SetOwner(TRef pOwner); const char * GetRank() { Rank rank = Rank(m_nScore / 100); if (rank < RANK_START || rank >= RANK_MAX) return Rank2String(RANK_UNKNOWN); return Rank2String(rank); } int GetRanking(SQUAD_SORT_COLUMN column) { return m_nRanking[column]; } void SetRanking(SQUAD_SORT_COLUMN column, int nRanking) { m_nRanking[column] = nRanking; } int GetWins() { return m_nWins; } void SetWins(int nWins) { m_nWins = nWins; } int GetLosses() { return m_nLosses; } void SetLosses(int nLosses) { m_nLosses = nLosses; } CivID GetCivID() { return m_idCiv; } void SetCivID(int id) { m_idCiv = id; } short GetScore() { return m_nScore; } void SetScore(short nScore) { m_nScore = nScore; } void SetDetailsReceived() { m_bDetailsReceived = true; } bool WereDetailsReceived() { return m_bDetailsReceived; } void AddPlayer(IZonePlayer & pPlayer); // consider using SquadScreen::AddPlayerToSquad() over this void QuitPlayer(IZonePlayer & pPlayer); // consider using SquadScreen::RemovePlayerFromSquad() over this void RejectPlayer(IZonePlayer & pPlayer); void BootPlayer(IZonePlayer & pPlayer); void AddJoinRequest(IZonePlayer & pPlayer); void CancelJoinRequest(IZonePlayer & pPlayer); void SetEmpty(); void AddPlayersToList(XZonePlayers & list); void SetOwnershipLog(char * szLog) { m_listStrOwnershipLog.SetEmpty(); if(!szLog) return; const char * szDelimit = ";"; // set bLastOneTruncated int nLen = strlen(szLog); int c = 0; for (int i = 0; i < nLen; ++i) if (szLog[i] == ';') c++; bool bLastOneTruncated = c % 2 != 0; char * szToken; // establish string and get the first token szToken = strtok(szLog, szDelimit); while (szToken) { // szToken is Name ZString strLine(szToken); szToken = strtok(NULL, szDelimit); if (!szToken) break; strLine += " "; // szToken is date strLine += szToken; szToken = strtok(NULL, szDelimit); m_listStrOwnershipLog.PushFront(strLine); } if(bLastOneTruncated) m_listStrOwnershipLog.PopFront(); } void SetStatus(IZonePlayer & player, IMemberBase::DetailedStatus detailedstatus); void AddPlayer(IZonePlayer & player, IMemberBase::DetailedStatus detailedstatus) { SetStatus(player, detailedstatus); } TRef FindMembership(IZonePlayer & player); IMemberBase::DetailedStatus FindStatus(IZonePlayer & player); TList * GetOwnershipLog() { return &m_listStrOwnershipLog; } CZoneSquadImpl() : m_rank(RANK_UNKNOWN), m_nWins(0), m_nLosses(0), m_idCiv(NA), m_nScore(0), m_bDetailsReceived(false), // false here means data for this squad is incomplete m_listMemberships(), m_bWasJustMade(false), // assume not recently made by interactive user m_pOwner(NULL) { for (int i = 0; i < SSC_MAX; ++i) m_nRanking[i] = -1; m_szName[0] = 0; m_szDescription[0] = 0; m_szURL[0] = 0; m_szInceptionDate[0] = 0; } private: char m_szName[32]; char m_szDescription[512]; char m_szURL[256]; char m_szInceptionDate[32]; Rank m_rank; int m_nRanking[SSC_MAX]; int m_nWins; int m_nLosses; CivID m_idCiv; short m_nScore; bool m_bDetailsReceived; // have the details been gotten for the server yet? TRef m_pOwner; XMemberships m_listMemberships; // members of, along with hours been with (and position data) TList m_listStrOwnershipLog; // TODO: make this a a simple ZString, not a list int m_nID; // True ID determined by Zone database servers int m_nCreationID; // Creation ID is valid on client only bool m_bWasJustMade; // mainly for interactive user }; TRef CreateZoneSquad() { return new CZoneSquadImpl; } /*------------------------------------------------------------------------- * GetStatus() *------------------------------------------------------------------------- */ IMemberBase::DetailedStatus CZonePlayerImpl::GetStatus(IZoneSquad & squad) { TRef pMembership = ((CZoneSquadImpl*)(&squad))->FindMembership(*this); if (pMembership) return pMembership->GetStatus(); return DSTAT_NO_ASSOCIATION; } /*------------------------------------------------------------------------- * SetPosition() *------------------------------------------------------------------------- * Remarks: setting pos to leader should only be done from IZoneSquad::SetOwner() */ void CZonePlayerImpl::SetPosition(IZoneSquad & squad, Position pos) { TRef pMembership = ((CZoneSquadImpl*)(&squad))->FindMembership(*this); assert(pMembership); // Cannot set position if player in not a member of the squad if (pMembership) { pMembership->SetPosition(pos); } } /*------------------------------------------------------------------------- * SetHours() *------------------------------------------------------------------------- */ void CZonePlayerImpl::SetHours(IZoneSquad & squad, float fHours) { assert(0); // not impl } /*------------------------------------------------------------------------- * GetPosition() *------------------------------------------------------------------------- */ IZonePlayer::Position CZonePlayerImpl::GetPosition(IZoneSquad & squad) { TRef pMembership = ((CZoneSquadImpl*)(&squad))->FindMembership(*this); if (pMembership) { return pMembership->GetPosition(); } else return POS_UNKNOWN; } /*------------------------------------------------------------------------- * GetLastPlayedDate() *------------------------------------------------------------------------- */ char * CZonePlayerImpl::GetLastPlayedDate(IZoneSquad & squad) { TRef pMembership = ((CZoneSquadImpl*)(&squad))->FindMembership(*this); if (pMembership) { return pMembership->GetLastPlayedDate(); } else return " "; } /*------------------------------------------------------------------------- * SetLastPlayedDate() *------------------------------------------------------------------------- */ void CZonePlayerImpl::SetLastPlayedDate(IZoneSquad & squad, PCC szLastPlayedDate) { TRef pMembership = ((CZoneSquadImpl*)(&squad))->FindMembership(*this); assert(pMembership); // Cannot set position if player in not a member of the squad if (pMembership) { pMembership->SetLastPlayedDate(szLastPlayedDate); } } /*------------------------------------------------------------------------- * GetHours() *------------------------------------------------------------------------- */ float CZonePlayerImpl::GetHours(IZoneSquad & squad) { assert(0); // not impl return 0; } /*------------------------------------------------------------------------- * MakePlayerList() *------------------------------------------------------------------------- */ void CZoneSquadImpl::AddPlayersToList(XZonePlayers & list) { XMembershipsIt it(m_listMemberships); while(!it.End()) { if (!list.Find(it.Value()->GetPlayer())) // no duplicates list.PushEnd(it.Value()->GetPlayer()); it.Next(); } } /*------------------------------------------------------------------------- * FindMembership() *------------------------------------------------------------------------- */ TRef CZoneSquadImpl::FindMembership(IZonePlayer & player) { XMembershipsIt it(m_listMemberships); while(!it.End()) { if (it.Value()->GetPlayer() == &player) { return it.Value(); } it.Next(); } return NULL; } /*------------------------------------------------------------------------- * FindStatus() *------------------------------------------------------------------------- */ IMemberBase::DetailedStatus CZoneSquadImpl::FindStatus(IZonePlayer & player) { XMembershipsIt it(m_listMemberships); while(!it.End()) { if (it.Value()->GetPlayer() == &player) { return it.Value()->GetStatus(); } it.Next(); } return IMemberBase::DSTAT_NO_ASSOCIATION; } /*------------------------------------------------------------------------- * AddPlayer() *------------------------------------------------------------------------- * Note: consider using SquadScreen::AddPlayerToSquad() instead of this * to ensure proper screen refresh */ void CZoneSquadImpl::SetStatus(IZonePlayer & player, IMemberBase::DetailedStatus detailedstatus) { TRef pMembership = FindMembership(player); if(!pMembership) { pMembership = new CMembership; m_listMemberships.PushEnd(pMembership); pMembership->SetPlayer(&player); } if (detailedstatus == IMemberBase::DSTAT_LEADER) SetOwner(&player); else pMembership->SetStatus(detailedstatus); } /*------------------------------------------------------------------------- * QuitPlayer() *------------------------------------------------------------------------- * Note: consider using SquadScreen::RemovePlayerFromSquad() instead of this * to ensure proper screen refresh */ void CZoneSquadImpl::QuitPlayer(IZonePlayer & player) { TRef pMembership = FindMembership(player); if(pMembership) { if (m_pOwner == &player) { m_pOwner = NULL; // for now set to nobody // // Server will update who is owner later // } m_listMemberships.Remove(pMembership); } } /*------------------------------------------------------------------------- * AddJoinRequest() *------------------------------------------------------------------------- */ void CZoneSquadImpl::AddJoinRequest(IZonePlayer & player) { SetStatus(player, IZonePlayer::DSTAT_PENDING); } /*------------------------------------------------------------------------- * SetEmpty() -- Clears all membership *------------------------------------------------------------------------- */ void CZoneSquadImpl::SetEmpty() { m_listMemberships.SetEmpty(); } /*------------------------------------------------------------------------- * RejectPlayer() *------------------------------------------------------------------------- * * Used to reject * */ void CZoneSquadImpl::RejectPlayer(IZonePlayer & player) { QuitPlayer(player); } /*------------------------------------------------------------------------- * BootPlayer() *------------------------------------------------------------------------- * * Used to boot * */ void CZoneSquadImpl::BootPlayer(IZonePlayer & player) { QuitPlayer(player); } /*------------------------------------------------------------------------- * CancelJoinRequest() *------------------------------------------------------------------------- */ void CZoneSquadImpl::CancelJoinRequest(IZonePlayer & player) { QuitPlayer(player); } /*------------------------------------------------------------------------- * SetOwner() *------------------------------------------------------------------------- */ void CZoneSquadImpl::SetOwner(TRef pOwner) { // demote existing owner if (m_pOwner && m_pOwner->IsMemberOf(*this)) m_pOwner->SetPosition(*this, IZonePlayer::POS_MEMBER); // promote new guy m_pOwner = pOwner; m_pOwner->SetPosition(*this, IZonePlayer::POS_LEADER); } TRef CreateZonePlayer(const char *szName, int nID) { return new CZonePlayerImpl(szName, nID); }