diff --git a/doc/ChangeLog.html b/doc/ChangeLog.html index c3e61dd80..0b75e405f 100644 --- a/doc/ChangeLog.html +++ b/doc/ChangeLog.html @@ -36,6 +36,7 @@ <li>Future 2.00 Release<p> <ul> <li>++ + <li>Removed the demolish action, we now use the demolish spell. (from Crestez Leonard). <li>Applied patch #1969 (AI enhancement) (from Ludovic Pollet). <li>Added the demolish spell, though not complete (from Crestez Leonard). <li>Added the spawn-missile action, removed fireball death-coil whirlwind runes flame-shield (from Crestez Leonard). diff --git a/doc/scripts/magic.html b/doc/scripts/magic.html index cd98b09bf..25d202e4e 100644 --- a/doc/scripts/magic.html +++ b/doc/scripts/magic.html @@ -311,6 +311,17 @@ Here are the supported operations, their paramenters, and what they do.<p> 2 hit-points for 1 caster mana up to 20 hit-points/10 mana per cast </dd> </dl> + <dt>demolish</dt> + <dl>This will remove any trees/rocks/walls in and inflict a fixed damage + to a fixed area. Possible tags: + <dt>damage</dt> + <dd>Each and every unit in range will receive that damage. FIXME: no + support for dampening damage. + </dd> + <dt>range</dt> + <dd>The range of the terrain and unit damage. + </dd> + </dl> <dt>summon</dt> <dl>This will summon a new unit. Possible tags: <dt>unit-type</dt> diff --git a/doc/scripts/unittype.html b/doc/scripts/unittype.html index 1b1b85a18..4e0280fb4 100644 --- a/doc/scripts/unittype.html +++ b/doc/scripts/unittype.html @@ -326,9 +326,9 @@ F.E. "icon-knight", "icon-gold-mine". <dd>This should be used for resource gathering units. It will return goods when on a deposit and mine when on a resource. </dd> - <dt>right-demolish</dt> - <dd>This is for demolishing units. It will try to demolish instead of attack (since - demolishing units can still have a normal attack, but it really shouldn't be used) + <dt>right-spell-cast</dt> + <dd>This is an ugly hack for demolishing units. The unit will cast it's first + known spell(in order of spell definition) instead of attacking a hostile unit. </dd> <p></dl> <dt>can-gather-resource</dt> @@ -462,13 +462,6 @@ F.E.: '( gold 2 wood 1 oil 1 ). <dt>detect-cloak</dt> <dd>Unit can detect cloaked units. If an unit is detected other units can attack it as well\ </dd> -<dt>demolish-range</dt> -<dd>If non-zero this is the range for units that can demolish.The demolished area is a square, sorry. -</dd> -<dt>demolish-damage</dt> -<dd>Damage dealt to unit affected by demolition. This can be 0, in this case -only terrain will be affected. Units have to be in demolish-range to be affected. -</dd> <dt>random-movement-probablitity</dt> <dd>When the unit is idle this is the probability that it will take a step in a random direction, in percents. Usefull for neutral animals. diff --git a/src/action/Module.make b/src/action/Module.make index 5f355643b..e3eda038b 100644 --- a/src/action/Module.make +++ b/src/action/Module.make @@ -26,7 +26,7 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA MODULE = src/action -MSRC = action_attack.c action_board.c action_build.c action_demolish.c \ +MSRC = action_attack.c action_board.c action_build.c \ action_die.c action_follow.c action_move.c action_patrol.c \ action_repair.c action_research.c action_resource.c \ action_returngoods.c action_spellcast.c action_stand.c \ diff --git a/src/action/action_demolish.cpp b/src/action/action_demolish.cpp deleted file mode 100644 index b6a77e7fe..000000000 --- a/src/action/action_demolish.cpp +++ /dev/null @@ -1,229 +0,0 @@ -// _________ __ __ -// / _____// |_____________ _/ |______ ____ __ __ ______ -// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/ -// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ | -// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ > -// \/ \/ \//_____/ \/ -// ______________________ ______________________ -// T H E W A R B E G I N S -// Stratagus - A free fantasy real time strategy game engine -// -/**@name action_demolish.c - The demolish action. */ -// -// (c) Copyright 1999-2001 by Vladi Belperchinov-Shabanski -// -// 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 -// the Free Software Foundation; version 2 dated June, 1991. -// -// This program 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. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -// 02111-1307, USA. -// -// $Id$ - -//@{ - -/*---------------------------------------------------------------------------- --- Includes -----------------------------------------------------------------------------*/ - -#include <stdio.h> -#include <stdlib.h> - -#include "stratagus.h" -#include "unittype.h" -#include "player.h" -#include "unit.h" -#include "actions.h" -#include "sound.h" -#include "map.h" -#include "pathfinder.h" - -/*---------------------------------------------------------------------------- --- Functions -----------------------------------------------------------------------------*/ - -/* -** Unit Demolishes -** -** @param unit Unit, for that the demolish is handled. -*/ -global void HandleActionDemolish(Unit* unit) -{ - Unit* table[UnitMax]; - int i; - int n; - int xmin; - int ymin; - int xmax; - int ymax; - int ix; - int iy; - Unit* goal; - int err; - - DebugLevel3Fn("Demolish %d\n" _C_ UnitNumber(unit)); - - switch (unit->SubAction) { - // - // Move near to target. - // - case 0: // first entry. - NewResetPath(unit); - unit->SubAction = 1; - // - // Already at target? FIXME: duplicate code. - // - if ((goal = unit->Orders[0].Goal)) { - if (MapDistanceBetweenUnits(unit,goal) <= 1) { - unit->State = 0; - unit->SubAction = 2; - HandleActionDemolish(unit); - return; - } - } else if (MapDistanceToUnit(unit->Orders[0].X, - unit->Orders[0].Y,unit) <= 1) { - unit->State = 0; - unit->SubAction = 2; - HandleActionDemolish(unit); - return; - } - // FALL THROUGH - case 1: - // FIXME: reset first!! why? (johns) - err=DoActionMove(unit); - if (unit->Reset) { - goal = unit->Orders[0].Goal; - // - // Target is dead, stop demolish. - // FIXME: what should I do, go back or explode on place? - // - if (goal) { - if (goal->Destroyed) { - DebugLevel0Fn("Destroyed unit\n"); - RefsDebugCheck(!goal->Refs); - if (!--goal->Refs) { - ReleaseUnit(goal); - } - // FIXME: perhaps I should choose an alternative - unit->Orders[0].Goal = NoUnitP; - unit->Orders[0].Action = UnitActionStill; - unit->SubAction = 0; - return; - } else if (goal->Removed || !goal->HP || - goal->Orders[0].Action == UnitActionDie) { - RefsDebugCheck(!goal->Refs); - --goal->Refs; - RefsDebugCheck(!goal->Refs); - unit->Orders[0].Goal = NoUnitP; - // FIXME: perhaps I should choose an alternative - unit->Orders[0].Action = UnitActionStill; - unit->SubAction = 0; - return; - } - } - - // - // Have reached target? FIXME: could use pathfinder result? - // - if (goal) { - if (MapDistanceBetweenUnits(unit, goal) <= 1) { - unit->State = 0; - unit->SubAction = 2; - } - } else if (MapDistanceToUnit(unit->Orders[0].X, unit->Orders[0].Y, - unit) <= 1) { - unit->State = 0; - unit->SubAction = 2; - } else if (err == PF_UNREACHABLE) { - unit->Orders[0].Action = UnitActionStill; - return; - } - DebugCheck(unit->Orders[0].Action != UnitActionDemolish); - } - break; - - // - // Demolish the target. - // - case 2: - goal = unit->Orders[0].Goal; - if (goal) { - RefsDebugCheck(!goal->Refs); - --goal->Refs; - RefsDebugCheck(!goal->Refs); - unit->Orders[0].Goal = NoUnitP; - } - - if (unit->Type->DemolishRange) { - xmin = unit->X - unit->Type->DemolishRange; - ymin = unit->Y - unit->Type->DemolishRange; - xmax = unit->X + unit->Type->DemolishRange; - ymax = unit->Y + unit->Type->DemolishRange; - if (xmin < 0) { - xmin = 0; - } - if (xmax > TheMap.Width - 1) { - xmax = TheMap.Width - 1; - } - if (ymin < 0) { - ymin = 0; - } - if (ymax > TheMap.Height - 1) { - ymax = TheMap.Height - 1; - } - - // FIXME: Must play explosion sound - - // - // Effect of the explosion on units. Don't bother if damage is 0 - // - if (unit->Type->DemolishDamage) { - n = SelectUnits(xmin, ymin, xmax, ymax, table); - for (i = 0; i < n; ++i) { - if (table[i]->Type->UnitType != UnitTypeFly && - table[i]->HP && table[i] != unit && - MapDistanceBetweenUnits(unit, table[i]) <= - unit->Type->DemolishRange) { - // Don't hit flying units! - HitUnit(unit, table[i], unit->Type->DemolishDamage); - } - } - } - - // - // Terrain effect of the explosion - // - for (ix = xmin; ix <= xmax; ++ix) { - for (iy = ymin; iy <= ymax; ++iy) { - n = TheMap.Fields[ix + iy * TheMap.Width].Flags; - if (MapDistanceToUnit(ix, iy, unit) > - unit->Type->DemolishRange) { - // Not in circle range - continue; - } else if (n & MapFieldWall) { - MapRemoveWall(ix, iy); - } else if (n & MapFieldRocks) { - MapRemoveRock(ix, iy); - } else if (n & MapFieldForest) { - MapRemoveWood(ix, iy); - } - } - } - } - LetUnitDie(unit); -#ifdef HIERARCHIC_PATHFINDER - PfHierMapChangedCallback (xmin, ymin, xmax, ymax); -#endif - break; - } -} - -//@} diff --git a/src/action/action_spellcast.cpp b/src/action/action_spellcast.cpp index c7277363c..72615f21c 100644 --- a/src/action/action_spellcast.cpp +++ b/src/action/action_spellcast.cpp @@ -95,6 +95,7 @@ global void AnimateActionSpellCast(Unit* unit) */ local void SpellMoveToTarget(Unit* unit) { + SpellType* spell; Unit* goal; int err; @@ -139,17 +140,29 @@ local void SpellMoveToTarget(Unit* unit) unit->SubAction++; // cast the spell return; } else if (err) { - // goal/spot out of range -- move to target - unit->Orders[0].Action = UnitActionStill; - unit->State = unit->SubAction = 0; + // + // Target self-> we don't really have to get in range, + // just as close as possible, since the spell is centered + // on the caster anyway. + // + if ((spell = unit->Orders[0].Arg1)->Target == TargetSelf) { + DebugLevel0Fn("Increase range for spellcast."); + unit->Orders->Range++; + } else { + // + // goal/spot out of range -- give up + // + unit->Orders[0].Action = UnitActionStill; + unit->State = unit->SubAction = 0; - if (unit->Orders[0].Goal) { // Release references - RefsDebugCheck(!unit->Orders[0].Goal->Refs); - if (!--unit->Orders[0].Goal->Refs) { - RefsDebugCheck(!unit->Orders[0].Goal->Destroyed); - ReleaseUnit(unit->Orders[0].Goal); + if (unit->Orders[0].Goal) { // Release references + RefsDebugCheck(!unit->Orders[0].Goal->Refs); + if (!--unit->Orders[0].Goal->Refs) { + RefsDebugCheck(!unit->Orders[0].Goal->Destroyed); + ReleaseUnit(unit->Orders[0].Goal); + } + unit->Orders[0].Goal = NoUnitP; } - unit->Orders[0].Goal = NoUnitP; } } DebugCheck(unit->Type->Vanishes || unit->Destroyed); diff --git a/src/action/actions.cpp b/src/action/actions.cpp index 8ac05165a..40f804b15 100644 --- a/src/action/actions.cpp +++ b/src/action/actions.cpp @@ -177,7 +177,7 @@ local void (*HandleActionTable[256])(Unit*) = { HandleActionRepair, HandleActionResource, HandleActionReturnGoods, - HandleActionDemolish, + HandleActionNotWritten, HandleActionNotWritten, // Enough for the future ? diff --git a/src/action/command.cpp b/src/action/command.cpp index 29f29312f..b082ee083 100644 --- a/src/action/command.cpp +++ b/src/action/command.cpp @@ -1159,74 +1159,6 @@ global void CommandCancelResearch(Unit* unit) ClearSavedAction(unit); } -/** -** Demolish at position -** -** @param unit pointer to unit. -** @param x X map position to move to. -** @param y Y map position to move to. -** @param dest if != NULL, pointer to unit to destroy. -** @param flush if true, flush command queue. -*/ -global void CommandDemolish(Unit* unit, int x, int y, Unit* dest, int flush) -{ - Order* order; - -#ifdef DEBUG - if (x < 0 || y < 0 || x >= TheMap.Width || y >= TheMap.Height) { - DebugLevel0Fn("Internal movement error\n"); - return; - } -#endif - - // - // Check if unit is still valid? (NETWORK!) - // - if (!unit->Removed && unit->Orders[0].Action != UnitActionDie) { - if (unit->Type->Building) { - // FIXME: should find a better way for pending orders. - order = &unit->NewOrder; - ReleaseOrder(order); - } else if (!(order = GetNextOrder(unit, flush))) { - return; - } - - order->Action = UnitActionDemolish; - if (dest) { - // - // Destination could be killed. - // Should be handled in action, but is not possible! - // Unit::Refs is used as timeout counter. - // - if (dest->Destroyed) { - order->X = dest->X + dest->Type->TileWidth / 2; - order->Y = dest->Y + dest->Type->TileHeight / 2; - order->Goal = NoUnitP; - order->Range = 0; - } else { - order->X = order->Y = -1; - order->Goal = dest; - RefsDebugCheck(!dest->Refs); - dest->Refs++; - order->Range = 1; - } - } else if (WallOnMap(x,y) || ForestOnMap(x,y) || RockOnMap(x,y)) { - order->X = x; - order->Y = y; - order->Range = 1; - order->Goal = NoUnitP; - } else { - order->X = x; - order->Y = y; - order->Range = 0; - order->Goal = NoUnitP; - } - order->Type = NULL; - order->Arg1 = NULL; - } - ClearSavedAction(unit); -} - /** ** Cast a spell at position or unit. ** diff --git a/src/include/actions.h b/src/include/actions.h index 3a7b223ee..0a46c3849 100644 --- a/src/include/actions.h +++ b/src/include/actions.h @@ -121,8 +121,6 @@ extern void CommandResearch(Unit* unit,Upgrade* what,int flush); extern void CommandCancelResearch(Unit* unit); /// Prepare command upgrade //extern void CommandUpgradeUnit(Unit* unit,int what,int flush); - /// Prepare command demolish -extern void CommandDemolish(Unit* unit,int x,int y,Unit* dest,int flush); /// Prepare command spellcast extern void CommandSpellCast(Unit* unit,int x,int y,Unit* dest ,SpellType* spell,int flush); @@ -179,8 +177,6 @@ extern void HandleActionUpgradeTo(Unit* unit); extern void HandleActionUpgrade(Unit* unit); /// Handle command research extern void HandleActionResearch(Unit* unit); - /// Handle command demolish -extern void HandleActionDemolish(Unit* unit); /// Handle command spellcast extern void HandleActionSpellCast(Unit* unit); diff --git a/src/include/commands.h b/src/include/commands.h index 868717ae6..c59b0176c 100644 --- a/src/include/commands.h +++ b/src/include/commands.h @@ -116,8 +116,6 @@ extern void SendCommandCancelUpgradeTo(Unit* unit); extern void SendCommandResearch(Unit* unit,Upgrade* what,int flush); /// Send cancel research command extern void SendCommandCancelResearch(Unit* unit); - /// Send demolish command -extern void SendCommandDemolish(Unit* unit,int x,int y,Unit* dest,int flush); /// Send spell cast command extern void SendCommandSpellCast(Unit* unit,int x,int y,Unit* dest,int spellid ,int flush); diff --git a/src/include/interface.h b/src/include/interface.h index f4f90b4b4..d600afb1e 100644 --- a/src/include/interface.h +++ b/src/include/interface.h @@ -47,16 +47,15 @@ /// Button Commands that need target selection enum _button_cmd_ { - ButtonMove, /// order move - ButtonAttack, /// order attack - ButtonRepair, /// order repair - ButtonHarvest, /// order harvest - ButtonBuild, /// order build - ButtonPatrol, /// order patrol - ButtonAttackGround, /// order attack ground - ButtonSpellCast, /// order cast spell - ButtonUnload, /// order unload unit - ButtonDemolish, /// order demolish/explode + ButtonMove, /// order move + ButtonAttack, /// order attack + ButtonRepair, /// order repair + ButtonHarvest, /// order harvest + ButtonBuild, /// order build + ButtonPatrol, /// order patrol + ButtonAttackGround, /// order attack ground + ButtonSpellCast, /// order cast spell + ButtonUnload, /// order unload unit ButtonStop, /// order stop ButtonButton, /// choose other button set ButtonTrain, /// order train diff --git a/src/include/network.h b/src/include/network.h index c36d6fae2..0f4e356d1 100644 --- a/src/include/network.h +++ b/src/include/network.h @@ -93,7 +93,6 @@ enum _message_type_ { MessageCommandCancelUpgrade, /// Unit command cancel upgrade MessageCommandResearch, /// Unit command research MessageCommandCancelResearch, /// Unit command cancel research - MessageCommandDemolish, /// Unit command demolish MessageExtendedCommand, /// Command is the next byte diff --git a/src/include/unit.h b/src/include/unit.h index 0f39bcc0f..56873fa74 100644 --- a/src/include/unit.h +++ b/src/include/unit.h @@ -421,9 +421,7 @@ enum _unit_action_ { UnitActionRepair, /// unit repairing UnitActionResource, /// unit harvesting resources - UnitActionReturnGoods, /// unit returning any resource - - UnitActionDemolish, /// unit demolish at position/unit + UnitActionReturnGoods /// unit returning any resource }; /** diff --git a/src/include/unittype.h b/src/include/unittype.h index 4204a1d40..2ac9c1769 100644 --- a/src/include/unittype.h +++ b/src/include/unittype.h @@ -257,17 +257,6 @@ ** ** How many points you get for unit. Used in the final score table. ** -** UnitType::DemolishRange -** -** If non-zero This is the range for units that can demolish. -** The demolished area is a square, sorry. -** -** UnitType::DemolishDamage -** -** Damage dealt to unit affected by demolition. This can be 0, -** in this case only terrain will be affected. Units have to be in -** DemolishRange to be affected. -** ** UnitType::CanTarget ** ** Which units can it attack @@ -712,8 +701,6 @@ struct _unit_type_ { int _BasicDamage; /// Basic damage dealt int _PiercingDamage; /// Piercing damage dealt int _RegenerationRate; /// HP regeneration HP per sec - int DemolishRange; /// Unit will Demolish around when dead. - int DemolishDamage; /// Damage dealt to unit affected by demolition. int RepairRange; /// Units repair range. char *CanCastSpell; /// Unit is able to use spells. // FIXME: n0body: AutoBuildRate not implemented. @@ -735,7 +722,7 @@ struct _unit_type_ { #define MouseActionAttack 1 /// Attack #define MouseActionMove 2 /// Move #define MouseActionHarvest 3 /// Harvest resources -#define MouseActionDemolish 5 /// Demolish +#define MouseActionSpellCast 5 /// Cast the first spell known #define MouseActionSail 6 /// Sail int Points; /// How many points you get for unit int CanTarget; /// Which units can it attack diff --git a/src/network/commands.cpp b/src/network/commands.cpp index ae7c5a98e..332f7faac 100644 --- a/src/network/commands.cpp +++ b/src/network/commands.cpp @@ -577,8 +577,6 @@ local void DoNextReplay(void) SendCommandResearch(UnitSlots[unit],UpgradeByIdent(val), flags); } else if (!strcmp(name, "cancel-research")) { SendCommandCancelResearch(UnitSlots[unit]); - } else if (!strcmp(name, "demolish")) { - SendCommandDemolish(UnitSlots[unit], posx, posy, dunit, flags); } else if (!strcmp(name, "spell-cast")) { SendCommandSpellCast(UnitSlots[unit], posx, posy, dunit, num, flags); } else if (!strcmp(name, "auto-spell-cast")) { @@ -1055,25 +1053,6 @@ global void SendCommandCancelResearch(Unit* unit) } } -/** -** Send command: Unit demolish at position. -** -** @param unit pointer to unit. -** @param x X map tile position where to demolish. -** @param y Y map tile position where to demolish. -** @param attack or !=NoUnitP unit to be demolished. -** @param flush Flag flush all pending commands. -*/ -global void SendCommandDemolish(Unit* unit, int x, int y, Unit* attack, int flush) -{ - if (NetworkFildes == (Socket)-1) { - CommandLog("demolish", unit, flush, x, y, attack, NULL, -1); - CommandDemolish(unit, x, y, attack, flush); - } else { - NetworkSendCommand(MessageCommandDemolish, unit, x, y, attack, NULL, flush); - } -} - /** ** Send command: Unit spell cast on position/unit. ** @@ -1365,15 +1344,6 @@ global void ParseCommand(unsigned char msgnr, UnitRef unum, NULL, -1); CommandCancelResearch(unit); break; - case MessageCommandDemolish: - dest = NoUnitP; - if (dstnr != (unsigned short)0xFFFF) { - dest = UnitSlots[dstnr]; - DebugCheck(!dest || !dest->Type); - } - CommandLog("demolish", unit, status, x, y, dest, NULL, -1); - CommandDemolish(unit, x, y, dest, status); - break; default: id = (msgnr&0x7f) - MessageCommandSpellCast; if (y != (unsigned short)0xFFFF) { diff --git a/src/stratagus/selection.cpp b/src/stratagus/selection.cpp index f1c6897b6..cae2ce25a 100644 --- a/src/stratagus/selection.cpp +++ b/src/stratagus/selection.cpp @@ -104,7 +104,7 @@ local void HandleSuicideClick(Unit* unit) // FIXME: make this configurable if (unit->Value == unit->Type->ClicksToExplode) { - SendCommandDemolish(unit, unit->X, unit->Y, 0, FlushCommands); + LetUnitDie(unit); unit->Value = 0; } } diff --git a/src/stratagus/spells.cpp b/src/stratagus/spells.cpp index 4ceb94540..802dc7afe 100644 --- a/src/stratagus/spells.cpp +++ b/src/stratagus/spells.cpp @@ -109,10 +109,13 @@ global int CastDemolish(Unit* caster, const SpellType* spell __attribute__((unus int n; Unit* table[UnitMax]; - xmin = x - action->Data.Demolish.Range; - ymin = y - action->Data.Demolish.Range; - xmax = x + action->Data.Demolish.Range; - ymax = y + action->Data.Demolish.Range; + // + // Allow error margnins. (Lame, I know) + // + xmin = x - action->Data.Demolish.Range - 2; + ymin = y - action->Data.Demolish.Range - 2; + xmax = x + action->Data.Demolish.Range + 2; + ymax = y + action->Data.Demolish.Range + 2; if (xmin < 0) { xmin = 0; } @@ -130,9 +133,9 @@ global int CastDemolish(Unit* caster, const SpellType* spell __attribute__((unus // Effect of the explosion on units. Don't bother if damage is 0 // if (action->Data.Demolish.Damage) { - n = SelectUnits(xmin, ymin, xmax+1, ymax+1, table); + n = SelectUnits(xmin, ymin, xmax, ymax, table); for (i = 0; i < n; ++i) { - DebugLevel0("Hit an unit at %d %d?\n" _C_ table[i]->X _C_ table[i]->Y); + DebugLevel3("Hit an unit at %d %d?\n" _C_ table[i]->X _C_ table[i]->Y); if (table[i]->Type->UnitType != UnitTypeFly && table[i]->HP && MapDistanceToUnit(x, y, table[i]) <= action->Data.Demolish.Range) { // Don't hit flying units! @@ -1137,6 +1140,14 @@ global int SpellCast(Unit* caster, const SpellType* spell, Unit* target, x += spell->Range; // Why ?? y += spell->Range; // Why ?? } + // + // For TargetSelf, you target.... YOURSELF + // + if (spell->Target==TargetSelf) { + x=caster->X; + y=caster->Y; + target=caster; + } DebugLevel3Fn("Spell cast: (%s), %s -> %s (%d,%d)\n" _C_ spell->IdentName _C_ unit->Type->Name _C_ target ? target->Type->Name : "none" _C_ x _C_ y); if (CanCastSpell(caster, spell, target, x, y)) { diff --git a/src/ui/botpanel.cpp b/src/ui/botpanel.cpp index 46fd31f65..6a722f0d2 100644 --- a/src/ui/botpanel.cpp +++ b/src/ui/botpanel.cpp @@ -135,8 +135,6 @@ global void SaveButtons(CLFile* file) CLprintf(file, "'attack-ground"); break; case ButtonReturn: CLprintf(file, "'return-goods"); break; - case ButtonDemolish: - CLprintf(file, "'demolish"); break; case ButtonSpellCast: CLprintf(file, "'cast-spell"); break; case ButtonResearch: @@ -431,9 +429,6 @@ global void DrawButtonPanel(void) case ButtonAttack: action = UnitActionAttack; break; - case ButtonDemolish: - action = UnitActionDemolish; - break; case ButtonAttackGround: action = UnitActionAttackGround; break; @@ -616,13 +611,6 @@ local void UpdateButtonPanelMultipleUnits(void) break; } } - } else if (UnitButtonTable[z]->Action == ButtonDemolish) { - for (i = NumSelected; --i;) { - if (Selected[i]->Type->Volatile) { - allow = 1; - break; - } - } } else if (UnitButtonTable[z]->Action == ButtonCancel) { allow = 1; } else if (UnitButtonTable[z]->Action == ButtonCancelUpgrade) { @@ -784,11 +772,6 @@ global void UpdateButtonPanel(void) allow = 1; } break; - case ButtonDemolish: - if (Selected[0]->Type->Volatile) { - allow = 1; - } - break; case ButtonTrain: // Check if building queue is enabled if (!EnableTrainingQueue && @@ -890,7 +873,6 @@ global void DoButtonButtonClicked(int button) case ButtonAttack: case ButtonRepair: case ButtonAttackGround: - case ButtonDemolish: case ButtonSpellCast: if (CurrentButtons[button].Action == ButtonSpellCast && (KeyModifiers & ModifierControl)) { diff --git a/src/ui/mainscr.cpp b/src/ui/mainscr.cpp index 3b48e5f26..76b0d78fb 100644 --- a/src/ui/mainscr.cpp +++ b/src/ui/mainscr.cpp @@ -527,7 +527,10 @@ global void DrawUnitInfo(const Unit* unit) } } - if (type->CanCastSpell) { + // + // Unit can cast spell without mana, so only show mana bar for units with mana + // + if (type->_MaxMana) { if (0) { VideoDrawText(x + 59, y + 8 + 140 + 1, GameFont, "Magic:"); VideoDrawRectangleClip(ColorGray, x + 108, y + 8 + 140, 61, 14); diff --git a/src/ui/mouse.cpp b/src/ui/mouse.cpp index fe14d7a78..d24a7fc56 100644 --- a/src/ui/mouse.cpp +++ b/src/ui/mouse.cpp @@ -56,6 +56,7 @@ #include "sound.h" #include "ui.h" #include "network.h" +#include "spells.h" /*---------------------------------------------------------------------------- -- Variables @@ -110,6 +111,7 @@ global void DoRightButton(int sx, int sy) int acknowledged; int flush; int res; + int spellnum; // // No unit selected @@ -259,13 +261,17 @@ global void DoRightButton(int sx, int sy) // // Fighters // - if (action == MouseActionDemolish || action == MouseActionAttack) { + if (action == MouseActionSpellCast || action == MouseActionAttack) { if (dest) { if (IsEnemy(unit->Player, dest)) { dest->Blink = 4; - if (action == MouseActionDemolish) { + if (action == MouseActionSpellCast) { // This is for demolition squads and such - SendCommandDemolish(unit, x, y, dest, flush); + DebugCheck(!unit->Type->CanCastSpell); + for (spellnum=0; !unit->Type->CanCastSpell[spellnum] && + spellnum < SpellTypeCount ; spellnum++) ; + DebugCheck(spellnum == SpellTypeCount); + SendCommandSpellCast(unit, x, y, dest, spellnum, flush); } else { SendCommandAttack(unit, x, y, dest, flush); } @@ -945,39 +951,6 @@ local void SendPatrol(int sx, int sy) } } -/** -** Let a unit explode at selected point -** -** @param sx X screen map position -** @param sy Y screen map position -*/ -local void SendDemolish(int sx, int sy) -{ - int i; - Unit* unit; - Unit* dest; - int x; - int y; - - x = sx / TileSizeX; - y = sy / TileSizeY; - for (i = 0; i < NumSelected; ++i) { - unit = Selected[i]; - if (unit->Type->Volatile) { - // FIXME: choose correct unit no flying ... - if ((dest = UnitUnderCursor) && CanTarget(unit->Type, dest->Type)) { - dest->Blink = 4; - } else { - dest = NoUnitP; - } - SendCommandDemolish(unit, sx / TileSizeX, sy / TileSizeY, dest, - !(KeyModifiers & ModifierShift)); - } else { - DebugLevel0Fn("can't demolish %p\n" _C_ unit); - } - } -} - /** ** Let units harvest wood/mine gold/haul oil ** @@ -1119,9 +1092,6 @@ local void SendCommand(int sx, int sy) case ButtonUnload: SendUnload(sx, sy); break; - case ButtonDemolish: - SendDemolish(sx, sy); - break; case ButtonSpellCast: SendSpellCast(sx, sy); break; diff --git a/src/ui/script_ui.cpp b/src/ui/script_ui.cpp index a3e05b6f8..67bc927e2 100644 --- a/src/ui/script_ui.cpp +++ b/src/ui/script_ui.cpp @@ -2785,8 +2785,6 @@ local SCM CclDefineButton(SCM list) ba.Action = ButtonAttackGround; } else if (gh_eq_p(value, gh_symbol2scm("return-goods"))) { ba.Action = ButtonReturn; - } else if (gh_eq_p(value, gh_symbol2scm("demolish"))) { - ba.Action = ButtonDemolish; } else if (gh_eq_p(value, gh_symbol2scm("cast-spell"))) { ba.Action = ButtonSpellCast; } else if (gh_eq_p(value, gh_symbol2scm("research"))) { diff --git a/src/unit/script_unit.cpp b/src/unit/script_unit.cpp index 9b38fe5f2..46f59a052 100644 --- a/src/unit/script_unit.cpp +++ b/src/unit/script_unit.cpp @@ -215,8 +215,6 @@ local void CclParseOrder(SCM list,Order* order) order->Action = UnitActionResource; } else if (gh_eq_p(value, gh_symbol2scm("action-return-goods"))) { order->Action = UnitActionReturnGoods; - } else if (gh_eq_p(value, gh_symbol2scm("action-demolish"))) { - order->Action = UnitActionDemolish; } else if (gh_eq_p(value, gh_symbol2scm("flags"))) { value = gh_car(list); diff --git a/src/unit/script_unittype.cpp b/src/unit/script_unittype.cpp index 8b562f9e3..c33d7bb6c 100644 --- a/src/unit/script_unittype.cpp +++ b/src/unit/script_unittype.cpp @@ -364,8 +364,8 @@ local SCM CclDefineUnitType(SCM list) type->MouseAction = MouseActionMove; } else if (gh_eq_p(value, gh_symbol2scm("right-harvest"))) { type->MouseAction = MouseActionHarvest; - } else if (gh_eq_p(value, gh_symbol2scm("right-demolish"))) { - type->MouseAction = MouseActionDemolish; + } else if (gh_eq_p(value, gh_symbol2scm("right-spell-cast"))) { + type->MouseAction = MouseActionSpellCast; } else if (gh_eq_p(value, gh_symbol2scm("right-sail"))) { type->MouseAction = MouseActionSail; @@ -373,12 +373,6 @@ local SCM CclDefineUnitType(SCM list) type->GroundAttack = 1; } else if (gh_eq_p(value, gh_symbol2scm("can-attack"))) { type->CanAttack = 1; - } else if (gh_eq_p(value, gh_symbol2scm("demolish-range"))){ - type->DemolishRange = gh_scm2int(gh_car(list)); - list = gh_cdr(list); - } else if (gh_eq_p(value, gh_symbol2scm("demolish-damage"))){ - type->DemolishDamage = gh_scm2int(gh_car(list)); - list = gh_cdr(list); } else if (gh_eq_p(value, gh_symbol2scm("repair-range"))) { type->RepairRange = gh_scm2int(gh_car(list)); list = gh_cdr(list); @@ -595,14 +589,6 @@ local SCM CclDefineUnitType(SCM list) } } - // - // Unit type checks. - // - if (type->CanCastSpell && !type->_MaxMana) { - DebugLevel0Fn("%s: Need max mana value\n" _C_ type->Ident); - type->_MaxMana = 1; - } - return SCM_UNSPECIFIED; } diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp index 2e85eb42e..b9c71a940 100644 --- a/src/unit/unit.cpp +++ b/src/unit/unit.cpp @@ -3424,10 +3424,6 @@ local void SaveOrder(const Order* order, CLFile* file) CLprintf(file, "action-return-goods"); break; - case UnitActionDemolish: - CLprintf(file, "action-demolish"); - break; - default: DebugLevel0Fn("Unknown action in order\n"); } diff --git a/src/unit/unit_draw.cpp b/src/unit/unit_draw.cpp index db767dd14..d676b2c92 100644 --- a/src/unit/unit_draw.cpp +++ b/src/unit/unit_draw.cpp @@ -1485,11 +1485,6 @@ local void ShowSingleOrder(const Unit* unit, int x1, int y1, const Order* order) dest = 1; break; - case UnitActionDemolish: - e_color = color = ColorRed; - dest = 1; - break; - default: e_color = color = ColorGray; DebugLevel1Fn("Unknown action %d\n" _C_ order->Action); diff --git a/src/unit/unittype.cpp b/src/unit/unittype.cpp index 510d9f0c1..e90b169dc 100644 --- a/src/unit/unittype.cpp +++ b/src/unit/unittype.cpp @@ -507,13 +507,6 @@ global void ParsePudUDTA(const char* udta, int length __attribute__((unused))) if (BIT(31, v)) DebugLevel0("Unused bit 31 used in %d\n" _C_ i); #endif #undef BIT - // - // Unit type checks. - // - if (unittype->CanCastSpell && !unittype->_MaxMana) { - DebugLevel0Fn("%s: Need max mana value\n" _C_ unittype->Ident); - unittype->_MaxMana = 255; - } } // FIXME: peon applies also to peon-with-gold and peon-with-wood @@ -851,8 +844,8 @@ local void SaveUnitType(CLFile* file, const UnitType* type, int all) case MouseActionHarvest: CLprintf(file, "'right-harvest"); break; - case MouseActionDemolish: - CLprintf(file, "'right-demolish"); + case MouseActionSpellCast: + CLprintf(file, "'right-spell-cast"); break; case MouseActionSail: CLprintf(file, "'right-sail"); @@ -872,12 +865,6 @@ local void SaveUnitType(CLFile* file, const UnitType* type, int all) if (type->RepairRange) { CLprintf(file, " 'repair-range %d\n", type->RepairRange); } - if (type->DemolishRange) { - CLprintf(file, " 'demolish-range %d\n", type->DemolishRange); - } - if (type->DemolishRange) { - CLprintf(file, " 'demolish-damage %d\n", type->DemolishDamage); - } if (type->CanTarget) { CLprintf(file, " "); if (type->CanTarget & CanTargetLand) { @@ -1242,6 +1229,8 @@ global UnitType* NewUnitTypeSlot(char* ident) } memset(type, 0, sizeof(UnitType)); type->Type = NumUnitTypes; + DebugLevel3Fn("Making a new unit, called %s, branded %d\n" + _C_ ident _C_ type->Type); type->Ident = ident; UnitTypes[NumUnitTypes++] = type; // diff --git a/src/unit/upgrade.cpp b/src/unit/upgrade.cpp index 44a99456f..b0e61c435 100644 --- a/src/unit/upgrade.cpp +++ b/src/unit/upgrade.cpp @@ -1265,7 +1265,7 @@ local void ConvertUnitTypeTo(Player* player, const UnitType* src, UnitType* dst) unit->Type = dst; unit->Stats = &dst->Stats[player->Player]; // and we have new one... - player->UnitTypesCount[dst->Type]++; + UpdateForNewUnit(unit, 1); if (dst->CanCastSpell) { unit->Mana = MAGIC_FOR_NEW_UNITS;