/***************************************************************************
* file: mob_act.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. *
* *
* Copyright (C) 1992, 1993 Michael Chastain, Michael Quan, Mitchell Tse *
* Performance optimization and bug fixes by MERC Industries. *
* You can use our stuff in any way you like whatsoever so long as this *
* copyright notice remains intact. If you like it please drop a line *
* to mec@garnet.berkeley.edu. *
* *
* This is free software and you are benefitting. We hope that you *
* share your changes too. What goes around, comes around. *
***************************************************************************/
#include <stdio.h>
#include "structs.h"
#include "mob.h"
#include "obj.h"
#include "utils.h"
#include "db.h"
extern struct char_data *character_list;
extern struct index_data *mob_index;
extern struct room_data *world;
extern struct str_app_type str_app[];
void mobile_activity(void)
{
register struct char_data *ch;
struct char_data *tmp_ch;
struct obj_data *obj, *best_obj;
int door, max;
void do_move(struct char_data *ch, char *argument, int cmd);
void do_get(struct char_data *ch, char *argument, int cmd);
/* Examine all mobs. */
for ( ch = character_list; ch; ch = ch->next )
{
if ( !IS_MOB(ch) )
continue;
/* Examine call for special procedure */
if ( IS_SET(ch->specials.act, ACT_SPEC) )
{
if (!mob_index[ch->nr].func)
{
sprintf( log_buf, "Mobile_activity: MOB %d no func",
mob_index[ch->nr].virtual );
log( log_buf );
REMOVE_BIT( ch->specials.act, ACT_SPEC );
}
else
{
if ( (*mob_index[ch->nr].func) (ch, 0, "") )
continue;
}
}
/* That's all for busy monster */
if ( !AWAKE(ch) || ch->specials.fighting )
continue;
/* Scavenge */
if ( IS_SET(ch->specials.act, ACT_SCAVENGER)
&& world[ch->in_room].contents && number(0,10) == 0 )
{
max = 1;
best_obj = 0;
for ( obj = world[ch->in_room].contents; obj;
obj = obj->next_content )
{
if ( CAN_GET_OBJ(ch, obj) && obj->obj_flags.cost > max )
{
best_obj = obj;
max = obj->obj_flags.cost;
}
}
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 );
}
}
/* Wander */
if ( !IS_SET(ch->specials.act, ACT_SENTINEL)
&& 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|DEATH) )
{
if (ch->specials.last_direction == door)
{
ch->specials.last_direction = -1;
}
else if ( !IS_SET(ch->specials.act, ACT_STAY_ZONE)
|| world[EXIT(ch, door)->to_room].zone == world[ch->in_room].zone )
{
ch->specials.last_direction = door;
do_move( ch, "", ++door );
}
}
/* Aggress */
if ( IS_SET(ch->specials.act, ACT_AGGRESSIVE) )
{
for ( tmp_ch = world[ch->in_room].people; tmp_ch;
tmp_ch = tmp_ch->next_in_room )
{
if ( IS_NPC(tmp_ch) || !CAN_SEE(ch, tmp_ch) || GET_LEVEL(tmp_ch)>31)
continue;
if ( IS_SET(ch->specials.act, ACT_WIMPY) && AWAKE(tmp_ch) )
continue;
if ( ( IS_SET(ch->specials.act, ACT_AGGR_EVIL)
&& IS_EVIL(tmp_ch) )
|| ( IS_SET(ch->specials.act, ACT_AGGR_NEUT)
&& IS_NEUTRAL(tmp_ch) )
|| ( IS_SET(ch->specials.act, ACT_AGGR_GOOD)
&& IS_GOOD(tmp_ch) )
|| ( ch->specials.act & ACT_AGGR_ALL ) == 0 )
{
hit(ch, tmp_ch, 0);
break;
}
}
}
}
}