forked from github/server
Merge branch 'develop' of github.com:ennorehling/eressea into develop
This commit is contained in:
commit
441c5d602d
|
@ -2370,7 +2370,7 @@ msgid "sp_confusion_effect_0"
|
||||||
msgstr "\"$unit($mage) intones a mysterious chant. There is a sudden hubbub, but order is restored quickly.\""
|
msgstr "\"$unit($mage) intones a mysterious chant. There is a sudden hubbub, but order is restored quickly.\""
|
||||||
|
|
||||||
msgid "pest"
|
msgid "pest"
|
||||||
msgstr "\"The region is visited by the plague and $int($dead) $resource($$peasants,$dead) died.\""
|
msgstr "\"The region is visited by the plague and $int($dead) $resource($peasants,$dead) died.\""
|
||||||
|
|
||||||
msgid "wormhole_exit"
|
msgid "wormhole_exit"
|
||||||
msgstr "\"$unit($unit) travels through a wormhole to $region($region).\""
|
msgstr "\"$unit($unit) travels through a wormhole to $region($region).\""
|
||||||
|
|
|
@ -15,16 +15,20 @@ end
|
||||||
|
|
||||||
function test_fetch_astral()
|
function test_fetch_astral()
|
||||||
local r = region.create(0, 0, "plain")
|
local r = region.create(0, 0, "plain")
|
||||||
|
local ra = r:get_astral('fog')
|
||||||
|
local rb = region.create(ra.x + 1, ra.y, 'fog')
|
||||||
local f = faction.create("human")
|
local f = faction.create("human")
|
||||||
local u1 = unit.create(f, r, 1)
|
local u1 = unit.create(f, r, 1)
|
||||||
local u2 = unit.create(f, r, 1)
|
local u2 = unit.create(f, r, 1)
|
||||||
|
local u3 = unit.create(f, rb, 1)
|
||||||
|
rb.plane = ra.plane
|
||||||
u1.magic = "gray"
|
u1.magic = "gray"
|
||||||
u1:set_skill("magic", 6)
|
u1:set_skill("magic", 6)
|
||||||
u1.aura = 0
|
u1.aura = 0
|
||||||
u1:add_spell("fetch_astral")
|
u1:add_spell("fetch_astral")
|
||||||
|
|
||||||
u1:clear_orders()
|
u1:clear_orders()
|
||||||
u1:add_order("ZAUBERE Ruf~der~Realitaet " .. itoa36(u2.id))
|
u1:add_order("ZAUBERE Ruf~der~Realitaet " .. itoa36(u2.id) .. " " .. itoa36(u3.id))
|
||||||
process_orders()
|
process_orders()
|
||||||
assert_equal(1, f:count_msg_type('missing_components_list'), 'no components')
|
assert_equal(1, f:count_msg_type('missing_components_list'), 'no components')
|
||||||
|
|
||||||
|
@ -33,10 +37,11 @@ function test_fetch_astral()
|
||||||
assert_equal(12, u1.aura)
|
assert_equal(12, u1.aura)
|
||||||
assert_equal(1, f:count_msg_type('spellfail_astralonly'), 'astral space')
|
assert_equal(1, f:count_msg_type('spellfail_astralonly'), 'astral space')
|
||||||
|
|
||||||
u2.region = u2.region:get_astral('fog')
|
u2.region = ra
|
||||||
process_orders()
|
process_orders()
|
||||||
assert_equal(0, u1.aura)
|
assert_equal(0, u1.aura)
|
||||||
assert_equal(u1.region, u2.region)
|
assert_equal(r, u2.region)
|
||||||
|
assert_equal(rb, u3.region)
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_pull_astral()
|
function test_pull_astral()
|
||||||
|
|
|
@ -9,6 +9,7 @@ function setup()
|
||||||
eressea.settings.set("NewbieImmunity", "0")
|
eressea.settings.set("NewbieImmunity", "0")
|
||||||
eressea.settings.set("rules.food.flags", "4")
|
eressea.settings.set("rules.food.flags", "4")
|
||||||
eressea.settings.set("rules.peasants.growth.factor", "0")
|
eressea.settings.set("rules.peasants.growth.factor", "0")
|
||||||
|
eressea.settings.set("magic.resist.enable", "0")
|
||||||
eressea.settings.set("magic.fumble.enable", "0")
|
eressea.settings.set("magic.fumble.enable", "0")
|
||||||
eressea.settings.set("magic.regeneration.enable", "0")
|
eressea.settings.set("magic.regeneration.enable", "0")
|
||||||
end
|
end
|
||||||
|
@ -234,8 +235,6 @@ function test_familiar_school()
|
||||||
local u = unit.create(f, r)
|
local u = unit.create(f, r)
|
||||||
u.magic = "draig"
|
u.magic = "draig"
|
||||||
u:set_skill("magic", 10)
|
u:set_skill("magic", 10)
|
||||||
u.aura = 200
|
|
||||||
u:add_spell("fireball")
|
|
||||||
local uf = unit.create(f, r)
|
local uf = unit.create(f, r)
|
||||||
uf.race = "lynx"
|
uf.race = "lynx"
|
||||||
u.familiar = uf
|
u.familiar = uf
|
||||||
|
@ -247,3 +246,19 @@ function test_familiar_school()
|
||||||
assert_equal(0, uf.aura)
|
assert_equal(0, uf.aura)
|
||||||
assert_nil(uf.magic)
|
assert_nil(uf.magic)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function test_astral_disruption()
|
||||||
|
local r = region.create(0, 0, "plain")
|
||||||
|
local r2 = r:get_astral('fog')
|
||||||
|
local f = faction.create("human")
|
||||||
|
local u = unit.create(f, r)
|
||||||
|
local uh = unit.create(get_monsters(), r2, 1, "braineater")
|
||||||
|
u.magic = "draig"
|
||||||
|
u:set_skill("magic", 100) -- level 100 should beat magic resistance
|
||||||
|
u.aura = 200
|
||||||
|
u:add_spell("astral_disruption")
|
||||||
|
u:add_order('ZAUBERE STUFE 1 "Stoere Astrale Integritaet"')
|
||||||
|
process_orders()
|
||||||
|
assert_not_nil(r2:get_curse("astralblock"))
|
||||||
|
assert_equal(r, uh.region)
|
||||||
|
end
|
||||||
|
|
|
@ -1153,7 +1153,8 @@ static void destroy_items(troop dt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void calculate_defense_type(troop at, troop dt, int type, bool missile,
|
static void calculate_defense_type(troop at, troop dt, int type, bool missile,
|
||||||
const weapon_type **dwtype, int *defskill) {
|
const weapon_type **dwtype, int *defskill)
|
||||||
|
{
|
||||||
const weapon *weapon;
|
const weapon *weapon;
|
||||||
weapon = select_weapon(dt, false, true); /* missile=true to get the unmodified best weapon she has */
|
weapon = select_weapon(dt, false, true); /* missile=true to get the unmodified best weapon she has */
|
||||||
*defskill = weapon_effskill(dt, at, weapon, false, false);
|
*defskill = weapon_effskill(dt, at, weapon, false, false);
|
||||||
|
@ -1265,14 +1266,11 @@ terminate(troop dt, troop at, int type, const char *damage_formula, bool missile
|
||||||
unit *au = af->unit;
|
unit *au = af->unit;
|
||||||
unit *du = df->unit;
|
unit *du = df->unit;
|
||||||
battle *b = df->side->battle;
|
battle *b = df->side->battle;
|
||||||
|
|
||||||
int armor_value;
|
int armor_value;
|
||||||
|
|
||||||
const weapon_type *dwtype = NULL;
|
const weapon_type *dwtype = NULL;
|
||||||
const weapon_type *awtype = NULL;
|
const weapon_type *awtype = NULL;
|
||||||
const armor_type *armor = NULL;
|
const armor_type *armor = NULL;
|
||||||
const armor_type *shield = NULL;
|
const armor_type *shield = NULL;
|
||||||
|
|
||||||
int reduced_damage, attskill = 0, defskill = 0;
|
int reduced_damage, attskill = 0, defskill = 0;
|
||||||
bool magic = false;
|
bool magic = false;
|
||||||
|
|
||||||
|
|
|
@ -260,7 +260,7 @@ static int tolua_faction_debug_messages(lua_State * L)
|
||||||
int i = 1;
|
int i = 1;
|
||||||
if (f->msgs) {
|
if (f->msgs) {
|
||||||
mlist *ml;
|
mlist *ml;
|
||||||
for (ml = self->msgs->begin; ml; ml = ml->next, ++i) {
|
for (ml = f->msgs->begin; ml; ml = ml->next, ++i) {
|
||||||
char buf[120];
|
char buf[120];
|
||||||
nr_render(ml->msg, default_locale, buf, sizeof(buf), NULL);
|
nr_render(ml->msg, default_locale, buf, sizeof(buf), NULL);
|
||||||
puts(buf);
|
puts(buf);
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct lua_State;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct lua_State;
|
|
||||||
int tolua_factionlist_next(struct lua_State *L);
|
int tolua_factionlist_next(struct lua_State *L);
|
||||||
void tolua_faction_open(struct lua_State *L);
|
void tolua_faction_open(struct lua_State *L);
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,14 @@ static int tolua_region_get_plane(lua_State * L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tolua_region_set_plane(lua_State * L)
|
||||||
|
{
|
||||||
|
region *r = (region *)tolua_tousertype(L, 1, NULL);
|
||||||
|
plane *pl = (plane *)tolua_tousertype(L, 2, NULL);
|
||||||
|
r->_plane = pl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int tolua_region_get_terrain(lua_State * L)
|
static int tolua_region_get_terrain(lua_State * L)
|
||||||
{
|
{
|
||||||
region *self = (region *)tolua_tousertype(L, 1, NULL);
|
region *self = (region *)tolua_tousertype(L, 1, NULL);
|
||||||
|
@ -579,10 +587,10 @@ static int tolua_region_getastral(lua_State * L)
|
||||||
|
|
||||||
if (!rt) {
|
if (!rt) {
|
||||||
const char *tname = tolua_tostring(L, 2, NULL);
|
const char *tname = tolua_tostring(L, 2, NULL);
|
||||||
|
const terrain_type *terrain = get_terrain(tname ? tname : "fog");
|
||||||
plane *pl = get_astralplane();
|
plane *pl = get_astralplane();
|
||||||
rt = new_region(real2tp(r->x), real2tp(r->y), pl, 0);
|
rt = new_region(real2tp(r->x), real2tp(r->y), pl, 0);
|
||||||
if (tname) {
|
if (terrain) {
|
||||||
const terrain_type *terrain = get_terrain(tname);
|
|
||||||
terraform_region(rt, terrain);
|
terraform_region(rt, terrain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -768,7 +776,8 @@ void tolua_region_open(lua_State * L)
|
||||||
tolua_variable(L, TOLUA_CAST "id", tolua_region_get_id, NULL);
|
tolua_variable(L, TOLUA_CAST "id", tolua_region_get_id, NULL);
|
||||||
tolua_variable(L, TOLUA_CAST "x", tolua_region_get_x, NULL);
|
tolua_variable(L, TOLUA_CAST "x", tolua_region_get_x, NULL);
|
||||||
tolua_variable(L, TOLUA_CAST "y", tolua_region_get_y, NULL);
|
tolua_variable(L, TOLUA_CAST "y", tolua_region_get_y, NULL);
|
||||||
tolua_variable(L, TOLUA_CAST "plane", tolua_region_get_plane, NULL);
|
tolua_variable(L, TOLUA_CAST "plane", tolua_region_get_plane,
|
||||||
|
tolua_region_set_plane);
|
||||||
tolua_variable(L, TOLUA_CAST "name", tolua_region_get_name,
|
tolua_variable(L, TOLUA_CAST "name", tolua_region_get_name,
|
||||||
tolua_region_set_name);
|
tolua_region_set_name);
|
||||||
tolua_variable(L, TOLUA_CAST "morale", tolua_region_get_morale,
|
tolua_variable(L, TOLUA_CAST "morale", tolua_region_get_morale,
|
||||||
|
|
|
@ -1464,14 +1464,16 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r)
|
||||||
cr_output_curses_compat(F, f, r, TYP_REGION);
|
cr_output_curses_compat(F, f, r, TYP_REGION);
|
||||||
cr_borders(r, f, r->seen.mode, F);
|
cr_borders(r, f, r->seen.mode, F);
|
||||||
if (r->seen.mode >= seen_unit && is_astral(r)
|
if (r->seen.mode >= seen_unit && is_astral(r)
|
||||||
&& !is_cursed(r->attribs, &ct_astralblock)) {
|
&& !is_cursed(r->attribs, &ct_astralblock))
|
||||||
|
{
|
||||||
/* Sonderbehandlung Teleport-Ebene */
|
/* Sonderbehandlung Teleport-Ebene */
|
||||||
region_list *rl = astralregions(r, inhabitable);
|
region *rl[MAX_SCHEMES];
|
||||||
|
int num = get_astralregions(r, inhabitable, rl);
|
||||||
|
|
||||||
if (rl) {
|
if (num > 0) {
|
||||||
region_list *rl2 = rl;
|
int i;
|
||||||
while (rl2) {
|
for (i = 0; i != num; ++i) {
|
||||||
region *r2 = rl2->data;
|
region *r2 = rl[i];
|
||||||
plane *plx = rplane(r2);
|
plane *plx = rplane(r2);
|
||||||
|
|
||||||
nx = r2->x;
|
nx = r2->x;
|
||||||
|
@ -1480,9 +1482,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r)
|
||||||
adjust_coordinates(f, &nx, &ny, plx);
|
adjust_coordinates(f, &nx, &ny, plx);
|
||||||
fprintf(F, "SCHEMEN %d %d\n", nx, ny);
|
fprintf(F, "SCHEMEN %d %d\n", nx, ny);
|
||||||
fprintf(F, "\"%s\";Name\n", rname(r2, f->locale));
|
fprintf(F, "\"%s\";Name\n", rname(r2, f->locale));
|
||||||
rl2 = rl2->next;
|
|
||||||
}
|
}
|
||||||
free_regionlist(rl);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1152,6 +1152,14 @@ target_resists_magic(unit * magician, void *obj, int objtyp, int t_bonus)
|
||||||
{
|
{
|
||||||
variant v02p, v98p, prob = frac_make(t_bonus, 100);
|
variant v02p, v98p, prob = frac_make(t_bonus, 100);
|
||||||
attrib *a = NULL;
|
attrib *a = NULL;
|
||||||
|
static bool never_resist;
|
||||||
|
static int config;
|
||||||
|
if (config_changed(&config)) {
|
||||||
|
never_resist = config_get_int("magic.resist.enable", 1) == 0;
|
||||||
|
}
|
||||||
|
if (never_resist) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (magician == NULL || obj == NULL) {
|
if (magician == NULL || obj == NULL) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1062,8 +1062,6 @@ char *report_list(const struct locale *lang, char *buffer, size_t len, int argc,
|
||||||
return format_list(argc, argv, buffer, len, two, start, middle, end);
|
return format_list(argc, argv, buffer, len, two, start, middle, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_SCHEMES ((TP_RADIUS * 2 + 1) * (TP_RADIUS * 2 + 1) - 4)
|
|
||||||
|
|
||||||
static void report_region_schemes(struct stream *out, const region * r, faction * f) {
|
static void report_region_schemes(struct stream *out, const region * r, faction * f) {
|
||||||
|
|
||||||
if (r->seen.mode >= seen_unit && is_astral(r) &&
|
if (r->seen.mode >= seen_unit && is_astral(r) &&
|
||||||
|
|
281
src/spells.c
281
src/spells.c
|
@ -15,7 +15,7 @@
|
||||||
#include "monsters.h"
|
#include "monsters.h"
|
||||||
#include "teleport.h"
|
#include "teleport.h"
|
||||||
|
|
||||||
/* triggers includes */
|
/* triggers includes */
|
||||||
#include <triggers/changefaction.h>
|
#include <triggers/changefaction.h>
|
||||||
#include <triggers/changerace.h>
|
#include <triggers/changerace.h>
|
||||||
#include <triggers/createcurse.h>
|
#include <triggers/createcurse.h>
|
||||||
|
@ -121,6 +121,27 @@ static double curse_chance(const struct curse *c, double force)
|
||||||
return 1.0 + (force - c->vigour) * 0.1;
|
return 1.0 + (force - c->vigour) * 0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RANGE_MAX 32
|
||||||
|
static void for_all_in_range(const region * r, int range, void(*callback)(region *, void *), void *cbdata) {
|
||||||
|
if (r) {
|
||||||
|
int x, y;
|
||||||
|
plane *pl = rplane(r);
|
||||||
|
for (x = r->x - range; x <= r->x + range; ++x) {
|
||||||
|
for (y = r->y - range; y <= r->y + range; ++y) {
|
||||||
|
if (koor_distance(r->x, r->y, x, y) <= range) {
|
||||||
|
region *r2;
|
||||||
|
int nx = x, ny = y;
|
||||||
|
pnormalize(&nx, &ny, pl);
|
||||||
|
r2 = findregion(nx, ny);
|
||||||
|
if (r2) {
|
||||||
|
callback(r2, cbdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void magicanalyse_region(region * r, unit * mage, double force)
|
static void magicanalyse_region(region * r, unit * mage, double force)
|
||||||
{
|
{
|
||||||
attrib *a;
|
attrib *a;
|
||||||
|
@ -1071,7 +1092,7 @@ static int sp_blessedharvest(castorder * co)
|
||||||
|
|
||||||
if (create_curse(caster, &r->attribs, &ct_blessedharvest, co->force,
|
if (create_curse(caster, &r->attribs, &ct_blessedharvest, co->force,
|
||||||
duration, 1.0, 0)) {
|
duration, 1.0, 0)) {
|
||||||
const char * effect = co->sp->sname[0]=='b' ? "harvest_effect" : "raindance_effect";
|
const char * effect = co->sp->sname[0] == 'b' ? "harvest_effect" : "raindance_effect";
|
||||||
message *seen = msg_message(effect, "mage", caster);
|
message *seen = msg_message(effect, "mage", caster);
|
||||||
message *unseen = msg_message(effect, "mage", (unit *)NULL);
|
message *unseen = msg_message(effect, "mage", (unit *)NULL);
|
||||||
report_effect(r, caster, seen, unseen);
|
report_effect(r, caster, seen, unseen);
|
||||||
|
@ -1852,8 +1873,6 @@ static int sp_treewalkenter(castorder * co)
|
||||||
static int sp_treewalkexit(castorder * co)
|
static int sp_treewalkexit(castorder * co)
|
||||||
{
|
{
|
||||||
region *rt;
|
region *rt;
|
||||||
region_list *rl, *rl2;
|
|
||||||
int tax, tay;
|
|
||||||
unit *u, *u2;
|
unit *u, *u2;
|
||||||
int remaining_cap;
|
int remaining_cap;
|
||||||
int n;
|
int n;
|
||||||
|
@ -1885,23 +1904,7 @@ static int sp_treewalkexit(castorder * co)
|
||||||
/* Koordinaten setzen und Region loeschen fuer Ueberpruefung auf
|
/* Koordinaten setzen und Region loeschen fuer Ueberpruefung auf
|
||||||
* Gueltigkeit */
|
* Gueltigkeit */
|
||||||
rt = pa->param[0]->data.r;
|
rt = pa->param[0]->data.r;
|
||||||
tax = rt->x;
|
if (!rt || !inhabitable(rt) || r_standard_to_astral(rt) != r) {
|
||||||
tay = rt->y;
|
|
||||||
|
|
||||||
rl = astralregions(r, inhabitable);
|
|
||||||
rt = NULL;
|
|
||||||
|
|
||||||
rl2 = rl;
|
|
||||||
while (rl2) {
|
|
||||||
if (rl2->data->x == tax && rl2->data->y == tay) {
|
|
||||||
rt = rl2->data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
rl2 = rl2->next;
|
|
||||||
}
|
|
||||||
free_regionlist(rl);
|
|
||||||
|
|
||||||
if (!rt) {
|
|
||||||
cmistake(caster, co->order, 195, MSG_MAGIC);
|
cmistake(caster, co->order, 195, MSG_MAGIC);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2534,6 +2537,23 @@ static void patzer_fumblecurse(const castorder * co)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cb_set_dragon_target(region *r2, void *cbdata) {
|
||||||
|
region *r = (region *)cbdata;
|
||||||
|
unit *u;
|
||||||
|
for (u = r2->units; u; u = u->next) {
|
||||||
|
if (u_race(u) == get_race(RC_WYRM) || u_race(u) == get_race(RC_DRAGON)) {
|
||||||
|
attrib *a = a_find(u->attribs, &at_targetregion);
|
||||||
|
if (!a) {
|
||||||
|
a = a_add(&u->attribs, make_targetregion(r));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
a->data.v = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Name: Drachenruf
|
/* Name: Drachenruf
|
||||||
* Stufe: 11
|
* Stufe: 11
|
||||||
|
@ -2556,13 +2576,10 @@ static int sp_summondragon(castorder * co)
|
||||||
{
|
{
|
||||||
region *r = co_get_region(co);
|
region *r = co_get_region(co);
|
||||||
unit *caster = co_get_caster(co);
|
unit *caster = co_get_caster(co);
|
||||||
unit *u;
|
|
||||||
int cast_level = co->level;
|
int cast_level = co->level;
|
||||||
double power = co->force;
|
double power = co->force;
|
||||||
region_list *rl, *rl2;
|
|
||||||
faction *f;
|
faction *f;
|
||||||
int time;
|
int time, number;
|
||||||
int number;
|
|
||||||
const race *race;
|
const race *race;
|
||||||
|
|
||||||
f = get_monsters();
|
f = get_monsters();
|
||||||
|
@ -2599,27 +2616,11 @@ static int sp_summondragon(castorder * co)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rl = all_in_range(r, (short)power, NULL);
|
for_all_in_range(r, (int)power, cb_set_dragon_target, r);
|
||||||
|
|
||||||
for (rl2 = rl; rl2; rl2 = rl2->next) {
|
|
||||||
region *r2 = rl2->data;
|
|
||||||
for (u = r2->units; u; u = u->next) {
|
|
||||||
if (u_race(u) == get_race(RC_WYRM) || u_race(u) == get_race(RC_DRAGON)) {
|
|
||||||
attrib *a = a_find(u->attribs, &at_targetregion);
|
|
||||||
if (!a) {
|
|
||||||
a = a_add(&u->attribs, make_targetregion(r));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
a->data.v = r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ADDMSG(&caster->faction->msgs, msg_message("summondragon",
|
ADDMSG(&caster->faction->msgs, msg_message("summondragon",
|
||||||
"unit region command target", caster, caster->region, co->order, r));
|
"unit region command target", caster, caster->region, co->order, r));
|
||||||
|
|
||||||
free_regionlist(rl);
|
|
||||||
return cast_level;
|
return cast_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2825,7 +2826,7 @@ static int dc_age(struct curse *c)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reduziert durch Magieresistenz */
|
/* Reduziert durch Magieresistenz */
|
||||||
dmg = frac_mul(dmg, frac_sub(frac_make(1,1), magic_resistance(u)));
|
dmg = frac_mul(dmg, frac_sub(frac_make(1, 1), magic_resistance(u)));
|
||||||
damage *= dmg.sa[0];
|
damage *= dmg.sa[0];
|
||||||
damage /= dmg.sa[1];
|
damage /= dmg.sa[1];
|
||||||
hp = change_hitpoints(u, -(int)damage);
|
hp = change_hitpoints(u, -(int)damage);
|
||||||
|
@ -5051,7 +5052,6 @@ int sp_pullastral(castorder * co)
|
||||||
{
|
{
|
||||||
region *rt, *ro;
|
region *rt, *ro;
|
||||||
unit *u, *u2;
|
unit *u, *u2;
|
||||||
region_list *rl, *rl2;
|
|
||||||
int remaining_cap;
|
int remaining_cap;
|
||||||
int n, w;
|
int n, w;
|
||||||
region *r = co_get_region(co);
|
region *r = co_get_region(co);
|
||||||
|
@ -5064,23 +5064,12 @@ int sp_pullastral(castorder * co)
|
||||||
case 1:
|
case 1:
|
||||||
rt = r;
|
rt = r;
|
||||||
ro = pa->param[0]->data.r;
|
ro = pa->param[0]->data.r;
|
||||||
rl = astralregions(r, NULL);
|
|
||||||
rl2 = rl;
|
if (r_astral_to_standard(r) != ro) {
|
||||||
while (rl2 != NULL) {
|
|
||||||
region *r2 = rl2->data;
|
|
||||||
if (r2->x == ro->x && r2->y == ro->y) {
|
|
||||||
ro = r2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
rl2 = rl2->next;
|
|
||||||
}
|
|
||||||
if (!rl2) {
|
|
||||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||||
"spellfail::nocontact", "target", rt));
|
"spellfail::nocontact", "target", rt));
|
||||||
free_regionlist(rl);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
free_regionlist(rl);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||||
|
@ -5192,7 +5181,6 @@ int sp_pullastral(castorder * co)
|
||||||
int sp_leaveastral(castorder * co)
|
int sp_leaveastral(castorder * co)
|
||||||
{
|
{
|
||||||
region *rt, *ro;
|
region *rt, *ro;
|
||||||
region_list *rl, *rl2;
|
|
||||||
unit *u, *u2;
|
unit *u, *u2;
|
||||||
int remaining_cap;
|
int remaining_cap;
|
||||||
int n, w;
|
int n, w;
|
||||||
|
@ -5204,27 +5192,13 @@ int sp_leaveastral(castorder * co)
|
||||||
|
|
||||||
switch (getplaneid(r)) {
|
switch (getplaneid(r)) {
|
||||||
case 1:
|
case 1:
|
||||||
ro = r;
|
|
||||||
rt = pa->param[0]->data.r;
|
rt = pa->param[0]->data.r;
|
||||||
if (!rt) {
|
if (!rt || r_standard_to_astral(rt) != r || !inhabitable(rt)) {
|
||||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||||
"spellfail::noway", ""));
|
"spellfail::noway", ""));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
rl = astralregions(r, inhabitable);
|
ro = r;
|
||||||
rl2 = rl;
|
|
||||||
while (rl2 != NULL) {
|
|
||||||
if (rl2->data == rt)
|
|
||||||
break;
|
|
||||||
rl2 = rl2->next;
|
|
||||||
}
|
|
||||||
if (rl2 == NULL) {
|
|
||||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
|
||||||
"spellfail::noway", ""));
|
|
||||||
free_regionlist(rl);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
free_regionlist(rl);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||||
|
@ -5328,7 +5302,6 @@ int sp_fetchastral(castorder * co)
|
||||||
spellparameter *pa = co->par;
|
spellparameter *pa = co->par;
|
||||||
double power = co->force;
|
double power = co->force;
|
||||||
int remaining_cap = (int)((power - 3) * 1500);
|
int remaining_cap = (int)((power - 3) * 1500);
|
||||||
region_list *rtl = NULL;
|
|
||||||
region *rt = co_get_region(co); /* region to which we are fetching */
|
region *rt = co_get_region(co); /* region to which we are fetching */
|
||||||
region *ro = NULL; /* region in which the target is */
|
region *ro = NULL; /* region in which the target is */
|
||||||
|
|
||||||
|
@ -5350,21 +5323,13 @@ int sp_fetchastral(castorder * co)
|
||||||
if (u->region != ro) {
|
if (u->region != ro) {
|
||||||
/* this can happen several times if the units are from different astral
|
/* this can happen several times if the units are from different astral
|
||||||
* regions. Only possible on the intersections of schemes */
|
* regions. Only possible on the intersections of schemes */
|
||||||
region_list *rfind;
|
|
||||||
if (!is_astral(u->region)) {
|
if (!is_astral(u->region)) {
|
||||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||||
"spellfail_astralonly", ""));
|
"spellfail_astralonly", ""));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtl != NULL)
|
if (r_standard_to_astral(mage->region) != u->region) {
|
||||||
free_regionlist(rtl);
|
|
||||||
rtl = astralregions(u->region, NULL);
|
|
||||||
for (rfind = rtl; rfind != NULL; rfind = rfind->next) {
|
|
||||||
if (rfind->data == mage->region)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (rfind == NULL) {
|
|
||||||
/* the region r is not in the schemes of rt */
|
/* the region r is not in the schemes of rt */
|
||||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||||
"spellfail_distance", "target", u));
|
"spellfail_distance", "target", u));
|
||||||
|
@ -5446,8 +5411,6 @@ int sp_fetchastral(castorder * co)
|
||||||
if (m)
|
if (m)
|
||||||
msg_release(m);
|
msg_release(m);
|
||||||
}
|
}
|
||||||
if (rtl != NULL)
|
|
||||||
free_regionlist(rtl);
|
|
||||||
return cast_level;
|
return cast_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5545,11 +5508,12 @@ int sp_showastral(castorder * co)
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
int sp_viewreality(castorder * co)
|
int sp_viewreality(castorder * co)
|
||||||
{
|
{
|
||||||
region_list *rl, *rl2;
|
|
||||||
region *r = co_get_region(co);
|
region *r = co_get_region(co);
|
||||||
unit *mage = co_get_caster(co);
|
unit *mage = co_get_caster(co);
|
||||||
int cast_level = co->level;
|
int cast_level = co->level;
|
||||||
message *m;
|
message *m;
|
||||||
|
region *rl[MAX_SCHEMES];
|
||||||
|
int num;
|
||||||
|
|
||||||
if (getplaneid(r) != 1) {
|
if (getplaneid(r) != 1) {
|
||||||
/* sprintf(buf, "Dieser Zauber kann nur im Astralraum gezaubert werden."); */
|
/* sprintf(buf, "Dieser Zauber kann nur im Astralraum gezaubert werden."); */
|
||||||
|
@ -5558,17 +5522,16 @@ int sp_viewreality(castorder * co)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rl = astralregions(r, NULL);
|
num = get_astralregions(r, NULL, rl);
|
||||||
|
if (num > 0) {
|
||||||
/* Irgendwann mal auf Curses u/o Attribut umstellen. */
|
int i;
|
||||||
for (rl2 = rl; rl2; rl2 = rl2->next) {
|
for (i = 0; i != num; ++i) {
|
||||||
region *rt = rl2->data;
|
region *rt = rl[i];
|
||||||
if (!is_cursed(rt->attribs, &ct_astralblock)) {
|
if (!is_cursed(rt->attribs, &ct_astralblock)) {
|
||||||
set_observer(rt, mage->faction, co->level / 2, 2);
|
set_observer(rt, mage->faction, co->level / 2, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
free_regionlist(rl);
|
|
||||||
|
|
||||||
m = msg_message("viewreality_effect", "unit", mage);
|
m = msg_message("viewreality_effect", "unit", mage);
|
||||||
r_addmessage(r, mage->faction, m);
|
r_addmessage(r, mage->faction, m);
|
||||||
|
@ -5577,17 +5540,70 @@ int sp_viewreality(castorder * co)
|
||||||
return cast_level;
|
return cast_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
static void cb_disrupt_astral(region *r2, void *cbdata) {
|
||||||
|
castorder *co = (castorder *)cbdata;
|
||||||
|
attrib *a;
|
||||||
|
region *rtargets[MAX_SCHEMES];
|
||||||
|
region *r = co_get_region(co);
|
||||||
|
unit *caster = co_get_caster(co);
|
||||||
|
int duration = (int)(co->force / 3) + 2;
|
||||||
|
|
||||||
|
if (is_cursed(r2->attribs, &ct_astralblock)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nicht-Permanente Tore zerstoeren */
|
||||||
|
a = a_find(r->attribs, &at_direction);
|
||||||
|
|
||||||
|
while (a != NULL && a->type == &at_direction) {
|
||||||
|
attrib *a2 = a->next;
|
||||||
|
spec_direction *sd = (spec_direction *)(a->data.v);
|
||||||
|
if (sd->duration != -1)
|
||||||
|
a_remove(&r->attribs, a);
|
||||||
|
a = a2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Einheiten auswerfen */
|
||||||
|
|
||||||
|
if (r2->units != NULL) {
|
||||||
|
int inhab_regions = get_astralregions(r2, inhabitable, rtargets);
|
||||||
|
|
||||||
|
if (inhab_regions) {
|
||||||
|
unit *u;
|
||||||
|
for (u = r2->units; u; u = u->next) {
|
||||||
|
int c = rng_int() % inhab_regions;
|
||||||
|
region *tr = rtargets[c];
|
||||||
|
|
||||||
|
if (!is_magic_resistant(caster, u, 0) && can_survive(u, tr)) {
|
||||||
|
message *msg = msg_message("disrupt_astral", "unit region", u, tr);
|
||||||
|
add_message(&u->faction->msgs, msg);
|
||||||
|
add_message(&tr->msgs, msg);
|
||||||
|
msg_release(msg);
|
||||||
|
|
||||||
|
move_unit(u, tr, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Kontakt unterbinden */
|
||||||
|
create_curse(caster, &r2->attribs, &ct_astralblock, co->force, duration, 100, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zauber: Störe astrale Integrität
|
||||||
|
*
|
||||||
|
* Dieser Zauber bewirkt eine schwere Störung des Astralraums. Innerhalb eines
|
||||||
|
* astralen Radius von Stufe/5 Regionen werden alle Astralwesen, die dem Zauber
|
||||||
|
* nicht wiederstehen können, aus der astralen Ebene geschleudert. Der astrale
|
||||||
|
* Kontakt mit allen betroffenen Regionen ist für Stufe/3 Wochen gestört.
|
||||||
|
*/
|
||||||
int sp_disruptastral(castorder * co)
|
int sp_disruptastral(castorder * co)
|
||||||
{
|
{
|
||||||
region_list *rl, *rl2;
|
|
||||||
region *rt;
|
region *rt;
|
||||||
unit *u;
|
|
||||||
region *r = co_get_region(co);
|
region *r = co_get_region(co);
|
||||||
unit *mage = co_get_caster(co);
|
unit *mage = co_get_caster(co);
|
||||||
int cast_level = co->level;
|
|
||||||
double power = co->force;
|
double power = co->force;
|
||||||
int duration = (int)(power / 3) + 1;
|
|
||||||
|
|
||||||
switch (getplaneid(r)) {
|
switch (getplaneid(r)) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -5607,71 +5623,8 @@ int sp_disruptastral(castorder * co)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rl = all_in_range(rt, (short)(power / 5), NULL);
|
for_all_in_range(rt, (int)(power / 5), cb_disrupt_astral, co);
|
||||||
|
return co->level;
|
||||||
for (rl2 = rl; rl2 != NULL; rl2 = rl2->next) {
|
|
||||||
attrib *a;
|
|
||||||
double effect;
|
|
||||||
region *r2 = rl2->data;
|
|
||||||
int inhab_regions = 0;
|
|
||||||
region_list *trl = NULL;
|
|
||||||
|
|
||||||
if (is_cursed(r2->attribs, &ct_astralblock))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (r2->units != NULL) {
|
|
||||||
region_list *trl2;
|
|
||||||
|
|
||||||
trl = astralregions(rl2->data, inhabitable);
|
|
||||||
for (trl2 = trl; trl2; trl2 = trl2->next)
|
|
||||||
++inhab_regions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nicht-Permanente Tore zerstoeren */
|
|
||||||
a = a_find(r->attribs, &at_direction);
|
|
||||||
|
|
||||||
while (a != NULL && a->type == &at_direction) {
|
|
||||||
attrib *a2 = a->next;
|
|
||||||
spec_direction *sd = (spec_direction *)(a->data.v);
|
|
||||||
if (sd->duration != -1)
|
|
||||||
a_remove(&r->attribs, a);
|
|
||||||
a = a2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Einheiten auswerfen */
|
|
||||||
|
|
||||||
if (trl != NULL) {
|
|
||||||
for (u = r2->units; u; u = u->next) {
|
|
||||||
region_list *trl2 = trl;
|
|
||||||
region *tr;
|
|
||||||
int c = rng_int() % inhab_regions;
|
|
||||||
|
|
||||||
/* Zufaellige Zielregion suchen */
|
|
||||||
while (c-- != 0) {
|
|
||||||
trl2 = trl2->next;
|
|
||||||
}
|
|
||||||
tr = trl2->data;
|
|
||||||
|
|
||||||
if (!is_magic_resistant(mage, u, 0) && can_survive(u, tr)) {
|
|
||||||
message *msg = msg_message("disrupt_astral", "unit region", u, tr);
|
|
||||||
add_message(&u->faction->msgs, msg);
|
|
||||||
add_message(&tr->msgs, msg);
|
|
||||||
msg_release(msg);
|
|
||||||
|
|
||||||
move_unit(u, tr, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free_regionlist(trl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Kontakt unterbinden */
|
|
||||||
effect = 100;
|
|
||||||
create_curse(mage, &rl2->data->attribs, &ct_astralblock,
|
|
||||||
power, duration, effect, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
free_regionlist(rl);
|
|
||||||
return cast_level;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
|
|
@ -43,37 +43,6 @@ static region *tpregion(const region * r)
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
region_list *astralregions(const region * r, bool(*valid) (const region *))
|
|
||||||
{
|
|
||||||
region_list *rlist = NULL;
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
assert(is_astral(r));
|
|
||||||
if (!is_astral(r)) {
|
|
||||||
log_error("astralregions was called with a non-astral region.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
r = r_astral_to_standard(r);
|
|
||||||
if (r == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (x = -TP_RADIUS; x <= +TP_RADIUS; ++x) {
|
|
||||||
for (y = -TP_RADIUS; y <= +TP_RADIUS; ++y) {
|
|
||||||
region *rn;
|
|
||||||
int dist = koor_distance(0, 0, x, y);
|
|
||||||
int nx = r->x + x, ny = r->y + y;
|
|
||||||
|
|
||||||
if (dist > TP_RADIUS)
|
|
||||||
continue;
|
|
||||||
pnormalize(&nx, &ny, rplane(r));
|
|
||||||
rn = findregion(nx, ny);
|
|
||||||
if (rn != NULL && (valid == NULL || valid(rn)))
|
|
||||||
add_regionlist(&rlist, rn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int get_astralregions(const region * r, bool(*valid) (const region *), region *result[])
|
int get_astralregions(const region * r, bool(*valid) (const region *), region *result[])
|
||||||
{
|
{
|
||||||
|
@ -91,7 +60,10 @@ int get_astralregions(const region * r, bool(*valid) (const region *), region *r
|
||||||
pnormalize(&nx, &ny, rplane(r));
|
pnormalize(&nx, &ny, rplane(r));
|
||||||
rn = findregion(nx, ny);
|
rn = findregion(nx, ny);
|
||||||
if (rn != NULL && (valid == NULL || valid(rn))) {
|
if (rn != NULL && (valid == NULL || valid(rn))) {
|
||||||
result[num++] = rn;
|
if (result) {
|
||||||
|
result[num] = rn;
|
||||||
|
}
|
||||||
|
++num;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,32 +95,6 @@ region *r_astral_to_standard(const region * r)
|
||||||
return r2;
|
return r2;
|
||||||
}
|
}
|
||||||
|
|
||||||
region_list *all_in_range(const region * r, int n,
|
|
||||||
bool(*valid) (const region *))
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
region_list *rlist = NULL;
|
|
||||||
plane *pl = rplane(r);
|
|
||||||
|
|
||||||
if (r == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (x = r->x - n; x <= r->x + n; x++) {
|
|
||||||
for (y = r->y - n; y <= r->y + n; y++) {
|
|
||||||
if (koor_distance(r->x, r->y, x, y) <= n) {
|
|
||||||
region *r2;
|
|
||||||
int nx = x, ny = y;
|
|
||||||
pnormalize(&nx, &ny, pl);
|
|
||||||
r2 = findregion(nx, ny);
|
|
||||||
if (r2 != NULL && (valid == NULL || valid(r2)))
|
|
||||||
add_regionlist(&rlist, r2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAX_BRAIN_SIZE 100
|
#define MAX_BRAIN_SIZE 100
|
||||||
|
|
||||||
void spawn_braineaters(float chance)
|
void spawn_braineaters(float chance)
|
||||||
|
|
|
@ -8,6 +8,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TP_RADIUS 2 /* Radius von Schemen */
|
#define TP_RADIUS 2 /* Radius von Schemen */
|
||||||
|
#define MAX_SCHEMES ((TP_RADIUS * 2 + 1) * (TP_RADIUS * 2 + 1) - 4)
|
||||||
|
|
||||||
struct region;
|
struct region;
|
||||||
struct region_list;
|
struct region_list;
|
||||||
|
@ -15,10 +16,6 @@ extern "C" {
|
||||||
|
|
||||||
struct region *r_standard_to_astral(const struct region *r);
|
struct region *r_standard_to_astral(const struct region *r);
|
||||||
struct region *r_astral_to_standard(const struct region *);
|
struct region *r_astral_to_standard(const struct region *);
|
||||||
struct region_list *astralregions(const struct region *rastral,
|
|
||||||
bool(*valid) (const struct region *));
|
|
||||||
struct region_list *all_in_range(const struct region *r, int n,
|
|
||||||
bool(*valid) (const struct region *));
|
|
||||||
bool inhabitable(const struct region *r);
|
bool inhabitable(const struct region *r);
|
||||||
bool is_astral(const struct region *r);
|
bool is_astral(const struct region *r);
|
||||||
struct plane *get_astralplane(void);
|
struct plane *get_astralplane(void);
|
||||||
|
|
Loading…
Reference in New Issue