/* ************************************************************************ * 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 <stdlib.h> #include "structs.h" #include "utils.h" #include "db.h" #include "comm.h" #include "interpreter.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 hit(struct char_data *ch, struct char_data *victim, int type); void mobile_activity(void) { register struct char_data *ch; struct char_data *tmp_ch, *vict; struct obj_data *obj, *best_obj; int door, found, max; memory_rec * names; extern int no_specials; ACMD(do_move); ACMD(do_get); for (ch = character_list; ch; ch = ch->next) if (IS_MOB(ch)) { /* Examine call for special procedure */ if (IS_SET(ch->specials2.act, MOB_SPEC) && !no_specials) { if (!mob_index[ch->nr].func) { sprintf(buf, "%s (#%d): Attempting to call non-existing mob func", GET_NAME(ch), (int)mob_index[ch->nr].virtual); log(buf); REMOVE_BIT(ch->specials2.act, MOB_SPEC); } else { if ((*mob_index[ch->nr].func) (ch, 0, "")) continue; /* go to next char */ } } if (AWAKE(ch) && !(ch->specials.fighting)) { if (IS_SET(ch->specials2.act, MOB_SCAVENGER)) { /* if 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 */ if (!IS_SET(ch->specials2.act, MOB_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) && !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->specials2.act, MOB_STAY_ZONE)) { ch->specials.last_direction = door; do_move(ch, "", ++door, 0); } else { if (world[EXIT(ch, door)->to_room].zone == world[ch->in_room].zone) { ch->specials.last_direction = door; do_move(ch, "", ++door, 0); } } } } /* if can go */ if (IS_SET(ch->specials2.act, MOB_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) && !PRF_FLAGGED(tmp_ch, PRF_NOHASSLE)) { if (!IS_SET(ch->specials2.act, MOB_WIMPY) || !AWAKE(tmp_ch)) { if ((IS_SET(ch->specials2.act, MOB_AGGRESSIVE_EVIL) && IS_EVIL(tmp_ch)) || (IS_SET(ch->specials2.act, MOB_AGGRESSIVE_GOOD) && IS_GOOD(tmp_ch)) || (IS_SET(ch->specials2.act, MOB_AGGRESSIVE_NEUTRAL) && IS_NEUTRAL(tmp_ch)) || (!IS_SET(ch->specials2.act, MOB_AGGRESSIVE_EVIL) && !IS_SET(ch->specials2.act, MOB_AGGRESSIVE_NEUTRAL) && !IS_SET(ch->specials2.act, MOB_AGGRESSIVE_GOOD) ) ) { hit(ch, tmp_ch, 0); found = TRUE; } } } } } /* if aggressive */ if (IS_SET(ch->specials2.act, MOB_MEMORY) && ch->specials.memory) { for (vict = 0, tmp_ch = world[ch->in_room].people; tmp_ch && !vict; tmp_ch = tmp_ch->next_in_room) if (!IS_NPC(tmp_ch)) for (names = ch->specials.memory; names && !vict; names = names->next) if (names->id == GET_IDNUM(tmp_ch)) vict = tmp_ch; if (vict) { act("'Hey! You're the fiend that attacked me!!!', exclaims $n.", FALSE, ch, 0, 0, TO_ROOM); hit(ch, vict, 0); } } /* mob memory */ } } /* If IS_MOB(ch) */ } /* Mob Memory Routines */ /* make ch remember victim */ void remember (struct char_data *ch, struct char_data *victim) { memory_rec * tmp; bool present = FALSE; if (!IS_NPC(ch) || IS_NPC(victim)) return; for (tmp = ch->specials.memory; tmp && !present; tmp = tmp->next) if (tmp->id == GET_IDNUM(victim)) present = TRUE; if (!present) { CREATE(tmp, memory_rec, 1); tmp->next = ch->specials.memory; tmp->id = GET_IDNUM(victim); ch->specials.memory = tmp; } } /* make ch forget victim */ void forget (struct char_data *ch, struct char_data *victim) { memory_rec * curr, *prev; if (!(curr = ch->specials.memory)) return; while (curr && curr->id != GET_IDNUM(victim)) { prev = curr; curr = curr->next; } if (!curr) return; /* person wasn't there at all. */ if (curr == ch->specials.memory) ch->specials.memory = curr->next; else prev->next = curr->next; free(curr); } /* erase ch's memory */ void clearMemory(struct char_data *ch) { memory_rec * curr, *next; curr = ch->specials.memory; while (curr) { next = curr->next; free(curr); curr = next; } ch->specials.memory = NULL; }