если у тебя сборка предметов не через заряды реализована (что немного кринжом попахивает_), то тебе нужен цикл на целочисленную и проверять 1-6 слоты на наличие предмета
ну типа считаешь расстояние между точкой каста и кастером, и после телепорта наносишь урон кому надо ориентируясь на расстояние, формула процента в единичку: расстояние / макс. расстояние
то есть урон умножаешь на полученный результат
или ты имел ввиду наносить всем кто находится между точкой каста и кастером?
Заказчик: Roy Mustang Способность: Advanced Defend Выполнено: Да
инструкция по импорту
копирнуть папку/триггеры и вставить в свою карту
т.к. я на патче 1.26 у меня нет нужных функций чтобы блочить урон, поэтому юзал NegateDamageLib от Прометея
по коду тебе нужно изменить в триггере DamageEvent несколько переменных
AbilityID - равкод переключаемой абилки, которая должна блочить урон
OrderIDUp - целочисленный приказ каста абилки (поднятия щита)
OrderIDDown - целочисленный приказ каста абилки (опускания щита)
MaxLifeBonusAbility - абилка, дающая хп
MaxLifeBonus - сколько хп даёт абилка выше
если ты умеешь менять урон самостоятельно (т.к. у тебя реф), то можешь избавиться от этой либы и от соответствующих функций в триггере Negate
если у тебя уже есть триггер отвечающий за получение юнитом урона, то возможно тебе понадобится дополнительная помощь с импортом, дабы не засорять лишними событиями игру, это уже по твоему желанию, можешь отписаться в лс
всё в принципе запривачено так что конфликтов быть не должно (искл если у тебя уже есть NegateDamageLib или похожие названия глобалок, в таком случае придётся создавать новые и по коду в DamageEvent_Actions заменить названия переменных на свои
если что-то работает не так, то опять же, пиши, разберёмся
код
library DamageEventLib
globals
private constant group OrderGroup = CreateGroup( )
private constant group TempG = CreateGroup( )
private trigger trg = null
private unit bj_lastFilterUnit = null
// specified
private constant integer AbilityID = 'Adef'
private constant integer OrderIDUp = 852055
private constant integer OrderIDDown = 852056
endglobals
private function DamageEvent_Actions takes nothing returns nothing
local real orientation
local real lenght
local real x
local real y
local real x1
local real y1
if IsUnitInGroup( GetTriggerUnit( ), OrderGroup ) then
set udg_Damaged = GetTriggerUnit( )
set udg_Attacker = GetEventDamageSource( )
set udg_Damage = GetEventDamage( )
set x1 = GetUnitX( udg_Damaged )
set y1 = GetUnitY( udg_Damaged )
set x = GetUnitX( udg_Attacker )
set y = GetUnitY( udg_Attacker )
set orientation = GetUnitFacing( udg_Damaged ) * bj_DEGTORAD
set lenght = SquareRoot( ( x - x1 ) * ( x - x1 ) + ( y - y1 ) * ( y - y1 ) )
set udg_Angle = Acos( Cos( orientation ) * ( x - x1 ) / lenght + Sin( orientation ) * ( y - y1 ) / lenght ) * bj_RADTODEG
call TriggerExecute( gg_trg_Negate )
endif
endfunction
//===========================================================================
private function Order_Actions takes nothing returns nothing
if GetUnitAbilityLevel( GetTriggerUnit( ), AbilityID ) > 0 then
if GetIssuedOrderId( ) == OrderIDUp then
call GroupAddUnit( OrderGroup, GetTriggerUnit( ) )
elseif GetIssuedOrderId( ) == OrderIDDown then
call GroupRemoveUnit( OrderGroup, GetTriggerUnit( ) )
endif
endif
endfunction
private function Death_Actions takes nothing returns nothing
call GroupRemoveUnit( OrderGroup, GetTriggerUnit( ) )
endfunction
//===========================================================================
private function RegistEvent_2 takes nothing returns boolean
set bj_lastFilterUnit = GetTriggerUnit( )
if GetUnitAbilityLevel( bj_lastFilterUnit, 'Aloc' ) == 0 then
call TriggerRegisterUnitEvent( trg, bj_lastFilterUnit, EVENT_UNIT_DAMAGED )
endif
return false
endfunction
private function RegistEvent_1 takes nothing returns boolean
set bj_lastFilterUnit = GetFilterUnit( )
if GetUnitAbilityLevel( bj_lastFilterUnit, 'Aloc' ) == 0 then
call TriggerRegisterUnitEvent( trg, bj_lastFilterUnit, EVENT_UNIT_DAMAGED )
endif
return false
endfunction
private function RegistEvent takes nothing returns nothing
if trg != null then
call DestroyTrigger( trg )
endif
set trg = CreateTrigger( )
call GroupEnumUnitsInRect( TempG, bj_mapInitialPlayableArea, Condition( function RegistEvent_1 ) )
call TriggerAddCondition( trg, Condition( function DamageEvent_Actions ) )
call TimerStart( GetExpiredTimer( ), 600.00, true, function RegistEvent )
endfunction
function InitTrig_DamageEvent takes nothing returns nothing
local region rectRegion = CreateRegion( )
local trigger t
set gg_trg_DamageEvent = CreateTrigger( )
call RegionAddRect( rectRegion, bj_mapInitialPlayableArea )
call TriggerRegisterEnterRegion( gg_trg_DamageEvent, rectRegion, null )
call TriggerAddCondition( gg_trg_DamageEvent, Condition( function RegistEvent_2 ) )
call TimerStart( CreateTimer( ), 0.00, false, function RegistEvent )
set rectRegion = null
set t = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerAddAction( t, function Order_Actions )
set t = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddAction( t, function Death_Actions )
set t = null
endfunction
endlibrary
//===========================================================================
// https://xgm.guru/p/wc3/negate-damage-lib
library NegateDamageLib
globals
private constant group Group = CreateGroup()
private constant timer Timer = CreateTimer()
// MUST BE SPECIFIED
public constant integer MaxLifeBonusAbility = 'A000'
public constant integer MaxLifeBonus = 1000000
endglobals
native UnitAlive takes unit id returns boolean
private function ProcessUnits takes nothing returns nothing
local unit u
local real life2set
loop
set u = FirstOfGroup(Group)
exitwhen u == null
call GroupRemoveUnit(Group, u)
if UnitAlive(u) then
set life2set = GetWidgetLife(u)
call UnitRemoveAbility(u, MaxLifeBonusAbility)
call SetWidgetLife(u, life2set)
else
call UnitRemoveAbility(u, MaxLifeBonusAbility)
endif
endloop
endfunction
function NegateDamage takes unit u, real negated returns nothing
local real life = GetWidgetLife(u)
call GroupAddUnit(Group, u)
call UnitAddAbility(u, MaxLifeBonusAbility)
call SetWidgetLife(u, life + negated)
call TimerStart(Timer, 0., false, function ProcessUnits)
endfunction
function GetUnitMaxHealth takes unit u returns real
return GetUnitState(u, UNIT_STATE_MAX_LIFE) - MaxLifeBonus * GetUnitAbilityLevel(u, MaxLifeBonusAbility)
endfunction
endlibrary
function GetItemBaseIconPathById takes integer iid returns string
return GetItemBaseUIStringParamById( iid, 1, 0x24C )
endfunction
function SetItemBaseIconPathById takes integer iid, string text returns nothing
call SetItemBaseUIStringParamById( iid, 1, 0x24C, text )
endfunction
function GetItemBaseIconPath takes item it returns string
return GetItemBaseIconPathById( GetItemTypeId( it ) )
endfunction
function SetItemBaseIconPath takes item it, string text returns nothing
call SetItemBaseIconPathById( GetItemTypeId( it ), text )
endfunction
"Менять текущую иконку - нельзя, она читается всегда из бд, потому итем нужно будет прятать/пересоздавать и т.д. чтобы вызвать обновление UI структуры."
CountDD = колво спавнящихся цепей, по факту дальность хука, само расстояние между цепями всегда фиксировано (50), больше 100 эту переменную ставить нельзя, либо сам вручную смещай массивы, кол-во таких кастов одновременно ограничено и зависит от этой переменной, в данном случае может быть сразу около 82~ хуков, в общем-то, надеюсь по математике всё норм, и посчитать, чтобы цифра не превышала 8192 ты сможешь
периодичность таймера думаю не требует пояснений
кастер может двигаться, но хук никак не сместится и цель притянет в точку каста, а не к кастеру, то есть тебе нужно тогда юзать паузу на кастера, хук может притянуть летающих и здания, там есть булекспр где выставишь всё что нужно, рядом с ним валяется коммент про радиус хука, сейчас там сотка стоит, вообще лучше переходи на луа или джасс, гуи говнище
» WarCraft 3 / Не запускается 1.26 JNGP и редактор после запуска Reforged
» WarCraft 3 / Кол-во нужных для крафта предметов
» WarCraft 3 / Как нанести урон блинком?(Заклинание)
» WarCraft 3 / Как нанести урон блинком?(Заклинание)
то есть урон умножаешь на полученный результат
» WarCraft 3 / Затемнение определённых областей
» WarCraft 3 / ИИ
» WarCraft 3 / Заставить юнитов игрока компьютера, атаковать самих себя
» Unity / Marcos
играл на минималках, а всё равно падает фпс, эх
но вот результат
» WarCraft 3 / Помощь
» WarCraft 3 / Помощь
» WarCraft 3 / дальность атаки
» WarCraft 3 / Помощь
» WarCraft 3 / Помощь
» Блог им. rsfghd / Спеллпак Повелителя Грома
» WarCraft 3 / Гнездо дракона
» Блог им. rsfghd / Спеллпак Повелителя Грома
Ред. rsfghd
» WarCraft 3 / Способности и алгоритмы на заказ
Заклинание готово!
Способность: Advanced Defend
Выполнено: Да
т.к. я на патче 1.26 у меня нет нужных функций чтобы блочить урон, поэтому юзал NegateDamageLib от Прометея
по коду тебе нужно изменить в триггере DamageEvent несколько переменных
если у тебя уже есть триггер отвечающий за получение юнитом урона, то возможно тебе понадобится дополнительная помощь с импортом, дабы не засорять лишними событиями игру, это уже по твоему желанию, можешь отписаться в лс
всё в принципе запривачено так что конфликтов быть не должно (искл если у тебя уже есть NegateDamageLib или похожие названия глобалок, в таком случае придётся создавать новые и по коду в DamageEvent_Actions заменить названия переменных на свои
если что-то работает не так, то опять же, пиши, разберёмся
Ред. rsfghd
» WarCraft 3 / Способности и алгоритмы на заказ
Заказ принят
Способность: Advanced Defend
Спелл будет завершен к: мб сегодня
Ред. rsfghd
» WarCraft 3 / Способности и алгоритмы на заказ
» WarCraft 3 / Способности и алгоритмы на заказ
» WarCraft 3 / Нестандартная декорация
Ред. rsfghd
» WarCraft 3 / Leoric (Skin Vrykul)
» WarCraft 3 / Замена иконки предмета через memhack
» WarCraft 3 / Как триггерно проигрывать анимацию у кастера при касте спелла.
» WarCraft 3 / Гении GUI нужна ваша помощь
периодичность таймера думаю не требует пояснений