From a36fd3f9f0e5bde3dd9d74e1742cfbd2f045c635 Mon Sep 17 00:00:00 2001 From: dshaligram Date: Mon, 21 Sep 2009 08:23:35 +0000 Subject: Allow vaults to request use of the acquirement code with "acquire " or "acquire: " in item specs (due). git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@10765 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/dungeon.cc | 19 ++++- crawl-ref/source/effects.cc | 199 +++++++++++++++++++++++--------------------- crawl-ref/source/effects.h | 4 + crawl-ref/source/items.cc | 6 ++ crawl-ref/source/items.h | 1 + crawl-ref/source/mapdef.cc | 26 ++++++ crawl-ref/source/mapdef.h | 8 +- crawl-ref/source/stuff.cc | 2 +- 8 files changed, 163 insertions(+), 102 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index f4a2b62621..f4f8a147bb 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -23,6 +23,7 @@ REVISION("$Rev$"); #include "chardump.h" #include "cloud.h" #include "defines.h" +#include "effects.h" #include "enum.h" #include "externs.h" #include "directn.h" @@ -4438,6 +4439,7 @@ static void _dgn_place_item_explicit(const item_spec &spec, return; object_class_type base_type = spec.base_type; + bool acquire = false; if (spec.level >= 0) level = spec.level; @@ -4456,6 +4458,9 @@ static void _dgn_place_item_explicit(const item_spec &spec, case ISPEC_SUPERB: level = MAKE_GOOD_ITEM; break; + case ISPEC_ACQUIREMENT: + acquire = true; + break; default: adjust_type = false; break; @@ -4465,14 +4470,22 @@ static void _dgn_place_item_explicit(const item_spec &spec, base_type = RANDOM_ELEMENT(_acquirement_item_classes); } - const int item_made = items( spec.allow_uniques, base_type, - spec.sub_type, true, level, spec.race, 0, - spec.ego ); + const int item_made = + (acquire ? + acquirement_create_item(base_type, spec.acquirement_source, + true, where) + : items( spec.allow_uniques, base_type, + spec.sub_type, true, level, spec.race, 0, + spec.ego )); if (item_made != NON_ITEM && item_made != -1) { item_def &item(mitm[item_made]); item.pos = where; + // Remove unsuitable inscriptions such as {god gift}. + item.inscription.clear(); + // And wipe item origin to remove "this is a god gift!" from there. + origin_reset(item); if (is_stackable_item(item) && spec.qty > 0) { item.quantity = spec.qty; diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index 9576d5b95e..83a048b643 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -1774,87 +1774,21 @@ static bool _do_book_acquirement(item_def &book, int agent) return (true); } -bool acquirement(object_class_type class_wanted, int agent, - bool quiet, int* item_index) +static int _failed_acquirement(bool quiet) { - ASSERT(!crawl_state.arena); - - int thing_created = NON_ITEM; - - if (item_index == NULL) - item_index = &thing_created; - - *item_index = NON_ITEM; - - while (class_wanted == OBJ_RANDOM) - { - ASSERT(!quiet); - mesclr(); - mpr("[a] Weapon [b] Armour [c] Jewellery [d] Book"); - mpr("[e] Staff [f] Wand [g] Miscellaneous [h] Food [i] Gold"); - mpr("What kind of item would you like to acquire? ", MSGCH_PROMPT); - - const int keyin = tolower( get_ch() ); - switch (keyin) - { - case 'a': case ')': class_wanted = OBJ_WEAPONS; break; - case 'b': case '[': case ']': class_wanted = OBJ_ARMOUR; break; - case 'c': case '=': case '"': class_wanted = OBJ_JEWELLERY; break; - case 'd': case '+': case ':': class_wanted = OBJ_BOOKS; break; - case 'e': case '\\': case '|': class_wanted = OBJ_STAVES; break; - case 'f': case '/': class_wanted = OBJ_WANDS; break; - case 'g': case '}': case '{': class_wanted = OBJ_MISCELLANY; break; - case 'h': case '%': class_wanted = OBJ_FOOD; break; - case 'i': case '$': class_wanted = OBJ_GOLD; break; - default: - // Lets wizards escape out of accidently choosing acquirement. - if (agent == AQ_WIZMODE) - { - canned_msg(MSG_OK); - return (false); - } - -#if defined(USE_UNIX_SIGNALS) && defined(SIGHUP_SAVE) && defined(USE_CURSES) - // If we've gotten a HUP signal then the player will be unable - // to make a selection. - if (crawl_state.seen_hups) - { - mpr("Acquirement interrupted by HUP signal.", MSGCH_ERROR); - you.turn_is_over = false; - return (false); - } -#endif - break; - } - } - - if (grid_destroys_items(grd(you.pos()))) - { - // How sad (and stupid). - if (!silenced(you.pos()) && !quiet) - mprf(MSGCH_SOUND, grid_item_destruction_message(grd(you.pos()))); - - if (agent > GOD_NO_GOD && agent < NUM_GODS) - { - if (agent == GOD_XOM) - simple_god_message(" snickers.", GOD_XOM); - else - { - ASSERT(!"God gave gift item while player was on grid which " - "destroys items."); - mprf(MSGCH_ERROR, "%s gave a god gift while you were on " - "terrain which destroys items.", - god_name((god_type) agent).c_str()); - } - } - - *item_index = NON_ITEM; + if (!quiet) + mpr("The demon of the infinite void smiles upon you."); + return (NON_ITEM); +} - // Well, the item may have fallen in the drink, but the intent is - // that acquirement happened. -- bwr - return (true); - } +int acquirement_create_item(object_class_type class_wanted, + int agent, + bool quiet, + const coord_def &pos) +{ + ASSERT(class_wanted != OBJ_RANDOM); + int thing_created = NON_ITEM; int quant = 1; for (int item_tries = 0; item_tries < 40; item_tries++) { @@ -2008,12 +1942,7 @@ bool acquirement(object_class_type class_wanted, int agent, } if (thing_created == NON_ITEM) - { - if (!quiet) - mpr("The demon of the infinite void smiles upon you."); - *item_index = NON_ITEM; - return (false); - } + return _failed_acquirement(quiet); // Easier to read this way. item_def& thing(mitm[thing_created]); @@ -2036,11 +1965,8 @@ bool acquirement(object_class_type class_wanted, int agent, { if (!_do_book_acquirement(thing, agent)) { - if (!quiet) - mpr("The demon of the infinite void smiles upon you."); - *item_index = NON_ITEM; destroy_item(thing, true); - return (false); + return _failed_acquirement(quiet); } mark_had_book(thing); } @@ -2164,21 +2090,102 @@ bool acquirement(object_class_type class_wanted, int agent, if (agent > GOD_NO_GOD && agent < NUM_GODS && agent == you.religion) thing.inscription = "god gift"; - move_item_to_grid( &thing_created, you.pos() ); + move_item_to_grid( &thing_created, pos ); // This should never actually be NON_ITEM because of the way // move_item_to_grid works (doesn't create a new item ever), // but we're checking it anyways. -- bwr - if (thing_created != NON_ITEM) + if (thing_created != NON_ITEM && !quiet) + canned_msg(MSG_SOMETHING_APPEARS); + + return (thing_created); +} + +bool acquirement(object_class_type class_wanted, int agent, + bool quiet, int* item_index) +{ + ASSERT(!crawl_state.arena); + + int thing_created = NON_ITEM; + + if (item_index == NULL) + item_index = &thing_created; + + *item_index = NON_ITEM; + + while (class_wanted == OBJ_RANDOM) { - if (!quiet) - canned_msg(MSG_SOMETHING_APPEARS); + ASSERT(!quiet); + mesclr(); + mpr("[a] Weapon [b] Armour [c] Jewellery [d] Book"); + mpr("[e] Staff [f] Wand [g] Miscellaneous [h] Food [i] Gold"); + mpr("What kind of item would you like to acquire? ", MSGCH_PROMPT); + + const int keyin = tolower( get_ch() ); + switch (keyin) + { + case 'a': case ')': class_wanted = OBJ_WEAPONS; break; + case 'b': case '[': case ']': class_wanted = OBJ_ARMOUR; break; + case 'c': case '=': case '"': class_wanted = OBJ_JEWELLERY; break; + case 'd': case '+': case ':': class_wanted = OBJ_BOOKS; break; + case 'e': case '\\': case '|': class_wanted = OBJ_STAVES; break; + case 'f': case '/': class_wanted = OBJ_WANDS; break; + case 'g': case '}': case '{': class_wanted = OBJ_MISCELLANY; break; + case 'h': case '%': class_wanted = OBJ_FOOD; break; + case 'i': case '$': class_wanted = OBJ_GOLD; break; + default: + // Lets wizards escape out of accidently choosing acquirement. + if (agent == AQ_WIZMODE) + { + canned_msg(MSG_OK); + return (false); + } + +#if defined(USE_UNIX_SIGNALS) && defined(SIGHUP_SAVE) && defined(USE_CURSES) + // If we've gotten a HUP signal then the player will be unable + // to make a selection. + if (crawl_state.seen_hups) + { + mpr("Acquirement interrupted by HUP signal.", MSGCH_ERROR); + you.turn_is_over = false; + return (false); + } +#endif + break; + } } - *item_index = thing_created; - // Well, the item may have fallen in the drink, but the intent is - // that acquirement happened. -- bwr - return (true); + if (grid_destroys_items(grd(you.pos()))) + { + // How sad (and stupid). + if (!silenced(you.pos()) && !quiet) + mprf(MSGCH_SOUND, grid_item_destruction_message(grd(you.pos()))); + + if (agent > GOD_NO_GOD && agent < NUM_GODS) + { + if (agent == GOD_XOM) + simple_god_message(" snickers.", GOD_XOM); + else + { + ASSERT(!"God gave gift item while player was on grid which " + "destroys items."); + mprf(MSGCH_ERROR, "%s gave a god gift while you were on " + "terrain which destroys items.", + god_name((god_type) agent).c_str()); + } + } + + *item_index = NON_ITEM; + + // Well, the item may have fallen in the drink, but the intent is + // that acquirement happened. -- bwr + return (true); + } + + *item_index = + acquirement_create_item(class_wanted, agent, quiet, you.pos()); + + return (*item_index != NON_ITEM); } bool recharge_wand(int item_slot) diff --git a/crawl-ref/source/effects.h b/crawl-ref/source/effects.h index f80f1bc4dd..440fc32e3d 100644 --- a/crawl-ref/source/effects.h +++ b/crawl-ref/source/effects.h @@ -86,6 +86,10 @@ void random_uselessness(int scroll_slot = -1); bool acquirement(object_class_type force_class, int agent, bool quiet = false, int *item_index = NULL); +int acquirement_create_item(object_class_type class_wanted, + int agent, + bool quiet, + const coord_def &pos); // last updated 12may2000 {dlb} /* *********************************************************************** diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index 2666b4d1ca..2f7929b391 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -831,6 +831,12 @@ bool origin_known(const item_def &item) return (item.orig_place != 0); } +void origin_reset(item_def &item) +{ + item.orig_place = 0; + item.orig_monnum = 0; +} + // We have no idea where the player found this item. void origin_set_unknown(item_def &item) { diff --git a/crawl-ref/source/items.h b/crawl-ref/source/items.h index 8a0c9bd397..275bac2b3c 100644 --- a/crawl-ref/source/items.h +++ b/crawl-ref/source/items.h @@ -135,6 +135,7 @@ bool drop_item( int item_dropped, int quant_drop, bool try_offer = false ); int get_equip_slot(const item_def *item); mon_inv_type get_mon_equip_slot(const monsters* mon, const item_def &item); +void origin_reset(item_def &item); void origin_set(const coord_def& where); void origin_set_monster(item_def &item, const monsters *monster); bool origin_known(const item_def &item); diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc index b9df39c83f..71f28e40f5 100644 --- a/crawl-ref/source/mapdef.cc +++ b/crawl-ref/source/mapdef.cc @@ -34,6 +34,7 @@ REVISION("$Rev$"); #include "monplace.h" #include "mon-util.h" #include "place.h" +#include "religion.h" #include "stuff.h" #include "tags.h" @@ -2823,6 +2824,15 @@ static int str_to_ego(item_spec &spec, std::string ego_str) return 0; } +int item_list::parse_acquirement_source(const std::string &source) +{ + const std::string god_name(replace_all_of(source, "_", " ")); + const god_type god(string_to_god(god_name.c_str(), true)); + if (god == GOD_NO_GOD) + error = make_stringf("unknown god name: '%s'", god_name.c_str()); + return (god); +} + item_spec item_list::parse_single_spec(std::string s) { item_spec result; @@ -2844,6 +2854,22 @@ item_spec item_list::parse_single_spec(std::string s) if (qty != TAG_UNFOUND) result.qty = qty; + const std::string acquirement_source = strip_tag_prefix(s, "acquire:"); + if (!acquirement_source.empty() || strip_tag(s, "acquire")) + { + if (!acquirement_source.empty()) + result.acquirement_source = + parse_acquirement_source(acquirement_source); + // If requesting acquirement, must specify item base type or + // "any". + result.level = ISPEC_ACQUIREMENT; + if (s == "any") + result.base_type = OBJ_RANDOM; + else + parse_random_by_class(s, result); + return (result); + } + std::string ego_str = strip_tag_prefix(s, "ego:"); std::string race_str = strip_tag_prefix(s, "race:"); lowercase(ego_str); diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h index 6909ff4580..3efffadb0f 100644 --- a/crawl-ref/source/mapdef.h +++ b/crawl-ref/source/mapdef.h @@ -411,7 +411,8 @@ enum item_spec_type ISPEC_GOOD = -2, ISPEC_SUPERB = -3, ISPEC_DAMAGED = -4, - ISPEC_BAD = -5 + ISPEC_BAD = -5, + ISPEC_ACQUIREMENT = -9 }; struct item_spec @@ -426,11 +427,13 @@ struct item_spec int level; int race; int qty; + int acquirement_source; level_id place; item_spec() : genweight(10), base_type(OBJ_RANDOM), sub_type(OBJ_RANDOM), plus(-1), plus2(-1), ego(0), allow_uniques(1), level(-1), - race(MAKE_ITEM_RANDOM_RACE), qty(0) + race(MAKE_ITEM_RANDOM_RACE), qty(0), acquirement_source(0), + place() { } }; @@ -464,6 +467,7 @@ private: item_spec item_by_specifier(const std::string &spec); item_spec_slot parse_item_spec(std::string spec); item_spec parse_single_spec(std::string s); + int parse_acquirement_source(const std::string &source); void parse_raw_name(std::string name, item_spec &spec); void parse_random_by_class(std::string c, item_spec &spec); item_spec pick_item(item_spec_slot &slot); diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc index 89ac13703f..1836db3c75 100644 --- a/crawl-ref/source/stuff.cc +++ b/crawl-ref/source/stuff.cc @@ -1350,7 +1350,7 @@ unsigned char make_low_colour(unsigned char colour) unsigned char make_high_colour(unsigned char colour) { - if (colour >= 0 && colour <= 7) + if (colour <= 7) return (colour + 8); return (colour); -- cgit v1.2.3-54-g00ecf