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

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

Ответ
 
Alex_Hell
Mapmaker 'N' Programmer
offline
Опыт: 6,885
Активность:
Спелл "Бомбардировка"
Я создаю свою новую карту и специально для нее придумал спелл Бомбардировка, вызывающий 3-х бомбардировщиков, которые сбрасывают снаряды(с помощью дамми-юнита, движущегося за бомбардировщиком) и летают по области...но я протестил спелл и
ничего не получается...бомбардировщики почти сразу летят куда-то наверх(все 3-е) и остаются там до окончания спелла(5 сек.)...а также дамми-юниты должны атаковать местность и находиться в воздухе, следуя за бомбером...но они на земле(в настройках юнита поставил и max высоту и высоту на 350!).
Я пробовал разобраться в чем дело, но так и не понял...уже голова раздувается в этом коде копаться
Думаю, что дело в локациях, в которые летят бомбардировщики, чего-то там не так...прошу у вас помощи и выкладываю тут весь спелл:
» globals

Код:
globals
    unit array udg_bomber
    location array udg_order
    location array udg_currentorder
    integer array udg_currentordernum
endglobals



» триггер, запускающийся при касте спелла

Код:
function Bomb takes unit u, location point returns nothing
///////////////////////////////////////
////////Спелл "Бомбардировка"//////////
////вызов 3-х бомбардировщиков,////////
//атакующих всех врагов в выбранной////
//////области, включая здания./////////
////////Время действия - 5 сек.////////
//////Область воздействия - 350////////
//создан на основе заклинания "Гроза"//
/////////Автор: Alex_Hell//////////////
//===========================================================================
// u = GetSpellAbilityUnit()//////
//point =  = GetSpellTargetLoc()//
//////////////////////////////////
    local integer i = GetUnitAbilityLevel(u,'A007')
    local integer bomberid
    local location p = point
    local trigger array trg
//===========================================================================
//u00[0-3] = дамми-юнит с масштабированием 0.01, выполняющий роль атакующего
    if i == 1 then
        set bomberid = 'u000'//1-й уровень
//===========================================================================
    elseif i == 2 then
        set bomberid = 'u001'//2-й уровень
//===========================================================================
    elseif i == 3 then
        set bomberid = 'u002'//3-й уровень
//===========================================================================
    else
        set bomberid = 'u003'//4-й уровень
    endif
//===========================================================================
//создание бомбера(дирижабль гоблинов) для видимости:
    set udg_bomber[0] = CreateUnitAtLoc(GetOwningPlayer(u),bomberid,p,270.00)
//создание дамми-юнита для атаки:
    set udg_bomber[3] = CreateUnitAtLoc(GetOwningPlayer(u),'u004',p,270.00)
    set udg_order[0] = p
//===========================================================================
    call MoveLocation(p,GetLocationX(p)+250*CosBJ(45),GetLocationY(p)+250*SinBJ(45))
    set udg_bomber[1] = CreateUnitAtLoc(GetOwningPlayer(u),bomberid,p,270.00)
    set udg_bomber[4] = CreateUnitAtLoc(GetOwningPlayer(u),'u004',p,270.00)
    set udg_order[6] = p
//===========================================================================
    call MoveLocation(p,GetLocationX(point)+250*CosBJ(135),GetLocationY(point)+250*SinBJ(  135))
    set udg_bomber[2] = CreateUnitAtLoc(GetOwningPlayer(u),bomberid,p,270.00)
    set udg_bomber[5] = CreateUnitAtLoc(GetOwningPlayer(u),'u004',p,270.00)
    set udg_order[12] = p
//===========================================================================
//занесение в глобальный массив точки, в которые по-очереди будут двигаться бомберы
    call MoveLocation(p,GetLocationX(point)+100*CosBJ(135),GetLocationY(point)+100*SinBJ(  135))
    set udg_order[1] = p
    call MoveLocation(p,GetLocationX(p)+75*CosBJ(190),GetLocationY(p)+75*SinBJ(190))
    set udg_order[2] = p
    call MoveLocation(p,GetLocationX(p)+75*CosBJ(250),GetLocationY(p)+75*SinBJ(250))
    set udg_order[3] = p
    call MoveLocation(p,GetLocationX(p)+75*CosBJ(350),GetLocationY(p)+75*SinBJ(350))
    set udg_order[4] = p
    call MoveLocation(p,GetLocationX(p)+75*CosBJ(45),GetLocationY(p)+75*SinBJ(45))
    set udg_order[5] = p
