Move CUnit::OrderFlush into COrder::Finished
some clean up
This commit is contained in:
parent
77334d3533
commit
c8d9a9f20c
22 changed files with 278 additions and 458 deletions
|
@ -47,6 +47,15 @@
|
|||
#include "iolib.h"
|
||||
#include "script.h"
|
||||
|
||||
|
||||
|
||||
enum {
|
||||
State_Init = 0,
|
||||
State_MoveToTransporterMax = 200, // Range from previous
|
||||
State_WaitForTransporter = 201,
|
||||
State_EnterTransporter = 202
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
@ -55,6 +64,9 @@
|
|||
{
|
||||
file.printf("{\"action-board\",");
|
||||
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
file.printf(" \"range\", %d,", this->Range);
|
||||
if (this->HasGoal()) {
|
||||
CUnit &goal = *this->GetGoal();
|
||||
|
@ -152,7 +164,7 @@ bool COrder_Board::WaitForTransporter(CUnit &unit)
|
|||
// is not there. The unit searches with a big range, so it thinks
|
||||
// it's there. This is why we reset the search. The transporter
|
||||
// should be a lot closer now, so it's not as bad as it seems.
|
||||
this->State = 0;
|
||||
this->State = State_Init;
|
||||
this->Range = 1;
|
||||
// Uhh wait a bit.
|
||||
unit.Wait = 10;
|
||||
|
@ -194,39 +206,40 @@ static void EnterTransporter(CUnit &unit, COrder_Board &order)
|
|||
DebugPrint("No free slot in transporter\n");
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Board::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_Board::Execute(CUnit &unit)
|
||||
{
|
||||
switch (this->State) {
|
||||
// Wait for transporter
|
||||
case 201:
|
||||
case State_WaitForTransporter:
|
||||
if (this->WaitForTransporter(unit)) {
|
||||
this->State = 202;
|
||||
this->State = State_EnterTransporter;
|
||||
} else {
|
||||
UnitShowAnimation(unit, unit.Type->Animations->Still);
|
||||
}
|
||||
break;
|
||||
// Enter transporter
|
||||
case 202:
|
||||
|
||||
case State_EnterTransporter: {
|
||||
EnterTransporter(unit, *this);
|
||||
return true;
|
||||
break;
|
||||
// Move to transporter
|
||||
case 0:
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
case State_Init:
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
this->NewResetPath();
|
||||
this->State = 1;
|
||||
// FALL THROUGH
|
||||
default:
|
||||
if (this->State <= 200) {
|
||||
default: { // Move to transporter
|
||||
if (this->State <= State_MoveToTransporterMax) {
|
||||
const int pathRet = MoveToTransporter(unit);
|
||||
// FIXME: if near transporter wait for enter
|
||||
if (pathRet) {
|
||||
if (pathRet == PF_UNREACHABLE) {
|
||||
if (++this->State == 200) {
|
||||
return true;
|
||||
if (++this->State == State_MoveToTransporterMax) {
|
||||
this->Finished = true;
|
||||
return;
|
||||
} else {
|
||||
// Try with a bigger range.
|
||||
if (this->CheckRange()) {
|
||||
|
@ -235,27 +248,14 @@ static void EnterTransporter(CUnit &unit, COrder_Board &order)
|
|||
}
|
||||
}
|
||||
} else if (pathRet == PF_REACHED) {
|
||||
this->State = 201;
|
||||
this->State = State_WaitForTransporter;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
** The unit boards a transporter.
|
||||
**
|
||||
** @todo FIXME: While waiting for the transporter the units must defend themselves.
|
||||
**
|
||||
** @param unit Pointer to unit.
|
||||
*/
|
||||
void HandleActionBoard(COrder& order, CUnit &unit)
|
||||
{
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -74,6 +74,10 @@ enum
|
|||
/* virtual */ void COrder_Build::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-build\",");
|
||||
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
file.printf(" \"range\", %d,", this->Range);
|
||||
#if 1 // Fixed with Type
|
||||
file.printf(" \"width\", %d,", this->Width);
|
||||
|
@ -371,22 +375,24 @@ bool COrder_Build::BuildFromOutside(CUnit &unit) const
|
|||
}
|
||||
|
||||
|
||||
/* virtual */ bool COrder_Build::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_Build::Execute(CUnit &unit)
|
||||
{
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
if (this->State <= State_MoveToLocationMax) {
|
||||
if (this->MoveToLocation(unit)) {
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
const CUnitType &type = this->GetUnitType();
|
||||
|
||||
if (State_NearOfLocation <= this->State && this->State < State_StartBuilding_Failed) {
|
||||
if (CheckLimit(unit, type) == false) {
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
CUnit *ontop = this->CheckCanBuild(unit);
|
||||
|
||||
|
@ -400,31 +406,14 @@ bool COrder_Build::BuildFromOutside(CUnit &unit) const
|
|||
if (unit.Player->AiEnabled) {
|
||||
AiCanNotBuild(unit, type);
|
||||
}
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
if (this->State == State_BuildFromOutside) {
|
||||
this->BuildFromOutside(unit);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
** Unit builds a building.
|
||||
**
|
||||
** @param unit Unit that builds a building
|
||||
*/
|
||||
void HandleActionBuild(COrder& order, CUnit &unit)
|
||||
{
|
||||
Assert(order.Action == UnitActionBuild);
|
||||
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// Action_built
|
||||
|
@ -433,7 +422,9 @@ void HandleActionBuild(COrder& order, CUnit &unit)
|
|||
/* virtual */ void COrder_Built::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-built\", ");
|
||||
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
CConstructionFrame *cframe = unit.Type->Construction->Frames;
|
||||
int frame = 0;
|
||||
while (cframe != this->Frame) {
|
||||
|
@ -501,7 +492,7 @@ static void CancelBuilt(COrder_Built &order, CUnit &unit)
|
|||
LetUnitDie(unit);
|
||||
}
|
||||
|
||||
static bool Finish(COrder_Built &order, CUnit& unit)
|
||||
static void Finish(COrder_Built &order, CUnit& unit)
|
||||
{
|
||||
const CUnitType &type = *unit.Type;
|
||||
CPlayer &player = *unit.Player;
|
||||
|
@ -565,7 +556,7 @@ static bool Finish(COrder_Built &order, CUnit& unit)
|
|||
UnitLost(unit);
|
||||
UnitClearOrders(unit);
|
||||
unit.Release();
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
|
||||
UpdateForNewUnit(unit, 0);
|
||||
|
@ -587,11 +578,11 @@ static bool Finish(COrder_Built &order, CUnit& unit)
|
|||
MapUnmarkUnitSight(unit);
|
||||
unit.CurrentSightRange = unit.Stats->Variables[SIGHTRANGE_INDEX].Max;
|
||||
MapMarkUnitSight(unit);
|
||||
return true;
|
||||
order.Finished = true;
|
||||
}
|
||||
|
||||
|
||||
/* virtual */ bool COrder_Built::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_Built::Execute(CUnit &unit)
|
||||
{
|
||||
const CUnitType &type = *unit.Type;
|
||||
|
||||
|
@ -610,16 +601,16 @@ static bool Finish(COrder_Built &order, CUnit& unit)
|
|||
DebugPrint("%d: %s canceled.\n" _C_ unit.Player->Index _C_ unit.Type->Name.c_str());
|
||||
|
||||
CancelBuilt(*this, unit);
|
||||
return false;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
|
||||
const int maxProgress = type.Stats[unit.Player->Index].Costs[TimeCost] * 600;
|
||||
|
||||
// Check if building ready. Note we can both build and repair.
|
||||
if (!unit.Anim.Unbreakable && this->ProgressCounter >= maxProgress) {
|
||||
return Finish(*this, unit);
|
||||
Finish(*this, unit);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_Built::Cancel(CUnit &unit)
|
||||
|
@ -734,21 +725,4 @@ void COrder_Built::Boost(CUnit &building, int amount, int varIndex) const
|
|||
currentValue = std::min(currentValue, maxValue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
** Unit under Construction
|
||||
**
|
||||
** @param unit Unit that is being built
|
||||
*/
|
||||
void HandleActionBuilt(COrder& order, CUnit &unit)
|
||||
{
|
||||
Assert(order.Action == UnitActionBuilt);
|
||||
|
||||
if (order.Execute(unit)) {
|
||||
order.ClearGoal();
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -49,7 +49,11 @@
|
|||
|
||||
/* virtual */ void COrder_Die::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-die\"}");
|
||||
file.printf("{\"action-die\"");
|
||||
if (this->Finished) {
|
||||
file.printf(", \"finished\"");
|
||||
}
|
||||
file.printf("}");
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Die::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit)
|
||||
|
@ -75,7 +79,7 @@ static bool AnimateActionDie(CUnit &unit)
|
|||
}
|
||||
|
||||
|
||||
/* virtual */ bool COrder_Die::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_Die::Execute(CUnit &unit)
|
||||
{
|
||||
// Show death animation
|
||||
if (AnimateActionDie(unit) == false) {
|
||||
|
@ -83,7 +87,7 @@ static bool AnimateActionDie(CUnit &unit)
|
|||
unit.Anim.Unbreakable = 0;
|
||||
}
|
||||
if (unit.Anim.Unbreakable) {
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
CUnitType &type = *unit.Type;
|
||||
|
||||
|
@ -91,7 +95,7 @@ static bool AnimateActionDie(CUnit &unit)
|
|||
if (type.CorpseType == NULL) {
|
||||
unit.Remove(NULL);
|
||||
unit.Release();
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
|
||||
CUnitType &corpseType = *type.CorpseType;
|
||||
|
@ -109,22 +113,6 @@ static bool AnimateActionDie(CUnit &unit)
|
|||
unit.Frame = 0;
|
||||
UnitUpdateHeading(unit);
|
||||
AnimateActionDie(unit); // with new corpse.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** Unit dies!
|
||||
**
|
||||
** @param unit The unit which dies.
|
||||
*/
|
||||
void HandleActionDie(COrder& order, CUnit &unit)
|
||||
{
|
||||
Assert(order.Action == UnitActionDie);
|
||||
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -45,6 +45,15 @@
|
|||
#include "iolib.h"
|
||||
#include "script.h"
|
||||
|
||||
enum {
|
||||
State_Init = 0,
|
||||
State_Initialized = 1,
|
||||
|
||||
State_TargetReached = 128,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
@ -54,6 +63,9 @@
|
|||
{
|
||||
file.printf("{\"action-follow\",");
|
||||
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
file.printf(" \"range\", %d,", this->Range);
|
||||
if (this->HasGoal()) {
|
||||
CUnit &goal = *this->GetGoal();
|
||||
|
@ -87,26 +99,28 @@
|
|||
return true;
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Follow::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_Follow::Execute(CUnit &unit)
|
||||
{
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
CUnit *goal = this->GetGoal();
|
||||
|
||||
// Reached target
|
||||
if (this->State == 128) {
|
||||
if (this->State == State_TargetReached) {
|
||||
|
||||
if (!goal || !goal->IsVisibleAsGoal(*unit.Player)) {
|
||||
DebugPrint("Goal gone\n");
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
|
||||
if (goal->tilePos == this->goalPos) {
|
||||
// Move to the next order
|
||||
if (unit.Orders.size() > 1) {
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
|
||||
// Reset frame to still frame while we wait
|
||||
|
@ -116,14 +130,14 @@
|
|||
unit.Wait = 10;
|
||||
if (this->Range > 1) {
|
||||
this->Range = 1;
|
||||
this->State = 0;
|
||||
this->State = State_Init;
|
||||
}
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
this->State = 0;
|
||||
this->State = State_Init;
|
||||
}
|
||||
if (!this->State) { // first entry
|
||||
this->State = 1;
|
||||
if (this->State == State_Init) { // first entry
|
||||
this->State = State_Initialized;
|
||||
this->NewResetPath();
|
||||
}
|
||||
switch (DoActionMove(unit)) { // reached end-point?
|
||||
|
@ -137,7 +151,8 @@
|
|||
case PF_REACHED:
|
||||
{
|
||||
if (!goal) { // goal has died
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
// Handle Teleporter Units
|
||||
// FIXME: BAD HACK
|
||||
|
@ -163,24 +178,24 @@
|
|||
|| (dest.NewOrder->Action == UnitActionResource && !unit.Type->Harvester)
|
||||
|| (dest.NewOrder->Action == UnitActionAttack && !unit.Type->CanAttack)
|
||||
|| (dest.NewOrder->Action == UnitActionBoard && unit.Type->UnitType != UnitTypeLand)) {
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
} else {
|
||||
if (dest.NewOrder->HasGoal()) {
|
||||
if (dest.NewOrder->GetGoal()->Destroyed) {
|
||||
delete dest.NewOrder;
|
||||
dest.NewOrder = NULL;
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
delete unit.CurrentOrder();
|
||||
unit.Orders[0] = dest.NewOrder->Clone();
|
||||
unit.CurrentResource = dest.CurrentResource;
|
||||
return false;
|
||||
unit.Orders.insert(unit.Orders.begin() + 1, dest.NewOrder->Clone());
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
this->goalPos = goal->tilePos;
|
||||
this->State = 128;
|
||||
this->State = State_TargetReached;
|
||||
}
|
||||
// FALL THROUGH
|
||||
default:
|
||||
|
@ -197,7 +212,7 @@
|
|||
}
|
||||
|
||||
if (unit.Anim.Unbreakable) {
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
// If our leader is dead or stops or attacks:
|
||||
// Attack any enemy in reaction range.
|
||||
|
@ -210,23 +225,15 @@
|
|||
// Save current command to come back.
|
||||
COrder *savedOrder = this->Clone();
|
||||
|
||||
CommandAttack(unit, target->tilePos, NULL, FlushCommands);
|
||||
this->Finished = true;
|
||||
unit.Orders.insert(unit.Orders.begin() + 1, COrder::NewActionAttack(unit, target->tilePos));
|
||||
|
||||
if (unit.StoreOrder(savedOrder) == false) {
|
||||
delete savedOrder;
|
||||
savedOrder = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void HandleActionFollow(COrder& order, CUnit &unit)
|
||||
{
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -59,6 +59,9 @@
|
|||
{
|
||||
file.printf("{\"action-move\",");
|
||||
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
file.printf(" \"range\", %d,", this->Range);
|
||||
file.printf(" \"tile\", {%d, %d},", this->goalPos.x, this->goalPos.y);
|
||||
|
||||
|
@ -178,13 +181,13 @@ int DoActionMove(CUnit &unit)
|
|||
}
|
||||
|
||||
|
||||
/* virtual */ bool COrder_Move::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_Move::Execute(CUnit &unit)
|
||||
{
|
||||
Assert(unit.CanMove());
|
||||
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
// FIXME: (mr-russ) Make a reachable goal here with GoalReachable ...
|
||||
|
||||
|
@ -193,22 +196,17 @@ int DoActionMove(CUnit &unit)
|
|||
// Some tries to reach the goal
|
||||
if (this->CheckRange()) {
|
||||
this->Range++;
|
||||
break;
|
||||
} else {
|
||||
this->Finished = true;
|
||||
}
|
||||
// FALL THROUGH
|
||||
break;
|
||||
|
||||
case PF_REACHED:
|
||||
return true;
|
||||
this->Finished = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void HandleActionMove(COrder& order, CUnit &unit)
|
||||
{
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -54,6 +54,9 @@
|
|||
{
|
||||
file.printf("{\"action-patrol\",");
|
||||
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
file.printf(" \"tile\", {%d, %d},", this->goalPos.x, this->goalPos.y);
|
||||
file.printf(" \"range\", %d,", this->Range);
|
||||
|
||||
|
@ -85,11 +88,11 @@
|
|||
return true;
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Patrol::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_Patrol::Execute(CUnit &unit)
|
||||
{
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
|
||||
switch (DoActionMove(unit)) {
|
||||
|
@ -130,30 +133,9 @@
|
|||
|
||||
if (!unit.Anim.Unbreakable) {
|
||||
if (AutoAttack(unit) || AutoRepair(unit) || AutoCast(unit)) {
|
||||
return true;
|
||||
this->Finished = true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
** Unit Patrol:
|
||||
** The unit patrols between two points.
|
||||
** Any enemy unit in reaction range is attacked.
|
||||
** @todo FIXME:
|
||||
** Should do some tries to reach the end-points.
|
||||
** Should support patrol between more points!
|
||||
** Patrol between units.
|
||||
**
|
||||
** @param unit Patroling unit pointer.
|
||||
*/
|
||||
void HandleActionPatrol(COrder& order, CUnit &unit)
|
||||
{
|
||||
Assert(order.Action == UnitActionPatrol);
|
||||
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -59,6 +59,9 @@
|
|||
{
|
||||
file.printf("{\"action-repair\",");
|
||||
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
file.printf(" \"range\", %d,", this->Range);
|
||||
if (this->HasGoal()) {
|
||||
CUnit &goal = *this->GetGoal();
|
||||
|
@ -157,7 +160,7 @@ static void AnimateActionRepair(CUnit &unit)
|
|||
UnitShowAnimation(unit, unit.Type->Animations->Repair);
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Repair::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_Repair::Execute(CUnit &unit)
|
||||
{
|
||||
switch (this->State) {
|
||||
case 0:
|
||||
|
@ -194,7 +197,8 @@ static void AnimateActionRepair(CUnit &unit)
|
|||
const Vec2i dir = goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos;
|
||||
UnitHeadingFromDeltaXY(unit, dir);
|
||||
} else if (err < 0) {
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -203,7 +207,7 @@ static void AnimateActionRepair(CUnit &unit)
|
|||
AnimateActionRepair(unit);
|
||||
this->RepairCycle++;
|
||||
if (unit.Anim.Unbreakable) {
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
CUnit *goal = this->GetGoal();
|
||||
|
||||
|
@ -220,7 +224,8 @@ static void AnimateActionRepair(CUnit &unit)
|
|||
|
||||
if (dist <= unit.Type->RepairRange) {
|
||||
if (RepairUnit(unit, *goal)) {
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
} else if (dist > unit.Type->RepairRange) {
|
||||
// If goal has move, chase after it
|
||||
|
@ -231,21 +236,14 @@ static void AnimateActionRepair(CUnit &unit)
|
|||
}
|
||||
// Target is fine, choose new one.
|
||||
if (!goal || goal->Variable[HP_INDEX].Value >= goal->Variable[HP_INDEX].Max) {
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
// FIXME: automatic repair
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void HandleActionRepair(COrder& order, CUnit &unit)
|
||||
{
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -58,6 +58,9 @@
|
|||
{
|
||||
file.printf("{\"action-research\"");
|
||||
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
if (this->Upgrade) {
|
||||
file.printf(", \"upgrade\", \"%s\"", this->Upgrade->Ident.c_str());
|
||||
}
|
||||
|
@ -89,7 +92,7 @@
|
|||
**
|
||||
** @return true when finished.
|
||||
*/
|
||||
/* virtual */ bool COrder_Research::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_Research::Execute(CUnit &unit)
|
||||
{
|
||||
const CUpgrade &upgrade = this->GetUpgrade();
|
||||
const CUnitType &type = *unit.Type;
|
||||
|
@ -99,11 +102,11 @@
|
|||
UnitShowAnimation(unit, type.Animations->Still);
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
#if 0
|
||||
if (unit.Anim.Unbreakable) {
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
#endif
|
||||
CPlayer &player = *unit.Player;
|
||||
|
@ -122,10 +125,10 @@
|
|||
AiResearchComplete(unit, &upgrade);
|
||||
}
|
||||
UpgradeAcquire(player, &upgrade);
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
unit.Wait = CYCLES_PER_SECOND / 6;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_Research::Cancel(CUnit &unit)
|
||||
|
@ -136,19 +139,4 @@
|
|||
unit.Player->AddCostsFactor(upgrade.Costs, CancelResearchCostsFactor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** Unit researches!
|
||||
**
|
||||
** @param unit Pointer of researching unit.
|
||||
*/
|
||||
void HandleActionResearch(COrder& order, CUnit &unit)
|
||||
{
|
||||
Assert(order.Action == UnitActionResearch);
|
||||
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -65,6 +65,9 @@
|
|||
{
|
||||
file.printf("{\"action-spell-cast\",");
|
||||
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
file.printf(" \"range\", %d,", this->Range);
|
||||
file.printf(" \"width\", %d,", this->Width);
|
||||
file.printf(" \"height\", %d,", this->Height);
|
||||
|
@ -185,13 +188,13 @@ bool COrder_SpellCast::SpellMoveToTarget(CUnit &unit)
|
|||
}
|
||||
|
||||
|
||||
/* virtual */ bool COrder_SpellCast::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_SpellCast::Execute(CUnit &unit)
|
||||
{
|
||||
COrder_SpellCast &order = *this;
|
||||
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
const SpellType &spell = order.GetSpell();
|
||||
switch (this->State) {
|
||||
|
@ -212,7 +215,8 @@ bool COrder_SpellCast::SpellMoveToTarget(CUnit &unit)
|
|||
if (unit.Player->AiEnabled) {
|
||||
DebugPrint("FIXME: do we need an AI callback?\n");
|
||||
}
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
// FIXME FIXME FIXME: Check if already in range and skip straight to 2(casting)
|
||||
if (!spell.IsCasterOnly()) {
|
||||
|
@ -224,9 +228,10 @@ bool COrder_SpellCast::SpellMoveToTarget(CUnit &unit)
|
|||
case 1: // Move to the target.
|
||||
if (spell.Range && spell.Range != INFINITE_RANGE) {
|
||||
if (SpellMoveToTarget(unit) == true) {
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
return false;
|
||||
return ;
|
||||
} else {
|
||||
this->State = 2;
|
||||
}
|
||||
|
@ -235,7 +240,7 @@ bool COrder_SpellCast::SpellMoveToTarget(CUnit &unit)
|
|||
if (!spell.IsCasterOnly()) {
|
||||
AnimateActionSpellCast(unit, *this);
|
||||
if (unit.Anim.Unbreakable) {
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
} else {
|
||||
// FIXME: what todo, if unit/goal is removed?
|
||||
|
@ -247,7 +252,8 @@ bool COrder_SpellCast::SpellMoveToTarget(CUnit &unit)
|
|||
}
|
||||
}
|
||||
if (!unit.ReCast && unit.CurrentAction() != UnitActionDie) {
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -255,27 +261,6 @@ bool COrder_SpellCast::SpellMoveToTarget(CUnit &unit)
|
|||
this->State = 0; // Reset path, than move to target
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_SpellCast::Cancel(CUnit&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** Unit casts a spell!
|
||||
**
|
||||
** @param unit Unit, for that the spell cast is handled.
|
||||
*/
|
||||
void HandleActionSpellCast(COrder& order, CUnit &unit)
|
||||
{
|
||||
Assert(order.Action == UnitActionSpellCast);
|
||||
|
||||
if (order.Execute(unit)) {
|
||||
order.ClearGoal();
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -36,25 +36,10 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "stratagus.h"
|
||||
#include "unit.h"
|
||||
#include "actions.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** Unit stands ground!
|
||||
**
|
||||
** @param unit Action handled for this unit pointer.
|
||||
*/
|
||||
void HandleActionStandGround(COrder& order, CUnit &unit)
|
||||
{
|
||||
Assert(order.Action == UnitActionStandGround);
|
||||
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -63,6 +63,9 @@ enum {
|
|||
} else {
|
||||
file.printf("{\"action-stand-ground\",");
|
||||
}
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
if (this->HasGoal()) {
|
||||
CUnit &goal = *this->GetGoal();
|
||||
if (goal.Destroyed) {
|
||||
|
@ -241,19 +244,9 @@ bool COrder_Still::AutoAttackStand(CUnit &unit)
|
|||
if (goal == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CUnit *oldGoal =this->GetGoal();
|
||||
if (oldGoal && oldGoal->CurrentAction() == UnitActionDie) {
|
||||
this->ClearGoal();
|
||||
oldGoal = NULL;
|
||||
}
|
||||
if (this->State < SUB_STILL_ATTACK || oldGoal != goal) {
|
||||
// New target.
|
||||
this->SetGoal(goal);
|
||||
unit.State = 0;
|
||||
this->State = SUB_STILL_ATTACK; // Mark attacking.
|
||||
UnitHeadingFromDeltaXY(unit, goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos);
|
||||
}
|
||||
this->SetGoal(goal);
|
||||
this->State = SUB_STILL_ATTACK; // Mark attacking.
|
||||
UnitHeadingFromDeltaXY(unit, goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -291,13 +284,14 @@ bool AutoAttack(CUnit &unit)
|
|||
}
|
||||
|
||||
|
||||
/* virtual */ bool COrder_Still::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_Still::Execute(CUnit &unit)
|
||||
{
|
||||
// If unit is not bunkered and removed, wait
|
||||
if (unit.Removed
|
||||
&& (unit.Container == NULL || unit.Container->Type->AttackFromTransporter == false)) {
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
this->Finished = false;
|
||||
|
||||
switch (this->State) {
|
||||
case SUB_STILL_INIT: //first entry
|
||||
|
@ -311,38 +305,22 @@ bool AutoAttack(CUnit &unit)
|
|||
break;
|
||||
}
|
||||
if (unit.Anim.Unbreakable) { // animation can't be aborted here
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
this->State = SUB_STILL_STANDBY;
|
||||
this->Finished = (this->Action == UnitActionStill);
|
||||
if (this->Action == UnitActionStandGround || unit.Removed || unit.CanMove() == false) {
|
||||
if (unit.IsAgressive()) {
|
||||
this->AutoAttackStand(unit);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ((unit.IsAgressive() && AutoAttack(unit))
|
||||
|| AutoCast(unit)
|
||||
|| AutoRepair(unit)
|
||||
|| MoveRandomly(unit)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
** Unit stands still!
|
||||
**
|
||||
** @param unit Unit pointer for still action.
|
||||
*/
|
||||
void HandleActionStill(COrder& order, CUnit &unit)
|
||||
{
|
||||
Assert(order.Action == UnitActionStill);
|
||||
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//@}
|
||||
|
|
|
@ -58,6 +58,9 @@
|
|||
/* virtual */ void COrder_Train::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-train\",");
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
file.printf("\"type\", \"%s\",", this->Type->Ident.c_str());
|
||||
file.printf("\"ticks\", %d", this->Ticks);
|
||||
file.printf("}");
|
||||
|
@ -152,12 +155,12 @@ static void AnimateActionTrain(CUnit &unit)
|
|||
}
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Train::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_Train::Execute(CUnit &unit)
|
||||
{
|
||||
AnimateActionTrain(unit);
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
CPlayer &player = *unit.Player;
|
||||
CUnitType &nType = *this->Type;
|
||||
|
@ -166,14 +169,14 @@ static void AnimateActionTrain(CUnit &unit)
|
|||
|
||||
if (this->Ticks < cost) {
|
||||
unit.Wait = CYCLES_PER_SECOND / 6;
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
this->Ticks = std::min(this->Ticks, cost);
|
||||
|
||||
// Check if there are still unit slots.
|
||||
if (NumUnits >= UnitMax) {
|
||||
unit.Wait = CYCLES_PER_SECOND / 6;
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
|
||||
// Check if enough supply available.
|
||||
|
@ -183,7 +186,7 @@ static void AnimateActionTrain(CUnit &unit)
|
|||
AiNeedMoreSupply(*unit.Player);
|
||||
}
|
||||
unit.Wait = CYCLES_PER_SECOND / 6;
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
|
||||
CUnit *newUnit = MakeUnit(nType, &player);
|
||||
|
@ -192,7 +195,7 @@ static void AnimateActionTrain(CUnit &unit)
|
|||
player.Notify(NotifyYellow, unit.tilePos.x, unit.tilePos.y,
|
||||
_("Unable to train %s"), nType.Name.c_str());
|
||||
unit.Wait = CYCLES_PER_SECOND / 6;
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
|
||||
// New unit might supply food
|
||||
|
@ -228,27 +231,18 @@ static void AnimateActionTrain(CUnit &unit)
|
|||
}
|
||||
|
||||
if (CanHandleOrder(*newUnit, unit.NewOrder) == true) {
|
||||
delete newUnit->CurrentOrder();
|
||||
delete newUnit->Orders[0];
|
||||
newUnit->Orders[0] = unit.NewOrder->Clone();
|
||||
} else {
|
||||
#if 0
|
||||
// Tell the unit to rigth-click ?
|
||||
#endif
|
||||
}
|
||||
this->Finished = true;
|
||||
if (IsOnlySelected(unit)) {
|
||||
UI.ButtonPanel.Update();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleActionTrain(COrder& order, CUnit &unit)
|
||||
{
|
||||
Assert(order.Action == UnitActionTrain);
|
||||
|
||||
if (order.Execute(unit)) {
|
||||
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -53,6 +53,9 @@
|
|||
/* virtual */ void COrder_Unload::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-unload\",");
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
if (this->HasGoal()) {
|
||||
CUnit &goal = *this->GetGoal();
|
||||
if (goal.Destroyed) {
|
||||
|
@ -352,7 +355,7 @@ bool COrder_Unload::LeaveTransporter(CUnit &transporter)
|
|||
}
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Unload::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_Unload::Execute(CUnit &unit)
|
||||
{
|
||||
const int maxSearchRange = 20;
|
||||
|
||||
|
@ -365,7 +368,8 @@ bool COrder_Unload::LeaveTransporter(CUnit &transporter)
|
|||
Vec2i pos;
|
||||
|
||||
if (!ClosestFreeDropZone(unit, this->goalPos, maxSearchRange, &pos)) {
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
this->goalPos = pos;
|
||||
}
|
||||
|
@ -382,40 +386,26 @@ bool COrder_Unload::LeaveTransporter(CUnit &transporter)
|
|||
if (moveResult) {
|
||||
if (moveResult == PF_REACHED) {
|
||||
if (++this->State == 1) {
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
} else {
|
||||
this->State = 2;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
case 2: { // Leave the transporter
|
||||
// FIXME: show still animations ?
|
||||
if (LeaveTransporter(unit)) {
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** The transporter unloads a unit.
|
||||
**
|
||||
** @param unit Pointer to unit.
|
||||
*/
|
||||
void HandleActionUnload(COrder& order, CUnit &unit)
|
||||
{
|
||||
Assert(order.Action == UnitActionUnload);
|
||||
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//@}
|
||||
|
|
|
@ -145,6 +145,9 @@ static int TransformUnitIntoType(CUnit &unit, const CUnitType &newtype)
|
|||
/* virtual */ void COrder_TransformInto::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-transform-into\",");
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
file.printf(" \"type\", \"%s\"", this->Type->Ident.c_str());
|
||||
file.printf("}");
|
||||
}
|
||||
|
@ -162,19 +165,10 @@ static int TransformUnitIntoType(CUnit &unit, const CUnitType &newtype)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_TransformInto::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_TransformInto::Execute(CUnit &unit)
|
||||
{
|
||||
TransformUnitIntoType(unit, *this->Type);
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleActionTransformInto(COrder& order, CUnit &unit)
|
||||
{
|
||||
Assert(order.Action == UnitActionTransformInto);
|
||||
|
||||
if (order.Execute(unit)) {
|
||||
// unit.ClearAction();
|
||||
}
|
||||
this->Finished = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -184,6 +178,9 @@ void HandleActionTransformInto(COrder& order, CUnit &unit)
|
|||
/* virtual */ void COrder_UpgradeTo::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-upgrade-to\",");
|
||||
if (this->Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
file.printf(" \"type\", \"%s\",", this->Type->Ident.c_str());
|
||||
file.printf(" \"ticks\", %d", this->Ticks);
|
||||
file.printf("}");
|
||||
|
@ -215,12 +212,12 @@ static void AnimateActionUpgradeTo(CUnit &unit)
|
|||
UnitShowAnimation(unit, unit.Type->Animations->Still);
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_UpgradeTo::Execute(CUnit &unit)
|
||||
/* virtual */ void COrder_UpgradeTo::Execute(CUnit &unit)
|
||||
{
|
||||
AnimateActionUpgradeTo(unit);
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
CPlayer &player = *unit.Player;
|
||||
const CUnitType &newtype = *this->Type;
|
||||
|
@ -229,18 +226,19 @@ static void AnimateActionUpgradeTo(CUnit &unit)
|
|||
this->Ticks += SpeedUpgrade;
|
||||
if (this->Ticks < newstats.Costs[TimeCost]) {
|
||||
unit.Wait = CYCLES_PER_SECOND / 6;
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
|
||||
if (unit.Anim.Unbreakable) {
|
||||
this->Ticks = newstats.Costs[TimeCost];
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
|
||||
if (TransformUnitIntoType(unit, newtype) == 0) {
|
||||
player.Notify(NotifyGreen, unit.tilePos.x, unit.tilePos.y,
|
||||
_("Upgrade to %s canceled"), newtype.Name.c_str());
|
||||
return true;
|
||||
this->Finished = true;
|
||||
return ;
|
||||
}
|
||||
player.Notify(NotifyGreen, unit.tilePos.x, unit.tilePos.y,
|
||||
_("Upgrade to %s complete"), unit.Type->Name.c_str());
|
||||
|
@ -249,7 +247,7 @@ static void AnimateActionUpgradeTo(CUnit &unit)
|
|||
if (player.AiEnabled) {
|
||||
AiUpgradeToComplete(unit, newtype);
|
||||
}
|
||||
return true;
|
||||
this->Finished = true;
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_UpgradeTo::Cancel(CUnit &unit)
|
||||
|
@ -267,16 +265,5 @@ static void AnimateActionUpgradeTo(CUnit &unit)
|
|||
unit.Variable[UPGRADINGTO_INDEX].Max = this->Type->Stats[unit.Player->Index].Costs[TimeCost];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void HandleActionUpgradeTo(COrder& order, CUnit &unit)
|
||||
{
|
||||
Assert(order.Action == UnitActionUpgradeTo);
|
||||
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
//@}
|
||||
|
|
|
@ -168,8 +168,6 @@ unsigned SyncHash; /// Hash calculated to find sync failures
|
|||
{
|
||||
COrder_Built* order = new COrder_Built();
|
||||
|
||||
order->Action = UnitActionBuilt;
|
||||
|
||||
// Make sure the bulding doesn't cancel itself out right away.
|
||||
|
||||
unit.Variable[HP_INDEX].Value = 1;
|
||||
|
@ -261,8 +259,6 @@ unsigned SyncHash; /// Hash calculated to find sync failures
|
|||
{
|
||||
COrder_Research *order = new COrder_Research();
|
||||
|
||||
order->Action = UnitActionResearch;
|
||||
|
||||
// FIXME: if you give quick an other order, the resources are lost!
|
||||
unit.Player->SubCosts(upgrade.Costs);
|
||||
|
||||
|
@ -324,8 +320,6 @@ unsigned SyncHash; /// Hash calculated to find sync failures
|
|||
{
|
||||
COrder_SpellCast *order = new COrder_SpellCast;
|
||||
|
||||
order->Action = UnitActionSpellCast;
|
||||
|
||||
order->Range = spell.Range;
|
||||
if (target) {
|
||||
// Destination could be killed.
|
||||
|
@ -457,7 +451,7 @@ void COrder::ReleaseRefs(CUnit &unit)
|
|||
}
|
||||
}
|
||||
// Still shouldn't have a reference unless attacking
|
||||
Assert(!(this->Action == UnitActionStill && !SubAction.Attack));
|
||||
Assert(this->Action != UnitActionStill);
|
||||
this->ClearGoal();
|
||||
}
|
||||
#ifdef DEBUG
|
||||
|
@ -1339,26 +1333,26 @@ static void HandleActionNotWritten(COrder&, CUnit &unit)
|
|||
*/
|
||||
static void (*HandleActionTable[256])(COrder&, CUnit &) = {
|
||||
HandleActionNone,
|
||||
HandleActionStill,
|
||||
HandleActionStandGround,
|
||||
HandleActionFollow,
|
||||
HandleActionMove,
|
||||
HandleActionNone, // HandleActionStill,
|
||||
HandleActionNone, // HandleActionStandGround,
|
||||
HandleActionNone, // HandleActionFollow,
|
||||
HandleActionNone, // HandleActionMove,
|
||||
HandleActionAttack,
|
||||
HandleActionAttack, // HandleActionAttackGround,
|
||||
HandleActionDie,
|
||||
HandleActionSpellCast,
|
||||
HandleActionTrain,
|
||||
HandleActionUpgradeTo,
|
||||
HandleActionResearch,
|
||||
HandleActionBuilt,
|
||||
HandleActionBoard,
|
||||
HandleActionUnload,
|
||||
HandleActionPatrol,
|
||||
HandleActionBuild,
|
||||
HandleActionRepair,
|
||||
HandleActionNone, // HandleActionDie,
|
||||
HandleActionNone, // HandleActionSpellCast,
|
||||
HandleActionNone, // HandleActionTrain,
|
||||
HandleActionNone, // HandleActionUpgradeTo,
|
||||
HandleActionNone, // HandleActionResearch,
|
||||
HandleActionNone, // HandleActionBuilt,
|
||||
HandleActionNone, // HandleActionBoard,
|
||||
HandleActionNone, // HandleActionUnload,
|
||||
HandleActionNone, // HandleActionPatrol,
|
||||
HandleActionNone, // HandleActionBuild,
|
||||
HandleActionNone, // HandleActionRepair,
|
||||
HandleActionResource,
|
||||
HandleActionReturnGoods,
|
||||
HandleActionTransformInto,
|
||||
HandleActionNone, // HandleActionTransformInto,
|
||||
HandleActionNotWritten,
|
||||
|
||||
// Enough for the future ?
|
||||
|
@ -1522,9 +1516,12 @@ static void HandleBuffs(CUnit &unit, int amount)
|
|||
}
|
||||
}
|
||||
|
||||
static void RunAction(COrder &order, CUnit &unit)
|
||||
|
||||
|
||||
|
||||
void COrder::Execute(CUnit &unit)
|
||||
{
|
||||
HandleActionTable[order.Action](order, unit);
|
||||
HandleActionTable[Action](*this, unit);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1538,40 +1535,44 @@ static void HandleUnitAction(CUnit &unit)
|
|||
// If current action is breakable proceed with next one.
|
||||
if (!unit.Anim.Unbreakable) {
|
||||
if (unit.CriticalOrder != NULL) {
|
||||
RunAction(*unit.CriticalOrder, unit);
|
||||
unit.CriticalOrder->Execute(unit);
|
||||
delete unit.CriticalOrder;
|
||||
unit.CriticalOrder = NULL;
|
||||
}
|
||||
|
||||
if (unit.Orders[0]->Finished && unit.Orders[0]->Action != UnitActionStill
|
||||
&& unit.Orders.size() == 1) {
|
||||
unit.Orders[0]->ReleaseRefs(unit);
|
||||
|
||||
delete unit.Orders[0];
|
||||
unit.Orders[0] = new COrder_Still(false);
|
||||
unit.State = 0;
|
||||
if (IsOnlySelected(unit)) { // update display for new action
|
||||
SelectedUnitChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// o Look if we have a new order and old finished.
|
||||
// o Or the order queue should be flushed.
|
||||
if (unit.Orders.size() > 1
|
||||
&& (unit.CurrentAction() == UnitActionStill || unit.OrderFlush)) {
|
||||
|
||||
if (unit.Orders[0]->Finished && unit.Orders.size() > 1) {
|
||||
if (unit.Removed) { // FIXME: johns I see this as an error
|
||||
DebugPrint("Flushing removed unit\n");
|
||||
// This happens, if building with ALT+SHIFT.
|
||||
return;
|
||||
}
|
||||
COrderPtr order = unit.CurrentOrder();
|
||||
unit.Orders[0]->ReleaseRefs(unit);
|
||||
|
||||
order->ReleaseRefs(unit);
|
||||
|
||||
unit.OrderFlush = 0;
|
||||
delete unit.Orders[0];
|
||||
unit.Orders.erase(unit.Orders.begin());
|
||||
|
||||
unit.State = 0;
|
||||
unit.Wait = 0;
|
||||
|
||||
if (IsOnlySelected(unit)) { // update display for new action
|
||||
SelectedUnitChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Select action.
|
||||
RunAction(*unit.CurrentOrder(), unit);
|
||||
unit.Orders[0]->Execute(unit);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -67,7 +67,7 @@ static void ReleaseOrders(CUnit &unit)
|
|||
delete unit.Orders[i];
|
||||
}
|
||||
unit.Orders.resize(1);
|
||||
unit.OrderFlush = 1;
|
||||
unit.Orders[0]->Finished = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -101,9 +101,10 @@ struct lua_State;
|
|||
*/
|
||||
class COrder
|
||||
{
|
||||
|
||||
public:
|
||||
COrder(int action) : Goal(NULL), Range(0), MinRange(0), Width(0),
|
||||
Height(0), Action(action), CurrentResource(0)
|
||||
Height(0), Action(action), Finished(false), CurrentResource(0)
|
||||
{
|
||||
goalPos.x = -1;
|
||||
goalPos.y = -1;
|
||||
|
@ -114,7 +115,7 @@ public:
|
|||
virtual ~COrder();
|
||||
|
||||
virtual COrder *Clone() const;
|
||||
virtual bool Execute(CUnit &unit) { return false; }
|
||||
virtual void Execute(CUnit &unit);
|
||||
virtual void Cancel(CUnit &unit) {}
|
||||
virtual void OnAnimationAttack(CUnit &unit);
|
||||
|
||||
|
@ -184,6 +185,7 @@ public:
|
|||
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
|
||||
bool Finished; /// true when order is finish
|
||||
unsigned char CurrentResource; ///used in UnitActionResource and UnitActionReturnGoods
|
||||
|
||||
Vec2i goalPos; /// or tile coordinate of destination
|
||||
|
@ -227,7 +229,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
|
||||
private:
|
||||
bool WaitForTransporter(CUnit &unit);
|
||||
|
@ -247,7 +249,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
|
||||
virtual void AiUnitKilled(CUnit &unit);
|
||||
|
||||
|
@ -276,7 +278,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
virtual void Cancel(CUnit &unit);
|
||||
|
||||
virtual void UpdateUnitVariables(CUnit &unit) const;
|
||||
|
@ -312,7 +314,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
};
|
||||
|
||||
class COrder_Follow : public COrder
|
||||
|
@ -325,7 +327,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
private:
|
||||
unsigned int State;
|
||||
};
|
||||
|
@ -340,7 +342,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
};
|
||||
|
||||
|
||||
|
@ -356,7 +358,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
|
||||
const Vec2i& GetWayPoint() const { return WayPoint; }
|
||||
private:
|
||||
|
@ -376,7 +378,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
private:
|
||||
bool RepairUnit(const CUnit &unit, CUnit &goal);
|
||||
private:
|
||||
|
@ -396,7 +398,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
virtual void Cancel(CUnit &unit);
|
||||
|
||||
virtual void UpdateUnitVariables(CUnit &unit) const;
|
||||
|
@ -417,8 +419,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Cancel(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
virtual void OnAnimationAttack(CUnit &unit);
|
||||
|
||||
const SpellType& GetSpell() const { return *Spell; }
|
||||
|
@ -440,7 +441,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
private:
|
||||
bool AutoAttackStand(CUnit &unit);
|
||||
private:
|
||||
|
@ -459,7 +460,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
virtual void Cancel(CUnit &unit);
|
||||
|
||||
virtual void UpdateUnitVariables(CUnit &unit) const;
|
||||
|
@ -483,7 +484,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
|
||||
private:
|
||||
CUnitType *Type; /// Transform unit into this unit-type
|
||||
|
@ -502,7 +503,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
|
||||
private:
|
||||
bool LeaveTransporter(CUnit &transporter);
|
||||
|
@ -522,7 +523,7 @@ public:
|
|||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
||||
virtual bool Execute(CUnit &unit);
|
||||
virtual void Execute(CUnit &unit);
|
||||
virtual void Cancel(CUnit &unit);
|
||||
|
||||
virtual void UpdateUnitVariables(CUnit &unit) const;
|
||||
|
@ -619,55 +620,22 @@ extern int GetNumWaitingWorkers(const CUnit &mine);
|
|||
extern bool AutoAttack(CUnit &unit);
|
||||
extern bool AutoRepair(CUnit &unit);
|
||||
extern bool AutoCast(CUnit &unit);
|
||||
|
||||
extern void UnHideUnit(CUnit &unit);
|
||||
|
||||
/// Generic move action
|
||||
extern int DoActionMove(CUnit &unit);
|
||||
/// Show attack animation
|
||||
extern void AnimateActionAttack(CUnit &unit);
|
||||
|
||||
|
||||
typedef void HandleActionFunc(COrder& order, CUnit &unit);
|
||||
|
||||
/// Handle command still
|
||||
extern HandleActionFunc HandleActionStill;
|
||||
/// Handle command stand ground
|
||||
extern HandleActionFunc HandleActionStandGround;
|
||||
/// Handle command follow
|
||||
extern HandleActionFunc HandleActionFollow;
|
||||
/// Generic move action
|
||||
extern int DoActionMove(CUnit &unit);
|
||||
/// Handle command move
|
||||
extern HandleActionFunc HandleActionMove;
|
||||
/// Handle command repair
|
||||
extern HandleActionFunc HandleActionRepair;
|
||||
/// Handle command patrol
|
||||
extern HandleActionFunc HandleActionPatrol;
|
||||
/// Show attack animation
|
||||
extern void AnimateActionAttack(CUnit &unit);
|
||||
/// Handle command attack
|
||||
extern HandleActionFunc HandleActionAttack;
|
||||
/// Handle command board
|
||||
extern HandleActionFunc HandleActionBoard;
|
||||
/// Handle command unload
|
||||
extern HandleActionFunc HandleActionUnload;
|
||||
/// Handle command resource
|
||||
extern HandleActionFunc HandleActionResource;
|
||||
/// Handle command return
|
||||
extern HandleActionFunc HandleActionReturnGoods;
|
||||
/// Handle command die
|
||||
extern HandleActionFunc HandleActionDie;
|
||||
/// Handle command build
|
||||
extern HandleActionFunc HandleActionBuild;
|
||||
/// Handle command built
|
||||
extern HandleActionFunc HandleActionBuilt;
|
||||
/// Handle command train
|
||||
extern HandleActionFunc HandleActionTrain;
|
||||
/// Handle command upgrade to
|
||||
extern HandleActionFunc HandleActionUpgradeTo;
|
||||
/// Handle command transform into
|
||||
extern HandleActionFunc HandleActionTransformInto;
|
||||
/// Handle command upgrade
|
||||
extern HandleActionFunc HandleActionUpgrade;
|
||||
/// Handle command research
|
||||
extern HandleActionFunc HandleActionResearch;
|
||||
/// Handle command spellcast
|
||||
extern HandleActionFunc HandleActionSpellCast;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Actions: actions.c
|
||||
|
|
|
@ -295,12 +295,6 @@
|
|||
** Pointer to the original owner of a unit. It will be NULL if
|
||||
** the unit was not rescued.
|
||||
**
|
||||
**
|
||||
** CUnit::OrderFlush
|
||||
**
|
||||
** A flag, which tells the unit to stop with the current order
|
||||
** and immediately start with the next order.
|
||||
**
|
||||
** CUnit::Orders
|
||||
**
|
||||
** Contains all orders of the unit. Slot 0 is always used.
|
||||
|
@ -566,11 +560,11 @@ public:
|
|||
} Anim;
|
||||
|
||||
|
||||
char OrderFlush; /// cancel current order, take next
|
||||
std::vector<COrder *> Orders; /// orders to process
|
||||
COrder *SavedOrder; /// order to continue after current
|
||||
COrder *NewOrder; /// order for new trained units
|
||||
COrder *CriticalOrder; /// order to do as possible in breakable animation.
|
||||
|
||||
char *AutoCastSpell; /// spells to auto cast
|
||||
|
||||
CUnit *Goal; /// Generic/Teleporter goal pointer
|
||||
|
|
|
@ -188,6 +188,10 @@ bool COrder::ParseGenericData(lua_State *l, int &j, const char *value)
|
|||
lua_rawgeti(l, -1, j + 1);
|
||||
this->Height = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
} else if (!strcmp(value, "finished")) {
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
this->Finished = true;
|
||||
lua_pop(l, 1);
|
||||
} else if (!strcmp(value, "goal")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
|
@ -656,8 +660,6 @@ static int CclUnit(lua_State *l)
|
|||
lua_pop(l, 1);
|
||||
u->AddInContainer(*unit);
|
||||
}
|
||||
} else if (!strcmp(value, "order-flush")) {
|
||||
unit->OrderFlush = LuaToNumber(l, j + 1);
|
||||
} else if (!strcmp(value, "orders")) {
|
||||
lua_pushvalue(l, j + 1);
|
||||
CclParseOrders(l, *unit);
|
||||
|
|
|
@ -178,7 +178,6 @@ void CUnit::Init()
|
|||
CacheLock = 0;
|
||||
memset(&Anim, 0, sizeof(Anim));
|
||||
CurrentResource = 0;
|
||||
OrderFlush = 0;
|
||||
Orders.clear();
|
||||
delete SavedOrder;
|
||||
SavedOrder = NULL;
|
||||
|
@ -264,8 +263,7 @@ unsigned int CUnit::CurrentAction() const
|
|||
|
||||
void CUnit::ClearAction()
|
||||
{
|
||||
delete CurrentOrder();
|
||||
Orders[0] = COrder::NewActionStill();
|
||||
Orders[0]->Finished = true;
|
||||
|
||||
if (Selected) {
|
||||
SelectedUnitChanged();
|
||||
|
@ -373,13 +371,13 @@ bool CUnit::RestoreOrder()
|
|||
|
||||
// Cannot delete this->Orders[0] since it is generally that order
|
||||
// which call this method.
|
||||
this->Orders[0]->Finished = true;
|
||||
|
||||
|
||||
//copy
|
||||
this->Orders[0] = this->SavedOrder;
|
||||
this->Orders.insert(this->Orders.begin() + 1, this->SavedOrder);
|
||||
this->CurrentResource = this->SavedOrder->CurrentResource;
|
||||
|
||||
this->CurrentOrder()->NewResetPath();
|
||||
|
||||
this->SavedOrder = NULL;
|
||||
return true;
|
||||
}
|
||||
|
@ -2131,8 +2129,6 @@ void DropOutAll(const CUnit &source)
|
|||
|
||||
for (int i = source.InsideCount; i; --i, unit = unit->NextContained) {
|
||||
DropOutOnSide(*unit, LookingW, &source);
|
||||
Assert(!unit->CurrentOrder()->HasGoal());
|
||||
unit->CurrentOrder()->Action = UnitActionStill;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -854,9 +854,10 @@ void ShowOrder(const CUnit &unit)
|
|||
const PixelPos mapPos = unit.GetMapPixelPosCenter();
|
||||
PixelPos screenStartPos = CurrentViewport->MapToScreenPixelPos(mapPos);
|
||||
COrderPtr order;
|
||||
const bool flushed = unit.Orders[0]->Finished;
|
||||
|
||||
// If the current order is cancelled show the next one
|
||||
if (unit.Orders.size() > 1 && unit.OrderFlush) {
|
||||
if (unit.Orders.size() > 1 && flushed) {
|
||||
order = unit.Orders[1];
|
||||
} else {
|
||||
order = unit.Orders[0];
|
||||
|
@ -864,7 +865,7 @@ void ShowOrder(const CUnit &unit)
|
|||
ShowSingleOrder(unit, screenStartPos, *order);
|
||||
|
||||
// Show the rest of the orders
|
||||
for (size_t i = 1 + (unit.OrderFlush ? 1 : 0); i < unit.Orders.size(); ++i) {
|
||||
for (size_t i = 1 + (flushed ? 1 : 0); i < unit.Orders.size(); ++i) {
|
||||
PixelPos screenPos;
|
||||
GetOrderPosition(unit, *unit.Orders[i - 1], &screenPos);
|
||||
ShowSingleOrder(unit, screenPos, *unit.Orders[i]);
|
||||
|
|
|
@ -116,6 +116,11 @@ void SaveOrder(const COrder &order, const CUnit &unit, CFile *file)
|
|||
file.printf(" \"width\", %d,", order.Width);
|
||||
file.printf(" \"height\", %d,", order.Height);
|
||||
file.printf(" \"min-range\", %d,", order.MinRange);
|
||||
|
||||
if (order.Finished) {
|
||||
file.printf(" \"finished\", ");
|
||||
}
|
||||
|
||||
if (order.HasGoal()) {
|
||||
CUnit &goal = *order.GetGoal();
|
||||
if (goal.Destroyed) {
|
||||
|
@ -382,7 +387,6 @@ void SaveUnit(const CUnit &unit, CFile *file)
|
|||
}
|
||||
file->printf("},\n ");
|
||||
}
|
||||
file->printf("\"order-flush\", %d,\n ", unit.OrderFlush);
|
||||
file->printf("\"orders\", {\n");
|
||||
Assert(unit.Orders.empty() == false);
|
||||
SaveOrder(*unit.Orders[0], unit, file);
|
||||
|
|
Loading…
Add table
Reference in a new issue