/* * enchantment.cpp * Enchantment spells * ____ _ * | _ \ ___ __ _| |_ __ ___ ___ * | |_) / _ \/ _` | | '_ ` _ \/ __| * | _ < __/ (_| | | | | | | \__ \ * |_| \_\___|\__,_|_|_| |_| |_|___/ * * 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 "magic.h" //********************************************************************* // splHoldPerson //********************************************************************* int splHoldPerson(Creature* player, cmd* cmnd, SpellData* spellData) { int bns=0, nohold=0, dur=0; Creature* target=0; if( player->getClass() != CLERIC && player->getClass() != MAGE && player->getClass() != LICH && player->getClass() != PALADIN && !player->isCt() && spellData->how == CAST ) { player->print("You are unable to cast that spell.\n"); return(0); } if(cmnd->num == 2) { if(spellData->how != POTION) { player->print("Hold whom?\n"); return(0); } else if(player->getClass() == LICH) { player->print("Nothing happens.\n"); return(0); } else if(player->isEffected("vampirism") && !isDay()) { player->print("Nothing happens.\n"); return(0); } else if(player->flagIsSet(P_MISTED)) { player->print("Nothing happens.\n"); return(0); } else { player->print("You are suddenly unable to move!\n"); broadcast(player->getSock(), player->getRoom(), "%M becomes unable to move!", player); player->unhide(); player->addEffect("hold-person", 0, 0, true, player); } } else { if(noPotion(player, spellData)) return(0); cmnd->str[2][0] = up(cmnd->str[2][0]); target = player->getRoom()->findCreature(player, cmnd->str[2], cmnd->val[2], true, true); if(!target) { player->print("Cast on whom?\n"); return(0); } if(player->isPlayer() && target->isPlayer() && target->inCombat(false) && !player->flagIsSet(P_OUTLAW)) { player->print("Not in the middle of combat.\n"); return(0); } if(player->isPlayer() && target->isPlayer() && !player->isCt() && target->isCt()) { player->printColor("^yYour spell failed.\n"); return(0); } if(player->isPlayer() && target->isPlayer() && !player->isDm() && target->isDm()) { player->printColor("^yYour spell failed.\n"); return(0); } player->print("You cast a hold-person spell on %N.\n", target); target->print("%M casts a hold-person spell on you.\n", player); broadcast(player->getSock(), target->getSock(), player->getRoom(), "%M casts a hold-person spell on %N.", player, target); if(target->getClass() == LICH) { player->printColor("Liches cannot be held.\n^yYour spell failed.\n"); return(0); } if(target->isEffected("vampirism") && !isDay()) { player->printColor("Vampires cannot be held at night.\n^yYour spell failed.\n"); return(0); } if(target->flagIsSet(P_BERSERKED)) { player->print("No one berserk can be held.\nYour spell failed.\n"); return(0); } if( target->isPlayer() && (target->flagIsSet(P_UNCONSCIOUS) || target->isEffected("petrification") || target->flagIsSet(P_MISTED)) ) { player->printColor("^yYour spell failed.\n"); return(0); } if(target->isPlayer() && target->isEffected("hold-person")) { player->printColor("%M is already held fast.\n^yYour spell fails^x.\n", target); return(0); } if(target->isPlayer() && mrand(1,100) <= 50 && target->isEffected("resist-magic")) { player->printColor("^yYour spell failed.\n"); return(0); } if(spellData->how == CAST) bns = 5*(spellData->level - target->getLevel()) + 2*crtWisdom(target) - 2*bonus((int)player->intelligence.getCur()); if(target->isPlayer() && target->getClass() == CLERIC && target->getDeity() == ARES) bns += 25; if(target->isMonster()) { if( target->flagIsSet(M_DM_FOLLOW) || target->flagIsSet(M_PERMENANT_MONSTER) || !target->getRace() || target->isEffected("resist-magic") || target->flagIsSet(M_RESIST_STUN_SPELL) || target->isEffected("reflect-magic") ) nohold = 1; if( target->flagIsSet(M_LEVEL_BASED_STUN) && (((int)target->getLevel() - (int)spellData->level) > ((player->getClass() == LICH || player->getClass() == MAGE) ? 6:4)) ) nohold = 1; } if(target->isMonster()) { player->smashInvis(); if((!target->chkSave(SPL, player, bns) && !nohold) || player->isCt()) { if(spellData->how == CAST) dur = mrand(9,18) + 2*bonus((int)player->intelligence.getCur()) - crtWisdom(target); else dur = mrand(9,12); target->stun(dur); player->print("%M is held in place!\n", target); broadcast(player->getSock(), player->getRoom(), "%M's spell holds %N in place!", player, target); if(player->isCt()) player->print("*DM* %d seconds.\n", dur); if(target->isMonster()) target->getMonster()->addEnmCrt(player); } else { player->print("%M resisted your spell.\n", target); broadcast(player->getSock(), target->getRoom(), "%M resisted %N's hold-person spell.",target, player); if(target->isMonster()) target->getMonster()->addEnmCrt(player); } } else { player->smashInvis(); if(!target->chkSave(SPL, player, bns) || player->isCt()) { if(spellData->how == CAST) dur = mrand(12,18) + 2*bonus((int)player->intelligence.getCur()) - crtWisdom(target); else dur = mrand(9,12); if(player->isCt()) player->print("*DM* %d seconds.\n", dur); target->addEffect("hold-person", 0, 0, true, player); } else { player->print("%M resisted your spell.\n", target); broadcast(player->getSock(), target->getSock(), target->getRoom(), "%M resisted %N's hold-person spell.",target, player); target->print("%M tried to cast a hold-person spell on you.\n", player); } } } return(1); } //********************************************************************* // splScare //********************************************************************* int splScare(Creature* player, cmd* cmnd, SpellData* spellData) { Player *target=0; int bns=0; long t = time(0); Object *weapon=0, *weapon2=0; if(spellData->how == POTION && player->getClass() == PALADIN && (player->getDeity() == ENOCH || player->getDeity() == LINOTHAN) ) { player->print("Your deity forbids such dishonorable actions!\n"); return(0); } if(player->getClass() != CLERIC && player->getClass() != MAGE && player->getClass() != LICH && player->getClass() != DEATHKNIGHT && player->getClass() != BARD && !player->isEffected("vampirism") && !player->isCt() && spellData->how == CAST ) { player->print("You are unable to cast that spell.\n"); return(0); } // Cast scare if(cmnd->num == 2) { if(spellData->how != POTION) { player->print("On whom?\n"); return(0); } if(player->flagIsSet(P_BERSERKED)) { player->print("You are too enraged to drink that right now.\n"); return(0); } if(player->isEffected("courage")) { player->print("You feel a strange tingle.\n"); return(0); } player->print("You are suddenly terrified to the bone!\n"); broadcast(player->getSock(), player->getRoom(), "%M becomes utterly terrified!", player); if(player->ready[WIELD-1]) { weapon = player->ready[WIELD-1]; player->ready[WIELD-1] = 0; } if(player->ready[HELD-1]) { weapon2 = player->ready[HELD-1]; player->ready[HELD-1] = 0; } target = player->getPlayer(); // killed while fleeing? if(target->flee(true) == 2) return(1); if(weapon) player->ready[WIELD-1] = weapon; if(weapon2) player->ready[HELD-1] = weapon2; // Cast scare on another player } else { if(noPotion(player, spellData)) return(0); cmnd->str[2][0] = up(cmnd->str[2][0]); target = player->getRoom()->findPlayer(player, cmnd, 2); if(!target) { player->print("On whom?\n"); return(0); } if(target->inCombat(false) && !player->flagIsSet(P_OUTLAW)) { player->print("Not in the middle of combat.\n"); return(0); } if(!player->isCt() && target->isCt()) { player->printColor("^yYour spell failed.\n"); return(0); } if(!player->isDm() && target->isDm()) { player->printColor("^yYour spell failed.\n"); return(0); } if(!player->isCt() && !dec_daily(&player->daily[DL_SCARES])) { player->print("You cannot cast that again today.\n"); return(0); } player->print("You cast a scare spell on %N.\n", target); target->print("%M casts a scare spell on you.\n", player); broadcast(player->getSock(), target->getSock(), player->getRoom(), "%M casts a scare spell on %N.", player, target); if(target->getClass() == PALADIN) { player->printColor("Paladins are immune to magical fear.\n^yYour spell failed.\n"); return(0); } if(target->flagIsSet(P_BERSERKED) || target->isUnconscious() || target->isEffected("petrification")) { player->printColor("^yYour spell failed.\n"); return(0); } if(target->isEffected("courage")) { player->print("Your spell is ineffective against %N right now.\n", target); return(0); } if(mrand(1,100) <= 50 && target->isEffected("resist-magic")) { player->printColor("^yYour spell failed.\n"); return(0); } target->wake("Terrible nightmares disturb your sleep!"); // Pets are immune. if(target->isPet()) { player->print("%M's %s is too loyal to be magically scared.\n", target->following, target->name); return(0); } bns = 5*((int)target->getLevel() - (int)spellData->level) + crtWisdom(target); if(!target->chkSave(SPL, player, bns) || player->isCt()) { if(spellData->how == CAST && player->isPlayer()) player->getPlayer()->statistics.offensiveCast(); target->clearFlag(P_SITTING); target->print("You are suddenly terrified to the bone!\n"); broadcast(target->getSock(), player->getRoom(), "%M becomes utterly terrified!", target); target->updateAttackTimer(true, DEFAULT_WEAPON_DELAY); target->lasttime[LT_SPELL].ltime = t; target->lasttime[LT_SPELL].interval = 3L; /* the following code keeps jackasses from abusing re-wield triggers */ /* to make people drop their weapons. Remove the weapon, store it in */ /* temp variable...then have player attempt flee, then put weapons back. */ //********************************************************************* if(target->ready[WIELD-1]) { weapon = target->ready[WIELD-1]; target->ready[WIELD-1] = 0; } if(target->ready[HELD-1]) { weapon2 = target->ready[HELD-1]; target->ready[HELD-1] = 0; } player->setFlag(P_RUNNING); player->lasttime[LT_ENDURANCE].ltime = t; player->lasttime[LT_ENDURANCE].interval = 3L; // killed while fleeing? if(target->flee(true) == 2) return(1); target->clearFlag(P_RUNNING); target->stun(mrand(5,8)); if(weapon) target->ready[WIELD-1] = weapon; if(weapon2) target->ready[HELD-1] = weapon2; //********************************************************************* } else { player->print("%M resisted your spell.\n", target); broadcast(player->getSock(), target->getSock(), target->getRoom(), "%M resisted %N's scare spell.",target, player); target->print("%M tried to cast a scare spell on you.\n", player); } } return(1); } //********************************************************************* // splCourage //********************************************************************* int splCourage(Creature* player, cmd* cmnd, SpellData* spellData) { Creature* target=0; long dur=0; int noCast=0; if(spellData->how != POTION) { if(!player->isCt() && player->getClass() != PALADIN && player->getClass() != CLERIC) { player->print("Your class is unable to cast that spell.\n"); return(0); } if(player->getClass() == CLERIC) { switch(player->getDeity()) { case CERIS: case ARAMON: case GRADIUS: case ARACHNUS: case JAKAR: case MARA: noCast=1; break; } } if(noCast) { player->print("%s does not allow you to cast that spell.\n", gConfig->getDeity(player->getDeity())->getName().c_str()); return(0); } } if(cmnd->num == 2) { target = player; if(spellData->how == CAST || spellData->how == SCROLL || spellData->how == WAND) { player->print("Courage spell cast.\nYou feel unnaturally brave.\n"); broadcast(player->getSock(), player->getRoom(), "%M casts a courage spell on %sself.", player, player->himHer()); } else if(spellData->how == POTION) player->print("You feel unnaturally brave.\n"); } else { if(noPotion(player, spellData)) return(0); cmnd->str[2][0] = up(cmnd->str[2][0]); target = player->getRoom()->findCreature(player, cmnd->str[2], cmnd->val[2], false); if(!target) { player->print("You don't see that person here.\n"); return(0); } if(checkRefusingMagic(player, target)) return(0); player->print("Courage cast on %s.\n", target->name); target->print("%M casts a courage spell on you.\n", player); broadcast(player->getSock(), target->getSock(), player->getRoom(), "%M casts a courage spell on %N.", player, target); } target->removeEffect("fear", true, false); if(target->isEffected("fear")) { player->print("Your spell fails.\n"); target->print("The spell fails.\n"); return(0); } if(spellData->how == CAST) { dur = MAX(300, 900 + bonus((int) player->intelligence.getCur()) * 300); if(player->getRoom()->magicBonus()) { player->print("The room's magical properties increase the power of your spell.\n"); dur += 300L; } } else dur = 600; target->addEffect("courage", dur, 1, true, player); return(1); } //********************************************************************* // splFear //********************************************************************* // The fear spell causes the monster to have a high wimpy / flee // percentage and a penality of -2 on all attacks int splFear(Creature* player, cmd* cmnd, SpellData* spellData) { Creature* target=0; int dur=0; if(player->getClass() == LICH && player->getLevel() < 3 && spellData->how == CAST) { player->print("You are not experienced enough to cast that yet.\n"); return(0); } if(spellData->how == CAST) { dur = 600 + mrand(1, 30) * 10 + bonus((int) player->intelligence.getCur()) * 150; } else if(spellData->how == SCROLL) dur = 600 + mrand(1, 15) * 10 + bonus((int) player->intelligence.getCur()) * 50; else dur = 600 + mrand(1, 30) * 10; if(spellData->how == POTION) dur = mrand(1,120) + 180L; if(spell_fail(player, spellData->how)) return(0); // fear on self if(cmnd->num == 2) { if(player->isEffected("resist-magic")) dur /= 2; if(spellData->how == CAST || spellData->how == WAND || spellData->how == SCROLL) { player->print("You cast a fear spell on yourself.\n"); player->print("Nothing happens.\n"); broadcast(player->getSock(), player->getRoom(), "%M casts a fear spell on %sself.", player, player->himHer()); return(0); } if(spellData->how == POTION && player->getClass() == PALADIN) { player->print("You feel a jitter, then shrug it off.\n"); return(0); } else if(spellData->how == POTION) player->print("You begin to shake in terror.\n"); // fear a monster or player } else { if(noPotion(player, spellData)) return(0); target = player->getRoom()->findCreature(player, cmnd->str[2], cmnd->val[2], false); if(!target || target == player) { player->print("That's not here.\n"); return(0); } if(spellData->how == WAND || spellData->how == SCROLL || spellData->how == CAST) { if( player->isPlayer() && target->isPlayer() && player->getRoom()->flagIsSet(R_SAFE_ROOM) && !target->flagIsSet(P_OUTLAW) ) { player->print("You cannot cast that spell here.\n"); return(0); } } if(!player->canAttack(target)) return(0); if( (target->isMonster() && target->flagIsSet(M_PERMENANT_MONSTER)) || (target->getClass() == PALADIN && target->isMonster()) ) { player->print("%M seems unaffected by fear.\n", target); player->print("%M attacks you.\n", target); broadcast(player->getSock(), target->getSock(), player->getRoom(), "%M casts a fear spell on %N.\n", player, target); broadcast(player->getSock(), target->getSock(), player->getRoom(), "%M brushes it off and attacks %N.\n", player, target); target->getMonster()->addEnmCrt(player); return(0); } if( (target->isPlayer() && target->isEffected("resist-magic")) || (target->isMonster() && target->isEffected("resist-magic")) ) dur /= 2; player->smashInvis(); target->wake("Terrible nightmares disturb your sleep!"); if(target->isPlayer() && target->getClass() == PALADIN) { player->print("Fear spell cast on %s.\n", target->name); player->print("It doesn't do anything noticeable.\n"); broadcast(player->getSock(), target->getSock(), player->getRoom(), "%M casts fear on %N.", player, target); target->print("%M casts a fear spell on you.\n", player); target->print("It has no apparent effect.\n"); return(0); } if(target->chkSave(SPL, player, 0) && !player->isCt()) { target->print("%M tried to cast a fear spell on you!\n", player); broadcast(player->getSock(), target->getSock(), player->getRoom(), "%M tried to cast a fear spell on %N!", player, target); player->print("Your spell fizzles.\n"); return(0); } if(spellData->how == CAST || spellData->how == SCROLL || spellData->how == WAND) { player->print("Fear spell cast on %s.\n", target->name); broadcast(player->getSock(), target->getSock(), player->getRoom(), "%M casts fear on %N.", player, target); target->print("%M casts a fear spell on you.\n", player); } if(target->isMonster()) target->getMonster()->addEnmCrt(player); } target->addEffect("fear", dur, 1, true, player); if(spellData->how == CAST && player->isPlayer()) player->getPlayer()->statistics.offensiveCast(); return(1); } //********************************************************************* // splSilence //********************************************************************* // Silence causes a player or monster to lose their voice, making them // unable to casts spells, use scrolls, speak, yell, or broadcast int splSilence(Creature* player, cmd* cmnd, SpellData* spellData) { Creature* target=0; int bns=0, canCast=0, mpCost=0; long dur=0; if(player->getClass() == BUILDER) { player->print("You cannot cast this spell.\n"); return(0); } if(player->getClass() == LICH || player->getClass() == MAGE || player->getClass() == CLERIC || player->isCt()) canCast = 1; if(!canCast && player->isPlayer() && spellData->how == CAST) { player->print("You are unable to cast that spell.\n"); return(0); } if(player->getClass() == LICH && player->getLevel() < 3 && spellData->how == CAST) { player->print("You are not experienced enough to cast that yet.\n"); return(0); } if(player->getClass() == MAGE || player->getClass() == LICH) mpCost = 35; else mpCost = 20; if(spellData->how == CAST && !player->checkMp(mpCost)) return(0); player->smashInvis(); if(spellData->how == CAST) { dur = mrand(180,300) + 3*bonus((int) player->intelligence.getCur()); player->subMp(mpCost); } else if(spellData->how == SCROLL) dur = mrand(30,120) + bonus((int) player->intelligence.getCur()); else dur = mrand(30,60); if(spell_fail(player, spellData->how)) return(0); // silence on self if(cmnd->num == 2) { target = player; if(player->isEffected("resist-magic")) dur /= 2; if(spellData->how == CAST || spellData->how == SCROLL || spellData->how == WAND) { broadcast(player->getSock(), player->getRoom(), "%M casts silence on %sself.", player, player->himHer()); } else if(spellData->how == POTION) player->print("Your throat goes dry and you cannot speak.\n"); // silence a monster or player } else { if(noPotion(player, spellData)) return(0); target = player->getRoom()->findCreature(player, cmnd->str[2], cmnd->val[2], false); if(!target || target == player) { player->print("That's not here.\n"); return(0); } if(!player->canAttack(target)) return(0); if(player->isPlayer() && target->isMonster() && target->flagIsSet(M_PERMENANT_MONSTER)) { if(!dec_daily(&player->daily[DL_SILENCE]) && !player->isCt()) { player->print("You have done that enough times for today.\n"); return(0); } } bns = ((int)target->getLevel() - (int)spellData->level)*10; if( (target->isPlayer() && target->isEffected("resist-magic")) || (target->isMonster() && target->isEffected("resist-magic")) ) { bns += 50; dur /= 2; } if(target->isPlayer() && player->isCt()) dur = 600L; if(target->isMonster() && target->flagIsSet(M_PERMENANT_MONSTER)) bns = (target->saves[SPL].chance)/3; target->wake("Terrible nightmares disturb your sleep!"); if(target->chkSave(SPL, player, bns) && !player->isCt()) { target->print("%M tried to cast a silence spell on you!\n", player); broadcast(player->getSock(), target->getSock(), player->getRoom(), "%M tried to cast a silence spell on %N!", player, target); player->print("Your spell fizzles.\n"); return(0); } if(player->isPlayer() && target->isPlayer()) { if(!dec_daily(&player->daily[DL_SILENCE]) && !player->isCt()) { player->print("You have done that enough times for today.\n"); return(0); } } if(spellData->how == CAST || spellData->how == SCROLL || spellData->how == WAND) { player->print("Silence casted on %s.\n", target->name); broadcast(player->getSock(), target->getSock(), player->getRoom(), "%M casts a silence spell on %N.", player, target); logCast(player, target, "silence"); target->print("%M casts a silence spell on you.\n", player); } if(target->isMonster()) target->getMonster()->addEnmCrt(player); } target->addEffect("silence", dur, 1, true, player); if(spellData->how == CAST && player->isPlayer()) player->getPlayer()->statistics.offensiveCast(); if(player->isCt() && target->isPlayer()) target->setFlag(P_DM_SILENCED); return(1); } //********************************************************************* // canEnchant //********************************************************************* bool canEnchant(Player* player, SpellData* spellData) { if(!player->isStaff()) { if(spellData->how == CAST && player->getClass() != MAGE && player->getClass() != LICH) { player->print("Only mages may enchant objects.\n"); return(false); } if(spellData->level < 16 && !player->isCt()) { player->print("You are not experienced enough to cast that spell yet.\n"); return(false); } } return(true); } bool canEnchant(Creature* player, Object* object) { if(player->isStaff()) return(true); if( object->flagIsSet(O_CUSTOM_OBJ) || (object->getType() > ARMOR && object->getType() != MISC) || object->flagIsSet(O_NULL_MAGIC) || object->flagIsSet(O_NO_ENCHANT) ) { player->print("That cannot be enchanted.\n"); return(false); } if(object->getAdjustment()) { player->printColor("%O is already enchanted.\n", object); return(false); } return(true); } //********************************************************************* // decEnchant //********************************************************************* bool decEnchant(Player* player, int how) { if(how == CAST) { if(!dec_daily(&player->daily[DL_ENCHA]) && !player->isCt()) { player->print("You have enchanted enough today.\n"); return(false); } } return(true); } //********************************************************************* // splEnchant //********************************************************************* // This function allows mages to enchant items. int splEnchant(Creature* player, cmd* cmnd, SpellData* spellData) { Player* pPlayer = player->getPlayer(); if(!pPlayer) return(0); Object *object=0; int adj=1; if(!canEnchant(pPlayer, spellData)) return(0); if(cmnd->num < 3) { pPlayer->print("Cast the spell on what?\n"); return(0); } object = findObject(pPlayer, pPlayer->first_obj, cmnd, 2); if(!object) { pPlayer->print("You don't have that in your inventory.\n"); return(0); } if(!canEnchant(pPlayer, object)) return(1); if(!decEnchant(pPlayer, spellData->how)) return(0); if((pPlayer->getClass() == MAGE || pPlayer->isStaff()) && spellData->how == CAST) adj = MIN(4, (spellData->level / 5)); object->setAdjustment(MAX(adj, object->getAdjustment())); if(object->getType() == WEAPON) { object->setShotsmax(object->getShotsmax() + adj * 10); object->incShotscur(adj * 10); } object->value.set(500 * adj, GOLD); pPlayer->printColor("%O begins to glow brightly.\n", object); broadcast(pPlayer->getSock(), pPlayer->getRoom(), "%M enchants %1P.", pPlayer, object); if(!pPlayer->isDm()) log_immort(true, pPlayer, "%s enchants a %s^g in room %s.\n", pPlayer->name, object->name, pPlayer->getRoom()->fullName().c_str()); return(1); } //********************************************************************* // cmdEnchant //********************************************************************* // This function enables mages to randomly enchant an item // for a short period of time. int cmdEnchant(Player* player, cmd* cmnd) { Object* object=0; int dur; if(!player->ableToDoCommand()) return(0); if(!player->knowsSkill("enchant")) { player->print("You lack the training to enchant objects.\n"); return(0); } if(player->isBlind()) { player->printColor("^CYou can't do that! You're blind!\n"); return(0); } if(cmnd->num < 2) { player->print("Enchant what?\n"); return(0); } object = findObject(player, player->first_obj, cmnd); if(!object) { player->print("You don't have that item in your inventory.\n"); return(0); } if(!canEnchant(player, object)) return(0); // I do suppose temp enchant sucks enough that we can let it go without daily limits -Bane // if(!dec_daily(&player->daily[DL_ENCHA]) && !player->isCt()) { // player->print("You have enchanted enough today.\n"); // return(0); // } dur = MAX(600, MIN(7200, (int)(player->getSkillLevel("enchant")*100) + (int)bonus((int)player->intelligence.getCur())*100)); object->lasttime[LT_ENCHA].interval = dur; object->lasttime[LT_ENCHA].ltime = time(0); object->randomEnchant((int)player->getSkillLevel("enchant")/2); player->printColor("%O begins to glow brightly.\n", object); broadcast(player->getSock(), player->getRoom(), "%M enchants %1P.", player, object); player->checkImprove("enchant", true); if(!player->isDm()) log_immort(true, player, "%s temp_enchants a %s in room %s.\n", player->name, object->name, player->getRoom()->fullName().c_str()); object->setFlag(O_TEMP_ENCHANT); return(0); } //********************************************************************* // splStun //********************************************************************* int splStun(Creature* player, cmd* cmnd, SpellData* spellData) { Player *pPlayer = player->getPlayer(); Creature* target=0; Monster *mTarget=0; int dur=0, bns=0, mageStunBns=0; if(pPlayer) pPlayer->computeLuck(); // luck for stun if(player->getClass() == LICH && player->getLevel() == 1 && spellData->how == CAST) { player->print("You are not experienced enough to cast that yet.\n"); return(0); } player->smashInvis(); if( player->getClass() == LICH || (pPlayer && pPlayer->getClass() == MAGE && !pPlayer->getSecondClass()) || player->isCt()) mageStunBns = mrand(1,5); // stun self if(cmnd->num == 2) { if(spellData->how == CAST) { dur = bonus((int) player->intelligence.getCur()) * 2 + (((Player*)player)->getLuck() / 10) + mageStunBns; } else dur = dice(2, 6, 0); dur = MAX(5, dur); player->updateAttackTimer(true, dur*10); if(spellData->how == CAST || spellData->how == SCROLL || spellData->how == WAND) { player->print("You're stunned.\n"); broadcast(player->getSock(), player->getRoom(), "%M casts a stun spell on %sself.", player, player->himHer()); } else if(spellData->how == POTION) player->print("You feel dizzy.\n"); // Stun a monster or player } else { if(noPotion(player, spellData)) return(0); target = player->getRoom()->findCreature(player, cmnd, 2); if(!target || target == player) { player->print("That's not here.\n"); return(0); } mTarget = target->getMonster(); if(mTarget) { if(player->flagIsSet(P_LAG_PROTECTION_SET)) player->setFlag(P_LAG_PROTECTION_ACTIVE); } if(!player->canAttack(target)) return(0); if(mTarget) { if(mrand(1,100) < mTarget->getMagicResistance()) { player->printColor("^MYour spell has no effect on %N.\n", mTarget); if(player->isPlayer()) broadcast(player->getSock(), player->getRoom(), "%M's spell has no effect on %N.", player, mTarget); return(0); } } if(mTarget && player->isPlayer()) { if( !mTarget->flagIsSet(M_RESTRICT_EXP_LEVEL) && mTarget->flagIsSet(M_LEVEL_RESTRICTED) && mTarget->getMaxLevel() && !mTarget->flagIsSet(M_AGGRESSIVE) && !mTarget->isEnmCrt(player->name) ) { if( spellData->level > mTarget->getMaxLevel() && !player->checkStaff("You shouldn't be picking on %s.\n", mTarget->himHer()) ) return(0); } } if(spellData->how == CAST) { dur = bonus((int) player->intelligence.getCur()) * 2 + dice(2, 6, 0) + mageStunBns; } else dur = dice(2, 5, 0); if(player->isPlayer() && !mTarget) { dur = ((spellData->level - target->getLevel()) + (bonus((int) player->intelligence.getCur()) - bonus((int) target->intelligence.getCur()))); if(dur < 3) dur = 3; dur += mageStunBns; if(target->isEffected("resist-magic") || target->flagIsSet(P_RESIST_STUN)) dur= 3; } if( target->isEffected("resist-magic") || target->flagIsSet(mTarget ? M_RESIST_STUN_SPELL : P_RESIST_STUN)) { if(spellData->how != CAST) dur = 0; else dur = 3; } else dur = MAX(5, dur); if(mTarget) { if(mTarget->flagIsSet(M_MAGE_LICH_STUN_ONLY) && player->getClass() != MAGE && player->getClass() != LICH && !player->isStaff()) { player->print("Your training in magic is insufficient to properly stun %N!\n", mTarget); if(spellData->how != CAST) dur = 0; else dur = 3; } if( player->isPlayer() && !mTarget->isEffected("resist-magic") && !mTarget->flagIsSet(M_RESIST_STUN_SPELL) && mTarget->flagIsSet(M_LEVEL_BASED_STUN) ) { if(((int)mTarget->getLevel() - (int)spellData->level) > ((player->getClass() == LICH || player->getClass() == MAGE) ? 6:4)) dur = MAX(3, bonus((int) player->intelligence.getCur())); else dur = MAX(5, dur); } if(player->isEffected("reflect-magic") && mTarget->isEffected("reflect-magic")) { player->print("Your stun is cancelled by both your magical-shields!\n"); mTarget->addEnmCrt(player); return(1); } if(mTarget->isEffected("reflect-magic")) { player->print("Your stun is reflected back at you!\n"); broadcast(player->getSock(), mTarget->getSock(), player->getRoom(), "%M's stun is reflected back at %s!", player, player->himHer()); if(mTarget->isDm() && !player->isDm()) dur = 0; player->stun(dur); mTarget->addEnmCrt(player); return(1); } } else { if(player->isEffected("reflect-magic") && target->isEffected("reflect-magic")) { player->print("Your stun is cancelled by both your magical-shields!\n"); target->print("Your magic-shield reflected %N's stun!\n", player); return(1); } if(target->isEffected("reflect-magic")) { player->print("Your stun is reflected back at you!\n"); target->print("%M's stun is reflected back at %s!\n", player, player->himHer()); if(player->flagIsSet(P_RESIST_STUN) || player->isEffected("resist-magic")) dur = 3; broadcast(player->getSock(), target->getSock(), player->getRoom(), "%M's stun is reflected back at %s!", player, player->himHer()); if(target->isDm() && !player->isDm()) dur = 0; player->stun(dur); return(1); } } if(player->isMonster() && !mTarget && target->isEffected("reflect-magic")) { if(player->isEffected("reflect-magic")) { target->print("Your magic-shield reflects %N's stun!\n", player); target->print("%M's magic-shield cancels it!\n", player); return(1); } if(player->flagIsSet(M_RESIST_STUN_SPELL) || player->isEffected("resist-magic")) dur = 3; target->print("%M's stun is reflected back at %s!\n", player, player->himHer()); if(target->isDm() && !player->isDm()) dur = 0; player->stun(dur); return(1); } if(!mTarget && target->flagIsSet(P_BERSERKED)) dur /= 2; if(target->isDm() && !player->isDm()) dur = 0; if(spellData->how == CAST || spellData->how == SCROLL || spellData->how == WAND) { player->print("Stun cast on %s.\n", target->name); broadcast(player->getSock(), target->getSock(), player->getRoom(), "%M casts stun on %N.", player, target); logCast(player, target, "stun"); if(mTarget && player->isPlayer()) { if(mTarget->flagIsSet(M_YELLED_FOR_HELP) && (mrand(1,100) <= (MAX(25, mTarget->parent_rom ? mTarget->parent_rom->wander.getTraffic() : 25)))) { mTarget->summonMobs(player); mTarget->clearFlag(M_YELLED_FOR_HELP); mTarget->setFlag(M_WILL_YELL_FOR_HELP); } if(mTarget->flagIsSet(M_WILL_YELL_FOR_HELP) && !mTarget->flagIsSet(M_YELLED_FOR_HELP)) { check_for_yell(mTarget, player); } if(mTarget->flagIsSet(M_LEVEL_BASED_STUN) && (((int)mTarget->getLevel() - (int)spellData->level) > ((player->getClass() == LICH || player->getClass() == MAGE) ? 6:4))) { player->printColor("^yYour magic is currently too weak to fully stun %N!\n", mTarget); switch(mrand(1,9)) { case 1: player->print("%M laughs wickedly at you.\n", target); break; case 2: player->print("%M shrugs off your weak attack.\n", target); break; case 3: player->print("%M glares menacingly at you.\n",target); break; case 4: player->print("%M grins defiantly at your weak stun magic.\n",target); break; case 5: player->print("What were you thinking?\n"); break; case 6: player->print("Uh oh...you're in trouble now.\n"); break; case 7: player->print("%M says, \"That tickled. Now it's my turn...\"\n",target); break; case 8: player->print("I hope you're prepared to meet your destiny.\n"); break; case 9: player->print("Your stun just seemed to bounce off. Strange....\n"); break; default: break; } } } player->wake("You awaken suddenly!"); target->print("%M stunned you.\n", player); if((!(mTarget && mTarget->flagIsSet(M_RESIST_STUN_SPELL)) && (spellData->level <= target->getLevel()) && !target->isCt()) ) { if(mTarget && mTarget->flagIsSet(M_PERMENANT_MONSTER)) bns = 10; if(!mTarget && target->getClass() == CLERIC && target->getDeity() == ARES) bns += 25; if(target->chkSave(SPL, player, bns)) { player->printColor("^y%M avoided the full power of your stun!\n", target); if(target->isPlayer()) broadcast(player->getSock(), player->getRoom(), "%M avoided a full stun.", target); dur /= 2; dur = MIN(5,dur); target->print("You avoided a full stun.\n"); } } target->stun(dur); } if(mTarget) mTarget->addEnmCrt(player); } return(1); } //********************************************************************* // splGlobeOfSilence //********************************************************************* int splGlobeOfSilence(Creature* player, cmd* cmnd, SpellData* spellData) { int strength = 1; long duration = 600; if(noPotion(player, spellData)) return(0); if(player->getRoom()->flagIsSet(R_SAFE_ROOM) && !player->isCt()) { player->print("That spell is not allowed here.\n"); return(0); } player->print("You cast a globe of silence spell.\n"); broadcast(player->getSock(), player->getRoom(), "%M casts a globe of silence spell.", player); if(player->getRoom()->hasPermEffect("globe-of-silence")) { player->print("The spell didn't take hold.\n"); return(0); } if(spellData->how == CAST) { if(player->getRoom()->magicBonus()) player->print("The room's magical properties increase the power of your spell.\n"); } player->getRoom()->addEffect("globe-of-silence", duration, strength, true, player); return(1); }