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

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

Ответ
 
Laikon
Жаркие времена..
offline
Опыт: 16,636
Активность:
Обьясните дураку
В общем я совсем нуб в джассе и вот решил сделать способность. Используются только локалки, простой скилл типа Исцеляющий Газ после поздния снарядов происходит 3 взрыва (модельки самодельные) и наносится урон врагам. На гуи все нормально, но когда я переношу на джасс и делаю локальные переменные вообще нечего не работает, в чем проблема не могу понять.
Код креплю снизу так как с телефона пишу и подругому не получается.
Прикрепленные файлы
Тип файла: rar PoisonBomb.rar (787 байт, 3 просмотров )
Старый 29.03.2012, 03:24
quq_CCCP
Я белый и пушистый!
offline
Опыт: 93,279
Активность:
Постараюсь помоч
» вот твой код:
((код jass
function Trig_PoisonBomb_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A016' ) ) then
return false
endif
return true
endfunction
function Trig_PoisonBomb_Func010Func001C takes nothing returns boolean
if ( not ( GetOwningPlayer(GetEnumUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE) ) ) then
return false
endif
return true
endfunction
function Trig_PoisonBomb_Func010A takes unit H returns nothing
if ( Trig_PoisonBomb_Func010Func001C() ) then
call UnitDamageTargetBJ( H, GetEnumUnit(), ( 99.00 + 1.00 ), ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
else
endif
endfunction
function Trig_PoisonBomb_Actions takes nothing returns nothing
local unit H = GetSpellAbilityUnit()
local location T = GetSpellTargetLoc()
call TriggerSleepAction( ( DistanceBetweenPoints(GetUnitLoc(H), T) / 700.00 ) )
call AddSpecialEffectLocBJ( GetRandomLocInRect(RectFromCenterSizeBJ(T, 100.00, 100.00)), "PoisonBomb Effect.mdx" )
call DestroyEffectBJ( GetLastCreatedEffectBJ() )
call AddSpecialEffectLocBJ( GetRandomLocInRect(RectFromCenterSizeBJ(T, 100.00, 100.00)), "PoisonBomb Effect.mdx" )
call DestroyEffectBJ( GetLastCreatedEffectBJ() )
call AddSpecialEffectLocBJ( GetRandomLocInRect(RectFromCenterSizeBJ(T, 100.00, 100.00)), "PoisonBomb Effect.mdx" )
call DestroyEffectBJ( GetLastCreatedEffectBJ() )
call AddSpecialEffectTargetUnitBJ( "overhead", H, "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl" )
call DestroyEffectBJ( GetLastCreatedEffectBJ() )
call ForGroupBJ( GetUnitsInRangeOfLocAll(150.00, T), function Trig_PoisonBomb_Func010A )
set H = null
set T = null
endfunction
===========================================================================
function InitTrig_PoisonBomb takes nothing returns nothing
set gg_trg_PoisonBomb = CreateTrigger( )
call DisableTrigger( gg_trg_PoisonBomb )
call TriggerRegisterAnyUnitEventBJ( gg_trg_PoisonBomb, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( gg_trg_PoisonBomb, Condition( function Trig_PoisonBomb_Conditions ) )
call TriggerAddAction( gg_trg_PoisonBomb, function Trig_PoisonBomb_Actions )
endfunction
))
вот это:
((код jass
function Trig_PoisonBomb_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A016' ) ) then
return false
endif
return true
endfunction
))
лучше заменить на это:
((код jass
function Trig_PoisonBomb_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A016'
endfunction
))
И лутьше всегда переписывай условия после конверта в гуи, так хоть читаемость повышается ну и чуть чуть быстродействие...
Далее:
((код Jass
function Trig_PoisonBomb_Func010Func001C takes nothing returns boolean
if ( not ( GetOwningPlayer(GetEnumUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE) ) ) then
return false
endif
return true
endfunction
))
Эта функция нам нафиг не нужна, поэтому делаем так:
((код Jass
function Trig_PoisonBomb_Func010A takes nothing returns nothing
if ( GetOwningPlayer(GetEnumUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE ) then
call UnitDamageTargetBJ( bj_groupRandomCurrentPick, GetEnumUnit(), 100.00, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
endif
endfunction
))
И как ты можеш давать аргумент функции которая вызывается функцией ForGroupBJ?
Все функции которые вызываются функциями в которых есть аргумент Code(***) не могут не брать не возвращать аргументы, те они процедуры, просто что то делают...
Далее:
((код Jass
function Trig_PoisonBomb_Actions takes nothing returns nothing
local unit uTemp = GetSpellAbilityUnit()
local location TempLoc = GetSpellTargetLoc()
call TriggerSleepAction( ( DistanceBetweenPoints(GetUnitLoc(uTemp), TempLoc) / 700.00 ) )
call DestroyEffect(AddSpecialEffectLocBJ( GetRandomLocInRect(RectFromCenterSizeBJ(TempLoc, 100.00, 100.00)), "PoisonBomb Effect.mdx" ))
call DestroyEffect(AddSpecialEffectLocBJ( GetRandomLocInRect(RectFromCenterSizeBJ(TempLoc, 100.00, 100.00)), "PoisonBomb Effect.mdx" ))
call DestroyEffect(AddSpecialEffectLocBJ( GetRandomLocInRect(RectFromCenterSizeBJ(TempLoc, 100.00, 100.00)), "PoisonBomb Effect.mdx" ))
call DestroyEffect(AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl", uTemp, "overhead" ))
set bj_wantDestroyGroup = true чтобы небыло утечки группы...
set bj_groupRandomCurrentPick = uTemp
call ForGroupBJ( GetUnitsInRangeOfLocAll(150.00, TempLoc), function Trig_PoisonBomb_Func010A )
call RemoveLocation(TempLoc)
set uTemp = null
set TempLoc = null
endfunction
))
вроде бы всё,
Все location (точка) нужно удалять функцией RemoveLocation(ссылка на точку)
Но увы эту функцию нельзя вызвать в гуи, ну если только через CustomScript...
Тоже самое с триггерами группами и аналогичными хендлами, их нужно удалять после использования...
Если интересно как сделать не по корявому то учи jass)
есть вопросы по коду задавай, что тебе не понятно?

Отредактировано quq_CCCP, 29.03.2012 в 06:43.
Старый 29.03.2012, 04:32
Rampage
Бицепс
offline
Опыт: 9,722
Активность:
quq_CCCP, это утечный вариант. Laikon, такие спеллы делаются хотя бы с таймерами и отловом урона. Научись пока что без снарядов. Снаряды не будут долетать - урон будет наноситься, или наоборот воин решит подбежать к тебе, а снаряд прилетевший снесет позже.
Старый 29.03.2012, 06:18
quq_CCCP
Я белый и пушистый!
offline
Опыт: 93,279
Активность:
Rampage, я нестал делать идеально оптимальный код лишь затем чтобы человек разобрался, он только гуи юзает...
Щяс напиши ему всё как надо, он будет смотреть на это как коза в афишу)
Старый 29.03.2012, 06:29
Laikon
Жаркие времена..
offline
Опыт: 16,636
Активность:
Я все исправил вроде бы, но нечего опять таки не работает. Вообще никак не реагирует, будто и нет никакого триггера. Смена скилла тоже не помогает.
И если можете скиньте код с исправлениями так же текстом, а то мне с телефона только часть кода видно.
Прикрепленные файлы
Тип файла: rar PoisonBomb.rar (758 байт, 3 просмотров )
Старый 29.03.2012, 15:47
ScorpioT1000
Работаем
offline
Опыт: отключен
Все функции которые вызываются функциями в которых есть аргумент Code(***)
это называется callback или handler, если что
Старый 29.03.2012, 15:51
Laikon
Жаркие времена..
offline
Опыт: 16,636
Активность:
Я дико извиняюсь, но мне кто нибудь может помочь с проблемой и обьяснить где я допустил ошибку?
Старый 30.03.2012, 01:57
DaeDR

offline
Опыт: 8,074
Активность:
Laikon, У тебя триггер просто не включен(вернее при создании он выключается):
function InitTrig_PoisonBomb takes nothing returns nothing
    set gg_trg_PoisonBomb = CreateTrigger(  )
    //call DisableTrigger( gg_trg_PoisonBomb ) убери вот это и все будет работать
    call TriggerRegisterAnyUnitEventBJ( gg_trg_PoisonBomb, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_PoisonBomb, Condition( function Trig_PoisonBomb_Conditions ) )
    call TriggerAddAction( gg_trg_PoisonBomb, function Trig_PoisonBomb_Actions )
endfunction
Старый 30.03.2012, 05:16
DaeDR

offline
Опыт: 8,074
Активность:
Laikon, Как бы сделал я: (хотя удаление эффектов лучше сделать через отдельную функцию, через таймеры)
» PoisonBomb
function Trig_PoisonBomb_Conditions takes nothing returns boolean
        return GetSpellAbilityId() == 'A016'
endfunction

function Trig_PoisonBomb_FILTER takes nothing returns boolean
        return (GetOwningPlayer(GetFilterUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endfunction

function Trig_PoisonBomb_Func010A takes nothing returns nothing
    call UnitDamageTarget( GetTriggerUnit(), GetEnumUnit(), ( 99.00 + 1.00 ), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
endfunction

function Trig_PoisonBomb_Actions takes nothing returns nothing
    //цель заклинания - точка
    local real xCast = GetUnitX(GetTriggerUnit()) //положение кастера по Х
    local real yCast = GetUnitY(GetTriggerUnit())//положение кастера по Y
    local real xTarget = GetSpellTargetX() //положение точки цели по Х
    local real yTarget = GetSpellTargetY() //положение точки цели по Y
    local real dx = xTarget - xCast //разница положений кастера и цели по Х
    local real dy = yTarget - yCast //разница положений кастера и цели по Y
    local real dist = SquareRoot(dx * dx + dy * dy) //дистанция между кастером и целью
    local real x
    local real y
    local real angle
    local group g = CreateGroup()
    local boolexpr f = Condition(function Trig_PoisonBomb_FILTER) //ссылка на функцию, которая возвращает "да" или "нет"
    local string s = "Abilities\\Spells\\Human\\Heal\\HealTarget.mdl" //эффект
    local effect array e //некоторые эффекты нельзя удалять сразу(т.к. у них нет анимации смерти и они просто удаляются)
    local integer i = 1
    local integer max = 3 //кол-во создаваемых эффектов
    call TriggerSleepAction( dist/700.00 )
    loop
     exitwhen i > max
        set angle = GetRandomReal (1,360) //случайное направление
        set x = xTarget + 100.0 * Cos(angle * bj_DEGTORAD) //случайное положение по Х от Х-цели
        set y = yTarget + 100.0 * Sin(angle * bj_DEGTORAD) //случайное положение по Y от Y-цели
        set e[i] = AddSpecialEffect ( s, x, y ) //эффект
     set i = i + 1
    endloop
    set s = null //обнуляем
    call GroupEnumUnitsInRange ( g, xTarget, yTarget, 150.0, f ) //выделяем всех в области (удовлетворяющие условиям f)
    call ForGroup( g, function Trig_PoisonBomb_Func010A ) //произодим действия
    call DestroyBoolExpr (f) //обнуление
    set f = null //обнуление
    call GroupClear (g) //обнуление
    call DestroyGroup (g) //обнуление
    set g = null //обнуление
    call TriggerSleepAction ( 2.0 ) //ждем, чтобы удалить эффекты
    set i = 1
    loop
     exitwhen i > max
        call DestroyEffect ( e[i] ) //удаляем все созданные эффекты
        set e[i] = null // и обнуляем переменные
     set i = i + 1
    endloop
endfunction

//===========================================================================
function InitTrig_PoisonBomb takes nothing returns nothing
    set gg_trg_PoisonBomb = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_PoisonBomb, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_PoisonBomb, Condition( function Trig_PoisonBomb_Conditions ) )
    call TriggerAddAction( gg_trg_PoisonBomb, function Trig_PoisonBomb_Actions )
endfunction
DaeDR добавил:
Там есть такая функция, как
function Trig_PoisonBomb_FILTER takes nothing returns boolean
        return (GetOwningPlayer(GetFilterUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endfunction
в нее лучше записать побольше условий. Сейчас урон наносится всем враждебным в области (даже мертвым и невидимым).
Поэтому лучше записать туда вот это: (я создал триггер и вписал нужные условия, а потом конвертировал в текст, часть которого можно забить в фильтр)
Можно все это записать в одну строчку, но тогда понижается читабельность
function Trig_PoisonBomb_FILTER takes nothing returns boolean
        if ( not ( GetOwningPlayer(GetFilterUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE) ) ) then
        return false
    endif
    if ( not ( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false ) ) then
        return false
    endif
    if ( not ( IsUnitVisible(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true ) ) then
        return false
    endif
    if ( not ( GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.00 ) ) then
        return false
    endif
    return true
endfunction
DaeDR добавил:
Вот как бы я записал:
function Trig_PoisonBomb_FILTER takes nothing returns boolean
return (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.00)and(IsUnitVisible(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())))and(IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false)and(GetOwningPlayer(GetFilterUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE))
endfunction
и еще ( зачем наносить урон только нейтральным? ). Вместо
GetOwningPlayer(GetFilterUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE)
можно поставить
IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit()))
тогда урон будет наноситься всем видимым, живым и не зданиям враждебным юнитам в области
Старый 30.03.2012, 06:07
Ответ

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

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

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

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



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