Спасибо, действительно работает. Но все-таки кто-нибудь может зайти и за крипов, а это будет проблема, не всегда же закрывать компьютером слот. Я нашел другое решение.
Ходьба крипов как в Dota Allstars
Доброго времени суток дорогие посетители.
Сегодня я расскажу вам как избежать сложностей с созданием крипов из нейтральных игроков.
Даже самые начитаные мапперы сталкивались с проблемой когда созданный крип не выполнял поставленных
ему действий, а именно:
1. Когда крип доходит до последней точки, он (если еще остался живым) возвращается на то место, где появился.
2. Здания - они атакуют находящегося в зоне действия крипа при этом когда у крипа оказывается уровень жизни на 50%, он убегает.
3. Крипы на пролом проходят мимо оборонительных сооружений, при этом получают урон и получается проблема № 2. Конечно когда они будут возвращатся, тогда их окончательно убьёт оборонительное сооружение.
Давайте разберёмся от чего получаются подобные проблемы.
Наверное все замечали, что если ударить любого крипа (нейтрала, врага) и отбежать, то он будет бежать за вами, но не долго. После он развернётся и пойдёт на исходную позицию. Это так сказать "фишка" близзардов, так сказать что бы крипы не скитались по миру, а были на своём посту, но если мы делаем карту типа Доты, Коридоров то, нам просто необходимо отключить данную способность. За эту способность отвечает одна интересная функция Guard Position, далее рассмотрим ее более подробно.
Для понимания данной функции мы направим крипа в точку обозначая ее Locations записывая в колонку Custom value ID направления к которому должен идти наш крип. Теперь рассмотрим это в действии, так описываем событие Trigger:
Code
call TriggerRegisterPlayerUnitEvent(t,Player(13),EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER,null)
call TriggerRegisterPlayerUnitEvent(t,Player(14),EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER,null)
Условие, здесь опишем что нам нужно от события, а нам нужно передвижение к определенному ID Locations:
Code
return GetIssuedOrderId()==OrderId("move")
Описываем действие (перемещения крипа) события:
Code
function IssOrder takes nothing returns nothing
local unit u = GetTriggerUnit()
call SetUnitPosition(u,GetUnitX(u),GetUnitY(u))
call DisableTrigger(GetTriggeringTrigger())
call IssuePointOrderByIdLoc(u,OrderId("attack"),udg_Locations[GetUnitUserData(u)])
call EnableTrigger(GetTriggeringTrigger())
endfunction
Обратите внимание на скрипт:
Code
call SetUnitPosition(u,GetUnitX(u),GetUnitY(u))
Что же делает этот участок скрипта, спросите вы, а делает он очень не хитрое, но очень нужное действие. Он сбивает точку появления крипа и заменяет ее на ту где он в данный момент. Тоесть он будет следовать совей цели не смотря ни на что. Вот и всё, убили одновременно два зайца, так как проблемы под № 1 и 2 мы только что решили.
Хочу ещё обратить ваше внимание на не менее интересный кусок скрипта:
Code
call IssuePointOrderByIdLoc(u,OrderId("attack"),udg_Locations[GetUnitUserData(u)])
Как видим из написаного, наш крип перемещается с точки "рождения" которая постоянно меняется на ту где он находится по пути атакуя все вражиские цели, за это отвечает функция attack.
У нас осталась проблема под № 3, давайте решим и её.
Исправить данную проблуму можно двумя способами, первый самый простой, но не очень надёжный. Берем направляем нашего крипа в нужную точку с параметром attack. Для примера взгляните на скрипт описанный выше. Это так сказать домашне задание. Теперь давайте рассмотрим самый сложный и в одно время самы надёжный способ решения проблемы с атакой сооружений.
Для этого напишем событие, в котором будем перебирать юнитов и сооружения. Первым делом создаём Trigger и добавим ему следующее событие:
Code
set t = CreateTrigger()
set g = CreateGroup()
call GroupEnumUnitsOfPlayer(g,Player(13),null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g,u)
if GetUnitAcquireRange(u)!=0 and IsUnitType(u,UNIT_TYPE_STRUCTURE) then
call TriggerRegisterUnitInRange(t,u,600,null)
endif
endloop
call DestroyGroup(g)
set g = CreateGroup()
call GroupEnumUnitsOfPlayer(g,Player(14),null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g,u)
if GetUnitAcquireRange(u)!=0 and IsUnitType(u,UNIT_TYPE_STRUCTURE) then
call TriggerRegisterUnitInRange(t,u,600,null)
endif
endloop
call DestroyGroup(g)
Здесь мы указали что крип проходя свой путь (Locations) не только вражеских юнитов, но и сооружения, как это сделано в "Dota Allstars".
Добавим условие нашему Triggers, описанное в решении проблемы № 1 и 2:
Code
call TriggerAddCondition(t,Condition(function IsMobCondition))
call TriggerAddAction(t,function IssOrder)
А наша функция условия, будет таковой:
function IsMobCondition takes nothing returns boolean
return (GetOwningPlayer(GetTriggerUnit())==Player(13)) or (GetOwningPlayer(GetTriggerUnit())==Player(14))
endfunction
Вот и всё, удачного маппинга и до новых встречь!
Источник http://zone-game.info/guard_position.html
Я знаю джасс на самом нубском уровне, ниже некуда. Я понял, что здесь делать, но писать скрипт с нуля не умею, тем более незнаю порядок написания скриптов. Так, что если есть знатоки джасса, пожалуйста объедените это один скрипт.