218 lines
8.8 KiB
C++

/*
** Command & Conquer Generals(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: BuildAssistant.h /////////////////////////////////////////////////////////////////////////
// Author: Colin Day, February 2002
// Desc: Singleton class to encapsulate some of the more common functions or rules
// that apply to building structures and units
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __BUILDASSISTANT_H_
#define __BUILDASSISTANT_H_
// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
#include "Common/STLTypedefs.h"
#include "Lib/BaseType.h"
#include "Common/SubsystemInterface.h"
#include "GameLogic/Object.h"
// FORWARD DECLARATIONS ///////////////////////////////////////////////////////////////////////////
class ThingTemplate;
class Player;
class Object;
// ------------------------------------------------------------------------------------------------
// this enum is used for the construction percent of objects
enum { CONSTRUCTION_COMPLETE = -1 };
typedef void (*IterateFootprintFunc)( const Coord3D *samplePoint, void *userData );
// ------------------------------------------------------------------------------------------------
class ObjectSellInfo : public MemoryPoolObject
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( ObjectSellInfo, "ObjectSellInfo" )
public:
ObjectSellInfo( void );
// virtual destructor prototypes provided by memory pool object
ObjectID m_id; ///< id of object to sell
UnsignedInt m_sellFrame; ///< frame the sell occurred on
};
// ------------------------------------------------------------------------------------------------
typedef std::list<ObjectSellInfo *> ObjectSellList;
typedef ObjectSellList::iterator ObjectSellListIterator;
//-------------------------------------------------------------------------------------------------
/** Return codes for queries about being able to build */
//-------------------------------------------------------------------------------------------------
enum CanMakeType
{
CANMAKE_OK,
CANMAKE_NO_PREREQ,
CANMAKE_NO_MONEY,
CANMAKE_FACTORY_IS_DISABLED,
CANMAKE_QUEUE_FULL, // production bldg has full production queue
CANMAKE_PARKING_PLACES_FULL, // production bldg has finite slots for existing units
CANMAKE_MAXED_OUT_FOR_PLAYER // player has as many as they are allowed at once (eg, Black Lotus
};
//-------------------------------------------------------------------------------------------------
/** Return codes for queries about legal build locations */
//-------------------------------------------------------------------------------------------------
enum LegalBuildCode
{
LBC_OK = 0,
LBC_RESTRICTED_TERRAIN,
LBC_NOT_FLAT_ENOUGH,
LBC_OBJECTS_IN_THE_WAY,
LBC_NO_CLEAR_PATH,
LBC_SHROUD,
LBC_TOO_CLOSE_TO_SUPPLIES,
};
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
class BuildAssistant : public SubsystemInterface
{
public:
struct TileBuildInfo
{
Int tilesUsed;
Coord3D *positions;
};
enum LocalLegalToBuildOptions
{
TERRAIN_RESTRICTIONS = 0x00000001, ///< Check for basic terrain restrictions
CLEAR_PATH = 0x00000002, ///< Must be able to path find to location
NO_OBJECT_OVERLAP = 0X00000004, ///< Can't overlap enemy objects, or locally controled objects that can't move out of the way
USE_QUICK_PATHFIND = 0x00000008, ///< Use the quick pathfind method for CLEAR_PATH
SHROUD_REVEALED = 0x00000010, ///< Check to make sure the shroud is revealed
NO_ENEMY_OBJECT_OVERLAP=0x00000020, ///< Can't overlap enemy objects only.
};
public:
BuildAssistant( void );
virtual ~BuildAssistant( void );
virtual void init( void ); ///< for subsytem
virtual void reset( void ); ///< for subsytem
virtual void update( void ); ///< for subsytem
/// iterate the "footprint" area of a structure at the given "sample resolution"
void iterateFootprint( const ThingTemplate *build,
Real buildOrientation,
const Coord3D *worldPos,
Real sampleResolution,
IterateFootprintFunc func,
void *funcUserData );
/// create object from a build and put it in the world now
virtual Object *buildObjectNow( Object *constructorObject, const ThingTemplate *what,
const Coord3D *pos, Real angle, Player *owningPlayer );
/// using the "line placement" for objects (like walls etc) create that line of objects line
virtual void buildObjectLineNow( Object *constructorObject, const ThingTemplate *what,
const Coord3D *start, const Coord3D *end, Real angle,
Player *owningPlayer );
/// query if we can build at this location
virtual LegalBuildCode isLocationLegalToBuild( const Coord3D *worldPos,
const ThingTemplate *build,
Real angle, // angle to construct 'build' at
UnsignedInt options, // use LocationLegalToBuildOptions
Object *builderObject,
Player *player);
/// query if we can build at this location
virtual Bool isLocationClearOfObjects( const Coord3D *worldPos,
const ThingTemplate *build,
Real angle, // angle to construct 'build' a
Object *builderObject,
UnsignedInt options,
Player *thePlayer);
/// Adds bib highlighting for this location.
virtual void addBibs( const Coord3D *worldPos,
const ThingTemplate *build );
/// tiling wall object helper function, we can use this to "tile" walls when building
virtual TileBuildInfo *buildTiledLocations( const ThingTemplate *thingBeingTiled,
Real angle, // angle to consturct thing being tiled
const Coord3D *start, const Coord3D *end,
Real tilingSize, Int maxTiles,
Object *builderObject );
/// return the "scratch pad" array that can be used to create a line of build locations
virtual inline Coord3D *getBuildLocations( void ) { return m_buildPositions; }
/// is the template a line build object, like a wall
virtual Bool isLineBuildTemplate( const ThingTemplate *tTemplate );
/// are all the requirements for making this unit satisfied
virtual CanMakeType canMakeUnit( Object *builder, const ThingTemplate *whatToBuild ) const;
/// are all the requirements for making this unit (except available cash) are satisfied
virtual Bool isPossibleToMakeUnit( Object *builder, const ThingTemplate *whatToBuild ) const;
/// sell an object
virtual void sellObject( Object *obj );
void xferTheSellList(Xfer *xfer );
protected:
/// some objects will be "cleared" automatically when constructing
Bool isRemovableForConstruction( Object *obj );
/// clear the area of removable objects for construction
void clearRemovableForConstruction( const ThingTemplate *whatToBuild,
const Coord3D *pos, Real angle );
/// will move objects that can move out of the way.
/// will return false if there are objects that cannot be moved out of the way.
Bool moveObjectsForConstruction( const ThingTemplate *whatToBuild,
const Coord3D *pos, Real angle, Player *playerToBuild );
Coord3D *m_buildPositions; ///< array used to create a line of build locations (think walls)
Int m_buildPositionSize; ///< number of elements in the build position array
ObjectSellList m_sellList; ///< list of objects currently going through the "sell process"
}; // end BuildAssistant
// EXTERN /////////////////////////////////////////////////////////////////////////////////////////
extern BuildAssistant *TheBuildAssistant;
#endif // __BUILDASSISTANT_H_