forked from github/server
Bug 2684 Astraler Blick
Old implementation was bad, using set_observer is better. Still missing a test, but improved the one for sp_viewreality, which is almost doing the same thing - adaptation should be easy. Fixes https://bugs.eressea.de/view.php?id=2684
This commit is contained in:
parent
9a4bc1ede1
commit
b06f3cf0e2
7 changed files with 56 additions and 91 deletions
|
@ -79,7 +79,7 @@ static void free_nodes(node * root)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct selist *regions_in_range(struct region *handle_start, int maxdist,
|
struct selist *path_regions_in_range(struct region *handle_start, int maxdist,
|
||||||
bool(*allowed) (const struct region *, const struct region *))
|
bool(*allowed) (const struct region *, const struct region *))
|
||||||
{
|
{
|
||||||
selist * rlist = NULL;
|
selist * rlist = NULL;
|
||||||
|
|
|
@ -8,15 +8,10 @@ extern "C" {
|
||||||
const struct region *target, int maxlen,
|
const struct region *target, int maxlen,
|
||||||
bool(*allowed) (const struct region *, const struct region *));
|
bool(*allowed) (const struct region *, const struct region *));
|
||||||
extern bool path_exists(struct region *handle_start, const struct region *target,
|
extern bool path_exists(struct region *handle_start, const struct region *target,
|
||||||
int maxlen, bool(*allowed) (const struct region *,
|
int maxlen, bool(*allowed) (const struct region *, const struct region *));
|
||||||
const struct region *));
|
extern bool allowed_fly(const struct region *src, const struct region *target);
|
||||||
extern bool allowed_swim(const struct region *src,
|
extern bool allowed_walk(const struct region *src, const struct region *target);
|
||||||
const struct region *target);
|
extern struct selist *path_regions_in_range(struct region *src, int maxdist,
|
||||||
extern bool allowed_fly(const struct region *src,
|
|
||||||
const struct region *target);
|
|
||||||
extern bool allowed_walk(const struct region *src,
|
|
||||||
const struct region *target);
|
|
||||||
extern struct selist *regions_in_range(struct region *src, int maxdist,
|
|
||||||
bool(*allowed) (const struct region *, const struct region *));
|
bool(*allowed) (const struct region *, const struct region *));
|
||||||
|
|
||||||
extern void pathfinder_cleanup(void);
|
extern void pathfinder_cleanup(void);
|
||||||
|
|
|
@ -497,7 +497,7 @@ static attrib *set_new_dragon_target(unit * u, region * r, int range)
|
||||||
{
|
{
|
||||||
int max_affinity = 0;
|
int max_affinity = 0;
|
||||||
region *max_region = NULL;
|
region *max_region = NULL;
|
||||||
selist *ql, *rlist = regions_in_range(r, range, allowed_dragon);
|
selist *ql, *rlist = path_regions_in_range(r, range, allowed_dragon);
|
||||||
int qi;
|
int qi;
|
||||||
|
|
||||||
for (qi = 0, ql = rlist; ql; selist_advance(&ql, &qi, 1)) {
|
for (qi = 0, ql = rlist; ql; selist_advance(&ql, &qi, 1)) {
|
||||||
|
|
74
src/spells.c
74
src/spells.c
|
@ -5423,19 +5423,22 @@ int sp_fetchastral(castorder * co)
|
||||||
return cast_level;
|
return cast_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SHOWASTRAL_IS_BORKED
|
static bool cb_not_astral_blocked(const struct region *rt) {
|
||||||
|
return !is_cursed(rt->attribs, &ct_astralblock);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef SHOWASTRAL_IS_BORKED
|
||||||
#ifndef SHOWASTRAL_IS_BORKED
|
#ifndef SHOWASTRAL_IS_BORKED
|
||||||
|
#define SHOWASTRAL_MAX_RADIUS 5
|
||||||
int sp_showastral(castorder * co)
|
int sp_showastral(castorder * co)
|
||||||
{
|
{
|
||||||
unit *u;
|
|
||||||
region *rt;
|
region *rt;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
int c = 0;
|
|
||||||
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 force = (int) co->force;
|
||||||
double power = co->force;
|
int radius = (force < SHOWASTRAL_MAX_RADIUS) ? force : SHOWASTRAL_MAX_RADIUS;
|
||||||
|
region *targets[4 * SHOWASTRAL_MAX_RADIUS * SHOWASTRAL_MAX_RADIUS];
|
||||||
|
|
||||||
switch (getplaneid(r)) {
|
switch (getplaneid(r)) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -5455,62 +5458,21 @@ int sp_showastral(castorder * co)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rl = all_in_range(rt, power / 5);
|
n = regions_in_range(rt, radius, cb_not_astral_blocked, targets);
|
||||||
|
|
||||||
/* Erst Einheiten zaehlen, fuer die Grammatik. */
|
|
||||||
|
|
||||||
for (rl2 = rl; rl2; rl2 = rl2->next) {
|
|
||||||
region *r2 = rl2->data;
|
|
||||||
if (!is_cursed(r2->attribs, &ct_astralblock)) {
|
|
||||||
for (u = r2->units; u; u = u->next) {
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
/* sprintf(buf, "%s kann niemanden im astralen Nebel entdecken.",
|
/* sprintf(buf, "%s kann niemanden im astralen Nebel entdecken.",
|
||||||
unitname(mage)); */
|
unitname(mage)); */
|
||||||
cmistake(mage, co->order, 220, MSG_MAGIC);
|
cmistake(mage, co->order, 220, MSG_MAGIC);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
int i;
|
||||||
/* Ausgeben */
|
for (i = 0; i != n; ++i) {
|
||||||
|
region *rt = targets[i];
|
||||||
sprintf(buf, "%s hat eine Vision der astralen Ebene. Im astralen "
|
set_observer(rt, mage->faction, (int)(co->force / 2), 2);
|
||||||
"Nebel zu erkennen sind ", unitname(mage));
|
|
||||||
|
|
||||||
for (rl2 = rl; rl2; rl2 = rl2->next) {
|
|
||||||
if (!is_cursed(rl2->data->attribs, &ct_astralblock)) {
|
|
||||||
for (u = rl2->data->units; u; u = u->next) {
|
|
||||||
c++;
|
|
||||||
scat(unitname(u));
|
|
||||||
scat(" (");
|
|
||||||
if (!fval(u, UFL_ANON_FACTION)) {
|
|
||||||
scat(factionname(u->faction));
|
|
||||||
scat(", ");
|
|
||||||
}
|
}
|
||||||
icat(u->number);
|
|
||||||
scat(" ");
|
|
||||||
scat(LOC(mage->faction->locale, rc_name_s(u_race(u), (u->number == 1) ? NAME_SINGULAR : NAME_PLURAL)));
|
|
||||||
scat(", Entfernung ");
|
|
||||||
icat(distance(rl2->data, rt));
|
|
||||||
scat(")");
|
|
||||||
if (c == n - 1) {
|
|
||||||
scat(" und ");
|
|
||||||
}
|
|
||||||
else if (c < n - 1) {
|
|
||||||
scat(", ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scat(".");
|
|
||||||
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_INFO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free_regionlist(rl);
|
return co->level;
|
||||||
return cast_level;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -5519,7 +5481,7 @@ int sp_viewreality(castorder * co)
|
||||||
{
|
{
|
||||||
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 force = (int)co->force;
|
||||||
message *m;
|
message *m;
|
||||||
region *rl[MAX_SCHEMES];
|
region *rl[MAX_SCHEMES];
|
||||||
int num;
|
int num;
|
||||||
|
@ -5537,7 +5499,7 @@ int sp_viewreality(castorder * co)
|
||||||
for (i = 0; i != num; ++i) {
|
for (i = 0; i != num; ++i) {
|
||||||
region *rt = rl[i];
|
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, force / 2, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5546,7 +5508,7 @@ int sp_viewreality(castorder * co)
|
||||||
r_addmessage(r, mage->faction, m);
|
r_addmessage(r, mage->faction, m);
|
||||||
msg_release(m);
|
msg_release(m);
|
||||||
|
|
||||||
return cast_level;
|
return co->level;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cb_disrupt_astral(region *r2, void *cbdata) {
|
static void cb_disrupt_astral(region *r2, void *cbdata) {
|
||||||
|
|
|
@ -116,7 +116,7 @@ static void test_bad_dreams(CuTest *tc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_view_reality(CuTest *tc) {
|
static void test_view_reality(CuTest *tc) {
|
||||||
region *r, *ra;
|
region *r, *ra, *rx;
|
||||||
faction *f;
|
faction *f;
|
||||||
unit *u;
|
unit *u;
|
||||||
castorder co;
|
castorder co;
|
||||||
|
@ -127,12 +127,13 @@ static void test_view_reality(CuTest *tc) {
|
||||||
mt_create_va(mt_new("viewreality_effect", NULL),
|
mt_create_va(mt_new("viewreality_effect", NULL),
|
||||||
"unit:unit", MT_NEW_END);
|
"unit:unit", MT_NEW_END);
|
||||||
r = test_create_region(0, 0, NULL);
|
r = test_create_region(0, 0, NULL);
|
||||||
|
rx = test_create_region(0, TP_RADIUS+1, NULL);
|
||||||
ra = test_create_region(real2tp(r->x), real2tp(r->y), NULL);
|
ra = test_create_region(real2tp(r->x), real2tp(r->y), NULL);
|
||||||
ra->_plane = get_astralplane();
|
ra->_plane = get_astralplane();
|
||||||
f = test_create_faction(NULL);
|
f = test_create_faction(NULL);
|
||||||
u = test_create_unit(f, r);
|
u = test_create_unit(f, r);
|
||||||
|
|
||||||
test_create_castorder(&co, u, 10, 10., 0, NULL);
|
test_create_castorder(&co, u, 10, 10.0, 0, NULL);
|
||||||
CuAssertIntEquals(tc, -1, get_observer(r, f));
|
CuAssertIntEquals(tc, -1, get_observer(r, f));
|
||||||
CuAssertIntEquals(tc, 0, sp_viewreality(&co));
|
CuAssertIntEquals(tc, 0, sp_viewreality(&co));
|
||||||
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "spell_astral_only"));
|
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "spell_astral_only"));
|
||||||
|
@ -141,11 +142,12 @@ static void test_view_reality(CuTest *tc) {
|
||||||
test_clear_messagelist(&f->msgs);
|
test_clear_messagelist(&f->msgs);
|
||||||
move_unit(u, ra, NULL);
|
move_unit(u, ra, NULL);
|
||||||
|
|
||||||
test_create_castorder(&co, u, 9, 10., 0, NULL);
|
test_create_castorder(&co, u, 9, 10.0, 0, NULL);
|
||||||
CuAssertIntEquals(tc, -1, get_observer(r, f));
|
CuAssertIntEquals(tc, -1, get_observer(r, f));
|
||||||
CuAssertIntEquals(tc, 9, sp_viewreality(&co));
|
CuAssertIntEquals(tc, 9, sp_viewreality(&co));
|
||||||
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "spell_astral_only"));
|
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "spell_astral_only"));
|
||||||
CuAssertIntEquals(tc, 4, get_observer(r, f));
|
CuAssertIntEquals(tc, 5, get_observer(r, f));
|
||||||
|
CuAssertIntEquals(tc, -1, get_observer(rx, f));
|
||||||
CuAssertPtrEquals(tc, f, (void *)ra->individual_messages->viewer);
|
CuAssertPtrEquals(tc, f, (void *)ra->individual_messages->viewer);
|
||||||
CuAssertPtrNotNull(tc, test_find_messagetype(ra->individual_messages->msgs, "viewreality_effect"));
|
CuAssertPtrNotNull(tc, test_find_messagetype(ra->individual_messages->msgs, "viewreality_effect"));
|
||||||
free_castorder(&co);
|
free_castorder(&co);
|
||||||
|
|
|
@ -43,21 +43,18 @@ static region *tpregion(const region * r)
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int regions_in_range(const region * r, int radius, bool(*valid) (const region *), region *result[])
|
||||||
int get_astralregions(const region * r, bool(*valid) (const region *), region *result[])
|
|
||||||
{
|
{
|
||||||
assert(is_astral(r));
|
|
||||||
r = r_astral_to_standard(r);
|
|
||||||
if (r) {
|
|
||||||
int x, y, num = 0;
|
int x, y, num = 0;
|
||||||
for (x = -TP_RADIUS; x <= +TP_RADIUS; ++x) {
|
const struct plane *pl = rplane(r);
|
||||||
for (y = -TP_RADIUS; y <= +TP_RADIUS; ++y) {
|
for (x = -radius; x <= +radius; ++x) {
|
||||||
region *rn;
|
for (y = -radius; y <= radius; ++y) {
|
||||||
int dist = koor_distance(0, 0, x, y);
|
int dist = koor_distance(0, 0, x, y);
|
||||||
|
|
||||||
if (dist <= TP_RADIUS) {
|
if (dist <= radius) {
|
||||||
|
region *rn;
|
||||||
int nx = r->x + x, ny = r->y + y;
|
int nx = r->x + x, ny = r->y + y;
|
||||||
pnormalize(&nx, &ny, rplane(r));
|
pnormalize(&nx, &ny, pl);
|
||||||
rn = findregion(nx, ny);
|
rn = findregion(nx, ny);
|
||||||
if (rn != NULL && (valid == NULL || valid(rn))) {
|
if (rn != NULL && (valid == NULL || valid(rn))) {
|
||||||
if (result) {
|
if (result) {
|
||||||
|
@ -70,6 +67,14 @@ int get_astralregions(const region * r, bool(*valid) (const region *), region *r
|
||||||
}
|
}
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_astralregions(const region * r, bool(*valid) (const region *), region *result[])
|
||||||
|
{
|
||||||
|
assert(is_astral(r));
|
||||||
|
r = r_astral_to_standard(r);
|
||||||
|
if (r) {
|
||||||
|
return regions_in_range(r, TP_RADIUS, valid, result);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ extern "C" {
|
||||||
bool is_astral(const struct region *r);
|
bool is_astral(const struct region *r);
|
||||||
struct plane *get_astralplane(void);
|
struct plane *get_astralplane(void);
|
||||||
int get_astralregions(const struct region * r, bool(*valid) (const struct region *), struct region *result[]);
|
int get_astralregions(const struct region * r, bool(*valid) (const struct region *), struct region *result[]);
|
||||||
|
int regions_in_range(const struct region * r, int radius, bool(*valid) (const struct region *), struct region *result[]);
|
||||||
|
|
||||||
void create_teleport_plane(void);
|
void create_teleport_plane(void);
|
||||||
void spawn_braineaters(float chance);
|
void spawn_braineaters(float chance);
|
||||||
|
|
Loading…
Reference in a new issue