ldmud-3.2.9/doc/
ldmud-3.2.9/doc/efun/
ldmud-3.2.9/mud/
ldmud-3.2.9/mud/heaven7/
ldmud-3.2.9/mud/heaven7/lib/
ldmud-3.2.9/mud/lp-245/
ldmud-3.2.9/mud/lp-245/banish/
ldmud-3.2.9/mud/lp-245/doc/
ldmud-3.2.9/mud/lp-245/doc/examples/
ldmud-3.2.9/mud/lp-245/doc/sefun/
ldmud-3.2.9/mud/lp-245/log/
ldmud-3.2.9/mud/lp-245/obj/Go/
ldmud-3.2.9/mud/lp-245/players/lars/
ldmud-3.2.9/mud/lp-245/room/death/
ldmud-3.2.9/mud/lp-245/room/maze1/
ldmud-3.2.9/mud/lp-245/room/sub/
ldmud-3.2.9/mud/lp-245/secure/
ldmud-3.2.9/mud/morgengrauen/
ldmud-3.2.9/mud/morgengrauen/lib/
ldmud-3.2.9/mud/sticklib/
ldmud-3.2.9/mud/sticklib/src/
ldmud-3.2.9/mudlib/uni-crasher/
ldmud-3.2.9/pkg/
ldmud-3.2.9/pkg/debugger/
ldmud-3.2.9/pkg/diff/
ldmud-3.2.9/pkg/misc/
ldmud-3.2.9/src/autoconf/
ldmud-3.2.9/src/bugs/
ldmud-3.2.9/src/bugs/MudCompress/
ldmud-3.2.9/src/bugs/b-020916-files/
ldmud-3.2.9/src/bugs/doomdark/
ldmud-3.2.9/src/bugs/ferrycode/ferry/
ldmud-3.2.9/src/bugs/ferrycode/obj/
ldmud-3.2.9/src/bugs/psql/
ldmud-3.2.9/src/done/
ldmud-3.2.9/src/done/order_alist/
ldmud-3.2.9/src/done/order_alist/obj/
ldmud-3.2.9/src/done/order_alist/room/
ldmud-3.2.9/src/gcc/
ldmud-3.2.9/src/gcc/2.7.0/
ldmud-3.2.9/src/gcc/2.7.1/
ldmud-3.2.9/src/hosts/
ldmud-3.2.9/src/hosts/GnuWin32/
ldmud-3.2.9/src/hosts/amiga/NetIncl/
ldmud-3.2.9/src/hosts/amiga/NetIncl/netinet/
ldmud-3.2.9/src/hosts/amiga/NetIncl/sys/
ldmud-3.2.9/src/hosts/i386/
ldmud-3.2.9/src/hosts/msdos/byacc/
ldmud-3.2.9/src/hosts/msdos/doc/
ldmud-3.2.9/src/hosts/os2/
ldmud-3.2.9/src/hosts/win32/
ldmud-3.2.9/src/util/
ldmud-3.2.9/src/util/erq/
ldmud-3.2.9/src/util/indent/hosts/next/
ldmud-3.2.9/src/util/xerq/
ldmud-3.2.9/src/util/xerq/lpc/
ldmud-3.2.9/src/util/xerq/lpc/www/
/*
 * A general purpose monster. Clone this object,
 * and call local functions to configure it.
 */

/*
 * If you are going to copy this file, in the purpose of changing
 * it a little to your own need, beware:
 *
 * First try one of the following:
 *
 * 1. Do clone_object(), and then configure it. This object is specially
 *    prepared for configuration.
 *
 * 2. If you still is not pleased with that, create a new empty
 *    object, and make an inheritance of this objet on the first line.
 *    This will automatically copy all variables and functions from the
 *    original object. Then, add the functions you want to change. The
 *    original function can still be accessed with '::' prepended on the name.
 *
 * The maintainer of this LPmud might become sad with you if you fail
 * to do any of the above. Ask other wizards if you are doubtful.
 *
 * The reason of this, is that the above saves a lot of memory.
 */

#include "living.h"

/*
 * The heart beat is always started in living.h when we are attacked.
 */

string short_desc, long_desc, alias, alt_name, race;
int move_at_reset, aggressive;
object kill_ob;
status healing;		/* True if this monster is healing itself. */

string chat_head;	/* Vector with all chat strings. */
int chat_chance;

string a_chat_head;	/* Vector with all a_chat strings. */
int a_chat_chance;

