28

» WarCraft 3 / Утечки в коде

ArhiMEN, ну так и правильно показывает, ерунду делаешь. Сделай глобалку и ей перебирай
28

» WarCraft 3 / Утечки в коде

там нет утечек, действия происходят в основном с реальными, единственное что обнулять в конце юнита не нужно, если цикл уже заканчивается юнит == null, но это явно не причина твоих бед

а стоп, нашел утечку, ты создал группу в начале но не удалил в конце, лол)

короче будь внимательнее
28

» WarCraft 3 / Триггер пополняющий группу юнитов в Word Editor WarCraft 3

Условие - целочисленная - колво юнитов в группе меньше 4 - добавить юнита
Загруженные файлы
28

» WarCraft 3 / Способности и алгоритмы на заказ

Заказ принят

Заказчик: mistwood
Способность: Аванпост
Спелл будет завершен к: сегодня ближе к вечеру
28

» WarCraft 3 / Чем полезен и полезен ли вообще этот чудо тригер?))))

это бред полный, уже миллион раз форсили эту тему

если ты выставляешь дамми не разлагается и не оживляется всё - после смерти он сразу же удаляется из игры, а этот триггер юзлесс и лишь портит качество способностей, потому что когда юнит умирает он хотя бы анимацию ещё проигрывает, частицы ещё разлетаются, а при мгновенном удалении юнита это выглядит отвратительно

сорян конечно если чью-то религию подпортил, но меня раздражает когда вижу подобную фигню

сам же триггер по факту лишняя нагрузка, если бы тут была подчистка хэша под родительским ключом юнита или что-то в этом духе - я бы ещё понял, но обычное удаление когда можно выставить время смерти на 0.00...
28

» WarCraft 3 / Обучение jass

Гуванч, ты мне говорил, что по джассу нет нормальных видео и предлагал даже мне начать записывать ролики, втф?
28

» WarCraft 3 / Есть ли модели дота в открытом доступе?

Nikolay36, программист высшего уровня это если бы всё самостоятельно было написано, а просто подкрутить и что-то переделать это даже гуишник может, да и вообще это прозвучало от тебя как боготворение фрога
28

» WarCraft 3 / Полёт клинка

ArhiMEN, и в локальной не запустилась?

проверь эту карту тогда

если она запустится, то попробуй постепенно восстанавливать код, когда перестанет запускаться скажи на каком месте оно перестало работать
Загруженные файлы
28

» WarCraft 3 / Полёт клинка

ArhiMEN, включи вджасс и сохрани карту

либо запусти через локальную сеть

если вообще не запускается то похоже ты сидишь на другой версии вара

хотя я не понимаю каким боком, ведь я смотрел твой спеллпак и ты даже мемхак юзаешь
28

» WarCraft 3 / Триггер при взятии предмета в WorldEditor

Extremator, вроде как нельзя отловить с какой области подобрали предмет, разве что если приказ+периодический таймер с проверкой дистанции

но я бы наверное в сам предмет сохранил индекс области для проверки
28

» WarCraft 3 / Warcraft 3 Reforged Взломан!

Жаль, что из 40 комментариев, нет ни одного толкового
да я бы попробовал, но если чё-то пойдёт не так и комп взорвётся то хз, не хочу рисковать, хы)
28

» WarCraft 3 / Вопрос по снаряду

Я уже делал подобное, только без возвращения, юзаешь функции параболы и всё

Загруженные файлы
28

» WarCraft 3 / Неуязвимое здание с отображением хп

вроде как нужно зданию убрать галочку в типах цели "механические" (не уверен)

проверил, ошибся, похоже нельзя отобразить стандартными средствами
28

» WarCraft 3 / Полёт клинка

ArhiMEN, работаю над этим, немного осталось

