• 🏆 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!

Sliding System v3.4

Sliding System v3.4


Info

Sliders can have a special sliding behaviour on different terrain types.
Each slider also can have it's own movement speed while sliding, seperated and indepentand from the terrain type.

This library provides various possibilities to create an individual behaviour for each terrain type. (Config - Part)

Requires (credits)

- Table (Bribe)

-
TimerUtils (Vexorian)

-
UnitIndexer (Nestharus)

-
WorldBounds(Nestharus)

-
Event(Nestharus)

Code
JASS:
library SlidingSystem/* v3.4    By IcemanBo

 */ requires /*

        */ UnitIndexer    /* The one in test map. (by Nestharus v4.0.2.6)
        */ TimerUtils     /* http://www.wc3c.net/showthread.php?t=101322
        */ Table          /* http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/
        */ WorldBounds    /* https://github.com/nestharus/JASS/blob/master/jass/Systems/WorldBounds/script.j
        */ Event          /* The one in test map.


**                          Info
**                        ¯¯¯¯¯¯¯¯
**
**  Sliders can have a special sliding behaviour on different terrain types.
**  Each slider also can have it's own movement speed while sliding,
**  seperated and indepentand from the terrain type.
**
**  This library provides various possibilities
**  to create an individual behaviour for each terrain type. (Config - Part)
**   
**
**  Struct Terrain:
**
**
**      static method create takes integer terainType, real terrainSpeed returns thistype
**
**          Furthermore you can define and read these public members:
**          (by default all values are "0" or "false".
**
**          pullSpeed      = Unit will be constantly pulled with this speed. (real)
**          pullDirection  = Direction for pulling, in degrees. (real)
**          angle          = Angle that will be added, when steering. (real)
**          lifeAddition   = Life that will be added each second. Negagtive values are also possible. (real)
**          allowSteer     = If unit can steer on the tarrainType or not. (boolean)
**          allowCast      = If unit can cast on the terrainType or not. (boolean)
**          kill           = Kill the unit on the terrainType or not. (boolean)
**          
**
**    You can have a look into folder TestMap -> "Terrain Settings" for a better understanding and examples.
**
**
**  Struct Slider:
**
**
**      static methods:
**     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
**
**          static method create takes unit u returns thistype
**
**          static method getSliderId takes unit u returns thistype
**
**          static method isUnitSlider takes unit u returns boolean
**
**
**
**      methods:
**     ¯¯¯¯¯¯¯¯¯¯
**
**          method destroy takes nothing returns nothing
**
**          method enable takes boolean b returns nothing   (disabled instance can't slide)
**             
**          method isEnabled takes nothing returns boolean
**
**          method getDefaultSpeed takes nothing returns real
**
**          method getTempSpeed takes nothing returns real
**
**          method setDefaultSpeed takes real s returns nothing
** 
**          method addDefaultSpeed takes real s returns nothing
**
**          method addTempSpeed takes real speed, real duration returns nothing
**
**
**
**    Deindexed units will be automatically removed from system.
**    You can have a look into folder TestMap -> "Create Slider" for a better understanding and examples.
**
***************************************************************************
**
**  Credits to guys named in brackets.
**
**  Requires:
**      - Table (Bribe)
**      - TimerUtils (Vexorian)
**      - UnitIndexer (Nestharus)
**          • WorldBounds (Nestharus)
**          • Event (Nestharus)
**
**
**************************************************************************
*
*
************************  Configuration - Start ***************************/

    globals
   
        private constant boolean SLIDER_UNCLICKABLE    = true    // Make Slider unclickable.
        private constant boolean SLIDER_NO_PATHING     = true    // Disable pathing for Slider.
        private constant boolean CHECK_PATHING         = false   // Check for pathability while sliding.
       
       
