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

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

Закрытая тема
 
Kenshi245

offline
Опыт: 2,252
Активность:
Spell Rejuvenation
Есть скрипт на спелл rejuvenation, механика такая же как в оригинальном варике - лечит хп со временем и отображает цыферки, но в скрипте есть жесткий баг - иногда, когда часто накладываешь бафф на разные цели, бафф появляется, но ни лечения ни цифр нету, кто может сказать в чем проблема?

Код:
// ### Rejuvenation Spell ###
function Spell_Rejuvenation_Tick takes nothing returns nothing
    local timer timerA = GetExpiredTimer()
    local unit unitA = I2U(GetStoredInteger(udg_Game_Cache, I2S(H2I(timerA)), "Rej_Targ"))
    local integer pID = GetPlayerId(GetOwningPlayer(unitA))
    local real HealingA = GetStoredInteger(udg_Game_Cache, I2S(H2I(timerA)), "Rej_Heal")+udg_Hpw[pID]*GetRandomReal(0.1,0.3)
    if GetUnitAbilityLevel(unitA, 'B00L') > 0 then
    call TextTargetA(unitA,HealingA,2,false)
    else
    call FlushStoredMission(udg_Game_Cache, I2S(H2I(timerA)))
    call FlushStoredInteger(udg_Game_Cache, I2S(H2I(unitA)),"Rej_targ")
    call DestroyTimer(timerA)
    endif
    set timerA = null
    set unitA = null
endfunction

function Spell_Rejuvenation takes nothing returns nothing
    local unit unitA = GetTriggerUnit()
    local unit unitB = GetSpellTargetUnit()
    local timer timerA = CreateTimer()
    local timer timerB = I2T(GetStoredInteger(udg_Game_Cache, I2S(H2I(unitB)), "Rej_Buff"))
    local integer pID = GetPlayerId(GetOwningPlayer(unitA))
    local real HealingA = GetUnitAbilityLevel(unitA,'A00U')*25
    call FlushStoredMission(udg_Game_Cache, I2S(H2I(timerB)))
    call DestroyTimer(timerB)
    call StoreInteger(udg_Game_Cache, I2S(H2I(timerA)), "Rej_Heal", R2I(HealingA))
    call StoreInteger(udg_Game_Cache, I2S(H2I(timerA)), "Rej_Targ", H2I(unitB))
    call StoreInteger(udg_Game_Cache, I2S(H2I(unitB)), "Rej_Buff", H2I(timerA))
    call TimerStart(timerA, 1, true, function Spell_Rejuvenation_Tick)
    set timerA = null
    set timerB = null
    set unitA = null
    set unitB = null
endfunction
Старый 13.04.2008, 21:50
Toadcop

offline
Опыт: 54,313
Активность:
вы води сообщение рода...
"unit X heald for X" т.е. в действие выводи сообщение что бы ты знал что оно выполнилось или нет.
кстати удалять возможно не существующий таймер не советуетьса =)
Старый 14.04.2008, 03:54
adic3x

offline
Опыт: 108,439
Активность:
http://xgm.guru/forum/showthread.php?t=14923
статья по теме отладки скриптов впринципе
Старый 14.04.2008, 13:46
ShadoW DaemoN

offline
Опыт: 37,078
Активность:
Хмм, вместо того, чтобы лишний раз удалять таймер, лучше лишний раз проверять, создан ли он. Т.е. сделать так, чтобы таймер существовал тогда и только тогда, когда бафф лежит на цели.

По сути, нам необходимо определить, сколько лечения дает rejuvination - это безусловно - аттачим значение к юниту-цели. Затем, если таймер, приаттаченный к цели, не создан - создаем и работаем. Если таймер уже был создан - ничего не делаем (время баффа обновляет сам спелл), при каждом выполнении таймера будет браться значение local real Heal, приаттаченное к юниту.

+ я не понял, где у тебя используется значение local integer pID в Spell_Rejuvination, т.к. можно сразу получать номер игрока в таймер-функции.