//===========================================================================
    call MoveLocation(p,GetLocationX(udg_order[6])+75*CosBJ(120),GetLocationY(udg_order[6])+75*SinBJ(120))
    set udg_order[7] = p
    call MoveLocation(p,GetLocationX(p)+100*CosBJ(190),GetLocationY(p)+100*SinBJ(190))
    set udg_order[8] = p
    call MoveLocation(p,GetLocationX(p)+75*CosBJ(275),GetLocationY(p)+75*SinBJ(275))
    set udg_order[9] = p
    call MoveLocation(p,GetLocationX(p)+75*CosBJ(320),GetLocationY(p)+75*SinBJ(320))
    set udg_order[10] = p
    call MoveLocation(p,GetLocationX(p)+75*CosBJ(150),GetLocationY(p)+75*SinBJ(150))
    set udg_order[11] = p
//===========================================================================
    call MoveLocation(p,GetLocationX(udg_order[12])+75*CosBJ(65),GetLocationY(udg_order[12])+75*SinBJ(65))
    set udg_order[13] = p
    call MoveLocation(p,GetLocationX(p)+75*CosBJ(350),GetLocationY(p)+75*SinBJ(350))
    set udg_order[14] = p
    call MoveLocation(p,GetLocationX(p)+75*CosBJ(250),GetLocationY(p)+75*SinBJ(250))
    set udg_order[15] = p
    call MoveLocation(p,GetLocationX(p)+100*CosBJ(110),GetLocationY(p)+100*SinBJ(110))
    set udg_order[16] = p
    call MoveLocation(p,GetLocationX(p)+75*CosBJ(20),GetLocationY(p)+75*SinBJ(20))
    set udg_order[17] = p
//===========================================================================
    set udg_currentorder[0] = udg_order[1]
    set udg_currentorder[1] = udg_order[7]
    set udg_currentorder[2] = udg_order[13]
    set udg_currentordernum[0] = 1
    set udg_currentordernum[1] = 7
    set udg_currentordernum[2] = 13
//===========================================================================
//создание триггера, отдающего приказ "move" бомберам(см. нест. код)
    set trg[0] = CreateTrigger()
    call TriggerRegisterTimerEventPeriodic(trg[0], 0.20)
    call TriggerAddAction(trg[0], function Trig_bomber_move_Actions)
//===========================================================================
//создание триггера, двигающего дамми-юниты за бомберами(см. нест. код)
    set trg[1] = CreateTrigger()
    call TriggerRegisterTimerEventPeriodic(trg[1], 0.05)
    call TriggerAddAction(trg[1], function Trig_bomber_motion_Actions)
//===========================================================================
//создание триггера, заставляющего дамми-юнитов атаковать(см. нест. код)
    set trg[2] = CreateTrigger()
    call TriggerRegisterTimerEventPeriodic(trg[2], 1.00)
    call TriggerAddAction(trg[2], function Trig_bomber_attack_Actions)
//===========================================================================
    call TriggerSleepAction(5.4)
//===========================================================================
    set bj_forLoopAIndex = 0
    set bj_forLoopAIndexEnd = 5
//===========================================================================
//обнуление переменных и удаление триггеров
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        call DestroyTrigger(trg[bj_forLoopAIndex])
        set trg[bj_forLoopAIndex] = null
        call RemoveLocation(udg_currentorder[bj_forLoopAIndex])
        set udg_currentorder[bj_forLoopAIndex] = null
        set udg_currentordernum[bj_forLoopAIndex] = 0
        call RemoveUnit(udg_bomber[bj_forLoopAIndex])
        set udg_bomber[bj_forLoopAIndex] = null
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
//===========================================================================
    set bj_forLoopAIndex = 0
    set bj_forLoopAIndexEnd = 17
//===========================================================================
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        call RemoveLocation(udg_order[bj_forLoopAIndex])
        set udg_order[bj_forLoopAIndex] = null
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
//===========================================================================
    set u = null
    call RemoveLocation(p)
    call RemoveLocation(point)
    set p = null
    set point = null
endfunction




» нестандартный код

Код:
function Bomber_Motion takes integer i returns nothing
//двигает дамми-юнита за бомбером
    local unit u = udg_bomber
    local location p = GetUnitLoc(udg_bomber[i+3])
