Idk what's wrong is it me or is the script slow ? It rarly kills anything..
Printable View
Idk what's wrong is it me or is the script slow ? It rarly kills anything..
If anyone wants to beta test the autocoloring version, I think it's stable enough to let you try.
It's a long way from done so keep an eye on it. I killed myself yesterday.
When the form comes up, type "autodetect" into the NPC name.
The first time you fight something takes a while to get some colors but once it gets cranking it gets better and better. If you return to an NPC you already colored it gets right down to business.
Replace your SIMBADIR/scripts/bonsaiFighter.simba and SIMBADIR/includes/bonsai/libnpc.simba with the below.
SIMBADIR/includes/bonsai/libcolorizer.simba is a new file, put it in place.
Let me know how you do!!
SIMBADIR/scripts/bonsaiFighter.simba:
Simba Code:// -----------------------------------------------------------------------------
// -- bonsaiFighter.simba
// -- Written by: bonsai
// -----------------------------------------------------------------------------
program bonsaiFighter;
{$DEFINE SMART}
{$DEFINE DEBUG_ON}
{$include_once srl-6/srl.simba}
{$include_once srl-6/lib/misc/srlplayerform.simba}
{$include_once bonsai/libnpc.simba}
{$include_once bonsai/libitem.simba}
{$include_once bonsai/libtracker.simba}
{$include_once bonsai/libbreak.simba}
{$f-}
// -----------------------------------------------------------------------------
// -- CUSTOMIZING
// --
// -- Script is customized by using the form that pops up when you run it
// --
// -- To add NPCs, you edit SIMBADIR/includes/bonsai/libnpcUser.xml.
// -- See the script thread for more information.
// -----------------------------------------------------------------------------
const
scriptName = 'bonsaiFighter';
bonsaiFighterVersion = '2.0';
bonsaiFighterVerUrl = 'http://pastebin.com/raw.php?i=pTW8JsUM';
bonsaiFighterCodeUrl = 'http://pastebin.com/raw.php?i=94U0sEny';
bonsaiFighterXmlVerUrl = 'http://pastebin.com/raw.php?i=asBUvqnX';
bonsaiFighterXmlCodeUrl = 'http://pastebin.com/raw.php?i=KDTDguyH';
var
healthPercentToEatAt: integer = 50;
healthPercentToQuit: integer = 25;
healthTimer: TTimeMarker;
logoutWhenExiting: boolean = false;
playerName: string = 'noname';
playerFile: string = 'nofile';
desiredWorld: integer = 0;
mouseStyle: integer = MOUSE_RIGHT;
cantFindNpcLoops: integer = 150;
manualAbilities: boolean = false;
averageSessionMin: integer = 120;
sessionVarianceMin: integer = 20;
averageBreakMin: integer = 17;
breakVarianceMin: integer = 5;
graphicsMode: string = 'OpenGL';
npcToFight: string = 'autodetect';
// -----------------------------------------------------------------------------
// doPlayerLogin()
//
// Checks if the player is logged in and attempts to log it in if not.
// Also sets screen settings to our default (overhead view).
// Takes a screenshot to help debug why the user would need to get
// logged in.
// -----------------------------------------------------------------------------
procedure doPlayerLogin();
begin
if (not isLoggedIn()) then
begin
writeln('***** Logging player in');
takeScreenshot(scriptName + '.png');
if (not players[currentPlayer].login()) then
begin
writeln('*************************************************');
writeln('***** ERROR GETTING PLAYER LOGGED IN, EXITING!!!');
writeln('*************************************************');
terminateScript();
end
else
begin
mainscreen.setangle(MS_ANGLE_HIGH);
exitSquealOfFortune();
end;
end;
end;
// -----------------------------------------------------------------------------
// checkHealthAndEat()
//
// Checks the health percentage and eats if needed. If health is too low
// it initiates shutdown so we don't die. Uses a timer so it doesn't check
// it too frequently.
// -----------------------------------------------------------------------------
procedure checkHealthAndEat();
var
hp: integer;
begin
if (healthTimer.getTime() < 8000) then
exit;
hp := actionbar.getHPPercent();
{$IFDEF DEBUG_ON}
writeln('***** Health check returning ', hp, ' percent');
{$ENDIF}
if (hp < healthPercentToEatAt) then
sendKeys('z', 250, 40);
if (hp < healthPercentToQuit) then
begin
writeln('***** Terminating script due to low health');
terminateScript();
end;
healthTimer.start();
end;
// -----------------------------------------------------------------------------
// antiBan()
//
// This gets called often to provide some random actions.
// -----------------------------------------------------------------------------
procedure antiBan();
begin
case (random(275)) of
1, 19, 35, 60:
begin
{$IFDEF DEBUG_ON} writeln('****** antiBan [move off client and sleep]'); {$ENDIF}
mouseOffClient(OFF_CLIENT_RANDOM);
wait(randomRange(5000,10000));
end;
5,8,15,25,28,35,38,45,48:
begin
{$IFDEF DEBUG_ON} writeln('****** antiBan [sleep and move mouse] + [secondary]'); {$ENDIF}
sleepAndMoveMouse(randomRange(2000,3000));
case (random(12)) of
1: randomRclickItem();
2: sleepAndMoveMouse(randomRange(1000,2000));
3: pickUpMouse();
4,5,11: begin mouseOffClient(OFF_CLIENT_RANDOM); wait(randomRange(5000,10000)); end;
6: smallRandomMouse();
7: randomCompass(50, 150, true);
8: mouseMovingObject();
9,10: begin
tabStats.open();
mouseBox(tabStats.getSkillBox(random(25)), MOUSE_MOVE);
wait(randomRange(2750,4750));
tabBackpack.open();
end;
end; // case (random(12))
end;
end;
end;
// -----------------------------------------------------------------------------
// scriptShutdown()
//
// This function is put into the termination chain to be called whenever
// the script stops.
// -----------------------------------------------------------------------------
procedure scriptShutdown();
begin
{$IFDEF DEBUG_ON} writeln('****** ' + scriptName + ': Script shutting down'); {$ENDIF}
takeScreenshot(scriptName + '.png');
tracker.progressReport();
if (logoutWhenExiting and isLoggedIn()) then
players[currentPlayer].logout();
end;
// -----------------------------------------------------------------------------
// onBreakStart()
//
// This gets called whenever we start a break. Tells the time tracker we
// are paused.
// -----------------------------------------------------------------------------
procedure onBreakStart();
begin
tracker.pause();
end;
// -----------------------------------------------------------------------------
// onBreakEnd()
//
// This gets called when we come back from a break. Turns the timer back on
// and makes sure the player is logged in.
// -----------------------------------------------------------------------------
procedure onBreakEnd();
begin
tracker.resume();
doPlayerLogin();
end;
// -----------------------------------------------------------------------------
// initPlayerForm()
//
// Set up the form
// -----------------------------------------------------------------------------
procedure initPlayerForm();
var
i: integer;
n: Tnpc;
begin
with playerForm do
begin
name := scriptName + bonsaiFighterVersion;
scriptHelpThread := 'http://villavu.com/forum/showthread.php?t=106661';
scriptSettingsPath := scriptPath + scriptName + 'settings.txt';
editBoxLabels := ['World', 'When to eat (Health %)', 'When To Quit (Health %)', 'Loops Without Finding NPC',
'Session Length (Minutes)', 'Session Variance (Minutes)', 'Break Length (Minutes)', 'Break Variance (Minutes)'];
editBoxDefaults := [ '0', '50', '25', '150', '120', '20', '17', '5'];
checkBoxLabels := ['Manual Abilites', 'Logout when exiting'];
checkBoxDefaults := ['False', 'False'];
comboBoxLabels := ['Mouse Style', 'GraphicsMode', 'NPC'];
comboBoxDefaults := ['Left', 'OpenGL', 'autodetect'];
setLength(comboBoxItems, length(comboBoxLabels));
comboBoxItems[0] := ['Left', 'Right'];
comboBoxItems[1] := ['OpenGL', 'DirectX'];
// comboBoxItems[2] := n.listAllNpcs();
comboBoxItems[2] := ['i','need','to','write','this'];
end;
end;
// -----------------------------------------------------------------------------
// getPlayerForm()
//
// Get results from the form
// -----------------------------------------------------------------------------
procedure getPlayerForm();
var
i: integer;
mouseStr: string;
begin
players.setup(playerForm.playerNames, playerForm.playerFile);
if (length(players) < 1) then
begin
writeln('*************************************************************************');
writeln('***** ERROR: You did not provide a valid playername/nickname/player file');
writeln('*************************************************************************');
terminateScript();
end;
desiredWorld := StrToIntDef (playerForm.players[0].settings[0], 0);
healthPercentToEatAt := StrToIntDef (playerForm.players[0].settings[1], 50);
healthPercentToQuit := StrToIntDef (playerForm.players[0].settings[2], 25);
cantFindNpcLoops := StrToIntDef (playerForm.players[0].settings[3], 150);
averageSessionMin := StrToIntDef (playerForm.players[0].settings[4], 120);
sessionVarianceMin := StrToIntDef (playerForm.players[0].settings[5], 20);
averageBreakMin := StrToIntDef (playerForm.players[0].settings[6], 17);
breakVarianceMin := StrToIntDef (playerForm.players[0].settings[7], 5);
manualAbilities := StrToBoolDef(playerForm.players[0].settings[8], false);
logoutWhenExiting := StrToBoolDef(playerForm.players[0].settings[9], false);
mouseStr := lowercase (playerForm.players[0].settings[10]);
graphicsMode := playerForm.players[0].settings[11];
npcToFight := playerForm.players[0].settings[12];
case mouseStr of
'right', 'mouse_right':
mouseStyle := MOUSE_RIGHT;
'left', 'mouse_left':
mouseStyle := MOUSE_LEFT;
end;
currentPlayer := 0;
players[currentPlayer].world := desiredWorld;
end;
// -----------------------------------------------------------------------------
// MAIN
// -----------------------------------------------------------------------------
const
WAIT_FOR_END_OF_FIGHT = true;
trackingHeader: TStringArray = [
' ( )\ ) ) ) ',
' ( )\ ) ( (()/( ( ( ( ( /( ( /( ( ( ',
' )((_) ( ( ( ( /( )\ /(_)) )\ )\))( )\()) )\()) ))\ )( ',
'((_)_ )\ )\ ) )\ )(_))((_) (_))_|((_)((_))\ ((_)\ (_))/ /((_)(()\ ',
' | _ ) ((_) _(_/( ((_)((_)_ (_) | |_ (_) (()(_)| |(_)| |_ (_)) ((_)',
' | _ \/ _ \| '' \))(_-</ _` | | | | __| | |/ _` | | '' \ | _|/ -_) | ''_|',
' |___/\___/|_||_| /__/\__,_| |_| |_| |_|\__, | |_||_| \__|\___| |_| ',
' |___/ '];
// http://patorjk.com/software/taag/#p=display&f=Graffiti&t=Type%20Something%20
var
timesFailed: integer; // how many times did we fail to find an npc
npc: Tnpc; // object representing the npc we are fighting
pb: TBox;
begin
// initialize and prepare things
//
updater.check4update('bonsaiFighter.simba', bonsaiFighterVersion,
bonsaiFighterVerUrl, bonsaiFighterCodeUrl, false);
if (updater.wereUpdatesPerformed) then
begin
writeln('');
writeln('////////////////////////////////////////////');
writeln('////////////////////////////////////////////');
writeln('/// SCRIPT WAS UPDATED, CLOSE AND REOPEN ///');
writeln('/// SCRIPT WAS UPDATED, CLOSE AND REOPEN ///');
writeln('/// SCRIPT WAS UPDATED, CLOSE AND REOPEN ///');
writeln('/// SCRIPT WAS UPDATED, CLOSE AND REOPEN ///');
writeln('////////////////////////////////////////////');
writeln('////////////////////////////////////////////');
terminateScript();
end;
addOnTerminate('scriptShutdown');
initPlayerForm();
runPlayerForm();
if (not playerForm.isScriptReady) then
terminatescript;
getPlayerForm();
smartEnableDrawing := true;
tracker.init(scriptName, trackingHeader);
breakTimer.init(averageSessionMin, sessionVarianceMin,
averageBreakMin, breakVarianceMin, onBreakStart, onBreakEnd);
if (graphicsMode = 'DirectX') then
smartPlugins := ['d3d9.dll'];
SetupSRL();
disableSRLDebug := true;
// do the work
//
healthTimer.start();
timesFailed := 0;
while (true) do
begin
breakTimer.check4break();
doPlayerLogin();
checkHealthAndEat();
if (npc.name() = '') then
npc.init(npcToFight);
if (npc.name() = '') then
begin
writeln('****** Could not set up NPC [', npcToFight, '].');
break;
end;
if npc.attack(WAIT_FOR_END_OF_FIGHT, checkHealthAndEat, mouseStyle, manualAbilities) then
begin
{$IFDEF DEBUG_ON} writeln('***** Killed a ' + npc.name()); {$ENDIF}
timesFailed := 0;
antiBan();
tracker.recordKill(npc.name());
tracker.killHud();
if ((tracker.numKilled(npc) mod 15) = 0) then
tracker.progressReport();
case npc.colorCount() of
01..05: npc.colorize(10000, 5);
06..09: npc.colorize(2500, 10);
10..19:
begin
case random(10) of
0..6: npc.colorize(850, 20);
end;
end;
else
begin
case random(10) of
0,1: npc.colorize(400, 99999);
end;
end;
end;
end
else
begin // npc was not found
inc(timesFailed);
{$IFDEF DEBUG_ON}
writeln('****** Didnt find a ', npc.name(), ' to fight. timesFailed = ', timesFailed);
{$ENDIF}
if (timesFailed >= cantFindNpcLoops) then
begin
writeln('**** Terminating script due to too many failures to find npc');
break;
end;
if ((timesFailed mod 10) = 0) then
begin
{$IFDEF DEBUG_ON}
writeln('****** Having problems finding NPC, rotating cam.');
{$ENDIF}
npc.angleTowards();
// not sure how it happens but I found screenshot with bad angle when
// it failed.
mainscreen.setangle(MS_ANGLE_HIGH);
end;
if ((timesFailed mod 23) = 0) then
begin
{$IFDEF DEBUG_ON}
writeln('****** Having problems finding NPC, sleeping');
{$ENDIF}
wait(randomRange(3500,4500));
end;
if ((timesFailed mod 31) = 0) then
begin
{$IFDEF DEBUG_ON}
writeln('****** Having problems finding NPC, moving to closest yellow dot');
{$ENDIF}
npc.moveToClosest();
end;
end; // npc not found
end; // while (true)
writeln('***** Loop ended, terminating');
terminateScript();
end.
SIMBADIR/includes/bonsai/libnpc.simba:
Simba Code:// -----------------------------------------------------------------------------
// -- libnpc.simba
// -- Written by: bonsai
// -----------------------------------------------------------------------------
// {$DEFINE SMART}
{$include_once srl-6/srl.simba}
{$include_once bonsai/libupdater.simba}
{$include_once bonsai/libcolorizer.simba}
{$f-}
const
libnpcVersion = '2.0';
libnpcVerUrl = 'http://pastebin.com/raw.php?i=PmQqYTCq';
libnpcCodeUrl = 'http://pastebin.com/raw.php?i=UEsQSzsu';
type
Tnpc = record
_name : string; // runescape name for npc, is used as a key for lookups
_xp : extended; // combat xp received when killed
_constitutionXp : extended; // constitution xp received when killed
_colorizer : Tcolorizer;
_maxFightSeconds : integer; // how long is too long to be in a fight?
end;
const
// _npcInfightDTM = 'mlwAAAHicY2dgYOhkYWDoB+JJSLgPiLuAWIgRgsWBWAGINYBYC4q5BUVwYqBWnJgRD4YCAOi5Bls=';
_npcInfightDTM = 'mlwAAAHicY2eAAEYgZgViTiTMBpWTgGIxIOaDqgMBbkERnJgLKM+CAzPiwVAAAKx0AgE=';
var
_npcDtmId: integer;
_npcFightFlag: boolean = false;
// -----------------------------------------------------------------------------
// Tnpc access functions
//
// Simple functions to give users access to the object data. Users should
// not be accessing the internal data directly in case we change it.
// -----------------------------------------------------------------------------
function Tnpc.name(): string;
begin
result := self._name;
end;
function Tnpc.xp(): extended;
begin
result := self._xp;
end;
function Tnpc.constitutionXp(): extended;
begin
result := self._constitutionXp;
end;
function Tnpc.uptext(): String;
begin
result := self._colorizer.uptext;
end;
function Tnpc.dist(): integer;
begin
result := self._colorizer.dist;
end;
function Tnpc.minPixels(): integer;
begin
result := self._colorizer.minPixels;
end;
function Tnpc.maxPixels(): integer;
begin
result := self._colorizer.maxPixels;
end;
function Tnpc.maxFightSeconds(): integer;
begin
result := self._maxFightSeconds;
end;
function Tnpc.colorCount(): integer;
begin
result := length(self._colorizer.successful);
end;
// -----------------------------------------------------------------------------
// init()
//
// initialize an NPC object.
// -----------------------------------------------------------------------------
procedure Tnpc.init(npcName: string);
var
i: integer;
begin
self._colorizer.init(npcName, 'Attack', 150, 5, 10, 1, 2000);
if (npcName <> '') and (lowercase(npcName) <> 'autodetect') then
begin
self._name := npcName;
self._xp := 10; // need to look these up online
self._constitutionXp := 5;
self._maxFightSeconds := 60;
self._colorizer.load();
end;
if (lowercase(npcName) = 'autodetect') then
begin
{$IFDEF DEBUG_ON} writeln('****** Tnpc.init: Starting auto detect process'); {$ENDIF}
self.motionDetect();
writeln('****** Tnpc.init: Auto detected NPC: ' + self.name());
end;
end;
// -----------------------------------------------------------------------------
// equals()
//
// Function to compare one NPC object to another. Perhaps it's not solid
// but only the name field is checked. var is used even though compareTo
// is not changed. This is due to wierd lape violation errors when passing
// records around.
// -----------------------------------------------------------------------------
function Tnpc.equals(var compareTo: Tnpc): boolean;
begin
result := (self._name = compareTo.name());
end;
// -----------------------------------------------------------------------------
// angleTowards()
//
// Splits the minimap into quadrants and changes our view to the quadrant
// with the most NPCs in it
// -----------------------------------------------------------------------------
procedure Tnpc.angleTowards()
var
b: TBox;
c: TPoint;
quadrant: array[0..3] of TBox;
dotCount: TPointArray;
i, longest, longestQ, angl: integer;
begin
b := minimap.getBounds();
c := minimap.getCenterPoint();
// NE, SE, SW, NW
quadrant[0] := IntToBox(c.x, b.y1, b.x2, c.y);
quadrant[1] := IntToBox(c.x, c.y, b.x2, b.y2);
quadrant[2] := IntToBox(b.x1, c.y, c.x, b.y2);
quadrant[3] := IntToBox(b.x1, b.y1, c.x, c.y);
longest := -1;
for i := 0 to 3 do
begin
dotCount := minimap.getDots(MM_DOT_NPC, quadrant[i]);
if (length(dotCount) > longest) then
begin
longestQ := i;
longest := length(dotCount);
end;
end;
angl := trunc(minimap.getAngleDegrees()) + (45*((longestQ*2)+1));
if (angl > 360) then
angl := angl - 360;
{$IFDEF DEBUG_ON} writeln('***** Tnpc.angleTowards: Altering angle to ', angl); {$ENDIF}
minimap.setAngle(trunc(angl));
end;
// -----------------------------------------------------------------------------
// moveToClosest()
//
// Clicks on the closest yellow dot on the minimap in an attempt to get
// us back in view of an npc to fight. It's possible for it to click
// on something unrelated and make things worse :)
// -----------------------------------------------------------------------------
procedure Tnpc.moveToClosest()
var
yellowDots: TPointArray;
begin
yellowDots := minimap.getDots(MM_DOT_NPC, minimap.getBounds());
yellowDots.sortFromPoint(minimap.getBounds().getMiddle());
mouse(yellowDots[0], MOUSE_LEFT);
end;
// -----------------------------------------------------------------------------
// isInFight()
//
// Function to determine if the npc is in a fight.
// -----------------------------------------------------------------------------
function Tnpc.isInFight(suppressDebug: boolean = false): boolean;
var
votes, gold1, red1, box1, box2, green1, green2, dtmfs1, sum: integer;
tpa: TPointArray;
search: TBox;
begin
votes := 0;
gold1 := countColorTolerance(2726093, mainscreen.getBounds(),
9, colorSetting(2,0.14,2.16));
if (gold1 > 50) then
inc(votes);
if (gold1 > 80) then
inc(votes);
if (gold1 > 100) then
inc(votes);
red1 := countColorTolerance(3094484, mainscreen.getBounds(),
25, colorSetting(0));
if (red1 > 45) then
inc(votes);
box1 := countColorTolerance(1380618, mainscreen.getBounds(),
0, colorSetting(0));
if (box1 > 150) then
votes := votes + 2;
box2 := countColorTolerance(1381133, mainscreen.getBounds(),
2, colorSetting(0));
if (box2 > 150) then
votes := votes + 2;
green1 := countColorTolerance(3308832, mainscreen.getBounds(),
15, colorSetting(2, 0.27, 1.56));
if (green1 > 125) then
inc(votes);
search := mainscreen.playerBox;
search.expand(35);
green2 := countColorTolerance(45128, search, 9, colorSetting(2, 0.70, 0.00));
if (green2 > 40) then
inc(votes);
// if (findDTMs(_npcDtmId, tpa, mainscreen.getBounds())) then
// begin
// dtmfs1 := length(tpa);
// end;
// if (dtmfs1 > 1) then // if we can see more than one dtm, the mouse is
// smallRandomMouse(100); // probably on another npc so two popups are open
//
// sum := gold1 + red1 + box1 + box2 + green2 + green1 + dtmfs1;
if (votes > 4) then
result := true
else
result := false;
if (not suppressDebug) then
begin
{$IFDEF DEBUG_ON}
writeln('***** Tnpc.isInFight: result=', result, ' votes=', votes, ' gold1=', gold1,
' red1=', red1, ' box1=', box1, ' box2=', box2,
' green1=', green1, ' green2=', green2);
{$ENDIF}
end;
end;
// -----------------------------------------------------------------------------
// _doAbilities()
//
// Chooses available abilities during s fight
// -----------------------------------------------------------------------------
procedure Tnpc._doAbilities();
var
i, pct: integer;
keyStr: string;
begin
for i := 9 downto 1 do // used 9 to match revolution
begin
pct := actionBar.getAbilityCooldown(i);
// {$IFDEF DEBUG_ON}
// writeln('***** Tnpc._doAbilities: ability[', i, '] returned cooldown ', pct);
// {$ENDIF}
if (pct = 1) then
begin
case i of
0..9: keyStr := intToStr(i);
10: keyStr := '0';
11: keyStr := '-';
12: keyStr := '=';
end;
SendKeys(keyStr[1], 60 + Random(60), 60 + Random(60));
{$IFDEF DEBUG_ON}
writeln('***** Tnpc._doAbilities: activated ability[', i, ']');
{$ENDIF}
exit; // only do one ability
end;
end;
end;
// -----------------------------------------------------------------------------
// attack()
//
// Finds an NPC, initiates an attack, and (if asked to) waits for the fight
// to complete. Calls a user specified procedure to check if we need
// food and eat.
// -----------------------------------------------------------------------------
function Tnpc.attack(waitTilDead: boolean; foodProc: procedure; mouseStyle: integer = MOUSE_RIGHT;
manualAbilities: boolean = false): boolean;
var
t, i, x, y, col: integer;
b: TBox;
nname: string;
found, found2: boolean;
colList: TIntegerArray;
begin
with self._colorizer do
begin
// b := likelyBox(col);
b := multiBox(colList);
if not b.equals(intToBox(-1,-1,-1,-1)) then
begin
result := detectObj(x, y, nname, b, mouseStyle);
for i := 0 to high(colList) do
updateTrials(colList[i], result);
end
else
result := false;
end;
if (result and waitTilDead) then
begin
{$IFDEF DEBUG_ON} writeln('***** Tnpc.attack: Fight initiated'); {$ENDIF}
found := false;
found2 := false;
// give it time to run over and get into the fight
// if a smaller value is used it gets more kills/hr but
// sometimes it does take that long to run around
t := getSystemTime() + randomRange(3200,3900);
repeat
wait(50);
found := self.isInFight(true);
until (found or (getSystemTime() >= t));
i := 0;
t := getSystemTime() + (self._maxFightSeconds * 1000);
while self.isInFight() do
begin
found2 := true;
wait(randomRange(150,250));
if (i mod 15) = 0 then // don't call too frequently
begin
if (manualAbilities) then
self._doAbilities();
foodProc();
end;
if (getSystemTime() >= t) then
begin
{$IFDEF DEBUG_ON} writeln('****** Tnpc.attack: Something wrong... in fight too long'); {$ENDIF}
terminateScript();
end;
inc(i);
end;
if not (found or found2) then
begin
{$IFDEF DEBUG_ON} writeln('****** Tnpc.attack: Probable miss, did not detect start of fight'); {$ENDIF}
result := false;
end
else
begin
{$IFDEF DEBUG_ON} writeln('***** Tnpc.attack: End of fight detected'); {$ENDIF}
end;
end;
end;
// -----------------------------------------------------------------------------
// colorize()
//
// Tests new and in progress colors to try to find new ones that are successful.
// -----------------------------------------------------------------------------
function Tnpc.colorize(maxTime: integer = 120000; enough: integer = 5): boolean;
begin
result := self._colorizer.colorize(maxTime, enough);
end;
// -----------------------------------------------------------------------------
// motionDetect()
//
// Finds NPCs based on screen movement (pixel shift).
//
// Improves color knowledge until we have at least 5 successful colors to use.
// -----------------------------------------------------------------------------
function Tnpc.motionDetect(): string;
var
s, nname: string;
function strToNpc(s: string): string;
var
sa, sa2: TStringArray;
i: integer;
begin
// Returns the NPC name from strings like
// "Attack NPC NAME (level XX)"
// "Attack *NPC NAME (level XX)"
if (pos('Attack', s) <> 1) then exit;
sa := explode(' ', s);
if (length(sa) <= 1) then exit;
if (pos('*', sa[1]) > 0) then
begin
sa2 := explode('*', sa[1]);
sa[1] := sa2[1];
end
result := sa[1];
for i := 2 to high(sa) do
begin
if (pos('(', sa[i]) > 0) then break;
result := result + ' ' + sa[i];
end;
end;
begin
{$IFDEF DEBUG_ON} writeln('***** Tnpc.motionDetect: Starting ... '); {$ENDIF}
self.init('');
s := self._colorizer.motionDetect();
// nname := strToNpc(s);
nname := s;
if (s <> '') then
self.init(nname);
{$IFDEF DEBUG_ON} writeln('***** Tnpc.motionDetect: Detected ', nname, '(', s, ')'); {$ENDIF}
while (self.colorCount() < 5) do
begin
{$IFDEF DEBUG_ON} writeln('***** Tnpc.motionDetect: Trying to identify more colors'); {$ENDIF}
self.colorize(60000, 5);
end;
end;
// -----------------------------------------------------------------------------
// _npcTerminate
//
// This is hooked into the script termination stream. It frees up any
// DTMs we loaded.
// -----------------------------------------------------------------------------
procedure _npcTerminate();
begin
freeDTM(_npcDtmId);
end;
// -----------------------------------------------------------------------------
// initializer
//
// Ensures we call the function to free DTMS if the script exits.
// Checks for online updates.
// -----------------------------------------------------------------------------
begin
addOnTerminate('_npcTerminate');
// updater.check4update('libnpc.simba', libnpcVersion,
// libnpcVerUrl, libnpcCodeUrl, true);
_npcDtmId := DTMFromString(_npcInfightDTM);
end;
SIMBADIR/includes/bonsai/libcolorizer.simba:
Simba Code:// -----------------------------------------------------------------------------
// -- libcolorizer.simba
// -- Written by: bonsai
// -----------------------------------------------------------------------------
// {$DEFINE SMART}
{$include_once srl-6/srl.simba}
{$include_once bonsai/libupdater.simba}
{$f-}
const
libcolorizerVersion = '1.0';
libcolorizerVerUrl = 'http://pastebin.com/raw.php?i=PmQqYXXX';
libcolorizerCodeUrl = 'http://pastebin.com/raw.php?i=UEsQXXXX';
BLACKLIST_THRESHOLD = 500; // msec. if a findcolor takes longer than this we dont want it
PIXELSHIFT_WAIT = 300; // msec
SUCCESS_THRESHOLD = 0.66; // what is good enough (percent) to call a color successful
FAILURE_THRESHOLD = 0.30; // what is bad enough (percent) to call a failure
ATTEMPT_THRESHOLD = 30; // by this many attempts, demand success or blacklist
GRIDSIZE = 50; // box size to break up the screen for motion detection
CLEANUP_LOW_WATER = 40; // how many colors to keep if we are cleaning up
type
TcolRec = record
color : integer;
count : integer;
attempts : integer;
matches : integer;
lastPoints : integer;
lastObj : integer;
maxPoints : integer;
maxObj : integer;
queryTime : integer;
end;
TcolSet = array of TcolRec;
Tcolorizer = record
name : string;
discovered : TcolSet;
active : TcolSet;
successful : TcolSet;
blacklist : TcolSet;
runty : TcolSet;
uptext : string;
uptextTimeout : integer;
tol : integer;
dist : integer;
minPixels : integer;
maxPixels : integer;
end;
// -----------------------------------------------------------------------------
// Some functions that had issues or were missing from SRL
// -----------------------------------------------------------------------------
function getPixelShiftAverage(b: TBoxArray; waitPerLoop,
maxTime: integer): TIntegerArray; override;
var
len, i, j: integer;
samples: array of TIntegerArray;
tmp: TIntegerArray;
timer: TTimeMarker;
begin
i := 0;
timer.start();
while (timer.getTime() < maxTime) do
begin
setLength(samples, i + 1);
samples[i] := getPixelShift(b, waitPerLoop);
inc(i);
end;
setLength(tmp, i); // i got incremented one extra time so is good for length
len := length(b);
setLength(result, len);
for i := 0 to (len - 1) do
begin
for j := 0 to high(samples) do
tmp[j] := samples[j][i];
result[i] := tmp.average();
end;
end;
function getPixelShift(b: TBoxArray; time: integer): TIntegerArray; override;
var
hi, i: integer;
before, after: integer;
begin
hi := high(b);
setLength(result, hi+1);
before := bitmapFromClient(mainscreen.getBounds());
sleep(time);
after := bitmapFromClient(mainscreen.getBounds());
for i := 0 to hi do
result[i] := calculatePixelShift(before, after, b[i]);
freeBitmap(before);
freeBitmap(after);
end;
function TIntegerArray.max(): integer;
var
i, tmpmax: integer;
begin
tmpmax := -(MAXINT);
for i := 0 to length(self) do
if self[i] > tmpmax then tmpmax := self[i];
exit(tmpmax);
end;
function TBoxArray.pixelShift(time: integer = 200): TIntegerArray;
begin
result := getPixelShift(self, time);
end;
function TBoxArray.returnInArray(const b : TBox) : integer;
var
i: integer;
begin
for i := 0 to high(self) do
if (self[i].equals(b)) then exit(i);
exit(-1);
end;
function TBoxArray.isInArray(const b : TBox) : Boolean;
begin
if (self.returnInArray(b) <> -1) then
result := true
else
result := false;
end;
procedure TBoxArray.addIndex(const b : TBox; const index : Integer);
var
I : Integer;
begin
if not inRange(index, low(self), length(self)) then
begin
WriteLn('ERROR: addIndex: index larger than array length.');
Exit;
end;
setLength(self, length(self)+1);
for I := high(self)-1 downto index do
self[I+1] := self[I];
self[index] := b;
end;
procedure TBoxArray.append(const b : TBox);
begin
self.addIndex(b, length(self));
end;
procedure TBoxArray.combine(const arr : TBoxArray);
var
i : integer;
begin
for i := 0 to high(arr) do
self.append(arr[i]);
end;
// -----------------------------------------------------------------------------
// successPercent()
//
// Returns the success percentage
// -----------------------------------------------------------------------------
function TcolRec.successPercent(): extended;
begin
result := (self.matches / self.attempts);
end;
// -----------------------------------------------------------------------------
// sortByCount()
//
// sorts the array by count desc
// -----------------------------------------------------------------------------
procedure TcolSet.sortByCount();
var
i, j, m: integer;
tmp: TcolSet;
begin
setLength(tmp, 1);
for i := 0 to high(self) - 1 do
begin
m := i;
for j := i + 1 to high(self) do
begin
if self[j].count > self[m].count then
m := j;
end;
tmp[0] := self[m];
self[m] := self[i];
self[i] := tmp[0];
end;
end;
// -----------------------------------------------------------------------------
// sortBySuccess()
//
// sorts the array by success rate desc
// -----------------------------------------------------------------------------
procedure TcolSet.sortBySuccess();
var
i, j, m: integer;
tmp: TcolSet;
begin
setLength(tmp, 1);
for i := 0 to high(self) - 1 do
begin
m := i;
for j := i + 1 to high(self) do
begin
if ((self[j].attempts = 0) or (self[m].attempts = 0)) then continue;
if (self[j].successPercent() > self[m].successPercent()) then
m := j;
end;
tmp[0] := self[m];
self[m] := self[i];
self[i] := tmp[0];
end;
end;
// -----------------------------------------------------------------------------
// returnInArray()
//
// Returns the index of color c in the array (-1 if not found)
// -----------------------------------------------------------------------------
function TcolSet.returnInArray(const c: integer): integer;
var
i: integer;
begin
for i := 0 to high(self) do
if (self[i].color = c) then exit(i);
exit(-1);
end;
// -----------------------------------------------------------------------------
// isInArray()
//
// Returns true if color c in the array
// -----------------------------------------------------------------------------
function TcolSet.isInArray(const c: integer): boolean;
var
i: integer;
begin
i := self.returnInArray(c);
if (i = -1) then
result := false
else
result := true;
end;
// -----------------------------------------------------------------------------
// append()
//
// Adds a color to the array
// -----------------------------------------------------------------------------
procedure TcolSet.append(const t: TcolRec);
var
i: integer;
begin
setLength(self, (length(self) + 1));
self[high(self)] := t;
end;
// -----------------------------------------------------------------------------
// deleteIndex()
//
// Deletes the color at the given index
// -----------------------------------------------------------------------------
procedure TcolSet.deleteIndex(const index: integer);
var
i : integer;
begin
if not inRange(index, low(self), high(self)) then
begin
writeln('TcolSet.deleteIndex: ERROR - index (', index, ' is out of range');
exit;
end;
for i := index to (high(self) - 1) do
self[i] := self[i + 1];
setLength(self, (length(self) - 1));
end;
// -----------------------------------------------------------------------------
// delete()
//
// Deletes the color
// -----------------------------------------------------------------------------
procedure TcolSet.delete(const c: integer);
var
i : integer;
begin
i := self.returnInArray(c);
if (i >= 0) then
self.deleteIndex(i);
end;
// -----------------------------------------------------------------------------
// cleanupColors()
//
// Weeds down the color list
// -----------------------------------------------------------------------------
procedure TcolSet.cleanupColors();
var
i, t, cnt: integer;
tmp: TcolSet;
begin
cnt := 1;
while (cnt < 15) do
begin
if (length(self) < CLEANUP_LOW_WATER) then exit;
t := 0;
setLength(tmp, length(self));
for i := 0 to high(self) do
begin
if ((self[i].matches > 0) or (self[i].count > cnt)) then
begin
tmp[t] := self[i];
inc(t);
end;
end;
setLength(tmp, t);
self := tmp;
inc(cnt);
end;
end;
// -----------------------------------------------------------------------------
// _fpath()
//
// Make a file path
// -----------------------------------------------------------------------------
function Tcolorizer._fpath(): string;
var
s: string;
begin
if (self.name = '') then
begin
result := '';
exit;
end;
s := lowercase(self.name);
s := replace(s, ' ', '-', [rfReplaceAll]);
s := replace(s, '/', '-', [rfReplaceAll]);
s := replace(s, ':', '-', [rfReplaceAll]);
result := includePath + 'bonsai\colors\';
if (not DirectoryExists(result)) then
begin
if (CreateDirectory(result)) then
writeln('***** Tcolorizer._fpath: created include folder ' + result)
else
writeln('***** Tcolorizer._fpath: ERROR - Could not create directory ' + result);
end;
result := result + s + '.xml';
end;
// -----------------------------------------------------------------------------
// load()
//
// Loads previous work from a file
// -----------------------------------------------------------------------------
function Tcolorizer.load(): boolean;
var
fileId, i, j, k: integer;
filePath, fileData: string;
allData, colArr, colorSets, cRec: TStringArray;
tmp: TcolRec;
begin
result := false;
filePath := self._fpath();
if (not FileExists(filePath)) then
begin
{$IFDEF DEBUG_ON} writeln('***** Tcolorizer.load: Requested file does not exist [', filePath, ']'); {$ENDIF}
exit;
end;
fileId := OpenFile(filePath, false);
if (fileId = -1) then
begin
{$IFDEF DEBUG_ON} writeln('***** Tcolorizer.load: OpenFile failed [', filePath, ']'); {$ENDIF}
exit;
end;
if (not ReadFileString(fileId, fileData, FileSize(fileId))) then
begin
{$IFDEF DEBUG_ON} writeln('***** Tcolorizer.load: ReadFileString failed [', filePath, ']'); {$ENDIF}
exit;
end;
CloseFile(fileId);
// now we have the contents in fileData, parse it
allData := MultiBetween(fileData, '<colorizer>', '</colorizer>');
if (length(allData) <> 1) then
begin
writeln('***** Tcolorizer.load: Corrupt file [', filePath,
'], does not have proper <colorizer></colorizer> tags');
exit;
end;
self.name := between('<name>', '</name>', allData[0]);
self.uptext := between('<uptext>', '</uptext>', allData[0]);
uptextTimeout := StrToIntDef(between('<uptextTimeout>', '</uptextTimeout>', allData[0]), 0);
tol := StrToIntDef(between('<tol>', '</tol>', allData[0]), 0);
dist := StrToIntDef(between('<dist>', '</dist>', allData[0]), 0);
minPixels := StrToIntDef(between('<minPixels>', '</minPixels>', allData[0]), 0);
maxPixels := StrToIntDef(between('<maxPixels>', '</maxPixels>', allData[0]), 0);
colorSets := ['discovered', 'active', 'successful', 'blacklist', 'runty'];
for i := 0 to high(colorSets) do
begin
colArr := multiBetween(allData[0], '<' + colorSets[i] + '>', '</' + colorSets[i] + '>');
for j := 0 to high(colArr) do
begin
cRec := multiBetween(colArr[j], '<colorRecord>', '</colorRecord>');
for k := 0 to high(cRec) do
begin
tmp.color := StrToIntDef(between('<color>', '</color>', cRec[k]), 0);
tmp.count := StrToIntDef(between('<count>', '</count>', cRec[k]), 0);
tmp.attempts := StrToIntDef(between('<attempts>', '</attempts>', cRec[k]), 0);
tmp.matches := StrToIntDef(between('<matches>', '</matches>', cRec[k]), 0);
tmp.lastPoints := StrToIntDef(between('<lastPoints>', '</lastPoints>', cRec[k]), 0);
tmp.lastObj := StrToIntDef(between('<lastObj>', '</lastObj>', cRec[k]), 0);
tmp.maxPoints := StrToIntDef(between('<maxPoints>', '</maxPoints>', cRec[k]), 0);
tmp.maxObj := StrToIntDef(between('<maxObj>', '</maxObj>', cRec[k]), 0);
tmp.queryTime := StrToIntDef(between('<queryTime>', '</queryTime>', cRec[k]), 0);
case colorSets[i] of
'discovered' : begin; self.discovered.append(tmp); end;
'active' : begin; self.active.append(tmp); end;
'successful' : begin; self.successful.append(tmp); end;
'blacklist' : begin; self.blacklist.append(tmp); end;
'runty' : begin; self.runty.append(tmp); end;
end;
end;
end;
end;
end;
// -----------------------------------------------------------------------------
// save()
//
// Saves the accumulated data
// -----------------------------------------------------------------------------
procedure Tcolorizer.save();
var
s, filePath: string;
i, j, fileId: integer;
colorSets: TstringArray;
function colRec(r: TcolRec): string;
begin
result := result + ' <colorRecord>';
result := result + '<color>' + intToStr(r.color) + '</color>';
result := result + '<count>' + intToStr(r.count) + '</count>';
result := result + '<attempts>' + intToStr(r.attempts) + '</attempts>';
result := result + '<matches>' + intToStr(r.matches) + '</matches>';
result := result + '<lastPoints>' + intToStr(r.lastPoints) + '</lastPoints>';
result := result + '<lastObj>' + intToStr(r.lastObj) + '</lastObj>';
result := result + '<maxPoints>' + intToStr(r.maxPoints) + '</maxPoints>';
result := result + '<maxObj>' + intToStr(r.maxObj) + '</maxObj>';
result := result + '<queryTime>' + intToStr(r.queryTime) + '</queryTime>';
result := result + '</colorRecord>' + #13#10;
end;
begin
s := s + '<colorizer>' + #13#10;
s := s + ' <name>' + self.name + '</name>' + #13#10;
s := s + ' <uptext>' + self.uptext + '</uptext>' + #13#10;
s := s + ' <uptextTimeout>' + intToStr(self.uptextTimeout) + '</uptextTimeout>' + #13#10;
s := s + ' <tol>' + intToStr(self.tol) + '</tol>' + #13#10;
s := s + ' <dist>' + intToStr(self.dist) + '</dist>' + #13#10;
s := s + ' <minPixels>' + intToStr(self.minPixels) + '</minPixels>' + #13#10;
s := s + ' <maxPixels>' + intToStr(self.maxPixels) + '</maxPixels>' + #13#10;
colorSets := ['discovered', 'active', 'successful', 'blacklist', 'runty'];
for i := 0 to high(colorSets) do
case colorSets[i] of
'discovered':
begin
s := s + ' <discovered>' + #13#10;
for j := 0 to high(self.discovered) do
s := s + colRec(self.discovered[j]);
s := s + ' </discovered>' + #13#10;
end;
'active':
begin
s := s + ' <active>' + #13#10;
for j := 0 to high(self.active) do
s := s + colRec(self.active[j]);
s := s + ' </active>' + #13#10;
end;
'successful':
begin
s := s + ' <successful>' + #13#10;
for j := 0 to high(self.successful) do
s := s + colRec(self.successful[j]);
s := s + ' </successful>' + #13#10;
end;
'blacklist':
begin
s := s + ' <blacklist>' + #13#10;
for j := 0 to high(self.blacklist) do
s := s + colRec(self.blacklist[j]);
s := s + ' </blacklist>' + #13#10;
end;
'runty':
begin
s := s + ' <runty>' + #13#10;
for j := 0 to high(self.runty) do
s := s + colRec(self.runty[j]);
s := s + ' </runty>' + #13#10;
end;
end;
s := s + '</colorizer>' + #13#10;
filePath := self._fpath();
fileId := RewriteFile(filePath, false);
if (fileId = -1) then
begin
{$IFDEF DEBUG_ON} writeln('***** Tcolorizer.save: RewriteFile failed [', filePath, ']'); {$ENDIF}
exit;
end;
if (not WriteFileString(fileId, s)) then
begin
{$IFDEF DEBUG_ON} writeln('***** Tcolorizer.save: WriteFileString failed [', filePath, ']'); {$ENDIF}
exit;
end;
CloseFile(fileId);
end;
// -----------------------------------------------------------------------------
// init()
//
// Initialize the object
// -----------------------------------------------------------------------------
procedure Tcolorizer.init(nm: string; ut: string; utt: integer; t: integer;
d: integer; minp: integer; maxp: integer);
begin
self.name := nm;
self.uptext := ut;
self.uptextTimeout := utt;
self.tol := t;
self.dist := d;
self.minPixels := minp;
self.maxPixels := maxp;
// setLength(self.discovered, 0);
// setLength(self.active, 0);
// setLength(self.successful, 0);
// setLength(self.blacklist, 0);
// setLength(self.runty, 0);
end;
// -----------------------------------------------------------------------------
// setName()
//
// Initialize the object
// -----------------------------------------------------------------------------
procedure Tcolorizer.setName(nm: string);
begin
self.name := nm;
end;
// -----------------------------------------------------------------------------
// updateCount()
//
// Updates count info for a color. Adds it if new.
// -----------------------------------------------------------------------------
procedure Tcolorizer.updateCount(col: integer; cnt: integer);
var
d, a, s, b, r: integer;
begin
d := self.discovered.returnInArray(col);
a := self.active.returnInArray(col);
s := self.successful.returnInArray(col);
b := self.blacklist.returnInArray(col);
r := self.runty.returnInArray(col);
if (d+a+s+b+r = -5) then // this is a new color
begin
setLength(self.discovered, length(self.discovered) + 1);
with self.discovered[high(self.discovered)] do
begin
color := col;
count := cnt;
attempts := 0;
matches := 0;
lastPoints := 0;
lastObj := 0;
maxPoints := 0;
maxObj := 0;
queryTime := 0;
end;
end
else
begin
if (d >= 0) then
self.discovered[d].count := self.discovered[d].count + cnt;
if (a >= 0) then
self.active[a].count := self.active[a].count + cnt;
if (s >= 0) then
self.successful[s].count := self.successful[s].count + cnt;
if (b >= 0) then
self.blacklist[b].count := self.blacklist[b].count + cnt;
if (r >= 0) then
self.runty[r].count := self.runty[r].count + cnt;
end;
end;
// -----------------------------------------------------------------------------
// updateTrials()
//
// Records success/failure of an attempt to use a color. Will move the
// color from place to place depending on the situation.
// -----------------------------------------------------------------------------
procedure Tcolorizer.updateTrials(col: integer; success: boolean);
var
d, a, s, b, r: integer;
percent: extended;
begin
d := self.discovered.returnInArray(col);
a := self.active.returnInArray(col);
s := self.successful.returnInArray(col);
b := self.blacklist.returnInArray(col);
r := self.runty.returnInArray(col);
if (d+a+s+b+r = -5) then
begin
writeln('Tcolorizer.updateTrials: ERROR - Asked to update color, ', col, ' - does not exist');
exit;
end
if (d >= 0) then
with self.discovered[d] do
begin
inc(attempts);
if (success) then inc(matches);
// move it to active since it is being used.
{$IFDEF DEBUG_ON} writeln('***** Tcolorizer.updateTrials: moving (', self.discovered[d].color, ') discovered -> active'); {$ENDIF}
self.active.append(self.discovered[d]);
self.discovered.deleteIndex(d);
end;
if (a >= 0) then
with self.active[a] do
begin
inc(attempts);
if (success) then inc(matches);
percent := matches / attempts;
// see if this active color has met criteria for blacklist or success
if ((attempts >= ATTEMPT_THRESHOLD) and (percent < SUCCESS_THRESHOLD)) or
((attempts >= 5) and (percent < FAILURE_THRESHOLD)) then
begin
{$IFDEF DEBUG_ON}
writeln('***** Tcolorizer.updateTrials: moving (', self.active[a].color,
') active -> blacklist');
{$ENDIF}
self.blacklist.append(self.active[a]); // time to give up on this one
self.active.deleteIndex(a);
end
else if ((matches >= 5) and (percent >= SUCCESS_THRESHOLD)) then
begin
{$IFDEF DEBUG_ON}
writeln('***** Tcolorizer.updateTrials: moving (', self.active[a].color,
') active -> successful');
{$ENDIF}
self.successful.append(self.active[a]);
self.active.deleteIndex(a);
self.save();
end;
end;
if (s >= 0) then
with self.successful[s] do
begin
inc(attempts);
if (success) then inc(matches);
// if ((matches / attempts) < (SUCCESS_THRESHOLD - 0.1)) then
// begin
// {$IFDEF DEBUG_ON}
// writeln('***** Tcolorizer.updateTrials: moving (', self.successful[s].color,
// ') successful -> active');
// {$ENDIF}
// self.active.append(self.successful[s]);
// self.successful.deleteIndex(s);
// self.save();
// end;
end;
if (b >= 0) then
with self.blacklist[b] do
begin
inc(attempts);
if (success) then inc(matches);
end;
if (r >= 0) then
with self.runty[r] do
begin
inc(attempts);
if (success) then inc(matches);
end;
// self.save();
end;
// -----------------------------------------------------------------------------
// updatePointCount()
//
// Updates stats on a color
// -----------------------------------------------------------------------------
procedure Tcolorizer.updatePointCount(col: integer; points: integer;
objs: integer; msec: integer);
var
d, a, s, b, r: integer;
begin
d := self.discovered.returnInArray(col);
a := self.active.returnInArray(col);
s := self.successful.returnInArray(col);
b := self.blacklist.returnInArray(col);
r := self.runty.returnInArray(col);
if (d+a+s+b+r = -5) then
begin
writeln('***** Tcolorizer.updatePointCount: ERROR - Asked to update color, ',
col, ' - does not exist');
exit;
end
if (d >= 0) then
with self.discovered[d] do
begin
lastPoints := points;
lastObj := objs;
if (points > maxPoints) then maxPoints := points;
if (objs > maxObj) then maxObj := objs;
if (msec > queryTime) then queryTime := msec;
if (msec > BLACKLIST_THRESHOLD) then // move it to the blacklist
begin
{$IFDEF DEBUG_ON}
writeln('***** Tcolorizer.updatePointCount: moving (', self.discovered[d].color,
') discovered -> blacklist');
{$ENDIF}
self.blacklist.append(self.discovered[d]);
self.discovered.deleteIndex(d);
end
else if ((objs < 1) and (matches = 0)) then // move it to the runty list
begin
{$IFDEF DEBUG_ON}
writeln('***** Tcolorizer.updatePointCount: moving (', self.discovered[d].color,
') discovered -> runty. objs=', objs, ' points=', points);
{$ENDIF}
self.runty.append(self.discovered[d]);
self.discovered.deleteIndex(d);
end
else // since it is being used, move it to active
begin
{$IFDEF DEBUG_ON}
writeln('***** Tcolorizer.updatePointCount: moving (', self.discovered[d].color,
') discovered -> active');
{$ENDIF}
self.active.append(self.discovered[d]);
self.discovered.deleteIndex(d);
end;
end;
if (a >= 0) then
with self.active[a] do
begin
lastPoints := points;
lastObj := objs;
if (points > maxPoints) then maxPoints := points;
if (objs > maxObj) then maxObj := objs;
if (msec > queryTime) then queryTime := msec;
if (msec > BLACKLIST_THRESHOLD) then // move it to the blacklist
begin
{$IFDEF DEBUG_ON}
writeln('***** Tcolorizer.updatePointCount: moving (', self.active[a].color,
') active -> blacklist');
{$ENDIF}
self.blacklist.append(self.active[a]);
self.active.deleteIndex(a);
end
else if ((objs < 1) and (matches = 0)) then // move it to the runty list
begin
{$IFDEF DEBUG_ON}
writeln('***** Tcolorizer.updatePointCount: moving (', self.active[a].color,
') active -> runty');
{$ENDIF}
self.runty.append(self.active[a]);
self.active.deleteIndex(a);
end;
end;
if (s >= 0) then
with self.successful[s] do
begin
lastPoints := points;
lastObj := objs;
if (points > maxPoints) then maxPoints := points;
if (objs > maxObj) then maxObj := objs;
if (msec > queryTime) then queryTime := msec;
if (msec > BLACKLIST_THRESHOLD) then // move it to the blacklist
begin
{$IFDEF DEBUG_ON}
writeln('***** Tcolorizer.updatePointCount: moving (', self.successful[s].color,
') successful -> blacklist');
{$ENDIF}
self.blacklist.append(self.successful[s]);
self.successful.deleteIndex(s);
self.save();
end
else if (objs < 1) then // move it to the runty list
begin
// {$IFDEF DEBUG_ON}
// writeln('***** Tcolorizer.updatePointCount: moving (', self.successful[s].color,
// ') successful -> runty');
// {$ENDIF}
// self.runty.append(self.successful[s]);
// self.successful.deleteIndex(s);
end;
end;
if (b >= 0) then
with self.blacklist[b] do
begin
writeln('***** Tcolorizer.updatePointCount: Warning - Updating blacklisted color (', col, ')');
lastPoints := points;
lastObj := objs;
if (points > maxPoints) then maxPoints := points;
if (objs > maxObj) then maxObj := objs;
if (msec > queryTime) then queryTime := msec;
end;
if (r >= 0) then
with self.runty[r] do
begin
writeln('***** Tcolorizer.updatePointCount: Warning - Updating runty color (', col, ')');
lastPoints := points;
lastObj := objs;
if (points > maxPoints) then maxPoints := points;
if (objs > maxObj) then maxObj := objs;
if (msec > queryTime) then queryTime := msec;
if (msec > BLACKLIST_THRESHOLD) then // move it to the blacklist
begin
{$IFDEF DEBUG_ON}
writeln('***** Tcolorizer.updatePointCount: moving (', self.runty[r].color,
') runty -> blacklist');
{$ENDIF}
self.blacklist.append(self.runty[r]);
self.runty.deleteIndex(r);
end
else if (objs > 1) then // it started providing matches, move out of runty
begin
{$IFDEF DEBUG_ON}
writeln('***** Tcolorizer.updatePointCount: moving (', self.runty[r].color,
') runty -> active');
{$ENDIF}
self.active.append(self.runty[r]);
self.runty.deleteIndex(r);
end;
end;
self.save();
end;
// -----------------------------------------------------------------------------
// delete()
//
// Delete info for a color
// -----------------------------------------------------------------------------
procedure Tcolorizer.delete(col: integer);
var
d, a, s, b, r: integer;
begin
d := self.discovered.returnInArray(col);
a := self.active.returnInArray(col);
s := self.successful.returnInArray(col);
b := self.blacklist.returnInArray(col);
r := self.runty.returnInArray(col);
if (d+a+s+b+r = -5) then
begin
writeln('Tcolorizer.delete: ERROR - Asked to delete color, ',
col, ' - does not exist');
exit;
end
{$IFDEF DEBUG_ON} writeln('***** Tcolorizer.delete: deleting (', col, ')'); {$ENDIF}
if (d >= 0) then self.discovered.delete(col);
if (a >= 0) then self.active.delete(col);
if (s >= 0) then self.successful.delete(col);
if (b >= 0) then self.blacklist.delete(col);
if (r >= 0) then self.runty.delete(col);
end;
// -----------------------------------------------------------------------------
// cleanupColors()
//
// Weeds down the color list. Does not clean sucessful, blacklisted,
// or runty lists since these keep us from using bad colors or are the result
// of hard searching.
// -----------------------------------------------------------------------------
procedure Tcolorizer.cleanupColors();
var
i, t, cnt: integer;
found: boolean;
tmp: Tcolorizer;
begin
self.discovered.cleanupColors();
self.active.cleanupColors();
end;
// -----------------------------------------------------------------------------
// gather()
//
// Gathers a color by screen quadrants so we dont get so bogged
// down on background colors that take forever to collect. Hopefully
// don't have to break this into eights or make it recursive.
// -----------------------------------------------------------------------------
function Tcolorizer.gather(var tpa: TPointArray; col: integer): boolean;
var
b: TBox;
c: TPoint;
quadrant: array[0..3] of TBox;
i: integer;
timer: TTimeMarker;
qtpa: TPointArray;
begin
b := mainscreen.getBounds();
c := mainscreen.getCenterPoint();
// NE, SE, SW, NW
quadrant[0] := IntToBox(c.x, b.y1, b.x2, c.y);
quadrant[1] := IntToBox(c.x, c.y, b.x2, b.y2);
quadrant[2] := IntToBox(b.x1, c.y, c.x, b.y2);
quadrant[3] := IntToBox(b.x1, b.y1, c.x, c.y);
setLength(tpa, 0);
timer.start();
for i := 0 to 3 do
begin
setLength(qtpa, 0);
if (findColorsTolerance(qtpa, col, quadrant[i], self.tol)) then
begin
if (timer.getTime() > (BLACKLIST_THRESHOLD div 4)) then
begin
// dump this color for something more productive
{$IFDEF DEBUG_ON}
writeln('***** Tcolorizer.gather: blacklisting (', col, ') for timeout.');
{$ENDIF}
self.updatePointCount(col, length(qtpa)*4, 0, BLACKLIST_THRESHOLD+1);
result := false;
exit;
end
else
tpa.combine(qtpa);
end;
end;
if (length(tpa) > 0) then
result := true
else
result := false;
end;
// -----------------------------------------------------------------------------
// gather()
//
// Gathers a color into an atpa.
// -----------------------------------------------------------------------------
function Tcolorizer.gather(var atpa: T2DPointArray; c: integer): boolean; overload;
var
tpa: TPointArray;
timer: TTimeMarker;
begin
setLength(tpa, 0);
result := true;
timer.start();
if (not self.gather(tpa, c)) then
begin
result := false;
// no point in updating if it already got blacklisted
if (not self.blacklist.isInArray(c)) then
begin
self.updatePointCount(c, 0, 0, timer.getTime());
end;
exit;
end;
atpa := tpa.split(self.dist);
atpa.filterBetween(0, self.minPixels);
atpa.filterBetween(self.maxPixels, maxint);
atpa.sortBySize();
if (length(atpa) = 0) then
result := false;
self.updatePointCount(c, length(tpa), length(atpa), timer.getTime());
end;
// -----------------------------------------------------------------------------
// sample()
//
// Grabs a sampling of colors around the mouse area
// -----------------------------------------------------------------------------
procedure Tcolorizer.sample(n: integer = 3);
var
i, x, y: integer;
b: TBox;
colList: TIntegerArray;
begin
getMousePos(x,y);
b := [x, y, x, y];
b.expand(n);
if (b.x1 < 0) then b.x1 := 0;
if (b.x2 < 0) then b.x2 := 0;
if (b.y1 < 0) then b.y1 := 0;
if (b.y2 < 0) then b.y2 := 0;
colList := getColors(b.createTPA());
for i := 0 to high(colList) do
self.updateCount(colList[i], 1);
end;
// -----------------------------------------------------------------------------
// deepSample()
//
// Jiggles the mouse around a good spot to see if we can collect more colors
// -----------------------------------------------------------------------------
procedure Tcolorizer.deepSample(x: integer; y: integer; n: integer = 3);
var
p: TPoint;
i, t: integer;
matched: boolean;
s: string;
begin
p.create(x,y);
i := 5;
matched := true;
while (matched) do
begin
matched := false;
mouse(p.rand(i));
inc(i);
t := getSystemTime() + randomRange(uptextTimeout, uptextTimeout+80);
repeat
wait(20);
s := getMouseOverText();
if (pos(self.uptext, s) > 0) then
begin
matched := true;
self.sample(n);
end
else
if (s <> '') then // we got an uptext, but it isnt what we want
break;
until (matched or (getSystemTime() > t));
end;
end;
// -----------------------------------------------------------------------------
// untriedColors()
//
// Returns an array of colors we havent tried yet
// -----------------------------------------------------------------------------
function Tcolorizer.untriedColors() : TIntegerArray;
var
i, j: integer;
closeToBG, bgList: TIntegerArray;
begin
if (length(self.discovered) > CLEANUP_LOW_WATER) then
self.cleanupColors(); // might as well try to cut it down
self.discovered.sortByCount();
// put colors close to successful ones first in the list
for i := 0 to high(self.successful) do
for j := 0 to high(self.discovered) do
begin
if SimilarColors(self.successful[i].color, self.discovered[j].color, 10) then
begin
result.append(self.discovered[j].color);
break;
end;
end;
// find background colors (blacklisted with high queryTime). Put
// things close to the blacklist at the end.
setLength(bgList, 0);
for i := 0 to high(self.blacklist) do
begin
if self.blacklist[i].queryTime > BLACKLIST_THRESHOLD then
bgList.append(self.blacklist[i].color);
end;
setLength(closeToBG, 0);
for i := 0 to high(bgList) do
for j := 0 to high(self.discovered) do
begin
if (not result.isInArray(self.discovered[j].color)) and
SimilarColors(bgList[i], self.discovered[j].color, 10) then
begin
closeToBG.append(self.discovered[j].color);
break;
end;
end;
for i := 0 to high(self.discovered) do
if (not result.isInArray(self.discovered[i].color)) and
(not closeToBG.isInArray(self.discovered[i].color)) then
begin
result.append(self.discovered[i].color);
end;
result.combine(closeToBG);
end;
// -----------------------------------------------------------------------------
// activeColors()
//
// Returns an array of colors we need to test more
// -----------------------------------------------------------------------------
function Tcolorizer.activeColors() : TIntegerArray;
var
i: integer;
begin
if (length(self.active) > CLEANUP_LOW_WATER) then
self.cleanupColors(); // might as well try to cut it down
setLength(result, 0);
self.active.sortBySuccess();
for i := 0 to high(self.active) do
result.append(self.active[i].color);
end;
// -----------------------------------------------------------------------------
// successfulColors()
//
// Returns an array of colors we have confidence in
// -----------------------------------------------------------------------------
function Tcolorizer.successfulColors() : TIntegerArray;
var
i: integer;
begin
self.successful.sortBySuccess();
for i := 0 to high(self.successful) do
result.append(self.successful[i].color);
end;
// -----------------------------------------------------------------------------
// multiBox()
//
// Uses the five most successful colors to return a box that is likely
// to have an NPC in it
// -----------------------------------------------------------------------------
function Tcolorizer.multiBox(var clist: TIntegerArray; rand: boolean = true) : Tbox;
var
s, pointCount, qTimes: TIntegerArray;
atpa: T2DPointArray;
allPoints, tpa: TPointArray;
t: TTimeMarker;
i: integer;
begin
s := self.successfulColors();
if (length(s) < 1) then
begin
result := [-1,-1,-1,-1];
exit;
end;
setLength(clist, 0);
setLength(pointCount, 0);
setLength(qTimes, 0);
for i := 0 to min(5, high(s)) do
begin
t.reset();
t.start();
if self.gather(tpa, s[i]) then
begin
allPoints.combine(tpa);
clist.append(s[i]);
pointCount.append(length(tpa));
qTimes.append(t.getTime());
end;
end;
atpa := allPoints.split(self.dist);
atpa.filterBetween(0, self.minPixels);
atpa.filterBetween(self.maxPixels, maxint);
if (length(atpa) < 1) then
begin
result := [-1,-1,-1,-1];
exit;
end;
if rand then
result := atpa[random(length(atpa))].getBounds()
else
begin
atpa.sortBySize();
result := atpa[0].getBounds();
end;
for i := 0 to min(5, high(s)) do
self.updatePointCount(clist[i], pointCount[i], length(atpa), qTimes[i]);
{$IFDEF DEBUG_ON}
smartImage.drawBox(result, true, clOrange);
sleep(80);
smartImage.clearArea(result);
{$ENDIF}
end;
// -----------------------------------------------------------------------------
// likelyBox()
//
// Uses the successful list to return a box that is likely to have an NPC in it
// -----------------------------------------------------------------------------
function Tcolorizer.likelyBox(var c: integer; rand: boolean = true) : Tbox;
var
s: TIntegerArray;
atpa: T2DPointArray;
begin
s := self.successfulColors();
if (length(s) < 1) then
begin
result := [-1,-1,-1,-1];
exit;
end;
if rand then
c := s[random(length(s))]
else
c := s[0];
if self.gather(atpa, c) then
begin
if rand then
result := atpa[random(length(atpa))].getBounds()
else
result := atpa[0].getBounds();
end
else
begin
result := [-1,-1,-1,-1];
exit;
end;
{$IFDEF DEBUG_ON}
smartImage.drawBox(result, true, clOrange);
sleep(80);
smartImage.clearArea(result);
{$ENDIF}
end;
// -----------------------------------------------------------------------------
// testCol()
//
// Sees if a color will get us to the desired mousetext
// -----------------------------------------------------------------------------
function Tcolorizer.testCol(c: integer; trials: integer = 1): boolean;
var
i, t, x, y: integer;
s: string;
atpa: T2DPointArray;
matched: boolean;
timer: TTimeMarker;
begin
result := false;
if (not self.gather(atpa, c)) then
begin
self.updateTrials(c, false);
exit;
end;
for i := 0 to high(atpa) do
begin
if (trials = 0) then
break
else
trials := trials - 1;;
matched := false;
timer.start();
t := randomRange(uptextTimeout, uptextTimeout+80);
atpa[i].getBounds().mouse();
repeat
wait(20);
s := getMouseOverText();
if (pos(self.uptext, s) > 0) then
matched := true
else
if (s <> '') then // we got an uptext, but it isnt what we want
break;
until (matched or (timer.getTime() > t));
if (matched) then
begin
case random(10) of
0: begin
getMousePos(x,y);
self.deepSample(x,y);
end;
end;
self.updateTrials(c, true);
result := true;
end
else
self.updateTrials(c, false);
end;
end;
// -----------------------------------------------------------------------------
// colorize()
//
// Tests colors to try to find new ones that are successful.
// -----------------------------------------------------------------------------
function Tcolorizer.colorize(maxTime: integer = 120000; enough: integer = 5): boolean;
var
i, timeout: integer;
tia: TIntegerArray;
begin
if (length(self.successful) >= enough) then
begin
result := true;
exit;
end;
result := false;
timeout := getSystemTime() + maxTime;
while (getSystemTime() < timeout) do
begin
if ((length(self.active) < 8) and (length(self.discovered) > 0)) then
begin
tia := self.untriedColors();
if (length(tia) < 1) then exit;
self.testCol(tia[0], 1);
end
else
begin
tia := self.activeColors();
if (length(tia) < 1) then exit;
self.testCol(tia[random(length(tia))], 5);
end;
if (length(self.successful) >= enough) then
begin
{$IFDEF DEBUG_ON}
writeln('***** Tcolorizer.colorize: Reached our goal of ', enough, ' good colors.');
{$ENDIF}
result := true;
exit;
end;
end;
end;
// -----------------------------------------------------------------------------
// detectObj()
//
// Detect an object in a box.
// -----------------------------------------------------------------------------
function Tcolorizer.detectObj(var x: integer; var y: integer; var menuText: string;
b: TBox; mouseButton: integer = MOUSE_MOVE): boolean;
var
i, j: integer;
s: string;
opts: TOptionArray;
t: integer;
p: TPoint;
matched: boolean;
begin
x := 0;
y := 0;
menuText := '';
result := false;
matched := false;
if (mouseButton = MOUSE_NONE) or (mouseButton = MOUSE_MIDDLE) then exit;
t := getSystemTime() + randomRange(uptextTimeout, uptextTimeout+80);
repeat
b.mouse();
wait(20);
s := getMouseOverText();
if (pos(self.uptext, s) > 0) then
begin
menuText := s;
matched := true;
result := true;
end
else
if (s <> '') then break; // we got an uptext, but it isnt what we want
until (matched or (getSystemTime() > t));
if (matched) then
begin
self.sample();
getMousePos(x,y); // save this for a sec
case (mouseButton) of
MOUSE_LEFT:
begin
fastClick(MOUSE_LEFT);
exit;
end;
MOUSE_RIGHT, MOUSE_MOVE:
begin
fastClick(MOUSE_RIGHT);
if (mouseButton = MOUSE_RIGHT) then
begin
result := chooseoption.select([self.uptext], 100);
exit;
end
opts := chooseOption.getOptions();
chooseOption.close();
for j := 0 to high(opts) do
begin
if (pos(self.uptext, opts[j].str) > 0) then
begin
menuText := opts[j].str;
break;
end;
end;
mouse(point(x,y), MOUSE_MOVE);
end;
end;
end;
end;
// -----------------------------------------------------------------------------
// examineGrid()
//
// Try to detect an object in one of the boxes in grid.
// -----------------------------------------------------------------------------
function Tcolorizer.examineGrid(grid: TBoxArray): string;
var
i, j, x, y, t: integer;
s: string;
opts: TOptionArray;
p: TPoint;
matched: boolean;
begin
result := '';
while (length(grid) > 0) do
begin
i := randomRange(0, length(grid));
if self.detectObj(x, y, s, grid[i]) then
begin
result := s;
break;
end;
grid.deleteIndex(i);
end;
if (result <> '') then
self.deepSample(x,y);
end;
// -----------------------------------------------------------------------------
// motionDetect()
//
// Finds objects based on screen movement (pixel shift).
// -----------------------------------------------------------------------------
function Tcolorizer.motionDetect(): string;
var
i, j, t: integer;
grid, targetGrid, tried: TBoxArray;
pixels: TIntegerArray;
max, percent: integer;
begin
result := '';
setLength(tried, 0);
grid := mainscreen.getBounds().split(GRIDSIZE, GRIDSIZE);
for t := 15 to 95 with 20 do
begin
if (t > 70) then // we're not doing very good, lets try some
setLength(tried, 0); // of the boxes we tried earlier
pixels := grid.pixelShift(PIXELSHIFT_WAIT);
max := pixels.max();
setLength(targetGrid, 0);
for i := 0 to high(grid) do
begin
if (tried.isInArray(grid[i])) then // dont keep moving the mouse to the
continue; // same place... try new ones
percent := trunc( ((pixels[i]/max) * 100.0 ));
if ((percent + t) > 100) then
begin
setLength(targetGrid, length(targetGrid)+1);
targetGrid[high(targetGrid)] := grid[i];
end;
end;
result := self.examineGrid(targetGrid);
if ((result = '') or (result = 'Attack')) then
begin
{$IFDEF DEBUG_ON} writeln('***** Tcolorizer.motionDetect: FAILED TO IDENTIFY ANYTHING. tol=', t); {$ENDIF}
end
else
begin
{$IFDEF DEBUG_ON} writeln('***** Tcolorizer.motionDetect: Identified - ', result); {$ENDIF}
exit;
end;
tried.combine(targetGrid);
end;
end;
// -----------------------------------------------------------------------------
// _colorizerTerminate
//
// This is hooked into the script termination stream.
// -----------------------------------------------------------------------------
procedure _colorizerTerminate();
begin
end;
// -----------------------------------------------------------------------------
// initializer
//
// Ensures we call the function to free DTMS if the script exits.
// Checks for online updates.
// -----------------------------------------------------------------------------
begin
addOnTerminate('_colorizerTerminate');
// updater.check4update('libcolorizer.simba', libcolorizerVersion,
// libcolorizerVerUrl, libcolorizerCodeUrl, true);
end;
A couple of other notes....
It's a good idea to check the box for "logout when exiting". That's the source of some instances of dying. I always leave it unchecked because I'm running around or testing different things.
There will never be looting or banking in the generic fighter. It's for XP or knocking out slayer tasks. Anyway, there is no sensible way to implement generic looting and banking for all npcs. Looting, maybe.
I may release specific versions for something (like a charm gatherer or DRS) but this one won't have it.
Hey, you guys that use the SGS...
Do you want it to activate it the same time it would have eaten food (i.e. don't use it until health drops to the % in the form)?
Or would you prefer to be more aggressive (i.e. use it any time it's available)?
use it same time it would have eaten food
SGS user~~
imo i would prefer it to be more aggressive as you may say
i dont know about the others, though
just a quick question, bonsai, do you use OpenGL or DirectX?
If it doesn't say to use DirectX then always use OpenGL because using OpenGL is part of the correct graphics settings by default. Scripts will specify if they want you to use DirectX because it's not part of the default graphic settings for SIMBA.
It doesn't say to use DirectX in the original post, so you need to use OpenGL
autocoloring is a really good idea man !! i am testing it atm and i will give u feedback and proggries if its flawless :)
the autocoloring is just amaizing it work perfecly only some monster are just too close to background color so it doesnt find it but its normal:p
and here my little proggries i didnt pass the 6hours limit??Attachment 23796
i used a new acc that why the exp/h is low but i used right-click and the script is pretty flawless
Thanks, pipos.
One of the things not done yet is the XP tracking. For now I set it to 10XP per kill and 1ConstitutionXP.
The string I get back from the menu option can be corrupt. It's not getting some of the yellow text and the spaces get dropped sometimes. So it's hard to get an exact real NPC name. Then need to look the name up on runescape wiki or something to get the XP. I know everyone loves their progress reports but I consider it secondary to making the script work.
Which NPC was too close to BG to color? The ony one I had real trouble with so far is the ghost/ankou. Too much white for that one to work.
I tested some in rooms with 2-3 NPC types and it often ends up with mixed colors from all of them. So it kills a mixture of things.
I saw it catching rats so I know it's fast/accurate enough.
i tried again alot of monster with the autocolor and the only monster it didnt work is monk at edgeville in the dungeon
How long should the autocolour take? Tried it with troll chuckers and t didn't work, (stuck on finding colours) though that might have been because they have similar colours to their background
when the debug is spamming: ***** Tnpc.motionDetect: Trying to identify more colors
just stop the script and start it again when the monster is similar to background it can take 2-3 time before you find it
the autocolor take between about 1-3min once it took me like 6min lol
btw troll chucker work i was training there yesterday
No longer getting the
***** Tnpc.motionDetect: Trying to identify more color
line at troll chuckers, seems to be replaced by this:
***** Tcolorizer.updatePointCount: moving (5332091) discovered -> blacklist
***** Tcolorizer.updatePointCount: moving (9213345) discovered -> active
***** Tcolorizer.updateTrials: moving (12379621) active -> blacklist
***** Tcolorizer.updatePointCount: moving (6586272) discovered -> blacklist
***** Tcolorizer.updatePointCount: moving (8751767) discovered -> active
***** Tcolorizer.updateTrials: moving (9213345) active -> successful
***** Tcolorizer.updatePointCount: moving (5398398) discovered -> blacklist
***** Tcolorizer.updatePointCount: moving (6653600) discovered -> active
this is good its finding color it can take 1-3min but i think its at troll chucker it took me 6min lol
srry for double post my computer lagged :/ idk how to delete it
Have been using it on fire giants, has ran perfectly for 10-15 hours before. This evening I checked on it after 3 hours and found it timed out, Somehow it died at fire giants, last health check in the log showed 78%. I guess it went though another portal and kept taking hits. Maybe make it check health anyway every 30 seconds?
having a little issue loading the script and i can't post a screenshot because i just joined the community, so i'll try my utmost best to describe it. when i start the script, it allows me to choose whatever options but when click "run" a new window pops up saying "invalid parameter". i copied some of the code in simba to below, if that helps.
thanks,
-------- Using plugins "OpenGL32.dll"
-------- FATAL ERROR: Failed to spawn a SMART client
****** bonsaiFighter: Script shutting down
//////////
//////////////////////////////////////// KILLS ////////////////////////////////////////
////////// Warped Cockroach //////////
////////// 1020(Killed) 582(per hour run) 582(per hour active) //////////
////////// 25398(xp) 14485(per hour run) 14485(per hour active) //////////
////////// 8364(const xp) 4770(per hour run) 4770(per hour active) //////////
////////// //////////
////////////////////////////////////////////////////////////////////////////////////////////////////
Seems to be working well, but choosing warped cockroaches causes it to attack corpse spiders. Choosing corpse spiders makes it attack corpse spiders.
Sweet script. Works nice for slayer. Curently at 55 slayer :) Thankyou
Thanks. Are you using the original from the first post or the new one I posted a little ways up?
Still working on cleaning things up for an update. I was running a long test yesterday but some fool wanted to be my BF after a couple of hours so I bailed before he reported it :duh:
Progress Report://////////////////////////////////////////////////////////////////////////////////////////////////// ////////// ( )\ ) ) ) ////////// ////////// ( )\ ) ( (()/( ( ( ( ( /( ( /( ( ( ////////// ////////// )((_) ( ( ( ( /( )\ /(_)) )\ )\))( )\()) )\()) ))\ )( ////////// ////////// ((_)_ )\ )\ ) )\ )(_))((_) (_))_|((_)((_))\ ((_)\ (_))/ /((_)(()\ ////////// ////////// | _ ) ((_) _(_/( ((_)((_)_ (_) | |_ (_) (()(_)| |(_)| |_ (_)) ((_) ////////// ////////// | _ \/ _ \| ' \))(_-</ _` | | | | __| | |/ _` | | ' \ | _|/ -_) | '_| ////////// ////////// |___/\___/|_||_| /__/\__,_| |_| |_| |_|\__, | |_||_| \__|\___| |_| ////////// ////////// |___/ ////////// ////////// ////////// ////////// Script runtime: ////////// ////////// 2 hr 41 min 51 sec(Total) 2 hr 29 min 3 sec(Active) 12 min 48 sec(Break) ////////// ////////// ////////// //////////////////////////////////////// KILLS //////////////////////////////////////// ////////// Gelatinous Abomination ////////// ////////// 561(Killed) 208(per hour run) 226(per hour active) ////////// ////////// 22440(xp) 8320(per hour run) 9040(per hour active) ////////// ////////// 7405(const xp) 2746(per hour run) 2983(per hour active) ////////// ////////// ////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
hi im using your latest scipt (autodetect) . why on me it always say tnpc.motiondetect: trying to identitiy more color for almost 10 minuets? im trying to hunt corpse spider
It might take 5 minutes or so to get colors initially.
The success of the autocolor has some luck involved. If the first time it grabs color it gets bad ones, it will take a long time or sometimes not even find anything.
It if doesn't seem to be hitting them while coloring, stop and retry. I would remove the color file if it made one (SIMBADIR\includes\bonsai\colors)
I'm going to release some coloring tools with the fighter. I figured some ways to pre-seed the color file and get much better results. Then you can color separate from fighting or share color files. I don't like all that crazy mouse activity on my better accounts!
I was able to set it up but when im logged in it just keeps moving the mouse around and then ends it after awhile tried it on Warped Cockroaches.. was planning on using it on Cave slimes but have no idea how to. please help me :<
^Fixed i already got it working but was wondering if it can pick up loot/or bank
anyway can you help me set it up with other monsters as i dont understand the post on 1st page. Thank you
^Fixed Got it to do other monsters
Now trying to develop looting for the script. cant determine what procedure to use it always gives error on compiling
For food, it either uses the 'Z' key or the form has a place to enter the keystroke depending on your version. So bind your food to the actionbar and key and it will eat.
The script does not loot or walk to specific places. You want an NPC specific script for that like The Mayors GAO.
The main bonsaiFighter script is pretty simple. A motivated person could customize it for a specific purpose.
ok thanks. im also using The mayor gao script. its worked well. but your script killing really fast. about 470-500 lvl.19 skeleton per hours. with my 38 combat account. there so many thread in this forum. where can i start to make may own scipt ?
Deinitely The Mayor's guide.
Your second post is so helpful, I didn't think about that yet.
Works well, I used it on hell hounds for the charms they drop and it worked great, ran it for about 2 hours and babysat while doing some work just incase.
I'm doing it differently in the next version. It does have the full autodetect/color but I'm finding it best to spend a little time up front pre-coloring. Plus you can run color tests on a junky account. The coloring is really mouse crazy. Anyway, here's how I've been doing it now...
BTW, this process works great to get colors for anything, not just NPCs.
1. Grab a bitmap of the mainscreen in the desired spot.
2. Copy it to another file, edit it, and black out the NPCs.
3. Run a script to grab the colors that make up the NPC.
3a. Compare the blacked out places to the original to come up with every color that was blacked out. This is all the colors in the NPC (plus whatever slop you blacked out).
3b. Take that list, query back to the blacked out mask. Since the mask only has background, this tells us if the color bleeds to other objects and should be avoided.
3c. Query good colors against the full picture to see what a real query would get. If it takes too long, too little results it is weeded out.
3c. Output a list of colors from 3a that did not match the background in 3b or perform poorly in 3c.
This weeds out most of the bad colors that cause long hangs if you do it live. It's shocking to see how big these are, 2000+ colors per NPC even with tol 10/20/30
I run another script while logged in. It takes this color list and makes attempts at NPC location. It weeds through the list and comes up with the truly successful colors that can be used.
Here's an example of the first part for skeletons. They're tough due to similar color with the background. It only found ~50 colors worth using and weeded out ~2800 colors that we need to avoid. Coloring live it would waste tons of time on those.
Skeleton pic http://i58.tinypic.com/rivudy.png
Mask http://i61.tinypic.com/2a9zaix.png
result http://pastebin.com/raw.php?i=MBWWiSXe
Road tested the new one... 6 hour fix didn't restart smart but it was cranking along. Still a little pokey but at least it's not crapping out.
Progress Report://////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////// Bonsai //////////////////////////////////////// //////////////////////////////////////// Fighter //////////////////////////////////////// //////////////////////////////////////// _______ //////////////////////////////////////// ////////// ////////// ////////// Script runtime: ////////// ////////// 6 hr 54 min 23 sec(Total) 6 hr 3 min 23 sec(Active) 51 min 0 sec(Break) ////////// ////////// ////////// //////////////////////////////////////// Kills //////////////////////////////////////// ////////// Total Per Hour /Hour Active ////////// ////////// warped-fly 1,981 286.83 327.08 ////////// ////////// ////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
I've read your reply multiple times but I still can't visualise most of the stuff you said. I'm feeling kind of dumb because I don't really get it... :p
A printscreen would be good enough, I understand this.
Copy the original and edit the copied file in Photoshop to black out the NPC's, yes I also understand this.
What script are you talking about? I thought the way to get colours was by using ACA?
To be honest, I really don't know what you're talking about. I would lie if I would say that I understood everything... :p
You don't need to explain it because I probably won't use it any time soon but it's definitely a very interesting idea you have. If you have some time on your hands, why not make a little tutorial or something so people like me could learn from you. :)