/* ************************************************************************ * file: mobact.c , Mobile action module. Part of DIKUMUD * * Usage: Procedures generating 'intelligent' behavior in the mobiles. * * Copyright (C) 1990, 1991 - see 'license.doc' for complete information. * ************************************************************************* */ #include <stdio.h> #include "utils.h" #include "structs.h" #include "db.h" #include "comm.h" #include "spells.h" extern struct char_data *character_list; extern struct index_data *mob_index; extern struct room_data *world; extern struct zone_data *zone_table; extern struct str_app_type str_app[]; void do_kick(struct char_data *ch, char *argument, int cmd); void do_bash(struct char_data *ch, char *argument, int cmd); void cast_charm_person(byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_fire_breath( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_frost_breath( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_acid_breath( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_gas_breath( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_lightning_breath( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_sleep( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_colour_spray( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_blindness( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_burning_hands( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_call_lightning( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_chill_touch( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_shocking_grsp( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_colour_spray( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_earthquake( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_energy_drain( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_fireball( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_harm( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_lightning_bolt( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_magic_missile( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_armor( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_bless( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_blindness( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_cure_blind( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_cure_critic( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_cure_light( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_curse( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_heal( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_poison( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_remove_curse( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_remove_poison( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_sanctuary( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_sleep( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_strength( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_dispel_evil( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void cast_shocking_grasp( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); void hit(struct char_data *ch, struct char_data *victim, int type); int niceness(struct char_data *ch) { struct char_data *tmp_ch; int count=0; int lv=0; int base; for(tmp_ch = world[ch->in_room].people; tmp_ch; tmp_ch = tmp_ch->next_in_room){ if(!IS_NPC(tmp_ch)){ lv += tmp_ch->player.level; count++; } } /* base is random (2..4) to start. * The base is modified on the number of people appearing * in the room: * 1 == person : +1 * 3 <= person : +0 * 5 <= person : -1 * Also by the average level of the people in the room: * 5 <= lv : +2 * 10 <= lv : +1 * 15 <= lv : +0 * 20 <= lv : -1 * 25 <= lv : -2 * -- Swiftest */ if(!count) count=1; base=number(2,4); switch(count){ case 1: case 2: base++; break; case 3: case 4: /* no modifier */ break; default: base--; break; } switch(lv/count){ case 1: case 2: case 3: case 4: case 5: base += 2; break; case 6: case 7: case 8: case 9: case 10: --base; break; case 11: case 12: case 13: case 14: case 15: /* no modifier */ break; case 16: case 17: case 18: case 19: case 20: --base; break; default: base -= 2; break; } return(base); } void mobile_activity(void) { register struct char_data *ch; struct char_data *tmp_ch, *vict, *t_vict; struct obj_data *obj, *best_obj, *worst_obj; int door, found, max, min; char buf[100]; MEMtMemoryRec *names; /* Added Player data to call for commands -Sman */ void (*funct_ptr)( byte level, struct char_data *ch, char *arg, int type, struct char_data *tar_ch, struct obj_data *tar_obj ); extern int no_specials; void do_move(struct char_data *ch, char *argument, int cmd); void do_get(struct char_data *ch, char *argument, int cmd); int chance; for (ch = character_list; ch; ch = ch->next) if (IS_MOB(ch)) { /* For delaying mobs with bash, etc */ if(ch->specials.timer) { ch->specials.timer--; continue; } /* Examine call for special procedure */ if (IS_SET(ch->specials.act, ACT_SPEC) && !no_specials) { if (!mob_index[ch->nr].func) { sprintf(buf,"%s %d",ch->player.name, (int)ch->nr); log(buf); log("Attempting to call a non-existing MOB func. (mobact.c)"); REMOVE_BIT(ch->specials.act, ACT_SPEC); } else { if ((*mob_index[ch->nr].func) (ch, 0, 0, "")) continue; } } if (AWAKE(ch) && !(ch->specials.fighting)) { if (IS_SET(ch->specials.act, ACT_SCAVENGER)) { if (world[ch->in_room].contents && !number(0,10)) { for (max = 1, best_obj = 0, obj = world[ch->in_room].contents; obj; obj = obj->next_content) { if (CAN_GET_OBJ(ch, obj)) { if (obj->obj_flags.cost > max) { best_obj = obj; max = obj->obj_flags.cost; } } } /* for */ if (best_obj) { obj_from_room(best_obj); obj_to_char(best_obj, ch); act("$n gets $p.",FALSE,ch,best_obj,0,TO_ROOM); } } } /* Scavenger */ /* Here is a contender for game's ugliest if */ if ((!IS_SET(ch->specials.act, ACT_SENTINEL)|| (IS_SET(ch->specials.act,ACT_AGGRESSIVE) && IS_SET(world[ch->in_room].room_flags,SAFE) && GET_HIT(ch) > GET_MAX_HIT(ch)/2)) && (GET_POS(ch) >= POSITION_STANDING) && ((door=number(0,45))<=5) && CAN_GO(ch,door)&& !IS_SET(world[EXIT(ch, door)->to_room].room_flags, NO_MOB) && !IS_SET(world[EXIT(ch, door)->to_room].room_flags, DEATH)) { if (ch->specials.last_direction == door) { ch->specials.last_direction = -1; } else { if (!IS_SET(ch->specials.act, ACT_STAY_ZONE)) { ch->specials.last_direction = door; do_move(ch, "", ++door); } else { if (world[EXIT(ch, door)->to_room].zone == world[ch->in_room].zone) { ch->specials.last_direction = door; do_move(ch, "", ++door); } } } } /* if can go */ if (IS_SET(ch->specials.act,ACT_AGGRESSIVE)) { found = FALSE; for (tmp_ch = world[ch->in_room].people; tmp_ch && !found; tmp_ch = tmp_ch->next_in_room) { if (!IS_NPC(tmp_ch) && CAN_SEE(ch, tmp_ch) && !IS_TRUSTED(tmp_ch) && !IS_AFFECTED(tmp_ch,AFF_HIDE)) { if (!IS_SET(ch->specials.act, ACT_WIMPY) || !AWAKE(tmp_ch)) { if ((IS_SET(ch->specials.act, ACT_AGGRESSIVE_EVIL) && IS_EVIL(tmp_ch)) || (IS_SET(ch->specials.act, ACT_AGGRESSIVE_GOOD) && IS_GOOD(tmp_ch)) || (IS_SET(ch->specials.act, ACT_AGGRESSIVE_NEUTRAL) && IS_NEUTRAL(tmp_ch)) || (!IS_SET(ch->specials.act, ACT_AGGRESSIVE_EVIL) && !IS_SET(ch->specials.act, ACT_AGGRESSIVE_NEUTRAL) && !IS_SET(ch->specials.act, ACT_AGGRESSIVE_GOOD) ) && !(IS_EVIL(ch)&&IS_AFFECTED(tmp_ch,AFF_PROTECT_EVIL)&&GET_LEVEL(ch)<GET_LEVEL(tmp_ch)) ) { if(world[ch->in_room].room_flags & SAFE) { if(GET_HIT(ch)>GET_MAX_HIT(ch)*3/4) do_action(ch,"",31); } else { /* hit(ch, tmp_ch, 0);*/ /* Changed so that specs */ /* get called (witness) */ sprintf(buf,"hit %s", GET_NAME(tmp_ch)); command_interpreter(ch,buf); found = TRUE; } } } } } } if (IS_SET(ch->specials.act, ACT_MEMORY)) { found = FALSE; for (tmp_ch = world[ch->in_room].people; tmp_ch != NULL && !found; tmp_ch = tmp_ch->next_in_room) { for (names = ch->specials.memory; names != NULL && !found; names = names->next) { if ((str_cmp(names->name, tmp_ch->player.name) == 0) && CAN_SEE(ch,tmp_ch) && ch!=tmp_ch) { found = TRUE; vict = tmp_ch; } } } if (found) { if(world[ch->in_room].room_flags & SAFE) { if(!number(0,6)) { if(GET_HIT(ch)>GET_MAX_HIT(ch)*3/4) act("\"Hey! I know you, you jerk! Care to step outside?\", exclaims the $n.",TRUE,ch,0,0,TO_ROOM); else if(GET_HIT(ch)<GET_MAX_HIT(ch)/2) do_say(ch,"Just wait until I heal up, buster!",0); } } else { act("\"Hey! You're the fiend that attacked me!!!!!\", exclaims the $n.", TRUE, ch, 0, 0, TO_ROOM); hit(ch, vict, 0); } } } } /* awake && not fighting */ if (IS_SET(ch->specials.act, ACT_ISHUMANOID) && IS_FIGHTING(ch)){ switch(GET_LEVEL(ch)){ case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: case 32: default: if(IS_GOOD(ch)) do_say(ch,"Make peace, not war!",0); } } /* ISHUMANOID */ if (IS_SET(ch->specials.act, ACT_ISDRAGON) && IS_FIGHTING(ch)){ chance = niceness(ch); vict=ch->specials.fighting; if(ch->in_room!=vict->in_room) return; if (IS_AFFECTED(ch, AFF_BLIND) && GET_LEVEL(ch)>5){ act("$n says, 'Cure blindness!'", 1, ch, 0, 0, TO_ROOM); cast_cure_blind(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0); } else if(number(0,chance+1)==0){ act("$n says, 'Sleep!'", 1, ch, 0, 0, TO_ROOM); for(t_vict=world[ch->in_room].people; t_vict; t_vict=t_vict->next_in_room){ if(!IS_NPC(t_vict) && CAN_SEE(ch, t_vict) && number(0,(31-GET_LEVEL(ch))/5)==0){ cast_sleep(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, t_vict, 0); } } } else if (vict && CAN_SEE(ch,vict) && number(0,chance)==0){ act("$n says, 'Blindness!'", 1, ch, 0, 0, TO_ROOM); cast_blindness(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0); } funct_ptr=0; if(CAN_SEE(ch, vict) && number(0,9)==0){ act("$n breathes fire!", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_fire_breath; } else if(CAN_SEE(ch, vict) && number(0,7)==0){ act("$n breathes frost!", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_frost_breath; } else if(CAN_SEE(ch, vict) && number(0,5)==0){ act("$n breathes acid!", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_acid_breath; } else if(CAN_SEE(ch, vict) && number(0,3)==0){ act("$n breathes gas!", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_gas_breath; } else if(CAN_SEE(ch, vict) && number(0,2)==0){ act("$n breathes lightning!", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_lightning_breath; } if(funct_ptr){ if(vict) funct_ptr(GET_LEVEL(ch),ch, "", SPELL_TYPE_SPELL, vict, 0); for(t_vict=world[ch->in_room].people; t_vict; t_vict= t_vict->next_in_room){ if(!IS_NPC(t_vict) && CAN_SEE(ch, t_vict) && number(0,(31-GET_LEVEL(ch))/5)==0 && t_vict != vict){ funct_ptr(GET_LEVEL(ch),ch, "", SPELL_TYPE_SPELL, t_vict, 0); } } } } /* ISDRAGON */ if (IS_SET(ch->specials.act, ACT_ISDEMON) && IS_FIGHTING(ch)){ if(ch->specials.fighting->in_room!=ch->in_room) return; vict=ch->specials.fighting; chance=niceness(ch); if(!CAN_SEE(ch, vict) && IS_AFFECTED(ch, AFF_BLIND)){ act("$n says, 'Cure blindness!'", 1, ch, 0, 0, TO_ROOM); cast_cure_blind(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } else if(CAN_SEE(ch, vict) && number(0,chance)==0 && GET_HIT(ch)<100 && GET_LEVEL(ch)>=14){ act("$n says, 'Heal!'", 1, ch, 0, 0, TO_ROOM); cast_heal(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } else if(CAN_SEE(ch, vict) && number(0,chance)==0 && GET_HIT(ch)<75 && GET_LEVEL(ch)>=9){ act("$n says, 'Cure critical!'", 1, ch, 0, 0, TO_ROOM); cast_cure_critic(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } else if(CAN_SEE(ch, vict) && number(0,chance)==0 && GET_HIT(ch)<50){ act("$n says, 'Cure light wounds!'", 1, ch, 0, 0, TO_ROOM); cast_cure_light(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } else if(CAN_SEE(ch, vict) && !IS_AFFECTED(ch,AFF_SANCTUARY)&& GET_LEVEL(ch)>=13 && number(0,chance)==0){ act("$n says, 'Sanctuary!'", 1, ch, 0, 0, TO_ROOM); cast_sanctuary(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } funct_ptr=0; if(GET_LEVEL(ch)>10 && number(0,chance-1)==0){ act("$n breathes lightning!", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_lightning_breath; } else if(GET_LEVEL(ch)>15 && number(0,chance-2)==0){ act("$n breathes gas!", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_gas_breath; } if(funct_ptr){ if(vict) funct_ptr(GET_LEVEL(ch),ch, "", SPELL_TYPE_SPELL, vict, 0); for(t_vict=world[ch->in_room].people; t_vict; t_vict= t_vict->next_in_room){ if(!IS_NPC(t_vict) && CAN_SEE(ch, t_vict) && number(0,(31-GET_LEVEL(ch))/6)==0 && vict != t_vict){ funct_ptr(GET_LEVEL(ch),ch, "", SPELL_TYPE_SPELL, t_vict, 0); } } } switch(GET_LEVEL(ch)){ case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: default: if(number(0,7)==0){ act("$n says, 'My minions will destroy your kind!'", 1, ch, 0, 0, TO_ROOM); } else if(number(0,6)==0){ act("$n says, 'You will soon die!'", 1, ch, 0, 0, TO_ROOM); } else if(number(0,5)==0){ act("$n says, 'You are but a speck of sand to my power!'", 1, ch, 0, 0, TO_ROOM); } else if(number(0,4)==0){ act("$n says, 'Pray that I kill you mercifully!'", 1, ch, 0, 0, TO_ROOM); } } } /* ISDEMON */ if (IS_SET(ch->specials.act, ACT_ISANIMAL) && IS_FIGHTING(ch)){ switch(GET_LEVEL(ch)){ case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: default: act("$n growls!", 1, ch, 0, 0, TO_ROOM); } } /* ISANIMAL */ if (IS_SET(ch->specials.act, ACT_ISINSECT) && IS_FIGHTING(ch)){ switch(GET_LEVEL(ch)){ case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: default: } } /* ISINSECT */ if (IS_SET(ch->specials.act, ACT_CANFLY) && IS_FIGHTING(ch)){ switch(GET_LEVEL(ch)){ case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: case 32: default: } } /* CANFLY */ if (IS_SET(ch->specials.act, ACT_CANSWIM) && IS_FIGHTING(ch)){ switch(GET_LEVEL(ch)){ case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: default: } } /* CANSWIM */ if (IS_SET(ch->specials.act, ACT_HAS_CL) && IS_FIGHTING(ch)){ vict=ch->specials.fighting; if(vict->in_room!=ch->in_room) return; chance=niceness(ch); if(!CAN_SEE(ch, vict) && GET_LEVEL(ch)>=4 && IS_AFFECTED(ch, AFF_BLIND)){ act("$n says, 'Cure blindness!'", 1, ch, 0, 0, TO_ROOM); cast_cure_blind(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } else if(CAN_SEE(ch, vict) && GET_LEVEL(ch)>=12 && IS_AFFECTED(ch, AFF_CURSE)){ act("$n says, 'Remove curse!'", 1, ch, 0, 0, TO_ROOM); cast_remove_curse(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } else if(CAN_SEE(ch, vict) && GET_LEVEL(ch)>=9 && IS_AFFECTED(ch, AFF_POISON)){ act("$n says, 'Remove poison!'", 1, ch, 0, 0, TO_ROOM); cast_remove_poison(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } else if(CAN_SEE(ch, vict) && GET_LEVEL(ch)>=13 && !IS_AFFECTED(ch, AFF_SANCTUARY) && number(0,chance)==0){ act("$n says, 'Sanctuary!'", 1, ch, 0, 0, TO_ROOM); cast_sanctuary(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } else if(CAN_SEE(ch, vict) && GET_LEVEL(ch)>=14 && GET_HIT(ch)<70 && number(0,chance)==0){ act("$n says, 'Heal!'", 1, ch, 0, 0, TO_ROOM); cast_heal(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } else if(CAN_SEE(ch, vict) && GET_LEVEL(ch)>=9 && GET_HIT(ch)<60 && number(0,chance)==0){ act("$n says, 'Cure critical wounds!'", 1, ch, 0, 0, TO_ROOM); cast_cure_critic(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } else if(CAN_SEE(ch, vict) && GET_HIT(ch)<50 && number(0,chance)==0){ act("$n says, 'Cure light wounds!'", 1, ch, 0, 0, TO_ROOM); cast_cure_light(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } else if(number(0,chance)==0){ act("$n says, 'Armor!'", 1, ch, 0, 0, TO_ROOM); cast_armor(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } funct_ptr=0; switch(GET_LEVEL(ch)){ case 1: case 2: case 3: case 4: case 5: case 6: if(CAN_SEE(ch, vict) && number(0,chance)==0 && !IS_AFFECTED(vict, AFF_POISON)){ act("$n says, 'Poison!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_poison; } else if(CAN_SEE(ch, vict) && number(0,chance)==0) { act("$n says, 'Blindness!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_blindness; } break; case 7: case 8: case 9: case 10: case 11: if(CAN_SEE(ch, vict) && number(0,chance)==0) { act("$n says, 'Quake!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_earthquake; } else if(CAN_SEE(ch, vict) && IS_GOOD(ch) && IS_EVIL(vict) && number(0,chance)==0) { act("$n says, 'Dispel evil!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_dispel_evil; } break; case 12: case 13: case 14: case 15: if(CAN_SEE(ch, vict) && !IS_EVIL(ch) && IS_EVIL(vict) && number(0,chance)==0){ act("$n says, 'Dispel evil!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_dispel_evil; } else if(CAN_SEE(ch, vict) && number(0,chance)==0) { act("$n says, 'Quake!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_earthquake; } break; case 16: case 17: case 18: case 19: case 20: if(CAN_SEE(ch, vict) && number(0,chance)==0 && OUTSIDE(ch) && (zone_table[world[ch->in_room].zone].conditions.precip_rate > 5)){ act("$n says, 'Call lightning!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_call_lightning; } else if(CAN_SEE(ch, vict) && number(0,chance)==0) { act("$n says, 'Harm!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_harm; } else if(CAN_SEE(ch, vict) && number(0,chance)==0) { act("$n says, 'Quake!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_earthquake; } break; case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: default: if(!IS_EVIL(ch) && IS_EVIL(vict) && number(0,chance)==0){ act("$n says, 'Dispel evil!'", 1, ch, 0, 0, TO_ROOM); cast_dispel_evil(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0); } else if(number(0,chance)==0){ act("$n says, 'Harm!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_harm; } else if(CAN_SEE(ch, vict) && number(0,chance)==0 && OUTSIDE(ch) && (zone_table[world[ch->in_room].zone].conditions.precip_rate > 5)){ act("$n says, 'Call lightning!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_call_lightning; } else if(CAN_SEE(ch, vict) && number(0,chance)==0) { act("$n says, 'Quake!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_earthquake; } break; } if(funct_ptr){ if(funct_ptr==cast_earthquake){ for(t_vict=world[ch->in_room].people; t_vict; t_vict = t_vict->next_in_room){ if(IS_NPC(t_vict)){ /* No quake if NPCs in the same room */ act("$n says, 'Blind!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_blindness; break; } } } if(vict) funct_ptr(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0); if(funct_ptr!=cast_earthquake){ for(t_vict=world[ch->in_room].people; t_vict; t_vict=t_vict->next_in_room){ if(!IS_NPC(t_vict) && CAN_SEE(ch, t_vict) && t_vict != vict && number(0,(31-GET_LEVEL(ch))/5)==0){ funct_ptr(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, t_vict, 0); } } } } } /* HAS_CL */ if (IS_SET(ch->specials.act, ACT_HAS_MU) && IS_FIGHTING(ch)){ chance=niceness(ch); vict = ch->specials.fighting; if(vict->in_room!=ch->in_room) return; if(GET_LEVEL(ch)>8 && CAN_SEE(ch, vict) && number(0,chance)==0){ act("$n says, 'Blindness!'", 1, ch, 0, 0, TO_ROOM); cast_blindness(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0); } else if (CAN_SEE(ch, vict) && GET_LEVEL(ch)>=14 && number(0,chance)==0){ act("$n says, 'Sleep!'", 1, ch, 0, 0, TO_ROOM); for(t_vict=world[ch->in_room].people; t_vict; t_vict=t_vict->next_in_room){ if(!IS_NPC(t_vict) && CAN_SEE(ch, t_vict) && number(0, (31-GET_LEVEL(ch))/6)==0){ cast_sleep(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, t_vict, 0); } } } else if (CAN_SEE(ch, vict) && GET_LEVEL(ch)>=5 && number(0,chance)==0){ act("$n says, 'Armor!'", 1, ch, 0, 0, TO_ROOM); cast_armor(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } else if (GET_LEVEL(ch)>=7 && number(0,chance)==0){ act("$n says, 'Strength!'", 1, ch, 0, 0, TO_ROOM); cast_strength(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, ch, 0); } else if (CAN_SEE(ch, vict) && GET_LEVEL(ch)>=12 && number(0,chance)==0){ act("$n says, 'Curse!'", 1, ch, 0, 0, TO_ROOM); cast_curse(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0); } funct_ptr=0; switch(GET_LEVEL(ch)){ case 1: case 2: case 3: if(vict && CAN_SEE(ch, vict) && number(0,chance)==0){ act("$n says, 'Magic missile!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_magic_missile; } else if(vict && CAN_SEE(ch, vict) && number(0,chance)==0){ act("$n says, 'Chill touch!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_chill_touch; } break; case 4: case 5: case 6: if(CAN_SEE(ch, vict) && number(0,chance)==0){ act("$n says, 'Burning hands!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_burning_hands; } if(CAN_SEE(ch, vict) && number(0,chance)==0){ act("$n says, 'Chill touch!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_chill_touch; } break; case 7: case 8: case 9: case 10: if(CAN_SEE(ch, vict) && number(0,chance)==0){ act("$n says, 'Shocking Grasp!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_shocking_grasp; } else if(CAN_SEE(ch, vict) && number(0,chance)==0){ act("$n says, 'Chill touch!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_chill_touch; } break; case 11: case 12: case 13: if(CAN_SEE(ch, vict) && number(0,chance)==0){ act("$n says, 'Colour spray!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_colour_spray; } if(CAN_SEE(ch, vict) && number(0,chance)==0){ act("$n says, 'Magic missile!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_magic_missile; } break; case 14: case 15: case 16: case 17: case 18: case 19: if(CAN_SEE(ch, vict) && number(0,chance)==0){ act("$n says, 'Energy drain!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_energy_drain; } else if(CAN_SEE(ch, vict) && number(0,chance)==0){ act("$n says, 'Lightning bolt!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_lightning_bolt; } break; case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: default: if(CAN_SEE(ch, vict) && number(0,chance)==0){ act("$n says, 'Fireball!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_fireball; } else if(CAN_SEE(ch, vict) && number(0,chance)==0){ act("$n says, 'Lightning bolt!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_lightning_bolt; } else if(CAN_SEE(ch, vict) && number(0,chance)==0 && !(IS_AFFECTED(vict, AFF_CHARM) && vict->master==ch)){ act("$n says, 'Charm!'", 1, ch, 0, 0, TO_ROOM); funct_ptr=cast_charm_person; } break; } if(funct_ptr){ if(vict) funct_ptr(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, vict, 0); for(t_vict=world[ch->in_room].people; t_vict; t_vict=t_vict->next_in_room){ if(!IS_NPC(t_vict) && t_vict!=vict && CAN_SEE(ch, t_vict) && number(0,(31-GET_LEVEL(ch))/6)==0){ funct_ptr(GET_LEVEL(ch), ch, "", SPELL_TYPE_SPELL, t_vict, 0); } } } } /* HAS_MU */ if (IS_SET(ch->specials.act, ACT_HAS_TH) && IS_FIGHTING(ch)){ switch(GET_LEVEL(ch)){ case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: default: } } /* HAS_TH */ if (IS_SET(ch->specials.act, ACT_HAS_WA) && IS_FIGHTING(ch)){ vict = ch->specials.fighting; chance = niceness(ch); if(CAN_SEE(ch, vict) && number(0,chance)==0){ do_bash(ch, "", 0); } else if(CAN_SEE(ch, vict) && number(0,chance)==0){ do_kick(ch, "", 0); } if(CAN_SEE(ch, vict) && number(0,chance)==0 && GET_LEVEL(ch)>10){ do_kick(ch, "", 0); } else if(CAN_SEE(ch, vict) && number(0,chance)==0 && GET_LEVEL(ch)>15){ do_bash(ch, "", 0); } } /* HAS_WA */ } /* If IS_MOB(ch) */ }