From 84d24b72b573becc9cfed52b423c4c9da8180456 Mon Sep 17 00:00:00 2001 From: dshaligram Date: Thu, 9 Nov 2006 18:19:00 +0000 Subject: [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 --- crawl-ref/source/acr.cc | 40 ---------------------------------------- crawl-ref/source/beam.cc | 30 +++++++++++++++++++++++++++--- crawl-ref/source/describe.cc | 10 ++++++++++ crawl-ref/source/direct.cc | 3 ++- crawl-ref/source/dungeon.cc | 16 +++++++++++++++- crawl-ref/source/enum.h | 4 ++++ crawl-ref/source/fight.cc | 3 ++- crawl-ref/source/mon-data.h | 24 ++++++++++++++++++++++++ crawl-ref/source/mon-util.cc | 13 +++++++++++++ crawl-ref/source/mon-util.h | 3 ++- crawl-ref/source/monplace.cc | 4 ++++ crawl-ref/source/monstuff.cc | 11 +++++++++++ crawl-ref/source/mstuff2.cc | 36 ++++++++++++++++++++++++++++++++++++ crawl-ref/source/mstuff2.h | 2 ++ crawl-ref/source/spells4.cc | 23 +++++++++++++++++++++++ crawl-ref/source/view.cc | 9 --------- 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 { -- cgit v1.2.3-54-g00ecf