Рубка деревьев с возвращением в дом (Lumberjacking recall to Home)
Внешний вид
Скрипт для Legnes Assist. Скрипт для рубки деревьев на Легнес. После того как дерево упало, персонаж полностью рубит лежащее дерево и идёт к следующему. По наполнению рюкзака он возвращается домой по руне.
Автор скрипта: Hotride
// Использовать фильтр логов, 0 - не использовать, 1 - использовать
var UseLogsNameFilter = 0;
// Названия логов для игнорирования дерева (не продолжать рубить)
var IgnoreLogsNames = 'the log';
// Использовать хайд, 0 - не использовать, 1 - использовать
var UseHidding = 0;
// Дистанция для поиска деревьев
var SearchDistance = 15;
// Звук при появлении элементаля
var SoundForGuard = 'C:/a.wav';
// Количество повтора звука
var SoundRepeatCount = 5;
// Серийник сундука, в котором находятся мешки (может быть пустым)
var TopChest = '0x401EFC28';
// Серийник мешка с инструментами, регами и едой
var ToolsBag = '0x40351B31';
// Серийник мешка для логов
var LogsBag = '0x401EFC28';
// Типы еды
var FoodType = '0x09B7|0x09F2|0x097B';
// Серийник оружия, который использовать при появлении гварда
var UseWeaponForGuard = 'guard_weapon';
// Список зон, в которых не производить вырубку леса (территории домов)
// StartX, StartY, EndX, EndY
var IgnoreAreaList =
[
[ 75, 99, 89, 126 ]
];
// Использовать реколл или бегать относить логи пешком
var UseRecall = 1;
// Серийник руны домой
var RuneHome = '0x40325C4C';
// Координаты точки рядом с сундуками (должна быть в пешей доступности от леса)
// Только если UseRecall = 0
var HomeX = 0;
var HomeY = 0;
// Серийники рун в лес
var RunesToForest =
[
// Home forest
'0x40325DF6'
];
// Координаты точки в лесу (должна быть в пешей доступности от дома если UseRecall = 0)
var ForestSpots =
[
// Home forest
[
[ 118, 302 ],
[ 142, 302 ],
[ 146, 327 ],
[ 123, 327 ]
]
];
// Графика деревьев целых
var Trees =
[
0x0CDD, 0x0CCD, 0x0CD3, 0x0CDA, 0x0CD8,
0x0CE6, 0x0CE3, 0x0CD6
];
// Графика частей срубленных деревьев
var TreeParts =
[
0x3A97, 0x3A98, 0x3A99, 0x3AA2, 0x3AA1, 0x3AA0, 0x3A9A, 0x3A9B, 0x3A9C, 0x3A9D, 0x3A9E, 0x3A9F,
0x3AA9, 0x3AAA, 0x3AB9, 0x3AB8, 0x3AAB, 0x3AAC, 0x3AB7, 0x3AB6, 0x3AAD, 0x3AAC, 0x3AAE, 0x3AAF, 0x3AB3, 0x3AB0, 0x3AB1, 0x3AB4, 0x3AB5, 0x3AB2,
0x3A80, 0x3A81, 0x3A82, 0x3A83, 0x3A84, 0x3A8F, 0x3A8E, 0x3A8D, 0x3A8C, 0x3A88, 0x3A87, 0x3A86, 0x3A85, 0x3A8B, 0x3A8A, 0x3A89,
0x3A10, 0x3A11, 0x3A12, 0x3A13, 0x3A1B, 0x3A1A, 0x3A1C, 0x3A1D, 0x3A1E, 0x3A1F, 0x3A20, 0x3A21, 0x3A16, 0x3A14, 0x3A15, 0x3A19, 0x3A18, 0x3A17,
0x39FC, 0x39FD, 0x39FE, 0x39FF, 0x3A00, 0x3A09, 0x3A08, 0x3A07, 0x3A04, 0x3A03, 0x3A02, 0x3A01, 0x3A05, 0x3A06,
0x3AC0, 0x3AC1, 0x3AC2, 0x3AC3, 0x3ACE, 0x3ACD, 0x3ACC, 0x3AC8, 0x3AC7, 0x3AC6, 0x3AC5, 0x3ACB, 0x3AC4, 0x3AC9, 0x3ACA,
0x3A5A, 0x3A5B, 0x3A5C, 0x3A5D, 0x3A5E, 0x3A62, 0x3A61, 0x3A60, 0x3A5F, 0x3A63, 0x3A67, 0x3A66, 0x3A65, 0x3A64,
0x3A36, 0x3A37, 0x3A38, 0x3A39, 0x3A3A, 0x3A3E, 0x3A3D, 0x3A3C, 0x3A40, 0x3A3F, 0x3A3B, 0x3A40, 0x3A3F,
0x3A6E, 0x3A6F, 0x3A70, 0x3A71, 0x3A72, 0x3A79, 0x3A78, 0x3A77, 0x3A76, 0x3A75, 0x3A74, 0x3A73,
0x3A97, 0x3A98, 0x3A99, 0x3A9A, 0x3A9B, 0x3A9E, 0x3A9D, 0x3A9F, 0x3AA2, 0x3AA1, 0x3AA0,
0x3A47, 0x3A48, 0x3A49, 0x3A4A, 0x3A4B, 0x3A4C, 0x3A53, 0x3A52, 0x3A4F, 0x3A4E, 0x3A4D
];
// Не трогать!!!
var BannedLocations = [];
var FakeId = 0;
function UseHatchet(_private)
{
if (!Orion.UseType('0x0F43', 'any', self, false))
{
if (!Orion.UseType('0x0F43'))
{
Orion.Print('0x0021', 'Your tool is gone!');
return false;
}
}
return true;
}
function WalkHangChecker(distance)
{
var x = Player.X();
var y = Player.Y();
var count = 0;
var now = Orion.Now() + (distance * 500);
while (now > Orion.Now())
{
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.GetDistance(x, y));
Orion.Wait(30)
// Потому что на пути следования могут быть динамические препятствия
for (var i = 0; i < 3; i++)
{
if (Orion.WalkTo(x, y, 0, distance, 255, run))
{
Orion.Terminate('WalkHangChecker');
Orion.Wait(30)
return true;
}
}
Orion.Terminate('WalkHangChecker');
Orion.Wait(30)
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;
}
}
}
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, runeForest)
{
if (forced || Player.Weight('%') >= 95)
{
var oldX = Player.X();
var oldY = Player.Y();
if (!forced)
Orion.Print('0x0021', 'Weight limit reached!!!');
if (UseRecall)
RecallTo(RuneHome);
else
WalkToWrapper(HomeX, HomeY, 0, true);
if (TopChest != '')
Orion.UseObject(TopChest);
Orion.UseObject(LogsBag);
Orion.UseObject(ToolsBag);
Orion.Wait(200);
UnloadLogs();
if (Orion.Count(FoodType, '0') > 0 || Orion.MoveItemType(FoodType, '0', ToolsBag, 1))
{
Orion.UseType(FoodType, '0');
Orion.Wait(100);
}
Restock('0x0F43', 4); // Axe
if (Orion.Count('0x0F43') < 1)
{
Orion.Print('0x0021', 'No hatchets!!!');
Orion.PauseScript();
}
if (UseRecall)
{
Restock('mr', 20);
Restock('bp', 20);
Restock('bm', 20);
if (Orion.Count('mr') < 5 || Orion.Count('bp') < 5 || Orion.Count('bm') < 5)
{
Orion.Print('0x0021', 'No reagents to recalls!!!');
Orion.PauseScript();
}
}
if (runeForest != '')
{
if (UseRecall)
RecallTo(runeForest);
else
WalkToWrapper(oldX, oldY, 0, true);
}
}
}
function PlayGuardAlarm(_private)
{
for (var i = 0; i < SoundRepeatCount; i++)
{
Orion.PlayWav(SoundForGuard);
Orion.Wait(1000);
}
}
function CheckIgnoredArea(x, y)
{
for (var i = 0; i < IgnoreAreaList.length; i++)
{
var loc = IgnoreAreaList[i];
if (x >= loc[0] && y >= loc[1] && x <= loc[2] && y <= loc[3])
return true;
}
return false;
}
function LumberPart(tile, runeForest)
{
var text = 'в свой рюкзак|in your pack|Вы некоторое время рубите дерево, но не можете получить|but fail to produce any|Цель находится вне прямой видимости|too far away to chop|Target is not in line of sight|Вы не можете срубить это|cut it down|no logs left here to chop';
if (!WalkToWrapper(tile.X(), tile.Y(), 2, (UseHidding == 0 || !Player.Hidden())))
return false;
Orion.Ignore(self);
var tryingCount = 0;
while (tryingCount < 10)
{
if (Orion.FindType('0x0008', 'any', ground, 'mobile|near', 10).length > 0)
{
var oldX = Player.X();
var oldY = Player.Y();
if (UseWeaponForGuard != '')
Orion.UseObject(UseWeaponForGuard);
Orion.Exec('PlayGuardAlarm');
if (!Player.Hidden())
Orion.UseSkill('21');
//if (!Player.Hidden())
// CheckOverweight(true, '');
Orion.PauseScript();
Orion.WarMode(false);
WalkToWrapper(oldX, oldY, 0, (UseHidding == 0 || !Player.Hidden()));
}
var mobiles = Orion.FindType('any', 'any', ground, 'mobile|near', 1, 'red|gray|criminal');
if (mobiles.length > 0)
{
var oldX = Player.X();
var oldY = Player.Y();
var obj = Orion.FindObject(mobiles[0]);
if (UseWeaponForGuard != '')
Orion.UseObject(UseWeaponForGuard);
Orion.Exec('PlayGuardAlarm');
while (obj.Exists())
{
Orion.Attack(mobiles[0]);
if (obj.Distance() > 5)
Orion.WalkTo(obj.X(), obj.Y(), 0, 1, 255, true);
Orion.Wait(500);
}
WalkToWrapper(oldX, oldY, 0, (UseHidding == 0 || !Player.Hidden()));
}
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, runeForest);
var now = Orion.Now();
Orion.WaitTargetTile(tile.Graphic(), tile.X(), tile.Y(), tile.Z());
if (!UseHatchet(0))
{
CheckOverweight(true, runeForest);
Orion.WaitTargetTile(tile.Graphic(), tile.X(), tile.Y(), tile.Z());
UseHatchet(0);
}
tryingCount++;
var msg = Orion.WaitJournal(text, now, now + 5000, 'my|sys');
if (msg != null)
{
if (msg.FindTextID() > 3)
{
if ((msg.FindTextID() >= 4 && msg.FindTextID() <= 6) && !Orion.WalkTo(tile.X(), tile.Y(), tile.Z(), 0, 255, true))
{
BannedLocations.push([ tile.X(), tile.Y(), Orion.Now() + 15 * 60 * 1000 ]);
return false;
}
return (msg.FindTextID() == 3);
}
else if (UseLogsNameFilter && msg.FindTextID() <= 1)
{
if (Orion.Contains(msg.Text(), IgnoreLogsNames))
{
BannedLocations.push([ tile.X(), tile.Y(), Orion.Now() + 15 * 60 * 1000 ]);
return false;
}
}
}
Orion.Wait(10);
}
return (tryingCount < 10);
}
function LumberParts(_private, runeForest)
{
var tiles = Orion.GetTilesInRect('any', Player.X() - SearchDistance, Player.Y() - SearchDistance, Player.X() + SearchDistance, Player.Y() + SearchDistance);
var result = false;
for (var i = 0; i < tiles.length; i++)
{
if (CheckIgnoredArea(tiles[i].X(), tiles[i].Y()))
continue;
var graphic = parseInt(tiles[i].Graphic(), 16);
if (TreeParts.indexOf(graphic) != -1)
{
if (UseLogsNameFilter)
{
var now = Orion.Now();
var inBan = false;
for (var j = BannedLocations.length - 1; j >= 0; j--)
{
var loc = BannedLocations[j];
if (now > loc[2])
BannedLocations.splice(j, 1);
else if (loc[0] == tiles[i].X() && loc[1] == tiles[i].Y())
{
inBan = true;
break;
}
}
if (inBan)
continue;
}
if (LumberPart(tiles[i], runeForest))
result = true;
}
}
return result;
}
function LumberTree(tile, runeForest)
{
if (!WalkToWrapper(tile.X(), tile.Y(), 2, (UseHidding == 0 || !Player.Hidden())))
return false;
Orion.WaitTargetTile(tile.Graphic(), tile.X(), tile.Y(), tile.Z());
UseHatchet(0);
Orion.Wait(4500);
var result = false;
while (LumberParts(0, runeForest))
{
result = true;
Orion.Wait(100);
}
return result;
}
function LumberTrees()
{
var maxForestsCount = (UseRecall ? RunesToForest.length : 1);
var now = Orion.Now() + 5 * 60 * 1000;
for (var forest = 0; forest < maxForestsCount; forest++)
{
var spots = ForestSpots[forest];
if (UseRecall)
RecallTo(RunesToForest[forest]);
for (var spot = 0; spot < spots.length; spot++)
{
WalkToWrapper(spots[spot][0], spots[spot][1], 0, true);
var x = Player.X();
var y = Player.Y();
LumberParts(0, RunesToForest[forest]);
while (true)
{
Orion.WalkTo(x, y, 0, 1, 255, true);
var tiles = Orion.GetTilesInRect('any', x - SearchDistance, y - SearchDistance, x + SearchDistance, y + SearchDistance);
var hasTree = false;
for (var i = 0; i < tiles.length; i++)
{
if (CheckIgnoredArea(tiles[i].X(), tiles[i].Y()))
continue;
var graphic = parseInt(tiles[i].Graphic(), 16);
if (Trees.indexOf(graphic) != -1)
{
if (LumberTree(tiles[i], RunesToForest[forest]))
hasTree = true;
}
}
if (!hasTree)
break;
}
}
if (Player.Weight('%') >= 45)
CheckOverweight(true, '');
}
var delta = now - Orion.Now();
if (delta > 0)
{
var secs = delta / 1000;
var mins = Math.floor(secs / 60);
Orion.Print('Wait to respawn: ' + mins + ' min ' + Math.floor(secs - (mins * 60)) + ' sec');
Orion.Wait(delta);
}
Orion.Wait(100);
Orion.Exec('LumberTrees');
Orion.Wait(500);
}
function UnloadLogs()
{
while (Orion.MoveItemType('0x1BDD|0x0F90|0x0F79|gp', 'any', backpack, 0, LogsBag))
Orion.Wait(400);
}
function CheckHP()
{
while (true)
{
if (Player.Hits('%') < 90)
Orion.PlayWav('С:/1.wav');
Orion.Wait(1000);
}
}
function TestHarvestingZones(rune)
{
if (rune < 0 || rune >= ForestSpots.length)
{
Orion.Print('0x0021', 'Invalid rune index: ' + rune);
return;
}
Orion.ClearFakeMapObjects();
FakeId = 1;
var spots = ForestSpots[rune];
for (var spot = 0; spot < spots.length; spot++)
{
TestHarvestingZone(spots[spot][0], spots[spot][1], SearchDistance);
}
}
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());
}
}
}