Some more COrder_ (Die, Patrol, StandGroung, Still)
This commit is contained in:
parent
58f777c425
commit
c3dea78611
13 changed files with 492 additions and 527 deletions
|
@ -350,10 +350,6 @@ void HandleActionBuild(COrder& /*order*/, CUnit &unit)
|
|||
// Action_built
|
||||
//////////////////////////
|
||||
|
||||
/* virtual */ COrder_Built *COrder_Built::Clone() const
|
||||
{
|
||||
return new COrder_Built(*this);
|
||||
}
|
||||
/* virtual */ void COrder_Built::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-built\", ");
|
||||
|
|
|
@ -39,15 +39,81 @@
|
|||
#include "stratagus.h"
|
||||
#include "unittype.h"
|
||||
#include "animation.h"
|
||||
#include "player.h"
|
||||
#include "unit.h"
|
||||
#include "actions.h"
|
||||
#include "map.h"
|
||||
#include "iolib.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/* virtual */ void COrder_Die::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-die\"}");
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Die::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool AnimateActionDie(CUnit &unit)
|
||||
{
|
||||
const CAnimations *animations = unit.Type->Animations;
|
||||
|
||||
if (animations == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (animations->Death[unit.DamagedType]) {
|
||||
UnitShowAnimation(unit, animations->Death[unit.DamagedType]);
|
||||
return true;
|
||||
} else if (animations->Death[ANIMATIONS_DEATHTYPES]) {
|
||||
UnitShowAnimation(unit, animations->Death[ANIMATIONS_DEATHTYPES]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* virtual */ bool COrder_Die::Execute(CUnit &unit)
|
||||
{
|
||||
// Show death animation
|
||||
if (AnimateActionDie(unit) == false) {
|
||||
// some units has no death animation
|
||||
unit.Anim.Unbreakable = 0;
|
||||
}
|
||||
if (unit.Anim.Unbreakable) {
|
||||
return false;
|
||||
}
|
||||
CUnitType &type = *unit.Type;
|
||||
|
||||
// Die sequence terminated, generate corpse.
|
||||
if (type.CorpseType == NULL) {
|
||||
unit.Remove(NULL);
|
||||
unit.Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
CUnitType &corpseType = *type.CorpseType;
|
||||
Assert(type.TileWidth >= corpseType.TileWidth && type.TileHeight >= corpseType.TileHeight);
|
||||
|
||||
// Update sight for new corpse
|
||||
// We have to unmark BEFORE changing the type.
|
||||
// Always do that, since types can have different vision properties.
|
||||
|
||||
unit.Remove(NULL);
|
||||
unit.Type = &corpseType;
|
||||
unit.Stats = &type.Stats[unit.Player->Index];
|
||||
unit.Place(unit.tilePos);
|
||||
|
||||
unit.SubAction = 0;
|
||||
unit.Frame = 0;
|
||||
UnitUpdateHeading(unit);
|
||||
AnimateActionDie(unit); // with new corpse.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** Unit dies!
|
||||
**
|
||||
|
@ -57,48 +123,8 @@ void HandleActionDie(COrder& order, CUnit &unit)
|
|||
{
|
||||
Assert(order.Action == UnitActionDie);
|
||||
|
||||
// Show death animation
|
||||
if (unit.Type->Animations && unit.Type->Animations->Death[unit.DamagedType]) {
|
||||
UnitShowAnimation(unit, unit.Type->Animations->Death[unit.DamagedType]);
|
||||
}
|
||||
else if (unit.Type->Animations && unit.Type->Animations->Death[ANIMATIONS_DEATHTYPES]) {
|
||||
UnitShowAnimation(unit, unit.Type->Animations->Death[ANIMATIONS_DEATHTYPES]);
|
||||
} else {
|
||||
// some units has no death animation
|
||||
unit.Anim.Unbreakable = 0;
|
||||
}
|
||||
|
||||
if (unit.Anim.Unbreakable) {
|
||||
return;
|
||||
}
|
||||
// Die sequence terminated, generate corpse.
|
||||
if (!unit.Type->CorpseType) {
|
||||
// We may be in the cache if we just finished out death animation
|
||||
// even though there is no corpse.
|
||||
// (unit.Type->Animations && unit.Type->Animations->Death)
|
||||
// Remove us from the map to be safe
|
||||
unit.Remove(NULL);
|
||||
unit.Release();
|
||||
return;
|
||||
}
|
||||
|
||||
Assert(unit.Type->TileWidth >= unit.Type->CorpseType->TileWidth &&
|
||||
unit.Type->TileHeight >= unit.Type->CorpseType->TileHeight);
|
||||
|
||||
// Update sight for new corpse
|
||||
// We have to unmark BEFORE changing the type.
|
||||
// Always do that, since types can have different vision properties.
|
||||
|
||||
unit.Remove(NULL);
|
||||
unit.Type = unit.Type->CorpseType;
|
||||
unit.Stats = &unit.Type->Stats[unit.Player->Index];
|
||||
unit.Place(unit.tilePos);
|
||||
|
||||
unit.SubAction = 0;
|
||||
unit.Frame = 0;
|
||||
UnitUpdateHeading(unit);
|
||||
if (unit.Type->Animations && unit.Type->Animations->Death[ANIMATIONS_DEATHTYPES]) {
|
||||
UnitShowAnimation(unit, unit.Type->Animations->Death[ANIMATIONS_DEATHTYPES]);
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,26 +42,97 @@
|
|||
#include "actions.h"
|
||||
#include "pathfinder.h"
|
||||
#include "map.h"
|
||||
#include "iolib.h"
|
||||
#include "script.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
extern bool AutoRepair(CUnit &unit);
|
||||
extern bool AutoCast(CUnit &unit);
|
||||
|
||||
/**
|
||||
** Swap the patrol points.
|
||||
*/
|
||||
static void SwapPatrolPoints(CUnit &unit)
|
||||
/* virtual */ void COrder_Patrol::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
COrderPtr order = unit.CurrentOrder();
|
||||
file.printf("{\"action-patrol\",");
|
||||
|
||||
std::swap(order->Arg1.Patrol.x, order->goalPos.x);
|
||||
std::swap(order->Arg1.Patrol.y, order->goalPos.y);
|
||||
file.printf(" \"tile\", {%d, %d},", this->goalPos.x, this->goalPos.y);
|
||||
file.printf(" \"range\", %d,", this->Range);
|
||||
|
||||
unit.CurrentOrder()->Data.Move.Cycles = 0; //moving counter
|
||||
unit.CurrentOrder()->NewResetPath();
|
||||
file.printf(" \"patrol\", {%d, %d},\n ", this->WayPoint.x, this->WayPoint.y);
|
||||
SaveDataMove(file);
|
||||
file.printf("}");
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Patrol::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit)
|
||||
{
|
||||
if (ParseMoveData(l, j, value)) {
|
||||
return true;
|
||||
} else if (!strcmp(value, "patrol")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
CclGetPos(l, &this->WayPoint.x , &this->WayPoint.y);
|
||||
lua_pop(l, 1);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Patrol::Execute(CUnit &unit)
|
||||
{
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!unit.SubAction) { // first entry.
|
||||
this->Data.Move.Cycles = 0; //moving counter
|
||||
this->NewResetPath();
|
||||
unit.SubAction = 1;
|
||||
}
|
||||
|
||||
switch (DoActionMove(unit)) {
|
||||
case PF_FAILED:
|
||||
unit.SubAction = 1;
|
||||
break;
|
||||
case PF_UNREACHABLE:
|
||||
// Increase range and try again
|
||||
unit.SubAction = 1;
|
||||
if (this->CheckRange()) {
|
||||
this->Range++;
|
||||
break;
|
||||
}
|
||||
// FALL THROUGH
|
||||
case PF_REACHED:
|
||||
unit.SubAction = 1;
|
||||
this->Range = 0;
|
||||
std::swap(this->WayPoint, this->goalPos);
|
||||
|
||||
this->Data.Move.Cycles = 0; //moving counter
|
||||
this->NewResetPath();
|
||||
break;
|
||||
case PF_WAIT:
|
||||
// Wait for a while then give up
|
||||
unit.SubAction++;
|
||||
if (unit.SubAction == 5) {
|
||||
unit.SubAction = 1;
|
||||
this->Range = 0;
|
||||
std::swap(this->WayPoint, this->goalPos);
|
||||
|
||||
this->Data.Move.Cycles = 0; //moving counter
|
||||
this->NewResetPath();
|
||||
}
|
||||
break;
|
||||
default: // moving
|
||||
unit.SubAction = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!unit.Anim.Unbreakable) {
|
||||
if (AutoAttack(unit, false) || AutoRepair(unit) || AutoCast(unit)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,76 +148,10 @@ static void SwapPatrolPoints(CUnit &unit)
|
|||
*/
|
||||
void HandleActionPatrol(COrder& order, CUnit &unit)
|
||||
{
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
return;
|
||||
}
|
||||
Assert(order.Action == UnitActionPatrol);
|
||||
|
||||
if (!unit.SubAction) { // first entry.
|
||||
order.Data.Move.Cycles = 0; //moving counter
|
||||
order.NewResetPath();
|
||||
unit.SubAction = 1;
|
||||
}
|
||||
|
||||
switch (DoActionMove(unit)) {
|
||||
case PF_FAILED:
|
||||
unit.SubAction = 1;
|
||||
break;
|
||||
case PF_UNREACHABLE:
|
||||
// Increase range and try again
|
||||
unit.SubAction = 1;
|
||||
if (order.CheckRange()) {
|
||||
order.Range++;
|
||||
break;
|
||||
}
|
||||
// FALL THROUGH
|
||||
case PF_REACHED:
|
||||
unit.SubAction = 1;
|
||||
order.Range = 0;
|
||||
SwapPatrolPoints(unit);
|
||||
break;
|
||||
case PF_WAIT:
|
||||
// Wait for a while then give up
|
||||
unit.SubAction++;
|
||||
if (unit.SubAction == 5) {
|
||||
unit.SubAction = 1;
|
||||
order.Range = 0;
|
||||
SwapPatrolPoints(unit);
|
||||
}
|
||||
break;
|
||||
default: // moving
|
||||
unit.SubAction = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!unit.Anim.Unbreakable) {
|
||||
//
|
||||
// Attack any enemy in reaction range.
|
||||
// If don't set the goal, the unit can then choose a
|
||||
// better goal if moving nearer to enemy.
|
||||
//
|
||||
if (unit.Type->CanAttack) {
|
||||
const CUnit *goal = AttackUnitsInReactRange(unit);
|
||||
if (goal) {
|
||||
// Save current command to come back.
|
||||
COrder *savedOrder = order.Clone();
|
||||
|
||||
DebugPrint("Patrol attack %d\n" _C_ UnitNumber(*goal));
|
||||
CommandAttack(unit, goal->tilePos, NULL, FlushCommands);
|
||||
|
||||
if (unit.StoreOrder(savedOrder) == false) {
|
||||
delete savedOrder;
|
||||
savedOrder = NULL;
|
||||
}
|
||||
unit.ClearAction();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Look for something to auto repair or auto cast
|
||||
if (AutoRepair(unit) || AutoCast(unit)) {
|
||||
return;
|
||||
}
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,11 +54,6 @@
|
|||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/* virtual */ COrder_Research *COrder_Research::Clone() const
|
||||
{
|
||||
return new COrder_Research(*this);
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_Research::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-research\"");
|
||||
|
|
|
@ -62,11 +62,6 @@
|
|||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/* virtual */ COrder_SpellCast *COrder_SpellCast::Clone() const
|
||||
{
|
||||
return new COrder_SpellCast(*this);
|
||||
}
|
||||
|
||||
/* virtual */ void COrder_SpellCast::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-spell-cast\",");
|
||||
|
@ -94,7 +89,9 @@
|
|||
|
||||
/* virtual */ bool COrder_SpellCast::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit)
|
||||
{
|
||||
if (!strcmp(value, "spell")) {
|
||||
if (ParseMoveData(l, j, value)) {
|
||||
return true;
|
||||
} else if (!strcmp(value, "spell")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
this->Spell = SpellTypeByIdent(LuaToString(l, -1));
|
||||
|
|
|
@ -38,19 +38,53 @@
|
|||
#include "stratagus.h"
|
||||
#include "unit.h"
|
||||
#include "actions.h"
|
||||
#include "iolib.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* virtual */ void COrder_StandGround::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-stand-ground\"");
|
||||
if (this->HasGoal()) {
|
||||
CUnit &goal = *this->GetGoal();
|
||||
if (goal.Destroyed) {
|
||||
/* this unit is destroyed so it's not in the global unit
|
||||
* array - this means it won't be saved!!! */
|
||||
printf ("FIXME: storing destroyed Goal - loading will fail.\n");
|
||||
}
|
||||
file.printf(", \"goal\", \"%s\"", UnitReference(goal).c_str());
|
||||
}
|
||||
file.printf("}");
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_StandGround::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_StandGround::Execute(CUnit &unit)
|
||||
{
|
||||
ActionStillGeneric(unit, true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** Unit stands ground!
|
||||
**
|
||||
** @param unit Action handled for this unit pointer.
|
||||
*/
|
||||
void HandleActionStandGround(COrder& /*order*/, CUnit &unit)
|
||||
void HandleActionStandGround(COrder& order, CUnit &unit)
|
||||
{
|
||||
ActionStillGeneric(unit, true);
|
||||
Assert(order.Action == UnitActionStandGround);
|
||||
|
||||
if (order.Execute(unit)) {
|
||||
unit.ClearAction();
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -47,11 +47,35 @@
|
|||
#include "pathfinder.h"
|
||||
#include "spells.h"
|
||||
#include "player.h"
|
||||
#include "iolib.h"
|
||||
|
||||
#define SUB_STILL_INIT 0
|
||||
#define SUB_STILL_STANDBY 1
|
||||
#define SUB_STILL_ATTACK 2
|
||||
|
||||
|
||||
|
||||
/* virtual */ void COrder_Still::Save(CFile &file, const CUnit &unit) const
|
||||
{
|
||||
file.printf("{\"action-still\"");
|
||||
if (this->HasGoal()) {
|
||||
CUnit &goal = *this->GetGoal();
|
||||
if (goal.Destroyed) {
|
||||
/* this unit is destroyed so it's not in the global unit
|
||||
* array - this means it won't be saved!!! */
|
||||
printf ("FIXME: storing destroyed Goal - loading will fail.\n");
|
||||
}
|
||||
file.printf(", \"goal\", \"%s\"", UnitReference(goal).c_str());
|
||||
}
|
||||
file.printf("}");
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Still::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
@ -239,66 +263,81 @@ bool AutoRepair(CUnit &unit)
|
|||
{
|
||||
const int repairRange = unit.Type->Variable[AUTOREPAIRRANGE_INDEX].Value;
|
||||
|
||||
if (unit.AutoRepair && repairRange) {
|
||||
CUnit *repairedUnit = UnitToRepairInRange(unit, repairRange);
|
||||
|
||||
if (repairedUnit != NoUnitP) {
|
||||
const Vec2i invalidPos = {-1, -1};
|
||||
COrder *savedOrder = unit.CurrentOrder()->Clone();
|
||||
|
||||
//Command* will clear unit.SavedOrder
|
||||
CommandRepair(unit, invalidPos, repairedUnit, FlushCommands);
|
||||
if (unit.StoreOrder(savedOrder) == false) {
|
||||
delete savedOrder;
|
||||
savedOrder = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (unit.AutoRepair == false || repairRange == 0) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
CUnit *repairedUnit = UnitToRepairInRange(unit, repairRange);
|
||||
|
||||
if (repairedUnit == NoUnitP) {
|
||||
return false;
|
||||
}
|
||||
const Vec2i invalidPos = {-1, -1};
|
||||
COrder *savedOrder = unit.CurrentOrder()->Clone();
|
||||
|
||||
//Command* will clear unit.SavedOrder
|
||||
CommandRepair(unit, invalidPos, repairedUnit, FlushCommands);
|
||||
if (unit.StoreOrder(savedOrder) == false) {
|
||||
delete savedOrder;
|
||||
savedOrder = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
** Auto attack nearby units if possible
|
||||
*/
|
||||
static bool AutoAttack(CUnit &unit, bool stand_ground)
|
||||
bool AutoAttack(CUnit &unit, bool stand_ground)
|
||||
{
|
||||
CUnit *goal;
|
||||
|
||||
// Cowards and invisible units don't attack unless ordered.
|
||||
if (unit.IsAgressive()) {
|
||||
// Normal units react in reaction range.
|
||||
if (!stand_ground && !unit.Removed && unit.CanMove()) {
|
||||
if ((goal = AttackUnitsInReactRange(unit))) {
|
||||
// Weak goal, can choose other unit, come back after attack
|
||||
CommandAttack(unit, goal->tilePos, NULL, FlushCommands);
|
||||
COrder *savedOrder = COrder::NewActionAttack(unit, unit.tilePos);
|
||||
|
||||
if (unit.StoreOrder(savedOrder) == false) {
|
||||
delete savedOrder;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Removed units can only attack in AttackRange, from bunker
|
||||
} else {
|
||||
if ((goal = AttackUnitsInRange(unit))) {
|
||||
CUnit *temp = unit.CurrentOrder()->GetGoal();
|
||||
if (temp && temp->CurrentAction() == UnitActionDie) {
|
||||
unit.CurrentOrder()->ClearGoal();
|
||||
temp = NoUnitP;
|
||||
}
|
||||
if (unit.SubAction < SUB_STILL_ATTACK || temp != goal) {
|
||||
// New target.
|
||||
unit.CurrentOrder()->SetGoal(goal);
|
||||
unit.State = 0;
|
||||
unit.SubAction = SUB_STILL_ATTACK; // Mark attacking.
|
||||
UnitHeadingFromDeltaXY(unit, goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (unit.Type->CanAttack == false) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
if (stand_ground || unit.Removed || unit.CanMove() == false) {
|
||||
// Removed units can only attack in AttackRange, from bunker
|
||||
CUnit *goal = AttackUnitsInRange(unit);
|
||||
|
||||
if (goal == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CUnit *temp = unit.CurrentOrder()->GetGoal();
|
||||
if (temp && temp->CurrentAction() == UnitActionDie) {
|
||||
unit.CurrentOrder()->ClearGoal();
|
||||
temp = NoUnitP;
|
||||
}
|
||||
if (unit.SubAction < SUB_STILL_ATTACK || temp != goal) {
|
||||
// New target.
|
||||
unit.CurrentOrder()->SetGoal(goal);
|
||||
unit.State = 0;
|
||||
unit.SubAction = SUB_STILL_ATTACK; // Mark attacking.
|
||||
UnitHeadingFromDeltaXY(unit, goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Normal units react in reaction range.
|
||||
CUnit *goal = AttackUnitsInReactRange(unit);
|
||||
|
||||
if (goal == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
COrder *savedOrder;
|
||||
|
||||
if (unit.SavedOrder != NULL) {
|
||||
savedOrder = unit.SavedOrder->Clone();
|
||||
} else if (unit.CurrentAction() == UnitActionStill) {
|
||||
savedOrder = COrder::NewActionAttack(unit, unit.tilePos);
|
||||
} else {
|
||||
savedOrder = unit.CurrentOrder()->Clone();
|
||||
}
|
||||
|
||||
// Weak goal, can choose other unit, come back after attack
|
||||
CommandAttack(unit, goal->tilePos, NULL, FlushCommands);
|
||||
|
||||
if (unit.StoreOrder(savedOrder) == false) {
|
||||
delete savedOrder;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AutoAttack(CUnit &unit, CUnitCache &targets, bool stand_ground)
|
||||
|
@ -360,8 +399,7 @@ void ActionStillGeneric(CUnit &unit, bool stand_ground)
|
|||
return;
|
||||
}
|
||||
|
||||
switch (unit.SubAction)
|
||||
{
|
||||
switch (unit.SubAction) {
|
||||
case SUB_STILL_INIT: //first entry
|
||||
MapMarkUnitGuard(unit);
|
||||
unit.SubAction = SUB_STILL_STANDBY;
|
||||
|
@ -378,7 +416,7 @@ void ActionStillGeneric(CUnit &unit, bool stand_ground)
|
|||
return;
|
||||
}
|
||||
|
||||
if (AutoAttack(unit, stand_ground)
|
||||
if ((unit.IsAgressive() && AutoAttack(unit, stand_ground))
|
||||
|| AutoCast(unit)
|
||||
|| AutoRepair(unit)
|
||||
|| MoveRandomly(unit)) {
|
||||
|
@ -391,9 +429,18 @@ void ActionStillGeneric(CUnit &unit, bool stand_ground)
|
|||
**
|
||||
** @param unit Unit pointer for still action.
|
||||
*/
|
||||
void HandleActionStill(COrder& /*order*/, CUnit &unit)
|
||||
void HandleActionStill(COrder& order, CUnit &unit)
|
||||
{
|
||||
ActionStillGeneric(unit, false);
|
||||
Assert(order.Action == UnitActionStill);
|
||||
|
||||
order.Execute(unit);
|
||||
}
|
||||
|
||||
/* virtual */ bool COrder_Still::Execute(CUnit &unit)
|
||||
{
|
||||
ActionStillGeneric(unit, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//@}
|
||||
|
|
|
@ -92,9 +92,7 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
|
||||
/* static */ COrder* COrder::NewActionAttack(const CUnit &attacker, CUnit &target)
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionAttack;
|
||||
COrder *order = new COrder(UnitActionAttack);
|
||||
|
||||
if (target.Destroyed) {
|
||||
order->goalPos = target.tilePos + target.Type->GetHalfTileSize();
|
||||
|
@ -111,9 +109,7 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
{
|
||||
Assert(Map.Info.IsPointOnMap(dest));
|
||||
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionAttack;
|
||||
COrder *order = new COrder(UnitActionAttack);
|
||||
|
||||
if (Map.WallOnMap(dest) && Map.IsFieldExplored(*attacker.Player, dest)) {
|
||||
// FIXME: look into action_attack.cpp about this ugly problem
|
||||
|
@ -128,9 +124,8 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
|
||||
/* static */ COrder* COrder::NewActionAttackGround(const CUnit &attacker, const Vec2i &dest)
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
COrder *order = new COrder(UnitActionAttackGround);
|
||||
|
||||
order->Action = UnitActionAttackGround;
|
||||
order->goalPos = dest;
|
||||
order->Range = attacker.Stats->Variables[ATTACKRANGE_INDEX].Max;
|
||||
order->MinRange = attacker.Type->MinAttackRange;
|
||||
|
@ -141,9 +136,8 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
|
||||
/* static */ COrder* COrder::NewActionBoard(CUnit &unit)
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
COrder *order = new COrder(UnitActionBoard);
|
||||
|
||||
order->Action = UnitActionBoard;
|
||||
order->SetGoal(&unit);
|
||||
order->Range = 1;
|
||||
|
||||
|
@ -153,9 +147,7 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
|
||||
/* static */ COrder* COrder::NewActionBuild(const CUnit &builder, const Vec2i &pos, CUnitType &building)
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionBuild;
|
||||
COrder *order = new COrder(UnitActionBuild);
|
||||
|
||||
order->goalPos = pos;
|
||||
order->Width = building.TileWidth;
|
||||
|
@ -200,17 +192,13 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
|
||||
/* static */ COrder* COrder::NewActionDie()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionDie;
|
||||
return order;
|
||||
return new COrder_Die;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionFollow(CUnit &dest)
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
COrder *order = new COrder(UnitActionFollow);
|
||||
|
||||
order->Action = UnitActionFollow;
|
||||
// Destination could be killed.
|
||||
// Should be handled in action, but is not possible!
|
||||
// Unit::Refs is used as timeout counter.
|
||||
|
@ -227,9 +215,8 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
|
||||
/* static */ COrder* COrder::NewActionMove(const Vec2i &pos)
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
COrder *order = new COrder(UnitActionMove);
|
||||
|
||||
order->Action = UnitActionMove;
|
||||
order->goalPos = pos;
|
||||
|
||||
return order;
|
||||
|
@ -241,20 +228,18 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
Assert(Map.Info.IsPointOnMap(currentPos));
|
||||
Assert(Map.Info.IsPointOnMap(dest));
|
||||
|
||||
COrder *order = new COrder;
|
||||
COrder_Patrol *order = new COrder_Patrol();
|
||||
|
||||
order->Action = UnitActionPatrol;
|
||||
order->goalPos = dest;
|
||||
order->Arg1.Patrol = currentPos;
|
||||
order->WayPoint = currentPos;
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionRepair(CUnit &unit, CUnit &target)
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
COrder *order = new COrder(UnitActionRepair);
|
||||
|
||||
order->Action = UnitActionRepair;
|
||||
if (target.Destroyed) {
|
||||
order->goalPos = target.tilePos + target.Type->GetHalfTileSize();
|
||||
} else {
|
||||
|
@ -268,9 +253,8 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
{
|
||||
Assert(Map.Info.IsPointOnMap(pos));
|
||||
|
||||
COrder *order = new COrder;
|
||||
COrder *order = new COrder(UnitActionRepair);
|
||||
|
||||
order->Action = UnitActionRepair;
|
||||
order->goalPos = pos;
|
||||
return order;
|
||||
}
|
||||
|
@ -293,11 +277,9 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
|
||||
/* static */ COrder* COrder::NewActionResource(CUnit &harvester, const Vec2i &pos)
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
COrder *order = new COrder(UnitActionResource);
|
||||
Vec2i ressourceLoc;
|
||||
|
||||
order->Action = UnitActionResource;
|
||||
|
||||
// Find the closest piece of wood next to a tile where the unit can move
|
||||
if (!FindTerrainType(0, (harvester.Type->MovementMask), 1, 20, harvester.Player, pos, &ressourceLoc)) {
|
||||
DebugPrint("FIXME: Give up???\n");
|
||||
|
@ -319,9 +301,8 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
|
||||
/* static */ COrder* COrder::NewActionResource(CUnit &mine)
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
COrder *order = new COrder(UnitActionResource);
|
||||
|
||||
order->Action = UnitActionResource;
|
||||
order->SetGoal(&mine);
|
||||
order->Range = 1;
|
||||
|
||||
|
@ -332,9 +313,8 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
|
||||
/* static */ COrder* COrder::NewActionReturnGoods(CUnit *depot)
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
COrder *order = new COrder(UnitActionReturnGoods);
|
||||
|
||||
order->Action = UnitActionReturnGoods;
|
||||
// Destination could be killed. NETWORK!
|
||||
if (depot && !depot->Destroyed) {
|
||||
order->SetGoal(depot);
|
||||
|
@ -374,19 +354,12 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
|
||||
/* static */ COrder* COrder::NewActionStandGround()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionStandGround;
|
||||
return order;
|
||||
return new COrder_StandGround;
|
||||
}
|
||||
|
||||
|
||||
/* static */ COrder* COrder::NewActionStill()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionStill;
|
||||
return order;
|
||||
return new COrder_Still;
|
||||
}
|
||||
|
||||
|
||||
|
@ -394,9 +367,8 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
|
||||
/* static */ COrder* COrder::NewActionTrain(CUnit &trainer, CUnitType &type)
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
COrder *order = new COrder(UnitActionTrain);
|
||||
|
||||
order->Action = UnitActionTrain;
|
||||
order->Arg1.Type = &type;
|
||||
// FIXME: if you give quick an other order, the resources are lost!
|
||||
trainer.Player->SubUnitType(type);
|
||||
|
@ -406,9 +378,7 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
|
||||
/* static */ COrder* COrder::NewActionTransformInto(CUnitType &type)
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionTransformInto;
|
||||
COrder *order = new COrder(UnitActionTransformInto);
|
||||
|
||||
order->Arg1.Type = &type;
|
||||
|
||||
|
@ -417,9 +387,8 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
|
||||
/* static */ COrder* COrder::NewActionUnload(const Vec2i &pos, CUnit *what)
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
COrder *order = new COrder(UnitActionUnload);
|
||||
|
||||
order->Action = UnitActionUnload;
|
||||
order->goalPos = pos;
|
||||
if (what && !what->Destroyed) {
|
||||
order->SetGoal(what);
|
||||
|
@ -430,9 +399,7 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
|
||||
/* static */ COrder* COrder::NewActionUpgradeTo(CUnit &unit, CUnitType &type)
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionUpgradeTo;
|
||||
COrder *order = new COrder(UnitActionUpgradeTo);
|
||||
|
||||
// FIXME: if you give quick an other order, the resources are lost!
|
||||
unit.Player->SubUnitType(type);
|
||||
|
@ -441,152 +408,10 @@ extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
|||
return order;
|
||||
}
|
||||
|
||||
#if 1 // currently needed for parsing
|
||||
/* static */ COrder* COrder::NewActionAttack()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionAttack;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionAttackGround()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionAttackGround;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionBoard()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionBoard;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionBuild()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionBuild;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionBuilt()
|
||||
{
|
||||
COrder *order = new COrder_Built;
|
||||
|
||||
order->Action = UnitActionBuilt;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionFollow()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionFollow;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionMove()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionMove;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionPatrol()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionPatrol;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionRepair()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionRepair;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionResearch()
|
||||
{
|
||||
COrder_Research *order = new COrder_Research;
|
||||
|
||||
order->Action = UnitActionResearch;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionResource()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionResource;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionReturnGoods()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionReturnGoods;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionSpellCast()
|
||||
{
|
||||
COrder *order = new COrder_SpellCast;
|
||||
|
||||
order->Action = UnitActionSpellCast;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionTrain()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionTrain;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionTransformInto()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionTransformInto;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionUnload()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionUnload;
|
||||
return order;
|
||||
}
|
||||
|
||||
/* static */ COrder* COrder::NewActionUpgradeTo()
|
||||
{
|
||||
COrder *order = new COrder;
|
||||
|
||||
order->Action = UnitActionUpgradeTo;
|
||||
return order;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
COrder* COrder::Clone() const
|
||||
{
|
||||
COrder *clone = new COrder();
|
||||
COrder *clone = new COrder(this->Action);
|
||||
|
||||
clone->Action = this->Action;
|
||||
clone->Range = this->Range;
|
||||
clone->MinRange = this->MinRange;
|
||||
clone->Width = this->Width;
|
||||
|
|
|
@ -102,8 +102,8 @@ struct lua_State;
|
|||
class COrder
|
||||
{
|
||||
public:
|
||||
COrder() : Goal(NULL), Range(0), MinRange(0), Width(0),
|
||||
Height(0), Action(UnitActionNone), CurrentResource(0)
|
||||
COrder(int action) : Goal(NULL), Range(0), MinRange(0), Width(0),
|
||||
Height(0), Action(action), CurrentResource(0)
|
||||
{
|
||||
goalPos.x = -1;
|
||||
goalPos.y = -1;
|
||||
|
@ -154,7 +154,7 @@ public:
|
|||
*/
|
||||
void NewResetPath() { Data.Move.Fast = 1; Data.Move.Length = 0; }
|
||||
void SaveDataMove(CFile &file) const;
|
||||
|
||||
bool ParseMoveData(lua_State *l, int &j, const char *value);
|
||||
|
||||
bool OnAiHitUnit(CUnit &unit, CUnit *attacker, int /*damage*/);
|
||||
void AiUnitKilled(CUnit &unit);
|
||||
|
@ -165,7 +165,6 @@ public:
|
|||
static COrder* NewActionAttackGround(const CUnit &attacker, const Vec2i &dest);
|
||||
static COrder* NewActionBoard(CUnit &unit);
|
||||
static COrder* NewActionBuild(const CUnit &builder, const Vec2i &pos, CUnitType &building);
|
||||
static COrder* NewActionBuilt();
|
||||
static COrder* NewActionBuilt(CUnit &builder, CUnit &unit);
|
||||
static COrder* NewActionDie();
|
||||
static COrder* NewActionFollow(CUnit &dest);
|
||||
|
@ -186,22 +185,19 @@ public:
|
|||
static COrder* NewActionUpgradeTo(CUnit &unit, CUnitType &type);
|
||||
|
||||
#if 1 // currently needed for parsing
|
||||
static COrder* NewActionAttack();
|
||||
static COrder* NewActionAttackGround();
|
||||
static COrder* NewActionBoard();
|
||||
static COrder* NewActionBuild();
|
||||
static COrder* NewActionFollow();
|
||||
static COrder* NewActionMove();
|
||||
static COrder* NewActionPatrol();
|
||||
static COrder* NewActionRepair();
|
||||
static COrder* NewActionResearch();
|
||||
static COrder* NewActionResource();
|
||||
static COrder* NewActionReturnGoods();
|
||||
static COrder* NewActionSpellCast();
|
||||
static COrder* NewActionTrain();
|
||||
static COrder* NewActionTransformInto();
|
||||
static COrder* NewActionUnload();
|
||||
static COrder* NewActionUpgradeTo();
|
||||
static COrder* NewActionAttack() { return new COrder(UnitActionAttack); }
|
||||
static COrder* NewActionAttackGround() { return new COrder(UnitActionAttackGround); }
|
||||
static COrder* NewActionBoard() { return new COrder(UnitActionBoard); }
|
||||
static COrder* NewActionBuild() { return new COrder(UnitActionBuild); }
|
||||
static COrder* NewActionFollow() { return new COrder(UnitActionFollow); }
|
||||
static COrder* NewActionMove() { return new COrder(UnitActionMove); }
|
||||
static COrder* NewActionRepair() { return new COrder(UnitActionRepair); }
|
||||
static COrder* NewActionResource() { return new COrder(UnitActionResource); }
|
||||
static COrder* NewActionReturnGoods() { return new COrder(UnitActionReturnGoods); }
|
||||
static COrder* NewActionTrain() { return new COrder(UnitActionTrain); }
|
||||
static COrder* NewActionTransformInto() { return new COrder(UnitActionTransformInto); }
|
||||
static COrder* NewActionUnload() { return new COrder(UnitActionUnload); }
|
||||
static COrder* NewActionUpgradeTo() { return new COrder(UnitActionUpgradeTo); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
@ -218,7 +214,6 @@ public:
|
|||
Vec2i goalPos; /// or tile coordinate of destination
|
||||
|
||||
union {
|
||||
Vec2i Patrol; /// position for patroling.
|
||||
struct {
|
||||
Vec2i Pos; /// position for terrain resource.
|
||||
CUnit *Mine;
|
||||
|
@ -257,7 +252,9 @@ class COrder_Built : public COrder
|
|||
{
|
||||
friend COrder* COrder::NewActionBuilt(CUnit &builder, CUnit &unit);
|
||||
public:
|
||||
virtual COrder_Built *Clone() const;
|
||||
COrder_Built() : COrder(UnitActionBuilt) {}
|
||||
|
||||
virtual COrder_Built *Clone() const { return new COrder_Built(*this); }
|
||||
|
||||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
@ -289,11 +286,45 @@ private:
|
|||
};
|
||||
|
||||
|
||||
class COrder_Die : public COrder
|
||||
{
|
||||
public:
|
||||
COrder_Die() : COrder(UnitActionDie) {}
|
||||
|
||||
virtual COrder_Die *Clone() const { return new COrder_Die(*this); }
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
class COrder_Patrol : public COrder
|
||||
{
|
||||
friend COrder* COrder::NewActionPatrol(const Vec2i ¤tPos, const Vec2i &dest);
|
||||
public:
|
||||
COrder_Patrol() : COrder(UnitActionPatrol) {}
|
||||
|
||||
virtual COrder_Patrol *Clone() const { return new COrder_Patrol(*this); }
|
||||
|
||||
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);
|
||||
|
||||
const Vec2i& GetWayPoint() const { return WayPoint; }
|
||||
private:
|
||||
Vec2i WayPoint; /// position for patroling.
|
||||
};
|
||||
|
||||
|
||||
class COrder_Research : public COrder
|
||||
{
|
||||
public:
|
||||
virtual COrder_Research *Clone() const;
|
||||
COrder_Research() : COrder(UnitActionResearch), Upgrade(NULL) {}
|
||||
|
||||
virtual COrder_Research *Clone() const { return new COrder_Research(*this); }
|
||||
|
||||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
@ -309,10 +340,12 @@ private:
|
|||
CUpgrade *Upgrade;
|
||||
};
|
||||
|
||||
class COrder_SpellCast: public COrder
|
||||
class COrder_SpellCast : public COrder
|
||||
{
|
||||
public:
|
||||
virtual COrder_SpellCast *Clone() const;
|
||||
COrder_SpellCast() : COrder(UnitActionSpellCast), Spell(NULL) {}
|
||||
|
||||
virtual COrder_SpellCast *Clone() const { return new COrder_SpellCast(*this); }
|
||||
|
||||
virtual void Save(CFile &file, const CUnit &unit) const;
|
||||
virtual bool ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit);
|
||||
|
@ -329,6 +362,36 @@ private:
|
|||
|
||||
|
||||
|
||||
|
||||
class COrder_StandGround : public COrder
|
||||
{
|
||||
public:
|
||||
COrder_StandGround() : COrder(UnitActionStandGround) {}
|
||||
|
||||
virtual COrder_StandGround *Clone() const { return new COrder_StandGround(*this); }
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
class COrder_Still : public COrder
|
||||
{
|
||||
public:
|
||||
COrder_Still() : COrder(UnitActionStill) {}
|
||||
|
||||
virtual COrder_Still *Clone() const { return new COrder_Still(*this); }
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Variables
|
||||
----------------------------------------------------------------------------*/
|
||||
|
@ -413,6 +476,10 @@ extern void DropResource(CUnit &unit);
|
|||
extern void ResourceGiveUp(CUnit &unit);
|
||||
extern int GetNumWaitingWorkers(const CUnit &mine);
|
||||
extern void AutoAttack(CUnit &unit, CUnitCache &targets, bool stand_ground);
|
||||
extern bool AutoAttack(CUnit &unit, bool stand_ground);
|
||||
extern bool AutoRepair(CUnit &unit);
|
||||
extern bool AutoCast(CUnit &unit);
|
||||
|
||||
extern void UnHideUnit(CUnit &unit);
|
||||
|
||||
typedef void HandleActionFunc(COrder& order, CUnit &unit);
|
||||
|
|
|
@ -287,7 +287,28 @@ extern int CclCommand(const std::string &command, bool exitOnError = true);
|
|||
|
||||
CUnit *CclGetUnitFromRef(lua_State *l);
|
||||
|
||||
|
||||
/**
|
||||
** Get a position from lua state
|
||||
**
|
||||
** @param l Lua state.
|
||||
** param x pointer to output x position.
|
||||
** @param y pointer to output y position.
|
||||
**
|
||||
** @return The unit pointer
|
||||
*/
|
||||
template <typename T>
|
||||
static void CclGetPos(lua_State *l, T *x , T *y, const int offset = -1)
|
||||
{
|
||||
if (!lua_istable(l, offset) || lua_objlen(l, offset) != 2) {
|
||||
LuaError(l, "incorrect argument");
|
||||
}
|
||||
lua_rawgeti(l, offset, 1);
|
||||
*x = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
lua_rawgeti(l, offset, 2);
|
||||
*y = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
|
||||
extern NumberDesc *Damage; /// Damage calculation for missile.
|
||||
|
||||
|
|
|
@ -132,29 +132,6 @@ CUnit *CclGetUnitFromRef(lua_State *l)
|
|||
return UnitSlots[slot];
|
||||
}
|
||||
|
||||
/**
|
||||
** Get a position from lua state
|
||||
**
|
||||
** @param l Lua state.
|
||||
** @param x pointer to output x position.
|
||||
** @param y pointer to output y position.
|
||||
**
|
||||
** @return The unit pointer
|
||||
*/
|
||||
template <typename T>
|
||||
static void CclGetPos(lua_State *l, T *x , T *y, const int offset = -1)
|
||||
{
|
||||
if (!lua_istable(l, offset) || lua_objlen(l, offset) != 2) {
|
||||
LuaError(l, "incorrect argument");
|
||||
}
|
||||
lua_rawgeti(l, offset, 1);
|
||||
*x = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
lua_rawgeti(l, offset, 2);
|
||||
*y = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
** Parse res worker data
|
||||
**
|
||||
|
@ -251,55 +228,6 @@ static void CclParseTrain(lua_State *l, COrderPtr order)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Parse stored data for move order
|
||||
**
|
||||
** @param l Lua state.
|
||||
** @param unit Unit pointer which should be filled with the data.
|
||||
*/
|
||||
static void CclParseMove(lua_State *l, COrderPtr order)
|
||||
{
|
||||
const char *value;
|
||||
int args;
|
||||
int j;
|
||||
|
||||
if (!lua_istable(l, -1)) {
|
||||
LuaError(l, "incorrect argument");
|
||||
}
|
||||
args = lua_objlen(l, -1);
|
||||
for (j = 0; j < args; ++j) {
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
value = LuaToString(l, -1);
|
||||
lua_pop(l, 1);
|
||||
++j;
|
||||
if (!strcmp(value, "cycles")) {
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
order->Data.Move.Cycles = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
} else if (!strcmp(value, "fast")) {
|
||||
order->Data.Move.Fast = 1;
|
||||
--j;
|
||||
} else if (!strcmp(value, "path")) {
|
||||
int subargs;
|
||||
int k;
|
||||
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
if (!lua_istable(l, -1)) {
|
||||
LuaError(l, "incorrect argument");
|
||||
}
|
||||
subargs = lua_objlen(l, -1);
|
||||
for (k = 0; k < subargs; ++k) {
|
||||
lua_rawgeti(l, -1, k + 1);
|
||||
order->Data.Move.Path[k] = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
order->Data.Move.Length = subargs;
|
||||
lua_pop(l, 1);
|
||||
} else {
|
||||
LuaError(l, "ParseMove: Unsupported tag: %s" _C_ value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool COrder::ParseGenericData(lua_State *l, int &j, const char *value)
|
||||
{
|
||||
|
@ -339,6 +267,52 @@ bool COrder::ParseGenericData(lua_State *l, int &j, const char *value)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool COrder::ParseMoveData(lua_State *l, int &j, const char *value)
|
||||
{
|
||||
if (strcmp(value, "data-move") != 0) {
|
||||
return false;
|
||||
}
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
|
||||
if (!lua_istable(l, -1)) {
|
||||
LuaError(l, "incorrect argument");
|
||||
}
|
||||
const int args = 1 + lua_objlen(l, -1);
|
||||
for (int i = 1; i < args; ++i) {
|
||||
lua_rawgeti(l, -1, i);
|
||||
const char *tag = LuaToString(l, -1);
|
||||
lua_pop(l, 1);
|
||||
++i;
|
||||
if (!strcmp(tag, "cycles")) {
|
||||
lua_rawgeti(l, -1, i);
|
||||
this->Data.Move.Cycles = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
} else if (!strcmp(tag, "fast")) {
|
||||
this->Data.Move.Fast = 1;
|
||||
--i;
|
||||
} else if (!strcmp(tag, "path")) {
|
||||
lua_rawgeti(l, -1, i);
|
||||
if (!lua_istable(l, -1)) {
|
||||
LuaError(l, "incorrect argument _");
|
||||
}
|
||||
const int subargs = lua_objlen(l, -1);
|
||||
for (int k = 0; k < subargs; ++k) {
|
||||
lua_rawgeti(l, -1, k + 1);
|
||||
this->Data.Move.Path[k] = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
this->Data.Move.Length = subargs;
|
||||
lua_pop(l, 1);
|
||||
} else {
|
||||
LuaError(l, "ParseMove: Unsupported tag: %s" _C_ tag);
|
||||
}
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool COrder::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit)
|
||||
{
|
||||
if (!strcmp(value, "type")) {
|
||||
|
@ -347,11 +321,6 @@ bool COrder::ParseSpecificData(lua_State *l, int &j, const char *value, const CU
|
|||
this->Arg1.Type = UnitTypeByIdent(LuaToString(l, -1));
|
||||
lua_pop(l, 1);
|
||||
|
||||
} else if (!strcmp(value, "patrol")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
CclGetPos(l, &this->Arg1.Patrol.x , &this->Arg1.Patrol.y);
|
||||
lua_pop(l, 1);
|
||||
} else if (!strcmp(value, "current-resource")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
|
@ -387,11 +356,6 @@ bool COrder::ParseSpecificData(lua_State *l, int &j, const char *value, const CU
|
|||
lua_rawgeti(l, -1, j + 1);
|
||||
CclParseTrain(l, this);
|
||||
lua_pop(l, 1);
|
||||
} else if (!strcmp(value, "data-move")) {
|
||||
++j;
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
CclParseMove(l, this);
|
||||
lua_pop(l, 1);
|
||||
} else if (!strcmp(value, "mine")) { /* old save format */
|
||||
int pos;
|
||||
++j;
|
||||
|
@ -439,9 +403,9 @@ void CclParseOrder(lua_State *l, const CUnit &unit, COrderPtr *orderPtr)
|
|||
lua_pop(l, 1);
|
||||
|
||||
if (!strcmp(actiontype, "action-still")) {
|
||||
*orderPtr = COrder::NewActionStill();
|
||||
*orderPtr = new COrder_Still;
|
||||
} else if (!strcmp(actiontype, "action-stand-ground")) {
|
||||
*orderPtr = COrder::NewActionStandGround();
|
||||
*orderPtr = new COrder_StandGround;
|
||||
} else if (!strcmp(actiontype, "action-follow")) {
|
||||
*orderPtr = COrder::NewActionFollow();
|
||||
} else if (!strcmp(actiontype, "action-move")) {
|
||||
|
@ -451,23 +415,23 @@ void CclParseOrder(lua_State *l, const CUnit &unit, COrderPtr *orderPtr)
|
|||
} else if (!strcmp(actiontype, "action-attack-ground")) {
|
||||
*orderPtr = COrder::NewActionAttackGround();
|
||||
} else if (!strcmp(actiontype, "action-die")) {
|
||||
*orderPtr = COrder::NewActionDie();
|
||||
*orderPtr = new COrder_Die;
|
||||
} else if (!strcmp(actiontype, "action-spell-cast")) {
|
||||
*orderPtr = COrder::NewActionSpellCast();
|
||||
*orderPtr = new COrder_SpellCast;
|
||||
} else if (!strcmp(actiontype, "action-train")) {
|
||||
*orderPtr = COrder::NewActionTrain();
|
||||
} else if (!strcmp(actiontype, "action-upgrade-to")) {
|
||||
*orderPtr = COrder::NewActionUpgradeTo();
|
||||
} else if (!strcmp(actiontype, "action-research")) {
|
||||
*orderPtr = COrder::NewActionResearch();
|
||||
*orderPtr = new COrder_Research;
|
||||
} else if (!strcmp(actiontype, "action-built")) {
|
||||
*orderPtr = COrder::NewActionBuilt();
|
||||
*orderPtr = new COrder_Built;
|
||||
} else if (!strcmp(actiontype, "action-board")) {
|
||||
*orderPtr = COrder::NewActionBoard();
|
||||
} else if (!strcmp(actiontype, "action-unload")) {
|
||||
*orderPtr = COrder::NewActionUnload();
|
||||
} else if (!strcmp(actiontype, "action-patrol")) {
|
||||
*orderPtr = COrder::NewActionPatrol();
|
||||
*orderPtr = new COrder_Patrol;
|
||||
} else if (!strcmp(actiontype, "action-build")) {
|
||||
*orderPtr = COrder::NewActionBuild();
|
||||
} else if (!strcmp(actiontype, "action-repair")) {
|
||||
|
|
|
@ -737,12 +737,15 @@ static void ShowSingleOrder(const CUnit &unit, const PixelPos &pos, const COrder
|
|||
break;
|
||||
|
||||
case UnitActionPatrol:
|
||||
{
|
||||
Video.DrawLineClip(ColorGreen, pos1.x, pos1.y, pos2.x, pos2.y);
|
||||
e_color = color = ColorBlue;
|
||||
pos1 = CurrentViewport->TilePosToScreen_Center(order.Arg1.Patrol);
|
||||
const COrder_Patrol &orderPatrol = static_cast<const COrder_Patrol&>(order);
|
||||
|
||||
pos1 = CurrentViewport->TilePosToScreen_Center(orderPatrol.GetWayPoint());
|
||||
dest = true;
|
||||
break;
|
||||
|
||||
}
|
||||
case UnitActionRepair:
|
||||
e_color = color = ColorGreen;
|
||||
dest = true;
|
||||
|
|
|
@ -96,12 +96,6 @@ void SaveOrder(const COrder &order, const CUnit &unit, CFile *file)
|
|||
case UnitActionNone:
|
||||
file.printf("\"action-none\",");
|
||||
break;
|
||||
case UnitActionStill:
|
||||
file.printf("\"action-still\",");
|
||||
break;
|
||||
case UnitActionStandGround:
|
||||
file.printf("\"action-stand-ground\",");
|
||||
break;
|
||||
case UnitActionFollow:
|
||||
file.printf("\"action-follow\",");
|
||||
break;
|
||||
|
@ -114,9 +108,6 @@ void SaveOrder(const COrder &order, const CUnit &unit, CFile *file)
|
|||
case UnitActionAttackGround:
|
||||
file.printf("\"action-attack-ground\",");
|
||||
break;
|
||||
case UnitActionDie:
|
||||
file.printf("\"action-die\",");
|
||||
break;
|
||||
case UnitActionTrain:
|
||||
file.printf("\"action-train\",");
|
||||
break;
|
||||
|
@ -129,9 +120,6 @@ void SaveOrder(const COrder &order, const CUnit &unit, CFile *file)
|
|||
case UnitActionUnload:
|
||||
file.printf("\"action-unload\",");
|
||||
break;
|
||||
case UnitActionPatrol:
|
||||
file.printf("\"action-patrol\",");
|
||||
break;
|
||||
case UnitActionBuild:
|
||||
file.printf("\"action-build\",");
|
||||
break;
|
||||
|
@ -174,9 +162,6 @@ void SaveOrder(const COrder &order, const CUnit &unit, CFile *file)
|
|||
case UnitActionTransformInto:
|
||||
file.printf(", \"type\", \"%s\"", order.Arg1.Type->Ident.c_str());
|
||||
break;
|
||||
case UnitActionPatrol:
|
||||
file.printf(", \"patrol\", {%d, %d}", order.Arg1.Patrol.x, order.Arg1.Patrol.y);
|
||||
break;
|
||||
case UnitActionResource :
|
||||
case UnitActionReturnGoods :
|
||||
if (order.CurrentResource) {
|
||||
|
|
Loading…
Add table
Reference in a new issue