Skip to content

Commit eee10d3

Browse files
authored
Merge pull request #52 from Andreas-W/AdvancedCollide
Advanced collide module and Sticky Bomb improvements
2 parents d8ecf03 + a3a1fc4 commit eee10d3

File tree

12 files changed

+438
-51
lines changed

12 files changed

+438
-51
lines changed

Core/GameEngine/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ set(GAMEENGINE_SRC
322322
# Include/GameLogic/Module/FireSpreadUpdate.h
323323
# Include/GameLogic/Module/FirestormDynamicGeometryInfoUpdate.h
324324
# Include/GameLogic/Module/FireWeaponCollide.h
325+
# Include/GameLogic/Module/AdvancedCollide.h
325326
# Include/GameLogic/Module/FireWeaponPower.h
326327
# Include/GameLogic/Module/FireWeaponUpdate.h
327328
# Include/GameLogic/Module/FireWeaponWhenDamagedBehavior.h
@@ -907,6 +908,7 @@ set(GAMEENGINE_SRC
907908
# Source/GameLogic/Object/Collide/CrateCollide/UnitCrateCollide.cpp
908909
# Source/GameLogic/Object/Collide/CrateCollide/VeterancyCrateCollide.cpp
909910
# Source/GameLogic/Object/Collide/FireWeaponCollide.cpp
911+
# Source/GameLogic/Object/Collide/AdvancedCollide.cpp
910912
# Source/GameLogic/Object/Collide/SquishCollide.cpp
911913
# Source/GameLogic/Object/Contain/CaveContain.cpp
912914
# Source/GameLogic/Object/Contain/GarrisonContain.cpp

Core/GameEngine/Source/Common/System/GameMemoryInitPools_GeneralsMD.inl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ static PoolSizeRec PoolSizes[] =
143143
{ "FireSpreadUpdate", 2048, 128 },
144144
{ "FirestormDynamicGeometryInfoUpdate", 16, 16 },
145145
{ "FireWeaponCollide", 2048, 32 },
146+
{ "AdvancedCollide", 512, 32 },
146147
{ "FireWeaponUpdate", 32, 32 },
147148
{ "FireWeaponAdvancedUpdate", 32, 32 },
148149
{ "FlammableUpdate", 512, 256 },

Generals/Code/GameEngine/Source/Common/Thing/ModuleFactory.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,6 @@
230230
#include "GameLogic/Module/ImmortalBody.h"
231231
#include "GameLogic/Module/StructureBody.h"
232232
#include "GameLogic/Module/HiveStructureBody.h"
233-
#include "GameLogic/Module/ShieldBody.h"
234233

235234
// contain includes
236235
// (none)

GeneralsMD/Code/GameEngine/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ set(GAMEENGINE_SRC
326326
Include/GameLogic/Module/FireSpreadUpdate.h
327327
Include/GameLogic/Module/FirestormDynamicGeometryInfoUpdate.h
328328
Include/GameLogic/Module/FireWeaponCollide.h
329+
Include/GameLogic/Module/AdvancedCollide.h
329330
Include/GameLogic/Module/FireWeaponPower.h
330331
Include/GameLogic/Module/FireWeaponUpdate.h
331332
Include/GameLogic/Module/FireWeaponAdvancedUpdate.h
@@ -929,6 +930,7 @@ set(GAMEENGINE_SRC
929930
Source/GameLogic/Object/Collide/CrateCollide/UnitCrateCollide.cpp
930931
Source/GameLogic/Object/Collide/CrateCollide/VeterancyCrateCollide.cpp
931932
Source/GameLogic/Object/Collide/FireWeaponCollide.cpp
933+
Source/GameLogic/Object/Collide/AdvancedCollide.cpp
932934
Source/GameLogic/Object/Collide/SquishCollide.cpp
933935
Source/GameLogic/Object/Contain/CaveContain.cpp
934936
Source/GameLogic/Object/Contain/GarrisonContain.cpp
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
** Command & Conquer Generals Zero Hour(tm)
3+
** Copyright 2025 Electronic Arts Inc.
4+
**
5+
** This program is free software: you can redistribute it and/or modify
6+
** it under the terms of the GNU General Public License as published by
7+
** the Free Software Foundation, either version 3 of the License, or
8+
** (at your option) any later version.
9+
**
10+
** This program is distributed in the hope that it will be useful,
11+
** but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
** GNU General Public License for more details.
14+
**
15+
** You should have received a copy of the GNU General Public License
16+
** along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
////////////////////////////////////////////////////////////////////////////////
20+
// //
21+
// (c) 2001-2003 Electronic Arts Inc. //
22+
// //
23+
////////////////////////////////////////////////////////////////////////////////
24+
25+
// FILE: AdvancedCollide.h ///////////////////////////////////////////////////////////////////////////
26+
// Author: Andi W, Oct 25
27+
// Desc: Do something if we collide with objects or the ground
28+
///////////////////////////////////////////////////////////////////////////////////////////////////
29+
30+
#pragma once
31+
32+
#ifndef __AdvancedCollide_H_
33+
#define __AdvancedCollide_H_
34+
35+
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
36+
#include "GameLogic/Module/CollideModule.h"
37+
#include "GameLogic/Weapon.h"
38+
39+
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
40+
class Object;
41+
class FXList;
42+
class ObjectCreationList;
43+
44+
//-------------------------------------------------------------------------------------------------
45+
class AdvancedCollideModuleData : public CollideModuleData
46+
{
47+
public:
48+
const WeaponTemplate* m_collideWeaponTemplate; ///< Weapon To Fire
49+
const FXList* m_fxlist; ///< FX to play
50+
const ObjectCreationList* m_ocl; ///< object creaton list to make
51+
52+
KindOfMaskType m_kindof; ///< the kind(s) of units that can be collided with
53+
KindOfMaskType m_kindofnot; ///< the kind(s) of units that CANNOT be collided with
54+
55+
ObjectStatusMaskType m_requiredStatus;
56+
ObjectStatusMaskType m_forbiddenStatus;
57+
ObjectStatusMaskType m_targetRequiredStatus;
58+
ObjectStatusMaskType m_targetForbiddenStatus;
59+
60+
Bool m_fireOnce; ///< trigger effects only once
61+
Bool m_collideWithGround; ///< trigger on collide with Ground
62+
Bool m_collideWithObjects; ///< trigger on collide with Objects
63+
64+
Real m_triggerChance; ///< chance to trigger effects on a valid collission
65+
Bool m_rollOnce; ///< Only Roll once to trigger effects; Or roll every frame.
66+
67+
68+
AdvancedCollideModuleData()
69+
{
70+
m_collideWeaponTemplate = NULL;
71+
m_fxlist = NULL;
72+
m_ocl = NULL;
73+
m_fireOnce = FALSE;
74+
m_collideWithGround = FALSE;
75+
m_collideWithObjects = TRUE;
76+
m_triggerChance = 1.0;
77+
m_rollOnce = FALSE;
78+
}
79+
80+
static void buildFieldParse(MultiIniFieldParse& p);
81+
};
82+
83+
//-------------------------------------------------------------------------------------------------
84+
class AdvancedCollide : public CollideModule
85+
{
86+
87+
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( AdvancedCollide, AdvancedCollideModuleData );
88+
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AdvancedCollide, "AdvancedCollide" )
89+
90+
public:
91+
92+
AdvancedCollide( Thing *thing, const ModuleData* moduleData );
93+
// virtual destructor prototype provided by memory pool declaration
94+
95+
protected:
96+
97+
virtual void onCollide( Object *other, const Coord3D *loc, const Coord3D *normal );
98+
99+
virtual Bool shouldTrigger(Object* other);
100+
101+
private:
102+
Weapon* m_collideWeapon;
103+
Bool m_everFired;
104+
Real m_roll;
105+
106+
};
107+
108+
109+
#endif
110+

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/StickyBombCrateCollide.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,15 @@ class StickyBombCrateCollideModuleData : public CrateCollideModuleData
5151
Bool m_allowMultiCollide; ///< if we are a crate, allow spawning multiple sticky bombs, or just single use
5252
Bool m_showInfiltrationEvent; ///< show an infiltration map event for the target player
5353
AsciiString m_stickyBombObjectName; ///< the object to create
54+
Real m_triggerChance; ///< chance to create the bomb when triggering the module
5455

5556
StickyBombCrateCollideModuleData()
5657
{
5758
m_needsTarget = FALSE;
5859
m_allowMultiCollide = FALSE;
5960
m_showInfiltrationEvent = FALSE;
6061
m_stickyBombObjectName = AsciiString::TheEmptyString;
62+
m_triggerChance = 1.0;
6163
}
6264

6365
static void buildFieldParse(MultiIniFieldParse& p)
@@ -70,6 +72,7 @@ class StickyBombCrateCollideModuleData : public CrateCollideModuleData
7072
{ "AllowMultiCollide", INI::parseBool, NULL, offsetof(StickyBombCrateCollideModuleData, m_allowMultiCollide) },
7173
{ "ShowInfiltrationEvent", INI::parseBool, NULL, offsetof(StickyBombCrateCollideModuleData, m_showInfiltrationEvent) },
7274
{ "StickyBombObject", INI::parseAsciiString, NULL, offsetof(StickyBombCrateCollideModuleData, m_stickyBombObjectName) },
75+
{ "ChanceToTriggerPercent", INI::parsePercentToReal, NULL, offsetof(StickyBombCrateCollideModuleData, m_triggerChance) },
7376
{ 0, 0, 0, 0 }
7477
};
7578
p.add( dataFieldParse );
@@ -92,7 +95,7 @@ class StickyBombCrateCollide : public CrateCollide
9295
protected:
9396

9497
/// This allows specific vetoes to certain types of crates and their data
95-
virtual Bool isValidToExecute( const Object *other ) const;
98+
// virtual Bool isValidToExecute( const Object *other ) const;
9699

97100
/// This is the game logic execution function that all real CrateCollides will implement
98101
virtual Bool executeCrateBehavior( Object *other );

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/StickyBombUpdate.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ class StickyBombUpdateModuleData : public UpdateModuleData
5050

5151
AsciiString m_animBaseTemplate;
5252
AsciiString m_animTimedTemplate;
53-
Bool m_showTimer;
53+
Bool m_showTimer; ///< if this is disabled, only use animBase for timed bombs
54+
55+
Bool m_hideAnimBase; ///< will be set automatically if String is Null
56+
Bool m_hideAnimTimed; ///< will be set automatically if String is Null
5457

5558
StickyBombUpdateModuleData()
5659
{
@@ -62,6 +65,9 @@ class StickyBombUpdateModuleData : public UpdateModuleData
6265
m_showTimer = TRUE;
6366
}
6467

68+
static void parseAnimBaseName(INI* ini, void* instance, void* store, const void* userData);
69+
static void parseAnimTimedName(INI* ini, void* instance, void* store, const void* userData);
70+
6571
static void buildFieldParse(MultiIniFieldParse& p)
6672
{
6773
UpdateModuleData::buildFieldParse(p);
@@ -71,8 +77,8 @@ class StickyBombUpdateModuleData : public UpdateModuleData
7177
{ "OffsetZ", INI::parseReal, NULL, offsetof( StickyBombUpdateModuleData, m_offsetZ ) },
7278
{ "GeometryBasedDamageWeapon",INI::parseWeaponTemplate, NULL, offsetof( StickyBombUpdateModuleData, m_geometryBasedDamageWeaponTemplate ) },
7379
{ "GeometryBasedDamageFX", INI::parseFXList, NULL, offsetof( StickyBombUpdateModuleData, m_geometryBasedDamageFX ) },
74-
{ "Animation2DBase", INI::parseAsciiString, NULL, offsetof( StickyBombUpdateModuleData, m_animBaseTemplate) },
75-
{ "Animation2DTimed", INI::parseAsciiString, NULL, offsetof( StickyBombUpdateModuleData, m_animTimedTemplate) },
80+
{ "Animation2DBase", parseAnimBaseName, NULL, 0 },
81+
{ "Animation2DTimed", parseAnimTimedName, NULL, 0 },
7682
{ "ShowTimer", INI::parseBool, NULL, offsetof( StickyBombUpdateModuleData, m_showTimer) },
7783
{ 0, 0, 0, 0 }
7884
};
@@ -109,6 +115,9 @@ class StickyBombUpdate : public UpdateModule
109115
Anim2DTemplate* getAnimBaseTemplate();
110116
Anim2DTemplate* getAnimTimedTemplate();
111117

118+
inline Bool showAnimBaseTemplate() { return !getStickyBombUpdateModuleData()->m_hideAnimBase; }
119+
inline Bool showAnimTimedTemplate() { return !getStickyBombUpdateModuleData()->m_hideAnimTimed; }
120+
112121
private:
113122

114123
ObjectID m_targetID;

GeneralsMD/Code/GameEngine/Source/Common/Thing/ModuleFactory.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@
245245

246246
// collide includes
247247
#include "GameLogic/Module/FireWeaponCollide.h"
248+
#include "GameLogic/Module/AdvancedCollide.h"
248249
#include "GameLogic/Module/SquishCollide.h"
249250

250251
#include "GameLogic/Module/ConvertToCarBombCrateCollide.h"
@@ -543,6 +544,7 @@ void ModuleFactory::init( void )
543544

544545
// collide modules
545546
addModule( FireWeaponCollide );
547+
addModule( AdvancedCollide );
546548
addModule( SquishCollide );
547549

548550
addModule( HealCrateCollide );

GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3744,8 +3744,8 @@ void Drawable::drawBombed(const IRegion2D* healthBarRegion)
37443744
{
37453745
if( update->isTimedBomb() )
37463746
{
3747-
//Timed bomb
3748-
if( !getIconInfo()->m_icon[ ICON_BOMB_TIMED ] )
3747+
//Timed bomb - Base layer
3748+
if (!getIconInfo()->m_icon[ICON_BOMB_REMOTE] && update->showAnimBaseTemplate())
37493749
{
37503750
Anim2DTemplate* templ = update->getAnimBaseTemplate();
37513751

@@ -3754,7 +3754,11 @@ void Drawable::drawBombed(const IRegion2D* healthBarRegion)
37543754

37553755
getIconInfo()->m_icon[ICON_BOMB_REMOTE] = newInstance(Anim2D)(templ, TheAnim2DCollection);
37563756

3757-
templ = update->getAnimTimedTemplate();
3757+
}
3758+
//Timed bomb - Timer
3759+
if( !getIconInfo()->m_icon[ ICON_BOMB_TIMED ] && update->showAnimTimedTemplate())
3760+
{
3761+
Anim2DTemplate* templ = update->getAnimTimedTemplate();
37583762

37593763
if (templ == NULL) // Default icon
37603764
templ = s_animationTemplates[ICON_BOMB_TIMED];
@@ -3785,7 +3789,9 @@ void Drawable::drawBombed(const IRegion2D* healthBarRegion)
37853789
getIconInfo()->m_icon[ ICON_BOMB_TIMED ]->setMinFrame(numFrames - seconds - 1);
37863790
getIconInfo()->m_icon[ ICON_BOMB_TIMED ]->reset();
37873791
}
3788-
if( getIconInfo()->m_icon[ ICON_BOMB_TIMED ] )
3792+
Bool showTimedAnim = (getIconInfo()->m_icon[ICON_BOMB_TIMED]) != NULL;
3793+
Bool showBaseAnim = (getIconInfo()->m_icon[ICON_BOMB_REMOTE]) != NULL;
3794+
if( showTimedAnim || showBaseAnim)
37893795
{
37903796
//
37913797
// we are going to draw the healing icon relative to the size of the health bar region
@@ -3796,8 +3802,15 @@ void Drawable::drawBombed(const IRegion2D* healthBarRegion)
37963802
Int barWidth = healthBarRegion->hi.x - healthBarRegion->lo.x;
37973803
Int barHeight = healthBarRegion->hi.y - healthBarRegion->lo.y;
37983804

3799-
Int frameWidth = getIconInfo()->m_icon[ ICON_BOMB_TIMED ]->getCurrentFrameWidth();
3800-
Int frameHeight = getIconInfo()->m_icon[ ICON_BOMB_TIMED ]->getCurrentFrameHeight();
3805+
Int frameWidth, frameHeight;
3806+
if (showTimedAnim) {
3807+
frameWidth = getIconInfo()->m_icon[ICON_BOMB_TIMED]->getCurrentFrameWidth();
3808+
frameHeight = getIconInfo()->m_icon[ICON_BOMB_TIMED]->getCurrentFrameHeight();
3809+
}
3810+
else {
3811+
frameWidth = getIconInfo()->m_icon[ICON_BOMB_REMOTE]->getCurrentFrameWidth();
3812+
frameHeight = getIconInfo()->m_icon[ICON_BOMB_REMOTE]->getCurrentFrameHeight();
3813+
}
38013814

38023815
// adjust the width to be a % of the health bar region size
38033816
Int size = REAL_TO_INT( barWidth * 0.65f );
@@ -3809,18 +3822,21 @@ void Drawable::drawBombed(const IRegion2D* healthBarRegion)
38093822
screen.x = REAL_TO_INT( healthBarRegion->lo.x + (barWidth * 0.5f) - (frameWidth * 0.5f) );
38103823
screen.y = REAL_TO_INT( healthBarRegion->lo.y + barHeight * 0.5f ) + BOMB_ICON_EXTRA_OFFSET;
38113824

3812-
getIconInfo()->m_icon[ ICON_BOMB_REMOTE ]->draw( screen.x, screen.y, frameWidth, frameHeight );
3813-
getIconInfo()->m_keepTillFrame[ ICON_BOMB_REMOTE ] = now + 1;
3814-
getIconInfo()->m_icon[ ICON_BOMB_TIMED ]->draw( screen.x, screen.y, frameWidth, frameHeight );
3815-
getIconInfo()->m_keepTillFrame[ ICON_BOMB_TIMED ] = now + 1;
3825+
if (showBaseAnim) {
3826+
getIconInfo()->m_icon[ICON_BOMB_REMOTE]->draw(screen.x, screen.y, frameWidth, frameHeight);
3827+
getIconInfo()->m_keepTillFrame[ICON_BOMB_REMOTE] = now + 1;
3828+
}
3829+
if (showTimedAnim) {
3830+
getIconInfo()->m_icon[ICON_BOMB_TIMED]->draw(screen.x, screen.y, frameWidth, frameHeight);
3831+
getIconInfo()->m_keepTillFrame[ICON_BOMB_TIMED] = now + 1;
3832+
}
38163833
}
38173834
}
38183835
}
38193836
else
38203837
{
38213838
//Remote charge
3822-
//Timed bomb
3823-
if( !getIconInfo()->m_icon[ ICON_BOMB_REMOTE ] )
3839+
if( !getIconInfo()->m_icon[ ICON_BOMB_REMOTE ] && update->showAnimBaseTemplate())
38243840
{
38253841
Anim2DTemplate* templ = update->getAnimBaseTemplate();
38263842

0 commit comments

Comments
 (0)