more work on operate.cc
This commit is contained in:
parent
05ec30b994
commit
7d298e5a41
2
Makefile
2
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)
|
||||
|
||||
445
reference/game.c
445
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)
|
||||
|
||||
{
|
||||
|
||||
@ -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){
|
||||
|
||||
@ -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){
|
||||
|
||||
216
src/operate.cc
216
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,7 @@ void CheckTopUseObject(uint32 CreatureID, Object Obj){
|
||||
Best = Help;
|
||||
}
|
||||
|
||||
if(HelpType.getFlag(FORCEUSE)){
|
||||
break;
|
||||
}
|
||||
|
||||
if(!HelpType.getFlag(BANK)
|
||||
&& !HelpType.getFlag(CLIP)
|
||||
&& !HelpType.getFlag(BOTTOM)
|
||||
&& !HelpType.getFlag(TOP)
|
||||
&& !HelpType.isCreatureContainer()){
|
||||
if(HelpType.getFlag(FORCEUSE) || GetObjectPriority(Help) == PRIORITY_LOW){
|
||||
break;
|
||||
}
|
||||
|
||||
@ -395,6 +382,203 @@ void CheckTopUseObject(uint32 CreatureID, Object Obj){
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Help = Help.getNextObject();
|
||||
}
|
||||
|
||||
if(Obj != Best){
|
||||
throw NOTACCESSIBLE;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user