make disrupt_astral use callback, not region_list.

This commit is contained in:
Enno Rehling 2019-09-29 18:25:08 +02:00
parent 17fbd0d67d
commit 7b9ea75d16
1 changed files with 59 additions and 73 deletions

View File

@ -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>
@ -122,7 +122,7 @@ static double curse_chance(const struct curse *c, double force)
} }
#define RANGE_MAX 32 #define RANGE_MAX 32
static void for_all_in_range(const region * r, int range, void (*callback)(region *, void *), void *cbdata) { static void for_all_in_range(const region * r, int range, void(*callback)(region *, void *), void *cbdata) {
if (r) { if (r) {
int x, y; int x, y;
plane *pl = rplane(r); plane *pl = rplane(r);
@ -147,15 +147,6 @@ static void cb_collect(region *r, void *cbdata) {
add_regionlist(rlistp, r); add_regionlist(rlistp, r);
} }
static region_list *list_all_in_range(const region * r, int n)
{
region_list *rlist = NULL;
for_all_in_range(r, n, cb_collect, &rlist);
return rlist;
}
static void magicanalyse_region(region * r, unit * mage, double force) static void magicanalyse_region(region * r, unit * mage, double force)
{ {
attrib *a; attrib *a;
@ -1106,7 +1097,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);
@ -2840,7 +2831,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);
@ -5554,24 +5545,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) + 1;
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 * Zauber: Störe astrale Integrität
* *
* Dieser Zauber bewirkt eine schwere Störung des Astralraums. Innerhalb eines * Dieser Zauber bewirkt eine schwere Störung des Astralraums. Innerhalb eines
* astralen Radius von Stufe/5 Regionen werden alle Astralwesen, die dem Zauber * astralen Radius von Stufe/5 Regionen werden alle Astralwesen, die dem Zauber
* nicht wiederstehen können, aus der astralen Ebene geschleudert. Der astrale * nicht wiederstehen können, aus der astralen Ebene geschleudert. Der astrale
* Kontakt mit allen betroffenen Regionen ist für Stufe/3 Wochen gestört. * 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:
@ -5591,59 +5628,8 @@ int sp_disruptastral(castorder * co)
return 0; return 0;
} }
rl = list_all_in_range(rt, (int)(power / 5)); 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 *rtargets[MAX_SCHEMES];
if (is_cursed(r2->attribs, &ct_astralblock))
continue;
if (r2->units != NULL) {
inhab_regions = get_astralregions(r2, inhabitable, rtargets);
}
/* 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 (inhab_regions) {
for (u = r2->units; u; u = u->next) {
int c = rng_int() % inhab_regions;
region *tr = rtargets[c];
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);
}
}
}
/* Kontakt unterbinden */
effect = 100;
create_curse(mage, &rl2->data->attribs, &ct_astralblock,
power, duration, effect, 0);
}
free_regionlist(rl);
return cast_level;
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
@ -6538,7 +6524,7 @@ void register_spells(void)
register_borders(); register_borders();
at_deprecate("zauber_todeswolke", dc_read_compat); at_deprecate("zauber_todeswolke", dc_read_compat);
/* init_firewall(); */ /* init_firewall(); */
ct_register(&ct_firewall); ct_register(&ct_firewall);
ct_register(&ct_deathcloud); ct_register(&ct_deathcloud);