SRL Archive - Help and Support

Please write me a function that returns the sum of the colors within a TPA...


WT-Fakawi

2011-01-27 17:11:27

Working on Ratz! revived. Slowly progressing on my own path. During this outlining phase I am unable to write function that returns the sum of the colors in a TPA….because I don't have the programming skills, thus I ask here :)

Why do I need this?

I am working on a humble system that keeps track of all my objects in the inventory. I know there are a couple of systems alive today, such as blacklists, but mine is simple and hopefully effective.

  1. I take the TPA of the black outline of an object.
  2. I take the TPABounds of the object.
That all works fine. These three simple parameters almost ensure object uniqueness. Almost, because stuff like body vs mind runes, and raw vs cooked meat I can't distinguish.

So, instead I want to calculate the sum of the colors in the TPA

…or one pixel that lies 100% in the TPA. (With shrimps or a hatchet f.i. it is difficult to tell 100% that the color is from the object)

Anyone capable and willing to write me such a function?

P.S. Forgot to mention: I am relating those parameters to the uptext of the object and keep track of the objects during runtime.

Naum

2011-01-27 17:25:59

Something as such? :

Function SumOfColorsInTPA(TPA : TPointArray) : Integer;
Var TIA : TIntegerArray;
Begin
TIA := GetColors(TPA);
Result := SumIntegerArray(TIA);
End;
Edit: coded in a hurry

lordsaturn

2011-01-27 17:27:57

Sum of the colors doesn't sound like a good idea to me, because the colors are always changing (afaik) (edit:confirmed). However your second idea would work well if you could find a static color on the item.

Perhaps just do a FindColorsTolerance, and then compare Length(YellowColorsInMindRuneTPA) to TPALengths[YellowColorsInMindRune].

Gu3st...

2011-01-27 17:38:58

Plus, adding all the colors from an item might result in something larger than an integer supports (probably not int64 though..)

WT-Fakawi

2011-01-27 18:05:12

From: Naum
Something as such? :

Function SumOfColorsInTPA(TPA : TPointArray) : Integer;
Var TIA : TIntegerArray;
Begin
TIA := GetColors(TPA);
Result := SumIntegerArray(TIA);
End;
Edit: coded in a hurry


SumIntegerArray doesn't work on Simba….yet.


From: Zyt3x
Plus, adding all the colors from an item might result in something larger than an integer supports (probably not int64 though..)

LongInt will do I guess. Doesn't matter that much. As long as the sum yields a reference.

From: lordsaturn
Sum of the colors doesn't sound like a good idea to me, because the colors are always changing (afaik) (edit:confirmed). However your second idea would work well if you could find a static color on the item.

Perhaps just do a FindColorsTolerance, and then compare Length(YellowColorsInMindRuneTPA) to TPALengths[YellowColorsInMindRune].


Colors of objects in inventory vary? Sure? anyway, doesn't matter with this sytem, since I create a runtime relation between name and object.


Anyway: one unique pixel inside the TPA would do also :)

Hobbit

2011-01-27 18:18:22

Why Dont you first go through and sqrt or divide each number in the array before adding up the sum to control the end value size? It will still give you a unique reference as well as keep the size down?

WT-Fakawi

2011-01-27 18:27:53

From: Hobbit
Why Dont you first go through and sqrt or divide each number in the array before adding up the sum to control the end value size? It will still give you a unique reference as well as keep the size down?


Thats a great idea, but that is not an idea I would have come up with, for I don't comprehend that. It doesn't solve the raw vs cooked meat issue. Thats the only one left

Hobbit

2011-01-27 18:30:40

But the colors are still different on the raw /cooked so if maybe you stick 1 reference point in the middle of the objects the colors will be different so they will have different values in the end giving a different end result? (this is all theoretical in my head)

WT-Fakawi

2011-01-27 18:46:52

Middle of objects can be transparant like shrimps or hatchets, thus effectively picking the empty inventory background colors. Thats why I need just one unique pixel, but preferly the sum. I need to accumulate that as invitems like cons vary in pixels. And once I know at what spot the coins are, I can update the outline.

