/* Crimson2 Mud Server * All source written/copyright Ryan Haksi 1995 * * This source code is proprietary. Use in whole or in part without * explicity permission by the author is strictly prohibited * * Current email address(es): cryogen@infoserve.net * Phone number: (604) 591-5295 * * C4 Script Language written/copyright Cam Lesiuk 1995 * Email: clesiuk@engr.uvic.ca */ /* Inventory related commands */ #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <time.h> #include "crimson2.h" #include "macro.h" #include "queue.h" #include "log.h" #include "str.h" #include "ini.h" #include "extra.h" #include "file.h" #include "thing.h" #include "index.h" #include "edit.h" #include "history.h" #include "socket.h" #include "alias.h" #include "area.h" #include "exit.h" #include "world.h" #include "send.h" #include "base.h" #include "object.h" #include "char.h" #include "mobile.h" #include "fight.h" #include "affect.h" #include "effect.h" #include "player.h" #include "skill.h" #include "parse.h" #include "cmd_god.h" #include "cmd_misc.h" COLORPREFLIST colorPrefList[] = { { "Name:", '0', 0 }, { "Description:", '1', 0 }, { "LDesc:", '2', 0 }, { "Info-text:", '3', 0 }, { "Info-filler:", '4', 0 }, { "Info-highlight:", '5', 0 }, { "Speech:", '6', 0 }, { "Fight-Hit:", '7', 0 }, { "Fight-Damage:", '8', 0 }, { "Fight-Others:", '9', 0 }, { "Channels:", ':', 1 }, { "Hint-Text:", ';', 1 }, { "Hint-Highlight:", '<', 1 }, { "", '=', 0 }, { "", '>', 0 }, { "", '?', 0 }, { "", '@', 0 }, }; CMDPROC(CmdTitle) { /* Cmd(THING *thing, BYTE *cmd) */ BYTE buf[512]; BYTE *i; cmd = StrOneWord(cmd, NULL); /* lose the command at the start */ i = StrFind(cmd, "$$n"); while (i && i[2]=='N') i=StrFind(i+1, "$$n"); if (i) { /* convert $$n into $n */ while( *(i+1) ) { *i = *(i+1); i++; } *i = '\0'; /* copy null too */ sprintf(buf, "%s", cmd); } else { sprintf(buf, "$n %s", cmd); } SendThing("^GOkay Doke, you are now:\n^g", thing); STRFREE(Base(thing)->bLDesc); Base(thing)->bLDesc = STRCREATE(buf); /* name & title */ SendAction(Base(thing)->bLDesc->sText, thing, NULL, SEND_SRC); SendThing("\n", thing); } /* at some point you should be able to who names to skip the titles */ /* also who gods */ CMDPROC(CmdWho) { /* Cmd(THING *thing, BYTE *cmd) */ SOCK *sock; SOCK *s; BYTE buf[256]; LWORD i = 0; sock = BaseControlFind(thing); if (!sock) return; SendThing("^pWho's on with you:\n", thing); SendThing("^P-----------------\n", thing); for (s = sockList; s; s=s->sNext) { if (s->sHomeThing) { /* block out those halfway thru signon */ i++; if (Character(s->sHomeThing)->cLevel>=LEVEL_IMMORTAL) { if (Character(s->sHomeThing)->cLevel>=LEVEL_CODER) SendThing("^WIMP ^w", thing); else if (Character(s->sHomeThing)->cLevel>=LEVEL_ADMIN) SendThing("^WADM ^w", thing); else if (Character(s->sHomeThing)->cLevel>=LEVEL_GOD) SendThing("^WGOD ^p", thing); else SendThing("^WIMM ^r", thing); } else SendThing("^W ^g", thing); /* Should use ThingShow so they can see flags */ SendAction(Base(s->sHomeThing)->bLDesc->sText, s->sHomeThing, thing, SEND_DST|SEND_CAPFIRST|SEND_SELF); if (Plr(s->sHomeThing)->pIdleTick > playerIdleTick) { sprintf(buf, " <IDLE %ldM>", Plr(s->sHomeThing)->pIdleTick); SendThing(buf, thing); } if (BIT(Plr(s->sHomeThing)->pAuto, PA_AFK)) SendThing(" <AFK>", thing); /* Show if they are signing on */ if (s->sMode != MODE_PLAY) { if (Character(sock->sHomeThing)->cLevel >= LEVEL_GOD) { SendThing(" <", thing); SendThing(sModeList[s->sMode], thing); SendThing(">", thing); } else SendThing(" <SIGNING ON>", thing); } } else SendThing("<New Connect in Progress>", thing); SendThing("^V\n", thing); } sprintf(buf, "^w%ld ^pPeople total\n", i); SendThing(buf, thing); } CMDPROC(CmdWhere) { /* Cmd(THING *thing, BYTE *cmd) */ BYTE srcKey[256]; LWORD srcNum; LWORD srcOffset; THING *found; SOCK *sock; THING *homeThing; BYTE buf[256]; BYTE truncateStr[256]; LWORD i = 0; LWORD area; sock = BaseControlFind(thing); if (!sock) return; homeThing = sock->sHomeThing; cmd = StrOneWord(cmd, NULL); /* lose the command at the start */ SendThing("^pWhere on earth is everybody:\n", thing); SendThing("^P---------------------------\n", thing); if (!Base(thing)->bInside || Base(thing)->bInside->tType != TTYPE_WLD) return; area = Wld(Base(thing)->bInside)->wArea; /* Show where all the players are */ if (!*cmd) { for (sock = sockList; sock; sock=sock->sNext) { if (sock->sHomeThing && Base(sock->sHomeThing)->bInside && Base(sock->sHomeThing)->bInside->tType == TTYPE_WLD && ( Wld(Base(sock->sHomeThing)->bInside)->wArea == area ||Character(homeThing)->cLevel >= LEVEL_GOD )) { /* block out those halfway thru signon */ i++; /* show the person */ if (i%2) SendThing(" ^r", thing); else SendThing(" ^R", thing); sprintf(buf, "%-25s - ", StrTruncate(truncateStr, sock->sHomeThing->tSDesc->sText, 25)); SendThing(buf, thing); /* show the location */ if (i%2) SendThing("^c", thing); else SendThing("^C", thing); SendThing(Base(sock->sHomeThing)->bInside->tSDesc->sText, thing); /* Gods get to see the area */ if ( Character(homeThing)->cLevel >= LEVEL_GOD ) { LWORD area; BYTE word[256]; BYTE truncateStr[256]; /* Find area name */ area = Wld( Base(sock->sHomeThing)->bInside )->wArea; StrFirstWord(areaList[area].aFileName->sText,word); StrTruncate(truncateStr, word, 25); /* send it */ SendThing(" (", thing); SendThing( truncateStr, thing); SendThing(")", thing); sprintf(word, " [%ld]", Wld( Base(sock->sHomeThing)->bInside )->wVirtual); SendThing(word, thing); } SendThing("\n", thing); } } sprintf(buf, "^w%ld ^pPeople total\n", i); SendThing(buf, thing); return; } /* show matching mobs and plrs in the same area */ cmd = ParseFind(cmd, srcKey, &srcOffset, &srcNum, NULL, NULL); found = ThingFind(srcKey, -1, Base(thing)->bInside, TF_MOB|TF_PLR|TF_MOB_WLD|TF_PLR_WLD, &srcOffset); if (!found) { SendThing("^wWhere's who?, Never heard of 'em\n", thing); return; } while (found && srcNum!=0 && i<50) { if (found && Base(found)->bInside && Base(found)->bInside->tType == TTYPE_WLD && ( Wld(Base(found)->bInside)->wArea == area ||Character(homeThing)->cLevel >= LEVEL_GOD )) { /* block out those halfway thru signon */ i++; /* show the person */ if (i%2) SendThing(" ^r", thing); else SendThing(" ^R", thing); sprintf(buf, "%-25s - ", StrTruncate(truncateStr, found->tSDesc->sText, 25)); SendThing(buf, thing); /* show the location */ if (i%2) SendThing("^c", thing); else SendThing("^C", thing); SendThing(Base(found)->bInside->tSDesc->sText, thing); SendThing("\n", thing); } else { if (srcNum>=0) srcNum++; } found = ThingFind(srcKey, -1, Base(thing)->bInside, TF_MOB|TF_PLR|TF_MOB_WLD|TF_PLR_WLD|TF_CONTINUE, &srcOffset); } } CMDPROC(CmdSave) { /* Cmd(THING *thing, BYTE *cmd) */ SOCK *sock; sock = BaseControlFind(thing); SendThing("^wSaving your Player Data\n", thing); PlayerWrite(sock->sHomeThing, PWRITE_CRASH); } /******************* CmdSet - Start ************************/ /* The following is all to do with the Set command, it's kind of complicated but it allows nicely formatted output and easy addition of arbitrary columns and rows */ #define SV_TITLE 0 /* title no flag */ #define SV_SOCKPREF 1 /* socket preference flag */ #define SV_AUTO 2 /* autoaction preference */ #define SV_SYSTEM 3 /* Player system */ FLAG *SetFlag(SOCK *sock, LWORD flagNum) { if (!sock) return NULL; switch (flagNum) { case SV_SOCKPREF: return &(sock->sPref); case SV_SYSTEM: return &(Plr(sock->sHomeThing)->pSystem); case SV_AUTO: return &(Plr(sock->sHomeThing)->pAuto); default: return NULL; } } struct SetType { BYTE *sName; LWORD sColumn; LWORD sVariable; LWORD sFlag; BYTE *sCmd; /* priviledge based on this cmd # */ }; #define MAX_COLUMN 4 struct SetType expertSetList[] = { { "SOCKET:", 0, SV_TITLE, 0, NULL }, { "Car.Ret.", 0, SV_SOCKPREF, SP_CR, NULL }, { "LineFeed", 0, SV_SOCKPREF, SP_LF, NULL }, { "Continue", 0, SV_SOCKPREF, SP_CONTINUE, NULL }, { "TelnetGA", 0, SV_SOCKPREF, SP_TELNETGA, NULL }, { "Ansi", 0, SV_SOCKPREF, SP_ANSI, NULL }, { "Compact", 0, SV_SOCKPREF, SP_COMPACT, NULL }, { " " , 0, SV_TITLE, 0, NULL }, /* spacer must be " " */ { "ScreenSize", 0, SV_TITLE, SP_COMPACT, NULL }, { " " , 0, SV_TITLE, 0, NULL }, /* spacer must be " " */ /* so people see the words */ { "INFO:", 0, SV_TITLE, 0, NULL }, /* spacer must be " " */ { "^3Description",0, SV_TITLE, 0, NULL, }, { "^3Email", 0, SV_TITLE, 0, NULL, }, { "^3Plan", 0, SV_TITLE, 0, NULL, }, { "CHANNELS:", 1, SV_TITLE, 0, NULL }, { "Private", 1, SV_SOCKPREF, SP_CHANPRIVATE, NULL }, { "Group", 1, SV_SOCKPREF, SP_CHANGROUP, NULL }, { "Gossip", 1, SV_SOCKPREF, SP_CHANGOSSIP, NULL }, { "Auction", 1, SV_SOCKPREF, SP_CHANAUCTION, NULL }, { "Usage", 1, SV_SOCKPREF, SP_CHANUSAGE, NULL }, { "Tick", 1, SV_SOCKPREF, SP_CHANTICK, NULL }, { "Port", 1, SV_SOCKPREF, SP_CHANPORT, "stat" }, { "Error", 1, SV_SOCKPREF, SP_CHANERROR, "stat" }, { "God", 1, SV_SOCKPREF, SP_CHANGOD, "stat" }, { "Area", 1, SV_SOCKPREF, SP_CHANAREA, "astat" }, /* { "Spy", 1, SV_SOCKPREF, SP_CHANSPY, "stat" },*/ { "Board", 1, SV_SOCKPREF, SP_CHANBOARD, "blist" }, { "PROMPT:", 2, SV_TITLE, 0, NULL }, { "Hit Pts", 2, SV_SOCKPREF, SP_PROMPTHP, NULL }, { "Move Pts", 2, SV_SOCKPREF, SP_PROMPTMV, NULL }, { "Power Pts", 2, SV_SOCKPREF, SP_PROMPTPP, NULL }, { "Room #'s", 2, SV_SOCKPREF, SP_PROMPTRM, "wgoto" }, { "Exits", 2, SV_SOCKPREF, SP_PROMPTEX, NULL }, { " " , 2, SV_TITLE , 0, NULL }, /* spacer must be " " */ { "PREFS:", 2, SV_TITLE, 0, NULL }, { "NoEmail", 2, SV_AUTO, PA_NOEMAIL, NULL }, { "Hint", 2, SV_AUTO, PA_HINT, NULL }, { "Expert", 2, SV_AUTO, PA_EXPERT, NULL }, { "NoHassle", 2, SV_SYSTEM, PS_NOHASSLE, "mload" }, { "AFK", 2, SV_AUTO, PA_AFK, NULL }, { "AUTO:", 3, SV_TITLE, 0, NULL }, { "AutoLook", 3, SV_AUTO, PA_AUTOLOOK, NULL }, { "AutoExit", 3, SV_AUTO, PA_AUTOEXIT, NULL }, { "AutoLoot", 3, SV_AUTO, PA_AUTOLOOT, NULL }, { "AutoAssist", 3, SV_AUTO, PA_AUTOASSIST, NULL }, { "AutoAggr", 3, SV_AUTO, PA_AUTOAGGR, NULL }, { "AutoRescue", 3, SV_AUTO, PA_AUTORESCUE, NULL }, { "AutoJunk", 3, SV_AUTO, PA_AUTOJUNK, NULL }, { "AutoFlee", 3, SV_AUTO, PA_AUTOFLEE, NULL }, { "AutoEat", 3, SV_AUTO, PA_AUTOEAT, NULL }, { "AutoDrink", 3, SV_AUTO, PA_AUTODRINK, NULL }, { "Consider", 3, SV_AUTO, PA_CONSIDER, NULL }, { "" , -1, SV_TITLE, 0, NULL } }; struct SetType newbieSetList[] = { { "SOCKET:", 0, SV_TITLE, 0, NULL }, { "Ansi", 0, SV_SOCKPREF, SP_ANSI, NULL }, { " " , 0, SV_TITLE, 0, NULL }, /* spacer must be " " */ /* so people see the words */ { "INFO:", 0, SV_TITLE, 0, NULL }, /* spacer must be " " */ { "^3Description",0, SV_TITLE, 0, NULL, }, { "^3Email", 0, SV_TITLE, 0, NULL, }, { "^3Plan", 0, SV_TITLE, 0, NULL, }, { "CHANNELS:", 1, SV_TITLE, 0, NULL }, { "Private", 1, SV_SOCKPREF, SP_CHANPRIVATE, NULL }, { "Group", 1, SV_SOCKPREF, SP_CHANGROUP, NULL }, { "Gossip", 1, SV_SOCKPREF, SP_CHANGOSSIP, NULL }, { "Auction", 1, SV_SOCKPREF, SP_CHANAUCTION, NULL }, { "Usage", 1, SV_SOCKPREF, SP_CHANUSAGE, NULL }, { "PROMPT:", 2, SV_TITLE, 0, NULL }, { "Hit Pts", 2, SV_SOCKPREF, SP_PROMPTHP, NULL }, { "Move Pts", 2, SV_SOCKPREF, SP_PROMPTMV, NULL }, { "Power Pts", 2, SV_SOCKPREF, SP_PROMPTPP, NULL }, { "Exits", 2, SV_SOCKPREF, SP_PROMPTEX, NULL }, { " " , 2, SV_TITLE , 0, NULL }, /* spacer must be " " */ { "PREFS:", 2, SV_TITLE, 0, NULL }, { "Expert", 2, SV_AUTO, PA_EXPERT, NULL }, { "AUTO:", 3, SV_TITLE, 0, NULL }, { "AutoLook", 3, SV_AUTO, PA_AUTOLOOK, NULL }, { "AutoFlee", 3, SV_AUTO, PA_AUTOFLEE, NULL }, { "AutoEat", 3, SV_AUTO, PA_AUTOEAT, NULL }, { "AutoDrink", 3, SV_AUTO, PA_AUTODRINK, NULL }, { "" , -1, SV_TITLE, 0, NULL } }; /* This proc goes through the thing's setting list and makes sure * it has permission to have all it's set's set. */ void SetFlagCheck(THING *thing) { LWORD i; SOCK *sock; FLAG *flag; if (!thing) return; if (thing->tType!=TTYPE_PLR) return; sock = BaseControlFind(thing); for (i=0; expertSetList[i].sName[0]; i++) { if (expertSetList[i].sCmd) { /* this is a restricted flag - let's check it */ if (!ParseCommandCheck(TYPEFIND(expertSetList[i].sCmd,commandList),sock, "")) { /* uh oh, clear this sucker! if it's set! */ flag = SetFlag(sock, expertSetList[i].sVariable); if (flag) BITCLR(*flag, expertSetList[i].sFlag); } } } } CMDPROC(CmdSet) { /* Cmd(THING *thing, BYTE *cmd) */ struct SetType * setList; LWORD columnIndex[MAX_COLUMN]; BYTE bufColumn[256]; BYTE bufLine[512]; BYTE word[256]; FLAG *flag; LWORD i; LWORD temp; BYTE notDone = TRUE; SOCK *sock; BYTE expert = FALSE; /* what are we doing */ cmd = StrOneWord(cmd, word); /* toss "set" */ cmd = StrOneWord(cmd, word); /* grab argument (if any) */ /* need this to change socket prefs */ sock = BaseControlFind(thing); /* Determine is expert is set */ if (sock && BIT(Plr(sock->sHomeThing)->pAuto, PA_EXPERT)) expert = TRUE; /* Give them appropriate list of options to change */ if (expert) setList = expertSetList; else setList = newbieSetList; /* See if they want to change a flag setting */ if (*word) { for (i=0; setList[i].sName[0]; i++) { /* ignore color code to determine match */ if (StrAbbrev(setList[i].sName, word) || (setList[i].sName[0]=='^' && StrAbbrev(setList[i].sName+2, word)) ) { if (setList[i].sCmd && !ParseCommandCheck(TYPEFIND(setList[i].sCmd, commandList), sock, "")) { SendThing("^cI'm afraid you're not authorized to do that\n", thing); return; } if (setList[i].sVariable!=SV_TITLE) { flag = SetFlag(sock, setList[i].sVariable); BITFLIP(*flag, setList[i].sFlag); sprintf( bufLine, "^3Setting ^5%s^3 to ^5%-3s^V\n", setList[i].sName, BIT(*flag, setList[i].sFlag) ? "On" : "Off" ); SendThing(bufLine, thing); Plr(sock->sHomeThing)->pSockPref = sock->sPref; return; } else if (!strcmp(setList[i].sName, "ScreenSize")) { /* special case for screen size */ cmd = StrOneWord(cmd, word); /* grab argument (if any) */ if (!word) { SendThing("^cYes but what do you want to set it to?\n", thing); return; } sock->sScreenLines = atoi(word); MINSET(sock->sScreenLines, 5); temp = sock->sScreenLines; sprintf(bufLine, "^3Setting ^5ScreenSize^3 to ^5%ld\n", temp); SendThing(bufLine, thing); Plr(sock->sHomeThing)->pScreenLines = temp; return; } else if (!strcmp(setList[i].sName, "^3Description")) { EditStr(sock, &sock->sHomeThing->tDesc, 512, "Player Description", EP_ENDLF); return; } else if (!strcmp(setList[i].sName, "^3Email")) { SendThing("^cEnter your email address:\n", thing); EditStr(sock, &Plr(sock->sHomeThing)->pEmail, 128, "Email Address", EP_IMMNEW|EP_ONELINE|EP_ENDNOLF); return; } else if (!strcmp(setList[i].sName, "^3Plan")) { EditStr(sock, &Plr(sock->sHomeThing)->pPlan, 512, "Plan Description", EP_ENDLF); return; } } } SendThing("^cWhat was it you wanted to set now?\n", thing); return; } /* setup to display all the settings */ notDone = TRUE; for (i=0; i<MAX_COLUMN; i++) /* init all the column indices to zero */ columnIndex[i]=0; /* Okay List what all the flags are currently */ while (notDone) { bufLine[0] = '\0'; notDone = FALSE; /* print one from each column */ for (i = 0; i<MAX_COLUMN; i++) { /* find next column entry that they are authorized to see */ while((setList[columnIndex[i]].sName[0] ) &&( (setList[columnIndex[i]].sColumn!=i) ||( (setList[columnIndex[i]].sCmd) &&(!ParseCommandCheck(TYPEFIND(setList[columnIndex[i]].sCmd, commandList), sock, "")) ))) columnIndex[i]++; /* Write out column data */ flag = SetFlag(sock, setList[columnIndex[i]].sVariable); if (!flag) { if (!strcmp(setList[columnIndex[i]].sName, "ScreenSize")){ /* special case for screen size */ temp = sock->sScreenLines; sprintf(bufColumn, "^3%-12s^5%-7ld", setList[columnIndex[i]].sName, temp); } else /* Allow for color formats in TITLE's */ if (setList[columnIndex[i]].sName[0] == '^') sprintf(bufColumn, "^%c%-19s", setList[columnIndex[i]].sName[1], setList[columnIndex[i]].sName+2); else sprintf(bufColumn, "^4%-19s", setList[columnIndex[i]].sName); } else { sprintf( bufColumn, "^3%-12s^5%-7s^V", setList[columnIndex[i]].sName, BIT(*flag, setList[columnIndex[i]].sFlag) ? "On" : "Off" ); } /* See if we have displayed every entry to this column */ if (setList[columnIndex[i]].sName[0]) { columnIndex[i]++;/* still going */ notDone = TRUE; /* as long as at least one column printed something keep going */ } strcat(bufLine, bufColumn); } if (notDone) { strcat(bufLine, "\n"); SendThing(bufLine, thing); } } SendHint("^V\n", thing); SendHint("^;HINT: See also ^<SETCOLOR^;\n", thing); } /******************* CmdSet - End **************************/ CMDPROC(CmdScore) { /* void CmdProc(THING *thing, BYTE* cmd) */ BYTE buf[256]; BYTE buf2[256]; BYTE expert = FALSE; SOCK *sock; LWORD gain; /* Determine is expert is set */ sock = BaseControlFind(thing); if (sock && BIT(Plr(sock->sHomeThing)->pAuto, PA_EXPERT)) expert = TRUE; /* show them the stats */ SendThing("^3SDesc:^4[^0", thing); SendThing(thing->tSDesc->sText, thing); SendThing("^4]\n^3LDesc: ^2", thing); SendAction(Base(thing)->bLDesc->sText, thing, NULL, SEND_SRC); SendThing("\n", thing); SendThing("^3Description:\n^1", thing); SendThing(thing->tDesc->sText, thing); if (thing->tType == TTYPE_PLR) { SendThing("^3Class:^4[^5", thing); TYPESPRINTF(buf2, Plr(thing)->pClass, classList, sizeof(buf2)); strcat(buf2, "^4]"); sprintf(buf, "%-13s ", buf2); SendThing(buf, thing); SendThing(" ^3Race:^4[^5", thing); SendThing(TYPESPRINTF(buf, Plr(thing)->pRace, raceList, sizeof(buf)), thing); SendThing("^4]\n", thing); } sprintf(buf, "^3Level:^4[^5%4hd^4] ", Character(thing)->cLevel); SendThing(buf, thing); if (expert) { sprintf(buf, " ^3Aura:^4[^5%4hd^4]", Character(thing)->cAura); SendThing(buf, thing); } SendThing(" ^3Sex:^4[^5", thing); SendThing(TYPESPRINTF(buf, Character(thing)->cSex, sexList, 512), thing); SendThing("^4]\n", thing); sprintf(buf, "^3Armor:^4[^5%4hd^4] ", Character(thing)->cArmor); SendThing(buf, thing); if (expert) { sprintf(buf, " ^3HitBonus:^4[^5%4ld^4] ", CharGetHitBonus(thing, Character(thing)->cWeapon)); SendThing(buf, thing); sprintf(buf, " ^3DamBonus:^4[^5%4ld^4]", CharGetDamBonus(thing, Character(thing)->cWeapon)); SendThing(buf, thing); } SendThing("\n", thing); sprintf(buf2, "^3Money:^4[^5%ld^4] ", Character(thing)->cMoney); sprintf(buf, "%-34s ", buf2); SendThing(buf, thing); if (thing->tType == TTYPE_PLR) { sprintf(buf2, "^3Bank:^4[^5%ld^4] ", Plr(thing)->pBank); sprintf(buf, "%-34s ", buf2); SendThing(buf, thing); } sprintf(buf, "^3Exp:^4[^5%ld^4/^5%ld^4]\n", Character(thing)->cExp, PlayerExpNeeded(thing)); SendThing(buf, thing); if (thing->tType == TTYPE_PLR) { sprintf(buf2, "^3Fame:^4[^5%hd^4] ", Plr(thing)->pFame); sprintf(buf, "%-34s ", buf2); SendThing(buf, thing); sprintf(buf, "^3Infamy:^4[^5%hd^4]\n", Plr(thing)->pInfamy); SendThing(buf, thing); } if (thing->tType == TTYPE_PLR && expert) { gain = raceList[Plr(thing)->pRace].rGainHunger; gain = CharGainAdjust(thing, GAIN_HUNGER, gain); MINSET(gain, 1); SendThing("\n^5Your Abilities are currently:\n^3", thing); sprintf(buf, "^3Str: ^4[^5%4hd^4] ^3HP:^4[^5%5ld^4/^5%5ld^3] ^3Hunger:^4[^5%hd/%hd^4] +^5%ld^4/tick\n", Plr(thing)->pStr, Character(thing)->cHitP, CharGetHitPMax(thing), Plr(thing)->pHunger, raceList[Plr(thing)->pRace].rMaxHunger, gain ); SendThing(buf, thing); gain = raceList[Plr(thing)->pRace].rGainThirst; gain = CharGainAdjust(thing, GAIN_THIRST, gain); MINSET(gain, 1); sprintf(buf, "^3Dex: ^4[^5%4hd^4] ^3MP:^4[^5%5ld^4/^5%5ld^3] ^3Thirst:^4[^5%hd/%hd^4] +^5%ld^4/tick\n", Plr(thing)->pDex, Character(thing)->cMoveP, CharGetMovePMax(thing), Plr(thing)->pThirst, raceList[Plr(thing)->pRace].rMaxThirst, gain ); SendThing(buf, thing); sprintf(buf, "^3Con: ^4[^5%4hd^4] ^3PP:^4[^5%5ld^4/^5%5ld^3] ^3Intox: ^4[^5%hd/%hd^4] -^5%hd^4/tick\n", Plr(thing)->pCon, Character(thing)->cPowerP, CharGetPowerPMax(thing), Plr(thing)->pIntox, raceList[Plr(thing)->pRace].rMaxIntox, raceList[Plr(thing)->pRace].rGainIntox ); SendThing(buf, thing); sprintf(buf, "^3Wis: ^4[^5%4hd^4]\n", Plr(thing)->pWis); SendThing(buf, thing); sprintf(buf, "^3Int: ^4[^5%4hd^4] ^3Practices:^4[^5%ld^4]\n", Plr(thing)->pInt, Plr(thing)->pPractice); SendThing(buf, thing); } else { sprintf(buf, "^3HP:^4[^5%5ld^4/^5%5ld^3]\n", Character(thing)->cHitP, CharGetHitPMax(thing)); SendThing(buf, thing); sprintf(buf, "^3MP:^4[^5%5ld^4/^5%5ld^3]\n", Character(thing)->cMoveP, CharGetMovePMax(thing)); SendThing(buf, thing); sprintf(buf, "^3PP:^4[^5%5ld^4/^5%5ld^3]\n", Character(thing)->cPowerP, CharGetPowerPMax(thing)); SendThing(buf, thing); } if (expert) { SendThing("\nYour Resistances are:\n", thing); sprintf(buf, "^3Puncture ^4[^5%3hd^4]", CharGetResist(thing, FD_PUNCTURE)); SendThing(buf, thing); sprintf(buf, " ^3Slash ^4[^5%3hd^4]", CharGetResist(thing, FD_SLASH)); SendThing(buf, thing); sprintf(buf, " ^3Concussive^4[^5%3hd^4]\n", CharGetResist(thing, FD_CONCUSSIVE)); SendThing(buf, thing); sprintf(buf, "^3Heat ^4[^5%3hd^4]", CharGetResist(thing, FD_HEAT)); SendThing(buf, thing); sprintf(buf, " ^3EMR ^4[^5%3hd^4]", CharGetResist(thing, FD_EMR)); SendThing(buf, thing); sprintf(buf, " ^3Laser ^4[^5%3hd^4]\n", CharGetResist(thing, FD_LASER)); SendThing(buf, thing); sprintf(buf, "^3Psychic ^4[^5%3hd^4]", CharGetResist(thing, FD_PSYCHIC)); SendThing(buf, thing); sprintf(buf, " ^3Acid ^4[^5%3hd^4]", CharGetResist(thing, FD_ACID)); SendThing(buf, thing); sprintf(buf, " ^3Poison ^4[^5%3hd^4]\n", CharGetResist(thing, FD_POISON)); SendThing(buf, thing); SendThing("\n^3Affected by: ^4[^5", thing); SendThing(FlagSprintf(buf, Character(thing)->cAffectFlag, affectList, ' ', 512), thing); SendThing("^4]\n", thing); if (Character(thing)->cAffect) { SendHint("^;HINT: You can see what is affecting you by typing ^<AFFECT^;\n", thing); } } } CMDPROC(CmdAlias) { /* Cmd(THING *thing, BYTE *cmd) */ ALIAS *alias; SOCK *sock; BYTE buf[512]; BYTE word[256]; LWORD i; sock = BaseControlFind(thing); if (!sock) return; cmd = StrOneWord(cmd, NULL); /* lose the command at the start */ if (!*cmd) { SendThing("^5Pattern Action\n", thing); SendThing("^4======= ======\n", thing); for (i=0; i<sock->sAliasIndex.iNum; i++) { sprintf(buf, "^3%-10s ^4= ^b%s\n", Alias(sock->sAliasIndex.iThing[i])->aPattern->sText, Alias(sock->sAliasIndex.iThing[i])->aAction->sText); SendThing(buf, thing); } SendThing("\n", thing); sprintf(buf, "^5%ld Aliases listed.\n", sock->sAliasIndex.iNum); SendThing(buf, thing); return; } cmd = StrOneWord(cmd, word); alias = AliasFind(&sock->sAliasIndex, word); if (*cmd) { if (alias) { sprintf(buf, "^5Overwriting ^3old Alias %s\n", alias->aPattern->sText); ALIASFREE(&sock->sAliasIndex, alias); SendThing(buf, thing); } alias = AliasCreate(&sock->sAliasIndex, word, cmd); if (!alias) { SendThing("^wI'm sorry you allready have too many aliases to create another\n", thing); return; } sprintf(buf, "^3Creating %s = %s\n", alias->aPattern->sText, cmd); } else if (alias) { sprintf(buf, "^3Deleting Alias %s\n", alias->aPattern->sText); ALIASFREE(&sock->sAliasIndex, alias); } SendThing(buf, thing); AliasWrite(sock); } CMDPROC(CmdUnAlias) { /* Cmd(THING *thing, BYTE *cmd) */ ALIAS *alias; SOCK *sock; BYTE buf[256]; sock = BaseControlFind(thing); if (!sock) return; cmd = StrOneWord(cmd, NULL); /* lose the command at the start */ if (!*cmd) { CmdAlias(thing, ""); /* get list */ return; } cmd = StrOneWord(cmd, buf); alias = AliasFind(&sock->sAliasIndex, buf); if (alias) { sprintf(buf, "^3Deleting Alias %s\n", alias->aPattern->sText); ALIASFREE(&sock->sAliasIndex, alias); AliasWrite(sock); } else sprintf(buf, "^gNo such Alias\n"); SendThing(buf, thing); } CMDPROC(CmdTime) { /* Cmd(THING *thing, BYTE *cmd) */ BYTE buf[256]; LWORD timeSinceReset; LWORD timeUntilReset; LWORD area; SendThing("^CUptime: ^g ", thing); TimeSprintf(buf, time(0)-startTime); SendThing(buf, thing); if (Base(thing)->bInside && Base(thing)->bInside->tType==TTYPE_WLD) { area = Wld(Base(thing)->bInside)->wArea; SendThing("\n^CArea Reset: ^g", thing); if (areaList[area].aResetDelay <= 0) { SendThing("^rNever!\n", thing); } else { timeSinceReset = time(0) - areaList[area].aResetLast - startTime; timeUntilReset = areaList[area].aResetDelay*60 - timeSinceReset; if (timeUntilReset <= 0) { SendThing("^wAny Time!\n", thing); } else { TimeSprintf(buf, timeUntilReset); SendThing(buf, thing); SendThing("\n", thing); } } } } CMDPROC(CmdEnterMsg) { /* Cmd(THING *thing, BYTE *cmd) */ BYTE buf[512]; BYTE *i; if (thing->tType!=TTYPE_PLR) return; cmd = StrOneWord(cmd, NULL); /* lose the command at the start */ if (!*cmd) { SendThing("^GYour Entrance message is currently:\n^g", thing); SendAction(Plr(thing)->pEnter->sText, thing, NULL, SEND_SRC); return; } i = StrFind(cmd, "$$n"); while (i && i[2]=='N') i=StrFind(cmd, "$$n"); if (i) { /* convert $$n into $n */ while( *(i+1) ) { *i = *(i+1); i++; } *i = '\0'; /* copy null too */ sprintf(buf, "%s\n", cmd); } else { sprintf(buf, "$n %s\n", cmd); } SendThing("^GOkay Doke, your entrance message is now:\n^g", thing); STRFREE(Plr(thing)->pEnter); Plr(thing)->pEnter = STRCREATE(buf); /* name & title */ SendAction(Plr(thing)->pEnter->sText, thing, NULL, SEND_SRC); } CMDPROC(CmdExitMsg) { /* Cmd(THING *thing, BYTE *cmd) */ BYTE buf[512]; BYTE *i; if (thing->tType!=TTYPE_PLR) return; cmd = StrOneWord(cmd, NULL); /* lose the command at the start */ if (!*cmd) { SendThing("^GYour exit message is currently:\n^g", thing); SendAction(Plr(thing)->pExit->sText, thing, NULL, SEND_SRC); return; } i = StrFind(cmd, "$$n"); while (i && i[2]=='N') i=StrFind(cmd, "$$n"); if (i) { /* convert $$n into $n */ while( *(i+1) ) { *i = *(i+1); i++; } *i = '\0'; /* copy null too */ sprintf(buf, "%s\n", cmd); } else { sprintf(buf, "$n %s\n", cmd); } SendThing("^GOkay Doke, your exit message is now:\n^g", thing); STRFREE(Plr(thing)->pExit); Plr(thing)->pExit = STRCREATE(buf); /* name & title */ SendAction(Plr(thing)->pExit->sText, thing, NULL, SEND_SRC); } CMDPROC(CmdPrompt) { /* Cmd(THING *thing, BYTE *cmd) */ if (thing->tType!=TTYPE_PLR) return; cmd = StrOneWord(cmd, NULL); /* lose the command at the start */ if (!*cmd) { SendThing("^GRestoring default settable prompt:\n^g", thing); STRFREE(Plr(thing)->pPrompt); Plr(thing)->pPrompt = STRCREATE(""); SendThing("\n^GCustom prompt variables are ie (%<letter>):\n^g", thing); SendThing("h hitpoints m move\n", thing); SendThing("p power H max hits\n", thing); SendThing("M max move P max power\n", thing); SendThing("t thirst n hunger\n", thing); SendThing("u aura c credits\n", thing); SendThing("i intox R room#\n", thing); SendThing("e exits a areaname\n", thing); SendThing("N name f fighting\n", thing); SendThing("l leadername w weaponname\n", thing); SendThing("b hitbonus B dambonus\n", thing); SendThing("r Armor E total experience\n", thing); SendThing("L XP to Next level\n", thing); SendHint("\n^;HINT: A typical prompt would be: ^<^^gH%h/%H M%m/%M P%p/%P ^^G-+^^C>\n", thing); return; } SendThing("^GOkay Doke, your prompt message is now:\n^g", thing); STRFREE(Plr(thing)->pPrompt); Plr(thing)->pPrompt = STRCREATE(cmd); SendAction(Plr(thing)->pPrompt->sText, thing, NULL, SEND_SRC); SendThing("\n", thing); } CMDPROC(CmdFinger) { BYTE readPlayer = FALSE; THING *player; BYTE buf[256]; cmd = StrOneWord(cmd, NULL); /* lose the command at the start */ player = PlayerFind(cmd); if (!player) { player = PlayerRead(cmd, PREAD_SCAN); readPlayer = TRUE; } if (!player) { SendThing("^wFinger who exactly?!?\n", thing); return; } SendAction("You finger $N\n", thing, player, SEND_SRC); if (readPlayer || Character(thing)->cLevel >= LEVEL_GOD) { sprintf(buf, "^gLevel:^G[^c%4hd^G] ", Character(player)->cLevel); SendThing(buf, thing); } else { sprintf(buf, "^G[^c%s^G] ", PlayerGetLevelDesc(player)); SendThing(buf, thing); } SendThing("^gClass:^G[", thing); SendThing(TYPESPRINTF(buf, Plr(player)->pClass, classList, sizeof(buf)), thing); SendThing("^G] ^gRace:^G[", thing); SendThing(TYPESPRINTF(buf, Plr(player)->pRace, raceList, sizeof(buf)), thing); SendThing("^G]\n", thing); if (readPlayer) { SendThing("^wOffline ^g", thing); TimeSprintf(buf, time(0)-Plr(player)->pTimeLastOn); SendThing(buf, thing); SendThing("\n", thing); } else { sprintf(buf, "^wIdle %ld Ticks\n", Plr(player)->pIdleTick); SendThing(buf, thing); } SendThing("^wTotal Playtime ^g", thing); TimeSprintf(buf, Plr(player)->pTimeTotal); SendThing(buf, thing); SendThing("\n", thing); if (Character(thing)->cLevel >= LEVEL_ADMIN) { SendThing("^wLast Login: ^g", thing); SendThing(Plr(player)->pLastLogin->sText, thing); SendThing("\n", thing); } /* send their email if they have one */ SendThing("^CEmail:\n^g", thing); if (BIT(Plr(player)->pAuto, PA_NOEMAIL) && Character(thing)->cLevel<LEVEL_ADMIN) SendThing("^r<Private>", thing); else if (*Plr(player)->pEmail->sText) SendThing(Plr(player)->pEmail->sText, thing); else SendThing("^r<None>", thing); /* send their plan if they have one */ SendThing("\n^CPlan:\n^g", thing); if (*Plr(player)->pPlan->sText) SendThing(Plr(player)->pPlan->sText, thing); else SendThing("^r<None>", thing); SendThing("\n", thing); if (readPlayer) THINGFREE(player); } /* Theoretically quite a simple little command, but then I wanted 3 nicely formatted columns so simplicity and readability went to hell... ah well */ CMDPROC(CmdLevels) { /* Cmd(THING *thing, BYTE *cmd) */ LWORD i; LWORD level; LWORD realLevel; BYTE buf[256]; if (thing->tType != TTYPE_PLR) { SendThing("^wI'm afraid you cant go up in level...\n", thing); return; } SendThing("^CLevels and the experience points required for them...\n\n", thing); realLevel = Character(thing)->cLevel; level = Character(thing)->cLevel-1; for (i=0; i<10; i++) { Character(thing)->cLevel=level; if (level < LEVEL_GOD) { sprintf(buf, "^w%4ld ^y%13ld ", level+1, PlayerExpNeeded(thing)); SendThing(buf, thing); } else { sprintf(buf, "^w%4ld ^g<GOD>\n", level+1); SendThing(buf, thing); break; } level+=10; Character(thing)->cLevel=level; if (level < LEVEL_GOD) { sprintf(buf, "^w%4ld ^y%13ld ", level+1, PlayerExpNeeded(thing)); SendThing(buf, thing); } level+=10; Character(thing)->cLevel=level; if (level < LEVEL_GOD) { sprintf(buf, "^w%4ld ^y%13ld\n", level+1, PlayerExpNeeded(thing)); SendThing(buf, thing); } else SendThing("\n", thing); level-=19; } Character(thing)->cLevel = realLevel; } CMDPROC(CmdSkillMax) { BYTE buf[256]; LWORD level; if (thing->tType!=TTYPE_PLR) return; cmd = StrOneWord(cmd, NULL); cmd = StrOneWord(cmd, buf); if (!*buf) { SendThing("^gSkillMax shows you the maximum skills you can have for a given level\n", thing); SendThing("^gUsage: SkillMax <level>\n", thing); return; } level = Character(thing)->cLevel; Character(thing)->cLevel = atol(buf); sprintf(buf, "pr %s", cmd); SkillShow(thing, buf, 0, 0xFFFFFFFF, 200); /* Thing, Cmd, CanPractice, CantPractice, maxLevel */ Character(thing)->cLevel = level; } CMDPROC(CmdAffects) { /* Cmd(THING *thing, BYTE *cmd) */ AFFECT *affect; BYTE buf[512]; SendThing("^pYou are currently affected by:\n", thing); SendThing("^P-+- +-+ -+-+-+-+- +-+-+-+- +-\n", thing); for (affect = Character(thing)->cAffect; affect; affect=affect->aNext) { sprintf(buf, "^3%-20s %hd\n", effectList[affect->aEffect].eName, affect->aDuration); SendThing(buf, thing); } SendThing("\n", thing); SendThing("^3AffectFlags:^4[^5", thing); SendThing(FlagSprintf(buf, Character(thing)->cAffectFlag, affectList, ' ', 512), thing); SendThing("^4]\n", thing); } /* * Stop affects, things like Spiritwalk, Invis etc that you might * want to wear off prematurely */ CMDPROC(CmdStop) { /* match the name of the effect here */ BYTE *stopList[] = { "Spiritwalk", "Invisibility", "ImprovedInvis", "\0" }; LWORD i; BYTE buf[256]; AFFECT *affect; cmd = StrOneWord(cmd, NULL); cmd = StrOneWord(cmd, buf); if (!*buf) { SendThing("^5Stoppable Affects are:\n^3", thing); SENDARRAY(stopList, 3, thing); return; } i = TYPEFIND(buf, stopList); if (i==-1) { SendThing("^wI'm afraid that is not a stoppable affect\n", thing); return; } /* Find the affect and set its duration to 0 - get rid of it */ i = TYPEFIND(buf, effectList); if (i==-1) { SendThing("^wThe sysadmin has corrupted the stopList, what a loser!\n", thing); return; } affect = AffectFind(thing, i); if (!affect) { SendThing("^wBut you're not being affected by that right now!\n", thing); SendHint("^;HINT: Type ^<AFFECT^; for a list of things you are being affected by\n", thing); return; } AffectRemove(thing, affect); } void MiscGetColorName(BYTE *name, BYTE fg, BYTE bg) { LWORD i; LWORD j; bg = toupper(bg); for (i=0; *ansiFGColorList[i].cName && ansiFGColorList[i].cSymbol!=fg; i++); for (j=0; *ansiBGColorList[j].cName && ansiBGColorList[j].cSymbol!=bg; j++); sprintf(name, "%s-On-%s", ansiFGColorList[i].cName, ansiBGColorList[j].cName); } BYTE MiscGetColorSymbol(BYTE *name, BYTE *fg, BYTE *bg) { LWORD i; LWORD j; BYTE buf[256]; if (strlen(name)==4 && name[0]=='^' && name[1]=='&') { /* should validate against colorlist */ for (i=0; *ansiFGColorList[i].cName && ansiFGColorList[i].cSymbol!=name[2]; i++); for (j=0; *ansiBGColorList[j].cName && ansiBGColorList[j].cSymbol!=name[3]; j++); if (!*ansiFGColorList[i].cName) return FALSE; if (!*ansiFGColorList[j].cName) return FALSE; *fg = name[2]; *bg = name[3]; return TRUE; } if (strlen(name)==2 && name[0]=='^') { /* should validate against colorlist */ for (i=0; *ansiFGColorList[i].cName && ansiFGColorList[i].cSymbol!=name[1]; i++); if (!*ansiFGColorList[i].cName) return FALSE; *fg = name[1]; *bg = 'A'; return TRUE; } for (j=0; *ansiBGColorList[j].cName; j++) { for (i=0; *ansiFGColorList[i].cName; i++) { MiscGetColorName(buf, ansiFGColorList[i].cSymbol, ansiBGColorList[j].cSymbol); if (StrAbbrev(buf, name)) { *fg = ansiFGColorList[i].cSymbol; *bg = ansiBGColorList[j].cSymbol; return TRUE; } } } return FALSE; } /* Set the color prefs */ CMDPROC(CmdSetColor) { LWORD i; LWORD j; BYTE buf[256]; BYTE word[256]; LWORD numSent; if (thing->tType != TTYPE_PLR) return; cmd = StrOneWord(cmd, NULL); if (!*cmd) { SendThing("^5Color Preferences:\n", thing); /* show the list of current color prefs */ i=0; j=0; while (*colorPrefList[i].cName || *colorPrefList[j].cName) { while (*colorPrefList[i].cName && colorPrefList[i].cColumn != 0) i++; while (*colorPrefList[j].cName && colorPrefList[j].cColumn != 1) j++; if (*colorPrefList[i].cName) { MiscGetColorName(word, Plr(thing)->pColorPref[i].cFG, Plr(thing)->pColorPref[i].cBG); sprintf(buf, "^3%-18s^%c%-18s^V ", colorPrefList[i].cName, colorPrefList[i].cSymbol, word); i++; } else { sprintf(buf, "%-40c", ' '); } SendThing(buf, thing); if (*colorPrefList[j].cName) { MiscGetColorName(word, Plr(thing)->pColorPref[j].cFG, Plr(thing)->pColorPref[j].cBG); sprintf(buf, "^3%-18s^%c%-18s^V\n", colorPrefList[j].cName, colorPrefList[j].cSymbol, word); j++; } else strcpy(buf, "\n"); SendThing(buf, thing); } return; } cmd = StrOneWord(cmd, word); i = TYPEFIND(word, colorPrefList); if (i == -1) { SendThing("^wThat isnt a valid preference name\n", thing); return; } if (!*cmd) { /* Show all the possible colors they could choose */ SendThing("^5Available Colors Are:\n", thing); numSent = 0; for (j=0; *ansiBGColorList[j].cName; j++) { for (i=0; *ansiFGColorList[i].cName; i++) { if (ansiBGColorList[j].cFG != ansiFGColorList[i].cFG) { MiscGetColorName(word, ansiFGColorList[i].cSymbol, ansiBGColorList[j].cSymbol); sprintf(buf, "^&%c%c%-20s", ansiFGColorList[i].cSymbol, ansiBGColorList[j].cSymbol, word); /* strcpy(buf, word); */ numSent++; if (numSent%4==0) strcat(buf, "\n"); SendThing(buf, thing); } } } return; } /* okay pick a setting and change its color */ if (!MiscGetColorSymbol(cmd, &Plr(thing)->pColorPref[i].cFG, &Plr(thing)->pColorPref[i].cBG)) { SendThing("^wThat is not a valid color name\n", thing); return; } else { MiscGetColorName(word, Plr(thing)->pColorPref[i].cFG, Plr(thing)->pColorPref[i].cBG); sprintf(buf, "^3Okey doke, from on it's %s ^%c%-20s\n", colorPrefList[i].cName, colorPrefList[i].cSymbol, word); SendThing(buf, thing); return; } } CMDPROC(CmdQuit) { /* Cmd(THING *thing, BYTE *cmd) */ SOCK *sock; if (strcmp(cmd, "quit") == 0) { sock = BaseControlFind(thing); if (sock) { if (sock->sControlThing != sock->sHomeThing) CmdSwitch(thing, ""); else sock->sMode = MODE_MAINMENU; SendThing(fileList[FILE_QUIT].fileStr->sText, thing); if (thing->tType == TTYPE_MOB && Mob(thing)->mTemplate == spiritTemplate) THINGFREE(thing); } } else { SendThing("^GType ^gQUIT ^Gno less, no more to quit\n", thing); } }