Skip to content

Commit 104c309

Browse files
authored
Implement Extend for Weapon and Locomotor (#64)
Fix for worldbuilder crash
1 parent 5640360 commit 104c309

File tree

8 files changed

+144
-4
lines changed

8 files changed

+144
-4
lines changed

GeneralsMD/Code/GameEngine/Include/Common/INI.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,12 @@ class INI
191191
static void parseObjectReskinDefinition( INI *ini );
192192
static void parseObjectExtendDefinition( INI* ini );
193193
static void parseWeaponTemplateDefinition( INI *ini );
194+
static void parseWeaponExtendTemplateDefinition(INI* ini);
194195
static void parseScienceDefinition( INI *ini );
195196
static void parseRankDefinition( INI *ini );
196197
static void parseCrateTemplateDefinition( INI *ini );
197198
static void parseLocomotorTemplateDefinition( INI *ini );
199+
static void parseLocomotorExtendTemplateDefinition( INI *ini );
198200
static void parseLanguageDefinition( INI *ini );
199201
static void parsePlayerTemplateDefinition( INI *ini );
200202
static void parseGameDataDefinition( INI *ini );

GeneralsMD/Code/GameEngine/Include/GameLogic/Locomotor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,7 @@ class LocomotorStore : public SubsystemInterface
510510

511511

512512
static void parseLocomotorTemplateDefinition(INI* ini);
513+
static void parseLocomotorExtendTemplateDefinition(INI* ini);
513514

514515
protected:
515516

GeneralsMD/Code/GameEngine/Include/GameLogic/Weapon.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,8 @@ class WeaponTemplate : public MemoryPoolObject
417417
/// field table for loading the values from an INI
418418
const FieldParse* getFieldParse() const { return TheWeaponTemplateFieldParseTable; }
419419

420+
void copy_from(const WeaponTemplate& other);
421+
420422
/**
421423
fire the weapon. return the logic-frame in which the damage will be dealt.
422424
@@ -973,6 +975,7 @@ class WeaponStore : public SubsystemInterface
973975
void handleProjectileDetonation( const WeaponTemplate* w, const Object *source, const Coord3D* pos, WeaponBonusConditionFlags extraBonusFlags, Bool inflictDamage = TRUE );
974976

975977
static void parseWeaponTemplateDefinition(INI* ini);
978+
static void parseWeaponExtendTemplateDefinition(INI* ini);
976979

977980
protected:
978981

GeneralsMD/Code/GameEngine/Source/Common/INI/INI.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ static const BlockParse theTypeTable[] =
107107
{ "GameData", INI::parseGameDataDefinition },
108108
{ "InGameUI", INI::parseInGameUIDefinition },
109109
{ "Locomotor", INI::parseLocomotorTemplateDefinition },
110+
{ "LocomotorExtend", INI::parseLocomotorExtendTemplateDefinition },
110111
{ "Language", INI::parseLanguageDefinition },
111112
{ "MapCache", INI::parseMapCacheDefinition },
112113
{ "MapData", INI::parseMapDataDefinition },
@@ -134,9 +135,10 @@ static const BlockParse theTypeTable[] =
134135
{ "Upgrade", INI::parseUpgradeDefinition },
135136
{ "Video", INI::parseVideoDefinition },
136137
{ "WaterSet", INI::parseWaterSettingDefinition },
137-
{ "WaterTransparency", INI::parseWaterTransparencyDefinition},
138-
{ "Weather", INI::parseWeatherDefinition},
138+
{ "WaterTransparency", INI::parseWaterTransparencyDefinition },
139+
{ "Weather", INI::parseWeatherDefinition },
139140
{ "Weapon", INI::parseWeaponTemplateDefinition },
141+
{ "WeaponExtend", INI::parseWeaponExtendTemplateDefinition },
140142
{ "WebpageURL", INI::parseWebpageURLDefinition },
141143
{ "HeaderTemplate", INI::parseHeaderTemplateDefinition },
142144
{ "StaticGameLOD", INI::parseStaticGameLODDefinition },

GeneralsMD/Code/GameEngine/Source/Common/INI/INIWeapon.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,9 @@ void INI::parseWeaponTemplateDefinition( INI* ini )
4545
WeaponStore::parseWeaponTemplateDefinition(ini);
4646
}
4747

48+
void INI::parseWeaponExtendTemplateDefinition(INI* ini)
49+
{
50+
WeaponStore::parseWeaponExtendTemplateDefinition(ini);
51+
}
52+
4853

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Locomotor.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,12 +641,62 @@ LocomotorTemplate *LocomotorStore::newOverride( LocomotorTemplate *locoTemplate
641641
TheLocomotorStore->m_locomotorTemplates[namekey] = loco;
642642
}
643643

644+
void LocomotorStore::parseLocomotorExtendTemplateDefinition(INI* ini)
645+
{
646+
if (!TheLocomotorStore)
647+
throw INI_INVALID_DATA;
648+
649+
Bool isOverride = false;
650+
// read the Locomotor name
651+
const char* token = ini->getNextToken();
652+
NameKeyType namekey = NAMEKEY(token);
653+
654+
const char* token2 = ini->getNextToken();
655+
NameKeyType parentKey = NAMEKEY(token2);
656+
657+
LocomotorTemplate* locoParent = TheLocomotorStore->findLocomotorTemplate(parentKey);
658+
if (locoParent) {
659+
660+
LocomotorTemplate* loco = TheLocomotorStore->findLocomotorTemplate(namekey);
661+
if (loco) {
662+
if (ini->getLoadType() == INI_LOAD_CREATE_OVERRIDES) {
663+
loco = TheLocomotorStore->newOverride((LocomotorTemplate*)loco->friend_getFinalOverride());
664+
}
665+
isOverride = true;
666+
}
667+
else {
668+
loco = newInstance(LocomotorTemplate);
669+
if (ini->getLoadType() == INI_LOAD_CREATE_OVERRIDES) {
670+
loco->markAsOverride();
671+
}
672+
}
673+
// copy all parent values
674+
*loco = *locoParent;
675+
loco->friend_setName(token);
676+
ini->initFromINI(loco, loco->getFieldParse());
677+
loco->validate();
678+
679+
// if this is an override, then we want the pointer on the existing named locomotor to point us
680+
// to the override, so don't add it to the map.
681+
if (!isOverride)
682+
TheLocomotorStore->m_locomotorTemplates[namekey] = loco;
683+
}
684+
else {
685+
DEBUG_CRASH(("LocomotorExtend '%s': parent '%s' does not exist", token, token2));
686+
}
687+
}
688+
644689
//-------------------------------------------------------------------------------------------------
645690
/*static*/ void INI::parseLocomotorTemplateDefinition( INI* ini )
646691
{
647692
LocomotorStore::parseLocomotorTemplateDefinition(ini);
648693
}
649694

695+
/*static*/ void INI::parseLocomotorExtendTemplateDefinition(INI* ini)
696+
{
697+
LocomotorStore::parseLocomotorExtendTemplateDefinition(ini);
698+
}
699+
650700
//-------------------------------------------------------------------------------------------------
651701
//-------------------------------------------------------------------------------------------------
652702
//-------------------------------------------------------------------------------------------------

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,20 @@ void WeaponTemplate::reset( void )
365365
m_historicDamage.clear();
366366
}
367367

