/* * dm.cpp * Standard staff functions * ____ _ * | _ \ ___ __ _| |_ __ ___ ___ * | |_) / _ \/ _` | | '_ ` _ \/ __| * | _ < __/ (_| | | | | | | \__ \ * |_| \_\___|\__,_|_|_| |_| |_|___/ * * Copyright (C) 2007-2009 Jason Mitchell, Randi Mitchell * Contributions by Tim Callahan, Jonathan Hseu * Based on Mordor (C) Brooke Paul, Brett J. Vickers, John P. Freeman * */ // C++ includes #include <sstream> // Mud Includes #include "mud.h" #include "commands.h" #include "dm.h" //#include "socket.h" #include "effects.h" #include "quests.h" #include "magic.h" #include <sstream> #include <iomanip> #include <locale> extern int controlSock; long last_dust_output; extern long last_weather_update; //********************************************************************* // dmReboot //********************************************************************* int dmReboot(Player* player, cmd* cmnd) { bool resetShips=false; if( !player->isDm() && !(player->flagIsSet(P_CAN_REBOOT) && player->getClass() == CARETAKER) ) return(cmdNoAuth(player)); if(cmnd->num==2 && !strcmp(cmnd->str[1], "-ships")) resetShips = true; player->print("Rebooting now!\n"); logn("log.bane", "Reboot by %s.\n", player->name); broadcast("### Going for a reboot, hang onto your seats!"); if(resetShips) player->print("Resetting game time to midnight, updating ships...\n"); gServer->processOutput(); loge("--- Attempting game reboot ---\n"); gConfig->resaveAllRooms(0); gServer->startReboot(resetShips); merror("dmReboot failed!!!", FATAL); return(0); } //********************************************************************* // dmMobInventory //********************************************************************* int dmMobInventory(Player* player, cmd* cmnd) { Monster *monster=0; Object *object; otag *op=0; char str[2048]; int count=0, i=0; if(!player->canBuildMonsters()) return(cmdNoAuth(player)); if(cmnd->num < 2) { player->print("Which monster?\n"); return(0); } monster = player->getRoom()->findMonster(player, cmnd); if(!monster) { player->print("That's not here.\n"); return(0); } if(!strcmp(cmnd->str[2], "-l") || player->getClass() == BUILDER) { player->print("Items %s will possibly drop:\n", monster->name); for(i=0;i<10;i++) { if(!monster->carry[i].info.id) { player->print("Carry slot %d: %sNothing.\n", i+1, i < 9 ? " " : ""); continue; } if(!loadObject(monster->carry[i].info, &object)) continue; if(!object) continue; if(player->getClass() == BUILDER && player->checkRangeRestrict(object->info)) player->print("Carry slot %d: %sout of range(%s).\n", i+1, i < 9 ? " " : "", object->info.str().c_str()); else player->printColor("Carry slot %d: %s%s(%s).\n", i+1, i < 9 ? " " : "", object->name, object->info.str().c_str()); delete object; } return(0); } sprintf(str, "%s%s is carrying: ", (monster->flagIsSet(M_NO_PREFIX) ? "":"The "), monster->name); op = monster->first_obj; while(op) { count++; strcat(str, op->obj->name); strcat(str, "^x"); if(op->obj->flagIsSet(O_NOT_PEEKABLE)) strcat(str, "(NoPeek)"); if(op->obj->flagIsSet(O_NO_STEAL)) strcat(str, "(NoSteal)"); if(op->obj->flagIsSet(O_BODYPART)) strcat(str, "(BodyPart)"); strcat(str, ", "); op = op->next_tag; } if(!count) strcat(str, "Nothing."); else { str[strlen(str) - 2] = '.'; str[strlen(str) - 1] = 0; } player->printColor("%s\n", str); return(0); } //********************************************************************* // dmSockets //********************************************************************* int dmSockets(Player* player, cmd* cmnd) { int num=0; player->print("Connected Sockets:\n"); foreach(Socket* sock, gServer->sockets) { num += 1; player->print("Fd: %-2d %s\n", sock->getFd(), sock->getHostname().c_str()); } player->print("%d total connection%s.\n", num, num != 1 ? "s" : ""); return(PROMPT); } //********************************************************************* // dmLoadSave //********************************************************************* // handles loading and saving of a bunch of config files int dmLoadSave(Player* player, cmd* cmnd, bool load) { if(cmnd->num < 2) { player->print("*dmload / *dmsave supports the following options:\n"); player->printColor("^yLOAD:\n"); player->print(" areas bans\n"); player->print(" calendar catrefinfo\n"); player->print(" config classes\n"); player->print(" clans deities\n"); player->print(" faction fishing\n"); player->print(" flags guilds\n"); player->print(" limited properties\n"); player->print(" quests races\n"); player->print(" recipes ships\n"); player->print(" skills spells\n"); player->printColor(" spl ^c[spell id]\n"); player->print(" startlocs\n"); player->printColor("^ySAVE:\n"); player->print(" bans config\n"); player->print(" guilds limited\n"); player->print(" properties recipes\n"); player->print(" spells\n"); player->print("\n"); return(0); } if(!strcmp(cmnd->str[1], "bans")) { if(load) { gConfig->loadBans(); player->print("Bans reloaded.\n"); dmListbans(player, NULL); } else { gConfig->saveBans(); player->print("Bans saved.\n"); } } else if(!strcmp(cmnd->str[1], "config")) { if(load) { player->print("Reloading configuration file.\n"); gConfig->loadConfig(); } else { player->print("Saving configuration file.\n"); gConfig->saveConfig(); } } else if(!strcmp(cmnd->str[1], "guilds")) { if(load) { player->print("Reloading guilds.\n"); gConfig->loadGuilds(); } else { player->print("Saving guilds.\n"); gConfig->saveGuilds(); } } else if(!strcmp(cmnd->str[1], "recipes")) { if(load) { gConfig->loadRecipes(); player->print("Recipes reloaded.\n"); } else { gConfig->saveRecipes(); player->print("Recipes saved.\n"); } } else if(!strcmp(cmnd->str[1], "properties")) { if(load) { gConfig->loadProperties(); player->print("Properties reloaded.\n"); } else { gConfig->saveProperties(); player->print("Properties saved.\n"); } } else if(!strcmp(cmnd->str[1], "limited")) { if(load) { gConfig->loadLimited(); player->print("Limited items reloaded.\n"); } else { gConfig->saveLimited(); player->print("Limited items saved.\n"); } } else if(!strcmp(cmnd->str[1], "spells")) { if(load) { gConfig->loadSpellList(); player->print("Spell list reloaded.\n"); } else { gConfig->saveSpellList(); player->print("Spell list saved.\n"); } } else if(!strcmp(cmnd->str[1], "areas") && load) { if(!strcmp(cmnd->str[2], "confirm")) { std::list<Area*>::iterator at; std::map<bstring, AreaRoom*>::iterator it; AreaRoom* aRoom = 0; for(at = gConfig->areas.begin() ; at != gConfig->areas.end() ; at++) { for(it = (*at)->rooms.begin() ; it != (*at)->rooms.end() ; it++) { aRoom = (*it).second; aRoom->setStayInMemory(true); aRoom->expelPlayers(); } } gConfig->loadAreas(); player->print("Area reloaded.\n"); } else { player->print("This will expel all current players in the overland to their recall rooms.\n"); player->printColor("Type ^y*dmload areas confirm^x to continue.\n"); } } else if(!strcmp(cmnd->str[1], "quests") && load) { gConfig->loadQuestTable(); gConfig->loadQuests(); gConfig->resetParentQuests(); player->print("Quests reloaded.\n"); } else if(!strcmp(cmnd->str[1], "clans") && load) { gConfig->loadClans(); player->print("Clans reloaded.\n"); } else if(!strcmp(cmnd->str[1], "classes") && load) { gConfig->loadClasses(); player->print("Classes reloaded.\n"); } else if(!strcmp(cmnd->str[1], "races") && load) { gConfig->loadRaces(); player->print("Races reloaded.\n"); } else if(!strcmp(cmnd->str[1], "deities") && load) { gConfig->loadDeities(); player->print("Deities reloaded.\n"); } else if(!strcmp(cmnd->str[1], "skills") && load) { gConfig->loadSkills(); player->print("Skills reloaded.\n"); } else if(!strcmp(cmnd->str[1], "startlocs") && load) { gConfig->loadStartLoc(); player->print("StartLocs reloaded.\n"); } else if(!strcmp(cmnd->str[1], "catrefinfo") && load) { gConfig->loadCatRefInfo(); player->print("CatRefInfo reloaded.\n"); } else if(!strcmp(cmnd->str[1], "flags") && load) { gConfig->loadFlags(); player->print("Flags reloaded.\n"); } else if(!strcmp(cmnd->str[1], "faction") && load) { gConfig->loadFactions(); player->print("Factions reloaded.\n"); } else if(!strcmp(cmnd->str[1], "fishing") && load) { gConfig->loadFishing(); player->print("Fishing reloaded.\n"); } else if(!strcmp(cmnd->str[1], "spl") && load) { SpellInfo* spell=0; if(cmnd->str[2][0]) { std::map<bstring, SpellInfo>::iterator it = gConfig->spells.find(cmnd->str[2]); if(it != gConfig->spells.end()) spell = &(*it).second; } if(!spell) { player->print("Spell id \"%s\" not found.\n", cmnd->str[2]); } else { bool success = spell->loadScript(); player->print("Reloading spell \"%s\" %s.\n", spell->id.c_str(), success ? "was successful" : "failed"); } } else if(!strcmp(cmnd->str[1], "calendar") && load) { reloadCalendar(player); } else { player->print("Invalid request!\n"); cmnd->num = 1; dmLoadSave(player, cmnd, load); } return(0); } //********************************************************************* // dmLoad //********************************************************************* // a wrapper int dmLoad(Player* player, cmd* cmnd) { if(!strcmp(cmnd->str[0], "*banload")) { cmnd->num = 2; strcpy(cmnd->str[1], "ban"); } else if(!strcmp(cmnd->str[0], "*guildload")) { cmnd->num = 2; strcpy(cmnd->str[1], "guild"); } else if(!strcmp(cmnd->str[0], "*questload")) { cmnd->num = 2; strcpy(cmnd->str[1], "quest"); } else if(!strcmp(cmnd->str[0], "*clanload")) { cmnd->num = 2; strcpy(cmnd->str[1], "clan"); } else if(!strcmp(cmnd->str[0], "*exitload")) { cmnd->num = 2; strcpy(cmnd->str[1], "exit"); } else if(!strcmp(cmnd->str[0], "*recload")) { cmnd->num = 2; strcpy(cmnd->str[1], "recipes"); } dmLoadSave(player, cmnd, true); return(0); } //********************************************************************* // dmSave //********************************************************************* // a wrapper int dmSave(Player* player, cmd* cmnd) { if(!strcmp(cmnd->str[0], "*bansave")) { cmnd->num = 2; strcpy(cmnd->str[1], "ban"); } else if(!strcmp(cmnd->str[0], "*guildsave")) { cmnd->num = 2; strcpy(cmnd->str[1], "guild"); } else if(!strcmp(cmnd->str[0], "*questsave")) { cmnd->num = 2; strcpy(cmnd->str[1], "quest"); } else if(!strcmp(cmnd->str[0], "*clansave")) { cmnd->num = 2; strcpy(cmnd->str[1], "clan"); } else if(!strcmp(cmnd->str[0], "*recsave")) { cmnd->num = 2; strcpy(cmnd->str[1], "recipes"); } dmLoadSave(player, cmnd, false); return(0); } //********************************************************************* // dmTeleport //********************************************************************* // This function allows staff to teleport to a given room number, or to // a player's location. It will also teleport a player to the DM or // one player to another. void Player::dmPoof(BaseRoom* room, BaseRoom *newRoom) { if(flagIsSet(P_ALIASING)) { alias_crt->deleteFromRoom(); broadcast(getSock(), room, "%M just wandered away.", alias_crt); if(newRoom) alias_crt->addToRoom(newRoom); } if(flagIsSet(P_DM_INVIS)) { if(isDm()) broadcast(::isDm, getSock(), room, "*DM* %s disappears in a puff of smoke.", name); if(cClass == CARETAKER) broadcast(::isCt, getSock(), room, "*DM* %s disappears in a puff of smoke.", name); if(!isCt()) broadcast(::isStaff, getSock(), room, "*DM* %s disappears in a puff of smoke.", name); } else { broadcast(getSock(), room, "%M disappears in a puff of smoke.", this); } } int dmTeleport(Player* player, cmd* cmnd) { BaseRoom *room=0, *old_room=0; Room *uRoom=0; Creature *creature=0; Player *target=0, *target2=0; Location l; // *t 1 and *t 1.-10.7 will trigger num < 2, // *t misc.100 will not, so we need to make an exception bstring str = getFullstrText(cmnd->fullstr, 1); bstring txt = getFullstrText(str, 1, '.'); // set default *t room if(str == "") { if(player->getClass() == BUILDER && player->room.isArea(gConfig->defaultArea)) l.room.id = ROOM_BUILDER_PERM_LOW; else l = player->getRecallRoom(); if(player->area_room && l.mapmarker == player->area_room->mapmarker) { player->print("You are already there!\n"); return(0); } room = l.loadRoom(); } else if(cmnd->num < 2 || (txt != "" && txt.getAt(0))) { Area *area=0; getDestination(str, &l, player); if(player->getClass() != BUILDER && l.mapmarker.getArea()) { if(player->area_room && l.mapmarker == player->area_room->mapmarker) { player->print("You are already there!\n"); return(0); } area = gConfig->getArea(l.mapmarker.getArea()); if(!area) { player->print("Area does not exist.\n"); return(0); } // pointer to old room player->dmPoof(player->getRoom(), 0); area->move(player, &l.mapmarker); // manual if(player->flagIsSet(P_ALIASING)) player->getAlias()->addToRoom(player->getRoom()); return(0); } if(!validRoomId(l.room)) { player->print("Error: out of range.\n"); return(0); } if(!loadRoom(l.room, &uRoom)) { player->print("Error (%s)\n", l.str().c_str()); return(0); } if(!player->checkBuilder(l.room)) return(0); room = uRoom; } else if(cmnd->num < 3) { lowercize(cmnd->str[1], 1); creature = gServer->findPlayer(cmnd->str[1]); if(!creature || creature == player || !player->canSee(creature)) { player->print("%s is not on.\n", cmnd->str[1]); return(0); } if(player->getClass() == BUILDER && creature->getClass() != BUILDER) { player->print("You are only allowed to teleport to other builder.\n"); return(0); } old_room = player->getRoom(); room = creature->getRoom(); player->dmPoof(old_room, room); player->deleteFromRoom(); player->addToSameRoom(creature); player->doFollow(); return(0); } else { if(!player->isCt()) { player->print("You are not allowed to teleport others to you.\n"); return(0); } lowercize(cmnd->str[1], 1); target = gServer->findPlayer(cmnd->str[1]); if(!target || target == player || !player->canSee(target)) { player->print("%s is not on.\n", cmnd->str[1]); return(0); } lowercize(cmnd->str[2], 1); if(*cmnd->str[2] == '.') target2 = player; else target2 = gServer->findPlayer(cmnd->str[2]); if(!target2) { player->print("%s is not on.\n", cmnd->str[1]); return(0); } if(target == target2) { player->print("You cant do that.\n"); return(0); } old_room = target->getRoom(); room = target2->getRoom(); target->dmPoof(old_room, room); target->deleteFromRoom(); target->addToSameRoom(target2); target->doPetFollow(); return(0); } old_room = player->getRoom(); player->dmPoof(old_room, room); player->deleteFromRoom(); player->addToRoom(room); player->doFollow(); return(0); } //********************************************************************* // dmUsers //********************************************************************* // This function allows staff to list all users online, displaying // level, name, current room # and name, and address. int dmUsers(Player* player, cmd* cmnd) { long t = time(0); bool full=false; bstring tmp="", host=""; Player* user=0; //Socket* sock=0; std::ostringstream oStr; char str[100]; oStr.setf(std::ios::left, std::ios::adjustfield); oStr.imbue(std::locale("")); bstring cr = gConfig->defaultArea; if(player->parent_rom) cr = player->parent_rom->info.area; if(cmnd->num > 1 && cmnd->str[1][0] == 'f') full = true; oStr << "^bLev Clas Player "; if(full) oStr << "Address Idle"; else oStr << "Room Address Last Command Idle"; oStr << "\n---------------------------------------------------------------------------------------\n"; //std::pair<bstring, Player*> p; foreach(Socket* sock, gServer->sockets) { //user = p.second; //sock = user->getSock(); user = sock->getPlayer(); if(!user || !player->canSee(user)) continue; host = sock->getHostname(); if(user->isDm() && !player->isDm()) host = "mud.rohonline.net"; oStr.setf(std::ios::right, std::ios::adjustfield); oStr << "^x[" << std::setw(2) << user->getLevel() << "] "; oStr.setf(std::ios::left, std::ios::adjustfield); if(user->isStaff()) oStr << "^g"; oStr << std::setw(4) << bstring(getShortClassName(user)).left(4) << "^w "; if(!user->flagIsSet(P_SECURITY_CHECK_OK)) oStr << "^r"; else oStr << "^y"; if(user->flagIsSet(P_DM_INVIS)) oStr << "+"; else if(user->flagIsSet(P_INCOGNITO)) oStr << "g"; else if(user->isInvisible()) oStr << "*"; else oStr << " "; if(user->flagIsSet(P_OUTLAW)) oStr << "^R"; else if(user->flagIsSet(P_LINKDEAD)) oStr << "^G"; else if(user->flagIsSet(P_WATCHER)) oStr << "^w"; else if(user->flagIsSet(P_GLOBAL_GAG)) oStr << "^m"; oStr << std::setw(10) << bstring(user->name).left(10) << "^w "; if(!sock->isConnected()) { sprintf(str, "connecting (Fd: %d)", sock->getFd()); oStr << "^Y" << std::setw(20) << str << " ^c" << std::setw(37) << host.left(37); } else if(full) { oStr << "^m" << std::setw(58) << host.left(58); } else { if(user->parent_rom) { sprintf(str, "%s: ^b%s", user->parent_rom->info.str(cr, 'b').c_str(), bstring(user->parent_rom->name).c_str()); oStr << std::setw(22 + (str[0] == '^' ? 4 : 0)) << bstring(str).left(22 + (str[0] == '^' ? 4 : 0)); } else { //sprintf(str, "%s", user->area_room->mapmarker.str(true).c_str()); //oStr << std::setw(26) << bstring(str).left(26); oStr << std::setw(38) << user->area_room->mapmarker.str(true).left(38); } oStr << " ^c" << std::setw(19) << host.left(19) << " ^g"; if(!user->isDm() || player->isDm()) oStr << std::setw(17) << dmLastCommand(user).left(17); else oStr << std::setw(17) << "l"; } sprintf(str, "%02ld:%02ld", (t-sock->ltime)/60L, (t-sock->ltime)%60L); oStr << " ^w" << str << "\n"; } player->printColor("%s", oStr.str().c_str()); player->hasNewMudmail(); player->print("\n"); return(0); } //********************************************************************* // dmFlushSave //********************************************************************* // This function allows staff to save all the rooms in memory back to // disk in one fell swoop. int dmFlushSave(Player* player, cmd* cmnd) { if(cmnd->num < 2) { player->print("All rooms and contents flushed to disk.\n"); gConfig->resaveAllRooms(0); } else { player->print("All rooms and PERM contents flushed to disk.\n"); gConfig->resaveAllRooms(PERMONLY); } return(0); } //********************************************************************* // dmShutdown //********************************************************************* // This function allows staff to shut down the game in a given number of // minutes. int dmShutdown(Player* player, cmd* cmnd) { player->print("Ok.\n"); log_immort(true, player, "*** Shutdown by %s.\n", player->name); Shutdown.ltime = time(0); Shutdown.interval = cmnd->val[0] * 60 + 1; return(0); } //********************************************************************* // dmFlushCrtObj //********************************************************************* // This function allows staff to flush the object and creature data so // that updated data can be loaded into memory instead. int dmFlushCrtObj(Player* player, cmd* cmnd) { if(!player->canBuildObjects() && !player->canBuildMonsters()) return(cmdNoAuth(player)); if(player->canBuildObjects()) gConfig->flushObject(); if(player->canBuildMonsters()) gConfig->flushMonster(); player->print("Basic object and monster data flushed from memory.\n"); return(0); } //********************************************************************* // dmResave //********************************************************************* // This function allows staff to save a room back to disk. int dmResave(Player* player, cmd* cmnd) { int s=0; if(!player->builderCanEditRoom("use *save")) return(0); if( cmnd->num > 1 && (!strcmp(cmnd->str[1], "c") || !strcmp(cmnd->str[1], "o")) ) { bstring str = getFullstrText(cmnd->fullstr, 3); if(str == "") { player->print("Syntax: *save %c [name] [number]\n", cmnd->str[1]); return(0); } CatRef cr; getCatRef(str, &cr, player); if(!strcmp(cmnd->str[1], "c")) dmSaveMob(player, cmnd, cr); else if(!strcmp(cmnd->str[1], "o")) dmSaveObj(player, cmnd, cr); return(0); } if(!player->checkBuilder(player->parent_rom)) { player->print("Error: this room is out of your range; you cannot save this room.\n"); return(0); } if(player->parent_rom) { s = gConfig->resaveRoom(player->parent_rom->info); if(s < 0) player->print("Resave failed. Tell this number to Bane: (%d)\n",s); else player->print("Room saved.\n"); } else if(player->area_room) { player->area_room->save(player); } else player->print("Nothing to save!\n"); return(0); } //********************************************************************* // dmPerm //********************************************************************* // This function allows staff to make a given object sitting on the // floor into a permanent object. int dmPerm(Player* player, cmd* cmnd) { std::map<int, crlasttime>::iterator it; Monster* target=0; Object *object=0; int x=0; if(!player->canBuildMonsters() && !player->canBuildObjects()) return(cmdNoAuth(player)); if(!player->checkBuilder(player->parent_rom)) { player->print("Room number not in any of your alotted ranges.\n"); return(0); } if(!player->builderCanEditRoom("use *perm")) return(0); if(!needUniqueRoom(player)) return(0); if(cmnd->num < 2) { player->print("Syntax: *perm [o|c|t] [name|d|exit] [timeout|slot]\n"); return(0); } switch(low(cmnd->str[1][0])) { case 'o': if(!player->canBuildObjects()) { player->print("Error: you cannot perm objects.\n"); return(PROMPT); } if(!strcmp(cmnd->str[2], "d") && strlen(cmnd->str[2])<2) { if(cmnd->val[2] > NUM_PERM_SLOTS || cmnd->val[2] < 1) { player->print("Slot to delete out of range.\n"); return(0); } it = player->parent_rom->permObjects.find(cmnd->val[2]-1); if(it != player->parent_rom->permObjects.end()) { player->parent_rom->permObjects.erase(it); player->print("Perm Object slot #%d cleared.\n", cmnd->val[2]); } else { player->print("Perm object slot #%d already empty.\n", cmnd->val[2]); } return(0); } object = findObject(player, player->parent_rom->first_obj, cmnd->str[2], 1); if(!object) { player->print("Object not found.\n"); return(0); } if(!object->info.id) { player->print("Object is not in database. Not permed.\n"); return(0); } if(cmnd->val[2] < 2) cmnd->val[2] = 7200; x = player->parent_rom->permObjects.size(); if(x > NUM_PERM_SLOTS) { player->print("Room is already full.\n"); return(0); } player->parent_rom->permObjects[x].cr = object->info; player->parent_rom->permObjects[x].interval = (long)cmnd->val[2]; log_immort(true, player, "%s permed %s^g in room %s.\n", player->name, object->name, player->parent_rom->info.str().c_str()); player->printColor("%s^x (%s) permed with timeout of %d.\n", object->name, object->info.str().c_str(), cmnd->val[2]); return(0); // perm Creature case 'c': if(!player->canBuildMonsters()) { player->print("Error: you cannot perm mobs.\n"); return(PROMPT); } if(!strcmp(cmnd->str[2], "d") && strlen(cmnd->str[2])<2) { if(cmnd->val[2] > NUM_PERM_SLOTS || cmnd->val[2] < 1) { player->print("Slot to delete out of range.\n"); return(0); } it = player->parent_rom->permMonsters.find(cmnd->val[2]-1); if(it != player->parent_rom->permMonsters.end()) { player->parent_rom->permMonsters.erase(it); player->print("Perm monster slot #%d cleared.\n", cmnd->val[2]); } else { player->print("Perm monster slot #%d already empty.\n", cmnd->val[2]); } return(0); } target = player->parent_rom->findMonster(player, cmnd->str[2], 1); if(!target) { player->print("Creature not found.\n"); return(0); } if(!target->info.id) { player->print("Monster is not in database. Not permed.\n"); return(0); } if(!player->checkBuilder(target->info)) { player->print("Monster number not in any of your alotted ranges.\n"); return(0); } if(cmnd->val[2] < 2) cmnd->val[2] = 7200; x = player->parent_rom->permMonsters.size(); if(x > NUM_PERM_SLOTS) { player->print("Room is already full.\n"); return(0); } player->parent_rom->permMonsters[x].cr = target->info; player->parent_rom->permMonsters[x].interval = (long)cmnd->val[2]; log_immort(true, player, "%s permed %s in room %s.\n", player->name, target->name, player->parent_rom->info.str().c_str()); player->print("%s (%s) permed with timeout of %d.\n", target->name, target->info.str().c_str(), cmnd->val[2]); return(0); // perm tracks case 't': if(!strcmp(cmnd->str[2], "d") || cmnd->num < 3) { player->parent_rom->clearFlag(R_PERMENANT_TRACKS); player->print("Perm tracks deleted.\n"); return(0); } player->parent_rom->track.setDirection(cmnd->str[2]); player->parent_rom->setFlag(R_PERMENANT_TRACKS); player->print("Perm tracks added leading %s.\n", player->parent_rom->track.getDirection().c_str()); return(0); default: player->print("Syntax: *perm [o|c|t] [name|d|exit] [timeout|slot]\n"); return(0); } } //********************************************************************* // dmInvis //********************************************************************* // This function allows staff to turn themself invisible. int dmInvis(Player* player, cmd* cmnd) { if(player->flagIsSet(P_DM_INVIS)) { if(!player->builderCanEditRoom("turn off invis")) return(0); player->clearFlag(P_DM_INVIS); player->printColor("^mInvisibility off.\n"); } else { player->setFlag(P_DM_INVIS); player->printColor("^yInvisibility on.\n"); } return(0); } //********************************************************************* // dmIncog //********************************************************************* int dmIncog(Player* player, cmd* cmnd) { if(player->flagIsSet(P_INCOGNITO)) { if(!player->isCt()) { player->print("You cannot unlock your presence.\n"); } else { player->clearFlag(P_INCOGNITO); player->printColor("^gYou unlock your presence.\n"); } } else { player->setFlag(P_INCOGNITO); player->printColor("^gYou cloak your pressence.\n"); } return(0); } //********************************************************************* // dmAc //********************************************************************* // This function allows staff to take a look at their own special stats. // or another user's stats. int dmAc(Player* player, cmd* cmnd) { Player *target=0; if(cmnd->num == 2) { lowercize(cmnd->str[1], 1); target = gServer->findPlayer(cmnd->str[1]); if(!target || !player->canSee(target)) { player->print("%s is not on.\n", cmnd->str[1]); return(0); } } else { player->hp.restore(); player->mp.restore(); target = player; } player->print("WeaponSkill: %d Defense Skill: %d Armor: %d(%.0f%%)\n", target->getWeaponSkill(player->ready[WIELD-1]), target->getDefenseSkill(), target->getArmor(), (target->getDamageReduction(target)*100.0)); return(0); } //********************************************************************* // dmWipe //********************************************************************* int dmWipe(Player* player, cmd* cmnd) { // Room* room=0; // ctag *cp; //otag *op; // int a=0, fd = player->fd, low=0, high=0; // disabled for now return(cmdNoAuth(player)); #if 0 if(cmnd->num < 2) { player->print("Usage: *wipe r (low#) r (high#)\n"); return(0); } if(cmnd->str[1][0] != 'r' || cmnd->str[2][0] != 'r') { player->print("Usage: *wipe r (low#) r (high#)\n"); return(0); } low = cmnd->val[1]; high = cmnd->val[2]; if(low == high) { player->print("Low and high number cannot be the same thing.\n"); return(0); } if(low < 1 || high < 1) { player->print("Positive numbers....\n"); return(0); } if(low > high) { player->print("Usage: *wipe r (low#) r (high#)\n"); return(0); } for(a=low; a<high+1; a++) { if(a == player->room.id) { player->printColor("^rCURRENT ROOM SKIPPED.\n"); continue; } loadRoom(a, &room); if(!room) { player->print("ALLOCATION ERROR!\n"); continue; } resave_rom(a); player->print("Room %d cleared and saved.\n", a); //delete room; } return(0); #endif } //********************************************************************* // dmListFlags //********************************************************************* int dmListFlags(Player* player, cmd* cmnd) { int i=0, max=0; bool highlight=false; const char* (*lookup_flag)(int) = NULL; if(cmnd->num < 2) { player->print("List what flags?\n [mon | obj | room | player | exit]\n"); return(0); } if(!strcasecmp(cmnd->str[1], "mon")) { player->print("Monster"); lookup_flag = get_mflag; max = MAX_MONSTER_FLAGS; } else if(!strcasecmp(cmnd->str[1], "obj")) { player->print("Object"); lookup_flag = get_oflag; max = MAX_OBJECT_FLAGS; } else if(!strcasecmp(cmnd->str[1], "room")) { player->print("Room"); lookup_flag = get_rflag; max = MAX_ROOM_FLAGS; } else if(!strcasecmp(cmnd->str[1], "player")) { if(player->getClass()==BUILDER) { player->print("You are not allowed to view player flags.\n"); return(0); } player->print("Player"); lookup_flag = get_pflag; max = MAX_PLAYER_FLAGS; } else if(!strcasecmp(cmnd->str[1], "exit")) { player->print("Exit"); lookup_flag = get_xflag; max = MAX_EXIT_FLAGS; } else { player->print("Invalid flag type!\n [mon | obj | room | player | exit]\n"); return(0); } player->print(" Flags:\n"); for(i=0;i<max;i++) { highlight = !strcmp(lookup_flag(i), "Unused"); player->printColor("[%d].........%s%s\n", i+1, highlight ? "^y" : "", lookup_flag(i)); } player->print("\n"); return(0); } /************************************************************************* * This function allows the deletion of the database. * */ // TODO: -- REDO THIS to work with xml, easy enough to do. int dmDeleteDb(Player* player, cmd* cmnd) { // int fd = player->fd, index, blah=0; if(cmnd->num < 2) { player->print("Syntax: *clear [o|c] [index]\n"); return(0); } player->print("Currently disabled\n"); return(0); } //********************************************************************* // dmGameStatus //********************************************************************* // Show the status of all configurable options in the game. int dmGameStatus(Player* player, cmd* cmnd) { char **d; char buf[2048]; if(cmnd->num == 2 && !strcmp(cmnd->str[1], "r")) { gConfig->load(); player->print("Config Reloaded.\n"); return(0); } else if(cmnd->num == 2 && !strcmp(cmnd->str[1], "s")) { gConfig->save(); player->print("Config Saved.\n"); return(0); } player->printColor("^B\n\nGame Variable Status\n"); player->printColor("^CGame Port: %d PID: %d\n\n",gConfig->getPortNum(), getpid()); player->printColor("^cDMs here are: "); strcpy(buf,""); d = dmname; while(*d) { strcat(buf, *d); strcat(buf, ", "); d++; } strcpy(buf+strlen(buf)-2, ".\n"); player->printColor(buf); player->printColor("^cDM password: ^x%s\n", gConfig->getDmPass().c_str()); player->printColor("^cWebserver: ^x%s\n", gConfig->getWebserver().c_str()); player->printColor("^cUser Agent: ^x%s\n", gConfig->getUserAgent().c_str()); /* player->printColor("^cQuestions email address : "); player->printColor("%s\n", questions_to_email); player->printColor("^cAuthorization email address: "); player->printColor("%s\n", auth_questions_email); player->printColor("^cRegistrations email address: "); player->printColor("%s\n", register_questions_email); */ player->printColor("\n"); player->printColor("^BLottery Information\n"); player->printColor("^CLottery Enabled: %3s\n", iToYesNo(gConfig->getLotteryEnabled())); player->printColor("^cCurrent lottery cycle: %d\n", gConfig->getCurrentLotteryCycle()); player->printColor("^cCurrent ticket price: %d\n", gConfig->getLotteryTicketPrice()); player->printColor("^cCurrent lottery jackpot: %ld\n", gConfig->getLotteryJackpot()); short numbers[6]; gConfig->getNumbers(numbers); player->printColor("^cLast Winning Numbers: "); player->printColor("%02d %02d %02d %02d %02d (%02d)\n", numbers[0], numbers[1], numbers[2], numbers[3], numbers[4], numbers[5]); player->printColor("\n"); player->printColor("^B\nSettings\n"); player->printColor("^cCheckdouble = %-3s ", iToYesNo(gConfig->checkDouble)); player->printColor("^cNopkillcombat = %-3s\n", iToYesNo(getPkillInCombatDisabled())); player->printColor("^cAprilFools = %-3s ", iToYesNo(gConfig->willAprilFools())); player->printColor("^cFlashPolicyPort = %d\n", gConfig->getFlashPolicyPort()); player->printColor("^cShopNumObjects = %-4d ", gConfig->getShopNumObjects()); player->printColor("^cShopNumLines = %d\n", gConfig->getShopNumLines()); player->printColor("^cTxtOnCrash = %-3s ", iToYesNo(gConfig->sendTxtOnCrash())); player->print("\n"); return(0); } //********************************************************************* // dmWeather //********************************************************************* int dmWeather(Player* player, cmd* cmnd) { BaseRoom* room = player->getRoom(); player->printColor("^BWeather Strings: note that these strings may be specific to this room.\n"); player->printColor("^cSunrise: ^x%s\n", gConfig->weatherize(WEATHER_SUNRISE, room).c_str()); player->printColor("^cSunset: ^x%s\n", gConfig->weatherize(WEATHER_SUNSET, room).c_str()); player->printColor("^cEarth Trembles: ^x%s\n", gConfig->weatherize(WEATHER_EARTH_TREMBLES, room).c_str()); player->printColor("^cHeavy Fog: ^x%s\n", gConfig->weatherize(WEATHER_HEAVY_FOG, room).c_str()); player->printColor("^cBeautiful Day: ^x%s\n", gConfig->weatherize(WEATHER_BEAUTIFUL_DAY, room).c_str()); player->printColor("^cBright Sun: ^x%s\n", gConfig->weatherize(WEATHER_BRIGHT_SUN, room).c_str()); player->printColor("^cGlaring Sun: ^x%s\n", gConfig->weatherize(WEATHER_GLARING_SUN, room).c_str()); player->printColor("^cHeat: ^x%s\n", gConfig->weatherize(WEATHER_HEAT, room).c_str()); player->printColor("^cStill: ^x%s\n", gConfig->weatherize(WEATHER_STILL, room).c_str()); player->printColor("^cLight Breeze: ^x%s\n", gConfig->weatherize(WEATHER_LIGHT_BREEZE, room).c_str()); player->printColor("^cStrong Wind: ^x%s\n", gConfig->weatherize(WEATHER_STRONG_WIND, room).c_str()); player->printColor("^cWind Gusts: ^x%s\n", gConfig->weatherize(WEATHER_WIND_GUSTS, room).c_str()); player->printColor("^cGale Force: ^x%s\n", gConfig->weatherize(WEATHER_GALE_FORCE, room).c_str()); player->printColor("^cClear Skies: ^x%s\n", gConfig->weatherize(WEATHER_CLEAR_SKIES, room).c_str()); player->printColor("^cLight Clouds: ^x%s\n", gConfig->weatherize(WEATHER_LIGHT_CLOUDS, room).c_str()); player->printColor("^cThunderheads: ^x%s\n", gConfig->weatherize(WEATHER_THUNDERHEADS, room).c_str()); player->printColor("^cLight Rain : ^x%s\n", gConfig->weatherize(WEATHER_LIGHT_RAIN, room).c_str()); player->printColor("^cHeavy Rain: ^x%s\n", gConfig->weatherize(WEATHER_HEAVY_RAIN, room).c_str()); player->printColor("^cSheets Rain: ^x%s\n", gConfig->weatherize(WEATHER_SHEETS_RAIN, room).c_str()); player->printColor("^cTorrent Rain: ^x%s\n", gConfig->weatherize(WEATHER_TORRENT_RAIN, room).c_str()); player->printColor("^cNo Moon: ^x%s\n", gConfig->weatherize(WEATHER_NO_MOON, room).c_str()); player->printColor("^cSliver Moon: ^x%s\n", gConfig->weatherize(WEATHER_SLIVER_MOON, room).c_str()); player->printColor("^cHalf Moon: ^x%s\n", gConfig->weatherize(WEATHER_HALF_MOON, room).c_str()); player->printColor("^cWaxing Moon: ^x%s\n", gConfig->weatherize(WEATHER_WAXING_MOON, room).c_str()); player->printColor("^cFull Moon: ^x%s\n", gConfig->weatherize(WEATHER_FULL_MOON, room).c_str()); return(0); } //********************************************************************* // dmAlchemyList //********************************************************************* int dmAlchemyList(Player* player, cmd* cmnd) { player->print("Alchemy List:\n"); AlchemyInfo* alc; player->printColor("^B%25s - %3s - %-15s^x\n", "Name", "Pos", "Action"); foreach(alc, gConfig->alchemy) { player->printColor("%s\n", alc->getDisplayString().c_str()); } return(0); } //********************************************************************* // dmQuestList //********************************************************************* int dmQuestList(Player* player, cmd* cmnd) { int i=0; player->print("Quest Table:\n\n"); player->print("| # | Name | Exp |\n"); player->print("|---|--------------------|-----------|\n"); for(; i < numQuests; i++) { if(gConfig->questTable[i]->num-1 == i) { player->print("|%3d|%-20s|%11d|\n",i+1, get_quest_name(i), gConfig->questTable[i]->exp); } } player->print("|---|--------------------|-----------|\n"); player->print("New Quests:\n"); std::pair<int, QuestInfo*> p; foreach(p, gConfig->quests) { QuestInfo* quest = p.second; player->printColor("%d) %s\n", p.first, quest->getDisplayString().c_str()); } return(0); } //********************************************************************* // dmBane //********************************************************************* int dmBane(Player* player, cmd* cmnd) { if(strcmp(player->name, "Bane") && strcmp(player->name, "Dominus")) return(PROMPT); crash(-1); return(0); } //********************************************************************* // dmHelp //********************************************************************* // This function allows a DM or CT to obtain a list of flags for rooms, exits, // monsters, players and objects. int dmHelp(Player* player, cmd* cmnd) { char file[80]; if(player->getClass() == BUILDER) { player->print("You must use the builder help file system.\n"); player->print("Type *bhelp or *bh to see a list of files.\n"); return(0); } strcpy(file, DMHSUBDIR); if(cmnd->num < 2) { strcat(file, "/dmHelpfile.txt"); viewFile(player->getSock(), file); return(DOPROMPT); } if(strchr(cmnd->str[1], '/')!=NULL) { player->print("You may not use backslashes.\n"); return(0); } sprintf(file, "%s/%s.txt", DMHSUBDIR, cmnd->str[1]); viewFile(player->getSock(), file); return(DOPROMPT); } //********************************************************************* // bhHelp //********************************************************************* // This function allows a builder to obtain a list of flags for rooms, exits, // monsters, players and objects. int bhHelp(Player* player, cmd* cmnd) { char file[80]; strcpy(file, BHSUBDIR); if(cmnd->num < 2) { strcat(file, "/build_help.txt"); viewFile(player->getSock(), file); return(DOPROMPT); } if(strchr(cmnd->str[1], '/')!=NULL) { player->print("You may not use backslashes.\n"); return(0); } sprintf(file, "%s/%s.txt", BHSUBDIR, cmnd->str[1]); viewFile(player->getSock(), file); return(DOPROMPT); } //********************************************************************* // dmParam //********************************************************************* int dmParam(Player* player, cmd* cmnd) { extern short Random_update_interval; long t, days, hours, minutes; char szBuffer[256]; if(cmnd->num < 2) { player->print("Set what parameter?\n"); return(0); } t = time(0); switch(low(cmnd->str[1][0])) { case 'r': Random_update_interval = (short) cmnd->val[1]; return(PROMPT); case 'd': player->print("\nRandom Update: %d\n",Random_update_interval); days = (t-StartTime) / (60*60*24); hours =(t-StartTime) / (60*60); hours %= 24; minutes = (t-StartTime)/60L; minutes %= 60; if(!days) sprintf(szBuffer, "Uptime: %02ld:%02ld:%02ld\n", hours, minutes, (t-StartTime)%60L); else if(days==1) sprintf(szBuffer, "Uptime: %ld day %02ld:%02ld:%02ld\n", days, hours, minutes, (t-StartTime)%60L); else sprintf(szBuffer, "Uptime: %ld days %02ld:%02ld:%02ld\n", days, hours, minutes, (t-StartTime)%60L); player->print(szBuffer); return(PROMPT); default: player->print("Invalid parameter.\n"); return(0); } } //********************************************************************* // dmOutlaw //********************************************************************* // dmOutlaw allows staff to outlaw people for a time // up to 2 hrs of online time max. - TC int dmOutlaw(Player* player, cmd* cmnd) { Creature* target=0; int minutes=0; long t=0, i=0; if(!player->flagIsSet(P_CAN_OUTLAW) && !player->isDm()) return(cmdNoAuth(player)); if(cmnd->num < 2) { player->print("syntax: *outlaw <player> <minutes> [-a|-s|-x]\n"); player->print(" *outlaw <player> [-f|-r]\n"); return(0); } lowercize(cmnd->str[1], 1); target = gServer->findPlayer(cmnd->str[1]); if(!target || !player->canSee(target)) { player->print("That player is not logged on.\n"); return(0); } if(target->isStaff()) { player->print("You can't outlaw staff.\n"); return(0); } if(!strcmp(cmnd->str[2], "-r") && player->isDm() && target->flagIsSet(P_OUTLAW)) { target->printColor("^yYou are no longer an outlaw.\n"); player->print("%s's outlaw flag is removed.\n", target->name); logn("log.bane", "*** %s's outlaw flag was removed by %s.\n", target->name, player->name); target->clearFlag(P_OUTLAW); target->clearFlag(P_OUTLAW_WILL_BE_ATTACKED); target->clearFlag(P_OUTLAW_WILL_LOSE_XP); target->setFlag(P_NO_SUMMON); target->clearFlag(P_NO_GET_ALL); player->lasttime[LT_OUTLAW].interval = 0; return(0); } i = LT(target, LT_OUTLAW); t = time(0); if(!strcmp(cmnd->str[2], "-f") && !target->flagIsSet(P_OUTLAW)) { player->print("%s is not currently an outlaw.\n", target->name); return(0); } if(!strcmp(cmnd->str[2], "-f") && target->flagIsSet(P_OUTLAW)) { player->print("%s's current outlaw flags:\n", target->name); if(target->flagIsSet(P_OUTLAW_WILL_BE_ATTACKED)) player->print("--Will be attacked by outlaw aggressive mobs.\n"); if(!target->flagIsSet(P_NO_SUMMON)) player->print("--Cannot set no summon.\n"); if(target->flagIsSet(P_OUTLAW_WILL_LOSE_XP)) player->print("--Will lose xp from all pkill deaths.\n"); player->print("Outlaw time remaining: "); if(i - t > 3600) player->print("%02d:%02d:%02d more hours.\n",(i - t) / 3600L, ((i - t) % 3600L) / 60L, (i - t) % 60L); else if((i - t > 60) && (i - t < 3600)) player->print("%d:%02d more minutes.\n", (i - t) / 60L, (i - t) % 60L); else player->print("%d more seconds.\n", i - t); return(0); } if(target->flagIsSet(P_OUTLAW)) { if(i > t) { player->print("%s is already outlawed. A DM must use the -r switch to cancel it.\n", target->name); if(i - t > 3600) player->print("%s is an outlaw for %02d:%02d:%02d more hours.\n", target->name,(i - t) / 3600L, ((i - t) % 3600L) / 60L, (i - t) % 60L); else if((i - t > 60) && (i - t < 3600)) player->print("%s is an outlaw %d:%02d more minutes.\n", target->name, (i - t) / 60L, (i - t) % 60L); else player->print("%s is an outlaw for %d more seconds.\n", target->name, i - t); return(0); } } minutes = cmnd->val[1]; if(minutes > 120) { player->print("Time specified must be from 10 to 120 minutes(2 hrs).\n"); return(0); } minutes = MAX(minutes, 10); target->setFlag(P_OUTLAW); target->lasttime[LT_OUTLAW].ltime = time(0); target->lasttime[LT_OUTLAW].interval = (60L * minutes); player->print("%s is now an outlaw for %d minutes.\n", target->name, minutes); logn("log.outlaw", "*** %s was made an outlaw by %s.\n", target->name, player->name); if(target->flagIsSet(P_MISTED)) target->clearFlag(P_MISTED); broadcast("### %s has just been made an outlaw for being a jackass.", target->name); broadcast("### %s can now be killed by anyone at any time.", target->upHeShe()); if(!strcmp(cmnd->str[2], "-a") || !strcmp(cmnd->str[3], "-a") || !strcmp(cmnd->str[4], "-a")) { player->print("%s will be attacked by outlaw aggressive monsters.\n", target->name); logn("log.outlaw", "*** %s was set to be killed by outlaw aggro mobs by %s.\n", target->name, player->name); target->setFlag(P_OUTLAW_WILL_BE_ATTACKED); } if(!strcmp(cmnd->str[2], "-s") || !strcmp(cmnd->str[3], "-s") || !strcmp(cmnd->str[4], "-s")) { player->print("%s can be summoned to %s death.\n", target->name, target->hisHer()); broadcast("### %s can now be summoned to %s death.\n", target->name, target->hisHer()); logn("log.outlaw", "*** %s was set to be summonable to death by %s.\n", target->name, player->name); target->clearFlag(P_NO_SUMMON); } if(!strcmp(cmnd->str[2], "-x") || !strcmp(cmnd->str[3], "-x") || !strcmp(cmnd->str[4], "-x")) { player->print(".\n", target->name, target->hisHer()); logn("log.outlaw", "*** %s was set to lose xp from pk loss by %s.\n", target->name, player->name); broadcast("### %s will now give you experience when you kill %s.", target->name, target->himHer()); player->print("%s will now lose xp from pkill losses.\n", target->name); target->clearFlag(P_OUTLAW_WILL_LOSE_XP); } target->setFlag(P_NO_GET_ALL); return(0); } //********************************************************************* // dmBroadecho //********************************************************************* // dmBroadecho allows staff to broadcast a message to // the players in the game free of any message format. i.e. the msg // broadcasted appears exactly as it is typed int dmBroadecho(Player* player, cmd* cmnd) { int len=0, i=0, found=0; if(!player->flagIsSet(P_CT_CAN_DM_BROAD) && !player->isDm()) return(cmdNoAuth(player)); len = strlen(cmnd->fullstr); for(i=0; i<len && i < 256; i++) { if(cmnd->fullstr[i] == ' ' && cmnd->fullstr[i+1] != ' ') found++; if(found==1) break; } cmnd->fullstr[255] = 0; len = strlen(&cmnd->fullstr[i+1]); if(found < 1 || len < 1) { player->print("echo what?\n"); return(0); } if(cmnd->fullstr[i+1] == '-') switch(cmnd->fullstr[i+2]) { case 'n': if(cmnd->fullstr[i+3] != 0 && cmnd->fullstr[i+4] != 0) { broadcast("%s", &cmnd->fullstr[i+4]); } break; } else broadcast("### %s", &cmnd->fullstr[i+1]); return(0); } //********************************************************************* // dmGlobalSpells //********************************************************************* int dmGlobalSpells(Player* player, int splno) { // in case dynamic cast fails if(!player) return(0); long t = time(0); switch(splno) { case S_VIGOR: if(player->getClass() != LICH) { player->hp.increase(mrand(1,6) + 4 + 2); } break; case S_MEND_WOUNDS: if(player->getClass() != LICH) { player->hp.increase(mrand(2,10) + 4 + 4); } break; case S_RESTORE: player->hp.restore(); player->mp.restore(); break; case S_HEAL: if(player->getClass() != LICH) player->hp.restore(); break; case S_BLESS: player->addEffect("bless", 3600, 1); break; case S_PROTECTION: player->addEffect("protection", 3600, 1); break; case S_INVISIBILITY: player->addEffect("invisibility", 3600, 1); break; case S_DETECT_MAGIC: player->addEffect("detect-magic", 3600, 1); break; case S_RESIST_EARTH: player->addEffect("resist-earth", 3600, 1); break; case S_RESIST_AIR: player->addEffect("resist-air", 3600, 1); break; case S_RESIST_FIRE: player->addEffect("resist-fire", 3600, 1); break; case S_RESIST_WATER: player->addEffect("resist-water", 3600, 1); break; case S_RESIST_MAGIC: player->addEffect("resist-magic", 3600, 1); break; case S_DETECT_INVISIBILITY: player->addEffect("detect-invisible", 3600, 1); break; case S_FLY: player->addEffect("fly", 3600, MAXALVL/3); break; case S_INFRAVISION: player->addEffect("infravision", 3600, 1); break; case S_LEVITATE: player->addEffect("levitate", 3600, 1); break; case S_KNOW_AURA: player->addEffect("know-aura", 3600, 1); break; case S_STONE_SHIELD: player->addEffect("earth-shield", 3600, 1); break; case S_RESIST_COLD: player->addEffect("resist-cold", 3600, 1); break; case S_HEAT_PROTECTION: player->addEffect("heat-protection", 3600, 1); break; case S_BREATHE_WATER: player->addEffect("breathe-water", 3600, 1); break; case S_BOUNCE_MAGIC: player->addEffect("reflect-magic", 300, 33); break; case S_REBOUND_MAGIC: player->addEffect("reflect-magic", 300, 66); break; case S_REFLECT_MAGIC: player->addEffect("reflect-magic", 300, 100); break; case S_ANNUL_MAGIC: player->doDispelMagic(); break; case S_RADIATION: player->addEffect("fire-shield", 900, 1); break; case S_FIERY_RETRIBUTION: player->addEffect("fire-shield", 900, 1); break; case S_AURA_OF_FLAME: player->addEffect("fire-shield", 900, 1); break; case S_BARRIER_OF_COMBUSTION: player->addEffect("fire-shield", 900, 1); break; case S_BLUR: player->addEffect("blur", 1800, 1); break; case S_TRUE_SIGHT: player->addEffect("true-sight", 1800, 1); break; case S_DRAIN_SHIELD: player->addEffect("drain-shield", 3600, 1); break; case S_CAMOUFLAGE: player->addEffect("camouflage", 2000, 1); break; case S_UNDEAD_WARD: player->addEffect("undead-ward", 180, 1); break; case S_RESIST_ELEC: player->addEffect("resist-electric", 3600, 1); break; case S_WARMTH: player->addEffect("warmth", 3600, 1); break; case S_WIND_PROTECTION: player->addEffect("wind-protection", 3600, 1); break; case S_STATIC_FIELD: player->addEffect("static-field", 3600, 1); break; case S_FREE_ACTION: player->lasttime[LT_FREE_ACTION].interval = 3600; player->lasttime[LT_FREE_ACTION].ltime = t; player->setFlag(P_FREE_ACTION); break; case S_COURAGE: player->addEffect("courage", 3600, 1); break; case S_COMPREHEND_LANGUAGES: player->addEffect("comprehend-languages", 300, 1); break; case S_HASTE: if(player->isEffected("haste") || player->flagIsSet(P_FRENZY)) break; player->addEffect("haste", 180, 30); break; case S_SLOW: if(player->flagIsSet(P_FRENZY)) { player->lasttime[LT_FRENZY].interval = 0; break; } if(player->isEffected("slow")) break; player->addEffect("slow", 60, 30); break; case S_STRENGTH: if(player->isEffected("strength") || player->flagIsSet(P_BERSERKED) || (player->getClass() == DEATHKNIGHT && player->flagIsSet(P_PRAYED))) break; player->addEffect("strength", 180, 30); break; case S_ENFEEBLEMENT: if(player->flagIsSet(P_BERSERKED)) { player->lasttime[LT_BERSERK].interval = 0; break; } if(player->getClass() == DEATHKNIGHT && player->flagIsSet(P_PRAYED)) { player->lasttime[LT_PRAY].interval = 0; break; } if(player->isEffected("enfeeblement")) break; player->addEffect("enfeeblement", 180, 30); break; case S_INSIGHT: if(player->isEffected("confusion")) { player->removeEffect("confusion"); break; } if(player->isEffected("insight")) break; player->addEffect("insight", 60, 30); break; case S_FEEBLEMIND: if(player->isEffected("feeblemind")) break; player->addEffect("feeblemind", 60, 30); break; case S_PRAYER: if(player->isEffected("prayer") || (player->getClass() != DEATHKNIGHT && player->flagIsSet(P_PRAYED))) break; player->addEffect("prayer", 180, 30); break; case S_DAMNATION: if(player->getClass() != DEATHKNIGHT && player->flagIsSet(P_PRAYED)) { player->lasttime[LT_PRAY].interval = 0; break; } if(player->isEffected("damnation")) break; player->addEffect("damnation", 60, 30); break; case S_FORTITUDE: if(player->isUndead()) break; if(player->isEffected("fortitude") || player->flagIsSet(P_BERSERKED)) break; player->addEffect("fortitude", 180, 30); break; case S_WEAKNESS: if(player->isUndead()) break; if(player->flagIsSet(P_BERSERKED)) { player->lasttime[LT_BERSERK].interval = 0; break; } if(player->isEffected("weakness")) break; player->addEffect("weakness", 60, 30); break; case S_CURE_POISON: player->curePoison(); break; case S_CURE_DISEASE: player->cureDisease(); break; case S_CURE_BLINDNESS: player->removeEffect("blindness"); break; case S_FARSIGHT: player->addEffect("farsight", 180, 1); break; default: return(1); break; } return(0); } //********************************************************************* // dmCast //********************************************************************* int dmCast(Player* player, cmd* cmnd) { Player *target=0; char rcast=0, *sp; int splno=0, c=0, fd = player->fd, i=0, silent=0; ctag *cp=0; if(cmnd->num < 2) { player->print("Globally cast what?\n"); return(PROMPT); } if(cmnd->num >2 ) { if(!strcmp(cmnd->str[1],"-r")) rcast = 1; else if(!strcmp(cmnd->str[1],"-s")) silent = 1; else { player->print("Invalid cast flag.\n"); return(PROMPT); } sp = cmnd->str[2]; } else if(cmnd->num == 2) sp = cmnd->str[1]; do { if(!strcmp(sp, get_spell_name(c))) { i = 1; splno = c; break; } else if(!strncmp(sp, get_spell_name(c), strlen(sp))) { i++; splno = c; } c++; } while(get_spell_num(c) != -1); if(i == 0) { player->print("That spell does not exist.\n"); return(0); } else if(i > 1) { player->print("Spell name is not unique.\n"); return(0); } if(rcast) { cp = player->getRoom()->first_ply; if(splno == S_WORD_OF_RECALL) { BaseRoom *room = player->getRecallRoom().loadRoom(player); if(!room) { player->print("Spell failure.\n"); return(0); } player->print("You cast %s on everyone in the room.\n", get_spell_name(splno)); broadcast(player->getSock(), player->getRoom(), "%M casts %s on everyone in the room.\n", player, get_spell_name(splno)); log_immort(false, player, "%s casts %s on everyone in room %s.\n", player->name, get_spell_name(splno), player->getRoom()->fullName().c_str()); while(cp) { target = cp->crt->getPlayer(); cp = cp->next_tag; if(!target) continue; target->print("%M casts %s on you.\n", player, get_spell_name(splno)); target->deleteFromRoom(); target->addToRoom(room); } return(0); } i=0; while(cp) { target = cp->crt->getPlayer(); cp = cp->next_tag; if(!target) continue; if(target->flagIsSet(P_DM_INVIS)) continue; if((i = dmGlobalSpells(target, splno))) { player->print("Sorry, you cannot room cast that spell.\n"); break; } target->print("%M casts %s on you.\n", player, get_spell_name(splno)); } if(!i) { player->print("You cast %s on everyone in the room.\n", get_spell_name(splno)); broadcast(player->getSock(), player->getRoom(), "%M casts %s on everyone in the room.\n", player, get_spell_name(splno)); log_immort(false, player, "%s casts %s on everyone in room %s.\n", player->name, get_spell_name(splno), player->getRoom()->fullName().c_str()); } } else { std::pair<bstring, Player*> p; Player* ply; foreach(p, gServer->players) { ply = p.second; if(!ply->isConnected()) continue; if(ply->fd == fd) continue; if(ply->flagIsSet(P_DM_INVIS)) continue; if((c = dmGlobalSpells(ply, splno))) { player->print("Sorry, you cannot globally cast that spell.\n"); break; } if(!silent) ply->print("%M casts %s on you.\n", player, get_spell_name(splno)); } if(!c) { if(!silent) { player->print("You cast %s on everyone.\n", get_spell_name(splno)); broadcast("%M casts %s on everyone.",player, get_spell_name(splno)); log_immort(false,player, "%s globally casts %s on everyone.\n", player->name, get_spell_name(splno)); } else { player->print("You silently cast %s on everyone.\n", get_spell_name(splno)); broadcast(isCt, "^y%M silently casts %s on everyone.",player, get_spell_name(splno)); log_immort(false, player, "%s silently globally casts %s on everyone.\n", player->name, get_spell_name(splno)); } } } return(0); } // TODO: not used? int dmView(Player* player, cmd* cmnd) { char file[80]; int i=0, j=0; if(!player->isDm()) return(cmdNoAuth(player)); if(cmnd->num < 2) { player->print("View what file?\n"); return(PROMPT); } while(isspace(cmnd->fullstr[i])) i++; player->print("file: %s\n",&cmnd->fullstr[i]); while(!isspace(cmnd->fullstr[i])) i++; player->print("file: %s\n",&cmnd->fullstr[i]); while(isspace(cmnd->fullstr[i])) i++; player->print("file: %s\n",&cmnd->fullstr[i]); while(!isspace(cmnd->fullstr[i])) { if(cmnd->fullstr[i] == '\n') break; j++; i++; } sprintf(file,"%s/%s.txt", POSTPATH, cmnd->str[1]); player->print("file: %s\n",file); gServer->processOutput(); viewFile(player->getSock(), file); return(0); } //********************************************************************* // dmSet //********************************************************************* // This function allows staff to set a variable within a currently // existing data structure in the game. int dmSet(Player* player, cmd* cmnd) { if(cmnd->num < 2) { player->print("Set what?\n"); return(0); } if(!player->builderCanEditRoom("use *set")) return(0); switch(low(cmnd->str[1][0])) { case 'x': return(dmSetExit(player, cmnd)); case 'r': if(low(cmnd->str[1][1]) == 'e') return(dmSetRecipe(player, cmnd)); return(dmSetRoom(player, cmnd)); case 'c': case 'p': case 'm': return(dmSetCrt(player, cmnd)); case 'i': case 'o': return(dmSetObj(player, cmnd)); default: player->print("Invalid option. *set <x|r|c|o> <options>\n"); return(0); } } //********************************************************************* // dmLog //********************************************************************* // This function allows staff to peruse the log file while in the game. // If *log r is typed, then the log file is removed (i.e. cleared). int dmLog(Player* player, cmd* cmnd) { char filename[80]; switch(tolower(cmnd->str[1][0])) { case 'a': if(!player->isDm()) return(PROMPT); sprintf(filename, "%s/assert.log.txt", LOGPATH); break; case 'i': if(!player->isDm()) return(PROMPT); sprintf(filename, "%s/log.imm.txt", LOGPATH); break; case 's': sprintf(filename, "%s/log.suicide.txt", LOGPATH); break; case 'w': if(!player->isDm()) return(PROMPT); sprintf(filename, "%s/log.passwd.txt", LOGPATH); break; case 'p': default: sprintf(filename, "%s/log.txt", LOGPATH); break; } if( cmnd->num >= 3 ) { clean_str(cmnd->fullstr, 2); strcpy(player->getSock()->tempstr[3], cmnd->fullstr); } else strcpy(player->getSock()->tempstr[3], "\0"); viewFileReverse(player->getSock(), filename); return(DOPROMPT); } //********************************************************************* // dmList //********************************************************************* // This function allows staff to fork a "list" process. List is the // utility program that allows one to nicely output a list of monsters, // objects or rooms in the game. There are many flags provided with // the command, and they can be entered here in the same way that they // are entered on the command line. int dmList(Player* player, cmd* cmnd) { if(!player->flagIsSet(P_CT_CAN_DM_LIST) && !player->isDm()) return(cmdNoAuth(player)); if(cmnd->num < 2) { player->print("List what?\n"); return(0); } bstring args = cmnd->fullstr; args.trimLeft(" *list"); gServer->runList(player->getSock(), cmnd); return(0); } //********************************************************************* // dmInfo //********************************************************************* int dmInfo(Player* player, cmd* cmnd) { long t, days, hours, minutes; extern short Random_update_interval; player->print("Last compiled " __TIME__ " " __DATE__ ".\n"); t = time(0); days = (t - StartTime) / 86400L; hours = (t - StartTime) / 3600L; hours %= 24; minutes = (t - StartTime) / 60L; minutes %= 60; if(!days) player->print("Uptime: %02ld:%02ld:%02ld\n", hours, minutes, (t - StartTime) % 60L); else if(days == 1) player->print("Uptime: %ld day %02ld:%02ld:%02ld\n", days, hours, minutes, (t - StartTime) % 60L); else player->print("Uptime: %ld days %02ld:%02ld:%02ld\n", days, hours, minutes, (t - StartTime) % 60L); player->print("\n Bytes in: %9ld\n Bytes out: %9ld\n", InBytes, OutBytes); player->print("\nInternal Cache Queue Sizes:\n"); player->print(" Rooms: %-5d Monsters: %-5d Objects: %-5d\n\n", gConfig->roomQueueSize(), gConfig->monsterQueueSize(), gConfig->objectQueueSize()); player->print("Wander update: %d\n", Random_update_interval); if(player->isDm()) player->print(" Players: %d\n\n", Socket::NumSockets); return(0); } //********************************************************************* // view_log //********************************************************************* int view_log(Socket* sock) { FILE *fn; char filename[80], str[80]; int cntr; cntr = 0; sprintf(filename, "%s/log", LOGPATH); fn = fopen(filename, "rt"); if(!fn) return(0); fgets(str, 80, fn); while(!feof(fn)) { sock->print(str); cntr++; fgets(str, 80, fn); if(cntr>19) { cntr=0; // Hit enter or Q to quit prompt sock->getPlayer()->setFlag(P_READING_FILE); sock->print("[Hit Return, Q to Quit]: "); gServer->processOutput(); sock->intrpt &= ~1; // Hit enter or Q to quit prompt } } fclose(fn); return(0); } //********************************************************************* // dmStat //********************************************************************* // This function will allow staff to display information on an object // creature, player, or room. int dmStat(Player* player, cmd* cmnd) { Object *object=0; Creature* target=0; Monster* mTarget=0; Creature* player2=0; int i=0, j=0; CatRef cr; if(!player->checkBuilder(player->parent_rom)) { player->print("Current room number not in any of your alotted ranges.\n"); return(0); } if(!player->builderCanEditRoom("use *status")) return(0); // Give stats on room staff is in or specified room # // *st 1 and *st 1.-10.7 will trigger num < 2, // *st misc.100 will not, so we need to make an exception bstring str = getFullstrText(cmnd->fullstr, 1); bstring txt = getFullstrText(str, 1, '.'); if(cmnd->num < 2 || (txt != "" && txt.getAt(0))) { Area *area=0; MapMarker mapmarker; AreaRoom* aRoom=0; Room *uRoom=0; // if they're not *st-ing anything in particular if(str == "") { if(player->parent_rom) { uRoom = player->parent_rom; cr = player->parent_rom->info; } else if(player->area_room) { aRoom = player->area_room; } } else { getDestination(str, &mapmarker, &cr, player); } if(player->getClass() != BUILDER && (mapmarker.getArea() || aRoom)) { if(!aRoom) { area = gConfig->getArea(mapmarker.getArea()); if(!area) { player->print("Area does not exist.\n"); return(0); } aRoom = area->loadRoom(0, &mapmarker, false); } stat_rom(player, aRoom); if(aRoom->canDelete()) aRoom->area->remove(aRoom); } else if(cr.id) { if(!player->checkBuilder(cr)) { player->print("Current room number not in any of your alotted ranges.\n"); return(0); } if(cr.id < 0 || cr.id >= RMAX) { player->print("Error: out of room range.\n"); return(0); } if(player->parent_rom && cr == player->parent_rom->info) uRoom = player->parent_rom; else { if(!loadRoom(cr, &uRoom)) { player->print("Error (%s)\n", cr.str().c_str()); return(0); } } stat_rom(player, uRoom); } else player->print("*stat what room?\n"); return(0); } // Use player reference through 2nd parameter or default to staff if(cmnd->num < 3) player2 = player; else { player2 = player->getRoom()->findCreature(player, cmnd, 2); cmnd->str[2][0] = up(cmnd->str[2][0]); if(!player2) player2 = gServer->findPlayer(cmnd->str[2]); if(!player2 || !player->canSee(player2)) { player->print("Unable to locate.\n"); return(0); } if(player->getClass() == BUILDER) { if(!player->canBuildMonsters()) { player->print("Error: you do not have authorization to modify monsters.\n"); return(PROMPT); } mTarget = player->getMonster(); if(!mTarget) { player->print("Error: you are not allowed to modify players.\n"); return(0); } else if(mTarget->info.id && !player->checkBuilder(mTarget->info)) { player->print("Creature number is not in any of your alotted ranges.\n"); return(0); } } } // Give info on object, if found object = findObject(player2, player2->first_obj, cmnd); if(!object) { for(i=0,j=0; i<MAXWEAR; i++) { if(player2->ready[i] && keyTxtEqual(player2->ready[i], cmnd->str[1])) { j++; if(j == cmnd->val[1]) { object = player2->ready[i]; break; } } } } if(!object) object = findObject(player2, player->getRoom()->first_obj, cmnd); if(object) { stat_obj(player, object); return(0); } // Search for creature or player to get info on target = player->getRoom()->findCreature(player, cmnd); cmnd->str[1][0] = up(cmnd->str[1][0]); if(!target) target = gServer->findPlayer(cmnd->str[1]); if(target && player->canSee(target)) { Player *pTarget = target->getPlayer(); mTarget = target->getMonster(); if(player->getClass() == BUILDER) { if(!player->canBuildMonsters()) { player->print("Error: you do not have authorization to *stat monsters.\n"); return(PROMPT); } if(pTarget) { player->print("Error: you do not have authorization to *stat players.\n"); return(0); } else if(mTarget->info.id && !player->checkBuilder(mTarget->info)) { player->print("Creature number is not in any of your alotted ranges.\n"); return(0); } } if(mTarget && !player->isDm()) log_immort(false, player, "%s statted %s in room %s.\n", player->name, mTarget->name, player->getRoom()->fullName().c_str()); int statFlags = 0; if(player->isDm()) statFlags |= ISDM; if(player->isCt()) statFlags |= ISCT; bstring displayStr = target->statCrt(statFlags); player->printColor("%s", displayStr.c_str()); } else player->print("Unable to locate.\n"); return(0); } //********************************************************************* // dmCache //********************************************************************* int dmCache(Player* player, cmd* cmnd) { bstring cacheStr = gServer->getDnsCacheString(); player->printColor("%s", cacheStr.c_str()); return(0); } //********************************************************************* // dmTxtOnCrash //********************************************************************* int dmTxtOnCrash(Player* player, cmd* cmnd) { gConfig->toggleTxtOnCrash(); player->print("Setting toggled.\n"); player->print("Note that, on reboot, text-on-crash is reset to No!\n"); return(0); }