После того, как смог запустить мемхак, создал там триггер с событием "Юнит Атакован" и проверял функции. Первом делом проверил функцию SetUnitAttackSpeed ( u, 150 ), но после 2 удара герой начинает бить на макс. скорости. Попробовал поставить SetUnitAttackSpeed ( u, 0,01 ), это тоже не помогло
Потом, после неудачи со скоростью, попробовал AddUnitArmour ( u, 1 ) - функция не работает! Сидел около 2 мин и бил героя, но защита не хотела увеличиваться.
Дальше, идет функция AddUnitBonusDamage( u, 10 ) - она баганая, урон прибавляется после каждых 3-5 ударов, если сделать около 20-30, то урон увеличится 4-6 раза и урон не бонусный (зеленый) а кости (белый)
//! nocjass
library TestHookedDamageEvent
    globals
        group gMain         = CreateGroup( )
        unit uTemp          = null
        trigger trTemp      = null
    endglobals

    function GetDamageId takes integer dmg_t returns integer
        return log( dmg_t, 2 ) // Gets base 2 logarithm of WeaponType.
    endfunction

    function Damaged_Handler takes unit source, unit target, real dmg returns nothing
        local integer evnt  = GetDamageEventESPData( )
        local integer data  = ReadRealMemory( evnt + 0x00 )
        local real init_dmg = CleanReal( IndexToReal( ReadRealMemory( evnt + 0x04 ) ) )
        local integer pMod  = ReadRealMemory( evnt + 0x08 ) // Pointer to parametres or flag saved by damage source, results may vary!
        local integer flags = ReadRealMemory( data + 0x0C )
        local real real_dmg = CleanReal( IndexToReal( ReadRealMemory( data + 0x10 ) ) )
        local integer wpn_t = ReadRealMemory( data + 0x04 )
        local integer dmg_t = ReadRealMemory( data + 0x14 ) // Use GetDamageTypeByAddr( dmg_t ) to get Damage Type id.
        local integer atk_t = ReadRealMemory( data + 0x20 )

        // Attack Types: Spell = 0, Normal = 1, Piercing = 2, Siege = 3, Magic = 4, Chaos = 5, Hero = 6
        // Weapon Types: Melee = 0, Instant = 1, Ranged = 2, ?? = 3, ?? = 4, Splash = 5, Bounce = 6, ?? = 7, ?? = 8
        // 0x4 - DO NOT DEAL DAMAGE (?) | 0x8 - Multishot | 0x10 - Projectile | 0x20 - Penetrates invulnerability
        // 0x40 - DO NOT cause "unit attacked" for the owner (red blinking) (cleave & splash use it!)
        // 0x100 - Melee | 0x101 - Ranged
        // 0x200 - DO NOT cause "unit attacked" for the owner (minimap ping, etc) used in Cyclone (land), hex (end), etc, not sure
        // plain 0x40 == cleave, 0x141 == splash | 0x80 - autocast modifier? | 0x10 - slow aura flag (not a relevant damage? nullify any damage value)
        // Damage Types: ConvertDamageType( i ) = 2 ^ i => ConvertDamageType( 5 ) = 2 ^ 5 = 32 = DAMAGE_TYPE_ENHANCED | Thus reverse is MathLog( 32, 2 ) => 5

        if false then // Miscellaneous Checks
            if init_dmg == 0. and real_dmg == 0. and flags == 0x10 and pMod == ConvertHandle( target ) then // Check WindWalk | Thunderbolt
                
            endif
            
            if real_dmg == 0. and flags == 1 and atk_t == 0 and dmg_t == 0x20 and GetUnitAbilityLevel( source, 'AEfk' ) > 0 then // Check Fan of Knives based on Id.
                // Change 'NONE' to your Fan of Knives id, to check if damage was caused by it.
            endif
        endif

        if ( IsFlagBitSet( flags, 0x100 ) or IsFlagBitSet( flags, 0x101 ) ) and atk_t != 0 then // Non-Spell Damage
            call DisplayTextToPlayer( GetLocalPlayer( ), 0, 0, "Attack Type: " + I2S( atk_t ) )
            call DisplayTextToPlayer( GetLocalPlayer( ), 0, 0, "Damage Type: " + I2S( dmg_t ) )
            call DisplayTextToPlayer( GetLocalPlayer( ), 0, 0, "Weapon Type: " + I2S( wpn_t ) )
        endif
    endfunction

    function Damage_Event takes nothing returns nothing
        call DisableTrigger( GetTriggeringTrigger( ) )
        call Damaged_Handler( GetEventDamageSource( ), GetTriggerUnit( ), GetEventDamage( ) )
        call EnableTrigger( GetTriggeringTrigger( ) )
    endfunction
