summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorMatthew Cline <zelgadis@sourceforge.net>2009-10-19 04:41:44 -0700
committerMatthew Cline <zelgadis@sourceforge.net>2009-10-19 04:41:44 -0700
commita94b70783e1f4a0d1dd444c7c95a374ad2a140ca (patch)
treebefbecb618d084d61d9e31c23944380d1623e45c /crawl-ref
parent41246dc5351d38d025879564b02ac19822afeeb9 (diff)
downloadcrawl-ref-a94b70783e1f4a0d1dd444c7c95a374ad2a140ca.tar.gz
crawl-ref-a94b70783e1f4a0d1dd444c7c95a374ad2a140ca.zip
New arena option "respawn"
If the arena option "respawn" is used then when one of the originally placed monster dies it will be replaced by a copy.
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/docs/arena.txt5
-rw-r--r--crawl-ref/source/arena.cc59
2 files changed, 64 insertions, 0 deletions
diff --git a/crawl-ref/docs/arena.txt b/crawl-ref/docs/arena.txt
index 3a1cbee8ee..1633f0fe74 100644
--- a/crawl-ref/docs/arena.txt
+++ b/crawl-ref/docs/arena.txt
@@ -162,3 +162,8 @@ The parameters include:
* miscasts: Every turn each monster (besides test spawners) will have a
random miscast happen to it.
+
+* respawn: When one of the originally replaced monsters is killed it will
+ be replaced by the same type of monster. This allows for an endless
+ fight between exactly specified factions, rather than the random
+ kind you get by pitting two test spawners against each other.
diff --git a/crawl-ref/source/arena.cc b/crawl-ref/source/arena.cc
index 1617f916d0..c89e328644 100644
--- a/crawl-ref/source/arena.cc
+++ b/crawl-ref/source/arena.cc
@@ -46,6 +46,9 @@ namespace arena
int active_members;
bool won;
+ std::vector<int> respawn_list;
+ std::vector<coord_def> respawn_pos;
+
faction(bool fr) : members(), friendly(fr), active_members(0),
won(false) { }
@@ -55,6 +58,9 @@ namespace arena
{
active_members = 0;
won = false;
+
+ respawn_list.clear();
+ respawn_pos.clear();
}
void clear()
@@ -84,6 +90,7 @@ namespace arena
bool random_uniques = false;
bool real_summons = false;
bool move_summons = false;
+ bool respawn = false;
bool miscasts = false;
@@ -92,6 +99,7 @@ namespace arena
std::vector<int> uniques_list;
std::vector<int> a_spawners;
std::vector<int> b_spawners;
+ char to_respawn[MAX_MONSTERS];
int item_drop_times[MAX_ITEMS];
@@ -195,6 +203,7 @@ namespace arena
end(1, false, "Failed to create monster at (%d,%d) grd: %s",
loc.x, loc.y, dungeon_feature_name(grd(loc)));
list_eq(imon);
+ to_respawn[imon] = i;
}
}
}
@@ -307,8 +316,13 @@ namespace arena
real_summons = strip_tag(spec, "real_summons");
move_summons = strip_tag(spec, "move_summons");
miscasts = strip_tag(spec, "miscasts");
+ respawn = strip_tag(spec, "respawn");
summon_throttle = strip_number_tag(spec, "summon_throttle:");
+ if (real_summons && respawn)
+ throw (std::string("Can't set real_summons and respawn at "
+ "same time."));
+
if (summon_throttle <= 0)
summon_throttle = INT_MAX;
@@ -394,6 +408,9 @@ namespace arena
faction_a.reset();
faction_b.reset();
+ for (int i = 0; i < MAX_MONSTERS; i++)
+ to_respawn[i] = -1;
+
unwind_var< FixedVector<bool, NUM_MONSTERS> >
uniq(you.unique_creatures);
@@ -737,6 +754,26 @@ namespace arena
process_command(cmd);
}
+ void do_respawn(faction &fac)
+ {
+ for (unsigned int i = 0; i < fac.respawn_list.size(); i++)
+ {
+ coord_def pos = fac.respawn_pos[i];
+ int spec_idx = fac.respawn_list[i];
+ mons_spec spec = fac.members.get_monster(spec_idx);
+
+ if (fac.friendly)
+ spec.attitude = ATT_FRIENDLY;
+
+ int idx = dgn_place_monster(spec, 0, pos, false, true);
+
+ if (idx != -1)
+ to_respawn[idx] = spec_idx;
+ }
+ fac.respawn_list.clear();
+ fac.respawn_pos.clear();
+ }
+
void do_fight()
{
viewwindow(true, false);
@@ -772,6 +809,8 @@ namespace arena
//report_foes();
world_reacts();
do_miscasts();
+ do_respawn(faction_a);
+ do_respawn(faction_b);
balance_spawners();
delay(Options.arena_delay);
mesclr();
@@ -1159,6 +1198,26 @@ void arena_monster_died(monsters *monster, killer_type killer,
}
}
+ // Only respawn those monsers which were initally placed in the
+ // arena.
+ const int midx = monster->mindex();
+ if (arena::respawn && arena::to_respawn[midx] != -1)
+ {
+ arena::faction *fac = NULL;
+ if (monster->attitude == ATT_FRIENDLY)
+ fac = &arena::faction_a;
+ else if (monster->attitude == ATT_HOSTILE)
+ fac = &arena::faction_b;
+
+ if (fac)
+ {
+ fac->respawn_list.push_back(arena::to_respawn[midx]);
+ fac->respawn_pos.push_back(monster->pos());
+
+ arena::to_respawn[midx] = -1;
+ }
+ }
+
if (corpse != -1 && corpse != NON_ITEM)
arena::item_drop_times[corpse] = arena::turns;