DESo3latorTro0pe, ну статью написать как можно управлять мобами?
У одного триггера может быть множество событий, причем разных, а юнитам можно поставить custom value (в гуях) и таким образом проверять какой чекпоинт он преодалел и в какой отправить его сейчас, ну и брать от областей GetCenterOfPos (или как там в гуях) тоже ненадо, делаем массив куда заносим все эти точки, и о чудо все в одном триггере, обьекты не создаются, и кода маньше в 10 раз.
Стоит только подумать или посмотреть как сделано у других.
DESo3latorTro0pe, ну для начла вот, еще вот
Тут ищем что конкретно интересует, ну есть статья про jass
Ибо полностью на гуи от утечек не избавится, да и будет масса неудобств, все твои пути крипов в 1 триггере можно было сделать. Потом нужно практиковатся, я и предложил для начала карту близардов конфетные войны.
хм, ntdll.dll - случаем никаких читов или прог не было включено?
Есть такая функция IsUnitVisibleToPlayer и аналог для детекции (типа инвизера спалили труесайтом или нет).
Но юнит виден игроку, юнит види юнита, это есть такое событие - юнит обнаружил цель в пределах досигаймости или как то так на гуях...
На мемхаке тоже куча функций, насчет видимости и детекции.
DESo3latorTro0pe, ну потому что я сразу сказал как надо, но намек раз не понятен, надо тыкать носом. Каждый триггер год разбирать будем, статей и примеров как делать надо и как избавится от утечек полно, про то что лучше не удалять юнитов (кроме редких исключений) и не пытатся ничего делать с мертвыми юнитами, никаких вручений абилок, изменений уровня. Вейты зло, после wait функция DyingUniy может вернуть уже и не того юнита который умер, ибо это разрыв потока выполнения, вовсе порой можно обойтись без вейтов, чтобы какой нить юнит умер не сразу а спустя мгновение - ему можно установить время жизни.
Нет нетак, нужна пассивка с кулдаун индикатором, их 2 - перерождение таурена и эксгумация труповозки, на одной можно запустить кд не убивая юнита лишь мемхаком, а вот вторая запускается в кд технической абилкой труповозки (смотри как устроена труповозка), тогда на ней пойдет кд. Ну там правда будет баг, это считается кастом и будет сбивать инвиз с героя если запустить таким образом кулдаун у эксгумации.
DESo3latorTro0pe, юнита лучше скрывать (HideUnit) и убивать. Так же советую не плодить по 10 триггеров на перемещение юнитов, это мало того что глупая и неоправданная реализация, так еще и утечек море. GetPosition все эти функции создают обьект location которые не удаляются, хотябы посмотри конфетные войны близзардов.
Daro, рексар - целиком выложен на хайве, модели апарата и его спеллов, модель энигмы, модель ульта акаши - на хайве 20 лет лежит как.
Вокер старый, новый вроде был просто самопис по оглядке на то что есть в карте, так же в титрах вы найдете векса, и других людей кто делал спеллы или системы. Все не вспомню уже, берешь и гуглишь - и о чудо, оно есть.
Ну вот подобный код может как раз вызывать подобные фаталы, + ну очень хреновый гуи код с тоннами утечек, так что приводим код в порядок, не мешало бы почитать статьи про оптимизацию, исключаем вейты и ремув юнитов. Так же не делаем никаких махинаций с абилками дохлых юнитов.
Потом все в доте, натырено с хайва - прочесываем хайв и о чудо, там вплоть до героев целиком с кодом, импортом есть. Фрог то не сам делал а тырил готовое и балансил, по репортам комьюнити.
А зачем неуязвомость? Если охото как в кампании альянса с обсерваториями, триггер на получение урон и хил здания, ровно на величину этого урона + делаем его за нейтрально пассивного пока не достроено.
Гуванч, он на мемхаке функции вращения модели юзает, но там надо думать, yaw, pith, roll надо задавать чтобы повернуть модель, и придумать формулу где по всей траектории полёта они будут высчитыватся.
ArhiMEN, там была отдельная функция, я забыл название в разделе юнита смотри:
function GetUnitCritterFlag takes unit u returns integer
local integer pData = ConvertHandle( u )
if pData > 0 then
// 0 - normal | 1 - critter
return ReadRealMemory( pData + 0x60 )
endif
return -1
endfunction
function SetUnitCritterFlag takes unit u, integer id returns nothing
// Acts similar to 'Amec', meaning if unit has flag equal to 1
// then he is considered a creep and will be ignored by autoattacks.
// However, an attack may still be forced with 'A' key or rightclick
local integer pData = ConvertHandle( u )
if pData > 0 then
if id >= 0 and id <= 1 then
call WriteRealMemory( pData + 0x60, id )
endif
endif
endfunction
Как то много кода для такой примитивной абилки...
Пример кода:
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 триггер.
эта способность просто заставляет юнита перейте в альтернативный режим отображения модели, такое не новость, механик и иллидан сделаны точно так же, велючение тега Alternatex. Разумеется не у всех есть такие анимайции.
'AMec' - mechanical critter, создает рандомного нейтрального юнита для данного тайслета (ну полярнася сова на летнем лордероне не заспаунится), который подконтролен вам, врагам же он отображается как нейтрально пассивный юнит. Ваши ауры не работают на критера и вы его можите атаковать вредными скиллами, так же если критер имеет атаку и атакует врага (нанесёт любой вред) - он будет отображатся вашим юнитам врагу до тех пор, пока не выйдет из поля зрения. Делают юнита таким особый флаг, можно установить мемхаком.
М-да, болекспры не утекают, нет смысла удалять.. Триггер просто так лучше не удалять в его потоке, тут спеллы из доты выкладывали, там есть пример как юзать триггеры.
» WarCraft 3 / Начала внезапно вылетать карта. (редактор 1.26а)
У одного триггера может быть множество событий, причем разных, а юнитам можно поставить custom value (в гуях) и таким образом проверять какой чекпоинт он преодалел и в какой отправить его сейчас, ну и брать от областей GetCenterOfPos (или как там в гуях) тоже ненадо, делаем массив куда заносим все эти точки, и о чудо все в одном триггере, обьекты не создаются, и кода маньше в 10 раз.
Стоит только подумать или посмотреть как сделано у других.
» WarCraft 3 / Начала внезапно вылетать карта. (редактор 1.26а)
Тут ищем что конкретно интересует, ну есть статья про jass
Ибо полностью на гуи от утечек не избавится, да и будет масса неудобств, все твои пути крипов в 1 триггере можно было сделать. Потом нужно практиковатся, я и предложил для начала карту близардов конфетные войны.
» WarCraft 3 / Видимость юнита
Но юнит виден игроку, юнит види юнита, это есть такое событие - юнит обнаружил цель в пределах досигаймости или как то так на гуях...
» WarCraft 3 / Перезарядка пассивного навыка
» WarCraft 3 / Начала внезапно вылетать карта. (редактор 1.26а)
» WarCraft 3 / Перезарядка пассивного навыка
» WarCraft 3 / Начала внезапно вылетать карта. (редактор 1.26а)
» WarCraft 3 / Есть ли модели дота в открытом доступе?
Вокер старый, новый вроде был просто самопис по оглядке на то что есть в карте, так же в титрах вы найдете векса, и других людей кто делал спеллы или системы. Все не вспомню уже, берешь и гуглишь - и о чудо, оно есть.
» WarCraft 3 / Телепортация через диалог
» WarCraft 3 / Начала внезапно вылетать карта. (редактор 1.26а)
» WarCraft 3 / Есть ли модели дота в открытом доступе?
» WarCraft 3 / Начала внезапно вылетать карта. (редактор 1.26а)
» WarCraft 3 / Есть ли модели дота в открытом доступе?
» WarCraft 3 / Массив с буквами в место чисел
» WarCraft 3 / Неуязвимое здание с отображением хп
» WarCraft 3 / Полёт клинка
» WarCraft 3 / Полёт клинка
» WarCraft 3 / Волна силы не пашет vJass
Ред. quq_CCCP
» WarCraft 3 / Стальной вихрь (whirlwind) и Заводной зверь
Ред. quq_CCCP
» WarCraft 3 / Волна силы не пашет vJass
Пример кода:
» WarCraft 3 / Стальной вихрь (whirlwind) и Заводной зверь
» WarCraft 3 / Вращение юнита
» WarCraft 3 / Магический лайфстил
» WarCraft 3 / Обязательно ли подгружать и удалять боолекспр Хэндл?
» WarCraft 3 / Функции МемХака2