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