summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/abl-show.cc8
-rw-r--r--crawl-ref/source/decks.cc130
-rw-r--r--crawl-ref/source/decks.h1
-rw-r--r--crawl-ref/source/describe.cc15
-rw-r--r--crawl-ref/source/enum.h1
-rw-r--r--crawl-ref/source/itemname.cc5
-rw-r--r--crawl-ref/source/itemprop.cc9
-rw-r--r--crawl-ref/source/itemprop.h2
-rw-r--r--crawl-ref/source/output.cc3
-rw-r--r--crawl-ref/source/religion.cc4
10 files changed, 143 insertions, 35 deletions
diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc
index 3a897a841e..55f2b0a801 100644
--- a/crawl-ref/source/abl-show.cc
+++ b/crawl-ref/source/abl-show.cc
@@ -128,7 +128,7 @@ ability_type god_abilities[MAX_NUM_GODS][MAX_GOD_ABILITIES] =
ABIL_TROG_HASTE_SELF, ABIL_NON_ABILITY },
// Nemelex
{ ABIL_NEMELEX_PEEK, ABIL_NEMELEX_TRIPLE_DRAW, ABIL_NON_ABILITY,
- ABIL_NON_ABILITY, ABIL_NON_ABILITY },
+ ABIL_NON_ABILITY, ABIL_NEMELEX_STACK_DECK },
// Elyvilon
{ ABIL_ELYVILON_LESSER_HEALING, ABIL_ELYVILON_PURIFICATION,
ABIL_ELYVILON_HEALING, ABIL_ELYVILON_RESTORATION,
@@ -272,6 +272,7 @@ static const ability_def Ability_List[] =
// Nemelex
{ ABIL_NEMELEX_TRIPLE_DRAW, "Triple Draw", 2, 0, 100, 2, ABFLAG_NONE },
{ ABIL_NEMELEX_PEEK, "Deck Peek", 3, 0, 0, 1, ABFLAG_INSTANT },
+ { ABIL_NEMELEX_STACK_DECK, "Stack Deck", 5, 0, 150, 6, ABFLAG_NONE },
// These six are unused "evil" god abilities:
{ ABIL_CHARM_SNAKE, "Charm Snake", 6, 0, 200, 5, ABFLAG_NONE },
@@ -1563,6 +1564,11 @@ static bool do_ability(const ability_def& abil)
return false;
break;
+ case ABIL_NEMELEX_STACK_DECK:
+ if ( !deck_stack() )
+ return false;
+ break;
+
//jmf: intended as invocations from evil god(s):
case ABIL_CHARM_SNAKE:
cast_snake_charm( you.experience_level * 2
diff --git a/crawl-ref/source/decks.cc b/crawl-ref/source/decks.cc
index 496a50f176..23c0d64c9d 100644
--- a/crawl-ref/source/decks.cc
+++ b/crawl-ref/source/decks.cc
@@ -20,6 +20,7 @@
#include "effects.h"
#include "food.h"
#include "it_use2.h"
+#include "itemprop.h"
#include "items.h"
#include "misc.h"
#include "monplace.h"
@@ -171,33 +172,33 @@ const char* card_name(card_type card)
case CARD_NORMALITY: return "Normality";
case CARD_SHADOW: return "the Shadow";
case CARD_GATE: return "the Gate";
- case CARD_STATUE: return "the Crystal Statue";
+ case CARD_STATUE: return "a statue";
case CARD_ACQUISITION: return "Acquisition";
case CARD_HASTEN: return "Haste";
- case CARD_DEMON_LESSER: return "a little demon";
+ case CARD_DEMON_LESSER: return "a demon";
case CARD_DEMON_COMMON: return "a demon";
- case CARD_DEMON_GREATER: return "a huge demon";
- case CARD_DEMON_SWARM: return "a swarm of little demons";
- case CARD_YAK: return "a huge, shaggy yak";
- case CARD_FIEND: return "a huge, scaly devil";
- case CARD_DRAGON: return "a huge, scaly dragon";
+ case CARD_DEMON_GREATER: return "a demon";
+ case CARD_DEMON_SWARM: return "a demon";
+ case CARD_YAK: return "a yak";
+ case CARD_FIEND: return "a devil";
+ case CARD_DRAGON: return "a dragon";
case CARD_GOLEM: return "a statue";
case CARD_THING_FUGLY: return "a very ugly thing";
- case CARD_LICH: return "a very irritated-looking skeletal thing";
+ case CARD_LICH: return "a lich";
case CARD_HORROR_UNSEEN:
- return player_see_invis() ? "a hideous abomination" : "a blank card";
+ return player_see_invis() ? "an abomination" : "a blank card";
case CARD_BLINK: return "Blink";
- case CARD_TELEPORT: return "the Portal of Delayed Transposition";
- case CARD_TELEPORT_NOW: return "the Portal of Instantaneous Transposition";
+ case CARD_TELEPORT: return "the Portal";
+ case CARD_TELEPORT_NOW: return "the Portal";
case CARD_RAGE: return "Rage";
case CARD_LEVITY: return "Levity";
case CARD_VENOM: return "Venom";
case CARD_XOM: return "the card of Xom";
case CARD_SLOW: return "Slowness";
case CARD_DECAY: return "Decay";
- case CARD_HEALING: return "the Elixir of Health";
- case CARD_HEAL_WOUNDS: return "the Symbol of Immediate Regeneration";
- case CARD_TORMENT: return "the Symbol of Torment";
+ case CARD_HEALING: return "Health";
+ case CARD_HEAL_WOUNDS: return "Health";
+ case CARD_TORMENT: return "Torment";
case CARD_FOUNTAIN: return "the Fountain";
case CARD_ALTAR: return "the Altar";
case CARD_FAMINE: return "Famine";
@@ -209,7 +210,7 @@ const char* card_name(card_type card)
case CARD_MAZE: return "the Maze";
case CARD_PANDEMONIUM: return "Pandemonium";
case CARD_IMPRISONMENT: return "the Prison";
- case CARD_RULES_FOR_BRIDGE: return "the rules for contract bridge";
+ case CARD_RULES_FOR_BRIDGE: return "the rules";
case NUM_CARDS: case CARD_RANDOM: return "a buggy card";
}
return "a very buggy card";
@@ -283,9 +284,7 @@ static bool wielding_deck()
{
if ( you.equip[EQ_WEAPON] == -1 )
return false;
- const item_def& item = you.inv[you.equip[EQ_WEAPON]];
- return ( item.base_type == OBJ_MISCELLANY &&
- subtype_to_decktype(item.sub_type) != DECK_OF_PUNISHMENT );
+ return is_deck(you.inv[you.equip[EQ_WEAPON]]);
}
bool deck_peek()
@@ -296,7 +295,7 @@ bool deck_peek()
return false;
}
item_def& item(you.inv[you.equip[EQ_WEAPON]]);
- if ( item.special != 0 )
+ if ( item.plus2 != 0 )
{
mpr("You already know what the next card will be.");
return false;
@@ -304,7 +303,67 @@ bool deck_peek()
const deck_type dtype = subtype_to_decktype(item.sub_type);
const card_type chosen = choose_one_card(dtype, false);
msg::stream << "You see " << card_name(chosen) << '.' << std::endl;
- item.special = chosen + 1;
+ item.plus2 = chosen + 1;
+ you.wield_change = true;
+ return true;
+}
+
+bool deck_stack()
+{
+ if ( !wielding_deck() )
+ {
+ mpr("You aren't wielding a deck!");
+ return false;
+ }
+ item_def& item(you.inv[you.equip[EQ_WEAPON]]);
+ if ( item.plus2 != 0 )
+ {
+ mpr("You can't stack a marked deck.");
+ return false;
+ }
+ const int num_to_stack = (item.plus < 5 ? item.plus : 5);
+ const deck_type dtype = subtype_to_decktype(item.sub_type);
+
+ std::vector<card_type> draws;
+ for ( int i = 0; i < num_to_stack; ++i )
+ draws.push_back(choose_one_card(dtype, false));
+
+ if ( draws.size() == 1 )
+ mpr("There's only one card left!");
+ else
+ mpr("Order the cards (bottom to top)...", MSGCH_PROMPT);
+
+ item.special = 0;
+
+ while ( draws.size() > 1 )
+ {
+ for ( unsigned int i = 0; i < draws.size(); ++i )
+ {
+ msg::stream << (static_cast<char>(i + 'a')) << " - "
+ << card_name(draws[i]) << std::endl;
+ }
+
+ int selected = -1;
+ while ( 1 )
+ {
+ const int keyin = tolower(get_ch());
+ if (keyin >= 'a' && keyin < 'a' + static_cast<int>(draws.size()))
+ {
+ selected = keyin - 'a';
+ break;
+ }
+ else
+ {
+ canned_msg(MSG_HUH);
+ }
+ }
+ item.special <<= 8;
+ item.special += draws[selected] + 1;
+ draws.erase(draws.begin() + selected);
+ mpr("Next card?", MSGCH_PROMPT);
+ }
+ item.plus2 = draws[0] + 1;
+ item.plus = num_to_stack; // no more deck after the stack
you.wield_change = true;
return true;
}
@@ -318,7 +377,7 @@ bool deck_triple_draw()
}
item_def& item(you.inv[you.equip[EQ_WEAPON]]);
- if ( item.special != 0 )
+ if ( item.plus2 != 0 )
{
mpr("You can't triple draw from a marked deck.");
return false;
@@ -345,9 +404,7 @@ bool deck_triple_draw()
int selected = -1;
while ( 1 )
{
- int keyin = get_ch();
- if ( isalpha(keyin) )
- keyin = tolower(keyin);
+ const int keyin = tolower(get_ch());
if (keyin >= 'a' && keyin < 'a' + num_to_draw)
{
selected = keyin - 'a';
@@ -370,18 +427,35 @@ bool deck_triple_draw()
return true;
}
+// In general, if the next cards in a deck are known, they will
+// be stored in plus2 (the next card) and special (up to 4 cards
+// after that, bitpacked.)
+// Hidden assumption: no more than 126 cards, otherwise the 5th
+// card could clobber the sign bit in special.
void evoke_deck( item_def& deck )
{
const deck_type which_deck = subtype_to_decktype(deck.sub_type);
mpr("You draw a card...");
- if ( deck.special == 0 )
+ if ( deck.plus2 == 0 )
{
deck_of_cards(which_deck);
}
else
{
- cards(static_cast<card_type>(deck.special - 1));
- deck.special = 0;
+ // draw the marked card
+ cards(static_cast<card_type>(deck.plus2 - 1));
+
+ // If there are more marked cards, shift them up
+ if ( deck.special )
+ {
+ const short next_card = (deck.special & 0xFF);
+ deck.special >>= 8;
+ deck.plus2 = next_card;
+ }
+ else
+ {
+ deck.plus2 = 0;
+ }
you.wield_change = true;
}
deck.plus--;
@@ -881,7 +955,7 @@ static void cards(card_type which_card)
mprf("A beautiful fountain of clear blue water grows from the "
"floor %s!",
(you.species == SP_NAGA || you.species == SP_CENTAUR) ?
- "before you!" : "at your feet!" );
+ "before you" : "at your feet" );
grd[you.x_pos][you.y_pos] = DNGN_BLUE_FOUNTAIN;
}
else
diff --git a/crawl-ref/source/decks.h b/crawl-ref/source/decks.h
index b0064b464a..671f57c88c 100644
--- a/crawl-ref/source/decks.h
+++ b/crawl-ref/source/decks.h
@@ -23,6 +23,7 @@ void deck_of_cards(deck_type which_deck);
deck_type subtype_to_decktype(int subtype);
bool deck_triple_draw();
bool deck_peek();
+bool deck_stack();
const char* card_name(card_type card);
#endif
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index e6b330cf1f..510d3c5441 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -35,6 +35,7 @@
#include "abl-show.h"
#include "debug.h"
+#include "decks.h"
#include "fight.h"
#include "itemname.h"
#include "itemprop.h"
@@ -3055,6 +3056,20 @@ static std::string describe_misc_item( const item_def &item )
description += "$";
+ if ( is_deck(item) && item.plus2 != 0 )
+ {
+ description += "$Next card(s): ";
+ description += card_name(static_cast<card_type>(item.plus2 - 1));
+ long spec = item.special;
+ while ( spec )
+ {
+ description += ", ";
+ description += card_name(static_cast<card_type>((spec & 0xFF)-1));
+ spec >>= 8;
+ }
+ description += "$";
+ }
+
return (description);
}
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index a6c3fe3ac5..29ed9d632c 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -115,6 +115,7 @@ enum ability_type
ABIL_LUGONU_ABYSS_ENTER,
ABIL_NEMELEX_TRIPLE_DRAW,
ABIL_NEMELEX_PEEK,
+ ABIL_NEMELEX_STACK_DECK,
ABIL_CHARM_SNAKE,
ABIL_TRAN_SERPENT_OF_HELL,
diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc
index 1605a8fd04..2db75c8220 100644
--- a/crawl-ref/source/itemname.cc
+++ b/crawl-ref/source/itemname.cc
@@ -1332,12 +1332,11 @@ std::string item_def::name_aux( bool terse, bool ident ) const
else
{
buff << misc_type_name(item_typ, know_type);
- if ( subtype_to_decktype(item_typ) != DECK_OF_PUNISHMENT &&
- this->special != 0 )
+ if ( is_deck(*this) && item_plus2 != 0 )
{
// an inscribed deck!
buff << " {"
- << card_name(static_cast<card_type>(this->special - 1))
+ << card_name(static_cast<card_type>(item_plus2 - 1))
<< "}";
}
}
diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc
index 6204158da4..bf786ca31f 100644
--- a/crawl-ref/source/itemprop.cc
+++ b/crawl-ref/source/itemprop.cc
@@ -2133,6 +2133,15 @@ bool is_shield_incompatible(const item_def &weapon, const item_def *shield)
&& !is_range_weapon(weapon);
}
+bool is_deck(const item_def &item)
+{
+ return item.base_type == OBJ_MISCELLANY
+ && (item.sub_type == MISC_DECK_OF_TRICKS
+ || item.sub_type == MISC_DECK_OF_SUMMONINGS
+ || item.sub_type == MISC_DECK_OF_POWER
+ || item.sub_type == MISC_DECK_OF_WONDERS);
+}
+
std::string item_base_name(const item_def &item)
{
switch ( item.base_type )
diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h
index c4311fd5e1..98c524b345 100644
--- a/crawl-ref/source/itemprop.h
+++ b/crawl-ref/source/itemprop.h
@@ -148,6 +148,8 @@ bool is_shield(const item_def &item);
bool is_shield_incompatible(const item_def &weapon,
const item_def *shield = NULL);
+bool is_deck(const item_def &item);
+
// Only works for armour/weapons/missiles
std::string item_base_name(const item_def &item);
const char* weapon_base_name(unsigned char subtype);
diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc
index b145a512fd..f1948b024a 100644
--- a/crawl-ref/source/output.cc
+++ b/crawl-ref/source/output.cc
@@ -350,7 +350,8 @@ void print_stats(void)
textcolor(prefcol);
cprintf("%s",
- wpn.name(DESC_INVENTORY, Options.terse_hand).c_str());
+ wpn.name(DESC_INVENTORY,
+ Options.terse_hand).substr(0,38).c_str());
textcolor(LIGHTGREY);
}
else
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 65c5a1edae..3fee742462 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -158,7 +158,7 @@ const char* god_gain_power_messages[MAX_NUM_GODS][MAX_GOD_ABILITIES] =
"draw cards with careful consideration",
"",
"",
- "" },
+ "stack decks" },
// Elyvilon
{ "call upon Elyvilon for minor healing",
"call upon Elyvilon for purification",
@@ -238,7 +238,7 @@ const char* god_lose_power_messages[MAX_NUM_GODS][MAX_GOD_ABILITIES] =
"draw cards with careful consideration",
"",
"",
- "" },
+ "stack decks" },
// Elyvilon
{ "call upon Elyvilon for minor healing",
"call upon Elyvilon for purification",