Собственно, вот проверенный код:
Код:
// ### Rejuvination Spell ###
function Spell_Rejuvination_Tick takes nothing returns nothing
    local timer timerA = GetExpiredTimer()
    local unit  unitA  = I2U(GetStoredInteger(udg_Game_Cache, I2S(H2I(timerA)), "Rej_Targ"))
    local real  Heal   =     GetStoredReal   (udg_Game_Cache, I2S(H2I(unitA)),  "Rej_Heal") + udg_Hpw[GetPlayerId(GetOwningPlayer(unitA))] * GetRandomReal(.1,.3)
    if GetUnitAbilityLevel(unitA, 'B00L') > 0 then
        call TextTargetA(unitA, Heal, 2, false)
    else
        // пофиксено
        call FlushStoredInteger(udg_Game_Cache, I2S(H2I(timerA)), "Rej_Targ")
        call FlushStoredReal   (udg_Game_Cache, I2S(H2I(unitA)),  "Rej_Heal")
        call DestroyTimer(timerA)
    endif
    set timerA = null
    set unitA  = null
endfunction

function Spell_Rejuvination takes nothing returns nothing
    local unit  unitA  = GetSpellTargetUnit()
    local timer timerA = null
    call StoreReal(udg_Game_Cache, I2S(H2I(unitA)), "Rej_Heal", GetUnitAbilityLevel(GetTriggerUnit(), 'A00U') * 25.)
    // и тут тоже
    if GetUnitAbilityLevel(unitA, 'B00L') == 0
        set timerA = CreateTimer()
        call StoreInteger(udg_Game_Cache, I2S(H2I(timerA)), "Rej_Targ", H2I(unitA))
        call TimerStart(timerA, 1., true, function Spell_Rejuvination_Tick)
        set timerA = null
    endif
    set unitA = null
endfunction

А по-хорошему лучше делать без кэша и без RB ^_^

Отредактировано ShadoW DaemoN, 17.04.2008 в 05:26.
Старый 14.04.2008, 16:29
J
expert
offline
Опыт: 48,447
Активность:
эм... притбавлю только что этот спел будет работать некоректно т.к. очищается ключ хендла юнита который также может быть использован и в других спелах, там лчше строку прибовлять какуюнить
Старый 14.04.2008, 17:03
Erica

offline
Опыт: 28
Активность:
Jon
Все коректно будет работать
Старый 14.04.2008, 17:50
J
expert
offline
Опыт: 48,447
Активность:
Erica потомучто ShadoW DaemoN уже подредактировал ошибку
Старый 14.04.2008, 17:59
adic3x

offline
Опыт: 108,439
Активность:
Erica, обоснуй

в любом случае в 99% можно сделать лучше без кеша

кешь нужен для переноса между картами
Старый 14.04.2008, 18:03
FellGuard
Losyash
offline
Опыт: 39,547
Активность:
подредактировал ли?
call FlushStoredMission(udg_Game_Cache, I2S(H2I(unitA)), "Rej_Time")
синтаксическая ошибка.. видимо FlushStoredInteger
Старый 14.04.2008, 18:04
J
expert
offline
Опыт: 48,447
Активность:
хм, я увидел надпись "Пофиксено" подумал что исправил... да у него и не толкьо в этом ошибка была, короче чтото вроде такого нуно...
» code
Код:
// ### Rejuvination Spell ###
function Spell_Rejuvination_Tick takes nothing returns nothing
    local timer timerA = GetExpiredTimer()
    local unit  unitA  = I2U(GetStoredInteger(udg_Game_Cache, I2S(H2I(timerA)), "Rej_Targ"))
    local real  Heal   =     GetStoredReal   (udg_Game_Cache, I2S(H2I(timerA)), "Rej_Heal") + udg_Hpw[GetPlayerId(GetOwningPlayer(unitA))] * GetRandomReal(.1,.3)
    if GetUnitAbilityLevel(unitA, 'B00L') > 0 then
        call TextTargetA(unitA, Heal, 2, false)
    else
        call FlushStoredMission(udg_Game_Cache, I2S(H2I(timerA)))
        call FlushStoredInteger(udg_Game_Cache, I2S(H2I(unitA)),  "Rej_Time")
        call DestroyTimer(timerA)
    endif
    set timerA = null
    set unitA  = null
endfunction

function Spell_Rejuvination takes nothing returns nothing
    local unit  unitA  = GetSpellTargetUnit()
    local timer timerA = I2T(GetStoredInteger(udg_Game_Cache, I2S(H2I(unitA)), "Rej_Time"))
    call StoreReal(udg_Game_Cache, I2S(H2I(timerA)), "Rej_Heal", GetUnitAbilityLevel(GetTriggerUnit(), 'A00U') * 25.)
    if timerA == null then
        set timerA = CreateTimer()
        call StoreInteger(udg_Game_Cache, I2S(H2I(unitA)),  "Rej_Time", H2I(timerA))
        call StoreInteger(udg_Game_Cache, I2S(H2I(timerA)), "Rej_Targ", H2I(unitA))
        call TimerStart(timerA, 1., true, function Spell_Rejuvination_Tick)
    endif
    set unitA  = null
    set timerA = null
