Добавлен , опубликован
Способ реализации:
Версия Warcraft:
Для чайников не подойдет, тут нужно хоть какое то понимание JASS и последняя версия мемхака от Unryze, поэтому я специально не буду делать подробных инструкций. Сделал недавно демедж хендлер для своей карты Naruto Legend, который сначала обнуляет весь урон, потом считывает нужные модификаторы и в конце наносит его. Решил поделиться решением. Если найдете баг - можете смело писать в комментарии, поправлю.
DamageHandlerAct нужно вызывать через ивент EVENT_UNIT_DAMAGED
`
ОЖИДАНИЕ РЕКЛАМЫ...
Этот комментарий удален
32
Хм, а миссы же до урона рисуются, как и спелл нигейшин срабатывет?
7
quq_CCCP, Эта система отлавливает нанесенный урон в ивенте EVENT_UNIT_DAMAGED, потом смотрит были ли миссы и если дамаг проходит по всем проверкам, то амплифаит его и затем снова наносит, предварительно обнулив исходный дамаг функцией ClearHandledDamage. Урон нанесенный в хендлере он не отловит, нужно будет использовать таймер 0.0, но это база.
Я ответил на вопрос или я не понял его?
32
SAND, просто миссы до начала начала события урона срабатывают, я вот юзал хак на успешное завершение атаки чтобы сделать промахи и их отключение...
7
quq_CCCP, А ты про это, как я знаю этот хак работает адекватно только для 1.26a патча, ну через демедж такой же эффект, один фиг обнуляю же урон
32
SAND, ну я вот для доты такой хак юзаю:
function InitAttackDamageCalculationHook takes integer pTriggerHandle returns nothing
    local integer old1 = RMem( pMeleeAttackCatcher )
    local integer old2 = RMem( pMeleeAttackCatcher + 4 )
    local integer oldprotection = ChangeOffsetProtection( pMeleeAttackCatcher, 8, 0x40 )
    
    call WMem( pReservedMemoryForMeleeAttackHook + 0, 0x30498B60 )
    call WMem( pReservedMemoryForMeleeAttackHook + 4, 0x000000BB )
    call WMem( pReservedMemoryForMeleeAttackHook + 8, 0xE80B8900 )
    call WMem( pReservedMemoryForMeleeAttackHook + 5, DataArray1Address + 260 )// source address
    call WMem( pReservedMemoryForMeleeAttackHook + 12, ( pToJUnit ) - ( pReservedMemoryForMeleeAttackHook + 12 ) - 4 )
    call WMem( pReservedMemoryForMeleeAttackHook + 16, 0x000000BB )
    call WMem( pReservedMemoryForMeleeAttackHook + 20, 0x61038900 )
    call WMem( pReservedMemoryForMeleeAttackHook + 17, pGlobalUnitArrayForDataPassing + 12 )// source l__udg_GlobalUnitArrayForDataPassing[3]
    call WMem( pReservedMemoryForMeleeAttackHook + 24, 0x6C798160 )
    call WMem( pReservedMemoryForMeleeAttackHook + 28, 0xFFFFFFFF )
    call WMem( pReservedMemoryForMeleeAttackHook + 32, 0xC1833a74 )
    call WMem( pReservedMemoryForMeleeAttackHook + 36, 0x0000E86C )
    call WMem( pReservedMemoryForMeleeAttackHook + 40, 0xC88B0000 )
    call WMem( pReservedMemoryForMeleeAttackHook + 38, pGetAgentInternal - ( pReservedMemoryForMeleeAttackHook + 38 ) - 4 )
    call WMem( pReservedMemoryForMeleeAttackHook + 44, 0x000000B8 )
    call WMem( pReservedMemoryForMeleeAttackHook + 48, 0x8B088900 )
    call WMem( pReservedMemoryForMeleeAttackHook + 45, DataArray1Address + 264 )//66 target address
    call WMem( pReservedMemoryForMeleeAttackHook + 52, 0x1C5B8B19 )
    call WMem( pReservedMemoryForMeleeAttackHook + 56, 0x00BBD3FF )
    call WMem( pReservedMemoryForMeleeAttackHook + 60, 0x89000000 )
    call WMem( pReservedMemoryForMeleeAttackHook + 59, DataArray1Address + 268 )//67 target type
    call WMem( pReservedMemoryForMeleeAttackHook + 64, 0x00E89003 )
    call WMem( pReservedMemoryForMeleeAttackHook + 68, 0xBB000000 )
    call WMem( pReservedMemoryForMeleeAttackHook + 67, pToJUnit - ( pReservedMemoryForMeleeAttackHook + 67 ) - 4 )
    call WMem( pReservedMemoryForMeleeAttackHook + 72, pGlobalUnitArrayForDataPassing + 16 )//4 target handle
    call WMem( pReservedMemoryForMeleeAttackHook + 76, 0x00BB0389 )
    call WMem( pReservedMemoryForMeleeAttackHook + 80, 0xC7000000 )
    call WMem( pReservedMemoryForMeleeAttackHook + 79, DataArray1Address + 272 )//68 result
    call WMem( pReservedMemoryForMeleeAttackHook + 84, 0x00000103 )
    call WMem( pReservedMemoryForMeleeAttackHook + 88, 0x0BEB9000 )
    call WMem( pReservedMemoryForMeleeAttackHook + 92, 0x000000BB )
    call WMem( pReservedMemoryForMeleeAttackHook + 96, 0x0003C700 )
    call WMem( pReservedMemoryForMeleeAttackHook + 93, DataArray1Address + 272 )//68 result
    call WMem( pReservedMemoryForMeleeAttackHook + 100, 0x61000000 )
    call WMem( pReservedMemoryForMeleeAttackHook + 104, 0x90909060 )
    call WMem( pReservedMemoryForMeleeAttackHook + 108, 0x00000068 )
    call WMem( pReservedMemoryForMeleeAttackHook + 112, 0x0000B800 )
    call WMem( pReservedMemoryForMeleeAttackHook + 109, pTriggerHandle )
    call WMem( pReservedMemoryForMeleeAttackHook + 116, 0xD0FF0000 )
    call WMem( pReservedMemoryForMeleeAttackHook + 114, pTriggerExecute )
    call WMem( pReservedMemoryForMeleeAttackHook + 120, 0x6104C483 )
    call WMem( pReservedMemoryForMeleeAttackHook + 124, 0x8B575651 )
    call WMem( pReservedMemoryForMeleeAttackHook + 128, 0xB8BE8BF1 )
    call WMem( pReservedMemoryForMeleeAttackHook + 132, 0x8B000002 )
    call WMem( pReservedMemoryForMeleeAttackHook + 136, 0x00ACBE84 )
    call WMem( pReservedMemoryForMeleeAttackHook + 140, 0x84030000 )
    call WMem( pReservedMemoryForMeleeAttackHook + 144, 0x0000A0BE )
    //call WMem( pReservedMemoryForMeleeAttackHook + 148, 0x8C860300 )
    //call WMem( pReservedMemoryForMeleeAttackHook + 152, 0x8B000000 )
    
    //call WMem( pReservedMemoryForMeleeAttackHook + 156, 0x00008C8E )
    //call WMem( pReservedMemoryForMeleeAttackHook + 160, 0x988E8900 )
    //call WMem( pReservedMemoryForMeleeAttackHook + 164, 0xC7000000 )
    
    //call WMem( pReservedMemoryForMeleeAttackHook + 168, 0x00008C86 )
    //call WMem( pReservedMemoryForMeleeAttackHook + 172, 0x00000000 )
    call WMem( pReservedMemoryForMeleeAttackHook + 148, 0xBE8C8B00 )
    call WMem( pReservedMemoryForMeleeAttackHook + 152, 0x00000094 )
    call WMem( pReservedMemoryForMeleeAttackHook + 156, 0x88BE948B )
    call WMem( pReservedMemoryForMeleeAttackHook + 160, 0xE9000000 )
    call WMem( pReservedMemoryForMeleeAttackHook + 164, ( pMeleeAttackRetun ) - ( pReservedMemoryForMeleeAttackHook + 164 ) - 4 )
    
    call WMem( pMeleeAttackCatcher, 0xE9E9E9E9 )
    call WMem( pMeleeAttackCatcher + 4, 0x90909090 )
    
    call WMem( pMeleeAttackCatcher + 1, pReservedMemoryForMeleeAttackHook - pMeleeAttackCatcher - 5 )
    
    call ChangeOffsetProtection( pMeleeAttackCatcher, 8, oldprotection )
endfunction

function OnAttackerDeath takes nothing returns boolean
    local unit dying = GetTriggerUnit( )
    local integer id
    if IsUnitInGroup( dying, MissGroup ) then
        set id = GetHandleId( dying )
        call GroupRemoveUnit( MissGroup, dying )
        call RemoveSavedInteger( HashData, ExMissPrdKey, id )
        call RemoveSavedReal( HashData, ExMissCdTime, id )
    endif
    
    if GetUnitTypeId( dying ) =='Opgh' and IsUnitIllusion( dying ) then
        set id = GetHandleId( dying )
        call RemoveSavedInteger( HashData, id, 823 )
        call RemoveSavedReal( HashData, ExCounerBool, id )
    endif
    if IsUnitType( dying, UNIT_TYPE_SAPPER ) then
        call UnitRemoveType( dying, UNIT_TYPE_SAPPER )
        call RemoveSavedInteger( HashData, ExMultishoTarg, GetHandleId(dying) )
    endif

    set dying = null
    return false
endfunction

function InitMMEhack takes nothing returns nothing
    local trigger trig
    call PresetSomeArray( )
    set pReservedMemoryForMeleeAttackHook = pfast_call_1 + 300
    set pGlobalUnitArrayForDataPassing = RMem( GetUnitArrayAddress( ) + 0xC )
    set DataArray1Address = RMem( GetDataArrayAAddress( ) + 0xC )
    set OnAttack = CreateTrigger( )
    call TriggerAddAction( OnAttack, function OnAttackDamageActions )
    call InitAttackDamageCalculationHook( GetHandleId( OnAttack ) )
    set DummyBlinder = CreateUnit( Player( 15 ), DUMMY, 0.00, 0.00, 270.00 )
    call UnitAddAbility( DummyBlinder, 'A15A' )
    set trig = CreateTrigger( )
    set MissGroup = CreateGroup( )
    call TriggerAddCondition( trig, Condition( function OnAttackerDeath ) )
    call TriggerRegisterPlayerUnitEvent( trig, Player( 0 ), EVENT_PLAYER_UNIT_DEATH, null )
    call TriggerRegisterPlayerUnitEvent( trig, Player( 1 ), EVENT_PLAYER_UNIT_DEATH, null )
    call TriggerRegisterPlayerUnitEvent( trig, Player( 2 ), EVENT_PLAYER_UNIT_DEATH, null )
    call TriggerRegisterPlayerUnitEvent( trig, Player( 3 ), EVENT_PLAYER_UNIT_DEATH, null )
    call TriggerRegisterPlayerUnitEvent( trig, Player( 4 ), EVENT_PLAYER_UNIT_DEATH, null )
    call TriggerRegisterPlayerUnitEvent( trig, Player( 5 ), EVENT_PLAYER_UNIT_DEATH, null )
    call TriggerRegisterPlayerUnitEvent( trig, Player( 6 ), EVENT_PLAYER_UNIT_DEATH, null )
    call TriggerRegisterPlayerUnitEvent( trig, Player( 7 ), EVENT_PLAYER_UNIT_DEATH, null )
    call TriggerRegisterPlayerUnitEvent( trig, Player( 8 ), EVENT_PLAYER_UNIT_DEATH, null )
    call TriggerRegisterPlayerUnitEvent( trig, Player( 9 ), EVENT_PLAYER_UNIT_DEATH, null )
    call TriggerRegisterPlayerUnitEvent( trig, Player( 10 ), EVENT_PLAYER_UNIT_DEATH, null )
    call TriggerRegisterPlayerUnitEvent( trig, Player( 11 ), EVENT_PLAYER_UNIT_DEATH, null )
    call TriggerRegisterPlayerUnitEvent( trig, Player( 12 ), EVENT_PLAYER_UNIT_DEATH, null )
    call TriggerRegisterPlayerUnitEvent( trig, Player( 15 ), EVENT_PLAYER_UNIT_DEATH, null )
    set trig = null
endfunction
4
Зачем нужен мемхак, если есть Damage Engine? Я прописал на нем все модификаторы урона, включая криты, миссы, отжор и орбы, с возможностью динамической смены % в любой момент.
7
MACOH, чтобы не использовать везде таймер 0.0 для правильного скейлинга критов сплеша и тд, если не понял о чем я - то мне впадлу тебе объяснять про это. Да и тут все наносится одним действием, без костылей в виде использования хила для блока дамага, тк урон можно адекватно очистить только через мемхак/ужапи. Я долго искал способ очистки дамага на мемхаке, спрашивал многих специалистов, но в итоге нашел сам и решил поделиться
4
SAND, тем не менее, костыльная система работает и гораздо более гибкая/безопасная. К тому же большинство популярных платформ мемхак не поддерживают.
7
MACOH, в каком месте она более гибкая/безопасная xD. у меня почему -то нет фаталов в карте из за этой системы. хотя карта имеет большой онлайн и игр с этой системой было сыграно +-500 , я перед тем как публиковать ее потестил. Какие именно платформы не поддерживают мемхак?? . Ирина и айкап поддерживают ну и китайский KK!. а на рефе играют только пиндосы и сумасшедшие
4
SAND, Использование мемхака априори опаснее, чем использование стандартного встроенного функционала. В Damage Engine встроен удобный базовый функционал, который позволяет совершать действия до/во время/после нанесения урона, а так же защита от рекурсии. Плюс поддержка гуёв, кому нужно. Работает почти без проблем (есть маленькие недостатки, к которым пришлось придумать обходные пути). Ирина давно грозится запретить карты с мемхаком, оставив только ужопу, а где ты на айкапе нашел поддержку мемхака, учитывая, что у них свой собственный лаунчер, я хз.
1
Но, к сожалению, ты будешь закрывать глаза на баги и проблемы при использовании костылей
SAND, Ты сейчас себе в ногу стреляешь, ведь сам используешь такое же древнее костыльное г* )))
Ну а MACOH вообще какой-то непонятный вброс кинул с DE, когда возможный функционал мемговна этим не ограничивается...
4
DiZzicH, ну, я конкретно про представленную систему, смысла я в ней особого не вижу, когда есть альтернативы.
4
Дружок - пирожок, ну ты магний б6 попей чтоль, что ж тебя понесло то так... И кто тебе сказал, что я пишу на гуях?) Пишу на ZinC, твой любимый чистоджасс давно никому не интересен.
По поводу твоего вброса, ты когда поделку свою выкладываешь замечательную, будь готов, что люди будут сравнивать с существующими аналогами и задавать соответствующие вопросы. Если ты не готов к такому взаимодействию - лучше ничего не выкладывай, пожалей нервы. Я тебе сказал, что DE прекрасно справляется с
функциями по нанесению урона и дружелюбен к пользователю. Чем твое изделие выгодно отличается? То что мемхак многое может я в курсе, как это отражено в твоей системе?
2 пункта от Narberal Gamma: 2.2 Провокация других пользователей на нарушение правил. Прекращайте срач
1
MACOH, Смысл в ней есть. Если уже начал использовать мемхак во всю, то желание использовать костыли на глобалках и нулевом таймере отпадает. Да и сам автор написал, что наработка для уверенных пользователей jass и мемхака, так что твоё рвение доказать превосходство DE ещё более неуместно...
4
DiZzicH, если и делать подобное, то на ужопе. К мемхаку у меня отношение прохладное, мягко говоря, тем более учитывая основную аудиторию раздела наработок.
1
MACOH, И опять же наработка сделана на базе мемхака для людей, которые по каким-то причинам (чаще консервативным) его и используют. Мнение о том что и как делать и что использовать тут никто не спрашивает, поэтому я до сих пор не понимаю к чему весь этот срач.
4
DiZzicH, ну, я имею право оценивать и обсуждать ресурс, находящийся в общем доступе. И срач не я начал)
Чтобы оставить комментарий, пожалуйста, войдите на сайт.