type
InvItem = record
w, h : Integer; // width, height
z : TPointArray; // outline count
n : string; // uptext name
c : longint; // color count
end;

var
InvBase: Array[1..28] of InvItem;


Maybe I need more, but I guess thats all I need.

Hobbit

2011-01-27 18:54:18

You could also do something like TPA[1].x (+/-) 1 and get the colors on both the left and right of one of the TPA points, yes one of them will have the background color but then it will also have the item color and if it's the same for all the objects then it will just equal out?



Edit: nvm forgot Inv background isn't a solid color :(

Wanted

2011-01-27 19:19:35

Total color seems like a number you can't work with, instead why not convert colors to RGB scale, total them, then average them out, convert back to decimal value in order to get an average color. Or do something along the lines of comparing the RGB scales..

function AverageColor(TIA: TIntegerArray): Integer;
var
I, H, R, G, B: LongInt;
tR, tG, tB: Int64;
begin
H := High(TIA);
for I := 0 to H do
begin
ColorToRGB(TIA[I], R, G, B);
tR := tR + R;
tG := tG + G;
tB := tB + B;
end;
I := Length(TIA);
Result := RGBToColor(Round(tR div I), Round(tG div I), Round(tB div I));
end;

var
TIA: TIntegerArray;
TPA: TPointArray;

begin
TIA := GetColors(TPA);
end.

Also, why doesn't SumIntegerArray work in simba? Isn't that a pretty simple function?

function SumIntegerArray(TIA: TIntegerArray): LongInt;
var
I, H, L: LongInt;
begin
L := Low(TIA);
H := High(TIA);
for I := L to H do
IncEx(Result, TIA[I]);
end;

WT-Fakawi

2011-01-27 20:08:13

From: IceFire908
hy doesn't SumIntegerArray work in simba? Isn't that a pretty simple function?

function SumIntegerArray(TIA: TIntegerArray): LongInt;
var
I, H, L: LongInt;
begin
L := Low(TIA);
H := High(TIA);
for I := L to H do
IncEx(Result, TIA[I]);
end;


Thank you. I have a pretty simple mind. On my simba this function doesn't work.

Got it working on my own crappy way, just a couple of lines, all but the color. It dynamically updates the inventory, i.e it knows at any moment what I have at which spot. Thats the framework :)

Sir R. M8gic1an

2011-01-27 21:17:50


function ItemCBM(which: integer; Action: TAction): boolean;
var
t: TItem;
begin
if Action == Find then
begin
t.BM := SRLItems[which].BM;

if SRLItems[which].w > 0 then
t.w := SRLItems[which].w;

if SRLItems[which].h > 0 then
t.h := SRLItems[which].h;

if (t.BM > 0)and(t.h > 0)and(t.w >0) then //item exists in database
begin
Result := FindItem(SRLItems[which]);
exit;
end;

//find item here

if Result then
SRLDebugToDB(SRLItem[which]);
end;
end;

~RM

Bonfield

2011-01-27 23:12:37

  if Action == Find then
why the double equals? is it just a typo?

i had similar problem, i wanted to count the black pixels then find the area inside of it and compare it eg a bucket to clay. What i ended up going was getTPAbounds finding the area then subtracting it from the area f an inventory box, it was a pretty crude way of doing it but it worked for what i needed it to, the only problem is it wouldnt work for say raw and cooked shrimps

mormonman

2011-01-28 00:39:16

From: Bonfield
  if Action == Find then
why the double equals? is it just a typo?


He is in java mode :p

WT-Fakawi

2011-01-28 03:53:19

Using my system I have been able to identify most object in the inventory. This is what I have so far.

Use the normal client, not SMART if you want to test it yourself. also, use low level noob, since mouse moves very detectable!


What does the testscript do?


Stand inside a bank, fill your inventory with anything, doesn't matter what. As long as you can 'Wield', 'Use', 'Eat', 'Drink', or 'Wear' it. (Close bank before starting script)

Start the script. The mouse will move very detecable over all invspots. (use low level noob) It will grab the names and the dimensions of all objects in the inventory. Note that the level of UpText succes depends on the background. solid background = better succes.

