move inner class CUnit::Corder to actions.h

This commit is contained in:
joris 2012-02-13 12:28:38 +01:00
parent a8892060d1
commit 79d5c7c344
27 changed files with 441 additions and 410 deletions

View file

@ -147,7 +147,7 @@ static int CheckForTargetInRange(CUnit &unit)
CUnit *goal = AttackUnitsInReactRange(unit);
if (goal) {
CUnit::COrder *savedOrder = new CUnit::COrder();
COrder *savedOrder = new COrder();
savedOrder->Action = order->Action;
@ -172,7 +172,7 @@ static int CheckForTargetInRange(CUnit &unit)
CUnit *temp = AttackUnitsInReactRange(unit);
if (temp && temp->Type->Priority > goal->Type->Priority) {
CUnit::COrder *savedOrder = new CUnit::COrder(*order);
COrder *savedOrder = new COrder(*order);
if (unit.StoreOrder(savedOrder) == false) {
delete savedOrder;
@ -330,7 +330,7 @@ static void AttackTarget(CUnit &unit)
return;
}
// Save current command to come back.
CUnit::COrder *savedOrder = new CUnit::COrder(*order);
COrder *savedOrder = new COrder(*order);
if (unit.StoreOrder(savedOrder) == false) {
delete savedOrder;
@ -351,7 +351,7 @@ static void AttackTarget(CUnit &unit)
if ((unit.SubAction & WEAK_TARGET)) {
CUnit *temp = AttackUnitsInReactRange(unit);
if (temp && temp->Type->Priority > goal->Type->Priority) {
CUnit::COrder *savedOrder = new CUnit::COrder(*order);
COrder *savedOrder = new COrder(*order);
if (unit.StoreOrder(savedOrder) == false) {
delete savedOrder;
@ -372,7 +372,7 @@ static void AttackTarget(CUnit &unit)
//
int dist = unit.MapDistanceTo(*goal);
if (dist > unit.Stats->Variables[ATTACKRANGE_INDEX].Max) {
CUnit::COrder *savedOrder = new CUnit::COrder(*order);
COrder *savedOrder = new COrder(*order);
if (unit.StoreOrder(savedOrder) == false) {
delete savedOrder;
@ -410,7 +410,7 @@ static void AttackTarget(CUnit &unit)
**
** @param unit Unit, for that the attack is handled.
*/
void HandleActionAttack(CUnit::COrder& order, CUnit &unit)
void HandleActionAttack(COrder& order, CUnit &unit)
{
Assert(order.Action == UnitActionAttackGround || order.Action == UnitActionAttack);
Assert(order.HasGoal() || Map.Info.IsPointOnMap(order.goalPos));

View file

@ -175,7 +175,7 @@ static void EnterTransporter(CUnit &unit)
**
** @param unit Pointer to unit.
*/
void HandleActionBoard(CUnit::COrder& order, CUnit &unit)
void HandleActionBoard(COrder& order, CUnit &unit)
{
switch (unit.SubAction) {
// Wait for transporter

View file

@ -408,7 +408,7 @@ static void BuildBuilding(CUnit &unit)
**
** @param unit Unit that builds a building
*/
void HandleActionBuild(CUnit::COrder& /*order*/, CUnit &unit)
void HandleActionBuild(COrder& /*order*/, CUnit &unit)
{
CUnit *ontop;
@ -430,7 +430,7 @@ void HandleActionBuild(CUnit::COrder& /*order*/, CUnit &unit)
**
** @param unit Unit that is being built
*/
void HandleActionBuilt(CUnit::COrder& order, CUnit &unit)
void HandleActionBuilt(COrder& order, CUnit &unit)
{
CUnit *worker;
CUnitType *type;

View file

@ -53,7 +53,7 @@
**
** @param unit The unit which dies.
*/
void HandleActionDie(CUnit::COrder& order, CUnit &unit)
void HandleActionDie(COrder& order, CUnit &unit)
{
Assert(order.Action == UnitActionDie);

View file

@ -58,7 +58,7 @@
**
** @param unit Pointer to unit.
*/
void HandleActionFollow(CUnit::COrder& order, CUnit &unit)
void HandleActionFollow(COrder& order, CUnit &unit)
{
if (unit.Wait) {
unit.Wait--;
@ -186,7 +186,7 @@ void HandleActionFollow(CUnit::COrder& order, CUnit &unit)
goal = AttackUnitsInReactRange(unit);
if (goal) {
// Save current command to come back.
CUnit::COrder *savedOrder = new CUnit::COrder(order);
COrder *savedOrder = new COrder(order);
CommandAttack(unit, goal->tilePos, NULL, FlushCommands);

View file

@ -172,7 +172,7 @@ int DoActionMove(CUnit &unit)
**
** @param unit Pointer to unit.
*/
void HandleActionMove(CUnit::COrder& order, CUnit &unit)
void HandleActionMove(COrder& order, CUnit &unit)
{
CUnit *goal;

View file

@ -75,7 +75,7 @@ static void SwapPatrolPoints(CUnit &unit)
**
** @param unit Patroling unit pointer.
*/
void HandleActionPatrol(CUnit::COrder& order, CUnit &unit)
void HandleActionPatrol(COrder& order, CUnit &unit)
{
if (unit.Wait) {
unit.Wait--;
@ -129,7 +129,7 @@ void HandleActionPatrol(CUnit::COrder& order, CUnit &unit)
const CUnit *goal = AttackUnitsInReactRange(unit);
if (goal) {
// Save current command to come back.
CUnit::COrder *savedOrder = new CUnit::COrder(order);
COrder *savedOrder = new COrder(order);
if (unit.StoreOrder(savedOrder) == false) {
delete savedOrder;

View file

@ -144,7 +144,7 @@ static int AnimateActionRepair(CUnit &unit)
**
** @param unit Unit, for that the attack is handled.
*/
void HandleActionRepair(CUnit::COrder& order, CUnit &unit)
void HandleActionRepair(COrder& order, CUnit &unit)
{
CUnit *goal;
int err;

View file

@ -57,7 +57,7 @@
**
** @param unit Pointer of researching unit.
*/
void HandleActionResearch(CUnit::COrder& order, CUnit &unit)
void HandleActionResearch(COrder& order, CUnit &unit)
{
const CUpgrade *upgrade;

View file

@ -885,7 +885,7 @@ static bool ActionResourceInit(CUnit &unit)
**
** @param unit Pointer to unit.
*/
void HandleActionResource(CUnit::COrder& order, CUnit &unit)
void HandleActionResource(COrder& order, CUnit &unit)
{
if (unit.Wait) {
// FIXME: show idle animation while we wait?

View file

@ -55,7 +55,7 @@
**
** @todo FIXME: move this into action_resource?
*/
void HandleActionReturnGoods(CUnit::COrder& order, CUnit &unit)
void HandleActionReturnGoods(COrder& order, CUnit &unit)
{
Assert(unit.Type->Harvester);

View file

@ -135,7 +135,7 @@ static void SpellMoveToTarget(CUnit &unit)
**
** @param unit Unit, for that the spell cast is handled.
*/
void HandleActionSpellCast(CUnit::COrder& order, CUnit &unit)
void HandleActionSpellCast(COrder& order, CUnit &unit)
{
if (unit.Wait) {
unit.Wait--;

View file

@ -48,7 +48,7 @@
**
** @param unit Action handled for this unit pointer.
*/
void HandleActionStandGround(CUnit::COrder& /*order*/, CUnit &unit)
void HandleActionStandGround(COrder& /*order*/, CUnit &unit)
{
ActionStillGeneric(unit, true);
}

View file

@ -244,7 +244,7 @@ bool AutoRepair(CUnit &unit)
if (repairedUnit != NoUnitP) {
const Vec2i invalidPos = {-1, -1};
CUnit::COrder *savedOrder = new CUnit::COrder(*unit.CurrentOrder());
COrder *savedOrder = new COrder(*unit.CurrentOrder());
//Command* will clear unit.SavedOrder
CommandRepair(unit, invalidPos, repairedUnit, FlushCommands);
@ -272,7 +272,7 @@ static bool AutoAttack(CUnit &unit, bool stand_ground)
if ((goal = AttackUnitsInReactRange(unit))) {
// Weak goal, can choose other unit, come back after attack
CommandAttack(unit, goal->tilePos, NULL, FlushCommands);
CUnit::COrder *savedOrder = new CUnit::COrder;
COrder *savedOrder = new COrder;
savedOrder->Action = UnitActionAttack;
savedOrder->Range = 0;
@ -316,7 +316,7 @@ void AutoAttack(CUnit &unit, CUnitCache &targets, bool stand_ground)
if (goal) {
// Weak goal, can choose other unit, come back after attack
CommandAttack(unit, goal->tilePos, NULL, FlushCommands);
CUnit::COrder *savedOrder = new CUnit::COrder;
COrder *savedOrder = new COrder;
savedOrder->Action = UnitActionAttack;
savedOrder->Range = 0;
@ -399,7 +399,7 @@ void ActionStillGeneric(CUnit &unit, bool stand_ground)
**
** @param unit Unit pointer for still action.
*/
void HandleActionStill(CUnit::COrder& /*order*/, CUnit &unit)
void HandleActionStill(COrder& /*order*/, CUnit &unit)
{
ActionStillGeneric(unit, false);
}

View file

@ -94,7 +94,7 @@ static bool CanHandleOrder(CUnit &unit, COrderPtr order)
**
** @param unit Unit that trains.
*/
void HandleActionTrain(CUnit::COrder& order, CUnit &unit)
void HandleActionTrain(COrder& order, CUnit &unit)
{
// First entry
if (!unit.SubAction) {

View file

@ -323,7 +323,7 @@ static void LeaveTransporter(CUnit &transporter)
**
** @param unit Pointer to unit.
*/
void HandleActionUnload(CUnit::COrder& order, CUnit &unit)
void HandleActionUnload(COrder& order, CUnit &unit)
{
const int maxSearchRange = 20;

View file

@ -134,7 +134,7 @@ static int TransformUnitIntoType(CUnit &unit, CUnitType &newtype)
**
** @param unit Pointer to unit.
*/
void HandleActionTransformInto(CUnit::COrder& order, CUnit &unit)
void HandleActionTransformInto(COrder& order, CUnit &unit)
{
// What to do if an error occurs ?
TransformUnitIntoType(unit, *order.Arg1.Type);
@ -145,7 +145,7 @@ void HandleActionTransformInto(CUnit::COrder& order, CUnit &unit)
**
** @param unit Pointer to unit.
*/
void HandleActionUpgradeTo(CUnit::COrder& order, CUnit &unit)
void HandleActionUpgradeTo(COrder& order, CUnit &unit)
{
if (!unit.SubAction) { // first entry
order.Data.UpgradeTo.Ticks = 0;

View file

@ -39,12 +39,13 @@
#include <time.h>
#include "stratagus.h"
#include "actions.h"
#include "video.h"
#include "unittype.h"
#include "animation.h"
#include "player.h"
#include "unit.h"
#include "actions.h"
#include "missile.h"
#include "interface.h"
#include "map.h"
@ -61,6 +62,120 @@ unsigned SyncHash; /// Hash calculated to find sync failures
-- Functions
----------------------------------------------------------------------------*/
COrder::~COrder() {
if (Goal) {
Goal->RefsDecrease();
Goal = NoUnitP;
}
if (Action == UnitActionResource && Arg1.Resource.Mine) {
Arg1.Resource.Mine->RefsDecrease();
Arg1.Resource.Mine = NoUnitP;
}
}
void COrder::ReleaseRefs(CUnit &unit)
{
// Release pending references.
if (this->Action == UnitActionResource) {
CUnit *mine = this->Arg1.Resource.Mine;
if (mine) {
unit.DeAssignWorkerFromMine(*mine);
mine->RefsDecrease();
this->Arg1.Resource.Mine = NULL;
}
}
if (this->HasGoal()) {
// If mining decrease the active count on the resource.
if (this->Action == UnitActionResource) {
if (unit.SubAction == 60 /* SUB_GATHER_RESOURCE */ ) {
CUnit *goal = this->GetGoal();
goal->CurrentOrder()->Data.Resource.Active--;
Assert(goal->CurrentOrder()->Data.Resource.Active >= 0);
}
}
// Still shouldn't have a reference unless attacking
Assert(!(this->Action == UnitActionStill && !unit.SubAction));
this->ClearGoal();
}
#ifdef DEBUG
else {
if (unit.CurrentResource &&
!unit.Type->ResInfo[unit.CurrentResource]->TerrainHarvester) {
Assert(this->Action != UnitActionResource);
}
}
#endif
}
COrder::COrder(const COrder &rhs): Goal(rhs.Goal), Range(rhs.Range),
MinRange(rhs.MinRange), Width(rhs.Width), Height(rhs.Height),
Action(rhs.Action), CurrentResource(rhs.CurrentResource),
goalPos(rhs.goalPos)
{
if (Goal) {
Goal->RefsIncrease();
}
memcpy(&Arg1, &rhs.Arg1, sizeof(Arg1));
memcpy(&Data, &rhs.Data, sizeof (Data));
if (Action == UnitActionResource && Arg1.Resource.Mine) {
Arg1.Resource.Mine->RefsIncrease();
}
}
COrder& COrder::operator=(const COrder &rhs) {
if (this != &rhs) {
Action = rhs.Action;
Range = rhs.Range;
MinRange = rhs.MinRange;
Width = rhs.Width;
Height = rhs.Height;
CurrentResource = rhs.CurrentResource;
SetGoal(rhs.Goal);
goalPos = rhs.goalPos;
memcpy(&Arg1, &rhs.Arg1, sizeof(Arg1));
memcpy(&Data, &rhs.Data, sizeof (Data));
//FIXME: Hardcoded wood
if (Action == UnitActionResource && Arg1.Resource.Mine) {
Arg1.Resource.Mine->RefsIncrease();
}
}
return *this;
}
void COrder::SetGoal(CUnit *const new_goal)
{
if (new_goal) {
new_goal->RefsIncrease();
}
if (Goal) {
Goal->RefsDecrease();
}
Goal = new_goal;
}
void COrder::ClearGoal()
{
if (Goal) {
Goal->RefsDecrease();
}
Goal = NULL;
}
bool COrder::CheckRange() const
{
return (Range <= Map.Info.MapWidth || Range <= Map.Info.MapHeight);
}
/*----------------------------------------------------------------------------
-- Animation
@ -255,7 +370,7 @@ int UnitShowAnimationScaled(CUnit &unit, const CAnimation *anim, int scale)
**
** @param unit Unit pointer for none action.
*/
static void HandleActionNone(CUnit::COrder&, CUnit &unit)
static void HandleActionNone(COrder&, CUnit &unit)
{
DebugPrint("FIXME: Should not happen!\n");
DebugPrint("FIXME: Unit (%d) %s has action none.!\n" _C_
@ -267,7 +382,7 @@ static void HandleActionNone(CUnit::COrder&, CUnit &unit)
**
** @param unit Unit pointer for not written action.
*/
static void HandleActionNotWritten(CUnit::COrder&, CUnit &unit)
static void HandleActionNotWritten(COrder&, CUnit &unit)
{
DebugPrint("FIXME: Not written!\n");
DebugPrint("FIXME: Unit (%d) %s has action %d.!\n" _C_
@ -279,7 +394,7 @@ static void HandleActionNotWritten(CUnit::COrder&, CUnit &unit)
**
** @note can move function into unit structure.
*/
static void (*HandleActionTable[256])(CUnit::COrder&, CUnit &) = {
static void (*HandleActionTable[256])(COrder&, CUnit &) = {
HandleActionNone,
HandleActionStill,
HandleActionStandGround,
@ -465,7 +580,7 @@ static void HandleBuffs(CUnit &unit, int amount)
}
}
static void RunAction(CUnit::COrder &order, CUnit &unit)
static void RunAction(COrder &order, CUnit &unit)
{
HandleActionTable[order.Action](order, unit);
}

View file

@ -224,7 +224,7 @@ void CommandStandGround(CUnit &unit, int flush)
if (unit.Type->Building) {
// FIXME: should find a better way for pending orders.
delete unit.NewOrder;
unit.NewOrder = new CUnit::COrder;
unit.NewOrder = new COrder;
order = unit.NewOrder;
} else if (!(order = GetNextOrder(unit, flush))) {
return;
@ -252,7 +252,7 @@ void CommandFollow(CUnit &unit, CUnit &dest, int flush)
if (!unit.CanMove()) {
// FIXME: should find a better way for pending orders.
delete unit.NewOrder;
unit.NewOrder = new CUnit::COrder;
unit.NewOrder = new COrder;
order = unit.NewOrder;
} else if (!(order = GetNextOrder(unit, flush))) {
return;
@ -295,7 +295,7 @@ void CommandMove(CUnit &unit, const Vec2i &pos, int flush)
if (!unit.CanMove()) {
// FIXME: should find a better way for pending orders.
delete unit.NewOrder;
unit.NewOrder = new CUnit::COrder;
unit.NewOrder = new COrder;
order = unit.NewOrder;
} else if (!(order = GetNextOrder(unit, flush))) {
return;
@ -326,7 +326,7 @@ void CommandRepair(CUnit &unit, const Vec2i &pos, CUnit *dest, int flush)
if (unit.Type->Building) {
// FIXME: should find a better way for pending orders.
delete unit.NewOrder;
unit.NewOrder = new CUnit::COrder;
unit.NewOrder = new COrder;
order = unit.NewOrder;
} else if (!(order = GetNextOrder(unit, flush))) {
return;
@ -390,7 +390,7 @@ void CommandAttack(CUnit &unit, const Vec2i &pos, CUnit *attack, int flush)
if (!unit.Type->CanAttack) {
// FIXME: should find a better way for pending orders.
delete unit.NewOrder;
unit.NewOrder = new CUnit::COrder;
unit.NewOrder = new COrder;
order = unit.NewOrder;
} else if (!(order = GetNextOrder(unit, flush))) {
return;
@ -444,7 +444,7 @@ void CommandAttackGround(CUnit &unit, const Vec2i &pos, int flush)
if (unit.Type->Building) {
// FIXME: should find a better way for pending orders.
delete unit.NewOrder;
unit.NewOrder = new CUnit::COrder;
unit.NewOrder = new COrder;
order = unit.NewOrder;
} else if (!(order = GetNextOrder(unit, flush))) {
return;
@ -483,7 +483,7 @@ void CommandPatrolUnit(CUnit &unit, const Vec2i &pos, int flush)
if (!unit.CanMove()) {
// FIXME: should find a better way for pending orders.
delete unit.NewOrder;
unit.NewOrder = new CUnit::COrder;
unit.NewOrder = new COrder;
order = unit.NewOrder;
} else if (!(order = GetNextOrder(unit, flush))) {
return;
@ -525,7 +525,7 @@ void CommandBoard(CUnit &unit, CUnit &dest, int flush)
if (unit.Type->Building) {
// FIXME: should find a better way for pending orders.
delete unit.NewOrder;
unit.NewOrder = new CUnit::COrder;
unit.NewOrder = new COrder;
order = unit.NewOrder;
} else if (!(order = GetNextOrder(unit, flush))) {
return;
@ -593,7 +593,7 @@ void CommandBuildBuilding(CUnit &unit, const Vec2i &pos, CUnitType &what, int fl
if (unit.Type->Building) {
// FIXME: should find a better way for pending orders.
delete unit.NewOrder;
unit.NewOrder = new CUnit::COrder;
unit.NewOrder = new COrder;
order = unit.NewOrder;
} else if (!(order = GetNextOrder(unit, flush))) {
return;
@ -659,7 +659,7 @@ void CommandResourceLoc(CUnit &unit, const Vec2i &pos, int flush)
if (unit.Type->Building) {
// FIXME: should find a better way for pending orders.
delete unit.NewOrder;
unit.NewOrder = new CUnit::COrder;
unit.NewOrder = new COrder;
order = unit.NewOrder;
} else if (!(order = GetNextOrder(unit, flush))) {
return;
@ -714,7 +714,7 @@ void CommandResource(CUnit &unit, CUnit &dest, int flush)
if (unit.Type->Building) {
// FIXME: should find a better way for pending orders.
delete unit.NewOrder;
unit.NewOrder = new CUnit::COrder;
unit.NewOrder = new COrder;
order = unit.NewOrder;
} else if (!(order = GetNextOrder(unit, flush))) {
return;
@ -751,7 +751,7 @@ void CommandReturnGoods(CUnit &unit, CUnit *goal, int flush)
if (unit.Type->Building) {
// FIXME: should find a better way for pending orders.
delete unit.NewOrder;
unit.NewOrder = new CUnit::COrder;
unit.NewOrder = new COrder;
order = unit.NewOrder;
} else if (!(order = GetNextOrder(unit, flush))) {
return;
@ -925,7 +925,7 @@ void CommandUpgradeTo(CUnit &unit, CUnitType &type, int flush)
*/
void CommandTransformIntoType(CUnit &unit, CUnitType &type)
{
COrderPtr order = new CUnit::COrder;
COrderPtr order = new COrder;
Assert(unit.CriticalOrder == NULL);

View file

@ -746,7 +746,7 @@ void AiHelpMe(const CUnit *attacker, CUnit &defender)
&& CanTarget(aiunit->Type, attacker->Type)) {
CommandAttack(*aiunit, attacker->tilePos, const_cast<CUnit*>(attacker), FlushCommands);
if (aiunit->SavedOrder == NULL) {
CUnit::COrder *savedOrder = new CUnit::COrder;
COrder *savedOrder = new COrder;
savedOrder->Action = UnitActionAttack;
savedOrder->Range = 0;

View file

@ -271,7 +271,7 @@ public:
public:
CUnit *Unit;
CUnit::COrder Order;
COrder Order;
};
/**

View file

@ -52,12 +52,161 @@ enum _diplomacy_ {
DiplomacyCrazy /// Ally and attack opponent
}; /// Diplomacy states for CommandDiplomacy
/**
** All possible unit actions.
**
** @note Always change the table ::HandleActionTable
**
** @see HandleActionTable
*/
enum UnitAction {
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
UnitActionUpgradeTo, /// building is upgrading itself
UnitActionResearch, /// building is researching spell
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
UnitActionReturnGoods, /// unit returning any resource
UnitActionTransformInto /// unit transform into type.
};
class CConstructionFrame;
class CUnit;
class CUnitType;
class CUpgrade;
class SpellType;
class CAnimation;
/**
** Unit order structure.
*/
class COrder
{
public:
COrder() : Goal(NULL), Range(0), MinRange(0), Width(0),
Height(0), Action(UnitActionNone), CurrentResource(0)
{
goalPos.x = -1;
goalPos.y = -1;
memset(&Arg1, 0, sizeof (Arg1));
memset(&Data, 0, sizeof (Data));
}
COrder(const COrder &ths);
~COrder();
void ReleaseRefs(CUnit &owner);
COrder& operator=(const COrder &rhs);
bool CheckRange() const;
void Init() {
Assert(Action != UnitActionResource
|| (Action == UnitActionResource && Arg1.Resource.Mine == NULL));
Action = UnitActionNone;
Range = 0;
MinRange = 0;
Width = 0;
Height = 0;
CurrentResource = 0;
Assert(!Goal);
goalPos.x = -1;
goalPos.y = -1;
memset(&Arg1, 0, sizeof(Arg1));
memset(&Data, 0, sizeof(Data));
};
bool HasGoal() const { return Goal != NULL; }
CUnit * GetGoal() const { return Goal; };
void SetGoal(CUnit *const new_goal);
void ClearGoal();
private:
friend void CclParseOrder(lua_State *l, const CUnit &unit, COrder* order);
CUnit *Goal;
public:
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)
unsigned char Action; /// global action
unsigned char CurrentResource; //used in UnitActionResource and
//UnitActionReturnGoods
Vec2i goalPos; /// or tile coordinate of destination
union {
Vec2i Patrol; /// position for patroling.
struct {
Vec2i Pos; /// position for terrain resource.
CUnit *Mine;
} Resource;
SpellType *Spell; /// spell when casting.
CUpgrade *Upgrade; /// upgrade.
CUnitType *Type; /// Unit-type argument used mostly for traning/building, etc.
} Arg1; /// Extra command argument.
union _order_data_ {
struct _order_move_ {
unsigned short int Cycles; /// how much Cycles we move.
char Fast; /// Flag fast move (one step)
char Length; /// stored path length
#define MAX_PATH_LENGTH 28 /// max length of precalculated path
char Path[MAX_PATH_LENGTH]; /// directions of stored path
} Move; /// ActionMove,...
struct _order_built_ {
CUnit *Worker; /// Worker building this unit
int Progress; /// Progress counter, in 1/100 cycles.
int Cancel; /// Cancel construction
CConstructionFrame *Frame; /// Construction frame
} Built; /// ActionBuilt,...
struct _order_build_ {
int Cycles; /// Cycles unit has been building for
} Build; /// ActionBuild
struct _order_resource_ {
CUnit *Workers; //pointer to first assigned worker to this resource.
int Assigned; /// how many units are assigned to harvesting from the resource.
int Active; /// how many units are harvesting from the resource.
} Resource; /// Resource still
struct _order_resource_worker_ {
int TimeToHarvest; /// how much time until we harvest some more.
unsigned DoneHarvesting:1; /// Harvesting done, wait for action to break.
} ResWorker; /// Worker harvesting
struct _order_repair_ {
int Cycles; /// Cycles unit has been repairing for
} Repair; /// Repairing unit
struct _order_research_ {
CUpgrade *Upgrade; /// Upgrade researched
} Research; /// Research action
struct _order_upgradeto_ {
int Ticks; /// Ticks to complete
} UpgradeTo; /// Upgrade to action
struct _order_train_ {
int Ticks; /// Ticks to complete
} Train; /// Train units action
} Data; /// Storage room for different commands
};
/*----------------------------------------------------------------------------
-- Variables
@ -151,7 +300,7 @@ extern int GetNumWaitingWorkers(const CUnit &mine);
extern void AutoAttack(CUnit &unit, CUnitCache &targets, bool stand_ground);
extern void UnHideUnit(CUnit &unit);
typedef void HandleActionFunc(CUnit::COrder& order, CUnit &unit);
typedef void HandleActionFunc(COrder& order, CUnit &unit);
/// Generic still action
extern void ActionStillGeneric(CUnit &unit, bool stand_ground);

View file

@ -365,12 +365,15 @@
#include "player.h"
#endif
#include "actions.h"
#include "vec2i.h"
/*----------------------------------------------------------------------------
-- Declarations
----------------------------------------------------------------------------*/
class COrder;
class CUnit;
class CUnitType;
class CUnitStats;
@ -432,43 +435,6 @@ extern int MapDistanceBetweenTypes(const CUnitType &src, const Vec2i &pos1,
*/
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
UnitActionUpgradeTo, /// building is upgrading itself
UnitActionResearch, /// building is researching spell
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
UnitActionReturnGoods, /// unit returning any resource
UnitActionTransformInto /// unit transform into type.
} UnitAction;
/**
** Voice groups for a unit
*/
@ -512,203 +478,9 @@ enum _directions_ {
/// The big unit structure
class CUnit {
public:
/**
** Unit order structure.
*/
class COrder
{
public:
COrder() : Goal(NULL), Range(0), MinRange(0), Width(0),
Height(0), Action(UnitActionNone), CurrentResource(0)
{
goalPos.x = -1;
goalPos.y = -1;
memset(&Arg1, 0, sizeof (Arg1));
memset(&Data, 0, sizeof (Data));
}
COrder(const COrder &ths);
~COrder();
void ReleaseRefs(CUnit &owner);
COrder& operator=(const COrder &rhs);
bool CheckRange() const;
void Init() {
Assert(Action != UnitActionResource
|| (Action == UnitActionResource && Arg1.Resource.Mine == NULL));
Action = UnitActionNone;
Range = 0;
MinRange = 0;
Width = 0;
Height = 0;
CurrentResource = 0;
Assert(!Goal);
goalPos.x = -1;
goalPos.y = -1;
memset(&Arg1, 0, sizeof(Arg1));
memset(&Data, 0, sizeof(Data));
};
bool HasGoal() const { return Goal != NULL; }
CUnit * GetGoal() const { return Goal; };
void SetGoal(CUnit *const new_goal)
{
if (new_goal) {
new_goal->RefsIncrease();
}
if (Goal) {
Goal->RefsDecrease();
}
Goal = new_goal;
}
void ClearGoal()
{
if (Goal) {
Goal->RefsDecrease();
}
Goal = NULL;
}
private:
friend void CclParseOrder(lua_State *l, const CUnit &unit, COrder* order);
CUnit *Goal;
public:
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)
unsigned char Action; /// global action
unsigned char CurrentResource; //used in UnitActionResource and
//UnitActionReturnGoods
Vec2i goalPos; /// or tile coordinate of destination
union {
Vec2i Patrol; /// position for patroling.
struct {
Vec2i Pos; /// position for terrain resource.
CUnit *Mine;
} Resource;
SpellType *Spell; /// spell when casting.
CUpgrade *Upgrade; /// upgrade.
CUnitType *Type; /// Unit-type argument used mostly for traning/building, etc.
} Arg1; /// Extra command argument.
union _order_data_ {
struct _order_move_ {
unsigned short int Cycles; /// how much Cycles we move.
char Fast; /// Flag fast move (one step)
char Length; /// stored path length
#define MAX_PATH_LENGTH 28 /// max length of precalculated path
char Path[MAX_PATH_LENGTH]; /// directions of stored path
} Move; /// ActionMove,...
struct _order_built_ {
CUnit *Worker; /// Worker building this unit
int Progress; /// Progress counter, in 1/100 cycles.
int Cancel; /// Cancel construction
CConstructionFrame *Frame; /// Construction frame
} Built; /// ActionBuilt,...
struct _order_build_ {
int Cycles; /// Cycles unit has been building for
} Build; /// ActionBuild
struct _order_resource_ {
CUnit *Workers; //pointer to first assigned worker to this resource.
int Assigned; /// how many units are assigned to harvesting from the resource.
int Active; /// how many units are harvesting from the resource.
} Resource; /// Resource still
struct _order_resource_worker_ {
int TimeToHarvest; /// how much time until we harvest some more.
unsigned DoneHarvesting:1; /// Harvesting done, wait for action to break.
} ResWorker; /// Worker harvesting
struct _order_repair_ {
int Cycles; /// Cycles unit has been repairing for
} Repair; /// Repairing unit
struct _order_research_ {
CUpgrade *Upgrade; /// Upgrade researched
} Research; /// Research action
struct _order_upgradeto_ {
int Ticks; /// Ticks to complete
} UpgradeTo; /// Upgrade to action
struct _order_train_ {
int Ticks; /// Ticks to complete
} Train; /// Train units action
} Data; /// Storage room for different commands
};
CUnit() : SavedOrder(NULL), NewOrder(NULL), CriticalOrder(NULL) { Init(); }
void Init() {
Refs = 0;
Slot = 0;
UnitSlot = NULL;
PlayerSlot = NULL;
Next = NULL;
InsideCount = 0;
BoardCount = 0;
UnitInside = NULL;
Container = NULL;
NextContained = NULL;
PrevContained = NULL;
NextWorker = NULL;
tilePos.x = 0;
tilePos.y = 0;
Offset = 0;
Type = NULL;
Player = NULL;
Stats = NULL;
CurrentSightRange = 0;
Colors = NULL;
IX = 0;
IY = 0;
Frame = 0;
Direction = 0;
DamagedType = ANIMATIONS_DEATHTYPES;
Attacked = 0;
Burning = 0;
Destroyed = 0;
Removed = 0;
Selected = 0;
TeamSelected = 0;
Constructed = 0;
Active = 0;
Boarded = 0;
RescuedFrom = NULL;
memset(VisCount, 0, sizeof(VisCount));
memset(&Seen, 0, sizeof(Seen));
Variable = NULL;
TTL = 0;
GroupId = 0;
LastGroup = 0;
ResourcesHeld = 0;
SubAction = 0;
Wait = 0;
State = 0;
Blink = 0;
Moving = 0;
ReCast = 0;
CacheLock = 0;
GuardLock = 0;
memset(&Anim, 0, sizeof(Anim));
CurrentResource = 0;
OrderCount = 0;
OrderFlush = 0;
Orders.clear();
delete SavedOrder;
SavedOrder = NULL;
delete NewOrder;
NewOrder = NULL;
delete CriticalOrder;
CriticalOrder = NULL;
AutoCastSpell = NULL;
AutoRepair = 0;
Goal = NULL;
}
void Init();
// @note int is faster than shorts
unsigned int Refs; /// Reference counter
int Slot; /// Assigned slot number
@ -817,24 +589,15 @@ public:
CUnit *Goal; /// Generic/Teleporter goal pointer
COrder * CreateOrder() {
Orders.push_back(new COrder);
return Orders[(int)OrderCount++];
}
COrder *CreateOrder();
COrder *CurrentOrder() const { return Orders[0]; }
UnitAction CurrentAction() const { return (UnitAction)(CurrentOrder()->Action); }
unsigned int CurrentAction() const;
bool IsIdle() const { return OrderCount == 1 && CurrentAction() == UnitActionStill; }
bool IsIdle() const;
inline void ClearAction() {
CurrentOrder()->Action = UnitActionStill;
SubAction = 0;
if (Selected) {
SelectedUnitChanged();
}
}
void ClearAction();
inline int GetReactRange() const
{
@ -874,7 +637,7 @@ public:
void Release(bool final = false);
bool RestoreOrder();
bool StoreOrder(CUnit::COrder* order);
bool StoreOrder(COrder* order);
// Cowards and invisible units don't attack unless ordered.
bool IsAgressive() const
@ -898,10 +661,7 @@ public:
**
** @return True if alive, false otherwise.
*/
inline bool IsAlive() const
{
return !Destroyed && CurrentAction() != UnitActionDie;
}
bool IsAlive() const;
/**
** Returns true if unit is alive and on the map.
@ -1009,22 +769,14 @@ public:
** Test if unit can move.
** For the moment only check for move animation.
**
** @return 0 if unit cannot move.
** @return true if unit cann move.
*/
bool CanMove() const
{
return Type->CanMove();
}
int GetDrawLevel() const
{
return ((Type->CorpseType && CurrentAction() == UnitActionDie) ?
Type->CorpseType->DrawLevel : Type->DrawLevel);
}
bool CanMove() const { return Type->CanMove(); }
int GetDrawLevel() const;
};
typedef CUnit::COrder* COrderPtr;
typedef COrder* COrderPtr;
class CUnitPtr {
CUnit *unit;
@ -1351,7 +1103,7 @@ extern int CanTransport(const CUnit &transporter, const CUnit &unit);
/// Generate a unit reference, a printable unique string for unit
extern std::string UnitReference(const CUnit &unit);
/// Save an order
extern void SaveOrder(const CUnit::COrder &order, const CUnit &unit, CFile *file);
extern void SaveOrder(const COrder &order, const CUnit &unit, CFile *file);
/// save unit-structure
extern void SaveUnit(const CUnit &unit, CFile *file);
/// save all units

View file

@ -307,7 +307,7 @@ void GroupHelpMe(CUnit *attacker, CUnit &defender)
&& CanTarget(gunit.Type, attacker->Type)) {
CommandAttack(gunit, attacker->tilePos, attacker, FlushCommands);
if (gunit.SavedOrder == NULL) {
CUnit::COrder *savedOrder = new CUnit::COrder;
COrder *savedOrder = new COrder;
savedOrder->Action = UnitActionAttack;
savedOrder->goalPos = gunit.tilePos;

View file

@ -883,17 +883,17 @@ static int CclUnit(lua_State *l)
}
} else if (!strcmp(value, "critical-order")) {
lua_pushvalue(l, j + 1);
unit->CriticalOrder = new CUnit::COrder;
unit->CriticalOrder = new COrder;
CclParseOrder(l, *unit , unit->CriticalOrder);
lua_pop(l, 1);
} else if (!strcmp(value, "saved-order")) {
lua_pushvalue(l, j + 1);
unit->SavedOrder = new CUnit::COrder;
unit->SavedOrder = new COrder;
CclParseOrder(l, *unit, unit->SavedOrder);
lua_pop(l, 1);
} else if (!strcmp(value, "new-order")) {
lua_pushvalue(l, j + 1);
unit->NewOrder = new CUnit::COrder;
unit->NewOrder = new COrder;
CclParseOrder(l, *unit, unit->NewOrder);
lua_pop(l, 1);
} else if (!strcmp(value, "goal")) {

View file

@ -121,97 +121,72 @@ void CUnit::RefsDecrease()
}
}
CUnit::COrder::~COrder() {
if (Goal) {
Goal->RefsDecrease();
Goal = NoUnitP;
}
if (Action == UnitActionResource && Arg1.Resource.Mine) {
Arg1.Resource.Mine->RefsDecrease();
Arg1.Resource.Mine = NoUnitP;
}
}
void CUnit::COrder::ReleaseRefs(CUnit &unit)
void CUnit::Init()
{
// Release pending references.
if (this->Action == UnitActionResource) {
CUnit *mine = this->Arg1.Resource.Mine;
if (mine) {
unit.DeAssignWorkerFromMine(*mine);
mine->RefsDecrease();
this->Arg1.Resource.Mine = NULL;
}
}
if (this->HasGoal()) {
// If mining decrease the active count on the resource.
if (this->Action == UnitActionResource) {
if (unit.SubAction == 60 /* SUB_GATHER_RESOURCE */ ) {
CUnit *goal = this->GetGoal();
goal->CurrentOrder()->Data.Resource.Active--;
Assert(goal->CurrentOrder()->Data.Resource.Active >= 0);
}
}
// Still shouldn't have a reference unless attacking
Assert(!(this->Action == UnitActionStill && !unit.SubAction));
this->ClearGoal();
}
#ifdef DEBUG
else {
if (unit.CurrentResource &&
!unit.Type->ResInfo[unit.CurrentResource]->TerrainHarvester) {
Assert(this->Action != UnitActionResource);
}
}
#endif
}
CUnit::COrder::COrder(const CUnit::COrder &rhs): Goal(rhs.Goal), Range(rhs.Range),
MinRange(rhs.MinRange), Width(rhs.Width), Height(rhs.Height),
Action(rhs.Action), CurrentResource(rhs.CurrentResource),
goalPos(rhs.goalPos)
{
if (Goal) {
Goal->RefsIncrease();
}
memcpy(&Arg1, &rhs.Arg1, sizeof(Arg1));
memcpy(&Data, &rhs.Data, sizeof (Data));
if (Action == UnitActionResource && Arg1.Resource.Mine) {
Arg1.Resource.Mine->RefsIncrease();
}
}
CUnit::COrder& CUnit::COrder::operator=(const CUnit::COrder &rhs) {
if (this != &rhs) {
Action = rhs.Action;
Range = rhs.Range;
MinRange = rhs.MinRange;
Width = rhs.Width;
Height = rhs.Height;
CurrentResource = rhs.CurrentResource;
SetGoal(rhs.Goal);
goalPos = rhs.goalPos;
memcpy(&Arg1, &rhs.Arg1, sizeof(Arg1));
memcpy(&Data, &rhs.Data, sizeof (Data));
//FIXME: Hardcoded wood
if (Action == UnitActionResource && Arg1.Resource.Mine) {
Arg1.Resource.Mine->RefsIncrease();
}
}
return *this;
}
bool CUnit::COrder::CheckRange() const
{
return (Range <= Map.Info.MapWidth || Range <= Map.Info.MapHeight);
Refs = 0;
Slot = 0;
UnitSlot = NULL;
PlayerSlot = NULL;
Next = NULL;
InsideCount = 0;
BoardCount = 0;
UnitInside = NULL;
Container = NULL;
NextContained = NULL;
PrevContained = NULL;
NextWorker = NULL;
tilePos.x = 0;
tilePos.y = 0;
Offset = 0;
Type = NULL;
Player = NULL;
Stats = NULL;
CurrentSightRange = 0;
Colors = NULL;
IX = 0;
IY = 0;
Frame = 0;
Direction = 0;
DamagedType = ANIMATIONS_DEATHTYPES;
Attacked = 0;
Burning = 0;
Destroyed = 0;
Removed = 0;
Selected = 0;
TeamSelected = 0;
Constructed = 0;
Active = 0;
Boarded = 0;
RescuedFrom = NULL;
memset(VisCount, 0, sizeof(VisCount));
memset(&Seen, 0, sizeof(Seen));
Variable = NULL;
TTL = 0;
GroupId = 0;
LastGroup = 0;
ResourcesHeld = 0;
SubAction = 0;
Wait = 0;
State = 0;
Blink = 0;
Moving = 0;
ReCast = 0;
CacheLock = 0;
GuardLock = 0;
memset(&Anim, 0, sizeof(Anim));
CurrentResource = 0;
OrderCount = 0;
OrderFlush = 0;
Orders.clear();
delete SavedOrder;
SavedOrder = NULL;
delete NewOrder;
NewOrder = NULL;
delete CriticalOrder;
CriticalOrder = NULL;
AutoCastSpell = NULL;
AutoRepair = 0;
Goal = NULL;
}
@ -280,6 +255,46 @@ void CUnit::Release(bool final)
UnitManager.ReleaseUnit(this);
}
COrder *CUnit::CreateOrder()
{
Orders.push_back(new COrder);
return Orders[(int)OrderCount++];
}
unsigned int CUnit::CurrentAction() const
{
return (CurrentOrder()->Action);
}
void CUnit::ClearAction()
{
CurrentOrder()->Action = UnitActionStill;
SubAction = 0;
if (Selected) {
SelectedUnitChanged();
}
}
bool CUnit::IsIdle() const
{
return OrderCount == 1 && CurrentAction() == UnitActionStill;
}
bool CUnit::IsAlive() const
{
return !Destroyed && CurrentAction() != UnitActionDie;
}
int CUnit::GetDrawLevel() const
{
return ((Type->CorpseType && CurrentAction() == UnitActionDie) ?
Type->CorpseType->DrawLevel : Type->DrawLevel);
}
/**
** Initialize the unit slot with default values.
**
@ -380,7 +395,7 @@ bool CUnit::RestoreOrder()
**
** @return True if the current order was saved
*/
bool CUnit::StoreOrder(CUnit::COrder* order)
bool CUnit::StoreOrder(COrder* order)
{
Assert(order);
Assert(order->HasGoal() || Map.Info.IsPointOnMap(order->goalPos));
@ -3002,7 +3017,7 @@ void HitUnit(CUnit *attacker, CUnit &target, int damage)
}
if (goal) {
if (target.SavedOrder == NULL) {
CUnit::COrder* savedOrder = new CUnit::COrder;
COrder* savedOrder = new COrder;
savedOrder->Action = UnitActionAttack;
savedOrder->goalPos = target.tilePos;

View file

@ -68,7 +68,7 @@ std::string UnitReference(const CUnit &unit)
** @param unit Order behave to this unit.
** @param file Output file.
*/
void SaveOrder(const CUnit::COrder &order, const CUnit &unit, CFile *file)
void SaveOrder(const COrder &order, const CUnit &unit, CFile *file)
{
file->printf("{");
switch (order.Action) {