diff --git a/scripts/tests/e2/init.lua b/scripts/tests/e2/init.lua
index 32199b257..e7a4c9020 100644
--- a/scripts/tests/e2/init.lua
+++ b/scripts/tests/e2/init.lua
@@ -4,6 +4,7 @@ require 'tests.e2.e2features'
require 'tests.e2.movement'
require 'tests.e2.destroy'
require 'tests.e2.guard'
+require 'tests.e2.spells'
require 'tests.e2.stealth'
require 'tests.orders'
require 'tests.common'
diff --git a/scripts/tests/e2/spells.lua b/scripts/tests/e2/spells.lua
new file mode 100644
index 000000000..2eb54c406
--- /dev/null
+++ b/scripts/tests/e2/spells.lua
@@ -0,0 +1,28 @@
+require "lunit"
+
+module("tests.e2.spells", package.seeall, lunit.testcase)
+
+function setup()
+ eressea.free_game()
+ eressea.settings.set("nmr.removenewbie", "0")
+ eressea.settings.set("nmr.timeout", "0")
+ eressea.settings.set("NewbieImmunity", "0")
+ eressea.settings.set("rules.economy.food", "4")
+end
+
+function test_shapeshift()
+ local r = region.create(42, 0, "plain")
+ local f = faction.create("noreply@eressea.de", "demon", "de")
+ local u1 = unit.create(f, r, 1)
+ local u2 = unit.create(f, r, 1)
+ u1:clear_orders()
+ u1.magic = "gray"
+ u1:set_skill("magic", 2)
+ u1.aura = 1
+ u1:add_spell("shapeshift")
+ u1:add_order("ZAUBERE STUFE 1 Gestaltwandlung " .. itoa36(u2.id) .. " Goblin")
+ process_orders()
+ assert_equal(f.race, u2.race)
+ s = u2:show()
+ assert_equal("1 Goblin", string.sub(s, string.find(s, "1 Goblin")))
+end
diff --git a/se/eressea.vpj b/se/eressea.vpj
index 78271d8af..f301fc66d 100644
--- a/se/eressea.vpj
+++ b/se/eressea.vpj
@@ -513,7 +513,6 @@
-
diff --git a/src/battle.c b/src/battle.c
index d45cf02e7..672baaf71 100644
--- a/src/battle.c
+++ b/src/battle.c
@@ -1852,7 +1852,7 @@ static void do_combatspell(troop at)
log_error("spell '%s' has no function.\n", sp->sname);
}
else {
- level = cast_combatspell(at, sp, level, power);
+ level = cast_combatspell(at, sp, level, MagicPower(power));
}
}
@@ -1869,9 +1869,8 @@ static void do_extra_spell(troop at, const att * a)
log_error("spell '%s' has no function.\n", sp->sname);
}
else {
- double force = a->level * MagicPower();
assert(a->level > 0);
- cast_combatspell(at, sp, a->level, force);
+ cast_combatspell(at, sp, a->level, MagicPower(a->level));
}
}
diff --git a/src/bind_unit.c b/src/bind_unit.c
index 59f2ad13c..94bd34e77 100755
--- a/src/bind_unit.c
+++ b/src/bind_unit.c
@@ -17,6 +17,7 @@ without prior permission by the authors of Eressea.
#include "alchemy.h"
#include "bindings.h"
#include "move.h"
+#include "reports.h"
/* attributes includes */
#include
@@ -54,6 +55,17 @@ without prior permission by the authors of Eressea.
#include
#include
+static int tolua_bufunit(lua_State * L) {
+ char buf[8192];
+ unit *self = (unit *)tolua_tousertype(L, 1, 0);
+ int mode = (int)tolua_tonumber(L, 2, see_unit);
+ if (!self) return 0;
+
+ bufunit(self->faction, self, 0, mode, buf, sizeof(buf));
+ tolua_pushstring(L, buf);
+ return 1;
+
+}
static int tolua_unit_get_objects(lua_State * L)
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
@@ -513,7 +525,7 @@ static void unit_castspell(unit * u, const char *name, int level)
}
else {
castorder co;
- create_castorder(&co, u, 0, sp, u->region, level, level * MagicPower(), 0, 0, 0);
+ create_castorder(&co, u, 0, sp, u->region, level, MagicPower((float)level), 0, 0, 0);
sp->cast(&co);
free_castorder(&co);
}
@@ -1034,6 +1046,7 @@ void tolua_unit_open(lua_State * L)
tolua_variable(L, TOLUA_CAST "hp_max", &tolua_unit_get_hpmax, 0);
tolua_variable(L, TOLUA_CAST "objects", &tolua_unit_get_objects, 0);
+ tolua_function(L, TOLUA_CAST "show", &tolua_bufunit);
}
tolua_endmodule(L);
}
diff --git a/src/kernel/race.h b/src/kernel/race.h
index b9c541aa1..b087825a6 100644
--- a/src/kernel/race.h
+++ b/src/kernel/race.h
@@ -120,7 +120,6 @@ extern "C" {
extern int num_races;
typedef struct race {
- struct param *parameters;
char *_name;
float magres;
double maxaura; /* Faktor auf Maximale Aura */
@@ -141,6 +140,7 @@ extern "C" {
int df_default; /* Verteidigungsskill Unbewaffnet (default: -2) */
int at_bonus; /* Verändert den Angriffsskill (default: 0) */
int df_bonus; /* Verändert den Verteidigungskill (default: 0) */
+ struct param *parameters; // additional properties, for an example see natural_armor
const struct spell *precombatspell;
signed char *study_speed; /* study-speed-bonus in points/turn (0=30 Tage) */
int flags;
diff --git a/src/kernel/spellid.h b/src/kernel/spellid.h
deleted file mode 100644
index 387c592db..000000000
--- a/src/kernel/spellid.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
-* +-------------------+ Christian Schlittchen
-* | | Enno Rehling
-* | Eressea PBEM host | Katja Zedel
-* | (c) 1998 - 2005 |
-* | | This program may not be used, modified or distributed
-* +-------------------+ without prior permission by the authors of Eressea.
-*
-*/
-
-#ifndef H_KRNL_SPELLID
-#define H_KRNL_SPELLID
-
-/* Sprüche. Neue NUR hinten anfügen, oder das Datenfile geht kaputt */
-enum {
- SPL_NOSPELL = 0,
- SPL_FIREBALL = 4,
- SPL_HAGEL,
- SPL_RUSTWEAPON,
- SPL_COMBATRUST,
- SPL_TREEGROW,
- SPL_HEALING,
- SPL_HEALINGSONG,
- SPL_BADDREAMS,
- SPL_GOODDREAMS,
- SPL_DREAMREADING,
- SPL_SWEETDREAMS,
- SPL_TIREDSOLDIERS,
- SPL_PLAGUE,
- SPL_MAGICBOOST,
- SPL_CHAOSROW,
- SPL_SONG_OF_CONFUSION,
- SPL_FLEE,
- SPL_SONG_OF_FEAR,
- SPL_BERSERK,
- SPL_BLOODTHIRST,
- SPL_MAELSTROM,
- SPL_TRANSFERAURA_DRUIDE = 27,
- SPL_TRANSFERAURA_BARDE,
- SPL_TRANSFERAURA_CHAOS,
- SPL_TRANSFERAURA_TRAUM,
- SPL_TRANSFERAURA_ASTRAL,
- SPL_STONEGOLEM,
- SPL_IRONGOLEM,
- SPL_SUMMONSHADOW,
- SPL_SUMMONSHADOWLORDS,
- SPL_REELING_ARROWS,
- SPL_ANTIMAGICZONE = 37,
- SPL_KAELTESCHUTZ = 39,
- SPL_STEALAURA,
- SPL_SUMMONUNDEAD,
- SPL_AURALEAK,
- SPL_GREAT_DROUGHT,
- SPL_STRONG_WALL,
- SPL_HOMESTONE,
- SPL_DROUGHT,
- SPL_FOREST_FIRE = 47,
- SPL_SUMMONENT = 49,
- SPL_DISTURBINGDREAMS,
- SPL_DENYATTACK,
- SPL_SLEEP,
- SPL_EARTHQUAKE,
- SPL_IRONKEEPER,
- SPL_STORMWINDS,
- SPL_GOODWINDS,
- SPL_FLYING_SHIP,
- SPL_SUMMON_ALP,
- SPL_WINDSHIELD,
- SPL_RAISEPEASANTS,
- SPL_DEPRESSION,
- SPL_HEADACHE = 62,
- SPL_ENTERASTRAL = 64,
- SPL_LEAVEASTRAL,
- SPL_SHOWASTRAL,
- SPL_VERSTEINERN,
- SPL_TREEWALKENTER,
- SPL_TREEWALKEXIT,
- SPL_CHAOSSUCTION,
- SPL_VIEWREALITY,
- SPL_DISRUPTASTRAL,
- SPL_SEDUCE,
- SPL_PUMP,
- SPL_CALM_MONSTER,
- SPL_HERO,
- SPL_FRIGHTEN,
- SPL_MINDBLAST,
- SPL_SPEED,
- SPL_SPEED2,
- SPL_FIREDRAGONODEM,
- SPL_DRAGONODEM,
- SPL_WYRMODEM, /* 83 */
- SPL_MAGICSTREET,
- SPL_REANIMATE,
- SPL_RECRUIT,
- SPL_GENEROUS,
- SPL_PERMTRANSFER,
- SPL_SONG_OF_PEACE,
- SPL_MIGRANT,
- SPL_RALLYPEASANTMOB,
- SPL_RAISEPEASANTMOB,
- SPL_ILL_SHAPESHIFT,
- SPL_WOLFHOWL,
- SPL_FOG_OF_CONFUSION,
- SPL_DREAM_OF_CONFUSION,
- SPL_RESISTMAGICBONUS,
- SPL_KEEPLOOT,
- SPL_SCHILDRUNEN,
- SPL_SONG_RESISTMAGIC,
- SPL_SONG_SUSCEPTMAGIC,
- SPL_ANALYSEMAGIC,
- SPL_ANALYSEDREAM,
- SPL_UNIT_ANALYSESONG,
- SPL_OBJ_ANALYSESONG,
- SPL_TYBIED_DESTROY_MAGIC,
- SPL_DESTROY_MAGIC,
- SPL_METEORRAIN,
- SPL_REDUCESHIELD,
- SPL_ARMORSHIELD,
- SPL_DEATHCLOUD,
- SPL_ORKDREAM,
- SPL_SUMMONDRAGON = 113,
- SPL_MOVECASTLE = 116,
- SPL_BLESSSTONECIRCLE,
- SPL_ILLAUN_FAMILIAR,
- SPL_GWYRRD_FAMILIAR,
- SPL_DRAIG_FAMILIAR,
- SPL_CERDDOR_FAMILIAR,
- SPL_TYBIED_FAMILIAR,
- SPL_SONG_OF_ENSLAVE = 123,
- SPL_FUMBLECURSE = 136,
- SPL_ICASTLE,
- SPL_GWYRRD_DESTROY_MAGIC,
- SPL_DRAIG_DESTROY_MAGIC,
- SPL_ILLAUN_DESTROY_MAGIC,
- SPL_CERDDOR_DESTROY_MAGIC,
- SPL_GWYRRD_ARMORSHIELD,
- SPL_DRAIG_FUMBLESHIELD,
- SPL_GWYRRD_FUMBLESHIELD,
- SPL_CERDDOR_FUMBLESHIELD,
- SPL_TYBIED_FUMBLESHIELD,
- SPL_SHADOWKNIGHTS = 147,
- SPL_ITEMCLOAK = 150,
- SPL_FIREWALL,
- SPL_WISPS,
- SPL_SPARKLE_CHAOS,
- SPL_SPARKLE_DREAM = 154,
- SPL_PULLASTRAL = 156,
- SPL_FETCHASTRAL = 157,
- SPL_SHOCKWAVE = 163,
- SPL_UNDEADHERO = 164,
- SPL_BECOMEWYRM = 166,
- SPL_ETERNIZEWALL,
- SPL_PUTTOREST,
- SPL_UNHOLYPOWER,
- SPL_HOLYGROUND,
- SPL_BLOODSACRIFICE,
- SPL_MALLORN,
- SPL_CLONECOPY,
- SPL_DRAINODEM,
- SPL_AURA_OF_FEAR,
- SPL_SHADOWCALL,
- SPL_MALLORNTREEGROW = 177,
- SPL_BIGRECRUIT = 179,
- SPL_IMMOLATION,
- SPL_FIREODEM, /* 181 */
- SPL_ICEODEM,
- SPL_ACIDODEM,
- /* no longer used, but kept for reference: */
- XMLSPL_WDWPYRAMID_TRAUM = 184,
- XMLSPL_WDWPYRAMID_ASTRAL = 185,
- XMLSPL_WDWPYRAMID_DRUIDE = 186,
- XMLSPL_WDWPYRAMID_BARDE = 187,
- XMLSPL_WDWPYRAMID_CHAOS = 188
-};
-
-#endif
diff --git a/src/magic.c b/src/magic.c
index 075880020..3ab5bc3c7 100644
--- a/src/magic.c
+++ b/src/magic.c
@@ -118,14 +118,13 @@ static float MagicRegeneration(void)
return value;
}
-double MagicPower(void)
-{
- static double value = -1.0;
- if (value < 0) {
+double MagicPower(double force) {
+ if (force > 0) {
const char *str = get_param(global.parameters, "magic.power");
- value = str ? atof(str) : 1.0;
+ double value = str ? atof(str) : 1.0;
+ return _max(value * force, 1.0f);
}
- return value;
+ return 0;
}
static int a_readicastle(attrib * a, void *owner, struct storage *store)
@@ -1075,7 +1074,7 @@ spellpower(region * r, unit * u, const spell * sp, int cast_level, struct order
}
}
- force = force * MagicPower();
+ force = MagicPower(force);
return _max(force, 0);
}
diff --git a/src/magic.h b/src/magic.h
index 39d5877e0..ed8ce4bc7 100644
--- a/src/magic.h
+++ b/src/magic.h
@@ -360,7 +360,7 @@ extern "C" {
extern void write_spells(struct quicklist *slist, struct storage *store);
extern void read_spells(struct quicklist **slistp, magic_t mtype,
struct storage *store);
- extern double MagicPower(void);
+ double MagicPower(double force);
extern struct spellbook * get_spellbook(const char * name);
extern void free_spellbooks(void);
diff --git a/src/spells.c b/src/spells.c
index ed6898139..e811967bd 100644
--- a/src/spells.c
+++ b/src/spells.c
@@ -36,7 +36,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -6647,7 +6646,6 @@ static spelldata spell_functions[] = {
{ "firestorm", sp_immolation, 0 },
{ "coldfront", sp_immolation, 0 },
{ "acidrain", sp_immolation, 0 },
- /* SPL_NOSPELL MUSS der letzte Spruch der Liste sein */
{ 0, 0, 0 }
};
diff --git a/src/spells/combatspells.c b/src/spells/combatspells.c
index feed41ef0..26d8d8b6d 100644
--- a/src/spells/combatspells.c
+++ b/src/spells/combatspells.c
@@ -25,7 +25,6 @@
#include
#include
#include
-#include
#include
#include
@@ -47,6 +46,30 @@
#define EFFECT_HEALING_SPELL 5
+// Some spells with a fixed, known ID (in XML).
+// TODO: this method of identifying spells is error-prone, do not use it for new spells.
+enum {
+ SPL_FIREBALL = 4,
+ SPL_HAGEL = 5,
+ SPL_CHAOSROW = 18,
+ SPL_FLEE = 20,
+ SPL_SONG_OF_FEAR = 21,
+ SPL_BERSERK = 22,
+ SPL_BLOODTHIRST = 23,
+ SPL_WINDSHIELD = 59,
+ SPL_HERO = 76,
+ SPL_METEORRAIN = 108,
+ SPL_REDUCESHIELD = 109,
+ SPL_ARMORSHIELD = 110,
+ SPL_DRAIG_FUMBLESHIELD = 143,
+ SPL_GWYRRD_FUMBLESHIELD = 144,
+ SPL_CERDDOR_FUMBLESHIELD = 145,
+ SPL_TYBIED_FUMBLESHIELD = 146,
+ SPL_SHADOWKNIGHTS = 147,
+ SPL_SHOCKWAVE = 163,
+ SPL_AURA_OF_FEAR = 175
+};
+
/* ------------------------------------------------------------------ */
/* Kampfzauberfunktionen */