Now, while the script is still running, empty your inventory in the bank. Note that the debug is now empty.

Next place any item that the script has logged in any spot of the inventory, one or many doesn't matter. See that the script tracks your objects, the number of objects and the spot it is in.


Few problems left:


  1. Raw vs Cooked Meat. I still need some kind of inside-TPA color picker. Problems also with other objects with same TPA + TPABounds. Succes is now 95%. Not good enough!
  2. Amount. Stacked items vary in outline because of overlap with the outline color. Can be solved, but I haven't build this yet. Coins will prolly get their own handling.
  3. solid objectnames. I will need a system that can see that 'B^ z@ icka ' is actually a bronze pickaxe.


Potential of this system.

Of course, I only check 28 items now, for the Ratz script thats about all I can find on the ground, but this system can keep track of anything you have in your inventory. If an unknown TPA + TPABound + color pops up in the inv, I analyse it, and use in the script if needed. Theoretically, this sytem will work regardless of jagex updating bitmaps. And thats was exactly what I was looking for.

Also, the system allows me to do the following:

 with 'sling' do

and run the script until I pick up the rare goblin-drop 'sling'. Now that I have identified this sling, I can use it to train my range.





program test;
//{$i SRL/SRL/misc/SMART.scar}
{$i srl/srl.scar}

type
InvItem = record
w, h, z : Integer; // width, height, outline TPA count
n : string; // uptext name
c : longint; // color count
end;

var
InvBase: Array[1..28] of InvItem; // database of 28 different items
MyNamedInv:array[1..28] of string; // names of items current in inventory


const
SMART_world = 10;
InvOutline = 131072;
FawkiDebug = True;

procedure DeclarePlayers;
begin
HowManyPlayers:= 1;
NumberOfPlayers(HowManyPlayers);
CurrentPlayer := 0;

with Players[0] do
begin
Name := '';
Pass := '';
Nick := '';
Pin := '';
Active := true;
end;
end;

procedure Setup;
begin
if SMART_world <> 0 then
SMART_Server := SMART_world;
SMART_members := true;
SMART_signed := true;

SetUpSRL;
DeclarePlayers;
end;

// Extract Object Uptext name from string

Function GetInvName:String;
var
InvName, RawName, temp: String;
var
EFU : Array of string;
i :Integer;
begin
EFU := ['Wield','Use','Eat','Drink','Wear'];
RawName := (GetUpText);
for i := 0 to 4 do
begin
temp :=Between(EFU[i],'/',RawName);
if temp <> '' then
InvName := temp;
end;
Result := InvName;
end;

// grab properties of single invspot

Function GetSingleInv(InvSpot: Integer): InvItem;
var
TPA: TPointArray;
TP: TPoint;
InvObjectColors: TIntegerArray;
InvObjectBounds : Tbox;
w, x, y, i,j: Integer;
Begin
if not ExistsItem(InvSpot) then
begin
Exit;
end;
FindColorsSpiralTolerance(x, y, TPA, InvOutline, InvBox(InvSpot).x1, InvBox(InvSpot).y1, InvBox(InvSpot).x2, InvBox(InvSpot).y2, 0);
InvObjectBounds := GetTPABounds(TPA);
Result.w := InvObjectBounds.x2 - InvObjectBounds.x1;
Result.h := InvObjectBounds.y2 - InvObjectBounds.y1;
Result.z := Length(TPA);
end;

// Get properties of all spot...debugging purpose.

