32

» WarCraft 3 / Волна силы не пашет vJass

Как то много кода для такой примитивной абилки...
Пример кода:

function Group_Frost_Wave_Actions takes nothing returns nothing
    local DamageData dd = bj_forLoopAIndexEnd
    local unit Enemy = GetEnumUnit( )

    call GroupAddUnit( dd.grp, Enemy )
    
    set bj_lastCreatedUnit = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'hatk', GetUnitX( Enemy ), GetUnitY( Enemy ), GetUnitFacing( Enemy ) )
    call SetUnitPathing( bj_lastCreatedUnit, false )
    call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 0.50 )
    call UnitAddAbility( bj_lastCreatedUnit, 'A06Z' )
    call SetUnitAbilityLevel( bj_lastCreatedUnit, 'A06Z', dd.id )
    call SetUnitX( bj_lastCreatedUnit, GetUnitX( Enemy ) )
    call SetUnitY( bj_lastCreatedUnit, GetUnitY( Enemy ) )
    
    if IssueTargetOrderById( bj_lastCreatedUnit, 852243, Enemy ) then
        call UnitDamageTarget( dd.attacker, Enemy, dd.dmg, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD, WEAPON_TYPE_WHOKNOWS )
        call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl", Enemy, "origin" ) )
    endif
   
    set bj_lastCreatedUnit = null
    
    set Enemy = null
endfunction

function Timer_Frost_Wave_Expires takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local DamageData dd = GetDataBX( t )
    
    set dd.time = dd.time + 1
    
    if dd.time > 25 then //25 * 32 = 800
    
        call DestroyEffect( dd.fx )
        call KillUnit( dd.attacked )
        
        call GroupClear( dd.grp )
        call ReleaseGroup( dd.grp )
        
        call PauseTimer( t )
        call RemoveDataBX( t )
        call DestroyTimer( t )
        call dd.clear( )
        call dd.destroy( )
    else
    
        set dd.rx = dd.rx + 32.00 * Cos( dd.hp )
        set dd.ry = dd.ry + 32.00 * Sin( dd.hp )

        call SetUnitX( dd.attacked, CheckX( dd.rx ) )
        call SetUnitY( dd.attacked, CheckY( dd.ry ) )
    
        call GroupClear( gg_grp_TempGroup )
    
        set bj_groupEnumOwningPlayer = dd.pl
        set bj_forLoopAIndexEnd = dd
        set bj_lastReplacedUnit = dd.attacker
    
        call GroupEnumUnitsInRange( gg_grp_TempGroup, dd.rx, dd.ry, 128.00 + 4.00 * dd.time, OnlyWavedEnemy )
        call ForGroup( gg_grp_TempGroup, function Group_Frost_Wave_Actions )
    
        set bj_lastReplacedUnit = null
    endif

    set t = null
endfunction

//===========================================================================
function startTrig_Frost_Wave takes nothing returns nothing
    local timer t = CreateTimer( )
    local DamageData dd = DamageData.create( )
    
    set dd.attacker = GetSpellAbilityUnit( )
    set dd.id = GetUnitAbilityLevel( dd.attacker, 'A060' )
    set dd.dmg = dd.id * 125.00
    set dd.pl = GetOwningPlayer( dd.attacker )
    set dd.hp =  Atan2( GetSpellTargetY( ) - GetUnitY( dd.attacker ), GetSpellTargetX( ) - GetUnitX( dd.attacker ) )
    set dd.rx = GetUnitX( dd.attacker ) + 32.00 * Cos( dd.hp )
    set dd.ry = GetUnitY( dd.attacker ) + 32.00 * Sin( dd.hp )
    set dd.attacked = CreateUnit( dd.pl, 'hdum', dd.rx, dd.ry, bj_RADTODEG * dd.hp )
    set dd.fx = AddSpecialEffectTarget( "Abilities\\Spells\\Other\\WindWave\\PrismaticWave.mdx", dd.attacked, "origin" )
    set dd.grp = NewGroup( )
    set dd.time = 0

    call SetDataBX( t, dd )
    
    call SetUnitFlyHeight( dd.attacked, 0.00, 0.00 )
    call SetUnitScale( dd.attacked, 1.25, 1.25, 1.25 )
   
    call TimerStart( t, 0.03125, true, function Timer_Frost_Wave_Expires )
    
    set t = null
