,

Новый детект физического урона на мемхаке

» опубликован
» Способ реализации: Jass
» Тип: Алгоритм
» Версия Warcraft: 1.26a - 1.27a, не тестировалось на более ранних версиях.
Собственно небольшая библиотека требующая немного модифицированный мемхак второй версии (прилагается в тест карте), ну и немного терпения, которая добавить возможность проверять тип урона, атаки, типа атаки, флагов атаки, начального урона без резистов во всех триггерах вашей карты срабатывающих на событие EVENT_UNIT_DAMAGED.
» Код библиотеки
library MHDamage requires Memory, Utils

    globals
        private constant integer MAX_DAMAGE_STACK_SIZE = 1024
        private integer pDamageStack = 0
        private integer pDamageHook = 0
    endglobals

// Максимальное количество одновременных событий урона.
    function GetDamageEventESPData takes nothing returns integer
        local integer Length = RMem( pDamageStack )
	
        if ( Length > 0 ) then
            return RMem( pDamageStack + $04 + $04 * ( Length - 1 ) )
        endif
	
        return 0
    endfunction

    function InitHack takes nothing returns nothing
    // hook
        local integer CUnit_VMT = GameDLL + $931934
        local integer pSlot72 = CUnit_VMT + ( $04 * 72 )
    
        local integer OldProtection = ChangeOffsetProtection( pSlot72, 4, 0x40 )
        local integer PreviousMethod = RMem( pSlot72 )
        set pDamageStack = malloc( $04 + $04 * MAX_DAMAGE_STACK_SIZE )
        set pDamageHook = AllocateExecutableMemory( 1 * 1024 )
    
        call WMem( pSlot72, pDamageHook )
    
        call ChangeOffsetProtection( pSlot72, 4, OldProtection )
    
    // init code
    
        call WMem( pDamageHook + $00, $8DE58955 )
        call WMem( pDamageHook + $04, $53F82464 )
        call WMem( pDamageHook + $08, $B8F84D89 )
        call WMem( pDamageHook + $0C, pDamageStack )
        call WMem( pDamageHook + $10, $89044D8D )
        call WMem( pDamageHook + $14, $89138BC3 )
        call WMem( pDamageHook + $18, $8304904C )
        call WMem( pDamageHook + $1C, $4D8B0103 )
        call WMem( pDamageHook + $20, $1475FFF8 )
        call WMem( pDamageHook + $24, $8B1075FF )
        call WMem( pDamageHook + $28, $8B500C45 )
        call WMem( pDamageHook + $2C, $B8500845 )
        call WMem( pDamageHook + $30, PreviousMethod )
        call WMem( pDamageHook + $34, $4589D0FF )
        call WMem( pDamageHook + $38, $012B83FC )
        call WMem( pDamageHook + $3C, $5BFC458B )
        call WMem( pDamageHook + $40, $0010C2C9 )
    endfunction

endlibrary
Как видим библиотака с несколькими функциями, после её запуска можно будет делать так:
function Trig_Damage_Test_Conditions takes nothing returns boolean
    return GetEventDamage() > 0.00
endfunction

function Trig_Damage_Test_Actions takes nothing returns nothing
    local integer ESP = GetDamageEventESPData()
    local integer Data = RMem(ESP + $08) // second argument
    local real Amount = mI2R( RMem(Data + $10) )
    local integer WeaponType = RMem(Data + $04)
    local integer DamageType = RMem(Data + $14)
    local integer AttackType = RMem(Data + $20)
    local integer Flags = RMem( Data + 0x0C ) // 0x100 ближний бой, 0x101 дальний
    
    call BJDebugMsg("*** Damage info ***")
    call BJDebugMsg("Amount: " + R2S(Amount))
    call BJDebugMsg("WeaponType: " + I2S(WeaponType))
    call BJDebugMsg("DamageType: " + I2S(DamageType))
    call BJDebugMsg("AttackType: " + I2S(AttackType))
    call BJDebugMsg("Flags:"  + I2S( Flags ) )
endfunction

//===========================================================================
function InitTrig_Damage_Test takes nothing returns nothing
    set gg_trg_Damage_Test = CreateTrigger(  )
    call TriggerAddCondition( gg_trg_Damage_Test, Condition( function Trig_Damage_Test_Conditions ) )
    call TriggerAddAction( gg_trg_Damage_Test, function Trig_Damage_Test_Actions )
endfunction
Рассмотрим по подробнее:
    local integer ESP = GetDamageEventESPData()
    local integer Data = RMem(ESP + $08) // second argument
Это получения структуры в которой хранятся все данные об уроне на это событие урона.
 local real Amount = mI2R( RMem(Data + $10) )
Урон без учета резиста, все просто...
local integer WeaponType = RMem(Data + $04)
Это тип оружия, это вот тут используется:
native UnitDamageTarget takes unit whichUnit, widget target, real amount, boolean attack, boolean ranged, attacktype attackType, damagetype damageType, !!weapontype weaponType!! returns boolean 
Вот их столько:
Обратите внимание, weapontype в данном случаи получается в виде целочисленной переменной, их соотсветсвие можно глянуть в common.j или использовать ConverWeaponType
Идем далее:
local integer DamageType = RMem(Data + $14)
В данном случаи тип урона тоже представлен в виде целочисленной переменной, для преобразование в хендл damagetype модно юзать данный код:
» D2DT
function DT2DT takes integer k returns integer
    local integer i = 1
    if k == 0 then
        return 0
    endif
    loop
        exitwhen k / 2 <= 1
        set i = i + 1
        set k = k / 2
    endloop
    return i
endfunction

	//пример использования:
	ConvertDamageType(DT2DT(dmgTypeHex))==DAMAGE_TYPE_FIRE
local integer AttackType = RMem(Data + $20)
Это тип атаки юнита, причем тоже не хендл а целое чило, но тут все просто:
7 видов атаки, от 0 до 6, числовые значения можно превратить в хендлы с помощью нативки:
	constant native ConvertAttackType takes integer i returns attacktype
Ну и наконец флаги атаки:
 local integer Flags = RMem( Data + 0x0C )
Это целое число, а точнее сразу несколько слепленных в кучу, где каждое является флагом который что то означает, если Flags == 0x100 то это урон от атаки ближнего боя, 0х101 урон от атаки дальнего боя, многие способности ставят свои флаги на атаку, к примеру Стремительность ('AOwk' - windwalk ) - ставит флаг 0x500.
Ссылка на тестмап тут


Просмотров: 772

pro100master #1 - 3 месяца назад 2
если клон бьет то фаталит =)
DracoL1ch #2 - 3 месяца назад 2
без восстановления памяти вы угробите кучу карт
quq_CCCP #3 - 3 месяца назад 2
DracoL1ch, приложено, кстати надо будет описать.
Твоя старая восстанавливалка.
pro100master, лог фатала в студию, у меня ниче не фаталит, ни когда бьют иллюзии ни когда иллюзии бьют. Все работает исправно.
pro100master #4 - 3 месяца назад 2
прикреплены файлы