procedure GetAllInv;
var
TPA: TPointArray;
TP: TPoint;
InvObjectColors: TIntegerArray;
InvObjectBounds : Tbox;
InvObjectWidth, InvObjectHeight: Integer;
InvObjectName: String;
SumIntegerArray, color2, v, w, x, y, i,j: Integer;
Begin
for i := 1 to 28 do
begin
FindColorsSpiralTolerance(x, y, TPA, InvOutline, InvBox(i).x1, InvBox(i).y1, InvBox(i).x2, InvBox(i).y2, 0);
begin
// InvObjectColors := GetColors(TPA);
// SumIntegerArray(InvObjectColors);
InvObjectBounds := GetTPABounds(TPA);
InvObjectWidth := InvObjectBounds.x2 - InvObjectBounds.x1;
InvObjectHeight := InvObjectBounds.y2 - InvObjectBounds.y1;
MoveMouse(InvBox(i).x1 + (InvBox(i).x2-InvBox(i).x1)/2, InvBox(i).y2 - (InvBox(i).y2 -InvBox(i).y1)/2);
Wait(200);
InvObjectName := GetInvName;
InvBase[i].w := InvObjectWidth;
InvBase[i].h := InvObjectHeight;
InvBase[i].z := Length(TPA);
InvBase[i].n := InvObjectName;

Writeln('Inv ' + IntToStr(i) + ' = ' + InvObjectName + ' ' + IntToStr(Length(TPA))+ ' + '
+ IntToStr(InvObjectWidth) + ' + ' + IntToStr(InvObjectHeight) +' + ' + IntToStr(SumIntegerArray));

end
end
end;

procedure printoutinvbase;
var
i:Integer;
begin
writeln('_____CURRENT BASE______');
for i:= 1 to 28 do
begin
Writeln(InvBase[i].n);
end;
writeln('______________________');
end;

// Check if system works.

procedure CheckInv;

var
i,j:Integer;
TheInvItem: InvItem;
begin
for i := 1 to 28 do
begin
if not existsitem(i) then
begin
MyNamedInv[i] := '';
continue;
end;
TheInvItem := GetSingleInv(i);
For j := 1 to 28 do
begin
if (InvBase[j].w = TheInvItem.w) and (InvBase[j].h = TheInvItem.h) and
(InvBase[j].z = TheInvItem.z) then
begin
MyNamedInv[i] := InvBase[j].n; // Jackpot!, and place in current_invarray
end
end
end;
for i := 1 to 28 do
begin
writeln('Inv ' + IntToStr(i) + ' = ' + MyNamedInv[i]);
end
end;

begin
Setup;
LoginPlayer;
GetAllInv;
repeat
writeln('------------------------------------------');
CheckInv;
Wait(500);
Cleardebug;
writeln('------------------------------------------');
until false

end.

Sir R. M8gic1an

2011-01-28 06:07:11

I can sort out color filtering later if you want ;)

~RM

Bonfield

2011-01-28 06:34:34

How would you go about it? out of curiosity(

Sir R. M8gic1an

2011-01-28 06:43:02

From: Bonfield
How would you go about it? out of curiosity(


Something among these lines..

{*******************************************************************************
function GatherColors(var Rock: TMSObj): boolean;
By: Rasta Magician
Description: Gathers Colors from a box with double side length of
HALF_BOX_SIZE which match the Color and Tol from TMSObj
with the Hue and Sat modifiers and CTS 2
Sets TMSObj.SCArray to the gathered colors
*******************************************************************************}
function GatherColors(var Rock: TMSObj): boolean;
var
x, y, i, CTS, RockColorIndex, L: integer;
//H, S: extended;
TPA: TPointArray;
ColorArray, LengthArray: TIntegerArray;
begin
SC_Debug('gathering colors');
if not LoggedIn then exit;
if not IsUpTextMultiCustom(Rock.UpTexts) then exit;

SC_Debug('in color gatherer');
GetMousePos(x, y);
CTS := GetColorToleranceSpeed;
//GetColorspeed2Modifiers(H, S);

//scanning colors around in a HALF_BOX_SIZE*2 box
ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(Rock.Hue, Rock.Sat);
if not FindColorsTolerance(
TPA, Rock.Color,
x - Rock.Details.HALF_BOX_SIZE, y - Rock.Details.HALF_BOX_SIZE,
x + Rock.Details.HALF_BOX_SIZE, y + Rock.Details.HALF_BOX_SIZE,
Rock.Tol
) then
begin
ColorToleranceSpeed(CTS);
//SetColorspeed2Modifiers(H, S);
exit;
end;

ColorArray := GetColors(TPA);
ClearSameIntegers(ColorArray);

//analysing colors for uniqueness
L := Length(ColorArray);

SetLength(Rock.SCArray, L);
SetLength(LengthArray, L);

for i:= 0 to High(ColorArray) do
begin
L := AnalyseColor(ColorArray[i], Rock);

if L <= Rock.Details.UNIQUE_COLOR_MAX then
begin
Rock.SCArray[RockColorIndex] := ColorArray[i];
LengthArray[i] := L;
Inc(RockColorIndex);
end;
end;

SetLength(Rock.SCArray, RockColorIndex + 1);
Rock.SCArray := OrganizeColors(Rock.SCArray, LengthArray);
Result := (RockColorIndex > 2);

ColorToleranceSpeed(CTS);
//SetColorspeed2Modifiers(H, S);
end;

http://villavu.com/forum/showthread.php?t=52915

~RM

WT-Fakawi

2011-01-28 07:08:57

From: Sir R. Magician
I can sort out color filtering later if you want ;)

~RM


Looking forward to that, yes please. As you see from my crappy code, all I think I need is either one pixel, but better would be to have some sort of colorchecksum of each object.

nielsie95

2011-01-28 08:18:39

From: WT-Fakawi

I am working on a humble system that keeps track of all my objects in the inventory. I know there are a couple of systems alive today, such as blacklists, but mine is simple and hopefully effective.


Your system is a simple version of blacklists. When you want to fix those problems and make it for pretty much all RS items, it'll get more complicated (and you'll probably end up with a similar solution to mine). Check out these threads, they might give you some more information.

