Раньше я конвертил гуи триггеры с событие каста и условием id спелла. На сколько я знаю, это очень малоэффективно, т.к. каждый такой триггер срабатывает при касте любого спелла.
Потом я понял, что достаточно сделать один триггер с событием каста для каждого игрока, но тут я столкнулся с вопросом. если в функции-обработчике делать так:
if spellId = spell1 then
-- код спелла
elseif spellId = spell2 then
-- код спелла
elseif ...
То если код некоторых способностей слишком велик, то файл будет тянуть на > 2к строк кода, и вся эта каша такое себе.
Как делаете вы? Как делать лучше?

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

Если на луа, то можно что-то вроде
local id2callback = []
function registerSpell(id, callback){
	id2callback[id] = callback
}
...
function runSpell(id){
	local callback = id2callback[id[
	if (type(callback) == 'function){
		callback()
	}
}
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
1
27
3 года назад
1
Я в коде полная помойка, но могу на примере урона предложить. Если у меня урон меняется в зависимости от условия, то я не пишу каждый раз
if sgdf == true then
	call UnitDamageTarget(u,u1,100,...)
elseif sfdhgfdh == true then
	call UnitDamageTarget(u,u1,200,...)
endif
Я делаю отдельную переменную со счётчиком урона и уже после всех проверок на изменение урона наношу его
local real dmg
if sgdf == true then
	set dmg = 100
elseif sfdhgfdh == true then
	set dmg = 200
endif
call UnitDamageTarget(u,u1,dmg,...)
1
27
3 года назад
Отредактирован rsfghd
1
В коде у меня разные функции требовали одни и те же действия, чтобы не копировать старое я просто вынес в отдельную функцию действия со всеми нужными аргументами и вызывал её

Что по этому поводу? xgm.guru/p/blog-nvc123/ur1-3
1
29
3 года назад
Отредактирован Doc
1
Как делаете вы? Как делать лучше?
Лучше не заниматься преждевременной оптимизацией. Ну срабатывает каждый раз и что теперь?
2
28
3 года назад
2
У меня организовано вот так.
Effect
function BuilderAbilityEffect takes unit b, integer id returns nothing
    local CustomPlayer p = GetCustomPlayer(GetOwningPlayer(b))
    // SelectBarracks Faction 1
    if id == p.faction1.builder_icon0 then
        if p.isLocalPlayer then
            call ClearSelection()
            call SelectUnit(p.barracks, true)
        endif
        if p.current_barracks_faction != p.faction1 then
            call p.swapFactionInBarracks()
        endif
        return
    endif
    // SelectBarracks Faction 2
    if id == p.faction2.builder_icon1 then
        if p.isLocalPlayer then
            call ClearSelection()
            call SelectUnit(p.barracks, true)
        endif
        if p.current_barracks_faction != p.faction2 then
            call p.swapFactionInBarracks()
        endif
        return
    endif
    // SelectAltar
    if (id == p.herodata.builder_icon or id == BuilderSelectAltar) and p.isLocalPlayer then
        call ClearSelection()
        call SelectUnit(p.altar, true)
    endif
endfunction

function BarracksAbilityEffect takes unit b, integer id returns nothing
    local CustomPlayer p = GetCustomPlayer(GetOwningPlayer(b))
    // MinionSpawn
    if Minion.hire(p, id) then
        return
    endif
    // SelectBlacksmith
    if id == BarracksSelectBlacksmith then
        if p.isLocalPlayer then
            call ClearSelection()
            call SelectUnit(p.blacksmith, true)
        endif
        if p.current_barracks_faction != p.current_blacksmith_faction then
            call p.swapFactionInBlacksmith()
        endif
        return
    endif
    // SelectAltar
    if id == BarracksSelectAltar and p.isLocalPlayer then
        call ClearSelection()
        call SelectUnit(p.altar, true)
        return
    endif
    // SelectCapm
    if id == BarracksSelectCamp and p.isLocalPlayer then
        call ClearSelection()
        call SelectUnit(p.merccamp, true)
        return
    endif
    // SwapFaction
    if id == SwapFaction then
        call p.swapFactionInBarracks()
    endif
endfunction

function BlacksmithAbilityEffect takes unit b, integer id returns nothing
    local CustomPlayer p = GetCustomPlayer(GetOwningPlayer(b))
    // MinionUpgrades
    if Minion.makeUpgrade(p, id) then
        return
    endif
    // SwapFaction
    if id == SwapFaction then
        call p.swapFactionInBlacksmith()
        return
    endif
    // MHU
    if id == BlacksmithMHU then
        call UpgradeMinionHealth(p)
    endif
endfunction

function AltarAbilityEffect takes unit b, integer id returns nothing
    local CustomPlayer p = GetCustomPlayer(GetOwningPlayer(b))
    // Hero selection
    if id == p.faction1.herodata.altar_icon0 then
        call UnitRemoveAbility(b, p.faction2.herodata.altar_icon1)
        call p.addHero(p.faction1.herodata)
        return
    endif
    if id == p.faction2.herodata.altar_icon1 then
        call UnitRemoveAbility(b, p.faction1.herodata.altar_icon0)
        call p.addHero(p.faction2.herodata)
        return
    endif
    // Ability selection
    if p.changeHeroAbilityByRawCode(id) then
        return
    endif
    // Upgrades
    if Minion.makeUpgrade(p, id) then
        return
    endif
endfunction

function MercCampAbilityEffect takes unit b, integer id returns nothing
   call Minion.hire(GetCustomPlayer(GetOwningPlayer(b)), id)
endfunction

function TowerAbilityEffect takes Tower caster, integer id, integer target returns nothing
    // Sell
    if id == TowerAbilSell or id == TowerAbilDestroy then
        call caster.sell()
        return
    endif
    // Upgrade
    if id == TowerAbilUpgrade then
        call Tower.upgradeTower(caster)
        return
    endif
    // ExpGenerator
    if id == AbilExpGenerator.AbilSelectTower then
        call AbilExpGenerator.selectTowerAll(caster.abil, target)
    endif
endfunction

function Trig_PlayerAbilityEffect_Actions takes nothing returns nothing
    local integer id = GetSpellAbilityId()
    local unit u = GetSpellAbilityUnit()
    local integer caster = GetUnitUserData(u)
    local integer target = GetUnitUserData(GetSpellTargetUnit())
    local integer T = GetUnitTypeId(u)
    if T == BuilderId then
        call BuilderAbilityEffect(u, id)
    elseif T == BarracksId then
        call BarracksAbilityEffect(u, id)
    elseif T == BlacksmithId then
        call BlacksmithAbilityEffect(u, id)
    elseif T == AltarId then
        call AltarAbilityEffect(u, id)
    elseif T == MercCampId then
        call MercCampAbilityEffect(u, id)
    elseif IsUnitTower(u) then
        call TowerAbilityEffect(caster, id, target)
    endif
    set u = null
endfunction

function InitTrig_PlayerAbilityEffect takes nothing returns nothing
    set gg_trg_PlayerAbilityEffect = CreateTrigger()
    call TriggerAddAction(gg_trg_PlayerAbilityEffect, function Trig_PlayerAbilityEffect_Actions)
endfunction
Endcast
function TowerAbilityEndcast takes Tower caster, integer id returns nothing
    local TowerAbility abil = caster.abil
    // FocusedAttack
    if abil.getType() == AbilFocusedAttack.typeid then
        call AbilFocusedAttack.returnNormalProjectile(abil, id)
        return
    endif
    // ChillingAttack
    if abil.getType() == AbilChillingAttack.typeid then
        call AbilChillingAttack.returnNormalProjectile(abil, id)
        return
    endif
    // LightningAttack
    if abil.getType() == AbilLightningAttack.typeid then
        call AbilLightningAttack.returnNormalProjectile(abil, id)
        return
    endif
    // ExpGenerator
    if abil.getType() == AbilExpGenerator.typeid then
        call AbilExpGenerator.changeModeAll(abil, id)
    endif
endfunction

function MinionAbilityEndcast takes Minion m, integer id returns nothing
    // Stop
    if id == MinionAbilStop then
        call Minion.stopOrder(m.owner)
        return
    endif
    // Sell
    if id == MinionAbilSell or id == MinionAbilUnchallenge then
        call m.sell()
    endif
endfunction

function Trig_PlayerAbilityEndcast_Actions takes nothing returns nothing
    local integer id = GetSpellAbilityId()
    local unit u = GetSpellAbilityUnit()
    local integer caster = GetUnitUserData(u)
    if IsUnitTower(u) or IsUnitTowerAttacker(u) then
        call TowerAbilityEndcast(caster, id)
    elseif IsUnitMinion(u) then
        call MinionAbilityEndcast(caster, id)
    endif
    set u = null
endfunction

function InitTrig_PlayerAbilityEndcast takes nothing returns nothing
    set gg_trg_PlayerAbilityEndcast = CreateTrigger()
    call TriggerAddAction(gg_trg_PlayerAbilityEndcast, function Trig_PlayerAbilityEndcast_Actions)
endfunction

Тут всё зависит от того, какая карта.
Если куча-куча спелов, то стоит сохранять в хеш по любому парент ключу и равкоду спела как чайлд ключу функцию, которая запускает спел. Функция может не принимать аргументов, всё необходимое можно будет достать изнутри. Во время срабатывания спела достаётся это функция и запускается через .evaluate() или .execute().
1
8
3 года назад
1
Я делаю отдельную переменную со счётчиком урона и уже после всех проверок на изменение урона наношу его
С уроном да, так же делаю, но событие получения урона обычно проще, чем с 100+ скиллов.
rsfghd:
Что по этому поводу?
А это здорово. В lua без хэштаблицы даже можно.
Doc:
Лучше не заниматься преждевременной оптимизацией. Ну срабатывает каждый раз и что теперь?
Согласен, но переделывать эту кашу потом будет сложно же?
PT153:
Если куча-куча спелов, то стоит сохранять в хеш по любому парент ключу и равкоду спела как чайлд ключу функцию
Тоже об этом думал.
1
29
3 года назад
1
Если джасс умеет в хеш сохранять функцию - переделать потом стандартные ивенты на хеш будет тривиально.
1
13
3 года назад
Отредактирован Nelloy
1
Если на луа, то можно что-то вроде
local id2callback = []
function registerSpell(id, callback){
	id2callback[id] = callback
}
...
function runSpell(id){
	local callback = id2callback[id[
	if (type(callback) == 'function){
		callback()
	}
}
Принятый ответ
0
8
3 года назад
0
Примерно к такому я пока и пришел. Просто раньше я делал по принципу "я бы жил по понятиям, но живу как понял", т.е. каша из гуи конвертов, cJASS там же. Сейчас я перебрался на Lua, появилось больше свободы и возможностей, но у меня много вопросов по организации всего этого дела. Хочется сразу применять хорошие практики.

Всем спасибо!
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.