diff options
41 files changed, 317 insertions, 136 deletions
diff --git a/crawl-ref/source/actor.cc b/crawl-ref/source/actor.cc index 3cdeeb9c50..62a8d87cf6 100644 --- a/crawl-ref/source/actor.cc +++ b/crawl-ref/source/actor.cc @@ -161,9 +161,9 @@ void actor::shield_block_succeeded(actor *foe) } } -int actor::body_weight() const +int actor::body_weight(bool base) const { - switch (body_size(PSIZE_BODY)) + switch (body_size(PSIZE_BODY, base)) { case SIZE_TINY: return (150); diff --git a/crawl-ref/source/actor.h b/crawl-ref/source/actor.h index b29e826307..a6d4899bbb 100644 --- a/crawl-ref/source/actor.h +++ b/crawl-ref/source/actor.h @@ -63,7 +63,7 @@ public: virtual size_type body_size(size_part_type psize = PSIZE_TORSO, bool base = false) const = 0; - virtual int body_weight() const; + virtual int body_weight(bool base = false) const; virtual int total_weight() const = 0; virtual int damage_brand(int which_attack = -1) = 0; diff --git a/crawl-ref/source/attitude-change.cc b/crawl-ref/source/attitude-change.cc index fcfcf2d2a9..ef5ef2fcef 100644 --- a/crawl-ref/source/attitude-change.cc +++ b/crawl-ref/source/attitude-change.cc @@ -864,7 +864,7 @@ void beogh_convert_orc(monsters *orc, bool emergency, // The monster is not really *created* friendly, but should it // become hostile later on, it won't count as a good kill. - orc->flags |= MF_CREATED_FRIENDLY; + orc->flags |= MF_NO_REWARD; // Prevent assertion if the orc was previously worshipping a // different god, rather than already worshipping Beogh or being an diff --git a/crawl-ref/source/dat/clua/iter.lua b/crawl-ref/source/dat/clua/iter.lua index b7bf9bc0a0..d9496bdb3c 100644 --- a/crawl-ref/source/dat/clua/iter.lua +++ b/crawl-ref/source/dat/clua/iter.lua @@ -470,3 +470,75 @@ end function iter.slave_iterator (prop, value) return iter.point_iterator:new(dgn.find_marker_positions_by_prop(prop, value)) end + +------------------------------------------------------------------------------- +-- Inventory iterator +------------------------------------------------------------------------------- + +iter.invent_iterator = {} + +function iter.invent_iterator:_new () + local m = {} + setmetatable(m, self) + self.__index = self + return m +end + +function iter.invent_iterator:new (itable, filter, rv_instead) + if itable == nil then + error("itable cannot be nil for invent_iterator") + end + + local mt = iter.invent_iterator:_new() + mt.cur_p = 0 + mt.table = itable + mt.rvi = rv_instead or false + mt.filter = filter or nil + + return mt:iter() +end + +function iter.invent_iterator:next() + local point = nil + local q = 0 + repeat + q = q + 1 + self.cur_p = self.cur_p + 1 + point = self:check_filter(self.table[self.cur_p]) + until point or q == 10 + + return point +end + +function iter.invent_iterator:check_filter(item) + if self.filter ~= nil then + if self.filter(item) then + if self.rvi then + return self.filter(item) + else + return item + end + else + return nil + end + else + return item + end +end + +function iter.invent_iterator:iter () + return function() return self:next() end, nil, nil +end + +-- An easier and more posh way of interfacing with find_marker_positions_by_prop. +function iter.inventory_iterator () + return iter.invent_iterator:new(items.inventory()) +end + +function iter.stash_iterator (point, y) + if y == nil then + return iter.invent_iterator:new(dgn.items_at(point.x, point.y)) + else + return iter.invent_iterator:new(dgn.items_at(point, y)) + end +end diff --git a/crawl-ref/source/dat/descript/spells.txt b/crawl-ref/source/dat/descript/spells.txt index c79c9e1424..8e58527c87 100644 --- a/crawl-ref/source/dat/descript/spells.txt +++ b/crawl-ref/source/dat/descript/spells.txt @@ -280,7 +280,7 @@ This spell will freeze ammunition held by the caster. Such missiles will shatter %%%% Fulsome Distillation -This spell extracts the vile and poisonous essences from a corpse. A rotten corpse may produce a stronger potion. You probably don't want to drink the results. +This spell extracts the vile and poisonous essences from a corpse. You probably don't want to drink the results. The type of potion produced corresponds roughly to the effects of eating said corpse. %%%% Major Healing diff --git a/crawl-ref/source/dat/ossuary.des b/crawl-ref/source/dat/ossuary.des index 89d9465766..60c46d29dd 100644 --- a/crawl-ref/source/dat/ossuary.des +++ b/crawl-ref/source/dat/ossuary.des @@ -13,7 +13,13 @@ {{ function ossuary_portal(e) - local timeout_turns = crawl.random_range(1500, 2000) + local desc_long = +"You can make out a staircase leading downwards into a small tomb. Sand ".. +"surrounds the staircase and is continuously pouring onto it. Before long the ".. +"staircase will be gone. They say that some distant relatives of the pharaohs ".. +"were entombed here." + + local timeout_turns = crawl.random_range(1500, 2000) local messager = timed_msg { @@ -31,6 +37,7 @@ function ossuary_portal(e) timed_marker { disappear = "The staircase has disappeared completely beneath the sand.", desc = "A sand-covered staircase", + desc_long = desc_long, entity = 'staircase', dst = "ossuary", dstorigin = "in a tomb", diff --git a/crawl-ref/source/dat/vaults.des b/crawl-ref/source/dat/vaults.des index 274a32e4df..18f7bfe94f 100644 --- a/crawl-ref/source/dat/vaults.des +++ b/crawl-ref/source/dat/vaults.des @@ -362,7 +362,9 @@ ENDMAP # example), which will be used to orient that corner towards the middle of # the map. Each quadrant must be capable of generating a rune, which # should be done by placing an 'O' glyph and calling vault8_rune(_G). - +# +# There is a lot of variance among the possible quadrants but we do ensure +# that (exactly) one quadrant with rich loot is generated. ############################################################################### # The main vault for Vault:8. @@ -371,7 +373,7 @@ NAME: vaults_vault PLACE: Vault:8 ORIENT: encompass TAGS: no_rotate no_dump -SUBVAULT: A : vault8_quadrant +SUBVAULT: A : vault8_quadrant_prize SUBVAULT: B : vault8_quadrant SUBVAULT: C : vault8_quadrant SUBVAULT: D : vault8_quadrant @@ -491,7 +493,7 @@ ENDMAP # # about 24 | NAME: vault8_rooms -TAGS: vault8_quadrant uniq_vault8_prize +TAGS: vault8_quadrant_prize SHUFFLE: AC/BD, EG/FH, IKN/MJL SUBST: A=., B=xx=, C=+, D=x, E=+, F=xx=, G=., H=x SUBST: I=., M=xx=, J=x, K=+, N=+, L=xx= @@ -764,7 +766,7 @@ ENDMAP # Vault:8 - Triangles Quadrant (by Mu.) # about 19 | NAME: vault8_triangles -TAGS: vault8_quadrant uniq_vault8_prize +TAGS: vault8_quadrant_prize SUBST: Q = 8 9 .:20 NSUBST: ? = 1:O / *:| SUBST: " = =:1 x:99 @@ -882,7 +884,7 @@ ENDMAP # Vault:8 - Corners Quadrant (by Mu.) # about 25 | NAME: vault8_corners -TAGS: vault8_quadrant uniq_vault8_prize +TAGS: vault8_quadrant_prize SUBST: Q = 8 9 .:10 NSUBST: $ = 1:O / *:$ SUBST: $ = | *:20 $ @@ -919,7 +921,7 @@ ENDMAP # Vault:8 - Flips Quadrant (by Mu.) # about 21 | NAME: vault8_flips -TAGS: vault8_quadrant uniq_vault8_prize +TAGS: vault8_quadrant_prize NSUBST: ; = 3:l / 3:z / 3:a / *:. SUBST: Q = 8 9 SUBST: $ = | * $ @@ -960,7 +962,7 @@ ENDMAP # Vault:8 - Construction Quadrant (by Mu.) # about 21 | NAME: vault8_construction -TAGS: vault8_quadrant uniq_vault8_prize +TAGS: vault8_quadrant_prize SUBST: Q = 8 9 . NSUBST: $ = 1:O / *:$ SUBST: $ = |*$. diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc index da0070239e..a3a2b12ea9 100644 --- a/crawl-ref/source/dgn-shoals.cc +++ b/crawl-ref/source/dgn-shoals.cc @@ -6,6 +6,7 @@ #include "dungeon.h" #include "dgn-shoals.h" #include "env.h" +#include "flood_find.h" #include "items.h" #include "maps.h" #include "mon-place.h" @@ -76,6 +77,40 @@ static dungeon_feature_type _shoals_feature_at(const coord_def &c) return _shoals_feature_by_height(height); } +static int _shoals_feature_height(dungeon_feature_type feat) +{ + switch (feat) + { + case DNGN_FLOOR: + return SHT_FLOOR; + case DNGN_SHALLOW_WATER: + return SHT_SHALLOW_WATER; + case DNGN_DEEP_WATER: + return SHT_SHALLOW_WATER - 1; + default: + return 0; + } +} + +// Returns true if the given feature can be affected by Shoals tides. +static bool _shoals_tide_susceptible_feat(dungeon_feature_type feat) +{ + return (feat_is_water(feat) || feat == DNGN_FLOOR); +} + +// Return true if tide effects can propagate through this square. +// NOTE: uses RNG! +static bool _shoals_tide_passable_feat(dungeon_feature_type feat) +{ + return (feat_is_watery(feat) + // The Shoals tide can sometimes lap past the doorways of rooms + // near the water. Note that the actual probability of the tide + // getting through a doorway is this probability * 0.5 -- + // see _shoals_apply_tide. + || (feat == DNGN_OPEN_DOOR && !one_chance_in(3)) + || (feat == DNGN_CLOSED_DOOR && one_chance_in(3))); +} + static void _shoals_init_heights() { env.heightmap.reset(new grid_heightmap); @@ -448,6 +483,31 @@ void prepare_shoals(int level_number) _shoals_furniture(_shoals_margin); } +// Search the map for vaults and set the terrain heights for features +// in the vault to reasonable levels. +void shoals_postprocess_level() +{ + if (!player_in_branch(BRANCH_SHOALS) || !env.heightmap.get()) + return; + + for (rectangle_iterator ri(1); ri; ++ri) + { + const coord_def c(*ri); + if (!(dgn_Map_Mask(c) & MMT_VAULT)) + continue; + + const dungeon_feature_type feat(grd(c)); + if (!_shoals_tide_susceptible_feat(feat)) + continue; + + const dungeon_feature_type expected_feat(_shoals_feature_at(c)); + // It would be nice to do actual height contours within + // vaults, but for now, keep it simple. + if (feat != expected_feat) + shoals_heights(c) = _shoals_feature_height(feat); + } +} + // The raw tide height / TIDE_MULTIPLIER is the actual tide height. The higher // the tide multiplier, the slower the tide advances and recedes. A multiplier // of X implies that the tide will advance visibly about once in X turns. @@ -501,10 +561,11 @@ static bool _shoals_tide_sweep_items_clear(coord_def c) return true; const coord_def target(_shoals_escape_place_from(c, false)); - if (target.origin()) - return false; - - move_item_stack_to_grid(c, target); + // Don't abort tide entry because of items. If we can't sweep the + // item clear here, let dungeon_terrain_changed teleport the item + // to the nearest safe square. + if (!target.origin()) + move_item_stack_to_grid(c, target); return true; } @@ -554,22 +615,8 @@ static void _shoals_apply_tide_feature_at(coord_def c, dungeon_terrain_changed(c, feat, true, false, true); } -static int _shoals_feature_height(dungeon_feature_type feat) -{ - switch (feat) - { - case DNGN_FLOOR: - return SHT_FLOOR; - case DNGN_SHALLOW_WATER: - return SHT_SHALLOW_WATER; - case DNGN_DEEP_WATER: - return SHT_SHALLOW_WATER - 1; - default: - return 0; - } -} - -// Determines if the +// Determines if the tide is rising or falling based on before and +// after features at the same square. static tide_direction _shoals_feature_tide_height_change( dungeon_feature_type oldfeat, dungeon_feature_type newfeat) @@ -623,12 +670,16 @@ static void _shoals_apply_tide(int tide) for (int i = 0, size = cpage.size(); i < size; ++i) { coord_def c(cpage[i]); - const bool was_wet(feat_is_water(grd(c))); + const bool was_wet(_shoals_tide_passable_feat(grd(c))); seen_points(c) = true; _shoals_apply_tide_at(c, tide); - // Only wet squares can propagate the tide onwards. - if (was_wet) + const bool is_wet(feat_is_water(grd(c))); + // Only squares that were wet (before applying tide + // effects!) can propagate the tide onwards. If the tide is + // receding and just left the square dry, there's only a chance of + // it continuing past and draining other squares through this one. + if (was_wet && (is_wet || coinflip())) { for (adjacent_iterator ai(c); ai; ++ai) { @@ -638,7 +689,7 @@ static void _shoals_apply_tide(int tide) if (!seen_points(adj)) { const dungeon_feature_type feat = grd(adj); - if (feat_is_water(feat) || feat == DNGN_FLOOR) + if (_shoals_tide_susceptible_feat(feat)) { npage.push_back(adj); seen_points(adj) = true; diff --git a/crawl-ref/source/dgn-shoals.h b/crawl-ref/source/dgn-shoals.h index aae09ff653..f558f6606f 100644 --- a/crawl-ref/source/dgn-shoals.h +++ b/crawl-ref/source/dgn-shoals.h @@ -2,6 +2,7 @@ #define DGN_SHOALS_H void prepare_shoals(int level_number); +void shoals_postprocess_level(); void shoals_apply_tides(int turns_elapsed); #endif diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc index 3b0a1262b3..047dcd3974 100644 --- a/crawl-ref/source/directn.cc +++ b/crawl-ref/source/directn.cc @@ -1498,7 +1498,7 @@ void direction(dist& moves, const targetting_type restricts, { case ATT_FRIENDLY: m->attitude = ATT_GOOD_NEUTRAL; - m->flags &= ~MF_CREATED_FRIENDLY; + m->flags &= ~MF_NO_REWARD; m->flags |= MF_WAS_NEUTRAL; break; case ATT_GOOD_NEUTRAL: @@ -1513,7 +1513,7 @@ void direction(dist& moves, const targetting_type restricts, break; case ATT_HOSTILE: m->attitude = ATT_FRIENDLY; - m->flags |= MF_CREATED_FRIENDLY; + m->flags |= MF_NO_REWARD; break; } diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 89e643a68b..48268f2067 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -233,6 +233,8 @@ typedef std::list<coord_def> coord_list; static void _dgn_set_floor_colours(); static bool _fixup_interlevel_connectivity(); +void dgn_postprocess_level(); + ////////////////////////////////////////////////////////////////////////// // Static data @@ -374,6 +376,8 @@ bool builder(int level_number, int level_type) vault_names.push_back(you.level_type_name); } + dgn_postprocess_level(); + dgn_Layout_Type.clear(); Level_Unique_Maps.clear(); Level_Unique_Tags.clear(); @@ -398,6 +402,13 @@ bool builder(int level_number, int level_type) return (false); } +// Should be called after a level is constructed to perform any final +// fixups. +void dgn_postprocess_level() +{ + shoals_postprocess_level(); +} + void level_welcome_messages() { for (int i = 0, size = Level_Vaults.size(); i < size; ++i) @@ -4132,6 +4143,7 @@ bool dgn_place_map(const map_def *mdef, bool clobber, bool make_no_exits, } setup_environment_effects(); + dgn_postprocess_level(); } return (did_map); diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 61dbeb3b2f..2db6cbe37d 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -993,10 +993,10 @@ enum dungeon_feature_type // Highest grid value which can't be reached through. DNGN_MAX_NONREACH = DNGN_CLEAR_PERMAROCK_WALL, - DNGN_TREES, DNGN_OPEN_SEA, // Shoals equivalent for permarock // Can be seen through and reached past. + DNGN_TREES, DNGN_ORCISH_IDOL = 15, DNGN_GRANITE_STATUE = 21, // 21 DNGN_STATUE_RESERVED, @@ -2122,7 +2122,7 @@ enum mon_attitude_type // These are now saved in an unsigned long in the monsters struct. enum monster_flag_type { - MF_CREATED_FRIENDLY = 0x01, // no benefit from killing + MF_NO_REWARD = 0x01, // no benefit from killing MF_JUST_SUMMONED = 0x02, // monster skips next available action MF_TAKING_STAIRS = 0x04, // is following player through stairs MF_INTERESTING = 0x08, // Player finds monster interesting diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc index f8b6ce9960..8888f868ab 100644 --- a/crawl-ref/source/godabil.cc +++ b/crawl-ref/source/godabil.cc @@ -279,7 +279,7 @@ void yred_make_enslaved_soul(monsters *mon, bool force_hostile, mon->colour = ETC_UNHOLY; - mon->flags |= MF_CREATED_FRIENDLY; + mon->flags |= MF_NO_REWARD; mon->flags |= MF_ENSLAVED_SOUL; if (twisted) @@ -1146,7 +1146,7 @@ bool evolve_flora() current_plant->upgrade_type(current_target.new_type, true, true); current_plant->god = GOD_FEDHAS; current_plant->attitude = ATT_FRIENDLY; - current_plant->flags |= MF_CREATED_FRIENDLY; + current_plant->flags |= MF_NO_REWARD; current_plant->flags |= MF_ATT_CHANGE_ATTEMPT; // Try to remove slowly dying in case we are upgrading a diff --git a/crawl-ref/source/l_item.cc b/crawl-ref/source/l_item.cc index 80bbc88df9..e8dc23a2b1 100644 --- a/crawl-ref/source/l_item.cc +++ b/crawl-ref/source/l_item.cc @@ -686,6 +686,53 @@ static int l_item_do_destroy(lua_State *ls) return (1); } +static int l_item_do_dec_quantity(lua_State *ls) +{ + ASSERT_DLUA; + + LUA_ITEM(item, 1); + if (!item || !item->is_valid()) + { + lua_pushboolean(ls, false); + return (1); + } + + // The quantity to reduce by. + int quantity = luaL_checkint(ls, 2); + + bool destroyed = false; + + if (in_inventory(*item)) + destroyed = dec_inv_item_quantity(item->link, quantity); + else + destroyed = dec_mitm_item_quantity(item->index(), quantity); + + lua_pushboolean(ls, destroyed); + return (1); +} + +static int l_item_do_inc_quantity(lua_State *ls) +{ + ASSERT_DLUA; + + LUA_ITEM(item, 1); + if (!item || !item->is_valid()) + { + lua_pushboolean(ls, false); + return (1); + } + + // The quantity to increase by. + int quantity = luaL_checkint(ls, 2); + + if (in_inventory(*item)) + inc_inv_item_quantity(item->link, quantity); + else + inc_mitm_item_quantity(item->index(), quantity); + + return (0); +} + static const struct luaL_reg item_lib[] = { { "artefact", l_item_artefact }, @@ -717,6 +764,8 @@ static const struct luaL_reg item_lib[] = { "dropped", l_item_dropped }, { "can_cut_meat", l_item_can_cut_meat }, { "destroy", l_item_do_destroy }, + { "dec_quantity", l_item_do_dec_quantity }, + { "inc_quantity", l_item_do_inc_quantity }, { NULL, NULL }, }; diff --git a/crawl-ref/source/libutil.cc b/crawl-ref/source/libutil.cc index ce7fcbb429..26243f405c 100644 --- a/crawl-ref/source/libutil.cc +++ b/crawl-ref/source/libutil.cc @@ -69,6 +69,10 @@ description_level_type description_type_by_name(const char *desc) return DESC_INVENTORY; else if (!strcmp("none", desc)) return DESC_NONE; + else if (!strcmp("base", desc)) + return DESC_BASENAME; + else if (!strcmp("qual", desc)) + return DESC_QUALNAME; return DESC_PLAIN; } diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index b5c9e6bb40..2cc226f127 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -3219,7 +3219,7 @@ bool stop_attack_prompt(const monsters *mon, bool beam_attack, const bool isUnchivalric = is_unchivalric_attack(&you, mon); const bool isHoly = mon->is_holy() && (mon->attitude != ATT_HOSTILE - || testbits(mon->flags, MF_CREATED_FRIENDLY) + || testbits(mon->flags, MF_NO_REWARD) || testbits(mon->flags, MF_WAS_NEUTRAL)); if (isFriendly) diff --git a/crawl-ref/source/mon-abil.cc b/crawl-ref/source/mon-abil.cc index 5325d3f27b..b64ffcf9b4 100644 --- a/crawl-ref/source/mon-abil.cc +++ b/crawl-ref/source/mon-abil.cc @@ -1499,7 +1499,5 @@ void activate_ballistomycetes( monsters * monster, const coord_def & origin) } if (you.see_cell(origin) && found_others) - { mprf("You feel the ballistomycetes will spawn a replacement spore."); - } } diff --git a/crawl-ref/source/mon-place.cc b/crawl-ref/source/mon-place.cc index 3a88d27774..27b6c8fe20 100644 --- a/crawl-ref/source/mon-place.cc +++ b/crawl-ref/source/mon-place.cc @@ -1036,7 +1036,7 @@ int place_monster(mgen_data mg, bool force_pos) // Don't give XP for the slaves to discourage hunting. Pikel // has an artificially large XP modifier to compensate for // this. - menv[band_id].flags |= MF_CREATED_FRIENDLY; + menv[band_id].flags |= MF_NO_REWARD; menv[band_id].props["pikel_band"] = true; } } @@ -2578,7 +2578,7 @@ int mons_place(mgen_data mg) if (mg.behaviour > NUM_BEHAVIOURS) { if (mg.behaviour == BEH_FRIENDLY) - creation->flags |= MF_CREATED_FRIENDLY; + creation->flags |= MF_NO_REWARD; if (mg.behaviour == BEH_NEUTRAL || mg.behaviour == BEH_GOOD_NEUTRAL || mg.behaviour == BEH_STRICT_NEUTRAL) diff --git a/crawl-ref/source/mon-stuff.cc b/crawl-ref/source/mon-stuff.cc index 730fb54ef2..7a85194ea2 100644 --- a/crawl-ref/source/mon-stuff.cc +++ b/crawl-ref/source/mon-stuff.cc @@ -595,7 +595,7 @@ static void _give_adjusted_experience(monsters *monster, killer_type killer, const int experience = exper_value(monster); const bool created_friendly = - testbits(monster->flags, MF_CREATED_FRIENDLY); + testbits(monster->flags, MF_NO_REWARD); const bool was_neutral = testbits(monster->flags, MF_WAS_NEUTRAL); const bool no_xp = monster->has_ench(ENCH_ABJ) || !experience; const bool already_got_half_xp = testbits(monster->flags, MF_GOT_HALF_XP); @@ -1616,7 +1616,7 @@ int monster_die(monsters *monster, killer_type killer, && monster->visible_to(&you); const bool exploded = monster->flags & MF_EXPLODE_KILL; - const bool created_friendly = testbits(monster->flags, MF_CREATED_FRIENDLY); + const bool created_friendly = testbits(monster->flags, MF_NO_REWARD); bool anon = (killer_index == ANON_FRIENDLY_MONSTER); const mon_holy_type targ_holy = monster->holiness(); diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index 5285da7795..f9d18c97d9 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -316,7 +316,7 @@ size_type monsters::body_size(size_part_type /* psize */, bool /* base */) const return (ret); } -int monsters::body_weight() const +int monsters::body_weight(bool /*base*/) const { int mclass = type; @@ -5955,7 +5955,7 @@ void monsters::react_to_damage(int damage, beam_type flavour, kill_category whos if (nmons != -1 && nmons != NON_MONSTER) { // Don't allow milking the royal jelly. - menv[nmons].flags |= MF_CREATED_FRIENDLY; + menv[nmons].flags |= MF_NO_REWARD; spawned++; } } diff --git a/crawl-ref/source/monster.h b/crawl-ref/source/monster.h index 400ad01769..524c48b4d4 100644 --- a/crawl-ref/source/monster.h +++ b/crawl-ref/source/monster.h @@ -221,7 +221,7 @@ public: bool can_pass_through_feat(dungeon_feature_type grid) const; bool is_habitable_feat(dungeon_feature_type actual_grid) const; size_type body_size(size_part_type psize = PSIZE_TORSO, bool base = false) const; - int body_weight() const; + int body_weight(bool base = false) const; int total_weight() const; int damage_brand(int which_attack = -1); int damage_type(int which_attack = -1); diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 04c1498297..7ba87a20ff 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -2379,7 +2379,11 @@ int player_sust_abil(bool calc_unid) int carrying_capacity(burden_state_type bs) { - int cap = (2 * you.body_weight()) + (you.strength * 300) + // Yuck. We need this for gameplay - it nerfs small forms too much + // otherwise - but there's no good way to rationalize here... --sorear + int used_weight = std::max(you.body_weight(), you.body_weight(true)); + + int cap = (2 * used_weight) + (you.strength * 300) + (you.airborne() ? 1000 : 0); // We are nice to the lighter species in that strength adds absolutely // instead of relatively to body weight. --dpeg @@ -5593,9 +5597,12 @@ size_type player::body_size(size_part_type psize, bool base) const } } -int player::body_weight() const +int player::body_weight(bool base) const { - int weight = actor::body_weight(); + int weight = actor::body_weight(base); + + if (base) + return (weight); switch (attribute[ATTR_TRANSFORMATION]) { diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index a02e5f5c4c..ee34bd703e 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -383,7 +383,7 @@ public: bool can_pass_through_feat(dungeon_feature_type grid) const; bool is_habitable_feat(dungeon_feature_type actual_grid) const; size_type body_size(size_part_type psize = PSIZE_TORSO, bool base = false) const; - int body_weight() const; + int body_weight(bool base = false) const; int total_weight() const; int damage_brand(int which_attack = -1); int damage_type(int which_attack = -1); diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 763f1c0709..3a0c43fb0f 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -2683,7 +2683,7 @@ bool did_god_conduct(conduct_type thing_done, int level, bool known, } if (thing_done == DID_ATTACK_HOLY && victim - && !testbits(victim->flags, MF_CREATED_FRIENDLY) + && !testbits(victim->flags, MF_NO_REWARD) && !testbits(victim->flags, MF_WAS_NEUTRAL)) { break; @@ -3029,7 +3029,7 @@ bool did_god_conduct(conduct_type thing_done, int level, bool known, case GOD_SHINING_ONE: case GOD_ELYVILON: if (victim - && !testbits(victim->flags, MF_CREATED_FRIENDLY) + && !testbits(victim->flags, MF_NO_REWARD) && !testbits(victim->flags, MF_WAS_NEUTRAL)) { break; @@ -3097,7 +3097,7 @@ bool did_god_conduct(conduct_type thing_done, int level, bool known, case GOD_SHINING_ONE: case GOD_ELYVILON: if (victim - && !testbits(victim->flags, MF_CREATED_FRIENDLY) + && !testbits(victim->flags, MF_NO_REWARD) && !testbits(victim->flags, MF_WAS_NEUTRAL)) { break; diff --git a/crawl-ref/source/rltiles/dc-dngn.txt b/crawl-ref/source/rltiles/dc-dngn.txt index 5f428e7bb1..f306cfd048 100644 --- a/crawl-ref/source/rltiles/dc-dngn.txt +++ b/crawl-ref/source/rltiles/dc-dngn.txt @@ -881,6 +881,9 @@ wall/dngn_green_crystal_wall DNGN_GREEN_CRYSTAL_WALL DNGN_CRYSTAL DNGN_CRYSTAL_G %repeat DNGN_CRYSTAL DNGN_CRYSTAL_WHITE %resetcol +wall/tree1 DNGN_TREE +wall/tree2 + ## doors dngn_detected_secret_door DNGN_DETECTED_SECRET_DOOR dngn_closed_door DNGN_CLOSED_DOOR diff --git a/crawl-ref/source/rltiles/dc-dngn/wall/tree1.png b/crawl-ref/source/rltiles/dc-dngn/wall/tree1.png Binary files differnew file mode 100644 index 0000000000..c5c69a2156 --- /dev/null +++ b/crawl-ref/source/rltiles/dc-dngn/wall/tree1.png diff --git a/crawl-ref/source/rltiles/dc-dngn/wall/tree2.png b/crawl-ref/source/rltiles/dc-dngn/wall/tree2.png Binary files differnew file mode 100644 index 0000000000..711742ee6b --- /dev/null +++ b/crawl-ref/source/rltiles/dc-dngn/wall/tree2.png diff --git a/crawl-ref/source/rltiles/dc-mon.txt b/crawl-ref/source/rltiles/dc-mon.txt index b4a0c59fdf..208a27627e 100644 --- a/crawl-ref/source/rltiles/dc-mon.txt +++ b/crawl-ref/source/rltiles/dc-mon.txt @@ -473,6 +473,7 @@ two_headed_ogre MONS_TWO_HEADED_OGRE ogre_mage MONS_OGRE_MAGE ## Plants ('P') +%sdir dc-mon/fungi_plants plant MONS_PLANT plant_crypt MONS_WITHERED_PLANT oklob_plant MONS_OKLOB_PLANT @@ -543,8 +544,11 @@ deep_elf_master_archer MONS_DEEP_ELF_MASTER_ARCHER deformed_elf MONS_DEFORMED_ELF ## Fungi ('f') +%sdir dc-mon/fungi_plants fungus MONS_TOADSTOOL fungus MONS_FUNGUS +ballistomycete MONS_BALLISTOMYCETE_INACTIVE +active_ballistomycete MONS_BALLISTOMYCETE_ACTIVE wandering_mushroom MONS_WANDERING_MUSHROOM ## Goblins ('g') diff --git a/crawl-ref/source/rltiles/dc-mon/fungi_plants/active_ballistomycete.png b/crawl-ref/source/rltiles/dc-mon/fungi_plants/active_ballistomycete.png Binary files differnew file mode 100644 index 0000000000..bd01f0470c --- /dev/null +++ b/crawl-ref/source/rltiles/dc-mon/fungi_plants/active_ballistomycete.png diff --git a/crawl-ref/source/rltiles/dc-mon/fungi_plants/ballistomycete.png b/crawl-ref/source/rltiles/dc-mon/fungi_plants/ballistomycete.png Binary files differnew file mode 100644 index 0000000000..69bff99afd --- /dev/null +++ b/crawl-ref/source/rltiles/dc-mon/fungi_plants/ballistomycete.png diff --git a/crawl-ref/source/rltiles/dc-mon/fungus.png b/crawl-ref/source/rltiles/dc-mon/fungi_plants/fungus.png Binary files differindex 75d0cd66ed..75d0cd66ed 100644 --- a/crawl-ref/source/rltiles/dc-mon/fungus.png +++ b/crawl-ref/source/rltiles/dc-mon/fungi_plants/fungus.png diff --git a/crawl-ref/source/rltiles/dc-mon/oklob_plant.png b/crawl-ref/source/rltiles/dc-mon/fungi_plants/oklob_plant.png Binary files differindex 4f0f0da6b2..4f0f0da6b2 100644 --- a/crawl-ref/source/rltiles/dc-mon/oklob_plant.png +++ b/crawl-ref/source/rltiles/dc-mon/fungi_plants/oklob_plant.png diff --git a/crawl-ref/source/rltiles/dc-mon/plant.png b/crawl-ref/source/rltiles/dc-mon/fungi_plants/plant.png Binary files differindex b3124b5cae..b3124b5cae 100644 --- a/crawl-ref/source/rltiles/dc-mon/plant.png +++ b/crawl-ref/source/rltiles/dc-mon/fungi_plants/plant.png diff --git a/crawl-ref/source/rltiles/dc-mon/plant_crypt.png b/crawl-ref/source/rltiles/dc-mon/fungi_plants/plant_crypt.png Binary files differindex f17a501d4f..f17a501d4f 100644 --- a/crawl-ref/source/rltiles/dc-mon/plant_crypt.png +++ b/crawl-ref/source/rltiles/dc-mon/fungi_plants/plant_crypt.png diff --git a/crawl-ref/source/rltiles/dc-mon/wandering_mushroom.png b/crawl-ref/source/rltiles/dc-mon/fungi_plants/wandering_mushroom.png Binary files differindex e8cff68b06..e8cff68b06 100644 --- a/crawl-ref/source/rltiles/dc-mon/wandering_mushroom.png +++ b/crawl-ref/source/rltiles/dc-mon/fungi_plants/wandering_mushroom.png diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index 6fbb55f399..7da3ee46af 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -1177,10 +1177,8 @@ bool cast_evaporate(int pow, bolt& beem, int pot_idx) // Producing helpful potions would break game balance here... // and producing more than one potion from a corpse, or not // using up the corpse might also lead to game balance problems. - bwr -void cast_fulsome_distillation(int pow) +void cast_fulsome_distillation(int /*pow*/) { - pow = std::min(50, pow); - int corpse = -1; // Search items at the player's location for corpses. @@ -1205,96 +1203,63 @@ void cast_fulsome_distillation(int pow) return; } - const bool rotten = food_is_rotten(mitm[corpse]); - const bool big_monster = (mons_type_hit_dice(mitm[corpse].plus) >= 5); - const bool power_up = (rotten && big_monster); - potion_type pot_type = POT_WATER; - switch (mitm[corpse].plus) + switch (mons_corpse_effect(mitm[corpse].plus)) { - case MONS_GIANT_BAT: // extracting batty behaviour : 1 - case MONS_GIANT_BLOWFLY: // extracting batty behaviour : 5 - pot_type = POT_CONFUSION; + case CE_CLEAN: + pot_type = POT_WATER; break; - case MONS_RED_WASP: // paralysis attack : 8 - case MONS_YELLOW_WASP: // paralysis attack : 4 - pot_type = POT_PARALYSIS; + case CE_CONTAMINATED: + pot_type = (mons_weight(mitm[corpse].plus) >= 900) + ? POT_DEGENERATION : POT_CONFUSION; break; - case MONS_SNAKE: // clean meat, but poisonous attack : 2 - case MONS_GIANT_ANT: // clean meat, but poisonous attack : 3 - pot_type = (power_up ? POT_POISON : POT_CONFUSION); + case CE_POISONOUS: + pot_type = POT_POISON; break; - case MONS_ORANGE_RAT: // poisonous meat, but draining attack : 3 - pot_type = (power_up ? POT_DECAY : POT_POISON); + case CE_MUTAGEN_RANDOM: + case CE_MUTAGEN_GOOD: // unused + case CE_RANDOM: // unused + pot_type = POT_MUTATION; break; - case MONS_SPINY_WORM: // 12 - pot_type = (power_up ? POT_DECAY : POT_STRONG_POISON); + case CE_MUTAGEN_BAD: // unused + case CE_ROTTEN: // actually this only occurs via mangling + case CE_HCL: // necrophage + pot_type = POT_DECAY; break; + case CE_NOCORPSE: // shouldn't occur default: - switch (mons_corpse_effect(mitm[corpse].plus)) - { - case CE_CLEAN: - pot_type = (power_up ? POT_CONFUSION : POT_WATER); - break; - - case CE_CONTAMINATED: - pot_type = (power_up ? POT_DEGENERATION : POT_POISON); - break; - - case CE_POISONOUS: - pot_type = (power_up ? POT_STRONG_POISON : POT_POISON); - break; + break; + } - case CE_MUTAGEN_RANDOM: - case CE_MUTAGEN_GOOD: // unused - case CE_RANDOM: // unused - pot_type = POT_MUTATION; - break; + switch (mitm[corpse].plus) + { + case MONS_RED_WASP: // paralysis attack + pot_type = POT_PARALYSIS; + break; - case CE_MUTAGEN_BAD: // unused - case CE_ROTTEN: // actually this only occurs via mangling - case CE_HCL: // necrophage - pot_type = (power_up ? POT_DECAY : POT_STRONG_POISON); - break; + case MONS_YELLOW_WASP: // slowing attack + pot_type = POT_SLOWING; + break; - case CE_NOCORPSE: // shouldn't occur - default: - break; - } + default: break; } - // If not powerful enough, we downgrade the potion. - if (random2(50) > pow + 10 * rotten) + struct monsterentry* smc = get_monster_data(mitm[corpse].plus); + + for (int nattk = 0; nattk < 4; ++nattk) { - switch (pot_type) + if (smc->attack[nattk].flavour == AF_POISON_MEDIUM || + smc->attack[nattk].flavour == AF_POISON_STRONG || + smc->attack[nattk].flavour == AF_POISON_STR) { - case POT_DECAY: - case POT_DEGENERATION: - case POT_STRONG_POISON: - pot_type = POT_POISON; - break; - - case POT_MUTATION: - case POT_POISON: - pot_type = POT_CONFUSION; - break; - - case POT_PARALYSIS: - pot_type = POT_SLOWING; - break; - - case POT_CONFUSION: - case POT_SLOWING: - default: - pot_type = POT_WATER; - break; + pot_type = POT_STRONG_POISON; } } @@ -1310,6 +1275,8 @@ void cast_fulsome_distillation(int pow) mitm[corpse].inscription.clear(); item_colour(mitm[corpse]); // sets special as well + set_ident_type(mitm[corpse], ID_KNOWN_TYPE); + mprf("You extract %s from the corpse.", mitm[corpse].name(DESC_NOCAP_A).c_str()); diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc index 7a65c84f2e..9f875c298f 100644 --- a/crawl-ref/source/spl-cast.cc +++ b/crawl-ref/source/spl-cast.cc @@ -1058,7 +1058,7 @@ static void _try_monster_cast(spell_type spell, int powc, mon->type = MONS_HUMAN; mon->behaviour = BEH_SEEK; mon->attitude = ATT_FRIENDLY; - mon->flags = (MF_CREATED_FRIENDLY | MF_JUST_SUMMONED | MF_SEEN + mon->flags = (MF_NO_REWARD | MF_JUST_SUMMONED | MF_SEEN | MF_WAS_IN_VIEW | MF_HARD_RESET); mon->hit_points = you.hp; mon->hit_dice = you.experience_level; diff --git a/crawl-ref/source/spl-data.h b/crawl-ref/source/spl-data.h index 3adc30d1d3..61b544f635 100644 --- a/crawl-ref/source/spl-data.h +++ b/crawl-ref/source/spl-data.h @@ -927,7 +927,7 @@ SPTYP_TRANSMUTATION | SPTYP_NECROMANCY, SPFLAG_NONE, 1, - 50, + 0, -1, -1, 0, NULL, diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index 6d12c323ab..82a2f462ab 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -2426,7 +2426,7 @@ void tag_missing_level_attitude() if (menv[i].type < 0) continue; - is_friendly = testbits(menv[i].flags, MF_CREATED_FRIENDLY); + is_friendly = testbits(menv[i].flags, MF_NO_REWARD); menv[i].foe = MHITNOT; diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc index 34cbf7eb7f..723dbc0d00 100644 --- a/crawl-ref/source/tilepick.cc +++ b/crawl-ref/source/tilepick.cc @@ -199,7 +199,9 @@ int tileidx_monster_base(const monsters *mon, bool detected) // fungi ('f') case MONS_BALLISTOMYCETE: - return TILEP_MONS_FUNGUS; + if (!detected && mon->has_ench(ENCH_SPORE_PRODUCTION)) + return TILEP_MONS_BALLISTOMYCETE_ACTIVE; + return TILEP_MONS_BALLISTOMYCETE_INACTIVE; case MONS_TOADSTOOL: return TILEP_MONS_TOADSTOOL; case MONS_FUNGUS: @@ -2472,6 +2474,8 @@ int tileidx_feature(dungeon_feature_type feat, int gx, int gy) return TILE_DNGN_ORCISH_IDOL; case DNGN_WAX_WALL: return TILE_DNGN_WAX_WALL; + case DNGN_TREES: + return TILE_DNGN_TREE; case DNGN_GRANITE_STATUE: return TILE_DNGN_GRANITE_STATUE; case DNGN_LAVA: diff --git a/crawl-ref/source/wiz-mon.cc b/crawl-ref/source/wiz-mon.cc index d7270d082a..632b716b54 100644 --- a/crawl-ref/source/wiz-mon.cc +++ b/crawl-ref/source/wiz-mon.cc @@ -285,7 +285,7 @@ void debug_list_monsters() int exp = exper_value(*mi); total_exp += exp; - if ((mi->flags & (MF_WAS_NEUTRAL | MF_CREATED_FRIENDLY)) + if ((mi->flags & (MF_WAS_NEUTRAL | MF_NO_REWARD)) || mi->has_ench(ENCH_ABJ)) { continue; |