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
Original file line number Diff line number Diff line change
Expand Up @@ -701,5 +701,6 @@ static PoolSizeRec PoolSizes[] =
{ "CarrierDroneAIUpdate", 16, 16 },
{ "DrawBridgeTowerUpdate", 8, 8 },
{ "DrawBridgeUpdate", 4, 4 },
{ "CrateApplyUpgrade", 64, 32 },
{ 0, 0, 0 }
};
2 changes: 2 additions & 0 deletions GeneralsMD/Code/GameEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,7 @@ set(GAMEENGINE_SRC
Include/GameLogic/Module/BridgeTowerBody.h
Include/GameLogic/Module/DrawBridgeTowerUpdate.h
Include/GameLogic/Module/DrawBridgeUpdate.h
Include/GameLogic/Module/CrateApplyUpgrade.h
Include/GameLogic/Object.h
Include/GameLogic/ObjectCreationList.h
Include/GameLogic/BuffSystem.h
Expand Down Expand Up @@ -1147,6 +1148,7 @@ set(GAMEENGINE_SRC
Source/GameLogic/Object/Upgrade/UpgradeModule.cpp
Source/GameLogic/Object/Upgrade/WeaponBonusUpgrade.cpp
Source/GameLogic/Object/Upgrade/WeaponSetUpgrade.cpp
Source/GameLogic/Object/Upgrade/CrateApplyUpgrade.cpp
Source/GameLogic/Object/Weapon.cpp
Source/GameLogic/Object/WeaponSet.cpp
Source/GameLogic/ScriptEngine/ScriptActions.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class AutoHealBehaviorModuleData : public UpdateModuleData
KindOfMaskType m_forbiddenKindOf; //Only these types can heal -- defaults to everything.
const ParticleSystemTemplate* m_radiusParticleSystemTmpl; //Optional particle system meant to apply to entire effect for entire duration.
const ParticleSystemTemplate* m_unitHealPulseParticleSystemTmpl; //Optional particle system applying to each object getting healed each heal pulse.
Bool m_grantSalvageUpgrade; //Apply a salvage upgrade to unit when healing
Bool m_grantPromotion; //Give unit a levelup when healing

AutoHealBehaviorModuleData()
{
Expand All @@ -76,6 +78,8 @@ class AutoHealBehaviorModuleData : public UpdateModuleData
m_skipSelfForHealing = FALSE;
SET_ALL_KINDOFMASK_BITS( m_kindOf );
m_forbiddenKindOf.clear();
m_grantSalvageUpgrade = false;
m_grantPromotion = false;
}

static void buildFieldParse(MultiIniFieldParse& p)
Expand All @@ -94,6 +98,8 @@ class AutoHealBehaviorModuleData : public UpdateModuleData
{ "StartHealingDelay", INI::parseDurationUnsignedInt, nullptr, offsetof( AutoHealBehaviorModuleData, m_startHealingDelay ) },
{ "AffectsWholePlayer", INI::parseBool, nullptr, offsetof( AutoHealBehaviorModuleData, m_affectsWholePlayer ) },
{ "SkipSelfForHealing", INI::parseBool, nullptr, offsetof( AutoHealBehaviorModuleData, m_skipSelfForHealing ) },
{ "GrantSalvageUpgrade", INI::parseBool, nullptr, offsetof( AutoHealBehaviorModuleData, m_grantSalvageUpgrade ) },
{ "GrantPromotion", INI::parseBool, nullptr, offsetof( AutoHealBehaviorModuleData, m_grantPromotion ) },
{ 0, 0, 0, 0 }
};

Expand Down Expand Up @@ -173,7 +179,12 @@ class AutoHealBehavior : public UpdateModule,

private:

void pulseHealObject( Object *obj );
Bool canApplyWeaponSalvage(const Object* obj) const;
Bool canApplyArmorSalvage(const Object* obj) const;
Bool canApplyLevelUp(const Object* obj) const;

// Return if healing occured
Bool pulseHealObject( Object *obj );

ParticleSystemID m_radiusParticleSystemID;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// FILE: CrateApplyUpgrade.h ///////////////////////////////////////////////////////////////////////////
// Desc: apply salvage crate effetcs on upgrade
///////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/UpgradeModule.h"

// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
class Thing;
class Player;

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
class CrateApplyUpgradeModuleData : public UpgradeModuleData
{

public:
Bool m_applySalvageUpgrade;
Bool m_applyLevelUp;

CrateApplyUpgradeModuleData( void );

static void buildFieldParse(MultiIniFieldParse& p);

};

//-------------------------------------------------------------------------------------------------
/** The upgrade module */
//-------------------------------------------------------------------------------------------------
class CrateApplyUpgrade : public UpgradeModule
{

MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(CrateApplyUpgrade, "CrateApplyUpgrade" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA(CrateApplyUpgrade, CrateApplyUpgradeModuleData);

public:

CrateApplyUpgrade( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype defined by MemoryPoolObject

virtual Bool wouldUpgrade(const UpgradeMaskType& keyMask) const override;

protected:

virtual void upgradeImplementation( void ); ///< Here's the actual work of Upgrading
virtual Bool isSubObjectsUpgrade() { return false; }

Bool canApplyAnyCrateUpgade() const;

Bool canApplyWeaponUpgrade() const;
Bool canApplyArmorUpgrade() const;
Bool canApplyLevelUp() const;

};
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@
#include "GameLogic/Module/UnitProductionBonusUpgrade.h"
#include "GameLogic/Module/ExperienceScalarUpgrade.h"
#include "GameLogic/Module/MaxHealthUpgrade.h"
#include "GameLogic/Module/CrateApplyUpgrade.h"

// create includes
#include "GameLogic/Module/LockWeaponCreate.h"
Expand Down Expand Up @@ -552,6 +553,7 @@ void ModuleFactory::init( void )
addModule( WeaponBonusUpgrade );
addModule( ExperienceScalarUpgrade );
addModule( MaxHealthUpgrade );
addModule( CrateApplyUpgrade );

// create modules
addModule( LockWeaponCreate );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
#include "GameLogic/GameLogic.h"
#include "GameLogic/Object.h"
#include "GameLogic/PartitionManager.h"

#include "GameLogic/ExperienceTracker.h"
#include "Common/AudioEventRTS.h"
#include "Common/MiscAudio.h"

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -252,17 +254,20 @@ UpdateSleepTime AutoHealBehavior::update( void )
MemoryPoolObjectHolder hold( iter );
for( obj = iter->first(); obj; obj = iter->next() )
{
// do not heal if we are at max health already
// do not heal if we are at max health already, still apply if salvage/promotion is granted
BodyModuleInterface *body = obj->getBodyModule();
if( body->getHealth() < body->getMaxHealth() )
if( (body->getHealth() < body->getMaxHealth())
|| canApplyArmorSalvage( obj )
|| canApplyWeaponSalvage( obj )
|| canApplyLevelUp( obj ) )
{
if( obj->isAnyKindOf( d->m_kindOf ) && !obj->isAnyKindOf( d->m_forbiddenKindOf ) )
{
if( !d->m_skipSelfForHealing || obj != getObject() )
{
pulseHealObject( obj );
Bool healed = pulseHealObject( obj );

if( d->m_singleBurst && TheGameLogic->getDrawIconUI() )
if( healed && d->m_singleBurst && TheGameLogic->getDrawIconUI() )
{
if( TheAnim2DCollection && TheGlobalData->m_getHealedAnimationName.isEmpty() == FALSE )
{
Expand Down Expand Up @@ -290,22 +295,102 @@ UpdateSleepTime AutoHealBehavior::update( void )
}

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
void AutoHealBehavior::pulseHealObject( Object *obj )
Bool AutoHealBehavior::canApplyWeaponSalvage(const Object* obj) const
{
if (m_stopped)
return;
const AutoHealBehaviorModuleData* data = getAutoHealBehaviorModuleData();
return data->m_grantSalvageUpgrade && obj->isKindOf(KINDOF_WEAPON_SALVAGER) && !obj->testWeaponSetFlag(WEAPONSET_CRATEUPGRADE_TWO);
}

const AutoHealBehaviorModuleData *data = getAutoHealBehaviorModuleData();
Bool AutoHealBehavior::canApplyArmorSalvage(const Object* obj) const
{
const AutoHealBehaviorModuleData* data = getAutoHealBehaviorModuleData();
return data->m_grantSalvageUpgrade && obj->isKindOf(KINDOF_ARMOR_SALVAGER) && !obj->testArmorSetFlag(ARMORSET_CRATE_UPGRADE_TWO);
}

Bool AutoHealBehavior::canApplyLevelUp(const Object* obj) const
{
const AutoHealBehaviorModuleData* data = getAutoHealBehaviorModuleData();
return data->m_grantPromotion && obj->getExperienceTracker()->isTrainable() && obj->getExperienceTracker()->getVeterancyLevel() < LEVEL_HEROIC;
}

if ( data->m_radius == 0.0f )
obj->attemptHealing(data->m_healingAmount, getObject());
// ------------------------------------------------------------------------------------------------
static void applyWeaponSalvage(Object* unit)
{
if (unit->testWeaponSetFlag(WEAPONSET_CRATEUPGRADE_ONE))
{
unit->clearWeaponSetFlag(WEAPONSET_CRATEUPGRADE_ONE);
unit->setWeaponSetFlag(WEAPONSET_CRATEUPGRADE_TWO);
}
else
obj->attemptHealingFromSoleBenefactor( data->m_healingAmount, getObject(), data->m_healingDelay );
{
unit->setWeaponSetFlag(WEAPONSET_CRATEUPGRADE_ONE);
}
}

// ------------------------------------------------------------------------------------------------
static void applyArmorSalvage(Object* unit)
{
if (unit->testArmorSetFlag(ARMORSET_CRATE_UPGRADE_ONE))
{
unit->clearArmorSetFlag(ARMORSET_CRATE_UPGRADE_ONE);
unit->setArmorSetFlag(ARMORSET_CRATE_UPGRADE_TWO);
unit->clearAndSetModelConditionState(MODELCONDITION_ARMORSET_CRATEUPGRADE_ONE, MODELCONDITION_ARMORSET_CRATEUPGRADE_TWO);
}
else
{
unit->setArmorSetFlag(ARMORSET_CRATE_UPGRADE_ONE);
unit->setModelConditionState(MODELCONDITION_ARMORSET_CRATEUPGRADE_ONE);
}
}

// ------------------------------------------------------------------------------------------------
static void doLevelGain(Object* unit)
{
unit->getExperienceTracker()->gainExpForLevel(1);
}

static void doSalvageEffect(Object* unit) {
//Play the salvage installation crate pickup sound.
AudioEventRTS soundToPlay = TheAudio->getMiscAudio()->m_crateSalvage;
soundToPlay.setObjectID(unit->getID());
TheAudio->addAudioEvent(&soundToPlay);
}

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
Bool AutoHealBehavior::pulseHealObject(Object* obj)
{
if (m_stopped)
return false;

const AutoHealBehaviorModuleData* data = getAutoHealBehaviorModuleData();
bool needsHeal{ true };

if (data->m_grantSalvageUpgrade || data->m_grantPromotion) {
// Need to check for full HP
BodyModuleInterface* body = obj->getBodyModule();
needsHeal = (body != nullptr) && (body->getHealth() < body->getMaxHealth());
}
if (needsHeal) {
if (data->m_radius == 0.0f)
obj->attemptHealing(data->m_healingAmount, getObject());
else
obj->attemptHealingFromSoleBenefactor(data->m_healingAmount, getObject(), data->m_healingDelay);
}

if (canApplyArmorSalvage(obj)) {
applyArmorSalvage(obj);
doSalvageEffect(obj);
}
else if (canApplyWeaponSalvage(obj)) {
applyWeaponSalvage(obj);
doSalvageEffect(obj);
}
else if (canApplyLevelUp(obj)) {
doLevelGain(obj);
}

if( data->m_unitHealPulseParticleSystemTmpl )
if( needsHeal && data->m_unitHealPulseParticleSystemTmpl )
{
ParticleSystem *system = TheParticleSystemManager->createParticleSystem( data->m_unitHealPulseParticleSystemTmpl );
if( system )
Expand All @@ -315,6 +400,7 @@ void AutoHealBehavior::pulseHealObject( Object *obj )
}

m_soonestHealFrame = TheGameLogic->getFrame() + data->m_healingDelay;// In case onDamage tries to wake us up early
return needsHeal;
}

// ------------------------------------------------------------------------------------------------
Expand Down
Loading
Loading