#ifndef ps_GameAttributes_H #define ps_GameAttributes_H #include "Player.h" #include "scripting/SynchedJSObject.h" class CNetServerSession; class CGameAttributes; class CPlayerSlot; enum EPlayerSlotAssignment { SLOT_CLOSED, SLOT_OPEN, SLOT_SESSION, SLOT_AI }; typedef void (PlayerSlotAssignmentCB)(void *data, CPlayerSlot *); class CPlayerSlot: public CJSObject { int m_SlotID; EPlayerSlotAssignment m_Assignment; CNetServerSession *m_pSession; int m_SessionID; CPlayer *m_pPlayer; PlayerSlotAssignmentCB *m_Callback; void *m_CallbackData; bool JSI_AssignClosed(JSContext *cx, uintN argc, jsval *argv); // Assign to a session, takes one argument (a NetSession object) bool JSI_AssignToSession(JSContext *cx, uintN argc, jsval *argv); // Assign to the local player in SP or Server Player in MP bool JSI_AssignLocal(JSContext *cx, uintN argc, jsval *argv); bool JSI_AssignOpen(JSContext *cx, uintN argc, jsval *argv); // TODO This will wait until there actually is AI to set up // bool JSI_AssignAI(JSContext *cx, uintN argc, jsval *argv); jsval JSI_GetSession(); jsval JSI_GetAssignment(); void CallCallback(); void SetAssignment(EPlayerSlotAssignment, CNetServerSession *pSession, int sessionID); static void ScriptingInit(); protected: friend class CGameAttributes; inline void SetSlotID(int slotID) { m_SlotID=slotID; } public: CPlayerSlot(int slotID, CPlayer *pPlayer); ~CPlayerSlot(); inline CPlayer *GetPlayer() { return m_pPlayer; } inline int GetSessionID() { return m_SessionID; } inline int GetSlotID() { return m_SlotID; } // Only applicable on the server host, and may return NULL if the slot // is not assigned to a server session. inline CNetServerSession *GetSession() { return m_pSession; } inline void SetCallback(PlayerSlotAssignmentCB *callback, void *data) { m_Callback=callback; m_CallbackData=data; } inline EPlayerSlotAssignment GetAssignment() { return m_Assignment; } // Reset any assignment the slot might have had before and mark the slot as // closed. void AssignClosed(); // [Server] Assign the slot to a connected session void AssignToSession(CNetServerSession *pSession); // [Client] The slot has been assigned by the server to a session ID, mirror // the assignment void AssignToSessionID(int sessionID); // Reset any assignment the slot might have before and mark the slot as free void AssignOpen(); // Assign to the local player in SP or Server Player in MP void AssignLocal(); // TODO This will wait until there actually is AI to set up // void AssignAI(); }; namespace PlayerSlotArray_JS { JSBool GetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp ); }; class CGameAttributes: public CSynchedJSObject, public Singleton { public: typedef void (UpdateCallback)(CStrW name, CStrW newValue, void *data); CStrW m_MapFile; uint m_LOSSetting; private: friend JSBool PlayerSlotArray_JS::GetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp ); uint m_NumSlots; // All players in the game. m_Players[0] is the Gaia Player, like in CGame. // m_Players[1..n] have a corresponding player slot in m_PlayerSlots[0..n-1] std::vector m_Players; std::vector m_PlayerSlots; JSObject *m_PlayerSlotArrayJS; UpdateCallback *m_UpdateCB; void *m_UpdateCBData; CPlayer::UpdateCallback *m_PlayerUpdateCB; void *m_PlayerUpdateCBData; PlayerSlotAssignmentCB *m_PlayerSlotAssignmentCB; void *m_PlayerSlotAssignmentCBData; virtual void Update(CStrW name, ISynchedJSProperty *attrib); static void OnNumSlotsUpdate(CSynchedJSObjectBase *owner); jsval JSI_GetPlayerSlots(); jsval JSI_GetOpenSlot(JSContext *cx, uintN argc, jsval *argv); static void ScriptingInit(); public: CGameAttributes(); virtual ~CGameAttributes(); void SetValue(CStrW name, CStrW value); inline void SetUpdateCallback(UpdateCallback *cb, void *userdata) { m_UpdateCB=cb; m_UpdateCBData=userdata; } inline uint GetSlotCount() { return m_NumSlots; } // Remove all slots that are either opened or closed, so that all slots have // an assignment and a player. Player IDs will be assigned in the same order // as the slot indexes, but without holes in the numbering. void FinalizeSlots(); // Get the player object for the passed Player ID CPlayer *GetPlayer(int id); // Get the slot object with the specified index CPlayerSlot *GetSlot(int index); void SetPlayerUpdateCallback(CPlayer::UpdateCallback *cb, void *userdata); void SetPlayerSlotAssignmentCallback(PlayerSlotAssignmentCB *cb, void *userdata); }; #define g_GameAttributes CGameAttributes::GetSingleton() #endif