Эта тема жуется конечно уже вечно мною, но деваться некуда, выкладываю
Не получается, просто ничего не происходит заряды не добавляются
За основу взят вот этот материал xgm.guru/p/wc3/204295?postid=378427#comment6
  1. Поместил содержимое в триггер "utils"
  2. Сохранил, всё хорошо, ошибок нет
  3. Создаём болванчика который подгрузит нам
DracoL1ch:
где SentFountain - любой юнит, которому нужно вручить абилки для их подзагрузки; AEev - уклонение, чтобы взять адрес "нерабочей" кнопки, "A3HQ" - любая абилка на базе ракеты, тоже для получения адреса
  1. Запускаем через 2 секунды после старта игры
"Потом - если у ракеты 0 зарядов изначально, счетчик скрывается, поэтому"
call GetEvasionOrderIdFunctionData(gg_unit_n006_0003)
call FixChargesIndicator(gg_unit_n006_0003,'AEev') 
Далее юниту пытаемся дать заряды на абиле
call AddAbilityCharges(gg_unit_n006_0003,'AEev',2)
Ну и тоже самое для юнита для основного, проделываем и не проделываем, и так и таки в любом порядке.
Просто ничего не происходит, Господа отпишитесь, у кого удалось запустить эту фишку

Принятый ответ

