XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
vladfaust

offline
Опыт: 12,714
Активность:
Проблема с заклинанием (не ремувится эффект).
library SHAS4 initializer I uses DamageLib {
    
    define {
        // Optional
        private      AOE = 700.   // AOE of casting.
        private    TIMER = 6.
        private      P_S = 1.0
        private      MAX = 10
        // Strings
        // Not optional
        private       AR = 'A02M'   // Abil raw.
        private      EFF = "war3mapImported\\Stone Shield.mdx"
        private   ATTACH = "origin"
        // Hash
        private H_1 = StringHash("H_1")
        private H_2 = StringHash("H_2")
        private H_IS_SHIELD = StringHash("H_IS_SHIELD")
        private H_SHIELD_LEFT = StringHash("H_SHIELD_LEFT")
    }
    
    globals
        public trigger Trg_A = CreateTrigger()
        private player ch_p = null
        private group gr = CreateGroup()
    endglobals
    
    public void preload () {
        Preload(EFF)
        PreloadEnd(0.01)
    }
    
    private void Attacked () {
        local unit u = GetTriggerUnit()
        
        if LoadBoolean(HT, GetHandleId(u), H_IS_SHIELD) {
            if LoadInteger(HT, GetHandleId(u), H_SHIELD_LEFT) > 0 {
                local real heal = GetHeroStr(u, TRUE)*P_S
                DisableTrigger(GetTriggeringTrigger())
                DamageLib_SpellHeal(u, u, -heal)
                EnableTrigger(GetTriggeringTrigger())
                SaveInteger(HT, GetHandleId(u), H_SHIELD_LEFT, LoadInteger(HT, GetHandleId(u), H_SHIELD_LEFT)-1)
            else
                SaveBoolean(HT, GetHandleId(u), H_IS_SHIELD, FALSE)
            }
        }
        
        u = null
    }
    
    private void RemoveShield () {
        local timer  t = GetExpiredTimer()
        local unit   u = LoadUnitHandle(HT, GetHandleId(t), H_2)
        local effect e = LoadEffectHandle(HT, GetHandleId(u), H_1)
        
        DestroyEffect(e)
        SaveBoolean(HT, GetHandleId(u), H_IS_SHIELD, FALSE)
        
        FlushChildHashtable(HT, GetHandleId(t))
        DestroyTimer(t)
        
        e = null
        t = null
        u = null
    }
    
    private void Act () {
        if GetSpellAbilityId() == AR {
            local unit cst = GetTriggerUnit()
            local effect e = AddSpecialEffectTarget(EFF, cst, ATTACH)
            local timer  t = CreateTimer()
            
            SaveUnitHandle(HT, GetHandleId(t), H_2, cst)
            TimerStart(t, TIMER, FALSE, function RemoveShield)
            SaveBoolean(HT, GetHandleId(cst), H_IS_SHIELD, TRUE)
            SaveInteger(HT, GetHandleId(cst), H_SHIELD_LEFT, MAX)
            SaveEffectHandle(HT, GetHandleId(cst), H_1, e)
            
            e   = null
            cst = null
        }
    }
    
    private void I () {
        trigger Trg = CreateTrigger()
        TriggerRegisterAnyUnitEventBJ(Trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        TriggerAddAction(Trg,function Act)
        TriggerAddAction(Trg_A, function Attacked)
    }
    
}
Все работает нормально, но бывает так, что эффект остается. По наблюдениям, происходит это тогда, когда юнит умирает с этим эффектом.
inadequate_ добавил:
+Ставил проверку на >0.405 - не помогло.
Старый 27.02.2012, 14:36
Ty3uK

offline
Опыт: 2,469
Активность:
inadequate_, мб юзать
Код:
IsUnitType(unit, UNIT_TYPE_DEAD)
?
Старый 27.02.2012, 16:31
vladfaust

offline
Опыт: 12,714
Активность:
Ty3uK, 0_o. Нет)
Старый 27.02.2012, 16:34
Ty3uK

