2004-07-27 23:00:53 +02:00
# include "precompiled.h"
# include "Game.h"
2005-07-03 18:25:48 +02:00
# include "GameAttributes.h"
2004-08-05 15:07:51 +02:00
# include "CLogger.h"
2005-01-01 18:30:55 +01:00
# ifndef NO_GUI
# include "gui/CGUI.h"
# endif
2005-03-18 23:02:20 +01:00
# include "timer.h"
2005-03-30 18:14:19 +02:00
# include "Profile.h"
2005-03-22 03:17:55 +01:00
# include "Loader.h"
2004-07-27 23:00:53 +02:00
2004-07-31 17:57:18 +02:00
CGame * g_Game = NULL ;
2004-07-27 23:00:53 +02:00
2004-11-27 04:22:04 +01:00
// Disable "warning C4355: 'this' : used in base member initializer list".
// "The base-class constructors and class member constructors are called before
// this constructor. In effect, you've passed a pointer to an unconstructed
// object to another constructor. If those other constructors access any
// members or call member functions on this, the result will be undefined."
// In this case, the pointers are simply stored for later use, so there
// should be no problem.
2005-08-09 17:55:44 +02:00
# if MSC_VERSION
2004-11-27 04:22:04 +01:00
# pragma warning (disable: 4355)
# endif
2004-08-05 15:07:51 +02:00
CGame : : CGame ( ) :
m_World ( this ) ,
m_Simulation ( this ) ,
m_GameView ( this ) ,
2004-09-21 16:40:43 +02:00
m_pLocalPlayer ( NULL ) ,
m_GameStarted ( false )
2004-08-05 15:07:51 +02:00
{
2005-05-11 20:56:30 +02:00
debug_printf ( " CGame::CGame(): Game object CREATED; initializing.. \n " ) ;
2004-08-05 15:07:51 +02:00
}
2005-08-09 17:55:44 +02:00
# if MSC_VERSION
2004-11-27 04:22:04 +01:00
# pragma warning (default: 4355)
# endif
2004-08-05 15:07:51 +02:00
CGame : : ~ CGame ( )
{
2005-03-30 18:14:19 +02:00
// Again, the in-game call tree is going to be different to the main menu one.
g_Profiler . StructuralReset ( ) ;
2005-05-11 20:56:30 +02:00
debug_printf ( " CGame::~CGame(): Game object DESTROYED \n " ) ;
2004-08-05 15:07:51 +02:00
}
2005-03-22 03:17:55 +01:00
PSRETURN CGame : : RegisterInit ( CGameAttributes * pAttribs )
{
LDR_BeginRegistering ( ) ;
// RC, 040804 - GameView needs to be initialised before World, otherwise GameView initialisation
// overwrites anything stored in the map file that gets loaded by CWorld::Initialize with default
// values. At the minute, it's just lighting settings, but could be extended to store camera position.
// Storing lighting settings in the gameview seems a little odd, but it's no big deal; maybe move it at
// some point to be stored in the world object?
m_GameView . RegisterInit ( pAttribs ) ;
m_World . RegisterInit ( pAttribs ) ;
m_Simulation . RegisterInit ( pAttribs ) ;
LDR_EndRegistering ( ) ;
return 0 ;
}
PSRETURN CGame : : ReallyStartGame ( )
{
2005-03-23 00:31:30 +01:00
# ifndef NO_GUI
2005-03-30 18:14:19 +02:00
2005-06-28 01:04:34 +02:00
// Call the reallyStartGame function, but only if it exists
jsval fval , rval ;
JSBool ok = JS_GetProperty ( g_ScriptingHost . getContext ( ) , g_GUI . GetScriptObject ( ) , " reallyStartGame " , & fval ) ;
2005-06-28 06:06:25 +02:00
debug_assert ( ok ) ;
2005-06-28 01:04:34 +02:00
if ( ok & & ! JSVAL_IS_VOID ( fval ) )
{
ok = JS_CallFunctionValue ( g_ScriptingHost . getContext ( ) , g_GUI . GetScriptObject ( ) , fval , 0 , NULL , & rval ) ;
2005-08-07 23:58:36 +02:00
debug_assert ( ok ) ;
2005-06-28 01:04:34 +02:00
}
2005-03-23 00:31:30 +01:00
# endif
2005-03-22 03:17:55 +01:00
2005-05-11 20:56:30 +02:00
debug_printf ( " GAME STARTED, ALL INIT COMPLETE \n " ) ;
2005-03-22 03:17:55 +01:00
m_GameStarted = true ;
2005-03-30 18:14:19 +02:00
// The call tree we've built for pregame probably isn't useful in-game.
g_Profiler . StructuralReset ( ) ;
2005-03-22 03:17:55 +01:00
# ifndef NO_GUI
g_GUI . SendEventToAll ( " sessionstart " ) ;
# endif
return 0 ;
}
2004-08-16 17:19:17 +02:00
PSRETURN CGame : : StartGame ( CGameAttributes * pAttribs )
2004-07-27 23:00:53 +02:00
{
2004-07-31 17:57:18 +02:00
try
{
2005-02-21 18:13:31 +01:00
pAttribs - > FinalizeSlots ( ) ;
m_NumPlayers = pAttribs - > GetSlotCount ( ) ;
2005-01-18 01:46:18 +01:00
2005-01-23 02:36:47 +01:00
// Player 0 = Gaia - allocate one extra
2005-01-18 01:46:18 +01:00
m_Players . resize ( m_NumPlayers + 1 ) ;
for ( uint i = 0 ; i < = m_NumPlayers ; i + + )
2005-02-21 18:13:31 +01:00
m_Players [ i ] = pAttribs - > GetPlayer ( i ) ;
2004-11-07 22:59:52 +01:00
2005-01-18 01:46:18 +01:00
m_pLocalPlayer = m_Players [ 1 ] ;
2004-08-16 17:19:17 +02:00
2005-03-22 03:17:55 +01:00
RegisterInit ( pAttribs ) ;
2004-07-31 17:57:18 +02:00
}
2005-05-24 02:00:40 +02:00
catch ( PSERROR_Game & e )
2004-07-31 17:57:18 +02:00
{
2005-05-24 02:00:40 +02:00
return e . getCode ( ) ;
2004-07-31 17:57:18 +02:00
}
return 0 ;
2004-07-27 23:00:53 +02:00
}
void CGame : : Update ( double deltaTime )
{
m_Simulation . Update ( deltaTime ) ;
// TODO Detect game over and bring up the summary screen or something
}
2005-01-29 01:11:50 +01:00
CPlayer * CGame : : GetPlayer ( uint idx )
{
if ( idx > m_NumPlayers )
{
2005-02-21 20:49:20 +01:00
// debug_warn("Invalid player ID");
2005-03-18 23:02:20 +01:00
// LOG(ERROR, "", "Invalid player ID %d (outside 0..%d)", idx, m_NumPlayers);
2005-01-29 01:11:50 +01:00
return m_Players [ 0 ] ;
}
// Be a bit more paranoid - maybe m_Players hasn't been set large enough
else if ( idx > = m_Players . size ( ) )
{
debug_warn ( " Invalid player ID " ) ;
LOG ( ERROR , " " , " Invalid player ID %d (not <=%d - internal error?) " , idx , m_Players . size ( ) ) ;
if ( m_Players . size ( ) = = 0 )
{
// Hmm. This is a bit of a problem.
2005-08-09 17:55:44 +02:00
debug_warn ( " ### ### ### ### ERROR: Tried to access the players list when there aren't any players. That really isn't going to work, so I'll give up. ### ### " ) ;
2005-01-29 01:11:50 +01:00
abort ( ) ;
2005-02-27 23:11:26 +01:00
return NULL ; // else VC2005 warns about not returning a value
2005-01-29 01:11:50 +01:00
}
else
return m_Players [ 0 ] ;
}
else
return m_Players [ idx ] ;
}