Гуванч, что непонятного?)
10 секунд висит бафф который позволяет накладывать кровотечение с атак и умений длиной 6 сек, сам спелл упирается либо в мемхак либо наличие триггерных спеллов у данного героя, потому что там не все источники урона от юнита, а с указанием конкретных спеллов
впрочем, если автору нужно было такое простое движение, как скинули выше, то даже на ютубе уже делали подобные вещи, в виде подробного гайда и даже на гуи
у Анашина движение совсем по другому реализовано, покрасивее но механически похоже не подошло автору
Заказчик: Desgul Способность: Рывок урсока Выполнено: Да
инструкция по иморту
копируешь триггер Spell и смотришь на код, там всего 100 строк, а основное, что нужно отредактировать имеет комментарии
ты не просил, но я накинул рандомные эффекты, можешь их удалить, они находятся в функции Move и имеют начало call DestroyEffect( ...
код
library SpellLib
globals
constant hashtable H = InitHashtable( )
private constant integer SpellID = 'A000' // спелл прыжка
private constant integer SpellCD = 'A000' // спелл которому сбросить кд
endglobals
private struct SpellS
unit caster
unit target
real speed
real damage
real range
attacktype AttackType
damagetype DamageType
endstruct
native UnitAlive takes unit id returns boolean
// само движение
private function Move takes nothing returns nothing
local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
local real x = GetUnitX( A.caster )
local real y = GetUnitY( A.caster )
local real x1 = GetUnitX( A.target )
local real y1 = GetUnitY( A.target )
local real d = SquareRoot( ( x - x1 ) * ( x - x1 ) + ( y - y1 ) * ( y - y1 ) )
local integer i
set x = x + A.speed * ( ( x1 - x ) / d )
set y = y + A.speed * ( ( y1 - y ) / d )
call SetUnitX( A.caster, x )
call SetUnitY( A.caster, y )
call IssueImmediateOrder( A.caster, "stop" )
if SquareRoot( ( x - x1 ) * ( x - x1 ) + ( y - y1 ) * ( y - y1 ) ) <= A.range + A.speed or GetUnitTypeId( A.target ) == 0 or not UnitAlive( A.caster ) then
if UnitAlive( A.caster ) and GetRandomInt( 0, 100 ) <= 15 then // восстановить хп юниту с 15% шансом
call SetWidgetLife( A.caster, GetWidgetLife( A.caster ) + GetUnitState( A.caster, UNIT_STATE_MAX_LIFE ) * 0.15 )
call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl", A.caster, "origin" ) )
endif
if GetRandomInt( 0, 100 ) <= 15 then // ресетнуть абилку с 15% шансом
set i = GetUnitAbilityLevel( A.caster, SpellCD )
call UnitRemoveAbility( A.caster, SpellCD )
call UnitAddAbility( A.caster, SpellCD )
call SetUnitAbilityLevel( A.caster, SpellCD, i )
endif
call UnitDamageTarget( A.caster, A.target, A.damage, false, false, A.AttackType, A.DamageType, null )
call DestroyEffect( AddSpecialEffect( "Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl", x1, y1 ) )
call SetUnitPathing( A.caster, true )
call FlushChildHashtable( H, GetHandleId( GetExpiredTimer( ) ) )
call PauseTimer( GetExpiredTimer( ) )
call DestroyTimer( GetExpiredTimer( ) )
set A.caster = null
set A.target = null
call A.destroy( )
endif
endfunction
private function SetAnim takes nothing returns nothing
local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
// выставление анимок кастеру
call SetUnitAnimation( A.caster, "attack slam" )
call QueueUnitAnimation( A.caster, "stand" )
call TimerStart( GetExpiredTimer( ), 0.01, true, function Move ) // периодичность полёта
endfunction
function Spell_Actions takes nothing returns boolean
local timer t
local SpellS A
if GetSpellAbilityId( ) == SpellID then
set t = CreateTimer( )
set A = SpellS.create( )
set A.caster = GetTriggerUnit( ) // тот, кто полетит
set A.target = GetSpellTargetUnit( ) // тот, в кого полетят
set A.range = 100.00 // дистанция столкновения
set A.speed = ( SquareRoot( ( GetUnitX( A.caster ) - GetUnitX( A.target ) ) * ( GetUnitX( A.caster ) - GetUnitX( A.target ) ) + ( GetUnitY( A.caster ) - GetUnitY( A.target ) ) * ( GetUnitY( A.caster ) - GetUnitY( A.target ) ) ) - A.range ) * 0.015 // скорость
set A.damage = GetHeroAgi( A.caster, true ) * ( 2.25 * GetUnitAbilityLevel( A.caster, SpellID ) ) // урон
set A.AttackType = ATTACK_TYPE_NORMAL // тип атаки
set A.DamageType = DAMAGE_TYPE_NORMAL // тип урона
call SetUnitPathing( A.caster, false )
call SaveInteger( H, GetHandleId( t ), 0, A )
call TimerStart( t, 0.00, false, function SetAnim )
set t = null
endif
return false
endfunction
//===========================================================================
function InitTrig_Spell takes nothing returns nothing
local integer index = 0
set gg_trg_Spell = CreateTrigger( )
loop
call TriggerRegisterPlayerUnitEvent( gg_trg_Spell, Player( index ), EVENT_PLAYER_UNIT_SPELL_EFFECT, null )
set index = index + 1
exitwhen index >= 16
endloop
call TriggerAddCondition( gg_trg_Spell, Condition( function Spell_Actions ) )
endfunction
endlibrary
в карте для конкурса Crusader есть светляк ночью, вот его код движения
function Wisp_Actions takes nothing returns nothing
local real x1 = GetUnitX( Wisp )
local real y1 = GetUnitY( Wisp )
local real x = GetUnitX( MainUnit ) + Distance * Cos( CircleA )
local real y = GetUnitY( MainUnit ) + Distance * Sin( CircleA )
local real a = Atan2( y - y1, x - x1 )
local real d = SquareRoot( ( x1 - x ) * ( x1 - x ) + ( y1 - y ) * ( y1 - y ) ) * 0.01
set CircleA = CircleA + 1 * bj_DEGTORAD
call SetUnitX( Wisp, x1 + d * Cos( a ) )
call SetUnitY( Wisp, y1 + d * Sin( a ) )
if WispExplodeB then
call SetUnitFlyHeight( Wisp, GetUnitFlyHeight( MainUnit ) + 90, 0 )
endif
endfunction
ничего сложного, MainUnit вокруг которого движется висп, CircleA, угол для движения в точку вокруг юнита, Distance - расстояние движения от юнита, чтобы постепенно оно влетало в юнита можно просто уменьшать эту дистанцию, но у меня оно было фиксированным
Заказчик: mistwood Способность: Призрачная стена Выполнено: Да
утечек нет, можешь не волноваться, закинул счётчик хэндлов как показатель, он растёт разово только потому что идёт присвоение глобалкам в первый раз, в общем-то, можно не ориентироваться на него
инструкция по импорту
триггер Spell это сам спелл (кэп), там редачить нечего в принципе, только переменная хэш-таблицы (об этом ниже)
триггер SpellCast включает в себя настройки и прочую пургу, ты разберёшься, я везде комменты расставил что можно редачить
триггер OnDamage вызывается после нанесения урона юниту, там ты можешь свои действия пихать, я оставил там пример с созданием эффекта на юните
триггер отделенный комментарием тебе не нужен
если у тебя есть переменная с названием H, то пройдись по коду триггера Spell автозаменой по этой букве, если у тебя уже есть хэш-таблица, то можешь закомментить третью строку и опять же, пройтись автозаменой с указанием своей хэш-таблицы, если всё это делать лень, добавь приставку private, тогда никаких несостыковок не будет, но имей ввиду, макс колво объявлений хэш-таблиц 255 вроде
если что-то не работает или работает не так, как ты хотел, или же нужна помощь с импортом - пиши в лс
код
library SpellLib
globals
constant hashtable H = InitHashtable( )
private constant group TempG = CreateGroup( )
private constant group TempG_1 = CreateGroup( )
private attacktype AttackType = null
private damagetype DamageType = null
private boolexpr TempBoolexpr = null
private real TempReal
endglobals
private struct SpellS
unit caster
real damage
real radius
real damagePeriodic
real time
group g
attacktype AttackType
damagetype DamageType
boolexpr b
endstruct
private function Damage_2 takes nothing returns nothing
set udg_TempUnit = GetEnumUnit( )
if not IsUnitInGroup( udg_TempUnit, TempG_1 ) then
call GroupAddUnit( TempG_1, udg_TempUnit )
call UnitDamageTarget( udg_LastCaster, udg_TempUnit, TempReal, false, false, AttackType, DamageType, null )
call TriggerExecute( gg_trg_OnDamage )
endif
endfunction
private function Damage_1 takes nothing returns nothing
call GroupEnumUnitsInRange( TempG, GetUnitX( GetEnumUnit( ) ), GetUnitY( GetEnumUnit( ) ), TempReal, TempBoolexpr )
call ForGroup( TempG, function Damage_2 )
call GroupClear( TempG )
endfunction
private function Damage takes nothing returns nothing
local timer t = GetExpiredTimer( )
local SpellS A = LoadInteger( H, GetHandleId( t ), 0 )
local unit u
set A.time = A.time - A.damagePeriodic
set AttackType = A.AttackType
set DamageType = A.DamageType
set TempBoolexpr = A.b
set udg_LastCaster = A.caster
set TempReal = A.radius
call ForGroup( A.g, function Damage_1 )
call GroupClear( TempG_1 )
if A.time <= 0.00 then
call FlushChildHashtable( H, GetHandleId( t ) )
call DestroyTimer( t )
loop
set u = FirstOfGroup( A.g )
exitwhen u == null
call KillUnit( u )
call GroupRemoveUnit( A.g, u )
endloop
call DestroyGroup( A.g )
set A.g = null
set A.caster = null
call A.destroy( )
else
call TimerStart( t, A.damagePeriodic, false, function Damage )
endif
set t = null
endfunction
function Spell_Actions takes unit caster, integer id, attacktype at, damagetype dt, real damage, real x, real y, real weight, real radius, real distance, real damagePeriodic, real time, boolexpr blxpr returns nothing
local timer t = CreateTimer( )
local SpellS A = SpellS.create( )
local boolean b = true
local real d = distance / 2
local real a = Atan2( y - GetUnitY( caster ), x - GetUnitX( caster ) )
local real xl = Cos( a + ( 90 * bj_DEGTORAD ) )
local real yl = Sin( a + ( 90 * bj_DEGTORAD ) )
local unit u
set A.damage = damage
set A.caster = caster
set A.radius = radius
set A.time = time
set A.b = blxpr
set A.AttackType = at
set A.DamageType = dt
set A.damagePeriodic = damagePeriodic
set A.g = CreateGroup( )
set weight = weight / 2
set bj_groupEnumOwningPlayer = GetOwningPlayer( A.caster )
loop
if b then
set u = CreateUnit( bj_groupEnumOwningPlayer, id, x + d * xl, y + d * yl, 0.00 )
set b = false
else
set u = CreateUnit( bj_groupEnumOwningPlayer, id, x - d * xl, y - d * yl, 0.00 )
set b = true
set d = d + distance
endif
call GroupAddUnit( A.g, u )
exitwhen d >= weight
endloop
call SaveInteger( H, GetHandleId( t ), 0, A )
call TimerStart( t, 0.00, false, function Damage )
set u = null
set t = null
endfunction
//===========================================================================
function InitTrig_Spell takes nothing returns nothing
//set gg_trg_Spell = CreateTrigger( )
endfunction
endlibrary
VinerX, лол, то есть в моей карте ты эту переменную видишь, она там есть в наличии? В твоей собственной её нет?
если там нельзя её юзать каким-то чудом то придётся учить джасс)
попробуй скопировать триггер и перенести в свою карту, переменная должна скопироваться если есть соответствующая галочка в редакторе, при переносе триггеров копировать переменные
т.к. ты гуишник могу посоветовать в редакторе переменных создать переменную булекспра (она в самом низу списка где-то находится), потом через кастом скрипт call GroupEnumUnitsInRect( udg_Group, bj_mapInitialPlayableArea, udg_Boolexpr ), можешь дальше обращаться к этой группе на гуи, очистив потом
в данном случае оно выбирает всех юнитов на карте, но через условия указанные в твоём булекспре
есть так же
native GroupEnumUnitsOfPlayer takes group whichGroup, player whichPlayer, boolexpr filter returns nothing
это выбор всех юнитов игрока
ну и
native GroupEnumUnitsInRangeOfLoc takes group whichGroup, location whichLocation, real radius, boolexpr filter returns nothing
function GetUnitsInRectMatching takes rect r, boolexpr filter returns group
local group g = CreateGroup()
call GroupEnumUnitsInRect(g, r, filter)
call DestroyBoolExpr(filter)
return g
endfunction
Ред. rsfghd
» WarCraft 3 / Способности и алгоритмы на заказ
» WarCraft 3 / Autumn
Ред. rsfghd
» WarCraft 3 / Способности и алгоритмы на заказ
10 секунд висит бафф который позволяет накладывать кровотечение с атак и умений длиной 6 сек, сам спелл упирается либо в мемхак либо наличие триггерных спеллов у данного героя, потому что там не все источники урона от юнита, а с указанием конкретных спеллов
» WarCraft 3 / CastBar, модель анимация.
» WarCraft 3 / CastBar, модель анимация.
» WarCraft 3 / Пытаюсь создать кастомного героя.
» Модели из World Of WarCraft / Пак декораций наг
» WarCraft 3 / Движение по кругу
» WarCraft 3 / Способности и алгоритмы на заказ
Заклинание готово!
Способность: Рывок урсока
Выполнено: Да
ты не просил, но я накинул рандомные эффекты, можешь их удалить, они находятся в функции Move и имеют начало call DestroyEffect( ...
Ред. rsfghd
» WarCraft 3 / Движение по кругу
Ред. rsfghd
» WarCraft 3 / Движение по кругу
» WarCraft 3 / Способности и алгоритмы на заказ
Заказ принят
Способность: Рывок урсока
Спелл будет завершен к: примерно через час
» WarCraft 3 / Дополнительные ресурсы
» WarCraft 3 / Дополнительные ресурсы
» WarCraft 3 / Дополнительные ресурсы
Ред. rsfghd
» WarCraft 3 / Способности и алгоритмы на заказ
Заклинание готово!
Способность: Призрачная стена
Выполнено: Да
триггер SpellCast включает в себя настройки и прочую пургу, ты разберёшься, я везде комменты расставил что можно редачить
триггер OnDamage вызывается после нанесения урона юниту, там ты можешь свои действия пихать, я оставил там пример с созданием эффекта на юните
триггер отделенный комментарием тебе не нужен
если у тебя есть переменная с названием H, то пройдись по коду триггера Spell автозаменой по этой букве, если у тебя уже есть хэш-таблица, то можешь закомментить третью строку и опять же, пройтись автозаменой с указанием своей хэш-таблицы, если всё это делать лень, добавь приставку private, тогда никаких несостыковок не будет, но имей ввиду, макс колво объявлений хэш-таблиц 255 вроде
если что-то не работает или работает не так, как ты хотел, или же нужна помощь с импортом - пиши в лс
Ред. rsfghd
» WarCraft 3 / Способности и алгоритмы на заказ
Заказ принят
Способность: Призрачная стена
Спелл будет завершен к: без понятия
» WarCraft 3 / Что может вызвать утечки в этой системе инкома?
» WarCraft 3 / Что может вызвать утечки в этой системе инкома?
» WarCraft 3 / Что может вызвать утечки в этой системе инкома?
попробуй скопировать триггер и перенести в свою карту, переменная должна скопироваться если есть соответствующая галочка в редакторе, при переносе триггеров копировать переменные
» WarCraft 3 / Что может вызвать утечки в этой системе инкома?
Ред. rsfghd
» WarCraft 3 / Что может вызвать утечки в этой системе инкома?
» WarCraft 3 / Как запустить один раз стандартный музыкальный трек?
» WarCraft 3 / Что может вызвать утечки в этой системе инкома?
» WarCraft 3 / Система снаряда с настройками