/************************ Configuration - End *****************************/

       
        private constant real INTERVAL     = .03              // Sliding looks smoother smoother with .03 instead of 0.312500.
        private constant real TPS          = 1/INTERVAL       // Operation threads per second
        private trigger steerTrigger       = CreateTrigger()
        private trigger moveTrigger        = CreateTrigger()  // Sliding looks smoother with trigger instead of a timer.
        private constant integer SMART     = 851971
        private constant integer STOP      = 851972
        private constant integer PATROL    = 851990
        private constant integer MOVE      = 851986
                                       
    endglobals
   
    /*
    *   Terrain struct, to define sliding behaviour.
    */
   
    struct Terrain
        private static key k
        private static Table table = k
       
        private integer terrainType
       
        real speed
        real pullSpeed = 0
        real pullDirection = 0
        real angle = 0
        real lifeAddition = 0
        boolean allowSteer = false
        boolean allowCast = false
        boolean kill = false
       
        static method create takes integer whichTerrain, real whichSpeed returns thistype
            local thistype this = thistype.allocate()
            set thistype.table[whichTerrain] = this
            set this.terrainType = whichTerrain
            set this.speed = whichSpeed/TPS
            return this
        endmethod
        static method operator [] takes integer i returns thistype
            return thistype.table[i]
        endmethod
    endstruct

    /*
    *   Acceleration struct, to manipulate Slider's temporary speed
    */
   
    private struct Acceleration
        public timer tim
        public real speedChange
        public Slider instance
       
        static method create takes Slider slider, real speed returns thistype
            local thistype this = thistype.allocate()
            set this.instance = slider
            set this.speedChange = speed
            return this
        endmethod
       
        method destroy takes nothing returns nothing
            call this.deallocate()
            call ReleaseTimer(tim)
        endmethod
    endstruct
   
    /*
    *   Slider struct (main code)
    */

    struct Slider
       
       
        private static thistype array list
        private static boolean  array is    // Is unit a slider
       
        private unit slider
        public real defaultSpeed  //  Permanent speed
        public real bonusSpeed    //  Temporary speed
       
        private real propWindow
        private real turnSpeed
       
        private boolean enabled   // If slider is currently enabled.
       
        private thistype prev
        private thistype next
        static thistype first = 0
       
        static method create takes unit u returns thistype
            local thistype this
            local integer index = GetUnitUserData(u)
           
            if (isUnitSlider(u)) then
                debug call BJDebugMsg("Error -  Sliding System - create: " + GetUnitName(u) + ", Index[" + I2S(index) + "] is already a Slider." )
                return 0
            endif
           
            set this = thistype.allocate()
           
            set this.slider = u
            set thistype.list[index] = this
            set this.is[index] = true
            set this.enabled = true
           
            set this.propWindow = GetUnitDefaultPropWindow(slider)*bj_RADTODEG
            set this.turnSpeed  = GetUnitDefaultTurnSpeed(slider)
   
            static if (SLIDER_UNCLICKABLE) then
                call UnitAddAbility(u,'Aloc')
                call ShowUnit(u,false)
                call ShowUnit(u,true)
                call UnitRemoveAbility(u,'Aloc')
            endif
           
            static if (SLIDE_NO_PATHING) then
                call SetUnitPathing( u, false )
            endif
           
            if (thistype.first == 0) then
                call EnableTrigger(moveTrigger)
            endif
           
            set this.next = thistype.first
            set thistype.first.prev = this
            set thistype.first = this
            set this.prev = 0
           
            return this
        endmethod
       
        method destroy takes nothing returns nothing
            local integer index = GetUnitUserData(slider)
            call this.deallocate()           
            set thistype.list[index] = 0
            set this.is[index] = false
            set this.slider = null
           
            if (this == thistype.first) then
                set thistype.first = this.next
            endif
            set this.next.prev = this.prev
            set this.prev.next = this.next
            if (thistype.first == 0) then
                call DisableTrigger(moveTrigger)
            endif
        endmethod
       
        /*
        *   Sliding - Movement  (periodic call)
        */
       
        private static method onMove takes nothing returns nothing
            local real angle
            local real offset
            local real x
            local real y
            local integer terrainType
            local thistype this = thistype.first
           
            loop
               
                exitwhen this == 0
               
                if enabled then
                   
                    set x = GetUnitX(slider)
                    set y = GetUnitY(slider)
                   
                    set terrainType = GetTerrainType(x, y)
                   
                    // Check if slider is on a registered terrain type.
                    if (Terrain[terrainType] != 0) then
                       
                        if (Terrain[terrainType].kill) then
                            call KillUnit(slider)
                        else
                            set angle = (GetUnitFacing(slider)*bj_DEGTORAD)
                            set offset = defaultSpeed + bonusSpeed + Terrain[terrainType].speed
                           
                            //  Heal/damage the slider.
                            call SetWidgetLife(slider,GetWidgetLife(slider) + Terrain[terrainType].lifeAddition/TPS)
                           
                            set x = x + offset * Cos(angle)
                            set y = y + offset * Sin(angle)
                           
                            //  Sliding
                            static if (CHECK_PATHING) then
                                call SetUnitPosition(slider, x, y)
                            else
                                call SetUnitX(slider, x)
                                call SetUnitY(slider, y)
                            endif
                           
                            //  Check if terrain type is pulling.
                            if (Terrain[terrainType].pullSpeed != 0) then
                                static if (CHECK_PATHING) then
                                    call SetUnitPosition(slider, x + (Terrain[terrainType].pullSpeed/TPS) * Cos(Terrain[terrainType].pullDirection*bj_DEGTORAD), y + (Terrain[terrainType].pullSpeed/TPS) * Sin(Terrain[terrainType].pullDirection*bj_DEGTORAD))
                                else
                                    call SetUnitX(slider, x + (Terrain[terrainType].pullSpeed/TPS) * Cos(Terrain[terrainType].pullDirection*bj_DEGTORAD))
                                    call SetUnitY(slider, y + (Terrain[terrainType].pullSpeed/TPS) * Sin(Terrain[terrainType].pullDirection*bj_DEGTORAD))
                                endif
                            endif
                           
                            // Make slider unmoveable while sliding.
                            call SetUnitPropWindow(slider, 0)
                            call SetUnitTurnSpeed(slider, 0.00)
                           
                        endif
                    else
                        // Make slider moveable.
                        call SetUnitPropWindow(slider,  propWindow )
                        call SetUnitTurnSpeed(slider, turnSpeed)
                    endif
                endif
               
                set this = next
            endloop
        endmethod
       
        /*
        *   Sliding - Steering
        */
       
        private static method onTurn takes nothing returns boolean
            local unit u = GetTriggerUnit()
            local real x
            local real y
            local integer terrainType
            local integer order = GetIssuedOrderId()
            local boolean b = true

            if (isUnitSlider(u) and list[GetUnitUserData(u)].enabled) then
                set x = GetUnitX(u)
                set y = GetUnitY(u)
               
                set terrainType = GetTerrainType(x, y)
               
                // Check if slider is on a registered terrain type.
                if (Terrain[terrainType] != 0) then
                   
                    if( (order == SMART) and (Terrain[terrainType].allowSteer)) then
                        // Let the slider turn.
                        call SetUnitFacing( u, (Atan2(GetOrderPointY() - y , GetOrderPointX() - x) * bj_RADTODEG) + Terrain[terrainType].angle)
                       
                    elseif ((order != SMART) and (order != MOVE) and (order != PATROL) and (Terrain[terrainType].allowCast)) then
                        // The slider is casting an ability. Let him face wanted position, if allowed.
                        call SetUnitFacing( u, Atan2(GetOrderPointY() - y , GetOrderPointX() - x) * bj_RADTODEG)
                        set b = false
                    endif
                   
                    if ((order == SMART) or (order == MOVE) or (order == PATROL) or (b)) then
                        call DisableTrigger( steerTrigger )
                        call PauseUnit (u,true)
                        call IssueImmediateOrderById(u, STOP)   // That will abbort unit's order if unit is not casting.
                        call PauseUnit (u,false)
                        call EnableTrigger( steerTrigger )
                    endif
                endif
            endif
           
            set u = null
            return false
        endmethod
       
       // API - Start
       
        static method getSliderId takes unit u returns thistype
            return list[GetUnitUserData(u)]
        endmethod
       
        static method isUnitSlider takes unit u returns boolean
            return is[GetUnitUserData(u)]
        endmethod
       
        method enable takes boolean b returns nothing
            set enabled = b
        endmethod
       
        method isEnabled takes nothing returns boolean
            return enabled
        endmethod
       
        method getDefaultSpeed takes nothing returns real
            return defaultSpeed*TPS
        endmethod
       
        method getTempSpeed takes nothing returns real
            return bonusSpeed*TPS
        endmethod
       
        /*   Permanent Boost   */
       
        method setDefaultSpeed takes real s returns nothing
            set defaultSpeed = s/TPS
        endmethod
       
        method addDefaultSpeed takes real s returns nothing
            set defaultSpeed = defaultSpeed + s/TPS
        endmethod
       
        /*  Temporary Boost  */
       
        private static method callback takes nothing returns nothing
            local Acceleration this = GetTimerData(GetExpiredTimer())
            set this.instance.bonusSpeed = this.instance.bonusSpeed - this.speedChange
            call this.destroy()
        endmethod
       
        method addTempSpeed takes real speed, real duration returns nothing
            local integer handleId
            local Acceleration newData
           
            if duration > 0 then
                set speed = speed/TPS
                set bonusSpeed = bonusSpeed + speed
                set newData = Acceleration.create(this, speed)
                set newData.tim = NewTimerEx(newData)
                call TimerStart(newData.tim, duration, false, function thistype.callback)
            else
                debug call BJDebugMsg("Error -  Sliding System - AddTempSpeed:  Duration must be greater 0.")
            endif
           
        endmethod
       
        // API - End
       
        private static method onDeindex takes nothing returns boolean
            if (thistype.isUnitSlider(GetIndexedUnit())) then
                call thistype.getSliderId(GetIndexedUnit()).destroy()
            endif
            return false
        endmethod

        private static method onInit takes nothing returns nothing
            call TriggerRegisterAnyUnitEventBJ( steerTrigger, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
            call TriggerAddCondition(steerTrigger, Condition(function thistype.onTurn))
            call TriggerRegisterTimerEvent(moveTrigger, INTERVAL, true)
            call TriggerAddAction(moveTrigger, function thistype.onMove)
            call DisableTrigger(moveTrigger)
            call RegisterUnitIndexEvent(Condition(function thistype.onDeindex), UnitIndexer.DEINDEX)
        endmethod
    endstruct
endlibrary

Have a look into TestMap folder. It contains examples how to use the system.

JASS:
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//-=-=-= Terrain Type Constants by Darthfett =-=-=-=-=-
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//-=-=-=-= Thanks to Romek for the Raw Codes  -=-=-=-=-
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

scope LORDAERONSUMMER
// Lordaeron Summer
globals
    public constant integer DIRT = 'Ldrt'
    public constant integer ROUGH_DIRT = 'Ldro'
    public constant integer GRASSY_DIRT = 'Ldrg'
    public constant integer ROCK = 'Lrok'
    public constant integer GRASS = 'Lgrs'
    public constant integer DARK_GRASS = 'Lgrd'
    public constant integer DIRT_CLIFF = 'cLc2'
    public constant integer GRASS_CLIFF = 'cLc1'
endglobals

endscope

scope LORDAERONFALL
// Lordaeron Fall
globals
    public constant integer DIRT = 'Fdrt'
    public constant integer ROUGH_DIRT = 'Fdro'
    public constant integer GRASSY_DIRT = 'Fdrg'
    public constant integer ROCK = 'Frok'
    public constant integer GRASS = 'Fgrs'
    public constant integer DARK_GRASS = 'Fgrd'
    public constant integer DIRT_CLIFF = 'cFc2'
    public constant integer GRASS_CLIFF = 'cFc1'
endglobals

endscope

scope LORDAERONWINTER
// Lordaeron Winter
globals
    public constant integer DIRT = 'Wdrt'
    public constant integer ROUGH_DIRT = 'Wdro'
    public constant integer GRASSY_SNOW = 'Wsng'
    public constant integer ROCK = 'Wrok'
    public constant integer GRASS = 'Wgrs'
    public constant integer SNOW = 'Wsnw'
    public constant integer GRASS_CLIFF = 'cWc2'
    public constant integer SNOW_CLIFF = 'cWc1'
endglobals

endscope

scope BARRENS
// Barrens
globals
    public constant integer DIRT = 'Bdrt'
    public constant integer ROUGH_DIRT = 'Bdrh'
    public constant integer PEBBLES = 'Bdrr'
    public constant integer GRASSY_DIRT = 'Bdrg'
    public constant integer DESERT = 'Bdsr'
    public constant integer DARK_DESERT = 'Bdsd'
    public constant integer ROCK = 'Bflr'
    public constant integer GRASS = 'Bgrr'
    public constant integer DESERT_CLIFF = 'cBc2'
    public constant integer GRASS_CLIFF = 'cBc1'
endglobals

endscope

scope ASHENVALE
// Ashenvale
globals
    public constant integer DIRT = 'Adrt'
    public constant integer ROUGH_DIRT = 'Adrd'
    public constant integer GRASS = 'Agrs'
    public constant integer ROCK = 'Arck'
    public constant integer LUMPY_GRASS = 'Agrd'
    public constant integer VINES = 'Avin'
    public constant integer GRASSY_DIRT = 'Adrg'
    public constant integer LEAVES = 'Alvd'
    public constant integer DIRT_CLIFF = 'cAc2'
    public constant integer GRASS_CLIFF = 'cAc1'
endglobals

endscope

scope FELWOOD
// Felwood
globals
    public constant integer DIRT = 'Cdrt'
    public constant integer ROUGH_DIRT = 'Cdrd'
    public constant integer POISON = 'Cpos'
    public constant integer ROCK = 'Crck'
    public constant integer VINES = 'Cvin'
    public constant integer GRASS = 'Cgrs'
    public constant integer LEAVES = 'Clvg'
    public constant integer DIRT_CLIFF = 'cCc2'
    public constant integer GRASS_CLIFF = 'cCc1'
endglobals

endscope

scope NORTHREND
// Northrend
globals
    public constant integer DIRT = 'Ndrt'
    public constant integer DARK_DIRT = 'Ndrd'
    public constant integer ROCK = 'Nrck'
    public constant integer GRASS = 'Ngrs'
    public constant integer ICE = 'Nice'
    public constant integer SNOW = 'Nsnw'
    public constant integer ROCKY_SNOW = 'Nsnr'
    public constant integer DIRT_CLIFF = 'cNc2'
    public constant integer SNOW_CLIFF = 'cNc1'
endglobals

endscope

scope CITYSCAPE
// Cityscape
globals
    public constant integer DIRT = 'Ydrt'
    public constant integer ROUGH_DIRT = 'Ydtr'
    public constant integer BLACK_MARBLE = 'Yblm'
    public constant integer BRICK = 'Ybtl'
    public constant integer SQUARE_TILES = 'Ysqd'
    public constant integer ROUND_TILES = 'Yrtl'
    public constant integer GRASS = 'Ygsb'
    public constant integer GRASS_TRIM = 'Yhdg'
    public constant integer WHITE_MARBLE = 'Ywmb'
    public constant integer DIRT_CLIFF = 'cYc2'
    public constant integer SQUARE_TILES_CLIFF = 'cYc1'
endglobals

endscope

scope VILLAGE
// Village
globals
    public constant integer DIRT = 'Vdrt'
    public constant integer ROUGH_DIRT = 'Vdrr'
    public constant integer CROPS = 'Vcrp'
    public constant integer COBBLE_PATH = 'Vcbp'
    public constant integer STONE_PATH = 'Vstp'
    public constant integer SHORT_GRASS = 'Vgrs'
    public constant integer ROCKS = 'Vrck'
    public constant integer THICK_GRASS = 'Vgrt'
    public constant integer DIRT_CLIFF = 'cVc2'
    public constant integer GRASS_THICK_CLIFF = 'cVc1'
endglobals

endscope

scope VILLAGEFALL
// Village Fall
globals
    public constant integer DIRT = 'Qdrt'
    public constant integer ROUGH_DIRT = 'Qdrr'
    public constant integer CROPS = 'Qcrp'
    public constant integer COBBLE_PATH = 'Qcbp'
    public constant integer STONE_PATH = 'Qstp'
    public constant integer SHORT_GRASS = 'Qgrs'
    public constant integer ROCKS = 'Qrck'
    public constant integer THICK_GRASS = 'Qgrt'
    public constant integer DIRT_CLIFF = 'cQc2'
    public constant integer GRASS_THICK_CLIFF = 'cQc1'
endglobals

endscope

scope DALARAN
// Dalaran
globals
    public constant integer DIRT = 'Xdrt'
    public constant integer ROUGH_DIRT = 'Xdtr'
    public constant integer BLACK_MARBLE = 'Xblm'
    public constant integer BRICK_TILES = 'Xbtl'
    public constant integer SQUARE_TILES = 'Xsqd'
    public constant integer ROUND_TILES = 'Xrtl'
    public constant integer GRASS = 'Xgsb'
    public constant integer TRIM_GRASS = 'Xhdg'
    public constant integer WHITE_MARBLE = 'Xwmb'
    public constant integer DIRT_CLIFF = 'cXc2'
    public constant integer SQUARE_TILES_CLIFF = 'cXc1'
endglobals

endscope

scope DUNGEON
// Dungeon
globals
    public constant integer DIRT = 'Ddrt'
    public constant integer BRICK = 'Dbrk'
    public constant integer RED_STONES = 'Drds'
    public constant integer LAVA_CRACKS = 'Dlvc'
    public constant integer LAVA = 'Dlav'
    public constant integer DARK_ROCKS = 'Ddkr'
    public constant integer GREY_STONES = 'Dgrs'
    public constant integer SQUARE_TILES = 'Dsqd'
    public constant integer DIRT_CLIFF = 'cDc2'
    public constant integer SQUARE_TILES_CLIFF = 'cDc1'
endglobals

endscope

scope UNDERGROUND
// Underground
globals
    public constant integer DIRT = 'Gdrt'
    public constant integer BRICK = 'Gbrk'
    public constant integer RED_STONES = 'Grds'
    public constant integer LAVA_CRACKS = 'Glvc'
    public constant integer LAVA = 'Glav'
    public constant integer DARK_ROCKS = 'Gdkr'
    public constant integer GREY_STONES = 'Ggrs'
    public constant integer SQUARE_TILES = 'Gsqd'
    public constant integer DIRT_CLIFF = 'cGc2'
    public constant integer SQUARE_TILES_CLIFF = 'cGc1'
endglobals

endscope

scope SUNKENRUINS
// Sunken Ruins
globals
    public constant integer DIRT = 'Zdrt'
    public constant integer ROUGH_DIRT = 'Zdtr'
    public constant integer GRASSY_DIRT = 'Zdrg'
    public constant integer SMALL_BRICKS = 'Zbks'
    public constant integer SAND = 'Zsan'
    public constant integer LARGE_BRICKS = 'Zbkl'
    public constant integer ROUND_TILES = 'Ztil'
    public constant integer GRASS = 'Zgrs'
    public constant integer DARK_GRASS = 'Zvin'
    public constant integer DIRT_CLIFF = 'cZc2'
    public constant integer LARGE_BRICKS_CLIFF = 'cZc1'
endglobals

endscope

scope ICECROWNGLACIER
// Icecrown Glacier
globals
    public constant integer DIRT = 'Idrt'
    public constant integer ROUGH_DIRT = 'Idtr'
    public constant integer DARK_ICE = 'Idki'
    public constant integer BLACK_BRICKS = 'Ibkb'
    public constant integer RUNE_BRICKS = 'Irbk'
    public constant integer TILED_BRICKS = 'Itbk'
    public constant integer ICE = 'Iice'
    public constant integer BLACK_SQUARES = 'Ibsq'
    public constant integer SNOW = 'Isnw'
    public constant integer RUNE_BRICKS_CLIFF = 'cIc2'
    public constant integer SNOW_CLIFF = 'cIc1'
endglobals

endscope

scope OUTLAND
// Outland
globals
    public constant integer DIRT = 'Odrt'
    public constant integer LIGHT_DIRT = 'Odtr'
    public constant integer ROUGH_DIRT = 'Osmb'
    public constant integer CRACKED_DIRT = 'Ofst'
    public constant integer FLAT_STONES = 'Olgb'
    public constant integer ROCK = 'Orok'
    public constant integer LIGHT_FLAT_STONES = 'Ofsl'
    public constant integer ABYSS = 'Oaby'
    public constant integer ABYSS_CLIFF = 'cOc1'
    public constant integer ROUGH_DIRT_CLIFF = 'cOc2'
endglobals

endscope

scope BLACKCITADEL
// Black Citadel
globals
    public constant integer DIRT = 'Kdrt'
    public constant integer LIGHT_DIRT = 'Kfsl'
    public constant integer ROUGH_DIRT = 'Kdtr'
    public constant integer FLAT_STONES = 'Kfst'
    public constant integer SMALL_BRICKS = 'Ksmb'
    public constant integer LARGE_BRICKS = 'Klgb'
    public constant integer SQUARE_TILES = 'Ksqt'
    public constant integer DARK_TILES = 'Kdkt'
    public constant integer DIRT_CLIFF = 'cKc1'
    public constant integer DARK_TILES_CLIFF = 'cKc2'
endglobals

endscope

scope DALARANRUINS
// Dalaran Ruins
globals
    public constant integer DIRT = 'Jdrt'
    public constant integer ROUGH_DIRT = 'Jdtr'
    public constant integer BLACK_MARBLE =  'Jblm'
    public constant integer BRICK_TILES = 'Jbtl'
    public constant integer SQUARE_TILES = 'Jsqd'
    public constant integer ROUND_TILES = 'Jrtl'
    public constant integer GRASS = 'Jgsb'
    public constant integer TRIM_GRASS = 'Jhdg'
    public constant integer WHITE_MARBLE = 'Jwmb'
    public constant integer DIRT_CLIFF = 'cJc2'
    public constant integer SQUARE_TILES_CLIFF = 'cJc1'
endglobals

endscope

Changelog


v3.3
- Just some cleaning.
v3.2
- Enable/disable a slider is now possible.
v3.1
- API methods changed into public functions for easier usage.
v3.0
- Everything is rewritten, using vJass. (structs)
- "Pull" feature added for terrain configuration.
- Many API changes.
v2.5
- API added
- new function AddSpeed added (whichunit, speed, duration)
v2.4a
- unimportant cosmetic changes
v2.4
- now the code is in JASS, but still GUI configuration
v2.3
- trigger optimization
- Changed description
- few variable name changes
v2.2
- new feature: sliding can heal/damage the slider (depending on terrain type)
v2.1c
- restrctured GSS Addtive
- simplified example add/remove slider
v2.1b
- added AddSupport trigger
v2.1a(Approved)
- removed a location leak in Slide Steer
- "issued order" in Slide Steer stored into variable
v2.1(Needs fix)
- possibility to check pathing while sliding
- removed one not needed location in Slide Steer
v2.0a
- unit's angle is reset now with RADTODEG
- New additive trigger added, how to read out values
v2.0
- combined both sliding systems into one
- new system is MUI, and easy manipulation of specific speed is possible
- demo map improved
v1.3
- removed useless line in slide steer
- description changed a bit
v1.2b
- usuage of hashtable to find matching terrain type, instead of looping (thx to chobibo, suggested by Maker)
- few code improvements
- documentation improvements
v1.2a
- fixed bug with CasterGroup (sorry I forgot to initializise them)
- new feature: AllowCasting (for each terraintype configurable)
v1.2
- new debug methode in Slide-Steer trigger via locals
- new configuration available: CasterGroup & Tile-CastTurning
v1.1c
- Slide code simplified via locals (GSS1)
v1.1b
- fixed bug at deindex in GSS1
- little slide bug fixed
v1.1a
- In GSS1 changed to dynamic looping
- Loop ends after have found matching tile
- Sliding: Order 'stop' replaced by changing Unit's PropWindow/TurnSpeed
- Index of kill-terrain is no constant anymore
- Tiny other changes that aren't worth to be noted
v1.1(Approved)
- replaced 'move unit instantly' by Set unit X/Y
- terrain types are now more flexible with specific speed & turning angle
- moved all unnecessary stuff out of the system
- system 1 now also supports non-heroes
- system 1 now supports 12 players
- terrain types are no longer set with 'Centre of Region' - but with preset
- code improvement
v1.0 - release


Keywords:
Sliding, System, Ice, Skating, Escape, IcemanBo, clan null, null, nullSkill, MUI Movement, snow, area
Contents

Sliding System (Map)

Reviews
BPower: Re-approved after code update. Ralle: set back to pending by request. Bribe: Re-approved. Bribe: Custom script: call SetUnitFacingTimed( u, ( AngleBetweenPoints(Location(GetUnitX(u), GetUnitY(u)), udg_Point2) +...
Level 4
Joined
Jun 30, 2013
Messages
76
Is it possible to make a unit sliding during next second if attacked and terrain == ice with 2 simple changes or something like that? I mean, can it be used in strategy to make smg like "ice battle"? And can units attack while sliding? I know that you can do impossible while sliding, not as in my ss, as uve seen.
 
Yes you can make a unit slider when it's attacked and remove it again after short time. You can test my demo map for examples. :csmile:

Attacking while sliding only works, if 'AllowCasting' is set to 'true' on that terrain.
Otherwise the unit's order get interrupted immediatly. You can modify it for each terrain type, if casting/attacking is allowed or not.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
The turn rate is too instant. For real, you can't turn than instantly while sliding upon icy ground. Just check out my Ring Out for reference. Even though it was hard-coded, but the movement looks fairly realistic. I hope you can find a better algorithm/formula :)

Currently, it looks too easy for pro-slider. And I suggest the turn rate to be modifiable for every tile type.
 
What does look too easy? It surely depends on the map that you create.

I'll think of your idea, it would be a fancy feature indeed. But I doubt I will implement it (or at least soon), because in my eyes it's usage is kept limited for my target group.
(You might not understand it, but we create(d) many of our maps basing on this turning behaviour. So I don't know if I want support to change it)
 

Deleted member 219079

D

Deleted member 219079

If I credit you Darthfett and Romek, can I use the tileset types gallery in my own project?

Or wait I see this is really processed.

But in order that I could use it, I'd really make use for .enable() and .disable(), otherwise I have to reinvent the wheel. Why enable and disable vs create and destroy? I just wanna use like a spell that has a lil' channeling time (blink forward).
 

Deleted member 219079

D

Deleted member 219079

I was requesting you to add .enable() and .disable() , so you don't need to use .destroy() and .create(), as .create() calculates for proper window and stuff like that. Basically I'd need it for stuff like blink or channeled turnaround etc.
 
I'd really like to see some friction applied. You don't slide forever on a real ice without applying force.

This is not supposed to have friction...
^Actually exactly this.

The target group of this system doesn't want to have any friction.
I see it was more realistic, but it's really not intended to have something like this.
Even someone would write it for me, I would not want to have it, lol. :D

For the "general sliding map" there must be infinite sliding, that what it's made for.
I saw Dalvengyr made some cool, more realistic sliding system.. he will for sure submit it as well I believe.

Btw, @all... I prefer to have the resource unrated.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
I quickly scanned the code and would like to mention a few things ( not now, I'm traveling )
Friction or infinite sliding are two types of sliding systems.
What you need, depends on the map philosophy.

Why TriggerAddAction?

enabled could be a simple boolean instead of using
operator overloading for enabling/disabling.

I will check te whole code after the weekend.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
Code looks good to me. Is there a reason, why you wanted it to be set back to on pending?

I guess, one can still cast spells which are target order or instant order.

You could mention in one sentence, that dead or even deindexed units are not
removed automatically from the system. So the user knows that
destroying an instance is up to him in any case.

I guess for this kind of maps it doesn't matter so much, except a player leaves the game.

integer type mmh ... :/

I just want to mention for those users, who may wonder:
private static Table table = k, it's really nice, that Bribes Table allows to allocate a Table instance by using a constant key.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
the table isnt allocated tho, so if k is positive, it may just so happen that I allocate it too, unless it has some inner protection for this kind of thing, but it would slow down your library immensly if you tried doing that
 
I wanted to know why you choose TriggerAddAction over TriggerAddCondition.
It might be imagination, but the same reason why I use trigger for periodic event and not simply a timer.
I think the sliding movement looks a bit smoother with it. xD

Code looks good to me. Is there a reason, why you wanted it to be set back to on pending?
Back then I knew I would rework the code completly, but had no time.
Then I prefered to let it be until the update.

I guess, one can still cast spells which are target order or instant order.
Yeah, user can set it to true/false when he defines a new terrain for sliding.:)

You could mention in one sentence, that dead or even deindexed units are not
removed automatically from the system. So the user knows that
destroying an instance is up to him in any case.
True, deindexed units could be removed automatically. Done.

integer type mmh ... :/
... xD. Changed.

And yes, I prefered to stay to old Unit Indexer by Nes then. :/
 
Top