n[u]ll
You can change this now in User CP.
- Reaction score
- 93
Ultimate Slide System
v1.8
v1.8
This is my version of the Ice Slide/Skate functions that have become so popular. I call this one the Ultimate because of a few key improvements over any others I've seen:
- Simple to use, little to no JASS knowledge required
- No leaks, and lag free
- It uses only natives
- Allows for either both region-check sliding or terrain-check sliding (explained in the readme)
- Terrain check uses offsets for better paths
- Support for multiple "slide tiles"
- Highly customizable
- RoC compatible
Changelog
v1.0 - Initial Release
v1.1 - Addition of arrays/Collision and Off-path-death triggers.
v1.2 - Cleaned up some code/Minor bug fixes
v1.3 - Added testing functions
v1.4 - Added patrollers and other maze-like features.
v1.5 - Bug fix (thanks Aspard)/Rearranged the triggers/Clarified some triggers and functions.
v1.6 - Bug fixes, updated some code for aesthetics and effeciency
v.a - Documented a known bug, changed a testing trigger to avoid clicking an in-game hotkey.
v1.7 - Improved readability. Added TerrainCheck with changeable offset. Made changing the periodic timer in the Slide trigger easier.
v1.8 - Updated documentation. Changed tileset. Added support for multiple tile checks. Added more support for slower/faster sliding.
v1.1 - Addition of arrays/Collision and Off-path-death triggers.
v1.2 - Cleaned up some code/Minor bug fixes
v1.3 - Added testing functions
v1.4 - Added patrollers and other maze-like features.
v1.5 - Bug fix (thanks Aspard)/Rearranged the triggers/Clarified some triggers and functions.
v1.6 - Bug fixes, updated some code for aesthetics and effeciency
v.a - Documented a known bug, changed a testing trigger to avoid clicking an in-game hotkey.
v1.7 - Improved readability. Added TerrainCheck with changeable offset. Made changing the periodic timer in the Slide trigger easier.
v1.8 - Updated documentation. Changed tileset. Added support for multiple tile checks. Added more support for slower/faster sliding.
JASS:
//***************************************************************************************************
// *
// ##### / ## ####### ####### *
// ###### / ##### / ### / ### *
// /# / / ##### / ## / ## *
// / / ## # ## ## # ## # *
// / ### # ### ### *
// ## ## # ## ### ## ### *
// ## ## # ### ### ### ### *
// ## ## # ### ### ### ### *
// ## ## # ### /## ### /## *
// ## ## # #/ /## #/ /## *
// ## ## # #/ ## #/ ## *
// ## # # # / # / *
// ### / ## / ## / *
// #######/ ########/ ########/ *
// #### ##### ##### *
// *
// Created By N[o]obleT *
// *
//__________________________________________________________________________________________________*
//__________________________________________________________________________________________________*
// *
// It should be first noted that there are two ways this system can be used. *
// *
// The first and easiest way is through a terrain check (found under the TerrainCheck *
// folder). This will check if any of the units are on your designated sliding terrain. *
// If a unit is, it will make them slideable. It's simple, but a major downside is *
// that there little control over the area a unit can actually slide, and the path becomes very *
// strict (or "tight"). *
// *
// The other way to slide a unit in this system is through region checks. This is more time- *
// consuming, but in the long run it is better due to the high customizability. *
// *
// IMPORTING: *
// When you import this system, it's recommended that you copy every folder except for "Misc" into *
// your map. Make sure you do not rearrange the orders of the triggers or folders, doing this may *
// cause an error when saving the map. Once you've copied the folders over to your map, save your *
// map. There shouldn't be any errors when you save, but if there are you should contact me. *
// *
// HOW TO USE: *
// *
// How to use the REGION CHECK way: *
// 1.)If you'd like to use region checks, first disable every trigger under TerrainCheck. *
// 2.)Next make sure all the triggers in the RegionCheck folder are enabled. *
// 3.)Make note of the regions I used (and where i put them) in the map: *
// a. At any terrain touching ice, I made a region named SlideRect<#>. If a unit leaves these *
// regions, he will be able to slide. *
// *
// b. At any place where the safe path goes from touching snow and ice to ONLY touching snow, *
// I created a region named SlideFalse<#>. This is because if a unit leaves a SlideRect, *
// he will slide, but what if he leaves the region going away from the ice, like down a *
// grass path? Then these regions will catch him before he slides on grass, which would be *
// f'd up. Make sure that when you create these regions that they are not touching (leave *
// a slight gap). *
// *
// 4.)Update all of the CheckLeave/CheckFalse/CheckEnter triggers with the new regions you added. *
// *
// How to use the TERRAIN CHECK way: *
// 1.)Disable every trigger under RegionCheck. Enable every trigger under TerrainCheck. *
// 2.)Make sure the terrain type in TerrainSetup is the same terrain you're using to slide on. *
// 3.)Also change the terrain type (it says 'Nsnw') in TerrainCheck to the terrain you're using *
// for the opposite terrain of the path. Read ALL the comments, they are there for a reason. *
// *
// I HOPE YOU ENJOY IT! *
//__________________________________________________________________________________________________*
Code:
There's more to this system than the following, but I'm going to post just the most commonly used functions/triggers so this post won't get so cluttered.
SlideSteerVariables
TerrainCheckOffsetCheckTerrainCheckSlideTerrainCheckDeath
JASS:
function SlideA takes nothing returns nothing
local unit u = GetEnumUnit ( ) //Set the picked unit
local integer i = GetPlayerId ( GetOwningPlayer( u ) ) + 1 //Set the Player number of the unit.
local real x = GetUnitX ( u ) //Set the units X
local real y = GetUnitY ( u ) //Set the units Y
if udg_onIce[ i ] == true and GetUnitState( u, UNIT_STATE_LIFE ) > 0 then //Check if the unit is on ice and is alive
call SetUnitX( u , x + udg_Speed[ i ] * Cos( GetUnitFacing( u ) * 0.017453292 ) ) //Set the units x-axis position
call SetUnitY( u , y + udg_Speed[ i ] * Sin( GetUnitFacing( u ) * 0.017453292 ) ) //Set the units y-axis position
if udg_realisticSlide[ i ] == false then //If realisticSlide for that unit is turned off then
call IssueImmediateOrder( u,"stop" ) // Order the unit to stop
endif
endif
set u = null //Nulling the local unit variable (otherwise it will leak)
endfunction
function SlideG takes nothing returns nothing
call ForGroup( udg_Slideables , function SlideA ) //Pick every unit in Slideables and runs function SlideA for each picked unit
endfunction
function InitSlide takes nothing returns nothing
local timer t = CreateTimer( )
call TimerStart( t, udg_timeStep, true, function SlideG ) // Tell the timer to run SlideG every udg_timeStep seconds
set t = null
endfunction
function InitTrig_Slide takes nothing returns nothing
//Ignore this function, it's required by the World Editor but I don't need anything done in it.
endfunction
JASS:
function SteerObj takes nothing returns nothing
local unit u = GetTriggerUnit ( )
local integer i = GetPlayerId ( GetOwningPlayer( u ) ) + 1
local real x = GetUnitX ( u )
local real y = GetUnitY ( u )
local real a = GetWidgetX ( GetOrderTarget( ) )
local real b = GetWidgetY ( GetOrderTarget( ) )
if udg_Steerable[ i ] == true then
if udg_onIce[ i ] == true and IsUnitInGroup( u , udg_Slideables ) then
call SetUnitFacing( u , 57.2957795 * Atan2( b - y , a - x ) ) //Set the unit facing to Angle between points (x,y) and (a,b)
endif
endif
set u = null //Nulling the unit variable
endfunction
function SteerLoc takes nothing returns nothing
local unit u = GetTriggerUnit ( )
local integer i = GetPlayerId ( GetOwningPlayer( u ) ) + 1
local real x = GetUnitX ( u )
local real y = GetUnitY ( u )
local real a = GetOrderPointX ( )
local real b = GetOrderPointY ( )
if udg_Steerable[ i ] == true then
if udg_onIce[ i ] == true and IsUnitInGroup( u , udg_Slideables ) then
call SetUnitFacing( u , 57.2958279 * Atan2( b - y , a - x ) ) //Set the unit facing to Angle between points (x,y) and (a,b)
endif
endif
set u = null //Nulling the unit variable
endfunction
function InitTrig_Steer takes nothing returns nothing
local integer i = 0
local trigger SO = CreateTrigger( )
local trigger SL = CreateTrigger( )
call TriggerAddAction( SO , function SteerObj )
call TriggerAddAction( SL , function SteerLoc )
loop
exitwhen i > 11
call TriggerRegisterPlayerUnitEvent( SO , Player( i ) , EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER , null )
call TriggerRegisterPlayerUnitEvent( SL , Player( i ) , EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER , null )
set i = i + 1
endloop
set SO = null
set SL = null
endfunction
Trigger:
- Events
- Map initialization
- Conditions
- Actions
- Set timeStep = 0.02
- Set offsetDist = 32.00
- Set deathTerrain = 0
- Set slideTerrain[0] = 0
- For each (Integer A) from 1 to 12, do (Set realisticSlide[(Integer A)] = False)
- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- Custom script: set udg_slideTerrain[1] = 'Iice' //To change the terrain type, replace Iice with any of the terrains listed in the TTypes trigger
- Custom script: set udg_slideTerrain[2] = 'Idki' //To change the terrain type, replace Idki with any of the terrains listed in the TTypes trigger
- Custom script: set udg_slideTerrain[3] = 'Nice' //To change the terrain type, replace Nice with any of the terrains listed in the TTypes trigger
- Set maxSlideTerrains = 3
- Set speedMultiplier[1] = 1.00
- Set speedMultiplier[2] = 0.75
- Set speedMultiplier[3] = 1.25
- Custom script: set udg_deathTerrain = 'Isnw' //To change the terrain type, replace Isnw with any of the terrains listed in the TTypes trigger
- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- Unit Group - Add Runner 0000 <gen> to Slideables
- Unit Group - Add Runner 0004 <gen> to Slideables
- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- For each (Integer A) from 1 to 12, do (Set Steerable[(Integer A)] = True)
- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- Set initSpeed = 3.75
- For each (Integer A) from 1 to 12, do (Set Speed[(Integer A)] = (initSpeed x (100.00 x timeStep)))
- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- Custom script: call InitSlide( ) //And now we run the InitSlide trigger (it's important to run this anytime AFTER you setup your timeStep variabel)
TerrainCheckOffsetCheck
JASS:
function TerrainCheckOffsetCheck takes real x, real y, integer whichTerrain, boolean inverseCheck returns boolean
local integer terrain = 0
local integer degrees = 0
local real a = 0
local real b = 0
loop
exitwhen degrees > 360
set a = x + udg_offsetDist * Cos( degrees * 0.017453292 ) //Set x = unit's x + offsetDist facing n degrees
set b = y + udg_offsetDist * Sin( degrees * 0.017453292 ) //"" y " "" y " "" "" " ""
set terrain = GetTerrainType( a, b ) //Set terrain = terrain type at ( a, b )
if inverseCheck == true then
if terrain != whichTerrain then //Check if the terrain type at the unit's position offset by offsetDist facing n is NOT equal to the specified terrain
return true // If so then return true and
exitwhen true // exit the loop
endif
else
if terrain == whichTerrain then //Check if the terrain type at the unit's position offset by offsetDist facing n is equal to the specified terrain
return true // If so then return true and
exitwhen true // exit the loop
endif
endif
set degrees = degrees + 1 //Add 1 to degrees
endloop
return false //If nothing else was true, then return false
endfunction
function TerrainCheckOnIce takes integer whichPlayer, integer terrain, real x, real y returns boolean
local integer i = 1
loop
exitwhen i > udg_maxSlideTerrains
if terrain == udg_slideTerrain[ i ] or TerrainCheckOffsetCheck( x, y, udg_slideTerrain[ i ], false ) then //If the terrain at the unit is one of the sliding terrains then:
set udg_Speed[ whichPlayer ] = ( udg_initSpeed * 100 * udg_timeStep ) * udg_speedMultiplier[ i ] // Set that unit's speed to the original speed setting multiplied by the terrain's corresponding udg_speedMultiplier array
return true // Return that yes, the given parameters are on ice.
endif
set i = i +1
endloop
return false
endfunction
//===========================================================================
function InitTrig_TerrainCheckFunctions takes nothing returns nothing
//Ignore this function, it's required by the World Editor but I don't need anything done in it.
endfunction
JASS:
function TerrainCheckSlide_A2 takes nothing returns nothing
local unit u = GetEnumUnit ( ) //Set the picked unit as variable "u"
local integer i = GetPlayerId ( GetOwningPlayer( u ) ) + 1 //Get the Player number of the unit.
local real x = GetUnitX ( u ) //Get the units X
local real y = GetUnitY ( u ) //Get the units Y
local integer t = GetTerrainType ( x , y ) //Get the terrain type at the location of the unit
if GetUnitState( u , UNIT_STATE_LIFE ) > 0 then //Check if unit is alive
if TerrainCheckOnIce( i, t, x, y ) then //Check the parameters against the function TerrainCheckOnIce (located in the TerrainCheckFunctions trigger)
set udg_onIce[ i ] = true //Set OnIce[OwningPlayer'sNumber] = true, allowing the unit to slide.
else
set udg_onIce[ i ] = false //Set OnIce[OwningPlayer'sNumber] = false, disabling the unit's slide.
endif
endif
set u = null //Nulling the unit variable
endfunction
function TerrainCheckSlide_A1 takes nothing returns nothing
call ForGroup( udg_Slideables , function TerrainCheckSlide_A2 ) //Pick every unit in Slideables and runs function TerrainCheckSlide_A2 for each picked unit
endfunction
function InitTrig_TerrainCheckSlide takes nothing returns nothing
local timer t = CreateTimer( )
call TimerStart( t, 0.05, true, function TerrainCheckSlide_A1 ) //Tell the timer to run TerrainCheckSlide_A1 every 0.05 seconds
set t = null
endfunction
JASS:
function TerrainCheckDeath_A2 takes nothing returns nothing
local unit u = GetEnumUnit ( ) //Sets the picked unit as variable "u"
local real x = GetUnitX ( u ) //Gets the units X
local real y = GetUnitY ( u ) //Gets the units Y
local integer terrain = GetTerrainType ( x , y ) //Gets the terrain type at the location of the unit
if GetUnitState( u , UNIT_STATE_LIFE ) > 0 and terrain == udg_deathTerrain then //Check if unit is alive and is on the specified death terrain, if he is then do:
if not TerrainCheckOffsetCheck( x, y, udg_deathTerrain, true ) then //Check if the unit is NOT close to any non-death terrain
call KillUnit(u) //If he isn't then kill him
endif
endif
set u = null //Nulling the unit variable
endfunction
function TerrainCheckDeath_A1 takes nothing returns nothing
call ForGroup( udg_Slideables , function TerrainCheckDeath_A2 ) //Pick every unit in Slideables and runs function TerrainCheckDeathA2 for each picked unit
endfunction
function InitTrig_TerrainCheckDeath takes nothing returns nothing
local timer t = CreateTimer( )
call TimerStart( t, 0.05, true, function TerrainCheckDeath_A1 ) // Tell the timer to run TerrainCheckDeathA1 every 0.05 seconds
set t = null
endfunction
alt download link: http://www.hiveworkshop.com/forums/spells-569/ultime-sliding-system-v1-8-a-144440/