diff options
| author | fusion32 <marcopuzziello@gmail.com> | 2025-06-12 04:16:16 -0300 |
|---|---|---|
| committer | fusion32 <marcopuzziello@gmail.com> | 2025-06-12 04:17:13 -0300 |
| commit | 7d298e5a4119df0910daa070af1d23567a83e90c (patch) | |
| tree | 93bd46dec5b74186db806d61b66c2115065224fc | |
| parent | 05ec30b99472e8c17cd33c29d0e7859e02dc9fc8 (diff) | |
| download | game-7d298e5a4119df0910daa070af1d23567a83e90c.tar.gz game-7d298e5a4119df0910daa070af1d23567a83e90c.zip | |
more work on `operate.cc`
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | reference/game.c | 445 | ||||
| -rw-r--r-- | src/cract.cc | 6 | ||||
| -rw-r--r-- | src/info.cc | 4 | ||||
| -rw-r--r-- | src/operate.cc | 210 |
5 files changed, 203 insertions, 464 deletions
@@ -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; |
