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

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

Закрытая тема
 
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
Перемещение с помощью кеша
Думаю тема многим поможет, если я в ней найдут ответ на вопрос (т.к. много новичков, заказывающих способности, коротые отталкивает на расстояние, или просто способности с использованием кеша). Вот я начитался статей всяких про RB, про SCV вроде чтото понял но не совсем чтобы уже вободно способности писать с нуля. Так чтобы на практике разобрать, решил сделать способность, которая перемещяет в указанную точку и наносит урон всем по пути (Вроде "Wave form" у морфинга из доты). Только урон будет наносится не только один раз каждому воину а просто всем кто рядом. Для начала я создал триггер "InitCache", перевел его в текст и инитиализировал кеш. пока вроде ошибок не выдавал... но что делать дальше как перемещять героя "c" поляркой когда у меня только cx,cy,tx,ty я в JNGP смотрел там какаята обракодабра... закончите мой код пожалуста, буду благодарен. пожалуста говорите мне о всех ошибках которые я делаю...чтож вот что пока у меня есть:
» Весь Custom Script
Код:
//Custom Code
function H2I takes handle h returns integer
 return h
 return 0
endfunction

function I2U takes integer i returns unit
 return i
 return null
endfunction

//Triggers

//=================================================
function InitTrig_InitCache takes nothing returns nothing
 call FlushGameCache(InitGameCache("AbilityCache.w3v"))
 set udg_AbilityCache=InitGameCache("AbilityCache.w3v")
endfunction

//==================================================

function Trig_SpiritForm_Conditions takes nothing returns boolean
 return GetSpellAbilityId() == 'A000'
endfunction

function move takes nothing returns nothing
 local gamecache gc=udg_AbilityCache
 local timer ti=GetExpiredTimer()
 local string s=I2S(H2I(ti))
 local unit c=I2U(GetStoredInteger(gc,s,"caster"))
 local real tx=GetStoredReal(gc,s,"targx")
 local real ty=GetStoredReal(gc,s,"targy")
 local real cx=GetUnitX(c)
 local real cy=GetUnitY(c)

//...
endfunction

function Trig_SpiritForm_Actions takes nothing returns nothing
 local unit c=GetTriggerUnit()
 local gamecache gc=udg_AbilityCache
 local timer ti=CreateTimer()
 local string s=I2S(H2I(ti))
 local real cx=GetUnitX(c)
 local real cy=GetUnitY(c)
 local real tx=GetLocationX(GetSpellTargetLoc())
 local real ty=GetLocationY(GetSpellTargetLoc())

 call StoreInteger(gc,s,"caster",H2I(c))
 call StoreReal(gc,s,"targx",tx)
 call StoreReal(gc,s,"targy",ty)

 call TimerStart(ti,0.04,true,function move)

 set c=null
 set gc=null
 set ti=null
 set s=""
 set cx=0.00
 set cy=0.00
 set tx=0.00
 set ty=0.00
endfunction

function InitTrig_SpiritForm takes nothing returns nothing
    set gg_trg_SpiritForm = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_SpiritForm, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_SpiritForm, Condition( function Trig_SpiritForm_Conditions ) )
    call TriggerAddAction( gg_trg_SpiritForm, function Trig_SpiritForm_Actions )
endfunction

Отредактировано Bee, 30.05.2009 в 23:44.
Старый 30.05.2009, 21:22
J
expert
offline
Опыт: 48,447
Активность:
ну... _я_ бы сделала таг:
писал в блокноте не проверяя, могут быть ошибки
» раскрыть
Код:
globals
    group GG = CreateGroup()
    integer TempForGroup = 0
endglobals

library SpiritForm initializer Init

globals    
    private constant real g_Period = 0.04
    private timer g_Tm = CreateTimer()  
    private filterfunc g_ff
    private code g_functimer
    
    private SpiritForm array g_AllSpiritForm
    private integer g_CountSpiritForm = 0
endglobals

