SRL Archive - Test corner

Some Inventory stuff


Boreas

2009-07-21 22:33:48

These work with only the clickable areas of inventory slots. No more miss clicks with InvBox. And if you somehow get bad coords from another method, CoordsToItem will predict whether it will be a miss click. Also, since InvBox is accurate, if you want to do something like BlackLists, you can use the x1,y1 as a reference point (sort of like the parent point of a DTM).

{*******************************************************************************
Function InvBox(i :Integer): TBox;
By: Boreas. Coords by Ogre July 15th 2009.
Description: Returns TBox of surrounding Inventory SlotBox
1-2-3-4
5-6-7-8
etc.
*******************************************************************************}

function InvBox(i :Integer): TBox;
var Slot1, Slot6: TBox;
begin
if not InRange(I, 1, 28) then
begin
srl_Warn('InvBox', 'Incorrect index: ' + IntToStr(i), warn_AllVersions);
exit;
end;
Slot1 := IntToBox(563,213,594,244); //update these
Slot6 := IntToBox(605,249,31415,92653); //except pi :p
Result.x1 :=Slot1.X1+((((i+(4-1))mod 4))*(Slot6.X1-Slot1.X1)); //4 for number
Result.y1 :=Slot1.Y1+((((i-1)/4))*(Slot6.Y1-Slot1.Y1)); //of columns
Result.x2 := Result.x1+(Slot1.X2-Slot1.X1);
Result.y2 := Result.y1+(Slot1.Y2-Slot1.Y1);
end;

procedure MMouseItem(i: Integer);
var
TB: TBox;
begin
GameTab(tab_inv);
TB:=InvBox(I);
MouseBox(TB.X1, TB.Y1, TB.X2, TB.Y2,3);
end;

{*******************************************************************************
function CoordsToItem (ThePoint: TPoint): integer;
By: Boreas
Description: Returns which Inventory slot a ThePoint is in. If point is between
slots (or not in the inventory area at all) it will return 0.
*******************************************************************************}
function CoordsToItem (ThePoint: TPoint): integer;
var tmpBox: TBox;
begin
if not PointInBox(ThePoint, IntToBox(MIX1, MIY1, MIX2, MIY2)) then
exit;
for Result:=1 to 4 do
begin
tmpBox := InvBox(result);
if InRange(ThePoint.x, tmpBox.x1, tmpBox.x2) then
break;
end;
while not InRange(ThePoint.y, tmpBox.y1, tmpBox.y2) do
begin
IncEx(result,4);
if result>28 then
break;
tmpBox := InvBox(result);
end;
if not PointInBox(ThePoint, tmpBox) then
Result := 0;
end;

ShowerThoughts

2009-07-21 22:35:33

Vacation 0.o?

Boreas

2009-07-21 22:45:50

I'm slowly shaking off the rust :p

EvilChicken!

2009-07-21 22:56:32

MANY parentheses.. :eek:


This looks, ehm, math-ish.
It's ready to be comitted, right? Why didn't you commit it yourself?

Sir R. M8gic1an

2009-07-21 23:37:13

<3 Coords to box. GJ

~RM

noidea

2009-07-21 23:56:27

The beast is back :p
Good job Boreas :)

Naum

2009-07-22 00:13:37

From: Boreas
These work with only the clickable areas of inventory slots. No more miss clicks with InvBox. And if you somehow get bad coords from another method, CoordsToItem will predict whether it will be a miss click. Also, since InvBox is accurate, if you want to do something like BlackLists, you can use the x1,y1 as a reference point (sort of like the parent point of a DTM).

{*******************************************************************************
Function InvBox(i :Integer): TBox;
By: Boreas. Coords by Ogre July 15th 2009.
Description: Returns TBox of surrounding Inventory SlotBox
1-2-3-4
5-6-7-8
etc.
*******************************************************************************}

function InvBox(i :Integer): TBox;
var Slot1, Slot6: TBox;
begin
if not InRange(I, 1, 28) then
begin
srl_Warn('InvBox', 'Incorrect index: ' + IntToStr(i), warn_AllVersions);
exit;
end;
Slot1 := IntToBox(563,213,594,244); //update these
Slot6 := IntToBox(605,249,31415,92653); //except pi :p
Result.x1 :=Slot1.X1+((((i+(4-1))mod 4))*(Slot6.X1-Slot1.X1)); //4 for number
Result.y1 :=Slot1.Y1+((((i-1)/4))*(Slot6.Y1-Slot1.Y1)); //of columns
Result.x2 := Result.x1+(Slot1.X2-Slot1.X1);
Result.y2 := Result.y1+(Slot1.Y2-Slot1.Y1);
end;

