/* $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 "os.h"
#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;
}