PDA

View Full Version : function CheckIfInCombat(XpCounter, MaxTime: Integer): Boolean;



J J
06-07-2012, 12:34 PM
function CheckIfInCombat(XpCounter, MaxTime: Integer): Boolean;
var
X, Y, OldXp, NewXp, ShieldBitmap, SwordBitmap, t: Integer;

begin
ShieldBitmap := BitmapFromString(6, 6, 'meJxzMmU1Pv7PyZS1MpIdSNbf/lcY' +
'zAZkFIeAuOEXQVIbazggghCVzfHsQBEgQ2Q/QuPOZk6IGrjK/W2cQ' +
'EGgSiCCmAYAgGAjCw==');
SwordBitmap := BitmapFromString(5, 5, 'meJxzv/svNiEBiC5durRz9Xr3u/+A' +
'qLu7G8iGcFW3gRCQzVK1hSFkM4QLREAuu0U6kIRzAaL/Koo=');
OldXp := GetXpBar(XpCounter);

if Debug then
begin
SMART_ClearCanvas;
WriteLn('OldXp: '+IntToStr(OldXp)+'');
SMART_DrawBoxes(False, [IntToBox(MSCX-15, MSCY-50, MSCX+15, MSCY)], clRed); // Shield
SMART_DrawBoxes(False, [IntToBox(MSCX-20, MSCY-50, MSCX+10, MSCY)], clYellow); // Sword
end;

MarkTime(t);
repeat
Wait(50 + Random(50));
NewXp := GetXpBar(XpCounter);
if Debug then
WriteLn('NewXp: '+IntToStr(NewXp)+'');
until (FindBitmapToleranceIn(ShieldBitmap, X, Y, MSCX-15, MSCY-50, MSCX+15, MSCY, 20)) or (FindBitmapToleranceIn(SwordBitmap, X, Y, MSCX-20, MSCY-50, MSCX+10, MSCY, 20)) or (NewXp > OldXp) or (TimeFromMark(t)>MaxTime);
if TimeFromMark(t)<MaxTime then
Result := True;

FreeBitmap(ShieldBitmap);
FreeBitmap(SwordBitmap);
end;

Debug when found xp increase

OldXp: 1337192
NewXp: 1337192
NewXp: 1337192
NewXp: 1337192
NewXp: 1337192
NewXp: 1337192
NewXp: 1337192
NewXp: 1337192
NewXp: 1337260
In combat!

Debug when found a bitmap

OldXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
NewXp: 1337309
In combat!

Shield bitmap
http://img840.imageshack.us/img840/4792/shieldbitmap.png

Weapon bitmap
http://img11.imageshack.us/img11/9025/swordbitmap.png

In action
if CheckIfInCombat(1, 5000) then
WriteLn('In combat!');
XpCounter is set to number #1
Checks if it is in combat for max of 5000 ms

http://img215.imageshack.us/img215/6566/incombatx.png
Yellow box: searches for shield bitmap there
Red box: searches for attack bitmap there
Xp counter: checks for xp changes

It has been very accurate for me so far, let me know what you think.

[S]paz
06-07-2012, 12:43 PM
Would the xp counter work if you were doing something else?
EG mining near aggressive mobs?

Although nice function :)

Olly
06-07-2012, 12:55 PM
Looks nice, you could even back it up even more with hp bars :P

J J
06-07-2012, 01:13 PM
paz;1041732']Would the xp counter work if you were doing something else?
EG mining near aggressive mobs?

Although nice function :)
Well if you put a combat skill of your choice (eg. attack) on xp counter 1 and if you have auto retaliate on, it will work. If you get attack xp it means you are in combat, or it has found one of the symbols. But if you put overall on it will also detect mining xp as being in combat, so you have to use the right xp counter that doesn't include the non combat skill you are training.


Looks nice, you could even back it up even more with hp bars :P
Yeah we just talked on Skype :P I think this is more than enough and it fine for me. Other players could run through you and it could detect their HP bar. Other players' shield/attack icons can't be in the area it searches for, only yours can be in there :P

NCDS
06-07-2012, 03:24 PM
Does srl_InFight(); not work anymore?

J J
06-07-2012, 04:28 PM
Does srl_InFight(); not work anymore?
It does, but this is a more accurate and faster way to check if you are indeed in combat
(*
srl_InFight
~~~~~~~~~~~

.. code-block:: pascal

function srl_InFight: Boolean;

Checks whether player currently is in a fight, using mainscreen
HP bar presence detection. Returns True if Player's HP bar is detected.
Idea for improvement: Also check using PixelShift(); to see whether Player
is performing fighting animations to further improve the certainty of results.

.. note::

by Narcle

Example:

.. code-block:: pascal

while srl_InFight do
begin
CheckHP;
EatFood;
end;

*)
Function srl_InFight: Boolean;
begin
Result := InRange(Length(GetFightBarTPA(MFBox)), 30, 240);
end;

Mainly this part
Idea for improvement: Also check using PixelShift(); to see whether Player
is performing fighting animations to further improve the certainty of results.
Since the release of SRL_InFight there have been updates to add that blue shield & attack symbol so I made a new function that relies on those and on xp gains instead of hp bar presence.

Abu
06-07-2012, 05:27 PM
Hmmm

Okay let's say I want to check if I'm in combat while I'm mining - this won't work as my xp will already be changing.

J J
06-07-2012, 06:26 PM
Hmmm

Okay let's say I want to check if I'm in combat while I'm mining - this won't work as my xp will already be changing.
Answered that exact thing earlier

