summaryrefslogtreecommitdiff
path: root/src/being/playerinfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/being/playerinfo.cpp')
-rw-r--r--src/being/playerinfo.cpp398
1 files changed, 398 insertions, 0 deletions
diff --git a/src/being/playerinfo.cpp b/src/being/playerinfo.cpp
new file mode 100644
index 000000000..9abd617a5
--- /dev/null
+++ b/src/being/playerinfo.cpp
@@ -0,0 +1,398 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2010 The Mana Developers
+ * Copyright (C) 2011-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "being/playerinfo.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "depricatedevent.h"
+#include "inventory.h"
+#include "depricatedlistener.h"
+#include "logger.h"
+
+#include "gui/inventorywindow.h"
+#include "gui/npcdialog.h"
+#include "gui/npcpostdialog.h"
+
+#include "resources/iteminfo.h"
+
+#include "net/inventoryhandler.h"
+#include "net/playerhandler.h"
+
+#include "debug.h"
+
+namespace PlayerInfo
+{
+
+PlayerInfoBackend mData;
+int mCharId = 0;
+
+Inventory *mInventory = nullptr;
+Equipment *mEquipment = nullptr;
+
+#ifdef MANASERV_SUPPORT
+std::map<int, Special> mSpecials;
+signed char mSpecialRechargeUpdateNeeded = 0;
+#endif
+
+bool mTrading = false;
+int mLevelProgress = 0;
+std::set<int> mProtectedItems;
+
+// --- Triggers ---------------------------------------------------------------
+
+void triggerAttr(const int id, const int old)
+{
+ DepricatedEvent event(EVENT_UPDATEATTRIBUTE);
+ event.setInt("id", id);
+ event.setInt("oldValue", old);
+ event.setInt("newValue", mData.mAttributes.find(id)->second);
+ DepricatedEvent::trigger(CHANNEL_ATTRIBUTES, event);
+}
+
+void triggerStat(const int id, const std::string &changed,
+ const int old1, const int old2)
+{
+ const StatMap::const_iterator it = mData.mStats.find(id);
+ if (it == mData.mStats.end())
+ return;
+
+ DepricatedEvent event(EVENT_UPDATESTAT);
+ event.setInt("id", id);
+ const Stat &stat = it->second;
+ event.setInt("base", stat.base);
+ event.setInt("mod", stat.mod);
+ event.setInt("exp", stat.exp);
+ event.setInt("expNeeded", stat.expNeed);
+ event.setString("changed", changed);
+ event.setInt("oldValue1", old1);
+ event.setInt("oldValue2", old2);
+ DepricatedEvent::trigger(CHANNEL_ATTRIBUTES, event);
+}
+
+// --- Attributes -------------------------------------------------------------
+
+int getAttribute(const int id)
+{
+ const IntMap::const_iterator it = mData.mAttributes.find(id);
+ if (it != mData.mAttributes.end())
+ return it->second;
+ else
+ return 0;
+}
+
+void setAttribute(const int id, const int value, const bool notify)
+{
+ const int old = mData.mAttributes[id];
+ mData.mAttributes[id] = value;
+ if (notify)
+ triggerAttr(id, old);
+}
+
+int getSkillLevel(const int id)
+{
+ const IntMap::const_iterator it = mData.mSkills.find(id);
+ if (it != mData.mSkills.end())
+ return it->second;
+ else
+ return 0;
+}
+
+void setSkillLevel(const int id, const int value)
+{
+ mData.mSkills[id] = value;
+}
+
+// --- Stats ------------------------------------------------------------------
+
+int getStatBase(const int id)
+{
+ const StatMap::const_iterator it = mData.mStats.find(id);
+ if (it != mData.mStats.end())
+ return it->second.base;
+ else
+ return 0;
+}
+
+void setStatBase(const int id, const int value, const bool notify)
+{
+ const int old = mData.mStats[id].base;
+ mData.mStats[id].base = value;
+ if (notify)
+ triggerStat(id, "base", old);
+}
+
+int getStatMod(const int id)
+{
+ const StatMap::const_iterator it = mData.mStats.find(id);
+ if (it != mData.mStats.end())
+ return it->second.mod;
+ else
+ return 0;
+}
+
+void setStatMod(const int id, const int value, const bool notify)
+{
+ const int old = mData.mStats[id].mod;
+ mData.mStats[id].mod = value;
+ if (notify)
+ triggerStat(id, "mod", old);
+}
+
+int getStatEffective(const int id)
+{
+ const StatMap::const_iterator it = mData.mStats.find(id);
+ if (it != mData.mStats.end())
+ return it->second.base + it->second.mod;
+ else
+ return 0;
+}
+
+const std::pair<int, int> getStatExperience(const int id)
+{
+ const StatMap::const_iterator it = mData.mStats.find(id);
+ int a, b;
+ if (it != mData.mStats.end())
+ {
+ a = it->second.exp;
+ b = it->second.expNeed;
+ }
+ else
+ {
+ a = 0;
+ b = 0;
+ }
+ return std::pair<int, int>(a, b);
+}
+
+void setStatExperience(const int id, const int have,
+ const int need, const bool notify)
+{
+ Stat &stat = mData.mStats[id];
+
+ const int oldExp = stat.exp;
+ const int oldExpNeed = stat.expNeed;
+ stat.exp = have;
+ stat.expNeed = need;
+ if (notify)
+ triggerStat(id, "exp", oldExp, oldExpNeed);
+}
+
+// --- Inventory / Equipment --------------------------------------------------
+
+Inventory *getInventory()
+{
+ return mInventory;
+}
+
+Inventory *getStorageInventory()
+{
+ return Net::getInventoryHandler()->getStorage();
+}
+
+void clearInventory()
+{
+ if (mEquipment)
+ mEquipment->clear();
+ if (mInventory)
+ mInventory->clear();
+}
+
+void setInventoryItem(const int index, const int id,
+ const int amount, const int refine)
+{
+ bool equipment = false;
+ const int itemType = ItemDB::get(id).getType();
+ if (itemType != ITEM_UNUSABLE && itemType != ITEM_USABLE)
+ equipment = true;
+ if (mInventory)
+ mInventory->setItem(index, id, amount, refine, equipment);
+}
+
+Equipment *getEquipment()
+{
+ return mEquipment;
+}
+
+Item *getEquipment(const unsigned int slot)
+{
+ if (mEquipment)
+ return mEquipment->getEquipment(slot);
+ else
+ return nullptr;
+}
+
+void setEquipmentBackend(Equipment::Backend *const backend)
+{
+ if (mEquipment)
+ mEquipment->setBackend(backend);
+}
+
+// --- Misc -------------------------------------------------------------------
+
+void setBackend(const PlayerInfoBackend &backend)
+{
+ mData = backend;
+}
+
+void setCharId(const int charId)
+{
+ mCharId = charId;
+}
+
+int getCharId()
+{
+ return mCharId;
+}
+
+void logic()
+{
+#ifdef MANASERV_SUPPORT
+ if ((mSpecialRechargeUpdateNeeded % 11) == 0)
+ {
+ mSpecialRechargeUpdateNeeded = 0;
+ FOR_EACH (SpecialsMap::iterator, it, mSpecials)
+ {
+ Special &special = it->second;
+ special.currentMana += special.recharge;
+ if (special.currentMana > special.neededMana)
+ special.currentMana = special.neededMana;
+ }
+ }
+ mSpecialRechargeUpdateNeeded++;
+#endif
+}
+
+bool isTrading()
+{
+ return mTrading;
+}
+
+void setTrading(const bool trading)
+{
+ mTrading = trading;
+}
+
+void updateAttrs()
+{
+ const Net::PlayerHandler *const handler = Net::getPlayerHandler();
+ if (!handler)
+ return;
+ const int attr = handler->getAttackLocation();
+ const int attackDelay = getStatBase(ATTACK_DELAY);
+ if (attr != -1 && attackDelay)
+ {
+ setStatBase(ATTACK_SPEED, getStatBase(attr) * 1000
+ / attackDelay, false);
+ setStatMod(ATTACK_SPEED, getStatMod(attr) * 1000
+ / attackDelay, true);
+ }
+ else
+ {
+ setStatBase(ATTACK_SPEED, 0, false);
+ setStatMod(ATTACK_SPEED, 0, true);
+ }
+}
+
+void init()
+{
+}
+
+void deinit()
+{
+ clearInventory();
+}
+
+void loadData()
+{
+ mProtectedItems.clear();
+ splitToIntSet(mProtectedItems,
+ serverConfig.getStringValue("protectedItems"), ',');
+}
+
+void clear()
+{
+ mData.mSkills.clear();
+}
+
+bool isTalking()
+{
+ return NpcDialog::isActive() || NpcPostDialog::isActive()
+ || InventoryWindow::isStorageActive();
+}
+
+void gameDestroyed()
+{
+ delete mInventory;
+ mInventory = nullptr;
+ delete mEquipment;
+ mEquipment = nullptr;
+}
+
+void stateChange(const int state)
+{
+ if (state == STATE_GAME)
+ {
+ if (!mInventory)
+ {
+ mInventory = new Inventory(Inventory::INVENTORY);
+ mEquipment = new Equipment();
+ }
+ }
+}
+
+static void saveProtectedItems()
+{
+ std::string str;
+ std::set<int>::const_iterator it = mProtectedItems.begin();
+ std::set<int>::const_iterator it_end = mProtectedItems.end();
+ if (it != it_end)
+ {
+ str.append(toString(*it));
+ ++ it;
+ }
+ while (it != it_end)
+ {
+ str.append(",").append(toString(*it));
+ ++ it;
+ }
+ serverConfig.setValue("protectedItems", str);
+ serverConfig.write();
+}
+
+void protectItem(const int id)
+{
+ mProtectedItems.insert(id);
+ saveProtectedItems();
+}
+
+void unprotectItem(const int id)
+{
+ mProtectedItems.erase(id);
+ saveProtectedItems();
+}
+
+bool isItemProtected(const int id)
+{
+ return mProtectedItems.find(id) != mProtectedItems.end();
+}
+
+} // namespace PlayerInfo