Yet another angle problem.

Kazuga

Let the game begin...
Reaction score
110
I was testing out all of my spells in the map I'm working on at the moment and noticed that custom projectile spells didn't always shoot so precise. I looked through the codes and noticed that it was because I moved the dummy projectile towards he's facing angle instead of the angle between the points even though I set the dummy units facing to that angle. (The point of the caster and target point of ability being cast.)

Trying to fix this I used the angle between the points instead, but no matter what I did it turned out to be something complete else. The projectiles moved in all sorts of strange directions... I tried using what I usually do, taking the angle*bj_DEGTORAD/bj_RADTODEG. But none of them worked... Here is the code for one of the projectile spells:
JASS:
scope ArcaneBolt initializer Lightning
//! runtextmacro HAIL_CreateProperty ("Data", "integer", "private")
globals
private constant integer dummyID = 'e002'        
private constant integer raw     = 'A001'                    
private constant integer damage  = 25    
private constant integer aoe  = 50   
private constant real speed = 0.05


group Az
unit ArcaneBoltCaster  = null
endglobals
private struct TestStruct
real angle
unit dummy
integer delay
integer FirstTime
real tx
real ty
timer Timer
unit caster
endstruct

private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == raw
endfunction
function Trig_ArcaneBolt_FilterCondition takes nothing returns boolean
    return GetWidgetLife( GetFilterUnit() ) > 0.405 and IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO) and IsUnitEnemy( GetFilterUnit(), GetOwningPlayer( ArcaneBoltCaster ) ) == true and IsUnitInGroup(GetFilterUnit(),udg_Invulnerable) == false
    
endfunction




private function ASlide takes nothing returns nothing
    local TestStruct data = GetData (GetExpiredTimer ())
    local real x = GetUnitX(data.dummy)
    local real y = GetUnitY(data.dummy)
    local real x2 = x + 30 * Cos(data.angle)//*bj_RADTODEG) //This controls where the projectile is heading.
    local real y2 = y + 30 * Sin(data.angle)//*bj_RADTODEG)//Same goes for this line.
    local unit affected = null
    if RectContainsUnit(gg_rct_Arena,data.dummy) == false and RectContainsUnit(gg_rct_Shops_only,data.dummy) == false then
        call RemoveUnit(data.dummy)
        call PauseTimer (data.Timer)
        call ResetData (data.Timer)
        call DestroyTimer (data.Timer)
        call data.destroy ()
    endif
    set ArcaneBoltCaster = data.caster
    set Az = CreateGroup()
    call GroupEnumUnitsInRange(Az,x,y,aoe,Condition(function Trig_ArcaneBolt_FilterCondition))
    set affected = GroupPickRandomUnit(Az)
        if UnitHasItemOfTypeBJ(affected, 'I00E') == true then
            if GetRandomInt(1,100) <= 100 then
                set data.angle = data.angle + 180
                call AddSpecialEffect("Abilities\\Spells\\Items\\SpellShieldAmulet\\SpellShieldCaster.mdl",GetUnitX(affected),GetUnitY(affected))
            endif
        else
    call SetUnitX(data.dummy,x2)
    call SetUnitY(data.dummy,y2)
    if CountUnitsInGroup(Az) > 0 then
        call UnitDamageTarget(ArcaneBoltCaster,affected,(50+damage*I2R(GetUnitAbilityLevel(ArcaneBoltCaster,raw))),true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_UNIVERSAL,WEAPON_TYPE_WHOKNOWS)   
        set udg_KnockbackTarget = affected
        set udg_KnockbackR = ( ( R2I(GetUnitStateSwap(UNIT_STATE_MAX_LIFE, udg_KnockbackTarget)) - ( R2I(GetUnitStateSwap(UNIT_STATE_LIFE, udg_KnockbackTarget)) * 1 ) ) - udg_GameKBR[GetConvertedPlayerId(GetOwningPlayer(udg_KnockbackTarget))] )
        set udg_KnockbackR = ( udg_KnockbackR * 2 )
        if udg_KnockbackR < 0 then
            set udg_KnockbackR = 0
        endif
        call UnitKnockTargetEx(data.caster,udg_KnockbackTarget , GetUnitFacing(data.dummy), udg_KnockbackR, 0.00, 1.00, "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageDeathCaster.mdl", "origin")
        call RemoveUnit(data.dummy)
        call PauseTimer (data.Timer)
        call ResetData (data.Timer)
        call DestroyTimer (data.Timer)
        call data.destroy () 
    endif
    endif
    call DestroyGroup(Az)     
    set affected = null
    

endfunction


private function Actions takes nothing returns nothing
local TestStruct data = TestStruct.create ()
    local real x        =     GetUnitX(GetTriggerUnit())
    local real y        =     GetUnitY(GetTriggerUnit())
    local real angle    =     0
    local location loc = GetOrderPointLoc()
    local location loc2 = GetUnitLoc(GetTriggerUnit())

    set data.tx = GetLocationX(loc)
    set data.ty = GetLocationY(loc)
    set angle = AngleBetweenPoints(loc2,loc) 
    set data.angle = angle
    call RemoveLocation(loc)
    call RemoveLocation(loc2)
    set data.dummy = CreateUnit(GetOwningPlayer(GetTriggerUnit()),dummyID,x,y,GetUnitFacing(GetTriggerUnit()))
    call SetUnitX(data.dummy,x)
    call SetUnitY(data.dummy,y)
    set data.Timer = CreateTimer()
    call TimerStart (data.Timer,speed,true, function ASlide)
    call SetData (data.Timer, data)
    set data.caster = GetTriggerUnit()
endfunction


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

private function SafeFilt takes nothing returns boolean
return true
endfunction
private function Lightning takes nothing returns nothing
 local trigger trig = CreateTrigger()
local integer i = 0
loop
    exitwhen i > 15
    call TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Condition(function SafeFilt))
    set i = i + 1
endloop
 call TriggerAddCondition (trig, Condition (function Conditions ) )
 call TriggerAddAction (trig, function Actions )
 set trig = null
 endfunction

endscope


Any help is appreciated.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top