Add auto repair mode
This commit is contained in:
parent
1b7fa8c1e6
commit
414446bea9
14 changed files with 172 additions and 21 deletions
|
@ -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çois Beerten).
|
||||
<li>Added lua function ListDirectory which lists the files in a directory (from François Beerten).
|
||||
<li>Big unit can move (from Joris Dauphin).
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
//
|
||||
|
|
|
@ -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
|
||||
**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_ {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
**
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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\","
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue