Add auto repair mode

This commit is contained in:
jarod42 2004-12-16 19:16:29 +00:00
parent 1b7fa8c1e6
commit 414446bea9
14 changed files with 172 additions and 21 deletions

View file

@ -34,6 +34,7 @@
<ul>
<p><li>2.2 Released<p>
<ul>
<li>Add auto repair mode (use AutoRepairRange in DefineUnitType) (from Joris Dauphin).
<li>Allow graphics paths outside of the graphics subdirectory (from Russel Smith and Fran&ccedil;ois Beerten).
<li>Added lua function ListDirectory which lists the files in a directory (from Fran&ccedil;ois Beerten).
<li>Big unit can move (from Joris Dauphin).

View file

@ -219,6 +219,8 @@ Value correspond of min degat that the unit could do, and Max the max.</dd>
<dd>X position of the unit. Max is the Map size.</dd>
<dt>PosY</dt>
<dd>Y position of the unit. Max is the Map size.</dd>
<dt>AutoRepairRange</dt>
<dd>Range to check for unit to repair. (for unit which can repair)<dd>
<dt>Slot</dt>
<dd>Unique number that identifies the unit (begin at 0). Max is the last valid slot number.</dd>
</dl>
@ -575,6 +577,8 @@ F.E.: ImproveProduction = {"gold", 20, "wood", 5} will give 120% gold and 105% w
<dt>RepairRange = number</dt>
<dd>Range that a unit can repair from, eg. RepairRange = 1.
</dd>
<dt>AutoRepairRange = number</dt>
<dd>Range to check for unit to repair. (for unit which can repair)<dd>
<dt>RepairHp = number</dt>
<dd>Defines the amount of hp a unit gain for each repair animation. Units can only be
repaired if this value is non-zero.

View file

