Updated OpenAL to 1.1 (which no longer includes ALUT).

Changed player-id code a bit so the entity and actor and unit should
stay in sync more often. (The entity/actor/unit mixing still looks a bit
dodgy and unreliable, though.)
Simplified console help code.
Allowed init/shutdown to be done with the simulation/world/etc parts
disabled (so the actor viewer can load faster).

This was SVN commit r4289.
This commit is contained in:
Ykkrosh 2006-09-02 21:20:25 +00:00
parent 12b060d34f
commit 8e02ec84f9
28 changed files with 173 additions and 160 deletions

View File

@ -711,7 +711,7 @@ int CXMLReader::ReadEntities(XMBElement parent, double end_time)
LOG(ERROR, LOG_CATEGORY, "Failed to create entity of type '%ls'", TemplateName.c_str());
else
{
ent->SetPlayer(g_Game->GetPlayer(PlayerID));
ent->m_actor->SetPlayerID(PlayerID);
// TODO: save object IDs in the map file, and load them again,
// so that triggers have a persistent identifier for objects

View File

@ -7,9 +7,12 @@
#include "SkeletonAnim.h"
#include "SkeletonAnimDef.h"
#include "ps/Game.h"
#include "simulation/Entity.h"
CUnit::CUnit(CObjectEntry* object, CEntity* entity, const std::set<CStr>& actorSelections)
: m_Object(object), m_Model(object->m_Model->Clone()), m_Entity(entity),
m_ID(-1), m_ActorSelections(actorSelections)
m_ID(-1), m_ActorSelections(actorSelections), m_PlayerID(-1)
{
}
@ -132,6 +135,9 @@ void CUnit::SetPlayerID(int id)
{
m_PlayerID = id;
m_Model->SetPlayerID(m_PlayerID);
if (m_Entity)
m_Entity->SetPlayer(g_Game->GetPlayer(id));
}
void CUnit::SetEntitySelection(const CStr& selection)
@ -166,10 +172,13 @@ void CUnit::ReloadObject()
CObjectEntry* newObject = g_ObjMan.FindObjectVariation(m_Object->m_Base, selections);
if (newObject != m_Object)
{
// Clone the base model (lacking instance-specific data)
CModel* newModel = newObject->m_Model->Clone();
// Copy old settings to the new model
newModel->SetPlayerID(m_PlayerID);
// Copy the old instance-specific settings to the new model
newModel->SetTransform(m_Model->GetTransform());
if (m_PlayerID != -1)
newModel->SetPlayerID(m_PlayerID);
// TODO: preserve selection of animation, anim offset, etc?
delete m_Model;

View File

@ -56,7 +56,7 @@ public:
// matching 'name'.
bool IsPlayingAnimation(const CStr& name);
// Set player ID of this unit
// Set player ID of this unit (and the attached entity and actor)
void SetPlayerID(int id);
// Get player ID of this unit
@ -76,7 +76,7 @@ private:
CModel* m_Model;
// the entity that this actor represents, if any
CEntity* m_Entity;
// player id of this unit (only used for graphical effects)
// player id of this unit (only read for graphical effects), or -1 if unspecified
int m_PlayerID;
// unique (per map) ID number for units created in the editor, as a

View File

@ -14,14 +14,11 @@
#include "Model.h"
#include "UnitManager.h"
#include "Unit.h"
#include "ps/CConsole.h"
#include "ObjectManager.h"
#include "ObjectEntry.h"
#include "simulation/Entity.h"
#include "simulation/LOSManager.h"
extern CConsole* g_Console;
#include <algorithm>
///////////////////////////////////////////////////////////////////////////////

View File

@ -60,13 +60,8 @@ need only be renamed (e.g. _open, _stat).
#else
// unix/linux/glibc/gcc says that this macro has to be defined when including
// stdint.h from C++ for stdint.h to define SIZE_MAX and friends
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include "posix_types.h"
#include <stdint.h>
#include <sys/types.h>
#include <limits.h>
#include <unistd.h>

View File

@ -34,7 +34,12 @@
#else
// unix/linux/glibc/gcc says that this macro has to be defined when including
// stdint.h from C++ for stdint.h to define SIZE_MAX and friends
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)-1)
#endif
# ifndef __STDC_LIMIT_MACROS
# define __STDC_LIMIT_MACROS
# endif
# include <stdint.h>
// but sometimes it still doesn't get defined, so define it ourselves
# ifndef SIZE_MAX
# define SIZE_MAX ((size_t)-1)
# endif
#endif // #if OS_WIN

