/* Filename : demon.c
* Description : the demon summoned by blowing the horn
*
* written : 05-10-1996 - Gunner
* last modified : 28-05-1998 - Gunner
* HTML-Version : 06-02-2000 - Ghorwin
*/
#include <mudlib.h>
inherit I_MONSTER;
#define FUNC "/doc/crashcourse/course09/demonfuncs"
#define CMDPATH "/doc/crashcourse/course06/com/"
create()
{
::create();
set_name("iggiook");
add_id(({"demon","evil demon","demon from hell","shadow","dark demon"}));
set_short("A dark demon");
set_long("A dark demon from hell. It looks more like a shadow "
"than a living creature. It's probably not alive, anyways...\n");
set_level(20);
set_race("demon");
set_hp(500+random(500));
set_sp(500+random(500));
set_al(-500);
set_wc(30);
set_ac(10);
add_skill("vuln_cold",20);
add_skill("vuln_magic",80);
add_skill("vuln_acid",50);
add_skill("prot_blunt",20);
add_skill("prot_fire",80);
add_skill("prot_slash",20);
add_skill("prot_chop",20);
add_skill("prot_pierce",20);
add_cmdpath(CMDPATH);
load_a_chat(20,({"!meteor",
"!cast fireball at",
"!cast electric storm at",
"!cast lightning bolt at",
"*scream",
"*grin evi",
"*frin evi"}));
add_hook("__catch_tell",({FUNC,"demon_order"}),this_object());
add_hook("__move_player",({FUNC,"demon_move"}),this_object());
add_hook("__kill",({FUNC,"demon_kill"}));
add_hook("__bdie",({FUNC,"demon_dies"}),this_object());
replace_program(I_MONSTER);
}
/* Filename : demonfuncs.c
* Description : the functionfile for demon.c
*
* written : 05-10-1996 - Gunner
* last modified : 28-05-1998 - Gunner
* HTML-Version : 06-02-2000 - Ghorwin
*/
#include <mudlib.h>
#include "/doc/crashcourse/defs.h"
inherit I_DAEMON;
#define MAX_IDLETIME 60*5+random(60*5)
// A few global variables. For conveniency and efficiency
string name;
int playerkills = 0;
int demonkills = 0;
int stay_here = 0;
/*
* demon_order : Called by the __catch_tell in demon.c
*/
void
demon_order(object demon, string arg)
{
string line,
command,
enemy,
who;
object owner,
att,
notmaster;
int len;
if (!name) return;
if (strsrch(arg," tells you: ") == -1)
return; // Not a tell/order
arg = replace_string(arg,"\n","");
arg = replace_string(arg,"%^END%^","");
if (sscanf(arg,"%s tells you: %s",who,line) != 2)
{
tell_room(ENV(demon),"The demon looks kinda puzzled.\n");
return;
}
owner = find_player(name);
if (!owner) return;
if (lower_case(who) != name)
{
notmaster = find_living(lower_case(who));
if (!notmaster) return;
tell_object(notmaster,"Iggiook replies: 'YOU ARE NOT MY MASTER!'\n");
return;
}
if (sscanf(line,"%s %s",command,enemy) != 2)
{
command = line; enemy = 0;
}
switch (command)
{
case "report" :
tell_object(owner, "The demon tells you: 'I can report that I "
"have taken " + demonkills + " lives, while you have "
" taken " + playerkills + "!'\n");
break;
case "kill" :
if (!enemy)
{
tell_object(owner,"The demon tells you: 'Kill who, Master?'\n");
return;
}
att = present(enemy, ENV(demon));
if (!att)
{
tell_object(owner, "The demon tells you: 'I can't find " +
enemy + " anywhere, Master!'\n");
return 1;
}
if (!living(att) || Q_NOFIGHT(att) || Q_NOFIGHT(ENV(demon)))
{
tell_object(owner, "The demon tells you: 'I can't do that, "
"Master!\n");
return 1;
}
tell_object(owner,"The demon tells you: 'At once, Master!'\n");
demon->do_attack(att);
break;
case "stay" :
tell_object(owner,"The demon tells you: 'I will stay right here, "
"Master!'\n");
stay_here = 1;
break;
case "follow" :
tell_object(owner,"The demon tells you: 'I will follow you to the "
"end of the world, Master!'\n");
stay_here = 0;
break;
case "stop" :
tell_object(owner,"The demon tells you: 'Yes, Master!'\n");
demon->stop_fight();
break;
default :
tell_object(owner,"The demon tells you: 'I'm sorry, Master. I have "
"only learned a few commands.'\nThe demon sobs for a "
"while.\n'But, I do know how to 'stay', 'follow', "
"'report', 'stop' and 'kill'!'\nThe demon frins evilly.\n");
break;
}
}
/*
* demon_move : Called by the __move_player hook in demon.c
*/
void
demon_move(object demon, string direction, object oldenv, object newenv)
{
object owner;
if (demon->query_chat_chance() <= 0) // When the demon is called
{
name = demon->query_property("owner_name");
demon->load_chat(10,({
"*bow " + name,
"*worship " + name,
"*smile " + name,
"The demon says: 'Now what, master?'\n",
"The demon says: 'Can't we kill something, master?'\n",
(:call_other, TO, "idle_check", demon:)}));
tell_room(newenv,"The demon says: 'I have come to serve you, master. "
"My name is Iggiook. Tell me what you want done and I "
"will do it!'\n");
owner = present(name,newenv);
if (!owner)
{
demon->destroy(); // Something went wrong...
return;
}
owner->add_hook("__move_player",({TO, "player_moves"}));
owner->add_hook("__kill",({TO, "player_kills"}));
owner->add_hook("__notify_attack",({TO, "player_attacked"}));
owner->add_hook("__bdie",({TO, "player_dies",owner}));
owner->add_hook("__quit",(:call_other, TO, "player_quits",owner:));
}
}
/*
* demon_kill : The demon kills something
*/
void
demon_kill(object enemy, object killer)
{
tell_room(ENV(enemy),"The demon frins evilly. 'I did that.', it says...\n");
demonkills++;
}
/*
* demon_dies : The demon is about to die
*/
int
demon_dies(object demon, object killer)
{
object owner = find_living(name);
tell_room(ENV(demon),"The demon cries out into the night. It's a desperate "
"cry for help.\n");
if (random(200) < demonkills)
{
tell_room(ENV(demon),"Its powerful lords of hell hear its cry and "
"help their obidient servant!\n");
demon->heal_self(5000);
demonkills = 0;
return 1; // Igg survives!
}
tell_room(ENV(demon),"Its powerful lords of hell are silent...\n");
if (!owner) return;
owner->remove_hook("__move_player");
owner->remove_hook("__kill");
owner->remove_hook("__notify_attack");
owner->remove_hook("__bdie");
owner->remove_hook("__quit");
return 0; // Igg dies.. *sob*
}
/*
* player_moves : The player moves, time for the demon to follow. Or try at least
*/
void
player_moves(string direction, object oldenv, object newenv)
{
object igg = find_living("iggiook");
if (stay_here) return; // STAY!
if (!present(igg,oldenv)) return; // Not inside the same room
if (Q_NOPET(newenv))
{
tell_object(TP,"The demon tells you: 'Master! The lords tell me "
"not to go in there!'\n");
return;
}
igg->command(direction);
}
/*
* player_kill : The player kills something
*/
void
player_kills(object enemy, object killer)
{
tell_object(killer,"The demon tells you: 'You did it, Master!'\n");
playerkills++;
}
/*
* player_attacked : The player was attacked, help him/her/it
*/
void
player_attacked(object attacker)
{
object igg = present("iggiook",ENV(attacker));
if (!igg) return;
if (igg->query_attack()) return;
tell_room(ENV(attacker),"The demon shouts: 'I'll help you, Master!'\n");
igg->do_attack(attacker,igg);
}
/*
* player_dies : The player is about to die. Help?
*/
int
player_dies(object player, object killer)
{
if (random(300) < playerkills)
{
tell_object(PR,"The demon shouts: 'Master! The lords tells me you "
"will not die yet. They must be pleased with you! "
"But, they take the kills in return...'\n");
player->heal_self(500);
playerkills = 0;
return 1; // The player lives!
}
player->remove_hook("__move_player");
player->remove_hook("__kill");
player->remove_hook("__notify_attack");
player->remove_hook("__bdie");
player->remove_hook("__quit");
return 0; // Let the player die...
}
/*
* player_quits : The player quits! Bah.
*/
void
player_quits(object player)
{
object igg = find_living("iggiook");
if (!igg) return; // Where did Igg go??
tell_object(player,"The demon tells you: 'Are you leaving me, Master? But, "
"how am I going to survive here with you? Well, I better "
"go back then, I suppose... Goodbye, Master...'\n");
player->remove_hook("__move_player");
player->remove_hook("__kill");
player->remove_hook("__notify_attack");
player->remove_hook("__bdie");
player->remove_hook("__quit");
}
/*
* idle_check : Don't idle, or Igg'll run off...
*/
void
idle_check(object demon)
{
object owner = find_living(name);
if (!owner) return; // Eh? Now what?
if (query_idle(owner) > MAX_IDLETIME)
{
tell_object(owner,"The demon tells you: 'I am bored, Master. I think "
"I'll return to my lords of hell. Goodbye, Master...'\n");
owner->remove_hook("__move_player");
owner->remove_hook("__kill");
owner->remove_hook("__notify_attack");
owner->remove_hook("__bdie");
owner->remove_hook("__quit");
demon->destroy();
return 1;
}
if (Q_NOMAGIC(ENV(demon)))
{
tell_room(ENV(demon),"The demon sighs: 'This place is no fun. It blocks "
"my demonic powers...'\n");
return 1;
}
if (Q_NOFIGHT(ENV(demon)))
{
tell_room(ENV(demon),"The demon sighs: 'This place is totally uncool.'\n");
return 1;
}
return 1;
}