diff options
author | Adam Borowski <kilobyte@angband.pl> | 2009-11-08 20:04:10 +0100 |
---|---|---|
committer | Adam Borowski <kilobyte@angband.pl> | 2009-11-08 20:04:10 +0100 |
commit | 58b3ab725dec733191e76dcfa02243cc6b0ce3ac (patch) | |
tree | 1224e162ace233f3782645af45946b6b10ace2a8 | |
parent | 44191bee0ba18382a7c38cac428375d480d15af8 (diff) | |
download | crawl-ref-58b3ab725dec733191e76dcfa02243cc6b0ce3ac.tar.gz crawl-ref-58b3ab725dec733191e76dcfa02243cc6b0ce3ac.zip |
Split away monsters' starting gear from makeitem.cc to mon-gear.cc
-rw-r--r-- | crawl-ref/source/makefile.obj | 1 | ||||
-rw-r--r-- | crawl-ref/source/makeitem.cc | 1517 | ||||
-rw-r--r-- | crawl-ref/source/makeitem.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/mon-gear.cc | 1535 | ||||
-rw-r--r-- | crawl-ref/source/mon-gear.h | 12 | ||||
-rw-r--r-- | crawl-ref/source/monplace.cc | 1 |
6 files changed, 1553 insertions, 1516 deletions
diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj index eee65cc43f..b948deb7a4 100644 --- a/crawl-ref/source/makefile.obj +++ b/crawl-ref/source/makefile.obj @@ -101,6 +101,7 @@ mon-abil.o \ mon-act.o \ mon-behv.o \ mon-cast.o \ +mon-gear.o \ mon-info.o \ mon-pick.o \ mon-util.o \ diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc index 9f1a34af1d..d302dadc68 100644 --- a/crawl-ref/source/makeitem.cc +++ b/crawl-ref/source/makeitem.cc @@ -32,7 +32,7 @@ void item_set_appearance(item_def &item); -static bool _got_curare_roll(const int item_level) +bool got_curare_roll(const int item_level) { return one_chance_in(item_level > 27 ? 6 : item_level < 2 ? 15 : @@ -1819,7 +1819,7 @@ static special_missile_type _determine_missile_brand(const item_def& item, // All needles are either poison or curare. if (item.sub_type == MI_NEEDLE) - rc = _got_curare_roll(item_level) ? SPMSL_CURARE : SPMSL_POISONED; + rc = got_curare_roll(item_level) ? SPMSL_CURARE : SPMSL_POISONED; else { const int temp_rand = @@ -3241,1519 +3241,6 @@ static bool _armour_is_visibly_special(const item_def &item) return (false); } -static void _give_monster_item(monsters *mon, int thing, - bool force_item = false, - bool (monsters::*pickupfn)(item_def&, int) = NULL) -{ - if (thing == NON_ITEM || thing == -1) - return; - - item_def &mthing = mitm[thing]; - ASSERT(mthing.is_valid()); - -#ifdef DEBUG_DIAGNOSTICS - mprf(MSGCH_DIAGNOSTICS, - "Giving %s to %s...", mthing.name(DESC_PLAIN).c_str(), - mon->name(DESC_PLAIN, true).c_str()); -#endif - - mthing.pos.reset(); - mthing.link = NON_ITEM; - unset_ident_flags(mthing, ISFLAG_IDENT_MASK); - - if (mon->is_unholy() - && (is_blessed_blade(mthing) - || get_weapon_brand(mthing) == SPWPN_HOLY_WRATH)) - { - if (is_blessed_blade(mthing)) - convert2bad(mthing); - if (get_weapon_brand(mthing) == SPWPN_HOLY_WRATH) - set_item_ego_type(mthing, OBJ_WEAPONS, SPWPN_NORMAL); - } - - unwind_var<int> save_speedinc(mon->speed_increment); - if (!(pickupfn ? (mon->*pickupfn)(mthing, false) - : mon->pickup_item(mthing, false, true))) - { -#ifdef DEBUG_DIAGNOSTICS - mprf(MSGCH_DIAGNOSTICS, "Destroying %s because %s doesn't want it!", - mthing.name(DESC_PLAIN, false, true).c_str(), - mon->name(DESC_PLAIN, true).c_str()); -#endif - destroy_item(thing, true); - return; - } - if (!mthing.is_valid()) // missiles merged into an existing stack - return; - ASSERT(mthing.holding_monster() == mon); - - if (!force_item || mthing.colour == BLACK) - item_colour(mthing); -} - -static void _give_scroll(monsters *mon, int level) -{ - int thing_created = NON_ITEM; - - if (mon->type == MONS_ROXANNE) - { - // Not a scroll, but this comes closest. - int which_book = (one_chance_in(3) ? BOOK_TRANSFIGURATIONS - : BOOK_EARTH); - - thing_created = items(0, OBJ_BOOKS, which_book, true, level, 0); - - if (thing_created != NON_ITEM && coinflip()) - { - // Give Roxanne a random book containing Statue Form instead. - item_def &item(mitm[thing_created]); - make_book_Roxanne_special(&item); - _give_monster_item(mon, thing_created, true); - return; - } - } - else if (mons_is_unique(mon->type) && one_chance_in(3)) - thing_created = items(0, OBJ_SCROLLS, OBJ_RANDOM, true, level, 0); - - if (thing_created == NON_ITEM) - return; - - mitm[thing_created].flags = 0; - _give_monster_item(mon, thing_created, true); -} - -static void _give_wand(monsters *mon, int level) -{ - if (mons_is_unique(mon->type) && !mons_class_flag(mon->type, M_NO_WAND) - && (one_chance_in(5) || mon->type == MONS_MAURICE && one_chance_in(3))) - { - const int idx = items(0, OBJ_WANDS, OBJ_RANDOM, true, level, 0); - - if (idx == NON_ITEM) - return; - - item_def& wand = mitm[idx]; - - // Don't give top-tier wands before 5 HD. - if (mon->hit_dice < 5 || mons_class_flag(mon->type, M_NO_HT_WAND)) - { - // Technically these wands will be undercharged, but it - // doesn't really matter. - if (wand.sub_type == WAND_FIRE) - wand.sub_type = WAND_FLAME; - - if (wand.sub_type == WAND_COLD) - wand.sub_type = WAND_FROST; - - if (wand.sub_type == WAND_LIGHTNING) - wand.sub_type = (coinflip() ? WAND_FLAME : WAND_FROST); - } - - wand.flags = 0; - _give_monster_item(mon, idx); - } -} - -static void _give_potion(monsters *mon, int level) -{ - if (mons_species(mon->type) == MONS_VAMPIRE && one_chance_in(5)) - { - // This handles initialization of stack timer. - const int thing_created = - items(0, OBJ_POTIONS, POT_BLOOD, true, level, 0); - - if (thing_created == NON_ITEM) - return; - - mitm[thing_created].flags = 0; - _give_monster_item(mon, thing_created); - } - else if (mons_is_unique(mon->type) && one_chance_in(3)) - { - const int thing_created = - items(0, OBJ_POTIONS, OBJ_RANDOM, true, level, 0); - - if (thing_created == NON_ITEM) - return; - - mitm[thing_created].flags = 0; - _give_monster_item(mon, thing_created, false, - &monsters::pickup_potion); - } -} - -static item_make_species_type _give_weapon(monsters *mon, int level, - bool melee_only = false, - bool give_aux_melee = true) -{ - bool force_item = false; - - item_def item; - item_make_species_type item_race = MAKE_ITEM_RANDOM_RACE; - - item.base_type = OBJ_UNASSIGNED; - - if (mon->type == MONS_DANCING_WEAPON - && player_in_branch(BRANCH_HALL_OF_BLADES)) - { - level = MAKE_GOOD_ITEM; - } - - // moved setting of quantity here to keep it in mind {dlb} - item.quantity = 1; - - switch (mon->type) - { - case MONS_KOBOLD: - // A few of the smarter kobolds have blowguns. - if (one_chance_in(10) && level > 1) - { - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_BLOWGUN; - break; - } - // intentional fallthrough - case MONS_BIG_KOBOLD: - if (x_chance_in_y(3, 5)) // give hand weapon - { - item.base_type = OBJ_WEAPONS; - item.sub_type = random_choose(WPN_DAGGER, WPN_DAGGER, - WPN_SHORT_SWORD, WPN_SHORT_SWORD, - WPN_CLUB, WPN_WHIP, -1); - } - else - return (item_race); - break; - - case MONS_HOBGOBLIN: - if (one_chance_in(3)) - item_race = MAKE_ITEM_ORCISH; - - if (x_chance_in_y(3, 5)) // give hand weapon - { - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_CLUB; - } - else - return (item_race); - break; - - case MONS_GOBLIN: - if (one_chance_in(3)) - item_race = MAKE_ITEM_ORCISH; - - if (!melee_only && one_chance_in(12) && level) - { - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_SLING; - break; - } - // deliberate fall through {dlb} - case MONS_JESSICA: - case MONS_IJYB: - if (x_chance_in_y(3, 5)) // give hand weapon - { - item.base_type = OBJ_WEAPONS; - item.sub_type = (coinflip() ? WPN_DAGGER : WPN_CLUB); - } - else - return (item_race); - break; - - case MONS_WIGHT: - case MONS_NORRIS: - item.base_type = OBJ_WEAPONS; - - if (one_chance_in(6)) - { - item.sub_type = random_choose(WPN_SPIKED_FLAIL, WPN_GREAT_MACE, - WPN_WAR_AXE, WPN_TRIDENT, -1); - } - else - { - item.sub_type = random_choose( - WPN_MACE, WPN_FLAIL, WPN_MORNINGSTAR, - WPN_DAGGER, WPN_SHORT_SWORD, WPN_LONG_SWORD, - WPN_SCIMITAR, WPN_GREAT_SWORD, WPN_HAND_AXE, - WPN_BATTLEAXE, WPN_SPEAR, WPN_HALBERD, - -1); - } - - if (coinflip()) - { - force_item = true; - item.plus += 1 + random2(3); - item.plus2 += 1 + random2(3); - - if (one_chance_in(5)) - set_item_ego_type(item, OBJ_WEAPONS, SPWPN_FREEZING); - } - - if (one_chance_in(3)) - do_curse_item(item); - break; - - case MONS_AIZUL: - if (one_chance_in(3)) - level = MAKE_GOOD_ITEM; - - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = random_choose(WPN_HALBERD, WPN_SCIMITAR, WPN_GREAT_MACE, - WPN_LONG_SWORD, WPN_EVENINGSTAR, -1); - break; - - case MONS_GNOLL: - case MONS_OGRE_MAGE: - case MONS_NAGA_WARRIOR: - case MONS_GREATER_NAGA: - case MONS_EDMUND: - case MONS_DUANE: - item_race = MAKE_ITEM_NO_RACE; - if (!one_chance_in(5)) - { - item.base_type = OBJ_WEAPONS; - item.sub_type = random_choose(WPN_SPEAR, WPN_SPEAR, WPN_HALBERD, - WPN_CLUB, WPN_WHIP, WPN_FLAIL, -1); - } - break; - - case MONS_PIKEL: - force_item = true; // guaranteed flaming or pain - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_WHIP; - set_item_ego_type(item, OBJ_WEAPONS, coinflip() ? SPWPN_PAIN : SPWPN_FLAMING); - item.plus += random2(3); - item.plus2 += random2(3); - break; - - case MONS_GRUM: - force_item = true; // guaranteed reaching - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = random_choose(WPN_WHIP, WPN_WHIP, WPN_SPEAR, - WPN_HALBERD, WPN_GLAIVE, -1); - set_item_ego_type(item, OBJ_WEAPONS, SPWPN_REACHING); - item.plus += -2 + random2(4); - item.plus2 += -1 + random2(2); - break; - - case MONS_ORC: - case MONS_ORC_PRIEST: - item_race = MAKE_ITEM_ORCISH; - // deliberate fall through {gdl} - - case MONS_DRACONIAN: - case MONS_DRACONIAN_ZEALOT: - if (!one_chance_in(5)) - { - item.base_type = OBJ_WEAPONS; - item.sub_type = random_choose_weighted( - 30, WPN_DAGGER, 30, WPN_CLUB, - 27, WPN_FLAIL, 24, WPN_HAND_AXE, - 20, WPN_HAMMER, 20, WPN_SHORT_SWORD, - 20, WPN_MACE, 10, WPN_WHIP, - 10, WPN_TRIDENT, 10, WPN_FALCHION, - 10, WPN_MORNINGSTAR, 6, WPN_WAR_AXE, - 3, WPN_SPIKED_FLAIL, - 0); - } - else - return (item_race); - break; - - case MONS_TERENCE: - item.base_type = OBJ_WEAPONS; - item.sub_type = random_choose_weighted( 30, WPN_FLAIL, - 20, WPN_HAND_AXE, - 20, WPN_SHORT_SWORD, - 20, WPN_MACE, - 10, WPN_TRIDENT, - 10, WPN_FALCHION, - 10, WPN_MORNINGSTAR, - 3, WPN_SPIKED_FLAIL, - 0); - break; - - case MONS_DUVESSA: - item_race = MAKE_ITEM_ELVEN; - item.base_type = OBJ_WEAPONS; - item.sub_type = random_choose_weighted(30, WPN_SHORT_SWORD, - 10, WPN_SABRE, - 0); - break; - - case MONS_DEEP_ELF_FIGHTER: - case MONS_DEEP_ELF_HIGH_PRIEST: - case MONS_DEEP_ELF_KNIGHT: - case MONS_DEEP_ELF_PRIEST: - case MONS_DEEP_ELF_SOLDIER: - item_race = MAKE_ITEM_ELVEN; - item.base_type = OBJ_WEAPONS; - item.sub_type = random_choose_weighted( - 20, WPN_LONG_SWORD, 20, WPN_SHORT_SWORD, 14, WPN_SCIMITAR, - 14, WPN_MACE, 13, WPN_BOW, 13, WPN_HAND_CROSSBOW, - 5, WPN_LONGBOW, - 0); - break; - - case MONS_DEEP_ELF_BLADEMASTER: - { - item_race = MAKE_ITEM_ELVEN; - item.base_type = OBJ_WEAPONS; - - // If the blademaster already has a weapon, give him the exact same - // sub_type to match. - - const item_def *weap = mon->mslot_item(MSLOT_WEAPON); - if (weap && weap->base_type == OBJ_WEAPONS) - item.sub_type = weap->sub_type; - else - { - item.sub_type = random_choose_weighted(40, WPN_SABRE, - 10, WPN_SHORT_SWORD, - 2, WPN_QUICK_BLADE, - 0); - } - break; - } - - case MONS_DEEP_ELF_MASTER_ARCHER: - item_race = MAKE_ITEM_ELVEN; - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_LONGBOW; - break; - - case MONS_DEEP_ELF_ANNIHILATOR: - case MONS_DEEP_ELF_CONJURER: - case MONS_DEEP_ELF_DEATH_MAGE: - case MONS_DEEP_ELF_DEMONOLOGIST: - case MONS_DEEP_ELF_MAGE: - case MONS_DEEP_ELF_SORCERER: - case MONS_DEEP_ELF_SUMMONER: - item_race = MAKE_ITEM_ELVEN; - // deliberate fall-through - - case MONS_DRACONIAN_SHIFTER: - case MONS_DRACONIAN_SCORCHER: - case MONS_DRACONIAN_ANNIHILATOR: - case MONS_DRACONIAN_CALLER: - item.base_type = OBJ_WEAPONS; - item.sub_type = random_choose(WPN_LONG_SWORD, WPN_LONG_SWORD, - WPN_SHORT_SWORD, WPN_SABRE, - WPN_DAGGER, WPN_WHIP, - -1); - break; - - case MONS_ORC_WARRIOR: - case MONS_ORC_HIGH_PRIEST: - case MONS_BLORK_THE_ORC: - item_race = MAKE_ITEM_ORCISH; - // deliberate fall-through {dlb} - - case MONS_DANCING_WEAPON: // give_level may have been adjusted above - case MONS_FRANCES: - case MONS_FRANCIS: - case MONS_HAROLD: - case MONS_JOSEPH: - case MONS_LOUISE: - case MONS_MICHAEL: - case MONS_NAGA: - case MONS_NAGA_MAGE: - case MONS_RUPERT: - case MONS_SKELETAL_WARRIOR: - case MONS_WAYNE: - case MONS_PALE_DRACONIAN: - case MONS_RED_DRACONIAN: - case MONS_WHITE_DRACONIAN: - case MONS_GREEN_DRACONIAN: - case MONS_MOTTLED_DRACONIAN: - case MONS_BLACK_DRACONIAN: - case MONS_YELLOW_DRACONIAN: - case MONS_PURPLE_DRACONIAN: - case MONS_TIAMAT: - if (mons_genus(mon->type) == MONS_NAGA) - item_race = MAKE_ITEM_NO_RACE; - - item.base_type = OBJ_WEAPONS; - item.sub_type = random_choose_weighted( - 10, WPN_LONG_SWORD, 10, WPN_SHORT_SWORD, - 10, WPN_SCIMITAR, 10, WPN_BATTLEAXE, - 10, WPN_HAND_AXE, 10, WPN_HALBERD, - 10, WPN_GLAIVE, 10, WPN_MORNINGSTAR, - 10, WPN_GREAT_MACE, 10, WPN_TRIDENT, - 9, WPN_WAR_AXE, 9, WPN_FLAIL, - 1, WPN_BROAD_AXE, 1, WPN_SPIKED_FLAIL, - 0); - break; - - case MONS_ORC_WARLORD: - case MONS_SAINT_ROKA: - // being at the top has its privileges - if (one_chance_in(3)) - level = MAKE_GOOD_ITEM; - // deliberate fall-through - - case MONS_ORC_KNIGHT: - item_race = MAKE_ITEM_ORCISH; - // Occasionally get crossbows. - if (!melee_only && one_chance_in(9)) - { - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_CROSSBOW; - break; - } - // deliberate fall-through - - case MONS_URUG: - item_race = MAKE_ITEM_ORCISH; - // deliberate fall-through - - case MONS_NORBERT: - case MONS_JOZEF: - case MONS_VAULT_GUARD: - case MONS_VAMPIRE_KNIGHT: - case MONS_DRACONIAN_KNIGHT: - { - item.base_type = OBJ_WEAPONS; - - item.sub_type = random_choose_weighted( - 4, WPN_GREAT_SWORD, 4, WPN_LONG_SWORD, - 4, WPN_BATTLEAXE, 4, WPN_WAR_AXE, - 3, WPN_GREAT_MACE, 2, WPN_DIRE_FLAIL, - 1, WPN_BARDICHE, 1, WPN_GLAIVE, - 1, WPN_BROAD_AXE, 1, WPN_HALBERD, - 0); - - if (one_chance_in(4)) - item.plus += 1 + random2(3); - break; - } - - case MONS_POLYPHEMUS: - case MONS_CYCLOPS: - case MONS_STONE_GIANT: - item.base_type = OBJ_MISSILES; - item.sub_type = MI_LARGE_ROCK; - break; - - case MONS_TWO_HEADED_OGRE: - case MONS_ETTIN: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = (one_chance_in(3) ? WPN_GIANT_SPIKED_CLUB - : WPN_GIANT_CLUB); - - if (one_chance_in(10) || mon->type == MONS_ETTIN) - { - item.sub_type = (one_chance_in(10) ? WPN_DIRE_FLAIL - : WPN_GREAT_MACE); - } - break; - - case MONS_REAPER: - level = MAKE_GOOD_ITEM; - // intentional fall-through... - - case MONS_SIGMUND: - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_SCYTHE; - break; - - case MONS_BALRUG: - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_DEMON_WHIP; - break; - - case MONS_RED_DEVIL: - if (!one_chance_in(3)) - { - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = (one_chance_in(3) ? WPN_DEMON_TRIDENT - : WPN_TRIDENT); - } - break; - - case MONS_OGRE: - case MONS_HILL_GIANT: - case MONS_EROLCHA: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = (one_chance_in(3) ? WPN_GIANT_SPIKED_CLUB - : WPN_GIANT_CLUB); - - if (one_chance_in(10)) - { - item.sub_type = (one_chance_in(10) ? WPN_DIRE_FLAIL - : WPN_GREAT_MACE); - } - break; - - case MONS_MERFOLK: - if (one_chance_in(3)) - { - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_TRIDENT; - break; - } - // intentionally fall through - - case MONS_MERMAID: - if (one_chance_in(3)) - { - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_SPEAR; - } - break; - - case MONS_CENTAUR: - case MONS_CENTAUR_WARRIOR: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_BOW; - if (mon->type == MONS_CENTAUR_WARRIOR && one_chance_in(3)) - item.sub_type = WPN_LONGBOW; - break; - - case MONS_NESSOS: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_LONGBOW; - item.special = SPWPN_FLAME; - item.plus += 1 + random2(3); - item.plus2 += 1 + random2(3); - item.colour = DARKGREY; - force_item = true; - break; - - case MONS_YAKTAUR: - case MONS_YAKTAUR_CAPTAIN: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_CROSSBOW; - break; - - case MONS_EFREET: - case MONS_ERICA: - case MONS_AZRAEL: - force_item = true; - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_SCIMITAR; - item.plus = random2(5); - item.plus2 = random2(5); - item.colour = RED; // forced by force_item above {dlb} - set_item_ego_type( item, OBJ_WEAPONS, SPWPN_FLAMING ); - break; - - case MONS_ANGEL: - force_item = true; - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.colour = YELLOW; // forced by force_item above {dlb} - - item.sub_type = (one_chance_in(4) ? WPN_GREAT_MACE - : WPN_MACE); - - set_equip_desc(item, ISFLAG_GLOWING); - set_item_ego_type(item, OBJ_WEAPONS, SPWPN_HOLY_WRATH); - item.plus = 1 + random2(3); - item.plus2 = 1 + random2(3); - break; - - case MONS_DAEVA: - force_item = true; - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.colour = YELLOW; // forced by force_item above {dlb} - - item.sub_type = (one_chance_in(4) ? WPN_BLESSED_EUDEMON_BLADE - : WPN_LONG_SWORD); - - set_equip_desc(item, ISFLAG_GLOWING); - set_item_ego_type(item, OBJ_WEAPONS, SPWPN_HOLY_WRATH); - item.plus = 1 + random2(3); - item.plus2 = 1 + random2(3); - break; - - case MONS_HELL_KNIGHT: - case MONS_MAUD: - case MONS_FREDERICK: - case MONS_MARGERY: - force_item = true; - item.base_type = OBJ_WEAPONS; - item.sub_type = (one_chance_in(3) ? WPN_LONG_SWORD : - coinflip() ? WPN_SCIMITAR - : WPN_GREAT_SWORD); - - if (one_chance_in(7)) - item.sub_type = WPN_HALBERD; - if (one_chance_in(7)) - item.sub_type = WPN_GLAIVE; - if (one_chance_in(7)) - item.sub_type = WPN_GREAT_MACE; - if (one_chance_in(7)) - item.sub_type = WPN_BATTLEAXE; - if (one_chance_in(7)) - item.sub_type = WPN_WAR_AXE; - if (one_chance_in(7)) - item.sub_type = WPN_BROAD_AXE; - if (one_chance_in(7)) - item.sub_type = WPN_DEMON_WHIP; - if (one_chance_in(7)) - item.sub_type = WPN_DEMON_BLADE; - if (one_chance_in(7)) - item.sub_type = WPN_DEMON_TRIDENT; - - if (one_chance_in(3)) - set_item_ego_type(item, OBJ_WEAPONS, SPWPN_FLAMING); - else if (one_chance_in(3)) - { - set_item_ego_type(item, OBJ_WEAPONS, - random_choose(SPWPN_DRAINING, SPWPN_VORPAL, - SPWPN_PAIN, SPWPN_DISTORTION, - SPWPN_SPEED, -1)); - } - - item.plus += random2(6); - item.plus2 += random2(6); - - item.colour = RED; // forced by force_item above {dlb} - - if (one_chance_in(3)) - item.colour = DARKGREY; - if (one_chance_in(5)) - item.colour = CYAN; - break; - - case MONS_FIRE_GIANT: - force_item = true; - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_GREAT_SWORD; - item.plus = 0; - item.plus2 = 0; - set_item_ego_type( item, OBJ_WEAPONS, SPWPN_FLAMING ); - - item.colour = RED; // forced by force_item above {dlb} - if (one_chance_in(3)) - item.colour = DARKGREY; - if (one_chance_in(5)) - item.colour = CYAN; - break; - - case MONS_FROST_GIANT: - force_item = true; - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_BATTLEAXE; - item.plus = 0; - item.plus2 = 0; - set_item_ego_type( item, OBJ_WEAPONS, SPWPN_FREEZING ); - - // forced by force_item above {dlb} - item.colour = (one_chance_in(3) ? WHITE : CYAN); - break; - - case MONS_ORC_WIZARD: - case MONS_ORC_SORCERER: - case MONS_NERGALLE: - item_race = MAKE_ITEM_ORCISH; - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_DAGGER; - break; - - case MONS_DOWAN: - item_race = MAKE_ITEM_ELVEN; - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_DAGGER; - break; - - case MONS_KOBOLD_DEMONOLOGIST: - case MONS_NECROMANCER: - case MONS_WIZARD: - case MONS_PSYCHE: - case MONS_DONALD: - case MONS_JOSEPHINE: - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_DAGGER; - - if (mon->type == MONS_PSYCHE) - { - set_item_ego_type(item, OBJ_WEAPONS, - random_choose_weighted(3, SPWPN_CHAOS, - 1, SPWPN_DISTORTION, - 0)); - } - break; - - case MONS_AGNES: - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_LAJATANG; - if (!one_chance_in(3)) - level = MAKE_GOOD_ITEM; - break; - - case MONS_SONJA: - if (!melee_only) - { - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_BLOWGUN; - item_race = MAKE_ITEM_NO_RACE; - break; - } - force_item = true; - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = coinflip() ? WPN_DAGGER : WPN_SHORT_SWORD; - set_item_ego_type(item, OBJ_WEAPONS, - random_choose_weighted(3, SPWPN_DISTORTION, - 2, SPWPN_VENOM, - 1, SPWPN_DRAINING, - 0)); - break; - - case MONS_MAURICE: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = coinflip() ? WPN_DAGGER : WPN_SHORT_SWORD; - break; - - case MONS_EUSTACHIO: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = (one_chance_in(3) ? WPN_FALCHION : WPN_SABRE); - break; - - case MONS_NIKOLA: - force_item = true; - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = WPN_SABRE; - set_item_ego_type(item, OBJ_WEAPONS, SPWPN_ELECTROCUTION); - item.plus = random2(5); - item.plus2 = random2(5); - break; - - case MONS_CEREBOV: - force_item = true; - make_item_unrandart(item, UNRAND_CEREBOV); - break; - - case MONS_DISPATER: - force_item = true; - make_item_unrandart(item, UNRAND_DISPATER); - break; - - case MONS_ASMODEUS: - force_item = true; - make_item_unrandart(item, UNRAND_ASMODEUS); - break; - - case MONS_GERYON: - // mv: Probably should be moved out of this switch, but it's not - // worth it, unless we have more monsters with misc. items. - item.base_type = OBJ_MISCELLANY; - item.sub_type = MISC_HORN_OF_GERYON; - break; - - case MONS_SALAMANDER: // mv: new 8 Aug 2001 - // Yes, they've got really nice items, but - // it's almost impossible to get them. - force_item = true; - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_WEAPONS; - item.sub_type = random_choose(WPN_GREAT_SWORD, WPN_TRIDENT, - WPN_SPEAR, WPN_GLAIVE, - WPN_BOW, WPN_HALBERD, - -1); - - set_item_ego_type(item, OBJ_WEAPONS, is_range_weapon(item) ? - SPWPN_FLAME : SPWPN_FLAMING); - - item.plus = random2(5); - item.plus2 = random2(5); - item.colour = RED; // forced by force_item above {dlb} - break; - - default: - break; - } - - // Only happens if something in above switch doesn't set it. {dlb} - if (item.base_type == OBJ_UNASSIGNED) - return (item_race); - - if (!force_item && mons_is_unique( mon->type )) - { - if (x_chance_in_y(10 + mon->hit_dice, 100)) - level = MAKE_GOOD_ITEM; - else if (level != MAKE_GOOD_ITEM) - level += 5; - } - - const object_class_type xitc = item.base_type; - const int xitt = item.sub_type; - - // Note this mess, all the work above doesn't mean much unless - // force_item is set... otherwise we're just going to take the base - // and subtype and create a new item. - bwr - const int thing_created = - ((force_item) ? get_item_slot() : items(0, xitc, xitt, true, - level, item_race)); - - if (thing_created == NON_ITEM) - return (item_race); - - // Copy temporary item into the item array if were forcing it, since - // items() won't have done it for us. - if (force_item) - mitm[thing_created] = item; - - item_def &i = mitm[thing_created]; - if (melee_only && (i.base_type != OBJ_WEAPONS || is_range_weapon(i))) - { - destroy_item(thing_created); - return (item_race); - } - - if (force_item) - item_set_appearance(i); - - _give_monster_item(mon, thing_created, force_item); - - if (give_aux_melee && (i.base_type != OBJ_WEAPONS || is_range_weapon(i))) - _give_weapon(mon, level, true, false); - - return (item_race); -} - -// Hands out ammunition fitting the monster's launcher (if any), or else any -// throwable weapon depending on the monster type. -static void _give_ammo(monsters *mon, int level, - item_make_species_type item_race, - bool mons_summoned) -{ - // Note that item_race is not reset for this section. - if (const item_def *launcher = mon->launcher()) - { - const object_class_type xitc = OBJ_MISSILES; - int xitt = fires_ammo_type(*launcher); - - if (xitt == MI_STONE && one_chance_in(15)) - xitt = MI_SLING_BULLET; - - const int thing_created = items(0, xitc, xitt, true, level, item_race); - - if (thing_created == NON_ITEM) - return; - - if (xitt == MI_NEEDLE) - { - if (mon->type == MONS_SONJA) - { - set_item_ego_type(mitm[thing_created], OBJ_MISSILES, - SPMSL_CURARE); - - mitm[thing_created].quantity = random_range(4, 10); - } - else - { - set_item_ego_type(mitm[thing_created], OBJ_MISSILES, - _got_curare_roll(level) ? SPMSL_CURARE - : SPMSL_POISONED); - - if (get_ammo_brand( mitm[thing_created] ) == SPMSL_CURARE) - mitm[thing_created].quantity = random_range(2, 8); - } - } - else - { - // Sanity check to avoid useless brands. - const int bow_brand = get_weapon_brand(*launcher); - const int ammo_brand = get_ammo_brand(mitm[thing_created]); - if (ammo_brand != SPMSL_NORMAL - && (bow_brand == SPWPN_FLAME || bow_brand == SPWPN_FROST)) - { - mitm[thing_created].special = SPMSL_NORMAL; - } - } - - // Master archers get double ammo - archery is their only attack. - if (mon->type == MONS_DEEP_ELF_MASTER_ARCHER) - mitm[thing_created].quantity *= 2; - else if (mon->type == MONS_NESSOS) - mitm[thing_created].special = SPMSL_POISONED; - - _give_monster_item(mon, thing_created); - } - else - { - // Give some monsters throwing weapons. - int weap_type = -1; - object_class_type weap_class = OBJ_WEAPONS; - int qty = 0; - switch (mon->type) - { - case MONS_KOBOLD: - case MONS_BIG_KOBOLD: - if (x_chance_in_y(2, 5)) - { - item_race = MAKE_ITEM_NO_RACE; - weap_class = OBJ_MISSILES; - weap_type = MI_DART; - qty = 1 + random2(5); - } - break; - - case MONS_ORC_WARRIOR: - if (one_chance_in( - you.where_are_you == BRANCH_ORCISH_MINES? 9 : 20)) - { - weap_type = random_choose(WPN_HAND_AXE, WPN_SPEAR, -1); - qty = random_range(4, 8); - item_race = MAKE_ITEM_ORCISH; - } - break; - - case MONS_ORC: - if (one_chance_in(20)) - { - weap_type = random_choose(WPN_HAND_AXE, WPN_SPEAR, -1); - qty = random_range(2, 5); - item_race = MAKE_ITEM_ORCISH; - } - break; - - case MONS_URUG: - weap_type = MI_JAVELIN; - weap_class = OBJ_MISSILES; - item_race = MAKE_ITEM_ORCISH; - qty = random_range(4, 7); - break; - - case MONS_MERFOLK: - if (!one_chance_in(3)) - { - item_race = MAKE_ITEM_NO_RACE; - if (coinflip()) - { - weap_type = WPN_SPEAR; - qty = 1 + random2(3); - } - else - { - weap_class = OBJ_MISSILES; - weap_type = MI_JAVELIN; - qty = 3 + random2(6); - } - } - if (one_chance_in(6) && !mons_summoned) - { - weap_class = OBJ_MISSILES; - weap_type = MI_THROWING_NET; - qty = 1; - if (one_chance_in(4)) - qty += random2(3); // up to three nets - } - break; - - case MONS_DRACONIAN_KNIGHT: - case MONS_GNOLL: - case MONS_HILL_GIANT: - if (!one_chance_in(20)) - break; - // deliberate fall-through - - case MONS_HAROLD: // bounty hunters - case MONS_JOZEF: // up to 5 nets - if (mons_summoned) - break; - - weap_class = OBJ_MISSILES; - weap_type = MI_THROWING_NET; - qty = 1; - if (one_chance_in(3)) - qty++; - if (mon->type == MONS_HAROLD || mon->type == MONS_JOZEF) - qty += random2(4); - - break; - - default: - break; - } - - if (weap_type == -1) - return; - - const int thing_created = - items(0, weap_class, weap_type, true, level, item_race); - - if (thing_created != NON_ITEM) - { - item_def& w(mitm[thing_created]); - - // Limit returning brand to only one. - if (weap_type == OBJ_WEAPONS - && get_weapon_brand(w) == SPWPN_RETURNING) - { - qty = 1; - } - - w.quantity = qty; - - _give_monster_item(mon, thing_created, false, - &monsters::pickup_throwable_weapon); - } - } -} - -static bool make_item_for_monster( - monsters *mons, - object_class_type base, - int subtype, - int level, - item_make_species_type race = MAKE_ITEM_NO_RACE, - int allow_uniques = 0) -{ - const int bp = get_item_slot(); - if (bp == NON_ITEM) - return (false); - - const int thing_created = - items(allow_uniques, base, subtype, true, level, race); - - if (thing_created == NON_ITEM) - return (false); - - _give_monster_item(mons, thing_created); - return (true); -} - -void give_shield(monsters *mon, int level) -{ - const item_def *main_weap = mon->mslot_item(MSLOT_WEAPON); - const item_def *alt_weap = mon->mslot_item(MSLOT_ALT_WEAPON); - - // If the monster is already wielding/carrying a two-handed weapon, - // it doesn't get a shield. (Monsters always prefer raw damage to - // protection!) - if (main_weap && hands_reqd(*main_weap, mon->body_size()) == HANDS_TWO - || alt_weap && hands_reqd(*alt_weap, mon->body_size()) == HANDS_TWO) - { - return; - } - - switch (mon->type) - { - case MONS_DAEVA: - make_item_for_monster(mon, OBJ_ARMOUR, ARM_LARGE_SHIELD, - level * 2 + 1, MAKE_ITEM_NO_RACE, 1); - break; - - case MONS_DEEP_ELF_SOLDIER: - case MONS_DEEP_ELF_FIGHTER: - if (one_chance_in(6)) - { - make_item_for_monster(mon, OBJ_ARMOUR, ARM_BUCKLER, - level, MAKE_ITEM_ELVEN); - } - break; - case MONS_NAGA_WARRIOR: - case MONS_VAULT_GUARD: - if (one_chance_in(3)) - { - make_item_for_monster(mon, OBJ_ARMOUR, - one_chance_in(3) ? ARM_LARGE_SHIELD - : ARM_SHIELD, - level, MAKE_ITEM_NO_RACE); - } - break; - case MONS_DRACONIAN_KNIGHT: - if (coinflip()) - { - make_item_for_monster(mon, OBJ_ARMOUR, - coinflip()? ARM_LARGE_SHIELD : ARM_SHIELD, - level, MAKE_ITEM_NO_RACE); - } - break; - case MONS_DEEP_ELF_KNIGHT: - if (one_chance_in(3)) - { - make_item_for_monster(mon, OBJ_ARMOUR, ARM_BUCKLER, - level, MAKE_ITEM_ELVEN); - } - break; - case MONS_NORRIS: - make_item_for_monster(mon, OBJ_ARMOUR, ARM_BUCKLER, - level * 2 + 1, MAKE_ITEM_RANDOM_RACE, 1); - break; - case MONS_NORBERT: - case MONS_LOUISE: - make_item_for_monster(mon, OBJ_ARMOUR, ARM_LARGE_SHIELD, - level * 2 + 1, MAKE_ITEM_RANDOM_RACE, 1); - break; - case MONS_AIZUL: - case MONS_DONALD: - make_item_for_monster(mon, OBJ_ARMOUR, ARM_SHIELD, - level * 2 + 1, MAKE_ITEM_RANDOM_RACE, 1); - break; - case MONS_NIKOLA: - { - make_item_for_monster(mon, OBJ_ARMOUR, ARM_GLOVES, - level * 2 + 1, MAKE_ITEM_NO_RACE, 1); - - item_def *gaunt = mon->mslot_item(MSLOT_SHIELD); - if (gaunt) - gaunt->plus2 = TGLOV_DESC_GAUNTLETS; - } - break; - default: - break; - } -} - -void give_armour(monsters *mon, int level) -{ - item_make_species_type item_race = MAKE_ITEM_RANDOM_RACE; - - int force_colour = 0; // mv: Important!!! Items with force_colour = 0 - // are colored by default after following - // switch. Others will get force_colour. - - item_def item; - - switch (mon->type) - { - case MONS_DEEP_ELF_BLADEMASTER: - case MONS_DEEP_ELF_MASTER_ARCHER: - item_race = MAKE_ITEM_ELVEN; - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_LEATHER_ARMOUR; - break; - - case MONS_DUVESSA: - case MONS_DEEP_ELF_ANNIHILATOR: - case MONS_DEEP_ELF_CONJURER: - case MONS_DEEP_ELF_DEATH_MAGE: - case MONS_DEEP_ELF_DEMONOLOGIST: - case MONS_DEEP_ELF_FIGHTER: - case MONS_DEEP_ELF_HIGH_PRIEST: - case MONS_DEEP_ELF_KNIGHT: - case MONS_DEEP_ELF_MAGE: - case MONS_DEEP_ELF_PRIEST: - case MONS_DEEP_ELF_SOLDIER: - case MONS_DEEP_ELF_SORCERER: - case MONS_DEEP_ELF_SUMMONER: - if (item_race == MAKE_ITEM_RANDOM_RACE) - item_race = MAKE_ITEM_ELVEN; - // deliberate fall through {dlb} - - case MONS_IJYB: - case MONS_ORC: - case MONS_ORC_HIGH_PRIEST: - case MONS_ORC_PRIEST: - case MONS_ORC_SORCERER: - if (item_race == MAKE_ITEM_RANDOM_RACE) - item_race = MAKE_ITEM_ORCISH; - // deliberate fall through {dlb} - - case MONS_ERICA: - case MONS_HAROLD: - case MONS_JOSEPH: - case MONS_JOSEPHINE: - case MONS_JOZEF: - case MONS_NORBERT: - case MONS_PSYCHE: - if (x_chance_in_y(2, 5)) - { - item.base_type = OBJ_ARMOUR; - - const int temp_rand = random2(8); - item.sub_type = ((temp_rand < 4) ? ARM_LEATHER_ARMOUR : - (temp_rand < 6) ? ARM_RING_MAIL : - (temp_rand == 6) ? ARM_SCALE_MAIL - : ARM_CHAIN_MAIL); - } - else - return; - break; - - case MONS_TERENCE: - item.base_type = OBJ_ARMOUR; - item.sub_type = random_choose_weighted(1, ARM_RING_MAIL, - 3, ARM_SCALE_MAIL, - 2, ARM_CHAIN_MAIL, - 0); - break; - - case MONS_GRUM: - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_ANIMAL_SKIN; - break; - - case MONS_URUG: - item_race = MAKE_ITEM_ORCISH; - // deliberate fall through {dlb} - - case MONS_DUANE: - case MONS_EDMUND: - case MONS_RUPERT: - case MONS_WAYNE: - { - item.base_type = OBJ_ARMOUR; - - const int temp_rand = random2(4); - item.sub_type = ((temp_rand == 0) ? ARM_LEATHER_ARMOUR : - (temp_rand == 1) ? ARM_RING_MAIL : - (temp_rand == 2) ? ARM_SCALE_MAIL - : ARM_CHAIN_MAIL); - break; - } - - case MONS_ORC_WARLORD: - case MONS_SAINT_ROKA: - // Being at the top has its privileges. :) - if (one_chance_in(3)) - level = MAKE_GOOD_ITEM; - // deliberate fall through - - case MONS_ORC_KNIGHT: - case MONS_ORC_WARRIOR: - item_race = MAKE_ITEM_ORCISH; - // deliberate fall through {dlb} - - case MONS_FREDERICK: - case MONS_HELL_KNIGHT: - case MONS_LOUISE: - case MONS_MARGERY: - case MONS_MAUD: - case MONS_VAMPIRE_KNIGHT: - case MONS_VAULT_GUARD: - { - item.base_type = OBJ_ARMOUR; - - const int temp_rand = random2(4); - item.sub_type = ((temp_rand == 0) ? ARM_CHAIN_MAIL : - (temp_rand == 1) ? ARM_SPLINT_MAIL : - (temp_rand == 2) ? ARM_BANDED_MAIL - : ARM_PLATE_MAIL); - break; - } - - case MONS_ANGEL: - case MONS_SIGMUND: - case MONS_WIGHT: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_ROBE; - force_colour = WHITE; - break; - - // Centaurs sometimes wear barding. - case MONS_CENTAUR: - case MONS_CENTAUR_WARRIOR: - case MONS_YAKTAUR: - case MONS_YAKTAUR_CAPTAIN: - if ( one_chance_in( mon->type == MONS_CENTAUR ? 1000 : - mon->type == MONS_CENTAUR_WARRIOR ? 500 : - mon->type == MONS_YAKTAUR ? 300 - /* mon->type == MONS_YAKTAUR_CAPTAIN ? */ : 200)) - { - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_CENTAUR_BARDING; - } - else - return; - break; - - case MONS_NAGA: - case MONS_NAGA_MAGE: - case MONS_NAGA_WARRIOR: - case MONS_GREATER_NAGA: - if ( one_chance_in( mon->type == MONS_NAGA ? 800 : - mon->type == MONS_NAGA_WARRIOR ? 300 : - mon->type == MONS_NAGA_MAGE ? 200 - : 100 )) - { - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_NAGA_BARDING; - } - else if (mon->type == MONS_GREATER_NAGA || one_chance_in(3)) - { - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_ROBE; - } - else - return; - break; - - case MONS_GASTRONOK: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_WIZARD_HAT; - break; - - case MONS_MAURICE: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_CLOAK; - force_colour = DARKGREY; - break; - - case MONS_DOWAN: - item_race = MAKE_ITEM_ELVEN; - // intentional fall-through - case MONS_DONALD: - case MONS_JESSICA: - case MONS_KOBOLD_DEMONOLOGIST: - case MONS_OGRE_MAGE: - case MONS_EROLCHA: - case MONS_DRACONIAN: - case MONS_RED_DRACONIAN: - case MONS_WHITE_DRACONIAN: - case MONS_GREEN_DRACONIAN: - case MONS_PALE_DRACONIAN: - case MONS_MOTTLED_DRACONIAN: - case MONS_BLACK_DRACONIAN: - case MONS_YELLOW_DRACONIAN: - case MONS_PURPLE_DRACONIAN: - case MONS_DRACONIAN_SHIFTER: - case MONS_DRACONIAN_SCORCHER: - case MONS_DRACONIAN_ANNIHILATOR: - case MONS_DRACONIAN_CALLER: - case MONS_DRACONIAN_MONK: - case MONS_DRACONIAN_ZEALOT: - case MONS_DRACONIAN_KNIGHT: - case MONS_WIZARD: - case MONS_ILSUIW: - if (item_race == MAKE_ITEM_RANDOM_RACE) - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_ROBE; - break; - - case MONS_TIAMAT: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_GOLD_DRAGON_ARMOUR; - break; - - case MONS_ORC_WIZARD: - case MONS_BLORK_THE_ORC: - case MONS_NERGALLE: - item_race = MAKE_ITEM_ORCISH; - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_ROBE; - break; - - case MONS_BORIS: - level = MAKE_GOOD_ITEM; - // fall-through - case MONS_AGNES: - case MONS_FRANCES: - case MONS_FRANCIS: - case MONS_NECROMANCER: - case MONS_VAMPIRE_MAGE: - case MONS_PIKEL: - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_ROBE; - force_colour = DARKGREY; - break; - - case MONS_EUSTACHIO: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_LEATHER_ARMOUR; - break; - - case MONS_NESSOS: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_CENTAUR_BARDING; - force_colour = DARKGREY; - break; - - case MONS_NIKOLA: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_CLOAK; - force_colour = LIGHTCYAN; - break; - - case MONS_AIZUL: - item_race = MAKE_ITEM_NO_RACE; - item.base_type = OBJ_ARMOUR; - item.sub_type = ARM_NAGA_BARDING; - force_colour = RED; - break; - - default: - return; - } - - const object_class_type xitc = item.base_type; - const int xitt = item.sub_type; - - if (mons_is_unique(mon->type) && level != MAKE_GOOD_ITEM) - { - if (x_chance_in_y(9 + mon->hit_dice, 100)) - level = MAKE_GOOD_ITEM; - else - level = level * 2 + 5; - } - - const int thing_created = items(0, xitc, xitt, true, level, item_race); - - if (thing_created == NON_ITEM) - return; - - _give_monster_item(mon, thing_created); - - // mv: All items with force_colour = 0 are colored via items(). - if (force_colour) - mitm[thing_created].colour = force_colour; - switch(mon->type) - { - case MONS_NIKOLA: - mitm[thing_created].plus2 = TGLOV_DESC_GAUNTLETS; - break; - default: - break; - } -} - -static void _give_gold(monsters *mon, int level) -{ - const int idx = items(0, OBJ_GOLD, 0, true, level, 0); - _give_monster_item(mon, idx); -} - -void give_item(int mid, int level_number, bool mons_summoned) -{ - monsters *mons = &menv[mid]; - - if (mons->type == MONS_MAURICE) - _give_gold(mons, level_number); - - _give_scroll(mons, level_number); - _give_wand(mons, level_number); - _give_potion(mons, level_number); - - const item_make_species_type item_race = _give_weapon(mons, level_number); - - _give_ammo(mons, level_number, item_race, mons_summoned); - - give_armour(mons, 1 + level_number / 2); - give_shield(mons, 1 + level_number / 2); -} - jewellery_type get_random_amulet_type() { return (jewellery_type) diff --git a/crawl-ref/source/makeitem.h b/crawl-ref/source/makeitem.h index 05cde765c8..5445467c4b 100644 --- a/crawl-ref/source/makeitem.h +++ b/crawl-ref/source/makeitem.h @@ -25,7 +25,6 @@ int items( int allow_uniques, object_class_type force_class, int force_type, void item_colour(item_def &item); void init_rod_mp(item_def &item, int ncharges = -1); -void give_item(int mid, int level_number, bool mons_summoned); jewellery_type get_random_ring_type(); jewellery_type get_random_amulet_type(); @@ -36,6 +35,8 @@ void item_set_appearance(item_def &item); bool is_weapon_brand_ok(int type, int brand); bool is_armour_brand_ok(int type, int brand); +bool got_curare_roll(const int item_level); + #if DEBUG_DIAGNOSTICS || DEBUG_TESTS void makeitem_tests(); #endif diff --git a/crawl-ref/source/mon-gear.cc b/crawl-ref/source/mon-gear.cc new file mode 100644 index 0000000000..283639e95f --- /dev/null +++ b/crawl-ref/source/mon-gear.cc @@ -0,0 +1,1535 @@ +/* + * File: mon-gear.cc + * Summary: Monsters' starting equipment. + */ + +#include "AppHdr.h" + +#include <algorithm> + +#include "enum.h" +#include "externs.h" +#include "mon-gear.h" + +#include "artefact.h" +#include "dungeon.h" +#include "itemprop.h" +#include "items.h" +#include "makeitem.h" +#include "mon-util.h" +#include "random.h" +#include "spl-book.h" + + +static void _give_monster_item(monsters *mon, int thing, + bool force_item = false, + bool (monsters::*pickupfn)(item_def&, int) = NULL) +{ + if (thing == NON_ITEM || thing == -1) + return; + + item_def &mthing = mitm[thing]; + ASSERT(mthing.is_valid()); + +#ifdef DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, + "Giving %s to %s...", mthing.name(DESC_PLAIN).c_str(), + mon->name(DESC_PLAIN, true).c_str()); +#endif + + mthing.pos.reset(); + mthing.link = NON_ITEM; + unset_ident_flags(mthing, ISFLAG_IDENT_MASK); + + if (mon->is_unholy() + && (is_blessed_blade(mthing) + || get_weapon_brand(mthing) == SPWPN_HOLY_WRATH)) + { + if (is_blessed_blade(mthing)) + convert2bad(mthing); + if (get_weapon_brand(mthing) == SPWPN_HOLY_WRATH) + set_item_ego_type(mthing, OBJ_WEAPONS, SPWPN_NORMAL); + } + + unwind_var<int> save_speedinc(mon->speed_increment); + if (!(pickupfn ? (mon->*pickupfn)(mthing, false) + : mon->pickup_item(mthing, false, true))) + { +#ifdef DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, "Destroying %s because %s doesn't want it!", + mthing.name(DESC_PLAIN, false, true).c_str(), + mon->name(DESC_PLAIN, true).c_str()); +#endif + destroy_item(thing, true); + return; + } + if (!mthing.is_valid()) // missiles merged into an existing stack + return; + ASSERT(mthing.holding_monster() == mon); + + if (!force_item || mthing.colour == BLACK) + item_colour(mthing); +} + +static void _give_scroll(monsters *mon, int level) +{ + int thing_created = NON_ITEM; + + if (mon->type == MONS_ROXANNE) + { + // Not a scroll, but this comes closest. + int which_book = (one_chance_in(3) ? BOOK_TRANSFIGURATIONS + : BOOK_EARTH); + + thing_created = items(0, OBJ_BOOKS, which_book, true, level, 0); + + if (thing_created != NON_ITEM && coinflip()) + { + // Give Roxanne a random book containing Statue Form instead. + item_def &item(mitm[thing_created]); + make_book_Roxanne_special(&item); + _give_monster_item(mon, thing_created, true); + return; + } + } + else if (mons_is_unique(mon->type) && one_chance_in(3)) + thing_created = items(0, OBJ_SCROLLS, OBJ_RANDOM, true, level, 0); + + if (thing_created == NON_ITEM) + return; + + mitm[thing_created].flags = 0; + _give_monster_item(mon, thing_created, true); +} + +static void _give_wand(monsters *mon, int level) +{ + if (mons_is_unique(mon->type) && !mons_class_flag(mon->type, M_NO_WAND) + && (one_chance_in(5) || mon->type == MONS_MAURICE && one_chance_in(3))) + { + const int idx = items(0, OBJ_WANDS, OBJ_RANDOM, true, level, 0); + + if (idx == NON_ITEM) + return; + + item_def& wand = mitm[idx]; + + // Don't give top-tier wands before 5 HD. + if (mon->hit_dice < 5 || mons_class_flag(mon->type, M_NO_HT_WAND)) + { + // Technically these wands will be undercharged, but it + // doesn't really matter. + if (wand.sub_type == WAND_FIRE) + wand.sub_type = WAND_FLAME; + + if (wand.sub_type == WAND_COLD) + wand.sub_type = WAND_FROST; + + if (wand.sub_type == WAND_LIGHTNING) + wand.sub_type = (coinflip() ? WAND_FLAME : WAND_FROST); + } + + wand.flags = 0; + _give_monster_item(mon, idx); + } +} + +static void _give_potion(monsters *mon, int level) +{ + if (mons_species(mon->type) == MONS_VAMPIRE && one_chance_in(5)) + { + // This handles initialization of stack timer. + const int thing_created = + items(0, OBJ_POTIONS, POT_BLOOD, true, level, 0); + + if (thing_created == NON_ITEM) + return; + + mitm[thing_created].flags = 0; + _give_monster_item(mon, thing_created); + } + else if (mons_is_unique(mon->type) && one_chance_in(3)) + { + const int thing_created = + items(0, OBJ_POTIONS, OBJ_RANDOM, true, level, 0); + + if (thing_created == NON_ITEM) + return; + + mitm[thing_created].flags = 0; + _give_monster_item(mon, thing_created, false, + &monsters::pickup_potion); + } +} + +static item_make_species_type _give_weapon(monsters *mon, int level, + bool melee_only = false, + bool give_aux_melee = true) +{ + bool force_item = false; + + item_def item; + item_make_species_type item_race = MAKE_ITEM_RANDOM_RACE; + + item.base_type = OBJ_UNASSIGNED; + + if (mon->type == MONS_DANCING_WEAPON + && player_in_branch(BRANCH_HALL_OF_BLADES)) + { + level = MAKE_GOOD_ITEM; + } + + // moved setting of quantity here to keep it in mind {dlb} + item.quantity = 1; + + switch (mon->type) + { + case MONS_KOBOLD: + // A few of the smarter kobolds have blowguns. + if (one_chance_in(10) && level > 1) + { + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_BLOWGUN; + break; + } + // intentional fallthrough + case MONS_BIG_KOBOLD: + if (x_chance_in_y(3, 5)) // give hand weapon + { + item.base_type = OBJ_WEAPONS; + item.sub_type = random_choose(WPN_DAGGER, WPN_DAGGER, + WPN_SHORT_SWORD, WPN_SHORT_SWORD, + WPN_CLUB, WPN_WHIP, -1); + } + else + return (item_race); + break; + + case MONS_HOBGOBLIN: + if (one_chance_in(3)) + item_race = MAKE_ITEM_ORCISH; + + if (x_chance_in_y(3, 5)) // give hand weapon + { + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_CLUB; + } + else + return (item_race); + break; + + case MONS_GOBLIN: + if (one_chance_in(3)) + item_race = MAKE_ITEM_ORCISH; + + if (!melee_only && one_chance_in(12) && level) + { + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_SLING; + break; + } + // deliberate fall through {dlb} + case MONS_JESSICA: + case MONS_IJYB: + if (x_chance_in_y(3, 5)) // give hand weapon + { + item.base_type = OBJ_WEAPONS; + item.sub_type = (coinflip() ? WPN_DAGGER : WPN_CLUB); + } + else + return (item_race); + break; + + case MONS_WIGHT: + case MONS_NORRIS: + item.base_type = OBJ_WEAPONS; + + if (one_chance_in(6)) + { + item.sub_type = random_choose(WPN_SPIKED_FLAIL, WPN_GREAT_MACE, + WPN_WAR_AXE, WPN_TRIDENT, -1); + } + else + { + item.sub_type = random_choose( + WPN_MACE, WPN_FLAIL, WPN_MORNINGSTAR, + WPN_DAGGER, WPN_SHORT_SWORD, WPN_LONG_SWORD, + WPN_SCIMITAR, WPN_GREAT_SWORD, WPN_HAND_AXE, + WPN_BATTLEAXE, WPN_SPEAR, WPN_HALBERD, + -1); + } + + if (coinflip()) + { + force_item = true; + item.plus += 1 + random2(3); + item.plus2 += 1 + random2(3); + + if (one_chance_in(5)) + set_item_ego_type(item, OBJ_WEAPONS, SPWPN_FREEZING); + } + + if (one_chance_in(3)) + do_curse_item(item); + break; + + case MONS_AIZUL: + if (one_chance_in(3)) + level = MAKE_GOOD_ITEM; + + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = random_choose(WPN_HALBERD, WPN_SCIMITAR, WPN_GREAT_MACE, + WPN_LONG_SWORD, WPN_EVENINGSTAR, -1); + break; + + case MONS_GNOLL: + case MONS_OGRE_MAGE: + case MONS_NAGA_WARRIOR: + case MONS_GREATER_NAGA: + case MONS_EDMUND: + case MONS_DUANE: + item_race = MAKE_ITEM_NO_RACE; + if (!one_chance_in(5)) + { + item.base_type = OBJ_WEAPONS; + item.sub_type = random_choose(WPN_SPEAR, WPN_SPEAR, WPN_HALBERD, + WPN_CLUB, WPN_WHIP, WPN_FLAIL, -1); + } + break; + + case MONS_PIKEL: + force_item = true; // guaranteed flaming or pain + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_WHIP; + set_item_ego_type(item, OBJ_WEAPONS, coinflip() ? SPWPN_PAIN : SPWPN_FLAMING); + item.plus += random2(3); + item.plus2 += random2(3); + break; + + case MONS_GRUM: + force_item = true; // guaranteed reaching + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = random_choose(WPN_WHIP, WPN_WHIP, WPN_SPEAR, + WPN_HALBERD, WPN_GLAIVE, -1); + set_item_ego_type(item, OBJ_WEAPONS, SPWPN_REACHING); + item.plus += -2 + random2(4); + item.plus2 += -1 + random2(2); + break; + + case MONS_ORC: + case MONS_ORC_PRIEST: + item_race = MAKE_ITEM_ORCISH; + // deliberate fall through {gdl} + + case MONS_DRACONIAN: + case MONS_DRACONIAN_ZEALOT: + if (!one_chance_in(5)) + { + item.base_type = OBJ_WEAPONS; + item.sub_type = random_choose_weighted( + 30, WPN_DAGGER, 30, WPN_CLUB, + 27, WPN_FLAIL, 24, WPN_HAND_AXE, + 20, WPN_HAMMER, 20, WPN_SHORT_SWORD, + 20, WPN_MACE, 10, WPN_WHIP, + 10, WPN_TRIDENT, 10, WPN_FALCHION, + 10, WPN_MORNINGSTAR, 6, WPN_WAR_AXE, + 3, WPN_SPIKED_FLAIL, + 0); + } + else + return (item_race); + break; + + case MONS_TERENCE: + item.base_type = OBJ_WEAPONS; + item.sub_type = random_choose_weighted( 30, WPN_FLAIL, + 20, WPN_HAND_AXE, + 20, WPN_SHORT_SWORD, + 20, WPN_MACE, + 10, WPN_TRIDENT, + 10, WPN_FALCHION, + 10, WPN_MORNINGSTAR, + 3, WPN_SPIKED_FLAIL, + 0); + break; + + case MONS_DUVESSA: + item_race = MAKE_ITEM_ELVEN; + item.base_type = OBJ_WEAPONS; + item.sub_type = random_choose_weighted(30, WPN_SHORT_SWORD, + 10, WPN_SABRE, + 0); + break; + + case MONS_DEEP_ELF_FIGHTER: + case MONS_DEEP_ELF_HIGH_PRIEST: + case MONS_DEEP_ELF_KNIGHT: + case MONS_DEEP_ELF_PRIEST: + case MONS_DEEP_ELF_SOLDIER: + item_race = MAKE_ITEM_ELVEN; + item.base_type = OBJ_WEAPONS; + item.sub_type = random_choose_weighted( + 20, WPN_LONG_SWORD, 20, WPN_SHORT_SWORD, 14, WPN_SCIMITAR, + 14, WPN_MACE, 13, WPN_BOW, 13, WPN_HAND_CROSSBOW, + 5, WPN_LONGBOW, + 0); + break; + + case MONS_DEEP_ELF_BLADEMASTER: + { + item_race = MAKE_ITEM_ELVEN; + item.base_type = OBJ_WEAPONS; + + // If the blademaster already has a weapon, give him the exact same + // sub_type to match. + + const item_def *weap = mon->mslot_item(MSLOT_WEAPON); + if (weap && weap->base_type == OBJ_WEAPONS) + item.sub_type = weap->sub_type; + else + { + item.sub_type = random_choose_weighted(40, WPN_SABRE, + 10, WPN_SHORT_SWORD, + 2, WPN_QUICK_BLADE, + 0); + } + break; + } + + case MONS_DEEP_ELF_MASTER_ARCHER: + item_race = MAKE_ITEM_ELVEN; + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_LONGBOW; + break; + + case MONS_DEEP_ELF_ANNIHILATOR: + case MONS_DEEP_ELF_CONJURER: + case MONS_DEEP_ELF_DEATH_MAGE: + case MONS_DEEP_ELF_DEMONOLOGIST: + case MONS_DEEP_ELF_MAGE: + case MONS_DEEP_ELF_SORCERER: + case MONS_DEEP_ELF_SUMMONER: + item_race = MAKE_ITEM_ELVEN; + // deliberate fall-through + + case MONS_DRACONIAN_SHIFTER: + case MONS_DRACONIAN_SCORCHER: + case MONS_DRACONIAN_ANNIHILATOR: + case MONS_DRACONIAN_CALLER: + item.base_type = OBJ_WEAPONS; + item.sub_type = random_choose(WPN_LONG_SWORD, WPN_LONG_SWORD, + WPN_SHORT_SWORD, WPN_SABRE, + WPN_DAGGER, WPN_WHIP, + -1); + break; + + case MONS_ORC_WARRIOR: + case MONS_ORC_HIGH_PRIEST: + case MONS_BLORK_THE_ORC: + item_race = MAKE_ITEM_ORCISH; + // deliberate fall-through {dlb} + + case MONS_DANCING_WEAPON: // give_level may have been adjusted above + case MONS_FRANCES: + case MONS_FRANCIS: + case MONS_HAROLD: + case MONS_JOSEPH: + case MONS_LOUISE: + case MONS_MICHAEL: + case MONS_NAGA: + case MONS_NAGA_MAGE: + case MONS_RUPERT: + case MONS_SKELETAL_WARRIOR: + case MONS_WAYNE: + case MONS_PALE_DRACONIAN: + case MONS_RED_DRACONIAN: + case MONS_WHITE_DRACONIAN: + case MONS_GREEN_DRACONIAN: + case MONS_MOTTLED_DRACONIAN: + case MONS_BLACK_DRACONIAN: + case MONS_YELLOW_DRACONIAN: + case MONS_PURPLE_DRACONIAN: + case MONS_TIAMAT: + if (mons_genus(mon->type) == MONS_NAGA) + item_race = MAKE_ITEM_NO_RACE; + + item.base_type = OBJ_WEAPONS; + item.sub_type = random_choose_weighted( + 10, WPN_LONG_SWORD, 10, WPN_SHORT_SWORD, + 10, WPN_SCIMITAR, 10, WPN_BATTLEAXE, + 10, WPN_HAND_AXE, 10, WPN_HALBERD, + 10, WPN_GLAIVE, 10, WPN_MORNINGSTAR, + 10, WPN_GREAT_MACE, 10, WPN_TRIDENT, + 9, WPN_WAR_AXE, 9, WPN_FLAIL, + 1, WPN_BROAD_AXE, 1, WPN_SPIKED_FLAIL, + 0); + break; + + case MONS_ORC_WARLORD: + case MONS_SAINT_ROKA: + // being at the top has its privileges + if (one_chance_in(3)) + level = MAKE_GOOD_ITEM; + // deliberate fall-through + + case MONS_ORC_KNIGHT: + item_race = MAKE_ITEM_ORCISH; + // Occasionally get crossbows. + if (!melee_only && one_chance_in(9)) + { + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_CROSSBOW; + break; + } + // deliberate fall-through + + case MONS_URUG: + item_race = MAKE_ITEM_ORCISH; + // deliberate fall-through + + case MONS_NORBERT: + case MONS_JOZEF: + case MONS_VAULT_GUARD: + case MONS_VAMPIRE_KNIGHT: + case MONS_DRACONIAN_KNIGHT: + { + item.base_type = OBJ_WEAPONS; + + item.sub_type = random_choose_weighted( + 4, WPN_GREAT_SWORD, 4, WPN_LONG_SWORD, + 4, WPN_BATTLEAXE, 4, WPN_WAR_AXE, + 3, WPN_GREAT_MACE, 2, WPN_DIRE_FLAIL, + 1, WPN_BARDICHE, 1, WPN_GLAIVE, + 1, WPN_BROAD_AXE, 1, WPN_HALBERD, + 0); + + if (one_chance_in(4)) + item.plus += 1 + random2(3); + break; + } + + case MONS_POLYPHEMUS: + case MONS_CYCLOPS: + case MONS_STONE_GIANT: + item.base_type = OBJ_MISSILES; + item.sub_type = MI_LARGE_ROCK; + break; + + case MONS_TWO_HEADED_OGRE: + case MONS_ETTIN: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = (one_chance_in(3) ? WPN_GIANT_SPIKED_CLUB + : WPN_GIANT_CLUB); + + if (one_chance_in(10) || mon->type == MONS_ETTIN) + { + item.sub_type = (one_chance_in(10) ? WPN_DIRE_FLAIL + : WPN_GREAT_MACE); + } + break; + + case MONS_REAPER: + level = MAKE_GOOD_ITEM; + // intentional fall-through... + + case MONS_SIGMUND: + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_SCYTHE; + break; + + case MONS_BALRUG: + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_DEMON_WHIP; + break; + + case MONS_RED_DEVIL: + if (!one_chance_in(3)) + { + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = (one_chance_in(3) ? WPN_DEMON_TRIDENT + : WPN_TRIDENT); + } + break; + + case MONS_OGRE: + case MONS_HILL_GIANT: + case MONS_EROLCHA: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = (one_chance_in(3) ? WPN_GIANT_SPIKED_CLUB + : WPN_GIANT_CLUB); + + if (one_chance_in(10)) + { + item.sub_type = (one_chance_in(10) ? WPN_DIRE_FLAIL + : WPN_GREAT_MACE); + } + break; + + case MONS_MERFOLK: + if (one_chance_in(3)) + { + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_TRIDENT; + break; + } + // intentionally fall through + + case MONS_MERMAID: + if (one_chance_in(3)) + { + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_SPEAR; + } + break; + + case MONS_CENTAUR: + case MONS_CENTAUR_WARRIOR: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_BOW; + if (mon->type == MONS_CENTAUR_WARRIOR && one_chance_in(3)) + item.sub_type = WPN_LONGBOW; + break; + + case MONS_NESSOS: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_LONGBOW; + item.special = SPWPN_FLAME; + item.plus += 1 + random2(3); + item.plus2 += 1 + random2(3); + item.colour = DARKGREY; + force_item = true; + break; + + case MONS_YAKTAUR: + case MONS_YAKTAUR_CAPTAIN: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_CROSSBOW; + break; + + case MONS_EFREET: + case MONS_ERICA: + case MONS_AZRAEL: + force_item = true; + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_SCIMITAR; + item.plus = random2(5); + item.plus2 = random2(5); + item.colour = RED; // forced by force_item above {dlb} + set_item_ego_type( item, OBJ_WEAPONS, SPWPN_FLAMING ); + break; + + case MONS_ANGEL: + force_item = true; + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.colour = YELLOW; // forced by force_item above {dlb} + + item.sub_type = (one_chance_in(4) ? WPN_GREAT_MACE + : WPN_MACE); + + set_equip_desc(item, ISFLAG_GLOWING); + set_item_ego_type(item, OBJ_WEAPONS, SPWPN_HOLY_WRATH); + item.plus = 1 + random2(3); + item.plus2 = 1 + random2(3); + break; + + case MONS_DAEVA: + force_item = true; + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.colour = YELLOW; // forced by force_item above {dlb} + + item.sub_type = (one_chance_in(4) ? WPN_BLESSED_EUDEMON_BLADE + : WPN_LONG_SWORD); + + set_equip_desc(item, ISFLAG_GLOWING); + set_item_ego_type(item, OBJ_WEAPONS, SPWPN_HOLY_WRATH); + item.plus = 1 + random2(3); + item.plus2 = 1 + random2(3); + break; + + case MONS_HELL_KNIGHT: + case MONS_MAUD: + case MONS_FREDERICK: + case MONS_MARGERY: + force_item = true; + item.base_type = OBJ_WEAPONS; + item.sub_type = (one_chance_in(3) ? WPN_LONG_SWORD : + coinflip() ? WPN_SCIMITAR + : WPN_GREAT_SWORD); + + if (one_chance_in(7)) + item.sub_type = WPN_HALBERD; + if (one_chance_in(7)) + item.sub_type = WPN_GLAIVE; + if (one_chance_in(7)) + item.sub_type = WPN_GREAT_MACE; + if (one_chance_in(7)) + item.sub_type = WPN_BATTLEAXE; + if (one_chance_in(7)) + item.sub_type = WPN_WAR_AXE; + if (one_chance_in(7)) + item.sub_type = WPN_BROAD_AXE; + if (one_chance_in(7)) + item.sub_type = WPN_DEMON_WHIP; + if (one_chance_in(7)) + item.sub_type = WPN_DEMON_BLADE; + if (one_chance_in(7)) + item.sub_type = WPN_DEMON_TRIDENT; + + if (one_chance_in(3)) + set_item_ego_type(item, OBJ_WEAPONS, SPWPN_FLAMING); + else if (one_chance_in(3)) + { + set_item_ego_type(item, OBJ_WEAPONS, + random_choose(SPWPN_DRAINING, SPWPN_VORPAL, + SPWPN_PAIN, SPWPN_DISTORTION, + SPWPN_SPEED, -1)); + } + + item.plus += random2(6); + item.plus2 += random2(6); + + item.colour = RED; // forced by force_item above {dlb} + + if (one_chance_in(3)) + item.colour = DARKGREY; + if (one_chance_in(5)) + item.colour = CYAN; + break; + + case MONS_FIRE_GIANT: + force_item = true; + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_GREAT_SWORD; + item.plus = 0; + item.plus2 = 0; + set_item_ego_type( item, OBJ_WEAPONS, SPWPN_FLAMING ); + + item.colour = RED; // forced by force_item above {dlb} + if (one_chance_in(3)) + item.colour = DARKGREY; + if (one_chance_in(5)) + item.colour = CYAN; + break; + + case MONS_FROST_GIANT: + force_item = true; + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_BATTLEAXE; + item.plus = 0; + item.plus2 = 0; + set_item_ego_type( item, OBJ_WEAPONS, SPWPN_FREEZING ); + + // forced by force_item above {dlb} + item.colour = (one_chance_in(3) ? WHITE : CYAN); + break; + + case MONS_ORC_WIZARD: + case MONS_ORC_SORCERER: + case MONS_NERGALLE: + item_race = MAKE_ITEM_ORCISH; + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_DAGGER; + break; + + case MONS_DOWAN: + item_race = MAKE_ITEM_ELVEN; + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_DAGGER; + break; + + case MONS_KOBOLD_DEMONOLOGIST: + case MONS_NECROMANCER: + case MONS_WIZARD: + case MONS_PSYCHE: + case MONS_DONALD: + case MONS_JOSEPHINE: + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_DAGGER; + + if (mon->type == MONS_PSYCHE) + { + set_item_ego_type(item, OBJ_WEAPONS, + random_choose_weighted(3, SPWPN_CHAOS, + 1, SPWPN_DISTORTION, + 0)); + } + break; + + case MONS_AGNES: + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_LAJATANG; + if (!one_chance_in(3)) + level = MAKE_GOOD_ITEM; + break; + + case MONS_SONJA: + if (!melee_only) + { + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_BLOWGUN; + item_race = MAKE_ITEM_NO_RACE; + break; + } + force_item = true; + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = coinflip() ? WPN_DAGGER : WPN_SHORT_SWORD; + set_item_ego_type(item, OBJ_WEAPONS, + random_choose_weighted(3, SPWPN_DISTORTION, + 2, SPWPN_VENOM, + 1, SPWPN_DRAINING, + 0)); + break; + + case MONS_MAURICE: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = coinflip() ? WPN_DAGGER : WPN_SHORT_SWORD; + break; + + case MONS_EUSTACHIO: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = (one_chance_in(3) ? WPN_FALCHION : WPN_SABRE); + break; + + case MONS_NIKOLA: + force_item = true; + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = WPN_SABRE; + set_item_ego_type(item, OBJ_WEAPONS, SPWPN_ELECTROCUTION); + item.plus = random2(5); + item.plus2 = random2(5); + break; + + case MONS_CEREBOV: + force_item = true; + make_item_unrandart(item, UNRAND_CEREBOV); + break; + + case MONS_DISPATER: + force_item = true; + make_item_unrandart(item, UNRAND_DISPATER); + break; + + case MONS_ASMODEUS: + force_item = true; + make_item_unrandart(item, UNRAND_ASMODEUS); + break; + + case MONS_GERYON: + // mv: Probably should be moved out of this switch, but it's not + // worth it, unless we have more monsters with misc. items. + item.base_type = OBJ_MISCELLANY; + item.sub_type = MISC_HORN_OF_GERYON; + break; + + case MONS_SALAMANDER: // mv: new 8 Aug 2001 + // Yes, they've got really nice items, but + // it's almost impossible to get them. + force_item = true; + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_WEAPONS; + item.sub_type = random_choose(WPN_GREAT_SWORD, WPN_TRIDENT, + WPN_SPEAR, WPN_GLAIVE, + WPN_BOW, WPN_HALBERD, + -1); + + set_item_ego_type(item, OBJ_WEAPONS, is_range_weapon(item) ? + SPWPN_FLAME : SPWPN_FLAMING); + + item.plus = random2(5); + item.plus2 = random2(5); + item.colour = RED; // forced by force_item above {dlb} + break; + + default: + break; + } + + // Only happens if something in above switch doesn't set it. {dlb} + if (item.base_type == OBJ_UNASSIGNED) + return (item_race); + + if (!force_item && mons_is_unique( mon->type )) + { + if (x_chance_in_y(10 + mon->hit_dice, 100)) + level = MAKE_GOOD_ITEM; + else if (level != MAKE_GOOD_ITEM) + level += 5; + } + + const object_class_type xitc = item.base_type; + const int xitt = item.sub_type; + + // Note this mess, all the work above doesn't mean much unless + // force_item is set... otherwise we're just going to take the base + // and subtype and create a new item. - bwr + const int thing_created = + ((force_item) ? get_item_slot() : items(0, xitc, xitt, true, + level, item_race)); + + if (thing_created == NON_ITEM) + return (item_race); + + // Copy temporary item into the item array if were forcing it, since + // items() won't have done it for us. + if (force_item) + mitm[thing_created] = item; + + item_def &i = mitm[thing_created]; + if (melee_only && (i.base_type != OBJ_WEAPONS || is_range_weapon(i))) + { + destroy_item(thing_created); + return (item_race); + } + + if (force_item) + item_set_appearance(i); + + _give_monster_item(mon, thing_created, force_item); + + if (give_aux_melee && (i.base_type != OBJ_WEAPONS || is_range_weapon(i))) + _give_weapon(mon, level, true, false); + + return (item_race); +} + +// Hands out ammunition fitting the monster's launcher (if any), or else any +// throwable weapon depending on the monster type. +static void _give_ammo(monsters *mon, int level, + item_make_species_type item_race, + bool mons_summoned) +{ + // Note that item_race is not reset for this section. + if (const item_def *launcher = mon->launcher()) + { + const object_class_type xitc = OBJ_MISSILES; + int xitt = fires_ammo_type(*launcher); + + if (xitt == MI_STONE && one_chance_in(15)) + xitt = MI_SLING_BULLET; + + const int thing_created = items(0, xitc, xitt, true, level, item_race); + + if (thing_created == NON_ITEM) + return; + + if (xitt == MI_NEEDLE) + { + if (mon->type == MONS_SONJA) + { + set_item_ego_type(mitm[thing_created], OBJ_MISSILES, + SPMSL_CURARE); + + mitm[thing_created].quantity = random_range(4, 10); + } + else + { + set_item_ego_type(mitm[thing_created], OBJ_MISSILES, + got_curare_roll(level) ? SPMSL_CURARE + : SPMSL_POISONED); + + if (get_ammo_brand( mitm[thing_created] ) == SPMSL_CURARE) + mitm[thing_created].quantity = random_range(2, 8); + } + } + else + { + // Sanity check to avoid useless brands. + const int bow_brand = get_weapon_brand(*launcher); + const int ammo_brand = get_ammo_brand(mitm[thing_created]); + if (ammo_brand != SPMSL_NORMAL + && (bow_brand == SPWPN_FLAME || bow_brand == SPWPN_FROST)) + { + mitm[thing_created].special = SPMSL_NORMAL; + } + } + + // Master archers get double ammo - archery is their only attack. + if (mon->type == MONS_DEEP_ELF_MASTER_ARCHER) + mitm[thing_created].quantity *= 2; + else if (mon->type == MONS_NESSOS) + mitm[thing_created].special = SPMSL_POISONED; + + _give_monster_item(mon, thing_created); + } + else + { + // Give some monsters throwing weapons. + int weap_type = -1; + object_class_type weap_class = OBJ_WEAPONS; + int qty = 0; + switch (mon->type) + { + case MONS_KOBOLD: + case MONS_BIG_KOBOLD: + if (x_chance_in_y(2, 5)) + { + item_race = MAKE_ITEM_NO_RACE; + weap_class = OBJ_MISSILES; + weap_type = MI_DART; + qty = 1 + random2(5); + } + break; + + case MONS_ORC_WARRIOR: + if (one_chance_in( + you.where_are_you == BRANCH_ORCISH_MINES? 9 : 20)) + { + weap_type = random_choose(WPN_HAND_AXE, WPN_SPEAR, -1); + qty = random_range(4, 8); + item_race = MAKE_ITEM_ORCISH; + } + break; + + case MONS_ORC: + if (one_chance_in(20)) + { + weap_type = random_choose(WPN_HAND_AXE, WPN_SPEAR, -1); + qty = random_range(2, 5); + item_race = MAKE_ITEM_ORCISH; + } + break; + + case MONS_URUG: + weap_type = MI_JAVELIN; + weap_class = OBJ_MISSILES; + item_race = MAKE_ITEM_ORCISH; + qty = random_range(4, 7); + break; + + case MONS_MERFOLK: + if (!one_chance_in(3)) + { + item_race = MAKE_ITEM_NO_RACE; + if (coinflip()) + { + weap_type = WPN_SPEAR; + qty = 1 + random2(3); + } + else + { + weap_class = OBJ_MISSILES; + weap_type = MI_JAVELIN; + qty = 3 + random2(6); + } + } + if (one_chance_in(6) && !mons_summoned) + { + weap_class = OBJ_MISSILES; + weap_type = MI_THROWING_NET; + qty = 1; + if (one_chance_in(4)) + qty += random2(3); // up to three nets + } + break; + + case MONS_DRACONIAN_KNIGHT: + case MONS_GNOLL: + case MONS_HILL_GIANT: + if (!one_chance_in(20)) + break; + // deliberate fall-through + + case MONS_HAROLD: // bounty hunters + case MONS_JOZEF: // up to 5 nets + if (mons_summoned) + break; + + weap_class = OBJ_MISSILES; + weap_type = MI_THROWING_NET; + qty = 1; + if (one_chance_in(3)) + qty++; + if (mon->type == MONS_HAROLD || mon->type == MONS_JOZEF) + qty += random2(4); + + break; + + default: + break; + } + + if (weap_type == -1) + return; + + const int thing_created = + items(0, weap_class, weap_type, true, level, item_race); + + if (thing_created != NON_ITEM) + { + item_def& w(mitm[thing_created]); + + // Limit returning brand to only one. + if (weap_type == OBJ_WEAPONS + && get_weapon_brand(w) == SPWPN_RETURNING) + { + qty = 1; + } + + w.quantity = qty; + + _give_monster_item(mon, thing_created, false, + &monsters::pickup_throwable_weapon); + } + } +} + +static bool make_item_for_monster( + monsters *mons, + object_class_type base, + int subtype, + int level, + item_make_species_type race = MAKE_ITEM_NO_RACE, + int allow_uniques = 0) +{ + const int bp = get_item_slot(); + if (bp == NON_ITEM) + return (false); + + const int thing_created = + items(allow_uniques, base, subtype, true, level, race); + + if (thing_created == NON_ITEM) + return (false); + + _give_monster_item(mons, thing_created); + return (true); +} + +void give_shield(monsters *mon, int level) +{ + const item_def *main_weap = mon->mslot_item(MSLOT_WEAPON); + const item_def *alt_weap = mon->mslot_item(MSLOT_ALT_WEAPON); + + // If the monster is already wielding/carrying a two-handed weapon, + // it doesn't get a shield. (Monsters always prefer raw damage to + // protection!) + if (main_weap && hands_reqd(*main_weap, mon->body_size()) == HANDS_TWO + || alt_weap && hands_reqd(*alt_weap, mon->body_size()) == HANDS_TWO) + { + return; + } + + switch (mon->type) + { + case MONS_DAEVA: + make_item_for_monster(mon, OBJ_ARMOUR, ARM_LARGE_SHIELD, + level * 2 + 1, MAKE_ITEM_NO_RACE, 1); + break; + + case MONS_DEEP_ELF_SOLDIER: + case MONS_DEEP_ELF_FIGHTER: + if (one_chance_in(6)) + { + make_item_for_monster(mon, OBJ_ARMOUR, ARM_BUCKLER, + level, MAKE_ITEM_ELVEN); + } + break; + case MONS_NAGA_WARRIOR: + case MONS_VAULT_GUARD: + if (one_chance_in(3)) + { + make_item_for_monster(mon, OBJ_ARMOUR, + one_chance_in(3) ? ARM_LARGE_SHIELD + : ARM_SHIELD, + level, MAKE_ITEM_NO_RACE); + } + break; + case MONS_DRACONIAN_KNIGHT: + if (coinflip()) + { + make_item_for_monster(mon, OBJ_ARMOUR, + coinflip()? ARM_LARGE_SHIELD : ARM_SHIELD, + level, MAKE_ITEM_NO_RACE); + } + break; + case MONS_DEEP_ELF_KNIGHT: + if (one_chance_in(3)) + { + make_item_for_monster(mon, OBJ_ARMOUR, ARM_BUCKLER, + level, MAKE_ITEM_ELVEN); + } + break; + case MONS_NORRIS: + make_item_for_monster(mon, OBJ_ARMOUR, ARM_BUCKLER, + level * 2 + 1, MAKE_ITEM_RANDOM_RACE, 1); + break; + case MONS_NORBERT: + case MONS_LOUISE: + make_item_for_monster(mon, OBJ_ARMOUR, ARM_LARGE_SHIELD, + level * 2 + 1, MAKE_ITEM_RANDOM_RACE, 1); + break; + case MONS_AIZUL: + case MONS_DONALD: + make_item_for_monster(mon, OBJ_ARMOUR, ARM_SHIELD, + level * 2 + 1, MAKE_ITEM_RANDOM_RACE, 1); + break; + case MONS_NIKOLA: + { + make_item_for_monster(mon, OBJ_ARMOUR, ARM_GLOVES, + level * 2 + 1, MAKE_ITEM_NO_RACE, 1); + + item_def *gaunt = mon->mslot_item(MSLOT_SHIELD); + if (gaunt) + gaunt->plus2 = TGLOV_DESC_GAUNTLETS; + } + break; + default: + break; + } +} + +void give_armour(monsters *mon, int level) +{ + item_make_species_type item_race = MAKE_ITEM_RANDOM_RACE; + + int force_colour = 0; // mv: Important!!! Items with force_colour = 0 + // are colored by default after following + // switch. Others will get force_colour. + + item_def item; + + switch (mon->type) + { + case MONS_DEEP_ELF_BLADEMASTER: + case MONS_DEEP_ELF_MASTER_ARCHER: + item_race = MAKE_ITEM_ELVEN; + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_LEATHER_ARMOUR; + break; + + case MONS_DUVESSA: + case MONS_DEEP_ELF_ANNIHILATOR: + case MONS_DEEP_ELF_CONJURER: + case MONS_DEEP_ELF_DEATH_MAGE: + case MONS_DEEP_ELF_DEMONOLOGIST: + case MONS_DEEP_ELF_FIGHTER: + case MONS_DEEP_ELF_HIGH_PRIEST: + case MONS_DEEP_ELF_KNIGHT: + case MONS_DEEP_ELF_MAGE: + case MONS_DEEP_ELF_PRIEST: + case MONS_DEEP_ELF_SOLDIER: + case MONS_DEEP_ELF_SORCERER: + case MONS_DEEP_ELF_SUMMONER: + if (item_race == MAKE_ITEM_RANDOM_RACE) + item_race = MAKE_ITEM_ELVEN; + // deliberate fall through {dlb} + + case MONS_IJYB: + case MONS_ORC: + case MONS_ORC_HIGH_PRIEST: + case MONS_ORC_PRIEST: + case MONS_ORC_SORCERER: + if (item_race == MAKE_ITEM_RANDOM_RACE) + item_race = MAKE_ITEM_ORCISH; + // deliberate fall through {dlb} + + case MONS_ERICA: + case MONS_HAROLD: + case MONS_JOSEPH: + case MONS_JOSEPHINE: + case MONS_JOZEF: + case MONS_NORBERT: + case MONS_PSYCHE: + if (x_chance_in_y(2, 5)) + { + item.base_type = OBJ_ARMOUR; + + const int temp_rand = random2(8); + item.sub_type = ((temp_rand < 4) ? ARM_LEATHER_ARMOUR : + (temp_rand < 6) ? ARM_RING_MAIL : + (temp_rand == 6) ? ARM_SCALE_MAIL + : ARM_CHAIN_MAIL); + } + else + return; + break; + + case MONS_TERENCE: + item.base_type = OBJ_ARMOUR; + item.sub_type = random_choose_weighted(1, ARM_RING_MAIL, + 3, ARM_SCALE_MAIL, + 2, ARM_CHAIN_MAIL, + 0); + break; + + case MONS_GRUM: + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_ANIMAL_SKIN; + break; + + case MONS_URUG: + item_race = MAKE_ITEM_ORCISH; + // deliberate fall through {dlb} + + case MONS_DUANE: + case MONS_EDMUND: + case MONS_RUPERT: + case MONS_WAYNE: + { + item.base_type = OBJ_ARMOUR; + + const int temp_rand = random2(4); + item.sub_type = ((temp_rand == 0) ? ARM_LEATHER_ARMOUR : + (temp_rand == 1) ? ARM_RING_MAIL : + (temp_rand == 2) ? ARM_SCALE_MAIL + : ARM_CHAIN_MAIL); + break; + } + + case MONS_ORC_WARLORD: + case MONS_SAINT_ROKA: + // Being at the top has its privileges. :) + if (one_chance_in(3)) + level = MAKE_GOOD_ITEM; + // deliberate fall through + + case MONS_ORC_KNIGHT: + case MONS_ORC_WARRIOR: + item_race = MAKE_ITEM_ORCISH; + // deliberate fall through {dlb} + + case MONS_FREDERICK: + case MONS_HELL_KNIGHT: + case MONS_LOUISE: + case MONS_MARGERY: + case MONS_MAUD: + case MONS_VAMPIRE_KNIGHT: + case MONS_VAULT_GUARD: + { + item.base_type = OBJ_ARMOUR; + + const int temp_rand = random2(4); + item.sub_type = ((temp_rand == 0) ? ARM_CHAIN_MAIL : + (temp_rand == 1) ? ARM_SPLINT_MAIL : + (temp_rand == 2) ? ARM_BANDED_MAIL + : ARM_PLATE_MAIL); + break; + } + + case MONS_ANGEL: + case MONS_SIGMUND: + case MONS_WIGHT: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_ROBE; + force_colour = WHITE; + break; + + // Centaurs sometimes wear barding. + case MONS_CENTAUR: + case MONS_CENTAUR_WARRIOR: + case MONS_YAKTAUR: + case MONS_YAKTAUR_CAPTAIN: + if ( one_chance_in( mon->type == MONS_CENTAUR ? 1000 : + mon->type == MONS_CENTAUR_WARRIOR ? 500 : + mon->type == MONS_YAKTAUR ? 300 + /* mon->type == MONS_YAKTAUR_CAPTAIN ? */ : 200)) + { + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_CENTAUR_BARDING; + } + else + return; + break; + + case MONS_NAGA: + case MONS_NAGA_MAGE: + case MONS_NAGA_WARRIOR: + case MONS_GREATER_NAGA: + if ( one_chance_in( mon->type == MONS_NAGA ? 800 : + mon->type == MONS_NAGA_WARRIOR ? 300 : + mon->type == MONS_NAGA_MAGE ? 200 + : 100 )) + { + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_NAGA_BARDING; + } + else if (mon->type == MONS_GREATER_NAGA || one_chance_in(3)) + { + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_ROBE; + } + else + return; + break; + + case MONS_GASTRONOK: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_WIZARD_HAT; + break; + + case MONS_MAURICE: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_CLOAK; + force_colour = DARKGREY; + break; + + case MONS_DOWAN: + item_race = MAKE_ITEM_ELVEN; + // intentional fall-through + case MONS_DONALD: + case MONS_JESSICA: + case MONS_KOBOLD_DEMONOLOGIST: + case MONS_OGRE_MAGE: + case MONS_EROLCHA: + case MONS_DRACONIAN: + case MONS_RED_DRACONIAN: + case MONS_WHITE_DRACONIAN: + case MONS_GREEN_DRACONIAN: + case MONS_PALE_DRACONIAN: + case MONS_MOTTLED_DRACONIAN: + case MONS_BLACK_DRACONIAN: + case MONS_YELLOW_DRACONIAN: + case MONS_PURPLE_DRACONIAN: + case MONS_DRACONIAN_SHIFTER: + case MONS_DRACONIAN_SCORCHER: + case MONS_DRACONIAN_ANNIHILATOR: + case MONS_DRACONIAN_CALLER: + case MONS_DRACONIAN_MONK: + case MONS_DRACONIAN_ZEALOT: + case MONS_DRACONIAN_KNIGHT: + case MONS_WIZARD: + case MONS_ILSUIW: + if (item_race == MAKE_ITEM_RANDOM_RACE) + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_ROBE; + break; + + case MONS_TIAMAT: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_GOLD_DRAGON_ARMOUR; + break; + + case MONS_ORC_WIZARD: + case MONS_BLORK_THE_ORC: + case MONS_NERGALLE: + item_race = MAKE_ITEM_ORCISH; + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_ROBE; + break; + + case MONS_BORIS: + level = MAKE_GOOD_ITEM; + // fall-through + case MONS_AGNES: + case MONS_FRANCES: + case MONS_FRANCIS: + case MONS_NECROMANCER: + case MONS_VAMPIRE_MAGE: + case MONS_PIKEL: + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_ROBE; + force_colour = DARKGREY; + break; + + case MONS_EUSTACHIO: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_LEATHER_ARMOUR; + break; + + case MONS_NESSOS: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_CENTAUR_BARDING; + force_colour = DARKGREY; + break; + + case MONS_NIKOLA: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_CLOAK; + force_colour = LIGHTCYAN; + break; + + case MONS_AIZUL: + item_race = MAKE_ITEM_NO_RACE; + item.base_type = OBJ_ARMOUR; + item.sub_type = ARM_NAGA_BARDING; + force_colour = RED; + break; + + default: + return; + } + + const object_class_type xitc = item.base_type; + const int xitt = item.sub_type; + + if (mons_is_unique(mon->type) && level != MAKE_GOOD_ITEM) + { + if (x_chance_in_y(9 + mon->hit_dice, 100)) + level = MAKE_GOOD_ITEM; + else + level = level * 2 + 5; + } + + const int thing_created = items(0, xitc, xitt, true, level, item_race); + + if (thing_created == NON_ITEM) + return; + + _give_monster_item(mon, thing_created); + + // mv: All items with force_colour = 0 are colored via items(). + if (force_colour) + mitm[thing_created].colour = force_colour; + switch(mon->type) + { + case MONS_NIKOLA: + mitm[thing_created].plus2 = TGLOV_DESC_GAUNTLETS; + break; + default: + break; + } +} + +static void _give_gold(monsters *mon, int level) +{ + const int idx = items(0, OBJ_GOLD, 0, true, level, 0); + _give_monster_item(mon, idx); +} + +void give_item(int mid, int level_number, bool mons_summoned) +{ + monsters *mons = &menv[mid]; + + if (mons->type == MONS_MAURICE) + _give_gold(mons, level_number); + + _give_scroll(mons, level_number); + _give_wand(mons, level_number); + _give_potion(mons, level_number); + + const item_make_species_type item_race = _give_weapon(mons, level_number); + + _give_ammo(mons, level_number, item_race, mons_summoned); + + give_armour(mons, 1 + level_number / 2); + give_shield(mons, 1 + level_number / 2); +} diff --git a/crawl-ref/source/mon-gear.h b/crawl-ref/source/mon-gear.h new file mode 100644 index 0000000000..4e03286402 --- /dev/null +++ b/crawl-ref/source/mon-gear.h @@ -0,0 +1,12 @@ +/* + * File: mon-gear.h + * Summary: Monsters' initial equipment. + */ + +#ifndef MON_GEAR_H +#define MON_GEAR_H + +#include "itemprop.h" + +void give_item(int mid, int level_number, bool mons_summoned); +#endif diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index fea055da96..303d143e20 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -23,6 +23,7 @@ #include "makeitem.h" #include "message.h" #include "mon-behv.h" +#include "mon-gear.h" #include "mon-pick.h" #include "mon-util.h" #include "monstuff.h" |