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 @@ -198,6 +198,7 @@ static PoolSizeRec PoolSizes[] =
{ "BaikonurLaunchPower", 4, 4 },
{ "RadiusDecalUpdate", 16, 16 },
{ "RadiusDecalBehavior", 32, 32 },
{ "SpecialPowerDesignatorUpdate", 32, 32 },
{ "BattlePlanUpdate", 32, 32 },
{ "LifetimeUpdate", 32, 32 },
{ "LocomotorSetUpgrade", 512, 128 },
Expand Down
3 changes: 2 additions & 1 deletion GeneralsMD/Code/GameEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ set(GAMEENGINE_SRC
Include/GameLogic/Module/RadarUpgrade.h
Include/GameLogic/Module/RadiusDecalUpdate.h
Include/GameLogic/Module/RadiusDecalBehavior.h
Include/GameLogic/Module/SpecialPowerDesignatorUpdate.h
Include/GameLogic/Module/RailedTransportAIUpdate.h
Include/GameLogic/Module/RailedTransportContain.h
Include/GameLogic/Module/RailedTransportDockUpdate.h
Expand Down Expand Up @@ -1090,6 +1091,7 @@ set(GAMEENGINE_SRC
Source/GameLogic/Object/Update/RadarUpdate.cpp
Source/GameLogic/Object/Update/RadiusDecalUpdate.cpp
Source/GameLogic/Object/Update/RadiusDecalBehavior.cpp
Source/GameLogic/Object/Update/SpecialPowerDesignatorUpdate.cpp
Source/GameLogic/Object/Update/ResetSpecialPowerTimerWhileAliveUpdate.cpp
Source/GameLogic/Object/Update/ScatterShotUpdate.cpp
Source/GameLogic/Object/Update/SlavedUpdate.cpp
Expand Down Expand Up @@ -1220,7 +1222,6 @@ endif()
add_library(z_gameengine STATIC)

target_sources(z_gameengine PRIVATE ${GAMEENGINE_SRC})

target_include_directories(z_gameengine PUBLIC
Include
)
Expand Down
2 changes: 2 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/Common/KindOf.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ enum KindOfType CPP_11(: Int)
KINDOF_EXTRA15,
KINDOF_EXTRA16,

KINDOF_TARGET_DESIGNATOR,

KINDOF_COUNT, // total number of kindofs
KINDOF_FIRST = 0,
};
Expand Down
2 changes: 2 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/Common/SpecialPower.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class SpecialPowerTemplate : public Overridable
Real getViewObjectRange( void ) const { return getFO()->m_viewObjectRange; }
Real getRadiusCursorRadius() const { return getFO()->m_radiusCursorRadius; }
Bool isShortcutPower() const { return getFO()->m_shortcutPower; }
Bool isNeedsTargetDesignator() const { return getFO()->m_needsTargetDesignator; }
AcademyClassificationType getAcademyClassificationType() const { return m_academyClassificationType; }
EvaMessage getEvaDetectedOwn( void ) const { return getFO()->m_eva_detected_own; }
EvaMessage getEvaDetectedAlly( void ) const { return getFO()->m_eva_detected_ally; }
Expand Down Expand Up @@ -156,6 +157,7 @@ class SpecialPowerTemplate : public Overridable
Bool m_publicTimer; ///< display a countdown timer for this special power for all to see
Bool m_sharedNSync; ///< If true, this is a special that is shared between all of a player's command centers
Bool m_shortcutPower; ///< Is this shortcut power capable of being fired by the side panel?
Bool m_needsTargetDesignator; ///< Is this special power only allowed to hit designated areas
SpecialPowerType m_type_behavior; //< behave like a default special power, used by new ones only
EvaMessage m_eva_detected_own; //< eva event when constructed by self
EvaMessage m_eva_detected_ally; //< eva event when constructed by ally
Expand Down
10 changes: 10 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/GameClient/InGameUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,8 @@ friend class Drawable; // for selection/deselection transactions
virtual void DEBUG_addFloatingText(const AsciiString& text,const Coord3D * pos, Color color);
#endif

const SpecialPowerTemplate* getTargetDesignatorPower();

protected:
// snapshot methods
virtual void crc( Xfer *xfer );
Expand Down Expand Up @@ -687,6 +689,9 @@ friend class Drawable; // for selection/deselection transactions
void handleBuildPlacements( void ); ///< handle updating of placement icons based on mouse pos
void handleRadiusCursor(); ///< handle updating of "radius cursors" that follow the mouse pos

//void showDesignatorDecals(const SpecialPowerTemplate* powerTemplate);
//void hideDesignatorDecals(void);

void incrementSelectCount( void ) { ++m_selectCount; } ///< Increase by one the running total of "selected" drawables
void decrementSelectCount( void ) { --m_selectCount; } ///< Decrease by one the running total of "selected" drawables
virtual View *createView( void ) = 0; ///< Factory for Views
Expand Down Expand Up @@ -969,6 +974,11 @@ friend class Drawable; // for selection/deselection transactions

DrawableID m_soloNexusSelectedDrawableID; ///< The drawable of the nexus, if only one angry mob is selected, otherwise, null

// UI Decals
//Bool m_showDesignatorDecals;
const CommandButton* m_designatorCommand;


// ----------------------------------------------------------------------------------------------
// STATIC Protected Data -------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class RadiusDecalBehaviorModuleData : public UpdateModuleData
public:
UpgradeMuxData m_upgradeMuxData;
Bool m_initiallyActive;

Bool m_worksWhileContained;
RadiusDecalTemplate m_decalTemplate;
Real m_decalRadius;

Expand Down Expand Up @@ -83,6 +83,7 @@ class RadiusDecalBehavior : public UpdateModule, public UpgradeMux

protected:

void clearDecal(void);

virtual void upgradeImplementation()
{
Expand Down Expand Up @@ -115,11 +116,9 @@ class RadiusDecalBehavior : public UpdateModule, public UpgradeMux

virtual Bool isSubObjectsUpgrade() { return false; }

private:

RadiusDecal m_radiusDecal;

void clearDecal( void );
};

#endif // __RadiusDecalBehavior_H_
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
** 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: SpecialPowerDesignatorUpdate.h /////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

#ifndef __SpecialPowerDesignatorUpdate_H_
#define __SpecialPowerDesignatorUpdate_H_

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

// FORWARD REFERENCES /////////////////////////////////////////////////////////
class SpecialPowerTemplate;
class Thing;
class FXList;

//-------------------------------------------------------------------------------------------------
class SpecialPowerDesignatorUpdateModuleData : public RadiusDecalBehaviorModuleData
{
public:
SpecialPowerTemplate* m_specialPowerTemplate;
Real m_designatorRadius;
Bool m_alwaysShowDecal;
ObjectStatusTypes m_triggerStatusType;
UnsignedInt m_triggerStatusTime;
const FXList* m_triggerFX;

SpecialPowerDesignatorUpdateModuleData();

static void buildFieldParse(MultiIniFieldParse& p);
};

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
class SpecialPowerDesignatorUpdate : public RadiusDecalBehavior
{

MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( SpecialPowerDesignatorUpdate, "SpecialPowerDesignatorUpdate" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( SpecialPowerDesignatorUpdate, SpecialPowerDesignatorUpdateModuleData )

public:

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

// UpdateModuleInterface
virtual UpdateSleepTime update();

Real getDesignatorRadius() { return getSpecialPowerDesignatorUpdateModuleData()->m_designatorRadius; }

Bool isValidDesignatorForSpecialPower(const SpecialPowerTemplate* templ);

void triggerSpecialPower();

protected:

private:

UnsignedInt m_statusClearFrame;

};

#endif // __SpecialPowerDesignatorUpdate_H_

Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ class SpecialPowerModule : public BehaviorModule,
void resolveSpecialPower( void );
void aboutToDoSpecialPower( const Coord3D *location );

void handleTargetDesignator(const Coord3D* location);

UnsignedInt m_availableOnFrame; ///< on this frame, this special power is available
Int m_pausedCount; ///< Reference count of sources pausing me
UnsignedInt m_pausedOnFrame;
Expand Down
60 changes: 60 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/Common/RTS/ActionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include "GameLogic/Module/SupplyWarehouseDockUpdate.h"
#include "GameLogic/Module/SpecialPowerModule.h"
#include "GameLogic/Module/SpecialAbilityUpdate.h"
#include "GameLogic/Module/SpecialPowerDesignatorUpdate.h"
#include "GameLogic/Weapon.h"

#include "GameLogic/ExperienceTracker.h"//LORENZEN
Expand Down Expand Up @@ -1567,6 +1568,65 @@ Bool ActionManager::canDoSpecialPowerAtLocation( const Object *obj, const Coord3
}
}

// Check target designator

if (spTemplate->isNeedsTargetDesignator()) {
bool isDesignatorInRange = false;
static NameKeyType key_SpecialPowerDesignatorUpdate = NAMEKEY("SpecialPowerDesignatorUpdate");

//Iterate over all object and find this module!

//PartitionFilterRelationship relationship( obj, PartitionFilterRelationship::ALLOW_ALLIES );
PartitionFilterSamePlayer filterPlayer(obj->getControllingPlayer());
PartitionFilterSameMapStatus filterMapStatus(obj);
PartitionFilterAlive filterAlive;
PartitionFilterAcceptByKindOf filterKindOf(MAKE_KINDOF_MASK(KINDOF_TARGET_DESIGNATOR), KINDOFMASK_NONE);
PartitionFilter* filters[] = { &filterPlayer, &filterAlive, &filterMapStatus, &filterKindOf, NULL };
Real MAX_SCAN_RANGE = 5000.0f; //TODO: GlobalData?
// scan objects in our region
ObjectIterator* iter = ThePartitionManager->iterateObjectsInRange(loc, MAX_SCAN_RANGE, FROM_CENTER_2D, filters);
Object* obj2;
MemoryPoolObjectHolder hold(iter);
for (obj2 = iter->first(); obj2; obj2 = iter->next()) {

SpecialPowerDesignatorUpdate* update = (SpecialPowerDesignatorUpdate*)obj2->findUpdateModule(key_SpecialPowerDesignatorUpdate);
if (update) {
if (update->isValidDesignatorForSpecialPower(spTemplate)) {

Real distSqr = ThePartitionManager->getDistanceSquared(obj2, loc, FROM_CENTER_2D);
Real radius = update->getDesignatorRadius();
if (distSqr <= (radius*radius)) {
isDesignatorInRange = true;
break;
}
}
}
}
if (!isDesignatorInRange)
return FALSE;
}

//static NameKeyType key_SpecialPowerDesignatorUpdate = NAMEKEY("SpecialPowerDesignatorUpdate");

//PartitionFilterSamePlayer filterPlayer(ThePlayerList->getLocalPlayer());
//PartitionFilterAlive filterAlive;
//PartitionFilterAcceptByKindOf filterKindOf(MAKE_KINDOF_MASK(KINDOF_TARGET_DESIGNATOR), KINDOFMASK_NONE);
//PartitionFilter* filters[] = { &filterPlayer, &filterAlive, &filterKindOf, NULL };
//// scan objects on entire map
//ObjectIterator* iter = ThePartitionManager->iterateAllObjects(filters);
//Object* obj;
//MemoryPoolObjectHolder hold(iter);
//for (obj = iter->first(); obj; obj = iter->next()) {

// SpecialPowerDesignatorUpdate* update = (SpecialPowerDesignatorUpdate*)obj->findUpdateModule(key_SpecialPowerDesignatorUpdate);
// if (update) {
// if (update->isValidDesignatorForSpecialPower(powerTemplate)) {
// update->setActive(true);
// }
// }
//}


// First check terrain type, if it is cared about. Don't return a true, since there are more checks.
switch(behaviorType)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ void SpecialPowerStore::parseSpecialPowerDefinition( INI *ini )
{ "EvaReadyOwn", INI::parseEvaNameIndexList, TheEvaMessageNames, offsetof(SpecialPowerTemplate, m_eva_ready_own) },
{ "EvaReadyAlly", INI::parseEvaNameIndexList, TheEvaMessageNames, offsetof(SpecialPowerTemplate, m_eva_ready_ally) },
{ "EvaReadyEnemy", INI::parseEvaNameIndexList, TheEvaMessageNames, offsetof(SpecialPowerTemplate, m_eva_ready_enemy) },
{ "NeedsTargetDesignator", INI::parseBool, nullptr, offsetof(SpecialPowerTemplate, m_needsTargetDesignator) },
{ "Cost", INI::parseInt, NULL, offsetof(SpecialPowerTemplate, m_cost) },
{ nullptr, nullptr, nullptr, 0 }

Expand Down
2 changes: 2 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/Common/System/KindOf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ const char* const KindOfMaskType::s_bitNameList[] =
"EXTRA15",
"EXTRA16",

"TARGET_DESIGNATOR",

nullptr
};
static_assert(ARRAY_SIZE(KindOfMaskType::s_bitNameList) == KindOfMaskType::NumBits + 1, "Incorrect array size");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@
#include "GameLogic/Module/LifetimeUpdate.h"
#include "GameLogic/Module/RadiusDecalUpdate.h"
#include "GameLogic/Module/RadiusDecalBehavior.h"
#include "GameLogic/Module/SpecialPowerDesignatorUpdate.h"
#include "GameLogic/Module/AutoDepositUpdate.h"
#include "GameLogic/Module/MissileAIUpdate.h"
#include "GameLogic/Module/NeutronMissileUpdate.h"
Expand Down Expand Up @@ -436,6 +437,7 @@ void ModuleFactory::init( void )
addModule( LifetimeUpdate );
addModule( RadiusDecalUpdate );
addModule( RadiusDecalBehavior );
addModule( SpecialPowerDesignatorUpdate );
addModule( EMPUpdate );
addModule( LeafletDropBehavior );
addModule( AutoDepositUpdate );
Expand Down
28 changes: 28 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
#include "GameLogic/Module/ContainModule.h"
#include "GameLogic/Module/ProductionUpdate.h"
#include "GameLogic/Module/SpecialPowerModule.h"
#include "GameLogic/Module/SpecialPowerDesignatorUpdate.h"
#include "GameLogic/Module/StealthUpdate.h"
#include "GameLogic/Module/SupplyWarehouseDockUpdate.h"
#include "GameLogic/Module/MobMemberSlavedUpdate.h"//ML
Expand Down Expand Up @@ -1101,6 +1102,9 @@ InGameUI::InGameUI()

