/* * guilds.cpp * Player run guilds. * ____ _ * | _ \ ___ __ _| |_ __ ___ ___ * | |_) / _ \/ _` | | '_ ` _ \/ __| * | _ < __/ (_| | | | | | | \__ \ * |_| \_\___|\__,_|_|_| |_| |_|___/ * * Permission to use, modify and distribute ics granted via the * Creative Commons - Attribution - Non Commercial - Share Alike 3.0 License * http://creativecommons.org/licenses/by-nc-sa/3.0/ * * Copyright (C) 2007-2012 Jason Mitchell, Randi Mitchell * Contributions by Tim Callahan, Jonathan Hseu * Based on Mordor (C) Brooke Paul, Brett J. Vickers, John P. Freeman * */ #include "mud.h" #include "commands.h" #include "move.h" #include "guilds.h" #include "bank.h" #include "property.h" #include "dm.h" #include "web.h" #include <fcntl.h> //********************************************************************* // Guild //********************************************************************* Guild::Guild() { name = ""; leader = ""; num = 0; level = numMembers = pkillsIn = pkillsWon = 0; points = 0; } //********************************************************************* // getName //********************************************************************* bstring Guild::getName() const { return(name); } //********************************************************************* // getNum //********************************************************************* unsigned short Guild::getNum() const { return(num); } //********************************************************************* // getLeader //********************************************************************* bstring Guild::getLeader() const { return(leader); } //********************************************************************* // getLevel //********************************************************************* long Guild::getLevel() const { return(level); } //********************************************************************* // getNumMembers //********************************************************************* int Guild::getNumMembers() const { return(numMembers); } //********************************************************************* // getPkillsIn //********************************************************************* long Guild::getPkillsIn() const { return(pkillsIn); } //********************************************************************* // getPkillsWon //********************************************************************* long Guild::getPkillsWon() const { return(pkillsWon); } //********************************************************************* // getPoints //********************************************************************* long Guild::getPoints() const { return(points); } //********************************************************************* // setName //********************************************************************* void Guild::setName(bstring n) { name = n; } //********************************************************************* // setNum //********************************************************************* void Guild::setNum(unsigned short n) { num = n; } //********************************************************************* // setLeader //********************************************************************* void Guild::setLeader(bstring l) { leader = l; } //********************************************************************* // setLevel //********************************************************************* void Guild::setLevel(long l) { level = l; } //********************************************************************* // setNumMembers //********************************************************************* void Guild::setNumMembers(int n) { numMembers = n; } //********************************************************************* // setPkillsIn //********************************************************************* void Guild::setPkillsIn(long pk) { pkillsIn = pk; } //********************************************************************* // setPkillsWon //********************************************************************* void Guild::setPkillsWon(long pk) { pkillsWon = pk; } //********************************************************************* // setPoints //********************************************************************* void Guild::setPoints(long p) { points = p; } //********************************************************************* // incLevel //********************************************************************* void Guild::incLevel(int l) { level += l; } //********************************************************************* // incNumMembers //********************************************************************* void Guild::incNumMembers(int n) { numMembers += n; } //********************************************************************* // incPkillsIn //********************************************************************* void Guild::incPkillsIn(long pk) { pkillsIn += pk; } //********************************************************************* // incPkillsWon //********************************************************************* void Guild::incPkillsWon(long pk) { pkillsWon += pk; } //********************************************************************* // guildhallLocations //********************************************************************* // Calling function must provide fmt with 2 %s's. Example: // "Your guildhall is located at %s in the city of %s.\n" void Guild::guildhallLocations(const Player* player, const char* fmt) const { std::list<Property*>::const_iterator it; for(it = gConfig->properties.begin() ; it != gConfig->properties.end() ; it++) { if((*it)->getType() == PROP_GUILDHALL && (*it)->getGuild() == num) { player->print(fmt, (*it)->getLocation().c_str(), gConfig->catRefName((*it)->getArea()).c_str()); } } } //********************************************************************* // GuildCreation //********************************************************************* GuildCreation::GuildCreation() { name = ""; leader = leaderIp = ""; status = numSupporters = 0; } // Prototypes void printGuildSyntax(Player* player) { player->printColor("Syntax: guild ^e<^xlist^e>\n"); player->printColor(" ^e<^xfound^e>^x ^e<^cguild name^e>\n"); if(gConfig->getWebserver() != "") { player->printColor(" ^e<^xforum^e>^x :: set your account to guildmaster on the forum\n"); player->printColor(" -create :: create a guild and private board on the website\n"); } player->printColor(" ^e<^xcancel^e>\n"); player->printColor(" ^e<^xsupport^e>^x ^e<^cguild name^e>\n"); player->printColor(" ^e<^xinvite^e>^x ^e<^cplayer name^e>\n"); player->printColor(" ^e<^xremove^e>^x ^e<^cplayer name^e>\n"); player->printColor(" ^e<^xabdicate^e>^x ^e<^cplayer name^e>\n"); player->printColor(" ^e<^xaccept^e>\n"); player->printColor(" ^e<^xreject^e>\n"); player->printColor(" ^e<^xpromote^e>^x ^e<^cplayer name^e>^x ^e[^crank^e]\n"); player->printColor(" ^e<^xdemote^e>^x ^e<^cplayer name^e>^x ^e[^crank^e]\n"); player->printColor(" ^e<^xmembers^e>\n"); player->printColor(" ^e<^xhall^e>\n"); } //" <disband>\n"; // Guild Ranks // Non Officer Officer // 4, 5, 6, 7, 8, 9 Invite flags // 12, 13, 14, 17, 18, 19 Actual status const int GUILD_NONE = 0, GUILD_INVITED = 1, GUILD_INVITED_OFFICER = 5, GUILD_INVITED_BANKER = 6, GUILD_PEON = 11, GUILD_OFFICER = 15, GUILD_BANKER = 16, GUILD_MASTER = 20; // What happened -- Used in adjusting guild level const int GUILD_JOIN = 0, GUILD_REMOVE = 1, GUILD_LEVEL = 2, GUILD_DIE = 3; // Guild Creation Status variables const int GUILD_NEEDS_SUPPORT = 1, GUILD_AWAITING_APPROVAL = 2; // level requirements const int GUILD_FOUND_LEVEL = 13, GUILD_SUPPORT_LEVEL = 10, GUILD_JOIN_LEVEL = 7; //******************************************************************** // isGuildKill //******************************************************************** bool Player::isGuildKill(const Player *killer) const { // Dueling guild members don't count if(induel(killer, this)) return(false); // Staff members don't count if(killer->isStaff() || isStaff()) return(false); // Validate the guild: are they both in one? if(!killer->getGuild() || !getGuild()) return(false); // They've reached the lowest level? (ie, skip invited but unconfirmed) if(killer->getGuildRank() < GUILD_PEON || getGuildRank() < GUILD_PEON) return(false); // If they've de-leveled past the join level, they don't count for guild pkilling if(killer->getLevel() < GUILD_JOIN_LEVEL || getLevel() < GUILD_JOIN_LEVEL) return(false); return(true); } //********************************************************************* // cmdGuild //********************************************************************* // Player command used to do various guild functions int cmdGuild(Player* player, cmd* cmnd) { //Creature* target = NULL; int len=0; //int len,i=0,j=0; //guildCreationPtr newGuildCreation; if(cmnd->num < 2) { printGuildSyntax(player); return(0); } len = strlen(cmnd->str[1]); // Found/Create a new guild if( !strncmp(cmnd->str[1], "found", len) || !strncmp(cmnd->str[1], "create", len) ) { Guild::create(player, cmnd); } // Cancel the creation of a guild else if(!strncmp(cmnd->str[1], "cancel", len)) Guild::cancel(player, cmnd); // Create a forum for the guild else if(!strncmp(cmnd->str[1], "forum", len)) Guild::forum(player, cmnd); // Support the creation of a guild else if(!strncmp(cmnd->str[1], "support", len)) Guild::support(player, cmnd); // Invite someone into your guild else if(!strncmp(cmnd->str[1], "invite", len)) Guild::invite(player, cmnd); // Transfer leadership of the guild to someone else else if(!strncmp(cmnd->str[1], "abdicate", len)) Guild::abdicate(player, cmnd); // Remove someone from your guild else if(!strncmp(cmnd->str[1], "remove", len) || !strncmp(cmnd->str[1], "dismiss", len) ) { Guild::remove(player, cmnd); } // Accept an offer to join a guild else if(!strncmp(cmnd->str[1], "join", len) || !strncmp(cmnd->str[1], "accept", len) ) { Guild::join(player, cmnd); } // Reject someone's offer to join a guild else if(!strncmp(cmnd->str[1], "reject", len)) Guild::reject(player, cmnd); else if(!strcmp(cmnd->str[1], "disband")) Guild::disband(player, cmnd); // Promote someone else if(!strncmp(cmnd->str[1], "promote", len)) Guild::promote(player, cmnd); // Demote someone else if(!strncmp(cmnd->str[1], "demote", len)) Guild::demote(player, cmnd); // List current guilds else if(!strncmp(cmnd->str[1], "list", len)) Guild::list(player, cmnd); else if(!strncmp(cmnd->str[1], "members", len)) Guild::viewMembers(player, cmnd); // Guild Bank Stuff else if(!strncmp(cmnd->str[1], "balance", len)) Bank::balance(player, true); else if(!strncmp(cmnd->str[1], "deposit", len)) Bank::deposit(player, cmnd, true); else if(!strncmp(cmnd->str[1], "withdraw", len)) Bank::withdraw(player, cmnd, true); else if(!strncmp(cmnd->str[1], "transfer", len)) Bank::transfer(player, cmnd, true); else if(!strncmp(cmnd->str[1], "statement", len)) Bank::statement(player, true); else if(!strncmp(cmnd->str[1], "deletestatement", len)) Bank::deleteStatement(player, true); else if(!strncmp(cmnd->str[1], "hall", len)) Property::manage(player, cmnd, PROP_GUILDHALL, 2); else printGuildSyntax(player); return(0); } //********************************************************************* // create //********************************************************************* void Guild::create(Player* player, cmd* cmnd) { int len,i=0,j=0, a=0; GuildCreation* newGuildCreation; char guildName[41]; if(player->getLevel() < GUILD_FOUND_LEVEL && !player->isDm()) { player->print("You must be level %d to found a guild.\n", GUILD_FOUND_LEVEL); return; } if(player->getGuild() > 0) { player->print("You may not create a guild because you already belong to one.\n"); return; } // TODO: Check the awaiting approval list to see if they are supporting, or have a guild // on the approval list if(player->flagIsSet(P_CREATING_GUILD)) { player->print("You may only create one guild at a time.\n"); return; } if(cmnd->num < 3) { printGuildSyntax(player); return; } len = cmnd->fullstr.length(); // Kill the first 2 spaces while(i < len) { if(cmnd->fullstr[i] == ' ' && cmnd->fullstr[i+1] != ' ') j++; if(j==2) break; i++; } len = strlen(&cmnd->fullstr[i+1]); if(!len) { player->print("What would you like to call your guild?\n"); return; } if(len > 40) { player->print("The guild name is too long.\n"); return; } for(a=0;a<len;a++) { if(!isalpha(cmnd->fullstr[i+1+a]) && cmnd->fullstr[i+1+a] != ' ') { player->print("Name error: Characters other than letters are illegal.\n"); player->print("Please attempt creation with a different name.\n"); return; } } strcpy(guildName, &cmnd->fullstr[i+1]); if(gConfig->guildExists(guildName)) { player->print("A guild with that name already exists or is being considered for creation.\nPlease choose a different guild name.\n"); return; } // newGuild = gConfig->numGuilds + 1; // if(newGuild >= gConfig->maxGuilds) // expandGuildArray(); newGuildCreation = new GuildCreation; newGuildCreation->name = guildName; newGuildCreation->leader = player->getName(); newGuildCreation->leaderIp = player->getSock()->getIp(); newGuildCreation->status = GUILD_NEEDS_SUPPORT; newGuildCreation->numSupporters = 0; gConfig->addGuildCreation(newGuildCreation); player->setFlag(P_CREATING_GUILD); player->printColor("%sYou attempting to create a guild with the name of '%s'.\n", player->customColorize("*CC:GUILD*").c_str(), guildName); player->print("Go find %d people to support your guild now.\n", SUPPORT_REQUIRED); broadcast(isCt, "^y%s is attempting to create the guild '%s'.", player->getCName(), guildName); gConfig->saveGuilds(); } //********************************************************************* // cancel //********************************************************************* void Guild::cancel(Player* player, cmd* cmnd) { if(!player->flagIsSet(P_CREATING_GUILD)) { player->print("You aren't currently creating any guilds!\n"); return; } player->clearFlag(P_CREATING_GUILD); bstring guildName = gConfig->removeGuildCreation(player->getName()); if(guildName != "") { player->print("You remove your bid to create '%s'.\n", guildName.c_str()); return; } player->print("You aren't creating any guilds!\n"); } //********************************************************************* // forum //********************************************************************* // calls the webserver - no work is done here (besides parsing) void Guild::forum(Player* player, cmd* cmnd) { if(!player->getGuild() || player->getGuildRank() != GUILD_MASTER) { player->print("You are not a guildmaster.\n"); return; } Guild* guild = gConfig->getGuild(player->getGuild()); if(!guild || strstr(guild->name.c_str(), "&")) { player->print("Invalid guild!\n"); return; } if(gConfig->getWebserver() == "") { player->print("The mud currently does not have a webserver configured.\n"); return; } if(player->getForum() == "") { player->print("Your player must be associated with a forum account to update or create a guild forum.\n"); return; } bstring action = cmnd->str[2]; std::ostringstream url; url << "mud.php?mud_id=" << guild->getNum() << "&char=" << player->getName() << "&type="; if(action == "-create") { player->printColor("Attempting to create guild forum with you as guildmaster.\n"); url << "guildCreate&guildName=" << guild->name; } else { player->printColor("Attempting to update guild forum with you as guildmaster.\n"); url << "guildAbdicate"; } callWebserver(url.str()); } //********************************************************************* // support //********************************************************************* void Guild::support(Player* player, cmd* cmnd) { GuildCreation *toSupport=0; char guildName[41]; int len=0, i=0, j=0; if(player->getLevel() < GUILD_SUPPORT_LEVEL && !player->isDm()) { player->print("You must be level %d to support a guild!\n", GUILD_SUPPORT_LEVEL); return; } if(player->getGuild() > 0) { player->print("You may not support a guild because you already belong to one.\n"); return; } if(player->flagIsSet(P_CREATING_GUILD)) { player->print("You may only support one guild at a time.\n"); return; } if(cmnd->num < 3) { printGuildSyntax(player); return; } len = cmnd->fullstr.length(); // Kill the first 2 spaces while(i < len) { if(cmnd->fullstr[i] == ' ' && cmnd->fullstr[i+1] != ' ') j++; if(j==2) break; i++; } len = strlen(&cmnd->fullstr[i+1]); if(!len) { player->print("Which guild would you like to support?\n"); return; } if(len>40) cmnd->fullstr[40] = '\0'; strcpy(guildName, &cmnd->fullstr[i+1]); toSupport = gConfig->findGuildCreation(guildName); if(toSupport == NULL) { player->print("'%s' is not currently up for creation.\n", guildName); return; } if(toSupport->status != GUILD_NEEDS_SUPPORT) { player->print("'%s' is not currently in need of support.\n", guildName); return; } if(!player->flagIsSet(P_PTESTER)) { // check the address bool sameIp = (player->getSock()->getIp() == toSupport->leaderIp); if(!sameIp) { std::map<bstring, bstring>::iterator sIt; for(sIt = toSupport->supporters.begin() ; sIt != toSupport->supporters.end() ; sIt++) { if((*sIt).second == player->getSock()->getIp()) { sameIp = true; break; } } } if(sameIp) { player->print("Someone from your IP address is already supporting this guild.\n"); player->print("Remember, do not use alternate characters to support a guild.\n"); return; } } player->setFlag(P_CREATING_GUILD); player->print("You now supporting the creation of the guild '%s'.\n", guildName); broadcast(isCt, "^y%s is supporting the guild '%s'.", player->getCName(), guildName); toSupport->addSupporter(player); if(toSupport->numSupporters >= SUPPORT_REQUIRED) { Player* leader=0; toSupport->status = GUILD_AWAITING_APPROVAL; // We now have enough players to seek staff approval player->print("There are now enough people supporting the guild, it has been submitted for staff approval.\n"); leader = gServer->findPlayer(toSupport->leader.c_str()); if(leader) leader->printColor("%sThere are now enough people supporting your guild, it has been submitted for staff approval.\n", leader->customColorize("*CC:GUILD*").c_str()); broadcast(isCt, "^yThe guild '%s' is in need of staff approval.", guildName); } gConfig->saveGuilds(); } //********************************************************************* // invite //********************************************************************* void Guild::invite(Player* player, cmd* cmnd) { Player *target=0; if(!player->getGuild() || player->getGuildRank() < GUILD_OFFICER) { player->print("You are not an officer in a guild.\n"); return; } if(cmnd->num < 3) { player->print("Invite who into your guild?\n"); return; } lowercize(cmnd->str[2], 1); target = gServer->findPlayer(cmnd->str[2]); if(!target || !player->canSee(target)) { player->print("%s is not on.\n", cmnd->str[2]); return; } if(Move::tooFarAway(player, target, "invite into your guild")) return; if(target->getLevel() < GUILD_JOIN_LEVEL) { player->print("%s does not meet the minimum required level of %d to join a guild!\n", target->getCName(), GUILD_JOIN_LEVEL); return; } if(target->getGuildRank() >= GUILD_INVITED && target->getGuildRank() < GUILD_PEON) { player->print("%s is currently considering joining a guild already.\n", target->getCName()); return; } if(target->getGuild()) { player->print("%s is already in a guild.\n", target->getCName()); return; } if(target->isStaff()) { player->print("You cannot invite staff members to join a guild.\n"); return; } // Set this initially, change it if needed target->setGuildRank(GUILD_INVITED); target->setGuild(player->getGuild()); if(player->getGuildRank() == GUILD_MASTER) { if(!strncmp(cmnd->str[3], "officer", strlen(cmnd->str[3])) && cmnd->num == 4) { player->print("You invite %s to join your guild as an officer.\n", target->getCName()); target->print("You have been invited to join '%s' as an officer by %s.\n", getGuildName(player->getGuild()), player->getCName()); target->setGuildRank(GUILD_INVITED_OFFICER); } else if(!strncmp(cmnd->str[3], "banker", strlen(cmnd->str[3])) && cmnd->num == 4) { player->print("You invite %s to join your guild as a banker.\n", target->getCName()); target->print("You have been invited to join '%s' as a banker by %s.\n", getGuildName(player->getGuild()), player->getCName()); target->setGuildRank(GUILD_INVITED_BANKER); } else { player->print("You invite %s to join your guild as a normal member.\n", target->getCName()); target->print("You have been invited to join '%s' by %s.\n", getGuildName(player->getGuild()), player->getCName()); target->setGuildRank(GUILD_INVITED); } } else { player->print("You invite %s to join your guild as a normal member.\n", target->getCName()); target->print("You have been invited to join '%s' by %s.\n", getGuildName(player->getGuild()), player->getCName()); target->setGuildRank(GUILD_INVITED); } target->printColor("To join type ^yguild accept^x.\n"); } //********************************************************************* // shopStaysWithGuild //********************************************************************* bool shopStaysWithGuild(const UniqueRoom* shop) { return(!shop->exits.empty() && shop->exits.front()->target.room.isArea("guild")); } //********************************************************************* // remove //********************************************************************* void shopRemoveGuild(Property *p, Player* player, UniqueRoom* shop, UniqueRoom* storage); void Guild::remove(Player* player, cmd* cmnd) { Player *target=0; Property* p=0; int guildId = player->getGuild(); if((!player->getGuild() || player->getGuildRank() < GUILD_OFFICER) && cmnd->num >= 3) { player->print("You are not an officer. You can't do that.\n"); return; } if(!player->getGuild()) { player->print("You aren't in a guild!\n"); return; } if(cmnd->num < 3) { // Remove yourself if(player->getGuildRank() != GUILD_MASTER) { if(!canRemovePlyFromGuild(player)) { player->print("Guilds cannot drop below 3 players, the guild must be disbanded.\n"); return; } updateGuild(player, GUILD_REMOVE); player->print("You remove yourself from your guild (%s).\n", getGuildName(player->getGuild())); player->setGuild(0); broadcastGuild(guildId, 1, "%s has removed %sself from your guild.", player->getCName(), player->himHer()); player->setGuildRank(GUILD_NONE); // Kick them out if they don't belong p = gConfig->getProperty(player->currentLocation.room); if(p && p->getGuild() == guildId) p->expelToExit(player, false); } else { player->print("As a leader of the guild, you may not leave it. Transfer ownership to someone else first or Disband.\n"); } return; } lowercize(cmnd->str[2], 1); target = gServer->findPlayer(cmnd->str[2]); bool online = true; if(!target) { online = false; if(!loadPlayer(cmnd->str[2], &target)) { player->print("That player does not exist.\n"); return; } } if(target->getGuild() != guildId) { player->print("%s is not in your guild!\n", target->getCName()); return; } if(target->getGuildRank() >= player->getGuildRank()) { player->print("You may only remove members of lower rank than you.\n"); return; } if(target->getGuildRank() < GUILD_PEON) { player->print("%s is not in your guild!\n", target->getCName()); return; } if(!canRemovePlyFromGuild(target)) { player->print("Guilds cannot drop below 3 players; the guild must be disbanded.\n"); return; } updateGuild(target, GUILD_REMOVE); target->setGuild(0); target->setGuildRank(GUILD_NONE); target->print("You have been removed from your guild by %s.\n", player->getCName()); player->print("You remove %s from your guild.\n", target->getCName()); broadcastGuild(guildId, 1, "%s has been removed from your guild by %s.", target->getCName(), player->getCName()); if(target->getForum() != "") { player->printColor("%s is associated with forum account ^C%s^x.\n", target->getCName(), target->getForum().c_str()); player->printColor("You may wish to consider removing this account from the guild forum.\n"); } std::list<Property*>::iterator pt; for(pt = gConfig->properties.begin(); pt != gConfig->properties.end(); pt++) { if((*pt)->isOwner(target->getName()) && (*pt)->getGuild() == guildId) { if((*pt)->getType() == PROP_SHOP) { shopRemoveGuild(*pt, target, 0, 0); } else { bstring output = (*pt)->getName(); broadcast(isCt, "^r%s was removed from guild %d.\nProperty \"%s\" belongs to the guild, but is not a shop.", target, guildId, output.c_str()); } } } // Kick them out if they don't belong p = gConfig->getProperty(target->currentLocation.room); if(p && p->getGuild() == guildId) p->expelToExit(target, !online); gConfig->saveProperties(); if(!online) free_crt(target); } //********************************************************************* // promote //********************************************************************* void Guild::promote(Player* player, cmd* cmnd) { Player *target=0; int newRank=0; char rank[80]; if(!player->getGuild() || player->getGuildRank() != GUILD_MASTER) { player->print("You are not the guild leader.\n"); return; } if(cmnd->num < 3) { printGuildSyntax(player); return; } lowercize(cmnd->str[2], 1); target = gServer->findPlayer(cmnd->str[2]); if(!target || !player->canSee(target)) { player->print("%s is not on.\n", cmnd->str[2]); return; } if(target->getGuild() != player->getGuild() || target->getGuildRank() < GUILD_PEON) { player->print("%s is not in your guild!\n", target->getCName()); return; } if(cmnd->num == 4) { if(!strncmp(cmnd->str[3], "banker", strlen(cmnd->str[3])) && cmnd->num == 4) { strcpy(rank, "banker"); newRank = GUILD_BANKER; } else { // if(!strncmp(cmnd->str[3], "officer", strlen(cmnd->str[3])) && cmnd->num == 4) { strcpy(rank, "officer"); newRank = GUILD_OFFICER; } } else { if(target->getGuildRank() == GUILD_PEON) { newRank = GUILD_OFFICER; strcpy(rank, "officer"); } else if(target->getGuildRank() == GUILD_OFFICER) { strcpy(rank, "banker"); newRank = GUILD_BANKER; } else { strcpy(rank, "officer"); newRank = GUILD_OFFICER; } } if(newRank <= target->getGuildRank()) { player->print("You cannot promote someone to an equal or lesser rank.\n"); return; } target->setGuildRank(newRank); player->print("You promote %s to %s.\n", target, rank); target->print("You have been promoted to %s by %s.\n", rank, player->getCName()); broadcastGuild(player->getGuild(), 1, "%s has been promoted to the rank of %s by %s.", target, rank, player->getCName()); } //********************************************************************* // demote //********************************************************************* void Guild::demote(Player* player, cmd* cmnd) { Player *target=0; int newRank=0; char rank[80]; if(!player->getGuild() || player->getGuildRank() != GUILD_MASTER) { player->print("You are not the guild leader.\n"); return; } if(cmnd->num < 3) { printGuildSyntax(player); return; } lowercize(cmnd->str[2], 1); target = gServer->findPlayer(cmnd->str[2]); if(!target || !player->canSee(target)) { player->print("%s is not on.\n", cmnd->str[2]); return; } if(target->getGuild() != player->getGuild() || target->getGuildRank() < GUILD_PEON) { player->print("%s is not in your guild!\n", target->getCName()); return; } if(cmnd->num == 4) { if(!strncmp(cmnd->str[3], "officer", strlen(cmnd->str[3])) && cmnd->num == 4) { strcpy(rank, "officer"); newRank = GUILD_OFFICER; } else { // if(!strncmp(cmnd->str[3], "member", strlen(cmnd->str[3])) && cmnd->num == 4) { strcpy(rank, "member"); newRank = GUILD_PEON; } } else { if(target->getGuildRank() == GUILD_BANKER) { newRank = GUILD_OFFICER; strcpy(rank, "officer"); } else { //if(target->getGuildRank() == GUILD_OFFICER) { strcpy(rank, "member"); newRank = GUILD_PEON; } } if(newRank >= target->getGuildRank()) { player->print("You cannot demote someone to an equal or higher rank.\n"); return; } target->setGuildRank(newRank); player->print("You demote %s to %s.\n", target, rank); target->print("You have been demoted to %s rank by %s.\n", rank, player->getCName()); broadcastGuild(player->getGuild(), 1, "%s has been demoted to %s rank by %s.", target, rank, player->getCName()); } //********************************************************************* // abdicate //********************************************************************* void Guild::abdicate(Player* player, Player* target, bool online) { int guildId = player->getGuild(); if(!guildId || player->getGuildRank() != GUILD_MASTER) { player->print("You are not the leader of the guild.\n"); return; } if(target->getGuild() != player->getGuild() || target->getGuildRank() < GUILD_PEON) { player->print("%s is not in your guild!\n", target->getCName()); return; } target->setGuildRank(GUILD_MASTER); player->setGuildRank(GUILD_BANKER); target->print("You have been promoted to guild leader by %s.\n", player->getCName()); target->print("Use the \"guild\" command to set your forum account as guildmaster of the guild board.\n"); player->print("You promote %s to guild leader.\n", target->getCName()); std::list<Property*>::iterator pt; bstring pName; for(pt = gConfig->properties.begin(); pt != gConfig->properties.end(); pt++) { if( (*pt)->isOwner(player->getName()) && (*pt)->getGuild() == guildId ) { pName = gConfig->catRefName((*pt)->getArea()); if((*pt)->getType() == PROP_GUILDHALL) { // guildhalls are easy - ownership transfers to the new guildmaster (*pt)->setOwner(target->getName()); player->print("%s assumes ownership of the guildhall in %s.\n", target->getCName(), pName.c_str()); target->print("You assume ownership of the guildhall in %s.\n", pName.c_str()); } else if((*pt)->getType() == PROP_SHOP) { // shops located inside the guild transfer ownership to the new guildmaster CatRef cr = (*pt)->ranges.front().low; UniqueRoom* room=0; bool transferOwnership = false; if(loadRoom(cr, &room)) { // Look for the first exit linking to a guild if(shopStaysWithGuild(room)) transferOwnership = true; } if(transferOwnership) { (*pt)->setOwner(target->getName()); player->print("%s assumes ownership of the guild shop in %s.\n", target->getCName(), pName.c_str()); target->print("You assume ownership of the guild shop in %s.\n", pName.c_str()); } else { player->print("You retain ownership of the guild shop in %s.\n", pName.c_str()); } } } } broadcastGuild(player->getGuild(), 1, "%s has been promoted to guild leader by %s.", target->getCName(), player->getCName()); Guild* guild = gConfig->getGuild(guildId); guild->setLeader(target->getName()); gConfig->saveGuilds(); gConfig->saveProperties(); player->save(); target->save(online); std::ostringstream url; url << "mud.php?type=guildAbdicate&mud_id=" << guild->getNum() << "&char=" << target->getCName(); callWebserver(url.str()); } void Guild::abdicate(Player* player, cmd* cmnd) { Player *target=0; int guildId = player->getGuild(); if((!guildId || player->getGuildRank() != GUILD_MASTER) && cmnd->num >= 3) { player->print("You are not the leader of the guild.\n"); return; } if(cmnd->num < 3) { player->print("Abdicate to whom?\n"); return; } lowercize(cmnd->str[2], 1); target = gServer->findPlayer(cmnd->str[2]); if(!target || !player->canSee(target)) { player->print("%s is not on.\n", cmnd->str[2]); return; } Guild::abdicate(player, target, true); } //********************************************************************* // join //********************************************************************* void Guild::join(Player* player, cmd *cmnd) { bstring name = ""; if(!player->getGuildRank()) { player->print("You have not been invited to join any guilds!\n"); return; } if(player->getGuildRank() >= GUILD_PEON) { player->print("You are already in a guild.\n"); return; } if(player->getLevel() < GUILD_JOIN_LEVEL) { player->print("You must be at least level %d to join a guild.\n", GUILD_JOIN_LEVEL); return; } if(player->getGuildRank() == GUILD_INVITED_OFFICER) { broadcastGuild(player->getGuild(), 1, "%s has joined your guild as an officer.", player->getCName()); player->setGuildRank(GUILD_OFFICER); } else if(player->getGuildRank() == GUILD_INVITED_BANKER) { player->setGuildRank(GUILD_BANKER); broadcastGuild(player->getGuild(), 1, "%s has joined your guild as a banker.", player->getCName()); } else { // Default to normal member broadcastGuild(player->getGuild(), 1, "%s has joined your guild as a normal member.", player->getCName()); player->setGuildRank(GUILD_PEON); } updateGuild(player, GUILD_JOIN); name = getGuildName(player->getGuild()); player->print("You have joined %s.\n", name.c_str()); if(player->getForum() != "") callWebserver((bstring)"mud.php?type=autoguild&guild=" + name + "&user=" + player->getForum() + "&char=" + player->getCName()); } //********************************************************************* // reject //********************************************************************* void Guild::reject(Player* player, cmd* cmnd) { if(!player->getGuild() || player->getGuildRank() >= GUILD_PEON) { player->print("You have no offer to reject.\n"); return; } player->print("You reject the offer to join %s.\n", getGuildName(player->getGuild())); player->setGuild(0); player->setGuildRank(0); } //********************************************************************* // disband //********************************************************************* void Guild::disband(Player* player, cmd* cmnd) { if(!player->getGuild() || player->getGuildRank() < GUILD_MASTER) { player->print("You are not the guildmaster.\n"); return; } int guildId = player->getGuild(); Guild* guild = gConfig->getGuild(guildId); if(!guild->bank.isZero()) { player->print("You quickly swipe the guild's funds of %s!\n", guild->bank.str().c_str()); player->coins.add(guild->bank); } broadcastGuild(guildId, 1, "Your guild has been disbanded by %s.", player->getCName()); Player* ply; for(std::pair<bstring, Player*> p : gServer->players) { ply = p.second; if(!ply->getGuild() || ply->getGuild() != guildId) continue; ply->setGuild(0); ply->setGuildRank(0); } gConfig->deleteGuild(guildId); } //********************************************************************* // cmdGuildHall //********************************************************************* int cmdGuildHall(Player* player, cmd* cmnd) { Property::manage(player, cmnd, PROP_GUILDHALL, 1); return(0); } //********************************************************************* // doGuildSend //********************************************************************* // aka guildchat void doGuildSend(const Guild *guild, Player* player, bstring txt) { if(!guild) { player->print("Invalid guild!\n"); return; } broadcastGuild(guild->getNum(), 1, "### %s sent, \"%s\".", player->getCName(), escapeColor(txt).c_str()); txt = escapeColor(txt); broadcast(watchingEaves, "^E--- [%s] %s guild sent, \"%s\".", guild->getName().c_str(), player->getCName(), txt.c_str()); } //********************************************************************* // cmdGuildSend //********************************************************************* int cmdGuildSend(Player* player, cmd* cmnd) { bstring text = ""; player->clearFlag(P_AFK); if(!player->ableToDoCommand()) return(0); if(player->inJail()) { player->print("People in jail do not have that privilage.\n"); return(0); } if(!player->getGuild() || player->getGuildRank() < GUILD_PEON) { player->print("You do not belong to a guild.\n"); return(0); } text = getFullstrText(cmnd->fullstr, 1); if(text == "") { player->print("Send what?\n"); return(0); } if(!player->canSpeak()) { player->printColor("^yYou are unable to do that right now.\n"); return(0); } doGuildSend(gConfig->getGuild(player->getGuild()), player, text); return(0); } //********************************************************************* // dmApproveGuild //********************************************************************* int dmApproveGuild(Player* player, cmd* cmnd) { char guildName[41]; GuildCreation * toApprove; int len,i=0,j=0; if(cmnd->num < 2) { player->print("Approve what guild?\n"); return(0); } len = cmnd->fullstr.length(); // Kill the first space while(i < len) { if(cmnd->fullstr[i] == ' ' && cmnd->fullstr[i+1] != ' ') j++; if(j==1) break; i++; } len = strlen(&cmnd->fullstr[i+1]); if(!len) { player->print("Approve what guild?\n"); return(0); } if(len>40) cmnd->fullstr[40] = '\0'; strcpy(guildName, &cmnd->fullstr[i+1]); toApprove = gConfig->findGuildCreation(guildName); if(toApprove == NULL) { player->print("'%s' is not currently up for creation.\n", guildName); return(0); } if(toApprove->status == GUILD_NEEDS_SUPPORT) { player->print("'%s' still needs support.\n", guildName); return(0); } player->print("You approve the guild '%s'.\n", guildName); broadcast(isCt, "^y%s just approved the guild %s", player->getCName(), guildName); gConfig->creationToGuild(toApprove); // saved by above function //gConfig->saveGuilds(); return(0); } //********************************************************************* // dmRejectGuild //********************************************************************* int dmRejectGuild(Player* player, cmd* cmnd) { char guildName[41]; char *reason=0; GuildCreation * toReject; int len,i=0,j=0, iTmp=0, strLen; strLen = cmnd->fullstr.length(); // This kills all leading whitespace while(i<strLen && isspace(cmnd->fullstr[i])) i++; // This kills the command itself while(i<strLen && !isspace(cmnd->fullstr[i])) i++; // This kills all the white space before the guild while(i<strLen && isspace(cmnd->fullstr[i])) i++; len = strlen(&cmnd->fullstr[i]); if(!len) { player->print("Reject what guild?\n"); return(0); } // This finds out how long the guild is // Keep going untill we get to the end of the string or a - while(i+j < strLen && cmnd->fullstr[i+j] != '\0' && cmnd->fullstr[i+j] != '-') j++; j = MIN(j, 40); memcpy(guildName, &cmnd->fullstr[i], j); guildName[j] = '\0'; // Kill trailling whitespace len = strlen(guildName); if(!len) { player->print("Reject what guild?\n"); return(0); } while(isspace(guildName[len-1])) len--; guildName[len] = '\0'; player->print("Trying to reject '%s'\n", guildName); i = i+j; j=0; len = strlen(&cmnd->fullstr[i+1]); reason = strstr(&cmnd->fullstr[i], "-r "); if(reason) { // There is a reason string then iTmp = i; while(iTmp < strLen && &cmnd->fullstr[iTmp] != reason) iTmp++; reason += 3; while(isspace(*reason)) reason++; // Kill trailing whitespace len = strlen(reason); while(isspace(reason[len-1])) len--; reason[len] = '\0'; } if(iTmp) { // We have a reason, everything else stops at the beginging of the -r strLen = iTmp; cmnd->fullstr[iTmp] = '\0'; } if(reason != 0) { player->print("Reason '%s'\n", reason); } toReject = gConfig->findGuildCreation(guildName); if(toReject == NULL) { player->print("'%s' is not currently up for creation.\n", guildName); return(0); } player->print("You reject the guild '%s'.\n", guildName); broadcast(isCt, "^y%s just rejected the guild %s", player->getCName(), guildName); rejectGuild(toReject, reason); gConfig->saveGuilds(); return(0); } //********************************************************************* // showGuildsNeedingApproval //********************************************************************* void showGuildsNeedingApproval(Player* viewer) { GuildCreation *gcp; int num = 0; std::list<GuildCreation*>::iterator it; std::ostringstream oStr; for(it = gConfig->guildCreations.begin() ; it != gConfig->guildCreations.end() ; it++) { gcp = (*it); if(gcp->status != GUILD_AWAITING_APPROVAL) continue; num++; if(num == 1) { oStr << "\nGuilds needing approval:\n"; oStr << "--------------------------------------------------------------------------------\n"; } oStr << "^c" << num << ") " << gcp->name << " by " << gcp->leader << ".\n" << " " << gcp->numSupporters << " Supporter" << (gcp->numSupporters != 1 ? "s" : "") << ":"; std::map<bstring, bstring>::iterator sIt; for(sIt = gcp->supporters.begin() ; sIt != gcp->supporters.end() ; sIt++) oStr << " " << (*sIt).first; oStr << "\n"; } viewer->printColor("%s", oStr.str().c_str()); } //********************************************************************* // viewMembers //********************************************************************* void Guild::viewMembers(Player* player, cmd* cmnd) { if(cmnd->num < 3) { player->print("What guild were you looking for?\n\n"); Guild::list(player, cmnd); return; } Guild *guild = gConfig->getGuild(player, getFullstrText(cmnd->fullstr, 2)); if(!guild) { player->print("The guild you were looking for could not be found.\n"); return; } player->print("Guild: %s\nMembers: ", guild->name.c_str()); std::list<bstring>::iterator it; bstring toPrint; for(it = guild->members.begin() ; it != guild->members.end() ; it++ ) { toPrint += (*it); toPrint += ", "; } toPrint[toPrint.length() - 2] = '.'; player->printColor("^g%s^x\n", toPrint.c_str()); if(player->isCt() || guild->getNum() == player->getGuild()) guild->guildhallLocations(player, "Your guildhall is located at %s in %s.\n"); } //********************************************************************* // list //********************************************************************* void Guild::list(Player* player, cmd* cmnd) { int num = 1; GuildCreation * gcp; player->printColor("^b %-25s %-15s Info\n", "Guild", "Leader"); player->printColor("^b--------------------------------------------------------------------------------\n"); std::map<int, Guild*>::iterator it; Guild *guild; for(it = gConfig->guilds.begin() ; it != gConfig->guilds.end() ; it++) { guild = (*it).second; player->printColor("%2d> ^c%-25s ^g%-15s ^x%2d Member(s)", num++, guild->name.c_str(), guild->leader.c_str(), guild->numMembers); if(guild->pkillsIn) player->printColor("^r (Pk:%3d%%)", pkillPercent(guild->pkillsWon, guild->pkillsIn)); else player->printColor("^r (Pk: N/A)"); player->printColor("^y Avg Lvl: %2d\n", guild->averageLevel()); } std::list<GuildCreation*>::iterator gcIt; for(gcIt = gConfig->guildCreations.begin() ; gcIt != gConfig->guildCreations.end() ; gcIt++) { gcp = (*gcIt); if(gcp->status != GUILD_NEEDS_SUPPORT) continue; num ++; if(num == 1) { player->print("\nGuilds needing support\n"); player->print("--------------------------------------------------------------------------------\n"); } player->printColor("^c%d) %s by %s.\n", num, gcp->name.c_str(), gcp->leader.c_str()); player->print(" %d Supporter%s: ", gcp->numSupporters, gcp->numSupporters != 1 ? "s" : ""); std::map<bstring, bstring>::iterator sIt; for(sIt = gcp->supporters.begin() ; sIt != gcp->supporters.end() ; sIt++) { player->print("%s", (*sIt).first.c_str()); } player->print("\n"); } } //********************************************************************* // dmListGuilds //********************************************************************* // List currently created guilds, and guilds being opted for creation int dmListGuilds(Player* player, cmd* cmnd) { GuildCreation * gcp; int found = 0; //player->print("Max Guild Id: %d\n", gConfig->maxGuilds); player->print("Next Guild Id: %d\n\n", gConfig->nextGuildId); // gp = firstGuild; // while(gp) { std::map<int, Guild*>::iterator it; Guild *guild; for(it = gConfig->guilds.begin() ; it != gConfig->guilds.end() ; it++) { guild = (*it).second; player->printColor("^CGuild: "); player->printColor("^c%3d %-40s", guild->getNum(), guild->getName().c_str()); player->print("Leader: %s\n", guild->getLeader().c_str()); player->print(" NumMembers: %3d ", guild->getNumMembers()); player->print(" Avg Level: %3d ", guild->averageLevel()); player->print(" Total Levels %3d\n", guild->getLevel()); player->printColor(" Members: ^g"); std::list<bstring>::iterator mIt; bstring toPrint; for(mIt = guild->members.begin() ; mIt != guild->members.end() ; mIt++ ) { toPrint += (*mIt); toPrint += ", "; } toPrint[toPrint.length() - 2] = '.'; player->printColor("%s\n", toPrint.c_str()); player->print(" Pkills: %d/%d (%d%%) ", guild->getPkillsWon(), guild->getPkillsIn(), pkillPercent(guild->getPkillsWon(), guild->getPkillsIn())); player->print(" Points: %d\n", guild->getPoints()); player->print(" GuildBank: %s\n", guild->bank.str().c_str()); guild->guildhallLocations(player, " Guildhall: %s in %s\n"); } player->print("\nGuilds being supported by players for creation:\n"); std::list<GuildCreation*>::iterator gcIt; for(gcIt = gConfig->guildCreations.begin() ; gcIt != gConfig->guildCreations.end() ; gcIt++) { gcp = (*gcIt); found++; player->printColor("%s%d) %s by %s.\n", gcp->status == GUILD_NEEDS_SUPPORT ? "^c" : "^g", found, gcp->name.c_str(), gcp->leader.c_str()); player->print(" %d Supporter%s:", gcp->numSupporters, gcp->numSupporters != 1 ? "s" : ""); std::map<bstring, bstring>::iterator sIt; for(sIt = gcp->supporters.begin() ; sIt != gcp->supporters.end() ; sIt++) { player->print(" %s", (*sIt).first.c_str()); } player->print("\n"); } if(found == 0) player->printColor("^x None.\n"); return(0); } //********************************************************************* // guild membership functions //********************************************************************* bool Guild::addMember(bstring memberName) { if(memberName != "") { members.push_back(memberName); return(true); } return(false); } bool Guild::delMember(bstring memberName) { std::list<bstring>::iterator mIt; for(mIt = members.begin() ; mIt != members.end() ; mIt++) { if(memberName == (*mIt)) { members.erase(mIt); return(true); } } return(false); } bool Guild::isMember(bstring memberName) { std::list<bstring>::iterator mIt; for(mIt = members.begin() ; mIt != members.end() ; mIt++) { if(memberName == (*mIt)) return(true); } return(false); } void Guild::renameMember(bstring oldName, bstring newName) { std::list<bstring>::iterator mIt; if(leader == oldName) leader = newName; for(mIt = members.begin() ; mIt != members.end() ; mIt++) { if(oldName == (*mIt)) { (*mIt) = newName; break; } } } //********************************************************************* // addGuildCreation //********************************************************************* bool Config::addGuildCreation(GuildCreation* toAdd) { guildCreations.push_back(toAdd); return(true); } //********************************************************************* // supporter functions //********************************************************************* bool GuildCreation::addSupporter(Player* supporter) { if(supporter && supporters.find(supporter->getName()) == supporters.end()) { supporters[supporter->getName()] = supporter->getSock()->getIp(); numSupporters++; return(true); } return(false); } bool GuildCreation::removeSupporter(bstring supporterName) { if(supporters.find(supporterName) != supporters.end()) { supporters.erase(supporterName); numSupporters--; return(true); } return(false); } void GuildCreation::renameSupporter(bstring oldName, bstring newName) { if(leader == oldName) leader = newName; if(supporters.find(oldName) != supporters.end()) { supporters[newName] = supporters[oldName]; supporters.erase(oldName); } } void Config::guildCreationsRenameSupporter(bstring oldName, bstring newName) { std::list<GuildCreation*>::iterator gcIt; for(gcIt = guildCreations.begin(); gcIt != guildCreations.end(); gcIt++) { (*gcIt)->renameSupporter(oldName, newName); } } //********************************************************************* // findGuildCreation //********************************************************************* GuildCreation* Config::findGuildCreation(bstring creationName) { std::list<GuildCreation*>::iterator gcIt; GuildCreation* gcp; for(gcIt = guildCreations.begin(); gcIt != guildCreations.end(); gcIt++) { gcp = (*gcIt); if(gcp->name == creationName) return(gcp); } return(NULL); } //********************************************************************* // recalcLevel //********************************************************************* // this function is slow, so we don't want this to happen. void Guild::recalcLevel() { std::list<bstring>::iterator mIt; Player* member=0; bool online; broadcast(isCt, "\n^yError: Guild level for \"%s\" is being recalculated.\n", name.c_str()); level = 0; for(mIt = members.begin() ; mIt != members.end() ; mIt++) { online = false; member = gServer->findPlayer((*mIt).c_str()); if(!member) { if(!loadPlayer((*mIt).c_str(), &member)) continue; } else online = true; level += member->getLevel(); if(!online) free_crt(member); } gConfig->saveGuilds(); } //********************************************************************* // averageLevel //********************************************************************* int Guild::averageLevel() { int cLevel, cMembers; if(!level) recalcLevel(); cLevel = MAX(1, level); cMembers = MAX(1, numMembers); return(cLevel/cMembers); } //********************************************************************* // guildExists //********************************************************************* bool Config::guildExists(bstring guildName) { Guild* guild; guild = getGuild(guildName); if(guild) return(true); GuildCreation* gcp; gcp = findGuildCreation(guildName); if(gcp) return(true); return(false); } //********************************************************************* // getGuildName //********************************************************************* const char *getGuildName(int guildNum) { Guild* guild = gConfig->getGuild(guildNum); if(guild) return(guild->getName().c_str()); else return("Unknown Guild"); } //********************************************************************* // canRemovePlyFromGuild //********************************************************************* // True only if the guild will still have 3 or more players in it // otherwise it must be disbanded bool canRemovePlyFromGuild(Player* player) { const Guild* guild = gConfig->getGuild(player->getGuild()); if(!guild) return(false); if(guild->getNumMembers() > 3) return(true); return(false); } //********************************************************************* // updateGuild //********************************************************************* // Updates level statistics based upon the player, and 'what' is happening void updateGuild(Player* player, int what) { if(!player || !player->getGuild() || player->getGuildRank() < GUILD_PEON) return; std::ostringstream url; Guild *guild = gConfig->getGuild(player->getGuild()); if(!guild) return; if(what == GUILD_JOIN) { guild->incLevel(player->getLevel()); guild->incNumMembers(); guild->addMember(player->getName()); url << "mud.php?type=guildAddMember&mud_id=" << guild->getNum() << "&char=" << player->getCName(); } else if(what == GUILD_REMOVE) { bool online=false; guild->incNumMembers(-1); // There will be nobody is left in the guild! if(!guild->getNumMembers()) { // This invalidates the "guild" variable. It will also take care of saving // the guild and destroying guild property, so we can stop what we're doing. gConfig->deleteGuild(player->getGuild()); return; } guild->incLevel(player->getLevel() * -1); guild->delMember(player->getName()); // the guildmaster is leaving and did not abdicate their position! // find someone to take their place if(player->getGuildRank() == GUILD_MASTER) { Player* leader=0; do { guild->setLeader(guild->members.front()); leader = gServer->findPlayer(guild->getLeader().c_str()); if(leader) online = true; else { online = false; if(!loadPlayer(guild->getLeader().c_str(), &leader)) leader = 0; } if(leader) { Guild::abdicate(player, leader, online); if(!online) free_crt(leader); break; } // If we couldn't load a member, we've got data integrity problems guild->setLevel(0); guild->setLeader(""); guild->incNumMembers(-1); guild->members.pop_front(); } while(guild->members.size()); } // If we're removing, find the forum account. If any remaining members are associated // with this forum account, don't remove the forum account from the guild std::list<bstring>::const_iterator it; if(player->getForum() != "") { Player* target=0; bool removeForum = true; for(it = guild->members.begin(); it != guild->members.end(); it++) { target = gServer->findPlayer((*it).c_str()); if(target) online = true; else { online = false; if(!loadPlayer((*it).c_str(), &target)) target = 0; } if(target) { // if another member of this guild has the same forum account, don't remove the account if(player->getForum() == target->getForum()) removeForum = false; if(!online) free_crt(target); } if(!removeForum) break; } if(removeForum) url << "mud.php?type=guildRemoveMember&mud_id=" << guild->getNum() << "&char=" << player->getName(); } } else if(what == GUILD_LEVEL) { guild->incLevel(); } else if(what == GUILD_DIE) { guild->incLevel(-1); } gConfig->saveGuilds(); callWebserver(url.str()); } //********************************************************************* // creationToGuild //********************************************************************* void Config::creationToGuild(GuildCreation* toApprove) { std::map<bstring, bstring>::iterator sIt; Player *leader=0, *officer=0; int guildId=0; bool online=false; std::ostringstream url; url << "mud.php?type=guildCreate&char=" << toApprove->leader; // The suicide/*dust commands will take care of leaders / supporters // suiciding. These are extra checks in case anyone somehow sneaks past. // If the leader doesn't exist, we delete the guild. leader = gServer->findPlayer(toApprove->leader.c_str()); if(!leader) { if(!loadPlayer(toApprove->leader.c_str(), &leader)) { broadcast(isCt, "^yError creating guild '%s': Can't find the leader %s.\nThis guild is being erased.", toApprove->name.c_str(), toApprove->leader.c_str()); removeGuildCreation(toApprove->leader); return; } } else online = true; // If they suicide and remake a character with the same name, don't // let a level 1 character become the leader of the guild. if(!leader->flagIsSet(P_CREATING_GUILD)) { broadcast(isCt, "^yError creating guild '%s': %s is not flagged as creating a guild.\nThis guild is being erased.^", toApprove->name.c_str(), toApprove->leader.c_str()); removeGuildCreation(leader->getName()); if(!online) free_crt(leader); return; } // If we can't load the supporters for(sIt = toApprove->supporters.begin() ; sIt != toApprove->supporters.end() ; sIt++) { if(!gServer->findPlayer((*sIt).first.c_str())) { if(!loadPlayer((*sIt).first.c_str(), &officer)) { broadcast(isCt, "^yError loading guild supporter %s in guild %s.\nRemoving this person from the support list.", (*sIt).first.c_str(), toApprove->name.c_str()); toApprove->removeSupporter((*sIt).first); return; } free_crt(officer); } } // Everything has checked out - create the guild. guildId = nextGuildId; url << "&mud_id=" << guildId; nextGuildId++; numGuilds++; Guild* guild = new Guild; guild->setName(toApprove->name); url << "&guildName=" << toApprove->name; guild->setLeader(toApprove->leader); guild->setNum(guildId); guild->setPkillsWon(0); guild->setPkillsIn(0); guild->setPoints(0); guild->setLevel(leader->getLevel()); guild->setNumMembers(1); // Set the leader leader->setGuild(guildId); leader->setGuildRank(GUILD_MASTER); leader->clearFlag(P_CREATING_GUILD); leader->save(online); guild->addMember(leader->getName()); addGuild(guild); if(online) leader->print("You are now the leader of %s.\n", guild->getName().c_str()); for(sIt = toApprove->supporters.begin() ; sIt != toApprove->supporters.end() ; sIt++) { bool offOnline = false; url << "&supporter[]=" << (*sIt).first; officer = gServer->findPlayer((*sIt).first.c_str()); if(!officer) { if(!loadPlayer((*sIt).first.c_str(), &officer)) { broadcast(isCt, "^yError making %s an officer in %s.", (*sIt).first.c_str(), guild->getName().c_str()); continue; } } else offOnline = true; officer->setGuild(guildId); officer->setGuildRank(GUILD_OFFICER); officer->clearFlag(P_CREATING_GUILD); officer->save(offOnline); guild->incNumMembers(); guild->incLevel( officer->getLevel()); guild->addMember(officer->getName()); if(!offOnline) free_crt(officer); else officer->print("You are now an officer of %s.\n", guild->getName().c_str()); } removeGuildCreation(leader->getName()); if(!online) free_crt(leader); callWebserver(url.str()); } //********************************************************************* // rejectGuild //********************************************************************* void rejectGuild(GuildCreation * toReject, char *reason) { Player *leader=0, *officer=0; bstring leaderName = ""; int error = 0, ff; char Reason[250], file[80], outStr[1024], datestr[40]; long t; bool online=false; if(reason == 0) strcpy(Reason, "No reason given.\n"); else strcpy(Reason, reason); leader = gServer->findPlayer(toReject->leader.c_str()); if(!leader) { if(!loadPlayer(toReject->leader.c_str(), &leader)) { broadcast(isCt, "^yError rejecting guild '%s': Can't find the leader %s.", toReject->name.c_str(), toReject->leader.c_str()); error = 1; } } else online = true; if(error == 0) { leaderName = leader->getName(); leader->clearFlag(P_CREATING_GUILD); leader->save(online); if(!online) { // Send them a mudmail sprintf(file, "%s/%s.txt", Path::Post, leader->getCName()); ff = open(file, O_CREAT | O_APPEND | O_RDWR, ACC); if(ff > 0) { time(&t); strcpy(datestr, (char *) ctime(&t)); datestr[strlen(datestr) - 1] = 0; sprintf(outStr, "\n--..__..--..__..--..__..--..__..--..__..--..__..--..__..--..__..--..__..--\n\nMail from System (%s):\n\nYour guild '%s' has been rejected.\nReason: %s\n", datestr, toReject->name.c_str(), Reason); write(ff, outStr, strlen(outStr)); close(ff); leader->setFlag(P_UNREAD_MAIL); } free_crt(leader); } else leader->print("Your guild %s has been rejected.\nReason: %s\n", toReject->name.c_str(), Reason); } else error = 0; std::map<bstring, bstring>::iterator sIt; for(sIt = toReject->supporters.begin() ; sIt != toReject->supporters.end() ; sIt++) { online = false; officer = gServer->findPlayer((*sIt).first.c_str()); if(!officer) { if(!loadPlayer((*sIt).first.c_str(), &officer)) continue; } else online = true; officer->clearFlag(P_CREATING_GUILD); officer->save(online); if(!online) free_crt(officer); } gConfig->removeGuildCreation(leaderName); } //********************************************************************* // removeGuildCreation //********************************************************************* bstring Config::removeGuildCreation(bstring leaderName) { std::list<GuildCreation*>::iterator it; GuildCreation *gc; bstring toReturn = ""; for(it = gConfig->guildCreations.begin() ; it != gConfig->guildCreations.end() ; it++) { gc = (*it); if(gc && gc->leader == leaderName) { // We found the one we want to erase guildCreations.erase(it); toReturn = gc->name; delete gc; saveGuilds(); return(toReturn); } } return(""); } //********************************************************************* // getGuild //********************************************************************* Guild* Config::getGuild(const bstring& name) { Guild* guild=0; std::map<int, Guild*>::iterator it; for(it = guilds.begin(); it != guilds.end(); it++) { guild = (*it).second; if(guild->getName() == name) return(guild); } return (NULL); } Guild* Config::getGuild(int guildId) { if(guilds.find(guildId) != guilds.end()) return(guilds[guildId]); return(0); } // Will find a guild based on "txt". If a guild could not be found, it // will print a message to the player informing them of such. Guild* Config::getGuild(const Player* player, bstring txt) { Guild* guild=0; // 0 = not found, -1 = not unique int check = 0, len = txt.getLength(); txt = txt.toLower(); std::map<int, Guild*>::iterator it; for(it = gConfig->guilds.begin(); it != gConfig->guilds.end(); it++) { if((*it).second->getName().left(len).toLower() == txt) { if(!check) { check = 1; guild = (*it).second; } else check = -1; } } if(!check) { player->print("Guild not found.\n"); return(0); } else if(check == -1) { player->print("Guild name was not unique.\n"); return(0); } return(guild); } //********************************************************************* // deleteGuild //********************************************************************* // When calling this function, it is your responsibility to save the guild // leader (they get the guild's money). bool Config::deleteGuild(int guildId) { if(guilds.find(guildId) == guilds.end()) return(false); Guild* guild = guilds[guildId]; guilds.erase(guildId); Player *player = gServer->findPlayer(guild->getLeader().c_str()); bool online = true; if(!player) { online = false; if(!loadPlayer(guild->getLeader().c_str(), &player)) player = 0; } if(player) { // Destroy guild property std::list<Property*>::iterator it; for(it = gConfig->properties.begin() ; it != gConfig->properties.end() ;) { if(guildId != (*it)->getGuild()) { it++; continue; } if((*it)->getType() == PROP_SHOP) { // If the shop is located inside the guildhall, then destroy it. // If it isn't, then unlink it. CatRef cr = (*it)->ranges.front().low; UniqueRoom* shop=0; if(loadRoom(cr, &shop)) { // If the shop belongs to the guild, remove and continue if(!shop->exits.empty() && !shopStaysWithGuild(shop)) { shopRemoveGuild(*it, player, shop, 0); it++; continue; } } } (*it)->destroy(); it = properties.erase(it); } if(!online) free_crt(player); } std::ostringstream url; url << "mud.php?type=guildDisband&mud_id=" << guild->getNum(); callWebserver(url.str()); delete guild; saveGuilds(); return(true); } //********************************************************************* // addGuild //********************************************************************* bool Config::addGuild(Guild* toAdd) { if(!toAdd || !toAdd->getNum()) return(false); guilds[toAdd->getNum()] = toAdd; return(true); } // Clears the global list of guilds void Config::clearGuildList() { std::map<int, Guild*>::iterator it; Guild* guild; for(it = guilds.begin(); it != guilds.end(); it++) { guild = (*it).second; delete guild; //guilds.erase(it); } guilds.clear(); std::list<GuildCreation*>::iterator gcIt; GuildCreation* gcp; while(!guildCreations.empty()) { gcp = guildCreations.front(); delete gcp; guildCreations.pop_front(); } guildCreations.clear(); }