• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] Using (Atan2?) to properly bounce objects during KB

Status
Not open for further replies.

Cokemonkey11

Code Reviewer
Level 29
Joined
May 9, 2006
Messages
3,522
Hi there, I'm making a knockback/damage detection system for a map and I need to know what math functions to use to make units properly knock back. I'm using angle/power for my vector system (as oppososed to x/y) so I believe I need to use Atan2.

Here's the important part of the system:

JASS:
globals
    trigger tDDKB
endglobals

scope damageDetectedKnockback initializer i
    private struct kData
        unit u
        real direction
        integer power
    endstruct
    
    globals
        private timer time=CreateTimer()
        private kData array kDB
        private integer dbIndex=-1
    endglobals

    private function p takes nothing returns nothing
        local integer index=0
        local kData tempDat
        local real x
        local real y
        loop
            exitwhen index>dbIndex
            set tempDat=kDB[index]
            set x=GetUnitX(tempDat.u)+tempDat.power*Cos(tempDat.direction*bj_DEGTORAD)
            set y=GetUnitY(tempDat.u)+tempDat.power*Sin(tempDat.direction*bj_DEGTORAD)
            if IsTerrainWalkable(x,y) then
                call SetUnitX(tempDat.u,x)
                call SetUnitY(tempDat.u,y)
            else
                set tempDat.direction=tempDat.direction+180
                set tempDat.power=tempDat.power*3/4
            endif
            set tempDat.power=tempDat.power-1
            if GetUnitState(tempDat.u,UNIT_STATE_LIFE)<1 then
                set tempDat.power=tempDat.power-1
            endif
            if GetUnitMoveSpeed(tempDat.u)<270 then
                set tempDat.power=tempDat.power-1
            endif
            if tempDat.power<0 then
                call tempDat.destroy()
                set kDB[index]=kDB[dbIndex]
                set dbIndex=dbIndex-1
                if dbIndex==-1 then
                    call PauseTimer(time)
                endif
            endif
            set index=index+1
        endloop
    endfunction
    
    private function a takes nothing returns nothing
        local kData tempDat
        local unit source=GetEventDamageSource()
        local unit target=GetTriggerUnit()
        local location lS=GetUnitLoc(source)
        local location lT=GetUnitLoc(target)
        local real direction=AngleBetweenPoints(lS,lT)
        local real power=15+GetEventDamage()/2
        if power>65 then
            set power=65
        endif
        if GetUnitTypeId(source)=='hrif' or GetUnitTypeId(source)=='hgyr' or GetUnitTypeId(source)=='hgry' or GetUnitTypeId(source)=='hdhw' then
            set power=power/2
        endif
        if IsUnitType(target,UNIT_TYPE_FLYING)!=true and IsUnitType(target,UNIT_TYPE_STRUCTURE)!=true then
            set tempDat=kData.create()
            set tempDat.u=target
            set tempDat.direction=direction
            set tempDat.power=R2I(power)
            set dbIndex=dbIndex+1
            set kDB[dbIndex]=tempDat
            if dbIndex==0 then
                call TimerStart(time,.03,true,function p)
            endif
        endif
        call RemoveLocation(lS)
        call RemoveLocation(lT)
    endfunction
    
    private function i takes nothing returns nothing
        set tDDKB=CreateTrigger()
        call TriggerAddAction(tDDKB,function a)
    endfunction
endscope

Thanks in advance
 
Status
Not open for further replies.
Top