System ParabolaSystem

wraithseeker

Tired.
Reaction score
122
This is a system that allows units to jump much more realistic then ParabolaZ snippet. You can specify the gravity values like in real life on how they would affect you.

For a test run

JASS:
scope Test initializer init

private function SpellEffect takes nothing returns boolean
    local unit u=GetTriggerUnit()
    local FlyHeightData f=FlyHeightData.get(u)
    set f.velocity=f.velocity+20.
    return false
endfunction

globals
    private group TestGroup=CreateGroup()
endglobals

private function Add takes nothing returns nothing
    call FlyHeightData.create(GetEnumUnit())
endfunction

private function init takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerRegisterPlayerUnitEvent(t,Player(0),EVENT_PLAYER_UNIT_SELECTED,null)
    call TriggerAddCondition(t,Condition(function SpellEffect))
    call GroupEnumUnitsInRect(TestGroup,bj_mapInitialPlayableArea,null)
    call ForGroup(TestGroup,function Add)
endfunction
endscope


And now the library which is a standalone one

JASS:
library ParabolaSystem 

// made by Viikuna and wraithseeker

// WRAPPERS

private function H2I takes handle h returns integer
    return h
    return 0
endfunction
private function GetUnitId takes unit u returns integer
     return H2I(u)-0x100000 //return u:Id
endfunction
// ENDWRAPPERS


// you can use these functions for example:
// preventing flying units from walking around
private function Landing takes unit u returns nothing
//     call UnitModifyMoveSpeed(u, 10000)
endfunction

private function Takeoff takes unit u returns nothing
//    call UnitModifyMoveSpeed(u, -10000)
endfunction


//=================================================================
//                  HOW TO USE ?
//=================================================================
//     create for unit:
//       local FlyHeightData f= FlyHeightData.create( unit )
//
//            ....
//     get from unit:
//       local FlyHeightData f= FlyHeightData.get( unit )
//
//     modify values:  
//       set f.velocity=f.velocity+10.
//       set f.position=f.position-2.5
//       set f.gravity=1.2
//
//     do stuff to unit:
//      call KillUnit(f.unit)
//
//     destroy from unit:
//       call FlyHeightData.destroy( FlyHeightData.Get( unit ) )
//=================================================================
//                 SYSTEM CODE:
//=================================================================

globals
    private constant real TIMEOUT = .025
    private constant real DEFAULT_GRAVITY = 1.2
    private constant integer FLY_HEIGHT_ABILITY_ID = 'Amrf'
endglobals

private interface face
    method onIteration takes nothing returns nothing defaults nothing
    method onLanding takes nothing returns nothing defaults nothing
    method onTakeoff takes nothing returns nothing defaults nothing
endinterface

struct FlyHeightData extends face
    
    private static FlyHeightData array UnitData
    
    private static FlyHeightData array array
    private static timer timer=CreateTimer()
    private static integer Total=0
    
    private unit unitz
    private boolean time=false
    private real velocityZ=0.0
    private real positionZ=0.0
    real gravity=0.0
    

    method operator unit takes nothing returns unit
        return .unitz
    endmethod
    
    method operator velocity takes nothing returns real
        return .velocityZ
    endmethod
    
    method operator velocity= takes real r returns nothing
         set .velocityZ=r
         if not .time then
             set .time=true
             if .Total==0 then
                 call TimerStart(.timer,TIMEOUT,true,function FlyHeightData.periodic)
             endif
             set .array[.Total]=this
             set .Total=.Total+1
         endif
    endmethod
    
    method operator position takes nothing returns real
        return .positionZ
    endmethod
    
    method operator position= takes real r returns nothing
         if r<= 0.0 then
             set .positionZ=0.0
         else
             set .positionZ=r
             if not .time then
                 set .time=true
                 if .Total==0 then
                     call TimerStart(.timer,TIMEOUT,true,function FlyHeightData.periodic)
                 endif
                 set .array[.Total]=this
                 set .Total=.Total+1
            endif
         endif
    endmethod
    
    static method create takes unit u returns FlyHeightData
        local FlyHeightData f=FlyHeightData.allocate()
        set f.unitz=u
        call UnitAddAbility(u,FLY_HEIGHT_ABILITY_ID)
        call UnitRemoveAbility(u,FLY_HEIGHT_ABILITY_ID)
        set f.gravity= -(DEFAULT_GRAVITY/2.)
        set .UnitData[GetUnitId(u)]=f
        return f
    endmethod
    
    private method action takes nothing returns boolean
        local boolean b=.positionZ<=0.0
        if .onIteration.exists then
            call .onIteration()
        endif
        set .velocityZ=.velocityZ+.gravity
        set .positionZ=.positionZ+.velocityZ
        set .velocityZ=.velocityZ+.gravity
        call SetUnitFlyHeight(.unitz,.positionZ,0.0)
        if b and .positionZ>0.0 then
            call Takeoff(.unitz)
            if .onTakeoff.exists then
                call .onTakeoff()
            endif
        endif
        if .positionZ <= 0.0 then
            set .velocityZ=0.0
            call Landing(.unitz)
            if .onLanding.exists then
                call .onLanding()
            endif
            set .time=false
            return true
        endif
        return false
    endmethod
   
    private static method periodic takes nothing returns nothing
        local integer i=0
        loop
            exitwhen i>=.Total
            if .array<i>.action() then
                set .Total=.Total-1
                if .Total&gt;0 then
                    set .array<i>=.array[.Total]
                    set i=i-1
                else
                    call PauseTimer(.timer)
                endif
            endif
            set i=i+1
        endloop
    endmethod
    
    static method get takes unit u returns integer
        return .UnitData[ GetUnitId(u) ]
    endmethod
    
endstruct

endlibrary</i></i>



This library is a optional module, use it if you want and don't use it if you don't want to.

This system creates a flyheightdata for every unit that enters the game so as to ease people's work of creating it.

JASS:
  library ParabolaGet initializer Init requires ParabolaSystem

globals
    private boolexpr b
endglobals

private function True takes nothing returns boolean
    return true
endfunction

private function Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    call FlyHeightData.create(u)
    set u = null
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local region r = CreateRegion()
    local group g = CreateGroup()
    local unit u
    set b = Filter(function True)
    call RegionAddRect(r,bj_mapInitialPlayableArea)
    call TriggerRegisterEnterRegion(t,r,b)
    call TriggerAddAction( t, function Actions )
    call GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea,b)
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call FlyHeightData.create(u)
        call GroupRemoveUnit(g,u)
    endloop
    set u = null
    call DestroyGroup(g)
    set g = null
endfunction
endlibrary
 

Attachments

  • FlyHeightSystem.w3x
    32.1 KB · Views: 159

Trollvottel

never aging title
Reaction score
262
JASS:
private function GetUnitId takes unit u returns integer
     return H2I(u)-0x100000 //return u:Id
endfunction


not such a good idea.... attaching to units like this is never very clever. better use PUI. Well its a quite simple system isn't it? Could be nice for some beginners though, lets see...

Also make a better documentation for this please and move it to the top of the trigger.
 

Viikuna

No Marlo no game.
Reaction score
265
That function is there, so you can easily make it use any unit indexing system you want. Just make it return GetUnitUserData or GetUnitIndex or whatever that PUI function is.
 

Romek

Super Moderator
Reaction score
964
You don't explain a thing about what this does in the first post.
Why are there even two scripts? What's the difference?
What's each one for?
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top