diff options
| author | fusion32 <marcopuzziello@gmail.com> | 2025-06-27 18:57:29 -0300 |
|---|---|---|
| committer | fusion32 <marcopuzziello@gmail.com> | 2025-06-27 18:57:29 -0300 |
| commit | e59667ec6be0a21ce702ce077154357a1c7f7c04 (patch) | |
| tree | 8222cce37f8dbf1694cffa138c0bb0ad6b893bf3 | |
| parent | ea319bc2fbef91e3ea062be554b215756648d1d3 (diff) | |
| download | game-e59667ec6be0a21ce702ce077154357a1c7f7c04.tar.gz game-e59667ec6be0a21ce702ce077154357a1c7f7c04.zip | |
`moveuse.cc`
| -rw-r--r-- | TODO.md | 14 | ||||
| -rw-r--r-- | reference/enums.hh | 70 | ||||
| -rw-r--r-- | reference/game.c | 5733 | ||||
| -rw-r--r-- | reference/types.hh | 30 | ||||
| -rw-r--r-- | src/crcombat.cc | 4 | ||||
| -rw-r--r-- | src/crmain.cc | 109 | ||||
| -rw-r--r-- | src/crnonpl.cc | 6 | ||||
| -rw-r--r-- | src/crplayer.cc | 1 | ||||
| -rw-r--r-- | src/enums.hh | 31 | ||||
| -rw-r--r-- | src/info.cc | 3 | ||||
| -rw-r--r-- | src/magic.cc | 2 | ||||
| -rw-r--r-- | src/main.cc | 5 | ||||
| -rw-r--r-- | src/map.cc | 54 | ||||
| -rw-r--r-- | src/moveuse.cc | 3039 | ||||
| -rw-r--r-- | src/moveuse.hh | 186 | ||||
| -rw-r--r-- | src/operate.cc | 18 | ||||
| -rw-r--r-- | src/stubs.hh | 23 |
17 files changed, 3336 insertions, 5992 deletions
@@ -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); @@ -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_ |