в общем я поленился и не добавил все настройки, но оставил комменты по которым ты быстро сориентируешься что к чему и сам доделаешь как надо
то что я бы посоветовал переделать, это выбирать юнитов вокруг точки падения, которая регистрируется после первого пораженного юнита, а не вокруг последней пораженной цели, в видео ты можешь посмотреть пример как глупо полёт смотрелся (0:24)
раскрыть
library mylib
globals
    constant hashtable H = InitHashtable()
    private group TempG = CreateGroup()
    private group TempG1
    private unit bj_lastFilterUnit
    private unit TempUnit
    private unit CUEX
    private real TempReal
    private real MaxX
    private real MinX
    private real MaxY
    private real MinY
endglobals

// воспомогательные фукнции
native UnitAlive takes unit id returns boolean

private function SetUnitPositionEx takes unit u, real x, real y returns nothing
    if x > MaxX then
        set x = MaxX
    elseif x < MinX then
        set x = MinX
    endif
    if y > MaxY then
        set y = MaxY
    elseif y < MinY then
        set y = MinY
    endif
    call SetUnitX(u,x)
    call SetUnitY(u,y)
endfunction

private function CreateUnitEx takes player id, integer unitid, real x, real y, real face returns unit
    set CUEX = CreateUnit(id,unitid,x,y,face)
    call UnitAddAbility(CUEX,'Arav')
    call SetUnitPathing(CUEX,false)
    call SetUnitPositionEx(CUEX,x,y)
    return CUEX
endfunction

private function ParabolaZ takes real h, real d, real x returns real
    return (4 * h / d) * (d - x) * (x / d)
endfunction

private struct Spell
    unit caster
    unit target
    unit dummy
    unit dummy1
    real speed
    real angle
    real dmg
    real fly
    real fly1
    real time
    real dist
    real dist1
    real radius
    real x
    real y
    integer dummyid
    boolean b = true
    integer count
    group g
endstruct

private function cond takes nothing returns boolean // выбор ближайших целей для кинжала
    set bj_lastFilterUnit = GetFilterUnit()
    return UnitAlive(bj_lastFilterUnit) and IsUnitEnemy(bj_lastFilterUnit,GetOwningPlayer(TempUnit)) and not IsUnitInGroup(bj_lastFilterUnit,TempG1)
endfunction

private function DamageCond takes nothing returns boolean // кому наносить урон
    set bj_lastFilterUnit = GetFilterUnit()
    if UnitAlive(bj_lastFilterUnit) and IsUnitEnemy(bj_lastFilterUnit,GetOwningPlayer(TempUnit)) then
        call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Critters\\Albatross\\CritterBloodAlbatross.mdl",bj_lastFilterUnit,"chest"))
        call UnitDamageTarget(TempUnit,bj_lastFilterUnit,TempReal,false,false,null,null,null)
    endif
    return false
endfunction

private function casterr takes nothing returns boolean // это для кинжала, выбор кастера когда кинжал упал
    return GetFilterUnit() == TempUnit
endfunction

private function move1 takes nothing returns nothing //это для эффекта кругового удара
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local unit u = LoadUnitHandle(H,i,0)
    local unit u1 = LoadUnitHandle(H,i,1)
    local real tm = LoadReal(H,i,2)-.01
    
    call SetUnitPositionEx(u1,GetUnitX(u),GetUnitY(u))
    
    if tm <= 0. then
        call KillUnit(u1)
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(H,i)
    else
        call SaveReal(H,i,2,tm)
    endif
    
    set t = null
    set u = null
    set u1 = null
endfunction

