/*
* A general purpose monster. Clone this object,
* and call local functions to configure it.
*/
#include "living.h"
/*
* The heart beat is always started in living.h when we are attacked.
*/
string short_desc, long_desc, alias, race;
int move_at_reset, aggressive, can_kill;
object kill_ob;
object desc_ob;
int spell_chance, spell_dam;
string spell_mess1, spell_mess2;
set_desc_ob(ob) { desc_ob = ob; }
valid_attack(ob)
{
/* Don't attack other monsters unless specifically allowed to. */
return (!call_other(ob, "query_npc", 0) || can_kill);
}
reset(arg)
{
if (arg) {
if (move_at_reset)
random_move();
return;
}
is_npc = 1;
/* Only let this monster kill other monsters if specifically allowed. */
can_kill = 0;
enable_commands();
}
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() {
if (desc_ob) return call_other(desc_ob,"monster_short",0);
return short_desc;
}
long() {
if (desc_ob) {
call_other(desc_ob,"monster_long",0);
return;
}
write (long_desc);
}
id(str) {
if (desc_ob) return call_other(desc_ob,"monster_id",str);
return str == name || str == alias || str == race;
}
heart_beat()
{
age += 1;
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");
call_other(attacker_ob, "hit_player", random(spell_dam));
}
attack();
if (attacker_ob && whimpy && hit_point < max_hp/5)
run_away();
}
can_put_and_get(str)
{
if (!str)
return 0;
return 1;
}
catch_tell(str) {
string who;
if (attacker_ob)
return;
if (aggressive == 1 && sscanf(str, "%s arrives", who) == 1) {
kill_ob = this_player();
set_heart_beat(1);
}
}
/*
* Call the following functions to setup the monster.
* Call them in the order they appear.
*/
set_name(n) {
name = n;
alignment = 0; /* Neutral monster */
cap_name = capitalize(n);
short_desc = cap_name;
long_desc = "You see nothing special.\n";
}
/* Optional */
set_alias(a) {
alias = a;
}
/* Optional */
set_race(r) {race=r;}
set_level(l) {
level = l;
weapon_class = WEAPON_CLASS_OF_HANDS;
armor_class = 0;
hit_point = 50 + (level - 1) * 8; /* Same as a player */
max_hp = hit_point;
experience = call_other("room/adv_guild", "query_cost", l-1);
}
/* optional */
set_hp(hp) { max_hp = hp; hit_point = hp; }
/* optional */
set_ep(ep) { experience = ep; }
/* optional */
set_al(al) {
/* Limit alignment to keep wizards from making their monsters worth
much too much */
if (al > 1000)
al = 1000;
if (al < -1000)
al = -1000;
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) { weapon_class = wc; }
/* optional */
set_ac(ac) { armor_class = ac; }
/* optional */
set_move_at_reset() { move_at_reset = 1; }
/* optional
* 0: Peaceful.
* 1: Attack on sight.
*/
set_aggressive(a) {
aggressive = a;
}
/* optional
* 0: Can't attack other monsters.
* 1: Can attack other monsters.
*/
set_can_kill(a) {
can_kill = 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_dam = 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);
}