struct SpiritForm
    private integer Index
                  
    private unit Caster
    private real X
    private real Y
    private real SX
    private real SY
    private integer CountMove
    private real Range
    private real Damag

    static method FilterUnit takes nothing returns boolean
        local SpiritForm this = TempForGroup
        local unit f = GetFilterUnit()
        if (f != .Caster) then
            call UnitDamageTarget(.Caster, f, .Damag, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
        endif
        return false
    endmethod
    
    method Period takes nothing returns nothing
        set .X = .X + .SX                   
        set .Y = .Y + .SY
        set .CountMove = .CountMove - 1
        if (.CountMove > 0) then
            call SetUnitX(.Caster, .X) 
            call SetUnitY(.Caster, .Y)
            set TempForGroup = this
            call GroupEnumUnitsInRange(GG, .X, .Y, .Range, g_ff)
        else
            call .Delete()
            call .destroy()
        endif
    endmethod
    
    private method Add takes nothing returns nothing
        if (g_CountSpiritForm == 0) then
            call TimerStart(g_Tm, g_Period, true, g_functimer)
        endif
        set g_AllSpiritForm[g_CountSpiritForm] = this
        set .Index = g_CountSpiritForm
        set g_CountSpiritForm = g_CountSpiritForm + 1
    endmethod
    
    private method Delete takes nothing returns nothing
        set g_CountSpiritForm = g_CountSpiritForm - 1
        set g_AllSpiritForm[.Index] = g_AllSpiritForm[g_CountSpiritForm]
        set g_AllSpiritForm[.Index].Index = .Index
        if (g_CountSpiritForm == 0) then
            call PauseTimer(g_Tm)
        endif
    endmethod

    static method Cast takes unit Caster, location Target, real Speed, real Range, real Damag returns nothing
        local SpiritForm this = SpiritForm.create()
        local timer tm = CreateTimer()
        local real tx = GetLocationX(Target)
        local real ty = GetLocationY(Target)
        local real len
        set .Range = Range
        set .Damag = Damag*g_Period
        set .Caster = Caster
        set .X = GetUnitX(Caster)
        set .Y = GetUnitY(Caster)
        set .SX = tx-.X  
        set .SY = ty-.Y
        set len = SquareRoot(.SX*.SX+.SY*.SY)/Speed
        set .SX = .SX/len
        set .SY = .SY/len
        set .CountMove = R2I(len)
        call .Add()
    endmethod

endstruct
    
private function FunctionTimer takes nothing returns nothing
    local integer i = g_CountSpiritForm - 1
    loop
        call g_AllSpiritForm[i].Period()
        exitwhen i == 0
        set i = i - 1
    endloop
endfunction

private function Init takes nothing returns nothing
    set g_functimer = function FunctionTimer
    set g_ff = Filter(function SpiritForm.FilterUnit)
endfunction

endlibrary

function Trig_SpiritForm_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function Trig_SpiritForm_Actions takes nothing returns nothing
    local unit c = GetTriggerUnit()
    local location t = GetSpellTargetLoc()
    // 10 - скорость
    // 256 - расстояние в котором будет наносится урон
    // 100 - урон в секунду
    call SpiritForm.Cast(c, t, 10.0, 256.0, 100.0)
    call RemoveLocation(t)
    set c = null 
    set t = null
endfunction

function InitTrig_SpiritForm takes nothing returns nothing
    set gg_trg_SpiritForm = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_SpiritForm, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_SpiritForm, Condition(function Trig_SpiritForm_Conditions))
    call TriggerAddAction(gg_trg_SpiritForm, function Trig_SpiritForm_Actions)
endfunction

Отредактировано J, 01.06.2009 в 17:30.
Старый 31.05.2009, 07:13
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
омг... опять vJass!!! он меня преследует... =) мне Jass'a хватит. Меня интересует обнуление кеша переменной строки "s". т.е. я запускаю таймер, потом способность заканчивается и какими действиями все надо почистить (касается кеша)
ну помогите! пожалуйста... как очищать кеш от неиспользуемых переменных т.е. "s" (код вверху)

Отредактировано alexkill, 31.05.2009 в 21:20.
Старый 31.05.2009, 16:30
alexkill

offline
Опыт: 18,872
Активность:
Цитата:
Сообщение от Bee
ну помогите! пожалуйста... как очищать кеш от неиспользуемых переменных т.е. "s" (код вверху)

Код:
native FlushStoredMission takes gamecache cache, string missionKey returns nothing

missionKey - переведенный в строку хэндл твоего таймера

Также тебе понадобится эта функция для расчета угла между координатами:
Код:
function Angle takes real AX, real AY, real BX, real BY returns real
  return Atan2(BY-AY, BX-AX)
endfunction

