From 7d298e5a4119df0910daa070af1d23567a83e90c Mon Sep 17 00:00:00 2001 From: fusion32 Date: Thu, 12 Jun 2025 04:16:16 -0300 Subject: more work on `operate.cc` --- Makefile | 2 +- reference/game.c | 445 ------------------------------------------------------- src/cract.cc | 6 +- src/info.cc | 4 +- src/operate.cc | 210 ++++++++++++++++++++++++-- 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; -- cgit v1.2.3