|
From: <gi...@cr...> - 2013-07-30 20:50:22
|
via 9c9ad2be82ac0601b9a8ba53bf694f9989117f03 (commit)
via ed92a994f664c3d06841dd45e2479d5c037e3316 (commit)
via c67cb32cf693618954cf9a0211d99e07e5ed05b4 (commit)
from 83314a393d6b1ce958e77fe613aedebf71d2a732 (commit)
-----------------------------------------------------------------------
commit 9c9ad2be82ac0601b9a8ba53bf694f9989117f03
Author: Neil Moore <ne...@s-...>
Date: Tue Jul 30 16:44:19 2013 -0400
Tweak formatting and fix a typo.
commit ed92a994f664c3d06841dd45e2479d5c037e3316
Author: blackcustard <pet...@gm...>
Date: Tue Jul 30 14:11:30 2013 -0500
Fix a Kirke crash by deporkalating transiting hogs correctly.
Normally, monsters are stored in a list (env.mons or menv for short).
There is a grid (env.mgrid or mgrd for short) which maps the position (x,
y) of the monster to its index in the list. Transiting monsters, however,
exist outside both the monster list and the monster grid. They are stored
separately, and they do not really have positions.
The deporkalation code inside dactions.cc was not transiting-monster
aware. It would call monster::move_to_pos on transiting hogs, just as on
non-transiting hogs. When it did so, it would write their index inside the
monster list into the monster grid. Of course, since these hogs were not
in the monster list in the first place, this "index" was bogus.
Within a few turns one of several unrelated parts Crawl would try to
investigate the monster grid and trip over the bogus entry, triggering this
assertion in monster_at inside mon-util.cc:
ASSERT(mindex <= MAX_MONSTERS);
Changes:
1. Make the deporkalation code transiting-monster aware. Do not call
monster::move_to_pos on transiting monsters. (Fixes the crash.)
2. Add some informative comments.
3. Make an implicit type conversion from monster to follower explicit.
commit c67cb32cf693618954cf9a0211d99e07e5ed05b4
Author: Neil Moore <ne...@s-...>
Date: Tue Jul 30 16:29:37 2013 -0400
Forbid Cure Poison for Gargoyles.
They are completely immune to poison, even across changes of form.
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/dactions.cc | 34 +++++++++++++++++++++++++---------
crawl-ref/source/dactions.h | 3 ++-
crawl-ref/source/mon-transit.cc | 4 ++--
crawl-ref/source/spl-book.cc | 3 +++
4 files changed, 32 insertions(+), 12 deletions(-)
diff --git a/crawl-ref/source/dactions.cc b/crawl-ref/source/dactions.cc
index eb6428b..4680ba1 100644
--- a/crawl-ref/source/dactions.cc
+++ b/crawl-ref/source/dactions.cc
@@ -23,7 +23,7 @@
#include "travel.h"
#include "view.h"
-static void _daction_hog_to_human(monster *mon);
+static void _daction_hog_to_human(monster *mon, bool in_transit);
#ifdef DEBUG_DIAGNOSTICS
static const char *daction_names[] =
@@ -161,8 +161,13 @@ void add_daction(daction_type act)
}
-void apply_daction_to_mons(monster* mon, daction_type act, bool local)
+void apply_daction_to_mons(monster* mon, daction_type act, bool local,
+ bool in_transit)
{
+ // Transiting monsters exist outside the normal monster list (env.mons or
+ // menv for short). Be careful not to write them into the monster grid, by,
+ // for example, calling monster::move_to_pos on them.
+ // See _daction_hog_to_human for an example.
switch (act)
{
case DACT_ALLY_HOLY:
@@ -221,7 +226,7 @@ void apply_daction_to_mons(monster* mon, daction_type act, bool local)
break;
case DACT_KIRKE_HOGS:
- _daction_hog_to_human(mon);
+ _daction_hog_to_human(mon, in_transit);
break;
case DACT_END_SPIRIT_HOWL:
@@ -265,7 +270,7 @@ static void _apply_daction(daction_type act)
for (monster_iterator mi; mi; ++mi)
{
if (mons_matches_daction(*mi, act))
- apply_daction_to_mons(*mi, act, true);
+ apply_daction_to_mons(*mi, act, true, false);
}
break;
@@ -308,7 +313,7 @@ unsigned int query_da_counter(daction_type c)
return travel_cache.query_da_counter(c) + count_daction_in_transit(c);
}
-static void _daction_hog_to_human(monster *mon)
+static void _daction_hog_to_human(monster *mon, bool in_transit)
{
// Hogs to humans
monster orig;
@@ -317,19 +322,21 @@ static void _daction_hog_to_human(monster *mon)
// Was it a converted monster or original band member?
if (mon->props.exists(ORIG_MONSTER_KEY))
{
- // Copy it, since the instance in props will get deleted
- // as soon a **mi is assigned to.
+ // It was transformed into a pig. Copy it, since the instance in props
+ // will get deleted as soon as **mi is assigned to.
orig = mon->props[ORIG_MONSTER_KEY].get_monster();
orig.mid = mon->mid;
}
else
{
+ // It started life as a pig in Kirke's band.
orig.type = MONS_HUMAN;
orig.attitude = mon->attitude;
orig.mid = mon->mid;
define_monster(&orig);
}
- // Keep at same spot.
+ // Keep at same spot. This position is irrelevant if the hog is in transit.
+ // See below.
const coord_def pos = mon->pos();
// Preserve relative HP.
const float hp
@@ -343,7 +350,16 @@ static void _daction_hog_to_human(monster *mon)
// Restore original monster.
*mon = orig;
- mon->move_to_pos(pos);
+ // If the hog is in transit, then it is NOT stored in the normal
+ // monster list (env.mons or menv for short). We cannot call move_to_pos
+ // on such a hog, because move_to_pos will attempt to update the
+ // monster grid (env.mgrid or mgrd for short). Since the hog is not
+ // stored in the monster list, this will corrupt the grid. The transit code
+ // will update the grid properly once the transiting hog has been placed.
+ if (!in_transit)
+ mon->move_to_pos(pos);
+ // "else {mon->position = pos}" is unnecessary because the transit code will
+ // ignore the old position anyway.
mon->enchantments = enchantments;
mon->hit_points = max(1, (int) (mon->max_hit_points * hp));
mon->flags = mon->flags | preserve_flags;
diff --git a/crawl-ref/source/dactions.h b/crawl-ref/source/dactions.h
index df9e804..3f23505 100644
--- a/crawl-ref/source/dactions.h
+++ b/crawl-ref/source/dactions.h
@@ -9,6 +9,7 @@ void update_da_counters(LevelInfo *lev);
unsigned int query_da_counter(daction_type c);
bool mons_matches_daction(const monster* mon, daction_type act);
-void apply_daction_to_mons(monster* mons, daction_type act, bool local);
+void apply_daction_to_mons(monster* mons, daction_type act, bool local,
+ bool in_transit);
#endif
diff --git a/crawl-ref/source/mon-transit.cc b/crawl-ref/source/mon-transit.cc
index 54550a6..008c035 100644
--- a/crawl-ref/source/mon-transit.cc
+++ b/crawl-ref/source/mon-transit.cc
@@ -115,7 +115,7 @@ m_transit_list *get_transit_list(const level_id &lid)
void add_monster_to_transit(const level_id &lid, const monster& m)
{
m_transit_list &mlist = the_lost_ones[lid];
- mlist.push_back(m);
+ mlist.push_back(follower(m));
dprf("Monster in transit to %s: %s", lid.describe().c_str(),
m.name(DESC_PLAIN, true).c_str());
@@ -255,7 +255,7 @@ void apply_daction_to_transit(daction_type act)
{
monster* mon = &j->mons;
if (mons_matches_daction(mon, act))
- apply_daction_to_mons(mon, act, false);
+ apply_daction_to_mons(mon, act, false, true);
}
}
}
diff --git a/crawl-ref/source/spl-book.cc b/crawl-ref/source/spl-book.cc
index 27119ab..54c5db7 100644
--- a/crawl-ref/source/spl-book.cc
+++ b/crawl-ref/source/spl-book.cc
@@ -549,6 +549,9 @@ bool you_cannot_memorise(spell_type spell, bool &form)
form = true;
}
+ if (you.species == SP_GARGOYLE && spell == SPELL_CURE_POISON)
+ rc = true, form = false;
+
if (you.species == SP_DEEP_DWARF && spell == SPELL_REGENERATION)
rc = true, form = false;
--
Dungeon Crawl Stone Soup
|