258 lines
8.7 KiB
Lua
258 lines
8.7 KiB
Lua
-- File with most standard functions used in scripts
|
|
-- include it in your script:
|
|
-- dofile( "stdlib.lua" );
|
|
--
|
|
-- Ôàéë ñî ñòàíäàðòíûìè ôóíêöèÿìè äëÿ áîëüøèíñòâà ñêðèïòîâ
|
|
-- Ïîäêëþ÷àòü ýòè ôóíêöèè ê ñâîåìó ñêðèïòó òàê:
|
|
-- dofile( "stdlib.lua" );
|
|
|
|
-- âû÷èñëÿåò äèñòàíöèþ ïî dx, dy, dz: êîðåíü( dx*dx + dy*dy + dz*dz )
|
|
-- ïàðàìåòð dz ìîæåò áûòü ïðîïóùåí (íå çàäàí)
|
|
function calc_dist( dx, dy, dz )
|
|
if dz == nil then
|
|
return math.sqrt( dx*dx + dy*dy )
|
|
else
|
|
return math.sqrt( dx*dx + dy*dy + dz*dz )
|
|
end
|
|
end
|
|
|
|
function ensurestand()
|
|
local isSitting, isRunnig = l2c_getSitRun()
|
|
if isSitting then
|
|
l2c_sitStand();
|
|
l2h_delay( 1000 );
|
|
end
|
|
end
|
|
|
|
function ensuresit()
|
|
local isSitting, isRunnig = l2c_getSitRun()
|
|
if not isSitting then
|
|
l2c_sitStand();
|
|
l2h_delay( 1000 );
|
|
end
|
|
end
|
|
|
|
function ensurerun()
|
|
local isSitting, isRunnig = l2c_getSitRun()
|
|
if not isRunnig then
|
|
l2c_runWalk();
|
|
l2h_delay( 50 );
|
|
end
|
|
end
|
|
|
|
function ensurewalk()
|
|
local isSitting, isRunnig = l2c_getSitRun()
|
|
if isRunnig then
|
|
l2c_runWalk();
|
|
l2h_delay( 50 );
|
|
end
|
|
end
|
|
|
|
-- ôóíêöèÿ âåðíåò true, åñëè þçåð â ïàòè
|
|
function is_in_party()
|
|
local party = l2c_getParty();
|
|
local nMembers = #party;
|
|
if nMembers < 1 then return false end -- no party
|
|
return true
|
|
end
|
|
|
|
-- Ôóíêöèÿ ïûòàåòñÿ çàòàðãåòèòü objectID â òå÷åíèå timeoutSecs ñåêóíä
|
|
-- âåðíåò true, åñëè òàðãåò óäàëñÿ, èíà÷å false
|
|
function targetObject( objectID, timeoutSecs )
|
|
if timeoutSecs == nil then timeoutSecs = 2 end
|
|
local targetStartTime = l2h_time();
|
|
local targetObjectId = 0;
|
|
local timePassed = 0;
|
|
targetObjectId = l2c_getTarget();
|
|
if targetObjectId == objectID then return true end -- óæå íà òàðãåòå, íè÷î íå íàäî äåëàòü
|
|
l2c_action( objectID ); -- ïûòàåìñÿ çàòàðãåòèòü
|
|
l2h_delay( 100 );
|
|
repeat -- ïðîâåðÿåì â öèêëå, âçÿò ëè îáúåêò íà öåëü
|
|
targetObjectId = l2c_getTarget();
|
|
if sys_should_exit() then return end
|
|
local curTime = l2h_time(); -- çàîäíî ñìîòðèì ïî âðåìåíè
|
|
timePassed = curTime - targetStartTime;
|
|
l2h_delay( 100 );
|
|
if targetObjectId ~= objectID then l2c_action( objectID ); l2h_delay( 100 ); end
|
|
until (timePassed > timeoutSecs) or (targetObjectId == objectID) -- Ëèáî òàðãåò óäàëñÿ, ëèáî èñòåê òàéìàóò
|
|
if( targetObjectId ~= objectID ) then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
-- äâèãàòüñÿ â êîîðäèíàòû (x,y,z), îæèäàÿ äñòèæåíèÿ öåëè â òå÷åíèå timeout ñåêóíä
|
|
-- * tolerance - òî÷íîñòü äîñòèæåíèÿ öåëåâûõ êîîðäèíàò, àáñ. âåëè÷èíà, ïèêñåëè
|
|
-- * randomness - ñëó÷àéíîå îòêëîíåíèå îò öåëåâûõ êîîðäèíàò, ïèêñåëè
|
|
-- âåðíåò true, åñëè öåëü äîñòèãíóòà óñïåøíî, èíà÷å false
|
|
function moveTo( x, y, z, timeout, tolerance, randomness )
|
|
if timeout == nil then timeout = 30 end
|
|
if tolerance == nil then tolerance = 50 end
|
|
if randomness == nil then randomness = 0 end
|
|
local start_time = l2h_time();
|
|
repeat
|
|
if sys_should_exit() then return false end -- stop script
|
|
local cx, cy, cz = l2c_getPos(); -- get cur pos
|
|
-- target pos reached?
|
|
if (math.abs(cx - x) <= tolerance) and (math.abs(cy - y) <= tolerance) and (math.abs(cz - z) <= tolerance) then
|
|
return true
|
|
end
|
|
-- target not reached, try to move there
|
|
-- random XY offset (not exact move)
|
|
local x_rand = math.random( (0-randomness), randomness );
|
|
local y_rand = math.random( (0-randomness), randomness );
|
|
l2c_moveTo( x + x_rand, y + y_rand, z );
|
|
--- timeout expired?
|
|
local cur_time = l2h_time();
|
|
if (cur_time - start_time) > timeout then
|
|
l2h_print( "MOVETO: (",x,",",y,",",z,") ERROR: move timeout!\n" );
|
|
return false
|
|
end
|
|
l2h_delay( 300 ); -- delay 300 ms
|
|
until false
|
|
return false
|
|
end
|
|
|
|
-- âûáèðàåò íà öåëü NPC ñ íèêîì npcName;
|
|
-- âåðíåò true åñëè óñïåøíî, èíà÷å false
|
|
function npcSel( npcName )
|
|
if sys_should_exit() then return end
|
|
local oid = l2c_getNpcObjectIdByName( npcName );
|
|
if oid == nil then return false end
|
|
local ret = targetObject( oid, 5 );
|
|
if ret == false then l2h_print( "NPCSEL: cannot target [", npcName, "]!\n" ); end
|
|
return ret
|
|
end
|
|
|
|
-- îòêðûâàåò äèàëîã ñ ÍÏÖ êîòîðûé â äàííûé ìîìåíò íà òàðãåòå;
|
|
-- Íà òàðãåòå äîëæåí áûòü èìåííî ÍÏÖ! Ïðè íåîáõîäèìîñòè ôóíêöèÿ ïðèáëèæàåòñÿ ê ÍÏÖ íà ðàññòîÿíèå 50
|
|
-- * timeoutSecs - òàéìàóò îæèäàíèÿ îòêðûòèÿ äèàëîãà ñ ÍÏÖ, ñåê
|
|
function npcDlg( timeoutSecs )
|
|
if sys_should_exit() then return end
|
|
if timeoutSecs == nil then timeoutSecs = 5 end
|
|
local toid = l2c_getTarget();
|
|
if toid == 0 then -- no target :(
|
|
l2h_print( "NPCDLG: ERROR: No targeted NPC?\n" );
|
|
return false
|
|
end
|
|
local info = l2c_getObjectInfoByObjectId( toid );
|
|
if info == nil then
|
|
l2h_print( "NPCDLG: cannot get info about objectID [", toid, "]! Target disappeared??\n" );
|
|
return false
|
|
end
|
|
if info.type ~= "npc" then
|
|
l2h_print( "NPCDLG: ERROR: target [", toid, "] is not npc!..\n" );
|
|
return false
|
|
end
|
|
moveTo( info.x, info.y, info.z, 20, 50, 20 );
|
|
l2c_npcDlgClear(); -- î÷èñòèì èíôîðìàöèþ î ïîñëåäíåì îòêðûòîì äèàëîãå ñ ÍÏÖ
|
|
l2c_action( toid ); -- "êëèêíåì" ïî ÍÏÖ
|
|
-- òåïåðü æäåì êîãäà îòêðîåòñÿ äèàëîã (NpcHtmlMessage)
|
|
local st_time = l2h_time(); -- çàïîìíèì âðåìÿ íà÷àëà îæèäàíèÿ
|
|
while true do
|
|
l2h_delay( 50 );
|
|
local ok = l2c_npcDlgExists(); -- ñóùåñòâóåò ëè äèàëîã?)
|
|
if ok then return true end -- äà, îê
|
|
local nowTime = l2h_time(); -- íåò, òîãäà ïðîâåðèì ñêîëüêî âðåìåíè ïðîøëî
|
|
if (nowTime - st_time) > timeoutSecs then
|
|
l2h_print( "NPCDLG: ERROR: timeout waiting for NpcHtmlMessage!\n" );
|
|
return false -- òàéìàóò èñòåê
|
|
end
|
|
end
|
|
end
|
|
|
|
-- âûáèðàåò ñòðî÷êó èç äèàëîãà ñ ÍÏÖ
|
|
-- * talk_delay_ms - ñêîëüêî ìèëëèñåê æäàòü ïîñëå "êëèêà" ïî ññûëêå
|
|
function npcDlgSel( str, talk_delay_ms )
|
|
if talk_delay_ms == nil then talk_delay_ms = 500 end
|
|
l2c_npcDlg( str );
|
|
l2h_delay( talk_delay_ms );
|
|
end
|
|
|
|
-- ôóíêöèÿ çàêî÷èò ðàáîòó êîãäà þçåð çàêîí÷èò êàñò òåêóùåãî ñêèëëà
|
|
-- íè÷åãî íå âîçâðàùàåò
|
|
function waitEndOfCast()
|
|
while l2c_isCastingNow() do l2h_delay( 50 ) end
|
|
end
|
|
|
|
-- èñïîëüçóåò ñêèëë è äåëàåò çàäåðæêó 100ìñ ëÿ óâåðåííîñòè ÷òî êàñò ñêèëëà íà÷àëñÿ
|
|
-- ÷èñòà äëÿ óäîáñòâà. âåëè÷èíà çàäåðæêè çàâèñèò îò ëàãîâ êàíàëà äî ñåðâåðà
|
|
-- íè÷åãî íå âîçâðàùàåò
|
|
function useSkill( skillID, delay_ms )
|
|
if delay_ms == nil then delay_ms = 100 end
|
|
l2c_useSkill( skillID, true );
|
|
l2h_delay( delay_ms )
|
|
end
|
|
|
|
-- âåðíåò true, åñëè áàô skillID ïðèñóòñâóåò â ìàññèâå have_buffs
|
|
function buffIsPresent( skillID, have_buffs )
|
|
if not have_buffs then return false end
|
|
local i
|
|
for i=1, #have_buffs do
|
|
if have_buffs[i].skillID == skillID then return true end
|
|
end
|
|
return false
|
|
end
|
|
|
|
|
|
-- ïðèáëèæàåòñÿ ê ÷àðó ñ íèêîì name êàê ìèíèìóì íà ðàññòîÿíèå distance
|
|
function follow( name, distance )
|
|
-- ïîëó÷èì objectID ÷àðà
|
|
local randomness = 60;
|
|
local objectID = l2c_getCharObjectIdByName( name );
|
|
-- à åñòü ëè òàêîé ÷àð âîîáùå?
|
|
if objectID == nil then
|
|
l2h_print( "FOLLOW: Character [", name, "] is not visible!\n" );
|
|
return
|
|
end
|
|
-- âû÷èñëèì ñëó÷àéíîå îòêëîíåíèå îò öåëè
|
|
if randomness >= distance then randomness = distance/2 end -- îòêëîíåíèå íèêàê íå ìîæåò áûòü áîëüøå ðàññòîÿíèÿ äî öåëè
|
|
local x_rand = math.random( (0-randomness), randomness )
|
|
local y_rand = math.random( (0-randomness), randomness )
|
|
local x, y, z -- íàøè êîîðäèíàòû áóäóò òóò
|
|
local gox, goy, goz -- äâèãàòüñÿ áóäåì òóäà
|
|
local c -- èíôî î ÷àðå (öåëè) áóäåò òóò
|
|
-- à íàäî ëè íàì ñëåäîâàòü âîîáùå?
|
|
x,y,z = l2c_getPos(); -- ïîëó÷èì íàøè êîîðäèíàòû
|
|
c = l2c_getObjectInfoByObjectId( objectID ); -- èíôî î öåëè "ïðåñëåäîâàíèÿ"
|
|
if c == nil then
|
|
l2h_print( "FOLLOW: char [", name, "] suddenly disappeared!\n" );
|
|
return false
|
|
end
|
|
if (c.xDst ~= 0x7FFFFFFF) and (c.yDst ~= 0x7FFFFFFF) then
|
|
gox = c.xDst;
|
|
goy = c.yDst;
|
|
if c.zDst ~= 0x7FFFFFFF then goz = c.zDst else goz = c.z end
|
|
else
|
|
gox = c.x;
|
|
goy = c.y;
|
|
goz = c.z;
|
|
end
|
|
if (math.abs(gox - x) > distance) or (math.abs(goy - y) > distance) then
|
|
l2c_moveTo( gox + x_rand, goy + y_rand, goz ) -- äâèíåìñÿ ê íåìó
|
|
else
|
|
return -- äà ìû è òàê íåäàëåêî îò öåëè
|
|
end
|
|
-- öèêë ñëåäîâàíèÿ
|
|
repeat
|
|
if sys_should_exit() then return end -- þçåð íàæàë "Ñòîï ñêðèïò"
|
|
-- ïîëó÷èì èíôî î ÷àðå
|
|
c = l2c_getObjectInfoByObjectId( objectID )
|
|
--l2h_print( "Following [", name, "] to (", c.x, ",", c.y, ",", c.z, ")\n" )
|
|
if (c.xDst ~= 0x7FFFFFFF) and (c.yDst ~= 0x7FFFFFFF) then
|
|
gox = c.xDst;
|
|
goy = c.yDst;
|
|
if c.zDst ~= 0x7FFFFFFF then goz = c.zDst else goz = c.z end
|
|
else
|
|
gox = c.x;
|
|
goy = c.y;
|
|
goz = c.z;
|
|
end
|
|
l2c_moveTo( gox + x_rand, goy + y_rand, goz ) -- äâèíåìñÿ ê íåìó
|
|
l2h_delay( 300 ); -- ïîäîæäåì 300 ms
|
|
x,y,z = l2c_getPos(); -- ïîëó÷èì ñíîâà íàøè êîîðäèíàòû
|
|
-- ïðîâåðèì ðàçíèöó íàøèõ êîîðäèíàò è êîîðäèíàò ÷àðà.
|
|
-- åñëè ðàçíèöà áîëüøå äèñòàíöèè ñëåäîâàíèÿ, öèêë ñëåäîâàíèÿ ïîâòîðèòñÿ
|
|
until ((math.abs(gox - x) < distance) and (math.abs(goy - y) < distance) and (math.abs(goz - z) < distance))
|
|
end
|