diff options
author | DShaligram <DShaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-08-14 09:40:23 +0000 |
---|---|---|
committer | DShaligram <DShaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-08-14 09:40:23 +0000 |
commit | aa6e0f9a964e4aeb51e4b4a2b3e22d594a51f78d (patch) | |
tree | b636bf690fea6c82524e95108c3803b848ad63f6 | |
parent | b61d9eecfd8170f21e310a53f40361ea6359f917 (diff) | |
download | crawl-ref-aa6e0f9a964e4aeb51e4b4a2b3e22d594a51f78d.tar.gz crawl-ref-aa6e0f9a964e4aeb51e4b4a2b3e22d594a51f78d.zip |
First merge of Crawl 4.1.2 features into Stone Soup:
* Enhancer staves boost spell power only, not success rates
* Chain lightning is in at level 8, replaces orb of electrocution in
Annihilations.
* Spell levels changed: borgnor's (5), shadow creatures (6), silence
(5), simulacrum (6), Controlled Blink (8). I haven't rearranged
spellbooks in spell level order yet.
* Sif Muna appreciates spell skill training, not mere spellcasting (untested)
* Detect creatures is inaccurate, map is cleared before DC acts.
* The Shining One no longer cuts up rough about his Daevas dying.
* Rods are weaker. More on this below.
* Shields are mildly better in combat and ranged-attack-blocking, and
get a fuller range of brands. Needs more work.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup@16 c06c8d41-db1a-0410-9941-cceddc491573
63 files changed, 2709 insertions, 1394 deletions
diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc index 64a1c10e74..dc992da89a 100644 --- a/crawl-ref/source/abl-show.cc +++ b/crawl-ref/source/abl-show.cc @@ -906,7 +906,8 @@ bool activate_ability(void) break; case ABIL_KIKU_INVOKE_DEATH: - summon_ice_beast_etc(20 + you.skills[SK_INVOCATIONS] * 3, MONS_REAPER); + summon_ice_beast_etc( + 20 + you.skills[SK_INVOCATIONS] * 3, MONS_REAPER, true); exercise(SK_INVOCATIONS, 10 + random2(14)); break; diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index d736658d9e..953ed0d1a1 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -841,6 +841,61 @@ static bool check_stop_running( void ) return (false); } +static bool recharge_rod( item_def &rod, bool wielded ) +{ + if (!item_is_rod(rod) || rod.plus >= rod.plus2 || !enough_mp(1, true)) + return (false); + + const int charge = rod.plus / ROD_CHARGE_MULT; + + int rate = ((charge + 1) * ROD_CHARGE_MULT) / 10; + + rate *= (10 + skill_bump( SK_EVOCATIONS )); + rate = div_rand_round( rate, 100 ); + + if (rate < 5) + rate = 5; + else if (rate > ROD_CHARGE_MULT / 2) + rate = ROD_CHARGE_MULT / 2; + + // If not wielded, the rod charges far more slowly. + if (!wielded) + rate /= 3; + + if (rod.plus / ROD_CHARGE_MULT != (rod.plus + rate) / ROD_CHARGE_MULT) + { + dec_mp(1); + if (wielded) + you.wield_change = true; + } + + rod.plus += rate; + if (rod.plus > rod.plus2) + rod.plus = rod.plus2; + + if (wielded && rod.plus == rod.plus2 && is_resting()) + stop_running(); + + return (true); +} + +static void recharge_rods() +{ + const int wielded = you.equip[EQ_WEAPON]; + if (wielded != -1) + { + if (recharge_rod( you.inv[wielded], true )) + return ; + } + + for (int i = 0; i < ENDOFPACK; ++i) + { + if (i != wielded && is_valid_item(you.inv[i]) + && one_chance_in(3) + && recharge_rod( you.inv[i], false )) + return; + } +} /* This function handles the player's input. It's called from main(), from @@ -2139,7 +2194,7 @@ static void input(void) you.berserker = 0; //jmf: guilty for berserking /after/ berserk - naughty( NAUGHTY_STIMULANTS, 6 + random2(6) ); + did_god_conduct( DID_STIMULANTS, 6 + random2(6) ); // // Sometimes berserk leaves us physically drained @@ -2382,6 +2437,9 @@ static void input(void) ASSERT( tmp >= 0 && tmp < 100 ); you.magic_points_regeneration = static_cast< unsigned char >( tmp ); + // If you're wielding a rod, it'll gradually recharge. + recharge_rods(); + viewwindow(1, true); handle_monsters(); diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index afcbd0445b..669ba62e86 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -1164,15 +1164,17 @@ void fire_beam( struct bolt &pbolt, item_def *item ) bool sideBlocked, topBlocked, random_beam; #if DEBUG_DIAGNOSTICS - snprintf( info, INFO_SIZE, "%s%s (%d,%d) to (%d,%d): ty=%d col=%d flav=%d hit=%d dam=%dd%d", - (pbolt.isBeam) ? "beam" : "missile", - (pbolt.isTracer) ? " tracer" : "", - pbolt.source_x, pbolt.source_y, - pbolt.target_x, pbolt.target_y, - pbolt.type, pbolt.colour, pbolt.flavour, - pbolt.hit, pbolt.damage.num, pbolt.damage.size ); - - mpr( info, MSGCH_DIAGNOSTICS ); + if (pbolt.flavour != BEAM_LINE_OF_SIGHT) + { + mprf( MSGCH_DIAGNOSTICS, + "%s%s (%d,%d) to (%d,%d): ty=%d col=%d flav=%d hit=%d dam=%dd%d", + (pbolt.isBeam) ? "beam" : "missile", + (pbolt.isTracer) ? " tracer" : "", + pbolt.source_x, pbolt.source_y, + pbolt.target_x, pbolt.target_y, + pbolt.type, pbolt.colour, pbolt.flavour, + pbolt.hit, pbolt.damage.num, pbolt.damage.size ); + } #endif // init @@ -2031,10 +2033,7 @@ void poison_monster( struct monsters *monster, bool fromPlayer, int levels, // finally, take care of deity preferences if (fromPlayer) - { - naughty(NAUGHTY_POISON, 5 + random2(3)); //jmf: TSO now hates poison - done_good(GOOD_POISON, 5); //jmf: had test god who liked poison - } + did_god_conduct( DID_POISON, 5 + random2(3) ); } // end poison_monster() // actually napalms a monster (w/ message) @@ -2144,6 +2143,56 @@ void fire_tracer(struct monsters *monster, struct bolt &pbolt) pbolt.isTracer = false; } // end tracer_f() +bool check_line_of_sight( int sx, int sy, int tx, int ty ) +{ + struct bolt pbolt; + + const int dist = grid_distance( sx, sy, tx, ty ); + + // can always see one square away + if (dist <= 1) + return (true); + + // currently we limit the range to 8 + if (dist > MONSTER_LOS_RANGE) + return (false); + + // Redirect player centered LoS to the old method (using display table)... + // note that this assumes that viewwindow() has been called if needed + // before we get here (ie this won't work very well if this function gets + // called between moving the player and updating the display). + if (sx == you.x_pos && sy == you.y_pos) + return (see_grid( tx, ty )); + else if (tx == you.x_pos && ty == you.y_pos) + return (see_grid( sx, sy )); + + // Okay, no easy way... set up a LoS beam between the points + pbolt.flavour = BEAM_LINE_OF_SIGHT; + pbolt.isTracer = true; + pbolt.source_x = sx; + pbolt.source_y = sy; + pbolt.target_x = tx; + pbolt.target_y = ty; + pbolt.range = MONSTER_LOS_RANGE; + pbolt.rangeMax = MONSTER_LOS_RANGE; + + // setting these just to be safe: + pbolt.hit = 0; + pbolt.type = 0; + pbolt.damage = dice_def( 0, 1 ); + pbolt.colour = BLACK; + pbolt.isBeam = true; + + // init tracer variables (used to tell if we "hit" the target) + pbolt.foe_count = pbolt.fr_count = 0; + pbolt.foe_power = pbolt.fr_power = 0; + + // fire! + fire_beam( pbolt ); + + // got to target? + return (pbolt.foe_count == 1); +} /* When a mimic is hit by a ranged attack, it teleports away (the slow way) @@ -2269,6 +2318,11 @@ static void beam_explodes(struct bolt &beam, int x, int y) static bool beam_term_on_target(struct bolt &beam) { + if (beam.flavour == BEAM_LINE_OF_SIGHT) + { + beam.foe_count++; + return (true); + } // generic - all explosion-type beams can be targetted at empty space, // and will explode there. This semantic also means that a creature @@ -2485,6 +2539,10 @@ static int affect(struct bolt &beam, int x, int y) // extra range used by hitting something int rangeUsed = 0; + // line of sight never affects anything + if (beam.flavour == BEAM_LINE_OF_SIGHT) + return (0); + if (grd[x][y] < MINMOVE) { if (beam.isTracer) // tracers always stop on walls. @@ -2578,7 +2636,7 @@ static int affect_wall(struct bolt &beam, int x, int y) { if (!silenced(you.x_pos, you.y_pos)) { - mpr("You hear a grinding noise."); + mpr("You hear a grinding noise.", MSGCH_SOUND); beam.obviousEffect = true; } @@ -2601,7 +2659,7 @@ static int affect_wall(struct bolt &beam, int x, int y) grd[ x ][ y ] = DNGN_FLOOR; if (!silenced(you.x_pos, you.y_pos)) { - mpr("You hear a grinding noise."); + mpr("You hear a grinding noise.", MSGCH_SOUND); beam.obviousEffect = true; } } @@ -2614,9 +2672,10 @@ static int affect_wall(struct bolt &beam, int x, int y) if (!silenced(you.x_pos, you.y_pos)) { if (!see_grid( x, y )) - mpr("You hear a hideous screaming!"); + mpr("You hear a hideous screaming!", MSGCH_SOUND); else - mpr("The statue screams as its substance crumbles away!"); + mpr("The statue screams as its substance crumbles away!", + MSGCH_SOUND); } else { @@ -2673,7 +2732,7 @@ static int affect_place_clouds(struct bolt &beam, int x, int y) if (!silenced(x, y) && !silenced(you.x_pos, you.y_pos)) { - mpr("You hear a sizzling sound!"); + mpr("You hear a sizzling sound!", MSGCH_SOUND); } delete_cloud( clouty ); @@ -2982,11 +3041,14 @@ static int affect_player( struct bolt &beam ) && player_shield_class() > 0) { int exer = one_chance_in(3) ? 1 : 0; - const int hit = random2( beam.hit * 5 - + 10 * you.shield_blocks * you.shield_blocks ); + // [dshaligram] beam.hit multiplier lowererd to 3 - was 5. + // In favour of blocking, dex multiplier changed to .5 + // (was .2). + const int hit = random2( beam.hit * 3 + + 10 * you.shield_blocks * you.shield_blocks ); const int block = random2(player_shield_class()) - + (random2(you.dex) / 5) - 1; + + (random2(you.dex) / 2) - 1; if (hit < block) { @@ -3256,6 +3318,13 @@ static int affect_player( struct bolt &beam ) return (range_used_on_hit( beam )); } +static int beam_source(const bolt &beam) +{ + return MON_KILL(beam.thrower) ? beam.beam_source : + beam.thrower == KILL_MISC ? MHITNOT : + MHITYOU; +} + // return amount of range used up by affectation of this monster static int affect_monster(struct bolt &beam, struct monsters *mon) { @@ -3310,16 +3379,20 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) // naughty (even if a monster might resist) if (nasty_beam(mon, beam)) { - if (mons_friendly(mon) && YOU_KILL(beam.thrower)) - naughty(NAUGHTY_ATTACK_FRIEND, 5); + if (YOU_KILL( beam.thrower )) + { + if (mons_friendly( mon )) + did_god_conduct( DID_ATTACK_FRIEND, 5 ); - behaviour_event( mon, ME_ANNOY, - MON_KILL(beam.thrower) ? beam.beam_source : MHITYOU ); + if (mons_holiness( mon ) == MH_HOLY) + did_god_conduct( DID_ATTACK_HOLY, mon->hit_dice ); + } + + behaviour_event( mon, ME_ANNOY, beam_source(beam) ); } else { - behaviour_event( mon, ME_ALERT, - MON_KILL(beam.thrower) ? beam.beam_source : MHITYOU ); + behaviour_event( mon, ME_ALERT, beam_source(beam) ); } // !@#*( affect_monster_enchantment() has side-effects on @@ -3432,20 +3505,28 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) if (nasty_beam(mon, beam)) { - // could be naughty if it's your beam & the montster is friendly - if (mons_friendly(mon) && YOU_KILL(beam.thrower)) + bool annoyed = false; + + if (YOU_KILL(beam.thrower)) { - // but did you do enough damage to piss them off? - if (hurt_final > mon->hit_dice / 3) + if (mons_friendly(mon)) + { + did_god_conduct( DID_ATTACK_FRIEND, 5 ); + if (hurt_final > mon->hit_dice / 3) + annoyed = true; + } + else { - naughty(NAUGHTY_ATTACK_FRIEND, 5); - behaviour_event( mon, ME_ANNOY, MHITYOU ); + annoyed = true; } + + if (mons_holiness( mon ) == MH_HOLY) + did_god_conduct( DID_ATTACK_HOLY, mon->hit_dice ); } - else + + if (annoyed) { - behaviour_event(mon, ME_ANNOY, - MON_KILL(beam.thrower) ? beam.beam_source : MHITYOU ); + behaviour_event(mon, ME_ANNOY, beam_source(beam) ); } } @@ -3490,7 +3571,7 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) strcpy(info, "The "); strcat(info, beam.beam_name); strcat(info, " hits something."); - mpr(info); + mpr(info, MSGCH_SOUND); } } @@ -3943,7 +4024,7 @@ static void explosion1(struct bolt &pbolt) else { if (!(silenced(x,y) || silenced(you.x_pos, you.y_pos))) - mpr(hearMsg); + mpr(hearMsg, MSGCH_SOUND); else pbolt.msgGenerated = false; } diff --git a/crawl-ref/source/beam.h b/crawl-ref/source/beam.h index d2935843ec..503220db44 100644 --- a/crawl-ref/source/beam.h +++ b/crawl-ref/source/beam.h @@ -82,6 +82,7 @@ void place_cloud(unsigned char cl_type, unsigned char ctarget_x, unsigned char c * *********************************************************************** */ void fire_tracer( struct monsters *monster, struct bolt &pbolt ); +bool check_line_of_sight( int sx, int sy, int tx, int ty ); /* *********************************************************************** * called from: monstuff diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index 8bfdb776d8..eb77956909 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -972,6 +972,14 @@ void create_spec_object(void) mitm[thing_created].plus = 24; break; + case OBJ_STAVES: + if (item_is_rod( mitm[thing_created] )) + { + mitm[thing_created].plus = MAX_ROD_CHARGE * ROD_CHARGE_MULT; + mitm[thing_created].plus2 = MAX_ROD_CHARGE * ROD_CHARGE_MULT; + } + break; + case OBJ_MISCELLANY: // Runes to "demonic", decks have 50 cards, ignored elsewhere? mitm[thing_created].plus = 50; diff --git a/crawl-ref/source/decks.cc b/crawl-ref/source/decks.cc index 5f958b0512..47a74106be 100644 --- a/crawl-ref/source/decks.cc +++ b/crawl-ref/source/decks.cc @@ -224,7 +224,7 @@ void deck_of_cards(unsigned char which_deck) unsigned char *card = deck_of_wonders; unsigned char max_card = 0; int i = 0; - int brownie_points = 0; // for passing to done_good() {dlb} + int brownie_points = 0; // for passing to did_god_conduct() {dlb} mpr("You draw a card..."); @@ -292,7 +292,7 @@ void deck_of_cards(unsigned char which_deck) if (which_deck == DECK_OF_WONDERS || one_chance_in(3)) brownie_points++; - done_good(GOOD_CARDS, brownie_points); + did_god_conduct(DID_CARDS, brownie_points); } return; diff --git a/crawl-ref/source/defines.h b/crawl-ref/source/defines.h index dbb079a458..d7c28980d8 100644 --- a/crawl-ref/source/defines.h +++ b/crawl-ref/source/defines.h @@ -76,6 +76,17 @@ // lowest grid value which can be seen through #define MINSEE 11 +// This value is used to make test_hit checks always succeed +#define AUTOMATIC_HIT 1500 + +// grids that monsters can see +#define MONSTER_LOS_RANGE 8 + +// Maximum charge level for rods +#define MAX_ROD_CHARGE 17 +#define ROD_CHARGE_MULT 100 + +#define NUM_STAVE_ADJ 9 // some shortcuts: #define menv env.mons diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index 173e9b0ed4..95ea53b45d 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -962,6 +962,10 @@ static std::string describe_weapon( const item_def &item, char verbose) "A terrible weapon, forged in the fires of Hell. "; break; + case WPN_BLESSED_BLADE: + description += "A blade blessed by the Shining One. "; + break; + case WPN_DEMON_WHIP: description += "A terrible weapon, woven " "in the depths of the inferno. "; @@ -2845,11 +2849,12 @@ static std::string describe_staff( const item_def &item ) description += "allows its wielder to smite foes from afar. The wielder " "must be at least level four to safely use this ability, " - "which costs 4 magic points. "; + "which drains four charges. "; break; case STAFF_STRIKING: - description += "allows its wielder to strike foes from afar. "; + description += "allows its wielder to strike foes from afar " + "with force bolts. "; break; case STAFF_SPELL_SUMMONING: @@ -2893,8 +2898,11 @@ static std::string describe_staff( const item_def &item ) if (item_is_rod( item )) { - description += - "Casting a spell from it consumes no food, and will not fail.$"; + if (item.sub_type != STAFF_STRIKING) + description += + "$$It uses its own mana reservoir for casting spells, and " + "recharges automatically by channeling mana from its " + "wielder."; } else { @@ -4371,6 +4379,11 @@ void describe_spell(int spelled) "can be difficult to control. "; break; + case SPELL_CHAIN_LIGHTNING: + description += "releases a massive electrical discharge that " + "arcs from target to target until it grounds out."; + break; + case SPELL_TWIST: description += "causes a slight spatial distortion around a monster " "in line of sight of the caster, causing injury. "; @@ -6062,7 +6075,7 @@ void describe_monsters(int class_described, unsigned char which_mons) #if DEBUG_DIAGNOSTICS - if (mons_flag( menv[ which_mons ].type, M_SPELLCASTER )) + if (mons_class_flag( menv[ which_mons ].type, M_SPELLCASTER )) { int hspell_pass[6] = { MS_NO_SPELL, MS_NO_SPELL, MS_NO_SPELL, MS_NO_SPELL, MS_NO_SPELL, MS_NO_SPELL }; diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc index 911ccc8522..cab6fc74fa 100644 --- a/crawl-ref/source/direct.cc +++ b/crawl-ref/source/direct.cc @@ -688,7 +688,7 @@ static bool find_monster( int x, int y, int mode ) && !mons_friendly( &menv[targ_mon] ) && (Options.target_zero_exp || - !mons_flag( menv[targ_mon].type, M_NO_EXP_GAIN )) ))); + !mons_class_flag( menv[targ_mon].type, M_NO_EXP_GAIN )) ))); } static bool find_feature( int x, int y, int mode ) @@ -1343,7 +1343,7 @@ static void describe_cell(int mx, int my) if (mons_is_mimic( menv[i].type )) mimic_item = true; - else if (!mons_flag(menv[i].type, M_NO_EXP_GAIN)) + else if (!mons_class_flag(menv[i].type, M_NO_EXP_GAIN)) { if (menv[i].behaviour == BEH_SLEEP) { diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index a18ab7c726..d7d51abacb 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -157,6 +157,22 @@ static void place_altar(void); ************************************************** */ +// Determines if this feature blocks movement. +bool feat_blocks_movement(int feature) +{ + return (feature == DNGN_ROCK_WALL || + feature == DNGN_STONE_WALL || + feature == DNGN_METAL_WALL || + feature == DNGN_SECRET_DOOR || + feature == DNGN_GREEN_CRYSTAL_WALL || + feature == DNGN_ORCISH_IDOL || + feature == DNGN_WAX_WALL || + feature == DNGN_PERMAROCK_WALL || + feature == DNGN_SILVER_STATUE || + feature == DNGN_GRANITE_STATUE || + feature == DNGN_ORANGE_CRYSTAL_STATUE); +} + void builder(int level_number, char level_type) { int i; // generic loop variable @@ -1173,6 +1189,10 @@ int items( int allow_uniques, // not just true-false, set_weapon_special(p, SPWPN_VENOM); break; + case WPN_BLESSED_BLADE: // special gift of TSO + set_weapon_special( p, SPWPN_HOLY_WRATH ); + break; + // unlisted weapons have no associated, standard ego-types {dlb} default: break; @@ -1629,10 +1649,19 @@ int items( int allow_uniques, // not just true-false, case ARM_SHIELD: // shield - must do special things for this! case ARM_LARGE_SHIELD: case ARM_BUCKLER: - set_item_ego_type( mitm[p], OBJ_ARMOUR, SPARM_PROTECTION ); + { + const int tmp = random2(1000); + + set_item_ego_type( mitm[p], OBJ_ARMOUR, + (tmp < 40) ? SPARM_RESISTANCE : + (tmp < 160) ? SPARM_FIRE_RESISTANCE : + (tmp < 280) ? SPARM_COLD_RESISTANCE : + (tmp < 400) ? SPARM_POISON_RESISTANCE : + (tmp < 520) ? SPARM_POSITIVE_ENERGY + : SPARM_PROTECTION ); break; // prot //break; - + } case ARM_CLOAK: if (cmp_equip_race( mitm[p], ISFLAG_DWARVEN )) break; @@ -2339,7 +2368,14 @@ int items( int allow_uniques, // not just true-false, } } - mitm[p].special = random2(9); + mitm[p].special = random2(NUM_STAVE_ADJ); + + if (item_is_rod( mitm[p] )) + { + mitm[p].plus2 = (9 + random2( MAX_ROD_CHARGE - 8 )) + * ROD_CHARGE_MULT; + mitm[p].plus = mitm[p].plus2; + } quant = 1; break; @@ -2893,7 +2929,7 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes mitm[bp].base_type = OBJ_WEAPONS; mitm[bp].colour = WHITE; // forced by force_item above {dlb} - mitm[bp].sub_type = (one_chance_in(4) ? WPN_GREAT_SWORD + mitm[bp].sub_type = (one_chance_in(4) ? WPN_BLESSED_BLADE : WPN_LONG_SWORD); set_equip_desc( mitm[bp], ISFLAG_GLOWING ); @@ -6357,6 +6393,7 @@ static char rare_weapon(unsigned char w_type) case WPN_KNIFE: case WPN_QUICK_BLADE: case WPN_TRIPLE_SWORD: + case WPN_BLESSED_BLADE: return 0; default: diff --git a/crawl-ref/source/dungeon.h b/crawl-ref/source/dungeon.h index dedd41ae68..2da0e50a0c 100644 --- a/crawl-ref/source/dungeon.h +++ b/crawl-ref/source/dungeon.h @@ -19,6 +19,8 @@ void item_colour( item_def &item ); +bool feat_blocks_movement(int feature); + // last updated 12may2000 {dlb} /* *********************************************************************** * called from: files @@ -46,4 +48,6 @@ void give_item(int mid, int level_number); * *********************************************************************** */ void define_zombie(int mid, int ztype, int cs, int power); +bool is_wall(int feature); + #endif diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index 16517cba40..6fd208d562 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -471,23 +471,23 @@ bool acquirement(unsigned char force_class, int agent) //mpr("[r|R] - Just give me something good."); mpr("What kind of item would you like to acquire? ", MSGCH_PROMPT); - keyin = get_ch(); + keyin = tolower( get_ch() ); - if (keyin == 'a' || keyin == 'A') + if (keyin == 'a') class_wanted = OBJ_WEAPONS; - else if (keyin == 'b' || keyin == 'B') + else if (keyin == 'b') class_wanted = OBJ_ARMOUR; - else if (keyin == 'c' || keyin == 'C') + else if (keyin == 'c') class_wanted = OBJ_JEWELLERY; - else if (keyin == 'd' || keyin == 'D') + else if (keyin == 'd') class_wanted = OBJ_BOOKS; - else if (keyin == 'e' || keyin == 'E') + else if (keyin == 'e') class_wanted = OBJ_STAVES; - else if (keyin == 'f' || keyin == 'F') + else if (keyin == 'f') class_wanted = OBJ_FOOD; - else if (keyin == 'g' || keyin == 'G') + else if (keyin == 'g') class_wanted = OBJ_MISCELLANY; - else if (keyin == 'h' || keyin == 'H') + else if (keyin == 'h') class_wanted = OBJ_GOLD; } else @@ -584,6 +584,10 @@ bool acquirement(unsigned char force_class, int agent) if (i == WPN_KNIFE) i = WPN_FALCHION; + // blessed blades can only be created by the player, never found + if (i == WPN_BLESSED_BLADE) + continue; + // "rare" weapons are only considered some of the time... // still, the chance is higher than actual random creation if (weapon_skill( OBJ_WEAPONS, i ) == skill @@ -598,6 +602,72 @@ bool acquirement(unsigned char force_class, int agent) } } } + else if (class_wanted == OBJ_MISSILES) + { + int count = 0; + int skill = SK_THROWING; + + for (int i = SK_SLINGS; i <= SK_DARTS; i++) + { + if (you.skills[i]) + { + count += you.skills[i]; + if (random2(count) < you.skills[i]) + skill = i; + } + } + + switch (skill) + { + case SK_SLINGS: + type_wanted = MI_STONE; + break; + + case SK_BOWS: + type_wanted = MI_ARROW; + break; + + case SK_CROSSBOWS: + type_wanted = MI_DART; + for (int i = 0; i < ENDOFPACK; i++) + { + // Assuming that crossbow in inventory means that they + // want bolts for it (not darts for a hand crossbow)... + // perhaps we should check for both and compare ammo + // amounts on hand? + if (is_valid_item( you.inv[i] ) + && you.inv[i].base_type == OBJ_WEAPONS + && you.inv[i].sub_type == WPN_CROSSBOW) + { + type_wanted = MI_BOLT; + break; + } + } + break; + + case SK_DARTS: + type_wanted = MI_DART; + for (int i = 0; i < ENDOFPACK; i++) + { + if (is_valid_item( you.inv[i] ) + && you.inv[i].base_type == OBJ_WEAPONS + && you.inv[i].sub_type == WPN_BLOWGUN) + { + // Assuming that blowgun in inventory means that they + // may want needles for it (but darts might also be + // wanted). Maybe expand this... see above comment. + if (coinflip()) + type_wanted = MI_NEEDLE; + break; + } + } + break; + + default: + type_wanted = MI_DART; + break; + } + } else if (class_wanted == OBJ_ARMOUR) { // Increasing the representation of the non-body armour @@ -1050,10 +1120,11 @@ bool acquirement(unsigned char force_class, int agent) while (already_has[type_wanted] && !one_chance_in(200)); } - if (grd[you.x_pos][you.y_pos] == DNGN_LAVA - || grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER) + if (grid_destroys_items(grd[you.x_pos][you.y_pos])) { - mpr("You hear a splash."); // how sad (and stupid) + // how sad (and stupid) + mprf(MSGCH_SOUND, + grid_item_destruction_message(grd[you.x_pos][you.y_pos])); } else { @@ -1260,48 +1331,77 @@ bool acquirement(unsigned char force_class, int agent) bool recharge_wand(void) { - if (you.equip[EQ_WEAPON] == -1 - || you.inv[you.equip[EQ_WEAPON]].base_type != OBJ_WANDS) - { + if (you.equip[EQ_WEAPON] == -1) return (false); - } - unsigned char charge_gain = 0; + item_def &wand = you.inv[ you.equip[EQ_WEAPON] ]; + + if (wand.base_type != OBJ_WANDS && !item_is_rod(wand)) + return (false); - switch (you.inv[you.equip[EQ_WEAPON]].sub_type) + int charge_gain = 0; + if (wand.base_type == OBJ_WANDS) { - case WAND_INVISIBILITY: - case WAND_FIREBALL: - case WAND_HEALING: - charge_gain = 3; - break; + switch (wand.sub_type) + { + case WAND_INVISIBILITY: + case WAND_FIREBALL: + case WAND_HEALING: + charge_gain = 3; + break; - case WAND_LIGHTNING: - case WAND_DRAINING: - charge_gain = 4; - break; + case WAND_LIGHTNING: + case WAND_DRAINING: + charge_gain = 4; + break; - case WAND_FIRE: - case WAND_COLD: - charge_gain = 5; - break; + case WAND_FIRE: + case WAND_COLD: + charge_gain = 5; + break; - default: - charge_gain = 8; - break; + default: + charge_gain = 8; + break; + } + + char str_pass[ ITEMNAME_SIZE ]; + item_name(wand, DESC_CAP_YOUR, str_pass); + mprf("%s glows for a moment.", str_pass); + + wand.plus += 1 + random2avg( ((charge_gain - 1) * 3) + 1, 3 ); + + if (wand.plus > charge_gain * 3) + wand.plus = charge_gain * 3; } + else + { + // This is a rod. + bool work = false; - char str_pass[ ITEMNAME_SIZE ]; - in_name(you.equip[EQ_WEAPON], DESC_CAP_YOUR, str_pass); - strcpy(info, str_pass); - strcat(info, " glows for a moment."); - mpr(info); + if (wand.plus2 <= MAX_ROD_CHARGE * ROD_CHARGE_MULT) + { + wand.plus2 += ROD_CHARGE_MULT; - you.inv[you.equip[EQ_WEAPON]].plus += - 1 + random2avg( ((charge_gain - 1) * 3) + 1, 3 ); + if (wand.plus2 > MAX_ROD_CHARGE * ROD_CHARGE_MULT) + wand.plus2 = MAX_ROD_CHARGE * ROD_CHARGE_MULT; - if (you.inv[you.equip[EQ_WEAPON]].plus > charge_gain * 3) - you.inv[you.equip[EQ_WEAPON]].plus = charge_gain * 3; + work = true; + } + + if (wand.plus < wand.plus2) + { + wand.plus = wand.plus2; + work = true; + } + + if (!work) + return (false); + + char str_pass[ITEMNAME_SIZE]; + item_name( wand, DESC_CAP_YOUR, str_pass ); + mprf("%s glows for a moment.", str_pass); + } you.wield_change = true; return (true); @@ -1346,7 +1446,7 @@ void yell(void) switch (keyn) { case '!': - mpr("You yell for attention!"); + mpr("You yell for attention!", MSGCH_SOUND); you.turn_is_over = 1; noisy( 12, you.x_pos, you.y_pos ); return; diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 55d24085e1..c59fee8efa 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -363,7 +363,9 @@ enum BEAMS // beam[].flavour BEAM_POTION_BLACK_SMOKE, BEAM_POTION_BLUE_SMOKE, BEAM_POTION_PURP_SMOKE, - BEAM_POTION_RANDOM + BEAM_POTION_RANDOM, + + BEAM_LINE_OF_SIGHT, // only to check monster LOS }; enum BOOKS @@ -615,6 +617,45 @@ enum CONFIRM_LEVEL CONFIRM_ALL_EASY }; +// [dshaligram] 4.1 merge GOOD_ and NAUGHTY_ into generic conducts. +enum CONDUCTS +{ + DID_NECROMANCY = 1, // vamp/drain/pain wpns, Zong/Curses + DID_UNHOLY, // demon wpns, demon spells + DID_ATTACK_HOLY, + DID_ATTACK_FRIEND, + DID_FRIEND_DIES, + DID_STABBING, + DID_POISON, + DID_DEDICATED_BUTCHERY, + DID_DEDICATED_KILL_LIVING, + DID_DEDICATED_KILL_UNDEAD, + DID_DEDICATED_KILL_DEMON, + DID_DEDICATED_KILL_NATURAL_EVIL, // unused + DID_DEDICATED_KILL_WIZARD, + DID_DEDICATED_KILL_PRIEST, // unused + + // [dshaligram] No distinction between killing Angels during prayer or + // otherwise, borrowed from bwr 4.1. + DID_KILL_ANGEL, + DID_LIVING_KILLED_BY_UNDEAD_SLAVE, + DID_LIVING_KILLED_BY_SERVANT, + DID_UNDEAD_KILLED_BY_SERVANT, + DID_DEMON_KILLED_BY_SERVANT, + DID_NATURAL_EVIL_KILLED_BY_SERVANT, // unused + DID_ANGEL_KILLED_BY_SERVANT, + DID_SPELL_MEMORISE, + DID_SPELL_CASTING, + DID_SPELL_PRACTISE, + DID_SPELL_NONUTILITY, // unused + DID_CARDS, + DID_STIMULANTS, // unused + DID_EAT_MEAT, // unused + DID_CREATED_LIFE, // unused + + NUM_CONDUCTS +}; + enum CORPSE_EFFECTS { CE_NOCORPSE, // 0 @@ -1067,27 +1108,6 @@ enum GODS // you.religion GOD_RANDOM = 100 }; -enum GOOD_THINGS -{ - GOOD_KILLED_LIVING = 1, // 1 - killed a living monster in god's name - GOOD_KILLED_UNDEAD, // 2 - killed an undead in god's name - GOOD_KILLED_DEMON, // 3 - killed a demon in god's name - GOOD_KILLED_ANGEL_I, // 4 - killed an angel (any time) - GOOD_KILLED_ANGEL_II, // 5 - killed an angel in god's name - // (all above pass HD of monster as pgain) - GOOD_HACKED_CORPSE, // 6 - hacked up a corpse in god's name - GOOD_OFFER_STUFF, // 7 - offered inanimate stuff at an altar - GOOD_OFFER_CORPSE, // as above,including at least one corpse - GOOD_SLAVES_KILL_LIVING,// 9 - undead slaves killed a living thing - GOOD_SERVANTS_KILL, // 10 - any servants kill anything - GOOD_CARDS, // 11 - cards (Nemelex) - GOOD_KILLED_WIZARD, - GOOD_KILLED_PRIEST, - GOOD_POISON, - GOOD_ATTACKED_FRIEND, - NUM_GOOD_THINGS -}; - enum HANDS_REQUIRED { HANDS_ONE_HANDED = 1, // 1 @@ -1417,6 +1437,7 @@ enum MESSAGE_CHANNEL MSGCH_WARN, // much less serious threats MSGCH_FOOD, // hunger notices MSGCH_RECOVERY, // recovery from disease/stat/poison condition + MSGCH_SOUND, // messages about things the player hears MSGCH_TALK, // monster talk (param is monster type) MSGCH_INTRINSIC_GAIN, // player level/stat/species-power gains MSGCH_MUTATION, // player gain/lose mutations @@ -1487,6 +1508,77 @@ enum MISSILES // (unsigned char) MI_EGGPLANT }; +enum MONS_CLASS_FLAGS +{ + M_NO_FLAGS = 0, + + M_SPELLCASTER = (1<< 0), // any non-physical-attack powers, + M_ACTUAL_SPELLS = (1<< 1), // monster is a wizard, + M_PRIEST = (1<< 2), // monster is a priest + M_FIGHTER = (1<< 3), // monster is skilled fighter + + M_FLIES = (1<< 4), // will crash to ground if paralysed? + M_LEVITATE = (1<< 5), // ... but not if this is set + M_INVIS = (1<< 6), // is created invis + M_SEE_INVIS = (1<< 7), // can see invis + M_SPEAKS = (1<< 8), // uses talking code + M_CONFUSED = (1<< 9), // monster is perma-confused, + M_BATTY = (1<<10), // monster is batty + M_SPLITS = (1<<11), // monster can split + M_AMPHIBIOUS = (1<<12), // monster can swim in water, + M_THICK_SKIN = (1<<13), // monster has more effective AC, + M_HUMANOID = (1<<14), // for Glamour + M_COLD_BLOOD = (1<<15), // susceptible to cold + M_WARM_BLOOD = (1<<16), // no effect currently + M_REGEN = (1<<17), // regenerates quickly + M_BURROWS = (1<<18), // monster digs through rock + M_EVIL = (1<<19), // monster vulnerable to holy spells + + M_ON_FIRE = (1<<20), // XXX: Potentially ditchable + M_FROZEN = (1<<21), // XXX: Potentially ditchable + + + M_SPECIAL_ABILITY = (1<<26), // XXX: eventually make these spells? + M_COLOUR_SHIFT = (1<<27), // flag for element colour shifters + M_DCHAR_SYMBOL = (1<<28), // monster looks like a DCHAR terrain + + M_NO_SKELETON = (1<<29), // boneless corpses + M_NO_WOUNDS = (1<<30), // doesn't show would level + M_NO_EXP_GAIN = (1<<31) // worth 0 xp +}; + +enum mon_resist_flags +{ + MR_NO_FLAGS = 0, + + // resistances + // Notes: + // - negative energy is mostly handled via mons_has_life_force() + // - acid is handled mostly by genus (jellies) plus non-living + MR_RES_ELEC = (1<< 0), + MR_RES_POISON = (1<< 1), + MR_RES_FIRE = (1<< 2), + MR_RES_HELLFIRE = (1<< 3), + MR_RES_COLD = (1<< 4), + MR_RES_HELLFROST = (1<< 5), + + // vulnerabilities + MR_VUL_ELEC = (1<< 6), + MR_VUL_POISON = (1<< 7), + MR_VUL_FIRE = (1<< 8), + MR_VUL_COLD = (1<< 9), + + // melee armour resists/vulnerabilities + // XXX: how to do combos (bludgeon/slice, bludgeon/pierce) + MR_RES_PIERCE = (1<<10), + MR_RES_SLICE = (1<<11), + MR_RES_BLUDGEON = (1<<12), + + MR_VUL_PIERCE = (1<<13), + MR_VUL_SLICE = (1<<14), + MR_VUL_BLUDGEON = (1<<15) +}; + enum MON_TARG_MODE { TARG_ANY, @@ -2201,24 +2293,6 @@ enum MUTATIONS NUM_MUTATIONS }; -enum NAUGHTY_THINGS -{ - NAUGHTY_NECROMANCY = 1, // 1 - using necromancy (spell or device) - NAUGHTY_UNHOLY, // 2 - using unholy stuff (call imp, summon things) - NAUGHTY_KILLING, // 3 - killing in the name of a peaceful deity - NAUGHTY_ATTACK_HOLY, // 4 - attacking holy things - NAUGHTY_ATTACK_FRIEND, // 5 - attacking friendly things - NAUGHTY_FRIEND_DIES, // 6 - allowing friendly things to die - NAUGHTY_BUTCHER, // 7 - butchering in the name of a peaceful deity - NAUGHTY_STABBING, // 8 - stabbing - NAUGHTY_SPELLCASTING, // 9 - spellcasting - NAUGHTY_POISON, // 10 - poisoning - NAUGHTY_STIMULANTS, //jmf: next three new, some not yet used - NAUGHTY_ATE_MEAT, - NAUGHTY_CREATED_LIFE, - NUM_NAUGHTY_THINGS -}; - enum OBJECT_CLASSES // (unsigned char) mitm[].base_type { OBJ_WEAPONS, // 0 @@ -2833,11 +2907,25 @@ enum SPELLS SPELL_SEMI_CONTROLLED_BLINK, //jmf: to test effect 200 SPELL_STONESKIN, SPELL_SIMULACRUM, - SPELL_CONJURE_BALL_LIGHTNING, // 203 (be wary of 210, see below) + SPELL_CONJURE_BALL_LIGHTNING, + SPELL_CHAIN_LIGHTNING, // 204 (be wary of 209/210, see below) NUM_SPELLS, SPELL_NO_SPELL = 210 // 210 - added 22jan2000 {dlb} }; +enum SPELL_FLAGS +{ + SPFLAG_NONE = 0x0000, + SPFLAG_DIR_OR_TARGET = 0x0001, // use DIR_NONE targeting + SPFLAG_TARGET = 0x0002, // use DIR_TARGET targeting + SPFLAG_GRID = 0x0004, // use DIR_GRID targeting + SPFLAG_DIR = 0x0008, // use DIR_DIR targeting + SPFLAG_TARGETING_MASK = 0x000f, // used to test for targeting + SPFLAG_HELPFUL = 0x0010, // TARG_FRIENDS used + SPFLAG_NOT_SELF = 0x0020, // aborts on isMe + SPFLAG_UNHOLY = 0x0040 // counts at "unholy" +}; + enum SPELL_TYPES //jmf: 24jul2000: changed from integer-list to bitfield { SPTYP_NONE = 0, // "0" is reserved for no type at all {dlb} @@ -3115,7 +3203,8 @@ enum WEAPONS WPN_KNIFE, WPN_BLOWGUN, WPN_FALCHION, - NUM_WEAPONS, // 44 - must remain last regular member {dlb} + WPN_BLESSED_BLADE, // 44 + NUM_WEAPONS, // 45 - must be last regular member {dlb} // special cases WPN_UNARMED = 500, // 500 WPN_UNKNOWN = 1000, // 1000 diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 0a3a423b7c..b9c4b5d3f7 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -327,6 +327,8 @@ struct player char redraw_gold; char redraw_evasion; + unsigned char flash_colour; + unsigned char hit_points_regeneration; unsigned char magic_points_regeneration; @@ -403,6 +405,7 @@ struct player unsigned char gift_timeout; FixedVector<unsigned char, MAX_NUM_GODS> penance; FixedVector<unsigned char, MAX_NUM_GODS> worshipped; + FixedVector<short, MAX_NUM_GODS> num_gifts; FixedVector<unsigned char, 100> mutation; diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index 6a93de441e..42cb60edf5 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -258,10 +258,10 @@ void you_attack(int monster_attacked, bool unarmed_attacks) * * ************************************************************************** */ - bool helpless = mons_flag(defender->type, M_NO_EXP_GAIN); + bool helpless = mons_class_flag(defender->type, M_NO_EXP_GAIN); if (mons_friendly(defender)) - naughty(NAUGHTY_ATTACK_FRIEND, 5); + did_god_conduct(DID_ATTACK_FRIEND, 5); if (you.pet_target == MHITNOT) you.pet_target = monster_attacked; @@ -280,7 +280,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) if (player_is_swimming() // monster not a water creature && monster_habitat( defender->type ) != DNGN_DEEP_WATER - && !mons_flag( defender->type, M_AMPHIBIOUS ) + && !mons_class_flag( defender->type, M_AMPHIBIOUS ) // monster in water && (grd[defender->x][defender->y] == DNGN_SHALLOW_WATER || grd[defender->x][defender->y] == DNGN_DEEP_WATER) @@ -556,11 +556,14 @@ void you_attack(int monster_attacked, bool unarmed_attacks) { switch (you.inv[you.equip[EQ_SHIELD]].sub_type) { - case ARM_SHIELD: - weapon_speed2++; - break; case ARM_LARGE_SHIELD: - weapon_speed2 += 2; + if (you.skills[SK_SHIELDS] <= 10 + random2(17)) + weapon_speed2++; + // [dshaligram] Fall-through + + case ARM_SHIELD: + if (you.skills[SK_SHIELDS] <= 3 + random2(17)) + weapon_speed2++; break; } } @@ -599,7 +602,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) // confused (but not perma-confused) if (mons_has_ench(defender, ENCH_CONFUSION) - && !mons_flag(defender->type, M_CONFUSED)) + && !mons_class_flag(defender->type, M_CONFUSED)) { stabAttempt = true; stab_bonus = 2; @@ -784,7 +787,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) if (mons_holiness(defender->type) == MH_NATURAL || mons_holiness(defender->type) == MH_HOLY) { - naughty(NAUGHTY_STABBING, 4); + did_god_conduct(DID_STABBING, 4); } } else @@ -929,7 +932,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) if (you.hunger_state != HS_ENGORGED) lessen_hunger(30 + random2avg(59, 2), true); - naughty(NAUGHTY_NECROMANCY, 2); + did_god_conduct(DID_NECROMANCY, 2); } } @@ -1003,18 +1006,18 @@ void you_attack(int monster_attacked, bool unarmed_attacks) mpr(info); if (mons_holiness(defender->type) == MH_HOLY) - done_good(GOOD_KILLED_ANGEL_I, 1); + did_god_conduct(DID_KILL_ANGEL, 1); if (you.special_wield == SPWLD_TORMENT) { torment(you.x_pos, you.y_pos); - naughty(NAUGHTY_UNHOLY, 5); + did_god_conduct(DID_UNHOLY, 5); } if (you.special_wield == SPWLD_ZONGULDROK || you.special_wield == SPWLD_CURSE) { - naughty(NAUGHTY_NECROMANCY, 3); + did_god_conduct(DID_NECROMANCY, 3); } } @@ -1035,11 +1038,11 @@ void you_attack(int monster_attacked, bool unarmed_attacks) && you.inv[ weapon ].base_type == OBJ_WEAPONS && is_demonic( you.inv[ weapon ].sub_type )) { - naughty(NAUGHTY_UNHOLY, 1); + did_god_conduct(DID_UNHOLY, 1); } if (mons_holiness(defender->type) == MH_HOLY) - naughty(NAUGHTY_ATTACK_HOLY, defender->hit_dice); + did_god_conduct(DID_ATTACK_HOLY, defender->hit_dice); if (defender->type == MONS_HYDRA) { @@ -1204,7 +1207,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) ptr_monam(defender, DESC_CAP_THE) ); mpr(info); - naughty(NAUGHTY_NECROMANCY, 4); + did_god_conduct(DID_NECROMANCY, 4); } } break; @@ -1375,7 +1378,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) defender->hit_points = 0; specdam = 1 + (random2(damage_done) / 2); - naughty( NAUGHTY_NECROMANCY, 2 ); + did_god_conduct( DID_NECROMANCY, 2 ); break; /* 9 = speed - done before */ @@ -1411,7 +1414,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) if (you.hunger_state != HS_ENGORGED) lessen_hunger(random2avg(59, 2), true); - naughty( NAUGHTY_NECROMANCY, 2 ); + did_god_conduct( DID_NECROMANCY, 2 ); break; case SPWPN_DISRUPTION: @@ -1431,7 +1434,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) simple_monster_message(defender, " convulses in agony."); specdam += random2( 1 + you.skills[SK_NECROMANCY] ); } - naughty(NAUGHTY_NECROMANCY, 4); + did_god_conduct(DID_NECROMANCY, 4); break; case SPWPN_DISTORTION: @@ -1794,7 +1797,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) poison_monster( defender, true ); if (mons_holiness(defender->type) == MH_HOLY) - done_good(GOOD_KILLED_ANGEL_I, 1); + did_god_conduct(DID_KILL_ANGEL, 1); hit = true; } @@ -1932,7 +1935,7 @@ void monster_attack(int monster_attacking) if (grd[attacker->x][attacker->y] == DNGN_SHALLOW_WATER && !mons_flies( attacker ) - && !mons_flag( attacker->type, M_AMPHIBIOUS ) + && !mons_class_flag( attacker->type, M_AMPHIBIOUS ) && monster_habitat( attacker->type ) == DNGN_FLOOR && one_chance_in(4)) { @@ -2015,8 +2018,10 @@ void monster_attack(int monster_attacking) } // Factors against blocking - const int con_block = 15 + attacker->hit_dice - + (10 * you.shield_blocks * you.shield_blocks); + // [dshaligram] Scaled back HD effect to 50% of previous, reduced + // shield_blocks multiplier to 5. + const int con_block = 15 + attacker->hit_dice / 2 + + (5 * you.shield_blocks * you.shield_blocks); // Factors for blocking const int pro_block = player_shield_class() + (random2(you.dex) / 5); @@ -2941,7 +2946,7 @@ bool monsters_fight(int monster_attacking, int monster_attacked) if (grd[attacker->x][attacker->y] == DNGN_SHALLOW_WATER && !mons_flies( attacker ) - && !mons_flag( attacker->type, M_AMPHIBIOUS ) + && !mons_class_flag( attacker->type, M_AMPHIBIOUS ) && habitat == DNGN_FLOOR && one_chance_in(4)) { @@ -3781,6 +3786,7 @@ static int weapon_type_modify( int weapnum, char noise[80], char noise2[80], case WPN_TRIPLE_SWORD: case WPN_SABRE: case WPN_DEMON_BLADE: + case WPN_BLESSED_BLADE: if (damage < HIT_MED) strcpy( noise, "slash" ); else if (damage < HIT_STRONG) diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index 367fe30ec4..51b09a0bf9 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -1106,8 +1106,9 @@ void save_game(bool leave_game) // 4.2 spell and ability tables // 4.3 added you.magic_contamination (05/03/05) // 4.4 added item origins + // 4.5 added num_gifts - write_tagged_file( saveFile, 4, 4, TAGTYPE_PLAYER ); + write_tagged_file( saveFile, 4, 5, TAGTYPE_PLAYER ); fclose(saveFile); diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index 46bf73e40e..c7458e9f62 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -122,7 +122,7 @@ static int str_to_channel_colour( const std::string &str ) static const std::string message_channel_names[ NUM_MESSAGE_CHANNELS ] = { "plain", "prompt", "god", "duration", "danger", "warning", "food", - "recovery", "talk", "intrinsic_gain", "mutation", "monster_spell", + "recovery", "sound", "talk", "intrinsic_gain", "mutation", "monster_spell", "monster_enchant", "monster_damage", "rotten_meat", "equipment", "diagnostic", }; diff --git a/crawl-ref/source/it_use2.cc b/crawl-ref/source/it_use2.cc index 45449716d9..d03abea16e 100644 --- a/crawl-ref/source/it_use2.cc +++ b/crawl-ref/source/it_use2.cc @@ -105,7 +105,7 @@ bool potion_effect( char pot_eff, int pow ) if (you.might > 80) you.might = 80; - naughty( NAUGHTY_STIMULANTS, 4 + random2(4) ); + did_god_conduct( DID_STIMULANTS, 4 + random2(4) ); } break; @@ -279,7 +279,7 @@ bool potion_effect( char pot_eff, int pow ) mutate(100, false); } - naughty(NAUGHTY_STIMULANTS, 4 + random2(4)); + did_god_conduct(DID_STIMULANTS, 4 + random2(4)); break; } diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc index f3973806b2..c30ca12066 100644 --- a/crawl-ref/source/it_use3.cc +++ b/crawl-ref/source/it_use3.cc @@ -102,7 +102,7 @@ void special_wielded(void) (temp_rand == 29) ? "speaks gibberish." : (temp_rand == 30) ? "raves incoherently." : "yells in some weird language."); - mpr(info); + mpr(info, MSGCH_SOUND); } break; @@ -143,7 +143,7 @@ void special_wielded(void) if (one_chance_in(200)) { torment( you.x_pos, you.y_pos ); - naughty( NAUGHTY_UNHOLY, 1 ); + did_god_conduct( DID_UNHOLY, 1 ); } break; @@ -153,7 +153,7 @@ void special_wielded(void) if (one_chance_in(5)) { animate_dead( 1 + random2(3), BEH_HOSTILE, MHITYOU, 1 ); - naughty( NAUGHTY_NECROMANCY, 1 ); + did_god_conduct( DID_NECROMANCY, 1 ); } break; @@ -185,7 +185,7 @@ void special_wielded(void) if (random2(8) <= player_spec_death()) { - naughty( NAUGHTY_NECROMANCY, 1 ); + did_god_conduct( DID_NECROMANCY, 1 ); create_monster( MONS_SHADOW, ENCH_ABJ_II, BEH_FRIENDLY, you.x_pos, you.y_pos, you.pet_target, 250 ); } @@ -199,7 +199,7 @@ void special_wielded(void) in_name(wpn, DESC_CAP_YOUR, str_pass); strcpy(info, str_pass); strcat(info, " lets out a weird humming sound."); - mpr(info); + mpr(info, MSGCH_SOUND); } break; // to noisy() call at foot 2apr2000 {dlb} @@ -209,18 +209,18 @@ void special_wielded(void) in_name(wpn, DESC_CAP_YOUR, str_pass); strcpy(info, str_pass); strcat(info, " chimes like a gong."); - mpr(info); + mpr(info, MSGCH_SOUND); } break; case SPWLD_BECKON: if (makes_noise) - mpr("You hear a voice call your name."); + mpr("You hear a voice call your name.", MSGCH_SOUND); break; case SPWLD_SHOUT: if (makes_noise) - mpr("You hear a shout."); + mpr("You hear a shout.", MSGCH_SOUND); break; //case SPWLD_PRUNE: diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index 7ea1db4900..a153dbf6a3 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -69,7 +69,6 @@ bool drink_fountain(void); static void throw_it(struct bolt &pbolt, int throw_2); void use_randart(unsigned char item_wield_2); -static bool enchant_weapon( int which_stat, bool quiet = false ); static bool enchant_armour( void ); // Rather messy - we've gathered all the can't-wield logic from wield_weapon() @@ -114,12 +113,13 @@ bool can_wield(const item_def& weapon) && you.equip[EQ_SHIELD] != -1) return false; - int weap_brand = get_weapon_brand( weapon ); - + int weap_brand = get_weapon_brand( weapon ); if ((you.is_undead || you.species == SP_DEMONSPAWN) && (!is_fixed_artefact( weapon ) && (weap_brand == SPWPN_HOLY_WRATH - || weap_brand == SPWPN_DISRUPTION))) + || weap_brand == SPWPN_DISRUPTION + || (weapon.base_type == OBJ_WEAPONS + && weapon.sub_type == WPN_BLESSED_BLADE)))) return false; // We can wield this weapon. Phew! @@ -286,7 +286,9 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages) if ((you.is_undead || you.species == SP_DEMONSPAWN) && (!is_fixed_artefact( you.inv[item_slot] ) && (weap_brand == SPWPN_HOLY_WRATH - || weap_brand == SPWPN_DISRUPTION))) + || weap_brand == SPWPN_DISRUPTION + || (you.inv[item_slot].base_type == OBJ_WEAPONS + && you.inv[item_slot].sub_type == WPN_BLESSED_BLADE)))) { mpr("This weapon will not allow you to wield it."); you.turn_is_over = 1; @@ -2559,7 +2561,7 @@ static bool affix_weapon_enchantment( void ) return (success); } -static bool enchant_weapon( int which_stat, bool quiet ) +bool enchant_weapon( int which_stat, bool quiet ) { const int wpn = you.equip[ EQ_WEAPON ]; bool affected = true; @@ -2982,7 +2984,7 @@ void read_scroll(void) // is only naughty if you know you're doing it if (get_ident_type( OBJ_SCROLLS, SCR_TORMENT ) == ID_KNOWN_TYPE) { - naughty(NAUGHTY_UNHOLY, 10); + did_god_conduct(DID_UNHOLY, 10); } break; diff --git a/crawl-ref/source/item_use.h b/crawl-ref/source/item_use.h index 87c8e31455..61c2ea6741 100644 --- a/crawl-ref/source/item_use.h +++ b/crawl-ref/source/item_use.h @@ -130,4 +130,6 @@ bool puton_item(int slot, bool prompt_finger = true); int armour_equip_slot(const item_def &item); +bool enchant_weapon( int which_stat, bool quiet = false ); + #endif diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc index b92dcfc387..4531bded9e 100644 --- a/crawl-ref/source/itemname.cc +++ b/crawl-ref/source/itemname.cc @@ -1989,6 +1989,19 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], (item_typ == STAFF_CHANNELING) ? "channeling" : "bugginess", ITEMNAME_SIZE ); } + + if (item_is_rod( item ) && item.sub_type != STAFF_STRIKING + && item_ident( item, ISFLAG_KNOW_TYPE )) + { + strncat( buff, " (", ITEMNAME_SIZE ); + itoa( item.plus / ROD_CHARGE_MULT, tmp_quant, 10 ); + strncat( buff, tmp_quant, ITEMNAME_SIZE ); + strncat( buff, "/", ITEMNAME_SIZE ); + itoa( item.plus2 / ROD_CHARGE_MULT, tmp_quant, 10 ); + strncat( buff, tmp_quant, ITEMNAME_SIZE ); + strncat( buff, ")", ITEMNAME_SIZE ); + } + break; diff --git a/crawl-ref/source/message.cc b/crawl-ref/source/message.cc index 65faacbbd8..c6f391a53e 100644 --- a/crawl-ref/source/message.cc +++ b/crawl-ref/source/message.cc @@ -16,7 +16,8 @@ #include "message.h" #include "religion.h" -#include <string.h> +#include <cstdarg> +#include <cstring> #ifdef DOS #include <conio.h> @@ -215,6 +216,32 @@ static char channel_to_colour( int channel, int param ) #endif +static void do_message_print( int channel, int param, + const char *format, va_list argp ) +{ + char buff[80]; + vsnprintf( buff, sizeof( buff ), format, argp ); + buff[79] = '\0'; + + mpr(buff, channel, param); +} + +void mprf( int channel, const char *format, ... ) +{ + va_list argp; + va_start( argp, format ); + do_message_print( channel, 0, format, argp ); + va_end( argp ); +} + +void mprf( const char *format, ... ) +{ + va_list argp; + va_start( argp, format ); + do_message_print( MSGCH_PLAIN, 0, format, argp ); + va_end( argp ); +} + void mpr(const char *inf, int channel, int param) { char info2[80]; diff --git a/crawl-ref/source/message.h b/crawl-ref/source/message.h index c7fe736ef1..8878464d95 100644 --- a/crawl-ref/source/message.h +++ b/crawl-ref/source/message.h @@ -53,6 +53,9 @@ void more(void); * *********************************************************************** */ void mpr(const char *inf, int channel = MSGCH_PLAIN, int param = 0); +// 4.1-style mpr, currently named mprf for minimal disruption. +void mprf( int channel, const char *format, ... ); +void mprf( const char *format, ... ); // last updated 12may2000 {dlb} /* *********************************************************************** diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index 705a8acadb..24445e241f 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -132,6 +132,18 @@ void turn_corpse_into_chunks( item_def &item ) } } // end place_chunks() +bool grid_destroys_items( unsigned char grid ) +{ + return (grid == DNGN_LAVA || grid == DNGN_DEEP_WATER); +} + +const char *grid_item_destruction_message( unsigned char grid ) +{ + return grid == DNGN_DEEP_WATER? "You hear a splash." + : grid == DNGN_LAVA ? "You hear a sizzling splash." + : "You hear an empty echo."; +} + void search_around(void) { char srx = 0; diff --git a/crawl-ref/source/misc.h b/crawl-ref/source/misc.h index 7a754ffdd0..d444764b4b 100644 --- a/crawl-ref/source/misc.h +++ b/crawl-ref/source/misc.h @@ -131,5 +131,8 @@ void weird_writing(char stringy[40]); * *********************************************************************** */ unsigned char trap_category(unsigned char trap_type); +bool grid_destroys_items( unsigned char grid ); + +const char *grid_item_destruction_message( unsigned char grid ); #endif diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index 8580b8758b..748296cb60 100644 --- a/crawl-ref/source/mon-data.h +++ b/crawl-ref/source/mon-data.h @@ -1,6 +1,8 @@ #ifndef MONDATA_H #define MONDATA_H +#include "enum.h" + /* This whole file was very generously condensed from its initial ugly form by Wladimir van der Laan ($pellbinder). @@ -104,6 +106,7 @@ { MONS_PROGRAM_BUG, 'B', LIGHTRED, "program bug", M_NO_EXP_GAIN, + MR_NO_FLAGS, 0, 10, MONS_PROGRAM_BUG, MH_NATURAL, -3, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, @@ -115,7 +118,8 @@ // real monsters begin here {dlb}: { MONS_GIANT_ANT, 'a', DARKGREY, "giant ant", - M_ED_POISON, + M_NO_FLAGS, + MR_VUL_POISON, 700, 10, MONS_GIANT_ANT, MH_NATURAL, -3, { 8, 0, 0, 0 }, { 3, 3, 5, 0 }, @@ -127,6 +131,7 @@ { MONS_GIANT_BAT, 'b', DARKGREY, "giant bat", M_FLIES | M_SEE_INVIS | M_WARM_BLOOD, + MR_NO_FLAGS, 150, 4, MONS_GIANT_BAT, MH_NATURAL, -1, { 1, 0, 0, 0 }, { 1, 2, 3, 0 }, @@ -138,6 +143,7 @@ { MONS_CENTAUR, 'c', BROWN, "centaur", M_WARM_BLOOD, + MR_NO_FLAGS, 1500, 10, MONS_CENTAUR, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 4, 3, 5, 0 }, @@ -148,7 +154,8 @@ { MONS_RED_DEVIL, '4', RED, "red devil", - M_RES_POISON | M_RES_HELLFIRE | M_ED_COLD | M_FLIES, + M_FLIES | M_EVIL, + MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, 0, 10, MONS_RED_DEVIL, MH_DEMONIC, -7, { 18, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -159,7 +166,8 @@ { MONS_ETTIN, 'C', BROWN, "ettin", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 0, 10, MONS_ETTIN, MH_NATURAL, -3, { 18, 12, 0, 0 }, { 7, 3, 5, 0 }, @@ -170,7 +178,8 @@ { MONS_FUNGUS, 'f', LIGHTGREY, "fungus", - M_NO_EXP_GAIN | M_RES_POISON, + M_NO_EXP_GAIN, + MR_RES_POISON, 0, 10, MONS_FUNGUS, MH_PLANT, 5000, { 0, 0, 0, 0 }, { 8, 3, 5, 0 }, @@ -181,7 +190,8 @@ { MONS_GOBLIN, 'g', LIGHTGREY, "goblin", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 400, 10, MONS_GOBLIN, MH_NATURAL, -1, { 4, 0, 0, 0 }, { 1, 2, 4, 0 }, @@ -193,6 +203,7 @@ { MONS_HOUND, 'h', BROWN, "hound", M_SEE_INVIS | M_WARM_BLOOD, + MR_NO_FLAGS, 300, 10, MONS_HOUND, MH_NATURAL, -3, { 6, 0, 0, 0 }, { 3, 3, 5, 0 }, @@ -204,7 +215,8 @@ // note: these things regenerate { MONS_IMP, '5', RED, "imp", - M_RES_POISON | M_RES_HELLFIRE | M_ED_COLD | M_FLIES | M_SEE_INVIS | M_SPEAKS, + M_FLIES | M_SEE_INVIS | M_SPEAKS | M_EVIL, + MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, 0, 13, MONS_IMP, MH_DEMONIC, -9, { 4, 0, 0, 0 }, { 3, 3, 3, 0 }, @@ -216,6 +228,7 @@ { MONS_JACKAL, 'j', YELLOW, "jackal", M_WARM_BLOOD, + MR_NO_FLAGS, 200, 10, MONS_JACKAL, MH_NATURAL, -1, { 3, 0, 0, 0 }, { 1, 3, 5, 0 }, @@ -226,7 +239,8 @@ { MONS_KILLER_BEE, 'k', YELLOW, "killer bee", - M_ED_POISON | M_FLIES, + M_FLIES, + MR_VUL_POISON, 150, 11, MONS_KILLER_BEE, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 3, 3, 5, 0 }, @@ -237,7 +251,8 @@ { MONS_KILLER_BEE_LARVA, 'w', LIGHTGREY, "killer bee larva", - M_ED_POISON | M_NO_SKELETON, + M_NO_SKELETON, + MR_VUL_POISON, 150, 5, MONS_KILLER_BEE_LARVA, MH_NATURAL, -3, { 3, 0, 0, 0 }, { 1, 3, 5, 0 }, @@ -249,6 +264,7 @@ { MONS_MANTICORE, 'm', BROWN, "manticore", M_WARM_BLOOD, + MR_NO_FLAGS, 1800, 10, MONS_MANTICORE, MH_NATURAL, -3, { 14, 8, 8, 0 }, { 9, 3, 5, 0 }, @@ -260,7 +276,8 @@ // this thing doesn't have nr. 13 for nothing, has it? ($pellbinder) { MONS_NECROPHAGE, 'n', DARKGREY, "necrophage", - M_RES_POISON | M_RES_COLD, + M_EVIL, + MR_RES_POISON | MR_RES_COLD, 500, 10, MONS_NECROPHAGE, MH_UNDEAD, -5, { 8, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -271,7 +288,8 @@ { MONS_ORC, 'o', LIGHTRED, "orc", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 600, 10, MONS_ORC, MH_NATURAL, -3, { 5, 0, 0, 0 }, { 1, 4, 6, 0 }, @@ -284,7 +302,8 @@ // dangerous, but still come out at 200+ XP { MONS_PHANTOM, 'p', BLUE, "phantom", - M_RES_POISON | M_RES_COLD, + M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 5, MONS_PHANTOM, MH_UNDEAD, -4, { 10, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -295,7 +314,8 @@ { MONS_QUASIT, 'q', LIGHTGREY, "quasit", - M_RES_POISON | M_RES_FIRE | M_RES_COLD, + M_EVIL, + MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, 0, 10, MONS_QUASIT, MH_DEMONIC, 50, { 3, 2, 2, 0 }, { 3, 2, 6, 0 }, @@ -307,6 +327,7 @@ { MONS_RAT, 'r', BROWN, "rat", M_WARM_BLOOD, + MR_NO_FLAGS, 200, 10, MONS_RAT, MH_NATURAL, -1, { 3, 0, 0, 0 }, { 1, 1, 3, 0 }, @@ -317,7 +338,8 @@ { MONS_SCORPION, 's', DARKGREY, "scorpion", - M_ED_POISON, + M_NO_FLAGS, + MR_VUL_POISON, 500, 10, MONS_SCORPION, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 3, 3, 5, 0 }, @@ -331,7 +353,8 @@ // not until it can be reimplemented safely {dlb} { MONS_TUNNELING_WORM, 't', LIGHTRED, "tunneling worm", - M_RES_POISON, + M_NO_FLAGS, + MR_RES_POISON, 0, 10, 19, MH_NATURAL, 5000, { 50, 0, 0, 0 }, { 10, 5, 5, 0 }, @@ -344,6 +367,7 @@ { MONS_UGLY_THING, 'u', BROWN, "ugly thing", M_WARM_BLOOD | M_AMPHIBIOUS, + MR_NO_FLAGS, 600, 10, MONS_UGLY_THING, MH_NATURAL, -3, { 12, 0, 0, 0 }, { 8, 3, 5, 0 }, @@ -354,7 +378,8 @@ { MONS_FIRE_VORTEX, 'v', RED, "fire vortex", - M_RES_POISON | M_RES_FIRE | M_ED_COLD | M_RES_ELEC | M_LEVITATE | M_CONFUSED, + M_LEVITATE | M_CONFUSED, + MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD | MR_RES_ELEC, 0, 5, MONS_FIRE_VORTEX, MH_NONLIVING, 5000, { 30, 0, 0, 0 }, { 3, 3, 5, 0 }, @@ -366,6 +391,7 @@ { MONS_WORM, 'w', LIGHTRED, "worm", M_NO_SKELETON, + MR_NO_FLAGS, 350, 4, MONS_WORM, MH_NATURAL, -2, { 12, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -377,7 +403,8 @@ // random { MONS_ABOMINATION_SMALL, 'x', BLACK, "abomination", - M_NO_FLAGS, + M_EVIL, + MR_NO_FLAGS, 0, 10, MONS_ABOMINATION_SMALL, MH_DEMONIC, -5, { 23, 0, 0, 0 }, { 6, 2, 5, 0 }, @@ -388,7 +415,8 @@ { MONS_YELLOW_WASP, 'y', YELLOW, "yellow wasp", - M_ED_POISON | M_FLIES, + M_FLIES, + MR_VUL_POISON, 220, 12, MONS_YELLOW_WASP, MH_NATURAL, -3, { 13, 0, 0, 0 }, { 4, 3, 5, 0 }, @@ -400,7 +428,8 @@ // small zombie { MONS_ZOMBIE_SMALL, 'z', BROWN, "", - M_RES_POISON | M_RES_COLD, + M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 6, MONS_ZOMBIE_SMALL, MH_UNDEAD, -1, { 10, 0, 0, 0 }, { 1, 5, 5, 0 }, @@ -411,7 +440,8 @@ { MONS_ANGEL, 'A', WHITE, "Angel", - M_RES_POISON | M_FLIES | M_RES_ELEC | M_SPELLCASTER, + M_FLIES | M_SPELLCASTER, + MR_RES_POISON | MR_RES_ELEC, 0, 10, MONS_ANGEL, MH_HOLY, -8, { 20, 0, 0, 0 }, { 9, 3, 5, 0 }, @@ -422,7 +452,8 @@ { MONS_GIANT_BEETLE, 'B', DARKGREY, "giant beetle", - M_ED_POISON, + M_NO_FLAGS, + MR_VUL_POISON, 1000, 10, MONS_GIANT_BEETLE, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 5, 7, 6, 0 }, @@ -433,7 +464,8 @@ { MONS_CYCLOPS, 'C', BROWN, "cyclops", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 2500, 10, MONS_CYCLOPS, MH_NATURAL, -3, { 35, 0, 0, 0 }, { 9, 3, 5, 0 }, @@ -444,7 +476,8 @@ { MONS_DRAGON, 'D', GREEN, "dragon", - M_RES_POISON | M_RES_FIRE | M_ED_COLD | M_FLIES, //jmf: warm blood? + M_FLIES, //jmf: warm blood? + MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD, 2200, 12, MONS_DRAGON, MH_NATURAL, -4, { 20, 13, 13, 0 }, { 12, 5, 5, 0 }, @@ -457,7 +490,8 @@ // that they wield two weapons... I'm raising their xp modifier. -- bwr { MONS_TWO_HEADED_OGRE, 'O', LIGHTRED, "two-headed ogre", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 1500, 15, MONS_TWO_HEADED_OGRE, MH_NATURAL, -4, { 17, 13, 0, 0 }, { 6, 3, 5, 0 }, @@ -468,7 +502,8 @@ { MONS_FIEND, '1', LIGHTRED, "Fiend", //jmf: was RED, like Balrog - M_RES_POISON | M_RES_HELLFIRE | M_ED_COLD | M_FLIES | M_SEE_INVIS, + M_FLIES | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, 0, 18, MONS_FIEND, MH_DEMONIC, -12, { 25, 15, 15, 0 }, { 18, 3, 5, 0 }, @@ -479,7 +514,8 @@ { MONS_GIANT_SPORE, 'G', GREEN, "giant spore", - M_RES_POISON | M_LEVITATE, + M_LEVITATE, + MR_RES_POISON, 0, 10, MONS_GIANT_SPORE, MH_NATURAL, -3, { 1, 0, 0, 0 }, { 1, 0, 0, 1 }, @@ -490,7 +526,8 @@ { MONS_HOBGOBLIN, 'g', BROWN, "hobgoblin", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 500, 10, MONS_HOBGOBLIN, MH_NATURAL, -1, { 5, 0, 0, 0 }, { 1, 4, 5, 0 }, @@ -501,7 +538,8 @@ { MONS_ICE_BEAST, 'I', WHITE, "ice beast", - M_RES_POISON | M_ED_FIRE | M_RES_COLD, + M_NO_FLAGS, + MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 12, MONS_ICE_BEAST, MH_NATURAL, -3, { 5, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -512,7 +550,8 @@ { MONS_JELLY, 'J', LIGHTRED, "jelly", - M_RES_POISON | M_SEE_INVIS | M_SPLITS | M_AMPHIBIOUS, + M_SEE_INVIS | M_SPLITS | M_AMPHIBIOUS, + MR_RES_POISON, 0, 13, MONS_JELLY, MH_NATURAL, -3, { 8, 0, 0, 0 }, { 3, 5, 5, 0 }, @@ -524,6 +563,7 @@ { MONS_KOBOLD, 'K', BROWN, "kobold", M_WARM_BLOOD, + MR_NO_FLAGS, 400, 10, MONS_KOBOLD, MH_NATURAL, -1, { 4, 0, 0, 0 }, { 1, 2, 3, 0 }, @@ -534,7 +574,8 @@ { MONS_LICH, 'L', WHITE, "lich", - M_RES_POISON | M_RES_COLD | M_RES_ELEC | M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, 0, 16, MONS_LICH, MH_UNDEAD, -11, { 15, 0, 0, 0 }, { 20, 2, 4, 0 }, @@ -545,7 +586,8 @@ { MONS_MUMMY, 'M', WHITE, "mummy", - M_RES_POISON | M_ED_FIRE | M_RES_COLD, + M_EVIL, + MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 10, MONS_MUMMY, MH_UNDEAD, -5, { 20, 0, 0, 0 }, { 3, 5, 3, 0 }, @@ -556,7 +598,8 @@ { MONS_GUARDIAN_NAGA, 'N', LIGHTGREEN, "guardian naga", - M_RES_POISON | M_SPELLCASTER | M_SEE_INVIS | M_ACTUAL_SPELLS | M_WARM_BLOOD, + M_SPELLCASTER | M_SEE_INVIS | M_ACTUAL_SPELLS | M_WARM_BLOOD, + MR_RES_POISON, 350, 10, MONS_GUARDIAN_NAGA, MH_NATURAL, -6, { 19, 0, 0, 0 }, { 8, 3, 5, 0 }, @@ -567,7 +610,8 @@ { MONS_OGRE, 'O', BROWN, "ogre", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 1300, 10, MONS_OGRE, MH_NATURAL, -3, { 17, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -579,6 +623,7 @@ { MONS_PLANT, 'P', GREEN, "plant", M_NO_EXP_GAIN, + MR_NO_FLAGS, 0, 10, MONS_PLANT, MH_PLANT, 5000, { 0, 0, 0, 0 }, { 10, 3, 5, 0 }, @@ -589,7 +634,8 @@ { MONS_QUEEN_BEE, 'Q', YELLOW, "queen bee", - M_ED_POISON | M_FLIES, + M_FLIES, + MR_VUL_POISON, 200, 14, MONS_QUEEN_BEE, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -600,7 +646,8 @@ { MONS_RAKSHASA, 'R', YELLOW, "rakshasa", - M_RES_POISON | M_SPELLCASTER | M_SEE_INVIS, + M_SPELLCASTER | M_SEE_INVIS | M_EVIL, + MR_RES_POISON, 0, 15, MONS_RAKSHASA, MH_NATURAL, -10, { 20, 0, 0, 0 }, { 10, 3, 5, 0 }, @@ -612,6 +659,7 @@ { MONS_SNAKE, 'S', GREEN, "snake", M_COLD_BLOOD | M_AMPHIBIOUS, + MR_NO_FLAGS, 200, 10, MONS_SNAKE, MH_NATURAL, -3, { 5, 0, 0, 0 }, { 2, 3, 5, 0 }, @@ -622,7 +670,8 @@ { MONS_TROLL, 'T', BROWN, "troll", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 1500, 10, MONS_TROLL, MH_NATURAL, -3, { 20, 15, 15, 0 }, { 7, 3, 5, 0 }, @@ -633,7 +682,8 @@ { MONS_UNSEEN_HORROR, 'x', MAGENTA, "unseen horror", - M_LEVITATE | M_SEE_INVIS | M_RES_ELEC | M_INVIS, + M_LEVITATE | M_SEE_INVIS | M_INVIS, + MR_RES_ELEC, 0, 12, MONS_UNSEEN_HORROR, MH_NATURAL, -3, { 12, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -644,7 +694,8 @@ { MONS_VAMPIRE, 'V', RED, "vampire", - M_RES_POISON | M_RES_COLD | M_SPELLCASTER | M_SEE_INVIS, + M_SPELLCASTER | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 11, MONS_VAMPIRE, MH_UNDEAD, -6, { 22, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -655,7 +706,8 @@ { MONS_WRAITH, 'W', DARKGREY, "wraith", - M_RES_POISON | M_RES_COLD | M_LEVITATE | M_SEE_INVIS, + M_LEVITATE | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 11, MONS_WRAITH, MH_UNDEAD, -7, { 13, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -667,7 +719,8 @@ // Large abom: (the previous one was small) { MONS_ABOMINATION_LARGE, 'X', BLACK, "abomination", - M_NO_FLAGS, + M_EVIL, + MR_NO_FLAGS, 0, 10, MONS_ABOMINATION_LARGE, MH_DEMONIC, -7, { 40, 0, 0, 0 }, { 11, 2, 5, 0 }, @@ -678,7 +731,8 @@ { MONS_YAK, 'Y', BROWN, "yak", - M_WARM_BLOOD, + M_WARM_BLOOD, + MR_NO_FLAGS, 1200, 10, MONS_YAK, MH_NATURAL, -3, { 18, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -690,7 +744,8 @@ // big zombie { MONS_ZOMBIE_LARGE, 'Z', BROWN, "", - M_RES_POISON | M_RES_COLD, + M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 6, MONS_ZOMBIE_LARGE, MH_UNDEAD, -1, { 23, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -701,7 +756,8 @@ { MONS_ORC_WARRIOR, 'o', YELLOW, "orc warrior", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 0, 10, MONS_ORC, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 4, 4, 6, 0 }, @@ -712,7 +768,8 @@ { MONS_KOBOLD_DEMONOLOGIST, 'K', MAGENTA, "kobold demonologist", - M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 0, 10, MONS_KOBOLD, MH_NATURAL, -5, { 4, 0, 0, 0 }, { 4, 3, 5, 0 }, @@ -723,7 +780,8 @@ { MONS_ORC_WIZARD, 'o', MAGENTA, "orc wizard", - M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 0, 10, MONS_ORC, MH_NATURAL, -5, { 5, 0, 0, 0 }, { 3, 3, 4, 0 }, @@ -734,7 +792,8 @@ { MONS_ORC_KNIGHT, 'o', LIGHTCYAN, "orc knight", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 0, 10, MONS_ORC, MH_NATURAL, -3, { 25, 0, 0, 0 }, { 9, 4, 7, 0 }, @@ -748,7 +807,8 @@ // not until it can be reimplemented safely {dlb} { MONS_WORM_TAIL, '~', LIGHTRED, "worm tail", - M_NO_EXP_GAIN | M_RES_POISON, + M_NO_EXP_GAIN, + MR_RES_POISON, 0, 10, 56, MH_NATURAL, 5000, { 0, 0, 0, 0 }, { 10, 5, 5, 0 }, @@ -760,7 +820,8 @@ { MONS_WYVERN, 'D', LIGHTRED, "wyvern", - M_NO_FLAGS, //jmf: warm blood? + M_NO_FLAGS, //jmf: warm blood? + MR_NO_FLAGS, 2000, 10, MONS_WYVERN, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -771,7 +832,8 @@ { MONS_BIG_KOBOLD, 'K', RED, "big kobold", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 0, 10, MONS_BIG_KOBOLD, MH_NATURAL, -3, { 7, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -783,6 +845,7 @@ { MONS_GIANT_EYEBALL, 'G', WHITE, "giant eyeball", M_NO_SKELETON | M_LEVITATE, + MR_NO_FLAGS, 400, 10, MONS_GIANT_EYEBALL, MH_NATURAL, -3, { 0, 0, 0, 0 }, { 3, 3, 5, 0 }, @@ -793,7 +856,8 @@ { MONS_WIGHT, 'W', LIGHTGREY, "wight", - M_RES_POISON | M_RES_COLD, + M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_WIGHT, MH_UNDEAD, -4, { 8, 0, 0, 0 }, { 3, 3, 5, 0 }, @@ -804,7 +868,8 @@ { MONS_OKLOB_PLANT, 'P', GREEN, "oklob plant", - M_RES_POISON, + M_NO_FLAGS, + MR_RES_POISON, 0, 10, MONS_OKLOB_PLANT, MH_PLANT, -3, { 0, 0, 0, 0 }, { 10, 3, 5, 0 }, @@ -815,7 +880,8 @@ { MONS_WOLF_SPIDER, 's', BROWN, "wolf spider", - M_ED_POISON, + M_NO_FLAGS, + MR_VUL_POISON, 800, 10, MONS_WOLF_SPIDER, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 8, 3, 5, 0 }, @@ -826,7 +892,8 @@ { MONS_SHADOW, ' ', BLACK, "shadow", - M_RES_POISON | M_RES_COLD | M_SEE_INVIS, + M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_SHADOW, MH_UNDEAD, -5, { 5, 0, 0, 0 }, { 3, 3, 5, 0 }, @@ -837,7 +904,8 @@ { MONS_HUNGRY_GHOST, 'p', GREEN, "hungry ghost", - M_RES_POISON | M_RES_COLD | M_SEE_INVIS | M_FLIES, + M_SEE_INVIS | M_FLIES | M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_HUNGRY_GHOST, MH_UNDEAD, -4, { 5, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -849,6 +917,7 @@ { MONS_EYE_OF_DRAINING, 'G', LIGHTGREY, "eye of draining", M_NO_SKELETON | M_LEVITATE | M_SEE_INVIS, + MR_NO_FLAGS, 400, 10, MONS_EYE_OF_DRAINING, MH_NATURAL, 5000, { 0, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -859,7 +928,8 @@ { MONS_BUTTERFLY, 'b', BLACK, "butterfly", - M_FLIES | M_ED_POISON | M_CONFUSED, + M_FLIES | M_CONFUSED, + MR_VUL_POISON, 150, 10, MONS_BUTTERFLY, MH_NATURAL, -3, { 0, 0, 0, 0 }, { 1, 3, 5, 0 }, @@ -870,7 +940,8 @@ { MONS_WANDERING_MUSHROOM, 'f', BROWN, "wandering mushroom", - M_RES_POISON, + M_NO_FLAGS, + MR_RES_POISON, 0, 10, MONS_WANDERING_MUSHROOM, MH_PLANT, -3, { 20, 0, 0, 0 }, { 8, 3, 5, 0 }, @@ -881,7 +952,8 @@ { MONS_EFREET, 'E', RED, "efreet", - M_RES_POISON | M_RES_FIRE | M_ED_COLD | M_SPELLCASTER | M_LEVITATE, + M_SPELLCASTER | M_LEVITATE | M_EVIL, + MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD, 0, 12, MONS_EFREET, MH_DEMONIC, -3, { 12, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -893,6 +965,7 @@ { MONS_BRAIN_WORM, 'w', LIGHTMAGENTA, "brain worm", M_SPELLCASTER, + MR_NO_FLAGS, 150, 10, MONS_BRAIN_WORM, MH_NATURAL, -3, { 0, 0, 0, 0 }, { 5, 3, 3, 0 }, @@ -904,6 +977,7 @@ { MONS_GIANT_ORANGE_BRAIN, 'G', LIGHTRED, "giant orange brain", M_NO_SKELETON | M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS, + MR_NO_FLAGS, 1000, 13, MONS_GIANT_ORANGE_BRAIN, MH_NATURAL, -8, { 0, 0, 0, 0 }, { 10, 3, 5, 0 }, @@ -914,7 +988,8 @@ { MONS_BOULDER_BEETLE, 'B', LIGHTGREY, "boulder beetle", - M_ED_POISON, + M_NO_FLAGS, + MR_VUL_POISON, 2500, 10, MONS_BOULDER_BEETLE, MH_NATURAL, -3, { 35, 0, 0, 0 }, { 9, 3, 5, 0 }, @@ -925,7 +1000,8 @@ { MONS_FLYING_SKULL, 'z', WHITE, "flying skull", - M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_RES_ELEC | M_LEVITATE, + M_LEVITATE, + MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_FLYING_SKULL, MH_UNDEAD, -3, { 7, 0, 0, 0 }, { 2, 3, 5, 0 }, @@ -936,7 +1012,8 @@ { MONS_HELL_HOUND, 'h', DARKGREY, "hell hound", - M_RES_POISON | M_RES_HELLFIRE | M_ED_COLD | M_SEE_INVIS, + M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, 0, 10, MONS_HELL_HOUND, MH_DEMONIC, -3, { 13, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -948,6 +1025,7 @@ { MONS_MINOTAUR, 'm', LIGHTRED, "minotaur", M_WARM_BLOOD, + MR_NO_FLAGS, 1500, 10, MONS_MINOTAUR, MH_NATURAL, -3, { 35, 0, 0, 0 }, { 13, 3, 5, 0 }, @@ -958,7 +1036,8 @@ { MONS_ICE_DRAGON, 'D', WHITE, "ice dragon", - M_RES_POISON | M_ED_FIRE | M_RES_COLD | M_FLIES, + M_FLIES, + MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 2200, 10, MONS_ICE_DRAGON, MH_NATURAL, -3, { 17, 17, 17, 0 }, { 12, 5, 5, 0 }, @@ -969,7 +1048,8 @@ { MONS_SLIME_CREATURE, 'J', GREEN, "slime creature", - M_RES_POISON | M_AMPHIBIOUS, + M_AMPHIBIOUS, + MR_RES_POISON, 0, 5, MONS_SLIME_CREATURE, MH_NATURAL, -3, { 22, 0, 0, 0 }, { 11, 3, 5, 0 }, @@ -980,7 +1060,8 @@ { MONS_FREEZING_WRAITH, 'W', LIGHTBLUE, "freezing wraith", - M_RES_POISON | M_ED_FIRE | M_RES_COLD | M_LEVITATE | M_SEE_INVIS, + M_LEVITATE | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 10, MONS_FREEZING_WRAITH, MH_UNDEAD, -4, { 19, 0, 0, 0 }, { 8, 3, 5, 0 }, @@ -992,7 +1073,8 @@ // fake R - conjured by the R's illusion spell. { MONS_RAKSHASA_FAKE, 'R', YELLOW, "rakshasa", - M_RES_POISON, + M_EVIL, + MR_RES_POISON, 0, 10, MONS_RAKSHASA_FAKE, MH_NATURAL, 5000, { 0, 0, 0, 0 }, { 1, 0, 0, 1 }, @@ -1003,7 +1085,8 @@ { MONS_GREAT_ORB_OF_EYES, 'G', LIGHTGREEN, "great orb of eyes", - M_NO_SKELETON | M_RES_POISON | M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS, + M_NO_SKELETON | M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS, + MR_RES_POISON, 900, 13, MONS_GREAT_ORB_OF_EYES, MH_NATURAL, 5000, { 20, 0, 0, 0 }, { 12, 3, 5, 0 }, @@ -1014,7 +1097,8 @@ { MONS_HELLION, '3', BLACK, "hellion", - M_RES_POISON | M_RES_HELLFIRE | M_ED_COLD | M_SPELLCASTER | M_ON_FIRE, + M_SPELLCASTER | M_ON_FIRE | M_EVIL, + MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, 0, 11, MONS_HELLION, MH_DEMONIC, -7, { 10, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -1025,7 +1109,8 @@ { MONS_ROTTING_DEVIL, '4', GREEN, "rotting devil", - M_RES_POISON | M_RES_COLD, + M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_ROTTING_DEVIL, MH_DEMONIC, -7, { 8, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -1036,7 +1121,8 @@ { MONS_TORMENTOR, '3', YELLOW, "tormentor", - M_RES_POISON | M_RES_FIRE | M_SPELLCASTER | M_FLIES | M_SPEAKS, + M_SPELLCASTER | M_FLIES | M_SPEAKS | M_EVIL, + MR_RES_POISON | MR_RES_FIRE, 0, 10, MONS_TORMENTOR, MH_DEMONIC, -6, { 8, 8, 0, 0 }, { 7, 3, 5, 0 }, @@ -1047,7 +1133,8 @@ { MONS_REAPER, '2', LIGHTGREY, "reaper", - M_RES_POISON | M_RES_COLD | M_SEE_INVIS, + M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_REAPER, MH_DEMONIC, 5000, { 32, 0, 0, 0 }, { 8, 3, 5, 0 }, @@ -1058,7 +1145,8 @@ { MONS_SOUL_EATER, '2', DARKGREY, "soul eater", - M_RES_POISON | M_RES_COLD | M_LEVITATE | M_SEE_INVIS, + M_LEVITATE | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 12, MONS_SOUL_EATER, MH_DEMONIC, -10, { 25, 0, 0, 0 }, { 11, 3, 5, 0 }, @@ -1069,7 +1157,8 @@ { MONS_HAIRY_DEVIL, '4', LIGHTRED, "hairy devil", - M_RES_POISON, + M_EVIL, + MR_RES_POISON, 0, 10, MONS_HAIRY_DEVIL, MH_DEMONIC, -4, { 9, 9, 0, 0 }, { 6, 3, 5, 0 }, @@ -1080,7 +1169,8 @@ { MONS_ICE_DEVIL, '2', WHITE, "ice devil", - M_RES_POISON | M_ED_FIRE | M_RES_COLD | M_SEE_INVIS, + M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 11, MONS_ICE_DEVIL, MH_DEMONIC, -6, { 16, 0, 0, 0 }, { 11, 3, 5, 0 }, @@ -1091,7 +1181,8 @@ { MONS_BLUE_DEVIL, '3', BLUE, "blue devil", - M_RES_POISON | M_ED_FIRE | M_RES_COLD | M_FLIES, + M_FLIES | M_EVIL, + MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 10, MONS_BLUE_DEVIL, MH_DEMONIC, -5, { 21, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -1103,7 +1194,8 @@ // random { MONS_BEAST, '4', BROWN, "beast", - M_NO_FLAGS, + M_EVIL, + MR_NO_FLAGS, 0, 10, MONS_BEAST, MH_DEMONIC, -3, { 12, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -1114,7 +1206,8 @@ { MONS_IRON_DEVIL, '3', CYAN, "iron devil", - M_RES_ELEC | M_RES_POISON | M_RES_HELLFIRE | M_RES_COLD, + M_EVIL, + MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD, 0, 10, MONS_IRON_DEVIL, MH_DEMONIC, -6, { 14, 14, 0, 0 }, { 8, 3, 5, 0 }, @@ -1126,6 +1219,7 @@ { MONS_GLOWING_SHAPESHIFTER, '@', RED, "glowing shapeshifter", M_NO_FLAGS, + MR_NO_FLAGS, 600, 10, MONS_SHAPESHIFTER, MH_NATURAL, -6, { 15, 0, 0, 0 }, { 10, 3, 5, 0 }, @@ -1137,6 +1231,7 @@ { MONS_SHAPESHIFTER, '@', LIGHTRED, "shapeshifter", M_NO_FLAGS, + MR_NO_FLAGS, 600, 10, MONS_SHAPESHIFTER, MH_NATURAL, -6, { 5, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -1147,7 +1242,8 @@ { MONS_GIANT_MITE, 's', LIGHTRED, "giant mite", - M_ED_POISON, + M_NO_FLAGS, + MR_VUL_POISON, 350, 10, MONS_GIANT_MITE, MH_NATURAL, -1, { 5, 0, 0, 0 }, { 2, 3, 5, 0 }, @@ -1159,6 +1255,7 @@ { MONS_STEAM_DRAGON, 'd', LIGHTGREY, "steam dragon", M_SPELLCASTER | M_FLIES, + MR_NO_FLAGS, 1000, 10, MONS_STEAM_DRAGON, MH_NATURAL, -3, { 12, 0, 0, 0 }, { 4, 5, 5, 0 }, @@ -1170,6 +1267,7 @@ { MONS_VERY_UGLY_THING, 'u', RED, "very ugly thing", M_WARM_BLOOD | M_AMPHIBIOUS, + MR_NO_FLAGS, 750, 10, MONS_VERY_UGLY_THING, MH_NATURAL, -3, { 17, 0, 0, 0 }, { 12, 3, 5, 0 }, @@ -1180,7 +1278,8 @@ { MONS_ORC_SORCERER, 'o', DARKGREY, "orc sorcerer", - M_RES_FIRE | M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_ACTUAL_SPELLS | M_WARM_BLOOD, + M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, + MR_RES_FIRE, 600, 12, MONS_ORC, MH_NATURAL, -3, { 7, 0, 0, 0 }, { 8, 2, 3, 0 }, @@ -1192,6 +1291,7 @@ { MONS_HIPPOGRIFF, 'H', BROWN, "hippogriff", M_FLIES | M_WARM_BLOOD, + MR_NO_FLAGS, 1000, 10, MONS_HIPPOGRIFF, MH_NATURAL, -3, { 10, 8, 8, 0 }, { 7, 3, 5, 0 }, @@ -1203,6 +1303,7 @@ { MONS_GRIFFON, 'H', YELLOW, "griffon", M_FLIES | M_WARM_BLOOD, + MR_NO_FLAGS, 1800, 10, MONS_GRIFFON, MH_NATURAL, -3, { 18, 10, 10, 0 }, { 12, 3, 5, 0 }, @@ -1213,7 +1314,8 @@ { MONS_HYDRA, 'D', LIGHTGREEN, "hydra", - M_RES_POISON | M_AMPHIBIOUS, // because it likes the swamp -- bwr + M_AMPHIBIOUS, // because it likes the swamp -- bwr + MR_RES_POISON, 1800, 11, MONS_HYDRA, MH_NATURAL, -3, { 18, 0, 0, 0 }, { 13, 3, 5, 0 }, @@ -1225,7 +1327,8 @@ // small skeleton { MONS_SKELETON_SMALL, 'z', LIGHTGREY, "", - M_RES_POISON | M_RES_COLD, + M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_SKELETON_SMALL, MH_UNDEAD, -1, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, @@ -1237,7 +1340,8 @@ // large skeleton { MONS_SKELETON_LARGE, 'Z', LIGHTGREY, "", - M_RES_POISON | M_RES_COLD, + M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_SKELETON_LARGE, MH_UNDEAD, -1, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, @@ -1249,7 +1353,8 @@ { MONS_HELL_KNIGHT, '@', RED, "hell knight", - M_RES_FIRE | M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, + MR_RES_FIRE, 550, 10, MONS_HUMAN, MH_NATURAL, -3, { 13, 0, 0, 0 }, { 10, 3, 6, 0 }, @@ -1260,7 +1365,8 @@ { MONS_NECROMANCER, '@', DARKGREY, "necromancer", - M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 550, 10, MONS_HUMAN, MH_NATURAL, -4, { 6, 0, 0, 0 }, { 10, 2, 4, 0 }, @@ -1271,7 +1377,8 @@ { MONS_WIZARD, '@', MAGENTA, "wizard", - M_RES_ELEC | M_SPELLCASTER | M_SPEAKS | M_ACTUAL_SPELLS | M_WARM_BLOOD, + M_SPELLCASTER | M_SPEAKS | M_ACTUAL_SPELLS | M_WARM_BLOOD, + MR_RES_ELEC, 550, 10, MONS_HUMAN, MH_NATURAL, -4, { 6, 0, 0, 0 }, { 10, 2, 4, 0 }, @@ -1282,7 +1389,8 @@ { MONS_ORC_PRIEST, 'o', LIGHTGREEN, "orc priest", - M_SPELLCASTER | M_PRIEST | M_WARM_BLOOD, + M_SPELLCASTER | M_PRIEST | M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 600, 10, MONS_ORC, MH_NATURAL, -4, { 6, 0, 0, 0 }, { 3, 3, 4, 0 }, @@ -1293,7 +1401,8 @@ { MONS_ORC_HIGH_PRIEST, 'o', GREEN, "orc high priest", - M_RES_HELLFIRE | M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_PRIEST | M_WARM_BLOOD, + M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_PRIEST | M_WARM_BLOOD | M_EVIL, + MR_RES_HELLFIRE, 600, 10, MONS_ORC, MH_NATURAL, -4, { 7, 0, 0, 0 }, { 11, 3, 4, 0 }, @@ -1310,6 +1419,7 @@ { MONS_HUMAN, '@', LIGHTGRAY, "human", M_WARM_BLOOD, + MR_NO_FLAGS, 550, 10, MONS_HUMAN, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 1, 3, 5, 0 }, @@ -1321,6 +1431,7 @@ { MONS_GNOLL, 'g', YELLOW, "gnoll", M_WARM_BLOOD, + MR_NO_FLAGS, 750, 10, MONS_GNOLL, MH_NATURAL, -3, { 9, 0, 0, 0 }, { 2, 4, 5, 0 }, @@ -1331,7 +1442,8 @@ { MONS_CLAY_GOLEM, '8', BROWN, "clay golem", - M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_RES_ELEC | M_SEE_INVIS, + M_SEE_INVIS, + MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_CLAY_GOLEM, MH_NONLIVING, 5000, { 11, 11, 0, 0 }, { 8, 7, 3, 0 }, @@ -1342,7 +1454,8 @@ { MONS_WOOD_GOLEM, '8', YELLOW, "wood golem", - M_RES_POISON | M_ED_FIRE | M_RES_COLD | M_RES_ELEC, + M_NO_FLAGS, + MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_WOOD_GOLEM, MH_NONLIVING, 5000, { 10, 0, 0, 0 }, { 6, 6, 3, 0 }, @@ -1353,7 +1466,8 @@ { MONS_STONE_GOLEM, '8', LIGHTGREY, "stone golem", - M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_RES_ELEC, + M_NO_FLAGS, + MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_STONE_GOLEM, MH_NONLIVING, 5000, { 28, 0, 0, 0 }, { 12, 7, 4, 0 }, @@ -1364,7 +1478,8 @@ { MONS_IRON_GOLEM, '8', CYAN, "iron golem", - M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_RES_ELEC | M_SEE_INVIS, + M_SEE_INVIS, + MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_IRON_GOLEM, MH_NONLIVING, 5000, { 35, 0, 0, 0 }, { 15, 7, 4, 0 }, @@ -1375,7 +1490,8 @@ { MONS_CRYSTAL_GOLEM, '8', WHITE, "crystal golem", - M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_RES_ELEC | M_SEE_INVIS, + M_SEE_INVIS, + MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_CRYSTAL_GOLEM, MH_NONLIVING, 5000, { 40, 0, 0, 0 }, { 13, 7, 4, 0 }, @@ -1386,7 +1502,8 @@ { MONS_TOENAIL_GOLEM, '8', LIGHTGREY, "toenail golem", - M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_RES_ELEC, + M_NO_FLAGS, + MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_TOENAIL_GOLEM, MH_NONLIVING, 5000, { 13, 0, 0, 0 }, { 9, 5, 3, 0 }, @@ -1397,7 +1514,8 @@ { MONS_MOTTLED_DRAGON, 'd', LIGHTMAGENTA, "mottled dragon", - M_RES_POISON | M_RES_FIRE | M_SPELLCASTER | M_FLIES, + M_SPELLCASTER | M_FLIES, + MR_RES_POISON | MR_RES_FIRE, 1100, 10, MONS_MOTTLED_DRAGON, MH_NATURAL, -3, { 15, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -1408,7 +1526,8 @@ { MONS_EARTH_ELEMENTAL, '#', BROWN, "earth elemental", - M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_RES_ELEC, + M_NO_FLAGS, + MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_EARTH_ELEMENTAL, MH_NONLIVING, 5000, { 40, 0, 0, 0 }, { 6, 5, 5, 0 }, @@ -1419,7 +1538,8 @@ { MONS_FIRE_ELEMENTAL, '#', YELLOW, "fire elemental", - M_RES_POISON | M_RES_HELLFIRE | M_ED_COLD | M_RES_ELEC | M_FLIES, + M_FLIES, + MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD | MR_RES_ELEC, 0, 10, MONS_FIRE_ELEMENTAL, MH_NONLIVING, 5000, { 5, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -1430,7 +1550,8 @@ { MONS_AIR_ELEMENTAL, 'v', LIGHTGREY, "air elemental", - M_RES_ELEC | M_RES_POISON | M_LEVITATE | M_SEE_INVIS | M_FLIES, + M_LEVITATE | M_SEE_INVIS | M_FLIES, + MR_RES_ELEC | MR_RES_POISON, 0, 5, MONS_AIR_ELEMENTAL, MH_NONLIVING, 5000, { 15, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -1443,7 +1564,8 @@ { MONS_ICE_FIEND, '1', WHITE, "Ice Fiend", - M_RES_POISON | M_ED_FIRE | M_RES_COLD | M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_FROZEN, + M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_FROZEN | M_EVIL, + MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 10, MONS_ICE_FIEND, MH_DEMONIC, -12, { 25, 25, 0, 0 }, { 18, 3, 5, 0 }, @@ -1454,7 +1576,8 @@ { MONS_SHADOW_FIEND, '1', DARKGREY, "Shadow Fiend", - M_RES_POISON | M_RES_COLD | M_RES_ELEC | M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS, + M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_SHADOW_FIEND, MH_DEMONIC, -13, { 25, 15, 15, 0 }, { 18, 3, 5, 0 }, @@ -1465,7 +1588,8 @@ { MONS_BROWN_SNAKE, 'S', BROWN, "brown snake", - M_RES_POISON | M_COLD_BLOOD | M_AMPHIBIOUS, + M_COLD_BLOOD | M_AMPHIBIOUS, + MR_RES_POISON, 300, 10, MONS_BROWN_SNAKE, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 4, 3, 5, 0 }, @@ -1477,6 +1601,7 @@ { MONS_GIANT_LIZARD, 'l', GREEN, "giant lizard", M_COLD_BLOOD, + MR_NO_FLAGS, 600, 10, MONS_GIANT_LIZARD, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -1487,7 +1612,8 @@ { MONS_SPECTRAL_WARRIOR, 'W', LIGHTGREEN, "spectral warrior", - M_RES_POISON | M_RES_COLD | M_LEVITATE | M_SEE_INVIS, + M_LEVITATE | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 13, MONS_SPECTRAL_WARRIOR, MH_UNDEAD, -6, { 18, 0, 0, 0 }, { 9, 3, 5, 0 }, @@ -1498,7 +1624,8 @@ { MONS_PULSATING_LUMP, 'J', RED, "pulsating lump", - M_RES_POISON | M_SEE_INVIS, + M_SEE_INVIS, + MR_RES_POISON, 0, 3, MONS_PULSATING_LUMP, MH_NATURAL, -3, { 13, 0, 0, 0 }, { 10, 3, 5, 0 }, @@ -1509,7 +1636,8 @@ { MONS_STORM_DRAGON, 'D', LIGHTBLUE, "storm dragon", - M_RES_ELEC | M_RES_COLD | M_SPELLCASTER | M_FLIES, + M_SPELLCASTER | M_FLIES, + MR_RES_ELEC | MR_RES_COLD, 2800, 12, MONS_STORM_DRAGON, MH_NATURAL, -5, { 25, 15, 15, 0 }, { 14, 5, 5, 0 }, @@ -1521,6 +1649,7 @@ { MONS_YAKTAUR, 'c', LIGHTRED, "yaktaur", M_WARM_BLOOD, + MR_NO_FLAGS, 2000, 10, MONS_YAKTAUR, MH_NATURAL, -3, { 15, 0, 0, 0 }, { 8, 3, 5, 0 }, @@ -1531,7 +1660,8 @@ { MONS_DEATH_YAK, 'Y', DARKGREY, "death yak", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 1500, 10, MONS_DEATH_YAK, MH_NATURAL, -5, { 30, 0, 0, 0 }, { 14, 3, 5, 0 }, @@ -1542,7 +1672,8 @@ { MONS_ROCK_TROLL, 'T', LIGHTGREY, "rock troll", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 2200, 11, MONS_ROCK_TROLL, MH_NATURAL, -4, { 30, 20, 20, 0 }, { 11, 3, 5, 0 }, @@ -1553,7 +1684,8 @@ { MONS_STONE_GIANT, 'C', LIGHTGREY, "stone giant", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 3000, 10, MONS_STONE_GIANT, MH_NATURAL, -4, { 45, 0, 0, 0 }, { 16, 3, 5, 0 }, @@ -1564,7 +1696,8 @@ { MONS_FLAYED_GHOST, 'p', RED, "flayed ghost", - M_RES_POISON | M_FLIES, + M_FLIES | M_EVIL, + MR_RES_POISON, 0, 10, MONS_FLAYED_GHOST, MH_UNDEAD, -4, { 30, 0, 0, 0 }, { 11, 3, 5, 0 }, @@ -1575,7 +1708,8 @@ { MONS_BUMBLEBEE, 'k', RED, "bumblebee", - M_ED_POISON | M_FLIES, + M_FLIES, + MR_VUL_POISON, 300, 10, MONS_BUMBLEBEE, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -1586,7 +1720,8 @@ { MONS_REDBACK, 's', RED, "redback", - M_ED_POISON, + M_NO_FLAGS, + MR_VUL_POISON, 1000, 14, MONS_REDBACK, MH_NATURAL, -3, { 18, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -1597,7 +1732,8 @@ { MONS_INSUBSTANTIAL_WISP, 'p', LIGHTGREY, "insubstantial wisp", - M_RES_ELEC | M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_LEVITATE, + M_LEVITATE, + MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, 0, 17, MONS_INSUBSTANTIAL_WISP, MH_NONLIVING, 5000, { 12, 0, 0, 0 }, { 6, 1, 2, 0 }, @@ -1608,7 +1744,8 @@ { MONS_VAPOUR, '#', LIGHTGREY, "vapour", - M_RES_ELEC | M_RES_POISON | M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS | M_INVIS | M_CONFUSED, + M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS | M_INVIS | M_CONFUSED, + MR_RES_ELEC | MR_RES_POISON, 0, 21, MONS_VAPOUR, MH_NONLIVING, 5000, { 0, 0, 0, 0 }, { 12, 2, 3, 0 }, @@ -1619,7 +1756,8 @@ { MONS_OGRE_MAGE, 'O', MAGENTA, "ogre-mage", - M_RES_ELEC | M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD | M_EVIL, + MR_RES_ELEC, 0, 16, MONS_OGRE, MH_NATURAL, -6, { 12, 0, 0, 0 }, { 10, 3, 5, 0 }, @@ -1630,7 +1768,8 @@ { MONS_SPINY_WORM, 'w', DARKGREY, "spiny worm", - M_ED_POISON, + M_NO_FLAGS, + MR_VUL_POISON, 1300, 13, MONS_SPINY_WORM, MH_NATURAL, -3, { 32, 0, 0, 0 }, { 12, 3, 5, 0 }, @@ -1643,7 +1782,8 @@ // to examine them. { MONS_DANCING_WEAPON, '(', BLACK, "dancing weapon", - M_RES_POISON | M_RES_HELLFIRE | M_RES_COLD | M_RES_ELEC | M_LEVITATE, + M_LEVITATE, + MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_DANCING_WEAPON, MH_NONLIVING, 5000, { 30, 0, 0, 0 }, { 15, 0, 0, 15 }, @@ -1654,7 +1794,8 @@ { MONS_TITAN, 'C', MAGENTA, "titan", - M_RES_ELEC | M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS, + M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, + MR_RES_ELEC, 3500, 12, MONS_TITAN, MH_NATURAL, -7, { 55, 0, 0, 0 }, { 20, 3, 5, 0 }, @@ -1665,7 +1806,8 @@ { MONS_GOLDEN_DRAGON, 'D', YELLOW, "golden dragon", - M_RES_ELEC | M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_SPELLCASTER | M_FLIES | M_SEE_INVIS, + M_SPELLCASTER | M_FLIES | M_SEE_INVIS, + MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, 3000, 17, MONS_GOLDEN_DRAGON, MH_NATURAL, -8, { 40, 20, 20, 0 }, { 18, 4, 4, 0 }, @@ -1679,6 +1821,7 @@ { MONS_ELF, 'e', DARKGREY, "elf", M_WARM_BLOOD, + MR_NO_FLAGS, 450, 10, MONS_ELF, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 3, 3, 3, 0 }, @@ -1694,6 +1837,7 @@ { MONS_LINDWURM, 'd', LIGHTGREEN, "lindwurm", M_NO_FLAGS, + MR_NO_FLAGS, 1000, 11, MONS_LINDWURM, MH_NATURAL, -3, { 20, 10, 10, 0 }, { 9, 3, 5, 0 }, @@ -1704,7 +1848,8 @@ { MONS_ELEPHANT_SLUG, 'm', LIGHTGREY, "elephant slug", - M_ED_POISON | M_NO_SKELETON, + M_NO_SKELETON, + MR_VUL_POISON, 1500, 10, MONS_ELEPHANT_SLUG, MH_NATURAL, -3, { 40, 0, 0, 0 }, { 20, 5, 3, 0 }, @@ -1716,6 +1861,7 @@ { MONS_WAR_DOG, 'h', CYAN, "war dog", M_SEE_INVIS | M_WARM_BLOOD, + MR_NO_FLAGS, 350, 10, MONS_WAR_DOG, MH_NATURAL, -3, { 12, 0, 0, 0 }, { 4, 3, 5, 0 }, @@ -1727,6 +1873,7 @@ { MONS_GREY_RAT, 'r', LIGHTGREY, "grey rat", M_WARM_BLOOD, + MR_NO_FLAGS, 250, 10, MONS_GREY_RAT, MH_NATURAL, -3, { 5, 0, 0, 0 }, { 1, 3, 6, 0 }, @@ -1738,6 +1885,7 @@ { MONS_GREEN_RAT, 'r', LIGHTGREEN, "green rat", M_WARM_BLOOD, + MR_NO_FLAGS, 250, 10, MONS_GREEN_RAT, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 2, 3, 5, 0 }, @@ -1749,6 +1897,7 @@ { MONS_ORANGE_RAT, 'r', LIGHTRED, "orange rat", M_WARM_BLOOD, + MR_NO_FLAGS, 250, 10, MONS_ORANGE_RAT, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 3, 3, 5, 0 }, @@ -1759,7 +1908,8 @@ { MONS_BLACK_SNAKE, 'S', DARKGREY, "black snake", - M_RES_POISON | M_COLD_BLOOD, + M_COLD_BLOOD, + MR_RES_POISON, 500, 12, MONS_BLACK_SNAKE, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -1771,6 +1921,7 @@ { MONS_SHEEP, 'Y', LIGHTGREY, "sheep", M_WARM_BLOOD, + MR_NO_FLAGS, 1200, 10, MONS_SHEEP, MH_NATURAL, -3, { 13, 0, 0, 0 }, { 3, 3, 5, 0 }, @@ -1781,7 +1932,8 @@ { MONS_GHOUL, 'n', RED, "ghoul", - M_RES_POISON | M_RES_COLD, + M_EVIL, + MR_RES_POISON | MR_RES_COLD, 500, 12, MONS_GHOUL, MH_UNDEAD, -5, { 9, 0, 0, 0 }, { 4, 3, 5, 0 }, @@ -1793,6 +1945,7 @@ { MONS_HOG, 'h', LIGHTRED, "hog", M_WARM_BLOOD, + MR_NO_FLAGS, 700, 10, MONS_HOG, MH_NATURAL, -3, { 14, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -1803,7 +1956,8 @@ { MONS_GIANT_MOSQUITO, 'y', DARKGREY, "giant mosquito", - M_ED_POISON | M_FLIES, + M_FLIES, + MR_VUL_POISON, 100, 10, MONS_GIANT_MOSQUITO, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 1, 3, 5, 0 }, @@ -1814,7 +1968,8 @@ { MONS_GIANT_CENTIPEDE, 's', GREEN, "giant centipede", - M_ED_POISON, + M_NO_FLAGS, + MR_VUL_POISON, 350, 10, MONS_GIANT_CENTIPEDE, MH_NATURAL, -3, { 2, 0, 0, 0 }, { 2, 3, 3, 0 }, @@ -1827,7 +1982,8 @@ { MONS_IRON_TROLL, 'T', CYAN, "iron troll", - M_RES_FIRE | M_RES_COLD | M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_RES_FIRE | MR_RES_COLD, 2400, 10, MONS_IRON_TROLL, MH_NATURAL, -5, { 35, 25, 25, 0 }, { 16, 3, 5, 0 }, @@ -1838,7 +1994,8 @@ { MONS_NAGA, 'N', GREEN, "naga", - M_RES_POISON | M_SPELLCASTER | M_SEE_INVIS | M_WARM_BLOOD, + M_SPELLCASTER | M_SEE_INVIS | M_WARM_BLOOD, + MR_RES_POISON, 750, 10, MONS_NAGA, MH_NATURAL, -6, { 6, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -1849,7 +2006,8 @@ { MONS_FIRE_GIANT, 'C', RED, "fire giant", - M_RES_FIRE | M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS, + M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, + MR_RES_FIRE, 2400, 11, MONS_FIRE_GIANT, MH_NATURAL, -4, { 30, 0, 0, 0 }, { 16, 3, 6, 0 }, @@ -1860,7 +2018,8 @@ { MONS_FROST_GIANT, 'C', LIGHTBLUE, "frost giant", - M_RES_COLD | M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS, + M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, + MR_RES_COLD, 2600, 11, MONS_FROST_GIANT, MH_NATURAL, -4, { 35, 0, 0, 0 }, { 16, 4, 5, 0 }, @@ -1871,7 +2030,8 @@ { MONS_FIREDRAKE, 'd', RED, "firedrake", - M_RES_FIRE | M_FLIES, + M_FLIES, + MR_RES_FIRE, 900, 10, MONS_FIREDRAKE, MH_NATURAL, -3, { 8, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -1882,7 +2042,8 @@ { MONS_SHADOW_DRAGON, 'D', DARKGREY, "shadow dragon", - M_RES_POISON | M_RES_COLD | M_SPELLCASTER | M_FLIES | M_SEE_INVIS, + M_SPELLCASTER | M_FLIES | M_SEE_INVIS, + MR_RES_POISON | MR_RES_COLD, 2000, 12, MONS_SHADOW_DRAGON, MH_NATURAL, -5, { 20, 15, 15, 0 }, { 17, 5, 5, 0 }, @@ -1892,7 +2053,8 @@ , { MONS_YELLOW_SNAKE, 'S', YELLOW, "yellow snake", - M_RES_POISON | M_COLD_BLOOD, + M_COLD_BLOOD, + MR_RES_POISON, 400, 10, MONS_YELLOW_SNAKE, MH_NATURAL, -3, { 15, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -1904,6 +2066,7 @@ { MONS_GREY_SNAKE, 'S', LIGHTGREY, "grey snake", M_COLD_BLOOD, + MR_NO_FLAGS, 600, 10, MONS_GREY_SNAKE, MH_NATURAL, -3, { 30, 0, 0, 0 }, { 11, 3, 5, 0 }, @@ -1914,7 +2077,8 @@ { MONS_DEEP_TROLL, 'T', DARKGREY, "deep troll", - M_WARM_BLOOD | M_SEE_INVIS, + M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, + MR_NO_FLAGS, 1500, 12, MONS_DEEP_TROLL, MH_NATURAL, -3, { 27, 20, 20, 0 }, { 10, 3, 5, 0 }, @@ -1925,7 +2089,8 @@ { MONS_GIANT_BLOWFLY, 'y', LIGHTGREY, "giant blowfly", - M_ED_POISON | M_FLIES, + M_FLIES, + MR_VUL_POISON, 200, 10, MONS_GIANT_BLOWFLY, MH_NATURAL, -3, { 13, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -1936,7 +2101,8 @@ { MONS_RED_WASP, 'y', RED, "red wasp", - M_ED_POISON | M_FLIES, + M_FLIES, + MR_VUL_POISON, 400, 14, MONS_RED_WASP, MH_NATURAL, -3, { 23, 0, 0, 0 }, { 8, 3, 5, 0 }, @@ -1947,7 +2113,8 @@ { MONS_SWAMP_DRAGON, 'D', BROWN, "swamp dragon", - M_SPELLCASTER | M_FLIES | M_RES_POISON, + M_SPELLCASTER | M_FLIES, + MR_RES_POISON, 1900, 11, MONS_SWAMP_DRAGON, MH_NATURAL, -3, { 13, 9, 9, 0 }, { 9, 5, 5, 0 }, @@ -1958,7 +2125,8 @@ { MONS_SWAMP_DRAKE, 'd', BROWN, "swamp drake", - M_SPELLCASTER | M_FLIES | M_RES_POISON, + M_SPELLCASTER | M_FLIES | M_EVIL, + MR_RES_POISON, 900, 11, MONS_SWAMP_DRAKE, MH_NATURAL, -3, { 11, 0, 0, 0 }, { 4, 5, 5, 0 }, @@ -1969,7 +2137,8 @@ { MONS_SOLDIER_ANT, 'a', LIGHTGREY, "soldier ant", - M_ED_POISON, + M_NO_FLAGS, + MR_VUL_POISON, 900, 10, MONS_SOLDIER_ANT, MH_NATURAL, -3, { 14, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -1980,7 +2149,8 @@ { MONS_HILL_GIANT, 'C', LIGHTRED, "hill giant", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 1600, 10, MONS_HILL_GIANT, MH_NATURAL, -3, { 30, 0, 0, 0 }, { 11, 3, 5, 0 }, @@ -1991,7 +2161,8 @@ { MONS_QUEEN_ANT, 'Q', DARKGREY, "queen ant", - M_ED_POISON, + M_NO_FLAGS, + MR_VUL_POISON, 1200, 10, MONS_QUEEN_ANT, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 13, 3, 5, 0 }, @@ -2002,7 +2173,8 @@ { MONS_ANT_LARVA, 'w', LIGHTGREY, "ant larva", - M_ED_POISON | M_NO_SKELETON, + M_NO_SKELETON, + MR_VUL_POISON, 350, 5, MONS_ANT_LARVA, MH_NATURAL, -3, { 5, 0, 0, 0 }, { 2, 3, 5, 0 }, @@ -2015,6 +2187,7 @@ { MONS_GIANT_FROG, 'F', GREEN, "giant frog", M_COLD_BLOOD | M_AMPHIBIOUS, + MR_NO_FLAGS, 500, 10, MONS_GIANT_FROG, MH_NATURAL, -3, { 9, 0, 0, 0 }, { 4, 3, 5, 0 }, @@ -2026,6 +2199,7 @@ { MONS_GIANT_BROWN_FROG, 'F', BROWN, "giant brown frog", M_COLD_BLOOD | M_AMPHIBIOUS, + MR_NO_FLAGS, 890, 10, MONS_GIANT_BROWN_FROG, MH_NATURAL, -3, { 14, 0, 0, 0 }, { 8, 3, 5, 0 }, @@ -2036,7 +2210,8 @@ { MONS_SPINY_FROG, 'F', YELLOW, "spiny frog", - M_COLD_BLOOD | M_RES_POISON | M_AMPHIBIOUS, + M_COLD_BLOOD | M_AMPHIBIOUS, + MR_RES_POISON, 1000, 10, MONS_SPINY_FROG, MH_NATURAL, -3, { 26, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -2048,6 +2223,7 @@ { MONS_BLINK_FROG, 'F', LIGHTGREEN, "blink frog", M_COLD_BLOOD | M_AMPHIBIOUS, + MR_NO_FLAGS, 800, 12, MONS_BLINK_FROG, MH_NATURAL, -5, { 20, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -2058,6 +2234,7 @@ { MONS_GIANT_COCKROACH, 'a', BROWN, "giant cockroach", M_NO_FLAGS, + MR_NO_FLAGS, 250, 10, MONS_GIANT_COCKROACH, MH_NATURAL, -1, { 2, 0, 0, 0 }, { 1, 3, 4, 0 }, @@ -2068,6 +2245,7 @@ { MONS_SMALL_SNAKE, 'S', LIGHTGREEN, "small snake", M_COLD_BLOOD, + MR_NO_FLAGS, 100, 13, MONS_SMALL_SNAKE, MH_NATURAL, -1, { 2, 0, 0, 0 }, { 1, 2, 3, 0 }, @@ -2078,7 +2256,8 @@ { MONS_WHITE_IMP, '5', WHITE, "white imp", - M_RES_COLD | M_SPELLCASTER | M_FLIES | M_SPEAKS, + M_SPELLCASTER | M_FLIES | M_SPEAKS | M_EVIL, + MR_RES_COLD, 0, 10, MONS_WHITE_IMP, MH_DEMONIC, -3, { 4, 0, 0, 0 }, { 2, 3, 5, 0 }, @@ -2089,7 +2268,8 @@ { MONS_LEMURE, '5', YELLOW, "lemure", - M_RES_POISON, + M_EVIL, + MR_RES_POISON, 0, 10, MONS_LEMURE, MH_DEMONIC, -3, { 12, 0, 0, 0 }, { 2, 3, 5, 0 }, @@ -2100,7 +2280,8 @@ { MONS_UFETUBUS, '5', LIGHTCYAN, "ufetubus", - M_ED_FIRE | M_RES_COLD, + M_EVIL, + MR_VUL_FIRE | MR_RES_COLD, 0, 10, MONS_UFETUBUS, MH_DEMONIC, -3, { 5, 5, 0, 0 }, { 1, 4, 6, 0 }, @@ -2111,7 +2292,8 @@ { MONS_MANES, '5', LIGHTRED, "manes", - M_RES_ELEC | M_RES_FIRE | M_RES_COLD | M_RES_POISON, + M_EVIL, + MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON, 0, 10, MONS_MANES, MH_DEMONIC, -3, { 5, 3, 3, 0 }, { 3, 3, 5, 0 }, @@ -2122,7 +2304,8 @@ { MONS_MIDGE, '5', LIGHTGREEN, "midge", - M_RES_POISON | M_FLIES, + M_FLIES | M_EVIL, + MR_RES_POISON, 0, 10, MONS_MIDGE, MH_DEMONIC, -3, { 8, 0, 0, 0 }, { 2, 3, 5, 0 }, @@ -2133,7 +2316,8 @@ { MONS_NEQOXEC, '3', MAGENTA, "neqoxec", - M_RES_POISON | M_SPELLCASTER | M_LEVITATE, + M_SPELLCASTER | M_LEVITATE | M_EVIL, + MR_RES_POISON, 0, 12, MONS_NEQOXEC, MH_DEMONIC, -6, { 15, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -2144,7 +2328,8 @@ { MONS_ORANGE_DEMON, '3', LIGHTRED, "orange demon", - M_NO_FLAGS, + M_EVIL, + MR_NO_FLAGS, 0, 12, MONS_ORANGE_DEMON, MH_DEMONIC, -6, { 10, 5, 0, 0 }, { 8, 4, 5, 0 }, @@ -2155,7 +2340,8 @@ { MONS_HELLWING, '3', LIGHTGREY, "hellwing", - M_RES_POISON | M_SPELLCASTER | M_FLIES, + M_SPELLCASTER | M_FLIES | M_EVIL, + MR_RES_POISON, 0, 12, MONS_HELLWING, MH_DEMONIC, -6, { 17, 10, 0, 0 }, { 7, 4, 5, 0 }, @@ -2166,7 +2352,8 @@ { MONS_SMOKE_DEMON, '4', LIGHTGREY, "smoke demon", - M_RES_POISON | M_RES_FIRE | M_SPELLCASTER | M_FLIES, + M_SPELLCASTER | M_FLIES | M_EVIL, + MR_RES_POISON | MR_RES_FIRE, 0, 12, MONS_SMOKE_DEMON, MH_DEMONIC, -6, { 8, 5, 5, 0 }, { 7, 3, 5, 0 }, @@ -2177,7 +2364,8 @@ { MONS_YNOXINUL, '3', CYAN, "ynoxinul", - M_RES_ELEC | M_RES_POISON | M_RES_COLD | M_SPELLCASTER | M_FLIES | M_SEE_INVIS, + M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL, + MR_RES_ELEC | MR_RES_POISON | MR_RES_COLD, 0, 12, MONS_YNOXINUL, MH_DEMONIC, -6, { 12, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -2188,7 +2376,8 @@ { MONS_EXECUTIONER, '1', LIGHTGREY, "Executioner", - M_SPELLCASTER | M_RES_ELEC | M_RES_FIRE | M_RES_COLD | M_RES_POISON | M_SEE_INVIS, + M_SPELLCASTER | M_SEE_INVIS | M_EVIL, + MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON, 0, 14, MONS_EXECUTIONER, MH_DEMONIC, -9, { 30, 10, 10, 0 }, { 12, 3, 5, 0 }, @@ -2199,7 +2388,8 @@ { MONS_GREEN_DEATH, '1', GREEN, "Green Death", - M_RES_POISON | M_SPELLCASTER | M_SEE_INVIS, + M_SPELLCASTER | M_SEE_INVIS | M_EVIL, + MR_RES_POISON, 0, 14, MONS_GREEN_DEATH, MH_DEMONIC, -9, { 32, 0, 0, 0 }, { 13, 3, 5, 0 }, @@ -2210,7 +2400,8 @@ { MONS_BLUE_DEATH, '1', BLUE, "Blue Death", - M_RES_POISON | M_SPELLCASTER | M_ED_FIRE | M_RES_COLD | M_RES_ELEC | M_FLIES | M_SEE_INVIS, + M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 14, MONS_BLUE_DEATH, MH_DEMONIC, -9, { 20, 20, 0, 0 }, { 12, 3, 5, 0 }, @@ -2221,7 +2412,8 @@ { MONS_BALRUG, '1', RED, "Balrug", - M_RES_POISON | M_RES_HELLFIRE | M_ED_COLD | M_SPELLCASTER | M_FLIES | M_SEE_INVIS, + M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, 0, 14, MONS_BALRUG, MH_DEMONIC, -9, { 25, 0, 0, 0 }, { 14, 3, 5, 0 }, @@ -2232,7 +2424,8 @@ { MONS_CACODEMON, '1', YELLOW, "Cacodemon", - M_RES_POISON | M_RES_ELEC | M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS, + M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_ELEC, 0, 14, MONS_CACODEMON, MH_DEMONIC, -9, { 22, 0, 0, 0 }, { 13, 3, 5, 0 }, @@ -2244,7 +2437,8 @@ { MONS_DEMONIC_CRAWLER, '3', DARKGREY, "demonic crawler", - M_RES_ELEC | M_RES_POISON | M_RES_COLD | M_RES_FIRE | M_SEE_INVIS, + M_SEE_INVIS | M_EVIL, + MR_RES_ELEC | MR_RES_POISON | MR_RES_COLD | MR_RES_FIRE, 0, 12, MONS_DEMONIC_CRAWLER, MH_DEMONIC, -6, { 13, 13, 13, 13 }, { 9, 3, 5, 0 }, @@ -2255,7 +2449,8 @@ { MONS_SUN_DEMON, '2', YELLOW, "sun demon", - M_RES_ELEC | M_RES_POISON | M_ED_COLD | M_RES_HELLFIRE | M_SEE_INVIS | M_LEVITATE, + M_SEE_INVIS | M_LEVITATE | M_EVIL, + MR_RES_ELEC | MR_RES_POISON | MR_VUL_COLD | MR_RES_HELLFIRE, 0, 14, MONS_SUN_DEMON, MH_DEMONIC, -6, { 30, 0, 0, 0 }, { 10, 3, 5, 0 }, @@ -2266,7 +2461,8 @@ { MONS_SHADOW_IMP, '5', DARKGREY, "shadow imp", - M_RES_COLD | M_SPELLCASTER | M_FLIES | M_RES_POISON | M_SPEAKS, + M_SPELLCASTER | M_FLIES | M_SPEAKS | M_EVIL, + MR_RES_COLD | MR_RES_POISON, 0, 11, MONS_SHADOW_IMP, MH_DEMONIC, -3, { 6, 0, 0, 0 }, { 2, 3, 5, 0 }, @@ -2277,7 +2473,8 @@ { MONS_SHADOW_DEMON, '3', DARKGREY, "shadow demon", - M_RES_POISON | M_RES_COLD | M_SEE_INVIS | M_INVIS, + M_SEE_INVIS | M_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 12, MONS_SHADOW_DEMON, MH_DEMONIC, -7, { 21, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -2288,7 +2485,8 @@ { MONS_LOROCYPROCA, '2', BLUE, "Lorocyproca", - M_RES_POISON | M_RES_COLD | M_RES_FIRE | M_RES_ELEC | M_SEE_INVIS | M_INVIS, + M_SEE_INVIS | M_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD | MR_RES_FIRE | MR_RES_ELEC, 0, 12, MONS_LOROCYPROCA, MH_DEMONIC, -7, { 25, 25, 0, 0 }, { 12, 3, 5, 0 }, @@ -2299,7 +2497,8 @@ { MONS_SHADOW_WRAITH, 'W', BLUE, "shadow wraith", - M_RES_POISON | M_LEVITATE | M_SEE_INVIS | M_INVIS, + M_LEVITATE | M_SEE_INVIS | M_INVIS | M_EVIL, + MR_RES_POISON, 0, 15, MONS_SHADOW_WRAITH, MH_UNDEAD, -8, { 20, 0, 0, 0 }, { 10, 3, 5, 0 }, @@ -2310,7 +2509,8 @@ { MONS_GIANT_AMOEBA, 'J', BLUE, "giant amoeba", - M_RES_POISON | M_NO_SKELETON | M_SEE_INVIS | M_AMPHIBIOUS, + M_NO_SKELETON | M_SEE_INVIS | M_AMPHIBIOUS, + MR_RES_POISON, 1000, 10, MONS_GIANT_AMOEBA, MH_NATURAL, -3, { 25, 0, 0, 0 }, { 12, 3, 5, 0 }, @@ -2322,6 +2522,7 @@ { MONS_GIANT_SLUG, 'm', GREEN, "giant slug", M_NO_SKELETON | M_AMPHIBIOUS, + MR_NO_FLAGS, 700, 10, MONS_GIANT_SLUG, MH_NATURAL, -3, { 23, 0, 0, 0 }, { 10, 5, 3, 0 }, @@ -2333,6 +2534,7 @@ { MONS_GIANT_SNAIL, 'm', LIGHTGREEN, "giant snail", M_NO_SKELETON | M_AMPHIBIOUS, + MR_NO_FLAGS, 900, 10, MONS_GIANT_SNAIL, MH_NATURAL, -3, { 18, 0, 0, 0 }, { 14, 5, 3, 0 }, @@ -2343,7 +2545,8 @@ { MONS_SPATIAL_VORTEX, 'v', BLACK, "spatial vortex", - M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_RES_ELEC | M_LEVITATE | M_CONFUSED, + M_LEVITATE | M_CONFUSED, + MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 5, MONS_SPATIAL_VORTEX, MH_NONLIVING, 5000, { 50, 0, 0, 0 }, { 6, 6, 6, 0 }, @@ -2354,7 +2557,8 @@ { MONS_PIT_FIEND, '1', BROWN, "Pit Fiend", - M_RES_POISON | M_RES_HELLFIRE | M_RES_COLD | M_FLIES | M_SEE_INVIS | M_RES_ELEC, + M_FLIES | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD | MR_RES_ELEC, 0, 18, MONS_PIT_FIEND, MH_DEMONIC, -12, { 28, 21, 21, 0 }, { 19, 4, 5, 0 }, @@ -2365,7 +2569,8 @@ { MONS_BORING_BEETLE, 'B', BROWN, "boring beetle", - M_ED_POISON, + M_NO_FLAGS, + MR_VUL_POISON, 1300, 10, MONS_BORING_BEETLE, MH_NATURAL, -3, { 26, 0, 0, 0 }, { 8, 3, 5, 0 }, @@ -2376,7 +2581,8 @@ { MONS_GARGOYLE, 'g', DARKGREY, "gargoyle", - M_RES_POISON | M_RES_ELEC | M_FLIES, + M_FLIES, + MR_RES_POISON | MR_RES_ELEC, 0, 12, MONS_GARGOYLE, MH_NONLIVING, -6, { 10, 6, 6, 0 }, { 4, 3, 5, 0 }, @@ -2388,7 +2594,8 @@ // only appear in Dis castle { MONS_METAL_GARGOYLE, 'g', CYAN, "metal gargoyle", - M_RES_POISON | M_RES_ELEC | M_FLIES, + M_FLIES, + MR_RES_POISON | MR_RES_ELEC, 0, 12, MONS_METAL_GARGOYLE, MH_NONLIVING, -6, { 19, 10, 10, 0 }, { 8, 3, 5, 0 }, @@ -2400,7 +2607,8 @@ // only appear in Gehenna castle & one minivault { MONS_MOLTEN_GARGOYLE, 'g', RED, "molten gargoyle", - M_RES_POISON | M_RES_ELEC | M_FLIES | M_RES_FIRE, + M_FLIES, + MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE, 0, 12, MONS_MOLTEN_GARGOYLE, MH_NONLIVING, -6, { 12, 8, 8, 0 }, { 5, 3, 5, 0 }, @@ -2415,7 +2623,8 @@ { MONS_MNOLEG, '&', LIGHTGREEN, "Mnoleg", - M_RES_ELEC | M_RES_POISON | M_RES_FIRE | M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS, + M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS | M_EVIL, + MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE, 0, 25, MONS_MNOLEG, MH_DEMONIC, 5000, { 23, 23, 0, 0 }, { 17, 0, 0, 199 }, @@ -2426,7 +2635,8 @@ { MONS_LOM_LOBON, '&', LIGHTBLUE, "Lom Lobon", - M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_RES_ELEC | M_LEVITATE | M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS, + M_LEVITATE | M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS | M_EVIL, + MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 25, MONS_LOM_LOBON, MH_DEMONIC, 5000, { 40, 0, 0, 0 }, { 19, 0, 0, 223 }, @@ -2437,7 +2647,8 @@ { MONS_CEREBOV, '&', RED, "Cerebov", - M_RES_ELEC | M_RES_POISON | M_RES_HELLFIRE | M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS, + M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL, + MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE, 0, 25, MONS_CEREBOV, MH_DEMONIC, -6, { 50, 0, 0, 0 }, { 21, 0, 0, 253 }, @@ -2448,7 +2659,8 @@ { MONS_GLOORX_VLOQ, '&', DARKGREY, "Gloorx Vloq", - M_RES_POISON | M_RES_COLD | M_RES_ELEC | M_LEVITATE | M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS, + M_LEVITATE | M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS | M_EVIL, + MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, 0, 25, MONS_GLOORX_VLOQ, MH_DEMONIC, -14, { 20, 0, 0, 0 }, { 16, 0, 0, 234 }, @@ -2458,14 +2670,16 @@ , /* ****************************************************************** -{MONS_MOLLUSC_LORD, 'U', GREEN, "The Mollusc Lord", M_RES_POISON, +{MONS_MOLLUSC_LORD, 'U', GREEN, "The Mollusc Lord", M_NO_FLAGS, + MR_RES_POISON, 0, 25, 255, MH_DEMONIC, -3, {30,0,0,0}, {16,0,0,100}, 10, 10, 10, 7, 93, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_HIGH, 1}, ****************************************************************** */ { MONS_NAGA_MAGE, 'N', LIGHTRED, "naga mage", - M_RES_POISON | M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD, + MR_RES_POISON, 750, 13, MONS_NAGA, MH_NATURAL, -6, { 5, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -2476,7 +2690,8 @@ { MONS_NAGA_WARRIOR, 'N', BLUE, "naga warrior", - M_RES_POISON | M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD, + M_SPELLCASTER | M_SEE_INVIS | M_WARM_BLOOD, + MR_RES_POISON, 750, 12, MONS_NAGA, MH_NATURAL, -6, { 11, 0, 0, 0 }, { 10, 5, 5, 0 }, @@ -2487,7 +2702,8 @@ { MONS_ORC_WARLORD, 'o', RED, "orc warlord", - M_WARM_BLOOD, + M_WARM_BLOOD | M_EVIL, + MR_NO_FLAGS, 600, 15, MONS_ORC, MH_NATURAL, -3, { 32, 0, 0, 0 }, { 15, 4, 7, 0 }, @@ -2499,6 +2715,7 @@ { MONS_DEEP_ELF_SOLDIER, 'e', CYAN, "deep elf soldier", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, + MR_NO_FLAGS, 450, 10, MONS_ELF, MH_NATURAL, -6, { 6, 0, 0, 0 }, { 3, 3, 3, 0 }, @@ -2510,6 +2727,7 @@ { MONS_DEEP_ELF_FIGHTER, 'e', LIGHTBLUE, "deep elf fighter", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, + MR_NO_FLAGS, 450, 10, MONS_ELF, MH_NATURAL, -6, { 9, 0, 0, 0 }, { 6, 3, 3, 0 }, @@ -2521,6 +2739,7 @@ { MONS_DEEP_ELF_KNIGHT, 'e', BLUE, "deep elf knight", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, + MR_NO_FLAGS, 450, 10, MONS_ELF, MH_NATURAL, -6, { 14, 0, 0, 0 }, { 11, 3, 3, 0 }, @@ -2531,7 +2750,8 @@ { MONS_DEEP_ELF_MAGE, 'e', LIGHTRED, "deep elf mage", - M_RES_ELEC | M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, + MR_RES_ELEC, 450, 10, MONS_ELF, MH_NATURAL, -6, { 5, 0, 0, 0 }, { 4, 3, 3, 0 }, @@ -2543,6 +2763,7 @@ { MONS_DEEP_ELF_SUMMONER, 'e', YELLOW, "deep elf summoner", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, + MR_NO_FLAGS, 450, 10, MONS_ELF, MH_NATURAL, -6, { 5, 0, 0, 0 }, { 6, 3, 3, 0 }, @@ -2553,7 +2774,8 @@ { MONS_DEEP_ELF_CONJURER, 'e', LIGHTGREEN, "deep elf conjurer", - M_SPELLCASTER | M_ACTUAL_SPELLS | M_RES_ELEC | M_WARM_BLOOD, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, + MR_RES_ELEC, 450, 10, MONS_ELF, MH_NATURAL, -6, { 5, 0, 0, 0 }, { 6, 3, 3, 0 }, @@ -2565,6 +2787,7 @@ { MONS_DEEP_ELF_PRIEST, 'e', LIGHTGREY, "deep elf priest", M_SPELLCASTER | M_PRIEST | M_WARM_BLOOD, + MR_NO_FLAGS, 450, 10, MONS_ELF, MH_NATURAL, -6, { 9, 0, 0, 0 }, { 5, 3, 3, 0 }, @@ -2575,7 +2798,8 @@ { MONS_DEEP_ELF_HIGH_PRIEST, 'e', DARKGREY, "deep elf high priest", - M_SPELLCASTER | M_SPEAKS | M_PRIEST | M_WARM_BLOOD | M_SEE_INVIS, + M_SPELLCASTER | M_SPEAKS | M_PRIEST | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, + MR_NO_FLAGS, 450, 10, MONS_ELF, MH_NATURAL, -6, { 14, 0, 0, 0 }, { 11, 3, 3, 0 }, @@ -2586,7 +2810,8 @@ { MONS_DEEP_ELF_DEMONOLOGIST, 'e', MAGENTA, "deep elf demonologist", - M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, + MR_NO_FLAGS, 450, 10, MONS_ELF, MH_NATURAL, -6, { 12, 0, 0, 0 }, { 12, 3, 3, 0 }, @@ -2597,7 +2822,8 @@ { MONS_DEEP_ELF_ANNIHILATOR, 'e', GREEN, "deep elf annihilator", - M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_RES_ELEC | M_SEE_INVIS, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS, + MR_RES_ELEC, 450, 10, MONS_ELF, MH_NATURAL, -6, { 12, 0, 0, 0 }, { 15, 3, 3, 0 }, @@ -2609,6 +2835,7 @@ { MONS_DEEP_ELF_SORCERER, 'e', RED, "deep elf sorcerer", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS | M_SPEAKS, + MR_NO_FLAGS, 450, 10, MONS_ELF, MH_NATURAL, -6, { 12, 0, 0, 0 }, { 14, 3, 3, 0 }, @@ -2619,7 +2846,8 @@ { MONS_DEEP_ELF_DEATH_MAGE, 'e', WHITE, "deep elf death mage", - M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, + MR_NO_FLAGS, 450, 10, MONS_ELF, MH_NATURAL, -6, { 12, 0, 0, 0 }, { 15, 3, 3, 0 }, @@ -2630,7 +2858,8 @@ { MONS_BROWN_OOZE, 'J', BROWN, "brown ooze", - M_RES_POISON | M_NO_SKELETON | M_SEE_INVIS, + M_NO_SKELETON | M_SEE_INVIS, + MR_RES_POISON, 0, 11, MONS_BROWN_OOZE, MH_NATURAL, -7, { 25, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -2641,7 +2870,8 @@ { MONS_AZURE_JELLY, 'J', LIGHTBLUE, "azure jelly", - M_RES_POISON | M_RES_COLD | M_ED_FIRE | M_RES_ELEC | M_NO_SKELETON | M_SEE_INVIS, + M_NO_SKELETON | M_SEE_INVIS, + MR_RES_POISON | MR_RES_COLD | MR_VUL_FIRE | MR_RES_ELEC, 0, 11, MONS_AZURE_JELLY, MH_NATURAL, -4, { 12, 12, 12, 12 }, { 15, 3, 5, 0 }, @@ -2652,7 +2882,8 @@ { MONS_DEATH_OOZE, 'J', DARKGREY, "death ooze", - M_RES_POISON | M_RES_COLD | M_NO_SKELETON | M_SEE_INVIS, + M_NO_SKELETON | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 13, MONS_DEATH_OOZE, MH_UNDEAD, -8, { 32, 32, 0, 0 }, { 11, 3, 3, 0 }, @@ -2663,7 +2894,8 @@ { MONS_ACID_BLOB, 'J', LIGHTGREEN, "acid blob", - M_RES_POISON | M_NO_SKELETON | M_SEE_INVIS, + M_NO_SKELETON | M_SEE_INVIS, + MR_RES_POISON, 0, 12, MONS_ACID_BLOB, MH_NATURAL, -7, { 42, 0, 0, 0 }, { 18, 3, 5, 0 }, @@ -2674,7 +2906,8 @@ { MONS_ROYAL_JELLY, 'J', YELLOW, "royal jelly", - M_RES_POISON | M_NO_SKELETON | M_SEE_INVIS, + M_NO_SKELETON | M_SEE_INVIS, + MR_RES_POISON, 0, 20, MONS_ROYAL_JELLY, MH_NATURAL, -7, { 50, 0, 0, 0 }, { 21, 0, 0, 111 }, @@ -2685,7 +2918,8 @@ { MONS_TERENCE, '@', LIGHTCYAN, "Terence", - M_WARM_BLOOD| M_SPEAKS, + M_WARM_BLOOD | M_SPEAKS, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -3, { 3, 0, 0, 0 }, { 1, 0, 0, 14 }, @@ -2697,6 +2931,7 @@ { MONS_JESSICA, '@', LIGHTGREY, "Jessica", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -3, { 4, 0, 0, 0 }, { 1, 0, 0, 10 }, @@ -2708,6 +2943,7 @@ { MONS_IJYB, 'g', BLUE, "Ijyb", M_WARM_BLOOD | M_SPEAKS, + MR_NO_FLAGS, 0, 5, MONS_GOBLIN, MH_NATURAL, -3, { 4, 0, 0, 0 }, { 3, 0, 0, 28 }, @@ -2719,6 +2955,7 @@ { MONS_SIGMUND, '@', YELLOW, "Sigmund", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -3, { 5, 0, 0, 0 }, { 3, 0, 0, 25 }, @@ -2730,6 +2967,7 @@ { MONS_BLORK_THE_ORC, 'o', BROWN, "Blork the orc", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, + MR_NO_FLAGS, 0, 20, MONS_ORC, MH_NATURAL, -4, { 7, 0, 0, 0 }, { 3, 0, 0, 32 }, @@ -2741,6 +2979,7 @@ { MONS_EDMUND, '@', RED, "Edmund", M_WARM_BLOOD | M_SPEAKS, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -4, { 6, 0, 0, 0 }, { 4, 0, 0, 27 }, @@ -2752,6 +2991,7 @@ { MONS_PSYCHE, '@', LIGHTMAGENTA, "Psyche", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -4, { 7, 0, 0, 0 }, { 5, 0, 0, 24 }, @@ -2762,7 +3002,8 @@ { MONS_EROLCHA, 'O', LIGHTBLUE, "Erolcha", - M_RES_ELEC | M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD | M_SPEAKS, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD | M_SPEAKS | M_EVIL, + MR_RES_ELEC, 0, 20, MONS_OGRE, MH_NATURAL, -7, { 20, 0, 0, 0 }, { 6, 0, 0, 45 }, @@ -2774,6 +3015,7 @@ { MONS_DONALD, '@', BLUE, "Donald", M_WARM_BLOOD | M_SPEAKS, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 8, 0, 0, 0 }, { 5, 0, 0, 33 }, @@ -2785,6 +3027,7 @@ { MONS_URUG, 'o', RED, "Urug", M_WARM_BLOOD | M_SPEAKS, + MR_NO_FLAGS, 0, 20, MONS_ORC, MH_NATURAL, -5, { 12, 0, 0, 0 }, { 6, 0, 0, 38 }, @@ -2796,6 +3039,7 @@ { MONS_MICHAEL, '@', LIGHTGREY, "Michael", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 9, 0, 0, 0 }, { 6, 0, 0, 36 }, @@ -2807,6 +3051,7 @@ { MONS_JOSEPH, '@', CYAN, "Joseph", M_WARM_BLOOD | M_SPEAKS, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 9, 0, 0, 0 }, { 7, 0, 0, 42 }, @@ -2817,7 +3062,8 @@ { MONS_SNORG, 'T', GREEN, "Snorg", - M_WARM_BLOOD | M_SPEAKS, + M_WARM_BLOOD | M_SPEAKS | M_EVIL, + MR_NO_FLAGS, 0, 20, MONS_TROLL, MH_NATURAL, -6, { 20, 15, 15, 0 }, { 8, 0, 0, 45 }, @@ -2829,6 +3075,7 @@ { MONS_ERICA, '@', MAGENTA, "Erica", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 10, 0, 0, 0 }, { 9, 0, 0, 43 }, @@ -2840,6 +3087,7 @@ { MONS_JOSEPHINE, '@', WHITE, "Josephine", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 11, 0, 0, 0 }, { 9, 0, 0, 47 }, @@ -2851,6 +3099,7 @@ { MONS_HAROLD, '@', LIGHTGREEN, "Harold", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 12, 0, 0, 0 }, { 9, 0, 0, 51 }, @@ -2862,6 +3111,7 @@ { MONS_NORBERT, '@', BROWN, "Norbert", M_WARM_BLOOD | M_SPEAKS, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 14, 0, 0, 0 }, { 10, 0, 0, 53 }, @@ -2873,6 +3123,7 @@ { MONS_JOZEF, '@', LIGHTMAGENTA, "Jozef", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 14, 0, 0, 0 }, { 11, 0, 0, 60 }, @@ -2884,6 +3135,7 @@ { MONS_AGNES, '@', LIGHTBLUE, "Agnes", M_WARM_BLOOD | M_SPEAKS, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 11, 0, 0, 0 }, { 11, 0, 0, 64 }, @@ -2895,6 +3147,7 @@ { MONS_MAUD, '@', RED, "Maud", M_WARM_BLOOD | M_SPEAKS, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 14, 0, 0, 0 }, { 13, 0, 0, 55 }, @@ -2905,7 +3158,8 @@ { MONS_LOUISE, '@', BLUE, "Louise", - M_SPELLCASTER | M_RES_ELEC | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, + MR_RES_ELEC, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 12, 0, 0, 0 }, { 13, 0, 0, 52 }, @@ -2916,7 +3170,8 @@ { MONS_FRANCIS, '@', YELLOW, "Francis", - M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 12, 0, 0, 0 }, { 14, 0, 0, 67 }, @@ -2927,7 +3182,8 @@ { MONS_FRANCES, '@', YELLOW, "Frances", - M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 11, 0, 0, 0 }, { 14, 0, 0, 70 }, @@ -2938,7 +3194,8 @@ { MONS_RUPERT, '@', RED, "Rupert", - M_SPELLCASTER | M_RES_ELEC | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS, + MR_RES_ELEC, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 13, 0, 0, 0 }, { 16, 0, 0, 80 }, @@ -2950,6 +3207,7 @@ { MONS_WAYNE, '@', YELLOW, "Wayne", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 14, 0, 0, 0 }, { 17, 0, 0, 78 }, @@ -2961,6 +3219,7 @@ { MONS_DUANE, '@', YELLOW, "Duane", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 14, 0, 0, 0 }, { 18, 0, 0, 83 }, @@ -2971,7 +3230,8 @@ { MONS_XTAHUA, 'D', RED, "Xtahua", - M_SPEAKS | M_SEE_INVIS | M_RES_POISON | M_RES_FIRE | M_ED_COLD | M_FLIES, + M_SPEAKS | M_SEE_INVIS | M_FLIES, + MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD, 0, 20, MONS_DRAGON, MH_NATURAL, -7, { 29, 17, 17, 0 }, { 19, 0, 0, 133 }, @@ -2982,7 +3242,8 @@ { MONS_NORRIS, '@', LIGHTRED, "Norris", - M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 16, 0, 0, 0 }, { 20, 0, 0, 95 }, @@ -2993,7 +3254,8 @@ { MONS_ADOLF, '@', DARKGREY, "Adolf", - M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 17, 0, 0, 0 }, { 21, 0, 0, 105 }, @@ -3005,6 +3267,7 @@ { MONS_MARGERY, '@', RED, "Margery", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS, + MR_NO_FLAGS, 0, 20, MONS_HUMAN, MH_NATURAL, -5, { 18, 0, 0, 0 }, { 22, 0, 0, 119 }, @@ -3015,7 +3278,8 @@ { MONS_BORIS, 'L', RED, "Boris", - M_RES_POISON | M_RES_COLD | M_RES_ELEC | M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_SPEAKS, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_SPEAKS | M_EVIL, + MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, 0, 23, MONS_LICH, MH_UNDEAD, -11, { 15, 0, 0, 0 }, { 22, 0, 0, 99 }, @@ -3027,7 +3291,8 @@ { MONS_GERYON, '&', GREEN, "Geryon", - M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS, + M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL, + MR_NO_FLAGS, 0, 25, MONS_GERYON, MH_DEMONIC, -6, { 30, 0, 0, 0 }, { 15, 0, 0, 240 }, @@ -3038,7 +3303,8 @@ { MONS_DISPATER, '&', MAGENTA, "Dispater", - M_RES_ELEC | M_RES_POISON | M_RES_HELLFIRE | M_RES_COLD | M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS, + M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL, + MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD, 0, 25, MONS_DISPATER, MH_DEMONIC, -10, { 15, 0, 0, 0 }, { 16, 0, 0, 222 }, @@ -3049,7 +3315,8 @@ { MONS_ASMODEUS, '&', LIGHTMAGENTA, "Asmodeus", - M_RES_ELEC | M_RES_POISON | M_RES_HELLFIRE | M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_SPEAKS, + M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_SPEAKS | M_EVIL, + MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE, 0, 25, MONS_ASMODEUS, MH_DEMONIC, -12, { 20, 0, 0, 0 }, { 17, 0, 0, 245 }, @@ -3061,7 +3328,8 @@ // Antaeus is now demonic so that he'll resist torment. -- bwr { MONS_ANTAEUS, 'C', LIGHTCYAN, "Antaeus", - M_RES_ELEC | M_ED_FIRE | M_RES_COLD | M_SPELLCASTER | M_SPEAKS, + M_SPELLCASTER | M_SPEAKS, + MR_RES_ELEC | MR_VUL_FIRE | MR_RES_COLD, 0, 25, MONS_ANTAEUS, MH_DEMONIC, -9, { 30, 0, 0, 0 }, { 22, 0, 0, 250 }, @@ -3072,7 +3340,8 @@ { MONS_ERESHKIGAL, '&', WHITE, "Ereshkigal", - M_RES_ELEC | M_RES_POISON | M_RES_COLD | M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS, + M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL, + MR_RES_ELEC | MR_RES_POISON | MR_RES_COLD, 0, 25, MONS_ERESHKIGAL, MH_DEMONIC, -10, { 20, 0, 0, 0 }, { 18, 0, 0, 238 }, @@ -3083,7 +3352,8 @@ { MONS_ANCIENT_LICH, 'L', DARKGREY, "ancient lich", - M_RES_POISON | M_RES_COLD | M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_RES_FIRE | M_RES_ELEC, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD | MR_RES_FIRE | MR_RES_ELEC, 0, 20, MONS_LICH, MH_UNDEAD, -14, { 20, 0, 0, 0 }, { 27, 2, 4, 0 }, @@ -3095,7 +3365,8 @@ { MONS_OOZE, 'J', LIGHTGREY, "ooze", - M_RES_POISON | M_NO_SKELETON | M_SEE_INVIS, + M_NO_SKELETON | M_SEE_INVIS, + MR_RES_POISON, 0, 5, MONS_OOZE, MH_NATURAL, -6, { 5, 0, 0, 0 }, { 3, 3, 5, 0 }, @@ -3107,6 +3378,7 @@ { MONS_VAULT_GUARD, '@', CYAN, "vault guard", M_WARM_BLOOD | M_SEE_INVIS, + MR_NO_FLAGS, 0, 12, MONS_HUMAN, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 13, 3, 5, 0 }, @@ -3119,7 +3391,8 @@ placed in the Crypt. */ { MONS_CURSE_SKULL, 'z', DARKGREY, "curse skull", - M_RES_ELEC | M_RES_POISON | M_RES_HELLFIRE | M_RES_COLD | M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS, + M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS | M_EVIL, + MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD, 0, 50, MONS_CURSE_SKULL, MH_UNDEAD, 5000, { 0, 0, 0, 0 }, { 13, 0, 0, 66 }, @@ -3130,7 +3403,8 @@ { MONS_VAMPIRE_KNIGHT, 'V', CYAN, "vampire knight", - M_RES_POISON | M_RES_COLD | M_SPELLCASTER | M_SEE_INVIS, + M_SPELLCASTER | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 13, MONS_VAMPIRE, MH_UNDEAD, -6, { 33, 0, 0, 0 }, { 11, 3, 7, 0 }, @@ -3141,7 +3415,8 @@ { MONS_VAMPIRE_MAGE, 'V', MAGENTA, "vampire mage", - M_RES_POISON | M_RES_COLD | M_SPELLCASTER | M_SEE_INVIS | M_FLIES, + M_SPELLCASTER | M_SEE_INVIS | M_FLIES | M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 15, MONS_VAMPIRE, MH_UNDEAD, -6, { 22, 0, 0, 0 }, { 8, 3, 4, 0 }, @@ -3153,6 +3428,7 @@ { MONS_SHINING_EYE, 'G', LIGHTMAGENTA, "shining eye", M_NO_SKELETON | M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS, + MR_NO_FLAGS, 0, 14, MONS_SHINING_EYE, MH_NATURAL, 5000, { 0, 0, 0, 0 }, { 10, 3, 5, 0 }, @@ -3164,6 +3440,7 @@ { MONS_ORB_GUARDIAN, 'X', MAGENTA, "Orb Guardian", M_NO_SKELETON | M_SEE_INVIS, + MR_NO_FLAGS, 0, 20, MONS_ORB_GUARDIAN, MH_NATURAL, -6, { 40, 0, 0, 0 }, { 15, 3, 5, 0 }, @@ -3174,7 +3451,8 @@ { MONS_DAEVA, 'A', YELLOW, "Daeva", - M_RES_POISON | M_LEVITATE | M_SPELLCASTER, + M_LEVITATE | M_SPELLCASTER, + MR_RES_POISON, 0, 12, MONS_DAEVA, MH_HOLY, -8, { 25, 0, 0, 0 }, { 12, 3, 5, 0 }, @@ -3186,7 +3464,8 @@ /* spectral thing - similar to zombies/skeletons */ { MONS_SPECTRAL_THING, 'W', GREEN, "", - M_RES_POISON | M_RES_COLD | M_LEVITATE | M_SEE_INVIS, + M_LEVITATE | M_SEE_INVIS, + MR_RES_POISON | MR_RES_COLD, 0, 11, MONS_SPECTRAL_THING, MH_UNDEAD, 5000, { 20, 0, 0, 0 }, { 8, 3, 5, 0 }, @@ -3197,7 +3476,8 @@ { MONS_GREATER_NAGA, 'N', RED, "greater naga", - M_RES_POISON | M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD, + MR_RES_POISON, 750, 10, MONS_NAGA, MH_NATURAL, 5000, { 18, 0, 0, 0 }, { 15, 3, 5, 0 }, @@ -3208,7 +3488,8 @@ { MONS_SKELETAL_DRAGON, 'D', LIGHTGREY, "skeletal dragon", - M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_RES_ELEC | M_SEE_INVIS, + M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 12, MONS_SKELETAL_DRAGON, MH_UNDEAD, -4, { 30, 20, 20, 0 }, { 20, 8, 8, 0 }, @@ -3219,7 +3500,8 @@ { MONS_TENTACLED_MONSTROSITY, 'X', GREEN, "tentacled monstrosity", - M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_RES_ELEC | M_SEE_INVIS | M_AMPHIBIOUS, + M_SEE_INVIS | M_AMPHIBIOUS, + MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_TENTACLED_MONSTROSITY, MH_NATURAL, -5, { 22, 17, 13, 19 }, { 25, 3, 5, 0 }, @@ -3231,6 +3513,7 @@ { MONS_SPHINX, 'H', LIGHTGREY, "sphinx", M_FLIES | M_SEE_INVIS | M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, + MR_NO_FLAGS, 0, 10, MONS_SPHINX, MH_NATURAL, -3, { 25, 12, 12, 0 }, { 16, 3, 5, 0 }, @@ -3241,7 +3524,8 @@ { MONS_ROTTING_HULK, 'n', BROWN, "rotting hulk", - M_RES_POISON | M_RES_COLD, + M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 12, MONS_ROTTING_HULK, MH_UNDEAD, -5, { 25, 0, 0, 0 }, { 10, 3, 5, 0 }, @@ -3252,7 +3536,8 @@ { MONS_GUARDIAN_MUMMY, 'M', YELLOW, "guardian mummy", - M_RES_POISON | M_RES_COLD | M_SEE_INVIS, + M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 13, MONS_GUARDIAN_MUMMY, MH_UNDEAD, -5, { 30, 0, 0, 0 }, { 7, 5, 3, 0 }, @@ -3263,7 +3548,8 @@ { MONS_GREATER_MUMMY, 'M', DARKGREY, "greater mummy", - M_RES_POISON | M_RES_COLD | M_RES_ELEC | M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, 0, 20, MONS_MUMMY, MH_UNDEAD, 5000, { 35, 0, 0, 0 }, { 15, 5, 3, 100 }, @@ -3274,7 +3560,8 @@ { MONS_MUMMY_PRIEST, 'M', RED, "mummy priest", - M_RES_POISON | M_RES_COLD | M_RES_ELEC | M_SPELLCASTER | M_PRIEST | M_SEE_INVIS, + M_SPELLCASTER | M_PRIEST | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, 0, 16, MONS_MUMMY, MH_UNDEAD, 5000, { 30, 0, 0, 0 }, { 10, 5, 3, 0 }, @@ -3286,6 +3573,7 @@ { MONS_CENTAUR_WARRIOR, 'c', YELLOW, "centaur warrior", M_WARM_BLOOD, + MR_NO_FLAGS, 1500, 12, MONS_CENTAUR, MH_NATURAL, -3, { 16, 0, 0, 0 }, { 9, 3, 5, 0 }, @@ -3297,6 +3585,7 @@ { MONS_YAKTAUR_CAPTAIN, 'c', RED, "yaktaur captain", M_WARM_BLOOD, + MR_NO_FLAGS, 2000, 10, MONS_YAKTAUR, MH_NATURAL, -3, { 23, 0, 0, 0 }, { 14, 3, 5, 0 }, @@ -3307,7 +3596,8 @@ { MONS_KILLER_KLOWN, '@', BLACK, "Killer Klown", - M_RES_FIRE | M_RES_COLD | M_RES_POISON | M_SEE_INVIS | M_SPEAKS | M_WARM_BLOOD, + M_SEE_INVIS | M_SPEAKS | M_WARM_BLOOD, + MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON, 0, 15, MONS_KILLER_KLOWN, MH_NATURAL, 5000, { 30, 0, 0, 0 }, { 20, 5, 5, 0 }, @@ -3318,7 +3608,8 @@ { MONS_ELECTRIC_GOLEM, '8', LIGHTCYAN, "electric golem", - M_SPELLCASTER | M_RES_ELEC | M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_SEE_INVIS, + M_SPELLCASTER | M_SEE_INVIS, + MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, 0, 10, MONS_ELECTRIC_GOLEM, MH_NONLIVING, 5000, { 12, 12, 12, 12 }, { 15, 7, 4, 0 }, @@ -3329,7 +3620,8 @@ { MONS_BALL_LIGHTNING, '*', LIGHTCYAN, "ball lightning", - M_FLIES | M_RES_ELEC | M_CONFUSED | M_SPELLCASTER, + M_FLIES | M_CONFUSED | M_SPELLCASTER, + MR_RES_ELEC, 0, 20, MONS_BALL_LIGHTNING, MH_NONLIVING, 5000, { 5, 0, 0, 0 }, { 12, 0, 0, 1 }, @@ -3340,7 +3632,8 @@ { MONS_ORB_OF_FIRE, '*', RED, "orb of fire", - M_SPELLCASTER | M_FLIES | M_RES_ELEC | M_RES_FIRE | M_RES_COLD | M_RES_POISON | M_SEE_INVIS, + M_SPELLCASTER | M_FLIES | M_SEE_INVIS, + MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON, 0, 10, MONS_ORB_OF_FIRE, MH_NONLIVING, 5000, { 0, 0, 0, 0 }, { 30, 0, 0, 150 }, @@ -3352,6 +3645,7 @@ { MONS_QUOKKA, 'r', LIGHTGREY, "quokka", M_WARM_BLOOD, + MR_NO_FLAGS, 300, 10, MONS_QUOKKA, MH_NATURAL, -1, { 5, 0, 0, 0 }, { 1, 3, 5, 0 }, @@ -3363,6 +3657,7 @@ { MONS_EYE_OF_DEVASTATION, 'G', YELLOW, "eye of devastation", M_NO_SKELETON | M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS, + MR_NO_FLAGS, 0, 11, MONS_EYE_OF_DEVASTATION, MH_NATURAL, 5000, { 0, 0, 0, 0 }, { 10, 3, 5, 0 }, @@ -3374,6 +3669,7 @@ { MONS_MOTH_OF_WRATH, 'y', BROWN, "moth of wrath", M_FLIES, + MR_NO_FLAGS, 0, 10, MONS_MOTH_OF_WRATH, MH_NATURAL, -3, { 25, 0, 0, 0 }, { 9, 3, 5, 0 }, @@ -3384,7 +3680,8 @@ { MONS_DEATH_COB, '%', YELLOW, "death cob", - M_RES_POISON | M_RES_COLD | M_SPEAKS, + M_SPEAKS | M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_DEATH_COB, MH_UNDEAD, -3, { 20, 0, 0, 0 }, { 10, 4, 5, 0 }, @@ -3395,7 +3692,8 @@ { MONS_CURSE_TOE, 'z', DARKGREY, "curse toe", - M_RES_ELEC | M_RES_POISON | M_RES_HELLFIRE | M_RES_COLD | M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS, + M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS | M_EVIL, + MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD, 0, 60, MONS_CURSE_TOE, MH_UNDEAD, 5000, { 0, 0, 0, 0 }, { 14, 0, 0, 77 }, @@ -3407,7 +3705,8 @@ { // gold mimics are the only mimics that actually use their name -- bwr MONS_GOLD_MIMIC, '$', YELLOW, "pile of gold coins", - M_NO_SKELETON | M_RES_POISON | M_RES_ELEC | M_RES_FIRE | M_RES_COLD, + M_NO_SKELETON, + MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, 0, 13, MONS_GOLD_MIMIC, MH_NONLIVING, -3, { 12, 12, 12, 0 }, { 8, 3, 5, 0 }, @@ -3418,7 +3717,8 @@ { MONS_WEAPON_MIMIC, ')', BLACK, "mimic", - M_NO_SKELETON | M_RES_POISON | M_RES_ELEC | M_RES_FIRE | M_RES_COLD, + M_NO_SKELETON, + MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, 0, 13, MONS_GOLD_MIMIC, MH_NONLIVING, -3, { 17, 17, 17, 0 }, { 8, 3, 5, 0 }, @@ -3429,7 +3729,8 @@ { MONS_ARMOUR_MIMIC, '[', BLACK, "mimic", - M_NO_SKELETON | M_RES_POISON | M_RES_ELEC | M_RES_FIRE | M_RES_COLD, + M_NO_SKELETON, + MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, 0, 13, MONS_GOLD_MIMIC, MH_NONLIVING, -3, { 12, 12, 12, 0 }, { 8, 3, 5, 0 }, @@ -3440,7 +3741,8 @@ { MONS_SCROLL_MIMIC, '?', LIGHTGREY, "mimic", - M_NO_SKELETON | M_RES_POISON | M_RES_ELEC | M_RES_FIRE | M_RES_COLD, + M_NO_SKELETON, + MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, 0, 13, MONS_GOLD_MIMIC, MH_NONLIVING, -3, { 12, 12, 12, 0 }, { 8, 3, 5, 0 }, @@ -3451,7 +3753,8 @@ { MONS_POTION_MIMIC, '!', BLACK, "mimic", - M_NO_SKELETON | M_RES_POISON | M_RES_ELEC | M_RES_FIRE | M_RES_COLD, + M_NO_SKELETON, + MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, 0, 13, MONS_GOLD_MIMIC, MH_NONLIVING, -3, { 12, 12, 12, 0 }, { 8, 3, 5, 0 }, @@ -3462,7 +3765,8 @@ { MONS_HELL_HOG, 'h', RED, "hell-hog", - M_SPELLCASTER, + M_SPELLCASTER | M_THICK_SKIN | M_EVIL, + MR_NO_FLAGS, 0, 10, MONS_HELL_HOG, MH_DEMONIC, -3, { 20, 0, 0, 0 }, { 11, 3, 5, 0 }, @@ -3473,7 +3777,8 @@ { MONS_SERPENT_OF_HELL, 'D', RED, "Serpent of Hell", - M_SPELLCASTER | M_RES_POISON | M_RES_HELLFIRE | M_FLIES | M_SEE_INVIS, + M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL, + MR_RES_POISON | MR_RES_HELLFIRE, 0, 18, MONS_SERPENT_OF_HELL, MH_DEMONIC, -13, { 35, 15, 15, 0 }, { 20, 4, 4, 0 }, @@ -3485,6 +3790,7 @@ { MONS_BOGGART, 'g', DARKGREY, "boggart", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS, + MR_NO_FLAGS, 0, 14, MONS_BOGGART, MH_NATURAL, -7, { 5, 0, 0, 0 }, { 2, 3, 5, 0 }, @@ -3496,6 +3802,7 @@ { MONS_QUICKSILVER_DRAGON, 'D', LIGHTCYAN, "quicksilver dragon", M_SPELLCASTER | M_FLIES | M_SEE_INVIS, + MR_NO_FLAGS, 0, 14, MONS_QUICKSILVER_DRAGON, MH_NATURAL, -7, { 45, 0, 0, 0 }, { 16, 3, 5, 0 }, @@ -3506,7 +3813,8 @@ { MONS_IRON_DRAGON, 'D', CYAN, "iron dragon", - M_SPELLCASTER | M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_SEE_INVIS, + M_SPELLCASTER | M_SEE_INVIS, + MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, 0, 14, MONS_IRON_DRAGON, MH_NATURAL, -7, { 25, 25, 25, 0 }, { 18, 5, 3, 0 }, @@ -3517,7 +3825,8 @@ { MONS_SKELETAL_WARRIOR, 'z', CYAN, "skeletal warrior", - M_SPELLCASTER | M_RES_POISON | M_RES_COLD | M_ACTUAL_SPELLS, + M_SPELLCASTER | M_ACTUAL_SPELLS | M_EVIL, + MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_SKELETAL_WARRIOR, MH_UNDEAD, -7, { 25, 0, 0, 0 }, { 10, 5, 3, 0 }, @@ -3530,7 +3839,8 @@ /* player ghost - only one per level. stats are stored in ghost struct */ { MONS_PLAYER_GHOST, 'p', DARKGREY, "", - M_RES_POISON | M_SPEAKS | M_SPELLCASTER | M_ACTUAL_SPELLS | M_FLIES, + M_SPEAKS | M_SPELLCASTER | M_ACTUAL_SPELLS | M_FLIES, + MR_RES_POISON, 0, 15, MONS_PLAYER_GHOST, MH_UNDEAD, -5, { 5, 0, 0, 0 }, { 4, 2, 3, 0 }, @@ -3542,7 +3852,8 @@ /* random demon in pan - only one per level. stats are stored in ghost struct */ { MONS_PANDEMONIUM_DEMON, '&', BLACK, "&", - M_SPELLCASTER | M_RES_POISON | M_SPEAKS, + M_SPELLCASTER | M_SPEAKS | M_EVIL, + MR_RES_POISON, 0, 14, MONS_PANDEMONIUM_DEMON, MH_DEMONIC, -5, { 5, 0, 0, 0 }, { 4, 2, 3, 0 }, @@ -3554,7 +3865,8 @@ // begin lava monsters {dlb} { MONS_LAVA_WORM, 'w', RED, "lava worm", - M_RES_FIRE | M_ED_COLD, + M_NO_FLAGS, + MR_RES_FIRE | MR_VUL_COLD, 0, 10, MONS_LAVA_WORM, MH_NATURAL, -3, { 15, 0, 0, 0 }, { 6, 3, 5, 0 }, @@ -3565,7 +3877,8 @@ { MONS_LAVA_FISH, ';', RED, "lava fish", - M_RES_FIRE | M_ED_COLD, + M_NO_FLAGS, + MR_RES_FIRE | MR_VUL_COLD, 0, 10, MONS_LAVA_FISH, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 4, 3, 5, 0 }, @@ -3576,7 +3889,8 @@ { MONS_LAVA_SNAKE, 'S', RED, "lava snake", - M_RES_FIRE | M_ED_COLD, + M_NO_FLAGS, + MR_RES_FIRE | MR_VUL_COLD, 0, 10, MONS_LAVA_SNAKE, MH_NATURAL, -3, { 7, 0, 0, 0 }, { 3, 3, 5, 0 }, @@ -3587,7 +3901,8 @@ { // mv: was another lava thing MONS_SALAMANDER, 'S', LIGHTRED, "salamander", - M_RES_FIRE | M_ED_COLD | M_WARM_BLOOD, + M_WARM_BLOOD, + MR_RES_FIRE | MR_VUL_COLD, 0, 10, MONS_SALAMANDER, MH_NATURAL, -3, { 23, 0, 0, 0 }, { 14, 3, 5, 0 }, @@ -3602,6 +3917,7 @@ { MONS_BIG_FISH, ';', LIGHTGREEN, "big fish", M_COLD_BLOOD, + MR_NO_FLAGS, 0, 10, MONS_BIG_FISH, MH_NATURAL, -3, { 8, 0, 0, 0 }, { 4, 3, 5, 0 }, @@ -3613,6 +3929,7 @@ { MONS_GIANT_GOLDFISH, ';', LIGHTRED, "giant goldfish", M_COLD_BLOOD, + MR_NO_FLAGS, 0, 10, MONS_GIANT_GOLDFISH, MH_NATURAL, -3, { 15, 0, 0, 0 }, { 7, 3, 5, 0 }, @@ -3623,7 +3940,8 @@ { MONS_ELECTRICAL_EEL, ';', LIGHTBLUE, "electrical eel", - M_RES_ELEC | M_COLD_BLOOD, + M_COLD_BLOOD, + MR_RES_ELEC, 0, 10, MONS_ELECTRICAL_EEL, MH_NATURAL, -3, { 0, 0, 0, 0 }, { 3, 3, 5, 0 }, @@ -3634,7 +3952,8 @@ { MONS_JELLYFISH, 'J', CYAN, "jellyfish", - M_RES_POISON, + M_NO_FLAGS, + MR_RES_POISON, 0, 10, MONS_JELLYFISH, MH_NATURAL, -3, { 1, 1, 0, 0 }, { 4, 3, 5, 0 }, @@ -3645,7 +3964,8 @@ { MONS_WATER_ELEMENTAL, '{', LIGHTBLUE, "water elemental", - M_RES_POISON | M_ED_FIRE | M_FLIES | M_RES_ELEC, + M_FLIES, + MR_RES_POISON | MR_VUL_FIRE | MR_RES_ELEC, 0, 10, MONS_WATER_ELEMENTAL, MH_NONLIVING, 5000, { 25, 0, 0, 0 }, { 6, 5, 3, 0 }, @@ -3657,6 +3977,7 @@ { MONS_SWAMP_WORM, 'w', BROWN, "swamp worm", M_AMPHIBIOUS, + MR_NO_FLAGS, 0, 10, MONS_SWAMP_WORM, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 5, 5, 5, 0 }, @@ -3679,7 +4000,8 @@ not think it fits into Crawl ... {dlb} #if 0 { MONS_SHUGGOTH, 'A', LIGHTGREEN, "shuggoth", - M_NO_SKELETON | M_RES_ELEC | M_RES_POISON | M_RES_FIRE | M_RES_COLD | M_SEE_INVIS, + M_NO_SKELETON | M_SEE_INVIS, + MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, 1000, 10, MONS_SHUGGOTH, MH_DEMONIC, 300, { 5, 5, 5, 0 }, { 10, 4, 4, 0 }, @@ -3692,6 +4014,7 @@ not think it fits into Crawl ... {dlb} { MONS_WOLF, 'h', LIGHTGREY, "wolf", M_WARM_BLOOD | M_SEE_INVIS, //jmf: until smell exists + MR_NO_FLAGS, 450, 10, MONS_WOLF, MH_NATURAL, -3, { 8, 2, 2, 0 }, { 4, 3, 5, 0 }, @@ -3702,7 +4025,8 @@ not think it fits into Crawl ... {dlb} { MONS_WARG, 'h', DARKGREY, "warg", - M_SEE_INVIS | M_RES_POISON | M_WARM_BLOOD, + M_SEE_INVIS | M_WARM_BLOOD, + MR_RES_POISON, 600, 12, MONS_WARG, MH_NATURAL, -6, { 12, 3, 3, 0 }, { 4, 4, 5, 0 }, @@ -3714,6 +4038,7 @@ not think it fits into Crawl ... {dlb} { MONS_BEAR, 'U', BROWN, "bear", M_WARM_BLOOD, + MR_NO_FLAGS, 2000, 10, MONS_BEAR, MH_NATURAL, -3, { 10, 6, 6, 0 }, { 7, 3, 3, 0 }, @@ -3725,6 +4050,7 @@ not think it fits into Crawl ... {dlb} { MONS_GRIZZLY_BEAR, 'U', LIGHTGREY, "grizzly bear", M_WARM_BLOOD, + MR_NO_FLAGS, 2500, 10, MONS_GRIZZLY_BEAR, MH_NATURAL, -3, { 12, 8, 8, 0 }, { 7, 4, 4, 0 }, @@ -3735,7 +4061,8 @@ not think it fits into Crawl ... {dlb} { MONS_POLAR_BEAR, 'U', WHITE, "polar bear", - M_RES_COLD | M_WARM_BLOOD | M_AMPHIBIOUS, + M_WARM_BLOOD | M_AMPHIBIOUS, + MR_RES_COLD, 2500, 10, MONS_POLAR_BEAR, MH_NATURAL, -3, { 20, 5, 5, 0 }, //jmf: polar bears have very strong jaws & necks { 7, 5, 3, 0 }, @@ -3747,6 +4074,7 @@ not think it fits into Crawl ... {dlb} { MONS_BLACK_BEAR, 'U', DARKGREY, "black bear", M_WARM_BLOOD, + MR_NO_FLAGS, 1800, 10, MONS_BLACK_BEAR, MH_NATURAL, -3, { 4, 4, 4, 0 }, { 6, 3, 3, 0 }, @@ -3758,7 +4086,8 @@ not think it fits into Crawl ... {dlb} // small simulacrum { MONS_SIMULACRUM_SMALL, 'z', WHITE, "", - M_RES_POISON | M_ED_FIRE | M_RES_COLD, + M_EVIL, + MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 6, MONS_SIMULACRUM_SMALL, MH_UNDEAD, -1, { 6, 0, 0, 0 }, { 2, 3, 5, 0 }, @@ -3770,7 +4099,8 @@ not think it fits into Crawl ... {dlb} // large simulacrum { MONS_SIMULACRUM_LARGE, 'Z', WHITE, "", - M_RES_POISON | M_ED_FIRE | M_RES_COLD, + M_EVIL, + MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 6, MONS_SIMULACRUM_LARGE, MH_UNDEAD, -1, { 14, 0, 0, 0 }, { 5, 3, 5, 0 }, @@ -3782,6 +4112,7 @@ not think it fits into Crawl ... {dlb} { MONS_GIANT_NEWT, 'l', LIGHTGREEN, "giant newt", M_COLD_BLOOD | M_AMPHIBIOUS, + MR_NO_FLAGS, 150, 10, MONS_GIANT_NEWT, MH_NATURAL, -3, { 3, 0, 0, 0 }, { 1, 1, 2, 0 }, @@ -3793,6 +4124,7 @@ not think it fits into Crawl ... {dlb} { MONS_GIANT_GECKO, 'l', YELLOW, "giant gecko", M_COLD_BLOOD, + MR_NO_FLAGS, 250, 10, MONS_GIANT_GECKO, MH_NATURAL, -3, { 5, 0, 0, 0 }, { 1, 3, 5, 0 }, @@ -3804,6 +4136,7 @@ not think it fits into Crawl ... {dlb} { MONS_GIANT_IGUANA, 'l', BLUE, "giant iguana", M_COLD_BLOOD, + MR_NO_FLAGS, 400, 10, MONS_GIANT_IGUANA, MH_NATURAL, -3, { 15, 0, 0, 0 }, { 3, 3, 5, 0 }, @@ -3816,6 +4149,7 @@ not think it fits into Crawl ... {dlb} // gila monsters colours: lightmagenta, magenta, lightred, red, yellow MONS_GILA_MONSTER, 'l', BLACK, "gila monster", M_COLD_BLOOD, + MR_NO_FLAGS, 500, 10, MONS_GILA_MONSTER, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 5, 4, 4, 0 }, @@ -3827,6 +4161,7 @@ not think it fits into Crawl ... {dlb} { MONS_KOMODO_DRAGON, 'l', BROWN, "komodo dragon", M_COLD_BLOOD | M_AMPHIBIOUS, + MR_NO_FLAGS, 800, 10, MONS_KOMODO_DRAGON, MH_NATURAL, -3, { 30, 0, 0, 0 }, { 8, 3, 5, 0 }, diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 4df429aab7..7f1c28f148 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -143,11 +143,20 @@ void mons_init(FixedVector < unsigned short, 1000 > &colour) //return (monsterentry *) 0; // return value should not matter here {dlb} } // end mons_init() +unsigned long mons_class_resist(int mc) +{ + return (smc->resists); +} + +unsigned long mons_class_resist(int mc, unsigned long flags) +{ + return (smc->resists & flags); +} -int mons_flag(int mc, int bf) +bool mons_class_flag(int mc, int bf) { return ((smc->bitfields & bf) != 0); -} // end mons_flag() +} // end mons_class_flag() static int scan_mon_inv_randarts( struct monsters *mon, int ra_prop ) { @@ -181,6 +190,10 @@ static int scan_mon_inv_randarts( struct monsters *mon, int ra_prop ) return (ret); } +int mons_holiness(const monsters *mons) +{ + return (mons_holiness(mons->type)); +} int mons_holiness(int mc) { @@ -430,11 +443,10 @@ int mons_res_elec( struct monsters *mon ) return (ghost.values[ GVAL_RES_ELEC ]); /* this is a variable, not a player_xx() function, so can be above 1 */ - int u = 0, f = (seekmonster(&mc))->bitfields; + int u = 0; - // of course it makes no sense setting them both :) - if (f & M_RES_ELEC) - u++; //if(f&M_ED_ELEC) u--; + if (mons_class_resist(MR_RES_ELEC)) + u++; // don't bother checking equipment if the monster can't use it if (mons_itemuse(mc) >= MONUSE_STARTING_EQUIPMENT) @@ -458,12 +470,12 @@ int mons_res_poison( struct monsters *mon ) { int mc = mon->type; - int u = 0, f = (seekmonster(&mc))->bitfields; + int u = 0, f = mons_class_resist(mc); - if (f & M_RES_POISON) + if (f & MR_RES_POISON) u++; - if (f & M_ED_POISON) + if (f & MR_VUL_POISON) u--; if (mons_itemuse(mc) >= MONUSE_STARTING_EQUIPMENT) @@ -498,18 +510,18 @@ int mons_res_fire( struct monsters *mon ) if (mc == MONS_PLAYER_GHOST || mc == MONS_PANDEMONIUM_DEMON) return (ghost.values[ GVAL_RES_FIRE ]); - int u = 0, f = (seekmonster(&mc))->bitfields; + int u = 0, f = mons_class_resist(mc); // no Big Prize (tm) here either if you set all three flags. It's a pity uh? // // Note that natural monster resistance is two levels, this is duplicate // the fact that having this flag used to be a lot better than armour // for monsters (it used to make them immune in a lot of cases) -- bwr - if (f & M_RES_HELLFIRE) + if (f & MR_RES_HELLFIRE) u += 3; - else if (f & M_RES_FIRE) + else if (f & MR_RES_FIRE) u += 2; - else if (f & M_ED_FIRE) + else if (f & MR_VUL_FIRE) u--; if (mons_itemuse(mc) >= MONUSE_STARTING_EQUIPMENT) @@ -546,14 +558,14 @@ int mons_res_cold( struct monsters *mon ) if (mc == MONS_PLAYER_GHOST || mc == MONS_PANDEMONIUM_DEMON) return (ghost.values[ GVAL_RES_COLD ]); - int u = 0, f = (seekmonster(&mc))->bitfields; + int u = 0, f = mons_class_resist(mc); // Note that natural monster resistance is two levels, this is duplicate // the fact that having this flag used to be a lot better than armour // for monsters (it used to make them immune in a lot of cases) -- bwr - if (f & M_RES_COLD) + if (f & MR_RES_COLD) u += 2; - else if (f & M_ED_COLD) + else if (f & MR_VUL_COLD) u--; if (mons_itemuse(mc) >= MONUSE_STARTING_EQUIPMENT) @@ -690,10 +702,10 @@ int exper_value( struct monsters *monster ) const int item_usage = mons_itemuse(mclass); // XXX: shapeshifters can qualify here, even though they can't cast: - const bool spellcaster = mons_flag( mclass, M_SPELLCASTER ); + const bool spellcaster = mons_class_flag( mclass, M_SPELLCASTER ); // early out for no XP monsters - if (mons_flag(mclass, M_NO_EXP_GAIN)) + if (mons_class_flag(mclass, M_NO_EXP_GAIN)) return (0); // These undead take damage to maxhp, so we use only HD. -- bwr @@ -1301,7 +1313,7 @@ bool mons_is_stabbable(struct monsters *m) { // Make sure oklob plants are never highlighted. That'll defeat the // point of making them look like normal plants. - return (!mons_flag(m->type, M_NO_EXP_GAIN) + return (!mons_class_flag(m->type, M_NO_EXP_GAIN) && m->type != MONS_OKLOB_PLANT && !mons_friendly(m) && m->behaviour == BEH_SLEEP); @@ -1309,12 +1321,12 @@ bool mons_is_stabbable(struct monsters *m) bool mons_maybe_stabbable(struct monsters *m) { - return (!mons_flag(m->type, M_NO_EXP_GAIN) + return (!mons_class_flag(m->type, M_NO_EXP_GAIN) && m->type != MONS_OKLOB_PLANT && !mons_friendly(m) && ((m->foe != MHITYOU && !testbits(m->flags, MF_BATTY)) || (mons_has_ench(m, ENCH_CONFUSION) && - !mons_flag(m->type, M_CONFUSED)) + !mons_class_flag(m->type, M_CONFUSED)) || m->behaviour == BEH_FLEE)); } @@ -1474,7 +1486,7 @@ int mons_del_ench( struct monsters *mon, unsigned int ench, unsigned int ench2, if (ench == ENCH_INVIS) { // invisible monsters stay invisible - if (mons_flag(mon->type, M_INVIS)) + if (mons_class_flag(mon->type, M_INVIS)) { mon->enchantment[p] = ENCH_INVIS; } @@ -1902,7 +1914,7 @@ bool mons_has_ranged_spell( struct monsters *mon ) { const int mclass = mon->type; - if (mons_flag( mclass, M_SPELLCASTER )) + if (mons_class_flag( mclass, M_SPELLCASTER )) { const int msecc = ((mclass == MONS_HELLION) ? MST_BURNING_DEVIL : (mclass == MONS_PANDEMONIUM_DEMON) ? MST_GHOST diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h index 9a1fc22688..7a4b37a14b 100644 --- a/crawl-ref/source/mon-util.h +++ b/crawl-ref/source/mon-util.h @@ -15,57 +15,10 @@ #define MONUTIL_H #include "externs.h" +#include "enum.h" // ($pellbinder) (c) D.G.S.E. 1998 -// ****remember***** must make an hardcopy of this sometime - -#if defined(macintosh) || defined(__IBMCPP__) || defined(SOLARIS) || defined(__BCPLUSPLUS__) -#define PACKED -#else -#ifndef PACKED -#define PACKED __attribute__ ((packed)) -#endif -#endif - -// leaves no skeleton? ("blob" monsters?) -// if weight=0 or zombie_size=0, this is always true -#define M_NO_FLAGS 0 // clear -#define M_NO_SKELETON (1<<0) -// resistances -#define M_RES_ELEC (1<<1) -#define M_RES_POISON (1<<2) -#define M_RES_FIRE (1<<3) -#define M_RES_HELLFIRE (1<<4) -#define M_RES_COLD (1<<5) -// invisible -#define M_INVIS (1<<6) // is created with invis enchantment set, and never runs out -// vulnerabilities -//#define M_ED_ELEC (1<<6) // never used -#define M_ED_POISON (1<<7) // ??? - - This flag is now (2.50) set for insects (LRH) -#define M_ED_FIRE (1<<8) -#define M_ED_COLD (1<<9) -#define M_SPELLCASTER (1<<10) // any non-physical-attack powers -#define M_FLIES (1<<11) // will crash to ground if paralysed (wings) -#define M_LEVITATE (1<<12) // not if this is set -#define M_SEE_INVIS (1<<13) -// killing this beast only gives 10 experience (makes sense for plants/fungi) -#define M_NO_EXP_GAIN (1<<14) // must do this manually -#define M_SPEAKS (1<<15) -//jmf: M_SPELLCASTER was taken ... :-b -#define M_ACTUAL_SPELLS (1<<16) // monster is a wizard -#define M_PRIEST (1<<17) // monster is a priest of Brian's Orc God (BOG) -#define M_COLD_BLOOD (1<<18) -#define M_WARM_BLOOD (1<<19) -#define M_CONFUSED (1<<20) // monster is perma-confused -#define M_SPLITS (1<<21) // monster is perma-confused -#define M_AMPHIBIOUS (1<<22) // monster can swim in water - -//jmf: it'd be nice if these next two were implimented ... -#define M_ON_FIRE (1<<29) // flag for Hellion-like colour shift -#define M_FROZEN (1<<30) // flag for ice-like colour shift - - // zombie size #define Z_NOZOMBIE 0 // no zombie (and no skeleton) #define Z_SMALL 1 @@ -111,7 +64,9 @@ struct monsterentry unsigned char showchar, colour; const char *name /*[32]*/; //longest is 23 till now (31 is max alowed here) - int bitfields; + unsigned long bitfields; + unsigned long resists; + short weight; // experience is calculated like this: // ((((max_hp / 7) + 1) * (mHD * mHD) + 1) * exp_mod) / 10 @@ -263,7 +218,7 @@ int mons_corpse_thingy(int mclass); /* *********************************************************************** * called from: dungeon - fight - monstuff - mon-util * *********************************************************************** */ -int mons_flag(int mc, int bf); +bool mons_class_flag(int mc, int bf); // last updated 12may2000 {dlb} @@ -272,6 +227,7 @@ int mons_flag(int mc, int bf); * spells3 - spells4 * *********************************************************************** */ int mons_holiness(int mclass); +int mons_holiness(const monsters *); bool mons_is_mimic( int mc ); bool mons_is_demon( int mc ); diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index eeab5c61d7..9ed276c03e 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -449,10 +449,10 @@ static int place_monster_aux( int mon_type, char behaviour, int target, if (extra != 250) menv[id].number = extra; - if (mons_flag(mon_type, M_INVIS)) + if (mons_class_flag(mon_type, M_INVIS)) mons_add_ench(&menv[id], ENCH_INVIS); - if (mons_flag(mon_type, M_CONFUSED)) + if (mons_class_flag(mon_type, M_CONFUSED)) mons_add_ench(&menv[id], ENCH_CONFUSION); if (mon_type == MONS_SHAPESHIFTER) diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 644462b798..34577f1407 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -271,9 +271,9 @@ static void monster_drop_ething(struct monsters *monster, if (destroyed) { if (grd[monster->x][monster->y] == DNGN_LAVA) - mpr("You hear a hissing sound."); + mpr("You hear a hissing sound.", MSGCH_SOUND); else - mpr("You hear a splashing sound."); + mpr("You hear a splashing sound.", MSGCH_SOUND); } } // end monster_drop_ething() @@ -448,29 +448,30 @@ void monster_die(struct monsters *monster, char killer, int i) if (you.duration[DUR_PRAYER]) { if (mons_holiness(monster->type) == MH_NATURAL) - done_good(GOOD_KILLED_LIVING, monster->hit_dice); + did_god_conduct(DID_DEDICATED_KILL_LIVING, + monster->hit_dice); if (mons_holiness(monster->type) == MH_UNDEAD) - done_good(GOOD_KILLED_UNDEAD, monster->hit_dice); + did_god_conduct(DID_DEDICATED_KILL_UNDEAD, + monster->hit_dice); if (mons_holiness(monster->type) == MH_DEMONIC) - done_good(GOOD_KILLED_DEMON, monster->hit_dice); - - if (mons_holiness(monster->type) == MH_HOLY) - done_good(GOOD_KILLED_ANGEL_II, monster->hit_dice); + did_god_conduct(DID_DEDICATED_KILL_DEMON, + monster->hit_dice); //jmf: Trog hates wizards - if (mons_flag(monster->type, M_ACTUAL_SPELLS)) - done_good(GOOD_KILLED_WIZARD, monster->hit_dice); + if (mons_class_flag(monster->type, M_ACTUAL_SPELLS)) + did_god_conduct(DID_DEDICATED_KILL_WIZARD, + monster->hit_dice); //jmf: maybe someone hates priests? - if (mons_flag(monster->type, M_PRIEST)) - done_good(GOOD_KILLED_PRIEST, monster->hit_dice); - } - else if (mons_holiness(monster->type) == MH_HOLY) - { - done_good(GOOD_KILLED_ANGEL_I, monster->hit_dice); + if (mons_class_flag(monster->type, M_PRIEST)) + did_god_conduct(DID_DEDICATED_KILL_PRIEST, + monster->hit_dice); } + + if (mons_holiness(monster->type) == MH_HOLY) + did_god_conduct(DID_KILL_ANGEL, monster->hit_dice); } // Divine health and mp restoration doesn't happen when killing @@ -522,40 +523,83 @@ void monster_die(struct monsters *monster, char killer, int i) // no piety loss if god gifts killed by other monsters if (mons_friendly(monster) && !testbits(monster->flags,MF_GOD_GIFT)) - naughty(NAUGHTY_FRIEND_DIES, 1 + (monster->hit_dice / 2)); + did_god_conduct(DID_FRIEND_DIES, 1 + (monster->hit_dice / 2)); // Trying to prevent summoning abuse here, so we're trying to // prevent summoned creatures from being being done_good kills. // Only affects creatures which were friendly when summoned. if (!testbits(monster->flags, MF_CREATED_FRIENDLY) && pet_kill) { + bool notice = false; + gain_exp(exper_value( monster ) / 2 + 1); - if (mons_holiness(menv[i].type) == MH_UNDEAD) + int targ_holy = mons_holiness(monster->type), + attacker_holy = mons_holiness(menv[i].type); + + if (attacker_holy == MH_UNDEAD) { - if (mons_holiness(monster->type) == MH_NATURAL) - done_good(GOOD_SLAVES_KILL_LIVING, monster->hit_dice); - else - done_good(GOOD_SERVANTS_KILL, monster->hit_dice); + if (targ_holy == MH_NATURAL) + notice |= + did_god_conduct(DID_LIVING_KILLED_BY_UNDEAD_SLAVE, + monster->hit_dice); } - else + else if (you.religion == GOD_VEHUMET + || testbits( menv[i].flags, MF_GOD_GIFT )) { - done_good(GOOD_SERVANTS_KILL, monster->hit_dice); - - if (you.religion == GOD_VEHUMET - && (!player_under_penance() - && random2(you.piety) >= 30)) + // Yes, we are splitting undead pets from the others + // as a way to focus Necomancy vs Summoning (ignoring + // Summon Wraith here)... at least we're being nice and + // putting the natural creature Summons together with + // the Demon ones. Note that Vehumet gets a free + // pass here since those followers are assumed to + // come from Summoning spells... the others are + // from invocations (Zin, TSO, Makh, Kiku). -- bwr + + if (targ_holy == MH_NATURAL) { - /* Vehumet - only for non-undead servants (coding - convenience, no real reason except that Vehumet - prefers demons) */ - if (you.magic_points < you.max_magic_points) + notice |= did_god_conduct( DID_LIVING_KILLED_BY_SERVANT, + monster->hit_dice ); + + if (mons_class_flag( monster->type, M_EVIL )) { - mpr("You feel your power returning."); - inc_mp(1 + random2(random2(monster->hit_dice)), - false); + notice |= + did_god_conduct( + DID_NATURAL_EVIL_KILLED_BY_SERVANT, + monster->hit_dice ); } } + else if (targ_holy == MH_DEMONIC) + { + notice |= did_god_conduct( DID_DEMON_KILLED_BY_SERVANT, + monster->hit_dice ); + } + else if (targ_holy == MH_UNDEAD) + { + notice |= did_god_conduct( DID_UNDEAD_KILLED_BY_SERVANT, + monster->hit_dice ); + } + } + + // Angel kills are always noticed. + if (targ_holy == MH_HOLY) + { + notice |= did_god_conduct( DID_ANGEL_KILLED_BY_SERVANT, + monster->hit_dice ); + } + + if (you.religion == GOD_VEHUMET + && notice + && (!player_under_penance() && random2(you.piety) >= 30)) + { + /* Vehumet - only for non-undead servants (coding + convenience, no real reason except that Vehumet + prefers demons) */ + if (you.magic_points < you.max_magic_points) + { + mpr("You feel your power returning."); + inc_mp( 1 + random2(monster->hit_dice / 2), false ); + } } } break; @@ -720,7 +764,7 @@ static bool jelly_divide(struct monsters * parent) bool foundSpot = false; // to rid code of hideous goto {dlb} struct monsters *child = 0; // NULL - value determined with loop {dlb} - if (!mons_flag( parent->type, M_SPLITS ) || parent->hit_points == 1) + if (!mons_class_flag( parent->type, M_SPLITS ) || parent->hit_points == 1) return (false); // first, find a suitable spot for the child {dlb}: @@ -788,7 +832,7 @@ static bool jelly_divide(struct monsters * parent) if (!simple_monster_message(parent, " splits in two!")) { if (!silenced(parent->x, parent->y) || !silenced(child->x, child->y)) - mpr("You hear a squelching noise."); + mpr("You hear a squelching noise.", MSGCH_SOUND); } return (true); @@ -826,7 +870,7 @@ static bool valid_morph( struct monsters *monster, int new_mclass ) /* various inappropriate polymorph targets */ if (mons_holiness( new_mclass ) != mons_holiness( monster->type ) - || mons_flag( new_mclass, M_NO_EXP_GAIN ) // not helpless + || mons_class_flag( new_mclass, M_NO_EXP_GAIN ) // not helpless || new_mclass == mons_charclass( monster->type ) // must be different || new_mclass == MONS_PROGRAM_BUG || new_mclass == MONS_SHAPESHIFTER @@ -915,7 +959,7 @@ bool monster_polymorph( struct monsters *monster, int targetc, int power ) } // messaging: {dlb} - bool invis = mons_flag( targetc, M_INVIS ) + bool invis = mons_class_flag( targetc, M_INVIS ) || mons_has_ench( monster, ENCH_INVIS ); if (mons_has_ench( monster, ENCH_GLOWING_SHAPESHIFTER, ENCH_SHAPESHIFTER )) @@ -961,7 +1005,7 @@ bool monster_polymorph( struct monsters *monster, int targetc, int power ) if (shifter != ENCH_NONE) mons_add_ench( monster, shifter ); - if (mons_flag( monster->type, M_INVIS )) + if (mons_class_flag( monster->type, M_INVIS )) mons_add_ench( monster, ENCH_INVIS ); monster->hit_points = monster->max_hit_points @@ -1033,7 +1077,7 @@ static bool habitat_okay( struct monsters *monster, int targ ) // flying monsters don't care ret = true; } - else if (mons_flag( monster->type, M_AMPHIBIOUS ) + else if (mons_class_flag( monster->type, M_AMPHIBIOUS ) && (targ == DNGN_DEEP_WATER || targ == DNGN_SHALLOW_WATER)) { // Amphibious creatures are "land" by default in mon-data, @@ -1787,7 +1831,7 @@ static bool handle_enchantment(struct monsters *monster) if (random2(120) < mod_speed( monster->hit_dice + 5, speed )) { // don't delete perma-confusion - if (!mons_flag(monster->type, M_CONFUSED)) + if (!mons_class_flag(monster->type, M_CONFUSED)) mons_del_ench(monster, ENCH_CONFUSION); } break; @@ -1796,7 +1840,7 @@ static bool handle_enchantment(struct monsters *monster) if (random2(1000) < mod_speed( 25, speed )) { // don't delete perma-invis - if (!mons_flag( monster->type, M_INVIS )) + if (!mons_class_flag( monster->type, M_INVIS )) mons_del_ench(monster, ENCH_INVIS); } break; @@ -2172,7 +2216,7 @@ static void handle_nearby_ability(struct monsters *monster) return; } - if (mons_flag(monster->type, M_SPEAKS) && one_chance_in(21) + if (mons_class_flag(monster->type, M_SPEAKS) && one_chance_in(21) && monster->behaviour != BEH_WANDER) { mons_speaks(monster); @@ -2905,7 +2949,7 @@ static bool handle_wand(struct monsters *monster, bolt &beem) if (!simple_monster_message(monster, " zaps a wand.")) { if (!silenced(you.x_pos, you.y_pos)) - mpr("You hear a zap."); + mpr("You hear a zap.", MSGCH_SOUND); } // charge expenditure {dlb} @@ -2935,21 +2979,21 @@ static bool handle_spell( struct monsters *monster, bolt & beem ) // yes, there is a logic to this ordering {dlb}: if (monster->behaviour == BEH_SLEEP - || !mons_flag( monster->type, M_SPELLCASTER ) + || !mons_class_flag( monster->type, M_SPELLCASTER ) || mons_has_ench( monster, ENCH_SUBMERGED )) { return (false); } - if ((mons_flag(monster->type, M_ACTUAL_SPELLS) - || mons_flag(monster->type, M_PRIEST)) + if ((mons_class_flag(monster->type, M_ACTUAL_SPELLS) + || mons_class_flag(monster->type, M_PRIEST)) && (mons_has_ench(monster, ENCH_GLOWING_SHAPESHIFTER, ENCH_SHAPESHIFTER))) { return (false); //jmf: shapeshiftes don't get spells, just // physical powers. } else if (mons_has_ench(monster, ENCH_CONFUSION) - && !mons_flag(monster->type, M_CONFUSED)) + && !mons_class_flag(monster->type, M_CONFUSED)) { return (false); } @@ -3163,7 +3207,7 @@ static bool handle_spell( struct monsters *monster, bolt & beem ) if (silenced(monster->x, monster->y)) return (false); - if (mons_flag(monster->type, M_PRIEST)) + if (mons_class_flag(monster->type, M_PRIEST)) { switch (random2(3)) { @@ -3233,7 +3277,7 @@ static bool handle_spell( struct monsters *monster, bolt & beem ) if (!silenced(monster->x, monster->y) && !silenced(you.x_pos, you.y_pos)) { - mpr("You hear a roar.", MSGCH_MONSTER_SPELL); + mpr("You hear a roar.", MSGCH_SOUND); } } break; @@ -3271,7 +3315,7 @@ static bool handle_spell( struct monsters *monster, bolt & beem ) if (monster->type == MONS_GERYON && !silenced(you.x_pos, you.y_pos)) { - mpr("You hear a weird and mournful sound."); + mpr("You hear a weird and mournful sound.", MSGCH_SOUND); } } @@ -3288,7 +3332,7 @@ static bool handle_spell( struct monsters *monster, bolt & beem ) mmov_x = 0; mmov_y = 0; } - } // end "if mons_flag(monster->type, M_SPELLCASTER) ... + } // end "if mons_class_flag(monster->type, M_SPELLCASTER) ... return (true); } // end handle_spell() @@ -3591,7 +3635,7 @@ void handle_monsters(void) // shapeshifters don't get spells if (!mons_has_ench( monster, ENCH_GLOWING_SHAPESHIFTER, ENCH_SHAPESHIFTER ) - || !mons_flag( monster->type, M_ACTUAL_SPELLS )) + || !mons_class_flag( monster->type, M_ACTUAL_SPELLS )) { if (handle_spell(monster, beem)) continue; @@ -3822,10 +3866,10 @@ static bool handle_pickup(struct monsters *monster) if (!monsterNearby) strcat(info, " distant"); strcat(info, " slurping noise."); - mpr(info); + mpr(info, MSGCH_SOUND); } - if (mons_flag( monster->type, M_SPLITS )) + if (mons_class_flag( monster->type, M_SPLITS )) { const int reqd = (monster->hit_dice <= 6) ? 50 : monster->hit_dice * 8; @@ -4078,7 +4122,7 @@ static void monster_move(struct monsters *monster) if (mons_flies(monster) > 0 || habitat != DNGN_FLOOR - || mons_flag( monster->type, M_AMPHIBIOUS )) + || mons_class_flag( monster->type, M_AMPHIBIOUS )) { okmove = MINMOVE; } @@ -4320,7 +4364,7 @@ static void monster_move(struct monsters *monster) if (!mons_near(monster)) strcat(info, " distant"); strcat(info, " slurping noise."); - mpr(info); + mpr(info, MSGCH_SOUND); } monster->hit_points += 5; @@ -4329,7 +4373,7 @@ static void monster_move(struct monsters *monster) if (monster->hit_points > monster->max_hit_points) monster->max_hit_points = monster->hit_points; - if (mons_flag( monster->type, M_SPLITS )) + if (mons_class_flag( monster->type, M_SPLITS )) { // and here is where the jelly might divide {dlb} const int reqd = (monster->hit_dice < 6) ? 50 @@ -4488,7 +4532,7 @@ forget_it: grd[monster->x + mmov_x][monster->y + mmov_y] = DNGN_FLOOR; if (!silenced(you.x_pos, you.y_pos)) - mpr("You hear a grinding noise."); + mpr("You hear a grinding noise.", MSGCH_SOUND); } } diff --git a/crawl-ref/source/newgame.cc b/crawl-ref/source/newgame.cc index eca23d3815..fd54adede1 100644 --- a/crawl-ref/source/newgame.cc +++ b/crawl-ref/source/newgame.cc @@ -1648,6 +1648,7 @@ void init_player(void) { you.penance[i] = 0; you.worshipped[i] = 0; + you.num_gifts[i] = 0; } ghost.name[0] = '\0'; diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index c4d5d6c047..f14274f2a8 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -178,6 +178,42 @@ bool player_genus(unsigned char which_genus, unsigned char species) return (false); } // end player_genus() +bool player_weapon_wielded() +{ + const int wpn = you.equip[EQ_WEAPON]; + + if (wpn == -1) + return (false); + + if (you.inv[wpn].base_type != OBJ_WEAPONS + && you.inv[wpn].base_type != OBJ_STAVES) + { + return (false); + } + + // FIXME: This needs to go in eventually. + /* + // should never have a bad "shape" weapon in hand + ASSERT( check_weapon_shape( you.inv[wpn], false ) ); + + if (!check_weapon_wieldable_size( you.inv[wpn], player_size() )) + return (false); + */ + + return (true); +} + +// Returns the you.inv[] index of our wielded weapon or -1 (no item, not wield) +int get_player_wielded_item() +{ + return (you.equip[EQ_WEAPON]); +} + +int get_player_wielded_weapon() +{ + return (player_weapon_wielded()? get_player_wielded_item() : -1); +} + // Looks in equipment "slot" to see if there is an equiped "sub_type". // Returns number of matches (in the case of rings, both are checked) int player_equip( int slot, int sub_type, bool calc_unid ) @@ -201,7 +237,7 @@ int player_equip( int slot, int sub_type, bool calc_unid ) if (you.equip[EQ_WEAPON] != -1 && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_STAVES && you.inv[you.equip[EQ_WEAPON]].sub_type == sub_type - && (calc_unid || + && (calc_unid || item_ident(you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_TYPE))) { ret++; @@ -3839,7 +3875,7 @@ void haste_player( int amount ) if (you.haste > 80 + 20 * amu_eff) you.haste = 80 + 20 * amu_eff; - naughty( NAUGHTY_STIMULANTS, 4 + random2(4) ); + did_god_conduct( DID_STIMULANTS, 4 + random2(4) ); } void dec_haste_player( void ) diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index 1d99d6b154..ff7c06835a 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -17,6 +17,7 @@ bool player_in_branch( int branch ); bool player_in_hell( void ); +int get_player_wielded_weapon(); int player_equip( int slot, int sub_type, bool calc_unid = true ); int player_equip_ego_type( int slot, int sub_type ); int player_damage_type( void ); @@ -48,6 +49,7 @@ bool player_is_levitating(void); * *********************************************************************** */ bool player_under_penance(void); +int player_wielded_item(); /* *********************************************************************** * called from: ability - acr - fight - food - it_use2 - item_use - items - diff --git a/crawl-ref/source/randart.cc b/crawl-ref/source/randart.cc index b0486fe02f..753c1d15fe 100644 --- a/crawl-ref/source/randart.cc +++ b/crawl-ref/source/randart.cc @@ -1790,6 +1790,7 @@ void standard_name_weap(unsigned char item_typ, char glorg[ITEMNAME_SIZE]) (item_typ == WPN_WHIP) ? "whip" : (item_typ == WPN_SABRE) ? "sabre" : (item_typ == WPN_DEMON_BLADE) ? "demon blade" : + (item_typ == WPN_BLESSED_BLADE)? "blessed blade" : (item_typ == WPN_DEMON_WHIP) ? "demon whip" : (item_typ == WPN_DEMON_TRIDENT) ? "demon trident" : (item_typ == WPN_BROAD_AXE) ? "broad axe" : diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index fc51bc28bd..cb2202093a 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -39,6 +39,7 @@ #include "food.h" #include "it_use2.h" #include "itemname.h" +#include "item_use.h" #include "items.h" #include "misc.h" #include "monplace.h" @@ -46,6 +47,7 @@ #include "newgame.h" #include "ouch.h" #include "player.h" +#include "randart.h" #include "shopping.h" #include "skills2.h" #include "spells1.h" @@ -53,6 +55,7 @@ #include "spells3.h" #include "spl-cast.h" #include "stuff.h" +#include "wpn-misc.h" const char *sacrifice[] = { " glows silver and disappears.", @@ -115,9 +118,25 @@ static void inc_gift_timeout(int val) you.gift_timeout += val; } // end inc_gift_timeout() +static int random_undead_servant(int religion) +{ + // error trapping {dlb} + int thing_called = MONS_PROGRAM_BUG; + int temp_rand = random2(100); + thing_called = ((temp_rand > 66) ? MONS_WRAITH : // 33% + (temp_rand > 52) ? MONS_WIGHT : // 12% + (temp_rand > 40) ? MONS_SPECTRAL_WARRIOR : // 16% + (temp_rand > 31) ? MONS_ROTTING_HULK : // 9% + (temp_rand > 23) ? MONS_SKELETAL_WARRIOR : // 8% + (temp_rand > 16) ? MONS_VAMPIRE : // 7% + (temp_rand > 10) ? MONS_GHOUL : // 6% + (temp_rand > 4) ? MONS_MUMMY // 6% + : MONS_FLAYED_GHOST); // 5% + return (thing_called); +} + void pray(void) { - int temp_rand = 0; unsigned char was_praying = you.duration[DUR_PRAYER]; bool success = false; @@ -226,197 +245,217 @@ void pray(void) if (!you.penance[you.religion] && !you.gift_timeout && !was_praying) { // Remember to check for water/lava - //jmf: "good" god will sometimes feed you (a la Nethack) - if (you.religion == GOD_ZIN - && you.hunger_state == HS_STARVING - && random2(250) <= you.piety) - { - god_speaks(you.religion, "Your stomach feels content."); - set_hunger(6000, true); - lose_piety(5 + random2avg(10, 2)); - inc_gift_timeout(30 + random2avg(10, 2)); - return; - } - - if (you.religion == GOD_NEMELEX_XOBEH - && random2(200) <= you.piety - && (!you.attribute[ATTR_CARD_TABLE] || one_chance_in(3)) - && !you.attribute[ATTR_CARD_COUNTDOWN] - && grd[you.x_pos][you.y_pos] != DNGN_LAVA - && grd[you.x_pos][you.y_pos] != DNGN_DEEP_WATER) + switch (you.religion) { - int thing_created = NON_ITEM; - unsigned char gift_type = MISC_DECK_OF_TRICKS; - - if (!you.attribute[ATTR_CARD_TABLE]) - { - thing_created = items( 1, OBJ_MISCELLANY, - MISC_PORTABLE_ALTAR_OF_NEMELEX, - true, 1, 250 ); - - if (thing_created != NON_ITEM) - you.attribute[ATTR_CARD_TABLE] = 1; - } - else - { - if (random2(200) <= you.piety && one_chance_in(4)) - gift_type = MISC_DECK_OF_SUMMONINGS; - if (random2(200) <= you.piety && coinflip()) - gift_type = MISC_DECK_OF_WONDERS; - if (random2(200) <= you.piety && one_chance_in(4)) - gift_type = MISC_DECK_OF_POWER; - - thing_created = items( 1, OBJ_MISCELLANY, gift_type, - true, 1, 250 ); - } - - if (thing_created != NON_ITEM) - { - move_item_to_grid( &thing_created, you.x_pos, you.y_pos ); - origin_acquired(mitm[thing_created], you.religion); - - simple_god_message(" grants you a gift!"); - more(); - canned_msg(MSG_SOMETHING_APPEARS); - - you.attribute[ATTR_CARD_COUNTDOWN] = 10; - inc_gift_timeout(5 + random2avg(9, 2)); - } - } + default: + break; - if ((you.religion == GOD_OKAWARU || you.religion == GOD_TROG) - && you.piety > 130 - && random2(you.piety) > 120 - && grd[you.x_pos][you.y_pos] != DNGN_LAVA - && grd[you.x_pos][you.y_pos] != DNGN_DEEP_WATER - && one_chance_in(4)) - { - if (you.religion == GOD_TROG - || (you.religion == GOD_OKAWARU && coinflip())) - { - success = acquirement(OBJ_WEAPONS, you.religion); - } - else + case GOD_ZIN: + //jmf: "good" god will sometimes feed you (a la Nethack) + if (you.hunger_state == HS_STARVING + && random2(250) <= you.piety) { - success = acquirement(OBJ_ARMOUR, you.religion); + god_speaks(you.religion, "Your stomach feels content."); + set_hunger(6000, true); + lose_piety(5 + random2avg(10, 2)); + inc_gift_timeout(30 + random2avg(10, 2)); } + break; - if (success) + case GOD_NEMELEX_XOBEH: + if (random2(200) <= you.piety + && (!you.attribute[ATTR_CARD_TABLE] || one_chance_in(3)) + && !you.attribute[ATTR_CARD_COUNTDOWN] + && !grid_destroys_items(grd[you.x_pos][you.y_pos])) { - simple_god_message(" has granted you a gift!"); - more(); + int thing_created = NON_ITEM; + unsigned char gift_type = MISC_DECK_OF_TRICKS; - inc_gift_timeout(30 + random2avg(19, 2)); - } - } + if (!you.attribute[ATTR_CARD_TABLE]) + { + thing_created = items( 1, OBJ_MISCELLANY, + MISC_PORTABLE_ALTAR_OF_NEMELEX, + true, 1, 250 ); - if (you.religion == GOD_YREDELEMNUL - && random2(you.piety) > 80 && one_chance_in(5)) - { - int thing_called = MONS_PROGRAM_BUG; // error trapping {dlb} + if (thing_created != NON_ITEM) + you.attribute[ATTR_CARD_TABLE] = 1; + } + else + { + if (random2(200) <= you.piety && one_chance_in(4)) + gift_type = MISC_DECK_OF_SUMMONINGS; + if (random2(200) <= you.piety && coinflip()) + gift_type = MISC_DECK_OF_WONDERS; + if (random2(200) <= you.piety && one_chance_in(4)) + gift_type = MISC_DECK_OF_POWER; + + thing_created = items( 1, OBJ_MISCELLANY, gift_type, + true, 1, 250 ); + } - temp_rand = random2(100); - thing_called = ((temp_rand > 66) ? MONS_WRAITH : // 33% - (temp_rand > 52) ? MONS_WIGHT : // 12% - (temp_rand > 40) ? MONS_SPECTRAL_WARRIOR : // 16% - (temp_rand > 31) ? MONS_ROTTING_HULK : // 9% - (temp_rand > 23) ? MONS_SKELETAL_WARRIOR : // 8% - (temp_rand > 16) ? MONS_VAMPIRE : // 7% - (temp_rand > 10) ? MONS_GHOUL : // 6% - (temp_rand > 4) ? MONS_MUMMY // 6% - : MONS_FLAYED_GHOST); // 5% + if (thing_created != NON_ITEM) + { + move_item_to_grid( &thing_created, you.x_pos, you.y_pos ); + origin_acquired(mitm[thing_created], you.religion); + + simple_god_message(" grants you a gift!"); + more(); + canned_msg(MSG_SOMETHING_APPEARS); - if (create_monster( thing_called, 0, BEH_FRIENDLY, - you.x_pos, you.y_pos, - you.pet_target, 250 ) != -1) - { - simple_god_message(" grants you an undead servant!"); - more(); - inc_gift_timeout(4 + random2avg(7, 2)); + you.attribute[ATTR_CARD_COUNTDOWN] = 10; + inc_gift_timeout(5 + random2avg(9, 2)); + you.num_gifts[you.religion]++; + } } - } - - if ((you.religion == GOD_KIKUBAAQUDGHA - || you.religion == GOD_SIF_MUNA - || you.religion == GOD_VEHUMET) - && you.piety > 160 && random2(you.piety) > 100) - { - unsigned int gift = NUM_BOOKS; - - switch (you.religion) + break; + + case GOD_OKAWARU: + if (you.piety > 80 + && random2( you.piety ) > 70 + && !grid_destroys_items( grd[you.x_pos][you.y_pos] ) + && one_chance_in(4) + && you.skills[ best_skill(SK_SLINGS, SK_THROWING) ] >= 3) { - case GOD_KIKUBAAQUDGHA: // gives death books - if (!you.had_book[BOOK_NECROMANCY]) - gift = BOOK_NECROMANCY; - else if (!you.had_book[BOOK_DEATH]) - gift = BOOK_DEATH; - else if (!you.had_book[BOOK_UNLIFE]) - gift = BOOK_UNLIFE; - else if (!you.had_book[BOOK_NECRONOMICON]) - gift = BOOK_NECRONOMICON; - break; + success = acquirement( OBJ_MISSILES, you.religion ); + if (success) + { + simple_god_message( " has granted you a gift!" ); + more(); - case GOD_SIF_MUNA: - gift = OBJ_RANDOM; // Sif Muna - gives any + inc_gift_timeout( 4 + roll_dice(2,4) ); + you.num_gifts[ you.religion ]++; + } break; + } + // intentional fall through + + case GOD_TROG: + if (you.piety > 130 + && random2(you.piety) > 120 + && !grid_destroys_items(grd[you.x_pos][you.y_pos]) + && one_chance_in(4)) + { + if (you.religion == GOD_TROG + || (you.religion == GOD_OKAWARU && coinflip())) + { + success = acquirement(OBJ_WEAPONS, you.religion); + } + else + { + success = acquirement(OBJ_ARMOUR, you.religion); + } - // Vehumet - gives conj/summ. books (higher skill first) - case GOD_VEHUMET: - if (!you.had_book[BOOK_CONJURATIONS_I]) - gift = give_first_conjuration_book(); - else if (!you.had_book[BOOK_POWER]) - gift = BOOK_POWER; - else if (!you.had_book[BOOK_ANNIHILATIONS]) - gift = BOOK_ANNIHILATIONS; // conj books - - if (you.skills[SK_CONJURATIONS] < you.skills[SK_SUMMONINGS] - || gift == NUM_BOOKS) + if (success) { - if (!you.had_book[BOOK_CALLINGS]) - gift = BOOK_CALLINGS; - else if (!you.had_book[BOOK_SUMMONINGS]) - gift = BOOK_SUMMONINGS; - else if (!you.had_book[BOOK_DEMONOLOGY]) - gift = BOOK_DEMONOLOGY; // summoning bks + simple_god_message(" has granted you a gift!"); + more(); + + inc_gift_timeout(30 + random2avg(19, 2)); + you.num_gifts[ you.religion ]++; } - break; } + break; - if (gift != NUM_BOOKS - && (grd[you.x_pos][you.y_pos] != DNGN_LAVA - && grd[you.x_pos][you.y_pos] != DNGN_DEEP_WATER)) + case GOD_YREDELEMNUL: + if (random2(you.piety) > 80 && one_chance_in(5)) { - if (gift == OBJ_RANDOM) - success = acquirement(OBJ_BOOKS, you.religion); - else + int thing_called = random_undead_servant(GOD_YREDELEMNUL); + if (create_monster( thing_called, 0, BEH_FRIENDLY, + you.x_pos, you.y_pos, + you.pet_target, 250 ) != -1) { - int thing_created = items(1, OBJ_BOOKS, gift, true, 1, 250); - if (thing_created == NON_ITEM) - return; + simple_god_message(" grants you an undead servant!"); + more(); + inc_gift_timeout(4 + random2avg(7, 2)); + you.num_gifts[you.religion]++; + } + } + break; - move_item_to_grid( &thing_created, you.x_pos, you.y_pos ); + case GOD_KIKUBAAQUDGHA: + case GOD_SIF_MUNA: + case GOD_VEHUMET: + if (you.piety > 160 && random2(you.piety) > 100) + { + unsigned int gift = NUM_BOOKS; - if (thing_created != NON_ITEM) + switch (you.religion) + { + case GOD_KIKUBAAQUDGHA: // gives death books + if (!you.had_book[BOOK_NECROMANCY]) + gift = BOOK_NECROMANCY; + else if (!you.had_book[BOOK_DEATH]) + gift = BOOK_DEATH; + else if (!you.had_book[BOOK_UNLIFE]) + gift = BOOK_UNLIFE; + else if (!you.had_book[BOOK_NECRONOMICON]) + gift = BOOK_NECRONOMICON; + break; + + case GOD_SIF_MUNA: + gift = OBJ_RANDOM; // Sif Muna - gives any + break; + + // Vehumet - gives conj/summ. books (higher skill first) + case GOD_VEHUMET: + if (!you.had_book[BOOK_CONJURATIONS_I]) + gift = give_first_conjuration_book(); + else if (!you.had_book[BOOK_POWER]) + gift = BOOK_POWER; + else if (!you.had_book[BOOK_ANNIHILATIONS]) + gift = BOOK_ANNIHILATIONS; // conj books + + if (you.skills[SK_CONJURATIONS] < + you.skills[SK_SUMMONINGS] + || gift == NUM_BOOKS) { - success = true; - origin_acquired(mitm[thing_created], you.religion); + if (!you.had_book[BOOK_CALLINGS]) + gift = BOOK_CALLINGS; + else if (!you.had_book[BOOK_SUMMONINGS]) + gift = BOOK_SUMMONINGS; + else if (!you.had_book[BOOK_DEMONOLOGY]) + gift = BOOK_DEMONOLOGY; // summoning bks } + break; } - if (success) + if (gift != NUM_BOOKS + && (grd[you.x_pos][you.y_pos] != DNGN_LAVA + && grd[you.x_pos][you.y_pos] != DNGN_DEEP_WATER)) { - simple_god_message(" has granted you a gift!"); - more(); + if (gift == OBJ_RANDOM) + success = acquirement(OBJ_BOOKS, you.religion); + else + { + int thing_created = items(1, OBJ_BOOKS, gift, true, 1, 250); + if (thing_created == NON_ITEM) + return; - inc_gift_timeout(40 + random2avg(19, 2)); - } + move_item_to_grid( &thing_created, you.x_pos, you.y_pos ); + if (thing_created != NON_ITEM) + { + success = true; + origin_acquired(mitm[thing_created], you.religion); + } + } - // Vehumet gives books less readily - if (you.religion == GOD_VEHUMET && success) - inc_gift_timeout(10 + random2(10)); - } // end of giving book - } // end of book gods + if (success) + { + simple_god_message(" has granted you a gift!"); + more(); + + inc_gift_timeout(40 + random2avg(19, 2)); + you.num_gifts[ you.religion ]++; + } + + // Vehumet gives books less readily + if (you.religion == GOD_VEHUMET && success) + inc_gift_timeout(10 + random2(10)); + } // end of giving book + } // end of book gods + break; + } } // end of gift giving } // end pray() @@ -939,154 +978,367 @@ void Xom_acts(bool niceness, int sever, bool force_sever) goto okay_try_again; } // end Xom_acts() -void done_good(char thing_done, int pgain) +// This function is the merger of done_good() and naughty(). +// Returns true if god was interested (good or bad) in conduct. +bool did_god_conduct( int thing_done, int level ) { - if (you.religion == GOD_NO_GOD) - return; + bool ret = false; + int piety_change = 0; + int penance = 0; + + if (you.religion == GOD_NO_GOD || you.religion == GOD_XOM) + return (false); switch (thing_done) { - case GOOD_KILLED_LIVING: + case DID_NECROMANCY: + case DID_UNHOLY: + case DID_ATTACK_HOLY: + switch (you.religion) + { + case GOD_ZIN: + case GOD_SHINING_ONE: + case GOD_ELYVILON: + piety_change = -level; + penance = level * ((you.religion == GOD_ZIN) ? 2 : 1); + ret = true; + break; + } + break; + + case DID_STABBING: + case DID_POISON: + if (you.religion == GOD_SHINING_ONE) + { + ret = true; + piety_change = -level; + penance = level * 2; + } + break; + + case DID_ATTACK_FRIEND: + switch (you.religion) + { + case GOD_ZIN: + case GOD_SHINING_ONE: + case GOD_ELYVILON: + case GOD_OKAWARU: + piety_change = -level; + penance = level * 3; + ret = true; + break; + } + break; + + case DID_FRIEND_DIES: + switch (you.religion) + { + case GOD_ELYVILON: + penance = level; // healer god cares more about this + // fall through + case GOD_ZIN: + case GOD_SHINING_ONE: + case GOD_OKAWARU: + piety_change = -level; + ret = true; + break; + } + break; + + case DID_DEDICATED_BUTCHERY: // aka field sacrifice switch (you.religion) { case GOD_ELYVILON: simple_god_message(" did not appreciate that!"); - naughty(NAUGHTY_KILLING, 10); + ret = true; + piety_change = -10; + penance = 10; break; - case GOD_KIKUBAAQUDGHA: - case GOD_YREDELEMNUL: - case GOD_VEHUMET: + case GOD_OKAWARU: case GOD_MAKHLEB: case GOD_TROG: - simple_god_message(" accepts your kill."); - if (random2(18 + pgain) > 5) - gain_piety(1); + simple_god_message(" accepts your offering."); + ret = true; + if (random2(level + 10) > 5) + piety_change = 1; break; } break; - case GOOD_KILLED_UNDEAD: + case DID_DEDICATED_KILL_LIVING: switch (you.religion) { - case GOD_ZIN: - case GOD_SHINING_ONE: + case GOD_ELYVILON: + simple_god_message(" did not appreciate that!"); + ret = true; + piety_change = -level; + penance = level * 2; + break; + + case GOD_KIKUBAAQUDGHA: + case GOD_YREDELEMNUL: + case GOD_OKAWARU: case GOD_VEHUMET: case GOD_MAKHLEB: - case GOD_OKAWARU: + case GOD_TROG: simple_god_message(" accepts your kill."); - if (random2(18 + pgain) > 4) - gain_piety(1); + ret = true; + if (random2(level + 18) > 5) + piety_change = 1; break; } break; - case GOOD_KILLED_DEMON: + case DID_DEDICATED_KILL_UNDEAD: switch (you.religion) { case GOD_ZIN: case GOD_SHINING_ONE: + case GOD_OKAWARU: case GOD_VEHUMET: case GOD_MAKHLEB: - case GOD_OKAWARU: simple_god_message(" accepts your kill."); - if (random2(18 + pgain) > 3) - gain_piety(1); + ret = true; + if (random2(level + 18) > 4) + piety_change = 1; break; } break; - case GOOD_KILLED_ANGEL_I: - case GOOD_KILLED_ANGEL_II: + case DID_DEDICATED_KILL_DEMON: switch (you.religion) { case GOD_ZIN: case GOD_SHINING_ONE: - case GOD_ELYVILON: - simple_god_message(" did not appreciate that!"); - naughty(NAUGHTY_ATTACK_HOLY, (you.conf ? 3 : pgain * 3)); + case GOD_OKAWARU: + simple_god_message(" accepts your kill."); + ret = true; + if (random2(level + 18) > 3) + piety_change = 1; break; } break; - case GOOD_KILLED_WIZARD: - // hooking this up, but is it too good? - // enjoy it while you can -- bwr + case DID_DEDICATED_KILL_WIZARD: if (you.religion == GOD_TROG) { - simple_god_message( " appreciates your killing of a magic user." ); - - if (random2( 5 + pgain ) > 5) - gain_piety(1); + // hooking this up, but is it too good? + // enjoy it while you can -- bwr + simple_god_message(" appreciates your killing of a magic user."); + ret = true; + if (random2(level + 10) > 5) + piety_change = 1; } break; - case GOOD_HACKED_CORPSE: // NB - pgain is you.experience_level (maybe) + // Note that Angel deaths are special, they are always noticed... + // if you or any friendly kills one you'll get the credit or the blame. + case DID_ANGEL_KILLED_BY_SERVANT: + case DID_KILL_ANGEL: switch (you.religion) { - // case GOD_KIKUBAAQUDGHA: - case GOD_OKAWARU: - case GOD_MAKHLEB: - case GOD_TROG: - simple_god_message(" accepts your offering."); - if (random2(10 + pgain) > 5) - gain_piety(1); + case GOD_ZIN: + case GOD_SHINING_ONE: + case GOD_ELYVILON: + level *= 3; + piety_change = -level; + penance = level * ((you.religion == GOD_ZIN) ? 2 : 1); + ret = true; break; - // case GOD_ZIN: - // case GOD_SHINING_ONE: - case GOD_ELYVILON: - simple_god_message(" did not appreciate that!"); + case GOD_KIKUBAAQUDGHA: + case GOD_YREDELEMNUL: + case GOD_MAKHLEB: + snprintf( info, INFO_SIZE, " accepts your %skill.", + (thing_done == DID_KILL_ANGEL) ? "" : "collateral " ); + + simple_god_message( info ); - naughty(NAUGHTY_BUTCHER, 8); + ret = true; + if (random2(level + 18) > 2) + piety_change = 1; break; } break; - case GOOD_OFFER_STUFF: - simple_god_message(" is pleased with your offering."); - - gain_piety(1); - break; - - case GOOD_SLAVES_KILL_LIVING: + // Undead slave is any friendly undead... Kiku and Yred pay attention + // to the undead and both like the death of living things. + case DID_LIVING_KILLED_BY_UNDEAD_SLAVE: switch (you.religion) { case GOD_KIKUBAAQUDGHA: case GOD_YREDELEMNUL: - case GOD_VEHUMET: simple_god_message(" accepts your slave's kill."); - - if (random2(pgain + 18) > 5) - gain_piety(1); + ret = true; + if (random2(level + 10) > 5) + piety_change = 1; break; } break; - case GOOD_SERVANTS_KILL: + // Servants are currently any friendly monster under Vehumet, or + // any god given pet for everyone else (excluding undead which are + // handled above). + case DID_LIVING_KILLED_BY_SERVANT: switch (you.religion) { + case GOD_KIKUBAAQUDGHA: // note: reapers aren't undead case GOD_VEHUMET: case GOD_MAKHLEB: simple_god_message(" accepts your collateral kill."); + ret = true; + if (random2(level + 10) > 5) + piety_change = 1; + break; + } + break; - if (random2(pgain + 18) > 5) - gain_piety(1); + case DID_UNDEAD_KILLED_BY_SERVANT: + switch (you.religion) + { + case GOD_ZIN: + case GOD_SHINING_ONE: + case GOD_VEHUMET: + case GOD_MAKHLEB: + simple_god_message(" accepts your collateral kill."); + ret = true; + if (random2(level + 10) > 5) + piety_change = 1; break; } break; - case GOOD_CARDS: + case DID_DEMON_KILLED_BY_SERVANT: switch (you.religion) { - case GOD_NEMELEX_XOBEH: - gain_piety(pgain); + case GOD_ZIN: + case GOD_SHINING_ONE: + simple_god_message(" accepts your collateral kill."); + ret = true; + if (random2(level + 10) > 5) + piety_change = 1; break; } break; - // Offering at altars is covered in another function. + + case DID_SPELL_MEMORISE: + if (you.religion == GOD_TROG) + { + penance = level * 10; + piety_change = -penance; + ret = true; + } + break; + + case DID_SPELL_CASTING: + if (you.religion == GOD_TROG) + { + piety_change = -level; + penance = level * 5; + ret = true; + } + break; + + case DID_SPELL_PRACTISE: + // Like CAST, but for skill advancement. + // Level is number of skill points gained... typically 10 * exerise, + // but may be more/less if the skill is at 0 (INT adjustment), or + // if the PC's pool is low and makes change. + if (you.religion == GOD_SIF_MUNA) + { + // Old curve: random2(12) <= spell-level, this is similar, + // but faster at low levels (to help ease things for low level + // Power averages about (level * 20 / 3) + 10 / 3 now. Also + // note that spell skill practise comes just after XP gain, so + // magical kills tend to do both at the same time (unlike melee). + // This means high level spells probably work pretty much like + // they used to (use spell, get piety). + piety_change = div_rand_round( level + 10, 90 ); + ret = true; + } + break; + + case DID_CARDS: + if (you.religion == GOD_NEMELEX_XOBEH) + { + piety_change = level; + ret = true; + } + break; + + case DID_STIMULANTS: // unused + case DID_EAT_MEAT: // unused + case DID_CREATED_LIFE: // unused + case DID_DEDICATED_KILL_NATURAL_EVIL: // unused + case DID_NATURAL_EVIL_KILLED_BY_SERVANT: // unused + case DID_SPELL_NONUTILITY: // unused + default: + break; } -} // end done_good() + + if (piety_change > 0) + { + // positive conduct only interesting out in the real world + if (!player_in_branch( BRANCH_ECUMENICAL_TEMPLE )) + gain_piety( piety_change ); + else if (one_chance_in(10)) + { + simple_god_message( " says: \"Go forth into the world to show your devotion to me!\"" ); + } + } + else + { + const int piety_loss = -piety_change; + + if (piety_loss) + { + // output guilt message: + mprf( "You feel%sguilty.", + (piety_loss == 1) ? " a little " : + (piety_loss < 5) ? " " : + (piety_loss < 10) ? " very " + : " extremely " ); + + lose_piety( piety_loss ); + } + + if (you.piety < 1) + excommunication(); + else if (penance) // only if still in religion + { + god_speaks( you.religion, + "\"You will pay for your transgression, mortal!\"" ); + + inc_penance( penance ); + } + } + +#if DEBUG_DIAGNOSTICS + if (ret) + { + static const char *conducts[] = + { + "Necromancy", "Unholy", "Attack Holy", "Attack Friend", + "Friend Died", "Stab", "Poison", "Field Sacrifice", + "Kill Living", "Kill Undead", "Kill Demon", "Kill Wizard", + "Kill Priest", "Kill Angel", "Undead Slave Kill Living", + "Servant Kill Living", "Servant Kill Undead", + "Servant Kill Demon", "Servant Kill Angel", + "Spell Memorise", "Spell Cast", "Spell Practise", "Spell Nonutility", + "Cards", "Stimulants", "Eat Meat", "Create Life" + }; + + mprf( MSGCH_DIAGNOSTICS, + "conduct: %s; piety: %d (%+d); penance: %d (%+d)", + conducts[thing_done], + you.piety, piety_change, you.penance[you.religion], penance ); + + } +#endif + + return (ret); +} void gain_piety(char pgn) { @@ -1321,158 +1573,6 @@ void gain_piety(char pgn) } } // end gain_piety() -void naughty(char type_naughty, int naughtiness) -{ - int penance = 0; - int piety_loss = 0; - - // if you currently worship no deity in particular, exit function {dlb} - if (you.religion == GOD_NO_GOD) - return; - - switch (you.religion) - { - case GOD_ZIN: - switch (type_naughty) - { - case NAUGHTY_NECROMANCY: - case NAUGHTY_UNHOLY: - case NAUGHTY_ATTACK_HOLY: - piety_loss = naughtiness; - penance = piety_loss * 2; - break; - case NAUGHTY_ATTACK_FRIEND: - piety_loss = naughtiness; - penance = piety_loss * 3; - break; - case NAUGHTY_FRIEND_DIES: - piety_loss = naughtiness; - break; - case NAUGHTY_BUTCHER: - piety_loss = naughtiness; - if (one_chance_in(3)) - penance = piety_loss; - break; - } - break; - - case GOD_SHINING_ONE: - switch (type_naughty) - { - case NAUGHTY_NECROMANCY: - case NAUGHTY_UNHOLY: - case NAUGHTY_ATTACK_HOLY: - piety_loss = naughtiness; - penance = piety_loss; - break; - case NAUGHTY_ATTACK_FRIEND: - piety_loss = naughtiness; - penance = piety_loss * 3; - break; - case NAUGHTY_FRIEND_DIES: - piety_loss = naughtiness; - break; - case NAUGHTY_BUTCHER: - piety_loss = naughtiness; - if (one_chance_in(3)) - penance = piety_loss; - break; - case NAUGHTY_STABBING: - piety_loss = naughtiness; - if (one_chance_in(5)) // can be accidental so we're nice here - penance = piety_loss; - break; - case NAUGHTY_POISON: - piety_loss = naughtiness; - penance = piety_loss * 2; - break; - } - break; - - case GOD_ELYVILON: - switch (type_naughty) - { - case NAUGHTY_NECROMANCY: - case NAUGHTY_UNHOLY: - case NAUGHTY_ATTACK_HOLY: - piety_loss = naughtiness; - penance = piety_loss; - break; - case NAUGHTY_KILLING: - piety_loss = naughtiness; - penance = piety_loss * 2; - break; - case NAUGHTY_ATTACK_FRIEND: - piety_loss = naughtiness; - penance = piety_loss * 3; - break; - // Healer god gets a bit more upset since you should have - // used your healing powers to save them. - case NAUGHTY_FRIEND_DIES: - piety_loss = naughtiness; - penance = piety_loss; - break; - case NAUGHTY_BUTCHER: - piety_loss = naughtiness; - if (one_chance_in(3)) - penance = piety_loss; - break; - } - break; - - case GOD_OKAWARU: - switch (type_naughty) - { - case NAUGHTY_ATTACK_FRIEND: - piety_loss = naughtiness; - penance = piety_loss * 3; - break; - case NAUGHTY_FRIEND_DIES: - piety_loss = naughtiness; - break; - } - break; - - case GOD_TROG: - switch (type_naughty) - { - case NAUGHTY_SPELLCASTING: - piety_loss = naughtiness; - // This penance isn't so bad since its much easier to - // gain piety with Trog than the other gods in this function. - penance = piety_loss * 10; - break; - } - break; - } - - // exit function early iff piety loss is zero: - if (piety_loss < 1) - return; - - // output guilt message: - strcpy(info, "You feel"); - - strcat(info, (piety_loss == 1) ? " a little " : - (piety_loss < 5) ? " " : - (piety_loss < 10) ? " very " - : " extremely "); - - strcat(info, "guilty."); - mpr(info); - - lose_piety(piety_loss); - - if (you.piety < 1) - excommunication(); - else if (penance) // Don't bother unless we're not kicking them out - { - //jmf: FIXME: add randomness to following message: - god_speaks(you.religion, "\"You will pay for your transgression, mortal!\""); - inc_penance(penance); - } -} // end naughty() - void lose_piety(char pgn) { int old_piety = you.piety; @@ -2222,6 +2322,45 @@ void excommunication(void) } } // end excommunication() +static bool bless_weapon( int god, int brand, int colour ) +{ + const int wpn = get_player_wielded_weapon(); + + // Assuming the type of weapon is correct, we only need to check + // to see if it's an artefact we can successfully clobber: + if (!is_fixed_artefact( you.inv[wpn] ) + && !is_random_artefact( you.inv[wpn] )) + { + you.duration[DUR_WEAPON_BRAND] = 0; // just in case + + set_equip_desc( you.inv[wpn], ISFLAG_GLOWING ); + set_item_ego_type( you.inv[wpn], OBJ_WEAPONS, brand ); + you.inv[wpn].colour = colour; + + do_uncurse_item( you.inv[wpn] ); + enchant_weapon( ENCHANT_TO_HIT, true ); + enchant_weapon( ENCHANT_TO_DAM, true ); + + you.wield_change = true; + you.num_gifts[god]++; + + you.flash_colour = colour; + viewwindow( true, false ); + + mprf( MSGCH_GOD, "Your weapon shines brightly!" ); + simple_god_message( " booms: Use this gift wisely!" ); + + // as currently only Zin and TSO do this is our permabrand effect: + holy_word( 100, true ); + + more(); + mesclr(); + + return (true); + } + + return (false); +} void altar_prayer(void) { @@ -2239,9 +2378,48 @@ void altar_prayer(void) mpr( "You kneel at the altar and pray." ); - if (you.religion == GOD_SHINING_ONE || you.religion == GOD_XOM) + if (you.religion == GOD_XOM) return; + // TSO blesses long swords with holy wrath + if (you.religion == GOD_SHINING_ONE + && !you.num_gifts[GOD_SHINING_ONE] + && !player_under_penance() + && you.piety > 160) + { + const int wpn = get_player_wielded_weapon(); + + if (wpn != -1 + && weapon_skill( you.inv[wpn] ) == SK_LONG_SWORDS + && get_weapon_brand( you.inv[wpn] ) != SPWPN_HOLY_WRATH) + { + if (bless_weapon( GOD_SHINING_ONE, SPWPN_HOLY_WRATH, YELLOW )) + { + // convert those demon blades if blessed: + if (you.inv[wpn].sub_type == WPN_DEMON_BLADE) + you.inv[wpn].sub_type = WPN_BLESSED_BLADE; + } + } + } + + // Zin blesses maces with disruption + if (you.religion == GOD_ZIN + && !you.num_gifts[GOD_ZIN] + && !player_under_penance() + && you.piety > 160) + { + const int wpn = get_player_wielded_weapon(); + + if (wpn != -1 + && (you.inv[wpn].base_type == OBJ_WEAPONS + && (you.inv[wpn].sub_type == WPN_MACE + || you.inv[wpn].sub_type == WPN_GREAT_MACE)) + && get_weapon_brand( you.inv[wpn] ) != SPWPN_DISRUPTION) + { + bless_weapon( GOD_ZIN, SPWPN_DISRUPTION, WHITE ); + } + } + i = igrd[you.x_pos][you.y_pos]; while (i != NON_ITEM) { @@ -2410,7 +2588,7 @@ void offer_corpse(int corpse) strcat(info, sacrifice[you.religion - 1]); mpr(info); - done_good(GOOD_HACKED_CORPSE, 10); + did_god_conduct(DID_DEDICATED_BUTCHERY, 10); } // end offer_corpse() //jmf: moved stuff from items::handle_time() diff --git a/crawl-ref/source/religion.h b/crawl-ref/source/religion.h index 7ca62f4e03..1ec71c827b 100644 --- a/crawl-ref/source/religion.h +++ b/crawl-ref/source/religion.h @@ -14,103 +14,20 @@ #include "enum.h" -// last updated 03jun2000 {dlb} -/* *********************************************************************** - * called from: ouch - religion - * *********************************************************************** */ void simple_god_message( const char *event, int which_deity = GOD_NO_GOD ); - - -// last updated 11jan2001 {mv} -/* *********************************************************************** - * called from: chardump - overmap - religion - * *********************************************************************** */ char *god_name(int which_god,bool long_name=false); //mv - - -// last updated 24may2000 {dlb} -/* *********************************************************************** - * called from: religion - spell - * *********************************************************************** */ void dec_penance(int val); - - -// last updated 24may2000 {dlb} -/* *********************************************************************** - * called from: acr - decks - fight - player - religion - spell - * *********************************************************************** */ +void dec_penance(int god, int val); void Xom_acts(bool niceness, int sever, bool force_sever); - - -// last updated 24may2000 {dlb} -/* *********************************************************************** - * called from: beam - decks - fight - religion - * *********************************************************************** */ -void done_good(char thing_done, int pgain); - - -// last updated 24may2000 {dlb} -/* *********************************************************************** - * called from: ability - religion - * *********************************************************************** */ +bool did_god_conduct(int thing_done, int pgain); void excommunication(void); - - -// last updated 24may2000 {dlb} -/* *********************************************************************** - * called from: acr - religion - spell - * *********************************************************************** */ void gain_piety(char pgn); - - -// last updated 24may2000 {dlb} -/* *********************************************************************** - * called from: spell - religion - * *********************************************************************** */ void god_speaks( int god, const char *mesg ); - - -// last updated 24may2000 {dlb} -/* *********************************************************************** - * called from: ability - religion - * *********************************************************************** */ void lose_piety(char pgn); - - -// last updated 24may2000 {dlb} -/* *********************************************************************** - * called from: acr - beam - fight - it_use2 - item_use - religion - spell - - * spellbook - spells4 - * *********************************************************************** */ -void naughty(char type_naughty, int naughtiness); - - -// last updated 24may2000 {dlb} -/* *********************************************************************** - * called from: food - * *********************************************************************** */ void offer_corpse(int corpse); - - -// last updated 24may2000 {dlb} -/* *********************************************************************** - * called from: acr - * *********************************************************************** */ void pray(void); - - -// last updated 24may2000 {dlb} -/* *********************************************************************** - * called from: items - * *********************************************************************** */ void handle_god_time(void); - -// created 5jan2001 {mv} -/* *********************************************************************** - * called from: message, describe - * *********************************************************************** */ char god_colour(char god); - void god_pitch(unsigned char which_god); #endif diff --git a/crawl-ref/source/shopping.cc b/crawl-ref/source/shopping.cc index dee10a8d8c..cef4bb0d78 100644 --- a/crawl-ref/source/shopping.cc +++ b/crawl-ref/source/shopping.cc @@ -498,7 +498,6 @@ unsigned int item_value( item_def item, id_arr id, bool ident ) item.flags = (ident) ? (item.flags | ISFLAG_IDENT_MASK) : (item.flags); int valued = 0; - int charge_value = 0; switch (item.base_type) { @@ -660,22 +659,23 @@ unsigned int item_value( item_def item, id_arr id, bool ident ) break; case WPN_DOUBLE_SWORD: - valued += 200; + valued += 100; break; case WPN_DEMON_WHIP: - valued += 230; + valued += 130; break; case WPN_QUICK_BLADE: case WPN_DEMON_TRIDENT: - valued += 250; + valued += 150; break; case WPN_KATANA: case WPN_TRIPLE_SWORD: case WPN_DEMON_BLADE: - valued += 300; + case WPN_BLESSED_BLADE: + valued += 200; break; } @@ -1059,100 +1059,66 @@ unsigned int item_value( item_def item, id_arr id, bool ident ) break; case OBJ_WANDS: - charge_value = 0; - if (id[0][item.sub_type]) + if (!id[ IDTYPE_WANDS ][item.sub_type]) + valued += 200; + else { switch (item.sub_type) { case WAND_FIREBALL: - case WAND_LIGHTNING: - valued += 20; - charge_value += 5; + case WAND_HASTING: + valued += 600; break; - case WAND_DRAINING: - valued += 20; - charge_value += 4; + case WAND_HEALING: + case WAND_TELEPORTATION: + valued += 500; break; + case WAND_INVISIBILITY: case WAND_DISINTEGRATION: - valued += 17; - charge_value += 4; - break; - - case WAND_POLYMORPH_OTHER: - valued += 15; - charge_value += 4; + case WAND_LIGHTNING: + valued += 400; break; case WAND_COLD: - case WAND_ENSLAVEMENT: case WAND_FIRE: - case WAND_HASTING: - valued += 15; - charge_value += 3; - break; - - case WAND_INVISIBILITY: - valued += 15; - charge_value += 2; + valued += 350; break; - case WAND_RANDOM_EFFECTS: - valued += 13; - charge_value += 3; + case WAND_DIGGING: + valued += 200; break; + case WAND_FLAME: + case WAND_FROST: + case WAND_DRAINING: case WAND_PARALYSIS: - valued += 12; - charge_value += 3; + valued += 150; break; + case WAND_ENSLAVEMENT: + case WAND_POLYMORPH_OTHER: case WAND_SLOWING: - valued += 10; - charge_value += 3; + valued += 100; break; case WAND_CONFUSION: - case WAND_DIGGING: - case WAND_TELEPORTATION: - valued += 10; - charge_value += 2; - break; - - case WAND_HEALING: - valued += 7; - charge_value += 3; - break; - - case WAND_FLAME: - case WAND_FROST: - valued += 5; - charge_value += 2; - break; - case WAND_MAGIC_DARTS: - valued += 3; - charge_value++; - break; - - default: // no default charge_value ??? 15jan2000 {dlb} - valued += 10; + case WAND_RANDOM_EFFECTS: + default: + valued += 75; break; } if (item_ident( item, ISFLAG_KNOW_PLUSES )) { - valued += item.plus * charge_value; + if (item.plus == 0) + valued -= 50; + else + valued = (valued * (item.plus + 45)) / 50; } - - valued *= 3; - - if (item.plus == 0) - valued = 3; // change if wands are rechargeable! } - else - valued = 35; // = 10; break; case OBJ_POTIONS: @@ -1514,6 +1480,10 @@ unsigned int item_value( item_def item, id_arr id, bool ident ) } else valued = 250; + + if (item_is_rod( item ) && item_ident( item, ISFLAG_KNOW_PLUSES )) + valued += 50 * (item.plus2 / ROD_CHARGE_MULT); + break; case OBJ_ORBS: diff --git a/crawl-ref/source/skills.cc b/crawl-ref/source/skills.cc index 9dc63d54f0..2c96373bf3 100644 --- a/crawl-ref/source/skills.cc +++ b/crawl-ref/source/skills.cc @@ -38,7 +38,7 @@ #define MAX_COST_LIMIT 250 #define MAX_SPENDING_LIMIT 250 -static void exercise2( char exsk ); +static int exercise2( int exsk ); // These values were calculated by running a simulation of gaining skills. // The goal is to try and match the old cost system which used the player's @@ -146,27 +146,37 @@ static int calc_skill_cost( int skill_cost_level, int skill_level ) return (ret); } -void exercise(char exsk, int deg) +// returns total number of skill points gained +int exercise(int exsk, int deg) { - if (you.exp_available > 0 && you.skills[exsk] < 27) + int ret = 0; + + while (deg > 0) { - while (deg > 0) - { - if (!you.practise_skill[exsk] && !one_chance_in(4)) - break; + if (you.exp_available <= 0 || you.skills[exsk] >= 27) + break; - if (you.skills[exsk] >= 27) - break; + if (you.practise_skill[exsk] || one_chance_in(4)) + ret += exercise2( exsk ); - exercise2( exsk ); - deg--; - } + deg--; + } + +#ifdef DEBUG_DIAGNOSTICS + if (ret) + { + mprf(MSGCH_DIAGNOSTICS, + "Exercised %s (deg: %d) by %d", + skill_name(exsk), + deg, + ret); } +#endif - return; + return (ret); } // end exercise() -static void exercise2( char exsk ) +static int exercise2( int exsk ) { int deg = 1; int bonus = 0; @@ -237,7 +247,7 @@ static void exercise2( char exsk ) || you.skills[SK_EARTH_MAGIC] > you.skills[exsk])) { if (one_chance_in(3)) - return; + return (0); } // some are direct opposites @@ -247,7 +257,7 @@ static void exercise2( char exsk ) { // of course, this is cumulative with the one above. if (!one_chance_in(3)) - return; + return (0); } if ((exsk == SK_AIR_MAGIC || exsk == SK_EARTH_MAGIC) @@ -255,7 +265,7 @@ static void exercise2( char exsk ) || you.skills[SK_EARTH_MAGIC] > you.skills[exsk])) { if (!one_chance_in(3)) - return; + return (0); } // experimental restriction (too many spell schools) -- bwr @@ -270,7 +280,7 @@ static void exercise2( char exsk ) // Things get progressively harder, but not harder than // the Fire-Air or Ice-Earth level. if (skill_rank > 3 && one_chance_in(10 - skill_rank)) - return; + return (0); } int fraction = 0; @@ -351,6 +361,9 @@ static void exercise2( char exsk ) } } + if (skill_inc <= 0) + return (0); + you.skill_points[exsk] += skill_inc; you.exp_available -= skill_change; @@ -438,4 +451,5 @@ static void exercise2( char exsk ) redraw_skill( you.your_name, player_title() ); } } + return (skill_inc); } // end exercise2() diff --git a/crawl-ref/source/skills.h b/crawl-ref/source/skills.h index 10afa1df8a..35136ec427 100644 --- a/crawl-ref/source/skills.h +++ b/crawl-ref/source/skills.h @@ -20,7 +20,7 @@ void calc_total_skill_points( void ); * called from: ability - bang - beam - debug - fight - it_use3 - item_use - * items - misc - spell * *********************************************************************** */ -void exercise(char exsk, int deg); +int exercise(int exsk, int deg); #endif diff --git a/crawl-ref/source/skills2.cc b/crawl-ref/source/skills2.cc index f4012d0462..416c31de9c 100644 --- a/crawl-ref/source/skills2.cc +++ b/crawl-ref/source/skills2.cc @@ -1947,7 +1947,7 @@ void show_skills(void) } -const char *skill_name(unsigned char which_skill) +const char *skill_name(int which_skill) { return (skills[which_skill][0]); } // end skill_name() @@ -2038,10 +2038,9 @@ const char *player_title( void ) return (skill_title( best, you.skills[ best ] )); } // end player_title() -unsigned char best_skill( unsigned char min_skill, unsigned char max_skill, - unsigned char excl_skill ) +int best_skill( int min_skill, int max_skill, int excl_skill ) { - unsigned char ret = SK_FIGHTING; + int ret = SK_FIGHTING; unsigned int best_skill_level = 0; unsigned int best_position = 1000; diff --git a/crawl-ref/source/skills2.h b/crawl-ref/source/skills2.h index 05c5d03068..73658f31af 100644 --- a/crawl-ref/source/skills2.h +++ b/crawl-ref/source/skills2.h @@ -23,7 +23,7 @@ /* *********************************************************************** * called from: chardump - it_use3 - itemname - skills * *********************************************************************** */ -const char *skill_name(unsigned char which_skill); +const char *skill_name(int which_skill); // last_updated 24may2000 {dlb} @@ -46,7 +46,7 @@ const char *player_title( void ); * called from: acr - chardump - effects - files - player - skills - * skills2 - stuff * *********************************************************************** */ -unsigned char best_skill(unsigned char min_skill, unsigned char max_skill, unsigned char excl_skill); +int best_skill(int min_skill, int max_skill, int excl_skill = -1); void init_skill_order( void ); diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc index 64bb5630f0..53a3d580dd 100644 --- a/crawl-ref/source/spells1.cc +++ b/crawl-ref/source/spells1.cc @@ -229,6 +229,146 @@ void cast_fire_storm(int powc) viewwindow(1, false); } // end cast_fire_storm() + +void cast_chain_lightning( int powc ) +{ + struct bolt beam; + + // initialize beam structure + strcpy( beam.beam_name, "lightning arc" ); + beam.aux_source = "chain lightning"; + beam.beam_source = MHITYOU; + beam.thrower = KILL_YOU_MISSILE; + beam.range = 8; + beam.rangeMax = 8; + beam.hit = AUTOMATIC_HIT; + beam.type = SYM_ZAP; + beam.flavour = BEAM_ELECTRICITY; + beam.obviousEffect = true; + beam.isBeam = false; // since we want to stop at our target + beam.isExplosion = false; + beam.isTracer = false; + beam.isExplosion = false; + + int sx, sy; + int tx, ty; + int i; + + for (sx = you.x_pos, sy = you.y_pos; + powc > 0; + powc -= 8 + random2(13), sx = tx, sy = ty) + { + // infinity as far as this spell is concerned + // (Range - 1) is used because the distance is randomized and + // may be shifted by one. + int min_dist = MONSTER_LOS_RANGE - 1; + + int dist; + int count = 0; + + tx = -1; + ty = -1; + + for (i = 0; i < MAX_MONSTERS; i++) + { + struct monsters *monster = &menv[i]; + + if (monster->type == -1) + continue; + + dist = grid_distance( sx, sy, monster->x, monster->y ); + + // check for the source of this arc + if (!dist) + continue; + + // randomize distance (arcs don't care about a couple of feet) + dist += (random2(3) - 1); + + // always ignore targets further than current one + if (dist > min_dist) + continue; + + if (!check_line_of_sight( sx, sy, monster->x, monster->y )) + continue; + + count++; + + if (dist < min_dist) + { + // switch to looking for closer targets (but not always) + if (!one_chance_in(10)) + { + min_dist = dist; + tx = monster->x; + ty = monster->y; + count = 0; + } + } + else if (tx == -1 || one_chance_in( count )) + { + // either first target, or new selected target at min_dist + tx = monster->x; + ty = monster->y; + + // need to set min_dist for first target case + if (dist < min_dist) + min_dist = dist; + } + } + + // now check if the player is a target: + dist = grid_distance( sx, sy, you.x_pos, you.y_pos ); + + if (dist) // ie player was not the source + { + // distance randomized (as above) + dist += (random2(3) - 1); + + // select player if only, closest, or randomly selected + if ((tx == -1 + || dist < min_dist + || (dist == min_dist && one_chance_in( count + 1 ))) + && check_line_of_sight( sx, sy, you.x_pos, you.y_pos )) + { + tx = you.x_pos; + ty = you.y_pos; + } + } + + const bool see_source = see_grid( sx, sy ); + const bool see_targ = see_grid( tx, ty ); + + if (tx == -1) + { + if (see_source) + mpr( "The lightning grounds out." ); + + break; + } + + // Trying to limit message spamming here so we'll only mention + // the thunder when it's out of LoS. + if (noisy( 25, sx, sy ) && !see_source) + mpr( "You hear a mighty clap of thunder!", MSGCH_SOUND ); + + if (see_source && !see_targ) + mpr( "The lightning arcs out of your line of sight!" ); + else if (!see_source && see_targ) + mpr( "The lightning arc suddenly appears!" ); + + beam.source_x = sx; + beam.source_y = sy; + beam.target_x = tx; + beam.target_y = ty; + beam.colour = LIGHTBLUE; + beam.damage = calc_dice( 2, 10 + powc / 2 ); // from beam.cc + fire_beam( beam ); + } + + more(); +} + void identify(int power) { int id_used = 1; diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index dbd8f00f3b..45bd01391c 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -29,6 +29,7 @@ #include "beam.h" #include "cloud.h" #include "direct.h" +#include "dungeon.h" #include "effects.h" #include "itemname.h" #include "items.h" @@ -112,14 +113,79 @@ unsigned char detect_items( int pow ) return (items_found); } // end detect_items() +static void fuzz_detect_creatures(int pow, int *fuzz_radius, int *fuzz_chance) +{ +#ifdef DEBUG_DIAGNOSTICS + mprf("dc_fuzz: Power is %d", pow); +#endif + + if (pow < 1) + pow = 1; + + *fuzz_radius = pow >= 50? 1 : 2; + + // Fuzz chance starts off at 100% and declines to a low of 10% for obscenely + // powerful castings (pow caps around the 60 mark). + *fuzz_chance = 100 - 90 * (pow - 1) / 59; + if (*fuzz_chance < 10) + *fuzz_chance = 10; +} + +static void mark_detected_creature(int gridx, int gridy, const monsters *mon, + int fuzz_chance, int fuzz_radius) +{ + if (fuzz_radius && fuzz_chance > random2(100)) + { + const int fuzz_diam = 2 * fuzz_radius + 1; + + int gx, gy; + bool found_good = false; + for (int itry = 0; itry < 5; ++itry) + { + gx = gridx + random2(fuzz_diam) - fuzz_radius; + gy = gridy + random2(fuzz_diam) - fuzz_radius; + + if (in_map_grid(gx, gy) && !feat_blocks_movement(grd[gx][gy])) + { + found_good = true; + break; + } + } + + if (found_good) + { + gridx = gx; + gridy = gy; + } + } + + const int envx = gridx - 1, + envy = gridy - 1; + + unsigned short flags = env.map[envx][envy]; + flags = !flags || (flags & ENVF_DETECTED)? + ENVF_DETECTED + : 0; + + env.map[envx][envy] = + mons_char( mon->type ) | ENVF_DETECT_MONS | flags; +} + unsigned char detect_creatures( int pow ) { + int fuzz_radius = 0, fuzz_chance = 0; + fuzz_detect_creatures(pow, &fuzz_radius, &fuzz_chance); + if (pow > 50) pow = 50; unsigned char creatures_found = 0; const int map_radius = 8 + random2(8) + pow; + // Clear the map so detect creatures is more useful and the detection + // fuzz is harder to analyse by averaging. + clear_map(); + mpr("You detect creatures!"); for (int i = you.x_pos - map_radius; i < you.x_pos + map_radius; i++) @@ -132,19 +198,12 @@ unsigned char detect_creatures( int pow ) if (mgrd[i][j] != NON_MONSTER) { struct monsters *mon = &menv[ mgrd[i][j] ]; - - unsigned short flags = env.map[i - 1][j - 1]; - flags = !flags || (flags & ENVF_DETECTED)? - ENVF_DETECTED - : 0; - - env.map[i - 1][j - 1] = - mons_char( mon->type ) | ENVF_DETECT_MONS | flags; + mark_detected_creature(i, j, mon, fuzz_chance, fuzz_radius); // Assuming that highly intelligent spellcasters can // detect scyring. -- bwr if (mons_intel( mon->type ) == I_HIGH - && mons_flag( mon->type, M_SPELLCASTER )) + && mons_class_flag( mon->type, M_SPELLCASTER )) { behaviour_event( mon, ME_DISTURB, MHITYOU, you.x_pos, you.y_pos ); @@ -707,11 +766,12 @@ void turn_undead(int pow) } // end "for tu" } // end turn_undead() -void holy_word(int pow) +void holy_word(int pow, bool silent) { struct monsters *monster; - mpr("You speak a Word of immense power!"); + if (!silent) + mpr("You speak a Word of immense power!"); // doubt this will ever happen, but it's here as a safety -- bwr if (pow > 300) @@ -859,7 +919,7 @@ void cast_refrigeration(int pow) print_wounds(monster); //jmf: "slow snakes" finally available - if (mons_flag( monster->type, M_COLD_BLOOD ) && coinflip()) + if (mons_class_flag( monster->type, M_COLD_BLOOD ) && coinflip()) mons_add_ench(monster, ENCH_SLOW); } } @@ -1082,7 +1142,7 @@ char burn_freeze(int pow, char flavour) if (flavour == BEAM_COLD) { - if (mons_flag( monster->type, M_COLD_BLOOD ) && coinflip()) + if (mons_class_flag( monster->type, M_COLD_BLOOD ) && coinflip()) mons_add_ench(monster, ENCH_SLOW); const int cold_res = mons_res_cold( monster ); @@ -1314,10 +1374,10 @@ void summon_scorpions(int pow) } } // end summon_scorpions() -void summon_ice_beast_etc(int pow, int ibc) +void summon_ice_beast_etc(int pow, int ibc, bool divine_gift) { int numsc = ENCH_ABJ_II + (random2(pow) / 4); - int beha = BEH_FRIENDLY; + int beha = divine_gift? BEH_GOD_GIFT : BEH_FRIENDLY; if (numsc > ENCH_ABJ_VI) numsc = ENCH_ABJ_VI; diff --git a/crawl-ref/source/spells2.h b/crawl-ref/source/spells2.h index 8c3bef71c5..409aff5a25 100644 --- a/crawl-ref/source/spells2.h +++ b/crawl-ref/source/spells2.h @@ -116,7 +116,7 @@ void drain_life(int pow); /* *********************************************************************** * called from: ability - spell * *********************************************************************** */ -void holy_word(int pow); +void holy_word(int pow, bool silent = false); // last updated 24may2000 {dlb} @@ -131,7 +131,7 @@ bool restore_stat(unsigned char which_stat, bool suppress_msg); /* *********************************************************************** * called from: ability - spell * *********************************************************************** */ -void summon_ice_beast_etc(int pow, int ibc); +void summon_ice_beast_etc(int pow, int ibc, bool divine_gift = false); // last updated 24may2000 {dlb} diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index e2a2bf325f..ff66e68eb1 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -877,12 +877,12 @@ bool project_noise(void) if (!silenced( you.x_pos, you.y_pos )) { if (!success) - mpr("You hear a dull thud."); + mpr("You hear a dull thud.", MSGCH_SOUND); else { snprintf( info, INFO_SIZE, "You hear a %svoice call your name.", (see_grid( plox[0], plox[1] ) ? "distant " : "") ); - mpr( info ); + mpr( info , MSGCH_SOUND ); } } } diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index 26b09c3901..b8082ce6d0 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -298,7 +298,7 @@ static int shatter_items(int x, int y, int pow, int garbage) if (broke_stuff) { if (!silenced(x, y) && !silenced(you.x_pos, you.y_pos)) - mpr("You hear glass break."); + mpr("You hear glass break.", MSGCH_SOUND); return 1; } @@ -394,7 +394,7 @@ void cast_shatter(int pow) noisy( 30, you.x_pos, you.y_pos ); snprintf(info, INFO_SIZE, "The dungeon %s!", (sil ? "shakes" : "rumbles")); - mpr(info); + mpr(info, (sil? MSGCH_PLAIN : MSGCH_SOUND)); switch (you.attribute[ATTR_TRANSFORMATION]) { @@ -434,7 +434,7 @@ void cast_shatter(int pow) pow, rad, 0 ); if (dest && !sil) - mpr("Ka-crash!"); + mpr("Ka-crash!", MSGCH_SOUND); } // end cast_shatter() // cast_forescry: raises evasion (by 8 currently) via divination @@ -864,7 +864,7 @@ static int sleep_monsters(int x, int y, int pow, int garbage) menv[mnstr].behaviour = BEH_SLEEP; mons_add_ench( &menv[mnstr], ENCH_SLEEP_WARY ); - if (mons_flag( menv[mnstr].type, M_COLD_BLOOD ) && coinflip()) + if (mons_class_flag( menv[mnstr].type, M_COLD_BLOOD ) && coinflip()) mons_add_ench( &menv[mnstr], ENCH_SLOW ); return 1; @@ -3014,7 +3014,7 @@ static bool mons_can_host_shuggoth(int type) //jmf: simplified { if (mons_holiness(type) != MH_NATURAL) return false; - if (mons_flag(type, M_WARM_BLOOD)) + if (mons_class_flag(type, M_WARM_BLOOD)) return true; return false; diff --git a/crawl-ref/source/spells4.h b/crawl-ref/source/spells4.h index 94cc74fcac..d34f83e87a 100644 --- a/crawl-ref/source/spells4.h +++ b/crawl-ref/source/spells4.h @@ -45,6 +45,7 @@ void cast_silence(int pow); void cast_sticks_to_snakes(int pow); void cast_summon_butterflies(int pow); void cast_summon_dragon(int pow); +void cast_chain_lightning( int pow ); void cast_conjure_ball_lightning(int pow); void cast_summon_large_mammal(int pow); void cast_tame_beasts(int pow); diff --git a/crawl-ref/source/spl-book.cc b/crawl-ref/source/spl-book.cc index c6efbae9cf..c1fc77d4dd 100644 --- a/crawl-ref/source/spl-book.cc +++ b/crawl-ref/source/spl-book.cc @@ -26,6 +26,7 @@ #include "debug.h" #include "delay.h" +#include "food.h" #include "invent.h" #include "itemname.h" #include "items.h" @@ -434,7 +435,7 @@ static int spellbook_template_array[NUMBER_SPELLBOOKS][SPELLBOOK_SIZE] = {0, SPELL_ISKENDERUNS_MYSTIC_BLAST, SPELL_POISON_ARROW, - SPELL_ORB_OF_ELECTROCUTION, // XXX: chain lightning? + SPELL_CHAIN_LIGHTNING, SPELL_LEHUDIBS_CRYSTAL_SPEAR, SPELL_ICE_STORM, SPELL_FIRE_STORM, @@ -513,7 +514,7 @@ static int spellbook_template_array[NUMBER_SPELLBOOKS][SPELLBOOK_SIZE] = // 40 - Book of Earth {0, - SPELL_MAXWELLS_SILVER_HAMMER, + // SPELL_MAXWELLS_SILVER_HAMMER, SPELL_MAGIC_MAPPING, SPELL_DIG, SPELL_STATUE_FORM, @@ -1423,7 +1424,7 @@ bool learn_spell(void) you.turn_is_over = 1; redraw_screen(); - naughty( NAUGHTY_SPELLCASTING, 2 + random2(5) ); + did_god_conduct( DID_SPELL_CASTING, 2 + random2(5) ); return (true); } // end which_spell() @@ -1457,7 +1458,7 @@ int staff_spell( int staff ) { int spell; unsigned char specspell; - int mana, diff; + int mana, diff, food, energy; FixedVector< int, SPELLBOOK_SIZE > spell_list; // converting sub_type into book index type @@ -1468,8 +1469,8 @@ int staff_spell( int staff ) const int powc = 5 + you.skills[SK_EVOCATIONS] + roll_dice( 2, you.skills[SK_EVOCATIONS] ); - if (you.inv[staff].sub_type < STAFF_SMITING - || you.inv[staff].sub_type >= STAFF_AIR) + const int staff_type = you.inv[staff].sub_type; + if (staff_type < STAFF_SMITING || staff_type >= STAFF_AIR) { //mpr("That staff has no spells in it."); canned_msg(MSG_NOTHING_HAPPENS); @@ -1529,13 +1530,36 @@ int staff_spell( int staff ) if (specspell == SPELL_NO_SPELL) goto whattt; - mana = spell_mana( specspell ); + mana = spell_mana( specspell ) * ROD_CHARGE_MULT; diff = spell_difficulty( specspell ); + food = spell_hunger( specspell ); - if (you.magic_points < mana || you.experience_level < diff) + if (food && (you.is_undead != US_UNDEAD + && (you.hunger_state < HS_HUNGRY || you.hunger <= food))) { - mpr("Your brain hurts!"); - confuse_player( 2 + random2(4) ); + mpr("You don't have the energy to cast that spell."); + return (0); + } + + if (staff_type == STAFF_STRIKING) + mana /= ROD_CHARGE_MULT; + + if ((staff_type == STAFF_STRIKING? + you.magic_points < mana + : you.inv[staff].plus < mana) + || you.experience_level < diff) + { +#ifdef DEBUG_DIAGNOSTICS + mprf("Mana needed: %d, Staff plus: %d, Difficulty: %d, XP: %d", + mana, you.inv[staff].plus, diff, you.experience_level); +#endif + if (you.experience_level < diff) + mprf("You need to be at least level %d to use that.", diff); + else + mprf("%s have enough magic points.", + staff_type == STAFF_STRIKING? "You don't" : "The rod doesn't"); + + // confuse_player( 2 + random2(4) ); you.turn_is_over = 1; return (0); } @@ -1548,8 +1572,28 @@ int staff_spell( int staff ) // exercise_spell(specspell, true, true); your_spells(specspell, powc, false); + + + // [dshaligram] + // dec_mp(spell_mana(specspell)); + if (staff_type != STAFF_STRIKING) + you.inv[staff].plus -= mana; + else { + you.magic_points -= mana; + you.redraw_magic_points = true; + } + + energy = player_energy(); + if (energy <= 0 && you.is_undead != US_UNDEAD) + { + food -= 10 * you.skills[SK_EVOCATIONS]; + if (food < diff * 5) + food = diff * 5; + + make_hungry( food, true ); + } - dec_mp(spell_mana(specspell)); + you.wield_change = true; you.turn_is_over = 1; diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc index 6044904dc0..35cff2da38 100644 --- a/crawl-ref/source/spl-cast.cc +++ b/crawl-ref/source/spl-cast.cc @@ -230,7 +230,7 @@ int spell_fail(int spell) int chance = 60; int chance2 = 0, armour = 0; - chance -= 6 * calc_spell_power( spell, false ); + chance -= 6 * calc_spell_power( spell, false, true ); chance -= (you.intel * 2); //chance -= (you.intel - 10) * abs(you.intel - 10); @@ -423,7 +423,7 @@ int spell_fail(int spell) } // end spell_fail() -int calc_spell_power( int spell, bool apply_intel ) +int calc_spell_power( int spell, bool apply_intel, bool fail_rate_check ) { unsigned int bit; int ndx; @@ -453,7 +453,10 @@ int calc_spell_power( int spell, bool apply_intel ) if (apply_intel) power = (power * you.intel) / 10; - enhanced = spell_enhancement( disciplines ); + // [dshaligram] Enhancers don't affect fail rates any more, only spell + // power. Note that this does not affect Vehumet's boost in castability. + if (!fail_rate_check) + enhanced = spell_enhancement( disciplines ); if (enhanced > 0) { @@ -634,12 +637,25 @@ bool cast_a_spell(void) else { exercise_spell( spell, true, your_spells( spell ) ); - naughty( NAUGHTY_SPELLCASTING, 1 + random2(5) ); + did_god_conduct( DID_SPELL_CASTING, 1 + random2(5) ); } return (true); } // end cast_a_spell() +// "Utility" spells for the sake of simplicity are currently ones with +// enchantments, translocations, or divinations. +bool spell_is_utility_spell( int spell_id ) +{ + return (spell_typematch( spell_id, + SPTYP_ENCHANTMENT | SPTYP_TRANSLOCATION | SPTYP_DIVINATION )); +} + +bool spell_is_unholy( int spell_id ) +{ + return (testbits( get_spell_flags( spell_id ), SPFLAG_UNHOLY )); +} + // returns true if spell if spell is successfully cast for purposes of // exercising and false otherwise (note: false == less exercise, not none). bool your_spells( int spc2, int powc, bool allow_fail ) @@ -740,17 +756,17 @@ bool your_spells( int spc2, int powc, bool allow_fail ) int spfl = random2avg(100, 3); if (you.religion != GOD_SIF_MUNA - && you.penance[GOD_SIF_MUNA] && one_chance_in(40)) + && you.penance[GOD_SIF_MUNA] && one_chance_in(20)) { god_speaks(GOD_SIF_MUNA, "You feel a surge of divine spite."); // This will cause failure and increase the miscast effect. spfl = -you.penance[GOD_SIF_MUNA]; - // Reduced penenance reduction here because casting spells + // Reduced penance reduction here because casting spells // is a player controllable act. -- bwr - if (one_chance_in(7)) - dec_penance(1); + if (one_chance_in(12)) + dec_penance(GOD_SIF_MUNA, 1); } if (spfl < spell_fail(spc2)) @@ -813,41 +829,45 @@ bool your_spells( int spc2, int powc, bool allow_fail ) return (false); // XXX: still gets trained! } + if (!spell_is_utility_spell(spc2)) + did_god_conduct( DID_SPELL_NONUTILITY, 10 + spell_difficulty(spc2) ); + + if (spell_is_unholy( spc2 )) + did_god_conduct( DID_UNHOLY, 10 + spell_difficulty(spc2) ); + // Linley says: Condensation Shield needs some disadvantages to keep // it from being a no-brainer... this isn't much, but its a start -- bwr if (you.duration[DUR_CONDENSATION_SHIELD] > 0 && spell_typematch( spc2, SPTYP_FIRE )) { + // TODO: Pull in Brent's expose_player_to_element fn. mpr( "Your icy shield dissipates!", MSGCH_DURATION ); you.duration[DUR_CONDENSATION_SHIELD] = 0; you.redraw_armour_class = 1; } - if (spc2 == SPELL_SUMMON_HORRIBLE_THINGS - || spc2 == SPELL_CALL_IMP - || spc2 == SPELL_SUMMON_DEMON - || spc2 == SPELL_DEMONIC_HORDE - || spc2 == SPELL_SUMMON_GREATER_DEMON || spc2 == SPELL_HELLFIRE) - { - naughty(NAUGHTY_UNHOLY, 10 + spell_difficulty(spc2)); - } - if (spell_typematch( spc2, SPTYP_NECROMANCY )) - naughty( NAUGHTY_NECROMANCY, 10 + spell_difficulty(spc2) ); - - if (spc2 == SPELL_NECROMUTATION - && (you.religion == GOD_ELYVILON - || you.religion == GOD_SHINING_ONE - || you.religion == GOD_ZIN)) { - excommunication(); + did_god_conduct( DID_NECROMANCY, 10 + spell_difficulty(spc2) ); + + if (spc2 == SPELL_NECROMUTATION + && (you.religion == GOD_ELYVILON + || you.religion == GOD_SHINING_ONE + || you.religion == GOD_ZIN)) + { + excommunication(); + } } + // [dshaligram] Sif Muna piety now increases only when training spell skills + // as per bwr 4.1. + /* if (you.religion == GOD_SIF_MUNA && you.piety < 200 && random2(12) <= spell_difficulty(spc2)) { gain_piety(1); } + */ #if DEBUG_DIAGNOSTICS snprintf( info, INFO_SIZE, "Spell #%d, power=%d", spc2, powc ); @@ -871,7 +891,7 @@ bool your_spells( int spc2, int powc, bool allow_fail ) case SPELL_CREATE_NOISE: // unused, the player can shout to do this - bwr if (!silenced(you.x_pos, you.y_pos)) { - mpr("You hear a voice call your name!"); + mpr("You hear a voice call your name!", MSGCH_SOUND); noisy( 25, you.x_pos, you.y_pos ); } break; @@ -1863,6 +1883,10 @@ bool your_spells( int spc2, int powc, bool allow_fail ) cast_conjure_ball_lightning(powc); break; + case SPELL_CHAIN_LIGHTNING: + cast_chain_lightning(powc); + break; + case SPELL_TWIST: cast_twist(powc); break; @@ -1892,6 +1916,7 @@ void exercise_spell( int spell, bool spc, bool success ) // (!success) reduces skill increase for miscast spells int ndx = 0; int skill; + int exer = 0; int workout = 0; unsigned int disciplines = spell_type(spell); @@ -1904,18 +1929,19 @@ void exercise_spell( int spell, bool spc, bool success ) if (!success) skillcount += 4 + random2(10); + const int diff = spell_difficulty(spell); for (ndx = 0; ndx <= SPTYP_LAST_EXPONENT; ndx++) { if (!spell_typematch( spell, 1 << ndx )) continue; skill = spell_type2skill( 1 << ndx ); - workout = (random2(1 + spell_difficulty(spell)) / skillcount); + workout = (random2(1 + diff) / skillcount); if (!one_chance_in(5)) workout++; // most recently, this was an automatic add {dlb} - exercise( skill, workout ); + exer += exercise( skill, workout ); } /* ****************************************************************** @@ -1932,21 +1958,12 @@ void exercise_spell( int spell, bool spc, bool success ) if (spc) { - exercise(SK_SPELLCASTING, one_chance_in(3) ? 1 - : random2(1 + random2(spell_difficulty(spell)))); + exer += exercise(SK_SPELLCASTING, one_chance_in(3) ? 1 + : random2(1 + random2(diff))); } - //+ (coinflip() ? 1 : 0) + (skillcount ? 1 : 0)); - -/* ****************************************************************** - 3.02 was: - - if ( spc && spellsy ) - exercise(SK_SPELLCASTING, random2(random2(spell_difficulty(spell_ex) + 1) / spellsy)); // + 1); - else if ( spc ) - exercise(SK_SPELLCASTING, random2(random2(spell_difficulty(spell_ex)))); // + 1); -****************************************************************** */ - + if (exer) + did_god_conduct( DID_SPELL_PRACTISE, exer ); } // end exercise_spell() static bool send_abyss() @@ -2185,7 +2202,7 @@ bool miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail, break; case 9: if (!silenced(you.x_pos, you.y_pos)) - mpr("You hear something strange."); + mpr("You hear something strange.", MSGCH_SOUND); else if (you.attribute[ATTR_TRANSFORMATION] != TRAN_AIR) mpr("Your skull vibrates slightly."); else @@ -2391,7 +2408,7 @@ bool miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail, break; case 1: if (!silenced(you.x_pos, you.y_pos)) - mpr("You hear strange voices."); + mpr("You hear strange voices.", MSGCH_SOUND); else mpr("You feel momentarily dizzy."); break; @@ -2560,7 +2577,7 @@ bool miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail, break; case 1: if (!silenced(you.x_pos, you.y_pos)) - mpr("You hear strange voices."); + mpr("You hear strange voices.", MSGCH_SOUND); else mpr("Your nose twitches."); break; @@ -2671,7 +2688,7 @@ bool miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail, break; case 1: if (!silenced(you.x_pos, you.y_pos)) - mpr("You hear strange and distant voices."); + mpr("You hear strange and distant voices.", MSGCH_SOUND); else mpr("You feel homesick."); break; @@ -2974,7 +2991,7 @@ bool miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail, break; case 9: if (!silenced(you.x_pos, you.y_pos)) - mpr("You hear a sizzling sound."); + mpr("You hear a sizzling sound.", MSGCH_SOUND); else mpr("You feel like you have heartburn."); break; @@ -3114,7 +3131,7 @@ bool miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail, break; case 9: if (!silenced(you.x_pos, you.y_pos)) - mpr("You hear a crackling sound."); + mpr("You hear a crackling sound.", MSGCH_SOUND); else mpr("A snowflake lands on your nose."); break; @@ -3216,7 +3233,7 @@ bool miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail, break; case 4: if (!silenced(you.x_pos, you.y_pos)) - mpr("You hear a distant rumble."); + mpr("You hear a distant rumble.", MSGCH_SOUND); else mpr("You sympathise with the stones."); break; @@ -3333,7 +3350,7 @@ bool miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail, case 7: // mummies cannot smell if (!silenced(you.x_pos, you.y_pos)) - mpr("You hear a whooshing sound."); + mpr("You hear a whooshing sound.", MSGCH_SOUND); else if (you.species != SP_MUMMY) mpr("You smell ozone."); break; @@ -3343,7 +3360,7 @@ bool miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail, case 9: // mummies cannot smell if (!silenced(you.x_pos, you.y_pos)) - mpr("You hear a crackling sound."); + mpr("You hear a crackling sound.", MSGCH_SOUND); else if (you.species != SP_MUMMY) mpr("You smell something musty."); break; @@ -3453,7 +3470,7 @@ bool miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail, break; case 9: if (!silenced(you.x_pos, you.y_pos)) - mpr("You hear a slurping sound."); + mpr("You hear a slurping sound.", MSGCH_SOUND); else if (you.species != SP_MUMMY) mpr("You taste almonds."); break; diff --git a/crawl-ref/source/spl-cast.h b/crawl-ref/source/spl-cast.h index f517a5ff3f..f04efa7332 100644 --- a/crawl-ref/source/spl-cast.h +++ b/crawl-ref/source/spl-cast.h @@ -14,7 +14,7 @@ char list_spells( void ); int spell_fail( int spell ); -int calc_spell_power( int spell, bool apply_intel ); +int calc_spell_power( int spell, bool apply_intel, bool fail_rate_chk = false ); int spell_enhancement( unsigned int typeflags ); // last updaetd 12may2000 {dlb} diff --git a/crawl-ref/source/spl-data.h b/crawl-ref/source/spl-data.h index aee5e09bc0..b016ecb552 100644 --- a/crawl-ref/source/spl-data.h +++ b/crawl-ref/source/spl-data.h @@ -135,114 +135,133 @@ { SPELL_IDENTIFY, "Identify", SPTYP_DIVINATION, + SPFLAG_NONE, 6 }, { SPELL_TELEPORT_SELF, "Teleport Self", SPTYP_TRANSLOCATION, + SPFLAG_NONE, 5 }, { SPELL_CAUSE_FEAR, "Cause Fear", SPTYP_ENCHANTMENT, + SPFLAG_NONE, 5 }, { SPELL_CREATE_NOISE, "Create Noise", SPTYP_ENCHANTMENT, + SPFLAG_NONE, 1 }, { SPELL_REMOVE_CURSE, "Remove Curse", SPTYP_ENCHANTMENT, + SPFLAG_NONE, 5 }, { SPELL_MAGIC_DART, "Magic Dart", SPTYP_CONJURATION, + SPFLAG_DIR_OR_TARGET, 1 }, { SPELL_FIREBALL, "Fireball", SPTYP_CONJURATION | SPTYP_FIRE, + SPFLAG_DIR_OR_TARGET, 6 }, { SPELL_SWAP, "Swap", SPTYP_TRANSLOCATION, - 3 + SPFLAG_NONE, + 4 }, { SPELL_APPORTATION, "Apportation", SPTYP_TRANSLOCATION, + SPFLAG_NONE, 1 }, { SPELL_TWIST, "Twist", SPTYP_TRANSLOCATION, + SPFLAG_DIR_OR_TARGET, 1 }, { SPELL_CONJURE_FLAME, "Conjure Flame", SPTYP_CONJURATION | SPTYP_FIRE, + SPFLAG_GRID | SPFLAG_NOT_SELF, 3 }, { SPELL_DIG, "Dig", SPTYP_TRANSMIGRATION | SPTYP_EARTH, + SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF, 4 }, { SPELL_BOLT_OF_FIRE, "Bolt of Fire", SPTYP_CONJURATION | SPTYP_FIRE, + SPFLAG_DIR_OR_TARGET, 5 }, { SPELL_BOLT_OF_COLD, "Bolt of Cold", SPTYP_CONJURATION | SPTYP_ICE, + SPFLAG_DIR_OR_TARGET, 5 }, { SPELL_LIGHTNING_BOLT, "Lightning Bolt", SPTYP_CONJURATION | SPTYP_AIR, + SPFLAG_DIR_OR_TARGET, 6 }, { SPELL_BOLT_OF_MAGMA, "Bolt of Magma", SPTYP_CONJURATION | SPTYP_FIRE | SPTYP_EARTH, + SPFLAG_DIR_OR_TARGET, 5 }, { SPELL_POLYMORPH_OTHER, "Polymorph Other", SPTYP_TRANSMIGRATION, // removed enchantment, wasn't needed -- bwr + SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF, 5 }, { SPELL_SLOW, "Slow", SPTYP_ENCHANTMENT, + SPFLAG_DIR_OR_TARGET, 3 }, { SPELL_HASTE, "Haste", SPTYP_ENCHANTMENT, + SPFLAG_DIR_OR_TARGET | SPFLAG_HELPFUL, 6 // lowered to 6 from 8, since its easily available from various items // and Swiftness is level 2 (and gives a similar effect). Its also // not that much better than Invisibility. -- bwr @@ -251,204 +270,238 @@ { SPELL_PARALYZE, "Paralyze", SPTYP_ENCHANTMENT, + SPFLAG_DIR_OR_TARGET, 4 }, { SPELL_CONFUSE, "Confuse", SPTYP_ENCHANTMENT, + SPFLAG_DIR_OR_TARGET, 3 }, { SPELL_INVISIBILITY, "Invisibility", SPTYP_ENCHANTMENT, + SPFLAG_DIR_OR_TARGET | SPFLAG_HELPFUL, 6 }, { SPELL_THROW_FLAME, "Throw Flame", SPTYP_CONJURATION | SPTYP_FIRE, + SPFLAG_DIR_OR_TARGET, 2 }, { SPELL_THROW_FROST, "Throw Frost", SPTYP_CONJURATION | SPTYP_ICE, + SPFLAG_DIR_OR_TARGET, 2 }, { SPELL_CONTROLLED_BLINK, "Controlled Blink", SPTYP_TRANSLOCATION, - 4 + SPFLAG_NONE, + 8 }, { SPELL_FREEZING_CLOUD, "Freezing Cloud", SPTYP_CONJURATION | SPTYP_ICE | SPTYP_AIR, + SPFLAG_GRID, 7 }, { SPELL_MEPHITIC_CLOUD, "Mephitic Cloud", SPTYP_CONJURATION | SPTYP_POISON | SPTYP_AIR, + SPFLAG_DIR_OR_TARGET, 3 }, { SPELL_RING_OF_FLAMES, "Ring of Flames", SPTYP_ENCHANTMENT | SPTYP_FIRE, + SPFLAG_NONE, 8 }, { SPELL_RESTORE_STRENGTH, "Restore Strength", SPTYP_HOLY, + SPFLAG_NONE, 2 }, { SPELL_RESTORE_INTELLIGENCE, "Restore Intelligence", SPTYP_HOLY, + SPFLAG_NONE, 2 }, { SPELL_RESTORE_DEXTERITY, "Restore Dexterity", SPTYP_HOLY, + SPFLAG_NONE, 2 }, { SPELL_VENOM_BOLT, "Venom Bolt", SPTYP_CONJURATION | SPTYP_POISON, + SPFLAG_DIR_OR_TARGET, 5 }, { SPELL_OLGREBS_TOXIC_RADIANCE, "Olgreb's Toxic Radiance", SPTYP_POISON, + SPFLAG_NONE, 4 }, { SPELL_TELEPORT_OTHER, "Teleport Other", SPTYP_TRANSLOCATION, + SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF, 4 }, { SPELL_LESSER_HEALING, "Lesser Healing", SPTYP_HOLY, + SPFLAG_NONE, 2 }, { SPELL_GREATER_HEALING, "Greater Healing", SPTYP_HOLY, + SPFLAG_NONE, 6 }, { SPELL_CURE_POISON_I, "Cure Poison", SPTYP_HOLY, + SPFLAG_NONE, 3 }, { SPELL_PURIFICATION, "Purification", SPTYP_HOLY, + SPFLAG_NONE, 5 }, { SPELL_DEATHS_DOOR, "Death's Door", SPTYP_ENCHANTMENT | SPTYP_NECROMANCY, + SPFLAG_NONE, 8 }, { SPELL_SELECTIVE_AMNESIA, "Selective Amnesia", SPTYP_ENCHANTMENT, + SPFLAG_NONE, 3 }, { SPELL_MASS_CONFUSION, "Mass Confusion", SPTYP_ENCHANTMENT, + SPFLAG_NONE, 6 }, { SPELL_SMITING, "Smiting", SPTYP_HOLY, + SPFLAG_NONE, 4 }, { SPELL_REPEL_UNDEAD, "Repel Undead", SPTYP_HOLY, + SPFLAG_NONE, 3 }, { SPELL_HOLY_WORD, "Holy Word", SPTYP_HOLY, + SPFLAG_NONE, 7 }, { SPELL_DETECT_CURSE, "Detect Curse", SPTYP_DIVINATION, + SPFLAG_NONE, 3 }, { SPELL_SUMMON_SMALL_MAMMAL, "Summon Small Mammals", SPTYP_SUMMONING, + SPFLAG_NONE, 1 }, { SPELL_ABJURATION_I, "Abjuration", SPTYP_SUMMONING, + SPFLAG_NONE, 3 }, { SPELL_SUMMON_SCORPIONS, "Summon Scorpions", SPTYP_SUMMONING | SPTYP_POISON, + SPFLAG_NONE, 4 }, { SPELL_LEVITATION, "Levitation", SPTYP_ENCHANTMENT | SPTYP_AIR, + SPFLAG_NONE, 2 }, { SPELL_BOLT_OF_DRAINING, "Bolt of Draining", SPTYP_CONJURATION | SPTYP_NECROMANCY, + SPFLAG_DIR_OR_TARGET, 6 }, { SPELL_LEHUDIBS_CRYSTAL_SPEAR, "Lehudib's Crystal Spear", SPTYP_CONJURATION | SPTYP_EARTH, + SPFLAG_DIR_OR_TARGET, 8 }, { SPELL_BOLT_OF_INACCURACY, "Bolt of Inaccuracy", SPTYP_CONJURATION, + SPFLAG_DIR_OR_TARGET, 2 }, { SPELL_POISONOUS_CLOUD, "Poisonous Cloud", SPTYP_CONJURATION | SPTYP_POISON | SPTYP_AIR, + SPFLAG_GRID, 6 } , @@ -456,18 +509,21 @@ { SPELL_FIRE_STORM, "Fire Storm", SPTYP_CONJURATION | SPTYP_FIRE, + SPFLAG_GRID, 9 }, { SPELL_DETECT_TRAPS, "Detect Traps", SPTYP_DIVINATION, + SPFLAG_NONE, 2 }, { SPELL_BLINK, "Blink", SPTYP_TRANSLOCATION, + SPFLAG_NONE, 2 }, @@ -477,174 +533,203 @@ { SPELL_ISKENDERUNS_MYSTIC_BLAST, "Iskenderun's Mystic Blast", SPTYP_CONJURATION, + SPFLAG_DIR_OR_TARGET, 4 }, { SPELL_SWARM, "Summon Swarm", SPTYP_SUMMONING, + SPFLAG_NONE, 6 }, { SPELL_SUMMON_HORRIBLE_THINGS, "Summon Horrible Things", SPTYP_SUMMONING, + SPFLAG_UNHOLY, 8 }, { SPELL_ENSLAVEMENT, "Enslavement", SPTYP_ENCHANTMENT, + SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF, 4 }, { SPELL_MAGIC_MAPPING, "Magic Mapping", SPTYP_DIVINATION | SPTYP_EARTH, + SPFLAG_NONE, 4 }, { SPELL_HEAL_OTHER, "Heal Other", SPTYP_HOLY, + SPFLAG_DIR_OR_TARGET | SPFLAG_HELPFUL | SPFLAG_NOT_SELF, 3 }, { SPELL_ANIMATE_DEAD, "Animate Dead", SPTYP_NECROMANCY, + SPFLAG_NONE, 4 }, { SPELL_PAIN, "Pain", SPTYP_NECROMANCY, + SPFLAG_DIR_OR_TARGET, 1 }, { SPELL_EXTENSION, "Extension", SPTYP_ENCHANTMENT, + SPFLAG_NONE, 5 }, { SPELL_CONTROL_UNDEAD, "Control Undead", SPTYP_ENCHANTMENT | SPTYP_NECROMANCY, + SPFLAG_NONE, 6 }, { SPELL_ANIMATE_SKELETON, "Animate Skeleton", SPTYP_NECROMANCY, + SPFLAG_NONE, 1 }, { SPELL_VAMPIRIC_DRAINING, "Vampiric Draining", SPTYP_NECROMANCY, + SPFLAG_DIR | SPFLAG_NOT_SELF, 3 }, { SPELL_SUMMON_WRAITHS, "Summon Wraiths", SPTYP_NECROMANCY | SPTYP_SUMMONING, + SPFLAG_NONE, 7 }, { SPELL_DETECT_ITEMS, "Detect Items", SPTYP_DIVINATION, + SPFLAG_NONE, 2 }, { SPELL_BORGNJORS_REVIVIFICATION, "Borgnjor's Revivification", SPTYP_NECROMANCY, - 6 + SPFLAG_NONE, + 5 }, { SPELL_BURN, "Burn", // used by wanderers SPTYP_FIRE, + SPFLAG_DIR | SPFLAG_NOT_SELF, 1 }, { SPELL_FREEZE, "Freeze", SPTYP_ICE, + SPFLAG_DIR | SPFLAG_NOT_SELF, 1 }, { SPELL_SUMMON_ELEMENTAL, "Summon Elemental", SPTYP_SUMMONING, + SPFLAG_NONE, 4 }, { SPELL_OZOCUBUS_REFRIGERATION, "Ozocubu's Refrigeration", SPTYP_ICE, + SPFLAG_NONE, 5 }, { SPELL_STICKY_FLAME, "Sticky Flame", SPTYP_CONJURATION | SPTYP_FIRE, + SPFLAG_DIR_OR_TARGET, 4 }, { SPELL_SUMMON_ICE_BEAST, "Summon Ice Beast", SPTYP_ICE | SPTYP_SUMMONING, + SPFLAG_NONE, 5 }, { SPELL_OZOCUBUS_ARMOUR, "Ozocubu's Armour", SPTYP_ENCHANTMENT | SPTYP_ICE, + SPFLAG_NONE, 3 }, { SPELL_CALL_IMP, "Call Imp", SPTYP_SUMMONING, + SPFLAG_UNHOLY, 3 }, { SPELL_REPEL_MISSILES, "Repel Missiles", SPTYP_ENCHANTMENT | SPTYP_AIR, + SPFLAG_NONE, 2 }, { SPELL_BERSERKER_RAGE, "Berserker Rage", SPTYP_ENCHANTMENT, + SPFLAG_NONE, 3 }, { SPELL_DISPEL_UNDEAD, "Dispel Undead", SPTYP_NECROMANCY, + SPFLAG_DIR_OR_TARGET, 4 }, { SPELL_GUARDIAN, "Guardian", SPTYP_HOLY, + SPFLAG_NONE, 7 }, { SPELL_PESTILENCE, "Pestilence", SPTYP_HOLY, + SPFLAG_NONE, 4 }, { SPELL_THUNDERBOLT, "Thunderbolt", SPTYP_HOLY | SPTYP_AIR, + SPFLAG_DIR_OR_TARGET, 6 // why is this the only holy spell with a secondary? {dlb} } , @@ -652,150 +737,175 @@ { SPELL_FLAME_OF_CLEANSING, "Flame of Cleansing", SPTYP_HOLY, + SPFLAG_DIR_OR_TARGET, 8 }, { SPELL_SHINING_LIGHT, "Shining Light", SPTYP_HOLY, + SPFLAG_NONE, 7 }, { SPELL_SUMMON_DAEVA, "Summon Daeva", SPTYP_HOLY, + SPFLAG_NONE, 8 }, { SPELL_ABJURATION_II, "Abjuration", SPTYP_HOLY, + SPFLAG_NONE, 4 }, { SPELL_TWISTED_RESURRECTION, "Twisted Resurrection", SPTYP_NECROMANCY, + SPFLAG_NONE, 5 }, { SPELL_REGENERATION, "Regeneration", SPTYP_ENCHANTMENT | SPTYP_NECROMANCY, + SPFLAG_NONE, 3 }, { SPELL_BONE_SHARDS, "Bone Shards", SPTYP_NECROMANCY, + SPFLAG_NONE, 3 }, { SPELL_BANISHMENT, "Banishment", SPTYP_TRANSLOCATION, + SPFLAG_DIR_OR_TARGET | SPFLAG_UNHOLY, 5 }, { SPELL_CIGOTUVIS_DEGENERATION, "Cigotuvi's Degeneration", SPTYP_TRANSMIGRATION | SPTYP_NECROMANCY, + SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF, 5 }, { SPELL_STING, "Sting", SPTYP_CONJURATION | SPTYP_POISON, + SPFLAG_DIR_OR_TARGET, 1 }, { SPELL_SUBLIMATION_OF_BLOOD, "Sublimation of Blood", SPTYP_NECROMANCY, + SPFLAG_NONE, 2 }, { SPELL_TUKIMAS_DANCE, "Tukima's Dance", SPTYP_ENCHANTMENT, + SPFLAG_NONE, 3 }, { SPELL_HELLFIRE, "Hellfire", SPTYP_CONJURATION | SPTYP_FIRE, + SPFLAG_DIR_OR_TARGET | SPFLAG_UNHOLY, 9 }, { SPELL_SUMMON_DEMON, "Summon Demon", SPTYP_SUMMONING, + SPFLAG_UNHOLY, 5 }, { SPELL_DEMONIC_HORDE, "Demonic Horde", SPTYP_SUMMONING, + SPFLAG_UNHOLY, 6 }, { SPELL_SUMMON_GREATER_DEMON, "Summon Greater Demon", SPTYP_SUMMONING, + SPFLAG_UNHOLY, 7 }, { SPELL_CORPSE_ROT, "Corpse Rot", SPTYP_NECROMANCY, + SPFLAG_NONE, 2 }, { SPELL_TUKIMAS_VORPAL_BLADE, "Tukima's Vorpal Blade", SPTYP_ENCHANTMENT, + SPFLAG_NONE, 2 }, { SPELL_FIRE_BRAND, "Fire Brand", SPTYP_ENCHANTMENT | SPTYP_FIRE, + SPFLAG_NONE, 2 }, { SPELL_FREEZING_AURA, "Freezing Aura", SPTYP_ENCHANTMENT | SPTYP_ICE, + SPFLAG_NONE, 2 }, { SPELL_LETHAL_INFUSION, "Lethal Infusion", SPTYP_ENCHANTMENT | SPTYP_NECROMANCY, + SPFLAG_NONE, 2 }, { - SPELL_CRUSH, "Crush", // used by wanderers + SPELL_CRUSH, "Crush", SPTYP_EARTH, + SPFLAG_DIR | SPFLAG_NOT_SELF, 1 }, { SPELL_BOLT_OF_IRON, "Bolt of Iron", SPTYP_CONJURATION | SPTYP_EARTH, + SPFLAG_DIR_OR_TARGET, 6 }, { SPELL_STONE_ARROW, "Stone Arrow", SPTYP_CONJURATION | SPTYP_EARTH, + SPFLAG_DIR_OR_TARGET, 3 }, { SPELL_TOMB_OF_DOROKLOHE, "Tomb of Doroklohe", SPTYP_CONJURATION | SPTYP_EARTH, // conj makes more sense than tmig -- bwr + SPFLAG_NONE, 7 } , @@ -803,48 +913,56 @@ { SPELL_STONEMAIL, "Stonemail", SPTYP_ENCHANTMENT | SPTYP_EARTH, + SPFLAG_NONE, 6 }, { SPELL_SHOCK, "Shock", SPTYP_CONJURATION | SPTYP_AIR, + SPFLAG_DIR_OR_TARGET, 1 }, { SPELL_SWIFTNESS, "Swiftness", SPTYP_ENCHANTMENT | SPTYP_AIR, + SPFLAG_NONE, 2 }, { SPELL_FLY, "Fly", SPTYP_ENCHANTMENT | SPTYP_AIR, + SPFLAG_NONE, 4 }, { SPELL_INSULATION, "Insulation", SPTYP_ENCHANTMENT | SPTYP_AIR, + SPFLAG_NONE, 4 }, { SPELL_ORB_OF_ELECTROCUTION, "Orb of Electrocution", SPTYP_CONJURATION | SPTYP_AIR, + SPFLAG_DIR_OR_TARGET, 7 }, { SPELL_DETECT_CREATURES, "Detect Creatures", SPTYP_DIVINATION, + SPFLAG_NONE, 2 }, { SPELL_CURE_POISON_II, "Cure Poison", SPTYP_POISON, + SPFLAG_NONE, 2 } , @@ -852,12 +970,14 @@ { SPELL_CONTROL_TELEPORT, "Control Teleport", SPTYP_ENCHANTMENT | SPTYP_TRANSLOCATION, - 6 + SPFLAG_NONE, + 5 }, { SPELL_POISON_AMMUNITION, "Poison Ammunition", SPTYP_ENCHANTMENT | SPTYP_POISON, + SPFLAG_NONE, 4 // jmf: SPTYP_TRANSMIGRATION vs SPTYP_ENCHANTMENT? } , @@ -865,150 +985,175 @@ { SPELL_POISON_WEAPON, "Poison Weapon", SPTYP_ENCHANTMENT | SPTYP_POISON, + SPFLAG_NONE, 4 }, { SPELL_RESIST_POISON, "Resist Poison", SPTYP_ENCHANTMENT | SPTYP_POISON, + SPFLAG_NONE, 4 }, { SPELL_PROJECTED_NOISE, "Projected Noise", SPTYP_ENCHANTMENT, + SPFLAG_NONE, 2 }, { SPELL_ALTER_SELF, "Alter Self", SPTYP_TRANSMIGRATION, + SPFLAG_NONE, 7 }, { SPELL_DEBUGGING_RAY, "Debugging Ray", SPTYP_CONJURATION, + SPFLAG_DIR_OR_TARGET, 7 }, { SPELL_RECALL, "Recall", SPTYP_SUMMONING | SPTYP_TRANSLOCATION, + SPFLAG_NONE, 3 }, { SPELL_PORTAL, "Portal", SPTYP_TRANSLOCATION, - 8 + SPFLAG_NONE, + 7 }, { SPELL_AGONY, "Agony", SPTYP_NECROMANCY, + SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF, 5 }, { SPELL_SPIDER_FORM, "Spider Form", SPTYP_TRANSMIGRATION | SPTYP_POISON, + SPFLAG_NONE, 3 }, { SPELL_DISRUPT, "Disrupt", SPTYP_TRANSMIGRATION, + SPFLAG_DIR_OR_TARGET, 1 }, { SPELL_DISINTEGRATE, "Disintegrate", SPTYP_TRANSMIGRATION, + SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF, 6 }, { SPELL_BLADE_HANDS, "Blade Hands", SPTYP_TRANSMIGRATION, + SPFLAG_NONE, 5 // only removes weapon, so I raised this from 4 -- bwr }, { SPELL_STATUE_FORM, "Statue Form", SPTYP_TRANSMIGRATION | SPTYP_EARTH, + SPFLAG_NONE, 6 }, { SPELL_ICE_FORM, "Ice Form", SPTYP_ICE | SPTYP_TRANSMIGRATION, + SPFLAG_NONE, 4 // doesn't allow for equipment, so I lowered this from 5 -- bwr }, { SPELL_DRAGON_FORM, "Dragon Form", SPTYP_FIRE | SPTYP_TRANSMIGRATION, + SPFLAG_NONE, 8 }, { SPELL_NECROMUTATION, "Necromutation", SPTYP_TRANSMIGRATION | SPTYP_NECROMANCY, + SPFLAG_NONE, 8 }, { SPELL_DEATH_CHANNEL, "Death Channel", SPTYP_NECROMANCY, + SPFLAG_NONE, 9 }, { SPELL_SYMBOL_OF_TORMENT, "Symbol of Torment", SPTYP_NECROMANCY, + SPFLAG_NONE, 6 }, { SPELL_DEFLECT_MISSILES, "Deflect Missiles", SPTYP_ENCHANTMENT | SPTYP_AIR, + SPFLAG_NONE, 6 }, { SPELL_ORB_OF_FRAGMENTATION, "Orb of Fragmentation", SPTYP_CONJURATION | SPTYP_EARTH, + SPFLAG_DIR_OR_TARGET, 7 }, { SPELL_ICE_BOLT, "Ice Bolt", SPTYP_CONJURATION | SPTYP_ICE, + SPFLAG_DIR_OR_TARGET, 4 }, { SPELL_ICE_STORM, "Ice Storm", SPTYP_CONJURATION | SPTYP_ICE, + SPFLAG_DIR_OR_TARGET, 9 }, { - SPELL_ARC, "Arc", // used by wanderers + SPELL_ARC, "Arc", SPTYP_AIR, + SPFLAG_DIR | SPFLAG_NOT_SELF, 1 }, { SPELL_AIRSTRIKE, "Airstrike", SPTYP_AIR, + SPFLAG_TARGET | SPFLAG_NOT_SELF, 4 }, { SPELL_SHADOW_CREATURES, "Shadow Creatures", SPTYP_SUMMONING, // jmf: or SPTYP_SUMMONING | SPTYP_CONJURATION + SPFLAG_NONE, 5 } , @@ -1016,12 +1161,14 @@ { SPELL_CONFUSING_TOUCH, "Confusing Touch", SPTYP_ENCHANTMENT, + SPFLAG_NONE, 1 }, { SPELL_SURE_BLADE, "Sure Blade", SPTYP_ENCHANTMENT, + SPFLAG_NONE, 2 }, @@ -1033,246 +1180,280 @@ { SPELL_FLAME_TONGUE, "Flame Tongue", SPTYP_CONJURATION | SPTYP_FIRE, + SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF, 1 }, { SPELL_PASSWALL, "Passwall", SPTYP_TRANSMIGRATION | SPTYP_EARTH, + SPFLAG_NONE, 3 }, { SPELL_IGNITE_POISON, "Ignite Poison", SPTYP_FIRE | SPTYP_TRANSMIGRATION, + SPFLAG_NONE, 7 }, { SPELL_STICKS_TO_SNAKES, "Sticks to Snakes", SPTYP_TRANSMIGRATION | SPTYP_SUMMONING, + SPFLAG_NONE, 2 }, { SPELL_SUMMON_LARGE_MAMMAL, "Call Canine Familiar", SPTYP_SUMMONING, + SPFLAG_NONE, 3 }, { SPELL_SUMMON_DRAGON, "Summon Dragon", SPTYP_FIRE | SPTYP_SUMMONING, + SPFLAG_NONE, 9 }, { SPELL_TAME_BEASTS, "Tame Beasts", SPTYP_ENCHANTMENT, + SPFLAG_NONE, 5 }, { SPELL_SLEEP, "Ensorcelled Hibernation", SPTYP_ENCHANTMENT | SPTYP_ICE, + SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF, 2 }, { SPELL_MASS_SLEEP, "Metabolic Englaciation", SPTYP_ENCHANTMENT | SPTYP_ICE, + SPFLAG_NONE, 7 }, { SPELL_DETECT_MAGIC, "Detect Magic", SPTYP_DIVINATION, + SPFLAG_NONE, 1 }, { SPELL_DETECT_SECRET_DOORS, "Detect Secret Doors", SPTYP_DIVINATION, + SPFLAG_NONE, 1 }, { SPELL_SEE_INVISIBLE, "See Invisible", SPTYP_ENCHANTMENT | SPTYP_DIVINATION, + SPFLAG_NONE, 4 }, { SPELL_FORESCRY, "Forescry", SPTYP_DIVINATION, + SPFLAG_NONE, 5 }, { SPELL_SUMMON_BUTTERFLIES, "Summon Butterflies", SPTYP_SUMMONING, + SPFLAG_NONE, 1 }, { SPELL_WARP_BRAND, "Warp Weapon", SPTYP_ENCHANTMENT | SPTYP_TRANSLOCATION, + SPFLAG_NONE, 7 // this is high for a reason - Warp brands are very powerful. }, { SPELL_SILENCE, "Silence", SPTYP_ENCHANTMENT | SPTYP_AIR, - 3 + SPFLAG_NONE, + 5 }, { SPELL_SHATTER, "Shatter", SPTYP_TRANSMIGRATION | SPTYP_EARTH, + SPFLAG_NONE, 9 }, { SPELL_DISPERSAL, "Dispersal", SPTYP_TRANSLOCATION, + SPFLAG_NONE, 7 }, { SPELL_DISCHARGE, "Static Discharge", SPTYP_CONJURATION | SPTYP_AIR, + SPFLAG_NONE, 4 }, { SPELL_BEND, "Bend", SPTYP_TRANSLOCATION, + SPFLAG_NONE, 1 }, { SPELL_BACKLIGHT, "Corona", SPTYP_ENCHANTMENT, + SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF, 1 }, { SPELL_INTOXICATE, "Alistair's Intoxication", SPTYP_TRANSMIGRATION | SPTYP_POISON, + SPFLAG_NONE, 4 }, { SPELL_GLAMOUR, "Glamour", SPTYP_ENCHANTMENT, + SPFLAG_NONE, 5 }, { SPELL_EVAPORATE, "Evaporate", SPTYP_FIRE | SPTYP_TRANSMIGRATION, + SPFLAG_NONE, 2 // XXX: level 2 or 3, what should it be now? -- bwr }, { SPELL_ERINGYAS_SURPRISING_BOUQUET, "Eringya's Surprising Bouquet", SPTYP_TRANSMIGRATION | SPTYP_EARTH, + SPFLAG_NONE, 4 }, { SPELL_FRAGMENTATION, "Lee's Rapid Deconstruction", SPTYP_TRANSMIGRATION | SPTYP_EARTH, + SPFLAG_NONE, 5 }, { SPELL_AIR_WALK, "Air Walk", SPTYP_TRANSMIGRATION | SPTYP_AIR, + SPFLAG_NONE, 9 }, { SPELL_SANDBLAST, "Sandblast", SPTYP_TRANSMIGRATION | SPTYP_EARTH, + SPFLAG_DIR_OR_TARGET | SPFLAG_NOT_SELF, 1 }, { SPELL_ROTTING, "Rotting", SPTYP_TRANSMIGRATION | SPTYP_NECROMANCY, + SPFLAG_NONE, 5 }, { - SPELL_SHUGGOTH_SEED, "Shuggoth Seed", - SPTYP_NECROMANCY | SPTYP_SUMMONING, - 7 -}, - -{ SPELL_MAXWELLS_SILVER_HAMMER, "Maxwell's Silver Hammer", - SPTYP_ENCHANTMENT | SPTYP_EARTH, + SPTYP_TRANSMIGRATION | SPTYP_EARTH, + SPFLAG_NONE, 2 }, { SPELL_CONDENSATION_SHIELD, "Condensation Shield", SPTYP_ICE | SPTYP_TRANSMIGRATION, + SPFLAG_NONE, 4 }, { SPELL_SEMI_CONTROLLED_BLINK, "Semi-Controlled Blink", SPTYP_TRANSLOCATION, + SPFLAG_NONE, 3 }, { SPELL_STONESKIN, "Stoneskin", SPTYP_EARTH | SPTYP_TRANSMIGRATION, // was ench -- bwr + SPFLAG_NONE, 2 }, { SPELL_SIMULACRUM, "Simulacrum", SPTYP_ICE | SPTYP_NECROMANCY, - 7 + SPFLAG_NONE, + 6 }, { SPELL_CONJURE_BALL_LIGHTNING, "Conjure Ball Lightning", SPTYP_AIR | SPTYP_CONJURATION, + SPFLAG_NONE, 8 }, { - SPELL_FAR_STRIKE, "Far Strike", - SPTYP_TRANSLOCATION, - 3 + SPELL_CHAIN_LIGHTNING, "Chain Lightning", + SPTYP_AIR | SPTYP_CONJURATION, + SPFLAG_NONE, + 8 }, { SPELL_DELAYED_FIREBALL, "Delayed Fireball", SPTYP_FIRE | SPTYP_CONJURATION, + SPFLAG_NONE, 7 }, { SPELL_FULSOME_DISTILLATION, "Fulsome Distillation", SPTYP_TRANSMIGRATION | SPTYP_NECROMANCY, + SPFLAG_NONE, 1 }, { SPELL_POISON_ARROW, "Poison Arrow", SPTYP_CONJURATION | SPTYP_POISON, + SPFLAG_DIR_OR_TARGET, 6 }, { SPELL_STRIKING, "Striking", 0, + SPFLAG_DIR_OR_TARGET, 1 }, @@ -1280,6 +1461,7 @@ SPELL_NO_SPELL, "nonexistent spell", 0, 0, + 0, }, diff --git a/crawl-ref/source/spl-util.cc b/crawl-ref/source/spl-util.cc index 58a9ecb2fe..aebf186999 100644 --- a/crawl-ref/source/spl-util.cc +++ b/crawl-ref/source/spl-util.cc @@ -200,6 +200,11 @@ int spell_levels_required( int which_spell ) return (levels); } +unsigned int get_spell_flags( int which_spell ) +{ + return (seekspell(which_spell)->flags); +} + bool spell_typematch(int which_spell, unsigned int which_discipline) { return (seekspell(which_spell)->disciplines & which_discipline); diff --git a/crawl-ref/source/spl-util.h b/crawl-ref/source/spl-util.h index 848530dbbf..c79268bacb 100644 --- a/crawl-ref/source/spl-util.h +++ b/crawl-ref/source/spl-util.h @@ -20,7 +20,8 @@ struct playerspell { int id; const char *title; - unsigned int disciplines; //jmf: a bitfield + unsigned int disciplines; // bitfield + unsigned int flags; // bitfield unsigned int level; }; @@ -46,6 +47,8 @@ int spell_difficulty(int which_spell); int spell_levels_required(int which_spell); +unsigned int get_spell_flags( int which_spell ); + // * called from: chardump - spell - spl-book - spells0 bool spell_typematch(int which_spell, unsigned int which_discipline); unsigned int spell_type( int which_spell ); //jmf: simplification of above diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc index 3a0a281d34..facdeacc47 100644 --- a/crawl-ref/source/stuff.cc +++ b/crawl-ref/source/stuff.cc @@ -539,6 +539,17 @@ int stepdown_value(int base_value, int stepping, int first_step, } // end stepdown_value() +int skill_bump( int skill ) +{ + return ((you.skills[skill] < 3) ? you.skills[skill] * 2 + : you.skills[skill] + 3); +} + +// Calculates num/den and randomly adds one based on the remainder. +int div_rand_round( int num, int den ) +{ + return (num / den + (random2(den) < num % den)); +} // I got so tired of seeing: ".. && random2(foo) == 0 && .." in the code // that I broke down and wrote this little -- very little -- function. diff --git a/crawl-ref/source/stuff.h b/crawl-ref/source/stuff.h index 72c7d2dcf5..b27ef2e10c 100644 --- a/crawl-ref/source/stuff.h +++ b/crawl-ref/source/stuff.h @@ -17,188 +17,60 @@ #include "externs.h" char *const make_time_string(time_t abs_time, char *const buff, int buff_size, bool terse = false); - void set_redraw_status( unsigned long flags ); - void tag_followers( void ); void untag_followers( void ); void seed_rng(void); - void seed_rng(long seed); - void push_rng_state(); - void pop_rng_state(); -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: acr - * *********************************************************************** */ void cf_setseed(void); - - -/* *********************************************************************** - * called from: xxx - * *********************************************************************** */ bool coinflip(void); - - -/* *********************************************************************** - * called from: xxx - * *********************************************************************** */ +int div_rand_round( int num, int den ); bool one_chance_in(int a_million); - - -/* *********************************************************************** - * called from: xxx - * *********************************************************************** */ int random2(int randmax); - unsigned long random_int(void); - -/* *********************************************************************** - * called from: xxx - * *********************************************************************** */ int random2avg( int max, int rolls ); int roll_dice( int num, int size ); int roll_dice( const struct dice_def &dice ); -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: beam - fight - misc - * *********************************************************************** */ int random2limit(int max, int limit); - - -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: bang - beam - monplace - monstuff - spells1 - spells2 - - * spells4 - view - * *********************************************************************** */ bool see_grid(unsigned char grx, unsigned char gry); - - -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: spells2 - * *********************************************************************** */ int stepdown_value(int base_value, int stepping, int first_step, int last_step, int ceiling_value); - - -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: ability - command - effects - food - item_use - items - - * newgame - ouch - shopping - spell - spl-book - spells1 - - * spells3 - * *********************************************************************** */ +int skill_bump( int skill ); unsigned char get_ch(void); - -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: files - newgame - ouch - * *********************************************************************** */ void end(int end_arg); - -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: newgame - * *********************************************************************** */ void modify_all_stats(int STmod, int IQmod, int DXmod); - -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: ability - acr - command - direct - invent - item_use - - * religion - shopping - spell - spl-book - spells3 - * *********************************************************************** */ void redraw_screen(void); - -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: ability - acr - beam - command - decks - debug - effects - - * it_use3 - item_use - items - misc - ouch - religion - - * spell - spl-book - spells - spells1 - spells2 - spells3 - - * spells4 - * *********************************************************************** */ void canned_msg(unsigned char which_message); - -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: ability - acr - command - it_use3 - item_use - items - - * misc - ouch - religion - spl-book - spells4 - * *********************************************************************** */ -// If safeanswer is nonzero, it should be a lowercase letter. bool yesno( const char * str, bool safe = true, int safeanswer = 0, bool clear_after = true ); - -// last updated 21may2000 {dlb} -/* *********************************************************************** - * called from: fight - monstuff - spells4 - view - * *********************************************************************** */ int grid_distance( int x, int y, int x2, int y2 ); int distance( int x, int y, int x2, int y2); bool adjacent( int x, int y, int x2, int y2 ); - -// last updated 21may2000 {dlb} -/* *********************************************************************** - * called from: ability - acr - bang - beam - effects - fight - it_use2 - - * it_use3 - monstuff - mstuff2 - religion - spell - spells - - * spells3 - spells4 - stuff - view - * *********************************************************************** */ bool silenced(char x, char y); - -// last updated XXmay2000 {dlb} -/* *********************************************************************** - * called from: xxx - * *********************************************************************** */ bool player_can_hear(char x, char y); - -// last updated 27may2000 {dlb} -/* *********************************************************************** - * called from: dungeon - files - it_use2 - it_use3 - monstuff - mon-util - - * mstuff2 - newgame - spells - view - * *********************************************************************** */ unsigned char random_colour(void); - -// last updated 08jun2000 {dlb} -/* *********************************************************************** - * called from: ability - chardump - command - files - invent - item_use - - * items - newgame - spl-book - spells0 - spells1 - * *********************************************************************** */ char index_to_letter (int the_index); - -// last updated 08jun2000 {dlb} -/* *********************************************************************** - * called from: ability - command - food - it_use3 - item_use - items - - * spell - spl-book - spells1 - spells3 - * *********************************************************************** */ int letter_to_index(int the_letter); - -// last updated 16mar2001 {dlb} -/* *********************************************************************** - * called from: monplace - * *********************************************************************** */ int near_stairs(int px, int py, int max_dist, unsigned char &stair_gfx); -// last updated 16mar2001 {dlb} -/* *********************************************************************** - * called from: fight - * *********************************************************************** */ -// just want to do this in a consistent fashion inline bool testbits(unsigned int flags, unsigned int test) { return ((flags & test) == test); diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index 1aa6752a6b..b115cbf6fe 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -687,6 +687,10 @@ static void tag_construct_you(struct tagHeader &th) for (i = 0; i < MAX_NUM_GODS; i++) marshallByte(th, you.worshipped[i]); + // what is the extent of divine generosity? + for (i = 0; i < MAX_NUM_GODS; i++) + marshallShort(th, you.num_gifts[i]); + marshallByte(th, you.gift_timeout); marshallByte(th, you.normal_vision); marshallByte(th, you.current_vision); @@ -981,6 +985,11 @@ static void tag_read_you(struct tagHeader &th, char minorVersion) count_c = unmarshallByte(th); for (i = 0; i < count_c; i++) you.worshipped[i] = unmarshallByte(th); + + if (minorVersion >= 5) + for (i = 0; i < count_c; i++) + you.num_gifts[i] = unmarshallShort(th); + } else { diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc index f9c3d2d3d7..6d8347f8dc 100644 --- a/crawl-ref/source/travel.cc +++ b/crawl-ref/source/travel.cc @@ -400,7 +400,7 @@ static bool is_travel_ok(int x, int y, bool ignore_hostile) // the information we're giving the player for free. // Navigate around plants and fungi. Yet another tasty hack. if (player_monster_visible(&menv[mon]) && - mons_flag( menv[mon].type, M_NO_EXP_GAIN )) + mons_class_flag( menv[mon].type, M_NO_EXP_GAIN )) { extern short point_distance[GXM][GYM]; @@ -447,7 +447,7 @@ static bool is_safe(int x, int y) } // Stop before wasting energy on plants and fungi. - if (mons_flag( menv[mon].type, M_NO_EXP_GAIN )) + if (mons_class_flag( menv[mon].type, M_NO_EXP_GAIN )) return false; // If this is any *other* monster, it'll be visible and @@ -736,6 +736,11 @@ void stop_running(void) you.running = 0; } +bool is_resting( void ) +{ + return (you.running > 0 && !you.run_x && !you.run_y); +} + void start_running(void) { userdef_run_startrunning_hook(); diff --git a/crawl-ref/source/travel.h b/crawl-ref/source/travel.h index 30327bd46a..e4478af0fb 100644 --- a/crawl-ref/source/travel.h +++ b/crawl-ref/source/travel.h @@ -33,25 +33,14 @@ bool is_stair(unsigned gridc); bool is_travelable_stair(unsigned gridc); int stair_direction(int stair_feat); bool is_player_mapped(unsigned char envch); +bool is_resting( void ); +bool can_travel_interlevel(); inline bool is_player_mapped(int grid_x, int grid_y) { return (is_player_mapped( env.map[grid_x - 1][grid_y - 1] )); } -/* *********************************************************************** - * Returns the direction to take to move along the shortest path between - * (you_x, you_y) and (you.run_x, you.run_y) in (*move_x, *move_y). - * If move_x or move_y is NULL, the function explores the map outwards from - * (you_x, you_y), populating the coords vector with the coordinates - * of every dungeon feature it finds, features closest to the character - * (travel distance-wise) coming first in the vector. A 'feature' is defined - * as a trap, and any other non-floor, non-water/lava square that the character - * can step onto. - * - * *********************************************************************** - * called from: acr - view - * *********************************************************************** */ void find_travel_pos(int you_x, int you_y, char *move_x, char *move_y, std::vector<coord_def>* coords = NULL); @@ -362,8 +351,6 @@ private: int level_distance(level_id first, level_id second); -bool can_travel_interlevel(); - extern TravelCache travel_cache; #endif // TRAVEL_H diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index adfb1a62bd..c4b4a23e0f 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -737,33 +737,43 @@ void viewwindow2(char draw_it, bool do_updates) Options.item_colour ); } } + + if (you.flash_colour != BLACK + && buffy[bufcount + 1] != DARKGREY) + buffy[bufcount + 1] = you.flash_colour; + bufcount += 2; } } - if (you.berserker) + if (you.flash_colour == BLACK) { - for (count_x = 1; count_x < 1400; count_x += 2) + if (you.berserker) { - if (buffy[count_x] != DARKGREY) - buffy[count_x] = RED; + for (count_x = 1; count_x < 1400; count_x += 2) + { + if (buffy[count_x] != DARKGREY) + buffy[count_x] = RED; + } } - } - if (show_green != BLACK) - { - for (count_x = 1; count_x < 1400; count_x += 2) + if (show_green != BLACK) { - if (buffy[count_x] != DARKGREY) - buffy[count_x] = show_green; - } + for (count_x = 1; count_x < 1400; count_x += 2) + { + if (buffy[count_x] != DARKGREY) + buffy[count_x] = show_green; + } - show_green = BLACK; + show_green = BLACK; - if (you.special_wield == SPWLD_SHADOW) - show_green = DARKGREY; + if (you.special_wield == SPWLD_SHADOW) + show_green = DARKGREY; + } } + you.flash_colour = BLACK; + #ifdef DOS_TERM puttext(2, 1, 34, 17, buffy.buffer()); #endif @@ -1211,7 +1221,7 @@ void monster_grid(bool do_updates) } else if (!mons_friendly( monster ) && !mons_is_mimic( monster->type ) - && !mons_flag( monster->type, M_NO_EXP_GAIN )) + && !mons_class_flag( monster->type, M_NO_EXP_GAIN )) { interrupt_activity( AI_SEE_MONSTER ); if (you.running != 0 @@ -1576,17 +1586,32 @@ void cloud_grid(void) } // end 'for s' loop } // end cloud_grid() - -void noisy( int loudness, int nois_x, int nois_y ) +// Noisy now has a messenging service for giving messages to the +// player is appropriate. +// +// Returns true if the PC heard the noise. +bool noisy( int loudness, int nois_x, int nois_y, const char *msg ) { int p; struct monsters *monster = 0; // NULL {dlb} + bool ret = false; + // If the origin is silenced there is no noise. if (silenced( nois_x, nois_y )) - return; + return (false); - int dist = loudness * loudness; + const int dist = loudness * loudness; + + // message the player + if (distance( you.x_pos, you.y_pos, nois_x, nois_y ) <= dist + && player_can_hear( nois_x, nois_y )) + { + if (msg) + mpr( msg, MSGCH_SOUND ); + ret = true; + } + for (p = 0; p < MAX_MONSTERS; p++) { monster = &menv[p]; @@ -1605,6 +1630,8 @@ void noisy( int loudness, int nois_x, int nois_y ) behaviour_event( monster, ME_DISTURB, MHITNOT, nois_x, nois_y ); } } + + return (ret); } // end noisy() /* ======================================================================== diff --git a/crawl-ref/source/view.h b/crawl-ref/source/view.h index b36ff18551..e45186cda2 100644 --- a/crawl-ref/source/view.h +++ b/crawl-ref/source/view.h @@ -69,7 +69,7 @@ void magic_mapping(int map_radius, int proportion); * called from: acr - effects - it_use2 - it_use3 - item_use - spell - * spells - spells3 - spells4 * *********************************************************************** */ -void noisy( int loudness, int nois_x, int nois_y ); +bool noisy( int loudness, int nois_x, int nois_y, const char *msg = NULL ); // last updated 12may2000 {dlb} @@ -108,4 +108,9 @@ void clear_map(); bool is_feature(int feature, int x, int y); +inline bool in_map_grid(int x, int y) +{ + return !(x < 1 || x >= GXM || y < 1 || y >= GYM); +} + #endif diff --git a/crawl-ref/source/wpn-misc.cc b/crawl-ref/source/wpn-misc.cc index c6d38f98e6..afc7494c01 100644 --- a/crawl-ref/source/wpn-misc.cc +++ b/crawl-ref/source/wpn-misc.cc @@ -178,10 +178,15 @@ unsigned char launched_by(unsigned char weapon_subtype) } } // end launched_by() +int weapon_skill(const item_def &item) +{ + return weapon_skill(item.base_type, item.sub_type); +} + // this function returns the skill that the weapon would use in melee -char weapon_skill(unsigned char wclass, unsigned char wtype) +int weapon_skill(int wclass, int wtype) { - char skill2use = SK_FIGHTING; + int skill2use = SK_FIGHTING; if (wclass == OBJ_STAVES && (wtype < STAFF_SMITING || wtype >= STAFF_AIR)) diff --git a/crawl-ref/source/wpn-misc.h b/crawl-ref/source/wpn-misc.h index e1d45c8d4a..dce7ba7cd4 100644 --- a/crawl-ref/source/wpn-misc.h +++ b/crawl-ref/source/wpn-misc.h @@ -61,7 +61,9 @@ bool launches_things( unsigned char weapon_subtype ); /* *********************************************************************** * called from: describe - fight - files - it_use3 - newgame - spells1 * *********************************************************************** */ -char weapon_skill(unsigned char wclass, unsigned char wtype); +int weapon_skill(int wclass, int wtype); + +int weapon_skill(const item_def &item); #endif |