HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Bolt Radar

02-14-2007, 11:34 AM#1
NmdSnprEnigma
Spell - it works with seemingly random success in game. The idea is starting from 90 to the left of the facing angle of the casting unit, it damage all units in a 180 degree arc within a range of 1000 and damages each one for an clamped amount proportional to the number of degrees since the previous unit. The delay between units is unclamped and proportional to the degree separation also. AoE all benefit packed units. This was a shot at something that hits spread units better. Sometimes it stops halfway. Sometimes at the first one. Sometimes it hits most of the units. Rarely does hit the last unit or two. I've just been staring at it too long. Can anyone spot the problem(s)?

PS - Angles_IsAngleBetweenAnglesE is the same as the CS function except that it is exclusive (i.e. will not return true if the test angle equals one of the comparison angles). Also, I know it's not multi-instanceable but I was gonna work on that later.


Collapse JASS:
function IsUnitInFacing takes unit s, unit o, real allowance returns boolean
    local real a = GetUnitFacing(s)
    local real b = AngleBetweenPoints(GetUnitLoc(s), GetUnitLoc(o))

    if Angles_GetAngleDifference(a,b) < allowance then
        return true
    endif
    return false
endfunction

//===========================================================================
function InitTrig_IsUnitInFacing takes nothing returns nothing
endfunction
Collapse JASS:
function CenterAngle takes unit u returns real
    return AngleBetweenPoints(GetUnitLoc(GetTriggerUnit()),GetUnitLoc(u))
endfunction


function Trig_Bolt_Radar_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A00N' ) ) then
        return false
    endif
    return true
endfunction

function FacingFilter takes nothing returns boolean
    if not ( IsUnitInFacing(GetTriggerUnit(),GetFilterUnit(),90) ) then
        return false
    endif
    if not ( GetFilterUnit() != GetTriggerUnit() ) then
        return false
    endif
    if not ( GetWidgetLife(GetFilterUnit()) >.405 ) then
        return false
    endif
    if not ( udg_last == null ) then
        if Angles_IsAngleBetweenAnglesE(CenterAngle(GetFilterUnit()), CenterAngle(udg_last), GetUnitFacing(GetTriggerUnit()) + 89.9) then
            return false
        endif
    endif
    return true
endfunction



function LeftOfGroup takes nothing returns nothing
    local real compare = GetUnitFacing(GetTriggerUnit()) + 89.9
    if udg_lowest == null then
       set udg_lowest = GetEnumUnit()
       return
    endif
    if udg_last != null then
        set compare = CenterAngle(udg_last)
    endif
    if Angles_IsAngleBetweenAnglesE(CenterAngle(GetEnumUnit()), CenterAngle(udg_lowest), compare) then
        set udg_lowest = GetEnumUnit()
    endif
endfunction



function Trig_Bolt_Radar_Actions takes nothing returns nothing
    local location center = GetUnitLoc(GetTriggerUnit())
    local real leftbound = GetUnitFacing(GetTriggerUnit())+89.9
    local integer i = 1 // max number of targets
    local real time = 2
    local real ad
    local group g

    loop
        call DisplayTextToForce( GetPlayersAll(), "Bolt! " + I2S(i) + "!" )
        exitwhen GetWidgetLife(GetTriggerUnit()) <= .405 
        exitwhen i > 100
        set g = GetUnitsInRangeOfLocMatching(1000.00, GetUnitLoc(GetTriggerUnit()), Condition(function FacingFilter))
        call ForGroupBJ( g, function LeftOfGroup )

        if udg_last == null then
            set ad = Angles_GetAngleDifference(CenterAngle(udg_lowest), leftbound)
        else
            if Angles_IsAngleBetweenAngles(CenterAngle(udg_lowest), CenterAngle(udg_last), leftbound) then
                call DestroyLightning( bj_lastCreatedLightning )
                exitwhen 1==1
            endif
            set ad = Angles_GetAngleDifference(CenterAngle(udg_lowest),CenterAngle(udg_last))
        endif
        call TriggerSleepAction (time*ad/180)
        call DestroyLightning( bj_lastCreatedLightning )
        call AddLightningLoc("CLPB",center,GetUnitLoc(udg_lowest))
        call UnitDamageTargetBJ( GetTriggerUnit(), udg_lowest, RMaxBJ(5.00, RMinBJ(12*ad, 100.00)), ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL )
        set udg_last = udg_lowest
        set udg_lowest = null
        set i = i + 1
    endloop

    
    set udg_last = null
    set udg_lowest = null
    call RemoveLocation(center)
    call DestroyGroup(g)
    set g = null
    set center = null
endfunction
02-15-2007, 01:59 AM#2
Pyrogasm
I don't see anything jarringly, obviously wrong with it, aside from being extremely ineffecient. Instead of
Collapse JASS:
if not ( <condition ) then
    return false
endif
You can just do this if it's the only condition:
Collapse JASS:
return ( <condition> )
Or this, if you have multiple conditions:
Collapse JASS:
return ( <condition 1> ) and ( <condition 2> ) and ( <condition 3> ) //etc...
That, and you're leaking tons of locations. For example, when you do stuff like local real b = AngleBetweenPoints(GetUnitLoc(s), GetUnitLoc(o)). That leaks two locations.

I would suggest you clean up your code and then take another look at it to see if there's something you've missed.
02-16-2007, 04:55 PM#3
NmdSnprEnigma
yeah, the over complicated conditions were just so I could see it all with out it stretching all the way across the screen 'cuz it's on one line. And yes, I realize it's leakier than... well than whatever it is that leaks a lot, but that doesn't prevent it from operating right. It's easier to clean something up once it works, cuz if I have to rework it, I either need to get it right the first time, or just clean it up all over again. So, yeah, I'll go back and look at it again, but I was hoping to get someone else's critical view of the operation of it, not the efficiency of it.