/* $Header: property.c,v 1.2 90/05/02 20:25:27 lachesis Exp $
* $Log: property.c,v $
* Revision 1.2 90/05/02 20:25:27 lachesis
* Converted gender substitution code to read properties,
* changed page to provide a message, too.
*
* Revision 1.1 90/04/21 17:21:01 lachesis
* Initial revision
*
*/
#include "copyright.h"
/* property.c
A whole new lachesis mod.
Adds property manipulation routines to TinyMUCK. */
#include "db.h"
#include "externs.h"
/* IN ALL CASES, the argument "value" is referred to only when "class" is
a NULL string. */
/* adds a new property to an object */
void
add_property(dbref player, const char *type, const char *class, int value)
{
struct plist *p, *l;
if (db[player].properties)
{
/* stick properties at the end because most frequently used ones
will be put in front. */
for (l = db[player].properties; l; l = l -> next)
{
if (!string_compare(type, l -> type))
{
if (class)
{
if (l -> class)
free((void *) l -> class);
l -> class = alloc_string(class);
}
#ifdef NUMBER_PROPS
else
l -> value = value;
#endif
return;
}
p = l;
}
p -> next = new_prop();
p = p -> next;
p -> type = alloc_string(type);
if (class)
p -> class = alloc_string(class);
#ifdef NUMBER_PROPS
else
p -> value = value;
#endif
}
else
{
/* no current property list --- create property list */
p = new_prop();
p -> type = alloc_string(type);
if (class)
p -> class = alloc_string(class);
#ifdef NUMBER_PROPS
else
p -> value = value;
#endif
db[player].properties = p;
}
}
/* removes property list --- if it's not there then ignore */
void
remove_property(dbref player, const char *type)
{
struct plist *last, *curr;
for (last = curr = db[player].properties; curr; curr = curr -> next)
{
if (!string_compare(curr -> type, type))
{
if (db[player].properties == curr)
db[player].properties = curr -> next;
else
last -> next = curr -> next;
free_prop(curr);
}
last = curr;
}
}
/* checks if object has property, returning 1 if it or any of it's contents has
the property stated */
int
has_property(dbref player, const char *type, const char *class, int value)
{
dbref things;
if (has_property_strict(player, type, class, value))
return 1;
for (things = db[player].contents; things != NOTHING; things = db[things].next)
if (has_property_strict(things, type, class, value))
return 1;
return 0;
}
/* checks if object has property, returning 1 if it has the property asked for */
int
has_property_strict(dbref player, const char *type, const char *class, int value)
{
struct plist *p;
for (p = db[player].properties; p; p = p -> next)
if (!string_compare(type, p -> type))
{
if (p -> class && class)
return (!string_compare(class, p -> class));
#ifdef NUMBER_PROPS
else
return (value == p -> value);
#endif
}
return 0;
}
/* return class of property */
const char *
get_property_class(dbref player, const char *type)
{
struct plist *p;
for (p = db[player].properties; p; p = p -> next)
if (!string_compare(type, p -> type))
return(p -> class);
return 0;
}
#ifdef NUMBER_PROPS
/* return value of property */
int
get_property_value(dbref player, const char *type)
{
struct plist *p;
for (p = db[player].properties; p; p = p -> next)
if (!string_compare(type, p -> type))
return p -> value;
return 0; /* I guess this is as good as any other.. */
}
#endif /* NUMBER_PROPS */
#ifdef GENDER
/* return old gender values for pronoun substitution code */
int
genderof(dbref player)
{
if (has_property_strict(player, "sex", "male", 0))
return GENDER_MALE;
else if (has_property_strict(player, "sex", "female", 0))
return GENDER_FEMALE;
else if (has_property_strict(player, "sex", "neuter", 0))
return GENDER_NEUTER;
else
return GENDER_UNASSIGNED;
}
#endif /* GENDER */
char *
get_string(const char *s)
{
char *n;
n = (char *) malloc(strlen(s) + 1);
*n = '\0';
if (!n)
abort();
strcpy(n, s);
return n;
}