/* * MusicMUD Daemon, version 1.0 * Copyright (C) 1998-2003 Abigail Brady, others * * 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <string.h> #include <stdarg.h> #include <stdio.h> #include <sys/time.h> #include <unistd.h> #include <string> #include <set> #include <deque> #include "vsprintf.h" #include "musicmud.h" #include "verbs.h" #include "misc.h" #include "MudObject.h" #include "Interpret.h" #include "log.h" #include "flagnames.h" #include "pflags.h" #include "pflagnames.h" #include "util.h" #include "Mission.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 "colour.h" #include "musictok.h" void MudObject::set_mission(Mission *m) { if (mission) mission->remove(this); mission = m; if (mission) mission->add(this); } static void convert(FILE *f, const char *string) { if (!strchr(string, '\\') && !strchr(string, '"')) fputs(string, f); else while (*string) { if (*string == '\\') fputs("\\\\", f); else if (*string == '"') fputs("\\\"", f); else fputc(*string, f); string++; } } Flag find_flag(const char *n) { if (strcasecmp(n, "Color")==0) return FL_COLOUR; for (Flag k=FL_FIRST;k<FL_MAX;k++) { if (strcasecmp(n, flag_names[k])==0) return k; } return FL_NONE; } PFlag find_priv(const char *n) { if (strncasecmp(n, "PFL_", 4)==0) n += 4; for (int k=0;k<PFL_MAX;k++) { if (strcasecmp(n, priv_names[k])==0) return PFlag(k); } return PFL_NONE; } MudObject::MudObject(const char *_id): Object(_id), of(0), zone(0), mission(0), next_time(now), wander_time(now), rant_time(now), follows(0), ilc(0), reftime(now), children(new World<MudObject>()), owner(0), players_here(0) { l.exit = 0; l.s = 0; }; void MudObject::ref() { reftime = now; } MudObject::~MudObject() { if (follows) { follow(0); } if (followers.getsize()) { MudObject *o; int i; foreach((&followers), o, i) { o->follow(0); i--; } } if (snooping.getsize()) { MudObject *o; int i; foreach((&snooping), o, i) { desnoop(o); i--; } } if (snoopers.getsize()) { MudObject *o; int i; foreach((&snoopers), o, i) { o->desnoop(this); i--; } } if (tracing.getsize()) { MudObject *o; int i; foreach((&tracing), o, i) { detrace(o); i--; } } if (tracers.getsize()) { MudObject *o; int i; foreach((&tracers), o, i) { o->detrace(this); i--; } } set_mission(0); MudObject *o; int i; foreach(children, o, i) { children->remove(*o); if (owner) { owner->children->add(*o); o->owner = owner; } else { set_owner(o, "@musicmud"); } i--; } delete children; if (owner) { owner->children->remove(*this); } if (zone) { set("zone", (const char *)0); } q_remove(); } void MudObject::reset() { if (get_flag(FL_DESTROYONRESET)) { set_flag(FL_SILENTQUIT, 1); if (children->getsize()) { MudObject *o; int i; foreach(children, o, i) set_owner(o, owner); } set_owner(this, "@musicud"); nuke_me = 1; return; } flags = resetflags; q_update(); set_bflag(FL_TIMER, 0); { strit i = strs.begin(); while (i != strs.end()) { if (i->first[0]=='!') { unset(i->first.c_str()); i = strs.begin(); } else i++; } } { intit i = ints.begin(); while (i != ints.end()) { if (i->first[0]=='!') { unset(i->first.c_str()); i = ints.begin(); } else i++; } } if (!is_player(this)) { if (MudObject*s=get_object("start")) if (s != owner) { set_owner(this, s); } if (get_int("initstrength")!=-1) set(KEY_STRENGTH, get_int("initstrength")); else if (get_int("maxstrength")!=-1) set(KEY_STRENGTH, get_int("maxstrength")); } if (get("wornby.start")) set(KEY_WORNBY, get("wornby.start")); if (get("wield.start")) set(KEY_WIELD, get("wield.start")); if (get("killedby")) unset("killedby"); if (const char *ss=get("siton.start")) { set(KEY_SITON, ss); } unset("_fighting"); set(KEY_STATE, get_int("initstate", 0)); if (get("$keycode.sofar")) set("$keycode.sofar", ""); if (follows) { interpret("leave"); } if (get_int("maxenergy")>0) set("!energy", get_int("maxenergy")); set_flag(FL_DONE, 0); set("$flag", get("initflag")); if (MudObject *ac=get_object(KEY_ACCEPTER)) { ac->unset("mission"); } unset(KEY_ACCEPTER); if (get_flag(FL_STARTPLAN) && get("plan")) { set("!plan", get("plan")); set("!when", 1); set("!what", ""); set_flag(FL_TIMER, 1); } if (get_int("initdeck")==1) { for (int i=0;i<52;i++) { array_set("$card", i, i); } set("$card.count", 52); } else { unset("$card.count"); } int c=array_size("shop"); for(int i=0;i<c;i++) { if (int r=array_get_int("shop", i, "istock")) { if (r != -1) { array_set("$stock", i, r); } } } if (MudObject*sub=get_object("fullof")) { array_set("$fill", 0, sub->id); array_set("$fillamt", 0, get_int("volume", 0)); set("$fill.count", 1); set("$fillamt.count", 1); } else { unset("$fill.count"); unset("$fillamt.count"); unset("$fill.0"); unset("$fillamt.0"); } dotrap(E_ONRESET, this, this); /* ::: reset o1==object being reset. */ } void MudObject::send_data() { } bool MudObject::spewfile(const char *, const char *, bool, const char *) { return 0; } MudObject *qui = 0; const char *current_command; Verb *quiverb; bool MudObject::interpretf(const char *format, PRINT_PARMS) { string buffer = formatprint(this, format, GET_PARMS()); bool b = interpret(buffer.c_str()); return b; } void MudObject::holo_clone(const MudObject *whatof, const char *prefix) { clone(whatof); cstrit i = whatof->strs.begin(); while (i != whatof->strs.end()) { if (strncmp(i->first.c_str(), "disc.", 5)==0) { i++; continue; } if (i->first == "wornfrom") { i++; continue; } if (MudObject *o=planet->get(i->second.c_str())) if (!streq(o->get("zone"), "template")) { string nstr = ""; const char * nval = i->second.c_str(); if (nval[0]==':') { nstr = ":"; nstr += prefix; nstr += "_"; nstr += nval + 1; } else { nstr = prefix; nstr += "_"; nstr += nval; } set(i->first, nstr); } i++; } } bool MudObject::interpret(const char *string) { std::string la; if (!string || !*string) return 0; while (*string==' ') string++; const char *oldcurrent_command = current_command; Verb *oldverb = quiverb; current_command = string; MudObject *oldwho = qui; qui = this; quiverb = 0; std::deque<std::string> what; std::string s = string; int argc = 0; int sofar = 0; Verb *verb = 0; while (1) { int sp = s.find(' '); if (sp == -1) break; if (sp || (verb && (verb->vflags & VFL_MAGICSPACE))) { what.push_back(s.substr(0, sp)); argc++; } if (!verb && argc) { verb = get_verb(what[0].c_str()); } sofar = sp+1; s = s.substr(sofar); } if (s.length() && ((s[0]!=' ') || verb && (verb->vflags & VFL_MAGICSPACE))) { what.push_back(s); argc++; } int success = 0; if (what.size()==0) { current_command = oldcurrent_command; qui = oldwho; quiverb = oldverb; return 0; } if (const char *al=get(ssprintf("alias.%s", what[0].c_str()).c_str())) { what.pop_front(); std::deque<std::string> v; StrTok tok(al); while (const char *txt=tok.next(" ")) { if (streq(txt, "$*")) { std::deque<std::string>::iterator i = what.begin(); while (i != what.end()) { v.push_back(*i); i++; } what = std::deque<std::string>(); continue; } v.push_back(txt); } std::deque<std::string>::iterator i = what.begin(); while (i != what.end()) { v.push_back(*i); i++; } what = v; argc = what.size(); std::string s; for (int i=0;i<argc;i++) { if (i) s += " "; s += what[i]; } printf("After aliasing, expands to: %s\2^n\n", s.c_str()); } verb = get_verb(what[0].c_str()); if (verb) what[0] = verb->id; const char *argv[argc+1]; for (int c=0;c<argc;c++) { argv[c] = what[c].c_str(); } argv[argc] = 0; if (verb) { if (!owner && !(verb->vflags & VFL_OKNOOWNER)) { printf("You don't have an owner atm, so can't do that.\n"); success = 1; } else if (verb->disabled) { printf("%#s is temporarily disabled.\n", verb->id); success = 1; } else if (verb->has_privs(this) || this->ilc) { quiverb = verb; verb->invoke(this, argc, argv); success = 1; } else if (verb->pflag == PFL_AWAKE) { printf("You toss and turn in your sleep.\n"); oprintf(cansee, "%#M tosses and turns in %s sleep.\n", this, his_or_her(this)); success = 1; } else if (!(verb->vflags & VFL_DENYEXISTS)) { printf("You can't do that : %s\n", argv[0]); success = 1; } } else { int i2; Interpreter *in; foreach(interpreters, in, i2) { int value = in->invoke(this, string, argc, argv); if (value == 0 || value == 1) { success = 1; break; } } } if (!success) { printf("What do you mean by \"%s\"?\n", argv[0]); } current_command = oldcurrent_command; qui = oldwho; quiverb = oldverb; return 0; } bool MudObject::cancel_printf() { return 1; } void MudObject::real_printf(const char *f, const PARMS &p, MudObject *target, int snoop) { if (!target) target = this; if (!snoop) { MudObject *o; int i; foreach((&snoopers), o, i) { string fm = "^R*^n"; fm += f; o->real_printf(fm.c_str(), p, target, 1); } } if (of) { string temp = formatprint(target, f, p); fprintf(of, "%s", temp.c_str()); return; } } void MudObject::printf(const char *fmt, PRINT_PARMS) { real_printf(fmt, GET_PARMS()); } void MudObject::spec_printf(const char *fmt, PRINT_PARMS) { real_spec_printf(fmt, GET_PARMS()); } void MudObject::real_spec_printf(const char *fmt, const PARMS &) { } void MudObject::aprintf(const char *fmt, PRINT_PARMS) { return real_aprintf(always, fmt, GET_PARMS(), this); } void MudObject::real_aprintf(const showto &f, const char * a, const PARMS &p, MudObject *target) { MudObject *o; int i; foreach(children, o, i) { o->real_aprintf(f, a, p, target); } if (f(this)) real_printf(a, p, target); } void MudObject::lprintf(const showto &o, const char *fmt, PRINT_PARMS) { if (!owner) return; PARMS p = GET_PARMS(); if (owner->get_flag(FL_LINKED)) { int i; MudObject *obj; foreach(owner->children, obj, i) { MudObject *dest = linkedlink(obj); if (dest && dest != owner) { dest->real_aprintf(o, fmt, p, 0); } } } } void MudObject::oprintf(const showto &f, const char *fmt, PRINT_PARMS) { if (!owner) return; PARMS p = GET_PARMS(); MudObject *o; int i; foreach(owner->children, o, i) if (o != this && (!is_player(o) || o->get_flag(FL_LOGGEDIN)) && f(o)) o->real_printf(fmt, p, 0); } void MudObject::oprintf(const char *fmt, PRINT_PARMS) { oprintf(always, fmt, PRINT_PASS_PARMS); } void MudObject::action_to(MudObject *from, const char *fmt, const char *t, MudObject *prop) { if (from && !filter(from)(this)) return; string buffer = sprinta(this, fmt, this, from, t, 2, prop); if (buffer.length()==0) return; printf("%s\n", buffer.c_str()); } void MudObject::action_from(MudObject *from, const char *fmt, const char *t, MudObject *second, MudObject *prop) { if (!is_player(this) && !is_mobile(this) && !snoopers.getsize()) return; if (from && !filter(from)(this)) return; string buffer = sprinta(this, fmt, from, second ? second : this, t, 2, prop); if (buffer.length()==0) return; printf("%s\n", buffer.c_str()); } MudObject *linkedlink(MudObject *ext) { if (!ext->owner->get_flag(FL_LINKED)) return 0; if (MudObject *door=ext->get_object("door")) { if (state(door) && !door->get_flag(FL_TRANSPARENT)) return 0; } MudObject *dest = ext->get_object("link"); if (!dest) return 0; if (dest==ext->owner) return 0; if (dest->get_flag(FL_LINKED)) return dest; return 0; } void MudObject::action(MudObject *avoid, const char *fmt, const char *t, MudObject *prop) { MudObject *o; int i; foreach(owner->children, o, i) { if (o!=avoid && o != this) o->action_from(this, fmt, t, avoid, prop); MudObject *ll = linkedlink(o); if (ll && ll != this->owner) { MudObject *m; int j; foreach(ll->children, m, j) if (m != avoid && m != this) { m->action_from(this, fmt, t, avoid, prop); } } } } void MudObject::action(const showto &s, MudObject *target, const char *fmt, const char *t, MudObject *prop) { MudObject *o; int i; foreach(owner->children, o, i) { if (o != target && o != this && s(o)) o->action_from(this, fmt, t, target, prop); MudObject *ll = linkedlink(o); if (ll && ll != this->owner) { MudObject *m; int j; foreach(ll->children, m, j) if (m != target && m != this && s(o)) { m->action_from(this, fmt, t, target, prop); } } } } void MudObject::set(const char *key, const char *value) { if (streq(key, "id")) { bool plan = (planet->get(id)) == this; if (plan) planet->remove(this); Object::set(key, value); if (plan) planet->add(this); return; } if (streq(key, "owner")) { MudObject *dest = planet->get(value); if (dest && is_in(dest, this)) { log(PFL_SEEINFO, 0, "debug", "attempt at moving %s into %s", id, dest->id); return; } if (!dest && this != mud) dest = mud; if (owner && owner->children) { owner->children->remove(*this); if (is_player(this)) owner->players_here--; } if (owner) owner->refcount--; owner = dest; if (owner) owner->refcount++; if (owner && owner->children) { owner->children->add(*this); if (is_player(this)) owner->players_here++; } return; } if (streq(key, "zone")) { if (zone && zone->children) zone->children->remove(*this); if (zone) zone->refcount--; if (zone && !zone->refcount) { zones->remove(*zone); delete zone; } if (value) { zone = zones->get(value); if (!zone) { zone = new MudObject(value); zones->add(*zone); } if (zone) zone->refcount++; if (zone && zone->children) zone->children->add(*this); } else zone = 0; } Object::set(key, value); } void MudObject::save_difference(FILE *f, const MudObject *ofwhat) const { { cstrit i = strs.begin(); while (i != strs.end()) { if (i->first[0] != '!' && !(streq(i->second.c_str(), ofwhat->get(i->first.c_str())))) { fprintf(f, "string %s \"", i->first.c_str()); convert(f, i->second.c_str()); fprintf(f, "\"\n"); } i++; } } { cintit i = ints.begin(); while (i != ints.end()) { if (i->first[0] != '!' && (i->second != ofwhat->get_int(i->first.c_str()))) { fprintf(f, "int %s %i\n", i->first.c_str(), i->second); } i++; } } } const char *MudObject::get(const char *key) const { if (strcmp(key, "owner")==0) if (owner) return owner->id; else return 0; else return Object::get(key); } MudObject *find_questob(const char *name) { int l = strlen(name); if (l < 2) return 0; extern set<MudObject*> s_quests; for (set<MudObject*>::iterator i=s_quests.begin();i!=s_quests.end();i++) { MudObject *q = *i; if (q->get("mname") && strncasecmp(q->get("mname"), name, l)==0) return q; } return NULL; } class autofree { void *v; public: autofree(void *v) : v(v) { } ~autofree() { free(v); } }; void priv_load(bitset<512> &s, const char *str, char *buffer) { if (strncmp(buffer, str, strlen(str))==0) { char *a = strtok(buffer+strlen(str), " "); while (a) { PFlag i = find_priv(a); if (i!=PFL_NONE) s[i] = 1; a = strtok(0, " "); } } } void priv_save(const bitset<512> &s, const char *str, FILE *f) { bool j = false; for (int p=2;p<PFL_MAX;p++) { if (s[p]) { if (!j) { fprintf(f, str); j = true; } fprintf(f, " %s", priv_names[p]); } } if (j) fprintf(f, "\n"); } void MudObject::load(const char *buf) { char *buffer = strdup(buf); autofree af(buffer); if (*buffer=='\t') buffer++; if (strncmp(buffer, "string ", 7)==0) { char *pname = buffer + 7; char *pvalue = strchr(buffer, '"'); if (!pvalue) { log(PFL_SEEINFO, 0, "zoneload", "error in zone file"); return; } *pvalue = 0; pvalue++; pvalue[strlen(pvalue)-1]=0; if (strchr(pname, ' ')) *strchr(pname, ' ')=0; if (strncmp(pname, "eq.", 3)==0) return; if (strncmp(pname, "q.", 2)==0) return; if (streq(pname, "wield")) pname = "$wield"; if (*pname != '_') { if (streq(pname, "owner") && !this->owner) set("!owner", pvalue); else this->set(pname, pvalue); } } if (strncmp(buffer, "int ", 4)==0) { char *pname = buffer + 4; char *pvalue = strchr(pname, ' '); *pvalue = 0; pvalue++; if (strncmp(pname, "eq.", 3)==0) return; if (strncmp(pname, "q.", 2)==0) return; if (strncmp(pname, "quest_id", 8)==0) return; if (streq(pname, "state")) this->set(KEY_STATE, atoi(pvalue)); else if (streq(pname, "initstate")) { int v = atoi(pvalue); if (v != -1) this->set(pname, v); } else if (*pname != '_' && (strcmp(pname, "noreset")!=0)) { if (streq(pname, "rantcount")) pname = "rant.count"; if (streq(pname, "balance")) pname = "$balance"; if (streq(pname, "cash")) pname = "$cash"; if (streq(pname, "armor")) pname = "armour"; this->set(pname, atoi(pvalue)); } } if (strncmp(buffer, "flags ", 6)==0) { char *a = strtok(buffer+6, " "); while (a) { Flag j = find_flag(a); if (j!=-1) { set_flag(j, 1); set_rflag(j, 1); } a = strtok(0, " "); } } if (strncmp(buffer, "privs ", 6)==0) { char *a = strtok(buffer+6, " "); while (a) { if (!is_player(this)) { PFlag pf = find_priv(a); if (pf != PFL_NONE) granted[pf] = 1; } a = strtok(0, " "); } } if (is_player(this) && strncmp(buffer, "quest ", 6)==0) { char *a = strtok(buffer+6, " "); while (a) { quest_set(this, a); a = strtok(0, " "); } } priv_load(withheld, "withheld ", buffer); priv_load(granted, "granted ", buffer); priv_load(abeyed, "abeyance ", buffer); return; } void MudObject::setf(const char*key, const char *format, PRINT_PARMS) { set(key, formatprint(this, format, GET_PARMS())); } MudObject *MudObject::get_object(const char *a) const { if (!a) return 0; const char *v = get(a); if (!v) return 0; return planet->get(v); } int MudObject::array_size(const char *aname) const { string n = aname; n += ".count"; return get_int(n.c_str(), 0); } const char *MudObject::array_get(const char *aname, int index) const { char n[1024]; sprintf(n, "%s.%i", aname, index); return get(n); } MudObject *MudObject::array_get_object(const char *aname, int index) const { char n[1024]; sprintf(n, "%s.%i", aname, index); return get_object(n); } const char *MudObject::array_get(const char *aname, int index, const char *prop) const { char n[1024]; sprintf(n, "%s.%i.%s", aname, index, prop); return get(n); } MudObject *MudObject::array_get_object(const char *aname, int index, const char *prop) const { char n[1024]; sprintf(n, "%s.%i.%s", aname, index, prop); return get_object(n); } int MudObject::array_get_int(const char *aname, int index, int def) const { char n[1024]; sprintf(n, "%s.%i", aname, index); return get_int(n, def); } int MudObject::array_get_int(const char *aname, int index, const char *prop, int def) const { char n[1024]; sprintf(n, "%s.%i.%s", aname, index, prop); return get_int(n, def); } void MudObject::array_set(const char *aname, int index, MudObject *what) { char n[1024]; sprintf(n, "%s.%i", aname, index); int size = array_size(aname); if ((index+1)>size) { size = index + 1; } if (what) { set(n, what->id); sprintf(n, "%s.count", aname); set(n, size); } else { unset(n); } } void MudObject::array_unset(const char *aname, int index, const char *prop) { char n[1024]; sprintf(n, "%s.%i.%s", aname, index, prop); unset(n); } void MudObject::array_unset(const char *aname, int index) { char n[1024]; sprintf(n, "%s.%i", aname, index); unset(n); } void MudObject::array_set(const char *aname, int index, const char *prop, int val) { char n[1024]; sprintf(n, "%s.%i.%s", aname, index, prop); set(n, val); } void MudObject::array_set(const char *aname, int index, const char *prop, const char *val) { char n[1024]; sprintf(n, "%s.%i.%s", aname, index, prop); set(n, val); } void MudObject::array_set(const char *aname, int index, int what) { char n[1024]; sprintf(n, "%s.%i", aname, index); int size = array_size(aname); if ((index+1)>size) { size = index + 1; } set(n, what); sprintf(n, "%s.count", aname); set(n, size); } void MudObject::array_set(const char *aname, int index, const char *what) { char n[1024]; sprintf(n, "%s.%i", aname, index); int size = array_size(aname); if ((index+1)>size) { size = index + 1; } set(n, what); sprintf(n, "%s.count", aname); set(n, size); } void MudObject::save(FILE *f, bool include_var) const { if (get_flag(FL_DESTROYONRESET)) return; if (get_flag(FL_NOSAVE)) return; if (id[0] == '@') return; fprintf(f, "mudobject \"%s\" {\n", id); bool j = false; for (Flag p=FL_FIRST;p<FL_MAX;p++) { if (p == FL_TIMER || p == FL_OBSERVED) continue; if (is_player(this)?get_flag(p):get_rflag(p)) { if (!j) { fprintf(f, "flags"); j = true; } fprintf(f, " %s", flag_names[p]); } } if (j) fprintf(f, "\n"); priv_save(withheld, "withheld", f); priv_save(abeyed, "abeyed", f); if (is_player(this)) priv_save(granted, "granted", f); else priv_save(granted, "privs", f); j = false; for (std::set<string>::iterator q=quests.begin();q!=quests.end();q++) { if (!j) { fprintf(f, "quest"); j = 1; } fprintf(f, " %s", q->c_str()); } if (j) fprintf(f, "\n"); if (owner) if (const char *s = get("start")) fprintf(f, "string owner \"%s\"\n", s); else fprintf(f, "string owner \"%s\"\n", owner->id); { cstrit i = strs.begin(); while (i != strs.end()) { if (i->first[0] != '!' && (include_var || i->first[0] != '$')) { if (!strchr(i->first.c_str(), '"')) { fprintf(f, "string %s \"", i->first.c_str()); convert(f, i->second.c_str()); fprintf(f, "\"\n"); } } i++; } } { cintit i = ints.begin(); while (i != ints.end()) { if (i->first[0] != '!' && (include_var || i->first[0] != '$')) { if (!strchr(i->first.c_str(), '"')) { fprintf(f, "int %s %i\n", i->first.c_str(), i->second); } } i++; } } fprintf(f, "}\n"); } void MudObject::set(const char *a, int b) { Object::set(a, b); } void MudObject::clone(const MudObject *whatof) { flags = whatof->flags; resetflags = whatof->resetflags; withheld = whatof->withheld; granted = whatof->granted; ints = whatof->ints; strs = whatof->strs; cstrit i = strs.begin(); while (i != strs.end()) { if (strncmp(i->first.c_str(), "lua.", 4)==0) { unset(i->first.c_str()); i = strs.begin(); } else i++; } } void MudObject::save_var(FILE *f) const { if (get_flag(FL_DESTROYONRESET)) return; if (get_flag(FL_NOSAVE)) return; int y = 0; cstrit i = strs.begin(); while (i != strs.end()) { if (i->first[0] == '$') { if (strchr(i->first.c_str(), '"')) continue; if (!y) fprintf(f, "vardata \"%s\" {\n", id); y++; fprintf(f, "string %s \"", i->first.c_str()); convert(f, i->second.c_str()); fprintf(f, "\"\n"); } i++; } { cintit i = ints.begin(); while (i != ints.end()) { if (i->first[0] == '$') { if (strchr(i->first.c_str(), '"')) continue; if (!y) fprintf(f, "vardata \"%s\" {\n", id); y++; fprintf(f, "int %s %i\n", i->first.c_str(), i->second); } i++; } } if (y) { fprintf(f, "}\n"); } } set<MudObject*> s_quests; void MudObject::q_update() { if (get_flag(FL_QUEST)) s_quests.insert(this); else s_quests.erase(this); } void MudObject::q_remove() { if (get_flag(FL_QUEST)) s_quests.erase(this); } void MudObject::set_flag(Flag what, bool value) { flags[what] = value; q_update(); } bool MudObject::get_flag(Flag which) const { return flags[which]; } void MudObject::set_rflag(Flag what, bool value) { resetflags[what] = value; } bool MudObject::get_rflag(Flag which) const { return resetflags[which]; } struct { int level; PFlag priv; } priv_things[] = { { 1, PFL_MAIL }, { 1, PFL_BECOME }, { 1, PFL_EMOTE }, { 4, PFL_BOARD }, { 7, PFL_ABERCHAT }, { 7, PFL_TITLE }, { LEV_COMMANDER , PFL_GOTO }, { LEV_COMMANDER , PFL_WHERE }, { LEV_COMMANDER , PFL_REMORT }, { LEV_COMMANDER, PFL_SEEBUGS }, { LEV_CAPTAIN , PFL_INVIS }, { LEV_CAPTAIN , PFL_NOHASSLE }, { LEV_CAPTAIN , PFL_SEESTATS }, { LEV_CAPTAIN , PFL_SETIN }, { LEV_CAPTAIN, PFL_BOOT }, { LEV_CAPTAIN, PFL_ECHO }, { LEV_CAPTAIN, PFL_HEAL }, { LEV_CAPTAIN, PFL_IMMORTAL }, { LEV_CAPTAIN, PFL_MAKE }, { LEV_CAPTAIN, PFL_RESET }, { LEV_CAPTAIN, PFL_SEEINFO }, { LEV_CAPTAIN, PFL_START }, { LEV_CAPTAIN, PFL_STATUS }, { LEV_CAPTAIN, PFL_ROOM }, { LEV_CAPTAIN, PFL_ACTIONS }, { LEV_CAPTAIN, PFL_DETAIL }, { LEV_CAPTAIN, PFL_ZAP }, { LEV_CAPTAIN, PFL_BEAM }, { LEV_CAPTAIN, PFL_ERASEOTHERS }, { LEV_CAPTAIN, PFL_MAKEFILE }, { LEV_CAPTAIN, PFL_MAKEINFO }, { LEV_CAPTAIN, PFL_MAKEHELP }, { LEV_CAPTAIN, PFL_ERASEFILE }, { LEV_CAPTAIN, PFL_ERASEINFO }, { LEV_CAPTAIN, PFL_ERASEHELP }, { LEV_CAPTAIN, PFL_ZONES }, { LEV_CAPTAIN, PFL_TRACE }, { LEV_CAPTAIN, PFL_CLONE }, { LEV_CAPTAIN, PFL_SEELUASPAM }, { LEV_COMMODORE, PFL_BAN }, { LEV_COMMODORE, PFL_FORCE }, { LEV_COMMODORE, PFL_REMORTANYWHERE }, { LEV_ADMIRAL, PFL_CANAKICK }, { LEV_ADMIRAL, PFL_CHQUEST }, { LEV_COMMODORE, PFL_FROB }, { LEV_CAPTAIN, PFL_HOSTS }, { LEV_CAPTAIN, PFL_EDITALL }, { LEV_COMMANDER, PFL_MINIMISSIONS }, { LEV_COMMODORE, PFL_SHUTDOWN }, { LEV_COMMODORE, PFL_CODER }, { LEV_ADMIRAL, PFL_MAKEPOLICY }, { LEV_ADMIRAL, PFL_ERASEPOLICY }, { LEV_COMMODORE, PFL_SNOOP }, { LEV_ADMIRAL, PFL_GOD }, { 0, PFL_NONE }, }; bool MudObject::get_dpriv(PFlag which) const { for (int i=0;priv_things[i].level;i++) if (priv_things[i].priv == which) return privs_of(this)>=priv_things[i].level; return 0; } void MudObject::set_apriv(PFlag which, int i) { abeyed[which] = i; } void MudObject::set_gpriv(PFlag which, int i) { granted[which] = i; } void MudObject::set_wpriv(PFlag which, int i) { withheld[which] = i; } bool MudObject::get_wpriv(PFlag which) const { return withheld[which]; } bool MudObject::get_apriv(PFlag which) const { return abeyed[which]; } bool MudObject::get_gpriv(PFlag which) const { return granted[which]; } bool MudObject::get_priv(PFlag which) const { if (withheld[which] || abeyed[which]) return 0; if (granted[which] && (get_int("remort")==-1 || which==PFL_REMORTANYWHERE)) return 1; // look up our level then return it for (int i=0;priv_things[i].level;i++) { if (priv_things[i].priv == which) return privs_of(this)>=priv_things[i].level; } return get_dpriv(which); } void MudObject::file_divert(FILE *f) { of = f; } void MudObject::file_undivert() { of = 0; } void MudObject::push_data() { }