/* ************************************************************************
* 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) */
}