Finding the points inside the bounds isn't that hard. If you have the outline, you can find all the points in the box around it that are not the outline using ReturnPointsNotInTPA (giving you the inner points + the points around the outline). After that, you just have to filter the points outside the outline using SplitTPA (if you have taken a box larger than the bounds of the item, it simply is the group with point (0, 0)). Now you are left with all the points inside the bounds.

Boreas

2011-01-28 10:11:23

From: nielsie95
Your system is a simple version of blacklists. When you want to fix those problems and make it for pretty much all RS items, it'll get more complicated (and you'll probably end up with a similar solution to mine). Check out these threads, they might give you some more information.

Finding the points inside the bounds isn't that hard. If you have the outline, you can find all the points in the box around it that are not the outline using ReturnPointsNotInTPA (giving you the inner points + the points around the outline). After that, you just have to filter the points outside the outline using SplitTPA (if you have taken a box larger than the bounds of the item, it simply is the group with point (0, 0)). Now you are left with all the points inside the bounds.


TBH I have no idea why SRL, MSI and all other scripts don't use your system by now. It's fast, auto updating, can create during runtime for a brand new item nobody has ever seen before, and can even do fire staff vs water staff.

WT-Fakawi

2011-01-28 11:53:42

From: nielsie95
Your system is a simple version of blacklists. When you want to fix those problems and make it for pretty much all RS items, it'll get more complicated (and you'll probably end up with a similar solution to mine). Check out these threads, they might give you some more information.


Haha, my system is nothing compared to your and Boreas's blacklists. I have tried to comprehend your wonderful code, but I miserably fail. I can only use code I understand, at least in my own scripts. I am trying to keep it simple yet elegant, and focus on the outcome. I know what I want, but I need to find my own way to implement it.


From: nielsie95

Finding the points inside the bounds isn't that hard. If you have the outline, you can find all the points in the box around it that are not the outline using ReturnPointsNotInTPA (giving you the inner points + the points around the outline). After that, you just have to filter the points outside the outline using SplitTPA (if you have taken a box larger than the bounds of the item, it simply is the group with point (0, 0)). Now you are left with all the points inside the bounds.


Thanks man. That is a great help. I think I can implement it myself now.


From: Boreas
TBH I have no idea why SRL, MSI and all other scripts don't use your system by now. It's fast, auto updating, can create during runtime for a brand new item nobody has ever seen before, and can even do fire staff vs water staff.


So why isn't it? All I need is one function that returns the names and the places of the items in my inventory. It should be in SRL.

Gu3st...

2011-01-28 11:56:59

