summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-11-09 18:19:00 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-11-09 18:19:00 +0000
commit84d24b72b573becc9cfed52b423c4c9da8180456 (patch)
tree46021359f276b78fd5ec37e8b57e4c10ace54c5e
parent414ade94db4f4c13c8b8b2f95ca0eb9a238cc559 (diff)
downloadcrawl-ref-84d24b72b573becc9cfed52b423c4c9da8180456.tar.gz
crawl-ref-84d24b72b573becc9cfed52b423c4c9da8180456.zip
[1589854] Orange and silver statues are now monsters. Statue effects are handled
as monster special abilities. Disintegration continues to instakill, and the statue can also be destroyed physically. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup@377 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/source/acr.cc40
-rw-r--r--crawl-ref/source/beam.cc30
-rw-r--r--crawl-ref/source/describe.cc10
-rw-r--r--crawl-ref/source/direct.cc3
-rw-r--r--crawl-ref/source/dungeon.cc16
-rw-r--r--crawl-ref/source/enum.h4
-rw-r--r--crawl-ref/source/fight.cc3
-rw-r--r--crawl-ref/source/mon-data.h24
-rw-r--r--crawl-ref/source/mon-util.cc13
-rw-r--r--crawl-ref/source/mon-util.h3
-rw-r--r--crawl-ref/source/monplace.cc4
-rw-r--r--crawl-ref/source/monstuff.cc11
-rw-r--r--crawl-ref/source/mstuff2.cc36
-rw-r--r--crawl-ref/source/mstuff2.h2
-rw-r--r--crawl-ref/source/spells4.cc23
-rw-r--r--crawl-ref/source/view.cc9
16 files changed, 175 insertions, 56 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index daf8f0f219..746d9627c4 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -2171,46 +2171,6 @@ static void world_reacts() {
if (you.fire_shield > 0)
manage_fire_shield();
- // There used to be signs of intent to have statues as some sort
- // of more complex state machine... I'm boiling them down to bare
- // basics for now. -- bwr
- if (you.visible_statue[ STATUE_SILVER ])
- {
- interrupt_activity( AI_STATUE );
-
- if ((!you.invis && one_chance_in(3)) || one_chance_in(5))
- {
- char wc[30];
-
- weird_colours( random2(256), wc );
- snprintf(info, INFO_SIZE, "The silver statue's eyes glow %s.", wc);
- mpr( info, MSGCH_WARN );
-
- create_monster( summon_any_demon((coinflip() ? DEMON_COMMON
- : DEMON_LESSER)),
- ENCH_ABJ_V, BEH_HOSTILE,
- you.x_pos, you.y_pos,
- MHITYOU, 250 );
- }
-
- you.visible_statue[ STATUE_SILVER ] = 0;
- }
-
- if (you.visible_statue[ STATUE_ORANGE_CRYSTAL ])
- {
- interrupt_activity( AI_STATUE );
-
- if ((!you.invis && coinflip()) || one_chance_in(4))
- {
- mpr("A hostile presence attacks your mind!", MSGCH_WARN);
-
- miscast_effect( SPTYP_DIVINATION, random2(15), random2(150), 100,
- "an orange crystal statue" );
- }
-
- you.visible_statue[ STATUE_ORANGE_CRYSTAL ] = 0;
- }
-
// food death check:
if (you.is_undead != US_UNDEAD && you.hunger <= 500)
{
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 009746c653..15a8174eb7 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -1836,7 +1836,8 @@ int mons_ench_f2(struct monsters *monster, struct bolt &pbolt)
}
// not hasted, slow it
- if (mons_add_ench(monster, ENCH_SLOW))
+ if (!mons_has_ench(monster, ENCH_SLOW)
+ && mons_add_ench(monster, ENCH_SLOW))
{
// put in an exception for fungi, plants and other things you won't
// notice slow down.
@@ -3291,6 +3292,9 @@ static int affect_monster(struct bolt &beam, struct monsters *mon)
{
const int tid = mgrd[mon->x][mon->y];
const int mons_type = menv[tid].type;
+ const int thrower = YOU_KILL(beam.thrower)? KILL_YOU_MISSILE
+ : KILL_MON_MISSILE;
+
int hurt;
int hurt_final;
@@ -3315,6 +3319,28 @@ static int affect_monster(struct bolt &beam, struct monsters *mon)
return 0;
}
}
+ else if ((beam.flavour == BEAM_DISINTEGRATION || beam.flavour == BEAM_NUKE)
+ && mons_is_statue(mons_type))
+ {
+ if (!silenced(you.x_pos, you.y_pos))
+ {
+ if (!see_grid( mon->x, mon->y ))
+ mpr("You hear a hideous screaming!", MSGCH_SOUND);
+ else
+ mpr("The statue screams as its substance crumbles away!",
+ MSGCH_SOUND);
+ }
+ else
+ {
+ if (see_grid( mon->x, mon->y ))
+ mpr("The statue twists and shakes as its substance "
+ "crumbles away!");
+ }
+ beam.obvious_effect = true;
+ mon->hit_points = 0;
+ monster_die(mon, thrower, beam.beam_source);
+ return (BEAM_STOP);
+ }
if (beam.name[0] == '0')
{
@@ -3525,8 +3551,6 @@ static int affect_monster(struct bolt &beam, struct monsters *mon)
// now hurt monster
hurt_monster( mon, hurt_final );
- int thrower = YOU_KILL(beam.thrower) ? KILL_YOU_MISSILE : KILL_MON_MISSILE;
-
if (mon->hit_points < 1)
{
monster_die(mon, thrower, beam.beam_source);
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index 43c6653845..c139140db4 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -6148,6 +6148,16 @@ void describe_monsters(int class_described, unsigned char which_mons)
"covered in thick red scales and thorns.";
break;
+ case MONS_ORANGE_STATUE:
+ description += "An intricately carved statue of glittering orange "
+ "crystal. Its eyes fix on yours with a piercing gaze.";
+ break;
+
+ case MONS_SILVER_STATUE:
+ description += "A beautiful filigreed statue of silver. Its eyes "
+ "glow with an otherworldly radiance.";
+ break;
+
case MONS_PROGRAM_BUG:
default:
description += "If this monster is a \"program bug\", then it's "
diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc
index a3706fa9fe..65e6d2cdb5 100644
--- a/crawl-ref/source/direct.cc
+++ b/crawl-ref/source/direct.cc
@@ -1382,7 +1382,8 @@ static void describe_cell(int mx, int my)
if (mons_is_mimic( menv[i].type ))
mimic_item = true;
- else if (!mons_class_flag(menv[i].type, M_NO_EXP_GAIN))
+ else if (!mons_class_flag(menv[i].type, M_NO_EXP_GAIN)
+ && !mons_is_statue(menv[i].type))
{
if (menv[i].behaviour == BEH_SLEEP)
{
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index f210d817e0..2cf8c88e3d 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -5605,7 +5605,8 @@ static int vault_grid( int level_number, int vx, int vy, int altar_count,
int not_used;
// first, set base tile for grids {dlb}:
- grd[vx][vy] = ((vgrid == 'x') ? DNGN_ROCK_WALL :
+ const int grid =
+ grd[vx][vy] = ((vgrid == 'x') ? DNGN_ROCK_WALL :
(vgrid == 'X') ? DNGN_PERMAROCK_WALL :
(vgrid == 'c') ? DNGN_STONE_WALL :
(vgrid == 'v') ? DNGN_METAL_WALL :
@@ -5742,6 +5743,19 @@ static int vault_grid( int level_number, int vx, int vy, int altar_count,
break;
}
+ if (grid == DNGN_ORANGE_CRYSTAL_STATUE
+ || grid == DNGN_SILVER_STATUE)
+ {
+ const int mtype =
+ grid == DNGN_ORANGE_CRYSTAL_STATUE? MONS_ORANGE_STATUE
+ : MONS_SILVER_STATUE;
+
+ grd[vx][vy] = DNGN_FLOOR;
+
+ place_monster( not_used, mtype, 30, BEH_HOSTILE,
+ MHITNOT, true, vx, vy, false);
+ }
+
// finally, handle grids that place monsters {dlb}:
if (vgrid >= '0' && vgrid <= '9')
{
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 3e49122b01..5ffe7351be 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -2248,6 +2248,10 @@ enum monster_type // (int) menv[].type
MONS_WATER_ELEMENTAL,
MONS_SWAMP_WORM, // 435
+ // Statuary
+ MONS_ORANGE_STATUE,
+ MONS_SILVER_STATUE,
+
NUM_MONSTERS, // used for polymorph
RANDOM_MONSTER = 1000, // used to distinguish between a random monster and using program bugs for error trapping {dlb}
WANDERING_MONSTER = 2500 // only used in monster placement routines - forced limit checks {dlb}
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index 76ceafd748..48444db55e 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -451,7 +451,8 @@ bool you_attack(int monster_attacked, bool unarmed_attacks)
* *
**************************************************************************
*/
- bool helpless = mons_class_flag(defender->type, M_NO_EXP_GAIN);
+ bool helpless = mons_class_flag(defender->type, M_NO_EXP_GAIN)
+ || mons_is_statue(defender->type);
if (mons_friendly(defender))
did_god_conduct(DID_ATTACK_FRIEND, 5);
diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h
index c7ff09a8ea..45711ded9d 100644
--- a/crawl-ref/source/mon-data.h
+++ b/crawl-ref/source/mon-data.h
@@ -4390,4 +4390,28 @@ not think it fits into Crawl ... {dlb}
}
,
+{
+ MONS_ORANGE_STATUE, '8', LIGHTRED, "orange crystal statue",
+ M_SPECIAL_ABILITY,
+ MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
+ 0, 10, MONS_CLAY_GOLEM, MONS_ORANGE_STATUE, MH_NONLIVING, 5000,
+ { 0, 0, 0, 0 },
+ { 3, 50, 30, 120 },
+ 30, 3, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH,
+ MONUSE_NOTHING
+}
+,
+
+{
+ MONS_SILVER_STATUE, '8', WHITE, "silver statue",
+ M_SPECIAL_ABILITY,
+ MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
+ 0, 10, MONS_CLAY_GOLEM, MONS_SILVER_STATUE, MH_NONLIVING, 5000,
+ { 0, 0, 0, 0 },
+ { 3, 50, 0, 120 },
+ 30, 3, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH,
+ MONUSE_NOTHING
+}
+,
+
#endif
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 5aa8142652..a2400b89b1 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -316,6 +316,7 @@ bool mons_class_is_stationary(int type)
|| type == MONS_PLANT
|| type == MONS_FUNGUS
|| type == MONS_CURSE_SKULL
+ || mons_is_statue(type)
|| mons_is_mimic(type));
}
@@ -337,6 +338,11 @@ bool invalid_monster_class(int mclass)
|| mon_entry[mclass] == MONS_PROGRAM_BUG);
}
+bool mons_is_statue(int mc)
+{
+ return (mc == MONS_ORANGE_STATUE || mc == MONS_SILVER_STATUE);
+}
+
bool mons_is_mimic( int mc )
{
return (mons_species( mc ) == MONS_GOLD_MIMIC);
@@ -891,6 +897,11 @@ int exper_value( const struct monsters *monster )
if (mons_class_flag(mclass, M_NO_EXP_GAIN))
return (0);
+ // no experience for destroying furniture, even if the furniture started
+ // the fight.
+ if (mons_is_statue(mclass))
+ return (0);
+
// These undead take damage to maxhp, so we use only HD. -- bwr
if (mclass == MONS_ZOMBIE_SMALL
|| mclass == MONS_ZOMBIE_LARGE
@@ -1623,6 +1634,7 @@ bool mons_looks_stabbable(const monsters *m)
return (!mons_class_flag(m->type, M_NO_EXP_GAIN)
&& m->type != MONS_OKLOB_PLANT
&& !mons_is_mimic(m->type)
+ && !mons_is_statue(m->type)
&& !mons_friendly(m)
&& mons_is_sleeping(m));
}
@@ -1632,6 +1644,7 @@ bool mons_looks_distracted(const monsters *m)
return (!mons_class_flag(m->type, M_NO_EXP_GAIN)
&& m->type != MONS_OKLOB_PLANT
&& !mons_is_mimic(m->type)
+ && !mons_is_statue(m->type)
&& !mons_friendly(m)
&& ((m->foe != MHITYOU && !mons_is_batty(m))
|| mons_is_confused(m)
diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h
index b5e0109dfb..ea56bfe14c 100644
--- a/crawl-ref/source/mon-util.h
+++ b/crawl-ref/source/mon-util.h
@@ -223,7 +223,8 @@ mon_holy_type mons_class_holiness(int mclass);
mon_holy_type mons_holiness(const monsters *);
bool mons_is_mimic( int mc );
-bool mons_is_demon( int mc );
+bool mons_is_statue(int mc);
+bool mons_is_demon( int mc );
bool mons_is_humanoid( int mc );
diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc
index 1a45ff6bff..98bb07551d 100644
--- a/crawl-ref/source/monplace.cc
+++ b/crawl-ref/source/monplace.cc
@@ -579,6 +579,10 @@ static int place_monster_aux( int mon_type, char behaviour, int target,
// set attitude, behaviour and target
menv[id].attitude = ATT_HOSTILE;
menv[id].behaviour = behaviour;
+
+ if (mon_type == MONS_ORANGE_STATUE || mon_type == MONS_SILVER_STATUE)
+ menv[id].behaviour = BEH_WANDER;
+
menv[id].foe_memory = 0;
// setting attitude will always make the
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 1ad69266c0..013fe39d0e 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -2344,6 +2344,14 @@ static bool handle_special_ability(struct monsters *monster, bolt & beem)
switch (mclass)
{
+ case MONS_ORANGE_STATUE:
+ used = orange_statue_effects(monster);
+ break;
+
+ case MONS_SILVER_STATUE:
+ used = silver_statue_effects(monster);
+ break;
+
case MONS_BALL_LIGHTNING:
if (monster->attitude == ATT_HOSTILE
&& distance( you.x_pos, you.y_pos, monster->x, monster->y ) <= 5)
@@ -5215,6 +5223,9 @@ bool hurt_monster(struct monsters * victim, int damage_dealt)
bool heal_monster(struct monsters * patient, int health_boost,
bool permit_growth)
{
+ if (mons_is_statue(patient->type))
+ return (false);
+
if (health_boost < 1)
return (false);
else if (!permit_growth && patient->hit_points == patient->max_hit_points)
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index 9f3682ac0a..c47363ad7d 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -1837,3 +1837,39 @@ static unsigned char monster_abjuration(int pow, bool test)
return result;
} // end monster_abjuration()
+
+bool silver_statue_effects(monsters *mons)
+{
+ if ((mons_player_visible(mons) || one_chance_in(3))
+ && !one_chance_in(3))
+ {
+ char wc[30];
+
+ weird_colours( random2(256), wc );
+ snprintf(info, INFO_SIZE, "'s eyes glow %s.", wc);
+ simple_monster_message(mons, info, MSGCH_WARN);
+
+ create_monster( summon_any_demon((coinflip() ? DEMON_COMMON
+ : DEMON_LESSER)),
+ ENCH_ABJ_V, BEH_HOSTILE,
+ you.x_pos, you.y_pos,
+ MHITYOU, 250 );
+ return (true);
+ }
+ return (false);
+}
+
+bool orange_statue_effects(monsters *mons)
+{
+ if ((mons_player_visible(mons) || one_chance_in(3))
+ && !one_chance_in(3))
+ {
+ mpr("A hostile presence attacks your mind!", MSGCH_WARN);
+
+ miscast_effect( SPTYP_DIVINATION, random2(15), random2(150), 100,
+ "an orange crystal statue" );
+ return (true);
+ }
+
+ return (false);
+}
diff --git a/crawl-ref/source/mstuff2.h b/crawl-ref/source/mstuff2.h
index d7bdc0dc5a..aedb2cdcd0 100644
--- a/crawl-ref/source/mstuff2.h
+++ b/crawl-ref/source/mstuff2.h
@@ -100,5 +100,7 @@ void throw_type(int lnchClass, int lnchType, int wepClass, int wepType,
bool &launched, bool &thrown);
+bool orange_statue_effects(monsters *mons);
+bool silver_statue_effects(monsters *mons);
#endif
diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc
index 1c665cec12..4f005c81ac 100644
--- a/crawl-ref/source/spells4.cc
+++ b/crawl-ref/source/spells4.cc
@@ -191,6 +191,7 @@ static int shatter_monsters(int x, int y, int pow, int garbage)
case MONS_ICE_BEAST: // 3/2 damage
case MONS_SIMULACRUM_SMALL:
case MONS_SIMULACRUM_LARGE:
+ case MONS_SILVER_STATUE:
dam_dice.num = 4;
break;
@@ -201,6 +202,7 @@ static int shatter_monsters(int x, int y, int pow, int garbage)
case MONS_STONE_GOLEM:
case MONS_IRON_GOLEM:
case MONS_CRYSTAL_GOLEM:
+ case MONS_ORANGE_STATUE:
case MONS_EARTH_ELEMENTAL:
case MONS_GARGOYLE:
case MONS_SKELETAL_DRAGON:
@@ -2476,6 +2478,27 @@ void cast_fragmentation(int pow) // jmf: ripped idea from airstrike
blast.damage.num += 1;
break;
+ case MONS_SILVER_STATUE:
+ case MONS_ORANGE_STATUE:
+ explode = true;
+ blast.ex_size = 2;
+ if (menv[mon].type == MONS_SILVER_STATUE)
+ {
+ blast.name = "blast of silver fragments";
+ blast.colour = WHITE;
+ blast.damage.num = 3;
+ }
+ else
+ {
+ blast.name = "blast of orange crystal shards";
+ blast.colour = LIGHTRED;
+ blast.damage.num = 6;
+ }
+
+ if (player_hurt_monster(mon, roll_dice( blast.damage )))
+ blast.damage.num += 2;
+ break;
+
case MONS_CRYSTAL_GOLEM:
explode = true;
blast.ex_size = 2;
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 38bec13fb2..6ede62ba02 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -301,15 +301,6 @@ static void get_symbol( unsigned int object, unsigned short *ch,
// Note anything we see that's notable
if (Feature[object].notable)
seen_notable_thing( object );
-
- // These effects apply every turn when in sight however.
- if (Feature[object].seen_effect)
- {
- if (object == DNGN_SILVER_STATUE)
- you.visible_statue[ STATUE_SILVER ] = 1;
- else if (object == DNGN_ORANGE_CRYSTAL_STATUE)
- you.visible_statue[ STATUE_ORANGE_CRYSTAL ] = 1;
- }
}
else
{