1. Find your way through the deepest dungeon in the 18th Mini Mapping Contest Poll.
    Dismiss Notice
  2. A brave new world lies beyond the seven seas. Join the 34th Modeling Contest today!
    Dismiss Notice
  3. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
Hive 3 Remoosed BETA - NOW LIVE. Go check it out at BETA Hive Workshop! Post your feedback in this new forum BETA Feedback.
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[System] [Needs Work] Move Unit API

Discussion in 'Graveyard' started by Section, Aug 15, 2012.

  1. Section

    Section

    Joined:
    Jul 23, 2008
    Messages:
    97
    Resources:
    0
    Resources:
    0
    Unit Move API
    Script Type : JASS

    Requires :

    Code (vJASS):
    globals
        hashtable udg_SkillTable = InitHashtable()
        real udg_updateSpeed = 0.04 //Default value
    endglobals


    Code and description :

    Code (vJASS):
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //
    //
    //        Move Unit API
    //
    //          by SECTION
    //
    //  Requires :
    //      udg_SkillTable : Hashtable
    //      udg_updateSpeed: real
    //
    //  What API?
    //
    //      This API is used to make a unit moves via trigger, which is Linear or Circular.
    //      
    //  What features/benefits?
    //
    //      See that some functions returned trigger?
    //      This is used for controlling the movement. You can manipulate a unit's movement which is moving
    //      via included functions, so you could increase or decrease its speed, change its destination, and
    //      even stop or force done the movement.
    //
    //      Also, because of return trigger, you could attach one or more values to it via Hashtable so
    //      you may transport some values from any trigger to next another trigger.
    //
    //  What bug/leak?
    //
    //      I have tested some and it did well, although the use of the function is a bit "difficult".
    //      But it still works well and fast. I still don't see any leak or memory inefficient.
    //      If you might see some unusefulness of function, please report it.
    //
    //  What for?
    //      
    //      You could use this system for :
    //      - Missile
    //      - Dash
    //      - Some spell mechanics
    //  
    //
    //  What's next?
    //
    //      If you have something to say (lets say it... a bug? new feature? some requests? or.. signature? XD)
    //      Just post your comment here, or e-mail those things to [email]Section_another@hotmail.com[/email]
    //      Prior signature >_<
    //
    //
    //  Here is the list of function that could be used :
    //
    //
    ////////////trigger MoveUnitXY( unit wUnit, real speed, real X, real Y, trigger exec )
    //          
    //      This trigger will move wUnit to target X,Y which travels speed units per second.
    //      After wUnit arrives at destination point, trigger exec will be executed.
    //          wUnit   : Specifies which unit is being to be moved.
    //          speed   : Specifies how fast the moving will be. (in units)
    //          X       : Specifies where the X coordinate of destination point.
    //          Y       : Specifies where the Y coordinate of destination point.
    //          exec    : Specifies what trigger will be run after the movement is done.
    //      Returns a trigger, which is the control of the movement.
    //
    ////////////trigger MoveUnitToUnit( unit wUnit, real speed, unit wTarget, trigger exec )
    //
    //      This trigger will move wUnit to target wTarget which travels speed units per second.
    //          wUnit   : Specifies which unit is being to be moved.
    //          speed   : Specifies how fast the moving will be. (in units)
    //          wTarget : Specifies which unit is to be the destination target.
    //          exec    : Specifies what trigger will be run after the movement is done.
    //      Returns a trigger, which is the control of the movement.
    //
    ////////////trigger MoveUnitCircular( unit wUnit, real degreeSpeed, real radius, real X, real Y, real degreeInit )
    //
    //      This trigger will make wUnit rotates toward X,Y, which rotates degreeSpeed angle per second, rotates in
    //      a radius distance of pivot point, and will start moving from angle of degreeInit.
    //          wUnit       : Specifies which unit is being to be moved.
    //          degreeSpeed : Specifies the angle of rotation movement size per second (in degrees)
    //          X,Y         : Specifies the target X, Y of pivot point of rotation.
    //          degreeInit  : Specifies the initial angle of unit position towards pivot point.
    //      Returns a trigger, which is the control of the movement.
    //
    //////////trigger MoveUnitCircularUnit( unit wUnit, real degreeSpeed, real radius, unit wTarget, real degreeInit )
    //
    //      This trigger will make wUnit rotates toward wTarget unit, which rotates degreeSpeed angle per second,
    //      rotates in a radius distance of pivot point, and will start moving from angle of degreeInit.
    //          wUnit       : Specifies which unit is being to be moved.
    //          degreeSpeed : Specifies the angle of rotation movement size per second (in degrees)
    //          wTarget     : Specifies the unit target of pivot point of rotation.
    //          degreeInit  : Specifies the initial angle of unit position towards pivot point.
    //
    //////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////
    ////////Control Functions
    //////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////
    //
    //
    //      Control functions are used for manipulate unit's movement, such as increase or decrease the speed,
    //      changes the destination, or many more.
    //          real XYDist(real X1, real Y1, real X2, real Y2)
    //      Function List :
    //
    //
    ////////////void StopMovingUnitXY( trigger t )
    //
    //      This function will force stop the unit's movement.
    //          t : Specifies the trigger control.
    //
    ////////////void UpdateMoveUnitSpeed( trigger t, real newSpeed)
    //
    //      This function will modifies the unit's movement speed.
    //          t        : Specifies the trigger control.
    //          newSpeed : Specifies the new speed of movement.
    //
    ////////////void UpdateMoveUnitXY( trigger t, real newX, real newY )
    //
    //      This function will modifies the destination point in X,Y.
    //          t   : Specifies the trigger control.
    //          newX: Specifies the new X coordinate of destination point.
    //          newY: Specifies the new Y coordinate of destination point.
    //
    ////////////void UpdateMoveUnitTarget ( trigger t, unit newTarget )
    //
    //      This function will modifies the unit which is target of the movement.
    //          t        : Specifies the trigger control.
    //          newTarget: Specifies the new target unit of movement.
    //
    ////////////void UpdateMoveUnitRadius ( trigger t, real newRadius )
    //
    //      This function will modifies the distance of circular movement.
    //          t        : Specifies the trigger control.
    //          newRadius: Specifies the new distance of circular movement.
    //
    //      NOTE: This function is specialized for Circular Movement.
    //
    ////////////void UpdateMoveUnitDegreeSpeed ( trigger t, real newDegreeSpeed )
    //
    //      This function will modifies the angle speed of circular movement.
    //          t             : Specifies the trigger control.
    //          newDegreeSpeed: Specifies the new angle speed in degrees.
    //
    //      NOTE: This function is specialized for Circular Movement.
    //
    ////////////void UpdateMoveUnitDegreePosition ( trigger t, real newCurrentDegree )
    //
    //      This function will forcely modifies the angle position of circular movement.
    //          t               : Specifies the trigger control.
    //          newCurrentDegree: Specifies the new angle position in degrees.
    //
    //      NOTE: This function is specialized for Circular Movement.
    //
    ////////////void ForceExecute ( trigger t )
    //
    //      This function will forcely execute the trigger exec of trigger control.
    //          t : Specifies the trigger control.
    //      
    ////////////unit GetMovingUnit( trigger t )
    //
    //      This function will return the unit that specified in movement.
    //          t : Specifies the trigger control.
    //
    //      This function will returns a unit.
    //
    ////////////void SetUnitPosEx( unit wUnit, real moveSize, real tgtX, real tgtY )
    //
    //      This function will instantly move (or set the new position) wUnit towards tgtX,tgtY location
    //      and moves moveSize units.
    //          wUnit   : Specifies the unit that want to be moved.
    //          moveSize: Specifies the distance of movement in units.
    //          tgtX    : Specifies the X coordinate of destination facing point.
    //          tgtY    : Specifies the Y coordinate of destination facing point.
    //
    //
    //////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////
    //END OF DESCRIPTION
    //////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////


    //========================================================================
    //========================================================================
    //Control and Other Function
    //========================================================================
    //========================================================================

    function ForceExecute takes trigger t returns nothing
        call TriggerExecute(LoadTriggerHandle(udg_SkillTable, GetHandleId(t), StringHash("Exec")  ))
    endfunction

    function GetMovingUnit takes trigger t returns unit
        return LoadUnitHandle(udg_SkillTable, GetHandleId(t), StringHash("wUnit") )
    endfunction

    function XYDist takes real X1, real Y1, real X2, real Y2 returns real
        local real dx = X2 - X1
        local real dy = Y2 - Y1
        return SquareRoot(dx * dx + dy * dy)  
    endfunction

    function SetUnitPosEx takes unit wUnit, real moveSize, real tgtX, real tgtY returns nothing
        local real getAngle = bj_RADTODEG * Atan2(tgtY - GetUnitY(wUnit), tgtX - GetUnitX(wUnit))
        local real x = GetUnitX(wUnit) + moveSize * Cos(getAngle * bj_DEGTORAD)
        local real y = GetUnitY(wUnit) + moveSize * Sin(getAngle * bj_DEGTORAD)
        call SetUnitPosition(wUnit, x,y)
        call SetUnitFacing(wUnit, getAngle)
    endfunction

    function StopMovingUnitXY takes trigger t returns nothing
        call FlushChildHashtable(udg_SkillTable, GetHandleId(t) )
        call DestroyTrigger(t)
    endfunction

    function UpdateMoveUnitSpeed takes trigger t, real newSpeed returns nothing
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("speed"), newSpeed)
    endfunction


    function UpdateMoveUnitXY takes trigger t, real newX, real newY returns nothing
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("X"), newX)
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("Y"), newY)
    endfunction

    function UpdateMoveUnitRadius takes trigger t, real newRadius returns nothing
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("radius"), newRadius)
    endfunction

    function UpdateMoveUnitDegreeSpeed takes trigger t, real newDegreeSpeed returns nothing
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("degreeSpeed"), newDegreeSpeed)
    endfunction

    function UpdateMoveUnitDegreePosition takes trigger t, real newCurrentDegree returns nothing
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("currentDegree"), newCurrentDegree)
    endfunction

    function UpdateMoveUnitTarget takes trigger t, unit newTarget returns nothing
        call SaveUnitHandle(udg_SkillTable, GetHandleId(t), StringHash("wTarget"), newTarget)
    endfunction

    //========================================================================
    //========================================================================
    //Hardcore Action Function
    //========================================================================
    //========================================================================

    function MoveProc takes nothing returns nothing
        //Unpack the load
        local unit wUnit = LoadUnitHandle (udg_SkillTable, GetHandleId(GetTriggeringTrigger()), StringHash("wUnit") )
        local real speed = LoadReal       (udg_SkillTable, GetHandleId(GetTriggeringTrigger()), StringHash("speed") )                                                                      
        local real X     = LoadReal       (udg_SkillTable, GetHandleId(GetTriggeringTrigger()), StringHash("X")     )
        local real Y     = LoadReal       (udg_SkillTable, GetHandleId(GetTriggeringTrigger()), StringHash("Y")     )
        local trigger exec= LoadTriggerHandle(udg_SkillTable, GetHandleId(GetTriggeringTrigger()), StringHash("Exec")  )
        //Let's process the movement
        //First, check if UnitX is bigger than target X (also Y), to determine the upside/downside.
        //Oh, we can use XYDist!
        call SetUnitPosEx( wUnit, speed * udg_updateSpeed, X, Y )
        //Check!
        if XYDist(GetUnitX(wUnit), GetUnitY(wUnit), X, Y ) <= speed * udg_updateSpeed then
            //Finish touch here!
            //Note that we can't create new listener. Therefore, we use Trigger!
            //call ExecuteFunc(exec)
            call SetUnitPosition(wUnit, X, Y)
            call TriggerExecute(exec)
            //Clean this mess and let it tingle
            call StopMovingUnitXY(GetTriggeringTrigger())
            call FlushChildHashtable(udg_SkillTable, GetHandleId(GetTriggeringTrigger() ) )  
        endif
        //Trying to Nullify the allocated pointer
        //Because even pointer takes 4 byte for declaration, right?
        set wUnit = null
        set exec = null //don't destroy! it won't work...
    endfunction

    function MoveProcUnit takes nothing returns nothing    
        local unit wUnit = LoadUnitHandle (udg_SkillTable, GetHandleId(GetTriggeringTrigger()), StringHash("wUnit") )
        local real speed = LoadReal       (udg_SkillTable, GetHandleId(GetTriggeringTrigger()), StringHash("speed") )                                                                      
        local unit wTarget=LoadUnitHandle (udg_SkillTable, GetHandleId(GetTriggeringTrigger()),StringHash("wTarget"))
        local trigger exec= LoadTriggerHandle(udg_SkillTable, GetHandleId(GetTriggeringTrigger()), StringHash("Exec")  )
       
        call SetUnitPosEx( wUnit, speed * udg_updateSpeed, GetUnitX(wTarget), GetUnitY(wTarget) )

        if XYDist(GetUnitX(wUnit), GetUnitY(wUnit), GetUnitX(wTarget), GetUnitY(wTarget) ) <= speed * udg_updateSpeed then

            call SetUnitPosition(wUnit, GetUnitX(wTarget), GetUnitY(wTarget))
            call TriggerExecute(exec)

            call StopMovingUnitXY(GetTriggeringTrigger())
            call FlushChildHashtable(udg_SkillTable, GetHandleId(GetTriggeringTrigger() ) )  
        endif

        set wUnit = null
        set exec = null
    endfunction

    function MoveProcCircular takes nothing returns nothing
        local real sourceX = LoadReal(udg_SkillTable, GetHandleId(GetTriggeringTrigger() ), StringHash("X") )
        local real sourceY = LoadReal(udg_SkillTable, GetHandleId(GetTriggeringTrigger() ), StringHash("Y") )                                                                                  
        local unit wUnit = LoadUnitHandle(udg_SkillTable, GetHandleId(GetTriggeringTrigger() ), StringHash("wUnit") )
       
        local real Angle = LoadReal(udg_SkillTable, GetHandleId(GetTriggeringTrigger() ), StringHash("currentDegree") )
        local real radius = LoadReal(udg_SkillTable, GetHandleId(GetTriggeringTrigger() ), StringHash("radius") )
        local real degreeSpeed = LoadReal(udg_SkillTable, GetHandleId(GetTriggeringTrigger() ), StringHash("degreeSpeed") )
        //
       
        //
        local real x = sourceX + radius * Cos((Angle + degreeSpeed) * bj_DEGTORAD)
        local real y = sourceY + radius * Sin((Angle + degreeSpeed) * bj_DEGTORAD)
        call SetUnitPosition(wUnit,x,y)
       
        call SetUnitFacing(wUnit, ((RAbsBJ(degreeSpeed)/degreeSpeed) * 90) + Angle )
        if (Angle) >= 360 then
            set Angle = RAbsBJ(360 - Angle)
        endif
        call SaveReal(udg_SkillTable, GetHandleId(GetTriggeringTrigger()), StringHash("currentDegree"), Angle + degreeSpeed)
       
        set wUnit = null
    endfunction

    function MoveProcCircularUnit takes nothing returns nothing
        local unit target = LoadUnitHandle(udg_SkillTable, GetHandleId(GetTriggeringTrigger() ), StringHash("wTarget") )
        local unit wUnit = LoadUnitHandle(udg_SkillTable, GetHandleId(GetTriggeringTrigger() ), StringHash("wUnit") )
        local real Angle = LoadReal(udg_SkillTable, GetHandleId(GetTriggeringTrigger() ), StringHash("currentDegree") )
        local real radius = LoadReal(udg_SkillTable, GetHandleId(GetTriggeringTrigger() ), StringHash("radius") )
        local real degreeSpeed = LoadReal(udg_SkillTable, GetHandleId(GetTriggeringTrigger() ), StringHash("degreeSpeed") )
     
        local real x = GetUnitX(target) + radius * Cos((Angle + degreeSpeed) * bj_DEGTORAD)
        local real y = GetUnitY(target) + radius * Sin((Angle + degreeSpeed) * bj_DEGTORAD)
        call SetUnitPosition(wUnit,x,y)
        call SetUnitFacing(wUnit, ((RAbsBJ(degreeSpeed)/degreeSpeed) * 90) + Angle )
        if (Angle) >= 360 then
            set Angle = RAbsBJ(360 - Angle)
        endif
        call SaveReal(udg_SkillTable, GetHandleId(GetTriggeringTrigger()), StringHash("currentDegree"), Angle + degreeSpeed)
        set wUnit = null
    endfunction

    //========================================================================
    //========================================================================
    //Main Move Function
    //========================================================================
    //========================================================================

    function MoveUnitXY takes unit wUnit, real speed, real X, real Y, trigger exec returns trigger
        local trigger t = CreateTrigger()
        //Packing before expanding

        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("X"), X)
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("Y"), Y)
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("speed"), speed)
        call SaveUnitHandle(udg_SkillTable, GetHandleId(t), StringHash("wUnit"), wUnit)
        call SaveTriggerHandle( udg_SkillTable, GetHandleId(t), StringHash("Exec"), exec )
       
        //Trigger Session
        call TriggerRegisterTimerEvent(t, udg_updateSpeed, true)
        call TriggerAddAction(t,function MoveProc)
       
        //Return huff... w00t with return trigger? ooo...
        return t
    endfunction

    function MoveUnitToUnit takes unit wUnit, real speed, unit wTarget, trigger exec returns trigger
        local trigger t = CreateTrigger()
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("speed"), speed)
        call SaveUnitHandle(udg_SkillTable, GetHandleId(t), StringHash("wUnit"), wUnit)
        call SaveUnitHandle(udg_SkillTable, GetHandleId(t), StringHash("wTarget"), wTarget)
        call SaveTriggerHandle( udg_SkillTable, GetHandleId(t), StringHash("Exec"), exec )
       
        call TriggerRegisterTimerEvent(t, udg_updateSpeed, true)
        call TriggerAddAction(t,function MoveProcUnit)
       
        return t
    endfunction

    function MoveUnitCircular takes unit wUnit, real degreeSpeed, real radius, real X, real Y, real degreeInit returns trigger
        local trigger t = CreateTrigger()
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("degreeSpeed"), degreeSpeed)
        call SaveUnitHandle(udg_SkillTable, GetHandleId(t), StringHash("wUnit"), wUnit)
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("X"), X)
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("Y"), Y)
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("radius"), radius)
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("degreeInit"), degreeInit)
       
        call TriggerRegisterTimerEvent(t, udg_updateSpeed, true)
        call TriggerAddAction(t, function MoveProcCircular)
       
        //Init Position
        call SetUnitPosition(wUnit, X + radius * Cos(degreeInit * bj_DEGTORAD) , Y + radius * Sin(degreeInit * bj_DEGTORAD) )
        return t
    endfunction

    function MoveUnitCircularUnit takes unit wUnit, real degreeSpeed, real radius, unit wTarget, real degreeInit returns trigger
        local trigger t = CreateTrigger()
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("degreeSpeed"), degreeSpeed)
        call SaveUnitHandle(udg_SkillTable, GetHandleId(t), StringHash("wUnit"), wUnit)
        call SaveUnitHandle(udg_SkillTable, GetHandleId(t), StringHash("wTarget"), wTarget)
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("radius"), radius)
        call SaveReal(udg_SkillTable, GetHandleId(t), StringHash("currentDegree"), degreeInit)
       
        call TriggerRegisterTimerEvent(t, udg_updateSpeed, true)
        call TriggerAddAction(t, function MoveProcCircularUnit)
       
        call SetUnitPosition(wUnit, GetUnitX(wTarget) + radius * Cos(degreeInit * bj_DEGTORAD) , GetUnitY(wTarget) + radius * Sin(degreeInit * bj_DEGTORAD) )
        return t
    endfunction


    An example could be downloaded here, or from attachment below.

    ===============================================
    reminder

    Reminder for self :
    - return timer thing, which probably much faster.
    - Cache the GetTriggeringTrigger() etc.
    - Reduce unused calculations and conversion. (bj_DEGTORAD)
    - Replace the StringHash with traditional integer.
    - Library form.
     

    Attached Files:

    Last edited: Aug 15, 2012
  2. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,430
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    First thing I noticed, you should use timers instead of triggers; it is 1 handle vs. ~3 handles (trigger + event + action)
     
  3. Section

    Section

    Joined:
    Jul 23, 2008
    Messages:
    97
    Resources:
    0
    Resources:
    0
    Uh... oh...
    I really don't know actually that trigger handle carries 3 more handles instead just trigger itself...

    But is it a bit... weird? As far as I know, is Handle similar to pointer? which takes 4 byte of memory (long) whatever it refers to. I use return trigger because every use of those functions will create a trigger.

    CMIIW :3
     
  4. mckill2009

    mckill2009

    Joined:
    Mar 10, 2009
    Messages:
    4,696
    Resources:
    34
    Maps:
    5
    Spells:
    27
    JASS:
    2
    Resources:
    34
    - This is better off in a library without the udg_
    - Never use StringHash, it's too slow
    - some of the conversions are too slow also, like;
    Code (vJASS):

    function SetUnitPosEx takes unit wUnit, real moveSize, real tgtX, real tgtY returns nothing
        local real getAngle = bj_RADTODEG * Atan2(tgtY - GetUnitY(wUnit), tgtX - GetUnitX(wUnit))
        local real x = GetUnitX(wUnit) + moveSize * Cos(getAngle * bj_DEGTORAD)
        local real y = GetUnitY(wUnit) + moveSize * Sin(getAngle * bj_DEGTORAD)
        call SetUnitPosition(wUnit, x,y)
        call SetUnitFacing(wUnit, getAngle)
    endfunction
     

    -->
    Code (vJASS):

    function SetUnitPosEx takes unit wUnit, real moveSize, real tgtX, real tgtY returns nothing
        local real getAngle = Atan2(tgtY - GetUnitY(wUnit), tgtX - GetUnitX(wUnit))
        local real x = GetUnitX(wUnit) + moveSize * Cos(getAngle)
        local real y = GetUnitY(wUnit) + moveSize * Sin(getAngle)
        call SetUnitPosition(wUnit, x,y)
        call SetUnitFacing(wUnit, getAngle*bj_RADTODEG)
    endfunction
     

    - Cache the GetTriggeringTrigger, GetUnitX, etc...coz it spams...
     
  5. Section

    Section

    Joined:
    Jul 23, 2008
    Messages:
    97
    Resources:
    0
    Resources:
    0
    1. Yeah, I want to, but surprisingly I'm still learning vJass thing until this day... and somewhat I still don't get used with that and back to this classic JASS...

    Though, the library thing will be more efficient, I will work on it, although it would take a bit 'long' time.

    2. About StringHash thing... I don't know that. Ok I'll change it to 'traditional' integers.

    3 & 4. Aiye cap'n.
     
  6. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,430
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    Yes, handles are 4 bytes (32 bits), but 3 handles take up more memory than 1.

    As for the system, it is nice and functional, just needs some work to optimize it. :) Some things I recommend are looking into timer systems and vJASS. It isn't necessary to have it in vJASS, but it might be good practice to make the conversion if you want to learn it eventually. It also makes implementation a bit easier, because instead of having to declare the variables in the variable editor, you can just put them in a globals block.

    I recommend downloading JASS NewGen Pack:
    http://wc3modding.info/4263/the-jass-newgen-pack-jngp-1-5e/

    Then you can get started on vJASS in the manual. Of course, these are just suggestions, you don't have to move to it if you don't want to, but it could make the system a bit better and it could make your modding experience a lot more fun. :D
     
  7. Nestharus

    Nestharus

    Joined:
    Jul 10, 2007
    Messages:
    6,146
    Resources:
    8
    Spells:
    3
    Tutorials:
    4
    JASS:
    1
    Resources:
    8
    Bro, look at my sig to learn most of vjass in a couple of hours =p.


    Also, there are currently much better missile systems in the jass section, both in terms of efficiency and capability.

    edit
    with further review, this system is in a horrendous state in terms of efficiency. Using a module for specific movement schemes and having 1 movement core is much smarter. With this systems' current setup, I would be impressed if you could even run 50 units smoothly. Keep in mind that a good unit movement system can run between 650 to 700 units smoothly (300-350 on a meh comp).

    I would applaud your efforts in any other language, but the overhead of trigger evaluations in JASS is simply too steep. Ovoid them like the plague and only use them when absolutely necessary.
     
    Last edited: Aug 17, 2012
  8. Section

    Section

    Joined:
    Jul 23, 2008
    Messages:
    97
    Resources:
    0
    Resources:
    0
    Oh I see... Maybe I was too naive for JASS... Because I always taught that is better to let a system work like "an object" (class-like)...

    I can't do much for converting the return trigger... but I will find out. The best what I can do now is the StringHash, unused calculations and the caching.

    Thanks for giving me some benchmark value (the 50 and 600 thingy...).
     
  9. Nestharus

    Nestharus

    Joined:
    Jul 10, 2007
    Messages:
    6,146
    Resources:
    8
    Spells:
    3
    Tutorials:
    4
    JASS:
    1
    Resources:
    8
    That is ture, it is just tricky in jass/vjass
     
  10. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,003
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    Pro-tip:
    You can omit the SquareRoot function call when retrieving the distance.
    All you would have to do is compare with whatever you want squared. (Don't use Pow(x, 2), use x*x, because Pow is pretty slow)
     
  11. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,398
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    GetMovingUnit is an API already in the IsUnitMoving library.
     
  12. Laiev

    Laiev

    Joined:
    Oct 11, 2008
    Messages:
    275
    Resources:
    1
    Template:
    1
    Resources:
    1
    Sorry, I can't ready your docs, and this isn't Starcraft II.

    ////////////trigger MoveUnitXY( unit wUnit, real speed, real X, real Y, trigger exec )

    ////////////void StopMovingUnitXY( trigger t )
     
  13. Nestharus

    Nestharus

    Joined:
    Jul 10, 2007
    Messages:
    6,146
    Resources:
    8
    Spells:
    3
    Tutorials:
    4
    JASS:
    1
    Resources:
    8
    This is the documentation style that a lot of the more active JASS people use now.

    http://www.hiveworkshop.com/forums/jass-resources-412/repo-comment-headers-192184/

    It was influenced by purge's style. It's pretty much the most readable and compact style there is atm. I personally don't use the entire style as doing all of it is quite a bit of work ; ).

    This is an example of mag's take on the style -> http://www.hiveworkshop.com/forums/submissions-414/snippet-bufferex-215816/

    You should aspire to use the entire style as it is at a professional level (function headers, struct headers, etc). It is the style I use when writing c++ for college or work (the entire style that is). I don't use the full style in vjass because I really am too lazy to write it all up. When you code, more than half of the time is usually spent on documentation ; |.

    Even when instructors have dictated everyone to use a certain style, this style has still been accepted w/o notice or anything, so the style is extremely good. There have been no complaints about it in professional environments or classroom environments.
     
  14. Section

    Section

    Joined:
    Jul 23, 2008
    Messages:
    97
    Resources:
    0
    Resources:
    0
    Ok holiday's done... I'm back...

    Oh you're right... Even I have done some cleaning... it's quite lagged when system runs about 40-50 projectiles...

    looks these codes need to be reworked... completely reworked T_T... although it runs fine...
     
  15. TriggerHappy

    TriggerHappy

    Code Moderator

    Joined:
    Jun 23, 2007
    Messages:
    3,833
    Resources:
    22
    Spells:
    11
    Tutorials:
    2
    JASS:
    9
    Resources:
    22
    This really inefficient and it leaks. The API is also awkward and some function names aren't unique enough.
     
  16. Malhorne

    Malhorne

    Joined:
    Sep 14, 2012
    Messages:
    2,327
    Resources:
    6
    Spells:
    4
    Tutorials:
    1
    JASS:
    1
    Resources:
    6
    Code (vJASS):
    function XYDist takes real X1, real Y1, real X2, real Y2 returns real
        local real dx = X2 - X1
        local real dy = Y2 - Y1
        return SquareRoot(dx * dx + dy * dy)  
    endfunction

    ->
    Code (vJASS):
    function XYDist takes real X1, real Y1, real X2, real Y2 returns real
        return SquareRoot((X2-X1)*(X2-X1) + (Y2-Y1)*(Y2-Y1))  
    endfunction



    Not to mention that this is slow and leaky :/
     
  17. edo494

    edo494

    Joined:
    Apr 16, 2012
    Messages:
    3,846
    Resources:
    5
    Spells:
    1
    JASS:
    4
    Resources:
    5
    no, just no

    purly inline it, you only use it 2 times, and its not that hard to inline it

    if you want to have additional function call, ommit SquareRoot, and call it something like XYDistPow, so it is evident that it is not square rooted

    are you sure this is great idea? Because firing trigger whenever any unit on map uses sounds pretty heavy to me, you tested it with like 500 units moving on 240x240 or so map?
     
  18. Malhorne

    Malhorne

    Joined:
    Sep 14, 2012
    Messages:
    2,327
    Resources:
    6
    Spells:
    4
    Tutorials:
    1
    JASS:
    1
    Resources:
    6
    Why are you saying no ?
    I was simplifying his func ^^
    I didn't say it was a good pratice to not inline this kind of calculus.
     
  19. edo494

    edo494

    Joined:
    Apr 16, 2012
    Messages:
    3,846
    Resources:
    5
    Spells:
    1
    JASS:
    4
    Resources:
    5
    you are still calling SquareRoot, which is not good :D and I didnt mean the no-s seriously, just disagreeing with simplifing, just inline that shit :D , yes the if block will be like 50 characters long, but meh, its Jass, it cant debug, not to mention optimizations
     
  20. Malhorne

    Malhorne

    Joined:
    Sep 14, 2012
    Messages:
    2,327
    Resources:
    6
    Spells:
    4
    Tutorials:
    1
    JASS:
    1
    Resources:
    6
    Ah yes but if he doesn't want to inline I didn't force him ^^^
    I was saying that his func could be better :)
    You're suggesting another way (which is better ofc ^^) that's different ;)
    But anyway when you want the exact distance you need to use SquareRoot sorry xD