diff options
Diffstat (limited to 'crawl-ref')
-rw-r--r-- | crawl-ref/source/abl-show.cc | 14 | ||||
-rw-r--r-- | crawl-ref/source/beam.cc | 1 | ||||
-rw-r--r-- | crawl-ref/source/cloud.cc | 31 | ||||
-rw-r--r-- | crawl-ref/source/dat/altar.des | 2 | ||||
-rw-r--r-- | crawl-ref/source/dat/crypt.des | 19 | ||||
-rw-r--r-- | crawl-ref/source/describe.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.cc | 146 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/fight.cc | 10 | ||||
-rw-r--r-- | crawl-ref/source/fight.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/godabil.cc | 379 | ||||
-rw-r--r-- | crawl-ref/source/godwrath.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/mon-act.cc | 74 | ||||
-rw-r--r-- | crawl-ref/source/mon-data.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/monster.cc | 15 | ||||
-rw-r--r-- | crawl-ref/source/newgame.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/religion.cc | 38 | ||||
-rw-r--r-- | crawl-ref/source/rltiles/dc-misc.txt | 2 | ||||
-rw-r--r-- | crawl-ref/source/rltiles/dc-mon.txt | 5 | ||||
-rw-r--r-- | crawl-ref/source/rltiles/effect/cloud_gloom.png | bin | 0 -> 177 bytes | |||
-rw-r--r-- | crawl-ref/source/show.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/skills2.cc | 19 | ||||
-rw-r--r-- | crawl-ref/source/tilepick.cc | 14 |
23 files changed, 568 insertions, 232 deletions
diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc index e6a0ee2d4c..66c878dcb3 100644 --- a/crawl-ref/source/abl-show.cc +++ b/crawl-ref/source/abl-show.cc @@ -145,8 +145,8 @@ ability_type god_abilities[MAX_NUM_GODS][MAX_GOD_ABILITIES] = { ABIL_JIYVA_CALL_JELLY, ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_JIYVA_SLIMIFY, ABIL_JIYVA_CURE_BAD_MUTATION }, // Fedhas - { ABIL_FEDHAS_SUNLIGHT, ABIL_FEDHAS_PLANT_RING, ABIL_FEDHAS_RAIN, - ABIL_FEDHAS_SPAWN_SPORES, ABIL_FEDHAS_EVOLUTION }, + { ABIL_FEDHAS_EVOLUTION, ABIL_FEDHAS_SUNLIGHT, ABIL_FEDHAS_PLANT_RING, + ABIL_FEDHAS_SPAWN_SPORES, ABIL_FEDHAS_RAIN}, // Cheibriados { ABIL_NON_ABILITY, ABIL_CHEIBRIADOS_TIME_BEND, ABIL_NON_ABILITY, ABIL_CHEIBRIADOS_SLOUCH, ABIL_CHEIBRIADOS_TIME_STEP }, @@ -327,11 +327,12 @@ static const ability_def Ability_List[] = // Fedhas { ABIL_FEDHAS_FUNGAL_BLOOM, "Decomposition", 0, 0, 0, 0, ABFLAG_NONE }, + { ABIL_FEDHAS_EVOLUTION, "Evolution", 2, 0, 0, 0, ABFLAG_FRUIT}, { ABIL_FEDHAS_SUNLIGHT, "Sunlight", 2, 0, 0, 0, ABFLAG_NONE}, - { ABIL_FEDHAS_PLANT_RING, "Growth", 2, 0, 0, 1, ABFLAG_FRUIT}, - { ABIL_FEDHAS_RAIN, "Rain", 4, 0, 100, 2, ABFLAG_NONE}, + { ABIL_FEDHAS_PLANT_RING, "Growth", 2, 0, 0, 0, ABFLAG_FRUIT}, { ABIL_FEDHAS_SPAWN_SPORES, "Reproduction", 4, 0, 50, 2, ABFLAG_NONE}, - { ABIL_FEDHAS_EVOLUTION, "Evolution", 4, 0, 0, 2, ABFLAG_FRUIT}, + { ABIL_FEDHAS_RAIN, "Rain", 4, 0, 100, 4, ABFLAG_NONE}, + // Cheibriados { ABIL_CHEIBRIADOS_PONDEROUSIFY, "Make Ponderous", 2, 0, 0, 0, ABFLAG_NONE }, @@ -682,6 +683,7 @@ static talent _get_talent(ability_type ability, bool check_confused) case ABIL_LUGONU_ABYSS_EXIT: case ABIL_JIYVA_CALL_JELLY: case ABIL_FEDHAS_SUNLIGHT: + case ABIL_FEDHAS_EVOLUTION: invoc = true; failure = 30 - (you.piety / 20) - (6 * you.skills[SK_INVOCATIONS]); break; @@ -767,7 +769,6 @@ static talent _get_talent(ability_type ability, bool check_confused) case ABIL_OKAWARU_HASTE: case ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB: case ABIL_LUGONU_CORRUPT: - case ABIL_FEDHAS_EVOLUTION: invoc = true; failure = 70 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4); break; @@ -1990,7 +1991,6 @@ static bool _do_ability(const ability_def& abil) case ABIL_FEDHAS_EVOLUTION: if (!evolve_flora()) { - canned_msg(MSG_NOTHING_HAPPENS); return (false); } diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 36c47d85b8..49b464b608 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -6396,6 +6396,7 @@ std::string beam_type_name(beam_type type) case BEAM_VISUAL: return ("visual effects"); case BEAM_TORMENT_DAMAGE: return ("torment damage"); case BEAM_STEAL_FOOD: return ("steal food"); + case BEAM_GLOOM: return ("gloom"); case NUM_BEAMS: DEBUGSTR("invalid beam type"); return ("INVALID"); diff --git a/crawl-ref/source/cloud.cc b/crawl-ref/source/cloud.cc index 823164846d..50e27a3fd2 100644 --- a/crawl-ref/source/cloud.cc +++ b/crawl-ref/source/cloud.cc @@ -12,6 +12,7 @@ #include "externs.h" +#include "areas.h" #include "branch.h" #include "cloud.h" #include "colour.h" @@ -41,6 +42,8 @@ static int _actual_spread_rate(cloud_type type, int spread_rate) switch (type) { + case CLOUD_GLOOM: + return 50; case CLOUD_STEAM: case CLOUD_GREY_SMOKE: case CLOUD_BLACK_SMOKE: @@ -227,6 +230,22 @@ void manage_clouds() dissipate *= 4; else if ((cloud.type == CLOUD_COLD || cloud.type == CLOUD_RAIN) && grd(cloud.pos) == DNGN_LAVA) dissipate *= 4; + else if (cloud.type == CLOUD_GLOOM) + { + int count = 0; + for (adjacent_iterator ai(cloud.pos); ai; ++ai) + if (env.cgrid(*ai) != EMPTY_CLOUD) + if (env.cloud[env.cgrid(*ai)].type == CLOUD_GLOOM) + count++; + + if (!haloers(cloud.pos).empty() && !silenced(cloud.pos)) + count = 0; + + if (count < 4) + dissipate *= 50; + else + dissipate /= 20; + } expose_items_to_element(cloud2beam(cloud.type), cloud.pos, 2); @@ -514,6 +533,8 @@ cloud_type beam2cloud(beam_type flavour) return CLOUD_RAIN; case BEAM_POTION_MUTAGENIC: return CLOUD_MUTAGENIC; + case BEAM_GLOOM: + return CLOUD_GLOOM; case BEAM_RANDOM: return CLOUD_RANDOM; } @@ -539,6 +560,7 @@ beam_type cloud2beam(cloud_type flavour) case CLOUD_CHAOS: return BEAM_CHAOS; case CLOUD_RAIN: return BEAM_POTION_RAIN; case CLOUD_MUTAGENIC: return BEAM_POTION_MUTAGENIC; + case CLOUD_GLOOM: return BEAM_GLOOM; case CLOUD_RANDOM: return BEAM_RANDOM; } } @@ -833,6 +855,11 @@ void in_a_cloud() } break; + case CLOUD_GLOOM: + mprf("You are engulfed in %s!", !name.empty() ? name.c_str() : "a thick gloom"); + + break; + default: break; } @@ -887,6 +914,7 @@ bool is_harmless_cloud(cloud_type type) case CLOUD_MIST: case CLOUD_RAIN: case CLOUD_MAGIC_TRAIL: + case CLOUD_GLOOM: case CLOUD_DEBUGGING: return (true); default: @@ -963,6 +991,8 @@ std::string cloud_name(cloud_type type) return "mutagenic fog"; case CLOUD_MAGIC_TRAIL: return "magical condensation"; + case CLOUD_GLOOM: + return "gloom"; default: return "buggy goodness"; } @@ -1078,6 +1108,7 @@ int get_cloud_colour(int cloudno) case CLOUD_PURPLE_SMOKE: case CLOUD_TLOC_ENERGY: + case CLOUD_GLOOM: which_colour = MAGENTA; break; diff --git a/crawl-ref/source/dat/altar.des b/crawl-ref/source/dat/altar.des index 9d67838a2d..513838d30d 100644 --- a/crawl-ref/source/dat/altar.des +++ b/crawl-ref/source/dat/altar.des @@ -444,7 +444,7 @@ SUBST: y = c. COLOUR: 1. = random MARKER: P = lua:fog_machine { cloud_type="blue smoke", walk_dist=1, \ size=9, pow_max=20, delay=10, buildup_amnt=14, buildup_time=7, \ - spread_rate=3, start_clouds=1 } + spread_rate=3, start_clouds=1, colour="blue" } : if crawl.coinflip() then KFEAT: _ = altar_lugonu KFEAT: P = enter_abyss diff --git a/crawl-ref/source/dat/crypt.des b/crawl-ref/source/dat/crypt.des index c1b6ade7cf..174bc6fbde 100644 --- a/crawl-ref/source/dat/crypt.des +++ b/crawl-ref/source/dat/crypt.des @@ -601,6 +601,25 @@ MONS: flying skull / skeletal warrior / w:40 nothing KFEAT: ^ = alarm trap SUBST: F = G:100 F:1 KMONS: F = orange crystal statue / silver statue / ice statue +{{ +lua_marker("m", portal_desc { wall_phase =1 }) + +function drop_walls (data, triggerable, triggerer, marker, ev) + if data.trig == true then + return + else + data.trig = true + end + + crawl.mpr("The liches are set free!", "warning") + for slave in iter.slave_iterator("wall_phase", 1) do + dgn.terrain_changed(slave.x, slave.y, "floor", false, false, false) + end +end + +lua_marker("|", Triggerable.synchronized_markers(function_at_spot(drop_walls, + { trig = false}, true, { only_at_slave = true, listen_to_slaves = true }))) +}} MAP ..................... ..................... diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index 396e6a674b..83524b08da 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -3372,11 +3372,9 @@ const char *divine_title[NUM_GODS][8] = {"Scum", "Jelly", "Squelcher", "Dissolver", "Putrid Slime", "Consuming %s", "Archjelly", "Royal Jelly"}, - // Fedhas Madash -- nature theme. Titles could use some work, but the - // progression is generally from nature lover to walking disaster. - // -cao - {"Walking Fertiliser", "Green %s", "Photosynthesist", "Planter", - "Nimbus", "Sporadic Warrior", "Green Death", "Force of Nature"}, + // Fedhas Madash -- nature theme. Titles could use some work + {"Walking Fertiliser", "Green %s", "Inducer", "Photosynthesist", + "Planter", "Sporadic Warrior", "Nimbus", "Force of Nature"}, // Cheibriados -- slow theme {"Unwound %s", "Timekeeper", "Righteous Timekeeper", "Chronographer", diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index cc3e884478..fdf91dd06b 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -155,7 +155,9 @@ static bool _join_the_dots_rigorous(const coord_def &from, static void _build_river(dungeon_feature_type river_type); //mv static void _build_lake(dungeon_feature_type lake_type); //mv -static void _ruin_level(); +static void _ruin_level(int ruination = 10, int plant_density = 5); +static void _add_plant_clumps(int frequency = 10, int clump_density = 12, + int clump_radius = 4); static void _bigger_room(); static void _plan_main(int level_number, int force_plan); @@ -1135,11 +1137,6 @@ static void _build_layout_skeleton(int level_number, int level_type, _builder_extras(level_number, level_type); } } - - if (player_in_branch(BRANCH_LAIR)) - { - _ruin_level(); - } } static int _num_items_wanted(int level_number) @@ -1790,7 +1787,7 @@ static void _build_overflow_temples(int level_number) if (!dgn_ensure_vault_placed(_build_vaults(level_number, vault), false)) { #ifdef DEBUG_TEMPLES - mprf(MSGCH_DIAGNOSTICS, "Couldn't place overlfow temple '%s', " + mprf(MSGCH_DIAGNOSTICS, "Couldn't place overflow temple '%s', " "vetoing level.", vault->name.c_str()); #endif return; @@ -1837,6 +1834,16 @@ static void _build_dungeon_level(int level_number, int level_type) if (!player_in_branch(BRANCH_DIS) && !player_in_branch(BRANCH_VAULTS)) _hide_doors(); + if (player_in_branch(BRANCH_LAIR)) + { + int depth = player_branch_depth() + 1; + do { + _ruin_level(20 - depth, depth / 2 + 5); + _add_plant_clumps(12 - depth, 18 - depth / 4, depth / 4 + 2); + depth -= 3; + } while (depth > 0); + } + // Change pre-rock to rock, and pre-floor to floor. dgn_replace_area(0, 0, GXM-1, GYM-1, DNGN_BUILDER_SPECIAL_WALL, DNGN_ROCK_WALL); @@ -7736,22 +7743,27 @@ static void _build_lake(dungeon_feature_type lake_type) //mv } } -static void _ruin_level() +static void _ruin_level(int ruination /* = 10 */, int plant_density /* = 5 */) { std::vector<coord_def> to_replace; for (rectangle_iterator ri(1); ri; ++ri) { - /* only try to replace wall tiles */ - if (!feat_is_wall(grd(*ri))) + /* only try to replace wall and door tiles */ + if (!feat_is_wall(grd(*ri)) && !feat_is_door(grd(*ri))) { continue; } + /* don't mess with permarock */ + if (grd(*ri) == DNGN_PERMAROCK_WALL) { + continue; + } + int floor_count = 0; for (adjacent_iterator ai(*ri); ai; ++ai) { - if (!feat_is_wall(grd(*ai))) + if (!feat_is_wall(grd(*ai)) && !feat_is_door(grd(*ai))) { floor_count++; } @@ -7759,7 +7771,7 @@ static void _ruin_level() /* chance of removing the tile is dependent on the number of adjacent * floor tiles */ - if (x_chance_in_y(floor_count, 10)) + if (x_chance_in_y(floor_count, ruination)) { to_replace.push_back(*ri); } @@ -7769,13 +7781,115 @@ static void _ruin_level() it != to_replace.end(); ++it) { + /* only remove some doors, to preserve tactical options */ /* XXX: should this pick a random adjacent floor type, rather than * just hardcoding DNGN_FLOOR? */ - grd(*it) = DNGN_FLOOR; + if (feat_is_wall(grd(*it)) || + (coinflip() && feat_is_door(grd(*it)))) + { + grd(*it) = DNGN_FLOOR; + } - /* replace some ruined walls with plants/fungi */ - if (one_chance_in(5)) { - mons_place(mgen_data(coinflip() ? MONS_PLANT : MONS_FUNGUS)); + /* but remove doors if we've removed all adjacent walls */ + for (adjacent_iterator wai(*it); wai; ++wai) + { + if (feat_is_door(grd(*wai))) + { + bool remove = true; + for (adjacent_iterator dai(*wai); dai; ++dai) + { + if (feat_is_wall(grd(*dai))) + { + remove = false; + } + } + if (remove) + { + grd(*wai) = DNGN_FLOOR; + } + } + } + + /* replace some ruined walls with plants/fungi/bushes */ + if (one_chance_in(plant_density)) + { + mgen_data mg; + mg.cls = one_chance_in(20) ? MONS_BUSH : + coinflip() ? MONS_PLANT : + MONS_FUNGUS; + mg.pos = *it; + mons_place(mgen_data(mg)); + } + } +} + +static void _add_plant_clumps(int frequency /* = 10 */, + int clump_density /* = 12 */, + int clump_radius /* = 4 */) +{ + for (rectangle_iterator ri(1); ri; ++ri) + { + mgen_data mg; + if (mgrd(*ri) != NON_MONSTER) + { + /* clump plants around things that already exist */ + monster_type type = menv[mgrd(*ri)].type; + if ((type == MONS_PLANT || + type == MONS_FUNGUS || + type == MONS_BUSH) && one_chance_in(frequency)) { + mg.cls = type; + } + else { + continue; + } + } + else { + continue; + } + + std::vector<coord_def> to_place; + to_place.push_back(*ri); + for (int i = 1; i < clump_radius; ++i) + { + for (radius_iterator rad(*ri, i, C_SQUARE); rad; ++rad) + { + if (grd(*rad) != DNGN_FLOOR) + { + continue; + } + + /* make sure the iterator stays valid */ + std::vector<coord_def> more_to_place; + for (std::vector<coord_def>::const_iterator it = to_place.begin(); + it != to_place.end(); + ++it) + { + if (*rad == *it) + { + continue; + } + /* only place plants next to previously placed plants */ + if (abs(rad->x - it->x) <= 1 && abs(rad->y - it->y) <= 1) + { + if (one_chance_in(clump_density)) { + more_to_place.push_back(*rad); + } + } + } + to_place.insert(to_place.end(), more_to_place.begin(), more_to_place.end()); + } + } + + for (std::vector<coord_def>::const_iterator it = to_place.begin(); + it != to_place.end(); + ++it) + { + if (*it == *ri) + { + continue; + } + mg.pos = *it; + mons_place(mgen_data(mg)); } } } diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 90b38b78ae..622cee97ad 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -254,6 +254,7 @@ enum beam_type // beam[].flavour BEAM_POTION_BLUE_SMOKE, BEAM_POTION_PURPLE_SMOKE, BEAM_POTION_RAIN, + BEAM_GLOOM, BEAM_POTION_RANDOM, BEAM_LAST_REAL = BEAM_POTION_RANDOM, @@ -420,9 +421,10 @@ enum cloud_type CLOUD_TLOC_ENERGY, CLOUD_FOREST_FIRE, CLOUD_STEAM, + CLOUD_GLOOM, CLOUD_OPAQUE_FIRST = CLOUD_BLACK_SMOKE, - CLOUD_OPAQUE_LAST = CLOUD_STEAM, + CLOUD_OPAQUE_LAST = CLOUD_GLOOM, CLOUD_MIASMA, CLOUD_MIST, diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index 1b7e53e9fd..ef9f525e0f 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -5821,6 +5821,16 @@ static void mons_lose_attack_energy(monsters *attacker, int wpn_speed, } } +bool monster_attack_actor(monsters *attacker, actor *defender, + bool allow_unarmed) +{ + ASSERT(defender == &you || defender->atype() == ACT_MONSTER); + return (defender->atype() == ACT_PLAYER ? + monster_attack(attacker, allow_unarmed) + : monsters_fight(attacker, dynamic_cast<monsters*>(defender), + allow_unarmed)); +} + // A monster attacking the player. bool monster_attack(monsters* attacker, bool allow_unarmed) { diff --git a/crawl-ref/source/fight.h b/crawl-ref/source/fight.h index 538858a4d8..70427a8ec1 100644 --- a/crawl-ref/source/fight.h +++ b/crawl-ref/source/fight.h @@ -56,6 +56,8 @@ int resist_adjust_damage(actor *defender, beam_type flavour, int weapon_str_weight( object_class_type wpn_class, int wpn_type ); bool you_attack(int monster_attacked, bool unarmed_attacks); +bool monster_attack_actor(monsters *attacker, actor *defender, + bool allow_unarmed); bool monster_attack(monsters* attacker, bool allow_unarmed = true); bool monsters_fight(monsters* attacker, monsters* attacked, bool allow_unarmed = true); diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc index f6a1d82c1d..e0a0aa06f1 100644 --- a/crawl-ref/source/godabil.cc +++ b/crawl-ref/source/godabil.cc @@ -345,7 +345,7 @@ bool fedhas_shoot_through(const bolt & beam, const monsters * victim) { monsters * temp = dynamic_cast<monsters *> (originator); if (!temp) - return false; + return (false); origin_worships_fedhas = temp->god == GOD_FEDHAS; origin_attitude = temp->attitude; } @@ -485,7 +485,7 @@ int fungal_bloom() return (processed_count); } -static int _create_plant(coord_def & target) +static int _create_plant(coord_def & target, int hp_adjust = 0) { if (actor_at(target) || !mons_class_can_pass(MONS_PLANT, grd(target))) return (0); @@ -504,8 +504,16 @@ static int _create_plant(coord_def & target) if (plant != -1) { env.mons[plant].flags |= MF_ATT_CHANGE_ATTEMPT; + env.mons[plant].max_hit_points += hp_adjust; + env.mons[plant].hit_points += hp_adjust; + if (you.see_cell(target)) - mpr("A plant grows up from the ground."); + { + if (hp_adjust) + mpr("A plant grows up from the ground, it is strengthened by Fedhas."); + else + mpr("A plant grows up from the ground."); + } } @@ -536,6 +544,9 @@ bool sunlight() int plant_count = 0; int processed_count = 0; + // This is dealt with outside of the main loop. + int cloud_count = 0; + // FIXME: Uncomfortable level of code duplication here but the explosion // code in bolt subjects the input radius to r*(r+1) for the threshold and // since r is an integer we can never get just the 4-connected neighbours. @@ -634,6 +645,20 @@ bool sunlight() } } + // We damage clousd for a large radius, though. + for (radius_iterator ai(base, 7); ai; ++ai) + { + if (env.cgrid(*ai) != EMPTY_CLOUD) + { + const int cloudidx = env.cgrid(*ai); + if (env.cloud[cloudidx].type == CLOUD_GLOOM) + { + cloud_count++; + delete_cloud(cloudidx); + } + } + } + #ifndef USE_TILE // Move the cursor out of the way (it looks weird). cgotoxy(base.x, base.y, GOTO_DNGN); @@ -650,13 +675,16 @@ bool sunlight() if (evap_count) mprf("Some water evaporates in the bright sunlight."); + if (cloud_count) + mprf("Sunlight penetrates the thick gloom."); + return (processed_count); } template<typename T> bool less_second(const T & left, const T & right) { - return left.second < right.second; + return (left.second < right.second); } typedef std::pair<coord_def, int> point_distance; @@ -858,23 +886,94 @@ int _prompt_for_fruit(int & count, const char * prompt_string) return (rc); } +bool _prompt_amount(int max, int & selected, const std::string & prompt) +{ + selected = max; + while (true) + { + msg::streams(MSGCH_PROMPT) << prompt <<" (" << max << " max)"<< std::endl; + + unsigned char keyin = get_ch(); + + // Cancel + if (keyin == ESCAPE || keyin == ' ') + { + canned_msg( MSG_OK ); + return (false); + } + + // Default is max + if (keyin == '\n' || keyin == '\r') + return (true); + + // Otherwise they should enter a digit + if (isdigit(keyin)) + { + selected = keyin - '0'; + if (selected > 0 && selected <= max) + return (true); + } + // else they entered some garbage? + } + + return (max); +} + + +int _collect_fruit(std::vector<std::pair<int,int> > & available_fruit) +{ + int total=0; + + for (int i = 0; i < ENDOFPACK; i++) + { + if (you.inv[i].is_valid() + && is_fruit(you.inv[i]) ) + { + total += you.inv[i].quantity; + available_fruit.push_back(std::pair<int,int> (you.inv[i].quantity, i)); + } + } + + return (total); +} + +bool _less_first(const std::pair<int, int> & left, const std::pair<int, int> & right) +{ + return (left.first < right.first); +} +void _decrease_amount(std::vector<std::pair<int, int> > & available, int amount) +{ + int total_decrease = amount; + for (unsigned i=0; i < available.size() && amount > 0; i++) + { + + int decrease_amount = available[i].first; + if (decrease_amount > amount) + { + decrease_amount = amount; + } + amount -= decrease_amount; + dec_inv_item_quantity(available[i].second, decrease_amount); + } + if (total_decrease > 1) + mprf("%d pieces of fruit are consumed!", total_decrease); + else + mpr("A piece of fruit is consumed!"); + +} + // Create a ring or partial ring around the caster. The user is // prompted to select a stack of fruit, and then plants are placed on open // squares adjacent to the user. Of course, one piece of fruit is // consumed per plant, so a complete ring may not be formed. bool plant_ring_from_fruit() { - int possible_count; - int created_count = 0; - int rc = _prompt_for_fruit(possible_count, - "Use which fruit? [0-9] specify amount"); - - // Prompt failed? - if (rc < 0) - return (false); + // How much fruit is available? + std::vector<std::pair<int, int> > collected_fruit; + int total_fruit = _collect_fruit(collected_fruit); + // How many adjacent open spaces are there? std::vector<coord_def> adjacent; - for (adjacent_iterator adj_it(you.pos()); adj_it; ++adj_it) { if (mons_class_can_pass(MONS_PLANT, env.grid(*adj_it)) @@ -884,22 +983,34 @@ bool plant_ring_from_fruit() } } - if ((int)adjacent.size() > possible_count) + int max_use = std::min(total_fruit, int(adjacent.size()) ); + + // Don't prompt if we can't do anything (due to having no fruit or + // no squares to place plants on). + if (max_use == 0) + return (false); + + // And how many plants does the user want to create? + int target_count; + if (!_prompt_amount(max_use, target_count, "How many plants will you create?")) { - prioritise_adjacent(you.pos(), adjacent); + return (false); } - unsigned target_count = - (possible_count < (int)adjacent.size()) ? possible_count - : adjacent.size(); + if ((int)adjacent.size() > target_count) + prioritise_adjacent(you.pos(), adjacent); + + int hp_adjust = you.skills[SK_INVOCATIONS] * 10; - for (unsigned i = 0; i < target_count; ++i) + int created_count = 0; + for (int i = 0; i < target_count; ++i) { - if (_create_plant(adjacent[i])) + if (_create_plant(adjacent[i], hp_adjust)) created_count++; } - dec_inv_item_quantity(rc, created_count); + std::sort(collected_fruit.begin(), collected_fruit.end(), _less_first); + _decrease_amount(collected_fruit, created_count); return (created_count); } @@ -1059,19 +1170,19 @@ int corpse_spores(beh_type behavior) struct monster_conversion { + monster_conversion() + { + base_monster = NULL; + piety_cost = 0; + fruit_cost = 0; + + } monsters * base_monster; - int cost; + int piety_cost; + int fruit_cost; monster_type new_type; }; -bool operator<(const monster_conversion & left, - const monster_conversion & right) -{ - if (left.cost == right.cost) - return (coinflip()); - - return (left.cost < right.cost); -} // Given a monster (which should be a plant/fungus), see if // evolve_flora() can upgrade it, and set up a monster_conversion @@ -1080,27 +1191,24 @@ bool operator<(const monster_conversion & left, bool _possible_evolution(monsters * input, monster_conversion & possible_monster) { - int plant_cost = 10; - int toadstool_cost = 1; - int fungus_cost = 5; - possible_monster.base_monster = input; switch (input->mons_species()) { case MONS_PLANT: - possible_monster.cost = plant_cost; + case MONS_BUSH: possible_monster.new_type = MONS_OKLOB_PLANT; + possible_monster.fruit_cost = 1; break; case MONS_FUNGUS: case MONS_BALLISTOMYCETE: - possible_monster.cost = fungus_cost; possible_monster.new_type = MONS_WANDERING_MUSHROOM; + possible_monster.piety_cost = 1; break; case MONS_TOADSTOOL: - possible_monster.cost = toadstool_cost; - possible_monster.new_type = MONS_BALLISTOMYCETE; + possible_monster.new_type = MONS_WANDERING_MUSHROOM; + possible_monster.piety_cost = 2; break; default: @@ -1110,70 +1218,138 @@ bool _possible_evolution(monsters * input, return (true); } +void _collect_adjacent_monsters(std::vector<monster_conversion> & available, + const coord_def & center) +{ + for (adjacent_iterator adjacent(center, false); adjacent; ++adjacent) + { + monsters * candidate = monster_at(*adjacent); + monster_conversion monster_upgrade; + if (candidate && _possible_evolution(candidate, monster_upgrade)) + available.push_back(monster_upgrade); + } +} + +void _cost_summary(int oklob_count, int wandering_count, int total_in_range) +{ + mesclr(true); + if (oklob_count) + { + std::string str = (oklob_count > 1 ? "ts" : "t"); + mprf("Upgrading %d plan%s to oklob plan%s (%d fruit)", + oklob_count, str.c_str(), str.c_str(), oklob_count); + } + + if (wandering_count) + mprf("Upgrading %d fungi to wandering mushroo%s (piety cost)", + wandering_count, (wandering_count > 1 ? "ms" : "m ")); +} + bool evolve_flora() { - int rc; - int available_count; + // Collect adjacent monsters + std::vector<monster_conversion> available_monsters; + _collect_adjacent_monsters(available_monsters, you.pos()); - int points_per_fruit = 8; - int oklob_cost = 10; + // No monsters in range can be upgraded. + if (available_monsters.empty() ) + { + mpr("No flora in range can be evolved."); + return (false); + } - float approx_oklob_rate = float(points_per_fruit)/float(oklob_cost); + // What are the total costs of all adjacent upgrades? + int piety_cost = 0; + int fruit_cost = 0; - char prompt_string[100]; - memset(prompt_string,0,100); - sprintf(prompt_string, - "Use which fruit? %1.1f oklob plants per fruit, [0-9] specify amount", - approx_oklob_rate); + int oklob_generation = 0; + int wandering_generation = 0; - rc = _prompt_for_fruit(available_count, prompt_string); + for (unsigned i=0; i < available_monsters.size(); i++) + { + piety_cost += available_monsters[i].piety_cost; + fruit_cost += available_monsters[i].fruit_cost; + switch(available_monsters[i].new_type) + { + case MONS_OKLOB_PLANT: + oklob_generation++; + break; + case MONS_WANDERING_MUSHROOM: + wandering_generation++; + break; + + default: + break; + } + } - // Prompt failed? - if (rc < 0) - return (false); - int points = points_per_fruit * available_count; - int starting_points = points; + std::vector<std::pair<int, int> > collected_fruit; + int total_fruit = _collect_fruit(collected_fruit); + int useable_fruit = std::min(total_fruit, fruit_cost); - std::priority_queue<monster_conversion> available_targets; + _cost_summary(useable_fruit, wandering_generation, available_monsters.size()); - monster_conversion temp_conversion; + crawl_state.darken_range = 1; + viewwindow(false, false); - for (radius_iterator rad(you.pos(), LOS_RADIUS, true, true, true); - rad; ++rad) + int target_fruit = useable_fruit; + // Ask the user how many fruit to use + if (useable_fruit > 1) + { + if(!_prompt_amount(useable_fruit, target_fruit, + "How many oklobs will you create?")) + { + crawl_state.darken_range = -1; + viewwindow(false,false); + return (false); + } + } + else { - monsters * target = monster_at(*rad); + delay(500); + } - if (!target) - continue; + crawl_state.darken_range = -1; + viewwindow(false, false); - if (_possible_evolution(target, temp_conversion)) - available_targets.push(temp_conversion); - } + int fruit_used = target_fruit; + int reduction = fruit_cost - target_fruit; - // Nothing available to upgrade. - if (available_targets.empty()) + if (int(available_monsters.size()) <= reduction) { - mpr("No flora in sight can be evolved."); - return (false); + mprf("Not enough fruit available."); + return false; } int plants_evolved = 0; int toadstools_evolved = 0; int fungi_evolved = 0; - while (!available_targets.empty() && points > 0) - { - monster_conversion current_target = available_targets.top(); - monsters * current_plant = current_target.base_monster; - available_targets.pop(); + std::random_shuffle(available_monsters.begin(), available_monsters.end() ); - // Can we afford this thing? - if (current_target.cost > points) - continue; + for (unsigned i=0; i < available_monsters.size(); i++) + { + monsters * current_plant = available_monsters[i].base_monster; + monster_conversion current_target = available_monsters[i]; - points -= current_target.cost; + if (current_target.new_type == MONS_OKLOB_PLANT) + { + if (target_fruit) + target_fruit--; + else + continue; + } + else if (you.piety > current_target.piety_cost) + { + lose_piety(current_target.piety_cost); + } + // This would wipe out our remaining piety, so don't do it. + else + { + continue; + } switch (current_plant->mons_species()) { @@ -1199,58 +1375,15 @@ bool evolve_flora() // Try to remove slowly dying in case we are upgrading a // toadstool, and spore production in case we are upgrading a - // fungus. + // ballistomycete. current_plant->del_ench(ENCH_SLOWLY_DYING); current_plant->del_ench(ENCH_SPORE_PRODUCTION); - - // Maybe we can upgrade it again? - if (_possible_evolution(current_plant, temp_conversion) - && temp_conversion.cost <= points) - { - available_targets.push(temp_conversion); - } - } - - // How many pieces of fruit did we use up? - int points_used = starting_points - points; - int fruit_used = points_used / points_per_fruit; - if (points_used % points_per_fruit) - fruit_used++; - - // The player didn't have enough points to upgrade anything (probably - // supplied only one fruit). - if (!fruit_used) - { - mpr("Not enough fruit to cause evolution."); - return (false); } - dec_inv_item_quantity(rc, fruit_used); - - // Mention how many plants were used. - if (fruit_used > 1) - mprf("%d pieces of fruit are consumed!", fruit_used); - else - mpr("A piece of fruit is consumed!"); - - // Messaging for generated plants. - if (plants_evolved > 1) - mprf("%d plants can now spit acid.", plants_evolved); - else if (plants_evolved == 1) - mpr("A plant can now spit acid."); - - if (toadstools_evolved > 1) - mprf("%d toadstools gained stability.", toadstools_evolved); - else if (toadstools_evolved == 1) - mpr("A toadstool gained stability."); - - if (fungi_evolved > 1) + if (fruit_used) { - mprf("%d fungal colonies can now pick up their mycelia and move.", - fungi_evolved); + _decrease_amount(collected_fruit, fruit_used); } - else if (fungi_evolved == 1) - mpr("A fungal colony can now pick up its mycelia and move."); return (true); } diff --git a/crawl-ref/source/godwrath.cc b/crawl-ref/source/godwrath.cc index 5be08ab8f1..a2ad1c79ed 100644 --- a/crawl-ref/source/godwrath.cc +++ b/crawl-ref/source/godwrath.cc @@ -91,8 +91,9 @@ static bool _okawaru_random_servant() : MONS_TITAN); // 5% return (create_monster( - mgen_data::hostile_at(mon_type, "the fury of Okawaru", - true, 0, 0, you.pos(), 0, GOD_OKAWARU)) != -1); + mgen_data::hostile_at(mon_type, "the fury of Okawaru", + true, 6, MON_SUMM_WRATH, you.pos(), 0, + GOD_OKAWARU)) != -1); } static bool _tso_retribution() diff --git a/crawl-ref/source/mon-act.cc b/crawl-ref/source/mon-act.cc index 2065414df9..bc15130cc4 100644 --- a/crawl-ref/source/mon-act.cc +++ b/crawl-ref/source/mon-act.cc @@ -44,6 +44,7 @@ #include "random.h" #include "religion.h" #include "shopping.h" // for item values +#include "spells1.h" #include "state.h" #include "stuff.h" #include "terrain.h" @@ -739,6 +740,10 @@ static bool _handle_reaching(monsters *monster) bool ret = false; item_def *wpn = monster->weapon(0); const mon_attack_def attk(mons_attack_spec(monster, 0)); + actor *foe = monster->get_foe(); + + if (!foe) + return (false); if (monster->submerged()) return (false); @@ -746,47 +751,35 @@ static bool _handle_reaching(monsters *monster) if (mons_aligned(monster->mindex(), monster->foe)) return (false); - if ((wpn && get_weapon_brand(*wpn) == SPWPN_REACHING) - || (attk.flavour == AF_REACH && attk.damage)) + const coord_def foepos(foe->pos()); + const coord_def delta(foepos - monster->pos()); + const int grid_distance(delta.rdist()); + const coord_def middle(monster->pos() + delta / 2); + + if (grid_distance == 2 + // The monster has to be attacking the correct position. + && monster->target == foepos + // With a reaching weapon OR ... + && ((wpn && get_weapon_brand(*wpn) == SPWPN_REACHING) + // ... with a native reaching attack, provided the attack + // is not on a full diagonal. + || (attk.flavour == AF_REACH && attk.damage + && delta.abs() <= 5)) + // And with no dungeon furniture in the way of the reaching + // attack; if the middle square is empty, skip the LOS check. + && (grd(middle) > DNGN_MAX_NONREACH + || (monster->foe == MHITYOU? + you.see_cell_no_trans(monster->pos()) + : monster->mon_see_cell(foepos, true)))) { - if (monster->foe == MHITYOU) - { - const coord_def delta = monster->pos() - you.pos(); - const int x_middle = std::max(monster->pos().x, you.pos().x) - - (abs(delta.x) / 2); - const int y_middle = std::max(monster->pos().y, you.pos().y) - - (abs(delta.y) / 2); - const coord_def middle(x_middle, y_middle); + ret = true; + monster_attack_actor(monster, foe, false); - // This check isn't redundant -- player may be invisible. - if (monster->target == you.pos() - && grid_distance(monster->pos(), you.pos()) == 2 - && (you.see_cell_no_trans(monster->pos()) - || grd(middle) > DNGN_MAX_NONREACH)) - { - ret = true; - monster_attack(monster, false); - } - } - else if (monster->foe != MHITNOT) - { - monsters& mfoe = menv[monster->foe]; - coord_def foepos = mfoe.pos(); - // Same comments as to invisibility as above. - if (monster->target == foepos - && monster->mon_see_cell(foepos, true) - && grid_distance(monster->pos(), foepos) == 2) - { - ret = true; - monsters_fight(monster, &mfoe, false); - } - } + // Player saw the item reach. + if (wpn && !is_artefact(*wpn) && you.can_see(monster)) + set_ident_flags(*wpn, ISFLAG_KNOW_TYPE); } - // Player saw the item reach. - if (ret && wpn && !is_artefact(*wpn) && you.can_see(monster)) - set_ident_flags(*wpn, ISFLAG_KNOW_TYPE); - return (ret); } @@ -3454,6 +3447,13 @@ static bool _monster_move(monsters *monster) 2 + random2(3), monster->kill_alignment(), KILL_MON_MISSILE ); } + + // Commented out, but left in as an example of gloom. {due} + //if (monster->type == MONS_SHADOW) + //{ + // big_cloud (CLOUD_GLOOM, monster->kill_alignment(), monster->pos(), 10 + random2(5), 2 + random2(8)); + //} + } else { diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index b46e13b2c0..26ab9513fb 100644 --- a/crawl-ref/source/mon-data.h +++ b/crawl-ref/source/mon-data.h @@ -1532,7 +1532,7 @@ static monsterentry mondata[] = { MONS_SNAPPING_TURTLE, 't', GREEN, "snapping turtle", M_COLD_BLOOD, MR_NO_FLAGS, - 500, 5, MONS_SNAPPING_TURTLE, MONS_SNAPPING_TURTLE, MH_NATURAL, -3, + 500, 10, MONS_SNAPPING_TURTLE, MONS_SNAPPING_TURTLE, MH_NATURAL, -3, { {AT_BITE, AF_REACH, 30}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 10, 3, 6, 0 }, 16, 5, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_HISS, @@ -1544,7 +1544,7 @@ static monsterentry mondata[] = { MONS_ALLIGATOR_SNAPPING_TURTLE, 't', LIGHTGREEN, "alligator snapping turtle", M_COLD_BLOOD, MR_NO_FLAGS, - 1000, 5, MONS_SNAPPING_TURTLE, MONS_ALLIGATOR_SNAPPING_TURTLE, + 1000, 10, MONS_SNAPPING_TURTLE, MONS_ALLIGATOR_SNAPPING_TURTLE, MH_NATURAL, -3, { {AT_BITE, AF_REACH, 50}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 16, 7, 4, 0 }, diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index 9bb2e8a298..d1d6f659a9 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -6103,13 +6103,14 @@ void monsters::react_to_damage(int damage, beam_type flavour, kill_category whos static const char *enchant_names[] = { - "none", "slow", "haste", "might", "fear", "conf", "inv", "pois", "bers", - "rot", "summon", "abj", "backlit", "charm", "fire", - "gloshifter", "shifter", "tp", "wary", "submerged", - "short-lived", "paralysis", "sick", "sleep", "fatigue", "held", - "blood-lust", "neutral", "petrifying", "petrified", "magic-vulnerable", - "soul-ripe", "decay", "hungry", "flopping", "spore-producing", - "downtrodden", "swift", "tide", "frenzied", "bug" + "none", "berserk", "haste", "might", "fatigue", "slow", "fear", + "confusion", "invis", "poison", "rot", "summon", "abj", "corona", + "charm", "sticky_flame", "glowing_shapeshifter", "shapeshifter", "tp", + "sleep_wary", "submerged", "short_lived", "paralysis", "sick", + "sleepy", "held", "battle_frenzy", "temp_pacif", "petrifying", + "petrified", "lowered_mr", "soul_ripe", "slowly_dying", "eat_items", + "aquatic_land", "spore_production", "slouch", "swift", "tide", + "insane", "buggy" }; static const char *_mons_enchantment_name(enchant_type ench) diff --git a/crawl-ref/source/newgame.cc b/crawl-ref/source/newgame.cc index cf51b30a1a..f3358e52f4 100644 --- a/crawl-ref/source/newgame.cc +++ b/crawl-ref/source/newgame.cc @@ -4515,7 +4515,7 @@ bool _give_items_skills() you.skills[SK_STEALTH] = 2; you.skills[SK_STABBING] = 2; you.skills[SK_TRAPS_DOORS] = 2; - you.skills[SK_CROSSBOWS] = 1; + you.skills[SK_THROWING] = 2; break; case JOB_ASSASSIN: diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 3d5fe9d31e..0c79623409 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -299,11 +299,11 @@ const char* god_gain_power_messages[NUM_GODS][MAX_GOD_ABILITIES] = "call upon Jiyva to remove your harmful mutations" }, // Fedhas - { "call sunshine", + { "induce evolution", + "call sunshine", "cause a ring of plants to grow", - "control the weather", "spawn explosive spores", - "induce evolution" + "control the weather" }, // Cheibriados { "Cheibriados is slowing your {biology}.", @@ -406,11 +406,11 @@ const char* god_lose_power_messages[NUM_GODS][MAX_GOD_ABILITIES] = "call upon Jiyva to remove your harmful mutations" }, // Fedhas - { "call sunshine", + { "induce evolution", + "call sunshine", "cause a ring of plants to grow", - "control the weather", "spawn explosive spores", - "induce evolution" + "control the weather" }, // Cheibriados { "Cheibriados will no longer slow your {biology}.", @@ -2812,6 +2812,21 @@ bool did_god_conduct(conduct_type thing_done, int level, bool known, case DID_FRIEND_DIED: switch (you.religion) { + + case GOD_FEDHAS: + // Toadstools are exempt from this conduct + if (victim && fedhas_protects(victim) + && victim->mons_species() != MONS_TOADSTOOL) + { + // level is (1 + monsterHD/2) for this conduct, + // trying a fixed cost since plant HD aren't that + // meaningful. -cao + piety_change = -1; + retval = true; + break; + } + break; + case GOD_ELYVILON: // healer god cares more about this // Converted allies (marked as TSOites) can be martyrs. if (victim && victim->god == GOD_SHINING_ONE) @@ -2829,17 +2844,6 @@ bool did_god_conduct(conduct_type thing_done, int level, bool known, break; // fall through - case GOD_FEDHAS: - // double-check god because of fall-throughs from other gods - // Toadstools are an exception for this conduct - if (you.religion == GOD_FEDHAS && (!victim - || !fedhas_protects(victim) - || victim->mons_species() == MONS_TOADSTOOL)) - { - break; - } - // fall through - case GOD_OKAWARU: piety_change = -level; retval = true; diff --git a/crawl-ref/source/rltiles/dc-misc.txt b/crawl-ref/source/rltiles/dc-misc.txt index 92329d2dd8..8050483dcd 100644 --- a/crawl-ref/source/rltiles/dc-misc.txt +++ b/crawl-ref/source/rltiles/dc-misc.txt @@ -42,6 +42,8 @@ cloud_rain1 CLOUD_RAIN cloud_rain2 cloud_grey_smoke CLOUD_MIST +cloud_gloom CLOUD_GLOOM + #########MAP %sdir dc-misc %corpse 0 diff --git a/crawl-ref/source/rltiles/dc-mon.txt b/crawl-ref/source/rltiles/dc-mon.txt index 3570121966..16983a8b83 100644 --- a/crawl-ref/source/rltiles/dc-mon.txt +++ b/crawl-ref/source/rltiles/dc-mon.txt @@ -193,6 +193,7 @@ pit_fiend MONS_PIT_FIEND shadow_fiend MONS_SHADOW_FIEND # type '2' demons +beast MONS_BEAST ice_devil MONS_ICE_DEVIL lorocyproca MONS_LOROCYPROCA reaper MONS_REAPER @@ -204,7 +205,6 @@ blue_devil MONS_BLUE_DEVIL chaos_spawn MONS_CHAOS_SPAWN demonic_crawler MONS_DEMONIC_CRAWLER hellion MONS_HELLION -hellwing MONS_HELLWING iron_devil MONS_IRON_DEVIL neqoxec MONS_NEQOXEC orange_demon MONS_ORANGE_DEMON @@ -213,11 +213,12 @@ tormentor MONS_TORMENTOR ynoxinul MONS_YNOXINUL # type '4' demons -beast MONS_BEAST hairy_devil MONS_HAIRY_DEVIL red_devil MONS_RED_DEVIL rotting_devil MONS_ROTTING_DEVIL smoke_demon MONS_SMOKE_DEMON +#sixfirhy MONS_SIXFIRHY +hellwing MONS_HELLWING # type '5' demons imp MONS_IMP diff --git a/crawl-ref/source/rltiles/effect/cloud_gloom.png b/crawl-ref/source/rltiles/effect/cloud_gloom.png Binary files differnew file mode 100644 index 0000000000..914e500a3c --- /dev/null +++ b/crawl-ref/source/rltiles/effect/cloud_gloom.png diff --git a/crawl-ref/source/show.cc b/crawl-ref/source/show.cc index 0148d92438..342c424dcd 100644 --- a/crawl-ref/source/show.cc +++ b/crawl-ref/source/show.cc @@ -272,7 +272,11 @@ void show_def::_update_cloud(int cloudno) const coord_def e = grid2show(env.cloud[cloudno].pos); int which_colour = get_cloud_colour(cloudno); _set_backup(e); - grid(e).cls = SH_CLOUD; + if (env.cloud[cloudno].type != CLOUD_GLOOM) + { + grid(e).cls = SH_CLOUD; + } + grid(e).colour = which_colour; #ifdef USE_TILE diff --git a/crawl-ref/source/skills2.cc b/crawl-ref/source/skills2.cc index 3dd241f9fd..2d182e0b4b 100644 --- a/crawl-ref/source/skills2.cc +++ b/crawl-ref/source/skills2.cc @@ -1283,11 +1283,14 @@ static const skill_type skill_display_order[] = SK_BLANK_LINE, - SK_ARMOUR, SK_DODGING, SK_STEALTH, SK_STABBING, SK_SHIELDS, SK_TRAPS_DOORS, + SK_ARMOUR, SK_DODGING, SK_STABBING, SK_SHIELDS, - SK_BLANK_LINE, SK_COLUMN_BREAK, + SK_STEALTH, SK_TRAPS_DOORS, + + SK_BLANK_LINE, + SK_SPELLCASTING, SK_CONJURATIONS, SK_ENCHANTMENTS, SK_SUMMONINGS, SK_NECROMANCY, SK_TRANSLOCATIONS, SK_TRANSMUTATIONS, SK_FIRE_MAGIC, SK_ICE_MAGIC, SK_AIR_MAGIC, SK_EARTH_MAGIC, SK_POISON_MAGIC, @@ -1370,7 +1373,7 @@ static void _display_skill_table(bool show_aptitudes, bool show_description) if (you.skills[x] == 27) textcolor(YELLOW); - if (you.skills[x] == 0 || you.skills[x] == 27) + if (you.skills[x] == 0 || !show_description && you.skills[x] == 27) putch(' '); else putch(lcount++); @@ -1437,7 +1440,7 @@ static void _display_skill_table(bool show_aptitudes, bool show_description) else { // NOTE: If any more skills added, must adapt letters to go into caps. - cgotoxy(1, bottom_line-2); + cgotoxy(1, bottom_line-3); textcolor(LIGHTGREY); if (show_description) @@ -1449,7 +1452,8 @@ static void _display_skill_table(bool show_aptitudes, bool show_description) else { cprintf("Press the letter of a skill to choose whether you want to " - "practise it."); + "practise it." EOL "Skills marked with '+' will train more " + "quickly than those with '-'."); } cgotoxy(1, bottom_line-1); @@ -1517,7 +1521,10 @@ void show_skills() if (x == SK_BLANK_LINE || x == SK_COLUMN_BREAK) continue; - if (you.skills[x] == 0 || you.skills[x] == 27) + if (you.skills[x] == 0) + continue; + + if (!show_description && you.skills[x] == 27) continue; if (keyin == lcount) diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc index 9e5b4fd390..d56139759a 100644 --- a/crawl-ref/source/tilepick.cc +++ b/crawl-ref/source/tilepick.cc @@ -817,10 +817,12 @@ int tileidx_monster_base(const monsters *mon, bool detected) return TILEP_MONS_HAIRY_DEVIL; case MONS_ROTTING_DEVIL: return TILEP_MONS_ROTTING_DEVIL; - case MONS_BEAST: - return TILEP_MONS_BEAST; case MONS_SMOKE_DEMON: return TILEP_MONS_SMOKE_DEMON; +// case MONS_SIXFIRHY: // TODO +// return TILEP_MONS_SIXFIRHY; + case MONS_HELLWING: + return TILEP_MONS_HELLWING; // '3' demons case MONS_HELLION: @@ -835,8 +837,6 @@ int tileidx_monster_base(const monsters *mon, bool detected) return TILEP_MONS_NEQOXEC; case MONS_ORANGE_DEMON: return TILEP_MONS_ORANGE_DEMON; - case MONS_HELLWING: - return TILEP_MONS_HELLWING; case MONS_YNOXINUL: return TILEP_MONS_YNOXINUL; case MONS_DEMONIC_CRAWLER: @@ -847,6 +847,8 @@ int tileidx_monster_base(const monsters *mon, bool detected) return TILEP_MONS_CHAOS_SPAWN; // '2' demon + case MONS_BEAST: + return TILEP_MONS_BEAST; case MONS_SUN_DEMON: return TILEP_MONS_SUN_DEMON; case MONS_REAPER: @@ -2796,6 +2798,10 @@ static int _tileidx_cloud(cloud_struct cl) ch = TILE_CLOUD_RAIN + random2(tile_main_count(TILE_CLOUD_RAIN)); break; + case CLOUD_GLOOM: + ch = TILE_CLOUD_GLOOM; + break; + default: ch = TILE_CLOUD_GREY_SMOKE; break; |