diff options
author | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-09-28 08:27:29 +0000 |
---|---|---|
committer | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-09-28 08:27:29 +0000 |
commit | 3205c9289fd9ff8bcf739903a49215f75212128e (patch) | |
tree | 6a9b4a29e9e8bd96d4e8b87934d17ce84987a8e0 /crawl-ref/source | |
parent | dc3aa32db050e7923a4e802b874fccd997c1d6c6 (diff) | |
download | crawl-ref-3205c9289fd9ff8bcf739903a49215f75212128e.tar.gz crawl-ref-3205c9289fd9ff8bcf739903a49215f75212128e.zip |
crawl_state now keeps track of whether or not the current code is being
executed because of a god's actions, and if so which god (with "actions"
not including god-supplied invocations). Currently only used to prevent
Xom from being amused/stimulated by his own actions.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2235 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/acr.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/religion.cc | 35 | ||||
-rw-r--r-- | crawl-ref/source/state.cc | 102 | ||||
-rw-r--r-- | crawl-ref/source/state.h | 28 | ||||
-rw-r--r-- | crawl-ref/source/xom.cc | 37 |
5 files changed, 207 insertions, 1 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 2d35510bb4..9a427e6b6f 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -1183,6 +1183,8 @@ bool apply_berserk_penalty = false; */ static void input() { + crawl_state.clear_god_acting(); + if (crawl_state.is_replaying_keys() && crawl_state.is_repeating_cmd() && kbhit()) { @@ -1394,6 +1396,8 @@ static void input() curr_PlaceInfo += delta; curr_PlaceInfo.assert_validity(); } + + crawl_state.clear_god_acting(); } static bool toggle_flag( bool* flag, const char* flagname ) @@ -2604,6 +2608,8 @@ static void check_banished() static void world_reacts() { + crawl_state.clear_god_acting(); + if (Options.stash_tracking) stashes.update_visible_stashes( Options.stash_tracking == STM_ALL? diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 52f3f4b452..abedd6393d 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -542,6 +542,8 @@ static void do_god_gift(bool prayed_for) if (prayed_for != (you.religion == GOD_ZIN)) return; + crawl_state.inc_god_acting(); + #if DEBUG_DIAGNOSTICS || DEBUG_GIFTS int old_gifts = you.num_gifts[ you.religion ]; #endif @@ -816,6 +818,7 @@ static void do_god_gift(bool prayed_for) mprf(MSGCH_DIAGNOSTICS, "Total number of gifts from this god: %d", you.num_gifts[ you.religion ] ); #endif + crawl_state.dec_god_acting(); } static bool is_risky_sacrifice(const item_def& item) @@ -1125,6 +1128,8 @@ bool did_god_conduct( conduct_type thing_done, int level, const actor *victim ) if (you.religion == GOD_NO_GOD || you.religion == GOD_XOM) return (false); + crawl_state.inc_god_acting(); + switch (thing_done) { case DID_DRINK_BLOOD: @@ -1581,6 +1586,8 @@ bool did_god_conduct( conduct_type thing_done, int level, const actor *victim ) } #endif + crawl_state.dec_god_acting(); + return (ret); } @@ -1703,6 +1710,8 @@ bool ely_destroy_weapons() if (you.religion != GOD_ELYVILON) return false; + crawl_state.inc_god_acting(); + bool success = false; int i = igrd[you.x_pos][you.y_pos]; while (i != NON_ITEM) @@ -1745,6 +1754,8 @@ bool ely_destroy_weapons() mpr("There are no weapons here to destroy!"); } + crawl_state.dec_god_acting(); + return success; } @@ -1753,6 +1764,8 @@ void trog_burn_books() if (you.religion != GOD_TROG) return; + crawl_state.inc_god_acting(); + int i = igrd[you.x_pos][you.y_pos]; while (i != NON_ITEM) { @@ -1863,6 +1876,7 @@ void trog_burn_books() simple_god_message(" is delighted!", GOD_TROG); gain_piety(totalpiety); } + crawl_state.dec_god_acting(); } void lose_piety(int pgn) @@ -2516,6 +2530,8 @@ void divine_retribution( god_type god ) if (god == you.religion && is_good_god(god) ) return; + crawl_state.inc_god_acting(god, true); + // Just the thought of retribution (getting this far) mollifies // the god by at least a point... the punishment might reduce // penance further. @@ -2566,6 +2582,7 @@ void divine_retribution( god_type god ) } } } + crawl_state.dec_god_acting(god); } // upon excommunication, (now ex) Beogh adepts lose their orcish followers @@ -2658,6 +2675,8 @@ bool followers_abandon_you() // Destroying orcish idols (a.k.a. idols of Beogh) may anger Beogh void beogh_idol_revenge() { + crawl_state.inc_god_acting(GOD_BEOGH, true); + // Beogh watches his charges closely, but for others doesn't always notice if (you.religion == GOD_BEOGH || (you.species == SP_HILL_ORC && coinflip()) @@ -2713,12 +2732,16 @@ void beogh_idol_revenge() did_god_conduct(DID_ATTACK_FRIEND, 8); } } + + crawl_state.dec_god_acting(GOD_BEOGH); } void excommunication(void) { const god_type old_god = you.religion; + crawl_state.inc_god_acting(old_god, true); + take_note(Note(NOTE_LOSE_GOD, old_god)); you.duration[DUR_PRAYER] = 0; @@ -2810,6 +2833,8 @@ void excommunication(void) inc_penance( old_god, 25 ); break; } + + crawl_state.dec_god_acting(old_god); } // end excommunication() static bool bless_weapon( int god, int brand, int colour ) @@ -2872,6 +2897,8 @@ void altar_prayer(void) if (you.religion == GOD_XOM) return; + crawl_state.inc_god_acting(); + // TSO blesses long swords with holy wrath if (you.religion == GOD_SHINING_ONE && !you.num_gifts[GOD_SHINING_ONE] @@ -2924,6 +2951,8 @@ void altar_prayer(void) } offer_items(); + + crawl_state.dec_god_acting(); } // end altar_prayer() static bool god_likes_items(god_type god) @@ -2970,6 +2999,8 @@ void offer_items() if (you.religion == GOD_NO_GOD || !god_likes_items(you.religion)) return; + crawl_state.inc_god_acting(); + int num_sacced = 0; int i = igrd[you.x_pos][you.y_pos]; while (i != NON_ITEM) @@ -3094,6 +3125,8 @@ void offer_items() if (num_sacced > 0 && you.religion == GOD_NEMELEX_XOBEH) show_pure_deck_chances(); #endif + + crawl_state.dec_god_acting(); } void god_pitch(god_type which_god) @@ -3117,7 +3150,9 @@ void god_pitch(god_type which_god) if (which_god == GOD_LUGONU && you.penance[GOD_LUGONU]) { simple_god_message(" is most displeased with you!", which_god); + crawl_state.inc_god_acting(GOD_LUGONU, true); lugonu_retribution(); + crawl_state.dec_god_acting(GOD_LUGONU); return; } diff --git a/crawl-ref/source/state.cc b/crawl-ref/source/state.cc index 03cd5817db..25e314eda6 100644 --- a/crawl-ref/source/state.cc +++ b/crawl-ref/source/state.cc @@ -240,3 +240,105 @@ void game_state::reset_cmd_again() prev_cmd_keys.clear(); } + +/////////////////////////////////////////////////////////// +// Keeping track of which god is currently doing something +/////////////////////////////////////////////////////////// + +god_act_state::god_act_state() +{ + reset(); +} + +void god_act_state::reset() +{ + which_god = GOD_NO_GOD; + retribution = false; + depth = 0; +} + +bool game_state::is_god_acting() const +{ + ASSERT(god_act.depth >= 0); + ASSERT(!(god_act.depth > 0 && god_act.which_god == GOD_NO_GOD)); + ASSERT(!(god_act.depth == 0 && god_act.which_god != GOD_NO_GOD)); + ASSERT(!(god_act.depth == 0 && god_act_stack.size() > 0)); + + return (god_act.depth > 0); +} + +bool game_state::is_god_retribution() const +{ + ASSERT(is_god_acting()); + + return (god_act.retribution); +} + +god_type game_state::which_god_acting() const +{ + return god_act.which_god; +} + +void game_state::inc_god_acting(bool is_retribution) +{ + inc_god_acting(you.religion, is_retribution); +} + +void game_state::inc_god_acting(god_type which_god, bool is_retribution) +{ + ASSERT(which_god != GOD_NO_GOD); + + if (god_act.which_god != GOD_NO_GOD && + god_act.which_god != which_god) + { + ASSERT(god_act.depth >= 1); + + god_act_stack.push_back(god_act); + god_act.reset(); + } + + god_act.which_god = which_god; + god_act.retribution = is_retribution; + god_act.depth++; +} + +void game_state::dec_god_acting() +{ + dec_god_acting(you.religion); +} + +void game_state::dec_god_acting(god_type which_god) +{ + ASSERT(which_god != GOD_NO_GOD); + ASSERT(god_act.depth > 0); + ASSERT(god_act.which_god == which_god); + + god_act.depth--; + + if (god_act.depth == 0) + { + god_act.reset(); + if (god_act_stack.size() > 0) + { + god_act = god_act_stack[god_act_stack.size() - 1]; + god_act_stack.pop_back(); + ASSERT(god_act.depth >= 1); + ASSERT(god_act.which_god != GOD_NO_GOD); + ASSERT(god_act.which_god != which_god); + } + } +} + +void game_state::clear_god_acting() +{ + ASSERT(!is_god_acting()); + ASSERT(god_act_stack.size() == 0); + + god_act.reset(); +} + +std::vector<god_act_state> game_state::other_gods_acting() const +{ + ASSERT(is_god_acting()); + return god_act_stack; +} diff --git a/crawl-ref/source/state.h b/crawl-ref/source/state.h index 0f4da3bbbd..8e5a9cc4b5 100644 --- a/crawl-ref/source/state.h +++ b/crawl-ref/source/state.h @@ -13,6 +13,20 @@ #ifndef STATE_H #define STATE_H +#include "enum.h" + +struct god_act_state +{ +public: + + god_act_state(); + void reset(); + + god_type which_god; + bool retribution; + int depth; +}; + // Track various aspects of Crawl game state. struct game_state { @@ -58,6 +72,9 @@ protected: void reset_cmd_repeat(); void reset_cmd_again(); + god_act_state god_act; + std::vector<god_act_state> god_act_stack; + public: game_state(); @@ -78,6 +95,17 @@ public: if (terminal_resize_check) (*terminal_resize_check)(); } + + bool is_god_acting() const; + bool is_god_retribution() const; + god_type which_god_acting() const; + void inc_god_acting(bool is_retribution = false); + void inc_god_acting(god_type which_god, bool is_retribution = false); + void dec_god_acting(); + void dec_god_acting(god_type which_god); + void clear_god_acting(); + + std::vector<god_act_state> other_gods_acting() const; }; extern game_state crawl_state; diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc index 8293fc4925..ed8b244b5c 100644 --- a/crawl-ref/source/xom.cc +++ b/crawl-ref/source/xom.cc @@ -25,6 +25,7 @@ #include "spells3.h" #include "spl-cast.h" #include "spl-util.h" +#include "state.h" #include "stuff.h" #include "view.h" @@ -113,6 +114,11 @@ void xom_is_stimulated(int maxinterestingness) { if (you.religion != GOD_XOM) return; + + // Xom is not stimulated by his own acts, at least not directly. + if (crawl_state.which_god_acting() == GOD_XOM) + return; + int interestingness = random2(maxinterestingness); if (interestingness < 12) return; @@ -135,6 +141,8 @@ void xom_makes_you_cast_random_spell(int sever) { int spellenum = sever; + crawl_state.inc_god_acting(GOD_XOM); + const int nxomspells = ARRAYSIZE(xom_spells); if (spellenum >= nxomspells) spellenum = nxomspells - 1; @@ -149,6 +157,8 @@ void xom_makes_you_cast_random_spell(int sever) #endif your_spells(spell, sever, false); + + crawl_state.dec_god_acting(GOD_XOM); } static void xom_make_item(object_class_type base, @@ -165,11 +175,15 @@ static void xom_make_item(object_class_type base, return; } + crawl_state.inc_god_acting(GOD_XOM); + move_item_to_grid( &thing_created, you.x_pos, you.y_pos ); canned_msg(MSG_SOMETHING_APPEARS); stop_running(); origin_acquired(mitm[thing_created], GOD_XOM); + + crawl_state.dec_god_acting(GOD_XOM); } static object_class_type get_unrelated_wield_class(object_class_type ref) @@ -197,11 +211,16 @@ static object_class_type get_unrelated_wield_class(object_class_type ref) (temp_rand == 1) ? OBJ_STAVES : OBJ_MISCELLANY; } + return (objtype); } static bool xom_annoyance_gift(int power) { + // Can't simply use unwind_var because of the way that god act + // state is maintained. + crawl_state.inc_god_acting(GOD_XOM); + if (coinflip() && player_in_a_dangerous_place()) { const item_def *weapon = you.weapon(); @@ -216,6 +235,7 @@ static bool xom_annoyance_gift(int power) xom_make_item(weapon->base_type, weapon->sub_type, power * 3); else acquirement(weapon->base_type, GOD_XOM); + crawl_state.dec_god_acting(GOD_XOM); return (true); } @@ -228,6 +248,7 @@ static bool xom_annoyance_gift(int power) // A random ring. (Not necessarily a good one.) god_speaks(GOD_XOM, RANDOM_ELEMENT(xom_try_this)); xom_make_item(OBJ_JEWELLERY, get_random_ring_type(), power * 3); + crawl_state.dec_god_acting(GOD_XOM); return (true); }; @@ -238,6 +259,7 @@ static bool xom_annoyance_gift(int power) // you an amulet. Ha ha! god_speaks(GOD_XOM, RANDOM_ELEMENT(xom_try_this)); xom_make_item(OBJ_JEWELLERY, get_random_amulet_type(), power * 3); + crawl_state.dec_god_acting(GOD_XOM); return (true); }; @@ -250,6 +272,7 @@ static bool xom_annoyance_gift(int power) // a ring. Ha ha! god_speaks(GOD_XOM, RANDOM_ELEMENT(xom_try_this_ring)); xom_make_item(OBJ_JEWELLERY, get_random_ring_type(), power * 3); + crawl_state.dec_god_acting(GOD_XOM); return (true); } @@ -266,9 +289,12 @@ static bool xom_annoyance_gift(int power) acquirement(objtype, GOD_XOM); else xom_make_item(objtype, OBJ_RANDOM, power * 3); + crawl_state.dec_god_acting(GOD_XOM); return (true); } } + + crawl_state.dec_god_acting(GOD_XOM); return (false); } @@ -276,7 +302,7 @@ bool xom_gives_item(int power) { if (xom_annoyance_gift(power)) return (true); - + const item_def *cloak = you.slot_item(EQ_CLOAK); if (coinflip() && cloak && cloak->cursed()) { @@ -310,7 +336,10 @@ bool xom_gives_item(int power) (r == 5) ? OBJ_FOOD : (r == 6) ? OBJ_MISCELLANY : OBJ_GOLD; + + crawl_state.inc_god_acting(GOD_XOM); acquirement(objtype, GOD_XOM); + crawl_state.dec_god_acting(GOD_XOM); } else { @@ -397,6 +426,7 @@ static bool xom_is_good(int sever) // Okay, now for the nicer stuff (note: these things are not // necessarily nice): + crawl_state.inc_god_acting(GOD_XOM); if (random2(sever) <= 1) { temp_rand = random2(4); @@ -579,6 +609,7 @@ static bool xom_is_good(int sever) done = true; } + crawl_state.dec_god_acting(GOD_XOM); return (done); } @@ -590,6 +621,8 @@ static bool xom_is_bad(int sever) bolt beam; + crawl_state.inc_god_acting(GOD_XOM); + // begin "Bad Things" while (!done) { @@ -778,6 +811,8 @@ static bool xom_is_bad(int sever) } } + crawl_state.dec_god_acting(GOD_XOM); + return (done); } |