/* Copyright (C) 2009 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * 0 A.D. is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 0 A.D. If not, see . */ #include "precompiled.h" #include "Player.h" #include "network/NetMessage.h" #include "ps/scripting/JSCollection.h" #include "simulation/LOSManager.h" CPlayer::CPlayer(size_t playerID): m_PlayerID(playerID), m_Name(CStrW(L"Player #")+CStrW((unsigned)playerID)), m_Civilization(L""), m_Colour(0.7f, 0.7f, 0.7f), m_UpdateCB(0), m_Active(false) { // m_LOSToken = LOS_GetTokenFor(playerID); // Initialize diplomacy: we need to be neutral to Gaia and enemy to everyone else; // however, if we are Gaia, we'll just be neutral to everyone; finally, everyone // will be allied with themselves. m_DiplomaticStance[0] = DIPLOMACY_NEUTRAL; for(int i=1; i<=PS_MAX_PLAYERS; i++) { m_DiplomaticStance[i] = (m_PlayerID==0 ? DIPLOMACY_NEUTRAL : DIPLOMACY_ENEMY); } m_DiplomaticStance[m_PlayerID] = DIPLOMACY_ALLIED; AddSynchedProperty( L"name", &m_Name ); AddSynchedProperty( L"civilization", &m_Civilization ); // HACK - since we have to use setColour to update this, we don't want to // expose a colour property. Meanwhile, we want to have a property "colour" // available to be able to use the update/sync system. // So, this is only added to the SynchedProperties list and not also passed // to CJSObject's list ISynchedJSProperty *prop=new CSynchedJSProperty(L"colour", &m_Colour, this); m_SynchedProperties[L"colour"]=prop; // HACK - maintain diplomacy synced in the same way, by adding a dummy property for each stance for(int i=0; i<=PS_MAX_PLAYERS; i++) { CStrW name = CStrW(L"diplomaticStance_") + CStrW(i); ISynchedJSProperty *prop=new CSynchedJSProperty(name, &m_DiplomaticStance[i], this); m_SynchedProperties[name]=prop; } } CPlayer::~CPlayer() { // Side-effect of HACKs - since these properties are not passed to CJSObject's list, // they don't get freed automatically delete m_SynchedProperties[L"colour"]; for(int i=0; i<=PS_MAX_PLAYERS; i++) { CStrW name = CStrW(L"diplomaticStance_") + CStrW(i); delete m_SynchedProperties[name]; } } void CPlayer::ScriptingInit() { g_ScriptingHost.DefineConstant("DIPLOMACY_ENEMY", DIPLOMACY_ENEMY); g_ScriptingHost.DefineConstant("DIPLOMACY_NEUTRAL", DIPLOMACY_NEUTRAL); g_ScriptingHost.DefineConstant("DIPLOMACY_ALLIED", DIPLOMACY_ALLIED); AddMethod("toString", 0); AddMethod("setColour", 1); AddMethod("getColour", 0); AddMethod("setDiplomaticStance", 2); AddMethod("getDiplomaticStance", 1); AddProperty( L"id", &CPlayer::m_PlayerID, true ); AddProperty( L"active", &CPlayer::m_Active, true ); AddProperty( L"name", &CPlayer::m_Name, true ); // MT: Work out how this fits with the Synched stuff... // AddClassProperty( L"name", &CPlayer::m_Name ); // AddClassProperty( L"colour", &CPlayer::m_Colour ); CJSObject::ScriptingInit( "Player" ); } void CPlayer::Update(const CStrW& name, ISynchedJSProperty *prop) { if (m_UpdateCB) m_UpdateCB(name, prop->ToString(), this, m_UpdateCBData); } void CPlayer::SetValue(const CStrW& name, const CStrW& value) { ISynchedJSProperty *prop=GetSynchedProperty(name); if (prop) { prop->FromString(value); } } bool CPlayer::ValidateCommand(CNetMessage* UNUSED(pMsg)) { return true; } CStrW CPlayer::JSI_ToString( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) ) { return L"[object Player: " + m_Name + L"]"; } void CPlayer::JSI_SetColour( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* argv ) { m_Colour=*( ToNative(argv[0]) ); ISynchedJSProperty *prop=GetSynchedProperty(L"colour"); Update(L"colour", prop); } jsval_t CPlayer::JSI_GetColour( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) ) { //ISynchedJSProperty *prop=GetSynchedProperty(L"colour"); //return prop->Get(cx, this); SPlayerColour* col = &m_Colour; return ToJSVal(col); } void CPlayer::JSI_SetDiplomaticStance(JSContext *cx, uintN UNUSED(argc), jsval *argv) { try { CPlayer* player = ToPrimitive( argv[0] ); int stance = ToPrimitive( argv[1] ); if (! (stance==DIPLOMACY_ENEMY || stance==DIPLOMACY_NEUTRAL || stance==DIPLOMACY_ALLIED)) { JS_ReportError(cx, "Argument 2 must be a valid stance ID"); return; } m_DiplomaticStance[player->m_PlayerID] = (EDiplomaticStance) stance; CStrW name = CStrW(L"diplomaticStance_") + CStrW((unsigned)player->m_PlayerID); ISynchedJSProperty *prop=GetSynchedProperty(name); Update(name, prop); } catch( PSERROR_Scripting_ConversionFailed ) { JS_ReportError( cx, "Could not convert argument 1 to a Player object" ); } } jsval_t CPlayer::JSI_GetDiplomaticStance(JSContext *cx, uintN UNUSED(argc), jsval *argv) { try { CPlayer* player = ToPrimitive( argv[0] ); return ToJSVal( (int) m_DiplomaticStance[player->m_PlayerID] ); } catch( PSERROR_Scripting_ConversionFailed ) { JS_ReportError( cx, "Could not convert argument 1 to a Player object" ); return JSVAL_VOID; } }