1
0
forked from 0ad/0ad

A few organization changes:

- Removed "Base" from the Technology and Formation class names (it
doesn't make sense because these don't use inheritance).
- Modified the tech methods a little so a player ID is passed to
applyEffects, not getTechnology.

Also added a game startup script which will eventually set up player
resource pools and give them their civ techs.

This was SVN commit r3996.
This commit is contained in:
Matei 2006-06-09 23:07:11 +00:00
parent 005983f237
commit 8d06d8601b
21 changed files with 212 additions and 200 deletions

View File

@ -82,7 +82,7 @@ PSRETURN CGame::ReallyStartGame()
{
#ifndef NO_GUI
// Call the reallyStartGame function, but only if it exists
// Call the reallyStartGame GUI function, but only if it exists
jsval fval, rval;
JSBool ok = JS_GetProperty(g_ScriptingHost.getContext(), g_GUI.GetScriptObject(), "reallyStartGame", &fval);
debug_assert(ok);
@ -93,6 +93,10 @@ PSRETURN CGame::ReallyStartGame()
}
#endif
// Call the game startup script
// TODO: Maybe don't do this if we're in Atlas
g_ScriptingHost.RunScript( "scripts/game_startup.js" );
debug_printf("GAME STARTED, ALL INIT COMPLETE\n");
m_GameStarted=true;

View File

@ -24,7 +24,7 @@ CPlayerSlot::CPlayerSlot(int slotID, CPlayer *pPlayer):
);
//AddProperty(L"session", (GetFn)&CPlayerSlot::JSI_GetSession);
AddLocalProperty(L"session", &m_pSession, true );
AddLocalProperty(L"session", &m_pSession, true );
AddLocalProperty(L"player", &m_pPlayer, true );
}
@ -183,6 +183,9 @@ namespace PlayerSlotArray_JS
CGameAttributes::CGameAttributes():
m_MapFile("test01.pmp"),
m_ResourceLevel("default"),
m_StartingPhase("default"),
m_LOSSetting(2),
m_NumSlots(8),
m_UpdateCB(NULL),
m_PlayerUpdateCB(NULL),
@ -197,6 +200,8 @@ CGameAttributes::CGameAttributes():
JS_SetPrivate(g_ScriptingHost.GetContext(), m_PlayerSlotArrayJS, this);
AddSynchedProperty(L"mapFile", &m_MapFile);
AddSynchedProperty(L"resourceLevel", &m_ResourceLevel);
AddSynchedProperty(L"startingPhase", &m_StartingPhase);
AddSynchedProperty(L"numSlots", &m_NumSlots, &CGameAttributes::OnNumSlotsUpdate);
AddSynchedProperty(L"losSetting", &m_LOSSetting);

View File

@ -116,9 +116,12 @@ public:
typedef void (UpdateCallback)(CStrW name, CStrW newValue, void *data);
CStrW m_MapFile;
CStrW m_ResourceLevel;
CStrW m_StartingPhase;
uint m_LOSSetting;
// Note: we must use the un-internationalized name of the resource level and starting phase
private:
friend JSBool PlayerSlotArray_JS::GetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp );

View File

@ -48,8 +48,8 @@
#include "maths/MathUtil.h"
#include "simulation/BaseEntityCollection.h"
#include "simulation/BaseFormationCollection.h"
#include "simulation/BaseTechCollection.h"
#include "simulation/FormationCollection.h"
#include "simulation/TechnologyCollection.h"
#include "simulation/Entity.h"
#include "simulation/EntityHandles.h"
#include "simulation/EntityManager.h"
@ -788,7 +788,7 @@ void Shutdown()
delete &g_JSGameEvents;
delete &g_FormationManager;
delete &g_BaseTechCollection;
delete &g_TechnologyCollection;
delete &g_EntityFormationCollection;
delete &g_EntityTemplateCollection;
TIMER_END("shutdown game scripting stuff");
@ -1013,10 +1013,10 @@ void Init(int argc, char* argv[], uint flags)
TIMER("Init_entitiessection");
// This needs to be done after the renderer has loaded all its actors...
new CBaseEntityCollection;
new CBaseFormationCollection;
new CBaseTechCollection;
new CFormationCollection;
new CTechnologyCollection;
g_EntityFormationCollection.loadTemplates();
g_BaseTechCollection.loadTemplates();
g_TechnologyCollection.loadTechnologies();
new CFormationManager;
// CEntityManager is managed by CWorld
@ -1088,7 +1088,6 @@ void Init(int argc, char* argv[], uint flags)
g_GameAttributes.m_MapFile = g_AutostartMap+".pmp";
for (int i=1; i<8; ++i)
g_GameAttributes.GetSlot(i)->AssignLocal();
g_GameAttributes.m_LOSSetting = 2;
g_Game = new CGame();
PSRETURN ret = g_Game->StartGame(&g_GameAttributes);

View File

@ -10,12 +10,15 @@
CPlayer::CPlayer(uint playerID):
m_PlayerID(playerID),
m_Name(CStrW(L"Player #")+CStrW(playerID)),
m_Civilization(L""),
m_Colour(0.7f, 0.7f, 0.7f),
m_UpdateCB(0)
{
m_LOSToken = LOS_GetTokenFor(playerID);
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.
@ -23,7 +26,6 @@ CPlayer::CPlayer(uint playerID):
// to CJSObject's list
ISynchedJSProperty *prop=new CSynchedJSProperty<SPlayerColour>(L"colour", &m_Colour, this);
m_SynchedProperties[L"colour"]=prop;
}
CPlayer::~CPlayer()

View File

