Добавлен
Вопрос на скрине

Принятый ответ

Steal nerves:
SquareRoot это математический корень
О чем это мне говорит? Он должен высчитать расстояние между коордами. Я переписал в одну строку все из функции DistanceBP, но выдает всегда 0
Лол, нужно минусы в скобки просто. Мда
0
19
7 лет назад
0
Похожие вопросы:

ответ
GF RaiseD:
Нашёл систему, где звук передаётся в таймер, который истекает через 0 секунд. В результате один и тот же звук может проигрываться несколько раз без всяких проблем. В инетике пишут мол это такой баг движка.
ответ
BaHeK:
Darknessay, я имел ввиду изначальное расстояние между объектами.
Вот нарисовал схематично.
Обозначим расстояние которое прошёл 1 юнит за х. Красная линия это путь который прошел юнит 2 до встречи. Двигались они одинаковое время, значит составим равенство(s1 и s2 это скорости) и немного преобразуем.
sqrt(a^2 + (b-x)^2)/s1 = x/s2
s1^2(a^2 + b^2)x^2 + 2*s1^2*b*x - s1^2(a^2 + b^2) = 0
Решаем полученное уравнение и получаем
x1 = (-2*s1^2*b + sqrt((2*s1^2*b)^2 + 4*(s2^2 - s1^2)*s1^2(a^2 + b^2))) / (2*s1^2(a^2 + b^2))
x2 = (-2*s1^2*b - sqrt((2*s1^2*b)^2 + 4*(s2^2 - s1^2)*s1^2(a^2 + b^2))) / (2*s1^2(a^2 + b^2))
Искомый угол равен arctg((b-x)/a).
Вод мою систему такой расчет не подойдет.
GF RaiseD:
Это не в одну строку посчитать
function getTargetOffset takes unit Caster, unit Target, real targetSpeed, real missileSpeed returns real

local real x1 = GetUnitX(Caster)
local real x2 = GetUnitX(Target)
local real x3

local real X4 //Координата X точки пересечения

local real y1 = GetUnitY(Caster)
local real y2 = GetUnitY(Target)
local real y3

local realY4 //Координата Y точки пересечения

local real targetSpeed
local real missileSpeed

local real distancex1x2 = Sqrt(Pow(x2-x1,2)+Pow(y2-y1,2))
local real distancex1x3
local real distanceX4Y4

set x3 = GetUnitX(Target)+targetSpeed*distaancex1x2/missileSpeed*Cos(GetUnitFacing(Target))*bj_DEGSTORAD
set y3 = GetUnitY(Target)+targetSpeed*distaancex1x2/missileSpeed*Sin(GetUnitFacing(Target))*bj_DEGSTORAD

set distaancex1x3 = Sqrt(Pow(x3-x1,2)+Pow(y3-y1,2))

set X4 = GetUnitX(Target)+targetSpeed*distancex1x2/missileSpeed*distancex1x3/distancex1x2*Cos(GetUnitFacing(Target))*bj_DEGSTORAD

set Y4 = GetUnitY(Target)+targetSpeed*distancex1x2/missileSpeed*distancex1x3/distancex1x2*Sin(GetUnitFacing(Target))*bj_DEGSTORAD

set Caster = null
set Target = null

set distanceX4Y4 = Sqrt(Pow(X4-x2,2)+PowY4-y2,2)) // Опережение (по отношению к повороту юнита-цели)

return distanceX4Y4

endfunction

Если что - я не проверял. Но должно бы работать.
Если тебе нужен угол с точки x2 на точку x3, определяется он так:
Atan2(y3-y2,x3-x2)*bj_RADTODEG
Убрал синтаксические ошибки, немного "допилил" - не хочет работать.
Всем привет работяги, я сам справился. Проверил: всё работает.
//===============Вспомогательные_функции================
function GetAngleXY takes real x, real y, real xx, real yy returns real
    return bj_RADTODEG * Atan2(yy - y, xx - x)
endfunction

function GetDisXY takes real x, real y, real xx, real yy returns real
    return SquareRoot((xx-x) * (xx-x) + (yy-y) * (yy-y))
endfunction

function GetPolarX takes real x, real f, real d returns real
return x + Cos(f*0.0174)*d
endfunction

function GetPolarY takes real y, real f, real d returns real
return y + Sin(f*0.0174)*d
endfunction

//=======================Основная часть=======================
function GetTargetOffset takes unit host, unit target, real speedm returns real
local real speedt = GetUnitMoveSpeed(target)
local real x = GetUnitX(host)
local real y = GetUnitY(host)
local real xx = GetUnitX(target)
local real yy = GetUnitY(target)
local real fac = GetUnitFacing(target)
local real dis = GetDisXY(x,y,xx,yy)
local real time = dis/speedm
local real dispost = GetDisXY(xx,yy,GetPolarX(xx,fac,time*speedt),GetPolarY(yy,fac,time*speedt))
local real X = GetPolarX(xx,fac,dispost) //нужные координаты цели
local real Y = GetPolarY(yy,fac,dispost)
    return GetAngleXY(x,y,X,Y)//возвращает угол который нужен для корректировки стрельбы