endfunctionfunction Group_Frost_Wave_Actions takes nothing returns nothing
    local DamageData dd = bj_forLoopAIndexEnd
    local unit Enemy = GetEnumUnit( )

    call GroupAddUnit( dd.grp, Enemy )
    
    set bj_lastCreatedUnit = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'hatk', GetUnitX( Enemy ), GetUnitY( Enemy ), GetUnitFacing( Enemy ) )
    call SetUnitPathing( bj_lastCreatedUnit, false )
    call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 0.50 )
    call UnitAddAbility( bj_lastCreatedUnit, 'A06Z' )
    call SetUnitAbilityLevel( bj_lastCreatedUnit, 'A06Z', dd.id )
    call SetUnitX( bj_lastCreatedUnit, GetUnitX( Enemy ) )
    call SetUnitY( bj_lastCreatedUnit, GetUnitY( Enemy ) )
    
    if IssueTargetOrderById( bj_lastCreatedUnit, 852243, Enemy ) then
        call UnitDamageTarget( dd.attacker, Enemy, dd.dmg, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD, WEAPON_TYPE_WHOKNOWS )
        call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl", Enemy, "origin" ) )
    endif
   
    set bj_lastCreatedUnit = null
    
    set Enemy = null
endfunction

function Timer_Frost_Wave_Expires takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local DamageData dd = GetDataBX( t )
    
    set dd.time = dd.time + 1
    
    if dd.time > 25 then //25 * 32 = 800
    
        call DestroyEffect( dd.fx )
        call KillUnit( dd.attacked )
        
        call GroupClear( dd.grp )
        call ReleaseGroup( dd.grp )
        
        call PauseTimer( t )
        call RemoveDataBX( t )
        call DestroyTimer( t )
        call dd.clear( )
        call dd.destroy( )
    else
    
        set dd.rx = dd.rx + 32.00 * Cos( dd.hp )
        set dd.ry = dd.ry + 32.00 * Sin( dd.hp )

        call SetUnitX( dd.attacked, CheckX( dd.rx ) )
        call SetUnitY( dd.attacked, CheckY( dd.ry ) )
    
        call GroupClear( gg_grp_TempGroup )
    
        set bj_groupEnumOwningPlayer = dd.pl
        set bj_forLoopAIndexEnd = dd
        set bj_lastReplacedUnit = dd.attacker
    
        call GroupEnumUnitsInRange( gg_grp_TempGroup, dd.rx, dd.ry, 128.00 + 4.00 * dd.time, OnlyWavedEnemy )
        call ForGroup( gg_grp_TempGroup, function Group_Frost_Wave_Actions )
    
        set bj_lastReplacedUnit = null
    endif

    set t = null
endfunction

//===========================================================================
function startTrig_Frost_Wave takes nothing returns nothing
    local timer t = CreateTimer( )
    local DamageData dd = DamageData.create( )
    
    set dd.attacker = GetSpellAbilityUnit( )
    set dd.id = GetUnitAbilityLevel( dd.attacker, 'A060' )
    set dd.dmg = dd.id * 125.00
    set dd.pl = GetOwningPlayer( dd.attacker )
    set dd.hp =  Atan2( GetSpellTargetY( ) - GetUnitY( dd.attacker ), GetSpellTargetX( ) - GetUnitX( dd.attacker ) )
    set dd.rx = GetUnitX( dd.attacker ) + 32.00 * Cos( dd.hp )
    set dd.ry = GetUnitY( dd.attacker ) + 32.00 * Sin( dd.hp )
    set dd.attacked = CreateUnit( dd.pl, 'hdum', dd.rx, dd.ry, bj_RADTODEG * dd.hp )
    set dd.fx = AddSpecialEffectTarget( "Abilities\\Spells\\Other\\WindWave\\PrismaticWave.mdx", dd.attacked, "origin" )
    set dd.grp = NewGroup( )
    set dd.time = 0

    call SetDataBX( t, dd )
    
    call SetUnitFlyHeight( dd.attacked, 0.00, 0.00 )
    call SetUnitScale( dd.attacked, 1.25, 1.25, 1.25 )
   
    call TimerStart( t, 0.03125, true, function Timer_Frost_Wave_Expires )
    
    set t = null
