1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#include "info.hh"
#include "cr.hh"
#include "stubs.hh"
bool JumpPossible(int x, int y, int z, bool AvoidPlayers){
bool HasBank = false;
Object Obj = GetFirstObject(x, y, z);
while(Obj != NONE){
ObjectType ObjType = Obj.getObjectType();
if(ObjType.getFlag(BANK)){
HasBank = true;
}
if(ObjType.getFlag(UNPASS) && ObjType.getFlag(UNMOVE)){
return false;
}
if(AvoidPlayers && ObjType.isCreatureContainer()){
TCreature *Creature = GetCreature(Obj);
if(Creature != NULL && Creature->Type == PLAYER){
return false;
}
}
Obj = Obj.getNextObject();
}
return HasBank;
}
bool SearchFreeField(int *x, int *y, int *z, int Distance, uint16 HouseID, bool Jump){
int OffsetX = 0;
int OffsetY = 0;
int CurrentDistance = 0;
int CurrentDirection = DIRECTION_EAST;
while(CurrentDistance <= Distance){
int FieldX = *x + OffsetX;
int FieldY = *y + OffsetY;
int FieldZ = *z;
// TODO(fusion): This is probably some form of the `TCreature::MovePossible`
// function inlined.
bool MovePossible;
if(Jump){
MovePossible = JumpPossible(FieldX, FieldY, FieldZ, true);
}else{
MovePossible = CoordinateFlag(FieldX, FieldY, FieldZ, BANK)
&& !CoordinateFlag(FieldX, FieldY, FieldZ, UNPASS);
// TODO(fusion): This one I'm not so sure.
if(MovePossible && CoordinateFlag(FieldX, FieldY, FieldZ, AVOID)){
MovePossible = CoordinateFlag(FieldX, FieldY, FieldZ, BED);
}
}
if(MovePossible){
if(HouseID == HOUSEID_ANY || !IsHouse(FieldX, FieldY, FieldZ)
|| (HouseID != 0 && HouseID == GetHouseID(FieldX, FieldY, FieldZ))){
*x = FieldX;
*y = FieldY;
return true;
}
}
// NOTE(fusion): We're spiraling out from the initial coordinate.
// TODO(fusion): This function used directions different from the ones
// used by creatures and defined in `enums.hh` so I made it use them
// instead, LOL.
if(CurrentDirection == DIRECTION_NORTH){
OffsetY -= 1;
if(OffsetY <= -CurrentDistance){
CurrentDirection = DIRECTION_WEST;
}
}else if(CurrentDirection == DIRECTION_WEST){
OffsetX -= 1;
if(OffsetX <= -CurrentDistance){
CurrentDirection = DIRECTION_SOUTH;
}
}else if(CurrentDirection == DIRECTION_SOUTH){
OffsetY += 1;
if(OffsetY >= CurrentDistance){
CurrentDirection = DIRECTION_EAST;
}
}else{
ASSERT(CurrentDirection == DIRECTION_EAST);
OffsetX += 1;
if(OffsetX > CurrentDistance){
CurrentDistance = OffsetX;
CurrentDirection = DIRECTION_NORTH;
}
}
}
return false;
}
|