#if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" #include "interp.h" #include "magic.h" #include "balance.h" /*****************************************\ * First Circle Spells * \*****************************************/ /* Spell Name: Cure Light Wounds Base Mana Cost: 10 Heal 10-20 + 1d4 per level */ void spell_1_cure_light (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int heal; heal = number_range (10, 20) + level; heal_char(victim, heal, TRUE); update_pos (victim); send_to_char ("You feel better!\n\r", victim); if (ch != victim) send_to_char ("Ok.\n\r", ch); return; } /* Spell Name: Cause Light Wounds Base Mana Cost: 10 Damage 10-20 + 1d4 per level */ void spell_1_cause_light (int sn, int level, CHAR_DATA * ch, void *vo, int target) { int dam = number_range (10, 20) + level; damage (ch, (CHAR_DATA *) vo, dam, sn, DAM_HARM, TRUE, TRUE); return; } /* Spell Name: Bane Base Mana Cost: 20 Type: Offensive Enchantment Effect: Target has a 15% chance to miss melee */ void spell_1_bane (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (is_affected (victim, sn)) { if (victim == ch) send_to_char ("You are already baned!\n\r", ch); else act ("$N can't be baned yet again.", ch, NULL, victim, TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_HITROLL; af.modifier = -1; af.bitvector = 0; affect_to_char (victim, &af); send_to_char ("Your feel the the curse of the bane!\n\r", victim); act ("$n's has been cursed with bane.", victim, NULL, NULL, TO_ROOM); return; } /* SPell Name: Bless Base mana Cost: 10 Effect +2 hitroll +1 per level */ void spell_1_bless (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (is_affected (victim, sn)) { if (victim == ch) send_to_char ("You are already blessed!\n\r", ch); else act ("$N is already blessed.", ch, NULL, victim, TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_HITROLL; af.modifier = 2 + level; af.bitvector = 0; affect_to_char (victim, &af); send_to_char ("Your are blessed!\n\r", victim); act ("$n's has been blessed.", victim, NULL, NULL, TO_ROOM); return; } /* * Spell ideas.. * *adept - Can see spells names when cast cleanse - Super cancel *holy sight - can 'see' everything *rejuvination - spell effect regen, super *suppression - victim's spells do 50% less *word of god - High level single hit damage spell *bark skin - High -ac spell *brushfire - high damage fire spell *divinity - Highest damage harm spell. Ouchy *sun's ritual - Mid level defense sanct *hurricane - area effect spell *earthquake - area effect spell *wall of ice - defensive ac spell, -damage taken *sanctify - anti-pk spell *replenish - highly draining low level room restore *grudge - low level elemental damage spell *malady - prevents target from healing sticks to snakes - Low level damage attack spel restore - Single hit restoration spell (hp/move) *fire storm - High level damage spell fireseeds - damage spell, mid level chant - temporarily increases spell damage to target holy might - increases str/damroll and melee damage divine insight - increases wis/int and spell damage luck of the irish - increases 'luck' divine armor - VERY high ac spell retrubution - enemy effect, enemy takes 33% damage back thorns - damage spell, slows enemy wolf spirit - 'speed' increases, haste, roundtime hawk spirit - 'hit' increases, hitroll, damroll owl spirit - 'magic' increases, damage, reduced spell cost viper spirit - 'poison' all spells do poison damage, weapons deal poison, imm poison mouse spirit - 'flee' increases, flee/recall 100% regardless oliphaunt armor - damage reduction insect swarm - Charmmies, 6x of em at 105 treant - Strong charmie confusion - makes enemy attack themselves */ /* * spell_adept() * * Good effect, target can 'see' spells that are being cast * also slight bonus to spell power */ void spell_adept (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_AFFECTED2 (victim, AFF2_ADEPT)) { if (victim == ch) send_to_char ("You can already reconize spells!\n\r", ch); else act ("$N can already reconize spells!", ch, NULL, victim, TO_CHAR); return; } af.where = TO_AFFECTS2; af.type = sn; af.level = level; af.duration = level; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF2_ADEPT; affect_to_char (victim, &af); send_to_char ("You become adept at reconizing spells.\n\r", victim); if (ch != victim) send_to_char ("Ok.\n\r", ch); return; } /* * spell_holy_sight() * * Good effect, target can see 'everything' */ void spell_holy_sight (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (is_affected (victim, sn)) { if (victim == ch) send_to_char ("You already have true sight.\n\r", ch); else act ("$N already has true sight.", ch, NULL, victim, TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 3; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_DETECT_HIDDEN; affect_to_char (victim, &af); af.bitvector = AFF_DETECT_INVIS; affect_to_char (victim, &af); af.bitvector = AFF_DETECT_MAGIC; affect_to_char (victim, &af); af.bitvector = AFF_DETECT_GOOD; affect_to_char (victim, &af); af.bitvector = AFF_DETECT_EVIL; affect_to_char (victim, &af); af.bitvector = AFF_DARK_VISION; affect_to_char (victim, &af); af.bitvector = AFF_INFRARED; affect_to_char (victim, &af); send_to_char ("Your sight becomes true.\n\r", victim); if (ch != victim) send_to_char ("Ok.\n\r", ch); return; } /* * spell_rejuvination() * * Good effect spell, victim heals 1000x faster */ void spell_rejuvination (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_AFFECTED2 (victim, AFF2_REJUVINATION)) { if (victim == ch) send_to_char ("You body is already rejuvinating\n\r", ch); else act ("$N's body is already rejuvinating!", ch, NULL, victim, TO_CHAR); return; } af.where = TO_AFFECTS2; af.type = sn; af.level = level; af.duration = level; af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF2_REJUVINATION; affect_to_char (victim, &af); send_to_char ("Your body regenerates VERY quickly!\n\r", victim); if (ch != victim) send_to_char ("Ok.\n\r", ch); return; } /* * spell_suppression() * * Offensive spell, victim's spells and spell based damage do 1/2 damage */ void spell_suppression (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_AFFECTED2 (victim, AFF2_SUPPRESSION)) { if (victim == ch) send_to_char ("{RYour magic casting abilities are already suppressed!{\n\r", ch); else act ("{R$N's magic casting abilities are already suppressed!{", ch, NULL, victim, TO_CHAR); return; } af.where = TO_AFFECTS2; af.type = sn; af.level = level; af.duration = number_range(1, 3); af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF2_SUPPRESSION; affect_to_char (victim, &af); send_to_char ("{RYou feel your magical abilities suppressed!{x\n\r", victim); if (ch != victim) send_to_char ("{ROk. Target is suppressed\n\r", ch); return; } /* * spell_word_of_god() * * Medium level holy damage spell. * 3x damage is victim is evil. * Note: Some serious damage to evil creatures at high levels */ void spell_word_of_god (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int i = ch->level / 20; int dam; while (i != 0) { dam = dice(10, 20); dam *= ch->level / 20; if (victim->alignment <= -250) dam *= 3; damage (ch, (CHAR_DATA *) vo, dam, sn, DAM_HOLY, TRUE, TRUE); i--; } return; } /* * spell_bark_skin() * * Low level, but all level effective defensive spell. * lowers AC, and reduces damage slightly */ void spell_bark_skin (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_AFFECTED2 (victim, AFF2_BARK_SKIN)) { if (victim == ch) send_to_char ("Your skin is already covered in bark!\n\r", ch); else act ("$N's skin is already covered in bark!", ch, NULL, victim, TO_CHAR); return; } af.where = TO_AFFECTS2; af.type = sn; af.level = level; af.duration = level; af.modifier = -50 * ch->level / 3; af.location = APPLY_AC; af.bitvector = AFF2_BARK_SKIN; affect_to_char (victim, &af); send_to_char ("Your body covers itself in a brownish bark.\n\r", victim); if (ch != victim) send_to_char ("Your body covers itself in a brownish bark.\n\r", victim); return; } /* * spell_fire_storm() * * Low level fire spell */ void spell_fire_storm (int sn, int level, CHAR_DATA * ch, void *vo, int target) { int i = level / 25; int dam; while (i > 0) { dam = fix_spell_damage(level, i); if (!IS_NPC(ch)) dam = dam * ch->pcdata->learned[skill_lookup("fire storm")] / 100; i--; damage (ch, (CHAR_DATA *) vo, dam, sn, DAM_FIRE, TRUE, TRUE); if (!saves_spell (level, ch, DAM_FIRE)) fire_effect ((void *) ch, level / 2, dam, TARGET_CHAR); } return; } /* * spell_brushfire() * * mid level fire spell */ void spell_brushfire (int sn, int level, CHAR_DATA * ch, void *vo, int target) { int i = level / 33; int dam; while (i > 0) { dam = fix_spell_damage(level + 20, i); if (!IS_NPC(ch)) dam = dam * ch->pcdata->learned[skill_lookup("brushfire")] / 100; i--; damage (ch, (CHAR_DATA *) vo, dam, sn, DAM_FIRE, TRUE, TRUE); if (!saves_spell (level, ch, DAM_FIRE)) fire_effect ((void *) ch, level / 2, dam, TARGET_CHAR); } return; } /* * spell_divinity() * * Mid/Low level damage spell for White magic. * Does multiple damage types. * FIXME: Damage */ void spell_divinity (int sn, int level, CHAR_DATA * ch, void *vo, int target) { int i = 3; int dam; while (i != 0) { dam = fix_spell_damage(level + 100, i); if (!IS_NPC(ch)) dam = dam * ch->pcdata->learned[skill_lookup("divinity")] / 100; damage (ch, (CHAR_DATA *) vo, dam, sn, DAM_HARM, TRUE, TRUE); i--; } return; } /* * spell_sun_ritual() * * Mid-level White magic defensive spell. * cuts all damage by 1/3 */ void spell_sun_ritual (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_AFFECTED2 (victim, AFF2_SUN_RITUAL)) { if (victim == ch) send_to_char ("You are already basking in the sunlight!\n\r", ch); else act ("$N is already basking in the sunlight!", ch, NULL, victim, TO_CHAR); return; } af.where = TO_AFFECTS2; af.type = sn; af.level = level; af.duration = level * 5; af.modifier = -500; af.location = APPLY_AC; af.bitvector = AFF2_BARK_SKIN; affect_to_char (victim, &af); send_to_char ("You begin basking in the sunlight.\n\r", victim); if (ch != victim) send_to_char ("You begin basking in the sunlight.\n\r", victim); return; } /* * spell_earthquake() * * Low/mid level area effect spell * Useful most levels */ void spell_earthquake (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *vch; CHAR_DATA *vch_next; int dam; send_to_char ("The earth trembles beneath your feet!\n\r", ch); act ("$n makes the earth tremble and shiver.", ch, NULL, NULL, TO_ROOM); for (vch = char_list; vch != NULL; vch = vch_next) { vch_next = vch->next; if (vch->in_room == NULL) continue; if (vch->in_room == ch->in_room) { if (vch != ch && !is_safe_spell (ch, vch, TRUE)) { dam = fix_spell_damage(level, 1); if (!IS_NPC(ch)) dam = dam * ch->pcdata->learned[skill_lookup("earthquake")] / 100; if (IS_AFFECTED (vch, AFF_FLYING)) damage (ch, vch, 0, sn, DAM_BASH, TRUE, TRUE); else damage (ch, vch, dam, sn, DAM_BASH, TRUE, TRUE); } continue; } if (vch->in_room->area == ch->in_room->area) send_to_char ("The earth trembles and shivers.\n\r", vch); } return; } /* * spell_hurricane() * * Low/mid level area effect spell * Useful most levels * Answer to earthquake */ void spell_hurricane (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *vch; CHAR_DATA *vch_next; int dam; send_to_char ("The skies turn black and a hurricane appears!\n\r", ch); act ("$n makes the skies turn black and a hurricane appears.", ch, NULL, NULL, TO_ROOM); for (vch = char_list; vch != NULL; vch = vch_next) { vch_next = vch->next; if (vch->in_room == NULL) continue; if (vch->in_room == ch->in_room) { if (vch != ch && !is_safe_spell (ch, vch, TRUE)) { dam = fix_spell_damage(level, 1); if (!IS_NPC(ch)) dam = dam * ch->pcdata->learned[skill_lookup("hurricane")] / 100; if (!IS_AFFECTED (vch, AFF_FLYING)) damage (ch, vch, 0, sn, DAM_BASH, TRUE, TRUE); else damage (ch, vch, dam, sn, DAM_BASH, TRUE, TRUE); } continue; } if (vch->in_room->area == ch->in_room->area) send_to_char ("The skies scream in a raging hurricane!\n\r", vch); } return; } /* * spell_wall_of_ice() * * Mid level defensive spell, yet another sanct */ void spell_wall_of_ice (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_AFFECTED2 (victim, AFF2_WALL_OF_ICE)) { if (victim == ch) send_to_char ("You already have a wall of ice surrounding you!\n\r", ch); else act ("$N already has a wall of ice surrounding them!", ch, NULL, victim, TO_CHAR); return; } af.where = TO_AFFECTS2; af.type = sn; af.level = level; af.duration = level; af.modifier = -50 * ch->level / 4; af.location = APPLY_AC; af.bitvector = AFF2_WALL_OF_ICE; affect_to_char (victim, &af); send_to_char ("You surround yourself in a wall of ice.\n\r", victim); if (ch != victim) send_to_char ("Ok.\n\r", ch); return; } /* * spell_sanctify() * * Sanctify is a low level anti-PK spell. */ void spell_sanctify (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (is_affected (victim, sn)) { if (victim == ch) send_to_char ("You are already sanctified.\n", ch); else act ("$N is already sanctified.", ch, NULL, victim, TO_CHAR); return; } af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_SANCTIFY; affect_to_char (victim, &af); act ("$n's aura becomes serene.", victim, NULL, NULL, TO_ROOM); send_to_char ("You become serene as the effects of sanctity take over.\n", victim); return; } /* * spell_replenish() * * Highest level cure spell. Heals all in the room to max health/mana/move * and removes some bad effects. */ void spell_replenish (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *vch_next; CHAR_DATA *vch; AFFECT_DATA af; for (vch = ch->in_room->people; vch != NULL; vch = vch_next) { vch_next = vch->next_in_room; if (vch == ch) continue; vch->hit = vch->max_hit; vch->mana = vch->max_mana; vch->move = vch->max_move; update_pos (vch); send_to_char ("Your body completely regenrates itself!\n", vch); } af.where = TO_AFFECTS2; af.type = sn; af.level = level; af.duration = 5; af.location = AFF2_REPLENISH; af.modifier = 0; af.bitvector = 0; affect_to_char (ch, &af); stc("You feel drained...\n", ch); stc("You will be able to replenish again in 5 hours.\n", ch); return; } /* * spell_grudge() * * Mid/Low level damage spell for White magic. * Does multiple damage types. * FIXME: Count + Damage mods */ void spell_grudge (int sn, int level, CHAR_DATA * ch, void *vo, int target) { int i = 6; int dam; int type; while (i != 0) { dam = fix_spell_damage(level + 50, i); if (!IS_NPC(ch)) dam = dam * ch->pcdata->learned[skill_lookup("grudge")] / 100; type = number_range(1, 19); damage (ch, (CHAR_DATA *) vo, dam, sn, type, TRUE, TRUE); i--; } return; } /* * spell_malady() * * Vulgar offensive enchantment * Target cannot heal. */ void spell_malady (int sn, int level, CHAR_DATA * ch, void *vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; AFFECT_DATA af; if (IS_AFFECTED2 (victim, AFF2_MALADY)) { if (victim == ch) send_to_char ("Your body is already effected by an unknown malady!\n\r", ch); else act ("$N's body is already effected by an unknown malady!", ch, NULL, victim, TO_CHAR); return; } af.where = TO_AFFECTS2; af.type = sn; af.level = level; af.duration = number_range(1, 3); af.modifier = 0; af.location = APPLY_NONE; af.bitvector = AFF2_MALADY; affect_to_char (victim, &af); send_to_char ("{mYour body feels strange. You feel sickly.\n\r", victim); if (ch != victim) send_to_char ("Ok.\n\r", ch); return; }