aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfusion32 <marcopuzziello@gmail.com>2025-06-12 04:16:16 -0300
committerfusion32 <marcopuzziello@gmail.com>2025-06-12 04:17:13 -0300
commit7d298e5a4119df0910daa070af1d23567a83e90c (patch)
tree93bd46dec5b74186db806d61b66c2115065224fc
parent05ec30b99472e8c17cd33c29d0e7859e02dc9fc8 (diff)
downloadgame-7d298e5a4119df0910daa070af1d23567a83e90c.tar.gz
game-7d298e5a4119df0910daa070af1d23567a83e90c.zip
more work on `operate.cc`
-rw-r--r--Makefile2
-rw-r--r--reference/game.c445
-rw-r--r--src/cract.cc6
-rw-r--r--src/info.cc4
-rw-r--r--src/operate.cc210
5 files changed, 203 insertions, 464 deletions
diff --git a/Makefile b/Makefile
index 88234fe..3569eba 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ endif
HEADERS = $(SRCDIR)/common.hh $(SRCDIR)/config.hh $(SRCDIR)/connection.hh $(SRCDIR)/containers.hh $(SRCDIR)/cr.hh $(SRCDIR)/enums.hh $(SRCDIR)/info.hh $(SRCDIR)/magic.hh $(SRCDIR)/map.hh $(SRCDIR)/objects.hh $(SRCDIR)/operate.hh $(SRCDIR)/script.hh $(SRCDIR)/stubs.hh $(SRCDIR)/thread.hh
$(BUILDDIR)/$(OUTPUTEXE): $(BUILDDIR)/config.obj $(BUILDDIR)/cract.obj $(BUILDDIR)/crcombat.obj $(BUILDDIR)/crmain.obj $(BUILDDIR)/crplayer.obj $(BUILDDIR)/crskill.obj $(BUILDDIR)/info.obj $(BUILDDIR)/magic.obj $(BUILDDIR)/main.obj $(BUILDDIR)/map.obj $(BUILDDIR)/objects.obj $(BUILDDIR)/operate.obj $(BUILDDIR)/script.obj $(BUILDDIR)/shm.obj $(BUILDDIR)/strings.obj $(BUILDDIR)/thread.obj $(BUILDDIR)/time.obj $(BUILDDIR)/util.obj
- $(CC) -c $(CFLAGS) $(LFLAGS) -o $@ $^
+ echo $(CC) $(CFLAGS) $(LFLAGS) -o $@ $^
$(BUILDDIR)/config.obj: $(SRCDIR)/config.cc $(HEADERS)
@mkdir -p $(@D)
diff --git a/reference/game.c b/reference/game.c
index 3686e32..b68c771 100644
--- a/reference/game.c
+++ b/reference/game.c
@@ -18375,451 +18375,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority
return;
}
-void CheckTopMultiuseObject(ulong CreatureID,Object *Obj)
-
-{
- bool bVar1;
- bool bVar2;
- undefined4 *puVar3;
- Object *pOVar4;
- Object local_7c [4];
- Object local_6c [4];
- Object local_5c [4];
- Object local_4c;
- Object Help;
- Object local_3c;
- Object Best;
- Object local_2c;
- Object Con;
-
- // try { // try from 0808f2cb to 0808f4eb has its CatchHandler @ 0808f503
- bVar1 = Object::exists(Obj);
- if (!bVar1) {
- error("CheckTopMultiuseObject: Objekt existiert nicht.\n");
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0xffffffff;
-LAB_0808f43d:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,&RESULT::typeinfo,0);
- }
- if ((CreatureID != 0) && (bVar1 = IsCreaturePlayer(CreatureID), bVar1)) {
- Object::getContainer(&local_2c);
- Object::getObjectType(&local_3c);
- if (local_3c.ObjectID == 0) {
- pOVar4 = local_5c;
- local_3c.ObjectID = NONE.ObjectID;
- local_5c[0].ObjectID = local_2c.ObjectID;
- GetFirstContainerObject(&local_4c);
- local_5c[0].ObjectID = NONE.ObjectID;
- if (local_4c.ObjectID != NONE.ObjectID) {
- do {
- local_6c[0].ObjectID = NONE.ObjectID;
- bVar1 = false;
- local_5c[0].ObjectID = NONE.ObjectID;
- if (local_3c.ObjectID == NONE.ObjectID) {
-LAB_0808f36d:
- bVar1 = true;
- }
- else {
- Object::getObjectType(local_5c);
- bVar2 = ObjectType::getFlag((ObjectType *)local_5c,LIQUIDPOOL);
- if (!bVar2) goto LAB_0808f36d;
- }
- if (bVar1) {
- local_7c[0].ObjectID = local_4c.ObjectID;
- local_3c.ObjectID = local_4c.ObjectID;
- local_5c[0].ObjectID = local_4c.ObjectID;
- }
- Object::getObjectType(local_7c);
- pOVar4 = (Object *)0x9;
- bVar1 = ObjectType::getFlag((ObjectType *)local_7c,FORCEUSE);
- if (bVar1) break;
- Object::getObjectType(local_7c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_7c,BANK);
- if (!bVar1) {
- Object::getObjectType(local_7c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_7c,CLIP);
- if (!bVar1) {
- Object::getObjectType(local_7c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_7c,BOTTOM);
- if (!bVar1) {
- Object::getObjectType(local_7c);
- pOVar4 = (Object *)0x3;
- bVar1 = ObjectType::getFlag((ObjectType *)local_7c,TOP);
- if (!bVar1) break;
- }
- }
- }
- pOVar4 = &local_4c;
- Object::getNextObject(local_6c);
- local_7c[0].ObjectID = local_6c[0].ObjectID;
- local_4c.ObjectID = local_6c[0].ObjectID;
- local_5c[0].ObjectID = NONE.ObjectID;
- } while (local_6c[0].ObjectID != NONE.ObjectID);
- }
- local_7c[0].ObjectID = local_3c.ObjectID;
- local_6c[0].ObjectID = local_3c.ObjectID;
- if (Obj->ObjectID != local_3c.ObjectID) {
- puVar3 = (undefined4 *)__cxa_allocate_exception(4,pOVar4);
- *puVar3 = 1;
- goto LAB_0808f43d;
- }
- }
- }
- return;
-}
-
-
-
-void CheckMoveObject(ulong CreatureID,Object *Obj,bool Take)
-
-{
- bool bVar1;
- undefined4 *puVar2;
- ulong uVar3;
- TCreature *pTVar4;
- int iVar5;
- Object *pOVar6;
- Object OStack_2c;
- bool Take_local;
-
- if (CreatureID == 0) {
- return;
- }
- OStack_2c = (Object)Obj->ObjectID;
- // try { // try from 0808f567 to 0808f674 has its CatchHandler @ 0808f6a7
- bVar1 = ObjectAccessible(CreatureID,&stack0xffffffd4,1);
- if (!bVar1) {
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 1;
- goto LAB_0808f5ef;
- }
- Object::getObjectType(&stack0xffffffd4);
- bVar1 = ObjectType::getFlag((ObjectType *)&stack0xffffffd4,UNMOVE);
- if (!bVar1) {
- pOVar6 = Obj;
- Object::getObjectType(&stack0xffffffd4);
- if ((OStack_2c.ObjectID == 99) && (uVar3 = Object::getCreatureID(Obj), uVar3 != CreatureID))
- {
- OStack_2c = (Object)Obj->ObjectID;
- pTVar4 = GetCreature(&stack0xffffffd4);
- if (pTVar4 == (TCreature *)0x0) {
- error("CheckMoveObject: Kreatur existiert nicht.\n",pOVar6);
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0xffffffff;
- goto LAB_0808f5ef;
- }
- bVar1 = GetRaceUnpushable(pTVar4->Race);
- if ((bVar1) &&
- ((WorldType != NON_PVP ||
- (iVar5 = (*pTVar4->_vptr_TCreature[4])(pTVar4), (char)iVar5 == '\0'))))
- goto LAB_0808f655;
- }
- if (Take) {
- Object::getObjectType(&stack0xffffffd4);
- bVar1 = ObjectType::getFlag((ObjectType *)&stack0xffffffd4,TAKE);
- if (!bVar1) {
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 3;
- goto LAB_0808f5ef;
- }
- }
- return;
- }
-LAB_0808f655:
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 2;
-LAB_0808f5ef:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,&RESULT::typeinfo,0);
-}
-
-
-
-void CheckMapDestination(ulong CreatureID,Object *Obj,Object *MapCon)
-
-{
- bool bVar1;
- bool bVar2;
- TCreature *pTVar3;
- uint uVar4;
- int iVar5;
- undefined4 *puVar6;
- int *piVar7;
- int iVar8;
- Object *pOVar9;
- Object *pOVar10;
- int iVar11;
- int iVar12;
- int *y_00;
- int *z_00;
- undefined4 uVar13;
- TCreature *cr_1;
- TCreature *cr;
- int local_44;
- int sx;
- int sy;
- int sz;
- int x;
- int y;
- int z;
-
- if (CreatureID == 0) {
- return;
- }
- z = MapCon->ObjectID;
- // try { // try from 0808f713 to 0808fe64 has its CatchHandler @ 0808fe78
- GetObjectCoordinates((Object *)&z,&sz,&x,&y);
- Object::getObjectType((Object *)&z);
- piVar7 = (int *)y;
- if (z != 99) {
- bVar1 = false;
- z_00 = (int *)0x0;
- y_00 = (int *)y;
- bVar2 = CoordinateFlag();
- if (bVar2) {
- z_00 = (int *)0x20;
- bVar1 = CoordinateFlag();
- bVar1 = !bVar1;
- y_00 = piVar7;
- }
- if (bVar1) goto LAB_0808f731;
- Object::getObjectType((Object *)&z);
- pOVar9 = (Object *)0x20;
- bVar1 = ObjectType::getFlag((ObjectType *)&z,UNPASS);
- if (!bVar1) {
- bVar1 = false;
- bVar2 = CoordinateFlag();
- if (bVar2) {
- bVar1 = CoordinateFlag();
- bVar1 = !bVar1;
- }
- y_00 = (int *)y;
- pOVar9 = (Object *)x;
- if (bVar1) goto LAB_0808f731;
- bVar1 = false;
- z_00 = (int *)0x2a;
- pOVar10 = (Object *)x;
- piVar7 = (int *)y;
- bVar2 = CoordinateFlag();
- if (bVar2) {
-LAB_0808fd7b:
- y_00 = piVar7;
- pOVar9 = pOVar10;
- bVar1 = true;
- }
- else {
- z_00 = (int *)0x2b;
- bVar2 = CoordinateFlag();
- pOVar10 = pOVar9;
- piVar7 = y_00;
- if (bVar2) goto LAB_0808fd7b;
- }
- if (bVar1) {
- Object::getObjectType((Object *)&z);
- pOVar9 = (Object *)0x29;
- bVar1 = ObjectType::getFlag((ObjectType *)&z,HANG);
- if (bVar1) {
- z_00 = (int *)0x29;
- pOVar9 = (Object *)x;
- y_00 = (int *)y;
- bVar1 = CoordinateFlag();
- if (!bVar1) goto LAB_0808f731;
- }
- }
- }
-LAB_0808fb60:
- puVar6 = (undefined4 *)__cxa_allocate_exception(4,pOVar9,y_00,z_00);
- *puVar6 = 4;
- goto LAB_0808f965;
- }
-LAB_0808f731:
- z = Obj->ObjectID;
- z_00 = &sy;
- y_00 = &sx;
- GetObjectCoordinates((Object *)&z,&local_44,y_00,z_00);
- pOVar9 = Obj;
- Object::getObjectType((Object *)&z);
- if (z == 99) {
- z = Obj->ObjectID;
- pTVar3 = GetCreature((Object *)&z);
- uVar4 = sz - pTVar3->posx;
- if (0x7fffffff < uVar4) {
- uVar4 = -uVar4;
- }
- if ((int)uVar4 < 2) {
- uVar4 = x - pTVar3->posy;
- if (0x7fffffff < uVar4) {
- uVar4 = -uVar4;
- }
- if ((int)uVar4 < 2) {
- piVar7 = (int *)pTVar3->posz;
- uVar4 = y - (int)piVar7;
- if (0x7fffffff < uVar4) {
- uVar4 = -uVar4;
- }
- if ((int)uVar4 < 2) {
- if ((int *)(y + 1) == piVar7) {
- pOVar9 = (Object *)pTVar3->posy;
- y_00 = piVar7;
- iVar5 = GetHeight();
- if (iVar5 < 0x18) goto LAB_0808fb60;
- piVar7 = (int *)pTVar3->posz;
- }
- if (y == (int)piVar7 + 1) {
- pOVar9 = (Object *)x;
- y_00 = (int *)y;
- iVar5 = GetHeight();
- if (iVar5 < 0x18) {
- puVar6 = (undefined4 *)__cxa_allocate_exception(4,pOVar9,y_00);
- *puVar6 = 0x2c;
- goto LAB_0808f965;
- }
- piVar7 = (int *)pTVar3->posz;
- }
- if ((pTVar3->Type != MONSTER) || ((int *)y == piVar7)) {
- iVar5 = (*pTVar3->_vptr_TCreature[3])
- (pTVar3,sz,x,y,1,(uint)((int *)y != piVar7));
- if ((char)iVar5 == '\0') {
- uVar13 = 0x34;
- puVar6 = (undefined4 *)__cxa_allocate_exception(4);
- if (CreatureID != pTVar3->ID) {
- uVar13 = 4;
- }
- *puVar6 = uVar13;
- goto LAB_0808f965;
- }
- if (CreatureID != pTVar3->ID) {
- z_00 = (int *)0x24;
- pOVar9 = (Object *)x;
- y_00 = (int *)y;
- bVar1 = CoordinateFlag();
- if (bVar1) goto LAB_0808fb60;
- if (((CreatureID != pTVar3->ID) && (bVar1 = IsProtectionZone(), bVar1))
- && (iVar5 = x, iVar12 = y, bVar1 = IsProtectionZone(), !bVar1)) {
- puVar6 = (undefined4 *)__cxa_allocate_exception(4,iVar5,iVar12,z_00)
- ;
- *puVar6 = 0x2f;
- goto LAB_0808f965;
- }
- }
- goto LAB_0808f8b2;
- }
- }
- }
- }
- goto LAB_0808fa8d;
- }
- Object::getObjectType((Object *)&z);
- bVar1 = ObjectType::getFlag((ObjectType *)&z,TAKE);
- if (!bVar1) {
- z = MapCon->ObjectID;
- y_00 = (int *)0x2;
- pOVar9 = (Object *)&z;
- bVar1 = ObjectInRange(CreatureID,(Object *)&z,2);
- if (!bVar1) goto LAB_0808fa8d;
- }
-LAB_0808f8b2:
- Object::getObjectType((Object *)&z);
- bVar1 = ObjectType::getFlag((ObjectType *)&z,HANG);
- iVar12 = y;
- iVar5 = x;
- if (bVar1) {
- bVar1 = false;
- uVar13 = 0x2a;
- iVar8 = x;
- iVar11 = y;
- bVar2 = CoordinateFlag();
- if (bVar2) {
-LAB_0808f908:
- iVar12 = iVar11;
- iVar5 = iVar8;
- bVar1 = true;
- }
- else {
- uVar13 = 0x2b;
- bVar2 = CoordinateFlag();
- iVar8 = iVar5;
- iVar11 = iVar12;
- if (bVar2) goto LAB_0808f908;
- }
- if (bVar1) {
- pTVar3 = GetCreature(CreatureID);
- if (pTVar3 == (TCreature *)0x0) {
- error(&DAT_080ff140,iVar5,iVar12,uVar13);
- puVar6 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar6 = 0xffffffff;
- goto LAB_0808f965;
- }
- if (pTVar3->posz < y) {
- puVar6 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar6 = 0x18;
- goto LAB_0808f965;
- }
- if (y < pTVar3->posz) {
- puVar6 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar6 = 0x17;
- goto LAB_0808f965;
- }
- z_00 = (int *)0x2a;
- pOVar9 = (Object *)x;
- y_00 = (int *)y;
- bVar1 = CoordinateFlag();
- if (bVar1) {
- bVar1 = false;
- if ((x <= pTVar3->posy) && (pTVar3->posy <= x + 1)) {
- bVar1 = true;
- }
- if (bVar1) {
- bVar1 = false;
- if ((sz + -1 <= pTVar3->posx) && (pTVar3->posx <= sz + 1)) {
- bVar1 = true;
- }
- if (bVar1) goto LAB_0808fa1f;
- }
- }
- else {
-LAB_0808fa1f:
- z_00 = (int *)0x2b;
- pOVar9 = (Object *)x;
- bVar1 = CoordinateFlag();
- if (!bVar1) {
- return;
- }
- bVar1 = false;
- if ((sz <= pTVar3->posx) && (pTVar3->posx <= sz + 1)) {
- bVar1 = true;
- }
- y_00 = (int *)y;
- if (bVar1) {
- bVar1 = false;
- if ((x + -1 <= pTVar3->posy) && (pTVar3->posy <= x + 1)) {
- bVar1 = true;
- }
- if (bVar1) {
- return;
- }
- }
- }
-LAB_0808fa8d:
- puVar6 = (undefined4 *)__cxa_allocate_exception(4,pOVar9,y_00,z_00);
- *puVar6 = 5;
- goto LAB_0808f965;
- }
- }
- bVar1 = ThrowPossible(local_44,sx,sy,sz,x,y,1);
- if (bVar1) {
- return;
- }
- puVar6 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar6 = 7;
-LAB_0808f965:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar6,&RESULT::typeinfo,0);
-}
-
-
-
void CheckMapPlace(ulong CreatureID,ObjectType *Type,Object *MapCon)
{
diff --git a/src/cract.cc b/src/cract.cc
index 325fbdc..15fdf66 100644
--- a/src/cract.cc
+++ b/src/cract.cc
@@ -986,10 +986,10 @@ void TCreature::ToDoWait(int Delay){
}
void TCreature::ToDoGo(int DestX, int DestY, int DestZ, bool MustReach, int MaxSteps){
- if(this->posz < DestZ){
- throw DOWNSTAIRS;
- }else if(this->posz > DestZ){
+ if(this->posz > DestZ){
throw UPSTAIRS;
+ }else if(this->posz < DestZ){
+ throw DOWNSTAIRS;
}
if(this->LockToDo){
diff --git a/src/info.cc b/src/info.cc
index d15f470..3cdfe02 100644
--- a/src/info.cc
+++ b/src/info.cc
@@ -805,8 +805,8 @@ bool SearchFreeField(int *x, int *y, int *z, int Distance, uint16 HouseID, bool
return false;
}
-// TODO(fusion): This is a helper function for `SearchLoginField`. Perhaps we
-// should try to merge it there?
+// NOTE(fusion): This is a helper function for `SearchLoginField` and improves
+// the readability of an otherwise convoluted function.
static bool LoginPossible(int x, int y, int z, uint16 HouseID, bool Player){
Object Obj = GetFirstObject(x, y, z);
if(Obj == NONE){
diff --git a/src/operate.cc b/src/operate.cc
index 603cc7f..34df0a7 100644
--- a/src/operate.cc
+++ b/src/operate.cc
@@ -1,4 +1,5 @@
#include "operate.hh"
+#include "config.hh"
#include "info.hh"
#include "stubs.hh"
@@ -333,13 +334,7 @@ void CheckTopMoveObject(uint32 CreatureID, Object Obj, Object Ignore){
BestIsCreature = HelpType.isCreatureContainer();
}
- // TODO(fusion): This is probably some inlined function to check whether
- // an object has a low stack priority.
- if(!HelpType.getFlag(BANK)
- && !HelpType.getFlag(CLIP)
- && !HelpType.getFlag(BOTTOM)
- && !HelpType.getFlag(TOP)
- && !HelpType.isCreatureContainer()){
+ if(GetObjectPriority(Help) == PRIORITY_LOW){
break;
}
}
@@ -375,15 +370,43 @@ void CheckTopUseObject(uint32 CreatureID, Object Obj){
Best = Help;
}
- if(HelpType.getFlag(FORCEUSE)){
+ if(HelpType.getFlag(FORCEUSE) || GetObjectPriority(Help) == PRIORITY_LOW){
break;
}
- if(!HelpType.getFlag(BANK)
- && !HelpType.getFlag(CLIP)
- && !HelpType.getFlag(BOTTOM)
- && !HelpType.getFlag(TOP)
- && !HelpType.isCreatureContainer()){
+ Help = Help.getNextObject();
+ }
+
+ if(Obj != Best){
+ throw NOTACCESSIBLE;
+ }
+}
+
+void CheckTopMultiuseObject(uint32 CreatureID, Object Obj){
+ if(!Obj.exists()){
+ error("CheckTopMultiuseObject: Objekt existiert nicht.\n");
+ throw ERROR;
+ }
+
+ if(CreatureID == 0 || !IsCreaturePlayer(CreatureID)){
+ return;
+ }
+
+ Object Con = Obj.getContainer();
+ ObjectType ConType = Con.getObjectType();
+ if(!ConType.isMapContainer()){
+ return;
+ }
+
+ Object Best = NONE;
+ Object Help = GetFirstContainerObject(Con);
+ while(Help != NONE){
+ ObjectType HelpType = Help.getObjectType();
+ if(Best == NONE || !HelpType.getFlag(LIQUIDPOOL)){
+ Best = Help;
+ }
+
+ if(HelpType.getFlag(FORCEUSE) || GetObjectPriority(Help) >= PRIORITY_CREATURE){
break;
}
@@ -395,6 +418,167 @@ void CheckTopUseObject(uint32 CreatureID, Object Obj){
}
}
+void CheckMoveObject(uint32 CreatureID, Object Obj, bool Take){
+ if(CreatureID == 0){
+ return;
+ }
+
+ if(!ObjectAccessible(CreatureID, Obj, 1)){
+ throw NOTACCESSIBLE;
+ }
+
+ ObjectType ObjType = Obj.getObjectType();
+ if(ObjType.getFlag(UNMOVE)){
+ throw NOTMOVABLE;
+ }
+
+ if(ObjType.isCreatureContainer() && Obj.getCreatureID() != CreatureID){
+ TCreature *MovingCreature = GetCreature(Obj);
+ if(MovingCreature == NULL){
+ error("CheckMoveObject: Kreatur existiert nicht.\n");
+ throw ERROR;
+ }
+
+ if(GetRaceUnpushable(MovingCreature->Race) && (WorldType != NON_PVP || !MovingCreature->IsPeaceful())){
+ throw NOTMOVABLE;
+ }
+ }
+
+ if(Take && !ObjType.getFlag(TAKE)){
+ throw NOTTAKABLE;
+ }
+}
+
+// NOTE(fusion): This is a helper function for `CheckMapDestination` and improves
+// the readability of an otherwise convoluted function.
+static bool IsMapDestinationBlocked(int DestX, int DestY, int DestZ, ObjectType Type){
+ if(Type.isCreatureContainer()){
+ return false;
+ }
+
+ bool HasBank = CoordinateFlag(DestX, DestY, DestZ, BANK);
+ if(HasBank && !CoordinateFlag(DestX, DestY, DestZ, UNPASS)){
+ return false;
+ }
+
+ if(!Type.getFlag(UNPASS)){
+ if(HasBank && !CoordinateFlag(DestX, DestY, DestZ, UNLAY)){
+ return false;
+ }
+
+ if(CoordinateFlag(DestX, DestY, DestZ, HOOKSOUTH) || CoordinateFlag(DestX, DestY, DestZ, HOOKEAST)){
+ if(Type.getFlag(HANG) && !CoordinateFlag(DestX, DestY, DestZ, HANG)){
+ return true;
+ }
+ }
+ }
+
+ return true;
+}
+
+void CheckMapDestination(uint32 CreatureID, Object Obj, Object MapCon){
+ if(CreatureID == 0){
+ return;
+ }
+
+ int DestX, DestY, DestZ;
+ ObjectType ObjType = Obj.getObjectType();
+ GetObjectCoordinates(MapCon, &DestX, &DestY, &DestZ);
+ if(IsMapDestinationBlocked(DestX, DestY, DestZ, ObjType)){
+ throw NOROOM;
+ }
+
+ int OrigX, OrigY, OrigZ;
+ GetObjectCoordinates(Obj, &OrigX, &OrigY, &OrigZ);
+ if(ObjType.isCreatureContainer()){
+ if(std::abs(OrigX - DestX) > 1
+ || std::abs(OrigY - DestY) > 1
+ || std::abs(OrigZ - DestZ) > 1){
+ throw OUTOFRANGE;
+ }
+
+ if(DestZ == (OrigZ - 1)){
+ if(GetHeight(OrigX, OrigY, OrigZ) < 24){ // JUMP_HEIGHT ?
+ throw NOROOM;
+ }
+ }else if(DestZ == (OrigZ + 1)){
+ if(GetHeight(DestX, DestY, DestZ) < 24){ // JUMP_HEIGHT ?
+ throw NOWAY;
+ }
+ }
+
+ // TODO(fusion): Should probably check if moving creature is NULL?
+ TCreature *MovingCreature = GetCreature(Obj);
+ if(OrigZ == DestZ || MovingCreature->Type != MONSTER){
+ if(!MovingCreature->MovePossible(DestX, DestY, DestZ, true, OrigZ != DestZ)){
+ if(CreatureID == MovingCreature->ID){
+ throw MOVENOTPOSSIBLE;
+ }else{
+ throw NOROOM;
+ }
+ }
+
+ if(CreatureID != MovingCreature->ID){
+ if(CoordinateFlag(DestX, DestY, DestZ, AVOID)){
+ throw NOROOM;
+ }
+
+ if(IsProtectionZone(OrigX, OrigY, OrigZ) && !IsProtectionZone(DestX, DestY, DestZ)){
+ throw PROTECTIONZONE;
+ }
+ }
+ }
+ }else{
+ if(!ObjType.getFlag(TAKE) && !ObjectInRange(CreatureID, MapCon, 2)){
+ throw OUTOFRANGE;
+ }
+ }
+
+ // TODO(fusion): This looks awfully similar to `ObjectAccessible` outside
+ // from the exceptions and floor check.
+ if(ObjType.getFlag(HANG)){
+ bool HookSouth = CoordinateFlag(DestX, DestY, DestZ, HOOKSOUTH);
+ bool HookEast = CoordinateFlag(DestX, DestY, DestZ, HOOKEAST);
+ if(HookSouth || HookEast){
+ TCreature *Creature = GetCreature(CreatureID);
+ if(Creature == NULL){
+ error("CheckMapDestination: Ausführende Kreatur existiert nicht.\n");
+ throw ERROR;
+ }
+
+ if(Creature->posz > DestZ){
+ throw UPSTAIRS;
+ }else if(Creature->posz < DestZ){
+ throw DOWNSTAIRS;
+ }
+
+ if(HookSouth){
+ if(Creature->posy < DestY
+ || Creature->posy > (DestY + 1)
+ || Creature->posx < (DestX - 1)
+ || Creature->posx > (DestX + 1)){
+ throw OUTOFRANGE;
+ }
+ }
+
+ if(HookEast){
+ if(Creature->posx < DestX
+ || Creature->posx > (DestX + 1)
+ || Creature->posy < (DestY - 1)
+ || Creature->posy > (DestY + 1)){
+ throw OUTOFRANGE;
+ }
+ }
+
+ return;
+ }
+ }
+
+ if(!ThrowPossible(OrigX, OrigY, OrigZ, DestX, DestY, DestZ, 1)){
+ throw CANNOTTHROW;
+ }
+}
+
// TODO(fusion): This could have been a simple return value.
void CheckContainerDestination(Object Obj, Object Con){
Object Help = Con;