Потому что бездумно реализован детект урона, происходит рекурсия, нету никаких проверок. Ты наносишь урон в триггере который реагирует на урон, ну само собой вылетать будет. Такие вещи лучше реализовать на jass.
Вышла версия 1.6, появились фишки работы с фреймами, вроде таки сделал анрайз функции рисовать хп\мп бары, кулдауны, и прочее без дллок, там доработал работу фремов и оптимизировал код, чтение\запись памяти стало быстрее. Добавил некоторые функции для продвинутых, пользователей, изучил работу китайцев которые конвертируют карту в байткод для защиты, скоро будут карты в которых кроме длл... Много интересного, но для наших нубов бесполезное...
Там внезапно даже другой формат данных, модельки просто так не взять и вставить, офк народ брал вытаскивал и конвертировал, особо впечатлительные брали и делали с нуля модель по мотивам доты 2. На хайве поищи, но не думаю что всё из доты 2 удастся найти под варкравт.
Как то делал способность, которая похищает % атаки у врагов поблизости на несколько секунд, используя мемхак. Способность так то вроде не сложная в реализации, но вот про новичков наверное не по адресу, ибо написано на vjass. Если интересно прокоментирую код и обьясню что и зачем:
код
globals
integer HASH_EXTRA_DAMAGE_INDEX = 5
integer array abilityAddDamageLvl //Массив способностей для увеличения дополнительного урона
endglobals
function GetUnitExtraDamage takes unit u returns integer
local integer iD = GetHandleId( u )
local integer ammount
set ammount = LoadInteger( gg_htb_HashData, iD, HASH_EXTRA_DAMAGE_INDEX )
return ammount
endfunction
function SetUnitExtraDamage takes unit u, integer ammount returns nothing
local integer iD = GetHandleId( u )
local integer power = 12
local integer index = 0
local integer rest
if ammount > 8191 then
set ammount = 8191
endif
loop
call UnitRemoveAbility( u, abilityAddDamageLvl[index] )
exitwhen index == 12
set index = index + 1
endloop
if ammount > 0 then
set rest = ammount
loop
exitwhen rest <= 0
if R2I( Pow( 2, power ) ) > rest then
set power = power - 1
elseif R2I( Pow( 2, power ) ) <= rest then
call UnitAddAbility( u, abilityAddDamageLvl[power] )
call UnitMakeAbilityPermanent( u, true, abilityAddDamageLvl[power] )
set rest = rest - R2I( Pow( 2, power ) )
set power = power - 1
endif
endloop
call SaveInteger( gg_htb_HashData, iD, HASH_EXTRA_DAMAGE_INDEX, ammount )
endif
endfunction
function Only_Alive_Player_No_Dummy_No_Ward_Filter takes nothing returns boolean
set bj_lastFilterUnit = GetFilterUnit( )
return not ( IsUnitDead( bj_lastFilterUnit ) or IsUnitWard( bj_lastFilterUnit ) or IsUnitType( bj_lastFilterUnit, UNIT_TYPE_MECHANICAL ) or IsUnitIllusion( bj_lastFilterUnit ) or IsUnitHidden( bj_lastFilterUnit ) )
endfunction
function Group_Remove_Damage_Enum takes nothing returns nothing
local unit ally = GetEnumUnit( )
local TriggerData dd = bj_forceRandomConsidered
local integer bonus = R2I( GetUnitExtraDamage( ally ) - dd.dmg )
call UnitRemoveAbility( ally, 'B00H' )
call UnitRemoveAbility( ally, 'A0DV' )
call SetUnitExtraDamage( ally, bonus )
call SaveInteger( gg_htb_HashData, GetHandleId(ally), HASH_EXTRA_DAMAGE_INDEX, bonus )
call RemoveSavedHandle( gg_htb_HashData, ExSpeedSteal, GetHandleId(ally) )
set ally = null
endfunction
function Group_Add_Damage_Enum takes nothing returns nothing
local TriggerData dd = bj_forceRandomConsidered
local unit ally = GetEnumUnit( )
local integer bonus = 0
local integer pBuff
call TriggerRegisterDeathEvent( dd.trg, ally )
call SaveTriggerHandle( gg_htb_HashData, ExSpeedSteal, GetHandleId(ally), dd.trg )
call SetUnitExtraDamage( ally, R2I( GetUnitExtraDamage( ally ) + dd.dmg ) )
call UnitAddAbility( ally, 'A0DV' )
call UnitMakeAbilityPermanent( ally, true, 'A0DV' )
call UnitAddAbility( ally, 'A03W' )
set pBuff = GetUnitAbility( ally, 'B00H' )
if pBuff < 1 then
call BJDebugMsg(DEBUG+" "+ GetAbilityEffectById( 'A0DV', EFFECT_TYPE_SPECIAL, 1 ) )
call BJDebugMsg(INFO)
return
endif
set dd.c = TimerGetElapsed( DispTimer )
call SetBuffLevel( pBuff, dd.id )
call WMem( RMem( pBuff + 0x90 ) + 0x4, mR2I( dd.c + 15.10 ) )
call WMem( RMem( pBuff + 0x90 ) + 0x8, mR2I( dd.c + 10.408 ) )
call UnitRemoveAbilityTimed( ally, 'A03W', 0.00 )
set ally = null
endfunction
function Speed_Steal_damage_enemy takes nothing returns nothing
set TempDamage = TempDamage + GetUnitBaseDamage( GetEnumUnit( ) )
endfunction
function Trig_Speed_Steal_Buff_Expires_Conditions takes nothing returns boolean
local TriggerData dd
local unit dies
if ( GetTriggerEventId() == EVENT_WIDGET_DEATH ) then
set dd = GetDataBX( GetTriggeringTrigger( ) )
set dies = GetDyingUnit( )
if IsUnitInGroup( dies, dd.grp ) then
call GroupRemoveUnit( dd.grp, dies )
call SetUnitExtraDamage( dies, 0 )
call RemoveSavedHandle( gg_htb_HashData, ExSpeedSteal, GetHandleId(dies) )
call RemoveSavedInteger( gg_htb_HashData, GetHandleId(dies), HASH_EXTRA_DAMAGE_INDEX )
call UnitRemoveAbility( dies, 'A0DV' )
endif
set dies = null
return false
elseif ( GetTriggerEventId() != EVENT_GAME_TIMER_EXPIRED ) then
set dd = GetDataBX( GetTriggeringTrigger( ) )
set dies = bj_lastReplacedUnit
call GroupRemoveUnit( dd.grp, dies )
call SetUnitExtraDamage( dies, R2I( GetUnitExtraDamage( dies ) - dd.dmg ) )
call SaveInteger( gg_htb_HashData, GetHandleId(dies), HASH_EXTRA_DAMAGE_INDEX, R2I( GetUnitExtraDamage( dies ) - dd.dmg ) )
call RemoveSavedHandle( gg_htb_HashData, ExSpeedSteal, GetHandleId(dies) )
call UnitRemoveAbility( dies, 'A0DV' )
set dies = null
return false
endif
return true
endfunction
function Trig_Speed_Steal_Buff_Expires_Actions takes nothing returns nothing
local TriggerData dd = GetDataBX( GetTriggeringTrigger() )
call DisableTrigger( dd.trg )
set bj_forceRandomConsidered = dd
call ForGroup( dd.grp, function Group_Remove_Damage_Enum )
call ReleaseGroup( dd.grp )
call RemoveDataBX( dd.trg )
call dd.RemoveTrigger( )
call dd.destroy( )
endfunction
function Trig_Speed_Steal_Actions takes nothing returns nothing
local unit Runner = GetSpellAbilityUnit( )
local integer Level = GetUnitAbilityLevel( Runner, 'A03Q' )
local real CX = GetUnitX( Runner )
local real CY = GetUnitY( Runner )
local player pl = GetOwningPlayer( Runner )
local TriggerData dd
call GroupClear( gg_grp_TempGroup )
set bj_groupEnumOwningPlayer = pl
call GroupEnumUnitsInRange( gg_grp_TempGroup, CX, CY, 500.00, OnlyEnemy )
if FirstOfGroup( gg_grp_TempGroup ) != null then
set TempDamage = 0.00
call ForGroup( gg_grp_TempGroup, function Speed_Steal_damage_enemy )
if TempDamage > 1.00 then
set dd = TriggerData.create()
set dd.trg = CreateTrigger( )
set dd.trc = TriggerAddCondition( dd.trg, Condition( function Trig_Speed_Steal_Buff_Expires_Conditions ) )
set dd.tra = TriggerAddAction( dd.trg, function Trig_Speed_Steal_Buff_Expires_Actions )
set dd.grp = NewGroup()
set dd.dmg = ( 0.15 * Level ) * TempDamage
set dd.id = Level
call SetDataBX( dd.trg, dd )
call GroupEnumUnitsOfPlayer( dd.grp, pl, Condition( function Only_Alive_Player_No_Dummy_No_Ward_Filter ) )
set bj_forceRandomConsidered = dd
call ForGroup( dd.grp, function Group_Add_Damage_Enum )
call TriggerRegisterTimerEvent( dd.trg, 15.00, false )
endif
endif
set Runner = null
endfunction
function Init_ExtraDamageSystem takes nothing returns nothing
if abilityAddDamageLvl[0] > 0 then
return
endif
set abilityAddDamageLvl[0] = 'A0DS'
set abilityAddDamageLvl[1] = 'A0DA'
set abilityAddDamageLvl[2] = 'A0DK'
set abilityAddDamageLvl[3] = 'A0DL'
set abilityAddDamageLvl[4] = 'A0DM'
set abilityAddDamageLvl[5] = 'A0DN'
set abilityAddDamageLvl[6] = 'A0DO'
set abilityAddDamageLvl[7] = 'A0DP'
set abilityAddDamageLvl[8] = 'A0DQ'
set abilityAddDamageLvl[9] = 'A0DR'
set abilityAddDamageLvl[10] = 'A0DJ'
set abilityAddDamageLvl[11] = 'A0DT'
set abilityAddDamageLvl[12] = 'A0DU'
set bj_lastCreatedUnit = CreateUnit( Player( 15 ), 'hpea', 4435.41, 4295.44, 270.00 )
call UnitAddAbility( bj_lastCreatedUnit, abilityAddDamageLvl[0] )
call UnitAddAbility( bj_lastCreatedUnit, abilityAddDamageLvl[1] )
call UnitAddAbility( bj_lastCreatedUnit, abilityAddDamageLvl[2] )
call UnitAddAbility( bj_lastCreatedUnit, abilityAddDamageLvl[3] )
call UnitAddAbility( bj_lastCreatedUnit, abilityAddDamageLvl[4] )
call UnitAddAbility( bj_lastCreatedUnit, abilityAddDamageLvl[5] )
call UnitAddAbility( bj_lastCreatedUnit, abilityAddDamageLvl[6] )
call UnitAddAbility( bj_lastCreatedUnit, abilityAddDamageLvl[7] )
call UnitAddAbility( bj_lastCreatedUnit, abilityAddDamageLvl[8] )
call UnitAddAbility( bj_lastCreatedUnit, abilityAddDamageLvl[9] )
call UnitAddAbility( bj_lastCreatedUnit, abilityAddDamageLvl[10] )
call UnitAddAbility( bj_lastCreatedUnit, abilityAddDamageLvl[11] )
call UnitAddAbility( bj_lastCreatedUnit, abilityAddDamageLvl[12] )
call ShowUnit( bj_lastCreatedUnit, false )
call KillUnit( bj_lastCreatedUnit )
endfunction
Пока юнит разлагается и ты видишь на земле труп, юнит занимает место в памяти, если же юнит разложился -то его уже нет и память он не занимает.
Разумеется в картах типа товер дефенсов имеет смысл сокращать время сокращения или делать суммонами, чтобы после смерти они исчезали не оставляя трупы - вспомните что происходит с духами волков после их убийства. Но тут палка о двух концах, юниты могут наносить урон и убивать других юнитов - так вот если какой нить самон плюнет во врага и сдохет, а тычка долетит до цели через некоторое время и убьет - убивший юнит будет равен null, в доте есть такой баг, змейки веномансера имеют ядовитую атаку и часто обеспечивают суецид врагам, не давая бабки за фраг их хозяину.
А их нету, есть скрипты для melee AI где просто тактика и экономика, никакого микроконтроля и расположения зданий. Все микро, стройка и прочее описано в движке игры, так что разрабатываем самостоятельно методом тыка.
Light Strike Array - A027
EMP - Z609
Как бы очевидно что ищут ID в файлах игры, стан лины - сделан из огненного голема, следовательно ищем его в Neutral Ability String.txt ну а emp на канале, в common ability func. Ну а в целом карту восстановили для открывания в редакторе и смотрим в чем проблема то?
Vipas1707, своих написать, бот если что то не улучшает - это не значит что он тупит, быть может в записаной для него тактике это бесполезно, бот просто разыгрывает шаблонный бой, где он либо выиграл - либо проиграл, причем не умер от тебя - а просто не успел убить тебя за определенное время - ты впереди по развитию, он считай сдался - на про уровне обычно сразу выходят в таком случае - ибо соперник шанса тебе не оставит.
» WarCraft 3 / Как заставить пламя феникса атаковать цели с наименьшим хп?
» WarCraft 3 / Вылетает при атаке
» WarCraft 3 / Мемхак для нуба
» WarCraft 3 / Мемхак для нуба
» WarCraft 3 / Как изменять значение атаки появляющихся саранчидов?
» WarCraft 3 / Эффекты аур\заклинаний из Dota 2
» WarCraft 3 / Нестабильная система опыта
» WarCraft 3 / Эффекты аур\заклинаний из Dota 2
» WarCraft 3 / Урон в зависимости от дальности
Ред. quq_CCCP
» WarCraft 3 / Вычислительная геометрия часть 2
» WarCraft 3 / деБафф плейсеры
» WarCraft 3 / Как называется анимация брызгов крови в редакторе?
Ред. quq_CCCP
» WarCraft 3 / Как создать подсчёт урона юнитов в области?
» WarCraft 3 / Фатал при загрузке сейва
» WarCraft 3 / Помогите найти карты детства
Exota
» WarCraft 3 / Как сделать скилл, как у тролля в доте?
» WarCraft 3 / this application has encountered a critical error FATAL ERROR
» WarCraft 3 / Утечки памяти от юнитов
Разумеется в картах типа товер дефенсов имеет смысл сокращать время сокращения или делать суммонами, чтобы после смерти они исчезали не оставляя трупы - вспомните что происходит с духами волков после их убийства. Но тут палка о двух концах, юниты могут наносить урон и убивать других юнитов - так вот если какой нить самон плюнет во врага и сдохет, а тычка долетит до цели через некоторое время и убьет - убивший юнит будет равен null, в доте есть такой баг, змейки веномансера имеют ядовитую атаку и часто обеспечивают суецид врагам, не давая бабки за фраг их хозяину.
» WarCraft 3 / Поделитесь кто нибудь фаилами ИИ на основные расы режима Melee
» WarCraft 3 / CustomKeys – DotA v6.74e LoD – Помогите найти последние два ID
EMP - Z609
Как бы очевидно что ищут ID в файлах игры, стан лины - сделан из огненного голема, следовательно ищем его в Neutral Ability String.txt ну а emp на канале, в common ability func. Ну а в целом карту восстановили для открывания в редакторе и смотрим в чем проблема то?
» WarCraft 3 / По поводу мемхака и изменению параметров способностей.
» WarCraft 3 / По поводу мемхака и изменению параметров способностей.
» WarCraft 3 / "Перемещение юнита при определённым % здоровья
» WarCraft 3 / Как сделать, чтобы компьютер сильный, всегда улучшал ратушу?
» WarCraft 3 / Горючая смесь