Replace some COrder in CUnit by pointer.
Begin to have order and action more linked.
This commit is contained in:
parent
0bd9d6ad4c
commit
12e8eb6846
28 changed files with 289 additions and 392 deletions
src
action
action_attack.cppaction_board.cppaction_build.cppaction_die.cppaction_follow.cppaction_move.cppaction_patrol.cppaction_repair.cppaction_research.cppaction_resource.cppaction_returngoods.cppaction_spellcast.cppaction_stand.cppaction_still.cppaction_train.cppaction_unload.cppaction_upgradeto.cppactions.cppcommand.cpp
ai
include
map
stratagus
unit
|
@ -135,31 +135,21 @@ static int CheckForDeadGoal(CUnit &unit)
|
|||
*/
|
||||
static int CheckForTargetInRange(CUnit &unit)
|
||||
{
|
||||
|
||||
//
|
||||
// Target is dead?
|
||||
//
|
||||
if (CheckForDeadGoal(unit)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
COrderPtr order = unit.CurrentOrder();
|
||||
|
||||
//
|
||||
// No goal: if meeting enemy attack it.
|
||||
//
|
||||
if (!order->HasGoal() &&
|
||||
order->Action != UnitActionAttackGround &&
|
||||
!Map.WallOnMap(order->goalPos)) {
|
||||
CUnit *goal = AttackUnitsInReactRange(unit);
|
||||
|
||||
if (goal) {
|
||||
#ifdef DEBUG
|
||||
if (unit.StoreOrder()) {
|
||||
Assert(!order->HasGoal());
|
||||
}
|
||||
#else
|
||||
unit.StoreOrder();
|
||||
#endif
|
||||
|
||||
order->SetGoal(goal);
|
||||
order->MinRange = unit.Type->MinAttackRange;
|
||||
order->Range = unit.Stats->Variables[ATTACKRANGE_INDEX].Max;
|
||||
|
@ -167,13 +157,11 @@ static int CheckForTargetInRange(CUnit &unit)
|
|||
unit.SubAction |= WEAK_TARGET; // weak target
|
||||
NewResetPath(*order);
|
||||
}
|
||||
|
||||
//
|
||||
// Have a weak target, try a better target.
|
||||
//
|
||||
} else if (order->HasGoal() && (unit.SubAction & WEAK_TARGET)) {
|
||||
CUnit *goal = order->GetGoal();
|
||||
CUnit *temp = AttackUnitsInReactRange(unit);
|
||||
|
||||
if (temp && temp->Type->Priority > goal->Type->Priority) {
|
||||
unit.StoreOrder();
|
||||
order->SetGoal(temp);
|
||||
|
@ -183,8 +171,7 @@ static int CheckForTargetInRange(CUnit &unit)
|
|||
}
|
||||
|
||||
Assert(!unit.Type->Vanishes && !unit.Destroyed && !unit.Removed);
|
||||
Assert(order->Action == UnitActionAttack ||
|
||||
order->Action == UnitActionAttackGround);
|
||||
Assert(order->Action == UnitActionAttack || order->Action == UnitActionAttackGround);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -406,13 +393,10 @@ static void AttackTarget(CUnit &unit)
|
|||
**
|
||||
** @param unit Unit, for that the attack is handled.
|
||||
*/
|
||||
void HandleActionAttack(CUnit &unit)
|
||||
void HandleActionAttack(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
|
||||
Assert(unit.CurrentAction() == UnitActionAttackGround ||
|
||||
unit.CurrentAction() == UnitActionAttack);
|
||||
Assert(unit.CurrentOrder()->HasGoal() ||
|
||||
(unit.CurrentOrder()->goalPos.x != -1 && unit.CurrentOrder()->goalPos.y != -1));
|
||||
Assert(order.Action == UnitActionAttackGround || order.Action == UnitActionAttack);
|
||||
Assert(order.HasGoal() || (order.goalPos.x != -1 && order.goalPos.y != -1));
|
||||
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
|
@ -429,8 +413,8 @@ void HandleActionAttack(CUnit &unit)
|
|||
return;
|
||||
}
|
||||
// Can we already attack ?
|
||||
if (unit.CurrentOrder()->HasGoal()) {
|
||||
CUnit *goal = unit.CurrentOrder()->GetGoal();
|
||||
if (order.HasGoal()) {
|
||||
CUnit *goal = order.GetGoal();
|
||||
// dist between unit and unit.CurrentOrder()->Goal.
|
||||
int dist = goal->MapDistanceTo(unit);
|
||||
if (unit.Type->MinAttackRange < dist &&
|
||||
|
@ -444,7 +428,7 @@ void HandleActionAttack(CUnit &unit)
|
|||
}
|
||||
}
|
||||
unit.SubAction = MOVE_TO_TARGET;
|
||||
NewResetPath(*unit.CurrentOrder());
|
||||
NewResetPath(order);
|
||||
//
|
||||
// FIXME: should use a reachable place to reduce pathfinder time.
|
||||
//
|
||||
|
|
|
@ -175,12 +175,10 @@ static void EnterTransporter(CUnit &unit)
|
|||
**
|
||||
** @param unit Pointer to unit.
|
||||
*/
|
||||
void HandleActionBoard(CUnit &unit)
|
||||
void HandleActionBoard(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
switch (unit.SubAction) {
|
||||
//
|
||||
// Wait for transporter
|
||||
//
|
||||
case 201:
|
||||
if (WaitForTransporter(unit)) {
|
||||
unit.SubAction = 202;
|
||||
|
@ -188,21 +186,17 @@ void HandleActionBoard(CUnit &unit)
|
|||
UnitShowAnimation(unit, unit.Type->Animations->Still[GetAnimationDamagedState(unit,1)]);
|
||||
}
|
||||
break;
|
||||
//
|
||||
// Enter transporter
|
||||
//
|
||||
case 202:
|
||||
EnterTransporter(unit);
|
||||
break;
|
||||
//
|
||||
// Move to transporter
|
||||
//
|
||||
case 0:
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
return;
|
||||
}
|
||||
NewResetPath(*unit.CurrentOrder());
|
||||
NewResetPath(order);
|
||||
unit.SubAction = 1;
|
||||
// FALL THROUGH
|
||||
default:
|
||||
|
@ -213,13 +207,13 @@ void HandleActionBoard(CUnit &unit)
|
|||
if (i == PF_UNREACHABLE) {
|
||||
if (++unit.SubAction == 200) {
|
||||
unit.ClearAction();
|
||||
unit.CurrentOrder()->ClearGoal();
|
||||
order.ClearGoal();
|
||||
} else {
|
||||
//
|
||||
// Try with a bigger range.
|
||||
//
|
||||
if (unit.CurrentOrder()->CheckRange()) {
|
||||
unit.CurrentOrder()->Range++;
|
||||
if (order.CheckRange()) {
|
||||
order.Range++;
|
||||
unit.SubAction--;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -408,7 +408,7 @@ static void BuildBuilding(CUnit &unit)
|
|||
**
|
||||
** @param unit Unit that builds a building
|
||||
*/
|
||||
void HandleActionBuild(CUnit &unit)
|
||||
void HandleActionBuild(CUnit::COrder& /*order*/, CUnit &unit)
|
||||
{
|
||||
CUnit *ontop;
|
||||
|
||||
|
@ -430,7 +430,7 @@ void HandleActionBuild(CUnit &unit)
|
|||
**
|
||||
** @param unit Unit that is being built
|
||||
*/
|
||||
void HandleActionBuilt(CUnit &unit)
|
||||
void HandleActionBuilt(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
CUnit *worker;
|
||||
CUnitType *type;
|
||||
|
@ -446,8 +446,8 @@ void HandleActionBuilt(CUnit &unit)
|
|||
smod = (unit.Stats->Costs[TimeCost] * 600) - unit.Variable[SHIELD_INDEX].Value;
|
||||
|
||||
// n is the current damage taken by the unit.
|
||||
n = (unit.CurrentOrder()->Data.Built.Progress * unit.Variable[HP_INDEX].Max + (mod - 1)) / mod;
|
||||
sn = (unit.CurrentOrder()->Data.Built.Progress * unit.Variable[SHIELD_INDEX].Max + (smod - 1)) / smod;
|
||||
n = (order.Data.Built.Progress * unit.Variable[HP_INDEX].Max + (mod - 1)) / mod;
|
||||
sn = (order.Data.Built.Progress * unit.Variable[SHIELD_INDEX].Max + (smod - 1)) / smod;
|
||||
|
||||
// This below is most often 0
|
||||
if (type->BuilderOutside) {
|
||||
|
@ -459,14 +459,14 @@ void HandleActionBuilt(CUnit &unit)
|
|||
}
|
||||
// Building speeds increase or decrease.
|
||||
progress *= SpeedBuild;
|
||||
oldprogress = unit.CurrentOrder()->Data.Built.Progress;
|
||||
unit.CurrentOrder()->Data.Built.Progress += progress;
|
||||
oldprogress = order.Data.Built.Progress;
|
||||
order.Data.Built.Progress += progress;
|
||||
// mod is use for round to upper and use it as cache
|
||||
mod = type->Stats[unit.Player->Index].Costs[TimeCost] * 600;
|
||||
|
||||
// Keep the same level of damage while increasing HP.
|
||||
unit.Variable[HP_INDEX].Value +=
|
||||
(unit.CurrentOrder()->Data.Built.Progress * unit.Variable[HP_INDEX].Max + (mod - n - 1)) / (mod - n) -
|
||||
(order.Data.Built.Progress * unit.Variable[HP_INDEX].Max + (mod - n - 1)) / (mod - n) -
|
||||
(oldprogress * unit.Variable[HP_INDEX].Max + (mod - n - 1)) / (mod - n);
|
||||
if (unit.Variable[HP_INDEX].Value > unit.Stats->Variables[HP_INDEX].Max) {
|
||||
unit.Variable[HP_INDEX].Value = unit.Stats->Variables[HP_INDEX].Max;
|
||||
|
@ -474,21 +474,18 @@ void HandleActionBuilt(CUnit &unit)
|
|||
if (unit.Variable[SHIELD_INDEX].Max > 0)
|
||||
{
|
||||
unit.Variable[SHIELD_INDEX].Value +=
|
||||
(unit.CurrentOrder()->Data.Built.Progress * unit.Variable[SHIELD_INDEX].Max + (mod - sn - 1)) / (mod - sn) -
|
||||
(order.Data.Built.Progress * unit.Variable[SHIELD_INDEX].Max + (mod - sn - 1)) / (mod - sn) -
|
||||
(oldprogress * unit.Variable[SHIELD_INDEX].Max + (mod - sn - 1)) / (mod - sn);
|
||||
if (unit.Variable[SHIELD_INDEX].Value > unit.Stats->Variables[SHIELD_INDEX].Max) {
|
||||
unit.Variable[SHIELD_INDEX].Value = unit.Stats->Variables[SHIELD_INDEX].Max;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check if construction should be canceled...
|
||||
//
|
||||
if (unit.CurrentOrder()->Data.Built.Cancel || unit.CurrentOrder()->Data.Built.Progress < 0) {
|
||||
DebugPrint("%d: %s canceled.\n" _C_ unit.Player->Index
|
||||
_C_ unit.Type->Name.c_str());
|
||||
if (order.Data.Built.Cancel || order.Data.Built.Progress < 0) {
|
||||
DebugPrint("%d: %s canceled.\n" _C_ unit.Player->Index _C_ unit.Type->Name.c_str());
|
||||
// Drop out unit
|
||||
if ((worker = unit.CurrentOrder()->Data.Built.Worker)) {
|
||||
if ((worker = order.Data.Built.Worker)) {
|
||||
|
||||
worker->CurrentOrder()->ClearGoal();
|
||||
worker->ClearAction();
|
||||
|
@ -512,7 +509,7 @@ void HandleActionBuilt(CUnit &unit)
|
|||
// Check if building ready. Note we can both build and repair.
|
||||
//
|
||||
//if (unit.CurrentOrder()->Data.Built.Progress >= unit.Stats->Costs[TimeCost] * 600 ||
|
||||
if (!unit.CurrentOrder()->Data.Built.Worker->Anim.Unbreakable && (unit.CurrentOrder()->Data.Built.Progress >= mod ||
|
||||
if (!order.Data.Built.Worker->Anim.Unbreakable && (order.Data.Built.Progress >= mod ||
|
||||
unit.Variable[HP_INDEX].Value >= unit.Stats->Variables[HP_INDEX].Max)) {
|
||||
DebugPrint("%d: Building %s(%s) ready.\n" _C_ unit.Player->Index
|
||||
_C_ unit.Type->Ident.c_str() _C_ unit.Type->Name.c_str() );
|
||||
|
|
|
@ -53,8 +53,10 @@
|
|||
**
|
||||
** @param unit The unit which dies.
|
||||
*/
|
||||
void HandleActionDie(CUnit &unit)
|
||||
void HandleActionDie(CUnit::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]);
|
||||
|
@ -92,10 +94,6 @@ void HandleActionDie(CUnit &unit)
|
|||
unit.Stats = &unit.Type->Stats[unit.Player->Index];
|
||||
unit.Place(unit.tilePos);
|
||||
|
||||
// We must be dead to get here, it we aren't we need to know why
|
||||
// This assert replaces and old DEBUG message "Reset to die is really needed"
|
||||
Assert(unit.CurrentAction() == UnitActionDie);
|
||||
|
||||
unit.SubAction = 0;
|
||||
unit.Frame = 0;
|
||||
UnitUpdateHeading(unit);
|
||||
|
|
|
@ -58,34 +58,28 @@
|
|||
**
|
||||
** @param unit Pointer to unit.
|
||||
*/
|
||||
void HandleActionFollow(CUnit &unit)
|
||||
void HandleActionFollow(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
CUnit *goal;
|
||||
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
return;
|
||||
}
|
||||
CUnit *goal = order.GetGoal();
|
||||
|
||||
//
|
||||
// Reached target
|
||||
//
|
||||
if (unit.SubAction == 128) {
|
||||
COrderPtr order = unit.CurrentOrder();
|
||||
goal = order->GetGoal();
|
||||
|
||||
if (!goal || !goal->IsVisibleAsGoal(*unit.Player)) {
|
||||
DebugPrint("Goal gone\n");
|
||||
order->ClearGoal();
|
||||
order.ClearGoal();
|
||||
unit.ClearAction();
|
||||
return;
|
||||
}
|
||||
|
||||
if (goal->tilePos == order->goalPos) {
|
||||
|
||||
if (goal->tilePos == order.goalPos) {
|
||||
// Move to the next order
|
||||
if (unit.OrderCount > 1) {
|
||||
order->ClearGoal();
|
||||
order.ClearGoal();
|
||||
unit.ClearAction();
|
||||
return;
|
||||
}
|
||||
|
@ -95,40 +89,36 @@ void HandleActionFollow(CUnit &unit)
|
|||
unit.Frame = unit.Type->StillFrame;
|
||||
UnitUpdateHeading(unit);
|
||||
unit.Wait = 10;
|
||||
if (order->Range > 1) {
|
||||
order->Range = 1;
|
||||
if (order.Range > 1) {
|
||||
order.Range = 1;
|
||||
unit.SubAction = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
unit.SubAction = 0;
|
||||
}
|
||||
|
||||
if (!unit.SubAction) { // first entry
|
||||
unit.SubAction = 1;
|
||||
NewResetPath(*unit.CurrentOrder());
|
||||
NewResetPath(order);
|
||||
Assert(unit.State == 0);
|
||||
}
|
||||
|
||||
switch (DoActionMove(unit)) { // reached end-point?
|
||||
case PF_UNREACHABLE:
|
||||
//
|
||||
// Some tries to reach the goal
|
||||
//
|
||||
if (unit.CurrentOrder()->CheckRange()) {
|
||||
unit.CurrentOrder()->Range++;
|
||||
if (order.CheckRange()) {
|
||||
order.Range++;
|
||||
break;
|
||||
}
|
||||
// FALL THROUGH
|
||||
case PF_REACHED:
|
||||
{
|
||||
if (!goal) { // goal has died
|
||||
unit.ClearAction();
|
||||
return;
|
||||
}
|
||||
// Handle Teleporter Units
|
||||
// FIXME: BAD HACK
|
||||
if ((goal = unit.CurrentOrder()->GetGoal()) &&
|
||||
goal->Type->Teleporter && goal->Goal &&
|
||||
unit.MapDistanceTo(*goal) <= 1) {
|
||||
CUnit *dest;
|
||||
|
||||
if (goal->Type->Teleporter && goal->Goal && unit.MapDistanceTo(*goal) <= 1) {
|
||||
// Teleport the unit
|
||||
unit.Remove(NULL);
|
||||
unit.tilePos = goal->Goal->tilePos;
|
||||
|
@ -145,83 +135,63 @@ void HandleActionFollow(CUnit &unit)
|
|||
#endif
|
||||
unit.ClearAction();
|
||||
|
||||
//
|
||||
// FIXME: we must check if the units supports the new order.
|
||||
//
|
||||
dest = goal->Goal;
|
||||
CUnit &dest = *goal->Goal;
|
||||
|
||||
if (dest) {
|
||||
if ((dest->NewOrder.Action == UnitActionResource &&
|
||||
!unit.Type->Harvester) ||
|
||||
(dest->NewOrder.Action == UnitActionAttack &&
|
||||
!unit.Type->CanAttack) ||
|
||||
(dest->NewOrder.Action == UnitActionBoard &&
|
||||
unit.Type->UnitType != UnitTypeLand)) {
|
||||
DebugPrint("Wrong order for unit\n");
|
||||
unit.ClearAction();
|
||||
unit.CurrentOrder()->ClearGoal();
|
||||
} else {
|
||||
if (dest->NewOrder.HasGoal()) {
|
||||
if (dest->NewOrder.GetGoal()->Destroyed) {
|
||||
// FIXME: perhaps we should use another dest?
|
||||
DebugPrint("Destroyed unit in teleport unit\n");
|
||||
dest->RefsDecrease();///???????
|
||||
dest->NewOrder.ClearGoal();
|
||||
dest->NewOrder.Action = UnitActionStill;
|
||||
}
|
||||
if (dest.NewOrder == NULL
|
||||
|| (dest.NewOrder->Action == UnitActionResource && !unit.Type->Harvester)
|
||||
|| (dest.NewOrder->Action == UnitActionAttack && !unit.Type->CanAttack)
|
||||
|| (dest.NewOrder->Action == UnitActionBoard && unit.Type->UnitType != UnitTypeLand)) {
|
||||
unit.ClearAction();
|
||||
unit.CurrentOrder()->ClearGoal();
|
||||
} else {
|
||||
if (dest.NewOrder->HasGoal()) {
|
||||
if (dest.NewOrder->GetGoal()->Destroyed) {
|
||||
// FIXME: perhaps we should use another dest?
|
||||
DebugPrint("Destroyed unit in teleport unit\n");
|
||||
dest.NewOrder->ClearGoal();
|
||||
dest.NewOrder->Action = UnitActionStill;
|
||||
}
|
||||
|
||||
*(unit.CurrentOrder()) = dest->NewOrder;
|
||||
unit.CurrentResource = dest->CurrentResource;
|
||||
|
||||
}
|
||||
|
||||
*(unit.CurrentOrder()) = *dest.NewOrder;
|
||||
unit.CurrentResource = dest.CurrentResource;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
goal = unit.CurrentOrder()->GetGoal();
|
||||
if (!goal) { // goal has died
|
||||
unit.ClearAction();
|
||||
return;
|
||||
}
|
||||
unit.CurrentOrder()->goalPos = goal->tilePos;
|
||||
order.goalPos = goal->tilePos;
|
||||
unit.SubAction = 128;
|
||||
|
||||
}
|
||||
// FALL THROUGH
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Target destroyed?
|
||||
//
|
||||
goal = unit.CurrentOrder()->GetGoal();
|
||||
if (goal && !goal->IsVisibleAsGoal(*unit.Player)) {
|
||||
DebugPrint("Goal gone\n");
|
||||
unit.CurrentOrder()->goalPos = goal->tilePos + goal->Type->GetHalfTileSize();
|
||||
unit.CurrentOrder()->ClearGoal();
|
||||
order.goalPos = goal->tilePos + goal->Type->GetHalfTileSize();
|
||||
order.ClearGoal();
|
||||
goal = NoUnitP;
|
||||
NewResetPath(*unit.CurrentOrder());
|
||||
NewResetPath(order);
|
||||
}
|
||||
|
||||
if (!unit.Anim.Unbreakable) {
|
||||
//
|
||||
// If our leader is dead or stops or attacks:
|
||||
// Attack any enemy in reaction range.
|
||||
// If don't set the goal, the unit can than choose a
|
||||
// better goal if moving nearer to enemy.
|
||||
//
|
||||
if (unit.Type->CanAttack &&
|
||||
(!goal || goal->CurrentAction() == UnitActionAttack ||
|
||||
goal->CurrentAction() == UnitActionStill)) {
|
||||
if (unit.Type->CanAttack
|
||||
&& (!goal || goal->CurrentAction() == UnitActionAttack || goal->CurrentAction() == UnitActionStill)) {
|
||||
goal = AttackUnitsInReactRange(unit);
|
||||
if (goal) {
|
||||
CommandAttack(unit, goal->tilePos, NULL, FlushCommands);
|
||||
// Save current command to come back.
|
||||
unit.SavedOrder = *(unit.CurrentOrder());
|
||||
|
||||
unit.SavedOrder = order;
|
||||
// This stops the follow command and the attack is executed
|
||||
order.ClearGoal();
|
||||
unit.ClearAction();
|
||||
unit.CurrentOrder()->ClearGoal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ int DoActionMove(CUnit &unit)
|
|||
**
|
||||
** @param unit Pointer to unit.
|
||||
*/
|
||||
void HandleActionMove(CUnit &unit)
|
||||
void HandleActionMove(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
CUnit *goal;
|
||||
|
||||
|
@ -186,7 +186,7 @@ void HandleActionMove(CUnit &unit)
|
|||
if (!unit.SubAction) { // first entry
|
||||
unit.SubAction = 1;
|
||||
NewResetPath(*unit.CurrentOrder());
|
||||
unit.CurrentOrder()->Data.Move.Cycles = 0;
|
||||
order.Data.Move.Cycles = 0;
|
||||
Assert(unit.State == 0);
|
||||
}
|
||||
|
||||
|
@ -197,14 +197,14 @@ void HandleActionMove(CUnit &unit)
|
|||
//
|
||||
// Some tries to reach the goal
|
||||
//
|
||||
if (unit.CurrentOrder()->CheckRange()) {
|
||||
unit.CurrentOrder()->Range++;
|
||||
if (order.CheckRange()) {
|
||||
order.Range++;
|
||||
break;
|
||||
}
|
||||
// FALL THROUGH
|
||||
case PF_REACHED:
|
||||
// Release target, if any.
|
||||
unit.CurrentOrder()->ClearGoal();
|
||||
order.ClearGoal();
|
||||
unit.ClearAction();
|
||||
return;
|
||||
|
||||
|
@ -215,12 +215,12 @@ void HandleActionMove(CUnit &unit)
|
|||
//
|
||||
// Target destroyed?
|
||||
//
|
||||
goal = unit.CurrentOrder()->GetGoal();
|
||||
goal = order.GetGoal();
|
||||
if (goal && goal->Destroyed) {
|
||||
DebugPrint("Goal dead\n");
|
||||
unit.CurrentOrder()->goalPos = goal->tilePos + goal->Type->GetHalfTileSize();
|
||||
unit.CurrentOrder()->ClearGoal();
|
||||
NewResetPath(*unit.CurrentOrder());
|
||||
order.goalPos = goal->tilePos + goal->Type->GetHalfTileSize();
|
||||
order.ClearGoal();
|
||||
NewResetPath(order);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ static void SwapPatrolPoints(CUnit &unit)
|
|||
**
|
||||
** @param unit Patroling unit pointer.
|
||||
*/
|
||||
void HandleActionPatrol(CUnit &unit)
|
||||
void HandleActionPatrol(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
|
@ -83,8 +83,8 @@ void HandleActionPatrol(CUnit &unit)
|
|||
}
|
||||
|
||||
if (!unit.SubAction) { // first entry.
|
||||
unit.CurrentOrder()->Data.Move.Cycles = 0; //moving counter
|
||||
NewResetPath(*unit.CurrentOrder());
|
||||
order.Data.Move.Cycles = 0; //moving counter
|
||||
NewResetPath(order);
|
||||
unit.SubAction = 1;
|
||||
}
|
||||
|
||||
|
@ -95,14 +95,14 @@ void HandleActionPatrol(CUnit &unit)
|
|||
case PF_UNREACHABLE:
|
||||
// Increase range and try again
|
||||
unit.SubAction = 1;
|
||||
if (unit.CurrentOrder()->CheckRange()) {
|
||||
unit.CurrentOrder()->Range++;
|
||||
if (order.CheckRange()) {
|
||||
order.Range++;
|
||||
break;
|
||||
}
|
||||
// FALL THROUGH
|
||||
case PF_REACHED:
|
||||
unit.SubAction = 1;
|
||||
unit.CurrentOrder()->Range = 0;
|
||||
order.Range = 0;
|
||||
SwapPatrolPoints(unit);
|
||||
break;
|
||||
case PF_WAIT:
|
||||
|
@ -110,7 +110,7 @@ void HandleActionPatrol(CUnit &unit)
|
|||
unit.SubAction++;
|
||||
if (unit.SubAction == 5) {
|
||||
unit.SubAction = 1;
|
||||
unit.CurrentOrder()->Range = 0;
|
||||
order.Range = 0;
|
||||
SwapPatrolPoints(unit);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -144,59 +144,51 @@ static int AnimateActionRepair(CUnit &unit)
|
|||
**
|
||||
** @param unit Unit, for that the attack is handled.
|
||||
*/
|
||||
void HandleActionRepair(CUnit &unit)
|
||||
void HandleActionRepair(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
CUnit *goal;
|
||||
int err;
|
||||
|
||||
switch (unit.SubAction) {
|
||||
case 0:
|
||||
NewResetPath(*unit.CurrentOrder());
|
||||
NewResetPath(order);
|
||||
unit.SubAction = 1;
|
||||
// FALL THROUGH
|
||||
//
|
||||
// Move near to target.
|
||||
//
|
||||
case 1:
|
||||
case 1:// Move near to target.
|
||||
// FIXME: RESET FIRST!! Why? We move first and than check if
|
||||
// something is in sight.
|
||||
err = DoActionMove(unit);
|
||||
if (!unit.Anim.Unbreakable) {
|
||||
//
|
||||
// No goal: if meeting damaged building repair it.
|
||||
//
|
||||
goal = unit.CurrentOrder()->GetGoal();
|
||||
goal = order.GetGoal();
|
||||
|
||||
//
|
||||
// Target is dead, choose new one.
|
||||
//
|
||||
// Check if goal is correct unit.
|
||||
if (goal) {
|
||||
if (!goal->IsVisibleAsGoal(*unit.Player)) {
|
||||
DebugPrint("repair target gone.\n");
|
||||
unit.CurrentOrder()->goalPos = goal->tilePos;
|
||||
order.goalPos = goal->tilePos;
|
||||
// FIXME: should I clear this here?
|
||||
unit.CurrentOrder()->ClearGoal();
|
||||
order.ClearGoal();
|
||||
goal = NULL;
|
||||
NewResetPath(*unit.CurrentOrder());
|
||||
NewResetPath(order);
|
||||
}
|
||||
} else if (unit.Player->AiEnabled) {
|
||||
// Ai players workers should stop if target is killed
|
||||
err = -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Have reached target? FIXME: could use return value
|
||||
//
|
||||
if (goal && unit.MapDistanceTo(*goal) <= unit.Type->RepairRange &&
|
||||
goal->Variable[HP_INDEX].Value < goal->Variable[HP_INDEX].Max) {
|
||||
unit.State = 0;
|
||||
unit.SubAction = 2;
|
||||
unit.CurrentOrder()->Data.Repair.Cycles = 0;
|
||||
order.Data.Repair.Cycles = 0;
|
||||
const Vec2i dir = goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos;
|
||||
UnitHeadingFromDeltaXY(unit, dir);
|
||||
} else if (err < 0) {
|
||||
unit.CurrentOrder()->ClearGoal();
|
||||
order.ClearGoal();
|
||||
if (!unit.RestoreOrder()) {
|
||||
unit.ClearAction();
|
||||
unit.State = 0;
|
||||
|
@ -209,16 +201,12 @@ void HandleActionRepair(CUnit &unit)
|
|||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// Repair the target.
|
||||
//
|
||||
case 2:
|
||||
case 2:// Repair the target.
|
||||
AnimateActionRepair(unit);
|
||||
unit.CurrentOrder()->Data.Repair.Cycles++;
|
||||
order.Data.Repair.Cycles++;
|
||||
if (!unit.Anim.Unbreakable) {
|
||||
goal = unit.CurrentOrder()->GetGoal();
|
||||
|
||||
//
|
||||
// Target is dead, choose new one.
|
||||
//
|
||||
// Check if goal is correct unit.
|
||||
|
@ -226,16 +214,16 @@ void HandleActionRepair(CUnit &unit)
|
|||
if (goal) {
|
||||
if (!goal->IsVisibleAsGoal(*unit.Player)) {
|
||||
DebugPrint("repair goal is gone\n");
|
||||
unit.CurrentOrder()->goalPos = goal->tilePos;
|
||||
order.goalPos = goal->tilePos;
|
||||
// FIXME: should I clear this here?
|
||||
unit.CurrentOrder()->ClearGoal();
|
||||
order.ClearGoal();
|
||||
goal = NULL;
|
||||
NewResetPath(*unit.CurrentOrder());
|
||||
NewResetPath(order);
|
||||
} else {
|
||||
int dist = unit.MapDistanceTo(*goal);
|
||||
if (dist <= unit.Type->RepairRange) {
|
||||
RepairUnit(unit, *goal);
|
||||
goal = unit.CurrentOrder()->GetGoal();
|
||||
goal = order.GetGoal();
|
||||
} else if (dist > unit.Type->RepairRange) {
|
||||
// If goal has move, chase after it
|
||||
unit.State = 0;
|
||||
|
@ -244,20 +232,15 @@ void HandleActionRepair(CUnit &unit)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Target is fine, choose new one.
|
||||
//
|
||||
if (!goal || goal->Variable[HP_INDEX].Value >=
|
||||
goal->Variable[HP_INDEX].Max) {
|
||||
unit.CurrentOrder()->ClearGoal();
|
||||
if (!goal || goal->Variable[HP_INDEX].Value >= goal->Variable[HP_INDEX].Max) {
|
||||
order.ClearGoal();
|
||||
if (!unit.RestoreOrder()) {
|
||||
unit.ClearAction();
|
||||
unit.State = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: automatic repair
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "stratagus.h"
|
||||
#include "video.h"
|
||||
#include "sound.h"
|
||||
#include "unitsound.h"
|
||||
#include "unittype.h"
|
||||
|
@ -47,7 +46,6 @@
|
|||
#include "actions.h"
|
||||
#include "upgrade_structs.h"
|
||||
#include "upgrade.h"
|
||||
#include "interface.h"
|
||||
#include "ai.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
@ -59,19 +57,17 @@
|
|||
**
|
||||
** @param unit Pointer of researching unit.
|
||||
*/
|
||||
void HandleActionResearch(CUnit &unit)
|
||||
void HandleActionResearch(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
const CUpgrade *upgrade;
|
||||
|
||||
if (!unit.SubAction) { // first entry
|
||||
upgrade = unit.CurrentOrder()->Data.Research.Upgrade = unit.CurrentOrder()->Arg1.Upgrade;
|
||||
upgrade = order.Data.Research.Upgrade = order.Arg1.Upgrade;
|
||||
#if 0
|
||||
// FIXME: I want to support both, but with network we need this check
|
||||
// but if want combined upgrades this is worse
|
||||
|
||||
//
|
||||
// Check if an other building has already started?
|
||||
//
|
||||
if (unit.Player->UpgradeTimers.Upgrades[upgrade - Upgrades]) {
|
||||
DebugPrint("Two researches running\n");
|
||||
PlayerAddCosts(unit.Player, upgrade->Costs);
|
||||
|
@ -82,7 +78,7 @@ void HandleActionResearch(CUnit &unit)
|
|||
#endif
|
||||
unit.SubAction = 1;
|
||||
} else {
|
||||
upgrade = unit.CurrentOrder()->Data.Research.Upgrade;
|
||||
upgrade = order.Data.Research.Upgrade;
|
||||
}
|
||||
|
||||
unit.Type->Animations->Research ?
|
||||
|
@ -94,8 +90,7 @@ void HandleActionResearch(CUnit &unit)
|
|||
}
|
||||
|
||||
unit.Player->UpgradeTimers.Upgrades[upgrade->ID] += SpeedResearch;
|
||||
if (unit.Player->UpgradeTimers.Upgrades[upgrade->ID] >=
|
||||
upgrade->Costs[TimeCost]) {
|
||||
if (unit.Player->UpgradeTimers.Upgrades[upgrade->ID] >= upgrade->Costs[TimeCost]) {
|
||||
|
||||
unit.Player->Notify(NotifyGreen, unit.tilePos.x, unit.tilePos.y,
|
||||
_("%s: research complete"), unit.Type->Name.c_str());
|
||||
|
@ -108,12 +103,9 @@ void HandleActionResearch(CUnit &unit)
|
|||
AiResearchComplete(unit, upgrade);
|
||||
}
|
||||
UpgradeAcquire(*unit.Player, upgrade);
|
||||
|
||||
unit.ClearAction();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
unit.Wait = CYCLES_PER_SECOND / 6;
|
||||
}
|
||||
|
||||
|
|
|
@ -885,7 +885,7 @@ static bool ActionResourceInit(CUnit &unit)
|
|||
**
|
||||
** @param unit Pointer to unit.
|
||||
*/
|
||||
void HandleActionResource(CUnit &unit)
|
||||
void HandleActionResource(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
if (unit.Wait) {
|
||||
// FIXME: show idle animation while we wait?
|
||||
|
@ -997,15 +997,14 @@ void HandleActionResource(CUnit &unit)
|
|||
if (unit.SubAction == SUB_RETURN_RESOURCE) {
|
||||
if (WaitInDepot(unit)) {
|
||||
unit.SubAction = SUB_START_RESOURCE;
|
||||
//
|
||||
|
||||
// It's posible, though very rare that the unit's goal blows up
|
||||
// this cycle, but after this unit. Thus, next frame the unit
|
||||
// will start mining a destroyed site. If, on the otherhand we
|
||||
// are already in SUB_MOVE_TO_RESOURCE then we can handle it.
|
||||
// So, we pass through SUB_START_RESOURCE the very instant it
|
||||
// goes out of the depot.
|
||||
//
|
||||
HandleActionResource(unit);
|
||||
HandleActionResource(order, unit);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
**
|
||||
** @todo FIXME: move this into action_resource?
|
||||
*/
|
||||
void HandleActionReturnGoods(CUnit &unit)
|
||||
void HandleActionReturnGoods(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
Assert(unit.Type->Harvester);
|
||||
|
||||
|
@ -71,23 +71,23 @@ void HandleActionReturnGoods(CUnit &unit)
|
|||
}
|
||||
|
||||
// If depot was destroyed search for another one.
|
||||
if (!unit.CurrentOrder()->HasGoal()) {
|
||||
if (!order.HasGoal()) {
|
||||
CUnit *destu;
|
||||
|
||||
if (!(destu = FindDeposit(unit, 1000, unit.CurrentResource))) {
|
||||
ResourceGiveUp(unit);
|
||||
return;
|
||||
}
|
||||
unit.CurrentOrder()->SetGoal(destu);
|
||||
order.SetGoal(destu);
|
||||
}
|
||||
|
||||
unit.CurrentOrder()->Action = UnitActionResource;
|
||||
order.Action = UnitActionResource;
|
||||
// Somewhere on the way the loaded worker could have change Arg1
|
||||
// Bummer, go get the closest resource to the depot
|
||||
//FIXME!!!!!!!!!!!!!!!!!!!!
|
||||
//unit.CurrentOrder()->Arg1.ResourcePos = -1;
|
||||
|
||||
NewResetPath(*unit.CurrentOrder());
|
||||
NewResetPath(order);
|
||||
unit.SubAction = /* SUB_MOVE_TO_DEPOT */ 70; // FIXME : Define value.
|
||||
}
|
||||
|
||||
|
|
|
@ -135,24 +135,18 @@ static void SpellMoveToTarget(CUnit &unit)
|
|||
**
|
||||
** @param unit Unit, for that the spell cast is handled.
|
||||
*/
|
||||
void HandleActionSpellCast(CUnit &unit)
|
||||
void HandleActionSpellCast(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
if (unit.Wait) {
|
||||
unit.Wait--;
|
||||
return;
|
||||
}
|
||||
COrderPtr order = unit.CurrentOrder();
|
||||
const SpellType *spell = order->Arg1.Spell;
|
||||
const SpellType *spell = order.Arg1.Spell;
|
||||
switch (unit.SubAction) {
|
||||
case 0:
|
||||
//
|
||||
// Check if we can cast the spell.
|
||||
//
|
||||
if (!CanCastSpell(unit, spell, order->GetGoal(), order->goalPos.x, order->goalPos.y)) {
|
||||
|
||||
//
|
||||
if (!CanCastSpell(unit, spell, order.GetGoal(), order.goalPos.x, order.goalPos.y)) {
|
||||
// Notify player about this problem
|
||||
//
|
||||
if (unit.Variable[MANA_INDEX].Value < spell->ManaCost) {
|
||||
unit.Player->Notify(NotifyYellow, unit.tilePos.x, unit.tilePos.y,
|
||||
_("%s: not enough mana for spell: %s"),
|
||||
|
@ -166,8 +160,8 @@ void HandleActionSpellCast(CUnit &unit)
|
|||
if (unit.Player->AiEnabled) {
|
||||
DebugPrint("FIXME: do we need an AI callback?\n");
|
||||
}
|
||||
order.ClearGoal(); // Release references
|
||||
unit.ClearAction();
|
||||
order->ClearGoal(); // Release references
|
||||
return;
|
||||
}
|
||||
// FIXME FIXME FIXME: Check if already in range and skip straight to 2(casting)
|
||||
|
@ -194,16 +188,16 @@ void HandleActionSpellCast(CUnit &unit)
|
|||
}
|
||||
} else {
|
||||
// FIXME: what todo, if unit/goal is removed?
|
||||
CUnit *goal = order->GetGoal();
|
||||
CUnit *goal = order.GetGoal();
|
||||
if (goal && goal != &unit && !goal->IsVisibleAsGoal(*unit.Player)) {
|
||||
unit.ReCast = 0;
|
||||
} else {
|
||||
unit.ReCast = SpellCast(unit, spell, goal, order->goalPos.x, order->goalPos.y);
|
||||
unit.ReCast = SpellCast(unit, spell, goal, order.goalPos.x, order.goalPos.y);
|
||||
}
|
||||
}
|
||||
if (!unit.ReCast && unit.CurrentAction() != UnitActionDie) {
|
||||
order.ClearGoal(); // Release references
|
||||
unit.ClearAction();
|
||||
order->ClearGoal(); // Release references
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
**
|
||||
** @param unit Action handled for this unit pointer.
|
||||
*/
|
||||
void HandleActionStandGround(CUnit &unit)
|
||||
void HandleActionStandGround(CUnit::COrder& /*order*/, CUnit &unit)
|
||||
{
|
||||
ActionStillGeneric(unit, true);
|
||||
}
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
#include "missile.h"
|
||||
#include "unittype.h"
|
||||
#include "animation.h"
|
||||
#include "actions.h"
|
||||
#include "unit.h"
|
||||
#include "actions.h"
|
||||
#include "tileset.h"
|
||||
#include "map.h"
|
||||
#include "pathfinder.h"
|
||||
|
@ -387,7 +387,7 @@ void ActionStillGeneric(CUnit &unit, bool stand_ground)
|
|||
**
|
||||
** @param unit Unit pointer for still action.
|
||||
*/
|
||||
void HandleActionStill(CUnit &unit)
|
||||
void HandleActionStill(CUnit::COrder& /*order*/, CUnit &unit)
|
||||
{
|
||||
ActionStillGeneric(unit, false);
|
||||
}
|
||||
|
|
|
@ -61,29 +61,32 @@
|
|||
** @param unit Newly trained unit.
|
||||
** @param order New order for the unit.
|
||||
**
|
||||
** @return 1 if the the unit can do it, 0 otherwise.
|
||||
** @return true if the the unit can do it, false otherwise.
|
||||
*/
|
||||
static int CanHandleOrder(CUnit &unit, COrderPtr order)
|
||||
static bool CanHandleOrder(CUnit &unit, COrderPtr order)
|
||||
{
|
||||
if (order == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (order->Action == UnitActionResource) {
|
||||
// Check if new unit can harvest.
|
||||
if (!unit.Type->Harvester) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
// Also check if new unit can harvest this specific resource.
|
||||
CUnit *goal = order->GetGoal();
|
||||
if (goal && !unit.Type->ResInfo[goal->Type->GivesResource]) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
if (order->Action == UnitActionAttack && !unit.Type->CanAttack) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (order->Action == UnitActionBoard && unit.Type->UnitType != UnitTypeLand) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,11 +94,11 @@ static int CanHandleOrder(CUnit &unit, COrderPtr order)
|
|||
**
|
||||
** @param unit Unit that trains.
|
||||
*/
|
||||
void HandleActionTrain(CUnit &unit)
|
||||
void HandleActionTrain(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
// First entry
|
||||
if (!unit.SubAction) {
|
||||
unit.CurrentOrder()->Data.Train.Ticks = 0;
|
||||
order.Data.Train.Ticks = 0;
|
||||
unit.SubAction = 1;
|
||||
}
|
||||
|
||||
|
@ -109,32 +112,27 @@ void HandleActionTrain(CUnit &unit)
|
|||
}
|
||||
|
||||
CPlayer *player = unit.Player;
|
||||
CUnitType &ntype = *unit.CurrentOrder()->Arg1.Type;
|
||||
CUnitType &ntype = *order.Arg1.Type;
|
||||
const int cost = ntype.Stats[player->Index].Costs[TimeCost];
|
||||
unit.CurrentOrder()->Data.Train.Ticks += SpeedTrain;
|
||||
order.Data.Train.Ticks += SpeedTrain;
|
||||
// FIXME: Should count down
|
||||
if (unit.CurrentOrder()->Data.Train.Ticks >= cost) {
|
||||
if (order.Data.Train.Ticks >= cost) {
|
||||
order.Data.Train.Ticks = cost;
|
||||
|
||||
unit.CurrentOrder()->Data.Train.Ticks = cost;
|
||||
|
||||
//
|
||||
// Check if there are still unit slots.
|
||||
//
|
||||
if (NumUnits >= UnitMax) {
|
||||
unit.Wait = CYCLES_PER_SECOND / 6;
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if enough supply available.
|
||||
//
|
||||
const int food = player->CheckLimits(ntype);
|
||||
if (food < 0) {
|
||||
if (food == -3 && unit.Player->AiEnabled) {
|
||||
AiNeedMoreSupply(*unit.Player);
|
||||
}
|
||||
|
||||
unit.CurrentOrder()->Data.Train.Ticks = cost;
|
||||
order.Data.Train.Ticks = cost;
|
||||
unit.Wait = CYCLES_PER_SECOND / 6;
|
||||
return;
|
||||
}
|
||||
|
@ -184,23 +182,24 @@ void HandleActionTrain(CUnit &unit)
|
|||
unit.SubAction = 0;
|
||||
}
|
||||
|
||||
if (!CanHandleOrder(*nunit, &unit.NewOrder)) {
|
||||
DebugPrint("Wrong order for unit\n");
|
||||
if (unit.NewOrder && unit.NewOrder->HasGoal()
|
||||
&& unit.NewOrder->GetGoal()->Destroyed) {
|
||||
// FIXME: perhaps we should use another goal?
|
||||
DebugPrint("Destroyed unit in train unit\n");
|
||||
|
||||
delete unit.NewOrder;
|
||||
unit.NewOrder = NULL;
|
||||
}
|
||||
|
||||
if (CanHandleOrder(*nunit, unit.NewOrder) == true) {
|
||||
*(nunit->CurrentOrder()) = *unit.NewOrder;
|
||||
#if 0
|
||||
} else {
|
||||
// Tell the unit to move instead of trying any funny stuff.
|
||||
*(nunit->CurrentOrder()) = unit.NewOrder;
|
||||
nunit->CurrentOrder()->Action = UnitActionMove;
|
||||
nunit->CurrentOrder()->ClearGoal();
|
||||
} else {
|
||||
if (unit.NewOrder.HasGoal()) {
|
||||
if (unit.NewOrder.GetGoal()->Destroyed) {
|
||||
// FIXME: perhaps we should use another goal?
|
||||
DebugPrint("Destroyed unit in train unit\n");
|
||||
unit.NewOrder.ClearGoal();
|
||||
unit.NewOrder.Action = UnitActionStill;
|
||||
}
|
||||
}
|
||||
*(nunit->CurrentOrder()) = unit.NewOrder;
|
||||
#endif
|
||||
}
|
||||
if (IsOnlySelected(unit)) {
|
||||
UI.ButtonPanel.Update();
|
||||
|
|
|
@ -323,7 +323,7 @@ static void LeaveTransporter(CUnit &transporter)
|
|||
**
|
||||
** @param unit Pointer to unit.
|
||||
*/
|
||||
void HandleActionUnload(CUnit &unit)
|
||||
void HandleActionUnload(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
const int maxSearchRange = 20;
|
||||
|
||||
|
@ -332,15 +332,15 @@ void HandleActionUnload(CUnit &unit)
|
|||
}
|
||||
switch (unit.SubAction) {
|
||||
case 0: // Choose destination
|
||||
if (!unit.CurrentOrder()->HasGoal()) {
|
||||
if (!order.HasGoal()) {
|
||||
Vec2i pos;
|
||||
|
||||
if (!ClosestFreeDropZone(unit, unit.CurrentOrder()->goalPos, maxSearchRange, &pos)) {
|
||||
if (!ClosestFreeDropZone(unit, order.goalPos, maxSearchRange, &pos)) {
|
||||
// Sorry... I give up.
|
||||
unit.ClearAction();
|
||||
return;
|
||||
}
|
||||
unit.CurrentOrder()->goalPos = pos;
|
||||
order.goalPos = pos;
|
||||
}
|
||||
|
||||
NewResetPath(*unit.CurrentOrder());
|
||||
|
@ -367,7 +367,7 @@ void HandleActionUnload(CUnit &unit)
|
|||
// FIXME: show still animations ?
|
||||
LeaveTransporter(unit);
|
||||
if (unit.CanMove() && unit.CurrentAction() != UnitActionStill) {
|
||||
HandleActionUnload(unit);
|
||||
HandleActionUnload(*unit.CurrentOrder() , unit);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -134,11 +134,10 @@ static int TransformUnitIntoType(CUnit &unit, CUnitType &newtype)
|
|||
**
|
||||
** @param unit Pointer to unit.
|
||||
*/
|
||||
void HandleActionTransformInto(CUnit &unit)
|
||||
void HandleActionTransformInto(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
// What to do if an error occurs ?
|
||||
TransformUnitIntoType(unit, *unit.CriticalOrder.Arg1.Type);
|
||||
unit.CriticalOrder.Action = UnitActionStill;
|
||||
TransformUnitIntoType(unit, *order.Arg1.Type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,10 +145,10 @@ void HandleActionTransformInto(CUnit &unit)
|
|||
**
|
||||
** @param unit Pointer to unit.
|
||||
*/
|
||||
void HandleActionUpgradeTo(CUnit &unit)
|
||||
void HandleActionUpgradeTo(CUnit::COrder& order, CUnit &unit)
|
||||
{
|
||||
if (!unit.SubAction) { // first entry
|
||||
unit.CurrentOrder()->Data.UpgradeTo.Ticks = 0;
|
||||
order.Data.UpgradeTo.Ticks = 0;
|
||||
unit.SubAction = 1;
|
||||
}
|
||||
unit.Type->Animations->Upgrade ?
|
||||
|
@ -160,12 +159,12 @@ void HandleActionUpgradeTo(CUnit &unit)
|
|||
return;
|
||||
}
|
||||
CPlayer *player = unit.Player;
|
||||
CUnitType &newtype = *unit.CurrentOrder()->Arg1.Type;
|
||||
CUnitType &newtype = *order.Arg1.Type;
|
||||
const CUnitStats *newstats = &newtype.Stats[player->Index];
|
||||
|
||||
// FIXME: Should count down here
|
||||
unit.CurrentOrder()->Data.UpgradeTo.Ticks += SpeedUpgrade;
|
||||
if (unit.CurrentOrder()->Data.UpgradeTo.Ticks < newstats->Costs[TimeCost]) {
|
||||
order.Data.UpgradeTo.Ticks += SpeedUpgrade;
|
||||
if (order.Data.UpgradeTo.Ticks < newstats->Costs[TimeCost]) {
|
||||
unit.Wait = CYCLES_PER_SECOND / 6;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -255,7 +255,7 @@ int UnitShowAnimationScaled(CUnit &unit, const CAnimation *anim, int scale)
|
|||
**
|
||||
** @param unit Unit pointer for none action.
|
||||
*/
|
||||
static void HandleActionNone(CUnit &unit)
|
||||
static void HandleActionNone(CUnit::COrder&, CUnit &unit)
|
||||
{
|
||||
DebugPrint("FIXME: Should not happen!\n");
|
||||
DebugPrint("FIXME: Unit (%d) %s has action none.!\n" _C_
|
||||
|
@ -267,7 +267,7 @@ static void HandleActionNone(CUnit &unit)
|
|||
**
|
||||
** @param unit Unit pointer for not written action.
|
||||
*/
|
||||
static void HandleActionNotWritten(CUnit &unit)
|
||||
static void HandleActionNotWritten(CUnit::COrder&, CUnit &unit)
|
||||
{
|
||||
DebugPrint("FIXME: Not written!\n");
|
||||
DebugPrint("FIXME: Unit (%d) %s has action %d.!\n" _C_
|
||||
|
@ -279,7 +279,7 @@ static void HandleActionNotWritten(CUnit &unit)
|
|||
**
|
||||
** @note can move function into unit structure.
|
||||
*/
|
||||
static void (*HandleActionTable[256])(CUnit &) = {
|
||||
static void (*HandleActionTable[256])(CUnit::COrder&, CUnit &) = {
|
||||
HandleActionNone,
|
||||
HandleActionStill,
|
||||
HandleActionStandGround,
|
||||
|
@ -465,9 +465,9 @@ static void HandleBuffs(CUnit &unit, int amount)
|
|||
}
|
||||
}
|
||||
|
||||
static void RunAction(unsigned char action, CUnit &unit)
|
||||
static void RunAction(CUnit::COrder &order, CUnit &unit)
|
||||
{
|
||||
HandleActionTable[action](unit);
|
||||
HandleActionTable[order.Action](order, unit);
|
||||
}
|
||||
|
||||
|
||||
|
@ -478,19 +478,16 @@ static void RunAction(unsigned char action, CUnit &unit)
|
|||
*/
|
||||
static void HandleUnitAction(CUnit &unit)
|
||||
{
|
||||
//
|
||||
// If current action is breakable proceed with next one.
|
||||
//
|
||||
if (!unit.Anim.Unbreakable) {
|
||||
if (unit.CriticalOrder.Action != UnitActionStill) {
|
||||
HandleActionTable[unit.CriticalOrder.Action](unit);
|
||||
unit.CriticalOrder.Action = UnitActionStill;
|
||||
if (unit.CriticalOrder != NULL) {
|
||||
RunAction(*unit.CriticalOrder, unit);
|
||||
delete unit.CriticalOrder;
|
||||
unit.CriticalOrder = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// o Look if we have a new order and old finished.
|
||||
// o Or the order queue should be flushed.
|
||||
//
|
||||
if (unit.OrderCount > 1 &&
|
||||
(unit.CurrentAction() == UnitActionStill || unit.OrderFlush)) {
|
||||
|
||||
|
@ -524,10 +521,8 @@ static void HandleUnitAction(CUnit &unit)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Select action.
|
||||
//
|
||||
RunAction(unit.CurrentAction(), unit);
|
||||
RunAction(*unit.CurrentOrder(), unit);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -544,8 +539,7 @@ void UnitActions()
|
|||
int i;
|
||||
int tabsize;
|
||||
|
||||
buffsthiscycle = regenthiscycle = blinkthiscycle =
|
||||
!(GameCycle % CYCLES_PER_SECOND);
|
||||
buffsthiscycle = regenthiscycle = blinkthiscycle = !(GameCycle % CYCLES_PER_SECOND);
|
||||
|
||||
memcpy(table, Units, NumUnits * sizeof(CUnit *));
|
||||
tabsize = NumUnits;
|
||||
|
|
|
@ -148,18 +148,16 @@ static void ClearSavedAction(CUnit &unit)
|
|||
*/
|
||||
void CommandStopUnit(CUnit &unit)
|
||||
{
|
||||
COrderPtr order;
|
||||
|
||||
// Ignore that the unit could be removed.
|
||||
|
||||
order = GetNextOrder(unit, FlushCommands); // Flush them.
|
||||
COrderPtr order = GetNextOrder(unit, FlushCommands); // Flush them.
|
||||
Assert(order);
|
||||
order->Init();
|
||||
|
||||
order->Action = UnitActionStill;
|
||||
unit.SavedOrder.Release();
|
||||
unit.NewOrder.Release();
|
||||
unit.SavedOrder = unit.NewOrder = *order;
|
||||
unit.SavedOrder = *order;
|
||||
delete unit.NewOrder;
|
||||
unit.NewOrder = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -227,8 +225,9 @@ void CommandStandGround(CUnit &unit, int flush)
|
|||
|
||||
if (unit.Type->Building) {
|
||||
// FIXME: should find a better way for pending orders.
|
||||
order = &unit.NewOrder;
|
||||
order->Release();
|
||||
delete unit.NewOrder;
|
||||
unit.NewOrder = new CUnit::COrder;
|
||||
order = unit.NewOrder;
|
||||
} else if (!(order = GetNextOrder(unit, flush))) {
|
||||
return;
|
||||
}
|
||||
|
@ -254,8 +253,9 @@ void CommandFollow(CUnit &unit, CUnit &dest, int flush)
|
|||
if (!unit.Removed && unit.CurrentAction() != UnitActionDie) {
|
||||
if (!unit.CanMove()) {
|
||||
// FIXME: should find a better way for pending orders.
|
||||
order = &unit.NewOrder;
|
||||
order->Release();
|
||||
delete unit.NewOrder;
|
||||
unit.NewOrder = new CUnit::COrder;
|
||||
order = unit.NewOrder;
|
||||
} else if (!(order = GetNextOrder(unit, flush))) {
|
||||
return;
|
||||
}
|
||||
|
@ -296,8 +296,9 @@ void CommandMove(CUnit &unit, const Vec2i &pos, int flush)
|
|||
if (!unit.Removed && unit.CurrentAction() != UnitActionDie) {
|
||||
if (!unit.CanMove()) {
|
||||
// FIXME: should find a better way for pending orders.
|
||||
order = &unit.NewOrder;
|
||||
order->Release();
|
||||
delete unit.NewOrder;
|
||||
unit.NewOrder = new CUnit::COrder;
|
||||
order = unit.NewOrder;
|
||||
} else if (!(order = GetNextOrder(unit, flush))) {
|
||||
return;
|
||||
}
|
||||
|
@ -326,8 +327,9 @@ void CommandRepair(CUnit &unit, const Vec2i &pos, CUnit *dest, int flush)
|
|||
if (!unit.Removed && unit.CurrentAction() != UnitActionDie) {
|
||||
if (unit.Type->Building) {
|
||||
// FIXME: should find a better way for pending orders.
|
||||
order = &unit.NewOrder;
|
||||
order->Release();
|
||||
delete unit.NewOrder;
|
||||
unit.NewOrder = new CUnit::COrder;
|
||||
order = unit.NewOrder;
|
||||
} else if (!(order = GetNextOrder(unit, flush))) {
|
||||
return;
|
||||
}
|
||||
|
@ -389,8 +391,9 @@ void CommandAttack(CUnit &unit, const Vec2i &pos, CUnit *attack, int flush)
|
|||
if (!unit.Removed && unit.CurrentAction() != UnitActionDie) {
|
||||
if (!unit.Type->CanAttack) {
|
||||
// FIXME: should find a better way for pending orders.
|
||||
order = &unit.NewOrder;
|
||||
order->Release();
|
||||
delete unit.NewOrder;
|
||||
unit.NewOrder = new CUnit::COrder;
|
||||
order = unit.NewOrder;
|
||||
} else if (!(order = GetNextOrder(unit, flush))) {
|
||||
return;
|
||||
}
|
||||
|
@ -442,8 +445,9 @@ void CommandAttackGround(CUnit &unit, const Vec2i &pos, int flush)
|
|||
if (!unit.Removed && unit.CurrentAction() != UnitActionDie) {
|
||||
if (unit.Type->Building) {
|
||||
// FIXME: should find a better way for pending orders.
|
||||
order = &unit.NewOrder;
|
||||
order->Release();
|
||||
delete unit.NewOrder;
|
||||
unit.NewOrder = new CUnit::COrder;
|
||||
order = unit.NewOrder;
|
||||
} else if (!(order = GetNextOrder(unit, flush))) {
|
||||
return;
|
||||
}
|
||||
|
@ -480,8 +484,9 @@ void CommandPatrolUnit(CUnit &unit, const Vec2i &pos, int flush)
|
|||
if (!unit.Removed && unit.CurrentAction() != UnitActionDie) {
|
||||
if (!unit.CanMove()) {
|
||||
// FIXME: should find a better way for pending orders.
|
||||
order = &unit.NewOrder;
|
||||
order->Release();
|
||||
delete unit.NewOrder;
|
||||
unit.NewOrder = new CUnit::COrder;
|
||||
order = unit.NewOrder;
|
||||
} else if (!(order = GetNextOrder(unit, flush))) {
|
||||
return;
|
||||
}
|
||||
|
@ -521,8 +526,9 @@ void CommandBoard(CUnit &unit, CUnit &dest, int flush)
|
|||
|
||||
if (unit.Type->Building) {
|
||||
// FIXME: should find a better way for pending orders.
|
||||
order = &unit.NewOrder;
|
||||
order->Release();
|
||||
delete unit.NewOrder;
|
||||
unit.NewOrder = new CUnit::COrder;
|
||||
order = unit.NewOrder;
|
||||
} else if (!(order = GetNextOrder(unit, flush))) {
|
||||
return;
|
||||
}
|
||||
|
@ -588,8 +594,9 @@ void CommandBuildBuilding(CUnit &unit, const Vec2i &pos, CUnitType &what, int fl
|
|||
if (!unit.Removed && unit.CurrentAction() != UnitActionDie) {
|
||||
if (unit.Type->Building) {
|
||||
// FIXME: should find a better way for pending orders.
|
||||
order = &unit.NewOrder;
|
||||
order->Release();
|
||||
delete unit.NewOrder;
|
||||
unit.NewOrder = new CUnit::COrder;
|
||||
order = unit.NewOrder;
|
||||
} else if (!(order = GetNextOrder(unit, flush))) {
|
||||
return;
|
||||
}
|
||||
|
@ -653,8 +660,9 @@ void CommandResourceLoc(CUnit &unit, const Vec2i &pos, int flush)
|
|||
if (!unit.Removed && unit.CurrentAction() != UnitActionDie) {
|
||||
if (unit.Type->Building) {
|
||||
// FIXME: should find a better way for pending orders.
|
||||
order = &unit.NewOrder;
|
||||
order->Release();
|
||||
delete unit.NewOrder;
|
||||
unit.NewOrder = new CUnit::COrder;
|
||||
order = unit.NewOrder;
|
||||
} else if (!(order = GetNextOrder(unit, flush))) {
|
||||
return;
|
||||
}
|
||||
|
@ -707,8 +715,9 @@ void CommandResource(CUnit &unit, CUnit &dest, int flush)
|
|||
|
||||
if (unit.Type->Building) {
|
||||
// FIXME: should find a better way for pending orders.
|
||||
order = &unit.NewOrder;
|
||||
order->Release();
|
||||
delete unit.NewOrder;
|
||||
unit.NewOrder = new CUnit::COrder;
|
||||
order = unit.NewOrder;
|
||||
} else if (!(order = GetNextOrder(unit, flush))) {
|
||||
return;
|
||||
}
|
||||
|
@ -743,8 +752,9 @@ void CommandReturnGoods(CUnit &unit, CUnit *goal, int flush)
|
|||
|
||||
if (unit.Type->Building) {
|
||||
// FIXME: should find a better way for pending orders.
|
||||
order = &unit.NewOrder;
|
||||
order->Release();
|
||||
delete unit.NewOrder;
|
||||
unit.NewOrder = new CUnit::COrder;
|
||||
order = unit.NewOrder;
|
||||
} else if (!(order = GetNextOrder(unit, flush))) {
|
||||
return;
|
||||
}
|
||||
|
@ -917,14 +927,13 @@ void CommandUpgradeTo(CUnit &unit, CUnitType &type, int flush)
|
|||
*/
|
||||
void CommandTransformIntoType(CUnit &unit, CUnitType &type)
|
||||
{
|
||||
COrderPtr order;
|
||||
COrderPtr order = new CUnit::COrder;
|
||||
|
||||
Assert(unit.CriticalOrder.Action == UnitActionStill);
|
||||
order = &unit.CriticalOrder;
|
||||
order->Init();
|
||||
Assert(unit.CriticalOrder == NULL);
|
||||
|
||||
order->Action = UnitActionTransformInto;
|
||||
order->Arg1.Type = &type;
|
||||
unit.CriticalOrder = order;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "unittype.h"
|
||||
#include "map.h"
|
||||
#include "pathfinder.h"
|
||||
#include "unit.h"
|
||||
#include "actions.h"
|
||||
#include "ai_local.h"
|
||||
|
||||
|
|
|
@ -151,52 +151,54 @@ extern int GetNumWaitingWorkers(const CUnit &mine);
|
|||
extern void AutoAttack(CUnit &unit, CUnitCache &targets, bool stand_ground);
|
||||
extern void UnHideUnit(CUnit &unit);
|
||||
|
||||
typedef void HandleActionFunc(CUnit::COrder& order, CUnit &unit);
|
||||
|
||||
/// Generic still action
|
||||
extern void ActionStillGeneric(CUnit &unit, bool stand_ground);
|
||||
/// Handle command still
|
||||
extern void HandleActionStill(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionStill;
|
||||
/// Handle command stand ground
|
||||
extern void HandleActionStandGround(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionStandGround;
|
||||
/// Handle command follow
|
||||
extern void HandleActionFollow(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionFollow;
|
||||
/// Generic move action
|
||||
extern int DoActionMove(CUnit &unit);
|
||||
/// Handle command move
|
||||
extern void HandleActionMove(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionMove;
|
||||
/// Handle command repair
|
||||
extern void HandleActionRepair(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionRepair;
|
||||
/// Handle command patrol
|
||||
extern void HandleActionPatrol(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionPatrol;
|
||||
/// Show attack animation
|
||||
extern void AnimateActionAttack(CUnit &unit);
|
||||
/// Handle command attack
|
||||
extern void HandleActionAttack(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionAttack;
|
||||
/// Handle command board
|
||||
extern void HandleActionBoard(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionBoard;
|
||||
/// Handle command unload
|
||||
extern void HandleActionUnload(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionUnload;
|
||||
/// Handle command resource
|
||||
extern void HandleActionResource(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionResource;
|
||||
/// Handle command return
|
||||
extern void HandleActionReturnGoods(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionReturnGoods;
|
||||
/// Handle command die
|
||||
extern void HandleActionDie(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionDie;
|
||||
/// Handle command build
|
||||
extern void HandleActionBuild(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionBuild;
|
||||
/// Handle command built
|
||||
extern void HandleActionBuilt(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionBuilt;
|
||||
/// Handle command train
|
||||
extern void HandleActionTrain(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionTrain;
|
||||
/// Handle command upgrade to
|
||||
extern void HandleActionUpgradeTo(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionUpgradeTo;
|
||||
/// Handle command transform into
|
||||
extern void HandleActionTransformInto(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionTransformInto;
|
||||
/// Handle command upgrade
|
||||
extern void HandleActionUpgrade(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionUpgrade;
|
||||
/// Handle command research
|
||||
extern void HandleActionResearch(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionResearch;
|
||||
/// Handle command spellcast
|
||||
extern void HandleActionSpellCast(CUnit &unit);
|
||||
extern HandleActionFunc HandleActionSpellCast;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Actions: actions.c
|
||||
|
|
|
@ -537,7 +537,7 @@ public:
|
|||
void Release();
|
||||
void ReleaseRefs(CUnit &owner);
|
||||
COrder& operator=(const COrder &rhs);
|
||||
bool CheckRange();
|
||||
bool CheckRange() const;
|
||||
|
||||
void Init() {
|
||||
Assert(Action != UnitActionResource
|
||||
|
@ -645,7 +645,7 @@ public:
|
|||
} Data; /// Storage room for different commands
|
||||
};
|
||||
|
||||
CUnit() { Init(); }
|
||||
CUnit() : NewOrder(NULL), CriticalOrder(NULL) { Init(); }
|
||||
|
||||
void Init() {
|
||||
Refs = 0;
|
||||
|
@ -704,8 +704,10 @@ public:
|
|||
OrderFlush = 0;
|
||||
Orders.clear();
|
||||
SavedOrder.Init();
|
||||
NewOrder.Init();
|
||||
CriticalOrder.Init();
|
||||
delete NewOrder;
|
||||
NewOrder = NULL;
|
||||
delete CriticalOrder;
|
||||
CriticalOrder = NULL;
|
||||
AutoCastSpell = NULL;
|
||||
AutoRepair = 0;
|
||||
Goal = NULL;
|
||||
|
@ -812,34 +814,23 @@ public:
|
|||
char OrderCount; /// how many orders in queue
|
||||
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.
|
||||
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
|
||||
|
||||
inline COrder * CreateOrder() {
|
||||
COrder * CreateOrder() {
|
||||
Orders.push_back(new COrder);
|
||||
return Orders[(int)OrderCount++];
|
||||
}
|
||||
|
||||
inline COrder *CurrentOrder() const
|
||||
{
|
||||
#if __GNUC__ < 4
|
||||
return Orders[0];
|
||||
#else
|
||||
return *(Orders.data());
|
||||
#endif
|
||||
}
|
||||
inline UnitAction CurrentAction() const
|
||||
{
|
||||
return (UnitAction)(CurrentOrder()->Action);
|
||||
}
|
||||
COrder *CurrentOrder() const { return Orders[0]; }
|
||||
|
||||
inline bool IsIdle() const {
|
||||
return OrderCount == 1 && CurrentAction() == UnitActionStill;
|
||||
}
|
||||
UnitAction CurrentAction() const { return (UnitAction)(CurrentOrder()->Action); }
|
||||
|
||||
bool IsIdle() const { return OrderCount == 1 && CurrentAction() == UnitActionStill; }
|
||||
|
||||
inline void ClearAction() {
|
||||
CurrentOrder()->Action = UnitActionStill;
|
||||
|
|
|
@ -292,7 +292,6 @@ static int CclShowMapLocation(lua_State *l)
|
|||
}
|
||||
CUnit *target = MakeUnit(*unitType, ThisPlayer);
|
||||
if (target != NoUnitP) {
|
||||
target->CurrentOrder()->Action = UnitActionStill;
|
||||
target->Variable[HP_INDEX].Value = 0;
|
||||
target->tilePos.x = LuaToNumber(l, 1);
|
||||
target->tilePos.y = LuaToNumber(l, 2);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "player.h"
|
||||
#include "script.h"
|
||||
#include "ai.h"
|
||||
#include "unit.h"
|
||||
#include "actions.h"
|
||||
#include "commands.h"
|
||||
#include "map.h"
|
||||
|
|
|
@ -883,7 +883,8 @@ static int CclUnit(lua_State *l)
|
|||
}
|
||||
} else if (!strcmp(value, "critical-order")) {
|
||||
lua_pushvalue(l, j + 1);
|
||||
CclParseOrder(l, *unit , &unit->CriticalOrder);
|
||||
unit->CriticalOrder = new CUnit::COrder;
|
||||
CclParseOrder(l, *unit , unit->CriticalOrder);
|
||||
lua_pop(l, 1);
|
||||
} else if (!strcmp(value, "saved-order")) {
|
||||
lua_pushvalue(l, j + 1);
|
||||
|
@ -891,7 +892,8 @@ static int CclUnit(lua_State *l)
|
|||
lua_pop(l, 1);
|
||||
} else if (!strcmp(value, "new-order")) {
|
||||
lua_pushvalue(l, j + 1);
|
||||
CclParseOrder(l, *unit, &unit->NewOrder);
|
||||
unit->NewOrder = new CUnit::COrder;
|
||||
CclParseOrder(l, *unit, unit->NewOrder);
|
||||
lua_pop(l, 1);
|
||||
} else if (!strcmp(value, "goal")) {
|
||||
unit->Goal = UnitSlots[(int)LuaToNumber(l, j + 1)];
|
||||
|
|
|
@ -209,7 +209,7 @@ CUnit::COrder& CUnit::COrder::operator=(const CUnit::COrder &rhs) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool CUnit::COrder::CheckRange()
|
||||
bool CUnit::COrder::CheckRange() const
|
||||
{
|
||||
return (Range <= Map.Info.MapWidth || Range <= Map.Info.MapHeight);
|
||||
}
|
||||
|
@ -290,15 +290,11 @@ void CUnit::Init(CUnitType &type)
|
|||
// Set refs to 1. This is the "I am alive ref", lost in ReleaseUnit.
|
||||
Refs = 1;
|
||||
|
||||
//
|
||||
// Build all unit table
|
||||
//
|
||||
UnitSlot = &Units[NumUnits]; // back pointer
|
||||
Units[NumUnits++] = this;
|
||||
|
||||
//
|
||||
// Initialise unit structure (must be zero filled!)
|
||||
//
|
||||
Type = &type;
|
||||
|
||||
Seen.Frame = UnitNotSeen; // Unit isn't yet seen
|
||||
|
@ -343,15 +339,13 @@ void CUnit::Init(CUnitType &type)
|
|||
CurrentOrder()->Action = UnitActionStill;
|
||||
CurrentOrder()->goalPos.x = CurrentOrder()->goalPos.y = -1;
|
||||
Assert(!CurrentOrder()->HasGoal());
|
||||
NewOrder.Action = UnitActionStill;
|
||||
NewOrder.goalPos.x = NewOrder.goalPos.y = -1;
|
||||
Assert(!NewOrder.HasGoal());
|
||||
Assert(NewOrder == NULL);
|
||||
NewOrder = NULL;
|
||||
SavedOrder.Action = UnitActionStill;
|
||||
SavedOrder.goalPos.x = SavedOrder.goalPos.y = -1;
|
||||
Assert(!SavedOrder.HasGoal());
|
||||
CriticalOrder.Action = UnitActionStill;
|
||||
CriticalOrder.goalPos.x = CriticalOrder.goalPos.y = -1;
|
||||
Assert(!CriticalOrder.HasGoal());
|
||||
Assert(CriticalOrder == NULL);
|
||||
CriticalOrder = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1048,22 +1042,13 @@ void UnitLost(CUnit &unit)
|
|||
*/
|
||||
void UnitClearOrders(CUnit &unit)
|
||||
{
|
||||
int i;
|
||||
|
||||
//
|
||||
// Release all references of the unit.
|
||||
//
|
||||
for (i = unit.OrderCount; i-- > 0;) {
|
||||
if (i != 0) {
|
||||
COrderPtr order = unit.Orders.back();
|
||||
delete order;
|
||||
unit.Orders.pop_back();
|
||||
} else unit.Orders[0]->Release();
|
||||
for (int i = 0; i != unit.OrderCount; ++i)
|
||||
{
|
||||
delete unit.Orders[i];
|
||||
}
|
||||
unit.OrderCount = 1;
|
||||
unit.NewOrder.Release();
|
||||
unit.SavedOrder.Release();
|
||||
unit.CurrentOrder()->Action = UnitActionStill;
|
||||
unit.Orders.clear();
|
||||
unit.OrderCount = 0;
|
||||
CommandStopUnit(unit);
|
||||
unit.SubAction = unit.State = 0;
|
||||
}
|
||||
|
||||
|
@ -3413,7 +3398,7 @@ void CleanUnits()
|
|||
ResourceInfo *resinfo = unit->Type->ResInfo[unit->CurrentResource];
|
||||
if (resinfo && !resinfo->TerrainHarvester) {
|
||||
CUnit *mine = unit->CurrentOrder()->Arg1.Resource.Mine;
|
||||
if (mine) {
|
||||
if (mine && !mine->Destroyed) {
|
||||
unit->DeAssignWorkerFromMine(*mine);
|
||||
mine->RefsDecrease();
|
||||
unit->CurrentOrder()->Arg1.Resource.Mine = NULL;
|
||||
|
|
|
@ -878,8 +878,8 @@ void ShowOrder(const CUnit &unit)
|
|||
}
|
||||
|
||||
// Show order for new trained units
|
||||
if (!unit.CanMove()) {
|
||||
ShowSingleOrder(unit, x1, y1, (COrderPtr)(&unit.NewOrder));
|
||||
if (!unit.CanMove() && unit.NewOrder) {
|
||||
ShowSingleOrder(unit, x1, y1, unit.NewOrder);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -477,10 +477,14 @@ void SaveUnit(const CUnit &unit, CFile *file)
|
|||
}
|
||||
file->printf("},\n \"saved-order\", ");
|
||||
SaveOrder(unit.SavedOrder, unit, file);
|
||||
file->printf(",\n \"critical-order\", ");
|
||||
SaveOrder(unit.CriticalOrder, unit, file);
|
||||
file->printf(",\n \"new-order\", ");
|
||||
SaveOrder(unit.NewOrder, unit, file);
|
||||
if (unit.CriticalOrder) {
|
||||
file->printf(",\n \"critical-order\", ");
|
||||
SaveOrder(*unit.CriticalOrder, unit, file);
|
||||
}
|
||||
if (unit.NewOrder) {
|
||||
file->printf(",\n \"new-order\", ");
|
||||
SaveOrder(*unit.NewOrder, unit, file);
|
||||
}
|
||||
|
||||
if (unit.Goal) {
|
||||
file->printf(",\n \"goal\", %d", UnitNumber(*unit.Goal));
|
||||
|
|
Loading…
Add table
Reference in a new issue