Фаталит карта при вызове функции GetConstructedStructure() или GetTriggeringUnit() в потоке триггера, который был вызван отловом события EVENT_PLAYER_UNIT_CONSTRUCT_FINISH.
Регистрация события идёт следующим образом:
library RegisterAnyUnitEvent initializer onInit


    globals
        private  trigger  array  triggers
    endglobals


    function RegisterAnyUnitEvent takes playerunitevent whichPlayerUnitEvent, code actionFunc returns nothing
        local integer index = GetHandleId(whichPlayerUnitEvent)

        if (triggers[index] == null) then
            set triggers[index] = CreateTrigger()

            call TriggerRegisterPlayerUnitEvent(triggers[index], Player(0), whichPlayerUnitEvent, null)
            call TriggerRegisterPlayerUnitEvent(triggers[index], Player(1), whichPlayerUnitEvent, null)
            call TriggerRegisterPlayerUnitEvent(triggers[index], Player(2), whichPlayerUnitEvent, null)
            call TriggerRegisterPlayerUnitEvent(triggers[index], Player(3), whichPlayerUnitEvent, null)
            call TriggerRegisterPlayerUnitEvent(triggers[index], Player(4), whichPlayerUnitEvent, null)
            call TriggerRegisterPlayerUnitEvent(triggers[index], Player(5), whichPlayerUnitEvent, null)
        endif

        call TriggerAddAction(triggers[index], actionFunc)
    endfunction


endlibrary
Логи приложил.