procedure MMouseItem(i: Integer);
var
TB: TBox;
begin
GameTab(tab_inv);
TB:=InvBox(I);
MouseBox(TB.X1, TB.Y1, TB.X2, TB.Y2,3);
end;

{*******************************************************************************
function CoordsToItem (ThePoint: TPoint): integer;
By: Boreas
Description: Returns which Inventory slot a ThePoint is in. If point is between
slots (or not in the inventory area at all) it will return 0.
*******************************************************************************}
function CoordsToItem (ThePoint: TPoint): integer;
var tmpBox: TBox;
begin
if not PointInBox(ThePoint, IntToBox(MIX1, MIY1, MIX2, MIY2)) then
exit;
for Result:=1 to 4 do
begin
tmpBox := InvBox(result);
if InRange(ThePoint.x, tmpBox.x1, tmpBox.x2) then
break;
end;
while not InRange(ThePoint.y, tmpBox.y1, tmpBox.y2) do
begin
IncEx(result,4);
tmpBox := InvBox(result);
if result>28 then
break;
end;
if not PointInBox(ThePoint, tmpBox) then
Result := 0;
end;


It's cool but still old school ;). Only you can do that, GJ

EvilChicken!

2009-07-22 00:15:46

From: NaumanAkhlaQ
It's cool but still old school ;)


And really nessesary to quote his entire post?

ShowerThoughts

2009-07-22 00:16:58

From: EvilChicken!
And really nessesary to quote his entire post?


I am on MSN are you?

Anyway, Boreas nice code, could you explain some of it somehow?

Naum

2009-07-22 01:01:59

From: EvilChicken!
And really nessesary to quote his entire post?


I'm on the iPhone 2G, blame apple not me :p

Boreas

2009-07-22 02:12:46

From: Hermen
Anyway, Boreas nice code, could you explain some of it somehow?

I'm not very good at explaining, so any questions are welcome.

{*******************************************************************************
Function InvBox(i :Integer): TBox;
By: Boreas. Coords by Ogre July 15th 2009.
Description: Returns TBox of surrounding Inventory SlotBox
1-2-3-4
5-6-7-8
etc.
*******************************************************************************}

function InvBox(i :Integer): TBox;
var Slot1, Slot6: TBox;
begin
if not InRange(I, 1, 28) then
begin
srl_Warn('InvBox', 'Incorrect index: ' + IntToStr(i), warn_AllVersions);
exit;
end;
[COLOR="Red"] //Nothing new there[/COLOR]

Slot1 := IntToBox(563,213,594,244); //update these
[COLOR="Red"] //These are the X1 Y1 X2 Y2 of the first row first column[/COLOR]
Slot6 := IntToBox(605,249,31415,92653); //except pi :p
[COLOR="Red"] //These are the X1 Y1 of the second row, second column
//(which is 6 if you have 4 colums)
//you really only need the first 2, so you could use a tpoint
//but I thought 2 Tboxes looked better, so I filled in pi for the lulz

//You can update these by hovering the mouse over the item in spot 1
//and moving left until the uptext no longer says the items name,
//then move 1 pixel right so that the uptext does say the item, and that is X1
//Same idea for the rest.
[/COLOR]
[COLOR="Red"] //If need be, the number of columns can be updated by changing all the 4s
//below. This is why it says 4-1 and not 3.[/COLOR]

Result.x1 :=Slot1.X1+((((i+(4-1))mod 4))*(Slot6.X1-Slot1.X1));
[COLOR="Red"] //This is just like A+(B*C)
//A is the starting point, the very left
//B is how many blocks we want to add on the starting point
//C is how wide each block is.
//C is (Slot6.X1-Slot1.X1), the distance between the start of the first
//column and the start of the second column
//B needs to be 0 for the 1st column, because we are adding nothing
//1 for the 2nd col, because we are adding 1 block, etc so 0 1 2 3
//0 1 2 3 are all the possible values (SomeInt mod 4) can give
//All we need to do is add 3 (one less than the number of coulmns) to the
//slot numbers, and we get 0 1 2 3, repeated for each row[/COLOR]

Result.y1 :=Slot1.Y1+((((i-1)/4))*(Slot6.Y1-Slot1.Y1));
[COLOR="Red"]//Same idea here, except B is different
//This time for B we need 0 1 2 3 4 5 6
//4 goes into 0, 1, 2, and 3 0 times (integers here so no fractions)
//but we need that to work with 1 2 3 4, so we just -1[/COLOR]