Well if you put a combat skill of your choice (eg. attack) on xp counter 1 and if you have auto retaliate on, it will work. If you get attack xp it means you are in combat, or it has found one of the symbols. But if you put overall on it will also detect mining xp as being in combat, so you have to use the right xp counter that doesn't include the non combat skill you are training.
TL;DR: You can choose a counter of your choice, if you put mining on counter #1 and a combat skill on counter #2 you can use counter #2 to check if you are in combat if you have auto retaliate on.

Abu
06-07-2012, 06:30 PM
Answered that exact thing earlier

TL;DR: You can choose a counter of your choice, if you put mining on counter #1 and a combat skill on counter #2 you can use counter #2 to check if you are in combat if you have auto retaliate on.

Ahh missed that thanks.

Recursive
06-07-2012, 06:38 PM
Suggestion:
Remove this part from the code

or (NewXp > OldXp);

The first part of finding the blue shield splat thing and the sword is enough cause as most people already stated it might get confused if you are doing an activity that is not focused on combat but has a possibility of becoming engaged in combat; and can pick up on the increase in xp as being in combat.

Moving on...what if you are fighting with ranged or magic, it won't be able to pick up that you are in combat if it is doesn't find the blue splat cause the ranging or magic icon will be present.

You can also try and merge this with Srl_inFight and it could check for all those icons being visible and also check srl_infight.

J J
06-07-2012, 06:58 PM
Suggestion:
Remove this part from the code

or (NewXp > OldXp);

The first part of finding the blue shield splat thing and the sword is enough cause as most people already stated it might get confused if you are doing an activity that is not focused on combat but has a possibility of becoming engaged in combat; and can pick up on the increase in xp as being in combat.

Moving on...what if you are fighting with ranged or magic, it won't be able to pick up that you are in combat if it is doesn't find the blue splat cause the ranging or magic icon will be present.

You can also try and merge this with Srl_inFight and it could check for all those icons being visible and also check srl_infight.
SRL_InFight relies on the hp bar. When you are maging/ranging and safespotting it won't be above your head either so there is no point in using SRL_InFight. Checking the xp has a point though because that means you have attacked something with ranged or magic :)

Also for the "confusing" part when skilling, it is a scripters choice to add this to their script. If they decided to add it they will know that this relies on the xpbar aswell. Then they can add it to their mainpost :P

I could add the SRL_InFight part but your xp bar will update earlier than your hp bar and/or blue shield and/or damage splat (attack icon) will be visible. Once your hp bar is visible it also means that you have got hit so either a damage splat (=attack icon) or blue shield is visible (blocking damage) so it would be a bit of an overkill really. If you are fighting a small monster it could also pick up the hp bar of the small monster instead of yours.

litoris
06-19-2012, 10:56 AM
Just bumping this here, I have had problems with srl_infight lately but didn't have any problems with this function. It's much more useful when using ranged or mage because it sometimes takes a while before the opponent hits you.

bolshak25
06-19-2012, 05:25 PM
NewXp := GetXpBar(1);

shouldnt that be

NewXp := GetXpBar(XPCounter);

J J
06-19-2012, 08:40 PM
Just bumping this here, I have had problems with srl_infight lately but didn't have any problems with this function. It's much more useful when using ranged or mage because it sometimes takes a while before the opponent hits you.
Great :P This will indeed instantly see the xp pop up when ranging/maging.


NewXp := GetXpBar(1);

shouldnt that be

NewXp := GetXpBar(XPCounter);
o.O Yeah it should be, forgot to change it I guess, thanks :P

Shatterhand
06-20-2012, 12:19 PM
By the way this function would be shorter/easier if it was waiting for xp increasing or blue shield only.
When are we in fight? If we do a hit, xp gets increased, if we hit zero, a blue shield appears on the monster.
XP reading works flawless, its like 99.999% safe so you should remove the sword dtm part.
And you cant see other fights' blue shields, so just do MSX1,MSY1,MSX2,MSY2 for that.
This is what im using in my fighter scripts:
function WaitInFight(Timeout: Integer) : Boolean; //waits until Timeout or till we get into a fight (will return true in this case)
var
X,Y,XP1,XP2,ShieldDTM,Time : Integer;
begin
XP1 := GetXPBar(XPCounter);
MarkTime(Time);
ShieldDTM := DTMFromString('mQwAAAHicY2ZgYGBlYWAQAmIOIJZmZGCQAm J1IGax9mT4+/cvA9eCJwxcQHUwzIiEgQAAxXEFvA==');
repeat
XP2 := GetXPBar(XPCounter);
if (XP2 > XP1) then
begin
if DebugLines then
Writeln('XP is increased, we are fighting.');
if PaintDebug then
begin
SMART_DrawBoxEx(false,IntToBox(524,54,543,73),ClYe llow);
Wait(100);
SMART_ClearCanvasArea(IntToBox(520,50,547,77));
end;
Result := True;
FreeDTM(ShieldDTM);
Exit;
end;
if (TimeFromMark(Time) > 3000) and FindDTM(ShieldDTM,X,Y,MSX1,MSY1,MSX2,MSY2) then
begin
if DebugLines then
Writeln('Blue shield found, we are fighting.');
Result := True;
FreeDTM(ShieldDTM);
Exit;
end;
until (TimeFromMark(Time) > Timeout)
FreeDTM(ShieldDTM);
Result := False;
end;
This starts looking for blue shield only after 3 seconds to avoid getting false detection because of the previous fight. I usually set the timeout to 5 seconds.