diff options
-rw-r--r-- | crawl-ref/source/acr.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/describe.cc | 13 | ||||
-rw-r--r-- | crawl-ref/source/directn.cc | 13 | ||||
-rw-r--r-- | crawl-ref/source/directn.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/invent.cc | 26 | ||||
-rw-r--r-- | crawl-ref/source/invent.h | 19 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 92 | ||||
-rw-r--r-- | crawl-ref/source/makeitem.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/output.cc | 20 | ||||
-rw-r--r-- | crawl-ref/source/quiver.cc | 64 | ||||
-rw-r--r-- | crawl-ref/source/quiver.h | 10 | ||||
-rw-r--r-- | crawl-ref/source/randart.cc | 6 |
12 files changed, 185 insertions, 89 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index fa2a47c612..f6b290e344 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -2080,7 +2080,7 @@ void process_command( command_type cmd ) break; case CMD_QUIVER_ITEM: - mpr("Sorry, this command has not yet been implemented."); + choose_item_for_quiver(); break; case CMD_WEAR_ARMOUR: diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index 42cd0de8da..90f5b2c6f4 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -1344,19 +1344,26 @@ static std::string _describe_jewellery( const item_def &item, bool verbose) break; case RING_SLAYING: - if (item.plus != 0 || is_random_artefact( item )) + if (item.plus != 0) { description += "$It affects your accuracy ("; _append_value( description, item.plus, true ); description += ")."; } - if (item.plus2 != 0 || is_random_artefact( item )) + if (item.plus2 != 0) { description += "$It affects your damage-dealing abilities ("; _append_value( description, item.plus2, true ); description += ")."; } + + if (item.plus == 0 && item.plus2 == 0) + { + description += "This buggy ring affects neither your " + "accuracy nor your damage-dealing " + "abilities."; + } break; default: @@ -1365,7 +1372,7 @@ static std::string _describe_jewellery( const item_def &item, bool verbose) } } - // randart properties + // Randart properties. if (is_random_artefact( item )) { description += "$"; diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc index e84c8d8319..2f86f47638 100644 --- a/crawl-ref/source/directn.cc +++ b/crawl-ref/source/directn.cc @@ -134,18 +134,18 @@ void direction_choose_compass( dist& moves, targeting_behaviour *beh) } const int i = _targeting_cmd_to_compass(key_command); - if ( i != -1 ) + if (i != -1) { moves.dx = Compass[i].x; moves.dy = Compass[i].y; } - else if ( key_command == CMD_TARGET_CANCEL ) + else if (key_command == CMD_TARGET_CANCEL) { moves.isCancel = true; moves.isValid = false; } } - while ( !moves.isCancel && moves.dx == 0 && moves.dy == 0 ); + while (!moves.isCancel && moves.dx == 0 && moves.dy == 0); } static int _targeting_cmd_to_compass( command_type command ) @@ -832,6 +832,7 @@ void direction(dist& moves, targeting_type restricts, case CMD_TARGET_CANCEL: loop_done = true; moves.isCancel = true; + beh->mark_ammo_nonchosen(); break; #ifdef WIZARD @@ -839,6 +840,7 @@ void direction(dist& moves, targeting_type restricts, // Maybe we can skip this check...but it can't hurt if (!you.wizard || !in_bounds(moves.tx, moves.ty)) break; + mid = mgrd[moves.tx][moves.ty]; if (mid == NON_MONSTER) // can put in terrain description here break; @@ -2575,3 +2577,8 @@ bool targeting_behaviour::should_redraw() { return (false); } + +void targeting_behaviour::mark_ammo_nonchosen() +{ + // Nothing to be done. +} diff --git a/crawl-ref/source/directn.h b/crawl-ref/source/directn.h index a4cc637df2..b6cbd52bed 100644 --- a/crawl-ref/source/directn.h +++ b/crawl-ref/source/directn.h @@ -116,6 +116,7 @@ public: virtual int get_key(); virtual command_type get_command(int key = -1); virtual bool should_redraw(); + virtual void mark_ammo_nonchosen(); public: bool just_looking; diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc index b623a73411..e2955ca7db 100644 --- a/crawl-ref/source/invent.cc +++ b/crawl-ref/source/invent.cc @@ -357,6 +357,8 @@ static std::string _no_selectables_message(int item_selector) return("You aren't carrying any books or scrolls."); case OBJ_WANDS: return("You aren't carrying any wands."); + case OSEL_THROWABLE: + return("You aren't carrying any items that might be thrown or fired."); } return("You aren't carrying any such object."); @@ -804,33 +806,55 @@ static bool _item_class_selected(const item_def &i, int selector) { case OSEL_UNIDENT: return !fully_identified(i); + case OBJ_MISSILES: return (itype == OBJ_MISSILES || itype == OBJ_WEAPONS); + + case OSEL_THROWABLE: + { + if (i.base_type != OBJ_WEAPONS && i.base_type != OBJ_MISSILES) + return (false); + + const launch_retval projected = is_launched(&you, you.weapon(), i); + + if (projected == LRET_FUMBLED) + return (false); + + return (true); + } case OBJ_WEAPONS: case OSEL_WIELD: return (itype == OBJ_WEAPONS || itype == OBJ_STAVES || itype == OBJ_MISCELLANY); + case OSEL_MEMORISE: return (itype == OBJ_BOOKS && i.sub_type != BOOK_MANUAL && (i.sub_type != BOOK_DESTRUCTION || !item_type_known(i))); + case OBJ_SCROLLS: return (itype == OBJ_SCROLLS || itype == OBJ_BOOKS); + case OSEL_RECHARGE: return (item_is_rechargable(i, true)); + case OSEL_ENCH_ARM: return (is_enchantable_armour(i, true)); + case OSEL_VAMP_EAT: return (itype == OBJ_CORPSES && i.sub_type == CORPSE_BODY && !food_is_rotten(i) && mons_has_blood(i.plus)); + case OSEL_DRAW_DECK: return (is_deck(i)); + case OSEL_EQUIP: for (int eq = 0; eq < NUM_EQUIP; eq++) { if (you.equip[eq] == i.link) return (true); } - // fall through + return (false); + default: return (false); } diff --git a/crawl-ref/source/invent.h b/crawl-ref/source/invent.h index f11916107e..8ff0a75e35 100644 --- a/crawl-ref/source/invent.h +++ b/crawl-ref/source/invent.h @@ -22,15 +22,16 @@ enum object_selector { - OSEL_ANY = -1, - OSEL_WIELD = -2, - OSEL_UNIDENT = -3, - OSEL_EQUIP = -4, - OSEL_MEMORISE = -5, - OSEL_RECHARGE = -6, - OSEL_ENCH_ARM = -7, - OSEL_VAMP_EAT = -8, - OSEL_DRAW_DECK = -9 + OSEL_ANY = -1, + OSEL_WIELD = -2, + OSEL_UNIDENT = -3, + OSEL_EQUIP = -4, + OSEL_MEMORISE = -5, + OSEL_RECHARGE = -6, + OSEL_ENCH_ARM = -7, + OSEL_VAMP_EAT = -8, + OSEL_DRAW_DECK = -9, + OSEL_THROWABLE = -10 }; #define PROMPT_ABORT -1 diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index 3ec29799a1..392a37016f 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -1292,7 +1292,8 @@ class fire_target_behaviour : public targeting_behaviour { public: fire_target_behaviour() - : m_slot(-1), selected_from_inventory(false), need_prompt(false) + : m_slot(-1), selected_from_inventory(false), need_prompt(false), + chosen_ammo(false) { m_slot = you.m_quiver->get_fire_item(&m_noitem_reason); } @@ -1300,6 +1301,7 @@ public: // targeting_behaviour API virtual command_type get_command(int key = -1); virtual bool should_redraw(); + virtual void mark_ammo_nonchosen(); void message_ammo_prompt(const std::string* pre_text = 0); @@ -1308,6 +1310,7 @@ public: std::string m_noitem_reason; bool selected_from_inventory; bool need_prompt; + bool chosen_ammo; }; void fire_target_behaviour::message_ammo_prompt(const std::string* pre_text) @@ -1381,6 +1384,11 @@ bool fire_target_behaviour::should_redraw() return (false); } +void fire_target_behaviour::mark_ammo_nonchosen() +{ + chosen_ammo = false; +} + command_type fire_target_behaviour::get_command(int key) { if (key == -1) @@ -1388,42 +1396,44 @@ command_type fire_target_behaviour::get_command(int key) switch (key) { - case '(': - case CONTROL('N'): - case ')': - case CONTROL('P'): - { - const int direction = (key == CONTROL('P') || key == ')') ? -1 : +1; - const int next = get_next_fire_item(m_slot, direction); - if (next != m_slot && next != -1) - { - m_slot = next; - selected_from_inventory = false; - } - // Do this stuff unconditionally to make the prompt redraw. - message_ammo_prompt(); - need_prompt = true; - break; - } - case 'i': - { - std::string err; - const int selected = _fire_prompt_for_item(err); - if (selected >= 0 && _fire_validate_item(selected, err)) - { - m_slot = selected; - selected_from_inventory = true; - } - message_ammo_prompt( err.length() ? &err : NULL ); - need_prompt = true; - return (CMD_NO_CMD); - } - case '?': - show_targeting_help(); - redraw_screen(); - message_ammo_prompt(); - need_prompt = true; - return (CMD_NO_CMD); + case '(': + case CONTROL('N'): + case ')': + case CONTROL('P'): + { + const int direction = (key == CONTROL('P') || key == ')') ? -1 : +1; + const int next = get_next_fire_item(m_slot, direction); + if (next != m_slot && next != -1) + { + m_slot = next; + selected_from_inventory = false; + chosen_ammo = true; + } + // Do this stuff unconditionally to make the prompt redraw. + message_ammo_prompt(); + need_prompt = true; + break; + } + case 'i': + { + std::string err; + const int selected = _fire_prompt_for_item(err); + if (selected >= 0 && _fire_validate_item(selected, err)) + { + m_slot = selected; + selected_from_inventory = true; + chosen_ammo = true; + } + message_ammo_prompt( err.length() ? &err : NULL ); + need_prompt = true; + return (CMD_NO_CMD); + } + case '?': + show_targeting_help(); + redraw_screen(); + message_ammo_prompt(); + need_prompt = true; + return (CMD_NO_CMD); } return targeting_behaviour::get_command(key); @@ -1462,17 +1472,20 @@ static bool _fire_choose_item_and_target(int& slot, dist& target, return (false); } + you.m_quiver->on_item_fired(you.inv[beh.m_slot], beh.chosen_ammo); +/* // If ammo was chosen via 'fi', it's not supposed to get quivered. // Otherwise, if the user chose different ammo, quiver it. // Same for items selected in tile mode. if (was_chosen || !beh.selected_from_inventory) { - you.m_quiver->on_item_fired(you.inv[beh.m_slot]); + you.m_quiver->on_item_fired(you.inv[beh.m_slot], beh.chosen_ammo); } else { you.m_quiver->on_item_fired_fi(you.inv[beh.m_slot]); } +*/ you.redraw_quiver = true; slot = beh.m_slot; @@ -1493,8 +1506,9 @@ static int _fire_prompt_for_item(std::string& err) int slot = prompt_invent_item( "Fire/throw which item? (* to show all)", MT_INVLIST, - OBJ_MISSILES, true, true, true, 0, NULL, + OSEL_THROWABLE, true, true, true, 0, NULL, OPER_FIRE ); + if (slot == PROMPT_ABORT || slot == PROMPT_NOTHING) { err = "Nothing selected."; diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc index b885d764f8..52989e4462 100644 --- a/crawl-ref/source/makeitem.cc +++ b/crawl-ref/source/makeitem.cc @@ -2596,17 +2596,17 @@ static void _generate_jewellery_item(item_def& item, bool allow_uniques, : get_random_ring_type()); } - // everything begins as uncursed, unenchanted jewellery {dlb}: + // Everything begins as uncursed, unenchanted jewellery {dlb}: item.plus = 0; item.plus2 = 0; item.plus = _determine_ring_plus(item.sub_type); - if ( item.plus < 0 ) + if (item.plus < 0) do_curse_item(item); if (item.sub_type == RING_SLAYING ) // requires plus2 too { - if (item_cursed( item ) && !one_chance_in(20)) + if (item_cursed(item) && !one_chance_in(20)) item.plus2 = -1 - random2avg(6, 2); else { @@ -2615,7 +2615,7 @@ static void _generate_jewellery_item(item_def& item, bool allow_uniques, if (random2(25) < 9) // 36% of such rings {dlb} { // make "ring of damage" - do_uncurse_item( item ); + do_uncurse_item(item); item.plus = 0; item.plus2 += 2; } diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc index c1dca948a5..ad0e9a284b 100644 --- a/crawl-ref/source/output.cc +++ b/crawl-ref/source/output.cc @@ -507,6 +507,7 @@ static void _print_stats_qv(int y) const std::string prefix = menu_colour_item_prefix(quiver); const int prefcol = menu_colour(quiver.name(DESC_INVENTORY), prefix); + if (prefcol != -1) textcolor(prefcol); @@ -519,25 +520,6 @@ static void _print_stats_qv(int y) { textcolor(LIGHTGREY); cprintf("Nothing quivered"); - -/* - const item_def* item; - you.m_quiver->get_desired_item(&item, &q); - - if (item != NULL && is_valid_item(*item)) - { - textcolor(item->colour); - cprintf("-) %s", item->name(DESC_PLAIN, true) - .substr(0, crawl_view.hudsz.x - 15).c_str()); - textcolor(RED); - cprintf(" (empty)"); - } - else - { - textcolor(LIGHTGREY); - cprintf("Nothing quivered"); - } -*/ } textcolor(LIGHTGREY); diff --git a/crawl-ref/source/quiver.cc b/crawl-ref/source/quiver.cc index 6ecf4c8661..e22f5097c3 100644 --- a/crawl-ref/source/quiver.cc +++ b/crawl-ref/source/quiver.cc @@ -12,6 +12,7 @@ #include "AppHdr.h" #include "quiver.h" +#include "invent.h" #include "item_use.h" #include "itemprop.h" #include "items.h" @@ -122,9 +123,60 @@ int player_quiver::get_fire_item(std::string* no_item_reason) const return slot; } +void player_quiver::set_quiver(const item_def &item, ammo_t ammo_type) +{ + m_last_used_of_type[ammo_type] = item; + m_last_used_of_type[ammo_type].quantity = 1; + m_last_used_type = ammo_type; + you.redraw_quiver = true; +} + +void choose_item_for_quiver() +{ + int slot = prompt_invent_item( "Quiver which item? (* to show all)", + MT_INVLIST, + OSEL_THROWABLE, true, true, true, 0, NULL, + OPER_FIRE ); + + if (slot == PROMPT_ABORT) + { + canned_msg(MSG_OK); + return; + } + else if (slot == PROMPT_NOTHING) + return; + + const item_def item = you.inv[slot]; + + if (!is_valid_item(item)) + return; + + ammo_t t = AMMO_THROW; + + const item_def *weapon = you.weapon(); + if (weapon && item.launched_by(*weapon)) + t = _get_weapon_ammo_type(weapon); + + you.m_quiver->set_quiver(you.inv[slot], t); + mprf("Quivering %s %s.", you.inv[slot].name(DESC_INVENTORY).c_str(), + t == AMMO_THROW ? "as throwing weapon" : + t == AMMO_BLOWGUN ? "for blowguns" : + t == AMMO_SLING ? "for slings" : + t == AMMO_BOW ? "for bows" : + t == AMMO_CROSSBOW ? "for crossbows" + : "for hand crossbows"); +} + // Notification that item was fired with 'f'. -void player_quiver::on_item_fired(const item_def& item) +void player_quiver::on_item_fired(const item_def& item, bool explicitly_chosen) { + if (!explicitly_chosen) + { + // If the item was not actively chosen, i.e. just automatically + // passed into the quiver, don't change any of the quiver settings. + you.redraw_quiver = true; + return; + } // If item matches the launcher, put it in that launcher's last-used item. // Otherwise, it goes into last hand-thrown item. @@ -376,9 +428,12 @@ void player_quiver::load(reader& inf) preserve_quiver_slots::preserve_quiver_slots() { - if (!you.m_quiver) return; + if (!you.m_quiver) + return; + COMPILE_CHECK(ARRAYSZ(m_last_used_of_type) == ARRAYSZ(you.m_quiver->m_last_used_of_type), a); + for (unsigned int i = 0; i < ARRAYSZ(m_last_used_of_type); i++) { m_last_used_of_type[i] = @@ -388,7 +443,9 @@ preserve_quiver_slots::preserve_quiver_slots() preserve_quiver_slots::~preserve_quiver_slots() { - if (! you.m_quiver) return; + if (!you.m_quiver) + return; + for (unsigned int i = 0; i < ARRAYSZ(m_last_used_of_type); i++) { const int slot = m_last_used_of_type[i]; @@ -473,7 +530,6 @@ static int _get_pack_slot(const item_def& item) return -1; } - // Returns the type of ammo used by the player's equipped weapon, // or AMMO_THROW if it's not a launcher. static ammo_t _get_weapon_ammo_type(const item_def* weapon) diff --git a/crawl-ref/source/quiver.h b/crawl-ref/source/quiver.h index 04366051d2..5014cc1a8f 100644 --- a/crawl-ref/source/quiver.h +++ b/crawl-ref/source/quiver.h @@ -34,12 +34,13 @@ class 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; + 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 set_quiver(const item_def &item, ammo_t ammo_type); + void on_item_fired(const item_def &item, bool explicitly_chosen = false); + void on_item_fired_fi(const item_def &item); void on_inv_quantity_changed(int slot, int amt); void on_weapon_changed(); @@ -77,4 +78,7 @@ class preserve_quiver_slots int m_last_used_of_type[NUM_AMMO]; }; + +void choose_item_for_quiver(void); + #endif diff --git a/crawl-ref/source/randart.cc b/crawl-ref/source/randart.cc index 9471d21190..ecbca074da 100644 --- a/crawl-ref/source/randart.cc +++ b/crawl-ref/source/randart.cc @@ -470,7 +470,7 @@ void randart_desc_properties( const item_def &item, break; case RING_STRENGTH: - fake_rap = RAP_STRENGTH; + fake_rap = RAP_STRENGTH; fake_plus = item.plus; break; @@ -510,10 +510,10 @@ void randart_desc_properties( const item_def &item, break; } - if (fake_rap != RAP_NUM_PROPERTIES) + if (fake_rap != RAP_NUM_PROPERTIES && fake_plus != 0) proprt[fake_rap] += fake_plus; - if (fake_rap2 != RAP_NUM_PROPERTIES) + if (fake_rap2 != RAP_NUM_PROPERTIES && fake_plus2 != 0) proprt[fake_rap2] += fake_plus2; if (item_ident( item, ISFLAG_KNOW_PROPERTIES ) |