nightmare4_fluffos_v1/
nightmare4_fluffos_v1/bin/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/ChangeLog.old/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/Win32/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/compat/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/compat/simuls/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/include/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/clone/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/command/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/data/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/etc/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/include/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/inherit/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/inherit/master/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/log/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/single/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/single/tests/compiler/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/single/tests/efuns/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/single/tests/operators/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/testsuite/u/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/tmp/
nightmare4_fluffos_v1/fluffos-2.9-ds2.14/windows/
nightmare4_fluffos_v1/lib/cfg/
nightmare4_fluffos_v1/lib/cmds/admins/
nightmare4_fluffos_v1/lib/cmds/common/
nightmare4_fluffos_v1/lib/cmds/creators/include/
nightmare4_fluffos_v1/lib/cmds/creators/include/SCCS/
nightmare4_fluffos_v1/lib/cmds/hm/
nightmare4_fluffos_v1/lib/daemon/services/
nightmare4_fluffos_v1/lib/doc/
nightmare4_fluffos_v1/lib/doc/faq/
nightmare4_fluffos_v1/lib/doc/help/classes/
nightmare4_fluffos_v1/lib/doc/help/creators/
nightmare4_fluffos_v1/lib/doc/help/hm/
nightmare4_fluffos_v1/lib/doc/help/players/
nightmare4_fluffos_v1/lib/doc/help/races/
nightmare4_fluffos_v1/lib/doc/help/religion/
nightmare4_fluffos_v1/lib/doc/mudlib/
nightmare4_fluffos_v1/lib/doc/mudlib/cfg/
nightmare4_fluffos_v1/lib/domains/Ylsrim/
nightmare4_fluffos_v1/lib/domains/Ylsrim/adm/
nightmare4_fluffos_v1/lib/domains/Ylsrim/armour/
nightmare4_fluffos_v1/lib/domains/Ylsrim/fish/
nightmare4_fluffos_v1/lib/domains/Ylsrim/meal/
nightmare4_fluffos_v1/lib/domains/Ylsrim/npc/
nightmare4_fluffos_v1/lib/domains/Ylsrim/virtual/
nightmare4_fluffos_v1/lib/domains/Ylsrim/weapon/
nightmare4_fluffos_v1/lib/domains/Ylsrim/xtra/
nightmare4_fluffos_v1/lib/lib/comp/
nightmare4_fluffos_v1/lib/lib/lvs/
nightmare4_fluffos_v1/lib/lib/std/
nightmare4_fluffos_v1/lib/lib/user/
nightmare4_fluffos_v1/lib/news/
nightmare4_fluffos_v1/lib/obj/
nightmare4_fluffos_v1/lib/obj/include/
nightmare4_fluffos_v1/lib/save/
nightmare4_fluffos_v1/lib/save/kills/a/
nightmare4_fluffos_v1/lib/save/kills/b/
nightmare4_fluffos_v1/lib/save/kills/f/
nightmare4_fluffos_v1/lib/save/kills/m/
nightmare4_fluffos_v1/lib/save/kills/q/
nightmare4_fluffos_v1/lib/save/kills/r/
nightmare4_fluffos_v1/lib/secure/cfg/
nightmare4_fluffos_v1/lib/secure/cfg/classes/
nightmare4_fluffos_v1/lib/secure/cfg/races/SCCS/
nightmare4_fluffos_v1/lib/secure/cmds/creators/include/
nightmare4_fluffos_v1/lib/secure/cmds/players/
nightmare4_fluffos_v1/lib/secure/cmds/players/include/
nightmare4_fluffos_v1/lib/secure/daemon/include/
nightmare4_fluffos_v1/lib/secure/lib/
nightmare4_fluffos_v1/lib/secure/lib/include/
nightmare4_fluffos_v1/lib/secure/lib/net/
nightmare4_fluffos_v1/lib/secure/lib/std/
nightmare4_fluffos_v1/lib/secure/obj/
nightmare4_fluffos_v1/lib/secure/obj/include/
nightmare4_fluffos_v1/lib/secure/save/
nightmare4_fluffos_v1/lib/secure/save/boards/
nightmare4_fluffos_v1/lib/secure/save/votes/
nightmare4_fluffos_v1/lib/spells/
nightmare4_fluffos_v1/lib/verbs/admins/include/
nightmare4_fluffos_v1/lib/verbs/common/
nightmare4_fluffos_v1/lib/verbs/common/include/
nightmare4_fluffos_v1/lib/verbs/creators/
nightmare4_fluffos_v1/lib/verbs/creators/include/
nightmare4_fluffos_v1/lib/verbs/players/include/SCCS/
nightmare4_fluffos_v1/lib/verbs/rooms/
nightmare4_fluffos_v1/lib/verbs/rooms/include/
nightmare4_fluffos_v1/lib/www/
nightmare4_fluffos_v1/old/
nightmare4_fluffos_v1/old/tools/
nightmare4_fluffos_v1/win32/
/*    /lib/germ.c
 *    From the Nightmare IV Object Library
 *    Germs which cause disease
 *    created by Descartes of Borg 940905
 *    Version: @(#) germ.c 1.12@(#)
 *    Last modified: 97/01/01
 */