From: Boreas
TBH I have no idea why SRL, MSI and all other scripts don't use your system by now. It's fast, auto updating, can create during runtime for a brand new item nobody has ever seen before, and can even do fire staff vs water staff.
I agree. I'll bump MSI's thread about it…

Wizzup?

2011-01-28 13:36:38

Probably because for some unknown reason it is included in MSI instead of in SRL? Also, AFAIK Fakawi, you wanted a function that returns the points in a bounding box defined by a TPA… See: within TPA.

bugger0001

2011-01-30 07:45:59

Wouldn't the number of all different colors in the item bounds be sufficient for your purpose? I mean you also check the outline of the item, which gives you some elimination and combined with the number of all different colors on that item you should be good to go. Am I wrong? It can turn out to be buggy in some(if any) cases but it should be accurate in most cases…

Sir R. M8gic1an

2011-01-30 08:01:42

I just realized how simple it is to count all the colors within the TPA.


type
TBLColor = record;
Color: integer;
Count: integer;

TBLColorArray: array of TBLColor;

var
i, L, cL, R, previous: integer;
TCA: TBLColorArray;

Colors := GetColors(WithinTPA(TPA_BL));
BubbleSort(Colors);

L := Length(Colors)

SetLength(TCA, L);

R := 0;
cL := 1;
previous := Colors[0];
TCA[0].Color := Colors[0];
TCA[0].Count := 0;

for i:= 0 to L - 1 do
if previous = Colors[i] then
inc(TCA[R].Count)
else begin
Inc(R);
TCA[R].Color := Colors[i];
TCA[R].Count := 1;
Previous := Colors[i];
Inc(cL);
end;

This also gives you an organized list of colors :)


for i := 0 to high(TCA) do
writeln('Color: ' + TCA[i].Color + '; ' + TCA[i].Count);

I think it's time for SmartColors to kick ass.

~RM :)

Wizzup?

2011-01-30 08:03:46

Let me rephrase:

Given a TPA(X) of the outline of an item, return a TPA(Y) that contains the points enclosed by the TPA X. So, basically: Floodfill.

Sir R. M8gic1an

2011-01-30 08:07:09

From: Wizzup?
Let me rephrase:

Given a TPA(X) of the outline of an item, return a TPA(Y) that contains the points enclosed by the TPA X. So, basically: Floodfill.


I think we can solve mordaut once and for all…

mastaraymond

2011-01-30 10:27:50


program new;