View File

@ -102,21 +102,7 @@
//#include <ciso646> // defines e.g. "and" to "&". unnecessary and causes trouble with asm.
#include <climits>
#include <clocale>
// Don't use <cmath>! libstdc++ on MacOSX is 'clever' and insists on
// 'strict conformance'. That means #undef-ing C99 math macros such as
// isfinite, which is a misguided (who cares if namespace includes isfinite;
// that is a well-known and unlikely to be reimplemented macro) and
// annoying incompatibility with C99.
// simply using math.h avoids the #undefs and is fine because we don't
// use std::cos anywhere. possible alternate fixes:
// - add an e.g. std::isfinite version of our HAVE_C99 emulation macros
// (a good bit of work)
// - #define isfinite to std::isfinite (destroys the utility of
// namespaces)
// - use _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC to prevent libstdc++ from
// #undefing the macros (might work, but hacky and potentially confusing)
//#include <cmath>
#include <math.h>
#include <cmath>
// Including setjmp.h here causes incompatibilities with libpng on Debian/Ubuntu
//#include <csetjmp>
#include <csignal>

View File

@ -248,7 +248,7 @@ static LibError alc_init()
#if OS_WIN
__try
{
alc_dev = alcOpenDevice((ALubyte*)alc_dev_name);
alc_dev = alcOpenDevice((ALCchar*)alc_dev_name);
}
// if invalid handle, handle it; otherwise, continue handler search.
__except(GetExceptionCode() == EXCEPTION_INVALID_HANDLE)

View File

@ -25,7 +25,7 @@
#include <string.h>
#include "lib.h"
#include "posix_types.h" // SIZE_MAX
#include "posix.h" // SIZE_MAX
// written against http://std.dkuug.dk/jtc1/sc22/wg14/www/docs/n1031.pdf .

View File

@ -25,7 +25,6 @@
#include "lib/config.h"
#include "lib/debug.h" // ErrorReaction
#include <cmath>
// some functions among the sysdep API are implemented as macros
// that redirect to the platform-dependent version. this is done where
@ -146,8 +145,11 @@ extern void* alloca(size_t size);
//# define signbit
#else
// Some systems have C99 support but in C++ they provide only std::isfinite
// and not isfinite. C99 specifies that isfinite is a macro, so define it if
// it doesn't already exist.
// and not isfinite. C99 specifies that isfinite is a macro, so we can use
// #ifndef and define it if it's not there.
// Since sysdep.h will normally be included before cmath is, make sure we load
// cmath first to let it define/undef that macro.
# include <cmath>
# ifndef isfinite
# define isfinite std::isfinite
# define isnan std::isnan

View File

@ -382,7 +382,7 @@ trace_run("../logs/trace.txt");
Frame();
#endif
Shutdown();
Shutdown(0);
MainControllerShutdown();
debug_printf("Shutdown complete, calling exit() now\n");

View File