object talk_ob;
string talk_func;	/* Vector of functions. */
string talk_match;	/* Vector of strings. */
string talk_type;	/* Vector of types. */
string the_text;
int have_text;


object dead_ob;
object init_ob;

int random_pick;

int spell_chance, spell_damage;
string spell_mess1, spell_mess2;
object me;
object create_room;

random_move();
test_match();
heal_slowly();
pick_any_obj();

reset(arg)
{
    if (arg) {
	if (move_at_reset)
	    random_move();
	return;
    }
    is_npc = 1;
    enable_commands();
    me = this_object();
    create_room = environment(me);
}

random_move()
{
    int n;
    n = random(4);
    if (n == 0)
	command("west");
    else if (n == 1)
	command("east");
    else if (n == 2)
	command("south");
    else if (n == 3)
	command("north");
}

short() {
    return short_desc;
}

long() {
    write (long_desc);
}

id(str) { return str == name || str == alias || str == race || str == alt_name; }

heart_beat()
{
    int c;

    age += 1;
    if(!test_if_any_here()) {
	if(have_text && talk_ob) {
	    have_text = 0;
	    test_match(the_text);
	} else {
	    set_heart_beat(0);
	    if (!healing)
		heal_slowly();
	    return;
	}
    }
    if (kill_ob && present(kill_ob, environment(this_object()))) {
	if (random(2) == 1)
	    return;		/* Delay attack some */
	attack_object(kill_ob);
	kill_ob = 0;
	return;
    }
    if (attacker_ob && present(attacker_ob, environment(this_object())) &&
      spell_chance > random(100)) {
	say(spell_mess1 + "\n", attacker_ob);
	tell_object(attacker_ob, spell_mess2 + "\n");
	attacker_ob->hit_player(random(spell_damage));
    }
    attack();
    if (attacker_ob && whimpy && hit_point < max_hp/5)
	run_away();
    if(chat_chance || a_chat_chance){
	c = random(100);
	if(attacker_ob && a_chat_head) {
	    if(c < a_chat_chance){
		c = random(sizeof(a_chat_head));
		tell_room(environment(), a_chat_head[c]);
	    }
	} else {
	    if(c < chat_chance && chat_chance){
		c = random(sizeof(chat_head));
		tell_room(environment(), chat_head[c]);
	    }
	}
    }
    if(random_pick) {
	c = random(100);
	if(c < random_pick)
	    pick_any_obj();
    }
    if(have_text && talk_ob) {
	have_text = 0;
	test_match(the_text);
    }
}

can_put_and_get(str)
{
    if (!str)
	return 0;
    return 1;
}

int busy_catch_tell;

catch_tell(str) {
    if (busy_catch_tell)
	return;
    busy_catch_tell = 1;
    if(talk_ob) {
	if(have_text) {
	    test_match(the_text);
	    the_text = str;
	} else {
	    the_text = str;
	    have_text = 1;
	}
    }
    busy_catch_tell = 0;
}

/*
 * Call the following functions to setup the monster.
 * Call them in the order they appear.
 */

set_name(n) {
    name = n;
    set_living_name(n);
    alignment = 0;		/* Neutral monster */
    cap_name = capitalize(n);
    short_desc = cap_name;
    long_desc = "You see nothing special.\n";
}

set_level(l) {
    level = l;
    Str = l; Int = l; Con = l; Dex = l;
    weapon_class = level/2 + 3;
    armour_class = level/4;
    hit_point = 50 + (level - 1) * 8;	/* Same as a player */
    max_hp = hit_point;
    spell_points = max_hp;
    experience = "room/adv_guild"->query_cost(l-1);
    /* This is for level 1 monsters. */
    if (experience == 0)
	experience = random(500);
}

/* Optional */
set_alias(a) { alias = a; }
/* Optional */
set_alt_name(a) { alt_name = a; }
/* Optional */
set_race(r) { race = r; }
/* optional */
set_hp(hp) { max_hp = hp; hit_point = hp; }
/* optional. Can only be lowered */
set_ep(ep) { if (ep < experience) experience = ep; }
/* optional */
set_al(al) { alignment = al; }
/* optional */
set_short(sh) { short_desc = sh; long_desc = short_desc + "\n";}
/* optional */
set_long(lo) { long_desc = lo; }
/* optional */
set_wc(wc) { if (wc > weapon_class) weapon_class = wc; }
/* optional */
set_ac(ac) { if (ac > armour_class) armour_class = ac; }
/* optional */
set_move_at_reset() { move_at_reset = 1; }
/* optional
 * 0: Peaceful.
 * 1: Attack on sight.
 */