m_tooltipsDisabledUntil = 0;

//m_showDesignatorDecals = FALSE;
m_designatorCommand = NULL;

// init hint lists
for( i = 0; i < MAX_MOVE_HINTS; i++ )
{
Expand Down Expand Up @@ -3245,6 +3249,18 @@ void InGameUI::setGUICommand( const CommandButton *command )
// set the command
m_pendingGUICommand = command;

// Target designator checks
if (m_designatorCommand && m_designatorCommand != m_pendingGUICommand) {
m_designatorCommand = NULL;
}

if (command && BitIsSet(command->getOptions(), COMMAND_OPTION_NEED_TARGET)) {
const SpecialPowerTemplate* sp = command->getSpecialPowerTemplate();
if (sp != nullptr && sp->isNeedsTargetDesignator()) {
m_designatorCommand = command;
}
}

// set the mouse cursor for commands that need a targeting or to normal with no command
if( command && BitIsSet( command->getOptions(), COMMAND_OPTION_NEED_TARGET ) && !command->isContextCommand() )
{
Expand Down Expand Up @@ -6429,3 +6445,15 @@ void InGameUI::drawPlayerInfoList()
drawY += lineH;
}
}

// -------------
// -------------
const SpecialPowerTemplate* InGameUI::getTargetDesignatorPower()
{
if (m_designatorCommand != nullptr)
return m_designatorCommand->getSpecialPowerTemplate();

return nullptr;
}
// -------------
// -------------
Loading
Loading