Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@ void WeaponSet::xfer( Xfer *xfer )
if (tt == nullptr)
throw INI_INVALID_DATA;

// TheSuperHackers @fix bobtista 27/01/2026 findTemplate returns the base template, but Object
// uses getFinalOverride() in its constructor. We must do the same here so m_curWeaponTemplateSet
// points to the same ThingTemplate's weapon sets, avoiding unnecessary reallocation in updateWeaponSet.
tt = static_cast<const ThingTemplate*>(tt->getFinalOverride());

m_curWeaponTemplateSet = tt->findWeaponTemplateSet(wsFlags);
if (m_curWeaponTemplateSet == nullptr)
throw INI_INVALID_DATA;
Expand Down
3 changes: 3 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/Common/ThingFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ class ThingFactory : public SubsystemInterface
get a template given template database name. return null if not found.
note, this is now substantially faster (does a hash-table lookup)
*/
// TheSuperHackers @info bobtista 12/08/2026 Keep returning the base template from the hash map.
// Some callers cache this pointer across matches, while reset() deletes map overrides. Code that
// needs the current override must call getFinalOverride() without caching the result.
const ThingTemplate *findTemplate( const AsciiString& name, Bool check = TRUE ) { return findTemplateInternal( name, check ); }

/**
Expand Down
2 changes: 2 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/Common/Thing/Thing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ Thing::~Thing()
//=============================================================================
const ThingTemplate *Thing::getTemplate() const
{
// TheSuperHackers @info bobtista 12/08/2026 Resolve the current override here.
// m_template holds the original template pointer and OVERRIDE follows the override chain each time.
return m_template;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ void WeaponSet::xfer( Xfer *xfer )
if (tt == nullptr)
throw INI_INVALID_DATA;

// TheSuperHackers @fix bobtista 27/01/2026 Resolve the final override before restoring
// the weapon set. Object::getTemplate() returns the final override, otherwise the next
// updateWeaponSet() sees a different WeaponTemplateSet pointer and recreates the weapons,
// replacing the ammo and reload timing just loaded.
tt = static_cast<const ThingTemplate*>(tt->getFinalOverride());

m_curWeaponTemplateSet = tt->findWeaponTemplateSet(wsFlags);
if (m_curWeaponTemplateSet == nullptr)
throw INI_INVALID_DATA;
Expand Down Expand Up @@ -294,6 +300,8 @@ void WeaponSet::loadPostProcess( void )
//-------------------------------------------------------------------------------------------------
void WeaponSet::updateWeaponSet(const Object* obj)
{
// TheSuperHackers @info bobtista 12/08/2026 Compare the set pointers to detect a weapon set change.
// m_curWeaponTemplateSet must belong to obj->getTemplate(), including its final override.
const WeaponTemplateSet* set = obj->getTemplate()->findWeaponTemplateSet(obj->getWeaponSetFlags());
DEBUG_ASSERTCRASH(set, ("findWeaponSet should never return null"));
if (set && set != m_curWeaponTemplateSet)
Expand Down
Loading