endfunction
Вот примерчик как надо делать такие спеллы, 1 структура на все спеллы и общий "движок" всех волн, клонов которых с одним кодом можно наделать 100500, на все абилки у меня 1 триггер.
32

» WarCraft 3 / Стальной вихрь (whirlwind) и Заводной зверь

  1. эта способность просто заставляет юнита перейте в альтернативный режим отображения модели, такое не новость, механик и иллидан сделаны точно так же, велючение тега Alternatex. Разумеется не у всех есть такие анимайции.
  2. 'AMec' - mechanical critter, создает рандомного нейтрального юнита для данного тайслета (ну полярнася сова на летнем лордероне не заспаунится), который подконтролен вам, врагам же он отображается как нейтрально пассивный юнит. Ваши ауры не работают на критера и вы его можите атаковать вредными скиллами, так же если критер имеет атаку и атакует врага (нанесёт любой вред) - он будет отображатся вашим юнитам врагу до тех пор, пока не выйдет из поля зрения. Делают юнита таким особый флаг, можно установить мемхаком.
32

» WarCraft 3 / Обязательно ли подгружать и удалять боолекспр Хэндл?

М-да, болекспры не утекают, нет смысла удалять.. Триггер просто так лучше не удалять в его потоке, тут спеллы из доты выкладывали, там есть пример как юзать триггеры.
32

» WarCraft 3 / Функции МемХака2

ArhiMEN, ну для абилок, сперва InitCustomAbilityAddressChargesHook( указатель на абилку) чтобы включить для данной абилки возможность отрисовки зарядов, лучше выбрать абилку с кулдауниндикатором (это все активки или 2 пассивки, перерождение или эксгумация труповозки), юнит с абилкой на этот момент должен существовать. EnableCustomUnitAbilityCharges - включить отображение, и так далее.
Создал героя, у него есть абилка - InitCustomAbilityAddressChargesHook(GetUnitAbility(твой юнит, 'A000'))
32

» WarCraft 3 / Функции МемХака2

Ну для начала нужно указать веросию мемхака, какую юзаешь. Вот тут описание функций, ссылка
Предоставил DracoL1ch, в разных версиях немного отличается, но работает одинаково - рисует заряды абилкам, вроде не всем.
Для смены модели в некоторых версиях нужно чтобы юнита не было на карте, а в мемхаке анрайза должно работать на лету - модель меняется, судя по Base это для глобальной смены, до того как юнит созан, ну и для функции Get xxx которая получает эти данные от юнита, можно же посмотреть какая модель у юнита.
32

» WarCraft 3 / Вопросы по мемхаку

JackFastGame, для мемхака из темы с детектом урона функции выложены либо на хайве,либо в этом файле:
unction GetUnitUbertip takes integer id returns string
	return GetUnitUIStringParam(id,1,0x268)
endfunction

function SetUnitUbertip takes integer id, string s returns nothing
	call SetUnitUIStringParam(id,1,0x268,s)
endfunction

function GetUnitTip takes integer id returns string
	return GetUnitUIStringParam(id,1,0x25C)
endfunction

function SetUnitTip takes integer id, string s returns nothing
	call SetUnitUIStringParam(id,1,0x25C,s)
endfunction

