Skip to content
Merged
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
2 changes: 2 additions & 0 deletions Core/GameEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ set(GAMEENGINE_SRC
# Include/GameLogic/Module/ConvertToHijackedVehicleCrateCollide.h
# Include/GameLogic/Module/CostModifierUpgrade.h
# Include/GameLogic/Module/CountermeasuresBehavior.h
# Include/GameLogic/Module/BattlePlanBonusBehavior.h
# Include/GameLogic/Module/CrateCollide.h
# Include/GameLogic/Module/CreateCrateDie.h
# Include/GameLogic/Module/CreateModule.h
Expand Down Expand Up @@ -852,6 +853,7 @@ set(GAMEENGINE_SRC
# Source/GameLogic/Object/Behavior/BridgeTowerBehavior.cpp
# Source/GameLogic/Object/Behavior/BunkerBusterBehavior.cpp
# Source/GameLogic/Object/Behavior/CountermeasuresBehavior.cpp
# Source/GameLogic/Object/Behavior/BattlePlanBonusBehavior.cpp
# Source/GameLogic/Object/Behavior/DumbProjectileBehavior.cpp
# Source/GameLogic/Object/Behavior/FireWeaponWhenDamagedBehavior.cpp
# Source/GameLogic/Object/Behavior/FireWeaponWhenDeadBehavior.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static PoolSizeRec PoolSizes[] =
{ "GrantStealthBehavior", 4096, 32 },
{ "NeutronBlastBehavior", 4096, 32 },
{ "CountermeasuresBehavior", 256, 32 },
{ "BattlePlanBonusBehavior", 256, 32 },
{ "BaseRegenerateUpdate", 128, 32 },
{ "BoneFXDamage", 64, 32 },
{ "BoneFXUpdate", 64, 32 },
Expand Down
2 changes: 2 additions & 0 deletions GeneralsMD/Code/GameEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ set(GAMEENGINE_SRC
Include/GameLogic/Module/ProductionTimeModifierUpgrade.h
Include/GameLogic/Module/UnitProductionBonusUpgrade.h
Include/GameLogic/Module/CountermeasuresBehavior.h
Include/GameLogic/Module/BattlePlanBonusBehavior.h
Include/GameLogic/Module/CrateCollide.h
Include/GameLogic/Module/CreateCrateDie.h
Include/GameLogic/Module/CreateModule.h
Expand Down Expand Up @@ -867,6 +868,7 @@ set(GAMEENGINE_SRC
Source/GameLogic/Object/Behavior/BridgeTowerBehavior.cpp
Source/GameLogic/Object/Behavior/BunkerBusterBehavior.cpp
Source/GameLogic/Object/Behavior/CountermeasuresBehavior.cpp
Source/GameLogic/Object/Behavior/BattlePlanBonusBehavior.cpp
Source/GameLogic/Object/Behavior/DumbProjectileBehavior.cpp
Source/GameLogic/Object/Behavior/FreeFallProjectileBehavior.cpp
Source/GameLogic/Object/Behavior/FireWeaponWhenDamagedBehavior.cpp
Expand Down
6 changes: 4 additions & 2 deletions GeneralsMD/Code/GameEngine/Include/Common/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ class Player : public Snapshot
this call externally, you probably don't... you should probably be
using grantScience() instead.
*/
Bool addScience(ScienceType science);
Bool addScience(ScienceType science, Bool playerAction = FALSE);

public:
Int getSkillPoints() const { return m_skillPoints; }
Expand Down Expand Up @@ -740,7 +740,7 @@ class Player : public Snapshot
attempt to purchase the science, but use prereqs, and charge points.
return true if successful.
*/
Bool attemptToPurchaseScience(ScienceType science);
Bool attemptToPurchaseScience(ScienceType science, Bool playerAction = FALSE);

/**
grant the science, ignore prereqs & charge no points,
Expand All @@ -753,6 +753,8 @@ class Player : public Snapshot
/** return true attemptToPurchaseScience() would succeed for this science. */
Bool isCapableOfPurchasingScience(ScienceType science) const;

const BattlePlanBonuses* getBattlePlanBonuses(void) const { return m_battlePlanBonuses; }

protected:

// snapshot methods
Expand Down
3 changes: 3 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/Common/Science.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class ScienceInfo : public Overridable
ScienceVec m_prereqSciences;
Int m_sciencePurchasePointCost;
Bool m_grantable;
std::vector<AsciiString> m_grantedUpgradeNames;

ScienceInfo() :
m_science(SCIENCE_INVALID),
Expand Down Expand Up @@ -91,6 +92,8 @@ class ScienceStore : public SubsystemInterface

Bool isScienceGrantable(ScienceType st) const;

Bool getGrantedUpgradeNames(ScienceType st, std::vector<AsciiString>& grantedUpgradeNames) const;

Bool getNameAndDescription(ScienceType st, UnicodeString& name, UnicodeString& description) const;

Bool playerHasPrereqsForScience(const Player* player, ScienceType st) const;
Expand Down
4 changes: 4 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/Common/Upgrade.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ class UpgradeTemplate : public MemoryPoolObject
const AudioEventRTS* getUnitSpecificSound() const { return &m_unitSpecificSound; }
AcademyClassificationType getAcademyClassificationType() const { return m_academyClassificationType; }

const Bool isSilentCompletion(void) const { return m_silentCompletion; }

/// inventory pictures
void cacheButtonImage();
const Image* getButtonImage() const { return m_buttonImage; }
Expand Down Expand Up @@ -212,6 +214,8 @@ class UpgradeTemplate : public MemoryPoolObject
AudioEventRTS m_unitSpecificSound; ///< Secondary sound played when upgrade researched.
AcademyClassificationType m_academyClassificationType; ///< A value used by the academy to evaluate advice based on what players do.

Bool m_silentCompletion; ///< hide notification and audio when this upgrade is completed.

UpgradeTemplate *m_next; ///< next
UpgradeTemplate *m_prev; ///< prev

Expand Down
1 change: 1 addition & 0 deletions GeneralsMD/Code/GameEngine/Include/GameLogic/ArmorSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class INI;
// has all condition flags set to zero.
enum ArmorSetType CPP_11(: Int)
{
ARMORSET_NONE = -1,
// The access and use of this enum has the bit shifting built in, so this is a 0,1,2,3,4,5 enum
ARMORSET_VETERAN = 0,
ARMORSET_ELITE = 1,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
** Command & Conquer Generals Zero Hour(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: BattlePlanBonusBehavior.h /////////////////////////////////////////////////////////////////////////
// Author: Andi W, September 2025
// Desc: Behavior to react to battlePlans being applied or removed to this object
///////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

#ifndef __BATTLEPLANBONUSBEHAVIOR_H_
#define __BATTLEPLANBONUSBEHAVIOR_H_

// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////

#include "GameLogic/Module/BehaviorModule.h"
#include "GameLogic/Module/UpgradeModule.h"
#include "GameLogic/Module/BattlePlanUpdate.h"

enum BattlePlanStatus CPP_11(: Int);
enum WeaponBonusConditionType CPP_11(: Int);
enum WeaponSetType CPP_11(: Int);
enum ArmorSetType CPP_11(: Int);
enum ObjectStatusTypes CPP_11(: Int);

enum { BATTLE_PLAN_COUNT = PLANSTATUS_COUNT-1 };

//-------------------------------------------------------------------------------------------------
class BattlePlanBonusBehaviorModuleData : public BehaviorModuleData
{
public:
UpgradeMuxData m_upgradeMuxData;

Bool m_initiallyActive; // Apply upgrade immediately (Does this make sense?)
Bool m_overrideGlobal; // Do not apply effects from global BattlePlan bonus
Bool m_shouldParalyze; // Paralyze this unit when applying BattlePlans

WeaponBonusConditionType m_weaponBonusEntries[BATTLE_PLAN_COUNT];
WeaponSetType m_weaponSetFlagEntries[BATTLE_PLAN_COUNT];
ArmorSetType m_armorSetFlagEntries[BATTLE_PLAN_COUNT];
Real m_armorDamageScalarEntries[BATTLE_PLAN_COUNT];
Real m_sightRangeScalarEntries[BATTLE_PLAN_COUNT];
//Real m_movementSpeedScalarEntries[BATTLE_PLAN_COUNT];
ObjectStatusTypes m_statusToSetEntries[BATTLE_PLAN_COUNT];
ObjectStatusTypes m_statusToClearEntries[BATTLE_PLAN_COUNT];

//std::vector<std::vector<WeaponBonusConditionType>> m_weaponBonusEntries;
//std::vector<std::vector<WeaponSetType>> m_weaponSetFlagEntries;
//std::vector<std::vector<WeaponBonusConditionType>> m_armorSetFlagEntries;
//std::vector<std::vector<WeaponBonusConditionType>> m_armorDamageScalarEntries;
//std::vector<std::vector<WeaponBonusConditionType>> m_sightRangeScalarEntries;
//std::vector<std::vector<WeaponBonusConditionType>> m_movementSpeedScalarEntries;

BattlePlanBonusBehaviorModuleData();

static void buildFieldParse(MultiIniFieldParse& p);

private:
static void parseBPWeaponBonus(INI* ini, void* instance, void* store, const void* userData);
static void parseBPWeaponSetFlag(INI* ini, void* instance, void* store, const void* userData);
static void parseBPArmorSetFlag(INI* ini, void* instance, void* store, const void* userData);
static void parseBPArmorDamageScalar(INI* ini, void* instance, void* store, const void* userData);
static void parseBPSightRangeScalar(INI* ini, void* instance, void* store, const void* userData);
//static void parseBPMovementSpeedScalar(INI* ini, void* instance, void* store, const void* userData);
static void parseBPStatusToSet(INI* ini, void* instance, void* store, const void* userData);
static void parseBPStatusToClear(INI* ini, void* instance, void* store, const void* userData);
};
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
class BattlePlanBonusBehaviorInterface
{
public:
virtual void applyBonus(const BattlePlanBonuses* bonus, bool checkIsValid = TRUE) = 0;
//virtual void removeBonus(const BattlePlanBonuses* bonus) = 0;
virtual Bool shouldParalyze() const = 0;
virtual Bool isOverrideGlobalBonus() const = 0;
virtual Bool isConflicting() const = 0;
virtual Bool isAnyEffectApplied() const = 0;
virtual void removeActiveEffects() = 0;
};
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
class BattlePlanBonusBehavior : public BehaviorModule, public UpgradeMux, public BattlePlanBonusBehaviorInterface
{

MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(BattlePlanBonusBehavior, "BattlePlanBonusBehavior")
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA(BattlePlanBonusBehavior, BattlePlanBonusBehaviorModuleData)

private:
//UnsignedInt m_triggerFrame;
//// UnsignedInt m_shotsLeft;
//// TODO: Which weaponslot
//Bool m_triggerCompleted;

public:

BattlePlanBonusBehavior(Thing* thing, const ModuleData* moduleData);
// virtual destructor prototype provided by memory pool declaration

// module methods
static Int getInterfaceMask() { return BehaviorModule::getInterfaceMask() | MODULEINTERFACE_UPGRADE; }

// BehaviorModule
virtual UpgradeModuleInterface* getUpgrade() { return this; }
virtual BattlePlanBonusBehaviorInterface* getBattlePlanBonusBehaviorInterface() { return this; }

protected:
// BattlePlan stuff

void applyBonus(const BattlePlanBonuses*, bool checkIsValid = TRUE);
//void removeBonus(const BattlePlanBonuses*);
Bool shouldParalyze() const;
Bool isOverrideGlobalBonus() const;

Bool isConflicting() const;
Bool isAnyEffectApplied() const;
void removeActiveEffects();

// Upgrade stuff

virtual void upgradeImplementation();

virtual void getUpgradeActivationMasks(UpgradeMaskType& activation, UpgradeMaskType& conflicting) const
{
getBattlePlanBonusBehaviorModuleData()->m_upgradeMuxData.getUpgradeActivationMasks(activation, conflicting);
}

virtual void performUpgradeFX()
{
getBattlePlanBonusBehaviorModuleData()->m_upgradeMuxData.performUpgradeFX(getObject());
}

virtual void processUpgradeRemoval()
{
// I can't take it any more. Let the record show that I think the UpgradeMux multiple inheritence is CRAP.
getBattlePlanBonusBehaviorModuleData()->m_upgradeMuxData.muxDataProcessUpgradeRemoval(getObject());
}

virtual Bool requiresAllActivationUpgrades() const
{
return getBattlePlanBonusBehaviorModuleData()->m_upgradeMuxData.m_requiresAllTriggers;
}

inline Bool isUpgradeActive() const { return isAlreadyUpgraded(); }

virtual Bool isSubObjectsUpgrade() { return false; }

private:
Bool isEffectValid() const;
void addBonusForType(BattlePlanStatus plan);
void removeBonusForType(BattlePlanStatus plan);

Bool m_effectApplied[BATTLE_PLAN_COUNT];
};

#endif // __BattlePlanBonusBehavior_H_

Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,26 @@ enum TransitionStatus CPP_11(: Int)
TRANSITIONSTATUS_PACKING,
};

#ifdef DEFINE_BATTLEPLANSTATUS_NAMES
static const char* TheBattlePlanStatusNames[] =
{
"NONE",
"BOMBARDMENT",
"HOLD_THE_LINE",
"SEARCH_AND_DESTROY",

NULL
};
#endif

enum BattlePlanStatus CPP_11(: Int)
{
PLANSTATUS_NONE,
PLANSTATUS_BOMBARDMENT,
PLANSTATUS_HOLDTHELINE,
PLANSTATUS_SEARCHANDDESTROY,

PLANSTATUS_COUNT
};

class BattlePlanBonuses : public MemoryPoolObject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ class DamageInfo;
class ParticleSystemTemplate;
class StealthUpdate;
class SpyVisionUpdate;

// -----------------
class BattlePlanBonusBehaviorInterface;

//-------------------------------------------------------------------------------------------------
class BehaviorModuleData : public ModuleData
Expand Down Expand Up @@ -140,6 +141,8 @@ class BehaviorModuleInterface
virtual CountermeasuresBehaviorInterface* getCountermeasuresBehaviorInterface() = 0;
virtual const CountermeasuresBehaviorInterface* getCountermeasuresBehaviorInterface() const = 0;

virtual BattlePlanBonusBehaviorInterface* getBattlePlanBonusBehaviorInterface() = 0;

};

//-------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -194,6 +197,7 @@ class BehaviorModule : public ObjectModule, public BehaviorModuleInterface
virtual SpawnBehaviorInterface* getSpawnBehaviorInterface() { return NULL; }
virtual CountermeasuresBehaviorInterface* getCountermeasuresBehaviorInterface() { return NULL; }
virtual const CountermeasuresBehaviorInterface* getCountermeasuresBehaviorInterface() const { return NULL; }
virtual BattlePlanBonusBehaviorInterface* getBattlePlanBonusBehaviorInterface() { return NULL; };

protected:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
class Thing;
enum StealthLookType CPP_11(: Int);
enum EvaMessage CPP_11(: Int);
enum WeaponSetType CPP_11(: Int);
class FXList;

enum
Expand Down Expand Up @@ -155,6 +156,8 @@ class StealthUpdate : public UpdateModule
Bool isGrantedBySpecialPower( void ) { return getStealthUpdateModuleData()->m_grantedBySpecialPower; }
Bool isTemporaryGrant() { return m_framesGranted > 0; }

inline void setStealthLevelOverride(UnsignedInt stealthLevel) { m_stealthLevelOverride = stealthLevel; }

protected:

StealthLookType calcStealthedStatusForPlayer(const Object* obj, const Player* player);
Expand All @@ -175,6 +178,8 @@ class StealthUpdate : public UpdateModule
Real m_pulsePhaseRate;
Real m_pulsePhase;

UnsignedInt m_stealthLevelOverride; //Override stealth conditions via upgrade

//Disguise only members
Int m_disguiseAsPlayerIndex; //The player team we are wanting to disguise as (might not actually be disguised yet).
const ThingTemplate *m_disguiseAsTemplate; //The disguise template (might not actually be using it yet)
Expand All @@ -187,7 +192,6 @@ class StealthUpdate : public UpdateModule
// runtime xfer members (does not need saving)
Bool m_xferRestoreDisguise; //Tells us we need to restore our disguise
WeaponSetType m_requiresWeaponSetType;

};


Expand Down
Loading