Скрипт для добычи руды (Mining script)
Внешний вид
Скрипт для Legnes/Orion Assist. Вариант с возвратом (Recall) по руне в банке. Отстреливает "слабых" стражей (Ore Guardian) из лука с примитивным отбеганием, использует магию Рассеивание (Dispel) на призванных стражем существ.
Автор скрипта: Hotride
// В ToolsBag должны лежать расходники:
// Реги на реколл и диспел, свитки диспела, бинты, стрелы для лука, кирки
// Руны в пещеры должны лежать в банке
// Использовать фильтр руды, 0 - не использовать, 1 - использовать
var UseOreNameFilter = 1;
// Названия руды для игнорирования жилы (не продолжать копать)
var IgnoreOreNames = 'Iron ore|Железная руда';
// Использовать хайд, 0 - не использовать, 1 - использовать
var UseHidding = 0;
// Выгружать руду с переплавкой, 0 - не плавить, 1 - плавить
var UnloadWithSmelt = 1;
// Звук при появлении элементаля
var SoundForGuard = 'C:/a.wav';
// Количество повтора звука
var SoundRepeatCount = 5;
// Серийник сундука, в котором находятся мешки (может быть пустым)
var TopChest = '0x401EFC28';
// Серийник мешка с инструментами, регами и едой
var ToolsBag = '0x402D405A';
// Серийник мешка для руды
var OresBag = '0x401C01A2';
// Типы еды
var FoodType = '0x09B7|0x09F2|0x097B';
// Серийник оружия, который использовать при появлении гварда
var UseWeaponForGuard = 'guard_weapon';
// Серийник руны домой
var RuneHome = '0x40325C4C';
// Серийники рун в пещеры
var RunesToCave =
[
// Trinsic secret cave
'0x40299CC3',
// Trinsic cave
'0x40299CBB',
// Hytloth 1
'0x402D1461',
// Hytloth 2
'0x402D145A',
// Cave 3
'0x40299CB6'
];
// Точки обкопки в пещерах
var CaveSpots =
[
// Trinsic secret cave
[
[ 1662, 2935 ],
[ 1661, 2934 ],
[ 1659, 2932 ],
[ 1655, 2932 ],
[ 1655, 2927 ],
[ 1653, 2926 ],
[ 1653, 2922 ],
[ 1652, 2917 ],
[ 1650, 2915 ],
[ 1649, 2912 ],
[ 1648, 2908 ],
[ 1647, 2903 ],
[ 1647, 2898 ],
[ 1648, 2894 ],
],
// Trinsic cave
[
[ 1490, 2852 ],
[ 1494, 2852 ],
[ 1491, 2847 ],
[ 1495, 2848 ],
[ 1495, 2843 ],
[ 1494, 2839 ],
[ 1495, 2834 ],
[ 1491, 2834 ],
[ 1489, 2837 ],
[ 1484, 2837 ],
[ 1481, 2840 ],
[ 1478, 2842 ],
[ 1488, 2834 ],
[ 1492, 2829 ],
[ 1488, 2825 ],
[ 1489, 2821 ],
[ 1492, 2824 ],
[ 1496, 2828 ],
[ 1498, 2830 ],
],
// Hytloth 1
[
[ 4605, 3821 ],
[ 4602, 3819 ],
[ 4600, 3815 ],
[ 4598, 3813 ],
[ 4600, 3811 ],
[ 4604, 3813 ],
[ 4605, 3816 ],
[ 4609, 3817 ],
[ 4612, 3817 ],
[ 4610, 3820 ]
],
// Hytloth 2
[
[ 4552, 3172 ],
[ 4551, 3175 ],
[ 4548, 3175 ],
[ 4547, 3172 ],
[ 4547, 3167 ],
[ 4551, 3167 ]
],
// Cave 3
[
[ 996, 1600 ],
[ 998, 1600 ],
[ 996, 1595 ],
[ 996, 1590 ],
[ 991, 1593 ],
[ 989, 1589 ],
[ 992, 1588 ],
[ 990, 1584 ],
[ 995, 1585 ],
[ 994, 1580 ],
[ 998, 1581 ],
[ 996, 1576 ],
[ 1000, 1576 ],
[ 1003, 1579 ],
[ 1003, 1584 ],
[ 1000, 1586 ],
[ 1004, 1589 ],
[ 1001, 1591 ],
[ 1001, 1596 ],
[ 1005, 1594 ],
[ 1008, 1595 ],
[ 1010, 1592 ],
[ 1008, 1589 ],
[ 1007, 1586 ]
]
];
// Не трогать!!!
var FakeId = 0;
function UsePickaxe(_private)
{
if (!Orion.UseType('0x0E85', 'any', self, false))
{
if (!Orion.UseType('0x0E85'))
{
Orion.Print('0x0021', 'Your tool is gone!');
return false;
}
}
return true;
}
function WalkHangChecker(_private)
{
var x = Player.X();
var y = Player.Y();
var count = 0;
while (true)
{
if (x == Player.X() && y == Player.Y())
count++;
else
count = 0;
if (count >= 15)
{
Orion.StopWalking();
count = 0;
}
x = Player.X();
y = Player.Y();
Orion.Wait(1000);
}
}
function WalkToWrapper(x, y, distance, run)
{
Orion.Exec('WalkHangChecker');
Orion.Wait(20);
// Потому что на пути следования могут быть динамические препятствия
for (var i = 0; i < 3; i++)
{
if (Orion.WalkTo(x, y, 0, distance, 255, run))
{
Orion.Terminate('WalkHangChecker');
Orion.Wait(20);
return true;
}
}
Orion.Terminate('WalkHangChecker');
Orion.Wait(20);
return false;
}
function RecallTo(rune)
{
var x = Player.X();
var y = Player.Y();
var successCount = 0;
while (x == Player.X() && y == Player.Y() && successCount < 5)
{
Orion.WarMode(0);
Orion.Wait(100);
Orion.ClearJournal();
var timeout = Orion.Now() + 10000;
var mr = Orion.Count('mr');
Orion.Cast('32', rune);
while (mr == Orion.Count('mr') && timeout > Orion.Now())
Orion.Wait(100);
if (Orion.InJournal('The spell fizzles', 'my|sys') == null)
successCount++;
var msgUses = Orion.InJournal('uses left', 'my|sys');
if (msgUses != null)
{
for (var i = 0; i < 10; i++)
{
if (Orion.Contains(msgUses.Text(), 'has ' + i + ' uses left'))
{
MarkRune(rune);
break;
}
}
break;
}
}
if (Player.Mana('%') < 99)
{
Orion.WarMode(false);
Orion.Exec('AutoMeditation', true);
}
}
function MarkRune(rune)
{
while (true)
{
if (Player.Mana('%') < 40)
{
while (Player.Mana('%') < 100)
{
Orion.UseSkill('46');
Orion.Wait(500);
}
}
Orion.WarMode(0);
Orion.Wait(100);
Orion.ClearJournal();
var timeout = Orion.Now() + 10000;
var mr = Orion.Count('mr');
Orion.Cast('45', rune);
while (mr == Orion.Count('mr') && timeout > Orion.Now())
Orion.Wait(100);
if (Orion.InJournal('The spell fizzles', 'my|sys') == null)
break;
}
}
function Restock(graphic, count)
{
var val = Orion.Count(graphic);
while (val < count)
{
if (!Orion.MoveItemType(graphic, 'any', ToolsBag, count - val))
break;
Orion.Wait(400);
val = Orion.Count(graphic);
}
}
function CheckOverweight(forced, runeCave)
{
if (forced || Player.Weight('%') >= 97)
{
var oldX = Player.X();
var oldY = Player.Y();
if (!forced)
Orion.Print('0x0021', 'Weight limit reached!!!');
RecallTo(RuneHome);
if (UnloadWithSmelt)
{
while (Orion.UseType('0x19B7|0x19BA|0x19B8|0x19B9'))
Orion.Wait(100);
}
if (TopChest != '')
Orion.UseObject(TopChest);
Orion.UseObject(ToolsBag);
Orion.UseObject(OresBag);
Orion.Wait(200);
UnloadIngots();
UnloadOres();
// Bloody bandages
if (Orion.MoveItemType('0x0E20', '0', backpack, 0, ToolsBag))
Orion.Wait(400);
if (Orion.Count(FoodType, '0') > 0 || Orion.MoveItemType(FoodType, '0', ToolsBag, 1))
{
Orion.UseType(FoodType, '0');
Orion.Wait(100);
}
Restock('0x0E85', 4); // Pickaxe
Restock('0x0F3F', 100); // Arrows
Restock('0x1F55', 20); // Dispel scrolls
//Restock('0x1F62', 10); // Mass dispel scrolls
Restock('bandage', 100);
Restock('mr', 50);
Restock('bp', 20);
Restock('bm', 20);
Restock('ga', 30);
Restock('sa', 30);
if (Orion.Count('0x0E85') == 0)
{
Orion.Print('0x0021', 'No pickaxes!!!');
Orion.PauseScript();
}
else if (Orion.Count('0x0F3F') < 30)
{
Orion.Print('0x0021', 'No arrows!!!');
Orion.PauseScript();
}
else if (Orion.Count('mr') < 5 || Orion.Count('bp') < 5 || Orion.Count('bm') < 5)
{
Orion.Print('0x0021', 'No reagents to recalls!!!');
Orion.PauseScript();
}
if (runeCave != '')
RecallTo(runeCave);
if (!forced)
WalkToWrapper(oldX, oldY, 0, (UseHidding == 0 || !Player.Hidden()));
}
}
function PlayGuardAlarm(_private)
{
for (var i = 0; i < SoundRepeatCount; i++)
{
Orion.PlayWav(SoundForGuard);
Orion.Wait(1000);
}
}
function DispelSummons(guard)
{
var summon = null;
if (guard != null && guard.Color() == '0x0000')
summon = guard;
else
{
var summons = Orion.FindTypeEx('0x000E|0x000F|0x0009|0x023E', '0', ground, 'mobile|near', 10);
if (summons.length > 0)
summon = summons[0];
}
if (summon != null)
{
while (summon.Exists() && Player.Hits('%') >= 50 && Player.Mana() >= 20)
{
var timeout = Orion.Now() + 6000;
var type = '0x1F55';
var count = Orion.Count(type);
if (count > 0)
{
Orion.WaitTargetObject(summon.Serial());
Orion.UseType(type);
}
else
{
type = 'mr';
count = Orion.Count(type);
if (count > 0 && Orion.Count('ga') > 0 && Orion.Count('sa') > 0)
Orion.Cast('41', summon.Serial());
else
return false;
}
while (count == Orion.Count(type) && timeout > Orion.Now())
Orion.Wait(100);
Orion.Wait(100);
}
return !summon.Exists();
}
return true;
}
function GetDirectionToFlee(target, mirrored, inversedXY)
{
var targetX = target.X();
var targetY = target.Y();
var x = Player.X();
var y = Player.Y();
if (mirrored)
{
targetX = Player.X();
targetY = Player.Y();
x = target.X();
y = target.Y();
}
if (inversedXY)
{
var temp = targetX;
targetX = targetY;
targetY = temp;
temp = x;
x = y;
y = temp;
}
if (x == targetX)
{
if (y < targetY)
return 0;
else //if (y >= targetY)
return 4;
}
else if (y == targetY)
{
if (x < targetX)
return 6;
else //if (x > targetX)
return 2;
}
else
{
if (x > targetX)
{
if (y < targetY)
return 1;
else //if (y > targetY)
return 3;
}
else //if (x < targetX)
{
if (y > targetY)
return 5;
else //if (y < targetY)
return 7;
}
}
return 0;
}
function Flee(target, direction, distance)
{
switch (direction)
{
case 0:
return Orion.WalkTo(target.X(), target.Y() - distance, 0, 0, 255, true);
case 1:
return Orion.WalkTo(target.X() + distance, target.Y() - distance, 0, 0, 255, true);
case 2:
return Orion.WalkTo(target.X() + distance, target.Y(), 0, 0, 255, true);
case 3:
return Orion.WalkTo(target.X() + distance, target.Y() + distance, 0, 0, 255, true);
case 4:
return Orion.WalkTo(target.X(), target.Y() + distance, 0, 0, 255, true);
case 5:
return Orion.WalkTo(target.X() - distance, target.Y() + distance, 0, 0, 255, true);
case 6:
return Orion.WalkTo(target.X() - distance, target.Y(), 0, 0, 255, true);
case 7:
return Orion.WalkTo(target.X() - distance, target.Y() - distance, 0, 0, 255, true);
default:
break;
}
return false;
}
function CheckGuards(_private)
{
var guards = Orion.FindTypeEx('0x000E', 'any', ground, 'mobile|near', 10);
if (guards.length > 0)
{
var oldX = Player.X();
var oldY = Player.Y();
if (UseWeaponForGuard != '')
Orion.UseObject(UseWeaponForGuard);
var guard = guards[0];
if (Orion.Contains('0x07D1|0x0253|0x052D|0x0455|0x0486|0x0487', guard.Color()))
{
Orion.Exec('PlayGuardAlarm');
if (!Player.Hidden())
{
Orion.WarMode(false);
Orion.Wait(100);
Orion.UseSkill('21');
}
Orion.PauseScript();
}
Orion.WarMode(true);
Orion.Ignore(guard.Serial());
while (guard.Exists() && Player.Hits('%') >= 50)
{
if (guard.Distance() > 6)
{
Orion.WalkTo(guard.X(), guard.Y(), 0, 4, 255, true);
}
else
{
var distance = 4;
if (guard.Distance() < distance)
{
var direction = GetDirectionToFlee(guard, false, false);
if (!Flee(guard, direction, distance))
{
direction = GetDirectionToFlee(guard, false, true);
if (!Flee(guard, direction, distance))
{
direction = GetDirectionToFlee(guard, true, true);
if (!Flee(guard, direction, distance))
{
direction = GetDirectionToFlee(guard, true, false);
Flee(guard, direction, distance);
}
}
}
}
}
Orion.Attack(guard.Serial());
Orion.Wait(500);
if (!DispelSummons(guard))
break;
}
if (guard.Exists())
{
Orion.Exec('PlayGuardAlarm');
Orion.PauseScript();
}
else
{
DispelSummons(null);
// Blade spirits
while (Player.Hits('%') >= 50)
{
var summons = Orion.FindTypeEx('0x023E', 'any', ground, 'mobile|near', 10);
if (summons.length == 0)
break;
guard = summons[0];
Orion.Ignore(guard.Serial());
while (guard.Exists() && Player.Hits('%') >= 50)
{
Orion.Attack(guard.Serial());
Orion.Wait(500);
}
}
}
if (Player.Mana('%') < 99)
{
Orion.WarMode(false);
Orion.Exec('AutoMeditation', true);
}
var corpses = Orion.FindTypeEx('0x2006', 'any', ground, '', 10);
if (corpses.length > 0)
{
for (var c = 0; c < corpses.length; c++)
{
var corpse = corpses[c];
WalkToWrapper(corpse.X(), corpse.Y(), 1, true);
Orion.Wait(1000);
Orion.UseObject(corpse.Serial());
Orion.Ignore(corpse.Serial());
Orion.Wait(2500);
}
}
else
{
Orion.Print('0x0021', 'Corpse not found!');
Orion.Exec('PlayGuardAlarm');
Orion.PauseScript();
}
Orion.WarMode(false);
WalkToWrapper(oldX, oldY, 0, (UseHidding == 0 || !Player.Hidden()));
}
}
function AutoMeditation(_private)
{
while (Player.Hits('%') > 50 && Player.Mana('%') < 99)
{
Orion.UseSkill('46');
Orion.Wait(500);
}
}
function MiningDig(runeCave)
{
var text = 'в свой рюкзак|in your pack|Вы расшатываете несколько камней, но не можете найти|You loosen some rocks but fail to find|Это слишком далеко|That is too far away|Цель находится вне прямой видимости|Target is not in line of sight|Здесь нет руды, которую можно было бы добывать|There is no ore here to mine';
for (var x = -2; x <= 2; x++)
{
for (var y = -2; y <= 2; y++)
{
var tryingCount = 0;
while (true)
{
if (Player.Hits('%') < 50)
{
Orion.Exec('PlayGuardAlarm');
Orion.PauseScript();
}
CheckGuards(0);
DispelSummons(null);
var hits = Player.Hits('%');
var needHeal = (hits > 50 && hits < 99 && Orion.Count('bandage') > 0);
if (needHeal)
{
Orion.PauseScript('AutoMeditation');
while (needHeal)
{
Orion.BandageSelf();
Orion.Wait(2000);
hits = Player.Hits('%');
needHeal = (hits > 50 && hits < 99 && Orion.Count('bandage') > 0);
}
Orion.ResumeScript('AutoMeditation');
}
while (Orion.ScriptRunning('AutoMeditation'))
Orion.Wait(500);
while (UseHidding && !Player.Hidden())
{
Orion.WarMode(false);
Orion.Wait(100);
Orion.UseSkill('21');
Orion.WaitJournal('Вы хорошо спрятались|You have hidden yourself well|Кажется, ты не можешь здесь спрятаться|t seem to hide here', Orion.Now(), Orion.Now() + 3000);
}
CheckOverweight(false, runeCave);
if (!Orion.ValidateTargetTileRelative('mine', x, y, 0))
break;
var now = Orion.Now();
Orion.WaitTargetTileRelative('mine', x, y, 0);
if (!UsePickaxe(0))
{
CheckOverweight(true, runeCave);
Orion.WaitTargetTileRelative('mine', x, y, 0);
UsePickaxe(0);
}
var msg = Orion.WaitJournal(text, now, now + 5000, 'my|sys');
if (msg != null)
{
if (msg.FindTextID() > 3)
break;
tryingCount++;
if (tryingCount >= 10)
break;
if (UseOreNameFilter && Orion.Contains(msg.Text(), IgnoreOreNames))
break;
}
Orion.WarMode(false);
Orion.Wait(50);
}
}
}
}
function Mining()
{
for (var cave = 0; cave < CaveSpots.length; cave++)
{
RecallTo(RunesToCave[cave]);
var spot = CaveSpots[cave];
//for (var c = 0; c < 2; c++) // Потому что на первом проходе, почему-то, бывают пропуски тайлов и недокопы
{
for (var i = 0; i < spot.length; i++)
{
WalkToWrapper(spot[i][0], spot[i][1], 0, (UseHidding == 0 || !Player.Hidden()));
MiningDig(RunesToCave[cave]);
}
}
if (Player.Weight('%') >= 65)
CheckOverweight(true, '');
}
Orion.Print(0x0044, 'Caves cycle done, restarting in ' + SoundRepeatCount + ' seconds...');
PlayGuardAlarm(0);
Orion.Wait(5000);
// Exec а не while (true) чтобы перезагружались константы (если ломается лук или какие-то правки кода)
// Чтоб вручную не ловить конец цикла/стопать на полпути и не перезапускать заново
Orion.Exec('Mining');
Orion.Wait(500);
}
function UnloadIngots()
{
while (Orion.MoveItemType('0x1BEF|0x1BF2|0x1BE3|0x1BE9|0x1BF5|0x0F02', 'any', backpack, 0, OresBag))
Orion.Wait(400);
}
function UnloadOres()
{
while (Orion.MoveItemType('0x19B7|0x19BA|0x19B8|0x19B9|gp', 'any', backpack, 0, OresBag))
Orion.Wait(400);
}
function SmeltIronOres()
{
while (true)
{
var list = Orion.FindTypeEx('0x19B7|0x19BA|0x19B8|0x19B9', '0');
for (var i = 0; i < list.length; i++)
{
if (list[i].Count() == 1)
{
Orion.UseObject(list[i].Serial());
Orion.Wait(100);
}
else
{
Orion.MoveItem(list[i].Serial(), 1, backpack, 50, 50);
Orion.Wait(400);
}
}
if (list.length == 0)
return;
}
}
function TestHarvestingZones(rune)
{
Orion.ClearFakeMapObjects();
if (rune < 0 || rune >= CaveSpots.length)
{
Orion.Print('0x0021', 'Invalid rune index: ' + rune);
return;
}
FakeId = 1;
var spots = CaveSpots[rune];
for (var spot = 0; spot < spots.length; spot++)
{
TestHarvestingZone(spots[spot][0], spots[spot][1], 2);
}
}
function TestHarvestingZone(centerX, centerY, distance)
{
for (var x = -distance; x <= distance; x++)
{
for (var y = -distance; y <= distance; y++)
{
Orion.AddFakeMapObject(FakeId++, '0x051A', '0x0044', centerX + x, centerY + y, Player.Z());
}
}
}