summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2007-06-17 20:43:18 +0000
committerharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2007-06-17 20:43:18 +0000
commit44f56edce815f5ff8fb4124829523439f1cc8ad2 (patch)
treedc7be3b6e516b32ca8130786b35ebecf43abbabd /crawl-ref
parentb7516d279965cc139c24507688047172bb7a0f7f (diff)
downloadcrawl-ref-44f56edce815f5ff8fb4124829523439f1cc8ad2.tar.gz
crawl-ref-44f56edce815f5ff8fb4124829523439f1cc8ad2.zip
Complete revamp of cards and decks, following David's ideas.
Many of the cards don't work yet (e.g., all Summoning cards); this will be fixed in the near future. Deck rarity, by the way, is encoded in its colour. Yuck - but I was out of bits in the item_def struct. Better ideas welcome. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1594 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/debug.cc2
-rw-r--r--crawl-ref/source/decks.cc1319
-rw-r--r--crawl-ref/source/decks.h5
-rw-r--r--crawl-ref/source/describe.cc88
-rw-r--r--crawl-ref/source/effects.cc4
-rw-r--r--crawl-ref/source/enum.h161
-rw-r--r--crawl-ref/source/externs.h20
-rw-r--r--crawl-ref/source/it_use2.cc6
-rw-r--r--crawl-ref/source/it_use2.h2
-rw-r--r--crawl-ref/source/it_use3.cc16
-rw-r--r--crawl-ref/source/item_use.cc5
-rw-r--r--crawl-ref/source/itemname.cc38
-rw-r--r--crawl-ref/source/itemprop.cc21
-rw-r--r--crawl-ref/source/itemprop.h1
-rw-r--r--crawl-ref/source/makeitem.cc46
-rw-r--r--crawl-ref/source/player.cc2
-rw-r--r--crawl-ref/source/religion.cc40
-rw-r--r--crawl-ref/source/shopping.cc3
-rw-r--r--crawl-ref/source/spells2.cc6
19 files changed, 897 insertions, 888 deletions
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc
index 0bf048d311..8aab11f501 100644
--- a/crawl-ref/source/debug.cc
+++ b/crawl-ref/source/debug.cc
@@ -2092,7 +2092,7 @@ void debug_card()
const card_type c = static_cast<card_type>(i);
if ( strstr(card_name(c), buf) != NULL )
{
- card_effect(c);
+ card_effect(c, DECK_RARITY_LEGENDARY);
break;
}
}
diff --git a/crawl-ref/source/decks.cc b/crawl-ref/source/decks.cc
index 62042cfb2b..d42dc33dfb 100644
--- a/crawl-ref/source/decks.cc
+++ b/crawl-ref/source/decks.cc
@@ -17,6 +17,7 @@
#include "externs.h"
+#include "beam.h"
#include "effects.h"
#include "food.h"
#include "it_use2.h"
@@ -29,253 +30,192 @@
#include "player.h"
#include "religion.h"
#include "spells1.h"
+#include "spells2.h"
#include "spells3.h"
+#include "spells4.h"
#include "spl-cast.h"
+#include "spl-util.h"
#include "stuff.h"
+#include "transfor.h"
+#include "view.h"
-static card_type deck_of_wonders[] =
-{
- CARD_BLANK,
- CARD_BUTTERFLY,
- CARD_WRAITH,
- CARD_EXPERIENCE,
- CARD_WEALTH,
- CARD_INTELLIGENCE,
- CARD_STRENGTH,
- CARD_QUICKSILVER,
- CARD_STUPIDITY,
- CARD_WEAKNESS,
- CARD_SLOTH,
- CARD_SHUFFLE,
- CARD_FREAK,
- CARD_DEATH,
- CARD_NORMALITY,
- CARD_SHADOW,
- CARD_GATE,
- CARD_STATUE,
- CARD_ACQUISITION,
- CARD_HASTEN,
- CARD_LICH,
- CARD_XOM,
- CARD_DECAY,
- CARD_ALTAR,
- CARD_FOUNTAIN,
- CARD_MAZE,
- CARD_PANDEMONIUM
+#define VECFROM(x) (x), (x) + ARRAYSIZE(x)
+#define DEFVEC(Z) static std::vector<card_type> Z(VECFROM(a_##Z))
+
+static card_type a_deck_of_transport[] = {
+ CARD_PORTAL, CARD_WARP, CARD_SWAP, CARD_VELOCITY
};
-static card_type deck_of_summoning[] =
-{
- CARD_STATUE,
- CARD_DEMON_LESSER,
- CARD_DEMON_COMMON,
- CARD_DEMON_GREATER,
- CARD_DEMON_SWARM,
- CARD_YAK,
- CARD_FIEND,
- CARD_DRAGON,
- CARD_GOLEM,
- CARD_THING_FUGLY,
- CARD_HORROR_UNSEEN
+DEFVEC(deck_of_transport);
+
+static card_type a_deck_of_emergency[] = {
+ CARD_TOMB, CARD_BANSHEE, CARD_DAMNATION, CARD_SOLITUDE, CARD_WARPWRIGHT
};
-static card_type deck_of_tricks[] =
-{
- CARD_BLANK,
- CARD_BUTTERFLY,
- CARD_BLINK,
- CARD_TELEPORT,
- CARD_TELEPORT_NOW,
- CARD_RAGE,
- CARD_LEVITY,
- CARD_HEALING,
- CARD_WILD_MAGIC,
- CARD_DEMON_LESSER,
- CARD_HASTEN
+DEFVEC(deck_of_emergency);
+
+static card_type a_deck_of_destruction[] = {
+ CARD_VITRIOL, CARD_FLAME, CARD_FROST, CARD_HAMMER
};
-static card_type deck_of_power[] =
-{
- CARD_BLANK,
- CARD_DEMON_COMMON,
- CARD_DEMON_GREATER,
- CARD_TELEPORT_NOW,
- CARD_VENOM,
- CARD_XOM,
- CARD_HEAL_WOUNDS,
- CARD_FAMINE,
- CARD_FEAST,
- CARD_WILD_MAGIC,
- CARD_VIOLENCE,
- CARD_PROTECTION,
- CARD_KNOWLEDGE,
- CARD_HASTEN,
- CARD_TORMENT,
- CARD_DEMON_SWARM,
- CARD_SLOW
+DEFVEC(deck_of_destruction);
+
+static card_type a_deck_of_battle[] = {
+ CARD_ELIXIR, CARD_BATTLELUST, CARD_METAMORPHOSIS,
+ CARD_HELM, CARD_BLADE, CARD_SHADOW
};
-// Supposed to be bad, small chance of OK... Nemelex wouldn't like a game
-// that didn't have some chance of "losing".
-static card_type deck_of_punishment[] =
-{
- CARD_BLANK,
- CARD_BUTTERFLY,
- CARD_WRAITH,
- CARD_WEALTH,
- CARD_STUPIDITY,
- CARD_WEAKNESS,
- CARD_SLOTH,
- CARD_SHUFFLE,
- CARD_FREAK,
- CARD_DEATH,
- CARD_NORMALITY,
- CARD_SHADOW,
- CARD_GATE,
- CARD_DEMON_SWARM,
- CARD_RAGE,
- CARD_VENOM,
- CARD_SLOW,
- CARD_DECAY,
- CARD_TORMENT,
- CARD_FAMINE,
- CARD_WILD_MAGIC,
- CARD_MAZE,
- CARD_PANDEMONIUM
+DEFVEC(deck_of_battle);
+
+static card_type a_deck_of_enchantments[] = {
+ CARD_ELIXIR
+};
+
+DEFVEC(deck_of_enchantments);
+
+static card_type a_deck_of_summoning[] = {
+ CARD_SUMMON_ANIMAL, CARD_SUMMON_DEMON, CARD_SUMMON_WEAPON
+};
+
+DEFVEC(deck_of_summoning);
+
+static card_type a_deck_of_wonders[] = {
+ CARD_POTION, CARD_FOCUS, CARD_SHUFFLE,
+ CARD_EXPERIENCE, CARD_WILD_MAGIC, CARD_GENETIC_ENGINEER
+};
+
+DEFVEC(deck_of_wonders);
+
+static card_type a_deck_of_dungeons[] = {
+ CARD_MAP, CARD_DOWSING, CARD_SPADE, CARD_TROWEL, CARD_MINEFIELD
+};
+
+DEFVEC(deck_of_dungeons);
+
+static card_type a_deck_of_oddities[] = {
+ CARD_GENIE, CARD_BARGAIN, CARD_WRATH, CARD_XOM,
+ CARD_FEAST, CARD_FAMINE, CARD_CURSE
};
-#define DECK_WONDERS_SIZE ARRAYSIZE(deck_of_wonders)
-#define DECK_SUMMONING_SIZE ARRAYSIZE(deck_of_summoning)
-#define DECK_TRICKS_SIZE ARRAYSIZE(deck_of_tricks)
-#define DECK_POWER_SIZE ARRAYSIZE(deck_of_power)
-#define DECK_PUNISHMENT_SIZE ARRAYSIZE(deck_of_punishment)
+DEFVEC(deck_of_oddities);
+
+static card_type a_deck_of_punishment[] = {
+ CARD_WRAITH, CARD_WILD_MAGIC, CARD_WRATH,
+ CARD_XOM, CARD_FAMINE, CARD_CURSE, CARD_TOMB,
+ CARD_DAMNATION, CARD_PORTAL, CARD_MINEFIELD
+};
+
+DEFVEC(deck_of_punishment);
+
+#undef DEFVEC
+#undef VECFROM
const char* card_name(card_type card)
{
switch (card)
{
- case CARD_BLANK: return "a blank card";
- case CARD_BUTTERFLY: return "Butterfly";
- case CARD_WRAITH: return "the Wraith";
- case CARD_EXPERIENCE: return "Experience";
- case CARD_WEALTH: return "Wealth";
- case CARD_INTELLIGENCE: return "the Brain";
- case CARD_STRENGTH: return "Strength";
- case CARD_QUICKSILVER: return "Quicksilver";
- case CARD_STUPIDITY: return "Stupidity";
- case CARD_WEAKNESS: return "Weakness";
- case CARD_SLOTH: return "the Slug";
- case CARD_SHUFFLE: return "Shuffle";
- case CARD_FREAK: return "the Freak";
- case CARD_DEATH: return "Death";
- case CARD_NORMALITY: return "Normality";
+ case CARD_BLANK: return "blank card";
+ case CARD_PORTAL: return "the Portal";
+ case CARD_WARP: return "the Warp";
+ case CARD_SWAP: return "Swap";
+ case CARD_VELOCITY: return "Velocity";
+ case CARD_DAMNATION: return "Damnation";
+ case CARD_SOLITUDE: return "Solitude";
+ case CARD_ELIXIR: return "the Elixir";
+ case CARD_BATTLELUST: return "Battlelust";
+ case CARD_METAMORPHOSIS: return "Metamorphosis";
+ case CARD_HELM: return "the Helm";
+ case CARD_BLADE: return "the Blade";
case CARD_SHADOW: return "the Shadow";
- case CARD_GATE: return "the Gate";
- case CARD_STATUE: return "a statue";
- case CARD_ACQUISITION: return "Acquisition";
- case CARD_HASTEN: return "Haste";
- case CARD_DEMON_LESSER: return "a demon";
- case CARD_DEMON_COMMON: return "a demon";
- 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 lich";
- case CARD_HORROR_UNSEEN:
- return player_see_invis() ? "an abomination" : "a blank card";
- case CARD_BLINK: return "Blink";
- 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 "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_POTION: return "the Potion";
+ case CARD_FOCUS: return "Focus";
+ case CARD_SHUFFLE: return "Shuffle";
+ case CARD_EXPERIENCE: return "Experience";
+ case CARD_GENETIC_ENGINEER: return "Genetics";
+ case CARD_DOWSING: return "Dowsing";
+ case CARD_TROWEL: return "the Trowel";
+ case CARD_MINEFIELD: return "the Minefield";
+ case CARD_GENIE: return "the Genie";
+ case CARD_TOMB: return "the Tomb";
+ case CARD_MAP: return "the Map";
+ case CARD_BANSHEE: return "the Banshee";
+ case CARD_WILD_MAGIC: return "Wild Magic";
+ case CARD_SUMMON_ANIMAL: return "the Herd";
+ case CARD_SUMMON_DEMON: return "the Pentagram";
+ case CARD_SUMMON_WEAPON: return "the Dance";
+ case CARD_SUMMON_ANY: return "Summoning";
+ case CARD_XOM: return "Xom";
case CARD_FAMINE: return "Famine";
case CARD_FEAST: return "the Feast";
- case CARD_WILD_MAGIC: return "Wild Magic";
- case CARD_VIOLENCE: return "Violence";
- case CARD_PROTECTION: return "Protection";
- case CARD_KNOWLEDGE: return "Knowledge";
- 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";
- case NUM_CARDS: case CARD_RANDOM: return "a buggy card";
+ case CARD_WARPWRIGHT: return "Warpwright";
+ case CARD_VITRIOL: return "Vitriol";
+ case CARD_FLAME: return "Flame";
+ case CARD_FROST: return "Frost";
+ case CARD_HAMMER: return "the Hammer";
+ case CARD_SPADE: return "the Spade";
+ case CARD_BARGAIN: return "the Bargain";
+ case CARD_WRATH: return "Wrath";
+ case CARD_WRAITH: return "the Wraith";
+ case CARD_CURSE: return "the Curse";
+ case NUM_CARDS: return "a buggy card";
}
return "a very buggy card";
}
-static card_type choose_one_card(deck_type which_deck, bool message)
+static card_type choose_one_card(const item_def& item, bool message)
{
- card_type *deck = deck_of_wonders;
- int max_card = 0;
-
- switch (which_deck)
+ std::vector<card_type> *pdeck = NULL;
+ switch ( item.sub_type )
{
- case DECK_OF_WONDERS:
- deck = deck_of_wonders;
- max_card = DECK_WONDERS_SIZE;
- break;
- case DECK_OF_SUMMONING:
- deck = deck_of_summoning;
- max_card = DECK_SUMMONING_SIZE;
- break;
- case DECK_OF_TRICKS:
- deck = deck_of_tricks;
- max_card = DECK_TRICKS_SIZE;
+ case MISC_DECK_OF_ESCAPE:
+ pdeck = (coinflip() ? &deck_of_transport : &deck_of_emergency);
+ break;
+ case MISC_DECK_OF_DESTRUCTION: pdeck = &deck_of_destruction; break;
+ case MISC_DECK_OF_DUNGEONS: pdeck = &deck_of_dungeons; break;
+ case MISC_DECK_OF_SUMMONING: pdeck = &deck_of_summoning; break;
+ case MISC_DECK_OF_WONDERS: pdeck = &deck_of_wonders; break;
+ case MISC_DECK_OF_PUNISHMENT: pdeck = &deck_of_punishment; break;
+ case MISC_DECK_OF_WAR:
+ switch ( random2(6) )
+ {
+ case 0: pdeck = &deck_of_destruction; break;
+ case 1: pdeck = &deck_of_enchantments; break;
+ case 2: pdeck = &deck_of_battle; break;
+ case 3: pdeck = &deck_of_summoning; break;
+ case 4: pdeck = &deck_of_transport; break;
+ case 5: pdeck = &deck_of_emergency; break;
+ }
break;
- case DECK_OF_POWER:
- deck = deck_of_power;
- max_card = DECK_POWER_SIZE;
+ case MISC_DECK_OF_CHANGES:
+ switch ( random2(3) )
+ {
+ case 0: pdeck = &deck_of_battle; break;
+ case 1: pdeck = &deck_of_dungeons; break;
+ case 2: pdeck = &deck_of_wonders; break;
+ }
break;
- case DECK_OF_PUNISHMENT:
- deck = deck_of_punishment;
- max_card = DECK_PUNISHMENT_SIZE;
+ case MISC_DECK_OF_DEFENSE:
+ pdeck = (coinflip() ? &deck_of_emergency : &deck_of_battle);
break;
}
- card_type chosen = deck[random2(max_card)];
-
- if (one_chance_in(250))
+ ASSERT( pdeck );
+
+ if ( one_chance_in(100) )
{
if ( message )
mpr("This card doesn't seem to belong here.");
- chosen = static_cast<card_type>(random2(NUM_CARDS));
+ pdeck = &deck_of_oddities;
}
+ card_type chosen = (*pdeck)[random2(pdeck->size())];
+
// High Evocations gives you another shot (but not at being punished...)
- if (which_deck != DECK_OF_PUNISHMENT && chosen == CARD_BLANK &&
+ if (pdeck != &deck_of_punishment && chosen == CARD_BLANK &&
you.skills[SK_EVOCATIONS] > random2(30))
- chosen = deck[random2(max_card)];
- return chosen;
-}
+ chosen = (*pdeck)[random2(pdeck->size())];
-// returns the deck type, of DECK_OF_PUNISHMENT if none
-deck_type subtype_to_decktype(int subtype)
-{
- switch ( subtype )
- {
- case MISC_DECK_OF_WONDERS:
- return DECK_OF_WONDERS;
- case MISC_DECK_OF_POWER:
- return DECK_OF_POWER;
- case MISC_DECK_OF_SUMMONINGS:
- return DECK_OF_SUMMONING;
- case MISC_DECK_OF_TRICKS:
- return DECK_OF_TRICKS;
- default: // sentinel
- return DECK_OF_PUNISHMENT;
- }
+ return chosen;
}
static bool wielding_deck()
@@ -298,8 +238,9 @@ bool deck_peek()
mpr("You already know what the next card will be.");
return false;
}
- const deck_type dtype = subtype_to_decktype(item.sub_type);
- const card_type chosen = choose_one_card(dtype, false);
+
+ const card_type chosen = choose_one_card(item, false);
+
msg::stream << "You see " << card_name(chosen) << '.' << std::endl;
item.plus2 = chosen + 1;
you.wield_change = true;
@@ -320,11 +261,10 @@ bool deck_stack()
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));
+ draws.push_back(choose_one_card(item, false));
if ( draws.size() == 1 )
mpr("There's only one card left!");
@@ -381,19 +321,17 @@ bool deck_triple_draw()
return false;
}
- const deck_type dtype = subtype_to_decktype(item.sub_type);
-
if (item.plus == 1)
{
// only one card to draw, so just draw it
- deck_of_cards(dtype);
+ evoke_deck(item);
return true;
}
const int num_to_draw = (item.plus < 3 ? item.plus : 3);
std::vector<card_type> draws;
for ( int i = 0; i < num_to_draw; ++i )
- draws.push_back(choose_one_card(dtype, false));
+ draws.push_back(choose_one_card(item, false));
mpr("You draw... (choose one card)");
for ( int i = 0; i < num_to_draw; ++i )
@@ -411,7 +349,7 @@ bool deck_triple_draw()
else
canned_msg(MSG_HUH);
}
- card_effect(draws[selected]);
+ card_effect(draws[selected], deck_rarity(item));
// remove the cards from the deck
item.plus -= num_to_draw;
@@ -425,6 +363,17 @@ bool deck_triple_draw()
return true;
}
+void draw_from_deck_of_punishment()
+{
+ item_def deck;
+ deck.plus = 10; // don't let it puff away
+ deck.plus2 = 0;
+ deck.colour = BLACK; // for rarity
+ deck.base_type = OBJ_MISCELLANY;
+ deck.sub_type = MISC_DECK_OF_PUNISHMENT;
+ evoke_deck(deck);
+}
+
// 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.)
@@ -432,16 +381,16 @@ bool deck_triple_draw()
// 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.plus2 == 0 )
{
- deck_of_cards(which_deck);
+ card_effect( choose_one_card(deck, true), deck_rarity(deck) );
}
else
{
// draw the marked card
- card_effect(static_cast<card_type>(deck.plus2 - 1));
+ card_effect(static_cast<card_type>(deck.plus2 - 1),
+ deck_rarity(deck));
// If there are more marked cards, shift them up
if ( deck.special )
@@ -465,527 +414,520 @@ void evoke_deck( item_def& deck )
unwield_item(you.equip[EQ_WEAPON]);
dec_inv_item_quantity( you.equip[EQ_WEAPON], 1 );
- // these bonuses happen only when the deck expires {dlb}:
brownie_points = (coinflip() ? 2 : 1);
-
- if (which_deck == DECK_OF_WONDERS)
- brownie_points += 2;
- else if (which_deck == DECK_OF_POWER)
- brownie_points++;
}
- // this bonus happens with every use {dlb}:
- if (which_deck == DECK_OF_WONDERS || one_chance_in(3))
+ if (one_chance_in(3))
brownie_points++;
did_god_conduct(DID_CARDS, brownie_points);
}
-void deck_of_cards(deck_type which_deck)
-{
- card_effect(choose_one_card(which_deck, true));
-}
-
-void card_effect(card_type which_card)
+int get_power_level(int power, deck_rarity_type rarity)
{
- FixedVector < int, 5 > dvar;
- FixedVector < int, 5 > mvar;
- int dvar1 = 0;
- int loopy = 0; // general purpose loop variable {dlb}
- bool success = false; // for summoning messages {dlb}
- bool failMsg = true;
- int summ_dur, summ_beh, summ_num;
-
- if (which_card == CARD_BLANK && one_chance_in(10))
- which_card = CARD_RULES_FOR_BRIDGE;
-
- switch (which_card)
+ int power_level = 0;
+ switch ( rarity )
{
- case CARD_BLANK:
- mpr("It is blank.");
- break;
-
- case CARD_BUTTERFLY:
- mpr("You have drawn the Butterfly.");
-
- summ_dur = 1 + random2(3) + you.skills[SK_EVOCATIONS] / 2;
- if (summ_dur > 6)
- summ_dur = 6;
-
- if (create_monster( MONS_BUTTERFLY, summ_dur, BEH_FRIENDLY,
- you.x_pos, you.y_pos, MHITYOU, 250 ) != -1)
- {
- mpr("A brightly coloured insect flies from the card!");
- }
- break;
-
- case CARD_WRAITH:
- mpr("You have drawn the Wraith.");
-
- lose_level();
- drain_exp();
- break;
-
- case CARD_EXPERIENCE:
- mpr( "You have drawn Experience." );
- potion_effect( POT_EXPERIENCE, 0 );
- break;
-
- case CARD_WEALTH:
- mpr("You have drawn Wealth.");
-
- you.gold += roll_dice( 2, 20 * you.skills[SK_EVOCATIONS] );
- you.redraw_gold = 1;
- break;
-
- case CARD_INTELLIGENCE:
- mpr("You have drawn the Brain!");
-
- you.intel += 1 + random2( you.skills[SK_EVOCATIONS] ) / 7;
-
- if (you.max_intel < you.intel)
- you.max_intel = you.intel;
-
- you.redraw_intelligence = 1;
- break;
-
- case CARD_STRENGTH:
- mpr("You have drawn Strength!");
-
- you.strength += 1 + random2( you.skills[SK_EVOCATIONS] ) / 7;
-
- if (you.max_strength < you.strength)
- you.max_strength = you.strength;
-
- you.redraw_strength = 1;
- break;
-
- case CARD_QUICKSILVER:
- mpr("You have drawn the Quicksilver card.");
-
- you.dex += 1 + random2( you.skills[SK_EVOCATIONS] ) / 7;
-
- if (you.max_dex < you.dex)
- you.max_dex = you.dex;
-
- you.redraw_dexterity = 1;
+ case DECK_RARITY_COMMON:
break;
-
- case CARD_STUPIDITY:
- mpr("You have drawn Stupidity!");
-
- you.intel -= (2 + random2avg(3, 2));
- if (you.intel < 4)
- you.intel = 0;
-
- if (you.skills[SK_EVOCATIONS] < random2(30))
- you.max_intel--;
-
- you.redraw_intelligence = 1;
- break;
-
- case CARD_WEAKNESS:
- mpr("You have drawn Weakness.");
-
- you.strength -= (2 + random2avg(3, 2));
- if (you.strength < 4)
- you.strength = 0;
-
- if (you.skills[SK_EVOCATIONS] < random2(30))
- you.max_strength--;
-
- you.redraw_strength = 1;
+ case DECK_RARITY_LEGENDARY:
+ if ( random2(500) < power )
+ ++power_level;
+ // deliberate fall-through
+ case DECK_RARITY_RARE:
+ if ( random2(700) < power )
+ ++power_level;
break;
+ }
+ return power_level;
+}
- case CARD_SLOTH:
- mpr("You have drawn the Slug.");
+/* Actual card implementations follow. */
+void portal_card(int power, deck_rarity_type rarity)
+{
+ const int control_level = get_power_level(power, rarity);
+ bool instant = false;
+ bool controlled = false;
+ if ( control_level >= 2 )
+ {
+ instant = true;
+ controlled = true;
+ }
+ else if ( control_level == 1 )
+ {
+ if ( coinflip() )
+ instant = true;
+ else
+ controlled = true;
+ }
- you.dex -= (2 + random2avg(3, 2));
- if (you.dex < 4)
- you.dex = 0;
+ const bool was_controlled = player_control_teleport();
+ if ( controlled && !was_controlled )
+ you.duration[DUR_CONTROL_TELEPORT] = 1;
- if (you.skills[SK_EVOCATIONS] < random2(30))
- you.max_dex--;
+ if ( instant )
+ you_teleport_now( true );
+ else
+ you_teleport();
- you.redraw_dexterity = 1;
- break;
+ if ( controlled && !was_controlled )
+ you.duration[DUR_CONTROL_TELEPORT] = 0;
+}
- case CARD_SHUFFLE: // shuffle stats
- mpr("You have drawn the Shuffle card!");
+void warp_card(int power, deck_rarity_type rarity)
+{
+ const int control_level = get_power_level(power, rarity);
+ if ( control_level >= 2 )
+ blink();
+ else if ( control_level == 1 )
+ cast_semi_controlled_blink(power / 4);
+ else
+ random_blink(false);
+}
- dvar[STAT_STRENGTH] = you.strength;
- dvar[STAT_DEXTERITY] = you.dex;
- dvar[STAT_INTELLIGENCE] = you.intel;
+void swap_monster_card(int power, deck_rarity_type rarity)
+{
+ // swap between you and another monster
+}
- mvar[STAT_STRENGTH] = you.max_strength;
- mvar[STAT_DEXTERITY] = you.max_dex;
- mvar[STAT_INTELLIGENCE] = you.max_intel;
+void velocity_card(int power, deck_rarity_type rarity)
+{
+ const int power_level = get_power_level(power, rarity);
+ if ( power_level >= 2 )
+ {
+ potion_effect( POT_SPEED, random2(power / 4) );
+ }
+ else if ( power_level == 1 )
+ {
+ potion_effect( POT_LEVITATION, random2(power / 4) );
+ cast_swiftness( random2(power/4) );
+ }
+ else
+ {
+ cast_swiftness( random2(power/4) );
+ }
+}
- you.strength = 101;
- you.intel = 101;
- you.dex = 101;
+void damnation_card(int power, deck_rarity_type rarity)
+{
+ // pick a random monster nearby to banish
+ int mons_count = 1; // you
+ int mon_to_banish = NON_MONSTER;
+
+ int ystart = you.y_pos - 9, xstart = you.x_pos - 9;
+ int yend = you.y_pos + 9, xend = you.x_pos + 9;
+ if ( xstart < 0 ) xstart = 0;
+ if ( ystart < 0 ) ystart = 0;
+ if ( xend >= GXM ) xend = GXM;
+ if ( ystart >= GYM ) yend = GYM;
+
+ /* monster check */
+ for ( int y = ystart; y < yend; ++y )
+ for ( int x = xstart; x < xend; ++x )
+ if ( see_grid(x,y) && mgrd[x][y] != NON_MONSTER )
+ if ( one_chance_in(++mons_count) )
+ mon_to_banish = mgrd[x][y];
+
+ if ( mon_to_banish == NON_MONSTER ) // banish yourself!
+ {
+ banished(DNGN_ENTER_ABYSS);
+ }
+ else
+ {
+ menv[mon_to_banish].banish();
+ }
+}
- do
+void warpwright_card(int power, deck_rarity_type rarity)
+{
+ int count = 0;
+ int fx = -1, fy = -1;
+ for ( int dx = -1; dx <= 1; ++dx )
+ {
+ for ( int dy = -1; dy <= 1; ++dy )
{
- dvar1 = random2(NUM_STATS);
-
- if (dvar[dvar1] == 101)
+ if ( dx == 0 && dy == 0 )
continue;
-
- if (you.strength == 101)
- {
- you.strength = dvar[dvar1];
- you.max_strength = mvar[dvar1];
- }
- else if (you.intel == 101)
- {
- you.intel = dvar[dvar1];
- you.max_intel = mvar[dvar1];
- }
- else if (you.dex == 101)
+ const int rx = you.x_pos + dx;
+ const int ry = you.y_pos + dy;
+ if ( grd[rx][ry] == DNGN_FLOOR && trap_at_xy(rx,ry) == -1 )
{
- you.dex = dvar[dvar1];
- you.max_dex = mvar[dvar1];
+ if ( one_chance_in(++count) )
+ {
+ fx = rx;
+ fy = ry;
+ }
}
-
- dvar[dvar1] = 101;
}
- while (dvar[STAT_STRENGTH] != 101 || dvar[STAT_DEXTERITY] != 101
- || dvar[STAT_INTELLIGENCE] != 101);
-
- you.redraw_strength = 1;
- you.redraw_intelligence = 1;
- you.redraw_dexterity = 1;
- burden_change();
- break;
+ }
- case CARD_FREAK:
- mpr("You have drawn the Freak!");
- for (loopy = 0; loopy < 6; loopy++)
+ if ( fx >= 0 ) // found a spot
+ {
+ if ( place_specific_trap(fx, fy, TRAP_TELEPORT) )
{
- if (!mutate(100, failMsg))
- failMsg = false;
+ // mark it discovered if enough power
+ if ( get_power_level(power, rarity) >= 1 )
+ {
+ const int i = trap_at_xy(fx, fy);
+ if (i != -1) // should always happen
+ grd[fx][fy] = trap_category(env.trap[i].type);
+ }
}
- break;
-
- case CARD_DEATH:
- mpr("Oh no! You have drawn the Death card!");
-
- if (you.duration[DUR_TELEPORT])
- you_teleport();
+ }
+}
- for (loopy = 0; loopy < 5; loopy++)
- {
- create_monster( MONS_REAPER, 0, BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 );
- }
- break;
+void damaging_card( card_type card, int power, deck_rarity_type rarity )
+{
+ dist target;
+ bolt beam;
+
+
+ zap_type ztype;
+ switch ( card )
+ {
+ case CARD_VITRIOL: ztype = ZAP_BREATHE_ACID; break;
+ case CARD_FLAME: ztype = ZAP_BREATHE_FIRE; break;
+ case CARD_FROST: ztype = ZAP_BREATHE_FROST; break;
+ case CARD_HAMMER: ztype = ZAP_BREATHE_POWER; break;
+ default: ztype = ZAP_DEBUGGING_RAY; break;
+ }
- case CARD_NORMALITY:
- mpr("You have drawn Normalisation.");
- for (loopy = 0; loopy < 6; loopy++)
- {
- delete_mutation(100);
- }
- break;
+ // For now, just throw a bolt in that direction.
+ // Make this more interesting later! XXX
+ if ( spell_direction( target, beam ) != -1 )
+ zapping(ztype, random2(power/4), beam);
+}
- case CARD_SHADOW:
- mpr("You have drawn the Shadow.");
- create_monster( MONS_SOUL_EATER, 0, BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 );
- break;
+void elixir_card(int power, deck_rarity_type rarity)
+{
+ int power_level = get_power_level(power, rarity);
- case CARD_GATE:
- mpr("You have drawn the Gate!");
+ if ( power_level == 1 && you.hp * 2 > you.hp_max )
+ power_level = 0;
- if (you.level_type == LEVEL_ABYSS)
- banished(DNGN_EXIT_ABYSS, "drew the Gate");
- else if (you.level_type == LEVEL_LABYRINTH)
- canned_msg(MSG_NOTHING_HAPPENS);
+ if ( power_level == 0 )
+ {
+ if ( coinflip() )
+ potion_effect( POT_HEAL_WOUNDS, 40 ); // doesn't matter
else
- {
- mpr("You are cast into the Abyss!");
- banished(DNGN_ENTER_ABYSS, "drew the Gate");
- }
- break;
-
- case CARD_STATUE:
- mpr("You have drawn the Crystal Statue.");
- create_monster( MONS_CRYSTAL_GOLEM, 0, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 );
- break;
-
- case CARD_ACQUISITION:
- mpr( "You have drawn Acquisition!" );
- mpr( "The card unfolds to form a scroll of paper." );
- acquirement( OBJ_RANDOM, AQ_CARD_ACQUISITION );
- break;
-
- case CARD_HASTEN:
- mpr("You have drawn Haste.");
- potion_effect( POT_SPEED, 5 * you.skills[SK_EVOCATIONS] );
- break;
-
- case CARD_DEMON_LESSER:
- mpr("On the card is a picture of a little demon.");
-
- summ_dur = cap_int(1 + random2(3) + you.skills[SK_EVOCATIONS] / 3, 6);
-
- if (create_monster( summon_any_demon( DEMON_LESSER ), summ_dur,
- BEH_FRIENDLY, you.x_pos, you.y_pos, you.pet_target,
- 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
-
- case CARD_DEMON_COMMON:
- mpr("On the card is a picture of a demon.");
-
- summ_dur = cap_int(1 + random2(3) + you.skills[SK_EVOCATIONS] / 4, 6);
-
- if (create_monster( summon_any_demon( DEMON_COMMON ), summ_dur,
- BEH_FRIENDLY, you.x_pos, you.y_pos, you.pet_target,
- 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
-
- case CARD_DEMON_GREATER:
- mpr("On the card is a picture of a huge demon.");
-
- summ_beh = (you.skills[SK_EVOCATIONS] > random2(30)) ? BEH_FRIENDLY
- : BEH_CHARMED;
+ cast_regen( random2(power / 4) );
+ }
+ else if ( power_level == 1 )
+ {
+ you.hp = you.hp_max;
+ you.magic_points = 0;
+ }
+ else if ( power_level >= 2 )
+ {
+ you.hp = you.hp_max;
+ you.magic_points = you.max_magic_points;
+ }
+}
- if (summ_beh == BEH_CHARMED)
- mpr( "You don't feel so good about this..." );
+void battle_lust_card(int power, deck_rarity_type rarity)
+{
+ const int power_level = get_power_level(power, rarity);
+ if ( power_level >= 2 )
+ {
+ // temporary ring of slaying effect XXX
+ }
+ else if ( power_level == 1 )
+ go_berserk(false);
+ else if ( power_level == 0 )
+ potion_effect(POT_MIGHT, random2(power/4));
+}
- if (create_monster( summon_any_demon( DEMON_GREATER ), 5,
- summ_beh, you.x_pos, you.y_pos,
- you.pet_target, 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
+void metamorphosis_card(int power, deck_rarity_type rarity)
+{
+ const int power_level = get_power_level(power, rarity);
+ transformation_type trans;
+ if ( power_level >= 2 )
+ trans = (coinflip() ? TRAN_DRAGON : TRAN_LICH);
+ else
+ trans = (coinflip() ? TRAN_STATUE : TRAN_BLADE_HANDS);
+ transform(random2(power/4), trans);
+}
- case CARD_DEMON_SWARM:
- mpr("On the card is a picture of a swarm of little demons.");
+void helm_card(int power, deck_rarity_type rarity)
+{
+ const int power_level = get_power_level(power, rarity);
+ bool do_forescry = false;
+ bool do_stoneskin = false;
+ bool do_shield = false;
+ int num_resists = 0;
+ if ( power_level >= 2 )
+ {
+ if ( coinflip() ) do_forescry = true;
+ if ( coinflip() ) do_stoneskin = true;
+ if ( coinflip() ) do_shield = true;
+ num_resists = random2(4);
+ }
+ if ( power_level >= 1 )
+ {
+ if ( coinflip() ) do_forescry = true;
+ if ( coinflip() ) do_stoneskin = true;
+ if ( coinflip() ) do_shield = true;
+ }
+ if ( power_level >= 0 )
+ {
+ if ( coinflip() )
+ do_forescry = true;
+ else
+ do_stoneskin = true;
+ }
- success = false;
+ if ( do_forescry )
+ cast_forescry( random2(power/4) );
+ if ( do_stoneskin )
+ cast_stoneskin( random2(power/4) );
- summ_num = 7 + random2(6);
+ // XXX XXX FIXME handle do_shield, do_resist
+}
- for (loopy = 0; loopy < summ_num; loopy++)
- {
- if (create_monster( summon_any_demon( DEMON_LESSER ), 6,
- BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250 ) != -1)
- {
- success = true;
- }
- }
+// Do one of: vorpalise, sure blade, dancing weapon
+// XXX XXX FIXME Hard to do now, because you have to
+// wield the deck in order to evoke it!
+void blade_card(int power, deck_rarity_type rarity)
+{
+ return;
+ const int power_level = get_power_level(power, rarity);
+ if ( power_level >= 2 )
+ {
+ dancing_weapon( random2(power/4), false );
+ }
+ else if ( power_level == 1 )
+ {
+ cast_sure_blade( random2(power/4) );
+ }
+ else
+ {
+ brand_weapon(SPWPN_VORPAL, random2(power/4)); // maybe other brands?
+ }
+}
- if (success)
- mpr("The picture comes to life!");
- break;
+void shadow_card(int power, deck_rarity_type rarity)
+{
+ const int power_level = get_power_level(power, rarity);
+ if ( power_level >= 1 )
+ {
+ // XXX add a stealth attribute here
+ }
+ potion_effect(POT_INVISIBILITY, random2(power/4));
+}
- case CARD_YAK:
- mpr("On the card is a picture of a huge shaggy yak.");
+void potion_card(int power, deck_rarity_type rarity)
+{
+ const int power_level = get_power_level(power, rarity);
+ potion_type pot_effects[] = {
+ POT_HEAL_WOUNDS, POT_HEAL_WOUNDS, POT_HEAL_WOUNDS,
+ POT_HEALING, POT_HEALING, POT_HEALING,
+ POT_RESTORE_ABILITIES, POT_RESTORE_ABILITIES,
+ POT_POISON, POT_CONFUSION, POT_DEGENERATION
+ };
- summ_dur = cap_int(2 + you.skills[SK_EVOCATIONS] / 2, 6);
- if (create_monster( MONS_DEATH_YAK, summ_dur, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
+ potion_type pot = pot_effects[random2(ARRAYSIZE(pot_effects))];
- case CARD_FIEND:
- mpr("On the card is a picture of a huge scaly devil.");
+ if ( power_level >= 1 && coinflip() )
+ pot = (coinflip() ? POT_CURE_MUTATION : POT_MUTATION);
- summ_dur = cap_int(2 + you.skills[SK_EVOCATIONS] / 6, 6);
- if (create_monster( MONS_FIEND, summ_dur, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
+ if ( power_level >= 2 && one_chance_in(5) )
+ pot = POT_MAGIC;
- case CARD_DRAGON:
- mpr("On the card is a picture of a huge scaly dragon.");
+ potion_effect(pot, random2(power/4));
+}
- summ_dur = cap_int(3 + you.skills[SK_EVOCATIONS] / 6, 6);
- if (create_monster( (coinflip() ? MONS_DRAGON : MONS_ICE_DRAGON),
- summ_dur, BEH_FRIENDLY, you.x_pos, you.y_pos,
- you.pet_target, 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
+void focus_card(int power, deck_rarity_type rarity)
+{
+ char* max_statp[] = { &you.max_strength, &you.max_intel, &you.max_dex };
+ char* base_statp[] = { &you.strength, &you.intel, &you.dex };
+ int best_stat = 0;
+ int worst_stat = 0;
- case CARD_GOLEM:
- mpr("On the card is a picture of a statue.");
+ for ( int i = 1; i < 3; ++i )
+ {
+ const int best_diff = *max_statp[i] - *max_statp[best_stat];
+ if ( best_diff > 0 || (best_diff == 0 && coinflip()) )
+ best_stat = i;
+ const int worst_diff = *max_statp[i] - *max_statp[worst_stat];
+ if ( worst_diff < 0 || (worst_diff == 0 && coinflip()) )
+ worst_stat = i;
+ }
- summ_dur = cap_int(2 + you.skills[SK_EVOCATIONS] / 4, 6);
- if (create_monster( MONS_CLAY_GOLEM + random2(6), summ_dur,
- BEH_FRIENDLY, you.x_pos, you.y_pos,
- you.pet_target, 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
+ while ( best_stat == worst_stat )
+ {
+ best_stat = random2(3);
+ worst_stat = random2(3);
+ }
- case CARD_THING_FUGLY:
- mpr("On the card is a picture of a very ugly thing.");
+ (*max_statp[best_stat])++;
+ (*max_statp[worst_stat])--;
+ (*base_statp[best_stat])++;
+ (*base_statp[worst_stat])--;
+ you.redraw_strength = true;
+ you.redraw_intelligence = true;
+ you.redraw_dexterity = true;
+}
- summ_dur = cap_int(2 + you.skills[SK_EVOCATIONS] / 4, 6);
- if (create_monster( MONS_VERY_UGLY_THING, summ_dur, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 ) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
+void shuffle_card(int power, deck_rarity_type rarity)
+{
+ // not yet implemented
+ // should shuffle *base* stat levels
+ return;
+}
- case CARD_LICH:
- mpr( "On the card is a picture of a very irritated-looking "
- "skeletal thing." );
+void genetic_engineer_card(int power, deck_rarity_type rarity)
+{
+ mutation_type bad_mutations[] = {
+ MUT_FAST_METABOLISM, MUT_WEAK, MUT_DOPEY, MUT_CLUMSY,
+ MUT_TELEPORT, MUT_DEFORMED, MUT_LOST, MUT_DETERIORATION,
+ MUT_BLURRY_VISION, MUT_FRAIL
+ };
+
+ mutation_type which_mut;
+ int numfound = 0;
+ for ( unsigned int i = 0; i < ARRAYSIZE(bad_mutations); ++i )
+ {
+ if (you.mutation[bad_mutations[i]] > you.demon_pow[bad_mutations[i]])
+ if ( one_chance_in(++numfound) )
+ which_mut = bad_mutations[i];
+ }
+ if ( numfound )
+ delete_mutation(which_mut);
+}
- if (create_monster( MONS_LICH, 0, BEH_HOSTILE, you.x_pos, you.y_pos,
- MHITYOU, 250) != -1)
- {
- mpr("The picture comes to life!");
- }
- break;
+void dowsing_card(int power, deck_rarity_type rarity)
+{
+ const int power_level = get_power_level(power, rarity);
+ bool things_to_do[3] = { false, false, false };
+ things_to_do[random2(3)] = true;
+
+ if ( power_level == 1 )
+ things_to_do[random2(3)] = true;
+
+ if ( power_level >= 2 )
+ for ( int i = 0; i < 3; ++i )
+ things_to_do[i] = true;
+
+ if ( things_to_do[0] )
+ cast_detect_secret_doors( random2(power/4) );
+ if ( things_to_do[1] )
+ detect_traps( random2(power/4) );
+ if ( things_to_do[2] )
+ detect_creatures( random2(power/4) );
+}
- case CARD_HORROR_UNSEEN:
- if (!player_see_invis())
- mpr("It is blank!");
- else
- mpr("On the card is a picture of a hideous abomination.");
+void trowel_card(int power, deck_rarity_type rarity)
+{
+ // not implemented yet
+ return;
+}
- summ_dur = cap_int(2 + you.skills[SK_EVOCATIONS] / 4, 6);
- if (create_monster( MONS_UNSEEN_HORROR, summ_dur, BEH_FRIENDLY,
- you.x_pos, you.y_pos, you.pet_target, 250 ) != -1)
- {
- if (player_see_invis())
- {
- mpr("The picture comes to life!");
- }
- }
- break;
+void minefield_card(int power, deck_rarity_type rarity)
+{
+ // not implemented yet
+ return;
+}
- case CARD_BLINK:
- mpr("You have drawn Blink.");
- blink();
- // random_blink(true);
- break;
+void genie_card(int power, deck_rarity_type rarity)
+{
+ if ( coinflip() )
+ acquirement( OBJ_RANDOM, AQ_CARD_ACQUISITION );
+ else
+ potion_effect( coinflip() ? POT_DEGENERATION : POT_DECAY, 40 );
+}
- case CARD_TELEPORT:
- mpr("You have drawn the Portal of Delayed Transposition.");
- you_teleport();
- break;
+int card_power(deck_rarity_type rarity)
+{
+ int result = 0;
- case CARD_TELEPORT_NOW:
- mpr( "You have drawn the Portal of Instantaneous Transposition." );
- you_teleport_now( true, true ); // in abyss, always to new area
- break;
+ if ( you.penance[GOD_NEMELEX_XOBEH] )
+ {
+ result -= you.penance[GOD_NEMELEX_XOBEH];
+ }
+ else if ( you.religion == GOD_NEMELEX_XOBEH && you.duration[DUR_PRAYER] )
+ {
+ result = you.piety;
+ result *= (you.skills[SK_INVOCATIONS] + 25);
+ result /= 27;
+ }
- case CARD_RAGE:
- mpr("You have drawn Rage.");
+ result += you.skills[SK_EVOCATIONS] * 9;
+ if ( rarity == DECK_RARITY_RARE )
+ result += random2(result / 2);
+ if ( rarity == DECK_RARITY_LEGENDARY )
+ result += random2(result);
- if (!go_berserk(false))
- canned_msg(MSG_NOTHING_HAPPENS);
- else
- you.berserk_penalty = NO_BERSERK_PENALTY;
- break;
+ return result;
+}
- case CARD_LEVITY:
- mpr("You have drawn Levity.");
- potion_effect( POT_LEVITATION, 5 * you.skills[SK_EVOCATIONS] );
- break;
+void card_effect(card_type which_card, deck_rarity_type rarity)
+{
+ const int power = card_power(rarity);
- case CARD_VENOM:
- mpr("You have drawn Venom.");
- poison_player( 2 + random2( 7 - you.skills[SK_EVOCATIONS] / 5 ) );
- break;
+ msg::stream << "You have drawn " << card_name( which_card )
+ << '.' << std::endl;
- case CARD_XOM:
- mpr("You have drawn the card of Xom!");
- xom_acts( true, 5 + random2( you.skills[SK_EVOCATIONS] ));
+ switch (which_card)
+ {
+ case CARD_BLANK: break;
+ case CARD_PORTAL: portal_card(power, rarity); break;
+ case CARD_WARP: warp_card(power, rarity); break;
+ case CARD_SWAP: swap_monster_card(power, rarity); break;
+ case CARD_VELOCITY: velocity_card(power, rarity); break;
+ case CARD_DAMNATION: damnation_card(power, rarity); break;
+ case CARD_SOLITUDE: cast_dispersal(power/4); break;
+ case CARD_ELIXIR: elixir_card(power, rarity); break;
+ case CARD_BATTLELUST: battle_lust_card(power, rarity); break;
+ case CARD_METAMORPHOSIS: metamorphosis_card(power, rarity); break;
+ case CARD_HELM: helm_card(power, rarity); break;
+ case CARD_BLADE: blade_card(power, rarity); break;
+ case CARD_SHADOW: shadow_card(power, rarity); break;
+ case CARD_POTION: potion_card(power, rarity); break;
+ case CARD_FOCUS: focus_card(power, rarity); break;
+ case CARD_SHUFFLE: shuffle_card(power, rarity); break;
+ case CARD_EXPERIENCE: potion_effect(POT_EXPERIENCE, power/4); break;
+ case CARD_GENETIC_ENGINEER: genetic_engineer_card(power, rarity); break;
+ case CARD_DOWSING: dowsing_card(power, rarity); break;
+ case CARD_TROWEL: trowel_card(power, rarity); break;
+ case CARD_MINEFIELD: minefield_card(power, rarity); break;
+ case CARD_GENIE: genie_card(power, rarity); break;
+ case CARD_TOMB: entomb(); break;
+
+ case CARD_WARPWRIGHT: case CARD_SPADE: case CARD_WRATH:
+ case CARD_WRAITH: case CARD_CURSE: case CARD_BARGAIN:
+ mpr("Sorry, this card is not yet available.");
break;
-
- case CARD_SLOW:
- mpr("You have drawn Slowness.");
- potion_effect( POT_SLOWING, 100 - 2 * you.skills[SK_EVOCATIONS] );
+
+ case CARD_VITRIOL: case CARD_FLAME: case CARD_FROST: case CARD_HAMMER:
+ damaging_card(which_card, power, rarity);
break;
- case CARD_DECAY:
- mpr("You have drawn Decay.");
- if (you.is_undead)
- mpr("You feel terrible.");
- else
- rot_player( 2 + random2( 7 - you.skills[SK_EVOCATIONS] / 4 ) );
- break;
+ case CARD_MAP: magic_mapping( random2(power/10) + 15,
+ random2(power) );
- case CARD_HEALING:
- mpr("You have drawn the Elixir of Health.");
- potion_effect( POT_HEALING, 5 * you.skills[SK_EVOCATIONS] );
- break;
+ case CARD_BANSHEE: mass_enchantment(ENCH_FEAR, power, MHITYOU); break;
- case CARD_HEAL_WOUNDS:
- mpr("You have drawn the Symbol of Immediate Regeneration.");
- potion_effect( POT_HEAL_WOUNDS, 5 * you.skills[SK_EVOCATIONS] );
+ case CARD_WILD_MAGIC:
+ // yes, high power is bad here
+ miscast_effect( SPTYP_RANDOM, random2(power/15) + 5,
+ random2(power), 0 );
break;
- case CARD_TORMENT:
- mpr("You have drawn the Symbol of Torment.");
- torment( TORMENT_CARDS, you.x_pos, you.y_pos );
- break;
-
- case CARD_FOUNTAIN:
- // what about checking whether there are items there, too? {dlb}
- mpr("You have drawn the Fountain.");
+ case CARD_SUMMON_ANIMAL: break;
+ case CARD_SUMMON_DEMON: break;
+ case CARD_SUMMON_WEAPON: break;
+ case CARD_SUMMON_ANY: break;
- if (grd[you.x_pos][you.y_pos] == DNGN_FLOOR)
- {
- 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" );
- grd[you.x_pos][you.y_pos] = DNGN_BLUE_FOUNTAIN;
- }
- else
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- }
- break;
- case CARD_ALTAR:
- mpr("You have drawn the Altar.");
+ /* if (create_monster( summon_any_demon( DEMON_LESSER ), 6,
+ BEH_HOSTILE, you.x_pos, you.y_pos,
+ MHITYOU, 250 ) != -1)
+ */
- if (you.religion == GOD_NO_GOD ||
- grd[you.x_pos][you.y_pos] != DNGN_FLOOR)
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- }
- else
- {
- const dungeon_feature_type altar =
- static_cast<dungeon_feature_type>(
- DNGN_ALTAR_ZIN + you.religion - 1 );
-
- mprf("An altar grows from the floor %s!",
- (you.species == SP_NAGA || you.species == SP_CENTAUR)
- ? "before you" : "at your feet");
- grd[you.x_pos][you.y_pos] = altar;
- }
- break;
+ case CARD_XOM: xom_acts(5 + random2(power/10)); break;
case CARD_FAMINE:
- mpr("You have drawn Famine.");
-
if (you.is_undead == US_UNDEAD)
mpr("You feel rather smug.");
else
@@ -993,66 +935,13 @@ void card_effect(card_type which_card)
break;
case CARD_FEAST:
- mpr("You have drawn the Feast.");
-
if (you.is_undead == US_UNDEAD)
mpr("You feel a horrible emptiness.");
else
set_hunger(12000, true);
break;
- case CARD_WILD_MAGIC:
- mpr( "You have drawn Wild Magic." );
- miscast_effect( SPTYP_RANDOM, random2(15) + 5, random2(250), 0 );
- break;
-
- case CARD_VIOLENCE:
- mpr("You have drawn Violence.");
- acquirement( OBJ_WEAPONS, AQ_CARD_VIOLENCE );
- break;
-
- case CARD_PROTECTION:
- mpr("You have drawn Protection.");
- acquirement( OBJ_ARMOUR, AQ_CARD_PROTECTION );
- break;
-
- case CARD_KNOWLEDGE:
- mpr("You have drawn Knowledge.");
- acquirement( OBJ_BOOKS, AQ_CARD_KNOWLEDGE );
- break;
-
- case CARD_MAZE:
- mpr("You have drawn the Maze!");
- more();
-
- if (you.level_type == LEVEL_DUNGEON)
- banished( DNGN_ENTER_LABYRINTH );
- break;
-
- case CARD_PANDEMONIUM:
- mpr("You have drawn the Pandemonium card!");
- more();
-
- if (you.level_type == LEVEL_PANDEMONIUM)
- banished(DNGN_EXIT_PANDEMONIUM);
- else if (you.level_type == LEVEL_LABYRINTH)
- canned_msg(MSG_NOTHING_HAPPENS);
- else
- banished(DNGN_ENTER_PANDEMONIUM);
- break;
-
- case CARD_RULES_FOR_BRIDGE:
- mpr("You have drawn the rules for contract bridge.");
- mpr("How intriguing!");
- break;
-
- case CARD_IMPRISONMENT:
- mpr("You have drawn the Prison!");
- entomb();
- break;
-
case NUM_CARDS:
- case CARD_RANDOM:
mpr("You have drawn a buggy card!");
break;
}
diff --git a/crawl-ref/source/decks.h b/crawl-ref/source/decks.h
index 735be7218d..4e980b15ad 100644
--- a/crawl-ref/source/decks.h
+++ b/crawl-ref/source/decks.h
@@ -19,11 +19,10 @@
const char* card_name(card_type card);
void evoke_deck(item_def& deck);
-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();
-void card_effect(card_type which_card);
+void card_effect(card_type which_card, deck_rarity_type rarity);
+void draw_from_deck_of_punishment();
#endif
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index 4eb3b343ea..882e19c74c 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -2889,9 +2889,11 @@ static std::string describe_misc_item( const item_def &item )
description.reserve(100);
+ const misc_item_type subtype = static_cast<misc_item_type>(item.sub_type);
+
if (item_type_known(item))
{
- switch (item.sub_type)
+ switch (subtype)
{
case MISC_BOTTLED_EFREET:
description +=
@@ -2943,17 +2945,60 @@ static std::string describe_misc_item( const item_def &item )
"A magical box containing many wild beasts. One may "
"allow them to escape by opening the box's lid. ";
break;
- case MISC_DECK_OF_WONDERS:
+ case MISC_DECK_OF_ESCAPE:
+ description +=
+ "A deck of magical cards, mainly dealing with various "
+ "forms of escape. Incautious use may lead to being "
+ "dumped from the frying pan into the fire! ";
+ break;
+ case MISC_DECK_OF_DESTRUCTION:
description +=
- "A deck of highly mysterious and magical cards. One may "
- "draw a random card from it, but should be prepared to "
- "suffer the possible consequences! ";
+ "A deck of magical cards, most of which hurl death "
+ "and destruction at one's foes (or, if unlucky, at oneself.) ";
break;
- case MISC_DECK_OF_SUMMONINGS:
+ case MISC_DECK_OF_DUNGEONS:
+ description +=
+ "A deck of magical cards which deal with shaping the "
+ "dungeon. Unlike most other decks, the cards from this deck "
+ "tend to be ignored by Nemelex, who prefers more amusing "
+ "pursuits. ";
+ break;
+ case MISC_DECK_OF_SUMMONING:
description +=
"A deck of magical cards, depicting a range of weird and "
"wondrous creatures. ";
break;
+
+ case MISC_DECK_OF_WONDERS:
+ description +=
+ "A deck of highly mysterious and magical cards, which can "
+ "permanently alter the drawer's physical and mental "
+ "condition, for better or worse. ";
+ break;
+
+ case MISC_DECK_OF_PUNISHMENT:
+ description +=
+ "A deck of magical cards which wreak havoc on the user. ";
+ break;
+
+ case MISC_DECK_OF_WAR:
+ description +=
+ "A deck of magical cards which are useful before and during "
+ "battle. ";
+ break;
+
+ case MISC_DECK_OF_CHANGES:
+ description +=
+ "A deck of magical cards which induce changes in the user "
+ "or his environment. ";
+ break;
+
+ case MISC_DECK_OF_DEFENSE:
+ description +=
+ "A deck of magical cards, most of which defend the user "
+ "from harm in various ways. ";
+ break;
+
case MISC_CRYSTAL_BALL_OF_ENERGY:
description +=
"A magical device which can be used to restore one's "
@@ -2979,24 +3024,20 @@ static std::string describe_misc_item( const item_def &item )
"hands of one skilled in air elemental magic, but cannot "
"be used by one who is not a conductor. ";
break;
+
case MISC_RUNE_OF_ZOT:
description +=
"A talisman which allows entry into Zot's domain. ";
break;
- case MISC_DECK_OF_TRICKS:
- description +=
- "A deck of magical cards, full of amusing tricks. ";
- break;
- case MISC_DECK_OF_POWER:
- description += "A deck of powerful magical cards. ";
+
+ case NUM_MISCELLANY:
+ description += "A buggy miscellaneous item.";
break;
- default:
- DEBUGSTR("Unknown misc item (2)");
}
}
else
{
- switch (item.sub_type)
+ switch (subtype)
{
case MISC_BOTTLED_EFREET:
description += "A heavy bronze flask, warm to the touch. ";
@@ -3025,10 +3066,16 @@ static std::string describe_misc_item( const item_def &item )
case MISC_EMPTY_EBONY_CASKET:
description += "A small black box. I wonder what's inside? ";
break;
+
+ case MISC_DECK_OF_ESCAPE:
+ case MISC_DECK_OF_DESTRUCTION:
+ case MISC_DECK_OF_DUNGEONS:
+ case MISC_DECK_OF_SUMMONING:
case MISC_DECK_OF_WONDERS:
- case MISC_DECK_OF_TRICKS:
- case MISC_DECK_OF_POWER:
- case MISC_DECK_OF_SUMMONINGS:
+ case MISC_DECK_OF_PUNISHMENT:
+ case MISC_DECK_OF_WAR:
+ case MISC_DECK_OF_CHANGES:
+ case MISC_DECK_OF_DEFENSE:
description += "A deck of cards. ";
break;
case MISC_RUNE_OF_ZOT:
@@ -3037,8 +3084,9 @@ static std::string describe_misc_item( const item_def &item )
case MISC_DISC_OF_STORMS:
description += "A grey disc. ";
break;
- default:
- DEBUGSTR("Unknown misc item");
+ case NUM_MISCELLANY:
+ description += "A buggy miscellaneous item. ";
+ break;
}
}
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc
index c3fdf3aa29..a37f635f4d 100644
--- a/crawl-ref/source/effects.cc
+++ b/crawl-ref/source/effects.cc
@@ -193,8 +193,8 @@ bool forget_spell(void)
bool lose_stat(unsigned char which_stat, unsigned char stat_loss, bool force)
{
bool statLowered = false; // must initialize to false {dlb}
- char *ptr_stat = 0; // NULL {dlb}
- char *ptr_redraw = 0; // NULL {dlb}
+ char *ptr_stat = NULL;
+ bool *ptr_redraw = NULL;
char newValue = 0; // holds new value, for comparison to old {dlb}
// begin outputing message: {dlb}
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 7f786bf09b..b55baccbca 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -450,21 +450,21 @@ enum branch_type // you.where_are_you
enum builder_rc_type
{
- BUILD_QUIT = -1, // all done, don't continue
- BUILD_SKIP = 1, // skip further generation
- BUILD_CONTINUE = 0 // continue generation
+ BUILD_QUIT = -1, // all done, don't continue
+ BUILD_SKIP = 1, // skip further generation
+ BUILD_CONTINUE = 0 // continue generation
};
-enum burden_state_type // you.burden_state
+enum burden_state_type // you.burden_state
{
- BS_UNENCUMBERED, // 0
- BS_ENCUMBERED = 2, // 2
- BS_OVERLOADED = 5 // 5
+ BS_UNENCUMBERED, // 0
+ BS_ENCUMBERED = 2, // 2
+ BS_OVERLOADED = 5 // 5
};
-enum canned_message_type // canned_msg() - unsigned char
+enum canned_message_type
{
- MSG_SOMETHING_APPEARS, // 0
+ MSG_SOMETHING_APPEARS,
MSG_NOTHING_HAPPENS,
MSG_YOU_RESIST,
MSG_TOO_BERSERK,
@@ -479,63 +479,59 @@ enum canned_message_type // canned_msg() - unsigned char
enum card_type
{
- CARD_BLANK = 0, // 0
- CARD_BUTTERFLY,
- CARD_WRAITH,
- CARD_EXPERIENCE,
- CARD_WEALTH,
- CARD_INTELLIGENCE, // 5
- CARD_STRENGTH,
- CARD_QUICKSILVER,
- CARD_STUPIDITY,
- CARD_WEAKNESS,
- CARD_SLOTH, // 10
+ CARD_BLANK = 0,
+ CARD_PORTAL, // "the mover"
+ CARD_WARP, // "the jumper"
+ CARD_SWAP, // "swap"
+ CARD_VELOCITY, // "the runner"
+
+ CARD_TOMB, // "the wall"
+ CARD_BANSHEE, // "the scream"
+ CARD_DAMNATION, // banishment
+ CARD_SOLITUDE, // dispersal
+ CARD_WARPWRIGHT, // create teleport trap
+
+ CARD_VITRIOL, // acid damage
+ CARD_FLAME, // fire damage
+ CARD_FROST, // cold damage
+ CARD_HAMMER, // pure damage
+
+ CARD_ELIXIR, // healing
+ CARD_BATTLELUST, // melee boosts
+ CARD_METAMORPHOSIS, // transformation
+ CARD_HELM, // defense
+ CARD_BLADE, // weapon boosts
+ CARD_SHADOW, // assassin skills
+
+ CARD_SUMMON_ANIMAL,
+ CARD_SUMMON_DEMON,
+ CARD_SUMMON_WEAPON,
+ CARD_SUMMON_ANY,
+
+ CARD_POTION,
+ CARD_FOCUS,
CARD_SHUFFLE,
- CARD_FREAK,
- CARD_DEATH,
- CARD_NORMALITY,
- CARD_SHADOW, // 15
- CARD_GATE,
- CARD_STATUE,
- CARD_ACQUISITION,
- CARD_HASTEN,
- CARD_DEMON_LESSER, // 20
- CARD_DEMON_COMMON,
- CARD_DEMON_GREATER,
- CARD_DEMON_SWARM,
- CARD_YAK,
- CARD_FIEND, // 25
- CARD_DRAGON,
- CARD_GOLEM,
- CARD_THING_FUGLY,
- CARD_LICH,
- CARD_HORROR_UNSEEN, // 30
- CARD_BLINK,
- CARD_TELEPORT,
- CARD_TELEPORT_NOW,
- CARD_RAGE,
- CARD_LEVITY, // 35
- CARD_VENOM,
+
+ CARD_EXPERIENCE,
+ CARD_WILD_MAGIC,
+ CARD_GENETIC_ENGINEER, // remove one *bad* mutation
+
+ CARD_MAP, // magic mapping
+ CARD_DOWSING, // detect SD/traps/items/monsters
+ CARD_SPADE, // dig
+ CARD_TROWEL, // create feature/vault
+ CARD_MINEFIELD, // plant traps
+
+ CARD_GENIE, // acquirement OR rotting/deterioration
+ CARD_BARGAIN, // shopping discount
+ CARD_WRATH, // Godly wrath
+ CARD_WRAITH, // drain XP
CARD_XOM,
- CARD_SLOW,
- CARD_DECAY,
- CARD_HEALING, // 40
- CARD_HEAL_WOUNDS,
- CARD_TORMENT,
- CARD_FOUNTAIN,
- CARD_ALTAR,
- CARD_FAMINE, // 45
CARD_FEAST,
- CARD_WILD_MAGIC,
- CARD_VIOLENCE,
- CARD_PROTECTION,
- CARD_KNOWLEDGE, // 50
- CARD_MAZE,
- CARD_PANDEMONIUM,
- CARD_IMPRISONMENT,
- CARD_RULES_FOR_BRIDGE, // 54
- NUM_CARDS, // must remain last regular member {dlb}
- CARD_RANDOM = 255 // must remain final member {dlb}
+ CARD_FAMINE,
+ CARD_CURSE, // Curse your items
+
+ NUM_CARDS
};
enum char_set_type
@@ -842,13 +838,21 @@ enum startup_book_type
SBT_RANDOM
};
+enum deck_rarity_type
+{
+ DECK_RARITY_COMMON,
+ DECK_RARITY_RARE,
+ DECK_RARITY_LEGENDARY
+};
+
enum deck_type
{
- DECK_OF_WONDERS, // 0
+ // pure decks
+ DECK_OF_ESCAPE,
+ DECK_OF_DESTRUCTION,
+ DECK_OF_DUNGEONS,
DECK_OF_SUMMONING,
- DECK_OF_TRICKS,
- DECK_OF_POWER,
- DECK_OF_PUNISHMENT
+ DECK_OF_WONDERS
};
// When adding new delays, update their names in delay.cc, or bad things will
@@ -1805,18 +1809,29 @@ enum misc_item_type
MISC_AIR_ELEMENTAL_FAN,
MISC_LAMP_OF_FIRE,
MISC_STONE_OF_EARTH_ELEMENTALS,
- MISC_LANTERN_OF_SHADOWS, // 5
+ MISC_LANTERN_OF_SHADOWS,
MISC_HORN_OF_GERYON,
MISC_BOX_OF_BEASTS,
- MISC_DECK_OF_WONDERS,
- MISC_DECK_OF_SUMMONINGS,
- MISC_CRYSTAL_BALL_OF_ENERGY, // 10
+ MISC_CRYSTAL_BALL_OF_ENERGY,
MISC_EMPTY_EBONY_CASKET,
MISC_CRYSTAL_BALL_OF_FIXATION,
MISC_DISC_OF_STORMS,
+
+ // pure decks
+ MISC_DECK_OF_ESCAPE,
+ MISC_DECK_OF_DESTRUCTION,
+ MISC_DECK_OF_DUNGEONS,
+ MISC_DECK_OF_SUMMONING,
+ MISC_DECK_OF_WONDERS,
+ MISC_DECK_OF_PUNISHMENT,
+
+ // mixed decks
+ MISC_DECK_OF_WAR,
+ MISC_DECK_OF_CHANGES,
+ MISC_DECK_OF_DEFENSE,
+
MISC_RUNE_OF_ZOT,
- MISC_DECK_OF_TRICKS, // 15
- MISC_DECK_OF_POWER,
+
NUM_MISCELLANY // mv: used for random generation
};
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index 18c85f65df..59436307f6 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -629,16 +629,16 @@ public:
int symbol;
int colour;
- char redraw_hit_points;
- char redraw_magic_points;
- char redraw_strength;
- char redraw_intelligence;
- char redraw_dexterity;
- char redraw_experience;
- char redraw_armour_class;
-
- char redraw_gold;
- char redraw_evasion;
+ bool redraw_hit_points;
+ bool redraw_magic_points;
+ bool redraw_strength;
+ bool redraw_intelligence;
+ bool redraw_dexterity;
+ bool redraw_experience;
+ bool redraw_armour_class;
+
+ bool redraw_gold;
+ bool redraw_evasion;
unsigned char flash_colour;
diff --git a/crawl-ref/source/it_use2.cc b/crawl-ref/source/it_use2.cc
index 9f9004a568..01ccda0cd8 100644
--- a/crawl-ref/source/it_use2.cc
+++ b/crawl-ref/source/it_use2.cc
@@ -41,7 +41,7 @@
#include "view.h"
// From an actual potion, pow == 40 -- bwr
-bool potion_effect( char pot_eff, int pow )
+bool potion_effect( potion_type pot_eff, int pow )
{
bool effect = true; // current behaviour is all potions id on quaffing
@@ -278,6 +278,10 @@ bool potion_effect( char pot_eff, int pow )
did_god_conduct(DID_STIMULANTS, 4 + random2(4));
break;
+
+ case NUM_POTIONS:
+ mpr("You feel bugginess flow through your body.");
+ break;
}
return (effect);
diff --git a/crawl-ref/source/it_use2.h b/crawl-ref/source/it_use2.h
index 8351086bea..06e2a20942 100644
--- a/crawl-ref/source/it_use2.h
+++ b/crawl-ref/source/it_use2.h
@@ -20,7 +20,7 @@
* called from: ability - beam - decks - item_use - misc - religion -
* spell - spells - spells1
* *********************************************************************** */
-bool potion_effect(char pot_eff, int pow);
+bool potion_effect(potion_type pot_eff, int pow);
/* ***********************************************************************
diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc
index 300e12a55e..e361ed000d 100644
--- a/crawl-ref/source/it_use3.cc
+++ b/crawl-ref/source/it_use3.cc
@@ -509,6 +509,14 @@ bool evoke_wielded( void )
case OBJ_MISCELLANY:
did_work = true; // easier to do it this way for misc items
+
+ if ( is_deck(wpn) )
+ {
+ evoke_deck(wpn);
+ pract = 1;
+ break;
+ }
+
switch (wpn.sub_type)
{
case MISC_BOTTLED_EFREET:
@@ -624,14 +632,6 @@ bool evoke_wielded( void )
}
break;
- case MISC_DECK_OF_WONDERS:
- case MISC_DECK_OF_SUMMONINGS:
- case MISC_DECK_OF_TRICKS:
- case MISC_DECK_OF_POWER:
- evoke_deck(wpn);
- pract = 1;
- break;
-
case MISC_BOX_OF_BEASTS:
if (box_of_beasts())
pract = 1;
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index ea48262cd1..c89044ce54 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -2757,7 +2757,8 @@ void drink(void)
const bool dangerous =
player_in_a_dangerous_place() && (you.experience_level > 1);
- if (potion_effect( you.inv[item_slot].sub_type, 40 ))
+ if (potion_effect(static_cast<potion_type>(you.inv[item_slot].sub_type),
+ 40))
{
set_ident_flags( you.inv[item_slot], ISFLAG_IDENT_MASK );
@@ -2786,7 +2787,7 @@ bool drink_fountain(void)
{
bool gone_dry = false;
int temp_rand; // for probability determinations {dlb}
- int fountain_effect = POT_WATER; // for fountain effects {dlb}
+ potion_type fountain_effect = POT_WATER; // for fountain effects {dlb}
switch (grd[you.x_pos][you.y_pos])
{
diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc
index 44b7095f7c..69dc3ae52b 100644
--- a/crawl-ref/source/itemname.cc
+++ b/crawl-ref/source/itemname.cc
@@ -677,16 +677,33 @@ static const char* rune_type_name(int p)
}
}
+static const char* deck_rarity_name(deck_rarity_type rarity)
+{
+ switch (rarity)
+ {
+ case DECK_RARITY_COMMON: return "common";
+ case DECK_RARITY_RARE: return "rare";
+ case DECK_RARITY_LEGENDARY: return "legendary";
+ }
+ return "buggy rarity";
+}
+
static const char* misc_type_name(int type, bool known)
{
if (known)
{
switch ( static_cast<misc_item_type>(type) )
{
- case MISC_DECK_OF_POWER: return "deck of power";
- case MISC_DECK_OF_SUMMONINGS: return "deck of summonings";
- case MISC_DECK_OF_TRICKS: return "deck of tricks";
+ case MISC_DECK_OF_ESCAPE: return "deck of escape";
+ case MISC_DECK_OF_DESTRUCTION: return "deck of destruction";
+ case MISC_DECK_OF_DUNGEONS: return "deck of dungeons";
+ case MISC_DECK_OF_SUMMONING: return "deck of summonings";
case MISC_DECK_OF_WONDERS: return "deck of wonders";
+ case MISC_DECK_OF_PUNISHMENT: return "deck of punishment";
+ case MISC_DECK_OF_WAR: return "deck of war";
+ case MISC_DECK_OF_CHANGES: return "deck of changes";
+ case MISC_DECK_OF_DEFENSE: return "deck of defense";
+
case MISC_CRYSTAL_BALL_OF_ENERGY: return "crystal ball of energy";
case MISC_CRYSTAL_BALL_OF_FIXATION: return "crystal ball of fixation";
case MISC_CRYSTAL_BALL_OF_SEEING: return "crystal ball of seeing";
@@ -710,10 +727,15 @@ static const char* misc_type_name(int type, bool known)
{
switch ( static_cast<misc_item_type>(type) )
{
- case MISC_DECK_OF_POWER:
- case MISC_DECK_OF_SUMMONINGS:
- case MISC_DECK_OF_TRICKS:
+ case MISC_DECK_OF_ESCAPE:
+ case MISC_DECK_OF_DESTRUCTION:
+ case MISC_DECK_OF_DUNGEONS:
+ case MISC_DECK_OF_SUMMONING:
case MISC_DECK_OF_WONDERS:
+ case MISC_DECK_OF_PUNISHMENT:
+ case MISC_DECK_OF_WAR:
+ case MISC_DECK_OF_CHANGES:
+ case MISC_DECK_OF_DEFENSE:
return "deck of cards";
case MISC_CRYSTAL_BALL_OF_ENERGY:
case MISC_CRYSTAL_BALL_OF_FIXATION:
@@ -1314,6 +1336,10 @@ std::string item_def::name_aux( description_level_type desc,
}
else
{
+ if ( is_deck(*this) )
+ {
+ buff << deck_rarity_name(deck_rarity(*this)) << ' ';
+ }
buff << misc_type_name(item_typ, know_type);
if ( is_deck(*this) && item_plus2 != 0 )
{
diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc
index 593fcf8e37..20724ebca9 100644
--- a/crawl-ref/source/itemprop.cc
+++ b/crawl-ref/source/itemprop.cc
@@ -2137,10 +2137,23 @@ bool is_shield_incompatible(const item_def &weapon, const item_def *shield)
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);
+ && (item.sub_type >= MISC_DECK_OF_ESCAPE &&
+ item.sub_type <= MISC_DECK_OF_DEFENSE);
+}
+
+deck_rarity_type deck_rarity(const item_def &item)
+{
+ ASSERT( is_deck(item) );
+ switch (item.colour)
+ {
+ case BLACK: case BLUE: case GREEN: case CYAN: case RED:
+ default:
+ return DECK_RARITY_COMMON;
+ case MAGENTA: case BROWN:
+ return DECK_RARITY_RARE;
+ case LIGHTMAGENTA:
+ return DECK_RARITY_LEGENDARY;
+ }
}
std::string item_base_name(const item_def &item)
diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h
index 5c6ab77bd8..48f3c53796 100644
--- a/crawl-ref/source/itemprop.h
+++ b/crawl-ref/source/itemprop.h
@@ -150,6 +150,7 @@ bool is_shield_incompatible(const item_def &weapon,
const item_def *shield = NULL);
bool is_deck(const item_def &item);
+deck_rarity_type deck_rarity(const item_def &item);
// Only works for armour/weapons/missiles
std::string item_base_name(const item_def &item);
diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc
index 6bd00913e7..81bdcd6b86 100644
--- a/crawl-ref/source/makeitem.cc
+++ b/crawl-ref/source/makeitem.cc
@@ -714,6 +714,16 @@ void item_colour( item_def &item )
break;
case OBJ_MISCELLANY:
+ if ( is_deck(item) )
+ {
+ item.colour = GREEN;
+ if ( one_chance_in(10) )
+ item.colour = LIGHTMAGENTA; // legendary
+ if ( one_chance_in(5) )
+ item.colour = (coinflip() ? MAGENTA : BROWN);
+ break;
+ }
+
switch (item.sub_type)
{
case MISC_BOTTLED_EFREET:
@@ -808,11 +818,7 @@ void item_colour( item_def &item )
case MISC_EMPTY_EBONY_CASKET:
item.colour = DARKGREY;
break;
-
- case MISC_DECK_OF_SUMMONINGS:
- case MISC_DECK_OF_WONDERS:
- case MISC_DECK_OF_TRICKS:
- case MISC_DECK_OF_POWER:
+
default:
item.colour = random_colour();
break;
@@ -2748,18 +2754,21 @@ int items( int allow_uniques, // not just true-false,
if (force_type == OBJ_RANDOM)
{
do
+ {
mitm[p].sub_type = random2(NUM_MISCELLANY);
- while //mv: never generated
+ }
+ while
+ //mv: never generated
((mitm[p].sub_type == MISC_RUNE_OF_ZOT)
|| (mitm[p].sub_type == MISC_HORN_OF_GERYON)
- // mv: others are possible but less often
- // btw. chances of generating decks are almost the same as
- // before, other chances are now distributed more steadily
- || (mitm[p].sub_type == MISC_DECK_OF_POWER && !one_chance_in(12))
- || (mitm[p].sub_type == MISC_DECK_OF_SUMMONINGS && !one_chance_in(3))
- || (mitm[p].sub_type == MISC_DECK_OF_TRICKS && !one_chance_in(3))
- || (mitm[p].sub_type == MISC_DECK_OF_WONDERS && !one_chance_in(3))
- );
+ || (mitm[p].sub_type == MISC_DECK_OF_PUNISHMENT)
+ // pure decks are rare in the dungeon
+ || ((mitm[p].sub_type == MISC_DECK_OF_ESCAPE ||
+ mitm[p].sub_type == MISC_DECK_OF_DESTRUCTION ||
+ mitm[p].sub_type == MISC_DECK_OF_DUNGEONS ||
+ mitm[p].sub_type == MISC_DECK_OF_SUMMONING ||
+ mitm[p].sub_type == MISC_DECK_OF_WONDERS) &&
+ !one_chance_in(5)));
// filling those silly empty boxes -- bwr
if (mitm[p].sub_type == MISC_EMPTY_EBONY_CASKET
@@ -2773,15 +2782,8 @@ int items( int allow_uniques, // not just true-false,
mitm[p].sub_type = force_type;
}
- if (mitm[p].sub_type == MISC_DECK_OF_WONDERS
- || mitm[p].sub_type == MISC_DECK_OF_SUMMONINGS
- || mitm[p].sub_type == MISC_DECK_OF_POWER)
- {
+ if ( is_deck(mitm[p]) )
mitm[p].plus = 4 + random2(10);
- }
-
- if (mitm[p].sub_type == MISC_DECK_OF_TRICKS)
- mitm[p].plus = 6 + random2avg(15, 2);
if (mitm[p].sub_type == MISC_RUNE_OF_ZOT)
mitm[p].plus = item_race;
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index a41cd41521..91d3062472 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -3738,7 +3738,7 @@ void modify_stat(unsigned char which_stat, char amount, bool suppress_msg)
{
char *ptr_stat = NULL;
char *ptr_stat_max = NULL;
- char *ptr_redraw = NULL;
+ bool *ptr_redraw = NULL;
// sanity - is non-zero amount?
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index dd271451c3..c453640fec 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -452,18 +452,32 @@ static void do_god_gift()
&& !you.attribute[ATTR_CARD_COUNTDOWN]
&& !grid_destroys_items(grd[you.x_pos][you.y_pos]))
{
- int thing_created = NON_ITEM;
- int gift_type = MISC_DECK_OF_TRICKS;
-
- if (random2(200) <= you.piety && one_chance_in(4))
- gift_type = MISC_DECK_OF_SUMMONINGS;
- if (random2(200) <= you.piety && coinflip())
- gift_type = MISC_DECK_OF_WONDERS;
- if (random2(200) <= you.piety && one_chance_in(4))
- gift_type = MISC_DECK_OF_POWER;
-
- thing_created = items( 1, OBJ_MISCELLANY, gift_type,
- true, 1, MAKE_ITEM_RANDOM_RACE );
+ misc_item_type gift_type;
+ if ( random2(200) <= you.piety )
+ {
+ // make a pure deck
+ misc_item_type pure_decks[] = {
+ MISC_DECK_OF_ESCAPE,
+ MISC_DECK_OF_DESTRUCTION,
+ MISC_DECK_OF_DUNGEONS,
+ MISC_DECK_OF_SUMMONING,
+ MISC_DECK_OF_WONDERS
+ };
+ gift_type = pure_decks[random2(ARRAYSIZE(pure_decks))];
+ }
+ else
+ {
+ // make a mixed deck
+ misc_item_type mixed_decks[] = {
+ MISC_DECK_OF_WAR,
+ MISC_DECK_OF_CHANGES,
+ MISC_DECK_OF_DEFENSE
+ };
+ gift_type = mixed_decks[random2(ARRAYSIZE(mixed_decks))];
+ }
+
+ int thing_created = items( 1, OBJ_MISCELLANY, gift_type,
+ true, 1, MAKE_ITEM_RANDOM_RACE );
if (thing_created != NON_ITEM)
{
@@ -2047,7 +2061,7 @@ void divine_retribution( god_type god )
// like Xom, this might actually help the player -- bwr
simple_god_message(" makes you draw from the Deck of Punishment.",
god);
- deck_of_cards(DECK_OF_PUNISHMENT);
+ draw_from_deck_of_punishment();
break;
case GOD_SIF_MUNA:
diff --git a/crawl-ref/source/shopping.cc b/crawl-ref/source/shopping.cc
index c29375dd58..e7b2765ee7 100644
--- a/crawl-ref/source/shopping.cc
+++ b/crawl-ref/source/shopping.cc
@@ -1451,9 +1451,6 @@ unsigned int item_value( item_def item, bool ident )
case MISC_BOTTLED_EFREET:
valued += 350;
break;
- case MISC_DECK_OF_TRICKS:
- valued += 100;
- break;
default:
valued += 400;
}
diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc
index 6708c9b42b..8bd05d4bc1 100644
--- a/crawl-ref/source/spells2.cc
+++ b/crawl-ref/source/spells2.cc
@@ -657,9 +657,9 @@ bool restore_stat(unsigned char which_stat, bool suppress_msg)
}
// the real function begins here {dlb}:
- char *ptr_stat = 0; // NULL {dlb}
- char *ptr_stat_max = 0; // NULL {dlb}
- char *ptr_redraw = 0; // NULL {dlb}
+ char *ptr_stat = NULL;
+ char *ptr_stat_max = NULL;
+ bool *ptr_redraw = NULL;
std::string msg = "You feel your ";