Cohadar
master of fugue
- Reaction score
- 209
JASS:
//==============================================================================
// UnitLock -- by Cohadar -- v1.0
//==============================================================================
//
// PURPOUSE:
// * Preventing multiple spells from moving the unit at the same time,
// thus preventing spell interference bugs.
//
// * Orders spells by priority which has 2 effects:
// * Stronger spells can overtake the weaker ones.
// * Weaker spells will not work on units affected by stronger spell.
//
// FUNCTIONS:
// * UnitLock_Set(whichUnit, priority, overtakeIfSame) -> lockId
// * UnitLock_Get(whichUnit) -> lockId
// * UnitLock_Release(whichUnit, lockId)
//
// HOW TO USE:
// * The Set function creates a lock on the unit and returns the lockId
// lockId can be any number different from zero
//
// * priority field determines what to do if there already exists a lock on the unit
// Some spells can have higher priority than others so they can overtake the unit
//
// * There are 3 lock types: weak, normal, strong
// * [weak] (priority <= 0.0)
// Weak locks will always be overtaken even if new lock is of lower priority
// All weak locks are equal
// * [normal] (0.0 < priority <= 1.0)
// Normal locks can be overtaken only by a lock of higher priority
// or if overtakeIfSame is true for a lock of same priority
// If overtaking fails Set function returns zero
// * [strong] (1.0 < priority)
// Strong locks cannot be overtaken
// All strong locks are equal
//
// * Get function returns the lockId, or zero if no lock is set.
// You should use this function inside a spell loop to check if your spell
// stil has lock on the unit.
//
// * Release function must provide a valid lockId.
// Spell instance can unlock only it's own locks.
//
// DETAILS:
// * The release method will restore the unit's default fly height.
//
// * Units that get close to map borders will have their lock broken.
// This will prevent the spell from taking the unit beyond border.
//
// * There is no GetPriority function, this is on purpose.
//
// REQUIREMENTS:
// * PUI
//
// HOW TO IMPORT:
// * Just create a trigger named UnitLock
// * convert it to text and replace the whole trigger text with this one
//
//==============================================================================
library UnitLock initializer Init uses PUI
//! runtextmacro PUI_PROPERTY("private", "integer", "LockId", "0")
//! runtextmacro PUI_PROPERTY("private", "real", "LockPriority", "0.0")
globals
public constant real HEIGHT_RESTORATION_SPEED = 400.
private integer lockCounter = 0
endglobals
//===========================================================================
// Returns zero if lock could not be set
//===========================================================================
public function Set takes unit whichUnit, real priority, boolean overtakeIfSame returns integer
local boolean overtake = false
if (LockId[whichUnit] == 0) or (LockPriority[whichUnit] <= 0.0) then
set overtake = true
else
if (LockPriority[whichUnit] <= 1.0) then
if LockPriority[whichUnit] < priority then
set overtake = true
elseif LockPriority[whichUnit] == priority then
set overtake = overtakeIfSame
endif
endif
endif
if overtake then
set lockCounter = lockCounter + 1
set LockId[whichUnit] = lockCounter
set LockPriority[whichUnit] = priority
return lockCounter
else
return 0
endif
endfunction
//===========================================================================
// Use this inside a spell loop to check if your spell stil has lock on the unit.
//===========================================================================
public function Get takes unit whichUnit returns integer
return LockId[whichUnit]
endfunction
//===========================================================================
// Spell instance can only release it's own lock.
//===========================================================================
public function Release takes unit whichUnit, integer lockId returns nothing
if LockId[whichUnit] == lockId then
set LockId[whichUnit] = 0
set LockPriority[whichUnit] = 0.0
call SetUnitFlyHeight(whichUnit, GetUnitDefaultFlyHeight(whichUnit), HEIGHT_RESTORATION_SPEED)
endif
endfunction
//===========================================================================
private function BorderStop takes nothing returns nothing
local unit whichUnit = GetTriggerUnit()
set LockId[whichUnit] = 0
set LockPriority[whichUnit] = 0.0
call SetUnitFlyHeight(whichUnit, GetUnitDefaultFlyHeight(whichUnit), HEIGHT_RESTORATION_SPEED)
set whichUnit = null
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterLeaveRectSimple( trig, GetPlayableMapRect() )
call TriggerAddAction( trig, function BorderStop )
endfunction
endlibrary
It might not look that way at first but this little script is actually a physics system. The biggest lol about this is that it is actually the most powerfull wc3 physics system ever created.
Try out the spells from demo map and be amazed