ManaPlus
playerinfo.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2010 The Mana Developers
4  * Copyright (C) 2011-2018 The ManaPlus Developers
5  *
6  * This file is part of The ManaPlus Client.
7  *
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
11  * any later version.
12  *
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.
17  *
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/>.
20  */
21 
22 #include "being/playerinfo.h"
23 
24 #include "configuration.h"
25 #include "itemsoundmanager.h"
26 
27 #include "being/localplayer.h"
28 
29 #include "being/homunculusinfo.h"
30 #include "being/mercenaryinfo.h"
31 #include "being/petinfo.h"
32 
34 #include "gui/windows/npcdialog.h"
35 
36 #include "listeners/statlistener.h"
37 
38 #include "net/homunculushandler.h"
39 #include "net/inventoryhandler.h"
40 #include "net/mercenaryhandler.h"
41 #include "net/playerhandler.h"
42 
43 #include "resources/item/item.h"
44 
45 #include "utils/delete2.h"
46 
48 
49 #include "debug.h"
50 
51 namespace PlayerInfo
52 {
53 
55 int mCharId = 0;
56 
57 Inventory *mInventory = nullptr;
61 PetInfo *mPet = nullptr;
62 std::string mRoomName;
63 Equipment *mEquipment = nullptr;
67 
69 bool mVending = false;
71 int mServerLanguage = -1;
72 std::set<int> mProtectedItems;
73 
74 // --- Triggers ---------------------------------------------------------------
75 
76 void triggerAttr(const AttributesT id,
77  const int64_t old)
78 {
80  mData.mAttributes.find(id)->second);
81 }
82 
83 void triggerStat(const AttributesT id,
84  const int old1,
85  const int old2)
86 {
87  StatListener::distributeEvent(id, old1, old2);
88 }
89 
90 // --- Attributes -------------------------------------------------------------
91 
92 int64_t getAttribute64(const AttributesT id)
93 {
94  const AtrIntMap::const_iterator it = mData.mAttributes.find(id);
95  if (it != mData.mAttributes.end())
96  return it->second;
97  return 0;
98 }
99 
100 int32_t getAttribute(const AttributesT id)
101 {
102  const AtrIntMap::const_iterator it = mData.mAttributes.find(id);
103  if (it != mData.mAttributes.end())
104  return CAST_S32(it->second);
105  return 0;
106 }
107 
108 void setAttribute(const AttributesT id,
109  const int64_t value,
110  const Notify notify)
111 {
112  const int64_t old = mData.mAttributes[id];
113  mData.mAttributes[id] = value;
114  if (notify == Notify_true)
115  triggerAttr(id, old);
116 }
117 
118 int getSkillLevel(const int id)
119 {
120  const IntMap::const_iterator it = mData.mSkills.find(id);
121  if (it != mData.mSkills.end())
122  return it->second;
123  return 0;
124 }
125 
126 void setSkillLevel(const int id, const int value)
127 {
128  mData.mSkills[id] = value;
129 }
130 
131 // --- Stats ------------------------------------------------------------------
132 
134 {
135  const StatMap::const_iterator it = mData.mStats.find(id);
136  if (it != mData.mStats.end())
137  return it->second.base;
138  return 0;
139 }
140 
141 void setStatBase(const AttributesT id, const int value, const Notify notify)
142 {
143  const int old = mData.mStats[id].base;
144  mData.mStats[id].base = value;
145  if (notify == Notify_true)
146  triggerStat(id, old, 0);
147 }
148 
149 int getStatMod(const AttributesT id)
150 {
151  const StatMap::const_iterator it = mData.mStats.find(id);
152  if (it != mData.mStats.end())
153  return it->second.mod;
154  return 0;
155 }
156 
157 void setStatMod(const AttributesT id, const int value, const Notify notify)
158 {
159  const int old = mData.mStats[id].mod;
160  mData.mStats[id].mod = value;
161  if (notify == Notify_true)
162  triggerStat(id, old, 0);
163 }
164 
166 {
167  const StatMap::const_iterator it = mData.mStats.find(id);
168  if (it != mData.mStats.end())
169  return it->second.base + it->second.mod;
170  return 0;
171 }
172 
173 const std::pair<int, int> getStatExperience(const AttributesT id)
174 {
175  const StatMap::const_iterator it = mData.mStats.find(id);
176  int a, b;
177  if (it != mData.mStats.end())
178  {
179  a = it->second.exp;
180  b = it->second.expNeed;
181  }
182  else
183  {
184  a = 0;
185  b = 0;
186  }
187  return std::pair<int, int>(a, b);
188 }
189 
190 // --- Inventory / Equipment --------------------------------------------------
191 
193 {
194  return mInventory;
195 }
196 
198 {
199  if (inventoryHandler != nullptr)
200  return inventoryHandler->getStorage();
201  return nullptr;
202 }
203 
205 {
206  return mCartInventory;
207 }
208 
210 {
211  if (mEquipment != nullptr)
212  mEquipment->clear();
213  if (mInventory != nullptr)
214  mInventory->clear();
215 }
216 
218 {
219  return mEquipment;
220 }
221 
222 const Item *getEquipment(const unsigned int slot)
223 {
224  if (mEquipment != nullptr)
225  return mEquipment->getEquipment(slot);
226  return nullptr;
227 }
228 
230 {
231  if (mEquipment != nullptr)
232  mEquipment->setBackend(backend);
233 }
234 
235 void equipItem(const Item *const item, const Sfx sfx)
236 {
237  if (sfx == Sfx_true)
239  if (inventoryHandler != nullptr)
241 }
242 
243 void unequipItem(const Item *const item, const Sfx sfx)
244 {
245  if (sfx == Sfx_true)
247  if (inventoryHandler != nullptr)
249 }
250 
251 void useItem(const Item *const item, const Sfx sfx)
252 {
253  if (sfx == Sfx_true)
255  if (inventoryHandler != nullptr)
256  inventoryHandler->useItem(item);
257 }
258 
259 void useEquipItem(const Item *const item,
260  const int16_t useType,
261  const Sfx sfx)
262 {
263  if (item != nullptr)
264  {
265  if (item->getType() == ItemType::Card)
266  {
267  if (mProtectedItems.find(item->getId()) == mProtectedItems.end())
268  {
269  if (inventoryHandler != nullptr)
270  inventoryHandler->useCard(item);
271  if (sfx == Sfx_true)
273  }
274  }
275  else if (item->isEquipment() == Equipm_true)
276  {
277  if (item->isEquipped() == Equipped_true)
278  {
279  if (sfx == Sfx_true)
281  if (inventoryHandler != nullptr)
283  }
284  else
285  {
286  if (sfx == Sfx_true)
288  if (inventoryHandler != nullptr)
290  }
291  }
292  else
293  {
294  if (mProtectedItems.find(item->getId()) == mProtectedItems.end())
295  {
296  if (inventoryHandler != nullptr)
297  {
298  if (useType == 0)
299  inventoryHandler->useItem(item);
300  else
301  inventoryHandler->useItem(item, useType);
302  }
303  if (sfx == Sfx_true)
305  }
306  }
307  }
308 }
309 
310 void useEquipItem2(const Item *const item,
311  const int16_t useType,
312  const Sfx sfx)
313 {
314  if (item != nullptr)
315  {
316  if (item->isEquipment() == Equipm_false)
317  {
318  if (item->isEquipped() == Equipped_true)
319  {
320  if (sfx == Sfx_true)
322  if (inventoryHandler != nullptr)
324  }
325  else
326  {
327  if (sfx == Sfx_true)
329  if (inventoryHandler != nullptr)
331  }
332  }
333  else
334  {
335  if (mProtectedItems.find(item->getId()) == mProtectedItems.end())
336  {
337  if (sfx == Sfx_true)
339  if (inventoryHandler != nullptr)
340  {
341  if (useType == 0)
342  inventoryHandler->useItem(item);
343  else
344  inventoryHandler->useItem(item, useType);
345  }
346  }
347  }
348  }
349 }
350 
351 void dropItem(const Item *const item, const int amount, const Sfx sfx)
352 {
353  if (item != nullptr &&
354  mProtectedItems.find(item->getId()) == mProtectedItems.end())
355  {
356  if (sfx == Sfx_true)
358  if (inventoryHandler != nullptr)
359  inventoryHandler->dropItem(item, amount);
360  }
361 }
362 
363 void pickUpItem(const FloorItem *const item, const Sfx sfx)
364 {
365  if (sfx == Sfx_true)
367  if (playerHandler != nullptr)
368  playerHandler->pickUp(item);
369 }
370 
371 // --- Misc -------------------------------------------------------------------
372 
373 void setBackend(const PlayerInfoBackend &backend)
374 {
375  mData = backend;
376 }
377 
378 void setCharId(const int charId)
379 {
380  mCharId = charId;
381 }
382 
384 {
385  return mCharId;
386 }
387 
389 {
390  return mTrading;
391 }
392 
393 void setTrading(const Trading trading)
394 {
395  mTrading = trading;
396 }
397 
398 #define updateAttackStat(atk, delay, speed) \
399  attackDelay = getStatBase(delay); \
400  if (attackDelay != 0) \
401  { \
402  setStatBase(speed, \
403  getStatBase(atk) * 1000 / attackDelay, \
404  Notify_false); \
405  setStatMod(speed, \
406  getStatMod(atk) * 1000 / attackDelay, \
407  Notify_true); \
408  } \
409  else \
410  { \
411  setStatBase(speed, 0, \
412  Notify_false); \
413  setStatMod(speed, 0, \
414  Notify_true); \
415  }
416 
418 {
419  int attackDelay;
429 }
430 
431 void init()
432 {
433 }
434 
435 void deinit()
436 {
437  clearInventory();
438  delete2(mMercenary);
439  mPetBeingId = BeingId_zero;
440 }
441 
442 void loadData()
443 {
444  mProtectedItems.clear();
445  splitToIntSet(mProtectedItems,
446  serverConfig.getStringValue("protectedItems"), ',');
447 }
448 
449 void clear()
450 {
451  mData.mSkills.clear();
452  mPetBeingId = BeingId_zero;
453 }
454 
455 bool isTalking()
456 {
458 }
459 
461 {
462  delete2(mInventory);
463  delete2(mEquipment);
464  delete2(mCartInventory);
465 }
466 
467 void stateChange(const StateT state)
468 {
469  if (state == State::GAME)
470  {
471  if (mInventory == nullptr)
472  {
473  mInventory = new Inventory(InventoryType::Inventory, -1);
474  mEquipment = new Equipment;
475  mCartInventory = new Inventory(InventoryType::Cart, -1);
476  }
477  }
478 }
479 
480 static void saveProtectedItems()
481 {
482  std::string str;
483  std::set<int>::const_iterator it = mProtectedItems.begin();
484  std::set<int>::const_iterator it_end = mProtectedItems.end();
485  if (it != it_end)
486  {
487  str.append(toString(*it));
488  ++ it;
489  }
490  while (it != it_end)
491  {
492  str.append(",").append(toString(*it));
493  ++ it;
494  }
495  serverConfig.setValue("protectedItems", str);
497 }
498 
499 void protectItem(const int id)
500 {
501  mProtectedItems.insert(id);
503 }
504 
505 void unprotectItem(const int id)
506 {
507  mProtectedItems.erase(id);
509 }
510 
511 bool isItemProtected(const int id)
512 {
513  return mProtectedItems.find(id) != mProtectedItems.end();
514 }
515 
517 {
518  delete mMercenary;
519  mMercenary = info;
520 }
521 
522 void setMercenaryBeing(Being *const being)
523 {
524  if (being == nullptr ||
525  mMercenary == nullptr)
526  {
527  return;
528  }
529  being->setName(mMercenary->name);
530  being->setOwner(localPlayer);
531  being->setLevel(mMercenary->level);
532  being->setAttackRange(mMercenary->range);
533 }
534 
535 void setElemental(const BeingId id)
536 {
537  mElementalId = id;
538 }
539 
541 {
542  return mElementalId;
543 }
544 
546 {
547  return mMercenary;
548 }
549 
550 void setPet(PetInfo *const info)
551 {
552  delete mPet;
553  mPet = info;
554 }
555 
556 void setPetBeing(Being *const being)
557 {
558  if (being != nullptr)
559  mPetBeingId = being->getId();
560  else
561  mPetBeingId = BeingId_zero;
562  if (being == nullptr ||
563  mPet == nullptr)
564  {
565  return;
566  }
567  being->setName(mPet->name);
568  being->setOwner(localPlayer);
569  being->setLevel(mPet->level);
570 }
571 
573 {
574  return mPet;
575 }
576 
578 {
579  return mPetBeingId;
580 }
581 
583 {
584  delete mHomunculus;
585  mHomunculus = info;
586 }
587 
588 void setHomunculusBeing(Being *const being)
589 {
590  if (being == nullptr ||
591  mHomunculus == nullptr)
592  {
593  return;
594  }
595  being->setName(mHomunculus->name);
596  being->setOwner(localPlayer);
597 }
598 
600 {
601  return mHomunculus;
602 }
603 
605 {
606  return mHomunculus != nullptr ? mHomunculus->id : BeingId_zero;
607 }
608 
610 {
611  return mMercenary != nullptr ? mMercenary->id : BeingId_zero;
612 }
613 
614 void updateAttackAi(const BeingId targetId,
615  const Keep keep)
616 {
617  if (mMercenary != nullptr &&
618  mercenaryHandler != nullptr)
619  {
620  mercenaryHandler->attack(targetId, keep);
621  }
622  if (mHomunculus != nullptr &&
623  homunculusHandler != nullptr)
624  {
625  homunculusHandler->attack(targetId, keep);
626  }
627 }
628 
629 std::string getRoomName()
630 {
631  return mRoomName;
632 }
633 
634 void setRoomName(const std::string &name)
635 {
636  mRoomName = name;
637 }
638 
639 bool isInRoom()
640 {
641  return !mRoomName.empty();
642 }
643 
645 {
646  mGuildPositionFlags = pos;
647 }
648 
650 {
651  return mGuildPositionFlags;
652 }
653 
654 void enableVending(const bool b)
655 {
656  mVending = b;
657 }
658 
659 bool isVending()
660 {
661  return mVending;
662 }
663 
664 void setServerLanguage(const int lang)
665 {
666  if (lang != mServerLanguage)
667  {
668  mServerLanguage = lang;
670  }
671 }
672 
674 {
675  return mServerLanguage;
676 }
677 
678 } // namespace PlayerInfo
Net::PlayerHandler * playerHandler
Definition: net.cpp:92
void setGuildPositionFlags(const GuildPositionFlags::Type pos)
Definition: playerinfo.cpp:644
static bool isActive()
Definition: npcdialog.h:190
void gameDestroyed()
Definition: playerinfo.cpp:460
static bool isStorageActive()
virtual void attack(const BeingId targetId, const Keep keep) const =0
void deinit()
Definition: playerinfo.cpp:435
std::string getStringValue(const std::string &key) const
std::string mRoomName
Definition: playerinfo.cpp:62
void setStatMod(const AttributesT id, const int value, const Notify notify)
Definition: playerinfo.cpp:157
static void distributeEvent(const AttributesT id, const int64_t oldVal, const int64_t newVal)
virtual Inventory * getStorage() const =0
void setPetBeing(Being *const being)
Definition: playerinfo.cpp:556
void setAttackRange(const int range)
Definition: being.h:842
BeingId mElementalId
Definition: playerinfo.cpp:66
void splitToIntSet(std::set< int > &tokens, const std::string &text, const char separator)
void equipItem(const Item *const item, const Sfx sfx)
Definition: playerinfo.cpp:235
const bool Trading_false
Definition: trading.h:29
bool isTalking()
Definition: playerinfo.cpp:455
void setStatBase(const AttributesT id, const int value, const Notify notify)
Definition: playerinfo.cpp:141
Equipment * getEquipment()
Definition: playerinfo.cpp:217
void init()
Definition: playerinfo.cpp:431
std::string name
Equipped isEquipped() const
Definition: item.h:128
GuildPositionFlags::Type getGuildPositionFlags()
Definition: playerinfo.cpp:649
BeingId getId() const
Definition: actorsprite.h:63
std::string name
Definition: mercenaryinfo.h:40
virtual void useItem(const Item *const item) const =0
#define updateAttackStat(atk, delay, speed)
Definition: playerinfo.cpp:398
Inventory * getInventory()
Definition: playerinfo.cpp:192
Trading mTrading
Definition: playerinfo.cpp:68
const std::pair< int, int > getStatExperience(const AttributesT id)
Definition: playerinfo.cpp:173
void setHomunculus(HomunculusInfo *const info)
Definition: playerinfo.cpp:582
void clearInventory()
Definition: playerinfo.cpp:209
bool Trading
Definition: trading.h:29
const bool Sfx_true
Definition: sfx.h:29
int BeingId
Definition: beingid.h:29
void clear()
Definition: playerinfo.cpp:449
BeingId mPetBeingId
Definition: playerinfo.cpp:64
bool isInRoom()
Definition: playerinfo.cpp:639
State ::T StateT
Definition: state.h:70
std::string name
Definition: petinfo.h:46
PetInfo * mPet
Definition: playerinfo.cpp:61
void triggerAttr(const AttributesT id, const int64_t old)
Definition: playerinfo.cpp:76
void pickUpItem(const FloorItem *const item, const Sfx sfx)
Definition: playerinfo.cpp:363
void setEquipmentBackend(Equipment::Backend *const backend)
Definition: playerinfo.cpp:229
void notify(const unsigned int message)
#define delete2(var)
Definition: delete2.h:24
Configuration serverConfig
const bool Equipped_true
Definition: equipped.h:29
virtual void pickUp(const FloorItem *const floorItem) const =0
void setCharId(const int charId)
Definition: playerinfo.cpp:378
void updateAttrs()
Definition: playerinfo.cpp:417
int getStatEffective(const AttributesT id)
Definition: playerinfo.cpp:165
void clear()
Definition: inventory.cpp:237
void setHomunculusBeing(Being *const being)
Definition: playerinfo.cpp:588
const Item * getEquipment(const int index) const
Definition: equipment.h:68
MercenaryInfo * getMercenary()
Definition: playerinfo.cpp:545
int64_t getAttribute64(const AttributesT id)
Definition: playerinfo.cpp:92
void setElemental(const BeingId id)
Definition: playerinfo.cpp:535
virtual void unequipItem(const Item *const item) const =0
void triggerStat(const AttributesT id, const int old1, const int old2)
Definition: playerinfo.cpp:83
bool Keep
Definition: keep.h:29
virtual void equipItem(const Item *const item) const =0
std::string getRoomName()
Definition: playerinfo.cpp:629
bool Notify
Definition: notify.h:29
void useEquipItem(const Item *const item, const int16_t useType, const Sfx sfx)
Definition: playerinfo.cpp:259
Inventory * getCartInventory()
Definition: playerinfo.cpp:204
#define CAST_S32
Definition: cast.h:29
static void distributeEvent(const AttributesT id, const int oldVal1, const int oldVal2)
void clear()
Definition: equipment.h:77
int mServerLanguage
Definition: playerinfo.cpp:71
const bool Equipm_true
Definition: equipm.h:29
bool info(InputEvent &event)
Definition: commands.cpp:56
void useEquipItem2(const Item *const item, const int16_t useType, const Sfx sfx)
Definition: playerinfo.cpp:310
void setOwner(Being *const owner)
Definition: being.h:910
void updateAttackAi(const BeingId targetId, const Keep keep)
Definition: playerinfo.cpp:614
void setBackend(Backend *const backend)
Definition: equipment.h:87
LocalPlayer * localPlayer
void setAttribute(const AttributesT id, const int64_t value, const Notify notify)
Definition: playerinfo.cpp:108
void protectItem(const int id)
Definition: playerinfo.cpp:499
AtrIntMap mAttributes
Definition: playerinfo.h:72
Definition: item.h:48
Inventory * getStorageInventory()
Definition: playerinfo.cpp:197
Net::MercenaryHandler * mercenaryHandler
Definition: net.cpp:112
BeingId getHomunculusId()
Definition: playerinfo.cpp:604
static void saveProtectedItems()
Definition: playerinfo.cpp:480
PlayerInfoBackend mData
Definition: playerinfo.cpp:54
MercenaryInfo * mMercenary
Definition: playerinfo.cpp:59
int getStatBase(const AttributesT id)
Definition: playerinfo.cpp:133
void useItem(const Item *const item, const Sfx sfx)
Definition: playerinfo.cpp:251
void setMercenary(MercenaryInfo *const info)
Definition: playerinfo.cpp:516
BeingId getMercenaryId()
Definition: playerinfo.cpp:609
void setSkillLevel(const int id, const int value)
Definition: playerinfo.cpp:126
int getCharId()
Definition: playerinfo.cpp:383
Net::InventoryHandler * inventoryHandler
Definition: net.cpp:85
BeingId getElementalId()
Definition: playerinfo.cpp:540
virtual void attack(const BeingId targetId, const Keep keep) const =0
bool isVending()
Definition: playerinfo.cpp:659
Inventory * mInventory
Definition: playerinfo.cpp:57
static void playSfx(const int item, const ItemSoundEvent::Type sound)
void enableVending(const bool b)
Definition: playerinfo.cpp:654
bool isItemProtected(const int id)
Definition: playerinfo.cpp:511
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:1774
int getId() const
Definition: item.h:80
void setRoomName(const std::string &name)
Definition: playerinfo.cpp:634
void unequipItem(const Item *const item, const Sfx sfx)
Definition: playerinfo.cpp:243
Net::HomunculusHandler * homunculusHandler
Definition: net.cpp:107
void loadData()
Definition: playerinfo.cpp:442
int getSkillLevel(const int id)
Definition: playerinfo.cpp:118
HomunculusInfo * mHomunculus
Definition: playerinfo.cpp:60
Equipment * mEquipment
Definition: playerinfo.cpp:63
bool Sfx
Definition: sfx.h:29
void setName(const std::string &name)
Definition: being.cpp:1135
HomunculusInfo * getHomunculus()
Definition: playerinfo.cpp:599
Attributes ::T AttributesT
Definition: attributes.h:117
ItemTypeT getType() const
Definition: item.h:224
Equipm isEquipment() const
Definition: item.h:116
void setMercenaryBeing(Being *const being)
Definition: playerinfo.cpp:522
void stateChange(const StateT state)
Definition: playerinfo.cpp:467
int level
Definition: petinfo.h:48
BeingId getPetBeingId()
Definition: playerinfo.cpp:577
const BeingId BeingId_zero
Definition: beingid.h:29
void setBackend(const PlayerInfoBackend &backend)
Definition: playerinfo.cpp:373
bool mVending
Definition: playerinfo.cpp:69
static void loadDictionaryLang()
void setServerLanguage(const int lang)
Definition: playerinfo.cpp:664
std::set< int > mProtectedItems
Definition: playerinfo.cpp:72
PetInfo * getPet()
Definition: playerinfo.cpp:572
int32_t getAttribute(const AttributesT id)
Definition: playerinfo.cpp:100
int mLevelProgress
Definition: playerinfo.cpp:70
void unprotectItem(const int id)
Definition: playerinfo.cpp:505
int getStatMod(const AttributesT id)
Definition: playerinfo.cpp:149
int getServerLanguage()
Definition: playerinfo.cpp:673
Definition: being.h:93
void setValue(const std::string &key, const std::string &value)
GuildPositionFlags::Type mGuildPositionFlags
Definition: playerinfo.cpp:65
virtual void dropItem(const Item *const item, const int amount) const =0
virtual void useCard(const Item *const item)=0
const bool Notify_true
Definition: notify.h:29
void dropItem(const Item *const item, const int amount, const Sfx sfx)
Definition: playerinfo.cpp:351
void setPet(PetInfo *const info)
Definition: playerinfo.cpp:550
Inventory * mCartInventory
Definition: playerinfo.cpp:58
const bool Equipm_false
Definition: equipm.h:29
void setLevel(const int n)
Definition: being.h:600
Trading isTrading()
Definition: playerinfo.cpp:388
void setTrading(const Trading trading)
Definition: playerinfo.cpp:393