Initial commit of Command & Conquer Generals and Command & Conquer Generals Zero Hour source code.
This commit is contained in:
parent
2e338c00cb
commit
3d0ee53a05
6072 changed files with 2283311 additions and 0 deletions
196
Generals/Code/GameEngine/Source/GameLogic/System/CaveSystem.cpp
Normal file
196
Generals/Code/GameEngine/Source/GameLogic/System/CaveSystem.cpp
Normal file
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CaveSystem.cpp /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood July 2002
|
||||
// Desc: System responsible for keeping track of all cave systems on the map
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
|
||||
|
||||
#include "Common/GameState.h"
|
||||
#include "Common/TunnelTracker.h"
|
||||
#include "Common/Xfer.h"
|
||||
#include "GameLogic/CaveSystem.h"
|
||||
|
||||
CaveSystem *TheCaveSystem = NULL;
|
||||
|
||||
CaveSystem::CaveSystem()
|
||||
{
|
||||
}
|
||||
|
||||
CaveSystem::~CaveSystem()
|
||||
{
|
||||
}
|
||||
|
||||
void CaveSystem::init()
|
||||
{
|
||||
}
|
||||
|
||||
void CaveSystem::reset()
|
||||
{
|
||||
for( std::vector<TunnelTracker*>::iterator iter = m_tunnelTrackerVector.begin(); iter != m_tunnelTrackerVector.end(); iter++ )
|
||||
{
|
||||
TunnelTracker *currentTracker = *iter;
|
||||
if( currentTracker )// could be NULL, since we don't slide back to fill deleted entries so offsets don't shift
|
||||
{
|
||||
currentTracker->deleteInstance();
|
||||
}
|
||||
}
|
||||
m_tunnelTrackerVector.clear();
|
||||
}
|
||||
|
||||
void CaveSystem::update()
|
||||
{
|
||||
}
|
||||
|
||||
Bool CaveSystem::canSwitchIndexToIndex( Int oldIndex, Int newIndex )
|
||||
{
|
||||
// When I grant permission, you need to do it. ie call Unregister and then re-register with the new number
|
||||
TunnelTracker *oldTracker = NULL;
|
||||
TunnelTracker *newTracker = NULL;
|
||||
if( m_tunnelTrackerVector.size() > oldIndex )
|
||||
{
|
||||
oldTracker = m_tunnelTrackerVector[oldIndex];
|
||||
if( oldTracker && oldTracker->getContainCount() > 0 )
|
||||
return FALSE;// You can't switch a connection if one of the two is non empty
|
||||
}
|
||||
if( m_tunnelTrackerVector.size() > newIndex )
|
||||
{
|
||||
newTracker = m_tunnelTrackerVector[newIndex];
|
||||
if( newTracker && newTracker->getContainCount() > 0 )
|
||||
return FALSE;// You can't switch a connection if one of the two is non empty
|
||||
}
|
||||
|
||||
// Both are either empty or non-existent, so go ahead.
|
||||
// (Remember non-exist is only a valid case because you are going to do the switch now.)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CaveSystem::registerNewCave( Int theIndex )
|
||||
{
|
||||
Bool needToCreate = FALSE;
|
||||
if( theIndex >= m_tunnelTrackerVector.size() )
|
||||
{
|
||||
// You are new and off the edge, so I will fill NULLs up to you and then make a newTracker at that spot
|
||||
while( theIndex >= m_tunnelTrackerVector.size() )
|
||||
m_tunnelTrackerVector.push_back( NULL );
|
||||
|
||||
needToCreate = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// else you either exist or have existed, so I will either let things be or re-create that slot
|
||||
if( m_tunnelTrackerVector[theIndex] == NULL )
|
||||
needToCreate = TRUE;
|
||||
}
|
||||
|
||||
if( needToCreate )// if true, we new theIndex is the index of a NULL to be filled
|
||||
m_tunnelTrackerVector[theIndex] = newInstance(TunnelTracker);
|
||||
}
|
||||
|
||||
void CaveSystem::unregisterCave( Int theIndex )
|
||||
{
|
||||
// Doesn't need to do a thing. ContainModule logic knows how to say goodbye, and a TunnelTracker
|
||||
// knows how to exist while having no entry points.
|
||||
theIndex;
|
||||
}
|
||||
|
||||
TunnelTracker *CaveSystem::getTunnelTrackerForCaveIndex( Int theIndex )
|
||||
{
|
||||
TunnelTracker *theTracker = NULL;
|
||||
if( theIndex < m_tunnelTrackerVector.size() )
|
||||
{
|
||||
theTracker = m_tunnelTrackerVector[theIndex];
|
||||
}
|
||||
|
||||
DEBUG_ASSERTCRASH( theTracker != NULL, ("No one should be interested in a sub-cave that doesn't exist.") );
|
||||
|
||||
return theTracker;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/** Xfer Method
|
||||
* Version Info
|
||||
* 1: Initial version */
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CaveSystem::xfer( Xfer *xfer )
|
||||
{
|
||||
|
||||
// version
|
||||
XferVersion currentVersion = 1;
|
||||
XferVersion version = currentVersion;
|
||||
xfer->xferVersion( &version, currentVersion );
|
||||
|
||||
// tunnel tracker size and data
|
||||
UnsignedShort count = m_tunnelTrackerVector.size();
|
||||
xfer->xferUnsignedShort( &count );
|
||||
TunnelTracker *tracker;
|
||||
if( xfer->getXferMode() == XFER_SAVE )
|
||||
{
|
||||
std::vector< TunnelTracker* >::iterator it;
|
||||
|
||||
for( it = m_tunnelTrackerVector.begin(); it != m_tunnelTrackerVector.end(); ++it )
|
||||
{
|
||||
|
||||
// xfer data
|
||||
tracker = *it;
|
||||
xfer->xferSnapshot( tracker );
|
||||
|
||||
} // end
|
||||
|
||||
} // end if, save
|
||||
else
|
||||
{
|
||||
|
||||
// the list must be empty now
|
||||
if( m_tunnelTrackerVector.empty() == FALSE )
|
||||
{
|
||||
|
||||
DEBUG_CRASH(( "CaveSystem::xfer - m_tunnelTrackerVector should be empty but is not\n" ));
|
||||
throw SC_INVALID_DATA;
|
||||
|
||||
} // end if
|
||||
|
||||
// read each item
|
||||
for( UnsignedShort i = 0; i < count; ++i )
|
||||
{
|
||||
|
||||
// allocate new tracker
|
||||
tracker = newInstance( TunnelTracker );
|
||||
|
||||
// read data
|
||||
xfer->xferSnapshot( tracker );
|
||||
|
||||
// put in vector
|
||||
m_tunnelTrackerVector.push_back( tracker );
|
||||
|
||||
} // end for, i
|
||||
|
||||
} // end else, laod
|
||||
|
||||
} // end xfer
|
||||
|
||||
|
229
Generals/Code/GameEngine/Source/GameLogic/System/CrateSystem.cpp
Normal file
229
Generals/Code/GameEngine/Source/GameLogic/System/CrateSystem.cpp
Normal file
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CrateSystem.cpp /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood Feb 2002
|
||||
// Desc: System responsible for Crates as code objects - ini, new/delete etc
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
|
||||
|
||||
#define DEFINE_VETERANCY_NAMES // for TheVeterancyNames[]
|
||||
|
||||
#include "GameLogic/CrateSystem.h"
|
||||
#include "Common/BitFlagsIO.h"
|
||||
|
||||
CrateSystem *TheCrateSystem = NULL;
|
||||
|
||||
CrateSystem::CrateSystem()
|
||||
{
|
||||
m_crateTemplateVector.clear();
|
||||
}
|
||||
|
||||
CrateSystem::~CrateSystem()
|
||||
{
|
||||
Int count = m_crateTemplateVector.size();
|
||||
for( Int templateIndex = 0; templateIndex < count; templateIndex ++ )
|
||||
{
|
||||
CrateTemplate *currentTemplate = m_crateTemplateVector[templateIndex];
|
||||
if( currentTemplate )
|
||||
{
|
||||
currentTemplate->deleteInstance();
|
||||
}
|
||||
}
|
||||
m_crateTemplateVector.clear();
|
||||
}
|
||||
|
||||
void CrateSystem::init( void )
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void CrateSystem::reset( void )
|
||||
{
|
||||
// clean up overrides
|
||||
std::vector<CrateTemplate *>::iterator it;
|
||||
for( it = m_crateTemplateVector.begin(); it != m_crateTemplateVector.end(); )
|
||||
{
|
||||
CrateTemplate *currentTemplate = *it;
|
||||
if( currentTemplate )
|
||||
{
|
||||
Overridable *tempCrateTemplate = currentTemplate->deleteOverrides();
|
||||
if (!tempCrateTemplate)
|
||||
{
|
||||
// base dude was an override - kill it from the vector
|
||||
it = m_crateTemplateVector.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
it = m_crateTemplateVector.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CrateSystem::parseCrateTemplateDefinition(INI* ini)
|
||||
{
|
||||
AsciiString name;
|
||||
|
||||
// read the crateTemplate name
|
||||
const char* c = ini->getNextToken();
|
||||
name.set(c);
|
||||
|
||||
CrateTemplate *crateTemplate = TheCrateSystem->friend_findCrateTemplate(name);
|
||||
if (crateTemplate == NULL) {
|
||||
crateTemplate = TheCrateSystem->newCrateTemplate(name);
|
||||
|
||||
if (ini->getLoadType() == INI_LOAD_CREATE_OVERRIDES) {
|
||||
crateTemplate->markAsOverride();
|
||||
}
|
||||
} else if( ini->getLoadType() != INI_LOAD_CREATE_OVERRIDES ) {
|
||||
DEBUG_CRASH(( "[LINE: %d in '%s'] Duplicate crate %s found!", ini->getLineNum(), ini->getFilename().str(), name.str() ));
|
||||
} else {
|
||||
crateTemplate = TheCrateSystem->newCrateTemplateOverride(crateTemplate);
|
||||
}
|
||||
|
||||
// parse the ini weapon definition
|
||||
ini->initFromINI(crateTemplate, crateTemplate->getFieldParse());
|
||||
}
|
||||
|
||||
CrateTemplate *CrateSystem::newCrateTemplate( AsciiString name )
|
||||
{
|
||||
// sanity
|
||||
if(name.isEmpty())
|
||||
return NULL;
|
||||
|
||||
// allocate a new weapon
|
||||
CrateTemplate *ct = newInstance(CrateTemplate);
|
||||
|
||||
// if the default template is present, get it and copy over any data to the new template
|
||||
const CrateTemplate *defaultCT = findCrateTemplate(AsciiString("DefaultCrate"));
|
||||
if(defaultCT)
|
||||
{
|
||||
*ct = *defaultCT;
|
||||
}
|
||||
|
||||
ct->setName( name );
|
||||
m_crateTemplateVector.push_back(ct);
|
||||
|
||||
return ct;
|
||||
}
|
||||
|
||||
CrateTemplate *CrateSystem::newCrateTemplateOverride( CrateTemplate *crateToOverride )
|
||||
{
|
||||
if (!crateToOverride) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CrateTemplate *newOverride = newInstance(CrateTemplate);
|
||||
*newOverride = *crateToOverride;
|
||||
|
||||
newOverride->markAsOverride();
|
||||
|
||||
crateToOverride->setNextOverride(newOverride);
|
||||
return newOverride;
|
||||
}
|
||||
|
||||
const CrateTemplate *CrateSystem::findCrateTemplate(AsciiString name) const
|
||||
{
|
||||
// search weapon list for name
|
||||
for (Int i = 0; i < m_crateTemplateVector.size(); i++)
|
||||
if(m_crateTemplateVector[i]->getName() == name) {
|
||||
CrateTemplateOverride overridable(m_crateTemplateVector[i]);
|
||||
return overridable;
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CrateTemplate *CrateSystem::friend_findCrateTemplate(AsciiString name)
|
||||
{
|
||||
// search weapon list for name
|
||||
for (Int i = 0; i < m_crateTemplateVector.size(); i++)
|
||||
if(m_crateTemplateVector[i]->getName() == name) {
|
||||
CrateTemplateOverride overridable(m_crateTemplateVector[i]);
|
||||
return const_cast<CrateTemplate*>((const CrateTemplate *)overridable);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------
|
||||
const FieldParse CrateTemplate::TheCrateTemplateFieldParseTable[] =
|
||||
{
|
||||
{ "CreationChance", INI::parseReal, NULL, offsetof( CrateTemplate, m_creationChance ) },
|
||||
{ "VeterancyLevel", INI::parseIndexList, TheVeterancyNames, offsetof( CrateTemplate, m_veterancyLevel ) },
|
||||
{ "KilledByType", KindOfMaskType::parseFromINI, NULL, offsetof( CrateTemplate, m_killedByTypeKindof) },
|
||||
{ "CrateObject", CrateTemplate::parseCrateCreationEntry, NULL, NULL },
|
||||
{ "KillerScience", INI::parseScience, NULL, offsetof( CrateTemplate, m_killerScience) },
|
||||
{ "OwnedByMaker", INI::parseBool, NULL, offsetof( CrateTemplate, m_isOwnedByMaker) },
|
||||
{ NULL, NULL, NULL, NULL }, // keep this last!
|
||||
};
|
||||
|
||||
CrateTemplate::CrateTemplate()
|
||||
{
|
||||
m_name = "";
|
||||
|
||||
m_creationChance = 0;
|
||||
CLEAR_KINDOFMASK(m_killedByTypeKindof);
|
||||
m_veterancyLevel = LEVEL_INVALID;
|
||||
m_killerScience = SCIENCE_INVALID;
|
||||
m_possibleCrates.clear();
|
||||
m_isOwnedByMaker = FALSE;
|
||||
}
|
||||
|
||||
CrateTemplate::~CrateTemplate()
|
||||
{
|
||||
m_possibleCrates.clear();
|
||||
}
|
||||
|
||||
void CrateTemplate::parseCrateCreationEntry( INI* ini, void *instance, void *, const void* )
|
||||
{
|
||||
CrateTemplate *self = (CrateTemplate *)instance;
|
||||
|
||||
const char *token = ini->getNextToken();
|
||||
AsciiString crateName = token;
|
||||
|
||||
token = ini->getNextToken();
|
||||
Real crateValue;
|
||||
if (sscanf( token, "%f", &crateValue ) != 1)
|
||||
throw INI_INVALID_DATA;
|
||||
|
||||
crateCreationEntry newEntry;
|
||||
newEntry.crateName = crateName;
|
||||
newEntry.crateChance = crateValue;
|
||||
|
||||
self->m_possibleCrates.push_back( newEntry );
|
||||
}
|
||||
|
113
Generals/Code/GameEngine/Source/GameLogic/System/Damage.cpp
Normal file
113
Generals/Code/GameEngine/Source/GameLogic/System/Damage.cpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: Damage.cpp ///////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, September 2002
|
||||
// Desc: Basic structures for the damage process
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "PreRTS.h"
|
||||
#include "Common/Xfer.h"
|
||||
#include "GameLogic/Damage.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/** Xfer method
|
||||
* Version Info:
|
||||
* 1: Initial version */
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void DamageInfo::xfer( Xfer *xfer )
|
||||
{
|
||||
|
||||
// version
|
||||
XferVersion currentVersion = 1;
|
||||
XferVersion version = currentVersion;
|
||||
xfer->xferVersion( &version, currentVersion );
|
||||
|
||||
// xfer input
|
||||
xfer->xferSnapshot( &in );
|
||||
|
||||
// xfer output
|
||||
xfer->xferSnapshot( &out );
|
||||
|
||||
} // end xfer
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/** Xfer method
|
||||
* Version Info:
|
||||
* 1: Initial version */
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void DamageInfoInput::xfer( Xfer *xfer )
|
||||
{
|
||||
|
||||
// version
|
||||
XferVersion currentVersion = 1;
|
||||
XferVersion version = currentVersion;
|
||||
xfer->xferVersion( &version, currentVersion );
|
||||
|
||||
// source id
|
||||
xfer->xferObjectID( &m_sourceID );
|
||||
|
||||
// source player mask
|
||||
xfer->xferUser( &m_sourcePlayerMask, sizeof( PlayerMaskType ) );
|
||||
|
||||
// damage type
|
||||
xfer->xferUser( &m_damageType, sizeof( DamageType ) );
|
||||
|
||||
// death type
|
||||
xfer->xferUser( &m_deathType, sizeof( DeathType ) );
|
||||
|
||||
// amount
|
||||
xfer->xferReal( &m_amount );
|
||||
|
||||
} // end xfer
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/** Xfer method
|
||||
* Version Info:
|
||||
* 1: Initial version */
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void DamageInfoOutput::xfer( Xfer *xfer )
|
||||
{
|
||||
|
||||
// version
|
||||
XferVersion currentVersion = 1;
|
||||
XferVersion version = currentVersion;
|
||||
xfer->xferVersion( &version, currentVersion );
|
||||
|
||||
// actual damage
|
||||
xfer->xferReal( &m_actualDamageDealt );
|
||||
|
||||
// damage clipped
|
||||
xfer->xferReal( &m_actualDamageClipped );
|
||||
|
||||
// no effect
|
||||
xfer->xferBool( &m_noEffect );
|
||||
|
||||
} // end xfer
|
||||
|
4529
Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp
Normal file
4529
Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
161
Generals/Code/GameEngine/Source/GameLogic/System/RankInfo.cpp
Normal file
161
Generals/Code/GameEngine/Source/GameLogic/System/RankInfo.cpp
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: RankInfo.cpp /////////////////////////////////////////////////////////
|
||||
// Created: Steven Johnson, Sep 2002
|
||||
// Desc:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
|
||||
|
||||
#include "Common/INI.h"
|
||||
#include "Common/Player.h"
|
||||
#include "GameLogic/RankInfo.h"
|
||||
|
||||
RankInfoStore* TheRankInfoStore = NULL;
|
||||
|
||||
#ifdef _INTERNAL
|
||||
// for occasional debugging...
|
||||
//#pragma optimize("", off)
|
||||
//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RankInfoStore::init()
|
||||
{
|
||||
DEBUG_ASSERTCRASH(m_rankInfos.empty(), ("Hmm"));
|
||||
m_rankInfos.clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RankInfoStore::reset()
|
||||
{
|
||||
// nope.
|
||||
//m_rankInfos.clear();
|
||||
|
||||
for (RankInfoVec::iterator it = m_rankInfos.begin(); it != m_rankInfos.end(); /*++it*/)
|
||||
{
|
||||
RankInfo* ri = *it;
|
||||
if (ri)
|
||||
{
|
||||
Overridable* temp = ri->deleteOverrides();
|
||||
if (!temp)
|
||||
{
|
||||
DEBUG_CRASH(("hmm, should not be possible for RankInfo"));
|
||||
it = m_rankInfos.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
Int RankInfoStore::getRankLevelCount() const
|
||||
{
|
||||
return m_rankInfos.size();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// note that level is 1...n, NOT 0...n-1
|
||||
const RankInfo* RankInfoStore::getRankInfo(Int level) const
|
||||
{
|
||||
if (level >= 1 && level <= getRankLevelCount())
|
||||
{
|
||||
const RankInfo* ri = m_rankInfos[level-1];
|
||||
if (ri)
|
||||
{
|
||||
return (const RankInfo*)ri->getFinalOverride();
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RankInfoStore::friend_parseRankDefinition( INI* ini )
|
||||
{
|
||||
if (TheRankInfoStore)
|
||||
{
|
||||
Int rank = INI::scanInt(ini->getNextToken());
|
||||
|
||||
static const FieldParse myFieldParse[] =
|
||||
{
|
||||
{ "RankName", INI::parseAndTranslateLabel, NULL, offsetof( RankInfo, m_rankName ) },
|
||||
{ "SkillPointsNeeded", INI::parseInt, NULL, offsetof( RankInfo, m_skillPointsNeeded ) },
|
||||
{ "SciencesGranted", INI::parseScienceVector, NULL, offsetof( RankInfo, m_sciencesGranted ) },
|
||||
{ "SciencePurchasePointsGranted", INI::parseUnsignedInt, NULL, offsetof( RankInfo, m_sciencePurchasePointsGranted ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
if (ini->getLoadType() == INI_LOAD_CREATE_OVERRIDES)
|
||||
{
|
||||
// we aren't allowed to add ranks in overrides, only to override existing ones.
|
||||
if (rank < 1 || rank > TheRankInfoStore->m_rankInfos.size())
|
||||
{
|
||||
DEBUG_CRASH(("Rank not found in map.ini"));
|
||||
throw INI_INVALID_DATA;
|
||||
}
|
||||
|
||||
RankInfo* info = TheRankInfoStore->m_rankInfos[rank-1];
|
||||
if (!info)
|
||||
{
|
||||
DEBUG_CRASH(("Rank not found in map.ini"));
|
||||
throw INI_INVALID_DATA;
|
||||
}
|
||||
|
||||
RankInfo* newInfo = newInstance(RankInfo);
|
||||
|
||||
// copy data from final override to 'newInfo' as a set of initial default values
|
||||
info = (RankInfo*)(info->friend_getFinalOverride());
|
||||
|
||||
*newInfo = *info;
|
||||
info->setNextOverride(newInfo);
|
||||
newInfo->markAsOverride(); // must do AFTER the copy
|
||||
|
||||
ini->initFromINI(newInfo, myFieldParse);
|
||||
//TheRankInfoStore->m_rankInfos.push_back(newInfo); // NO, BAD, WRONG -- don't add in this case.
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rank != TheRankInfoStore->m_rankInfos.size() + 1)
|
||||
{
|
||||
DEBUG_CRASH(("Ranks must increase monotonically"));
|
||||
throw INI_INVALID_DATA;
|
||||
}
|
||||
RankInfo* info = newInstance(RankInfo);
|
||||
ini->initFromINI(info, myFieldParse);
|
||||
TheRankInfoStore->m_rankInfos.push_back(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void INI::parseRankDefinition( INI* ini )
|
||||
{
|
||||
RankInfoStore::friend_parseRankDefinition(ini);
|
||||
}
|
||||
|
Reference in a new issue