И вот эта для пошагового расчета расстояния между координатами:
Код:
function Distance takes real AX, real AY, real BX, real BY returns real
  return SquareRoot((BX - AX) * (BX - AX) + (BY - AY) * (BY - AY))
endfunction

Нижеперечисленные переменные обнулять не нужно, они утечек не вызовут:
Код:
set s=""
 set cx=0.00
 set cy=0.00
 set tx=0.00
 set ty=0.00

И еще советую забросить кеш. Используй структуры (вариант жона), либо просто массивы (чтоб вжассом голову не забивать).
Старый 31.05.2009, 21:31
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
alexkill огромное спасибо!!! пока не закрыто...

Bee добавил:
Цитата:
И еще советую забросить кеш. Используй структуры (вариант жона), либо просто массивы (чтоб вжассом голову не забивать).
просто хочется сделать норм спеллы без глобальных и vJassa.
Старый 31.05.2009, 21:34
ScorpioT1000
Работаем
offline
Опыт: отключен
Цитата:
просто хочется сделать норм спеллы без глобальных и vJassa.

зачем? ни скилла от этого, ни пользы
Старый 31.05.2009, 21:58
J
expert
offline
Опыт: 48,447
Активность:
Цитата:
просто хочется сделать норм спеллы без глобальных и vJassa.
ололо... какие нынче новечки пошли... ты нешариш...
это фактически определение мягко сказать "НЕнорм спела"
Старый 31.05.2009, 22:09
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
Цитата:
зачем? ни скилла от этого, ни пользы
с чего ты взял? если все правильно сделать то спелл крутой может получится.
Старый 31.05.2009, 22:09
J
expert
offline
Опыт: 48,447
Активность:
пока еще толкьо начинаеш учись слушать что тебе говорят, потом небудеш удивляться почему твои крутые спелы будут называть уг всеголиш раз вглянув на код
Старый 31.05.2009, 22:13
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
J ладно. потом мб буду идивлятся, но сейчас я редактирую и радуюсь жизни! Мне нравится то что я делаю. А это главное!. чето я начал филосовствовать
Старый 31.05.2009, 22:19
ScorpioT1000
Работаем
offline
Опыт: отключен
Цитата:
с чего ты взял? если все правильно сделать то спелл крутой может получится.

потомучто кеш предназначался для красивого и удобного упакования масс информации в один целый файл. а с вашими scv итп только пудрят мозги и представление о структуре памяти. Лучше один раз понять как работают параллельные массивы + индекс в custom value, чем все время писать то, что полностью понять не можешь
Старый 31.05.2009, 22:19
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
появился новый вопрос: как фильтром отловить врага? т.е.
Код:
local gamecache gc=udg_gamecache
 local timer t=GetExpiredTimer()
 local string s=I2S(H2I(t))
 local unit c=I2U(GetStoredInteger(gc,s,"c"))
 local location l=GetUnitLoc(c)
 local group g=CreateGroup()
 local real r=600.00
 local boolexpr b=Condition(function fdfd)

 call GroupEnumUnitsInRangeOfLoc(g,l,r,b)
 call ForGroup(g, function ggg)
(выше есть функция фильтра на то что GetFilterUnit() не здание, живой, и если он враг) но кого написать в функции которая берет 2 воина.
Код:
function fdfd takes nothing returns boolean
 return ...IsUnitEnemy(GetFilterUnit(), <<?>> == true
endfunction
нужно чтобы на месте вопроса был unit "c". как это сделать? или нужно обязательно создать udg_...?
Старый 02.06.2009, 16:08
J
expert
offline
Опыт: 48,447
Активность:
боже што за гомно, в моем случае чтобы действовало на врагов надо заменить строчку
Код:
if (f != .Caster) then
на
Код:
if (f != .Caster and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(.Caster)) then
Старый 02.06.2009, 16:23
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
Цитата:
в моем случае

Jэто не твой случай со структурами на вжасс. здесь нет vjassa и я его использовать не собраюсь.
Старый 02.06.2009, 16:30
J
expert
offline
Опыт: 48,447
Активность:
мне безразници, если человек хочет ответ на вопрос я отвечаю, нравится ему ответ иил нет)
Старый 02.06.2009, 16:33
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
чтож придется заносить в переменную? или другой вариант есть?

Bee добавил:
хм... видимо "да". ну спасибо за все ответы в этой теме...
Старый 02.06.2009, 17:47
Закрытая тема

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

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

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

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



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