/* * MAGIC3.C: * * Additional spell-casting routines. * * Copyright (C) 1991, 1992, 1993 Brett J. Vickers * */ #include "mstruct.h" #include "mextern.h" #ifdef DMALLOC #include "/usr/local/include/dmalloc.h" #endif /**********************************************************************/ /* bless */ /**********************************************************************/ /* This function allows a player to cast a bless spell on himself or */ /* on another player, reducing the target's thaco by 1. */ int bless(ply_ptr, cmnd, how) creature *ply_ptr; cmd *cmnd; int how; { creature *crt_ptr; room *rom_ptr; long t; int fd; fd = ply_ptr->fd; rom_ptr = ply_ptr->parent_rom; t = time(0); if(ply_ptr->mpcur < 10 && how == CAST) { print(fd, "Not enough magic points.\n"); return(0); } if(!S_ISSET(ply_ptr, SBLESS) && how == CAST) { print(fd, "You don't know that spell.\n"); return(0); } if(ply_ptr->class != CLERIC && ply_ptr->class != PALADIN && spell_fail(ply_ptr, how)) { if(how==CAST) ply_ptr->mpcur -= 10; return(0); } /* Cast bless on self */ if(cmnd->num == 2) { F_SET(ply_ptr, PBLESS); compute_thaco(ply_ptr); ply_ptr->lasttime[LT_BLESS].ltime = t; if(how == CAST) { ply_ptr->lasttime[LT_BLESS].interval = MAX(300, 1200 + bonus[ply_ptr->intelligence]*600); if(ply_ptr->class == CLERIC || ply_ptr->class == PALADIN) ply_ptr->lasttime[LT_BLESS].interval += 60*ply_ptr->level; ply_ptr->mpcur -= 10; if (F_ISSET(ply_ptr->parent_rom,RPMEXT)){ print(fd,"The room's magical properties increase the power of your spell.\n"); ply_ptr->lasttime[LT_BLESS].interval += 800L; } } else ply_ptr->lasttime[LT_BLESS].interval = 1200; if(how == CAST || how == SCROLL || how == WAND) { print(fd,"Bless spell cast.\nYou feel holy.\n"); broadcast_rom(fd, ply_ptr->rom_num, "%M casts a bless spell on %sself.", ply_ptr, F_ISSET(ply_ptr, PMALES) ? "him":"her"); } else if(how == POTION) print(fd, "You feel holy.\n"); return(1); } /* Cast bless on another player */ else { if(how == POTION) { print(fd, "You can only use a potion on yourself.\n"); return(0); } cmnd->str[2][0] = up(cmnd->str[2][0]); crt_ptr = find_crt(ply_ptr, rom_ptr->first_ply, cmnd->str[2], cmnd->val[2]); if(!crt_ptr) { print(fd, "That player is not here.\n"); return(0); } F_SET(crt_ptr, PBLESS); compute_thaco(crt_ptr); crt_ptr->lasttime[LT_BLESS].ltime = t; if(how == CAST) { crt_ptr->lasttime[LT_BLESS].interval = MAX(300, 1200 + bonus[ply_ptr->intelligence]*600); if(ply_ptr->class == CLERIC || ply_ptr->class == PALADIN) crt_ptr->lasttime[LT_BLESS].interval += 60*ply_ptr->level; ply_ptr->mpcur -= 10; if (F_ISSET(ply_ptr->parent_rom,RPMEXT)){ print(fd,"The room's magical properties increase the power of your spell.\n"); crt_ptr->lasttime[LT_BLESS].interval += 800L; } } else crt_ptr->lasttime[LT_BLESS].interval = 1200; if(how == CAST || how == SCROLL || how == WAND) { print(fd, "Bless cast on %s.\n", crt_ptr->name); print(crt_ptr->fd, "%M casts a bless spell on you.\n%s", ply_ptr, "You feel holy.\n"); broadcast_rom2(fd, crt_ptr->fd, ply_ptr->rom_num, "%M casts a bless spell on %m.", ply_ptr, crt_ptr); return(1); } } return(1); } /**********************************************************************/ /* turn */ /**********************************************************************/ /* This function allows clerics and paladins to turn undead creatures. */ /* If they succeed then the creature is either disintegrated or harmed */ /* for approximately half of its hit points. */ int turn(ply_ptr, cmnd) creature *ply_ptr; cmd *cmnd; { creature *crt_ptr; room *rom_ptr; long i, t; int chance, m, dmg, fd; fd = ply_ptr->fd; rom_ptr = ply_ptr->parent_rom; if(cmnd->num < 2) { print(fd, "Turn whom?\n"); return(0); } if(ply_ptr->class != CLERIC && ply_ptr->class != PALADIN && ply_ptr->class < CARETAKER) { print(fd, "Only clerics and paladins may turn undead.\n"); return(0); } crt_ptr = find_crt(ply_ptr, rom_ptr->first_mon, cmnd->str[1], cmnd->val[1]); if(!crt_ptr) { print(fd, "That isn't here.\n"); return(0); } if(!F_ISSET(crt_ptr, MUNDED)) { print(fd, "You may only turn undead monsters.\n"); return(0); } if(F_ISSET(ply_ptr, PINVIS)) { F_CLR(ply_ptr, PINVIS); print(fd, "Your invisibility fades.\n"); broadcast_rom(fd, ply_ptr->rom_num, "%M fades into view.", ply_ptr); } i = LT(ply_ptr, LT_TURNS); t = time(0); if(i > t) { please_wait(fd, i-t); return(0); } if(crt_ptr->type != PLAYER && F_ISSET(crt_ptr, MUNKIL)) { print(fd, "You cannot harm %s.\n", F_ISSET(crt_ptr, MMALES) ? "him":"her"); return(0); } add_enm_crt(ply_ptr->name, crt_ptr); ply_ptr->lasttime[LT_TURNS].ltime = t; ply_ptr->lasttime[LT_ATTCK].ltime = t; ply_ptr->lasttime[LT_TURNS].interval = 30L; chance = (ply_ptr->level - crt_ptr->level)*20 + bonus[ply_ptr->piety]*5 + (ply_ptr->class == PALADIN ? 15:25); chance = MIN(chance, 80); if(mrand(1,100) > chance) { print(fd, "You failed to turn %m.\n", crt_ptr); broadcast_rom(fd, ply_ptr->rom_num, "%M failed to turn %m.", ply_ptr, crt_ptr); return(0); } if(mrand(1,100) > 90 - bonus[ply_ptr->piety]) { print(fd, "You disintegrated %m.\n", crt_ptr); broadcast_rom(fd, ply_ptr->rom_num, "%M disintegrated %m.", ply_ptr, crt_ptr); add_enm_dmg(ply_ptr->name, crt_ptr, crt_ptr->hpcur); die(crt_ptr, ply_ptr); } else { dmg = MAX(1, crt_ptr->hpcur / 2); m = MIN(crt_ptr->hpcur, dmg); crt_ptr->hpcur -= dmg; add_enm_dmg(ply_ptr->name, crt_ptr, m); print(fd, "You turned %m for %d damage.\n", crt_ptr, dmg); broadcast_rom(fd, ply_ptr->rom_num, "%M turned %m.", ply_ptr, crt_ptr); if(crt_ptr->hpcur < 1) { print(fd, "You killed %m.\n", crt_ptr); broadcast_rom(fd, ply_ptr->rom_num, "%M killed %m.", ply_ptr, crt_ptr); die(crt_ptr, ply_ptr); } } return(0); } /**********************************************************************/ /* invisibility */ /**********************************************************************/ /* This function allows a player to cast an invisibility spell on himself */ /* or on another player. */ int invisibility(ply_ptr, cmnd, how) creature *ply_ptr; cmd *cmnd; int how; { creature *crt_ptr; room *rom_ptr; ctag *cp; long t; int fd; fd = ply_ptr->fd; rom_ptr = ply_ptr->parent_rom; t = time(0); if(ply_ptr->mpcur < 15 && how == CAST) { print(fd, "Not enough magic points.\n"); return(0); } if(!S_ISSET(ply_ptr, SINVIS) && how == CAST) { print(fd, "You don't know that spell.\n"); return(0); } if(spell_fail(ply_ptr, how)) { if(how==CAST) ply_ptr->mpcur -= 15; return(0); } cp = rom_ptr->first_mon; while(cp) { if(is_enm_crt(ply_ptr->name, cp->crt)) { print(fd, "Not in the middle of combat.\n"); return(0); } cp = cp->next_tag; } /* Cast invisibility on self */ if(cmnd->num == 2) { ply_ptr->lasttime[LT_INVIS].ltime = t; if(how == CAST) { ply_ptr->lasttime[LT_INVIS].interval = 1200 + bonus[ply_ptr->intelligence]*600; if(ply_ptr->class == MAGE) ply_ptr->lasttime[LT_INVIS].interval += 60*ply_ptr->level; ply_ptr->mpcur -= 15; if (F_ISSET(ply_ptr->parent_rom,RPMEXT)){ print(fd,"The room's magical properties increase the power of your spell.\n"); ply_ptr->lasttime[LT_INVIS].interval += 600L; } } else ply_ptr->lasttime[LT_INVIS].interval = 1200; if(how == CAST || how == SCROLL || how == WAND) { print(fd,"Invisibility spell cast.\n"); broadcast_rom(fd, ply_ptr->rom_num, "%s cast invisibility on %sself.", ply_ptr->name, F_ISSET(ply_ptr, PMALES) ? "him":"her"); } else if(how == POTION) print(fd, "You turn invisible.\n"); F_SET(ply_ptr, PINVIS); return(1); } /* Cast invisibility on another player */ else { if(how == POTION) { print(fd, "You can only use a potion on yourself.\n"); return(0); } cmnd->str[2][0] = up(cmnd->str[2][0]); crt_ptr = find_crt(ply_ptr, rom_ptr->first_ply, cmnd->str[2], cmnd->val[2]); if(!crt_ptr) { print(fd, "That player is not here.\n"); return(0); } crt_ptr->lasttime[LT_INVIS].ltime = t; if(how == CAST) { crt_ptr->lasttime[LT_INVIS].interval = 1200 + bonus[ply_ptr->intelligence]*600; if(ply_ptr->class == MAGE) crt_ptr->lasttime[LT_INVIS].interval += 60*ply_ptr->level; ply_ptr->mpcur -= 15; if (F_ISSET(ply_ptr->parent_rom,RPMEXT)){ print(fd,"The room's magical properties increase the power of your spell.\n"); crt_ptr->lasttime[LT_INVIS].interval += 600L; } } else crt_ptr->lasttime[LT_INVIS].interval = 1200; if(how == CAST || how == SCROLL || how == WAND) { print(fd, "Invisibility cast on %m.\n", crt_ptr); print(crt_ptr->fd, "%M casts an invisibility spell on you.\n", ply_ptr); broadcast_rom2(fd, crt_ptr->fd, ply_ptr->rom_num, "%M casts an invisibility spell on %m.", ply_ptr, crt_ptr); F_SET(crt_ptr, PINVIS); return(1); } } return(1); } /**********************************************************************/ /* restore */ /**********************************************************************/ /* This function allows a player to cast the restore spell using either */ /* a potion or a wand. Restore should not be a cast-able spell because */ /* it can restore magic points to full. */ int restore(ply_ptr, cmnd, how) creature *ply_ptr; cmd *cmnd; int how; { creature *crt_ptr; room *rom_ptr; int fd; fd = ply_ptr->fd; rom_ptr = ply_ptr->parent_rom; if(how == CAST && ply_ptr->class < CARETAKER) { print(fd, "You may not cast that spell.\n"); return(0); } /* Cast restore on self */ if(cmnd->num == 2) { ply_ptr->hpcur += dice(2,10,0); ply_ptr->hpcur = MIN(ply_ptr->hpcur, ply_ptr->hpmax); if(mrand(1,100) < 34) ply_ptr->mpcur = ply_ptr->mpmax; if(how == CAST || how == WAND) { print(fd, "Restore spell cast.\n"); broadcast_rom(fd, ply_ptr->rom_num, "%M casts restore on %sself.", ply_ptr, F_ISSET(ply_ptr, PMALES) ? "him":"her"); } else if(how == POTION) print(fd, "You feel restored.\n"); return(1); } /* Cast restore on another player */ else { if(how == POTION) { print(fd, "You can only use a potion on yourself.\n"); return(0); } cmnd->str[2][0] = up(cmnd->str[2][0]); crt_ptr = find_crt(ply_ptr, rom_ptr->first_ply, cmnd->str[2], cmnd->val[2]); if(!crt_ptr) { print(fd, "That player is not here.\n"); return(0); } crt_ptr->hpcur += dice(2,10,0); crt_ptr->hpcur = MIN(crt_ptr->hpcur, crt_ptr->hpmax); if(mrand(1,100) < 34) crt_ptr->mpcur = crt_ptr->mpmax; if(how == CAST || how == WAND) { print(fd, "Restore spell cast on %m.\n", crt_ptr); print(crt_ptr->fd, "%M casts a restore spell on you.\n", ply_ptr); broadcast_rom2(fd, crt_ptr->fd, ply_ptr->rom_num, "%M casts a restore spell on %m.", ply_ptr, crt_ptr); return(1); } } return(1); } /**********************************************************************/ /* befuddle */ /**********************************************************************/ int befuddle(ply_ptr, cmnd, how) creature *ply_ptr; cmd *cmnd; int how; { creature *crt_ptr; room *rom_ptr; int fd, dur; fd = ply_ptr->fd; rom_ptr = ply_ptr->parent_rom; luck(ply_ptr); /* luck for stun */ if(ply_ptr->mpcur < 10 && how == CAST) { print(fd, "Not enough magic points.\n"); return(0); } if(!S_ISSET(ply_ptr, SBEFUD) && how == CAST) { print(fd, "You don't know that spell.\n"); return(0); } if(F_ISSET(ply_ptr, PINVIS)) { F_CLR(ply_ptr, PINVIS); print(fd, "Your invisibility fades.\n"); broadcast_rom(fd, ply_ptr->rom_num, "%M fades into view.", ply_ptr); } if(spell_fail(ply_ptr, how)) { if(how==CAST) ply_ptr->mpcur -= 10; return(0); } /* Befuddle self */ if(cmnd->num == 2) { if(how == CAST) { dur = bonus[ply_ptr->intelligence]*2 + (Ply[fd].extr->luck/10) + (ply_ptr->class == MAGE ? ply_ptr->level/3 : 0); ply_ptr->mpcur -= 10; } else dur = dice(2,6,0); dur = MAX(5, dur); ply_ptr->lasttime[LT_ATTCK].ltime = time(0); ply_ptr->lasttime[LT_ATTCK].interval = dur; if(how == CAST || how == SCROLL || how == WAND) { print(fd, "You're stunned.\n"); broadcast_rom(fd, ply_ptr->rom_num, "%M casts a stun spell on %sself.", ply_ptr, F_ISSET(ply_ptr, PMALES) ? "him":"her"); } else if(how == POTION) print(fd, "You feel dizzy.\n"); } /* Befuddle a monster or player */ else { if(how == POTION) { print(fd, "You can only use a potion on yourself.\n"); return(0); } crt_ptr = find_crt(ply_ptr, rom_ptr->first_mon, cmnd->str[2], cmnd->val[2]); if(!crt_ptr) { cmnd->str[2][0] = up(cmnd->str[2][0]); crt_ptr = find_crt(ply_ptr, rom_ptr->first_ply, cmnd->str[2], cmnd->val[2]); if(!crt_ptr || crt_ptr == ply_ptr || strlen(cmnd->str[2]) < 3) { print(fd, "That's not here.\n"); return(0); } } if(crt_ptr->type != PLAYER && F_ISSET(crt_ptr, MUNKIL)) { print(fd, "You cannot harm %s.\n", F_ISSET(crt_ptr, MMALES) ? "him":"her"); return(0); } if(crt_ptr->type == PLAYER && ply_ptr->type == PLAYER) { if(!F_ISSET(ply_ptr, PCHAOS) && ply_ptr->class < DM) { print(fd, "Sorry, you're lawful.\n"); return(0); } if(!F_ISSET(crt_ptr, PCHAOS) && ply_ptr->class < DM) { print(fd, "Sorry, that player is lawful.\n"); return(0); } } if(how == CAST) { dur = bonus[ply_ptr->intelligence]*2 + dice(2,6,0); ply_ptr->mpcur -= 10; } else dur = dice(2,5,0); if((crt_ptr->type == PLAYER && F_ISSET(crt_ptr, PRMAGI)) || (crt_ptr->type != PLAYER && (F_ISSET(crt_ptr, MRMAGI) || F_ISSET(crt_ptr, MRBEFD)))) dur = 3; else dur = MAX(5, dur); crt_ptr->lasttime[LT_ATTCK].ltime = time(0); crt_ptr->lasttime[LT_ATTCK].interval = dur; crt_ptr->lasttime[LT_SPELL].ltime = time(0); dur = MIN(10, dur); crt_ptr->lasttime[LT_SPELL].interval = dur; if(how == CAST || how == SCROLL || how == WAND) { print(fd, "Stun cast on %s.\n", crt_ptr->name); broadcast_rom2(fd, crt_ptr->fd, ply_ptr->rom_num, "%M casts stun on %m.", ply_ptr, crt_ptr); print(crt_ptr->fd, "%M stunned you.\n", ply_ptr); } if(crt_ptr->type != PLAYER) add_enm_crt(ply_ptr->name, crt_ptr); } return(1); }