/* $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; }