Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*######################-> [[GOLD BANKER ]] <-#########################
- **************************! DEV: ak47sigh !****************************
- #######################################################################*/
- // Rewritten by Rochet2
- #include "ScriptPCH.h"
- #include <cstring>
- #include "Chat.h"
- #include <cctype>
- // -- [[ Configs:
- const uint8 maxPlayerDeposits = 3; // absolute max 30
- const uint8 minDepositNameLenght = 3;
- const uint8 maxDepositNameLenght = 255;
- const uint32 createDepositCost = 100000; // default 10 gold per deposit (number in copper)
- const uint32 createDepositPlus = 50000; // increase the cost by X gold for each new repository
- // -- [[ DO NOT EDIT BELOW // --
- struct depInfo
- {
- uint32 gold;
- std::string name;
- std::string pass;
- };
- bool cmp_by_name(const depInfo &a, const depInfo &b)
- {
- return a.name < b.name; // c_str()?
- }
- class gold_banker : public CreatureScript
- {
- public:
- enum banker_actions
- {
- CREATE_DEPOSIT,
- LIST_DEPOSITS,
- EDIT_DEPOSIT,
- CLOSE_MENU,
- DEPOSIT_WITHDRAW,
- DEPOSIT_DEPOSIT,
- DEPOSIT_RENAME,
- DEPOSIT_DELETE,
- ADD_PASSWORD,
- MODIFY_PASSWORD,
- REMOVE_PASSWORD,
- };
- UNORDERED_MAP<uint32, std::list<depInfo> > deposits; // plrGUID, info
- depInfo* getDeposit(Player* player, uint8 key = 0)
- {
- std::list<depInfo>::iterator it = deposits[player->GetGUIDLow()].begin();
- if(key)
- std::advance(it, key);
- if(it == deposits[player->GetGUIDLow()].end())
- {
- sendError(player, "Internal error. Deposit no longer exists!");
- return NULL;
- }
- return &(*it);
- }
- void sendError(Player* player, const char* error)
- {
- player->GetSession()->SendNotification(error);
- ChatHandler(player->GetSession()).PSendSysMessage(error);
- }
- // A custom ModifyMoney that can handle up to uint32 values, which allows transactions the size of max money amount.
- bool modifyMoney(Player* player, uint32 amount, bool addMoney)
- {
- if (!amount)
- return true;
- if (!addMoney)
- player->SetMoney(player->GetMoney() > amount ? player->GetMoney() - amount : 0);
- else
- {
- if (player->GetMoney() < uint32(MAX_MONEY_AMOUNT - amount))
- player->SetMoney(player->GetMoney() + amount);
- else
- {
- player->SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL);
- return false;
- }
- }
- return true;
- }
- bool checkName(Player* player, std::string nameStr)
- {
- if(nameStr.length() < minDepositNameLenght)
- {
- sendError(player, ("You inserted too short name: "+nameStr).c_str());
- return false;
- }
- if(nameStr.length() > maxDepositNameLenght)
- {
- sendError(player, ("You inserted too long name: "+nameStr).c_str());
- return false;
- }
- std::list<depInfo> infos = deposits[player->GetGUIDLow()];
- std::list<depInfo>::iterator it = infos.begin();
- while(it != infos.end())
- {
- if(it->name == nameStr)
- {
- sendError(player, ("You already have a deposit with name "+nameStr).c_str());
- return false;
- }
- ++it;
- }
- return true;
- }
- gold_banker() : CreatureScript("Gold_Banker")
- {
- CharacterDatabase.DirectExecute("DELETE FROM gold_bank_data WHERE NOT EXISTS(SELECT 1 FROM characters WHERE characters.guid = gold_bank_data.plrGUID)");
- QueryResult result = CharacterDatabase.Query("SELECT `plrGUID`, `name`, `gold`, `password` FROM `gold_bank_data` ORDER BY `name` ASC");
- if(result)
- {
- Field* fields = result->Fetch();
- do
- {
- uint32 plrGUID = fields[0].GetUInt32();
- std::string name = fields[1].GetString();
- uint32 gold = fields[2].GetUInt32();
- std::string pass = fields[3].GetString();
- depInfo info = {gold, name, pass};
- deposits[plrGUID].push_back(info);
- }
- while (result->NextRow());
- }
- }
- bool OnGossipHello(Player * player, Creature * creature)
- {
- ListPlayerDeposits(player, creature);
- return true;
- }
- bool OnGossipSelect(Player * player, Creature * creature, uint32 action, uint32 deposit)
- {
- player->PlayerTalkClass->ClearMenus();
- switch(action)
- {
- case LIST_DEPOSITS:
- ListPlayerDeposits(player, creature);
- return true;
- case EDIT_DEPOSIT:
- EditDeposit(player, creature, deposit);
- return true;
- case CLOSE_MENU:
- player->CLOSE_GOSSIP_MENU();
- return true;
- }
- ListPlayerDeposits(player, creature);
- return true;
- }
- bool OnGossipSelectCode(Player* player, Creature* creature, uint32 action, uint32 deposit, const char* code)
- {
- player->PlayerTalkClass->ClearMenus();
- switch(action)
- {
- case CREATE_DEPOSIT:
- CreateDeposit(player, code);
- break;
- case DEPOSIT_WITHDRAW:
- WithdrawGold(player, deposit, (uint32)atol(code));
- break;
- case DEPOSIT_DEPOSIT:
- DepositGold(player, deposit, (uint32)atol(code));
- break;
- case DEPOSIT_RENAME:
- RenameDeposit(player, deposit, code);
- break;
- case DEPOSIT_DELETE:
- DisbandDeposit(player, deposit, code);
- break;
- case ADD_PASSWORD:
- AddPasswordToDeposit(player, deposit, code);
- break;
- case MODIFY_PASSWORD:
- if(AskOldDepositPass(player, deposit, code))
- {
- player->ADD_GOSSIP_ITEM(7, "|cff5C5C5C[Return]|r", LIST_DEPOSITS, 0);
- player->ADD_GOSSIP_ITEM_EXTENDED(4, "Add password", ADD_PASSWORD, deposit, "Insert new password", 0, true);
- player->SEND_GOSSIP_MENU(7777778, creature->GetGUID());
- return true;
- }
- break;
- case REMOVE_PASSWORD:
- if(AskOldDepositPass(player, deposit, code))
- RemoveDepositPass(player, deposit);
- break;
- case EDIT_DEPOSIT:
- EditDeposit(player, creature, deposit, code);
- return true;
- }
- ListPlayerDeposits(player, creature);
- return true;
- }
- // Creates a deposit
- void CreateDeposit(Player* player, const char* name)
- {
- std::list<depInfo> infos = deposits[player->GetGUIDLow()];
- if(infos.size() >= maxPlayerDeposits)
- {
- sendError(player, "You have too many deposits");
- return;
- }
- uint32 cost = createDepositCost + (infos.size() * createDepositPlus);
- if(player->GetMoney() < cost)
- {
- sendError(player, "You dont have enough money");
- return;
- }
- std::string nameStr(name);
- if(!checkName(player, nameStr))
- return;
- if(!modifyMoney(player, cost, false))
- return;
- depInfo info = {0, nameStr, ""};
- deposits[player->GetGUIDLow()].push_back(info);
- CharacterDatabase.PExecute("INSERT INTO `gold_bank_data` (`plrGUID`, `name`, `gold`, `password`) VALUES (%u, \"%s\", 0, NULL)", player->GetGUIDLow(), name);
- deposits[player->GetGUIDLow()].sort(cmp_by_name); // resort the deposits after adding new
- ChatHandler(player->GetSession()).PSendSysMessage("Deposit %s created and ready to use", name);
- }
- // Opens a list with the player's available deposits
- void ListPlayerDeposits(Player* player, WorldObject* obj)
- {
- std::list<depInfo> infos = deposits[player->GetGUIDLow()];
- std::list<depInfo>::iterator it = infos.begin();
- uint8 i = 0;
- while(it != infos.end() || i >= 30)
- {
- std::ostringstream ss;
- ss << "[Deposit: \"|cff0055FF";
- ss << it->name;
- ss << "|r\"]\n |cff00ff00available|r ";
- ss << it->gold;
- ss << "|cffFF0000 gold|r";
- player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_MONEY_BAG, ss.str().c_str(), EDIT_DEPOSIT, i++, it->pass.empty() ? "" : "Insert password", 0, !it->pass.empty());
- ++it;
- }
- if(i < maxPlayerDeposits)
- player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_2, "[+] Create a new Deposit", CREATE_DEPOSIT, 0, "Insert a new unique name\n\nWould you like to create a new deposit?", createDepositCost + (i * createDepositPlus), true);
- player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TALK, "Nevermid..", CLOSE_MENU, 0, "", 0, false);
- player->SEND_GOSSIP_MENU(7777778, obj->GetGUID());
- }
- // Asks for the deposit password
- bool CheckPassword(Player* player, Creature* creature, uint8 deposit)
- {
- depInfo* info = getDeposit(player, deposit);
- if(!info)
- {
- ListPlayerDeposits(player, creature);
- return true;
- }
- if(info->pass.empty())
- return false;
- player->ADD_GOSSIP_ITEM(7, "|cff5C5C5C[Return]|r", LIST_DEPOSITS, 0);
- player->ADD_GOSSIP_ITEM_EXTENDED(6, "Withdraw some gold", DEPOSIT_WITHDRAW, deposit, "Insert how much gold you would like to|cffFF0000 withdraw|r?", 0, true);
- player->SEND_GOSSIP_MENU(7777778, creature->GetGUID());
- return true;
- }
- // Opens a menu to edit the selected deposit
- void EditDeposit(Player* player, Creature* creature, uint8 deposit, const char* pass = NULL)
- {
- depInfo* info = getDeposit(player, deposit);
- if(!info)
- {
- ListPlayerDeposits(player, creature);
- return;
- }
- if(!info->pass.empty()) // has pass
- {
- if(!pass)
- {
- ListPlayerDeposits(player, creature);
- return;
- }
- // to String and trim it
- std::string passStr(pass);
- if(passStr != info->pass)
- {
- sendError(player, ("Wrong password for deposit "+info->name).c_str());
- ListPlayerDeposits(player, creature);
- return;
- }
- }
- player->ADD_GOSSIP_ITEM(7, "|cff5C5C5C[Return]|r", LIST_DEPOSITS, 0);
- player->ADD_GOSSIP_ITEM_EXTENDED(6, "Withdraw some gold", DEPOSIT_WITHDRAW, deposit, "Insert how much gold you would like to|cffFF0000 withdraw|r?", 0, true);
- player->ADD_GOSSIP_ITEM_EXTENDED(6, "Deposit some gold", DEPOSIT_DEPOSIT, deposit, "Insert how much gold you would like to|cFF00FF00 deposit|r?", 0, true);
- player->ADD_GOSSIP_ITEM_EXTENDED(8, "|cff9E00FFRename deposit|r", DEPOSIT_RENAME, deposit, "|cffEBFF00Press insert a new name|r", 0, true);
- player->ADD_GOSSIP_ITEM_EXTENDED(4, "|cffFF0000Disband deposit|r", DEPOSIT_DELETE, deposit, "|cffEBFF00Are you sure about disbanding this deposit?\n|cFFFF0000Once disbanded cannot be recovered!|r\n\nWrite |cFFFF0000Disband|r to the box to confirm", 0, true);
- if(info->pass.empty())
- player->ADD_GOSSIP_ITEM_EXTENDED(4, "Add password", ADD_PASSWORD, deposit, "Insert new password", 0, true);
- else
- {
- player->ADD_GOSSIP_ITEM_EXTENDED(4, "Modify password", MODIFY_PASSWORD, deposit, "Insert old password", 0, true);
- player->ADD_GOSSIP_ITEM_EXTENDED(4, "Delete password", REMOVE_PASSWORD, deposit, "Insert old password", 0, true);
- }
- player->SEND_GOSSIP_MENU(7777778, creature->GetGUID());
- }
- // Withdraw gold from the deposit
- void WithdrawGold(Player* player, uint8 deposit, uint32 amount)
- {
- if(!amount) // gave bad value to input box
- {
- sendError(player, "Invalid gold amount");
- return;
- }
- depInfo* info = getDeposit(player, deposit);
- if(!info)
- return;
- if(!info->gold) // empty deposit
- {
- sendError(player, "Deposit is empty");
- return;
- }
- if(amount > info->gold)
- amount = info->gold;
- if(!modifyMoney(player, amount*GOLD, true))
- return;
- info->gold -= amount;
- CharacterDatabase.PExecute("UPDATE `gold_bank_data` SET `gold`= %u WHERE `plrGUID`= %u AND `name` = \"%s\"", info->gold, player->GetGUIDLow(), info->name.c_str());
- ChatHandler(player->GetSession()).PSendSysMessage("Deposit [%s] withdrew %u gold", info->name.c_str(), amount);
- }
- // Deposit gold in the deposit
- void DepositGold(Player* player, uint8 deposit, uint32 amount)
- {
- if(!amount) // gave bad value to input box
- {
- sendError(player, "Invalid gold amount");
- return;
- }
- if(amount*GOLD > player->GetMoney())
- {
- sendError(player, "You dont have the amount of gold inserted!");
- return;
- }
- depInfo* info = getDeposit(player, deposit);
- if(!info)
- return;
- if(info->gold >= uint32(MAX_MONEY_AMOUNT - amount)) // can only add to max money amount
- amount = MAX_MONEY_AMOUNT-info->gold;
- if(!modifyMoney(player, amount*GOLD, false))
- return;
- info->gold += amount;
- CharacterDatabase.PExecute("UPDATE `gold_bank_data` SET `gold`= %u WHERE `plrGUID`= %u AND `name` = \"%s\"", info->gold, player->GetGUIDLow(), info->name.c_str());
- ChatHandler(player->GetSession()).PSendSysMessage("Deposit [%s] deposited %u gold", info->name.c_str(), amount);
- return;
- }
- // Rename the deposit
- void RenameDeposit(Player* player, uint8 deposit, const char* newName)
- {
- std::string nameStr(newName);
- if(!checkName(player, nameStr))
- return;
- depInfo* info = getDeposit(player, deposit);
- if(!info)
- return;
- CharacterDatabase.PExecute("UPDATE `gold_bank_data` SET `name`= \"%s\" WHERE `plrGUID`= %u AND `name` = \"%s\"", newName, player->GetGUIDLow(), info->name.c_str());
- info->name = nameStr;
- deposits[player->GetGUIDLow()].sort(cmp_by_name); // resort the deposits after rename
- ChatHandler(player->GetSession()).PSendSysMessage("Deposit renamed to %s", newName);
- }
- //Disband deposit
- void DisbandDeposit(Player* player, uint8 deposit, const char* message)
- {
- std::string data(message);
- std::transform(data.begin(), data.end(), data.begin(), ::tolower);
- if(data != "disband")
- {
- sendError(player, "You need to insert Disband to disband the deposit");
- return;
- }
- depInfo* info = getDeposit(player, deposit);
- if(!info)
- return;
- ChatHandler(player->GetSession()).PSendSysMessage("Deposit %s disbanded", info->name.c_str());
- CharacterDatabase.PExecute("DELETE FROM `gold_bank_data` WHERE `plrGUID`= %u AND `name` = \"%s\"", player->GetGUIDLow(), info->name.c_str());
- std::list<depInfo>::iterator it = deposits[player->GetGUIDLow()].begin();
- std::advance(it, deposit);
- if(it != deposits[player->GetGUIDLow()].end())
- deposits[player->GetGUIDLow()].erase(it);
- }
- //Add new password
- void AddPasswordToDeposit(Player* player, uint8 deposit, const char* newPass)
- {
- std::string passStr(newPass);
- if(passStr.empty() || passStr.length() < 2 || passStr.length() > 255)
- {
- sendError(player, "Invalid password length");
- return;
- }
- depInfo* info = getDeposit(player, deposit);
- if(!info)
- return;
- info->pass = passStr;
- CharacterDatabase.PExecute("UPDATE `gold_bank_data` SET `password`= \"%s\" WHERE `plrGUID`= %u AND `name` = \"%s\"", newPass, player->GetGUIDLow(), info->name.c_str());
- ChatHandler(player->GetSession()).PSendSysMessage("Deposit %s now has a new password", info->name.c_str());
- }
- //Check old pass
- bool AskOldDepositPass(Player* player, uint8 deposit, const char* oldPass)
- {
- depInfo* info = getDeposit(player, deposit);
- if(!info)
- return false;
- if(info->pass.empty())
- {
- sendError(player, "Internal error. Deposit has no password!");
- return false;
- }
- std::string passStr(oldPass);
- if(passStr.empty())
- {
- sendError(player, "Invalid password inputted");
- return false;
- }
- if(info->pass != passStr)
- {
- sendError(player, "Password inserted does not match the old password");
- return false;
- }
- return true;
- }
- void RemoveDepositPass(Player* player, uint8 deposit)
- {
- depInfo* info = getDeposit(player, deposit);
- if(!info)
- return;
- info->pass = "";
- CharacterDatabase.PExecute("UPDATE `gold_bank_data` SET `password`= NULL WHERE `plrGUID`= %u AND `name` = \"%s\"", player->GetGUIDLow(), info->name.c_str());
- ChatHandler(player->GetSession()).PSendSysMessage("Deposit %s no longer has a password", info->name.c_str());
- }
- };
- void AddSC_Gold_Banker()
- {
- new gold_banker();
- }
Add Comment
Please, Sign In to add comment