Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
d53b29c
bugfix(w3d): Skip rivers that overflow the dynamic index buffer (#3489)
tintinhamans Oct 13, 2026
cfa0c8c
fix(worldheightmap): Free the legacy cliff state buffer when loading …
tintinhamans Oct 13, 2026
ba0eb5d
bugfix(worldheightmap): Reject map sizes that overflow the cell array…
tintinhamans Oct 15, 2026
85280dc
fix(lanapi): Fix GameInfo memory leaks in LANAPI::OnGameStart(), LANA…
tintinhamans Oct 10, 2026
f424006
bugfix(network): Close sockets that fail to bind (#3488)
tintinhamans Oct 12, 2026
12d0f88
fix(network): Release the disconnect chat message after sending it (#…
tintinhamans Oct 15, 2026
1ce1722
fix(lanapi): Delete the lobby player when they leave the lobby (#3499)
tintinhamans Oct 15, 2026
bde9e9c
fix(addoncompat): Close fullviewport.dat file handle after reading it…
tintinhamans Oct 11, 2026
0f6f0e4
fix: Close leaked system handles in GameWindowManager, ImageCollectio…
tintinhamans Oct 13, 2026
7833a75
fix(maputil): Close the file and free the buffer when a map preview c…
tintinhamans Oct 15, 2026
35a0070
perf(displaystring): Rebuild static text only when its hotkey setting…
tintinhamans Oct 9, 2026
ba92aba
bugfix(w3d): Fix leaked surface copy in screenshot and movie capture …
tintinhamans Oct 12, 2026
5bf92eb
bugfix(gamewindow): Remove destroyed windows from the modal stack and…
tintinhamans Sep 9, 2026
f1ae9e2
perf(script): Reduce cost of ScriptEngine::findScript() by around 85%…
Mauller Aug 14, 2026
97a2f3b
bugfix(pathfinder): Prevent a retail crash where the head of the clos…
Mauller Aug 3, 2026
fcc79fb
bugfix(pathfinder): Prevent a retail crash where a pathfindCell has a…
Mauller Aug 3, 2026
c4952d4
bugfix: Prevent the game from freezing during scripted camera movemen…
tintinhamans Oct 25, 2026
dd163b9
refactor(particlesys): Cleanup retail smudge particle type identifica…
Mauller Aug 18, 2026
2e824b7
unify(particlesys): Move W3DParticleSys.h to Core (#3172)
stephanmeesters Aug 19, 2026
51cdf13
tweak(particlesys): Cleanup volume particle depth handling and add IN…
Mauller Aug 26, 2026
b1be9fa
perf(particlesys): Batch same type particles to reduce cost of partic…
Mauller Sep 6, 2026
800e6a6
bugfix(particlesys): Render lone streak type particles as regular par…
Mauller Sep 20, 2026
e11536c
bugfix(texturefilter): Fix blocky shroud edges from misconfigured tex…
mirelle7 Oct 20, 2026
a4541c8
fix(htree): Reject invalid W3D hierarchy pivot counts (#3195)
CryoTheRenegade Sep 1, 2026
0417095
fix(controlbar): Prevent null dereference in ControlBar::showRallyPoi…
CryoTheRenegade Sep 17, 2026
3e5fa46
fix(controlbar): Prevent null dereference in ControlBar::updateSpecia…
CryoTheRenegade Sep 22, 2026
17dec29
fix(pointgroup): Prevent null dereference in PointGroupClass::RenderV…
CryoTheRenegade Sep 17, 2026
39c06b0
fix(terrainvisual): Prevent null dereference in W3DTerrainVisual::loa…
CryoTheRenegade Sep 17, 2026
afe0961
fix(modeldraw): Prevent null dereference in W3DModelDraw::handleClien…
CryoTheRenegade Sep 19, 2026
8e1a8f8
fix(gamewindowtransitions): Prevent null dereference in GameWindowTra…
CryoTheRenegade Sep 22, 2026
d5c69b6
fix(ini): Prevent using unitialized stack variable in INI::parseBitSt…
CryoTheRenegade Sep 17, 2026
ae2ad15
fix(milesaudiomanager): Prevent heap-buffer-overflow read in MilesAud…
CryoTheRenegade Sep 15, 2026
6bdd838
fix(firewallhelper): Prevent stack-buffer-overflow write in FirewallH…
CryoTheRenegade Sep 26, 2026
f9bb5ae
fix(ww3d2): Copy string setter inputs before freeing potentially alia…
CryoTheRenegade Sep 20, 2026
1b977f7
fix(audio): Copy SoundSceneObjClass state safely (#3247)
CryoTheRenegade Sep 15, 2026
391029e
fix(gameinfo): Clear GameSlot IP on reset (#3311)
CryoTheRenegade Sep 18, 2026
eef9e3d
bugfix(debug): Skip system-modal crash dialogs in headless runs (#3030)
bobtista Jul 31, 2026
027d4aa
fix(w3ddisplay): Fix cinematic text display string leak (#3517)
tintinhamans Oct 18, 2026
19761e0
fix(ingameui): Properly delete ControlBar and ReplayControl game wind…
xezon Oct 10, 2026
fa57b67
bugfix(pathfinder): Prevent crash in Pathfinder::processHierarchical…
Caball009 Sep 16, 2026
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
4 changes: 4 additions & 0 deletions Core/GameEngine/Include/Common/GameDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@
#define PRESERVE_RETAIL_SCRIPTED_CAMERA (1) // Retain scripted camera behavior present in retail Generals 1.08 and Zero Hour 1.04
#endif

#ifndef PRESERVE_RETAIL_PARTICLES
#define PRESERVE_RETAIL_PARTICLES (1) // Preserve original look of particles present in retail Generals 1.08 and Zero Hour 1.04
#endif

#ifndef RETAIL_COMPATIBLE_CRC
#if defined(GENERALS_ONLINE)
#define RETAIL_COMPATIBLE_CRC (0)
Expand Down
28 changes: 17 additions & 11 deletions Core/GameEngine/Include/GameClient/ParticleSys.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@ enum ParticleSystemID CPP_11(: Int)
INVALID_PARTICLE_SYSTEM_ID = 0
};

#define MAX_VOLUME_PARTICLE_DEPTH ( 16 )
#define DEFAULT_VOLUME_PARTICLE_DEPTH ( 0 )//The Default is not to do the volume thing!
#define OPTIMUM_VOLUME_PARTICLE_DEPTH ( 6 )
constexpr const UnsignedInt INVALID_VOLUME_PARTICLE_DEPTH = 0; //The volume depth is not initialized
constexpr const UnsignedInt DEFAULT_VOLUME_PARTICLE_DEPTH = 1; //The Default is not to do the volume thing!
constexpr const UnsignedInt MIN_VOLUME_PARTICLE_DEPTH = 2;
constexpr const UnsignedInt OPTIMUM_VOLUME_PARTICLE_DEPTH = 6;
constexpr const UnsignedInt MAX_VOLUME_PARTICLE_DEPTH = 16;

// TheSuperHackers @info The X and Y angles are not necessary for particles because there are only 2 placement modes:
// Billboard (always facing camera) and Ground Aligned, which overwrite any rotations on the X and Y axis by design.
Expand Down Expand Up @@ -511,7 +513,9 @@ class ParticleSystemTemplate : public MemoryPoolObject, protected ParticleSystem
public:
ParticleSystemTemplate( const AsciiString &name );

AsciiString getName() const { return m_name; }
void validate();

const AsciiString& getName() const { return m_name; }

// This function was made const because of update modules' module data being all const.
ParticleSystem *createSlaveSystem( Bool createSlaves = TRUE ) const ; ///< if returns non-null, it is a slave system for use
Expand Down Expand Up @@ -602,15 +606,17 @@ class ParticleSystem : public MemoryPoolObject,

void setInitialDelay( UnsignedInt delay ) { m_delayLeft = delay; }

AsciiString getParticleTypeName() { return m_particleTypeName; } ///< return the name of the particles
Bool isUsingDrawables() { return (m_particleType == DRAWABLE) ? true : false; }
Bool isUsingStreak() { return (m_particleType == STREAK) ? true : false; }
Bool isUsingSmudge() { return (m_particleType == SMUDGE) ? true : false; }
UnsignedInt getVolumeParticleDepth() { return ( m_particleType == VOLUME_PARTICLE ) ? OPTIMUM_VOLUME_PARTICLE_DEPTH : 0; }
const AsciiString& getParticleTypeName() const { return m_particleTypeName; } ///< return the name of the particles
Bool isUsingParticles() const { return m_particleType == PARTICLE; }
Bool isUsingDrawables() const { return m_particleType == DRAWABLE; }
Bool isUsingStreak() const { return m_particleType == STREAK; }
Bool isUsingSmudge() const { return m_particleType == SMUDGE; }
Bool isUsingVolumeParticles() const { return m_particleType == VOLUME_PARTICLE; }
UnsignedInt getVolumeParticleDepth() const { return m_volumeParticleDepth; }

Bool shouldBillboard() { return !m_isGroundAligned; }
Bool shouldBillboard() const { return !m_isGroundAligned; }

ParticleShaderType getShaderType() { return m_shaderType; }
ParticleShaderType getShaderType() const { return m_shaderType; }

void setSlave( ParticleSystem *slave ); ///< set a slave system for us
ParticleSystem *getSlave() { return m_slaveSystem; }
Expand Down
2 changes: 1 addition & 1 deletion Core/GameEngine/Include/GameNetwork/FirewallHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ class FirewallHelperClass {

void flagNeedToRefresh(Bool flag);

static void getManglerName(Int manglerIndex, Char *nameBuf);
static AsciiString getManglerName(Int manglerIndex);
Bool sendToManglerFromPort(UnsignedInt address, UnsignedShort port, UnsignedShort packetID, Bool blitzme = FALSE);
UnsignedShort getManglerResponse(UnsignedShort packetID, Int time = 0);
Bool openSpareSocket(UnsignedShort port);
Expand Down
1 change: 1 addition & 0 deletions Core/GameEngine/Include/GameNetwork/GameInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ class SkirmishGameInfo : public GameInfo, public Snapshot
for (Int i = 0; i< MAX_SLOTS; ++i)
setSlotPointer(i, &m_skirmishSlot[i]);
}
virtual ~SkirmishGameInfo() override {}
};

extern SkirmishGameInfo *TheSkirmishGameInfo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class GameSpyStagingRoom : public GameInfo

public:
GameSpyStagingRoom();
virtual ~GameSpyStagingRoom() override {}
virtual void reset() override;

void cleanUpSlotPointers();
Expand Down
1 change: 1 addition & 0 deletions Core/GameEngine/Include/GameNetwork/LANGameInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class LANGameInfo : public GameInfo

public:
LANGameInfo();
virtual ~LANGameInfo() override {}
void setSlot( Int slotNum, LANGameSlot slotInfo ); ///< Set the slot state (human, open, AI, etc)
LANGameSlot* getLANSlot( Int slotNum ); ///< Get the slot
const LANGameSlot* getConstLANSlot( Int slotNum ) const; ///< Get the slot
Expand Down
1 change: 1 addition & 0 deletions Core/GameEngine/Source/Common/AddonCompat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Bool HasFullviewportDat()
if (File* file = TheFileSystem->openFile("GenTool/fullviewport.dat", File::READ | File::BINARY))
{
file->read(&value, 1);
file->close();
}
return value != '0';
}
Expand Down
2 changes: 1 addition & 1 deletion Core/GameEngine/Source/Common/INI/INI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ void INI::parsePercentToReal( INI* ini, void * /*instance*/, void *store, const
//-------------------------------------------------------------------------------------------------
void INI::parseBitString8( INI* ini, void * /*instance*/, void *store, const void* userData )
{
UnsignedInt tmp;
UnsignedInt tmp = *(Byte*)store;
INI::parseBitString32(ini, nullptr, &tmp, userData);
if (tmp & 0xffffff00)
{
Expand Down
1 change: 1 addition & 0 deletions Core/GameEngine/Source/Common/INI/INIParticleSys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,5 @@ void INI::parseParticleSystemDefinition( INI* ini )

// parse the ini definition
ini->initFromINI( sysTemplate, sysTemplate->getFieldParse() );
sysTemplate->validate();
}
19 changes: 14 additions & 5 deletions Core/GameEngine/Source/Common/System/Debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -811,16 +811,22 @@ void ReleaseCrash(const char *reason)
#if defined(RTS_DEBUG)
/* static */ char buff[8192]; // not so static so we can be threadsafe
snprintf(buff, 8192, "Sorry, a serious error occurred. (%s)", reason);
::MessageBox(nullptr, buff, "Technical Difficulties...", MB_OK|MB_SYSTEMMODAL|MB_ICONERROR);
if (!(TheGlobalData && TheGlobalData->m_headless))
{
::MessageBox(nullptr, buff, "Technical Difficulties...", MB_OK|MB_SYSTEMMODAL|MB_ICONERROR);
}
#else
// crash error messaged changed 3/6/03 BGC
// ::MessageBox(nullptr, "Sorry, a serious error occurred.", "Technical Difficulties...", MB_OK|MB_TASKMODAL|MB_ICONERROR);
// ::MessageBox(nullptr, "You have encountered a serious error. Serious errors can be caused by many things including viruses, overheated hardware and hardware that does not meet the minimum specifications for the game. Please visit the forums at www.generals.ea.com for suggested courses of action or consult your manual for Technical Support contact information.", "Technical Difficulties...", MB_OK|MB_TASKMODAL|MB_ICONERROR);

// crash error message changed again 8/22/03 M Lorenzen... made this message box modal to the system so it will appear on top of any task-modal windows, splash-screen, etc.
::MessageBox(nullptr, "You have encountered a serious error. Serious errors can be caused by many things including viruses, overheated hardware and hardware that does not meet the minimum specifications for the game. Please visit the forums at www.generals.ea.com for suggested courses of action or consult your manual for Technical Support contact information.",
"Technical Difficulties...",
MB_OK|MB_SYSTEMMODAL|MB_ICONERROR);
if (!(TheGlobalData && TheGlobalData->m_headless))
{
::MessageBox(nullptr, "You have encountered a serious error. Serious errors can be caused by many things including viruses, overheated hardware and hardware that does not meet the minimum specifications for the game. Please visit the forums at www.generals.ea.com for suggested courses of action or consult your manual for Technical Support contact information.",
"Technical Difficulties...",
MB_OK|MB_SYSTEMMODAL|MB_ICONERROR);
}


#endif
Expand Down Expand Up @@ -850,7 +856,10 @@ void ReleaseCrashLocalized(const AsciiString& p, const AsciiString& m)
}
}

::MessageBoxW(nullptr, mesg.str(), prompt.str(), MB_OK | MB_SYSTEMMODAL | MB_ICONERROR);
if (!(TheGlobalData && TheGlobalData->m_headless))
{
::MessageBoxW(nullptr, mesg.str(), prompt.str(), MB_OK | MB_SYSTEMMODAL | MB_ICONERROR);
}

char prevbuf[ _MAX_PATH ];
char curbuf[ _MAX_PATH ];
Expand Down
13 changes: 8 additions & 5 deletions Core/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2742,13 +2742,15 @@ void ControlBar::showRallyPoint(const Coord3D* loc)
if (m_rallyPointDrawableID == INVALID_DRAWABLE_ID)
{
const ThingTemplate* ttn = TheThingFactory->findTemplate("RallyPointMarker");
marker = TheThingFactory->newDrawable(ttn);
DEBUG_ASSERTCRASH(marker, ("showRallyPoint: Unable to create rally point drawable"));
if (marker)
if (!ttn)
{
marker->setDrawableStatus(DRAWABLE_STATUS_NO_SAVE);
m_rallyPointDrawableID = marker->getID();
return;
}

marker = TheThingFactory->newDrawable(ttn);
DEBUG_ASSERTCRASH(marker, ("showRallyPoint: Unable to create rally point drawable"));
marker->setDrawableStatus(DRAWABLE_STATUS_NO_SAVE);
m_rallyPointDrawableID = marker->getID();
}
else
marker = TheGameClient->findDrawableByID(m_rallyPointDrawableID);
Expand Down Expand Up @@ -3602,6 +3604,7 @@ void ControlBar::updateSpecialPowerShortcut()
}
else if( !hasValidShortcutButton
&& !m_specialPowerShortcutParent->winIsHidden()
&& m_animateWindowManagerForGenShortcuts
&& m_animateWindowManagerForGenShortcuts->isFinished() )
{
animateSpecialPowerShortcut(FALSE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -486,9 +486,29 @@ WindowMsgHandledType ControlBarSystem( GameWindow *window, UnsignedInt msg,

}

extern void showReplayControls();
extern void hideReplayControls();
extern void toggleReplayControls();
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
void showReplayControls()
{
if (TheInGameUI != nullptr)
TheInGameUI->showReplayControls();
}

// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
void hideReplayControls()
{
if (TheInGameUI != nullptr)
TheInGameUI->hideReplayControls();
}

// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
void toggleReplayControls()
{
if (TheInGameUI != nullptr)
TheInGameUI->toggleReplayControls();
}

//-------------------------------------------------------------------------------------------------
/** Force the control bar to be shown */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,13 @@ void GameWindowTransitionsHandler::reverse( AsciiString groupName )

void GameWindowTransitionsHandler::remove( AsciiString groupName, Bool skipPending )
{
TransitionGroup *g = findGroup(groupName);
TransitionGroup* g = findGroup(groupName);

if (!g)
{
return;
}

if(m_pendingGroup == g)
{
if(skipPending)
Expand Down
58 changes: 17 additions & 41 deletions Core/GameEngine/Source/GameClient/MapUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1142,53 +1142,38 @@ const MapMetaData *MapCache::findMap(AsciiString mapName)
// ------------------------------------------------------------------------------------------------
/** Embed the pristine map into the xfer stream */
// ------------------------------------------------------------------------------------------------
static void copyFromBigToDir( const AsciiString& infile, const AsciiString& outfile )
static Bool copyFromBigToDir( const AsciiString& infile, const AsciiString& outfile )
{
// open the map file

File *file = TheFileSystem->openFile( infile.str(), File::READ | File::BINARY );
if( file == nullptr )
{
DEBUG_CRASH(( "copyFromBigToDir - Error opening source file '%s'", infile.str() ));
throw SC_INVALID_DATA;
return FALSE;
}

// how big is the map file
Int fileSize = file->seek( 0, File::END );


// rewind to beginning of file
const Int fileSize = file->seek( 0, File::END );
file->seek( 0, File::START );

// allocate buffer big enough to hold the entire map file
char *buffer = NEW char[ fileSize ];
if( buffer == nullptr )
{
DEBUG_CRASH(( "copyFromBigToDir - Unable to allocate buffer for file '%s'", infile.str() ));
throw SC_INVALID_DATA;
}

// copy the file to the buffer
if( file->read( buffer, fileSize ) < fileSize )
{
DEBUG_CRASH(( "copyFromBigToDir - Error reading from file '%s'", infile.str() ));
throw SC_INVALID_DATA;
}
// close the BIG file
const Bool readOk = file->read( buffer, fileSize ) == fileSize;
file->close();
DEBUG_ASSERTCRASH( readOk, ( "copyFromBigToDir - Error reading from file '%s'", infile.str() ) );

File *filenew = TheFileSystem->openFile( outfile.str(), File::WRITE | File::CREATE | File::BINARY );

if( !filenew || filenew->write(buffer, fileSize) < fileSize)
Bool writeOk = FALSE;
if( readOk )
{
DEBUG_CRASH(( "copyFromBigToDir - Error writing to file '%s'", outfile.str() ));
throw SC_INVALID_DATA;
File *filenew = TheFileSystem->openFile( outfile.str(), File::WRITE | File::CREATE | File::BINARY );
if( filenew != nullptr )
{
writeOk = filenew->write( buffer, fileSize ) == fileSize;
filenew->close();
}
DEBUG_ASSERTCRASH( writeOk, ( "copyFromBigToDir - Error writing to file '%s'", outfile.str() ) );
}

filenew->close();

// delete the buffer
delete [] buffer;

return writeOk;
}

Image *getMapPreviewImage( AsciiString mapName )
Expand Down Expand Up @@ -1233,16 +1218,7 @@ Image *getMapPreviewImage( AsciiString mapName )

mapPreviewDir.concat(name);

Bool success = false;
try
{
copyFromBigToDir(tgaName, mapPreviewDir);
success = true;
}
catch (...)
{
success = false; // no rethrow
}
const Bool success = copyFromBigToDir(tgaName, mapPreviewDir);

if (success)
{
Expand Down
36 changes: 32 additions & 4 deletions Core/GameEngine/Source/GameClient/System/ParticleSys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,7 @@ ParticleSystemInfo::ParticleSystemInfo()
m_windMotionEndAngleMax = TWO_PI;
m_windMotionEndAngle = m_windMotionEndAngleMin;
m_windMotionMovingToEndAngle = TRUE;
m_volumeParticleDepth = DEFAULT_VOLUME_PARTICLE_DEPTH;
m_volumeParticleDepth = INVALID_VOLUME_PARTICLE_DEPTH;

}

Expand Down Expand Up @@ -1122,7 +1122,7 @@ ParticleSystem::ParticleSystem( const ParticleSystemTemplate *sysTemplate,


///@todo: further formalize this parameter with an UnsignedInt field in the editor
m_volumeParticleDepth = DEFAULT_VOLUME_PARTICLE_DEPTH;
m_volumeParticleDepth = sysTemplate->m_volumeParticleDepth;


m_driftVelocity = sysTemplate->m_driftVelocity;
Expand Down Expand Up @@ -2741,6 +2741,9 @@ const FieldParse ParticleSystemTemplate::m_fieldParseTable[] =
{ "SizeRate", INI::parseGameClientRandomVariable, nullptr, offsetof( ParticleSystemTemplate, m_sizeRate ) },
{ "SizeRateDamping", INI::parseGameClientRandomVariable, nullptr, offsetof( ParticleSystemTemplate, m_sizeRateDamping ) },

// TheSuperHackers @feature Volume particle depth is now exposed for configuration
{ "VolParticleDepth", INI::parseUnsignedInt, nullptr, offsetof(ParticleSystemTemplate, m_volumeParticleDepth) },

{ "Alpha1", ParticleSystemTemplate::parseRandomKeyframe, nullptr, offsetof( ParticleSystemTemplate, m_alphaKey[0] ) },
{ "Alpha2", ParticleSystemTemplate::parseRandomKeyframe, nullptr, offsetof( ParticleSystemTemplate, m_alphaKey[1] ) },
{ "Alpha3", ParticleSystemTemplate::parseRandomKeyframe, nullptr, offsetof( ParticleSystemTemplate, m_alphaKey[2] ) },
Expand Down Expand Up @@ -2910,6 +2913,31 @@ ParticleSystemTemplate::~ParticleSystemTemplate()
}

// ------------------------------------------------------------------------------------------------
void ParticleSystemTemplate::validate()
{
// TheSuperHackers @info Initialise all volume particles that lack ini configuration to the optimum depth of 6
// In retail, volume particle depth was not configurable through ini and was hard coded to a particle depth of 6
if (m_particleType == ParticleSystemInfo::VOLUME_PARTICLE)
{
if (m_volumeParticleDepth == INVALID_VOLUME_PARTICLE_DEPTH)
m_volumeParticleDepth = OPTIMUM_VOLUME_PARTICLE_DEPTH;
}
else
{
m_volumeParticleDepth = DEFAULT_VOLUME_PARTICLE_DEPTH;
}

#if PRESERVE_RETAIL_PARTICLES
// TheSuperHackers @info Hack to allow isUsingSmudge() functionality with retail smudge particles
// The retail data template for smudge particles is not correctly configured with the smudge particle type
if (m_particleType != ParticleSystemInfo::SMUDGE && m_particleTypeName.startsWithNoCase("SMUDGE."))
{
m_particleType = ParticleSystemInfo::SMUDGE;
}
#endif
}

// ------------------------------------------------------------------------------------------------
/** If returns non-null, it is a slave system for use ... the create slaves parameter
* tells *this* slave system whether or not it should create any slaves itself
* automatically during its own constructor */
Expand Down Expand Up @@ -3082,8 +3110,8 @@ void ParticleSystemManager::update()
if (sys->isUsingDrawables())
continue;

// temporary hack that checks if texture name starts with "SMUD" - if so, we can assume it's a smudge type
if (/*sys->isUsingSmudge()*/ *((DWORD *)sys->getParticleTypeName().str()) == 0x44554D53)
// Handle smudge type particles
if (sys->isUsingSmudge())
{
for (Particle *p = sys->getFirstParticle(); p; p = p->m_systemNext)
{
Expand Down
Loading
Loading