function FloodFillEdge(Edges : TPointArray;StartPT : TPoint; Box : TBox) : TPointArray;
var
Bounds : TBox;
RealBox : TBox;
FillArea : Array of Array of Boolean;
W,H,I,X,Y,X1,Y1,StackI : integer;
CurPT : TPoint;
//We use Result as stack, dirty!
begin
Bounds := GetTPABounds(Edges);
RealBox := IntToBox(Min(Box.x1,Bounds.x1),
Min(Box.y1,Bounds.y1),
Max(box.x2,Bounds.x2),
Max(box.y2,bounds.y2));
W := RealBox.x2-RealBox.x1+1;
H := RealBox.y2-RealBox.y1+1;
Writeln(realbox);
if (w=0) or (h=0) or not PointInBox(StartPT,RealBox) then
Exit;
SetLength(FillArea,w+2); //Dirty check to work around the out of range
for i := w+1 downto 0 do
Setlength(FillArea[i],h+2);
X1 := RealBox.X1 - 1; //-1 Because of the cornor points, which do not count.
Y1 := RealBox.Y1 - 1;
for i := Length(Edges) -1 downto 0 do
FillArea[Edges[i].x-x1][Edges[i].y-y1] := True;
(* Next sets the points on the edge to True, so it doesn't cause out of range *)
for x := 0 to w+1 do
begin;
FillArea[x][0] := true;
FillArea[x][h+1] := true;
end;
for y := 0 to h+1 do
begin
FillArea[0][y] := True;
FillArea[w+1][y] := True;
end;
SetLength(Result,W*H);
Result[0] := Point(StartPT.x-x1,StartPT.y-y1);
StackI := 0;
while StackI >= 0 do
begin
CurPT := Result[StackI];
Dec(StackI);
if (FillArea[CurPT.x][CurPT.y] = True) then //We do not need to check, as this is already checked
Continue;
if FillArea[CurPT.x][CurPT.y-1] = False then
begin
Inc(StackI);
Result[StackI] := Point(CurPT.x,CurPT.y-1);
end;
if FillArea[CurPT.x][CurPT.y+1] = False then
begin
Inc(StackI);
Result[StackI] := Point(CurPT.x,CurPT.y+1);
end;
if FillArea[CurPT.x-1][CurPT.y] = False then
begin
Inc(StackI);
Result[StackI] := Point(CurPT.x-1,CurPT.y);
end;
if FillArea[CurPT.x+1][CurPT.y] = False then
begin
Inc(StackI);
Result[StackI] := Point(CurPT.x+1,CurPT.y);
end;
FillArea[CurPT.x][CurPT.y] := True;
end;
StackI := 0;
for i := Length(Edges) -1 downto 0 do
FillArea[Edges[i].x-x1][Edges[i].y-y1] := False; //To filter from result
for x := 1 to w do
for y := 1 to h do
if FillArea[x][y] then
begin;
Result[StackI] := Point(x+x1,y+y1);
inc(StackI);
end;
SetLength(Result,StackI);
end;
var
Bmp,BMP2 : integer;
Test : TPointArray;
i : integer;
begin
Bmp := BitmapFromString(38, 36, 'meJydV+tLk1EYlz63zd033Qf/gI' +
'y5dfGSujmnswQvEbPS0JpiZiYqNpaXJEQUEVEklBBFlCjEPhRBFEr' +
'9Y/3Onu14ds55X6fw8LKdy/N7fs/1fUON8VBjPFjbZC6V1ZHi17HI' +
'RV0MN7aSGGFJW0bQWkStDVCo5cgXOaKKRWdMbOBbRohcudaMYtiZX' +
'6G/oUiLCGTiXon71UBJQyifPOFIAgYE62JM+Bn6y+WSNDUG5JUADr' +
'9zFPLKmTGRFmaGiH55XqIAKOfJrDbiyxYbEjknFCKe/748LmXOeRz' +
'rYhyd+Kq8CtDzcq2kRBJzpqL94BWuP+ebuyt6stCrpD/w/l9g7qx8' +
'5k955lfZ2x/+qW8irkYMkgRX3Il1PI3iiC3/5Il7YNPekfaPf/W9P' +
'vK+OvCNHvrefPGNfcbvC3AVR3lS23hWVAQhYtXAV6TK/XzLEZm310' +
'3b7oza76Wd0QVXfAUGeAZ3PEOf2DO1jTPFgOIMLHTGFglR3YUeZ2x' +
'Jip0zuQhQrAPX1brmefHR+3LP3b9BSsSYSiXP4jJ35upd5QTJSPEK' +
'QdAuHXA9XbG3T9nrM4xp87K7bcPbsQs/gya2cICuq/2WtJW/+w0L4' +
'R/S7HqyrHqGsIzS1f1gy9u1708ee9q3VV9xRKp97Jalf8Kr8AnCga' +
'zgjMxjIVK+XpPE0/fwyH1/02KxItCizVV1MVEY4vR35BtDHNwBNDz' +
's6JrB+q1IQjqsys2aKClhydC5h5jaa6dKq8fJZjpDCV+Vf7KTw7sA' +
'QggIEZmv1rgoKiLpQQKX3h2zhodKayY4YrC2oElyx7r61hBH97N1E' +
'EQcWR4+WnA2fUBQYLDlxmNf9yEylp3JZmO2VDU5T9XB00xECRW+e9' +
'Axe2eGi6NhBqkIs223R4AIdM5RTGlRA2Upj69aHRIoKeECanARcsA' +
'aSlkqn0KkAkHcVVAJy4SjNgMlEbWxHjW4o6a0NsPFiRwURrxRDYpC' +
'lcWaRv+pt/uAGpF4Ra33YOFbhAinekkV6rGAQ9Ghs+FZTOVK0RSjg' +
'A5AoDyH1TNsgiSPUemsFvJ1p4Uwf0Ei49kgyE6QXO/KFoIoGIioVk' +
'QQQ4SVXih1IUcjXB4glCRqCmQDs6fo8IH5v5i/aLxs8k6eeEf2ccD' +
'RPWuLj6DSeTqJ4TOPoyqsrHpXGW7/BlofGPknjtlQGNzBirNnCSPD' +
'1jxsjaYkOG3OXEicbuVmX88SBP2HWg3D6szYWketsSFrZMBS36cOi' +
'Cu8UUsZwrpQRxpdHW4sbRtnWNEUYanFzgeitBI0+HaQUhdnjPqA2H' +
'm07/wqZfM40gcIe4PNf4mofYCombtR3JI6ACk3T2NVuTk7bcZyRqI' +
'YZZTWBhNHSUZKmo0QVeKGr9wXfXxpEY12tfrFatLaQ0r4yn/lkWe4');
SetTargetBitmap(Bmp);
FindColors(Test,131072 ,0,0,37,35);
Bmp2 := CreateBitmap(38,38);
DrawTPABitmap(Bmp2,Test,clRed);
DrawTPABitmap(Bmp2,FloodFillEdge(test,Point(10, 16),IntToBox(0,0,38,38)),clYellow);
DisplayDebugImgWindow(38,38);
DrawBitmapDebugImg(Bmp2);
end.

nielsie95

2011-01-30 11:04:48

Nice, Ray :)

