/* * MusicMUD - Player Customisation Module * Copyright (C) 1998-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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <ctype.h> #include "musicmud.h" #include "util.h" #include "verbs.h" #include "State.h" #include "Player.h" #include "misc.h" #include "flagnames.h" #include "pflags.h" #include "pflagnames.h" #include "colour.h" #include "prep.h" #include "msi.h" #include <list> #include <algorithm> #define MODULE "custom" static bool verb_prompt(MudObject *player, int argc, const char **argv) { if (argc < 2) { player->printf("syntax : prompt what\n"); return true; return true; } string rest = the_rest(argc, argv, 1); char temp[4096]; if (rest[0]=='!') temp[0]=0; else strcpy(temp, rest.c_str()); if (streq(argv[1], "\\")) { player->unset("prompt.cmd"); } else { player->set("prompt.cmd", temp); } player->printf("Prompt set.\n"); return true; } static bool verb_nametransplant(MudObject *who, int argc, const char **argv) { if (argc < 3) { who->printf("nametransplant <oldname> <newname>\n"); return true; } MudObject *what = get_player(who, argv[1]); if (!is_player(what)) { who->printf("You may only give a name transplant to a player.\n"); return true; } if (what!=who && !IS_ADMIRAL(who)) { who->printf("You are not powerful enough.\n"); return true; } if (!IS_CAPTAIN(who)) { who->printf("You are not powerful enough.\n"); return true; } if (player_exist(argv[2])) { who->printf("Name already in use.\n"); return true; } { Object *target = planet->get(argv[2]); if (!target) target = verbs->get(argv[2]); if (target) { who->printf("That name is already in use.\n"); return true; } } string newshort = argv[2]; newshort[0] = toupper(newshort[0]); string newlong = "^p"; newlong += newshort; newlong += "^n"; string newid = argv[2]; for (unsigned int i=0;i<newid.length();i++) { newid[i] = tolower(newid[i]); } what->set("id", newid.c_str()); what->set("short", newid.c_str()); what->set("name", newlong.c_str()); what->interpret("save"); return true; } static bool verb_homeroom(MudObject *player, int argc, const char **argv) { if (argc < 2) { const char *s = player->get("start"); if (s) { player->printf("Your homeroom is %s.\n", s); if (!planet->get(s)) { player->printf("That location does not exist - you should set your homeroom to something that does.\n", s); } } else player->printf("You haven't set a homeroom.\n"); return true; } if (streq(argv[1], "here")) { player->set("start", player->owner->id); return true; } if (!planet->get(argv[1])) { player->printf("No such location as %s\n", argv[1]); return true; } player->set("start", argv[1]); return true; } struct { const char *cmd; const char *id; const char *synt; } setfinger[] = { { "email", "finger.email", "<address>" }, { "irlname", "finger.name", "<name>" }, { "url", "finger.url", "<address>" }, { "uin", "finger.uin", "<number>" }, { "phone", "finger.phone", "<number>" }, { "dob", "finger.dob", "yyyy-mm-dd" }, }; #define ELEMENTS(a) (int)(sizeof(a)/sizeof(a[0])) static bool verb_setfinger(MudObject *player, int argc, const char **argv) { if (argc < 2) { for (int i=0;i<ELEMENTS(setfinger);i++) { if (streq(setfinger[i].cmd, argv[0])) { player->printf("%s %s\n", argv[0], setfinger[i].synt); } } return true; } string text = the_rest(argc, argv, 1); if ((text == "erase") || (text == "none") || (text == "off") || (text == "delete")) { for (int i=0;i<ELEMENTS(setfinger);i++) { if (streq(setfinger[i].cmd, argv[0])) { player->unset(setfinger[i].id); player->printf("OK.\n"); return true; } } return true; } if (streq(argv[0], "dob")) { if (text.length()!=strlen("yyyy-mm-dd")) { player->printf("Date must be in yyyy-mm-dd format.\n"); return true; } if (!isdigit(text[0]) || !isdigit(text[1]) || !isdigit(text[2]) || !isdigit(text[3]) || !isdigit(text[5]) || !isdigit(text[6]) || !isdigit(text[8]) || !isdigit(text[9]) || text[4] != '-' || text[7] != '-') { player->printf("Date must be in yyyy-mm-dd format.\n"); return true; } player->set("finger.dob", text.c_str()); player->printf("OK.\n"); return true; } bool ok = false; for (int i=0;i<ELEMENTS(setfinger);i++) { if (streq(setfinger[i].cmd, argv[0])) { player->set(setfinger[i].id, text.c_str()); ok = true; } } player->printf(ok ? "OK.\n" : "THIS IS A BUG : PLEASE REPORT.\n"); return true; } static void unreset(MudObject *who, MudObject *what) { if (what->get_flag(FL_GETFLIPS)) what->set(KEY_STATE, 1); if (!what->owner) { set_owner(what, "@musicmud"); } what->set("start", what->owner->id); what->set("initstate", state(what)); if (MudObject *w=what->get_object(KEY_WIELD)) { if (w->get_flag(FL_DESTROYONRESET)) who->printf("Warning: not set wield.start because it would be to a temporary object."); else what->set("wield.start", w->id); } if (MudObject *w=what->get_object(KEY_WORNBY)) { if (w->get_flag(FL_DESTROYONRESET)) who->printf("Warning: not set wornby.start because it would be to a temporary object."); else what->set("wornby.start", w->id); } if (MudObject *w=what->get_object(KEY_SITON)) { if (w->get_flag(FL_DESTROYONRESET)) who->printf("Warning: not set siton.start because it would be to a temporary object."); else what->set("siton.start", w->id); } what->unreset(); } static bool verb_unreset(MudObject *player, int argc, const char **argv) { if (argc < 2) { player->printf("syntax : unreset objectname\n"); return true; } MudObject *what = find_object(player, argv[1]); if (!what) { player->printf("Cannot find %s\n", argv[1]); return true; } if (what->get_flag(FL_DESTROYONRESET)) { player->printf("You can't unreset objects with DestroyOnReset flag.\n"); return true; } unreset(player, what); player->printf("%s : reset state set.\n", what->id); return true; } static bool verb_review (MudObject *who, int argc, const char **argv) { MudObject *v=who; if (argc>1) { v = planet->get(argv[1]); if (!v) { who->printf("Look at whose travel messages?\n"); return true; } } who->spec_printf("%s\n\n", title_for(ssprintf("Travel messages for %M", v), who).c_str()); struct set_t { const char *str; setin_t s; } sets[] = { { "setmin", setmin, }, { "setmout", setmout, }, { "setvin", setvin, }, { "setvout", setvout, }, { "setqin", setqin, }, { "setqout", setqout, }, { "setsit", setsit, }, { "setstand", setstand, }, { "setsleep", setsleep, }, }; const char *name = v->get("name"); bool yes = 0; for (int i=0;i<9;i++) { if (v->get(sets[i].str)) { who->printf(" %#8s : ^`^Z%s^'\n", sets[i].str, build_setin(v, get_message(v, sets[i].s), name, NULL, NULL).c_str()); yes = 1; } } if (yes) who->printf("\n%s\n", footer_for(who).c_str()); else { who->cancel_printf(); who->printf("%#P %[has/have] no custom travel messages.\n", v); } return true; } static bool verb_flags(MudObject *who, int argc, const char **argv) { if (argc==1 || argv[1][0]=='|') { int i; vector<string> flags; size_t maxlen = 0, n = 0; for (i=0;i<FL_MAX;i++) { if (strncmp(flag_names[i], "Spare", 5)==0) continue; if (argc>1 && !strcasestr(flag_names[i], argv[1]+1)) continue; flags.insert(flags.begin(), flag_names[i]); if (strlen(flag_names[i])>maxlen) maxlen = strlen(flag_names[i]); } sort(flags.begin(), flags.end()); for (vector<string>::iterator i = flags.begin();i!=flags.end();i++) { who->printf("%-*s", maxlen+1, i->c_str()); n++; if (n>=(columns(who)/(maxlen+1))-1) { n=0; who->printf("\n"); } } who->printf("\n"); return true; } MudObject *what = find_object(who, argv[1]); if (!what) { who->printf("Cannot locate : %s\n", argv[1]); return true; } if (argc == 2) { who->spec_printf("^dFlags ^n"); bool thing = 0; for (Flag i=FL_FIRST;i<FL_MAX;i++) { int a = what->get_rflag(i); int b = what->get_flag(i); if (a || b) { if (a && b) who->printf("^d[^D%s^d]^n ", flag_names[i]); if (!a && b) who->printf("+^d[^D%s^d]^n ", flag_names[i]); if (a && !b) who->printf("(-%s) ", flag_names[i]); thing = 1; } } if (thing) { who->printf("\n"); } else { who->cancel_printf(); } return true; } if (is_player(what) && !IS_ADMIRAL(who)) { who->printf("You can't set flags on players.\n"); return true; } if (!cantouch_zone(who, what->get("zone")) && !who->ilc) { who->printf("You aren't authorised to modify that object.\n"); return true; } int value = -1; if (argc == 4) { if (yes(argv[3])) value = 1; if (no(argv[3])) value = 0; if (value==-1) { who->printf("Set it to what?\n"); } } for (Flag l=FL_FIRST;l<FL_MAX;l++) { if (strcasecmp(argv[2], flag_names[l])==0) { if (value != -1) { if (streq(argv[0], "flags") || streq(argv[0], "tflags")) { what->set_flag(l, value); } if (streq(argv[0], "flags") || streq(argv[0], "rflags")) { what->set_rflag(l, value); } } who->printf("%s::%s == %i (r:%i)\n", what->id, flag_names[l], what->get_flag(l), what->get_rflag(l)); return true; } } who->printf("Unrecognised flag.\n"); return true; } static bool verb_pflags(MudObject *who, int argc, const char **argv) { MudObject *what = 0; if (argc>1) { what = find_object(who, argv[1]); if (!what) { who->printf("Whose pflags?\n"); return 1; } } else { what = who; } if (what != who && !who->get_priv(PFL_GOD)) { who->printf("I don't think so.\n"); return true; } if (argv[1] && argv[2]) { PFlag p = find_priv(argv[2]); if (p == PFL_NONE) { who->printf("Can't find that pflag.\n"); return true; } const char *now=""; if (argv[3]) { if (streq(argv[3], "deny") || no(argv[3])) { if (!who->get_priv(PFL_GOD)) { who->printf("I don't think so.\n"); return true; } if (!what->get_priv(p)) { who->printf("%#P %[doesn't/don't] have %s.\n", who, priv_names[p]); return true; } if (what->get_gpriv(p)) what->set_gpriv(p, 0); else what->set_wpriv(p, 1); now = "now "; } if (streq(argv[3], "grant") || yes(argv[3])) { if (!who->get_priv(PFL_GOD)) { who->printf("I don't think so.\n"); return true; } if (what->get_priv(p)) { who->printf("%#P already %[has/have] %s.\n", what, priv_names[p]); return true; } if (what->get_wpriv(p)) { what->set_wpriv(p, 0); if (!what->get_dpriv(p)) what->set_gpriv(p, 1); } else what->set_gpriv(p, 1); now = "now "; } if (streq(argv[3], "abey")) { what->set_apriv(p, 1); now = "now "; } if (streq(argv[3], "reclaim")) { what->set_apriv(p, 0); now = "now "; } if (!*now) { what->printf("Don't know how to %s - can deny and grant or abey and reclaim.\n", argv[3]); } } if (what->get_priv(p) && what->get_dpriv(p)) { who->printf("%#P %[is/are] %sentitled to and %[has/have] %s.\n", what, now, priv_names[p]); return true; } if (what->get_priv(p) && what->get_gpriv(p)) { who->printf("%#P %[has/have] %sbeen granted %s.\n", what, now, priv_names[p]); return true; } if (what->get_wpriv(p)) { who->printf("%#P %[has/have] %sbeen denied %s.\n", what, now, priv_names[p]); return true; } if (what->get_gpriv(p) && what->get_apriv(p)) { who->printf("%#P %[has/have] %sbeen granted %s but %[has/have] turned it off.\n", what, now, priv_names[p]); return true; } if (what->get_dpriv(p) && what->get_apriv(p)) { who->printf("%#P %[is/are] %sentitled to %s but %[has/have] turned it off.\n", what, now, priv_names[p]); return true; } who->printf("%#P %s%[doesn't/don't] have %s.\n", what, now, priv_names[p]); return true; } who->spec_printf("%#P %[has/have] been granted: ", what); for (PFlag l=PFlag(2);l<PFL_MAX;l++) if (what->get_priv(l) && !what->get_dpriv(l)) who->printf("%s ", priv_names[l]); if (who->cancel_printf()) who->printf("\n"); who->spec_printf("%#P %[is/are] entitled to: ", what); for (PFlag l=PFlag(2);l<PFL_MAX;l++) if (what->get_priv(l) && what->get_dpriv(l)) who->printf("%s ", priv_names[l]); if (who->cancel_printf()) who->printf("\n"); who->spec_printf("%#P %[have/has] has been stripped of: ", what); for (PFlag l=PFlag(2);l<PFL_MAX;l++) if (what->get_wpriv(l)) who->printf("%s ", priv_names[l]); if (who->cancel_printf()) who->printf("\n"); who->spec_printf("%#P %[have/has] placed in abeyance: ", what); for (PFlag l=PFlag(2);l<PFL_MAX;l++) if (what->get_dpriv(l) && !what->get_wpriv(l) && what->get_apriv(l)) who->printf("%s ", priv_names[l]); if (who->cancel_printf()) who->printf("\n"); return true; } static bool verb_rows(Player *who, int argc, const char **argv) { if (argc == 1) { who->printf("Syntax : rows <number>\n"); return true; } if (atoi(argv[1])<10) { who->printf("Rows must be >= 10.\n"); return true; } who->set("rows", atoi(argv[1])); if (who->p && who->p->col && !who->get_flag(FL_NONAWS)) { who->printf("Warning: NAWS is in effect, this overrides your set window size. Use 'NoNaws' to disable it'.\n"); return true; } return true; } static bool verb_columns(Player *who, int argc, const char **argv) { if (argc == 1) { who->printf("Syntax : columns <number>\n"); return true; } if (atoi(argv[1])<10) { who->printf("Columns must be >= 10.\n"); return true; } if (atoi(argv[1])>320) { who->printf("Columns must be <= 320.\n"); return true; } who->set("columns", atoi(argv[1])); if (who->p && who->p->col && !who->get_flag(FL_NONAWS)) { who->printf("Warning: NAWS is in effect, this overrides your set window size. Use 'NoNaws' to disable it'.\n"); return true; } who->printf("Done.\n"); return true; } static bool verb_wimpy(MudObject *who, int argc, const char **argv) { if (argc == 1) { who->printf("Syntax : wimpy <number>\n"); return true; } who->set("wimpy", atoi(argv[1])); return true; } static void compose_desc(Player *who, const char *what) { if (streq(what, ".") || streq(what, "**")) { who->pop_state(); MudObject *what = (MudObject *)planet->get(who->get("!desc.what")); if (!what) { who->printf("Can't find that object.\nOops. Hope that description wasn't very long :).\n"); return; } string descbuffer = who->get("!desc.buffer"); if (descbuffer.length()==0) { what->unset(who->get("!desc.prop")); } else { if (strncmp(who->get("!desc.prop"), "lua.", 4)==0) { string db = ","; db += who->id; db += ",1;"; db += descbuffer; descbuffer = db; } descbuffer.erase((int)descbuffer.length()-1, 1); what->set(who->get("!desc.prop"), descbuffer.c_str()); log(PFL_SEEINFO, LEV_INTERNAL, "fiddle", "set %s :: %s with desc", what->id, who->get("!desc.prop")); } } if (streq(what, "!") || streq(what, "~")) { who->printf("OK. abandoning desc\n"); who->pop_state(); } string descbuffer = who->get("!desc.buffer"); descbuffer += what; descbuffer += "\n"; who->set("!desc.buffer", descbuffer.c_str()); } static bool verb_namestyle(MudObject *w, int argc, const char **argv) { MudObject *what = w->owner; if (!cantouch_zone(w, what->get("zone"))) { w->printf("You don't have write privs here.\n"); return true; } int wanted = DIRECT; if (argc>1) { string a = argv[1]; if (argc>2) { a += argv[2]; } const char *b = a.c_str(); if (streq(b, "in")) wanted = IN; if (streq(b, "inthe")) wanted = IN_THE; if (streq(b, "on")) wanted = ON; if (streq(b, "onthe")) wanted = ON_THE; if (streq(b, "by")) wanted = BY; if (streq(b, "bythe")) wanted = BY_THE; if (streq(b, "at")) wanted = AT; if (streq(b, "atthe")) wanted = AT_THE; if (streq(b, "onboard")) wanted = ON_BOARD; } w->owner->set("namestyle", wanted); return true; } static bool verb_description(MudObject *w, int argc, const char **argv) { if (argc < 2) { w->printf("syntax: description me, here, or <what>\n"); return true; } if (!is_player(w)) { w->printf("Sorry, only real players can do this..\n"); return true; } Player *who = (Player *)w; MudObject *what = planet->get(argv[1]); if (streq(argv[1], "me")) what = who; if (streq(argv[1], "here")) what = who->owner; if (streq(argv[1], "HERE")) what = who->owner; if (!what) { who->printf("Cannot find object called : %s\n", argv[1]); return true; } if (what->get_object("$player")==w) { who->set("!desc.what", what->id); who->set("!desc.buffer", ""); who->set("!desc.prop", "$desc"); who->printf(". to finish, ~ to abort.\n"); who->push_state( "make.desc"); return true; } if (!w->get_priv(PFL_MAKE) && what != w) { who->printf("You can only set your own (or your quarters') description.\n"); return true; } int allow_custom = 0; if (what != who) { if (!cantouch_zone(who, what->get("zone"))) { who->printf("You can't edit that zone.\n"); return true; } allow_custom = who->get_priv(PFL_CODER); } else { allow_custom = who->get_priv(PFL_CODER); } if (what->get_flag(FL_WILDERNESS)) { who->printf("You really don't want to edit that.\n"); return true; } const char *prop = "desc"; if (argv[2]) { if (allow_custom) prop = argv[2]; else { who->printf("You can only set descriptions with desc.\n"); return true; } } who->set("!desc.what", what->id); who->set("!desc.buffer", ""); who->set("!desc.prop", prop); who->printf(". to finish, ~ to abort.\n"); who->push_state( "make.desc"); return true; } static bool verb_alias(MudObject *who, int argc, const char **argv) { Divert d(who, "alias"); if(argc==1) { int count=0; Object::strit i = who->strs.begin(); while(i != who->strs.end()) { const char *key = i->first.c_str(); if(!strncmp(key,"alias.",6)) { if(!count)who->printf("^WYour current aliases^n:\n"); who->printf("%-13s ^B:^n %s\n", (key)+6 , escape_colour((string)who->get(key)).c_str()); count++; } i++; } if(!count) who->printf("^WYou have no aliases^n\n"); } else if(argc==2) { //who->printf("Attempting to remove %s from your list of aliases...\n",argv[1]); char key[1024]; snprintf(key,1024,"alias.%s",argv[1]); if(!(who->get(key)==NULL)) { who->unset(key); who->printf("^W%s^n is no longer in your alias list.\n",argv[1]); } else { who->printf("Can't find ^W%s^n in your alias list.\n",argv[1]); } } else { if(!strcmp(argv[1],"alias")) { who->printf("An alias for alias? Don't be silly.\n"); return true; } if(!strcmp(argv[2],"at") || !strcmp(argv[2],"by")) { who->printf("You can't create aliases for 'at' or 'by' for recursive reasons.\n"); return true; } //who->printf("Attempting to add %s to your list of aliases...\n",argv[1]); char key[1024]; snprintf(key,1024,"alias.%s",argv[1]); char value[1024]; int counter=strlen(argv[2]); strncpy(value,argv[2],1023); value[1023]='\0'; if(argc>=3) for(int i=3;i<argc;i++) { char temp[1024]; snprintf(temp, 1024," %s",argv[i]); counter+=strlen(temp); if(counter>1023) break; strncat(value,temp,1023-counter); } value[1023]='\0'; who->printf("Adding ^W%s^n (%s^n) to your alias list.\n",argv[1],escape_colour(value).c_str()); Verb *v = verbs->get(argv[1]); if (v) who->printf("^RWarning^n: this overrides the '%s' command'.\n", v->id); who->set(key,value); } return true; } #if 0 bool verb_pn(MudObject *who, int argc, const char **argv) { who->printf("Me : %M.\n", who); who->printf("It : %Y.\n", who->get_object("!it")); who->printf("Her : %M.\n", who->get_object("!her")); who->printf("Him : %M.\n", who->get_object("!him")); who->printf("Them: %M.\n", who->get_object("!them")); return true; } #endif static bool verb_timezone(MudObject *who, int argc, const char **argv) { const char *tz = who->get("timezone"); if (!tz) tz = MUD_DEFTZ; string tzs = tz; tz = tzs.c_str(); if (argc==1) { who->printf("Your timezone is currently %s.\n", tz); return 1; } if (argc==2) { who->set("timezone", argv[1]); who->printf("Your timezone is now %s (was %s).\n", argv[1], tz); } return true; } #define CREATE_VERB(what) \ static bool verb_##what(MudObject *who, int argc, const char **argv) { \ if (argc==1) { who->printf("syntax: " #what " <message>\n"); \ return true; } string txt = the_rest(argc, argv, 1); \ if (streq(txt.c_str(), "\\")) who->unset(#what); else who->set(#what, txt.c_str()); \ return true; } CREATE_VERB(setmin) CREATE_VERB(setmout) CREATE_VERB(setqin) CREATE_VERB(setqout) CREATE_VERB(setvin) CREATE_VERB(setvout) #include "verbmodule.h" void startup() { #define SET(a) AUTO_VERB(set##a, THING, 0, PFL_SETIN) #define THING 5 SET(vin); SET(vout); SET(qin); SET(qout); SET(min); SET(mout); #undef THING #define verb_tflags verb_flags #define verb_rflags verb_flags AUTO_VERB(timezone, 5, 0, PFL_NONE); AUTO_VERB(prompt, 4, 0, PFL_NONE); AUTO_VERB(unreset, 5, 0, PFL_MAKE); AUTO_VERB(flags, 2, 0, PFL_MAKE); AUTO_VERB(rflags, 2, 0, PFL_MAKE); AUTO_VERB(tflags, 2, 0, PFL_MAKE); AUTO_VERB(wimpy, 3, 0, PFL_NONE); AUTO_VERB(rows, 4, 0, PFL_NONE); AUTO_VERB(columns, 3, 0, PFL_NONE); ADD_ALIAS(cols, 4, columns); AUTO_VERB(pflags, 2, 0, PFL_NONE); AUTO_VERB(homeroom, 5, 0, PFL_GOTO); AUTO_VERB(nametransplant, 5, 0, PFL_NONE); AUTO_VERB(description, 4, 0, PFL_NONE); ADD_STATE("make.desc", "Desc : ", compose_desc, false); AUTO_VERB(alias,5,0,PFL_NONE); AUTO_VERB(namestyle, 2, 0, PFL_MAKE); AUTO_VERB(review, 3, 0, PFL_SETIN); #if 0 AUTO_VERB(pn, 2, 0, PFL_NONE); #endif for (int i=0;i<ELEMENTS(setfinger);i++) { ADD_VERB(setfinger[i].cmd, strlen(setfinger[i].cmd), verb_setfinger, 0, PFL_NONE); } }