From b7dee52a419fd5470a063b2e34b3d2bfb7a04e5f Mon Sep 17 00:00:00 2001 From: Adam Borowski Date: Sun, 4 Oct 2009 18:15:56 +0200 Subject: Amulet of guardian spirit, it comes as an amulet or a cap. When worn, all non-poison damage will drain mana instead, hurting hp only after mana is depleted. The cap brand is intended only for a fixedart, but per dpeg's request, it will be generated on ordinary caps for now, as a test. --- crawl-ref/source/artefact.cc | 7 +++++++ crawl-ref/source/dat/descript/items.txt | 6 ++++++ crawl-ref/source/delay.cc | 8 ++++++++ crawl-ref/source/describe.cc | 8 ++++++++ crawl-ref/source/enum.h | 1 + crawl-ref/source/it_use2.cc | 16 ++++++++++++++++ crawl-ref/source/item_use.cc | 17 +++++++++++++++++ crawl-ref/source/itemname.cc | 3 +++ crawl-ref/source/itemprop.h | 4 +++- crawl-ref/source/makeitem.cc | 7 ++++++- crawl-ref/source/ouch.cc | 11 +++++++++++ crawl-ref/source/output.cc | 4 +++- crawl-ref/source/player.cc | 7 +++++++ crawl-ref/source/player.h | 1 + crawl-ref/source/shopping.cc | 1 + crawl-ref/source/util/art-data.pl | 3 ++- 16 files changed, 100 insertions(+), 4 deletions(-) (limited to 'crawl-ref') diff --git a/crawl-ref/source/artefact.cc b/crawl-ref/source/artefact.cc index 5c8a1dafc0..94f0dc4a6b 100644 --- a/crawl-ref/source/artefact.cc +++ b/crawl-ref/source/artefact.cc @@ -1058,6 +1058,13 @@ void static _get_randart_properties(const item_def &item, power_level++; } + if (!done_powers && one_chance_in(10) && aclass == OBJ_ARMOUR + && (atype == ARM_CAP || atype == ARM_SHIELD)) + { + proprt[ARTP_SPIRIT_SHIELD] = 1; + power_level++; + } + // Armours get fewer powers, and are also less likely to be // cursed than weapons if (aclass == OBJ_ARMOUR) diff --git a/crawl-ref/source/dat/descript/items.txt b/crawl-ref/source/dat/descript/items.txt index 8a00206fee..5004c73566 100644 --- a/crawl-ref/source/dat/descript/items.txt +++ b/crawl-ref/source/dat/descript/items.txt @@ -23,6 +23,12 @@ motion. This allows the descent of staircases and the retrieval of items lying on the ground, for example, but does not deprive the wearer of the benefits of levitation. %%%% +amulet of guardian spirit + +This amulet makes its wearer immune to damage, draining magical power +instead. Should the reserves of magic be depleted, the spirit will +fail to provide its protection until more power is available. +%%%% amulet of inaccuracy This amulet makes its wearer less accurate in hand combat and when diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc index 7ebb5a8b82..0dcf44a472 100644 --- a/crawl-ref/source/delay.cc +++ b/crawl-ref/source/delay.cc @@ -1597,6 +1597,14 @@ void armour_wear_effects(const int item_slot) else mpr("You feel extremely powerful."); break; + + case SPARM_SPIRIT_SHIELD: + if (player_spirit_shield()<2) + { + set_mp(0, false); + mpr("You feel spirits watching over you."); + } + break; } } diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index ccb0a2e45d..2189bd4071 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -152,6 +152,7 @@ const char* jewellery_base_ability_string(int subtype) case AMU_CONSERVATION: return "Cons"; case AMU_CONTROLLED_FLIGHT: return "cFly"; case AMU_RESIST_MUTATION: return "rMut"; + case AMU_GUARDIAN_SPIRIT: return "Spirit"; } return ""; } @@ -202,6 +203,7 @@ static std::vector _randart_propnames( const item_def& item ) { "rC", ARTP_COLD, 1 }, { "rN", ARTP_NEGATIVE_ENERGY, 1 }, { "MR", ARTP_MAGIC, 2 }, + { "Spirit", ARTP_SPIRIT_SHIELD, 2 }, // Quantitative attributes { "AC", ARTP_AC, 0 }, @@ -395,6 +397,7 @@ static std::string _randart_descrip( const item_def &item ) { ARTP_CAN_TELEPORT, "It lets you teleport.", false}, { ARTP_BERSERK, "It lets you go berserk.", false}, { ARTP_MAPPING, "It lets you sense your surroundings.", false}, + { ARTP_SPIRIT_SHIELD, "It shields you from harm at the cost of magical power.", false}, { ARTP_NOISES, "It makes noises.", false}, { ARTP_PREVENT_SPELLCASTING, "It prevents spellcasting.", false}, { ARTP_CAUSE_TELEPORTATION, "It causes teleportation.", false}, @@ -1261,6 +1264,11 @@ static std::string _describe_armour( const item_def &item, bool verbose ) description += "It reflects blocked things back in the " "direction they came from."; break; + + case SPARM_SPIRIT_SHIELD: + description += "It shields its wearer from harm at the cost " + "of magical power."; + break; } } diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index f299733d9f..cab5580985 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -2550,6 +2550,7 @@ enum artefact_prop_type ARTP_CURSED, ARTP_STEALTH, ARTP_MAGICAL_POWER, // 30 + ARTP_SPIRIT_SHIELD, ARTP_NUM_PROPERTIES }; diff --git a/crawl-ref/source/it_use2.cc b/crawl-ref/source/it_use2.cc index a9cbc99bd3..c39b92b9ca 100644 --- a/crawl-ref/source/it_use2.cc +++ b/crawl-ref/source/it_use2.cc @@ -632,6 +632,22 @@ void unwear_armour(int slot) mpr("You feel strangely numb."); break; + case SPARM_SPIRIT_SHIELD: + if (!player_spirit_shield()) + mpr("You feel strangely alone."); + else if (player_equip(EQ_AMULET, AMU_GUARDIAN_SPIRIT, true)) + { + item_def& amu(you.inv[you.equip[EQ_AMULET]]); + if (!item_type_known(amu)) + { + set_ident_type(amu.base_type, amu.sub_type, ID_KNOWN_TYPE); + set_ident_flags(amu, ISFLAG_KNOW_PROPERTIES); + mprf("You are wearing: %s", + amu.name(DESC_INVENTORY_EQUIP).c_str()); + } + } + break; + default: break; } diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index beb1ef5331..7418d8e98c 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -3249,6 +3249,16 @@ void jewellery_wear_effects(item_def &item) ident = ID_KNOWN_TYPE; } break; + + case AMU_GUARDIAN_SPIRIT: + if (player_spirit_shield()<2) + { + set_mp(0, false); + mpr("You feel your power drawn to a protective spirit."); + ident = ID_KNOWN_TYPE; + } + break; + } // Artefacts have completely different appearance than base types @@ -5365,6 +5375,13 @@ void use_artefact(item_def &item, bool *show_msgs, bool unmeld) if (proprt[ARTP_NOISES]) you.attribute[ATTR_NOISES] = 1; + if (proprt[ARTP_SPIRIT_SHIELD]) + { + set_mp(0, false); + mpr("You feel the spirits watch over you."); + artefact_wpn_learn_prop(item, ARTP_SPIRIT_SHIELD); + } + if (!alreadyknown && Options.autoinscribe_artefacts) add_autoinscription(item, artefact_auto_inscription(item)); diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc index 936bbb59a5..d00e81fb54 100644 --- a/crawl-ref/source/itemname.cc +++ b/crawl-ref/source/itemname.cc @@ -380,6 +380,7 @@ static const char* armour_ego_name( special_armour_type sparm, bool terse ) case SPARM_ARCHMAGI: return "the Archmagi"; case SPARM_PRESERVATION: return "preservation"; case SPARM_REFLECTION: return "reflection"; + case SPARM_SPIRIT_SHIELD: return "spirit shield"; default: return "bugginess"; } } @@ -406,6 +407,7 @@ static const char* armour_ego_name( special_armour_type sparm, bool terse ) case SPARM_ARCHMAGI: return " {Archmagi}"; case SPARM_PRESERVATION: return " {rCorr, Cons}"; case SPARM_REFLECTION: return " {rflct}"; + case SPARM_SPIRIT_SHIELD: return " {Spirit}"; default: return " {buggy}"; } } @@ -592,6 +594,7 @@ static const char* jewellery_type_name(int jeweltype) case AMU_CONTROLLED_FLIGHT: return "amulet of controlled flight"; case AMU_INACCURACY: return "amulet of inaccuracy"; case AMU_RESIST_MUTATION: return "amulet of resist mutation"; + case AMU_GUARDIAN_SPIRIT: return "amulet of guardian spirit"; default: return "buggy jewellery"; } } diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h index dd1fc9da8b..883e7e682c 100644 --- a/crawl-ref/source/itemprop.h +++ b/crawl-ref/source/itemprop.h @@ -191,6 +191,7 @@ enum jewellery_type AMU_CONTROLLED_FLIGHT, AMU_INACCURACY, AMU_RESIST_MUTATION, + AMU_GUARDIAN_SPIRIT, NUM_JEWELLERY }; @@ -336,7 +337,8 @@ enum special_armour_type SPARM_ARCHMAGI, SPARM_PRESERVATION, SPARM_REFLECTION, - NUM_SPECIAL_ARMOURS // 20 + SPARM_SPIRIT_SHIELD, // 20 + NUM_SPECIAL_ARMOURS // 21 }; enum special_missile_type // to separate from weapons in general {dlb} diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc index 10dc28ff7c..45e2ce8f87 100644 --- a/crawl-ref/source/makeitem.cc +++ b/crawl-ref/source/makeitem.cc @@ -2033,8 +2033,13 @@ static special_armour_type _determine_armour_ego(const item_def& item, } break; - case ARM_HELMET: case ARM_CAP: + if (one_chance_in(10)) + { + rc = SPARM_SPIRIT_SHIELD; + break; + } + case ARM_HELMET: rc = coinflip() ? SPARM_SEE_INVISIBLE : SPARM_INTELLIGENCE; break; diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc index 91753b5ff0..69bba8b5dc 100644 --- a/crawl-ref/source/ouch.cc +++ b/crawl-ref/source/ouch.cc @@ -943,6 +943,17 @@ void ouch(int dam, int death_source, kill_method_type death_type, if (dam != INSTANT_DEATH) { + if (player_spirit_shield() && death_type != KILLED_BY_POISON) + { + if (dam <= you.magic_points) + { + dec_mp(dam); + return; + } + dam -= you.magic_points; + dec_mp(you.magic_points); + } + if (dam >= you.hp) { if (harm_protection_type hpt = god_protects_from_harm(you.religion)) diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc index da8a9fc8da..ea936a3c29 100644 --- a/crawl-ref/source/output.cc +++ b/crawl-ref/source/output.cc @@ -2108,6 +2108,7 @@ static std::vector _get_overview_resistances( const int rlife = player_prot_life(calc_unid); const int rpois = player_res_poison(calc_unid); const int relec = player_res_electricity(calc_unid); + const int rspir = player_spirit_shield(calc_unid); const int rsust = player_sust_abil(calc_unid); const int rmuta = (wearing_amulet(AMU_RESIST_MUTATION, calc_unid) || player_mutation_level(MUT_MUTATION_RESISTANCE) == 3 @@ -2120,7 +2121,7 @@ static std::vector _get_overview_resistances( "%sLife Prot.: %s\n" "%sRes.Poison: %s\n" "%sRes.Elec. : %s\n" - "\n" + "%sSpirit.Shd: %s\n" "%sSust.Abil.: %s\n" "%sRes.Mut. : %s\n" "%sRes.Slow : %s\n", @@ -2129,6 +2130,7 @@ static std::vector _get_overview_resistances( _determine_colour_string(rlife, 3), itosym3(rlife), _determine_colour_string(rpois, 1), itosym1(rpois), _determine_colour_string(relec, 1), itosym1(relec), + _determine_colour_string(rspir, 1), itosym1(rspir), _determine_colour_string(rsust, 1), itosym1(rsust), _determine_colour_string(rmuta, 1), itosym1(rmuta), _determine_colour_string(rslow, 1), itosym1(rslow)); diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index aa79a289d6..b902943ec8 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -4495,6 +4495,13 @@ int player_mental_clarity(bool calc_unid, bool items) return ((ret > 3) ? 3 : ret); } +int player_spirit_shield(bool calc_unid) +{ + return player_equip(EQ_AMULET, AMU_GUARDIAN_SPIRIT, calc_unid) + + player_equip_ego_type(EQ_HELMET, SPARM_SPIRIT_SHIELD) + + scan_artefacts(ARTP_SPIRIT_SHIELD); +} + // Returns whether the player has the effect of the amulet from a // non-amulet source. bool extrinsic_amulet_effect(jewellery_type amulet) diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index 0cca6db53d..55d9cc5c03 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -206,6 +206,7 @@ int player_res_torment(bool calc_unid = true); bool player_item_conserve(bool calc_unid = true); int player_mental_clarity(bool calc_unid = true, bool items = true); +int player_spirit_shield(bool calc_unid = true); bool player_can_smell(); bool player_likes_chunks(bool permanently = false); diff --git a/crawl-ref/source/shopping.cc b/crawl-ref/source/shopping.cc index 1994f78777..07d1548eec 100644 --- a/crawl-ref/source/shopping.cc +++ b/crawl-ref/source/shopping.cc @@ -1551,6 +1551,7 @@ unsigned int item_value( item_def item, bool ident ) valued -= 50; break; case AMU_THE_GOURMAND: + case AMU_GUARDIAN_SPIRIT: valued += 35; break; case AMU_CLARITY: diff --git a/crawl-ref/source/util/art-data.pl b/crawl-ref/source/util/art-data.pl index 2c4efe2760..8540847ecb 100755 --- a/crawl-ref/source/util/art-data.pl +++ b/crawl-ref/source/util/art-data.pl @@ -48,6 +48,7 @@ my %field_type = ( RND_TELE => "bool", SEEINV => "bool", SPECIAL => "bool", + SPIRIT => "bool", STEALTH => "num", STR => "num", VALUE => "num", @@ -471,7 +472,7 @@ my @art_order = ( "SEEINV", "INV", "LEV", "BLINK", "CANTELEP", "BERSERK", "\n", "MAPPING", "NOISES", "NOSPELL", "RND_TELE", "NOTELEP", "\n", "ANGRY", "METAB", "MUTATE", "ACC", "DAM", "\n", - "CURSED", "STEALTH", "MP", "}", + "CURSED", "STEALTH", "MP", "SPIRIT", "}", "DESC", "\n", "DESC_ID", "\n", -- cgit v1.2.3-54-g00ecf