#define INTERVAL_BETWEEN_HEALING 10 #define WEAPON_CLASS_OF_HANDS (3) #define ARMOUR_CLASS_OF_BARE 0 #define KILL_NEUTRAL_ALIGNMENT 10 #define ADJ_ALIGNMENT(al) ((-al - KILL_NEUTRAL_ALIGNMENT)/4) #define MAX_LIST 20 #define NAME_OF_GHOST "some mist" /* * Include this file in objects that "lives". * The following variables are defined here: * */ int time_to_heal; /* Count down variable. */ int money; /* Amount of money on player. */ string name; /* Name of object. */ string msgin, msgout; /* Messages when entering or leaving a room. */ int is_npc, brief; /* Flags. */ int level; /* Level of monster. */ int armour_class; /* What armour class of monster. */ int hit_point; /* Number of hit points of monster. */ int max_hp; int experience; /* Experience points of monster. */ string mmsgout; /* Message when leaving magically. */ string mmsgin; /* Message when arriving magically. */ string attacker_ob; /* Name of player attacking us. */ string alt_attacker_ob; /* Name of other player also attacking us. */ int weapon_class; /* How good weapon. Used to calculate damage. */ string name_of_weapon; /* To see if we are wielding a weapon. */ string name_of_armour; /* What armour we have. */ int ghost; /* Used for monsters that can leave a ghost. */ int local_weight; /* weight of items */ object hunted, hunter; /* used in the hunt mode */ int hunting_time; /* How long we will stay in hunting mode. */ string cap_name; /* Capital version of "name". */ int spell_points; /* Current spell points. Same max as max_hp. */ string spell_name; int spell_cost, spell_dam; int age; /* Number of heart beats of this character. */ int is_invis; /* True when player is invisible */ int frog; /* If the player is a frog */ int whimpy; /* Automatically run when low on HP */ /* * All characters have an aligment, depending on how good or chaotic * they are. * This value is updated when killing other players. */ int alignment; /* * The following routines are defined for usage: * hit_player Called when fighting. * transfer_all_to: Transfer all objects to dest. * move_player: Called by the object that moves the monster. * query_name: Gives the name to external objects. * attacked_by Tells us who are attacking us. * show_stats Dump local status. * stop_wielding Called when we drop a weapon. * stop_wearing Called when we drop an armour. * query_level Give our level to external objects. * query_value Always return 0. Can't sell this object. * get Always return 0. Can't take this object. * attack Should be called from heart_beat. Will maintain attack. * query_attack * drop_all_money Used when the object dies. * wield Called by weapons. * wear Called by armour. * add_weight Used when picking up things. * heal_self Enable wizarfs to heal this object. * can_put_and_get Can look at inventory, but not take things from it. * attack_object Called when starting to attack an object. * test_if_any_here For monsters. Call this one if you suspect no enemy * is here any more. This will be checked, and the * heart beat turned off in that case. * force_us Force us to do a command. */ /* * This routine is called from objects that moves the player. * Special: direction "X" means teleport. */ move_player(dir_dest) { string dir, dest; object ob; int is_light; if (sscanf(dir_dest, "%s#%s", dir, dest) != 2) { tell_object(this_object(), "Move to bad dir/dest\n"); return; } hunting_time -= 1; if (hunting_time == 0) { if (hunter) call_other(hunter, "stop_hunting"); hunter = 0; hunted = 0; } if (attacker_ob && present(attacker_ob)) { hunting_time = 10; if (!hunter) tell_object(this_object(), "You are now hunted by " + call_other(attacker_ob, "query_name", 0) + ".\n"); hunter = attacker_ob; } if (!msgout) msgout = "leaves"; if (ghost) say(NAME_OF_GHOST + " " + msgout + " " + dir + ".\n"); else if (dir == "X" && !is_invis) say(cap_name + " " + mmsgout + ".\n"); else if (!is_invis) say(cap_name + " " + msgout + " " + dir + ".\n"); move_object(this_object(), dest); is_light = set_light(0); if (level >= 20) tell_object(this_object(), dest + "\n"); if (!msgin) msgin = "arrives"; if (ghost && is_light) say(NAME_OF_GHOST + " " + msgin + ".\n"); else if (!is_invis && dir == "X") say(cap_name + " " + mmsgin + ".\n"); else if (!is_invis && is_light) say(cap_name + " " + msgin + ".\n"); if (hunted && present(hunted)) attack_object(hunted); if (hunter && present(hunter)) call_other(hunter, "attack_object", this_object()); if (is_npc) return; if (!is_light) { write("A dark room.\n"); return; } ob = environment(this_object()); if (brief) write(call_other(ob, "short", 0) + ".\n"); else call_other(ob, "long", 0); ob = first_inventory(ob); while(ob) { if (ob != this_object()) { string short_str; short_str = call_other(ob, "short"); if (short_str) write(short_str + ".\n"); } ob = next_inventory(ob); } } /* * This function is called from other players when they want to make * damage to us. We return how much damage we received, which will * change the attackers score. This routine is probably called from * heart_beat() from another player. */ hit_player(dam) { if (level >= 20) /* You can't hit a wizard ! */ return 0; dam -= armour_class; if (dam <= 0) return 0; if (dam > hit_point+1) dam = hit_point+1; hit_point = hit_point - dam; if (hit_point<0) { object corpse; /* We died ! */ if (hunter) call_other(hunter, "stop_hunting"); hunter = 0; hunted = 0; say(cap_name + " died.\n"); experience = experience / 2; /* Nice, isn't it ? */ hit_point = 10; /* The player killing us will update his alignment ! */ call_other(attacker_ob, "add_alignment", ADJ_ALIGNMENT(alignment)); call_other(attacker_ob, "add_exp", experience / 25); corpse = clone_object("obj/corpse"); call_other(corpse, "set_name", name); transfer_all_to(corpse); if (!is_npc) save_object("players/" + name); move_object(corpse, environment(this_object())); if (!call_other(this_object(), "second_life", 0)) destruct(this_object()); } return dam; } transfer_all_to(dest) { object ob; object next_ob; ob = first_inventory(this_object()); while(ob) { next_ob = next_inventory(ob); call_other(ob, "drop", 1); move_object(ob, dest); ob = next_ob; } local_weight = 0; if (money == 0) return; ob = clone_object("obj/money"); call_other(ob, "set_money", money); move_object(ob, dest); money = 0; } query_name() { if (ghost) return NAME_OF_GHOST; return cap_name; } query_alignment() { return alignment; } /* * This routine is called when we are attacked by a player. */ attacked_by(ob) { if (!attacker_ob) { attacker_ob = ob; set_heart_beat(1); return; } if (!alt_attacker_ob) { attacker_ob = ob; return; } } show_stats() { int i; write(short() + "\nlevel:\t" + level + "\ncoins:\t" + money + "\nhp:\t" + hit_point + "\nmax:\t" + max_hp + "\nspell\t" + spell_points); write("\nep:\t"); write(experience); write("\nac:\t"); write(armour_class); if (name_of_armour) write("\narmour: " + call_other(name_of_armour, "query_name", 0)); write("\nwc:\t"); write(weapon_class); if (name_of_weapon) write("\nweapon: " + call_other(name_of_weapon, "query_name", 0)); write("\ncarry:\t" + local_weight); if (attacker_ob && living(attacker_ob)) write("\nattack: " + call_other(attacker_ob, "query_name")); write("\nalign:\t" + alignment + "\n"); show_age(); } stop_wielding() { if (!name_of_weapon) { /* This should not happen ! */ log_file("wield_bug", "Weapon not wielded !\n"); write("Bug ! The weapon was marked as wielded ! (fixed)\n"); return; } call_other(name_of_weapon, "un_wield", 0); name_of_weapon = 0; weapon_class = WEAPON_CLASS_OF_HANDS; } stop_wearing() { armour_class -= call_other(name_of_armour, "armour_class", 0); call_other(name_of_armour, "un_wear", 0); name_of_armour = 0; } query_level() { return level; } /* This object is not worth anything in the shop ! */ query_value() { return 0; } /* It is never possible to pick up a player ! */ get() { return 0; } /* * Return true if there still is a fight. */ attack() { int tmp; string name_of_attacker; if (!attacker_ob) { spell_cost = 0; return 0; } name_of_attacker = call_other(attacker_ob, "query_name", 0); if (!name_of_attacker || name_of_attacker == NAME_OF_GHOST || environment(attacker_ob) != environment(this_object())) { if (!hunter && name_of_attacker && !call_other(attacker_ob, "query_ghost", 0)) { tell_object(this_object(), "You are now hunting " + call_other(attacker_ob, "query_name", 0) + ".\n"); hunted = attacker_ob; hunting_time = 10; } attacker_ob = 0; if (!alt_attacker_ob) return 0; attacker_ob = alt_attacker_ob; alt_attacker_ob = 0; if (attack()) { tell_object(this_object(), "You turn to attack " + cap_name + ".\n"); return 1; } return 0; } call_other(attacker_ob, "attacked_by", this_object()); if (spell_cost) { spell_points -= spell_cost; tell_object(attacker_ob, "You are hit by a " + spell_name + ".\n"); write("You cast a " + spell_name + ".\n"); } tmp = call_other(attacker_ob, "hit_player", random(weapon_class) + spell_dam); if (tmp == 0) { tell_object(this_object(), "You missed.\n"); say(cap_name + " missed " + name_of_attacker + ".\n"); spell_cost = 0; spell_dam = 0; return 1; } experience += tmp; tmp -= spell_dam; spell_cost = 0; spell_dam = 0; /* Does the enemy still live ? */ if (call_other(attacker_ob, "query_name", 0) != NAME_OF_GHOST) { string how, what; how = " to small fragments"; what = "massacre"; if (tmp < 30) { how = " with a bone crushing sound"; what = "smash"; } if (tmp < 20) { how = " very hard"; what = "hit"; } if (tmp < 10) { how = " hard"; what = "hit"; } if (tmp < 5) { how = ""; what = "hit"; } if (tmp < 3) { how = ""; what = "grazed"; } if (tmp == 1) { how = " in the stomach"; what = "tickled"; } tell_object(this_object(), "You " + what + " " + name_of_attacker + how + ".\n"); tell_object(attacker_ob, cap_name + " " + what + " you" + how + ".\n"); return 1; } tell_object(this_object(), "You killed " + name_of_attacker + ".\n"); attacker_ob = alt_attacker_ob; alt_attacker_ob = 0; if (attacker_ob) return 1; } query_attack() { if (attacker_ob) return 1; return 0; } drop_all_money(verbose) { object mon; if (money == 0) return; mon = clone_object("obj/money"); call_other(mon, "set_money", money); move_object(mon, environment()); if (verbose) { say(cap_name + " drops " + money + " gold coins.\n"); tell_object(this_object(), "You drop " + money + " gold coins.\n"); } money = 0; } /* Wield a weapon. */ wield(w) { if (name_of_weapon) stop_wielding(); name_of_weapon = w; weapon_class = call_other(w, "weapon_class", 0); say(cap_name + " wields " + call_other(w, "query_name", 0) + ".\n"); write("Ok.\n"); } /* Wear some armour. */ wear(a) { if (name_of_armour) stop_wearing(); name_of_armour = a; armour_class += call_other(a, "armour_class", 0); say(cap_name + " wears " + call_other(a, "query_name", 0) + ".\n"); write("Ok.\n"); } add_weight(w) { if (w + local_weight > level + 10 && level < 20) return 0; local_weight += w; return 1; } heal_self(h) { if (!h) return; hit_point += h; if (hit_point > max_hp) hit_point = max_hp; spell_points += h; if (spell_points > max_hp) spell_points = max_hp; } can_put_and_get(str) { return str != 0; } attack_object(ob) { if (call_other(ob, "query_ghost", 0)) return; set_heart_beat(1); /* For monsters, start the heart beat */ if (attacker_ob == ob) { attack(); return; } if (alt_attacker_ob == ob) { alt_attacker_ob = attacker_ob; attacker_ob = ob; attack(); return; } if (!alt_attacker_ob) alt_attacker_ob = attacker_ob; attacker_ob = ob; attack(); } query_ghost() { return ghost; } attack_object(ob) { if (call_other(ob, "query_ghost", 0)) return; if (attacker_ob == ob) { attack(); return; } if (alt_attacker_ob == ob) { alt_attacker_ob = attacker_ob; attacker_ob = ob; attack(); return; } if (!alt_attacker_ob) alt_attacker_ob = attacker_ob; attacker_ob = ob; attack(); } query_ghost() { return ghost; } zap_object(ob) { call_other(ob, "attacked_by", this_object()); say(cap_name + " summons a flash from the sky.\n"); write("You summon a flash from the sky.\n"); experience += call_other(ob, "hit_player", 100000); shout("There is a big clap of thunder.\n\n"); } missile_object(ob) { if (spell_points < 10) { write("Too low on power.\n"); return; } spell_name = "magic missile"; spell_dam = random(20); spell_cost = 10; attacker_ob = ob; } shock_object(ob) { if (spell_points < 15) { write("Too low on power.\n"); return; } spell_name = "shock"; spell_dam = random(30); spell_cost = 15; attacker_ob = ob; } fire_ball_object(ob) { if (spell_points < 20) { write("Too low on power.\n"); return; } spell_name = "fire ball"; spell_dam = random(40); spell_cost = 20; attacker_ob = ob; } /* * If no one is here (except ourself), then turn off the heart beat. */ test_if_any_here() { object ob; ob = first_inventory(environment()); while(ob) { if (!call_other(ob, "id", "name") && living(ob)) return; ob = next_inventory(ob); } set_heart_beat(0); } show_age() { int i; write("age:\t"); i = age; if (i/43200) { write(i/43200 + " days "); i = i - (i/43200)*43200; } if (i/1800) { write(i/1800 + " hours "); i = i - (i/1800)*1800; } if (i/30) { write(i/30 + " minutes "); i = i - (i/30)*30; } write(i*2 + " seconds.\n"); } stop_hunter() { hunter = 0; tell_object(this_object(), "You are no longer hunted.\n"); } force_us(cmd) { if (level >= call_other(this_player(), "query_level")) { tell_object(this_object(), call_other(this_player(), "query_name") + " tried to force you to " + cmd + ".\n"); return; } tell_object(this_object(), call_other(this_player(), "query_name") + " forced you to '" + cmd + "'.\n"); command(cmd); } /* This is used by the shop etc. */ add_money(m) { money = money + m; } query_money() { return money; } query_exp() { return experience; } query_frog() { return frog; } frog_curse(arg) { if (arg) { if (frog) return 1; tell_object(this_player(), "You turn into a frog !\n"); frog = 1; return 1; } tell_object(this_object(), "You turn HUMAN again.\n"); frog = 0; return 0; } run_away() { object here; int i, j; here = environment(); i = 0; j = random(6); while(i<6 && here == environment()) { i += 1; j += 1; if (j > 6) j = 1; if (j == 1) command("east"); if (j == 2) command("west"); if (j == 3) command("north"); if (j == 4) command("south"); if (j == 5) command("up"); if (j == 6) command("down"); } if (here == environment()) { say(cap_name + " tried, but failed to run away.\n", this_object()); tell_object(this_object(), "Your legs tried to run away, but failed.\n"); } else { tell_object(this_object(), "Your legs run away with you!\n"); } }