aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfusion32 <marcopuzziello@gmail.com>2025-06-27 18:57:29 -0300
committerfusion32 <marcopuzziello@gmail.com>2025-06-27 18:57:29 -0300
commite59667ec6be0a21ce702ce077154357a1c7f7c04 (patch)
tree8222cce37f8dbf1694cffa138c0bb0ad6b893bf3
parentea319bc2fbef91e3ea062be554b215756648d1d3 (diff)
downloadgame-e59667ec6be0a21ce702ce077154357a1c7f7c04.tar.gz
game-e59667ec6be0a21ce702ce077154357a1c7f7c04.zip
`moveuse.cc`
-rw-r--r--TODO.md14
-rw-r--r--reference/enums.hh70
-rw-r--r--reference/game.c5733
-rw-r--r--reference/types.hh30
-rw-r--r--src/crcombat.cc4
-rw-r--r--src/crmain.cc109
-rw-r--r--src/crnonpl.cc6
-rw-r--r--src/crplayer.cc1
-rw-r--r--src/enums.hh31
-rw-r--r--src/info.cc3
-rw-r--r--src/magic.cc2
-rw-r--r--src/main.cc5
-rw-r--r--src/map.cc54
-rw-r--r--src/moveuse.cc3039
-rw-r--r--src/moveuse.hh186
-rw-r--r--src/operate.cc18
-rw-r--r--src/stubs.hh23
17 files changed, 3336 insertions, 5992 deletions
diff --git a/TODO.md b/TODO.md
index fe5db50..dce0e29 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,6 +1,4 @@
## TODO NEXT
-- CRNONPL.CC <- GAME
-- MOVEUSE.CC <- GAME
- HOUSES.CC <- GAME
- QUERY.CC
- READER.CC
@@ -13,11 +11,19 @@
`ObjectType` to be used as an alias when pertinent.
- Make some `TNonplayer` random step function? One version that does a random step and another that does a random step keeping some distance from a certain position.
+- I realized that `Change` with an `ObjectType` parameter was being called where
+ the version with `INSTANCEATTRIBUTE` parameter was expected due to `ObjectType`
+ having an implicit conversion constructor from `int`. I think it is best to make
+ all converting constructors explicit to avoid these types of errors, although
+ there aren't that many function overloads.
+
+- Define a few constants like `MAX_NAME_LENGTH`, `MAX_SKILLS`, and `MAX_OPEN_CONTAINERS` instead of relying on `NARRAY`.
+
## Stack allocations
Any functions that use `alloca` or some other form of dynamic stack allocations will cause decompiled functions to be an absolute mess. It usually shows up in the decompiled code as both a size computation like `-(VAR + CONST & 0xfffffff0)`, followed by some assignment. It doesn't make total sense without looking at the disassembly. I've encountered ~30 such computations and expect the functions containing them to be amongt the most challenging/annoying to be properly decompiled.
## Exceptions
-I didn't dive into how exceptions are handled, but it seems that the ones related to creature actions have the outter most endpoint at `TCreature::Execute`. There can also be some checkpoints in between to modify a `RESULT` value or handle a failure.
+It's absolute hell.
## Synchronization
I'm not sure whether synchronization is done properly. The implementation of the first few `crplayer.cc` functions left me with a taste of race conditions although integer loads on x86 are generally atomic.
@@ -31,6 +37,8 @@ We'll have to address this BEFORE trying to run the server.
The decompiled file has ~115K lines of C. If we take ~15K lines to be rubbish, this can be round to ~100K. Considering a low estimate of 200 lines per day, the whole process could take up to 500 days which is quite a bit but not impossible. Now considering a high estimate of 1K lines per day, it could take 100 days which is also quite a bit.
## TODO AFTER FIRST PASS
+- Remove VTABLE comments.
+- Split NPC, Monster, and Player into separate header files.
- Review dividing comments. I feel like the current "//========" blends in too easily, making it hard to see.
- Trim rough edges.
- Replace unsafe libc functions like `strcpy`, `strncpy`, `strcat`, `sprintf` etc...
diff --git a/reference/enums.hh b/reference/enums.hh
index 6834e5a..d54a03f 100644
--- a/reference/enums.hh
+++ b/reference/enums.hh
@@ -1,51 +1,4 @@
-enum ActionType: int {
- ACTION_CREATEONMAP=0,
- ACTION_CREATE=1,
- ACTION_MONSTERONMAP=2,
- ACTION_MONSTER=3,
- ACTION_EFFECTONMAP=4,
- ACTION_EFFECT=5,
- ACTION_TEXTONMAP=6,
- ACTION_TEXT=7,
- ACTION_CHANGEONMAP=8,
- ACTION_CHANGE=9,
- ACTION_CHANGEREL=10,
- ACTION_SETATTRIBUTE=11,
- ACTION_CHANGEATTRIBUTE=12,
- ACTION_SETQUESTVALUE=13,
- ACTION_DAMAGE=14,
- ACTION_SETSTART=15,
- ACTION_WRITENAME=16,
- ACTION_WRITETEXT=17,
- ACTION_LOGOUT=18,
- ACTION_MOVEALLONMAP=19,
- ACTION_MOVEALL=20,
- ACTION_MOVEALLREL=21,
- ACTION_MOVETOPONMAP=22,
- ACTION_MOVETOP=23,
- ACTION_MOVETOPREL=24,
- ACTION_MOVE=25,
- ACTION_MOVEREL=26,
- ACTION_RETRIEVE=27,
- ACTION_DELETEALLONMAP=28,
- ACTION_DELETETOPONMAP=29,
- ACTION_DELETEONMAP=30,
- ACTION_DELETE=31,
- ACTION_DELETEININVENTORY=32,
- ACTION_DESCRIPTION=33,
- ACTION_LOADDEPOT=34,
- ACTION_SAVEDEPOT=35,
- ACTION_SENDMAIL=36,
- ACTION_NOP=37
-};
-
-enum ModifierType: int {
- MODIFIER_NORMAL=0,
- MODIFIER_INVERT=1,
- MODIFIER_TRUE=2
-};
-
enum TWriterThreadReplyType: int {
REPLY_BROADCAST=0,
REPLY_DIRECT=1,
@@ -76,29 +29,6 @@ enum CHANNEL: int {
HELP_CHANNEL=7
};
-enum EventType: int {
- EVENT_USE=0,
- EVENT_MULTIUSE=1,
- EVENT_MOVEMENT=2,
- EVENT_COLLISION=3,
- EVENT_SEPARATION=4
-};
-
-enum ParameterType: int {
- PARAMETER_OBJECT=0,
- PARAMETER_TYPE=1,
- PARAMETER_FLAG=2,
- PARAMETER_TYPEATTRIBUTE=3,
- PARAMETER_INSTANCEATTRIBUTE=4,
- PARAMETER_COORDINATE=5,
- PARAMETER_VECTOR=6,
- PARAMETER_RIGHT=7,
- PARAMETER_SKILL=8,
- PARAMETER_NUMBER=9,
- PARAMETER_TEXT=10,
- PARAMETER_COMPARISON=11
-};
-
enum TReaderThreadOrderType: int {
ORDER_TERMINATE=0,
ORDER_LOADSECTOR=1,
diff --git a/reference/game.c b/reference/game.c
index 4b7b5b7..b6cd717 100644
--- a/reference/game.c
+++ b/reference/game.c
@@ -12110,5739 +12110,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority
return;
}
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-Object GetEventObject(void)
-
-{
- Object OVar1;
- ulong *in_stack_00000004;
- undefined4 in_stack_00000008;
- ulong *in_stack_0000000c;
- ulong *in_stack_00000010;
- ulong *in_stack_00000014;
- ulong *in_stack_00000018;
-
- switch(in_stack_00000008) {
- case 1:
- in_stack_00000018 = in_stack_00000010;
- break;
- case 2:
- in_stack_00000018 = in_stack_00000014;
- break;
- case 3:
- in_stack_00000018 = in_stack_0000000c;
- break;
- case 4:
- break;
- default:
- error("GetEventObject: Unbekannte Nummer %d.\n");
- case 0:
- OVar1.ObjectID = NONE.ObjectID;
- goto LAB_08072475;
- }
- OVar1.ObjectID = *in_stack_00000018;
-LAB_08072475:
- *in_stack_00000004 = OVar1.ObjectID;
- return (Object)(ulong)in_stack_00000004;
-}
-
-
-
-bool Compare(int Value1,int Operator,int Value2)
-
-{
- bool bVar1;
-
- switch(Operator) {
- case 0x3c:
- bVar1 = Value1 < Value2;
- break;
- case 0x3d:
- bVar1 = Value1 == Value2;
- break;
- case 0x3e:
- bVar1 = Value2 < Value1;
- break;
- default:
- error(&DAT_080f79e0,Operator);
- bVar1 = false;
- break;
- case 0x47:
- bVar1 = Value2 <= Value1;
- break;
- case 0x4c:
- bVar1 = Value1 <= Value2;
- break;
- case 0x4e:
- bVar1 = Value1 != Value2;
- }
- return bVar1;
-}
-
-
-
-bool CheckCondition(EventType param_1,TMoveUseCondition *Condition,Object *User,Object *Obj1,
- Object *Obj2,Object *Temp)
-
-{
- ModifierType MVar1;
- FLAG Flag;
- TYPEATTRIBUTE Attribute;
- byte bVar2;
- char cVar3;
- bool bVar4;
- ushort HouseID;
- TCreature *pTVar5;
- char *__s2;
- char *__s1;
- int iVar6;
- int iVar7;
- ObjectType *pOVar8;
- TPlayer *pTVar9;
- ulong uVar10;
- ulong uVar11;
- long lVar12;
- Object *pOVar13;
- undefined4 uVar14;
- ulong *puVar15;
- ulong *puVar16;
- ulong *puVar17;
- bool local_a7;
- bool local_a6;
- bool local_a5;
- int iStack_a4;
- bool fulfilled;
- int x2;
- int y2;
- int z2;
- int x1;
- int y1;
- int z1;
- Object local_7c [4];
- ObjectType local_6c [4];
- ulong local_5c [4];
- ulong local_4c [4];
- ulong local_3c [4];
- Object local_2c;
- Object Obj;
-
- local_a5 = false;
- local_2c.ObjectID = 0;
- switch(Condition->Condition) {
- case CONDITION_ISPOSITION:
- local_5c[0] = Temp->ObjectID;
- local_6c[0].TypeID = Obj2->ObjectID;
- local_7c[0] = (Object)Obj1->ObjectID;
- z1 = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_4c[0];
- local_3c[0] = local_4c[0];
- UnpackAbsoluteCoordinate();
- z1 = local_2c.ObjectID;
- GetObjectCoordinates((Object *)&z1,&stack0xffffff5c,&x2,&y2);
- local_a5 = false;
- if ((z2 == iStack_a4) && (x1 == x2)) {
- bVar4 = y1 == y2;
-LAB_08072693:
- local_a5 = false;
- if (bVar4) {
-LAB_08072695:
- local_a5 = true;
- }
- }
- break;
- case CONDITION_ISTYPE:
- local_6c[0].TypeID = Temp->ObjectID;
- local_5c[0] = Obj2->ObjectID;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- Object::getObjectType((Object *)&z1);
- local_a5 = z1 == Condition->Parameters[1];
- break;
- case CONDITION_ISCREATURE:
- local_6c[0].TypeID = Temp->ObjectID;
- local_5c[0] = Obj2->ObjectID;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- Object::getObjectType((Object *)&z1);
- local_a5 = z1 == 99;
- break;
- case CONDITION_ISPLAYER:
- local_6c[0].TypeID = Temp->ObjectID;
- local_5c[0] = Obj2->ObjectID;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- Object::getObjectType((Object *)&z1);
- if (z1 == 99) {
- z1 = local_2c.ObjectID;
-LAB_08072828:
- pTVar5 = GetCreature((Object *)&z1);
- local_a5 = false;
- if (pTVar5 != (TCreature *)0x0) {
- bVar4 = pTVar5->Type == PLAYER;
- goto LAB_08072693;
- }
- }
- break;
- case CONDITION_HASFLAG:
- local_6c[0].TypeID = Temp->ObjectID;
- local_5c[0] = Obj2->ObjectID;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- Flag = Condition->Parameters[1];
- Object::getObjectType((Object *)&z1);
- local_a5 = ObjectType::getFlag((ObjectType *)&z1,Flag);
- break;
- case CONDITION_HASTYPEATTRIBUTE:
- local_6c[0].TypeID = Temp->ObjectID;
- puVar17 = local_4c;
- local_5c[0] = Obj2->ObjectID;
- puVar16 = local_3c;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- Attribute = Condition->Parameters[1];
- Object::getObjectType((Object *)&z1);
- uVar11 = ObjectType::getAttribute((ObjectType *)&z1,Attribute);
- iVar7 = Condition->Parameters[2];
- uVar10 = Condition->Parameters[3];
- switch(iVar7) {
- case 0x3c:
-switchD_0807323b_caseD_3c:
- local_a5 = (int)uVar11 < (int)uVar10;
- break;
- case 0x3d:
-switchD_0807323b_caseD_3d:
- local_a5 = uVar11 == uVar10;
- break;
- case 0x3e:
-switchD_0807323b_caseD_3e:
- local_a5 = (int)uVar10 < (int)uVar11;
- break;
- default:
-switchD_0807323b_caseD_3f:
- error(&DAT_080f79e0,iVar7,puVar16,puVar17);
- local_a5 = false;
- break;
- case 0x47:
-switchD_0807323b_caseD_47:
- local_a5 = (int)uVar10 <= (int)uVar11;
- break;
- case 0x4c:
-switchD_0807323b_caseD_4c:
- local_a5 = (int)uVar11 <= (int)uVar10;
- break;
- case 0x4e:
-switchD_0807323b_caseD_4e:
- local_a5 = uVar11 != uVar10;
- }
- break;
- case CONDITION_HASINSTANCEATTRIBUTE:
- local_6c[0].TypeID = Temp->ObjectID;
- puVar17 = local_4c;
- local_5c[0] = Obj2->ObjectID;
- puVar16 = local_3c;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- uVar11 = Object::getAttribute(&local_2c,Condition->Parameters[1]);
- iVar7 = Condition->Parameters[2];
- uVar10 = Condition->Parameters[3];
- switch(iVar7) {
- case 0x3c:
- goto switchD_0807323b_caseD_3c;
- case 0x3d:
- goto switchD_0807323b_caseD_3d;
- case 0x3e:
- goto switchD_0807323b_caseD_3e;
- default:
- goto switchD_0807323b_caseD_3f;
- case 0x47:
- goto switchD_0807323b_caseD_47;
- case 0x4c:
- goto switchD_0807323b_caseD_4c;
- case 0x4e:
- goto switchD_0807323b_caseD_4e;
- }
- case CONDITION_HASTEXT:
- local_6c[0].TypeID = Temp->ObjectID;
- local_5c[0] = Obj2->ObjectID;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- __s2 = GetDynamicString(Condition->Parameters[1]);
- uVar10 = Object::getAttribute(&local_2c,TEXTSTRING);
- __s1 = GetDynamicString(uVar10);
- iVar7 = strcmp(__s1,__s2);
- local_a5 = iVar7 == 0;
- break;
- case CONDITION_ISPEACEFUL:
- local_6c[0].TypeID = Temp->ObjectID;
- puVar17 = local_4c;
- pOVar8 = local_6c;
- local_5c[0] = Obj2->ObjectID;
- puVar16 = local_3c;
- local_4c[0] = Obj1->ObjectID;
- puVar15 = local_5c;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- pOVar13 = &local_2c;
- Object::getObjectType((Object *)&z1);
- if (z1 == 99) {
- z1 = local_2c.ObjectID;
- pTVar5 = GetCreature((Object *)&z1);
- local_a5 = false;
- if (pTVar5 != (TCreature *)0x0) {
- iVar7 = (*pTVar5->_vptr_TCreature[4])(pTVar5,pOVar13,puVar16,puVar17,puVar15,pOVar8)
- ;
- cVar3 = (char)iVar7;
-LAB_08072b84:
- local_a5 = false;
- if (cVar3 != '\0') goto LAB_08072695;
- }
- }
- break;
- case CONDITION_MAYLOGOUT:
- local_6c[0].TypeID = Temp->ObjectID;
- local_5c[0] = Obj2->ObjectID;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- Object::getObjectType((Object *)&z1);
- if (z1 == 99) {
- z1 = local_2c.ObjectID;
- pTVar5 = GetCreature((Object *)&z1);
- local_a5 = false;
- if ((pTVar5 != (TCreature *)0x0) && (pTVar5->Type == PLAYER)) {
- iVar7 = TCreature::LogoutPossible(pTVar5);
- bVar4 = iVar7 == 0;
- goto LAB_08072693;
- }
- }
- break;
- case CONDITION_HASPROFESSION:
- local_6c[0].TypeID = Temp->ObjectID;
- local_5c[0] = Obj2->ObjectID;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- Object::getObjectType((Object *)&z1);
- if (z1 == 99) {
- z1 = local_2c.ObjectID;
- pTVar9 = (TPlayer *)GetCreature((Object *)&z1);
- local_a5 = false;
- if ((pTVar9 != (TPlayer *)0x0) && ((pTVar9->super_TCreature).Type == PLAYER)) {
- bVar2 = TPlayer::GetEffectiveProfession(pTVar9);
- bVar4 = (uint)bVar2 == Condition->Parameters[1];
- goto LAB_08072693;
- }
- }
- break;
- case CONDITION_HASLEVEL:
- local_6c[0].TypeID = Temp->ObjectID;
- puVar17 = local_4c;
- local_5c[0] = Obj2->ObjectID;
- puVar16 = local_3c;
- local_4c[0] = Obj1->ObjectID;
- puVar15 = local_5c;
- local_3c[0] = User->ObjectID;
- pOVar8 = local_6c;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- Object::getObjectType((Object *)&z1);
- if (z1 == 99) {
- z1 = local_2c.ObjectID;
- pTVar5 = GetCreature((Object *)&z1);
- local_a6 = false;
- if (pTVar5 != (TCreature *)0x0) {
- iVar6 = TSkill::Get((pTVar5->super_TSkillBase).Skills[0]);
- iVar7 = Condition->Parameters[2];
- switch(Condition->Parameters[1]) {
- case 0x3c:
- bVar4 = iVar6 < iVar7;
- break;
- case 0x3d:
- bVar4 = iVar6 == iVar7;
- break;
- case 0x3e:
- bVar4 = iVar7 < iVar6;
- break;
- default:
- error(&DAT_080f79e0,Condition->Parameters[1],puVar16,puVar17,puVar15,pOVar8);
- bVar4 = false;
- break;
- case 0x47:
- bVar4 = iVar7 <= iVar6;
- break;
- case 0x4c:
- bVar4 = iVar6 <= iVar7;
- break;
- case 0x4e:
- bVar4 = iVar6 != iVar7;
- }
- if (bVar4) {
- local_a6 = true;
- }
- }
- local_a5 = local_a6;
- }
- break;
- case CONDITION_HASRIGHT:
- local_6c[0].TypeID = Temp->ObjectID;
- local_5c[0] = Obj2->ObjectID;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- Object::getObjectType((Object *)&z1);
- if (z1 == 99) {
- z1 = local_2c.ObjectID;
- pTVar5 = GetCreature((Object *)&z1);
- local_a5 = false;
- if ((pTVar5 != (TCreature *)0x0) && (pTVar5->Type == PLAYER)) {
- cVar3 = CheckRight(pTVar5->ID,Condition->Parameters[1]);
- goto LAB_08072b84;
- }
- }
- break;
- case CONDITION_HASQUESTVALUE:
- local_6c[0].TypeID = Temp->ObjectID;
- puVar17 = local_4c;
- puVar16 = local_5c;
- local_5c[0] = Obj2->ObjectID;
- puVar15 = local_3c;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- pOVar8 = local_6c;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- Object::getObjectType((Object *)&z1);
- if (z1 == 99) {
- z1 = local_2c.ObjectID;
- pTVar9 = (TPlayer *)GetCreature((Object *)&z1);
- local_a7 = false;
- if ((pTVar9 != (TPlayer *)0x0) && ((pTVar9->super_TCreature).Type == PLAYER)) {
- iVar6 = TPlayer::GetQuestValue(pTVar9,Condition->Parameters[1]);
- iVar7 = Condition->Parameters[3];
- switch(Condition->Parameters[2]) {
- case 0x3c:
- bVar4 = iVar6 < iVar7;
- break;
- case 0x3d:
- bVar4 = iVar6 == iVar7;
- break;
- case 0x3e:
- bVar4 = iVar7 < iVar6;
- break;
- default:
- error(&DAT_080f79e0,Condition->Parameters[2],puVar15,puVar17,puVar16,pOVar8);
- bVar4 = false;
- break;
- case 0x47:
- bVar4 = iVar7 <= iVar6;
- break;
- case 0x4c:
- bVar4 = iVar6 <= iVar7;
- break;
- case 0x4e:
- bVar4 = iVar6 != iVar7;
- }
- if (bVar4) {
- local_a7 = true;
- }
- }
- local_a5 = local_a7;
- }
- break;
- case CONDITION_TESTSKILL:
- local_6c[0].TypeID = Temp->ObjectID;
- puVar17 = local_4c;
- pOVar8 = local_6c;
- puVar16 = local_5c;
- local_5c[0] = Obj2->ObjectID;
- puVar15 = local_3c;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- Object::getObjectType((Object *)&z1);
- if (z1 == 99) {
- z1 = local_2c.ObjectID;
- pTVar5 = GetCreature((Object *)&z1);
- bVar4 = false;
- iVar7 = Condition->Parameters[1];
- if ((-1 < iVar7) && (iVar7 < 0x19)) {
- bVar4 = true;
- }
- if (bVar4) {
- local_a5 = false;
- if (pTVar5 != (TCreature *)0x0) {
- iVar7 = (*(pTVar5->super_TSkillBase).Skills[iVar7]->_vptr_TSkill[9])
- ((pTVar5->super_TSkillBase).Skills[iVar7],
- Condition->Parameters[2],Condition->Parameters[3],1);
- cVar3 = (char)iVar7;
- goto LAB_08072b84;
- }
- }
- else {
- error(&DAT_080f7a20,iVar7,puVar15,puVar17,puVar16,pOVar8);
- }
- }
- break;
- case CONDITION_COUNTOBJECTS:
- local_6c[0].TypeID = Temp->ObjectID;
- puVar17 = local_4c;
- local_5c[0] = Obj2->ObjectID;
- puVar16 = local_3c;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- GetMapContainer((Object *)&z1);
- uVar11 = CountObjectsInContainer((Object *)&z1);
- iVar7 = Condition->Parameters[1];
- uVar10 = Condition->Parameters[2];
- switch(iVar7) {
- case 0x3c:
- goto switchD_0807323b_caseD_3c;
- case 0x3d:
- goto switchD_0807323b_caseD_3d;
- case 0x3e:
- goto switchD_0807323b_caseD_3e;
- default:
- goto switchD_0807323b_caseD_3f;
- case 0x47:
- goto switchD_0807323b_caseD_47;
- case 0x4c:
- goto switchD_0807323b_caseD_4c;
- case 0x4e:
- goto switchD_0807323b_caseD_4e;
- }
- case CONDITION_COUNTOBJECTSONMAP:
- UnpackAbsoluteCoordinate();
- GetMapContainer((int)&z1,z2,x1);
- uVar11 = CountObjectsInContainer((Object *)&z1);
- iVar7 = Condition->Parameters[1];
- uVar10 = Condition->Parameters[2];
- puVar16 = (ulong *)x1;
- puVar17 = (ulong *)y1;
- switch(iVar7) {
- case 0x3c:
- goto switchD_0807323b_caseD_3c;
- case 0x3d:
- goto switchD_0807323b_caseD_3d;
- case 0x3e:
- goto switchD_0807323b_caseD_3e;
- default:
- goto switchD_0807323b_caseD_3f;
- case 0x47:
- goto switchD_0807323b_caseD_47;
- case 0x4c:
- goto switchD_0807323b_caseD_4c;
- case 0x4e:
- goto switchD_0807323b_caseD_4e;
- }
- case CONDITION_ISOBJECTTHERE:
- UnpackAbsoluteCoordinate();
- ObjectType::setTypeID(local_6c,Condition->Parameters[1]);
- goto LAB_080732ab;
- case CONDITION_ISCREATURETHERE:
- UnpackAbsoluteCoordinate();
- ObjectType::setTypeID(local_6c,99);
-LAB_080732ab:
- GetFirstSpecObject();
-LAB_080732b0:
- Temp->ObjectID = (ulong)local_7c[0];
- local_a5 = Temp->ObjectID != NONE.ObjectID;
- break;
- case CONDITION_ISPLAYERTHERE:
- UnpackAbsoluteCoordinate();
- ObjectType::setTypeID(local_6c,99);
- GetFirstSpecObject();
- Temp->ObjectID = (ulong)local_7c[0];
- z1 = Temp->ObjectID;
- if (z1 != NONE.ObjectID) goto LAB_08072828;
- break;
- case CONDITION_ISOBJECTININVENTORY:
- local_6c[0].TypeID = Temp->ObjectID;
- local_5c[0] = Obj2->ObjectID;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- Object::getObjectType((Object *)&z1);
- if (z1 != 99) break;
- ObjectType::setTypeID(local_6c,Condition->Parameters[1]);
- pOVar8 = (ObjectType *)Object::getCreatureID(&local_2c);
- GetInventoryObject((ulong)local_7c,pOVar8,(ulong)local_6c);
- goto LAB_080732b0;
- case CONDITION_ISPROTECTIONZONE:
- local_6c[0].TypeID = Temp->ObjectID;
- local_5c[0] = Obj2->ObjectID;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- GetObjectCoordinates((Object *)&z1,&z2,&x1,&y1);
- local_a5 = IsProtectionZone();
- break;
- case CONDITION_ISHOUSE:
- local_6c[0].TypeID = Temp->ObjectID;
- local_5c[0] = Obj2->ObjectID;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- GetObjectCoordinates((Object *)&z1,&z2,&x1,&y1);
- local_a5 = IsHouse(z2,x1,y1);
- break;
- case CONDITION_ISHOUSEOWNER:
- local_6c[0].TypeID = Temp->ObjectID;
- local_5c[0] = Obj2->ObjectID;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- GetObjectCoordinates((Object *)&z1,&z2,&x1,&y1);
- local_6c[0].TypeID = Temp->ObjectID;
- local_5c[0] = Obj2->ObjectID;
- local_4c[0] = Obj1->ObjectID;
- local_3c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- Object::getObjectType((Object *)&z1);
- if (z1 == 99) {
- z1 = local_2c.ObjectID;
- pTVar9 = (TPlayer *)GetCreature((Object *)&z1);
- local_a5 = false;
- if ((pTVar9 != (TPlayer *)0x0) && ((pTVar9->super_TCreature).Type == PLAYER)) {
- HouseID = GetHouseID(z2,x1,y1);
- cVar3 = IsOwner(HouseID,pTVar9);
- goto LAB_08072b84;
- }
- }
- break;
- case CONDITION_ISDRESSED:
- local_6c[0].TypeID = Temp->ObjectID;
- puVar17 = local_4c;
- local_5c[0] = Obj2->ObjectID;
- puVar16 = local_3c;
- local_4c[0] = Obj1->ObjectID;
- puVar15 = local_5c;
- local_3c[0] = User->ObjectID;
- pOVar8 = local_6c;
- GetEventObject();
- local_2c.ObjectID = local_7c[0].ObjectID;
- z1 = local_7c[0].ObjectID;
- Object::getObjectType((Object *)&z1);
- uVar14 = 0x2e;
- bVar4 = ObjectType::getFlag((ObjectType *)&z1,CLOTHES);
- if (bVar4) {
- z1 = local_2c.ObjectID;
- uVar10 = GetObjectBodyPosition((Object *)&z1);
- Object::getObjectType(local_7c);
- uVar11 = ObjectType::getAttribute((ObjectType *)local_7c,BODYPOSITION);
- local_a5 = uVar10 == uVar11;
- }
- else {
- error(&DAT_080f7a60,uVar14,puVar16,puVar17,puVar15,pOVar8);
- }
- break;
- case CONDITION_RANDOM:
- lVar12 = random();
- local_a5 = lVar12 <= Condition->Parameters[0];
- break;
- default:
- error("CheckCondition: Unbekannte Bedingung %d.\n",Condition->Condition);
- goto LAB_08072659;
- }
- MVar1 = Condition->Modifier;
- if (MVar1 == MODIFIER_INVERT) {
- local_a5 = (bool)(local_a5 ^ 1);
- }
- else {
- if ((int)MVar1 < 2) {
- if (MVar1 == MODIFIER_NORMAL) {
- return local_a5;
- }
- }
- else if (MVar1 == MODIFIER_TRUE) {
- return true;
- }
-LAB_08072659:
- local_a5 = false;
- }
- return local_a5;
-}
-
-
-
-Object CreateObject(Object *Con,ObjectType *Type,ulong Value)
-
-{
- bool bVar1;
- ObjectType *Type_00;
- RESULT r;
- int x;
- int y;
- int z;
- Object local_3c [4];
- Object local_2c [7];
-
- // try { // try from 08073896 to 08073934 has its CatchHandler @ 08073937
- Object::getObjectType(local_2c);
- bVar1 = false;
- if ((0 < (int)local_2c[0].ObjectID) && ((int)local_2c[0].ObjectID < 0xb)) {
- bVar1 = true;
- }
- if (bVar1) {
- ObjectType::setTypeID((ObjectType *)local_2c,*(int *)Value);
- local_3c[0].ObjectID = Type->TypeID;
- Type_00 = (ObjectType *)GetObjectCreatureID(local_3c);
- CreateAtCreature((ulong)Con,Type_00,(ulong)local_2c);
- }
- else {
- ObjectType::setTypeID((ObjectType *)local_3c,*(int *)Value);
- local_2c[0].ObjectID = Type->TypeID;
- Create(Con,(ObjectType *)local_2c,(ulong)local_3c);
- }
- return (Object)(ulong)Con;
-}
-
-
-
-void ChangeObject(Object *Obj,ObjectType *NewType,ulong Value)
-
-{
- bool bVar1;
- ulong uVar2;
- RESULT r;
- char *Text;
- int iVar3;
- Object local_5c [4];
- Object local_4c [4];
- Object local_3c [4];
- Object local_2c;
- Object Con;
-
- // try { // try from 08073a18 to 08073a5c has its CatchHandler @ 08073ce0
- bVar1 = Object::exists(Obj);
- if (bVar1) {
- Object::getContainer(&local_2c);
- bVar1 = Object::exists(Obj);
- if (bVar1) {
- // try { // try from 08073a6f to 08073b27 has its CatchHandler @ 08073b42
- Object::getObjectType(local_3c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_3c,CUMULATIVE);
- if ((bVar1) && (uVar2 = Object::getAttribute(Obj,AMOUNT), 1 < uVar2)) {
- local_3c[0].ObjectID = NONE.ObjectID;
- uVar2 = Object::getAttribute(Obj,AMOUNT);
- local_4c[0].ObjectID = local_2c.ObjectID;
- local_5c[0] = (Object)Obj->ObjectID;
- Move(0,local_5c,local_4c,uVar2 - 1,true,local_3c);
- }
- ObjectType::setTypeID((ObjectType *)local_5c,NewType->TypeID);
- local_4c[0] = (Object)Obj->ObjectID;
- Change(local_4c,(ObjectType *)local_5c,Value);
- return;
- }
- iVar3 = NewType->TypeID;
- Text = &DAT_080f7ba0;
- }
- else {
- iVar3 = NewType->TypeID;
- Text = &DAT_080f7b40;
- }
- error(Text,iVar3);
- return;
-}
-
-
-
-void MoveOneObject(Object *Obj,Object *Con)
-
-{
- bool bVar1;
- RESULT r;
- char *Text;
- int x;
- int y;
- int z;
- Object local_3c [4];
- Object local_2c [7];
-
- bVar1 = Object::exists(Obj);
- if (bVar1) {
- bVar1 = Object::exists(Con);
- if (bVar1) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,CONTAINER);
- if (bVar1) {
- Object::getObjectType(local_2c);
- if ((local_2c[0].ObjectID != 99) ||
- (Object::getObjectType(local_2c), local_2c[0].ObjectID == 0)) {
- // try { // try from 08073da1 to 08073e39 has its CatchHandler @ 08073e4c
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,LIQUIDPOOL);
- if (!bVar1) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,MAGICFIELD);
- if (!bVar1) {
- local_2c[0].ObjectID = NONE.ObjectID;
- local_3c[0] = (Object)Con->ObjectID;
- z = Obj->ObjectID;
- Move(0,(Object *)&z,local_3c,-1,true,local_2c);
- return;
- }
- }
- local_2c[0] = (Object)Obj->ObjectID;
- Delete(local_2c,-1);
- return;
- }
- Text = "MoveOneObject: \"Con\" ist kein MapContainer.\n";
- goto LAB_08073d18;
- }
- }
- Text = "MoveOneObject: \"Con\" ist kein Container.\n";
- }
- else {
- Text = &DAT_080f7c60;
- }
-LAB_08073d18:
- error(Text);
- return;
-}
-
-
-
-void MoveAllObjects(Object *Obj,Object *Dest,Object *Exclude,bool MoveUnmovable)
-
-{
- bool bVar1;
- Object *pOVar2;
- bool MoveUnmovable_local;
- int x;
- int y;
- int z;
- Object local_4c;
- ObjectType Type;
- Object local_3c [4];
- Object local_2c [7];
-
- local_2c[0].ObjectID = NONE.ObjectID;
- if (Obj->ObjectID != NONE.ObjectID) {
- pOVar2 = Dest;
- Object::getObjectType(local_2c);
- if (local_2c[0].ObjectID == 0) {
- local_2c[0] = (Object)Exclude->ObjectID;
- local_3c[0] = (Object)Dest->ObjectID;
- Object::getNextObject(&local_4c);
- MoveAllObjects(&local_4c,local_3c,local_2c,MoveUnmovable);
- local_4c = (Object)Exclude->ObjectID;
- if (Obj->ObjectID != local_4c.ObjectID) {
- Object::getObjectType(&local_4c);
- // try { // try from 08073fb1 to 0807408e has its CatchHandler @ 08074094
- Object::getObjectType(local_3c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_3c,LIQUIDPOOL);
- if (!bVar1) {
- Object::getObjectType(local_3c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_3c,MAGICFIELD);
- if (!bVar1) {
- if (!MoveUnmovable) {
- Object::getObjectType(local_3c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_3c,UNMOVE);
- if (bVar1) {
- return;
- }
- }
- local_3c[0].ObjectID = NONE.ObjectID;
- local_2c[0] = (Object)Dest->ObjectID;
- z = Obj->ObjectID;
- Move(0,(Object *)&z,local_2c,-1,true,local_3c);
- return;
- }
- }
- local_3c[0] = (Object)Obj->ObjectID;
- Delete(local_3c,-1);
- }
- }
- else {
- error("MoveAllObjects: \"Dest\" ist kein Mapcontainer.\n",pOVar2);
- }
- }
- return;
-}
-
-
-
-void DeleteAllObjects(Object *Obj,Object *Exclude,bool DeleteUnmovable)
-
-{
- bool bVar1;
- RESULT r;
- int iStack_48;
- bool DeleteUnmovable_local;
- int x;
- int y;
- int z;
- Object local_2c [7];
-
- if (Obj->ObjectID != NONE.ObjectID) {
- local_2c[0] = (Object)Exclude->ObjectID;
- Object::getNextObject((Object *)&z);
- DeleteAllObjects((Object *)&z,local_2c,DeleteUnmovable);
- z = Exclude->ObjectID;
- if (Obj->ObjectID != z) {
- Object::getObjectType((Object *)&z);
- if (z == 99) {
- z = Obj->ObjectID;
- GetObjectCoordinates((Object *)&z,&stack0xffffffb8,&x,&y);
- error(&DAT_080f7e00,iStack_48,x,y);
- }
- else {
- if (!DeleteUnmovable) {
- // try { // try from 080741bb to 08074244 has its CatchHandler @ 0807429b
- Object::getObjectType((Object *)&z);
- bVar1 = ObjectType::getFlag((ObjectType *)&z,UNMOVE);
- if (bVar1) {
- Object::getObjectType((Object *)&z);
- bVar1 = ObjectType::getFlag((ObjectType *)&z,LIQUIDPOOL);
- if (!bVar1) {
- Object::getObjectType((Object *)&z);
- bVar1 = ObjectType::getFlag((ObjectType *)&z,MAGICFIELD);
- if (!bVar1) {
- return;
- }
- }
- }
- }
- z = Obj->ObjectID;
- Delete((Object *)&z,-1);
- }
- }
- }
- return;
-}
-
-
-
-void ClearField(Object *Obj,Object *Exclude)
-
-{
- bool bVar1;
- bool bVar2;
- Object *this;
- Object *Exclude_00;
- int local_58;
- int x;
- int y;
- int z;
- Object local_3c [4];
- Object local_2c [7];
-
- bVar1 = Object::exists(Obj);
- if (!bVar1) {
- error("ClearField: Objekt existiert nicht.\n");
- return;
- }
- local_2c[0] = (Object)Obj->ObjectID;
- GetObjectCoordinates(local_2c,&local_58,&x,&y);
- bVar1 = false;
- bVar2 = CoordinateFlag();
- if (bVar2) {
- bVar1 = CoordinateFlag();
- bVar1 = !bVar1;
- }
- if (bVar1) {
- this = (Object *)&z;
- local_2c[0] = (Object)Exclude->ObjectID;
- GetMapContainer((int)local_3c,local_58 + 1,x);
- Object::getNextObject(this);
- Exclude_00 = local_2c;
- goto LAB_080743c6;
- }
- bVar1 = false;
- bVar2 = CoordinateFlag();
- if (bVar2) {
- bVar1 = CoordinateFlag();
- bVar1 = !bVar1;
- }
- if (bVar1) {
-LAB_08074550:
- z = Exclude->ObjectID;
- x = x + 1;
-LAB_0807449d:
- GetMapContainer((int)local_3c,local_58,x);
- Object::getNextObject(local_2c);
- }
- else {
- bVar1 = false;
- bVar2 = CoordinateFlag();
- if (bVar2) {
- bVar1 = CoordinateFlag();
- bVar1 = !bVar1;
- }
- if (bVar1) {
-LAB_08074594:
- z = Exclude->ObjectID;
- local_58 = local_58 + -1;
- goto LAB_0807449d;
- }
- bVar1 = false;
- bVar2 = CoordinateFlag();
- if (bVar2) {
- bVar1 = CoordinateFlag();
- bVar1 = !bVar1;
- }
- if (bVar1) {
- z = Exclude->ObjectID;
- x = x + -1;
- goto LAB_0807449d;
- }
- bVar1 = JumpPossible(local_58 + 1,x,y,false);
- if (bVar1) {
- z = Exclude->ObjectID;
- local_58 = local_58 + 1;
- goto LAB_0807449d;
- }
- bVar1 = JumpPossible(local_58,x + 1,y,false);
- if (bVar1) goto LAB_08074550;
- bVar1 = JumpPossible(local_58 + -1,x,y,false);
- if (bVar1) goto LAB_08074594;
- bVar1 = JumpPossible(local_58,x + -1,y,false);
- if (!bVar1) {
- return;
- }
- z = Exclude->ObjectID;
- GetMapContainer((int)local_3c,local_58,x + -1);
- Object::getNextObject(local_2c);
- }
- Exclude_00 = (Object *)&z;
- this = local_2c;
-LAB_080743c6:
- MoveAllObjects(this,local_3c,Exclude_00,true);
- return;
-}
-
-
-
-void LoadDepotBox(ulong CreatureID,int Nr,Object *Con)
-
-{
- bool bVar1;
- TCreature *pTVar2;
- int iVar3;
- int iVar4;
- TCreature *cr;
- char *pcVar5;
- Object local_3c [4];
- Object local_2c [7];
-
- // try { // try from 0807470b to 08074872 has its CatchHandler @ 08074890
- pTVar2 = GetCreature(CreatureID);
- if (pTVar2 == (TCreature *)0x0) {
- pcVar5 = "moveuse::LoadDepotBox: Kreatur nicht gefunden.\n";
- }
- else {
- bVar1 = Object::exists(Con);
- if (bVar1) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,CONTAINER);
- if (bVar1) {
- if (pTVar2->Type == PLAYER) {
- local_2c[0] = (Object)Con->ObjectID;
- LoadDepot((TPlayerData *)pTVar2[1].super_TSkillBase.TimerList[10],Nr,local_2c);
- local_2c[0] = (Object)Con->ObjectID;
- pTVar2[1].super_TSkillBase.TimerList[6] = (TSkill *)local_2c[0].ObjectID;
- pTVar2[1].super_TSkillBase.TimerList[7] = (TSkill *)Nr;
- local_3c[0] = (Object)Con->ObjectID;
- iVar3 = CountObjects(local_3c);
- iVar3 = iVar3 + -1;
- bVar1 = CheckRight(pTVar2->ID,PREMIUM_ACCOUNT);
- iVar4 = GetDepotSize(Nr,bVar1);
- pTVar2[1].super_TSkillBase.TimerList[8] = (TSkill *)(iVar4 - iVar3);
- print();
- pcVar5 = "s";
- if (iVar3 == 1) {
- pcVar5 = "";
- }
- SendMessage(pTVar2->Connection,0x15,"Your depot contains %d item%s.",iVar3,
- pcVar5);
- if (-1 < (int)pTVar2[1].super_TSkillBase.TimerList[8]) {
- return;
- }
- SendMessage(pTVar2->Connection,0x16,
- "Your depot is full. Remove surplus items before storing new ones.",
- iVar3,pcVar5);
- return;
- }
- pcVar5 = "moveuse::LoadDepotBox: Kreatur ist kein Spieler.\n";
- }
- else {
- pcVar5 = &DAT_080f8020;
- }
- }
- else {
- pcVar5 = &DAT_080f7ee0;
- }
- }
- error(pcVar5);
- return;
-}
-
-
-
-void SaveDepotBox(ulong CreatureID,int Nr,Object *Con)
-
-{
- bool bVar1;
- TCreature *pTVar2;
- int iVar3;
- TCreature *cr;
- char *Text;
- int Count;
- Object Obj;
- Object local_2c [7];
-
- // try { // try from 080748cb to 08074a1a has its CatchHandler @ 08074a40
- pTVar2 = GetCreature(CreatureID);
- if (pTVar2 == (TCreature *)0x0) {
- Text = "moveuse::SaveDepotBox: Kreatur nicht gefunden.\n";
- }
- else {
- bVar1 = Object::exists(Con);
- if (bVar1) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,CONTAINER);
- if (bVar1) {
- if (pTVar2->Type == PLAYER) {
- local_2c[0] = (Object)Con->ObjectID;
- iVar3 = CountObjects(local_2c);
- Log("game",&DAT_080f8120,Nr,pTVar2->Name,iVar3 + -1);
- print();
- local_2c[0] = (Object)Con->ObjectID;
- SaveDepot((TPlayerData *)pTVar2[1].super_TSkillBase.TimerList[10],Nr,local_2c);
- Count = NONE.ObjectID;
- pTVar2[1].super_TSkillBase.TimerList[6] = (TSkill *)NONE.ObjectID;
- while( true ) {
- local_2c[0] = (Object)Con->ObjectID;
- GetFirstContainerObject((Object *)&Count);
- if (Count == NONE.ObjectID) break;
- local_2c[0].ObjectID = Count;
- Delete(local_2c,-1);
- }
- return;
- }
- Text = "moveuse::SaveDepotBox: Kreatur ist kein Spieler.\n";
- }
- else {
- Text = &DAT_080f81c0;
- }
- }
- else {
- Text = &DAT_080f80a0;
- }
- }
- error(Text);
- return;
-}
-
-
-
-void SendMail(Object *Obj)
-
-{
- uint *Text_00;
- TPlayer *pTVar1;
- ulong uVar2;
- bool bVar3;
- RESULT r_1;
- ulong uVar4;
- char *pcVar5;
- int iVar6;
- TDelayedMail *pTVar7;
- uchar *__dest;
- char *Text;
- uint *puVar8;
- uint *puVar9;
- char cVar10;
- uint uVar11;
- uint uVar12;
- int pos;
- int iVar13;
- int pos2;
- int iVar14;
- int *this;
- bool PlayerOnline;
- int DepotNumber;
- TPlayer *local_280;
- TPlayer *Player;
- char Town [256];
- char Addressee [256];
- undefined1 local_6c [4];
- TDynamicWriteBuffer Buffer;
- Object Label;
- Object local_4c [4];
- Object local_3c [4];
- Object local_2c [7];
-
- // try { // try from 08074a78 to 08074d69 has its CatchHandler @ 08075210
- bVar3 = Object::exists(Obj);
- if (bVar3) {
- bVar3 = false;
- Object::getObjectType(local_2c);
- GetSpecialObject((SPECIALMEANING)local_3c);
- ObjectType::setTypeID((ObjectType *)local_4c,local_3c[0].ObjectID);
- if (local_2c[0].ObjectID != local_4c[0].ObjectID) {
- Object::getObjectType(local_4c);
- GetSpecialObject((SPECIALMEANING)&Buffer.super_TWriteBuffer.Position);
- ObjectType::setTypeID((ObjectType *)local_6c,Buffer.super_TWriteBuffer.Position);
- if ((undefined1 [4])local_4c[0].ObjectID != local_6c) {
- bVar3 = true;
- }
- }
- if (!bVar3) {
- print();
- Object::getObjectType((Object *)local_6c);
- GetSpecialObject((SPECIALMEANING)&Buffer.super_TWriteBuffer.Position);
- this = (int *)Obj;
- if (local_6c != (undefined1 [4])Buffer.super_TWriteBuffer.Position) {
- local_4c[0] = (Object)Obj->ObjectID;
- GetFirstContainerObject((Object *)&Buffer.super_TWriteBuffer.Position);
- while( true ) {
- bVar3 = false;
- local_4c[0].ObjectID = NONE.ObjectID;
- local_3c[0].ObjectID = NONE.ObjectID;
- if (Buffer.super_TWriteBuffer.Position != NONE.ObjectID) {
- Object::getObjectType(local_3c);
- GetSpecialObject((SPECIALMEANING)local_2c);
- ObjectType::setTypeID((ObjectType *)(Addressee + 0xfc),local_2c[0].ObjectID)
- ;
- if (local_3c[0].ObjectID != Addressee._252_4_) {
- bVar3 = true;
- }
- }
- if (!bVar3) break;
- Object::getNextObject(local_4c);
- Addressee._252_4_ = local_4c[0].ObjectID;
- Buffer.super_TWriteBuffer.Position = Addressee._252_4_;
- }
- Addressee._252_4_ = NONE.ObjectID;
- if (Buffer.super_TWriteBuffer.Position == NONE.ObjectID) {
- return;
- }
- this = &Buffer.super_TWriteBuffer.Position;
- }
- uVar4 = Object::getAttribute((Object *)this,TEXTSTRING);
- pcVar5 = GetDynamicString(uVar4);
- if (pcVar5 != (char *)0x0) {
- cVar10 = *pcVar5;
- iVar13 = 0;
- if ((cVar10 != '\n') && (cVar10 != '\0')) {
- while( true ) {
- Town[iVar13 + 0xfc] = cVar10;
- iVar13 = iVar13 + 1;
- cVar10 = pcVar5[iVar13];
- if (cVar10 == '\n') break;
- if ((cVar10 == '\0') || (0xff < iVar13)) break;
- }
- }
- iVar14 = 0;
- Town[iVar13 + 0xfc] = '\0';
- if ((pcVar5[iVar13 + 1] != '\n') && (iVar6 = iVar13, pcVar5[iVar13 + 1] != '\0')) {
- do {
- Town[iVar14 + -4] = pcVar5[iVar6 + 1];
- iVar14 = iVar14 + 1;
- if ((pcVar5[iVar14 + iVar13 + 1] == '\n') ||
- (pcVar5[iVar14 + iVar13 + 1] == '\0')) break;
- iVar6 = iVar14 + iVar13;
- } while (iVar14 < 0x100);
- }
- Town[iVar14 + -4] = '\0';
- Text_00 = (uint *)(Town + 0xfc);
- Trim((char *)Text_00);
- Trim((char *)&Player);
- puVar9 = Text_00;
- if (Town[0xfc] != '\0') {
- do {
- puVar8 = puVar9;
- uVar11 = *puVar8 + 0xfefefeff & ~*puVar8;
- uVar12 = uVar11 & 0x80808080;
- puVar9 = puVar8 + 1;
- } while (uVar12 == 0);
- bVar3 = (uVar11 & 0x8080) == 0;
- if (bVar3) {
- uVar12 = uVar12 >> 0x10;
- }
- if (bVar3) {
- puVar9 = (uint *)((int)puVar8 + 6);
- }
- if (((char *)((int)puVar9 +
- ((-3 - (uint)CARRY1((byte)uVar12,(byte)uVar12)) - (int)Text_00)) <
- (char *)0x1e) && ((char)Player != '\0')) {
- Log("game","Post an %s in %s.\n",Text_00,&Player);
- iVar13 = GetDepotNumber((char *)&Player);
- if (iVar13 != -1) {
- iVar14 = IdentifyPlayer((char *)Text_00,true,true,&local_280);
- bVar3 = iVar14 == 0;
- if (bVar3) {
- uVar4 = (local_280->super_TCreature).ID;
- }
- else {
- // try { // try from 08075019 to 08075139 has its CatchHandler @ 08075210
- uVar4 = GetCharacterID((char *)Text_00);
- if (uVar4 == 0) {
- return;
- }
- }
- uVar2 = Addressee._252_4_;
- if ((bVar3) && (local_280->DepotNr == iVar13)) {
- local_6c = (undefined1 [4])NONE.ObjectID;
- Addressee[0xfc] = (undefined1)NONE.ObjectID;
- Addressee[0xfd] = NONE.ObjectID._1_1_;
- Addressee[0xfe] = NONE.ObjectID._2_1_;
- Addressee[0xff] = NONE.ObjectID._3_1_;
- uVar2 = (ulong)local_6c;
- if ((local_280->Depot).ObjectID != NONE.ObjectID) {
- print();
- local_6c = (undefined1 [4])NONE.ObjectID;
- Buffer.super_TWriteBuffer.Position = (local_280->Depot).ObjectID
- ;
- local_4c[0] = (Object)Obj->ObjectID;
- // try { // try from 08074ef3 to 08075003 has its CatchHandler @ 08075152
- Move(0,local_4c,(Object *)&Buffer.super_TWriteBuffer.Position,-1
- ,true,(Object *)local_6c);
- Object::getObjectType((Object *)local_6c);
- GetSpecialObject((SPECIALMEANING)
- &Buffer.super_TWriteBuffer.Position);
- GetSpecialObject((SPECIALMEANING)
- &Buffer.super_TWriteBuffer.Position);
- local_4c[0] = (Object)Obj->ObjectID;
- Change(local_4c,(ObjectType *)
- &Buffer.super_TWriteBuffer.Position,0);
- Log("game","Post an %s in %s versandt.\n",Text_00,&Player);
- pTVar1 = local_280;
- local_6c = (undefined1 [4])Obj->ObjectID;
- iVar13 = CountObjects((Object *)local_6c);
- pTVar1->DepotSpace = pTVar1->DepotSpace - iVar13;
- iVar13 = local_280->DepotSpace;
- print();
- SendMessage((local_280->super_TCreature).Connection,0x16,
- "New mail has arrived.",iVar13);
- print();
- return;
- }
- }
- Addressee._252_4_ = uVar2;
- print();
- Object::getObjectType((Object *)local_6c);
- GetSpecialObject((SPECIALMEANING)&Buffer.super_TWriteBuffer.Position);
- GetSpecialObject((SPECIALMEANING)&Buffer.super_TWriteBuffer.Position);
- local_4c[0] = (Object)Obj->ObjectID;
- Change(local_4c,(ObjectType *)&Buffer.super_TWriteBuffer.Position,0);
- // try { // try from 08074d78 to 08074d7c has its CatchHandler @ 08075205
- TDynamicWriteBuffer::TDynamicWriteBuffer
- ((TDynamicWriteBuffer *)local_6c,0x400);
- Buffer.super_TWriteBuffer.Position = Obj->ObjectID;
- // try { // try from 08074d97 to 08074de3 has its CatchHandler @ 080751b6
- SaveObjects((Object *)&Buffer.super_TWriteBuffer.Position,
- (TWriteStream *)local_6c,true);
- Buffer.super_TWriteBuffer.Position = Obj->ObjectID;
- Delete((Object *)&Buffer.super_TWriteBuffer.Position,-1);
- pTVar7 = vector<>::operator()(&DelayedMail,DelayedMails);
- pTVar7->CharacterID = uVar4;
- pTVar7->DepotNumber = iVar13;
- pTVar7->PacketSize = Buffer.super_TWriteBuffer.Size;
- __dest = (uchar *)operator_new__(Buffer.super_TWriteBuffer.Size);
- pTVar7->Packet = __dest;
- memcpy(__dest,Buffer.super_TWriteBuffer.super_TWriteStream.
- _vptr_TWriteStream,pTVar7->PacketSize);
- // try { // try from 08074e03 to 08074e07 has its CatchHandler @ 08075205
- TDynamicWriteBuffer::~TDynamicWriteBuffer
- ((TDynamicWriteBuffer *)local_6c,
- (int)Buffer.super_TWriteBuffer.super_TWriteStream.
- _vptr_TWriteStream);
- DelayedMails = DelayedMails + 1;
- // try { // try from 08074e2b to 08074eaa has its CatchHandler @ 08075210
- Log("game",&DAT_080f82c0,Text_00,&Player);
- print();
- if (bVar3) {
- SendMails(local_280->PlayerData);
- }
- else {
- LoadCharacterOrder(uVar4);
- }
- }
- }
- }
- }
- }
- }
- else {
- error(&DAT_080f8240);
- }
- return;
-}
-
-
-
-void SendMails(TPlayerData *PlayerData)
-
-{
- __pid_t _Var1;
- TDelayedMail *pTVar2;
- uint uVar3;
- uchar *__dest;
- TDelayedMail *pTVar4;
- int iVar5;
- TDelayedMail *D;
- int i;
- int i_00;
- bool bVar6;
- char *Text;
- uchar *NewDepot;
- int NewDepotSize;
- ushort local_3c;
- bool DepotEmpty;
- undefined1 local_2c [4];
- TWriteBuffer Buffer;
-
- if (PlayerData == (TPlayerData *)0x0) {
- Text = "SendMails: PlayerData ist NULL.\n";
- }
- else if (PlayerData->CharacterID == 0) {
- Text = "SendMails: Slot ist nicht belegt.\n";
- }
- else {
- _Var1 = getpid();
- if (PlayerData->Locked == _Var1) {
- if (DelayedMails < 1) {
- return;
- }
- i_00 = 0;
- do {
- pTVar2 = vector<>::operator()(&DelayedMail,i_00);
- if (pTVar2->CharacterID == PlayerData->CharacterID) {
- iVar5 = pTVar2->DepotNumber;
- bVar6 = false;
- if ((-1 < iVar5) && (iVar5 < 9)) {
- bVar6 = true;
- }
- if (!bVar6) {
- error(&DAT_080f84e0,iVar5);
- iVar5 = 0;
- pTVar2->DepotNumber = 0;
- }
- bVar6 = PlayerData->Depot[iVar5] != (uchar *)0x0;
- if (bVar6) {
- uVar3 = pTVar2->PacketSize + PlayerData->DepotSize[iVar5];
- }
- else {
- uVar3 = pTVar2->PacketSize + 5;
- }
- __dest = (uchar *)operator_new__(uVar3);
- memcpy(__dest,pTVar2->Packet,pTVar2->PacketSize);
- if (pTVar2->Packet != (uchar *)0x0) {
- operator_delete__(pTVar2->Packet);
- }
- if (bVar6) {
- memcpy(__dest + pTVar2->PacketSize,PlayerData->Depot[pTVar2->DepotNumber],
- PlayerData->DepotSize[pTVar2->DepotNumber]);
- iVar5 = pTVar2->DepotNumber;
- if (PlayerData->Depot[iVar5] != (uchar *)0x0) {
- operator_delete__(PlayerData->Depot[iVar5]);
- goto LAB_0807537c;
- }
- }
- else {
- TWriteBuffer::TWriteBuffer
- ((TWriteBuffer *)local_2c,__dest + pTVar2->PacketSize,5);
- GetSpecialObject((SPECIALMEANING)&local_3c);
- TWriteBuffer::writeWord((TWriteBuffer *)local_2c,local_3c);
- TWriteBuffer::writeByte((TWriteBuffer *)local_2c,0xff);
- TWriteBuffer::writeWord((TWriteBuffer *)local_2c,0xffff);
-LAB_0807537c:
- iVar5 = pTVar2->DepotNumber;
- }
- PlayerData->Depot[iVar5] = __dest;
- iVar5 = pTVar2->DepotNumber;
- PlayerData->Dirty = true;
- PlayerData->DepotSize[iVar5] = uVar3;
- Log("game","Post an %s zugestellt.\n",PlayerData->Name);
- if (i_00 != DelayedMails + -1) {
- pTVar2 = vector<>::operator()(&DelayedMail,i_00);
- pTVar4 = vector<>::operator()(&DelayedMail,DelayedMails + -1);
- pTVar2->CharacterID = pTVar4->CharacterID;
- pTVar2->DepotNumber = pTVar4->DepotNumber;
- pTVar2->Packet = pTVar4->Packet;
- pTVar2->PacketSize = pTVar4->PacketSize;
- }
- DelayedMails = DelayedMails + -1;
- i_00 = i_00 + -1;
- }
- i_00 = i_00 + 1;
- if (DelayedMails <= i_00) {
- return;
- }
- } while( true );
- }
- Text = "SendMails: Slot ist nicht vom GameThread gesperrt.\n";
- }
- error(Text);
- return;
-}
-
-
-
-void TextEffect(char *Text,int x,int y,int z,int Radius)
-
-{
- TConnection *this;
- ulong ID;
- ulong CharacterID;
- TPlayer *pTVar1;
- TConnection *Connection;
- int local_58;
- int destX;
- int destY;
- int destZ;
- TFindCreatures Search;
-
- if (Text == (char *)0x0) {
- error("TextEffect: Text existiert nicht.\n");
- }
- else {
- TFindCreatures::TFindCreatures((TFindCreatures *)&destZ,Radius,Radius,x,y,1);
- while( true ) {
- CharacterID = TFindCreatures::getNext((TFindCreatures *)&destZ);
- if (CharacterID == 0) break;
- pTVar1 = GetPlayer(CharacterID);
- if ((pTVar1 != (TPlayer *)0x0) &&
- (this = (pTVar1->super_TCreature).Connection, this != (TConnection *)0x0)) {
- TConnection::GetPosition(this,&local_58,&destX,&destY);
- if (((7 < Radius) || (z == destY)) &&
- (((0x1e < Radius || (z == destY)) || ((z < 8 && (destY < 8)))))) {
- SendTalk(this,0,"",0x10,x,y,z,Text);
- }
- }
- }
- }
- return;
-}
-
-
-
-void ExecuteAction(EventType Event,TMoveUseAction *Action,Object *User,Object *Obj1,Object *Obj2,
- Object *Temp)
-
-{
- bool bVar1;
- ulong uVar2;
- TPlayer *pTVar3;
- undefined4 *puVar4;
- char *__s;
- size_t sVar5;
- TCreature *pTVar6;
- ulong uVar7;
- int iVar8;
- uint *puVar9;
- uint *puVar10;
- RESULT r;
- uint uVar11;
- uint uVar12;
- TCreature *cr;
- bool bVar13;
- char *pcVar14;
- ActionType AVar15;
- Object *pOVar16;
- INSTANCEATTRIBUTE Attribute;
- ulong *puVar17;
- Object *pOVar18;
- Object *pOVar19;
- Object *pOVar20;
- int local_1c4;
- int pos;
- char *Text2;
- TCreature *cr2;
- int dx;
- int dy;
- int dz;
- int x;
- int y;
- int z;
- Object local_18c [4];
- Object local_17c [4];
- Object local_16c [4];
- Object local_15c [4];
- ulong local_14c [4];
- uint local_13c;
- char Text [256];
- Object Con;
- Object local_2c;
- Object Obj;
-
- Text[0xfc] = '\0';
- Text[0xfd] = '\0';
- Text[0xfe] = '\0';
- Text[0xff] = '\0';
- local_2c.ObjectID = 0;
- switch(Action->Action) {
- case ACTION_CREATEONMAP:
- // try { // try from 08075619 to 08077e1c has its CatchHandler @ 08077e32
- UnpackAbsoluteCoordinate();
- ObjectType::setTypeID((ObjectType *)local_16c,Action->Parameters[1]);
- GetMapContainer((int)local_17c,dz,x);
- CreateObject(local_15c,(ObjectType *)local_17c,(ulong)local_16c);
- Temp->ObjectID = (ulong)local_15c[0];
- break;
- case ACTION_CREATE:
- local_15c[0] = (Object)Temp->ObjectID;
- local_14c[0] = Obj2->ObjectID;
- local_18c[0] = (Object)Obj1->ObjectID;
- z = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_16c[0].ObjectID;
- local_17c[0].ObjectID = local_16c[0].ObjectID;
- ObjectType::setTypeID((ObjectType *)local_17c,Action->Parameters[1]);
- Object::getContainer(local_16c);
- CreateObject(local_18c,(ObjectType *)local_16c,(ulong)local_17c);
- Temp->ObjectID = (ulong)local_18c[0];
- break;
- case ACTION_MONSTERONMAP:
- UnpackAbsoluteCoordinate();
- iVar8 = Action->Parameters[1];
- goto LAB_080757f5;
- case ACTION_MONSTER:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- GetObjectCoordinates((Object *)&z,&dz,&x,&y);
- iVar8 = Action->Parameters[1];
-LAB_080757f5:
- CreateMonster(iVar8,dz,x,y,0,0,true);
- break;
- case ACTION_EFFECTONMAP:
- UnpackAbsoluteCoordinate();
- GetMapContainer((int)&z,dz,x);
- goto LAB_08075945;
- case ACTION_EFFECT:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- GetMapContainer((Object *)&z);
-LAB_08075945:
- GraphicalEffect((Object *)&z,Action->Parameters[1]);
- break;
- case ACTION_TEXTONMAP:
- UnpackAbsoluteCoordinate();
- pcVar14 = GetDynamicString(Action->Parameters[1]);
- goto LAB_08075a34;
- case ACTION_TEXT:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- GetObjectCoordinates((Object *)&z,&dz,&x,&y);
- pcVar14 = GetDynamicString(Action->Parameters[1]);
-LAB_08075a34:
- TextEffect(pcVar14,dz,x,y,Action->Parameters[2]);
- break;
- case ACTION_CHANGEONMAP:
- UnpackAbsoluteCoordinate();
- ObjectType::setTypeID((ObjectType *)local_17c,Action->Parameters[1]);
- GetFirstSpecObject();
- Temp->ObjectID = (ulong)local_18c[0];
- z = NONE.ObjectID;
- if (Temp->ObjectID == NONE.ObjectID) {
- iVar8 = Action->Parameters[1];
- pcVar14 = "ExecuteAction (CHANGEONMAP): Kein Objekt %d auf [%d,%d,%d].\n";
-LAB_08075be0:
- NONE.ObjectID = z;
- error(pcVar14,iVar8,dz,x,y);
- return;
- }
- ObjectType::setTypeID((ObjectType *)&z,Action->Parameters[2]);
- local_18c[0] = (Object)Temp->ObjectID;
- uVar7 = Action->Parameters[3];
- goto LAB_08075c18;
- case ACTION_CHANGE:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- ObjectType::setTypeID((ObjectType *)&z,Action->Parameters[1]);
- local_18c[0].ObjectID = local_2c.ObjectID;
- uVar7 = Action->Parameters[2];
- goto LAB_08075c18;
- case ACTION_CHANGEREL:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- GetObjectCoordinates((Object *)&z,&dz,&x,&y);
- UnpackRelativeCoordinate();
- dz = (int)(cr2->super_TSkillBase).Skills + dz + -4;
- x = x + dx;
- y = y + dy;
- ObjectType::setTypeID((ObjectType *)local_17c,Action->Parameters[2]);
- GetFirstSpecObject();
- Temp->ObjectID = (ulong)local_18c[0];
- z = NONE.ObjectID;
- if (Temp->ObjectID == NONE.ObjectID) {
- iVar8 = Action->Parameters[2];
- pcVar14 = "ExecuteAction (CHANGEREL): Kein Objekt %d auf [%d,%d,%d].\n";
- goto LAB_08075be0;
- }
- ObjectType::setTypeID((ObjectType *)&z,Action->Parameters[3]);
- local_18c[0] = (Object)Temp->ObjectID;
- uVar7 = Action->Parameters[4];
-LAB_08075c18:
- ChangeObject(local_18c,(ObjectType *)&z,uVar7);
- break;
- case ACTION_SETATTRIBUTE:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- uVar7 = Action->Parameters[2];
- Attribute = Action->Parameters[1];
- goto LAB_08075f26;
- case ACTION_CHANGEATTRIBUTE:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- uVar7 = Object::getAttribute(&local_2c,Action->Parameters[1]);
- uVar7 = uVar7 + Action->Parameters[2];
- if ((int)uVar7 < 1) {
- dz = uVar7;
- uVar7 = Object::getAttribute(&local_2c,Action->Parameters[1]);
- uVar7 = (ulong)(uVar7 != 0);
- }
- Attribute = Action->Parameters[1];
- dz = uVar7;
- goto LAB_08075f26;
- case ACTION_SETQUESTVALUE:
- pOVar18 = local_15c;
- local_17c[0] = (Object)Temp->ObjectID;
- pOVar19 = local_16c;
- local_16c[0] = (Object)Obj2->ObjectID;
- puVar17 = local_14c;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- pOVar20 = local_17c;
- GetEventObject();
- pOVar16 = &local_2c;
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- Object::getObjectType((Object *)&z);
- if (z == 99) {
- z = local_2c.ObjectID;
- pTVar3 = (TPlayer *)GetCreature((Object *)&z);
- if ((pTVar3 != (TPlayer *)0x0) && ((pTVar3->super_TCreature).Type == PLAYER)) {
- TPlayer::SetQuestValue(pTVar3,Action->Parameters[1],Action->Parameters[2]);
- return;
- }
- pcVar14 =
- "ExecuteAction (SETQUESTVALUE): Kreatur existiert nicht oder ist kein Spieler.\n";
-LAB_08076102:
- error(pcVar14,pOVar16,puVar17,pOVar18,pOVar19,pOVar20);
- return;
- }
- Object::getObjectType((Object *)&z);
- pcVar14 = "ExecuteAction (SETQUESTVALUE): Objekt ist keine Kreatur, sondern Typ %ld.\n";
- AVar15 = z;
- goto switchD_080755eb_default;
- case ACTION_DAMAGE:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- Text2 = (char *)0x0;
- local_2c.ObjectID = local_18c[0].ObjectID;
- bVar13 = local_18c[0].ObjectID != NONE.ObjectID;
- z = NONE.ObjectID;
- local_18c[0].ObjectID = NONE.ObjectID;
- if (bVar13) {
- Object::getObjectType(local_18c);
- if (local_18c[0].ObjectID == 99) {
- local_18c[0].ObjectID = local_2c.ObjectID;
- Text2 = (char *)GetCreature(local_18c);
- }
- Object::getObjectType(local_18c);
- bVar13 = ObjectType::getFlag((ObjectType *)local_18c,MAGICFIELD);
- if ((bVar13) && (uVar7 = Object::getAttribute(&local_2c,RESPONSIBLE), uVar7 != 0)) {
- local_18c[0].ObjectID = local_2c.ObjectID;
- uVar7 = CronInfo(local_18c,false);
- Object::getObjectType(local_17c);
- uVar2 = ObjectType::getAttribute((ObjectType *)local_17c,TOTALEXPIRETIME);
- if (uVar2 < uVar7 + 5) {
- uVar7 = Object::getAttribute(&local_2c,RESPONSIBLE);
- Text2 = (char *)GetCreature(uVar7);
- }
- }
- }
- pOVar20 = local_17c;
- pOVar19 = local_16c;
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- puVar17 = local_14c;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- pOVar18 = local_15c;
- GetEventObject();
- pOVar16 = &local_2c;
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- Object::getObjectType((Object *)&z);
- if (z == 99) {
- z = local_2c.ObjectID;
- pTVar6 = GetCreature((Object *)&z);
- if (pTVar6 != (TCreature *)0x0) {
- TCreature::Damage(pTVar6,(TCreature *)Text2,Action->Parameters[3],
- Action->Parameters[2]);
- return;
- }
- pcVar14 = "ExecuteAction (DAMAGE): Kreatur existiert nicht.\n";
- goto LAB_08076102;
- }
- Object::getObjectType((Object *)&z);
- pcVar14 = "ExecuteAction (DAMAGE): Objekt ist keine Kreatur, sondern Typ %d.\n";
- AVar15 = z;
- goto switchD_080755eb_default;
- case ACTION_SETSTART:
- pOVar20 = local_16c;
- local_17c[0] = (Object)Temp->ObjectID;
- puVar17 = local_14c;
- local_16c[0] = (Object)Obj2->ObjectID;
- pOVar16 = local_15c;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- pOVar19 = local_17c;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- pcVar14 = (char *)&local_2c;
- Object::getObjectType((Object *)&z);
- uVar7 = Text._252_4_;
- if (z == 99) {
- z = local_2c.ObjectID;
- pTVar3 = (TPlayer *)GetCreature((Object *)&z);
- uVar7 = Text._252_4_;
- if ((pTVar3 != (TPlayer *)0x0) && ((pTVar3->super_TCreature).Type == PLAYER)) {
- Log("game",&DAT_080f8780,(pTVar3->super_TCreature).Name,pOVar16,pOVar20,pOVar19);
- UnpackAbsoluteCoordinate();
- TPlayer::SaveData(pTVar3);
- return;
- }
- }
- goto LAB_08076474;
- case ACTION_WRITENAME:
- local_17c[0] = (Object)Temp->ObjectID;
- pOVar20 = local_16c;
- local_16c[0] = (Object)Obj2->ObjectID;
- pOVar16 = local_15c;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- puVar17 = local_14c;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- pcVar14 = (char *)&local_2c;
- Object::getObjectType((Object *)&z);
- uVar7 = Text._252_4_;
- if (z != 99) goto LAB_08076474;
- z = local_2c.ObjectID;
- pTVar6 = GetCreature((Object *)&z);
- uVar7 = Text._252_4_;
- if (pTVar6 == (TCreature *)0x0) goto LAB_08076474;
- puVar10 = &local_13c;
- for (iVar8 = 0x40; iVar8 != 0; iVar8 = iVar8 + -1) {
- *puVar10 = 0;
- puVar10 = puVar10 + 1;
- }
- __s = GetDynamicString(Action->Parameters[1]);
- for (local_1c4 = 0; sVar5 = strlen(__s), local_1c4 < (int)sVar5; local_1c4 = local_1c4 + 1)
- {
- if ((__s[local_1c4] == '%') && (__s[local_1c4 + 1] == 'N')) {
- pcVar14 = pTVar6->Name;
- local_1c4 = local_1c4 + 1;
- strcat((char *)&local_13c,pcVar14);
- }
- else {
- puVar10 = &local_13c;
- do {
- puVar9 = puVar10;
- uVar11 = *puVar9 + 0xfefefeff & ~*puVar9;
- uVar12 = uVar11 & 0x80808080;
- puVar10 = puVar9 + 1;
- } while (uVar12 == 0);
- bVar13 = (uVar11 & 0x8080) == 0;
- if (bVar13) {
- uVar12 = uVar12 >> 0x10;
- }
- if (bVar13) {
- puVar10 = (uint *)((int)puVar9 + 6);
- }
- *(char *)((int)puVar10 + (-3 - (uint)CARRY1((byte)uVar12,(byte)uVar12))) =
- __s[local_1c4];
- }
- uVar7 = Text._252_4_;
- if (Text[0xc4] != '\0') goto LAB_08076474;
- }
- pOVar20 = local_16c;
- local_17c[0] = (Object)Temp->ObjectID;
- puVar17 = local_14c;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- pOVar16 = local_15c;
- pcVar14 = (char *)Action->Parameters[2];
- GetEventObject();
- bVar13 = false;
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = NONE.ObjectID;
- if (local_18c[0].ObjectID == NONE.ObjectID) {
-LAB_08076725:
- bVar13 = true;
- }
- else {
- Object::getObjectType(local_18c);
- pcVar14 = (char *)0x18;
- bVar1 = ObjectType::getFlag((ObjectType *)local_18c,TEXT);
- if (!bVar1) goto LAB_08076725;
- }
- uVar7 = Text._252_4_;
- if (bVar13) goto LAB_08076474;
- uVar7 = Object::getAttribute(&local_2c,TEXTSTRING);
- DeleteDynamicString(uVar7);
- z = local_2c.ObjectID;
- uVar7 = AddDynamicString((char *)&local_13c);
- Change((Object *)&z,TEXTSTRING,uVar7);
- uVar7 = 0;
- Attribute = EDITOR;
- goto LAB_08075f26;
- case ACTION_WRITETEXT:
- pOVar20 = local_16c;
- local_17c[0] = (Object)Temp->ObjectID;
- pOVar16 = local_15c;
- local_16c[0] = (Object)Obj2->ObjectID;
- puVar17 = local_14c;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- pcVar14 = (char *)Action->Parameters[1];
- GetEventObject();
- bVar13 = false;
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = NONE.ObjectID;
- if (local_18c[0].ObjectID == NONE.ObjectID) {
-LAB_08076857:
- bVar13 = true;
- }
- else {
- Object::getObjectType(local_18c);
- pcVar14 = (char *)0x18;
- bVar1 = ObjectType::getFlag((ObjectType *)local_18c,TEXT);
- if (!bVar1) goto LAB_08076857;
- }
- uVar7 = Text._252_4_;
- if (bVar13) goto LAB_08076474;
- uVar7 = Object::getAttribute(&local_2c,TEXTSTRING);
- DeleteDynamicString(uVar7);
- z = local_2c.ObjectID;
- pcVar14 = GetDynamicString(Action->Parameters[0]);
- uVar7 = AddDynamicString(pcVar14);
- Change((Object *)&z,TEXTSTRING,uVar7);
- uVar7 = 0;
- Attribute = EDITOR;
-LAB_08075f26:
- z = local_2c.ObjectID;
- Change((Object *)&z,Attribute,uVar7);
- break;
- case ACTION_LOGOUT:
- pOVar20 = local_16c;
- local_17c[0] = (Object)Temp->ObjectID;
- puVar17 = local_14c;
- local_16c[0] = (Object)Obj2->ObjectID;
- pOVar16 = local_15c;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- pcVar14 = (char *)&local_2c;
- Object::getObjectType((Object *)&z);
- uVar7 = Text._252_4_;
- if (z == 99) {
- z = local_2c.ObjectID;
- pTVar6 = GetCreature((Object *)&z);
- uVar7 = Text._252_4_;
- if (pTVar6 != (TCreature *)0x0) {
- TCreature::StartLogout(pTVar6,true,true);
- return;
- }
- }
- goto LAB_08076474;
- case ACTION_MOVEALLONMAP:
- UnpackAbsoluteCoordinate();
- GetFirstObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- UnpackAbsoluteCoordinate();
- GetMapContainer((int)local_18c,dz,x);
- bVar13 = false;
- z = NONE.ObjectID;
- Text[0xfc] = (undefined1)local_18c[0].ObjectID;
- Text[0xfd] = local_18c[0].ObjectID._1_1_;
- Text[0xfe] = local_18c[0].ObjectID._2_1_;
- Text[0xff] = local_18c[0].ObjectID._3_1_;
- local_17c[0].ObjectID = local_2c.ObjectID;
- goto LAB_08076acf;
- case ACTION_MOVEALL:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- Object::getContainer(local_17c);
- GetFirstContainerObject(local_18c);
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- UnpackAbsoluteCoordinate();
- goto LAB_08076bd6;
- case ACTION_MOVEALLREL:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- Object::getContainer(local_17c);
- GetFirstContainerObject(local_18c);
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- GetObjectCoordinates((Object *)&z,&dz,&x,&y);
- UnpackRelativeCoordinate();
- x = dx + x;
- dz = (int)(cr2->super_TSkillBase).Skills + dz + -4;
-LAB_08076bd6:
- GetMapContainer((int)local_18c,dz,x);
- bVar13 = false;
- Text[0xfc] = (undefined1)local_18c[0].ObjectID;
- Text[0xfd] = local_18c[0].ObjectID._1_1_;
- Text[0xfe] = local_18c[0].ObjectID._2_1_;
- Text[0xff] = local_18c[0].ObjectID._3_1_;
- z = local_2c.ObjectID;
- local_17c[0].ObjectID = local_2c.ObjectID;
- goto LAB_08076acf;
- case ACTION_MOVETOPONMAP:
- UnpackAbsoluteCoordinate();
- ObjectType::setTypeID((ObjectType *)local_17c,Action->Parameters[1]);
- GetFirstSpecObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = NONE.ObjectID;
- if (local_18c[0].ObjectID == NONE.ObjectID) {
- iVar8 = Action->Parameters[1];
- pcVar14 = "ExecuteAction (MOVETOPONMAP): Kein Objekt %d auf [%d,%d,%d].\n";
- goto LAB_08075be0;
- }
- UnpackAbsoluteCoordinate();
- GetMapContainer((int)local_18c,dz,x);
- z = NONE.ObjectID;
- Text[0xfc] = (undefined1)local_18c[0].ObjectID;
- Text[0xfd] = local_18c[0].ObjectID._1_1_;
- Text[0xfe] = local_18c[0].ObjectID._2_1_;
- Text[0xff] = local_18c[0].ObjectID._3_1_;
- Object::getNextObject(local_17c);
- bVar13 = true;
- goto LAB_08076acf;
- case ACTION_MOVETOP:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- UnpackAbsoluteCoordinate();
- goto LAB_08076f87;
- case ACTION_MOVETOPREL:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- GetObjectCoordinates((Object *)&z,&dz,&x,&y);
- UnpackRelativeCoordinate();
- x = dx + x;
- dz = (int)(cr2->super_TSkillBase).Skills + dz + -4;
-LAB_08076f87:
- GetMapContainer((int)local_18c,dz,x);
- z = NONE.ObjectID;
- Text[0xfc] = (undefined1)local_18c[0].ObjectID;
- Text[0xfd] = local_18c[0].ObjectID._1_1_;
- Text[0xfe] = local_18c[0].ObjectID._2_1_;
- Text[0xff] = local_18c[0].ObjectID._3_1_;
- Object::getNextObject(local_17c);
- bVar13 = true;
-LAB_08076acf:
- MoveAllObjects(local_17c,local_18c,(Object *)&z,bVar13);
- break;
- case ACTION_MOVE:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- UnpackAbsoluteCoordinate();
- GetMapContainer((int)local_18c,dz,x);
- Text[0xfc] = (undefined1)local_18c[0].ObjectID;
- Text[0xfd] = local_18c[0].ObjectID._1_1_;
- Text[0xfe] = local_18c[0].ObjectID._2_1_;
- Text[0xff] = local_18c[0].ObjectID._3_1_;
- goto LAB_080771eb;
- case ACTION_MOVEREL:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- local_18c[0] = (Object)Temp->ObjectID;
- local_17c[0] = (Object)Obj2->ObjectID;
- local_16c[0] = (Object)Obj1->ObjectID;
- local_15c[0] = (Object)User->ObjectID;
- GetEventObject();
- GetObjectCoordinates((Object *)&z,&dz,&x,&y);
- UnpackRelativeCoordinate();
- GetMapContainer((int)local_18c,(int)(cr2->super_TSkillBase).Skills + dz + -4,dx + x);
- Text[0xfc] = (undefined1)local_18c[0].ObjectID;
- Text[0xfd] = local_18c[0].ObjectID._1_1_;
- Text[0xfe] = local_18c[0].ObjectID._2_1_;
- Text[0xff] = local_18c[0].ObjectID._3_1_;
- goto LAB_080771eb;
- case ACTION_RETRIEVE:
- local_18c[0] = (Object)Temp->ObjectID;
- local_17c[0] = (Object)Obj2->ObjectID;
- local_16c[0] = (Object)Obj1->ObjectID;
- local_15c[0] = (Object)User->ObjectID;
- GetEventObject();
- GetObjectCoordinates((Object *)&z,&dz,&x,&y);
- UnpackRelativeCoordinate();
- GetTopObject((int)local_18c,(int)(cr2->super_TSkillBase).Skills + dz + -4,dx + x,
- (bool)((char)dy + (char)y));
- bVar13 = false;
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = NONE.ObjectID;
- if (local_18c[0].ObjectID == NONE.ObjectID) {
-LAB_080774d6:
- bVar13 = true;
- }
- else {
- Object::getObjectType(local_18c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_18c,UNMOVE);
- if (bVar1) goto LAB_080774d6;
- }
- if (bVar13) {
- return;
- }
- UnpackRelativeCoordinate();
- GetMapContainer((int)local_18c,(int)(cr2->super_TSkillBase).Skills + dz + -4,dx + x);
- Text._252_4_ = local_18c[0].ObjectID;
-LAB_080771eb:
- z = Text._252_4_;
- local_18c[0].ObjectID = local_2c.ObjectID;
- MoveOneObject(local_18c,(Object *)&z);
- break;
- case ACTION_DELETEALLONMAP:
- UnpackAbsoluteCoordinate();
- GetFirstObject();
- bVar13 = false;
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- goto LAB_0807762f;
- case ACTION_DELETETOPONMAP:
- UnpackAbsoluteCoordinate();
- pOVar20 = local_17c;
- ObjectType::setTypeID((ObjectType *)pOVar20,Action->Parameters[1]);
- GetFirstSpecObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = NONE.ObjectID;
- pcVar14 = (char *)dz;
- puVar17 = (ulong *)x;
- pOVar16 = (Object *)y;
- uVar7 = Text._252_4_;
- if (local_18c[0].ObjectID == NONE.ObjectID) goto LAB_08076474;
- z = local_18c[0].ObjectID;
- Object::getNextObject(local_18c);
- bVar13 = true;
-LAB_0807762f:
- DeleteAllObjects(local_18c,(Object *)&z,bVar13);
- break;
- case ACTION_DELETEONMAP:
- UnpackAbsoluteCoordinate();
- ObjectType::setTypeID((ObjectType *)local_17c,Action->Parameters[1]);
- GetFirstSpecObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = NONE.ObjectID;
- if (local_18c[0].ObjectID == NONE.ObjectID) {
- iVar8 = Action->Parameters[1];
- pcVar14 = "ExecuteAction (DELETEONMAP): Kein Objekt %d auf [%d,%d,%d].\n";
- goto LAB_08075be0;
- }
- goto LAB_080777c6;
- case ACTION_DELETE:
- pOVar16 = local_15c;
- local_17c[0] = (Object)Temp->ObjectID;
- pOVar20 = local_16c;
- local_16c[0] = (Object)Obj2->ObjectID;
- puVar17 = local_14c;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- pcVar14 = (char *)Action->Parameters[0];
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = NONE.ObjectID;
- uVar7 = Text._252_4_;
- if (local_18c[0].ObjectID == NONE.ObjectID) goto LAB_08076474;
-LAB_080777c6:
- Delete((Object *)&z,(-(uint)(Event < EVENT_MOVEMENT) & 2) - 1);
- break;
- case ACTION_DELETEININVENTORY:
- pOVar20 = local_16c;
- local_17c[0] = (Object)Temp->ObjectID;
- puVar17 = local_14c;
- local_16c[0] = (Object)Obj2->ObjectID;
- pOVar16 = local_15c;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- pcVar14 = (char *)&local_2c;
- Object::getObjectType((Object *)&z);
- uVar7 = Text._252_4_;
- if (z != 99) goto LAB_08076474;
- ObjectType::setTypeID((ObjectType *)&z,Action->Parameters[1]);
- uVar7 = Object::getCreatureID(&local_2c);
- DeleteAtCreature(uVar7,(ObjectType *)&z,1,Action->Parameters[2]);
- break;
- case ACTION_DESCRIPTION:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- Object::getObjectType((Object *)&z);
- if (z == 99) {
- z = local_2c.ObjectID;
- pTVar6 = GetCreature((Object *)&z);
- if ((pTVar6 != (TCreature *)0x0) && (pTVar6->Type == PLAYER)) {
- local_17c[0] = (Object)Temp->ObjectID;
- pOVar16 = local_16c;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- pOVar20 = local_17c;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- pcVar14 = GetInfo((Object *)&z);
- SendMessage(pTVar6->Connection,0x16,"%s.",pcVar14,pOVar16,pOVar20);
- }
- }
- break;
- case ACTION_LOADDEPOT:
- pOVar16 = local_15c;
- local_17c[0] = (Object)Temp->ObjectID;
- pOVar20 = local_16c;
- local_16c[0] = (Object)Obj2->ObjectID;
- puVar17 = local_14c;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- pcVar14 = (char *)&local_2c;
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- Object::getObjectType((Object *)&z);
- uVar7 = Text._252_4_;
- if (z == 99) {
- UnpackAbsoluteCoordinate();
- ObjectType::setTypeID((ObjectType *)local_17c,Action->Parameters[1]);
- pOVar20 = local_17c;
- GetFirstSpecObject();
- Text[0xfc] = (undefined1)local_18c[0].ObjectID;
- Text[0xfd] = local_18c[0].ObjectID._1_1_;
- Text[0xfe] = local_18c[0].ObjectID._2_1_;
- Text[0xff] = local_18c[0].ObjectID._3_1_;
- z = NONE.ObjectID;
- pcVar14 = (char *)dz;
- puVar17 = (ulong *)x;
- pOVar16 = (Object *)y;
- uVar7 = Text._252_4_;
- if (local_18c[0].ObjectID != NONE.ObjectID) {
- z = local_18c[0].ObjectID;
- uVar7 = Object::getCreatureID(&local_2c);
- LoadDepotBox(uVar7,Action->Parameters[3],(Object *)&z);
- return;
- }
- }
- goto LAB_08076474;
- case ACTION_SAVEDEPOT:
- pOVar16 = local_15c;
- local_17c[0] = (Object)Temp->ObjectID;
- pOVar20 = local_16c;
- local_16c[0] = (Object)Obj2->ObjectID;
- puVar17 = local_14c;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- pcVar14 = (char *)&local_2c;
- Object::getObjectType((Object *)&z);
- uVar7 = Text._252_4_;
- if (z == 99) {
- UnpackAbsoluteCoordinate();
- ObjectType::setTypeID((ObjectType *)local_17c,Action->Parameters[1]);
- pOVar20 = local_17c;
- GetFirstSpecObject();
- z = NONE.ObjectID;
- Text[0xfc] = (undefined1)local_18c[0].ObjectID;
- Text[0xfd] = local_18c[0].ObjectID._1_1_;
- Text[0xfe] = local_18c[0].ObjectID._2_1_;
- Text[0xff] = local_18c[0].ObjectID._3_1_;
- pcVar14 = (char *)dz;
- puVar17 = (ulong *)x;
- pOVar16 = (Object *)y;
- uVar7 = local_18c[0].ObjectID;
- if (local_18c[0].ObjectID != NONE.ObjectID) {
- z = local_18c[0].ObjectID;
- uVar7 = Object::getCreatureID(&local_2c);
- SaveDepotBox(uVar7,Action->Parameters[3],(Object *)&z);
- return;
- }
- }
-LAB_08076474:
- Text._252_4_ = uVar7;
- puVar4 = (undefined4 *)__cxa_allocate_exception(4,pcVar14,puVar17,pOVar16,pOVar20);
- *puVar4 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,&RESULT::typeinfo,0);
- case ACTION_SENDMAIL:
- local_17c[0] = (Object)Temp->ObjectID;
- local_16c[0] = (Object)Obj2->ObjectID;
- local_15c[0] = (Object)Obj1->ObjectID;
- local_14c[0] = User->ObjectID;
- GetEventObject();
- local_2c.ObjectID = local_18c[0].ObjectID;
- z = local_18c[0].ObjectID;
- SendMail((Object *)&z);
- break;
- case ACTION_NOP:
- break;
- default:
- pcVar14 = "ExecuteAction: Unbekannte Aktion %d.\n";
- AVar15 = Action->Action;
-switchD_080755eb_default:
- error(pcVar14,AVar15);
- }
- return;
-}
-
-
-
-bool HandleEvent(EventType Event,Object *User,Object *Obj1,Object *Obj2)
-
-{
- bool bVar1;
- bool bVar2;
- TMoveUseCondition *Condition;
- TMoveUseRule *pTVar3;
- TMoveUseCondition *Condition_00;
- TMoveUseAction *Action;
- int condition;
- int iVar4;
- int iVar5;
- TMoveUseRule *Rule;
- TMoveUseDatabase *DB;
- int iStack_60;
- bool fulfilled;
- int rule;
- Object local_4c [4];
- Object local_3c [4];
- Object local_2c;
- Object Temp;
-
- if (HandleEvent::RecursionDepth < 0xb) {
- iStack_60 = 1;
- HandleEvent::RecursionDepth = HandleEvent::RecursionDepth + 1;
- if (0 < MoveUseDatabases[Event].NumberOfRules) {
- do {
- pTVar3 = vector<>::operator()(&MoveUseDatabases[Event].Rules,iStack_60);
- bVar1 = true;
- local_2c.ObjectID = NONE.ObjectID;
- iVar4 = pTVar3->FirstCondition;
- if (iVar4 <= pTVar3->LastCondition) {
- do {
- Condition_00 = vector<>::operator()(&MoveUseConditions,iVar4);
- local_3c[0] = (Object)Obj2->ObjectID;
- local_4c[0] = (Object)Obj1->ObjectID;
- rule = User->ObjectID;
- bVar2 = CheckCondition(Event,Condition_00,(Object *)&rule,local_4c,local_3c,
- &local_2c);
- if (!bVar2) {
- bVar1 = false;
- }
- iVar4 = iVar4 + 1;
- if (!bVar1) goto LAB_08077f6d;
- } while (iVar4 <= pTVar3->LastCondition);
- }
- if (bVar1) {
- iVar4 = pTVar3->FirstAction;
- if (pTVar3->FirstAction <= pTVar3->LastAction) {
- do {
- iVar5 = iVar4 + 1;
- Action = vector<>::operator()(&MoveUseActions,iVar4);
- rule = Obj2->ObjectID;
- local_4c[0] = (Object)Obj1->ObjectID;
- local_3c[0] = (Object)User->ObjectID;
- ExecuteAction(Event,Action,local_3c,local_4c,(Object *)&rule,&local_2c);
- iVar4 = iVar5;
- } while (iVar5 <= pTVar3->LastAction);
- }
- HandleEvent::RecursionDepth = HandleEvent::RecursionDepth + -1;
- return true;
- }
-LAB_08077f6d:
- iStack_60 = iStack_60 + 1;
- } while (iStack_60 <= MoveUseDatabases[Event].NumberOfRules);
- }
- HandleEvent::RecursionDepth = HandleEvent::RecursionDepth + -1;
- }
- else {
- error("HandleEvent: Endlosschleife im Move/Use-System vermutet.\n");
- }
- return false;
-}
-
-
-
-void UseContainer(ulong CreatureID,Object *Con,uchar Window)
-
-{
- bool bVar1;
- TPlayer *this;
- undefined4 *puVar2;
- int Window_00;
- char *pcVar3;
- Object *pOVar4;
- TPlayer *pl;
- Object OStack_4c;
- uchar Window_local;
- _func_int_varargs **local_3c;
- _func_int_varargs **local_2c;
-
- // try { // try from 0807802f to 080781a2 has its CatchHandler @ 080781b0
- bVar1 = Object::exists(Con);
- if (bVar1) {
- Object::getObjectType((Object *)&local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)&local_2c,CONTAINER);
- if (!bVar1) {
- pcVar3 = &DAT_080f8980;
- goto LAB_0807819e;
- }
- if (Window < 0x10) {
- pOVar4 = Con;
- Object::getObjectType((Object *)&local_2c);
- if (local_2c == (_func_int_varargs **)0x63) {
- puVar2 = (undefined4 *)__cxa_allocate_exception(4,pOVar4);
- *puVar2 = 0x1d;
- goto LAB_0807815a;
- }
- this = GetPlayer(CreatureID);
- if (this != (TPlayer *)0x0) {
- Window_00 = 0;
- do {
- TPlayer::GetOpenContainer((TPlayer *)&local_2c,(int)this);
- local_3c = (_func_int_varargs **)Con->ObjectID;
- if (local_2c == local_3c) {
- OStack_4c.ObjectID = NONE.ObjectID;
- TPlayer::SetOpenContainer(this,Window_00,&stack0xffffffb4);
- SendCloseContainer((this->super_TCreature).Connection,Window_00);
- return;
- }
- Window_00 = Window_00 + 1;
- } while (Window_00 < 0x10);
- OStack_4c.ObjectID = (ulong)local_3c;
- TPlayer::SetOpenContainer(this,(uint)Window,&stack0xffffffb4);
- SendContainer((this->super_TCreature).Connection,(uint)Window);
- return;
- }
- pcVar3 = "UseContainer: Spieler %d existiert nicht.\n";
- }
- else {
- CreatureID = (ulong)Window;
- pcVar3 = &DAT_080f8940;
- }
- error(pcVar3,CreatureID);
- }
- else {
- pcVar3 = &DAT_080f89c0;
-LAB_0807819e:
- error(pcVar3);
- }
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0xffffffff;
-LAB_0807815a:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,&RESULT::typeinfo,0);
-}
-
-
-
-void UseChest(ulong CreatureID,Object *Chest)
-
-{
- bool bVar1;
- bool bVar2;
- ulong uVar3;
- int iVar4;
- TPlayer *this;
- char *pcVar5;
- int iVar6;
- int iVar7;
- char *pcVar8;
- undefined4 *puVar9;
- int Weight;
- ulong uVar10;
- undefined4 uVar11;
- undefined8 local_bc;
- int iStack_b8;
- bool invert;
- bool first;
- int pos;
- TPlayer *pl;
- int Number;
- int x;
- int y;
- int z;
- Object local_7c [4];
- Object local_6c;
- Object Obj;
- Object local_4c [4];
- Object local_3c [4];
- Object local_2c;
- Object Treasure;
-
- // try { // try from 080781e8 to 08078562 has its CatchHandler @ 08078948
- bVar2 = Object::exists(Chest);
- if (bVar2) {
- Object::getObjectType(&local_2c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_2c,CHEST);
- if (bVar2) {
- local_2c = (Object)Chest->ObjectID;
- GetObjectCoordinates(&local_2c,&Number,&x,&y);
- uVar3 = Object::getAttribute(Chest,CHESTQUESTNUMBER);
- bVar2 = false;
- if ((0 < (int)uVar3) && ((int)uVar3 < 500)) {
- bVar2 = true;
- }
- if (!bVar2) {
- error(&DAT_080f8b40,uVar3,Number,x,y);
- goto LAB_0807875e;
- }
- local_2c = (Object)Chest->ObjectID;
- iVar4 = CountObjectsInContainer(&local_2c);
- if (iVar4 != 1) {
- error(&DAT_080f8ae0,Number,x,y);
- goto LAB_0807875e;
- }
- local_3c[0] = (Object)Chest->ObjectID;
- GetFirstContainerObject(&local_2c);
- Object::getObjectType(local_3c);
- bVar2 = ObjectType::getFlag((ObjectType *)local_3c,UNMOVE);
- if (!bVar2) {
- Object::getObjectType(local_3c);
- bVar2 = ObjectType::getFlag((ObjectType *)local_3c,TAKE);
- if (bVar2) {
- this = GetPlayer(CreatureID);
- if (this == (TPlayer *)0x0) {
- // try { // try from 08078759 to 080787f5 has its CatchHandler @ 08078948
- error("UseChest: Spieler %d existiert nicht.\n",CreatureID);
- goto LAB_0807875e;
- }
- iVar4 = TPlayer::GetQuestValue(this,uVar3);
- if (iVar4 != 0) {
- print();
- Object::getObjectType(local_3c);
- pcVar5 = ObjectType::getName((ObjectType *)local_3c);
- SendMessage((this->super_TCreature).Connection,0x16,"The %s is empty.",
- pcVar5);
- return;
- }
- bVar2 = CheckRight(CreatureID,UNLIMITED_CAPACITY);
- if (bVar2) {
-LAB_080784f2:
- Object::getContainer(&local_6c);
- Copy(local_4c,&local_6c);
- local_2c.ObjectID = local_4c[0].ObjectID;
- local_3c[0].ObjectID = local_4c[0].ObjectID;
- Object::getObjectType(&local_6c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_6c,MOVEMENTEVENT);
- uVar11 = 1;
- uVar10 = CreatureID;
- // try { // try from 08078586 to 08078614 has its CatchHandler @ 0807880d
- GetBodyObject((ulong)&local_6c,CreatureID);
- if ((bVar2) || (local_6c.ObjectID != NONE.ObjectID)) {
- bVar1 = false;
- if (bVar2) {
- local_7c[0] = (Object)NONE.ObjectID;
- local_4c[0].ObjectID = NONE.ObjectID;
- if (local_6c.ObjectID != NONE.ObjectID) {
- Object::getObjectType(local_4c);
- uVar10 = 4;
- bVar2 = ObjectType::getFlag((ObjectType *)local_4c,CONTAINER);
- if (bVar2) {
- bVar1 = true;
- }
- }
- }
- if (!bVar1) {
- puVar9 = (undefined4 *)__cxa_allocate_exception(4,uVar10,uVar11);
- *puVar9 = 4;
- // WARNING: Subroutine does not return
- // try { // try from 08078698 to 0807873f has its CatchHandler @ 0807880d
- __cxa_throw(puVar9,&RESULT::typeinfo,0);
- }
- local_4c[0].ObjectID = NONE.ObjectID;
- local_3c[0].ObjectID = local_6c.ObjectID;
- z = local_2c.ObjectID;
- Move(CreatureID,(Object *)&z,local_3c,-1,true,local_4c);
- }
- else {
- local_4c[0].ObjectID = NONE.ObjectID;
- GetBodyContainer((ulong)local_3c,CreatureID);
- local_7c[0].ObjectID = local_2c.ObjectID;
- Move(CreatureID,local_7c,local_3c,-1,true,local_4c);
- }
- z = local_2c.ObjectID;
- // try { // try from 08078621 to 0807866d has its CatchHandler @ 08078948
- pcVar5 = GetName((Object *)&z);
- SendMessage((this->super_TCreature).Connection,0x16,"You have found %s.\n",
- pcVar5);
- TPlayer::SetQuestValue(this,uVar3,1);
- return;
- }
- local_3c[0].ObjectID = local_2c.ObjectID;
- iVar4 = GetCompleteWeight(local_3c);
- iVar6 = GetInventoryWeight(CreatureID);
- iVar7 = TSkill::Get((this->super_TCreature).super_TSkillBase.Skills[5]);
- if ((iVar4 + iVar6 <= iVar7 * 100) &&
- (bVar2 = CheckRight(CreatureID,ZERO_CAPACITY), !bVar2)) goto LAB_080784f2;
- Object::getObjectType(local_3c);
- bVar2 = ObjectType::getFlag((ObjectType *)local_3c,CUMULATIVE);
- if (bVar2) {
- uVar3 = Object::getAttribute(&local_2c,AMOUNT);
- pcVar5 = "they are";
- if (1 < uVar3) goto LAB_0807844b;
- }
- pcVar5 = "it is";
-LAB_0807844b:
- local_3c[0].ObjectID = local_2c.ObjectID;
- pcVar8 = GetName(local_3c);
- iVar6 = (iStack_b8 >> 5) - (iVar4 >> 0x1f);
- SendMessage((this->super_TCreature).Connection,0x16,
- "You have found %s. Weighing %d.%02d oz %s too heavy.",pcVar8,iVar6,
- iVar4 + iVar6 * -100,pcVar5);
- return;
- }
- }
- pcVar5 = "UseChest: Schatz auf Position [%d,%d,%d] ist nicht nehmbar.\n";
- }
- else {
- pcVar5 = &DAT_080f8ba0;
- }
- }
- else {
- pcVar5 = &DAT_080f8be0;
- }
- error(pcVar5);
-LAB_0807875e:
- puVar9 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar9 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar9,&RESULT::typeinfo,0);
-}
-
-
-
-void UseLiquidContainer(ulong CreatureID,Object *Obj,Object *Dest)
-
-{
- TSkill *pTVar1;
- bool bVar2;
- bool bVar3;
- ulong uVar4;
- undefined4 *puVar5;
- TPlayer *this;
- int iVar6;
- char *pcVar7;
- int iVar8;
- undefined4 uVar9;
- int LiquidType;
- int local_58;
- int x;
- int y;
- int z;
- Object local_3c [4];
- Object local_2c;
- Object Help;
-
- // try { // try from 0807897b to 08078f23 has its CatchHandler @ 08078f43
- bVar2 = Object::exists(Obj);
- if (bVar2) {
- bVar2 = Object::exists(Dest);
- if (bVar2) {
- Object::getObjectType(&local_2c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_2c,LIQUIDCONTAINER);
- if (!bVar2) {
- pcVar7 = &DAT_080f8ce0;
- goto LAB_08078f0b;
- }
- Object::getObjectType(&local_2c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_2c,LIQUIDSOURCE);
- if ((bVar2) && (uVar4 = Object::getAttribute(Obj,CONTAINERLIQUIDTYPE), uVar4 == 0)) {
- Object::getObjectType(&local_2c);
- uVar4 = ObjectType::getAttribute((ObjectType *)&local_2c,SOURCELIQUIDTYPE);
- local_2c = (Object)Obj->ObjectID;
-LAB_08078ec5:
- Change(&local_2c,CONTAINERLIQUIDTYPE,uVar4);
- return;
- }
- Object::getObjectType(&local_2c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_2c,LIQUIDCONTAINER);
- if ((bVar2) &&
- ((uVar4 = Object::getAttribute(Obj,CONTAINERLIQUIDTYPE), uVar4 != 0 &&
- (uVar4 = Object::getAttribute(Dest,CONTAINERLIQUIDTYPE), uVar4 == 0)))) {
- local_2c = (Object)Dest->ObjectID;
- uVar4 = Object::getAttribute(Obj,CONTAINERLIQUIDTYPE);
- Change(&local_2c,CONTAINERLIQUIDTYPE,uVar4);
- local_2c = (Object)Obj->ObjectID;
- uVar4 = 0;
- goto LAB_08078ec5;
- }
- Object::getObjectType(&local_2c);
- if (local_2c.ObjectID != 99) {
- Object::getContainer(local_3c);
- GetFirstContainerObject(&local_2c);
- z = NONE.ObjectID;
- local_3c[0].ObjectID = z;
- if (local_2c.ObjectID != NONE.ObjectID) {
- do {
- z = NONE.ObjectID;
- local_3c[0].ObjectID = NONE.ObjectID;
- Object::getObjectType((Object *)&z);
- if ((z == 99) &&
- (uVar4 = Object::getCreatureID(&local_2c), uVar4 == CreatureID)) {
- local_3c[0].ObjectID = local_2c.ObjectID;
- Dest->ObjectID = (ulong)local_2c;
- z = local_2c.ObjectID;
- break;
- }
- Object::getNextObject(local_3c);
- local_2c.ObjectID = local_3c[0].ObjectID;
- bVar2 = local_3c[0].ObjectID != NONE.ObjectID;
- local_3c[0].ObjectID = NONE.ObjectID;
- z = NONE.ObjectID;
- } while (bVar2);
- }
- }
- Object::getObjectType((Object *)&z);
- if ((z != 99) || (uVar4 = Object::getCreatureID(Dest), uVar4 != CreatureID)) {
- uVar4 = Object::getAttribute(Obj,CONTAINERLIQUIDTYPE);
- if (uVar4 == 0) {
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0x1d;
- }
- else {
- z = Dest->ObjectID;
- GetObjectCoordinates((Object *)&z,&local_58,&x,&y);
- bVar2 = false;
- uVar9 = 0;
- iVar6 = x;
- iVar8 = y;
- bVar3 = CoordinateFlag();
- if (bVar3) {
- uVar9 = 0x23;
- bVar2 = CoordinateFlag();
- bVar2 = !bVar2;
- iVar6 = x;
- iVar8 = y;
- }
- if (bVar2) {
- Object::getAttribute(Obj,CONTAINERLIQUIDTYPE);
- z = Obj->ObjectID;
- Change((Object *)&z,CONTAINERLIQUIDTYPE,0);
- local_3c[0] = (Object)Dest->ObjectID;
- GetMapContainer((Object *)&z);
- GetSpecialObject((SPECIALMEANING)&local_2c);
- CreatePool();
- return;
- }
- puVar5 = (undefined4 *)__cxa_allocate_exception(4,iVar6,iVar8,uVar9);
- *puVar5 = 4;
- }
- goto LAB_08078b95;
- }
- this = GetPlayer(CreatureID);
- if (this != (TPlayer *)0x0) {
- uVar4 = Object::getAttribute(Obj,CONTAINERLIQUIDTYPE);
- switch(uVar4) {
- case 0:
- return;
- default:
- z = Obj->ObjectID;
- Change((Object *)&z,CONTAINERLIQUIDTYPE,0);
- pcVar7 = "Gulp.";
- break;
- case 2:
- case 3:
- z = Obj->ObjectID;
- Change((Object *)&z,CONTAINERLIQUIDTYPE,0);
- pTVar1 = (this->super_TCreature).super_TSkillBase.Skills[0x14];
- pcVar7 = "Aah...";
- iVar6 = (*pTVar1->_vptr_TSkill[0xd])(pTVar1);
- if (iVar6 < 5) {
- pTVar1 = (this->super_TCreature).super_TSkillBase.Skills[0x14];
- (*pTVar1->_vptr_TSkill[0xd])(pTVar1);
- TSkillBase::SetTimer(&(this->super_TCreature).super_TSkillBase);
- }
- break;
- case 6:
- z = Obj->ObjectID;
- Change((Object *)&z,CONTAINERLIQUIDTYPE,0);
- pcVar7 = "Urgh!";
- TCreature::Damage(&this->super_TCreature,(TCreature *)0x0,200,0x20);
- break;
- case 8:
- z = Obj->ObjectID;
- Change((Object *)&z,CONTAINERLIQUIDTYPE,0);
- pcVar7 = "Urgh!";
- break;
- case 10:
- case 0xb:
- z = Obj->ObjectID;
- DrinkPotion(CreatureID,(Object *)&z);
- pcVar7 = "Aaaah...";
- break;
- case 0xc:
- z = Obj->ObjectID;
- Change((Object *)&z,CONTAINERLIQUIDTYPE,0);
- pcVar7 = "Mmmh.";
- }
- Talk(CreatureID,1,(char *)0x0,pcVar7,false);
- return;
- }
- pcVar7 = "UseLiquidContainer: Spieler %d existiert nicht.\n";
- }
- else {
- Object::getObjectType(&local_2c);
- pcVar7 = &DAT_080f8d40;
- CreatureID = local_2c.ObjectID;
- }
- error(pcVar7,CreatureID);
- }
- else {
- pcVar7 = &DAT_080f8da0;
-LAB_08078f0b:
- error(pcVar7);
- }
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0xffffffff;
-LAB_08078b95:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar5,&RESULT::typeinfo,0);
-}
-
-
-
-void UseFood(ulong CreatureID,Object *Obj)
-
-{
- TSkill *pTVar1;
- int iVar2;
- bool bVar3;
- TPlayer *pTVar4;
- int iVar5;
- ulong uVar6;
- undefined4 *puVar7;
- char *Text;
- TPlayer *pl;
-
- // try { // try from 08078f78 to 080790e9 has its CatchHandler @ 080790f5
- bVar3 = Object::exists(Obj);
- if (bVar3) {
- Object::getObjectType((Object *)&pl);
- bVar3 = ObjectType::getFlag((ObjectType *)&pl,FOOD);
- if (!bVar3) {
- Text = &DAT_080f8e20;
- goto LAB_080790e5;
- }
- pTVar4 = GetPlayer(CreatureID);
- if (pTVar4 != (TPlayer *)0x0) {
- pTVar1 = (pTVar4->super_TCreature).super_TSkillBase.Skills[0xe];
- iVar5 = (*pTVar1->_vptr_TSkill[0xd])(pTVar1);
- iVar2 = pTVar1->Max;
- Object::getObjectType((Object *)&pl);
- uVar6 = ObjectType::getAttribute((ObjectType *)&pl,NUTRITION);
- if (iVar5 <= (int)(iVar2 + uVar6 * -0xc)) {
- (*pTVar1->_vptr_TSkill[0xd])(pTVar1);
- Object::getObjectType((Object *)&pl);
- ObjectType::getAttribute((ObjectType *)&pl,NUTRITION);
- TSkillBase::SetTimer(&(pTVar4->super_TCreature).super_TSkillBase);
- pl = (TPlayer *)Obj->ObjectID;
- Delete((Object *)&pl,1);
- return;
- }
- puVar7 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar7 = 0x1e;
- goto LAB_080790a2;
- }
- error("UseFood: Kreatur %d existiert nicht.\n",CreatureID);
- }
- else {
- Text = &DAT_080f8e60;
-LAB_080790e5:
- error(Text);
- }
- puVar7 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar7 = 0xffffffff;
-LAB_080790a2:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar7,&RESULT::typeinfo,0);
-}
-
-
-
-void UseTextObject(ulong CreatureID,Object *Obj)
-
-{
- bool bVar1;
- TPlayer *pTVar2;
- undefined4 *puVar3;
- TPlayer *pl;
- char *Text;
- Object local_2c [7];
-
- // try { // try from 08079128 to 080791d2 has its CatchHandler @ 080791e0
- bVar1 = Object::exists(Obj);
- if (bVar1) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,TEXT);
- if (bVar1) {
- pTVar2 = GetPlayer(CreatureID);
- if (pTVar2 != (TPlayer *)0x0) {
- local_2c[0] = (Object)Obj->ObjectID;
- SendEditText((pTVar2->super_TCreature).Connection,local_2c);
- return;
- }
- error("UseTextObject: Kreatur %d existiert nicht.\n",CreatureID);
- goto LAB_0807919d;
- }
- Text = &DAT_080f8ee0;
- }
- else {
- Text = &DAT_080f8f20;
- }
- error(Text);
-LAB_0807919d:
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,&RESULT::typeinfo,0);
-}
-
-
-
-void UseAnnouncer(ulong CreatureID,Object *Obj)
-
-{
- bool bVar1;
- TPlayer *this;
- ulong uVar2;
- int iVar3;
- undefined4 *puVar4;
- char cVar5;
- char *Text;
- TPlayer *pl;
- int Hour;
- int Minute;
- int Year;
- int Cycle;
- int Day;
- char Help [200];
- Object local_2c [7];
-
- // try { // try from 0807921b to 080795fa has its CatchHandler @ 08079606
- bVar1 = Object::exists(Obj);
- if (bVar1) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,INFORMATION);
- if (bVar1) {
- this = GetPlayer(CreatureID);
- if (this != (TPlayer *)0x0) {
- Object::getObjectType(local_2c);
- uVar2 = ObjectType::getAttribute((ObjectType *)local_2c,INFORMATIONTYPE);
- if (uVar2 == 2) {
- GetTime((int *)&pl,&Hour);
- SendMessage((this->super_TCreature).Connection,0x16,"The time is %d:%.2d.",pl,
- Hour);
- return;
- }
- if (uVar2 < 3) {
- if (uVar2 == 1) {
- GetDate(&Minute,&Year,&Cycle);
- GetTime((int *)&pl,&Hour);
- SendMessage((this->super_TCreature).Connection,0x16,
- "It is the %dth day of the %dth cycle in the year %d. The time is %d:%.2d."
- ,Cycle,Year,Minute,pl,Hour);
- return;
- }
- }
- else {
- if (uVar2 == 3) {
- Day = 0x65636552;
- builtin_strncpy(Help,"ived blessings:",0x10);
- iVar3 = TPlayer::GetQuestValue(this,0x65);
- cVar5 = iVar3 != 0;
- if ((bool)cVar5) {
- strcat((char *)&Day,"\nWisdom of Solitude");
- }
- iVar3 = TPlayer::GetQuestValue(this,0x66);
- if (iVar3 != 0) {
- cVar5 = cVar5 + '\x01';
- strcat((char *)&Day,"\nSpark of the Phoenix");
- }
- iVar3 = TPlayer::GetQuestValue(this,0x67);
- if (iVar3 != 0) {
- cVar5 = cVar5 + '\x01';
- strcat((char *)&Day,"\nFire of the Suns");
- }
- iVar3 = TPlayer::GetQuestValue(this,0x68);
- if (iVar3 != 0) {
- cVar5 = cVar5 + '\x01';
- strcat((char *)&Day,"\nSpiritual Shielding");
- }
- iVar3 = TPlayer::GetQuestValue(this,0x69);
- if (iVar3 != 0) {
- cVar5 = cVar5 + '\x01';
- strcat((char *)&Day,"\nEmbrace of Tibia");
- }
- if (cVar5 == '\0') {
- builtin_strncpy(Help,"lessings received.",0x13);
- Day = 0x62206f4e;
- }
- SendMessage((this->super_TCreature).Connection,0x16,"%s",&Day);
- return;
- }
- if (uVar2 == 4) {
- local_2c[0] = (Object)Obj->ObjectID;
- SendEditText((this->super_TCreature).Connection,local_2c);
- return;
- }
- }
- Object::getObjectType(local_2c);
- uVar2 = ObjectType::getAttribute((ObjectType *)local_2c,INFORMATIONTYPE);
- error(&DAT_080f8f60,uVar2);
- return;
- }
- error("UseAnnouncer: Kreatur %d existiert nicht.\n",CreatureID);
- goto LAB_080795c5;
- }
- Text = &DAT_080f9040;
- }
- else {
- Text = &DAT_080f9080;
- }
- error(Text);
-LAB_080795c5:
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,&RESULT::typeinfo,0);
-}
-
-
-
-void UseKeyDoor(ulong param_1,Object *Key,Object *Door)
-
-{
- bool bVar1;
- ulong uVar2;
- ulong uVar3;
- undefined4 *puVar4;
- char *Text;
- Object local_4c [4];
- Object local_3c [4];
- Object local_2c;
- ObjectType Target;
-
- // try { // try from 08079638 to 08079834 has its CatchHandler @ 08079850
- bVar1 = Object::exists(Key);
- if (bVar1) {
- bVar1 = Object::exists(Door);
- if (!bVar1) {
- Text = &DAT_080f9140;
- goto LAB_08079830;
- }
- Object::getObjectType(&local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)&local_2c,KEY);
- if (!bVar1) {
- Text = &DAT_080f9100;
- goto LAB_08079830;
- }
- Object::getObjectType(&local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)&local_2c,KEYDOOR);
- if (!bVar1) {
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0x1d;
- goto LAB_080797e9;
- }
- uVar2 = Object::getAttribute(Door,KEYHOLENUMBER);
- if ((uVar2 == 0) || (uVar2 = Object::getAttribute(Key,KEYNUMBER), uVar2 == 0)) {
-LAB_08079801:
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0x16;
- goto LAB_080797e9;
- }
- uVar2 = Object::getAttribute(Door,KEYHOLENUMBER);
- uVar3 = Object::getAttribute(Key,KEYNUMBER);
- if (uVar2 != uVar3) goto LAB_08079801;
- Object::getObjectType(local_3c);
- uVar2 = ObjectType::getAttribute((ObjectType *)local_3c,KEYDOORTARGET);
- ObjectType::setTypeID((ObjectType *)&local_2c,uVar2);
- ObjectType::setTypeID((ObjectType *)local_3c,0);
- if (local_2c.ObjectID != local_3c[0].ObjectID) {
- bVar1 = ObjectType::getFlag((ObjectType *)&local_2c,UNPASS);
- if (bVar1) {
- local_4c[0].ObjectID = NONE.ObjectID;
- local_3c[0] = (Object)Door->ObjectID;
- ClearField(local_3c,local_4c);
- }
- ObjectType::setTypeID((ObjectType *)local_4c,local_2c.ObjectID);
- local_3c[0] = (Object)Door->ObjectID;
- Change(local_3c,(ObjectType *)local_4c,0);
- return;
- }
- Object::getObjectType(local_4c);
- error(&DAT_080f90c0,local_4c[0].ObjectID);
- }
- else {
- Text = &DAT_080f9180;
-LAB_08079830:
- error(Text);
- }
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0xffffffff;
-LAB_080797e9:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,&RESULT::typeinfo,0);
-}
-
-
-
-void UseNameDoor(ulong CreatureID,Object *Door)
-
-{
- bool bVar1;
- ushort HouseID;
- TPlayer *pl_00;
- ulong _TypeID;
- undefined4 *puVar2;
- TPlayer *pl;
- char *Text;
- int local_58;
- int x;
- int y;
- int z;
- Object local_3c [4];
- Object local_2c;
- ObjectType Target;
-
- // try { // try from 08079885 to 08079ace has its CatchHandler @ 08079af0
- bVar1 = Object::exists(Door);
- if (bVar1) {
- Object::getObjectType(&local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)&local_2c,NAMEDOOR);
- if (!bVar1) {
- Text = &DAT_080f92c0;
- goto LAB_08079aca;
- }
- Object::getObjectType(&local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)&local_2c,TEXT);
- if (!bVar1) {
- Text = &DAT_080f9280;
- goto LAB_08079aca;
- }
- pl_00 = GetPlayer(CreatureID);
- if (pl_00 == (TPlayer *)0x0) {
- Text = "UseNameDoor: Spieler existiert nicht.\n";
- goto LAB_08079aca;
- }
- local_2c = (Object)Door->ObjectID;
- GetObjectCoordinates(&local_2c,&local_58,&x,&y);
- HouseID = GetHouseID(local_58,x,y);
- if (HouseID == 0) {
- error(&DAT_080f9200,local_58,x,y);
- }
- else {
- bVar1 = IsOwner(HouseID,pl_00);
- if ((!bVar1) && (bVar1 = CheckRight((pl_00->super_TCreature).ID,OPEN_NAMEDOORS), !bVar1)
- ) {
- local_2c = (Object)Door->ObjectID;
- bVar1 = MayOpenDoor(&local_2c,pl_00);
- if (!bVar1) {
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 1;
- goto LAB_08079a3a;
- }
- }
- Object::getObjectType(local_3c);
- _TypeID = ObjectType::getAttribute((ObjectType *)local_3c,NAMEDOORTARGET);
- ObjectType::setTypeID((ObjectType *)&local_2c,_TypeID);
- ObjectType::setTypeID((ObjectType *)local_3c,0);
- if (local_2c.ObjectID != local_3c[0].ObjectID) {
- bVar1 = ObjectType::getFlag((ObjectType *)&local_2c,UNPASS);
- if (bVar1) {
- z = NONE.ObjectID;
- local_3c[0] = (Object)Door->ObjectID;
- ClearField(local_3c,(Object *)&z);
- }
- ObjectType::setTypeID((ObjectType *)&z,local_2c.ObjectID);
- local_3c[0] = (Object)Door->ObjectID;
- Change(local_3c,(ObjectType *)&z,0);
- return;
- }
- Object::getObjectType((Object *)&z);
- error(&DAT_080f91c0,z);
- }
- }
- else {
- Text = &DAT_080f9320;
-LAB_08079aca:
- error(Text);
- }
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0xffffffff;
-LAB_08079a3a:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,&RESULT::typeinfo,0);
-}
-
-
-
-void UseLevelDoor(ulong CreatureID,Object *Door)
-
-{
- bool bVar1;
- bool bVar2;
- TPlayer *pTVar3;
- int iVar4;
- ulong uVar5;
- char *pcVar6;
- undefined4 *puVar7;
- TPlayer *pl;
- Object local_4c [4];
- Object local_3c;
- ObjectType Target;
- Object local_2c [7];
-
- // try { // try from 08079b28 to 08079d8b has its CatchHandler @ 08079d97
- bVar1 = Object::exists(Door);
- if (bVar1) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,LEVELDOOR);
- if (!bVar1) goto LAB_08079d8e;
- Object::getContainer(local_2c);
- Object::getObjectType(&local_3c);
- if (local_3c.ObjectID != 0) goto LAB_08079d8e;
- pTVar3 = GetPlayer(CreatureID);
- if (pTVar3 == (TPlayer *)0x0) {
- pcVar6 = "UseLevelDoor: Spieler existiert nicht.\n";
- goto LAB_08079d87;
- }
- Object::getObjectType(&local_3c);
- bVar1 = ObjectType::getFlag((ObjectType *)&local_3c,UNPASS);
- if (!bVar1) {
- puVar7 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar7 = 0x1d;
- goto LAB_08079d37;
- }
- iVar4 = TSkill::Get((pTVar3->super_TCreature).super_TSkillBase.Skills[0]);
- uVar5 = Object::getAttribute(Door,DOORLEVEL);
- if (iVar4 < (int)uVar5) {
- local_3c = (Object)Door->ObjectID;
- pcVar6 = GetInfo(&local_3c);
- SendMessage((pTVar3->super_TCreature).Connection,0x16,"%s.",pcVar6);
- return;
- }
- Object::getObjectType(local_2c);
- uVar5 = ObjectType::getAttribute((ObjectType *)local_2c,LEVELDOORTARGET);
- ObjectType::setTypeID((ObjectType *)&local_3c,uVar5);
- bVar1 = false;
- ObjectType::setTypeID((ObjectType *)local_2c,0);
- if ((local_3c.ObjectID == local_2c[0].ObjectID) ||
- (bVar2 = ObjectType::getFlag((ObjectType *)&local_3c,UNPASS), bVar2)) {
- bVar1 = true;
- }
- if (!bVar1) {
- ObjectType::setTypeID((ObjectType *)local_4c,local_3c.ObjectID);
- local_2c[0] = (Object)Door->ObjectID;
- Change(local_2c,(ObjectType *)local_4c,0);
- local_4c[0].ObjectID = NONE.ObjectID;
- Object::getContainer(local_2c);
- pl = (TPlayer *)(pTVar3->super_TCreature).CrObject.ObjectID;
- Move(0,(Object *)&pl,local_2c,-1,false,local_4c);
- return;
- }
- Object::getObjectType(local_4c);
- error(&DAT_080f9360,local_4c[0].ObjectID);
- }
- else {
-LAB_08079d8e:
- pcVar6 = &DAT_080f9400;
-LAB_08079d87:
- error(pcVar6);
- }
- puVar7 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar7 = 0xffffffff;
-LAB_08079d37:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar7,&RESULT::typeinfo,0);
-}
-
-
-
-void UseQuestDoor(ulong CreatureID,Object *Door)
-
-{
- bool bVar1;
- bool bVar2;
- TPlayer *this;
- ulong uVar3;
- ulong uVar4;
- char *pcVar5;
- undefined4 *puVar6;
- TPlayer *pl;
- Object local_4c [4];
- Object local_3c;
- ObjectType Target;
- Object local_2c [7];
-
- // try { // try from 08079dc8 to 0807a03c has its CatchHandler @ 0807a048
- bVar1 = Object::exists(Door);
- if (bVar1) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,QUESTDOOR);
- if (!bVar1) goto LAB_0807a03f;
- Object::getContainer(local_2c);
- Object::getObjectType(&local_3c);
- if (local_3c.ObjectID != 0) goto LAB_0807a03f;
- this = GetPlayer(CreatureID);
- if (this == (TPlayer *)0x0) {
- pcVar5 = "UseQuestDoor: Spieler existiert nicht.\n";
- goto LAB_0807a038;
- }
- Object::getObjectType(&local_3c);
- bVar1 = ObjectType::getFlag((ObjectType *)&local_3c,UNPASS);
- if (!bVar1) {
- puVar6 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar6 = 0x1d;
- goto LAB_08079fe8;
- }
- uVar3 = Object::getAttribute(Door,DOORQUESTNUMBER);
- uVar3 = TPlayer::GetQuestValue(this,uVar3);
- uVar4 = Object::getAttribute(Door,DOORQUESTVALUE);
- if (uVar3 != uVar4) {
- local_3c = (Object)Door->ObjectID;
- pcVar5 = GetInfo(&local_3c);
- SendMessage((this->super_TCreature).Connection,0x16,"%s.",pcVar5);
- return;
- }
- Object::getObjectType(local_2c);
- uVar3 = ObjectType::getAttribute((ObjectType *)local_2c,QUESTDOORTARGET);
- ObjectType::setTypeID((ObjectType *)&local_3c,uVar3);
- bVar1 = false;
- ObjectType::setTypeID((ObjectType *)local_2c,0);
- if ((local_3c.ObjectID == local_2c[0].ObjectID) ||
- (bVar2 = ObjectType::getFlag((ObjectType *)&local_3c,UNPASS), bVar2)) {
- bVar1 = true;
- }
- if (!bVar1) {
- ObjectType::setTypeID((ObjectType *)local_4c,local_3c.ObjectID);
- local_2c[0] = (Object)Door->ObjectID;
- Change(local_2c,(ObjectType *)local_4c,0);
- local_4c[0].ObjectID = NONE.ObjectID;
- Object::getContainer(local_2c);
- pl = (TPlayer *)(this->super_TCreature).CrObject.ObjectID;
- Move(0,(Object *)&pl,local_2c,-1,false,local_4c);
- return;
- }
- Object::getObjectType(local_4c);
- error(&DAT_080f9440,local_4c[0].ObjectID);
- }
- else {
-LAB_0807a03f:
- pcVar5 = &DAT_080f94e0;
-LAB_0807a038:
- error(pcVar5);
- }
- puVar6 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar6 = 0xffffffff;
-LAB_08079fe8:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar6,&RESULT::typeinfo,0);
-}
-
-
-
-void UseWeapon(ulong CreatureID,Object *Weapon,Object *Target)
-
-{
- bool bVar1;
- TPlayer *pl;
- ulong uVar2;
- TPlayer *pTVar3;
- long lVar4;
- undefined4 *puVar5;
- char *Text;
- Object *pOVar6;
- Object local_4c [4];
- Object local_3c;
- ObjectType Dest;
- Object local_2c [7];
-
- // try { // try from 0807a078 to 0807a2c9 has its CatchHandler @ 0807a2d5
- bVar1 = Object::exists(Weapon);
- if (bVar1) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,WEAPON);
- if (!bVar1) goto LAB_0807a2cc;
- Object::getObjectType(local_2c);
- uVar2 = ObjectType::getAttribute((ObjectType *)local_2c,WEAPONTYPE);
- bVar1 = false;
- if ((0 < (int)uVar2) && ((int)uVar2 < 4)) {
- bVar1 = true;
- }
- if (!bVar1) goto LAB_0807a2cc;
- bVar1 = Object::exists(Target);
- if (!bVar1) {
-LAB_0807a2be:
- Text = &DAT_080f9560;
- goto LAB_0807a2c5;
- }
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,DESTROY);
- if (!bVar1) goto LAB_0807a2be;
- pTVar3 = GetPlayer(CreatureID);
- if (pTVar3 != (TPlayer *)0x0) {
- Object::getContainer(local_2c);
- pOVar6 = local_2c;
- Object::getObjectType(&local_3c);
- if (local_3c.ObjectID == 0) {
- local_3c = (Object)Target->ObjectID;
- GraphicalEffect(&local_3c,3);
- lVar4 = random();
- if (lVar4 == 1) {
- Object::getObjectType(local_2c);
- uVar2 = ObjectType::getAttribute((ObjectType *)local_2c,DESTROYTARGET);
- ObjectType::setTypeID((ObjectType *)&local_3c,uVar2);
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,CONTAINER);
- if (bVar1) {
- ObjectType::setTypeID((ObjectType *)local_2c,0);
- if ((local_3c.ObjectID == local_2c[0].ObjectID) ||
- (bVar1 = ObjectType::getFlag((ObjectType *)&local_3c,CONTAINER), !bVar1))
- {
- uVar2 = 0;
- }
- else {
- uVar2 = ObjectType::getAttribute((ObjectType *)&local_3c,CAPACITY);
- }
- local_4c[0] = (Object)Target->ObjectID;
- Empty(local_4c,uVar2);
- }
- ObjectType::setTypeID((ObjectType *)local_4c,local_3c.ObjectID);
- local_2c[0] = (Object)Target->ObjectID;
- Change(local_2c,(ObjectType *)local_4c,0);
- }
- return;
- }
- puVar5 = (undefined4 *)__cxa_allocate_exception(4,pOVar6);
- *puVar5 = 1;
- goto LAB_0807a27f;
- }
- error("UseWeapon: Spieler %d existiert nicht.\n",CreatureID);
- }
- else {
-LAB_0807a2cc:
- Text = &DAT_080f95c0;
-LAB_0807a2c5:
- error(Text);
- }
- puVar5 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar5 = 0xffffffff;
-LAB_0807a27f:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar5,&RESULT::typeinfo,0);
-}
-
-
-
-void UseChangeObject(ulong CreatureID,Object *Obj)
-
-{
- bool bVar1;
- bool bVar2;
- TPlayer *pl;
- TPlayer *pTVar3;
- ulong _TypeID;
- undefined4 *puVar4;
- Object *this;
- Object *Exclude;
- int local_88;
- int x;
- int y;
- int z;
- Object local_6c [4];
- Object local_5c [4];
- Object local_4c [4];
- Object local_3c [4];
- Object local_2c;
- ObjectType NewType;
-
- // try { // try from 0807a30b to 0807a849 has its CatchHandler @ 0807a850
- bVar1 = Object::exists(Obj);
- if (bVar1) {
- Object::getObjectType(&local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)&local_2c,CHANGEUSE);
- if (bVar1) {
- pTVar3 = GetPlayer(CreatureID);
- if (pTVar3 != (TPlayer *)0x0) {
- Object::getObjectType(local_3c);
- _TypeID = ObjectType::getAttribute((ObjectType *)local_3c,CHANGETARGET);
- ObjectType::setTypeID((ObjectType *)&local_2c,_TypeID);
- bVar1 = false;
- Object::getObjectType(local_3c);
- bVar2 = ObjectType::getFlag((ObjectType *)local_3c,UNPASS);
- if (!bVar2) {
- ObjectType::setTypeID((ObjectType *)local_3c,0);
- ObjectType::setTypeID((ObjectType *)local_4c,local_3c[0].ObjectID);
- if ((local_2c.ObjectID != local_4c[0].ObjectID) &&
- (bVar2 = ObjectType::getFlag((ObjectType *)&local_2c,UNPASS), bVar2)) {
- bVar1 = true;
- }
- }
- if (bVar1) {
- local_5c[0] = (Object)Obj->ObjectID;
- local_4c[0].ObjectID = local_5c[0].ObjectID;
- ClearField(local_5c,local_4c);
- }
- else {
- bVar1 = false;
- Object::getObjectType(local_5c);
- bVar2 = ObjectType::getFlag((ObjectType *)local_5c,UNLAY);
- if (!bVar2) {
- ObjectType::setTypeID((ObjectType *)local_5c,0);
- ObjectType::setTypeID((ObjectType *)local_4c,local_5c[0].ObjectID);
- if ((local_2c.ObjectID != local_4c[0].ObjectID) &&
- (bVar2 = ObjectType::getFlag((ObjectType *)&local_2c,UNLAY), bVar2)) {
- bVar1 = true;
- }
- }
- if (bVar1) {
- local_4c[0] = (Object)Obj->ObjectID;
- GetObjectCoordinates(local_4c,&local_88,&x,&y);
- bVar1 = false;
- bVar2 = CoordinateFlag();
- if (bVar2) {
- bVar1 = CoordinateFlag();
- bVar1 = !bVar1;
- }
- if (bVar1) {
- local_4c[0].ObjectID = NONE.ObjectID;
- GetMapContainer((int)local_6c,local_88 + 1,x);
- this = (Object *)&z;
- Object::getNextObject(this);
- Exclude = local_4c;
- }
- else {
- bVar1 = false;
- bVar2 = CoordinateFlag();
- if (bVar2) {
- bVar1 = CoordinateFlag();
- bVar1 = !bVar1;
- }
- if (bVar1) {
- x = x + 1;
- z = NONE.ObjectID;
- }
- else {
- bVar1 = false;
- bVar2 = CoordinateFlag();
- if (bVar2) {
- bVar1 = CoordinateFlag();
- bVar1 = !bVar1;
- }
- if (bVar1) {
- z = NONE.ObjectID;
- local_88 = local_88 + -1;
- }
- else {
- bVar1 = false;
- bVar2 = CoordinateFlag();
- if (bVar2) {
- bVar1 = CoordinateFlag();
- bVar1 = !bVar1;
- }
- if (!bVar1) goto LAB_0807a3d4;
- x = x + -1;
- z = NONE.ObjectID;
- }
- }
- Exclude = (Object *)&z;
- NONE.ObjectID = z;
- GetMapContainer((int)local_6c,local_88,x);
- Object::getNextObject(local_4c);
- this = local_4c;
- }
- MoveAllObjects(this,local_6c,Exclude,true);
- }
- }
-LAB_0807a3d4:
- ObjectType::setTypeID((ObjectType *)&z,local_2c.ObjectID);
- local_6c[0] = (Object)Obj->ObjectID;
- Change(local_6c,(ObjectType *)&z,0);
- return;
- }
- error("UseChangeObject: Spieler %d existiert nicht.\n",CreatureID);
- goto LAB_0807a814;
- }
- }
- error("UseChangeObject: Objekt existiert nicht oder ist kein CHANGEUSE-Objekt.\n");
-LAB_0807a814:
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0xffffffff;
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,&RESULT::typeinfo,0);
-}
-
-
-
-void UseObject(ulong CreatureID,Object *Obj)
-
-{
- bool bVar1;
- TCreature *cr;
- TCreature *pTVar2;
- undefined4 *puVar3;
- char *Text;
- Object local_5c [4];
- Object local_4c [4];
- Object local_3c [4];
- Object local_2c;
- Object User;
-
- // try { // try from 0807a888 to 0807a967 has its CatchHandler @ 0807a985
- bVar1 = Object::exists(Obj);
- if (bVar1) {
- Object::getObjectType(&local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)&local_2c,USEEVENT);
- if (bVar1) {
- if (CreatureID == 0) {
- pTVar2 = (TCreature *)0x0;
- }
- else {
- pTVar2 = GetCreature(CreatureID);
- }
- if (pTVar2 == (TCreature *)0x0) {
- local_2c.ObjectID = NONE.ObjectID;
- }
- else {
- local_2c.ObjectID = (pTVar2->CrObject).ObjectID;
- }
- local_3c[0] = (Object)NONE.ObjectID;
- local_4c[0] = (Object)Obj->ObjectID;
- local_5c[0].ObjectID = local_2c.ObjectID;
- bVar1 = HandleEvent(EVENT_USE,local_5c,local_4c,local_3c);
- if (bVar1) {
- return;
- }
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0x1d;
- goto LAB_0807a92d;
- }
- Text = &DAT_080f96c0;
- }
- else {
- Text = &DAT_080f9700;
- }
- error(Text);
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0xffffffff;
-LAB_0807a92d:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,&RESULT::typeinfo,0);
-}
-
-
-
-void UseObjects(ulong CreatureID,Object *Obj1,Object *Obj2)
-
-{
- bool bVar1;
- TCreature *cr;
- TCreature *pTVar2;
- undefined4 *puVar3;
- char *Text;
- Object local_5c [4];
- Object local_4c [4];
- Object local_3c [4];
- Object local_2c;
- Object User;
-
- // try { // try from 0807a9b8 to 0807aaa7 has its CatchHandler @ 0807aad0
- bVar1 = Object::exists(Obj1);
- if (bVar1) {
- bVar1 = Object::exists(Obj2);
- if (bVar1) {
- Object::getObjectType(&local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)&local_2c,USEEVENT);
- if (bVar1) {
- if (CreatureID == 0) {
- pTVar2 = (TCreature *)0x0;
- }
- else {
- pTVar2 = GetCreature(CreatureID);
- }
- local_5c[0].ObjectID = NONE.ObjectID;
- if (pTVar2 != (TCreature *)0x0) {
- local_5c[0].ObjectID = (pTVar2->CrObject).ObjectID;
- }
- local_3c[0] = (Object)Obj2->ObjectID;
- local_4c[0] = (Object)Obj1->ObjectID;
- local_2c.ObjectID = local_5c[0].ObjectID;
- bVar1 = HandleEvent(EVENT_MULTIUSE,local_5c,local_4c,local_3c);
- if (bVar1) {
- return;
- }
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0x1d;
- goto LAB_0807aa6d;
- }
- Text = &DAT_080f9740;
- }
- else {
- Text = &DAT_080f9780;
- }
- }
- else {
- Text = &DAT_080f97c0;
- }
- error(Text);
- puVar3 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar3 = 0xffffffff;
-LAB_0807aa6d:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar3,&RESULT::typeinfo,0);
-}
-
-
-
-void MovementEvent(Object *Obj,Object *Start,Object *Dest)
-
-{
- bool bVar1;
- undefined4 *puVar2;
- char *Text;
- Object local_4c [4];
- Object local_3c [4];
- Object local_2c [7];
-
- // try { // try from 0807ab0b to 0807aca1 has its CatchHandler @ 0807acc0
- bVar1 = Object::exists(Obj);
- if (bVar1) {
- bVar1 = Object::exists(Start);
- if (bVar1) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,CONTAINER);
- if (!bVar1) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,CHEST);
- if (!bVar1) goto LAB_0807acaa;
- }
- bVar1 = Object::exists(Dest);
- if (bVar1) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,CONTAINER);
- if (!bVar1) {
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,CHEST);
- if (!bVar1) goto LAB_0807ac5d;
- }
- Object::getObjectType(local_2c);
- bVar1 = ObjectType::getFlag((ObjectType *)local_2c,MOVEMENTEVENT);
- if (!bVar1) {
- return;
- }
- local_2c[0].ObjectID = NONE.ObjectID;
- local_3c[0] = (Object)Obj->ObjectID;
- local_4c[0].ObjectID = NONE.ObjectID;
- HandleEvent(EVENT_MOVEMENT,local_4c,local_3c,local_2c);
- bVar1 = Object::exists(Obj);
- if (bVar1) {
- return;
- }
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0x1f;
- goto LAB_0807ac18;
- }
-LAB_0807ac5d:
- Text = "MovementEvent: \"Dest\" ist kein Container.\n";
- }
- else {
-LAB_0807acaa:
- Text = "MovementEvent: \"Start\" ist kein Container.\n";
- }
- }
- else {
- Text = &DAT_080f9880;
- }
- error(Text);
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = 0xffffffff;
-LAB_0807ac18:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,&RESULT::typeinfo,0);
-}
-
-
-
-void SeparationEvent(Object *Obj,Object *Start)
-
-{
- Object OVar1;
- bool bVar2;
- bool bVar3;
- undefined4 *puVar4;
- ulong uVar5;
- char *Text;
- Object local_6c;
- Object Obj2;
- Object local_5c;
- Object Help;
- Object local_4c;
- ObjectType Target;
- Object local_3c [4];
- Object local_2c;
- Object Obj2_1;
-
- // try { // try from 0807acfb to 0807b14b has its CatchHandler @ 0807b160
- bVar2 = Object::exists(Obj);
- if (bVar2) {
- bVar2 = Object::exists(Start);
- if (bVar2) {
- Object::getObjectType(&local_2c);
- if (local_2c.ObjectID != 0) {
- return;
- }
- Object::getObjectType(&local_2c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_2c,SEPARATIONEVENT);
- if (bVar2) {
- local_3c[0] = (Object)Start->ObjectID;
- GetFirstContainerObject(&local_2c);
- OVar1.ObjectID = local_5c.ObjectID;
- do {
- do {
- local_5c.ObjectID = OVar1.ObjectID;
- bVar2 = false;
- local_3c[0].ObjectID = NONE.ObjectID;
- local_4c.ObjectID = NONE.ObjectID;
- if ((local_2c.ObjectID != NONE.ObjectID) &&
- (bVar3 = Object::exists(&local_2c), bVar3)) {
- bVar2 = true;
- }
- if (!bVar2) goto LAB_0807ad65;
- local_4c.ObjectID = local_2c.ObjectID;
- Object::getNextObject(&local_5c);
- local_2c.ObjectID = local_5c.ObjectID;
- local_3c[0].ObjectID = local_5c.ObjectID;
- uVar5 = Obj->ObjectID;
- OVar1.ObjectID = local_4c.ObjectID;
- } while (uVar5 == local_4c.ObjectID);
- if (uVar5 == local_5c.ObjectID) {
- Object::getNextObject(&local_6c);
- local_2c.ObjectID = local_6c.ObjectID;
- uVar5 = Obj->ObjectID;
- }
- local_6c.ObjectID = local_4c.ObjectID;
- local_3c[0].ObjectID = NONE.ObjectID;
- local_5c.ObjectID = uVar5;
- HandleEvent(EVENT_SEPARATION,local_3c,&local_5c,&local_6c);
- bVar2 = Object::exists(Obj);
- OVar1.ObjectID = local_5c.ObjectID;
- } while (bVar2);
- }
- else {
-LAB_0807ad65:
- local_5c = (Object)Start->ObjectID;
- GetFirstContainerObject(&local_6c);
- do {
- do {
- bVar2 = false;
- local_5c.ObjectID = NONE.ObjectID;
- local_4c.ObjectID = NONE.ObjectID;
- if ((local_6c.ObjectID != NONE.ObjectID) &&
- (bVar3 = Object::exists(&local_6c), bVar3)) {
- bVar2 = true;
- }
- if (!bVar2) {
- return;
- }
- local_5c.ObjectID = local_6c.ObjectID;
- Object::getNextObject(local_3c);
- local_6c.ObjectID = local_3c[0].ObjectID;
- local_4c = (Object)Obj->ObjectID;
- } while (local_5c.ObjectID == local_4c.ObjectID);
- if (local_3c[0].ObjectID == local_4c.ObjectID) {
- Object::getNextObject(&local_2c);
- local_3c[0].ObjectID = local_2c.ObjectID;
- }
- local_6c.ObjectID = local_3c[0].ObjectID;
- Object::getObjectType(&local_4c);
- if (local_4c.ObjectID == 99) {
- Object::getObjectType(&local_4c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_4c,LEVELDOOR);
- if (!bVar2) {
- Object::getObjectType(&local_4c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_4c,QUESTDOOR);
- if (!bVar2) goto LAB_0807ae44;
- }
- Object::getObjectType(local_3c);
- bVar2 = ObjectType::getFlag((ObjectType *)local_3c,LEVELDOOR);
- Object::getObjectType(local_3c);
- uVar5 = ObjectType::getAttribute
- ((ObjectType *)local_3c,!bVar2 + LEVELDOORTARGET);
- ObjectType::setTypeID((ObjectType *)&local_4c,uVar5);
- bVar2 = false;
- ObjectType::setTypeID((ObjectType *)local_3c,0);
- if ((local_4c.ObjectID == local_3c[0].ObjectID) ||
- (bVar3 = ObjectType::getFlag((ObjectType *)&local_4c,UNPASS), !bVar3)) {
- bVar2 = true;
- }
- if (!bVar2) {
- local_3c[0] = (Object)Obj->ObjectID;
- local_2c.ObjectID = local_5c.ObjectID;
- ClearField(&local_2c,local_3c);
- ObjectType::setTypeID((ObjectType *)local_3c,local_4c.ObjectID);
- local_2c.ObjectID = local_5c.ObjectID;
- Change(&local_2c,(ObjectType *)local_3c,0);
- return;
- }
- Object::getObjectType(&local_2c);
- error(&DAT_080f98c0,local_2c.ObjectID);
- goto LAB_0807afdc;
- }
-LAB_0807ae44:
- Object::getObjectType(&local_4c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_4c,SEPARATIONEVENT);
- if (bVar2) {
- local_4c = (Object)Obj->ObjectID;
- local_3c[0].ObjectID = local_5c.ObjectID;
- local_2c.ObjectID = NONE.ObjectID;
- HandleEvent(EVENT_SEPARATION,&local_2c,local_3c,&local_4c);
- }
- bVar2 = Object::exists(Obj);
- } while (bVar2);
- }
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0x1f;
- goto LAB_0807ae92;
- }
- Text = &DAT_080f9920;
- }
- else {
- Text = &DAT_080f9960;
- }
- error(Text);
-LAB_0807afdc:
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0xffffffff;
-LAB_0807ae92:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,&RESULT::typeinfo,0);
-}
-
-
-
-void CollisionEvent(Object *Obj,Object *Dest)
-
-{
- Object OVar1;
- bool bVar2;
- bool bVar3;
- undefined4 *puVar4;
- ulong uVar5;
- char *Text;
- Object *pOVar6;
- int local_9c;
- int dx_1;
- int dy_1;
- int dz_1;
- int x_1;
- int y_1;
- int z_1;
- int dx;
- int dy;
- int dz;
- int x;
- int y;
- int z;
- Object Obj2;
- Object local_5c;
- Object Help;
- Object local_4c;
- Object Obj2_1;
- Object local_3c;
- Object Help_1;
- Object local_2c [7];
-
- // try { // try from 0807b19b to 0807b86b has its CatchHandler @ 0807b890
- bVar2 = Object::exists(Obj);
- if (bVar2) {
- bVar2 = Object::exists(Dest);
- if (bVar2) {
- Object::getObjectType(local_2c);
- if (local_2c[0].ObjectID != 0) {
- return;
- }
- Object::getObjectType(local_2c);
- bVar2 = ObjectType::getFlag((ObjectType *)local_2c,TELEPORTABSOLUTE);
- if (bVar2) {
-LAB_0807b228:
- Object::getObjectType(local_2c);
- bVar2 = ObjectType::getFlag((ObjectType *)local_2c,TELEPORTABSOLUTE);
- if (bVar2) {
- Object::getAttribute(Obj,ABSTELEPORTDESTINATION);
- UnpackAbsoluteCoordinate();
- }
- else {
- local_2c[0] = (Object)Obj->ObjectID;
- GetObjectCoordinates(local_2c,&dz,&x,&y);
- Object::getObjectType(local_2c);
- ObjectType::getAttribute((ObjectType *)local_2c,RELTELEPORTDISPLACEMENT);
- UnpackRelativeCoordinate();
- dz = dz + z_1;
- x = x + dx;
- y = y + dy;
- }
- local_2c[0].ObjectID = NONE.ObjectID;
- GetMapContainer((int)&local_3c,dz,x);
- Object::getNextObject(&local_4c);
- MoveAllObjects(&local_4c,&local_3c,local_2c,true);
- Object::getObjectType(&local_4c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_4c,TELEPORTABSOLUTE);
- Object::getObjectType(&local_4c);
- ObjectType::getAttribute
- ((ObjectType *)&local_4c,(uint)!bVar2 * 2 + ABSTELEPORTEFFECT);
- pOVar6 = (Object *)x;
- GraphicalEffect();
- bVar2 = Object::exists(Obj);
- if (bVar2) {
- return;
- }
- }
- else {
- Object::getObjectType(local_2c);
- bVar2 = ObjectType::getFlag((ObjectType *)local_2c,TELEPORTRELATIVE);
- if (bVar2) goto LAB_0807b228;
- Object::getObjectType(&local_4c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_4c,COLLISIONEVENT);
- if (bVar2) {
- local_3c = (Object)Dest->ObjectID;
- GetFirstContainerObject(&local_4c);
- OVar1.ObjectID = local_5c.ObjectID;
- do {
- do {
- local_5c.ObjectID = OVar1.ObjectID;
- bVar2 = false;
- local_3c.ObjectID = NONE.ObjectID;
- local_2c[0].ObjectID = NONE.ObjectID;
- if ((local_4c.ObjectID != NONE.ObjectID) &&
- (bVar3 = Object::exists(&local_4c), bVar3)) {
- bVar2 = true;
- }
- if (!bVar2) goto LAB_0807b41e;
- local_3c.ObjectID = local_4c.ObjectID;
- Object::getNextObject(&local_5c);
- local_4c.ObjectID = local_5c.ObjectID;
- local_2c[0].ObjectID = local_5c.ObjectID;
- uVar5 = Obj->ObjectID;
- OVar1.ObjectID = local_3c.ObjectID;
- } while (uVar5 == local_3c.ObjectID);
- if (uVar5 == local_5c.ObjectID) {
- Object::getNextObject((Object *)&z);
- local_4c.ObjectID = z;
- uVar5 = Obj->ObjectID;
- }
- z = local_3c.ObjectID;
- local_2c[0].ObjectID = NONE.ObjectID;
- pOVar6 = local_2c;
- local_5c.ObjectID = uVar5;
- HandleEvent(EVENT_COLLISION,local_2c,&local_5c,(Object *)&z);
- bVar2 = Object::exists(Obj);
- OVar1.ObjectID = local_5c.ObjectID;
- } while (bVar2);
- }
- else {
-LAB_0807b41e:
- local_5c = (Object)Dest->ObjectID;
- GetFirstContainerObject((Object *)&z);
- do {
- do {
- bVar2 = false;
- local_5c.ObjectID = NONE.ObjectID;
- local_4c.ObjectID = NONE.ObjectID;
- if ((z != NONE.ObjectID) &&
- (bVar3 = Object::exists((Object *)&z), bVar3)) {
- bVar2 = true;
- }
- if (!bVar2) {
- return;
- }
- local_5c.ObjectID = z;
- Object::getNextObject(&local_3c);
- z = local_3c.ObjectID;
- local_4c = (Object)Obj->ObjectID;
- } while (local_5c.ObjectID == local_4c.ObjectID);
- if (local_3c.ObjectID == local_4c.ObjectID) {
- Object::getNextObject(local_2c);
- local_3c.ObjectID = local_2c[0].ObjectID;
- }
- z = local_3c.ObjectID;
- Object::getObjectType(&local_4c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_4c,TELEPORTABSOLUTE);
- if (bVar2) {
-LAB_0807b4e5:
- Object::getObjectType(&local_4c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_4c,TELEPORTABSOLUTE);
- if (bVar2) {
- Object::getAttribute(&local_5c,ABSTELEPORTDESTINATION);
- UnpackAbsoluteCoordinate();
- }
- else {
- local_4c.ObjectID = local_5c.ObjectID;
- GetObjectCoordinates(&local_4c,&dz_1,&x_1,&y_1);
- Object::getObjectType(&local_4c);
- ObjectType::getAttribute
- ((ObjectType *)&local_4c,RELTELEPORTDISPLACEMENT);
- UnpackRelativeCoordinate();
- dz_1 = dz_1 + local_9c;
- x_1 = x_1 + dx_1;
- y_1 = y_1 + dy_1;
- }
- local_4c = (Object)Obj->ObjectID;
- GetMapContainer((int)&local_3c,dz_1,x_1);
- MoveOneObject(&local_4c,&local_3c);
- Object::getObjectType(&local_4c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_4c,TELEPORTABSOLUTE);
- Object::getObjectType(&local_4c);
- ObjectType::getAttribute
- ((ObjectType *)&local_4c,(uint)!bVar2 * 2 + ABSTELEPORTEFFECT)
- ;
- pOVar6 = (Object *)x_1;
- GraphicalEffect();
- }
- else {
- Object::getObjectType(&local_4c);
- bVar2 = ObjectType::getFlag((ObjectType *)&local_4c,TELEPORTRELATIVE);
- if (bVar2) goto LAB_0807b4e5;
- Object::getObjectType(&local_4c);
- pOVar6 = (Object *)0xd;
- bVar2 = ObjectType::getFlag((ObjectType *)&local_4c,COLLISIONEVENT);
- if (bVar2) {
- local_4c = (Object)Obj->ObjectID;
- local_3c.ObjectID = local_5c.ObjectID;
- local_2c[0].ObjectID = NONE.ObjectID;
- pOVar6 = local_2c;
- HandleEvent(EVENT_COLLISION,local_2c,&local_3c,&local_4c);
- }
- }
- bVar2 = Object::exists(Obj);
- } while (bVar2);
- }
- }
- puVar4 = (undefined4 *)__cxa_allocate_exception(4,pOVar6);
- *puVar4 = 0x1f;
- goto LAB_0807b364;
- }
- Text = &DAT_080f99a0;
- }
- else {
- Text = &DAT_080f99e0;
- }
- error(Text);
- puVar4 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar4 = 0xffffffff;
-LAB_0807b364:
- // WARNING: Subroutine does not return
- __cxa_throw(puVar4,&RESULT::typeinfo,0);
-}
-
-
-
-// WARNING: Variable defined which should be unmapped: z
-
-void LoadParameters(TReadScriptFile *Script,int *Parameters,int NumberOfParameters,...)
-
-{
- bool bVar1;
- char cVar2;
- int iVar3;
- ulong uVar4;
- char *pcVar5;
- char *pcVar6;
- char *pcVar7;
- undefined1 uVar8;
- char *Ident;
- int local_24;
- int i;
- va_list va;
- int x;
- int y;
- int z;
-
- if (5 < NumberOfParameters) {
- error("LoadParameters: Zu viele Parameter (%d).\n",NumberOfParameters);
- TReadScriptFile::error(Script,"too many parameters");
- }
- if (NumberOfParameters != 0) {
- if ((Script->Token != SPECIAL) ||
- (cVar2 = TReadScriptFile::getSpecial(Script), cVar2 != '(')) {
- // try { // try from 0807b8eb to 0807bcc7 has its CatchHandler @ 0807bcd0
- TReadScriptFile::error(Script,"\'(\' expected");
- }
- local_24 = 0;
- i = (int)&stack0x00000010;
- if (0 < NumberOfParameters) {
- do {
- if (0 < local_24) {
- TReadScriptFile::readSymbol(Script,',');
- }
- uVar8 = *(int *)i == 0xb;
- switch(*(int *)i) {
- case 0:
- pcVar5 = TReadScriptFile::readIdentifier(Script);
- iVar3 = 5;
- pcVar6 = pcVar5;
- pcVar7 = "null";
- do {
- if (iVar3 == 0) break;
- iVar3 = iVar3 + -1;
- uVar8 = *pcVar6 == *pcVar7;
- pcVar6 = pcVar6 + 1;
- pcVar7 = pcVar7 + 1;
- } while ((bool)uVar8);
- if ((bool)uVar8) {
-LAB_0807ba55:
- Parameters[local_24] = 0;
- }
- else {
- iVar3 = 5;
- pcVar6 = pcVar5;
- pcVar7 = "obj1";
- do {
- if (iVar3 == 0) break;
- iVar3 = iVar3 + -1;
- uVar8 = *pcVar6 == *pcVar7;
- pcVar6 = pcVar6 + 1;
- pcVar7 = pcVar7 + 1;
- } while ((bool)uVar8);
- if ((bool)uVar8) {
- Parameters[local_24] = 1;
- }
- else {
- iVar3 = 5;
- pcVar6 = pcVar5;
- pcVar7 = "obj2";
- do {
- if (iVar3 == 0) break;
- iVar3 = iVar3 + -1;
- uVar8 = *pcVar6 == *pcVar7;
- pcVar6 = pcVar6 + 1;
- pcVar7 = pcVar7 + 1;
- } while ((bool)uVar8);
- if ((bool)uVar8) {
- Parameters[local_24] = 2;
- }
- else {
- iVar3 = 5;
- pcVar6 = pcVar5;
- pcVar7 = "user";
- do {
- if (iVar3 == 0) break;
- iVar3 = iVar3 + -1;
- uVar8 = *pcVar6 == *pcVar7;
- pcVar6 = pcVar6 + 1;
- pcVar7 = pcVar7 + 1;
- } while ((bool)uVar8);
- if ((bool)uVar8) {
- Parameters[local_24] = 3;
- }
- else {
- iVar3 = 5;
- pcVar6 = "temp";
- do {
- if (iVar3 == 0) break;
- iVar3 = iVar3 + -1;
- uVar8 = *pcVar5 == *pcVar6;
- pcVar5 = pcVar5 + 1;
- pcVar6 = pcVar6 + 1;
- } while ((bool)uVar8);
- if (!(bool)uVar8) {
- pcVar5 = "Object expected";
- goto LAB_0807ba48;
- }
- Parameters[local_24] = 4;
- }
- }
- }
- }
- break;
- case 1:
- iVar3 = TReadScriptFile::readNumber(Script);
- Parameters[local_24] = iVar3;
- bVar1 = ObjectTypeExists(iVar3);
- if (!bVar1) {
- pcVar5 = "Unknown object type";
-LAB_0807ba48:
- TReadScriptFile::error(Script,pcVar5);
- }
- break;
- case 2:
- pcVar5 = TReadScriptFile::readIdentifier(Script);
- iVar3 = GetFlagByName(pcVar5);
- Parameters[local_24] = iVar3;
- if (iVar3 == -1) {
- pcVar5 = "Unknown flag";
- goto LAB_0807ba48;
- }
- break;
- case 3:
- pcVar5 = TReadScriptFile::readIdentifier(Script);
- iVar3 = GetTypeAttributeByName(pcVar5);
- Parameters[local_24] = iVar3;
- if (iVar3 == -1) {
- pcVar5 = "Unknown type attribute";
- goto LAB_0807ba48;
- }
- break;
- case 4:
- pcVar5 = TReadScriptFile::readIdentifier(Script);
- iVar3 = GetInstanceAttributeByName(pcVar5);
- Parameters[local_24] = iVar3;
- if (iVar3 == -1) {
- pcVar5 = "Unknown instance attribute";
- goto LAB_0807ba48;
- }
- break;
- case 5:
- TReadScriptFile::readCoordinate(Script);
- uVar4 = PackAbsoluteCoordinate((int)va,x,y);
- goto LAB_0807bb56;
- case 6:
- TReadScriptFile::readCoordinate(Script);
- uVar4 = PackRelativeCoordinate((int)va,x,y);
- goto LAB_0807bb9a;
- case 7:
- pcVar5 = TReadScriptFile::readIdentifier(Script);
- iVar3 = 0x10;
- pcVar6 = pcVar5;
- pcVar7 = "premium_account";
- do {
- if (iVar3 == 0) break;
- iVar3 = iVar3 + -1;
- uVar8 = *pcVar6 == *pcVar7;
- pcVar6 = pcVar6 + 1;
- pcVar7 = pcVar7 + 1;
- } while ((bool)uVar8);
- if ((bool)uVar8) goto LAB_0807ba55;
- iVar3 = 0x10;
- pcVar6 = "special_moveuse";
- do {
- if (iVar3 == 0) break;
- iVar3 = iVar3 + -1;
- uVar8 = *pcVar5 == *pcVar6;
- pcVar5 = pcVar5 + 1;
- pcVar6 = pcVar6 + 1;
- } while ((bool)uVar8);
- if (!(bool)uVar8) {
- pcVar5 = "Unknown right";
- goto LAB_0807ba48;
- }
- Parameters[local_24] = 0x37;
- break;
- case 8:
- pcVar5 = TReadScriptFile::readIdentifier(Script);
- iVar3 = GetSkillByName(pcVar5);
- Parameters[local_24] = iVar3;
- if (iVar3 == -1) {
- pcVar5 = "Unknown skill";
- goto LAB_0807ba48;
- }
- break;
- case 9:
- uVar4 = TReadScriptFile::readNumber(Script);
-LAB_0807bb9a:
- Parameters[local_24] = uVar4;
- break;
- case 10:
- pcVar5 = TReadScriptFile::readString(Script);
- uVar4 = AddDynamicString(pcVar5);
-LAB_0807bb56:
- Parameters[local_24] = uVar4;
- break;
- case 0xb:
- cVar2 = TReadScriptFile::readSpecial(Script);
- Parameters[local_24] = (int)cVar2;
- pcVar5 = strchr("<L=G>N",(int)cVar2);
- if (pcVar5 == (char *)0x0) {
- pcVar5 = "Unknown comparison operator";
- goto LAB_0807ba48;
- }
- }
- local_24 = local_24 + 1;
- i = i + 4;
- } while (local_24 < NumberOfParameters);
- }
- TReadScriptFile::readSymbol(Script,')');
- TReadScriptFile::nextToken(Script);
- }
- return;
-}
-
-
-
-void LoadCondition(TReadScriptFile *Script,TMoveUseCondition *Condition)
-
-{
- char *pcVar1;
- int iVar2;
- char *pcVar3;
- undefined1 uVar4;
- char local_3c [4];
- char Ident [30];
-
- uVar4 = &stack0x00000000 == (undefined1 *)0x5c;
- // try { // try from 0807bd05 to 0807c4e2 has its CatchHandler @ 0807c4e8
- pcVar1 = TReadScriptFile::getIdentifier(Script);
- strcpy(local_3c,pcVar1);
- TReadScriptFile::nextToken(Script);
- iVar2 = 0xb;
- pcVar1 = local_3c;
- pcVar3 = "isposition";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_ISPOSITION;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,2);
- }
- iVar2 = 7;
- pcVar1 = local_3c;
- pcVar3 = "istype";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_ISTYPE;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,2);
- }
- iVar2 = 0xb;
- pcVar1 = local_3c;
- pcVar3 = "iscreature";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_ISCREATURE;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,1);
- }
- iVar2 = 9;
- pcVar1 = local_3c;
- pcVar3 = "isplayer";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_ISPLAYER;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,1);
- }
- iVar2 = 8;
- pcVar1 = local_3c;
- pcVar3 = "hasflag";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_HASFLAG;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,2);
- }
- iVar2 = 0x11;
- pcVar1 = local_3c;
- pcVar3 = "hastypeattribute";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_HASTYPEATTRIBUTE;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,4);
- }
- iVar2 = 0x15;
- pcVar1 = local_3c;
- pcVar3 = "hasinstanceattribute";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_HASINSTANCEATTRIBUTE;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,4);
- }
- iVar2 = 8;
- pcVar1 = local_3c;
- pcVar3 = "hastext";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_HASTEXT;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,2);
- }
- iVar2 = 0xb;
- pcVar1 = local_3c;
- pcVar3 = "ispeaceful";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_ISPEACEFUL;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,1);
- }
- iVar2 = 10;
- pcVar1 = local_3c;
- pcVar3 = "maylogout";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_MAYLOGOUT;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,1);
- }
- iVar2 = 0xe;
- pcVar1 = local_3c;
- pcVar3 = "hasprofession";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_HASPROFESSION;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,2);
- }
- iVar2 = 9;
- pcVar1 = local_3c;
- pcVar3 = "haslevel";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_HASLEVEL;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,3);
- }
- iVar2 = 9;
- pcVar1 = local_3c;
- pcVar3 = "hasright";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_HASRIGHT;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,2);
- }
- iVar2 = 0xe;
- pcVar1 = local_3c;
- pcVar3 = "hasquestvalue";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_HASQUESTVALUE;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,4);
- }
- iVar2 = 10;
- pcVar1 = local_3c;
- pcVar3 = "testskill";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_TESTSKILL;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,4);
- }
- iVar2 = 0xd;
- pcVar1 = local_3c;
- pcVar3 = "countobjects";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_COUNTOBJECTS;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,3);
- }
- iVar2 = 0x12;
- pcVar1 = local_3c;
- pcVar3 = "countobjectsonmap";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_COUNTOBJECTSONMAP;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,3);
- }
- iVar2 = 0xe;
- pcVar1 = local_3c;
- pcVar3 = "isobjectthere";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_ISOBJECTTHERE;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,2);
- }
- iVar2 = 0x10;
- pcVar1 = local_3c;
- pcVar3 = "iscreaturethere";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_ISCREATURETHERE;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,1);
- }
- iVar2 = 0xe;
- pcVar1 = local_3c;
- pcVar3 = "isplayerthere";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_ISPLAYERTHERE;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,1);
- }
- iVar2 = 0x14;
- pcVar1 = local_3c;
- pcVar3 = "isobjectininventory";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_ISOBJECTININVENTORY;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,3);
- }
- iVar2 = 0x11;
- pcVar1 = local_3c;
- pcVar3 = "isprotectionzone";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_ISPROTECTIONZONE;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,1);
- }
- iVar2 = 8;
- pcVar1 = local_3c;
- pcVar3 = "ishouse";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_ISHOUSE;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,1);
- }
- iVar2 = 0xd;
- pcVar1 = local_3c;
- pcVar3 = "ishouseowner";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_ISHOUSEOWNER;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,2);
- }
- iVar2 = 10;
- pcVar1 = local_3c;
- pcVar3 = "isdressed";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_ISDRESSED;
- uVar4 = Condition->Parameters == (int *)0x0;
- LoadParameters(Script,Condition->Parameters,1);
- }
- iVar2 = 7;
- pcVar1 = local_3c;
- pcVar3 = "random";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Condition->Condition = CONDITION_RANDOM;
- LoadParameters(Script,Condition->Parameters,1);
- }
- return;
-}
-
-
-
-void LoadAction(TReadScriptFile *Script,TMoveUseAction *Action)
-
-{
- char *pcVar1;
- int iVar2;
- char *pcVar3;
- undefined1 uVar4;
- char local_3c [4];
- char Ident [30];
-
- uVar4 = &stack0x00000000 == (undefined1 *)0x5c;
- // try { // try from 0807c515 to 0807d0d8 has its CatchHandler @ 0807d0e0
- pcVar1 = TReadScriptFile::getIdentifier(Script);
- strcpy(local_3c,pcVar1);
- TReadScriptFile::nextToken(Script);
- iVar2 = 0xc;
- pcVar1 = local_3c;
- pcVar3 = "createonmap";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_CREATEONMAP;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,3);
- }
- iVar2 = 7;
- pcVar1 = local_3c;
- pcVar3 = "create";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_CREATE;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,3);
- }
- iVar2 = 0xd;
- pcVar1 = local_3c;
- pcVar3 = "monsteronmap";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_MONSTERONMAP;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 8;
- pcVar1 = local_3c;
- pcVar3 = "monster";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_MONSTER;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 0xc;
- pcVar1 = local_3c;
- pcVar3 = "effectonmap";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_EFFECTONMAP;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 7;
- pcVar1 = local_3c;
- pcVar3 = "effect";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_EFFECT;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 10;
- pcVar1 = local_3c;
- pcVar3 = "textonmap";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_TEXTONMAP;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,3);
- }
- iVar2 = 5;
- pcVar1 = local_3c;
- pcVar3 = "text";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_TEXT;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,3);
- }
- iVar2 = 0xc;
- pcVar1 = local_3c;
- pcVar3 = "changeonmap";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_CHANGEONMAP;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,4);
- }
- iVar2 = 7;
- pcVar1 = local_3c;
- pcVar3 = "change";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_CHANGE;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,3);
- }
- iVar2 = 10;
- pcVar1 = local_3c;
- pcVar3 = "changerel";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_CHANGEREL;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,5);
- }
- iVar2 = 0xd;
- pcVar1 = local_3c;
- pcVar3 = "setattribute";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_SETATTRIBUTE;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,3);
- }
- iVar2 = 0x10;
- pcVar1 = local_3c;
- pcVar3 = "changeattribute";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_CHANGEATTRIBUTE;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,3);
- }
- iVar2 = 0xe;
- pcVar1 = local_3c;
- pcVar3 = "setquestvalue";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_SETQUESTVALUE;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,3);
- }
- iVar2 = 7;
- pcVar1 = local_3c;
- pcVar3 = "damage";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_DAMAGE;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,4);
- }
- iVar2 = 9;
- pcVar1 = local_3c;
- pcVar3 = "setstart";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_SETSTART;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 10;
- pcVar1 = local_3c;
- pcVar3 = "writename";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_WRITENAME;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,3);
- }
- iVar2 = 10;
- pcVar1 = local_3c;
- pcVar3 = "writetext";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_WRITETEXT;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 7;
- pcVar1 = local_3c;
- pcVar3 = "logout";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_LOGOUT;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,1);
- }
- iVar2 = 0xd;
- pcVar1 = local_3c;
- pcVar3 = "moveallonmap";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_MOVEALLONMAP;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 8;
- pcVar1 = local_3c;
- pcVar3 = "moveall";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_MOVEALL;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 0xb;
- pcVar1 = local_3c;
- pcVar3 = "moveallrel";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_MOVEALLREL;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 0xd;
- pcVar1 = local_3c;
- pcVar3 = "movetoponmap";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_MOVETOPONMAP;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,3);
- }
- iVar2 = 8;
- pcVar1 = local_3c;
- pcVar3 = "movetop";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_MOVETOP;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 0xb;
- pcVar1 = local_3c;
- pcVar3 = "movetoprel";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_MOVETOPREL;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 5;
- pcVar1 = local_3c;
- pcVar3 = "move";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_MOVE;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 8;
- pcVar1 = local_3c;
- pcVar3 = "moverel";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_MOVEREL;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,3);
- }
- iVar2 = 9;
- pcVar1 = local_3c;
- pcVar3 = "retrieve";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_RETRIEVE;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,3);
- }
- iVar2 = 0xf;
- pcVar1 = local_3c;
- pcVar3 = "deleteallonmap";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_DELETEALLONMAP;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,1);
- }
- iVar2 = 0xf;
- pcVar1 = local_3c;
- pcVar3 = "deletetoponmap";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_DELETETOPONMAP;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 0xc;
- pcVar1 = local_3c;
- pcVar3 = "deleteonmap";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_DELETEONMAP;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 7;
- pcVar1 = local_3c;
- pcVar3 = "delete";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_DELETE;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,1);
- }
- iVar2 = 0x12;
- pcVar1 = local_3c;
- pcVar3 = "deleteininventory";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_DELETEININVENTORY;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,3);
- }
- iVar2 = 0xc;
- pcVar1 = local_3c;
- pcVar3 = "description";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_DESCRIPTION;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,2);
- }
- iVar2 = 10;
- pcVar1 = local_3c;
- pcVar3 = "loaddepot";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_LOADDEPOT;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,4);
- }
- iVar2 = 10;
- pcVar1 = local_3c;
- pcVar3 = "savedepot";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_SAVEDEPOT;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,4);
- }
- iVar2 = 9;
- pcVar1 = local_3c;
- pcVar3 = "sendmail";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_SENDMAIL;
- uVar4 = Action->Parameters == (int *)0x0;
- LoadParameters(Script,Action->Parameters,1);
- }
- iVar2 = 4;
- pcVar1 = local_3c;
- pcVar3 = "nop";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar4 = *pcVar1 == *pcVar3;
- pcVar1 = pcVar1 + 1;
- pcVar3 = pcVar3 + 1;
- } while ((bool)uVar4);
- if ((bool)uVar4) {
- Action->Action = ACTION_NOP;
- LoadParameters(Script,Action->Parameters,0);
- }
- return;
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void LoadDataBase(void)
-
-{
- TReadScriptFile *Script_00;
- char cVar1;
- int i;
- int iVar2;
- TMoveUseAction *Action;
- TMoveUseRule *pTVar3;
- TMoveUseCondition *Condition_00;
- int *piVar4;
- int EventType;
- int iVar5;
- TMoveUseCondition *Condition;
- char *pcVar6;
- undefined1 uVar7;
- char *pcVar8;
- char local_501c [4];
- char Ident [30];
- TReadScriptFile Script;
- undefined1 local_101c [4];
- char FileName [4096];
-
- // try { // try from 0807d121 to 0807d151 has its CatchHandler @ 0807d510
- print();
- pcVar8 = DATAPATH;
- Action = (TMoveUseAction *)local_101c;
- sprintf((char *)Action,"%s/moveuse.dat");
- TReadScriptFile::TReadScriptFile((TReadScriptFile *)(Ident + 0x1c));
- // try { // try from 0807d15f to 0807d4d5 has its CatchHandler @ 0807d4f1
- TReadScriptFile::open((TReadScriptFile *)(Ident + 0x1c),(char *)Action,(int)pcVar8);
- piVar4 = &MoveUseDatabases[0].NumberOfRules;
- iVar2 = 4;
- do {
- *piVar4 = 0;
- piVar4 = piVar4 + 0xc;
- iVar2 = iVar2 + -1;
- } while (-1 < iVar2);
-LAB_0807d183:
- TReadScriptFile::nextToken((TReadScriptFile *)(Ident + 0x1c));
- do {
- uVar7 = stack0xffffb004 == 0;
- if ((bool)uVar7) {
- TReadScriptFile::close((TReadScriptFile *)(Ident + 0x1c),(int)Action);
- pcVar8 = "Move/Use-Datenbank mit %d/%d/%d/%d/%d Regeln gelesen.\n";
- print();
- // try { // try from 0807d4df to 0807d4e3 has its CatchHandler @ 0807d510
- TReadScriptFile::~TReadScriptFile((TReadScriptFile *)(Ident + 0x1c),(int)pcVar8);
- return;
- }
- Action = (TMoveUseAction *)TReadScriptFile::getIdentifier((TReadScriptFile *)(Ident + 0x1c))
- ;
- strcpy(local_501c,(char *)Action);
- iVar2 = 6;
- pcVar8 = local_501c;
- pcVar6 = "begin";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar7 = *pcVar8 == *pcVar6;
- pcVar8 = pcVar8 + 1;
- pcVar6 = pcVar6 + 1;
- } while ((bool)uVar7);
- if ((bool)uVar7) {
- TReadScriptFile::readString((TReadScriptFile *)(Ident + 0x1c));
- goto LAB_0807d183;
- }
- iVar2 = 4;
- pcVar8 = local_501c;
- pcVar6 = "end";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar7 = *pcVar8 == *pcVar6;
- pcVar8 = pcVar8 + 1;
- pcVar6 = pcVar6 + 1;
- } while ((bool)uVar7);
- if ((bool)uVar7) goto LAB_0807d183;
- iVar2 = 4;
- pcVar8 = local_501c;
- pcVar6 = "use";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar7 = *pcVar8 == *pcVar6;
- pcVar8 = pcVar8 + 1;
- pcVar6 = pcVar6 + 1;
- } while ((bool)uVar7);
- iVar5 = -1;
- iVar2 = 9;
- if ((bool)uVar7) {
- iVar5 = 0;
- }
- pcVar8 = local_501c;
- pcVar6 = "multiuse";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar7 = *pcVar8 == *pcVar6;
- pcVar8 = pcVar8 + 1;
- pcVar6 = pcVar6 + 1;
- } while ((bool)uVar7);
- iVar2 = 9;
- if ((bool)uVar7) {
- iVar5 = 1;
- }
- pcVar8 = local_501c;
- pcVar6 = "movement";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar7 = *pcVar8 == *pcVar6;
- pcVar8 = pcVar8 + 1;
- pcVar6 = pcVar6 + 1;
- } while ((bool)uVar7);
- iVar2 = 10;
- if ((bool)uVar7) {
- iVar5 = 2;
- }
- pcVar8 = local_501c;
- pcVar6 = "collision";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar7 = *pcVar8 == *pcVar6;
- pcVar8 = pcVar8 + 1;
- pcVar6 = pcVar6 + 1;
- } while ((bool)uVar7);
- iVar2 = 0xb;
- if ((bool)uVar7) {
- iVar5 = 3;
- }
- pcVar8 = local_501c;
- pcVar6 = "separation";
- do {
- if (iVar2 == 0) break;
- iVar2 = iVar2 + -1;
- uVar7 = *pcVar8 == *pcVar6;
- pcVar8 = pcVar8 + 1;
- pcVar6 = pcVar6 + 1;
- } while ((bool)uVar7);
- if ((bool)uVar7) {
- iVar5 = 4;
- }
- if (iVar5 == -1) {
- TReadScriptFile::error((TReadScriptFile *)(Ident + 0x1c),"Unknown event type");
- }
- iVar2 = MoveUseDatabases[iVar5].NumberOfRules + 1;
- MoveUseDatabases[iVar5].NumberOfRules = iVar2;
- pTVar3 = vector<>::operator()(&MoveUseDatabases[iVar5].Rules,iVar2);
- pTVar3->FirstCondition = NumberOfMoveUseConditions + 1;
- TReadScriptFile::readSymbol((TReadScriptFile *)(Ident + 0x1c),',');
- do {
- TReadScriptFile::nextToken((TReadScriptFile *)(Ident + 0x1c));
- NumberOfMoveUseConditions = NumberOfMoveUseConditions + 1;
- Condition_00 = vector<>::operator()(&MoveUseConditions,NumberOfMoveUseConditions);
- Condition_00->Modifier = MODIFIER_NORMAL;
- if (stack0xffffb004 == 6) {
- cVar1 = TReadScriptFile::getSpecial((TReadScriptFile *)(Ident + 0x1c));
- if (cVar1 == '!') {
- Condition_00->Modifier = MODIFIER_INVERT;
- }
- else {
- if ((stack0xffffb004 != 6) ||
- (cVar1 = TReadScriptFile::getSpecial((TReadScriptFile *)(Ident + 0x1c)),
- cVar1 != '~')) goto LAB_0807d301;
- Condition_00->Modifier = MODIFIER_TRUE;
- }
- TReadScriptFile::nextToken((TReadScriptFile *)(Ident + 0x1c));
- }
-LAB_0807d301:
- LoadCondition((TReadScriptFile *)(Ident + 0x1c),Condition_00);
- if (stack0xffffb004 != 6) goto LAB_0807d33a;
- cVar1 = TReadScriptFile::getSpecial((TReadScriptFile *)(Ident + 0x1c));
- } while (cVar1 == ',');
- if ((stack0xffffb004 != 6) ||
- (cVar1 = TReadScriptFile::getSpecial((TReadScriptFile *)(Ident + 0x1c)), cVar1 != 'I')) {
-LAB_0807d33a:
- TReadScriptFile::error((TReadScriptFile *)(Ident + 0x1c),"\'->\' expected");
- }
- pTVar3->LastCondition = NumberOfMoveUseConditions;
- TReadScriptFile::nextToken((TReadScriptFile *)(Ident + 0x1c));
- pTVar3->FirstAction = NumberOfMoveUseActions + 1;
- while( true ) {
- NumberOfMoveUseActions = NumberOfMoveUseActions + 1;
- Action = vector<>::operator()(&MoveUseActions,NumberOfMoveUseActions);
- Script_00 = (TReadScriptFile *)(Ident + 0x1c);
- LoadAction(Script_00,Action);
- if ((stack0xffffb004 != 6) ||
- (cVar1 = TReadScriptFile::getSpecial(Script_00), cVar1 != ',')) break;
- TReadScriptFile::nextToken(Script_00);
- }
- if (stack0xffffb004 == 3) {
- TReadScriptFile::nextToken((TReadScriptFile *)(Ident + 0x1c));
- }
- pTVar3->LastAction = NumberOfMoveUseActions;
- } while( true );
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void InitMoveUse(void)
-
-{
- NumberOfMoveUseConditions = 0;
- NumberOfMoveUseActions = 0;
- // try { // try from 0807d534 to 0807d538 has its CatchHandler @ 0807d545
- LoadDataBase();
- DelayedMails = 0;
- return;
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void ExitMoveUse(void)
-
-{
- TDelayedMail *pTVar1;
- int i;
- int i_00;
- int iVar2;
-
- if ((0 < DelayedMails) && (i_00 = 0, 0 < DelayedMails)) {
- do {
- iVar2 = i_00 + 1;
- pTVar1 = vector<>::operator()(&DelayedMail,i_00);
- error("ExitMoveUse: Paket an %ld wurde nicht zugestellt.\n",pTVar1->CharacterID);
- i_00 = iVar2;
- } while (iVar2 < DelayedMails);
- }
- return;
-}
-
-
-
void __tcf_0(void *param_1)
{
diff --git a/reference/types.hh b/reference/types.hh
index ae021ad..513fb78 100644
--- a/reference/types.hh
+++ b/reference/types.hh
@@ -55,37 +55,12 @@ struct THouse {
int Help;
};
-struct TDelayedMail {
- ulong CharacterID;
- int DepotNumber;
- uchar *Packet;
- int PacketSize;
-};
-
struct THelpDepot {
ulong CharacterID;
struct Object Box;
int DepotNr;
};
-struct TMoveUseAction {
- enum ActionType Action;
- int Parameters[5];
-};
-
-struct TMoveUseRule {
- int FirstCondition;
- int LastCondition;
- int FirstAction;
- int LastAction;
-};
-
-struct TMoveUseCondition {
- enum ModifierType Modifier;
- enum ConditionType Condition;
- int Parameters[5];
-};
-
struct THouseArea {
ushort ID;
int SQMPrice;
@@ -177,11 +152,6 @@ struct TKillStatisticsOrderData {
int *KilledCreatures;
};
-struct TMoveUseDatabase {
- struct vector<TMoveUseRule> Rules;
- int NumberOfRules;
-};
-
struct TReaderThreadOrder {
enum TReaderThreadOrderType OrderType;
int SectorX;
diff --git a/src/crcombat.cc b/src/crcombat.cc
index df8b312..43c3f76 100644
--- a/src/crcombat.cc
+++ b/src/crcombat.cc
@@ -271,7 +271,7 @@ int TCombat::GetDefendDamage(void){
if(RemainingUses > 1){
Change(Shield, REMAININGUSES, RemainingUses - 1);
}else{
- ObjectType WearOutType = ShieldType.getAttribute(WEAROUTTARGET);
+ ObjectType WearOutType = (int)ShieldType.getAttribute(WEAROUTTARGET);
Change(Shield, WearOutType, 0);
// TODO(fusion): Probably just check anyways, to be sure.
if(!Shield.exists() || !WearOutType.getFlag(SHIELD)){
@@ -684,7 +684,7 @@ void TCombat::CloseAttack(TCreature *Target){
if(RemainingUses > 1){
Change(Close, REMAININGUSES, RemainingUses - 1);
}else{
- ObjectType WearOutType = CloseType.getAttribute(WEAROUTTARGET);
+ ObjectType WearOutType = (int)CloseType.getAttribute(WEAROUTTARGET);
Change(Close, WearOutType, 0);
this->CheckCombatValues();
}
diff --git a/src/crmain.cc b/src/crmain.cc
index b786676..c70acb2 100644
--- a/src/crmain.cc
+++ b/src/crmain.cc
@@ -517,7 +517,7 @@ int TCreature::Damage(TCreature *Attacker, int Damage, int DamageType){
if(RemainingUses > 1){
Change(Obj, REMAININGUSES, RemainingUses - 1);
}else{
- ObjectType WearOutType = ObjType.getAttribute(WEAROUTTARGET);
+ ObjectType WearOutType = (int)ObjType.getAttribute(WEAROUTTARGET);
Change(Obj, WearOutType, 0);
}
}catch(RESULT r){
@@ -736,11 +736,11 @@ int TCreature::Damage(TCreature *Attacker, int Damage, int DamageType){
if(Attacker != NULL){
SendMessage(this->Connection, TALK_STATUS_MESSAGE,
"You lose %d hitpoint%s due to an attack by %s.",
- Damage, (Damage == 1 ? "" : "s"), Attacker->Name);
+ Damage, (Damage != 1 ? "s" : ""), Attacker->Name);
}else{
SendMessage(this->Connection, TALK_STATUS_MESSAGE,
"You lose %d hitpoint%s.",
- Damage, (Damage == 1 ? "" : "s"));
+ Damage, (Damage != 1 ? "s" : ""));
}
SendPlayerData(this->Connection);
}
@@ -1052,12 +1052,12 @@ void ProcessCreatures(void){
continue;
}
- // TODO(fusion): It is weird that we do check the connection all the time
- // and most of the time it is redundant because functions will check if
- // it's NULL before attempting anything.
-
- int FoodInterval = Creature->Skills[SKILL_FED]->Get();
- if(FoodInterval > 0 && (RoundNr % FoodInterval) == 0 && !Creature->IsDead
+ // TODO(fusion): I'm almost sure this is processing ITEM regen rather
+ // FOOD regen. It wouldn't make a lot of sense to have this plus what
+ // happens in `TSkillFed::Event` if we didn't consider things like the
+ // life ring, etc...
+ int RegenInterval = Creature->Skills[SKILL_FED]->Get();
+ if(RegenInterval > 0 && (RoundNr % RegenInterval) == 0 && !Creature->IsDead
&& !IsProtectionZone(Creature->posx, Creature->posy, Creature->posz)){
Creature->Skills[SKILL_HITPOINTS]->Change(1);
Creature->Skills[SKILL_MANA]->Change(4);
@@ -1701,13 +1701,19 @@ void LoadRaces(void){
throw "Cannot load races";
}
- char FilePath[4096];
+ char FileName[4096];
while(dirent *DirEntry = readdir(MonsterDir)){
+ if(DirEntry->d_type != DT_REG){
+ continue;
+ }
+
const char *FileExt = findLast(DirEntry->d_name, '.');
- if(FileExt != NULL && strcmp(FileExt, ".mon") == 0){
- snprintf(FilePath, sizeof(FilePath), "%s/%s", MONSTERPATH, DirEntry->d_name);
- LoadRace(FilePath);
+ if(FileExt == NULL || strcmp(FileExt, ".mon") != 0){
+ continue;
}
+
+ snprintf(FileName, sizeof(FileName), "%s/%s", MONSTERPATH, DirEntry->d_name);
+ LoadRace(FileName);
}
closedir(MonsterDir);
@@ -1929,44 +1935,49 @@ void LoadMonsterRaids(void){
char FileName[4096];
while(dirent *DirEntry = readdir(MonsterDir)){
+ if(DirEntry->d_type != DT_REG){
+ continue;
+ }
+
const char *FileExt = findLast(DirEntry->d_name, '.');
- if(FileExt != NULL && strcmp(FileExt, ".evt") == 0){
- snprintf(FileName, sizeof(FileName), "%s/%s", MONSTERPATH, DirEntry->d_name);
-
- bool BigRaid;
- int Date, Interval, Duration;
- LoadMonsterRaid(FileName, -1, &BigRaid, &Date, &Interval, &Duration);
- print(1, "Raid %s: Date %d, Interval %d, Duration %d\n",
- FileName, Date, Interval, Duration);
-
- if(Date > 0){
- if(Now <= Date && Date <= (Now + SecondsToReboot)){
- int Start = RoundNr + (Date - Now);
- LoadMonsterRaid(FileName, Start, NULL, NULL, NULL, NULL);
- if(BigRaid){
- BigRaidName[0] = 0;
- BigRaidDuration = 0;
- BigRaidTieBreaker = 100;
- }
+ if(FileExt == NULL || strcmp(FileExt, ".evt") != 0){
+ continue;
+ }
+
+ bool BigRaid;
+ int Date, Interval, Duration;
+ snprintf(FileName, sizeof(FileName), "%s/%s", MONSTERPATH, DirEntry->d_name);
+ LoadMonsterRaid(FileName, -1, &BigRaid, &Date, &Interval, &Duration);
+ print(1, "Raid %s: Date %d, Interval %d, Duration %d\n",
+ FileName, Date, Interval, Duration);
+
+ if(Date > 0){
+ if(Now <= Date && Date <= (Now + SecondsToReboot)){
+ int Start = RoundNr + (Date - Now);
+ LoadMonsterRaid(FileName, Start, NULL, NULL, NULL, NULL);
+ if(BigRaid){
+ BigRaidName[0] = 0;
+ BigRaidDuration = 0;
+ BigRaidTieBreaker = 100;
}
- }else if(Duration <= SecondsToReboot){
- // NOTE(fusion): `Interval` specifies an average raid interval
- // in seconds. With this function being called at startup, usually
- // after a reboot, we can expect `SecondsToReboot` to be close to
- // a day very regularly. Meaning we can approximate the condition
- // below to `random(1, AverageIntervalDays) == 1` which hopefully
- // makes more sense.
- if(random(0, Interval - 1) < SecondsToReboot){
- if(!BigRaid){
- int Start = RoundNr + random(0, SecondsToReboot - Duration);
- LoadMonsterRaid(FileName, Start, NULL, NULL, NULL, NULL);
- }else{
- int TieBreaker = random(0, 99);
- if(TieBreaker > BigRaidTieBreaker){
- strcpy(BigRaidName, FileName);
- BigRaidDuration = Duration;
- BigRaidTieBreaker = TieBreaker;
- }
+ }
+ }else if(Duration <= SecondsToReboot){
+ // NOTE(fusion): `Interval` specifies an average raid interval
+ // in seconds. With this function being called at startup, usually
+ // after a reboot, we can expect `SecondsToReboot` to be close to
+ // a day very regularly. Meaning we can approximate the condition
+ // below to `random(1, AverageIntervalDays) == 1` which hopefully
+ // makes more sense.
+ if(random(0, Interval - 1) < SecondsToReboot){
+ if(!BigRaid){
+ int Start = RoundNr + random(0, SecondsToReboot - Duration);
+ LoadMonsterRaid(FileName, Start, NULL, NULL, NULL, NULL);
+ }else{
+ int TieBreaker = random(0, 99);
+ if(TieBreaker > BigRaidTieBreaker){
+ strcpy(BigRaidName, FileName);
+ BigRaidDuration = Duration;
+ BigRaidTieBreaker = TieBreaker;
}
}
}
diff --git a/src/crnonpl.cc b/src/crnonpl.cc
index 3d43012..b05a5e5 100644
--- a/src/crnonpl.cc
+++ b/src/crnonpl.cc
@@ -1747,7 +1747,7 @@ void TNPC::IdleStimulus(void){
return;
}
- bool FoundDest = false;
+ bool DestFound = false;
int DestX, DestY, DestZ;
for(int i = 0; i < 10; i += 1){
DestX = this->posx;
@@ -1761,12 +1761,12 @@ void TNPC::IdleStimulus(void){
}
if(this->MovePossible(DestX, DestY, DestZ, true, false)){
- FoundDest = true;
+ DestFound = true;
break;
}
}
- if(FoundDest){
+ if(DestFound){
try{
this->ToDoGo(DestX, DestY, DestZ, true, INT_MAX);
this->ToDoWait(2000);
diff --git a/src/crplayer.cc b/src/crplayer.cc
index 2660c04..9978527 100644
--- a/src/crplayer.cc
+++ b/src/crplayer.cc
@@ -1,6 +1,7 @@
#include "cr.hh"
#include "config.hh"
#include "info.hh"
+#include "moveuse.hh"
#include "operate.hh"
#include "query.hh"
#include "threads.hh"
diff --git a/src/enums.hh b/src/enums.hh
index 6d6baf0..9dad622 100644
--- a/src/enums.hh
+++ b/src/enums.hh
@@ -126,37 +126,6 @@ enum Color: int {
COLOR_WHITE = 215,
};
-// TODO(fusion): These are used with `TMoveUseCondition`. Probably add a
-// `MOVEUSE` prefix not to mix with `TBehaviourCondition`?
-enum ConditionType: int {
- CONDITION_ISPOSITION = 0,
- CONDITION_ISTYPE = 1,
- CONDITION_ISCREATURE = 2,
- CONDITION_ISPLAYER = 3,
- CONDITION_HASFLAG = 4,
- CONDITION_HASTYPEATTRIBUTE = 5,
- CONDITION_HASINSTANCEATTRIBUTE = 6,
- CONDITION_HASTEXT = 7,
- CONDITION_ISPEACEFUL = 8,
- CONDITION_MAYLOGOUT = 9,
- CONDITION_HASPROFESSION = 10,
- CONDITION_HASLEVEL = 11,
- CONDITION_HASRIGHT = 12,
- CONDITION_HASQUESTVALUE = 13,
- CONDITION_TESTSKILL = 14,
- CONDITION_COUNTOBJECTS = 15,
- CONDITION_COUNTOBJECTSONMAP = 16,
- CONDITION_ISOBJECTTHERE = 17,
- CONDITION_ISCREATURETHERE = 18,
- CONDITION_ISPLAYERTHERE = 19,
- CONDITION_ISOBJECTININVENTORY = 20,
- CONDITION_ISPROTECTIONZONE = 21,
- CONDITION_ISHOUSE = 22,
- CONDITION_ISHOUSEOWNER = 23,
- CONDITION_ISDRESSED = 24,
- CONDITION_RANDOM = 25,
-};
-
enum CONNECTIONSTATE: int {
CONNECTION_FREE = 0,
CONNECTION_ASSIGNED = 1,
diff --git a/src/info.cc b/src/info.cc
index 8f520cf..13e777f 100644
--- a/src/info.cc
+++ b/src/info.cc
@@ -179,6 +179,9 @@ uint32 GetObjectCreatureID(Object Obj){
return CreatureID;
}
+// TODO(fusion): I'm not sure about this one. Objects inside containers would
+// also return the body position of the container even if it isn't activelly
+// equipped.
int GetObjectBodyPosition(Object Obj){
if(!Obj.exists()){
error("GetObjectBodyPosition: Übergebenes Objekt existiert nicht.\n");
diff --git a/src/magic.cc b/src/magic.cc
index 19a9dc8..e268a7d 100644
--- a/src/magic.cc
+++ b/src/magic.cc
@@ -2561,7 +2561,7 @@ void ChangeData(TCreature *Actor, const char *Param){
}
if(Attribute != -1){
- Change(Obj, Attribute, Value);
+ Change(Obj, (INSTANCEATTRIBUTE)Attribute, Value);
GraphicalEffect(Actor->posx, Actor->posy, Actor->posz, EFFECT_MAGIC_GREEN);
}else{
SendMessage(Actor->Connection, TALK_FAILURE_MESSAGE,
diff --git a/src/main.cc b/src/main.cc
index f4df04d..4b52ab2 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -4,6 +4,7 @@
#include "info.hh"
#include "map.hh"
#include "magic.hh"
+#include "moveuse.hh"
#include "objects.hh"
#include "operate.hh"
#include "query.hh"
@@ -227,7 +228,7 @@ static void InitAll(void){
InitObjects();
InitMap();
InitInfo();
- //InitMoveUse();
+ InitMoveUse();
InitMagic();
InitCr();
//InitHouses();
@@ -246,7 +247,7 @@ static void ExitAll(void){
ExitTime();
ExitCr();
ExitMagic();
- //ExitMoveUse();
+ ExitMoveUse();
ExitInfo();
//ExitHouses();
ExitMap(SaveMapOn);
diff --git a/src/map.cc b/src/map.cc
index 9eb29cd..64886bf 100644
--- a/src/map.cc
+++ b/src/map.cc
@@ -760,19 +760,23 @@ void DeleteSwappedSectors(void){
return;
}
- char FilePath[4096];
+ char FileName[4096];
while(dirent *DirEntry = readdir(SwapDir)){
- if(DirEntry->d_type == DT_REG){
- // NOTE(fusion): `DirEntry->d_name` will only contain the filename
- // so we need to assemble the actual file path (relative in this
- // case) to properly unlink it. Windows has the same behavior with
- // its `FindFirstFile`/`FindNextFile` API.
- const char *FileExt = findLast(DirEntry->d_name, '.');
- if(FileExt != NULL && strcmp(FileExt, ".swp") == 0){
- snprintf(FilePath, sizeof(FilePath), "%s/%s", SAVEPATH, DirEntry->d_name);
- unlink(FilePath);
- }
+ if(DirEntry->d_type != DT_REG){
+ continue;
}
+
+ // NOTE(fusion): `DirEntry->d_name` will only contain the filename
+ // so we need to assemble the actual file path (relative in this
+ // case) to properly unlink it. Windows has the same behavior with
+ // its `FindFirstFile`/`FindNextFile` API.
+ const char *FileExt = findLast(DirEntry->d_name, '.');
+ if(FileExt == NULL || strcmp(FileExt, ".swp") != 0){
+ continue;
+ }
+
+ snprintf(FileName, sizeof(FileName), "%s/%s", SAVEPATH, DirEntry->d_name);
+ unlink(FileName);
}
closedir(SwapDir);
@@ -1020,19 +1024,23 @@ void LoadMap(void){
ObjectCounter = 0;
int SectorCounter = 0;
- char FilePath[4096];
+ char FileName[4096];
while(dirent *DirEntry = readdir(MapDir)){
- if(DirEntry->d_type == DT_REG){
- // NOTE(fusion): See note in `DeleteSwappedSectors`.
- const char *FileExt = findLast(DirEntry->d_name, '.');
- if(FileExt != NULL && strcmp(FileExt, ".sec") == 0){
- int SectorX, SectorY, SectorZ;
- if(sscanf(DirEntry->d_name, "%d-%d-%d.sec", &SectorX, &SectorY, &SectorZ) == 3){
- snprintf(FilePath, sizeof(FilePath), "%s/%s", SAVEPATH, DirEntry->d_name);
- LoadSector(FilePath, SectorX, SectorY, SectorZ);
- SectorCounter += 1;
- }
- }
+ if(DirEntry->d_type != DT_REG){
+ continue;
+ }
+
+ // NOTE(fusion): See note in `DeleteSwappedSectors`.
+ const char *FileExt = findLast(DirEntry->d_name, '.');
+ if(FileExt == NULL || strcmp(FileExt, ".sec") != 0){
+ continue;
+ }
+
+ int SectorX, SectorY, SectorZ;
+ if(sscanf(DirEntry->d_name, "%d-%d-%d.sec", &SectorX, &SectorY, &SectorZ) == 3){
+ snprintf(FileName, sizeof(FileName), "%s/%s", SAVEPATH, DirEntry->d_name);
+ LoadSector(FileName, SectorX, SectorY, SectorZ);
+ SectorCounter += 1;
}
}
diff --git a/src/moveuse.cc b/src/moveuse.cc
index f11fffa..9cdcd95 100644
--- a/src/moveuse.cc
+++ b/src/moveuse.cc
@@ -1,27 +1,424 @@
+#include "moveuse.hh"
+#include "config.hh"
+#include "info.hh"
#include "operate.hh"
-// NOTE(fusion): Oh no.
+#include "stubs.hh"
+
+static vector<TMoveUseCondition> MoveUseConditions(1, 1000, 1000);
+static int NumberOfMoveUseConditions;
+
+static vector<TMoveUseAction> MoveUseActions(1, 1000, 1000);
+static int NumberOfMoveUseActions;
+
+static TMoveUseDatabase MoveUseDatabases[5];
+
+static vector<TDelayedMail> DelayedMail(0, 10, 10);
+static int DelayedMails;
+
+// Coordinate Packing
+// =============================================================================
+int PackAbsoluteCoordinate(int x, int y, int z){
+ // DOMAIN: [24576, 40959] x [24576, 40959] x [0, 15]
+ int Packed = (((x - 24576) & 0x00003FFF) << 18)
+ | (((y - 24576) & 0x00003FFF) << 4)
+ | (z & 0x0000000F);
+ return Packed;
+}
+
+void UnpackAbsoluteCoordinate(int Packed, int *x, int *y, int *z){
+ *x = ((Packed >> 18) & 0x00003FFF) + 24576;
+ *y = ((Packed >> 4) & 0x00003FFF) + 24576;
+ *z = ((Packed >> 0) & 0x0000000F);
+}
+
+int PackRelativeCoordinate(int x, int y, int z){
+ // DOMAIN: [-8192, 8191] x [-8192, 8191] x [-8, 7]
+ int Packed = (((x + 8192) & 0x00003FFF) << 18)
+ | (((y + 8192) & 0x00003FFF) << 4)
+ | ((z + 8) & 0x0000000F);
+ return Packed;
+}
+
+void UnpackRelativeCoordinate(int Packed, int *x, int *y, int *z){
+ *x = ((Packed >> 18) & 0x00003FFF) - 8192;
+ *y = ((Packed >> 4) & 0x00003FFF) - 8192;
+ *z = ((Packed >> 0) & 0x0000000F) - 8;
+}
+
+// Event Execution
+// =============================================================================
+Object GetEventObject(int Nr, Object User, Object Obj1, Object Obj2, Object Temp){
+ Object Obj = NONE;
+ switch(Nr){
+ case 0: Obj = NONE; break;
+ case 1: Obj = Obj1; break;
+ case 2: Obj = Obj2; break;
+ case 3: Obj = User; break;
+ case 4: Obj = Temp; break;
+ default:{
+ error("GetEventObject: Unbekannte Nummer %d.\n", Nr);
+ break;
+ }
+ }
+ return Obj;
+}
+
+bool Compare(int Value1, int Operator, int Value2){
+ bool Result = false;
+ switch(Operator){
+ case '<': Result = (Value1 < Value2); break;
+ case '>': Result = (Value1 > Value2); break;
+ case '=': Result = (Value1 == Value2); break;
+ case 'N': Result = (Value1 != Value2); break;
+ case 'L': Result = (Value1 <= Value2); break;
+ case 'G': Result = (Value1 >= Value2); break;
+ default:{
+ error("Compare: Ungültiger Operator %d.\n", Operator);
+ break;
+ }
+ }
+ return Result;
+}
+
+bool CheckCondition(MoveUseEventType EventType, TMoveUseCondition *Condition,
+ Object User, Object Obj1, Object Obj2, Object *Temp){
+ bool Result = false;
+ switch(Condition->Condition){
+ case MOVEUSE_CONDITION_ISPOSITION:{
+ int ObjX, ObjY, ObjZ, CoordX, CoordY, CoordZ;
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ UnpackAbsoluteCoordinate(Condition->Parameters[1], &CoordX, &CoordY, &CoordZ);
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+ Result = (ObjX == CoordX && ObjY == CoordY && ObjZ == CoordZ);
+ break;
+ }
+
+ case MOVEUSE_CONDITION_ISTYPE:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ Result = (Obj.getObjectType().TypeID == Condition->Parameters[1]);
+ break;
+ }
+
+ case MOVEUSE_CONDITION_ISCREATURE:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ Result = Obj.getObjectType().isCreatureContainer();
+ break;
+ }
+
+ case MOVEUSE_CONDITION_ISPLAYER:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ if(Obj.getObjectType().isCreatureContainer()){
+ TCreature *Creature = GetCreature(Obj);
+ Result = (Creature && Creature->Type == PLAYER);
+ }
+ break;
+ }
+
+ case MOVEUSE_CONDITION_HASFLAG:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ Result = Obj.getObjectType().getFlag((FLAG)Condition->Parameters[1]);
+ break;
+ }
+
+ case MOVEUSE_CONDITION_HASTYPEATTRIBUTE:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ int Attribute = (int)Obj.getObjectType().getAttribute((TYPEATTRIBUTE)Condition->Parameters[1]);
+ int Operator = Condition->Parameters[2];
+ int Value = Condition->Parameters[3];
+ Result = Compare(Attribute, Operator, Value);
+ break;
+ }
+
+ case MOVEUSE_CONDITION_HASINSTANCEATTRIBUTE:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ int Attribute = (int)Obj.getAttribute((INSTANCEATTRIBUTE)Condition->Parameters[1]);
+ int Operator = Condition->Parameters[2];
+ int Value = Condition->Parameters[3];
+ Result = Compare(Attribute, Operator, Value);
+ break;
+ }
+
+ case MOVEUSE_CONDITION_HASTEXT:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ const char *Attribute = GetDynamicString(Obj.getAttribute(TEXTSTRING));
+ const char *Text = GetDynamicString(Condition->Parameters[1]);
+ Result = (strcmp(Attribute, Text) == 0);
+ break;
+ }
+
+ case MOVEUSE_CONDITION_ISPEACEFUL:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ if(Obj.getObjectType().isCreatureContainer()){
+ TCreature *Creature = GetCreature(Obj);
+ Result = (Creature && Creature->IsPeaceful());
+ }
+ break;
+ }
+
+ case MOVEUSE_CONDITION_MAYLOGOUT:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ if(Obj.getObjectType().isCreatureContainer()){
+ TCreature *Creature = GetCreature(Obj);
+ Result = (Creature != NULL && Creature->Type == PLAYER
+ && Creature->LogoutPossible() == 0);
+ }
+ break;
+ }
+
+ case MOVEUSE_CONDITION_HASPROFESSION:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ int Profession = Condition->Parameters[1];
+ if(Obj.getObjectType().isCreatureContainer()){
+ TCreature *Creature = GetCreature(Obj);
+ Result = (Creature != NULL && Creature->Type == PLAYER
+ && ((TPlayer*)Creature)->GetEffectiveProfession() == Profession);
+ }
+ break;
+ }
+
+ case MOVEUSE_CONDITION_HASLEVEL:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ int Operator = Condition->Parameters[1];
+ int Value = Condition->Parameters[2];
+ if(Obj.getObjectType().isCreatureContainer()){
+ TCreature *Creature = GetCreature(Obj);
+ if(Creature != NULL){
+ int Level = Creature->Skills[SKILL_LEVEL]->Get();
+ Result = Compare(Level, Operator, Value);
+ }
+ }
+ break;
+ }
+
+ case MOVEUSE_CONDITION_HASRIGHT:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ RIGHT Right = (RIGHT)Condition->Parameters[1];
+ if(Obj.getObjectType().isCreatureContainer()){
+ TCreature *Creature = GetCreature(Obj);
+ Result = (Creature != NULL && Creature->Type == PLAYER
+ && CheckRight(Creature->ID, Right));
+ }
+ break;
+ }
+
+ case MOVEUSE_CONDITION_HASQUESTVALUE:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ int QuestNr = Condition->Parameters[1];
+ int Operator = Condition->Parameters[2];
+ int Value = Condition->Parameters[3];
+ if(Obj.getObjectType().isCreatureContainer()){
+ TCreature *Creature = GetCreature(Obj);
+ if(Creature != NULL && Creature->Type == PLAYER){
+ int QuestValue = ((TPlayer*)Creature)->GetQuestValue(QuestNr);
+ Result = Compare(QuestValue, Operator, Value);
+ }
+ }
+ break;
+ }
+
+ case MOVEUSE_CONDITION_TESTSKILL:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ int SkillNr = Condition->Parameters[1];
+ int Difficulty = Condition->Parameters[2];
+ int Probability = Condition->Parameters[3];
+ if(Obj.getObjectType().isCreatureContainer()){
+ TCreature *Creature = GetCreature(Obj);
+ if(Creature != NULL){
+ if(SkillNr >= 0 && SkillNr < NARRAY(Creature->Skills)){
+ Result = Creature->Skills[SkillNr]->Probe(Difficulty, Probability, true);
+ }else{
+ error("CheckCondition (TestSkill): Ungültige Skillnummer %d.\n", SkillNr);
+ }
+ }
+ }
+ break;
+ }
+
+ // TODO(fusion): This also counts objects at the object's map location?
+ case MOVEUSE_CONDITION_COUNTOBJECTS:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ int Operator = Condition->Parameters[1];
+ int Value = Condition->Parameters[2];
+ Object MapCon = GetMapContainer(Obj);
+ int ObjCount = CountObjectsInContainer(MapCon);
+ Result = Compare(ObjCount, Operator, Value);
+ break;
+ }
+
+ case MOVEUSE_CONDITION_COUNTOBJECTSONMAP:{
+ int CoordX, CoordY, CoordZ;
+ UnpackAbsoluteCoordinate(Condition->Parameters[0], &CoordX, &CoordY, &CoordZ);
+ int Operator = Condition->Parameters[1];
+ int Value = Condition->Parameters[2];
+ Object MapCon = GetMapContainer(CoordX, CoordY, CoordZ);
+ int ObjCount = CountObjectsInContainer(MapCon);
+ Result = Compare(ObjCount, Operator, Value);
+ break;
+ }
+
+ case MOVEUSE_CONDITION_ISOBJECTTHERE:{
+ int CoordX, CoordY, CoordZ;
+ UnpackAbsoluteCoordinate(Condition->Parameters[0], &CoordX, &CoordY, &CoordZ);
+ ObjectType Type = Condition->Parameters[1];
+ *Temp = GetFirstSpecObject(CoordX, CoordY, CoordZ, Type);
+ Result = (*Temp != NONE);
+ break;
+ }
+
+ case MOVEUSE_CONDITION_ISCREATURETHERE:{
+ int CoordX, CoordY, CoordZ;
+ UnpackAbsoluteCoordinate(Condition->Parameters[0], &CoordX, &CoordY, &CoordZ);
+ ObjectType Type = TYPEID_CREATURE_CONTAINER;
+ *Temp = GetFirstSpecObject(CoordX, CoordY, CoordZ, Type);
+ Result = (*Temp != NONE);
+ break;
+ }
+
+ // TODO(fusion): I feel this one should iterate the field because there
+ // could be more than one creature.
+ case MOVEUSE_CONDITION_ISPLAYERTHERE:{
+ int CoordX, CoordY, CoordZ;
+ UnpackAbsoluteCoordinate(Condition->Parameters[0], &CoordX, &CoordY, &CoordZ);
+ ObjectType Type = TYPEID_CREATURE_CONTAINER;
+ *Temp = GetFirstSpecObject(CoordX, CoordY, CoordZ, Type);
+ if(*Temp != NONE){
+ TCreature *Creature = GetCreature(*Temp);
+ Result = Creature && Creature->Type == PLAYER;
+ }
+ break;
+ }
+
+ case MOVEUSE_CONDITION_ISOBJECTININVENTORY:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ ObjectType Type = Condition->Parameters[1];
+ int Count = Condition->Parameters[2];
+ if(Obj.getObjectType().isCreatureContainer()){
+ *Temp = GetInventoryObject(Obj.getCreatureID(), Type, Count);
+ Result = (*Temp != NONE);
+ }
+ break;
+ }
+
+ case MOVEUSE_CONDITION_ISPROTECTIONZONE:{
+ int ObjX, ObjY, ObjZ;
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+ Result = IsProtectionZone(ObjX, ObjY, ObjZ);
+ break;
+ }
+
+ case MOVEUSE_CONDITION_ISHOUSE:{
+ int ObjX, ObjY, ObjZ;
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+ Result = IsHouse(ObjX, ObjY, ObjZ);
+ break;
+ }
+
+ case MOVEUSE_CONDITION_ISHOUSEOWNER:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ Object Cr = GetEventObject(Condition->Parameters[1], User, Obj1, Obj2, *Temp);
+ if(Cr.getObjectType().isCreatureContainer()){
+ TCreature *Creature = GetCreature(Cr);
+ if(Creature != NULL && Creature->Type == PLAYER){
+ int ObjX, ObjY, ObjZ;
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+ uint16 HouseID = GetHouseID(ObjX, ObjY, ObjZ);
+ Result = IsOwner(HouseID, (TPlayer*)Creature);
+ }
+ }
+ break;
+ }
+
+ case MOVEUSE_CONDITION_ISDRESSED:{
+ Object Obj = GetEventObject(Condition->Parameters[0], User, Obj1, Obj2, *Temp);
+ ObjectType ObjType = Obj.getObjectType();
+ if(ObjType.getFlag(CLOTHES)){
+ int CurPosition = GetObjectBodyPosition(Obj);
+ int ObjPosition = (int)ObjType.getAttribute(BODYPOSITION);
+ Result = (CurPosition == ObjPosition);
+ }else{
+ error("CheckCondition (IsDressed): Objekt ist kein Kleidungsstück.\n");
+ }
+ break;
+ }
+
+ case MOVEUSE_CONDITION_RANDOM:{
+ Result = (random(1, 100) <= Condition->Parameters[0]);
+ break;
+ }
+
+ default:{
+ error("CheckCondition: Unbekannte Bedingung %d.\n", Condition->Condition);
+ return false;
+ }
+ }
+
+ if(Condition->Modifier == MOVEUSE_MODIFIER_NORMAL){
+ // no-op
+ }else if(Condition->Modifier == MOVEUSE_MODIFIER_INVERT){
+ Result = !Result;
+ }else if(Condition->Modifier == MOVEUSE_MODIFIER_TRUE){
+ Result = true;
+ }else{
+ // TODO(fusion): Error?
+ Result = false;
+ }
+
+ return Result;
+}
+
+Object CreateObject(Object Con, ObjectType Type, uint32 Value){
+ for(int Attempt = 0; true; Attempt += 1){
+ try{
+ Object Obj = NONE;
+ ObjectType ConType = Con.getObjectType();
+ if(ConType.isBodyContainer()){
+ uint32 CreatureID = GetObjectCreatureID(Con);
+ Obj = CreateAtCreature(CreatureID, Type, Value);
+ }else{
+ Obj = Create(Con, Type, Value);
+ }
+ return Obj;
+ }catch(RESULT r){
+ if(Attempt == 0 && (r == NOTTAKABLE || r == TOOHEAVY || r == CONTAINERFULL)){
+ // NOTE(fusion): Try to create object on the map, ONCE.
+ Con = GetMapContainer(Con);
+ }else{
+ int ConX, ConY, ConZ;
+ GetObjectCoordinates(Con, &ConX, &ConY, &ConZ);
+ error("moveuse::CreateObject: Exception %d, Objekt %d, Position [%d,%d,%d].\n",
+ r, Type.TypeID, ConX, ConY, ConZ);
+ return NONE;
+ }
+ }
+ }
+}
+
void ChangeObject(Object Obj, ObjectType NewType, uint32 Value){
if(!Obj.exists()){
error("ChangeObject: Übergebenes Objekt existiert nicht (1, NewType=%d).\n", NewType.TypeID);
return;
}
- Object Con = Obj.getContainer();
- while(true){
+ // NOTE(fusion): `Change` requires CUMULATIVE objects to have AMOUNT
+ // equal to ONE or it fails with `SPLITOBJECT`. This means might need
+ // to split the object and the split destination may change depending
+ // on how things go.
+ Object SplitDest = Obj.getContainer();
+ for(int Attempt = 0; true; Attempt += 1){
if(!Obj.exists()){
error("ChangeObject: Übergebenes Objekt existiert nicht (2, NewType=%d).\n", NewType.TypeID);
return;
}
try{
- // NOTE(fusion): `Change` requires CUMULATIVE objects to have AMOUNT
- // equal to one or it fails with `SPLITOBJECT`.
ObjectType ObjType = Obj.getObjectType();
if(ObjType.getFlag(CUMULATIVE)){
uint32 Amount = Obj.getAttribute(AMOUNT);
if(Amount > 1){
- Move(0, Obj, Con, Amount - 1, true, NONE);
+ Move(0, Obj, SplitDest, Amount - 1, true, NONE);
}
}
@@ -33,20 +430,25 @@ void ChangeObject(Object Obj, ObjectType NewType, uint32 Value){
return;
}
+ // TODO(fusion): I feel a couple of attempts should be enough?
+ if(Attempt >= 2){
+ throw;
+ }
+
if(r == CONTAINERFULL){
- Con = GetMapContainer(Obj);
+ // NOTE(fusion): Set `SplitDest` to map.
+ SplitDest = GetMapContainer(Obj);
}else if(r == TOOHEAVY){
+ // NOTE(fusion): Move object to map, keep `SplitDest`.
Object MapCon = GetMapContainer(Obj);
Move(0, Obj, MapCon, -1, true, NONE);
- }else if(r == NOROOM){
- if(!Obj.getObjectType().getFlag(CUMULATIVE)
- || Obj.getAttribute(AMOUNT) <= 1){
- throw;
- }
-
- // TODO(fusion): Why do we use `Con` with `GetMapContainer` here?
+ }else if(r == NOROOM
+ && Obj.getObjectType().getFlag(CUMULATIVE)
+ && Obj.getAttribute(AMOUNT) > 1){
+ // NOTE(fusion): Split to map directly. Similar to setting `SplitDest`
+ // to map, although failing here will throw us out of the function.
uint32 Amount = Obj.getAttribute(AMOUNT);
- Object MapCon = GetMapContainer(Con);
+ Object MapCon = GetMapContainer(SplitDest);
Move(0, Obj, MapCon, Amount - 1, true, NONE);
}else{
throw;
@@ -54,3 +456,2610 @@ void ChangeObject(Object Obj, ObjectType NewType, uint32 Value){
}
}
}
+
+void MoveOneObject(Object Obj, Object Con){
+ if(!Obj.exists()){
+ error("MoveOneObject: Übergebenes Objekt existiert nicht.\n");
+ return;
+ }
+
+ if(!Con.exists()){
+ error("MoveOneObject: Übergebener Container existiert nicht.\n");
+ return;
+ }
+
+ ObjectType ConType = Con.getObjectType();
+ if(!ConType.getFlag(CONTAINER)){
+ error("MoveOneObject: \"Con\" ist kein Container.\n");
+ return;
+ }
+
+ ObjectType ObjType = Obj.getObjectType();
+ if(ObjType.isCreatureContainer() && !ConType.isMapContainer()){
+ error("MoveOneObject: \"Con\" ist kein MapContainer.\n");
+ return;
+ }
+
+ try{
+ if(ObjType.getFlag(LIQUIDPOOL) || ObjType.getFlag(MAGICFIELD)){
+ Delete(Obj, -1);
+ }else{
+ Move(0, Obj, Con, -1, true, NONE);
+ }
+ }catch(RESULT r){
+ if(r != DESTROYED){
+ int ConX, ConY, ConZ;
+ GetObjectCoordinates(Con, &ConX, &ConY, &ConZ);
+ error("MoveOneObject: Exception %d; Koordinate [%d,%d,%d].\n",
+ r, ConX, ConY, ConZ);
+ }
+
+ if(r == CONTAINERFULL){
+ Delete(Obj, -1);
+ }
+ }
+}
+
+void MoveAllObjects(Object Obj, Object Dest, Object Exclude, bool MoveUnmovable){
+ if(Obj == NONE){
+ return;
+ }
+
+ if(!Dest.getObjectType().isMapContainer()){
+ error("MoveAllObjects: \"Dest\" ist kein Mapcontainer.\n");
+ return;
+ }
+
+ // TODO(fusion): We probably use recursion to move objects in reverse order?
+ MoveAllObjects(Obj.getNextObject(), Dest, Exclude, MoveUnmovable);
+
+ if(Obj != Exclude){
+ ObjectType ObjType = Obj.getObjectType();
+ try{
+ if(ObjType.getFlag(LIQUIDPOOL) || ObjType.getFlag(MAGICFIELD)){
+ Delete(Obj, -1);
+ }else if(MoveUnmovable || !ObjType.getFlag(UNMOVE)){
+ Move(0, Obj, Dest, -1, true, NONE);
+ }
+ }catch(RESULT r){
+ if(r != DESTROYED){
+ int DestX, DestY, DestZ;
+ GetObjectCoordinates(Dest, &DestX, &DestY, &DestZ);
+ error("MoveAllObjects: Exception %d; Objekt %d, Zielkoordinate [%d,%d,%d].\n",
+ r, ObjType.TypeID, DestX, DestY, DestZ);
+ }
+ }
+ }
+}
+
+void DeleteAllObjects(Object Obj, Object Exclude, bool DeleteUnmovable){
+ if(Obj == NONE){
+ return;
+ }
+
+ // TODO(fusion): Same as `MoveAllObjects`.
+ DeleteAllObjects(Obj.getNextObject(), Exclude, DeleteUnmovable);
+
+ if(Obj != Exclude){
+ ObjectType ObjType = Obj.getObjectType();
+ if(ObjType.isCreatureContainer()){
+ int ObjX, ObjY, ObjZ;
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+ error("DeleteAllObjects: An Position [%d,%d,%d] soll eine Kreatur gelöscht werden.\n",
+ ObjX, ObjY, ObjZ);
+ return;
+ }
+
+ if(!DeleteUnmovable && ObjType.getFlag(UNMOVE)
+ && !ObjType.getFlag(LIQUIDPOOL)
+ && !ObjType.getFlag(MAGICFIELD)){
+ return;
+ }
+
+ try{
+ Delete(Obj, -1);
+ }catch(RESULT r){
+ error("DeleteAllObjects: Exception %d.\n", r);
+ }
+ }
+}
+
+void ClearField(Object Obj, Object Exclude){
+ // IMPORTANT(fusion): This function seems to be used when items transform
+ // into `UNPASS` versions of themselves, like doors, which is why we skip
+ // the actual object when calling `MoveAllObjects` at the end.
+ // The order we scan available fields may also be important which is why
+ // I've kept the same ordering used by the original function.
+
+ if(!Obj.exists()){
+ error("ClearField: Objekt existiert nicht.\n");
+ return;
+ }
+
+ int ObjX, ObjY, ObjZ;
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+
+ bool DestFound = false;
+ int DestX, DestY, DestZ;
+ int OffsetX[4] = { 1, 0, -1, 0};
+ int OffsetY[4] = { 0, 1, 0, -1};
+
+ // NOTE(fusion): First look for a field that's not blocked.
+ for(int i = 0; i < 4; i += 1){
+ DestX = ObjX + OffsetX[i];
+ DestY = ObjY + OffsetY[i];
+ DestZ = ObjZ;
+ if(CoordinateFlag(DestX, DestY, DestZ, BANK)
+ && !CoordinateFlag(DestX, DestY, DestZ, UNPASS)){
+ DestFound = true;
+ break;
+ }
+ }
+
+ // NOTE(fusion): Then look for a field where jumping is possible.
+ if(!DestFound){
+ for(int i = 0; i < 4; i += 1){
+ DestX = ObjX + OffsetX[i];
+ DestY = ObjY + OffsetY[i];
+ DestZ = ObjZ;
+ if(JumpPossible(DestX, DestY, DestZ, false)){
+ DestFound = true;
+ break;
+ }
+ }
+ }
+
+ if(DestFound){
+ Object Dest = GetMapContainer(DestX, DestY, DestZ);
+ MoveAllObjects(Obj.getNextObject(), Dest, Exclude, true);
+ }
+}
+
+void LoadDepotBox(uint32 CreatureID, int Nr, Object Con){
+ TPlayer *Player = GetPlayer(CreatureID);
+ if(Player == NULL){
+ error("moveuse::LoadDepotBox: Kreatur nicht gefunden.\n");
+ return;
+ }
+
+ if(!Con.exists()){
+ error("moveuse::LoadDepotBox: Übergebener Container existiert nicht.\n");
+ return;
+ }
+
+ if(!Con.getObjectType().getFlag(CONTAINER)){
+ error("moveuse::LoadDepotBox: Übergebenes Objekt ist kein Container.\n");
+ return;
+ }
+
+ // NOTE(fusion): Holy fuck. Objects are actually loaded into the depot box.
+ LoadDepot(Player->PlayerData, Nr, Con);
+
+ int DepotObjects = CountObjects(Con) - 1;
+ int DepotCapacity = GetDepotSize(Nr, CheckRight(Player->ID, PREMIUM_ACCOUNT));
+ int DepotSpace = DepotCapacity - DepotObjects;
+ Player->Depot = Con;
+ Player->DepotNr = Nr;
+ Player->DepotSpace = DepotSpace;
+
+ print(3, "Depot von %s hat %d freie Plätze.\n", Player->Name, DepotSpace);
+ SendMessage(Player->Connection, TALK_STATUS_MESSAGE,
+ "Your depot contains %d item%s.",
+ DepotObjects, (DepotObjects != 1 ? "s" : ""));
+
+ if(DepotSpace <= 0){
+ SendMessage(Player->Connection, TALK_INFO_MESSAGE,
+ "Your depot is full. Remove surplus items before storing new ones.");
+ }
+}
+
+void SaveDepotBox(uint32 CreatureID, int Nr, Object Con){
+ TPlayer *Player = GetPlayer(CreatureID);
+ if(Player == NULL){
+ error("moveuse::SaveDepotBox: Kreatur nicht gefunden.\n");
+ return;
+ }
+
+ if(!Con.exists()){
+ error("moveuse::SaveDepotBox: Übergebener Container existiert nicht.\n");
+ return;
+ }
+
+ if(!Con.getObjectType().getFlag(CONTAINER)){
+ error("moveuse::SaveDepotBox: Übergebenes Objekt ist kein Container.\n");
+ return;
+ }
+
+ int DepotObjects = CountObjects(Con) - 1;
+ Log("game", "Speichere Depot %d von %s ... Depotgröße: %d.\n",
+ Nr, Player->Name, DepotObjects);
+ print(3, "Depot von %s: berechnete freie Plätze %d, tatsächliche Objekte %d.\n",
+ Player->Name, Player->DepotSpace, DepotObjects);
+
+ SaveDepot(Player->PlayerData, Nr, Con);
+ Player->Depot = NONE;
+
+ Object Obj = GetFirstContainerObject(Con);
+ while(Obj != NONE){
+ Object Next = Obj.getNextObject();
+ Delete(Obj, -1);
+ Obj = Next;
+ }
+}
+
+void SendMail(Object Obj){
+ if(!Obj.exists()){
+ error("SendMail: Übergebenes Objekt existiert nicht.\n");
+ return;
+ }
+
+ ObjectType ObjType = Obj.getObjectType();
+ if(ObjType != GetSpecialObject(PARCEL_NEW)
+ && ObjType != GetSpecialObject(LETTER_NEW)){
+ return;
+ }
+
+ print(3,"Versende Post...\n");
+
+ uint32 TextAttr = 0;
+ if(ObjType == GetSpecialObject(LETTER_NEW)){
+ TextAttr = Obj.getAttribute(TEXTSTRING);
+ }else{
+ ObjectType LabelType = GetSpecialObject(PARCEL_LABEL);
+ Object Label = GetFirstContainerObject(Obj);
+ while(Label != NONE){
+ if(Label.getObjectType() == LabelType){
+ break;
+ }
+ Label = Label.getNextObject();
+ }
+
+ if(Label == NONE){
+ return;
+ }
+
+ TextAttr = Label.getAttribute(TEXTSTRING);
+ }
+
+ const char *Text = GetDynamicString(TextAttr);
+ if(Text == NULL || Text[0] == 0){
+ return;
+ }
+
+
+ // TODO(fusion): Have some helper functions to read lines?
+ char Addressee[256];
+ char Town[256];
+ {
+ int ReadPos = 0;
+ int WritePos = 0;
+ while(Text[ReadPos] != 0 && Text[ReadPos] != '\n'){
+ if(WritePos < (int)(sizeof(Addressee) - 1)){
+ Addressee[WritePos] = Text[ReadPos];
+ WritePos += 1;
+ }
+ ReadPos += 1;
+ }
+ Addressee[WritePos] = 0;
+
+ WritePos = 0;
+ while(Text[ReadPos] != 0 && Text[ReadPos] != '\n'){
+ if(WritePos < (int)(sizeof(Town) - 1)){
+ Town[WritePos] = Text[ReadPos];
+ WritePos += 1;
+ }
+ ReadPos += 1;
+ }
+ Town[WritePos] = 0;
+
+ Trim(Addressee);
+ Trim(Town);
+ }
+
+ if(Addressee[0] == 0 || Town[0] == 0){
+ return;
+ }
+
+ // TODO(fusion): This constant for the size of creature names showing up again.
+ // Maybe `MAX_NAME_LENGTH`?
+ if(strlen(Addressee) >= 30){
+ return;
+ }
+
+ Log("game", "Post an %s in %s.\n", Addressee, Town);
+ int DepotNr = GetDepotNumber(Town);
+ if(DepotNr == -1){
+ return;
+ }
+
+ TPlayer *Player;
+ bool PlayerOnline;
+ uint32 CharacterID;
+ if(IdentifyPlayer(Addressee, true, true, &Player) == 0){
+ PlayerOnline = true;
+ CharacterID = Player->ID;
+ }else{
+ PlayerOnline = false;
+ CharacterID = GetCharacterID(Addressee);
+ if(CharacterID == 0){
+ return;
+ }
+ }
+
+ if(PlayerOnline && Player->Depot != NONE && Player->DepotNr == DepotNr){
+ print(3, "Adressat ist eingeloggt und hat Depot offen.\n");
+ try{
+ Move(0, Obj, Player->Depot, -1, true, NONE);
+ if(ObjType == GetSpecialObject(LETTER_NEW)){
+ Change(Obj, GetSpecialObject(LETTER_STAMPED), 0);
+ }else{
+ Change(Obj, GetSpecialObject(PARCEL_STAMPED), 0);
+ }
+ Log("game", "Post an %s in %s versandt.\n", Addressee, Town);
+ Player->DepotSpace -= CountObjects(Obj);
+ print(3, "Depot von %s hat jetzt %d freie Plätze.\n", Player->Name, Player->DepotSpace);
+ SendMessage(Player->Connection, TALK_INFO_MESSAGE, "New mail has arrived.");
+ print(3, "Post erfolgreich versandt.\n");
+ }catch(RESULT r){
+ if(r != CONTAINERFULL){
+ error("SendMail (Depot offen): Exception %d.\n", r);
+ }
+
+ print(3, "Exception %d beim Postversand.\n", r);
+ }
+ }else{
+ print(3, "Adressat ist nicht eingeloggt oder hat Depot geschlossen.\n");
+
+ // TODO(fusion): The scope of this try block was unclear but I suppose
+ // this is correct due to how `Change` is also inside the try block in
+ // the try block above, when the player is online.
+ try{
+ if(ObjType == GetSpecialObject(LETTER_NEW)){
+ Change(Obj, GetSpecialObject(LETTER_STAMPED), 0);
+ }else{
+ Change(Obj, GetSpecialObject(PARCEL_STAMPED), 0);
+ }
+
+ TDynamicWriteBuffer WriteBuffer(1024);
+ SaveObjects(Obj, &WriteBuffer, true);
+ Delete(Obj, -1);
+
+ TDelayedMail *Mail = DelayedMail.at(DelayedMails);
+ Mail->CharacterID = CharacterID;
+ Mail->DepotNumber = DepotNr;
+ Mail->PacketSize = WriteBuffer.Position;
+ // TODO(fusion): Check if `WriteBuffer.Position` is not zero?
+ Mail->Packet = new uint8[WriteBuffer.Position];
+ memcpy(Mail->Packet, WriteBuffer.Data, WriteBuffer.Position);
+ DelayedMails += 1;
+
+ Log("game", "Post an %s in %s zurückgestellt.\n", Addressee, Town);
+ print(3, "Post zurückgestellt.\n");
+ if(PlayerOnline){
+ SendMails(Player->PlayerData);
+ }else{
+ LoadCharacterOrder(CharacterID);
+ }
+ }catch(RESULT r){
+ error("SendMail: Kann Paket nicht löschen (%d).\n", r);
+ }catch(const char *str){
+ error("SendMail: Kann Paket nicht schreiben (%s).\n", str);
+ }
+ }
+}
+
+void SendMails(TPlayerData *PlayerData){
+ if(PlayerData == NULL){
+ error("SendMails: PlayerData ist NULL.\n");
+ return;
+ }
+
+ if(PlayerData->CharacterID == 0){
+ error("SendMails: Slot ist nicht belegt.\n");
+ return;
+ }
+
+ if(PlayerData->Locked != getpid()){
+ error("SendMails: Slot ist nicht vom GameThread gesperrt.\n");
+ return;
+ }
+
+ for(int i = 0; i < DelayedMails; i += 1){
+ TDelayedMail *Mail = DelayedMail.at(i);
+ if(Mail->CharacterID != PlayerData->CharacterID){
+ continue;
+ }
+
+ int DepotNr = Mail->DepotNumber;
+ if(DepotNr < 0 || DepotNr >= 9){ // MAX_DEPOT ?
+ error("SendMails: Ungültige Depotnummer %d.\n", DepotNr);
+ DepotNr = 0;
+ }
+
+ int NewDepotSize = 0;
+ uint8 *NewDepot = NULL;
+ if(PlayerData->Depot[DepotNr] != NULL){
+ NewDepotSize = PlayerData->DepotSize[DepotNr] + Mail->PacketSize;
+ NewDepot = new uint8[NewDepotSize];
+ memcpy(&NewDepot[0], Mail->Packet, Mail->PacketSize);
+ memcpy(&NewDepot[Mail->PacketSize],
+ PlayerData->Depot[DepotNr],
+ PlayerData->DepotSize[DepotNr]);
+ delete[] PlayerData->Depot[DepotNr];
+ }else{
+ NewDepotSize = Mail->PacketSize + 5;
+ NewDepot = new uint8[NewDepotSize];
+ memcpy(&NewDepot[0], Mail->Packet, Mail->PacketSize);
+ TWriteBuffer WriteBuffer(&NewDepot[Mail->PacketSize], 5);
+ WriteBuffer.writeWord((uint16)GetSpecialObject(DEPOT_CHEST).TypeID);
+ WriteBuffer.writeByte(0xFF);
+ WriteBuffer.writeWord(0xFFFF);
+ }
+
+ PlayerData->Depot[DepotNr] = NewDepot;
+ PlayerData->DepotSize[DepotNr] = NewDepotSize;
+ PlayerData->Dirty = true;
+
+ Log("game", "Post an %s zugestellt.\n", PlayerData->Name);
+
+ if(Mail->Packet != NULL){
+ delete[] Mail->Packet;
+ }
+
+ // NOTE(fusion): A little swap and pop action.
+ DelayedMails -= 1;
+ *DelayedMail.at(i) = *DelayedMail.at(DelayedMails);
+ *DelayedMail.at(DelayedMails) = TDelayedMail{};
+
+ // NOTE(fusion): Check current index again after removal.
+ i -= 1;
+ }
+}
+
+void TextEffect(const char *Text, int x, int y, int z, int Radius){
+ if(Text == NULL){
+ error("TextEffect: Text existiert nicht.\n");
+ return;
+ }
+
+ TFindCreatures Search(Radius, Radius, x, y, FIND_PLAYERS);
+ while(true){
+ uint32 CharacterID = Search.getNext();
+ if(CharacterID == 0){
+ break;
+ }
+
+ TPlayer *Player = GetPlayer(CharacterID);
+ if(Player == NULL || Player->Connection == NULL){
+ continue;
+ }
+
+ int PlayerZ = Player->posz;
+ if(PlayerZ == z || Radius > 30 || (Radius > 7 && PlayerZ <= 7 && z <= 7)){
+ SendTalk(Player->Connection, 0, "", TALK_ANIMAL_LOW, x, y, z, Text);
+ }
+ }
+}
+
+void ExecuteAction(MoveUseEventType EventType, TMoveUseAction *Action,
+ Object User, Object Obj1, Object Obj2, Object *Temp){
+ try{
+ switch(Action->Action){
+ case MOVEUSE_ACTION_CREATEONMAP:{
+ int CoordX, CoordY, CoordZ;
+ UnpackAbsoluteCoordinate(Action->Parameters[0], &CoordX, &CoordY, &CoordZ);
+ ObjectType Type = Action->Parameters[1];
+ int Value = Action->Parameters[2];
+ Object MapCon = GetMapContainer(CoordX, CoordY, CoordZ);
+ *Temp = CreateObject(MapCon, Type, Value);
+ break;
+ }
+
+ case MOVEUSE_ACTION_CREATE:{
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ ObjectType Type = Action->Parameters[1];
+ int Value = Action->Parameters[2];
+ *Temp = CreateObject(Obj.getContainer(), Type, Value);
+ break;
+ }
+
+ case MOVEUSE_ACTION_MONSTERONMAP:{
+ int CoordX, CoordY, CoordZ;
+ UnpackAbsoluteCoordinate(Action->Parameters[0], &CoordX, &CoordY, &CoordZ);
+ int Race = Action->Parameters[1];
+ CreateMonster(Race, CoordX, CoordY, CoordZ, 0, 0, true);
+ break;
+ }
+
+ case MOVEUSE_ACTION_MONSTER:{
+ int ObjX, ObjY, ObjZ;
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ int Race = Action->Parameters[1];
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+ CreateMonster(Race, ObjX, ObjY, ObjZ, 0, 0, true);
+ break;
+ }
+
+ case MOVEUSE_ACTION_EFFECTONMAP:{
+ int CoordX, CoordY, CoordZ;
+ UnpackAbsoluteCoordinate(Action->Parameters[0], &CoordX, &CoordY, &CoordZ);
+ int Effect = Action->Parameters[1];
+ GraphicalEffect(CoordX, CoordY, CoordZ, Effect);
+ break;
+ }
+
+ case MOVEUSE_ACTION_EFFECT:{
+ int ObjX, ObjY, ObjZ;
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ int Effect = Action->Parameters[1];
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+ GraphicalEffect(ObjX, ObjY, ObjZ, Effect);
+ break;
+ }
+
+ case MOVEUSE_ACTION_TEXTONMAP:{
+ int CoordX, CoordY, CoordZ;
+ UnpackAbsoluteCoordinate(Action->Parameters[0], &CoordX, &CoordY, &CoordZ);
+ const char *Text = GetDynamicString(Action->Parameters[1]);
+ int Radius = Action->Parameters[2];
+ TextEffect(Text, CoordX, CoordY, CoordZ, Radius);
+ break;
+ }
+
+ case MOVEUSE_ACTION_TEXT:{
+ int ObjX, ObjY, ObjZ;
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ const char *Text = GetDynamicString(Action->Parameters[1]);
+ int Radius = Action->Parameters[2];
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+ TextEffect(Text, ObjX, ObjY, ObjZ, Radius);
+ break;
+ }
+
+ case MOVEUSE_ACTION_CHANGEONMAP:{
+ int CoordX, CoordY, CoordZ;
+ UnpackAbsoluteCoordinate(Action->Parameters[0], &CoordX, &CoordY, &CoordZ);
+ ObjectType OldType = Action->Parameters[1];
+ ObjectType NewType = Action->Parameters[2];
+ int NewValue = Action->Parameters[3];
+ *Temp = GetFirstSpecObject(CoordX, CoordY, CoordZ, OldType);
+ if(*Temp != NONE){
+ ChangeObject(*Temp, NewType, NewValue);
+ }else{
+ error("ExecuteAction (CHANGEONMAP): Kein Objekt %d auf [%d,%d,%d].\n",
+ OldType.TypeID, CoordX, CoordY, CoordZ);
+ }
+ break;
+ }
+
+ case MOVEUSE_ACTION_CHANGE:{
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ ObjectType NewType = Action->Parameters[1];
+ int NewValue = Action->Parameters[2];
+ ChangeObject(Obj, NewType, NewValue);
+ break;
+ }
+
+ case MOVEUSE_ACTION_CHANGEREL:{
+ int ObjX, ObjY, ObjZ, RelX, RelY, RelZ;
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ UnpackRelativeCoordinate(Action->Parameters[1], &RelX, &RelY, &RelZ);
+ ObjectType OldType = Action->Parameters[2];
+ ObjectType NewType = Action->Parameters[3];
+ int NewValue = Action->Parameters[4];
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+ *Temp = GetFirstSpecObject((ObjX + RelX), (ObjY + RelY), (ObjZ + RelZ), OldType);
+ if(*Temp != NONE){
+ ChangeObject(*Temp, NewType, NewValue);
+ }else{
+ error("ExecuteAction (CHANGEREL): Kein Objekt %d auf [%d,%d,%d].\n",
+ OldType.TypeID, (ObjX + RelX), (ObjY + RelY), (ObjZ + RelZ));
+ }
+ break;
+ }
+
+ case MOVEUSE_ACTION_SETATTRIBUTE:{
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ INSTANCEATTRIBUTE Attribute = (INSTANCEATTRIBUTE)Action->Parameters[1];
+ int Value = Action->Parameters[2];
+ Change(Obj, Attribute, Value);
+ break;
+ }
+
+ case MOVEUSE_ACTION_CHANGEATTRIBUTE:{
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ INSTANCEATTRIBUTE Attribute = (INSTANCEATTRIBUTE)Action->Parameters[1];
+ int Amount = Action->Parameters[2];
+ // TODO(fusion): This is weird.
+ int OldValue = (int)Obj.getAttribute(Attribute);
+ int NewValue = OldValue + Amount;
+ if(NewValue <= 0){
+ if(OldValue == 0){
+ NewValue = 0;
+ }else{
+ NewValue = 1;
+ }
+ }
+ Change(Obj, Attribute, NewValue);
+ break;
+ }
+
+ case MOVEUSE_ACTION_SETQUESTVALUE:{
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ int QuestNr = Action->Parameters[1];
+ int QuestValue = Action->Parameters[2];
+ ObjectType ObjType = Obj.getObjectType();
+ if(ObjType.isCreatureContainer()){
+ TCreature *Creature = GetCreature(Obj);
+ if(Creature != NULL && Creature->Type == PLAYER){
+ ((TPlayer*)Creature)->SetQuestValue(QuestNr, QuestValue);
+ }else{
+ error("ExecuteAction (SETQUESTVALUE): Kreatur existiert nicht oder ist kein Spieler.\n");
+ }
+ }else{
+ error("ExecuteAction (SETQUESTVALUE): Objekt ist keine Kreatur, sondern Typ %d.\n", ObjType.TypeID);
+ }
+ break;
+ }
+
+ case MOVEUSE_ACTION_DAMAGE:{
+ Object AttackerObj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ Object VictimObj = GetEventObject(Action->Parameters[1], User, Obj1, Obj2, *Temp);
+ int DamageType = Action->Parameters[2];
+ int Damage = Action->Parameters[3];
+
+ TCreature *Attacker = NULL;
+ if(AttackerObj != NONE){
+ ObjectType AttackerType = AttackerObj.getObjectType();
+ if(AttackerType.isCreatureContainer()){
+ Attacker = GetCreature(AttackerObj);
+ }else if(AttackerType.getFlag(MAGICFIELD)
+ && AttackerObj.getAttribute(RESPONSIBLE) != 0){
+ int TotalExpireTime = (int)AttackerType.getAttribute(TOTALEXPIRETIME);
+ int CurExpireTime = (int)CronInfo(AttackerObj, false);
+ if((TotalExpireTime - CurExpireTime) < 5){
+ Attacker = GetCreature(AttackerObj.getAttribute(RESPONSIBLE));
+ }
+ }
+ }
+
+ ObjectType VictimType = VictimObj.getObjectType();
+ if(VictimType.isCreatureContainer()){
+ TCreature *Victim = GetCreature(VictimObj);
+ if(Victim != NULL){
+ Victim->Damage(Attacker, Damage, DamageType);
+ }else{
+ error("ExecuteAction (DAMAGE): Kreatur existiert nicht.\n");
+ }
+ }else{
+ error("ExecuteAction (DAMAGE): Objekt ist keine Kreatur, sondern Typ %d.\n", VictimType.TypeID);
+ }
+ break;
+ }
+
+ case MOVEUSE_ACTION_SETSTART:{
+ int StartX, StartY, StartZ;
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ UnpackAbsoluteCoordinate(Action->Parameters[1], &StartX, &StartY, &StartZ);
+
+ if(!Obj.getObjectType().isCreatureContainer()){
+ throw ERROR;
+ }
+
+ TCreature *Creature = GetCreature(Obj);
+ if(Creature == NULL || Creature->Type != PLAYER){
+ throw ERROR;
+ }
+
+ Creature->startx = StartX;
+ Creature->starty = StartY;
+ Creature->startz = StartZ;
+ ((TPlayer*)Creature)->SaveData();
+ break;
+ }
+
+ case MOVEUSE_ACTION_WRITENAME:{
+ Object WriterObj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ const char *Format = GetDynamicString(Action->Parameters[1]);
+ Object TargetObj = GetEventObject(Action->Parameters[2], User, Obj1, Obj2, *Temp);
+
+ if(WriterObj == NONE || !WriterObj.getObjectType().isCreatureContainer()
+ || TargetObj == NONE || !TargetObj.getObjectType().getFlag(TEXT)){
+ throw ERROR;
+ }
+
+ TCreature *Writer = GetCreature(WriterObj);
+ if(Writer == NULL){
+ throw ERROR;
+ }
+
+ // TODO(fusion): Some helper function to format text?
+ char Text[256];
+ {
+ int ReadPos = 0;
+ int WritePos = 0;
+ int TextSize = (int)sizeof(Text);
+ while(Format[ReadPos] != 0){
+ if(Format[ReadPos] == '%' && Format[ReadPos + 1] == 'N'){
+ // NOTE(fusion): Make sure we don't overflow the buffer.
+ int NameLen = (int)strlen(Writer->Name);
+ if(NameLen > 0){
+ if((WritePos + NameLen) > TextSize){
+ NameLen = TextSize - WritePos;
+ }
+
+ if(NameLen > 0){
+ memcpy(&Text[WritePos], Writer->Name, NameLen);
+ WritePos += NameLen;
+ }
+ }
+
+ ReadPos += 2;
+ }else{
+ // NOTE(fusion): Make sure we don't overflow the buffer.
+ if(WritePos < TextSize){
+ Text[WritePos] = Format[ReadPos];
+ WritePos += 1;
+ }
+
+ ReadPos += 1;
+ }
+ }
+
+ if(WritePos >= TextSize){
+ throw ERROR;
+ }
+ }
+
+ DeleteDynamicString(TargetObj.getAttribute(TEXTSTRING));
+ DeleteDynamicString(TargetObj.getAttribute(EDITOR));
+ Change(TargetObj, TEXTSTRING, AddDynamicString(Text));
+ Change(TargetObj, EDITOR, 0);
+ break;
+ }
+
+ case MOVEUSE_ACTION_WRITETEXT:{
+ const char *Text = GetDynamicString(Action->Parameters[0]);
+ Object Obj = GetEventObject(Action->Parameters[1], User, Obj1, Obj2, *Temp);
+
+ if(Obj == NONE || !Obj.getObjectType().getFlag(TEXT)){
+ throw ERROR;
+ }
+
+ DeleteDynamicString(Obj.getAttribute(TEXTSTRING));
+ DeleteDynamicString(Obj.getAttribute(EDITOR));
+ Change(Obj, TEXTSTRING, AddDynamicString(Text));
+ Change(Obj, EDITOR, 0);
+ break;
+ }
+
+ case MOVEUSE_ACTION_LOGOUT:{
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+
+ if(Obj == NONE || !Obj.getObjectType().isCreatureContainer()){
+ throw ERROR;
+ }
+
+ TCreature *Creature = GetCreature(Obj);
+ if(Creature == NULL){
+ throw ERROR;
+ }
+
+ Creature->StartLogout(true, true);
+ break;
+ }
+
+ case MOVEUSE_ACTION_MOVEALLONMAP:{
+ int OrigX, OrigY, OrigZ, DestX, DestY, DestZ;
+ UnpackAbsoluteCoordinate(Action->Parameters[0], &OrigX, &OrigY, &OrigZ);
+ UnpackAbsoluteCoordinate(Action->Parameters[1], &DestX, &DestY, &DestZ);
+ Object First = GetFirstObject(OrigX, OrigY, OrigZ);
+ Object Dest = GetMapContainer(DestX, DestY, DestZ);
+ MoveAllObjects(First, Dest, NONE, false);
+ break;
+ }
+
+ case MOVEUSE_ACTION_MOVEALL:{
+ int DestX, DestY, DestZ;
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ UnpackAbsoluteCoordinate(Action->Parameters[1], &DestX, &DestY, &DestZ);
+ Object First = GetFirstContainerObject(Obj.getContainer());
+ Object Dest = GetMapContainer(DestX, DestY, DestZ);
+ // TODO(fusion): Why do we set the `Exclude` parameter to `First`?
+ // Maybe we just don't want to check if it is `NONE` can call
+ // `getNextObject()` like MOVETOPONMAP?
+ MoveAllObjects(First, Dest, First, false);
+ break;
+ }
+
+ case MOVEUSE_ACTION_MOVEALLREL:{
+ int ObjX, ObjY, ObjZ, RelX, RelY, RelZ;
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ UnpackRelativeCoordinate(Action->Parameters[1], &RelX, &RelY, &RelZ);
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+ Object First = GetFirstContainerObject(Obj.getContainer());
+ Object Dest = GetMapContainer((ObjX + RelX), (ObjY + RelY), (ObjZ + RelZ));
+ // TODO(fusion): Same as above?
+ MoveAllObjects(First, Dest, First, false);
+ break;
+ }
+
+ case MOVEUSE_ACTION_MOVETOPONMAP:{
+ int OrigX, OrigY, OrigZ, DestX, DestY, DestZ;
+ UnpackAbsoluteCoordinate(Action->Parameters[0], &OrigX, &OrigY, &OrigZ);
+ ObjectType Type = Action->Parameters[1];
+ UnpackAbsoluteCoordinate(Action->Parameters[2], &DestX, &DestY, &DestZ);
+ Object Obj = GetFirstSpecObject(OrigX, OrigY, OrigZ, Type);
+ if(Obj != NONE){
+ Object Dest = GetMapContainer(DestX, DestY, DestZ);
+ MoveAllObjects(Obj.getNextObject(), Dest, NONE, true);
+ }else{
+ error("ExecuteAction (MOVETOPONMAP): Kein Objekt %d auf [%d,%d,%d].\n",
+ Type.TypeID, OrigX, OrigY, OrigZ);
+ }
+ break;
+ }
+
+ case MOVEUSE_ACTION_MOVETOP:{
+ int DestX, DestY, DestZ;
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ UnpackAbsoluteCoordinate(Action->Parameters[1], &DestX, &DestY, &DestZ);
+ Object Dest = GetMapContainer(DestX, DestY, DestZ);
+ MoveAllObjects(Obj.getNextObject(), Dest, NONE, true);
+ break;
+ }
+
+ case MOVEUSE_ACTION_MOVETOPREL:{
+ int ObjX, ObjY, ObjZ, RelX, RelY, RelZ;
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ UnpackRelativeCoordinate(Action->Parameters[1], &RelX, &RelY, &RelZ);
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+ Object Dest = GetMapContainer((ObjX + RelX), (ObjY + RelY), (ObjZ + RelZ));
+ MoveAllObjects(Obj.getNextObject(), Dest, NONE, true);
+ break;
+ }
+
+ case MOVEUSE_ACTION_MOVE:{
+ int DestX, DestY, DestZ;
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ UnpackAbsoluteCoordinate(Action->Parameters[1], &DestX, &DestY, &DestZ);
+ Object Dest = GetMapContainer(DestX, DestY, DestZ);
+ MoveOneObject(Obj, Dest);
+ break;
+ }
+
+ case MOVEUSE_ACTION_MOVEREL:{
+ int ObjX, ObjY, ObjZ, RelX, RelY, RelZ;
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ UnpackRelativeCoordinate(Action->Parameters[1], &RelX, &RelY, &RelZ);
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+ Object Dest = GetMapContainer((ObjX + RelX), (ObjY + RelY), (ObjZ + RelZ));
+ MoveOneObject(Obj, Dest);
+ break;
+ }
+
+ case MOVEUSE_ACTION_RETRIEVE:{
+ int ObjX, ObjY, ObjZ, OrigRelX, OrigRelY, OrigRelZ, DestRelX, DestRelY, DestRelZ;
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ UnpackRelativeCoordinate(Action->Parameters[1], &OrigRelX, &OrigRelY, &OrigRelZ);
+ UnpackRelativeCoordinate(Action->Parameters[2], &DestRelX, &DestRelY, &DestRelZ);
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+ Object Top = GetTopObject((ObjX + OrigRelX), (ObjY + OrigRelY), (ObjZ + OrigRelZ), false);
+ if(Top != NONE && !Top.getObjectType().getFlag(UNMOVE)){
+ Object Dest = GetMapContainer((ObjX + DestRelX), (ObjY + DestRelY), (ObjZ + DestRelZ));
+ MoveOneObject(Obj, Dest);
+ }
+ break;
+ }
+
+ case MOVEUSE_ACTION_DELETEALLONMAP:{
+ int CoordX, CoordY, CoordZ;
+ UnpackAbsoluteCoordinate(Action->Parameters[0], &CoordX, &CoordY, &CoordZ);
+ Object First = GetFirstObject(CoordX, CoordY, CoordZ);
+ // TODO(fusion): Same as `MOVEALL`.
+ DeleteAllObjects(First, First, false);
+ break;
+ }
+
+ case MOVEUSE_ACTION_DELETETOPONMAP:{
+ int CoordX, CoordY, CoordZ;
+ UnpackAbsoluteCoordinate(Action->Parameters[0], &CoordX, &CoordY, &CoordZ);
+ ObjectType Type = Action->Parameters[1];
+ Object First = GetFirstSpecObject(CoordX, CoordY, CoordZ, Type);
+ // TODO(fusion): Sometimes we throw, sometimes we print an error,
+ // sometimes we ignore it, what a mess.
+ if(First == NONE){
+ throw ERROR;
+ }
+ DeleteAllObjects(First, First, true);
+ break;
+ }
+
+ case MOVEUSE_ACTION_DELETEONMAP:{
+ int CoordX, CoordY, CoordZ;
+ UnpackAbsoluteCoordinate(Action->Parameters[0], &CoordX, &CoordY, &CoordZ);
+ ObjectType Type = Action->Parameters[1];
+ Object Obj = GetFirstSpecObject(CoordX, CoordY, CoordZ, Type);
+ if(Obj != NONE){
+ bool IsUseEvent = (EventType == MOVEUSE_EVENT_USE
+ || EventType == MOVEUSE_EVENT_MULTIUSE);
+ Delete(Obj, (IsUseEvent ? 1 : -1));
+ }else{
+ error("ExecuteAction (DELETEONMAP): Kein Objekt %d auf [%d,%d,%d].\n",
+ Type.TypeID, CoordX, CoordY, CoordZ);
+ }
+ break;
+ }
+
+ case MOVEUSE_ACTION_DELETE:{
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ if(Obj == NONE){
+ throw ERROR;
+ }
+ bool IsUseEvent = (EventType == MOVEUSE_EVENT_USE
+ || EventType == MOVEUSE_EVENT_MULTIUSE);
+ Delete(Obj, (IsUseEvent ? 1 : -1));
+ break;
+ }
+
+ case MOVEUSE_ACTION_DELETEININVENTORY:{
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ ObjectType Type = Action->Parameters[1];
+ int Value = Action->Parameters[2];
+ if(Obj.getObjectType().isCreatureContainer()){
+ DeleteAtCreature(Obj.getCreatureID(), Type, 1, Value);
+ }else{
+ throw ERROR;
+ }
+ break;
+ }
+
+ case MOVEUSE_ACTION_DESCRIPTION:{
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ Object Cr = GetEventObject(Action->Parameters[1], User, Obj1, Obj2, *Temp);
+ if(Cr.getObjectType().isCreatureContainer()){
+ TCreature *Creature = GetCreature(Cr);
+ if(Creature != NULL && Creature->Type == PLAYER){
+ SendMessage(Creature->Connection, TALK_INFO_MESSAGE,
+ "%s.", GetInfo(Obj));
+ }
+ }
+ break;
+ }
+
+ case MOVEUSE_ACTION_LOADDEPOT:{
+ int CoordX, CoordY, CoordZ;
+ UnpackAbsoluteCoordinate(Action->Parameters[0], &CoordX, &CoordY, &CoordZ);
+ ObjectType Type = Action->Parameters[1];
+ Object Cr = GetEventObject(Action->Parameters[2], User, Obj1, Obj2, *Temp);
+ int DepotNr = Action->Parameters[3];
+
+ if(!Cr.getObjectType().isCreatureContainer()){
+ throw ERROR;
+ }
+
+ Object Depot = GetFirstSpecObject(CoordX, CoordY, CoordZ, Type);
+ if(Depot == NONE){
+ throw ERROR;
+ }
+
+ LoadDepotBox(Cr.getCreatureID(), DepotNr, Depot);
+ break;
+ }
+
+ case MOVEUSE_ACTION_SAVEDEPOT:{
+ int CoordX, CoordY, CoordZ;
+ UnpackAbsoluteCoordinate(Action->Parameters[0], &CoordX, &CoordY, &CoordZ);
+ ObjectType Type = Action->Parameters[1];
+ Object Cr = GetEventObject(Action->Parameters[2], User, Obj1, Obj2, *Temp);
+ int DepotNr = Action->Parameters[3];
+
+ if(!Cr.getObjectType().isCreatureContainer()){
+ throw ERROR;
+ }
+
+ Object Depot = GetFirstSpecObject(CoordX, CoordY, CoordZ, Type);
+ if(Depot == NONE){
+ throw ERROR;
+ }
+
+ SaveDepotBox(Cr.getCreatureID(), DepotNr, Depot);
+ break;
+ }
+
+ case MOVEUSE_ACTION_SENDMAIL:{
+ Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ SendMail(Obj);
+ break;
+ }
+
+ case MOVEUSE_ACTION_NOP:{
+ // no-op
+ break;
+ }
+
+ default:{
+ error("ExecuteAction: Unbekannte Aktion %d.\n", Action->Action);
+ break;
+ }
+ }
+ }catch(RESULT r){
+ error("ExecuteAction: Exception %d (Aktion %d).\n", r, Action->Action);
+ }
+}
+
+bool HandleEvent(MoveUseEventType EventType, Object User, Object Obj1, Object Obj2){
+ static int RecursionDepth = 0;
+
+ if(RecursionDepth > 10){
+ error("HandleEvent: Endlosschleife im Move/Use-System vermutet.\n");
+ return false;
+ }
+
+ bool Result = false;
+ RecursionDepth += 1;
+ TMoveUseDatabase *DB = &MoveUseDatabases[EventType];
+ for(int RuleNr = 1; RuleNr <= DB->NumberOfRules; RuleNr += 1){
+ bool Execute = true;
+ Object Temp = NONE;
+ TMoveUseRule *Rule = DB->Rules.at(RuleNr);
+ for(int ConditionNr = Rule->FirstCondition;
+ ConditionNr <= Rule->LastCondition;
+ ConditionNr += 1){
+ TMoveUseCondition *Condition = MoveUseConditions.at(ConditionNr);
+ if(!CheckCondition(EventType, Condition, User, Obj1, Obj2, &Temp)){
+ Execute = false;
+ break;
+ }
+ }
+
+ if(Execute){
+ for(int ActionNr = Rule->FirstAction;
+ ActionNr <= Rule->LastAction;
+ ActionNr += 1){
+ TMoveUseAction *Action = MoveUseActions.at(ActionNr);
+ ExecuteAction(EventType, Action, User, Obj2, Obj2, &Temp);
+ }
+ Result = true;
+ }
+ }
+ RecursionDepth -= 1;
+ return Result;
+}
+
+// Event Dispatching
+// =============================================================================
+void UseContainer(uint32 CreatureID, Object Con, int NextContainerNr){
+ if(!Con.exists()){
+ error("UseContainer: Übergebenes Objekt existiert nicht.\n");
+ throw ERROR;
+ }
+
+ ObjectType ConType = Con.getObjectType();
+ if(!ConType.getFlag(CONTAINER)){
+ error("UseContainer: Übergebenes Objekt ist kein Container.\n");
+ throw ERROR;
+ }
+
+ if(NextContainerNr < 0 || NextContainerNr >= NARRAY(TPlayer::OpenContainer)){
+ error("UseContainer: Ungültige Fensternummer %d.\n", NextContainerNr);
+ throw ERROR;
+ }
+
+ if(ConType.isCreatureContainer()){
+ throw NOTUSABLE;
+ }
+
+ TPlayer *Player = GetPlayer(CreatureID);
+ if(Player == NULL){
+ error("UseContainer: Spieler %d existiert nicht.\n", CreatureID);
+ throw ERROR;
+ }
+
+ bool ContainerClosed = false;
+ for(int ContainerNr = 0;
+ ContainerNr < NARRAY(TPlayer::OpenContainer);
+ ContainerNr += 1){
+ if(Player->GetOpenContainer(ContainerNr) == Con){
+ Player->SetOpenContainer(ContainerNr, NONE);
+ SendCloseContainer(Player->Connection, ContainerNr);
+ ContainerClosed = true;
+ break;
+ }
+ }
+
+ if(!ContainerClosed){
+ Player->SetOpenContainer(NextContainerNr, Con);
+ SendContainer(Player->Connection, NextContainerNr);
+ }
+}
+
+void UseChest(uint32 CreatureID, Object Chest){
+ if(!Chest.exists()){
+ error("UseChest: Übergebenes Objekt existiert nicht.\n");
+ throw ERROR;
+ }
+
+ ObjectType ChestType = Chest.getObjectType();
+ if(!ChestType.getFlag(CHEST)){
+ error("UseChest: Übergebenes Objekt ist keine Schatztruhe.\n");
+ throw ERROR;
+ }
+
+ int ChestX, ChestY, ChestZ;
+ GetObjectCoordinates(Chest, &ChestX, &ChestY, &ChestZ);
+
+ int QuestNr = (int)Chest.getAttribute(CHESTQUESTNUMBER);
+ if(QuestNr < 0 || QuestNr >= NARRAY(TPlayer::QuestValues)){
+ error("UseChest: Ungültige Nummer %d auf Schatztruhe an Position [%d,%d,%d].\n",
+ QuestNr, ChestX, ChestY, ChestZ);
+ throw ERROR;
+ }
+
+ if(CountObjectsInContainer(Chest) != 1){
+ error("UseChest: Schatztruhe auf Position [%d,%d,%d] enthält nicht genau ein Objekt.\n",
+ ChestX, ChestY, ChestZ);
+ throw ERROR;
+ }
+
+ Object Treasure = GetFirstContainerObject(Chest);
+ ObjectType TreasureType = Treasure.getObjectType();
+ if(TreasureType.getFlag(UNMOVE) || !TreasureType.getFlag(TAKE)){
+ error("UseChest: Schatz auf Position [%d,%d,%d] ist nicht nehmbar.\n",
+ ChestX, ChestY, ChestZ);
+ throw ERROR;
+ }
+
+ TPlayer *Player = GetPlayer(CreatureID);
+ if(Player == NULL){
+ error("UseChest: Spieler %u existiert nicht.\n", CreatureID);
+ throw ERROR;
+ }
+
+ if(Player->GetQuestValue(QuestNr) != 0){
+ print(3, "Schatztruhe ist schon bekannt.\n");
+ SendMessage(Player->Connection, TALK_INFO_MESSAGE,
+ "The %s is empty.", ChestType.getName(-1));
+ return;
+ }
+
+ if(!CheckRight(CreatureID, UNLIMITED_CAPACITY)){
+ int TreasureWeight = GetCompleteWeight(Treasure);
+ int InventoryWeight = GetInventoryWeight(CreatureID);
+ int MaxWeight = Player->Skills[SKILL_CARRY_STRENGTH]->Get() * 100;
+ if((InventoryWeight + TreasureWeight) > MaxWeight
+ || CheckRight(CreatureID, ZERO_CAPACITY)){
+ bool Multiple = TreasureType.getFlag(CUMULATIVE)
+ && Treasure.getAttribute(AMOUNT) > 1;
+ SendMessage(Player->Connection, TALK_INFO_MESSAGE,
+ "You have found %s. Weighing %d.%02d oz %s too heavy.",
+ GetName(Treasure), (TreasureWeight / 100), (TreasureWeight % 100),
+ (Multiple ? "they are" : "it is"));
+ return;
+ }
+ }
+
+ // NOTE(fusion): Copy treasure object and attempt to move into the player's
+ // inventory. The original version was somewhat confusing but this should
+ // achieve the same end result.
+ Treasure = Copy(Chest, Treasure);
+ bool CheckContainers = TreasureType.getFlag(MOVEMENTEVENT);
+ bool TreasureMoved = false;
+ for(int i = 0; i < 2 && !TreasureMoved; i += 1){
+ for(int Position = INVENTORY_FIRST;
+ Position <= INVENTORY_LAST && !TreasureMoved;
+ Position += 1){
+ try{
+ Object BodyObj = GetBodyObject(CreatureID, Position);
+ if(CheckContainers){
+ if(BodyObj != NONE && BodyObj.getObjectType().getFlag(CONTAINER)){
+ Move(CreatureID, Treasure, BodyObj, -1, true, NONE);
+ TreasureMoved = true;
+ }
+ }else{
+ if(BodyObj == NONE){
+ Object BodyCon = GetBodyContainer(CreatureID, Position);
+ Move(CreatureID, Treasure, BodyCon, -1, true, NONE);
+ TreasureMoved = true;
+ }
+ }
+ }catch(RESULT r){
+ // no-op
+ }
+ }
+ CheckContainers = !CheckContainers;
+ }
+
+ if(!TreasureMoved){
+ bool Multiple = TreasureType.getFlag(CUMULATIVE)
+ && Treasure.getAttribute(AMOUNT) > 1;
+ SendMessage(Player->Connection, TALK_INFO_MESSAGE,
+ "You have found %s, but you have no room to take %s.\n",
+ GetName(Treasure), (Multiple ? "them" : "it"));
+ Delete(Treasure, -1);
+ return;
+ }
+
+ SendMessage(Player->Connection, TALK_INFO_MESSAGE,
+ "You have found %s.\n", GetName(Treasure));
+ Player->SetQuestValue(QuestNr, 1);
+}
+
+void UseLiquidContainer(uint32 CreatureID, Object Obj, Object Dest){
+ if(!Obj.exists()){
+ error("UseLiquidContainer: Übergebenes Objekt Obj existiert nicht.\n");
+ throw ERROR;
+ }
+
+ ObjectType ObjType = Obj.getObjectType();
+ if(!Dest.exists()){
+ error("UseLiquidContainer: Übergebenes Objekt Dest existiert nicht (Obj %d).\n",
+ ObjType.TypeID);
+ throw ERROR;
+ }
+
+ if(!ObjType.getFlag(LIQUIDCONTAINER)){
+ error("UseLiquidContainer: Übergebenes Objekt ist kein Flüssigkeitscontainer.\n");
+ throw ERROR;
+ }
+
+ ObjectType DestType = Dest.getObjectType();
+ int LiquidType = Obj.getAttribute(CONTAINERLIQUIDTYPE);
+
+ // NOTE(fusion): Fill liquid container.
+ if(DestType.getFlag(LIQUIDSOURCE) && LiquidType == LIQUID_NONE){
+ int DestLiquidType = (int)DestType.getAttribute(SOURCELIQUIDTYPE);
+ Change(Obj, CONTAINERLIQUIDTYPE, DestLiquidType);
+ return;
+ }
+
+ // NOTE(fusion): Transfer liquid to another container.
+ if(DestType.getFlag(LIQUIDCONTAINER) && LiquidType != LIQUID_NONE
+ && Dest.getAttribute(CONTAINERLIQUIDTYPE) == LIQUID_NONE){
+ Change(Dest, CONTAINERLIQUIDTYPE, LiquidType);
+ Change(Obj, CONTAINERLIQUIDTYPE, LIQUID_NONE);
+ return;
+ }
+
+ // NOTE(fusion): This is similar to the target picking logic for runes except
+ // we want to prioritize the user drinking the liquid, instead of otherwise
+ // throwing it on the ground.
+ if(!DestType.isCreatureContainer()){
+ Object Help = GetFirstContainerObject(Dest.getContainer());
+ while(Help != NONE){
+ ObjectType HelpType = Help.getObjectType();
+ if(HelpType.isCreatureContainer() && Help.getCreatureID() == CreatureID){
+ Dest = Help;
+ DestType = HelpType;
+ break;
+ }
+ Help = Help.getNextObject();
+ }
+ }
+
+ // NOTE(fusion): Spill liquid.
+ if(!DestType.isCreatureContainer() || Dest.getCreatureID() != CreatureID){
+ if(LiquidType == LIQUID_NONE){
+ throw NOTUSABLE;
+ }
+
+ int DestX, DestY, DestZ;
+ GetObjectCoordinates(Dest, &DestX, &DestY, &DestZ);
+ if(!CoordinateFlag(DestX, DestY, DestZ, BANK)
+ || CoordinateFlag(DestX, DestY, DestZ, UNLAY)){
+ throw NOROOM;
+ }
+
+ Change(Obj, CONTAINERLIQUIDTYPE, LIQUID_NONE);
+ CreatePool(GetMapContainer(DestX, DestY, DestZ),
+ GetSpecialObject(BLOOD_POOL), LiquidType);
+ return;
+ }
+
+ // NOTE(fusion): Drink liquid.
+ TPlayer *Player = GetPlayer(CreatureID);
+ if(Player == NULL){
+ error("UseLiquidContainer: Spieler %d existiert nicht.\n", CreatureID);
+ throw ERROR;
+ }
+
+ switch(LiquidType){
+ case LIQUID_NONE:{
+ // no-op
+ break;
+ }
+
+ case LIQUID_WINE:
+ case LIQUID_BEER:{
+ Change(Obj, CONTAINERLIQUIDTYPE, LIQUID_NONE);
+ int DrunkLevel = Player->Skills[SKILL_DRUNKEN]->TimerValue();
+ if(DrunkLevel < 5){
+ Player->SetTimer(SKILL_DRUNKEN, (DrunkLevel + 1), 120, 120, -1);
+ }
+ Talk(CreatureID, TALK_SAY, NULL, "Aah...", false);
+ break;
+ }
+
+ case LIQUID_SLIME:{
+ Change(Obj, CONTAINERLIQUIDTYPE, LIQUID_NONE);
+ Player->Damage(NULL, 200, DAMAGE_POISON_PERIODIC);
+ Talk(CreatureID, TALK_SAY, NULL, "Urgh!", false);
+ break;
+ }
+
+ case LIQUID_URINE:{
+ Change(Obj, CONTAINERLIQUIDTYPE, LIQUID_NONE);
+ Talk(CreatureID, TALK_SAY, NULL, "Urgh!", false);
+ break;
+ }
+
+ case LIQUID_MANA:
+ case LIQUID_LIFE:{
+ DrinkPotion(CreatureID, Obj);
+ Talk(CreatureID, TALK_SAY, NULL, "Aaaah...", false);
+ break;
+ }
+
+ case LIQUID_LEMONADE:{
+ Change(Obj, CONTAINERLIQUIDTYPE, LIQUID_NONE);
+ Talk(CreatureID, TALK_SAY, NULL, "Mmmh.", false);
+ break;
+ }
+
+ default:{
+ Change(Obj, CONTAINERLIQUIDTYPE, LIQUID_NONE);
+ Talk(CreatureID, TALK_SAY, NULL, "Gulp.", false);
+ break;
+ }
+ }
+}
+
+void UseFood(uint32 CreatureID, Object Obj){
+ if(!Obj.exists()){
+ error("UseFood: Übergebenes Objekt existiert nicht.\n");
+ throw ERROR;
+ }
+
+ ObjectType ObjType = Obj.getObjectType();
+ if(!ObjType.getFlag(FOOD)){
+ error("UseFood: Übergebenes Objekt ist kein Nahrungsmittel.\n");
+ throw ERROR;
+ }
+
+ TPlayer *Player = GetPlayer(CreatureID);
+ if(Player == NULL){
+ error("UseFood: Kreatur %u existiert nicht.\n", CreatureID);
+ throw ERROR;
+ }
+
+ int ObjFoodTime = (int)ObjType.getAttribute(NUTRITION) * 12;
+ int CurFoodTime = Player->Skills[SKILL_FED]->TimerValue();
+ int MaxFoodTime = Player->Skills[SKILL_FED]->Max;
+ if((CurFoodTime + ObjFoodTime) > MaxFoodTime){
+ throw FEDUP;
+ }
+
+ Player->SetTimer(SKILL_FED, (CurFoodTime + ObjFoodTime), 0, 0, -1);
+ Delete(Obj, -1);
+}
+
+void UseTextObject(uint32 CreatureID, Object Obj){
+ if(!Obj.exists()){
+ error("UseTextObject: Übergebenes Objekt existiert nicht.\n");
+ throw ERROR;
+ }
+
+ ObjectType ObjType = Obj.getObjectType();
+ if(!ObjType.getFlag(TEXT)){
+ error("UseTextObject: Übergebenes Objekt ist kein Schriftstück.\n");
+ throw ERROR;
+ }
+
+ TPlayer *Player = GetPlayer(CreatureID);
+ if(Player == NULL){
+ error("UseTextObject: Kreatur %u existiert nicht.\n", CreatureID);
+ throw ERROR;
+ }
+
+ SendEditText(Player->Connection, Obj);
+}
+
+void UseAnnouncer(uint32 CreatureID, Object Obj){
+ if(!Obj.exists()){
+ error("UseAnnouncer: Übergebenes Objekt existiert nicht.\n");
+ throw ERROR;
+ }
+
+ ObjectType ObjType = Obj.getObjectType();
+ if(!ObjType.getFlag(INFORMATION)){
+ error("UseAnnouncer: Übergebenes Objekt liefert keine Informationen.\n");
+ throw ERROR;
+ }
+
+ TPlayer *Player = GetPlayer(CreatureID);
+ if(Player == NULL){
+ error("UseAnnouncer: Kreatur %d existiert nicht.\n", CreatureID);
+ throw ERROR;
+ }
+
+ int Information = (int)ObjType.getAttribute(INFORMATIONTYPE);
+ switch(Information){
+ case 1:{ // INFORMATION_DATETIME
+ int Year, Cycle, Day, Hour, Minute;
+ GetDate(&Year, &Cycle, &Day);
+ GetTime(&Hour, &Minute);
+ SendMessage(Player->Connection, TALK_INFO_MESSAGE,
+ "It is the %dth day of the %dth cycle in the year %d. The time is %d:%.2d.",
+ Day, Cycle, Year, Hour, Minute);
+ break;
+ }
+
+ case 2:{ // INFORMATION_TIME
+ int Hour, Minute;
+ GetTime(&Hour, &Minute);
+ SendMessage(Player->Connection, TALK_INFO_MESSAGE,
+ "The time is %d:%.2d.", Hour, Minute);
+ break;
+ }
+
+ case 3:{ // INFORMATION_BLESSINGS
+ int NumBlessings = 0;
+ char Help[256] = {};
+ strcpy(Help, "Received blessings:");
+
+ if(Player->GetQuestValue(101) != 0){
+ strcat(Help, "\nWisdom of Solitude");
+ NumBlessings += 1;
+ }
+
+ if(Player->GetQuestValue(102) != 0){
+ strcat(Help, "\nSpark of the Phoenix");
+ NumBlessings += 1;
+ }
+
+ if(Player->GetQuestValue(103) != 0){
+ strcat(Help, "\nFire of the Suns");
+ NumBlessings += 1;
+ }
+
+ if(Player->GetQuestValue(104) != 0){
+ strcat(Help, "\nSpiritual Shielding");
+ NumBlessings += 1;
+ }
+
+ if(Player->GetQuestValue(105) != 0){
+ strcat(Help, "\nEmbrace of Tibia");
+ NumBlessings += 1;
+ }
+
+ if(NumBlessings == 0){
+ strcpy(Help, "No blessings received.");
+ }
+
+ SendMessage(Player->Connection, TALK_INFO_MESSAGE, "%s", Help);
+ break;
+ }
+
+ case 4:{ // INFORMATION_SPELLBOOK
+ SendEditText(Player->Connection, Obj);
+ break;
+ }
+
+ default:{
+ error("UseAnnouncer: Ungültiger Informationstyp %d.\n", Information);
+ break;
+ }
+ }
+}
+
+void UseKeyDoor(uint32 CreatureID, Object Key, Object Door){
+ if(!Key.exists()){
+ error("UseKeyDoor: Übergebenes Objekt Key existiert nicht.\n");
+ throw ERROR;
+ }
+
+ if(!Door.exists()){
+ error("UseKeyDoor: Übergebenes Objekt Door existiert nicht.\n");
+ throw ERROR;
+ }
+
+ ObjectType KeyType = Key.getObjectType();
+ if(!KeyType.getFlag(KEY)){
+ error("UseKeyDoor: Übergebenes Objekt ist kein Schlüssel.\n");
+ throw ERROR;
+ }
+
+ ObjectType DoorType = Door.getObjectType();
+ if(!DoorType.getFlag(KEYDOOR)){
+ throw NOTUSABLE;
+ }
+
+ int KeyNumber = (int)Key.getAttribute(KEYNUMBER);
+ int KeyHoleNumber = (int)Door.getAttribute(KEYHOLENUMBER);
+ if(KeyNumber == 0 || KeyHoleNumber == 0 || KeyNumber != KeyHoleNumber){
+ throw NOKEYMATCH;
+ }
+
+ ObjectType KeyDoorTarget = (int)DoorType.getAttribute(KEYDOORTARGET);
+ if(KeyDoorTarget.isMapContainer()){
+ error("UseKeyDoor: Zieltür für Tür %d nicht spezifiziert.\n",
+ DoorType.TypeID);
+ throw ERROR;
+ }
+
+ if(KeyDoorTarget.getFlag(UNPASS)){
+ ClearField(Door, NONE);
+ }
+
+ Change(Door, KeyDoorTarget, 0);
+}
+
+void UseNameDoor(uint32 CreatureID, Object Door){
+ if(!Door.exists()){
+ error("UseNameDoor: Übergebenes Objekt Door existiert nicht.\n");
+ throw ERROR;
+ }
+
+ ObjectType DoorType = Door.getObjectType();
+ if(!DoorType.getFlag(NAMEDOOR)){
+ error("UseNameDoor: Übergebenes Objekt Door ist keine beschriftete Tür.\n");
+ throw ERROR;
+ }
+
+ if(!DoorType.getFlag(TEXT)){
+ error("UseNameDoor: Übergebenes Objekt Door trägt keinen Text.\n");
+ throw ERROR;
+ }
+
+ TPlayer *Player = GetPlayer(CreatureID);
+ if(Player == NULL){
+ error("UseNameDoor: Spieler existiert nicht.\n");
+ throw ERROR;
+ }
+
+ int DoorX, DoorY, DoorZ;
+ GetObjectCoordinates(Door, &DoorX, &DoorY, &DoorZ);
+
+ uint16 HouseID = GetHouseID(DoorX, DoorY, DoorZ);
+ if(HouseID == 0){
+ error("UseNameDoor: Koordinate [%d,%d,%d] gehört zu keinem Haus.\n",
+ DoorX, DoorY, DoorZ);
+ throw ERROR;
+ }
+
+ if(!IsOwner(HouseID, Player)
+ && !CheckRight(CreatureID, OPEN_NAMEDOORS)
+ && !MayOpenDoor(Door, Player)){
+ throw NOTACCESSIBLE;
+ }
+
+ ObjectType NameDoorTarget = (int)DoorType.getAttribute(NAMEDOORTARGET);
+ if(NameDoorTarget.isMapContainer()){
+ error("UseNameDoor: Zieltür für Tür %d nicht spezifiziert.\n",
+ DoorType.TypeID);
+ throw ERROR;
+ }
+
+ if(NameDoorTarget.getFlag(UNPASS)){
+ ClearField(Door, NONE);
+ }
+
+ Change(Door, NameDoorTarget, 0);
+}
+
+void UseLevelDoor(uint32 CreatureID, Object Door){
+ if(!Door.exists() || !Door.getObjectType().getFlag(LEVELDOOR)
+ || !Door.getContainer().getObjectType().isMapContainer()){
+ error("UseLevelDoor: Übergebenes Objekt Door ist keine Level-Tür.\n");
+ throw ERROR;
+ }
+
+ TPlayer *Player = GetPlayer(CreatureID);
+ if(Player == NULL){
+ error("UseLevelDoor: Spieler existiert nicht.\n");
+ throw ERROR;
+ }
+
+ ObjectType DoorType = Door.getObjectType();
+ if(!DoorType.getFlag(UNPASS)){
+ throw NOTUSABLE;
+ }
+
+ int DoorLevel = (int)Door.getAttribute(DOORLEVEL);
+ int PlayerLevel = Player->Skills[SKILL_LEVEL]->Get();
+ if(PlayerLevel < DoorLevel){
+ SendMessage(Player->Connection, TALK_INFO_MESSAGE, "%s.", GetInfo(Door));
+ return;
+ }
+
+ ObjectType LevelDoorTarget = (int)DoorType.getAttribute(LEVELDOORTARGET);
+ if(LevelDoorTarget.isMapContainer() || LevelDoorTarget.getFlag(UNPASS)){
+ error("UseLevelDoor: Zieltür für Tür %d nicht spezifiziert oder nicht passierbar.\n",
+ DoorType.TypeID);
+ throw ERROR;
+ }
+
+ Change(Door, LevelDoorTarget, 0);
+ Move(0, Player->CrObject, Door.getContainer(), -1, false, NONE);
+}
+
+void UseQuestDoor(uint32 CreatureID, Object Door){
+ if(!Door.exists() || !Door.getObjectType().getFlag(QUESTDOOR)
+ || !Door.getContainer().getObjectType().isMapContainer()){
+ error("UseQuestDoor: Übergebenes Objekt Door ist keine Quest-Tür.\n");
+ throw ERROR;
+ }
+
+ TPlayer *Player = GetPlayer(CreatureID);
+ if(Player == NULL){
+ error("UseQuestDoor: Spieler existiert nicht.\n");
+ throw ERROR;
+ }
+
+ ObjectType DoorType = Door.getObjectType();
+ if(!DoorType.getFlag(UNPASS)){
+ throw NOTUSABLE;
+ }
+
+ int QuestNr = Door.getAttribute(DOORQUESTNUMBER);
+ int QuestValue = Door.getAttribute(DOORQUESTVALUE);
+ if(Player->GetQuestValue(QuestNr) != QuestValue){
+ SendMessage(Player->Connection, TALK_INFO_MESSAGE, "%s.", GetInfo(Door));
+ return;
+ }
+
+ ObjectType QuestDoorTarget = (int)DoorType.getAttribute(QUESTDOORTARGET);
+ if(QuestDoorTarget.isMapContainer() || QuestDoorTarget.getFlag(UNPASS)){
+ error("UseQuestDoor: Zieltür für Tür %d nicht spezifiziert oder nicht passierbar.\n",
+ DoorType.TypeID);
+ throw ERROR;
+ }
+
+ Change(Door, QuestDoorTarget, 0);
+ Move(0, Player->CrObject, Door.getContainer(), -1, false, NONE);
+}
+
+void UseWeapon(uint32 CreatureID, Object Weapon, Object Target){
+ if(!Weapon.exists() || !Weapon.getObjectType().isCloseWeapon()){
+ error("UseWeapon: Übergebene Waffe existiert nicht oder ist keine Waffe.\n");
+ throw ERROR;
+ }
+
+ if(!Target.exists() || !Target.getObjectType().getFlag(DESTROY)){
+ error("UseWeapon: Übergebenes Ziel existiert nicht oder ist nicht zerstörbar.\n");
+ throw ERROR;
+ }
+
+ TPlayer *Player = GetPlayer(CreatureID);
+ if(Player == NULL){
+ error("UseWeapon: Spieler %d existiert nicht.\n", CreatureID);
+ throw ERROR;
+ }
+
+ if(!Target.getContainer().getObjectType().isMapContainer()){
+ throw NOTACCESSIBLE;
+ }
+
+ GraphicalEffect(Target, EFFECT_POFF);
+ if(random(1, 3) == 1){
+ // TODO(fusion): This is very similar to what is done in `ProcessCronSystem`
+ // and it is probably some inlined helper function to transform items that
+ // might be containers.
+ ObjectType TargetType = Target.getObjectType();
+ ObjectType DestroyTarget = (int)TargetType.getAttribute(DESTROYTARGET);
+ if(TargetType.getFlag(CONTAINER)){
+ int Remainder = 0;
+ if(!DestroyTarget.isMapContainer() && DestroyTarget.getFlag(CONTAINER)){
+ Remainder = (int)DestroyTarget.getAttribute(CAPACITY);
+ }
+
+ Empty(Target, Remainder);
+ }
+ Change(Target, DestroyTarget, 0);
+ }
+}
+
+void UseChangeObject(uint32 CreatureID, Object Obj){
+ if(!Obj.exists() || !Obj.getObjectType().getFlag(CHANGEUSE)){
+ error("UseChangeObject: Objekt existiert nicht oder ist kein CHANGEUSE-Objekt.\n");
+ throw ERROR;
+ }
+
+ TPlayer *Player = GetPlayer(CreatureID);
+ if(Player == NULL){
+ error("UseChangeObject: Spieler %d existiert nicht.\n", CreatureID);
+ throw ERROR;
+ }
+
+ ObjectType ObjType = Obj.getObjectType();
+ ObjectType ChangeTarget = (int)ObjType.getAttribute(CHANGETARGET);
+ if(!ObjType.getFlag(UNPASS)
+ && !ChangeTarget.isMapContainer()
+ && ChangeTarget.getFlag(UNPASS)){
+ ClearField(Obj, NONE);
+ }else if(!ObjType.getFlag(UNLAY)
+ && !ChangeTarget.isMapContainer()
+ && ChangeTarget.getFlag(UNLAY)){
+ // TODO(fusion): This is similar to `ClearField` except we look for an
+ // field without `UNLAY`. It is probably an inlined function.
+ int ObjX, ObjY, ObjZ;
+ GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
+
+ int OffsetX[4] = { 1, 0, -1, 0};
+ int OffsetY[4] = { 0, 1, 0, -1};
+ for(int i = 0; i < 4; i += 1){
+ int DestX = ObjX + OffsetX[i];
+ int DestY = ObjY + OffsetY[i];
+ int DestZ = ObjZ;
+ if(CoordinateFlag(DestX, DestY, DestZ, BANK)
+ && !CoordinateFlag(DestX, DestY, DestZ, UNPASS)){
+ Object Dest = GetMapContainer(DestX, DestY, DestZ);
+ MoveAllObjects(Obj.getNextObject(), Dest, NONE, true);
+ break;
+ }
+ }
+ }
+
+ Change(Obj, ChangeTarget, 0);
+}
+
+void UseObject(uint32 CreatureID, Object Obj){
+ if(!Obj.exists()){
+ error("UseObjects: Übergebenes Objekt existiert nicht.\n");
+ throw ERROR;
+ }
+
+ if(!Obj.getObjectType().getFlag(USEEVENT)){
+ error("UseObjects: Übergebenes Objekt ist nicht benutzbar.\n");
+ throw ERROR;
+ }
+
+ Object User = NONE;
+ if(CreatureID != 0){
+ TCreature *Creature = GetCreature(CreatureID);
+ if(Creature != NULL){
+ User = Creature->CrObject;
+ }
+ }
+
+ if(!HandleEvent(MOVEUSE_EVENT_USE, User, Obj, NONE)){
+ throw NOTUSABLE;
+ }
+}
+
+void UseObjects(uint32 CreatureID, Object Obj1, Object Obj2){
+ if(!Obj1.exists()){
+ error("UseObjects: Übergebenes Objekt Obj1 existiert nicht.\n");
+ throw ERROR;
+ }
+
+ if(!Obj2.exists()){
+ error("UseObjects: Übergebenes Objekt Obj2 existiert nicht.\n");
+ throw ERROR;
+ }
+
+ if(!Obj1.getObjectType().getFlag(USEEVENT)){
+ error("UseObjects: Übergebenes Objekt Obj1 ist nicht benutzbar.\n");
+ throw ERROR;
+ }
+
+ Object User = NONE;
+ if(CreatureID != 0){
+ TCreature *Creature = GetCreature(CreatureID);
+ if(Creature != NULL){
+ User = Creature->CrObject;
+ }
+ }
+
+ if(!HandleEvent(MOVEUSE_EVENT_MULTIUSE, User, Obj1, Obj2)){
+ throw NOTUSABLE;
+ }
+}
+
+void MovementEvent(Object Obj, Object Start, Object Dest){
+ if(!Obj.exists()){
+ error("MovementEvent: Übergebenes Objekt existiert nicht.\n");
+ throw ERROR;
+ }
+
+ ObjectType StartType = Start.getObjectType();
+ if(!Start.exists() || (!StartType.getFlag(CONTAINER) && !StartType.getFlag(CHEST))){
+ error("MovementEvent: \"Start\" ist kein Container.\n");
+ throw ERROR;
+ }
+
+ ObjectType DestType = Dest.getObjectType();
+ if(!Dest.exists() || (!DestType.getFlag(CONTAINER) && !DestType.getFlag(CHEST))){
+ error("MovementEvent: \"Dest\" ist kein Container.\n");
+ throw ERROR;
+ }
+
+ if(Obj.getObjectType().getFlag(MOVEMENTEVENT)){
+ HandleEvent(MOVEUSE_EVENT_MOVEMENT, NONE, Obj, NONE);
+ if(!Obj.exists()){
+ throw DESTROYED;
+ }
+ }
+}
+
+void SeparationEvent(Object Obj, Object Start){
+ if(!Obj.exists()){
+ error("SeparationEvent: Übergebenes Objekt existiert nicht.\n");
+ throw ERROR;
+ }
+
+ if(!Start.exists()){
+ error("SeparationEvent: Übergebener Container existiert nicht.\n");
+ throw ERROR;
+ }
+
+ ObjectType StartType = Start.getObjectType();
+ if(!StartType.isMapContainer()){
+ return;
+ }
+
+ // NOTE(fusion): Separation event for `Obj` against objects at `Start`.
+ ObjectType ObjType = Obj.getObjectType();
+ if(ObjType.getFlag(SEPARATIONEVENT)){
+ Object Help = GetFirstContainerObject(Start);
+ while(Help != NONE){
+ Object Next = Help.getNextObject();
+ if(Help != Obj){
+ HandleEvent(MOVEUSE_EVENT_SEPARATION, NONE, Obj, Help);
+ if(!Obj.exists()){
+ throw DESTROYED;
+ }
+ }
+ Help = Next;
+ }
+ }
+
+ // NOTE(fusion): Separation event for objects at `Start` against `Obj`.
+ Object Help = GetFirstContainerObject(Start);
+ while(Help != NONE){
+ Object Next = Help.getNextObject();
+ if(Help != Obj){
+ ObjectType HelpType = Help.getObjectType();
+ if(ObjType.isCreatureContainer()
+ && (HelpType.getFlag(LEVELDOOR) || HelpType.getFlag(QUESTDOOR))){
+ ObjectType DoorTarget = HelpType.getFlag(LEVELDOOR)
+ ? (int)HelpType.getAttribute(LEVELDOORTARGET)
+ : (int)HelpType.getAttribute(QUESTDOORTARGET);
+ if(DoorTarget.isMapContainer() || DoorTarget.getFlag(UNPASS)){
+ error("SeparationEvent: Zieltür für Tür %d nicht spezifiziert oder passierbar.\n",
+ HelpType.TypeID);
+ throw ERROR;
+ }
+
+ ClearField(Help, Obj);
+ Change(Help, DoorTarget, 0);
+ break;
+ }
+
+ if(HelpType.getFlag(SEPARATIONEVENT)){
+ HandleEvent(MOVEUSE_EVENT_SEPARATION, NONE, Help, Obj);
+ if(!Obj.exists()){
+ throw DESTROYED;
+ }
+ }
+ }
+ Help = Next;
+ }
+}
+
+void CollisionEvent(Object Obj, Object Dest){
+ if(!Obj.exists()){
+ error("CollisionEvent: Übergebenes Objekt existiert nicht.\n");
+ throw ERROR;
+ }
+
+ if(!Dest.exists()){
+ error("CollisionEvent: Übergebener Container existiert nicht.\n");
+ throw ERROR;
+ }
+
+ ObjectType DestType = Dest.getObjectType();
+ if(!DestType.isMapContainer()){
+ return;
+ }
+
+ ObjectType ObjType = Obj.getObjectType();
+ if(ObjType.getFlag(TELEPORTABSOLUTE) || ObjType.getFlag(TELEPORTRELATIVE)){
+ int TeleportEffect;
+ int TeleportDestX, TeleportDestY, TeleportDestZ;
+ if(ObjType.getFlag(TELEPORTABSOLUTE)){
+ UnpackAbsoluteCoordinate((int)Obj.getAttribute(ABSTELEPORTDESTINATION),
+ &TeleportDestX, &TeleportDestY, &TeleportDestZ);
+ TeleportEffect = (int)ObjType.getAttribute(ABSTELEPORTEFFECT);
+ }else{
+ int DisplacementX, DisplacementY, DisplacementZ;
+ GetObjectCoordinates(Obj, &TeleportDestX, &TeleportDestY, &TeleportDestZ);
+ UnpackRelativeCoordinate((int)ObjType.getAttribute(RELTELEPORTDISPLACEMENT),
+ &DisplacementX, &DisplacementY, &DisplacementZ);
+ TeleportDestX += DisplacementX;
+ TeleportDestY += DisplacementY;
+ TeleportDestZ += DisplacementZ;
+ TeleportEffect = (int)ObjType.getAttribute(RELTELEPORTEFFECT);
+ }
+
+ Object TeleportDest = GetMapContainer(TeleportDestX, TeleportDestY, TeleportDestZ);
+ MoveAllObjects(Obj.getNextObject(), TeleportDest, NONE, true);
+ GraphicalEffect(TeleportDestX, TeleportDestY, TeleportDestZ, TeleportEffect);
+
+ // TODO(fusion): Is this even possible? Maybe `MoveAllObjects` could
+ // trigger a separation event that destroys `Obj`?
+ if(!Obj.exists()){
+ throw DESTROYED;
+ }
+ }else{
+ // NOTE(fusion): Collision event for `Obj` against objects at `Dest`.
+ if(ObjType.getFlag(COLLISIONEVENT)){
+ Object Help = GetFirstContainerObject(Dest);
+ while(Help != NONE){
+ Object Next = Help.getNextObject();
+ if(Help != Obj){
+ HandleEvent(MOVEUSE_EVENT_COLLISION, NONE, Obj, Help);
+ if(!Obj.exists()){
+ throw DESTROYED;
+ }
+ }
+ Help = Next;
+ }
+ }
+
+ // NOTE(fusion): Collision event for objects at `Dest` against `Obj`.
+ Object Help = GetFirstContainerObject(Dest);
+ while(Help != NONE){
+ Object Next = Help.getNextObject();
+ if(Help != Obj){
+ ObjectType HelpType = Help.getObjectType();
+ if(HelpType.getFlag(TELEPORTABSOLUTE) || HelpType.getFlag(TELEPORTRELATIVE)){
+ int TeleportEffect;
+ int TeleportDestX, TeleportDestY, TeleportDestZ;
+ if(HelpType.getFlag(TELEPORTABSOLUTE)){
+ UnpackAbsoluteCoordinate((int)Help.getAttribute(ABSTELEPORTDESTINATION),
+ &TeleportDestX, &TeleportDestY, &TeleportDestZ);
+ TeleportEffect = (int)HelpType.getAttribute(ABSTELEPORTEFFECT);
+ }else{
+ int DisplacementX, DisplacementY, DisplacementZ;
+ GetObjectCoordinates(Help, &TeleportDestX, &TeleportDestY, &TeleportDestZ);
+ UnpackRelativeCoordinate((int)HelpType.getAttribute(RELTELEPORTDISPLACEMENT),
+ &DisplacementX, &DisplacementY, &DisplacementZ);
+ TeleportDestX += DisplacementX;
+ TeleportDestY += DisplacementY;
+ TeleportDestZ += DisplacementZ;
+ TeleportEffect = (int)HelpType.getAttribute(RELTELEPORTEFFECT);
+ }
+
+ Object TeleportDest = GetMapContainer(TeleportDestX, TeleportDestY, TeleportDestZ);
+ MoveOneObject(Obj, TeleportDest);
+ GraphicalEffect(TeleportDestX, TeleportDestY, TeleportDestZ, TeleportEffect);
+ }else if(HelpType.getFlag(COLLISIONEVENT)){
+ HandleEvent(MOVEUSE_EVENT_COLLISION, NONE, Help, Obj);
+ }
+
+ if(!Obj.exists()){
+ throw DESTROYED;
+ }
+ }
+ Help = Next;
+ }
+ }
+}
+
+// Event Loading / Initialization
+// =============================================================================
+void LoadParameters(TReadScriptFile *Script, int *Parameters, int NumberOfParameters, ...){
+ if(NumberOfParameters > MOVEUSE_MAX_PARAMETERS){
+ error("LoadParameters: Zu viele Parameter (%d).\n", NumberOfParameters);
+ Script->error("too many parameters");
+ }
+
+ if(NumberOfParameters == 0){
+ return;
+ }
+
+ if(Script->Token != SPECIAL || Script->getSpecial() != '('){
+ Script->error("'(' expected");
+ }
+
+ va_list ap;
+ va_start(ap, NumberOfParameters);
+ for(int i = 0; i < NumberOfParameters; i += 1){
+ if(i > 0){
+ Script->readSymbol(',');
+ }
+
+ int ParamType = va_arg(ap, int);
+ switch(ParamType){
+ case MOVEUSE_PARAMETER_OBJECT:{
+ const char *Object = Script->readIdentifier();
+ if(strcmp(Object, "null") == 0){
+ Parameters[i] = 0; // MOVEUSE_OBJECT_NULL ?
+ }else if(strcmp(Object, "obj1") == 0){
+ Parameters[i] = 1; // MOVEUSE_OBJECT_1 ?
+ }else if(strcmp(Object, "obj2") == 0){
+ Parameters[i] = 2; // MOVEUSE_OBJECT_2 ?
+ }else if(strcmp(Object, "user") == 0){
+ Parameters[i] = 3; // MOVEUSE_OBJECT_USER ?
+ }else if(strcmp(Object, "temp") == 0){
+ Parameters[i] = 4; // MOVEUSE_OBJECT_TEMP ?
+ }else{
+ Script->error("Object expected");
+ }
+ break;
+ }
+
+ case MOVEUSE_PARAMETER_TYPE:{
+ int TypeID = Script->readNumber();
+ Parameters[i] = TypeID;
+ if(!ObjectTypeExists(TypeID)){
+ Script->error("Unknown object type");
+ }
+ break;
+ }
+
+ case MOVEUSE_PARAMETER_FLAG:{
+ int Flag = GetFlagByName(Script->readIdentifier());
+ Parameters[i] = Flag;
+ if(Flag == -1){
+ Script->error("Unknown flag");
+ }
+ break;
+ }
+
+ case MOVEUSE_PARAMETER_TYPEATTRIBUTE:{
+ int TypeAttribute = GetTypeAttributeByName(Script->readIdentifier());
+ Parameters[i] = TypeAttribute;
+ if(TypeAttribute == -1){
+ Script->error("Unknown type attribute");
+ }
+ break;
+ }
+
+ case MOVEUSE_PARAMETER_INSTANCEATTRIBUTE:{
+ int InstanceAttribute = GetInstanceAttributeByName(Script->readIdentifier());
+ Parameters[i] = InstanceAttribute;
+ if(InstanceAttribute == -1){
+ Script->error("Unknown instance attribute");
+ }
+ break;
+ }
+
+ case MOVEUSE_PARAMETER_COORDINATE:{
+ int AbsX, AbsY, AbsZ;
+ Script->readCoordinate(&AbsX, &AbsY, &AbsZ);
+ Parameters[i] = PackAbsoluteCoordinate(AbsX, AbsY, AbsZ);
+ break;
+ }
+
+ case MOVEUSE_PARAMETER_VECTOR:{
+ int RelX, RelY, RelZ;
+ Script->readCoordinate(&RelX, &RelY, &RelZ);
+ Parameters[i] = PackRelativeCoordinate(RelX, RelY, RelZ);
+ break;
+ }
+
+ case MOVEUSE_PARAMETER_RIGHT:{
+ const char *Right = Script->getIdentifier();
+ if(strcmp(Right, "premium_account") == 0){
+ Parameters[i] = PREMIUM_ACCOUNT;
+ }else if(strcmp(Right, "special_moveuse") == 0){
+ Parameters[i] = SPECIAL_MOVEUSE;
+ }else{
+ Script->error("Unknown right");
+ }
+ break;
+ }
+
+ case MOVEUSE_PARAMETER_SKILL:{
+ int SkillNr = GetSkillByName(Script->readIdentifier());
+ Parameters[i] = SkillNr;
+ if(SkillNr == -1){
+ Script->error("Unknown skill");
+ }
+ break;
+ }
+
+ case MOVEUSE_PARAMETER_NUMBER:{
+ Parameters[i] = Script->readNumber();
+ break;
+ }
+
+ case MOVEUSE_PARAMETER_TEXT:{
+ const char *Text = Script->readString();
+ Parameters[i] = AddDynamicString(Text);
+ break;
+ }
+
+ case MOVEUSE_PARAMETER_COMPARISON:{
+ int Operator = (int)Script->readSpecial();
+ Parameters[i] = Operator;
+ if(strchr("<=>GLN", Operator) == NULL){
+ Script->error("Unknown comparison operator");
+ }
+ break;
+ }
+ }
+ }
+ va_end(ap);
+
+ Script->readSymbol(')');
+ Script->nextToken();
+}
+
+void LoadCondition(TReadScriptFile *Script, TMoveUseCondition *Condition){
+ char Identifier[MAX_IDENT_LENGTH];
+ strcpy(Identifier, Script->getIdentifier());
+
+ Script->nextToken();
+ if(strcmp(Identifier, "isposition") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_ISPOSITION;
+ LoadParameters(Script, Condition->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_COORDINATE);
+ }else if(strcmp(Identifier, "istype") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_ISTYPE;
+ LoadParameters(Script, Condition->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_TYPE);
+ }else if(strcmp(Identifier, "iscreature") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_ISCREATURE;
+ LoadParameters(Script, Condition->Parameters, 1,
+ MOVEUSE_PARAMETER_OBJECT);
+ }else if(strcmp(Identifier, "isplayer") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_ISPLAYER;
+ LoadParameters(Script, Condition->Parameters, 1,
+ MOVEUSE_PARAMETER_OBJECT);
+ }else if(strcmp(Identifier, "hasflag") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_HASFLAG;
+ LoadParameters(Script, Condition->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_FLAG);
+ }else if(strcmp(Identifier, "hastypeattribute") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_HASTYPEATTRIBUTE;
+ LoadParameters(Script, Condition->Parameters, 4,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_TYPEATTRIBUTE,
+ MOVEUSE_PARAMETER_COMPARISON,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "hasinstanceattribute") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_HASINSTANCEATTRIBUTE;
+ LoadParameters(Script, Condition->Parameters, 4,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_INSTANCEATTRIBUTE,
+ MOVEUSE_PARAMETER_COMPARISON,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "hastext") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_HASTEXT;
+ LoadParameters(Script, Condition->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_TEXT);
+ }else if(strcmp(Identifier, "ispeaceful") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_ISPEACEFUL;
+ LoadParameters(Script, Condition->Parameters, 1,
+ MOVEUSE_PARAMETER_OBJECT);
+ }else if(strcmp(Identifier, "maylogout") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_MAYLOGOUT;
+ LoadParameters(Script, Condition->Parameters, 1,
+ MOVEUSE_PARAMETER_OBJECT);
+ }else if(strcmp(Identifier, "hasprofession") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_HASPROFESSION;
+ LoadParameters(Script, Condition->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "haslevel") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_HASLEVEL;
+ LoadParameters(Script, Condition->Parameters, 3,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_COMPARISON,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "hasright") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_HASRIGHT;
+ LoadParameters(Script, Condition->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_RIGHT);
+ }else if(strcmp(Identifier, "hasquestvalue") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_HASQUESTVALUE;
+ LoadParameters(Script, Condition->Parameters, 4,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_NUMBER,
+ MOVEUSE_PARAMETER_COMPARISON,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "testskill") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_TESTSKILL;
+ LoadParameters(Script, Condition->Parameters, 4,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_SKILL,
+ MOVEUSE_PARAMETER_NUMBER,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "countobjects") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_COUNTOBJECTS;
+ LoadParameters(Script, Condition->Parameters, 3,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_COMPARISON,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "countobjectsonmap") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_COUNTOBJECTSONMAP;
+ LoadParameters(Script, Condition->Parameters, 3,
+ MOVEUSE_PARAMETER_COORDINATE,
+ MOVEUSE_PARAMETER_COMPARISON,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "isobjectthere") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_ISOBJECTTHERE;
+ LoadParameters(Script, Condition->Parameters, 2,
+ MOVEUSE_PARAMETER_COORDINATE,
+ MOVEUSE_PARAMETER_TYPE);
+ }else if(strcmp(Identifier, "iscreaturethere") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_ISCREATURETHERE;
+ LoadParameters(Script, Condition->Parameters, 1,
+ MOVEUSE_PARAMETER_COORDINATE);
+ }else if(strcmp(Identifier, "isplayerthere") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_ISPLAYERTHERE;
+ LoadParameters(Script, Condition->Parameters, 1,
+ MOVEUSE_PARAMETER_COORDINATE);
+ }else if(strcmp(Identifier, "isobjectininventory") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_ISOBJECTININVENTORY;
+ LoadParameters(Script, Condition->Parameters, 3,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_TYPE,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "isprotectionzone") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_ISPROTECTIONZONE;
+ LoadParameters(Script, Condition->Parameters, 1,
+ MOVEUSE_PARAMETER_OBJECT);
+ }else if(strcmp(Identifier, "ishouse") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_ISHOUSE;
+ LoadParameters(Script, Condition->Parameters, 1,
+ MOVEUSE_PARAMETER_OBJECT);
+ }else if(strcmp(Identifier, "ishouseowner") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_ISHOUSEOWNER;
+ LoadParameters(Script, Condition->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_OBJECT);
+ }else if(strcmp(Identifier, "isdressed") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_ISDRESSED;
+ LoadParameters(Script, Condition->Parameters, 1,
+ MOVEUSE_PARAMETER_OBJECT);
+ }else if(strcmp(Identifier, "random") == 0){
+ Condition->Condition = MOVEUSE_CONDITION_RANDOM;
+ LoadParameters(Script, Condition->Parameters, 1,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else{
+ Script->error("invalid condition");
+ }
+}
+
+void LoadAction(TReadScriptFile *Script, TMoveUseAction *Action){
+ char Identifier[MAX_IDENT_LENGTH];
+ strcpy(Identifier, Script->getIdentifier());
+
+ Script->nextToken();
+ if(strcmp(Identifier, "createonmap") == 0){
+ Action->Action = MOVEUSE_ACTION_CREATEONMAP;
+ LoadParameters(Script, Action->Parameters, 3,
+ MOVEUSE_PARAMETER_COORDINATE,
+ MOVEUSE_PARAMETER_TYPE,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "create") == 0){
+ Action->Action = MOVEUSE_ACTION_CREATE;
+ LoadParameters(Script, Action->Parameters, 3,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_TYPE,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "monsteronmap") == 0){
+ Action->Action = MOVEUSE_ACTION_MONSTERONMAP;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_COORDINATE,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "monster") == 0){
+ Action->Action = MOVEUSE_ACTION_MONSTER;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "effectonmap") == 0){
+ Action->Action = MOVEUSE_ACTION_EFFECTONMAP;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_COORDINATE,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "effect") == 0){
+ Action->Action = MOVEUSE_ACTION_EFFECT;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "textonmap") == 0){
+ Action->Action = MOVEUSE_ACTION_TEXTONMAP;
+ LoadParameters(Script, Action->Parameters, 3,
+ MOVEUSE_PARAMETER_COORDINATE,
+ MOVEUSE_PARAMETER_TEXT,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "text") == 0){
+ Action->Action = MOVEUSE_ACTION_TEXT;
+ LoadParameters(Script, Action->Parameters, 3,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_TEXT,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "changeonmap") == 0){
+ Action->Action = MOVEUSE_ACTION_CHANGEONMAP;
+ LoadParameters(Script, Action->Parameters, 4,
+ MOVEUSE_PARAMETER_COORDINATE,
+ MOVEUSE_PARAMETER_TYPE,
+ MOVEUSE_PARAMETER_TYPE,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "change") == 0){
+ Action->Action = MOVEUSE_ACTION_CHANGE;
+ LoadParameters(Script, Action->Parameters, 3,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_TYPE,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "changerel") == 0){
+ Action->Action = MOVEUSE_ACTION_CHANGEREL;
+ LoadParameters(Script, Action->Parameters, 5,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_VECTOR,
+ MOVEUSE_PARAMETER_TYPE,
+ MOVEUSE_PARAMETER_TYPE,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "setattribute") == 0){
+ Action->Action = MOVEUSE_ACTION_SETATTRIBUTE;
+ LoadParameters(Script, Action->Parameters, 3,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_INSTANCEATTRIBUTE,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "changeattribute") == 0){
+ Action->Action = MOVEUSE_ACTION_CHANGEATTRIBUTE;
+ LoadParameters(Script, Action->Parameters, 3,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_INSTANCEATTRIBUTE,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "setquestvalue") == 0){
+ Action->Action = MOVEUSE_ACTION_SETQUESTVALUE;
+ LoadParameters(Script, Action->Parameters, 3,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_NUMBER,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "damage") == 0){
+ Action->Action = MOVEUSE_ACTION_DAMAGE;
+ LoadParameters(Script, Action->Parameters, 4,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_NUMBER,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "setstart") == 0){
+ Action->Action = MOVEUSE_ACTION_SETSTART;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_COORDINATE);
+ }else if(strcmp(Identifier, "writename") == 0){
+ Action->Action = MOVEUSE_ACTION_WRITENAME;
+ LoadParameters(Script, Action->Parameters, 3,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_TEXT,
+ MOVEUSE_PARAMETER_OBJECT);
+ }else if(strcmp(Identifier, "writetext") == 0){
+ Action->Action = MOVEUSE_ACTION_WRITETEXT;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_TEXT,
+ MOVEUSE_PARAMETER_OBJECT);
+ }else if(strcmp(Identifier, "logout") == 0){
+ Action->Action = MOVEUSE_ACTION_LOGOUT;
+ LoadParameters(Script, Action->Parameters, 1,
+ MOVEUSE_PARAMETER_OBJECT);
+ }else if(strcmp(Identifier, "moveallonmap") == 0){
+ Action->Action = MOVEUSE_ACTION_MOVEALLONMAP;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_COORDINATE,
+ MOVEUSE_PARAMETER_COORDINATE);
+ }else if(strcmp(Identifier, "moveall") == 0){
+ Action->Action = MOVEUSE_ACTION_MOVEALL;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_COORDINATE);
+ }else if(strcmp(Identifier, "moveallrel") == 0){
+ Action->Action = MOVEUSE_ACTION_MOVEALLREL;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_VECTOR);
+ }else if(strcmp(Identifier, "movetoponmap") == 0){
+ Action->Action = MOVEUSE_ACTION_MOVETOPONMAP;
+ LoadParameters(Script, Action->Parameters, 3,
+ MOVEUSE_PARAMETER_COORDINATE,
+ MOVEUSE_PARAMETER_TYPE,
+ MOVEUSE_PARAMETER_COORDINATE);
+ }else if(strcmp(Identifier, "movetop") == 0){
+ Action->Action = MOVEUSE_ACTION_MOVETOP;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_COORDINATE);
+ }else if(strcmp(Identifier, "movetoprel") == 0){
+ Action->Action = MOVEUSE_ACTION_MOVETOPREL;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_VECTOR);
+ }else if(strcmp(Identifier, "move") == 0){
+ Action->Action = MOVEUSE_ACTION_MOVE;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_COORDINATE);
+ }else if(strcmp(Identifier, "moverel") == 0){
+ Action->Action = MOVEUSE_ACTION_MOVEREL;
+ LoadParameters(Script, Action->Parameters, 3,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_VECTOR);
+ }else if(strcmp(Identifier, "retrieve") == 0){
+ Action->Action = MOVEUSE_ACTION_RETRIEVE;
+ LoadParameters(Script, Action->Parameters, 3,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_VECTOR,
+ MOVEUSE_PARAMETER_VECTOR);
+ }else if(strcmp(Identifier, "deleteallonmap") == 0){
+ Action->Action = MOVEUSE_ACTION_DELETEALLONMAP;
+ LoadParameters(Script, Action->Parameters, 1,
+ MOVEUSE_PARAMETER_COORDINATE);
+ }else if(strcmp(Identifier, "deletetoponmap") == 0){
+ Action->Action = MOVEUSE_ACTION_DELETETOPONMAP;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_COORDINATE,
+ MOVEUSE_PARAMETER_TYPE);
+ }else if(strcmp(Identifier, "deleteonmap") == 0){
+ Action->Action = MOVEUSE_ACTION_DELETEONMAP;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_COORDINATE,
+ MOVEUSE_PARAMETER_TYPE);
+ }else if(strcmp(Identifier, "delete") == 0){
+ Action->Action = MOVEUSE_ACTION_DELETE;
+ LoadParameters(Script, Action->Parameters, 1,
+ MOVEUSE_PARAMETER_OBJECT);
+ }else if(strcmp(Identifier, "deleteininventory") == 0){
+ Action->Action = MOVEUSE_ACTION_DELETEININVENTORY;
+ LoadParameters(Script, Action->Parameters, 3,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_TYPE,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "description") == 0){
+ Action->Action = MOVEUSE_ACTION_DESCRIPTION;
+ LoadParameters(Script, Action->Parameters, 2,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_OBJECT);
+ }else if(strcmp(Identifier, "loaddepot") == 0){
+ Action->Action = MOVEUSE_ACTION_LOADDEPOT;
+ LoadParameters(Script, Action->Parameters, 4,
+ MOVEUSE_PARAMETER_COORDINATE,
+ MOVEUSE_PARAMETER_TYPE,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "savedepot") == 0){
+ Action->Action = MOVEUSE_ACTION_SAVEDEPOT;
+ LoadParameters(Script, Action->Parameters, 4,
+ MOVEUSE_PARAMETER_COORDINATE,
+ MOVEUSE_PARAMETER_TYPE,
+ MOVEUSE_PARAMETER_OBJECT,
+ MOVEUSE_PARAMETER_NUMBER);
+ }else if(strcmp(Identifier, "sendmail") == 0){
+ Action->Action = MOVEUSE_ACTION_SENDMAIL;
+ LoadParameters(Script, Action->Parameters, 1,
+ MOVEUSE_PARAMETER_OBJECT);
+ }else if(strcmp(Identifier, "nop") == 0){
+ Action->Action = MOVEUSE_ACTION_NOP;
+ LoadParameters(Script, Action->Parameters, 0);
+ }else{
+ Script->error("invalid action");
+ }
+}
+
+void LoadDataBase(void){
+ print(1, "Lade Move/Use-Datenbank ...\n");
+
+ char FileName[4096];
+ snprintf(FileName, sizeof(FileName), "%s/moveuse.dat", DATAPATH);
+
+ for(int i = 0; i < NARRAY(MoveUseDatabases); i += 1){
+ MoveUseDatabases[i].NumberOfRules = 0;
+ }
+
+ TReadScriptFile Script;
+ Script.open(FileName);
+ Script.nextToken();
+ while(Script.Token != ENDOFFILE){
+ const char *Identifier = Script.getIdentifier();
+
+ if(strcmp(Identifier, "begin") == 0){
+ Script.readString();
+ continue;
+ }else if(strcmp(Identifier, "end") == 0){
+ continue;
+ }
+
+ int EventType;
+ if(strcmp(Identifier, "use") == 0){
+ EventType = MOVEUSE_EVENT_MULTIUSE;
+ }else if(strcmp(Identifier, "multiuse") == 0){
+ EventType = MOVEUSE_EVENT_MULTIUSE;
+ }else if(strcmp(Identifier, "movement") == 0){
+ EventType = MOVEUSE_EVENT_MULTIUSE;
+ }else if(strcmp(Identifier, "collision") == 0){
+ EventType = MOVEUSE_EVENT_MULTIUSE;
+ }else if(strcmp(Identifier, "separation") == 0){
+ EventType = MOVEUSE_EVENT_MULTIUSE;
+ }else{
+ Script.error("Unknown event type");
+ }
+
+ Script.readSymbol(',');
+
+ MoveUseDatabases[EventType].NumberOfRules += 1;
+ TMoveUseRule *Rule = MoveUseDatabases[EventType].Rules.at(
+ MoveUseDatabases[EventType].NumberOfRules);
+
+ // NOTE(fusion): Conditions.
+ Rule->FirstCondition = NumberOfMoveUseConditions + 1;
+ while(true){
+ Script.nextToken();
+ NumberOfMoveUseConditions += 1;
+ TMoveUseCondition *Condition = MoveUseConditions.at(NumberOfMoveUseConditions);
+ Condition->Modifier = MOVEUSE_MODIFIER_NORMAL;
+ if(Script.Token == SPECIAL){
+ if(Script.getSpecial() == '!'){
+ Script.nextToken();
+ Condition->Modifier = MOVEUSE_MODIFIER_INVERT;
+ }else if(Script.getSpecial() == '~'){
+ Script.nextToken();
+ Condition->Modifier = MOVEUSE_MODIFIER_TRUE;
+ }
+ }
+ LoadCondition(&Script, Condition);
+
+ if(Script.Token != SPECIAL || Script.getSpecial() != ','){
+ break;
+ }
+ }
+ Rule->LastCondition = NumberOfMoveUseConditions;
+
+ if(Script.Token != SPECIAL || Script.getSpecial() != 'I'){
+ Script.error("'->' expected");
+ }
+
+ // NOTE(fusion): Actions.
+ Rule->FirstAction = NumberOfMoveUseActions + 1;
+ while(true){
+ Script.nextToken();
+ NumberOfMoveUseActions += 1;
+ TMoveUseAction *Action = MoveUseActions.at(NumberOfMoveUseActions);
+ LoadAction(&Script, Action);
+
+ if(Script.Token != SPECIAL || Script.getSpecial() != ','){
+ break;
+ }
+ }
+ Rule->LastAction = NumberOfMoveUseActions;
+
+ // NOTE(fusion): Optional tag?
+ if(Script.Token == STRING){
+ Script.nextToken();
+ }
+ }
+
+ Script.close();
+
+ print(1, "Move/Use-Datenbank mit %d/%d/%d/%d/%d Regeln gelesen.\n",
+ MoveUseDatabases[MOVEUSE_EVENT_USE].NumberOfRules,
+ MoveUseDatabases[MOVEUSE_EVENT_MULTIUSE].NumberOfRules,
+ MoveUseDatabases[MOVEUSE_EVENT_MOVEMENT].NumberOfRules,
+ MoveUseDatabases[MOVEUSE_EVENT_COLLISION].NumberOfRules,
+ MoveUseDatabases[MOVEUSE_EVENT_SEPARATION].NumberOfRules);
+}
+
+void InitMoveUse(void){
+ NumberOfMoveUseConditions = 0;
+ NumberOfMoveUseActions = 0;
+ DelayedMails = 0;
+ LoadDataBase();
+}
+
+void ExitMoveUse(void){
+ for(int i = 0; i < DelayedMails; i += 1){
+ error("ExitMoveUse: Paket an %u wurde nicht zugestellt.\n",
+ DelayedMail.at(i)->CharacterID);
+ }
+}
diff --git a/src/moveuse.hh b/src/moveuse.hh
index 1036142..83d0944 100644
--- a/src/moveuse.hh
+++ b/src/moveuse.hh
@@ -2,8 +2,194 @@
#define TIBIA_MOVEUSE_HH_ 1
#include "common.hh"
+#include "containers.hh"
#include "map.hh"
+#include "script.hh"
+#define MOVEUSE_MAX_PARAMETERS 5
+
+struct TPlayerData;
+
+enum MoveUseActionType: int {
+ MOVEUSE_ACTION_CREATEONMAP = 0,
+ MOVEUSE_ACTION_CREATE = 1,
+ MOVEUSE_ACTION_MONSTERONMAP = 2,
+ MOVEUSE_ACTION_MONSTER = 3,
+ MOVEUSE_ACTION_EFFECTONMAP = 4,
+ MOVEUSE_ACTION_EFFECT = 5,
+ MOVEUSE_ACTION_TEXTONMAP = 6,
+ MOVEUSE_ACTION_TEXT = 7,
+ MOVEUSE_ACTION_CHANGEONMAP = 8,
+ MOVEUSE_ACTION_CHANGE = 9,
+ MOVEUSE_ACTION_CHANGEREL = 10,
+ MOVEUSE_ACTION_SETATTRIBUTE = 11,
+ MOVEUSE_ACTION_CHANGEATTRIBUTE = 12,
+ MOVEUSE_ACTION_SETQUESTVALUE = 13,
+ MOVEUSE_ACTION_DAMAGE = 14,
+ MOVEUSE_ACTION_SETSTART = 15,
+ MOVEUSE_ACTION_WRITENAME = 16,
+ MOVEUSE_ACTION_WRITETEXT = 17,
+ MOVEUSE_ACTION_LOGOUT = 18,
+ MOVEUSE_ACTION_MOVEALLONMAP = 19,
+ MOVEUSE_ACTION_MOVEALL = 20,
+ MOVEUSE_ACTION_MOVEALLREL = 21,
+ MOVEUSE_ACTION_MOVETOPONMAP = 22,
+ MOVEUSE_ACTION_MOVETOP = 23,
+ MOVEUSE_ACTION_MOVETOPREL = 24,
+ MOVEUSE_ACTION_MOVE = 25,
+ MOVEUSE_ACTION_MOVEREL = 26,
+ MOVEUSE_ACTION_RETRIEVE = 27,
+ MOVEUSE_ACTION_DELETEALLONMAP = 28,
+ MOVEUSE_ACTION_DELETETOPONMAP = 29,
+ MOVEUSE_ACTION_DELETEONMAP = 30,
+ MOVEUSE_ACTION_DELETE = 31,
+ MOVEUSE_ACTION_DELETEININVENTORY = 32,
+ MOVEUSE_ACTION_DESCRIPTION = 33,
+ MOVEUSE_ACTION_LOADDEPOT = 34,
+ MOVEUSE_ACTION_SAVEDEPOT = 35,
+ MOVEUSE_ACTION_SENDMAIL = 36,
+ MOVEUSE_ACTION_NOP = 37,
+};
+
+enum MoveUseConditionType: int {
+ MOVEUSE_CONDITION_ISPOSITION = 0,
+ MOVEUSE_CONDITION_ISTYPE = 1,
+ MOVEUSE_CONDITION_ISCREATURE = 2,
+ MOVEUSE_CONDITION_ISPLAYER = 3,
+ MOVEUSE_CONDITION_HASFLAG = 4,
+ MOVEUSE_CONDITION_HASTYPEATTRIBUTE = 5,
+ MOVEUSE_CONDITION_HASINSTANCEATTRIBUTE = 6,
+ MOVEUSE_CONDITION_HASTEXT = 7,
+ MOVEUSE_CONDITION_ISPEACEFUL = 8,
+ MOVEUSE_CONDITION_MAYLOGOUT = 9,
+ MOVEUSE_CONDITION_HASPROFESSION = 10,
+ MOVEUSE_CONDITION_HASLEVEL = 11,
+ MOVEUSE_CONDITION_HASRIGHT = 12,
+ MOVEUSE_CONDITION_HASQUESTVALUE = 13,
+ MOVEUSE_CONDITION_TESTSKILL = 14,
+ MOVEUSE_CONDITION_COUNTOBJECTS = 15,
+ MOVEUSE_CONDITION_COUNTOBJECTSONMAP = 16,
+ MOVEUSE_CONDITION_ISOBJECTTHERE = 17,
+ MOVEUSE_CONDITION_ISCREATURETHERE = 18,
+ MOVEUSE_CONDITION_ISPLAYERTHERE = 19,
+ MOVEUSE_CONDITION_ISOBJECTININVENTORY = 20,
+ MOVEUSE_CONDITION_ISPROTECTIONZONE = 21,
+ MOVEUSE_CONDITION_ISHOUSE = 22,
+ MOVEUSE_CONDITION_ISHOUSEOWNER = 23,
+ MOVEUSE_CONDITION_ISDRESSED = 24,
+ MOVEUSE_CONDITION_RANDOM = 25,
+};
+
+enum MoveUseEventType: int {
+ MOVEUSE_EVENT_USE = 0,
+ MOVEUSE_EVENT_MULTIUSE = 1,
+ MOVEUSE_EVENT_MOVEMENT = 2,
+ MOVEUSE_EVENT_COLLISION = 3,
+ MOVEUSE_EVENT_SEPARATION = 4,
+};
+
+enum MoveUseModifierType: int {
+ MOVEUSE_MODIFIER_NORMAL = 0,
+ MOVEUSE_MODIFIER_INVERT = 1,
+ MOVEUSE_MODIFIER_TRUE = 2,
+};
+
+enum MoveUseParameterType: int {
+ MOVEUSE_PARAMETER_OBJECT = 0,
+ MOVEUSE_PARAMETER_TYPE = 1,
+ MOVEUSE_PARAMETER_FLAG = 2,
+ MOVEUSE_PARAMETER_TYPEATTRIBUTE = 3,
+ MOVEUSE_PARAMETER_INSTANCEATTRIBUTE = 4,
+ MOVEUSE_PARAMETER_COORDINATE = 5,
+ MOVEUSE_PARAMETER_VECTOR = 6,
+ MOVEUSE_PARAMETER_RIGHT = 7,
+ MOVEUSE_PARAMETER_SKILL = 8,
+ MOVEUSE_PARAMETER_NUMBER = 9,
+ MOVEUSE_PARAMETER_TEXT = 10,
+ MOVEUSE_PARAMETER_COMPARISON = 11,
+};
+
+struct TMoveUseAction {
+ MoveUseActionType Action;
+ int Parameters[MOVEUSE_MAX_PARAMETERS];
+};
+
+struct TMoveUseRule {
+ int FirstCondition;
+ int LastCondition;
+ int FirstAction;
+ int LastAction;
+};
+
+struct TMoveUseCondition {
+ MoveUseModifierType Modifier;
+ MoveUseConditionType Condition;
+ int Parameters[MOVEUSE_MAX_PARAMETERS];
+};
+
+struct TMoveUseDatabase {
+ TMoveUseDatabase(void) : Rules(1, 100, 100), NumberOfRules(0) {}
+
+ vector<TMoveUseRule> Rules;
+ int NumberOfRules;
+};
+
+struct TDelayedMail {
+ uint32 CharacterID;
+ int DepotNumber;
+ uint8 *Packet;
+ int PacketSize;
+};
+
+int PackAbsoluteCoordinate(int x, int y, int z);
+void UnpackAbsoluteCoordinate(int Packed, int *x, int *y, int *z);
+int PackRelativeCoordinate(int x, int y, int z);
+void UnpackRelativeCoordinate(int Packed, int *x, int *y, int *z);
+
+Object GetEventObject(int Nr, Object User, Object Obj1, Object Obj2, Object Temp);
+bool Compare(int Value1, int Operator, int Value2);
+bool CheckCondition(MoveUseEventType EventType, TMoveUseCondition *Condition,
+ Object User, Object Obj1, Object Obj2, Object *Temp);
+Object CreateObject(Object Con, ObjectType Type, uint32 Value);
void ChangeObject(Object Obj, ObjectType NewType, uint32 Value);
+void MoveOneObject(Object Obj, Object Con);
+void MoveAllObjects(Object Obj, Object Dest, Object Exclude, bool MoveUnmovable);
+void DeleteAllObjects(Object Obj, Object Exclude, bool DeleteUnmovable);
+void ClearField(Object Obj, Object Exclude);
+void LoadDepotBox(uint32 CreatureID, int Nr, Object Con);
+void SaveDepotBox(uint32 CreatureID, int Nr, Object Con);
+void SendMail(Object Obj);
+void SendMails(TPlayerData *PlayerData);
+void TextEffect(const char *Text, int x, int y, int z, int Radius);
+void ExecuteAction(MoveUseEventType EventType, TMoveUseAction *Action,
+ Object User, Object Obj1, Object Obj2, Object *Temp);
+bool HandleEvent(MoveUseEventType EventType, Object User, Object Obj1, Object Obj2);
+
+void UseContainer(uint32 CreatureID, Object Con, int NextContainerNr);
+void UseChest(uint32 CreatureID, Object Chest);
+void UseLiquidContainer(uint32 CreatureID, Object Obj, Object Dest);
+void UseFood(uint32 CreatureID, Object Obj);
+void UseTextObject(uint32 CreatureID, Object Obj);
+void UseAnnouncer(uint32 CreatureID, Object Obj);
+void UseKeyDoor(uint32 CreatureID, Object Key, Object Door);
+void UseNameDoor(uint32 CreatureID, Object Door);
+void UseLevelDoor(uint32 CreatureID, Object Door);
+void UseQuestDoor(uint32 CreatureID, Object Door);
+void UseWeapon(uint32 CreatureID, Object Weapon, Object Target);
+void UseChangeObject(uint32 CreatureID, Object Obj);
+void UseObject(uint32 CreatureID, Object Obj);
+void UseObjects(uint32 CreatureID, Object Obj1, Object Obj2);
+void MovementEvent(Object Obj, Object Start, Object Dest);
+void SeparationEvent(Object Obj, Object Start);
+void CollisionEvent(Object Obj, Object Dest);
+
+void LoadParameters(TReadScriptFile *Script, int *Parameters, int NumberOfParameters, ...);
+void LoadCondition(TReadScriptFile *Script, TMoveUseCondition *Condition);
+void LoadAction(TReadScriptFile *Script, TMoveUseAction *Action);
+void LoadDataBase(void);
+
+
+void InitMoveUse(void);
+void ExitMoveUse(void);
#endif //TIBIA_MOVEUSE_HH_
diff --git a/src/operate.cc b/src/operate.cc
index e742806..8123ba0 100644
--- a/src/operate.cc
+++ b/src/operate.cc
@@ -1,6 +1,7 @@
#include "operate.hh"
#include "config.hh"
#include "info.hh"
+#include "moveuse.hh"
#include "stubs.hh"
@@ -2107,15 +2108,12 @@ void Look(uint32 CreatureID, Object Obj){
if(CreatureID == 0 || ObjectInRange(CreatureID, Obj, 1)){
if(ObjType.getFlag(TAKE) && GetWeight(Obj, -1) > 0){
int ObjWeight = GetCompleteWeight(Obj);
- if(ObjType.getFlag(CUMULATIVE)
+ bool Multiple = ObjType.getFlag(CUMULATIVE)
&& Obj.getAttribute(AMOUNT) > 1
- && IsCountable(ObjType.getName(1))){
- snprintf(Help, sizeof(Help), "\nThey weigh %d.%02d oz.",
- ObjWeight / 100, ObjWeight % 100);
- }else{
- snprintf(Help, sizeof(Help), "\nIt weighs %d.%02d oz.",
- ObjWeight / 100, ObjWeight % 100);
- }
+ && IsCountable(ObjType.getName(1));
+ snprintf(Help, sizeof(Help), "\n%s %d.%02d oz.",
+ (Multiple ? "They weigh" : "It weighs"),
+ (ObjWeight / 100), (ObjWeight % 100));
strcat(Description, Help);
}
@@ -2570,7 +2568,7 @@ void Turn(uint32 CreatureID, Object Obj){
throw NOTTURNABLE;
}
- ObjectType RotateTarget = ObjType.getAttribute(ROTATETARGET);
+ ObjectType RotateTarget = (int)ObjType.getAttribute(ROTATETARGET);
if(RotateTarget == ObjType){
error("Turn: Objekt %d wird durch Drehen zerstört.\n", ObjType.TypeID);
}
@@ -2753,7 +2751,7 @@ void ProcessCronSystem(void){
}
ObjectType ObjType = Obj.getObjectType();
- ObjectType ExpireTarget = ObjType.getAttribute(EXPIRETARGET);
+ ObjectType ExpireTarget = (int)ObjType.getAttribute(EXPIRETARGET);
if(ObjType.getFlag(CONTAINER)){
int Remainder = 0;
if(!ExpireTarget.isMapContainer() && ExpireTarget.getFlag(CONTAINER)){
diff --git a/src/stubs.hh b/src/stubs.hh
index 4b9e3cc..191c733 100644
--- a/src/stubs.hh
+++ b/src/stubs.hh
@@ -31,11 +31,14 @@ extern const char *GetHouseName(uint16 HouseID);
extern const char *GetHouseOwner(uint16 HouseID);
extern void InitLog(const char *ProtocolName);
extern bool IsInvited(uint16 HouseID, TPlayer *Player, int TimeStamp);
+extern bool IsOwner(uint16 HouseID, TPlayer *Player);
extern void KickGuest(uint16 HouseID, TPlayer *Host, TPlayer *Guest);
extern void KillStatisticsOrder(int NumberOfRaces, const char *RaceNames, int *KilledPlayers, int *KilledCreatures);
+extern void LoadCharacterOrder(uint32 CharacterID);
extern void LoadSectorOrder(int SectorX, int SectorY, int SectorZ);
extern void Log(const char *ProtocolName, const char *Text, ...) ATTR_PRINTF(2, 3);
extern void LogoutOrder(TPlayer *Player);
+extern bool MayOpenDoor(Object Door, TPlayer *Player);
extern void PrepareHouseCleanup(void);
extern void FinishHouseCleanup(void);
extern void PlayerlistOrder(int NumberOfPlayers, char *PlayerNames, int *PlayerLevels, int *PlayerProfessions);
@@ -49,28 +52,8 @@ extern void SavePlayerData(TPlayerData *Slot);
extern bool LoadPlayerData(TPlayerData *Slot);
extern bool PlayerDataExists(uint32 CharacterID);
extern void SavePlayerDataOrder(void);
-extern void SendMails(TPlayerData *PlayerData);
extern void ShowGuestList(uint16 HouseID, TPlayer *Player, char *Buffer);
extern void ShowSubownerList(uint16 HouseID, TPlayer *Player, char *Buffer);
extern void ShowNameDoor(Object Door, TPlayer *Player, char *Buffer);
-// moveuse.cc
-extern void UseContainer(uint32 CreatureID, Object Con, uint8 ContainerNr);
-extern void UseChest(uint32 CreatureID, Object Chest);
-extern void UseLiquidContainer(uint32 CreatureID, Object Obj, Object Dest);
-extern void UseFood(uint32 CreatureID, Object Obj);
-extern void UseTextObject(uint32 CreatureID, Object Obj);
-extern void UseAnnouncer(uint32 CreatureID, Object Obj);
-extern void UseKeyDoor(uint32 CreatureID, Object Key, Object Door);
-extern void UseNameDoor(uint32 CreatureID, Object Door);
-extern void UseLevelDoor(uint32 CreatureID, Object Door);
-extern void UseQuestDoor(uint32 CreatureID, Object Door);
-extern void UseWeapon(uint32 CreatureID, Object Weapon, Object Target);
-extern void UseChangeObject(uint32 CreatureID, Object Obj);
-extern void UseObject(uint32 CreatureID, Object Obj);
-extern void UseObjects(uint32 CreatureID, Object Obj1, Object Obj2);
-extern void MovementEvent(Object Obj, Object Start, Object Dest);
-extern void CollisionEvent(Object Obj, Object Dest);
-extern void SeparationEvent(Object Obj, Object Start);
-
#endif //TIBIA_STUBS_HH_