//===========================================================================
    call SetUnitX(u,GetLocationX(p))
    call SetUnitY(u,GetLocationY(p))
    call SetUnitFlyHeight(u,350.00,0.00)//должно поднимать дамми-юнита в воздух, но этого не просходит
//===========================================================================
    set u = null
    call RemoveLocation(p)
    set p = null
endfunction
//###########################################################################
function Trig_bomber_move_Actions takes nothing returns nothing
//приказывает бомберу двигаться
    local real array X
    local real array Y
    local rect array R
//===========================================================================
    set bj_forLoopAIndex = 0
    set bj_forLoopAIndexEnd = 2
//===========================================================================
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        set X[bj_forLoopAIndex] = GetLocationX(udg_currentorder[bj_forLoopAIndex])
        set Y[bj_forLoopAIndex] = GetLocationY(udg_currentorder[bj_forLoopAIndex])
        set R[bj_forLoopAIndex] = Rect(X[bj_forLoopAIndex],Y[bj_forLoopAIndex],X[bj_forLoopAIndex],Y[bj_forLoopAIndex])
//===========================================================================
//если бомбер уже на этой локации - изменить currentorder-локацию
        if( RectContainsUnit(R[bj_forLoopAIndex], udg_bomber[bj_forLoopAIndex+3]) == true ) then
            set udg_currentorder[bj_forLoopAIndex] = udg_order[udg_currentordernum[bj_forLoopAIndex]+1]
        endif
//===========================================================================
        call IssuePointOrderLocBJ( udg_bomber[bj_forLoopAIndex+3], "move", udg_currentorder[bj_forLoopAIndex] )
        set R[bj_forLoopAIndex] = null
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
endfunction
//###########################################################################
//приказывает дамми-юнитам атаковать местность под собой
function Trig_bomber_attack_Actions takes nothing returns nothing
    local location array P
//===========================================================================
    set bj_forLoopAIndex = 0
    set bj_forLoopAIndexEnd = 2
//===========================================================================
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        set P[bj_forLoopAIndex] = GetUnitLoc(udg_bomber[bj_forLoopAIndex])
        call IssuePointOrderLocBJ(udg_bomber[bj_forLoopAIndex], "attackground", P[bj_forLoopAIndex])
        call RemoveLocation(P[bj_forLoopAIndex])
        set P[bj_forLoopAIndex] = null
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
endfunction
//###########################################################################
//передает номер дамми-юнита в функцию движения
function Trig_bomber_motion_Actions takes nothing returns nothing
    set bj_forLoopAIndex = 0
    set bj_forLoopAIndexEnd = 2
//===========================================================================
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        call Bomber_Motion(bj_forLoopAIndex)
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
endfunction



[i]Если мне кто-нибудь сможет помоч разобраться, в чем тут дело...я буду ему очень благодарен
Ваш
Alex_Hell
Старый 13.07.2007, 15:27
FellGuard
Losyash
offline
Опыт: 39,547
Активность:
Alex_Hell, вот, может быть, сходный спелл, на гуи :)
Старый 13.07.2007, 15:56
p01nTT

offline
Опыт: 10,760
Активность:
во первых юзай не периодические триггеры, а таймеры )
Старый 13.07.2007, 15:59
FellGuard
Losyash
offline
Опыт: 39,547
Активность:
не вникал, ибо делаю это долго как бегемот, но 1) избавься от циклов с перечислителем-глобалкой (exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd, set bj_forLoopAIndex = bj_forLoopAIndex + 1), замени на локальную переменную. И второе - там гден в воздух не поднимается юнит - уверен что он может летать? Если у него пеший тип передвижения то абилу 'Amrf' ему в лапы
Старый 13.07.2007, 15:59
Alex_Hell
Mapmaker 'N' Programmer
offline
Опыт: 6,885
Активность:
Цитата:
Сообщение от FellGuard
не вникал, ибо делаю это долго как бегемот, но 1) избавься от циклов с перечислителем-глобалкой (exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd, set bj_forLoopAIndex = bj_forLoopAIndex + 1), замени на локальную переменную. И второе - там гден в воздух не поднимается юнит - уверен что он может летать? Если у него пеший тип передвижения то абилу 'Amrf' ему в лапы


1)а почему нужно глобалку на локалку заменить, от этого чт0-то меняется?
2)У него тип передвижения - летающий...'Amrf' - это че за абила?