// периодическая проверка кастера у кинжала
private function checkcaster takes nothing returns nothing
    local Spell A = LoadInteger(H,GetHandleId(GetExpiredTimer()),0)
    local timer t
    set A.time = A.time-.01
    set TempUnit = A.caster
    call GroupEnumUnitsInRange(TempG,A.x,A.y,100,Condition(function casterr))
    if A.time <= 0. or FirstOfGroup(TempG) != null then
        if FirstOfGroup(TempG) != null then
            set t = CreateTimer()
            call SaveUnitHandle(H,GetHandleId(t),0,A.caster)
            call SaveUnitHandle(H,GetHandleId(t),1,CreateUnitEx(Player(0x0F),'u002',GetUnitX(A.caster),GetUnitY(A.caster),GetRandomReal(0,360)))
            call SaveReal(H,GetHandleId(t),2,.10)
            call SetUnitFlyHeight(CUEX,50,0)
            call SetUnitScale(CUEX,2,2,2)
            call TimerStart(t,.01,true,function move1)
            set t = null
            
            call GroupClear(TempG)
            set TempReal = A.dmg
            call GroupEnumUnitsInRange(TempG,GetUnitX(A.caster),GetUnitY(A.caster),A.radius*0.8,Condition(function DamageCond))
        endif
        
        call KillUnit(A.dummy)
        call KillUnit(A.dummy1)
        call RemoveUnit(A.dummy1)
        call DestroyGroup(A.g)
        set A.g = null
        set A.caster = null
        set A.dummy = null
        call A.destroy()
        call FlushChildHashtable(H,GetHandleId(GetExpiredTimer()))
        call PauseTimer(GetExpiredTimer())
        call DestroyTimer(GetExpiredTimer())
    endif
endfunction

// перемещение кинжала когда он падает
private function setpos takes nothing returns nothing
    local Spell A = LoadInteger(H,GetHandleId(GetExpiredTimer()),0)
    local real x = GetUnitX(A.dummy)+A.speed*Cos(A.angle)
    local real y = GetUnitY(A.dummy)+A.speed*Sin(A.angle)
    
    set A.dist = A.dist-A.speed
    call SetUnitPositionEx(A.dummy,x,y)
    call SetUnitFlyHeight(A.dummy,ParabolaZ(A.fly,A.dist1,A.dist)+A.fly1,0)
    
    if A.dist <= 0. then
        set A.x = x
        set A.y = y
        set A.dummy1 = CreateUnitEx(GetOwningPlayer(A.caster),A.dummyid,x,y,GetRandomReal(0,360))
        call SetUnitScale(A.dummy1,.5,.5,.5)
        call TimerStart(GetExpiredTimer(),.01,true,function checkcaster)
    endif
endfunction

private function move takes nothing returns nothing
    local Spell A = LoadInteger(H,GetHandleId(GetExpiredTimer()),0)
    local real x = GetUnitX(A.dummy)+A.speed*Cos(A.angle)
    local real y = GetUnitY(A.dummy)+A.speed*Sin(A.angle)
    local real x1 = GetUnitX(A.target)
    local real y1 = GetUnitY(A.target)
    local unit u
    local real r
    local real r1
    
    set A.angle = Atan2(y1-y,x1-x)
    call SetUnitPositionEx(A.dummy,x,y)
    
    if SquareRoot((x-x1)*(x-x1)+(y-y1)*(y-y1)) <= 50. then
        call SetUnitX(A.dummy,x1)
        call SetUnitY(A.dummy,y1)
        call UnitDamageTarget(A.caster,A.target,A.dmg,false,false,null,null,null)
        if A.b then // установление дистанции падения кинжала после первой цели
            set A.x = x1+A.radius*Cos(A.angle)
            set A.y = y1+A.radius*Sin(A.angle)
            set A.b = false
        endif
        set A.count = A.count-1
        set TempUnit = A.dummy
        set TempG1 = A.g
        call GroupEnumUnitsInRange(TempG,x1,y1,A.radius,Condition(function cond))
        if A.count <= 0 or FirstOfGroup(TempG) == null then
            // настройки для падения кинжала
            set A.dist = SquareRoot((x-A.x)*(x-A.x)+(y-A.y)*(y-A.y))
            set A.dist1 = A.dist // (для параболы)
            set A.angle = Atan2(A.y-y1,A.x-x1)
            set A.speed = SquareRoot((x-x1)*(x-x1)+(y-y1)*(y-y1))*.1
            call TimerStart(GetExpiredTimer(),.01,true,function setpos)
        else
            // выбор ближней цели
            set r = A.radius*2
            loop
                set u = FirstOfGroup(TempG)
                exitwhen u == null
                set r1 = SquareRoot((GetUnitX(u)-x1)*(GetUnitX(u)-x1)+(GetUnitY(u)-y1)*(GetUnitY(u)-y1))
                if r1 < r then
                    set r = r1
                    set A.target = u
                endif
                call GroupRemoveUnit(TempG,u)
            endloop
            call GroupAddUnit(A.g,A.target)
        endif
    endif
    
