summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-05-07 07:39:15 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-05-07 07:39:15 +0000
commit13089bbb1b6ca36c9acad9007a887cfa44b1e30f (patch)
tree027e4e3268bdd53dc72e257a7e2cf900705bacae /crawl-ref/source
parent6ccc5b0dae20c6589de6bf594efb8940d93b72d4 (diff)
downloadcrawl-ref-13089bbb1b6ca36c9acad9007a887cfa44b1e30f.tar.gz
crawl-ref-13089bbb1b6ca36c9acad9007a887cfa44b1e30f.zip
Disallow monsters from picking up missiles for which they don't have
the necessary launcher, but allow upgrading of missiles for ones with higher pluses or branded ones. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@4906 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/acr.cc2
-rw-r--r--crawl-ref/source/describe.cc2
-rw-r--r--crawl-ref/source/initfile.cc13
-rw-r--r--crawl-ref/source/itemprop.cc13
-rw-r--r--crawl-ref/source/itemprop.h2
-rw-r--r--crawl-ref/source/makeitem.cc81
-rw-r--r--crawl-ref/source/misc.cc1
-rw-r--r--crawl-ref/source/mon-util.cc66
-rw-r--r--crawl-ref/source/monstuff.cc11
9 files changed, 117 insertions, 74 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 20651e33b8..ce21e2f30f 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -4031,7 +4031,7 @@ static bool _initialise(void)
// set vision radius to player's current vision
setLOSRadius( you.current_vision );
- if (newc)
+ if (newc) // start a new game
{
Options.friendly_pickup = Options.default_friendly_pickup;
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index efc3a0eeb3..2a0928b164 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -1094,7 +1094,7 @@ static std::string _describe_ammo( const item_def &item )
if (get_equip_race(item) != ISFLAG_NO_RACE)
{
bool can_launch = has_launcher(item);
- bool can_throw = is_throwable(item);
+ bool can_throw = is_throwable(item);
description += "$";
if (need_new_line)
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index bf37c491d2..bc14c9545f 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -611,10 +611,10 @@ void game_options::reset_options()
mouse_input = false;
- view_max_width = 33;
- view_max_height = 21;
+ view_max_width = 33;
+ view_max_height = 21;
mlist_min_height = 5;
- msg_max_height = 10;
+ msg_max_height = 10;
mlist_allow_alternate_layout = false;
classic_hud = false;
@@ -629,7 +629,6 @@ void game_options::reset_options()
autopickup_on = true;
autoprayer_on = false;
default_friendly_pickup = 0; // allies may only pickup items
- friendly_pickup = 0; // dropped by allies
show_more_prompt = true;
show_gold_turns = false;
@@ -1806,11 +1805,11 @@ void game_options::read_option_line(const std::string &str, bool runscript)
else if (key == "default_friendly_pickup")
{
if (field == "none")
- friendly_pickup = -1;
+ default_friendly_pickup = -1;
else if (field == "all")
- friendly_pickup = 1;
+ default_friendly_pickup = 1;
else if (field == "friend")
- friendly_pickup = 0;
+ default_friendly_pickup = 0;
}
else BOOL_OPTION(show_inventory_weights);
else BOOL_OPTION(suppress_startup_errors);
diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc
index 4108fb0738..ffa7a24a71 100644
--- a/crawl-ref/source/itemprop.cc
+++ b/crawl-ref/source/itemprop.cc
@@ -2024,7 +2024,7 @@ missile_type fires_ammo_type( weapon_type wtype )
{
item_def wpn;
wpn.base_type = OBJ_WEAPONS;
- wpn.sub_type = wtype;
+ wpn.sub_type = wtype;
return (fires_ammo_type(wpn));
}
@@ -2065,18 +2065,19 @@ const char *ammo_name(missile_type ammo)
: Missile_prop[ Missile_index[ammo] ].name);
}
-const char * ammo_name( const item_def &bow )
+const char *ammo_name( const item_def &bow )
{
ASSERT( is_range_weapon( bow ) );
return ammo_name(fires_ammo_type( bow ));
}
// returns true if item has an associated launcher
-bool has_launcher( const item_def &wpn )
+bool has_launcher( const item_def &ammo )
{
- return (wpn.sub_type != MI_LARGE_ROCK &&
- wpn.sub_type != MI_JAVELIN &&
- wpn.sub_type != MI_THROWING_NET);
+ ASSERT(ammo.base_type == OBJ_MISSILES);
+ return (ammo.sub_type != MI_LARGE_ROCK
+ && ammo.sub_type != MI_JAVELIN
+ && ammo.sub_type != MI_THROWING_NET);
}
// returns true if item can be reasonably thrown without a launcher
diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h
index d24246a64d..b27c2573f1 100644
--- a/crawl-ref/source/itemprop.h
+++ b/crawl-ref/source/itemprop.h
@@ -694,7 +694,7 @@ missile_type fires_ammo_type( const item_def &item );
missile_type fires_ammo_type( weapon_type wtype );
const char * ammo_name( const item_def &bow );
const char * ammo_name( missile_type mtyp );
-bool has_launcher( const item_def &wpn );
+bool has_launcher( const item_def &ammo );
bool is_throwable( const item_def &wpn,
size_type bodysize = SIZE_MEDIUM );
launch_retval is_launched(actor *actor, const item_def *launcher,
diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc
index bf0a595bb2..e3dd651184 100644
--- a/crawl-ref/source/makeitem.cc
+++ b/crawl-ref/source/makeitem.cc
@@ -1325,17 +1325,14 @@ static brand_type _determine_weapon_brand(const item_def& item, int item_level)
if (one_chance_in(10))
rc = SPWPN_VAMPIRICISM;
- if (item.sub_type == WPN_HAND_AXE &&
- one_chance_in(10))
+ if (item.sub_type == WPN_HAND_AXE && one_chance_in(10))
rc = SPWPN_RETURNING;
if (_got_distortion_roll(item_level))
rc = SPWPN_DISTORTION;
if (one_chance_in(3) && (rc == SPWPN_NORMAL || one_chance_in(5)))
- {
rc = SPWPN_VORPAL;
- }
if (one_chance_in(4))
rc = coinflip() ? SPWPN_FLAMING : SPWPN_FREEZING;
@@ -1554,7 +1551,7 @@ static void _generate_weapon_item(item_def& item, bool allow_uniques,
item.sub_type = WPN_LONG_SWORD;
}
- item.plus = 0;
+ item.plus = 0;
item.plus2 = 0;
set_equip_race(item, _determine_weapon_race(item, item_race));
@@ -1588,7 +1585,7 @@ static void _generate_weapon_item(item_def& item, bool allow_uniques,
item.plus2 += 2 + random2(3);
}
- const int chance = force_good ? 200 : item_level;
+ const int chance = (force_good ? 200 : item_level);
// odd-looking, but this is how the algorithm compacts {dlb}:
for (int i = 0; i < 4; ++i)
@@ -1675,8 +1672,7 @@ static item_status_flag_type _determine_missile_race(const item_def& item,
// Dwarves don't make arrows, sling bullets, javelins, or
// throwing nets
- if ((item.sub_type == MI_DART
- || item.sub_type == MI_BOLT)
+ if ((item.sub_type == MI_DART || item.sub_type == MI_BOLT)
&& one_chance_in(6))
{
rc = ISFLAG_DWARVEN;
@@ -1741,8 +1737,8 @@ static special_missile_type _determine_missile_brand(const item_def& item,
// Un-poison sling bullets; un-flame and un-ice javelins; unbrand
// throwing nets.
if ((item.sub_type == MI_SLING_BULLET && rc == SPMSL_POISONED)
- || (item.sub_type == MI_JAVELIN
- && (rc == SPMSL_FLAME || rc == SPMSL_ICE))
+ || item.sub_type == MI_JAVELIN
+ && (rc == SPMSL_FLAME || rc == SPMSL_ICE)
|| item.sub_type == MI_THROWING_NET)
{
rc = SPMSL_NORMAL;
@@ -1754,7 +1750,7 @@ static special_missile_type _determine_missile_brand(const item_def& item,
static void _generate_missile_item(item_def& item, int force_type,
int item_level, int item_race)
{
- const bool no_brand = item.special == SPMSL_FORBID_BRAND;
+ const bool no_brand = (item.special == SPMSL_FORBID_BRAND);
if (no_brand)
item.special = SPMSL_NORMAL;
@@ -1784,7 +1780,7 @@ static void _generate_missile_item(item_def& item, int force_type,
}
else if (item.sub_type == MI_STONE)
{
- item.quantity = 1+ random2(9) + random2(12) + random2(15) + random2(12);
+ item.quantity = 1^+ random2(9) + random2(12) + random2(15) + random2(12);
return;
}
else if (item.sub_type == MI_THROWING_NET) // no fancy nets, either
@@ -1811,7 +1807,7 @@ static void _generate_missile_item(item_def& item, int force_type,
else if (get_ammo_brand( item ) != SPMSL_NORMAL)
item.quantity = 1 + random2(9) + random2(12) + random2(12);
else
- item.quantity = 1+ random2(9) + random2(12) + random2(12) + random2(15);
+ item.quantity = 1 + random2(9) + random2(12) + random2(12) + random2(15);
if (10 + item_level >= random2(100))
item.plus += random2(5);
@@ -1827,7 +1823,7 @@ static void _generate_missile_item(item_def& item, int force_type,
static bool _try_make_armour_artefact(item_def& item, int force_type,
int item_level)
{
- if ( item_level > 2 && random2(4000) <= (100 + item_level * 3))
+ if (item_level > 2 && random2(4000) <= (100 + item_level * 3))
{
// Make a randart or unrandart.
@@ -2114,8 +2110,8 @@ static void _generate_armour_item(item_def& item, bool allow_uniques,
item.plus++;
const bool force_good = (item_level == MAKE_GOOD_ITEM);
- const bool forced_ego = item.special > 0;
- const bool no_ego = item.special == SPARM_FORBID_EGO;
+ const bool forced_ego = (item.special > 0);
+ const bool no_ego = (item.special == SPARM_FORBID_EGO);
if (no_ego)
item.special = SPARM_NORMAL;
@@ -2141,7 +2137,7 @@ static void _generate_armour_item(item_def& item, bool allow_uniques,
_determine_armour_ego(item, force_type,
item_level));
- if ( get_armour_ego_type(item) == SPARM_PONDEROUSNESS )
+ if (get_armour_ego_type(item) == SPARM_PONDEROUSNESS)
item.plus += 3 + random2(4);
}
}
@@ -2817,7 +2813,10 @@ int items( int allow_uniques, // not just true-false,
default:
item.base_type = OBJ_GOLD;
if (force_good)
- item.quantity = 150+ random2(150) + random2(random2(random2(2000)));
+ {
+ item.quantity = 150 + random2(150)
+ + random2(random2(random2(2000)));
+ }
else
item.quantity = 1 + random2avg(19, 2) + random2(item_level);
break;
@@ -3031,8 +3030,7 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
}
// moved setting of quantity here to keep it in mind {dlb}
- int iquan = 1;
- // I wonder if this is even used, given calls to item() {dlb}
+ item.quantity = 1;
switch (mon->type)
{
@@ -3104,7 +3102,7 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
{
force_item = true;
item_race = MAKE_ITEM_NO_RACE;
- item.plus += 1 + random2(3);
+ item.plus += 1 + random2(3);
item.plus2 += 1 + random2(3);
if (one_chance_in(5))
@@ -3347,8 +3345,8 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
if (one_chance_in(10) || mon->type == MONS_ETTIN)
{
- item.sub_type = ((one_chance_in(10)) ? WPN_DIRE_FLAIL
- : WPN_GREAT_MACE);
+ item.sub_type = (one_chance_in(10) ? WPN_DIRE_FLAIL
+ : WPN_GREAT_MACE);
}
break;
@@ -3394,21 +3392,21 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
}
break;
- case MONS_MERMAID:
+ case MONS_MERFOLK:
if (one_chance_in(3))
{
item_race = MAKE_ITEM_NO_RACE;
item.base_type = OBJ_WEAPONS;
- item.sub_type = WPN_SPEAR;
+ item.sub_type = WPN_TRIDENT;
+ break;
}
- break;
-
- case MONS_MERFOLK:
+ // 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_TRIDENT;
+ item.sub_type = WPN_SPEAR;
}
break;
@@ -3417,8 +3415,7 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
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))
+ if (mon->type == MONS_CENTAUR_WARRIOR && one_chance_in(3))
item.sub_type = WPN_LONGBOW;
break;
@@ -3435,7 +3432,7 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
item_race = MAKE_ITEM_NO_RACE;
item.base_type = OBJ_WEAPONS;
item.sub_type = WPN_SCIMITAR;
- item.plus = random2(5);
+ 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 );
@@ -3458,7 +3455,7 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
item.sub_type = WPN_LONG_SWORD;
}
- item.plus = 1 + random2(3);
+ item.plus = 1 + random2(3);
item.plus2 = 1 + random2(3);
break;
@@ -3473,7 +3470,7 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
set_equip_desc( item, ISFLAG_GLOWING );
set_item_ego_type( item, OBJ_WEAPONS, SPWPN_HOLY_WRATH );
- item.plus = 1 + random2(3);
+ item.plus = 1 + random2(3);
item.plus2 = 1 + random2(3);
break;
@@ -3518,7 +3515,7 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
: SPWPN_SPEED) );
}
- item.plus += random2(6);
+ item.plus += random2(6);
item.plus2 += random2(6);
item.colour = RED; // forced by force_item above {dlb}
@@ -3533,7 +3530,7 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
force_item = true;
item.base_type = OBJ_WEAPONS;
item.sub_type = WPN_GREAT_SWORD;
- item.plus = 0;
+ item.plus = 0;
item.plus2 = 0;
set_item_ego_type( item, OBJ_WEAPONS, SPWPN_FLAMING );
@@ -3548,7 +3545,7 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
force_item = true;
item.base_type = OBJ_WEAPONS;
item.sub_type = WPN_BATTLEAXE;
- item.plus = 0;
+ item.plus = 0;
item.plus2 = 0;
set_item_ego_type( item, OBJ_WEAPONS, SPWPN_FREEZING );
@@ -3621,7 +3618,7 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
else
set_item_ego_type( item, OBJ_WEAPONS, SPWPN_FLAMING );
- item.plus = random2(5);
+ item.plus = random2(5);
item.plus2 = random2(5);
item.colour = RED; // forced by force_item above {dlb}
break;
@@ -3642,9 +3639,7 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
item.y = 0;
item.link = NON_ITEM;
- if (force_item)
- item.quantity = iquan;
- else if (mons_is_unique( mon->type ))
+ if (!force_item && mons_is_unique( mon->type ))
{
if (random2(100) <= 9 + mon->hit_dice)
level = MAKE_GOOD_ITEM;
@@ -3675,9 +3670,6 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
if (force_item)
item_set_appearance(i);
- if (iquan > 1 && !force_item)
- i.quantity = iquan;
-
_give_monster_item(mon, thing_created, force_item);
if (give_aux_melee && (i.base_type != OBJ_WEAPONS || is_range_weapon(i)))
@@ -3814,6 +3806,7 @@ static void _give_ammo(monsters *mon, int level,
const int thing_created =
items( 0, weap_class, weap_type, true, level, item_race );
+
if (thing_created != NON_ITEM)
{
mitm[thing_created].quantity = qty;
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index 0c1dd4faa9..b7fdba8714 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -2121,6 +2121,7 @@ void down_stairs( int old_level, dungeon_feature_type force_stair,
if (newlevel)
{
+ // When entering a new level, reset friendly_pickup to default.
Options.friendly_pickup = Options.default_friendly_pickup;
switch(you.level_type)
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index ab35bf2ab1..7d43b91891 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -2916,9 +2916,9 @@ bool monsters::has_spell_of_type(unsigned disciplines) const
bool monsters::can_use_missile(const item_def &item) const
{
- // Pretty simplistic at the moment. We allow monsters to pick up
- // missiles without the corresponding launcher, assuming that sufficient
- // wandering may get them to stumble upon the launcher.
+ // Don't allow monsters to pick up missiles without the corresponding
+ // launcher. The opposite is okay, and sufficient wandering will
+ // hopefully take the monster to a stack of appropriate missiles.
// Prevent monsters that have conjurations / summonings from
// grabbing missiles.
@@ -2941,7 +2941,20 @@ bool monsters::can_use_missile(const item_def &item) const
if (item.sub_type == MI_LARGE_ROCK && !can_throw_rocks())
return (false);
- return (true);
+ // These don't need any launcher, and always okay.
+ if (item.sub_type == MI_STONE || item.sub_type == MI_DART)
+ return (true);
+
+ item_def *launch;
+ for (int i = MSLOT_WEAPON; i <= MSLOT_ALT_WEAPON; ++i)
+ {
+ launch = mslot_item(static_cast<mon_inv_type>(i));
+ if (launch && fires_ammo_type(*launch) == item.sub_type)
+ return (true);
+ }
+
+ // no fitting launcher in inventory
+ return (false);
}
void monsters::swap_slots(mon_inv_type a, mon_inv_type b)
@@ -3378,7 +3391,7 @@ bool monsters::pickup_throwable_weapon(item_def &item, int near)
// If occupied, don't pick up a throwable weapons if it would just
// stack with an existing one. (Upgrading is possible.)
if (mslot_item(MSLOT_MISSILE)
- && behaviour == BEH_WANDER
+ && (behaviour == BEH_WANDER || mons_friendly(this) && foe == MHITYOU)
&& pickup(item, MSLOT_MISSILE, near, true))
{
return (true);
@@ -3584,10 +3597,6 @@ bool monsters::pickup_weapon(item_def &item, int near, bool force)
bool monsters::pickup_missile(item_def &item, int near, bool force)
{
- // XXX: Missile pickup could get a lot smarter if we allow monsters to
- // drop their existing missiles and pick up new stuff, but that's too
- // much work for now.
-
const item_def *miss = missiles();
if (item.sub_type == MI_THROWING_NET)
@@ -3604,7 +3613,7 @@ bool monsters::pickup_missile(item_def &item, int near, bool force)
// Monsters in a fight will only pick up missiles if doing so
// is worthwhile.
- if (behaviour != BEH_WANDER
+ if (behaviour != BEH_WANDER && (!mons_friendly(this) || foe != MHITYOU)
&& (item.quantity < 5 || miss && miss->quantity >= 7))
{
return (false);
@@ -3616,6 +3625,43 @@ bool monsters::pickup_missile(item_def &item, int near, bool force)
if (!force && !can_use_missile(item))
return (false);
+ if (miss)
+ {
+ item_def *launch;
+ for (int i = MSLOT_WEAPON; i <= MSLOT_ALT_WEAPON; ++i)
+ {
+ launch = mslot_item(static_cast<mon_inv_type>(i));
+ if (launch)
+ {
+ // If this ammunition is better, drop the old ones.
+ if (fires_ammo_type(*launch) == item.sub_type
+ && (fires_ammo_type(*launch) != miss->sub_type
+ || item.plus > miss->plus
+ || item.plus == miss->plus
+ && get_ammo_brand(*miss) == SPMSL_NORMAL
+ && get_ammo_brand(item) != SPMSL_NORMAL))
+ {
+ if (!drop_item(MSLOT_MISSILE, near))
+ return (false);
+ break;
+ }
+ }
+ }
+
+ // Darts don't absolutely need a launcher - still allow upgrading.
+ if (item.sub_type == miss->sub_type
+ && item.sub_type == MI_DART
+ && (item.plus > miss->plus
+ || item.plus == miss->plus
+ && get_ammo_brand(*miss) == SPMSL_NORMAL
+ && get_ammo_brand(item) != SPMSL_NORMAL))
+ {
+ if (!drop_item(MSLOT_MISSILE, near))
+ return (false);
+ }
+
+ }
+
return pickup(item, MSLOT_MISSILE, near);
}
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 3073e5d492..8677061f73 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -4850,8 +4850,10 @@ static void _handle_monster_move(int i, monsters *monster)
|| monster->type == MONS_NECROPHAGE
|| monster->type == MONS_GHOUL))
{
- // keep neutral and charmed monsters from picking up stuff
- if (!mons_neutral(monster) && !monster->has_ench(ENCH_CHARM))
+ // Keep neutral and charmed monsters from picking up stuff.
+ // Same for friendlies if friendly_pickup is set to -1.
+ if (!mons_neutral(monster) && !monster->has_ench(ENCH_CHARM)
+ && (!mons_friendly(monster) || Options.friendly_pickup >= 0))
{
if (_handle_pickup(monster))
{
@@ -5292,16 +5294,17 @@ static bool _handle_pickup(monsters *monster)
// Note: Monsters only look at stuff near the top of stacks.
+ bool success = false;
for (item = igrd[monster->x][monster->y]; item != NON_ITEM; )
{
item_def &topickup = mitm[item];
item = topickup.link;
if (monster->pickup_item(topickup, monsterNearby))
- return (true);
+ success = true;
if (coinflip())
break;
}
- return (false);
+ return (success);
} // end handle_pickup()
static void _jelly_grows(monsters *monster)