endfunction
Старый 14.04.2008, 18:16
adic3x

offline
Опыт: 108,439
Активность:
зачем к юниту аттачить таймер?
Старый 14.04.2008, 18:25
J
expert
offline
Опыт: 48,447
Активность:
ADOLF чтобы если повторно наслать на юнита спел то действее спела не удваивалось бы

Jon добавил:
хотя там при создании таймера можно проверку на баф делать... я хз, я просто привел код в состояние что должен работать, над алгоритмикой пусть думает автор
Старый 14.04.2008, 18:30
adic3x

offline
Опыт: 108,439
Активность:
Цитата:
чтобы если повторно наслать на юнита спел то действее спела не удваивалось бы

проверять бафф/аттачить в узер дату один бит-бул
Старый 14.04.2008, 18:37
ShadoW DaemoN

offline
Опыт: 37,078
Активность:
ADOLF, имхо, mission accomplished. Юзеру требовалось разобраться в чем ошибка, я привел некоторые выражения, как в данном случае можно было бы сделать, и привел код с минимальными изменениями.
Вероятным может оказаться, что юзердата занята чем-то другим.
+ я добавил после кода, что лучше бы и без кэша обойтись...
Кстати, про баффы я как-то сразу не сообразил =)

FellGuard, ок-ок, моя каюсь ^^ Я еще утречком хотел ответ выслать, но не получилось.

Цитата:
Сообщение от Jon
я просто привел код в состояние что должен работать

Он вообще-то и так работал (имеется в виду алгоритм), а чтение/запись кэша - это уже не сколько к алгоритму относится, сколько к обеспечению. >_<
Старый 14.04.2008, 19:14
Kenshi245

offline
Опыт: 2,252
Активность:
Вот моя отредактированная версия (Учитывает еще и то, что могут баффнуть спеллами разного лвл)
Код:
// ### Rejuvenation Spell ###
function Spell_Rejuvenation_Tick takes nothing returns nothing
    local timer timerA = GetExpiredTimer()
    local unit unitA = I2U(GetStoredInteger(udg_Game_Cache, I2S(H2I(timerA)), "Rej_Tar"))
    local real HealingA = GetStoredInteger(udg_Game_Cache, I2S(H2I(unitA)), "Rej_Heal")*GetRandomReal(0.95,1.05)
    if GetUnitAbilityLevel(unitA, 'B00L') > 0 then
    call TextTargetA(unitA,HealingA,2,false) // Функция лечения
    else
    call FlushStoredInteger(udg_Game_Cache, I2S(H2I(timerA)),"Rej_Tar")
    call FlushStoredInteger(udg_Game_Cache, I2S(H2I(unitA)),"Rej_Heal")
    call DestroyTimer(timerA)
    endif
    set timerA = null
    set unitA = null
endfunction

function Spell_Rejuvenation takes nothing returns nothing
    local timer timerA
    local unit unitA = GetTriggerUnit()
    local unit unitB = GetSpellTargetUnit()
    local integer pID = GetPlayerId(GetOwningPlayer(unitA))
    local real HealingA = GetUnitAbilityLevel(unitA,'A00U')*25*(udg_Hpw[pID]*0.002+1) // Подсчет урона от скила
    if GetStoredInteger(udg_Game_Cache, I2S(H2I(unitB)), "Rej_Heal") == 0 then
    set timerA = CreateTimer()
    call StoreInteger(udg_Game_Cache, I2S(H2I(timerA)), "Rej_Tar", H2I(unitB))
    call TimerStart(timerA, 1, true, function Spell_Rejuvenation_Tick)
    endif
    call StoreInteger(udg_Game_Cache, I2S(H2I(unitB)), "Rej_Heal", R2I(HealingA))
    set timerA = null
    set unitA = null
    set unitB = null
endfunction


А кстати как можно это без кеша сделать?

Отредактировано Kenshi245, 16.04.2008 в 21:46.
Старый 16.04.2008, 21:41
YellowStar
poon
offline
Опыт: 15,144
Активность:
ADOLF ярый противник кеша. Не такой уж он и плохой ии лично я использую его не только для переноса между миссиями, мне с ним тупо проще да и код запутанный выходит :D не сразуможно разобратся что к чему
Старый 17.04.2008, 06:25
Закрытая тема

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

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

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

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



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