#include <lib.h>

inherit LIB_ITEM;

private int             Communicable  = 1;
private static mixed    Cure          = 0;
private static function Infect        = 0;
private static int      LastHeartBeat = time();
private int             LifeSpan      = 60;
private string          Type          = "cold";

mixed eventMultiply();

/* ***************  /lib/germ.c data functions  *************** */
int isGerm() {
    return 1;
}

int GetCommunicable() {
    return Communicable;
}

/*
 * int SetCommunicable(int x);
 * int x - how infectious the germ is
 *
 * description:
 * Makes the germ multiply and infect on its own.  The more
 * communicable, the easier it infects hosts and the easier
 * it multiplies.
 * Non-communicable germs must be forced to infect hosts
 *
 * returns the degree to which it is communicable
 */
int SetCommunicable(int x) {
    if( x > 50 ) x = 50;
    return (Communicable = x);
}

mixed GetCure() {
    return Cure;
}

/* mixed SetCure(mixed val) 
 * mixed val - function to test whether germ is cured 
 *             or int indicating how hard it is to cure
 *             -1 means incurable
 *
 * description
 * If a function, then that function will be used to 
 * determine if a given cure attempt is successful.
 * That function should return 1 for success, 0 for failure
 * If an int and -1, the germ is incurable
 * If an int > 0, then that much of a cure of the right
 * type is needed to cure the disease
 *
 * returns the successfully set value
 */
mixed SetCure(mixed val) {
    return (Cure = val);
}

string array GetId() {
    return ({ item::GetId()..., "germ" });
}

function GetInfect() {
    return Infect;
}

/* function SetInfect(function f)
 * function f - Function to be called whenever this germ
 *              infects a host
 *
 * Sets a function to be called whenever a host is infected
 *
 * returns the function to be called
 */
function SetInfect(function f) {
    return (Infect = f);
}

int GetLifeSpan() {
    return LifeSpan;
}

/* int SetLifeSpan(int x)
 * int x - the length of time the germ can live outside
 *         a host
 * 
 * description
 * Sets the amount of time that can pass for the germ
 * to exist without a host
 *
 * returns the new life span
 */
int SetLifeSpan(int x) {
    if( x > 600 ) x = 600;
    return (LifeSpan = x);
}

string GetType() {
    return Type;
}

/* string SetType(string type)
 * string type - the nature of the infection
 *
 * description
 * determines what sort of cure is needed
 * valid values are:
 *     viral
 *     bacterial
 *
 * returns the new germ type
 */
string SetType(string type) {
    return (Type = type);
}

/* ***************  /lib/germ.c events  *************** */
/**
 * This event is triggered from within the player object by some
 * attempt by a cleric or other some such thing to cure the player.
 */
