#include <bit.h> #include <corpse.h> #include <move_failures.h> // 200/5*30 seconds == 20 minutes #define DECAY_BASE 200 #define PLAYER_DECAY_BASE 600 inherit "/std/container"; inherit "/std/living/carrying"; int decay, gender; string owner, race_ob, race_name, *bits_gone, *permitted; object weapon, *armours, *holding; void set_decay_messages(); void set_race_ob(string race_ob); int query_corpse() { return 1; } int query_decay() { return decay; } void set_decay(int dec) { decay = dec; } string query_owner() { return owner; } string *query_permitted() { return permitted; } void set_race_ob( string s) { race_ob = s; } string query_race_ob() { return race_ob; } void set_race_name(string str) { race_name = str; } string query_race_name() { return race_name; } object make_bit(string which_bit); object *make_bits(string *what_bits); void give_permission(string); void set_gender(int i) { gender = i; } int query_gender() { return gender; } string query_gender_string() { switch( gender ) { case 1: return "male"; case 2: return "female"; default: return "neuter"; } } /* query_gender_string() */ string *remove_array_parts(string *a1, string *a2) { int i; string a; if (sizeof(a2)) foreach (a in a2) { for (i=0; i<sizeof(a1); i++) { if (a == a1[i]) { a1 = delete(a1, i, 1); break; } } } return a1; } /* remove_array() */ void setup() { bits_gone = ({ }); add_property( "cureable", 1 ); add_property( "determinate", "the " ); owner = "noone"; race_name = "womble"; gender = 0; decay = DECAY_BASE; add_plural( "corpses" ); add_alias( ({ "corpse", "body", "carcass" }) ); set_name( "corpse" ); set_short( "corpse" ); set_long( "A corpse, it looks dead.\n" ); set_weight( STD_CORPSE_WEIGHT ); set_race_ob( "/std/races/unknown" ); permitted = ({ }); armours = ({ }); holding = ({ }); } /* setup() */ void give_permission( string words ) { permitted += ({ words }); } /* give_permission() */ int get(mixed dest) { if( query_property( "player" ) && dest ) { if( !TP ) return ::get(dest); if( member_array( (string)TP->query_name(), permitted ) == -1) return MOVE_INVALID_DEST; } return ::get(dest); } /* get() */ int test_remove( object thing, int flag, mixed dest ) { if( thing->query_property("my corpse") == TO ) { return 1; } if( query_property( "player" ) ) { if( !sizeof( permitted ) || !TP ) { return ::test_remove( thing, flag, dest ); } if( member_array( (string)TP->query_name(), permitted ) == -1 ) { return ::test_remove( thing, flag, dest ); } write((string)thing->the_short() +" $V$0=buzzes,buzz$V$ for a moment.\n" ); } return 1; } /* test_remove() */ string long( string words, int dark ) { if( dark == 2 || dark == -2 ) { if( query_living_contents( 0 ) != "" ) { return ::long( words, dark) + "Carrying, wearing or holding some " "things you cannot make out.\n"; } } return ::long( words, dark ) + query_living_contents( 0 ); } /* long() */ void set_owner( string words, object thing ) { string word; if( stringp( words ) ) { owner = words; } else { word = (string)thing->query_property( "determinate" ); if( stringp( word ) ) owner = word + (string)thing->short(); else owner = add_a( (string)thing->short() ); } if( thing && thing->query_property("player") ) { set_decay(PLAYER_DECAY_BASE); } set_short( "corpse of "+ owner ); add_alias( "corpse of "+ owner ); if( thing ) { if( thing->query_property("player") ) { set_main_plural( "corpses of "+ owner ); } else if ( thing->query_main_plural() ) { set_main_plural( "corpses of "+ (string)thing->query_main_plural() ); } else { set_main_plural( "corpses of "+ pluralize( (string)thing->short() ) ); } } else { set_main_plural( "corpses" ); } set_long( "This is the dead body of "+ owner +".\n" ); if( thing && thing->query_actual_weight() ) { set_weight( (int)thing->query_actual_weight() ); } else { set_weight( STD_CORPSE_WEIGHT ); } BIT_CONTROLLER->add_bit(TO); } /* set_owner() */ void do_decay() { int rate; if( !ENV(TO) ) { return; } rate = 5 + (int)(ENV(TO)->query_property("decay rate") ); if( rate > 0 ) { decay -= rate; } set_decay_messages(); } /* do_decay() */ void set_decay_messages() { if( !race_name ) { race_name = (string)race_ob->query_name(); } switch( decay ) { case 101 .. PLAYER_DECAY_BASE : break; case 51..100: if( !query_property("player") ) { set_short( "somewhat decayed remains of a corpse" ); set_short("somewhat decayed remains of "+ ( gender ? "a "+query_gender_string()+" "+race_name : add_a(race_name) ) ); set_main_plural( "somewhat decayed remains of "+ pluralize(race_name) ); } break; case 1..50: set_short("decayed remains of "+ ( gender ? "a "+query_gender_string()+" "+race_name : add_a(race_name) ) ); set_main_plural("decayed remains of "+pluralize(race_name) ); set_long("This is the dead body of "+ ( gender ? "a "+query_gender_string()+" "+race_name : add_a(race_name) )+".\n"); break; default : set_ownership( 0 ); all_inventory()->move( ENV(TO) ); move( "/room/rubbish" ); } } /* set_decay_messages() */ string query_bit_left(string s) { string *bits; bits = race_ob->query_possible_bits(s); if( !bits || !sizeof(bits) ) { return 0; } bits = remove_array_parts(bits, bits_gone); if( !sizeof(bits) ) { return 0; } return bits[0]; } /* query_bit_left() */ string *query_bit_left_pl(string s) { string *bits; bits = race_ob->query_possible_plural_bits(s); if( !bits || !sizeof(bits) ) { return 0; } bits = remove_array_parts(bits, bits_gone); if( !sizeof(bits) ) { return 0; } return bits; } /* query_bit_left() */ string *query_edible_bits_left() { string *bits; string *inedible; bits = race_ob->query_possible_bits(); inedible = race_ob->query_all_inedible(); if( !bits || !inedible ) { return ({ }); } return remove_array_parts(bits, bits_gone) - inedible; } /* query_edible_bits_left() */ varargs object *find_inv_match( string s, object looker ) { string bit, *bits; object *weap, wep; int cut; if( undefinedp( s ) ) return all_inventory(); bit = query_bit_left(s); bits = query_bit_left_pl(s); if( !bit && !sizeof(bits) ) return all_inventory(); cut = 0; if( looker ) weap = (object *)looker->query_weapons(); if( sizeof(weap) ) { foreach( wep in weap ) { if( wep->id("dagger") || wep->id("knife") ) cut = 1; } } if( bit ) { if( cut || (string)race_ob->query_pluckable(bit) ) return ({ make_bit(bit) }); if( sizeof(weap) ) { tell_object( looker, "You can only cut things from a corpse " "with a knife or dagger.\n" ); } else { tell_object( looker, "You can't cut bits from a corpse with your " "bare hands.\n" ); } return ({ }); } if( sizeof(bits) ) { if( cut ) if( sizeof(bits) > 5 ) { return make_bits(bits[0..4]); } else { return make_bits(bits); } foreach( bit in bits ) { if( !( (string)race_ob->query_pluckable(bit) ) ) bits -= ({ bit }); } if( sizeof(bits) ) if( sizeof(bits) > 5 ) { return make_bits(bits[0..4]); } else { return make_bits(bits); } if( sizeof(weap) ) { tell_object( looker, "You can only cut things from a corpse " "with a knife or dagger.\n" ); } else { tell_object( looker, "You can't cut bits from a corpse with your " "bare hands.\n" ); } return ({ }); } } /* find_inv_match() */ object make_bit(string which_bit) { mixed *bit; object bitobj; int i,j; string tempbit; bit = race_ob->query_bit(which_bit); if ((sizeof(bit[2][2]) > 1) && stringp(bit[2][2][0])) { bitobj = clone_object( bit[2][2][0] ); } else { bitobj = clone_object("/std/bit"); } bitobj->set_race_ob(race_ob); if (race_name) { bitobj->set_race_name(race_name); } else { bitobj->set_race_name(race_ob->query_name()); } bitobj->set_corpse_weight(query_weight()); if(!race_ob->query_eat(bit[BIT_NAME])) { bitobj->set_bit(bit[0], 0); } else { bitobj->set_bit(bit[0], (decay * 2) / 3); } for (i = 0; i < sizeof(bits_gone); i++) { j = member_array(bits_gone[i], bit[BIT_EXTRA]); if (j >= 0) { bitobj->add_bit_gone(bits_gone[i]); } } bits_gone += ({ bit[ BIT_NAME ] }); foreach (tempbit in bit[ BIT_EXTRA ][ 3 .. sizeof(bit[BIT_EXTRA]) ]) { if (arrayp(race_ob->query_bit( tempbit )[2][2]) && intp(race_ob->query_bit( tempbit )[2][2][1])) { for (i = 0; i < race_ob->query_bit( tempbit )[2][2][1]; i++) { bits_gone += ({ tempbit }); } } } if (which_bit == "head") { set_long(query_long() + "It is decapitated.\n"); set_short("decapitated corpse of " + owner); } if (bitobj->move(TO) != MOVE_OK) { if (ENV(TO)) { bitobj->move(ENV(TO)); } } bitobj->add_property("my corpse", TO); return bitobj; } /* make_bit() */ object *make_bits(string *what_bits) { string bit; object *bits = ({ }); foreach(bit in what_bits) { bits += ({ make_bit(bit) }); } return bits; } /* make_bits() */ string *query_bits_gone() { return bits_gone; } mixed *add_bit_gone( string bit ) { string *poss_bits, tempbit; mixed *bit_details; int i; poss_bits = remove_array_parts((string *)race_ob->query_possible_bits( bit ), bits_gone); if ( !sizeof( poss_bits ) ) return 0; bit_details = (mixed *)race_ob->query_bit( poss_bits[ 0 ] ); bits_gone += ({ bit_details[ BIT_NAME ] }); foreach (tempbit in bit_details[ BIT_EXTRA ][ 3 .. sizeof(bit_details[BIT_EXTRA]) ]) { if (arrayp(race_ob->query_bit( tempbit )[2][2]) && intp(race_ob->query_bit( tempbit )[2][2][1])) { for (i = 0; i < race_ob->query_bit( tempbit )[2][2][1]; i++) { bits_gone += ({ tempbit }); } } } return bit_details; } /* add_bit_gone() */ void set_bits_gone( string *bits ) { int i; bits_gone = ({ }); for( i = 0; i < sizeof( bits ); i++ ) add_bit_gone( bits[ i ] ); } /* set_bits_gone() */ string *query_bits_left() { int i, j; string *all_bits; mixed *bits; bits = (mixed *)race_ob->query_bits(); all_bits = ({ }); for ( i = 0; i < sizeof( bits ); i += 3 ) { if (bits[i + 2][2]) { for ( j = 0; j < bits[ i + 2][2][1]; j++ ) { all_bits += ({ bits[ i ] }); } } } return remove_array_parts(all_bits, bits_gone); } /* query_bits_left */ /* this for formatting of objects sake */ object *query_armours() { int i; armours -= ({ 0 }); for ( i = 0; i < sizeof( armours ); i++ ) { if ( (object)armours[ i ]->query_worn_by() != TO ) { armours = delete( armours, i, 1 ); i--; } } return armours + ({ }); } /* query_armours() */ object *query_wearing() { return query_armours(); } void set_armours( object *things ) { int i; armours = ({ }); for ( i = 0; i < sizeof( things ); i++ ) { if ( things[ i ]->query_no_limbs() ) { holding += ({ things[ i ] }); } else { armours += ({ things[ i ] }); } } } /* set_armours() */ void remove_armour(object arm) { armours -= ({ arm }); } object query_weapon() { return weapon; } void set_weapon(object wpn) { weapon = wpn; } void unwield_weapon(object wpn) { if(weapon == wpn) weapon = 0; } object *query_holding() { return holding; } void set_holding( object *hold ) { holding += hold; } int *set_unhold(object ob) { int pos; if ((pos = member_array(ob, holding)) == -1) { return ({ }); } if ( !ob->set_holder( 0 ) ) { return ({ }); } holding = holding - ({ ob }); return ({ pos }); } /* set_hold() */ int *set_hold(object ob, int pos) { if (member_array(ob, holding) != -1) { return ({ }); } holding += ({ ob }); return ({ pos }); } /* set_hold() */ int move_or_destruct(object dest) { if (objectp(dest)) { move_object(dest); } else { move("/room/void"); } return 1; } /* move_or_destruct() */ /* * This was added so that people dont loose stuff just in case it gets * dested for weird reasons. * Pinkfish 3rd may 1993 */ void dest_me() { mixed *xp; object ob; // This hands out the rest of the death Xp when the object is destructed // hopefully by burial or ventisepelating or whatever. xp = query_property("XP"); if(xp && sizeof(xp) == 2) { foreach(ob in xp[0]) { if(ob) ob->adjust_xp(xp[1], 1); } } BIT_CONTROLLER->remove_bit( TO ); if ( ENV(TO) ) all_inventory()->move( ENV(TO) ); ::dest_me(); } /* dest_me() */ /* * Added in save code - Tue Feb 25 00:57:06 WST 1997 * to do wombly stuff by Pinkfish. * Only does a bit of wombley stuff though. */ mapping query_static_auto_load() { return int_query_static_auto_load(); } /* query_static_auto_load() */ mapping query_dynamic_auto_load() { mapping tmp; tmp = ([ "::" : ::query_dynamic_auto_load(), "decay" : decay, "owner" : owner, "race ob" : race_ob, "race name" : race_name, "gender" : gender, "bits gone" : bits_gone, ]); return tmp; } /* query_dynamic_auto_load() */ void init_dynamic_arg(mapping map) { if (map["::"]) { ::init_dynamic_arg(map["::"]); } if (map["decay"]) { decay = map["decay"]; } if (map["owner"]) { owner = map["owner"]; } if (map["race ob"]) { race_ob = map["race ob"]; } if (map["race name"]) { race_name = map["race name"]; } if (map["gender"]) { gender = map["gender"]; } if (map["bits gone"]) { bits_gone = map["bits gone"]; } set_decay_messages(); } /* init_dynamic_arg() */ mixed *stats() { return ::stats() + ({ ({ "decay", decay, }), ({ "owner", owner, }), ({ "race ob", race_ob, }), ({ "race name", race_name, }), ({ "gender", query_gender_string(), }) }); } /* stat() */ /** * @ignore yes * This is added so that it acts like a living object and * things like non-movable signs cannot be added to it. */ int test_add(object ob, int flag) { // Allow bits in at any time... if (ob->query_bit_data()) { return 1; } return !flag; } /* test_add() */