793 lines
33 KiB
C++
793 lines
33 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: Player.h ////////////////////////////////////////////////////////////
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Westwood Studios Pacific.
|
|
//
|
|
// Confidential Information
|
|
// Copyright (C) 2001 - All Rights Reserved
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Project: RTS3
|
|
//
|
|
// File name: Player.h
|
|
//
|
|
// Created: Steven Johnson, October 2001
|
|
//
|
|
// Desc: @todo
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
#ifndef _PLAYER_H_
|
|
#define _PLAYER_H_
|
|
|
|
#include "Common/Debug.h"
|
|
#include "Common/Energy.h"
|
|
#include "Common/GameType.h"
|
|
#include "Common/Handicap.h"
|
|
#include "Common/KindOf.h"
|
|
#include "Common/MissionStats.h"
|
|
#include "Common/Money.h"
|
|
#include "Common/Science.h"
|
|
#include "Common/UnicodeString.h"
|
|
#include "Common/NameKeyGenerator.h"
|
|
#include "Common/Thing.h"
|
|
#include "Common/STLTypedefs.h"
|
|
#include "Common/ScoreKeeper.h"
|
|
#include "Common/Team.h"
|
|
#include "Common/STLTypedefs.h"
|
|
|
|
// ----------------------------------------------------------------------------------------------
|
|
|
|
class BuildListInfo;
|
|
class PolygonTrigger;
|
|
class ThingTemplate;
|
|
class AIPlayer;
|
|
class AIGroup;
|
|
class GameMessage;
|
|
class ResourceGatheringManager;
|
|
class PlayerTemplate;
|
|
class Squad;
|
|
class Team;
|
|
class TeamPrototype;
|
|
class TeamRelationMap;
|
|
class TunnelTracker;
|
|
class Upgrade;
|
|
class UpgradeTemplate;
|
|
class SpecialPowerModule;
|
|
|
|
class BattlePlanBonuses;
|
|
|
|
enum BattlePlanStatus;
|
|
enum UpgradeStatusType;
|
|
enum CommandSourceType;
|
|
|
|
enum ScienceAvailabilityType
|
|
{
|
|
SCIENCE_AVAILABILITY_INVALID = -1,
|
|
|
|
SCIENCE_AVAILABLE,
|
|
SCIENCE_DISABLED,
|
|
SCIENCE_HIDDEN,
|
|
|
|
SCIENCE_AVAILABILITY_COUNT,
|
|
};
|
|
|
|
#ifdef DEFINE_SCIENCE_AVAILABILITY_NAMES
|
|
static const char *ScienceAvailabilityNames[] =
|
|
{
|
|
"Available",
|
|
"Disabled",
|
|
"Hidden",
|
|
NULL
|
|
};
|
|
#endif // end DEFINE_SCIENCE_AVAILABILITY_NAMES
|
|
|
|
static const Int NUM_HOTKEY_SQUADS = 10;
|
|
|
|
enum { NO_HOTKEY_SQUAD = -1 };
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
typedef Int PlayerIndex;
|
|
#define PLAYER_INDEX_INVALID -1
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
class KindOfPercentProductionChange : public MemoryPoolObject
|
|
{
|
|
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(KindOfPercentProductionChange, "KindOfPercentProductionChange")
|
|
public:
|
|
KindOfMaskType m_kindOf;
|
|
Real m_percent;
|
|
UnsignedInt m_ref;
|
|
};
|
|
EMPTY_DTOR(KindOfPercentProductionChange)
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
struct SpecialPowerReadyTimerType
|
|
{
|
|
SpecialPowerReadyTimerType()
|
|
{
|
|
clear();
|
|
}
|
|
void clear( void )
|
|
{
|
|
m_readyFrame = 0xffffffff;
|
|
m_templateID = INVALID_ID;
|
|
};
|
|
|
|
UnsignedInt m_templateID; ///< The ID of the specialpower template associated with this timer... no dupes allowed
|
|
UnsignedInt m_readyFrame; ///< on what game frame will this special power be ready?
|
|
};
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
typedef std::hash_map< PlayerIndex, Relationship, std::hash<PlayerIndex>, std::equal_to<PlayerIndex> > PlayerRelationMapType;
|
|
class PlayerRelationMap : public MemoryPoolObject,
|
|
public Snapshot
|
|
{
|
|
|
|
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( PlayerRelationMap, "PlayerRelationMapPool" )
|
|
|
|
public:
|
|
|
|
PlayerRelationMap( void );
|
|
// virtual destructor provided by memory pool object
|
|
|
|
/** @todo I'm jsut wrappign this up in a nice snapshot object, we really should isolate
|
|
* m_map from public access and make access methods for our operations */
|
|
PlayerRelationMapType m_map;
|
|
|
|
protected:
|
|
|
|
virtual void crc( Xfer *xfer );
|
|
virtual void xfer( Xfer *xfer );
|
|
virtual void loadPostProcess( void );
|
|
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------------------------
|
|
/**
|
|
A "Player" as an entity that contains the persistent info of the Player, as well as containing
|
|
transient mission data.
|
|
|
|
Some of the Player's attributes persist between missions, whereas others are "transient" and only
|
|
have meaning in a mission, wherein they change a lot (current tech tree state, current buildings
|
|
built, units trained, money, etc). (For clarity of nomenclature, we'll refer to all "persistent"
|
|
vs "non-persistent" attributes, since "transient" has an unclear duration.)
|
|
|
|
A "Player" consists of an entity controlling a single set of units in a mission.
|
|
A Player may be human or computer controlled.
|
|
|
|
All Players have a (transient) "Player Index" associated which allows us to do some shorthand for
|
|
representing Players in some cases (mainly in bitfields). This is always a 0-based
|
|
number (-1 is used as an illegal index). Note that a logical conclusion of this
|
|
is that it makes it desirable to limit the maximum number of simultaneous Players
|
|
to 32, but that seems quite reasonable.
|
|
|
|
All persistent data associated with the Player will be saved to local storage and/or
|
|
synchronized with one of our servers for online play.
|
|
|
|
Note, simple accessor methods are omitted for brevity... for now, you may infer
|
|
them from the data structures.
|
|
|
|
Note also that the class (and the relevant subclasses) are almost certainly incomplete;
|
|
a short perusal of the RA2 equivalent class(es) have waaay more tweaky data fields,
|
|
some of which will probably be necessary (in some form, at some point), some of
|
|
which won't ever be necessary. Rather than trying to guess at all of them here,
|
|
we're limiting the initial setup to be the almost-certainly-necessary, filling in
|
|
the extra things as needed. (Note that most of these will be non-persistent!)
|
|
*/
|
|
class Player : public Snapshot
|
|
{
|
|
public:
|
|
|
|
Player( Int playerIndex );
|
|
virtual ~Player();
|
|
|
|
void update(); ///< player update opportunity
|
|
|
|
void newMap(); ///< player after map loaded opportunity
|
|
|
|
void init(const PlayerTemplate* pt);
|
|
void initFromDict(const Dict* d);
|
|
void setDefaultTeam(void);
|
|
|
|
inline UnicodeString getPlayerDisplayName() { return m_playerDisplayName; }
|
|
inline NameKeyType getPlayerNameKey() const { return m_playerNameKey; }
|
|
|
|
inline AsciiString getSide() const { return m_side; }
|
|
|
|
inline const PlayerTemplate* getPlayerTemplate() const { return m_playerTemplate; }
|
|
/// return the Player's Handicap sub-object
|
|
inline const Handicap *getHandicap() const { return &m_handicap; }
|
|
inline Handicap *getHandicap() { return &m_handicap; }
|
|
|
|
/// return the Player's Money sub-object
|
|
inline Money *getMoney() { return &m_money; }
|
|
inline const Money *getMoney() const { return &m_money; }
|
|
|
|
UnsignedInt getSupplyBoxValue();///< Many things can affect the alue of a crate, but at heart it is a GlobalData ratio.
|
|
|
|
inline Energy *getEnergy() { return &m_energy; }
|
|
inline const Energy *getEnergy() const { return &m_energy; }
|
|
|
|
// adds a power bonus to this player because of energy upgrade at his power plants
|
|
inline void addPowerBonus(Object *obj) { m_energy.addPowerBonus(obj); }
|
|
inline void removePowerBonus(Object *obj) { m_energy.removePowerBonus(obj); }
|
|
|
|
inline ResourceGatheringManager *getResourceGatheringManager(){ return m_resourceGatheringManager; }
|
|
inline TunnelTracker* getTunnelSystem(){ return m_tunnelSystem; }
|
|
|
|
inline Color getPlayerColor() const { return m_color; }
|
|
inline Color getPlayerNightColor() const { return m_nightColor;}
|
|
/// return the type of controller
|
|
inline PlayerType getPlayerType() const { return m_playerType; }
|
|
void setPlayerType(PlayerType t, Bool skirmish);
|
|
|
|
inline PlayerIndex getPlayerIndex() const { return m_playerIndex; }
|
|
|
|
/// return a bitmask that is unique to this player.
|
|
inline PlayerMaskType getPlayerMask() const { return 1 << m_playerIndex; }
|
|
|
|
/// a convenience function to test the ThingTemplate against the players canBuild flags
|
|
/// called by canBuild
|
|
Bool allowedToBuild(const ThingTemplate *tmplate) const;
|
|
|
|
/// true if we have the prereqs for this item
|
|
Bool canBuild(const ThingTemplate *tmplate) const;
|
|
|
|
// Can we afford to build?
|
|
Bool canAffordBuild( const ThingTemplate *whatToBuild ) const;
|
|
|
|
/// Difficulty level for this player.
|
|
GameDifficulty getPlayerDifficulty(void) const;
|
|
|
|
/** return the player's command center. (must be one of his "normal" ones,
|
|
not a captured one.)
|
|
if he has none, return null.
|
|
if he has multiple, return one arbitrarily. */
|
|
Object* findNaturalCommandCenter();
|
|
|
|
/// return t if the player has the given science, either intrinsically, via specialization, or via capture.
|
|
Bool hasScience(ScienceType t) const;
|
|
Bool isScienceDisabled( ScienceType t ) const; ///< Can't purchase this science because of script reasons.
|
|
Bool isScienceHidden( ScienceType t ) const; ///< This science is effectively hidden due to script reasons.
|
|
|
|
//Allows scripts to make specific sciences available, hidden, or disabled.
|
|
void setScienceAvailability( ScienceType science, ScienceAvailabilityType type );
|
|
|
|
ScienceAvailabilityType getScienceAvailabilityTypeFromString( const AsciiString& name );
|
|
|
|
/// return t iff the player has all sciences that are prereqs for knowing the given science
|
|
Bool hasPrereqsForScience(ScienceType t) const;
|
|
|
|
Bool hasUpgradeComplete( const UpgradeTemplate *upgradeTemplate ); ///< does player have totally done and produced upgrade
|
|
Bool hasUpgradeComplete( Int64 testMask ); ///< does player have totally done and produced upgrade
|
|
Int64 getCompletedUpgradeMask() const { return m_upgradesCompleted; } ///< get list of upgrades that are completed
|
|
Bool hasUpgradeInProduction( const UpgradeTemplate *upgradeTemplate ); ///< does player have this upgrade in progress right now
|
|
Upgrade *addUpgrade( const UpgradeTemplate *upgradeTemplate,
|
|
UpgradeStatusType status ); ///< add upgrade, or update existing upgrade status
|
|
void removeUpgrade( const UpgradeTemplate *upgradeTemplate ); ///< remove thsi upgrade from us
|
|
|
|
/** find upgrade, NOTE, the upgrade may *NOT* be "complete" and therefore "active", it could be in production
|
|
This function is for actually retrieving the Upgrade. To test existance, use the fast bit testers hasUpgradeX()
|
|
*/
|
|
Upgrade *findUpgrade( const UpgradeTemplate *upgradeTemplate );
|
|
|
|
void onUpgradeCompleted( const UpgradeTemplate *upgradeTemplate ); ///< An upgrade just finished, do things like tell all objects to recheck UpgradeModules
|
|
void onUpgradeRemoved(){} ///< An upgrade just got removed, this doesn't do anything now.
|
|
|
|
#if defined(_DEBUG) || defined(_INTERNAL)
|
|
/// Prereq disabling cheat key
|
|
void toggleIgnorePrereqs(){ m_DEMO_ignorePrereqs = !m_DEMO_ignorePrereqs; }
|
|
Bool ignoresPrereqs() const { return m_DEMO_ignorePrereqs; }
|
|
|
|
/// No cost building cheat key
|
|
void toggleFreeBuild(){ m_DEMO_freeBuild = !m_DEMO_freeBuild; }
|
|
Bool buildsForFree() const { return m_DEMO_freeBuild; }
|
|
|
|
/// No time building cheat key
|
|
void toggleInstantBuild(){ m_DEMO_instantBuild = !m_DEMO_instantBuild; }
|
|
Bool buildsInstantly() const { return m_DEMO_instantBuild; }
|
|
#endif
|
|
|
|
///< Power just changed at all. Didn't make two functions so you can't forget to undo something you didin one of them.
|
|
///< @todo Can't do edge trigger until after demo; make things check for power on creation
|
|
void onPowerBrownOutChange( Bool brownOut );
|
|
|
|
|
|
///< one of my command centers just fired a special power, let us reset timers for all command centers.
|
|
void resetOrStartSpecialPowerReadyFrame( const SpecialPowerTemplate *temp );
|
|
///< my new command center wants to init his timers to the status quo
|
|
UnsignedInt getOrStartSpecialPowerReadyFrame( const SpecialPowerTemplate *temp);
|
|
void expressSpecialPowerReadyFrame( const SpecialPowerTemplate *temp, UnsignedInt frame );
|
|
void addNewSharedSpecialPowerTimer( const SpecialPowerTemplate *temp, UnsignedInt frame );
|
|
|
|
|
|
void addRadar( Bool disableProof );///< One more producer of Radar exists
|
|
void removeRadar( Bool disableProof );///< One less thing produces radar
|
|
void disableRadar(); ///< No matter how many radar producers I have, I do not have radar
|
|
void enableRadar(); ///< remove the restriction imposed by disableRadar
|
|
Bool hasRadar() const;///< A positive number of radar producers, plus my radar is not disabled
|
|
Bool okToPlayRadarEdgeSound();///< just like it "sounds"
|
|
//Battle plans effect the players abilities... so may as well add it here. Also
|
|
//it's possible for multiple strategy centers to have the same plan, so we need
|
|
//to keep track of that like radar. Keep in mind multiple strategy centers with
|
|
//same plan do not stack, but different strategy centers with different plans do.
|
|
void changeBattlePlan( BattlePlanStatus plan, Int delta, BattlePlanBonuses *bonus );
|
|
Int getNumBattlePlansActive() const { return m_bombardBattlePlans + m_holdTheLineBattlePlans + m_searchAndDestroyBattlePlans; }
|
|
Int getBattlePlansActiveSpecific( BattlePlanStatus plan ) const;
|
|
void applyBattlePlanBonusesForObject( Object *obj ) const; //New object or converted object gaining our current battle plan bonuses.
|
|
void removeBattlePlanBonusesForObject( Object *obj ) const; //Object left team
|
|
void applyBattlePlanBonusesForPlayerObjects( const BattlePlanBonuses *bonus ); //Battle plan bonuses changing, so apply to all of our objects!
|
|
Bool doesObjectQualifyForBattlePlan( Object *obj ) const;
|
|
|
|
// If apply is false, then we are repealing already granted bonuses.
|
|
// Note: Should only be called by Object.
|
|
void friend_applyDifficultyBonusesForObject(Object* obj, Bool apply) const;
|
|
|
|
/// Decrement the ref counter on the typeof production list node
|
|
void removeKindOfProductionCostChange(KindOfMaskType kindOf, Real percent);
|
|
/// add type of production cost change (Used for upgrades)
|
|
void addKindOfProductionCostChange( KindOfMaskType kindOf, Real percent);
|
|
/// Returns production cost change based on typeof (Used for upgrades)
|
|
Real getProductionCostChangeBasedOnKindOf( KindOfMaskType kindOf ) const;
|
|
|
|
/** Return bonus or penalty for construction of this thing.
|
|
*/
|
|
Real getProductionCostChangePercent( AsciiString buildTemplateName ) const;
|
|
|
|
/** Return bonus or penalty for construction of this thing.
|
|
*/
|
|
Real getProductionTimeChangePercent( AsciiString buildTemplateName ) const;
|
|
|
|
/** Return starting veterancy level of a newly built thing of this type
|
|
*/
|
|
VeterancyLevel getProductionVeterancyLevel( AsciiString buildTemplateName ) const;
|
|
|
|
// Friend function for the script engine's usage.
|
|
void friend_setSkillset(Int skillSet);
|
|
|
|
/**
|
|
the given object has just become (or just ceased to be) a member of one of our teams (or subteams)
|
|
*/
|
|
void becomingTeamMember(Object *obj, Bool yes);
|
|
|
|
/**
|
|
this is called when the player becomes the local player (yes==true)
|
|
or ceases to be the local player (yes==false). you can't stop this
|
|
from happening; you can only react to it.
|
|
*/
|
|
void becomingLocalPlayer(Bool yes);
|
|
|
|
/// Is this player the local player?
|
|
Bool isLocalPlayer() const;
|
|
|
|
/// this player should be listed in the score screen.
|
|
void setListInScoreScreen(Bool listInScoreScreen);
|
|
|
|
/// return TRUE if this player should be listed in the score screen.
|
|
Bool getListInScoreScreen();
|
|
|
|
/// A unit was just created and is ready to control
|
|
void onUnitCreated( Object *factory, Object *unit );
|
|
|
|
/// A team is about to be destroyed.
|
|
void preTeamDestroy( const Team *team );
|
|
|
|
/// Is the nearest supply source safe?
|
|
Bool isSupplySourceSafe( Int minSupplies );
|
|
|
|
/// Is a supply source attacked?
|
|
Bool isSupplySourceAttacked( void );
|
|
|
|
/// Set delay between team production.
|
|
void setTeamDelaySeconds(Int delay);
|
|
|
|
/// Have the team guard a supply center.
|
|
void guardSupplyCenter( Team *team, Int minSupplies );
|
|
|
|
virtual void computeSuperweaponTarget(const SpecialPowerTemplate *power, Coord3D *pos, Int playerNdx, Real weaponRadius); ///< Calculates best pos for weapon given radius.
|
|
|
|
/// Get the enemy an ai player is currently focused on. NOTE - Can be NULL.
|
|
Player *getCurrentEnemy( void );
|
|
|
|
/// Is this player a skirmish ai player?
|
|
Bool isSkirmishAIPlayer( void );
|
|
|
|
/// Have the ai check for bridges.
|
|
virtual Bool checkBridges(Object *unit, Waypoint *way);
|
|
|
|
/// Get the center of the ai's base.
|
|
virtual Bool getAiBaseCenter(Coord3D *pos);
|
|
|
|
/// Have the ai check for bridges.
|
|
virtual void repairStructure(ObjectID structureID);
|
|
|
|
/// a structuer was just created, but is under construction
|
|
void onStructureCreated( Object *builder, Object *structure );
|
|
|
|
/// a structure that was under construction has become completed
|
|
void onStructureConstructionComplete( Object *builder, Object *structure, Bool isRebuild );
|
|
|
|
/// a structure that was created has been pre-emptively removed and shouldn't be counted in the score.
|
|
void onStructureUndone(Object *structure);
|
|
|
|
/**
|
|
a convenience routine to count the number of owned objects that match a set of ThingTemplates.
|
|
You input the count and an array of ThingTemplate*, and provide an array of Int of the same
|
|
size. It fills in the array to the correct counts. This is handy because we must traverse
|
|
the player's list-of-objects only once.
|
|
*/
|
|
void countObjectsByThingTemplate(Int numTmplates, const ThingTemplate* const * things, Bool ignoreDead, Int *counts, Bool ignoreUnderConstruction = TRUE ) const;
|
|
|
|
/**
|
|
simply returns the number of buildings owned by this player
|
|
*/
|
|
Int countBuildings(void);
|
|
|
|
/**
|
|
simply returns the number of objects owned by this player with a specific KindOfMaskType
|
|
*/
|
|
Int countObjects(KindOfMaskType setMask, KindOfMaskType clearMask);
|
|
|
|
/// Returns the closest of a given type to the given object
|
|
Object *findClosestByKindOf( Object *queryObject, KindOfMaskType setMask, KindOfMaskType clearMask );
|
|
|
|
/**
|
|
a convenience routine to quickly check if any buildings are owned.
|
|
*/
|
|
Bool hasAnyBuildings(void) const;
|
|
|
|
/**
|
|
a convenience routine to quickly check if any buildings with a specific KindOfType flag are owned.
|
|
*/
|
|
Bool hasAnyBuildings(KindOfMaskType kindOf) const;
|
|
|
|
/**
|
|
a convenience routine to quickly check if any units are owned.
|
|
*/
|
|
Bool hasAnyUnits(void) const;
|
|
|
|
/**
|
|
a convenience routine to quickly check if any objects are owned.
|
|
*/
|
|
Bool hasAnyObjects(void) const;
|
|
|
|
/**
|
|
a convenience routine to quickly check if any buildfacilities are owned.
|
|
*/
|
|
Bool hasAnyBuildFacility(void) const;
|
|
|
|
/**
|
|
a convenience routine to quickly update the state flags on all teams.
|
|
*/
|
|
void updateTeamStates(void);
|
|
|
|
/**
|
|
This player will heal everything owned by it
|
|
*/
|
|
void healAllObjects();
|
|
|
|
/**
|
|
* Iterate all objects that this player has
|
|
*/
|
|
void iterateObjects( ObjectIterateFunc func, void *userData );
|
|
|
|
/**
|
|
return this player's "default" team.
|
|
*/
|
|
Team *getDefaultTeam() { DEBUG_ASSERTCRASH(m_defaultTeam!=NULL,("default team is null")); return m_defaultTeam; }
|
|
const Team *getDefaultTeam() const { DEBUG_ASSERTCRASH(m_defaultTeam!=NULL,("default team is null")); return m_defaultTeam; }
|
|
|
|
void setBuildList(BuildListInfo *pBuildList); ///< sets the build list.
|
|
BuildListInfo *getBuildList( void ) { return m_pBuildList; } ///< returns the build list. (build list might be modified by the solo AI)
|
|
void addToBuildList(Object *obj); ///< Adds this to the build list. Used for factories placed instead of in build list.
|
|
void addToPriorityBuildList(AsciiString templateName, Coord3D *pos, Real angle); ///< Adds this to the build list. Used for factories placed instead of in build list.
|
|
|
|
/// get the relationship between this->that.
|
|
Relationship getRelationship(const Team *that) const;
|
|
|
|
/// set the relationship between this->that. (note that this doesn't affect the that->this relationship.)
|
|
void setPlayerRelationship(const Player *that, Relationship r);
|
|
Bool removePlayerRelationship(const Player *that);
|
|
void setTeamRelationship(const Team *that, Relationship r);
|
|
Bool removeTeamRelationship(const Team *that);
|
|
|
|
void addTeamToList(TeamPrototype* team);
|
|
void removeTeamFromList(TeamPrototype* team);
|
|
|
|
typedef std::list<TeamPrototype*> PlayerTeamList;
|
|
inline const PlayerTeamList* getPlayerTeams() const { return &m_playerTeamPrototypes; }
|
|
|
|
inline Int getMpStartIndex(void) {return m_mpStartIndex;}
|
|
|
|
/// Set that all units should begin hunting.
|
|
void setUnitsShouldHunt(Bool unitsShouldHunt, CommandSourceType source);
|
|
Bool getUnitsShouldHunt() const { return m_unitsShouldHunt; }
|
|
|
|
/// All of our units are new spied upon; they sight for the given enemy
|
|
void setUnitsVisionSpied( Bool setting, PlayerIndex byWhom );
|
|
|
|
/// This will be asked by units when they look to get extra people to sight for
|
|
PlayerMaskType getVisionSpiedMask() const;
|
|
|
|
/// Destroy all of the teams for this player, causing him to DIE.
|
|
void killPlayer(void);
|
|
|
|
/// Enabled/Disable all objects of type templateTypeToAffect
|
|
void setObjectsEnabled(AsciiString templateTypeToAffect, Bool enable);
|
|
|
|
/// Build an instance of a specific team. Gets passed to aiPlayer.
|
|
void buildSpecificTeam(TeamPrototype *teamProto);
|
|
|
|
/// Build an instance of a specific building. Gets passed to aiPlayer.
|
|
void buildSpecificBuilding(const AsciiString &thingName);
|
|
|
|
/// Build a building near a supply dump with at least cash. Gets passed to aiPlayer.
|
|
void buildBySupplies(Int minimumCash, const AsciiString &thingName);
|
|
|
|
/// Build an upgrade. Gets passed to aiPlayer.
|
|
void buildUpgrade(const AsciiString &upgrade);
|
|
|
|
/// Build base defense on front or flank of base. Gets passed to aiPlayer.
|
|
void buildBaseDefense(Bool flank);
|
|
|
|
/// Build structure type on front or flank of base. Gets passed to aiPlayer.
|
|
void buildBaseDefenseStructure(const AsciiString &thingName, Bool flank);
|
|
|
|
/// Recruits an instance of a specific team. Gets passed to aiPlayer.
|
|
void recruitSpecificTeam(TeamPrototype *teamProto, Real recruitRadius);
|
|
|
|
/// Enable/Disable the construction of units
|
|
Bool getCanBuildUnits(void) { return m_canBuildUnits; }
|
|
void setCanBuildUnits(Bool canProduce) { m_canBuildUnits = canProduce; }
|
|
|
|
/// Enable/Disable the construction of base buildings.
|
|
Bool getCanBuildBase(void) { return m_canBuildBase; }
|
|
void setCanBuildBase(Bool canProduce) { m_canBuildBase = canProduce; }
|
|
|
|
/// Transfer all assets from player that to this
|
|
void transferAssetsFromThat(Player* that);
|
|
|
|
/// Sell everything this player owns.
|
|
void sellEverythingUnderTheSun(void);
|
|
|
|
void garrisonAllUnits(CommandSourceType source);
|
|
void ungarrisonAllUnits(CommandSourceType source);
|
|
|
|
void setUnitsShouldIdleOrResume(Bool idle);
|
|
|
|
Bool isPlayableSide( void ) const;
|
|
|
|
Bool isPlayerObserver( void ) const; // Favor !isActive() - this is used for Observer GUI mostly, not in-game stuff
|
|
Bool isPlayerDead(void) const; // Favor !isActive() - this is used so OCLs don't give us stuff after death.
|
|
Bool isPlayerActive(void) const;
|
|
|
|
Bool didPlayerPreorder( void ) const { return m_isPreorder; }
|
|
|
|
/// Grab the scorekeeper so we can score up in here!
|
|
ScoreKeeper* getScoreKeeper( void ) { return &m_scoreKeeper; }
|
|
|
|
/// time to create a hotkey team based on this GameMessage
|
|
void processCreateTeamGameMessage(Int hotkeyNum, GameMessage *msg);
|
|
|
|
/// time to select a hotkey team based on this GameMessage
|
|
void processSelectTeamGameMessage(Int hotkeyNum, GameMessage *msg);
|
|
|
|
// add to the player's current selection this hotkey team.
|
|
void processAddTeamGameMessage(Int hotkeyNum, GameMessage *msg);
|
|
|
|
// returns an AIGroup object that is the currently selected group.
|
|
void getCurrentSelectionAsAIGroup(AIGroup *group);
|
|
|
|
// sets the currently selected group to be the given AIGroup
|
|
void setCurrentlySelectedAIGroup(AIGroup *group);
|
|
|
|
// adds the given AIGroup to the current selection of this player.
|
|
void addAIGroupToCurrentSelection(AIGroup *group);
|
|
|
|
// return the requested hotkey squad
|
|
Squad *getHotkeySquad(Int squadNumber);
|
|
|
|
// return the hotkey squad that a unit is in, or NO_HOTKEY_SQUAD if it isn't in one.
|
|
Int getSquadNumberForObject(const Object *objToFind) const;
|
|
|
|
// remove an object from any hotkey squads that its in.
|
|
void removeObjectFromHotkeySquad(Object *objToRemove);
|
|
|
|
void setAttackedBy( Int playerNdx );
|
|
Bool getAttackedBy( Int playerNdx ) const;
|
|
UnsignedInt getAttackedFrame(void) {return m_attackedFrame;} // Return last frame attacked.
|
|
|
|
Real getCashBounty() const { return m_cashBountyPercent; }
|
|
void setCashBounty(Real percentage) { m_cashBountyPercent = percentage; }
|
|
void doBountyForKill(const Object* killer, const Object* victim);
|
|
|
|
private:
|
|
|
|
/** give the science. doesn't check prereqs, nor charge to purchase points...
|
|
just grants it! so be careful! NOTE that this is private to Player,
|
|
and for a good reason; if public, this could be used to grant sciences
|
|
that shouldn't be directly granted (e.g., SCIENCE_RankX, which should
|
|
be managed via setRankLevel instead). If you think you need to use
|
|
this call externally, you probably don't... you should probably be
|
|
using grantScience() instead.
|
|
*/
|
|
Bool addScience(ScienceType science);
|
|
|
|
public:
|
|
Int getSkillPoints() const { return m_skillPoints; }
|
|
Int getSciencePurchasePoints() const { return m_sciencePurchasePoints; }
|
|
Int getRankLevel() const { return m_rankLevel; }
|
|
Int getSkillPointsLevelUp() const { return m_levelUp; }
|
|
Int getSkillPointsLevelDown() const { return m_levelDown; }
|
|
UnicodeString getGeneralName() const { return m_generalName; }
|
|
void setGeneralName( UnicodeString name ){ m_generalName = name; }
|
|
/// returns TRUE if rank level really changed.
|
|
Bool setRankLevel(Int level);
|
|
|
|
/// returns TRUE if the player gained/lost levels as a result.
|
|
Bool addSkillPoints(Int delta);
|
|
|
|
/// returns TRUE if the player gained/lost levels as a result.
|
|
Bool addSkillPointsForKill(const Object* killer, const Object* victim);
|
|
|
|
void addSciencePurchasePoints(Int delta);
|
|
|
|
void setSkillPointsModifier(Real expMod) { m_skillPointsModifier = expMod; }
|
|
Real getSkillPointsModifier(void) const { return m_skillPointsModifier; }
|
|
|
|
/// reset the sciences to just the intrinsic ones from the playertemplate, if any.
|
|
void resetSciences();
|
|
|
|
/// reset rank to 1.
|
|
void resetRank();
|
|
|
|
/**
|
|
attempt to purchase the science, but use prereqs, and charge points.
|
|
return true if successful.
|
|
*/
|
|
Bool attemptToPurchaseScience(ScienceType science);
|
|
|
|
/**
|
|
grant the science, ignore prereqs & charge no points,
|
|
but still restrict you to purchasable sciences (ie, intrinsic and rank sciences
|
|
are not allowed)
|
|
return true if successful.
|
|
*/
|
|
Bool grantScience(ScienceType science);
|
|
|
|
/** return true attemptToPurchaseScience() would succeed for this science. */
|
|
Bool isCapableOfPurchasingScience(ScienceType science) const;
|
|
|
|
protected:
|
|
|
|
// snapshot methods
|
|
virtual void crc( Xfer *xfer );
|
|
virtual void xfer( Xfer *xfer );
|
|
virtual void loadPostProcess( void );
|
|
|
|
void deleteUpgradeList( void ); ///< delete all our upgrades
|
|
|
|
private:
|
|
|
|
const PlayerTemplate* m_playerTemplate; ///< Pointer back to the Player Template
|
|
|
|
UnicodeString m_playerDisplayName; ///< This player's persistent name.
|
|
Handicap m_handicap; ///< adjustment to varied capabilities (@todo: is this persistent or recalced each time?)
|
|
AsciiString m_playerName; ///< player's itnernal name 9for matching map objects)
|
|
NameKeyType m_playerNameKey; ///< This player's internal name (for matching map objects)
|
|
PlayerIndex m_playerIndex; ///< player unique index.
|
|
AsciiString m_side; ///< the "side" this player is on
|
|
PlayerType m_playerType; ///< human/computer control
|
|
Money m_money; ///< Player's current wealth
|
|
Upgrade* m_upgradeList; ///< list of all upgrades this player has
|
|
Int m_radarCount; ///< # of facilities that have a radar under the players control
|
|
Int m_disableProofRadarCount; ///< # of disable proof radars. A disable proof one will be in both refcounts
|
|
Bool m_radarDisabled; ///< The radar is disabled regardless of the number of radar objects
|
|
Int m_bombardBattlePlans; ///< Number of strategy centers with active bombardment plan
|
|
Int m_holdTheLineBattlePlans; ///< Number of strategy centers with active hold the line plan
|
|
Int m_searchAndDestroyBattlePlans;///< Number of strategy centers with active search and destroy plan
|
|
BattlePlanBonuses* m_battlePlanBonuses;
|
|
Int64 m_upgradesInProgress; ///< Bit field of In Production status upgrades
|
|
Int64 m_upgradesCompleted; ///< Bit field of upgrades completed. Bits are assigned by UpgradeCenter
|
|
Energy m_energy; ///< current energy production & consumption
|
|
MissionStats m_stats; ///< stats about the current mission (units destroyed, etc)
|
|
BuildListInfo* m_pBuildList; ///< linked list of buildings for PLAYER_COMPUTER.
|
|
Color m_color; ///< color for our units
|
|
Color m_nightColor; ///<tweaked version of regular color to make it easier to see on night maps.
|
|
ProductionChangeMap m_productionCostChanges; ///< Map to keep track of Faction specific discounts or penalties on prices of units
|
|
ProductionChangeMap m_productionTimeChanges; ///< Map to keep track of Faction specific discounts or penalties on build times of units
|
|
ProductionVeterancyMap m_productionVeterancyLevels; ///< Map to keep track of starting level of produced units
|
|
#if !defined(_PLAYTEST)
|
|
AIPlayer* m_ai; ///< if PLAYER_COMPUTER, the entity that does the thinking
|
|
#endif
|
|
Int m_mpStartIndex; ///< The player's starting index for multiplayer.
|
|
ResourceGatheringManager* m_resourceGatheringManager; ///< Keeps track of all Supply Centers and Warehouses
|
|
TunnelTracker* m_tunnelSystem; ///< All TunnelContain buildings use this part of me for actual conatinment
|
|
Team* m_defaultTeam; ///< our "default" team.
|
|
|
|
ScienceVec m_sciences; ///< (SAVE) sciences that we know (either intrinsically or via later purchases)
|
|
ScienceVec m_sciencesDisabled; ///< (SAVE) sciences that we are not permitted to purchase "yet". Controlled by mission scripts.
|
|
ScienceVec m_sciencesHidden; ///< (SAVE) sciences that aren't shown. Controlled by mission scripts.
|
|
|
|
Int m_rankLevel; ///< (SAVE) our RankLevel, 1...n
|
|
Int m_skillPoints; ///< (SAVE) our cumulative SkillPoint total
|
|
Int m_sciencePurchasePoints; ///< (SAVE) our unspent SciencePurchasePoint total
|
|
Int m_levelUp, m_levelDown; ///< (NO-SAVE) skill points to go up/down a level (runtime only)
|
|
UnicodeString m_generalName; ///< (SAVE) This is the name of the general the player is allowed to change.
|
|
|
|
PlayerTeamList m_playerTeamPrototypes; ///< ALL the teams we control, via prototype
|
|
PlayerRelationMap *m_playerRelations; ///< allies & enemies
|
|
TeamRelationMap *m_teamRelations; ///< allies & enemies
|
|
|
|
Bool m_canBuildUnits; ///< whether the current player is allowed to build units
|
|
Bool m_canBuildBase; ///< whether the current player is allowed to build Base buildings
|
|
Bool m_observer;
|
|
Bool m_isPreorder;
|
|
Real m_skillPointsModifier; ///< Multiplied by skill points before they are applied
|
|
|
|
Bool m_listInScoreScreen; ///< should this player be listed in the score screen or not.
|
|
Bool m_unitsShouldHunt;
|
|
|
|
Bool m_attackedBy[MAX_PLAYER_COUNT]; ///< For each player, have they attacked me?
|
|
UnsignedInt m_attackedFrame; ///< Last frame attacked.
|
|
Int m_visionSpiedBy[MAX_PLAYER_COUNT]; ///< Reference count of having units spied on by players.
|
|
PlayerMaskType m_visionSpiedMask; ///< For quick lookup and edge triggered maintenance
|
|
|
|
Real m_cashBountyPercent;
|
|
|
|
/// @todo REMOVE (not disable) these cheat keys
|
|
#if defined(_DEBUG) || defined(_INTERNAL)
|
|
Bool m_DEMO_ignorePrereqs; ///< Can I ignore prereq checks?
|
|
Bool m_DEMO_freeBuild; ///< Can I build everything for no money?
|
|
Bool m_DEMO_instantBuild; ///< Can I build anything in one frame?
|
|
#endif
|
|
|
|
ScoreKeeper m_scoreKeeper; ///< The local scorekeeper for this player
|
|
|
|
typedef std::list<KindOfPercentProductionChange*> KindOfPercentProductionChangeList;
|
|
typedef KindOfPercentProductionChangeList::iterator KindOfPercentProductionChangeListIt;
|
|
mutable KindOfPercentProductionChangeList m_kindOfPercentProductionChangeList;
|
|
|
|
|
|
typedef std::list<SpecialPowerReadyTimerType> SpecialPowerReadyTimerList;
|
|
typedef SpecialPowerReadyTimerList::iterator SpecialPowerReadyTimerListIterator;
|
|
SpecialPowerReadyTimerList m_specialPowerReadyTimerList;
|
|
|
|
Squad *m_squads[NUM_HOTKEY_SQUADS]; ///< The hotkeyed squads
|
|
Squad *m_currentSelection; ///< This player's currently selected group
|
|
|
|
Bool m_isPlayerDead;
|
|
};
|
|
|
|
#endif // _PLAYER_H_
|