mixed eventCure(object who, int x, string type) {
    if( type != GetType() ) { // Can't cure this
	return 0;
    }
    if( Cure == -1 ) { // This is incureable
	return 0;
    }
    if( functionp(Cure) ) {
	mixed tmp = evaluate(Cure, who, x, type);
	
	if( tmp != 1 ) {
	    return tmp;
	}
	Cure = 0;
    }
    else if( intp(Cure) ) {
	Cure -= x;
    }
    else {
	error("Bad argument 2 to eventCure().");
    }
    if( Cure > 0 ) {
	return 0;
    }
    set_heart_beat(0);
    Destruct();
    return 1;
}

mixed eventEncounter(object who) {
    if( !living(who) ) {
	return 1;
    }
    if( !query_heart_beat() ) {
	eventMultiply();
	set_heart_beat(5);
    }
    return 1;
}

mixed eventInfect(object ob) {
    mixed tmp;
    
    if( functionp(Infect) ) {
	tmp = evaluate(Infect, ob);
	if( tmp != 1 ) {
	    Destruct();
	    return tmp;
	}
    }
    if( !query_heart_beat() ) {
	set_heart_beat(5);
    }
    eventMove(ob);
    return 1;
}

mixed eventMultiply() {
    object ob;

    if( Communicable > random(3000) ) {
	object array germs = filter(deep_inventory(environment()),
				    (: $1->isGerm() :));
	object germ;

	if( sizeof(germs) > 5 ) {
	    return 0;
	}
	germ = new(base_name(this_object()));
	if( !germ ) {
	    return 0;
	}
        if( (ob = environment()) && random(100) > 50 ) {
	    ob = (environment(ob) || ob);
	}
	if( living(ob) ) {
	    if( ob->eventInfect(germ) != 1 ) {
		germ->eventDestruct();
	    }
	}
	else {
	    germ->eventMove(ob);
	}
        return 1;
    }
    return 0;
}

void eventSuffer(object ob) {
}
   
/* ***************  /lib/germ.c driver applies  *************** */

static void create() {
    AddSave(({ "Communicable", "LifeSpan", "Type" }));
    item::create();
    SetInvis(1);
    SetMass(0);
    SetValue(0);
    SetPreventDrop("");
    SetPreventGet("");
    SetPreventPut("");
    call_out(function() { // Start up the HB if cloned into living thing
	         object env = environment();

		 if( !env || !living(env) ) {
		     return;
		 }
		 set_heart_beat(5);
             }, 2);
}

static void heart_beat() {
    object array victims;
    object env = environment();
    int interval;

    interval = time() - LastHeartBeat;
    LastHeartBeat = time();
    if( !env ) {
	set_heart_beat(0);
	if( clonep() ) {
	    Destruct();
	}
	return;
    }
    if( living(env) && environment(env) ) {
        eventSuffer(env);
	if( !this_object() ) {
	    return;
	}
        if( !env ) {
	    if( this_object() ) {
		Destruct();
	    }
            return;
        }
        if( Communicable ) {
	    eventMultiply();
	}
        victims = filter(all_inventory(environment(env)),
			 (: living :)) - ({ env });
    }
    else {
        LifeSpan -= interval;
        if( LifeSpan < 1 ) {
            Destruct();
            return;
        }
        victims = filter(all_inventory(env), (: living :));
        if( !sizeof(victims) ) {
            set_heart_beat(0);
            return;
        }
        if( Communicable ) {
	    eventMultiply();
	}
    }
    if( Communicable > random(1000) ) {
	object target, germ;
	
	victims = sort_array(victims,
			     function(object one, object two) {
	                         if( one->GetHealthPoints() >
				     two->GetHealthPoints() ) {
				     return -1;
				 }
				 else {
				     return 1;
				 }
	                     });
        if( sizeof(victims) ) {
	    target = victims[0];
	}
        else {
	    return;
	}
	germ = new(base_name(this_object()));
	if( germ ) {
	    if( target->eventInfect(germ) != 1 ) {
		germ->eventDestruct();
	    }
	}
    }
}