WT-Fakawi

2011-01-30 11:07:12

By Jove!

You've got it! You've actually got it!

EDIT: The StartPT : TPoint has to be inside the TPA (in the flood) in order for your function to work, right?…at least, that's what I have come up with. Would it be at all possible to omit the StartPT variable, and make it just return the Flood of any given offered TPA?

nielsie95

2011-01-30 14:21:02

Change line 119 to:

DrawTPABitmap(Bmp2,ReturnPointsNotInTPA(CombineTpa(Test, FloodFillEdge(test,Point(0, 0),IntToBox(0,0,38,38))), IntToBox(0,0,38,38)),clYellow);

That paints everything inside without the need of a StartPT. It just uses the first pixel (0,0) to fill everything around the edge and then inverts it.

WT-Fakawi

2011-01-30 14:52:42

Aaaa, so it is the CombineTPA of the ReturnPointsNotInTPA of the original object TPA? Why didn't I think of that? Trying soo hard to understand it all, but ol' Man Fakawi is having a hard time with it.

Aaah well, at least I am back programming :)

EDIT:

So, Ray, what you so is create a one bit empty matrix, and stamp the TPA onto it? And after that you fill it horizontally by going until the next boolean change? Just trying to comprehend.

The Claw

2011-02-01 00:32:51

Why not get the TPA of each invent box, then remove the black line and outside-background colours?

Array of TPA := Get all points of all invent boxs with items, split into 28
for i := 0 to 28 do
for z := 0 to GetArrayLength(ArrTPA[i]) do
if ArrTPA[i].z = black or invent-background with tol then
remove point
else
keep point there

PS - Is this nearly done-ish? Almost exactly the sort of system I need for my current script in progress. Somehow. :p

Boreas

2011-02-01 00:38:24

Did Narcle do something like this in his smelter?

mastaraymond

2011-02-01 04:09:18

From: WT-Fakawi
Aaaa, so it is the CombineTPA of the ReturnPointsNotInTPA of the original object TPA? Why didn't I think of that? Trying soo hard to understand it all, but ol' Man Fakawi is having a hard time with it.

Aaah well, at least I am back programming :)

EDIT:

So, Ray, what you so is create a one bit empty matrix, and stamp the TPA onto it? And after that you fill it horizontally by going until the next boolean change? Just trying to comprehend.

Yeah, it puts the edges into an empty matrix then it just does a (stack based 4-way) floodfill from the startpoint:

Nielsie starts filling from the corner, meaning that it will return all the points outside of the item. Then he just inverts this, so that it contains all the points of the item exactly :).

So now something like GetColors(TPA) would return all the colors of the item, which then can be used for some fancy calculation.