Attached Files:
|
iashol.patch [^] (93,969 bytes) 2014-06-09 00:57 [Show Content] [Hide Content]commit 35f02841a83f5e495073515cfdc7ced5194eaf34
Author: Corin Buchanan-Howland <corin@buchananhowland.net>
Date: Fri Apr 4 21:50:52 2014 -0400
First full Iashol commit
diff --git a/crawl-ref/source/ability.cc b/crawl-ref/source/ability.cc
index f159285..27036a1 100644
--- a/crawl-ref/source/ability.cc
+++ b/crawl-ref/source/ability.cc
@@ -196,12 +196,15 @@ ability_type god_abilities[NUM_GODS][MAX_GOD_ABILITIES] =
// Dithmenos
{ ABIL_NON_ABILITY, ABIL_DITHMENOS_SHADOW_STEP, ABIL_NON_ABILITY,
ABIL_NON_ABILITY, ABIL_DITHMENOS_SHADOW_FORM },
+ // Iashol
+ { ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_IASHOL_DRAW_OUT_POWER,
+ ABIL_IASHOL_POWER_LEAP, ABIL_IASHOL_CATACLYSM },
// Gozag
{ ABIL_GOZAG_POTION_PETITION, ABIL_GOZAG_CALL_MERCHANT,
ABIL_GOZAG_BRIBE_BRANCH, ABIL_NON_ABILITY, ABIL_NON_ABILITY },
// Qazlal
{ ABIL_NON_ABILITY, ABIL_QAZLAL_UPHEAVAL, ABIL_QAZLAL_ELEMENTAL_FORCE,
- ABIL_NON_ABILITY, ABIL_QAZLAL_DISASTER_AREA },
+ ABIL_NON_ABILITY, ABIL_QAZLAL_DISASTER_AREA }
};
// The description screen was way out of date with the actual costs.
@@ -414,6 +417,41 @@ static const ability_def Ability_List[] =
{ ABIL_DITHMENOS_SHADOW_FORM, "Shadow Form",
9, 0, 0, 10, 0, ABFLAG_SKILL_DRAIN },
+ // Iashol
+ { ABIL_IASHOL_DRAW_OUT_POWER, "Draw Out Power",
+ 0, 0, 0, 0, 0, ABFLAG_EXHAUSTION|ABFLAG_SKILL_DRAIN },
+ { ABIL_IASHOL_POWER_LEAP, "Power Leap",
+ 5, 0, 0, 0, 0, ABFLAG_EXHAUSTION },
+ { ABIL_IASHOL_CATACLYSM, "Cataclysm",
+ 8, 0, 0, 0, 0, ABFLAG_EXHAUSTION|ABFLAG_SKILL_DRAIN },
+
+ { ABIL_IASHOL_SACRIFICE_PURITY, "Sacrifice Purity",
+ 0, 0, 0, 0, 0, ABFLAG_NONE },
+ { ABIL_IASHOL_SACRIFICE_WORDS, "Sacrifice Words",
+ 0, 0, 0, 0, 0, ABFLAG_NONE },
+ { ABIL_IASHOL_SACRIFICE_DRINK, "Sacrifice Drink",
+ 0, 0, 0, 0, 0, ABFLAG_NONE },
+ { ABIL_IASHOL_SACRIFICE_EYE, "Sacrifice An Eye",
+ 0, 0, 0, 0, 0, ABFLAG_NONE },
+ { ABIL_IASHOL_SACRIFICE_ESSENCE, "Sacrifice Essence",
+ 0, 0, 0, 0, 0, ABFLAG_NONE },
+ { ABIL_IASHOL_SACRIFICE_HEALTH, "Sacrifice Health",
+ 0, 0, 0, 0, 0, ABFLAG_NONE },
+ { ABIL_IASHOL_SACRIFICE_STEALTH, "Sacrifice Stealth",
+ 0, 0, 0, 0, 0, ABFLAG_NONE },
+ { ABIL_IASHOL_SACRIFICE_ARTIFICE, "Sacrifice Artifice",
+ 0, 0, 0, 0, 0, ABFLAG_NONE },
+ { ABIL_IASHOL_SACRIFICE_SANITY, "Sacrifice Sanity",
+ 0, 0, 0, 0, 0, ABFLAG_NONE },
+ { ABIL_IASHOL_SACRIFICE_ARCANA, "Sacrifice Arcana",
+ 0, 0, 0, 0, 0, ABFLAG_NONE },
+ { ABIL_IASHOL_SACRIFICE_NIMBLENESS, "Sacrifice Nimbleness",
+ 0, 0, 0, 0, 0, ABFLAG_NONE },
+ { ABIL_IASHOL_SACRIFICE_DURABILITY, "Sacrifice Durability",
+ 0, 0, 0, 0, 0, ABFLAG_NONE },
+ { ABIL_IASHOL_SACRIFICE_HAND, "Sacrifice a Hand",
+ 0, 0, 0, 0, 0, ABFLAG_NONE },
+
// Gozag
{ ABIL_GOZAG_POTION_PETITION, "Potion Petition",
0, 0, 0, 0, 0, ABFLAG_GOLD },
@@ -1110,6 +1148,23 @@ talent get_talent(ability_type ability, bool check_confused)
case ABIL_GOZAG_POTION_PETITION:
case ABIL_GOZAG_CALL_MERCHANT:
case ABIL_GOZAG_BRIBE_BRANCH:
+ case ABIL_IASHOL_DRAW_OUT_POWER:
+ case ABIL_IASHOL_POWER_LEAP:
+ case ABIL_IASHOL_CATACLYSM:
+ case ABIL_IASHOL_SACRIFICE_PURITY:
+ case ABIL_IASHOL_SACRIFICE_WORDS:
+ case ABIL_IASHOL_SACRIFICE_DRINK:
+ case ABIL_IASHOL_SACRIFICE_EYE:
+ case ABIL_IASHOL_SACRIFICE_ESSENCE:
+ case ABIL_IASHOL_SACRIFICE_HEALTH:
+ case ABIL_IASHOL_SACRIFICE_STEALTH:
+ case ABIL_IASHOL_SACRIFICE_ARTIFICE:
+ case ABIL_IASHOL_SACRIFICE_LOVE:
+ case ABIL_IASHOL_SACRIFICE_SANITY:
+ case ABIL_IASHOL_SACRIFICE_ARCANA:
+ case ABIL_IASHOL_SACRIFICE_NIMBLENESS:
+ case ABIL_IASHOL_SACRIFICE_DURABILITY:
+ case ABIL_IASHOL_SACRIFICE_HAND:
case ABIL_STOP_RECALL:
invoc = true;
failure = 0;
@@ -2995,6 +3050,61 @@ static bool _do_ability(const ability_def& abil)
return false;
break;
+ case ABIL_IASHOL_SACRIFICE_PURITY:
+ case ABIL_IASHOL_SACRIFICE_WORDS:
+ case ABIL_IASHOL_SACRIFICE_DRINK:
+ case ABIL_IASHOL_SACRIFICE_EYE:
+ case ABIL_IASHOL_SACRIFICE_ESSENCE:
+ case ABIL_IASHOL_SACRIFICE_HEALTH:
+ case ABIL_IASHOL_SACRIFICE_STEALTH:
+ case ABIL_IASHOL_SACRIFICE_ARTIFICE:
+ case ABIL_IASHOL_SACRIFICE_LOVE:
+ case ABIL_IASHOL_SACRIFICE_SANITY:
+ case ABIL_IASHOL_SACRIFICE_ARCANA:
+ case ABIL_IASHOL_SACRIFICE_NIMBLENESS:
+ case ABIL_IASHOL_SACRIFICE_DURABILITY:
+ case ABIL_IASHOL_SACRIFICE_HAND:
+ iashol_do_sacrifice(abil.ability);
+ break;
+
+ case ABIL_IASHOL_DRAW_OUT_POWER:
+ if (you.duration[DUR_EXHAUSTED])
+ {
+ mpr("You're too exhausted to draw out your power.");
+ return false;
+ }
+ if (you.hp == you.hp_max && you.magic_points == you.max_magic_points)
+ return false;
+ iashol_draw_out_power();
+ you.increase_duration(DUR_EXHAUSTED, 30 + random2(20));
+ break;
+
+ case ABIL_IASHOL_POWER_LEAP:
+ if (you.duration[DUR_EXHAUSTED])
+ {
+ mpr("You're too exhausted to power leap.");
+ return false;
+ }
+ if (!iashol_power_leap())
+ {
+ canned_msg(MSG_OK);
+ return false;
+ }
+ you.increase_duration(DUR_EXHAUSTED, 30 + random2(20));
+ break;
+
+
+ case ABIL_IASHOL_CATACLYSM:
+ if (you.duration[DUR_EXHAUSTED])
+ {
+ mpr("You're too exhausted to unleash your cataclysmic power.");
+ return false;
+ }
+ if (!iashol_cataclysm())
+ return false;
+ you.increase_duration(DUR_EXHAUSTED, 30 + random2(20));
+ break;
+
case ABIL_RENOUNCE_RELIGION:
if (yesno("Really renounce your faith, foregoing its fabulous benefits?",
false, 'n')
@@ -3508,16 +3618,19 @@ vector<talent> your_talents(bool check_confused, bool include_unusable)
_add_talent(talents, ABIL_STOP_SINGING, check_confused);
// Evocations from items.
- if (you.scan_artefacts(ARTP_BLINK))
+ if (you.scan_artefacts(ARTP_BLINK)
+ && !player_mutation_level(MUT_NO_ARTIFICE))
_add_talent(talents, ABIL_EVOKE_BLINK, check_confused);
- if (you.scan_artefacts(ARTP_FOG))
+ if (you.scan_artefacts(ARTP_FOG)
+ && !player_mutation_level(MUT_NO_ARTIFICE))
_add_talent(talents, ABIL_EVOKE_FOG, check_confused);
- if (you.evokable_berserk())
+ if (you.evokable_berserk() && !player_mutation_level(MUT_NO_ARTIFICE))
_add_talent(talents, ABIL_EVOKE_BERSERK, check_confused);
- if (you.evokable_invis() && !you.attribute[ATTR_INVIS_UNCANCELLABLE])
+ if (you.evokable_invis() && !you.attribute[ATTR_INVIS_UNCANCELLABLE]
+ && !player_mutation_level(MUT_NO_ARTIFICE))
{
// Now you can only turn invisibility off if you have an
// activatable item. Wands and potions will have to time
@@ -3528,7 +3641,7 @@ vector<talent> your_talents(bool check_confused, bool include_unusable)
_add_talent(talents, ABIL_EVOKE_TURN_INVISIBLE, check_confused);
}
- if (you.evokable_flight())
+ if (you.evokable_flight() && !player_mutation_level(MUT_NO_ARTIFICE))
{
// Has no effect on permanently flying Tengu.
if (!you.permanent_flight() || !you.racial_permanent_flight())
@@ -3548,16 +3661,18 @@ vector<talent> your_talents(bool check_confused, bool include_unusable)
}
}
- if (you.evokable_jump())
+ if (you.evokable_jump() && !player_mutation_level(MUT_NO_ARTIFICE))
_add_talent(talents, ABIL_EVOKE_JUMP, check_confused);
- if (you.wearing(EQ_RINGS, RING_TELEPORTATION)
+ if (you.wearing(EQ_RINGS, RING_TELEPORTATION
+ && !player_mutation_level(MUT_NO_ARTIFICE))
&& !crawl_state.game_is_sprint())
{
_add_talent(talents, ABIL_EVOKE_TELEPORTATION, check_confused);
}
- if (you.wearing(EQ_RINGS, RING_TELEPORT_CONTROL))
+ if (you.wearing(EQ_RINGS, RING_TELEPORT_CONTROL)
+ && !player_mutation_level(MUT_NO_ARTIFICE))
_add_talent(talents, ABIL_EVOKE_TELEPORT_CONTROL, check_confused);
// Find hotkeys for the non-hotkeyed talents.
@@ -3724,6 +3839,22 @@ static int _find_ability_slot(const ability_def &abil)
first_slot = letter_to_index('W');
if (abil.ability == ABIL_CONVERT_TO_BEOGH)
first_slot = letter_to_index('Y');
+ if (abil.ability == ABIL_IASHOL_SACRIFICE_PURITY
+ || abil.ability == ABIL_IASHOL_SACRIFICE_WORDS
+ || abil.ability == ABIL_IASHOL_SACRIFICE_DRINK
+ || abil.ability == ABIL_IASHOL_SACRIFICE_EYE
+ || abil.ability == ABIL_IASHOL_SACRIFICE_ESSENCE
+ || abil.ability == ABIL_IASHOL_SACRIFICE_HEALTH
+ || abil.ability == ABIL_IASHOL_SACRIFICE_STEALTH
+ || abil.ability == ABIL_IASHOL_SACRIFICE_ARTIFICE
+ || abil.ability == ABIL_IASHOL_SACRIFICE_LOVE
+ || abil.ability == ABIL_IASHOL_SACRIFICE_SANITY
+ || abil.ability == ABIL_IASHOL_SACRIFICE_ARCANA
+ || abil.ability == ABIL_IASHOL_SACRIFICE_NIMBLENESS
+ || abil.ability == ABIL_IASHOL_SACRIFICE_DURABILITY
+ || abil.ability == ABIL_IASHOL_SACRIFICE_HAND)
+ first_slot = letter_to_index('P');
+
for (int slot = first_slot; slot < 52; ++slot)
{
@@ -3761,6 +3892,14 @@ vector<ability_type> get_god_abilities(bool include_unusable, bool ignore_piety)
{
abilities.push_back(ABIL_CHEIBRIADOS_TIME_BEND);
}
+ else if (you_worship(GOD_IASHOL))
+ {
+ int num_sacrifices = you.available_sacrifices.size();
+ for (int i = 0; i < num_sacrifices; ++i)
+ {
+ abilities.push_back(you.available_sacrifices[i]);
+ }
+ }
else if (you.transfer_skill_points > 0)
abilities.push_back(ABIL_ASHENZARI_END_TRANSFER);
diff --git a/crawl-ref/source/acquire.cc b/crawl-ref/source/acquire.cc
index ea1c059..2b93b13 100644
--- a/crawl-ref/source/acquire.cc
+++ b/crawl-ref/source/acquire.cc
@@ -495,6 +495,9 @@ static int _acquirement_weapon_subtype(bool divine)
const bool two_handed = you.hands_reqd(item_considered) == HANDS_TWO;
+ if (two_handed && player_mutation_level(MUT_MISSING_HAND))
+ continue;
+
// For non-Trog/Okawaru acquirements, give a boost to high-end items.
if (!divine && !is_range_weapon(item_considered))
{
diff --git a/crawl-ref/source/attack.cc b/crawl-ref/source/attack.cc
index 2f54ecd..45a38c7 100644
--- a/crawl-ref/source/attack.cc
+++ b/crawl-ref/source/attack.cc
@@ -221,6 +221,10 @@ int attack::calc_to_hit(bool random)
|| (weapon && is_range_weapon(*weapon)
&& using_weapon()));
+ //horror penalty
+ if (you.duration[DUR_HORROR])
+ mhit -= you.props["horror_penalty"].get_int();
+
// hunger penalty
if (you.hunger_state == HS_STARVING)
mhit -= 3;
@@ -231,7 +235,7 @@ int attack::calc_to_hit(bool random)
//mutation
if (player_mutation_level(MUT_EYEBALLS))
mhit += 2 * player_mutation_level(MUT_EYEBALLS) + 1;
-
+
// hit roll
mhit = maybe_random2(mhit, random);
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index e9012c1..2263652 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -1839,6 +1839,9 @@ static bool _monster_resists_mass_enchantment(monster* mons,
// Assuming that the only mass charm is control undead.
if (wh_enchant == ENCH_CHARM)
{
+ if (player_mutation_level(MUT_NO_LOVE))
+ return true;
+
if (mons->friendly())
return true;
diff --git a/crawl-ref/source/dat/descript/ability.txt b/crawl-ref/source/dat/descript/ability.txt
index 68b7cc9..85d6f31 100644
--- a/crawl-ref/source/dat/descript/ability.txt
+++ b/crawl-ref/source/dat/descript/ability.txt
@@ -612,6 +612,7 @@ will bleed smoke on any incoming attack. However, your ability to deal damage
in melee will be halved, your spellcasting power will be greatly hampered, and
your skills will be further drained when taking damage.
%%%%
+
# Gozag
Potion Petition ability
@@ -653,6 +654,163 @@ Disaster Area ability
Blasts the entire area around you with powerful natural forces.
%%%%
+# Iashol
+Draw Out Power ability
+
+Restores health and magic points to you. The amount restored increases with
+piety.
+
+Using this ability exhausts and slightly drains you.
+%%%%
+Power Leap ability
+
+Use the power that infuses you to perform an incredibly fast leap. On landing,
+the power that drove the leap explodes outward, damaging everything adjacent to
+you. The amount of damage done increases with your piety.
+
+Using this ability exhausts you.
+%%%%
+Cataclysm ability
+
+You unleash your hard-won power in a terrifying cataclysm. All enemies in your
+line of sight are dealt severe damage and may be rendered permanently mute or
+affected by antimagic or paralyzed or be attacked by summoned allies.
+
+Using this ability exhausts and severely drains you.
+%%%%
+Sacrifice Purity ability
+
+Adherents who choose to sacrifice their purity of body become twisted by
+mutation, and may begin to rot, have their body deformed, shout uncontrollably,
+heal slowly, or lose dexterity, strength, or intelligence. If you make this
+sacrifice, your powers granted by Iashol will become stronger in proportion to
+the value of the sacrifice, and you may gain new powers as well.
+
+Sacrifices cannot be taken back.
+%%%%
+Sacrifice Words ability
+
+Adherents who choose to sacrifice their words lose the ability to use magical
+scrolls. If you make this sacrifice, your powers granted by Iashol will become
+stronger in proportion to the value of the sacrifice, and you may gain new
+powers as well.
+
+Sacrifices cannot be taken back.
+%%%%
+Sacrifice Drink ability
+
+Adherents who choose to sacrifice their words lose the ability to drink
+potions. If you make this sacrifice, your powers granted by Iashol will become
+stronger in proportion to the value of the sacrifice, and you may gain new
+powers as well.
+
+Sacrifices cannot be taken back.
+%%%%
+Sacrifice an Eye ability
+
+Adherents who choose to sacrifice an eye suffer an accuracy penalty to all
+attacks that target non-adjacent foes. If you make this sacrifice, your powers
+granted by Iashol will become stronger in proportion to the value of the
+sacrifice, and you may gain new powers as well.
+
+Sacrifices cannot be taken back.
+%%%%
+Sacrifice Essence ability
+
+Adherents who choose to sacrifice their essence give up a part of their magical
+essence, which may lessen their magic pool, reduce their ability to resist
+hostile magic, or make it more difficult to successfully cast spells. If you
+make this sacrifice, your powers granted by Iashol will become stronger in
+proportion to the value of the sacrifice, and you may gain new powers as well.
+
+Sacrifices cannot be taken back.
+%%%%
+Sacrifice Health ability
+
+Adherents who choose to sacrifice their health may have their health pool
+decreased, suffer penalties to Evasion, or suffer penalties to AC. If you make
+this sacrifice, your powers granted by Iashol will become stronger in
+proportion to the value of the sacrifice, and you may gain new powers as well.
+
+Sacrifices cannot be taken back.
+%%%%
+Sacrifice Stealth ability
+
+Adherents who choose to sacrifice their stealth will always be noticed by foes
+and cannot have ranks in the Stealth skill. If you make this sacrifice, your
+powers granted by Iashol will become stronger in proportion to the value of the
+sacrifice, and you may gain new powers as well.
+
+Sacrifices cannot be taken back.
+%%%%
+Sacrifice Artifice ability
+
+Adherents who choose to sacrifice artifice may not evoke the latent power of
+magical objects and their Evocations skill is set to 0. If you make this
+sacrifice, your powers granted by Iashol will become stronger in proportion
+to the value of the sacrifice, and you may gain new powers as well.
+
+Sacrifices cannot be taken back.
+%%%%
+Sacrifice Love ability
+
+Adherents who choose to sacrifice love are despised by all. All creatures,
+even those summoned by the adherent, become hostile If you make this sacrifice,
+your powers granted by Iashol will become stronger in proportion to the value
+of the sacrifice, and you may gain new powers as well.
+
+Sacrifices cannot be taken back.
+%%%%
+Sacrifice Sanity ability
+
+Adherents who choose to sacrifice their sanity become terrified of blood. The
+sight of blood causes them to lose health and willpower, meaning that they will
+also be vulverable to hostile enchantments. If you make this sacrifice, your
+powers granted by Iashol will become stronger in proportion to the value of the
+sacrifice, and you may gain new powers as well.
+
+Sacrifices cannot be taken back.
+%%%%
+Sacrifice Arcana ability
+
+Adherents who choose to sacrifice their arcana lose the ability to use certain
+schools of magic. Any magic that includes a sacrificed school cannot be cast.
+Those magic skills cannot be trained. If you make this sacrifice, your powers
+granted by Iashol will become stronger in proportion to the value of the
+sacrifice, and you may gain new powers as well.
+
+Sacrifices cannot be taken back.
+%%%%
+Sacrifice Nimbleness ability
+
+Adherents who choose to sacrifice their nimbleness lose the ability to train
+the Dodging skill and have that skill set to 0. This sacrifice is worth more
+if you cannot train Armour. If you make this sacrifice, your powers granted
+by Iashol will become stronger in proportion to the value of the sacrifice,
+and you may gain new powers as well.
+
+Sacrifices cannot be taken back.
+%%%%
+Sacrifice Durability ability
+
+Adherents who choose to sacrifice their durability lose the ability to train
+the Armour skill and have that skill set to 0. This sacrifice is worth more
+if you cannot train Dodging. If you make this sacrifice, your powers granted
+by Iashol will become stronger in proportion to the value of the sacrifice,
+and you may gain new powers as well.
+
+Sacrifices cannot be taken back.
+%%%%
+Sacrifice a Hand ability
+
+Adherents who choose to sacrifice a hand lose the ability to lose two-handed
+weapons and shields, and also may only wear one ring. If you make this
+sacrifice, your powers granted by Iashol will become stronger in proportion
+to the value of the sacrifice, and you may gain new powers as well.
+
+Sacrifices cannot be taken back.
+
+%%%%
Renounce Religion ability
Renounce your faith. This will make your character leave your god (and usually
diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc
index 8c3f35d..f93f36f 100644
--- a/crawl-ref/source/directn.cc
+++ b/crawl-ref/source/directn.cc
@@ -3241,6 +3241,8 @@ static string _base_feature_desc(dungeon_feature_type grid, trap_type trap)
return "shattered altar of Ashenzari";
case DNGN_ALTAR_DITHMENOS:
return "shadowy altar of Dithmenos";
+ case DNGN_ALTAR_IASHOL:
+ return "the sacrificial altar of Iashol";
case DNGN_ALTAR_GOZAG:
return "opulent altar of Gozag";
case DNGN_ALTAR_QAZLAL:
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 61ff3d3..aa52307 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -186,12 +186,31 @@ enum ability_type
// Dithmenos
ABIL_DITHMENOS_SHADOW_STEP = 1170,
ABIL_DITHMENOS_SHADOW_FORM,
+ // Iashol
+ ABIL_IASHOL_DRAW_OUT_POWER = 1180,
+ ABIL_IASHOL_POWER_LEAP,
+ ABIL_IASHOL_CATACLYSM,
+
+ ABIL_IASHOL_SACRIFICE_PURITY,
+ ABIL_IASHOL_SACRIFICE_WORDS,
+ ABIL_IASHOL_SACRIFICE_DRINK,
+ ABIL_IASHOL_SACRIFICE_EYE,
+ ABIL_IASHOL_SACRIFICE_ESSENCE,
+ ABIL_IASHOL_SACRIFICE_HEALTH,
+ ABIL_IASHOL_SACRIFICE_STEALTH,
+ ABIL_IASHOL_SACRIFICE_ARTIFICE,
+ ABIL_IASHOL_SACRIFICE_LOVE,
+ ABIL_IASHOL_SACRIFICE_SANITY,
+ ABIL_IASHOL_SACRIFICE_ARCANA,
+ ABIL_IASHOL_SACRIFICE_NIMBLENESS,
+ ABIL_IASHOL_SACRIFICE_DURABILITY,
+ ABIL_IASHOL_SACRIFICE_HAND,
// Gozag
- ABIL_GOZAG_POTION_PETITION = 1180,
+ ABIL_GOZAG_POTION_PETITION = 1200,
ABIL_GOZAG_CALL_MERCHANT,
ABIL_GOZAG_BRIBE_BRANCH,
// Qazlal
- ABIL_QAZLAL_UPHEAVAL = 1190,
+ ABIL_QAZLAL_UPHEAVAL = 1210,
ABIL_QAZLAL_ELEMENTAL_FORCE,
ABIL_QAZLAL_DISASTER_AREA,
@@ -1093,6 +1112,7 @@ enum conduct_type
DID_KILL_ILLUMINATING, // Dithmenos
DID_FIRE, // Dithmenos
DID_KILL_FIERY, // Dithmenos
+ DID_SACRIFICE_LOVE, // Iashol
NUM_CONDUCTS
};
@@ -1496,8 +1516,9 @@ enum dungeon_feature_type
DNGN_ALTAR_CHEIBRIADOS,
DNGN_ALTAR_ASHENZARI,
DNGN_ALTAR_DITHMENOS,
+ DNGN_ALTAR_IASHOL,
#if TAG_MAJOR_VERSION == 34
- DNGN_ALTAR_LAST_GOD = DNGN_ALTAR_DITHMENOS,
+ DNGN_ALTAR_LAST_GOD = DNGN_ALTAR_IASHOL,
#else
DNGN_ALTAR_GOZAG,
DNGN_ALTAR_QAZLAL,
@@ -1721,11 +1742,13 @@ enum duration_type
DUR_ABJURATION_AURA,
DUR_MESMERISE_IMMUNE,
DUR_NO_POTIONS,
+ DUR_NO_SCROLLS,
DUR_QAZLAL_FIRE_RES,
DUR_QAZLAL_COLD_RES,
DUR_QAZLAL_ELEC_RES,
DUR_QAZLAL_AC,
DUR_CORROSION,
+ DUR_HORROR,
NUM_DURATIONS
};
@@ -1990,6 +2013,7 @@ enum god_type
GOD_CHEIBRIADOS,
GOD_ASHENZARI,
GOD_DITHMENOS,
+ GOD_IASHOL,
GOD_GOZAG,
GOD_QAZLAL,
NUM_GODS, // always after last god
@@ -3433,6 +3457,32 @@ enum mutation_type
MUT_SHOCK_VULNERABILITY,
MUT_COLD_BLOODED,
#endif
+ MUT_MISSING_HAND,
+ MUT_NO_READ,
+ MUT_NO_DRINK,
+ MUT_NO_STEALTH,
+ MUT_NO_ARTIFICE,
+ MUT_NO_LOVE,
+ MUT_FEAR_BLOOD,
+ MUT_NO_DODGING,
+ MUT_NO_ARMOUR,
+ MUT_NO_AIR_MAGIC,
+ MUT_NO_CHARM_MAGIC,
+ MUT_NO_CONJURATION_MAGIC,
+ MUT_NO_EARTH_MAGIC,
+ MUT_NO_FIRE_MAGIC,
+ MUT_NO_HEXES_MAGIC,
+ MUT_NO_ICE_MAGIC,
+ MUT_NO_NECROMANCY_MAGIC,
+ MUT_NO_POISON_MAGIC,
+ MUT_NO_SUMMONING_MAGIC,
+ MUT_NO_TRANSLOCATION_MAGIC,
+ MUT_NO_TRANSMUTATION_MAGIC,
+ MUT_PHYSICAL_VULNERABILITY,
+ MUT_SLOW_REFLEXES,
+ MUT_MAGICAL_VULNERABILITY,
+ MUT_ANTI_WIZARDRY,
+
NUM_MUTATIONS,
RANDOM_MUTATION,
diff --git a/crawl-ref/source/evoke.cc b/crawl-ref/source/evoke.cc
index d3c77dc..9c31781 100644
--- a/crawl-ref/source/evoke.cc
+++ b/crawl-ref/source/evoke.cc
@@ -1539,6 +1539,11 @@ bool evoke_item(int slot, bool check_range)
{
canned_msg(MSG_TOO_BERSERK);
return false;
+ } else if (player_mutation_level(MUT_NO_ARTIFICE) && (slot == -1
+ || slot != you.equip[EQ_WEAPON]
+ || weapon_reach(*you.weapon()) <= 2))
+ {
+ return mpr("You cannot evoke magical items."), false;
}
if (slot == -1)
@@ -1669,6 +1674,11 @@ bool evoke_item(int slot, bool check_range)
case OBJ_MISCELLANY:
did_work = true; // easier to do it this way for misc items
+ if (player_mutation_level(MUT_NO_ARTIFICE))
+ {
+ return mpr("You cannot evoke magical items."), false;
+ }
+
if (is_deck(item))
{
ASSERT(wielded);
diff --git a/crawl-ref/source/f038fe3d-1a59-40f9-9808-f4ae2e62bf42.dmp b/crawl-ref/source/f038fe3d-1a59-40f9-9808-f4ae2e62bf42.dmp
new file mode 100644
index 0000000..23b4b54
Binary files /dev/null and b/crawl-ref/source/f038fe3d-1a59-40f9-9808-f4ae2e62bf42.dmp differ
diff --git a/crawl-ref/source/feature.cc b/crawl-ref/source/feature.cc
index 2c3fbd6..6cfe12c 100644
--- a/crawl-ref/source/feature.cc
+++ b/crawl-ref/source/feature.cc
@@ -137,6 +137,7 @@ static colour_t _feat_colour(dungeon_feature_type feat)
case DNGN_ALTAR_DITHMENOS: return ETC_DITHMENOS;
case DNGN_ALTAR_GOZAG: return ETC_GOLD; // for the Gold God!
case DNGN_ALTAR_QAZLAL: return ETC_ELEMENTAL;
+ case DNGN_ALTAR_IASHOL: return BROWN;
default: return 0;
}
}
diff --git a/crawl-ref/source/fineff.cc b/crawl-ref/source/fineff.cc
index 98af2ce..9869e82 100644
--- a/crawl-ref/source/fineff.cc
+++ b/crawl-ref/source/fineff.cc
@@ -10,6 +10,7 @@
#include "effects.h"
#include "env.h"
#include "fineff.h"
+#include "godabil.h"
#include "libutil.h"
#include "mgen_data.h"
#include "misc.h"
@@ -44,6 +45,13 @@ bool mirror_damage_fineff::mergeable(const final_effect &fe) const
return o && att == o->att && def == o->def;
}
+bool iashol_retribution_fineff::mergeable(const final_effect &fe) const
+{
+ const iashol_retribution_fineff *o =
+ dynamic_cast<const iashol_retribution_fineff *>(&fe);
+ return o && att == o->att && def == o->def;
+}
+
bool trample_follow_fineff::mergeable(const final_effect &fe) const
{
const trample_follow_fineff *o =
@@ -116,6 +124,14 @@ void mirror_damage_fineff::merge(const final_effect &fe)
damage += mdfe->damage;
}
+void iashol_retribution_fineff::merge(const final_effect &fe)
+{
+ const iashol_retribution_fineff *mdfe =
+ dynamic_cast<const iashol_retribution_fineff *>(&fe);
+ ASSERT(mdfe);
+ ASSERT(mergeable(*mdfe));
+}
+
void trj_spawn_fineff::merge(const final_effect &fe)
{
const trj_spawn_fineff *trjfe =
@@ -184,6 +200,17 @@ void mirror_damage_fineff::fire()
}
}
+void iashol_retribution_fineff::fire()
+{
+ actor *attack = attacker();
+ if (!attack || attack == defender() || !attack->alive())
+ return;
+ if (def == MID_PLAYER)
+ {
+ iashol_do_retribution(monster_by_mid(att), damage);
+ }
+}
+
void trample_follow_fineff::fire()
{
actor *attack = attacker();
diff --git a/crawl-ref/source/fineff.h b/crawl-ref/source/fineff.h
index 1d5a9f3..bcdb051 100644
--- a/crawl-ref/source/fineff.h
+++ b/crawl-ref/source/fineff.h
@@ -47,6 +47,20 @@ protected:
int damage;
};
+class iashol_retribution_fineff : public final_effect
+{
+public:
+ iashol_retribution_fineff(const actor *attack, const actor *defend, int dam)
+ : final_effect(attack, defend, coord_def()), damage(dam)
+ {
+ }
+ bool mergeable(const final_effect &a) const;
+ void merge(const final_effect &a);
+ void fire();
+protected:
+ int damage;
+};
+
class trample_follow_fineff : public final_effect
{
public:
diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc
index 132e02e..9b96cf5 100644
--- a/crawl-ref/source/godabil.cc
+++ b/crawl-ref/source/godabil.cc
@@ -10,6 +10,7 @@
#include "areas.h"
#include "artefact.h"
+#include "ability.h"
#include "beam.h"
#include "branch.h"
#include "cloud.h"
@@ -4748,3 +4749,787 @@ bool qazlal_disaster_area()
return true;
}
+
+vector<ability_type> get_possible_sacrifices()
+{
+ vector<ability_type> possible_sacrifices;
+
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_PURITY);
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_ESSENCE);
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_HEALTH);
+
+ if (player_mutation_level(MUT_NO_AIR_MAGIC)
+ + player_mutation_level(MUT_NO_CHARM_MAGIC)
+ + player_mutation_level(MUT_NO_CONJURATION_MAGIC)
+ + player_mutation_level(MUT_NO_EARTH_MAGIC)
+ + player_mutation_level(MUT_NO_FIRE_MAGIC)
+ + player_mutation_level(MUT_NO_HEXES_MAGIC)
+ + player_mutation_level(MUT_NO_ICE_MAGIC)
+ + player_mutation_level(MUT_NO_NECROMANCY_MAGIC)
+ + player_mutation_level(MUT_NO_POISON_MAGIC)
+ + player_mutation_level(MUT_NO_SUMMONING_MAGIC)
+ + player_mutation_level(MUT_NO_TRANSLOCATION_MAGIC)
+ + player_mutation_level(MUT_NO_TRANSMUTATION_MAGIC)
+ < 6)
+ {
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_ARCANA);
+ }
+ if (!player_mutation_level(MUT_NO_READ))
+ {
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_WORDS);
+ }
+ if (!player_mutation_level(MUT_NO_DRINK))
+ {
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_DRINK);
+ }
+ if (!player_mutation_level(MUT_NO_STEALTH))
+ {
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_STEALTH);
+ }
+ if (!player_mutation_level(MUT_NO_ARTIFICE))
+ {
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_ARTIFICE);
+ }
+ if (!player_mutation_level(MUT_NO_LOVE))
+ {
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_LOVE);
+ }
+ if (!player_mutation_level(MUT_FEAR_BLOOD))
+ {
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_SANITY);
+ }
+ if (!player_mutation_level(MUT_NO_DODGING))
+ {
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_NIMBLENESS);
+ }
+ if (!player_mutation_level(MUT_NO_ARMOUR))
+ {
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_DURABILITY);
+ }
+ if (!player_mutation_level(MUT_MISSING_HAND))
+ {
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_HAND);
+ }
+
+ return possible_sacrifices;
+}
+
+const char* arcane_mutation_to_school_name(mutation_type mutation)
+{
+ switch (mutation)
+ {
+ case MUT_NO_AIR_MAGIC:
+ return "Air Magic";
+ case MUT_NO_CHARM_MAGIC:
+ return "Charms";
+ case MUT_NO_CONJURATION_MAGIC:
+ return "Conjurations";
+ case MUT_NO_EARTH_MAGIC:
+ return "Earth Magic";
+ case MUT_NO_FIRE_MAGIC:
+ return "Fire Magic";
+ case MUT_NO_HEXES_MAGIC:
+ return "Hexes";
+ case MUT_NO_ICE_MAGIC:
+ return "Ice Magic";
+ case MUT_NO_NECROMANCY_MAGIC:
+ return "Necromancy";
+ case MUT_NO_POISON_MAGIC:
+ return "Poison Magic";
+ case MUT_NO_SUMMONING_MAGIC:
+ return "Summoning";
+ case MUT_NO_TRANSLOCATION_MAGIC:
+ return "Translocations";
+ case MUT_NO_TRANSMUTATION_MAGIC:
+ return "Transmutations";
+ default:
+ return "N/A";
+ }
+}
+
+const skill_type arcane_mutation_to_skill(mutation_type mutation)
+{
+ switch (mutation)
+ {
+ case MUT_NO_AIR_MAGIC:
+ return SK_AIR_MAGIC;
+ case MUT_NO_CHARM_MAGIC:
+ return SK_CHARMS;
+ case MUT_NO_CONJURATION_MAGIC:
+ return SK_CONJURATIONS;
+ case MUT_NO_EARTH_MAGIC:
+ return SK_EARTH_MAGIC;
+ case MUT_NO_FIRE_MAGIC:
+ return SK_FIRE_MAGIC;
+ case MUT_NO_HEXES_MAGIC:
+ return SK_HEXES;
+ case MUT_NO_ICE_MAGIC:
+ return SK_ICE_MAGIC;
+ case MUT_NO_NECROMANCY_MAGIC:
+ return SK_NECROMANCY;
+ case MUT_NO_POISON_MAGIC:
+ return SK_POISON_MAGIC;
+ case MUT_NO_SUMMONING_MAGIC:
+ return SK_SUMMONINGS;
+ case MUT_NO_TRANSLOCATION_MAGIC:
+ return SK_TRANSLOCATIONS;
+ case MUT_NO_TRANSMUTATION_MAGIC:
+ return SK_TRANSMUTATIONS;
+ default:
+ return SK_NONE;
+ }
+}
+
+// Pick three new sacrifices to offer to the player. They should be distinct
+// from one another and not offer duplicates of some options. Ideally we'll
+// offer three "tiers" of sacrifices, but right now we mostly have two tiers.
+// Since these sacrifices will be abilities, we also need to set up those
+// abilities and the descriptions of them, so players know what they're
+// getting into.
+void iashol_offer_new_sacrifices()
+{
+ iashol_expire_sacrifices();
+
+ vector<ability_type> possible_sacrifices = get_possible_sacrifices();
+
+ //for now we'll just pick three at random
+ int num_sacrifices = possible_sacrifices.size();
+
+ // try to get three distinct sacrifices
+ int lesser_sacrifice = random2(num_sacrifices);
+ int sacrifice = -1;
+ int greater_sacrifice = -1;
+
+ do {
+ sacrifice = random2(num_sacrifices);
+ } while (sacrifice == -1 || sacrifice == lesser_sacrifice);
+
+ do {
+ greater_sacrifice = random2(num_sacrifices);
+ } while (greater_sacrifice == -1 || greater_sacrifice == lesser_sacrifice
+ || greater_sacrifice == sacrifice);
+
+ // set the new abilities
+ you.available_sacrifices.push_back(
+ possible_sacrifices[lesser_sacrifice]);
+ you.available_sacrifices.push_back(
+ possible_sacrifices[sacrifice]);
+ you.available_sacrifices.push_back(
+ possible_sacrifices[greater_sacrifice]);
+
+ if (possible_sacrifices[lesser_sacrifice] == ABIL_IASHOL_SACRIFICE_HEALTH
+ || possible_sacrifices[sacrifice] == ABIL_IASHOL_SACRIFICE_HEALTH
+ || possible_sacrifices[greater_sacrifice] == ABIL_IASHOL_SACRIFICE_HEALTH)
+ {
+ switch (random2(3)) {
+ case 0:
+ you.current_health_sacrifice.push_back(
+ MUT_PHYSICAL_VULNERABILITY);
+ mpr("phys vuln");
+ break;
+ case 1:
+ you.current_health_sacrifice.push_back(MUT_SLOW_REFLEXES);
+ mpr("slow reflexes");
+ break;
+ case 2:
+ you.current_health_sacrifice.push_back(MUT_FRAIL);
+ mpr("frail");
+ break;
+ }
+ }
+
+ if (possible_sacrifices[lesser_sacrifice] == ABIL_IASHOL_SACRIFICE_ESSENCE
+ || possible_sacrifices[sacrifice] == ABIL_IASHOL_SACRIFICE_ESSENCE
+ || possible_sacrifices[greater_sacrifice] == ABIL_IASHOL_SACRIFICE_ESSENCE)
+ {
+ switch (random2(3)) {
+ case 0:
+ you.current_essence_sacrifice.push_back(MUT_ANTI_WIZARDRY);
+ mpr("Anti-wiz");
+ break;
+ case 1:
+ you.current_essence_sacrifice.push_back(
+ MUT_MAGICAL_VULNERABILITY);
+ mpr("Magic vulnerable");
+ break;
+ case 2:
+ you.current_essence_sacrifice.push_back(MUT_LOW_MAGIC);
+ mpr("Low Magic");
+ break;
+ }
+ }
+
+ if (possible_sacrifices[lesser_sacrifice] == ABIL_IASHOL_SACRIFICE_PURITY
+ || possible_sacrifices[sacrifice] == ABIL_IASHOL_SACRIFICE_PURITY
+ || possible_sacrifices[greater_sacrifice] == ABIL_IASHOL_SACRIFICE_PURITY)
+ {
+ switch (random2(7)) {
+ case 0:
+ you.current_purity_sacrifice.push_back(MUT_DETERIORATION);
+ mpr("deterioration");
+ break;
+ case 1:
+ you.current_purity_sacrifice.push_back(MUT_SCREAM);
+ mpr("scream");
+ break;
+ case 2:
+ you.current_purity_sacrifice.push_back(MUT_DEFORMED);
+ mpr("deformed");
+ break;
+ case 3:
+ you.current_purity_sacrifice.push_back(MUT_SLOW_HEALING);
+ mpr("slow healing");
+ break;
+ case 4:
+ you.current_purity_sacrifice.push_back(MUT_DOPEY);
+ mpr("dopey");
+ break;
+ case 5:
+ you.current_purity_sacrifice.push_back(MUT_CLUMSY);
+ mpr("clumsy");
+ break;
+ case 6:
+ you.current_purity_sacrifice.push_back(MUT_WEAK);
+ mpr("weak");
+ break;
+ }
+ }
+
+ if (possible_sacrifices[lesser_sacrifice] == ABIL_IASHOL_SACRIFICE_ARCANA
+ || possible_sacrifices[sacrifice] == ABIL_IASHOL_SACRIFICE_ARCANA
+ || possible_sacrifices[greater_sacrifice] == ABIL_IASHOL_SACRIFICE_ARCANA)
+ {
+ vector<mutation_type> possible_minor_mutations;
+ vector<mutation_type> possible_medium_mutations;
+ vector<mutation_type> possible_major_mutations;
+ int num_major_mutations;
+ int num_medium_mutations;
+ int num_minor_mutations;
+
+ if (!player_mutation_level(MUT_NO_CHARM_MAGIC))
+ possible_major_mutations.push_back(MUT_NO_CHARM_MAGIC);
+ if (!player_mutation_level(MUT_NO_CONJURATION_MAGIC))
+ possible_major_mutations.push_back(MUT_NO_CONJURATION_MAGIC);
+ if (!player_mutation_level(MUT_NO_SUMMONING_MAGIC))
+ possible_major_mutations.push_back(MUT_NO_SUMMONING_MAGIC);
+ if (!player_mutation_level(MUT_NO_TRANSLOCATION_MAGIC))
+ possible_major_mutations.push_back(MUT_NO_TRANSLOCATION_MAGIC);
+ num_major_mutations = possible_major_mutations.size();
+ you.current_arcane_sacrifices.push_back(
+ possible_major_mutations[random2(num_major_mutations)]);
+
+ if (!player_mutation_level(MUT_NO_TRANSMUTATION_MAGIC))
+ possible_medium_mutations.push_back(MUT_NO_TRANSMUTATION_MAGIC);
+ if (!player_mutation_level(MUT_NO_NECROMANCY_MAGIC))
+ possible_medium_mutations.push_back(MUT_NO_NECROMANCY_MAGIC);
+ if (!player_mutation_level(MUT_NO_HEXES_MAGIC))
+ possible_medium_mutations.push_back(MUT_NO_HEXES_MAGIC);
+ num_medium_mutations = possible_medium_mutations.size();
+ you.current_arcane_sacrifices.push_back(
+ possible_medium_mutations[random2(num_medium_mutations)]);
+
+ if (!player_mutation_level(MUT_NO_AIR_MAGIC))
+ possible_minor_mutations.push_back(MUT_NO_AIR_MAGIC);
+ if (!player_mutation_level(MUT_NO_EARTH_MAGIC))
+ possible_minor_mutations.push_back(MUT_NO_EARTH_MAGIC);
+ if (!player_mutation_level(MUT_NO_FIRE_MAGIC))
+ possible_minor_mutations.push_back(MUT_NO_FIRE_MAGIC);
+ if (!player_mutation_level(MUT_NO_ICE_MAGIC))
+ possible_minor_mutations.push_back(MUT_NO_ICE_MAGIC);
+ if (!player_mutation_level(MUT_NO_POISON_MAGIC))
+ possible_minor_mutations.push_back(MUT_NO_POISON_MAGIC);
+ num_minor_mutations = possible_minor_mutations.size();
+ you.current_arcane_sacrifices.push_back(
+ possible_minor_mutations[random2(num_minor_mutations)]);
+ }
+}
+
+void iashol_do_sacrifice(ability_type sacrifice)
+{
+ skill_type mutation_skill;
+ int arcane_mutations_size;
+
+ switch (sacrifice)
+ {
+ case ABIL_IASHOL_SACRIFICE_PURITY:
+ mprf("Iashol asks you to corrupt yourself with %s.",
+ mutation_name(you.current_purity_sacrifice[0]));
+ if (!yesno("Do you really want to do make this sacrifice?",
+ false, 'n'))
+ {
+ canned_msg(MSG_OK);
+ return;
+ } else {
+ perma_mutate(you.current_purity_sacrifice[0],
+ 1, "Iashol sacrifice");
+ }
+ if (you.current_purity_sacrifice[0] == MUT_WEAK
+ || you.current_purity_sacrifice[0] == MUT_CLUMSY
+ || you.current_purity_sacrifice[0] == MUT_DOPEY)
+ gain_piety(10 + random2(5));
+ else
+ gain_piety(25 + random2(5));
+ break;
+ case ABIL_IASHOL_SACRIFICE_WORDS:
+ if (!yesno("Do you really want to do make this sacrifice?",
+ false, 'n'))
+ {
+ canned_msg(MSG_OK);
+ return;
+ } else {
+ perma_mutate(MUT_NO_READ, 1, "Iashol sacrifice");
+ }
+ gain_piety(35 + random2(5));
+ break;
+ case ABIL_IASHOL_SACRIFICE_DRINK:
+ if (!yesno("Do you really want to do make this sacrifice?",
+ false, 'n'))
+ {
+ canned_msg(MSG_OK);
+ return;
+ } else {
+ perma_mutate(MUT_NO_DRINK, 1, "Iashol sacrifice");
+ }
+ gain_piety(35 + random2(5));
+ break;
+ case ABIL_IASHOL_SACRIFICE_ESSENCE:
+ mprf("Iashol asks you to corrupt yourself with %s.",
+ mutation_name(you.current_essence_sacrifice[0]));
+ if (!yesno("Do you really want to do make this sacrifice?",
+ false, 'n'))
+ {
+ canned_msg(MSG_OK);
+ return;
+ } else {
+ perma_mutate(you.current_essence_sacrifice[0],
+ 1, "Iashol sacrifice");
+ }
+ gain_piety(30 + random2(5));
+ break;
+ case ABIL_IASHOL_SACRIFICE_HEALTH:
+ mprf("Iashol asks you to corrupt yourself with %s.",
+ mutation_name(you.current_health_sacrifice[0]));
+ if (!yesno("Do you really want to do make this sacrifice?",
+ false, 'n'))
+ {
+ canned_msg(MSG_OK);
+ return;
+ } else {
+ perma_mutate(you.current_health_sacrifice[0],
+ 1, "Iashol sacrifice");
+ }
+ gain_piety(30 + random2(5));
+ break;
+ case ABIL_IASHOL_SACRIFICE_STEALTH:
+ if (!yesno("Do you really want to do make this sacrifice?",
+ false, 'n'))
+ {
+ canned_msg(MSG_OK);
+ return;
+ } else {
+ perma_mutate(MUT_NO_STEALTH, 1, "Iashol sacrifice");
+ }
+ gain_piety(div_rand_round(skill_exp_needed(
+ you.skills[SK_STEALTH], SK_STEALTH, SP_HUMAN), 50));
+
+ // zero out useless skills
+ you.skills[SK_STEALTH] = 0;
+ gain_piety(30 + div_rand_round(skill_exp_needed(
+ you.skills[SK_STEALTH], SK_STEALTH, SP_HUMAN), 50));
+ break;
+ case ABIL_IASHOL_SACRIFICE_ARTIFICE:
+ if (!yesno("Do you really want to do make this sacrifice?",
+ false, 'n'))
+ {
+ canned_msg(MSG_OK);
+ return;
+ } else {
+ perma_mutate(MUT_NO_ARTIFICE, 1, "Iashol sacrifice");
+ }
+ gain_piety(div_rand_round(skill_exp_needed(
+ you.skills[SK_EVOCATIONS], SK_EVOCATIONS, SP_HUMAN), 50));
+
+ // zero out useless skills
+ you.skills[SK_EVOCATIONS] = 0;
+ gain_piety(40 + div_rand_round(skill_exp_needed(
+ you.skills[SK_EVOCATIONS], SK_EVOCATIONS, SP_HUMAN), 50));
+ break;
+ case ABIL_IASHOL_SACRIFICE_LOVE:
+ if (!yesno("Do you really want to do make this sacrifice?",
+ false, 'n'))
+ {
+ canned_msg(MSG_OK);
+ return;
+ } else {
+ perma_mutate(MUT_NO_LOVE, 1, "Iashol sacrifice");
+ }
+ gain_piety(25 + random2(5) + div_rand_round(skill_exp_needed(
+ you.skills[SK_SUMMONINGS], SK_SUMMONINGS, SP_HUMAN), 50));
+ break;
+ case ABIL_IASHOL_SACRIFICE_SANITY:
+ if (!yesno("Do you really want to do make this sacrifice?",
+ false, 'n'))
+ {
+ canned_msg(MSG_OK);
+ return;
+ } else {
+ perma_mutate(MUT_FEAR_BLOOD, 1, "Iashol sacrifice");
+ }
+ gain_piety(25 + random2(5));
+ break;
+ case ABIL_IASHOL_SACRIFICE_ARCANA:
+ mprf("Iashol asks you to sacrifice all use of %s, %s, and %s.",
+ arcane_mutation_to_school_name(
+ you.current_arcane_sacrifices[0]),
+ arcane_mutation_to_school_name(
+ you.current_arcane_sacrifices[1]),
+ arcane_mutation_to_school_name(
+ you.current_arcane_sacrifices[2])
+ );
+ if (!yesno("Do you want to accept this sacrifice? ",
+ true, 'n'))
+ {
+ canned_msg(MSG_OK);
+ return;
+ }
+
+ arcane_mutations_size = you.current_arcane_sacrifices.size();
+ for (int i = 0; i < arcane_mutations_size; ++i) {
+ perma_mutate(you.current_arcane_sacrifices[i], 1,
+ "Iashol sacrifice");
+
+ // gain one piety for every 50 skill points
+ mutation_skill =
+ arcane_mutation_to_skill(you.current_arcane_sacrifices[i]);
+ gain_piety(div_rand_round(skill_exp_needed(
+ you.skills[mutation_skill], mutation_skill, SP_HUMAN), 50));
+
+ // zero out useless skills
+ you.skills[mutation_skill] = 0;
+ }
+ break;
+ case ABIL_IASHOL_SACRIFICE_NIMBLENESS:
+ if (!yesno("Do you really want to do make this sacrifice?",
+ false, 'n'))
+ {
+ canned_msg(MSG_OK);
+ return;
+ } else {
+ perma_mutate(MUT_NO_DODGING, 1, "Iashol sacrifice");
+ }
+ gain_piety(div_rand_round(skill_exp_needed(
+ you.skills[SK_DODGING], SK_DODGING, SP_HUMAN), 50));
+
+ // zero out useless skills
+ you.skills[SK_DODGING] = 0;
+ gain_piety(30 + div_rand_round(skill_exp_needed(
+ you.skills[SK_DODGING], SK_DODGING, SP_HUMAN), 50));
+ break;
+ case ABIL_IASHOL_SACRIFICE_DURABILITY:
+ if (!yesno("Do you really want to do make this sacrifice?",
+ false, 'n'))
+ {
+ canned_msg(MSG_OK);
+ return;
+ } else {
+ perma_mutate(MUT_NO_ARMOUR, 1, "Iashol sacrifice");
+ }
+ gain_piety(div_rand_round(skill_exp_needed(
+ you.skills[SK_ARMOUR], SK_ARMOUR, SP_HUMAN), 50));
+
+ // zero out useless skills
+ you.skills[SK_ARMOUR] = 0;
+ gain_piety(30 + div_rand_round(skill_exp_needed(
+ you.skills[SK_ARMOUR], SK_ARMOUR, SP_HUMAN), 50));
+ break;
+ case ABIL_IASHOL_SACRIFICE_HAND:
+ if (!yesno("Do you really want to do make this sacrifice?",
+ false, 'n'))
+ {
+ canned_msg(MSG_OK);
+ return;
+ } else {
+ perma_mutate(MUT_MISSING_HAND, 1, "Iashol sacrifice");
+ }
+ gain_piety(80 + div_rand_round(skill_exp_needed(
+ you.skills[SK_SHIELDS], SK_SHIELDS, SP_HUMAN), 50));
+ break;
+ default:
+ return;
+ break;
+ }
+ iashol_expire_sacrifices();
+}
+
+// Remove the offer of sacrifices after they've been offered for sufficient
+// time or it's time to offer something new.
+void iashol_expire_sacrifices()
+{
+ you.available_sacrifices.clear();
+ you.current_health_sacrifice.clear();
+ you.current_essence_sacrifice.clear();
+ you.current_purity_sacrifice.clear();
+ you.current_arcane_sacrifices.clear();
+}
+
+// Check to see if you're eligible to retaliate.
+//Your chance of eligiblity scales with piety.
+bool will_iashol_retaliate()
+{
+ // Scales up to a 33% chance of retribution
+ return you_worship(GOD_IASHOL)
+ && you.piety >= piety_breakpoint(2)
+ && crawl_state.which_god_acting() != GOD_IASHOL
+ && one_chance_in(div_rand_round(600, you.piety));
+}
+
+// Power of retribution increases with damage, decreases with monster HD.
+void iashol_do_retribution(monster* mons, int damage)
+{
+ int power = max(0, random2(div_rand_round(you.piety, 4))
+ + damage - (2 * mons->hit_dice));
+ const actor* act = &you;
+
+ if (power > 50)
+ {
+ simple_monster_message(mons, " is silenced in retribution by your aura!");
+ mons->add_ench(mon_enchant(ENCH_MUTE, 1, act, power+random2(120)));
+ }
+ else if (power > 35)
+ {
+ simple_monster_message(mons, " is paralyzed in retribution by your aura!");
+ mons->add_ench(mon_enchant(ENCH_PARALYSIS, 1, act, power+random2(60)));
+ }
+ else if (power > 25)
+ {
+ simple_monster_message(mons, " is slowed in retribution by your aura!");
+ mons->add_ench(mon_enchant(ENCH_SLOW, 1, act, power+random2(100)));
+ }
+ else if (power > 15)
+ {
+ simple_monster_message(mons, " is blinded in retribution by your aura!");
+ mons->add_ench(mon_enchant(ENCH_BLIND, 1, act, power+random2(100)));
+ }
+ else if (power > 0)
+ {
+ simple_monster_message(mons, " is illuminated in retribution by your aura!");
+ mons->add_ench(mon_enchant(ENCH_CORONA, 1, act, power+random2(150)));
+ }
+}
+
+void iashol_draw_out_power()
+{
+ mpr("You are restored by drawing out deep reserves of power within.");
+ inc_hp(div_rand_round(you.piety, 20)
+ + roll_dice(div_rand_round(you.piety, 25), 5));
+ inc_mp(div_rand_round(you.piety, 60)
+ + roll_dice(div_rand_round(you.piety, 50), 3));
+ drain_exp(false, 20, true);
+}
+
+bool iashol_power_leap()
+{
+ ASSERT(!crawl_state.game_is_arena());
+
+ dist beam;
+
+ if (crawl_state.is_repeating_cmd())
+ {
+ crawl_state.cant_cmd_repeat("You can't repeat power leaps.");
+ crawl_state.cancel_cmd_again();
+ crawl_state.cancel_cmd_repeat();
+ return false;
+ }
+
+ // query for location:
+ while (1)
+ {
+ direction_chooser_args args;
+ args.restricts = DIR_TARGET;
+ args.needs_path = false;
+ args.may_target_monster = false;
+ args.top_prompt = "Leap to where?";
+ args.range = 3;
+ direction(beam, args);
+
+ if (crawl_state.seen_hups)
+ {
+ mpr("Cancelling jump due to HUP.");
+ return false;
+ }
+
+ if (!beam.isValid || beam.target == you.pos())
+ {
+ return false; // early return
+ }
+
+ monster* beholder = you.get_beholder(beam.target);
+ if (beholder)
+ {
+ mprf("You cannot leap away from %s!",
+ beholder->name(DESC_THE, true).c_str());
+ continue;
+ }
+
+ monster* fearmonger = you.get_fearmonger(beam.target);
+ if (fearmonger)
+ {
+ mprf("You cannot leap closer to %s!",
+ fearmonger->name(DESC_THE, true).c_str());
+ continue;
+ }
+
+ if (grd(beam.target) == DNGN_OPEN_SEA)
+ {
+ mesclr();
+ mpr("You can't leap into the sea!");
+ }
+ else if (grd(beam.target) == DNGN_LAVA_SEA)
+ {
+ mesclr();
+ mpr("You can't leap into the sea of lava!");
+ }
+ else if (!check_moveto(beam.target, "blink"))
+ {
+ // try again (messages handled by check_moveto)
+ }
+ else if (you.see_cell_no_trans(beam.target))
+ {
+ // Grid in los, no problem.
+ break;
+ }
+ else if (you.trans_wall_blocking(beam.target))
+ {
+ mesclr();
+ mpr("There's something in the way!");
+ }
+ else
+ {
+ mesclr();
+ mpr("You can only blink to visible locations.");
+ }
+ }
+
+ bool return_val = false;
+
+ if (you.attempt_escape(2)) // I'm hoping this returns true if not constrict
+ {
+ if (cell_is_solid(beam.target) || monster_at(beam.target))
+ {
+ mpr("Something unexpectedly blocked you, preventing you from leaping!");
+ }
+ else
+ {
+ move_player_to_grid(beam.target, false);
+ }
+
+ crawl_state.cancel_cmd_again();
+ crawl_state.cancel_cmd_repeat();
+ return_val = true;
+
+ }
+
+ bolt wave;
+ wave.thrower = KILL_YOU;
+ wave.name = "power leap";
+ wave.source_name = "you";
+ wave.beam_source = you.mindex();
+ wave.flavour = BEAM_VISUAL;
+ wave.colour = BROWN;
+ wave.glyph = dchar_glyph(DCHAR_EXPLOSION);
+ wave.range = 1;
+ wave.ex_size = 1;
+ wave.is_explosion = true;
+ wave.source = you.pos();
+ wave.target = you.pos();
+ wave.hit = AUTOMATIC_HIT;
+ //wave.damage = dice_def(3, div_rand_round(you.piety, 3));
+ wave.loudness = 4;
+ wave.explode();
+
+ // we need to exempt the player from damage.
+ for (adjacent_iterator ai(you.pos(), false); ai; ++ai)
+ {
+ monster* mon = monster_at(*ai);
+ if (mon == NULL || mons_is_projectile(mon->type) || mon->friendly())
+ {
+ continue;
+ }
+ ASSERT(mon);
+
+ mon->hurt((actor*)&you, roll_dice(div_rand_round(you.piety, 9), 3),
+ BEAM_MMISSILE, true);
+ }
+
+ return return_val;
+}
+
+static int _cataclysmable(coord_def where, int pow, int, actor* agent)
+{
+ monster* mon = monster_at(where);
+ if (mon == NULL || mons_is_projectile(mon->type) || mon->friendly())
+ {
+ return 0;
+ }
+ return 1;
+}
+
+static int _apply_cataclysm(coord_def where, int pow, int dummy, actor* agent)
+{
+ if (!_cataclysmable(where, pow, dummy, agent))
+ return 0;
+ monster* mons = monster_at(where);
+
+ ASSERT(mons);
+
+ int dmg;
+
+ int effect = random2(6);
+ switch (effect)
+ {
+ case 0:
+ simple_monster_message(mons, " silenced by your wave of power!");
+ mons->add_ench(mon_enchant(ENCH_MUTE, 1, agent, 120 + random2(120)));
+ dmg = roll_dice(div_rand_round(pow, 10), 4);
+ break;
+
+ case 1:
+ simple_monster_message(mons, " is paralyzed by your wave of power!");
+ mons->add_ench(mon_enchant(ENCH_PARALYSIS, 1, agent, 60 + random2(60)));
+ dmg = roll_dice(div_rand_round(pow, 10), 4);
+ break;
+
+ case 2:
+ simple_monster_message(mons, " is slowed by your wave of power!");
+ mons->add_ench(mon_enchant(ENCH_SLOW, 1, agent, 100 + random2(100)));
+ dmg = roll_dice(div_rand_round(pow, 10), 5);
+ break;
+
+ case 3:
+ case 4:
+ case 5:
+ dmg = roll_dice(div_rand_round(pow, 10), 6);
+ break;
+ }
+ mons->hurt(agent, dmg, BEAM_MMISSILE, true);
+
+ return 1;
+}
+
+bool iashol_cataclysm()
+{
+ int count = apply_area_visible(_cataclysmable, you.piety, &you);
+ if (!count)
+ {
+ if (!yesno("There are no visible enemies. Unleash your cataclysm anyway?",
+ true, 'n'))
+ {
+ return false;
+ }
+ }
+ mpr("You release an incredible wave of power!");
+
+ apply_area_visible(_apply_cataclysm, you.piety, &you);
+ drain_exp(false, 50, true);
+ return true;
+}
\ No newline at end of file
diff --git a/crawl-ref/source/godabil.h b/crawl-ref/source/godabil.h
index 01b967d..89e6521 100644
--- a/crawl-ref/source/godabil.h
+++ b/crawl-ref/source/godabil.h
@@ -99,4 +99,16 @@ bool gozag_bribe_branch();
bool qazlal_upheaval(coord_def target, bool quiet = false);
void qazlal_elemental_force();
bool qazlal_disaster_area();
+
+const skill_type arcane_mutation_to_skill(mutation_type mutation);
+const char* arcane_mutation_to_school_name(mutation_type mutation);
+vector<ability_type> get_possible_sacrifices();
+void iashol_offer_new_sacrifices();
+void iashol_do_sacrifice(ability_type sacrifice);
+void iashol_expire_sacrifices();
+bool will_iashol_retaliate();
+void iashol_do_retribution(monster* mons, int damage);
+void iashol_draw_out_power();
+bool iashol_power_leap();
+bool iashol_cataclysm();
#endif
diff --git a/crawl-ref/source/godconduct.cc b/crawl-ref/source/godconduct.cc
index 972ffab..e9731e4 100644
--- a/crawl-ref/source/godconduct.cc
+++ b/crawl-ref/source/godconduct.cc
@@ -1070,6 +1070,7 @@ bool did_god_conduct(conduct_type thing_done, int level, bool known,
}
break;
+ case DID_SACRIFICE_LOVE:
case DID_NOTHING:
case NUM_CONDUCTS:
break;
diff --git a/crawl-ref/source/godpassive.cc b/crawl-ref/source/godpassive.cc
index 5c1a7d4..88c4dd4 100644
--- a/crawl-ref/source/godpassive.cc
+++ b/crawl-ref/source/godpassive.cc
@@ -184,9 +184,15 @@ void ash_check_bondage(bool msg)
s = ET_SHIELD;
else if (i <= EQ_MAX_ARMOUR)
s = ET_ARMOUR;
+ // Missing hands mean fewer rings
+ else if (you.species != SP_OCTOPODE && i == EQ_LEFT_RING &&
+ player_mutation_level(MUT_MISSING_HAND))
+ continue;
// Octopodes don't count these slots:
else if (you.species == SP_OCTOPODE &&
- (i == EQ_LEFT_RING || i == EQ_RIGHT_RING))
+ ((i == EQ_LEFT_RING || i == EQ_RIGHT_RING)
+ || (i == EQ_RING_EIGHT
+ && player_mutation_level(MUT_MISSING_HAND))))
continue;
// *Only* octopodes count these slots:
else if (you.species != SP_OCTOPODE && i > EQ_AMULET)
@@ -203,7 +209,8 @@ void ash_check_bondage(bool msg)
const item_def& item = you.inv[you.equip[i]];
if (item.cursed() && (i != EQ_WEAPON || is_weapon(item)))
{
- if (s == ET_WEAPON && _two_handed())
+ if (s == ET_WEAPON && (_two_handed() ||
+ player_mutation_level(MUT_MISSING_HAND)))
{
cursed[ET_WEAPON] = 3;
cursed[ET_SHIELD] = 3;
diff --git a/crawl-ref/source/hiscores.cc b/crawl-ref/source/hiscores.cc
index 88d9b77..d01af24 100644
--- a/crawl-ref/source/hiscores.cc
+++ b/crawl-ref/source/hiscores.cc
@@ -1605,6 +1605,7 @@ void scorefile_entry::init(time_t dt)
STATUS_MAGIC_SAPPED,
DUR_PORTAL_PROJECTILE,
DUR_NO_POTIONS,
+ DUR_NO_SCROLLS,
#if TAG_MAJOR_VERSION == 34
STATUS_GOLDEN,
#endif
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index c23f0cb..4abe6d5 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -76,6 +76,11 @@ bool can_wield(item_def *weapon, bool say_reason,
bool ignore_temporary_disability, bool unwield, bool only_known)
{
#define SAY(x) {if (say_reason) { x; }}
+ if (player_mutation_level(MUT_MISSING_HAND) && is_shield_incompatible(*weapon))
+ {
+ SAY(mpr("You can't wield that without your missing limb."));
+ return false;
+ }
if (!ignore_temporary_disability && you.berserk())
{
@@ -1619,6 +1624,12 @@ void zap_wand(int slot)
return;
}
+ if (player_mutation_level(MUT_NO_ARTIFICE))
+ {
+ mpr("You cannot evoke magical items.");
+ return;
+ }
+
if (slot != -1)
item_slot = slot;
else
@@ -2621,6 +2632,12 @@ void read_scroll(int slot)
return;
}
+ if (you.duration[DUR_NO_SCROLLS])
+ {
+ mpr("You cannot read scrolls in your current state!");
+ return;
+ }
+
if (inv_count() < 1)
{
canned_msg(MSG_NOTHING_CARRIED);
diff --git a/crawl-ref/source/main.cc b/crawl-ref/source/main.cc
index b68e045..b8d4b97 100644
--- a/crawl-ref/source/main.cc
+++ b/crawl-ref/source/main.cc
@@ -2326,6 +2326,41 @@ void world_reacts()
// All markers should be activated at this point.
ASSERT(!env.markers.need_activate());
+ // If the player fears blood, horrify them in proportion to the blood
+ if (player_mutation_level(MUT_FEAR_BLOOD)) {
+ const coord_def& center = you.pos();
+ const int radius = 8;
+ int blood_count = 0;
+
+ for (radius_iterator ri(center, radius, C_POINTY); ri; ++ri)
+ {
+ const coord_def pos = *ri;
+
+ if (testbits(env.pgrid(pos), FPROP_BLOODY) && you.see_cell(pos))
+ blood_count++;
+ }
+
+ if (blood_count) {
+ you.props["horror_penalty"] = blood_count;
+ you.set_duration(DUR_HORROR, 1);
+ if (blood_count > 4)
+ mpr("Blood! Blood everywhere! You have to get out of here!");
+ else if (blood_count > 2) {
+ mpr("You reel with horror. There's so much blood!");
+ } else {
+ mpr("You are horrified by the sight of blood!");
+ }
+ } else if (you.duration[DUR_HORROR]) {
+ you.props["horror_penalty"] = 0;
+ you.set_duration(DUR_HORROR, 0);
+ }
+ } else if (you.duration[DUR_HORROR]) {
+ // If the player somehow stops fearing blood, we need to handle that too
+ you.props["horror_penalty"] = 0;
+ you.set_duration(DUR_HORROR, 0);
+ mpr("The sight of blood no longer horrifies you.");
+ }
+
fire_final_effects();
if (crawl_state.viewport_monster_hp)
diff --git a/crawl-ref/source/mon-act.cc b/crawl-ref/source/mon-act.cc
index 5ce05a4..b83aa7c 100644
--- a/crawl-ref/source/mon-act.cc
+++ b/crawl-ref/source/mon-act.cc
@@ -2087,6 +2087,17 @@ void handle_monster_move(monster* mons)
}
}
+ if (!mons->asleep()
+ && !mons->wont_attack() && you_worship(GOD_IASHOL))
+ {
+ if (random2(100) < you.piety / 10)
+ {
+ simple_monster_message(mons, " falters in the face of your power.");
+ mons->speed_increment -= non_move_energy;
+ return;
+ }
+ }
+
if (crawl_state.disables[DIS_MON_ACT] && _unfriendly_or_insane(mons))
{
mons->speed_increment -= non_move_energy;
diff --git a/crawl-ref/source/mon-death.cc b/crawl-ref/source/mon-death.cc
index 4433ae2..efcf669 100644
--- a/crawl-ref/source/mon-death.cc
+++ b/crawl-ref/source/mon-death.cc
@@ -2053,6 +2053,15 @@ int monster_die(monster* mons, killer_type killer,
}
}
+ if (good_kill && you_worship(GOD_IASHOL) && one_chance_in(80)
+ && you.piety < 200)
+ {
+ iashol_offer_new_sacrifices();
+
+ simple_god_message(" believes you are ready to make a new sacrifice.");
+ more();
+ }
+
// Randomly bless a follower.
if (!created_friendly
&& gives_xp
diff --git a/crawl-ref/source/mon-place.cc b/crawl-ref/source/mon-place.cc
index e9971c0..03f7975 100644
--- a/crawl-ref/source/mon-place.cc
+++ b/crawl-ref/source/mon-place.cc
@@ -3713,6 +3713,11 @@ conduct_type player_will_anger_monster(monster_type type)
conduct_type player_will_anger_monster(monster* mon)
{
+ if (player_mutation_level(MUT_NO_LOVE))
+ {
+ // Player angers all monsters
+ return DID_SACRIFICE_LOVE;
+ }
if (is_good_god(you.religion) && mon->is_unholy())
return DID_UNHOLY;
if (is_good_god(you.religion) && mon->is_evil())
@@ -3771,6 +3776,9 @@ bool player_angers_monster(monster* mon)
case DID_SPELL_CASTING:
mprf("%s is enraged by your magic-hating god!", mname.c_str());
break;
+ case DID_SACRIFICE_LOVE:
+ mprf("%s can only feel hate for you!", mname.c_str());
+ break;
default:
mprf("%s is enraged by a buggy thing about you!", mname.c_str());
break;
diff --git a/crawl-ref/source/mutation-data.h b/crawl-ref/source/mutation-data.h
index 41fd9e4..eceebcb 100644
--- a/crawl-ref/source/mutation-data.h
+++ b/crawl-ref/source/mutation-data.h
@@ -1677,4 +1677,278 @@ static const mutation_def mut_data[] =
"cold-blooded"
},
-};
+{ MUT_NO_DRINK, 0, 1, true, false, false,
+ "cannot drink while threatened",
+
+ {"You cannot drink potions while threatened.", "", ""},
+ {"You no longer can drink potions while threatened.", "", ""},
+ {"You can once more drink potions while threatened.", "", ""},
+
+ "cannot drink while threatened"
+},
+
+{ MUT_NO_READ, 0, 1, true, false, false,
+ "cannot read",
+
+ {"You cannot read scrolls while threatened.", "", ""},
+ {"You can no longer read scrolls while threatened.", "", ""},
+ {"You can once more read scrolls while threatened.", "", ""},
+
+ "cannot read while threatened"
+},
+
+{ MUT_MISSING_HAND, 0, 1, true, false, false,
+ "missing a hand",
+
+ {"You are missing a hand.", "", ""},
+ {"One of your hands has vanished, leaving only a stump!", "", ""},
+ {"Your stump has regrown into a hand!", "", ""},
+
+ "missing a hand"
+},
+
+{ MUT_NO_STEALTH, 0, 1, true, false, false,
+ "no stealth",
+
+ {"You cannot be stealthy.", "", ""},
+ {"You can no longer be stealthy.", "", ""},
+ {"You can once more be stealthy.", "", ""},
+
+ "no stealth"
+},
+
+{ MUT_NO_ARTIFICE, 0, 1, true, false, false,
+ "cannot use devices",
+
+ {"You cannot study or use magical devices.", "", ""},
+ {"You can no longer study or use magical devices.", "", ""},
+ {"You can once more study and use magical devices.", "", ""},
+
+ "cannot use devices"
+},
+
+{ MUT_NO_LOVE, 0, 1, true, false, false,
+ "inspire hatred in others",
+
+ {"You are hated by all.", "", ""},
+ {"You are now hated by all.", "", ""},
+ {"You are no longer hated by all.", "", ""},
+
+ "inspire hatred"
+},
+
+{ MUT_FEAR_BLOOD, 0, 1, true, false, false,
+ "fear blood",
+
+ {"You are terrified of blood.", "", ""},
+ {"You have become terrified of blood.", "", ""},
+ {"You are no longer terrified of blood.", "", ""},
+
+ "fear blood"
+},
+
+{ MUT_NO_DODGING, 0, 1, true, false, false,
+ "cannot train Dodging",
+
+ {"You cannot train Dodging.", "", ""},
+ {"You can no longer train Dodging.", "", ""},
+ {"You can once more train Dodging.", "", ""},
+
+ "cannot train Dodging"
+},
+
+{ MUT_NO_ARMOUR, 0, 1, true, false, false,
+ "cannot train Armour",
+
+ {"You cannot train your Armour skill.", "", ""},
+ {"You can no longer train your Armour skill.", "", ""},
+ {"You can once more train your Armour skill.", "", ""},
+
+ "cannot train Armour"
+},
+
+{ MUT_NO_AIR_MAGIC, 0, 1, true, false, false,
+ "cannot use Air magic",
+
+ {"You cannot study or cast Air magic.", "", ""},
+ {"You can no longer study or cast Air magic.", "", ""},
+ {"You can once more study and cast Air magic.", "", ""},
+
+ "cannot use Air magic"
+},
+
+{ MUT_NO_CHARM_MAGIC, 0, 1, true, false, false,
+ "cannot use Charms magic",
+
+ {"You cannot study or cast Charms magic.", "", ""},
+ {"You can no longer study or cast Charms magic.", "", ""},
+ {"You can once more study and cast Charms magic.", "", ""},
+
+ "cannot use Charms magic"
+},
+
+{ MUT_NO_CONJURATION_MAGIC, 0, 1, true, false, false,
+ "cannot use Conjurations magic",
+
+ {"You cannot study or cast Conjurations magic.", "", ""},
+ {"You can no longer study or cast Conjurations magic.", "", ""},
+ {"You can once more study and cast Conjurations magic.", "", ""},
+
+ "cannot use Conjurations magic"
+},
+
+{ MUT_NO_EARTH_MAGIC, 0, 1, true, false, false,
+ "cannot use Earth magic",
+
+ {"You cannot study or cast Earth magic.", "", ""},
+ {"You can no longer study or cast Earth magic.", "", ""},
+ {"You can once more study and cast Earth magic.", "", ""},
+
+ "cannot use Earth magic"
+},
+
+{ MUT_NO_FIRE_MAGIC, 0, 1, true, false, false,
+ "cannot use Fire magic",
+
+ {"You cannot study or cast Fire magic.", "", ""},
+ {"You can no longer study or cast Fire magic.", "", ""},
+ {"You can once more study and cast Fire magic.", "", ""},
+
+ "cannot use Fire magic"
+},
+
+{ MUT_NO_HEXES_MAGIC, 0, 1, true, false, false,
+ "cannot use Hexes magic",
+
+ {"You cannot study or cast Hexes magic.", "", ""},
+ {"You can no longer study or cast Hexes magic.", "", ""},
+ {"You can once more study and cast Hexes magic.", "", ""},
+
+ "cannot use Hexes magic"
+},
+
+{ MUT_NO_ICE_MAGIC, 0, 1, true, false, false,
+ "cannot use Ice magic",
+
+ {"You cannot study or cast Ice magic.", "", ""},
+ {"You can no longer study or cast Ice magic.", "", ""},
+ {"You can once more study and cast Ice magic.", "", ""},
+
+ "cannot use Ice magic"
+},
+
+{ MUT_NO_NECROMANCY_MAGIC, 0, 1, true, false, false,
+ "cannot use Necromancy magic",
+
+ {"You cannot study or cast Necromancy magic.", "", ""},
+ {"You can no longer study or cast Necromancy magic.", "", ""},
+ {"You can once more study and cast Necromancy magic.", "", ""},
+
+ "cannot use fire magic"
+},
+
+{ MUT_NO_POISON_MAGIC, 0, 1, true, false, false,
+ "cannot use Poison magic",
+
+ {"You cannot study or cast Poison magic.", "", ""},
+ {"You can no longer study or cast Poison magic.", "", ""},
+ {"You can once more study and cast Poison magic.", "", ""},
+
+ "cannot use Poison magic"
+},
+
+{ MUT_NO_SUMMONING_MAGIC, 0, 1, true, false, false,
+ "cannot use Summoning magic",
+
+ {"You cannot study or cast Summoning magic.", "", ""},
+ {"You can no longer study or cast Summoning magic.", "", ""},
+ {"You can once more study and cast Summoning magic.", "", ""},
+
+ "cannot use Summoning magic"
+},
+
+{ MUT_NO_TRANSLOCATION_MAGIC, 0, 1, true, false, false,
+ "cannot use Translocations magic",
+
+ {"You cannot study or cast Translocations magic.", "", ""},
+ {"You can no longer study or cast Translocations magic.", "", ""},
+ {"You can once more study and cast Translocations magic.", "", ""},
+
+ "cannot use Translocations magic"
+},
+
+{ MUT_NO_TRANSMUTATION_MAGIC, 0, 1, true, false, false,
+ "cannot use Transmutations magic",
+
+ {"You cannot study or cast Transmutations magic.", "", ""},
+ {"You can no longer study or cast Transmutations magic.", "", ""},
+ {"You can once more study and cast Transmutations magic.", "", ""},
+
+ "cannot use Transmutations magic"
+},
+
+{ MUT_PHYSICAL_VULNERABILITY, 0, 3, true, false, false,
+ "take more damage",
+
+ {"You take slightly more damage. (-3 AC)",
+ "You take more damage. (-6 AC)",
+ "You take considerably more damage. (-9 AC)"},
+ {"You feel more vulnerable to harm.",
+ "You feel more vulnerable to harm.",
+ "You feel more vulnerable to harm."},
+ {"You no longer feel extra vulnerable to harm.",
+ "You feel less vulnerable to harm.",
+ "You feel less vulnerable to harm."},
+
+ "take more damage"
+},
+
+{ MUT_SLOW_REFLEXES, 0, 3, true, false, false,
+ "have slow reflexes",
+
+ {"You have somewhat slow reflexes. (-3 EV)",
+ "You have slow reflexes. (-6 EV)",
+ "You have very slow reflexes. (-9 EV)"},
+ {"Your reflexes slow.",
+ "Your reflexes slow further.",
+ "Your reflexes slow further."},
+ {"You reflexes return to normal.",
+ "You reflexes speed back up.",
+ "You reflexes speed back up."},
+
+ "have slow reflexes"
+},
+
+{ MUT_MAGICAL_VULNERABILITY, 0, 3, true, false, false,
+ "magic vulnerable",
+
+ {"You are slightly vulnerable to magic. (-20 MR)",
+ "You are vulnerable to magic. (-20 MR)",
+ "You are extremely vulnerable to magic. (-20 MR)"},
+ {"You feel vulnerable to magic.",
+ "You feel more vulnerable to magic.",
+ "You feel more vulnerable to magic."},
+ {"You no longer feel vulnerable to magic.",
+ "You feel less vulnerable to magic.",
+ "You feel less vulnerable to magic."},
+
+ "magic vulnerable"
+},
+
+{ MUT_ANTI_WIZARDRY, 0, 3, true, false, false,
+ "disrupted magic",
+
+ {"Your casting is slightly disrupted.",
+ "Your casting is disrupted.",
+ "Your casting is seriously disrupted."},
+ {"Your ability to control magic is disrupted.",
+ "Your ability to control magic is more disrupted.",
+ "Your ability to control magic is more disrupted."},
+ {"Your ability to control magic is no longer disrupted.",
+ "Your ability to control magic is less disrupted.",
+ "Your ability to control magic is less disrupted."},
+
+ "disrupted magic"
+},
+
+};
\ No newline at end of file
diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc
index 772a9da..2a7c31e 100644
--- a/crawl-ref/source/ouch.cc
+++ b/crawl-ref/source/ouch.cc
@@ -828,6 +828,22 @@ static void _yred_mirrors_injury(int dam, int death_source)
}
}
+static void _maybe_iashol_retribution(int dam, int death_source)
+{
+ if (will_iashol_retaliate())
+ {
+ // Cap damage to what was enough to kill you. Can matter if
+ // you have an extra kitty.
+ if (you.hp < 0)
+ dam += you.hp;
+
+ if (dam <= 0 || invalid_monster_index(death_source))
+ return;
+ (new iashol_retribution_fineff(
+ &menv[death_source], &you, dam))->schedule();
+ }
+}
+
static void _maybe_spawn_jellies(int dam, const char* aux,
kill_method_type death_type, int death_source)
{
@@ -1039,6 +1055,22 @@ void ouch(int dam, int death_source, kill_method_type death_type,
ait_hp_loss hpl(dam, death_type);
interrupt_activity(AI_HP_LOSS, &hpl);
+ if (dam > 0 && player_mutation_level(MUT_NO_DRINK))
+ {
+ if (one_chance_in(min(1, you.hp_max - dam*2))) {
+ you.increase_duration(DUR_NO_POTIONS, 1 + random2(dam), 30);
+ mpr("You feel threatened and lose the ability to drink potions!");
+ }
+ }
+
+ if (dam > 0 && player_mutation_level(MUT_NO_READ))
+ {
+ if (one_chance_in(min(1, you.hp_max - dam*2))) {
+ you.increase_duration(DUR_NO_SCROLLS, 1 + random2(dam), 30);
+ mpr("You feel threatened and lose the ability to read scrolls!");
+ }
+ }
+
if (dam > 0 && death_type != KILLED_BY_POISON)
you.check_awaken(500);
@@ -1120,6 +1152,7 @@ void ouch(int dam, int death_source, kill_method_type death_type,
damage_desc.c_str()));
_yred_mirrors_injury(dam, death_source);
+ _maybe_iashol_retribution(dam, death_source);
_maybe_spawn_jellies(dam, aux, death_type, death_source);
_maybe_fog(dam);
_powered_by_pain(dam);
diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc
index aa35531..f02c1c9 100644
--- a/crawl-ref/source/output.cc
+++ b/crawl-ref/source/output.cc
@@ -1073,6 +1073,7 @@ static void _get_status_lights(vector<status_light>& out)
DUR_BRILLIANCE,
DUR_MIGHT,
DUR_NO_POTIONS,
+ DUR_NO_SCROLLS,
#if TAG_MAJOR_VERSION == 34
STATUS_GOLDEN,
#endif
@@ -1082,6 +1083,7 @@ static void _get_status_lights(vector<status_light>& out)
DUR_QAZLAL_ELEC_RES,
// DUR_QAZLAL_AC intentionally omitted - shows as AC bonus
DUR_CORROSION,
+ DUR_HORROR,
};
status_info inf;
@@ -2617,6 +2619,7 @@ static string _status_mut_abilities(int sw)
DUR_DRAGON_CALL,
DUR_ABJURATION_AURA,
DUR_NO_POTIONS,
+ DUR_NO_SCROLLS,
#if TAG_MAJOR_VERSION == 34
STATUS_GOLDEN,
#endif
diff --git a/crawl-ref/source/player-act.cc b/crawl-ref/source/player-act.cc
index 86ce07d..b93b2b0 100644
--- a/crawl-ref/source/player-act.cc
+++ b/crawl-ref/source/player-act.cc
@@ -413,7 +413,9 @@ bool player::can_wield(const item_def& item, bool ignore_curse,
const bool two_handed = item.base_type == OBJ_UNASSIGNED
|| hands_reqd(item) == HANDS_TWO;
- if (two_handed && !ignore_shield && player_wearing_slot(EQ_SHIELD))
+ if (two_handed && (
+ (!ignore_shield && player_wearing_slot(EQ_SHIELD))
+ || player_mutation_level(MUT_MISSING_HAND)))
return false;
return could_wield(item, ignore_brand, ignore_transform);
diff --git a/crawl-ref/source/player-reacts.cc b/crawl-ref/source/player-reacts.cc
index 24cc6a7..357a232 100644
--- a/crawl-ref/source/player-reacts.cc
+++ b/crawl-ref/source/player-reacts.cc
@@ -737,6 +737,10 @@ static void _decrement_durations()
"You can drink potions again.",
0, NULL, MSGCH_RECOVERY);
+ _decrement_a_duration(DUR_NO_SCROLLS, delay,
+ "You can read scrolls again.",
+ 0, NULL, MSGCH_RECOVERY);
+
dec_slow_player(delay);
dec_exhaust_player(delay);
dec_haste_player(delay);
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index 69ee59f..3468033 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -659,14 +659,21 @@ bool you_can_wear(int eq, bool special_armour)
if (eq == EQ_RING_AMULET && player_equip_unrand(UNRAND_FINGER_AMULET))
return true;
- if (you.species == SP_FELID)
- return eq == EQ_LEFT_RING || eq == EQ_RIGHT_RING || eq == EQ_AMULET;
+ if (you.species == SP_FELID) {
+ if (player_mutation_level(MUT_MISSING_HAND))
+ return eq == EQ_LEFT_RING || eq == EQ_RIGHT_RING || eq == EQ_AMULET;
+ else
+ return eq == EQ_RIGHT_RING || eq == EQ_AMULET;
+ }
// Octopodes can wear soft helmets, eight rings, and an amulet.
if (you.species == SP_OCTOPODE)
{
if (special_armour && eq == EQ_HELMET)
return true;
+ else if (player_mutation_level(MUT_MISSING_HAND))
+ return eq >= EQ_RING_ONE && eq <= EQ_RING_SEVEN
+ || eq == EQ_AMULET || eq == EQ_WEAPON;
else
return eq >= EQ_RING_ONE && eq <= EQ_RING_EIGHT
|| eq == EQ_AMULET || eq == EQ_SHIELD || eq == EQ_WEAPON;
@@ -675,6 +682,11 @@ bool you_can_wear(int eq, bool special_armour)
switch (eq)
{
case EQ_LEFT_RING:
+ if (player_mutation_level(MUT_MISSING_HAND))
+ return false;
+ else
+ return true;
+
case EQ_RIGHT_RING:
case EQ_AMULET:
case EQ_CLOAK:
@@ -727,6 +739,8 @@ bool you_can_wear(int eq, bool special_armour)
{
return false;
}
+ if (player_mutation_level(MUT_MISSING_HAND))
+ return false;
return true;
case EQ_HELMET:
@@ -861,6 +875,12 @@ bool you_tran_can_wear(int eq, bool check_mutation)
}
}
+ if (player_mutation_level(MUT_MISSING_HAND)
+ && (eq == EQ_LEFT_RING
+ || eq == EQ_SHIELD
+ || eq == EQ_RING_SEVEN))
+ return false;
+
// No further restrictions.
if (you.form == TRAN_NONE
|| you.form == TRAN_LICH
@@ -2527,6 +2547,9 @@ static int _player_evasion_bonuses(ev_ignore_type evit)
if (you.form == TRAN_STATUE)
evbonus -= 10; // stiff and slow
+ if (player_mutation_level(MUT_SLOW_REFLEXES))
+ evbonus -= player_mutation_level(MUT_SLOW_REFLEXES) * 3;
+
return evbonus;
}
@@ -3708,7 +3731,8 @@ int check_stealth(void)
if (crawl_state.disables[DIS_MON_SIGHT])
return 1000;
- if (you.attribute[ATTR_SHADOWS] || you.berserk() || you.stat_zero[STAT_DEX])
+ if (you.attribute[ATTR_SHADOWS] || you.berserk() || you.stat_zero[STAT_DEX]
+ || player_mutation_level(MUT_NO_STEALTH))
return 0;
int stealth = you.dex() * 3;
@@ -4260,6 +4284,7 @@ void display_char_status()
STATUS_MAGIC_SAPPED,
DUR_PORTAL_PROJECTILE,
DUR_NO_POTIONS,
+ DUR_NO_SCROLLS,
#if TAG_MAJOR_VERSION == 34
STATUS_GOLDEN,
#endif
@@ -4269,6 +4294,7 @@ void display_char_status()
DUR_QAZLAL_ELEC_RES,
DUR_QAZLAL_AC,
DUR_CORROSION,
+ DUR_HORROR
};
status_info inf;
@@ -4426,6 +4452,9 @@ int slaying_bonus(weapon_property_type which_affected, bool ranged)
if (you.duration[DUR_SONG_OF_SLAYING])
ret += you.props["song_of_slaying_bonus"].get_int();
+ if (you.duration[DUR_HORROR])
+ ret += you.props["horror_penalty"].get_int();
+
return ret;
}
@@ -6772,7 +6801,8 @@ int player::armour_class() const
? 100 + _mut_level(MUT_THIN_METALLIC_SCALES, MUTACT_FULL) * 100 : 0; // +2, +3, +4
AC += _mut_level(MUT_YELLOW_SCALES, MUTACT_FULL)
? 100 + _mut_level(MUT_YELLOW_SCALES, MUTACT_FULL) * 100 : 0; // +2, +3, +4
-
+ AC -= player_mutation_level(MUT_PHYSICAL_VULNERABILITY)
+ ? player_mutation_level(MUT_PHYSICAL_VULNERABILITY) * 300 : 0; // +3, +6, +9
return AC / 100;
}
/**
@@ -7131,6 +7161,7 @@ int player_res_magic(bool calc_unid, bool temp)
// Mutations
rm += 40 * player_mutation_level(MUT_MAGIC_RESISTANCE);
+ rm -= 20 * player_mutation_level(MUT_MAGICAL_VULNERABILITY);
// transformations
if (you.form == TRAN_LICH && temp)
@@ -7546,6 +7577,8 @@ int player::has_usable_tail(bool allow_tran) const
// purpose of punching.
bool player::has_usable_offhand() const
{
+ if (player_mutation_level(MUT_MISSING_HAND))
+ return false;
if (player_wearing_slot(EQ_SHIELD))
return false;
@@ -7599,7 +7632,9 @@ int player::has_tentacles(bool allow_tran) const
return 0;
}
- if (species == SP_OCTOPODE)
+ if (species == SP_OCTOPODE && player_mutation_level(MUT_MISSING_HAND))
+ return 7;
+ else if (species == SP_OCTOPODE)
return 8;
return 0;
diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h
index a69a950..cafe7ab 100644
--- a/crawl-ref/source/player.h
+++ b/crawl-ref/source/player.h
@@ -189,6 +189,11 @@ public:
FixedVector<short, NUM_GODS> num_total_gifts;
FixedBitVector< NUM_GODS> one_time_ability_used;
FixedVector<uint8_t, NUM_GODS> piety_max;
+ vector<ability_type> available_sacrifices;
+ vector<mutation_type> current_arcane_sacrifices;
+ vector<mutation_type> current_purity_sacrifice;
+ vector<mutation_type> current_health_sacrifice;
+ vector<mutation_type> current_essence_sacrifice;
FixedVector<uint8_t, NUM_MUTATIONS> mutation;
FixedVector<uint8_t, NUM_MUTATIONS> innate_mutation;
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 16715d8..c884c08 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -352,6 +352,13 @@ const char* god_gain_power_messages[NUM_GODS][MAX_GOD_ABILITIES] =
"Your shadow now sometimes tangibly mimics your actions.",
"transform into a swirling mass of shadows"
},
+ //Iashol
+ { "You exude an aura of power that intimidates your foes.",
+ "Your aura of power can strike those that harm you.",
+ "use your power to heal your body and restore your magic",
+ "gather your power into a mighty leap",
+ "wreak a terrible wrath on all visible foes"
+ },
// Gozag
{ "petition Gozag for potion effects",
"fund merchants seeking to open stores in the dungeon",
@@ -490,6 +497,13 @@ const char* god_lose_power_messages[NUM_GODS][MAX_GOD_ABILITIES] =
"Your shadow no longer tangibly mimics your actions.",
"transform into a swirling mass of shadows"
},
+ //Iashol
+ { "You no longer exude an aura of power that intimidates your foes.",
+ "Your aura of power no longer strikes those that harm you.",
+ "use your power to heal your body and restore your magic",
+ "gather your power into a mighty leap",
+ "wreak a terrible wrath on all visible foes"
+ },
// Gozag
{ "petition Gozag for potion effects",
"fund merchants seeking to open stores in the dungeon",
@@ -2421,7 +2435,6 @@ bool do_god_gift(bool forced)
}
} // End of giving books.
break; // End of book gods.
-
case GOD_VEHUMET:
const int gifts = you.num_total_gifts[you.religion];
if (forced || !you.duration[DUR_VEHUMET_GIFT]
@@ -2534,6 +2547,7 @@ string god_name(god_type which_god, bool long_name)
case GOD_XOM: return "Xom";
case GOD_ASHENZARI: return "Ashenzari";
case GOD_DITHMENOS: return "Dithmenos";
+ case GOD_IASHOL: return "Iashol";
case GOD_GOZAG: return "Gozag";
case GOD_QAZLAL: return "Qazlal";
case GOD_JIYVA: // This is handled at the beginning of the function
diff --git a/crawl-ref/source/rltiles/dc-feat.txt b/crawl-ref/source/rltiles/dc-feat.txt
index 0e454e8..69a3a2c 100644
--- a/crawl-ref/source/rltiles/dc-feat.txt
+++ b/crawl-ref/source/rltiles/dc-feat.txt
@@ -621,6 +621,7 @@ gozag2
qazlal0 DNGN_ALTAR_QAZLAL
qazlal1
qazlal2
+iashol DNGN_ALTAR_IASHOL
unknown DNGN_UNKNOWN_ALTAR
%sdir dngn
diff --git a/crawl-ref/source/skills2.cc b/crawl-ref/source/skills2.cc
index 6c70c5b..05ec105 100644
--- a/crawl-ref/source/skills2.cc
+++ b/crawl-ref/source/skills2.cc
@@ -490,6 +490,32 @@ bool is_useless_skill(skill_type skill)
if (skill == SK_STABBING || skill == SK_TRAPS)
return true;
#endif
+ if (
+ (skill == SK_AIR_MAGIC && player_mutation_level(MUT_NO_AIR_MAGIC))
+ || (skill == SK_CHARMS && player_mutation_level(MUT_NO_CHARM_MAGIC))
+ || (skill == SK_CONJURATIONS
+ && player_mutation_level(MUT_NO_CONJURATION_MAGIC))
+ || (skill == SK_EARTH_MAGIC
+ && player_mutation_level(MUT_NO_EARTH_MAGIC))
+ || (skill == SK_FIRE_MAGIC && player_mutation_level(MUT_NO_FIRE_MAGIC))
+ || (skill == SK_HEXES && player_mutation_level(MUT_NO_HEXES_MAGIC))
+ || (skill == SK_ICE_MAGIC && player_mutation_level(MUT_NO_ICE_MAGIC))
+ || (skill == SK_NECROMANCY
+ && player_mutation_level(MUT_NO_NECROMANCY_MAGIC))
+ || (skill == SK_POISON_MAGIC
+ && player_mutation_level(MUT_NO_POISON_MAGIC))
+ || (skill == SK_SUMMONINGS
+ && player_mutation_level(MUT_NO_SUMMONING_MAGIC))
+ || (skill == SK_TRANSLOCATIONS
+ && player_mutation_level(MUT_NO_TRANSLOCATION_MAGIC))
+ || (skill == SK_TRANSMUTATIONS
+ && player_mutation_level(MUT_NO_TRANSMUTATION_MAGIC))
+ || (skill == SK_DODGING && player_mutation_level(MUT_NO_DODGING))
+ || (skill == SK_ARMOUR && player_mutation_level(MUT_NO_ARMOUR))
+ || (skill == SK_EVOCATIONS && player_mutation_level(MUT_NO_ARTIFICE))
+ || (skill == SK_STEALTH && player_mutation_level(MUT_NO_STEALTH))
+ )
+ return true;
return species_apt(skill) == -99;
}
diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc
index 177d9ba..311ac69 100644
--- a/crawl-ref/source/spl-cast.cc
+++ b/crawl-ref/source/spl-cast.cc
@@ -383,6 +383,10 @@ int spell_fail(spell_type spell)
}
chance2 += 7 * player_mutation_level(MUT_WILD_MAGIC);
+ chance2 += 4 * player_mutation_level(MUT_ANTI_WIZARDRY);
+
+ if (you.duration[DUR_HORROR])
+ chance2 += 3 * you.props["horror_penalty"].get_int();
if (player_equip_unrand(UNRAND_HIGH_COUNCIL))
chance2 += 7;
diff --git a/crawl-ref/source/spl-util.cc b/crawl-ref/source/spl-util.cc
index 6e34f60..6f3a1d3 100644
--- a/crawl-ref/source/spl-util.cc
+++ b/crawl-ref/source/spl-util.cc
@@ -1110,6 +1110,35 @@ bool spell_is_useless(spell_type spell, bool transient)
#endif
}
+ // Check for banned schools.
+ if (
+ (spell_typematch(spell, SPTYP_AIR
+ && player_mutation_level(MUT_NO_AIR_MAGIC)))
+ || (spell_typematch(spell, SPTYP_CHARMS
+ && player_mutation_level(MUT_NO_CHARM_MAGIC)))
+ || (spell_typematch(spell, SPTYP_CONJURATION
+ && player_mutation_level(MUT_NO_CONJURATION_MAGIC)))
+ || (spell_typematch(spell, SPTYP_EARTH
+ && player_mutation_level(MUT_NO_EARTH_MAGIC)))
+ || (spell_typematch(spell, SPTYP_FIRE
+ && player_mutation_level(MUT_NO_FIRE_MAGIC)))
+ || (spell_typematch(spell, SPTYP_HEXES
+ && player_mutation_level(MUT_NO_HEXES_MAGIC)))
+ || (spell_typematch(spell, SPTYP_ICE
+ && player_mutation_level(MUT_NO_ICE_MAGIC)))
+ || (spell_typematch(spell, SPTYP_NECROMANCY
+ && player_mutation_level(MUT_NO_NECROMANCY_MAGIC)))
+ || (spell_typematch(spell, SPTYP_POISON
+ && player_mutation_level(MUT_NO_POISON_MAGIC)))
+ || (spell_typematch(spell, SPTYP_SUMMONING
+ && player_mutation_level(MUT_NO_SUMMONING_MAGIC)))
+ || (spell_typematch(spell, SPTYP_TRANSLOCATION
+ && player_mutation_level(MUT_NO_TRANSLOCATION_MAGIC)))
+ || (spell_typematch(spell, SPTYP_TRANSMUTATION
+ && player_mutation_level(MUT_NO_TRANSMUTATION_MAGIC)))
+ )
+ return true;
+
switch (spell)
{
case SPELL_BLINK:
diff --git a/crawl-ref/source/status.cc b/crawl-ref/source/status.cc
index ce25d6e..9b64201 100644
--- a/crawl-ref/source/status.cc
+++ b/crawl-ref/source/status.cc
@@ -168,6 +168,8 @@ static duration_def duration_data[] =
BLUE, "Abj", "aura of abjuration", "You are abjuring all hostile summons around you." },
{ DUR_NO_POTIONS, false,
RED, "-Potion", "no potions", "You cannot drink potions." },
+ { DUR_NO_SCROLLS, false,
+ RED, "-Scroll", "no scrolls", "You cannot read scrolls." },
{ DUR_QAZLAL_FIRE_RES, false,
LIGHTBLUE, "rF+", "protected from fire", "Qazlal is protecting you from fire." },
{ DUR_QAZLAL_COLD_RES, false,
@@ -178,6 +180,8 @@ static duration_def duration_data[] =
LIGHTBLUE, "", "protected from physical damage", "Qazlal is protecting you from physical damage." },
{ DUR_CORROSION, false,
RED, "Corr", "corroded equipment", "Your equipment is corroded." },
+ { DUR_HORROR, false,
+ RED, "Horr", "horrified", "You are horrified by the amount of blood." },
};
static int duration_index[NUM_DURATIONS];
@@ -716,6 +720,30 @@ bool fill_status_info(int status, status_info* inf)
break;
}
+ case DUR_HORROR:
+ if (you.props["song_of_slaying_bonus"].get_int() > 5)
+ {
+ inf->light_colour = RED;
+ inf->light_text = "Horr";
+ inf->short_text = "overwhelmed with horror";
+ inf->long_text = "There is blood everywhere and horror overwhelms you!";
+ }
+ else if (you.props["song_of_slaying_bonus"].get_int() > 3)
+ {
+ inf->light_colour = LIGHTRED;
+ inf->light_text = "Horr";
+ inf->short_text = "extremely horrified";
+ inf->long_text = "You are horrified by the exceptional amounts of blood.";
+ }
+ else if (you.props["song_of_slaying_bonus"].get_int())
+ {
+ inf->light_colour = YELLOW;
+ inf->light_text = "Horr";
+ inf->short_text = "horrified";
+ inf->long_text = "You are horrified by the amount of blood.";
+ }
+ break;
+
default:
if (!found)
{
diff --git a/crawl-ref/source/terrain.cc b/crawl-ref/source/terrain.cc
index 5193242..5c3d22e 100644
--- a/crawl-ref/source/terrain.cc
+++ b/crawl-ref/source/terrain.cc
@@ -1574,7 +1574,7 @@ static const char *dngn_feature_names[] =
"altar_okawaru", "altar_makhleb", "altar_sif_muna", "altar_trog",
"altar_nemelex_xobeh", "altar_elyvilon", "altar_lugonu",
"altar_beogh", "altar_jiyva", "altar_fedhas", "altar_cheibriados",
-"altar_ashenzari", "altar_dithmenos",
+"altar_ashenzari", "altar_dithmenos", "altar_iashol",
#if TAG_MAJOR_VERSION > 34
"altar_gozag", "altar_qazlal", "", "", "", "", "", "",
#endif
diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc
index 7be2746..49eda9b 100644
--- a/crawl-ref/source/tilepick.cc
+++ b/crawl-ref/source/tilepick.cc
@@ -446,6 +446,8 @@ static tileidx_t _tileidx_feature_base(dungeon_feature_type feat)
return TILE_DNGN_ALTAR_ASHENZARI;
case DNGN_ALTAR_DITHMENOS:
return TILE_DNGN_ALTAR_DITHMENOS;
+ case DNGN_ALTAR_IASHOL:
+ return TILE_DNGN_ALTAR_IASHOL;
case DNGN_ALTAR_GOZAG:
return TILE_DNGN_ALTAR_GOZAG;
case DNGN_ALTAR_QAZLAL:
@@ -5422,6 +5424,25 @@ tileidx_t tileidx_ability(const ability_type ability)
return TILEG_ABILITY_QAZLAL_ELEMENTAL_FORCE;
case ABIL_QAZLAL_DISASTER_AREA:
return TILEG_ABILITY_QAZLAL_DISASTER_AREA;
+ // Iashol
+ case ABIL_IASHOL_DRAW_OUT_POWER:
+ case ABIL_IASHOL_POWER_LEAP:
+ case ABIL_IASHOL_CATACLYSM:
+ case ABIL_IASHOL_SACRIFICE_PURITY:
+ case ABIL_IASHOL_SACRIFICE_WORDS:
+ case ABIL_IASHOL_SACRIFICE_DRINK:
+ case ABIL_IASHOL_SACRIFICE_EYE:
+ case ABIL_IASHOL_SACRIFICE_ESSENCE:
+ case ABIL_IASHOL_SACRIFICE_HEALTH:
+ case ABIL_IASHOL_SACRIFICE_STEALTH:
+ case ABIL_IASHOL_SACRIFICE_ARTIFICE:
+ case ABIL_IASHOL_SACRIFICE_LOVE:
+ case ABIL_IASHOL_SACRIFICE_SANITY:
+ case ABIL_IASHOL_SACRIFICE_ARCANA:
+ case ABIL_IASHOL_SACRIFICE_NIMBLENESS:
+ case ABIL_IASHOL_SACRIFICE_DURABILITY:
+ case ABIL_IASHOL_SACRIFICE_HAND:
+ return TILEG_ABILITY_DITHMENOS_SHADOW_FORM; //no tiles yet
// General divine (pseudo) abilities.
case ABIL_RENOUNCE_RELIGION:
diff --git a/crawl-ref/source/wiz-you.cc b/crawl-ref/source/wiz-you.cc
index 6289408..259a41b 100644
--- a/crawl-ref/source/wiz-you.cc
+++ b/crawl-ref/source/wiz-you.cc
@@ -878,11 +878,13 @@ static const char* dur_names[] =
"aura of abjuration",
"mesmerisation immunity",
"no potions",
+ "no scrolls",
"qazlal fire resistance",
"qazlal cold resistance",
"qazlal elec resistance",
"qazlal ac",
- "corrosion"
+ "corrosion",
+ "horror"
};
void wizard_edit_durations(void)
iashol3.patch [^] (144,319 bytes) 2014-06-09 03:27
iashol4.patch [^] (159,303 bytes) 2014-06-09 03:41
iashol5.patch [^] (123,357 bytes) 2014-06-12 03:24
iashol6.patch [^] (129,706 bytes) 2014-06-13 02:33
iashol7.patch [^] (136,073 bytes) 2014-06-14 13:46
iashol8.patch [^] (136,255 bytes) 2014-06-14 15:27
iashol9.patch [^] (130,700 bytes) 2014-06-14 18:54
iashol10.patch [^] (157,210 bytes) 2014-06-14 19:39
iashol11.patch [^] (127,725 bytes) 2014-06-14 22:27
iashol12.patch [^] (126,229 bytes) 2014-06-14 22:47
iashol_cleanups.diff [^] (8,854 bytes) 2014-06-14 23:41 [Show Content] [Hide Content]diff --git a/crawl-ref/source/ability.cc b/crawl-ref/source/ability.cc
index 3172bdf..0e4da1d 100644
--- a/crawl-ref/source/ability.cc
+++ b/crawl-ref/source/ability.cc
@@ -3613,11 +3613,15 @@ vector<talent> your_talents(bool check_confused, bool include_unusable)
// Evocations from items.
if (you.scan_artefacts(ARTP_BLINK)
&& !player_mutation_level(MUT_NO_ARTIFICE))
+ {
_add_talent(talents, ABIL_EVOKE_BLINK, check_confused);
+ }
if (you.scan_artefacts(ARTP_FOG)
&& !player_mutation_level(MUT_NO_ARTIFICE))
+ {
_add_talent(talents, ABIL_EVOKE_FOG, check_confused);
+ }
if (you.evokable_berserk() && !player_mutation_level(MUT_NO_ARTIFICE))
_add_talent(talents, ABIL_EVOKE_BERSERK, check_confused);
@@ -3666,7 +3670,9 @@ vector<talent> your_talents(bool check_confused, bool include_unusable)
if (you.wearing(EQ_RINGS, RING_TELEPORT_CONTROL)
&& !player_mutation_level(MUT_NO_ARTIFICE))
+ {
_add_talent(talents, ABIL_EVOKE_TELEPORT_CONTROL, check_confused);
+ }
// Find hotkeys for the non-hotkeyed talents.
for (unsigned int i = 0; i < talents.size(); ++i)
@@ -3845,7 +3851,9 @@ static int _find_ability_slot(const ability_def &abil)
|| abil.ability == ABIL_IASHOL_SACRIFICE_NIMBLENESS
|| abil.ability == ABIL_IASHOL_SACRIFICE_DURABILITY
|| abil.ability == ABIL_IASHOL_SACRIFICE_HAND)
+ {
first_slot = letter_to_index('P');
+ }
for (int slot = first_slot; slot < 52; ++slot)
@@ -3888,9 +3896,7 @@ vector<ability_type> get_god_abilities(bool include_unusable, bool ignore_piety)
{
int num_sacrifices = you.available_sacrifices.size();
for (int i = 0; i < num_sacrifices; ++i)
- {
abilities.push_back(you.available_sacrifices[i]);
- }
}
else if (you.transfer_skill_points > 0)
abilities.push_back(ABIL_ASHENZARI_END_TRANSFER);
diff --git a/crawl-ref/source/evoke.cc b/crawl-ref/source/evoke.cc
index 1331673..a3e349a 100644
--- a/crawl-ref/source/evoke.cc
+++ b/crawl-ref/source/evoke.cc
@@ -1697,9 +1697,7 @@ bool evoke_item(int slot, bool check_range)
did_work = true; // easier to do it this way for misc items
if (player_mutation_level(MUT_NO_ARTIFICE))
- {
return mpr("You cannot evoke magical items."), false;
- }
if (is_deck(item))
{
diff --git a/crawl-ref/source/fineff.cc b/crawl-ref/source/fineff.cc
index 39da17f..b3fba0a 100644
--- a/crawl-ref/source/fineff.cc
+++ b/crawl-ref/source/fineff.cc
@@ -206,9 +206,7 @@ void iashol_retribution_fineff::fire()
if (!attack || attack == defender() || !attack->alive())
return;
if (def == MID_PLAYER)
- {
iashol_do_retribution(monster_by_mid(att), damage);
- }
}
void trample_follow_fineff::fire()
diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc
index e25032f..724e6ab 100644
--- a/crawl-ref/source/godabil.cc
+++ b/crawl-ref/source/godabil.cc
@@ -4886,41 +4886,23 @@ vector<ability_type> get_possible_sacrifices()
possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_ARCANA);
}
if (!player_mutation_level(MUT_NO_READ))
- {
possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_WORDS);
- }
if (!player_mutation_level(MUT_NO_DRINK))
- {
possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_DRINK);
- }
if (!player_mutation_level(MUT_NO_STEALTH))
- {
possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_STEALTH);
- }
if (!player_mutation_level(MUT_NO_ARTIFICE))
- {
possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_ARTIFICE);
- }
if (!player_mutation_level(MUT_NO_LOVE))
- {
possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_LOVE);
- }
if (!player_mutation_level(MUT_FEAR_BLOOD))
- {
possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_SANITY);
- }
if (!player_mutation_level(MUT_NO_DODGING))
- {
possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_NIMBLENESS);
- }
if (!player_mutation_level(MUT_NO_ARMOUR))
- {
possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_DURABILITY);
- }
if (!player_mutation_level(MUT_MISSING_HAND))
- {
possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_HAND);
- }
return possible_sacrifices;
}
@@ -5200,7 +5182,9 @@ void iashol_do_sacrifice(ability_type sacrifice)
if (you.current_purity_sacrifice[0] == MUT_WEAK
|| you.current_purity_sacrifice[0] == MUT_CLUMSY
|| you.current_purity_sacrifice[0] == MUT_DOPEY)
+ {
gain_piety(10 + random2(5));
+ }
else
gain_piety(25 + random2(5));
break;
@@ -5455,9 +5439,7 @@ bool iashol_power_leap()
}
if (!beam.isValid || beam.target == you.pos())
- {
return false; // early return
- }
monster* beholder = you.get_beholder(beam.target);
if (beholder)
@@ -5511,13 +5493,9 @@ bool iashol_power_leap()
if (you.attempt_escape(2)) // I'm hoping this returns true if not constrict
{
if (cell_is_solid(beam.target) || monster_at(beam.target))
- {
mpr("Something unexpectedly blocked you, preventing you from leaping!");
- }
else
- {
move_player_to_grid(beam.target, false);
- }
crawl_state.cancel_cmd_again();
crawl_state.cancel_cmd_repeat();
@@ -5548,9 +5526,7 @@ bool iashol_power_leap()
{
monster* mon = monster_at(*ai);
if (mon == NULL || mons_is_projectile(mon->type) || mon->friendly())
- {
continue;
- }
ASSERT(mon);
mon->hurt((actor*)&you, roll_dice(div_rand_round(you.piety, 9), 3),
@@ -5564,9 +5540,7 @@ static int _cataclysmable(coord_def where, int pow, int, actor* agent)
{
monster* mon = monster_at(where);
if (mon == NULL || mons_is_projectile(mon->type) || mon->friendly())
- {
return 0;
- }
return 1;
}
diff --git a/crawl-ref/source/mon-death.cc b/crawl-ref/source/mon-death.cc
index 18056bf..07bd486 100644
--- a/crawl-ref/source/mon-death.cc
+++ b/crawl-ref/source/mon-death.cc
@@ -2052,7 +2052,9 @@ int monster_die(monster* mons, killer_type killer,
if (good_kill && you_worship(GOD_IASHOL) && you.piety < 200
&& one_chance_in(2))
+ {
you.iashol_points += 1;
+ }
// Randomly bless a follower.
if (!created_friendly
diff --git a/crawl-ref/source/player-act.cc b/crawl-ref/source/player-act.cc
index 638a965..beae689 100644
--- a/crawl-ref/source/player-act.cc
+++ b/crawl-ref/source/player-act.cc
@@ -412,7 +412,9 @@ bool player::can_wield(const item_def& item, bool ignore_curse,
if (two_handed && (
(!ignore_shield && player_wearing_slot(EQ_SHIELD))
|| player_mutation_level(MUT_MISSING_HAND)))
+ {
return false;
+ }
return could_wield(item, ignore_brand, ignore_transform);
}
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index 1dbc620..c82b60b 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -880,7 +880,9 @@ bool you_tran_can_wear(int eq, bool check_mutation)
&& (eq == EQ_LEFT_RING
|| eq == EQ_SHIELD
|| eq == EQ_RING_SEVEN))
+ {
return false;
+ }
// No further restrictions.
if (you.form == TRAN_NONE
@@ -3630,7 +3632,9 @@ int check_stealth()
if (you.attribute[ATTR_SHADOWS] || you.berserk() || you.stat_zero[STAT_DEX]
|| player_mutation_level(MUT_NO_STEALTH))
+ {
return 0;
+ }
int stealth = you.dex() * 3;
diff --git a/crawl-ref/source/skills2.cc b/crawl-ref/source/skills2.cc
index d79a1c4..4e80347 100644
--- a/crawl-ref/source/skills2.cc
+++ b/crawl-ref/source/skills2.cc
@@ -516,7 +516,9 @@ bool is_useless_skill(skill_type skill)
|| (skill == SK_EVOCATIONS && player_mutation_level(MUT_NO_ARTIFICE))
|| (skill == SK_STEALTH && player_mutation_level(MUT_NO_STEALTH))
)
+ {
return true;
+ }
return species_apt(skill) == -99;
}
diff --git a/crawl-ref/source/spl-util.cc b/crawl-ref/source/spl-util.cc
index bd3a332..b81e7ce 100644
--- a/crawl-ref/source/spl-util.cc
+++ b/crawl-ref/source/spl-util.cc
@@ -1137,7 +1137,9 @@ bool spell_is_useless(spell_type spell, bool transient)
|| (spell_typematch(spell, SPTYP_TRANSMUTATION
&& player_mutation_level(MUT_NO_TRANSMUTATION_MAGIC)))
)
+ {
return true;
+ }
switch (spell)
{
0001-IASHOL-EXPERIMENTAL-ONLY-Add-minor-tag-for-save-chan.patch [^] (1,865 bytes) 2014-06-15 23:59 [Show Content] [Hide Content]From 71219f53ded22f6546f1898fb3da469cdbed59be Mon Sep 17 00:00:00 2001
From: Corin Buchanan-Howland <corin@buchananhowland.net>
Date: Sun, 15 Jun 2014 17:59:03 -0400
Subject: [PATCH 1/1] (IASHOL EXPERIMENTAL ONLY) Add minor tag for save changes
---
crawl-ref/source/tag-version.h | 1 +
crawl-ref/source/tags.cc | 9 +++++++++
2 files changed, 10 insertions(+)
diff --git a/crawl-ref/source/tag-version.h b/crawl-ref/source/tag-version.h
index 9ea99b9..f3d985d 100644
--- a/crawl-ref/source/tag-version.h
+++ b/crawl-ref/source/tag-version.h
@@ -109,6 +109,7 @@ enum tag_minor_version
TAG_MINOR_FRIENDLY_PICKUP, // Remove the friendly_pickup setting.
TAG_MINOR_STICKY_FLAME, // Change the name of you.props "napalmer" & "napalm_aux"
TAG_MINOR_SLAYRING_PLUSES, // Combine Acc/Dam on rings of slaying and artefacts.
+ TAG_MINOR_IASHOL_DATA, // Restructuring persistent Iashol data to allow saving.
#endif
NUM_TAG_MINORS,
TAG_MINOR_VERSION = NUM_TAG_MINORS - 1
diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc
index ca3ea01..a6ffd62 100644
--- a/crawl-ref/source/tags.cc
+++ b/crawl-ref/source/tags.cc
@@ -3032,6 +3032,15 @@ static void tag_read_you(reader &th)
}
if (you.duration[DUR_WEAPON_BRAND] && !you.props.exists("orig brand"))
you.props["orig brand"] = SPWPN_NORMAL;
+ if (th.getMinorVersion() < TAG_MINOR_IASHOL_DATA)
+ {
+ you.props["available_sacrifices"].new_vector(SV_INT);
+ you.props["current_health_sacrifice"].new_vector(SV_INT);
+ you.props["current_essence_sacrifice"].new_vector(SV_INT);
+ you.props["current_purity_sacrifice"].new_vector(SV_INT);
+ you.props["current_arcane_sacrifices"].new_vector(SV_INT);
+ you.props["iashol_progress_to_next_sacrifice"] = 0;
+ }
#endif
}
--
1.9.0.msysgit.0
save-load_Iashol_variables.patch [^] (26,111 bytes) 2014-06-16 00:17 [Show Content] [Hide Content]From e4edd833863a22df45766266f9c8e5bf91f3c8bb Mon Sep 17 00:00:00 2001
From: Corin Buchanan-Howland <corin@buchananhowland.net>
Date: Sun, 15 Jun 2014 17:11:56 -0400
Subject: [PATCH 1/2] Adding saving for Iashol variables
This commit moves all Iashol variables into properties so that they're saved and loaded properly. It also slightly slows Iashol sacrifice offers and fixes double piety gain for some sacrifices.
---
crawl-ref/source/ability.cc | 10 +-
crawl-ref/source/godabil.cc | 202 ++++++++++++++++++++++++++++-------------
crawl-ref/source/godconduct.cc | 9 +-
crawl-ref/source/mon-death.cc | 7 +-
crawl-ref/source/player.cc | 2 -
crawl-ref/source/player.h | 6 --
crawl-ref/source/religion.cc | 17 +++-
7 files changed, 174 insertions(+), 79 deletions(-)
diff --git a/crawl-ref/source/ability.cc b/crawl-ref/source/ability.cc
index e16c5b5..9d5daaf 100644
--- a/crawl-ref/source/ability.cc
+++ b/crawl-ref/source/ability.cc
@@ -3894,9 +3894,15 @@ vector<ability_type> get_god_abilities(bool include_unusable, bool ignore_piety)
}
else if (you_worship(GOD_IASHOL))
{
- int num_sacrifices = you.available_sacrifices.size();
+
+ ASSERT(you.props.exists("available_sacrifices"));
+ CrawlVector &available_sacrifices
+ = you.props["available_sacrifices"].get_vector();
+
+ int num_sacrifices = available_sacrifices.size();
for (int i = 0; i < num_sacrifices; ++i)
- abilities.push_back(you.available_sacrifices[i]);
+ abilities.push_back(
+ static_cast<ability_type>(available_sacrifices[i].get_int()));
}
else if (you.transfer_skill_points > 0)
abilities.push_back(ABIL_ASHENZARI_END_TRANSFER);
diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc
index c73d268..9ce2fac 100644
--- a/crawl-ref/source/godabil.cc
+++ b/crawl-ref/source/godabil.cc
@@ -4865,9 +4865,9 @@ vector<ability_type> get_possible_sacrifices()
{
vector<ability_type> possible_sacrifices;
- possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_PURITY);
- possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_ESSENCE);
possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_HEALTH);
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_ESSENCE);
+ possible_sacrifices.push_back(ABIL_IASHOL_SACRIFICE_PURITY);
if (player_mutation_level(MUT_NO_AIR_MAGIC)
+ player_mutation_level(MUT_NO_CHARM_MAGIC)
@@ -5002,13 +5002,21 @@ void iashol_offer_new_sacrifices()
} while (greater_sacrifice == -1 || greater_sacrifice == lesser_sacrifice
|| greater_sacrifice == sacrifice);
+ ASSERT(you.props.exists("available_sacrifices"));
+ CrawlVector &available_sacrifices
+ = you.props["available_sacrifices"].get_vector();
+
// set the new abilities
- you.available_sacrifices.push_back(
- possible_sacrifices[lesser_sacrifice]);
- you.available_sacrifices.push_back(
- possible_sacrifices[sacrifice]);
- you.available_sacrifices.push_back(
- possible_sacrifices[greater_sacrifice]);
+ available_sacrifices.push_back(
+ static_cast<int>(possible_sacrifices[lesser_sacrifice]));
+ available_sacrifices.push_back(
+ static_cast<int>(possible_sacrifices[sacrifice]));
+ available_sacrifices.push_back(
+ static_cast<int>(possible_sacrifices[greater_sacrifice]));
+
+ ASSERT(you.props.exists("current_health_sacrifice"));
+ CrawlVector ¤t_health_sacrifice
+ = you.props["current_health_sacrifice"].get_vector();
if (possible_sacrifices[lesser_sacrifice] == ABIL_IASHOL_SACRIFICE_HEALTH
|| possible_sacrifices[sacrifice] == ABIL_IASHOL_SACRIFICE_HEALTH
@@ -5016,65 +5024,88 @@ void iashol_offer_new_sacrifices()
{
switch (random2(3)) {
case 0:
- you.current_health_sacrifice.push_back(
- MUT_PHYSICAL_VULNERABILITY);
+ current_health_sacrifice.push_back(
+ static_cast<int>(MUT_PHYSICAL_VULNERABILITY));
break;
case 1:
- you.current_health_sacrifice.push_back(MUT_SLOW_REFLEXES);
+ current_health_sacrifice.push_back(
+ static_cast<int>(MUT_SLOW_REFLEXES));
break;
case 2:
- you.current_health_sacrifice.push_back(MUT_FRAIL);
+ current_health_sacrifice.push_back(
+ static_cast<int>(MUT_FRAIL));
break;
}
}
+ ASSERT(you.props.exists("current_essence_sacrifice"));
+ CrawlVector ¤t_essence_sacrifice
+ = you.props["current_essence_sacrifice"].get_vector();
+
if (possible_sacrifices[lesser_sacrifice] == ABIL_IASHOL_SACRIFICE_ESSENCE
|| possible_sacrifices[sacrifice] == ABIL_IASHOL_SACRIFICE_ESSENCE
|| possible_sacrifices[greater_sacrifice] == ABIL_IASHOL_SACRIFICE_ESSENCE)
{
switch (random2(3)) {
case 0:
- you.current_essence_sacrifice.push_back(MUT_ANTI_WIZARDRY);
+ current_essence_sacrifice.push_back(
+ static_cast<int>(MUT_ANTI_WIZARDRY));
break;
case 1:
- you.current_essence_sacrifice.push_back(
- MUT_MAGICAL_VULNERABILITY);
+ current_essence_sacrifice.push_back(
+ static_cast<int>(MUT_MAGICAL_VULNERABILITY));
break;
case 2:
- you.current_essence_sacrifice.push_back(MUT_LOW_MAGIC);
+ current_essence_sacrifice.push_back(
+ static_cast<int>(MUT_LOW_MAGIC));
break;
}
}
+ ASSERT(you.props.exists("current_purity_sacrifice"));
+ CrawlVector ¤t_purity_sacrifice
+ = you.props["current_purity_sacrifice"].get_vector();
+
if (possible_sacrifices[lesser_sacrifice] == ABIL_IASHOL_SACRIFICE_PURITY
|| possible_sacrifices[sacrifice] == ABIL_IASHOL_SACRIFICE_PURITY
|| possible_sacrifices[greater_sacrifice] == ABIL_IASHOL_SACRIFICE_PURITY)
{
switch (random2(7)) {
case 0:
- you.current_purity_sacrifice.push_back(MUT_DETERIORATION);
+ current_purity_sacrifice.push_back(
+ static_cast<int>(MUT_DETERIORATION));
break;
case 1:
- you.current_purity_sacrifice.push_back(MUT_SCREAM);
+ current_purity_sacrifice.push_back(
+ static_cast<int>(MUT_SCREAM));
break;
case 2:
- you.current_purity_sacrifice.push_back(MUT_DEFORMED);
+ current_purity_sacrifice.push_back(
+ static_cast<int>(MUT_DEFORMED));
break;
case 3:
- you.current_purity_sacrifice.push_back(MUT_SLOW_HEALING);
+ current_purity_sacrifice.push_back(
+ static_cast<int>(MUT_SLOW_HEALING));
break;
case 4:
- you.current_purity_sacrifice.push_back(MUT_DOPEY);
+ current_purity_sacrifice.push_back(
+ static_cast<int>(MUT_DOPEY));
break;
case 5:
- you.current_purity_sacrifice.push_back(MUT_CLUMSY);
+ current_purity_sacrifice.push_back(
+ static_cast<int>(MUT_CLUMSY));
break;
case 6:
- you.current_purity_sacrifice.push_back(MUT_WEAK);
+ current_purity_sacrifice.push_back(
+ static_cast<int>(MUT_WEAK));
break;
}
}
+ ASSERT(you.props.exists("current_arcane_sacrifices"));
+ CrawlVector ¤t_arcane_sacrifices
+ = you.props["current_arcane_sacrifices"].get_vector();
+
if (possible_sacrifices[lesser_sacrifice] == ABIL_IASHOL_SACRIFICE_ARCANA
|| possible_sacrifices[sacrifice] == ABIL_IASHOL_SACRIFICE_ARCANA
|| possible_sacrifices[greater_sacrifice] == ABIL_IASHOL_SACRIFICE_ARCANA)
@@ -5095,8 +5126,9 @@ void iashol_offer_new_sacrifices()
if (!player_mutation_level(MUT_NO_TRANSLOCATION_MAGIC))
possible_major_mutations.push_back(MUT_NO_TRANSLOCATION_MAGIC);
num_major_mutations = possible_major_mutations.size();
- you.current_arcane_sacrifices.push_back(
- possible_major_mutations[random2(num_major_mutations)]);
+ current_arcane_sacrifices.push_back(
+ static_cast<int>(possible_major_mutations[
+ random2(num_major_mutations)]));
if (!player_mutation_level(MUT_NO_TRANSMUTATION_MAGIC))
possible_medium_mutations.push_back(MUT_NO_TRANSMUTATION_MAGIC);
@@ -5105,8 +5137,9 @@ void iashol_offer_new_sacrifices()
if (!player_mutation_level(MUT_NO_HEXES_MAGIC))
possible_medium_mutations.push_back(MUT_NO_HEXES_MAGIC);
num_medium_mutations = possible_medium_mutations.size();
- you.current_arcane_sacrifices.push_back(
- possible_medium_mutations[random2(num_medium_mutations)]);
+ current_arcane_sacrifices.push_back(
+ static_cast<int>(possible_medium_mutations[
+ random2(num_medium_mutations)]));
if (!player_mutation_level(MUT_NO_AIR_MAGIC))
possible_minor_mutations.push_back(MUT_NO_AIR_MAGIC);
@@ -5119,8 +5152,9 @@ void iashol_offer_new_sacrifices()
if (!player_mutation_level(MUT_NO_POISON_MAGIC))
possible_minor_mutations.push_back(MUT_NO_POISON_MAGIC);
num_minor_mutations = possible_minor_mutations.size();
- you.current_arcane_sacrifices.push_back(
- possible_minor_mutations[random2(num_minor_mutations)]);
+ current_arcane_sacrifices.push_back(
+ static_cast<int>(possible_minor_mutations[
+ random2(num_minor_mutations)]));
}
}
@@ -5129,6 +5163,24 @@ void iashol_do_sacrifice(ability_type sacrifice)
skill_type mutation_skill;
int arcane_mutations_size;
+ ASSERT(you.props.exists("current_health_sacrifice"));
+ ASSERT(you.props.exists("current_essence_sacrifice"));
+ ASSERT(you.props.exists("current_purity_sacrifice"));
+ ASSERT(you.props.exists("current_arcane_sacrifices"));
+
+ CrawlVector ¤t_health_sacrifice =
+ you.props["current_health_sacrifice"].get_vector();
+ CrawlVector ¤t_essence_sacrifice =
+ you.props["current_essence_sacrifice"].get_vector();
+ CrawlVector ¤t_purity_sacrifice =
+ you.props["current_purity_sacrifice"].get_vector();
+ CrawlVector ¤t_arcane_sacrifices
+ = you.props["current_arcane_sacrifices"].get_vector();
+
+ mutation_type health_sacrifice;
+ mutation_type essence_sacrifice;
+ mutation_type purity_sacrifice;
+
switch (sacrifice)
{
case ABIL_IASHOL_SACRIFICE_WORDS:
@@ -5154,48 +5206,54 @@ void iashol_do_sacrifice(ability_type sacrifice)
gain_piety(35 + random2(5));
break;
case ABIL_IASHOL_SACRIFICE_HEALTH:
+ health_sacrifice = static_cast<mutation_type>(
+ current_health_sacrifice[0].get_int());
+
mprf("Iashol asks you to corrupt yourself with %s.",
- mutation_name(you.current_health_sacrifice[0]));
+ mutation_name(health_sacrifice));
if (!yesno("Do you really want to do make this sacrifice?",
false, 'n'))
{
canned_msg(MSG_OK);
return;
} else {
- perma_mutate(you.current_health_sacrifice[0],
- 1, "Iashol sacrifice");
+ perma_mutate(health_sacrifice, 1, "Iashol sacrifice");
}
gain_piety(30 + random2(5));
break;
case ABIL_IASHOL_SACRIFICE_ESSENCE:
+ essence_sacrifice = static_cast<mutation_type>(
+ current_essence_sacrifice[0].get_int());
+
mprf("Iashol asks you to corrupt yourself with %s.",
- mutation_name(you.current_essence_sacrifice[0]));
+ mutation_name(essence_sacrifice));
if (!yesno("Do you really want to do make this sacrifice?",
false, 'n'))
{
canned_msg(MSG_OK);
return;
} else {
- perma_mutate(you.current_essence_sacrifice[0],
- 1, "Iashol sacrifice");
+ perma_mutate(essence_sacrifice, 1, "Iashol sacrifice");
}
gain_piety(30 + random2(5));
break;
case ABIL_IASHOL_SACRIFICE_PURITY:
+ purity_sacrifice = static_cast<mutation_type>(
+ current_purity_sacrifice[0].get_int());
+
mprf("Iashol asks you to corrupt yourself with %s.",
- mutation_name(you.current_purity_sacrifice[0]));
+ mutation_name(purity_sacrifice));
if (!yesno("Do you really want to do make this sacrifice?",
false, 'n'))
{
canned_msg(MSG_OK);
return;
} else {
- perma_mutate(you.current_purity_sacrifice[0],
- 1, "Iashol sacrifice");
+ perma_mutate(purity_sacrifice, 1, "Iashol sacrifice");
}
- if (you.current_purity_sacrifice[0] == MUT_WEAK
- || you.current_purity_sacrifice[0] == MUT_CLUMSY
- || you.current_purity_sacrifice[0] == MUT_DOPEY)
+ if (purity_sacrifice == MUT_WEAK
+ || purity_sacrifice == MUT_CLUMSY
+ || purity_sacrifice == MUT_DOPEY)
{
gain_piety(10 + random2(5));
}
@@ -5211,8 +5269,6 @@ void iashol_do_sacrifice(ability_type sacrifice)
} else {
perma_mutate(MUT_NO_STEALTH, 1, "Iashol sacrifice");
}
- gain_piety(div_rand_round(skill_exp_needed(
- you.skills[SK_STEALTH], SK_STEALTH, SP_HUMAN), 50));
// zero out useless skills
you.skills[SK_STEALTH] = 0;
@@ -5228,8 +5284,6 @@ void iashol_do_sacrifice(ability_type sacrifice)
} else {
perma_mutate(MUT_NO_ARTIFICE, 1, "Iashol sacrifice");
}
- gain_piety(div_rand_round(skill_exp_needed(
- you.skills[SK_EVOCATIONS], SK_EVOCATIONS, SP_HUMAN), 50));
// zero out useless skills
you.skills[SK_EVOCATIONS] = 0;
@@ -5245,8 +5299,6 @@ void iashol_do_sacrifice(ability_type sacrifice)
} else {
perma_mutate(MUT_NO_DODGING, 1, "Iashol sacrifice");
}
- gain_piety(div_rand_round(skill_exp_needed(
- you.skills[SK_DODGING], SK_DODGING, SP_HUMAN), 50));
// zero out useless skills
you.skills[SK_DODGING] = 0;
@@ -5262,8 +5314,6 @@ void iashol_do_sacrifice(ability_type sacrifice)
} else {
perma_mutate(MUT_NO_ARMOUR, 1, "Iashol sacrifice");
}
- gain_piety(div_rand_round(skill_exp_needed(
- you.skills[SK_ARMOUR], SK_ARMOUR, SP_HUMAN), 50));
// zero out useless skills
you.skills[SK_ARMOUR] = 0;
@@ -5291,16 +5341,19 @@ void iashol_do_sacrifice(ability_type sacrifice)
perma_mutate(MUT_NO_LOVE, 1, "Iashol sacrifice");
}
gain_piety(25 + random2(5) + div_rand_round(skill_exp_needed(
- you.skills[SK_SUMMONINGS], SK_SUMMONINGS, SP_HUMAN), 50));
+ you.skills[SK_SUMMONINGS], SK_SUMMONINGS, SP_HUMAN), 200));
break;
case ABIL_IASHOL_SACRIFICE_ARCANA:
mprf("Iashol asks you to sacrifice all use of %s, %s, and %s.",
arcane_mutation_to_school_name(
- you.current_arcane_sacrifices[0]),
+ static_cast<mutation_type>(
+ current_arcane_sacrifices[0].get_int())),
arcane_mutation_to_school_name(
- you.current_arcane_sacrifices[1]),
+ static_cast<mutation_type>(
+ current_arcane_sacrifices[1].get_int())),
arcane_mutation_to_school_name(
- you.current_arcane_sacrifices[2])
+ static_cast<mutation_type>(
+ current_arcane_sacrifices[2].get_int()))
);
if (!yesno("Do you want to accept this sacrifice? ",
true, 'n'))
@@ -5309,16 +5362,18 @@ void iashol_do_sacrifice(ability_type sacrifice)
return;
}
- arcane_mutations_size = you.current_arcane_sacrifices.size();
+ arcane_mutations_size = current_arcane_sacrifices.size();
for (int i = 0; i < arcane_mutations_size; ++i) {
- perma_mutate(you.current_arcane_sacrifices[i], 1,
- "Iashol sacrifice");
+ mutation_type arcane_sacrifice =
+ static_cast<mutation_type>(
+ current_arcane_sacrifices[i].get_int());
+ perma_mutate(arcane_sacrifice, 1, "Iashol sacrifice");
// gain one piety for every 50 skill points
- mutation_skill =
- arcane_mutation_to_skill(you.current_arcane_sacrifices[i]);
- gain_piety(div_rand_round(skill_exp_needed(
- you.skills[mutation_skill], mutation_skill, SP_HUMAN), 50));
+ mutation_skill = arcane_mutation_to_skill(arcane_sacrifice);
+ gain_piety(25 + random2(5) + div_rand_round(skill_exp_needed(
+ you.skills[mutation_skill], mutation_skill, SP_HUMAN),
+ 50));
// zero out useless skills
you.skills[mutation_skill] = 0;
@@ -5369,11 +5424,28 @@ void iashol_do_sacrifice(ability_type sacrifice)
// time or it's time to offer something new.
void iashol_expire_sacrifices()
{
- you.available_sacrifices.clear();
- you.current_health_sacrifice.clear();
- you.current_essence_sacrifice.clear();
- you.current_purity_sacrifice.clear();
- you.current_arcane_sacrifices.clear();
+ ASSERT(you.props.exists("available_sacrifices"));
+ ASSERT(you.props.exists("current_health_sacrifice"));
+ ASSERT(you.props.exists("current_essence_sacrifice"));
+ ASSERT(you.props.exists("current_purity_sacrifice"));
+ ASSERT(you.props.exists("current_arcane_sacrifices"));
+
+ CrawlVector &available_sacrifices
+ = you.props["available_sacrifices"].get_vector();
+ CrawlVector ¤t_health_sacrifice
+ = you.props["current_health_sacrifice"].get_vector();
+ CrawlVector ¤t_essence_sacrifice
+ = you.props["current_essence_sacrifice"].get_vector();
+ CrawlVector ¤t_purity_sacrifice
+ = you.props["current_purity_sacrifice"].get_vector();
+ CrawlVector ¤t_arcane_sacrifices
+ = you.props["current_arcane_sacrifices"].get_vector();
+
+ available_sacrifices.clear();
+ current_health_sacrifice.clear();
+ current_essence_sacrifice.clear();
+ current_purity_sacrifice.clear();
+ current_arcane_sacrifices.clear();
}
diff --git a/crawl-ref/source/godconduct.cc b/crawl-ref/source/godconduct.cc
index 01788e1..6bc1f8e 100644
--- a/crawl-ref/source/godconduct.cc
+++ b/crawl-ref/source/godconduct.cc
@@ -972,8 +972,15 @@ bool did_god_conduct(conduct_type thing_done, int level, bool known,
}
else if (you_worship(GOD_IASHOL))
{
+ ASSERT(you.props.exists("iashol_progress_to_next_sacrifice"));
if (one_chance_in(100))
- you.iashol_points += 1;
+ {
+ int current_progress =
+ you.props["iashol_progress_to_next_sacrifice"]
+ .get_int();
+ you.props["iashol_progress_to_next_sacrifice"] =
+ current_progress + 1;
+ }
}
break;
diff --git a/crawl-ref/source/mon-death.cc b/crawl-ref/source/mon-death.cc
index 07bd486..0250037 100644
--- a/crawl-ref/source/mon-death.cc
+++ b/crawl-ref/source/mon-death.cc
@@ -2053,7 +2053,12 @@ int monster_die(monster* mons, killer_type killer,
if (good_kill && you_worship(GOD_IASHOL) && you.piety < 200
&& one_chance_in(2))
{
- you.iashol_points += 1;
+ ASSERT(you.props.exists("iashol_progress_to_next_sacrifice"));
+ int current_progress =
+ you.props["iashol_progress_to_next_sacrifice"]
+ .get_int();
+ you.props["iashol_progress_to_next_sacrifice"] =
+ current_progress + 1;
}
// Randomly bless a follower.
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index c82b60b..e7b94df 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -92,8 +92,6 @@
#include "viewgeom.h"
#include "xom.h"
-int iashol_points = 0;
-
static void _moveto_maybe_repel_stairs()
{
const dungeon_feature_type new_grid = env.grid(you.pos());
diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h
index a3431e1..6b2d1df 100644
--- a/crawl-ref/source/player.h
+++ b/crawl-ref/source/player.h
@@ -186,12 +186,6 @@ public:
FixedVector<short, NUM_GODS> num_total_gifts;
FixedBitVector< NUM_GODS> one_time_ability_used;
FixedVector<uint8_t, NUM_GODS> piety_max;
- vector<ability_type> available_sacrifices;
- vector<mutation_type> current_arcane_sacrifices;
- vector<mutation_type> current_purity_sacrifice;
- vector<mutation_type> current_health_sacrifice;
- vector<mutation_type> current_essence_sacrifice;
- int iashol_points; // Used to smoothe out Iashol sacrifice frequency
FixedVector<uint8_t, NUM_MUTATIONS> mutation;
FixedVector<uint8_t, NUM_MUTATIONS> innate_mutation;
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 2f943d7..555523c 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -4042,6 +4042,18 @@ void god_pitch(god_type which_god)
you.piety = HALF_MAX_PIETY;
you.gift_timeout = random2(40) + random2(40);
}
+ else if (you_worship(GOD_IASHOL))
+ {
+ you.piety = 1; // you don't start w/ anything.
+ you.piety_hysteresis = 0;
+ you.gift_timeout = 0;
+ you.props["available_sacrifices"].new_vector(SV_INT);
+ you.props["current_health_sacrifice"].new_vector(SV_INT);
+ you.props["current_essence_sacrifice"].new_vector(SV_INT);
+ you.props["current_purity_sacrifice"].new_vector(SV_INT);
+ you.props["current_arcane_sacrifices"].new_vector(SV_INT);
+ you.props["iashol_progress_to_next_sacrifice"] = 0;
+ }
else
{
you.piety = 15; // to prevent near instant excommunication
@@ -4622,7 +4634,8 @@ void handle_god_time(int time_delta)
break;
case GOD_IASHOL:
- if (you.iashol_points >= 50)
+ ASSERT(you.props.exists("iashol_progress_to_next_sacrifice"));
+ if (you.props["iashol_progress_to_next_sacrifice"].get_int() >= 70)
{
if (you.piety < 200)
{
@@ -4631,7 +4644,7 @@ void handle_god_time(int time_delta)
simple_god_message(" believes you are ready to make a new sacrifice.");
more();
}
- you.iashol_points -= 50;
+ you.props["iashol_progress_to_next_sacrifice"].get_int() = 0;
}
break;
return;
--
1.9.0.msysgit.0
From c771834e15ed7c82b1d23796b1fa26509d46f4fb Mon Sep 17 00:00:00 2001
From: Corin Buchanan-Howland <corin@buchananhowland.net>
Date: Sun, 15 Jun 2014 17:59:03 -0400
Subject: [PATCH 2/2] (IASHOL EXPERIMENTAL ONLY) Add minor tag for save changes
---
crawl-ref/source/tag-version.h | 1 +
crawl-ref/source/tags.cc | 9 +++++++++
2 files changed, 10 insertions(+)
diff --git a/crawl-ref/source/tag-version.h b/crawl-ref/source/tag-version.h
index 9ea99b9..f3d985d 100644
--- a/crawl-ref/source/tag-version.h
+++ b/crawl-ref/source/tag-version.h
@@ -109,6 +109,7 @@ enum tag_minor_version
TAG_MINOR_FRIENDLY_PICKUP, // Remove the friendly_pickup setting.
TAG_MINOR_STICKY_FLAME, // Change the name of you.props "napalmer" & "napalm_aux"
TAG_MINOR_SLAYRING_PLUSES, // Combine Acc/Dam on rings of slaying and artefacts.
+ TAG_MINOR_IASHOL_DATA, // Restructuring persistent Iashol data to allow saving.
#endif
NUM_TAG_MINORS,
TAG_MINOR_VERSION = NUM_TAG_MINORS - 1
diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc
index ca3ea01..87f5fc3 100644
--- a/crawl-ref/source/tags.cc
+++ b/crawl-ref/source/tags.cc
@@ -3032,6 +3032,15 @@ static void tag_read_you(reader &th)
}
if (you.duration[DUR_WEAPON_BRAND] && !you.props.exists("orig brand"))
you.props["orig brand"] = SPWPN_NORMAL;
+ if (you_worship(GOD_IASHOL) && th.getMinorVersion() < TAG_MINOR_IASHOL_DATA)
+ {
+ you.props["available_sacrifices"].new_vector(SV_INT);
+ you.props["current_health_sacrifice"].new_vector(SV_INT);
+ you.props["current_essence_sacrifice"].new_vector(SV_INT);
+ you.props["current_purity_sacrifice"].new_vector(SV_INT);
+ you.props["current_arcane_sacrifices"].new_vector(SV_INT);
+ you.props["iashol_progress_to_next_sacrifice"] = 0;
+ }
#endif
}
--
1.9.0.msysgit.0
0001-Iashol-Fix-Missing-Hand.patch [^] (4,353 bytes) 2014-06-16 01:45 [Show Content] [Hide Content]From 87056dc62dcd351872edccac6f0c5fce8b2a0755 Mon Sep 17 00:00:00 2001
From: Corin Buchanan-Howland <corin@buchananhowland.net>
Date: Sun, 15 Jun 2014 19:45:27 -0400
Subject: [PATCH 1/1] Iashol: Fix Missing Hand
This commit fixes the Iashol Sacrifice a Hand ability to disallow shield use and properly unequip second ring / disallow reuse of second ring.
---
crawl-ref/source/godabil.cc | 32 +++++++++++++++++++++++++-------
crawl-ref/source/item_use.cc | 19 +++++++++++++++++--
2 files changed, 42 insertions(+), 9 deletions(-)
diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc
index 9ce2fac..e22583d 100644
--- a/crawl-ref/source/godabil.cc
+++ b/crawl-ref/source/godabil.cc
@@ -5181,6 +5181,18 @@ void iashol_do_sacrifice(ability_type sacrifice)
mutation_type essence_sacrifice;
mutation_type purity_sacrifice;
+ // set these up for Sac Hand
+ equipment_type ring_slot;
+
+ if (you.species == SP_OCTOPODE)
+ ring_slot = EQ_RING_EIGHT;
+ else
+ ring_slot = EQ_LEFT_RING;
+
+ item_def* const shield = you.slot_item(EQ_SHIELD, true);
+ item_def* const weapon = you.slot_item(EQ_WEAPON, true);
+ item_def* const ring = you.slot_item(ring_slot, true);
+
switch (sacrifice)
{
case ABIL_IASHOL_SACRIFICE_WORDS:
@@ -5390,26 +5402,32 @@ void iashol_do_sacrifice(ability_type sacrifice)
}
// Drop your shield if there is one
- if (you.inv[EQ_SHIELD].defined())
+ if (shield != NULL)
{
- item_def& shield = you.inv[EQ_SHIELD];
mprf("You can no longer hold %s!",
- shield.name(DESC_YOUR).c_str());
+ shield->name(DESC_YOUR).c_str());
unequip_item(EQ_SHIELD);
}
// And your two-handed weapon
- if (you.inv[EQ_WEAPON].defined())
+ if (weapon != NULL)
{
- item_def& weapon = you.inv[EQ_WEAPON];
- if (you.hands_reqd(weapon) == HANDS_TWO)
+ if (you.hands_reqd(*weapon) == HANDS_TWO)
{
mprf("You can no longer hold %s!",
- weapon.name(DESC_YOUR).c_str());
+ weapon->name(DESC_YOUR).c_str());
unequip_item(EQ_WEAPON);
}
}
+ // And one ring
+ if (ring != NULL )
+ {
+ mprf("You can no longer wear %s!",
+ ring->name(DESC_YOUR).c_str());
+ unequip_item(ring_slot);
+ }
+
gain_piety(80 + div_rand_round(skill_exp_needed(
you.skills[SK_SHIELDS], SK_SHIELDS, SP_HUMAN), 50));
break;
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 4e7597e..666ec53 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -796,6 +796,18 @@ bool do_wear_armour(int item, bool quiet)
}
}
+ if (player_mutation_level(MUT_MISSING_HAND) && is_shield(invitem))
+ {
+ if (!quiet)
+ {
+ if (you.species == SP_OCTOPODE)
+ mpr("You need the rest of your tentacles for walking.");
+ else
+ mprf("You'd need another %s to do that!", you.hand_name(true).c_str());
+ }
+ return false;
+ }
+
// if you're wielding something,
if (you.weapon()
// attempting to wear a shield,
@@ -915,14 +927,17 @@ static vector<equipment_type> _current_ring_types()
vector<equipment_type> ret;
if (you.species == SP_OCTOPODE)
{
- const int num_rings = (form_keeps_mutations() || you.form == TRAN_SPIDER
+ int num_rings = (form_keeps_mutations() || you.form == TRAN_SPIDER
? 8 : 2);
+ if (player_mutation_level(MUT_MISSING_HAND))
+ num_rings -= 1;
for (int i = 0; i != num_rings; ++i)
ret.push_back((equipment_type)(EQ_RING_ONE + i));
}
else
{
- ret.push_back(EQ_LEFT_RING);
+ if (player_mutation_level(MUT_MISSING_HAND) == 0)
+ ret.push_back(EQ_LEFT_RING);
ret.push_back(EQ_RIGHT_RING);
}
if (player_equip_unrand(UNRAND_FINGER_AMULET))
--
1.9.0.msysgit.0
0001-Iashol-Fix-Essence-mutation-description.patch [^] (1,082 bytes) 2014-06-16 01:59 [Show Content] [Hide Content]From 45c563722620b9d40cebbfbbc175cb4828768ba2 Mon Sep 17 00:00:00 2001
From: Corin Buchanan-Howland <corin@buchananhowland.net>
Date: Sun, 15 Jun 2014 19:59:30 -0400
Subject: [PATCH 1/1] Iashol: Fix Essence mutation description
The MR essence mutation said -20 MR for all levels, but it's -20 per level.
---
crawl-ref/source/mutation-data.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/crawl-ref/source/mutation-data.h b/crawl-ref/source/mutation-data.h
index 61e7a3e..1d7e4da 100644
--- a/crawl-ref/source/mutation-data.h
+++ b/crawl-ref/source/mutation-data.h
@@ -1971,8 +1971,8 @@ static const mutation_def mut_data[] =
"magic vulnerable",
{"You are slightly vulnerable to magic. (-20 MR)",
- "You are vulnerable to magic. (-20 MR)",
- "You are extremely vulnerable to magic. (-20 MR)"},
+ "You are vulnerable to magic. (-40 MR)",
+ "You are extremely vulnerable to magic. (-60 MR)"},
{"You feel vulnerable to magic.",
"You feel more vulnerable to magic.",
"You feel more vulnerable to magic."},
--
1.9.0.msysgit.0
0001-Iashol-Block-skill-training-from-sacrificed-skill.patch [^] (4,919 bytes) 2014-06-16 02:53 [Show Content] [Hide Content]From 46b7d7be1ca4ea77a09499a13a288000ee4bf6ec Mon Sep 17 00:00:00 2001
From: Corin Buchanan-Howland <corin@buchananhowland.net>
Date: Sun, 15 Jun 2014 20:53:38 -0400
Subject: [PATCH 1/1] Iashol: Block skill training from sacrificed skill
This disables skill training and disposes of skill points from skills that have been sacrificed.
---
crawl-ref/source/godabil.cc | 38 +++++++++++++++++++++++++++++---------
1 file changed, 29 insertions(+), 9 deletions(-)
diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc
index e22583d..6b3b5f0 100644
--- a/crawl-ref/source/godabil.cc
+++ b/crawl-ref/source/godabil.cc
@@ -59,6 +59,7 @@
#include "skill_menu.h"
#include "shopping.h"
#include "shout.h"
+#include "skills.h"
#include "spl-book.h"
#include "spl-monench.h"
#include "spl-summoning.h"
@@ -5282,10 +5283,14 @@ void iashol_do_sacrifice(ability_type sacrifice)
perma_mutate(MUT_NO_STEALTH, 1, "Iashol sacrifice");
}
- // zero out useless skills
- you.skills[SK_STEALTH] = 0;
gain_piety(30 + div_rand_round(skill_exp_needed(
you.skills[SK_STEALTH], SK_STEALTH, SP_HUMAN), 50));
+
+ // zero out useless skills
+ change_skill_points(SK_STEALTH,
+ -you.skill_points[SK_STEALTH], true);
+ you.stop_train.insert(SK_STEALTH);
+
break;
case ABIL_IASHOL_SACRIFICE_ARTIFICE:
if (!yesno("Do you really want to do make this sacrifice?",
@@ -5297,10 +5302,13 @@ void iashol_do_sacrifice(ability_type sacrifice)
perma_mutate(MUT_NO_ARTIFICE, 1, "Iashol sacrifice");
}
- // zero out useless skills
- you.skills[SK_EVOCATIONS] = 0;
gain_piety(40 + div_rand_round(skill_exp_needed(
you.skills[SK_EVOCATIONS], SK_EVOCATIONS, SP_HUMAN), 50));
+ // zero out useless skills
+ change_skill_points(SK_EVOCATIONS,
+ -you.skill_points[SK_EVOCATIONS], true);
+ you.stop_train.insert(SK_EVOCATIONS);
+
break;
case ABIL_IASHOL_SACRIFICE_NIMBLENESS:
if (!yesno("Do you really want to do make this sacrifice?",
@@ -5312,10 +5320,13 @@ void iashol_do_sacrifice(ability_type sacrifice)
perma_mutate(MUT_NO_DODGING, 1, "Iashol sacrifice");
}
- // zero out useless skills
- you.skills[SK_DODGING] = 0;
gain_piety(30 + div_rand_round(skill_exp_needed(
you.skills[SK_DODGING], SK_DODGING, SP_HUMAN), 50));
+ // zero out useless skills
+ change_skill_points(SK_DODGING,
+ -you.skill_points[SK_DODGING], true);
+ you.stop_train.insert(SK_DODGING);
+
break;
case ABIL_IASHOL_SACRIFICE_DURABILITY:
if (!yesno("Do you really want to do make this sacrifice?",
@@ -5327,10 +5338,13 @@ void iashol_do_sacrifice(ability_type sacrifice)
perma_mutate(MUT_NO_ARMOUR, 1, "Iashol sacrifice");
}
- // zero out useless skills
- you.skills[SK_ARMOUR] = 0;
gain_piety(30 + div_rand_round(skill_exp_needed(
you.skills[SK_ARMOUR], SK_ARMOUR, SP_HUMAN), 50));
+ // zero out useless skills
+ change_skill_points(SK_ARMOUR,
+ -you.skill_points[SK_ARMOUR], true);
+ you.stop_train.insert(SK_ARMOUR);
+
break;
case ABIL_IASHOL_SACRIFICE_SANITY:
if (!yesno("Do you really want to do make this sacrifice?",
@@ -5352,8 +5366,10 @@ void iashol_do_sacrifice(ability_type sacrifice)
} else {
perma_mutate(MUT_NO_LOVE, 1, "Iashol sacrifice");
}
+
gain_piety(25 + random2(5) + div_rand_round(skill_exp_needed(
you.skills[SK_SUMMONINGS], SK_SUMMONINGS, SP_HUMAN), 200));
+
break;
case ABIL_IASHOL_SACRIFICE_ARCANA:
mprf("Iashol asks you to sacrifice all use of %s, %s, and %s.",
@@ -5388,7 +5404,9 @@ void iashol_do_sacrifice(ability_type sacrifice)
50));
// zero out useless skills
- you.skills[mutation_skill] = 0;
+ change_skill_points(mutation_skill,
+ -you.skill_points[mutation_skill], true);
+ you.stop_train.insert(mutation_skill);
}
break;
case ABIL_IASHOL_SACRIFICE_HAND:
@@ -5430,6 +5448,8 @@ void iashol_do_sacrifice(ability_type sacrifice)
gain_piety(80 + div_rand_round(skill_exp_needed(
you.skills[SK_SHIELDS], SK_SHIELDS, SP_HUMAN), 50));
+
+ you.stop_train.insert(SK_SHIELDS);
break;
default:
return;
--
1.9.0.msysgit.0
0001-Iashol-Amnesia-forbidden-schools.patch [^] (6,549 bytes) 2014-06-16 03:56 [Show Content] [Hide Content]From 53cb735584cbd66e884ba59a872590e4bddf3617 Mon Sep 17 00:00:00 2001
From: Corin Buchanan-Howland <corin@buchananhowland.net>
Date: Sun, 15 Jun 2014 21:39:08 -0400
Subject: [PATCH 1/1] Iashol: Amnesia forbidden schools
This change forcibly amnesias all spells of a school the player sacrifices.
---
crawl-ref/source/godabil.cc | 13 +++++++++++
crawl-ref/source/spl-book.cc | 31 ++++++++++++++++++++++++++
crawl-ref/source/spl-util.cc | 53 ++++++++++++++++++--------------------------
crawl-ref/source/spl-util.h | 1 +
4 files changed, 67 insertions(+), 31 deletions(-)
diff --git a/crawl-ref/source/godabil.cc b/crawl-ref/source/godabil.cc
index 6b3b5f0..12b6925 100644
--- a/crawl-ref/source/godabil.cc
+++ b/crawl-ref/source/godabil.cc
@@ -5407,6 +5407,19 @@ void iashol_do_sacrifice(ability_type sacrifice)
change_skill_points(mutation_skill,
-you.skill_points[mutation_skill], true);
you.stop_train.insert(mutation_skill);
+
+ for (int j = 0; j < 52; ++j)
+ {
+ const char letter = index_to_letter(j);
+ const spell_type spell = get_spell_by_letter(letter);
+ if (!is_valid_spell(spell))
+ continue;
+ if (spell_typematch(spell,
+ skill2spell_type(mutation_skill)))
+ {
+ del_spell_from_memory_by_slot(j);
+ }
+ }
}
break;
case ABIL_IASHOL_SACRIFICE_HAND:
diff --git a/crawl-ref/source/spl-book.cc b/crawl-ref/source/spl-book.cc
index e844c50..5ddb639 100644
--- a/crawl-ref/source/spl-book.cc
+++ b/crawl-ref/source/spl-book.cc
@@ -589,6 +589,37 @@ bool you_cannot_memorise(spell_type spell, bool &form)
rc = true, form = false;
}
+ // Check for banned schools.
+ if (
+ (spell_typematch(spell, SPTYP_AIR)
+ && player_mutation_level(MUT_NO_AIR_MAGIC))
+ || (spell_typematch(spell, SPTYP_CHARMS)
+ && player_mutation_level(MUT_NO_CHARM_MAGIC))
+ || (spell_typematch(spell, SPTYP_CONJURATION)
+ && player_mutation_level(MUT_NO_CONJURATION_MAGIC))
+ || (spell_typematch(spell, SPTYP_EARTH)
+ && player_mutation_level(MUT_NO_EARTH_MAGIC))
+ || (spell_typematch(spell, SPTYP_FIRE)
+ && player_mutation_level(MUT_NO_FIRE_MAGIC))
+ || (spell_typematch(spell, SPTYP_HEXES)
+ && player_mutation_level(MUT_NO_HEXES_MAGIC))
+ || (spell_typematch(spell, SPTYP_ICE)
+ && player_mutation_level(MUT_NO_ICE_MAGIC))
+ || (spell_typematch(spell, SPTYP_NECROMANCY)
+ && player_mutation_level(MUT_NO_NECROMANCY_MAGIC))
+ || (spell_typematch(spell, SPTYP_POISON)
+ && player_mutation_level(MUT_NO_POISON_MAGIC))
+ || (spell_typematch(spell, SPTYP_SUMMONING)
+ && player_mutation_level(MUT_NO_SUMMONING_MAGIC))
+ || (spell_typematch(spell, SPTYP_TRANSLOCATION)
+ && player_mutation_level(MUT_NO_TRANSLOCATION_MAGIC))
+ || (spell_typematch(spell, SPTYP_TRANSMUTATION)
+ && player_mutation_level(MUT_NO_TRANSMUTATION_MAGIC))
+ )
+ {
+ return true;
+ }
+
return rc;
}
diff --git a/crawl-ref/source/spl-util.cc b/crawl-ref/source/spl-util.cc
index b81e7ce..25041b1 100644
--- a/crawl-ref/source/spl-util.cc
+++ b/crawl-ref/source/spl-util.cc
@@ -870,6 +870,28 @@ skill_type spell_type2skill(unsigned int spelltype)
}
}
+unsigned int skill2spell_type(skill_type spell_skill)
+{
+ switch (spell_skill)
+ {
+ case SK_CONJURATIONS: return SPTYP_CONJURATION;
+ case SK_HEXES: return SPTYP_HEXES;
+ case SK_CHARMS: return SPTYP_CHARMS;
+ case SK_FIRE_MAGIC: return SPTYP_FIRE;
+ case SK_ICE_MAGIC: return SPTYP_ICE;
+ case SK_TRANSMUTATIONS: return SPTYP_TRANSMUTATION;
+ case SK_NECROMANCY: return SPTYP_NECROMANCY;
+ case SK_SUMMONINGS: return SPTYP_SUMMONING;
+ case SK_TRANSLOCATIONS: return SPTYP_TRANSLOCATION;
+ case SK_POISON_MAGIC: return SPTYP_POISON;
+ case SK_EARTH_MAGIC: return SPTYP_EARTH;
+ case SK_AIR_MAGIC: return SPTYP_AIR;
+
+ default:
+ return SPTYP_NONE;
+ }
+}
+
/*
**************************************************
* *
@@ -1110,37 +1132,6 @@ bool spell_is_useless(spell_type spell, bool transient)
#endif
}
- // Check for banned schools.
- if (
- (spell_typematch(spell, SPTYP_AIR
- && player_mutation_level(MUT_NO_AIR_MAGIC)))
- || (spell_typematch(spell, SPTYP_CHARMS
- && player_mutation_level(MUT_NO_CHARM_MAGIC)))
- || (spell_typematch(spell, SPTYP_CONJURATION
- && player_mutation_level(MUT_NO_CONJURATION_MAGIC)))
- || (spell_typematch(spell, SPTYP_EARTH
- && player_mutation_level(MUT_NO_EARTH_MAGIC)))
- || (spell_typematch(spell, SPTYP_FIRE
- && player_mutation_level(MUT_NO_FIRE_MAGIC)))
- || (spell_typematch(spell, SPTYP_HEXES
- && player_mutation_level(MUT_NO_HEXES_MAGIC)))
- || (spell_typematch(spell, SPTYP_ICE
- && player_mutation_level(MUT_NO_ICE_MAGIC)))
- || (spell_typematch(spell, SPTYP_NECROMANCY
- && player_mutation_level(MUT_NO_NECROMANCY_MAGIC)))
- || (spell_typematch(spell, SPTYP_POISON
- && player_mutation_level(MUT_NO_POISON_MAGIC)))
- || (spell_typematch(spell, SPTYP_SUMMONING
- && player_mutation_level(MUT_NO_SUMMONING_MAGIC)))
- || (spell_typematch(spell, SPTYP_TRANSLOCATION
- && player_mutation_level(MUT_NO_TRANSLOCATION_MAGIC)))
- || (spell_typematch(spell, SPTYP_TRANSMUTATION
- && player_mutation_level(MUT_NO_TRANSMUTATION_MAGIC)))
- )
- {
- return true;
- }
-
switch (spell)
{
case SPELL_BLINK:
diff --git a/crawl-ref/source/spl-util.h b/crawl-ref/source/spl-util.h
index d42d40a..8ec5fd8 100644
--- a/crawl-ref/source/spl-util.h
+++ b/crawl-ref/source/spl-util.h
@@ -124,6 +124,7 @@ bool spell_direction(dist &spelld, bolt &pbolt,
desc_filter get_desc_func = NULL);
skill_type spell_type2skill(unsigned int which_spelltype);
+unsigned int skill2spell_type(skill_type spell_skill);
spell_type zap_type_to_spell(zap_type zap);
--
1.9.0.msysgit.0
0001-Iashol-Offer-monks-the-first-sacrifice-right-away.patch [^] (1,022 bytes) 2014-06-16 04:21 [Show Content] [Hide Content]From c8a0a9f7e9322e758812c8eeff5d7b0870ee8f37 Mon Sep 17 00:00:00 2001
From: Corin Buchanan-Howland <corin@buchananhowland.net>
Date: Sun, 15 Jun 2014 22:19:09 -0400
Subject: [PATCH 1/1] Iashol: Offer monks the first sacrifice right away
Monks get an immediate sacrifice in lieu of free piety.
---
crawl-ref/source/religion.cc | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 555523c..a133aa5 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -4232,7 +4232,10 @@ void god_pitch(god_type which_god)
if (you.char_class == JOB_MONK && had_gods() <= 1)
{
// monks get bonus piety for first god
- gain_piety(35, 1, false);
+ if (you_worship(GOD_IASHOL))
+ you.props["iashol_progress_to_next_sacrifice"] = 100;
+ else
+ gain_piety(35, 1, false);
}
if (you_worship(GOD_LUGONU) && you.worshipped[GOD_LUGONU] == 1)
--
1.9.0.msysgit.0
|