@ -18,6 +18,7 @@ public:
private:
CStrW m_Name;
CStrW m_Civilization; // Note: this must be the un-internationalized name of the civ
PS_uint m_PlayerID;
PS_uint m_LOSToken;
SPlayerColour m_Colour;

View File

@ -34,7 +34,7 @@
#include "renderer/SkyManager.h"
#include "renderer/WaterManager.h"
#include "simulation/BaseEntityCollection.h"
#include "simulation/BaseTechCollection.h"
#include "simulation/TechnologyCollection.h"
#include "simulation/Entity.h"
#include "simulation/EntityFormation.h"
#include "simulation/EntityHandles.h"
@ -332,30 +332,18 @@ JSBool isFormationLocked( JSContext* cx, JSObject* UNUSED(obj), uint argc, jsval
// Techs
//-----------------------------------------------------------------------------
JSBool getTechTemplate( JSContext* cx, JSObject* UNUSED(obj), uint argc, jsval* argv, jsval* rval )
JSBool getTechnology( JSContext* cx, JSObject* UNUSED(obj), uint argc, jsval* argv, jsval* rval )
{
REQUIRE_MIN_PARAMS(2, getTechTemplate);
REQUIRE_MIN_PARAMS(1, getTechnology);
CStrW name = ToPrimitive<CStrW>( argv[0] );
PS_uint playerID = (PS_uint)ToPrimitive<int>( argv[1] );
*rval = JSVAL_NULL;
if ( g_Game->GetPlayer(playerID) )
{
//The tech will now temporarily belong to this player. This will change on the next call.
CBaseTech* tech = g_BaseTechCollection.getTemplate(name);
if ( tech )
{
tech->setPlayer( g_Game->GetPlayer(playerID) );
//*rval = OBJECT_TO_JSVAL(tech->GetScript());
*rval = ToJSVal( tech );
//*rval = ToJSVal( 42 );
}
else
JS_ReportError(cx, "Invalid tech template name \"%ls\" passed for getTechTemplate()", name.c_str() );
}
CTechnology* tech = g_TechnologyCollection.getTechnology( name );
if ( tech )
*rval = ToJSVal( tech );
else
JS_ReportError(cx, "Invalid playerID \"%d\"passed for getTechTemplate()", playerID);
JS_ReportError(cx, "Invalid tech template name \"%ls\" passed for getTechnology()", name.c_str() );
if ( rval )
return JS_TRUE;
@ -1203,7 +1191,7 @@ JSFunctionSpec ScriptFunctionTable[] =
JS_FUNC(isFormationLocked, isFormationLocked, 1)
//Tech
JS_FUNC(getTechTemplate, getTechTemplate, 2)
JS_FUNC(getTechnology, getTechnology, 2)
// Camera
JS_FUNC(setCameraTarget, setCameraTarget, 1)

View File

@ -1,34 +0,0 @@
//Andrew aka pyrolink - ajdecker1022@msn.com
//Manages the tech templates. More detail: see CBaseFormation and CBaseEntity (collections)
#ifndef BASETECH_COLLECTION_INCLUDED
#define BASETECH_COLLECTION_INCLUDED
#include <vector>
#include "ps/CStr.h"
#include "ps/Singleton.h"
#include "BaseTech.h"
#include "ps/Game.h"
#define g_BaseTechCollection CBaseTechCollection::GetSingleton()
class CBaseTechCollection : public Singleton<CBaseTechCollection>
{
typedef std::map<CStrW, CBaseTech*> templateMap;
typedef std::map<CStrW, CStr> templateFilenameMap;
templateMap m_templates;
templateFilenameMap m_templateFilenames;
public:
~CBaseTechCollection();
CBaseTech* getTemplate( CStrW techType );
int loadTemplates();
void LoadFile( const char* path );
// Create a list of the names of all base techs, excluding template_*,
// for display in ScEd's entity-selection box.
void getBaseTechNames( std::vector<CStrW>& names );
};
#endif

View File

@ -23,7 +23,7 @@
#include "renderer/WaterManager.h"
#include "EntityFormation.h"
#include "simulation/FormationManager.h"
#include "BaseFormation.h"
#include "Formation.h"
#include "graphics/GameView.h"
#include "graphics/UnitManager.h"

View File

@ -3,14 +3,14 @@
#include "EntityFormation.h"
#include "Entity.h"
#include "BaseFormationCollection.h"
#include "FormationCollection.h"
#include "FormationManager.h"
#include "Simulation.h"
#include "ps/Game.h"
#include "ps/Interact.h"
#include "ps/Network/NetMessage.h"
CEntityFormation::CEntityFormation( CBaseFormation*& base, size_t index )
CEntityFormation::CEntityFormation( CFormation*& base, size_t index )
{
if (!base)
return;
@ -38,7 +38,7 @@ CEntityFormation::~CEntityFormation()
}
}
}
void CEntityFormation::SwitchBase( CBaseFormation*& base )
void CEntityFormation::SwitchBase( CFormation*& base )
{
std::vector<CEntity*> copy;
copy.resize( m_base->m_numSlots );
@ -201,8 +201,8 @@ CVector2D CEntityFormation::GetSlotPosition( int order )
}
void CEntityFormation::BaseToMovement()
{
CBaseFormation* tmp = m_self;
CBaseFormation* move = g_EntityFormationCollection.getTemplate( m_base->m_movement );
CFormation* tmp = m_self;
CFormation* move = g_EntityFormationCollection.getTemplate( m_base->m_movement );
if (!move)
return;
SwitchBase( move );

View File

@ -1,13 +1,13 @@
//Andrew aka pyrolink
//ajdecker1022@msn.com
//Instances of this class contain the actual information about in-game formations.
//It is based off of BaseFormation.cpp and uses it as a reference as to what can and cannot
//It is based off of Formation.cpp and uses it as a reference as to what can and cannot
//be done in this formation. This is represented as m_base.
#ifndef ENTITYFORMATION_INCLUDED
#define ENTITYFORMATION_INCLUDED
#include "BaseFormation.h"
#include "Formation.h"
#include "ps/Vector2D.h"
class CVector2D;
@ -19,7 +19,7 @@ class CEntityFormation
{
friend class CFormationManager;
public:
CEntityFormation( CBaseFormation*& base, size_t index );
CEntityFormation( CFormation*& base, size_t index );
~CEntityFormation();
int GetEntityCount() { return m_numEntities; }
@ -29,7 +29,7 @@ public:
CEntityList GetEntityList();
CVector2D GetSlotPosition( int order );
CVector2D GetPosition() { return m_position; }
CBaseFormation* GetBase() { return m_base; }
CFormation* GetBase() { return m_base; }
void BaseToMovement();
void SelectAllUnits();
@ -51,8 +51,8 @@ private:
//Prevents other selected units from reordering the formation after one has already done it.
bool m_duplication;
CBaseFormation* m_base;
CBaseFormation* m_self; //Keeps track of base (referred to during movement switching)
CFormation* m_base;
CFormation* m_self; //Keeps track of base (referred to during movement switching)
std::vector<CEntity*> m_entities; //number of units currently in this formation
std::vector<bool> m_angleDivs; //attack direction penalty-true=being attacked from sector
@ -64,7 +64,7 @@ private:
bool IsBetterUnit( int order, CEntity* entity );
void UpdateFormation();
void SwitchBase( CBaseFormation*& base );
void SwitchBase( CFormation*& base );
void ResetIndex( size_t index );
void ResetAllEntities(); //Sets all handles to invalid

View File

@ -1,16 +1,16 @@
#include "precompiled.h"
#include "BaseFormation.h"
#include "Formation.h"
#include "ps/CLogger.h"
#include "ps/CStr.h"
#include "maths/MathUtil.h"
#define LOG_CATEGORY "Formation"
CBaseFormation::CBaseFormation()
CFormation::CFormation()
{
m_numSlots = 0;
}
bool CBaseFormation::loadXML(CStr filename)
bool CFormation::loadXML(CStr filename)
{
CXeromyces XeroFile;
@ -52,7 +52,7 @@ bool CBaseFormation::loadXML(CStr filename)
XMBElement Root = XeroFile.getRoot();
if( Root.getNodeName() != el_formation )
{
LOG( ERROR, LOG_CATEGORY, "CBaseFormation::LoadXML: XML root was not \"Formation\" in file %s. Load failed.", filename.c_str() );
LOG( ERROR, LOG_CATEGORY, "CFormation::LoadXML: XML root was not \"Formation\" in file %s. Load failed.", filename.c_str() );
return( false );
}
@ -104,7 +104,7 @@ bool CBaseFormation::loadXML(CStr filename)
else
{
const char* invAttr = XeroFile.getAttributeString(Attr.Name).c_str();
LOG( ERROR, LOG_CATEGORY, "CBaseFormation::LoadXML: Invalid attribute %s defined in formation file %s. Load failed.", invAttr, filename.c_str() );
LOG( ERROR, LOG_CATEGORY, "CFormation::LoadXML: Invalid attribute %s defined in formation file %s. Load failed.", invAttr, filename.c_str() );
return( false );
}
}
@ -147,7 +147,7 @@ bool CBaseFormation::loadXML(CStr filename)
if( order <= 0 )
{
LOG( ERROR, LOG_CATEGORY, "CBaseFormation::LoadXML: Invalid (negative number or 0) order defined in formation file %s. The game will try to continue anyway.", filename.c_str() );
LOG( ERROR, LOG_CATEGORY, "CFormation::LoadXML: Invalid (negative number or 0) order defined in formation file %s. The game will try to continue anyway.", filename.c_str() );
continue;
}
--order; //We need this to be in line with arrays, so start at 0
@ -179,7 +179,7 @@ bool CBaseFormation::loadXML(CStr filename)
{
if ( m_slots.find(i) == m_slots.end() )
{
LOG( ERROR, LOG_CATEGORY, "CBaseFormation::LoadXML: Missing orders in %s. Load failed.", filename.c_str() );
LOG( ERROR, LOG_CATEGORY, "CFormation::LoadXML: Missing orders in %s. Load failed.", filename.c_str() );
return false;
}
else
@ -192,7 +192,7 @@ bool CBaseFormation::loadXML(CStr filename)
return true;
}
void CBaseFormation::AssignCategory(int order, CStr category)
void CFormation::AssignCategory(int order, CStr category)
{
category.Remove( CStr(",") );
category = category + " "; //So the final word will be pushed as well

View File

@ -2,8 +2,8 @@
//ajdecker1022@msn.com
//This class loads all the formation data needs to create an instance of a particular formation.
#ifndef BASEFORMATION_INCLUDED
#define BASEFORMATION_INCLUDED
#ifndef FORMATION_INCLUDED
#define FORMATION_INCLUDED
#include <vector>
#include <map>
@ -11,10 +11,10 @@
class CStr;
class CBaseFormation
class CFormation
{
friend class CFormationManager;
friend class CBaseFormationCollection;
friend class CFormationCollection;
friend class CEntityFormation;
struct FormationSlot
@ -25,8 +25,8 @@ struct FormationSlot
};
public:
CBaseFormation();
~CBaseFormation(){}
CFormation();
~CFormation(){}
CStr GetBonus(){ return m_bonus; }
CStr GetBonusBase(){ return m_bonusBase; }

View File

@ -1,6 +1,6 @@
#include "precompiled.h"
#include "BaseFormationCollection.h"
#include "FormationCollection.h"
#include "graphics/ObjectManager.h"
#include "graphics/Model.h"
#include "ps/CLogger.h"
@ -9,7 +9,7 @@
#define LOG_CATEGORY "formation"
void CBaseFormationCollection::LoadFile( const char* path )
void CFormationCollection::LoadFile( const char* path )
{
// Build the formation name -> filename mapping. This is done so that
// the formation 'x' can be in units/x.xml, structures/x.xml, etc, and
@ -23,19 +23,19 @@ void CBaseFormationCollection::LoadFile( const char* path )
static void LoadFormationThunk( const char* path, const DirEnt* UNUSED(ent), void* context )
{
CBaseFormationCollection* this_ = (CBaseFormationCollection*)context;
CFormationCollection* this_ = (CFormationCollection*)context;
this_->LoadFile(path);
}
int CBaseFormationCollection::loadTemplates()
int CFormationCollection::loadTemplates()
{
// Load all files in entities/formations and subdirectories.
THROW_ERR( vfs_dir_enum( "entities/formations", VFS_DIR_RECURSIVE, "*.xml",
// Load all files in formations and subdirectories.
THROW_ERR( vfs_dir_enum( "formations", VFS_DIR_RECURSIVE, "*.xml",
LoadFormationThunk, this ) );
return 0;
}
CBaseFormation* CBaseFormationCollection::getTemplate( CStrW name )
CFormation* CFormationCollection::getTemplate( CStrW name )
{
// Check whether this template has already been loaded
templateMap::iterator it = m_templates.find( name );
@ -50,28 +50,28 @@ CBaseFormation* CBaseFormationCollection::getTemplate( CStrW name )
CStr path( filename_it->second );
//Try to load to the formation
CBaseFormation* newTemplate = new CBaseFormation();
CFormation* newTemplate = new CFormation();
if( !newTemplate->loadXML( path ) )
{
LOG(ERROR, LOG_CATEGORY, "CBaseFormationCollection::loadTemplates(): Couldn't load template \"%s\"", path.c_str());
LOG(ERROR, LOG_CATEGORY, "CFormationCollection::loadTemplates(): Couldn't load template \"%s\"", path.c_str());
delete newTemplate;
return( NULL );
}
LOG(NORMAL, LOG_CATEGORY, "CBaseFormationCollection::loadTemplates(): Loaded template \"%s\"", path.c_str());
LOG(NORMAL, LOG_CATEGORY, "CFormationCollection::loadTemplates(): Loaded template \"%s\"", path.c_str());
m_templates[name] = newTemplate;
return newTemplate;
}
void CBaseFormationCollection::getBaseFormationNames( std::vector<CStrW>& names )
void CFormationCollection::getFormationNames( std::vector<CStrW>& names )
{
for( templateFilenameMap::iterator it = m_templateFilenames.begin(); it != m_templateFilenames.end(); ++it )
if( ! (it->first.Length() > 8 && it->first.Left(8) == L"template"))
names.push_back( it->first );
}
CBaseFormationCollection::~CBaseFormationCollection()
CFormationCollection::~CFormationCollection()
{
for( templateMap::iterator it = m_templates.begin(); it != m_templates.end(); ++it )
delete( it->second );

View File

@ -1,37 +1,37 @@
//BaseFormationCollection.h
//FormationCollection.h
//Andrew aka pyrolink: ajdecker1022@msn.com
//Nearly identical to BaseEntityCollection and associates i.e. BaseEntity, Entity.
//This is the manager of the entity formation "templates"
#ifndef BASEFORM_COLLECTION_INCLUDED
#define BASEFORM_COLLECTION_INCLUDED
#ifndef FORMATION_COLLECTION_INCLUDED
#define FORMATION_COLLECTION_INCLUDED
#include <vector>
#include "ps/CStr.h"
#include "ps/Singleton.h"
#include "BaseFormation.h"
#include "Formation.h"
#define g_EntityFormationCollection CBaseFormationCollection::GetSingleton()
#define g_EntityFormationCollection CFormationCollection::GetSingleton()
class CBaseFormationCollection : public Singleton<CBaseFormationCollection>
class CFormationCollection : public Singleton<CFormationCollection>
{
typedef std::map<CStrW, CBaseFormation*> templateMap;
typedef std::map<CStrW, CFormation*> templateMap;
typedef std::map<CStrW, CStr> templateFilenameMap;
templateMap m_templates;
templateFilenameMap m_templateFilenames;
public:
~CBaseFormationCollection();
CBaseFormation* getTemplate( CStrW formationType );
~CFormationCollection();
CFormation* getTemplate( CStrW formationType );
int loadTemplates();
void LoadFile( const char* path );
// Create a list of the names of all base entities, excluding template_*,
// for display in ScEd's entity-selection box.
void getBaseFormationNames( std::vector<CStrW>& names );
void getFormationNames( std::vector<CStrW>& names );
};
#endif

View File

@ -3,7 +3,7 @@
#include "FormationManager.h"
#include "Entity.h"
#include "ps/CStr.h"
#include "BaseFormation.h"
#include "Formation.h"
#include "EntityFormation.h"
#include "EventHandlers.h"
@ -21,7 +21,7 @@ void CFormationManager::CreateFormation( CEntityList& entities, CStrW& name )
debug_warn("Attempting to create a formation with no entities");
return;
}
CBaseFormation* base = g_EntityFormationCollection.getTemplate(name);
CFormation* base = g_EntityFormationCollection.getTemplate(name);
if (!base)
return;
if ( entities.size() < (size_t)base->m_required )
@ -79,7 +79,7 @@ bool CFormationManager::AddUnit( CEntity*& entity, int& form )
//Adding too many?
if ( (*it)->m_numEntities == (*it)->m_base->m_numSlots )
{
CBaseFormation* next = g_EntityFormationCollection.getTemplate((*it)->m_base->m_next);
CFormation* next = g_EntityFormationCollection.getTemplate((*it)->m_base->m_next);
if (next)
(*it)->SwitchBase( next );
}
@ -109,7 +109,7 @@ bool CFormationManager::RemoveUnit( CEntity*& entity )
FormIterator it = m_formations.begin() + entity->m_formation;
if ( (*it)->m_numEntities == (*it)->m_base->m_required )
{
CBaseFormation* prior = g_EntityFormationCollection.getTemplate((*it)->m_base->m_prior);
CFormation* prior = g_EntityFormationCollection.getTemplate((*it)->m_base->m_prior);
//Disband formation
if (!prior)
{

View File

@ -6,14 +6,14 @@
#define FORMATIONMANAGER_INCLUDED
#include "ps/Singleton.h"
#include "BaseFormationCollection.h"
#include "FormationCollection.h"
#include "scripting/DOMEvent.h"
#define g_FormationManager CFormationManager::GetSingleton()
class CEntity;
class CStr;
class CBaseFormation;
class CFormation;
class CVector2D;
class CEntityFormation;

View File

@ -1,6 +1,6 @@
#include "precompiled.h"
#include "BaseTech.h"
#include "BaseTechCollection.h"
#include "Technology.h"
#include "TechnologyCollection.h"
#include "EntityManager.h"
#include "ps/CStr.h"
#include "ps/CLogger.h"
@ -13,9 +13,9 @@
#define LOG_CATEGORY "Techs"
STL_HASH_SET<CStr, CStr_hash_compare> CBaseTech::m_scriptsLoaded;
STL_HASH_SET<CStr, CStr_hash_compare> CTechnology::m_scriptsLoaded;
CBaseTech::CBaseTech()
CTechnology::CTechnology()
{
ONCE( ScriptingInit(); );
@ -23,7 +23,7 @@ CBaseTech::CBaseTech()
m_effectFunction = NULL;
m_JSFirst = false;
}
bool CBaseTech::loadXML( CStr filename )
bool CTechnology::loadXML( CStr filename )
{
CXeromyces XeroFile;
@ -42,7 +42,7 @@ bool CBaseTech::loadXML( CStr filename )
XMBElement Root = XeroFile.getRoot();
if ( Root.getNodeName() != el_tech )
{
LOG( ERROR, LOG_CATEGORY, "CBaseTech: XML root was not \"Tech\" in file %s. Load failed.", filename.c_str() );
LOG( ERROR, LOG_CATEGORY, "CTechnology: XML root was not \"Tech\" in file %s. Load failed.", filename.c_str() );
return false;
}
XMBElementList RootChildren = Root.getChildNodes();
@ -61,14 +61,14 @@ bool CBaseTech::loadXML( CStr filename )
continue;
if ( !ret )
{
LOG( ERROR, LOG_CATEGORY, "CBaseTech: Load failed for file %s", filename.c_str() );
LOG( ERROR, LOG_CATEGORY, "CTechnology: Load failed for file %s", filename.c_str() );
return false;
}
}
return true;
}
bool CBaseTech::loadELID( XMBElement ID, CXeromyces& XeroFile )
bool CTechnology::loadELID( XMBElement ID, CXeromyces& XeroFile )
{
#define EL(x) int el_##x = XeroFile.getElementID(#x)
@ -106,13 +106,13 @@ bool CBaseTech::loadELID( XMBElement ID, CXeromyces& XeroFile )
else
{
const char* tagName = XeroFile.getElementString(name).c_str();
LOG( ERROR, LOG_CATEGORY, "CBaseTech: invalid tag %s for XML file", tagName );
LOG( ERROR, LOG_CATEGORY, "CTechnology: invalid tag %s for XML file", tagName );
return false;
}
}
return true;
}
bool CBaseTech::loadELReq( XMBElement Req, CXeromyces& XeroFile )
bool CTechnology::loadELReq( XMBElement Req, CXeromyces& XeroFile )
{
#define EL(x) int el_##x = XeroFile.getElementID(#x)
@ -156,7 +156,7 @@ bool CBaseTech::loadELReq( XMBElement Req, CXeromyces& XeroFile )
else
{
const char* tagName = XeroFile.getElementString(name).c_str();
LOG( ERROR, LOG_CATEGORY, "CBaseTech: invalid tag %s for XML file", tagName );
LOG( ERROR, LOG_CATEGORY, "CTechnology: invalid tag %s for XML file", tagName );
return false;
}
}
@ -168,13 +168,13 @@ bool CBaseTech::loadELReq( XMBElement Req, CXeromyces& XeroFile )
else
{
const char* tagName = XeroFile.getElementString(name).c_str();
LOG( ERROR, LOG_CATEGORY, "CBaseTech: invalid tag %s for XML file", tagName );
LOG( ERROR, LOG_CATEGORY, "CTechnology: invalid tag %s for XML file", tagName );
return false;
}
}
return true;
}
bool CBaseTech::loadELEffect( XMBElement effect, CXeromyces& XeroFile, CStr& filename )
bool CTechnology::loadELEffect( XMBElement effect, CXeromyces& XeroFile, CStr& filename )
{
#define EL(x) int el_##x = XeroFile.getElementID(#x)
#define AT(x) int at_##x = XeroFile.getAttributeID(#x)
@ -219,7 +219,7 @@ bool CBaseTech::loadELEffect( XMBElement effect, CXeromyces& XeroFile, CStr& fil
{
if ( CEntity::m_AttributeTable.find( modValue ) == CEntity::m_AttributeTable.end() )
{
LOG( ERROR, LOG_CATEGORY, "CBaseTech::loadXML invalid attribute %s for modifier attribute", modValue);
LOG( ERROR, LOG_CATEGORY, "CTechnology::loadXML invalid attribute %s for modifier attribute", modValue);
m_Modifiers.pop_back();
return false;
}
@ -230,7 +230,7 @@ bool CBaseTech::loadELEffect( XMBElement effect, CXeromyces& XeroFile, CStr& fil
m_Modifiers.back().value = modValue.ToFloat();
else
{
LOG( ERROR, LOG_CATEGORY, "CBaseTech::loadXML invalid tag inside \"Modifier\" tag" );
LOG( ERROR, LOG_CATEGORY, "CTechnology::loadXML invalid tag inside \"Modifier\" tag" );
m_Modifiers.pop_back();
return false;
}
@ -250,7 +250,7 @@ bool CBaseTech::loadELEffect( XMBElement effect, CXeromyces& XeroFile, CStr& fil
{
if ( CEntity::m_AttributeTable.find( setValue ) == CEntity::m_AttributeTable.end() )
{
LOG( ERROR, LOG_CATEGORY, "CBaseTech::loadXML invalid attribute %s for \"set\" attribute", setValue);
LOG( ERROR, LOG_CATEGORY, "CTechnology::loadXML invalid attribute %s for \"set\" attribute", setValue);
m_Sets.pop_back();
return false;
}
@ -261,7 +261,7 @@ bool CBaseTech::loadELEffect( XMBElement effect, CXeromyces& XeroFile, CStr& fil
m_Sets.back().value = setValue.ToFloat();
else
{
LOG( ERROR, LOG_CATEGORY, "CBaseTech::loadXML invalid tag inside \"Set\" tag" );
LOG( ERROR, LOG_CATEGORY, "CTechnology::loadXML invalid tag inside \"Set\" tag" );
m_Sets.pop_back();
return false;
}
@ -297,7 +297,7 @@ bool CBaseTech::loadELEffect( XMBElement effect, CXeromyces& XeroFile, CStr& fil
JSFunction* fn = JS_ValueToFunction( g_ScriptingHost.GetContext(), fnval );
if( !fn )
{
LOG( ERROR, LOG_CATEGORY, "CBaseTech::LoadXML: Function does not exist for %hs in file %s. Load failed.", funcName.c_str(), filename.c_str() );
LOG( ERROR, LOG_CATEGORY, "CTechnology::LoadXML: Function does not exist for %hs in file %s. Load failed.", funcName.c_str(), filename.c_str() );
return false;
}
m_effectFunction->SetFunction( fn );
@ -309,13 +309,13 @@ bool CBaseTech::loadELEffect( XMBElement effect, CXeromyces& XeroFile, CStr& fil
else
{
const char* tagName = XeroFile.getElementString(name).c_str();
LOG( ERROR, LOG_CATEGORY, "CBaseTech: invalid tag %s for XML file", tagName );
LOG( ERROR, LOG_CATEGORY, "CTechnology: invalid tag %s for XML file", tagName );
return false;
}
}
return true;
}
bool CBaseTech::isTechValid()
bool CTechnology::isTechValid()
{
if ( m_excluded )
return false;
@ -323,7 +323,7 @@ bool CBaseTech::isTechValid()
return true;
return false;
}
bool CBaseTech::hasReqEntities()
bool CTechnology::hasReqEntities()
{
bool ret=true;
std::vector<HEntity>* entities = m_player->GetControlledEntities();
@ -341,12 +341,12 @@ bool CBaseTech::hasReqEntities()
delete entities;
return ret;
}
bool CBaseTech::hasReqTechs()
bool CTechnology::hasReqTechs()
{
bool ret=true;
for ( std::vector<CStr>::iterator it=m_ReqTechs.begin(); it != m_ReqTechs.end(); it++ )
{
if ( !g_BaseTechCollection.getTemplate( (CStrW)*it )->isResearched() )
if ( !g_TechnologyCollection.getTechnology( (CStrW)*it )->isResearched() )
{
ret=false;
break;
@ -356,59 +356,66 @@ bool CBaseTech::hasReqTechs()
}
//JS stuff
void CBaseTech::ScriptingInit()
void CTechnology::ScriptingInit()
{
AddProperty(L"generic", &CBaseTech::m_Generic, true);
AddProperty(L"specific", &CBaseTech::m_Specific, true);
AddProperty(L"icon", &CBaseTech::m_Icon); //GUI might want to change this...?
AddProperty<int>(L"icon_cell", &CBaseTech::m_IconCell);
AddProperty(L"classes", &CBaseTech::m_Classes, true);
AddProperty(L"history", &CBaseTech::m_History, true);
AddProperty(L"generic", &CTechnology::m_Generic, true);
AddProperty(L"specific", &CTechnology::m_Specific, true);
AddProperty(L"icon", &CTechnology::m_Icon); //GUI might want to change this...?
AddProperty<int>(L"icon_cell", &CTechnology::m_IconCell);
AddProperty(L"classes", &CTechnology::m_Classes, true);
AddProperty(L"history", &CTechnology::m_History, true);
AddProperty<float>(L"time", &CBaseTech::m_ReqTime); //Techs may upgrade research time and cost of other techs
AddProperty<float>(L"food", &CBaseTech::m_ReqFood);
AddProperty<float>(L"wood", &CBaseTech::m_ReqWood);
AddProperty<float>(L"stone", &CBaseTech::m_ReqStone);
AddProperty<float>(L"ore", &CBaseTech::m_ReqOre);
AddProperty<float>(L"time", &CTechnology::m_ReqTime); //Techs may upgrade research time and cost of other techs
AddProperty<float>(L"food", &CTechnology::m_ReqFood);
AddProperty<float>(L"wood", &CTechnology::m_ReqWood);
AddProperty<float>(L"stone", &CTechnology::m_ReqStone);
AddProperty<float>(L"ore", &CTechnology::m_ReqOre);
AddMethod<jsval, &CBaseTech::ApplyEffects>( "applyEffects", 1 );
AddMethod<jsval, &CBaseTech::IsExcluded>( "isExcluded", 0 );
AddMethod<jsval, &CBaseTech::IsValid>( "isValid", 0 );
AddMethod<jsval, &CBaseTech::IsResearched>( "isResearched", 0 );
AddMethod<jsval, &CBaseTech::GetPlayerID>( "getPlayerID", 0 );
AddMethod<jsval, &CBaseTech::IsJSFirst>( "isJSFirst", 0 );
AddMethod<jsval, &CTechnology::ApplyEffects>( "applyEffects", 1 );
AddMethod<jsval, &CTechnology::IsExcluded>( "isExcluded", 0 );
AddMethod<jsval, &CTechnology::IsValid>( "isValid", 0 );
AddMethod<jsval, &CTechnology::IsResearched>( "isResearched", 0 );
AddMethod<jsval, &CTechnology::GetPlayerID>( "getPlayerID", 0 );
AddMethod<jsval, &CTechnology::IsJSFirst>( "isJSFirst", 0 );
CJSObject<CBaseTech>::ScriptingInit("TechTemplate");
CJSObject<CTechnology>::ScriptingInit("Technology");
debug_printf("CBaseTech::ScriptingInit complete");
debug_printf("CTechnology::ScriptingInit complete");
}
jsval CBaseTech::ApplyEffects( JSContext* cx, uintN argc, jsval* argv )
jsval CTechnology::ApplyEffects( JSContext* cx, uintN argc, jsval* argv )
{
if ( !isTechValid() )
return JS_FALSE;
else if ( argc < 2 )
else if ( argc < 3 )
{
JS_ReportError(cx, "too few parameters for CBaseTech::ApplyEffects.");
JS_ReportError(cx, "too few parameters for CTechnology::ApplyEffects.");
return JS_FALSE;
}
//Order overriding for some special case
bool first = ToPrimitive<bool>( argv[0] );
bool invert = ToPrimitive<bool>( argv[1] );
m_player = g_Game->GetPlayer( ToPrimitive<PS_uint>( argv[0] ) );
if( m_player == 0 )
{
JS_ReportError(cx, "invalid player number for CTechnology::ApplyEffects.");
return JS_FALSE;
}
bool first = ToPrimitive<bool>( argv[1] );
bool invert = ToPrimitive<bool>( argv[2] );
//Optional type overriding if some in some special case the script wants to modify non-floats
CStr varType("float");
if ( argc == 3 )
varType = ToPrimitive<CStr>( argv[2] );
if ( argc == 4 )
varType = ToPrimitive<CStr>( argv[3] );
if ( first )
if( m_effectFunction )
m_effectFunction->Run( this->GetScript() );
if ( first && m_effectFunction )
{
m_effectFunction->Run( this->GetScript() );
}
//Disable other templates
for ( std::vector<CStr>::iterator it=m_Pairs.begin(); it != m_Pairs.end(); it++ )
g_BaseTechCollection.getTemplate(*it)->setExclusion(true);
g_TechnologyCollection.getTechnology(*it)->setExclusion(true);
std::vector<HEntity>* entities = m_player->GetControlledEntities();
if ( entities->empty() )
@ -473,37 +480,38 @@ jsval CBaseTech::ApplyEffects( JSContext* cx, uintN argc, jsval* argv )
}
}
if ( !first )
if( m_effectFunction )
m_effectFunction->Run( this->GetScript() );
if ( !first && m_effectFunction )
{
m_effectFunction->Run( this->GetScript() );
}
delete entities;
debug_printf("Done! I think\n");
return JS_TRUE;
}
jsval CBaseTech::IsValid( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
jsval CTechnology::IsValid( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
{
if ( isTechValid() )
return JS_TRUE;
return JS_FALSE;
}
jsval CBaseTech::IsExcluded( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
jsval CTechnology::IsExcluded( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
{
if ( m_excluded )
return JS_TRUE;
return JS_FALSE;
}
jsval CBaseTech::IsResearched( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
jsval CTechnology::IsResearched( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
{
if ( isResearched() )
return JS_TRUE;
return JS_FALSE;
}
inline jsval CBaseTech::GetPlayerID( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
inline jsval CTechnology::GetPlayerID( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
{
return ToJSVal( m_player->GetPlayerID() );
}
jsval CBaseTech::IsJSFirst( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
jsval CTechnology::IsJSFirst( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv) )
{
if ( m_JSFirst )
return JS_TRUE;

View File

@ -2,8 +2,8 @@
//ajdecker1022@msn.com
//Holds template information for technologies and research
#ifndef BASETECH_INCLUDED
#define BASETECH_INCLUDED
#ifndef TECHNOLOGY_INCLUDED
#define TECHNOLOGY_INCLUDED
#include <vector>
#include "scripting/ScriptableObject.h"
@ -12,9 +12,9 @@ class CStr;
class XMBElement;
class CXeromyces;
class CBaseTech : public CJSObject<CBaseTech>
class CTechnology : public CJSObject<CTechnology>
{
friend class CBaseTechCollection;
friend class CTechnologyCollection;
typedef struct Modifier
{
@ -25,8 +25,8 @@ class CBaseTech : public CJSObject<CBaseTech>
static STL_HASH_SET<CStr, CStr_hash_compare> m_scriptsLoaded;
public:
CBaseTech();
~CBaseTech() {}
CTechnology();
~CTechnology() {}
//JS functions
static void ScriptingInit();
@ -75,6 +75,8 @@ private:
CScriptObject* m_effectFunction;
bool m_JSFirst; //Should JS effect function run before C++
// TODO: Make these per-player
bool m_excluded;
bool m_researched;

View File

@ -1,12 +1,12 @@
#include "precompiled.h"
#include "BaseTechCollection.h"
#include "TechnologyCollection.h"
#include "ps/CLogger.h"
#include "ps/VFSUtil.h"
#define LOG_CATEGORY "tech"
void CBaseTechCollection::LoadFile( const char* path )
void CTechnologyCollection::LoadFile( const char* path )
{
//Make tech file reading
CStrW tag = CStr(path).AfterLast("/").BeforeLast(".xml");
@ -15,19 +15,19 @@ void CBaseTechCollection::LoadFile( const char* path )
static void LoadTechThunk( const char* path, const DirEnt* UNUSED(ent), void* context )
{
CBaseTechCollection* this_ = (CBaseTechCollection*)context;
CTechnologyCollection* this_ = (CTechnologyCollection*)context;
this_->LoadFile(path);
}
int CBaseTechCollection::loadTemplates()
int CTechnologyCollection::loadTechnologies()
{
// Load all files in techs/ and subdirectories.
THROW_ERR( vfs_dir_enum( "techs/", VFS_DIR_RECURSIVE, "*.xml",
THROW_ERR( vfs_dir_enum( "technologies/", VFS_DIR_RECURSIVE, "*.xml",
LoadTechThunk, this ) );
return 0;
}
CBaseTech* CBaseTechCollection::getTemplate( CStrW name )
CTechnology* CTechnologyCollection::getTechnology( CStrW name )
{
// Check whether this template has already been loaded.
//If previously loaded, all slots will be found, so any entry works.
@ -43,28 +43,28 @@ CBaseTech* CBaseTechCollection::getTemplate( CStrW name )
CStr path( filename_it->second );
//Try to load to the tech
CBaseTech* newTemplate = new CBaseTech();
CTechnology* newTemplate = new CTechnology();
if( !newTemplate->loadXML( path ) )
{
LOG(ERROR, LOG_CATEGORY, "CBaseTechCollection::loadTemplates(): Couldn't load template \"%s\"", path.c_str());
LOG(ERROR, LOG_CATEGORY, "CTechnologyCollection::getTechnology(): Couldn't load template \"%s\"", path.c_str());
delete newTemplate;
return( NULL );
}
m_templates[name] = newTemplate;
LOG(NORMAL, LOG_CATEGORY, "CBaseTechCollection::loadTemplates(): Loaded template \"%s\"", path.c_str());
LOG(NORMAL, LOG_CATEGORY, "CTechnologyCollection::getTechnology(): Loaded template \"%s\"", path.c_str());
return newTemplate;
}
void CBaseTechCollection::getBaseTechNames( std::vector<CStrW>& names )
void CTechnologyCollection::getTechnologyNames( std::vector<CStrW>& names )
{
for( templateFilenameMap::iterator it = m_templateFilenames.begin(); it != m_templateFilenames.end(); ++it )
if( ! (it->first.Length() > 8 && it->first.Left(8) == L"template"))
names.push_back( it->first );
}
CBaseTechCollection::~CBaseTechCollection()
CTechnologyCollection::~CTechnologyCollection()
{
for( templateMap::iterator it = m_templates.begin(); it != m_templates.end(); ++it )
delete( it->second );

View File

@ -0,0 +1,34 @@
//Andrew aka pyrolink - ajdecker1022@msn.com
//Manages the tech templates. More detail: see CFormation and CBaseEntity (collections)
#ifndef TECHNOLOGY_COLLECTION_INCLUDED
#define TECHNOLOGY_COLLECTION_INCLUDED
#include <vector>
#include "ps/CStr.h"
#include "ps/Singleton.h"
#include "Technology.h"
#include "ps/Game.h"
#define g_TechnologyCollection CTechnologyCollection::GetSingleton()
class CTechnologyCollection : public Singleton<CTechnologyCollection>
{
typedef std::map<CStrW, CTechnology*> templateMap;
typedef std::map<CStrW, CStr> templateFilenameMap;
templateMap m_templates;
templateFilenameMap m_templateFilenames;
public:
~CTechnologyCollection();
CTechnology* getTechnology( CStrW techType );
int loadTechnologies();
void LoadFile( const char* path );
// Create a list of the names of all base techs, excluding template_*,
// for display in ScEd's entity-selection box.
void getTechnologyNames( std::vector<CStrW>& names );
};
#endif