function GetUnitHotkey takes integer id returns integer
	if GetUnitUIIntegerParam(id,0,0x26C)==0 and GetUnitUIIntegerParam(id,0,0x270)==0 then
		return 0
	endif
	return GetUnitUIIntegerParam(id,1,0x274)
endfunction

function SetUnitHotkey takes integer id, integer key returns nothing
	call SetUnitUIIntegerParam(id,0,0x26C,1)
	call SetUnitUIIntegerParam(id,0,0x270,key)
	call SetUnitUIIntegerParam(id,1,0x274,key)
endfunction

function GetHeroPrimaryAttributeById takes integer id returns integer
	local integer a=GetUnitDataDefByIdCaching(id)
	if a>0 then
		return RMem(a + 0x17C)
	endif
	return 0
endfunction
Ну и для всего прочего были, там не сложно. Смешения где лежат ссылки на строки. В мх анрайза вроде тоже было, покрайней мере для юнитов UnitNormalAPI и UnitBaseAPI, ну можно посмотреть в каких смещених относительно адресса итема лежат строки, предмет и юнит - оба виджеты, возможно прокатит с оффсетами юнита, но это неточно =)
Загруженные файлы
32

» WarCraft 3 / Функция GetLocalPlayer()

rsfghd, вылетит в любом случае, тег анимации меняем или создаем дамми и крепим к нему модель, пути модели разные. Так же мемхак позволяет менять модели на ходу.
32

» WarCraft 3 / Функция GetLocalPlayer()

Читали видимо плохо статью, нет нельзя, никак низя, ваще низя. Все глобальные обьекты которые синхронизируются между игроками - нельзя создать локально, мгновенный дисинх, почти все хендлы (кроме псевдохендлов вроде текстага) создавать локально нельзя. Поэтому сразу лесом с юнитом, его абилками, его координатами, его статами, его баффами и тому подобное.
Локально можно менять лишь данные визуализации, такие как всякие строки, модели, звуки, цвета и прозачность.
Полностью юнита невидимым не сделать, но настроить 100% прозрачность можно, подумайте хорошо что еще можно сделать?
32

» WarCraft 3 / Структуры в джассе: смещение без очистки и вытекающие проблемы.

Структуры vJassа посути массивы глобальных переменных и код, который управлет выделением ячеек, и все, поэтому твоя забота как разработчика сделать метод очистки и создания таким, чтобы небыло ни мусора ни ошибок.
32

» WarCraft 3 / Респавн крипов

Тут какое то глупое решение, вейтом ждать, dying unit может быть уже null, что мешать взять таймер на каждого юнита, или проходится по спотам крипов раз в минуту как в доте и если крипов там нет, то создать новых. На сейте выложена система респауна крипов без проблем.
32

» WarCraft 3 / Вопросы по мемхаку

JackFastGame, они есть в мемхаке, SetObjectTip\ubertip или как то так, для всех полей есть функции.
32

» WarCraft 3 / отлов удара на ГУИ

Ну блин очевидно же что подобная ахинея проигрывает нормальным системам вроде того же мемхака, где достаточно просто узнать все необходимое, копировал и вставил - все.
32

» WarCraft 3 / Мемхак анрайза v1.5+

1.5+ заказная, он не решил еще выкладывать в паблик или нет, в ваших силах повлиять на это.
32

» WarCraft 3 / Как повернуть юнита горизонтально или вертикально?

Юнита - стандартными средствами никак, ну если даммик - то ему можно модель сделать где есть анимация поворота на N градусов. Так же мемхак позволяет крутить обьекты по всем осям, но полностью это реализовано в мемхаке 1.5
32

» WarCraft 3 / Функция ForGroup

Глобальные переменные, так же в фортгруп будуттраьотать GetTriggerxxx нативки, к примеру кластер скилла
32

» WarCraft 3 / Минусы отлова урон через орб эффект

Смысл мемхака не только в том чтобы добавить че-то невозможное, а так же значительно упростить процесс разработки некоторых вещей, тот же детект урона на мемхаке быстрее и проще чем без него, при этом ничего дефолтного не ломается...