summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2009-09-21 08:23:35 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2009-09-21 08:23:35 +0000
commita36fd3f9f0e5bde3dd9d74e1742cfbd2f045c635 (patch)
tree162c04f1bb86a4f1bde64d55c69c81ee65b38680
parent02c7a7e290da364ed194a72ccc42240afe19e344 (diff)
downloadcrawl-ref-a36fd3f9f0e5bde3dd9d74e1742cfbd2f045c635.tar.gz
crawl-ref-a36fd3f9f0e5bde3dd9d74e1742cfbd2f045c635.zip
Allow vaults to request use of the acquirement code with "acquire <item_class>" or "acquire:<god> <item_class>" in item specs (due).
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@10765 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/docs/level_design.txt5
-rw-r--r--crawl-ref/source/dungeon.cc19
-rw-r--r--crawl-ref/source/effects.cc199
-rw-r--r--crawl-ref/source/effects.h4
-rw-r--r--crawl-ref/source/items.cc6
-rw-r--r--crawl-ref/source/items.h1
-rw-r--r--crawl-ref/source/mapdef.cc26
-rw-r--r--crawl-ref/source/mapdef.h8
-rw-r--r--crawl-ref/source/stuff.cc2
9 files changed, 168 insertions, 102 deletions
diff --git a/crawl-ref/docs/level_design.txt b/crawl-ref/docs/level_design.txt
index 4f723186e0..6c973d6220 100644
--- a/crawl-ref/docs/level_design.txt
+++ b/crawl-ref/docs/level_design.txt
@@ -562,6 +562,11 @@ ITEM: (list of items, separated by comma)
* "no_uniq" prevents the item from being turned into an artefact.
* "good_item" makes the builder try to make the item a good one
(acquirement quality).
+ * "acquire" requests the use of the acquirement code itself,
+ ensuring that the player gets wearable armour, etc. You can
+ also use acquire:<god> to request that the acquired item be
+ treated as a god gift. Examples: "acquire any", "acquire armour",
+ "acquire:sif_muna book", "acquire:trog weapon".
* "level:N" sets the object's item level (can't be used with
"good_item"). If set to -2 then the object's item level will
be the same as a "*" symbol item (five plus twice the
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);