set_aggressive(a) {
    aggressive = a;
}
/*
 * Now some functions for setting up spells !
 */
/*
 * The percent chance of casting a spell.
 */
set_chance(c) {
    spell_chance = c;
}
/* Message to the victim. */
set_spell_mess1(m) {
    spell_mess1 = m;
}
set_spell_mess2(m) {
    spell_mess2 = m;
}
set_spell_dam(d) {
    spell_damage = d;
}

/* Set the frog curse. */
set_frog() {
    frog = 1;
}

/* Set the whimpy mode */
set_whimpy() {
    whimpy = 1;
}

/*
 * Force the monster to do a command. The force_us() function isn't
 * always good, because it checks the level of the caller, and this function
 * can be called by a room.
 */
init_command(cmd) {
    command(cmd);
}

load_chat(chance, strs) {
    sizeof(strs);		/* Just ensure that it is an array. */
    chat_head = strs;
    chat_chance = chance;
}

/* Load attack chat */

load_a_chat(chance, strs) {
    sizeof(strs);		/* Just ensure that it is an array. */
    a_chat_head = strs;
    a_chat_chance = chance;
}

/* Catch the talk */

set_match(ob, func, type, match) {
    object old;

    if (sizeof(func) != sizeof(type) || sizeof(match) != sizeof(type))
	return;
    talk_ob = ob;
    talk_func = func;
    talk_type = type;
    talk_match = match;
    say("talk match length " + sizeof(func) + "\n");
}

set_dead_ob(ob)
{
    dead_ob = ob;
}

second_life()
{
    if(dead_ob)
	return dead_ob->monster_died(this_object());
}

set_random_pick(r)
{
    random_pick = r;
}

pick_any_obj() {
    object ob;
    int weight;

    ob = first_inventory(environment(this_object()));
    while(ob) {
	if (ob->get() && ob->short()) {
	    weight = ob->query_weight();
	    if (!add_weight(weight)) {
		say(cap_name + " tries to take " + ob->short() +
		    " but fails.\n");
		return;
	    }
	    move_object(ob, this_object());
	    say(cap_name + " takes " + ob->short() + ".\n");
	    if (ob->weapon_class())
		ob->wield(ob->query_name());
	    else if (ob->armour_class())
		ob->wear(ob->query_name());
	    return;
	}
	ob = next_inventory(ob);
    }
}

set_init_ob(ob)
{
    init_ob = ob;
}

init() {

    create_room = environment(me);
    if(this_player() == me)
	return;
    if(init_ob)
	if(init_ob->monster_init(this_object()))
	    return;
    if (attacker_ob) {
	set_heart_beat(1); /* Turn on heart beat */
    }
    if(this_player() && !this_player()->query_npc()) {
	set_heart_beat(1);
	if (aggressive == 1)
	    kill_ob = this_player();
    }
}

query_create_room() { return create_room; }

query_race() { return race; }

test_match(str) {
    string who, str1, type, match, func;
    int i;

    while(i < sizeof(talk_match)) {
	if (talk_type[i])
	    type = talk_type[i];
	match = talk_match[i];
	if (match == 0)
	    match = "";
	if (talk_func[i])
	    func = talk_func[i];
	if (sscanf(str,"%s " + type + match + " %s\n",who,str1) == 2 ||
	   sscanf(str,"%s " + type + match + "\n",who) == 1 ||
	   sscanf(str,"%s " + type + match + "%s\n",who,str1) == 2 ||
	   sscanf(str,"%s " + type + " " + match + "\n",who) == 1 ||
	   sscanf(str,"%s " + type + " " + match + " %s\n",who,str1) == 2)
	{
	    return call_other(talk_ob, func, str);
	}
	i += 1;
    }
}

/*
 * The monster will heal itself slowly.
 */
heal_slowly() {
    hit_point += 120 / (INTERVAL_BETWEEN_HEALING * 2);
    if (hit_point > max_hp)
	hit_point = max_hp;
    spell_points += 120 / (INTERVAL_BETWEEN_HEALING * 2);
    if (spell_points > max_hp)
	spell_points = max_hp;
    healing = 1;
    if (hit_point < max_hp || spell_points < max_hp)
	call_out("heal_slowly", 120);
    else
	healing = 0;
}