/*
* effect.cpp
* Effects on creatures
* ____ _
* | _ \ ___ __ _| |_ __ ___ ___
* | |_) / _ \/ _` | | '_ ` _ \/ __|
* | _ < __/ (_| | | | | | | \__ \
* |_| \_\___|\__,_|_|_| |_| |_|___/
*
* Permission to use, modify and distribute is granted via the
* Creative Commons - Attribution - Non Commercial - Share Alike 3.0 License
* http://creativecommons.org/licenses/by-nc-sa/3.0/
*
* Copyright (C) 2007-2009 Jason Mitchell, Randi Mitchell
* Contributions by Tim Callahan, Jonathan Hseu
* Based on Mordor (C) Brooke Paul, Brett J. Vickers, John P. Freeman
*
*/
#include "mud.h"
#include "effects.h"
//*********************************************************************
// EffectList
//*********************************************************************
// Local functions for work on list of effects
EffectList creatureEffects[] = {
{ "enlarge", "^CEnlarge^x", "",
"^CYou grow in size!^x", "^C%M grows in size!^x",
"^CYou shrink in size.^x", "^C%M shrinks in size.^x",
effectNatural, false, NEUTRAL_EFFECT
},
{ "reduce", "^cReduce^x", "",
"^CYou shrink in size!^x", "^C%M shrinks in size!^x",
"^CYou grow in size.^x", "^C%M grows in size.^x",
effectNatural, false, NEUTRAL_EFFECT
},
{ "blur", "^CBlur^x", "",
"^CYour form suddenly blurs.^x", "^C%M's outline begins to blur.^x",
"^CYour form comes into focus.^x", "^W%M's outline comes into focus.^x",
effectVisibility, false, GOOD_EFFECT
},
{ "illusion", "^CIllusion^x", "",
"^CYou are surrounded by an illusion.^x", "^W%M suddenly looks different.^x",
"^CYour illusion fades.^x", "^W%M suddenly looks different.^x",
effectVisibility, false, NEUTRAL_EFFECT
},
{ "invisibility", "^MInvisible^x", "",
"^WYou fade from view.^x", "^W%M fades from view.^x",
"^WYou fade into view.^x", "^W%M fades into view.^x",
effectVisibility, false, GOOD_EFFECT
},
{ "greater-invisibility", "^MGreater-Invisiblity^x", "",
"^WYou fade from view.^x", "^W%M fades from view.^x",
"^WYou fade into view.^x", "^W%M fades into view.^x",
effectVisibility, false, GOOD_EFFECT
},
{ "camouflage", "^GCamouflage^x", "",
"^gYou blend in with your surroundings.^x", "^g%M blends in with the surroundings.^x",
"^gYou no longer blend in with your surroundings.^x", "^g%M no longer blends in with the surroundings.^x",
effectVisibility, false, GOOD_EFFECT
},
{ "pass-without-trace", "^GPass-without-trace^x", "",
"^gYou no longer leave any tracks.^x", "^g%M starts to step very softly.^x",
"^gYou start leaving tracks again.^x", "^g%M begins stepping heavier.^x",
effectVisibility, false, GOOD_EFFECT
},
{ "detect-invisible", "^MDetect-Invisible^x", "",
"^yThe invisible slowly reveals itself to you.^x", "^y%M's eyes glow yellow.^x",
"^WThe invisible fades from view.^x", "^W%M's eyes lose their yellowish glow.^x",
effectDetect, false, GOOD_EFFECT
},
{ "detect-magic", "^rDetect-Magic^x", "",
"^rYour eyes glow red.^x", "^r%M's eyes glow red.^x",
"^WYou can no longer sense the magical.^x", "^W%M's eyes lose their reddish glow.^x",
effectDetect, false, GOOD_EFFECT
},
{ "true-sight", "^WTrue-Sight^x", "",
"^gThings become much clearer.^x", "^g%M's eyes glow green.^x",
"^WYour vision returns to normal.^x", "^W%M's eyes lose their greenish glow.^x",
effectDetect, false, GOOD_EFFECT
},
{ "know-aura", "^cKnow-Aura^x", "",
"^cYou become more perceptive.^x", "^c%M becomes more perceptive.^x",
"^cYour perception is diminished.^x", "^c%M's perception is diminished.^x",
effectDetect, false, GOOD_EFFECT
},
{ "farsight", "^WFarsight^x", "",
"^WYour vision improves.^x", "^W%M's vision improves.^x",
"^cYour vision returns to normal.^x", "^c%M's vision returns to normal.^x",
effectDetect, false, GOOD_EFFECT
},
{ "undead-ward", "^CUndead-Ward^x", "",
"^WYou feel guarded against the undead.^x", "^W%M is now guarded against the undead.^x",
"^CYour shiver and suddenly feel vulnerable to the undead.^x", "^C%M is no longer protected against the undead.^x",
effectBeneficial, false, GOOD_EFFECT
},
{ "bless", "^YBlessed^x", "",
"^WYou feel holy.^x", "^WA halo appears over %N's head.^x",
"^YYou feel less holy.^x", "^Y%M is no longer blessed.^x",
effectBeneficial, false, GOOD_EFFECT
},
{ "protection", "^WProtection^x", "",
"^WYou feel watched.^x", "^W%M is surrounded by a faint magical aura.^x",
"^yYour aura of protection fades.^x", "^y%M is no longer protected.^x",
effectBeneficial, false, GOOD_EFFECT
},
{ "drain-shield", "^WDrain-Shield^x", "",
"^WAn aura of positive energy surrounds you.^x", "^WAn aura of positive energy surrounds %N.^x",
"^DThe aura of positive energy around you dissipates.^x", "^DThe aura of positive energy around %N dissipates.^x",
effectBeneficial, false, GOOD_EFFECT
},
{ "warmth", "^RWarmth^x", "",
"^RA warm aura surrounds you.^x", "^RA warm aura surrounds %N.^x",
"^CA cold chill runs through your body.^x", "^C%M shivers.^x",
effectBeneficial, false, GOOD_EFFECT
},
{ "heat-protection", "^RHeat-Protection^x", "",
"^MYour skin toughens.^x", "^M%M's skin toughens.^x",
"^yYou are no longer protected from fire.^x", "^y%M's skin softens.^x",
effectBeneficial, false, GOOD_EFFECT
},
{ "wind-protection", "^cWind-Protection^x", "",
"^cYour skin toughens.^x", "^c%M's skin toughens.^x",
"^cYou are no longer protected from the wind.^x", "^x%M's skin softens.^x",
effectBeneficial, false, GOOD_EFFECT
},
{ "static-field", "^cStatic-Field^x", "",
"^cYour hair stands on end.^x", "^c%M's hair stands on end.^x",
"^cYour hair is no longer standing on end.^x", "^x%M's hair is no longer standing on end.^x",
effectBeneficial, false, GOOD_EFFECT
},
{ "breathe-water", "^BBreathe-Water^x", "",
"^bYour lungs increase in size.^x", "^b%M's lungs increase in size.^x",
"^BYour lungs contract in size.^x", "^B%M's lungs contract in size.^x",
effectBeneficial, false, GOOD_EFFECT
},
{ "earth-shield", "^GEarth-Shield^x", "",
"^GYour flesh strengthens.^x","^G%M's flesh strengthens.^x",
"^GYour skin softens.^x", "^G%M's skin softens.^x",
effectBeneficial, false, GOOD_EFFECT
},
{ "reflect-magic", "^MReflect-Magic^x", "",
"^MA shield of magical force surrounds you.^x", "^MA shield of magical force engulfs %N.^x",
"^MYour shield of magic dissipates.^x", "^M%M's shield of magic dissipates.^x",
effectBeneficial, false, GOOD_EFFECT
},
{ "fire-shield", "^yFire Shield^x", "",
"^RYou are protected by a fiery barrier.^x", "^r%M is protected by a fiery barrier.^x",
"^yYour shield of fire dissipates.^x", "^y%M's shield of fire dissipates.^x",
effectShield, false, GOOD_EFFECT
},
{ "armor", "^BArmor^x", "",
"^BYou are surrounded by magical armor.^x", "^B%M is surrounded by magical armor.^x",
"^BYour magical armor dissipates.^x", "^B%M's magical armor dissipates.^x",
effectShield, false, GOOD_EFFECT
},
{ "stoneskin", "^GStoneskin^x", "",
"^BYour skin hardens.^x", "^B%M's skin hardens.^x",
"^BYour stoneskin dissipates.^x", "^B%M's stoneskin dissipates.^x",
effectShield, false, GOOD_EFFECT
},
{ "barkskin", "^yBarkskin^x", "",
"^yYour skin toughens.^x", "^y%M's skin toughens.^x",
"^yYour barkskin erodes away.^x", "^y%M's barkskin erodes away.^x",
effectShield, false, GOOD_EFFECT
},
{ "darkness", "^DDarkness^x", "",
"^DYou are engulfed in darkness.\n","^D%M is engulfed in darkness.^x",
"^YThe globe of darkness around you fades.^x", "^YThe globe of darkness around %N fades.^x",
effectDarkInfra, false, BAD_EFFECT
},
{ "infravision", "^YInfravision^x", "",
"^YYour eyes glow yellow.\n","^Y%M's eyes glow yellow.^x",
"^DThe world darkens around you.^x", "^Y%M's magic vision fades.^x",
effectDarkInfra, false, GOOD_EFFECT
},
{ "comprehend-languages", "^gComprehend-Languages^x", "",
"^gYou feel understanding flow within you.^x", "^g%M gains newfound understanding.^x",
"^gYour understanding leaves you.^x", "^g%M looks dumbfounded.^x",
effectLanguages, false, GOOD_EFFECT
},
{ "tongues", "^gTongues^x", "",
"^gYou being speaking in tongues.^x", "^g%M begins speaking in tongues.^x",
"^gYou stop speaking in tongues.^x", "^g%M stops speaking in tongues.^x",
effectLanguages, false, GOOD_EFFECT
},
{ "fly", "^yFly^x", "",
"^yYou begin to fly.^x", "^y%M begins to fly.^x",
"^yYou slowly float to the ground.^x", "^y%M floats down to the ground.^x",
effectGravity, false, GOOD_EFFECT
},
{ "levitate", "^cLevitate^x", "",
"^cYou begin to float.^x", "^c%M begins to float.^x",
"^cYour feet hit the ground.^x", "^c%M's feet hit the ground.^x",
effectGravity, false, GOOD_EFFECT
},
{ "resist-magic", "^MResist-Magic^x", "",
"^mYou are surrounded by a magical shield.^x", "^m%M is surrounded by a magical shield.^x",
"^MYour magical shield dissipates.^x", "^M%M's magical shield dissipates.^x",
effectResist, false, GOOD_EFFECT
},
{ "resist-cold", "^bResist-Cold^x", "vuln-cold",
"^cYou feel resistant to cold.^x", "^c%M looks resistant to cold.^x",
"^cYou feel less resistant to cold.^x", "^c%M looks less resistant to cold.^x",
effectResist, false, GOOD_EFFECT
},
{ "resist-fire", "^rResist-Fire^x", "vuln-fire",
"^rYou feel resistant to fire.^x", "^r%M looks resistant to fire.^x",
"^rYou feel less resistant to fire.^x", "^r%M looks less resistant to fire.^x",
effectResist, false, GOOD_EFFECT
},
{ "resist-earth", "^YResist-Earth^x", "vuln-earth",
"^YYou feel resistant to earth.^x", "^Y%M looks resistant to earth.^x",
"^YYou feel less resistant to earth.^x", "^Y%M looks less resistant to earth.^x",
effectResist, false, GOOD_EFFECT
},
{ "resist-air", "^yResist-Air^x", "vuln-air",
"^yYou feel resistant to air.^x", "^y%M looks resistant to air.^x",
"^yYou feel less resistant to air.^x", "^y%M looks less resistant to air.^x",
effectResist, false, GOOD_EFFECT
},
{ "resist-water", "^BResist-Water^x", "vuln-water",
"^BYou feel resistant to water.^x", "^B%M looks resistant to water.^x",
"^BYou feel less resistant to water.^x", "^B%M looks less resistant to water.^x",
effectResist, false, GOOD_EFFECT
},
{ "resist-electric", "^cResist-Electric^x", "vuln-electric",
"^cYou feel resistant to electric.^x", "^c%M looks resistant to electric.^x",
"^cYou feel less resistant to electric.^x", "^c%M looks less resistant to electric.^x",
effectResist, false, GOOD_EFFECT
},
{ "vuln-cold", "^bVuln-Cold^x", "resist-cold",
"^cYou feel vulnerable to cold.^x", "^c%M looks vulnerable to cold.^x",
"^cYou feel less vulnerable to cold.^x", "^c%M looks less vulnerable to cold.^x",
effectResist, false, BAD_EFFECT
},
{ "vuln-fire", "^rVuln-Fire^x", "resist-fire",
"^cYou feel vulnerable to fire.^x", "^c%M looks vulnerable to fire.^x",
"^cYou feel less vulnerable to fire.^x", "^c%M looks less vulnerable to fire.^x",
effectResist, false, BAD_EFFECT
},
{ "vuln-earth", "^YVuln-Earth^x", "resist-earth",
"^cYou feel vulnerable to earth.^x", "^c%M looks vulnerable to earth.^x",
"^cYou feel less vulnerable to earth.^x", "^c%M looks less vulnerable to earth.^x",
effectResist, false, BAD_EFFECT
},
{ "vuln-air", "^yVuln-Air^x", "resist-air",
"^cYou feel vulnerable to air.^x", "^c%M looks vulnerable to air.^x",
"^cYou feel less vulnerable to air.^x", "^c%M looks less vulnerable to air.^x",
effectResist, false, BAD_EFFECT
},
{ "vuln-water", "^BVuln-Water^x", "resist-water",
"^cYou feel vulnerable to water.^x", "^c%M looks vulnerable to water.^x",
"^cYou feel less vulnerable to water.^x", "^c%M looks less vulnerable to water.^x",
effectResist, false, BAD_EFFECT
},
{ "vuln-electric", "^cVuln-Electric^x", "resist-electric",
"^cYou feel vulnerable to electric.^x", "^c%M looks vulnerable to electric.^x",
"^cYou feel less vulnerable to electric.^x", "^c%M looks less vulnerable to electric.^x",
effectResist, false, BAD_EFFECT
},
{ "immune-cold", "^bImmune-Cold^x", "", "", "", "", "", effectResist, false, GOOD_EFFECT },
{ "immune-fire", "^rImmune-Fire^x", "", "", "", "", "", effectResist, false, GOOD_EFFECT },
{ "immune-earth", "^YImmune-Earth^x", "", "", "", "", "", effectResist, false, GOOD_EFFECT },
{ "immune-air", "^yImmune-Air^x", "", "", "", "", "", effectResist, false, GOOD_EFFECT },
{ "immune-water", "^BImmune-Water^x", "", "", "", "", "", effectResist, false, GOOD_EFFECT },
{ "immune-electric", "^cImmune-Electric^x", "", "", "", "", "", effectResist, false, GOOD_EFFECT },
{ "vuln-crushing", "^rVuln-Crushing^x", "", "", "", "", "", effectWeaponRVI, false, BAD_EFFECT },
{ "vuln-chopping", "^rVuln-Chopping^x", "", "", "", "", "", effectWeaponRVI, false, BAD_EFFECT },
{ "vuln-piercing", "^rVuln-Piercing^x", "", "", "", "", "", effectWeaponRVI, false, BAD_EFFECT },
{ "vuln-slashing", "^rVuln-Slashing^x", "", "", "", "", "", effectWeaponRVI, false, BAD_EFFECT },
{ "vuln-exotic", "^rVuln-Exotic^x", "", "", "", "", "", effectWeaponRVI, false, BAD_EFFECT },
{ "vuln-ranged", "^rVuln-Ranged^x", "", "", "", "", "", effectWeaponRVI, false, BAD_EFFECT },
{ "resist-crushing", "^mResist-Crushing^x", "", "", "", "", "", effectWeaponRVI, false, GOOD_EFFECT },
{ "resist-chopping", "^mResist-Chopping^x", "", "", "", "", "", effectWeaponRVI, false, GOOD_EFFECT },
{ "resist-piercing", "^mResist-Piercing^x", "", "", "", "", "", effectWeaponRVI, false, GOOD_EFFECT },
{ "resist-slashing", "^mResist-Slashing^x", "", "", "", "", "", effectWeaponRVI, false, GOOD_EFFECT },
{ "resist-exotic", "^mResist-Exotic^x", "", "", "", "", "", effectWeaponRVI, false, GOOD_EFFECT },
{ "resist-ranged", "^mResist-Ranged^x", "", "", "", "", "", effectWeaponRVI, false, GOOD_EFFECT },
{ "immune-crushing", "^cImmune-Crushing^x", "", "", "", "", "", effectWeaponRVI, false, GOOD_EFFECT },
{ "immune-chopping", "^cImmune-Chopping^x", "", "", "", "", "", effectWeaponRVI, false, GOOD_EFFECT },
{ "immune-piercing", "^cImmune-Piercing^x", "", "", "", "", "", effectWeaponRVI, false, GOOD_EFFECT },
{ "immune-slashing", "^cImmune-Slashing^x", "", "", "", "", "", effectWeaponRVI, false, GOOD_EFFECT },
{ "immune-exotic", "^cImmune-Exotic^x", "", "", "", "", "", effectWeaponRVI, false, GOOD_EFFECT },
{ "immune-ranged", "^cImmune-Ranged^x", "", "", "", "", "", effectWeaponRVI, false, GOOD_EFFECT },
{ "porphyria", "^WPorphyria^x", "",
"^WYour skin turns pale.^x","^W%M looks pale.^x",
"", "",
effectCurse, true, BAD_EFFECT
},
{ "vampirism", "^rVampirism^x", "", "", "", "", "", effectGeneric, false, NEUTRAL_EFFECT },
{ "lycanthropy", "^oLycanthropy^x", "", "", "", "", "", effectDisease, true, BAD_EFFECT },
{ "slow-poison", "^gSlow-Poison^x", "", "", "", "", "", effectGeneric, true, GOOD_EFFECT },
{ "disease", "^rDisease^x", "", "", "", "", "", effectDisease, true, BAD_EFFECT },
{ "poison", "^gPoison^x", "",
"", "",
"^yThe poison has run it's course.", "",
effectPoison, true, BAD_EFFECT
},
{ "wounded", "^rFestering Wounds^x", "",
"", "",
"Your wounds are no longer unclean.", "",
effectCurse, true, BAD_EFFECT
},
{ "creeping-doom", "^DCreeping-Doom^x", "",
"", "",
"^WThe cursed spiders leave your body.^x", "",
effectCurse, true, BAD_EFFECT
},
{ "alwayscold", "^BAlways Cold^x", "",
"^bYour temperature drops.^x", "^b%M's temperature drops.^x",
"", "",
effectNatural, false, GOOD_EFFECT
},
{ "alwayswarm", "^RAlways Warm^x", "",
"^rYour temperature raises.^x", "^r%M's temperature raises.^x",
"", "",
effectNatural, false, GOOD_EFFECT
},
{ "death-sickness", "^#^DDeath Sickness!^x", "",
"^DYou have become afflicted with death sickness.^x", "",
"^WYou recover from your death sickness.^x", "^W%M looks much better.^x",
effectDeathSickness, true, BAD_EFFECT
},
{ "petrification", "^DPetrified!^x", "",
"^DYou turn to stone!^x", "^D%M has been turned to stone!",
"^YStone becomes flesh, you can move again!^x", "^YStone becomes flesh, %N can move again!^x",
effectDisable, false, BAD_EFFECT
},
{ "hold-person", "^YMagically Held!^x", "",
"^cYou are unable to move.^x", "^c%M is unable to move.^x",
"^cYou are able to move again.^x", "^c%M is able to move again.^x",
effectDisable, false, BAD_EFFECT
},
{ "drunkenness", "^o", "",
"^oYou feel light-headed and your vision blurs.^x", "^o%M hiccups and staggers.^x",
"^CYou no longer feel light-headed.^x", "^c^%M no longer looks inebriated.^x",
effectDisable, false, BAD_EFFECT
},
{ "confusion", "^CConfused!^x", "",
"^cYour mind clouds.^x", "^cA confused look overcomes %N.^x",
"^cThe fog over your mind lifts.^x", "^c^%M no longer looks confused.^x",
effectDisable, false, BAD_EFFECT
},
{ "blindness", "^YBlinded!^x", "",
"^yYou have gone blind!^x", "^y%M has gone blind.^x",
"^yYou can see again!^x", "^y%M's vision returns.^x",
effectDisable, false, BAD_EFFECT
},
{ "deafness", "^YDeafened!^x", "",
"^yYou lose your hearing!^x", "^y%M has gone deaf.^x",
"^yYou can hear again!^x", "^y%M's hearing returns.^x",
effectDisable, false, BAD_EFFECT
},
{ "silence", "^CSilent!^x", "",
"^CYour voice fades!^x", "^C%M's voice fades.^x",
"^gYou voice returns!^x", "^g%M's voice returns.^x",
effectDisable, false, BAD_EFFECT
},
{ "strength", "^YStrength^x", "enfeeblement",
"^YYou feel stronger!^x", "^Y%M looks stronger.^x",
"^yYour strength fades.^x", "^y%M's strength fades.^x",
effectStatRaise, false, GOOD_EFFECT
},
{ "haste", "^CHaste^x", "slow",
"^cThe world slows down around you.^x", "^c%M starts moving much faster.^x",
"^cThe world catches up to you.^x", "^c%M slows down.^x",
effectStatRaise, false, GOOD_EFFECT
},
{ "fortitude", "^GFortitude^x", "weakness",
"^GYou are vitalized by magical health.^x", "^G%M is vitalized by magical health.^x",
"^gYour magical health fades.^x", "^g%M's magical health fades.^x",
effectStatRaise, false, GOOD_EFFECT
},
{ "insight", "^mInsight^x", "feeblemind",
"^mYou become filled with magical insight.^x", "^Y%M is filled with magical insight.^x",
"^mYour magical insight fades.^x", "^y%M's magical insight fades.^x",
effectStatRaise, false, GOOD_EFFECT
},
{ "prayer", "^mPrayer^x", "damnation",
"^yYou shine with divine favor!^x", "^y%M shines radiently.^x",
"^yYour divine favor fades.^x", "^y%M's radient shine fades.^x",
effectStatRaise, false, GOOD_EFFECT
},
{ "enfeeblement", "^GEnfeeblement^x", "strength",
"^GYou feel weaker!^x", "^G%M looks much weaker.^x",
"^GYour weakness fades.^x", "^G%M's weakness fades.^x",
effectStatLower, false, BAD_EFFECT
},
{ "slow", "^gSlow^x", "haste",
"^gThe world speeds up around you.^x", "^g%M starts moving much slower.^x",
"^gYou catch up to the world.^x", "^g%M starts moving normally.^x",
effectStatLower, false, BAD_EFFECT
},
{ "weakness", "^YWeakness^x", "fortitude",
"^YA magical force saps your health.^x", "^Y%M looks unnaturally pale.^x",
"^YYour health returns.^x", "^Y%M's health returns.^x",
effectStatLower, false, BAD_EFFECT
},
{ "feeblemind", "^mFeeblemind^x", "insight",
"^mYour minds becomes feeble.^x", "^m%M blankly stares off into space.^x",
"^mThe fog in your mind fades.^x", "^m%M's blank stare dissipates.^x",
effectStatLower, false, BAD_EFFECT
},
{ "damnation", "^rDamnation^x", "prayer",
"^rYou are damned by the gods!^x", "^r%M has been damned by the gods!^x",
"^rYour spiritual punishment has ended.^x", "^r%M's spiritual punishment has ended.^x",
effectStatLower, false, BAD_EFFECT
},
{ "fear", "^YFear^x", "",
"^yYou suddenly feel very afraid.^x", "^r%M suddenly looks very afraid.^x",
"^yYou feel your courage return.^x", "^y%M's courage returns.^x",
effectGeneric, false, BAD_EFFECT
},
{ "courage", "^YCourage^x", "",
"^YYou suddenly feel very brave.^x", "^Y%M suddenly looks very brave.^x",
"^YYou are no longer unnaturally brave.\n", "^Y%M's courage returns to normal.^x",
effectGeneric, false, GOOD_EFFECT
},
{ "", "", "", "", "", "", 0, false, NO_EFFECT_TYPE }
};
EffectList roomEffects[] = {
{ "dense-fog", "^CDense Fog^x", "",
"", "^WFog begins to fill the area.^x",
"", "^WThe fog clears the area.^x",
effectGeneric, false, NEUTRAL_EFFECT
},
{ "hallow", "^YHallow^x", "",
"", "^YA holy aura fills the room.^x",
"", "^WThe holy aura in the room fades.^x",
effectGeneric, false, NEUTRAL_EFFECT
},
{ "unhallow", "^DUnhallow^x", "",
"", "^DAn unholy aura fills the room.^x",
"", "^WThe unholy aura in the room fades.^x",
effectGeneric, false, NEUTRAL_EFFECT
},
{ "toxic-cloud", "^GToxic Cloud^x", "",
"", "^GA toxic cloud begins to fill the area.^x",
"", "^WThe toxic cloud clears the area.^x",
effectRoomDoT, false, NEUTRAL_EFFECT
},
{ "globe-of-silence", "^DGlobe of Silence^x", "",
"", "^DSounds in the area begin to fade.^x",
"", "^WSounds in the area return.^x",
effectGeneric, false, NEUTRAL_EFFECT
},
{ "", "", "", "", "", "", 0, false, NO_EFFECT_TYPE }
};
EffectList exitEffects[] = {
{ "wall-of-fire", "^RWall Of Fire^x", "",
"", "^RA wall of fire ignites and blocks passage to the %s.^x",
"", "^WThe wall of fire blocking the %s dies down.^x",
effectWall, false, NEUTRAL_EFFECT
},
{ "wall-of-force", "^sWall Of Force^x", "",
"", "^sA wall of force appears and blocks passage to the %s.^x",
"", "^WThe wall of force blocking the %s vanishes.^x",
effectWall, true, NEUTRAL_EFFECT
},
{ "wall-of-thorns", "^oWall Of Thorns^x", "",
"", "^oA wall of thorns grows and blocks passage to the %s.^x",
"", "^WThe wall of thorns blocking the %s withers away.^x",
effectWall, false, NEUTRAL_EFFECT
},
{ "concealed", "^cConcealed^x", "", "", "", "", "", effectGeneric, false, NEUTRAL_EFFECT },
{ "", "", "", "", "", "", 0, false, NO_EFFECT_TYPE }
};
//*********************************************************************
// whichList
//*********************************************************************
EffectList* whichList(EffectParentType type) {
switch(type) {
case EFFECT_CREATURE:
return(creatureEffects);
case EFFECT_EXIT:
return(exitEffects);
case EFFECT_ROOM:
return(roomEffects);
default:
break;
}
return(0);
}
//*********************************************************************
// findEffect
//*********************************************************************
effectPtr findEffect(const bstring& effect, EffectParentType type) {
EffectList *list = whichList(type);
int i=0;
while(list[i].name != "") {
if(list[i].name == effect)
return(&list[i]);
i++;
}
return(0);
}
//*********************************************************************
// findEffectFn
//*********************************************************************
EffectFn findEffectFn(const bstring& effect, EffectParentType type) {
EffectList *list = whichList(type);
int i=0;
while(list[i].name != "") {
if(list[i].name == effect)
return(list[i].effFn);
i++;
}
return(0);
}
// End local functions
//*********************************************************************
// effectPrototype
//*********************************************************************
// use this when creating new effect functions
bool effectPrototype(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom)
{
//Player* pTarget = target->getPlayer();
//Monster* mTarget = target->getMonster();
switch(action) {
case EFFECT_COMPUTE:
{
int duration = 0;
int strength = 1;
if(aFrom == FROM_CREATURE) {
//Creature* caster = static_cast<Creature*>(applier);
} else {
duration = 1200;
}
effect->setStrength(strength);
effect->setDuration(duration);
}
break;
case EFFECT_APPLY:
break;
case EFFECT_UNAPPLY:
break;
case EFFECT_PULSE:
break;
default:
break;
}
return(true);
}
//*********************************************************************
// effectWall
//*********************************************************************
bool effectWall(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom)
{
switch(action) {
case EFFECT_COMPUTE:
break;
case EFFECT_APPLY:
break;
case EFFECT_UNAPPLY:
break;
case EFFECT_PULSE:
if(effect->getExtra() > 0) {
// tick down how long this wall is disabled
effect->setExtra(effect->getExtra() - 1);
if(!effect->getExtra()) {
EffectList* ef = effect->getEffect();
broadcast(0, effect->getParentRoom(), ef->roomStrAdd.c_str(), effect->getParentExit()->name);
}
}
break;
default:
break;
}
return(true);
}
//*********************************************************************
// effectDarkInfra
//*********************************************************************
bool effectDarkInfra(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom)
{
//Player* pTarget = target->getPlayer();
//Monster* mTarget = target->getMonster();
switch(action) {
case EFFECT_COMPUTE:
{
int duration = 0;
int strength = 1;
Creature* caster = 0;
if(aFrom == FROM_CREATURE) {
caster = static_cast<Creature*>(applier);
} else {
caster = target;
}
duration = 300L + caster->getLevel() * 300L + caster->getRoom()->magicBonus() ? 600L : 0;
if(effect->getName() == "darkness") {
if(target->isStaff())
return(false);
if(caster->getDeity() == ENOCH) duration = duration * 2 / 3;
if(caster->getDeity() == ARACHNUS) duration = duration * 3 / 2;
}
effect->setStrength(strength);
effect->setDuration(duration);
}
break;
case EFFECT_APPLY:
break;
case EFFECT_UNAPPLY:
if(effect->getName() == "darkness")
target->getRoom()->killMortalObjects();
break;
case EFFECT_PULSE:
break;
default:
break;
}
return(true);
}
//*********************************************************************
// effectBeneficial
//*********************************************************************
bool effectBeneficial(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom)
{
//Player* pTarget = target->getPlayer();
//Monster* mTarget = target->getMonster();
switch(action) {
case EFFECT_COMPUTE:
{
int duration = 0;
int strength = 1;
if(aFrom == FROM_CREATURE) {
Creature* caster = static_cast<Creature*>(applier);
duration = MAX(300, 1200 + bonus(caster->intelligence.getCur()) * 600);
if(caster->getClass() == CLERIC || caster->getClass() == PALADIN)
duration += 60 * caster->getLevel();
if(caster->getRoom()->magicBonus())
duration += 800L;
} else {
if(effect->getName() == "reflect-magic") {
duration = 600;
} else {
duration = 1200;
}
}
if( (effect->getName() == "warmth" && target->isEffected("alwayswarm")) ||
(effect->getName() == "heat-protection" && target->isEffected("alwayscold")) )
duration /= 4;
effect->setStrength(strength);
effect->setDuration(duration);
}
break;
case EFFECT_APPLY:
if(effect->getName() == "protection") {
// target->getArmor() -= 10;
} else if(effect->getName() == "bless") {
//target->thaco -= 1;
}
break;
case EFFECT_UNAPPLY:
if(effect->getName() == "protection") {
// target->getArmor() += 10;
} else if(effect->getName() == "bless") {
//target->thaco += 1;
}
break;
case EFFECT_PULSE:
break;
default:
break;
}
return(true);
}
//*********************************************************************
// effectShield
//*********************************************************************
bool effectShield(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom)
{
switch(action) {
case EFFECT_COMPUTE:
// addEffect needs this to return true
if(effect->getName() == "fire-shield")
return(true);
// Computed outside of this function
return(false);
case EFFECT_APPLY:
case EFFECT_UNAPPLY:
case EFFECT_PULSE:
default:
break;
}
return(true);
}
//*********************************************************************
// effectVisibility
//*********************************************************************
bool effectVisibility(EffectInfo* effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom)
{
Player* pTarget = target->getPlayer();
//Monster* mTarget = target->getMonster();
switch(action) {
case EFFECT_COMPUTE:
{
int duration = 0;
int strength = 1;
if(aFrom == FROM_CREATURE) {
Creature* caster = static_cast<Creature*>(applier);
if(effect->getName() == "invisibility")
duration = MAX(300, 1200 + bonus(caster->intelligence.getCur()) * 600);
else if(effect->getName() == "pass-without-trace")
duration = MAX(300, 1600 + bonus(caster->intelligence.getCur()) * 800);
else if(effect->getName() == "blur")
duration = MAX(300, 600 + bonus(caster->intelligence.getCur()) * 150);
else // Camouflage
duration = MAX(300, 600 + bonus(caster->intelligence.getCur()) * 300);
if(caster->getClass() == MAGE || caster->isCt())
duration += 60 * caster->getLevel();
if(caster->getRoom()->magicBonus())
duration += 600L;
// so dumb players don't have invis immediately wear off
if(target == caster)
duration = MAX(600, duration);
else
duration = MAX(60, duration);
} else {
duration = 1200;
}
effect->setDuration(duration);
effect->setStrength(strength);
}
break;
// These do nothing for invis
case EFFECT_APPLY:
case EFFECT_UNAPPLY:
break;
case EFFECT_PULSE:
// Refresh camouflage if it's getting low and we're a druid and in the forest
if(effect->getName() == "camouflage" && effect->getDuration() <= 60) {
if(pTarget && pTarget->getClass() == DRUID && pTarget->getRoom() && pTarget->getRoom()->isForest()) {
effect->setDuration(60);
}
}
default:
break;
}
return(true);
}
//*********************************************************************
// effectLanguages
//*********************************************************************
bool effectLanguages(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom)
{
Player* pTarget = target->getPlayer();
//Monster* mTarget = target->getMonster();
switch(action) {
case EFFECT_COMPUTE:
{
int duration = 0;
int strength = 1;
if(aFrom == FROM_CREATURE) {
Creature* caster = static_cast<Creature*>(applier);
duration = MAX(300, 480 + bonus(caster->intelligence.getCur()) * 60);
if(caster->getRoom()->magicBonus())
duration += 180L;
} else {
duration = 300;
}
effect->setStrength(strength);
effect->setDuration(duration);
}
break;
case EFFECT_APPLY:
break;
case EFFECT_UNAPPLY:
if(effect->getName() == "tongues") {
if(!pTarget->languageIsKnown(LUNKNOWN + pTarget->current_language)) {
bstring selfStr = "";
int i;
selfStr.append("You can no longer speak");
selfStr.append(get_language_adj(pTarget->current_language));
selfStr.append ("\n");
if(pTarget->languageIsKnown(LUNKNOWN+LCOMMON)) {
pTarget->current_language = LCOMMON;
} else {
// oh no, they don't know common; time to find a language they do know
for(i=0; i<LANGUAGE_COUNT; i++) {
if(pTarget->languageIsKnown(LUNKNOWN+i)) {
pTarget->current_language = i;
break;
}
}
}
}
}
break;
case EFFECT_PULSE:
break;
default:
break;
}
return(true);
}
//*********************************************************************
// effectDetect
//*********************************************************************
bool effectDetect(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom)
{
//Player* pTarget = target->getPlayer();
//Monster* mTarget = target->getMonster();
switch(action) {
case EFFECT_COMPUTE:
{
int duration = 0;
int strength = 1;
if(aFrom == FROM_CREATURE) {
Creature* caster = static_cast<Creature*>(applier);
if(effect->getName() == "true-sight") {
duration = MAX(300, 300 + bonus(caster->intelligence.getCur()) * 600);
if(caster->getClass() == CLERIC)
duration += 60 * caster->getLevel();
if(caster->getRoom()->magicBonus())
duration += 300L;
} else if(effect->getName() == "farsight") {
duration = MAX(300, 800 + bonus((int) caster->intelligence.getCur()) * 400);
if(caster->getRoom()->magicBonus())
duration += 400L;
} else {
duration = MAX(300, 1200 + bonus(caster->intelligence.getCur()) * 600);
if(caster->getClass() == MAGE)
duration += 60 * caster->getLevel();
if(caster->getRoom()->magicBonus())
duration += 600L;
}
} else {
if(effect->getName() == "true-sight" || effect->getName() == "farsight")
duration = 800;
else
duration = 1200;
}
effect->setStrength(strength);
effect->setDuration(duration);
}
break;
// These do nothing for detect spells
case EFFECT_APPLY:
case EFFECT_UNAPPLY:
case EFFECT_PULSE:
default:
break;
}
return(true);
}
//*********************************************************************
// effectGravity
//*********************************************************************
bool effectGravity(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom)
{
//Player* pTarget = target->getPlayer();
//Monster* mTarget = target->getMonster();
switch(action) {
case EFFECT_COMPUTE:
{
int duration = 0;
if(aFrom == FROM_CREATURE) {
Creature* caster = static_cast<Creature*>(applier);
duration = 2400L + bonus(caster->intelligence.getCur()) * 600L;
if(caster->getRoom()->magicBonus())
duration += 800L;
} else {
duration = 1200;
}
effect->setDuration(duration);
}
break;
case EFFECT_APPLY:
case EFFECT_UNAPPLY:
case EFFECT_PULSE:
default:
break;
}
return(true);
}
//*********************************************************************
// effectVuln
//*********************************************************************
bool effectVuln(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom)
{
switch(action) {
case EFFECT_COMPUTE:
{
// Cancel out a potential resist effect of the same element
if(target->removeOppositeEffect(effect))
return(false);
int duration = 0;
int strength = 1;
if(aFrom == FROM_CREATURE) {
Creature* caster = static_cast<Creature*>(applier);
duration = MAX(300, 1200 + bonus(caster->intelligence.getCur()) * 600);
if(caster->getRoom()->magicBonus())
duration += 800L;
} else {
duration = 240;
}
effect->setStrength(strength);
effect->setDuration(duration);
}
break;
// These do nothing for detect spells
case EFFECT_APPLY:
case EFFECT_UNAPPLY:
case EFFECT_PULSE:
default:
break;
}
return(true);
}
//*********************************************************************
// effectImmune
//*********************************************************************
bool effectImmune(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom) {
Player* pTarget = target->getPlayer();
switch(action) {
case EFFECT_COMPUTE:
// No players with this effect
if(pTarget)
return(false);
break;
// These do nothing for detect spells
case EFFECT_APPLY:
case EFFECT_UNAPPLY:
break;
case EFFECT_PULSE:
// No players with this effect
if(pTarget)
return(false);
default:
break;
}
return(true);
}
//*********************************************************************
// effectResist
//*********************************************************************
bool effectResist(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom)
{
//Player* pTarget = target->getPlayer();
//Monster* mTarget = target->getMonster();
switch(action) {
case EFFECT_COMPUTE:
{
// Cancel out a potential vuln effect of the same element
target->removeOppositeEffect(effect);
int duration = 0;
int strength = 1;
if(aFrom == FROM_CREATURE) {
Creature* caster = static_cast<Creature*>(applier);
duration = MAX(300, 1200 + bonus(caster->intelligence.getCur()) * 600);
if(caster->getRoom()->magicBonus())
duration += 800L;
}
else {
if(effect->getName() == "resist-magic")
duration = 1200;
else
duration = 240;
}
effect->setStrength(strength);
effect->setDuration(duration);
}
break;
case EFFECT_APPLY:
case EFFECT_UNAPPLY:
case EFFECT_PULSE:
default:
break;
}
return(true);
}
//*********************************************************************
// effectWeaponRVI
//*********************************************************************
bool effectWeaponRVI(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom) {
Player* pTarget = target->getPlayer();
switch(action) {
case EFFECT_COMPUTE:
// No players with this effect
if(pTarget)
return(false);
break;
// These do nothing for detect spells
case EFFECT_APPLY:
case EFFECT_UNAPPLY:
break;
case EFFECT_PULSE:
// No players with this effect
if(pTarget)
return(false);
default:
break;
}
return(true);
}
//*********************************************************************
// effectStatRaise
//*********************************************************************
bool effectStatRaise(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom) {
//Player* pTarget = target->getPlayer();
//Monster* mTarget = target->getMonster();
switch(action) {
case EFFECT_COMPUTE:
{
// We wore off the opposite effect, don't put this one into effect
if(target->removeOppositeEffect(effect))
return(false);
if(target->isUndead() && effect->getName() == "fortitude")
return(false);
int duration = 0;
// Default stat mod of 30, adjusted via the applier
int strength = 30;
if(aFrom == FROM_CREATURE) {
Creature* caster = static_cast<Creature*>(applier);
duration = 180;
if(caster->getRoom()->magicBonus())
duration += 90;
} else {
duration = 60;
}
effect->setStrength(strength);
effect->setDuration(duration);
}
break;
case EFFECT_APPLY:
target->addStatModEffect(effect);
break;
case EFFECT_UNAPPLY:
target->remStatModEffect(effect);
break;
case EFFECT_PULSE:
default:
break;
}
return(true);
}
//*********************************************************************
// effectStatLower
//*********************************************************************
bool effectStatLower(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom) {
//Player* pTarget = target->getPlayer();
//Monster* mTarget = target->getMonster();
switch(action) {
case EFFECT_COMPUTE:
{
// We wore off the opposite effect, don't put this one into effect
if(target->removeOppositeEffect(effect))
return(false);
if(target->isUndead() && effect->getName() == "weakness")
return(false);
int duration = 0;
// Default stat mod of 30, adjusted via the applier
int strength = -30;
if(aFrom == FROM_CREATURE) {
Creature* caster = static_cast<Creature*>(applier);
duration = 180;
if(caster->getRoom()->magicBonus())
duration += 90;
} else {
duration = 60;
}
effect->setStrength(strength);
effect->setDuration(duration);
}
break;
case EFFECT_APPLY:
target->addStatModEffect(effect);
break;
case EFFECT_UNAPPLY:
target->remStatModEffect(effect);
break;
case EFFECT_PULSE:
default:
break;
}
return(true);
}
//*********************************************************************
// effectNatural
//*********************************************************************
bool effectNatural(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom) {
//Player* pTarget = target->getPlayer();
//Monster* mTarget = target->getMonster();
switch(action) {
case EFFECT_COMPUTE:
if(effect->getName() == "enlarge" || effect->getName() == "reduce") {
// this should never happen, but just in case
bstring opposite = effect->getName() == "enlarge" ? "reduce" : "enlarge";
if(target->isEffected(opposite)) {
EffectInfo *e = target->getEffect(opposite);
if(e->getDuration() == -1) {
//target->removeEffect(effect, false);
return(false);
}
target->removeEffect(e, false);
}
// FROM_CREATURE is handled in the spell because it's strength can be set
// manually by the caster
if(aFrom != FROM_CREATURE) {
int strength = 1;
int duration = 800;
effect->setStrength(strength);
effect->setDuration(duration);
if(!target->changeSize(0, strength, effect->getName() == "enlarge"))
return(false);
}
} else {
effect->setStrength(1);
effect->setDuration(-1);
}
break;
case EFFECT_APPLY:
break;
case EFFECT_UNAPPLY:
if(effect->getName() == "enlarge" || effect->getName() == "reduce")
target->changeSize(effect->getStrength(), 0, effect->getName() == "enlarge");
break;
case EFFECT_PULSE:
default:
break;
}
return(true);
}
//*********************************************************************
// effectDisable
//*********************************************************************
bool effectDisable(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom) {
Player* pTarget = target->getPlayer();
//Monster* mTarget = target->getMonster();
switch(action) {
case EFFECT_COMPUTE:
{
int duration = 0;
int strength = 1;
if(effect->getName() == "petrification") {
strength = 1;
duration = -1;
} else if(effect->getName() == "hold-person") {
if(aFrom == FROM_CREATURE) {
Creature* caster = static_cast<Creature*>(applier);
duration = mrand(12,18) + 2*bonus(caster->intelligence.getCur()) - crtWisdom(target);;
} else {
duration = mrand(9, 12);
}
} else if(effect->getName() == "confusion") {
if(aFrom == FROM_CREATURE) {
Creature* caster = static_cast<Creature*>(applier);
duration = MAX(60, caster->intelligence.getCur());
} else {
duration = 60;
}
} else if(effect->getName() == "blindness") {
duration = 300 - (target->constitution.getCur()/10);
} else if(effect->getName() == "silence") {
duration = 600;
}
effect->setStrength(strength);
effect->setDuration(duration);
}
break;
case EFFECT_APPLY:
case EFFECT_UNAPPLY:
if(effect->getName() == "blindness" && pTarget)
pTarget->clearFlag(P_DM_BLINDED);
else if(effect->getName() == "silence" && pTarget)
pTarget->clearFlag(P_DM_SILENCED);
break;
case EFFECT_PULSE:
// Damage is handled by doDoT's for petrification
break;
default:
break;
}
return(true);
}
//*********************************************************************
// effectGeneric
//*********************************************************************
// For effects with no need for compute/pulse/etc
bool effectGeneric(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom)
{
//Player* pTarget = target->getPlayer();
//Monster* mTarget = target->getMonster();
switch(action) {
case EFFECT_COMPUTE:
case EFFECT_APPLY:
case EFFECT_UNAPPLY:
case EFFECT_PULSE:
default:
break;
}
return(true);
}
//*********************************************************************
// doRoomDoT
//*********************************************************************
void doRoomDoT(EffectInfo *effect, ctag* cp, Player* killer, bool online) {
Creature *target = 0;
DeathType dt;
Damage damage;
bool toxicCloud = (effect->getName() == "toxic-cloud");
while(cp) {
target = cp->crt;
cp = cp->next_tag;
if(effect->isOwner(target->isPet() ? target->following : target))
continue;
if(toxicCloud) {
if(target->immuneToPoison())
continue;
target->wake("Terrible nightmares disturb your sleep!");
damage.reset();
damage.set(mrand(2,15) + effect->getStrength() / 2);
target->modifyDamage(0, MAGICAL, damage);
dt = POISON_GENERAL;
target->printColor("^GYou choke on poisonous gases for %s%d^G damage.\n", target->customColorize("*CC:DAMAGE*"), damage.get());
broadcast(target->getSock(), target->getRoom(), "%M chokes and gags on poisonous gases.", target);
if(killer && target->isMonster()) {
target->getMonster()->addEnmCrt(killer);
if(online)
target->getMonster()->addEnmDmg(killer, damage.get());
}
target->hp.decrease(damage.get());
if(target->hp.getCur() < 1) {
target->printColor("^GThe poisonous gases fill your lungs!\n");
if(killer && online)
killer->print("%M chokes on your toxic cloud and dies!\n", target);
}
}
if(target->hp.getCur() < 1) {
if(killer) {
target->die(killer);
killer->save(online);
} else {
if(target->isPlayer())
target->getPlayer()->die(dt);
else
target->getMonster()->mobDeath();
}
}
}
}
//*********************************************************************
// effectRoomDoT
//*********************************************************************
bool effectRoomDoT(EffectInfo *effect, Creature* target, EffectAction action, void* applier, ApplyFrom aFrom)
{
switch(action) {
case EFFECT_COMPUTE:
break;
case EFFECT_APPLY:
break;
case EFFECT_UNAPPLY:
break;
case EFFECT_PULSE:
{
Player* killer=0;
bool online = true;
if(effect->getOwner() != "") {
killer = gServer->findPlayer(effect->getOwner());
if(!killer) {
if(loadPlayer(effect->getOwner().c_str(), &killer))
online = false;
else
killer = 0;
}
}
doRoomDoT(effect, effect->getParentRoom()->first_ply, killer, online);
doRoomDoT(effect, effect->getParentRoom()->first_mon, killer, online);
if(killer && !online)
free_crt(killer);
}
break;
default:
break;
}
return(true);
}