Result.x2 := Result.x1+(Slot1.X2-Slot1.X1);
Result.y2 := Result.y1+(Slot1.Y2-Slot1.Y1);
[COLOR="Red"] //Each slot is the same size, so we just look at the width and height of
//the first slot, and apply that to the rest[/COLOR]

end;

procedure MMouseItem(i: Integer);
var
TB: TBox;
begin
GameTab(tab_inv);
TB:=InvBox(I);
[COLOR="Red"] //Because InvBox will now only give you the clickable area
//theres no need to look at the bounds of the black outline[/COLOR]
MouseBox(TB.X1, TB.Y1, TB.X2, TB.Y2,3);
end;

{*******************************************************************************
function CoordsToItem (ThePoint: TPoint): integer;
By: Boreas
Description: Returns which Inventory slot a ThePoint is in. If point is between
slots (or not in the inventory area at all) it will return 0.
*******************************************************************************}
function CoordsToItem (ThePoint: TPoint): integer;
var tmpBox: TBox;
begin
if not PointInBox(ThePoint, IntToBox(MIX1, MIY1, MIX2, MIY2)) then
exit;
[COLOR="Red"]//Returns 0 if not in inverntory at all

//This is almost like looping thru each spot with InvBox
//and checking whether the point is in the Tbox, except with
//2.64 less InvBox checks, making it 2 to 3 times faster, even though
//more lines of code are used. This starts off in the first slot, and moves
//right until it finds a match for X, then moves down until it finds a match
//for Y, making a 7 shape, or rotated L.[/COLOR]

for Result:=1 to 4 do
begin
tmpBox := InvBox(result);
if InRange(ThePoint.x, tmpBox.x1, tmpBox.x2) then
break;
end;
[COLOR="Red"] //First, loop through the top 4 boxes, and break out when it is in the same
//X range, the same column[/COLOR]
[COLOR="Red"]
//Now that we know what column it is in, we look for row[/COLOR]
while not InRange(ThePoint.y, tmpBox.y1, tmpBox.y2) do
[COLOR="Red"] //if the slot happens to be in the first row, we dont even need to do the
//next part, so we check if it is in the current Y range[/COLOR]
begin
IncEx(result,4);
[COLOR="Red"] //if it isn't, we +4 to get to the slot below it[/COLOR]
if result>28 then
break; [COLOR="Red"]//we got thru the whole thing with no match, must be a bad point[/COLOR]
tmpBox := InvBox(result);
[COLOR="Red"] //try the while condition again with this box
//continue going down until we get match for Y[/COLOR]
end;

[COLOR="Red"] //The for loop has a finite end, and the break is for a positive result.
//In the case of a bad coord, it will just finish at 4.
//The while loop could go forever it doesn't find a match making the
//while condition true, so we have a break for the case of no matches.
//And here is where we deal the bad coords.[/COLOR]
if not PointInBox(ThePoint, tmpBox) then
Result := 0;
end;

Here is where I got 2.64 from:
If you just loop thru 28 InvBoxs until you get a match, the fastest scenario is if it's the first slot, and you check 1. The slowest is 28, taking 28 checks. With the column-then-row method, the slowest is 10 checks, where you go through all 4 boxes in the first row, and then check the 6 rows below it. If you look at the number of checks for spots 1 to 28, the average number of checks is 5.5, instead of 14.5. 14.5/5.5= 2.64 :)



@EC: lost my SVN pass a long time ago.

EvilChicken!

2009-07-22 05:57:14

I comitted this.
Thanks a lot.

Boreas

2009-07-22 07:03:14

Np. Thanks for fixing the point vs x,y thing. I originally wrote it as PointToInvSlot(ThePoint, but then I noticed there was a function that did the same thing, so then I renamed it to match the old one, but didn't notice old one was X,Y :duh:

Nava2

2009-07-22 07:12:10

Just ask the Wizzup for a new one.. :)

ZephyrsFury

2009-07-22 09:13:12

Wait wat! Didn't I already do this…like last week?

Boreas

2009-07-22 16:00:40

That was just the first 2, this is also a matching CoordsToItem. Plus RM committed without checking out, overwriting the changes from last week.

Sir R. M8gic1an

2009-07-22 16:07:26

From: Boreas
That was just the first 2, this is also a matching CoordsToItem. Plus RM committed without checking out, overwriting the changes from last week.


/me apologizes :$

~RM

Boreas

2009-07-22 23:15:39

Don't worry about it :). Just next time, remember to overwrite somebody else's function instead of mine :p