Otclient  14/8/2020
item.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "item.h"
24 #include "thingtypemanager.h"
25 #include "spritemanager.h"
26 #include "thing.h"
27 #include "tile.h"
28 #include "shadermanager.h"
29 #include "container.h"
30 #include "map.h"
31 #include "houses.h"
32 #include "game.h"
33 
34 #include <framework/core/clock.h>
39 
41  m_clientId(0),
42  m_serverId(0),
43  m_countOrSubType(1),
44  m_color(Color::alpha),
45  m_async(true),
46  m_phase(0),
47  m_lastPhase(0)
48 {
49 }
50 
52 {
53  ItemPtr item(new Item);
54  item->setId(id);
55  return item;
56 }
57 
59 {
60  ItemPtr item(new Item);
61  item->setOtbId(id);
62  return item;
63 }
64 
65 std::string Item::getName()
66 {
67  return g_things.findItemTypeByClientId(m_clientId)->getName();
68 }
69 
70 void Item::draw(const Point& dest, float scaleFactor, bool animate, LightView *lightView)
71 {
72  if(m_clientId == 0)
73  return;
74 
75  // determine animation phase
76  int animationPhase = calculateAnimationPhase(animate);
77 
78  // determine x,y,z patterns
79  int xPattern = 0, yPattern = 0, zPattern = 0;
80  calculatePatterns(xPattern, yPattern, zPattern);
81 
82  if(m_color != Color::alpha)
83  g_painter->setColor(m_color);
84  rawGetThingType()->draw(dest, scaleFactor, 0, xPattern, yPattern, zPattern, animationPhase, lightView);
85 
89  if(m_color != Color::alpha)
91 }
92 
94 {
96  id = 0;
97  m_serverId = g_things.findItemTypeByClientId(id)->getServerId();
98  m_clientId = id;
99 }
100 
102 {
103  if(!g_things.isValidOtbId(id))
104  id = 0;
105  auto itemType = g_things.getItemType(id);
106  m_serverId = id;
107 
108  id = itemType->getClientId();
110  id = 0;
111  m_clientId = id;
112 }
113 
115 {
116  return g_things.isValidDatId(m_clientId, ThingCategoryItem);
117 }
118 
120 {
121  try {
122  while(in->canRead()) {
123  int attrib = in->getU8();
124  if(attrib == 0)
125  break;
126 
127  switch(attrib) {
128  case ATTR_COUNT:
129  case ATTR_RUNE_CHARGES:
130  setCount(in->getU8());
131  break;
132  case ATTR_CHARGES:
133  setCount(in->getU16());
134  break;
135  case ATTR_HOUSEDOORID:
137  case ATTR_DUALWIELD:
138  case ATTR_DECAYING_STATE:
139  m_attribs.set(attrib, in->getU8());
140  break;
141  case ATTR_ACTION_ID:
142  case ATTR_UNIQUE_ID:
143  case ATTR_DEPOT_ID:
144  m_attribs.set(attrib, in->getU16());
145  break;
147  case ATTR_ATTACK:
148  case ATTR_EXTRAATTACK:
149  case ATTR_DEFENSE:
150  case ATTR_EXTRADEFENSE:
151  case ATTR_ARMOR:
152  case ATTR_ATTACKSPEED:
153  case ATTR_HITCHANCE:
154  case ATTR_DURATION:
155  case ATTR_WRITTENDATE:
156  case ATTR_SLEEPERGUID:
157  case ATTR_SLEEPSTART:
158  case ATTR_ATTRIBUTE_MAP:
159  m_attribs.set(attrib, in->getU32());
160  break;
161  case ATTR_TELE_DEST: {
162  Position pos;
163  pos.x = in->getU16();
164  pos.y = in->getU16();
165  pos.z = in->getU8();
166  m_attribs.set(attrib, pos);
167  break;
168  }
169  case ATTR_NAME:
170  case ATTR_TEXT:
171  case ATTR_DESC:
172  case ATTR_ARTICLE:
173  case ATTR_WRITTENBY:
174  m_attribs.set(attrib, in->getString());
175  break;
176  default:
177  stdext::throw_exception(stdext::format("invalid item attribute %d", attrib));
178  }
179  }
180  } catch(stdext::exception& e) {
181  g_logger.error(stdext::format("Failed to unserialize OTBM item: %s", e.what()));
182  }
183 }
184 
186 {
187  out->startNode(OTBM_ITEM);
188  out->addU16(getServerId());
189 
190  out->addU8(ATTR_COUNT);
191  out->addU8(getCount());
192 
193  out->addU8(ATTR_CHARGES);
194  out->addU16(getCountOrSubType());
195 
196  Position dest = m_attribs.get<Position>(ATTR_TELE_DEST);
197  if(dest.isValid()) {
198  out->addU8(ATTR_TELE_DEST);
199  out->addPos(dest.x, dest.y, dest.z);
200  }
201 
202  if(isDepot()) {
203  out->addU8(ATTR_DEPOT_ID);
204  out->addU16(getDepotId());
205  }
206 
207  if(isHouseDoor()) {
208  out->addU8(ATTR_HOUSEDOORID);
209  out->addU8(getDoorId());
210  }
211 
212  uint16 aid = m_attribs.get<uint16>(ATTR_ACTION_ID);
213  uint16 uid = m_attribs.get<uint16>(ATTR_UNIQUE_ID);
214  if(aid) {
215  out->addU8(ATTR_ACTION_ID);
216  out->addU16(aid);
217  }
218 
219  if(uid) {
220  out->addU8(ATTR_UNIQUE_ID);
221  out->addU16(uid);
222  }
223 
224  std::string text = getText();
225  if(g_things.getItemType(m_serverId)->isWritable() && !text.empty()) {
226  out->addU8(ATTR_TEXT);
227  out->addString(text);
228  }
229  std::string desc = getDescription();
230  if(!desc.empty()) {
231  out->addU8(ATTR_DESC);
232  out->addString(desc);
233  }
234 
235  out->endNode();
236  for(auto i : m_containerItems)
237  i->serializeItem(out);
238 }
239 
241 {
242  if(isSplash() || isFluidContainer())
243  return m_countOrSubType;
244  if(g_game.getClientVersion() > 862)
245  return 0;
246  return 1;
247 }
248 
250 {
251  if(isStackable())
252  return m_countOrSubType;
253  return 1;
254 }
255 
257 {
258  return !rawGetThingType()->isNotMoveable();
259 }
260 
262 {
263  return rawGetThingType()->isGround();
264 }
265 
267 {
268  ItemPtr item = ItemPtr(new Item);
269  *(item.get()) = *this;
270  return item;
271 }
272 
273 void Item::calculatePatterns(int& xPattern, int& yPattern, int& zPattern)
274 {
275  // Avoid crashes with invalid items
276  if(!isValid())
277  return;
278 
279  if(isStackable() && getNumPatternX() == 4 && getNumPatternY() == 2) {
280  if(m_countOrSubType <= 0) {
281  xPattern = 0;
282  yPattern = 0;
283  } else if(m_countOrSubType < 5) {
284  xPattern = m_countOrSubType-1;
285  yPattern = 0;
286  } else if(m_countOrSubType < 10) {
287  xPattern = 0;
288  yPattern = 1;
289  } else if(m_countOrSubType < 25) {
290  xPattern = 1;
291  yPattern = 1;
292  } else if(m_countOrSubType < 50) {
293  xPattern = 2;
294  yPattern = 1;
295  } else {
296  xPattern = 3;
297  yPattern = 1;
298  }
299  } else if(isHangable()) {
300  const TilePtr& tile = getTile();
301  if(tile) {
302  if(tile->mustHookSouth())
303  xPattern = getNumPatternX() >= 2 ? 1 : 0;
304  else if(tile->mustHookEast())
305  xPattern = getNumPatternX() >= 3 ? 2 : 0;
306  }
307  } else if(isSplash() || isFluidContainer()) {
308  int color = Otc::FluidTransparent;
310  switch(m_countOrSubType) {
311  case Otc::FluidNone:
312  color = Otc::FluidTransparent;
313  break;
314  case Otc::FluidWater:
315  color = Otc::FluidBlue;
316  break;
317  case Otc::FluidMana:
318  color = Otc::FluidPurple;
319  break;
320  case Otc::FluidBeer:
321  color = Otc::FluidBrown;
322  break;
323  case Otc::FluidOil:
324  color = Otc::FluidBrown;
325  break;
326  case Otc::FluidBlood:
327  color = Otc::FluidRed;
328  break;
329  case Otc::FluidSlime:
330  color = Otc::FluidGreen;
331  break;
332  case Otc::FluidMud:
333  color = Otc::FluidBrown;
334  break;
335  case Otc::FluidLemonade:
336  color = Otc::FluidYellow;
337  break;
338  case Otc::FluidMilk:
339  color = Otc::FluidWhite;
340  break;
341  case Otc::FluidWine:
342  color = Otc::FluidPurple;
343  break;
344  case Otc::FluidHealth:
345  color = Otc::FluidRed;
346  break;
347  case Otc::FluidUrine:
348  color = Otc::FluidYellow;
349  break;
350  case Otc::FluidRum:
351  color = Otc::FluidBrown;
352  break;
354  color = Otc::FluidYellow;
355  break;
357  color = Otc::FluidWhite;
358  break;
359  case Otc::FluidTea:
360  color = Otc::FluidBrown;
361  break;
362  case Otc::FluidMead:
363  color = Otc::FluidBrown;
364  break;
365  default:
366  color = Otc::FluidTransparent;
367  break;
368  }
369  } else
370  color = m_countOrSubType;
371 
372  xPattern = (color % 4) % getNumPatternX();
373  yPattern = (color / 4) % getNumPatternY();
374  } else {
375  xPattern = m_position.x % getNumPatternX();
376  yPattern = m_position.y % getNumPatternY();
377  zPattern = m_position.z % getNumPatternZ();
378  }
379 }
380 
382 {
383  if(getAnimationPhases() > 1) {
384  if(animate) {
385  if(getAnimator() != nullptr)
386  return getAnimator()->getPhase();
387 
388  if(m_async)
390  else {
391  if(g_clock.millis() - m_lastPhase >= Otc::ITEM_TICKS_PER_FRAME) {
392  m_phase = (m_phase + 1) % getAnimationPhases();
393  m_lastPhase = g_clock.millis();
394  }
395  return m_phase;
396  }
397  } else
398  return getAnimationPhases()-1;
399  }
400  return 0;
401 }
402 
403 int Item::getExactSize(int layer, int xPattern, int yPattern, int zPattern, int animationPhase)
404 {
405  calculatePatterns(xPattern, yPattern, zPattern);
406  animationPhase = calculateAnimationPhase(true);
407  return Thing::getExactSize(layer, xPattern, yPattern, zPattern, animationPhase);
408 }
409 
411 {
412  return g_things.getThingType(m_clientId, ThingCategoryItem);
413 }
414 
416 {
417  return g_things.rawGetThingType(m_clientId, ThingCategoryItem);
418 }
419 /* vim: set ts=4 sw=4 et :*/
binarytree.h
ThingTypeManager::rawGetThingType
ThingType * rawGetThingType(uint16 id, ThingCategory category)
Definition: thingtypemanager.h:57
Item::Item
Item()
Definition: item.cpp:40
Painter::setColor
virtual void setColor(const Color &color)
Definition: painter.h:77
ATTR_CHARGES
@ ATTR_CHARGES
Definition: item.h:56
thingtypemanager.h
Item::serializeItem
void serializeItem(const OutputBinaryTreePtr &out)
Definition: item.cpp:185
Item::isGround
bool isGround()
Definition: item.cpp:261
eventdispatcher.h
graphics.h
stdext::packed_storage::get
T get(Key id) const
Definition: packed_storage.h:80
Thing::isHangable
bool isHangable()
Definition: thing.h:103
ATTR_ARMOR
@ ATTR_ARMOR
Definition: item.h:64
Color
Definition: color.h:32
ATTR_CONTAINER_ITEMS
@ ATTR_CONTAINER_ITEMS
Definition: item.h:57
Otc::FluidSlime
@ FluidSlime
Definition: const.h:191
ATTR_ARTICLE
@ ATTR_ARTICLE
Definition: item.h:68
Thing::getTile
const TilePtr & getTile()
Definition: thing.cpp:62
ATTR_TEXT
@ ATTR_TEXT
Definition: item.h:40
ATTR_SLEEPSTART
@ ATTR_SLEEPSTART
Definition: item.h:55
Otc::FluidMead
@ FluidMead
Definition: const.h:202
Position::x
int x
Definition: position.h:243
ItemType::isWritable
bool isWritable()
Definition: itemtype.h:153
ATTR_SCRIPTPROTECTED
@ ATTR_SCRIPTPROTECTED
Definition: item.h:69
Position::isValid
bool isValid() const
Definition: position.h:182
Tile::mustHookEast
bool mustHookEast()
Definition: tile.cpp:561
ATTR_ATTACK
@ ATTR_ATTACK
Definition: item.h:60
uint32
uint32_t uint32
Definition: types.h:35
ATTR_COUNT
@ ATTR_COUNT
Definition: item.h:49
ATTR_UNIQUE_ID
@ ATTR_UNIQUE_ID
Definition: item.h:39
Otc::FluidBeer
@ FluidBeer
Definition: const.h:188
ATTR_ACTION_ID
@ ATTR_ACTION_ID
Definition: item.h:38
Otc::FluidTransparent
@ FluidTransparent
Definition: const.h:174
Thing::getAnimator
AnimatorPtr getAnimator()
Definition: thing.h:77
Item::unserializeItem
void unserializeItem(const BinaryTreePtr &in)
Definition: item.cpp:119
Logger::error
void error(const std::string &what)
Definition: logger.h:54
Thing::getAnimationPhases
int getAnimationPhases()
Definition: thing.h:76
Otc::FluidNone
@ FluidNone
Definition: const.h:185
Game::getClientVersion
int getClientVersion()
Definition: game.h:316
Item::getThingType
const ThingTypePtr & getThingType()
Definition: item.cpp:410
ItemType::getName
std::string getName()
Definition: itemtype.h:147
Otc::FluidTea
@ FluidTea
Definition: const.h:201
ATTR_DURATION
@ ATTR_DURATION
Definition: item.h:50
ThingTypeManager::getItemType
const ItemTypePtr & getItemType(uint16 id)
Definition: thingtypemanager.cpp:386
Tile::mustHookSouth
bool mustHookSouth()
Definition: tile.cpp:569
ATTR_TELE_DEST
@ ATTR_TELE_DEST
Definition: item.h:42
Otc::FluidWine
@ FluidWine
Definition: const.h:195
Item::setId
void setId(uint32 id)
Definition: item.cpp:93
g_game
Game g_game
Definition: game.cpp:37
Position::y
int y
Definition: position.h:244
Item::setOtbId
void setOtbId(uint16 id)
Definition: item.cpp:101
stdext::format
std::string format()
Definition: format.h:82
Thing::isFluidContainer
bool isFluidContainer()
Definition: thing.h:96
LightView
Definition: lightview.h:37
Thing::getNumPatternX
int getNumPatternX()
Definition: thing.h:73
Otc::FluidUrine
@ FluidUrine
Definition: const.h:197
ATTR_DECAYING_STATE
@ ATTR_DECAYING_STATE
Definition: item.h:51
Otc::FluidWhite
@ FluidWhite
Definition: const.h:180
clock.h
Thing::m_position
Position m_position
Definition: thing.h:131
ATTR_EXTRAATTACK
@ ATTR_EXTRAATTACK
Definition: item.h:61
Position::z
short z
Definition: position.h:245
uint16
uint16_t uint16
Definition: types.h:36
Otc::ITEM_TICKS_PER_FRAME
@ ITEM_TICKS_PER_FRAME
Definition: const.h:38
Otc::FluidOil
@ FluidOil
Definition: const.h:189
Item::calculatePatterns
void calculatePatterns(int &xPattern, int &yPattern, int &zPattern)
Definition: item.cpp:273
Item::getName
std::string getName()
Definition: item.cpp:65
Item::getDescription
std::string getDescription()
Definition: item.h:118
Thing::isSplash
bool isSplash()
Definition: thing.h:97
Item::isValid
bool isValid()
Definition: item.cpp:114
Item::isHouseDoor
bool isHouseDoor()
Definition: item.h:127
ATTR_RUNE_CHARGES
@ ATTR_RUNE_CHARGES
Definition: item.h:46
houses.h
g_logger
Logger g_logger
Definition: logger.cpp:35
spritemanager.h
container.h
Otc::FluidRum
@ FluidRum
Definition: const.h:198
ThingTypeManager::isValidOtbId
bool isValidOtbId(uint16 id)
Definition: thingtypemanager.h:76
Otc::FluidRed
@ FluidRed
Definition: const.h:176
Position
Definition: position.h:33
Item::draw
void draw(const Point &dest, float scaleFactor, bool animate, LightView *lightView=nullptr)
Definition: item.cpp:70
Item::createFromOtb
static ItemPtr createFromOtb(int id)
Definition: item.cpp:58
Thing::getNumPatternY
int getNumPatternY()
Definition: thing.h:74
ItemType::getServerId
uint16 getServerId()
Definition: itemtype.h:138
ThingTypeManager::findItemTypeByClientId
const ItemTypePtr & findItemTypeByClientId(uint16 id)
Definition: thingtypemanager.cpp:340
Item::getServerId
uint16 getServerId()
Definition: item.h:99
ThingCategoryItem
@ ThingCategoryItem
Definition: thingtype.h:43
Item::setCount
void setCount(int count)
Definition: item.h:90
map.h
ATTR_ATTRIBUTE_MAP
@ ATTR_ATTRIBUTE_MAP
Definition: item.h:71
ThingTypeManager::getThingType
const ThingTypePtr & getThingType(uint16 id, ThingCategory category)
Definition: thingtypemanager.cpp:377
Game::getFeature
bool getFeature(Otc::GameFeature feature)
Definition: game.h:310
Item::clone
ItemPtr clone()
Definition: item.cpp:266
ATTR_WRITTENDATE
@ ATTR_WRITTENDATE
Definition: item.h:52
ATTR_HITCHANCE
@ ATTR_HITCHANCE
Definition: item.h:66
Otc::GameNewFluids
@ GameNewFluids
Definition: const.h:390
ThingType
Definition: thingtype.h:123
ATTR_DESC
@ ATTR_DESC
Definition: item.h:41
Item::calculateAnimationPhase
int calculateAnimationPhase(bool animate)
Definition: item.cpp:381
Item::getSubType
int getSubType()
Definition: item.cpp:240
Otc::FluidBlue
@ FluidBlue
Definition: const.h:175
Item::getText
std::string getText()
Definition: item.h:117
stdext::throw_exception
void throw_exception(const std::string &what)
Throws a generic exception.
Definition: exception.h:43
ATTR_DUALWIELD
@ ATTR_DUALWIELD
Definition: item.h:70
Item::isMoveable
bool isMoveable()
Definition: item.cpp:256
Item::isDepot
bool isDepot()
Definition: item.h:128
Item::create
static ItemPtr create(int id)
Definition: item.cpp:51
Otc::FluidLemonade
@ FluidLemonade
Definition: const.h:193
Otc::FluidHealth
@ FluidHealth
Definition: const.h:196
Otc::FluidMud
@ FluidMud
Definition: const.h:192
ATTR_EXTRADEFENSE
@ ATTR_EXTRADEFENSE
Definition: item.h:63
Item
Definition: item.h:76
filestream.h
Color::alpha
static const Color alpha
Definition: color.h:100
ATTR_DEPOT_ID
@ ATTR_DEPOT_ID
Definition: item.h:44
ATTR_DEFENSE
@ ATTR_DEFENSE
Definition: item.h:62
Otc::FluidCoconutMilk
@ FluidCoconutMilk
Definition: const.h:200
stdext::exception::what
virtual const char * what() const
Definition: exception.h:37
Painter::resetColor
void resetColor()
Definition: painter.h:108
Otc::FluidPurple
@ FluidPurple
Definition: const.h:181
Thing::getNumPatternZ
int getNumPatternZ()
Definition: thing.h:75
stdext::shared_object_ptr< Item >
ThingType::draw
void draw(const Point &dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, LightView *lightView=nullptr)
Definition: thingtype.cpp:374
ThingType::isGround
bool isGround()
Definition: thingtype.h:164
Otc::FluidFruidJuice
@ FluidFruidJuice
Definition: const.h:199
Item::getExactSize
int getExactSize(int layer=0, int xPattern=0, int yPattern=0, int zPattern=0, int animationPhase=0)
Definition: item.cpp:403
Thing::getExactSize
virtual int getExactSize(int layer, int xPattern, int yPattern, int zPattern, int animationPhase)
Definition: thing.h:71
OTBM_ITEM
@ OTBM_ITEM
Definition: map.h:74
ThingType::isNotMoveable
bool isNotMoveable()
Definition: thingtype.h:178
Item::getDoorId
uint8 getDoorId()
Definition: item.h:110
g_painter
Painter * g_painter
Definition: painter.cpp:28
Item::getDepotId
uint16 getDepotId()
Definition: item.h:107
ATTR_SLEEPERGUID
@ ATTR_SLEEPERGUID
Definition: item.h:54
game.h
Clock::millis
ticks_t millis()
Definition: clock.h:37
ATTR_WRITTENBY
@ ATTR_WRITTENBY
Definition: item.h:53
ATTR_NAME
@ ATTR_NAME
Definition: item.h:58
thing.h
stdext::packed_storage::set
void set(Key id, const T &value)
Definition: packed_storage.h:47
TPoint< int >
Item::getCount
int getCount()
Definition: item.cpp:249
tile.h
Otc::FluidMana
@ FluidMana
Definition: const.h:187
Otc::FluidGreen
@ FluidGreen
Definition: const.h:178
ATTR_HOUSEDOORID
@ ATTR_HOUSEDOORID
Definition: item.h:48
g_clock
Clock g_clock
Definition: clock.cpp:25
ItemPtr
stdext::shared_object_ptr< Item > ItemPtr
Definition: declarations.h:61
g_things
ThingTypeManager g_things
Definition: thingtypemanager.cpp:38
Thing::isStackable
bool isStackable()
Definition: thing.h:90
Otc::FluidYellow
@ FluidYellow
Definition: const.h:179
Item::getCountOrSubType
int getCountOrSubType()
Definition: item.h:94
Otc::FluidBlood
@ FluidBlood
Definition: const.h:190
stdext::shared_object_ptr::get
T * get() const
Definition: shared_object.h:82
Otc::FluidMilk
@ FluidMilk
Definition: const.h:194
shadermanager.h
Animator::getPhase
int getPhase()
Definition: animator.cpp:96
ThingTypeManager::isValidDatId
bool isValidDatId(uint16 id, ThingCategory category)
Definition: thingtypemanager.h:75
Otc::FluidBrown
@ FluidBrown
Definition: const.h:177
ATTR_ATTACKSPEED
@ ATTR_ATTACKSPEED
Definition: item.h:65
Item::rawGetThingType
ThingType * rawGetThingType()
Definition: item.cpp:415
stdext::exception
Definition: exception.h:31
item.h
Otc::FluidWater
@ FluidWater
Definition: const.h:186