#include "living.h" inherit "/std/living/curses"; inherit "/std/living/force"; inherit "/std/living/skills"; inherit "/std/living/money"; inherit "/std/living/spells"; inherit "/std/living/equip"; inherit "/std/living/gender"; inherit "/std/living/stats"; inherit "/std/living/carrying"; inherit "/std/living/health"; inherit "/std/container"; string msgout, msgin, mmsgout, mmsgin; int verbose, level; static mixed *it_them; static object *followers; static mixed remember_follow; mixed attack_data, attack_name; void create() { //set_weap_skill("str.melee.right.unarmed"); equip::create(); curses::create(); spells::create(); skills::create(); health::create(); enable_commands(); attack_name = ({ }); attack_data = ({ }); followers = ({ }); max_hp = 1; max_gp = 1; container::create(); it_them = ({ this_object() }); } /* create() */ void living_commands() { add_action("wield", "wield"); add_action("wear", "wear"); add_action("hold", "hold"); add_action("do_equip", "equip"); add_action("remove", "remove"); add_action("follow", "follow"); add_action("lose", "lose"); add_action("unfollow", "unfollow"); add_action("follow_dummy", "FOLLOW_DUMMY"); combat_commands(); skill_commands(); } /* living_commands() */ /* move stuff */ int test_add(object ob, int flag) { return !flag; } int test_remove(object ob, int flag) { return !flag; } static int in_move; int query_in_move() { return in_move; } /* thats it... * no need for stupid checking to see if we are attacking something in * here stuff. */ varargs mixed move_player(string dir, string dest, mixed message, object followee, mixed enter) { int i, ret, no_see; string arr, leave, ppl, my_short; object last, *ok_follow, new_env; if (!msgout) { msgout = "@$N leaves $T."; msgin = "@$N arrives from $F."; } if (!mmsgout) { mmsgout = "@$N disappears in a puff of smoke."; mmsgin = "@$N appears out of the ground."; } last = environment(); if(!this_object()->query_invis()) { my_short = (string)this_object()->short(); if(my_short) my_short = capitalize(my_short); } if(!my_short || my_short == "" || (stringp(message) && message == "none")) { no_see = 1; } else if(!dir || dir == "X") { /* we are teleporting */ leave = implode(explode(mmsgout, "$N"), my_short) + "\n"; arr = implode(explode(mmsgin, "$N"), my_short) + "\n"; } else if(!sizeof(followers) && !followee) { if (!enter || !pointerp(enter)) enter = ({ 0, "somewhere" }); if (pointerp(message)) message = message[0]; leave = implode(explode(implode(explode((message?message:msgout), "$N"), my_short), "$T"), dir)+"\n"; switch (enter[0]) { case 0 : arr = implode(explode(implode(explode(msgin, "$N"), my_short), "$F"), enter[1])+"\n"; break; case 1 : arr = implode(explode(enter[1], "$N"), my_short)+"\n"; break; } } if(arr) ret = move(dest, arr[1..1000], leave[1..1000]); else ret = move(dest); if(ret) return 0; new_env = environment(); if (interactive(this_object()) && !query_property(UNKNOWN_MOVE_PROP)) { if (verbose) { this_object()->ignore_from_history("look"); command("look"); } else { this_object()->ignore_from_history("glance"); command("glance"); } } if(!dir || dir == "X" || (!sizeof(followers) && !followee)) return 1; else if(no_see) return ({}); in_move = 1; ok_follow = ({ this_object() }); for (i=0;i<sizeof(followers);i++) { object *tmp; if (followers[i]) { if(environment(followers[i])==last && !followers[i]->query_in_move()) { tmp = (object *)followers[i]->do_follow_command(dir); followers[i]->reset_remember_follow(); if(tmp && sizeof(tmp)) { tell_object(followers[i], "You follow " + my_short + " "+dir+".\n"); ok_follow += tmp; } else { tell_object(followers[i], "You fail to follow " + my_short + " " +dir+ ".\n"); } } } else { write("One of the people following you just quit or died a horrible " "death.\n"); followers = delete(followers, i, 1); i--; } } in_move = 0; if (followee) return ok_follow; /* * Yes we have to do some silly things for multiple exit and enter * messages lest they make no sense. */ ppl = capitalize(query_multiple_short(ok_follow)); if (pointerp(message)) message = message[1]; else message = "@$N leave $T."; leave = implode(explode(implode(explode(message, "$N"), ppl), "$T"), dir) + "\n"; if (!enter || !pointerp(enter)) enter = ({ 0, "somewhere" }); switch (enter[0]) { case 0 : arr = "@" + ppl + " arrive from " + enter[1] + ".\n"; break; case 1 : arr = implode(explode(enter[2], "$N"), ppl); break; } event(last, "exit", extract(leave, 1), new_env, ok_follow); event(new_env, "enter", extract(arr, 1), last, ok_follow); if(sizeof(ok_follow) > 1) tell_object(this_object(), capitalize(query_multiple_short(ok_follow- ({ this_player() })))+" follow" + /* add 's' if only one follower */ (sizeof(ok_follow) == 2?"s":"") + " you.\n"); return ok_follow; } /* move_player() */ object *do_follow_command(string dir) { remember_follow = ({ previous_object(), dir }); this_object()->ignore_from_history("FOLLOW_DUMMY"); command("FOLLOW_DUMMY"); return remember_follow; } void reset_remember_follow() { remember_follow = 0; } int follow_dummy() { remember_follow = (object *)environment()->do_exit_command(0, remember_follow[1], this_object(), remember_follow[0]); if(remember_follow && sizeof(remember_follow)) return 1; else return 0; } int cannot_get_stuff() { return 1; } mixed *stats() { return container::stats() + ({ ({ "max_hp", max_hp }), ({ "hp", hp }), ({ "max_gp", max_gp }), ({ "gp", gp }), /* ({ "weapon", (!weapon?"(none)":(string)weapon->short()) }), */ ({ "Str", query_str() }), ({ "Int", query_int() }), ({ "Dex", query_dex() }), ({ "Con", query_con() }), ({ "Wis", query_wis() }), ({ "Cha", query_cha() }), ({ "tmp Str", query_tmp_str() }), ({ "tmp dex", query_tmp_dex() }), ({ "tmp Con", query_tmp_con() }), ({ "tmp Int", query_tmp_int() }), ({ "tmp Wis", query_tmp_wis() }), ({ "tmp Cha", query_tmp_cha() }), ({ "bonus Str", query_bonus_str() }), ({ "bonus Int", query_bonus_int() }), ({ "bonus Dex", query_bonus_dex() }), ({ "bonus Con", query_bonus_con() }), ({ "bonus Wis", query_bonus_wis() }), ({ "bonus Cha", query_bonus_cha() }), ({ "Gender", query_gender_string() }), ({ "total money", query_value() }), ({ "Exp", query_xp() }), ({ "Total xp", query_total_xp() }), }) ; /* change to + equip::stats(); */ } void dest_me() { object *ob; int i; ob = deep_inventory(this_object()); for (i=0;i<sizeof(ob);i++) ob[i]->dest_me(); container::dest_me(); } mixed *query_it_them() { return it_them; } mixed *set_it_them(mixed *i) { return (it_them = i); } int add_follower(object ob) { if (ob == this_object()) return 0; if (member_array(ob, attacker_list) != -1) return 0; if (member_array(ob, followers) == -1) followers += ({ ob }); return 1; } int remove_follower(object ob) { int i; if ((i=member_array(ob, followers)) != -1) { followers = delete(followers, i, 1); return 1; } return 0; } int attack_by(object ob) { if (member_array(ob, followers) != -1) remove_follower(ob); equip::attack_by(ob); } /* attack_by() */ int follow(string str) { int i; object *obs, *ok; string s; if (!str) { notify_fail("Syntax: follow <person>\n"); return 0; } obs = find_match(str, environment()); ok = ({ }); if (!sizeof(obs)) { notify_fail("Could not find "+str+".\n"); return 0; } for (i=0;i<sizeof(obs);i++) if (obs[i]->add_follower(this_object())) ok += obs[i..i]; if (!sizeof(ok)) { notify_fail("You can only follow living things.\n"); return 1; } write("You follow "+(s=query_multiple_short(ok))+".\n"); say(this_player()->query_cap_name()+" follows "+s+".\n", ok); ok += ({ "you" }); for (i=0;i<sizeof(ok)-1;i++) tell_object(ok[i], this_player()->query_cap_name()+ " follows "+query_multiple_short(ok - ({ ok[i] }))+".\n"); return 1; } int unfollow(string str) { int i; object *ok, *obs; string s; if (!str) { notify_fail("Syntax: unfollow <person>\n"); return 0; } obs = find_match(str, environment()); if (!sizeof(obs)) { notify_fail("I cannot find "+str+" to unfollow.\n"); return 0; } ok = ({ }); for (i=0;i<sizeof(obs);i++) if (obs[i]->remove_follower(this_player())) ok += obs[i..i]; if (!sizeof(ok)) { notify_fail("You are not following "+query_multiple_short(obs)+".\n"); return 0; } write("You stop following "+(s=query_multiple_short(ok))+".\n"); say(this_player()->query_cap_name()+" stops following "+s+".\n", ok); ok += ({ "you" }); for (i=0;i<sizeof(ok)-1;i++) tell_object(ok[i], this_player()->query_cap_name()+ " stops following "+query_multiple_short(ok - ({ ok[i] }))+".\n"); return 1; } int lose(string str) { int i; object *ok, *obs; string s; if (!str) { notify_fail("Syntax: lose <person|everyone>\n"); return 0; } if (str == "everyone") obs = followers; else obs = find_match(str, environment()); if (!sizeof(obs)) { notify_fail("I cannot find "+str+" to lose.\n"); return 0; } ok = ({ }); for (i=0;i<sizeof(obs);i++) if (remove_follower(obs[i])) ok += obs[i..i]; if (!sizeof(ok)) { notify_fail("You are not being followed by "+ query_multiple_short(obs)+".\n"); return 0; } write("You lose "+(s=query_multiple_short(ok))+".\n"); say(this_player()->query_cap_name()+" loses "+s+".\n", ok); ok += ({ "you" }); for (i=0;i<sizeof(ok)-1;i++) tell_object(ok[i], this_player()->query_cap_name()+ " loses "+query_multiple_short(ok - ({ ok[i] }))+".\n"); return 1; } /* not needed is it? void attack_by(object ob) { armor::attack_by(ob); } */ object query_current_room() { return environment(); } mixed *query_followers() { return followers; } varargs int adjust_money(mixed amt, string type) { return money::adjust_money(amt, type); } /* adjust_money() */ mixed *query_money_array() { return money::query_money_array(); } /* query_money_array() */ int query_money(string type) { return money::query_money(type); } /* query_money() */ int query_value() { return money::query_value(); } query_teleport() { if (!msgin) { return 0; } if (!mmsgin) { return 1; } }