diff options
-rw-r--r-- | crawl-ref/init.txt | 1 | ||||
-rw-r--r-- | crawl-ref/source/acr.cc | 11 | ||||
-rw-r--r-- | crawl-ref/source/command.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/describe.cc | 1 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/files.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/initfile.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/it_use2.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/itemname.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/itemprop.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/items.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/output.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/quiver.cc | 97 | ||||
-rw-r--r-- | crawl-ref/source/quiver.h | 31 | ||||
-rw-r--r-- | crawl-ref/source/religion.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/spells3.cc | 25 | ||||
-rw-r--r-- | crawl-ref/source/stuff.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/tags.cc | 20 |
20 files changed, 177 insertions, 53 deletions
diff --git a/crawl-ref/init.txt b/crawl-ref/init.txt index be0a2d568b..6dc53a7e5a 100644 --- a/crawl-ref/init.txt +++ b/crawl-ref/init.txt @@ -256,7 +256,6 @@ message_colour = yellow:fails to return # fire_order = launcher, return # fire_order += javelin / dart / stone / rock / spear / net / handaxe / dagger / club # fire_order += inscribed -# fire_quiver_best = true ##### 4-l Channels ############################## # diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 2e3b6c79c9..6576ca2794 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -829,6 +829,7 @@ static void _handle_wizard_command( void ) break; case 'i': + { mpr( "You feel a rush of knowledge." ); for (i = 0; i < ENDOFPACK; i++) { @@ -841,10 +842,12 @@ static void _handle_wizard_command( void ) } } you.wield_change = true; - you.quiver_change = true; + you.redraw_quiver = true; break; + } case 'I': + { mpr( "You feel a rush of antiknowledge." ); for (i = 0; i < ENDOFPACK; i++) { @@ -857,7 +860,7 @@ static void _handle_wizard_command( void ) } } you.wield_change = true; - you.quiver_change = true; + you.redraw_quiver = true; // Forget things that nearby monsters are carrying, as well // (for use with the "give monster an item" wizard targetting @@ -886,6 +889,7 @@ static void _handle_wizard_command( void ) } } break; + } case CONTROL('I'): debug_item_statistics(); @@ -2391,7 +2395,6 @@ void process_command( command_type cmd ) { // kind of a hacky way to get quiver to change you.m_quiver->on_item_fired(you.inv[next]); - you.quiver_change = true; } break; } @@ -3930,8 +3933,8 @@ static bool _initialise(void) you.redraw_evasion = true; you.redraw_experience = true; you.redraw_gold = true; + you.redraw_quiver = true; you.wield_change = true; - you.quiver_change = true; you.start_time = time( NULL ); // start timer on session diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc index 04834336d9..4319b76850 100644 --- a/crawl-ref/source/command.cc +++ b/crawl-ref/source/command.cc @@ -153,8 +153,8 @@ void swap_inv_slots(int from_slot, int to_slot, bool verbose) if (to_slot == you.equip[EQ_WEAPON] || from_slot == you.equip[EQ_WEAPON]) { you.wield_change = true; + you.m_quiver->on_weapon_changed(); } - you.quiver_change = true; } static void _adjust_item(void) diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index 8ed7db72e3..0c2bbdfc24 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -1847,7 +1847,6 @@ void describe_item( item_def &item, bool allow_inscribe ) if (!cancelable_get_line(buf, sizeof buf)) { item.inscription = buf; - you.quiver_change = true; // might have added/removed !F } } else if (allow_autoinscribe diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 05e2459d14..f0e011e498 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -607,7 +607,7 @@ public: char hunger_state; bool wield_change; // redraw weapon - bool quiver_change; // redraw quiver + bool redraw_quiver; // redraw quiver bool received_weapon_warning; unsigned long redraw_status_flags; @@ -1622,7 +1622,6 @@ public: int fire_items_start;// index of first item for fire command std::vector<unsigned> fire_order; // missile search order for 'f' command - bool fire_quiver_best; bool auto_list; // automatically jump to appropriate item lists diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index 040a4ba570..b0626e786b 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -114,7 +114,8 @@ void save_level(int level_saved, level_area_type lt, // 1: starting version // 2: append piety_hysteresis to TAG_YOU -#define YOU_MINOR_VERSION 2 +// 3: add quiver info. +#define YOU_MINOR_VERSION 3 const short GHOST_SIGNATURE = short( 0xDC55 ); diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index a9bc0ba6b8..5f5baab92b 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -768,7 +768,6 @@ void game_options::reset_options() flush_input[ FLUSH_LUA ] = true; fire_items_start = 0; // start at slot 'a' - fire_quiver_best = false; // Clear fire_order and set up the defaults. set_fire_order("launcher, return, " @@ -1919,7 +1918,6 @@ void game_options::read_option_line(const std::string &str, bool runscript) field.c_str() ); } } - else BOOL_OPTION(fire_quiver_best); else if (key == "assign_item_slot") { if (field == "forward") diff --git a/crawl-ref/source/it_use2.cc b/crawl-ref/source/it_use2.cc index 6093cb0577..f9914847e3 100644 --- a/crawl-ref/source/it_use2.cc +++ b/crawl-ref/source/it_use2.cc @@ -33,6 +33,7 @@ #include "misc.h" #include "mutation.h" #include "player.h" +#include "quiver.h" #include "randart.h" #include "religion.h" #include "skills2.h" @@ -390,7 +391,7 @@ bool unwield_item(bool showMsgs) you.equip[EQ_WEAPON] = -1; you.special_wield = SPWLD_NONE; you.wield_change = true; - you.quiver_change = true; + you.m_quiver->on_weapon_changed(); item_def &item(you.inv[unw]); diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index 6ac82b95d4..482291666d 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -350,7 +350,7 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages) you.time_taken /= 2; you.wield_change = true; - you.quiver_change = true; + you.m_quiver->on_weapon_changed(); you.turn_is_over = true; return (true); @@ -1432,7 +1432,7 @@ static bool _fire_choose_item_and_target(int& slot, dist& target) { you.m_quiver->on_item_fired_fi(you.inv[beh.m_slot]); } - you.quiver_change = true; + you.redraw_quiver = true; slot = beh.m_slot; return (true); @@ -3405,7 +3405,6 @@ void inscribe_item() you.inv[item_slot].inscription = std::string(buf); you.wield_change = true; - you.quiver_change = true; } else { diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc index 3614af1c52..3cea6c4554 100644 --- a/crawl-ref/source/itemname.cc +++ b/crawl-ref/source/itemname.cc @@ -36,6 +36,7 @@ #include "makeitem.h" #include "mon-util.h" #include "notes.h" +#include "quiver.h" #include "randart.h" #include "skills2.h" #include "state.h" @@ -1724,6 +1725,7 @@ id_arr& get_typeid_array() void set_ident_type( object_class_type basetype, int subtype, item_type_id_state_type setting, bool force ) { + preserve_quiver_slots p; // Don't allow overwriting of known type with tried unless forced. if (!force && (setting == ID_MON_TRIED_TYPE || setting == ID_TRIED_TYPE) diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc index d225351ce5..4f99b634f0 100644 --- a/crawl-ref/source/itemprop.cc +++ b/crawl-ref/source/itemprop.cc @@ -32,6 +32,7 @@ #include "mon-util.h" #include "notes.h" #include "player.h" +#include "quiver.h" #include "randart.h" #include "skills2.h" #include "stuff.h" @@ -475,8 +476,6 @@ void do_curse_item( item_def &item ) } item.flags |= ISFLAG_CURSED; - - you.quiver_change = true; // potentially affected } void do_uncurse_item( item_def &item ) @@ -531,6 +530,7 @@ bool item_is_critical(const item_def &item) void set_ident_flags( item_def &item, unsigned long flags ) { + preserve_quiver_slots p; if ((item.flags & flags) != flags) { item.flags |= flags; @@ -551,6 +551,7 @@ void set_ident_flags( item_def &item, unsigned long flags ) void unset_ident_flags( item_def &item, unsigned long flags ) { + preserve_quiver_slots p; item.flags &= (~flags); } diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index 52aee95021..f7aa0a111b 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -244,7 +244,7 @@ bool dec_inv_item_quantity( int obj, int amount ) if (you.equip[EQ_WEAPON] == obj) you.wield_change = true; - you.m_quiver->on_inv_quantity_change(obj, amount); + you.m_quiver->on_inv_quantity_changed(obj, amount); if (you.inv[obj].quantity <= amount) { @@ -315,7 +315,7 @@ void inc_inv_item_quantity( int obj, int amount ) if (you.equip[EQ_WEAPON] == obj) you.wield_change = true; - you.m_quiver->on_inv_quantity_change(obj, amount); + you.m_quiver->on_inv_quantity_changed(obj, amount); you.inv[obj].quantity += amount; burden_change(); } @@ -1587,7 +1587,7 @@ int move_item_to_player( int obj, int quant_got, bool quiet ) item.quantity = quant_got; dec_mitm_item_quantity( obj, quant_got ); - you.quiver_change = true; + you.m_quiver->on_inv_quantity_changed(freeslot, quant_got); burden_change(); if (!quiet) diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc index d73034ad88..098fab8ca7 100644 --- a/crawl-ref/source/output.cc +++ b/crawl-ref/source/output.cc @@ -838,13 +838,13 @@ void print_stats(void) _print_stats_wp(10); } - if (you.quiver_change || you.wield_change) + if (you.redraw_quiver || you.wield_change) { _print_stats_qv(11); } you.wield_change = false; - you.quiver_change = false; + you.redraw_quiver = false; if (you.redraw_status_flags & REDRAW_LINE_1_MASK) _print_stats_line1(12); @@ -1058,6 +1058,7 @@ monster_pane_info::to_string( //out << " (friendly)"; desc_color = GREEN; break; + case ATT_GOOD_NEUTRAL: case ATT_NEUTRAL: //out << " (neutral)"; desc_color = BROWN; diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 54f4379754..e192b705a4 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -5391,7 +5391,7 @@ void player::init() hunger_state = HS_SATIATED; wield_change = false; - quiver_change = false; + redraw_quiver = false; received_weapon_warning = false; gold = 0; diff --git a/crawl-ref/source/quiver.cc b/crawl-ref/source/quiver.cc index 5694acae99..3950aa9538 100644 --- a/crawl-ref/source/quiver.cc +++ b/crawl-ref/source/quiver.cc @@ -16,6 +16,7 @@ #include "itemprop.h" #include "items.h" #include "stuff.h" +#include "tags.h" // checks base_type for OBJ_UNASSIGNED, and quantity // bool is_valid_item( const item_def &item ) @@ -29,17 +30,27 @@ static bool _items_similar(const item_def& a, const item_def& b); // ---------------------------------------------------------------------- player_quiver::player_quiver() - : m_last_used_type(AMMO_INVALID) + : m_last_used_type(AMMO_THROW) { COMPILE_CHECK(ARRAYSIZE(m_last_used_of_type) == NUM_AMMO, a); } -// Return item that we would like to fire by default, and its inv slot -// (if there are any in inv). If the item is in inv, its count will -// be correct. +// Return: +// *slot_out filled in with the inv slot of the item we would like +// to fire by default. If -1, the inv doesn't contain our desired +// item. +// +// *item_out filled in with item we would like to fire by default. +// This can be returned even if the item is not in inv (although if +// it is in inv, a reference to the inv item, with accurate count, +// is returned) +// // This is the item that will be displayed in Qv: +// void player_quiver::get_desired_item(const item_def** item_out, int* slot_out) const { + ASSERT(m_last_used_type != AMMO_INVALID); + // I'd like to get rid of this first case if (m_last_used_type == AMMO_INVALID) { if (item_out) *item_out = NULL; @@ -137,6 +148,8 @@ void player_quiver::on_item_fired(const item_def& item) m_last_used_of_type[AMMO_THROW].quantity = 1; m_last_used_type = AMMO_THROW; } + + you.redraw_quiver = true; } // Notification that ltem was fired with 'f' 'i' @@ -172,13 +185,13 @@ void player_quiver::on_weapon_changed() _maybe_fill_empty_slot(); } -void player_quiver::on_inv_quantity_change(int slot, int amt) +void player_quiver::on_inv_quantity_changed(int slot, int amt) { if (m_last_used_of_type[m_last_used_type].base_type == OBJ_UNASSIGNED) { // Empty quiver. Maybe we can fill it now? _maybe_fill_empty_slot(); - you.quiver_change = true; + you.redraw_quiver = true; } else if (m_last_used_of_type[m_last_used_type].base_type != you.inv[slot].base_type) @@ -188,9 +201,13 @@ void player_quiver::on_inv_quantity_change(int slot, int amt) else { // Maybe matches current stack. Redraw if so. - int qv_slot; get_desired_item(NULL, &qv_slot); + // + const item_def* desired; + int qv_slot; get_desired_item(&desired, &qv_slot); if (qv_slot == slot) - you.quiver_change = true; + { + you.redraw_quiver = true; + } } } @@ -283,6 +300,70 @@ void player_quiver::_get_fire_order( } // ---------------------------------------------------------------------- +// Save/load +// ---------------------------------------------------------------------- + +static const short QUIVER_COOKIE = 0xb015; +void player_quiver::save(writer& outf) const +{ + marshallShort(outf, QUIVER_COOKIE); + + marshallItem(outf, m_last_weapon); + marshallLong(outf, m_last_used_type); + marshallLong(outf, ARRAYSIZE(m_last_used_of_type)); + for (int i=0; i<ARRAYSIZE(m_last_used_of_type); i++) + { + marshallItem(outf, m_last_used_of_type[i]); + } +} + +void player_quiver::load(reader& inf) +{ + const short cooky = unmarshallShort(inf); + ASSERT(cooky == QUIVER_COOKIE); (void)cooky; + + unmarshallItem(inf, m_last_weapon); + m_last_used_type = (ammo_t)unmarshallLong(inf); + ASSERT(m_last_used_type >= AMMO_INVALID && m_last_used_type < NUM_AMMO); + + const long count = unmarshallLong(inf); + ASSERT(count <= ARRAYSIZE(m_last_used_of_type)); + for (int i=0; i<count; i++) + { + unmarshallItem(inf, m_last_used_of_type[i]); + } +} + +// ---------------------------------------------------------------------- +// Identify helper +// ---------------------------------------------------------------------- + +preserve_quiver_slots::preserve_quiver_slots() +{ + if (! you.m_quiver) return; + COMPILE_CHECK(ARRAYSIZE(m_last_used_of_type) == + ARRAYSIZE(you.m_quiver->m_last_used_of_type), a); + for (int i=0; i<ARRAYSIZE(m_last_used_of_type); i++) + { + you.m_quiver->get_desired_item(NULL, &m_last_used_of_type[i]); + } +} + +preserve_quiver_slots::~preserve_quiver_slots() +{ + if (! you.m_quiver) return; + for (int i=0; i<ARRAYSIZE(m_last_used_of_type); i++) + { + const int slot = m_last_used_of_type[i]; + if (slot != -1) + { + you.m_quiver->m_last_used_of_type[i] = you.inv[slot]; + } + } + you.redraw_quiver = true; +} + +// ---------------------------------------------------------------------- // Helpers // ---------------------------------------------------------------------- diff --git a/crawl-ref/source/quiver.h b/crawl-ref/source/quiver.h index dd76319e1a..4b0e7f8993 100644 --- a/crawl-ref/source/quiver.h +++ b/crawl-ref/source/quiver.h @@ -11,6 +11,10 @@ #include "externs.h" /* item_def */ #include <vector> +class reader; +class writer; +class preserve_quiver_slots; + enum ammo_t { AMMO_THROW, // no launcher wielded -> darts, stones, ... @@ -25,23 +29,31 @@ enum ammo_t class player_quiver { + friend class preserve_quiver_slots; public: player_quiver(); + // Queries from engine -- don't affect state void get_desired_item(const item_def** item_out, int* slot_out) const; int get_fire_item(std::string* no_item_reason=0) const; void get_fire_order(std::vector<int>& v) const; + // Callbacks from engine void on_item_fired(const item_def&); void on_item_fired_fi(const item_def&); - void on_inv_quantity_change(int slot, int amt); + void on_inv_quantity_changed(int slot, int amt); void on_weapon_changed(); + // save/load + void save(writer&) const; + void load(reader&); + private: void _get_fire_order(std::vector<int>&, bool ignore_inscription_etc, const item_def* launcher) const; void _maybe_fill_empty_slot(); + private: item_def m_last_weapon; @@ -49,4 +61,21 @@ class player_quiver item_def m_last_used_of_type[NUM_AMMO]; }; +// Quiver tracks items, which in most cases is the Right Thing. But +// when a quivered item is identified, the quiver doesn't change to +// match. We would like the quiver to store the identified item. +// +// This class saves off the quiver item slots, and restores them when +// destroyed. The expected use is to create one of these around code +// that identifies items in inv. +class preserve_quiver_slots +{ + public: + preserve_quiver_slots(); + ~preserve_quiver_slots(); + + private: + int m_last_used_of_type[NUM_AMMO]; +}; + #endif diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 9cf4d40ab2..c75cf958e1 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -64,6 +64,7 @@ #include "ouch.h" #include "output.h" #include "player.h" +#include "quiver.h" #include "randart.h" #include "shopping.h" #include "skills2.h" @@ -2888,9 +2889,8 @@ static void ely_destroy_inventory_weapon() { unwield_item(true); you.wield_change = true; + you.m_quiver->on_weapon_changed(); } - // just in case - you.quiver_change = true; destroy_item(you.inv[item]); burden_change(); diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index 843bb45f6a..019d2f81d8 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -44,6 +44,7 @@ #include "mon-util.h" #include "place.h" #include "player.h" +#include "quiver.h" #include "randart.h" #include "religion.h" #include "spells1.h" @@ -1095,19 +1096,21 @@ void cast_poison_ammo(void) return; } - const char *old_desc = you.inv[ammo].name(DESC_CAP_YOUR).c_str(); - if (set_item_ego_type( you.inv[ammo], OBJ_MISSILES, SPMSL_POISONED )) { - mprf("%s %s covered in a thin film of poison.", old_desc, - (you.inv[ammo].quantity == 1) ? "is" : "are"); + preserve_quiver_slots q; + const char *old_desc = you.inv[ammo].name(DESC_CAP_YOUR).c_str(); + if (set_item_ego_type( you.inv[ammo], OBJ_MISSILES, SPMSL_POISONED )) + { + mprf("%s %s covered in a thin film of poison.", old_desc, + (you.inv[ammo].quantity == 1) ? "is" : "are"); - you.quiver_change = true; - if (ammo == you.equip[EQ_WEAPON]) - you.wield_change = true; - } - else - { - canned_msg(MSG_NOTHING_HAPPENS); + if (ammo == you.equip[EQ_WEAPON]) + you.wield_change = true; + } + else + { + canned_msg(MSG_NOTHING_HAPPENS); + } } } // end cast_poison_ammo() diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc index b67f7a584c..0b3b6212c1 100644 --- a/crawl-ref/source/stuff.cc +++ b/crawl-ref/source/stuff.cc @@ -655,7 +655,7 @@ void redraw_screen(void) you.redraw_gold = true; you.redraw_experience = true; you.wield_change = true; - you.quiver_change = true; + you.redraw_quiver = true; set_redraw_status( REDRAW_LINE_1_MASK | REDRAW_LINE_2_MASK | REDRAW_LINE_3_MASK ); diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index d0a1dc4396..6c956e1f6c 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -79,6 +79,7 @@ #include "monstuff.h" #include "mon-util.h" #include "mtransit.h" +#include "quiver.h" #include "randart.h" #include "skills.h" #include "skills2.h" @@ -930,10 +931,8 @@ static void tag_construct_you(writer &th) for (j = 0; j < NUM_ATTRIBUTES; ++j) marshallByte(th,you.attribute[j]); - // remembered quiver items - marshallByte(th, NUM_QUIVER); - for (j = 0; j < NUM_QUIVER; ++j) - marshallByte(th,you.quiver[j]); + // was: remembered quiver items + marshallByte(th, 0); // sacrifice values marshallByte(th, NUM_OBJECT_CLASSES); @@ -1002,6 +1001,9 @@ static void tag_construct_you(writer &th) // minorVersion 2 starts here marshallByte(th, you.piety_hysteresis); + + // minorVersion 3 starts here + you.m_quiver->save(th); } static void tag_construct_you_items(writer &th) @@ -1322,10 +1324,13 @@ static void tag_read_you(reader &th, char minorVersion) for (j = 0; j < count_c; ++j) you.attribute[j] = unmarshallByte(th); - // how many quiver types? + // old: quiver info. Discard it. count_c = unmarshallByte(th); + if (minorVersion >= 3) ASSERT(count_c == 0); for (j = 0; j < count_c; ++j) - you.quiver[j] = unmarshallByte(th); + { + unmarshallByte(th); + } count_c = unmarshallByte(th); for (j = 0; j < count_c; ++j) @@ -1381,6 +1386,9 @@ static void tag_read_you(reader &th, char minorVersion) if (minorVersion >= 2) you.piety_hysteresis = unmarshallByte(th); + + if (minorVersion >= 3) + you.m_quiver->load(th); } static void tag_read_you_items(reader &th, char minorVersion) |