@ -52,6 +52,38 @@
-- Functions
----------------------------------------------------------------------------*/
/**
** Try to find a reparable unit around
** and return it.
**
** @param unit unit which could repare.
** @param range range to find a reparable unit.
**
** @return unit to repare if found, NULL else.
**
** @todo FIXME : find the better unit (most damaged, ...).
*/
static Unit* UnitToRepairInRange(Unit* unit, int range)
{
Unit* table[UnitMax]; // all unit in range.
int n; // number of unit in range.
int i; // iterator on unit.
n = UnitCacheSelect(unit->X - range, unit->Y - range,
unit->X + unit->Type->TileWidth + range,
unit->Y + unit->Type->TileHeight + range,
table);
for (i = 0; i < n; ++i) {
if (PlayersTeamed(table[i]->Player->Player, unit->Player->Player)
&& table[i]->Type->RepairHP && table[i]->HP < table[i]->Stats->HitPoints
&& UnitVisibleAsGoal(table[i], unit->Player)) {
return table[i];
}
}
return NoUnitP;
}
/**
** Unit stands still or stand ground.
**
@ -183,6 +215,19 @@ void ActionStillGeneric(Unit* unit, int ground)
}
}
}
// Auto Repair
if (unit->AutoRepair && type->Variable[AUTOREPAIRRANGE_INDEX].Value) {
Unit* repairedUnit; // Unit to repare
repairedUnit = UnitToRepairInRange(unit, type->Variable[AUTOREPAIRRANGE_INDEX].Value);
if (repairedUnit != NULL) {
CommandRepair(unit, -1, -1, repairedUnit, FlushCommands);
// unit has new order.
return ;
}
}
//
// Cowards don't attack unless instructed.
//

View file

@ -401,6 +401,23 @@ void CommandRepair(Unit* unit, int x, int y, Unit* dest, int flush)
ClearSavedAction(unit);
}
/**
** Auto repair.
**
** @param unit pointer to unit.
** @param spellid Spell id.
** @param on 1 for auto repair on, 0 for off.
*/
void CommandAutoRepair(Unit* unit, int on)
{
//
// Check if unit is still valid? (NETWORK!)
//
if (!unit->Removed && unit->Orders[0].Action != UnitActionDie) {
unit->AutoRepair = on;
}
}
/**
** Attack with unit at new position
**

View file

@ -84,6 +84,8 @@ extern void CommandMove(struct _unit_* unit, int x, int y, int flush);
/// Prepare command repair
extern void CommandRepair(struct _unit_* unit, int x, int y,
struct _unit_* dest, int flush);
/// Send auto repair command
extern void CommandAutoRepair(struct _unit_* unit, int on);
/// Prepare command attack
extern void CommandAttack(struct _unit_* unit, int x, int y,
struct _unit_* dest, int flush);

View file

@ -99,6 +99,8 @@ extern void SendCommandMove(struct _unit_* unit, int x, int y, int flush);
/// Send repair command
extern void SendCommandRepair(struct _unit_* unit, int x, int y,
struct _unit_* dest, int flush);
/// Send auto repair command
extern void SendCommandAutoRepair(struct _unit_* unit, int on);
/// Send attack command
extern void SendCommandAttack(struct _unit_* unit, int x, int y,
struct _unit_* dest, int flush);

View file

@ -82,6 +82,7 @@ enum _message_type_ {
MessageCommandFollow, ///< Unit command follow
MessageCommandMove, ///< Unit command move
MessageCommandRepair, ///< Unit command repair
MessageCommandAutoRepair, ///< Unit command autorepair
MessageCommandAttack, ///< Unit command attack
MessageCommandGround, ///< Unit command attack ground
MessageCommandPatrol, ///< Unit command patrol

View file

@ -627,6 +627,7 @@ struct _unit_ {
Order SavedOrder; ///< order to continue after current
Order NewOrder; ///< order for new trained units
char* AutoCastSpell; ///< spells to auto cast
unsigned AutoRepair : 1; ///< True if unit tries to repair on still action.
union _order_data_ {
struct _order_move_ {

View file

@ -660,7 +660,8 @@ typedef struct _variable_type_ {
#define POSY_INDEX 22
#define RADAR_INDEX 23
#define RADARJAMMER_INDEX 24
#define SLOT_INDEX 25
#define AUTOREPAIRRANGE_INDEX 25
#define SLOT_INDEX 26
#define NVARALREADYDEFINED SLOT_INDEX + 1 // Hardcoded variables

View file

@ -843,6 +843,8 @@ static void DoNextReplay(void)
SendCommandMove(UnitSlots[unit], posx, posy, flags);
} else if (!strcmp(action, "repair")) {
SendCommandRepair(UnitSlots[unit], posx, posy, dunit, flags);
} else if (!strcmp(action, "auto-repair")) {
SendCommandAutoRepair(UnitSlots[unit], posx);
} else if (!strcmp(action, "attack")) {
SendCommandAttack(UnitSlots[unit], posx, posy, dunit, flags);
} else if (!strcmp(action, "attack-ground")) {
@ -1072,6 +1074,24 @@ void SendCommandRepair(Unit* unit, int x, int y, Unit* dest, int flush)
}
}
/**
** Send command: Unit auto repair.
**
** @param unit pointer to unit.
** @param on 1 for auto repair on, 0 for off.
*/
void SendCommandAutoRepair(Unit* unit, int on)
{
if (!IsNetworkGame()) {
CommandLog("auto-repair", unit, FlushCommands, on, -1, NoUnitP,
NULL, 0);
CommandAutoRepair(unit, on);
} else {
NetworkSendCommand(MessageCommandAutoRepair,
unit, on, -1, NoUnitP, NULL, FlushCommands);
}
}
/**
** Send command: Unit attack unit or at position.
**

View file

@ -284,9 +284,6 @@ void DrawButtonPanel(void)
case ButtonAttackGround:
action = UnitActionAttackGround;
break;
case ButtonRepair:
action = UnitActionRepair;
break;
case ButtonPatrol:
action = UnitActionPatrol;
break;
@ -328,6 +325,9 @@ void DrawButtonPanel(void)
}
break;
case ButtonSpellCast:
// FIXME : and IconSelected ?
// Autocast
for (j = 0; j < NumSelected; ++j) {
Assert(Selected[j]->AutoCastSpell);
if (Selected[j]->AutoCastSpell[buttons[i].Value] != 1) {
@ -338,6 +338,27 @@ void DrawButtonPanel(void)
v |= IconAutoCast;
}
break;
case ButtonRepair:
for (j = 0; j < NumSelected; ++j) {
if (Selected[j]->Orders[0].Action != UnitActionRepair) {
break;
}
}
if (j == NumSelected) {
v |= IconSelected;
}
// Auto repair
for (j = 0; j < NumSelected; ++j) {
if (Selected[j]->AutoRepair != 1) {
break;
}
}
if (j == NumSelected) {
v |= IconAutoCast;
}
break;
break;
// FIXME: must handle more actions
@ -731,15 +752,16 @@ void DoButtonButtonClicked(int button)
!(KeyModifiers & ModifierShift));
break;
}
case ButtonMove:
case ButtonPatrol:
case ButtonHarvest:
case ButtonAttack:
case ButtonRepair:
case ButtonAttackGround:
CursorState = CursorStateSelect;
GameCursor = TheUI.YellowHair.Cursor;
CursorAction = CurrentButtons[button].Action;
CursorValue = CurrentButtons[button].Value;
CurrentButtonLevel = 9; // level 9 is cancel-only
UpdateButtonPanel();
SetStatusLine("Select Target");
break;
case ButtonSpellCast:
if (CurrentButtons[button].Action == ButtonSpellCast &&
(KeyModifiers & ModifierControl)) {
if (KeyModifiers & ModifierControl) {
int autocast;
int spellId;
@ -765,15 +787,43 @@ void DoButtonButtonClicked(int button)
spellId, autocast);
}
}
} else {
CursorState = CursorStateSelect;
GameCursor = TheUI.YellowHair.Cursor;
CursorAction = CurrentButtons[button].Action;
CursorValue = CurrentButtons[button].Value;
CurrentButtonLevel = 9; // level 9 is cancel-only
UpdateButtonPanel();
SetStatusLine("Select Target");
break;
}
// Follow Next -> Select target.
case ButtonRepair:
if (KeyModifiers & ModifierControl) {
int autorepair;
autorepair = 0;
// If any selected unit doesn't have autocast on turn it on
// for everyone
for (i = 0; i < NumSelected; ++i) {
if (Selected[i]->AutoRepair == 0) {
autorepair = 1;
break;
}
}
for (i = 0; i < NumSelected; ++i) {
if (Selected[i]->AutoRepair != autorepair) {
SendCommandAutoRepair(Selected[i], autorepair);
}
}
break;
}
// Follow Next -> Select target.
case ButtonMove:
case ButtonPatrol:
case ButtonHarvest:
case ButtonAttack:
case ButtonAttackGround:
// Select target.
CursorState = CursorStateSelect;
GameCursor = TheUI.YellowHair.Cursor;
CursorAction = CurrentButtons[button].Action;
CursorValue = CurrentButtons[button].Value;
CurrentButtonLevel = 9; // level 9 is cancel-only
UpdateButtonPanel();
SetStatusLine("Select Target");
break;
case ButtonReturn:
for (i = 0; i < NumSelected; ++i) {

View file

@ -696,6 +696,9 @@ static int CclUnit(lua_State* l)
} else if (!strcmp(value, "attacked")) {
// FIXME : unsigned long should be better handled
unit->Attacked = LuaToNumber(l, j + 1);
} else if (!strcmp(value, "auto-repair")) {
unit->AutoRepair = 1;
--j;
} else if (!strcmp(value, "burning")) {
unit->Burning = 1;
--j;

View file

@ -1938,7 +1938,7 @@ void InitDefinedVariables()
"Research", "Training", "UpgradeTo", "GiveResource", "CarryResource",
"Xp", "Level", "Kill", "Supply", "Demand", "Armor", "SightRange",
"AttackRange", "PiercingDamage", "BasicDamage", "Damage", "ExtraDamage",
"PosX", "PosY", "RadarRange", "RadarJammerRange", "Slot"
"PosX", "PosY", "RadarRange", "RadarJammerRange", "AutoRepairRange", "Slot"
}; // names of the variable.
const char* boolflag = "DefineBoolFlags(\"Coward\", \"Building\", \"Flip\","
"\"Revealer\", \"LandUnit\", \"AirUnit\", \"SeaUnit\", \"ExplodeWhenKilled\","

View file

@ -3761,6 +3761,10 @@ void SaveUnit(const Unit* unit, CLFile* file)
if (unit->Boarded) {
CLprintf(file, " \"boarded\",");
}
if (unit->AutoRepair) {
CLprintf(file, " \"auto-repair\",");
}
CLprintf(file, " \"rs\", %d,", unit->Rs);
CLprintf(file, " \"units-boarded-count\", %d,", unit->BoardCount);