Simba Code:
//Look for NPC with Name in spiral pattern around player, within an RxR square
function TReflectNPC.FindSpiral(Name: String; R: Integer; checkInteracting: Boolean): Boolean;
var
currTile: TTile;
i, j, n, k, di, dj, seg, segLen, buf, m, l: Integer;
tNPC: TReflectNPC;
tNPCA, tRNPCA: TReflectNPCArray;
condition: Boolean;
begin
if not isLoggedIn then
Exit;
//Get all NPCs and select only those with the right Name
Self.Null;
tNPCA.GetAll;
j := 0;
k := High(tNPCA);
SetLength(tRNPCA, k + 1);
for i := 0 to k do
if tNPCA[i].Name = Name then
begin
tRNPCA[j] := tNPCA[i];
Inc(j);
end;
l := j;
currTile := cP.GetTile; //cP is a global TReflectLocalPlayer
k := R * R;
i := 0;
j := 0;
di := 1;
dj := 0;
seg := 0;
segLen := 1;
//Spiral around the player, looking for matches between found NPCs' location and the current spiral location
for n := 0 to k do
begin
IncEx(currTile.X, di);
IncEx(currTile.Y, dj);
Inc(seg);
for m := 0 to l do
begin
if checkInteracting then
condition := (tRNPCA[m].Tile.X = currTile.X) and (tRNPCA[m].Tile.Y = currTile.Y) and (tRNPCA[m].InteractingIndex = -1)
else
condition := (tRNPCA[m].Tile.X = currTile.X) and (tRNPCA[m].Tile.Y = currTile.Y);
if condition then
begin
Self := tRNPCA[m];
Result := True;
Exit;
end;
end;
if seg = segLen then
begin
seg := 0;
buf := di;
di := -dj;
dj := buf;
if dj = 0 then
Inc(segLen);
end;
end;
Result := False;
end;
For a script I've created.
It will search the tiles around the player in a spiraling pattern for an NPC named 'Name' (todo: add ID support), in a R^2 square as max range.
The spiraling logic I've adapted from a StackOverflow answer that was in Python. The checkInteracting bit is because I'll mainly be looking for NPCs to fight, to make sure they're not already engaged.
This is my first thing since like 2009 so I'm quite rusty. Tell me what you think
EDIT:
Shortened it a bit, removed that first loop. Will test out when hooks are back up.
Simba Code:
//Look for NPC with Name in spiral pattern around player, within an RxR square
function TReflectNPC.FindSpiral(Name: String; R: Integer; checkInteracting: Boolean): Boolean;
var
currTile: TTile;
x, y, n, k, dx, dy, seg, segLen, buf, i, npcCount: Integer;
tNPCA: TReflectNPCArray;
condition: Boolean;
begin
if not isLoggedIn then
Exit;
Self.Null;
tNPCA.GetAll;
npcCount := High(tNPCA);
currTile := cP.GetTile;
k := R * R;
x := 0;
y := 0;
dx := 1;
dy := 0;
seg := 0;
segLen := 1;
//Spiral around the player, looking for matches between found NPCs' location and the current spiral location
for n := 0 to k do
begin
IncEx(currTile.X, dx);
IncEx(currTile.Y, dy);
Inc(seg);
for i := 0 to npcCount do
begin
if checkInteracting then
condition := (tNPCA[i].Name = Name) and (tNPCA[i].Tile.X = currTile.X) and (tNPCA[i].Tile.Y = currTile.Y) and (tNPCA[i].InteractingIndex = -1)
else
condition := (tNPCA[i].Name = Name) and (tNPCA[i].Tile.X = currTile.X) and (tNPCA[i].Tile.Y = currTile.Y);
if condition then
begin
Self := tNPCA[i];
Result := True;
Exit;
end;
end;
if seg = segLen then
begin
seg := 0;
buf := dx;
dx := -dy;
dy := buf;
if dy = 0 then
Inc(segLen);
end;
end;
Result := False;
end;