/* * MusicMUD Daemon, version 1.0 * Copyright (C) 1999-2003 Abigail Brady * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, writ<e to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <string.h> #include <ctype.h> #include <unistd.h> #include "musicmud.h" #include "misc.h" #include "util.h" #include "rooms.h" #include "Player.h" #include "events.h" #include "trap.h" #include "pflags.h" #include "death.h" #include "Mission.h" #include "zoneload.h" #include "msi.h" #include "paths.h" #include "privs.h" #include "vsprintf.h" #include "prep.h" #include "units.h" #include "shared.h" #include "musictok.h" #include "format.h" #include "pos.h" #include "body.h" #include "levels.h" #include "nations.h" void restore_stuff(MudObject *who) { string corpseid = "@auto_"; corpseid += who->id; MudObject *what = planet->get(corpseid.c_str()); if (!what) { return; } World<MudObject> b = *who->children; MudObject *o; int i; foreach((&b), o, i) { o->reset(); } World<MudObject> a = *what->children; foreach((&a), o, i) { set_owner(o, who); if (o->get_object("$unreal_wornby")) { o->set("$wornby", o->get("$unreal_wornby")); } if (MudObject *p=o->get_object("$unreal_wieldby")) { p->set(KEY_WIELD, o->id); } } moveallcash(what, who); set_owner(who, what->owner); rectify_state(who); vanish(what); } int canwalk(MudObject *what) { if (what->get_flag(FL_CANTWALK)) return 0; return 1; } int canswim(MudObject *what) { if (wf_wears_with_flag(what, FL_GILLS) || what->get_flag(FL_CANFLOAT)) return 1; return 0; } MudObject *mount(MudObject *who) { MudObject *m = who->get_object("$mount"); if (!m) return 0; if (m->owner == who->owner || m->owner == who) return m; who->unset("$mount"); return 0; } string capitalise(string what) { string what2; what2 = what; what2[0] = toupper(what2[0]); return what; } void handle_auto(MudObject *o, int rec); MudObject *clone_object(MudObject *what, MudObject *where, const char *newname, int flags, const char *zone) { if (!what) return 0; string name = newname?:get_clone_name().c_str(); MudObject *thing = new MudObject(name.c_str()); thing->clone(what); planet->add(*thing); set_owner(thing, where); thing->set(KEY_STATE, what->get_int(KEY_STATE, 0)); if (thing->id[0]=='@') thing->set_flag(FL_DESTROYONRESET, 1); if (!thing->get("cloneof")) thing->set("cloneof", what->id); if (!thing->get("treatas")) thing->set("treatas", what->id); if (!zone) zone = "@auto"; thing->set("zone", zone); if (flags & 1) { handle_auto(thing, 1); } return thing; } const char*get_wierd() { return "You can't do that."; } bool is_in(MudObject *child, MudObject *parent) { if (parent==child) return true; if (!child->owner) return false; if (parent == child->owner) return true; if (is_in(child->owner, parent)) return true; return false; } int isnighthour(int i) { if (i >= 20) return 1; if (i <= 4) return 1; return 0; } bool is_dark(MudObject *o) { while (o) { if (o->get_flag(FL_DARK)) return 1; if (o->get_flag(FL_OUTDOORS) && isnighthour(mudtime(o).hour)) return 1; o = o->owner; } return 0; } bool has_light(MudObject *where, bool def) { Object *obj; int i; if (!where) return false; MudObject *w2 = where->owner; if (w2) { if (is_lit(w2)) return true; MudObject *w3 = w2->owner; if (w3 && is_lit(w3)) return true; } if (is_lit(where)) return true; if (where->get_flag(FL_LIT) || where->get_flag(FL_ONFIRE)) return true; foreach(where->children, obj, i) { if (has_light((MudObject *)obj, false)) return true; } if (is_dark(where)) return false; return def; } void set_mass_capacity(MudObject *what, int grams) { what->unset("capacity"); what->set("maxload", grams); } int mass_in_grams(MudObject *where, bool recurse) { int used = 0; if (recurse) { MudObject *o; int i; foreach(where->children, o, i) { used += mass_in_grams(o, recurse); } } if (where->get_int("mass")!=-1) return where->get_int("mass") + used; if (where->get_int("size")!=-1) return where->get_int("size") * HECTOGRAM + used; return used; } int mass_used_in_grams(MudObject *where) { int used = 0, i; MudObject *o; foreach(where->children, o, i) { used += mass_in_grams(o, 1); } return used; } int mass_capacity_uncorrected_in_grams(MudObject *where, int def) { int ml = where->get_int("maxload"); int cp = where->get_int("capacity"); if (ml != -1) { return ml; } if (cp != -1) { return cp * HECTOGRAM; } return def==-1?SIZE_INFINITE:def; } int mass_capacity_in_grams(MudObject *where, int def) { const char *grav=get_zoneprop(where, "gravity"); if (!grav) grav = "1.0"; int c = mass_capacity_uncorrected_in_grams(where, def); if (c == SIZE_INFINITE) return c; double d = atof(grav); if (d==0) return SIZE_INFINITE; d = c / d; return (int)d; } int mass_capacity_left_in_grams(MudObject *where) { if (mass_capacity_in_grams(where)==-1) return SIZE_INFINITE; return mass_capacity_in_grams(where) - mass_used_in_grams(where); } int object_value(MudObject *what) { int value = what->get_int("value"); int cost = what->get_int("cost", 0); if (value == -1) { if (cost > 0 && cost < 10) return cost - 1; return cost * 9 / 10; } return value; } bool player_exist(const char *name) { if (!name || !*name) return false; if (strchr(name, '/')) return false; if (strchr(name, '.')) return false; struct stat who; char buffer[1024]; sprintf(buffer, DATA_USERS "/%s", name); int rval = stat(buffer, &who); return rval==0; } int parmour( MudObject * which ) { int armour = which->get_int("armour"); if (armour==-1) return 0; return armour; } bool iswornby(const MudObject *what, const MudObject *who) { if (what->owner != who) return false; return streq(what->get(KEY_WORNBY), who->id); } bool iswieldedby(MudObject *what, MudObject *who) { const char *wield = who->get(KEY_WIELD); if (!wield) return false; MudObject *wielded = planet->get(wield); if (!wielded) return false; if (wielded->owner != who) return false; if (wielded->owner == who && what == wielded) return true; return false; } int player_armour(MudObject *who) { MudObject *o; int i; int armour = 0; foreach(who->children, o, i) { int arm = o->get_int("armour"); if (iswornby(o, who) && arm > 0) armour += arm; } return armour; } MudObject *getzone(const char *zonestr) { return planet->get(ssprintf("%s_zone", zonestr).c_str()); } bool permitted_access(MudObject *who, const char *inwhat) { if (!inwhat) return 1; char owners[4096]; strcpy(owners, inwhat); char *user = strtok(owners, ","); while (user) { if (strcasecmp(user, who->id)==0) { return true; } user = strtok(0, ","); } return false; } bool permitted_access(const char *id, const char *inwhat) { if (!inwhat) return 1; char owners[4096]; strcpy(owners, inwhat); char *user = strtok(owners, ","); while (user) { if (strcasecmp(user, id)==0) { return true; } user = strtok(0, ","); } return false; } const char *uninvite(const char *id, const char *inwhat) { if (!inwhat) return ""; char owners[4096]; static char newlist[4096]; newlist[0] = 0; int i = 0; strcpy(owners, inwhat); char *user = strtok(owners, ","); while (user) { if (strcasecmp(user, id)!=0) { if (i) strcat(newlist, ","); else i = 1; strcat(newlist, user); } user = strtok(0, ","); } return newlist; } MudObject *find_free_quarters(MudObject *q) { int l = q->array_size("room"); int i; MudObject *free = 0; for (i=0;i<l;i++) { MudObject *q2 = q->array_get_object("room", i); if (q2) { if (q2->get("$player") || q2->get_flag(FL_PRIVATE)) { } else { if (!free) free = q2; } } } return free; } MudObject *quarters(MudObject *who) { MudObject *q = who->get_object("quarters"); if (!q) return 0; if (q->get_object("$player") != who) { who->unset("quarters"); return 0; } return q; } bool cantouch_zone(const MudObject *who, const char *zonestr) { if (who->get_priv(PFL_EDITALL)) { return true; } if (!zonestr) { return who->get_priv(PFL_MAKE); } MudObject *zone = getzone(zonestr); if (!zone) { return false; } if (zone) { const char *author = zone->get("author"); if (!author) { return who->get_priv(PFL_MAKE); } char owners[4096]; strcpy(owners, author); char *user = strtok(owners, ","); while (user) { if (streq(user, who->id)) { return true; } user = strtok(0, ","); } } return false; } bool can_affect(const MudObject *who, const char *zonestr) { if (privs_of(who)>= LEV_COMMODORE) return true; if (!zonestr) return false; if (!strncmp(zonestr, "@ship", 5)) { return 1; } char zoneobj_name[256]; sprintf(zoneobj_name, "%s_zone", zonestr); MudObject *zone = planet->get(zoneobj_name); if (!zone) { if (!strncmp(zonestr, "@auto_", 6)) return true; else return false; } if (zone->get_flag(FL_PRIVATE)) return cantouch_zone(who, zonestr); MudObject *q = zone->get_object("quest"); if (!q) return true; const char *quest2 = zone->get("quest2"); if (quest_done(who, q) && !quest2) return true; MudObject *q2 = planet->get(quest2); if (!quest_done(who, q) && !quest2) return false; if (quest_done(who, q2)) return true; return false; } string bw_name(MudObject *who) { return lose_colour(name(who)?:""); } int players_in(MudObject *where) { int i; MudObject *o; int players = 0; foreach(where->children, o, i) { if (is_player(o)) players++; } return players; } bool player_owns_with(MudObject *who, Flag flag) { if (flag==FL_NONE) return true; MudObject *o; int i; foreach(who->children, o, i) { if (o->get_flag(flag)) return true; } return false; } bool trigger_mobiles(MudObject *where, MudObject *who, MudObject *which, int incombat) { MudObject *o; int i; const char *dir = which->get("short"); foreach(where->children, o, i) { if (o!=who && o!=which) { int bar = 0; if (o->get_flag(FL_REFUSEMOVE)) bar = 1; if (o->get_flag(FL_MOBILE)) { if ((streq(dir, "south") && o->get_flag(FL_BARSOUTH)) || (streq(dir, "north") && o->get_flag(FL_BARNORTH)) || (streq(dir, "east") && o->get_flag(FL_BAREAST)) || (streq(dir, "west") && o->get_flag(FL_BARWEST)) || (streq(dir, "up") && o->get_flag(FL_BARUP)) || (streq(dir, "down") && o->get_flag(FL_BARDOWN))) bar =1 ; } if (!bar) continue; if (const char *ap=o->get("allowpast")) { if (streq(ap, who->get("nation"))) continue; MudObject *bl = block(who); if (bl && streq(bl->get("nation"), ap)) continue; } if (!incombat && dotrap(E_BEFOREBAR, who, o, which->get_object("link"))) continue; /* ::: before_bar o1==barrer, o2==new room; if return 1 then we won't bar, otherwise we will. */ if (!o->get_object("_fighting") || o->get_object("_fighting")==who) { who->printf("%#M %[stops/stop] you from going ^d%s^n.\n", o, which->get("short")); who->oprintf(avoid(o) && cansee, "%#M %[stops/stop] %M from going ^d%s^n.\n", o, who, which->get("short")); dotrap(E_AFTERBAR, who, o, which->get_object("link")); /* ::: after_bar o1==barrer, o2==new room; after the %M stops %m from going %s message. */ if (o->get("barwhy")) { o->interpret(o->get("barwhy")); } return false; } } } return true; } bool spare_people_capacity(MudObject *dest) { if (dest->get_flag(FL_ONEPERSON) && players_in(dest)>=1) return false; if (dest->get_flag(FL_TWOPERSON) && players_in(dest)>=2) return false; return true; } bool dryland(MudObject *where) { if (where->get_flag(FL_ONWATER) || where->get_flag(FL_UNDERWATER) || where->get_flag(FL_BYWATER)) return false; return true; } bool inwater(MudObject *where) { if (where->get_flag(FL_ONWATER) || where->get_flag(FL_UNDERWATER)) return true; return false; } int level_of(const MudObject *who) { int a = who->get_int("privs"), b = who->get_int("level"); if (a > b) return a; return b; } int player_rank(const void *first, const void *second) { Player *a = *((Player **)first); Player *b = *((Player **)second); int p1 = level_of(a); int p2 = level_of(b); if (p1>p2) return -1; if (p1==p2) return strcmp(a->id, b->id); return 1; } const char *is_are(MudObject *w) { return w->get_flag(FL_PLURAL) ? "are" : "is"; } const char *it_them(MudObject *w) { return w->get_flag(FL_PLURAL) ? "them" : "it"; } const char *it_they(MudObject *w) { return w->get_flag(FL_PLURAL) ? "they" : "it"; } bool has_pass(MudObject*who) { if (!who) return false; if (!who->get_flag(FL_LOGGEDIN)) return false; if (who->get_flag(FL_MAGICPASS)) return true; MudObject *o; int i; foreach(who->children, o, i) { if (o->get_flag(FL_MAGICPASS)) { return true; } } return false; } void broadcast(const showto &s, const char *txt, PRINT_PARMS) { PARMS p = GET_PARMS(); iforeach(o, *players) if (o->get_flag(FL_LOGGEDIN) && s(o)) o->real_printf(txt, p); } void broadcast(const char *txt, PRINT_PARMS) { PARMS p = GET_PARMS(); iforeach(o, *players) if (o->get_flag(FL_LOGGEDIN)) o->real_printf(txt, p); } string get_clone_name() { while (1) { static int object_id = 0; string name = ssprintf("@auto_%06i", object_id); object_id++; if (!planet->get(name.c_str())) { return name; } } } string random_firstname() { return (random_number(2) ? random_male:random_female)(); } string random_shipname() { string buffer; switch (random_number(4)) { case 0 : buffer += "Pride of "; goto placename; break; case 1 : buffer += "Spirit of "; goto placename; break; case 2 : buffer += "SS "; goto placename; break; case 3 : buffer += "SS Saint "; goto firstname; break; } firstname: buffer += random_firstname(); return buffer; placename: buffer += random_placename(); return buffer; } /* the noun */ /* the adjective noun */ void name_mobile(MudObject *who) { bool male = random_number(2); string first = (male ? random_male : random_female)(); string surname = random_surname(); string full = (string)"^P" + first + " " + surname + "^n"; who->set("short", first); who->set("name", full); who->set("forename", first); who->set("surname", surname); who->set("gender", male ? "male" : "female"); } void add_storeable_eq(MudObject *what, NewWorld &coll) { MudObject *o; int i; foreach(what->children, o, i) { if (o->get_flag(FL_QUARTERS)) continue; MudObject *clo = o->get_object("cloneof"); if (!is_mobile(o) && !is_player(o)) { add_storeable_eq(o, coll); } if (o->get_flag(FL_NOSAVE)) continue; if (o->mission) continue; if (!clo) continue; coll.add(*o); } } void save_var_zone(const char *zone); void save_var_data() { MudObject *o; int i; foreach(zones, o, i) if (o->id[0]!='@') { save_var_zone(o->id); } save_var_zone("@space"); unlink(VARDATA"/var"); FILE *f = xopen_tmp(STADATA, "mudconf", "w"); if (f) { mud->save_var(f); xclose_confirm(f, STADATA, "mudconf"); } } void save_var_zone(const char *zone) { FILE *f = xopen_tmp(VARVAR, zone, "w"); if (!f) return; MudObject *o; int i; NewWorld stuff; foreach(zones->get(zone)->children, o, i) { if (!is_player(o)) { o->save_var(f); } if (o->get_flag(FL_QUARTERS)) { add_storeable_eq(o, stuff); } MudObject *p; int j; foreach(o->children, p, j) { int la = 0; if (MUD_COMATOSE && p->get_object("cloneof") == MUD_COMATOSE) { if (!stuff.get(p->id)) { stuff.add(*p); p->set("$keepid", p->id); la = 1; } } if (streq(p->get("cloneof"), "template_4")) { if (!stuff.get(p->id)) { stuff.add(*p); la = 1; } p->set("$keepid", p->id); p->set("$keepat", p->get("$lastdock")); } if (p->get_flag(FL_QUARTERS)) { la = 1; } } } foreach(&stuff, o, i) { o->set("!id", i); } foreach(&stuff, o, i) { fprintf(f, "cloneof %s {\n", o->get("cloneof")); fprintf(f, "int !id %i\n", o->get_int("!id")); if (streq(o->get("zone"), "@ship")) { o->set("$keepid", o->id); } if (o->owner) { int i = o->owner->get_int("!id"); if (i != -1) { fprintf(f, "int !inid %i\n", i); } else { fprintf(f, "string owner \"%s\"\n", o->owner->id); } } o->save_difference(f, o->get_object("cloneof")); fprintf(f, "}\n"); } foreach(&stuff, o, i) { o->unset("!id"); } xclose_confirm(f, VARVAR, zone); } void load_var_data(FILE *f); void load_var_data(const char *p, const char *a) { FILE *f = xopen(p, a, "r"); if (!f) return; load_var_data(f); xclose(f); } void load_var_data() { load_var_data(VARDATA, "var"); MudObject *o; int i; foreach(zones, o, i) if (o->id[0]!='@') { load_var_data(VARVAR, o->id); } load_var_data(VARVAR, "@space"); load_var_data(STADATA, "mudconf"); } void load_var_data(FILE *f) { char buffer[4096]; if (!f) return; NewWorld eq; while (!feof(f)) { strcpy(buffer, getline(f).c_str()); if (feof(f)) break; if (strncmp(buffer, "vardata ", 8)==0) { char *ptr = strchr(buffer, '"')+1; char *ptr2 = strchr(ptr, '"'); *ptr2 = 0; ptr2++; MudObject *ob = planet->get(ptr); string buf; while (buf != "}") { buf = getproperty(f); if (feof(f)) break; if (ob) ob->load(buf.c_str()); } } else if (strncmp(buffer, "cloneof ", 8)==0) { char *b = strchr(buffer, ' '); if (b) b++; { char *a = strchr(b, ' '); if (a) *a = 0; } MudObject *k = 0; if (b) k = clone_object(planet->get(b), mud, NULL); if (!k) break; k->set("zone", "@auto"); eq.add(k); string buf; while (buf != "}") { buf = getproperty(f); if (feof(f)) break; k->load(buf.c_str()); } if (k->get_object("$keepat")) { k->set("$lastdock", k->get("$keepat")); set_owner(k, "space"); k->unset("$keepat"); } if (const char *ki=k->get("$keepid")) { if (planet->get(ki)) k->nuke_me = 1; else k->set("id", ki); } } } MudObject *o; int i; foreach(&eq, o, i) { int i2 = o->get_int("!inid"); if (i2 != -1) { MudObject *m; int j; foreach(&eq, m, j) { if (m->get_int("!id")==i2) { set_owner(o, m); continue; } } } } foreach(&eq, o, i) { o->unset("!inid"); o->unset("!id"); } return; } int holds_flagged_object(MudObject *who, Flag flag) { if (!who) return 0; if (who->get_flag(flag)) return 1; int i; MudObject *o; foreach(who->children, o, i) { int j = holds_flagged_object(o, flag); if (j) return j+1; } return 0; } MudObject *get_flagged_object(MudObject *who, Flag flag) { if (!who) return 0; if (who->get_flag(flag)) return who; MudObject *o; int i; foreach(who->children, o, i) { MudObject *j = get_flagged_object(o, flag); if (j) return j; } return 0; } MudObject *holds_clone_of(MudObject *who, MudObject *what) { if (!who || !what) return 0; if (who->get_object("cloneof")==what) return who; int i; MudObject *o; foreach(who->children, o, i) { MudObject *j = holds_clone_of(o, what); if (j) return j; } return 0; } void holset(MudObject *who, int which, int what) { int holo = who->get_int("holodone", 0); holo &= ~(1 << which); if (what) holo |= (1 << which); who->set("holodone", holo); } void vanish(MudObject *what) { if (is_player(what)) { set_owner(what, MUD_PLAYERHEAVEN); return; } set_owner(what, "empty"); if (is_mission(what)) { set_owner(what, "@musicmud"); what->unset(KEY_ACCEPTER); return; } if (what->get("cloneof") || what->get_flag(FL_DESTROYONRESET)) what->nuke_me = 1; } int givelimb(MudObject *who, const char *whichlimb) { int had = who->get_int(ssprintf("b.%s", whichlimb).c_str(), 1); who->unset(ssprintf("b.%s", whichlimb).c_str()); return had; } bool heal(MudObject *who, MudObject *what, int healing) { int strength = strength_of(what); int max = what->get_int("maxstrength"); if (MudObject *body=what->get_object("corpseof")) { set_owner(body, what->owner); while (body->owner && body->owner->owner && !body->owner->get_flag(FL_ROOM)) set_owner(body, body->owner->owner); what->nuke_me = 1; MudObject *o; int i; foreach(what->children, o, i) { const char *wb = o->get(KEY_WORNBY); #define KEY_WORNON "$wornon" const char *wo = o->get(KEY_WORNON); set_owner(o, body); i--; if (streq(o->get("$lootfrom"), body->id)) { o->nuke_me = 1; } if (streq(wb, what->id)) { o->set(KEY_WORNBY, body->id); o->set(KEY_WORNON, wo); } } if (MudObject *wpn=what->get_object(KEY_WIELD)) { if (wpn->owner == body) { body->set(KEY_WIELD, wpn->id); } } what = body; body->set_flag(FL_SLEEPING, 0); body->set_flag(FL_SITTING, 0); body->set_flag(FL_BLIND, 0); body->set_flag(FL_DEAF, 0); body->set_flag(FL_DUMB, 0); who->printf("You revive %M.\n", what); who->oprintf(cansee, "%#M %[revives/revive] %P.\n", who, what); max = what->get_int("maxstrength"); set_strength(what, max); what->unset(KEY_PISSED); what->unset(KEY_BUNNIED); what->unset("$pigged"); what->unset("$piggy"); what->unset("$trip"); what->unset("$blissed"); set_strength(what, max); rectify_state(what); return 1; } if ((MUD_CORPSE && what->get_object("cloneof") == MUD_CORPSE) || (MUD_DROID && what->get_object("cloneof") == MUD_DROID)) { const char *n = name(what); if (!n) n = "a ^ocorpse^n"; who->printf("You cannot revive this %s.\n", remove_articles(n)); return 0; } int healed = 0; if (what==who) { what->spec_printf("You heal yourself.\n"); } else { what->spec_printf("%#M %[heals/heal] you.\n", who); who->spec_printf("You heal %M.\n", what); } if (what->get_flag(FL_BLIND)) { what->set_flag(FL_BLIND, 0); healed = 1; what->printf("You can see.\n"); if (who != what) who->printf("%#s %s blind.\n", he_or_she(what), was_or_were(what)); } if (what->get_flag(FL_DEAF)) { what->set_flag(FL_DEAF, 0); healed = 1; what->printf("You can hear.\n"); if (who != what) who->printf("%#s %s deaf.\n", he_or_she(what), was_or_were(what)); } if (what->get_flag(FL_DUMB)) { what->set_flag(FL_DUMB, 0); healed = 1; what->printf("You can speak.\n"); if (who != what) who->printf("%#s %s dumb.\n", he_or_she(what), was_or_were(what)); } if (what->get_int(KEY_PISSED)!=-1) { what->unset(KEY_PISSED); healed = 1; what->printf("You are sober.\n"); if (who != what) who->printf("%#s %s drunk.\n", he_or_she(what), was_or_were(what)); } if (what->get_int("$trip")!=-1) { what->unset("$trip"); healed = 1; what->printf("^nYour vision is back to normal.\n"); if (who != what) who->printf("%#s %s tripping.\n", he_or_she(what), was_or_were(what)); } if (what->get_int("$blissed")!=-1) { what->unset("$blissed"); healed = 1; what->printf("^nYou no longer have delusions of divinty.\n"); if (who != what) who->printf("%#s %s having delusions of divinity.\n", he_or_she(what), was_or_were(what)); } if (what->get_int("$pigged")!=-1) { what->unset("$pigged"); healed = 1; what->printf("You are less %s.\n", what->get("$piggy")); if (who != what) who->printf("%#s was %s.\n", he_or_she(what), what->get("$piggy")); what->unset("$piggy"); if (species(what)) what->oprintf("%#M %[turns/turn] into a %s.\n", what, species(what)); } if (what->get_int(KEY_BUNNIED)!=-1) { what->unset(KEY_BUNNIED); healed = 1; what->printf("You no longer see bunnies.\n"); if (who != what) who->printf("%#s saw bunnies.\n", he_or_she(what)); } int ll = 0; int rl = 0; if (!givelimb(what, "head")) { ll |= (1 << 8); rl |= (1 << 8); what->printf("You had no head.\n"); healed = 1; } for (int i=0;i<pairs_n;i++) { if (!givelimb(what, pairs[i].left)) { ll |= 1 << i; if (pairs[i].depends==-1 || !(ll & (1 << pairs[i].depends))) { what->printf("You had no left %s.\n", pairs[i].single); if (who != what) who->printf("%#s had no left %s.\n", he_or_she(what), pairs[i].single); healed = 1; } } if (!givelimb(what, pairs[i].right)) { rl |= 1 << i; if (pairs[i].depends==-1 || !(rl & (1 << pairs[i].depends))) { what->printf("You had no right %s.\n", pairs[i].single); if (who != what) who->printf("%#s had no right %s.\n", he_or_she(what), pairs[i].single); healed = 1; } } if (pairs[i].depends != -1) { if (ll & (i << pairs[i].depends)) ll |= 1 << i; if (rl & (i << pairs[i].depends)) rl |= 1 << i; } } int fingers = 0; for (int i=0;i<8;i++) { if (!givelimb(what, ssprintf("finger.%i", i).c_str())) { healed = 1; if (!(i & 1) && !(ll & (1 << 2))) fingers++; if ((i & 1) && !(rl & (1 << 2))) fingers++; } } if (fingers) { who->printf("You had %i missing finger%s.\n", fingers, fingers==1?"":"s"); } if (strength < max) { int newh = strength + healing; if (healing == -1) newh = max; if (newh > max) newh = max; what->set(KEY_STRENGTH, newh); what->set("!holostrength", newh); if (who != what) { if (newh != max) { what->cancel_printf(); what->printf("%#M %s%[heals/heal] your wounds.\n", who, newh==max?"":"partially "); } } who->printf("%#P %[was/were] at %i/%i.\n", what, strength, max, newh); healed = 1; } if (!healed) { who->cancel_printf(); what->cancel_printf(); who->printf("%#P %[is/are] fine.\n", what); return 0; } rectify_state(what); return 1; } MudObject* choose_random_object_from(MudObject *w, fn_t whether) { int count = 0; if (!w) { return 0; } MudObject *o; int i; foreach(w->children, o, i) if (!is_player(o) && (!whether || whether(o))) count++; if (!count) { return 0; } int which = random_number(count); count = 0; MudObject *toclone = 0; foreach(w->children, o, i) { if (!is_player(o) && (!whether || whether(o))) { if (count==which) toclone = o; count++; } } return toclone; } MudObject* choose_random_player_from(MudObject *w) { int count = 0; if (!w) { return 0; } MudObject *o; int i; foreach(w->children, o, i) if (is_player(o)) count++; if (!count) { return 0; } int which = random_number(count); count = 0; MudObject *toclone = 0; foreach(w->children, o, i) { if (is_player(o)) { if (count==which) toclone = o; count++; } } return toclone; } MudObject* choose_random_object_from(const char *where) { if (!where) { return 0; } return choose_random_object_from(planet->get(where)); } const char *lang(const char *msg, MudObject *what) { return msg; } bool strhas(int argc, const char **argv, const char *what) { for (int i = 0 ; i < argc ; i++) { if (streq(argv[i], what)) return true; } return false; } void rectify_state(MudObject *who) { if (!streq(body(who), "avian") && who->get_flag(FL_FLYING) && !who->get_rflag(FL_FLYING)) { who->printf("You fall to the ground.\n"); who->oprintf(cansee, "%#M %[falls/fall] to the ground.\n", who); who->set_flag(FL_FLYING, 0); } if (MudObject *upon=who->get_object(KEY_SITON)) { MudObject *where = who->owner; int found = 0; for (int i=0;i<where->array_size("tele");i++) { if (where->array_get_object("tele", i)==upon) { found = 1; } } if (!found && upon->owner != who->owner) { who->printf("You fall to the floor.\n"); who->oprintf("%#M %[falls/fall] to the floor.\n", who); who->unset(KEY_SITON); who->unset(KEY_SITONN); } } if (who->get_flag(FL_FLYING)) return; if (is_player(who) || is_mobile(who)) { MudObject *loc = who->owner; if (!loc) return; if (inwater(loc)) { who->set_flag(FL_SWIMMING, 1); } if (dryland(loc)) { who->set_flag(FL_SWIMMING, 0); } } } MudObject *archetype(const MudObject *who) { MudObject *a = who->get_object("archetype"); if (a) return a; const char *n = nation(who); const char *b = body(who)?:"human"; const char *role = who->get("role"); MudObject *p = MUD_ARCHSTORE; if (p) { MudObject *o; int i; foreach(p->children, o, i) { const char *r = o->get("role"); if (o->get_flag(FL_MOBILE) && streq(o->get("nation"), n) && o->get_flag(FL_POLICE)==who->get_flag(FL_POLICE) && streq(body(o), b) && (r==role || streq(r, role)) && get_gender(o) == get_gender(who)) return o; } } if (p) { MudObject *o; int i; foreach(p->children, o, i) { const char *r = o->get("role"); if (o->get_flag(FL_MOBILE) && streq(o->get("nation"), n) && o->get_flag(FL_POLICE)==who->get_flag(FL_POLICE) && streq(body(o), b) && (r==role || streq(r, role))) return o; } } return 0; } MudObject *replace_with_empty(MudObject *o) { MudObject *no = 0; if (MudObject *em=o->get_object("empty")) { if (o->get_object("cloneof")) no = clone_object(em, o->owner, NULL); else { no = em; set_owner(em, o->owner); } } vanish(o); return no; } const char *wornon(MudObject *o) { const char *c = o->get("$wornon"); if (c) return c; return o->get("wornon"); } bool is_worn(MudObject *o) { return streq(o->get(KEY_WORNBY), o->owner->id); } MudObject *worn_on(MudObject *by, const char *what, int wol) { MudObject*o; int i; int hsofar = -1; MudObject *best = 0; if (!what) return 0; StrTok r(what); what = r.next(","); while (what) { foreach(by->children, o, i) { const char *wo = wornon(o); if (!wo) continue; StrTok r2(wo); int eq = 0; wo = r2.next(","); while (wo) { if (streq(what, "allover")) eq = 1; if (streq(wo, "allover")) eq = 1; if (streq(what, wo)) eq = 1; for (int p=0;p<pairs_n;p++) { if (streq(what, pairs[p].both) && streq(wo, pairs[p].right)) eq = 1; if (streq(what, pairs[p].both) && streq(wo, pairs[p].left)) eq = 1; if (streq(what, pairs[p].left) && streq(wo, pairs[p].both)) eq = 1; if (streq(what, pairs[p].right) && streq(wo, pairs[p].both)) eq = 1; } wo = r2.next(","); } if (is_worn(o) && (eq) && o->get_int("wornlevel",0)>=wol) { if (o->get_int("wornlevel",0)>=hsofar) { hsofar = o->get_int("wornlevel",0); best = o; } } } what = r.next(","); } return best; } int is_naked(MudObject *who) { if (worn_on(who, "body", 0)==0) return 1; if (worn_on(who, "legs", 0)==0) return 1; return 0; } MudObject *worn_provides(MudObject *who, const char *what) { MudObject *o; int i; foreach(who->children, o, i) { if (iswornby(o, who)) { if (streq(o->get("provides"), what)) return o; } } return 0; } void fixup_lapels(MudObject *who, NewWorld *what) { MudObject *b = worn_on(who, "body", 0); MudObject *o; int i; foreach(who->children, o, i) { if (!b && o->get_object(KEY_WORNBY)==who && streq(o->get("wornon"), "lapel")) { if (what) what->add(*o); o->unset(KEY_WORNBY); } const char *needs = o->get("needs"); if (needs) { if (!worn_provides(who, needs)) { if (what) what->add(*o); o->unset(KEY_WORNBY); } } } if (MudObject *wd=who->get_object(KEY_WIELD)) { if (wd->owner != who) who->unset(KEY_WIELD); } } static int countlimb(MudObject *player, string limb) { if (strncmp(limb.c_str(), "left", 4) && strncmp(limb.c_str(), "right", 5)) return countlimb(player, ssprintf("left%s", limb.c_str()))+ countlimb(player, ssprintf("right%s", limb.c_str())); return player->get_int(ssprintf("b.%s", limb.c_str()).c_str(), 1); } inline int MIN(int a, int b) { if (a<b) return a; return b; } #ifdef INVSLOTS int freehands(MudObject *player) { int fh = MIN(countlimb(player, "arm"), countlimb(player, "hand"))*((player->get_int("pockets", 10)))/2; /* 5 objects per hand */ MudObject *o; int i; MudObject *m = mount(player); foreach(player->children,o,i) { if (iswornby(o, player)) { fh += o->get_int("pockets", 0); } else if (o !=m) { fh --; } } if (fh < 0) return 0; return fh; } #endif int used_volume(MudObject *what) { int i; int sofar = 0; for (i=0;i<what->array_size("$fillamt");i++) { sofar += what->array_get_int("$fillamt", i, 0); } MudObject *o; foreach(what->children,o,i) { sofar += o->get_int("ovolume", 0); } return sofar; } MudObject *find_coproom(MudObject *who) { return get_zonepropobj(who, "coproom"); } #include "shared.h" #include "shared.cc" void setpos(MudObject *what, pos_t pos, MudObject *on, int onn) { what->unset("$siton"); what->unset("$sitonn"); what->set_flag(FL_SITTING, 0); what->set_flag(FL_SLEEPING, 0); what->set_flag(FL_FLYING, 0); what->set_flag(FL_SWIMMING, 0); switch (pos) { case P_STANDING: break; case P_SITTING: what->set_flag(FL_SITTING, 1); break; case P_LYING: what->set_flag(FL_SLEEPING, 1); break; case P_FLYING: what->set_flag(FL_SITTING, 1); break; case P_SWIMMING: what->set_flag(FL_SWIMMING, 1); break; } if (on) { what->set("$siton", on->id); what->set("$sitonn", onn); } } const char *other_dir(const char *what) { if (streq(what, "in")) return "out"; if (streq(what, "out")) return "in"; if (streq(what, "north")) return "south"; if (streq(what, "south")) return "north"; if (streq(what, "east")) return "west"; if (streq(what, "west")) return "east"; if (streq(what, "up")) return "down"; if (streq(what, "down")) return "up"; if (streq(what, "rimwards")) return "hubwards"; if (streq(what, "hubwards")) return "rimwards"; if (streq(what, "clockwise")) return "anticlockwise"; if (streq(what, "anticlockwise")) return "clockwise"; if (streq(what, "aft")) return "fore"; if (streq(what, "fore")) return "aft"; if (streq(what, "starboard")) return "port"; if (streq(what, "port")) return "starboard"; return 0; } string make_lower(const char *c) { string t = ""; while (*c) { t += tolower(*c); c++; } return t; } const char *drillid(MudObject *o) { if (o->get_object("cloneof")) return o->get("cloneof"); return o->id; } bool wf_wears_clone_of(MudObject *who, MudObject *c) { TeleWorld w = clothes(who); MudObject *o; int i; foreach(&w, o, i) if (o==c || o->get_object("treatas")==c) return 1; return 0; } MudObject *wf_wears_with_flag(MudObject *who, Flag f) { TeleWorld w = clothes(who); MudObject *o; int i; foreach(&w, o, i) if (o->get_flag(f)) return o; return 0; } NewWorld wf_allwearsflag(MudObject *who, Flag f) { NewWorld ret; if (who->get_flag(f)) ret.add(who); TeleWorld w = clothes(who); MudObject *o; int i; foreach(&w, o, i) { if (o->get_flag(f)) ret.add(o); } return ret; }