diff options
28 files changed, 767 insertions, 252 deletions
diff --git a/crawl-ref/docs/level-design.txt b/crawl-ref/docs/level-design.txt index 9bbd22112b..a61849c10f 100644 --- a/crawl-ref/docs/level-design.txt +++ b/crawl-ref/docs/level-design.txt @@ -346,10 +346,7 @@ PLACE: Used to specify certain special levels. Existing special levels are: PLACE can be used with random vaults and minivaults for testing them. -TAGS: allow_dup, generate_awake, mini_float, no_item_gen, no_monster_gen, - no_pool_fixup, orc_entry, uniq_BAR - - Tags go an a TAGS: line and are space-separated. Valid tags are: +TAGS: Tags go an a TAGS: line and are space-separated. Valid tags are: * "allow_dup": Vaults are normally used only once per game. If you have a vault that can be used more than once, use allow_dup to tell the dungeon builder that the vault can be reused. @@ -383,15 +380,15 @@ TAGS: allow_dup, generate_awake, mini_float, no_item_gen, no_monster_gen, the map eligible for said pan lord's lair. * "uniq_BAR": (uniq_ with any suffix) specifies that only one of the vaults with this tag can be used in a game. - -FLAGS: no_rotate, no_hmirror, no_vmirror - Flags go on a FLAGS: line and are space-separated. Valid flags are: * "no_rotate": Normally, the dungeon builder can, at its whim, rotate your vault. This flag tells it, "hey, don't do that to my vault!" * "no_hmirror": Like no_rotate, but for horizontal mirroring. * "no_vmirror": Like no_rotate, but for vertical mirroring. + Pre-0.3 Crawl distinguished between TAGS and FLAGS. 0.3 and + newer Crawls treat TAGS and FLAGS as synonyms. + LFLAGS: Persistent, changeable per-level flags which affect game behavior (FLAGS just controls how the vault is placed); should only be used for vaults with ORIENT encompass or with PLACE. diff --git a/crawl-ref/source/abyss.cc b/crawl-ref/source/abyss.cc index adb4fdfb7d..35da6aa06d 100644 --- a/crawl-ref/source/abyss.cc +++ b/crawl-ref/source/abyss.cc @@ -598,7 +598,7 @@ static bool spawn_corrupted_servant_near(const coord_def &pos) one_chance_in(5 + you.skills[SK_INVOCATIONS] / 4)? BEH_HOSTILE : BEH_NEUTRAL; const int mid = - create_monster( mons, 5, beh, p.x, p.y, MHITNOT, 250 ); + create_monster( mons, 5, beh, p.x, p.y, MHITNOT, MONS_PROGRAM_BUG ); return (mid != -1); } diff --git a/crawl-ref/source/dat/entry.des b/crawl-ref/source/dat/entry.des index 201498f361..2df4110cb1 100644 --- a/crawl-ref/source/dat/entry.des +++ b/crawl-ref/source/dat/entry.des @@ -1596,7 +1596,7 @@ ENDMAP # the snail NAME: david_023_snail -TAGS: entry no_monster_gen +TAGS: entry no_monster_gen no_rotate ORIENT: float MAP xxxxxxxxxxxxxxxxx diff --git a/crawl-ref/source/dat/hells.des b/crawl-ref/source/dat/hells.des index 8f09b7547b..aa76801766 100644 --- a/crawl-ref/source/dat/hells.des +++ b/crawl-ref/source/dat/hells.des @@ -1,9 +1,10 @@ ############################################################################## -# hells.des: vestibule entries, vestibule, all hell end levels +# hells.des: vestibule entries, vestibule, +# hell vaults, hell end levels ############################################################################## ############################################################################## -# Hell-themed random maps +# Vestibule entries ############################################################################## default-depth: D:12-26 @@ -108,9 +109,101 @@ MAP ..................??.......... ENDMAP -############################################################################# + +############################################################################## +# Hell vaults +############################################################################## + +############################################################################## +# lemuel_hellion_isle + +NAME: lemuel_hellion_isle +DEPTH: Geh:* +MONS: hellion, Fiend +SUBST: L = l. +SUBST: 1 = .:2 l:2 1 +MAP + lL + llL + LlLLL + LLllLL +llLLLlllLLL +LllllllllllLL +LLLlll11lllllLL + LLLll111llllL + LLlll121llLL + Lllll111lLL + LLllll1llL + LllllllL + LLLlllL + LLllL + LlL + LlL +ENDMAP + +############################################################################## +# lemuel_mystery_crypt + +NAME: lemuel_mystery_crypt +DEPTH: Dis:* +MONS: mummy / mummy priest / greater mummy, lich +NSUBST: 1:1=} / *=1 +NSUBST: 1:1=) / *=1 +NSUBST: 1:1=] / *=1 +SUBST: = : =+ +SUBST: }=}>, )=)>, ]=]> +# occasionally (12.5%), all downstairs are in this vault +ORIENT: float +MAP +xxxxxxxxxxxxxxxxxxxxxxx +xxFxxxx1.x1x.1xxx2..=1x +xx.xxxxx.x.x.xxxx...xxx +xx.xx1.x.x.x.x.1x...=1x +xx.xxx=x=x=x=x=xx...xxx +x...+...........+...=1x ++...+.....F.....+.F.xxx +x...+...........+...=1x +xx.xxx=x=x=x=x=xx...xxx +xx.xx1.x.x.x.x.1x...=1x +xx.xxxxx.x.x.xxxx...xxx +xxFxxxx1.x1x.1xxx2..=1x +xxxxxxxxxxxxxxxxxxxxxxx +ENDMAP + +############################################################################## +# lemuel_nasty_pond + +NAME: lemuel_nasty_pond +DEPTH: Tar:* +TAGS: no_pool_fixup +FLAGS: no_rotate +MONS: plant, oklob plant, death ooze, rotting devil, blue death / green death +SUBST: W:w. +SUBST: Z:w. +SUBST: w = w .:1 +SUBST: . = .:15 1:1 w:1 +SUBST: 1 = 1 2:2 +COLOUR: . = none / green w:2 +COLOUR: w = green / lightgreen +MAP + ...WWWW3.... + .3..WWWWW....3... + ....WWWwwW...3....3. +..Z.WWwwwwww3.....3... +3.ZZWwwwwwwwwww3...... +.ZZZ..wwwww5wwwwww3... +..3Z..44wwwwwww33..... +.3ZZZ..44wwwwww3..3... +.ZZZZZ.44wwwww........ + ..ZZZZZ4wwww.3...... + 3ZZZZwwwww....3. + .ZZwww3..... +ENDMAP + +############################################################################## # Vestibule of Hell and Geryon -# +############################################################################## + NAME: vestibule_of_hell PLACE: Hell ORIENT: encompass @@ -119,9 +212,7 @@ MARKER: G=feat:enter_gehenna MARKER: C=feat:enter_cocytus MARKER: T=feat:enter_tartarus SUBST: D=A, G=A, C=A, T=A - MONS: Geryon - MAP xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @@ -150,21 +241,21 @@ xxxxxxxxxxxxx.....................................................xxxxxxxxxxxxxx xxxxxxxxxxxx.......................................................xxxxxxxxxxxxx xxxxxxxxxxxx.......................................................xxxxxxxxxxxxx xxxxxxxxxxx.........................................................xxxxxxxxxxxx -xxxxxxxxxxx............................{............................xxxxxxxxxxxx -xxxxxxxxxxx.........................................................xxxxxxxxxxxx -xxxxxxxxxx...l.l.....................................................xxxxxxxxxxx -xxxxxxxxxx..l.l.l.l..................................................xxxxxxxxxxx -xxxxxxxxxx.l.l.l.l.l.................................................xxxxxxxxxxx -xxxxxxxxx.l.l.l.l.l...................................................xxxxxxxxxx -xxxxxxxxxl.l.l.l.l.l..................................................xxxxxxxxxx -xxxxxxxxx.l.l.l.G.l.l.................}1].............................=Txxxxxxxx -xxxxxxxxxl.l.l.l.l.l.l.................)..............................xxxxxxxxxx -xxxxxxxxx.l.l.l.l.l.l.................................................xxxxxxxxxx -xxxxxxxxxx.l.l.l.l.l.l...............................................xxxxxxxxxxx -xxxxxxxxxx..l.l.l.l..................................................xxxxxxxxxxx -xxxxxxxxxx.....l.l...................................................xxxxxxxxxxx -xxxxxxxxxxx......................[...........(......................xxxxxxxxxxxx -xxxxxxxxxxx.........................................................xxxxxxxxxxxx +xxxxxxxxxxx............................{......................cccc..xxxxxxxxxxxx +xxxxxxxxxxx...................................................ccccccccxxxxxxxxxx +xxxxxxxxxx...l.l..............................................cccc...cxxxxxxxxxx +xxxxxxxxxx..l.l.l.l.............................................c....cxxxxxxxxxx +xxxxxxxxxx.l.l.l.l.l............................................c....cxxxxxxxxxx +xxxxxxxxx.l.l.l.l.l.............................................c...ccccxxxxxxxx +xxxxxxxxxl.l.l.l.l.l............................................+...c..ccxxxxxxx +xxxxxxxxx.l.l.l.G.l.l.................}1].......................+...+.T.cxxxxxxx +xxxxxxxxxl.l.l.l.l.l.l.................)........................+...c..ccxxxxxxx +xxxxxxxxx.l.l.l.l.l.l...........................................c...ccccxxxxxxxx +xxxxxxxxxx.l.l.l.l.l.l..........................................c....cxxxxxxxxxx +xxxxxxxxxx..l.l.l.l.............................................c....cxxxxxxxxxx +xxxxxxxxxx.....l.l............................................cccc...cxxxxxxxxxx +xxxxxxxxxxx......................[...........(................ccccccccxxxxxxxxxx +xxxxxxxxxxx...................................................cccc..xxxxxxxxxxxx xxxxxxxxxxx.........................................................xxxxxxxxxxxx xxxxxxxxxxxx.......................................................xxxxxxxxxxxxx xxxxxxxxxxxx.......................................................xxxxxxxxxxxxx @@ -195,15 +286,17 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ENDMAP -############################################################################# + +############################################################################## # Dispater's castle - rest of level filled up with plan_4 (irregular city) -# +############################################################################## NAME: castle_dis PLACE: Dis:7 TAGS: dis ORIENT: north - +MONS: Dispater, Fiend, Ice Fiend, iron devil, metal gargoyle +MONS: random, random MAP xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @@ -243,17 +336,16 @@ xxxxxxxxv..vvvvvvvvv........................................vvvvvvvvv..vxxxxxxxx xxxxxxxxv............................{.[.(.............................vxxxxxxxx ENDMAP -MONS: Dispater, Fiend, Ice Fiend, iron devil, metal gargoyle -MONS: random, random -############################################################################# -# Asmodeus -# +############################################################################## +# Asmodeus +############################################################################## NAME: asmodeus PLACE: Geh:7 ORIENT: encompass - +MONS: Asmodeus, Fiend, Balrug, molten gargoyle +MONS: Serpent of Hell, random, random MAP xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @@ -327,12 +419,10 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ENDMAP -MONS: Asmodeus, Fiend, Balrug, molten gargoyle -MONS: Serpent of Hell, random, random -############################################################################ +############################################################################## # Antaeus; bottom of Cocytus. David's Improved Demon Lairs, episode I. -# +############################################################################## # To do: this level has much shorter distances to travel, hence should # come up with harder resistance. @@ -345,7 +435,6 @@ SHUFFLE: O1d / e0% / f9* / g8| KMONS: d = ice devil w:5 / Ice Fiend / nothing w:5 KITEM: d = any SUBST: ' = w . - MAP xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @@ -421,6 +510,7 @@ ENDMAP ############################################################################## # Old Antaeus level +############################################################################## NAME: antaeus_in_days_of_yore PLACE: Coc:7 @@ -428,7 +518,6 @@ ORIENT: encompass SHUFFLE: $|, 2X SUBST: X=., 3=3. MONS: Antaeus, Ice Fiend, ice dragon, Ice Fiend - MAP xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @@ -505,14 +594,13 @@ ENDMAP ############################################################################## # Ereshkigal (Tartarus) -# +############################################################################## NAME: ereshkigal PLACE: Tar:7 ORIENT: encompass MONS: Ereshkigal, necrophage, wraith, shadow, small zombie MONS: small skeleton, Shadow Fiend - MAP xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @@ -585,6 +673,3 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ENDMAP - - - diff --git a/crawl-ref/source/dat/lair.des b/crawl-ref/source/dat/lair.des index 9622f587f8..e4bdbc4f1c 100644 --- a/crawl-ref/source/dat/lair.des +++ b/crawl-ref/source/dat/lair.des @@ -961,6 +961,7 @@ ENDMAP NAME: swamp_alternative PLACE: Swamp:5 TAGS: no_pool_fixup +FLAGS: no_rotate ORIENT: float MONS: swamp dragon, swamp drake, hydra, firedrake ITEM: nothing diff --git a/crawl-ref/source/dat/zot.des b/crawl-ref/source/dat/zot.des index d832d224a2..f82becdc53 100644 --- a/crawl-ref/source/dat/zot.des +++ b/crawl-ref/source/dat/zot.des @@ -3,6 +3,234 @@ # should be serious challenges! Players dying on Zot:5 are okay :) ############################################################################## + +########################### +# +# Zot petite vaults +# + +NAME: lemuel_baited_zot_trap +DEPTH: Zot:* +CHANCE: 20 +TAGS: allow_dup +KFEAT: * = Zot trap +KITEM: * = any good_item +MAP +* +ENDMAP + +NAME: lemuel_zot_downstairs +DEPTH: Zot:1-4 +ORIENT: float +TAGS: allow_dup +SUBST: . = .^ +KFEAT: ^ = Zot trap +SUBST: > = }]) +MAP +xxxxxxx +@....>x +xxxxxxx +ENDMAP + +NAME: lemuel_zot_upstairs +DEPTH: Zot:2-5 +ORIENT: float +TAGS: allow_dup +SUBST: . = .^ +KFEAT: ^ = zot trap +SUBST: < = ([{ +MAP +xxxxxxx +@....<x +xxxxxxx +ENDMAP + + +########################### +# Halls of Wrath +# +NAME: lemuel_halls_of_wrath +DEPTH: Zot:1-4 +ORIENT: float +FLAGS: no_rotate +NSUBST: 1 = 6:2 / *=1 +SUBST: 1 = 1 .:5 +SUBST: 1 = 1 3 +MONS: troll/deep troll/iron troll/ogre/two-headed ogre/w:2 iron devil +MONS: moth of wrath +MONS: hill giant/stone giant/fire giant/frost giant/ettin/w:5 efreet/w:3 titan +NSUBST: C = 2:= / *=c +NSUBST: D = 2:= / *=c +MAP +cccccccccccccccccccccccc +n111111111111111111.c..c +n111111111111111111.c.)c +cCCCCCCCCCCCCCCcc++cc..c +n....F....F....F....c..c ++...................+..c ++...................+.}c ++...................+..c +n....F....F....F....c..c +cDDDDDDDDDDDDDDcc++cc..c +n111111111111111111.c.]c +n111111111111111111.c..c +cccccccccccccccccccccccc +ENDMAP + +########################### +# Lich library +# +NAME: lemuel_lich_library +DEPTH: Zot:1-4 +TAGS: no_monster_gen +MONS: flying skull, lich, ancient lich, necromancer, vampire mage, mimic +ITEM: any book, any scroll +SUBST: w:w? +SUBST: ?=. 1:1 +SUBST: x:xc +SUBST: +=+= +SUBST: d = d 6:1 +SUBST: 4 = 4 5:2 .:4 +SUBST: d = d:20 e +MAP +wwwwwwwwwwwwwwwwwwwwwww +wwwwwwwwwwwwwwwwwwwwwww +wwxxxxxxxxx+xxxxxxxxxww +wwx....x.......x....xww +wwx....+...F...+....xww +wwx.4..x.......x..4.xww +wwx4.4.xxxx+xxxx.4.4xww +wwx.4.4xxx...xxx4.4.xww +wwx4.4.xxx.2.xxx.4.4xww +wwxxxxxxxxx+xxxxxxx+xww +wwxxxxxxxxx.xxxxxx$$xww +wwxdddxxxxx.x...xx$$xww +wwx.2.xxxxx.+.F.xxxxxww +wwx...xxxxx.x...xxxxxww +wwx...xxxxx.xxxxxxxxxww +wwxx+xxxxxx.xxxdddddxww +wwxx.xxxxxx.xxxd232dxww +wwxx.xxxxxx.xxxd...dxww +wwxx......+...+....dxww +wwxxxxxxxxxmxxxd...dxww +wwxxxxxxxxxFxxxdddddxww +wwxxxxxxxxxxxxxxxxxxxww +wwwwwwwwwwwwwwwwwwwwwww +wwwwwwwwwwwwwwwwwwwwwww +ENDMAP + +########################### +# Lake of fire +# +NAME: lemuel_lake_of_fire +DEPTH: Zot:* +SUBST: * =*l +KMONS: * = orb of fire +KFEAT: * = l +SUBST: .=.l +MAP + ..ll.. +..llll.. +.llllll. +.ll**ll. +.ll**ll. +.llllll. +..llll.. + ..ll.. +ENDMAP + +########################### +# +# Globe of electric golems +# +NAME: lemuel_golem_globe +DEPTH: Zot:* +FLAGS: no_rotate +SUBST: 1 = 1. +MONS: electric golem +MAP + mmmm + mm..mm +mm.11.mm +m.1..1.m +mm.11.mm + mm..mm + mmmm +ENDMAP + +########################### +# Acid trip +# +NAME: lemuel_acid_trip +DEPTH: Zot:1-4 +ORIENT: float +MONS: oklob plant, acid blob, jelly, yellow draconian +MONS: any nonbase yellow draconian +SUBST: 1 = 1:2 . +SUBST: . = .:20 3:3 2:1 +SUBST: }=}>, )=)>, ]=]> +# chance for having all downstairs in the vault is 12.5% +MAP + xx++xx + xxx....xxx + xxx..4444..xxx + xx....4554....xx + xx.....cccc.....xx + x....ccc..ccc....x +xx...cc......cc...xx +x...cc..1111..cc...x +x...c...1}11...c...x +x.5.c...11]1...c.5.x +x...c...1)11...c...x +x...cc..1111..cc...x +xx...cc......cc...xx + x....cc....cc....x + xx....c....c....xx + xx............xx + xxx..4444..xxx + xxx4554xxx + xxxxxx +ENDMAP + +########################### +# Firehouse +# +NAME: lemuel_firehouse +DEPTH: Zot: 1-4 +ORIENT: float +MONS: orb of fire +MONS: fire elemental +MONS: red draconian / weight:2 mottled draconian +MONS: any nonbase red draconian +MONS: efreet +SUBST: 1=122, 3=322 +SUBST: 4 = 2:20 4:5 3:15 .:20 +MAP + lllll + lllllllllll + lllll.....lllll + llll....x....llll + llll....xxx....llll + llll...xx}xx...llll + llll...xx]2)xx...llll + llll..xx2...2xx..llll + llll..xx...5...xx..llll + llll..x...2.2...x..llll +llll...x.2xx+xx2.x...llll +llll...x.xx444xx.x...llll +llll...x.x44444x.x...llll + llll..x.x44F44x.x..llll + llll..x.x44444x.x..llll + llll.x.xx444xx.x.llll + llll.x.1x...x1.x.llll + llllxxxx+++xxxxllll + llll333...333llll + lllll.....lllll + lllllllllll + ll>ll +ENDMAP + + ############################################################################## # hall_of_Zot diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index a0eac1d559..18856e9122 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -393,7 +393,8 @@ void create_spec_monster(void) canned_msg( MSG_OK ); else create_monster( mon, 0, BEH_SLEEP, - you.x_pos, you.y_pos, MHITNOT, 250, true ); + you.x_pos, you.y_pos, MHITNOT, MONS_PROGRAM_BUG, + true ); } // end create_spec_monster() #endif @@ -2475,7 +2476,7 @@ static int create_fsim_monster(int mtype, int hp) { const int mi = create_monster( mtype, 0, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITNOT, 250 ); + MHITNOT, MONS_PROGRAM_BUG ); if (mi == -1) return (mi); diff --git a/crawl-ref/source/decks.cc b/crawl-ref/source/decks.cc index 6ed7a2f148..475def8b60 100644 --- a/crawl-ref/source/decks.cc +++ b/crawl-ref/source/decks.cc @@ -2162,7 +2162,8 @@ static bool trowel_card(int power, deck_rarity_type rarity) }; if ( create_monster(RANDOM_ELEMENT(statues), 0, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250) != -1 ) + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG) != -1 ) { mpr("A menacing statue appears!"); num_made++; @@ -2174,7 +2175,8 @@ static bool trowel_card(int power, deck_rarity_type rarity) }; if ( create_monster(RANDOM_ELEMENT(golems), 5, BEH_FRIENDLY, - you.x_pos, you.y_pos, MHITYOU, 250) != -1 ) + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG) != -1 ) { mpr("You construct a golem!"); num_made++; @@ -2317,7 +2319,8 @@ static void summon_demon_card(int power, deck_rarity_type rarity) else dct = DEMON_LESSER; create_monster( summon_any_demon(dct), std::min(power/50,6), - BEH_FRIENDLY, you.x_pos, you.y_pos, MHITYOU, 250 ); + BEH_FRIENDLY, you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG ); } static void summon_any_monster(int power, deck_rarity_type rarity) @@ -2359,10 +2362,10 @@ static void summon_any_monster(int power, deck_rarity_type rarity) if ( power_level == 0 && one_chance_in(4) ) create_monster( mon_chosen, 3, BEH_HOSTILE, - chosen_x, chosen_y, MHITYOU, 250 ); + chosen_x, chosen_y, MHITYOU, MONS_PROGRAM_BUG ); else create_monster( mon_chosen, 3, BEH_FRIENDLY, - chosen_x, chosen_y, you.pet_target, 250 ); + chosen_x, chosen_y, you.pet_target, MONS_PROGRAM_BUG ); } static void summon_dancing_weapon(int power, deck_rarity_type rarity) @@ -2373,7 +2376,8 @@ static void summon_dancing_weapon(int power, deck_rarity_type rarity) friendly ? BEH_FRIENDLY : BEH_HOSTILE, you.x_pos, you.y_pos, friendly ? you.pet_target : MHITYOU, - 250, false, false, false, true ); + MONS_PROGRAM_BUG, false, false, false, + true ); // Given the abundance of Nemelex decks, not setting hard reset // leaves a trail of weapons behind, most of which just get @@ -2440,7 +2444,7 @@ static void summon_flying(int power, deck_rarity_type rarity) for ( int i = 0; i < power_level * 5 + 2; ++i ) create_monster(result, std::min(power/50, 6), friendly ? BEH_FRIENDLY : BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250); + you.x_pos, you.y_pos, MHITYOU, MONS_PROGRAM_BUG); } static void summon_skeleton(int power, deck_rarity_type rarity) @@ -2453,7 +2457,7 @@ static void summon_skeleton(int power, deck_rarity_type rarity) create_monster(skeltypes[power_level], std::min(power/50,6), friendly ? BEH_FRIENDLY : BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250 ); + you.x_pos, you.y_pos, MHITYOU, MONS_PROGRAM_BUG ); } static int card_power(deck_rarity_type rarity) diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index b3bfeb30ce..91768a1fee 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -2683,7 +2683,7 @@ static int place_uniques(int level_number, char level_type) // note: unique_creatures 40 + used by unique demons if (place_monster( not_used, which_unique, level_number, BEH_SLEEP, MHITNOT, false, 1, 1, true, - PROX_ANYWHERE, 250, 0, MMT_NO_MONS )) + PROX_ANYWHERE, MONS_PROGRAM_BUG, 0, MMT_NO_MONS )) { #ifdef DEBUG_DIAGNOSTICS mprf(MSGCH_DIAGNOSTICS, "Placed %s", @@ -2704,7 +2704,8 @@ static int place_monster_vector(std::vector<int> montypes, { if (place_monster( not_used, montypes[random2(montypes.size())], level_number, BEH_SLEEP, MHITNOT, - false, 1, 1, true, PROX_ANYWHERE, 250, 0, + false, 1, 1, true, PROX_ANYWHERE, + MONS_PROGRAM_BUG, 0, MMT_NO_MONS )) { ++result; @@ -2783,8 +2784,8 @@ static void builder_monsters(int level_number, char level_type, int mon_wanted) for (int i = 0; i < mon_wanted; i++) place_monster( not_used, RANDOM_MONSTER, level_number, BEH_SLEEP, - MHITNOT, false, 1, 1, true, PROX_ANYWHERE, 250, 0, - MMT_NO_MONS ); + MHITNOT, false, 1, 1, true, PROX_ANYWHERE, + MONS_PROGRAM_BUG, 0, MMT_NO_MONS ); place_uniques(level_number, level_type); @@ -7068,7 +7069,7 @@ void define_zombie( int mid, int ztype, int cs, int power ) } // that is, random creature from which to fashion undead - if (ztype == 250) + if (ztype == MONS_PROGRAM_BUG) { // how OOD this zombie can be. int relax = 5; diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index 5d0a72054e..f73e2a233f 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -1990,7 +1990,7 @@ static void hell_effects() if (summon_instead) { create_monster( which_beastie, 0, BEH_HOSTILE, you.x_pos, - you.y_pos, MHITYOU, 250 ); + you.y_pos, MHITYOU, MONS_PROGRAM_BUG ); } else { @@ -2008,14 +2008,15 @@ static void hell_effects() if (one_chance_in(3)) { create_monster( RANDOM_MONSTER, 0, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250 ); + you.x_pos, you.y_pos, MHITYOU, MONS_PROGRAM_BUG ); for (int i = 0; i < 4; i++) { if (one_chance_in(3)) { create_monster( RANDOM_MONSTER, 0, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250 ); + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG ); } } } diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index a0a33036a3..facb2bb8f0 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -1677,15 +1677,20 @@ enum monster_type // (int) menv[].type // BCR - end second batch of uniques. MONS_DRACONIAN, - MONS_BLACK_DRACONIAN, + + // If adding more drac colours, sync up colour names in + // mon-util.cc. + MONS_BLACK_DRACONIAN, // Should always be first colour. MONS_MOTTLED_DRACONIAN, MONS_YELLOW_DRACONIAN, MONS_GREEN_DRACONIAN, // 315 MONS_PURPLE_DRACONIAN, MONS_RED_DRACONIAN, MONS_WHITE_DRACONIAN, - MONS_PALE_DRACONIAN, - MONS_DRACONIAN_CALLER, // 320 + MONS_PALE_DRACONIAN, // Should always be last colour. + + // Sync up with monplace.cc's draconian selection if adding more. + MONS_DRACONIAN_CALLER, MONS_DRACONIAN_MONK, MONS_DRACONIAN_ZEALOT, MONS_DRACONIAN_SHIFTER, @@ -1780,8 +1785,18 @@ enum monster_type // (int) menv[].type MONS_SILVER_STATUE, MONS_ICE_STATUE, - NUM_MONSTERS, // used for polymorph + NUM_MONSTERS, // used for polymorph RANDOM_MONSTER = 1000, // used to distinguish between a random monster and using program bugs for error trapping {dlb} + + // A random draconian, either base coloured drac or specialised. + RANDOM_DRACONIAN, + + // Any random base draconian colour. + RANDOM_BASE_DRACONIAN, + + // Any random specialised draconian, such as a draconian knight. + RANDOM_NONBASE_DRACONIAN, + WANDERING_MONSTER = 2500 // only used in monster placement routines - forced limit checks {dlb} }; diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc index 5b3a337dd3..151bf4b0b9 100644 --- a/crawl-ref/source/it_use3.cc +++ b/crawl-ref/source/it_use3.cc @@ -226,7 +226,8 @@ void special_wielded() { did_god_conduct( DID_NECROMANCY, 1 ); create_monster( MONS_SHADOW, 2, BEH_FRIENDLY, - you.x_pos, you.y_pos, you.pet_target, 250 ); + you.x_pos, you.y_pos, you.pet_target, + MONS_PROGRAM_BUG ); } show_green = DARKGREY; @@ -370,7 +371,7 @@ static bool evoke_horn_of_geryon() { mpr("You produce a hideous howling noise!"); create_monster( MONS_BEAST, 4, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250, false, false, false, true ); + MHITYOU, MONS_PROGRAM_BUG, false, false, false, true ); } return rc; } @@ -385,9 +386,10 @@ static bool evoke_sceptre_of_asmodeus() // summon devils, maybe a Fiend const monster_type mtype = (one_chance_in(4) ? MONS_FIEND : summon_any_demon(DEMON_COMMON)); - const bool good_summon = (create_monster( mtype, 6, BEH_HOSTILE, - you.x_pos, you.y_pos, - MHITYOU, 250) != -1); + const bool good_summon = + (create_monster( mtype, 6, BEH_HOSTILE, + you.x_pos, you.y_pos, + MHITYOU, MONS_PROGRAM_BUG) != -1); if (good_summon) { @@ -690,7 +692,8 @@ static bool efreet_flask(void) mpr("You open the flask..."); const int efreet = create_monster( MONS_EFREET, 0, behaviour, - you.x_pos, you.y_pos, MHITYOU, 250, + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG, false, false, true ); if (efreet != -1) { @@ -874,7 +877,8 @@ void tome_of_power(int slot) else if (one_chance_in(36)) { if (create_monster( MONS_ABOMINATION_SMALL, 6, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250 ) != -1) + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG ) != -1) { mpr("A horrible Thing appears!"); mpr("It doesn't look too friendly."); @@ -966,7 +970,8 @@ static bool box_of_beasts() ? BEH_HOSTILE : BEH_FRIENDLY); if (create_monster( beasty, 2 + random2(4), beh, - you.x_pos, you.y_pos, MHITYOU, 250 ) != -1) + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG ) != -1) { mpr("...and something leaps out!"); xom_is_stimulated(14); diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index f5596ffec2..ff65a9e8ed 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -4020,7 +4020,8 @@ void read_scroll( int slot ) case SCR_SUMMONING: if (create_monster( MONS_ABOMINATION_SMALL, 6, BEH_FRIENDLY, - you.x_pos, you.y_pos, you.pet_target, 250 ) != -1) + you.x_pos, you.y_pos, you.pet_target, + MONS_PROGRAM_BUG ) != -1) { mpr("A horrible Thing appears!"); } diff --git a/crawl-ref/source/libutil.cc b/crawl-ref/source/libutil.cc index 7c6a412303..ac78351bc2 100644 --- a/crawl-ref/source/libutil.cc +++ b/crawl-ref/source/libutil.cc @@ -174,13 +174,6 @@ std::string lowercase_string(std::string s) return (s); } -bool ends_with(const std::string &s, const std::string &suffix) -{ - if (s.length() < suffix.length()) - return false; - return (s.substr(s.length() - suffix.length()) == suffix); -} - int ends_with(const std::string &s, const char *suffixes[]) { if (!suffixes) diff --git a/crawl-ref/source/libutil.h b/crawl-ref/source/libutil.h index db63e6ff6c..4c64be32e6 100644 --- a/crawl-ref/source/libutil.h +++ b/crawl-ref/source/libutil.h @@ -94,6 +94,18 @@ typedef bool (*p_match)(void *compiled_pattern, const char *text, int length); std::string & trim_string( std::string &str ); std::string trimmed_string( std::string s ); +inline bool starts_with(const std::string &s, const std::string &prefix) +{ + return (s.rfind(prefix, 0) != std::string::npos); +} + +inline bool ends_with(const std::string &s, const std::string &suffix) +{ + if (s.length() < suffix.length()) + return false; + return (s.find(suffix, s.length() - suffix.length()) != std::string::npos); +} + // Splits string 's' on the separator 'sep'. If trim == true, trims each // segment. If accept_empties == true, accepts empty segments. If nsplits >= 0, // splits on the first nsplits occurrences of the separator, and stores the diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc index 29ad03c881..6b980994c5 100644 --- a/crawl-ref/source/mapdef.cc +++ b/crawl-ref/source/mapdef.cc @@ -1974,7 +1974,7 @@ mons_list::mons_spec_slot mons_list::parse_mons_spec(std::string spec) if (nspec.mid == MONS_PROGRAM_BUG) { - error = make_stringf("unrecognised monster \"%s\"", + error = make_stringf("unknown monster: \"%s\"", mon_str.c_str()); return (slot); } @@ -2092,18 +2092,97 @@ mons_spec mons_list::get_hydra_spec(const std::string &name) const { int nheads = atoi(name.c_str()); if (nheads < 1) - nheads = 250; // Choose randomly, doesn't mean a 250-headed hydra. + nheads = MONS_PROGRAM_BUG; // What can I say? :P else if (nheads > 19) nheads = 19; return mons_spec(MONS_HYDRA, nheads); } +// Handle draconians specified as: +// Exactly as in mon-data.h: +// yellow draconian or draconian knight - the monster specified. +// +// Others: +// any draconian => any random draconain +// any base draconian => any unspecialised coloured draconian. +// any nonbase draconian => any specialised coloured draconian. +// any <colour> draconian => any draconian of the colour. +// any nonbase <colour> draconian => any specialised drac of the colour. +// +mons_spec mons_list::drac_monspec(std::string name) const +{ + mons_spec spec; + + spec.mid = get_monster_by_name(name, true); + + // Check if it's a simple drac name, we're done. + if (spec.mid != MONS_PROGRAM_BUG) + return (spec); + + spec.mid = RANDOM_DRACONIAN; + + // Request for any draconian? + if (starts_with(name, "any ")) + // Strip "any " + name = name.substr(4); + + if (starts_with(name, "base ")) + { + // Base dracs need no further work. + return (RANDOM_BASE_DRACONIAN); + } + else if (starts_with(name, "nonbase ")) + { + spec.mid = RANDOM_NONBASE_DRACONIAN; + name = name.substr(8); + } + + trim_string(name); + + // Match "any draconian" + if (name == "draconian") + return (spec); + + // Check for recognition again to match any (nonbase) <colour> draconian. + const monster_type colour = get_monster_by_name(name, true); + if (colour != MONS_PROGRAM_BUG) + { + spec.monnum = colour; + return (spec); + } + + // Only legal possibility left is <colour> boss drac. + std::string::size_type wordend = name.find(' '); + if (wordend == std::string::npos) + return (MONS_PROGRAM_BUG); + + std::string scolour = name.substr(0, wordend); + if ((spec.monnum = draconian_colour_by_name(scolour)) == MONS_PROGRAM_BUG) + return (MONS_PROGRAM_BUG); + + name = trimmed_string(name.substr(wordend + 1)); + spec.mid = get_monster_by_name(name, true); + + // We should have a non-base draconian here. + if (spec.mid == MONS_PROGRAM_BUG + || mons_genus(spec.mid) != MONS_DRACONIAN + || spec.mid == MONS_DRACONIAN + || (spec.mid >= MONS_BLACK_DRACONIAN + && spec.mid <= MONS_PALE_DRACONIAN)) + { + return (MONS_PROGRAM_BUG); + } + + return (spec); +} + mons_spec mons_list::mons_by_name(std::string name) const { lowercase(name); name = replace_all_of( name, "_", " " ); + name = replace_all( name, "random", "any" ); if (name == "nothing") return (-1); @@ -2112,22 +2191,19 @@ mons_spec mons_list::mons_by_name(std::string name) const if (name == "pandemonium demon") return (MONS_PANDEMONIUM_DEMON); - if (name == "random" || name == "random monster") + if (name == "any" || name == "any monster") return (RANDOM_MONSTER); - if (name == "any demon" || name == "demon" || name == "random demon") + if (name == "any demon") return (-100 - DEMON_RANDOM); - if (name == "any lesser demon" - || name == "lesser demon" || name == "random lesser demon") + if (name == "any lesser demon" || name == "lesser demon") return (-100 - DEMON_LESSER); - if (name == "any common demon" - || name == "common demon" || name == "random common demon") + if (name == "any common demon" || name == "common demon") return (-100 - DEMON_COMMON); - if (name == "any greater demon" - || name == "greater demon" || name == "random greater demon") + if (name == "any greater demon" || name == "greater demon") return (-100 - DEMON_GREATER); if (name == "small zombie") @@ -2162,6 +2238,9 @@ mons_spec mons_list::mons_by_name(std::string name) const if (spec.mid != MONS_PROGRAM_BUG) return (spec); + if (name.find("draconian") != std::string::npos) + return drac_monspec(name); + return (get_monster_by_name(name, true)); } diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h index fe06561cd0..b58320684a 100644 --- a/crawl-ref/source/mapdef.h +++ b/crawl-ref/source/mapdef.h @@ -392,7 +392,7 @@ struct mons_spec { int mid; int monnum; // The zombified monster for zombies, or head - // count for hydras. + // count for hydras, or colour for draconians. int genweight, mlevel; bool fix_mons; bool generate_awake; @@ -400,7 +400,7 @@ struct mons_spec item_list items; - mons_spec(int id = RANDOM_MONSTER, int num = 250, + mons_spec(int id = RANDOM_MONSTER, int num = MONS_PROGRAM_BUG, int gw = 10, int ml = 0, bool _fixmons = false, bool awaken = false) : mid(id), monnum(num), genweight(gw), mlevel(ml), fix_mons(_fixmons), @@ -445,6 +445,7 @@ private: private: mons_spec mons_by_name(std::string name) const; + mons_spec drac_monspec(std::string name) const; void get_zombie_type(std::string s, mons_spec &spec) const; mons_spec get_hydra_spec(const std::string &name) const; mons_spec get_zombified_monster(const std::string &name, diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 96eb671584..bc321043ec 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -1318,7 +1318,7 @@ void define_monster(monsters &mons) ac = 3 + random2(7); ev = 7 + random2(6); - if (monnumber == 250) + if (monnumber == MONS_PROGRAM_BUG) // ?? col = random_colour(); break; @@ -1335,7 +1335,7 @@ void define_monster(monsters &mons) ac = 5 + random2avg(9, 2); ev = 3 + random2(5); - if (monnumber == 250) + if (monnumber == MONS_PROGRAM_BUG) col = random_colour(); break; @@ -1415,8 +1415,7 @@ void define_monster(monsters &mons) // apart from that, anything goes. do monnumber = MONS_BLACK_DRACONIAN + random2(8); - while (monnumber == MONS_WHITE_DRACONIAN - && mcls == MONS_DRACONIAN_SCORCHER); + while (drac_colour_incompatible(mcls, monnumber)); break; } case MONS_DRACONIAN_KNIGHT: @@ -1456,9 +1455,6 @@ void define_monster(monsters &mons) hp += m->hpdice[3]; hp_max = hp; - if (monnumber == 250) - monnumber = m->sec; - // so let it be written, so let it be done mons.hit_dice = hd; mons.hit_points = hp; @@ -1467,7 +1463,10 @@ void define_monster(monsters &mons) mons.ev = ev; mons.speed = speed; mons.speed_increment = 70; - mons.number = monnumber; + + if (mons.number == MONS_PROGRAM_BUG) + mons.number = monnumber; + mons.flags = 0L; mons.experience = 0L; mons.colour = col; @@ -1479,6 +1478,30 @@ void define_monster(monsters &mons) mons.ench_countdown = 0; } // end define_monster() +static const char *drac_colour_names[] = { + "black", "mottled", "yellow", "green", "purple", + "red", "white", "pale" +}; + +std::string draconian_colour_name(monster_type mtype) +{ + ASSERT(ARRAYSIZE(drac_colour_names) == + MONS_PALE_DRACONIAN - MONS_DRACONIAN); + if (mtype < MONS_BLACK_DRACONIAN || mtype > MONS_PALE_DRACONIAN) + return "buggy"; + return (drac_colour_names[mtype - MONS_BLACK_DRACONIAN]); +} + +monster_type draconian_colour_by_name(const std::string &name) +{ + ASSERT(ARRAYSIZE(drac_colour_names) == + MONS_PALE_DRACONIAN - MONS_DRACONIAN); + for (unsigned i = 0; i < ARRAYSIZE(drac_colour_names); ++i) + if (name == drac_colour_names[i]) + return static_cast<monster_type>(i + MONS_BLACK_DRACONIAN); + return (MONS_PROGRAM_BUG); +} + static std::string str_monam(const monsters& mon, description_level_type desc, bool force_seen) { @@ -1565,18 +1588,11 @@ static std::string str_monam(const monsters& mon, description_level_type desc, case MONS_DRACONIAN_ANNIHILATOR: case MONS_DRACONIAN_KNIGHT: case MONS_DRACONIAN_SCORCHER: - switch (mon.number) - { - default: break; - case MONS_BLACK_DRACONIAN: result += "black "; break; - case MONS_MOTTLED_DRACONIAN: result += "mottled "; break; - case MONS_YELLOW_DRACONIAN: result += "yellow "; break; - case MONS_GREEN_DRACONIAN: result += "green "; break; - case MONS_PURPLE_DRACONIAN: result += "purple "; break; - case MONS_RED_DRACONIAN: result += "red "; break; - case MONS_WHITE_DRACONIAN: result += "white "; break; - case MONS_PALE_DRACONIAN: result += "pale "; break; - } + result += + draconian_colour_name( + static_cast<monster_type>( mon.number ) ) + " "; + break; + default: break; } @@ -1642,7 +1658,9 @@ std::string mons_type_name(int type, description_level_type desc ) // see mons_init for initialization of mon_entry array. monsterentry *get_monster_data(int p_monsterid) { - const int me = p_monsterid != -1? mon_entry[p_monsterid] : -1; + const int me = + p_monsterid != -1 && p_monsterid < NUM_MONSTERS? + mon_entry[p_monsterid] : -1; if (me >= 0) // PARANOIA return (&mondata[me]); @@ -3753,7 +3771,7 @@ void monsters::ghost_init() foe = MHITNOT; foe_memory = 0; colour = mons_class_colour(MONS_PLAYER_GHOST); - number = 250; + number = MONS_PROGRAM_BUG; load_spells(MST_GHOST); inv.init(NON_ITEM); diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h index d1fb88cf00..e070e675b7 100644 --- a/crawl-ref/source/mon-util.h +++ b/crawl-ref/source/mon-util.h @@ -661,6 +661,8 @@ bool mons_is_paralysed(const monsters *m); bool monster_senior(const monsters *first, const monsters *second); monster_type draco_subspecies( const monsters *mon ); +std::string draconian_colour_name(monster_type mtype); +monster_type draconian_colour_by_name(const std::string &colour); monster_type random_monster_at_grid(int x, int y); monster_type random_monster_at_grid(dungeon_feature_type grid); diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index ceec4e4890..24828e149c 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -348,34 +348,41 @@ static bool can_place_on_trap(int mon_type, trap_type trap) return (true); } -bool place_monster(int &id, int mon_type, int power, beh_type behaviour, - int target, bool summoned, int px, int py, bool allow_bands, - proximity_type proximity, int extra, int dur, - unsigned mmask) +bool drac_colour_incompatible(int drac, int colour) { - int band_size = 0; - int band_monsters[BIG_BAND]; // band monster types - int lev_mons = power; // final 'power' - int i; - - dungeon_char_type stair_type = NUM_DCHAR_TYPES; - int tries = 0; - int pval = 0; - level_id place = level_id::current(); - - // set initial id to -1 (unsuccessful create) - id = -1; - - // (1) early out (summoned to occupied grid) - if (summoned && mgrd[px][py] != NON_MONSTER) - return (false); + return (drac == MONS_DRACONIAN_SCORCHER && colour == MONS_WHITE_DRACONIAN); +} +static int resolve_monster_type(int mon_type, proximity_type proximity, + int num, int px, int py, unsigned mmask, + dungeon_char_type *stair_type, + int *lev_mons) +{ + if (mon_type == RANDOM_DRACONIAN) + { + // Pick any random drac, constrained by colour if requested. + do + mon_type = + random_range(MONS_BLACK_DRACONIAN, MONS_DRACONIAN_SCORCHER); + while (num != MONS_PROGRAM_BUG + && mon_type != num + && (mons_species(mon_type) == mon_type + || drac_colour_incompatible(mon_type, num))); + } + else if (mon_type == RANDOM_BASE_DRACONIAN) + mon_type = random_range(MONS_BLACK_DRACONIAN, MONS_PALE_DRACONIAN); + else if (mon_type == RANDOM_NONBASE_DRACONIAN) + mon_type = random_range(MONS_DRACONIAN_CALLER, MONS_DRACONIAN_SCORCHER); + // (2) take care of random monsters if (mon_type == RANDOM_MONSTER) { + level_id place = level_id::current(); // respect destination level for staircases if (proximity == PROX_NEAR_STAIRS) { + int tries = 0; + int pval = 0; while(++tries <= 320) { px = 5 + random2(GXM - 10); @@ -402,7 +409,7 @@ bool place_monster(int &id, int mon_type, int power, beh_type behaviour, // check whether there's a stair // and whether it leads to another branch pval = near_stairs(coord_def(px, py), 1, - stair_type, place.branch); + *stair_type, place.branch); // no monsters spawned in the Temple if (branches[place.branch].id == BRANCH_ECUMENICAL_TEMPLE) @@ -418,34 +425,61 @@ bool place_monster(int &id, int mon_type, int power, beh_type behaviour, } else { - if ( stair_type == DCHAR_STAIRS_DOWN ) // deeper level - lev_mons++; - else if (stair_type == DCHAR_STAIRS_UP) // higher level + if ( *stair_type == DCHAR_STAIRS_DOWN ) // deeper level + ++*lev_mons; + else if (*stair_type == DCHAR_STAIRS_UP) // higher level { // monsters don't come from outside the dungeon - if (lev_mons <= 0) + if (*lev_mons <= 0) { proximity = PROX_AWAY_FROM_PLAYER; // in that case lev_mons stays as it is } else - lev_mons--; + --*lev_mons; } } } // end proximity check - if (branches[place.branch].id == BRANCH_HALL_OF_BLADES) + if (place.branch == BRANCH_HALL_OF_BLADES) mon_type = MONS_DANCING_WEAPON; else { // now pick a monster of the given branch and level - mon_type = pick_random_monster(place, lev_mons, - lev_mons); - - if (mon_type == MONS_PROGRAM_BUG) - return (false); + mon_type = pick_random_monster(place, *lev_mons, *lev_mons); } } + return (mon_type); +} + +bool place_monster(int &id, int mon_type, int power, beh_type behaviour, + int target, bool summoned, int px, int py, bool allow_bands, + proximity_type proximity, int extra, int dur, + unsigned mmask) +{ + int band_size = 0; + int band_monsters[BIG_BAND]; // band monster types + int lev_mons = power; // final 'power' + int i; + + int tries = 0; + int pval = 0; + dungeon_char_type stair_type = NUM_DCHAR_TYPES; + + // set initial id to -1 (unsuccessful create) + id = -1; + + // (1) early out (summoned to occupied grid) + if (summoned && mgrd[px][py] != NON_MONSTER) + return (false); + + mon_type = + resolve_monster_type(mon_type, proximity, extra, + px, py, mmask, &stair_type, + &lev_mons); + + if (mon_type == MONS_PROGRAM_BUG || mon_type == -1) + return (false); // (3) decide on banding (good lord!) band_size = 1; @@ -724,7 +758,8 @@ static int place_monster_aux( int mon_type, beh_type behaviour, int target, // now, actually create the monster (wheeee!) menv[id].type = mon_type; - menv[id].number = 250; + + menv[id].number = extra; menv[id].x = fx; menv[id].y = fy; @@ -754,9 +789,6 @@ static int place_monster_aux( int mon_type, beh_type behaviour, int target, if (mons_is_unique(mon_type)) you.unique_creatures[mon_type] = true; - if (extra != 250) - menv[id].number = extra; - if (mons_class_flag(mon_type, M_INVIS)) menv[id].add_ench(ENCH_INVIS); diff --git a/crawl-ref/source/monplace.h b/crawl-ref/source/monplace.h index 0bf912b5d5..462c5ed782 100644 --- a/crawl-ref/source/monplace.h +++ b/crawl-ref/source/monplace.h @@ -112,7 +112,8 @@ enum proximity_type // proximity to player to create monster * *********************************************************************** */ int mons_place( int mon_type, beh_type behaviour, int target, bool summoned, int px, int py, int level_type = LEVEL_DUNGEON, - proximity_type proximity = PROX_ANYWHERE, int extra = 250, + proximity_type proximity = PROX_ANYWHERE, + int extra = MONS_PROGRAM_BUG, int dur = 0, bool permit_bands = false ); // last updated 12may2000 {dlb} @@ -160,10 +161,12 @@ monster_type summon_any_demon( demon_class_type demon_class ); * *********************************************************************** */ bool place_monster( int &id, int mon_type, int power, beh_type behaviour, int target, bool summoned, int px, int py, bool allow_bands, - proximity_type proximity = PROX_ANYWHERE, int extra = 250, - int dur = 0, unsigned mmask = 0 ); + proximity_type proximity = PROX_ANYWHERE, + int extra = MONS_PROGRAM_BUG, int dur = 0, + unsigned mmask = 0 ); monster_type rand_dragon( dragon_class_type type ); +bool drac_colour_incompatible(int drac, int colour); /* *********************************************************************** * called from: monplace monstuff diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 4e50e232fa..2f663aeeac 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -1291,7 +1291,7 @@ bool monster_polymorph( monsters *monster, monster_type targetc, /* deal with mons_sec */ monster->type = targetc; - monster->number = 250; + monster->number = MONS_PROGRAM_BUG; mon_enchant abj = monster->get_ench(ENCH_ABJ); mon_enchant shifter = monster->get_ench(ENCH_GLOWING_SHAPESHIFTER, @@ -3184,7 +3184,7 @@ static bool handle_scroll(monsters *monster) simple_monster_message(monster, " reads a scroll."); create_monster( MONS_ABOMINATION_SMALL, 2, SAME_ATTITUDE(monster), monster->x, monster->y, - monster->foe, 250 ); + monster->foe, MONS_PROGRAM_BUG ); read = true; ident = ID_KNOWN_TYPE; } diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc index 4e59545ab5..c12ad69ae6 100644 --- a/crawl-ref/source/mstuff2.cc +++ b/crawl-ref/source/mstuff2.cc @@ -489,7 +489,7 @@ static void do_high_level_summon(monsters *monster, bool monsterNearby, continue; create_monster( which_mons, duration, SAME_ATTITUDE(monster), monster->x, monster->y, - monster->foe, 250 ); + monster->foe, MONS_PROGRAM_BUG ); } } @@ -569,7 +569,8 @@ void mons_cast(monsters *monster, bolt &pbolt, spell_type spell_cast) } create_monster( mons, 5, SAME_ATTITUDE(monster), - monster->x, monster->y, monster->foe, 250 ); + monster->x, monster->y, monster->foe, + MONS_PROGRAM_BUG ); } return; @@ -582,7 +583,8 @@ void mons_cast(monsters *monster, bolt &pbolt, spell_type spell_cast) for (sumcount = 0; sumcount < sumcount2; sumcount++) { create_monster( RANDOM_MONSTER, 5, SAME_ATTITUDE(monster), - monster->x, monster->y, monster->foe, 250 ); + monster->x, monster->y, monster->foe, + MONS_PROGRAM_BUG ); } return; @@ -593,7 +595,7 @@ void mons_cast(monsters *monster, bolt &pbolt, spell_type spell_cast) { create_monster( MONS_RAKSHASA_FAKE, 3, SAME_ATTITUDE(monster), monster->x, monster->y, - monster->foe, 250 ); + monster->foe, MONS_PROGRAM_BUG ); } return; @@ -608,7 +610,7 @@ void mons_cast(monsters *monster, bolt &pbolt, spell_type spell_cast) { create_monster( summon_any_demon(DEMON_COMMON), duration, SAME_ATTITUDE(monster), monster->x, monster->y, - monster->foe, 250 ); + monster->foe, MONS_PROGRAM_BUG ); } return; @@ -626,7 +628,7 @@ void mons_cast(monsters *monster, bolt &pbolt, spell_type spell_cast) { create_monster( summon_any_demon(DEMON_LESSER), duration, SAME_ATTITUDE(monster), monster->x, monster->y, - monster->foe, 250 ); + monster->foe, MONS_PROGRAM_BUG ); } return; @@ -638,18 +640,21 @@ void mons_cast(monsters *monster, bolt &pbolt, spell_type spell_cast) for (sumcount = 0; sumcount < sumcount2; sumcount++) { create_monster( MONS_UFETUBUS, duration, SAME_ATTITUDE(monster), - monster->x, monster->y, monster->foe, 250 ); + monster->x, monster->y, monster->foe, + MONS_PROGRAM_BUG ); } return; case SPELL_SUMMON_BEAST: // Geryon create_monster( MONS_BEAST, 4, SAME_ATTITUDE(monster), - monster->x, monster->y, monster->foe, 250 ); + monster->x, monster->y, monster->foe, + MONS_PROGRAM_BUG ); return; case SPELL_SUMMON_ICE_BEAST: create_monster( MONS_ICE_BEAST, 5, SAME_ATTITUDE(monster), - monster->x, monster->y, monster->foe, 250 ); + monster->x, monster->y, monster->foe, + MONS_PROGRAM_BUG ); return; case SPELL_SUMMON_MUSHROOMS: // Summon swarms of icky crawling fungi. @@ -664,7 +669,7 @@ void mons_cast(monsters *monster, bolt &pbolt, spell_type spell_cast) SAME_ATTITUDE(monster), monster->x, monster->y, monster->foe, - 250); + MONS_PROGRAM_BUG); return; case SPELL_SUMMON_WRAITHS: @@ -703,7 +708,7 @@ void mons_cast(monsters *monster, bolt &pbolt, spell_type spell_cast) { create_monster( summon_any_demon(DEMON_GREATER), duration, SAME_ATTITUDE(monster), monster->x, monster->y, - monster->foe, 250 ); + monster->foe, MONS_PROGRAM_BUG ); } return; @@ -735,7 +740,8 @@ void mons_cast(monsters *monster, bolt &pbolt, spell_type spell_cast) { create_monster( monsters[i], duration, SAME_ATTITUDE(monster), - monster->x, monster->y, monster->foe, 250 ); + monster->x, monster->y, monster->foe, + MONS_PROGRAM_BUG ); } } return; @@ -1070,17 +1076,25 @@ void setup_dragon(struct monsters *monster, struct bolt &pbolt) pbolt.thrower = KILL_MON; pbolt.is_beam = true; - // accuracy is halved if you're wielding a weapon of dragon slaying - // (which makes the dragon/draconian avoid looking at you) + // accuracy is halved if the dragon is attacking a target that's + // wielding a weapon of dragon slaying (which makes the + // dragon/draconian avoid looking at the foe). + // + // [ds] FIXME: This effect seems too strong. Perhaps use 75% of + // original to-hit instead of 50%. if ((mons_genus(monster->type) == MONS_DRAGON - || mons_genus(monster->type) == MONS_DRACONIAN) - && you.equip[EQ_WEAPON] - && get_weapon_brand(you.inv[you.equip[EQ_WEAPON]]) - == SPWPN_DRAGON_SLAYING) + || mons_genus(monster->type) == MONS_DRACONIAN)) { - pbolt.hit /= 2; + if (actor *foe = monster->get_foe()) + { + if (const item_def *weapon = foe->weapon()) + { + if (get_weapon_brand(*weapon) == SPWPN_DRAGON_SLAYING) + pbolt.hit /= 2; + } + } } -} // end setup_dragon(); +} void setup_generic_throw(struct monsters *monster, struct bolt &pbolt) { @@ -2247,7 +2261,7 @@ bool silver_statue_effects(monsters *mons) : DEMON_LESSER)), 5, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250 ); + MHITYOU, MONS_PROGRAM_BUG ); return (true); } return (false); diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 8d622730f4..982f0460d0 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -2062,7 +2062,8 @@ static bool tso_retribution() for (int i = 0; i < how_many; i++) if (create_monster( MONS_DAEVA, 0, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250) != -1) + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG ) != -1) success = true; simple_god_message( success ? @@ -2125,7 +2126,8 @@ static bool zin_retribution() for (int i = 0; i < how_many; i++) if (create_monster(MONS_ANGEL, 0, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250) != -1) + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG) != -1) success = true; simple_god_message( success ? @@ -2166,7 +2168,7 @@ static bool makhleb_retribution() { const bool success = create_monster(MONS_EXECUTIONER + random2(5), 0, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250) != -1; + MHITYOU, MONS_PROGRAM_BUG) != -1; simple_god_message(success ? " sends a greater servant after you!" : "'s greater servant is unavoidably detained.", @@ -2179,7 +2181,8 @@ static bool makhleb_retribution() for (int i = 0; i < how_many; i++) if (create_monster(MONS_NEQOXEC + random2(5), 0, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250) != -1) + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG) != -1) success = true; simple_god_message(success ? @@ -2203,7 +2206,7 @@ static bool kikubaaqudgha_retribution() for (int i = 0; i < how_many; i++) if (create_monster(MONS_REAPER, 0, BEH_HOSTILE, you.x_pos, - you.y_pos, MHITYOU, 250) != -1) + you.y_pos, MHITYOU, MONS_PROGRAM_BUG) != -1) success = true; if (success) @@ -2238,7 +2241,8 @@ static bool yredelemnul_retribution() monster_type punisher = random_servant(GOD_YREDELEMNUL); if (create_monster(punisher, 0, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250) != -1) + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG) != -1) count++; } @@ -2387,7 +2391,8 @@ static bool beogh_retribution() // now create monster int mons = create_monster( MONS_DANCING_WEAPON, 0, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250 ); + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG ); // hand item information over to monster if (mons != -1) @@ -2439,8 +2444,10 @@ static bool beogh_retribution() else punisher = MONS_ORC; - bool success = (create_monster(punisher, 0, BEH_HOSTILE, you.x_pos, - you.y_pos, MHITYOU, 250, true) != -1); + bool success = + (create_monster(punisher, 0, BEH_HOSTILE, you.x_pos, + you.y_pos, MHITYOU, + MONS_PROGRAM_BUG, true) != -1); simple_god_message(success ? " sends forth an army of orcs." : @@ -2465,7 +2472,8 @@ static bool okawaru_retribution() monster_type punisher = random_servant(GOD_OKAWARU); if (create_monster(punisher, 0, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250) != -1) + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG) != -1) success = true; } @@ -2554,7 +2562,7 @@ static bool lugonu_retribution() { if (create_monster(MONS_GREEN_DEATH + random2(3), 0, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250) != -1) + MHITYOU, MONS_PROGRAM_BUG) != -1) { simple_god_message(" sends a demon after you!", god); } @@ -2571,7 +2579,8 @@ static bool lugonu_retribution() for (int loopy = 0; loopy < how_many; loopy++) { if (create_monster(MONS_NEQOXEC + random2(5), 0, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250) != -1) + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG) != -1) { success = true; } diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index d01dd30478..78d648f4ad 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -1375,7 +1375,8 @@ int summon_elemental(int pow, int restricted_type, || random2(100) < unfriendly) { summ_success = create_monster( type_summoned, numsc, BEH_HOSTILE, - targ_x, targ_y, MHITYOU, 250, + targ_x, targ_y, MHITYOU, + MONS_PROGRAM_BUG, false, false, false, true); if (summ_success >= 0) @@ -1384,7 +1385,8 @@ int summon_elemental(int pow, int restricted_type, else { summ_success = create_monster( type_summoned, numsc, BEH_FRIENDLY, - targ_x, targ_y, you.pet_target, 250, + targ_x, targ_y, you.pet_target, + MONS_PROGRAM_BUG, false, false, false, true); } @@ -1433,8 +1435,8 @@ void summon_small_mammals(int pow) } create_monster( thing_called, 3, BEH_FRIENDLY, - you.x_pos, you.y_pos, you.pet_target, 250, - false, false, false, true); + you.x_pos, you.y_pos, you.pet_target, + MONS_PROGRAM_BUG, false, false, false, true); } } // end summon_small_mammals() @@ -1474,12 +1476,12 @@ void summon_animals(int pow) if ( random2(pow) < 5 ) // unfriendly create_monster( mon_chosen, 4, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250, - false, false, false, true); + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG, false, false, false, true); else create_monster( mon_chosen, 4, BEH_FRIENDLY, - you.x_pos, you.y_pos, you.pet_target, 250, - false, false, false, true); + you.x_pos, you.y_pos, you.pet_target, + MONS_PROGRAM_BUG, false, false, false, true); } } @@ -1495,8 +1497,8 @@ void summon_scorpions(int pow) { const int mindex = create_monster( MONS_SCORPION, 3, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250, - false, false, false, true); + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG, false, false, false, true); if (mindex != -1) mpr("A scorpion appears. It doesn't look very happy."); } @@ -1504,7 +1506,7 @@ void summon_scorpions(int pow) { if (create_monster( MONS_SCORPION, 3, BEH_FRIENDLY, you.x_pos, you.y_pos, - you.pet_target, 250, + you.pet_target, MONS_PROGRAM_BUG, false, false, false, true) != -1) { mpr("A scorpion appears."); @@ -1555,8 +1557,8 @@ void summon_ice_beast_etc(int pow, int ibc, bool divine_gift) } - create_monster( ibc, numsc, beha, you.x_pos, you.y_pos, MHITYOU, 250, - false, false, false, true); + create_monster( ibc, numsc, beha, you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG, false, false, false, true); } // end summon_ice_beast_etc() // Trog sends some fighting buddies for his followers (or enemies if @@ -1616,7 +1618,7 @@ bool summon_berserker(int pow, bool god_gift) } int mons = create_monster( mon, numsc, beha, you.x_pos, you.y_pos, - MHITYOU, 250 ); + MHITYOU, MONS_PROGRAM_BUG ); if (mons != -1) { @@ -1707,8 +1709,8 @@ bool summon_swarm( int pow, bool unfriendly, bool god_gift ) behaviour = BEH_FRIENDLY; if (create_monster( thing_called, 3, behaviour, - you.x_pos, you.y_pos, MHITYOU, 250, - false, false, false, true)) + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG, false, false, false, true)) { summoned = true; } @@ -1738,7 +1740,8 @@ void summon_undead(int pow) if (random2(pow) < 6) { if (create_monster( thing_called, 5, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250, + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG, false, false, false, true ) != -1) { mpr("You sense a hostile presence."); @@ -1747,7 +1750,8 @@ void summon_undead(int pow) else { if (create_monster( thing_called, 5, BEH_FRIENDLY, - you.x_pos, you.y_pos, you.pet_target, 250, + you.x_pos, you.y_pos, you.pet_target, + MONS_PROGRAM_BUG, false, false, false, true ) != -1) { mpr("An insubstantial figure forms in the air."); @@ -1799,16 +1803,16 @@ void summon_things( int pow ) { create_monster( MONS_TENTACLED_MONSTROSITY, 6, BEH_FRIENDLY, - you.x_pos, you.y_pos, you.pet_target, 250, - false, false, false, true ); + you.x_pos, you.y_pos, you.pet_target, + MONS_PROGRAM_BUG, false, false, false, true ); big_things--; } while (numsc > 0) { create_monster( MONS_ABOMINATION_LARGE, 6, BEH_FRIENDLY, - you.x_pos, you.y_pos, you.pet_target, 250, - false, false, false, true ); + you.x_pos, you.y_pos, you.pet_target, + MONS_PROGRAM_BUG, false, false, false, true ); numsc--; } diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index aa818273cf..f98bfa4981 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -467,7 +467,7 @@ void cast_summon_butterflies(int pow) for (int scount = 1; scount < num; scount++) { create_monster( MONS_BUTTERFLY, 3, BEH_FRIENDLY, - you.x_pos, you.y_pos, MHITYOU, 250, + you.x_pos, you.y_pos, MHITYOU, MONS_PROGRAM_BUG, false, false, false, true ); } } @@ -506,7 +506,7 @@ void cast_summon_large_mammal(int pow) } create_monster( mon, 3, BEH_FRIENDLY, you.x_pos, you.y_pos, - you.pet_target, 250, + you.pet_target, MONS_PROGRAM_BUG, false, false, false, true ); } @@ -548,7 +548,7 @@ void cast_sticks_to_snakes(int pow) } if (create_monster( mon, dur, behaviour, you.x_pos, you.y_pos, - MHITYOU, 250, + MHITYOU, MONS_PROGRAM_BUG, false, false, false, true ) != -1) { how_many++; @@ -594,8 +594,8 @@ void cast_sticks_to_snakes(int pow) if (pow > 20 && one_chance_in(3)) mon = MONS_BROWN_SNAKE; - create_monster(mon, dur, behaviour, you.x_pos, you.y_pos, MHITYOU, 250, - false, false, false, true); + create_monster(mon, dur, behaviour, you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG, false, false, false, true); } if (how_many > you.inv[you.equip[EQ_WEAPON]].quantity) @@ -628,7 +628,7 @@ void cast_summon_dragon(int pow) if (create_monster( MONS_DRAGON, 3, (happy ? BEH_FRIENDLY : BEH_HOSTILE), - you.x_pos, you.y_pos, MHITYOU, 250, + you.x_pos, you.y_pos, MHITYOU, MONS_PROGRAM_BUG, false, false, false, true) != -1) { mprf("A dragon appears.%s", @@ -673,7 +673,7 @@ void cast_conjure_ball_lightning( int pow ) true, tx, ty ); // int mon = create_monster( MONS_BALL_LIGHTNING, 0, BEH_FRIENDLY, - // tx, ty, MHITNOT, 250 ); + // tx, ty, MHITNOT, MONS_PROGRAM_BUG ); if (mon != -1) { @@ -1954,7 +1954,7 @@ void cast_fulsome_distillation( int powc ) void make_shuggoth(int x, int y, int hp) { int mon = create_monster( MONS_SHUGGOTH, 100 + random2avg(58, 3), - BEH_HOSTILE, x, y, MHITNOT, 250, + BEH_HOSTILE, x, y, MHITNOT, MONS_PROGRAM_BUG, false, false, false, true ); if (mon != -1) diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc index 05f2e17054..e191e70d88 100644 --- a/crawl-ref/source/spl-cast.cc +++ b/crawl-ref/source/spl-cast.cc @@ -1512,7 +1512,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) mpr("You don't feel so good about this..."); create_monster( summon_any_demon(DEMON_GREATER), 5, dem_beh, - you.x_pos, you.y_pos, MHITYOU, 250 ); + you.x_pos, you.y_pos, MHITYOU, MONS_PROGRAM_BUG ); } break; @@ -1723,7 +1723,8 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) { mpr( "Wisps of shadow whirl around you..." ); create_monster( RANDOM_MONSTER, 2, BEH_FRIENDLY, - you.x_pos, you.y_pos, you.pet_target, 250 ); + you.x_pos, you.y_pos, you.pet_target, + MONS_PROGRAM_BUG ); break; } //jmf: new spells 19mar2000 @@ -2285,7 +2286,7 @@ static void miscast_translocation(int severity, const char* cause) case 5: mpr("Space twists in upon itself!"); create_monster( MONS_SPATIAL_VORTEX, 3, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250 ); + you.x_pos, you.y_pos, MHITYOU, MONS_PROGRAM_BUG ); break; } break; @@ -2319,7 +2320,7 @@ static void miscast_translocation(int severity, const char* cause) { create_monster( MONS_SPATIAL_VORTEX, 3, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250 ); + MHITYOU, MONS_PROGRAM_BUG ); } } break; @@ -2412,14 +2413,14 @@ static void miscast_summoning(int severity, const char* cause) case 3: mpr("Space twists in upon itself!"); create_monster( MONS_SPATIAL_VORTEX, 3, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250 ); + you.x_pos, you.y_pos, MHITYOU, MONS_PROGRAM_BUG ); break; case 4: case 5: if (create_monster( summon_any_demon(DEMON_LESSER), 5, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250 ) != -1) + MHITYOU, MONS_PROGRAM_BUG ) != -1) { mpr("Something appears in a flash of light!"); } @@ -2438,7 +2439,7 @@ static void miscast_summoning(int severity, const char* cause) { create_monster( MONS_SPATIAL_VORTEX, 3, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250 ); + MHITYOU, MONS_PROGRAM_BUG ); } } break; @@ -2447,7 +2448,7 @@ static void miscast_summoning(int severity, const char* cause) case 2: if (create_monster( summon_any_demon(DEMON_COMMON), 5, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250) != -1) + MHITYOU, MONS_PROGRAM_BUG) != -1) { mpr("Something forms out of thin air!"); } @@ -2459,24 +2460,24 @@ static void miscast_summoning(int severity, const char* cause) mpr("A chorus of chattering voices calls out to you!"); create_monster( summon_any_demon(DEMON_LESSER), 5, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250 ); + MHITYOU, MONS_PROGRAM_BUG ); create_monster( summon_any_demon(DEMON_LESSER), 5, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250 ); + MHITYOU, MONS_PROGRAM_BUG ); if (coinflip()) { create_monster( summon_any_demon(DEMON_LESSER), 5, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250 ); + MHITYOU, MONS_PROGRAM_BUG ); } if (coinflip()) { create_monster( summon_any_demon(DEMON_LESSER), 5, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250 ); + MHITYOU, MONS_PROGRAM_BUG ); } break; } @@ -2487,7 +2488,8 @@ static void miscast_summoning(int severity, const char* cause) { case 0: if (create_monster( MONS_ABOMINATION_SMALL, 0, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250 ) != -1) + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG ) != -1) { mpr("Something forms out of thin air."); } @@ -2496,7 +2498,7 @@ static void miscast_summoning(int severity, const char* cause) case 1: if (create_monster( summon_any_demon(DEMON_GREATER), 0, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250 ) != -1) + MHITYOU, MONS_PROGRAM_BUG ) != -1) { mpr("You sense a hostile presence."); } @@ -2507,17 +2509,17 @@ static void miscast_summoning(int severity, const char* cause) create_monster( summon_any_demon(DEMON_COMMON), 3, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250 ); + MHITYOU, MONS_PROGRAM_BUG ); create_monster( summon_any_demon(DEMON_COMMON), 3, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250); + MHITYOU, MONS_PROGRAM_BUG ); if (coinflip()) { create_monster(summon_any_demon(DEMON_COMMON), 3, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250); + MHITYOU, MONS_PROGRAM_BUG); } break; @@ -2719,18 +2721,20 @@ static void miscast_necromancy(int severity, const char* cause) mpr("Flickering shadows surround you."); create_monster( MONS_SHADOW, 2, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250 ); + you.x_pos, you.y_pos, MHITYOU, MONS_PROGRAM_BUG ); if (coinflip()) { create_monster( MONS_SHADOW, 2, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250 ); + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG ); } if (coinflip()) { create_monster( MONS_SHADOW, 2, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250 ); + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG ); } break; @@ -2785,7 +2789,8 @@ static void miscast_necromancy(int severity, const char* cause) case 4: if (create_monster( MONS_SOUL_EATER, 4, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250) != -1) + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG) != -1) { mpr("Something reaches out for you..."); } @@ -2793,7 +2798,8 @@ static void miscast_necromancy(int severity, const char* cause) case 5: if (create_monster( MONS_REAPER, 4, BEH_HOSTILE, - you.x_pos, you.y_pos, MHITYOU, 250) != -1) + you.x_pos, you.y_pos, MHITYOU, + MONS_PROGRAM_BUG) != -1) { mpr("Death has come for you..."); } diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc index c6ec9d920b..800ff8867a 100644 --- a/crawl-ref/source/xom.cc +++ b/crawl-ref/source/xom.cc @@ -558,7 +558,8 @@ static bool xom_is_good(int sever) for (int i = 0; i < numdemons; i++) { create_monster(xom_random_demon(sever), 3, BEH_GOD_GIFT, - you.x_pos, you.y_pos, you.pet_target, 250 ); + you.x_pos, you.y_pos, you.pet_target, + MONS_PROGRAM_BUG); } done = true; @@ -571,7 +572,8 @@ static bool xom_is_good(int sever) else if (random2(sever) <= 5) { if (create_monster(xom_random_demon(sever), 6, BEH_GOD_GIFT, - you.x_pos, you.y_pos, you.pet_target, 250) != -1) + you.x_pos, you.y_pos, you.pet_target, + MONS_PROGRAM_BUG) != -1) { temp_rand = random2(3); @@ -634,7 +636,8 @@ static bool xom_is_good(int sever) { if (create_monster( xom_random_demon(sever, one_chance_in(8)), 0, BEH_GOD_GIFT, - you.x_pos, you.y_pos, you.pet_target, 250 ) != -1) + you.x_pos, you.y_pos, you.pet_target, + MONS_PROGRAM_BUG ) != -1) { temp_rand = random2(3); god_speaks(GOD_XOM, @@ -840,7 +843,7 @@ static bool xom_is_bad(int sever) create_monster( xom_random_punishment_demon(sever), 4, BEH_HOSTILE, you.x_pos, you.y_pos, - MHITNOT, 250); + MHITNOT, MONS_PROGRAM_BUG); } } |