endlibrary

function InitTrig_TestHookedDamageEvent takes nothing returns nothing
    if true then // Init Damaged Event
        set trTemp = CreateTrigger( )
        call GroupEnumUnitsInRect( gMain, GetWorldBounds( ), null )
        loop
            set uTemp = FirstOfGroup( gMain )
            exitwhen uTemp == null
            call TriggerRegisterUnitEvent( trTemp, uTemp, EVENT_UNIT_DAMAGED )
            call GroupRemoveUnit( gMain, uTemp )
        endloop
        call TriggerAddAction( trTemp, function Damage_Event )
    endif
endfunction
//! endnocjass
Как можно проверку удара перенести в другой триггер не копи-пастом, а чтобы использовать для вычисления кол-во ударов (для спела) по дефолту, Я делаю 2 триггера, это запись всех юнитов на событие "Получает урон" и Действие.
Мне нужно только мемхаки Unit API, Ability API, Item API, Group API, Agent API, а остальное не нужно какие триггеры нужно копировать с этими мемхаками.
Пожалуйста поясните эти вещи, если не сложно.

Не все функции мх работают быстро или как положено/ожидаемо, помимо указанных Api тебе нужно ещё закинуть триггеры, которые эти либы юзают. Просто юзай функции и смотри как работают, можешь попробовать SetUnitArmour( u, GetUnitArmour( u )+1 ), хз. Enable/DisableUnitControl тоже со странностями, отбирает иконки у юнита навсегда если юзать первый аргумент, если только последние три, то можно вернуть отдав юниту какой-либо приказ
`
ОЖИДАНИЕ РЕКЛАМЫ...
28
Не все функции мх работают быстро или как положено/ожидаемо, помимо указанных Api тебе нужно ещё закинуть триггеры, которые эти либы юзают. Просто юзай функции и смотри как работают, можешь попробовать SetUnitArmour( u, GetUnitArmour( u )+1 ), хз. Enable/DisableUnitControl тоже со странностями, отбирает иконки у юнита навсегда если юзать первый аргумент, если только последние три, то можно вернуть отдав юниту какой-либо приказ
Принятый ответ
8
Если я не ошибаюсь, событие "юнит атакован" срабатывает уже после начала замаха у атакующего, там ему уже все равно, какую ты поставишь ему скорость атаки, он будет замахиваться столько, сколько запомнил, с кд атаки также.
Функции добавления защиты и атаки не обновляют соответствующие цифирки. Перевыделение юнита или обновление соотв. информации все решат.
Добавлять зеленую атаку нельзя, насколько я помню, напрямую, нужно редактировать бонус от абилки когтей, при прямом изменении лишние бонусы сложатся в белую атаку.
Оставить нужные тебе api можно просто не копируя лишние - тебе понадобится скопировать только init и нужные тебе api, В init отключить функции инициализации лишних api.
32
Ну ты показываешь наработку для детекта урона, там все исчерпывающе. Триггер с событием урона всем на карте, в этом триггере ты можешь проверить тип урона, тип атаки, и прочие параметры.
11
Смотри, я делал способность с накопительным эффектом от ударов, механика та же самая.
Пример
//! nocjass
library Horror requires MemoryHackDamageEventHook
    globals
        group HorrorGroup   = CreateGroup()
    endglobals
    
    function HorrorCheckGroup takes nothing returns nothing
        local real HorrorTime = LoadReal(H, GetHandleId(GetEnumUnit()), StringHash("HorrorTime"))
        local effect HorrorEffect = LoadEffectHandle(H, GetHandleId(GetEnumUnit()), StringHash("HorrorEffect"))
        local unit Isazam = LoadUnitHandle(H, GetHandleId(GetEnumUnit()), StringHash("Isazam"))
        local real TargetX = GetUnitX(GetEnumUnit())
        local real TargetY = GetUnitY(GetEnumUnit())
        local real IsazamX = GetUnitX(Isazam)
        local real IsazamY = GetUnitY(Isazam)
        local integer HorrorQuest = LoadInteger(H, GetHandleId(Isazam), StringHash("HorrorQuest"))
        
        if HorrorTime >= 20 then
            set HorrorQuest = 1
            call SaveInteger(H, GetHandleId(Isazam), StringHash("HorrorQuest"), HorrorQuest)
        endif
        
        if SquareRoot((IsazamX - TargetX) * (IsazamX - TargetX) + (IsazamY - TargetY) * (IsazamY - TargetY)) >= 700 then //Указываем желаемую дальность увеличенного снижения ужаса
            set HorrorTime = HorrorTime - 1.5
        else
            set HorrorTime = HorrorTime - 1
        endif
                
        if HorrorTime <= 0 then
            call DestroyEffect(HorrorEffect)
            call GroupRemoveUnit(HorrorGroup, GetEnumUnit())
            set HorrorTime = 0
        else
            call PingMinimapEx(TargetX, TargetY, 1, 255, 0, 0, false)
        endif
        
        call SaveReal(H, GetHandleId(GetEnumUnit()), StringHash("HorrorTime"), HorrorTime)
        
        set HorrorEffect = null
        set Isazam = null
    endfunction
    
    function HorrorCheckAction takes nothing returns nothing
        call ForGroup(HorrorGroup, function HorrorCheckGroup)
    endfunction

    function Damaged_Handler takes unit source, unit target, real dmg returns nothing
        local integer evnt  = GetDamageEventESPData()
        local integer data  = ReadRealMemory(evnt + 0x00)
        local real init_dmg = CleanReal(IndexToReal(ReadRealMemory(evnt + 0x04)))
        local integer flags = ReadRealMemory(data + 0x0C)
        local integer atk_t = ReadRealMemory(data + 0x20)
        local real HorrorTime = LoadReal(H, GetHandleId(target), StringHash("HorrorTime"))
        local effect HorrorEffect
        local unit Isazam
        local integer HorrorQuest = LoadInteger(H, GetHandleId(source), StringHash("HorrorQuest"))
        
        if GetUnitTypeId(source) == 'U000' then // Ставим свой ID Исазама
            call SaveReal(H, GetHandleId(target), StringHash("HorrorTime"), HorrorTime + 2 + HorrorQuest)
            if HorrorTime <= 0 then
                set HorrorEffect = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\UnholyFrenzy\\UnholyFrenzyTarget.mdl", target, "chest")
                call SaveEffectHandle(H, GetHandleId(target), StringHash("HorrorEffect"), HorrorEffect)
                call SaveUnitHandle(H, GetHandleId(target), StringHash("Isazam"), source)
                call GroupAddUnit(HorrorGroup, target)
            elseif (IsFlagBitSet(flags, 0x100) or IsFlagBitSet(flags, 0x101)) and atk_t != 0 and HorrorTime > 0 then
                set HorrorEffect = AddSpecialEffectTarget("Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl", source, "origin")
                call DestroyEffectTimer(HorrorEffect, 0.3)
                call SetUnitState(source, UNIT_STATE_LIFE, (GetUnitState(source, UNIT_STATE_LIFE) + init_dmg * 0.2))
            endif
        endif
        
        set HorrorEffect = null
        set Isazam = null
    endfunction

    function Damage_Event takes nothing returns nothing
        call DisableTrigger( GetTriggeringTrigger( ) )
        call Damaged_Handler( GetEventDamageSource( ), GetTriggerUnit( ), GetEventDamage( ) )
        call EnableTrigger( GetTriggeringTrigger( ) )
    endfunction
endlibrary

function InitTrig_Horror takes nothing returns nothing
    local group gMain = CreateGroup()
    local unit uTemp 
    local trigger trTemp = CreateTrigger()
    local trigger HorrorCheck = CreateTrigger()
    
    if true then
        call GroupEnumUnitsInRect( gMain, bj_mapInitialPlayableArea, null )
        loop
            set uTemp = FirstOfGroup( gMain )
            exitwhen uTemp == null
            call TriggerRegisterUnitEvent( trTemp, uTemp, EVENT_UNIT_DAMAGED )
            call GroupRemoveUnit( gMain, uTemp )
        endloop
        call TriggerAddAction( trTemp, function Damage_Event )
    endif
    
    call TriggerRegisterTimerEvent(HorrorCheck, 1, true)
    call TriggerAddAction(HorrorCheck, function HorrorCheckAction)
    
    call DestroyGroup(gMain)
    
    set gMain = null
    set trTemp = null
    set HorrorCheck = null
endfunction

Мне нужно только мемхаки Unit API, Ability API, Item API, Group API, Agent API, а остальное не нужно какие триггеры нужно копировать с этими мемхаками.
Так просто удали остальные триггеры и в триггере InitMemoryHack удали вызов к нимм
Чтобы оставить комментарий, пожалуйста, войдите на сайт.