[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Stratagus-CVS] stratagus/src/action action_attack.c action_boa...
From: |
address@hidden |
Subject: |
[Stratagus-CVS] stratagus/src/action action_attack.c action_boa... |
Date: |
14 Dec 2003 19:10:39 +1100 |
CVSROOT: /home/strat
Module name: stratagus
Changes by: <address@hidden> 03/12/14 19:10:37
Modified files:
src/action : action_attack.c action_board.c action_follow.c
action_move.c action_research.c
action_resource.c action_stand.c action_still.c
action_unload.c action_upgradeto.c
Log message:
Tabs, and cleanup
Patches:
Index: stratagus/src/action/action_attack.c
diff -u stratagus/src/action/action_attack.c:1.91
stratagus/src/action/action_attack.c:1.92
--- stratagus/src/action/action_attack.c:1.91 Mon Dec 1 07:03:30 2003
+++ stratagus/src/action/action_attack.c Sun Dec 14 19:10:36 2003
@@ -3,14 +3,14 @@
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
-// \/ \/ \//_____/ \/
+// \/ \/ \//_____/ \/
// ______________________ ______________________
-// T H E W A R B E G I N S
-// Stratagus - A free fantasy real time strategy game engine
+// T H E W A R B E G I N S
+// Stratagus - A free fantasy real time strategy game engine
//
-/address@hidden action_attack.c - The attack action. */
+/address@hidden action_attack.c - The attack action. */
//
-// (c) Copyright 1998-2001 by Lutz Sammer
+// (c) Copyright 1998-2004 by Lutz Sammer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -26,17 +26,17 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: action_attack.c,v 1.91 2003/11/30 20:03:30 jsalmon3 Exp $
+// $Id: action_attack.c,v 1.92 2003/12/14 08:10:36 wizzard Exp $
//@{
/**
-** @todo FIXME: I should rewrite this action, if only the
-** new orders are supported.
+** @todo FIXME: I should rewrite this action, if only the
+** new orders are supported.
*/
/*----------------------------------------------------------------------------
--- Includes
+-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
@@ -54,536 +54,537 @@
#include <string.h>
/*----------------------------------------------------------------------------
--- Defines
+-- Defines
----------------------------------------------------------------------------*/
-#define WEAK_TARGET 2 /// Weak target, could be changed
-#define MOVE_TO_TARGET 4 /// Move to target state
-#define ATTACK_TARGET 5 /// Attack target state
+#define WEAK_TARGET 2 /// Weak target, could be changed
+#define MOVE_TO_TARGET 4 /// Move to target state
+#define ATTACK_TARGET 5 /// Attack target state
/*----------------------------------------------------------------------------
--- Functions
+-- Functions
----------------------------------------------------------------------------*/
/**
-** Generic unit attacker.
+** Generic unit attacker.
**
-** @param unit Unit, for that the attack animation is played.
-** @param attack Attack animation.
+** @param unit Unit, for that the attack animation is played.
+** @param attack Attack animation.
*/
local void DoActionAttackGeneric(Unit* unit,const Animation* attack)
{
- int flags;
+ int flags;
- flags = UnitShowAnimation(unit, attack);
+ flags = UnitShowAnimation(unit, attack);
- if ((flags & AnimationSound) && (UnitVisibleOnMap(unit) ||
ReplayRevealMap)) {
- PlayUnitSound(unit, VoiceAttacking);
- }
-
- if (flags & AnimationMissile) { // time to fire projectil
- FireMissile(unit);
- unit->Invisible = 0; // unit is invisible until attacks
- }
+ if ((flags & AnimationSound) && (UnitVisibleOnMap(unit) ||
ReplayRevealMap)) {
+ PlayUnitSound(unit, VoiceAttacking);
+ }
+
+ if (flags & AnimationMissile) { // time to fire projectil
+ FireMissile(unit);
+ unit->Invisible = 0; // unit is invisible until
attacks
+ }
}
/**
-** Animate unit attack!
+** Animate unit attack!
**
-** @param unit Unit, for that the attack animation is played.
+** @param unit Unit, for that the attack animation is played.
*/
global void AnimateActionAttack(Unit* unit)
{
- if (unit->Type->Animations) {
- DebugCheck(!unit->Type->Animations->Attack);
- DoActionAttackGeneric(unit, unit->Type->Animations->Attack);
- }
+ if (unit->Type->Animations) {
+ DebugCheck(!unit->Type->Animations->Attack);
+ DoActionAttackGeneric(unit, unit->Type->Animations->Attack);
+ }
}
/**
-** Check for dead goal.
+** Check for dead goal.
**
-** @warning
-** The caller must check, if he likes the restored SavedOrder!
+** @warning The caller must check, if he likes the restored SavedOrder!
**
-** @todo
-** If an unit enters an building, than the attack choose an
-** other goal, perhaps it is better to wait for the goal?
+** @todo If an unit enters an building, than the attack choose an
+** other goal, perhaps it is better to wait for the goal?
**
-** @param unit Unit using the goal.
+** @param unit Unit using the goal.
**
-** @return A valid goal, if available.
+** @return A valid goal, if available.
*/
local Unit* CheckForDeadGoal(Unit* unit)
{
- Unit* goal;
+ Unit* goal;
- //
- // Do we have a goal?
- //
- if ((goal = unit->Orders[0].Goal)) {
- if (GoalGone(unit, goal)) {
- //
- // Goal is destroyed
- //
- unit->Orders[0].X = goal->X + goal->Type->TileWidth / 2;
- unit->Orders[0].Y = goal->Y + goal->Type->TileHeight / 2;
- unit->Orders[0].MinRange = 0;
- unit->Orders[0].Range = 0;
-
- DebugLevel0Fn("attack target %d(%s) gone for %d(%s)\n" _C_
- UnitNumber(goal) _C_ goal->Type->Name _C_
- UnitNumber(unit) _C_ unit->Type->Name);
- RefsDecrease(goal);
-
- unit->Orders[0].Goal = goal = NoUnitP;
- }
-
- if (!goal) {
- //
- // If we have a saved order continue this saved order.
- //
- if (unit->SavedOrder.Action != UnitActionStill) {
- unit->Orders[0] = unit->SavedOrder;
- unit->SavedOrder.Action = UnitActionStill;
- unit->SavedOrder.Goal = NoUnitP;
+ //
+ // Do we have a goal?
+ //
+ if ((goal = unit->Orders[0].Goal)) {
+ if (GoalGone(unit, goal)) {
+ //
+ // Goal is destroyed
+ //
+ unit->Orders[0].X = goal->X + goal->Type->TileWidth / 2;
+ unit->Orders[0].Y = goal->Y + goal->Type->TileHeight /
2;
+ unit->Orders[0].MinRange = 0;
+ unit->Orders[0].Range = 0;
+
+ DebugLevel0Fn("attack target %d(%s) gone for %d(%s)\n"
_C_
+ UnitNumber(goal) _C_ goal->Type->Name _C_
+ UnitNumber(unit) _C_ unit->Type->Name);
+ RefsDecrease(goal);
- if (unit->Selected && unit->Player == ThisPlayer) {
- MustRedraw |= RedrawButtonPanel;
+ unit->Orders[0].Goal = goal = NoUnitP;
+ }
+
+ if (!goal) {
+ //
+ // If we have a saved order continue this saved order.
+ //
+ if (unit->SavedOrder.Action != UnitActionStill) {
+ unit->Orders[0] = unit->SavedOrder;
+ unit->SavedOrder.Action = UnitActionStill;
+ unit->SavedOrder.Goal = NoUnitP;
+
+ if (unit->Selected && unit->Player ==
ThisPlayer) {
+ MustRedraw |= RedrawButtonPanel;
+ }
+ goal = unit->Orders[0].Goal;
+ }
+ NewResetPath(unit);
}
- goal = unit->Orders[0].Goal;
- }
- NewResetPath(unit);
}
- }
- return goal;
+ return goal;
}
/**
-** Check for target in range.
+** Check for target in range.
+**
+** @param unit Unit to check if goal is in range
**
-** @return True if command is over.
+** @return True if command is over.
*/
local int CheckForTargetInRange(Unit* unit)
{
- Unit* goal;
- Unit* temp;
- int wall;
-
- //
- // Target is dead?
- //
- goal = CheckForDeadGoal(unit);
- // Fall back to last order, only works if this wasn't attack
- if (unit->Orders[0].Action != UnitActionAttackGround &&
- unit->Orders[0].Action != UnitActionAttack) {
- unit->State = unit->SubAction = 0;
- return 1;
- }
-
- //
- // No goal: if meeting enemy attack it.
- //
- wall = 0;
- if (!goal && !(wall = WallOnMap(unit->Orders[0].X, unit->Orders[0].Y)) &&
- unit->Orders[0].Action != UnitActionAttackGround) {
- goal=AttackUnitsInReactRange(unit);
- if (goal) {
- if (unit->SavedOrder.Action == UnitActionStill) {
- // Save current command to continue it later.
- DebugCheck(unit->Orders[0].Goal);
- unit->SavedOrder = unit->Orders[0];
- }
- RefsIncrease(goal);
- unit->Orders[0].Goal = goal;
- unit->Orders[0].MinRange = unit->Type->MinAttackRange;
- unit->Orders[0].Range = unit->Stats->AttackRange;
- unit->Orders[0].X = unit->Orders[0].Y = -1;
- unit->SubAction |= WEAK_TARGET; // weak target
- NewResetPath(unit);
- DebugLevel3Fn("%d in react range %d\n" _C_
- UnitNumber(unit) _C_ UnitNumber(goal));
- }
-
- //
- // Have a weak target, try a better target.
- //
- } else if (goal && (unit->SubAction & WEAK_TARGET)) {
- temp = AttackUnitsInReactRange(unit);
- if (temp && temp->Type->Priority > goal->Type->Priority) {
- RefsDecrease(goal);
- RefsIncrease(temp);
- if (unit->SavedOrder.Action == UnitActionStill) {
- // Save current command to come back.
- unit->SavedOrder = unit->Orders[0];
- if ((goal = unit->SavedOrder.Goal)) {
- DebugLevel0Fn("Have goal to come back %d\n" _C_
- UnitNumber(goal));
- unit->SavedOrder.X = goal->X + goal->Type->TileWidth / 2;
- unit->SavedOrder.Y = goal->Y + goal->Type->TileHeight / 2;
- unit->SavedOrder.MinRange = 0;
- unit->SavedOrder.Range = 0;
- unit->SavedOrder.Goal = NoUnitP;
- }
- }
- unit->Orders[0].Goal = goal = temp;
- unit->Orders[0].X = unit->Orders[0].Y = -1;
- NewResetPath(unit);
- }
- }
-
- DebugCheck(unit->Type->Vanishes || unit->Destroyed || unit->Removed);
- DebugCheck(unit->Orders[0].Action != UnitActionAttack &&
- unit->Orders[0].Action != UnitActionAttackGround);
+ Unit* goal;
+ Unit* temp;
+ int wall;
- return 0;
+ //
+ // Target is dead?
+ //
+ goal = CheckForDeadGoal(unit);
+ // Fall back to last order, only works if this wasn't attack
+ if (unit->Orders[0].Action != UnitActionAttackGround &&
+ unit->Orders[0].Action != UnitActionAttack) {
+ unit->State = unit->SubAction = 0;
+ return 1;
+ }
+
+ //
+ // No goal: if meeting enemy attack it.
+ //
+ wall = 0;
+ if (!goal && !(wall = WallOnMap(unit->Orders[0].X, unit->Orders[0].Y))
&&
+ unit->Orders[0].Action != UnitActionAttackGround) {
+ goal=AttackUnitsInReactRange(unit);
+ if (goal) {
+ if (unit->SavedOrder.Action == UnitActionStill) {
+ // Save current command to continue it later.
+ DebugCheck(unit->Orders[0].Goal);
+ unit->SavedOrder = unit->Orders[0];
+ }
+ RefsIncrease(goal);
+ unit->Orders[0].Goal = goal;
+ unit->Orders[0].MinRange = unit->Type->MinAttackRange;
+ unit->Orders[0].Range = unit->Stats->AttackRange;
+ unit->Orders[0].X = unit->Orders[0].Y = -1;
+ unit->SubAction |= WEAK_TARGET;
// weak target
+ NewResetPath(unit);
+ DebugLevel3Fn("%d in react range %d\n" _C_
+ UnitNumber(unit) _C_ UnitNumber(goal));
+ }
+
+ //
+ // Have a weak target, try a better target.
+ //
+ } else if (goal && (unit->SubAction & WEAK_TARGET)) {
+ temp = AttackUnitsInReactRange(unit);
+ if (temp && temp->Type->Priority > goal->Type->Priority) {
+ RefsDecrease(goal);
+ RefsIncrease(temp);
+ if (unit->SavedOrder.Action == UnitActionStill) {
+ // Save current command to come back.
+ unit->SavedOrder = unit->Orders[0];
+ if ((goal = unit->SavedOrder.Goal)) {
+ DebugLevel0Fn("Have goal to come back
%d\n" _C_
+ UnitNumber(goal));
+ unit->SavedOrder.X = goal->X +
goal->Type->TileWidth / 2;
+ unit->SavedOrder.Y = goal->Y +
goal->Type->TileHeight / 2;
+ unit->SavedOrder.MinRange = 0;
+ unit->SavedOrder.Range = 0;
+ unit->SavedOrder.Goal = NoUnitP;
+ }
+ }
+ unit->Orders[0].Goal = goal = temp;
+ unit->Orders[0].X = unit->Orders[0].Y = -1;
+ NewResetPath(unit);
+ }
+ }
+
+ DebugCheck(unit->Type->Vanishes || unit->Destroyed || unit->Removed);
+ DebugCheck(unit->Orders[0].Action != UnitActionAttack &&
+ unit->Orders[0].Action != UnitActionAttackGround);
+
+ return 0;
}
/**
-** FIXME: docu
+** Controls moving a unit to its target when attacking
+**
+** @param unit Unit that is attacking and moving
*/
local void MoveToTarget(Unit* unit)
{
- Unit* goal;
- int err;
+ Unit* goal;
+ int err;
- if (!unit->Orders[0].Goal) {
- if (unit->Orders[0].X == -1 || unit->Orders[0].Y == -1) {
- DebugLevel0Fn("FIXME: Wrong goal position, check where set!\n");
- unit->Orders[0].X = unit->Orders[0].Y = 0;
+ if (!unit->Orders[0].Goal) {
+ if (unit->Orders[0].X == -1 || unit->Orders[0].Y == -1) {
+ DebugLevel0Fn("FIXME: Wrong goal position, check where
set!\n");
+ unit->Orders[0].X = unit->Orders[0].Y = 0;
+ }
}
- }
- err = DoActionMove(unit);
+ err = DoActionMove(unit);
- if (unit->Reset) {
- //
- // Look if we have reached the target.
- //
- if (CheckForTargetInRange(unit)) {
- return;
- }
- goal = unit->Orders[0].Goal;
- if (err >= 0) {
- //
- // Nothing to do, we're on the way moving.
- //
- DebugLevel3Fn("Nothing to do.\n");
- return;
- }
- if (err == PF_REACHED) {
- //
- // Have reached target? FIXME: could use the new return code?
- //
- if (goal && MapDistanceBetweenUnits(unit, goal) <=
- unit->Stats->AttackRange) {
- DebugLevel3Fn("Reached another unit, now attacking it.\n");
- unit->State = 0;
- if (unit->Stats->Speed) {
- UnitHeadingFromDeltaXY(unit,
- goal->X + (goal->Type->TileWidth - 1) / 2 - unit->X,
- goal->Y + (goal->Type->TileHeight - 1) / 2 - unit->Y);
- // FIXME: only if heading changes
- CheckUnitToBeDrawn(unit);
+ if (unit->Reset) {
+ //
+ // Look if we have reached the target.
+ //
+ if (CheckForTargetInRange(unit)) {
+ return;
}
- unit->SubAction++;
- return;
- }
- //
- // Attacking wall or ground.
- //
- if (!goal && (WallOnMap(unit->Orders[0].X, unit->Orders[0].Y) ||
- unit->Orders[0].Action == UnitActionAttackGround) &&
- MapDistanceToUnit(unit->Orders[0].X, unit->Orders[0].Y,
unit) <=
- unit->Stats->AttackRange) {
- DebugLevel3Fn("Reached wall or ground, now attacking it.\n");
- unit->State = 0;
- if (unit->Stats->Speed) {
- UnitHeadingFromDeltaXY(unit, unit->Orders[0].X - unit->X,
- unit->Orders[0].Y - unit->Y);
- // FIXME: only if heading changes
- CheckUnitToBeDrawn(unit);
+ goal = unit->Orders[0].Goal;
+ if (err >= 0) {
+ //
+ // Nothing to do, we're on the way moving.
+ //
+ DebugLevel3Fn("Nothing to do.\n");
+ return;
}
- unit->SubAction &= WEAK_TARGET;
- unit->SubAction |= ATTACK_TARGET;
- return;
- }
- }
- //
- // Unreachable.
- //
- if (err == PF_UNREACHABLE) {
- unit->State = unit->SubAction = 0;
- DebugLevel3Fn("Target not reachable, unit: %d" _C_
- UnitNumber(unit));
- if (goal) {
- DebugLevel3(", target %d range %d\n" _C_ UnitNumber(goal) _C_
- unit->Orders[0].Range);
- } else {
- //
- // When attack-moving we have to allow a bigger range
- //
- DebugLevel3(", (%d,%d) Tring with more range...\n" _C_
- unit->Orders[0].X _C_ unit->Orders[0].Y);
- if (unit->Orders[0].Range < TheMap.Width ||
- unit->Orders[0].Range < TheMap.Height) {
- // Try again with more range
- unit->Orders[0].Range++;
- return;
+ if (err == PF_REACHED) {
+ //
+ // Have reached target? FIXME: could use the new return
code?
+ //
+ if (goal && MapDistanceBetweenUnits(unit, goal) <=
+ unit->Stats->AttackRange) {
+ DebugLevel3Fn("Reached another unit, now
attacking it.\n");
+ unit->State = 0;
+ if (unit->Stats->Speed) {
+ UnitHeadingFromDeltaXY(unit,
+ goal->X +
(goal->Type->TileWidth - 1) / 2 - unit->X,
+ goal->Y +
(goal->Type->TileHeight - 1) / 2 - unit->Y);
+ // FIXME: only if heading changes
+ CheckUnitToBeDrawn(unit);
+ }
+ unit->SubAction++;
+ return;
+ }
+ //
+ // Attacking wall or ground.
+ //
+ if (!goal && (WallOnMap(unit->Orders[0].X,
unit->Orders[0].Y) ||
+ unit->Orders[0].Action ==
UnitActionAttackGround) &&
+ MapDistanceToUnit(unit->Orders[0].X,
unit->Orders[0].Y, unit) <=
+ unit->Stats->AttackRange) {
+ DebugLevel3Fn("Reached wall or ground, now
attacking it.\n");
+ unit->State = 0;
+ if (unit->Stats->Speed) {
+ UnitHeadingFromDeltaXY(unit,
unit->Orders[0].X - unit->X,
+ unit->Orders[0].Y - unit->Y);
+ // FIXME: only if heading changes
+ CheckUnitToBeDrawn(unit);
+ }
+ unit->SubAction &= WEAK_TARGET;
+ unit->SubAction |= ATTACK_TARGET;
+ return;
+ }
+ }
+ //
+ // Unreachable.
+ //
+ if (err == PF_UNREACHABLE) {
+ unit->State = unit->SubAction = 0;
+ DebugLevel3Fn("Target not reachable, unit: %d" _C_
+ UnitNumber(unit));
+ if (goal) {
+ DebugLevel3(", target %d range %d\n" _C_
UnitNumber(goal) _C_
+ unit->Orders[0].Range);
+ } else {
+ //
+ // When attack-moving we have to allow a bigger
range
+ //
+ DebugLevel3(", (%d,%d) Tring with more
range...\n" _C_
+ unit->Orders[0].X _C_
unit->Orders[0].Y);
+ if (unit->Orders[0].Range < TheMap.Width ||
+ unit->Orders[0].Range <
TheMap.Height) {
+ // Try again with more range
+ unit->Orders[0].Range++;
+ return;
+ }
+ }
+ }
+ //
+ // Return to old task?
+ //
+ unit->State = unit->SubAction = 0;
+ DebugLevel3Fn("Returning to old task.\n");
+ if (unit->Orders[0].Goal) {
+ RefsDecrease(unit->Orders->Goal);
}
- }
+ unit->Orders[0] = unit->SavedOrder;
+ NewResetPath(unit);
+
+ // Must finish, if saved command finishes
+ unit->SavedOrder.Action = UnitActionStill;
+ unit->SavedOrder.Goal = NoUnitP;
+
+ if (unit->Selected && unit->Player == ThisPlayer) {
+ MustRedraw |= RedrawButtonPanel;
+ }
+ return;
}
- //
- // Return to old task?
- //
- unit->State = unit->SubAction = 0;
- DebugLevel3Fn("Returning to old task.\n");
- if (unit->Orders[0].Goal) {
- RefsDecrease(unit->Orders->Goal);
- }
- unit->Orders[0] = unit->SavedOrder;
- NewResetPath(unit);
-
- // Must finish, if saved command finishes
- unit->SavedOrder.Action = UnitActionStill;
- unit->SavedOrder.Goal = NoUnitP;
-
- if (unit->Selected && unit->Player == ThisPlayer) {
- MustRedraw |= RedrawButtonPanel;
- }
- return;
- }
- DebugCheck(unit->Type->Vanishes || unit->Destroyed || unit->Removed);
- DebugCheck(unit->Orders[0].Action != UnitActionAttack &&
- unit->Orders[0].Action != UnitActionAttackGround);
+ DebugCheck(unit->Type->Vanishes || unit->Destroyed || unit->Removed);
+ DebugCheck(unit->Orders[0].Action != UnitActionAttack &&
+ unit->Orders[0].Action != UnitActionAttackGround);
}
/**
-** Handle attacking the target.
+** Handle attacking the target.
**
-** @param unit Unit, for that the attack is handled.
+** @param unit Unit, for that the attack is handled.
*/
local void AttackTarget(Unit* unit)
{
- Unit* goal;
- Unit* temp;
+ Unit* goal;
+ Unit* temp;
- if (!unit->Orders[0].Goal) {
- if (unit->Orders[0].X == -1 || unit->Orders[0].Y == -1) {
- DebugLevel0Fn("FIXME: Wrong goal position, check where set!\n");
- unit->Orders[0].X = unit->Orders[0].Y = 0;
- }
- }
-
- AnimateActionAttack(unit);
- if (unit->Reset) {
- //
- // Goal is "weak" or a wall.
- //
- goal = unit->Orders[0].Goal;
- if (!goal && (WallOnMap(unit->Orders[0].X, unit->Orders[0].Y) ||
- unit->Orders[0].Action == UnitActionAttackGround)) {
- DebugLevel3Fn("attack a wall or ground!!!!\n");
- return;
- }
-
- //
- // Target is dead?
- //
- goal = CheckForDeadGoal(unit);
- // Fall back to last order.
- if (unit->Orders[0].Action != UnitActionAttackGround &&
- unit->Orders[0].Action != UnitActionAttack) {
- unit->State = unit->SubAction = 0;
- return;
+ if (!unit->Orders[0].Goal) {
+ if (unit->Orders[0].X == -1 || unit->Orders[0].Y == -1) {
+ DebugLevel0Fn("FIXME: Wrong goal position, check where
set!\n");
+ unit->Orders[0].X = unit->Orders[0].Y = 0;
+ }
}
- //
- // No target choose one.
- //
- if (!goal) {
- unit->State = 0;
- goal = AttackUnitsInReactRange(unit);
- //
- // No new goal, continue way to destination.
- //
- if (!goal) {
- unit->SubAction = MOVE_TO_TARGET;
- // Return to old task?
- if (unit->SavedOrder.Action != UnitActionStill) {
- unit->SubAction = 0;
- DebugCheck(unit->Orders[0].Goal != NoUnitP);
- unit->Orders[0] = unit->SavedOrder;
- NewResetPath(unit);
- // Must finish, if saved command finishes
- unit->SavedOrder.Action = UnitActionStill;
-
- // This isn't supported
- DebugCheck(unit->SavedOrder.Goal != NoUnitP);
+ AnimateActionAttack(unit);
+ if (unit->Reset) {
+ //
+ // Goal is "weak" or a wall.
+ //
+ goal = unit->Orders[0].Goal;
+ if (!goal && (WallOnMap(unit->Orders[0].X, unit->Orders[0].Y) ||
+ unit->Orders[0].Action ==
UnitActionAttackGround)) {
+ DebugLevel3Fn("attack a wall or ground!!!!\n");
+ return;
+ }
- if (unit->Selected && unit->Player == ThisPlayer) {
- MustRedraw |= RedrawButtonPanel;
- }
+ //
+ // Target is dead?
+ //
+ goal = CheckForDeadGoal(unit);
+ // Fall back to last order.
+ if (unit->Orders[0].Action != UnitActionAttackGround &&
+ unit->Orders[0].Action != UnitActionAttack) {
+ unit->State = unit->SubAction = 0;
+ return;
}
- return;
- }
- //
- // Save current command to come back.
- //
- if (unit->SavedOrder.Action == UnitActionStill) {
- unit->SavedOrder = unit->Orders[0];
- if ((temp = unit->SavedOrder.Goal)) {
- DebugLevel0Fn("Have unit to come back %d?\n" _C_
- UnitNumber(temp));
- unit->SavedOrder.X = temp->X + temp->Type->TileWidth / 2;
- unit->SavedOrder.Y = temp->Y + temp->Type->TileHeight / 2;
- unit->SavedOrder.MinRange = 0;
- unit->SavedOrder.Range = 0;
- unit->SavedOrder.Goal = NoUnitP;
- }
- }
-
- RefsIncrease(goal);
- DebugLevel3Fn("%d Unit in react range %d\n" _C_
- UnitNumber(unit) _C_ UnitNumber(goal));
- unit->Orders[0].Goal = goal;
- unit->Orders[0].X = unit->Orders[0].Y = -1;
- unit->Orders[0].MinRange = unit->Type->MinAttackRange;
- unit->Orders[0].Range = unit->Stats->AttackRange;
- NewResetPath(unit);
- unit->SubAction |= WEAK_TARGET;
+ //
+ // No target choose one.
+ //
+ if (!goal) {
+ unit->State = 0;
+ goal = AttackUnitsInReactRange(unit);
+ //
+ // No new goal, continue way to destination.
+ //
+ if (!goal) {
+ unit->SubAction = MOVE_TO_TARGET;
+ // Return to old task?
+ if (unit->SavedOrder.Action != UnitActionStill)
{
+ unit->SubAction = 0;
+ DebugCheck(unit->Orders[0].Goal !=
NoUnitP);
+ unit->Orders[0] = unit->SavedOrder;
+ NewResetPath(unit);
+ // Must finish, if saved command
finishes
+ unit->SavedOrder.Action =
UnitActionStill;
+
+ // This isn't supported
+ DebugCheck(unit->SavedOrder.Goal !=
NoUnitP);
+
+ if (unit->Selected && unit->Player ==
ThisPlayer) {
+ MustRedraw |= RedrawButtonPanel;
+ }
+ }
+ return;
+ }
+
+ //
+ // Save current command to come back.
+ //
+ if (unit->SavedOrder.Action == UnitActionStill) {
+ unit->SavedOrder = unit->Orders[0];
+ if ((temp = unit->SavedOrder.Goal)) {
+ DebugLevel0Fn("Have unit to come back
%d?\n" _C_
+ UnitNumber(temp));
+ unit->SavedOrder.X = temp->X +
temp->Type->TileWidth / 2;
+ unit->SavedOrder.Y = temp->Y +
temp->Type->TileHeight / 2;
+ unit->SavedOrder.MinRange = 0;
+ unit->SavedOrder.Range = 0;
+ unit->SavedOrder.Goal = NoUnitP;
+ }
+ }
+
+ RefsIncrease(goal);
+ DebugLevel3Fn("%d Unit in react range %d\n" _C_
+ UnitNumber(unit) _C_ UnitNumber(goal));
+ unit->Orders[0].Goal = goal;
+ unit->Orders[0].X = unit->Orders[0].Y = -1;
+ unit->Orders[0].MinRange = unit->Type->MinAttackRange;
+ unit->Orders[0].Range = unit->Stats->AttackRange;
+ NewResetPath(unit);
+ unit->SubAction |= WEAK_TARGET;
- //
- // Have a weak target, try a better target.
- // FIXME: if out of range also try another target quick
- //
- } else if (goal && (unit->SubAction & WEAK_TARGET)) {
- temp = AttackUnitsInReactRange(unit);
- if (temp && temp->Type->Priority > goal->Type->Priority) {
- RefsDecrease(goal);
- RefsIncrease(temp);
-
- if (unit->SavedOrder.Action == UnitActionStill) {
- // Save current order to come back or to continue it.
- unit->SavedOrder = unit->Orders[0];
- if ((goal = unit->SavedOrder.Goal)) {
- DebugLevel0Fn("Have goal to come back %d\n" _C_
- UnitNumber(goal));
- unit->SavedOrder.X = goal->X + goal->Type->TileWidth /
2;
- unit->SavedOrder.Y = goal->Y + goal->Type->TileHeight /
2;
- unit->SavedOrder.MinRange = 0;
- unit->SavedOrder.Range = 0;
- unit->SavedOrder.Goal = NoUnitP;
- }
- }
- unit->Orders[0].Goal = goal = temp;
- unit->Orders[0].X = unit->Orders[0].Y = -1;
- unit->Orders[0].MinRange = unit->Type->MinAttackRange;
- unit->SubAction = MOVE_TO_TARGET;
- NewResetPath(unit);
- }
- }
+ //
+ // Have a weak target, try a better target.
+ // FIXME: if out of range also try another target quick
+ //
+ } else if (goal && (unit->SubAction & WEAK_TARGET)) {
+ temp = AttackUnitsInReactRange(unit);
+ if (temp && temp->Type->Priority >
goal->Type->Priority) {
+ RefsDecrease(goal);
+ RefsIncrease(temp);
+
+ if (unit->SavedOrder.Action == UnitActionStill)
{
+ // Save current order to come back or
to continue it.
+ unit->SavedOrder = unit->Orders[0];
+ if ((goal = unit->SavedOrder.Goal)) {
+ DebugLevel0Fn("Have goal to
come back %d\n" _C_
+ UnitNumber(goal));
+ unit->SavedOrder.X = goal->X +
goal->Type->TileWidth / 2;
+ unit->SavedOrder.Y = goal->Y +
goal->Type->TileHeight / 2;
+ unit->SavedOrder.MinRange = 0;
+ unit->SavedOrder.Range = 0;
+ unit->SavedOrder.Goal = NoUnitP;
+ }
+ }
+ unit->Orders[0].Goal = goal = temp;
+ unit->Orders[0].X = unit->Orders[0].Y = -1;
+ unit->Orders[0].MinRange =
unit->Type->MinAttackRange;
+ unit->SubAction = MOVE_TO_TARGET;
+ NewResetPath(unit);
+ }
+ }
- //
- // Still near to target, if not goto target.
- //
- if (MapDistanceBetweenUnits(unit, goal) > unit->Stats->AttackRange) {
- if (unit->SavedOrder.Action == UnitActionStill) {
- // Save current order to come back or to continue it.
- unit->SavedOrder = unit->Orders[0];
- if ((temp = unit->SavedOrder.Goal)) {
- DebugLevel0Fn("Have goal to come back %d\n" _C_
- UnitNumber(temp));
- unit->SavedOrder.X = temp->X + temp->Type->TileWidth / 2;
- unit->SavedOrder.Y = temp->Y + temp->Type->TileHeight / 2;
- unit->SavedOrder.MinRange = 0;
- unit->SavedOrder.Range = 0;
- unit->SavedOrder.Goal = NoUnitP;
- }
- }
- NewResetPath(unit);
- unit->Frame = 0;
- unit->State = 0;
- unit->SubAction &= WEAK_TARGET;
- unit->SubAction |= MOVE_TO_TARGET;
- }
- if (MapDistanceBetweenUnits(unit, goal) < unit->Type->MinAttackRange) {
- unit->SubAction = MOVE_TO_TARGET;
- }
+ //
+ // Still near to target, if not goto target.
+ //
+ if (MapDistanceBetweenUnits(unit, goal) >
unit->Stats->AttackRange) {
+ if (unit->SavedOrder.Action == UnitActionStill) {
+ // Save current order to come back or to
continue it.
+ unit->SavedOrder = unit->Orders[0];
+ if ((temp = unit->SavedOrder.Goal)) {
+ DebugLevel0Fn("Have goal to come back
%d\n" _C_
+ UnitNumber(temp));
+ unit->SavedOrder.X = temp->X +
temp->Type->TileWidth / 2;
+ unit->SavedOrder.Y = temp->Y +
temp->Type->TileHeight / 2;
+ unit->SavedOrder.MinRange = 0;
+ unit->SavedOrder.Range = 0;
+ unit->SavedOrder.Goal = NoUnitP;
+ }
+ }
+ NewResetPath(unit);
+ unit->Frame = 0;
+ unit->State = 0;
+ unit->SubAction &= WEAK_TARGET;
+ unit->SubAction |= MOVE_TO_TARGET;
+ }
+ if (MapDistanceBetweenUnits(unit, goal) <
unit->Type->MinAttackRange) {
+ unit->SubAction = MOVE_TO_TARGET;
+ }
- //
- // Turn always to target
- //
- if (unit->Stats->Speed && goal) {
- UnitHeadingFromDeltaXY(unit,
- goal->X + (goal->Type->TileWidth - 1) / 2 - unit->X,
- goal->Y + (goal->Type->TileHeight - 1) / 2 - unit->Y);
- // FIXME: only if heading changes
- CheckUnitToBeDrawn(unit);
+ //
+ // Turn always to target
+ //
+ if (unit->Stats->Speed && goal) {
+ UnitHeadingFromDeltaXY(unit,
+ goal->X + (goal->Type->TileWidth - 1) / 2 -
unit->X,
+ goal->Y + (goal->Type->TileHeight - 1) / 2 -
unit->Y);
+ // FIXME: only if heading changes
+ CheckUnitToBeDrawn(unit);
+ }
}
- }
}
/**
-** Unit attacks!
+** Unit attacks!
**
-** I added a little trick, if SubAction&WEAK_TARGET is true the goal is
-** a weak goal. This means the unit AI (little AI) could choose a new
-** better goal.
-**
-** @todo
-** Lets do some tries to reach the target.
-** If target place is not reachable, choose better goal to reduce
-** the pathfinder load.
+** I added a little trick, if SubAction&WEAK_TARGET is true the goal is
+** a weak goal. This means the unit AI (little AI) could choose a new
+** better goal.
**
-** @param unit Unit, for that the attack is handled.
+** @todo Lets do some tries to reach the target.
+** If target place is not reachable, choose better goal to reduce
+** the pathfinder load.
+**
+** @param unit Unit, for that the attack is handled.
*/
global void HandleActionAttack(Unit* unit)
{
- DebugLevel3Fn("Attack %d range %d\n" _C_ UnitNumber(unit) _C_
- unit->Orders->Range);
+ DebugLevel3Fn("Attack %d range %d\n" _C_ UnitNumber(unit) _C_
+ unit->Orders->Range);
- switch (unit->SubAction) {
- //
- // First entry
- //
- case 0:
- unit->SubAction = MOVE_TO_TARGET;
- NewResetPath(unit);
- //
- // FIXME: should use a reachable place to reduce pathfinder time.
- //
- DebugCheck(unit->State != 0);
- //
- // Look for target, if already in range. Attack if So
- //
- if (CheckForTargetInRange(unit)) {
- unit->SubAction = ATTACK_TARGET;
- return;
- }
+ switch (unit->SubAction) {
+ //
+ // First entry
+ //
+ case 0:
+ unit->SubAction = MOVE_TO_TARGET;
+ NewResetPath(unit);
+ //
+ // FIXME: should use a reachable place to reduce
pathfinder time.
+ //
+ DebugCheck(unit->State != 0);
+ //
+ // Look for target, if already in range. Attack if So
+ //
+ if (CheckForTargetInRange(unit)) {
+ unit->SubAction = ATTACK_TARGET;
+ return;
+ }
- // FALL THROUGH
- //
- // Move near to the target.
- //
- case MOVE_TO_TARGET:
- case MOVE_TO_TARGET + WEAK_TARGET:
- MoveToTarget(unit);
- break;
+ // FALL THROUGH
+ //
+ // Move near to the target.
+ //
+ case MOVE_TO_TARGET:
+ case MOVE_TO_TARGET + WEAK_TARGET:
+ MoveToTarget(unit);
+ break;
- //
- // Attack the target.
- //
- case ATTACK_TARGET:
- case ATTACK_TARGET + WEAK_TARGET:
- AttackTarget(unit);
- break;
-
- case WEAK_TARGET:
- DebugLevel0("FIXME: wrong entry.\n");
- break;
- }
+ //
+ // Attack the target.
+ //
+ case ATTACK_TARGET:
+ case ATTACK_TARGET + WEAK_TARGET:
+ AttackTarget(unit);
+ break;
+
+ case WEAK_TARGET:
+ DebugLevel0("FIXME: wrong entry.\n");
+ break;
+ }
}
//@}
Index: stratagus/src/action/action_board.c
diff -u stratagus/src/action/action_board.c:1.46
stratagus/src/action/action_board.c:1.47
--- stratagus/src/action/action_board.c:1.46 Mon Dec 1 07:03:30 2003
+++ stratagus/src/action/action_board.c Sun Dec 14 19:10:36 2003
@@ -1,16 +1,16 @@
-// _________ __ __
+// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
-// \/ \/ \//_____/ \/
+// \/ \/ \//_____/ \/
// ______________________ ______________________
-// T H E W A R B E G I N S
-// Stratagus - A free fantasy real time strategy game engine
+// T H E W A R B E G I N S
+// Stratagus - A free fantasy real time strategy game engine
//
-/address@hidden action_board.c - The board action. */
+/address@hidden action_board.c - The board action. */
//
-// (c) Copyright 1998,2000-2002 by Lutz Sammer
+// (c) Copyright 1998-2004 by Lutz Sammer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -26,12 +26,12 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: action_board.c,v 1.46 2003/11/30 20:03:30 jsalmon3 Exp $
+// $Id: action_board.c,v 1.47 2003/12/14 08:10:36 wizzard Exp $
//@{
/*----------------------------------------------------------------------------
--- Includes
+-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
@@ -46,202 +46,202 @@
#include "pathfinder.h"
/*----------------------------------------------------------------------------
--- Functions
+-- Functions
----------------------------------------------------------------------------*/
/**
-** Move to transporter.
+** Move to transporter.
**
-** @param unit Pointer to unit, moving to transporter.
+** @param unit Pointer to unit, moving to transporter.
**
-** @return >0 remaining path length, 0 wait for path, -1
-** reached goal, -2 can't reach the goal.
+** @return >0 remaining path length, 0 wait for path, -1
+** reached goal, -2 can't reach the goal.
*/
local int MoveToTransporter(Unit* unit)
{
- int i;
- int x;
- int y;
-
- x = unit->X;
- y = unit->Y;
- i = DoActionMove(unit);
- // We have to reset a lot, or else they will circle each other and stuff.
- if (x != unit->X || y != unit->Y) {
- unit->Orders[0].Range = 1;
- NewResetPath(unit);
- }
- // New code has this as default.
- DebugCheck(unit->Orders[0].Action != UnitActionBoard);
- return i;
+ int i;
+ int x;
+ int y;
+
+ x = unit->X;
+ y = unit->Y;
+ i = DoActionMove(unit);
+ // We have to reset a lot, or else they will circle each other and
stuff.
+ if (x != unit->X || y != unit->Y) {
+ unit->Orders[0].Range = 1;
+ NewResetPath(unit);
+ }
+ // New code has this as default.
+ DebugCheck(unit->Orders[0].Action != UnitActionBoard);
+ return i;
}
/**
-** Wait for transporter.
+** Wait for transporter.
**
-** @param unit Pointer to unit.
-** @return True if ship arrived/present, False otherwise.
+** @param unit Pointer to unit.
+**
+** @return True if ship arrived/present, False otherwise.
*/
local int WaitForTransporter(Unit* unit)
{
- Unit* trans;
+ Unit* trans;
- unit->Wait = 6;
- unit->Reset = 1;
+ unit->Wait = 6;
+ unit->Reset = 1;
- trans = unit->Orders[0].Goal;
+ trans = unit->Orders[0].Goal;
- if (!trans || !trans->Type->Transporter) {
- // FIXME: destination destroyed??
- DebugLevel2Fn("TRANSPORTER NOT REACHED %d,%d\n" _C_ unit->X _C_
unit->Y);
- return 0;
- }
-
- if (GoalGone(unit, trans)) {
- DebugLevel0Fn("Transporter Gone\n");
- RefsDecrease(trans);
- unit->Orders[0].Goal = NoUnitP;
- return 0;
- }
+ if (!trans || !trans->Type->Transporter) {
+ // FIXME: destination destroyed??
+ DebugLevel2Fn("TRANSPORTER NOT REACHED %d,%d\n" _C_ unit->X _C_
unit->Y);
+ return 0;
+ }
+
+ if (GoalGone(unit, trans)) {
+ DebugLevel0Fn("Transporter Gone\n");
+ RefsDecrease(trans);
+ unit->Orders[0].Goal = NoUnitP;
+ return 0;
+ }
- if (MapDistanceBetweenUnits(unit,trans) == 1) {
- DebugLevel3Fn("Enter transporter\n");
- return 1;
- }
-
- //
- // FIXME: any enemies in range attack them, while waiting.
- //
-
- DebugLevel3Fn("TRANSPORTER NOT REACHED %d,%d\n" _C_ unit->X _C_ unit->Y);
- // n0b0dy: This means we have to search with a smaller range.
- // It happens only when you reach the shore,and the transporter
- // is not there. The unit searches with a big range, so it thinks
- // it's there. This is why we reset the search. The transporter
- // should be a lot closer now, so it's not as bad as it seems.
- unit->SubAction = 0;
- unit->Orders[0].Range = 1;
- //Uhh wait a bit.
- unit->Wait = 10;
+ if (MapDistanceBetweenUnits(unit,trans) == 1) {
+ DebugLevel3Fn("Enter transporter\n");
+ return 1;
+ }
+
+ //
+ // FIXME: any enemies in range attack them, while waiting.
+ //
- return 0;
+ DebugLevel3Fn("TRANSPORTER NOT REACHED %d,%d\n" _C_ unit->X _C_
unit->Y);
+ // n0b0dy: This means we have to search with a smaller range.
+ // It happens only when you reach the shore,and the transporter
+ // is not there. The unit searches with a big range, so it thinks
+ // it's there. This is why we reset the search. The transporter
+ // should be a lot closer now, so it's not as bad as it seems.
+ unit->SubAction = 0;
+ unit->Orders[0].Range = 1;
+ // Uhh wait a bit.
+ unit->Wait = 10;
+
+ return 0;
}
/**
-** Enter the transporter.
+** Enter the transporter.
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
*/
local void EnterTransporter(Unit* unit)
{
- Unit* transporter;
+ Unit* transporter;
+
+ unit->Wait = 1;
+ unit->Orders[0].Action = UnitActionStill;
+ unit->SubAction = 0;
+
+ transporter = unit->Orders[0].Goal;
+ if (GoalGone(unit,transporter)) {
+ DebugLevel0Fn("Transporter gone\n");
+ RefsDecrease(transporter);
+ unit->Orders[0].Goal = NoUnitP;
+ return;
+ }
- unit->Wait = 1;
- unit->Orders[0].Action = UnitActionStill;
- unit->SubAction = 0;
-
- transporter = unit->Orders[0].Goal;
- if (GoalGone(unit,transporter)) {
- DebugLevel0Fn("Transporter gone\n");
RefsDecrease(transporter);
unit->Orders[0].Goal = NoUnitP;
- return;
- }
- RefsDecrease(transporter);
- unit->Orders[0].Goal = NoUnitP;
+ //
+ // Place the unit inside the transporter.
+ //
+
+ if (transporter->InsideCount < transporter->Type->MaxOnBoard) {
+ RemoveUnit(unit, transporter);
+ if (!unit->Player->AiEnabled) {
+ // Don't make anything funny after going out of the
transporter.
+ // FIXME: This is probably wrong, but it works for me
(n0b0dy)
+ unit->OrderCount = 1;
+ unit->Orders[0].Action = UnitActionStill;
+ }
- //
- // Place the unit inside the transporter.
- //
-
- if (transporter->InsideCount < transporter->Type->MaxOnBoard) {
- RemoveUnit(unit, transporter);
- if (!unit->Player->AiEnabled) {
- //Don't make anything funny after going out of the transporter.
- // FIXME: This is probably wrong, but it works for me (n0b0dy)
- unit->OrderCount = 1;
- unit->Orders[0].Action = UnitActionStill;
- }
-
- if (IsOnlySelected(transporter)) {
- SelectedUnitChanged();
- MustRedraw |= RedrawInfoPanel;
- }
- return;
- }
- DebugLevel0Fn("No free slot in transporter\n");
+ if (IsOnlySelected(transporter)) {
+ SelectedUnitChanged();
+ MustRedraw |= RedrawInfoPanel;
+ }
+ return;
+ }
+ DebugLevel0Fn("No free slot in transporter\n");
}
/**
-** The unit boards a transporter.
+** The unit boards a transporter.
**
-** @todo FIXME:
-** While waiting for the transporter the units must defend themselfs.
+** @todo FIXME: While waiting for the transporter the units must defend
themselves.
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
*/
global void HandleActionBoard(Unit* unit)
{
- int i;
- Unit* goal;
+ int i;
+ Unit* goal;
- DebugLevel3Fn("%p(%d) SubAction %d\n" _C_
- unit _C_ UnitNumber(unit) _C_ unit->SubAction);
+ DebugLevel3Fn("%p(%d) SubAction %d\n" _C_
+ unit _C_ UnitNumber(unit) _C_ unit->SubAction);
- switch (unit->SubAction) {
- //
- // Wait for transporter
- //
- case 201:
- // FIXME: show still animations
- DebugLevel3Fn("Waiting\n");
- if (WaitForTransporter(unit)) {
- unit->SubAction = 202;
- }
- break;
- //
- // Enter transporter
- //
- case 202:
- EnterTransporter(unit);
- break;
- //
- // Move to transporter
- //
- case 0:
- NewResetPath(unit);
- unit->SubAction = 1;
- // FALL THROUGH
- default:
- if (unit->SubAction <= 200) {
- // FIXME: if near transporter wait for enter
- if ((i = MoveToTransporter(unit))) {
- if (i == PF_UNREACHABLE) {
- if (++unit->SubAction == 200) {
- unit->Orders[0].Action = UnitActionStill;
- if ((goal = unit->Orders[0].Goal)) {
- RefsDecrease(goal);
- unit->Orders[0].Goal = NoUnitP;
- }
- unit->SubAction = 0;
- } else {
- //
- // Try with a bigger range.
- //
- if (unit->Orders[0].Range <= TheMap.Width ||
- unit->Orders[0].Range <= TheMap.Height) {
- unit->Orders[0].Range++;
- unit->SubAction--;
- }
+ switch (unit->SubAction) {
+ //
+ // Wait for transporter
+ //
+ case 201:
+ // FIXME: show still animations
+ DebugLevel3Fn("Waiting\n");
+ if (WaitForTransporter(unit)) {
+ unit->SubAction = 202;
}
- } else if (i == PF_REACHED) {
- unit->SubAction = 201;
- }
- }
- }
- break;
- }
+ break;
+ //
+ // Enter transporter
+ //
+ case 202:
+ EnterTransporter(unit);
+ break;
+ //
+ // Move to transporter
+ //
+ case 0:
+ NewResetPath(unit);
+ unit->SubAction = 1;
+ // FALL THROUGH
+ default:
+ if (unit->SubAction <= 200) {
+ // FIXME: if near transporter wait for enter
+ if ((i = MoveToTransporter(unit))) {
+ if (i == PF_UNREACHABLE) {
+ if (++unit->SubAction == 200) {
+ unit->Orders[0].Action
= UnitActionStill;
+ if ((goal =
unit->Orders[0].Goal)) {
+
RefsDecrease(goal);
+
unit->Orders[0].Goal = NoUnitP;
+ }
+ unit->SubAction = 0;
+ } else {
+ //
+ // Try with a bigger
range.
+ //
+ if
(unit->Orders[0].Range <= TheMap.Width ||
+
unit->Orders[0].Range <= TheMap.Height) {
+
unit->Orders[0].Range++;
+
unit->SubAction--;
+ }
+ }
+ } else if (i == PF_REACHED) {
+ unit->SubAction = 201;
+ }
+ }
+ }
+ break;
+ }
}
//@}
Index: stratagus/src/action/action_follow.c
diff -u stratagus/src/action/action_follow.c:1.34
stratagus/src/action/action_follow.c:1.35
--- stratagus/src/action/action_follow.c:1.34 Mon Nov 10 09:13:56 2003
+++ stratagus/src/action/action_follow.c Sun Dec 14 19:10:36 2003
@@ -1,16 +1,16 @@
-// _________ __ __
+// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
-// \/ \/ \//_____/ \/
+// \/ \/ \//_____/ \/
// ______________________ ______________________
-// T H E W A R B E G I N S
-// Stratagus - A free fantasy real time strategy game engine
+// T H E W A R B E G I N S
+// Stratagus - A free fantasy real time strategy game engine
//
-/address@hidden action_follow.c - The follow action. */
+/address@hidden action_follow.c - The follow action. */
//
-// (c) Copyright 2001-2002 by Lutz Sammer
+// (c) Copyright 2001-2004 by Lutz Sammer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -26,12 +26,12 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: action_follow.c,v 1.34 2003/11/09 22:13:56 n0body Exp $
+// $Id: action_follow.c,v 1.35 2003/12/14 08:10:36 wizzard Exp $
//@{
/*----------------------------------------------------------------------------
--- Includes
+-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
@@ -45,209 +45,214 @@
#include "actions.h"
/*----------------------------------------------------------------------------
--- Variables
+-- Variables
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
--- Function
+-- Function
----------------------------------------------------------------------------*/
/**
-** Unit follow action:
+** Unit follow action:
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
*/
global void HandleActionFollow(Unit* unit)
{
- Unit* goal;
+ Unit* goal;
- //
- // Reached target
- //
- if (unit->SubAction == 128) {
- goal = unit->Orders[0].Goal;
- if (!goal || GoalGone(unit,goal)) {
- DebugLevel0Fn("Goal gone\n");
- if (goal) {
- RefsDecrease(goal);
- }
- unit->Orders[0].Goal = NoUnitP;
- unit->Wait = 1;
- unit->SubAction = 0;
- unit->Orders[0].Action = UnitActionStill;
- if (IsOnlySelected(unit)) { // update display for new action
- SelectedUnitChanged();
- }
- return;
- }
+ //
+ // Reached target
+ //
+ if (unit->SubAction == 128) {
+ goal = unit->Orders[0].Goal;
+ if (!goal || GoalGone(unit,goal)) {
+ DebugLevel0Fn("Goal gone\n");
+ if (goal) {
+ RefsDecrease(goal);
+ }
+ unit->Orders[0].Goal = NoUnitP;
+ unit->Wait = 1;
+ unit->SubAction = 0;
+ unit->Orders[0].Action = UnitActionStill;
+ if (IsOnlySelected(unit)) { // update display for new
action
+ SelectedUnitChanged();
+ }
+ return;
+ }
- // Two posibilities, both broken. maybe we should change the animation
system?
- // FIXME: Unit doesn't decrease range
+ // Two posibilities, both broken. maybe we should change the
animation system?
+ // FIXME: Unit doesn't decrease range
#if 0
- if ((goal->X == unit->Orders[0].X && goal->Y == unit->Orders[0].Y) ||
unit->State) {
- UnitShowAnimation(unit, unit->Type->Animations->Still);
- //
- // Sea and air units are floating up/down.
- //
- if (unit->Type->SeaUnit || unit->Type->AirUnit) {
- unit->IY = (MyRand() >> 15) & 1;
- }
- return;
- }
+ if ((goal->X == unit->Orders[0].X && goal->Y ==
unit->Orders[0].Y) || unit->State) {
+ UnitShowAnimation(unit, unit->Type->Animations->Still);
+ //
+ // Sea and air units are floating up/down.
+ //
+ if (unit->Type->SeaUnit || unit->Type->AirUnit) {
+ unit->IY = (MyRand() >> 15) & 1;
+ }
+ return;
+ }
#else
- // FIXME:Unit doesn't animate.
- if ((goal->X == unit->Orders[0].X && goal->Y == unit->Orders[0].Y)) {
- unit->Reset = 1;
- unit->Wait = 10;
- if (unit->Orders[0].Range > 1) {
- unit->Orders[0].Range = 1;
- unit->SubAction = 0;
- }
- return;
- }
+ // FIXME: Unit doesn't animate.
+ if ((goal->X == unit->Orders[0].X && goal->Y ==
unit->Orders[0].Y)) {
+ unit->Reset = 1;
+ unit->Wait = 10;
+ if (unit->Orders[0].Range > 1) {
+ unit->Orders[0].Range = 1;
+ unit->SubAction = 0;
+ }
+ return;
+ }
#endif
- unit->SubAction = 0;
- }
-
- if (!unit->SubAction) { // first entry
- unit->SubAction = 1;
- NewResetPath(unit);
- DebugCheck(unit->State != 0);
- }
-
- switch (DoActionMove(unit)) { // reached end-point?
- case PF_UNREACHABLE:
- //
- // Some tries to reach the goal
- //
- if (unit->Orders[0].Range <= TheMap.Width ||
- unit->Orders[0].Range <= TheMap.Height) {
- unit->Orders[0].Range++;
- break;
- }
- // FALL THROUGH
- case PF_REACHED:
- // FIXME: dark portal teleportation: Goal is used for target circle
of power
- // FIXME: teleporting of units should use dark portal's mana
- if ((goal = unit->Orders[0].Goal) &&
- goal->Type->Teleporter && goal->Goal &&
- MapDistanceBetweenUnits(unit, goal) < 4) {
- //Unit* table[UnitMax];
- Unit* dest;
- //int n;
- //int i;
-
- RemoveUnit(unit, NULL);
- unit->X = goal->Goal->X;
- unit->Y = goal->Goal->Y;
- DropOutOnSide(unit, unit->Direction, 1, 1);
- //FIXME: SoundIdForName() should be called once
-/* PlayGameSound(SoundIdForName("invisibility"), MaxSampleVolume);
- //FIXME: MissileTypeByIdent() should be called once
- MakeMissile(MissileTypeByIdent("missile-normal-spell"),
- unit->X * TileSizeX + TileSizeX / 2,
- unit->Y * TileSizeY + TileSizeY / 2,
- unit->X * TileSizeX + TileSizeX / 2,
- unit->Y * TileSizeY + TileSizeY / 2);*/
-
- unit->Wait = 1;
unit->SubAction = 0;
- unit->Orders[0].Action = UnitActionStill;
-
- //
- // FIXME: we must check if the units supports the new
order.
- //
- 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)) {
- DebugLevel0Fn("Wrong order for unit\n");
- unit->Orders->Action = UnitActionStill;
- unit->Orders->Goal = NoUnitP;
- } else {
- if (dest->NewOrder.Goal) {
- if (dest->NewOrder.Goal->Destroyed) {
- // FIXME: perhaps we should use another dest?
- DebugLevel0Fn("Destroyed unit in teleport
unit\n");
- RefsDecrease(dest);
- dest->NewOrder.Goal = NoUnitP;
- dest->NewOrder.Action = UnitActionStill;
- }
- }
+ }
- unit->Orders[0] = dest->NewOrder;
+ if (!unit->SubAction) { // first entry
+ unit->SubAction = 1;
+ NewResetPath(unit);
+ DebugCheck(unit->State != 0);
+ }
+ switch (DoActionMove(unit)) { // reached end-point?
+ case PF_UNREACHABLE:
//
- // FIXME: Pending command uses any references?
+ // Some tries to reach the goal
//
- if (unit->Orders[0].Goal) {
- RefsIncrease(unit->Orders->Goal);
+ if (unit->Orders[0].Range <= TheMap.Width ||
+ unit->Orders[0].Range <= TheMap.Height)
{
+ unit->Orders[0].Range++;
+ break;
}
- }
- }
- return;
- }
+ // FALL THROUGH
+ case PF_REACHED:
+ // FIXME: dark portal teleportation: Goal is used for
target circle of power
+ // FIXME: teleporting of units should use dark portal's
mana
+ if ((goal = unit->Orders[0].Goal) &&
+ goal->Type->Teleporter && goal->Goal &&
+ MapDistanceBetweenUnits(unit, goal) <
4) {
+#if 0
+ Unit* table[UnitMax];
+#endif
+ Unit* dest;
+#if 0
+ int n;
+ int i;
+#endif
- if (!(goal = unit->Orders[0].Goal)) {// goal has died
- unit->Wait = 1;
- unit->SubAction = 0;
- unit->Orders[0].Action = UnitActionStill;
- if (IsOnlySelected(unit)) { // update display for new action
- SelectedUnitChanged();
- }
- return;
- }
- unit->Orders[0].X = goal->X;
- unit->Orders[0].Y = goal->Y;
- unit->SubAction = 128;
-
- // FALL THROUGH
- default:
- break;
- }
-
- //
- // Target destroyed?
- //
- if ((goal = unit->Orders[0].Goal) && GoalGone(unit, goal)) {
- DebugLevel0Fn("Goal gone\n");
- unit->Orders[0].X = goal->X + goal->Type->TileWidth / 2;
- unit->Orders[0].Y = goal->Y + goal->Type->TileHeight / 2;
- unit->Orders[0].Goal = NoUnitP;
- RefsDecrease(goal);
- goal = NoUnitP;
- NewResetPath(unit);
- }
+ RemoveUnit(unit, NULL);
+ unit->X = goal->Goal->X;
+ unit->Y = goal->Goal->Y;
+ DropOutOnSide(unit, unit->Direction, 1, 1);
+#if 0
+ // FIXME: SoundIdForName() should be called once
+ PlayGameSound(SoundIdForName("invisibility"),
MaxSampleVolume);
+ // FIXME: MissileTypeByIdent() should be called
once
+
MakeMissile(MissileTypeByIdent("missile-normal-spell"),
+ unit->X * TileSizeX + TileSizeX / 2,
+ unit->Y * TileSizeY + TileSizeY / 2,
+ unit->X * TileSizeX + TileSizeX / 2,
+ unit->Y * TileSizeY + TileSizeY / 2);
+#endif
+ unit->Wait = 1;
+ unit->SubAction = 0;
+ unit->Orders[0].Action = UnitActionStill;
+
+ //
+ // FIXME: we must check if the units supports
the new order.
+ //
+ 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)) {
+ DebugLevel0Fn("Wrong order for
unit\n");
+ unit->Orders->Action =
UnitActionStill;
+ unit->Orders->Goal = NoUnitP;
+ } else {
+ if (dest->NewOrder.Goal) {
+ if
(dest->NewOrder.Goal->Destroyed) {
+ // FIXME:
perhaps we should use another dest?
+
DebugLevel0Fn("Destroyed unit in teleport unit\n");
+
RefsDecrease(dest);
+
dest->NewOrder.Goal = NoUnitP;
+
dest->NewOrder.Action = UnitActionStill;
+ }
+ }
+
+ unit->Orders[0] =
dest->NewOrder;
+
+ //
+ // FIXME: Pending command uses
any references?
+ //
+ if (unit->Orders[0].Goal) {
+
RefsIncrease(unit->Orders->Goal);
+ }
+ }
+ }
+ return;
+ }
+
+ if (!(goal = unit->Orders[0].Goal)) { // goal has died
+ unit->Wait = 1;
+ unit->SubAction = 0;
+ unit->Orders[0].Action = UnitActionStill;
+ if (IsOnlySelected(unit)) { // update display
for new action
+ SelectedUnitChanged();
+ }
+ return;
+ }
+ unit->Orders[0].X = goal->X;
+ unit->Orders[0].Y = goal->Y;
+ unit->SubAction = 128;
+
+ // FALL THROUGH
+ default:
+ break;
+ }
- if (unit->Reset) {
//
- // 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.
+ // Target destroyed?
//
- if (unit->Type->CanAttack && unit->Stats->Speed &&
- (!goal || goal->Orders[0].Action == UnitActionAttack ||
- goal->Orders[0].Action == UnitActionStill)) {
- goal = AttackUnitsInReactRange(unit);
- if (goal) {
- DebugLevel2Fn("Follow attack %d\n" _C_ UnitNumber(goal));
- CommandAttack(unit, goal->X, goal->Y, NULL, FlushCommands);
- // Save current command to come back.
- unit->SavedOrder = unit->Orders[0];
- // This stops the follow command and the attack is executed
- unit->Orders[0].Action = UnitActionStill;
+ if ((goal = unit->Orders[0].Goal) && GoalGone(unit, goal)) {
+ DebugLevel0Fn("Goal gone\n");
+ unit->Orders[0].X = goal->X + goal->Type->TileWidth / 2;
+ unit->Orders[0].Y = goal->Y + goal->Type->TileHeight / 2;
unit->Orders[0].Goal = NoUnitP;
- unit->SubAction = 0;
- unit->Wait = 1;
- }
+ RefsDecrease(goal);
+ goal = NoUnitP;
+ NewResetPath(unit);
+ }
+
+ if (unit->Reset) {
+ //
+ // 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 && unit->Stats->Speed &&
+ (!goal || goal->Orders[0].Action ==
UnitActionAttack ||
+ goal->Orders[0].Action ==
UnitActionStill)) {
+ goal = AttackUnitsInReactRange(unit);
+ if (goal) {
+ DebugLevel2Fn("Follow attack %d\n" _C_
UnitNumber(goal));
+ CommandAttack(unit, goal->X, goal->Y, NULL,
FlushCommands);
+ // Save current command to come back.
+ unit->SavedOrder = unit->Orders[0];
+ // This stops the follow command and the attack
is executed
+ unit->Orders[0].Action = UnitActionStill;
+ unit->Orders[0].Goal = NoUnitP;
+ unit->SubAction = 0;
+ unit->Wait = 1;
+ }
+ }
}
- }
}
//@}
Index: stratagus/src/action/action_move.c
diff -u stratagus/src/action/action_move.c:1.77
stratagus/src/action/action_move.c:1.78
--- stratagus/src/action/action_move.c:1.77 Mon Dec 1 07:03:30 2003
+++ stratagus/src/action/action_move.c Sun Dec 14 19:10:36 2003
@@ -1,32 +1,32 @@
-// _________ __ __
+// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
-// \/ \/ \//_____/ \/
+// \/ \/ \//_____/ \/
// ______________________ ______________________
-// T H E W A R B E G I N S
-// Stratagus - A free fantasy real time strategy game engine
+// T H E W A R B E G I N S
+// Stratagus - A free fantasy real time strategy game engine
//
-/address@hidden action_move.c - The move action. */
+/address@hidden action_move.c - The move action. */
//
-// (c) Copyright 1998,2001-2003 by Lutz Sammer
+// (c) Copyright 1998-2004 by Lutz Sammer
//
-// Stratagus is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published
-// by the Free Software Foundation; either only 2 of the License.
+// Stratagus is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published
+// by the Free Software Foundation; either only 2 of the License.
//
-// Stratagus is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
+// Stratagus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
//
-// $Id: action_move.c,v 1.77 2003/11/30 20:03:30 jsalmon3 Exp $
+// $Id: action_move.c,v 1.78 2003/12/14 08:10:36 wizzard Exp $
//@{
/*----------------------------------------------------------------------------
--- Includes
+-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
@@ -47,278 +47,279 @@
#include "ai.h"
/*----------------------------------------------------------------------------
--- Variables
+-- Variables
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
--- Function
+-- Function
----------------------------------------------------------------------------*/
-
-//#include "rdtsc.h"
+#if 0
+#include "rdtsc.h"
+#endif
/**
-** Generic unit mover.
+** Generic unit mover.
**
-** @param unit Unit that moves.
-** @param anim Animation script for unit.
+** @param unit Unit that moves.
+** @param anim Animation script for unit.
**
-** @return >0 remaining path length, 0 wait for path, -1
-** reached goal, -2 can't reach the goal.
+** @return >0 remaining path length, 0 wait for path, -1
+** reached goal, -2 can't reach the goal.
*/
local int ActionMoveGeneric(Unit* unit, const Animation* anim)
{
- int xd;
- int yd;
- int state;
- int d;
- int i;
- int x;
- int y;
- Unit* uninside;
-
- // FIXME: state 0?, should be wrong, should be Reset.
- // FIXME: Reset flag is cleared by HandleUnitAction.
- if (!(state = unit->State)) {
- // FIXME: So units flying up and down are not affected.
- unit->IX = unit->IY = 0;
+ int xd;
+ int yd;
+ int state;
+ int d;
+ int i;
+ int x;
+ int y;
+ Unit* uninside;
+
+ // FIXME: state 0?, should be wrong, should be Reset.
+ // FIXME: Reset flag is cleared by HandleUnitAction.
+ if (!(state = unit->State)) {
+ // FIXME: So units flying up and down are not affected.
+ unit->IX = unit->IY = 0;
#ifdef HIERARCHIC_PATHFINDER
- d = PfHierComputePath(unit, &xd, &yd);
+ d = PfHierComputePath(unit, &xd, &yd);
#if 0
- {
- int ts0;
- int ts1;
- ts0 = rdtsc();
- NextPathElement(unit, &xd, &yd);
- ts1 = rdtsc();
- printf("old pathfinder: %d cycles\n", ts1 - ts0);
- }
+ {
+ int ts0;
+ int ts1;
+ ts0 = rdtsc();
+ NextPathElement(unit, &xd, &yd);
+ ts1 = rdtsc();
+ printf("old pathfinder: %d cycles\n", ts1 - ts0);
+ }
#endif
- switch (d) {
+ switch (d) {
#else /* HIERARCHIC_PATHFINDER */
- switch (d = NextPathElement(unit, &xd, &yd)) {
+ switch (d = NextPathElement(unit, &xd, &yd)) {
#endif /* HIERARCHIC_PATHFINDER */
- case PF_UNREACHABLE: // Can't reach, stop
- if (unit->Player->AiEnabled) {
- AiCanNotMove(unit);
+ case PF_UNREACHABLE: // Can't reach, stop
+ if (unit->Player->AiEnabled) {
+ AiCanNotMove(unit);
+ }
+
+ unit->Reset = unit->Wait = 1;
+ unit->Moving = 0;
+
+ return d;
+ case PF_REACHED: // Reached goal, stop
+ unit->Reset = unit->Wait = 1;
+ unit->Moving = 0;
+ return d;
+ case PF_WAIT: // No path, wait
+ unit->Reset = unit->Wait = 1;
+ unit->Moving = 0;
+ return d;
+ default: // On the way moving
+ unit->Moving = 1;
+ break;
}
- unit->Reset = unit->Wait = 1;
- unit->Moving = 0;
+ //
+ // Transporter (un)docking?
+ //
+ // FIXME: This is an ugly hack
+ if (unit->Type->Transporter &&
+ ((WaterOnMap(unit->X, unit->Y) &&
+ CoastOnMap(unit->X + xd, unit->Y + yd))
||
+ (CoastOnMap(unit->X, unit->Y) &&
+ WaterOnMap(unit->X + xd, unit->Y +
yd)))) {
+ PlayUnitSound(unit, VoiceDocking);
+ }
+
+ //
+ // Update movement map.
+ //
+ i = unit->Type->FieldFlags;
+ TheMap.Fields[unit->X + unit->Y * TheMap.Width].Flags &= ~i;
+
+ UnitCacheRemove(unit);
+
+ MapUnmarkUnitSight(unit);
+ // ummark sight for units inside too.
+ uninside = unit->UnitInside;
+ for (i = unit->InsideCount; i; uninside =
uninside->NextContained, --i) {
+ MapUnmarkUnitOnBoardSight(uninside, unit);
+ }
+
+ x = unit->X += xd;
+ y = unit->Y += yd;
+ UnitCacheInsert(unit);
+
+ TheMap.Fields[x + y * TheMap.Width].Flags |=
unit->Type->FieldFlags;
+
+ MustRedraw |= RedrawMinimap;
+
+ MapMarkUnitSight(unit);
+ // Remove unit from the current selection
+ if (unit->Selected && !IsMapFieldVisible(ThisPlayer, unit->X,
unit->Y)) {
+ if (NumSelected == 1) { // Remove building cursor
+ CancelBuildingMode();
+ }
+ UnSelectUnit(unit);
+ SelectionChanged();
+ }
- return d;
- case PF_REACHED: // Reached goal, stop
- unit->Reset = unit->Wait = 1;
- unit->Moving = 0;
- return d;
- case PF_WAIT: // No path, wait
- unit->Reset = unit->Wait = 1;
- unit->Moving = 0;
- return d;
- default: // On the way moving
- unit->Moving = 1;
- break;
+ // Remark sight for units inside too.
+ uninside = unit->UnitInside;
+ for (i = unit->InsideCount; i; uninside =
uninside->NextContained, --i) {
+ MapMarkUnitOnBoardSight(uninside, unit);
+ }
+
+ // Reveal cloaked units.
+ if (unit->Type->DetectCloak) {
+ MapDetectCloakedUnits(unit);
+ }
+
+ unit->IX = -xd * TileSizeX;
+ unit->IY = -yd * TileSizeY;
+ unit->Frame = 0;
+ UnitHeadingFromDeltaXY(unit, xd, yd);
+ } else {
+ xd = Heading2X[unit->Direction / NextDirection];
+ yd = Heading2Y[unit->Direction / NextDirection];
+ d = 0;
}
+ DebugLevel3Fn(": %d,%d State %2d " _C_ xd _C_ yd _C_ unit->State);
+ DebugLevel3("Walk %d Frame %2d Wait %3d Heading %d %d,%d\n" _C_
+ anim[state].Pixel _C_ anim[state].Frame _C_ anim[state].Sleep
_C_
+ unit->Direction _C_ unit->IX _C_ unit->IY);
+
//
- // Transporter (un)docking?
+ // Next animation.
//
- // FIXME: This is an ugly hack
- if (unit->Type->Transporter &&
- ((WaterOnMap(unit->X, unit->Y) &&
- CoastOnMap(unit->X + xd, unit->Y + yd)) ||
- (CoastOnMap(unit->X, unit->Y) &&
- WaterOnMap(unit->X + xd, unit->Y + yd)))) {
- PlayUnitSound(unit, VoiceDocking);
+ unit->IX += xd * anim[state].Pixel;
+ unit->IY += yd * anim[state].Pixel;
+ if (unit->Frame < 0) {
+ unit->Frame += -anim[state].Frame;
+ } else {
+ unit->Frame += anim[state].Frame;
+ }
+ unit->Wait = anim[state].Sleep;
+ if (unit->Slow) { // unit is slowed down
+ unit->Wait <<= 1;
+ }
+ if (unit->Haste && unit->Wait > 1) { // unit is accelerated
+ unit->Wait >>= 1;
}
//
- // Update movement map.
+ // Any graphic change?
//
- i = unit->Type->FieldFlags;
- TheMap.Fields[unit->X + unit->Y * TheMap.Width].Flags &= ~i;
-
- UnitCacheRemove(unit);
+ if (!state || anim[state].Pixel || anim[state].Frame) {
+ CheckUnitToBeDrawn(unit);
+ }
- MapUnmarkUnitSight(unit);
- // ummark sight for units inside too.
- uninside = unit->UnitInside;
- for (i = unit->InsideCount; i; uninside = uninside->NextContained, --i)
{
- MapUnmarkUnitOnBoardSight(uninside, unit);
- }
-
- x = unit->X += xd;
- y = unit->Y += yd;
- UnitCacheInsert(unit);
-
- TheMap.Fields[x + y * TheMap.Width].Flags |= unit->Type->FieldFlags;
-
- MustRedraw |= RedrawMinimap;
-
- MapMarkUnitSight(unit);
- // Remove unit from the current selection
- if (unit->Selected && !IsMapFieldVisible(ThisPlayer, unit->X, unit->Y))
{
- if (NumSelected == 1) { // Remove building cursor
- CancelBuildingMode();
- }
- UnSelectUnit(unit);
- SelectionChanged();
- }
-
- // Remark sight for units inside too.
- uninside = unit->UnitInside;
- for (i = unit->InsideCount; i; uninside = uninside->NextContained, --i)
{
- MapMarkUnitOnBoardSight(uninside, unit);
- }
-
- // Reveal cloaked units.
- if (unit->Type->DetectCloak) {
- MapDetectCloakedUnits(unit);
- }
-
- unit->IX = -xd * TileSizeX;
- unit->IY = -yd * TileSizeY;
- unit->Frame = 0;
- UnitHeadingFromDeltaXY(unit, xd, yd);
- } else {
- xd = Heading2X[unit->Direction / NextDirection];
- yd = Heading2Y[unit->Direction / NextDirection];
- d = 0;
- }
-
- DebugLevel3Fn(": %d,%d State %2d " _C_ xd _C_ yd _C_ unit->State);
- DebugLevel3("Walk %d Frame %2d Wait %3d Heading %d %d,%d\n" _C_
- anim[state].Pixel _C_ anim[state].Frame _C_ anim[state].Sleep _C_
- unit->Direction _C_ unit->IX _C_ unit->IY);
-
- //
- // Next animation.
- //
- unit->IX += xd * anim[state].Pixel;
- unit->IY += yd * anim[state].Pixel;
- if (unit->Frame < 0) {
- unit->Frame += -anim[state].Frame;
- } else {
- unit->Frame += anim[state].Frame;
- }
- unit->Wait = anim[state].Sleep;
- if (unit->Slow) { // unit is slowed down
- unit->Wait <<= 1;
- }
- if (unit->Haste && unit->Wait > 1) { // unit is accelerated
- unit->Wait >>= 1;
- }
-
- //
- // Any graphic change?
- //
- if (!state || anim[state].Pixel || anim[state].Frame) {
- CheckUnitToBeDrawn(unit);
- }
-
- //
- // Handle the flags.
- //
- if (anim[state].Flags & AnimationReset) {
- unit->Reset = 1;
- }
- if (anim[state].Flags & AnimationRestart) {
- unit->State = 0;
- } else {
- ++unit->State;
- }
+ //
+ // Handle the flags.
+ //
+ if (anim[state].Flags & AnimationReset) {
+ unit->Reset = 1;
+ }
+ if (anim[state].Flags & AnimationRestart) {
+ unit->State = 0;
+ } else {
+ ++unit->State;
+ }
- return d;
+ return d;
}
/**
-** Unit moves! Generic function called from other actions.
+** Unit moves! Generic function called from other actions.
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
**
-** @return >0 remaining path length, 0 wait for path, -1
-** reached goal, -2 can't reach the goal.
+** @return >0 remaining path length, 0 wait for path, -1
+** reached goal, -2 can't reach the goal.
*/
global int DoActionMove(Unit* unit)
{
- if (unit->Type->Animations && unit->Type->Animations->Move) {
- DebugLevel3("%s: %p\n" _C_ unit->Type->Ident _C_
unit->Type->Animations);
- return ActionMoveGeneric(unit, unit->Type->Animations->Move);
- }
+ if (unit->Type->Animations && unit->Type->Animations->Move) {
+ DebugLevel3("%s: %p\n" _C_ unit->Type->Ident _C_
unit->Type->Animations);
+ return ActionMoveGeneric(unit, unit->Type->Animations->Move);
+ }
- DebugLevel0Fn("Warning tried to move an object, which can't move\n");
+ DebugLevel0Fn("Warning tried to move an object, which can't move\n");
- return PF_UNREACHABLE;
+ return PF_UNREACHABLE;
}
/**
-** Unit move action:
+** Unit move action:
**
-** Move to a place or to an unit (can move).
-** Tries 10x to reach the target, note this are the complete tries.
-** If the target entered another unit, move to it's position.
-** If the target unit is destroyed, continue to move to it's last position.
+** Move to a place or to an unit (can move).
+** Tries 10x to reach the target, note this are the complete tries.
+** If the target entered another unit, move to it's position.
+** If the target unit is destroyed, continue to move to it's last position.
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
*/
global void HandleActionMove(Unit* unit)
{
- Unit* goal;
+ Unit* goal;
- DebugLevel3Fn("%d: %d %d,%d \n" _C_ UnitNumber(unit) _C_
- unit->Orders[0].Goal ? UnitNumber(unit->Orders[0].Goal) : -1 _C_
- unit->Orders[0].X _C_ unit->Orders[0].Y);
-
- if (!unit->SubAction) { // first entry
- unit->SubAction = 1;
- NewResetPath(unit);
-
- DebugCheck(unit->State != 0);
- }
-
- // FIXME: (mr-russ) Make a reachable goal here with GoalReachable ...
-
- switch (DoActionMove(unit)) { // reached end-point?
- case PF_UNREACHABLE:
- //
- // Some tries to reach the goal
- //
- if (unit->Orders[0].Range <= TheMap.Width ||
- unit->Orders[0].Range <= TheMap.Height) {
- unit->Orders[0].Range++;
- break;
- }
- // FALL THROUGH
- case PF_REACHED:
- unit->SubAction = 0;
- // Release target, if any.
- if ((goal = unit->Orders[0].Goal)) {
- RefsDecrease(goal);
+ DebugLevel3Fn("%d: %d %d,%d \n" _C_ UnitNumber(unit) _C_
+ unit->Orders[0].Goal ? UnitNumber(unit->Orders[0].Goal) : -1 _C_
+ unit->Orders[0].X _C_ unit->Orders[0].Y);
+
+ if (!unit->SubAction) { // first entry
+ unit->SubAction = 1;
+ NewResetPath(unit);
+
+ DebugCheck(unit->State != 0);
+ }
+
+ // FIXME: (mr-russ) Make a reachable goal here with GoalReachable ...
+
+ switch (DoActionMove(unit)) { // reached end-point?
+ case PF_UNREACHABLE:
+ //
+ // Some tries to reach the goal
+ //
+ if (unit->Orders[0].Range <= TheMap.Width ||
+ unit->Orders[0].Range <= TheMap.Height)
{
+ unit->Orders[0].Range++;
+ break;
+ }
+ // FALL THROUGH
+ case PF_REACHED:
+ unit->SubAction = 0;
+ // Release target, if any.
+ if ((goal = unit->Orders[0].Goal)) {
+ RefsDecrease(goal);
+ unit->Orders[0].Goal = NoUnitP;
+ }
+ unit->Orders[0].Action = UnitActionStill;
+ if (unit->Selected) { // update display for new action
+ SelectedUnitChanged();
+ }
+ return;
+
+ default:
+ break;
+ }
+
+ //
+ // Target destroyed?
+ //
+ if ((goal = unit->Orders[0].Goal) && goal->Destroyed) {
+ DebugLevel0Fn("Goal dead\n");
+ unit->Orders[0].X = goal->X + goal->Type->TileWidth / 2;
+ unit->Orders[0].Y = goal->Y + goal->Type->TileHeight / 2;
unit->Orders[0].Goal = NoUnitP;
- }
- unit->Orders[0].Action = UnitActionStill;
- if (unit->Selected) { // update display for new action
- SelectedUnitChanged();
- }
- return;
-
- default:
- break;
- }
-
- //
- // Target destroyed?
- //
- if ((goal = unit->Orders[0].Goal) && goal->Destroyed) {
- DebugLevel0Fn("Goal dead\n");
- unit->Orders[0].X = goal->X + goal->Type->TileWidth / 2;
- unit->Orders[0].Y = goal->Y + goal->Type->TileHeight / 2;
- unit->Orders[0].Goal = NoUnitP;
- RefsDecrease(goal);
- NewResetPath(unit);
- }
+ RefsDecrease(goal);
+ NewResetPath(unit);
+ }
}
//@}
Index: stratagus/src/action/action_research.c
diff -u stratagus/src/action/action_research.c:1.34
stratagus/src/action/action_research.c:1.35
--- stratagus/src/action/action_research.c:1.34 Wed Nov 19 04:56:18 2003
+++ stratagus/src/action/action_research.c Sun Dec 14 19:10:36 2003
@@ -1,16 +1,16 @@
-// _________ __ __
+// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
-// \/ \/ \//_____/ \/
+// \/ \/ \//_____/ \/
// ______________________ ______________________
-// T H E W A R B E G I N S
-// Stratagus - A free fantasy real time strategy game engine
+// T H E W A R B E G I N S
+// Stratagus - A free fantasy real time strategy game engine
//
-/address@hidden action_research.c - The research action. */
+/address@hidden action_research.c - The research action. */
//
-// (c) Copyright 1998,2000-2002 by Lutz Sammer
+// (c) Copyright 1998-2004 by Lutz Sammer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -26,12 +26,12 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: action_research.c,v 1.34 2003/11/18 17:56:18 pludov Exp $
+// $Id: action_research.c,v 1.35 2003/12/14 08:10:36 wizzard Exp $
//@{
/*----------------------------------------------------------------------------
--- Includes
+-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
@@ -51,76 +51,76 @@
#include "ai.h"
/*----------------------------------------------------------------------------
--- Functions
+-- Functions
----------------------------------------------------------------------------*/
/**
-** Unit researches!
+** Unit researches!
**
-** @param unit Pointer of researching unit.
+** @param unit Pointer of researching unit.
*/
global void HandleActionResearch(Unit* unit)
{
- const Upgrade* upgrade;
+ const Upgrade* upgrade;
- if (!unit->SubAction) { // first entry
- upgrade = unit->Data.Research.Upgrade = unit->Orders[0].Arg1;
+ if (!unit->SubAction) { // first entry
+ upgrade = unit->Data.Research.Upgrade = unit->Orders[0].Arg1;
#if 0
- // FIXME: I want to support both, but with network we need this check
- // but if want combined upgrades this is worse
+ // 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]) {
- DebugLevel0Fn("Two researches running\n");
- PlayerAddCosts(unit->Player, upgrade->Costs);
-
- unit->Reset = unit->Wait = 1;
- unit->Orders[0].Action = UnitActionStill;
- unit->SubAction = 0;
- if (IsOnlySelected(unit)) {
- MustRedraw |= RedrawInfoPanel;
- }
- return;
- }
+ //
+ // Check if an other building has already started?
+ //
+ if (unit->Player->UpgradeTimers.Upgrades[upgrade-Upgrades]) {
+ DebugLevel0Fn("Two researches running\n");
+ PlayerAddCosts(unit->Player, upgrade->Costs);
+
+ unit->Reset = unit->Wait = 1;
+ unit->Orders[0].Action = UnitActionStill;
+ unit->SubAction = 0;
+ if (IsOnlySelected(unit)) {
+ MustRedraw |= RedrawInfoPanel;
+ }
+ return;
+ }
#endif
- unit->SubAction = 1;
- } else {
- upgrade = unit->Data.Research.Upgrade;
- }
-
- unit->Player->UpgradeTimers.Upgrades[upgrade-Upgrades] += SpeedResearch;
- if (unit->Player->UpgradeTimers.Upgrades[upgrade-Upgrades] >=
- upgrade->Costs[TimeCost]) {
-
- NotifyPlayer(unit->Player, NotifyGreen, unit->X, unit->Y,
- "%s: complete", unit->Type->Name);
- if (unit->Player->AiEnabled) {
- AiResearchComplete(unit, upgrade);
+ unit->SubAction = 1;
+ } else {
+ upgrade = unit->Data.Research.Upgrade;
}
- UpgradeAcquire(unit->Player, upgrade);
- unit->Reset = unit->Wait = 1;
- unit->Orders[0].Action = UnitActionStill;
- unit->SubAction = 0;
+ unit->Player->UpgradeTimers.Upgrades[upgrade-Upgrades] += SpeedResearch;
+ if (unit->Player->UpgradeTimers.Upgrades[upgrade-Upgrades] >=
+ upgrade->Costs[TimeCost]) {
+
+ NotifyPlayer(unit->Player, NotifyGreen, unit->X, unit->Y,
+ "%s: complete", unit->Type->Name);
+ if (unit->Player->AiEnabled) {
+ AiResearchComplete(unit, upgrade);
+ }
+ UpgradeAcquire(unit->Player, upgrade);
+
+ unit->Reset = unit->Wait = 1;
+ unit->Orders[0].Action = UnitActionStill;
+ unit->SubAction = 0;
- // Upgrade can change all
- SelectedUnitChanged();
- MustRedraw |= RedrawInfoPanel;
+ // Upgrade can change all
+ SelectedUnitChanged();
+ MustRedraw |= RedrawInfoPanel;
- return;
- }
+ return;
+ }
- if (IsOnlySelected(unit)) {
- // refresh info panel (to show progress, I think)
- MustRedraw |= RedrawInfoPanel;
- }
+ if (IsOnlySelected(unit)) {
+ // refresh info panel (to show progress, I think)
+ MustRedraw |= RedrawInfoPanel;
+ }
- unit->Reset = 1;
- unit->Wait = CYCLES_PER_SECOND / 6;
+ unit->Reset = 1;
+ unit->Wait = CYCLES_PER_SECOND / 6;
- // FIXME: should be animations here?
+ // FIXME: should be animations here?
}
//@}
Index: stratagus/src/action/action_resource.c
diff -u stratagus/src/action/action_resource.c:1.72
stratagus/src/action/action_resource.c:1.73
--- stratagus/src/action/action_resource.c:1.72 Wed Dec 10 19:22:04 2003
+++ stratagus/src/action/action_resource.c Sun Dec 14 19:10:36 2003
@@ -1,16 +1,16 @@
-// _________ __ __
+// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
-// \/ \/ \//_____/ \/
+// \/ \/ \//_____/ \/
// ______________________ ______________________
-// T H E W A R B E G I N S
-// Stratagus - A free fantasy real time strategy game engine
+// T H E W A R B E G I N S
+// Stratagus - A free fantasy real time strategy game engine
//
-/address@hidden action_resource.c - The generic resource action. */
+/address@hidden action_resource.c - The generic resource action. */
//
-// (c) Copyright 2001-2003 by Lutz Sammer and Crestez Leonard
+// (c) Copyright 2001-2004 by Lutz Sammer and Crestez Leonard
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -26,12 +26,12 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: action_resource.c,v 1.72 2003/12/10 08:22:04 wizzard Exp $
+// $Id: action_resource.c,v 1.73 2003/12/14 08:10:36 wizzard Exp $
//@{
/*----------------------------------------------------------------------------
--- Includes
+-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
@@ -47,7 +47,7 @@
#include "interface.h"
/*----------------------------------------------------------------------------
--- Declarations
+-- Declarations
----------------------------------------------------------------------------*/
#define SUB_START_RESOURCE 0
@@ -61,789 +61,794 @@
#define SUB_RETURN_RESOURCE 120
/*----------------------------------------------------------------------------
--- Functions
+-- Functions
----------------------------------------------------------------------------*/
/**
-** Move unit to resource.
+** Move unit to resource.
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
**
-** @return TRUE if reached, otherwise FALSE.
+** @return TRUE if reached, otherwise FALSE.
*/
local int MoveToResource(Unit* unit)
{
- Unit* goal;
- ResourceInfo* resinfo;
- int x;
- int y;
-
- resinfo = unit->Type->ResInfo[unit->CurrentResource];
- if (resinfo->TerrainHarvester) {
- x = unit->Orders->X;
- y = unit->Orders->Y;
- // Wood gone, look somewhere else.
- if ((!ForestOnMap(x, y)) && (!unit->IX) && (!unit->IY)) {
- if (!FindTerrainType(UnitMovementMask(unit), MapFieldForest, 0, 16,
- unit->Player, unit->Orders->X, unit->Orders->Y, &x, &y)) {
- DebugLevel3Fn("No wood in range\n");
- return -1;
- } else {
- DebugLevel3Fn("%d,%d -> %d,%d\n" _C_ unit->X _C_ unit->Y _C_ x
_C_ y);
- unit->Orders->X = x;
- unit->Orders->Y = y;
- NewResetPath(unit);
- }
- }
- switch (DoActionMove(unit)) {
- case PF_UNREACHABLE:
- if (FindTerrainType(UnitMovementMask(unit), MapFieldForest, 0,
9999,
- unit->Player, unit->X, unit->Y, &x, &y)) {
- unit->Orders->X = x;
- unit->Orders->Y = y;
- NewResetPath(unit);
- DebugLevel0Fn("Found a better place to harvest %d,%d\n" _C_
x _C_ y);
- // FIXME: can't this overflow? It really shouldn't, since
- // x and y are really supossed to be reachable, checked
thorugh a flood fill.
- // I don't know, sometimes shit happens.
- //return MoveToResource(unit);
- return 0;
+ Unit* goal;
+ ResourceInfo* resinfo;
+ int x;
+ int y;
+
+ resinfo = unit->Type->ResInfo[unit->CurrentResource];
+ if (resinfo->TerrainHarvester) {
+ x = unit->Orders->X;
+ y = unit->Orders->Y;
+ // Wood gone, look somewhere else.
+ if ((!ForestOnMap(x, y)) && (!unit->IX) && (!unit->IY)) {
+ if (!FindTerrainType(UnitMovementMask(unit),
MapFieldForest, 0, 16,
+ unit->Player, unit->Orders->X,
unit->Orders->Y, &x, &y)) {
+ DebugLevel3Fn("No wood in range\n");
+ return -1;
+ } else {
+ DebugLevel3Fn("%d,%d -> %d,%d\n" _C_ unit->X
_C_ unit->Y _C_ x _C_ y);
+ unit->Orders->X = x;
+ unit->Orders->Y = y;
+ NewResetPath(unit);
+ }
}
- return -1;
- case PF_REACHED:
- return 1;
- default:
- return 0;
- }
- } else {
- goal = unit->Orders[0].Goal;
- DebugCheck(!goal);
- switch (DoActionMove(unit)) { // reached end-point?
- case PF_UNREACHABLE:
- return -1;
- case PF_REACHED:
- break;
- default:
- // Goal gone or something.
- if (!unit->Reset || !GoalGone(unit, goal)) {
- return 0;
+ switch (DoActionMove(unit)) {
+ case PF_UNREACHABLE:
+ if (FindTerrainType(UnitMovementMask(unit),
MapFieldForest, 0, 9999,
+ unit->Player, unit->X, unit->Y,
&x, &y)) {
+ unit->Orders->X = x;
+ unit->Orders->Y = y;
+ NewResetPath(unit);
+ DebugLevel0Fn("Found a better place to
harvest %d,%d\n" _C_ x _C_ y);
+ // FIXME: can't this overflow? It
really shouldn't, since
+ // x and y are really supossed to be
reachable, checked thorugh a flood fill.
+ // I don't know, sometimes stuff
happens.
+#if 0
+ return MoveToResource(unit);
+#else
+ return 0;
+#endif
+ }
+ return -1;
+ case PF_REACHED:
+ return 1;
+ default:
+ return 0;
}
- break;
+ } else {
+ goal = unit->Orders[0].Goal;
+ DebugCheck(!goal);
+ switch (DoActionMove(unit)) { // reached end-point?
+ case PF_UNREACHABLE:
+ return -1;
+ case PF_REACHED:
+ break;
+ default:
+ // Goal gone or something.
+ if (!unit->Reset || !GoalGone(unit, goal)) {
+ return 0;
+ }
+ break;
+ }
+ return 1;
}
- return 1;
- }
}
/*
-** Start harvesting the resource.
+** Start harvesting the resource.
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
**
-** @return TRUE if ready, otherwise FALSE.
+** @return TRUE if ready, otherwise FALSE.
*/
local int StartGathering(Unit* unit)
{
- Unit* goal;
- ResourceInfo* resinfo;
+ Unit* goal;
+ ResourceInfo* resinfo;
- resinfo = unit->Type->ResInfo[unit->CurrentResource];
- DebugCheck(unit->IX);
- DebugCheck(unit->IY);
- if (resinfo->TerrainHarvester) {
- //
- // This shouldn't happend?
- /*
- if (!ForestOnMap(unit->Orders->X, unit->Orders->Y)) {
- DebugLevel0Fn("Wood gone, just like that?\n");
- return 0;
- }*/
- UnitHeadingFromDeltaXY(unit, unit->Orders->X - unit->X,
- unit->Orders->Y - unit->Y);
- if (resinfo->WaitAtResource) {
- unit->Data.ResWorker.TimeToHarvest = resinfo->WaitAtResource /
- SpeedResourcesHarvest[resinfo->ResourceId];
- } else {
- unit->Data.ResWorker.TimeToHarvest = 1;
+ resinfo = unit->Type->ResInfo[unit->CurrentResource];
+ DebugCheck(unit->IX);
+ DebugCheck(unit->IY);
+ if (resinfo->TerrainHarvester) {
+ // This shouldn't happend?
+#if 0
+ if (!ForestOnMap(unit->Orders->X, unit->Orders->Y)) {
+ DebugLevel0Fn("Wood gone, just like that?\n");
+ return 0;
+ }
+#endif
+ UnitHeadingFromDeltaXY(unit, unit->Orders->X - unit->X,
+ unit->Orders->Y - unit->Y);
+ if (resinfo->WaitAtResource) {
+ unit->Data.ResWorker.TimeToHarvest =
resinfo->WaitAtResource /
+ SpeedResourcesHarvest[resinfo->ResourceId];
+ } else {
+ unit->Data.ResWorker.TimeToHarvest = 1;
+ }
+ unit->Data.ResWorker.DoneHarvesting = 0;
+ return 1;
}
- unit->Data.ResWorker.DoneHarvesting = 0;
- return 1;
- }
- goal = unit->Orders[0].Goal;
- //
- // Target is dead, stop getting resources.
- //
- if (GoalGone(unit, goal)) {
- DebugLevel3Fn("Destroyed resource goal, stop gathering.\n");
- RefsDecrease(goal);
- // Find an alternative, but don't look too far.
- unit->Orders[0].X = unit->Orders[0].Y = -1;
- if ((goal = FindResource(unit, unit->X, unit->Y, 10,
unit->CurrentResource))) {
- unit->SubAction = SUB_START_RESOURCE;
- unit->Orders[0].Goal = goal;
- RefsIncrease(goal);
- } else {
- unit->Orders[0].Action = UnitActionStill;
- unit->Orders[0].Goal = NoUnitP;
- unit->SubAction = 0;
+ goal = unit->Orders[0].Goal;
+ //
+ // Target is dead, stop getting resources.
+ //
+ if (GoalGone(unit, goal)) {
+ DebugLevel3Fn("Destroyed resource goal, stop gathering.\n");
+ RefsDecrease(goal);
+ // Find an alternative, but don't look too far.
+ unit->Orders[0].X = unit->Orders[0].Y = -1;
+ if ((goal = FindResource(unit, unit->X, unit->Y, 10,
unit->CurrentResource))) {
+ unit->SubAction = SUB_START_RESOURCE;
+ unit->Orders[0].Goal = goal;
+ RefsIncrease(goal);
+ } else {
+ unit->Orders[0].Action = UnitActionStill;
+ unit->Orders[0].Goal = NoUnitP;
+ unit->SubAction = 0;
+ }
+ return 0;
}
- return 0;
- }
- // FIXME: 0 can happen, if to near placed by map designer.
- DebugLevel3Fn("%d\n" _C_ MapDistanceBetweenUnits(unit, goal));
- DebugCheck(MapDistanceBetweenUnits(unit, goal) > 1);
-
- //
- // Update the heading of a harvesting unit to looks straight at the
resource.
- //
- if (goal) {
- UnitHeadingFromDeltaXY(unit,
- 2 * (goal->X - unit->X) + goal->Type->TileWidth,
- 2 * (goal->Y - unit->Y) + goal->Type->TileHeight);
- }
-
- //
- // If resource is still under construction, wait!
- //
- if ((goal->Type->MaxOnBoard && goal->Data.Resource.Active >=
goal->Type->MaxOnBoard) ||
- goal->Orders[0].Action == UnitActionBuilded) {
- DebugLevel3Fn("Waiting at the resource with %d people inside.\n" _C_
- goal->Data.Resource.Active);
- // FIXME: Determine somehow when the resource will be free to use
- // FIXME: Could we somehow find another resource? Think minerals
- // FIXME: We should add a flag for that, and a limited range.
- // FIXME: Think minerals in st*rcr*ft!!
- // However the CPU usage is really low (no pathfinding stuff).
- unit->Wait = 10;
- unit->Reset = 1;
- return 0;
- }
+ // FIXME: 0 can happen, if to near placed by map designer.
+ DebugLevel3Fn("%d\n" _C_ MapDistanceBetweenUnits(unit, goal));
+ DebugCheck(MapDistanceBetweenUnits(unit, goal) > 1);
- // Activate the resource
- goal->Data.Resource.Active++;
+ //
+ // Update the heading of a harvesting unit to looks straight at the
resource.
+ //
+ if (goal) {
+ UnitHeadingFromDeltaXY(unit,
+ 2 * (goal->X - unit->X) + goal->Type->TileWidth,
+ 2 * (goal->Y - unit->Y) + goal->Type->TileHeight);
+ }
- UnitMarkSeen(goal);
- //
- // Place unit inside the resource
- //
- if (!resinfo->HarvestFromOutside) {
- RefsDecrease(goal);
- unit->Orders[0].Goal = NoUnitP;
+ //
+ // If resource is still under construction, wait!
+ //
+ if ((goal->Type->MaxOnBoard && goal->Data.Resource.Active >=
goal->Type->MaxOnBoard) ||
+ goal->Orders[0].Action == UnitActionBuilded) {
+ DebugLevel3Fn("Waiting at the resource with %d people
inside.\n" _C_
+ goal->Data.Resource.Active);
+ // FIXME: Determine somehow when the resource will be free to
use
+ // FIXME: Could we somehow find another resource? Think minerals
+ // FIXME: We should add a flag for that, and a limited range.
+ // FIXME: Think minerals in st*rcr*ft!!
+ // However the CPU usage is really low (no pathfinding stuff).
+ unit->Wait = 10;
+ unit->Reset = 1;
+ return 0;
+ }
- RemoveUnit(unit, goal);
- unit->X = goal->X;
- unit->Y = goal->Y;
- }
+ // Activate the resource
+ goal->Data.Resource.Active++;
+
+ UnitMarkSeen(goal);
+ //
+ // Place unit inside the resource
+ //
+ if (!resinfo->HarvestFromOutside) {
+ RefsDecrease(goal);
+ unit->Orders[0].Goal = NoUnitP;
+
+ RemoveUnit(unit, goal);
+ unit->X = goal->X;
+ unit->Y = goal->Y;
+ }
- unit->Data.ResWorker.TimeToHarvest = resinfo->WaitAtResource /
- SpeedResourcesHarvest[resinfo->ResourceId];
+ unit->Data.ResWorker.TimeToHarvest = resinfo->WaitAtResource /
+ SpeedResourcesHarvest[resinfo->ResourceId];
- unit->Data.ResWorker.DoneHarvesting = 0;
+ unit->Data.ResWorker.DoneHarvesting = 0;
- return 1;
+ return 1;
}
/**
-** FIXME: docu
+** Animate A unit that is harvesting
+**
+** @param unit Unit to animate
*/
local void AnimateActionHarvest(Unit* unit)
{
- int flags;
+ int flags;
- if (unit->Type->Animations) {
- DebugCheck(!unit->Type->Animations->Harvest[unit->CurrentResource]);
- flags = UnitShowAnimation(unit,
- unit->Type->Animations->Harvest[unit->CurrentResource]);
- if ((flags & AnimationSound) && (UnitVisibleOnMap(unit) ||
ReplayRevealMap)) {
- PlayUnitSound(unit, VoiceHarvesting);
+ if (unit->Type->Animations) {
+
DebugCheck(!unit->Type->Animations->Harvest[unit->CurrentResource]);
+ flags = UnitShowAnimation(unit,
+ unit->Type->Animations->Harvest[unit->CurrentResource]);
+ if ((flags & AnimationSound) && (UnitVisibleOnMap(unit) ||
ReplayRevealMap)) {
+ PlayUnitSound(unit, VoiceHarvesting);
+ }
}
- }
}
/*
-** Find something else to do when the resource is exhausted.
-** This is called from GatherResorce when the resource is empty.
+** Find something else to do when the resource is exhausted.
+** This is called from GatherResorce when the resource is empty.
**
-** @param unit pointer to harvester unit.
-** @param source pointer to resource unit.
+** @param unit pointer to harvester unit.
+** @param source pointer to resource unit.
*/
-local void LoseResource(Unit* unit,const Unit* source)
+local void LoseResource(Unit* unit, const Unit* source)
{
- Unit* depot;
- ResourceInfo* resinfo;
- resinfo = unit->Type->ResInfo[unit->CurrentResource];
-
- if (unit->Container) {
- DebugCheck(resinfo->HarvestFromOutside);
- }
-
- //
- // If we are loaded first search for a depot.
- //
- if (unit->Value && (depot = FindDeposit(unit, unit->X, unit->Y,
- 1000, unit->CurrentResource))) {
+ Unit* depot;
+ ResourceInfo* resinfo;
+ resinfo = unit->Type->ResInfo[unit->CurrentResource];
+
if (unit->Container) {
- DropOutNearest(unit, depot->X + depot->Type->TileWidth / 2,
- depot->Y + depot->Type->TileHeight / 2,
- source->Type->TileWidth, source->Type->TileHeight);
+ DebugCheck(resinfo->HarvestFromOutside);
}
+
//
- // Remember were it mined, so it can look around for another resource.
+ // If we are loaded first search for a depot.
//
- unit->Orders[0].Arg1 = (void*)((unit->X << 16) | unit->Y);
- unit->Orders[0].Goal = depot;
- RefsIncrease(depot);
- NewResetPath(unit);
- unit->SubAction = SUB_MOVE_TO_DEPOT;
- unit->Wait = unit->Reset = 1;
- unit->State = 0;
- DebugLevel0Fn("Sent unit %d to depot\n" _C_ unit->Slot);
- return;
- }
- //
- // No depot found, or harvester empty
- // Dump the unit outside and look for something to do.
- //
- if (unit->Container) {
- DebugCheck(resinfo->HarvestFromOutside);
- DropOutOnSide(unit, LookingW, source->Type->TileWidth,
- source->Type->TileHeight);
- }
- unit->Orders[0].X = unit->Orders[0].Y = -1;
- if ((unit->Orders[0].Goal = FindResource(unit, unit->X, unit->Y,
- 10, unit->CurrentResource))) {
- DebugLevel0Fn("Unit %d found another resource.\n" _C_ unit->Slot);
- unit->SubAction = SUB_START_RESOURCE;
- unit->Wait = unit->Reset = 1;
- unit->State = 0;
- RefsIncrease(unit->Orders[0].Goal);
- } else {
- DebugLevel0Fn("Unit %d just sits around confused.\n" _C_ unit->Slot);
- unit->Orders[0].Action = UnitActionStill;
- unit->SubAction = 0;
- unit->Wait = unit->Reset = 1;
- unit->State = 0;
- }
+ if (unit->Value && (depot = FindDeposit(unit, unit->X, unit->Y,
+ 1000, unit->CurrentResource))) {
+ if (unit->Container) {
+ DropOutNearest(unit, depot->X + depot->Type->TileWidth
/ 2,
+ depot->Y + depot->Type->TileHeight / 2,
+ source->Type->TileWidth,
source->Type->TileHeight);
+ }
+ //
+ // Remember were it mined, so it can look around for another
resource.
+ //
+ unit->Orders[0].Arg1 = (void*)((unit->X << 16) | unit->Y);
+ unit->Orders[0].Goal = depot;
+ RefsIncrease(depot);
+ NewResetPath(unit);
+ unit->SubAction = SUB_MOVE_TO_DEPOT;
+ unit->Wait = unit->Reset = 1;
+ unit->State = 0;
+ DebugLevel0Fn("Sent unit %d to depot\n" _C_ unit->Slot);
+ return;
+ }
+ //
+ // No depot found, or harvester empty
+ // Dump the unit outside and look for something to do.
+ //
+ if (unit->Container) {
+ DebugCheck(resinfo->HarvestFromOutside);
+ DropOutOnSide(unit, LookingW, source->Type->TileWidth,
+ source->Type->TileHeight);
+ }
+ unit->Orders[0].X = unit->Orders[0].Y = -1;
+ if ((unit->Orders[0].Goal = FindResource(unit, unit->X, unit->Y,
+ 10, unit->CurrentResource))) {
+ DebugLevel0Fn("Unit %d found another resource.\n" _C_
unit->Slot);
+ unit->SubAction = SUB_START_RESOURCE;
+ unit->Wait = unit->Reset = 1;
+ unit->State = 0;
+ RefsIncrease(unit->Orders[0].Goal);
+ } else {
+ DebugLevel0Fn("Unit %d just sits around confused.\n" _C_
unit->Slot);
+ unit->Orders[0].Action = UnitActionStill;
+ unit->SubAction = 0;
+ unit->Wait = unit->Reset = 1;
+ unit->State = 0;
+ }
}
/**
-** Wait in resource, for collecting the resource.
+** Wait in resource, for collecting the resource.
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
**
-** @return TRUE if ready, otherwise FALSE.
+** @return TRUE if ready, otherwise FALSE.
*/
local int GatherResource(Unit* unit)
{
- Unit* source;
- Unit* uins;
- ResourceInfo* resinfo;
- int i;
- int addload;
-
- resinfo = unit->Type->ResInfo[unit->CurrentResource];
- source = 0;
-
- if (resinfo->HarvestFromOutside || resinfo->TerrainHarvester) {
- AnimateActionHarvest(unit);
- unit->Data.ResWorker.TimeToHarvest -= unit->Wait;
- } else {
- unit->Data.ResWorker.TimeToHarvest--;
- unit->Wait = 1;
- }
-
- if (unit->Data.ResWorker.DoneHarvesting) {
- DebugCheck(!(resinfo->HarvestFromOutside || resinfo->TerrainHarvester));
- return unit->Reset;
- }
-
- // Target gone?
- if (resinfo->TerrainHarvester && !ForestOnMap(unit->Orders->X,
unit->Orders->Y)) {
- DebugLevel3Fn("Wood gone for unit %d.\n" _C_ unit->Slot);
- if (unit->Reset) {
- // Action now breakable, move to resource again.
- unit->SubAction = SUB_MOVE_TO_RESOURCE;
- // Give it some reasonable look while serching.
- unit->Frame = unit->Type->Animations->Still->Frame;
+ Unit* source;
+ Unit* uins;
+ ResourceInfo* resinfo;
+ int i;
+ int addload;
+
+ resinfo = unit->Type->ResInfo[unit->CurrentResource];
+ source = 0;
+
+ if (resinfo->HarvestFromOutside || resinfo->TerrainHarvester) {
+ AnimateActionHarvest(unit);
+ unit->Data.ResWorker.TimeToHarvest -= unit->Wait;
+ } else {
+ unit->Data.ResWorker.TimeToHarvest--;
+ unit->Wait = 1;
+ }
+
+ if (unit->Data.ResWorker.DoneHarvesting) {
+ DebugCheck(!(resinfo->HarvestFromOutside ||
resinfo->TerrainHarvester));
+ return unit->Reset;
+ }
+
+ // Target gone?
+ if (resinfo->TerrainHarvester && !ForestOnMap(unit->Orders->X,
unit->Orders->Y)) {
+ DebugLevel3Fn("Wood gone for unit %d.\n" _C_ unit->Slot);
+ if (unit->Reset) {
+ // Action now breakable, move to resource again.
+ unit->SubAction = SUB_MOVE_TO_RESOURCE;
+ // Give it some reasonable look while serching.
+ unit->Frame = unit->Type->Animations->Still->Frame;
+ }
+ return 0;
+ // No wood? Freeze!!!
}
- return 0;
- // No wood? Freeze!!!
- }
- while ((!unit->Data.ResWorker.DoneHarvesting) &&
- unit->Data.ResWorker.TimeToHarvest < 0) {
- unit->Data.ResWorker.TimeToHarvest += resinfo->WaitAtResource /
- SpeedResourcesHarvest[resinfo->ResourceId];
-
- //
- // Calculate how much we can load.
- //
- if (resinfo->ResourceStep) {
- addload = resinfo->ResourceStep;
- } else {
- addload = resinfo->ResourceCapacity;
- }
- // Make sure we don't bite more than we can chew.
- if (unit->Value + addload > resinfo->ResourceCapacity) {
- addload = resinfo->ResourceCapacity - unit->Value;
- }
-
- if (resinfo->TerrainHarvester) {
- DebugLevel3Fn("Harvested another %d resources.\n" _C_ addload);
- unit->Value += addload;
+ while ((!unit->Data.ResWorker.DoneHarvesting) &&
+ unit->Data.ResWorker.TimeToHarvest < 0) {
+ unit->Data.ResWorker.TimeToHarvest += resinfo->WaitAtResource /
+ SpeedResourcesHarvest[resinfo->ResourceId];
- if (addload && unit->Value == resinfo->ResourceCapacity) {
- DebugLevel3("Removed wood.\n");
- MapRemoveWood(unit->Orders->X, unit->Orders->Y);
- }
- } else {
- if (resinfo->HarvestFromOutside) {
- source = unit->Orders[0].Goal;
- } else {
- source = unit->Container;
- }
-
- DebugCheck(!source);
- DebugCheck(source->Value > 655350);
-
- //
- // Target is not dead, getting resources.
- //
- if (!GoalGone(unit, source)) {
- // Don't load more that there is.
- if (addload > source->Value) {
- addload = source->Value;
- }
-
- DebugLevel3Fn("Harvested another %d resources.\n" _C_ addload);
- unit->Value += addload;
- source->Value -= addload;
-
- UnitMarkSeen(source);
- if (IsOnlySelected(source)) {
- MustRedraw |= RedrawInfoPanel;
- }
- }
-
- //
- // End of resource: destroy the resource.
- // FIXME: implement depleted resources.
- //
- if (GoalGone(unit, source) || (source->Value == 0)) {
- DebugLevel0Fn("Resource is destroyed for unit %d\n" _C_
unit->Slot);
- uins = source->UnitInside;
//
- // Improved version of DropOutAll that makes workers go to the
depot.
+ // Calculate how much we can load.
//
- LoseResource(unit,source);
- for (i = source->InsideCount; i; --i, uins =
uins->NextContained) {
- LoseResource(uins,source);
+ if (resinfo->ResourceStep) {
+ addload = resinfo->ResourceStep;
+ } else {
+ addload = resinfo->ResourceCapacity;
+ }
+ // Make sure we don't bite more than we can chew.
+ if (unit->Value + addload > resinfo->ResourceCapacity) {
+ addload = resinfo->ResourceCapacity - unit->Value;
}
- // Don't destroy the resource twice.
- // This only happens when it's empty.
- if (!GoalGone(unit, source)){
- LetUnitDie(source);
- // FIXME: make the workers inside look for a new resource.
+ if (resinfo->TerrainHarvester) {
+ DebugLevel3Fn("Harvested another %d resources.\n" _C_
addload);
+ unit->Value += addload;
+
+ if (addload && unit->Value ==
resinfo->ResourceCapacity) {
+ DebugLevel3("Removed wood.\n");
+ MapRemoveWood(unit->Orders->X, unit->Orders->Y);
+ }
+ } else {
+ if (resinfo->HarvestFromOutside) {
+ source = unit->Orders[0].Goal;
+ } else {
+ source = unit->Container;
+ }
+
+ DebugCheck(!source);
+ DebugCheck(source->Value > 655350);
+
+ //
+ // Target is not dead, getting resources.
+ //
+ if (!GoalGone(unit, source)) {
+ // Don't load more that there is.
+ if (addload > source->Value) {
+ addload = source->Value;
+ }
+
+ DebugLevel3Fn("Harvested another %d
resources.\n" _C_ addload);
+ unit->Value += addload;
+ source->Value -= addload;
+
+ UnitMarkSeen(source);
+ if (IsOnlySelected(source)) {
+ MustRedraw |= RedrawInfoPanel;
+ }
+ }
+
+ //
+ // End of resource: destroy the resource.
+ // FIXME: implement depleted resources.
+ //
+ if (GoalGone(unit, source) || (source->Value == 0)) {
+ DebugLevel0Fn("Resource is destroyed for unit
%d\n" _C_ unit->Slot);
+ uins = source->UnitInside;
+ //
+ // Improved version of DropOutAll that makes
workers go to the depot.
+ //
+ LoseResource(unit,source);
+ for (i = source->InsideCount; i; --i, uins =
uins->NextContained) {
+ LoseResource(uins,source);
+ }
+
+ // Don't destroy the resource twice.
+ // This only happens when it's empty.
+ if (!GoalGone(unit, source)){
+ LetUnitDie(source);
+ // FIXME: make the workers inside look
for a new resource.
+ }
+ source = NULL;
+ return 0;
+ }
+ }
+ if (resinfo->TerrainHarvester) {
+ if (unit->Value == resinfo->ResourceCapacity) {
+ // Mark as complete.
+ DebugLevel3Fn("Done Harvesting, waiting for
reset.\n");
+ unit->Data.ResWorker.DoneHarvesting = 1;
+ }
+ return 0;
}
- source = NULL;
- return 0;
- }
- }
- if (resinfo->TerrainHarvester) {
- if (unit->Value == resinfo->ResourceCapacity) {
- // Mark as complete.
- DebugLevel3Fn("Done Harvesting, waiting for reset.\n");
- unit->Data.ResWorker.DoneHarvesting = 1;
- }
- return 0;
- }
- if (resinfo->HarvestFromOutside && !resinfo->TerrainHarvester) {
- if ((unit->Value == resinfo->ResourceCapacity) || (source == NULL))
{
- // Mark as complete.
- DebugLevel3Fn("Done Harvesting, waiting for reset %X.\n" _C_
(unsigned)source);
- unit->Data.ResWorker.DoneHarvesting = 1;
- }
- return 0;
- }
+ if (resinfo->HarvestFromOutside && !resinfo->TerrainHarvester) {
+ if ((unit->Value == resinfo->ResourceCapacity) ||
(source == NULL)) {
+ // Mark as complete.
+ DebugLevel3Fn("Done Harvesting, waiting for
reset %X.\n" _C_ (unsigned)source);
+ unit->Data.ResWorker.DoneHarvesting = 1;
+ }
+ return 0;
+ }
- if ((!resinfo->HarvestFromOutside) && (!resinfo->TerrainHarvester)) {
- return unit->Value == resinfo->ResourceCapacity && source;
+ if ((!resinfo->HarvestFromOutside) &&
(!resinfo->TerrainHarvester)) {
+ return unit->Value == resinfo->ResourceCapacity &&
source;
+ }
}
- }
- return 0;
+ return 0;
}
/**
-** Stop gathering from the resource, go home.
+** Stop gathering from the resource, go home.
**
-** @param unit Poiner to unit.
+** @param unit Poiner to unit.
**
-** @return TRUE if ready, otherwise FALSE.
+** @return TRUE if ready, otherwise FALSE.
*/
local int StopGathering(Unit* unit)
{
- Unit* depot;
- Unit* source;
- ResourceInfo* resinfo;
-
- resinfo = unit->Type->ResInfo[unit->CurrentResource];
-
- source = 0;
- if (!resinfo->TerrainHarvester) {
- if (resinfo->HarvestFromOutside) {
- source = unit->Orders[0].Goal;
+ Unit* depot;
+ Unit* source;
+ ResourceInfo* resinfo;
+
+ resinfo = unit->Type->ResInfo[unit->CurrentResource];
+
+ source = 0;
+ if (!resinfo->TerrainHarvester) {
+ if (resinfo->HarvestFromOutside) {
+ source = unit->Orders[0].Goal;
+ } else {
+ source = unit->Container;
+ }
+ source->Data.Resource.Active--;
+ DebugCheck(source->Data.Resource.Active < 0);
+ }
+
+
+ // Store resource position.
+ // FIXME: is this the best way?
+ unit->Orders[0].Arg1 = (void*)((unit->X << 16) | unit->Y);
+
+ if (!unit->Value) {
+ DebugLevel0Fn("Unit %d is empty???\n" _C_ unit->Slot);
} else {
- source = unit->Container;
+ DebugLevel3Fn("Unit %d is fine, search for a depot.\n" _C_
unit->Slot);
}
- source->Data.Resource.Active--;
- DebugCheck(source->Data.Resource.Active < 0);
- }
-
-
- // Store resource position.
- // FIXME: is this the best way?
- unit->Orders[0].Arg1 = (void*)((unit->X << 16) | unit->Y);
-
- if (!unit->Value) {
- DebugLevel0Fn("Unit %d is empty???\n" _C_ unit->Slot);
- } else {
- DebugLevel3Fn("Unit %d is fine, search for a depot.\n" _C_ unit->Slot);
- }
- // Find and send to resource deposit.
- if (!(depot = FindDeposit(unit, unit->X, unit->Y, 1000,
unit->CurrentResource)) ||
- !unit->Value) {
- if (!(resinfo->HarvestFromOutside || resinfo->TerrainHarvester)) {
- DebugCheck(!unit->Container);
- DropOutOnSide(unit, LookingW, source->Type->TileWidth,
- source->Type->TileHeight);
+ // Find and send to resource deposit.
+ if (!(depot = FindDeposit(unit, unit->X, unit->Y, 1000,
unit->CurrentResource)) ||
+ !unit->Value) {
+ if (!(resinfo->HarvestFromOutside ||
resinfo->TerrainHarvester)) {
+ DebugCheck(!unit->Container);
+ DropOutOnSide(unit, LookingW, source->Type->TileWidth,
+ source->Type->TileHeight);
+ }
+ DebugLevel0Fn("Can't find a resource deposit for unit %d.\n"
_C_ unit->Slot);
+ unit->Orders[0].Action = UnitActionStill;
+ unit->Orders[0].Goal = NoUnitP;
+ unit->SubAction = 0;
+ // should return 0, done below!
+ } else {
+ if (!(resinfo->HarvestFromOutside ||
resinfo->TerrainHarvester)) {
+ DebugCheck(!unit->Container);
+ DropOutNearest(unit, depot->X + depot->Type->TileWidth
/ 2,
+ depot->Y + depot->Type->TileHeight / 2,
+ source->Type->TileWidth,
source->Type->TileHeight);
+ }
+ unit->Orders[0].Goal = depot;
+ RefsIncrease(depot);
+ unit->Orders[0].Range = 1;
+ unit->Orders[0].X = unit->Orders[0].Y = -1;
+ unit->SubAction = SUB_MOVE_TO_DEPOT;
+ NewResetPath(unit);
}
- DebugLevel0Fn("Can't find a resource deposit for unit %d.\n" _C_
unit->Slot);
- unit->Orders[0].Action = UnitActionStill;
- unit->Orders[0].Goal = NoUnitP;
- unit->SubAction = 0;
- // should return 0, done below!
- } else {
- if (!(resinfo->HarvestFromOutside || resinfo->TerrainHarvester)) {
- DebugCheck(!unit->Container);
- DropOutNearest(unit, depot->X + depot->Type->TileWidth / 2,
- depot->Y + depot->Type->TileHeight / 2,
- source->Type->TileWidth, source->Type->TileHeight);
- }
- unit->Orders[0].Goal = depot;
- RefsIncrease(depot);
- unit->Orders[0].Range = 1;
- unit->Orders[0].X = unit->Orders[0].Y = -1;
- unit->SubAction = SUB_MOVE_TO_DEPOT;
- NewResetPath(unit);
- }
-
- CheckUnitToBeDrawn(unit);
- if (IsOnlySelected(unit)) {
- SelectedUnitChanged();
- // FIXME: redundant?
- MustRedraw |= RedrawButtonPanel;
- }
- unit->Wait = 1;
- return unit->Orders[0].Action != UnitActionStill;
+ CheckUnitToBeDrawn(unit);
+ if (IsOnlySelected(unit)) {
+ SelectedUnitChanged();
+ // FIXME: redundant?
+ MustRedraw |= RedrawButtonPanel;
+ }
+
+ unit->Wait = 1;
+ return unit->Orders[0].Action != UnitActionStill;
}
/**
-** Move to resource depot
+** Move to resource depot
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
**
-** @return TRUE if reached, otherwise FALSE.
+** @return TRUE if reached, otherwise FALSE.
*/
local int MoveToDepot(Unit* unit)
{
- Unit* goal;
- ResourceInfo* resinfo;
+ Unit* goal;
+ ResourceInfo* resinfo;
- resinfo = unit->Type->ResInfo[unit->CurrentResource];
+ resinfo = unit->Type->ResInfo[unit->CurrentResource];
- goal = unit->Orders[0].Goal;
- DebugCheck(!goal);
+ goal = unit->Orders[0].Goal;
+ DebugCheck(!goal);
- switch (DoActionMove(unit)) { // reached end-point?
- case PF_UNREACHABLE:
- return -1;
- case PF_REACHED:
- break;
- default:
- if (!unit->Reset || !GoalGone(unit, goal)) {
+ switch (DoActionMove(unit)) { // reached end-point?
+ case PF_UNREACHABLE:
+ return -1;
+ case PF_REACHED:
+ break;
+ default:
+ if (!unit->Reset || !GoalGone(unit, goal)) {
+ return 0;
+ }
+ break;
+ }
+
+ //
+ // Target is dead, stop getting resources.
+ //
+ if (GoalGone(unit, goal)) {
+ DebugLevel0Fn("Destroyed depot\n");
+ RefsDecrease(goal);
+ unit->Orders[0].Goal = NoUnitP;
+ // FIXME: perhaps we should choose an alternative
+ unit->Orders[0].Action = UnitActionStill;
+ unit->SubAction = 0;
return 0;
- }
- break;
- }
-
- //
- // Target is dead, stop getting resources.
- //
- if (GoalGone(unit, goal)) {
- DebugLevel0Fn("Destroyed depot\n");
- RefsDecrease(goal);
- unit->Orders[0].Goal = NoUnitP;
- // FIXME: perhaps we should choose an alternative
- unit->Orders[0].Action = UnitActionStill;
- unit->SubAction = 0;
- return 0;
- }
+ }
- DebugCheck(unit->Wait != 1);
+ DebugCheck(unit->Wait != 1);
- //
- // If resource depot is still under construction, wait!
- //
- if (goal->Orders[0].Action == UnitActionBuilded) {
- DebugLevel2Fn("Invalid resource depot. FIXME:WAIT!!! \n");
- return 0;
- }
+ //
+ // If resource depot is still under construction, wait!
+ //
+ if (goal->Orders[0].Action == UnitActionBuilded) {
+ DebugLevel2Fn("Invalid resource depot. FIXME:WAIT!!! \n");
+ return 0;
+ }
- RefsDecrease(goal);
- unit->Orders[0].Goal = NoUnitP;
+ RefsDecrease(goal);
+ unit->Orders[0].Goal = NoUnitP;
- //
- // Place unit inside the depot
- //
- RemoveUnit(unit, goal);
- unit->X = goal->X;
- unit->Y = goal->Y;
-
- //
- // Update resource.
- //
- unit->Player->Resources[resinfo->FinalResource] +=
- (unit->Value * unit->Player->Incomes[resinfo->FinalResource]) / 100;
- unit->Player->TotalResources[resinfo->FinalResource] +=
- (unit->Value * unit->Player->Incomes[resinfo->FinalResource]) / 100;
- unit->Value = 0;
- if (unit->Player == ThisPlayer) {
- MustRedraw |= RedrawResources;
- }
+ //
+ // Place unit inside the depot
+ //
+ RemoveUnit(unit, goal);
+ unit->X = goal->X;
+ unit->Y = goal->Y;
- unit->Wait = resinfo->WaitAtDepot /
SpeedResourcesReturn[resinfo->ResourceId];
- if (!unit->Wait) {
- unit->Wait = 1;
- }
+ //
+ // Update resource.
+ //
+ unit->Player->Resources[resinfo->FinalResource] +=
+ (unit->Value * unit->Player->Incomes[resinfo->FinalResource]) /
100;
+ unit->Player->TotalResources[resinfo->FinalResource] +=
+ (unit->Value * unit->Player->Incomes[resinfo->FinalResource]) /
100;
+ unit->Value = 0;
+ if (unit->Player == ThisPlayer) {
+ MustRedraw |= RedrawResources;
+ }
+
+ unit->Wait = resinfo->WaitAtDepot /
SpeedResourcesReturn[resinfo->ResourceId];
+ if (!unit->Wait) {
+ unit->Wait = 1;
+ }
- return 1;
+ return 1;
}
/**
-** Wait in depot, for the resources stored.
+** Wait in depot, for the resources stored.
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
**
-** @return TRUE if ready, otherwise FALSE.
+** @return TRUE if ready, otherwise FALSE.
*/
local int WaitInDepot(Unit* unit)
{
- const Unit* depot;
- Unit* goal;
- ResourceInfo* resinfo;
- int x;
- int y;
-
- resinfo = unit->Type->ResInfo[unit->CurrentResource];
-
- depot = ResourceDepositOnMap(unit->X, unit->Y, resinfo->ResourceId);
- DebugCheck(!depot);
- // Could be destroyed, but then we couldn't be in?
-
- if (unit->Orders[0].Arg1 == (void*)-1) {
- x = unit->X;
- y = unit->Y;
- } else {
- x = (int)unit->Orders[0].Arg1 >> 16;
- y = (int)unit->Orders[0].Arg1 & 0xFFFF;
- }
- // Range hardcoded. don't stray too far though
- if (resinfo->TerrainHarvester) {
- if (FindTerrainType(UnitMovementMask(unit), MapFieldForest, 0, 10,
- unit->Player, x, y, &x, &y)) {
- DropOutNearest(unit, x, y, depot->Type->TileWidth,
depot->Type->TileHeight);
- unit->Orders->X = x;
- unit->Orders->Y = y;
+ const Unit* depot;
+ Unit* goal;
+ ResourceInfo* resinfo;
+ int x;
+ int y;
+
+ resinfo = unit->Type->ResInfo[unit->CurrentResource];
+
+ depot = ResourceDepositOnMap(unit->X, unit->Y, resinfo->ResourceId);
+ DebugCheck(!depot);
+ // Could be destroyed, but then we couldn't be in?
+
+ if (unit->Orders[0].Arg1 == (void*)-1) {
+ x = unit->X;
+ y = unit->Y;
} else {
- DropOutOnSide(unit, LookingW, depot->Type->TileWidth,
depot->Type->TileHeight);
- unit->Orders[0].Action = UnitActionStill;
- unit->SubAction = 0;
- }
- } else {
- if ((goal = FindResource(unit, x, y, 10, unit->CurrentResource))) {
- DropOutNearest(unit, goal->X + goal->Type->TileWidth / 2,
- goal->Y + goal->Type->TileHeight / 2,
- depot->Type->TileWidth, depot->Type->TileHeight);
- unit->Orders[0].Goal = goal;
- RefsIncrease(goal);
- unit->Orders[0].Range = 1;
- unit->Orders[0].X = unit->Orders[0].Y = -1;
+ x = (int)unit->Orders[0].Arg1 >> 16;
+ y = (int)unit->Orders[0].Arg1 & 0xFFFF;
+ }
+ // Range hardcoded. don't stray too far though
+ if (resinfo->TerrainHarvester) {
+ if (FindTerrainType(UnitMovementMask(unit), MapFieldForest, 0,
10,
+ unit->Player, x, y, &x, &y)) {
+ DropOutNearest(unit, x, y, depot->Type->TileWidth,
depot->Type->TileHeight);
+ unit->Orders->X = x;
+ unit->Orders->Y = y;
+ } else {
+ DropOutOnSide(unit, LookingW, depot->Type->TileWidth,
depot->Type->TileHeight);
+ unit->Orders[0].Action = UnitActionStill;
+ unit->SubAction = 0;
+ }
} else {
- DropOutOnSide(unit, LookingW, depot->Type->TileWidth,
depot->Type->TileHeight);
- unit->Orders[0].Action = UnitActionStill;
- unit->SubAction = 0;
- }
- }
-
- CheckUnitToBeDrawn(unit);
- unit->Wait = 1;
- return unit->Orders[0].Action != UnitActionStill;
+ if ((goal = FindResource(unit, x, y, 10,
unit->CurrentResource))) {
+ DropOutNearest(unit, goal->X + goal->Type->TileWidth /
2,
+ goal->Y + goal->Type->TileHeight / 2,
+ depot->Type->TileWidth,
depot->Type->TileHeight);
+ unit->Orders[0].Goal = goal;
+ RefsIncrease(goal);
+ unit->Orders[0].Range = 1;
+ unit->Orders[0].X = unit->Orders[0].Y = -1;
+ } else {
+ DropOutOnSide(unit, LookingW, depot->Type->TileWidth,
depot->Type->TileHeight);
+ unit->Orders[0].Action = UnitActionStill;
+ unit->SubAction = 0;
+ }
+ }
+
+ CheckUnitToBeDrawn(unit);
+ unit->Wait = 1;
+ return unit->Orders[0].Action != UnitActionStill;
}
/**
-** Give up on gathering.
+** Give up on gathering.
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
*/
void ResourceGiveUp(Unit* unit)
{
- DebugLevel0Fn("Unit %d gave up on resource gathering.\n" _C_ unit->Slot);
- unit->Orders[0].Action = UnitActionStill;
- unit->Wait = 1;
- unit->Reset = 1;
- unit->Orders[0].X = unit->Orders[0].Y = -1;
- unit->SubAction = 0;
- if (unit->Type->ResInfo[unit->CurrentResource]->LoseResources &&
- unit->Value <
unit->Type->ResInfo[unit->CurrentResource]->ResourceCapacity) {
- unit->Value = 0;
- unit->CurrentResource = 0;
- }
- if (unit->Orders[0].Goal) {
- RefsDecrease(unit->Orders->Goal);
- unit->Orders[0].Goal = NoUnitP;
- }
+ DebugLevel0Fn("Unit %d gave up on resource gathering.\n" _C_
unit->Slot);
+ unit->Orders[0].Action = UnitActionStill;
+ unit->Wait = 1;
+ unit->Reset = 1;
+ unit->Orders[0].X = unit->Orders[0].Y = -1;
+ unit->SubAction = 0;
+ if (unit->Type->ResInfo[unit->CurrentResource]->LoseResources &&
+ unit->Value <
unit->Type->ResInfo[unit->CurrentResource]->ResourceCapacity) {
+ unit->Value = 0;
+ unit->CurrentResource = 0;
+ }
+ if (unit->Orders[0].Goal) {
+ RefsDecrease(unit->Orders->Goal);
+ unit->Orders[0].Goal = NoUnitP;
+ }
}
/**
-** Control the unit action: getting a resource.
+** Control the unit action: getting a resource.
**
-** This the generic function for oil, gold, ...
+** This the generic function for oil, gold, ...
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
*/
global void HandleActionResource(Unit* unit)
{
- int ret;
- int newres;
+ int ret;
+ int newres;
- DebugLevel3Fn("%s(%d) SubAction %d TTH %d res %s goal %ul\n" _C_
- unit->Type->Ident _C_ UnitNumber(unit) _C_ unit->SubAction _C_
- unit->Data.ResWorker.TimeToHarvest _C_
- DefaultResourceNames[unit->CurrentResource] _C_
- (unsigned int)unit->Orders->Goal);
-
- // Let's start mining.
- if (unit->SubAction == SUB_START_RESOURCE) {
- if (unit->Orders->Goal) {
- newres = unit->Orders->Goal->Type->GivesResource;
- } else {
- newres = WoodCost;
+ DebugLevel3Fn("%s(%d) SubAction %d TTH %d res %s goal %ul\n" _C_
+ unit->Type->Ident _C_ UnitNumber(unit) _C_ unit->SubAction _C_
+ unit->Data.ResWorker.TimeToHarvest _C_
+ DefaultResourceNames[unit->CurrentResource] _C_
+ (unsigned int)unit->Orders->Goal);
+
+ // Let's start mining.
+ if (unit->SubAction == SUB_START_RESOURCE) {
+ if (unit->Orders->Goal) {
+ newres = unit->Orders->Goal->Type->GivesResource;
+ } else {
+ newres = WoodCost;
+ }
+ if (newres != unit->CurrentResource) {
+ // Drop other resources.
+ unit->Value = 0;
+ }
+ unit->CurrentResource = newres;
+ NewResetPath(unit);
+ DebugLevel3Fn("Started mining. reset path.\n");
+ unit->SubAction = SUB_MOVE_TO_RESOURCE;
}
- if (newres != unit->CurrentResource) {
- // Drop other resources.
- unit->Value = 0;
- }
- unit->CurrentResource = newres;
- NewResetPath(unit);
- DebugLevel3Fn("Started mining. reset path.\n");
- unit->SubAction = SUB_MOVE_TO_RESOURCE;
- }
- DebugCheck(!unit->CurrentResource);
-
- // Move to the resource location.
- if (unit->SubAction >= SUB_MOVE_TO_RESOURCE &&
- unit->SubAction < SUB_UNREACHABLE_RESOURCE) {
- // -1 failure, 0 not yet reached, 1 reached
- if ((ret = MoveToResource(unit))) {
- if (ret == -1) {
- // Can't Reach
- unit->SubAction++;
- unit->Wait = 10;
+ DebugCheck(!unit->CurrentResource);
+
+ // Move to the resource location.
+ if (unit->SubAction >= SUB_MOVE_TO_RESOURCE &&
+ unit->SubAction < SUB_UNREACHABLE_RESOURCE) {
+ // -1 failure, 0 not yet reached, 1 reached
+ if ((ret = MoveToResource(unit))) {
+ if (ret == -1) {
+ // Can't Reach
+ unit->SubAction++;
+ unit->Wait = 10;
+ return;
+ } else {
+ // Reached
+ unit->SubAction = SUB_START_GATHERING;
+ }
+ } else {
+ // Move along.
+ return;
+ }
+ }
+
+ // Resource seems to be unreachable
+ if (unit->SubAction == SUB_UNREACHABLE_RESOURCE) {
+ ResourceGiveUp(unit);
return;
- } else {
- // Reached
- unit->SubAction = SUB_START_GATHERING;
- }
- } else {
- // Move along.
- return;
}
- }
- // Resource seems to be unreachable
- if (unit->SubAction == SUB_UNREACHABLE_RESOURCE) {
- ResourceGiveUp(unit);
- return;
- }
-
- // Start gathering the resource
- if (unit->SubAction == SUB_START_GATHERING) {
- if (StartGathering(unit)) {
- unit->SubAction = SUB_GATHER_RESOURCE;
- } else {
- return;
+ // Start gathering the resource
+ if (unit->SubAction == SUB_START_GATHERING) {
+ if (StartGathering(unit)) {
+ unit->SubAction = SUB_GATHER_RESOURCE;
+ } else {
+ return;
+ }
}
- }
- // Gather the resource.
- if (unit->SubAction == SUB_GATHER_RESOURCE) {
- if (GatherResource(unit)) {
- unit->SubAction = SUB_STOP_GATHERING;
- } else {
- return;
+ // Gather the resource.
+ if (unit->SubAction == SUB_GATHER_RESOURCE) {
+ if (GatherResource(unit)) {
+ unit->SubAction = SUB_STOP_GATHERING;
+ } else {
+ return;
+ }
}
- }
- // Stop gathering the resource.
- if (unit->SubAction == SUB_STOP_GATHERING) {
- if (StopGathering(unit)) {
- unit->SubAction = SUB_MOVE_TO_DEPOT;
- }
- }
-
- // Move back home.
- if (unit->SubAction >= SUB_MOVE_TO_DEPOT &&
- unit->SubAction < SUB_UNREACHABLE_DEPOT) {
- // -1 failure, 0 not yet reached, 1 reached
- if ((ret = MoveToDepot(unit))) {
- if (ret == -1) {
- // Can't Reach
- unit->SubAction++;
- unit->Wait = 10;
- } else {
- unit->SubAction = SUB_RETURN_RESOURCE;
- }
- }
- return;
- }
-
- // Depot seems to be unreachable
- if (unit->SubAction == SUB_UNREACHABLE_DEPOT) {
- ResourceGiveUp(unit);
- return;
- }
-
- // Unload resources at the depot.
- 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);
+ // Stop gathering the resource.
+ if (unit->SubAction == SUB_STOP_GATHERING) {
+ if (StopGathering(unit)) {
+ unit->SubAction = SUB_MOVE_TO_DEPOT;
+ }
+ }
+
+ // Move back home.
+ if (unit->SubAction >= SUB_MOVE_TO_DEPOT &&
+ unit->SubAction < SUB_UNREACHABLE_DEPOT) {
+ // -1 failure, 0 not yet reached, 1 reached
+ if ((ret = MoveToDepot(unit))) {
+ if (ret == -1) {
+ // Can't Reach
+ unit->SubAction++;
+ unit->Wait = 10;
+ } else {
+ unit->SubAction = SUB_RETURN_RESOURCE;
+ }
+ }
+ return;
+ }
+
+ // Depot seems to be unreachable
+ if (unit->SubAction == SUB_UNREACHABLE_DEPOT) {
+ ResourceGiveUp(unit);
+ return;
+ }
+
+ // Unload resources at the depot.
+ 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);
+ }
+ return;
}
- return;
- }
}
//@}
Index: stratagus/src/action/action_stand.c
diff -u stratagus/src/action/action_stand.c:1.23
stratagus/src/action/action_stand.c:1.24
--- stratagus/src/action/action_stand.c:1.23 Sat Oct 4 08:42:30 2003
+++ stratagus/src/action/action_stand.c Sun Dec 14 19:10:37 2003
@@ -1,16 +1,16 @@
-// _________ __ __
+// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
-// \/ \/ \//_____/ \/
+// \/ \/ \//_____/ \/
// ______________________ ______________________
-// T H E W A R B E G I N S
-// Stratagus - A free fantasy real time strategy game engine
+// T H E W A R B E G I N S
+// Stratagus - A free fantasy real time strategy game engine
//
-/address@hidden action_stand.c - The stand ground action. */
+/address@hidden action_stand.c - The stand ground action. */
//
-// (c) Copyright 2000,2001 by Lutz Sammer
+// (c) Copyright 2000-2004 by Lutz Sammer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -26,12 +26,12 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: action_stand.c,v 1.23 2003/10/03 22:42:30 jsalmon3 Exp $
+// $Id: action_stand.c,v 1.24 2003/12/14 08:10:37 wizzard Exp $
//@{
/*----------------------------------------------------------------------------
--- Includes
+-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
@@ -41,17 +41,17 @@
#include "actions.h"
/*----------------------------------------------------------------------------
--- Functions
+-- Functions
----------------------------------------------------------------------------*/
/**
-** Unit stands ground!
+** Unit stands ground!
**
-** @param unit Action handled for this unit pointer.
+** @param unit Action handled for this unit pointer.
*/
global void HandleActionStandGround(Unit* unit)
{
- ActionStillGeneric(unit, 1);
+ ActionStillGeneric(unit, 1);
}
//@}
Index: stratagus/src/action/action_still.c
diff -u stratagus/src/action/action_still.c:1.76
stratagus/src/action/action_still.c:1.77
--- stratagus/src/action/action_still.c:1.76 Mon Dec 1 07:03:31 2003
+++ stratagus/src/action/action_still.c Sun Dec 14 19:10:37 2003
@@ -1,16 +1,16 @@
-// _________ __ __
+// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
-// \/ \/ \//_____/ \/
+// \/ \/ \//_____/ \/
// ______________________ ______________________
-// T H E W A R B E G I N S
-// Stratagus - A free fantasy real time strategy game engine
+// T H E W A R B E G I N S
+// Stratagus - A free fantasy real time strategy game engine
//
-/address@hidden action_still.c - The stand still action. */
+/address@hidden action_still.c - The stand still action. */
//
-// (c) Copyright 1998,2000-2003 by Lutz Sammer and Jimmy Salmon
+// (c) Copyright 1998-2004 by Lutz Sammer and Jimmy Salmon
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -26,19 +26,18 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: action_still.c,v 1.76 2003/11/30 20:03:31 jsalmon3 Exp $
+// $Id: action_still.c,v 1.77 2003/12/14 08:10:37 wizzard Exp $
//@{
/*----------------------------------------------------------------------------
--- Includes
+-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include "stratagus.h"
-
#include "missile.h"
#include "unittype.h"
#include "actions.h"
@@ -48,218 +47,218 @@
#include "pathfinder.h"
/*----------------------------------------------------------------------------
--- Functions
+-- Functions
----------------------------------------------------------------------------*/
/**
-** Unit stands still or stand ground.
+** Unit stands still or stand ground.
**
-** @param unit Unit pointer for action.
-** @param ground Flag: true if unit is standing ground.
+** @param unit Unit pointer for action.
+** @param ground Flag: true if unit is standing ground.
*/
global void ActionStillGeneric(Unit* unit, int ground)
{
- const UnitType* type;
- Unit* temp;
- Unit* goal;
+ const UnitType* type;
+ Unit* temp;
+ Unit* goal;
+
+ DebugLevel3Fn(" %d\n" _C_ UnitNumber(unit));
+
+ if (unit->Removed) { // Removed units, do nothing?
+ // If peon is in building or unit is in transporter it is
removed.
+ unit->Wait = CYCLES_PER_SECOND / 6;
+ return;
+ }
- DebugLevel3Fn(" %d\n" _C_ UnitNumber(unit));
+ //
+ // Animations
+ //
- if (unit->Removed) { // Removed units, do nothing?
- // If peon is in building or unit is in transporter it is removed.
- unit->Wait = CYCLES_PER_SECOND / 6;
- return;
- }
+ type = unit->Type;
- //
- // Animations
- //
+ if (unit->SubAction) {
+ //
+ // Attacking unit in attack range.
+ //
+ AnimateActionAttack(unit);
+ } else {
+ //
+ // Still animation
+ //
+ DebugCheck(!type->Animations || !type->Animations->Still);
+
+ UnitShowAnimation(unit, type->Animations->Still);
+
+ //
+ // FIXME: this a workaround for some bad code.
+ // UnitShowAnimation resets frame.
+ // FIXME: the frames are hardcoded they should be configurable
+ //
+ if (unit->State == 1 && type->GivesResource == GoldCost) {
+ unit->Frame = unit->Data.Resource.Active ? 1 : 0;
+ }
+ if (unit->State == 1 && type->GivesResource == OilCost) {
+ unit->Frame = unit->Data.Resource.Active ? 2 : 0;
+ }
+ UnitMarkSeen(unit);
+ }
- type = unit->Type;
+ if (!unit->Reset) { // animation can't be aborted here
+ return;
+ }
- if (unit->SubAction) {
//
- // Attacking unit in attack range.
+ // Some units, like critter are moving random around randomly
//
- AnimateActionAttack(unit);
- } else {
+ if (type->RandomMovementProbability &&
+ ((SyncRand() % 100) <=
type->RandomMovementProbability)) {
+ int x;
+ int y;
+
+ x = unit->X;
+ y = unit->Y;
+ switch ((SyncRand() >> 12) & 15) {
+ case 0: x++; break;
+ case 1: y++; break;
+ case 2: x--; break;
+ case 3: y--; break;
+ case 4: x++; y++; break;
+ case 5: x--; y++; break;
+ case 6: y--; x++; break;
+ case 7: x--; y--; break;
+ default:
+ break;
+ }
+ if (x < 0) {
+ x = 0;
+ } else if (x >= TheMap.Width) {
+ x = TheMap.Width - 1;
+ }
+ if (y < 0) {
+ y = 0;
+ } else if (y >= TheMap.Height) {
+ y = TheMap.Height - 1;
+ }
+ if (x != unit->X || y != unit->Y) {
+ if (CheckedCanMoveToMask(x, y, TypeMovementMask(type)))
{
+ // FIXME: Don't use pathfinder for this, costs
too much cpu.
+ unit->Orders[0].Action = UnitActionMove;
+ DebugCheck(unit->Orders[0].Goal);
+ unit->Orders[0].Goal = NoUnitP;
+ unit->Orders[0].Range = 0;
+ unit->Orders[0].X = x;
+ unit->Orders[0].Y = y;
+ unit->State = 0;
+ }
+ }
+ // NOTE: critter couldn't attack automatic through the return
+ return;
+ }
+
//
- // Still animation
+ // Auto cast spells
//
- DebugCheck(!type->Animations || !type->Animations->Still);
-
- UnitShowAnimation(unit, type->Animations->Still);
+ if (unit->AutoCastSpell && AutoCastSpell(unit, unit->AutoCastSpell)) {
+ return;
+ }
//
- // FIXME: this a workaround for some bad code.
- // UnitShowAnimation resets frame.
- // FIXME: the frames are hardcoded they should be configurable
+ // Cowards don't attack unless instructed.
//
- if (unit->State == 1 && type->GivesResource == GoldCost) {
- unit->Frame = unit->Data.Resource.Active ? 1 : 0;
- }
- if (unit->State == 1 && type->GivesResource == OilCost) {
- unit->Frame = unit->Data.Resource.Active ? 2 : 0;
+ if (type->CanAttack && !type->Coward) {
+ //
+ // Normal units react in reaction range.
+ //
+ if (unit->Stats->Speed && !ground) {
+ if ((goal = AttackUnitsInReactRange(unit))) {
+ // Weak goal, can choose other unit, come back
after attack
+ CommandAttack(unit, goal->X, goal->Y, NULL,
FlushCommands);
+ DebugLevel3Fn(" %d Attacking in range %d\n" _C_
+ UnitNumber(unit) _C_ unit->SubAction);
+ DebugCheck(unit->SavedOrder.Action !=
UnitActionStill);
+ DebugCheck(unit->SavedOrder.Goal);
+ unit->SavedOrder.Action = UnitActionAttack;
+ unit->SavedOrder.Range = 0;
+ unit->SavedOrder.X = unit->X;
+ unit->SavedOrder.Y = unit->Y;
+ unit->SavedOrder.Goal = NoUnitP;
+ }
+ } else if ((goal = AttackUnitsInRange(unit))) {
+ DebugLevel3Fn(" %d #%d\n" _C_ UnitNumber(goal) _C_
goal->Refs);
+ //
+ // Old goal destroyed.
+ //
+ temp = unit->Orders[0].Goal;
+ if (temp && temp->Destroyed) {
+ RefsDecrease(temp);
+ unit->Orders[0].Goal = temp = NoUnitP;
+ }
+ if (!unit->SubAction || temp != goal) {
+ // New target.
+ if (temp) {
+ RefsDecrease(temp);
+ }
+ unit->Orders[0].Goal = goal;
+ RefsIncrease(goal);
+ unit->Reset = 0;
+ unit->State = 0;
+ unit->SubAction = 1; // Mark attacking.
+ if (type->Stats->Speed) {
+ UnitHeadingFromDeltaXY(unit,
+ goal->X +
(goal->Type->TileWidth - 1) / 2 - unit->X,
+ goal->Y +
(goal->Type->TileHeight - 1) / 2 - unit->Y);
+ AnimateActionAttack(unit);
+ }
+ }
+ return;
+ }
}
- UnitMarkSeen(unit);
- }
- if (!unit->Reset) { // animation can't be aborted here
- return;
- }
-
- //
- // Some units, like critter are moving random around randomly
- //
- if (type->RandomMovementProbability &&
- ((SyncRand() % 100) <= type->RandomMovementProbability)) {
- int x;
- int y;
-
- x = unit->X;
- y = unit->Y;
- switch ((SyncRand() >> 12) & 15) {
- case 0: x++; break;
- case 1: y++; break;
- case 2: x--; break;
- case 3: y--; break;
- case 4: x++; y++; break;
- case 5: x--; y++; break;
- case 6: y--; x++; break;
- case 7: x--; y--; break;
- default:
- break;
- }
- if (x < 0) {
- x = 0;
- } else if (x >= TheMap.Width) {
- x = TheMap.Width - 1;
- }
- if (y < 0) {
- y = 0;
- } else if (y >= TheMap.Height) {
- y = TheMap.Height - 1;
- }
- if (x != unit->X || y != unit->Y) {
- if (CheckedCanMoveToMask(x, y, TypeMovementMask(type))) {
- // FIXME: Don't use pathfinder for this, costs too much cpu.
- unit->Orders[0].Action = UnitActionMove;
- DebugCheck(unit->Orders[0].Goal);
- unit->Orders[0].Goal = NoUnitP;
- unit->Orders[0].Range = 0;
- unit->Orders[0].X = x;
- unit->Orders[0].Y = y;
- unit->State = 0;
- }
- }
- // NOTE: critter couldn't attack automatic through the return
- return;
- }
-
- //
- // Auto cast spells
- //
- if (unit->AutoCastSpell && AutoCastSpell(unit, unit->AutoCastSpell)) {
- return;
- }
-
- //
- // Cowards don't attack unless instructed.
- //
- if (type->CanAttack && !type->Coward) {
- //
- // Normal units react in reaction range.
- //
- if (unit->Stats->Speed && !ground) {
- if ((goal = AttackUnitsInReactRange(unit))) {
- // Weak goal, can choose other unit, come back after attack
- CommandAttack(unit, goal->X, goal->Y, NULL, FlushCommands);
- DebugLevel3Fn(" %d Attacking in range %d\n" _C_
- UnitNumber(unit) _C_ unit->SubAction);
- DebugCheck(unit->SavedOrder.Action != UnitActionStill);
- DebugCheck(unit->SavedOrder.Goal);
- unit->SavedOrder.Action = UnitActionAttack;
- unit->SavedOrder.Range = 0;
- unit->SavedOrder.X = unit->X;
- unit->SavedOrder.Y = unit->Y;
- unit->SavedOrder.Goal = NoUnitP;
- }
- } else if ((goal = AttackUnitsInRange(unit))) {
- DebugLevel3Fn(" %d #%d\n" _C_ UnitNumber(goal) _C_ goal->Refs);
- //
- // Old goal destroyed.
- //
- temp = unit->Orders[0].Goal;
- if (temp && temp->Destroyed) {
- RefsDecrease(temp);
- unit->Orders[0].Goal = temp = NoUnitP;
- }
- if (!unit->SubAction || temp != goal) {
- // New target.
- if (temp) {
- RefsDecrease(temp);
+ if (unit->SubAction) { // was attacking.
+ if ((temp = unit->Orders[0].Goal)) {
+ RefsDecrease(temp);
+ unit->Orders[0].Goal = NoUnitP;
}
- unit->Orders[0].Goal = goal;
- RefsIncrease(goal);
- unit->Reset = 0;
- unit->State = 0;
- unit->SubAction = 1; // Mark attacking.
- if (type->Stats->Speed) {
- UnitHeadingFromDeltaXY(unit,
- goal->X + (goal->Type->TileWidth - 1) / 2 - unit->X,
- goal->Y + (goal->Type->TileHeight - 1) / 2 - unit->Y);
- AnimateActionAttack(unit);
- }
- }
- return;
+ unit->SubAction = unit->State = 0; // No attacking, restart
}
- }
- if (unit->SubAction) { // was attacking.
- if ((temp = unit->Orders[0].Goal)) {
- RefsDecrease(temp);
- unit->Orders[0].Goal = NoUnitP;
+ //
+ // Land units are turning left/right.
+ //
+ if (type->LandUnit) {
+ switch ((MyRand() >> 8) & 0x0FF) {
+ case 0: // Turn clockwise
+ unit->Direction += NextDirection;
+ UnitUpdateHeading(unit);
+ CheckUnitToBeDrawn(unit);
+ break;
+ case 1: // Turn counter clockwise
+ unit->Direction -= NextDirection;
+ UnitUpdateHeading(unit);
+ CheckUnitToBeDrawn(unit);
+ break;
+ default: // does nothing
+ break;
+ }
+ return;
}
- unit->SubAction = unit->State = 0; // No attacking, restart
- }
- //
- // Land units are turning left/right.
- //
- if (type->LandUnit) {
- switch ((MyRand() >> 8) & 0x0FF) {
- case 0: // Turn clockwise
- unit->Direction += NextDirection;
- UnitUpdateHeading(unit);
- CheckUnitToBeDrawn(unit);
- break;
- case 1: // Turn counter clockwise
- unit->Direction -= NextDirection;
- UnitUpdateHeading(unit);
- CheckUnitToBeDrawn(unit);
- break;
- default: // does nothing
- break;
+ //
+ // Sea and air units are floating up/down.
+ //
+ if (unit->Type->SeaUnit || unit->Type->AirUnit) {
+ unit->IY = (MyRand() >> 15) & 1;
}
- return;
- }
-
- //
- // Sea and air units are floating up/down.
- //
- if (unit->Type->SeaUnit || unit->Type->AirUnit) {
- unit->IY = (MyRand() >> 15) & 1;
- }
}
/**
-** Unit stands still!
+** Unit stands still!
**
-** @param unit Unit pointer for still action.
+** @param unit Unit pointer for still action.
*/
global void HandleActionStill(Unit* unit)
{
- ActionStillGeneric(unit, 0);
+ ActionStillGeneric(unit, 0);
}
//@}
Index: stratagus/src/action/action_unload.c
diff -u stratagus/src/action/action_unload.c:1.44
stratagus/src/action/action_unload.c:1.45
--- stratagus/src/action/action_unload.c:1.44 Mon Dec 1 07:03:31 2003
+++ stratagus/src/action/action_unload.c Sun Dec 14 19:10:37 2003
@@ -1,16 +1,16 @@
-// _________ __ __
+// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
-// \/ \/ \//_____/ \/
+// \/ \/ \//_____/ \/
// ______________________ ______________________
-// T H E W A R B E G I N S
-// Stratagus - A free fantasy real time strategy game engine
+// T H E W A R B E G I N S
+// Stratagus - A free fantasy real time strategy game engine
//
-/address@hidden action_unload.c - The unload action. */
+/address@hidden action_unload.c - The unload action. */
//
-// (c) Copyright 1998,2000-2001 by Lutz Sammer
+// (c) Copyright 1998-2004 by Lutz Sammer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -26,12 +26,12 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: action_unload.c,v 1.44 2003/11/30 20:03:31 jsalmon3 Exp $
+// $Id: action_unload.c,v 1.45 2003/12/14 08:10:37 wizzard Exp $
//@{
/*----------------------------------------------------------------------------
--- Includes
+-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
@@ -47,395 +47,398 @@
#include "pathfinder.h"
/*----------------------------------------------------------------------------
--- Functions
+-- Functions
----------------------------------------------------------------------------*/
// Flag for searching a valid tileset for unloading
#define LandUnitMask ( \
- MapFieldLandUnit | \
- MapFieldBuilding | \
- MapFieldWall | \
- MapFieldRocks | \
- MapFieldForest | \
- MapFieldCoastAllowed | \
- MapFieldWaterAllowed | \
- MapFieldUnpassable)
+ MapFieldLandUnit | \
+ MapFieldBuilding | \
+ MapFieldWall | \
+ MapFieldRocks | \
+ MapFieldForest | \
+ MapFieldCoastAllowed | \
+ MapFieldWaterAllowed | \
+ MapFieldUnpassable)
#define NavalUnitMask ( \
- MapFieldLandUnit | \
- MapFieldBuilding | \
- MapFieldWall | \
- MapFieldRocks | \
- MapFieldForest | \
- MapFieldCoastAllowed | \
- MapFieldLandAllowed | \
- MapFieldUnpassable)
-
-
+ MapFieldLandUnit | \
+ MapFieldBuilding | \
+ MapFieldWall | \
+ MapFieldRocks | \
+ MapFieldForest | \
+ MapFieldCoastAllowed | \
+ MapFieldLandAllowed | \
+ MapFieldUnpassable)
+
+
/**
-** Find a free position close to x, y
+** Find a free position close to x, y
**
-** @param x Original x search position.
-** @param y Original y search position
-** @param resx Unload x position.
-** @param resy Unload y position.
-** @param mask Movement mask for the unit to be droped.
+** @param x Original x search position
+** @param y Original y search position
+** @param resx Unload x position.
+** @param resy Unload y position.
+** @param mask Movement mask for the unit to be droped.
**
-** @return True if a position was found, False otherwise.
-** @note resx and resy are undefined if a position is not found.
+** @return True if a position was found, False otherwise.
+** @note resx and resy are undefined if a position is not found.
**
-** @bug FIXME: Place unit only on fields reachable from the transporter
+** @bug FIXME: Place unit only on fields reachable from the
transporter
*/
local int FindUnloadPosition(int x, int y, int* resx, int* resy, int mask)
{
- int i;
- int n;
- int addx;
- int addy;
-
- addx = addy = 1;
- --x;
- for (n = 0; n < 2; ++n) {
- // Nobody: There was some code here to check for unloading units that
can
- // only go on even tiles. It's useless, since we can only unload land
units.
- for (i = addy; i--; ++y) {
- if (CheckedCanMoveToMask(x, y, mask)) {
- *resx = x;
- *resy = y;
- return 1;
- }
- }
- ++addx;
- for (i = addx; i--; ++x) {
- if (CheckedCanMoveToMask(x, y, mask)) {
- *resx = x;
- *resy = y;
- return 1;
- }
- }
- ++addy;
- for (i = addy; i--; --y) {
- if (CheckedCanMoveToMask(x, y, mask)) {
- *resx = x;
- *resy = y;
- return 1;
- }
- }
- ++addx;
- for (i = addx; i--; --x) {
- if (CheckedCanMoveToMask(x, y, mask)) {
- *resx = x;
- *resy = y;
- return 1;
- }
+ int i;
+ int n;
+ int addx;
+ int addy;
+
+ addx = addy = 1;
+ --x;
+ for (n = 0; n < 2; ++n) {
+ // Nobody: There was some code here to check for unloading
units that can
+ // only go on even tiles. It's useless, since we can only
unload land units.
+ for (i = addy; i--; ++y) {
+ if (CheckedCanMoveToMask(x, y, mask)) {
+ *resx = x;
+ *resy = y;
+ return 1;
+ }
+ }
+ ++addx;
+ for (i = addx; i--; ++x) {
+ if (CheckedCanMoveToMask(x, y, mask)) {
+ *resx = x;
+ *resy = y;
+ return 1;
+ }
+ }
+ ++addy;
+ for (i = addy; i--; --y) {
+ if (CheckedCanMoveToMask(x, y, mask)) {
+ *resx = x;
+ *resy = y;
+ return 1;
+ }
+ }
+ ++addx;
+ for (i = addx; i--; --x) {
+ if (CheckedCanMoveToMask(x, y, mask)) {
+ *resx = x;
+ *resy = y;
+ return 1;
+ }
+ }
+ ++addy;
}
- ++addy;
- }
- return 0;
+ return 0;
}
/**
-** Reappear unit on map.
+** Reappear unit on map.
**
-** @param unit Unit to drop out.
+** @param unit Unit to drop out.
**
-** @return True if unit can be unloaded.
+** @return True if unit can be unloaded.
**
-** @bug FIXME: Place unit only on fields reachable from the transporter
+** @bug FIXME: Place unit only on fields reachable from the
transporter
*/
global int UnloadUnit(Unit* unit)
{
- int x;
- int y;
+ int x;
+ int y;
- DebugCheck(!unit->Removed);
- if (!FindUnloadPosition(unit->X, unit->Y, &x, &y, UnitMovementMask(unit)))
{
- return 0;
- }
- unit->X = x;
- unit->Y = y;
- unit->Wait = 1; // should be correct unit has still action
- PlaceUnit(unit, x, y);
- return 1;
+ DebugCheck(!unit->Removed);
+ if (!FindUnloadPosition(unit->X, unit->Y, &x, &y,
UnitMovementMask(unit))) {
+ return 0;
+ }
+ unit->X = x;
+ unit->Y = y;
+ unit->Wait = 1; // should be correct unit has still
action
+ PlaceUnit(unit, x, y);
+ return 1;
}
/**
-** Find the closest piece of coast you can unload units on
-**
-** @param x start location for the search
-** @param y start location for the search
-** @param resx coast x position
-** @param resy coast y position
-** @return 1 if a location was found, 0 otherwise
+** Find the closest piece of coast you can unload units on
+**
+** @param x start location for the search
+** @param y start location for the search
+** @param resx coast x position
+** @param resy coast y position
+**
+** @return 1 if a location was found, 0 otherwise
*/
local int ClosestFreeCoast(int x, int y, int* resx, int* resy)
{
- int i;
- int addx;
- int addy;
- int nullx;
- int nully;
- int n;
-
- addx = addy = 1;
- if (CoastOnMap(x, y) &&
- FindUnloadPosition(x, y, &nullx, &nully, LandUnitMask)) {
- *resx = x;
- *resy = y;
- return 1;
- }
- --x;
- // The maximum distance to the coast. We have to stop somewhere...
- n = 20;
- while (n--) {
- for (i = addy; i--; ++y) {
- if (x >= 0 && y >= 0 && x < TheMap.Width && y < TheMap.Height &&
- CoastOnMap(x, y) && !UnitOnMapTile(x, y) &&
- FindUnloadPosition(x, y, &nullx, &nully, LandUnitMask)) {
- *resx = x;
- *resy = y;
- return 1;
- }
- }
- ++addx;
- for (i = addx; i--; ++x) {
- if (x >= 0 && y >= 0 && x < TheMap.Width && y < TheMap.Height &&
- CoastOnMap(x, y) && !UnitOnMapTile(x ,y) &&
- FindUnloadPosition(x, y, &nullx, &nully, LandUnitMask)) {
- *resx = x;
- *resy = y;
- return 1;
- }
- }
- ++addy;
- for (i = addy; i--; --y) {
- if (x >= 0 && y >= 0 && x < TheMap.Width && y < TheMap.Height &&
- CoastOnMap(x, y) && !UnitOnMapTile(x, y) &&
- FindUnloadPosition(x, y, &nullx, &nully, LandUnitMask)) {
+ int i;
+ int addx;
+ int addy;
+ int nullx;
+ int nully;
+ int n;
+
+ addx = addy = 1;
+ if (CoastOnMap(x, y) &&
+ FindUnloadPosition(x, y, &nullx, &nully, LandUnitMask))
{
*resx = x;
*resy = y;
return 1;
- }
}
- ++addx;
- for (i = addx; i--; --x) {
- if (x >= 0 && y >= 0 && x < TheMap.Width && y < TheMap.Height &&
- CoastOnMap(x, y) && !UnitOnMapTile(x, y) &&
- FindUnloadPosition(x, y, &nullx, &nully, LandUnitMask)) {
- *resx = x;
- *resy = y;
- return 1;
- }
+ --x;
+ // The maximum distance to the coast. We have to stop somewhere...
+ n = 20;
+ while (n--) {
+ for (i = addy; i--; ++y) {
+ if (x >= 0 && y >= 0 && x < TheMap.Width && y <
TheMap.Height &&
+ CoastOnMap(x, y) && !UnitOnMapTile(x,
y) &&
+ FindUnloadPosition(x, y, &nullx,
&nully, LandUnitMask)) {
+ *resx = x;
+ *resy = y;
+ return 1;
+ }
+ }
+ ++addx;
+ for (i = addx; i--; ++x) {
+ if (x >= 0 && y >= 0 && x < TheMap.Width && y <
TheMap.Height &&
+ CoastOnMap(x, y) && !UnitOnMapTile(x
,y) &&
+ FindUnloadPosition(x, y, &nullx,
&nully, LandUnitMask)) {
+ *resx = x;
+ *resy = y;
+ return 1;
+ }
+ }
+ ++addy;
+ for (i = addy; i--; --y) {
+ if (x >= 0 && y >= 0 && x < TheMap.Width && y <
TheMap.Height &&
+ CoastOnMap(x, y) && !UnitOnMapTile(x,
y) &&
+ FindUnloadPosition(x, y, &nullx,
&nully, LandUnitMask)) {
+ *resx = x;
+ *resy = y;
+ return 1;
+ }
+ }
+ ++addx;
+ for (i = addx; i--; --x) {
+ if (x >= 0 && y >= 0 && x < TheMap.Width && y <
TheMap.Height &&
+ CoastOnMap(x, y) && !UnitOnMapTile(x,
y) &&
+ FindUnloadPosition(x, y, &nullx,
&nully, LandUnitMask)) {
+ *resx = x;
+ *resy = y;
+ return 1;
+ }
+ }
+ ++addy;
}
- ++addy;
- }
- DebugLevel0Fn("Try clicking closer to an actual coast.\n");
- return 0;
+ DebugLevel0Fn("Try clicking closer to an actual coast.\n");
+ return 0;
}
/**
-** Find the closest available drop zone for a transporter.
-** Fail if transporter don't transport any unit..
-**
-** @param transporter the transporter
-** @param x start location for the search
-** @param y start location for the search
-** @param resx coast x position
-** @param resy coast y position
+** Find the closest available drop zone for a transporter.
+** Fail if transporter don't transport any unit..
+**
+** @param transporter the transporter
+** @param x start location for the search
+** @param y start location for the search
+** @param resx coast x position
+** @param resy coast y position
**
-** @return 1 if a location was found, 0 otherwise
+** @return 1 if a location was found, 0 otherwise
**
*/
local int ClosestFreeDropZone(Unit* transporter, int x, int y, int* resx, int*
resy)
{
- // Type ( land/fly/naval) of the transporter
- int transporterType;
- // Type ( land/fly/naval) of the units to unload
- int loadedType;
-
- // Check there are units onboard
- if (!transporter->UnitInside) {
- return 0;
- }
-
- transporterType=transporter->Type->UnitType;
- // Take the type of the onboard unit
- loadedType=transporter->UnitInside->Type->UnitType;
-
- // Don't move in thoses cases
- if ((transporterType == loadedType) || (loadedType == UnitTypeFly)) {
- *resx=x;
- *resy=y;
- return 1;
- }
+ // Type (land/fly/naval) of the transporter
+ int transporterType;
+ // Type (land/fly/naval) of the units to unload
+ int loadedType;
+
+ // Check there are units onboard
+ if (!transporter->UnitInside) {
+ return 0;
+ }
+
+ transporterType = transporter->Type->UnitType;
+ // Take the type of the onboard unit
+ loadedType = transporter->UnitInside->Type->UnitType;
- switch(transporterType) {
- case UnitTypeLand:
- // in this case, loadedType==UnitTypeSea
- return ClosestFreeCoast(x,y,resx,resy);
- case UnitTypeNaval:
- // Same ( but reversed... )
- return ClosestFreeCoast(x,y,resx,resy);
- case UnitTypeFly:
- // Here we have loadedType in [ UnitTypeLand,UnitTypeNaval ]
- if ( loadedType == UnitTypeLand ) {
- return FindUnloadPosition(x,y,resx,resy,LandUnitMask);
- } else {
- return FindUnloadPosition(x,y,resx,resy,NavalUnitMask);
- }
- }
- // Just to avoid a warning
- return 0;
+ // Don't move in thoses cases
+ if ((transporterType == loadedType) || (loadedType == UnitTypeFly)) {
+ *resx = x;
+ *resy = y;
+ return 1;
+ }
+
+ switch (transporterType) {
+ case UnitTypeLand:
+ // in this case, loadedType == UnitTypeSea
+ return ClosestFreeCoast(x, y, resx, resy);
+ case UnitTypeNaval:
+ // Same ( but reversed... )
+ return ClosestFreeCoast(x, y, resx, resy);
+ case UnitTypeFly:
+ // Here we have loadedType in [
UnitTypeLand,UnitTypeNaval ]
+ if (loadedType == UnitTypeLand) {
+ return FindUnloadPosition(x, y, resx, resy,
LandUnitMask);
+ } else {
+ return FindUnloadPosition(x, y, resx, resy,
NavalUnitMask);
+ }
+ }
+ // Just to avoid a warning
+ return 0;
}
/**
-** Move to dropzone.
+** Move to dropzone.
+**
+** @param unit Pointer to unit.
**
-** @param unit Pointer to unit.
-** @return -1 if unreachable, True if reached, False otherwise.
+** @return -1 if unreachable, True if reached, False otherwise.
*/
local int MoveToDropZone(Unit* unit)
{
- DebugLevel3Fn("%p\n" _C_ unit->Orders[0].Goal);
-
- switch (DoActionMove(unit)) { // reached end-point?
- case PF_UNREACHABLE:
- DebugLevel2Fn("CAN'T REACH DROPZONE\n");
- return -1;
- case PF_REACHED:
- break;
- default:
- return 0;
- }
+ DebugLevel3Fn("%p\n" _C_ unit->Orders[0].Goal);
+
+ switch (DoActionMove(unit)) { // reached end-point?
+ case PF_UNREACHABLE:
+ DebugLevel2Fn("CAN'T REACH DROPZONE\n");
+ return -1;
+ case PF_REACHED:
+ break;
+ default:
+ return 0;
+ }
- DebugCheck(unit->Orders[0].Action != UnitActionUnload);
- return 1;
+ DebugCheck(unit->Orders[0].Action != UnitActionUnload);
+ return 1;
}
/**
-** Make one or more unit leave the transporter.
+** Make one or more unit leave the transporter.
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
*/
local void LeaveTransporter(Unit* unit)
{
- int i;
- int stillonboard;
- Unit* goal;
-
- stillonboard = 0;
- goal = unit->Orders[0].Goal;
- //
- // Goal is the specific unit unit that you want to unload.
- // This can be NULL, in case you want to unload everything.
- DebugLevel3Fn("Goal %p\n" _C_ goal);
- if (goal) {
- unit->Orders[0].Goal = NoUnitP;
- if (goal->Destroyed) {
- DebugLevel0Fn("destroyed unit unloading?\n");
- RefsDecrease(goal);
- return;
- }
- RefsDecrease(goal);
- goal->X = unit->X;
- goal->Y = unit->Y;
- // Try to unload the unit. If it doesn't work there is no problem.
- UnloadUnit(goal);
- } else {
- // Unload all units.
- goal = unit->UnitInside;
- for (i = unit->InsideCount; i; --i, goal = goal->NextContained) {
- goal->X = unit->X;
- goal->Y = unit->Y;
- if (!UnloadUnit(goal)) {
- ++stillonboard;
- }
- }
- }
- if (IsOnlySelected(unit)) {
- SelectedUnitChanged();
- MustRedraw |= RedrawInfoPanel;
- }
-
- // We still have some units to unload, find a piece of free coast.
- if (stillonboard) {
- // We tell it to unload at it's current position. This can't be done,
- // so it will search for a piece of free coast nearby.
- unit->Orders[0].Action = UnitActionUnload;
- unit->Orders[0].Goal = NoUnitP;
- unit->Orders[0].X = unit->X;
- unit->Orders[0].Y = unit->Y;
- unit->SubAction = 0;
- unit->Reset = 0;
- unit->Wait = 0;
- } else {
- unit->Wait = 1;
- unit->Orders[0].Action = UnitActionStill;
- unit->SubAction = 0;
- }
+ int i;
+ int stillonboard;
+ Unit* goal;
+
+ stillonboard = 0;
+ goal = unit->Orders[0].Goal;
+ //
+ // Goal is the specific unit unit that you want to unload.
+ // This can be NULL, in case you want to unload everything.
+ //
+ DebugLevel3Fn("Goal %p\n" _C_ goal);
+ if (goal) {
+ unit->Orders[0].Goal = NoUnitP;
+ if (goal->Destroyed) {
+ DebugLevel0Fn("destroyed unit unloading?\n");
+ RefsDecrease(goal);
+ return;
+ }
+ RefsDecrease(goal);
+ goal->X = unit->X;
+ goal->Y = unit->Y;
+ // Try to unload the unit. If it doesn't work there is no
problem.
+ UnloadUnit(goal);
+ } else {
+ // Unload all units.
+ goal = unit->UnitInside;
+ for (i = unit->InsideCount; i; --i, goal = goal->NextContained)
{
+ goal->X = unit->X;
+ goal->Y = unit->Y;
+ if (!UnloadUnit(goal)) {
+ ++stillonboard;
+ }
+ }
+ }
+ if (IsOnlySelected(unit)) {
+ SelectedUnitChanged();
+ MustRedraw |= RedrawInfoPanel;
+ }
+
+ // We still have some units to unload, find a piece of free coast.
+ if (stillonboard) {
+ // We tell it to unload at it's current position. This can't be
done,
+ // so it will search for a piece of free coast nearby.
+ unit->Orders[0].Action = UnitActionUnload;
+ unit->Orders[0].Goal = NoUnitP;
+ unit->Orders[0].X = unit->X;
+ unit->Orders[0].Y = unit->Y;
+ unit->SubAction = 0;
+ unit->Reset = 0;
+ unit->Wait = 0;
+ } else {
+ unit->Wait = 1;
+ unit->Orders[0].Action = UnitActionStill;
+ unit->SubAction = 0;
+ }
}
/**
-** The transporter unloads an unit.
+** The transporter unloads an unit.
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
*/
global void HandleActionUnload(Unit* unit)
{
- int i;
- int x;
- int y;
-
- DebugLevel3Fn("%p(%d) SubAction %d\n" _C_
- unit _C_ UnitNumber(unit) _C_ unit->SubAction);
+ int i;
+ int x;
+ int y;
+
+ DebugLevel3Fn("%p(%d) SubAction %d\n" _C_
+ unit _C_ UnitNumber(unit) _C_ unit->SubAction);
+
+ switch (unit->SubAction) {
+ //
+ // Move the transporter
+ //
+ case 0:
+ if (!unit->Orders[0].Goal) {
+ if
(!ClosestFreeDropZone(unit,unit->Orders[0].X,unit->Orders[0].Y,
+ &x, &y)) {
+ // Sorry... I give up.
+ unit->Orders[0].Action =
UnitActionStill;
+ unit->SubAction = 0;
+ return;
+ }
+ unit->Orders[0].X = x;
+ unit->Orders[0].Y = y;
+ }
- switch (unit->SubAction) {
- //
- // Move the transporter
- //
- case 0:
- if (!unit->Orders[0].Goal) {
- if
(!ClosestFreeDropZone(unit,unit->Orders[0].X,unit->Orders[0].Y,
- &x, &y)) {
- // Sorry... I give up.
- unit->Orders[0].Action = UnitActionStill;
- unit->SubAction = 0;
- return;
- }
- unit->Orders[0].X = x;
- unit->Orders[0].Y = y;
- }
-
- NewResetPath(unit);
- unit->SubAction = 1;
- case 1:
- // The Goal is the unit that we have to unload.
- if (!unit->Orders[0].Goal) {
- // We have to unload everything
- if ((i = MoveToDropZone(unit))) {
- if (i == PF_REACHED) {
- if (++unit->SubAction == 1) {
- unit->Orders[0].Action = UnitActionStill;
- unit->SubAction = 0;
- }
- } else {
- unit->SubAction = 2;
- }
- }
- break;
- }
- //
- // Leave the transporter
- //
- case 2:
- // FIXME: show still animations ?
- LeaveTransporter(unit);
- if (unit->Orders[0].Action != UnitActionStill) {
- HandleActionUnload(unit);
- }
- break;
- }
+ NewResetPath(unit);
+ unit->SubAction = 1;
+ case 1:
+ // The Goal is the unit that we have to unload.
+ if (!unit->Orders[0].Goal) {
+ // We have to unload everything
+ if ((i = MoveToDropZone(unit))) {
+ if (i == PF_REACHED) {
+ if (++unit->SubAction == 1) {
+ unit->Orders[0].Action
= UnitActionStill;
+ unit->SubAction = 0;
+ }
+ } else {
+ unit->SubAction = 2;
+ }
+ }
+ break;
+ }
+ //
+ // Leave the transporter
+ //
+ case 2:
+ // FIXME: show still animations ?
+ LeaveTransporter(unit);
+ if (unit->Orders[0].Action != UnitActionStill) {
+ HandleActionUnload(unit);
+ }
+ break;
+ }
}
//@}
Index: stratagus/src/action/action_upgradeto.c
diff -u stratagus/src/action/action_upgradeto.c:1.42
stratagus/src/action/action_upgradeto.c:1.43
--- stratagus/src/action/action_upgradeto.c:1.42 Mon Dec 1 07:03:31 2003
+++ stratagus/src/action/action_upgradeto.c Sun Dec 14 19:10:37 2003
@@ -1,16 +1,16 @@
-// _________ __ __
+// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
-// \/ \/ \//_____/ \/
+// \/ \/ \//_____/ \/
// ______________________ ______________________
-// T H E W A R B E G I N S
-// Stratagus - A free fantasy real time strategy game engine
+// T H E W A R B E G I N S
+// Stratagus - A free fantasy real time strategy game engine
//
-/address@hidden action_upgradeto.c - The unit upgrading to new action. */
+/address@hidden action_upgradeto.c - The unit upgrading to new action. */
//
-// (c) Copyright 1998,2000-2002 by Lutz Sammer
+// (c) Copyright 1998-2004 by Lutz Sammer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -26,12 +26,12 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: action_upgradeto.c,v 1.42 2003/11/30 20:03:31 jsalmon3 Exp $
+// $Id: action_upgradeto.c,v 1.43 2003/12/14 08:10:37 wizzard Exp $
//@{
/*----------------------------------------------------------------------------
--- Includes
+-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
@@ -46,71 +46,71 @@
#include "interface.h"
/*----------------------------------------------------------------------------
--- Functions
+-- Functions
----------------------------------------------------------------------------*/
/**
-** Unit upgrades unit!
+** Unit upgrades unit!
**
-** @param unit Pointer to unit.
+** @param unit Pointer to unit.
*/
global void HandleActionUpgradeTo(Unit* unit)
{
- Player* player;
- UnitType* type;
- const UnitStats* stats;
-
- DebugLevel3Fn(" %d\n" _C_ UnitNumber(unit));
-
- player = unit->Player;
- if (!unit->SubAction) { // first entry
- unit->Data.UpgradeTo.Ticks = 0;
- unit->SubAction = 1;
- }
- type = unit->Orders[0].Type;
- stats = &type->Stats[player->Player];
-
- UnitMarkSeen(unit);
- // FIXME: Should count down here
- unit->Data.UpgradeTo.Ticks += SpeedUpgrade;
- if (unit->Data.UpgradeTo.Ticks >= stats->Costs[TimeCost]) {
-
- unit->HP += stats->HitPoints -
unit->Type->Stats[player->Player].HitPoints;
- // don't have such unit now
- player->UnitTypesCount[unit->Type->Type]--;
- unit->Type = type;
- unit->Stats = (UnitStats*)stats;
- // and we have new one...
- player->UnitTypesCount[unit->Type->Type]++;
- UpdateForNewUnit(unit, 1);
-
- NotifyPlayer(player, NotifyGreen, unit->X, unit->Y,
- "Upgrade to %s complete", unit->Type->Name);
- if (unit->Player->AiEnabled) {
- AiUpgradeToComplete(unit, type);
- }
- unit->Reset = unit->Wait = 1;
- unit->Orders[0].Action = UnitActionStill;
- unit->SubAction = 0;
-
- //
- // Update possible changed buttons.
- //
- if (IsOnlySelected(unit) || player == ThisPlayer) {
- // could affect the buttons of any selected unit
- SelectedUnitChanged();
- MustRedraw |= RedrawInfoPanel;
+ Player* player;
+ UnitType* type;
+ const UnitStats* stats;
+
+ DebugLevel3Fn(" %d\n" _C_ UnitNumber(unit));
+
+ player = unit->Player;
+ if (!unit->SubAction) { // first entry
+ unit->Data.UpgradeTo.Ticks = 0;
+ unit->SubAction = 1;
}
+ type = unit->Orders[0].Type;
+ stats = &type->Stats[player->Player];
+
+ UnitMarkSeen(unit);
+ // FIXME: Should count down here
+ unit->Data.UpgradeTo.Ticks += SpeedUpgrade;
+ if (unit->Data.UpgradeTo.Ticks >= stats->Costs[TimeCost]) {
+
+ unit->HP += stats->HitPoints -
unit->Type->Stats[player->Player].HitPoints;
+ // don't have such unit now
+ player->UnitTypesCount[unit->Type->Type]--;
+ unit->Type = type;
+ unit->Stats = (UnitStats*)stats;
+ // and we have new one...
+ player->UnitTypesCount[unit->Type->Type]++;
+ UpdateForNewUnit(unit, 1);
+
+ NotifyPlayer(player, NotifyGreen, unit->X, unit->Y,
+ "Upgrade to %s complete", unit->Type->Name);
+ if (unit->Player->AiEnabled) {
+ AiUpgradeToComplete(unit, type);
+ }
+ unit->Reset = unit->Wait = 1;
+ unit->Orders[0].Action = UnitActionStill;
+ unit->SubAction = 0;
+
+ //
+ // Update possible changed buttons.
+ //
+ if (IsOnlySelected(unit) || player == ThisPlayer) {
+ // could affect the buttons of any selected unit
+ SelectedUnitChanged();
+ MustRedraw |= RedrawInfoPanel;
+ }
- return;
- }
+ return;
+ }
- if (IsOnlySelected(unit)) {
- MustRedraw |= RedrawInfoPanel;
- }
+ if (IsOnlySelected(unit)) {
+ MustRedraw |= RedrawInfoPanel;
+ }
- unit->Reset = 1;
- unit->Wait = CYCLES_PER_SECOND / 6;
+ unit->Reset = 1;
+ unit->Wait = CYCLES_PER_SECOND / 6;
}
//@}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Stratagus-CVS] stratagus/src/action action_attack.c action_boa...,
address@hidden <=