The script can work for both, one tank (charge off a pet or off a mob) and two (charge off each other).
How it works: turns off the bot interface, puts on specific weapon used for charging (if any), starts hitting a pet (damage reflection is needed) or attacks itself with the second tank until it charges completely, puts on the sword + shield back (if any) and turns the bot interface back on (if necessary). Works with any tanks. Also, in the case of two tanks, at the beginning, it determines which one has lower cooldown as to charge this one first (Optimizing the whole process in case the script is restarted).
The code runs inside its own thread, making it easier to integrate in existing scripts. To configure it, just change the values of constants inside the procedure.
procedure IconAutouseThread();
const
// ---------------------- SETTINGS ----------------------
ENABLE_INTERFACE = False; // whether to reactivate the interface after charging (True - yes, False - no)
PET_ITEM_ID = 10426; // specify the item ID for the summon pet - Fenrir Necklace [id: 10426]
SECOND_TANK_NAME = 'Nickname'; // specify the nickname of the second tank to be charged about
CHARGE_WEAPON_ID = 256; // specify the weapon ID to charge - Cestus [id: 256]
SWORD_ID = 14120; // specify the main weapon ID
SHIELD_ID = 2498; // specify the shield ID
var
second_name: string;
seed_id, icon_id, trigger_id: cardinal;
seed, icon: TL2skill;
trigger: TL2Buff;
E, E2: TL2Control;
player: TL2Char;
target: TL2Live;
item: TL2Item;
point: TXYZ;
// procedure for setting variables depending on the class
procedure SetVars();
begin
if (E.GetUser.ClassID = 91) then begin // if we are - Hell Knight, then
seed_id:= 761; // skill Seed of Revenge [id: 761]
icon_id:= 762; // skill Insane Crusher [id: 762]
trigger_id:= 5561; // buff Seed of Revenge [id: 5561]
end;
if (E.GetUser.ClassID = 90) then begin // if we are - Phoenix Knight, then
seed_id:= 784; // skill Spirit of Phoenix [id: 784]
icon_id:= 785; // skill Flame Icon [id: 785]
trigger_id:= 5562; // buff Spirit of Phoenix [id: 5562]
end;
if (E.GetUser.ClassID = 99) then begin // if we are - Eva's Templar, then
seed_id:= 786; // skill Eva's Will [id: 786]
icon_id:= 787; // skill Touch of Eva [id: 787]
trigger_id:= 5563; // buff Eva's Will [id: 5563]
end;
if (E.GetUser.ClassID = 106) then begin // if we are - Shillien Templar, then
seed_id:= 788; // skill Pain of Shilen [id: 788]
icon_id:= 789; // skill Spirit of Shilen [id: 789]
trigger_id:= 5564; // buff Pain of Shillien [id: 5564]
end;
end;
// procedure that determines which tank will use the icon first
procedure Init();
var skill: TL2Skill; cd: cardinal;
begin
if (LanguageID = 1) then
Engine.Msg('AdrenalineBot.com', 'покупка ключей к боту, розыгрыши бесплатных ключей, бесплатные скрипты и многое другое!', $0045FF)
else
Engine.Msg('AdrenalineBot.com', 'selling bot keys, free keys lottery, free scripts and much more!', $0045FF);
if (GetControl(SECOND_TANK_NAME) = nil) then begin
E:= Engine;
second_name:= SECOND_TANK_NAME;
end else begin
E:= Engine;
SetVars();
if E.GetSkillList.ByID(icon_id, skill) then cd:= skill.EndTime;
E:= GetControl(SECOND_TANK_NAME);
SetVars();
if E.GetSkillList.ByID(icon_id, skill) then begin
if (cd > skill.EndTime) then begin
E:= GetControl(SECOND_TANK_NAME);
second_name:= User.Name;
end else begin
E:= Engine;
second_name:= SECOND_TANK_NAME;
end;
end;
end;
end;
// procedure putting on the specified item by ID
procedure EquipItem(item_id: integer; Control: TL2Control = nil);
var item: TL2Item;
begin
if (Control = nil) then Control:= E;
{while (Control.GetInventory.User.ByID(item_id, item) and (not item.Equipped)) do begin
if Control.UseItem(item) then Delay(1000);
end;}
if Control.GetInventory.User.ByID(item_id, item) and (not item.Equipped) then
if Control.UseItem(item) then Delay(1000);
end;
// role-changing procedure for tanks
procedure SwitchChars();
begin
if (E = Engine) then begin
E:= GetControl(SECOND_TANK_NAME);
second_name:= User.Name;
end else begin
E:= Engine;
second_name:= SECOND_TANK_NAME;
end;
end;
begin
Init();
while Delay(500) do begin // run an endless loop so that the thread runs continuously
SetVars();
if (E.Status = lsOnline) // if we are in the game
and (not (E.GetZoneType = ztPeace)) // and not in a peaceful zone
and ((not E.GetUser.Buffs.ByID(icon_id, icon)) or (icon.EndTime < 15000)) then begin // and the icon is not buffed or buff left < 15 sec, then
if E.GetSkillList.ByID(icon_id, icon) and (icon.EndTime < 15000) // if Icon cooldowns back after < 15 seconds (or is already ready)
and E.GetSkillList.ByID(seed_id, seed) and (seed.EndTime = 0) then begin // and seed isn't in cooldown, then
if (not E.GetUser.Buffs.ByID(seed_id, trigger)) // if we don’t have a charging buff
and (not E.GetUser.Buffs.ByID(trigger_id, trigger)) then begin
Engine.Msg('[IconAutouseThread]', E.GetUser.Name+': using a charging buff '+BaseSkillByID(seed_id, True), 0);
if E.UseSkill(seed) then Delay(E.GetUser.Cast.EndTime); // use a charging buff
end;
// 1st case: when the nickname of the 2nd tank was set and this tank in the line of sight are indicated
if (second_name <> '') and E.GetCharList.ByName(second_name, player) then begin
target:= E.GetUser; // determine who needs to be attacked (in this case, our character)
E2:= GetControl(second_name); // determine the controller of the 2nd tank
E2.FaceControl(0, False); // turn off the interface to the 2nd tank
EquipItem(CHARGE_WEAPON_ID, E2); // if the 2nd tank has a weapon for charging and it is not worn, then we put on
point:= CalcXYZ(E2.GetUser, target, -50, 0); // calculate the point next to the target
if E2.DMoveTo(point.X, point.Y, point.Z) then Delay(500); // run the 2nd tank to this point
while ( (E.GetUser.Buffs.ByID(seed_id, trigger))
or (E.GetUser.Buffs.ByID(trigger_id, trigger) and (trigger.Level < 3)) )// while the charging buff is hanging on us and its level is < 3
and (target <> nil) and (not target.Dead) do begin // and the target exists and is not dead
if (E2.GetUser.Dead) then break; // if the 2nd tank is dead, we exit the cycle
if (E2.GetUser.Target <> target) then // if the 2nd tank has no target selected (our character)
if E2.SetTarget(target) then Delay(500); // then we tell the 2nd tank to take our character to the target
E2.Attack(true); // tell the second tank to attack our character
end;
if (trigger.Level = 3) then begin // if our character has accumulated charge level = 3
while (icon.EndTime > 0) do Delay(500); // we wait until the icon exactly cooldowns back
while (not E.GetUser.Buffs.ByID(icon_id, icon)) or (icon.EndTime < 50000) do begin // until the icon buff is updated on us
if (not E.GetUser.Buffs.ByID(trigger_id, trigger)) or (trigger.Level < 3) then Break; // if the charge has flown - we exit the cycle
if E.UseSkill(icon_id) then Delay(E.GetUser.Cast.EndTime); // activate the icon and wait for the end of the cast
Delay(500);
end;
Engine.Msg('[IconAutouseThread]', E.GetUser.Name+': icon activated '+BaseSkillByID(icon_id, True), 0);
E2.DMoveTo(E2.GetUser.X+10, E2.GetUser.Y+10, E2.GetUser.Z+10); // move the 2nd tank to the point next to it to cancel the attack
EquipItem(SWORD_ID, E2); // we tell the 2nd tank to put back the sword if necessary
EquipItem(SHIELD_ID, E2); // we tell the 2nd tank to put back the shield, if necessary
E2.FaceControl(0, ENABLE_INTERFACE); // turns on the interface of the 2nd tank (you can comment if you don't need it)
Delay(5000);
SwitchChars(); // we call a procedure that changes characters in roles
end;
end
else
// 2nd case: when we have a living pet called up or have an item to summon him
if ((E.GetPetList.Count > 0) and (not E.GetPetList.Items(0).Dead))
or (E.GetInventory.User.ByID(PET_ITEM_ID, item)) then begin
if (E.GetPetList.Count = 0) then begin // check if the pet is not called, then
if E.UseItem(PET_ITEM_ID) then Delay(E.GetUser.Cast.EndTime); // use the item to summon the pet and expect the end of the cast
end;
target:= E.GetPetList.Items(0); // determine who needs to be attacked (in this case, our pet)
E.FaceControl(0, False); // turns off the interface
EquipItem(CHARGE_WEAPON_ID); // if we have a weapon for charging and it is not worn, then we put on
point:= CalcXYZ(E.GetUser, target, -50, 0); // calculate the point next to the target
if E.DMoveTo(point.X, point.Y, point.Z) then Delay(500); // run to this point
while ( (E.GetUser.Buffs.ByID(seed_id, trigger))
or (E.GetUser.Buffs.ByID(trigger_id, trigger) and (trigger.Level < 3)) )// while the charging buff is hanging on us and its level is <3
and (target <> nil) and (not target.Dead) do begin
if (E.GetUser.Dead) then break; // if we are dead we exit the cycle
if (E.GetUser.Target <> target) then // if pet is not in target
if E.SetTarget(target) then Delay(500); // then take it to target
E.Attack(true); // attack pet while waiting for charging
end;
if (trigger.Level = 3) then begin // if we have accumulated charge level = 3
while (icon.EndTime > 0) do Delay(500); // we wait until the icon exactly cooldowns back
while (not E.GetUser.Buffs.ByID(icon_id, icon)) or (icon.EndTime < 50000) do begin // until the icon buff is updated on us
if (not E.GetUser.Buffs.ByID(trigger_id, trigger)) or (trigger.Level < 3) then Break; // if the charge has flown - we exit the cycle
if E.UseSkill(icon_id) then Delay(E.GetUser.Cast.EndTime); // activate the icon and wait for the end of the cast
Delay(500);
end;
Engine.Msg('[IconAutouseThread]', E.GetUser.Name+': icon activated '+BaseSkillByID(icon_id, True), 0);
E.DMoveTo(E.GetUser.X+10, E.GetUser.Y+10, E.GetUser.Z); // cancel attack pet
EquipItem(SWORD_ID); // put the sword back if necessary
EquipItem(SHIELD_ID); // put the shield back if necessary
E.FaceControl(0, ENABLE_INTERFACE); // turn the interface back on (you can comment if you don't need it)
end;
end
else
// 3rd case: just wait until the charge is full
begin
if (trigger.Level = 3) then begin // if we have accumulated charge level = 3
if E.UseSkill(icon) then Delay(E.GetUser.Cast.EndTime); // activate the icon
end;
end;
end;
end;
end;
end;
begin
Script.NewThread(@IconAutouseThread); // start the thread for auto-charging icons
// code...
Delay(-1);
end.