Переопределение ванильного модификатора.

20 Дек 2016
892
170
Хочу, чтобы замедления от кристал новы стакались. Для этого достаточно (наверно) переопределить GetAttributes для modifier_crystal_maiden_crystal_nova. Но для этого мне необходимо как-то получить его в переменную.
Код:
LinkLuaModifier( "modifier_crystal_maiden_crystal_nova", 0 )
function modifier_crystal_maiden_crystal_nova:GetAttributes()
  return 2
end

Если переопределять функцию для уже наложенного модификатора то... То ничего. В тот момент, когда модификатор накладывается повторно, если он нон-мультипл, он просто рефрешится, даже если уже наложенный был мультиплом. Поэтому переопределить нужно именно абстрактный модифаер до его наложения.

Вариант с копированрем из Spell Library написанием абилки не катит, потому что в последствии я хочу дать мультипл всем модификаторам из ванильных абилок.

Есть еще вариант сделать так, но для этого мне придется как-то криво отслеживать рефреш модификатора (событие, при котором будет накладываться свой модификатор), чем бы мне хотелось заниматься в последнюю очередь.
 
Последнее редактирование модератором:
мамин программист, ордер фильтр и свои собственные модификаторы
 
[quote author=I_GRIN_I link=topic=1724.msg11930#msg11930 date=1508396949]
мамин программист, ордер фильтр и свои собственные модификаторы
[/quote]
Еще не пользовался ордер фильтром. Прочитал гайд и уведел в таблице евента параметр queue. Как я понял, фильтр срабатывает именно когда игром пальцем в мышку тыкает. Можно ли исходя из этого отследить момент, когда способность кастуется?
 
мамин программист, да, можно, можно и не дать скастоваться способности вовсе
 
Причем тут ордер фильтр вообще?
Я тоже этого не совсем понял. Я думаю, что это такой способ отследить каст способности, чтобы накладывать свой модификатор. Однако проблема в том, что он срабатывает когда игрок дает приказ, а не когда способность начинает действовать. Таким образом этими своими модификаторами можно заспамить всю карту без кулдауна, кастпоинта и ограничения по расстоянию, бегая при этом вокруг вражеской башни.
Надо либо как-то через ордер фильтр попытаться отследить начало действия способности, либо этого не делать.
А вообще, можно ли реализовать задачу без создания дополнительных модификаторов, т.е. тупо переопределением?
 
Последнее редактирование модератором:
Сделал пока так. Жду решения без создания своего модификатора ( если оно есть )
В кастомном модификаторе достаточно прописать мультипл, DeclareFunctions и необходимые значения. Остальное задается ванильным.

Код:
LinkLuaModifier( "modifier_crystal_maiden_crystal_nova_multiple", "override_modifiers/modifier_crystal_maiden_crystal_nova_multiple", LUA_MODIFIER_MOTION_NONE )

function addon_main:InitGameMode()
	ListenToGameEvent( "dota_player_used_ability", Dynamic_Wrap( addon_main, "OnAbilityUsed" ), self )
end

function addon_main:OnAbilityUsed( kv )
	local player = PlayerResource:GetPlayer( kv.PlayerID )
	local hero
	local ability
	if player then
		hero = player:GetAssignedHero()
	end
	if hero then
		ability = hero:FindAbilityByName( kv.abilityname )
		if ability then
			if ability:GetAbilityName() == "crystal_maiden_crystal_nova" then
				local vLocation = ability:GetCursorPosition()
				local radius = ability:GetSpecialValueFor( "radius" )
				local duration = 0
				local modifier
				
				local units = FindUnitsInRadius( ability:GetCaster():GetTeamNumber(), vLocation, ability:GetCaster(), radius, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC, 0, 0, false )
				for _, unit in pairs( units ) do
                    --[[Чтобы избежать двойного эффекта от первого каста (от родного модификатора и от кастомного), длительность я расчитываю вот так. Если на цели висел родной модификатор (на мое счастье евент срабатывает до каста, что позволяет получить модификактор до его рефреша способностью), то новому кастомному дается его длительность, а родной рефрешится, обновляя длительность до той, что в кв. Если же родного модификатора не висело, то кастомный вообще не накладывается (накладывается с нулевой длительностью), зато накладывается родной. Абсолютная эмитация механики мультипла.]]
					modifier = unit:FindModifierByName( "modifier_crystal_maiden_crystal_nova" )
					if modifier then
						duration = modifier:GetRemainingTime()
					end

					if unit ~= nil and ( not unit:IsMagicImmune() ) and ( not unit:IsInvulnerable() ) then
						unit:AddNewModifier( ability:GetCaster(), ability, "modifier_crystal_maiden_crystal_nova_multiple", { duration = duration } )
					end
				end
			end
		end
	end
end
 
Последнее редактирование модератором:
Почему не переделать абилку просто?

В последствии мне это надо будет сделать для всех способностей, дающих нескладывающиеся модификаторы. А организовывать у себя второй спелл лайбрари не хочется. Да и вообще любое повторение способности будет неточным, а так я просто дополняю существующую способность.
Это, конечно, тоже придется руками делать для всех скилов, но это намнооого легче и быстрее, чем писать абилку со всеми партиклами и фишками.
 
Последнее редактирование модератором:
Ты ордер фильтром ничего не сделаешь.

Попробуй модифаер фильтром реджектить и накладывать свой.
 
Вот еще такой вопрос.
В файле с описанием для вывода значений модификаторов используется %MODIFIER_PROPERTY_...%. Можно ли получить это значение в луа скрипте? Просто для ванильных модификаторов не работают GetModifier...() , а как по другому получить значения модификатора я не знаю.
 
Cделал с помощью модифаер фильтра. С одной стороны мне не нужно переписывать половину каждой способности, а с другой - нужно полностью переписывать модификатор, включая визуальные эффекты, т.к. фильтр не срабатывает при рефреше. Но это все-таки попроще.
Код:
function addon_main:InitGameMode()
    _G.GameModeEntity = GameRules:GetGameModeEntity()
    GameModeEntity:SetModifierGainedFilter( Dynamic_Wrap( addon_main, "ModifierFilter" ), self )
end

function addon_main:ModifierFilter( kv )
    local modifier_name = kv.name_const
    if modifier_name == "modifier_crystal_maiden_crystal_nova" then
        local parent = EntIndexToHScript( kv.entindex_parent_const )
        local caster = EntIndexToHScript( kv.entindex_caster_const )
        local ability = EntIndexToHScript( kv.entindex_ability_const )
        local duration = kv.duration
        parent:AddNewModifier( caster, ability, "modifier_crystal_maiden_crystal_nova_multiple", { duration = duration } )
        return false
    end
    return true
end
 
Последнее редактирование:
Реклама: