#include <player.h> int protecting; string protector; object player; object *allowed = ({ }); void setup_shadow(object thing, object *victors) { string *bits; protector = 0; if (environment(thing)) { bits = explode(file_name(environment(thing)), "/") - ({ "", "." }); if (sizeof(bits) > 1 && bits[0] == "d") { object mast; mast = load_object(implode(bits[0..1] + ({ "master" }), "/")); if (mast) protector = mast->query_protector_string(); } } if (!protector) protector = "The Rules of Fair Play"; shadow( thing, 1 ); player = thing; protecting = 1; call_out( "dest_surrender_shadow", 60 * 5 ); allowed = victors; } int can_be_nasty() { object who; object *inv; if (!protecting) return 1; if (!environment(player)) return 1; inv = all_inventory(environment(player)); foreach (who in allowed) if (member_array(who, inv) != -1) return 0; return 1; } string query_surrender_protector() { return protector; } void zap_surrender_shadow() { protecting = 0; tell_object( player, "You lose "+ protector +"'s protection.\n" ); call_out( "dest_surrender_shadow", 1 ); } /* zap_surrender_shadow() */ int adjust_hp( int number, object thing, object weapon, string attack ) { if ( ( number > 0 ) || !protecting || !thing || !pk_check(thing, player ) || player == this_player() ) return (int)player->adjust_hp( number, thing, weapon, attack ); return (int)player->query_hp(); } /* adjust_hp() */ int set_hp( int number, object thing ) { int current; current = (int)player->query_hp(); if (number > current || !protecting || !thing) return (int)player->set_hp( number, thing ); return current; } /* set_hp() */ /* * Hopefully there's no way a PKer can call these directly... * * void do_death() { return; } * int second_life() { return 1; } */ int cannot_walk() { if (!can_be_nasty()) { notify_fail("You can't leave while your subduer is here.\n"); return 1; } zap_surrender_shadow(); return player->cannot_walk(); } int attack_by( object thing ) { if (!protecting) return (int)player->attack_by( thing ); tell_object( thing, (string)player->the_short() + " is protected from combat by "+ protector +".\n" ); tell_object( player, "You are protected from combat by "+ protector +".\n" ); thing->stop_fight( player ); return 0; } /* attack_by() */ int attack_ob( object thing ) { if (!can_be_nasty()) return 0; zap_surrender_shadow(); return (int)player->attack_ob( thing ); } /* attack_ob() */ int query_unambushable() { return 1; } void do_ambushed() { write( protector +" stops you from harming "+ (string)player->the_short() +".\n" ); tell_object( player, protector +" stops "+ (string)this_player()->the_short() +" from harming you.\n" ); } /* do_ambushed() */ int no_offense() { if (!can_be_nasty()) return 1; zap_surrender_shadow(); return (int)player->no_offense(); } /* no_offense() */ mixed query_property( string word ) { if (protecting && word == "no attack") return 1; return (mixed)player->query_property( word ); } /* query_property() */ int query_player_killer() { return 0; } int command_shadowed( string verb, string args ) { if ( member_array( verb, ({ "cast", "scathe" }) ) == -1 ) return (int)player->command_shadowed( verb, args ); if (!can_be_nasty()) return notify_fail("You can't do that while you're subdued\n"); zap_surrender_shadow(); return (int)player->command_shadowed( verb, args ); } /* command_shadowed() */ varargs int adjust_xp( int number, int shared ) { #ifdef DEBUG log_file( "PROTECTED", ctime( time() ) +": "+ (string)player->query_name() + " gained "+ number +"xp ["+ implode( map_array( previous_object( -1 ), (: file_name( $1 ) :) ), ", " ) +"]\n" ); #endif return (int)player->adjust_xp( number, shared ); } /* adjust_xp() */ varargs int add_skill_level( string skill, int lvl, mixed exp ) { string what; if ( !exp ) exp = previous_object(); if ( objectp( exp ) ) what = " from "+ file_name( exp ); else what = " for "+ exp +"xp"; #ifdef DEBUG log_file( "PROTECTED", ctime( time() ) +": "+ (string)player->query_name() + " gained "+ lvl +" in "+ skill + what +" ["+ implode( map_array( previous_object( -1 ), (: file_name( $1 ) :) ), ", " ) +"]\n" ); #endif return (int)player->add_skill_level( skill, lvl, exp ); } /* add_skill_level() */ int test_remove(object thing, int flag, mixed dest) { allowed -= ({ 0 }); if (member_array(this_player(), allowed) != -1) return 1; else return player->test_remove(thing, flag, dest); } int allowed_to_loot(object who, object obj) { if (member_array(who, allowed) != -1) { object wb; if (!obj) return 1; wb = obj->query_worn_by(); if (wb == player && player->remove_armour(obj)) return 0; return 1; } else return player->allowed_to_loot(who); } void dest_surrender_shadow() { /* When the shadow wears off, NPCs should run off to /room/rubbish */ if (!player->query_property("player")) { player->move("/room/rubbish", "", player->one_short() + " runs off to recuperate."); } else { tell_object(player, "You feel that you can leave now.\n"); } destruct(this_object()); } int query_sanctuary() { if (protecting) return 1; else return player->query_sanctuary(); } int do_quit() { if (!can_be_nasty()) { write("You cannot quit while your subduer is here.\n"); return 1; } return player->do_quit(); } int quit_alt() { if (!can_be_nasty()) { write("You cannot quit while your subduer is here.\n"); return 1; } return player->do_quit(); }