Alex_Hell добавил:
Цитата:
Сообщение от p01nTT
во первых юзай не периодические триггеры, а таймеры )


А по-подробнее > ...,?
Таймеры...как реализовать?...типа создаеш таймер и он при своем end-е выполняет функцию, так?...

Так че мне никто не подскажет из-за чего бомберы могут не туда лететь?
Старый 14.07.2007, 13:07
FellGuard
Losyash
offline
Опыт: 39,547
Активность:
just do like we told you..
1) в каждом выполнении цикла, если потоков несколько, ряд чисел с локалками будет
Код:
------> 1 2 3 4 5 6 7 8
___|
   |______> 1 2 3 4 5 6 7 8
когда как с глобальной
Код:
------> 1 3 5 7 9 11 13 15
___|
   |______> 2 4 6 8 10 12 14 16
Уловил суть? ГЛОБАЛЬНАЯ переменная. Изменение ее в одном потоке повлечет смену значений во всех остальных выполняющихся ф-иях, содержащих эту же глобальную переменную.

FellGuard добавил:
2) Amrf - абила превращение в ворона, но раз юни т леткющий, то значит алгоритм либо не успевает дойти до того действия (анпример, ты подвесил цикл, и он никак не может завершится), либо ошибка в самом дейсвтии (неправильно устанловлена переменная до этого или в самом вызове ф-ии не та переменная)

FellGuard добавил:
Alex_Hell, Jass API. После создания таймера его можно запустить ф-ией TimerStart, как периодический с определенной частотой выполнения и повесить на таймер какую-нибудь функцию.

FellGuard добавил:
кстати зайди по ссылке на гуишный спелл, который я давал выше. У любых юнитов, подконтрольных игроку не-человеку периодически дается приказ лететь на исходную его позицию (guard position)
В триггерах есть ф-ии
ИИ - Ignore unit`s guard position
ИИ - Ignore all player`s units guard position

Тебе нужно для всех бомбардиров проигнорить эти позиции (Ignore unit`s guard position после создания юнита) и постоянно давать приказ перемещаться. Тогда проблем не должно возникнуть
Старый 14.07.2007, 14:36
Alex_Hell
Mapmaker 'N' Programmer
offline
Опыт: 6,885
Активность:
Суть заменения глобалки на локалку я понял...но проблема была не в этом...
Во-первых у меня просто локации были на маленьком расстоянии друг от друга
Во-вторых триггер отдания приказа работал некорректно:
Цитата:
function Trig_bomber_move_Actions takes nothing returns nothing
//приказывает бомберу двигаться
local real array X
local real array Y
local rect array R
//===========================================================================
set bj_forLoopAIndex = 0
set bj_forLoopAIndexEnd = 2
//===========================================================================
loop
exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
set X[bj_forLoopAIndex] = GetLocationX(udg_currentorder[bj_forLoopAIndex])
set Y[bj_forLoopAIndex] = GetLocationY(udg_currentorder[bj_forLoopAIndex])
set R[bj_forLoopAIndex] = Rect(X[bj_forLoopAIndex],Y[bj_forLoopAIndex],X[bj_forLoopAIndex],Y[bj_forLoopAIndex])
//===========================================================================
//если бомбер уже на этой локации - изменить currentorder-локацию
if( RectContainsUnit(R[bj_forLoopAIndex], udg_bomber[bj_forLoopAIndex+3]) == true ) then
//то, что серым цветом - это как было
set udg_currentorder[bj_forLoopAIndex] = udg_order[udg_currentordernum[bj_forLoopAIndex]+1]
//а надо было так:
set udg_currentordernum[bj_forLoopAIndex] = udg_currentordernum[bj_forLoopAIndex] + 1
set udg_currentorder[bj_forLoopAIndex] = udg_order[udg_currentordernum[bj_forLoopAIndex]]

//из-за этого приказ отдавался, а currentordernum не увеличивался и каждый последующий раз происходило тоже самое и бомбер стоял
endif
//===========================================================================
call IssuePointOrderLocBJ( udg_bomber[bj_forLoopAIndex+3], "move", udg_currentorder[bj_forLoopAIndex] )
set R[bj_forLoopAIndex] = null
set bj_forLoopAIndex = bj_forLoopAIndex + 1
endloop
endfunction


Свой спелл я сделал, FellGuard, спасибо за помощь
Старый 15.07.2007, 17:06
Ответ

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

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

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

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



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