endfunction
ответ
nvc123:
Bornikkeny, сделал специально чтобы доказать тебе что ты несёшь бред
даже 2 скрина приложил
думаю закинуть библиотеки сможешь сам (в папку *твой jngp*\AdicHelper\lib)
Хорошо группы реализуешь как альтернативу unit[array]. Я тоже самое получил.
nvc123, и всё же твой хук не тот что мне нужен.
Я решил проблему, спасибо что дал идею обрабатывать движение внутри структуры, а не в стеке.
кот
library Hook initializer Init_Hook uses LibMath

globals
    mhook   ahook[100]
    integer ihook = -1
endglobals
    
struct mhook
        unit       host = null
        unit       target = null
        real       face = 0
        real       speed = 0
        real       dis = 0
        real       dismax = 0
        integer    chaini = 0
        unit       chain[50]
        real       scale = 0
        integer    move = 1
        integer    i = 0
		
		
        static method Create takes unit host, real tx, real ty, real scale returns mhook
        local mhook h = mhook.create()
        local integer i = GetPlayerId(GetOwningPlayer(host))
        local real x = GetUnitX(host)
        local real y = GetUnitY(host)
        local real f = GetAngleXY(x,y,tx,ty)
            set h.host = host
            set h.face = f
            set h.speed = 600
            set h.dismax = 1400
            set h.scale = scale
            set h.chain[0] = CreateUnit(Player(i),'h007',GetPolarX(GetUnitX(host),f,h.scale/2),GetPolarY(GetUnitY(host),f,h.scale/2),f)
            set h.i = i
            call UnitAddAbility(h.chain[0],'Amrf')
            call UnitAddAbility(h.chain[0],'Amrf')
            call SetUnitFlyHeight(h.chain[0],50,0)
            call SetUnitPathing(h.chain[0],false)
            return h
        endmethod
        
        method Start takes nothing returns boolean
            if ihook < 1000 then  
                set ihook = ihook + 1
                set ahook[ihook] = this
                return true
            else
                return false
            endif
        endmethod
        
        method Destroy takes nothing returns nothing
        local integer i = 0
            loop
            exitwhen i > ihook
                if ahook[i] == this then
                    set ahook[i] = ahook[ihook]
                    set ahook[ihook] = 0
                    set ihook = ihook - 1
                    set i = ihook // выход из цикла
                endif
            set i = i + 1
            endloop
            set this.target = null
            set this.host = null
            call this.destroy()
        endmethod
        
        method Move takes nothing returns nothing
        local integer i1 = 0
        local integer l = 0
        local real x
        local real y
        local real xh
        local real yh
        local real f
            if move == 1
                set dis = dis + speed*0.025
                loop
                 exitwhen i1 > .chaini
                    set x = GetUnitX(.chain[i1])
                    set y = GetUnitY(.chain[i1])
                    if i1 > 0 then
                        set f = GetAngleXY(x,y,GetUnitX(.chain[i1-1]),GetUnitY(.chain[i1-1]))
                        call SetUnitX(.chain[i1],GetPolarX(x,f,.speed*0.025))
                        call SetUnitY(.chain[i1],GetPolarY(y,f,.speed*0.025))
                    else    
                        set f = face
                        call SetUnitX(chain[i1],GetPolarX(x,f,.speed*0.025))
                        call SetUnitY(chain[i1],GetPolarY(y,f,.speed*0.025))
                    endif
                    call SetUnitFacing(chain[i1],f)
                 set i1 = i1 + 1
                endloop
                set x = GetUnitX(chain[chaini])
                set y = GetUnitY(chain[chaini])
                set f = GetAngleXY(GetUnitX(.host),GetUnitY(.host),x,y)
                set xh = GetPolarX(GetUnitX(.host),f,.scale/2)
                set yh = GetPolarY(GetUnitY(.host),f,.scale/2)
                //Create==================
                
                if GetDisXY(xh,yh,x,y) >= .scale/2 then
                    set chaini = chaini + 1
                    set chain[chaini] = CreateUnit(Player(.i),'h007',xh,yh,f)
                    call UnitAddAbility(.chain[.chaini],'Amrf')
                    call UnitAddAbility(.chain[.chaini],'Amrf')
                    call SetUnitFlyHeight(.chain[.chaini],50,0)
                endif
                if dis > dismax then
                    set move = 0
                endif
            else
                //REVERSE=============
                set xh = GetUnitX(host)
                set yh = GetUnitY(host)
                set chain[chaini+1] = host
                loop
                exitwhen l > chaini
                        set x = GetUnitX(chain[l])
                        set y = GetUnitY(chain[l])
                        //if chain[chaini] == null then
                        //    set f = GetAngleXY()
                        //endif
                        set f = GetAngleXY(x,y,GetUnitX(chain[l+1]),GetUnitY(chain[l+1]))
                        call SetUnitX(chain[l],GetPolarX(x,f,speed*0.025))
                        call SetUnitY(chain[l],GetPolarY(y,f,speed*0.025))
                        call SetUnitFacing(chain[l],f-180)
                set l = l + 1
                endloop
                //Destroy==================
                set x = GetUnitX(chain[chaini])
                set y = GetUnitY(chain[chaini])
                set xh = GetUnitX(host)
                set yh = GetUnitY(host)
                if GetDisXY(GetUnitX(chain[chaini]),GetUnitY(chain[chaini]),GetUnitX(host),GetUnitY(host)) < 100 then
                    call RemoveUnit(chain[chaini])
                    set chain[chaini] = null
                    set chaini = chaini - 1
                    if chaini == -1 then
                        call .Destroy()
                    endif
                endif
            endif
        endmethod
        
