// ____ _ __ // / __ )____ _____ | | / /___ ___________ // / __ / __ \/ ___/ | | /| / / __ `/ ___/ ___/ // / /_/ / /_/ (__ ) | |/ |/ / /_/ / / (__ ) // /_____/\____/____/ |__/|__/\__,_/_/ /____/ // // A futuristic real-time strategy game. // This file is part of Bos Wars. // /**@name unit.h - The unit headerfile. */ // // (c) Copyright 1998-2007 by Lutz Sammer and Jimmy Salmon // // 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; only version 2 of the License. // // 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, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. #ifndef __UNIT_H__ #define __UNIT_H__ //@{ /*---------------------------------------------------------------------------- -- Documentation ----------------------------------------------------------------------------*/ /** ** @class CUnit unit.h ** ** \#include "unit.h" ** ** Everything belonging to a unit. FIXME: rearrange for less memory. ** ** This class contains all information about a unit in game. ** A unit could be anything: a man, a vehicle, a ship, or a building. ** Currently only a tile, a unit, or a missile could be placed on the map. ** ** The unit structure members: ** ** CUnit::Refs ** ** The reference counter of the unit. If the pointer to the unit ** is stored the counter must be incremented and if this reference ** is destroyed the counter must be decremented. Alternative it ** would be possible to implement a garbage collector for this. ** ** CUnit::Slot ** ** This is the unique slot number. It is not possible that two ** units have the same slot number at the same time. The slot ** numbers are reused. ** This field could be accessed by the macro UnitNumber(Unit *). ** Maximal 65535 (=#MAX_UNIT_SLOTS) simultaneous units are ** supported. ** ** CUnit::UnitSlot ** ** This is the pointer into #Units[], where the unit pointer is ** stored. #Units[] is a table of all units currently active in ** game. This pointer is only needed to speed up, the remove of ** the unit pointer from #Units[], it didn't must be searched in ** the table. ** ** CUnit::PlayerSlot ** ** A pointer into Player::Units[], where the unit pointer is ** stored. Player::Units[] is a table of all units currently ** belonging to a player. This pointer is only needed to speed ** up, the remove of the unit pointer from Player::Units[]. ** ** CUnit::Next ** ** A generic link pointer. This member is currently used, if an ** unit is on the map, to link all units on the same map field ** together. This also links corpses and stuff. Also, this is ** used in memory management to link unused units. ** ** CUnit::Container ** ** Pointer to the unit containing it, or NoUnitP if the unit is ** free. This points to the transporter for units on board, or to ** the building for peasants inside(when they are mining). ** ** CUnit::UnitInside ** ** Pointer to the last unit added inside. Order doesn't really ** matter. All units inside are kept in a circular linked list. ** This is NoUnitP if there are no units inside. Multiple levels ** of inclusion are allowed, though not very usefull right now ** ** CUnit::NextContained, CUnit::PrevContained ** ** The next and previous element in the curent container. Bogus ** values allowed for units not contained. ** ** CUnit::InsideCount ** ** The number of units inside the container. ** ** CUnit::BoardCount ** ** The number of units transported inside the container. This ** does not include for instance stuff like harvesters returning ** cargo. ** ** CUnit::X CUnit::Y ** ** The tile map coordinates of the unit. 0,0 is the upper left on ** the map. To convert the map coordinates into pixels, they ** must be multiplicated with the #TileSizeX and #TileSizeY. ** To get the pixel coordinates of a unit, calculate ** CUnit::X*#TileSizeX+CUnit::IX , CUnit::Y*#TileSizeY+CUnit::IY. ** ** CUnit::Type ** ** Pointer to the unit-type (::UnitType). The unit-type contains ** all informations that all units of the same type shares. ** (Animations, Name, Stats, ...) ** ** CUnit::SeenType ** Pointer to the unit-type that this unit was, when last seen. ** Currently only used by buildings. ** ** CUnit::Player ** ** Pointer to the owner of this unit (::Player). An unit could ** only be owned by one player. ** ** CUnit::Stats ** ** Pointer to the current status (::UnitStats) of a unit. The ** units of the same player and the same type could share the same ** stats. The status contains all values which could be different ** for each player. This f.e. the upgradeable abilities of an ** unit. (CUnit::Stats::SightRange, CUnit::Stats::Armor, ** CUnit::Stats::HitPoints, ...) ** ** CUnit::CurrentSightRange ** ** Current sight range of a unit, this changes when a unit enters ** a transporter or building or exits one of these. ** ** CUnit::Colors ** ** Player colors of the unit. Contains the hardware dependent ** pixel values for the player colors (palette index #208-#211). ** Setup from the global palette. This is a pointer. ** @note Index #208-#211 are various SHADES of the team color ** (#208 is brightest shade, #211 is darkest shade) .... these ** numbers are NOT red=#208, blue=#209, etc ** ** CUnit::IX CUnit::IY ** ** Coordinate displacement in pixels or coordinates inside a tile. ** Currently only !=0, if the unit is moving from one tile to ** another (0-32 and for ships/flyers 0-64). ** ** CUnit::Frame ** ** Current graphic image of the animation sequence. The high bit ** (128) is used to flip this image horizontal (x direction). ** This also limits the number of different frames/image to 126. ** ** CUnit::SeenFrame ** ** Graphic image (see CUnit::Frame) what the player on this ** computer has last seen. If UnitNotSeen the player haven't seen ** this unit yet. ** ** CUnit::Direction ** ** Contains the binary angle (0-255) in which the direction the ** unit looks. 0, 32, 64, 128, 160, 192, 224, 256 corresponds to ** 0, 45, 90, 135, 180, 225, 270, 315, 360 or north, ** north-east, east, south-east, south, south-west, west, ** north-west, north. Currently only 8 directions are used, this ** is more for the future. ** ** CUnit::Attacked ** ** Last cycle the unit was attacked. 0 means never. ** ** CUnit::Burning ** ** If Burning is non-zero, the unit is burning. ** ** CUnit::VisCount[PlayerMax] ** ** Used to keep track of visible units on the map, it counts the ** Number of seen tiles for each player. This is only modified ** in UnitsMarkSeen and UnitsUnmarkSeen, from fow. ** We keep track of visilibty for each player, and combine with ** Shared vision ONLY when querying and such. ** ** CUnit::SeenByPlayer ** ** This is a bitmask of 1 and 0 values. SeenByPlayer & (1<
#include "SDL.h"
#include "upgrade_structs.h"
/*----------------------------------------------------------------------------
-- Declarations
----------------------------------------------------------------------------*/
class CUnit;
class CUnitType;
class CUnitStats;
class CPlayer;
class SpellType;
class CUnitColors;
class CConstructionFrame;
class CVariable;
class CBuildRestrictionOnTop;
class CFile;
struct lua_State;
class CViewport;
class CAnimation;
/// Called whenever the selected unit was updated
extern void SelectedUnitChanged(void);
/**
** Unit references over network, or for memory saving.
*/
typedef unsigned short UnitRef;
/**
** All possible unit actions.
**
** @note Always change the table ::HandleActionTable
**
** @see HandleActionTable
*/
typedef enum _unit_action_ {
UnitActionNone, /// No valid action
UnitActionStill, /// unit stand still, does nothing
UnitActionStandGround, /// unit stands ground
UnitActionFollow, /// unit follows units
UnitActionMove, /// unit moves to position/unit
UnitActionAttack, /// unit attacks position/unit
UnitActionAttackGround, /// unit attacks ground
UnitActionDie, /// unit dies
UnitActionSpellCast, /// unit casts spell
UnitActionTrain, /// building is training
UnitActionBuilt, /// building is under construction
// Compound actions
UnitActionBoard, /// unit entering transporter
UnitActionUnload, /// unit leaving transporter
UnitActionPatrol, /// unit paroling area
UnitActionBuild, /// unit builds building
UnitActionRepair, /// unit repairing
UnitActionResource, /// unit harvesting resources
} UnitAction;
/**
** Unit order structure.
*/
class COrder {
public:
COrder() : Action(UnitActionNone), Range(0), MinRange(0), Width(0),
Height(0), Goal(NULL), X(-1), Y(-1), Type(NULL)
{
memset(&Arg1, 0, sizeof(Arg1));
};
void Init() {
Action = UnitActionNone;
Range = 0;
MinRange = 0;
Width = 0;
Height = 0;
Assert(!Goal);
X = -1; Y = -1;
Type = NULL;
memset(&Arg1, 0, sizeof(Arg1));
};
unsigned char Action; /// global action
int Range; /// How far away
unsigned int MinRange; /// How far away minimum
unsigned char Width; /// Goal Width (used when Goal is not)
unsigned char Height; /// Goal Height (used when Goal is not)
CUnit *Goal; /// goal of the order (if any)
int X; /// or X tile coordinate of destination
int Y; /// or Y tile coordinate of destination
CUnitType *Type; /// Unit-type argument
union {
struct {
int X; /// X position for patroling.
int Y; /// Y position for patroling.
} Patrol; /// position.
SpellType *Spell; /// spell when casting.
} Arg1; /// Extra command argument.
};
/**
** Voice groups for a unit
*/
enum UnitVoiceGroup {
VoiceSelected, /// If selected
VoiceAcknowledging, /// Acknowledge command
VoiceReady, /// Command completed
VoiceHelpMe, /// If attacked
VoiceDying, /// If killed
VoiceWorkCompleted, /// only worker, work completed
VoiceBuilding, /// only for building under construction
VoiceDocking, /// only for transport reaching coast
VoiceRepairing, /// repairing
VoiceHarvesting, /// harvesting
};
/**
** Unit/Missile headings.
** N
** NW NE
** W E
** SW SE
** S
*/
enum _directions_ {
LookingN = 0 * 32, /// Unit looking north
LookingNE = 1 * 32, /// Unit looking north east
LookingE = 2 * 32, /// Unit looking east
LookingSE = 3 * 32, /// Unit looking south east
LookingS = 4 * 32, /// Unit looking south
LookingSW = 5 * 32, /// Unit looking south west
LookingW = 6 * 32, /// Unit looking west
LookingNW = 7 * 32, /// Unit looking north west
};
#define NextDirection 32 /// Next direction N->NE->E...
#define UnitNotSeen 0x7fffffff /// Unit not seen, used by CUnit::SeenFrame
/// The big unit structure
class CUnit {
public:
CUnit() { Init(); }
void Init() {
Refs = 0;
Slot = 0;
UnitSlot = NULL;
PlayerSlot = NULL;
Next = NULL;
CacheLock = 0;
InsideCount = 0;
BoardCount = 0;
UnitInside = NULL;
Container = NULL;
NextContained = NULL;
PrevContained = NULL;
X = 0;
Y = 0;
Type = NULL;
Player = NULL;
Stats = NULL;
CurrentSightRange = 0;
Colors = NULL;
IX = 0;
IY = 0;
Frame = 0;
Direction = 0;
Attacked = 0;
Burning = 0;
Destroyed = 0;
Removed = 0;
Selected = 0;
TeamSelected = 0;
Constructed = 0;
Boarded = 0;
RescuedFrom = NULL;
memset(VisCount, 0, sizeof(VisCount));
memset(&Seen, 0, sizeof(Seen));
Variable = NULL;
TTL = 0;
GroupId = 0;
LastGroup = 0;
memset(ResourcesHeld, 0, sizeof(ResourcesHeld));
ProductionEfficiency = 100;
SubAction = 0;
Wait = 0;
State = 0;
Blink = 0;
Moving = 0;
ReCast = 0;
memset(&Anim, 0, sizeof(Anim));
OrderCount = 0;
OrderFlush = 0;
Orders.clear();
SavedOrder.Init();
NewOrder.Init();
AutoCastSpell = NULL;
AutoRepair = 0;
memset(&Data, 0, sizeof(Data));
Goal = NULL;
}
// @note int is faster than shorts
int Refs; /// Reference counter
int Slot; /// Assigned slot number
CUnit **UnitSlot; /// Slot pointer of Units
CUnit **PlayerSlot; /// Slot pointer of Player->Units
CUnit *Next; /// Generic link pointer (on map)
unsigned CacheLock : 1; /// Used to lock unit out of the cache.
int InsideCount; /// Number of units inside.
int BoardCount; /// Number of units transported inside.
CUnit *UnitInside; /// Pointer to one of the units inside.
CUnit *Container; /// Pointer to the unit containing it (or 0)
CUnit *NextContained; /// Next unit in the container.
CUnit *PrevContained; /// Previous unit in the container.
int X; /// Map position X
int Y; /// Map position Y
CUnitType *Type; /// Pointer to unit-type (peon,...)
CPlayer *Player; /// Owner of this unit
CUnitStats *Stats; /// Current unit stats
int CurrentSightRange; /// Unit's Current Sight Range
// DISPLAY:
CUnitColors *Colors; /// Player colors
signed char IX; /// X image displacement to map position
signed char IY; /// Y image displacement to map position
int Frame; /// Image frame: <0 is mirrored
unsigned Direction : 8; /// angle (0-255) unit looking
unsigned long Attacked; /// gamecycle unit was last attacked
unsigned Burning : 1; /// unit is burning
unsigned Destroyed : 1; /// unit is destroyed pending reference
unsigned Removed : 1; /// unit is removed (not on map)
unsigned Selected : 1; /// unit is selected
unsigned Constructed : 1; /// Unit is in construction
unsigned Boarded : 1; /// Unit is on board a transporter.
unsigned TeamSelected; /// unit is selected by a team member.
CPlayer *RescuedFrom; /// The original owner of a rescued unit.
/// NULL if the unit was not rescued.
/* Seen stuff. */
int VisCount[PlayerMax]; /// Unit visibility counts
struct _unit_seen_ {
unsigned ByPlayer : PlayerMax; /// Track unit seen by player
int Frame; /// last seen frame/stage of buildings
CUnitType *Type; /// Pointer to last seen unit-type
int X; /// Last unit->X Seen
int Y; /// Last unit->Y Seen
signed char IX; /// Seen X image displacement to map position
signed char IY; /// seen Y image displacement to map position
unsigned Constructed : 1; /// Unit seen construction
unsigned State : 3; /// Unit seen build/upgrade state
unsigned Destroyed : PlayerMax; /// Unit seen destroyed or not
CConstructionFrame *CFrame; /// Seen construction frame
} Seen;
CVariable *Variable; /// array of User Defined variables.
unsigned long TTL; /// time to live
int GroupId; /// unit belongs to this group id
int LastGroup; /// unit belongs to this last group
int ResourcesHeld[MaxCosts]; /// Resources held by a unit
unsigned ProductionEfficiency : 8; /// Production efficiency
unsigned SubAction : 8; /// sub-action of unit
unsigned Wait; /// action counter
unsigned State : 8; /// action state
unsigned Blink : 3; /// Let selection rectangle blink
unsigned Moving : 1; /// The unit is moving
unsigned ReCast : 1; /// Recast again next cycle
struct _unit_anim_ {
const CAnimation *Anim; /// Anim
const CAnimation *CurrAnim; /// CurrAnim
int Wait; /// Wait
int Unbreakable; /// Unbreakable
} Anim;
char OrderCount; /// how many orders in queue
char OrderFlush; /// cancel current order, take next
std::vector