summaryrefslogtreecommitdiffstats
path: root/trunk/source/spl-cast.cc
diff options
context:
space:
mode:
authorpeterb12 <peterb12@c06c8d41-db1a-0410-9941-cceddc491573>2005-07-21 02:34:44 +0000
committerpeterb12 <peterb12@c06c8d41-db1a-0410-9941-cceddc491573>2005-07-21 02:34:44 +0000
commit673bdae75485d14f759af597c3c62b99601f9a43 (patch)
tree368103f29fe0ce5dcf98060d9b5faa04590085fb /trunk/source/spl-cast.cc
parent7e900be770db24b0405fd2162491c405a425873e (diff)
downloadcrawl-ref-673bdae75485d14f759af597c3c62b99601f9a43.tar.gz
crawl-ref-673bdae75485d14f759af597c3c62b99601f9a43.zip
Initial revision
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'trunk/source/spl-cast.cc')
-rw-r--r--trunk/source/spl-cast.cc3542
1 files changed, 3542 insertions, 0 deletions
diff --git a/trunk/source/spl-cast.cc b/trunk/source/spl-cast.cc
new file mode 100644
index 0000000000..135d831af9
--- /dev/null
+++ b/trunk/source/spl-cast.cc
@@ -0,0 +1,3542 @@
+/*
+ * File: spl-cast.cc
+ * Summary: Spell casting and miscast functions.
+ * Written by: Linley Henzell
+ *
+ * Change History (most recent first):
+ *
+ * <4> 1/02/00 jmf changed values, marked //jmf:
+ * <3> 6/13/99 BWR Added Staff auto identify code
+ * <2> 5/20/99 BWR Added some screen redraws
+ * <1> -/--/-- LRH Created
+ */
+
+#include "AppHdr.h"
+#include "spl-cast.h"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "externs.h"
+
+#include "beam.h"
+#include "cloud.h"
+#include "effects.h"
+#include "fight.h"
+#include "food.h"
+#include "it_use2.h"
+#include "itemname.h"
+#include "macro.h"
+#include "monplace.h"
+#include "monstuff.h"
+#include "mutation.h"
+#include "ouch.h"
+#include "player.h"
+#include "religion.h"
+#include "skills.h"
+#include "spells1.h"
+#include "spells2.h"
+#include "spells3.h"
+#include "spells4.h"
+#include "spl-book.h"
+#include "spl-util.h"
+#include "stuff.h"
+#include "transfor.h"
+#include "view.h"
+
+#ifdef DOS
+#include <conio.h>
+#endif
+
+#define WILD_MAGIC_NASTINESS 150
+
+static void surge_power(int spell)
+{
+ int enhanced = 0;
+
+ //jmf: simplified
+ enhanced += spell_enhancement(spell_type(spell));
+
+ if (enhanced) // one way or the other {dlb}
+ {
+ strcpy(info, "You feel a");
+
+ strcat(info, (enhanced < -2) ? "n extraordinarily" :
+ (enhanced == -2) ? "n extremely" :
+ (enhanced == 2) ? " strong" :
+ (enhanced > 2) ? " huge"
+ : "");
+
+ strcat(info, (enhanced < 0) ? " numb sensation."
+ : " surge of power!");
+ mpr(info);
+ }
+} // end surge_power()
+
+char list_spells(void)
+{
+ int j;
+ int lines = 0;
+ unsigned int anything = 0;
+ unsigned int i;
+ int ki;
+ bool already = false;
+
+ const int num_lines = get_number_of_lines();
+
+#ifdef DOS_TERM
+ char buffer[4800];
+
+ gettext(1, 1, 80, 25, buffer);
+#endif
+
+#ifdef DOS_TERM
+ window(1, 1, 80, 25);
+#endif
+
+ clrscr();
+
+ cprintf( " Your Spells Type Success Level" );
+ lines++;
+
+ for (j = 0; j < 52; j++)
+ {
+ if (lines > num_lines - 2)
+ {
+ gotoxy(1, num_lines);
+ cprintf("-more-");
+
+ ki = getch();
+
+ if (ki == ESCAPE)
+ {
+#ifdef DOS_TERM
+ puttext(1, 1, 80, 25, buffer);
+#endif
+ return (ESCAPE);
+ }
+
+ if (isalpha( ki ))
+ {
+#ifdef DOS_TERM
+ puttext(1, 1, 80, 25, buffer);
+#endif
+ return (ki);
+ }
+
+ if (ki == 0)
+ ki = getch();
+
+ lines = 0;
+ clrscr();
+ gotoxy(1, 1);
+ anything = 0;
+ }
+
+ const char letter = index_to_letter(j);
+ const int spell = get_spell_by_letter(letter);
+
+ if (spell != SPELL_NO_SPELL)
+ {
+ anything++;
+
+ if (lines > 0)
+ cprintf(EOL);
+
+ lines++;
+
+ cprintf( " %c - %s", letter, spell_title( spell ) );
+ gotoxy(35, wherey());
+
+ already = false;
+
+ for (i = 0; i <= SPTYP_LAST_EXPONENT; i++)
+ {
+ if (spell_typematch( spell, (1 << i) ))
+ {
+ if (already)
+ cprintf( "/" );
+
+ cprintf( spelltype_name( 1 << i ) );
+ already = true;
+ }
+ }
+
+ char sval[16];
+
+ //gotoxy(58, wherey());
+ gotoxy(65, wherey());
+
+ int spell_f = spell_fail( spell );
+
+ cprintf( (spell_f == 100) ? "Useless" :
+ (spell_f > 90) ? "Terrible" :
+ (spell_f > 80) ? "Cruddy" :
+ (spell_f > 70) ? "Bad" :
+ (spell_f > 60) ? "Very Poor" :
+ (spell_f > 50) ? "Poor" :
+ (spell_f > 40) ? "Fair" :
+ (spell_f > 30) ? "Good" :
+ (spell_f > 20) ? "Very Good" :
+ (spell_f > 10) ? "Great" :
+ (spell_f > 0) ? "Excellent"
+ : "Perfect" );
+
+ gotoxy(77, wherey());
+
+ itoa( (int) spell_difficulty( spell ), sval, 10 );
+ cprintf(sval);
+ }
+ } // end of j loop
+
+ if (anything > 0)
+ {
+ ki = getch();
+
+ if (ki >= 'A' && ki <= 'z')
+ {
+#ifdef DOS_TERM
+ puttext(1, 1, 80, 25, buffer);
+#endif
+ return (ki);
+ }
+
+ if (ki == 0)
+ ki = getch();
+
+#ifdef DOS_TERM
+ puttext(1, 1, 80, 25, buffer);
+#endif
+
+ return (anything);
+ }
+
+#ifdef DOS_TERM
+ puttext(1, 1, 80, 25, buffer);
+#endif
+ // was 35
+ ki = getch();
+
+ return (ki);
+} // end list_spells()
+
+int spell_fail(int spell)
+{
+ int chance = 60;
+ int chance2 = 0, armour = 0;
+
+ chance -= 6 * calc_spell_power( spell, false );
+ chance -= (you.intel * 2);
+
+ //chance -= (you.intel - 10) * abs(you.intel - 10);
+ //chance += spell_difficulty(spell) * spell_difficulty(spell) * 3; //spell_difficulty(spell);
+
+ if (you.equip[EQ_BODY_ARMOUR] != -1)
+ {
+
+ int ev_penalty = abs(property( you.inv[you.equip[EQ_BODY_ARMOUR]],
+ PARM_EVASION ));
+
+ // The minus 15 is to make the -1 light armours not so bad
+ armour += (20 * ev_penalty) - 15;
+
+ //jmf: armour skill now reduces failure due to armour
+ //bwr: this was far too good, an armour skill of 5 was
+ // completely negating plate mail. Plate mail should
+ // hardly be completely negated, it should still be
+ // an important consideration for even high level characters.
+ // Truth is, even a much worse penalty than the above can
+ // easily be overcome by gaining spell skills... and a lot
+ // faster than any reasonable rate of bonus here.
+ int lim_str = (you.strength > 30) ? 30 :
+ (you.strength < 10) ? 10 : you.strength;
+
+ armour -= ((you.skills[SK_ARMOUR] * lim_str) / 15);
+
+ int race_arm = get_equip_race( you.inv[you.equip[EQ_BODY_ARMOUR]] );
+ int racial_type = 0;
+
+ if (player_genus(GENPC_DWARVEN))
+ racial_type = ISFLAG_DWARVEN;
+ else if (player_genus(GENPC_ELVEN))
+ racial_type = ISFLAG_ELVEN;
+ else if (you.species == SP_HILL_ORC)
+ racial_type = ISFLAG_ORCISH;
+
+ // Elven armour gives everyone some benefit to spellcasting,
+ // Dwarven armour hinders everyone.
+ switch (race_arm)
+ {
+ case ISFLAG_ELVEN:
+ armour -= 20;
+ break;
+ case ISFLAG_DWARVEN:
+ armour += 10;
+ break;
+ default:
+ break;
+ }
+
+ // Armour of the same racial type reduces penalty.
+ if (racial_type && race_arm == racial_type)
+ armour -= 10;
+
+ if (armour > 0)
+ chance += armour;
+ }
+
+ if (you.equip[EQ_WEAPON] != -1
+ && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_WEAPONS)
+ {
+ int wpn_penalty = (3 * (property( you.inv[you.equip[EQ_WEAPON]], PWPN_SPEED ) - 12)) / 2;
+
+ if (wpn_penalty > 0)
+ chance += wpn_penalty;
+ }
+
+ if (you.equip[EQ_SHIELD] != -1)
+ {
+ switch (you.inv[you.equip[EQ_SHIELD]].sub_type)
+ {
+ case ARM_BUCKLER:
+ chance += 5;
+ break;
+
+ case ARM_SHIELD:
+ chance += 15;
+ break;
+
+ case ARM_LARGE_SHIELD:
+ // *BCR* Large chars now get a lower penalty for large shields
+ if ((you.species >= SP_OGRE && you.species <= SP_OGRE_MAGE)
+ || player_genus(GENPC_DRACONIAN))
+ {
+ chance += 20;
+ }
+ else
+ chance += 30;
+ break;
+ }
+ }
+
+ switch (spell_difficulty(spell))
+ {
+ case 1: chance += 3; break;
+ case 2: chance += 15; break;
+ case 3: chance += 35; break;
+ case 4: chance += 70; break;
+ case 5: chance += 100; break;
+ case 6: chance += 150; break;
+ case 7: chance += 200; break;
+ case 8: chance += 260; break;
+ case 9: chance += 330; break;
+ case 10: chance += 420; break;
+ case 11: chance += 500; break;
+ case 12: chance += 600; break;
+ default: chance += 750; break;
+ }
+
+ //if (chance < 1 ) chance = 0;
+ if (chance > 100)
+ chance = 100;
+
+ chance2 = chance;
+
+ if (chance < 45)
+ chance2 = 45;
+ if (chance < 42)
+ chance2 = 43;
+ if (chance < 38)
+ chance2 = 41;
+ if (chance < 35)
+ chance2 = 40;
+ if (chance < 32)
+ chance2 = 38;
+ if (chance < 28)
+ chance2 = 36;
+ if (chance < 22)
+ chance2 = 34;
+ if (chance < 16)
+ chance2 = 32;
+ if (chance < 10)
+ chance2 = 30;
+ if (chance < 2)
+ chance2 = 28;
+ if (chance < -7)
+ chance2 = 26;
+ if (chance < -12)
+ chance2 = 24;
+ if (chance < -18)
+ chance2 = 22;
+ if (chance < -24)
+ chance2 = 20;
+ if (chance < -30)
+ chance2 = 18;
+ if (chance < -38)
+ chance2 = 16;
+ if (chance < -46)
+ chance2 = 14;
+ if (chance < -60)
+ chance2 = 12;
+ if (chance < -80)
+ chance2 = 10;
+ if (chance < -100)
+ chance2 = 8;
+ if (chance < -120)
+ chance2 = 6;
+ if (chance < -140)
+ chance2 = 4;
+ if (chance < -160)
+ chance2 = 2;
+ if (chance < -180)
+ chance2 = 0;
+
+ if (you.religion == GOD_VEHUMET
+ && you.duration[DUR_PRAYER]
+ && (!player_under_penance() && you.piety >= 50)
+ && (spell_typematch(spell, SPTYP_CONJURATION)
+ || spell_typematch(spell, SPTYP_SUMMONING)))
+ {
+ chance2 /= 2;
+ }
+
+ if (you.duration[DUR_TRANSFORMATION] > 0)
+ {
+ switch (you.attribute[ATTR_TRANSFORMATION])
+ {
+ case TRAN_BLADE_HANDS:
+ chance2 += 20;
+ break;
+
+ case TRAN_SPIDER:
+ chance2 += 10;
+ break;
+ }
+ }
+
+ return (chance2);
+} // end spell_fail()
+
+
+int calc_spell_power( int spell, bool apply_intel )
+{
+ unsigned int bit;
+ int ndx;
+ int power = (you.skills[SK_SPELLCASTING] / 2) + player_mag_abil(false);
+ int enhanced = 0;
+
+ unsigned int disciplines = spell_type( spell );
+
+ //jmf: evil evil evil -- exclude HOLY bit
+ disciplines &= (~SPTYP_HOLY);
+
+ int skillcount = count_bits( disciplines );
+ if (skillcount)
+ {
+ for (ndx = 0; ndx <= SPTYP_LAST_EXPONENT; ndx++)
+ {
+ bit = 1 << ndx;
+ if ((bit != SPTYP_HOLY) && (disciplines & bit))
+ {
+ int skill = spell_type2skill( bit );
+
+ power += (you.skills[skill] * 2) / skillcount;
+ }
+ }
+ }
+
+ if (apply_intel)
+ power = (power * you.intel) / 10;
+
+ enhanced = spell_enhancement( disciplines );
+
+ if (enhanced > 0)
+ {
+ for (ndx = 0; ndx < enhanced; ndx++)
+ {
+ power *= 15;
+ power /= 10;
+ }
+ }
+ else if (enhanced < 0)
+ {
+ for (ndx = enhanced; ndx < 0; ndx++)
+ power /= 2;
+ }
+
+ power = stepdown_value( power, 50, 50, 150, 200 );
+
+ return (power);
+} // end calc_spell_power()
+
+
+int spell_enhancement( unsigned int typeflags )
+{
+ int enhanced = 0;
+
+ if (typeflags & SPTYP_CONJURATION)
+ enhanced += player_spec_conj();
+
+ if (typeflags & SPTYP_ENCHANTMENT)
+ enhanced += player_spec_ench();
+
+ if (typeflags & SPTYP_SUMMONING)
+ enhanced += player_spec_summ();
+
+ if (typeflags & SPTYP_POISON)
+ enhanced += player_spec_poison();
+
+ if (typeflags & SPTYP_NECROMANCY)
+ enhanced += player_spec_death() - player_spec_holy();
+
+ if (typeflags & SPTYP_FIRE)
+ enhanced += player_spec_fire() - player_spec_cold();
+
+ if (typeflags & SPTYP_ICE)
+ enhanced += player_spec_cold() - player_spec_fire();
+
+ if (typeflags & SPTYP_EARTH)
+ enhanced += player_spec_earth() - player_spec_air();
+
+ if (typeflags & SPTYP_AIR)
+ enhanced += player_spec_air() - player_spec_earth();
+
+ if (you.special_wield == SPWLD_SHADOW)
+ enhanced -= 2;
+
+ // These are used in an exponential way, so we'll limit them a bit. -- bwr
+ if (enhanced > 3)
+ enhanced = 3;
+ else if (enhanced < -3)
+ enhanced = -3;
+
+ return (enhanced);
+} // end spell_enhancement()
+
+// returns false if spell failed, and true otherwise
+bool cast_a_spell(void)
+{
+ char spc = 0;
+ char spc2 = 0;
+ int spellh = 0;
+ unsigned char keyin = 0;
+ char unthing = 0;
+
+ if (!you.spell_no)
+ {
+ mpr("You don't know any spells.");
+ return (false);
+ }
+
+ if (you.berserker)
+ {
+ canned_msg(MSG_TOO_BERSERK);
+ return (false);
+ }
+
+ if (silenced(you.x_pos, you.y_pos))
+ {
+ mpr("You cannot cast spells when silenced!");
+ return (false);
+ }
+
+ // first query {dlb}:
+ for (;;)
+ {
+ //jmf: FIXME: change to reflect range of known spells
+ mpr( "Cast which spell ([?*] list)? ", MSGCH_PROMPT );
+
+ keyin = get_ch();
+
+ if (keyin == '?' || keyin == '*')
+ {
+ unthing = list_spells();
+
+ redraw_screen();
+ if (unthing == 2)
+ return (false);
+
+ if (unthing >= 'a' && unthing <= 'y')
+ {
+ keyin = unthing;
+ break;
+ }
+ else
+ mesclr();
+ }
+ else
+ {
+ break;
+ }
+
+ }
+
+ if (keyin == ESCAPE)
+ return (false);
+
+ spc = (int) keyin;
+
+ if (!isalpha(spc))
+ {
+ mpr("You don't know that spell.");
+ return (false);
+ }
+
+ const int spell = get_spell_by_letter( spc );
+
+ spc2 = letter_to_index(spc);
+
+ if (spell == SPELL_NO_SPELL)
+ {
+ mpr("You don't know that spell.");
+ return (false);
+ }
+
+ if (spell_mana( spell ) > you.magic_points)
+ {
+ mpr("You don't have enough magic to cast that spell.");
+ return (false);
+ }
+
+ if (you.is_undead != US_UNDEAD
+ && (you.hunger_state < HS_HUNGRY
+ || you.hunger <= spell_hunger( spell )))
+ {
+ mpr("You don't have the energy to cast that spell.");
+ return (false);
+ }
+
+ dec_mp( spell_mana(spell) );
+
+ if (!player_energy() && you.is_undead != US_UNDEAD)
+ {
+ spellh = spell_hunger( spell );
+
+ // I wonder if a better algorithm is called for? {dlb}
+ spellh -= you.intel * you.skills[SK_SPELLCASTING];
+
+ if (spellh < 1)
+ spellh = 1;
+ else
+ make_hungry(spellh, true);
+ }
+
+ you.turn_is_over = 1;
+ alert_nearby_monsters();
+
+ if (you.conf)
+ random_uselessness( 2 + random2(7), 0 );
+ else
+ {
+ exercise_spell( spell, true, your_spells( spell ) );
+ naughty( NAUGHTY_SPELLCASTING, 1 + random2(5) );
+ }
+
+ return (true);
+} // end cast_a_spell()
+
+// returns true if spell if spell is successfully cast for purposes of
+// exercising and false otherwise (note: false == less exercise, not none).
+bool your_spells( int spc2, int powc, bool allow_fail )
+{
+ int dem_hor = 0;
+ int dem_hor2 = 0;
+ int total_skill = 0;
+ struct dist spd;
+ struct bolt beam;
+
+ alert_nearby_monsters();
+
+ // Added this so that the passed in powc can have meaning -- bwr
+ if (powc == 0)
+ powc = calc_spell_power( spc2, true );
+
+ if (you.equip[EQ_WEAPON] != -1
+ && item_is_staff( you.inv[you.equip[EQ_WEAPON]] )
+ && item_not_ident( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_TYPE ))
+ {
+ switch (you.inv[you.equip[EQ_WEAPON]].sub_type)
+ {
+ case STAFF_ENERGY:
+ case STAFF_WIZARDRY:
+ total_skill = you.skills[SK_SPELLCASTING];
+ break;
+ case STAFF_FIRE:
+ if (spell_typematch(spc2, SPTYP_FIRE))
+ total_skill = you.skills[SK_FIRE_MAGIC];
+ else if (spell_typematch(spc2, SPTYP_ICE))
+ total_skill = you.skills[SK_ICE_MAGIC];
+ break;
+ case STAFF_COLD:
+ if (spell_typematch(spc2, SPTYP_ICE))
+ total_skill = you.skills[SK_ICE_MAGIC];
+ else if (spell_typematch(spc2, SPTYP_FIRE))
+ total_skill = you.skills[SK_FIRE_MAGIC];
+ break;
+ case STAFF_AIR:
+ if (spell_typematch(spc2, SPTYP_AIR))
+ total_skill = you.skills[SK_AIR_MAGIC];
+ else if (spell_typematch(spc2, SPTYP_EARTH))
+ total_skill = you.skills[SK_EARTH_MAGIC];
+ break;
+ case STAFF_EARTH:
+ if (spell_typematch(spc2, SPTYP_EARTH))
+ total_skill = you.skills[SK_EARTH_MAGIC];
+ else if (spell_typematch(spc2, SPTYP_AIR))
+ total_skill = you.skills[SK_AIR_MAGIC];
+ break;
+ case STAFF_POISON:
+ if (spell_typematch(spc2, SPTYP_POISON))
+ total_skill = you.skills[SK_POISON_MAGIC];
+ break;
+ case STAFF_DEATH:
+ if (spell_typematch(spc2, SPTYP_NECROMANCY))
+ total_skill = you.skills[SK_NECROMANCY];
+ break;
+ case STAFF_CONJURATION:
+ if (spell_typematch(spc2, SPTYP_CONJURATION))
+ total_skill = you.skills[SK_CONJURATIONS];
+ break;
+ case STAFF_ENCHANTMENT:
+ if (spell_typematch(spc2, SPTYP_ENCHANTMENT))
+ total_skill = you.skills[SK_ENCHANTMENTS];
+ break;
+ case STAFF_SUMMONING:
+ if (spell_typematch(spc2, SPTYP_SUMMONING))
+ total_skill = you.skills[SK_SUMMONINGS];
+ break;
+ }
+
+ if (you.skills[SK_SPELLCASTING] > total_skill)
+ total_skill = you.skills[SK_SPELLCASTING];
+
+ if (random2(100) < total_skill)
+ {
+ char str_pass[ ITEMNAME_SIZE ];
+
+ set_ident_flags( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_TYPE );
+
+ strcpy(info, "You are wielding ");
+ in_name(you.equip[EQ_WEAPON], DESC_NOCAP_A, str_pass);
+ strcat(info, str_pass);
+ strcat(info, ".");
+ mpr(info);
+
+ more();
+
+ you.wield_change = true;
+ }
+ }
+
+ surge_power(spc2);
+
+ if (allow_fail)
+ {
+ int spfl = random2avg(100, 3);
+
+ if (you.religion != GOD_SIF_MUNA
+ && you.penance[GOD_SIF_MUNA] && one_chance_in(40))
+ {
+ god_speaks(GOD_SIF_MUNA, "You feel a surge of divine spite.");
+
+ // This will cause failure and increase the miscast effect.
+ spfl = -you.penance[GOD_SIF_MUNA];
+
+ // Reduced penenance reduction here because casting spells
+ // is a player controllable act. -- bwr
+ if (one_chance_in(7))
+ dec_penance(1);
+ }
+
+ if (spfl < spell_fail(spc2))
+ {
+ mpr( "You miscast the spell." );
+ flush_input_buffer( FLUSH_ON_FAILURE );
+
+ if (you.religion == GOD_SIF_MUNA
+ && (!player_under_penance()
+ && you.piety >= 100 && random2(150) <= you.piety))
+ {
+ canned_msg(MSG_NOTHING_HAPPENS);
+ return (false);
+ }
+
+ unsigned int sptype = 0;
+
+ do
+ {
+ sptype = 1 << (random2(SPTYP_LAST_EXPONENT+1));
+ } while (!spell_typematch(spc2, sptype));
+
+ // all spell failures give a bit of magical radiation..
+ // failure is a function of power squared multiplied
+ // by how badly you missed the spell. High power
+ // spells can be quite nasty: 9 * 9 * 90 / 500 = 15
+ // points of contamination!
+ int nastiness = spell_mana(spc2) * spell_mana(spc2)
+ * (spell_fail(spc2) - spfl) + 250;
+
+ int cont_points = nastiness / 500;
+ // handle fraction
+ if (random2(500) < (nastiness % 500))
+ cont_points++;
+
+ contaminate_player( cont_points );
+
+ miscast_effect( sptype, spell_mana(spc2), spell_fail(spc2) - spfl, 100 );
+
+ if (you.religion == GOD_XOM && random2(75) < spell_mana(spc2))
+ Xom_acts(coinflip(), spell_mana(spc2), false);
+
+ return (false);
+ }
+ }
+
+ if (you.is_undead && spell_typematch( spc2, SPTYP_HOLY ))
+ {
+ mpr( "You can't use this type of magic!" );
+ return (false); // XXX: still gets trained!
+ }
+
+ // Normally undead can't memorize these spells, so this check is
+ // to catch those in Lich form. As such, we allow the Lich form
+ // to be extended here. -- bwr
+ if (spc2 != SPELL_NECROMUTATION
+ && undead_cannot_memorise( spc2, you.is_undead ))
+ {
+ mpr( "You cannot cast that spell in your current form!" );
+ return (false); // XXX: still gets trained!
+ }
+
+ // Linley says: Condensation Shield needs some disadvantages to keep
+ // it from being a no-brainer... this isn't much, but its a start -- bwr
+ if (you.duration[DUR_CONDENSATION_SHIELD] > 0
+ && spell_typematch( spc2, SPTYP_FIRE ))
+ {
+ mpr( "Your icy shield dissipates!", MSGCH_DURATION );
+ you.duration[DUR_CONDENSATION_SHIELD] = 0;
+ you.redraw_armour_class = 1;
+ }
+
+ if (spc2 == SPELL_SUMMON_HORRIBLE_THINGS
+ || spc2 == SPELL_CALL_IMP
+ || spc2 == SPELL_SUMMON_DEMON
+ || spc2 == SPELL_DEMONIC_HORDE
+ || spc2 == SPELL_SUMMON_GREATER_DEMON || spc2 == SPELL_HELLFIRE)
+ {
+ naughty(NAUGHTY_UNHOLY, 10 + spell_difficulty(spc2));
+ }
+
+ if (spell_typematch( spc2, SPTYP_NECROMANCY ))
+ naughty( NAUGHTY_NECROMANCY, 10 + spell_difficulty(spc2) );
+
+ if (spc2 == SPELL_NECROMUTATION
+ && (you.religion == GOD_ELYVILON
+ || you.religion == GOD_SHINING_ONE
+ || you.religion == GOD_ZIN))
+ {
+ excommunication();
+ }
+
+ if (you.religion == GOD_SIF_MUNA
+ && you.piety < 200 && random2(12) <= spell_difficulty(spc2))
+ {
+ gain_piety(1);
+ }
+
+#if DEBUG_DIAGNOSTICS
+ snprintf( info, INFO_SIZE, "Spell #%d, power=%d", spc2, powc );
+ mpr( info, MSGCH_DIAGNOSTICS );
+#endif
+
+ switch (spc2)
+ {
+ case SPELL_IDENTIFY:
+ identify(powc);
+ break;
+
+ case SPELL_TELEPORT_SELF:
+ you_teleport();
+ break;
+
+ case SPELL_CAUSE_FEAR:
+ mass_enchantment(ENCH_FEAR, powc, MHITYOU);
+ break;
+
+ case SPELL_CREATE_NOISE: // unused, the player can shout to do this - bwr
+ if (!silenced(you.x_pos, you.y_pos))
+ {
+ mpr("You hear a voice call your name!");
+ noisy( 25, you.x_pos, you.y_pos );
+ }
+ break;
+
+ case SPELL_REMOVE_CURSE:
+ remove_curse(false);
+ break;
+
+ case SPELL_MAGIC_DART:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+
+ zapping(ZAP_MAGIC_DARTS, powc, beam);
+ break;
+
+ case SPELL_FIREBALL:
+ fireball(powc);
+ break;
+
+ case SPELL_DELAYED_FIREBALL:
+ // This spell has two main advantages over Fireball:
+ //
+ // (1) The release is instantaneous, so monsters will not
+ // get an action before the player... this allows the
+ // player to hit monsters with a double fireball (this
+ // is why we only allow one delayed fireball at a time,
+ // if you want to allow for more, then the release should
+ // take at least some amount of time).
+ //
+ // The casting of this spell still costs a turn. So
+ // casting Delayed Fireball and immediately releasing
+ // the fireball is only slightly different than casting
+ // a regular Fireball (monsters act in the middle instead
+ // of at the end). This is why we allow for the spell
+ // level discount so that Fireball is free with this spell
+ // (so that it only costs 7 levels instead of 13 to have
+ // both).
+ //
+ // (2) When the fireball is released, it is guaranteed to
+ // go off... the spell only fails at this point. This can
+ // be a large advantage for characters who have difficulty
+ // casting Fireball in their standard equipment. However,
+ // the power level for the actual fireball is determined at
+ // release, so if you do swap out your enhancers you'll
+ // get a less powerful ball when its released. -- bwr
+ //
+ if (!you.attribute[ ATTR_DELAYED_FIREBALL ])
+ {
+ // okay, this message is weak but functional -- bwr
+ mpr( "You feel magically charged." );
+ you.attribute[ ATTR_DELAYED_FIREBALL ] = 1;
+ }
+ else
+ {
+ canned_msg( MSG_NOTHING_HAPPENS );
+ }
+ break;
+
+ case SPELL_STRIKING:
+ if (spell_direction( spd, beam ) == -1)
+ return (false);
+
+ zapping( ZAP_STRIKING, powc, beam );
+ break;
+
+ case SPELL_CONJURE_FLAME:
+ conjure_flame(powc);
+ break;
+
+ case SPELL_DIG:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+
+ if (spd.isMe)
+ {
+ canned_msg(MSG_UNTHINKING_ACT);
+ return (false);
+ }
+ zapping(ZAP_DIGGING, powc, beam);
+ break;
+
+ case SPELL_BOLT_OF_FIRE:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_FIRE, powc, beam);
+ break;
+
+ case SPELL_BOLT_OF_COLD:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_COLD, powc, beam);
+ break;
+
+ case SPELL_LIGHTNING_BOLT:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_LIGHTNING, powc, beam);
+ break;
+
+ case SPELL_BOLT_OF_MAGMA:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_MAGMA, powc, beam);
+ break;
+
+ case SPELL_POLYMORPH_OTHER:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+
+ if (spd.isMe)
+ {
+ mpr("Sorry, it doesn't work like that.");
+ return (false);
+ }
+ zapping(ZAP_POLYMORPH_OTHER, powc, beam);
+ break;
+
+ case SPELL_SLOW:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_SLOWING, powc, beam);
+ break;
+
+ case SPELL_HASTE:
+ if (spell_direction(spd, beam, DIR_NONE, TARG_FRIEND) == -1)
+ return (false);
+ zapping(ZAP_HASTING, powc, beam);
+ break;
+
+ case SPELL_PARALYZE:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_PARALYSIS, powc, beam);
+ break;
+
+ case SPELL_CONFUSE:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_CONFUSION, powc, beam);
+ break;
+
+ case SPELL_CONFUSING_TOUCH:
+ cast_confusing_touch(powc);
+ break;
+
+ case SPELL_SURE_BLADE:
+ cast_sure_blade(powc);
+ break;
+
+ case SPELL_INVISIBILITY:
+ if (spell_direction(spd, beam, DIR_NONE, TARG_FRIEND) == -1)
+ return (false);
+ zapping(ZAP_INVISIBILITY, powc, beam);
+ break;
+
+ case SPELL_THROW_FLAME:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_FLAME, powc, beam);
+ break;
+
+ case SPELL_THROW_FROST:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_FROST, powc, beam);
+ break;
+
+ case SPELL_CONTROLLED_BLINK:
+ blink();
+ break;
+
+ case SPELL_FREEZING_CLOUD:
+ cast_big_c(powc, CLOUD_COLD);
+ break;
+
+ case SPELL_MEPHITIC_CLOUD:
+ stinking_cloud(powc);
+ break;
+
+ case SPELL_RING_OF_FLAMES:
+ cast_ring_of_flames(powc);
+ break;
+
+ case SPELL_RESTORE_STRENGTH:
+ restore_stat(STAT_STRENGTH, false);
+ break;
+
+ case SPELL_RESTORE_INTELLIGENCE:
+ restore_stat(STAT_INTELLIGENCE, false);
+ break;
+
+ case SPELL_RESTORE_DEXTERITY:
+ restore_stat(STAT_DEXTERITY, false);
+ break;
+
+ case SPELL_VENOM_BOLT:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_VENOM_BOLT, powc, beam);
+ break;
+
+ case SPELL_OLGREBS_TOXIC_RADIANCE:
+ cast_toxic_radiance();
+ break;
+
+ case SPELL_TELEPORT_OTHER:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+
+ if (spd.isMe)
+ {
+ mpr("Sorry, it doesn't work like that.");
+ return (false);
+ }
+ // teleport creature (I think)
+ zapping(ZAP_TELEPORTATION, powc, beam);
+ break;
+
+ case SPELL_LESSER_HEALING:
+ cast_healing(5);
+ break;
+
+ case SPELL_GREATER_HEALING:
+ cast_healing(25);
+ break;
+
+ case SPELL_CURE_POISON_I: //jmf: `healing' version? group w/ S_C_P_II?
+ cast_cure_poison(powc);
+ break;
+
+ case SPELL_PURIFICATION:
+ purification();
+ break;
+
+ case SPELL_DEATHS_DOOR:
+ cast_deaths_door(powc);
+ break;
+
+ case SPELL_SELECTIVE_AMNESIA:
+ cast_selective_amnesia(false);
+ break; // Sif Muna power calls with true
+
+ case SPELL_MASS_CONFUSION:
+ mass_enchantment(ENCH_CONFUSION, powc, MHITYOU);
+ break;
+
+ case SPELL_SMITING:
+ cast_smiting(powc);
+ break;
+
+ case SPELL_REPEL_UNDEAD:
+ turn_undead(50);
+ break;
+
+ case SPELL_HOLY_WORD:
+ holy_word(50);
+ break;
+
+ case SPELL_DETECT_CURSE:
+ detect_curse(false);
+ break;
+
+ case SPELL_SUMMON_SMALL_MAMMAL:
+ summon_small_mammals(powc); //jmf: hmm, that's definately *plural* ;-)
+ break;
+
+ case SPELL_ABJURATION_I: //jmf: why not group with SPELL_ABJURATION_II?
+ abjuration(powc);
+ break;
+
+ case SPELL_SUMMON_SCORPIONS:
+ summon_scorpions(powc);
+ break;
+
+ case SPELL_LEVITATION:
+ potion_effect( POT_LEVITATION, powc );
+ break;
+
+ case SPELL_BOLT_OF_DRAINING:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_NEGATIVE_ENERGY, powc, beam);
+ break;
+
+ case SPELL_LEHUDIBS_CRYSTAL_SPEAR:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_CRYSTAL_SPEAR, powc, beam);
+ break;
+
+ case SPELL_BOLT_OF_INACCURACY:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_BEAM_OF_ENERGY, powc, beam);
+ break;
+
+ case SPELL_POISONOUS_CLOUD:
+ cast_big_c(powc, CLOUD_POISON);
+ break;
+
+ case SPELL_POISON_ARROW:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+
+ zapping( ZAP_POISON_ARROW, powc, beam );
+ break;
+
+ case SPELL_FIRE_STORM:
+ cast_fire_storm(powc);
+ break;
+
+ case SPELL_DETECT_TRAPS:
+ strcpy(info, "You detect ");
+ strcat(info, (detect_traps(powc) > 0) ? "some traps!" : "nothing.");
+ mpr(info);
+ break;
+
+ case SPELL_BLINK:
+ random_blink(true);
+ break;
+
+ case SPELL_ISKENDERUNS_MYSTIC_BLAST:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+
+ zapping( ZAP_MYSTIC_BLAST, powc, beam );
+ break;
+
+ case SPELL_SWARM:
+ summon_swarm( powc, false, false );
+ break;
+
+ case SPELL_SUMMON_HORRIBLE_THINGS:
+ summon_things(powc);
+ break;
+
+ case SPELL_ENSLAVEMENT:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ if (spd.isMe)
+ {
+ canned_msg(MSG_UNTHINKING_ACT);
+ return (false);
+ }
+ zapping(ZAP_ENSLAVEMENT, powc, beam);
+ break;
+
+ case SPELL_MAGIC_MAPPING:
+ if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
+ mpr("You feel momentarily disoriented.");
+ else if (you.level_type == LEVEL_PANDEMONIUM)
+ mpr("Your Earth magic cannot map Pandemonium.");
+ else
+ {
+ mpr( "You feel aware of your surroundings." );
+ powc = stepdown_value( powc, 10, 10, 40, 45 );
+ magic_mapping( 5 + powc, 50 + random2avg( powc * 2, 2 ) );
+ }
+ break;
+
+ case SPELL_HEAL_OTHER:
+ if (spell_direction(spd, beam, DIR_NONE, TARG_FRIEND) == -1)
+ return (false);
+
+ if (spd.isMe)
+ {
+ mpr("Sorry, it doesn't work like that.");
+ return (false);
+ }
+ zapping(ZAP_HEALING, powc, beam);
+ break;
+
+ case SPELL_ANIMATE_DEAD:
+ mpr("You call on the dead to walk for you.");
+ animate_dead(powc + 1, BEH_FRIENDLY, you.pet_target, 1);
+ break;
+
+ case SPELL_PAIN:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ dec_hp(1, false);
+ zapping(ZAP_PAIN, powc, beam);
+ break;
+
+ case SPELL_EXTENSION:
+ extension(powc);
+ break;
+
+ case SPELL_CONTROL_UNDEAD:
+ mass_enchantment(ENCH_CHARM, powc, MHITYOU);
+ break;
+
+ case SPELL_ANIMATE_SKELETON:
+ mpr("You attempt to give life to the dead...");
+ animate_a_corpse(you.x_pos, you.y_pos, BEH_FRIENDLY, you.pet_target,
+ CORPSE_SKELETON);
+ break;
+
+ case SPELL_VAMPIRIC_DRAINING:
+ vampiric_drain(powc);
+ break;
+
+ case SPELL_SUMMON_WRAITHS:
+ summon_undead(powc);
+ break;
+
+ case SPELL_DETECT_ITEMS:
+ detect_items(powc);
+ break;
+
+ case SPELL_BORGNJORS_REVIVIFICATION:
+ cast_revivification(powc);
+ break;
+
+ case SPELL_BURN:
+ burn_freeze(powc, BEAM_FIRE);
+ break;
+
+ case SPELL_FREEZE:
+ burn_freeze(powc, BEAM_COLD);
+ break;
+
+ case SPELL_SUMMON_ELEMENTAL:
+ summon_elemental(powc, 0, 2);
+ break;
+
+ case SPELL_OZOCUBUS_REFRIGERATION:
+ cast_refrigeration(powc);
+ break;
+
+ case SPELL_STICKY_FLAME:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_STICKY_FLAME, powc, beam);
+ break;
+
+ case SPELL_SUMMON_ICE_BEAST:
+ summon_ice_beast_etc(powc, MONS_ICE_BEAST);
+ break;
+
+ case SPELL_OZOCUBUS_ARMOUR:
+ ice_armour(powc, false);
+ break;
+
+ case SPELL_CALL_IMP:
+ if (one_chance_in(3))
+ summon_ice_beast_etc(powc, MONS_WHITE_IMP);
+ else if (one_chance_in(7))
+ summon_ice_beast_etc(powc, MONS_SHADOW_IMP);
+ else
+ summon_ice_beast_etc(powc, MONS_IMP);
+ break;
+
+ case SPELL_REPEL_MISSILES:
+ missile_prot(powc);
+ break;
+
+ case SPELL_BERSERKER_RAGE:
+ cast_berserk();
+ break;
+
+ case SPELL_DISPEL_UNDEAD:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_DISPEL_UNDEAD, powc, beam);
+ break;
+
+ case SPELL_GUARDIAN:
+ summon_ice_beast_etc(powc, MONS_ANGEL);
+ break;
+
+ //jmf: FIXME: SPELL_PESTILENCE?
+
+ case SPELL_THUNDERBOLT:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_LIGHTNING, powc, beam);
+ break;
+
+ case SPELL_FLAME_OF_CLEANSING:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_CLEANSING_FLAME, powc, beam);
+ break;
+
+ //jmf: FIXME: SPELL_SHINING_LIGHT?
+
+ case SPELL_SUMMON_DAEVA:
+ summon_ice_beast_etc(powc, MONS_DAEVA);
+ break;
+
+ case SPELL_ABJURATION_II:
+ abjuration(powc);
+ break;
+
+ // Remember that most holy spells above don't yet use powc!
+
+ case SPELL_TWISTED_RESURRECTION:
+ cast_twisted(powc, BEH_FRIENDLY, you.pet_target);
+ break;
+
+ case SPELL_REGENERATION:
+ cast_regen(powc);
+ break;
+
+ case SPELL_BONE_SHARDS:
+ cast_bone_shards(powc);
+ break;
+
+ case SPELL_BANISHMENT:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_BANISHMENT, powc, beam);
+ break;
+
+ case SPELL_CIGOTUVIS_DEGENERATION:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+
+ if (spd.isMe)
+ {
+ canned_msg(MSG_UNTHINKING_ACT);
+ return (false);
+ }
+ zapping(ZAP_DEGENERATION, powc, beam);
+ break;
+
+ case SPELL_STING:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_STING, powc, beam);
+ break;
+
+ case SPELL_SUBLIMATION_OF_BLOOD:
+ sublimation(powc);
+ break;
+
+ case SPELL_TUKIMAS_DANCE:
+ dancing_weapon(powc, false);
+ break;
+
+ case SPELL_HELLFIRE:
+ // should only be available from:
+ // staff of Dispater & Sceptre of Asmodeus
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+
+ zapping(ZAP_HELLFIRE, powc, beam);
+ break;
+
+ case SPELL_SUMMON_DEMON:
+ mpr("You open a gate to Pandemonium!");
+ summon_ice_beast_etc(powc, summon_any_demon(DEMON_COMMON));
+ break;
+
+ case SPELL_DEMONIC_HORDE:
+ mpr("You open a gate to Pandemonium!");
+ dem_hor2 = 3 + random2(5);
+ for (dem_hor = 0; dem_hor < 4 + dem_hor2; dem_hor++)
+ {
+ summon_ice_beast_etc(powc, summon_any_demon(DEMON_LESSER));
+ }
+ break;
+
+ case SPELL_SUMMON_GREATER_DEMON:
+ mpr("You open a gate to Pandemonium!");
+
+ dem_hor = ((random2(powc) <= 5) ? BEH_HOSTILE : BEH_CHARMED);
+
+ if (dem_hor == BEH_CHARMED)
+ mpr("You don't feel so good about this...");
+
+ create_monster( summon_any_demon(DEMON_GREATER), ENCH_ABJ_V, dem_hor,
+ you.x_pos, you.y_pos, MHITYOU, 250 );
+
+ break;
+
+ case SPELL_CORPSE_ROT:
+ corpse_rot(0);
+ break;
+
+ case SPELL_TUKIMAS_VORPAL_BLADE:
+ if (!brand_weapon(SPWPN_VORPAL, powc))
+ canned_msg(MSG_SPELL_FIZZLES);
+ break;
+
+ case SPELL_FIRE_BRAND:
+ if (!brand_weapon(SPWPN_FLAMING, powc))
+ canned_msg(MSG_SPELL_FIZZLES);
+ break;
+
+ case SPELL_FREEZING_AURA:
+ if (!brand_weapon(SPWPN_FREEZING, powc))
+ canned_msg(MSG_SPELL_FIZZLES);
+ break;
+
+ case SPELL_LETHAL_INFUSION:
+ if (!brand_weapon(SPWPN_DRAINING, powc))
+ canned_msg(MSG_SPELL_FIZZLES);
+ break;
+
+ case SPELL_MAXWELLS_SILVER_HAMMER:
+ if (!brand_weapon(SPWPN_DUMMY_CRUSHING, powc))
+ canned_msg(MSG_SPELL_FIZZLES);
+ break;
+
+ case SPELL_POISON_WEAPON:
+ if (!brand_weapon(SPWPN_VENOM, powc))
+ canned_msg(MSG_SPELL_FIZZLES);
+ break;
+
+ case SPELL_CRUSH:
+ burn_freeze(powc, BEAM_MISSILE);
+ break;
+
+ case SPELL_BOLT_OF_IRON:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_IRON_BOLT, powc, beam);
+ break;
+
+ case SPELL_STONE_ARROW:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_STONE_ARROW, powc, beam);
+ break;
+
+ case SPELL_TOMB_OF_DOROKLOHE:
+ entomb();
+ break;
+
+ case SPELL_STONEMAIL:
+ stone_scales(powc);
+ break;
+
+ case SPELL_SHOCK:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_ELECTRICITY, powc, beam);
+ break;
+
+ case SPELL_SWIFTNESS:
+ cast_swiftness(powc);
+ break;
+
+ case SPELL_FLY:
+ cast_fly(powc);
+ break;
+
+ case SPELL_INSULATION:
+ cast_insulation(powc);
+ break;
+
+ case SPELL_ORB_OF_ELECTROCUTION:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_ORB_OF_ELECTRICITY, powc, beam);
+ break;
+
+ case SPELL_DETECT_CREATURES:
+ detect_creatures(powc);
+ break;
+
+ case SPELL_CURE_POISON_II: // poison magic version of cure poison
+ cast_cure_poison(powc);
+ break;
+
+ case SPELL_CONTROL_TELEPORT:
+ cast_teleport_control(powc);
+ break;
+
+ case SPELL_POISON_AMMUNITION:
+ cast_poison_ammo();
+ break;
+
+ case SPELL_RESIST_POISON:
+ cast_resist_poison(powc);
+ break;
+
+ case SPELL_PROJECTED_NOISE:
+ project_noise();
+ break;
+
+ case SPELL_ALTER_SELF:
+ if (!enough_hp( you.hp_max / 2, true ))
+ {
+ mpr( "Your body is in too poor a condition "
+ "for this spell to function." );
+
+ return (false);
+ }
+
+ mpr("Your body is suffused with transfigurative energy!");
+
+ set_hp( 1 + random2(you.hp), false );
+
+ if (!mutate(100, false))
+ mpr("Odd... you don't feel any different.");
+ break;
+
+ case SPELL_DEBUGGING_RAY:
+ if (spell_direction(spd, beam, DIR_NONE, TARG_ANY) == -1)
+ return (false);
+ zapping(ZAP_DEBUGGING_RAY, powc, beam);
+ break;
+
+ case SPELL_RECALL:
+ recall(0);
+ break;
+
+ case SPELL_PORTAL:
+ portal();
+ break;
+
+ case SPELL_AGONY:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+
+ if (spd.isMe)
+ {
+ canned_msg(MSG_UNTHINKING_ACT);
+ return (false);
+ }
+ zapping(ZAP_AGONY, powc, beam);
+ break;
+
+ case SPELL_SPIDER_FORM:
+ transform(powc, TRAN_SPIDER);
+ break;
+
+ case SPELL_DISRUPT:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+
+ zapping(ZAP_DISRUPTION, powc, beam);
+ break;
+
+ case SPELL_DISINTEGRATE:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+
+ if (spd.isMe)
+ {
+ canned_msg(MSG_UNTHINKING_ACT);
+ return (false);
+ }
+ zapping(ZAP_DISINTEGRATION, powc, beam);
+ break;
+
+ case SPELL_BLADE_HANDS:
+ transform(powc, TRAN_BLADE_HANDS);
+ break;
+
+ case SPELL_STATUE_FORM:
+ transform(powc, TRAN_STATUE);
+ break;
+
+ case SPELL_ICE_FORM:
+ transform(powc, TRAN_ICE_BEAST);
+ break;
+
+ case SPELL_DRAGON_FORM:
+ transform(powc, TRAN_DRAGON);
+ break;
+
+ case SPELL_NECROMUTATION:
+ transform(powc, TRAN_LICH);
+ break;
+
+ case SPELL_DEATH_CHANNEL:
+ cast_death_channel(powc);
+ break;
+
+ case SPELL_SYMBOL_OF_TORMENT:
+ if (you.is_undead || you.mutation[MUT_TORMENT_RESISTANCE])
+ {
+ mpr("To torment others, one must first know what torment means. ");
+ return (false);
+ }
+ torment(you.x_pos, you.y_pos);
+ break;
+
+ case SPELL_DEFLECT_MISSILES:
+ deflection(powc);
+ break;
+
+ case SPELL_ORB_OF_FRAGMENTATION:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_ORB_OF_FRAGMENTATION, powc, beam);
+ break;
+
+ case SPELL_ICE_BOLT:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_ICE_BOLT, powc, beam);
+ break;
+
+ case SPELL_ARC:
+ burn_freeze(powc, BEAM_ELECTRICITY);
+ break;
+
+ case SPELL_AIRSTRIKE:
+ airstrike(powc);
+ break;
+
+ case SPELL_ICE_STORM:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ zapping(ZAP_ICE_STORM, powc, beam);
+ break;
+
+ case SPELL_SHADOW_CREATURES:
+ mpr( "Wisps of shadow whirl around you..." );
+ create_monster( RANDOM_MONSTER, ENCH_ABJ_II, BEH_FRIENDLY,
+ you.x_pos, you.y_pos, you.pet_target, 250 );
+ break;
+
+ //jmf: new spells 19mar2000
+ case SPELL_FLAME_TONGUE:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+
+ if (spd.isMe)
+ {
+ canned_msg(MSG_UNTHINKING_ACT);
+ return (false);
+ }
+ zapping(ZAP_FLAME_TONGUE, powc, beam);
+
+ /*
+ // This is not the place for this sort of power adjustment,
+ // it just makes it harder to balance -- bwr
+ zapping(ZAP_FLAME_TONGUE, 2 + random2(4) + random2(4)
+ + random2(powc) / 25, beam);
+ */
+ break;
+
+ case SPELL_PASSWALL:
+ cast_passwall(powc);
+ break;
+
+ case SPELL_IGNITE_POISON:
+ cast_ignite_poison(powc);
+ break;
+
+ case SPELL_STICKS_TO_SNAKES:
+ cast_sticks_to_snakes(powc);
+ break;
+
+ case SPELL_SUMMON_LARGE_MAMMAL:
+ cast_summon_large_mammal(powc);
+ break;
+
+ case SPELL_SUMMON_DRAGON:
+ cast_summon_dragon(powc);
+ break;
+
+ case SPELL_TAME_BEASTS:
+ cast_tame_beasts(powc);
+ break;
+
+ case SPELL_SLEEP:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+
+ if (spd.isMe)
+ {
+ canned_msg(MSG_UNTHINKING_ACT);
+ return (false);
+ }
+
+ zapping(ZAP_SLEEP, powc, beam);
+ break;
+
+ case SPELL_MASS_SLEEP:
+ cast_mass_sleep(powc);
+ break;
+
+ case SPELL_DETECT_MAGIC:
+ mpr("FIXME: implement!");
+ break;
+
+ case SPELL_DETECT_SECRET_DOORS:
+ cast_detect_secret_doors(powc);
+ break;
+
+ case SPELL_SEE_INVISIBLE:
+ cast_see_invisible(powc);
+ break;
+
+ case SPELL_FORESCRY:
+ cast_forescry(powc);
+ break;
+
+ case SPELL_SUMMON_BUTTERFLIES:
+ cast_summon_butterflies(powc);
+ break;
+
+ case SPELL_WARP_BRAND:
+ if (!brand_weapon(SPWPN_DISTORTION, powc))
+ canned_msg(MSG_SPELL_FIZZLES);
+ break;
+
+ case SPELL_SILENCE:
+ cast_silence(powc);
+ break;
+
+ case SPELL_SHATTER:
+ cast_shatter(powc);
+ break;
+
+ case SPELL_DISPERSAL:
+ cast_dispersal(powc);
+ break;
+
+ case SPELL_DISCHARGE:
+ cast_discharge(powc);
+ break;
+
+ case SPELL_BEND:
+ cast_bend(powc);
+ break;
+
+ case SPELL_BACKLIGHT:
+ if (spell_direction(spd, beam) == -1)
+ return (false);
+ if (spd.isMe)
+ {
+ canned_msg(MSG_UNTHINKING_ACT);
+ return (false);
+ }
+ zapping(ZAP_BACKLIGHT, powc + 10, beam);
+ break;
+
+ case SPELL_INTOXICATE:
+ cast_intoxicate(powc);
+ break;
+
+ case SPELL_GLAMOUR:
+ cast_glamour(powc);
+ break;
+
+ case SPELL_EVAPORATE:
+ cast_evaporate(powc);
+ break;
+
+ case SPELL_FULSOME_DISTILLATION:
+ cast_fulsome_distillation(powc);
+ break;
+
+ case SPELL_FRAGMENTATION:
+ cast_fragmentation(powc);
+ break;
+
+ case SPELL_AIR_WALK:
+ transform(powc, TRAN_AIR);
+ break;
+
+ case SPELL_SANDBLAST:
+ cast_sandblast(powc);
+ break;
+
+ case SPELL_ROTTING:
+ cast_rotting(powc);
+ break;
+
+ case SPELL_SHUGGOTH_SEED:
+ cast_shuggoth_seed(powc);
+ break;
+
+ case SPELL_CONDENSATION_SHIELD:
+ cast_condensation_shield(powc);
+ break;
+
+ case SPELL_SEMI_CONTROLLED_BLINK:
+ cast_semi_controlled_blink(powc); //jmf: powc is ignored
+ break;
+
+ case SPELL_STONESKIN:
+ cast_stoneskin(powc);
+ break;
+
+ case SPELL_SIMULACRUM:
+ simulacrum(powc);
+ break;
+
+ case SPELL_CONJURE_BALL_LIGHTNING:
+ cast_conjure_ball_lightning(powc);
+ break;
+
+ case SPELL_TWIST:
+ cast_twist(powc);
+ break;
+
+ case SPELL_FAR_STRIKE:
+ cast_far_strike(powc);
+ break;
+
+ case SPELL_SWAP:
+ cast_swap(powc);
+ break;
+
+ case SPELL_APPORTATION:
+ cast_apportation(powc);
+ break;
+
+ default:
+ mpr("Invalid spell!");
+ break;
+ } // end switch
+
+ return (true);
+} // end you_spells()
+
+void exercise_spell( int spell, bool spc, bool success )
+{
+ // (!success) reduces skill increase for miscast spells
+ int ndx = 0;
+ int skill;
+ int workout = 0;
+
+ unsigned int disciplines = spell_type(spell);
+
+ //jmf: evil evil evil -- exclude HOLY bit
+ disciplines &= (~SPTYP_HOLY);
+
+ int skillcount = count_bits( disciplines );
+
+ if (!success)
+ skillcount += 4 + random2(10);
+
+ for (ndx = 0; ndx <= SPTYP_LAST_EXPONENT; ndx++)
+ {
+ if (!spell_typematch( spell, 1 << ndx ))
+ continue;
+
+ skill = spell_type2skill( 1 << ndx );
+ workout = (random2(1 + spell_difficulty(spell)) / skillcount);
+
+ if (!one_chance_in(5))
+ workout++; // most recently, this was an automatic add {dlb}
+
+ exercise( skill, workout );
+ }
+
+ /* ******************************************************************
+ Other recent formulae for the above:
+
+ * workout = random2(spell_difficulty(spell_ex)
+ * (10 + (spell_difficulty(spell_ex) * 2 )) / 10 / spellsy + 1);
+
+ * workout = spell_difficulty(spell_ex)
+ * (15 + spell_difficulty(spell_ex)) / 15 / spellsy;
+
+ spellcasting had also been generally exercised at the same time
+ ****************************************************************** */
+
+ if (spc)
+ {
+ exercise(SK_SPELLCASTING, one_chance_in(3) ? 1
+ : random2(1 + random2(spell_difficulty(spell))));
+ }
+
+ //+ (coinflip() ? 1 : 0) + (skillcount ? 1 : 0));
+
+/* ******************************************************************
+ 3.02 was:
+
+ if ( spc && spellsy )
+ exercise(SK_SPELLCASTING, random2(random2(spell_difficulty(spell_ex) + 1) / spellsy)); // + 1);
+ else if ( spc )
+ exercise(SK_SPELLCASTING, random2(random2(spell_difficulty(spell_ex)))); // + 1);
+****************************************************************** */
+
+} // end exercise_spell()
+
+/* This determines how likely it is that more powerful wild magic effects
+ * will occur. Set to 100 for the old probabilities (although the individual
+ * effects have been made much nastier since then).
+ */
+
+bool miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail,
+ int force_effect, const char *cause )
+{
+/* sp_type is the type of the spell
+ * mag_pow is overall power of the spell or effect (ie its level)
+ * mag_fail is the degree to which you failed
+ * force_effect forces a certain effect to occur. Currently unused.
+ */
+ struct bolt beam;
+ bool failMsg = true;
+
+ int loopj = 0;
+ int spec_effect = 0;
+ int hurted = 0;
+
+ if (sp_type == SPTYP_RANDOM)
+ sp_type = 1 << (random2(12));
+
+ spec_effect = (mag_pow * mag_fail * (10 + mag_pow) / 7
+ * WILD_MAGIC_NASTINESS) / 100;
+
+ if (force_effect == 100
+ && random2(40) > spec_effect && random2(40) > spec_effect)
+ {
+ canned_msg(MSG_NOTHING_HAPPENS);
+ return (false);
+ }
+
+ // setup beam
+ beam.isTracer = false;
+
+ spec_effect = spec_effect / 100;
+
+#if DEBUG_DIAGNOSTICS
+ const int old_fail = spec_effect;
+#endif
+
+ spec_effect = random2(spec_effect);
+
+ if (spec_effect > 3)
+ spec_effect = 3;
+ else if (spec_effect < 0)
+ spec_effect = 0;
+
+#if DEBUG_DIAGNOSTICS
+ snprintf( info, INFO_SIZE, "Sptype: %d, failure1: %d, failure2: %d",
+ sp_type, old_fail, spec_effect );
+ mpr( info, MSGCH_DIAGNOSTICS );
+#endif
+
+ if (force_effect != 100)
+ spec_effect = force_effect;
+
+ switch (sp_type)
+ {
+ case SPTYP_CONJURATION:
+ switch (spec_effect)
+ {
+ case 0: // just a harmless message
+ switch (random2(10))
+ {
+ case 0:
+ snprintf( info, INFO_SIZE, "Sparks fly from your %s!",
+ your_hand(true) );
+ mpr(info);
+ break;
+
+ case 1:
+ mpr("The air around you crackles with energy!");
+ break;
+
+ case 2:
+ snprintf( info, INFO_SIZE, "Wisps of smoke drift from your %s.",
+ your_hand(true));
+ mpr(info);
+ break;
+ case 3:
+ mpr("You feel a strange surge of energy!");
+ break;
+ case 4:
+ mpr("You are momentarily dazzled by a flash of light!");
+ break;
+ case 5:
+ mpr("Strange energies run through your body.");
+ break;
+ case 6:
+ mpr("Your skin tingles.");
+ break;
+ case 7:
+ mpr("Your skin glows momentarily.");
+ break;
+ case 8:
+ canned_msg(MSG_NOTHING_HAPPENS);
+ break;
+ case 9:
+ // josh declares mummies cannot smell {dlb}
+ if (you.species != SP_MUMMY)
+ mpr("You smell something strange.");
+ else
+ mpr("Your bandages flutter.");
+ }
+ break;
+
+ case 1: // a bit less harmless stuff
+ switch (random2(2))
+ {
+ case 0:
+ snprintf( info, INFO_SIZE, "Smoke pours from your %s!",
+ your_hand(true));
+ mpr(info);
+
+ big_cloud( CLOUD_GREY_SMOKE, you.x_pos, you.y_pos, 20,
+ 7 + random2(7) );
+ break;
+ case 1:
+ mpr("A wave of violent energy washes through your body!");
+ ouch(6 + random2avg(7, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+ }
+ break;
+
+ case 2: // rather less harmless stuff
+ switch (random2(2))
+ {
+ case 0:
+ mpr("Energy rips through your body!");
+ ouch(9 + random2avg(17, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+ case 1:
+ mpr("You are caught in a violent explosion!");
+ beam.type = SYM_BURST;
+ beam.damage = dice_def( 3, 12 );
+ beam.flavour = BEAM_MISSILE; // unsure about this
+ // BEAM_EXPLOSION instead? {dlb}
+
+ beam.target_x = you.x_pos;
+ beam.target_y = you.y_pos;
+ strcpy(beam.beam_name, "explosion");
+ beam.colour = random_colour();
+ beam.beam_source = NON_MONSTER;
+ beam.thrower = (cause) ? KILL_MISC : KILL_YOU;
+ beam.aux_source = cause;
+ beam.ex_size = 1;
+
+ explosion(beam);
+ break;
+ }
+ break;
+
+ case 3: // considerably less harmless stuff
+ switch (random2(2))
+ {
+ case 0:
+ mpr("You are blasted with magical energy!");
+ ouch(12 + random2avg(29, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+ case 1:
+ mpr("There is a sudden explosion of magical energy!");
+ beam.type = SYM_BURST;
+ beam.damage = dice_def( 3, 20 );
+ beam.flavour = BEAM_MISSILE; // unsure about this
+ // BEAM_EXPLOSION instead? {dlb}
+ beam.target_x = you.x_pos;
+ beam.target_y = you.y_pos;
+ strcpy(beam.beam_name, "explosion");
+ beam.colour = random_colour();
+ beam.beam_source = NON_MONSTER;
+ beam.thrower = (cause) ? KILL_MISC : KILL_YOU;
+ beam.aux_source = cause;
+ beam.ex_size = coinflip()?1:2;
+
+ explosion(beam);
+ break;
+ }
+ break;
+ }
+ break; // end conjuration
+
+ case SPTYP_ENCHANTMENT:
+ switch (spec_effect)
+ {
+ case 0: // harmless messages only
+ switch (random2(10))
+ {
+ case 0:
+ snprintf( info, INFO_SIZE, "Your %s glow momentarily.",
+ your_hand(true) );
+ mpr(info);
+ break;
+ case 1:
+ mpr("The air around you crackles with energy!");
+ break;
+ case 2:
+ mpr("Multicolored lights dance before your eyes!");
+ break;
+ case 3:
+ mpr("You feel a strange surge of energy!");
+ break;
+ case 4:
+ mpr("Waves of light ripple over your body.");
+ break;
+ case 5:
+ mpr("Strange energies run through your body.");
+ break;
+ case 6:
+ mpr("Your skin tingles.");
+ break;
+ case 7:
+ mpr("Your skin glows momentarily.");
+ break;
+ case 8:
+ canned_msg(MSG_NOTHING_HAPPENS);
+ break;
+ case 9:
+ if (!silenced(you.x_pos, you.y_pos))
+ mpr("You hear something strange.");
+ else if (you.attribute[ATTR_TRANSFORMATION] != TRAN_AIR)
+ mpr("Your skull vibrates slightly.");
+ else
+ canned_msg(MSG_NOTHING_HAPPENS);
+ break;
+ }
+ break;
+
+ case 1: // slightly annoying
+ switch (random2(2))
+ {
+ case 0:
+ potion_effect(POT_LEVITATION, 20);
+ break;
+ case 1:
+ random_uselessness(2 + random2(7), 0);
+ break;
+ }
+ break;
+
+ case 2: // much more annoying
+ switch (random2(7))
+ {
+ case 0:
+ case 1:
+ case 2:
+ mpr("You sense a malignant aura.");
+ curse_an_item(0, 0);
+ break;
+ case 3:
+ case 4:
+ case 5:
+ potion_effect(POT_SLOWING, 10);
+ break;
+ case 6:
+ potion_effect(POT_BERSERK_RAGE, 10);
+ break;
+ }
+ break;
+
+ case 3: // potentially lethal
+ switch (random2(4))
+ {
+ case 0:
+ do
+ {
+ curse_an_item(0, 0);
+ loopj = random2(3);
+ }
+ while (loopj != 0);
+
+ mpr("You sense an overwhelmingly malignant aura!");
+ break;
+ case 1:
+ potion_effect(POT_PARALYSIS, 10);
+ break;
+ case 2:
+ potion_effect(POT_CONFUSION, 10);
+ break;
+ case 3:
+ mpr("You feel saturated with unharnessed energies!");
+ you.magic_contamination += random2avg(19,3);
+ break;
+ }
+ break;
+ }
+ break; // end enchantments
+
+ case SPTYP_TRANSLOCATION:
+ switch (spec_effect)
+ {
+ case 0: // harmless messages only
+ switch (random2(10))
+ {
+ case 0:
+ mpr("Space warps around you.");
+ break;
+ case 1:
+ mpr("The air around you crackles with energy!");
+ break;
+ case 2:
+ mpr("You feel a wrenching sensation.");
+ break;
+ case 3:
+ mpr("You feel a strange surge of energy!");
+ break;
+ case 4:
+ mpr("You spin around.");
+ break;
+ case 5:
+ mpr("Strange energies run through your body.");
+ break;
+ case 6:
+ mpr("Your skin tingles.");
+ break;
+ case 7:
+ mpr("The world appears momentarily distorted!");
+ break;
+ case 8:
+ canned_msg(MSG_NOTHING_HAPPENS);
+ break;
+ case 9:
+ mpr("You feel uncomfortable.");
+ break;
+ }
+ break;
+
+ case 1: // mostly harmless
+ switch (random2(6))
+ {
+ case 0:
+ case 1:
+ case 2:
+ mpr("You are caught in a localised field of spatial distortion.");
+ ouch(4 + random2avg(9, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+ case 3:
+ case 4:
+ mpr("Space bends around you!");
+ random_blink(false);
+ ouch(4 + random2avg(7, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+ case 5:
+ mpr("Space twists in upon itself!");
+ create_monster( MONS_SPATIAL_VORTEX, ENCH_ABJ_III, BEH_HOSTILE,
+ you.x_pos, you.y_pos, MHITYOU, 250 );
+ break;
+ }
+ break;
+
+ case 2: // less harmless
+ switch (random2(7))
+ {
+ case 0:
+ case 1:
+ case 2:
+ mpr("You are caught in a strong localised spatial distortion.");
+ ouch(9 + random2avg(23, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+ case 3:
+ case 4:
+ mpr("Space warps around you!");
+
+ if (one_chance_in(3))
+ you_teleport2( true );
+ else
+ random_blink( false );
+
+ ouch(5 + random2avg(9, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ potion_effect(POT_CONFUSION, 40);
+ break;
+ case 5:
+ mpr("Space twists in upon itself!");
+
+ for (loopj = 0; loopj < 2 + random2(3); loopj++)
+ {
+ create_monster( MONS_SPATIAL_VORTEX, ENCH_ABJ_III,
+ BEH_HOSTILE, you.x_pos, you.y_pos,
+ MHITYOU, 250 );
+ }
+ break;
+ case 6:
+ mpr("You are cast into the Abyss!");
+ more();
+ banished(DNGN_ENTER_ABYSS); // sends you to the abyss
+ break;
+ }
+ break;
+
+ case 3: // much less harmless
+
+ switch (random2(4))
+ {
+ case 0:
+ mpr("You are caught in an extremely strong localised spatial distortion!");
+ ouch(15 + random2avg(29, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+ case 1:
+ mpr("Space warps crazily around you!");
+ you_teleport2( true );
+
+ ouch(9 + random2avg(17, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ potion_effect(POT_CONFUSION, 60);
+ break;
+ case 2:
+ mpr("You are cast into the Abyss!");
+ more();
+ banished(DNGN_ENTER_ABYSS); // sends you to the abyss
+ break;
+ case 3:
+ mpr("You feel saturated with unharnessed energies!");
+ you.magic_contamination += random2avg(19,3);
+ break;
+ }
+ break;
+ }
+ break; // end translocations
+
+ case SPTYP_SUMMONING:
+ switch (spec_effect)
+ {
+ case 0: // harmless messages only
+ switch (random2(10))
+ {
+ case 0:
+ mpr("Shadowy shapes form in the air around you, then vanish.");
+ break;
+ case 1:
+ if (!silenced(you.x_pos, you.y_pos))
+ mpr("You hear strange voices.");
+ else
+ mpr("You feel momentarily dizzy.");
+ break;
+ case 2:
+ mpr("Your head hurts.");
+ break;
+ case 3:
+ mpr("You feel a strange surge of energy!");
+ break;
+ case 4:
+ mpr("Your brain hurts!");
+ break;
+ case 5:
+ mpr("Strange energies run through your body.");
+ break;
+ case 6:
+ mpr("The world appears momentarily distorted.");
+ break;
+ case 7:
+ mpr("Space warps around you.");
+ break;
+ case 8:
+ canned_msg(MSG_NOTHING_HAPPENS);
+ break;
+ case 9:
+ mpr("Distant voices call out to you!");
+ break;
+ }
+ break;
+
+ case 1: // a little bad
+ switch (random2(6))
+ {
+ case 0: // identical to translocation
+ case 1:
+ case 2:
+ mpr("You are caught in a localised spatial distortion.");
+ ouch(5 + random2avg(9, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+
+ case 3:
+ mpr("Space twists in upon itself!");
+ create_monster( MONS_SPATIAL_VORTEX, ENCH_ABJ_III, BEH_HOSTILE,
+ you.x_pos, you.y_pos, MHITYOU, 250 );
+ break;
+
+ case 4:
+ case 5:
+ if (create_monster( summon_any_demon(DEMON_LESSER), ENCH_ABJ_V,
+ BEH_HOSTILE, you.x_pos, you.y_pos,
+ MHITYOU, 250 ) != -1)
+ {
+ mpr("Something appears in a flash of light!");
+ }
+ break;
+ }
+
+ case 2: // more bad
+ switch (random2(6))
+ {
+ case 0:
+ mpr("Space twists in upon itself!");
+
+ for (loopj = 0; loopj < 2 + random2(3); loopj++)
+ {
+ create_monster( MONS_SPATIAL_VORTEX, ENCH_ABJ_III,
+ BEH_HOSTILE, you.x_pos, you.y_pos,
+ MHITYOU, 250 );
+ }
+ break;
+
+ case 1:
+ case 2:
+ if (create_monster( summon_any_demon(DEMON_COMMON), ENCH_ABJ_V,
+ BEH_HOSTILE, you.x_pos, you.y_pos,
+ MHITYOU, 250) != -1)
+ {
+ mpr("Something forms out of thin air!");
+ }
+ break;
+
+ case 3:
+ case 4:
+ case 5:
+ mpr("A chorus of chattering voices calls out to you!");
+ create_monster( summon_any_demon(DEMON_LESSER), ENCH_ABJ_V,
+ BEH_HOSTILE, you.x_pos, you.y_pos,
+ MHITYOU, 250 );
+
+ create_monster( summon_any_demon(DEMON_LESSER), ENCH_ABJ_V,
+ BEH_HOSTILE, you.x_pos, you.y_pos,
+ MHITYOU, 250 );
+
+ if (coinflip())
+ {
+ create_monster( summon_any_demon(DEMON_LESSER), ENCH_ABJ_V,
+ BEH_HOSTILE, you.x_pos, you.y_pos,
+ MHITYOU, 250 );
+ }
+
+ if (coinflip())
+ {
+ create_monster( summon_any_demon(DEMON_LESSER), ENCH_ABJ_V,
+ BEH_HOSTILE, you.x_pos, you.y_pos,
+ MHITYOU, 250 );
+ }
+ break;
+ }
+ break;
+
+ case 3: // more bad
+ switch (random2(4))
+ {
+ case 0:
+ if (create_monster( MONS_ABOMINATION_SMALL, 0, BEH_HOSTILE,
+ you.x_pos, you.y_pos, MHITYOU, 250 ) != -1)
+ {
+ mpr("Something forms out of thin air.");
+ }
+ break;
+
+ case 1:
+ if (create_monster( summon_any_demon(DEMON_GREATER), 0,
+ BEH_HOSTILE, you.x_pos, you.y_pos,
+ MHITYOU, 250 ) != -1)
+ {
+ mpr("You sense a hostile presence.");
+ }
+ break;
+
+ case 2:
+ mpr("Something turns its malign attention towards you...");
+
+ create_monster( summon_any_demon(DEMON_COMMON), ENCH_ABJ_III,
+ BEH_HOSTILE, you.x_pos, you.y_pos,
+ MHITYOU, 250 );
+
+ create_monster( summon_any_demon(DEMON_COMMON), ENCH_ABJ_III,
+ BEH_HOSTILE, you.x_pos, you.y_pos,
+ MHITYOU, 250);
+
+ if (coinflip())
+ {
+ create_monster(summon_any_demon(DEMON_COMMON), ENCH_ABJ_III,
+ BEH_HOSTILE, you.x_pos, you.y_pos,
+ MHITYOU, 250);
+ }
+ break;
+
+ case 3:
+ mpr("You are cast into the Abyss!");
+ banished(DNGN_ENTER_ABYSS);
+ break;
+ }
+ break;
+ } // end Summonings
+ break;
+
+ case SPTYP_DIVINATION:
+ switch (spec_effect)
+ {
+ case 0: // just a harmless message
+ switch (random2(10))
+ {
+ case 0:
+ mpr("Weird images run through your mind.");
+ break;
+ case 1:
+ if (!silenced(you.x_pos, you.y_pos))
+ mpr("You hear strange voices.");
+ else
+ mpr("Your nose twitches.");
+ break;
+ case 2:
+ mpr("Your head hurts.");
+ break;
+ case 3:
+ mpr("You feel a strange surge of energy!");
+ break;
+ case 4:
+ mpr("Your brain hurts!");
+ break;
+ case 5:
+ mpr("Strange energies run through your body.");
+ break;
+ case 6:
+ mpr("Everything looks hazy for a moment.");
+ break;
+ case 7:
+ mpr("You seem to have forgotten something, but you can't remember what it was!");
+ break;
+ case 8:
+ canned_msg(MSG_NOTHING_HAPPENS);
+ break;
+ case 9:
+ mpr("You feel uncomfortable.");
+ break;
+ }
+ break;
+
+ case 1: // more annoying things
+ switch (random2(2))
+ {
+ case 0:
+ mpr("You feel slightly disoriented.");
+ forget_map(10 + random2(10));
+ break;
+ case 1:
+ potion_effect(POT_CONFUSION, 10);
+ break;
+ }
+ break;
+
+ case 2: // even more annoying things
+ switch (random2(2))
+ {
+ case 0:
+ if (you.is_undead)
+ mpr("You suddenly recall your previous life!");
+ else if (lose_stat(STAT_INTELLIGENCE, 1 + random2(3)))
+ mpr("You have damaged your brain!");
+ else
+ mpr("You have a terrible headache.");
+ break;
+ case 1:
+ mpr("You feel lost.");
+ forget_map(40 + random2(40));
+ break;
+ }
+
+ potion_effect(POT_CONFUSION, 1); // common to all cases here {dlb}
+ break;
+
+ case 3: // nasty
+ switch (random2(3))
+ {
+ case 0:
+ mpr( forget_spell() ? "You have forgotten a spell!"
+ : "You get a splitting headache." );
+ break;
+ case 1:
+ mpr("You feel completely lost.");
+ forget_map(100);
+ break;
+ case 2:
+ if (you.is_undead)
+ mpr("You suddenly recall your previous life.");
+ else if (lose_stat(STAT_INTELLIGENCE, 3 + random2(3)))
+ mpr("You have damaged your brain!");
+ else
+ mpr("You have a terrible headache.");
+ break;
+ }
+
+ potion_effect(POT_CONFUSION, 1); // common to all cases here {dlb}
+ break;
+ }
+ break; // end divinations
+
+ case SPTYP_NECROMANCY:
+ if (you.religion == GOD_KIKUBAAQUDGHA
+ && (!player_under_penance() && you.piety >= 50
+ && random2(150) <= you.piety))
+ {
+ canned_msg(MSG_NOTHING_HAPPENS);
+ break;
+ }
+
+ switch (spec_effect)
+ {
+ case 0:
+ switch (random2(10))
+ {
+ case 0:
+ // mummies cannot smell {dlb}
+ if (you.species != SP_MUMMY)
+ mpr("You smell decay.");
+ break;
+ case 1:
+ if (!silenced(you.x_pos, you.y_pos))
+ mpr("You hear strange and distant voices.");
+ else
+ mpr("You feel homesick.");
+ break;
+ case 2:
+ mpr("Pain shoots through your body.");
+ break;
+ case 3:
+ mpr("Your bones ache.");
+ break;
+ case 4:
+ mpr("The world around you seems to dim momentarily.");
+ break;
+ case 5:
+ mpr("Strange energies run through your body.");
+ break;
+ case 6:
+ mpr("You shiver with cold.");
+ break;
+ case 7:
+ mpr("You sense a malignant aura.");
+ break;
+ case 8:
+ canned_msg(MSG_NOTHING_HAPPENS);
+ break;
+ case 9:
+ mpr("You feel very uncomfortable.");
+ break;
+ }
+ break;
+
+ case 1: // a bit nasty
+ switch (random2(3))
+ {
+ case 0:
+ if (you.is_undead)
+ {
+ mpr("You feel weird for a moment.");
+ break;
+ }
+ mpr("Pain shoots through your body!");
+ ouch(5 + random2avg(15, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+ case 1:
+ mpr("You feel horribly lethargic.");
+ potion_effect(POT_SLOWING, 15);
+ break;
+ case 2:
+ // josh declares mummies cannot smell {dlb}
+ if (you.species != SP_MUMMY)
+ {
+ mpr("You smell decay."); // identical to a harmless message
+ you.rotting++;
+ }
+ break;
+ }
+ break;
+
+ case 2: // much nastier
+ switch (random2(3))
+ {
+ case 0:
+ mpr("Flickering shadows surround you.");
+
+ create_monster( MONS_SHADOW, ENCH_ABJ_II, BEH_HOSTILE,
+ you.x_pos, you.y_pos, MHITYOU, 250 );
+
+ if (coinflip())
+ {
+ create_monster( MONS_SHADOW, ENCH_ABJ_II, BEH_HOSTILE,
+ you.x_pos, you.y_pos, MHITYOU, 250 );
+ }
+
+ if (coinflip())
+ {
+ create_monster( MONS_SHADOW, ENCH_ABJ_II, BEH_HOSTILE,
+ you.x_pos, you.y_pos, MHITYOU, 250 );
+ }
+ break;
+
+ case 1:
+ if (!player_prot_life() && one_chance_in(3))
+ {
+ drain_exp();
+ break;
+ } // otherwise it just flows through...
+
+ case 2:
+ if (you.is_undead)
+ {
+ mpr("You feel weird for a moment.");
+ break;
+ }
+ mpr("You convulse helplessly as pain tears through your body!");
+ ouch(15 + random2avg(23, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+ }
+ break;
+
+ case 3: // even nastier
+ switch (random2(6))
+ {
+ case 0:
+ if (you.is_undead)
+ {
+ mpr("Something just walked over your grave. No, really!");
+ break;
+ }
+ mpr("Your body is wracked with pain!");
+
+ dec_hp((you.hp / 2) - 1, false);
+ break;
+
+ case 1:
+ mpr("You are engulfed in negative energy!");
+
+ if (!player_prot_life())
+ {
+ drain_exp();
+ break;
+ } // otherwise it just flows through...
+
+ case 2:
+ lose_stat(STAT_RANDOM, 1 + random2avg(7, 2));
+ break;
+
+ case 3:
+ if (you.is_undead)
+ {
+ mpr("You feel terrible.");
+ break;
+ }
+
+ rot_player( random2avg(7, 2) + 1 );
+ break;
+
+ case 4:
+ if (create_monster( MONS_SOUL_EATER, ENCH_ABJ_IV, BEH_HOSTILE,
+ you.x_pos, you.y_pos, MHITYOU, 250) != -1)
+ {
+ mpr("Something reaches out for you...");
+ }
+ break;
+
+ case 5:
+ if (create_monster( MONS_REAPER, ENCH_ABJ_IV, BEH_HOSTILE,
+ you.x_pos, you.y_pos, MHITYOU, 250) != -1)
+ {
+ mpr("Death has come for you...");
+ }
+ break;
+ }
+ break;
+ }
+ break; // end necromancy
+
+ case SPTYP_TRANSMIGRATION:
+ switch (spec_effect)
+ {
+ case 0: // just a harmless message
+ switch (random2(10))
+ {
+ case 0:
+ snprintf( info, INFO_SIZE, "Your %s glow momentarily.",
+ your_hand(true));
+ mpr(info);
+ break;
+ case 1:
+ mpr("The air around you crackles with energy!");
+ break;
+ case 2:
+ mpr("Multicolored lights dance before your eyes!");
+ break;
+ case 3:
+ mpr("You feel a strange surge of energy!");
+ break;
+ case 4:
+ mpr("Waves of light ripple over your body.");
+ break;
+ case 5:
+ mpr("Strange energies run through your body.");
+ break;
+ case 6:
+ mpr("Your skin tingles.");
+ break;
+ case 7:
+ mpr("Your skin glows momentarily.");
+ break;
+ case 8:
+ canned_msg(MSG_NOTHING_HAPPENS);
+ break;
+ case 9:
+ // mummies cannot smell
+ if (you.species != SP_MUMMY)
+ mpr("You smell something strange.");
+ break;
+ }
+ break;
+
+ case 1: // slightly annoying
+ switch (random2(2))
+ {
+ case 0:
+ mpr("Your body is twisted painfully.");
+ ouch(1 + random2avg(11, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+ case 1:
+ random_uselessness(2 + random2(7), 0);
+ break;
+ }
+ break;
+
+ case 2: // much more annoying
+ switch (random2(4))
+ {
+ case 0:
+ mpr("Your body is twisted very painfully!");
+ ouch(3 + random2avg(23, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+ case 1:
+ mpr("You feel saturated with unharnessed energies!");
+ you.magic_contamination += random2avg(19,3);
+ break;
+ case 2:
+ potion_effect(POT_PARALYSIS, 10);
+ break;
+ case 3:
+ potion_effect(POT_CONFUSION, 10);
+ break;
+ }
+ break;
+
+ case 3: // even nastier
+
+ switch (random2(3))
+ {
+ case 0:
+ mpr("Your body is flooded with distortional energies!");
+ you.magic_contamination += random2avg(35, 3);
+
+ ouch(3 + random2avg(18, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+
+ case 1:
+ mpr("You feel very strange.");
+ delete_mutation(100);
+ ouch(5 + random2avg(23, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+
+ case 2:
+ mpr("Your body is distorted in a weirdly horrible way!");
+ failMsg = !give_bad_mutation();
+ if (coinflip())
+ give_bad_mutation(false, failMsg);
+
+ ouch(5 + random2avg(23, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+ }
+ break;
+ }
+ break; // end transmigrations
+
+ case SPTYP_FIRE:
+ switch (spec_effect)
+ {
+ case 0: // just a harmless message
+ switch (random2(10))
+ {
+ case 0:
+ snprintf( info, INFO_SIZE, "Sparks fly from your %s!",
+ your_hand(true));
+ mpr(info);
+ break;
+ case 1:
+ mpr("The air around you burns with energy!");
+ break;
+ case 2:
+ snprintf( info, INFO_SIZE, "Wisps of smoke drift from your %s.",
+ your_hand(true));
+ mpr(info);
+ break;
+ case 3:
+ mpr("You feel a strange surge of energy!");
+ break;
+ case 4:
+ // mummies cannot smell
+ if (you.species != SP_MUMMY)
+ mpr("You smell smoke.");
+ break;
+ case 5:
+ mpr("Heat runs through your body.");
+ break;
+ case 6:
+ mpr("You feel uncomfortably hot.");
+ break;
+ case 7:
+ mpr("Lukewarm flames ripple over your body.");
+ break;
+ case 8:
+ canned_msg(MSG_NOTHING_HAPPENS);
+ break;
+ case 9:
+ if (!silenced(you.x_pos, you.y_pos))
+ mpr("You hear a sizzling sound.");
+ else
+ mpr("You feel like you have heartburn.");
+ break;
+ }
+ break;
+
+ case 1: // a bit less harmless stuff
+ switch (random2(2))
+ {
+ case 0:
+ snprintf( info, INFO_SIZE, "Smoke pours from your %s!",
+ your_hand(true) );
+ mpr(info);
+
+ big_cloud( CLOUD_GREY_SMOKE + random2(3),
+ you.x_pos, you.y_pos, 20, 7 + random2(7) );
+ break;
+
+ case 1:
+ mpr("Flames sear your flesh.");
+ scrolls_burn(3, OBJ_SCROLLS);
+
+ if (player_res_fire() < 0)
+ {
+ ouch(2 + random2avg(13, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ }
+ break;
+ }
+ break;
+
+ case 2: // rather less harmless stuff
+ switch (random2(2))
+ {
+ case 0:
+ mpr("You are blasted with fire.");
+
+ ouch( check_your_resists( 5 + random2avg(29, 2), 2 ), 0,
+ KILLED_BY_WILD_MAGIC, cause );
+
+ scrolls_burn( 5, OBJ_SCROLLS );
+ break;
+
+ case 1:
+ mpr("You are caught a fiery explosion!");
+
+ beam.type = SYM_BURST;
+ beam.damage = dice_def( 3, 14 );
+ beam.flavour = BEAM_FIRE;
+ beam.target_x = you.x_pos;
+ beam.target_y = you.y_pos;
+ strcpy(beam.beam_name, "explosion");
+ beam.colour = RED;
+ beam.beam_source = NON_MONSTER;
+ beam.thrower = (cause) ? KILL_MISC : KILL_YOU;
+ beam.aux_source = cause;
+ beam.ex_size = 1;
+
+ explosion(beam);
+ break;
+ }
+ break;
+
+ case 3: // considerably less harmless stuff
+ switch (random2(3))
+ {
+ case 0:
+ mpr("You are blasted with searing flames!");
+
+ ouch( check_your_resists( 9 + random2avg(33, 2), 2 ), 0,
+ KILLED_BY_WILD_MAGIC, cause );
+
+ scrolls_burn( 10, OBJ_SCROLLS );
+ break;
+ case 1:
+ mpr("There is a sudden and violent explosion of flames!");
+
+ beam.type = SYM_BURST;
+ beam.damage = dice_def( 3, 20 );
+ beam.flavour = BEAM_FIRE;
+ beam.target_x = you.x_pos;
+ beam.target_y = you.y_pos;
+ strcpy( beam.beam_name, "fireball" );
+ beam.colour = RED;
+ beam.beam_source = NON_MONSTER;
+ beam.thrower = (cause) ? KILL_MISC : KILL_YOU;
+ beam.aux_source = cause;
+ beam.ex_size = coinflip()?1:2;
+
+ explosion(beam);
+ break;
+
+ case 2:
+ mpr("You are covered in liquid fire!");
+ you.duration[DUR_LIQUID_FLAMES] += random2avg(7, 3) + 1;
+ break;
+ }
+ break;
+ }
+ break; // end fire
+
+ case SPTYP_ICE:
+ switch (spec_effect)
+ {
+ case 0: // just a harmless message
+ switch (random2(10))
+ {
+ case 0:
+ mpr("You shiver with cold.");
+ break;
+ case 1:
+ mpr("A chill runs through your body.");
+ break;
+ case 2:
+ snprintf( info, INFO_SIZE, "Wisps of condensation drift from your %s.",
+ your_hand(true));
+ mpr(info);
+ break;
+ case 3:
+ mpr("You feel a strange surge of energy!");
+ break;
+ case 4:
+ snprintf( info, INFO_SIZE,"Your %s feel numb with cold.",
+ your_hand(true));
+ mpr(info);
+ break;
+ case 5:
+ mpr("A chill runs through your body.");
+ break;
+ case 6:
+ mpr("You feel uncomfortably cold.");
+ break;
+ case 7:
+ mpr("Frost covers your body.");
+ break;
+ case 8:
+ canned_msg(MSG_NOTHING_HAPPENS);
+ break;
+ case 9:
+ if (!silenced(you.x_pos, you.y_pos))
+ mpr("You hear a crackling sound.");
+ else
+ mpr("A snowflake lands on your nose.");
+ break;
+ }
+ break;
+
+ case 1: // a bit less harmless stuff
+ switch (random2(2))
+ {
+ case 0:
+ mpr("You feel extremely cold.");
+ break;
+ case 1:
+ mpr("You are covered in a thin layer of ice");
+ scrolls_burn(2, OBJ_POTIONS);
+
+ if (player_res_cold() < 0)
+ ouch(4 + random2avg(5, 2), 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+ }
+ break;
+
+ case 2: // rather less harmless stuff
+ switch (random2(2))
+ {
+ case 0:
+ mpr("Heat is drained from your body.");
+
+ ouch(check_your_resists(5 + random2(6) + random2(7), 3), 0,
+ KILLED_BY_WILD_MAGIC, cause);
+
+ scrolls_burn(4, OBJ_POTIONS);
+ break;
+
+ case 1:
+ mpr("You are caught in an explosion of ice and frost!");
+
+ beam.type = SYM_BURST;
+ beam.damage = dice_def( 3, 11 );
+ beam.flavour = BEAM_COLD;
+ beam.target_x = you.x_pos;
+ beam.target_y = you.y_pos;
+ strcpy(beam.beam_name, "explosion");
+ beam.colour = WHITE;
+ beam.beam_source = NON_MONSTER;
+ beam.thrower = (cause) ? KILL_MISC : KILL_YOU;
+ beam.aux_source = cause;
+ beam.ex_size = 1;
+
+ explosion(beam);
+ break;
+ }
+ break;
+
+ case 3: // less harmless stuff
+ switch (random2(2))
+ {
+ case 0:
+ mpr("You are blasted with ice!");
+
+ ouch(check_your_resists(9 + random2avg(23, 2), 3), 0,
+ KILLED_BY_WILD_MAGIC, cause);
+
+ scrolls_burn(9, OBJ_POTIONS);
+ break;
+ case 1:
+ snprintf( info, INFO_SIZE,"Freezing gasses pour from your %s!",
+ your_hand(true));
+ mpr(info);
+
+ big_cloud(CLOUD_COLD, you.x_pos, you.y_pos, 20,
+ 8 + random2(4));
+ break;
+ }
+ break;
+ }
+ break; // end ice
+
+ case SPTYP_EARTH:
+ switch (spec_effect)
+ {
+ case 0: // just a harmless message
+ case 1:
+ switch (random2(10))
+ {
+ case 0:
+ mpr("You feel earthy.");
+ break;
+ case 1:
+ mpr("You are showered with tiny particles of grit.");
+ break;
+ case 2:
+ snprintf( info, INFO_SIZE,"Sand pours from your %s.",
+ your_hand(true));
+ mpr(info);
+ break;
+ case 3:
+ mpr("You feel a surge of energy from the ground.");
+ break;
+ case 4:
+ if (!silenced(you.x_pos, you.y_pos))
+ mpr("You hear a distant rumble.");
+ else
+ mpr("You sympathise with the stones.");
+ break;
+ case 5:
+ mpr("You feel gritty.");
+ break;
+ case 6:
+ mpr("You feel momentarily lethargic.");
+ break;
+ case 7:
+ mpr("Motes of dust swirl before your eyes.");
+ break;
+ case 8:
+ canned_msg(MSG_NOTHING_HAPPENS);
+ break;
+ case 9:
+ strcpy(info, "Your ");
+ strcat(info, (you.species == SP_NAGA) ? "underbelly feels" :
+ (you.species == SP_CENTAUR) ? "hooves feel"
+ : "feet feel");
+ strcat(info, " warm.");
+ mpr(info);
+ break;
+ }
+ break;
+
+ case 2: // slightly less harmless stuff
+ switch (random2(1))
+ {
+ case 0:
+ switch (random2(3))
+ {
+ case 0:
+ mpr("You are hit by flying rocks!");
+ break;
+ case 1:
+ mpr("You are blasted with sand!");
+ break;
+ case 2:
+ mpr("Rocks fall onto you out of nowhere!");
+ break;
+ }
+
+ hurted = random2avg(13, 2) + 10;
+ hurted -= random2(1 + player_AC());
+
+ ouch(hurted, 0, KILLED_BY_WILD_MAGIC, cause);
+ break;
+ }
+ break;
+
+ case 3: // less harmless stuff
+ switch (random2(1))
+ {
+ case 0:
+ mpr("You are caught in an explosion of flying shrapnel!");
+
+ beam.type = SYM_BURST;
+ beam.damage = dice_def( 3, 15 );
+ beam.flavour = BEAM_FRAG;
+ beam.target_x = you.x_pos;
+ beam.target_y = you.y_pos;
+ strcpy(beam.beam_name, "explosion");
+ beam.colour = CYAN;
+
+ if (one_chance_in(5))
+ beam.colour = BROWN;
+ if (one_chance_in(5))
+ beam.colour = LIGHTCYAN;
+
+ beam.beam_source = NON_MONSTER;
+ beam.thrower = (cause) ? KILL_MISC : KILL_YOU;
+ beam.aux_source = cause;
+ beam.ex_size = 1;
+
+ explosion(beam);
+ break;
+ }
+ break;
+ }
+ break; // end Earth
+
+ case SPTYP_AIR:
+ switch (spec_effect)
+ {
+ case 0: // just a harmless message
+ switch (random2(10))
+ {
+ case 0:
+ mpr("Ouch! You gave yourself an electric shock.");
+ break;
+ case 1:
+ mpr("You feel momentarily weightless.");
+ break;
+ case 2:
+ snprintf( info, INFO_SIZE, "Wisps of vapour drift from your %s.",
+ your_hand(true));
+ mpr(info);
+ break;
+ case 3:
+ mpr("You feel a strange surge of energy!");
+ break;
+ case 4:
+ mpr("You feel electric!");
+ break;
+ case 5:
+ snprintf( info, INFO_SIZE, "Sparks of electricity dance between your %s.",
+ your_hand(true));
+ mpr(info);
+ break;
+ case 6:
+ mpr("You are blasted with air!");
+ break;
+ case 7:
+ // mummies cannot smell
+ if (!silenced(you.x_pos, you.y_pos))
+ mpr("You hear a whooshing sound.");
+ else if (you.species != SP_MUMMY)
+ mpr("You smell ozone.");
+ break;
+ case 8:
+ canned_msg(MSG_NOTHING_HAPPENS);
+ break;
+ case 9:
+ // mummies cannot smell
+ if (!silenced(you.x_pos, you.y_pos))
+ mpr("You hear a crackling sound.");
+ else if (you.species != SP_MUMMY)
+ mpr("You smell something musty.");
+ break;
+ }
+ break;
+
+ case 1: // a bit less harmless stuff
+ switch (random2(2))
+ {
+ case 0:
+ mpr("There is a short, sharp shower of sparks.");
+ break;
+ case 1:
+ snprintf( info, INFO_SIZE, "The wind %s around you!",
+ silenced(you.x_pos, you.y_pos) ? "whips" : "howls");
+ mpr(info);
+ break;
+ }
+ break;
+
+ case 2: // rather less harmless stuff
+ switch (random2(2))
+ {
+ case 0:
+ mpr("Electricity courses through your body.");
+ ouch(check_your_resists(4 + random2avg(9, 2), 5), 0,
+ KILLED_BY_WILD_MAGIC, cause);
+ break;
+ case 1:
+ snprintf( info, INFO_SIZE, "Noxious gasses pour from your %s!",
+ your_hand(true));
+ mpr(info);
+
+ big_cloud(CLOUD_STINK, you.x_pos, you.y_pos, 20,
+ 9 + random2(4));
+ break;
+ }
+ break;
+
+ case 3: // less harmless stuff
+ switch (random2(2))
+ {
+ case 0:
+ mpr("You are caught in an explosion of electrical discharges!");
+
+ beam.type = SYM_BURST;
+ beam.damage = dice_def( 3, 8 );
+ beam.flavour = BEAM_ELECTRICITY;
+ beam.target_x = you.x_pos;
+ beam.target_y = you.y_pos;
+ strcpy(beam.beam_name, "explosion");
+ beam.colour = LIGHTBLUE;
+ beam.beam_source = NON_MONSTER;
+ beam.thrower = (cause) ? KILL_MISC : KILL_YOU;
+ beam.aux_source = cause;
+ beam.ex_size = one_chance_in(4)?1:2;
+
+ explosion(beam);
+ break;
+ case 1:
+ snprintf( info, INFO_SIZE, "Venomous gasses pour from your %s!",
+ your_hand(true));
+ mpr(info);
+
+ big_cloud( CLOUD_POISON, you.x_pos, you.y_pos, 20,
+ 8 + random2(5) );
+ break;
+ }
+ break;
+ }
+ break; // end air
+
+ case SPTYP_POISON:
+ switch (spec_effect)
+ {
+ case 0: // just a harmless message
+ switch (random2(10))
+ {
+ case 0:
+ mpr("You feel mildly nauseous.");
+ break;
+ case 1:
+ mpr("You feel slightly ill.");
+ break;
+ case 2:
+ snprintf( info, INFO_SIZE, "Wisps of poison gas drift from your %s.",
+ your_hand(true) );
+ mpr(info);
+ break;
+ case 3:
+ mpr("You feel a strange surge of energy!");
+ break;
+ case 4:
+ mpr("You feel faint for a moment.");
+ break;
+ case 5:
+ mpr("You feel sick.");
+ break;
+ case 6:
+ mpr("You feel odd.");
+ break;
+ case 7:
+ mpr("You feel weak for a moment.");
+ break;
+ case 8:
+ canned_msg(MSG_NOTHING_HAPPENS);
+ break;
+ case 9:
+ if (!silenced(you.x_pos, you.y_pos))
+ mpr("You hear a slurping sound.");
+ else if (you.species != SP_MUMMY)
+ mpr("You taste almonds.");
+ break;
+ }
+ break;
+
+ case 1: // a bit less harmless stuff
+ switch (random2(2))
+ {
+ case 0:
+ if (player_res_poison())
+ {
+ canned_msg(MSG_NOTHING_HAPPENS);
+ return (false);
+ }
+
+ mpr("You feel sick.");
+ poison_player( 2 + random2(3) );
+ break;
+
+ case 1:
+ snprintf( info, INFO_SIZE, "Noxious gasses pour from your %s!",
+ your_hand(true) );
+ mpr(info);
+
+ place_cloud(CLOUD_STINK, you.x_pos, you.y_pos,
+ 2 + random2(4));
+ break;
+ }
+ break;
+
+ case 2: // rather less harmless stuff
+ switch (random2(3))
+ {
+ case 0:
+ if (player_res_poison())
+ {
+ canned_msg(MSG_NOTHING_HAPPENS);
+ return (false);
+ }
+
+ mpr("You feel very sick.");
+ poison_player( 3 + random2avg(9, 2) );
+ break;
+
+ case 1:
+ mpr("Noxious gasses pour from your hands!");
+ big_cloud(CLOUD_STINK, you.x_pos, you.y_pos, 20,
+ 8 + random2(5));
+ break;
+
+ case 2:
+ if (player_res_poison())
+ {
+ canned_msg(MSG_NOTHING_HAPPENS);
+ return (false);
+ }
+ lose_stat(STAT_RANDOM, 1);
+ break;
+ }
+ break;
+
+ case 3: // less harmless stuff
+ switch (random2(3))
+ {
+ case 0:
+ if (player_res_poison())
+ {
+ canned_msg(MSG_NOTHING_HAPPENS);
+ return (false);
+ }
+
+ mpr("You feel incredibly sick.");
+ poison_player( 10 + random2avg(19, 2) );
+ break;
+ case 1:
+ snprintf( info, INFO_SIZE, "Venomous gasses pour from your %s!",
+ your_hand(true));
+ mpr(info);
+
+ big_cloud(CLOUD_POISON, you.x_pos, you.y_pos, 20,
+ 7 + random2(7));
+ break;
+ case 2:
+ if (player_res_poison())
+ {
+ canned_msg(MSG_NOTHING_HAPPENS);
+ return (false);
+ }
+
+ lose_stat(STAT_RANDOM, 1 + random2avg(5, 2));
+ break;
+ }
+ break;
+ }
+ break; // end poison
+ }
+
+ return (true);
+} // end miscast_effect()