00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef ITEM_H
00020 #define ITEM_H
00021
00022 #include "Object.h"
00023 #include "ShapeInfo.h"
00024
00025 #include "intrinsics.h"
00026 #include "Box.h"
00027 class Container;
00028 class ShapeInfo;
00029 class Shape;
00030 class Gump;
00031 class ODataSource;
00032 class GravityProcess;
00033
00034 class Item : public Object
00035 {
00036 friend class ItemFactory;
00037
00038 public:
00039 Item();
00040 virtual ~Item();
00041
00042
00043 ENABLE_RUNTIME_CLASSTYPE();
00044
00046 ObjId getParent() const { return parent; }
00047
00049 void setParent(ObjId p) { parent = p; }
00050
00052 Container *getParentAsContainer() const;
00053
00056 Item* getTopItem();
00057
00060 void setLocation(sint32 x, sint32 y, sint32 z);
00061
00064 void move(sint32 x, sint32 y, sint32 z);
00065
00070 bool moveToContainer(Container *container, bool checkwghtvol=false);
00071
00073 void moveToEtherealVoid();
00074
00076 void returnFromEtherealVoid();
00077
00079 void movedByPlayer();
00080
00083 void getLocationAbsolute(sint32& x, sint32& y, sint32& z) const;
00084
00087 inline void getLocation(sint32& x, sint32& y, sint32& z) const;
00088
00090 sint32 getZ() const;
00091
00093 void setZ(sint32 z_) { z = z_; }
00094
00097 void getGumpLocation(sint32& x, sint32& y) const;
00098
00101 void setGumpLocation(sint32 x, sint32 y);
00102
00106 void randomGumpLocation();
00107
00110 void getCentre(sint32& x, sint32& y, sint32& z) const;
00111
00113 inline void getFootpadWorld(sint32& x, sint32& y, sint32& z) const;
00114
00117 inline void getFootpadData(sint32& x, sint32& y, sint32& z) const;
00118
00120 Pentagram::Box getWorldBox() const;
00121
00123 inline uint16 getFlags() const { return flags; }
00124
00126 void setFlag(uint32 mask) { flags |= mask; }
00127
00128 virtual void setFlagRecursively(uint32 mask) { setFlag(mask); }
00129
00131 void clearFlag(uint32 mask) { flags &= ~mask; }
00132
00134 void setExtFlags(uint32 f) { extendedflags = f; }
00135
00137 inline uint32 getExtFlags() const { return extendedflags; }
00138
00140 void setExtFlag(uint32 mask) { extendedflags |= mask; }
00141
00143 void clearExtFlag(uint32 mask) { extendedflags &= ~mask; }
00144
00146 uint32 getShape() const { return shape; }
00147
00149 void setShape(uint32 shape_)
00150 { shape = shape_; cachedShapeInfo = 0; cachedShape = 0; }
00151
00153 uint32 getFrame() const { return frame; }
00154
00156 void setFrame(uint32 frame_) { frame = frame_; }
00157
00159 uint16 getQuality() const { return quality; }
00160
00162 void setQuality(uint16 quality_) { quality = quality_; }
00163
00166 uint16 getNpcNum() const { return npcnum; }
00167
00170 void setNpcNum(uint16 npcnum_) { npcnum = npcnum_; }
00171
00174 uint16 getMapNum() const { return mapnum; }
00175
00178 void setMapNum(uint16 mapnum_) { mapnum = mapnum_; }
00179
00181 inline ShapeInfo* getShapeInfo() const;
00182
00184 ShapeInfo* getShapeInfoFromGameInstance() const;
00185
00187 Shape* getShapeObject() const;
00188
00191 uint16 getFamily();
00192
00194 bool canMergeWith(Item* other);
00195
00197 ObjId getGump() { return gump; }
00199 void clearGump();
00201 ObjId openGump(uint32 gumpshape);
00203 void closeGump();
00204
00206 virtual void destroy(bool delnow = false);
00207
00209 bool overlaps(Item& item2) const;
00210
00212 bool overlapsxy(Item& item2) const;
00213
00215 bool isOn(Item& item2) const;
00216
00218 bool canExistAt(sint32 x,sint32 y,sint32 z, bool needsupport=false) const;
00219
00222 int getDirToItemCentre(Item& item2) const;
00223
00226 int getRange(Item& item2, bool checkz=false) const;
00227
00234 bool canReach(Item* other, int range, sint32 x=0, sint32 y=0, sint32 z=0);
00235
00247 sint32 collideMove(sint32 x,sint32 y,sint32 z, bool teleport, bool force,
00248 ObjId* hititem=0);
00249
00256 sint32 ascend(int delta);
00257
00261 void fall();
00262
00267 void grab();
00268
00270 void hurl(int xs, int ys, int zs, int grav);
00271
00273 void setGravityPID(ProcId pid) { gravitypid = pid; }
00274
00276 ProcId getGravityPID() const { return gravitypid; }
00277
00279 virtual GravityProcess* ensureGravityProcess();
00280
00282 virtual uint32 getWeight();
00283
00285 virtual uint32 getTotalWeight();
00286
00288 virtual uint32 getVolume();
00289
00291 void explode();
00292
00294 virtual uint16 getDamageType();
00295
00301 virtual void receiveHit(ObjId other, int dir, int damage, uint16 type);
00302
00304 unsigned int countNearby(uint32 shape, uint16 range);
00305
00307 bool canDrag();
00308
00311 int getThrowRange();
00312
00317 bool checkLoopScript(const uint8* script, uint32 scriptsize);
00318
00319 uint32 callUsecodeEvent_look();
00320 uint32 callUsecodeEvent_use();
00321 uint32 callUsecodeEvent_anim();
00322 uint32 callUsecodeEvent_cachein();
00323 uint32 callUsecodeEvent_hit(ObjId hitted, sint16 hitforce);
00324 uint32 callUsecodeEvent_gotHit(ObjId hitter, sint16 hitforce);
00325 uint32 callUsecodeEvent_hatch();
00326 uint32 callUsecodeEvent_schedule(uint32 time);
00327 uint32 callUsecodeEvent_release();
00328 uint32 callUsecodeEvent_combine();
00329 uint32 callUsecodeEvent_enterFastArea();
00330 uint32 callUsecodeEvent_leaveFastArea();
00331 uint32 callUsecodeEvent_cast(uint16 unk);
00332 uint32 callUsecodeEvent_justMoved();
00333 uint32 callUsecodeEvent_AvatarStoleSomething(uint16 unk);
00334 uint32 callUsecodeEvent_guardianBark(sint16 unk);
00335
00336 uint32 use();
00337
00339 inline void getLerped(sint32& x, sint32& y, sint32& z) const
00340 { x = ix; y = iy; z = iz; }
00341
00345 inline void doLerp(sint32 factor)
00346 {
00347
00348
00349
00350 if (factor == 256)
00351 {
00352 ix = l_next.x;
00353 iy = l_next.y;
00354 iz = l_next.z;
00355 }
00356 else if (factor == 0)
00357 {
00358 ix = l_prev.x;
00359 iy = l_prev.y;
00360 iz = l_prev.z;
00361 }
00362 else
00363 {
00364 #if 1
00365
00366 ix = ((l_prev.x*(256-factor) + l_next.x*factor)>>8);
00367 iy = ((l_prev.y*(256-factor) + l_next.y*factor)>>8);
00368 iz = ((l_prev.z*(256-factor) + l_next.z*factor)>>8);
00369 #else
00370 ix = l_prev.x + (((l_next.x-l_prev.x)*factor)>>8);
00371 iy = l_prev.y + (((l_next.y-l_prev.y)*factor)>>8);
00372 iz = l_prev.z + (((l_next.z-l_prev.z)*factor)>>8);
00373 #endif
00374 }
00375 }
00376
00378 void setupLerp(sint32 gametick);
00379
00381 virtual void enterFastArea();
00382
00385 virtual void leaveFastArea();
00386
00388 virtual void dumpInfo();
00389
00390 bool loadData(IDataSource* ids, uint32 version);
00391
00392
00393 INTRINSIC(I_touch);
00394 INTRINSIC(I_getX);
00395 INTRINSIC(I_getY);
00396 INTRINSIC(I_getZ);
00397 INTRINSIC(I_getCX);
00398 INTRINSIC(I_getCY);
00399 INTRINSIC(I_getCZ);
00400 INTRINSIC(I_getPoint);
00401 INTRINSIC(I_getShape);
00402 INTRINSIC(I_setShape);
00403 INTRINSIC(I_getFrame);
00404 INTRINSIC(I_setFrame);
00405 INTRINSIC(I_getQuality);
00406 INTRINSIC(I_getUnkEggType);
00407 INTRINSIC(I_getQuantity);
00408 INTRINSIC(I_getContainer);
00409 INTRINSIC(I_getRootContainer);
00410 INTRINSIC(I_getQ);
00411 INTRINSIC(I_getQHi);
00412 INTRINSIC(I_getQLo);
00413 INTRINSIC(I_setQ);
00414 INTRINSIC(I_setQHi);
00415 INTRINSIC(I_setQLo);
00416 INTRINSIC(I_setQuality);
00417 INTRINSIC(I_setQuantity);
00418 INTRINSIC(I_getFamily);
00419 INTRINSIC(I_getTypeFlag);
00420 INTRINSIC(I_getStatus);
00421 INTRINSIC(I_orStatus);
00422 INTRINSIC(I_andStatus);
00423 INTRINSIC(I_getFootpadData);
00424 INTRINSIC(I_overlaps);
00425 INTRINSIC(I_overlapsXY);
00426 INTRINSIC(I_isOn);
00427 INTRINSIC(I_ascend);
00428 INTRINSIC(I_getWeight);
00429 INTRINSIC(I_getWeightIncludingContents);
00430 INTRINSIC(I_getVolume);
00431 INTRINSIC(I_bark);
00432 INTRINSIC(I_getMapArray);
00433 INTRINSIC(I_setMapArray);
00434 INTRINSIC(I_getNpcNum);
00435 INTRINSIC(I_getDirToCoords);
00436 INTRINSIC(I_getDirFromCoords);
00437 INTRINSIC(I_getDirToItem);
00438 INTRINSIC(I_getDirFromItem);
00439 INTRINSIC(I_look);
00440 INTRINSIC(I_use);
00441 INTRINSIC(I_gotHit);
00442 INTRINSIC(I_enterFastArea);
00443 INTRINSIC(I_ask);
00444 INTRINSIC(I_getSliderInput);
00445 INTRINSIC(I_openGump);
00446 INTRINSIC(I_closeGump);
00447 INTRINSIC(I_create);
00448 INTRINSIC(I_legalCreateAtPoint);
00449 INTRINSIC(I_legalCreateAtCoords);
00450 INTRINSIC(I_legalCreateInCont);
00451 INTRINSIC(I_push);
00452 INTRINSIC(I_pop);
00453 INTRINSIC(I_popToCoords);
00454 INTRINSIC(I_popToContainer);
00455 INTRINSIC(I_popToEnd);
00456 INTRINSIC(I_destroy);
00457 INTRINSIC(I_move);
00458 INTRINSIC(I_legalMoveToPoint);
00459 INTRINSIC(I_legalMoveToContainer);
00460 INTRINSIC(I_hurl);
00461 INTRINSIC(I_shoot);
00462 INTRINSIC(I_fall);
00463 INTRINSIC(I_grab);
00464 INTRINSIC(I_igniteChaos);
00465 INTRINSIC(I_getFamilyOfType);
00466 INTRINSIC(I_getEtherealTop);
00467 INTRINSIC(I_guardianBark);
00468 INTRINSIC(I_getSurfaceWeight);
00469 INTRINSIC(I_isExplosive);
00470 INTRINSIC(I_receiveHit);
00471 INTRINSIC(I_explode);
00472 INTRINSIC(I_canReach);
00473 INTRINSIC(I_getRange);
00474 INTRINSIC(I_isCrusTypeNPC);
00475
00476 private:
00477 uint32 shape;
00478
00479 protected:
00480 uint32 frame;
00481
00482 sint32 x,y,z;
00483 uint16 flags;
00484 uint16 quality;
00485 uint16 npcnum;
00486 uint16 mapnum;
00487
00488 uint32 extendedflags;
00489
00490 ObjId parent;
00491
00492 mutable Shape *cachedShape;
00493 mutable ShapeInfo *cachedShapeInfo;
00494
00495
00496 struct Lerped
00497 {
00498 sint32 x,y,z;
00499 uint32 shape,frame;
00500 };
00501
00502 Lerped l_prev;
00503 Lerped l_next;
00504 sint32 ix,iy,iz;
00505
00506 ObjId gump;
00507 ProcId gravitypid;
00508
00510 virtual void saveData(ODataSource* ods);
00511
00512 private:
00513
00515 uint32 callUsecodeEvent(uint32 event, const uint8* args=0, int argsize=0);
00516
00518 sint32 last_setup;
00519
00521 void animateItem();
00522
00523 public:
00524 enum statusflags {
00525 FLG_DISPOSABLE = 0x0002,
00526 FLG_OWNED = 0x0004,
00527 FLG_CONTAINED = 0x0008,
00528 FLG_INVISIBLE = 0x0010,
00529 FLG_FLIPPED = 0x0020,
00530 FLG_IN_NPC_LIST = 0x0040,
00531 FLG_FAST_ONLY = 0x0080,
00532 FLG_GUMP_OPEN = 0x0100,
00533 FLG_EQUIPPED = 0x0200,
00534 FLG_BOUNCING = 0x0400,
00535 FLG_ETHEREAL = 0x0800,
00536 FLG_HANGING = 0x1000,
00537 FLG_FASTAREA = 0x2000,
00538 FLG_LOW_FRICTION = 0x4000
00539 };
00540
00541 enum extflags {
00542 EXT_FIXED = 0x0001,
00543 EXT_INCURMAP = 0x0002,
00544 EXT_LERP_NOPREV = 0x0008,
00545 EXT_HIGHLIGHT = 0x0010,
00546 EXT_CAMERA = 0x0020,
00547 EXT_SPRITE = 0x0040,
00548 EXT_TRANSPARENT = 0x0080,
00549 EXT_PERMANENT_NPC= 0x0100
00550 };
00551 };
00552
00553 inline ShapeInfo* Item::getShapeInfo() const
00554 {
00555 if (!cachedShapeInfo)
00556 cachedShapeInfo = getShapeInfoFromGameInstance();
00557 return cachedShapeInfo;
00558 }
00559
00560 inline void Item::getFootpadData(sint32& X, sint32& Y, sint32& Z) const
00561 {
00562 ShapeInfo* si = getShapeInfo();
00563 Z = si->z;
00564
00565 if (flags & Item::FLG_FLIPPED) {
00566 X = si->y;
00567 Y = si->x;
00568 } else {
00569 X = si->x;
00570 Y = si->y;
00571 }
00572 }
00573
00574
00575 inline void Item::getFootpadWorld(sint32& X, sint32& Y, sint32& Z) const
00576 {
00577 ShapeInfo* si = getShapeInfo();
00578 Z = si->z * 8;
00579
00580 if (flags & Item::FLG_FLIPPED) {
00581 X = si->y * 32;
00582 Y = si->x * 32;
00583 } else {
00584 X = si->x * 32;
00585 Y = si->y * 32;
00586 }
00587 }
00588
00589 inline void Item::getLocation(sint32& X, sint32& Y, sint32& Z) const
00590 {
00591 X = x;
00592 Y = y;
00593 Z = z;
00594 }
00595
00596 #endif