offline
Опыт: 2,469
Активность:
inadequate_, "нет" - это типа не работает или типа не будешь юзать?
Старый 27.02.2012, 16:36
ScorpioT1000
Работаем
offline
Опыт: отключен
Общепризнанная проверка на смерть:
function IsUnitDead takes unit u returns boolean
    return IsUnitType(u, UNIT_TYPE_DEAD) or GetUnitTypeId(u) < 1
endfunction

Отредактировано ScorpioT1000, 27.02.2012 в 19:58.
Старый 27.02.2012, 16:56
vladfaust

offline
Опыт: 12,714
Активность:
Скорпи, ты ничего не попутал?
GetUnitTypeId(u)<= 0.405

Или все-таки

GetUnitState(u, UNIT_STATE_LIFE)>0.405
+Зачем проверка на UNIT_TYPE_DEAD, если уже есть проверка на кол-во хп?
Я проверить точно не могу, так как баг не всегда проявляется.
inadequate_ добавил:
И еще кое-что.
GetUnitState(u, UNIT_STATE_LIFE)>0.405
...отлично работает в других заклинаниях.
Старый 27.02.2012, 19:32
alpha

offline
Опыт: 7,387
Активность:
inadequate_:
GetUnitState(u, UNIT_STATE_LIFE)>0.405
GetWidgetLife(u) используй
+Зачем проверка на UNIT_TYPE_DEAD, если уже есть проверка на кол-во хп?
Для фильтра "непредскозуемости" вара
Старый 27.02.2012, 19:35
Nerevar
I'll be back!
offline
Опыт: 18,352
Активность:
alpha:
GetWidgetLife(u) используй
почему ?
Старый 27.02.2012, 19:53
ScorpioT1000
Работаем
offline
Опыт: отключен
пофиксил =))) когда добавлял в сообщение, не то сделал
жизнь проверять не надо
Старый 27.02.2012, 19:59
Nerevar
I'll be back!
offline
Опыт: 18,352
Активность:
К виджетам относятся юниты\предметы\разрушаемые.
Почему обращение к функции работающей только с юнитами будет медленнее, чем к функции с более широкой областью действия? из-за 2 вместо 1 передаваемого параметра?
Старый 27.02.2012, 20:35
prog

offline
Опыт: 32,865
Активность:
Nerevar, если не ошибаюсь, потому что вторая функция вызывает первую.
Старый 27.02.2012, 20:47
ScorpioT1000
Работаем
offline
Опыт: отключен
Да не дольше она работает, работает абсолютно одинаково - что юнит, что виджет, функция из C++ обращается к верхней части выделенной памяти объекта, которая принадлежит виджету и изменяет его. Обе нативки просто вызывают эту функцию. (максимум еще при загрузке карты при передаче виджету работает преобразование типов)
Оптимизатор C++ существовал еще в 99 году. А с патчами они перекомпилировали гейм.длл, что тем более подтверждает оптимальность простейших операций.
Старый 27.02.2012, 20:59
Ty3uK

offline
Опыт: 2,469
Активность:
Функции виджетов работают быстрее, наверное потому, что юнит, предмет, декорация- все это потомки виджета. Это имхо
Старый 27.02.2012, 21:05
alpha

offline
Опыт: 7,387
Активность:
ScorpioT1000:
Да не дольше она работает, работает абсолютно одинаково - что юнит, что виджет
Я пролетел :(
Это действительно так
Скорость срабатывания одинаковая, на моем дереве фунция срабатывала в за .000010-.0000109 секунды, брал локальную переменную в функцию
alpha добавил:
Но все равно лучше использовать GetWidgetLife, как никак
но разница даже под микроскопом ничтожна
Klop преоткрыл занавес =)
Выигришь в байтах кода и удобстве(чистоте) написания

Отредактировано alpha, 27.02.2012 в 23:49.
Старый 27.02.2012, 23:25
Klop
Папа римский
offline
Опыт: 13,006
Активность:
GetUnitState(u, UNIT_STATE_LIFE)>0.405
GetWidgetLife(u) > 0.405
Widget лучше тем что ненадо писать UNIT_STATE_LIFE
Старый 27.02.2012, 23:46
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 23:44.