Demolish action is now a spell.

This commit is contained in:
n0body 2003-10-24 00:58:34 +00:00
parent b702d6b9ef
commit 21058caaf4
27 changed files with 88 additions and 492 deletions

View file

@ -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).

View file

@ -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>

View file

@ -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.

View file

@ -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 \

View file

@ -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;
}
}
//@}

View file

@ -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);

View file

@ -177,7 +177,7 @@ local void (*HandleActionTable[256])(Unit*) = {
HandleActionRepair,
HandleActionResource,
HandleActionReturnGoods,
HandleActionDemolish,
HandleActionNotWritten,
HandleActionNotWritten,
// Enough for the future ?

View file

@ -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.
**

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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
};
/**

View file

@ -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

View file

@ -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) {

View file

@ -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;
}
}

View file

@ -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)) {

View file

@ -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)) {

View file

@ -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);

View file

@ -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;

View file

@ -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"))) {

View file

@ -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);

View file

@ -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;
}

View file

@ -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");
}

View file

@ -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);

View file

@ -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;
//

View file

@ -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;