@ -48,18 +48,15 @@ CConsole::CConsole()
file_buf_free(buf);
return;
}
const char* text = (const char*)buf;
CStrW temp = CStrW( CStr(text) );
size_t i=0, strings = temp.Length()/1024 ;
for ( ; i<strings; ++i )
m_helpText.push_back( temp.substr(i*1024, 1023) );
m_helpText.push_back( temp.substr(strings*1024) );
// TODO: read in text mode, or at least get rid of the \r\n somehow
// TODO: maybe the help file should be UTF-8 - we assume it's iso-8859-1 here
m_helpText = CStrW(CStr( (const char*)buf ));
file_buf_free(buf);
}
else
{
InsertMessage(L"No help file found.");
}
}
CConsole::~CConsole()
@ -528,9 +525,18 @@ void CConsole::InsertMessage(const wchar_t* szMessage, ...)
wcscpy(szBuffer+CONSOLE_MESSAGE_SIZE-4, L"...");
}
va_end(args);
InsertMessageRaw(CStrW(szBuffer));
}
void CConsole::InsertMessageRaw(const CStrW& message)
{
// (TODO: this text-wrapping is rubbish since we now use variable-width fonts)
//Insert newlines to wraparound text where needed
CStrW wrapAround( szBuffer ), newline(L'\n');
CStrW wrapAround(message);
CStrW newline(L'\n');
size_t oldNewline=0;
size_t distance;
@ -640,8 +646,7 @@ void CConsole::ProcessBuffer(const wchar_t* szLine){
{
InsertMessage(L"");
InsertMessage(L"[Help]");
for ( std::vector<std::wstring>::iterator it=m_helpText.begin(); it!=m_helpText.end(); it++ )
InsertMessage( it->c_str() );
InsertMessageRaw(m_helpText);
}
else
{

View File

@ -40,7 +40,7 @@ private:
// allows implementing other animations than sliding, e.g. fading in/out.
float m_fVisibleFrac;
std::vector<std::wstring> m_helpText;
CStrW m_helpText;
std::map<std::wstring, fptr> m_mapFuncList;
std::deque<std::wstring> m_deqMsgHistory;
@ -75,6 +75,10 @@ private:
void InsertBuffer(void){InsertMessage(L"%ls", m_szBuffer);};
void ProcessBuffer(const wchar_t* szLine);
// Insert message without printf-style formatting, and without
// length limits
void InsertMessageRaw(const CStrW& message);
void LoadHistory();
void SaveHistory();

View File

@ -757,7 +757,7 @@ void EndGame()
}
void Shutdown()
void Shutdown(uint flags)
{
MICROLOG(L"Shutdown");
@ -770,32 +770,36 @@ void Shutdown()
delete &g_Scheduler;
TIMER_END("shutdown Scheduler");
TIMER_BEGIN("shutdown SessionManager");
delete &g_SessionManager;
TIMER_END("shutdown SessionManager");
TIMER_BEGIN("shutdown mouse stuff");
delete &g_Mouseover;
delete &g_Selection;
delete &g_BuildingPlacer;
TIMER_END("shutdown mouse stuff");
TIMER_BEGIN("shutdown Pathfinder");
delete &g_Pathfinder;
TIMER_END("shutdown Pathfinder");
// Managed by CWorld
// delete &g_EntityManager;
TIMER_BEGIN("shutdown game scripting stuff");
delete &g_GameAttributes;
delete &g_JSGameEvents;
delete &g_FormationManager;
delete &g_TechnologyCollection;
delete &g_EntityFormationCollection;
delete &g_EntityTemplateCollection;
TIMER_END("shutdown game scripting stuff");
if (! (flags & INIT_NO_SIM))
{
TIMER_BEGIN("shutdown SessionManager");
delete &g_SessionManager;
TIMER_END("shutdown SessionManager");
TIMER_BEGIN("shutdown mouse stuff");
delete &g_Mouseover;
delete &g_Selection;
delete &g_BuildingPlacer;
TIMER_END("shutdown mouse stuff");
TIMER_BEGIN("shutdown Pathfinder");
delete &g_Pathfinder;
TIMER_END("shutdown Pathfinder");
// Managed by CWorld
// delete &g_EntityManager;
TIMER_BEGIN("shutdown game scripting stuff");
delete &g_GameAttributes;
delete &g_FormationManager;
delete &g_TechnologyCollection;
delete &g_EntityFormationCollection;
delete &g_EntityTemplateCollection;
TIMER_END("shutdown game scripting stuff");
}
// destroy actor related stuff
TIMER_BEGIN("shutdown actor stuff");
@ -1016,36 +1020,35 @@ void Init(int argc, char* argv[], uint flags)
oglCheck();
InitRenderer();
if (! (flags & INIT_NO_SIM))
{
TIMER("Init_entitiessection");
// This needs to be done after the renderer has loaded all its actors...
new CEntityTemplateCollection;
new CFormationCollection;
new CTechnologyCollection;
g_EntityFormationCollection.loadTemplates();
g_TechnologyCollection.loadTechnologies();
new CFormationManager;
{
TIMER("Init_entitiessection");
// This needs to be done after the renderer has loaded all its actors...
new CEntityTemplateCollection;
new CFormationCollection;
new CTechnologyCollection;
g_EntityFormationCollection.loadTemplates();
g_TechnologyCollection.loadTechnologies();
new CFormationManager;
// CEntityManager is managed by CWorld
//new CEntityManager;
new CSelectedEntities;
new CMouseoverEntities;
// CEntityManager is managed by CWorld
//new CEntityManager;
new CSelectedEntities;
new CMouseoverEntities;
}
{
TIMER("Init_miscgamesection");
new CPathfindEngine;
new CBuildingPlacer;
new CSessionManager;
new CGameAttributes;
}
// Register a few Game/Network JS globals
g_ScriptingHost.SetGlobal("g_GameAttributes", OBJECT_TO_JSVAL(g_GameAttributes.GetScript()));
}
{
TIMER("Init_miscgamesection");
new CPathfindEngine;
new CBuildingPlacer;
new CSessionManager;
new CGameAttributes;
}
{
TIMER("Init_misc");
// Register a few Game/Network JS globals
g_ScriptingHost.SetGlobal("g_GameAttributes", OBJECT_TO_JSVAL(g_GameAttributes.GetScript()));
// Check for heap corruption after every allocation. Very, very slowly.
@ -1056,7 +1059,6 @@ void Init(int argc, char* argv[], uint flags)
InitInput();
oglCheck();
}
#ifndef NO_GUI
{

View File

@ -17,8 +17,6 @@ extern void GUI_DisplayLoadProgress(int percent, const wchar_t* pending_task);
extern void Render();
extern void RenderActor();
extern void Shutdown();
enum InitFlags
{
@ -29,7 +27,12 @@ enum InitFlags
// skip initializing the in-game GUI.
// needed by map editor because it uses its own GUI.
INIT_NO_GUI = 2
INIT_NO_GUI = 2,
// skip initializing the simulation.
// used by actor viewer because it doesn't need the simulation code.
INIT_NO_SIM = 4,
};
extern void Init(int argc, char* argv[], uint flags);
extern void Shutdown(uint flags);

View File

@ -16,7 +16,6 @@
#include "lib/timer.h"
#include "maths/MathUtil.h"
#include "network/NetMessage.h"
#include "ps/CConsole.h"
#include "ps/Game.h"
#include "ps/Globals.h"
#include "ps/Hotkey.h"
@ -40,7 +39,6 @@
#include "ps/CLogger.h"
#define LOG_CATEGORY "world"
extern CConsole* g_Console;
extern CStr g_CursorName;
extern float g_xres, g_yres;

View File

@ -4,7 +4,6 @@
#include "ScriptingHost.h"
#include "ScriptGlue.h"
#include "ps/CConsole.h"
#include "ps/Profile.h"
#include "ps/CLogger.h"
@ -21,8 +20,6 @@
#define LOG_CATEGORY "scriptinghost"
extern CConsole* g_Console;
namespace
{
const int RUNTIME_MEMORY_ALLOWANCE = 16 * 1024 * 1024;

View File

@ -60,7 +60,7 @@ CBoundingObject* getCollisionObject( CBoundingObject* bounds, CPlayer* player, c
/* If the unit is marked to ignore ally collisions, and the player parameter
is passed in and the same player as the unit, then ignore the (potential) collision */
if( player && (*it)->m_base->m_passThroughAllies && (*it)->m_player == player ) continue;
if( player && (*it)->m_base->m_passThroughAllies && (*it)->GetPlayer() == player ) continue;
if( ignoreClass && (*it)->m_classes.IsMember( *ignoreClass ) ) continue;
@ -87,7 +87,7 @@ CEntity* getCollisionEntity( CBoundingObject* bounds, CPlayer* player, const CSt
/* If the unit is marked to ignore ally collisions, and the player parameter
is passed in and the same player as the unit, then ignore the (potential) collision */
if( player && (*it)->m_base->m_passThroughAllies && (*it)->m_player == player ) continue;
if( player && (*it)->m_base->m_passThroughAllies && (*it)->GetPlayer() == player ) continue;
if( ignoreClass && (*it)->m_classes.IsMember( *ignoreClass ) ) continue;
@ -117,7 +117,7 @@ HEntity getCollisionObject( CEntity* entity )
if( !(*it)->m_bounds ) continue;
if( (*it)->m_bounds == entity->m_bounds ) continue;
if( entity->m_base->m_passThroughAllies && (*it)->m_base->m_passThroughAllies
&& entity->m_player == (*it)->m_player ) continue;
&& entity->GetPlayer() == (*it)->GetPlayer() ) continue;
if( entity->m_bounds->intersects( (*it)->m_bounds ) )
{
HEntity collisionObject = HEntity((*it)->me);

View File

@ -8,7 +8,6 @@
#include "graphics/UnitManager.h"
#include "maths/MathUtil.h"
#include "maths/scripting/JSInterface_Vector3D.h"
#include "ps/CConsole.h"
#include "ps/Game.h"
#include "ps/Interact.h"
#include "ps/Profile.h"
@ -31,7 +30,6 @@
#include "TechnologyCollection.h"
#include "TerritoryManager.h"
extern CConsole* g_Console;
extern int g_xres, g_yres;
#include <algorithm>
@ -49,7 +47,7 @@ CEntity::CEntity( CEntityTemplate* base, CVector3D position, float orientation,
m_ahead.y = cos( m_orientation.Y );
m_position_previous = m_position;
m_orientation_previous = m_orientation;
m_player = 0;
m_player = NULL;
m_productionQueue = new CProductionQueue( this );
@ -251,9 +249,8 @@ void CEntity::SetPlayer(CPlayer *pPlayer)
{
m_player = pPlayer;
// Store the ID of the player in the associated model
if( m_actor )
m_actor->SetPlayerID( m_player->GetPlayerID() );
// This should usually be called CUnit::SetPlayerID, so we don't need to
// update the actor here.
// If we're a territory centre, change the territory's owner
if( m_associatedTerritory )
@ -1653,7 +1650,7 @@ JSBool CEntity::Construct( JSContext* cx, JSObject* UNUSED(obj), uint argc, jsva
std::set<CStr8> selections; // TODO: let scripts specify selections?
HEntity handle = g_EntityManager.create( baseEntity, position, orientation, selections );
handle->SetPlayer( player );
handle->m_actor->SetPlayerID( player->GetPlayerID() );
handle->Initialize();
*rval = ToJSVal<CEntity>( *handle );
@ -1699,17 +1696,10 @@ void CEntity::JSI_SetPlayer( jsval val )
(*it)->Remove( this );
}
// Switch player
m_player = newPlayer;
// Set actor player colour
if( m_actor )
m_actor->SetPlayerID( newPlayer->GetPlayerID() );
// If we're a territory centre, change the territory's owner
if( m_associatedTerritory )
m_associatedTerritory->owner = newPlayer;
m_actor->SetPlayerID( newPlayer->GetPlayerID() ); // calls this->SetPlayer
else
SetPlayer(newPlayer);
}
bool CEntity::Order( JSContext* cx, uintN argc, jsval* argv, bool Queued )

View File

@ -80,15 +80,13 @@ enum EntityFlags
class CEntity : public CJSComplex<CEntity>, public IEventTarget
{
friend class CEntityManager;
friend class CUnit;
typedef STL_HASH_MAP<CStrW, CAura*, CStrW_hash_compare> AuraTable;
typedef STL_HASH_MAP<int, SEntityAction> ActionTable;
typedef std::set<CAura*> AuraSet;
public:
// The player that owns this entity
CPlayer* m_player;
// Intrinsic properties
CEntityTemplate* m_base;
@ -274,10 +272,13 @@ public:
// Process tick.
void Tick();
// Store the player associated with this entity
void SetPlayer(CPlayer *pPlayer);
// Retrieve the player associated with this entity
private:
// The player that owns this entity.
// (Player is set publicly via CUnit::SetPlayerID)
CPlayer* m_player;
void SetPlayer(CPlayer* player);
public:
// Retrieve the player associated with this entity.
CPlayer* GetPlayer() { return m_player; }
// Update collision patch (move ourselves to a new one if necessary)

View File

@ -31,7 +31,7 @@ void CPathfindEngine::requestLowLevelPath( HEntity entity, const CVector2D& dest
CVector2D source( entity->m_position.X, entity->m_position.Z );
if ( mLowPathfinder.findPath(source, destination, entity->m_player, radius) )
if ( mLowPathfinder.findPath(source, destination, entity->GetPlayer(), radius) )
{
std::vector<CVector2D> path = mLowPathfinder.getLastPath();
if( path.size() > 0 )

View File

@ -14,7 +14,6 @@
#include "graphics/Unit.h"
#include "graphics/UnitManager.h"
#include "lib/timer.h"
#include "ps/CConsole.h"
#include "ps/CLogger.h"
#include "ps/Game.h"
#include "ps/GameAttributes.h"
@ -33,8 +32,6 @@
using namespace std;
extern CConsole *g_Console;
CSimulation::CSimulation(CGame *pGame):
m_pGame(pGame),
m_pWorld(pGame->GetWorld()),
@ -369,7 +366,7 @@ uint CSimulation::TranslateMessage(CNetMessage* pMsg, uint clientMask, void* UNU
// Create the object
CVector3D pos(msg->m_X/1000.0f, msg->m_Y/1000.0f, msg->m_Z/1000.0f);
HEntity newObj = g_EntityManager.createFoundation( msg->m_Template, player, pos, msg->m_Angle/1000.0f );
newObj->SetPlayer(player);
newObj->m_actor->SetPlayerID(player->GetPlayerID());
if( newObj->Initialize() )
{
// Order all the selected units to work on the new object using the given action

View File

@ -147,7 +147,7 @@ ActorViewer::ActorViewer(wxWindow* parent)
wglMakeCurrent(NULL, NULL);
POST_MESSAGE(SetContext, (canvas->GetContext()));
POST_MESSAGE(Init, ());
POST_MESSAGE(Init, (false));
canvas->InitSize();
canvas->PostLookAt();

View File

@ -357,7 +357,7 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent)
POST_MESSAGE(SetContext, (canvas->GetContext()));
POST_MESSAGE(Init, ());
POST_MESSAGE(Init, (true));
canvas->InitSize();

View File

@ -146,7 +146,7 @@ MESSAGEHANDLER(RotateAround)
MESSAGEHANDLER(LookAt)
{
// TODO: different view depending on
// TODO: different camera depending on msg->view
CCamera& camera = View::GetView_Actor()->GetCamera();
CVector3D tgt = msg->target->GetWorldSpace();

View File

@ -19,14 +19,23 @@
namespace AtlasMessage {
static bool g_DidInitSim;
MESSAGEHANDLER(Init)
{
UNUSED2(msg);
oglInit();
g_Quickstart = true;
Init(g_GameLoop->argc, g_GameLoop->argv, INIT_HAVE_VMODE|INIT_NO_GUI);
uint flags = INIT_HAVE_VMODE|INIT_NO_GUI;
if (! msg->initsimulation)
flags |= INIT_NO_SIM;
Init(g_GameLoop->argc, g_GameLoop->argv, flags);
g_DidInitSim = msg->initsimulation; // so we can shut down the right things later
#if OS_WIN
// HACK (to stop things looking very ugly when scrolling) - should
@ -48,7 +57,10 @@ MESSAGEHANDLER(Shutdown)
View::DestroyViews();
g_GameLoop->view = View::GetView_None();
Shutdown();
uint flags = 0;
if (! g_DidInitSim)
flags |= INIT_NO_SIM;
Shutdown(flags);
}

View File

@ -36,6 +36,8 @@ static bool SortObjectsList(const sObjectsListItem& a, const sObjectsListItem& b
QUERYHANDLER(GetObjectsList)
{
std::vector<sObjectsListItem> objects;
if (CEntityTemplateCollection::IsInitialised())
{
std::vector<CStrW> names;
g_EntityTemplateCollection.getEntityTemplateNames(names);
@ -184,20 +186,26 @@ BEGIN_COMMAND(SetObjectSettings)
void Redo()
{
CUnit* unit = g_UnitMan.FindByID(msg->id);
if (! unit) return;
unit->SetPlayerID(m_PlayerNew);
unit->SetActorSelections(m_SelectionsNew);
Set(m_PlayerNew, m_SelectionsNew);
}
void Undo()
{
Set(m_PlayerOld, m_SelectionsOld);
}
private:
void Set(int player, const std::set<CStr>& selections)
{
CUnit* unit = g_UnitMan.FindByID(msg->id);
if (! unit) return;
unit->SetPlayerID(m_PlayerOld);
unit->SetActorSelections(m_SelectionsOld);
unit->SetPlayerID(player);
unit->SetActorSelections(selections);
if (m_PlayerOld != m_PlayerNew)
g_Game->GetWorld()->GetTerritoryManager()->DelayedRecalculate();
}
};
END_COMMAND(SetObjectSettings);
@ -387,7 +395,7 @@ BEGIN_COMMAND(CreateObject)
}
else
{
ent->SetPlayer(g_Game->GetPlayer(m_Player));
ent->m_actor->SetPlayerID(m_Player);
ent->m_actor->SetID(m_ID);
if (ent->m_base->m_isTerritoryCentre)

View File

@ -9,7 +9,9 @@
//////////////////////////////////////////////////////////////////////////
MESSAGE(Init, );
MESSAGE(Init,
((bool, initsimulation)) // whether to initialise simulation/game-specific objects
);
MESSAGE(Shutdown, );