3
* Copyright (C) 2010 The Mana Developers
4
* Copyright (C) 2011-2013 The ManaPlus Developers
6
* This file is part of The ManaPlus Client.
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program. If not, see <http://www.gnu.org/licenses/>.
22
#include "being/playerinfo.h"
25
#include "configuration.h"
26
#include "depricatedevent.h"
27
#include "inventory.h"
29
#include "gui/inventorywindow.h"
30
#include "gui/npcdialog.h"
31
#include "gui/npcpostdialog.h"
33
#include "resources/iteminfo.h"
35
#include "net/inventoryhandler.h"
37
#include "net/playerhandler.h"
44
PlayerInfoBackend mData;
47
Inventory *mInventory = nullptr;
48
Equipment *mEquipment = nullptr;
50
#ifdef MANASERV_SUPPORT
51
std::map<int, Special> mSpecials;
52
signed char mSpecialRechargeUpdateNeeded = 0;
55
bool mTrading = false;
56
int mLevelProgress = 0;
57
std::set<int> mProtectedItems;
59
// --- Triggers ---------------------------------------------------------------
61
void triggerAttr(const int id, const int old)
63
DepricatedEvent event(EVENT_UPDATEATTRIBUTE);
64
event.setInt("id", id);
65
event.setInt("oldValue", old);
66
event.setInt("newValue", mData.mAttributes.find(id)->second);
67
DepricatedEvent::trigger(CHANNEL_ATTRIBUTES, event);
70
void triggerStat(const int id, const std::string &changed,
71
const int old1, const int old2)
73
const StatMap::const_iterator it = mData.mStats.find(id);
74
if (it == mData.mStats.end())
77
DepricatedEvent event(EVENT_UPDATESTAT);
78
event.setInt("id", id);
79
const Stat &stat = it->second;
80
event.setInt("base", stat.base);
81
event.setInt("mod", stat.mod);
82
event.setInt("exp", stat.exp);
83
event.setInt("expNeeded", stat.expNeed);
84
event.setString("changed", changed);
85
event.setInt("oldValue1", old1);
86
event.setInt("oldValue2", old2);
87
DepricatedEvent::trigger(CHANNEL_ATTRIBUTES, event);
90
// --- Attributes -------------------------------------------------------------
92
int getAttribute(const int id)
94
const IntMap::const_iterator it = mData.mAttributes.find(id);
95
if (it != mData.mAttributes.end())
101
void setAttribute(const int id, const int value, const bool notify)
103
const int old = mData.mAttributes[id];
104
mData.mAttributes[id] = value;
106
triggerAttr(id, old);
109
int getSkillLevel(const int id)
111
const IntMap::const_iterator it = mData.mSkills.find(id);
112
if (it != mData.mSkills.end())
118
void setSkillLevel(const int id, const int value)
120
mData.mSkills[id] = value;
123
// --- Stats ------------------------------------------------------------------
125
int getStatBase(const int id)
127
const StatMap::const_iterator it = mData.mStats.find(id);
128
if (it != mData.mStats.end())
129
return it->second.base;
134
void setStatBase(const int id, const int value, const bool notify)
136
const int old = mData.mStats[id].base;
137
mData.mStats[id].base = value;
139
triggerStat(id, "base", old);
142
int getStatMod(const int id)
144
const StatMap::const_iterator it = mData.mStats.find(id);
145
if (it != mData.mStats.end())
146
return it->second.mod;
151
void setStatMod(const int id, const int value, const bool notify)
153
const int old = mData.mStats[id].mod;
154
mData.mStats[id].mod = value;
156
triggerStat(id, "mod", old);
159
int getStatEffective(const int id)
161
const StatMap::const_iterator it = mData.mStats.find(id);
162
if (it != mData.mStats.end())
163
return it->second.base + it->second.mod;
168
const std::pair<int, int> getStatExperience(const int id)
170
const StatMap::const_iterator it = mData.mStats.find(id);
172
if (it != mData.mStats.end())
175
b = it->second.expNeed;
182
return std::pair<int, int>(a, b);
185
void setStatExperience(const int id, const int have,
186
const int need, const bool notify)
188
Stat &stat = mData.mStats[id];
190
const int oldExp = stat.exp;
191
const int oldExpNeed = stat.expNeed;
195
triggerStat(id, "exp", oldExp, oldExpNeed);
198
// --- Inventory / Equipment --------------------------------------------------
200
Inventory *getInventory()
205
Inventory *getStorageInventory()
207
return Net::getInventoryHandler()->getStorage();
210
void clearInventory()
218
void setInventoryItem(const int index, const int id,
219
const int amount, const int refine)
221
bool equipment = false;
222
const int itemType = ItemDB::get(id).getType();
223
if (itemType != ITEM_UNUSABLE && itemType != ITEM_USABLE)
226
mInventory->setItem(index, id, amount, refine, equipment);
229
Equipment *getEquipment()
234
Item *getEquipment(const unsigned int slot)
237
return mEquipment->getEquipment(slot);
242
void setEquipmentBackend(Equipment::Backend *const backend)
245
mEquipment->setBackend(backend);
248
// --- Misc -------------------------------------------------------------------
250
void setBackend(const PlayerInfoBackend &backend)
255
void setCharId(const int charId)
267
#ifdef MANASERV_SUPPORT
268
if ((mSpecialRechargeUpdateNeeded % 11) == 0)
270
mSpecialRechargeUpdateNeeded = 0;
271
FOR_EACH (SpecialsMap::iterator, it, mSpecials)
273
Special &special = it->second;
274
special.currentMana += special.recharge;
275
if (special.currentMana > special.neededMana)
276
special.currentMana = special.neededMana;
279
mSpecialRechargeUpdateNeeded++;
288
void setTrading(const bool trading)
295
const Net::PlayerHandler *const handler = Net::getPlayerHandler();
298
const int attr = handler->getAttackLocation();
299
const int attackDelay = getStatBase(ATTACK_DELAY);
300
if (attr != -1 && attackDelay)
302
setStatBase(ATTACK_SPEED, getStatBase(attr) * 1000
303
/ attackDelay, false);
304
setStatMod(ATTACK_SPEED, getStatMod(attr) * 1000
305
/ attackDelay, true);
309
setStatBase(ATTACK_SPEED, 0, false);
310
setStatMod(ATTACK_SPEED, 0, true);
325
mProtectedItems.clear();
326
splitToIntSet(mProtectedItems,
327
serverConfig.getStringValue("protectedItems"), ',');
332
mData.mSkills.clear();
337
return NpcDialog::isActive() || NpcPostDialog::isActive()
338
|| InventoryWindow::isStorageActive();
344
mInventory = nullptr;
346
mEquipment = nullptr;
349
void stateChange(const int state)
351
if (state == STATE_GAME)
355
mInventory = new Inventory(Inventory::INVENTORY);
356
mEquipment = new Equipment();
361
static void saveProtectedItems()
364
std::set<int>::const_iterator it = mProtectedItems.begin();
365
std::set<int>::const_iterator it_end = mProtectedItems.end();
368
str.append(toString(*it));
373
str.append(",").append(toString(*it));
376
serverConfig.setValue("protectedItems", str);
377
serverConfig.write();
380
void protectItem(const int id)
382
mProtectedItems.insert(id);
383
saveProtectedItems();
386
void unprotectItem(const int id)
388
mProtectedItems.erase(id);
389
saveProtectedItems();
392
bool isItemProtected(const int id)
394
return mProtectedItems.find(id) != mProtectedItems.end();
397
} // namespace PlayerInfo