368+
void WeaponTemplate::copy_from(const WeaponTemplate& other) {
369+
//Backup nextTemplate, name and namekey
370+
WeaponTemplate* nextTempl = this->m_nextTemplate;
371+
AsciiString name = this->m_name;
372+
NameKeyType nameKey = this->m_nameKey;
373+
374+
// take all values from other
375+
*this = other;
376+
377+
this->m_nextTemplate = nextTempl;
378+
this->m_name = name;
379+
this->m_nameKey = nameKey;
380+
}
381+
368382
//-------------------------------------------------------------------------------------------------
369383
/*static*/ void WeaponTemplate::parseWeaponBonusSet( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ )
370384
{
@@ -1936,6 +1950,69 @@ void WeaponStore::postProcessLoad()
19361950

19371951
}
19381952

1953+
1954+
//-------------------------------------------------------------------------------------------------
1955+
/*static*/ void WeaponStore::parseWeaponExtendTemplateDefinition(INI* ini)
1956+
{
1957+
AsciiString name;
1958+
AsciiString parent;
1959+
1960+
// read the weapon name
1961+
const char* c = ini->getNextToken();
1962+
name.set(c);
1963+
1964+
// read the parent name
1965+
const char* c2 = ini->getNextToken();
1966+
parent.set(c2);
1967+
1968+
// find parent if present
1969+
WeaponTemplate* parentWeapon = TheWeaponStore->findWeaponTemplatePrivate(TheNameKeyGenerator->nameToKey(parent));
1970+
if (parentWeapon)
1971+
{
1972+
1973+
// find existing item if present
1974+
WeaponTemplate* weapon = TheWeaponStore->findWeaponTemplatePrivate(TheNameKeyGenerator->nameToKey(name));
1975+
if (weapon)
1976+
{
1977+
if (ini->getLoadType() == INI_LOAD_CREATE_OVERRIDES)
1978+
weapon = TheWeaponStore->newOverride(weapon);
1979+
else
1980+
{
1981+
DEBUG_CRASH(("Weapon '%s' already exists, but OVERRIDE not specified", c));
1982+
return;
1983+
}
1984+
1985+
}
1986+
else
1987+
{
1988+
// no item is present, create a new one
1989+
weapon = TheWeaponStore->newWeaponTemplate(name);
1990+
}
1991+
1992+
//copy from parent
1993+
weapon->copy_from(*parentWeapon);
1994+
1995+
// parse the ini weapon definition
1996+
ini->initFromINI(weapon, weapon->getFieldParse());
1997+
1998+
if (weapon->m_projectileName.isNone())
1999+
weapon->m_projectileName.clear();
2000+
2001+
#if defined(RTS_DEBUG)
2002+
if (!weapon->getFireSound().getEventName().isEmpty() && weapon->getFireSound().getEventName().compareNoCase("NoSound") != 0)
2003+
{
2004+
DEBUG_ASSERTCRASH(TheAudio->isValidAudioEvent(&weapon->getFireSound()), ("Invalid FireSound %s in Weapon '%s'.", weapon->getFireSound().getEventName().str(), weapon->getName().str()));
2005+
}
2006+
#endif
2007+
2008+
}
2009+
else
2010+
{
2011+
DEBUG_CRASH(("Weapon '%s' cannot extend parrent '%s' as it not exists", c, c2));
2012+
}
2013+
2014+
}
2015+
19392016
//-------------------------------------------------------------------------------------------------
19402017
//-------------------------------------------------------------------------------------------------
19412018
//-------------------------------------------------------------------------------------------------

GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,7 +1040,7 @@ void W3DProjectedShadowManager::queueDecal(W3DProjectedShadow *shadow)
10401040
hmapVertex.X=(float)(i-borderSize)*MAP_XY_FACTOR;
10411041
hmapVertex.Z=__max((float)hmap->getHeight(i,j)*MAP_HEIGHT_SCALE,layerHeight);
10421042

1043-
if (TheGlobalData->m_heightAboveTerrainIncludesWater) {
1043+
if (TheGlobalData->m_heightAboveTerrainIncludesWater && TheTerrainLogic != nullptr) {
10441044
if (Real waterZ = 0; TheTerrainLogic->isUnderwater(hmapVertex.X, hmapVertex.Y, &waterZ)) {
10451045
if (waterZ > hmapVertex.Z) hmapVertex.Z = waterZ;
10461046
}
@@ -1066,7 +1066,7 @@ void W3DProjectedShadowManager::queueDecal(W3DProjectedShadow *shadow)
10661066
hmapVertex.X=(float)(i-borderSize)*MAP_XY_FACTOR;
10671067
hmapVertex.Z=(float)hmap->getHeight(i,j)*MAP_HEIGHT_SCALE+0.01f * MAP_XY_FACTOR;
10681068

1069-
if (TheGlobalData->m_heightAboveTerrainIncludesWater) {
1069+
if (TheGlobalData->m_heightAboveTerrainIncludesWater && TheTerrainLogic != nullptr) {
10701070
if (Real waterZ = 0; TheTerrainLogic->isUnderwater(hmapVertex.X, hmapVertex.Y, &waterZ)) {
10711071
if (waterZ > hmapVertex.Z) hmapVertex.Z = waterZ;
10721072
}

0 commit comments

Comments
 (0)