endfunction

private function Trig_Spell_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local Spell A = Spell.create()
    local integer lvl
    set A.caster = GetTriggerUnit()
    set A.target = GetSpellTargetUnit()
    set A.angle = Atan2(GetUnitY(A.target)-GetUnitY(A.caster),GetUnitX(A.target)-GetUnitX(A.caster))
    set A.dummy = CreateUnitEx(GetOwningPlayer(A.caster),'u000',GetUnitX(A.caster)+50*Cos(A.angle),GetUnitY(A.caster)+50*Sin(A.angle),A.angle*bj_RADTODEG)
    set A.g = CreateGroup()
    set lvl = GetUnitAbilityLevel(A.caster,'A000')
    
    if lvl == 1 then
        set A.dmg = 100.00
        set A.count = 3
        set A.speed = 25.00
        set A.radius = 300.00 // радиус поиска целей а так же дистанция падения кинжала от первой пораженной цели
        set A.fly = 300.00 // максимальная высота кинжала
        set A.fly1 = 50.00 // постоянная высота кинжала
        set A.time = 5.00 // время существования кинжала
        set A.dummyid = 'u001' // какого юнита спавнить для отображения радиуса подбора кинжала
    //elseif lvl == 2 then
    endif
    call GroupAddUnit(A.g,A.target)
    call SetUnitFlyHeight(A.dummy,A.fly1,0)
    call SaveInteger(H,GetHandleId(t),0,A)
    call TimerStart(t,.03125,true,function move)
    set t = null
endfunction

//===========================================================================
private function mycond takes nothing returns boolean
    if GetSpellAbilityId() == 'A000' then
        call Trig_Spell_Actions()
    endif
    return false
endfunction
function InitTrig_Spell takes nothing returns nothing
    set gg_trg_Spell = CreateTrigger(  )
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x00), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x01), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x02), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x03), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x04), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x05), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x06), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x07), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x08), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x09), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x0A), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x0B), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x0C), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x0D), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x0E), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerRegisterPlayerUnitEvent(gg_trg_Spell, Player(0x0F), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerAddCondition( gg_trg_Spell, Condition(function Trig_Spell_Actions) )
    
    set MaxX = GetRectMaxX(GetWorldBounds())
    set MinX = GetRectMinX(GetWorldBounds())
    set MaxY = GetRectMaxY(GetWorldBounds())
    set MinY = GetRectMinY(GetWorldBounds())
endfunction
endlibrary





а насчёт вращения юнита, если мемхак не помогает, можешь найти дамми модель 360 градусов и прикрепить к ней кинжал как эффект, устанавливая нужную анимацию модели в соответствии с таким-то градусом, костыльно, но работает без проблем
Загруженные файлы
28

» WarCraft 3 / Полёт клинка

господа, он не за вращение спрашивает, а за приземление кинжала там где не задумано)
28

» WarCraft 3 / Полёт клинка

Гуванч, нафига ему иконки?)
он спрашивает почему кинжал себя так странно ведёт)

через час примерно скину спелл
28

» WarCraft 3 / Полёт клинка

но столкнулся с рядом проблем в анимации: то, одно клинок улетает в неизвестность, невзирая на условия, то летит нормально; то клинок приземляется куда нужно, но оказывается, что только под определённым углом, то сильно мимо, можете помочь с тем, как правильно сделать анимацию?
у тебя проблемы с анимацией или с движением кинжала? не понятно что ты хочешь

если именно технические проблемы, а не визуальные (по которым ты мемхак юзаешь для вращения по yaw/pitch/roll), то я могу сделать эту абилку и скинуть тебе