тема абилки с зарядами. что-то код с мем хаком плодят разный
я эту фишку тестил. там по факту, значение меняется. Но визуально нет (не отрисовывается).
`
ОЖИДАНИЕ РЕКЛАМЫ...
4
27
5 лет назад
4
тема абилки с зарядами. что-то код с мем хаком плодят разный
я эту фишку тестил. там по факту, значение меняется. Но визуально нет (не отрисовывается).
Принятый ответ
0
32
5 лет назад
0
Steal nerves, тест карту с апающимся виндволком протестил, работает, полез в код, думаю и с пассивкой разберусь
4
16
5 лет назад
4
была же наработка с последней версией от CCCP, после манипуляций надо обновить экран юнита
4
27
5 лет назад
Отредактирован MpW
4
код 1
    //Перерисовывает коммандную панель юнита
    //Использует, если нужно обновить что-то. Например, обновить число зарядов абилки, сменить описание текста и прочее
    function RefreshUnitsCommandPanel takes unit u returns nothing
        set LastConvertedHandle = ConvertHandle( u )
        if LastConvertedHandle > 0 then
            call CallThisCallWith2Args( pRefreshUnitsCommandPanel, LastConvertedHandle, 852290 )
        endif
    endfunction
    //==========

//заряды к способности
//Работает это у таких способностей как осветительный снаряд Afla, сторожевая сова Aesn 
//у остальных абил не работает, просто не замечаем. Т.к. отключено отображение зарядов, и отсутствуют другие штрафы (не убавляются при юзе; когда кончаются, абила не пропадает)
//ячейка адреса "GetUnitAbility( u, id ) + 0x124" является просто счетчиком у абил, даже у обычных абил есть такой счетчик, просто не юзается нигде.
    //добавить к текущему количеству
    function AddAbilityCharges takes unit u, integer id, integer c returns nothing
        local integer a = GetUnitAbility( u, id )
        if a > 0 then
            call WMem( a + 0x124, RMem( a + 0x124 ) + c )
        endif
        call RefreshUnitsCommandPanel( u )//else changes will be visible only at next redraw
    endfunction
    //изменить текущее число зарядов на нужное число
    function SetCountAbilityCharges takes unit u, integer id, integer c returns nothing
        local integer a = GetUnitAbility( u, id )
        if a > 0 then
            call WMem( a + 0x124, c )
        endif
        call RefreshUnitsCommandPanel( u )//else changes will be visible only at next redraw
    endfunction
    //узнать текущее число зарядов
    function GetCountAbilityCharges takes unit u, integer id returns integer
        local integer a = GetUnitAbility( u, id )
        if a > 0 then
            return RMem( a + 0x124 )
        endif
        return 0
    endfunction
//======================
код 2 (код не полный)
//Редактирование зарядов способности (универсальный метод для всех)
//Некоторые переменные и данные инициируются в триггере Init Return Bug
//Можно редактировать не только активные способности, но и пассивки (по-крайне мере большая часть пассивок)
    function SaveUnlockWriteMemory takes integer a, integer val, boolean save, boolean unlock returns nothing
        local integer oldprotection 
        if unlock then
            set oldprotection = ChangeOffsetProtection(a,4,0x40)
        endif
        if save and unlock==false then
            call AddNewOffsetToRestore(a,RMem(a))
        endif
        call WMem(a,val)
        if unlock then
            call ChangeOffsetProtection(a,4,oldprotection)
        endif
    endfunction
//включает хук на эту абилку (основу) для отображения (короче обновляет, прорисовывает изменения)
//Это обязательная часть. После того, как установили настройки (задали число зарядов, включить/выключить отображение зарядов), у вас прорисовывают изменения (изменяются числа, и будут ли показываться числа в углу).
    function VisualChargesSystem_InitHookOnAbility takes unit u, integer id returns nothing
        local integer a
        local integer b
        set a=GetUnitAbility(u,id)
        if a!=0 then
            if RMem(RMem(a)+0x1C4)==GameDLL+0x378A0 then
                call SaveUnlockWriteMemory(RMem(a)+0x1C4,pCustomChargesDisplayer,true,true)
            elseif RMem(RMem(a)+0x1C4)==GameDLL+0x20AF0 then
                call SaveUnlockWriteMemory(RMem(a)+0x1C4,pCustomChargesDisplayer+40*4,true,true)
            else
                call BJDebugMsg("Unknown base ability, hook is not possible")
            endif
        endif
    endfunction
    
//отвечает за отображение зарядов
//с помощью хитросплетении, которых я не понимаю, эта хэш-таблица и пару переменных как-то влияют на отображение. с помощью хука InitHookOnAbility включает отображение каким-то образом. при чем не вижу связи
    //активирует отображение зарядов на этом id на этом юните (короче даже у обычной способности появляются заряды)
    function VisualChargesSystem_Init takes unit u, integer id returns nothing
        call SaveBoolean(ChargesIndicatorData,GetHandleId(u),id,true)
    endfunction
    //выключаем отображение зарядов (если были до этого заряды, их больше не отображают)
    function VisualChargesSystem_InitRemove takes unit u, integer id returns nothing
        call SaveBoolean(ChargesIndicatorData,GetHandleId(u),id,false) 
    endfunction
//редактирует кол-во зарядов (можно отредактировать выше AddAbilityCharges, подмять под себе. 
//Т.к. в этой функции можно напрямую узнать адрес зарядов абилы, не прибегая к хэш-таблицы)
    //записывает (изменяем) юниту в абилку кол-во зарядов
    function VisualChargesSystem_SetCharges takes unit u, integer id, integer charges returns nothing
        call SaveInteger(ChargesIndicatorData,GetHandleId(u),id,charges)
    endfunction
    //загружает кол-во зарядов
    function VisualChargesSystem_GetCharges takes unit u, integer id returns integer
        return LoadInteger(ChargesIndicatorData,GetHandleId(u),id)
    endfunction
//==========
можно вместо запоминания зарядов хэш-таблицы использовать функции из кода 1. запоминаешь туда, достаешь.
DracoL1ch, ты про RefreshUnitsCommandPanel? так оно же работает только у совы и осветительного заряда
4
16
5 лет назад
Отредактирован DracoL1ch
4
InitHookOnAbility вставляет хук в данные основной абилки. Один раз сделал заряды для абилки на основе War Stomp - дальше можешь её не вызывать для других абилок на WarStomp. Но если вызовешь, ничего страшного не случится в любом случае.
RefreshUnitsCommandPanel нужна в принципе после любого изменеиня. Она и вызывается игрой постоянно, но если юнит не делает ничего, то только таймером в 0.5 вроде. Поэтому после изменений вызвал и не паришься
2
32
5 лет назад
2
Всё работает на активках, да и на пассивках тоже и не критует, спасибо DracoL1ch, за мемхак и Steal nerves, за разжевывание для таких тугих я =)
4
32
5 лет назад
4
function GetEvasionOrderIdFunctionData takes nothing returns nothing
	local integer oldprotection
    local integer a
    
	call UnitAddAbility( DummyAttacker,'AEev' )
	set a = GetUnitAbility(DummyAttacker,'AEev' )
    
	if ( a > 0 ) then
		set pEvasionOrderIdFunction=RMem( RMem( a ) +0x30C )
		if pEvasionOrderIdFunction > GameDLL then
			call UnitAddAbility( DummyAttacker, 'Aesn' )
			set a=GetUnitAbility(DummyAttacker, 'Aesn')
			if ( a > 0 ) then
				set a=RMem(a)+0x30C
				set oldprotection=ChangeOffsetProtection(a,4,0x40)
				call WMem( a,pEvasionOrderIdFunction )
				call ChangeOffsetProtection( a,4,oldprotection )
			endif
			call UnitRemoveAbility( DummyAttacker, 'Aesn' )
		endif
	else
        //port value from AEev to Afla to disable icons
	endif
	call UnitRemoveAbility(DummyAttacker,'AEev')
endfunction
Вот для пассивок, при изучении вызвать call FixChargesIndicator( юнит, ид абилки )
Далее сохраняем для скорости адресс куда-нибудь и юзаем call SetAbilityChargesByAddr( адресс, заряды )
Чтобы оставить комментарий, пожалуйста, войдите на сайт.