summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/acr.cc2
-rw-r--r--crawl-ref/source/describe.cc13
-rw-r--r--crawl-ref/source/directn.cc13
-rw-r--r--crawl-ref/source/directn.h1
-rw-r--r--crawl-ref/source/invent.cc26
-rw-r--r--crawl-ref/source/invent.h19
-rw-r--r--crawl-ref/source/item_use.cc92
-rw-r--r--crawl-ref/source/makeitem.cc8
-rw-r--r--crawl-ref/source/output.cc20
-rw-r--r--crawl-ref/source/quiver.cc64
-rw-r--r--crawl-ref/source/quiver.h10
-rw-r--r--crawl-ref/source/randart.cc6
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 )