ScopteRectuS, насколько я помню, эти 2 функции вызывают ошибку, если в параметре идентификатор героя.
`
ОЖИДАНИЕ РЕКЛАМЫ...
21
После небольших тестов выяснил, что причина фатала не в регистрации, а в самой способности:
методы: onInit(), onUnitConstructFinish()
код:
struct demolish


    private  static  unit     tower   =  null
    private  static  integer  towerI  =  0
    private  static  real     towerX  =  0.0
    private  static  real     towerY  =  0.0
    private  static  player   owner   =  null
    private  static  integer  costG   =  0
    private  static  integer  costW   =  0
    private  static  Table    gold    =  Table( 0 )
    private  static  Table    wood    =  Table( 0 )


    private static method onUnitSpellCast takes nothing returns nothing
        if (GetSpellAbilityId() == 'A002') then
            set thistype.tower  = GetSpellAbilityUnit()
            set thistype.towerI = GetHandleId(thistype.tower)
            set thistype.towerX = GetUnitX(thistype.tower)
            set thistype.towerY = GetUnitY(thistype.tower)
            set thistype.owner  = GetOwningPlayer(thistype.tower)
            set thistype.costG  = gold[thistype.towerI]
            set thistype.costW  = wood[thistype.towerI]
            
            call KillUnit(thistype.tower)
            call ShowUnit(thistype.tower, false)
            call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\Transmute\\PileofGold.mdl", thistype.towerX, thistype.towerY))

            call CreateFloatingTextTag(thistype.owner, FLOATING_TEXTTAG_GOLD,   thistype.costG, thistype.towerX, thistype.towerY, GetUnitFlyHeight(thistype.tower) + 60.0 )
            call CreateFloatingTextTag(thistype.owner, FLOATING_TEXTTAG_LUMBER, thistype.costW, thistype.towerX, thistype.towerY, GetUnitFlyHeight(thistype.tower) + 120.0)

            call SetPlayerState(thistype.owner, PLAYER_STATE_RESOURCE_GOLD,   GetPlayerState(thistype.owner, PLAYER_STATE_RESOURCE_GOLD  ) + thistype.costG)
            call SetPlayerState(thistype.owner, PLAYER_STATE_RESOURCE_LUMBER, GetPlayerState(thistype.owner, PLAYER_STATE_RESOURCE_LUMBER) + thistype.costW)
        endif
    endmethod


    private static method onUnitConstructFinish takes nothing returns nothing
        set thistype.tower  = GetConstructedStructure() <== если это заменить на null, то фаталы прекращаются.
        set thistype.towerI = GetHandleId(thistype.tower)

        set  gold[thistype.towerI] = GetUnitGoldCost(GetUnitTypeId(thistype.tower))
        set  wood[thistype.towerI] = GetUnitWoodCost(GetUnitTypeId(thistype.tower))
    endmethod


    private static method onUnitUpgradeFinish takes nothing returns nothing
        set thistype.tower  = GetTriggerUnit()
        set thistype.towerI = GetHandleId(thistype.tower)

        set gold[thistype.towerI] = GetUnitGoldCost(GetUnitTypeId(thistype.tower)) + gold[thistype.towerI]
        set wood[thistype.towerI] = GetUnitWoodCost(GetUnitTypeId(thistype.tower)) + wood[thistype.towerI]
    endmethod


    private static method onInit takes nothing returns nothing
        set  gold  =  Table.create( )
        set  wood  =  Table.create( )

        call RegisterAnyUnitEvent( EVENT_PLAYER_UNIT_SPELL_CAST,       function thistype.onUnitSpellCast       )
        call RegisterAnyUnitEvent( EVENT_PLAYER_UNIT_CONSTRUCT_FINISH, function thistype.onUnitConstructFinish )
        call RegisterAnyUnitEvent( EVENT_PLAYER_UNIT_UPGRADE_FINISH,   function thistype.onUnitUpgradeFinish   )
    endmethod


endstruct
27
мб дело в этих строчках?
call KillUnit(thistype.tower)
call ShowUnit(thistype.tower, false)
ты пытаешь убить, а потом спрятать. действие с несуществующим объектом. у меня много раз такое было, и я хорошо это усвоил. вчера буквально проверочную системку делал, молнию удалил, а система пытается двигать ее - это приводило к фаталу
пробуй выяснить, где не работает. В каком триггере, в каком моменте. Пробуй отключать триггер и запустить способность-пустышку, выключать какие-то действия
я что-то в onUnitConstructFinish не вижу из-за чего может происходит фатал. наверное обращаешься к несуществующей? и какая связь между приводит в действие абилу и завершает строительство
21
Steal nerves, нет, причина не в этом. Методом удаления выявил проблемный участок:
private static method onUnitConstructFinish takes nothing returns nothing
	call GetUnitGoldCost(GetUnitTypeId(GetConstructedStructure()))
endmethod

private static method onInit takes nothing returns nothing
    call RegisterAnyUnitEvent( EVENT_PLAYER_UNIT_CONSTRUCT_FINISH, function thistype.onUnitConstructFinish )
endmethod

Удаляя еще больше лишнего, выяснил, что фаталит функция GetUnitGoldCost() при:
call GetUnitGoldCost('T000')
27
ScopteRectuS, эта функция GetUnitGoldCost не стандартна, это вы ее написали?
21
Steal nerves, нет не я. она из common.ai
native GetUnitWoodCost takes integer unitid returns integer
native GetUnitGoldCost takes integer unitid returns integer
27
ScopteRectuS, так догадывался. но у меня она почему не работает. jasshelper ругается (ее можно запустить?)
ничего не могу поделать. ждем умнейших
21
Steal nerves, чтобы она заработала нужно её объявить, где-нибудь написав:
((
native GetUnitWoodCost takes integer unitid returns integer
native GetUnitGoldCost takes integer unitid returns integer
))
13
Такое бывает, если у юнита есть что-то недопустимое в редакторе объектов (помню как-то делал перевоплощение в юнита, который в свою очередь тоже перевоплощался) - в итоге от размещения подобного юнита на карте (соответственно, ввиду его создания и прогрузки способностей) карта фаталила сразу. Думаю, может стоит РО проверить? Просто юнит при строительстве не будет обладать глючной способностью, что и даст фатал в момент ее обретения при завершении строительства.
21
Пушистый, Фатал происходит не из-за юнита, а из-за функций GetUnitGoldCost() и GetUnitWoodCost().
Вернее когда этот юнит и эти функции встречаются с друг другом
.
1
ScopteRectuS, насколько я помню, эти 2 функции вызывают ошибку, если в параметре идентификатор героя.
Принятый ответ
13
ScopteRectuS, ранее функции ai работали (так как они были даже основой мемхака). Может, в РО какая-то некорректная для вывода стоимость?
21
чет не пойму, так это че, есть стандартные функции определения голдкоста и "древесного коста"?
мб потому близзы их и отрубили, что нашлись косяки и времени фиксить не было
21
PT153, а на голдкост предмета нет такой?
в крайнем случае лично посмотрю
26
ScopteRectuS, может ловить не юнит, а тип юнита, как для события Юнит начинает тренировку?
GetTrainedUnitType()
28
может ловить не юнит, а тип юнита, как для события Юнит начинает тренировку?
А он тип и ловит, функции принимают равкод юнита.
21
Сори, ребзя. Так как это у меня здание-герой, я и совсем забыл, что башня является героем. А функции GetUnitGoldCost(), GetUnitWoodCost() не работают с героями, об этом я писал ранее:
ScopteRectuS:
Есть же функции:
native GetUnitGoldCost        takes integer unitid                    returns integer
native GetUnitWoodCost        takes integer unitid                    returns integer
Правда нелbзя использовать на воинов, у которых равкод начинается с прописной буквы (на героев).
Idency всё верно сказал. Всем спасибо за помощь.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.