Aifrediil, ну а если промахнулся, а если стопить атаку специально? Это максимально убогая реализация, по этому и нужно делать детект физического урона.
Ну хз, было бы желание, мне особо некогда этим заниматся, но людей которые могут это сделать много, стоит их заинтересовать.
Да и вы бы лучше бы сами учились чето делать, тогда бы все сделали и улыбались, не пришлось бы бегать за кодерами.
Нужная отдельная версия доты с ИИ, там так в названии написано DOTA некая версия AI By автор ИИ.
Т.к айкап решил что он сам себе на уме, для их доты ИИ версии никто не делал, поэтому только 6.83 фрога с Ии брать.
У тебя не то событие, нужно событие - Приводит способность в дейтсвие, только у него есть координаты каста, у завершения каста или начала нету координат, GetSpellTargetLoc() возвращяет null, следовательно юниты и идут в центр карты, ибо у него координаты 0.00, 0.00
Если чо, существует group, если есть нужда создавать и двигать множество даммиков, почему бы не собирать их в группу и перебирать там, то локальные массивы хрень.
Это обычный морф, у которого есть как применение так и приказ и смена ID юнита, следовательно проверяя отданный приказ или отлавливая каст способности и проверяя id юнита который её применил.
RvzerBro, ну там была ссылка на видос о багах доты, и видео начиналось с бага линкен сферы и обсидиан дестроера, видос за что то удалили...
Но можите погуглить, бага очень известная в кругах дотеров, и видосов по ней было тонны как и бага с хуком пуджа.
Там есть несколько хуков на детект урона, те что привели по ссылке выше урон обнулить не смогут, уже поздно при EventDamaged, нужен хук лича, но там можно прочитать лишь адресса, нету работы с JASS обьектами, да и ресурсоемко. Просто отхиливай урон, если нужно.
ang= ang - 180.00 + 2.00 * ( Atan2( cy - dx, cx - dx ) * bj_RADTODEG )// рикошет, угол падения = углу отражения и все такое...
))
Как то давно для своей карты делал, ang текущий угол юнита (или что там у тебя) cx-cy - координаты юнита (или что там у тебя(, dx-dy координаты препятствия, т.е того от чего идет рикошет.
TriggerData - это структура vjass, в данном случае туда сохраняется триггер и его условия и действия, чтобы их потом можно было удалять.
SetDataBX - можешь заменить хештаблицей, SaveInteger( Hashtable, GetHandleId( некий обьект), 0, значение)
library ArmorSystem initializer Init
globals
private integer array abilityAddArmor //Массив способностей для повышения брони
private integer HASH_EXTRA_ARMOR_INDEX = 4 //Данные о бонусном уроне, полученном с помощью системы будут хранится в хэш - таблице за хендлом юнита, под этим ключём
endglobals
//Узнать дополнительную броню
function GetUnitExtraArmor takes unit u returns integer
local integer iD = GetHandleId( u )
local integer ammount
set ammount = LoadInteger( gg_htb_HashData, iD, HASH_EXTRA_ARMOR_INDEX )
return ammount
endfunction
//Задать бонусную защиту (выше 8191 не поднять)
function SetUnitExtraArmor takes unit u, integer ammount returns nothing
local integer iD = GetHandleId( u )
local integer power = 13
local integer index = 0
local integer rest
if ammount > 8191 then
set ammount = 8191
endif
loop
call UnitRemoveAbility( u, abilityAddArmor[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, abilityAddArmor[power] )
set rest = rest - R2I( Pow( 2, power ) )
set power = power - 1
endif
endloop
call SaveInteger( gg_htb_HashData, iD, HASH_EXTRA_ARMOR_INDEX, ammount )
endif
if ammount == 0 then
call RemoveSavedInteger( gg_htb_HashData, iD, HASH_EXTRA_ARMOR_INDEX )
endif
endfunction
private function Init takes nothing returns nothing
local unit dummy = CreateUnit( Player( 9 ), 'hpea', 0.00, 0.00, 0.00 )
local integer nIndex = 0
call ShowUnit( dummy, false )
//Добавить защиту
set abilityAddArmor[0] = 'A0B7'
set abilityAddArmor[1] = 'A0B8'
set abilityAddArmor[2] = 'A0B9'
set abilityAddArmor[3] = 'A0BA'
set abilityAddArmor[4] = 'A0BB'
set abilityAddArmor[5] = 'A0BC'
set abilityAddArmor[6] = 'A0BD'
set abilityAddArmor[7] = 'A0BE'
set abilityAddArmor[8] = 'A0BF'
set abilityAddArmor[9] = 'A0BJ'
set abilityAddArmor[10] = 'A0BG'
set abilityAddArmor[11] = 'A0BH'
set abilityAddArmor[12] = 'A0BI'
loop
exitwhen nIndex > 12
call UnitAddAbility( dummy, abilityAddArmor[nIndex] )
set nIndex = nIndex + 1
endloop
call RemoveUnit( dummy )
set dummy = null
endfunction
endlibrary
function Trig_Summon_Lava_Spawn_Actions takes nothing returns nothing
local unit LavaSpawn = GetEnteringUnit( )
local unit Runner = gg_unt_PlayerHeroUnits[ GetPlayerId( GetOwningPlayer( LavaSpawn ) ) ]
local integer id
local TriggerData dd
local TriggerData st
call SetUnitUserData( LavaSpawn, 1 )
call SetUnitAbilityLevel( LavaSpawn, 'A0B6', GetUnitTypeId( LavaSpawn ) - 'elv0' )
if GetUnitAbilityLevel( Runner, 'A09S' ) == 0 then
set LavaSpawn = null
set Runner = null
return
endif
set st = LoadInteger( gg_htb_HashData, ExReactiveArmor, GetHandleId( Runner ) )
set dd = TriggerData.create( )
set dd.attacked = LavaSpawn
set dd.pl = GetOwningPlayer( Runner )
set dd.trg = CreateTrigger( )
set dd.trc = TriggerAddCondition( dd.trg, Condition( function Trig_Reactive_Armor_Conditions ) )
set dd.tra = TriggerAddAction( dd.trg, function Trig_Reactive_Armor_Actions )
set dd.id = 0
set dd.c = 0
set dd.ExCount = ( st.ExCount / 4 ) * 2 + 2
call TriggerRegisterUnitEvent( dd.trg, LavaSpawn, EVENT_UNIT_DAMAGED )
call TriggerRegisterUnitEvent( dd.trg, LavaSpawn, EVENT_UNIT_DEATH )
call UnitAddAbility( LavaSpawn, 'A06V' )
call UnitMakeAbilityPermanent( LavaSpawn, true, 'A06V' )
call SetDataBX( dd.trg, dd )
call SaveInteger( gg_htb_HashData, ExReactiveArmor, GetHandleId( LavaSpawn ), dd )
call SaveUnitHandle( gg_htb_HashData, GetHandleId( LavaSpawn ), 1, Runner )
set LavaSpawn = null
set Runner = null
endfunction
//===========================================================================
function InitTrig_Summon_Lava_Spawn takes nothing returns nothing
set gg_trg_Summon_Lava_Spawn = CreateTrigger( )
//call TriggerAddCondition( gg_trg_Summon_Lava_Spawn, Condition( function Trig_Summon_Lava_Spawn_Conditions ) )
call TriggerAddAction( gg_trg_Summon_Lava_Spawn, function Trig_Summon_Lava_Spawn_Actions )
endfunction
globals
constant real MeltingDamage = 4.25 // дополнительнй урон за удар.
endglobals
function Trig_Lava_Spawn_Conditions takes nothing returns boolean
local integer id
if GetTriggerEventId( ) == EVENT_PLAYER_UNIT_SPELL_EFFECT then
return GetSpellAbilityId( ) == 'A0B6'
elseif GetTriggerEventId( ) == EVENT_PLAYER_UNIT_ISSUED_ORDER and GetUnitAbilityLevel( GetOrderedUnit( ), 'A0B6' ) > 0 then
// включил или выключил игрок автоматическое применение, необходимо чтобы не создавать лишние триггеры!
set bj_lastCreatedUnit = GetOrderedUnit( )
set id = GetIssuedOrderId( )
if ( id == 852255 ) then // poison arrows
call SetUnitUserData( bj_lastCreatedUnit, 1 )
elseif ( id == 852256 ) then // unpoison arrows
call SetUnitUserData( bj_lastCreatedUnit, 0 )
endif
return false
endif
set id = GetUnitTypeId( GetAttacker( ) )
set bj_lastFilterUnit = GetTriggerUnit( )
// только для 'elv1'-'elv3' по не зданиям, не иммунным к магии, не вардам.
return ( id == 'elv1' or id == 'elv2' or id == 'elv3' ) and not( IsUnitWard( bj_lastFilterUnit ) or IsUnitType( bj_lastFilterUnit, UNIT_TYPE_STRUCTURE ) or IsUnitType( bj_lastFilterUnit, UNIT_TYPE_MAGIC_IMMUNE ))
endfunction
function Timer_LavaSpawn_Stop_Check takes nothing returns nothing
local TriggerData st = GetDataBX( GetExpiredTimer( ) )
set st.IsCheck = true
call TriggerRegisterTimerExpireEvent( st.trg, st.trix )
call TimerStart( st.trix, 1.75, false, null )
endfunction
function Trig_Incinerate_Conditions takes nothing returns boolean
local TriggerData st = GetDataBX( GetTriggeringTrigger( ) )
if GetTriggerEventId( ) == EVENT_UNIT_DAMAGED then
return GetEventDamage( ) >= 0.00 and GetUnitAbilityLevel( GetTriggerUnit( ), 'B02E' ) > 0 and GetEventDamageSource( ) == st.attacker
elseif GetTriggerEventId( ) == EVENT_UNIT_ISSUED_ORDER and st.IsCheck then
return false
endif
call DisableTrigger( st.trg )
call TimerStart( st.trix, 0.01, false, function Remove_Sun_Shell_Timer_Expires )
return false
endfunction
function Trig_Incinerate_Actions takes nothing returns nothing
local TriggerData dd = GetDataBX( GetTriggeringTrigger( ) )
if GetTriggerEventId( ) == EVENT_GAME_TIMER_EXPIRED and GetTriggerEvalCount( dd.trg ) < dd.time then
if IsUnitDead( dd.attacker ) and not IsUnitType( dd.attacker, UNIT_TYPE_HERO ) then
set dd.attacker = dd.dummy
endif
call UnitDamageTarget( dd.attacker, dd.attacked, dd.dmg, true, true, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
else
call DisableTrigger( dd.trg )
call SetUnitExtraArmor( dd.attacked, 0 )
call UnitRemoveAbility( dd.attacked, 'Ainc' )
if not IsUnitDead( dd.attacked ) then
call UnitRemoveAbility( dd.attacked, 'Binc' )
endif
call RemoveSavedHandle( gg_htb_HashData, ExIncinirate, GetHandleId( dd.attacked ) )
call dd.RemoveTrigger( )
call dd.destroy( )
endif
endfunction
function Init_Trig_Incinerate takes nothing returns nothing
local TriggerData st = GetDataBX( GetTriggeringTrigger( ) )
local integer id = GetHandleId( st.attacked )
local TriggerData dd
local trigger trig = LoadTriggerHandle( gg_htb_HashData, ExIncinirate, id )
call DisableTrigger( st.trg )
call UnitRemoveAbility( st.attacked, 'B02E' )
if trig == null then
set dd = TriggerData.create( )
set dd.trg = CreateTrigger( )
set dd.tra = TriggerAddAction( dd.trg, function Trig_Incinerate_Actions )
set dd.attacker = st.attacker
set dd.attacked = st.attacked
set dd.dummy = LoadUnitHandle( gg_htb_HashData, GetHandleId( dd.attacker ), 1 )
set dd.id = 1
set dd.dmg = MeltingDamage
set dd.time = 6
call TriggerRegisterDeathEvent( dd.trg, dd.attacked )
call TriggerRegisterTimerEvent( dd.trg, 1.00, true )
call UnitAddAbility( dd.attacked, 'Ainc' )
call SetDataBX( dd.trg, dd )
call SaveTriggerHandle( gg_htb_HashData, ExIncinirate, id, dd.trg )
else
set dd = GetDataBX( trig )
set dd.attacker = st.attacker
set dd.attacked = st.attacked
set dd.dummy = LoadUnitHandle( gg_htb_HashData, GetHandleId( dd.attacker ), 1 )
set dd.id = dd.id + 1
set dd.dmg = MeltingDamage * dd.id
call ResetTrigger( dd.trg )
endif
if not IsUnitDead( dd.attacked ) then
call SetUnitExtraArmor( dd.attacked, dd.id )
endif
call UnitDamageTarget( dd.attacker, dd.attacked, dd.dmg, true, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
call TimerStart( st.trix, 0.01, false, function Remove_Sun_Shell_Timer_Expires ) // утилизация триггера.
set trig = null
return
endfunction
function Trig_Lava_Spawn_Actions takes nothing returns nothing
local unit LavaSpawn
local unit enemy
local TriggerData st
local boolean bStrike = true
if GetTriggerEventId( ) == EVENT_PLAYER_UNIT_SPELL_EFFECT then // автокаст применен через хоткей
set LavaSpawn = GetSpellAbilityUnit( )
set enemy = GetSpellTargetUnit( )
else // автоматическое применение
set LavaSpawn = GetAttacker( )
set enemy = GetTriggerUnit( )
set bStrike = GetUnitState( LavaSpawn, UNIT_STATE_MANA ) > ( 15.00 * GetUnitAbilityLevel( LavaSpawn, 'A0B6' ) ) and GetUnitUserData( LavaSpawn ) > 0 and GetUnitAbilityLevel( LavaSpawn, 'BNso' ) < 1
endif
if bStrike then // проверка был ли применен автокаст, чтобы создать триггер детектор урона.
set st = TriggerData.create( )
set st.trg = CreateTrigger( )
set st.trix = CreateTimer( )
set st.trc = TriggerAddCondition( st.trg, Condition( function Trig_Incinerate_Conditions ) )
set st.tra = TriggerAddAction( st.trg, function Init_Trig_Incinerate )
set st.attacker = LavaSpawn
set st.attacked = enemy
set st.IsCheck = false
call SetDataBX( st.trg, st )
call SetDataBX( st.trix, st )
call TriggerRegisterUnitEvent( st.trg, enemy, EVENT_UNIT_DAMAGED )
call TriggerRegisterUnitEvent( st.trg, enemy, EVENT_UNIT_DEATH )
call TriggerRegisterUnitEvent( st.trg, LavaSpawn, EVENT_UNIT_ISSUED_ORDER )
call TimerStart( st.trix, 0.25, false, function Timer_LavaSpawn_Stop_Check )
endif
set LavaSpawn = null
set enemy = null
endfunction
//===========================================================================
function InitTrig_Lava_Spawn takes nothing returns nothing
set gg_trg_Lava_Spawn = CreateTrigger( )
call DisableTrigger( gg_trg_Lava_Spawn )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Lava_Spawn, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddCondition( gg_trg_Lava_Spawn, Condition( function Trig_Lava_Spawn_Conditions ) )
call TriggerAddAction( gg_trg_Lava_Spawn, function Trig_Lava_Spawn_Actions )
endfunction
» WarCraft 3 / Как сделать так, что-бы юнит терял ману при атаке.
» WarCraft 3 / Вылетает карта
» WarCraft 3 / Изменение закодированной карты
Да и вы бы лучше бы сами учились чето делать, тогда бы все сделали и улыбались, не пришлось бы бегать за кодерами.
» World of WarCraft / Естественная кожа у Северных Волков и Оргрима вне фильма
» WarCraft 3 / а как играть в доту 1 с ботами?
Т.к айкап решил что он сам себе на уме, для их доты ИИ версии никто не делал, поэтому только 6.83 фрога с Ии брать.
» WarCraft 3 / Отдать приказ юнитам через способность
» WarCraft 3 / Как создать способность которая отключает регенерацию врага?
» WarCraft 3 / Local unit
» WarCraft 3 / Способность Могильщика Закопаться\Выкопаться
» WarCraft 3 / Юнит просвечивается стреляя издалека
» WarCraft 3 / Как добавить спелл герою чтобы он его прокачивал?
» WarCraft 3 / Предметы, интересные баги и фитчи!
Но можите погуглить, бага очень известная в кругах дотеров, и видосов по ней было тонны как и бага с хуком пуджа.
» WarCraft 3 / Большой вопрос по морфу героев
» WarCraft 3 / Warcraft 3 не видит некоторые карты
» WarCraft 3 / Обнуление урона в ивенте UNIT_DAMAGED
» WarCraft 3 / Рикошет как в варлоках
))
Как то давно для своей карты делал, ang текущий угол юнита (или что там у тебя) cx-cy - координаты юнита (или что там у тебя(, dx-dy координаты препятствия, т.е того от чего идет рикошет.
» WarCraft 3 / Как добавить способность гальванизированным юнитам?
» WarCraft 3 / Почему не работает код
» WarCraft 3 / Посоветуйте что прочесть про динамическое создание триггеров
» WarCraft 3 / Убрать анимацию атаки у сплеша
» WarCraft 3 / Циклы и wait
» WarCraft 3 / Где сейчас можно скачать Warcraft 3 1.26a?
» WarCraft 3 / X-deprotect
» WarCraft 3 / Юнит, снижающий броню при уроне
SetDataBX - можешь заменить хештаблицей, SaveInteger( Hashtable, GetHandleId( некий обьект), 0, значение)
Ред. quq_CCCP
» WarCraft 3 / Юнит, снижающий броню при уроне