26 #ifndef SAGA2_OBJECTS_H 27 #define SAGA2_OBJECTS_H 29 #include "saga2/objproto.h" 30 #include "saga2/property.h" 40 const uint16 unlimitedCapacity = maxuint16;
55 kCannotStackOrMerge = 0,
82 #include "common/pack-start.h" 99 uint16 enchantmentType;
100 uint16 generatorFrequency;
112 #include "common/pack-end.h" 117 void cleanupActors();
120 friend void initWorlds();
121 friend void cleanupWorlds();
123 friend void initObjects();
126 friend void cleanupObjects();
128 friend void buildDisplayList();
129 friend void drawDisplayList();
132 friend bool Enchantment(ObjectID, ObjectID);
145 friend class ShopMode;
161 static const char *nameText(uint16 index);
165 static ObjectID *getHeadPtr(ObjectID parentID,
TilePoint &l);
169 void append(ObjectID newParent);
170 void insert(ObjectID newPrev);
195 static GameObject *objectAddress(ObjectID
id);
198 static ProtoObj *protoAddress(ObjectID
id);
201 static int32 nameIndexToID(uint16 ind);
209 void deleteObjectRecursive();
214 return _data.parentID == Nothing ? NULL : objectAddress(_data.parentID);
217 return _data.siblingID == Nothing ? NULL : objectAddress(_data.siblingID);
220 return _data.childID == Nothing ? NULL : objectAddress(_data.childID);
224 ObjectID IDParent() {
225 return _data.parentID ;
228 return _data.siblingID;
231 return _data.childID ;
242 int16 sprNum(int16 state);
245 int32 getSprOffset(int16 num = -1);
252 int16 getChargeType();
255 bool deductCharge(ActorManaID manaID, uint16 manaCost);
258 bool hasCharge(ActorManaID manaID, uint16 manaCost);
261 void setLocation(
const Location &loc);
266 void updateImage(ObjectID);
273 bool moveMerged(
const Location &loc);
274 bool moveMerged(
const Location &loc, int16 num = 1);
279 ObjectID extractMerged(
const Location &loc, int16 num);
288 ObjectID makeAlias(
const Location &loc);
291 void move(int16 slot);
301 return (_data.objectFlags & kObjectAlias) != 0;
305 bool canContain(ObjectID item) {
306 return _prototype->canContain(thisID(), item);
318 return objProp.operator()(
this);
326 bool getAvailableSlot(
329 bool canMerge =
false,
338 bool canMerge =
false,
342 void dropInventoryObject(
GameObject *obj, int16 count = 1);
345 GameObject *getIntangibleContainer(
int containerType);
348 bool use(ObjectID enactor) {
349 return _prototype->use(thisID(), enactor);
351 bool useOn(ObjectID enactor, ObjectID item) {
352 return _prototype->useOn(thisID(), enactor, item);
355 bool useOn(ObjectID enactor,
ActiveItem *item) {
356 return _prototype->useOn(thisID(), enactor, item);
359 bool useOn(ObjectID enactor,
Location &loc) {
360 return _prototype->useOn(thisID(), enactor, loc);
364 bool take(ObjectID enactor, int16 num = 1) {
365 return _prototype->take(thisID(), enactor, num);
367 bool drop(ObjectID enactor,
const Location &l, int16 num = 1) {
368 return _prototype->drop(thisID(), enactor, l, num);
371 bool dropOn(ObjectID enactor, ObjectID target, int16 num = 1) {
372 return _prototype->dropOn(thisID(), enactor, target, num);
375 bool dropOn(ObjectID enactor,
ActiveItem *target,
const Location &loc, int16 num = 1) {
376 return _prototype->dropOn(thisID(), enactor, target, loc, num);
378 bool open(ObjectID enactor) {
379 return _prototype->open(thisID(), enactor);
381 bool close(ObjectID enactor) {
382 return _prototype->close(thisID(), enactor);
384 bool strike(ObjectID enactor, ObjectID item) {
385 return _prototype->strike(thisID(), enactor, item);
387 bool damage(ObjectID enactor, ObjectID target) {
388 return _prototype->damage(thisID(), enactor, target);
390 bool eat(ObjectID enactor) {
391 return _prototype->eat(thisID(), enactor);
393 bool insert(ObjectID enactor, ObjectID item) {
394 return _prototype->insert(thisID(), enactor, item);
396 bool remove(ObjectID enactor) {
397 return _prototype->remove(thisID(), enactor);
399 bool acceptDrop(ObjectID enactor, ObjectID droppedObj,
int count) {
400 return _prototype->acceptDrop(thisID(), enactor, droppedObj, count);
405 effectDamageTypes dType = kDamageOther,
408 int8 perDieMod = 0) {
412 return _prototype->acceptDamage(
421 bool acceptHealing(ObjectID enactor, int8 absDamage, int8 dice = 0, uint8 sides = 1, int8 perDieMod = 0) {
422 return _prototype->acceptHealing(thisID(), enactor, absDamage, dice, sides, perDieMod);
426 ObjectID strikingObj,
428 return _prototype->acceptStrike(
434 bool acceptLockToggle(ObjectID enactor, uint8 keyCode) {
435 return _prototype->acceptLockToggle(thisID(), enactor, keyCode);
437 bool acceptMix(ObjectID enactor, ObjectID mixObj) {
438 return _prototype->acceptMix(thisID(), enactor, mixObj);
440 bool acceptInsertion(ObjectID enactor, ObjectID item, int16 count) {
441 return _prototype->acceptInsertion(thisID(), enactor, item, count);
443 bool acceptInsertionAt(ObjectID enactor, ObjectID item,
const TilePoint &where, int16 num = 1) {
444 return _prototype->acceptInsertionAt(thisID(), enactor, item, where, num);
448 ObjectID possessor();
455 return _data.location;
458 bool getWorldLocation(
Location &loc);
463 const char *objName() {
464 if (_data.nameIndex > 0)
465 return nameText((int16)_data.nameIndex);
467 return nameText((int16)_prototype->nameIndex);
473 void objCursorText(
char nameBuf[],
const int8 size, int16 count = -1);
479 uint16 getNameIndex() {
480 return _data.nameIndex;
482 void setNameIndex(uint16 n) {
487 const char *protoName() {
488 return nameText(_prototype->nameIndex);
497 return (int16)(_data.objectFlags & kObjectOpen);
500 return (int16)(_data.objectFlags & kObjectLocked);
503 return (int16)(_data.objectFlags & kObjectImportant);
506 return (_data.objectFlags & kObjectGhosted)
507 || (_prototype->flags & ResourceObjectPrototype::kObjPropGhosted);
510 return (_data.objectFlags & kObjectInvisible)
511 || (_prototype->flags & ResourceObjectPrototype::kObjPropHidden);
514 return (int16)(_data.objectFlags & kObjectMoving);
517 return (int16)(_data.objectFlags & kObjectActivated);
520 void setScavengable(
bool val) {
522 _data.objectFlags |= kObjectScavengable;
524 _data.objectFlags &= ~kObjectScavengable;
526 bool isScavengable() {
527 return (_data.objectFlags & kObjectScavengable) != 0;
530 void setObscured(
bool val) {
532 _data.objectFlags |= kObjectObscured;
534 _data.objectFlags &= ~kObjectObscured;
537 return (_data.objectFlags & kObjectObscured) != 0;
540 void setTriggeringTAG(
bool val) {
542 _data.objectFlags |= kObjectTriggeringTAG;
544 _data.objectFlags &= ~kObjectTriggeringTAG;
546 bool isTriggeringTAG() {
547 return (_data.objectFlags & kObjectTriggeringTAG) != 0;
550 void setOnScreen(
bool val) {
552 _data.objectFlags |= kObjectOnScreen;
554 _data.objectFlags &= ~kObjectOnScreen;
557 return (_data.objectFlags & kObjectOnScreen) != 0;
560 void setSightedByCenter(
bool val) {
562 _data.objectFlags |= kObjectSightedByCenter;
564 _data.objectFlags &= ~kObjectSightedByCenter;
566 bool isSightedByCenter() {
567 return (_data.objectFlags & kObjectSightedByCenter) != 0;
571 return _prototype->isMissile();
576 Sprite *getGroundSprite();
579 uint16 containmentSet();
581 uint16 scriptClass() {
585 return _prototype->script;
595 void setScript(uint16 scr) {
600 void setFlags(uint8 newval, uint8 changeMask) {
602 _data.objectFlags = (newval & changeMask)
603 | (_data.objectFlags & ~changeMask);
607 uint8 getHitPoints() {
608 return _data.hitPoints;
610 void setHitPoints(uint8 hp) {
611 _data.hitPoints = hp;
616 void getColorTranslation(ColorTable map) {
617 _prototype->getColorTranslation(map);
622 void setProtoNum(int32 nProto);
626 return _data.massCount;
628 void setExtra(uint16 x) {
633 void evalEnchantments();
635 bool makeSavingThrow() {
636 return _prototype->makeSavingThrow();
640 bool inRange(
const TilePoint &tp, uint16 range);
644 return _prototype->mass <= 200 && _prototype->bulk <= 200;
648 return (_prototype->flags & ResourceObjectPrototype::kObjPropMergeable) != 0;
652 void timerTick(TimerID timer);
655 void senseObject(SensorID sensor, ObjectID sensedObj);
661 ObjectID directObject,
662 ObjectID indirectObject);
665 bool addTimer(TimerID
id);
666 bool addTimer(TimerID
id, int16 frameInterval);
667 void removeTimer(TimerID
id);
668 void removeAllTimers();
672 bool addSensor(
Sensor *newSensor);
674 bool addProtaganistSensor(SensorID
id, int16 range);
675 bool addSpecificActorSensor(SensorID
id, int16 range,
Actor *a);
676 bool addSpecificObjectSensor(SensorID
id, int16 range, ObjectID obj);
677 bool addActorPropertySensor(
680 ActorPropertyID prop);
681 bool addObjectPropertySensor(
684 ObjectPropertyID prop);
685 bool addEventSensor(SensorID
id, int16 range, int16 eventType);
686 void removeSensor(SensorID
id);
687 void removeAllSensors();
689 bool canSenseProtaganist(
SenseInfo &info, int16 range);
690 bool canSenseSpecificActor(
SenseInfo &info, int16 range,
Actor *a);
691 bool canSenseSpecificObject(
SenseInfo &info, int16 range, ObjectID obj);
692 bool canSenseActorProperty(
695 ActorPropertyID prop);
696 bool canSenseObjectProperty(
699 ObjectPropertyID prop);
704 bool merge(ObjectID enactor, ObjectID objToMergeID, int16 count);
705 bool stack(ObjectID enactor, ObjectID objToStackID);
708 return _prototype->canFitBulkwise(
this, obj);
711 return _prototype->canFitMasswise(
this, obj);
714 uint16 totalContainedMass();
715 uint16 totalContainedBulk();
718 return _prototype->mass * (isMergeable() ? getExtra() : 1)
719 + totalContainedMass();
722 return _prototype->bulk * (isMergeable() ? getExtra() : 1);
725 uint16 massCapacity() {
726 return _prototype->massCapacity(
this);
728 uint16 bulkCapacity() {
729 return _prototype->bulkCapacity(
this);
739 uint16 _activationCount;
748 return _activationCount != 0;
770 friend void initWorlds();
771 friend void cleanupWorlds();
772 friend void buildDisplayList();
780 int16 _sectorArraySize;
785 GameWorld() : _sectorArraySize(0), _sectorArray(
nullptr), _mapNum(0) {}
798 Sector *getSector(int16 u, int16 v) {
799 if (u == -1 && v == -1)
802 if (v * _sectorArraySize + u >= _sectorArraySize * _sectorArraySize ||
803 v * _sectorArraySize + u < 0) {
804 warning(
"Sector::getSector: Invalid sector: (%d, %d) (sectorArraySize = %d)", u, v, _sectorArraySize);
808 return &(_sectorArray)[v * _sectorArraySize + u];
812 return TilePoint(_sectorArraySize, _sectorArraySize, 0);
815 static uint32 IDtoMapNum(ObjectID
id) {
817 return ((
GameWorld *)GameObject::objectAddress(
id))->_mapNum;
821 void setCurrentWorld(ObjectID worldID);
832 inline int16 GameObject::getMapNum() {
834 return world()->_mapNum;
835 else if (_data.siblingID) {
836 GameObject *sibling = GameObject::objectAddress(_data.siblingID);
837 return sibling->getMapNum();
839 return currentWorld->_mapNum;
859 friend void initActiveRegions();
860 friend void cleanupActiveRegions();
872 kActiveRegionSize = 22
885 tReg.min.u = _region.min.u << kSectorShift;
886 tReg.min.v = _region.min.v << kSectorShift;
887 tReg.max.u = _region.max.u << kSectorShift;
888 tReg.max.v = _region.max.v << kSectorShift;
889 tReg.min.z = tReg.max.z = 0;
896 return (
GameWorld *)GameObject::objectAddress(_worldID);
900 void updateActiveRegions();
905 void initActiveRegions();
908 inline void cleanupActiveRegions() {}
951 _minSector(sectorRegion.min),
952 _maxSector(sectorRegion.max),
953 _currentObject(
nullptr) {
954 assert(_searchWorld != NULL);
955 assert(isWorld(_searchWorld));
991 virtual int16 computeDist(
const TilePoint &tp) = 0;
1009 computeSectorRegion(
1010 world->sectorSize(),
1013 _center(searchCenter),
1018 ObjectID first(
GameObject **obj, int16 *dist);
1020 ObjectID next(
GameObject **obj, int16 *dist);
1024 return first(obj, NULL);
1028 return next(obj, NULL);
1070 int16 outerDistance,
1071 int16 innerDistance) :
1073 _innerDist = innerDistance;
1132 computeSectorRegion(world->sectorSize(), min, max)),
1215 MaxCenterRegion()) {}
1225 int16 _activeRegionIndex;
1229 uint8 _sectorBitMask;
1233 bool firstActiveRegion();
1234 bool nextActiveRegion();
1280 _root(container->thisID()), _id(0) {}
1292 uint8 soundFXHitFlesh,
1305 enum MissileFacings {
1343 uint32 terrainMask);
1352 ObjectID EnchantObject(
1354 int enchantmentType,
1358 ObjectID FindObjectEnchantment(
1360 int enchantmentType);
1363 bool DispelObjectEnchantment(
1365 int enchantmentType);
1368 void evalActorEnchantments(
Actor *a);
1371 void evalObjectEnchantments(
GameObject *obj);
1374 void initPrototypes();
1377 void cleanupPrototypes();
1380 void initObjectSoundFXTable();
1383 void cleanupObjectSoundFXTable();
1386 void initTempActorCount();
1395 void cleanupTempActorCount();
1398 void incTempActorCount(uint16 protoNum);
1401 void decTempActorCount(uint16 protoNum);
1404 uint16 getTempActorCount(uint16 protoNum);
1416 void cleanupWorlds();
1428 void cleanupObjects();
1431 void doBackgroundSimulation();
1433 void pauseBackgroundSimulation();
1434 void resumeBackgroundSimulation();
1438 void updateObjectStates();
1440 void pauseObjectStates();
1441 void resumeObjectStates();
1443 void readyContainerSetup();
1444 void cleanupReadyContainers();
Definition: objproto.h:371
Definition: objproto.h:105
Definition: objects.h:917
Definition: objects.h:1109
Definition: contain.h:302
Definition: savefile.h:54
void warning(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: idtypes.h:124
Definition: objects.h:1060
Definition: objproto.h:880
Definition: objproto.h:1542
Definition: memstream.h:194
Definition: tcoords.h:127
Definition: objects.h:1148
Definition: objects.h:1178
Definition: tcoords.h:222
Out copy(In first, In last, Out dst)
Definition: algorithm.h:52
Definition: contain.h:313
Definition: objects.h:934
Definition: objects.h:1273
Definition: objproto.h:798
Definition: objects.h:768
Definition: objects.h:118
Out move(In first, In last, Out dst)
Definition: algorithm.h:109
Definition: objects.h:1204
Definition: objects.h:1253
Definition: objects.h:1087
Definition: objects.h:1291
Definition: objects.h:976
Definition: objects.h:857
Definition: objects.h:1223
Definition: objproto.h:1493
Definition: property.h:45
Definition: objproto.h:902
Definition: objects.h:1038
Definition: objects.h:737