Добавлен Ancient,
опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
Jass
Тип:
Способность
Дело было вечером, делать было нечего
Описание: Юнит бежит определенное расстояние в указанном направлении, расталкивая всех наземных противников на своем пути. Учитываются клиффы и здания, от которых герой отталкивается.
Не действует на союзников. Ломает декорации, не может вылететь за границы карты.
Не действует на союзников. Ломает декорации, не может вылететь за границы карты.
Способность полностью MUI (может использоваться любым количеством игроков и юнитов).
Используемые глобальные переменные: 1 единственная глобалка для хэш-таблицы.
Как импортировать себе:
раскрыть
- Копируем триггеры Charge и ChargeMove
- Копируем способности
- Даем способность "Рывок" своему герою, настраиваем ее как нам нужно
- ???
- PROFIT!
Сам код способности:
раскрыть
globals
// Скорость движения юнита
real CR_Speed = 600.0
// Максимально возможное расстояние движения
real CR_Range_Max = 900.0
// Дальность обнаружения юнитов
real CR_Range_F = 128.0
// Дальность отброса юнитов
real CR_Range_M = 150.0
// Дальность отброса юнитов за 1 тик
real CR_Range_OM = 15.0
// Урон по юнитам, которые будут оттолкнуты
real CR_Damage = 50.0
// Максимальное изменение высоты юнитов, которые будут оттолкнуты
real CR_Height = 125.0
// Скорость проигрования анимации
// сейчас стоит скорость анимации для паладина, подправь на нужную тебе
real CR_Anim_Speed = 0.0766
// индекс для воcпроизведения анимации
integer CR_Anim_Index = 12
// группа для чарджа
group CR_Group = CreateGroup()
// еффект для движения
string CR_Eff_Move = "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageDeathCaster.mdl"
// еффект при ударе в клиф или здание
string CR_Eff_Str = "Abilities\\Spells\\Other\\Volcano\\VolcanoDeath.mdl"
endglobals
function Trig_ChargeMove_Conditions takes nothing returns boolean
local unit u = FirstOfGroup(CR_Group)
if u == null then
return false
else
set u = null
return true
endif
endfunction
function Trig_ChargeMove_Actions takes nothing returns nothing
local group g = CreateGroup()
local integer h
local unit u
local real angle
local real range
local real cur_z
local real start_z
local real x
local real y
local real z
call GroupAddGroup(CR_Group, g)
loop
set u = FirstOfGroup(g)
call GroupRemoveUnit(g, u)
exitwhen u == null
set h = GetHandleId(u)
set angle = LoadReal (udg_Hash, h, StringHash ("angle"))
set range = LoadReal (udg_Hash, h, StringHash ("range"))
set cur_z = LoadReal (udg_Hash, h, StringHash ("cur_z"))
set start_z = LoadReal (udg_Hash, h, StringHash ("start_z"))
if range < CR_Range_M then
set x = GetUnitX(u) + CR_Range_OM * Cos(angle* bj_DEGTORAD)
set y = GetUnitY(u) + CR_Range_OM * Sin(angle* bj_DEGTORAD)
if cur_z < start_z + CR_Height then
set z = cur_z + (CR_Height/10*2)
else
set z = cur_z - (CR_Height/10*2)
endif
call SetUnitPathing(u, false)
call SetUnitX(u, x)
call SetUnitY(u, y)
call SetUnitFlyHeight (u, z, 0.0)
call IssueImmediateOrder(u, "stop")
call DestroyEffect(AddSpecialEffect(CR_Eff_Move, GetUnitX(u), GetUnitY(u)))
call SaveReal (udg_Hash, h, StringHash ("cur_z"), z )
call SaveReal (udg_Hash, h, StringHash ("range"), range + CR_Range_OM)
else
call GroupRemoveUnit(CR_Group, u)
call FlushChildHashtable (udg_Hash, h)
call SetUnitFlyHeight (u, start_z, 0.00)
call SetUnitPathing(u, true)
endif
endloop
call DestroyGroup(g)
set g = null
set u = null
endfunction
//===========================================================================
function InitTrig_ChargeMove takes nothing returns nothing
set gg_trg_ChargeMove = CreateTrigger( )
call TriggerRegisterTimerEvent( gg_trg_ChargeMove, 0.04, true )
call TriggerAddCondition( gg_trg_ChargeMove, Condition( function Trig_ChargeMove_Conditions ) )
call TriggerAddAction( gg_trg_ChargeMove, function Trig_ChargeMove_Actions )
endfunction
function DestroyTrees takes nothing returns nothing
local destructable tree = GetEnumDestructable()
call KillDestructable (tree)
set tree = null
endfunction
function Charge_Timer takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer h = GetHandleId(t)
local unit caster = LoadUnitHandle(udg_Hash, h, StringHash("caster"))
local real anim_time = LoadReal (udg_Hash, h, StringHash("anim_time"))
local real range = LoadReal(udg_Hash, h, StringHash("range"))
local real x
local real y
local real angle
local real rxy
local group g = CreateGroup()
local unit dummy
local location loc
local location loc_cas
local boolean b = false
local integer h_a
if GetUnitState(caster, UNIT_STATE_LIFE) > 0.405 then
if range < CR_Range_Max then
set loc = Location(GetUnitX(caster), GetUnitY(caster))
call EnumDestructablesInCircleBJ(192.0, loc , function DestroyTrees)
call RemoveLocation(loc)
call GroupEnumUnitsInRange(g, GetUnitX(caster), GetUnitY(caster), CR_Range_F, null)
call GroupRemoveUnit(g, caster)
loop
set dummy = FirstOfGroup(g)
call GroupRemoveUnit(g, dummy)
exitwhen dummy == null
if not IsUnitType(dummy, UNIT_TYPE_STRUCTURE) then
if not IsUnitInGroup(dummy, CR_Group) and GetUnitState(dummy, UNIT_STATE_LIFE) > 0.405 and IsUnitEnemy (dummy, GetOwningPlayer(caster)) then
if IsUnitType (dummy, UNIT_TYPE_GROUND) and GetUnitAbilityLevel(dummy, 'Avul') == 0 then
call UnitDamageTarget (caster, dummy, CR_Damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
call UnitAddAbility (dummy, 'Amrf')
call UnitRemoveAbility (dummy, 'Amrf')
set h_a = GetHandleId(dummy)
set angle = bj_RADTODEG * Atan2(GetUnitY(dummy)- GetUnitY(caster), GetUnitX(dummy) - GetUnitX(caster))
call SaveReal(udg_Hash, h_a, StringHash("angle"), angle)
call SaveReal(udg_Hash, h_a, StringHash("range"), 0.0)
set loc = Location (GetUnitX(dummy), GetUnitY(dummy))
call SaveReal(udg_Hash, h_a, StringHash("cur_z"), GetLocationZ(loc) + GetUnitFlyHeight(dummy))
call SaveReal(udg_Hash, h_a, StringHash("start_z"), GetLocationZ(loc) + GetUnitFlyHeight(dummy))
call RemoveLocation(loc)
endif
call GroupAddUnit (CR_Group, dummy)
endif
else
set b = true
endif
endloop
set angle = LoadReal(udg_Hash, h, StringHash("angle"))
call SetUnitFacing(caster, angle)
call SetUnitPathing(caster, false)
set x = GetUnitX(caster) + (CR_Speed * 0.04) * Cos(GetUnitFacing(caster)* bj_DEGTORAD)
set y = GetUnitY(caster) + (CR_Speed * 0.04) * Sin(GetUnitFacing(caster)* bj_DEGTORAD)
set rxy = SquareRoot((GetUnitX(caster) - x) * (GetUnitX(caster) - x) + (GetUnitY(caster) - y) * (GetUnitY(caster) - y) )
set loc = Location(x, y)
set loc_cas = Location(GetUnitX(caster), GetUnitY(caster))
if GetLocationZ(loc) > GetLocationZ(loc_cas) + 15.0 or b or GetUnitX(caster) >= GetRectMaxX(GetPlayableMapRect()) or GetUnitY(caster) >= GetRectMaxY(GetPlayableMapRect()) or GetUnitX(caster) <= GetRectMinX(GetPlayableMapRect()) or GetUnitY(caster) <= GetRectMinY(GetPlayableMapRect())then
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash, h)
set h_a = GetHandleId(caster)
call SaveReal(udg_Hash, h_a, StringHash("angle"), 360.0 - GetUnitFacing(caster))
call SaveReal(udg_Hash, h_a, StringHash("range"), 0.0)
set loc = Location (GetUnitX(caster), GetUnitY(caster))
call SaveReal(udg_Hash, h_a, StringHash("cur_z"), GetLocationZ(loc) + GetUnitFlyHeight(caster) )
call SaveReal(udg_Hash, h_a, StringHash("start_z"), GetLocationZ(loc) + GetUnitFlyHeight(caster))
call GroupAddUnit (CR_Group, caster)
call RemoveLocation(loc)
call SetUnitPathing(caster, true)
call SetUnitAnimation (caster, "stand")
call DestroyEffect(AddSpecialEffect(CR_Eff_Str, GetUnitX(caster), GetUnitY(caster)))
set dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'dum0', GetUnitX(caster), GetUnitY(caster), 0.0)
call UnitAddAbility (dummy, 'Ast0')
call UnitApplyTimedLife (dummy, 'BTFL', 1.0)
call IssueTargetOrder (dummy, "thunderbolt", caster)
call RemoveLocation(loc)
call RemoveLocation(loc_cas)
else
set angle = LoadReal (udg_Hash, h, StringHash("angle"))
call SetUnitX(caster, x)
call SetUnitY(caster, y)
call SetUnitFacing(caster, angle)
call IssueImmediateOrder(caster, "stop")
if anim_time >= CR_Anim_Speed then
set anim_time = 0.0
call SetUnitAnimationByIndex(caster, CR_Anim_Index)
endif
call SaveReal (udg_Hash, h, StringHash("range"), range + rxy)
call SaveReal (udg_Hash, h, StringHash("anim_time"), anim_time + 0.04)
call DestroyEffect(AddSpecialEffect(CR_Eff_Move, GetUnitX(caster), GetUnitY(caster)))
endif
else
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash, h)
call SetUnitPathing(caster, true)
call SetUnitAnimation (caster, "stand")
endif
call TimerStart(t, 0.04, false, function Charge_Timer)
else
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash, h)
call SetUnitPathing(caster, true)
call SetUnitAnimation (caster, "stand")
endif
call DestroyGroup(g)
set t = null
set caster = null
set g = null
set dummy = null
set loc = null
set loc_cas = null
endfunction
function Trig_Charge_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'Acr1'
endfunction
function Trig_Charge_Actions takes nothing returns nothing
local unit caster = GetSpellAbilityUnit()
local timer t = CreateTimer()
local integer h = GetHandleId(t)
// Сохраняем все переменные в хэш таблицу
// наш кастер
call SaveUnitHandle(udg_Hash, h, StringHash("caster"), caster)
// время проигранной нимации
call SaveReal (udg_Hash, h, StringHash("anim_time"), 0.0)
// пройденное расстояние
call SaveReal (udg_Hash, h, StringHash("range"), 0.0)
// сохраняем угол поворота юнита
call SaveReal(udg_Hash, h, StringHash("angle"), GetUnitFacing(caster))
// группа для того что бы не бить одних и тех же юнитов по много раз
call SaveGroupHandle(udg_Hash, h, StringHash("g1"), CreateGroup())
call SetUnitAnimationByIndex (caster, CR_Anim_Index )
call TimerStart(t, 0.04, false, function Charge_Timer)
set t = null
set caster = null
endfunction
//===========================================================================
function InitTrig_Charge takes nothing returns nothing
set gg_trg_Charge = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Charge, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Charge, Condition( function Trig_Charge_Conditions ) )
call TriggerAddAction( gg_trg_Charge, function Trig_Charge_Actions )
endfunction
Скачать: ТЫК
Change logs:
Version 1.1
Пофикшена работа с таймерами
Добавлено более реалистичное движение при ударении об препятствие
Исправлена возможность взаимодействовать с трупами юнитов
Теперь корректно работает с парящими юнитами
Добавлено более реалистичное движение при ударении об препятствие
Исправлена возможность взаимодействовать с трупами юнитов
Теперь корректно работает с парящими юнитами
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Все пофикшу на днях и перезалью сюда.
Отредактирован Ancient