A basic example of a script that can kill mobs. The script searches for the nearest suitable target, approaches it in a straight line if necessary and attacks it with the specified skills.
uses SysUtils, Classes;
procedure GrindThread();
const
SEARCH_RANGE = 50;
FIGHT_DISTANCE = 20;
ACTIONS_DELAY = 300;
ATTACK_SKILLS = '10670; 10667; 10752; '; // Молния гнева [id: 10670]; Ледяная стрела [id: 10667]; Сгустки пламени [id: 10752]
var
i: Integer;
Enemy: TLive;
Skill: TSkill;
AtkSkillsSL: TStringList;
SkillFound: Boolean;
SkillID: Integer;
SkillName: String;
begin
Print('GrindThread started ...');
AtkSkillsSL:= TStringList.Create();
try
AtkSkillsSL.Text:= StringReplace(ATTACK_SKILLS, ';', #13#10, [rfReplaceAll]);
while Delay(500) do begin
if (Status = lsOnline) then begin
// first, check if we need to pick up loot
if Assigned(Enemy) and (Enemy.Valid) and (Enemy.Dead) and (Enemy.Lootable) then begin
Print(Format('Pickup drop from %s', [Enemy.Name]));
if (User.DistTo(Enemy) > 2) then Engine.MoveToObj(Enemy, 1);
Engine.PickUp(Enemy);
end;
// if we need to find new target - do it
if (not Assigned(Enemy)) or (not Enemy.Valid) or (Enemy.Dead) then begin
Print('Search for a new target ...');
Enemy:= FindEnemy(SEARCH_RANGE);
end;
if Assigned(Enemy) and (Enemy.Valid) then begin
Print(Format('New target: %s | Dist: %n', [Enemy.Name, User.DistTo(Enemy)]));
if (User.Target <> Enemy) then begin
Delay(ACTIONS_DELAY);
Engine.SetTarget(Enemy); // then target it
end;
if (User.DistTo(Enemy) > FIGHT_DISTANCE) then begin
Delay(ACTIONS_DELAY);
Engine.MoveToObj(Enemy, FIGHT_DISTANCE-3);
end;
for i:= 0 to AtkSkillsSL.Count-1 do begin
if (Enemy.Dead) then Break;
SkillName:= Trim(AtkSkillsSL[i]);
if (SkillName = '') then Continue;
if TryStrToInt(SkillName, SkillID) then begin
Skills.ByID(SkillID, Skill);
end else begin
Skills.ByName(SkillName, Skill);
end;
if Assigned(Skill) and (Skill.EndTime = 0) then begin
Print(Format('Use skill: %s [id: %d]', [Skill.Name, Skill.ID]));
Engine.TurnTo(Enemy);
Delay(ACTIONS_DELAY);
if Engine.UseSkill(Skill.ID) then
while (User.Cast.EndTime > 0) do Delay(50);
end;
end;
end;
end;
end;
finally
AtkSkillsSL.Free();
end;
end;
function FindEnemy(MaxDist: Single = 50.0): TLive;
var
i: integer;
Mob: TLive;
begin
Result:= nil;
for i:= 0 to Mobs.Count-1 do begin
Mob:= Mobs(i);
if (Mob.Valid) and (not Mob.Dead) and (User.DistTo(Mob) <= MaxDist)
and ((Mob.Target = nil) or (Mob.Target = User)) then begin
Result:= Mob;
MaxDist:= User.DistTo(Mob);
end;
end;
end;
function TryStrToInt(S: String; out Number: Integer): Boolean;
var Error: Integer;
begin
Val(S, Number, Error);
Result:= (Error = 0);
if (not Result) then Number:= 0;
end;
procedure PrintAvaialbeSkills();
var
i: integer;
Skill: TSkill;
begin
Print('--------------- Skills ---------------');
for i:= 0 to Skills.Count-1 do begin
Skill:= Skills(i);
if (not Skill.Passive) then Print(Format('%s [id: %d] %d lvl', [Skill.Name, Skill.ID, Skill.Level]));
end;
Print('----------------------------------------');
end;
begin
PrintAvaialbeSkills();
Script.NewThread(@GrindThread);
// ...
Delay(-1);
end.