/* /std/germ.c * from Nightmare IV * germs which cause disease * created by Descartes of Borg to silence whining mortals 940905 */ #include <std.h> #include "germ.h" inherit OBJECT; private int __Communicable, __LifeSpan; private string __Type; static private int __LastHeartBeat, __Creation; static private function __Infect; static private mixed __Cure; void create() { Object::create(); __Creation = time(); __LastHeartBeat = time(); set_invis(1); set_mass(0); set_value(0); set_prevent_drop(""); set_prevent_get(""); set_prevent_put(""); } void init() { int x; Object::init(); if(environment(this_object()) == this_player()) return; if(query_heart_beat()) return; set_heart_beat(5); x = time() - __LastHeartBeat; __LastHeartBeat = time(); if(!__Communicable) return; x = x/5; if(x > 7) x = 7; while(x--) multiply(); } void init_args(mixed *args) { __Communicable = args[0]; __LifeSpan = args[1]; __Type = args[2]; set_heart_beat(5); } void heart_beat() { object *obs, *boo; object ob; __LastHeartBeat = time(); if(!environment(this_object())) { set_heart_beat(0); return; } if(living(environment(this_object())) && environment(environment())) { suffer(environment()); if(!environment()) { if(this_object()) this_object()->remove(); return; } if(__Communicable) multiply(); obs = all_inventory(environment(environment())) - ({environment()}); } else { if(__LastHeartBeat - __Creation > __LifeSpan) { this_object()->remove(); return; } if(!sizeof(users() & all_inventory(environment()))) { set_heart_beat(0); return; } if(__Communicable) multiply(); obs = all_inventory(environment()); } if(!__Communicable) return; if(__Communicable > random(1000)) { boo = sort_array(filter_array(obs, "filter_living", this_object()), "sort_weak", this_object()); if(sizeof(boo)) ob = obs[0]; else return; new(base_name(this_object()))->infect(ob); } } int filter_living(object ob) { return living(ob); } int sort_weak(object a, object b) { int x, y; x = (int)a->query_stats("constitution") + (int)a->query_sp(); y = (int)b->query_stats("constitution") + (int)b->query_sp(); if( x > y ) return -1; else if( y > x ) return 1; else return 0; } void multiply() { object ob; if(__Communicable > random(10000)) { ob = environment(); if(environment(ob) && random(100) > 50) ob = environment(ob); new(base_name(this_object()))->move(ob); } } int infect(object ob) { if((int)ob->resist_infection(this_object())) return 0; if(__Infect && !((*__Infect)(ob))) return 0; __Creation = time(); if(!query_heart_beat()) set_heart_beat(5); this_object()->move(ob); return 1; } int cure(int x) { if(intp(__Cure)) __Cure -= x; else if(functionp(__Cure)) { if(!((*__Cure)(x))) return 0; else __Cure = 0; } else error("Bad argument 1 to cure()."); if(__Cure > 0) return 0; this_object()->remove(); return 1; } void suffer(object ob) { } void set_communicable(int x) { if(x > 50) x = 50; __Communicable = x; } int query_communicable() { return __Communicable; } void set_cure(mixed val) { if(!intp(val) && !functionp(val)) error("Bad argument 1 to set_cure()."); __Cure = val; } mixed query_cure() { return __Cure; } void set_infect(function f) { if(!functionp(f)) error("Bad argument 1 to set_infect()."); __Infect = f; } function query_infect() { return __Infect; } void set_life_span(int x) { if(x > 600) x = 600; __LifeSpan = x; } int query_life_span() { return __LifeSpan; } void set_type(string str) { __Type = str; } string query_type() { return __Type; } mixed *query_auto_load() { return ({ base_name(this_object()), ({ __Communicable, __LifeSpan, __Type }) }); } string *query_id() { return ({ "germ" }) + Object::query_id(); } int is_germ() { return 1; }