From b49316f91a8dfd8386ae41a4cf2b9e1814fb9166 Mon Sep 17 00:00:00 2001 From: haranp Date: Thu, 3 Apr 2008 14:40:19 +0000 Subject: Nemelex changes: - Renamed abilities, and reordered so that you get Draw One before Peek Two - Mark Four and Peek Two now lose some cards from the deck - Viewing a deck now shows which cards have been marked in it Also fixed a small warning in format.cc. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@4059 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/abl-show.cc | 40 ++++++------ crawl-ref/source/decks.cc | 148 +++++++++++++++++-------------------------- crawl-ref/source/describe.cc | 26 ++++++++ crawl-ref/source/enum.h | 8 +-- crawl-ref/source/format.cc | 2 +- 5 files changed, 110 insertions(+), 114 deletions(-) diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc index c2d1e5d6f9..02ec9b1103 100644 --- a/crawl-ref/source/abl-show.cc +++ b/crawl-ref/source/abl-show.cc @@ -146,9 +146,9 @@ ability_type god_abilities[MAX_NUM_GODS][MAX_GOD_ABILITIES] = { ABIL_TROG_BERSERK, ABIL_TROG_REGENERATION, ABIL_NON_ABILITY, ABIL_TROG_BROTHERS_IN_ARMS, ABIL_NON_ABILITY }, // Nemelex - { ABIL_NEMELEX_PEEK_DECK, ABIL_NEMELEX_DRAW_CARD, - ABIL_NEMELEX_TRIPLE_DRAW, ABIL_NEMELEX_MARK_DECK, - ABIL_NEMELEX_STACK_DECK }, + { ABIL_NEMELEX_DRAW_ONE, ABIL_NEMELEX_PEEK_TWO, + ABIL_NEMELEX_TRIPLE_DRAW, ABIL_NEMELEX_MARK_FOUR, + ABIL_NEMELEX_STACK_FIVE }, // Elyvilon { ABIL_ELYVILON_LESSER_HEALING, ABIL_ELYVILON_PURIFICATION, ABIL_ELYVILON_HEALING, ABIL_ELYVILON_RESTORATION, @@ -297,11 +297,11 @@ static const ability_def Ability_List[] = 9, 0, 500, generic_cost::fixed(35), ABFLAG_NONE }, // Nemelex - { ABIL_NEMELEX_PEEK_DECK, "Deck Peek", 3, 0, 0, 1, ABFLAG_INSTANT }, - { ABIL_NEMELEX_DRAW_CARD, "Draw Card", 2, 0, 0, 0, ABFLAG_NONE }, + { ABIL_NEMELEX_DRAW_ONE, "Draw One", 2, 0, 0, 0, ABFLAG_NONE }, + { ABIL_NEMELEX_PEEK_TWO, "Peek at Two", 3, 0, 0, 1, ABFLAG_INSTANT }, { ABIL_NEMELEX_TRIPLE_DRAW, "Triple Draw", 2, 0, 100, 2, ABFLAG_NONE }, - { ABIL_NEMELEX_MARK_DECK, "Mark Deck", 4, 0, 125, 5, ABFLAG_NONE }, - { ABIL_NEMELEX_STACK_DECK, "Stack Deck", 5, 0, 250, 10, ABFLAG_NONE }, + { ABIL_NEMELEX_MARK_FOUR, "Mark Four", 4, 0, 125, 5, ABFLAG_NONE }, + { ABIL_NEMELEX_STACK_FIVE, "Stack Five", 5, 0, 250, 10, ABFLAG_NONE }, // Beogh { ABIL_BEOGH_SMITING, "Smiting", @@ -724,12 +724,12 @@ static talent _get_talent(ability_type ability, bool check_confused) failure = 80 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4); break; - case ABIL_NEMELEX_STACK_DECK: + case ABIL_NEMELEX_STACK_FIVE: invoc = true; failure = 80 - (you.piety / 25) - (4 * you.skills[SK_EVOCATIONS]); break; - case ABIL_NEMELEX_MARK_DECK: + case ABIL_NEMELEX_MARK_FOUR: invoc = true; failure = 70 - (you.piety * 2 / 45) - (9 * you.skills[SK_EVOCATIONS] / 2); @@ -740,12 +740,12 @@ static talent _get_talent(ability_type ability, bool check_confused) failure = 60 - (you.piety / 20) - (5 * you.skills[SK_EVOCATIONS]); break; - case ABIL_NEMELEX_PEEK_DECK: + case ABIL_NEMELEX_PEEK_TWO: invoc = true; failure = 40 - (you.piety / 20) - (5 * you.skills[SK_EVOCATIONS]); break; - case ABIL_NEMELEX_DRAW_CARD: + case ABIL_NEMELEX_DRAW_ONE: invoc = true; perfect = true; // Tactically important to allow perfection failure = 50 - (you.piety / 20) - (5 * you.skills[SK_EVOCATIONS]); @@ -1721,31 +1721,31 @@ static bool _do_ability(const ability_def& abil) activate_notes(true); break; - case ABIL_NEMELEX_DRAW_CARD: + case ABIL_NEMELEX_DRAW_ONE: if ( !choose_deck_and_draw() ) return false; exercise(SK_EVOCATIONS, 1 + random2(2)); break; - case ABIL_NEMELEX_TRIPLE_DRAW: - if ( !deck_triple_draw() ) + case ABIL_NEMELEX_PEEK_TWO: + if ( !deck_peek() ) return false; - exercise(SK_EVOCATIONS, 3 + random2(3)); + exercise(SK_EVOCATIONS, 2 + random2(2)); break; - case ABIL_NEMELEX_PEEK_DECK: - if ( !deck_peek() ) + case ABIL_NEMELEX_TRIPLE_DRAW: + if ( !deck_triple_draw() ) return false; - exercise(SK_EVOCATIONS, 2 + random2(2)); + exercise(SK_EVOCATIONS, 3 + random2(3)); break; - case ABIL_NEMELEX_MARK_DECK: + case ABIL_NEMELEX_MARK_FOUR: if ( !deck_mark() ) return false; exercise(SK_EVOCATIONS, 4 + random2(4)); break; - case ABIL_NEMELEX_STACK_DECK: + case ABIL_NEMELEX_STACK_FIVE: if ( !deck_stack() ) return false; exercise(SK_EVOCATIONS, 5 + random2(5)); diff --git a/crawl-ref/source/decks.cc b/crawl-ref/source/decks.cc index 3f0a241148..b4d095be0b 100644 --- a/crawl-ref/source/decks.cc +++ b/crawl-ref/source/decks.cc @@ -729,52 +729,64 @@ bool choose_deck_and_draw() return true; } -static void _deck_peek_ident(item_def& deck) +static void _deck_ident(item_def& deck) { if (in_inventory(deck) && !item_ident(deck, ISFLAG_KNOW_TYPE)) { set_ident_flags(deck, ISFLAG_KNOW_TYPE); - mprf("This is %s.", deck.name(DESC_NOCAP_A).c_str()); - you.wield_change = true; } } -// Peek at a deck (show what the next card will be.) +// This also shuffles the deck. +static void _deck_lose_card(item_def& deck) +{ + unsigned char flags = 0; + // Seen cards are only half as likely to fall out, + // marked cards only one-quarter as likely (note that marked + // cards are also seen.) + do { + _shuffle_deck(deck); + get_card_and_flags(deck, -1, flags); + } while ( ((flags & CFLAG_MARKED) && coinflip()) || + ((flags & CFLAG_SEEN) && coinflip()) ); + + _draw_top_card(deck, false, flags); + deck.plus2++; +} + +// Peek at two cards in a deck, then shuffle them back in. // Return false if the operation was failed/aborted along the way. bool deck_peek() { - if ( !_wielding_deck() ) + const int slot = _choose_inventory_deck( "Peek at which deck?" ); + if ( slot == -1 ) { - mpr("You aren't wielding a deck!"); crawl_state.zero_turns_taken(); return false; } - item_def& deck(you.inv[you.equip[EQ_WEAPON]]); + item_def& deck(you.inv[slot]); if (_check_buggy_deck(deck)) return false; - if (deck.props["num_marked"].get_byte() > 0) + if ( cards_in_deck(deck) > 2 ) { - mpr("You can't peek into a marked deck."); - crawl_state.zero_turns_taken(); - return false; + _deck_lose_card(deck); + mpr("A card falls out of the deck."); } CrawlVector &cards = deck.props["cards"]; - int num_cards = cards.size(); + const int num_cards = cards.size(); - card_type card1, card2, card3; - unsigned char flags1, flags2, flags3; + card_type card1, card2; + unsigned char flags1, flags2; card1 = get_card_and_flags(deck, 0, flags1); if (num_cards == 1) { - _deck_peek_ident(deck); - mpr("There's only one card in the deck!"); _set_card_and_flags(deck, 0, card1, flags1 | CFLAG_SEEN | CFLAG_MARKED); @@ -787,103 +799,69 @@ bool deck_peek() card2 = get_card_and_flags(deck, 1, flags2); - if (num_cards == 2) - { - deck.props["non_brownie_draws"] = (char) 2; - deck.plus2 = -2; - - _deck_peek_ident(deck); - - mprf("Only two cards in the deck: %s and %s.", - card_name(card1), card_name(card2)); - - mpr("You shuffle the deck."); - - // If both cards are the same, then you know which card you're - // going to draw both times. - if (card1 == card2) - { - flags1 |= CFLAG_MARKED; - flags2 |= CFLAG_MARKED; - you.wield_change = true; - deck.props["num_marked"] = (char) 2; - } - - // "Shuffle" the two cards (even if they're the same, since - // the flags might differ). - if (coinflip()) - { - std::swap(card1, card2); - std::swap(flags1, flags2); - } - - // After the first of two differing cards is drawn, you know - // what the second card is going to be. - if (card1 != card2) - { - flags1 |= CFLAG_MARKED; - deck.props["num_marked"]++; - } - - _set_card_and_flags(deck, 0, card1, flags1 | CFLAG_SEEN); - _set_card_and_flags(deck, 1, card2, flags2 | CFLAG_SEEN); - - return true; - } - - _deck_peek_ident(deck); - - card3 = get_card_and_flags(deck, 2, flags3); - int already_seen = 0; if (flags1 & CFLAG_SEEN) already_seen++; if (flags2 & CFLAG_SEEN) already_seen++; - if (flags3 & CFLAG_SEEN) - already_seen++; - if (random2(3) < already_seen) + // always increase if seen 2, 50% increase if seen 1 + if ( coinflip() < already_seen) deck.props["non_brownie_draws"]++; - mprf("You draw three cards from the deck. They are: %s, %s and %s.", - card_name(card1), card_name(card2), card_name(card3)); + mprf("You draw two cards from the deck. They are: %s and %s.", + card_name(card1), card_name(card2)); _set_card_and_flags(deck, 0, card1, flags1 | CFLAG_SEEN); _set_card_and_flags(deck, 1, card2, flags2 | CFLAG_SEEN); - _set_card_and_flags(deck, 2, card3, flags3 | CFLAG_SEEN); mpr("You shuffle the cards back into the deck."); _shuffle_deck(deck); + // Peeking identifies the deck. + _deck_ident(deck); + + you.wield_change = true; return true; } // Mark a deck: look at the next four cards, mark them, and shuffle -// them back into the deck without losing any cards. The player won't -// know what order they're in, and the if the top card is non-marked -// then the player won't know what the next card is. -// Return false if the operation was failed/aborted along the way. +// them back into the deck. The player won't know what order they're +// in, and the if the top card is non-marked then the player won't +// know what the next card is. Return false if the operation was +// failed/aborted along the way. bool deck_mark() { - if ( !_wielding_deck() ) + const int slot = _choose_inventory_deck( "Mark which deck?" ); + if ( slot == -1 ) { - mpr("You aren't wielding a deck!"); crawl_state.zero_turns_taken(); return false; } - item_def& deck(you.inv[you.equip[EQ_WEAPON]]); + item_def& deck(you.inv[slot]); if (_check_buggy_deck(deck)) return false; CrawlHashTable &props = deck.props; if (props["num_marked"].get_byte() > 0) { - mpr("Deck is already marked."); + mpr("The deck is already marked."); crawl_state.zero_turns_taken(); return false; } + // lose some cards, but keep at least two + if ( cards_in_deck(deck) > 2 ) + { + const int num_lost = std::min(cards_in_deck(deck)-2, random2(3) + 1); + for ( int i = 0; i < num_lost; ++i ) + _deck_lose_card(deck); + if ( num_lost == 1 ) + mpr("A card falls out of the deck."); + else if ( num_lost > 1 ) + mpr("Some cards fall out of the deck."); + } + const int num_cards = cards_in_deck(deck); const int num_to_mark = (num_cards < 4 ? num_cards : 4); @@ -907,9 +885,8 @@ bool deck_mark() props["num_marked"] = (char) num_to_mark; if (num_cards == 1) - return true; - - if (num_cards < 4) + ; + else if (num_cards < 4) { mprf("You shuffle the deck."); deck.plus2 = -num_cards; @@ -918,6 +895,7 @@ bool deck_mark() mprf("You shuffle the cards back into the deck."); _shuffle_deck(deck); + _deck_ident(deck); you.wield_change = true; return true; @@ -1067,14 +1045,6 @@ bool deck_triple_draw() if (_check_buggy_deck(deck)) return false; - CrawlHashTable &props = deck.props; - if (props["num_marked"].get_byte() > 0) - { - mpr("You can't triple draw from a marked deck."); - crawl_state.zero_turns_taken(); - return false; - } - const int num_cards = cards_in_deck(deck); if (num_cards == 1) diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index 461ff62bd2..af1598b224 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -1377,6 +1377,7 @@ static std::string describe_deck( const item_def &item ) } const int num_cards = cards_in_deck(item); + int last_known_card = -1; if ( top_card_is_known(item) ) { description += "Next card(s): "; @@ -1389,6 +1390,7 @@ static std::string describe_deck( const item_def &item ) if ( i != 0 ) description += ", "; description += card_name(card); + last_known_card = i; } else break; @@ -1396,6 +1398,30 @@ static std::string describe_deck( const item_def &item ) description += "$"; } + // Marked cards which we don't know straight off. + std::vector marked_cards; + for ( int i = last_known_card + 1; i < num_cards; ++i ) + { + unsigned char flags; + const card_type card = get_card_and_flags(item, -i-1, flags); + if ( flags & CFLAG_MARKED ) + marked_cards.push_back(card); + } + if ( !marked_cards.empty() ) + { + std::sort(marked_cards.begin(), marked_cards.end(), + compare_card_names); + description += "Marked card(s): "; + for ( unsigned int i = 0; i < marked_cards.size(); ++i ) + { + if ( i != 0 ) + description += ", "; + description += card_name(marked_cards[i]); + } + description += "$"; + } + + // Seen cards in the deck. std::vector seen_cards; for ( int i = 0; i < num_cards; ++i ) { diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 483673a0f9..47356b9a2c 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -113,11 +113,11 @@ enum ability_type ABIL_LUGONU_BANISH, ABIL_LUGONU_CORRUPT, ABIL_LUGONU_ABYSS_ENTER, - ABIL_NEMELEX_PEEK_DECK, - ABIL_NEMELEX_DRAW_CARD, + ABIL_NEMELEX_DRAW_ONE, + ABIL_NEMELEX_PEEK_TWO, ABIL_NEMELEX_TRIPLE_DRAW, - ABIL_NEMELEX_MARK_DECK, - ABIL_NEMELEX_STACK_DECK, + ABIL_NEMELEX_MARK_FOUR, + ABIL_NEMELEX_STACK_FIVE, ABIL_BEOGH_SMITING, ABIL_BEOGH_RECALL_ORCISH_FOLLOWERS, diff --git a/crawl-ref/source/format.cc b/crawl-ref/source/format.cc index ebccc2bf10..ea97f21b4d 100644 --- a/crawl-ref/source/format.cc +++ b/crawl-ref/source/format.cc @@ -351,7 +351,7 @@ std::string formatted_string::to_colour_string() const while (true) { - const unsigned int left_angle = st.find('<', start); + const size_t left_angle = st.find('<', start); if (left_angle == std::string::npos) break; -- cgit v1.2.3-54-g00ecf