endstruct

private function Engine takes nothing returns nothing
local integer i = 0
local mhook h
local group g
local unit t 
    loop
    exitwhen i > ihook
        if ahook[i] != 0 then
            set h = ahook[i]
            //--run--//
            call h.Move()
        else
            set ahook[i] = ahook[ihook]
            set ahook[ihook] = 0
            set ihook = ihook - 1
            set i = i - 1 
        endif
    set i = i + 1
    endloop
    //call DestroyGroup(g)
    set g = null
    set t = null
endfunction

function Trig_HookC_Bool takes nothing returns boolean
    if GetSpellAbilityId() == 'A01D' then //Способность Мясной хук
        return true
    else
        return false
    endif
endfunction

function Trig_HookC_Actions takes nothing returns nothing
local mhook h
    set h = mhook.Create(GetSpellAbilityUnit(),GetSpellTargetX(),GetSpellTargetY(),110)
    call h.Start()
endfunction

function Init_Hook takes nothing returns nothing
local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( t, function Trig_HookC_Actions )
    call TriggerAddCondition(t,function Trig_HookC_Bool)
    call TimerStart(CreateTimer(),0.025,true,function Engine)
endfunction

endlibrary
ответ
да юнит должен быть летающим,либо добавь и сразу удали способность привратиться в ворона затем меняй высоту
ответ
Всё, разобрался, вопрос снимаю)

0
27
7 лет назад
Отредактирован MpW
0
SquareRoot - это математический корень
dx * dx - можно возвести в степень два, но в варкрафте такого нет, да и не нужно
dx - вектор, точнее его проекция на оси x (из конца вычитаем начало, этим мы можем узнать направление)
0
19
7 лет назад
0
Steal nerves:
SquareRoot это математический корень
О чем это мне говорит? Он должен высчитать расстояние между коордами. Я переписал в одну строку все из функции DistanceBP, но выдает всегда 0
Лол, нужно минусы в скобки просто. Мда
Принятый ответ
3
30
7 лет назад
Отредактирован Clamp
3
но в варкрафте такого нет, да и не нужно
    Pow(dx, 2.0)
этим мы можем узнать направление
Пример кода можно попросить?

Самый оптимальный вариант реализации функции поиска расстояния между двумя точками:
    float M_Distance(float x1, float y1, float z1, float x2, float y2, float z2) {
        float deltaX = x1 - x2
        float deltaY = y1 - y2
        float deltaZ = z1 - z2
        return SquareRoot(deltaX*deltaX + deltaY*deltaY + deltaZ*deltaZ)
    }
Автор, не пользуйся location, работай с координатами!
0
19
7 лет назад
0
Clamp:
но в варкрафте такого нет, да и не нужно
Pow(dx, 2.0)

Самый оптимальный вариант реализации функции поиска расстояния между двумя точками:
    float M_Distance(float x1, float y1, float z1, float x2, float y2, float z2) {
        float deltaX = x1 - x2
        float deltaY = y1 - y2
        float deltaZ = z1 - z2
        return SquareRoot(Pow(deltaX, 2) + Pow(deltaY, 2) + Pow(deltaZ, 2))
    }
Автор, не пользуйся location, работай с координатами!
Это была стандартная функция DistanceBP, я ее для сравнения взял просто
Спасибо
1
16
7 лет назад
1
напоминаю о существовании IsUnitInRange(u1,u2,rng) и IsUnitInRangeXY(u,x,y,rng) для проверки расстояний между юнитом и точкой/юнитом. В большинстве случаев проверяют, входит ли юнит в аое, и эта нативка будет в разы быстрее, чем самописцы
2
19
7 лет назад
2
DracoL1ch:
напоминаю о существовании IsUnitInRange(u1,u2,rng) и IsUnitInRangeXY(u,x,y,rng) для проверки расстояний между юнитом и точкой/юнитом. В большинстве случаев проверяют, входит ли юнит в аое, и эта нативка будет в разы быстрее, чем самописцы
Мне нужен реал расстояния, а не тру/фалс
Чтобы оставить комментарий, пожалуйста, войдите на сайт.