Гайд по написанию скриптов для гомункулусов
-
В блокноте есть мегакрутой конвертер для этих целей, вызывается сочетанием Ctrl+H
-
конвертер в моем понимании подал на вход одно, нажал кнопку, получил на выходе другое, а все остальное - так, полуавтоматика в лучшем случае
-
конвертер в моем понимании подал на вход одно, нажал кнопку, получил на выходе другое, а все остальное - так, полуавтоматика в лучшем случае
-
Для разнообразия решила покачать джобы в московии, а там от скуки решила добавить танкование в мираи.
Идея была следующая: в AI.lua в функции
[code:a03m5yaj]--------------------------------------------------
function OnATTACK_ST()
--------------------------------------------------[/code:a03m5yaj]
вместо
[code:a03m5yaj]DoCombat()[/code:a03m5yaj]
вставляем:
[code:a03m5yaj] if ((EnemyTarget ~= MyID) or (HTact.Behav ~= BEHA_tank)) then
DoCombat()
end[/code:a03m5yaj]И вносим соответствующее поведение в GetEnemyNoKS или как её. У меня не в неё, а в функции, которые она использует.
Естественно, в const.lua следует добавить
[code:a03m5yaj]BEHA_tank = 15 -- Tank mob[/code:a03m5yaj]Возникло два вопроса.
- Почему-то иногда, когда хозяин начинает бить моба, лифка всё же присоединяется. Довольно часто (на леших реже, на лесавках чаще), но не всегда. Не очень понимаю. Дело не в участке "помогать хозяину" - во-первых, там есть проверка на "другого врага", во-вторых, чтобы не сомневаться, я отключала этот участок... и больше, вроде как, DoCombat() не вызывается ниоткуда вообще.
- Может мне кто-нибудь кинуть оригинальный код GetEnemyNoKS, чтобы я могла сгенерировать соответствующую правку для не-модифицированной мирки? Если кому-нибудь нужно, конечно ^^''
upd: (1) поняла - похоже, дело в том, что даже неагрессивные мобы могут переключать цель время от времени. Меня лесавка сейчас куснула, на лифку заагренная. Сейчас посмотрю, как это будет действовать, если не руками бить, а кастами.
upd2: Вроде бы, пока моб не переагривается, всё нормально. Подпись, печать ><
-
Для разнообразия решила покачать джобы в московии, а там от скуки решила добавить танкование в мираи.
Идея была следующая: в AI.lua в функции
[code:a03m5yaj]--------------------------------------------------
function OnATTACK_ST()
--------------------------------------------------[/code:a03m5yaj]
вместо
[code:a03m5yaj]DoCombat()[/code:a03m5yaj]
вставляем:
[code:a03m5yaj] if ((EnemyTarget ~= MyID) or (HTact.Behav ~= BEHA_tank)) then
DoCombat()
end[/code:a03m5yaj]И вносим соответствующее поведение в GetEnemyNoKS или как её. У меня не в неё, а в функции, которые она использует.
Естественно, в const.lua следует добавить
[code:a03m5yaj]BEHA_tank = 15 -- Tank mob[/code:a03m5yaj]Возникло два вопроса.
- Почему-то иногда, когда хозяин начинает бить моба, лифка всё же присоединяется. Довольно часто (на леших реже, на лесавках чаще), но не всегда. Не очень понимаю. Дело не в участке "помогать хозяину" - во-первых, там есть проверка на "другого врага", во-вторых, чтобы не сомневаться, я отключала этот участок... и больше, вроде как, DoCombat() не вызывается ниоткуда вообще.
- Может мне кто-нибудь кинуть оригинальный код GetEnemyNoKS, чтобы я могла сгенерировать соответствующую правку для не-модифицированной мирки? Если кому-нибудь нужно, конечно ^^''
upd: (1) поняла - похоже, дело в том, что даже неагрессивные мобы могут переключать цель время от времени. Меня лесавка сейчас куснула, на лифку заагренная. Сейчас посмотрю, как это будет действовать, если не руками бить, а кастами.
upd2: Вроде бы, пока моб не переагривается, всё нормально. Подпись, печать ><
-
Как вариант - раз в сколько-то времени поддерживать агро на хомяке, пиная моба.
-
Как вариант - раз в сколько-то времени поддерживать агро на хомяке, пиная моба.
-
Loneliness, эта функция?
! [code:1v9tylrq]--------------------------------------------------
! function GetMyEnemy_AnyNoKS(myid)
! --------------------------------------------------
! -- Log(string.format("---- AGGRESSIVE SCAN STARTED for ID (%d)", myid))
! local result = 0
! local actors = GetActors ()
! local players = {}
! local player_idx = 1
! local enemy_1st = {} -- primary targets
! local index_1st = 1
! local enemy_std = {} -- normal targets
! local index_std = 1
! local enemy_lss = {} -- last targets
! local index_lss = 1
! local mob_type, mob_target, mobBehav, ListedType
! local EnemyMaxHP
! local HomunMaxHP = GetV(V_MAXHP, MyID)
!
! for i,v in ipairs(actors) do -- fill the (not "friend") player list
! if (v ~= OwnerID and v ~= MyID) then
! if (0 == IsMonster(v)) then
! if isNotFriend(v) then
! players[player_idx] = v
! player_idx = player_idx + 1
! end
! end
! end
! end
!
! for i,v in ipairs(actors) do
! if (v ~= OwnerID) and (v ~= MyID) then -- owner and homunculus aren't valid target, of course
! if (IsMonster(v) == 1) and (BlockedPathToEnemyID ~= v) then -- if target is a (reachable) monster
!
! local isOKToAttack = false
! mob_type = GetV(V_HOMUNTYPE, v) -- get tact data
! mobBehav = GetTact(V_TACTBEHAV, mob_type)
! if( (mobBehav == BEHA_attack_1st)
! or (mobBehav == BEHA_attack)
! or (mobBehav == BEHA_attack_last)
! or (mobBehav == BEHA_attack_weak)
! ) then -- OK, this a type of monster to attack
! if isMobMotionOK(v, players) then
! mob_target = GetV(V_TARGET, v) -- check for the monster's target
! if (mob_target == 0) then -- if the monster is not in battle
! isOKToAttack = true -- he/she can be attacked, unless...
! for i2,v2 in ipairs(players) do
! if (v == GetV(V_TARGET, v2)) then
! isOKToAttack = false -- ...another player is already aiming at him/her (anti-KS)
! break
! end
! end
! else -- else, if the monster is already in battle
! if (mob_target == MyID)
! or (mob_target == OwnerID)
! or (not isNotFriend(mob_target))
! or IsMonster2(mob_target) then
! isOKToAttack = true -- but with me/my owner/a friend, it's OK (anti-KS)
! end
! end
! end
! end
!
! if isOKToAttack then
! if (mobBehav == BEHA_attack_1st) then
! enemy_1st[index_1st] = v
! index_1st = index_1st + 1
! -- Log(string.format(" added to (1st) as enemyID %d", v))
! elseif (mobBehav == BEHA_attack) then
! enemy_std[index_std] = v
! index_std = index_std + 1
! -- Log(string.format(" added to (std) as enemyID %d", v))
! else -- BEHA_attack_last, BEHA_attack_weak
! enemy_lss[index_lss] = v
! index_lss = index_lss + 1
! -- Log(string.format(" added to (lss) as enemyID %d", v))
! end
! end
!
! end
! end
! end
!
! -- Searches for nearest target ---------------
! result = GetClosest(enemy_1st)
! if (result == 0) then
! -- Log("No primary target in range")
! result = GetClosest(enemy_std)
! end
! if (result == 0) then
! -- Log("No standard target in range")
! result = GetClosest(enemy_lss)
! end
! if (result == 0) then
! -- Log("No target in range")
! else
! Log(string.format("<aggressive scan> Target found (ID %d):", result))
! HTact = GetFullTact(GetV(V_HOMUNTYPE, result))
! end
!
! BlockedPathToEnemyID = 0
! -- Log("---- END OF AGGRESSIVE SCAN")
! return result
! end
! [/code:1v9tylrq] -
Loneliness, эта функция?
! [code:1v9tylrq]--------------------------------------------------
! function GetMyEnemy_AnyNoKS(myid)
! --------------------------------------------------
! -- Log(string.format("---- AGGRESSIVE SCAN STARTED for ID (%d)", myid))
! local result = 0
! local actors = GetActors ()
! local players = {}
! local player_idx = 1
! local enemy_1st = {} -- primary targets
! local index_1st = 1
! local enemy_std = {} -- normal targets
! local index_std = 1
! local enemy_lss = {} -- last targets
! local index_lss = 1
! local mob_type, mob_target, mobBehav, ListedType
! local EnemyMaxHP
! local HomunMaxHP = GetV(V_MAXHP, MyID)
!
! for i,v in ipairs(actors) do -- fill the (not "friend") player list
! if (v ~= OwnerID and v ~= MyID) then
! if (0 == IsMonster(v)) then
! if isNotFriend(v) then
! players[player_idx] = v
! player_idx = player_idx + 1
! end
! end
! end
! end
!
! for i,v in ipairs(actors) do
! if (v ~= OwnerID) and (v ~= MyID) then -- owner and homunculus aren't valid target, of course
! if (IsMonster(v) == 1) and (BlockedPathToEnemyID ~= v) then -- if target is a (reachable) monster
!
! local isOKToAttack = false
! mob_type = GetV(V_HOMUNTYPE, v) -- get tact data
! mobBehav = GetTact(V_TACTBEHAV, mob_type)
! if( (mobBehav == BEHA_attack_1st)
! or (mobBehav == BEHA_attack)
! or (mobBehav == BEHA_attack_last)
! or (mobBehav == BEHA_attack_weak)
! ) then -- OK, this a type of monster to attack
! if isMobMotionOK(v, players) then
! mob_target = GetV(V_TARGET, v) -- check for the monster's target
! if (mob_target == 0) then -- if the monster is not in battle
! isOKToAttack = true -- he/she can be attacked, unless...
! for i2,v2 in ipairs(players) do
! if (v == GetV(V_TARGET, v2)) then
! isOKToAttack = false -- ...another player is already aiming at him/her (anti-KS)
! break
! end
! end
! else -- else, if the monster is already in battle
! if (mob_target == MyID)
! or (mob_target == OwnerID)
! or (not isNotFriend(mob_target))
! or IsMonster2(mob_target) then
! isOKToAttack = true -- but with me/my owner/a friend, it's OK (anti-KS)
! end
! end
! end
! end
!
! if isOKToAttack then
! if (mobBehav == BEHA_attack_1st) then
! enemy_1st[index_1st] = v
! index_1st = index_1st + 1
! -- Log(string.format(" added to (1st) as enemyID %d", v))
! elseif (mobBehav == BEHA_attack) then
! enemy_std[index_std] = v
! index_std = index_std + 1
! -- Log(string.format(" added to (std) as enemyID %d", v))
! else -- BEHA_attack_last, BEHA_attack_weak
! enemy_lss[index_lss] = v
! index_lss = index_lss + 1
! -- Log(string.format(" added to (lss) as enemyID %d", v))
! end
! end
!
! end
! end
! end
!
! -- Searches for nearest target ---------------
! result = GetClosest(enemy_1st)
! if (result == 0) then
! -- Log("No primary target in range")
! result = GetClosest(enemy_std)
! end
! if (result == 0) then
! -- Log("No standard target in range")
! result = GetClosest(enemy_lss)
! end
! if (result == 0) then
! -- Log("No target in range")
! else
! Log(string.format("<aggressive scan> Target found (ID %d):", result))
! HTact = GetFullTact(GetV(V_HOMUNTYPE, result))
! end
!
! BlockedPathToEnemyID = 0
! -- Log("---- END OF AGGRESSIVE SCAN")
! return result
! end
! [/code:1v9tylrq] -
Да, эта, спасибо ^^ У меня она просто переписана для возможности выставления численных приоритетов и для ограничения минимальных хп/сп по мобам.
Как-то так должно быть. Не проверяла, но правка достаточно очевидна. Тут мобы для танкования считаются наиболее приоритетными наравне с attack_1st.
! [code:vrf7va6g]--------------------------------------------------
! function GetMyEnemy_AnyNoKS(myid)
! --------------------------------------------------
! -- Log(string.format("---- AGGRESSIVE SCAN STARTED for ID (%d)", myid))
! local result = 0
! local actors = GetActors ()
! local players = {}
! local player_idx = 1
! local enemy_1st = {} -- primary targets
! local index_1st = 1
! local enemy_std = {} -- normal targets
! local index_std = 1
! local enemy_lss = {} -- last targets
! local index_lss = 1
! local mob_type, mob_target, mobBehav, ListedType
! local EnemyMaxHP
! local HomunMaxHP = GetV(V_MAXHP, MyID)
!
! for i,v in ipairs(actors) do -- fill the (not "friend") player list
! if (v ~= OwnerID and v ~= MyID) then
! if (0 == IsMonster(v)) then
! if isNotFriend(v) then
! players[player_idx] = v
! player_idx = player_idx + 1
! end
! end
! end
! end
!
! for i,v in ipairs(actors) do
! if (v ~= OwnerID) and (v ~= MyID) then -- owner and homunculus aren't valid target, of course
! if (IsMonster(v) == 1) and (BlockedPathToEnemyID ~= v) then -- if target is a (reachable) monster
!
! local isOKToAttack = false
! mob_type = GetV(V_HOMUNTYPE, v) -- get tact data
! mobBehav = GetTact(V_TACTBEHAV, mob_type)
! if( (mobBehav == BEHA_attack_1st)
! or (mobBehav == BEHA_attack)
! or (mobBehav == BEHA_attack_last)
! or (mobBehav == BEHA_attack_weak)
! or (mobBehav == BEHA_tank)
! ) then -- OK, this a type of monster to attack
! if isMobMotionOK(v, players) then
! mob_target = GetV(V_TARGET, v) -- check for the monster's target
! if (mob_target == 0) then -- if the monster is not in battle
! isOKToAttack = true -- he/she can be attacked, unless...
! for i2,v2 in ipairs(players) do
! if (v == GetV(V_TARGET, v2)) then
! isOKToAttack = false -- ...another player is already aiming at him/her (anti-KS)
! break
! end
! end
! else -- else, if the monster is already in battle
! if (mob_target == MyID)
! or (mob_target == OwnerID)
! or (not isNotFriend(mob_target))
! or IsMonster2(mob_target) then
! isOKToAttack = true -- but with me/my owner/a friend, it's OK (anti-KS)
! end
! end
! end
! end
!
! if isOKToAttack then
! if ((mobBehav == BEHA_attack_1st) or (mobBehav == BEHA_tank)) then
! enemy_1st[index_1st] = v
! index_1st = index_1st + 1
! -- Log(string.format(" added to (1st) as enemyID %d", v))
! elseif (mobBehav == BEHA_attack) then
! enemy_std[index_std] = v
! index_std = index_std + 1
! -- Log(string.format(" added to (std) as enemyID %d", v))
! else -- BEHA_attack_last, BEHA_attack_weak
! enemy_lss[index_lss] = v
! index_lss = index_lss + 1
! -- Log(string.format(" added to (lss) as enemyID %d", v))
! end
! end
!
! end
! end
! end
!
! -- Searches for nearest target ---------------
! result = GetClosest(enemy_1st)
! if (result == 0) then
! -- Log("No primary target in range")
! result = GetClosest(enemy_std)
! end
! if (result == 0) then
! -- Log("No standard target in range")
! result = GetClosest(enemy_lss)
! end
! if (result == 0) then
! -- Log("No target in range")
! else
! Log(string.format("<aggressive scan> Target found (ID %d):", result))
! HTact = GetFullTact(GetV(V_HOMUNTYPE, result))
! end
!
! BlockedPathToEnemyID = 0
! -- Log("---- END OF AGGRESSIVE SCAN")
! return result
! end[/code:vrf7va6g]upd: Aiko Star, несложно, но смысла не вижу. Мне это нужно в основном, чтобы лифка добавляла 25% и не била моба дальше. Лешие и так не переагриваются, а лесавки очень быстро умирают (и у меня таки 194 фли). Ну, и на касты с расстояния лесавки тоже не идут (а если пойдут, то хом сразу начнёт их кусать), поэтому хрупкие интовые химы, по идее, тоже в безопасности.
Но если что, выглядеть это будет примерно так:
[code:vrf7va6g] if ( (EnemyTarget ~= MyID) or (HTact.Behav ~= BEHA_tank) or ((GetTick() - AgrPrevention_Last) > AgrPrevention_Delay ) then
DoCombat()
AgrPrevention_Last = GetTick()
end[/code:vrf7va6g]И где-нибудь в конфиг.луа объявить, соответственно,
AgrPrevention_Last = 0
AgrPrevention_Delay = 5000
(последнее - задержка между попинываниями в миллисекундах) -
Да, эта, спасибо ^^ У меня она просто переписана для возможности выставления численных приоритетов и для ограничения минимальных хп/сп по мобам.
Как-то так должно быть. Не проверяла, но правка достаточно очевидна. Тут мобы для танкования считаются наиболее приоритетными наравне с attack_1st.
! [code:vrf7va6g]--------------------------------------------------
! function GetMyEnemy_AnyNoKS(myid)
! --------------------------------------------------
! -- Log(string.format("---- AGGRESSIVE SCAN STARTED for ID (%d)", myid))
! local result = 0
! local actors = GetActors ()
! local players = {}
! local player_idx = 1
! local enemy_1st = {} -- primary targets
! local index_1st = 1
! local enemy_std = {} -- normal targets
! local index_std = 1
! local enemy_lss = {} -- last targets
! local index_lss = 1
! local mob_type, mob_target, mobBehav, ListedType
! local EnemyMaxHP
! local HomunMaxHP = GetV(V_MAXHP, MyID)
!
! for i,v in ipairs(actors) do -- fill the (not "friend") player list
! if (v ~= OwnerID and v ~= MyID) then
! if (0 == IsMonster(v)) then
! if isNotFriend(v) then
! players[player_idx] = v
! player_idx = player_idx + 1
! end
! end
! end
! end
!
! for i,v in ipairs(actors) do
! if (v ~= OwnerID) and (v ~= MyID) then -- owner and homunculus aren't valid target, of course
! if (IsMonster(v) == 1) and (BlockedPathToEnemyID ~= v) then -- if target is a (reachable) monster
!
! local isOKToAttack = false
! mob_type = GetV(V_HOMUNTYPE, v) -- get tact data
! mobBehav = GetTact(V_TACTBEHAV, mob_type)
! if( (mobBehav == BEHA_attack_1st)
! or (mobBehav == BEHA_attack)
! or (mobBehav == BEHA_attack_last)
! or (mobBehav == BEHA_attack_weak)
! or (mobBehav == BEHA_tank)
! ) then -- OK, this a type of monster to attack
! if isMobMotionOK(v, players) then
! mob_target = GetV(V_TARGET, v) -- check for the monster's target
! if (mob_target == 0) then -- if the monster is not in battle
! isOKToAttack = true -- he/she can be attacked, unless...
! for i2,v2 in ipairs(players) do
! if (v == GetV(V_TARGET, v2)) then
! isOKToAttack = false -- ...another player is already aiming at him/her (anti-KS)
! break
! end
! end
! else -- else, if the monster is already in battle
! if (mob_target == MyID)
! or (mob_target == OwnerID)
! or (not isNotFriend(mob_target))
! or IsMonster2(mob_target) then
! isOKToAttack = true -- but with me/my owner/a friend, it's OK (anti-KS)
! end
! end
! end
! end
!
! if isOKToAttack then
! if ((mobBehav == BEHA_attack_1st) or (mobBehav == BEHA_tank)) then
! enemy_1st[index_1st] = v
! index_1st = index_1st + 1
! -- Log(string.format(" added to (1st) as enemyID %d", v))
! elseif (mobBehav == BEHA_attack) then
! enemy_std[index_std] = v
! index_std = index_std + 1
! -- Log(string.format(" added to (std) as enemyID %d", v))
! else -- BEHA_attack_last, BEHA_attack_weak
! enemy_lss[index_lss] = v
! index_lss = index_lss + 1
! -- Log(string.format(" added to (lss) as enemyID %d", v))
! end
! end
!
! end
! end
! end
!
! -- Searches for nearest target ---------------
! result = GetClosest(enemy_1st)
! if (result == 0) then
! -- Log("No primary target in range")
! result = GetClosest(enemy_std)
! end
! if (result == 0) then
! -- Log("No standard target in range")
! result = GetClosest(enemy_lss)
! end
! if (result == 0) then
! -- Log("No target in range")
! else
! Log(string.format("<aggressive scan> Target found (ID %d):", result))
! HTact = GetFullTact(GetV(V_HOMUNTYPE, result))
! end
!
! BlockedPathToEnemyID = 0
! -- Log("---- END OF AGGRESSIVE SCAN")
! return result
! end[/code:vrf7va6g]upd: Aiko Star, несложно, но смысла не вижу. Мне это нужно в основном, чтобы лифка добавляла 25% и не била моба дальше. Лешие и так не переагриваются, а лесавки очень быстро умирают (и у меня таки 194 фли). Ну, и на касты с расстояния лесавки тоже не идут (а если пойдут, то хом сразу начнёт их кусать), поэтому хрупкие интовые химы, по идее, тоже в безопасности.
Но если что, выглядеть это будет примерно так:
[code:vrf7va6g] if ( (EnemyTarget ~= MyID) or (HTact.Behav ~= BEHA_tank) or ((GetTick() - AgrPrevention_Last) > AgrPrevention_Delay ) then
DoCombat()
AgrPrevention_Last = GetTick()
end[/code:vrf7va6g]И где-нибудь в конфиг.луа объявить, соответственно,
AgrPrevention_Last = 0
AgrPrevention_Delay = 5000
(последнее - задержка между попинываниями в миллисекундах) -
Обратный вопорос, как в Azzy сделать, чтобы мерк ждал смерти моба, но сам не бил его при этом?
1lvl арч в мск всё-равно дохнет от мантисов даже если прикрывать его забеганием химика и приоритетом атаки гома, а вот копейщик - держит и хп реген у него поприличнее ,да вот только подходит к лесавкам вплотную и они на него переагриваются.
Подозреваю что через сочетание TACT_REACT + KITE_ALWAYS, но KITE вообще не пашет почему-то. -
Обратный вопорос, как в Azzy сделать, чтобы мерк ждал смерти моба, но сам не бил его при этом?
1lvl арч в мск всё-равно дохнет от мантисов даже если прикрывать его забеганием химика и приоритетом атаки гома, а вот копейщик - держит и хп реген у него поприличнее ,да вот только подходит к лесавкам вплотную и они на него переагриваются.
Подозреваю что через сочетание TACT_REACT + KITE_ALWAYS, но KITE вообще не пашет почему-то. -
предположение Очень грубая правка - тупо прибить в скрипте то место, где мерку отдаётся команда "ударить"? Тогда мерк будет, так сказать, думать, что бьёт гомункула (и все остальные мозги ему поэтому заведомо не перекосит), но бить не будет...
Так-то в Аззи не разбиралась, совсем ><
-
предположение Очень грубая правка - тупо прибить в скрипте то место, где мерку отдаётся команда "ударить"? Тогда мерк будет, так сказать, думать, что бьёт гомункула (и все остальные мозги ему поэтому заведомо не перекосит), но бить не будет...
Так-то в Аззи не разбиралась, совсем ><
-
Всё проще оказалось:
В M_Config.lua
SuperPassive =1Соответственно для мск берём спира - он толще.
-
Всё проще оказалось:
В M_Config.lua
SuperPassive =1Соответственно для мск берём спира - он толще.
-
взял 99, осталось джоба 2)
не знаю куда пихнуть но всёже. поюзал ёки ии(yokiai)
настроил на танкование гома на хаях(все на танкование цели выставлены.) норм, но постояно вылетает ошибка.
http://cs9777.vkontakte.ru/u7332929/13645618/x_d71124fd.jpg
вылетает в таком случае - гом танкует одного моба, а я бью другого. что делать? отказатьсяо т идеи танкования гома в принципе?
пысы - оффтоп - куда можно кроме од пойти автокастеру качать джоб?) -
взял 99, осталось джоба 2)
не знаю куда пихнуть но всёже. поюзал ёки ии(yokiai)
настроил на танкование гома на хаях(все на танкование цели выставлены.) норм, но постояно вылетает ошибка.
http://cs9777.vkontakte.ru/u7332929/13645618/x_d71124fd.jpg
вылетает в таком случае - гом танкует одного моба, а я бью другого. что делать? отказатьсяо т идеи танкования гома в принципе?
пысы - оффтоп - куда можно кроме од пойти автокастеру качать джоб?) -
@ГеоПак:
вылетает в таком случае - гом танкует одного моба, а я бью другого. что делать? отказатьсяо т идеи танкования гома в принципе?Исправить ошибку в ИИ или воспользоваться другим.
Если выложите куда-нибудь ИИ именно в том виде, в котром оно у вас, - можно поковырять общими силами.@ГеоПак:
пысы - оффтоп - куда можно кроме од пойти автокастеру качать джоб?)Хилл винды.
Если не боитесь небольшого экстрима - кнокеры. Хотя по их мдефу...