diff options
author | j-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-01-30 16:04:28 +0000 |
---|---|---|
committer | j-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-01-30 16:04:28 +0000 |
commit | 160795e120184775ee58bdb01a12b42895c3f62a (patch) | |
tree | 5fb482ee43f938d1592d87feb119c7ba934c81dd /crawl-ref/source/delay.cc | |
parent | 9434334816f9a2404a18876899d74df04daab77f (diff) | |
download | crawl-ref-160795e120184775ee58bdb01a12b42895c3f62a.tar.gz crawl-ref-160795e120184775ee58bdb01a12b42895c3f62a.zip |
Improved recite. It now directly compares power (calculated using Invocations
and piety) with monsters' magic resistance. If the latter exceeds the former
or you get a bad roll, the bad effects (haste or berserk) will happen.
Otherwise you get one of a number of good effects the choice of which depends
on your power again. This is probably still too strict, but much better than
the older system.
Unfortunately I had to cut the influene of the number of attempts as
apply_area_visible currently only transfers power. So it's a clear 50%
chance of "nothing happens" each turn, leaving us at 12.5% of nothing
happening during 3 turns, plus a saving throw from bad effects.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3379 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/delay.cc')
-rw-r--r-- | crawl-ref/source/delay.cc | 184 |
1 files changed, 86 insertions, 98 deletions
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc index 50380cf0b2..e08e74998a 100644 --- a/crawl-ref/source/delay.cc +++ b/crawl-ref/source/delay.cc @@ -53,137 +53,112 @@ static void handle_macro_delay(); static void finish_delay(const delay_queue_item &delay); // monster cannot be affected in these states +// (all results of Recite, plus friendly) static bool recite_mons_useless(const monsters *mon) { - return (mons_is_fleeing(mon) + return (mons_intel(mon->type) < I_NORMAL + || mons_is_fleeing(mon) || mons_is_sleeping(mon) || mons_friendly(mon) || mons_neutral(mon) + || mons_is_confused(mon) + || mons_is_paralysed(mon) || mon->has_ench(ENCH_BERSERK)); } -static int recite_to_monsters(int x, int y, int pow, int turn) +static int recite_to_monsters(int x, int y, int pow, int unused) { + UNUSED(unused); + const int mon = mgrd[x][y]; if (mon == NON_MONSTER) return (0); monsters *mons = &menv[mon]; - // monster must be intelligent - if (mons_intel(mons->type) < I_NORMAL) - return (0); - if (recite_mons_useless(mons)) return (0); - int attempt = 3 - turn; - bool bad_effect = - (mons_class_holiness(mon) == MH_DEMONIC? !one_chance_in(8) - : pow < random2(attempt*5)); - - // 50% chance nothing happens - if (bad_effect && coinflip()) + if (coinflip()) // nothing happens return (0); - bool resist = check_mons_resist_magic(mons, pow); + const int resist = mons_resist_magic(mons); + pow -= resist; + + // much lower chances at influencing demons + if (mons_class_holiness(mon) == MH_DEMONIC) + pow -= 3 + random2(5); - if (bad_effect) // can still have positive effects + if (pow > 0) + pow = random2avg(pow,2); + + if (pow <= 0) // Uh oh... { - if (!resist) - { - if (one_chance_in(3) && mons->add_ench(mon_enchant(ENCH_CONFUSION, - 0, KC_YOU, (16 + random2avg(13, 2)) * 10))) - { - simple_monster_message(mons, " looks confused."); - return (1); - } - if (one_chance_in(4) && mons->add_ench(ENCH_FEAR)) - { - simple_monster_message(mons, " turns to flee."); - return (1); - } - if (one_chance_in(4)) - { - mons->put_to_sleep(); - simple_monster_message(mons, " falls asleep!"); - return (1); - } - } - if (one_chance_in(3) && mons->add_ench(mon_enchant(ENCH_HASTE, 0, - KC_YOU, (16 + random2avg(13, 2)) * 10))) - { - simple_monster_message(mons, " is annoyed!"); - return (1); - } - if (mons->can_go_berserk()) // seriously annoyed now - { + if (one_chance_in(resist+1)) // nothing happens, whew! + return (0); + + if (one_chance_in(4) && mons->can_go_berserk()) mons->go_berserk(true); - return (1); + else if (mons->add_ench(mon_enchant(ENCH_HASTE, 0, + KC_YOU, (16 + random2avg(13, 2)) * 10))) + { + simple_monster_message(mons, " speeds up in annoyance!"); } - return (0); // no effect - } - - if (resist) - { - simple_monster_message(mons, " resists!"); - return (0); + // bad effects stop the recital + stop_delay(); + return (1); } - switch (random2(pow)) + switch (pow) { - default: // nothing happens - return (0); + case 0: + return (0); // handled above + case 1: + case 2: + case 3: + case 4: + if (!mons->add_ench(mon_enchant(ENCH_CONFUSION, 0, KC_YOU, + (16 + random2avg(13, 2)) * 10))) + return (0); + simple_monster_message(mons, " looks confused."); + break; + case 5: case 6: case 7: - if (mons->add_ench(ENCH_FEAR)) - { - simple_monster_message(mons, " turns to flee."); - return (1); - } - break; case 8: + mons->put_to_sleep(); + simple_monster_message(mons, " falls asleep!"); + break; case 9: - mons->put_to_sleep(); - simple_monster_message(mons, " falls asleep!"); - return (1); case 10: case 11: case 12: - if (mons->add_ench(mon_enchant(ENCH_CONFUSION, 0, KC_YOU, - (16 + random2avg(13, 2)) * 10))) - { - simple_monster_message(mons, " looks confused."); - return (1); - } - break; + if (!mons->add_ench(ENCH_NEUTRAL)) + return (0); + simple_monster_message(mons, " seems impressed!"); + break; case 13: case 14: - if (mons->add_ench(mon_enchant(ENCH_PARALYSIS, 0, KC_YOU, - (16 + random2avg(13, 2)) * 10))) - { - simple_monster_message(mons, " is paralyzed!"); - return (1); - } - break; case 15: + if (!mons->add_ench(ENCH_FEAR)) + return (0); + simple_monster_message(mons, " turns to flee."); + break; case 16: case 17: - case 18: - if (mons->add_ench(ENCH_NEUTRAL)) - { - simple_monster_message(mons, " seems impressed!"); - return (1); - } - break; - case 19: - case 20: - mons->attitude = ATT_NEUTRAL; // but same message as above - simple_monster_message(mons, " seems impressed!"); - return (1); + if (!mons->add_ench(mon_enchant(ENCH_PARALYSIS, 0, KC_YOU, + (16 + random2avg(13, 2)) * 10))) + return (0); + simple_monster_message(mons, " freezes in fright!"); + break; + default: + // permanently neutral, but same message as enchantment + mons->attitude = ATT_NEUTRAL; + simple_monster_message(mons, " seems impressed!"); + break; } - return (0); + return (1); } // end recite_to_monsters() // Returns true if this delay can act as a parent to other delays, i.e. if @@ -435,10 +410,14 @@ bool is_being_butchered(const item_def &item) } // check whether there are monsters who might be influenced by Recite -bool check_recital_audience() +// return 0, if no monsters found +// return 1, if eligible audience found +// return -1, if entire audience already affected or too dumb to understand +int check_recital_audience() { int mid; monsters *mons; + bool found_monsters = false; for (int x = you.x_pos - 8; x <= you.x_pos + 8; x++) for (int y = you.y_pos - 8; y <= you.y_pos + 8; y++) @@ -451,20 +430,29 @@ bool check_recital_audience() continue; mons = &menv[mid]; + if (!found_monsters) + found_monsters = true; // can not be affected in these states if (recite_mons_useless(mons)) - continue;; + continue; - return (true); + return (1); } #ifdef DEBUG_DIAGNOSTICS - mprf(MSGCH_DIAGNOSTICS, "No audience found!"); + if (!found_monsters) + mprf(MSGCH_DIAGNOSTICS, "No audience found!"); + else + mprf(MSGCH_DIAGNOSTICS, "No sensible audience found!"); #endif + // no use preaching to the choir, nor to common animals + if (found_monsters) + return (-1); + // Sorry, no audience found! - return (false); + return (0); } // Xom is amused by a potential food source going to waste, and is @@ -509,7 +497,7 @@ void handle_delay( void ) mprf(MSGCH_MULTITURN_ACTION, "You begin to recite %s's Axioms of Law.", god_name(GOD_ZIN).c_str()); - apply_area_visible(recite_to_monsters, delay.parm1, delay.duration); + apply_area_visible(recite_to_monsters, delay.parm1); break; default: break; @@ -610,7 +598,7 @@ void handle_delay( void ) if ( delay.type == DELAY_RECITE) { - if (!check_recital_audience() // maybe no unaffected monsters in LOS? + if (check_recital_audience() < 1 // maybe you've lost your audience || Options.hp_warning && you.hp*Options.hp_warning <= you.hp_max && delay.parm2*Options.hp_warning > you.hp_max || you.hp*2 < delay.parm2) // or significant health drop @@ -658,7 +646,7 @@ void handle_delay( void ) case DELAY_RECITE: mpr("You continue reciting the Axioms of Law.", MSGCH_MULTITURN_ACTION); - apply_area_visible(recite_to_monsters, delay.parm1, delay.duration); + apply_area_visible(recite_to_monsters, delay.parm1); break; case DELAY_MULTIDROP: drop_item( items_for_multidrop[0].slot, |