Name | Type | is_array | initial_value |
CargoEvent | real | No | |
CargoTransportGroup | group | Yes | |
CargoTransportUnit | unit | Yes | |
CheckDeathList | integer | Yes | |
CheckDeathTimer | timer | No | |
DeathEvent | real | No | |
DetectRemoveAbility | abilcode | No | |
DetectTransformAbility | abilcode | No | |
gameTimer | timer | No | |
IsUnitAlive | boolean | Yes | |
IsUnitBeingUnloaded | boolean | Yes | |
IsUnitNew | boolean | Yes | |
IsUnitReincarnating | boolean | Yes | |
IsUnitRemoved | boolean | Yes | |
SummonerOfUnit | unit | Yes | |
UDex | integer | No | |
UDexLastRecycled | integer | No | |
UDexMax | integer | No | |
UDexNext | integer | Yes | |
UDexPrev | integer | Yes | |
UDexUnits | unit | Yes | |
UnitIndexerEnabled | boolean | No | |
UnitIndexEvent | real | No | |
UnitTypeEvent | real | No | |
WorldMaxX | real | No | |
WorldMaxY | real | No |
//TESH.scrollpos=0
//TESH.alwaysfold=0
//===========================================================================
function UnitEventDestroyGroup takes integer i returns nothing
if udg_CargoTransportGroup[i] != null then
call DestroyGroup(udg_CargoTransportGroup[i])
set udg_CargoTransportGroup[i] = null
endif
endfunction
function UnitEventCheckDeath takes nothing returns nothing
local integer i = udg_CheckDeathList[0]
set udg_CheckDeathList[0] = 0
loop
exitwhen i == 0
if udg_IsUnitNew[i] then
//The unit was just created.
set udg_IsUnitNew[i] = false
elseif udg_IsUnitAlive[i] then
//The unit has started reincarnating.
set udg_IsUnitReincarnating[i] = true
set udg_IsUnitAlive[i] = false
set udg_UDex = i
set udg_DeathEvent = 0.50
set udg_DeathEvent = 0.00
endif
set i = udg_CheckDeathList[i]
endloop
endfunction
function UnitEventCheckDeathProxy takes integer i returns nothing
if udg_CheckDeathList[0] == 0 then
call TimerStart(udg_CheckDeathTimer, 0.00, false, function UnitEventCheckDeath)
endif
set udg_CheckDeathList[i] = udg_CheckDeathList[0]
set udg_CheckDeathList[0] = i
endfunction
function UnitEventOnUnload takes nothing returns nothing
local integer i = udg_UDex
call GroupRemoveUnit(udg_CargoTransportGroup[GetUnitUserData(udg_CargoTransportUnit[i])], udg_UDexUnits[i])
set udg_IsUnitBeingUnloaded[i] = true
set udg_CargoEvent = 0.00
set udg_CargoEvent = 2.00
set udg_CargoEvent = 0.00
set udg_IsUnitBeingUnloaded[i] = false
if not IsUnitLoaded(udg_UDexUnits[i]) or IsUnitType(udg_CargoTransportUnit[i], UNIT_TYPE_DEAD) or GetUnitTypeId(udg_CargoTransportUnit[i]) == 0 then
set udg_CargoTransportUnit[i] = null
endif
endfunction
function UnitEventOnDeath takes nothing returns boolean
local integer pdex = udg_UDex
set udg_UDex = GetUnitUserData(GetTriggerUnit())
if udg_UDex != 0 then
set udg_IsUnitAlive[udg_UDex] = false
set udg_DeathEvent = 0.00
set udg_DeathEvent = 1.00
set udg_DeathEvent = 0.00
if udg_CargoTransportUnit[udg_UDex] != null then
call UnitEventOnUnload()
endif
endif
set udg_UDex = pdex
return false
endfunction
function UnitEventOnOrder takes nothing returns boolean
local integer pdex = udg_UDex
local unit u = GetFilterUnit()
local integer i = GetUnitUserData(u)
if i > 0 then
set udg_UDex = i
if GetUnitAbilityLevel(u, udg_DetectRemoveAbility) == 0 then
if not udg_IsUnitRemoved[i] then
set udg_IsUnitRemoved[i] = true
set udg_IsUnitAlive[i] = false
set udg_SummonerOfUnit[i] = null
//For backwards-compatibility:
set udg_DeathEvent = 0.00
set udg_DeathEvent = 3.00
set udg_DeathEvent = 0.00
//Fire deindex event for UDex:
set udg_UnitIndexEvent = 0.00
set udg_UnitIndexEvent = 2.00
set udg_UnitIndexEvent = 0.00
set udg_UDexNext[udg_UDexPrev[i]] = udg_UDexNext[i]
set udg_UDexPrev[udg_UDexNext[i]] = udg_UDexPrev[i]
// Recycle the index for later use
set udg_UDexUnits[i] = null
set udg_UDexPrev[i] = udg_UDexLastRecycled
set udg_UDexLastRecycled = i
call UnitEventDestroyGroup(i)
endif
elseif not udg_IsUnitAlive[i] then
if not IsUnitType(u, UNIT_TYPE_DEAD) then
set udg_IsUnitAlive[i] = true
set udg_DeathEvent = 0.00
set udg_DeathEvent = 2.00
set udg_DeathEvent = 0.00
set udg_IsUnitReincarnating[i] = false
endif
elseif IsUnitType(u, UNIT_TYPE_DEAD) then
if udg_IsUnitNew[i] then
//This unit was created as a corpse.
set udg_IsUnitAlive[i] = false
set udg_DeathEvent = 0.00
set udg_DeathEvent = 1.00
set udg_DeathEvent = 0.00
elseif udg_CargoTransportUnit[i] == null or not IsUnitType(u, UNIT_TYPE_HERO) then
//The unit may have just started reincarnating.
call UnitEventCheckDeathProxy(i)
endif
elseif GetUnitAbilityLevel(u, udg_DetectTransformAbility) == 0 then
call UnitAddAbility(u, udg_DetectTransformAbility)
set udg_UnitTypeEvent = 0.00
set udg_UnitTypeEvent = 1.00
set udg_UnitTypeEvent = 0.00
endif
if udg_CargoTransportUnit[i] != null and not udg_IsUnitBeingUnloaded[i] and not IsUnitLoaded(u) or IsUnitType(u, UNIT_TYPE_DEAD) then
call UnitEventOnUnload()
endif
set udg_UDex = pdex
endif
set u = null
return false
endfunction
function UnitEventOnSummon takes nothing returns boolean
local integer pdex = udg_UDex
set udg_UDex = GetUnitUserData(GetTriggerUnit())
if udg_IsUnitNew[udg_UDex] then
set udg_SummonerOfUnit[udg_UDex] = GetSummoningUnit()
set udg_UnitIndexEvent = 0.00
set udg_UnitIndexEvent = 0.50
set udg_UnitIndexEvent = 0.00
endif
set udg_UDex = pdex
return false
endfunction
function UnitEventOnLoad takes nothing returns boolean
local integer pdex = udg_UDex
local integer i = GetUnitUserData(GetTriggerUnit())
local integer index
if i != 0 then
set udg_UDex = i
if udg_CargoTransportUnit[i] != null then
call UnitEventOnUnload()
endif
//Loaded corpses do not issue an order when unloaded, therefore must
//use the enter-region event method taken from Jesus4Lyf's Transport.
if not udg_IsUnitAlive[i] then
call SetUnitX(udg_UDexUnits[i], udg_WorldMaxX)
call SetUnitY(udg_UDexUnits[i], udg_WorldMaxY)
endif
set udg_CargoTransportUnit[i] = GetTransportUnit()
set index = GetUnitUserData(udg_CargoTransportUnit[i])
if udg_CargoTransportGroup[index] == null then
set udg_CargoTransportGroup[index] = CreateGroup()
endif
call GroupAddUnit(udg_CargoTransportGroup[index], udg_UDexUnits[i])
set udg_CargoEvent = 0.00
set udg_CargoEvent = 1.00
set udg_CargoEvent = 0.00
set udg_UDex = pdex
endif
return false
endfunction
function UnitEventEnter takes nothing returns boolean
local integer pdex = udg_UDex
local integer i = udg_UDexLastRecycled
local unit u = GetFilterUnit()
if udg_UnitIndexerEnabled and GetUnitAbilityLevel(u, udg_DetectRemoveAbility) == 0 then
//Generate a unique integer index for this unit
if i == 0 then
set i = udg_UDexMax + 1
set udg_UDexMax = i
else
set udg_UDexLastRecycled = udg_UDexPrev[i]
endif
//Link index to unit, unit to index
set udg_UDexUnits[i] = u
call SetUnitUserData(u, i)
//For backwards-compatibility, add the unit to a linked list
set udg_UDexNext[i] = udg_UDexNext[0]
set udg_UDexPrev[udg_UDexNext[0]] = i
set udg_UDexNext[0] = i
set udg_UDexPrev[i] = 0
call UnitAddAbility(u, udg_DetectRemoveAbility)
call UnitMakeAbilityPermanent(u, true, udg_DetectRemoveAbility)
call UnitAddAbility(u, udg_DetectTransformAbility)
set udg_IsUnitNew[i] = true
set udg_IsUnitAlive[i] = true
set udg_IsUnitRemoved[i] = false
set udg_IsUnitReincarnating[i] = false
call UnitEventCheckDeathProxy(i)
//Fire index event for UDex
set udg_UDex = i
set udg_UnitIndexEvent = 0.00
set udg_UnitIndexEvent = 1.00
set udg_UnitIndexEvent = 0.00
else
set udg_UDex = GetUnitUserData(u)
if udg_CargoTransportUnit[udg_UDex] != null and not IsUnitLoaded(u) then
//The unit was dead, but has re-entered the map.
call UnitEventOnUnload()
endif
endif
set udg_UDex = pdex
set u = null
return false
endfunction
//===========================================================================
function UnitEventInit takes nothing returns nothing
local integer i = 16
local player p
local trigger t = CreateTrigger()
local trigger summon = CreateTrigger()
local trigger death = CreateTrigger()
local trigger load = CreateTrigger()
local region re = CreateRegion()
local rect r = GetWorldBounds()
set udg_WorldMaxX = GetRectMaxX(r)
set udg_WorldMaxY = GetRectMaxY(r)
call RegionAddRect(re, r)
call RemoveRect(r)
call UnitEventDestroyGroup(0)
call UnitEventDestroyGroup(1)
set udg_UnitIndexerEnabled = true
call TriggerRegisterEnterRegion(CreateTrigger(), re, Filter(function UnitEventEnter))
call TriggerAddCondition(summon, Filter(function UnitEventOnSummon))
call TriggerAddCondition(death, Filter(function UnitEventOnDeath))
call TriggerAddCondition(load, Filter(function UnitEventOnLoad))
loop
set i = i - 1
set p = Player(i)
call SetPlayerAbilityAvailable(p, udg_DetectRemoveAbility, false)
call SetPlayerAbilityAvailable(p, udg_DetectTransformAbility, false)
call TriggerRegisterPlayerUnitEvent(t, p, EVENT_PLAYER_UNIT_ISSUED_ORDER, Filter(function UnitEventOnOrder))
call TriggerRegisterPlayerUnitEvent(summon, p, EVENT_PLAYER_UNIT_SUMMON, null)
call TriggerRegisterPlayerUnitEvent(death, p, EVENT_PLAYER_UNIT_DEATH, null)
call TriggerRegisterPlayerUnitEvent(load, p, EVENT_PLAYER_UNIT_LOADED, null)
call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, p, Filter(function UnitEventEnter))
exitwhen i == 0
endloop
set summon = null
set death = null
set load = null
set re = null
set p = null
set r = null
set t = null
set udg_UnitIndexEvent = 3.00
set udg_UnitIndexEvent = 0.00
endfunction
function InitTrig_Unit_Event takes nothing returns nothing
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
library IsDestructableTree uses optional UnitIndexer /* v1.3.1
*************************************************************************************
* http://www.hiveworkshop.com/forums/jass-resources-412/snippet-isdestructabletree-248054/
* by BPower
* Detect whether a destructable is a tree or not.
*
***************************************************************************
*
* Credits
*
* To PitzerMike
* -----------------------
*
* for IsDestructableTree
*
*************************************************************************************
*
* Functions
*
* function IsDestructableTree takes destructable d returns boolean
*
* function IsDestructableAlive takes destructable d returns boolean
*
* function IsDestructableDead takes destructable d returns boolean
*
* function IsTreeAlive takes destructable tree returns boolean
* - May only return true for trees.
*
* function KillTree takes destructable tree returns boolean
* - May only kill trees.
*
*/
globals
private constant integer HARVESTER_UNIT_ID = 'hpea'//* human peasant
private constant integer HARVEST_ABILITY = 'Ahrl'//* ghoul harvest
private constant integer HARVEST_ORDER_ID = 0xD0032//* harvest order ( 852018 )
private constant player NEUTRAL_PLAYER = Player(PLAYER_NEUTRAL_PASSIVE)
private unit harvester = null
endglobals
function IsDestructableTree takes destructable d returns boolean
//* 851973 is the order id for stunned, it will interrupt the preceding harvest order.
return (IssueTargetOrderById(harvester, HARVEST_ORDER_ID, d)) and (IssueImmediateOrderById(harvester, 851973))
endfunction
function IsDestructableDead takes destructable d returns boolean
return (GetWidgetLife(d) <= 0.405)
endfunction
function IsDestructableAlive takes destructable d returns boolean
return (GetWidgetLife(d) > .405)
endfunction
function IsTreeAlive takes destructable tree returns boolean
return IsDestructableAlive(tree) and IsDestructableTree(tree)
endfunction
function KillTree takes destructable tree returns boolean
if (IsTreeAlive(tree)) then
call KillDestructable(tree)
return true
endif
return false
endfunction
private function Init takes nothing returns nothing
static if LIBRARY_UnitIndexer then//* You may adapt this to your own indexer.
set UnitIndexer.enabled = false
endif
set harvester = CreateUnit(NEUTRAL_PLAYER, HARVESTER_UNIT_ID, 0, 0, 0)
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = true
endif
call UnitAddAbility(harvester, HARVEST_ABILITY)
call UnitAddAbility(harvester, 'Aloc')
call ShowUnit(harvester, false)
endfunction
//* Seriously?
private module Inits
private static method onInit takes nothing returns nothing
call Init()
endmethod
endmodule
private struct I extends array
implement Inits
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library TerrainPathability initializer Init
//******************************************************************************
//* BY: Rising_Dusk
//*
//* This script can be used to detect the type of pathing at a specific point.
//* It is valuable to do it this way because the IsTerrainPathable is very
//* counterintuitive and returns in odd ways and aren't always as you would
//* expect. This library, however, facilitates detecting those things reliably
//* and easily.
//*
//******************************************************************************
//*
//* > function IsTerrainDeepWater takes real x, real y returns boolean
//* > function IsTerrainShallowWater takes real x, real y returns boolean
//* > function IsTerrainLand takes real x, real y returns boolean
//* > function IsTerrainPlatform takes real x, real y returns boolean
//* > function IsTerrainWalkable takes real x, real y returns boolean
//*
//* These functions return true if the given point is of the type specified
//* in the function's name and false if it is not. For the IsTerrainWalkable
//* function, the MAX_RANGE constant below is the maximum deviation range from
//* the supplied coordinates that will still return true.
//*
//* The IsTerrainPlatform works for any preplaced walkable destructable. It will
//* return true over bridges, destructable ramps, elevators, and invisible
//* platforms. Walkable destructables created at runtime do not create the same
//* pathing hole as preplaced ones do, so this will return false for them. All
//* other functions except IsTerrainWalkable return false for platforms, because
//* the platform itself erases their pathing when the map is saved.
//*
//* After calling IsTerrainWalkable(x, y), the following two global variables
//* gain meaning. They return the X and Y coordinates of the nearest walkable
//* point to the specified coordinates. These will only deviate from the
//* IsTerrainWalkable function arguments if the function returned false.
//*
//* Variables that can be used from the library:
//* [real] TerrainPathability_X
//* [real] TerrainPathability_Y
//*
globals
private constant real MAX_RANGE = 10.
private constant integer DUMMY_ITEM_ID = 'wolg'
endglobals
globals
private item Item = null
private rect Find = null
private item array Hid
private integer HidMax = 0
public real X = 0.
public real Y = 0.
endglobals
function IsTerrainDeepWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
function IsTerrainShallowWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
function IsTerrainLand takes real x, real y returns boolean
return IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY)
endfunction
function IsTerrainPlatform takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
private function HideItem takes nothing returns nothing
if IsItemVisible(GetEnumItem()) then
set Hid[HidMax] = GetEnumItem()
call SetItemVisible(Hid[HidMax], false)
set HidMax = HidMax + 1
endif
endfunction
function IsTerrainWalkable takes real x, real y returns boolean
//Hide any items in the area to avoid conflicts with our item
call MoveRectTo(Find, x, y)
call EnumItemsInRect(Find ,null, function HideItem)
//Try to move the test item and get its coords
call SetItemPosition(Item, x, y) //Unhides the item
set X = GetItemX(Item)
set Y = GetItemY(Item)
static if LIBRARY_IsTerrainWalkable then
//This is for compatibility with the IsTerrainWalkable library
set IsTerrainWalkable_X = X
set IsTerrainWalkable_Y = Y
endif
call SetItemVisible(Item, false)//Hide it again
//Unhide any items hidden at the start
loop
exitwhen HidMax <= 0
set HidMax = HidMax - 1
call SetItemVisible(Hid[HidMax], true)
set Hid[HidMax] = null
endloop
//Return walkability
return (X-x)*(X-x)+(Y-y)*(Y-y) <= MAX_RANGE*MAX_RANGE and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
private function Init takes nothing returns nothing
set Find = Rect(0., 0., 128., 128.)
set Item = CreateItem(DUMMY_ITEM_ID, 0, 0)
call SetItemVisible(Item, false)
endfunction
endlibrary
//TESH.scrollpos=672
//TESH.alwaysfold=0
library KnockbackSimple initializer Init uses IsDestructableTree, TerrainPathability // by ZibiTheWand3r3r v.1.03
// Features:
// Simple to use knockback: one function call, configurable behavior (16 possible versions), supports diffrent collision sizes
// callback function, can destroy knockbacks any time, system is for ground units only
// *****************************
// Requires:
// library IsDestructableTree * by BPower:
// http://www.hiveworkshop.com/forums/jass-resources-412/snippet-isdestructabletree-248054/
// library TerrainPathability * by Rising_Dusk
// http://www.wc3c.net/showthread.php?t=103862
// GUI Unit Event v2.2.1.0 * by Bribe
// http://www.hiveworkshop.com/threads/gui-unit-event-v2-2-1-0.201641/
// *****************************
// How to use:
// function KnockBack takes:
// (code) onHitCode = code that will be executed when unit bounce/hits other unit/obstacles (structure, cliff, doodad, tree)
// set to "null" if not needed, (onHitCode is executed as trigger action)
// (unit) u = knockbacked unit
// (real) distance = how far unit will be moved
// (real) duration = how long knockback exists [sec]
// (real) angle = knockback angle [in radians!]
// (boolean) interruptSpells = if "true" it's interrupts orders/channeling spells on unit u, when knockback starts
// (boolean) killTrees = if "true" unit(s) will destroy trees if unit travels with >minimum speed, kb_minSpeedToKillTree
// (boolean) disableMovement = if "true" unit won't be able to move during knockback, it's using SetUnitPropWindow
// technique, so if you already using this in your map it may interfere. In this case set this boolean to false.
// (integer) kbType see table below, avaiable 4 types: KB_TYPE_NO_BOUNCE ,
// KB_TYPE_SLIDE , KB_TYPE_STOP_ON_OBSTACLES , KB_TYPE_NORMAL
// (integer) bounceTypeFiltr see table below, avaiable 4 filters: KB_FILTR_BOUNCE_NONE ,
// KB_FILTR_BOUNCE_ENEMY_ONLY , KB_FILTR_BOUNCE_ALLIED_ONLY , KB_FILTR_BOUNCE_ALL
// (string) effects - special effect played on unit(s) every given distance (variable effectOccursDistance),
// if null, no effect will be played
// (string) effectAttachPoint - atachment point for special effect, example: "origin"
// (real) effectOccursDistance - special effect declared above will be played every [effectOccursDistance] distance
// *****************************
// (code) onHitCode example:
// function OnHitExample takes nothing returns nothing
// avaiable global variables inside this callback function, read-only:
// (unit) kb_unit = main unit connected with this function
// (unit) kb_obstacle_unit = unit who was hit by kb_unit (if a unit was hit)
// (integer) kb_hitCount = counts all hits done by kb_unit
// (integer) kb_callback use to determine 2 'events' type: KB_HIT_OBSTACLE_UNIT or KB_HIT_THE_WALL
// KB_HIT_THE_WALL = structure or doodad or cliff or tree, if KB_HIT_OBSTACLE_UNIT it refers to kb_obstacle_unit
// don't use "waits" here
// if kb_callback == KB_HIT_OBSTACLE_UNIT and kb_hitCount == 1 then
// call DisplayTextToForce(GetPlayersAll(), GetUnitName(kb_unit) + " hits the " + GetUnitName(kb_obstacle_unit))
// endif
// endfunction
// *****************************
// knockback types / bounce types description
// kbType: KB_TYPE_NO_BOUNCE: stops on obstacles /structures/cliffs/doodads
// if code "onHitCode" is specifed then it will be executed when unit hits obstacle/unit
// kb_bounceFiltrType: KB_FILTR_BOUNCE_NONE:
// ignore all units pathing on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ENEMY_ONLY:
// ignore alied units pathing on my way, stops on first enemy unit on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALLIED_ONLY:
// ignore enemy units pathing on my way, stops on first allied unit on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALL:
// stops on first unit found on my way
// kb_type: KB_TYPE_SLIDE: bounce me on obstacles and:
// if code "onHitCode" is specifed then it will be executed when unit hits obstacle/unit
// kb_bounceFiltrType: KB_FILTR_BOUNCE_NONE:
// ignore all units pathing on my way, don't bounce me from other units, and *don't bounce any units on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ENEMY_ONLY:
// ignore all units pathing on my way, don't bounce me from other units, but bounce unit on my way- enemies only
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALLIED_ONLY:
// ignore all units pathing on my way, don't bounce me from other units, but bounce unit on my way- allied only
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALL:
// ignore all units pathing on my way, don't bounce me from other units, but bounce all units on my way
// --> if 2 knockbacked units meet, KB_TYPE_SLIDE has priority and it *may* overwrite existing knockback <---
// --> if KB_TYPE_SLIDE will bounce other units it will be done with angle 90 degrees <--
// kb_type: KB_TYPE_STOP_ON_OBSTACLES: don't bounce me on obstacles structures/cliffs/doodads/trees and:
// if code "onHitCode" is specifed then it will be executed if unit hits obstacle/unit
// kb_bounceFiltrType: KB_FILTR_BOUNCE_NONE:
// bounce me on any other unit, and don't bounce units on my way (allied and enemy)
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ENEMY_ONLY:
// ignore only allies pathing on my way, and bounce me and enemy units on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALLIED_ONLY:
// ignore only enemies pathing on my way, and bounce me and allied units on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALL:
// bounce me on other unit, and bounce all units on my way (allied and enemy)
// kb_type: KB_TYPE_NORMAL: bounce me on obstacles and:
// if code "onHitCode" is specifed then it will be executed if unit hits obstacle/unit
// kb_bounceFiltrType: KB_FILTR_BOUNCE_NONE:
// bounce me on any other unit, and don't bounce units on my way (allied and enemy)
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ENEMY_ONLY:
// ignore only allies pathing on my way, and bounce me and enemy units on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALLIED_ONLY:
// ignore only enemies pathing on my way, and bounce me and allied units on my way
// kb_bounceFiltrType: KB_FILTR_BOUNCE_ALL:
// bounce me on other unit, and bounce all units on my way (allied and enemy)
//
private function KB_FilterOutAbility takes integer abiId returns nothing
set kb_filterOutAbiInteger = kb_filterOutAbiInteger + 1
set kb_filterOutAbility[kb_filterOutAbiInteger] = abiId
endfunction
//*****************************************************************
// **************** BEGIN OF USER CONFIGURABLES **********************
private function KB_AdvancedUserConfigurables takes nothing returns nothing
// these will apply >globaly< to knockback system:
set kb_minSpeedToKillTree = 500.00 // minimum unit speed that allow to destroy tree, only positive values allowed
set kb_reduceSpeedOnHitFactor = 20.00 // allowed range: 0 ... 100
// (very high values of kb_reduceSpeedOnHitFactor may look ugly and cause unit to stop instantly)
// following settings will filter out units with abilities "ghost" "ghosts visible" and with buff "windwalk"
// so units with these abilities will not be bounced, as they already can be walked over
call KB_FilterOutAbility('Agho')
call KB_FilterOutAbility('Aeth')
call KB_FilterOutAbility('BOwk')
// you can add more abilities/buffs here like 3 above
// call KB_FilterOutAbility('YourAbiId')
endfunction
// **************** END OF USER CONFIGURABLES ************************
//*****************************************************************
globals
group kb_ug
real array kb_distance
real array kb_time
real array kb_angle
real array kb_d1
real array kb_d2
real array kb_sin
real array kb_cos
boolean array kb_killTrees
boolean array kb_interruptSpells
boolean array kb_disableMovement
integer array kb_knockbackType
integer array kb_bounceFiltrType
string array kb_effect
string array kb_effectAttachPoint
real array kb_effectOccursDistance
real array kb_lastDistanceEffect
real array kb_collision
real array kb_distanceLeft
real array kb_timeLeft
trigger array kb_trg_onHit
trigger kb_trg_loop
integer array kb_hitCounter // for callback function
integer kb_hitCount = 0 // for callback function
unit kb_unit = null // for callback function
unit kb_obstacle_unit = null // for callback function
player kb_player
rect kb_rect
group kb_group
timer kb_timer
real kb_minSpeedToKillTree = 500.00
real kb_reduceSpeedOnHitFactor = 10.00
real kb_reduceSpeedOnHit = 1.00
constant real KB_DETECT_OBSTACLE_UNIT_RADIUS = 150.00
constant real KB_INTERVAL = 0.03125
constant real KB_STEPS_PER_SEC = 1.00 / KB_INTERVAL
constant real KB_PI_DIVIDED_BY_2 = bj_PI / 2.00
constant real KB_PI_MULTIPLIED_BY_2 = bj_PI * 2.00
boolexpr array kb_filtr
constant integer KB_FILTR_BOUNCE_NONE = 0
constant integer KB_FILTR_BOUNCE_ENEMY_ONLY = 2
constant integer KB_FILTR_BOUNCE_ALLIED_ONLY = 3
constant integer KB_FILTR_BOUNCE_ALL = 4
constant integer KB_TYPE_NO_BOUNCE = 0
constant integer KB_TYPE_SLIDE = 10
constant integer KB_TYPE_STOP_ON_OBSTACLES = 20
constant integer KB_TYPE_NORMAL = 30
constant integer KB_HIT_OBSTACLE_UNIT = 101
constant integer KB_HIT_THE_WALL = 102
integer kb_callback
integer kb_filterOutAbiInteger = 0
integer array kb_filterOutAbility
endglobals
//-----------------------------------------------------------
//x, y, = centerX, centerY
//-----------------------------------------------------------
function KB_IsPointWalkableForSize takes real x, real y, real whatSize returns boolean //x, y, = centerX, centerY
if whatSize <= 16.00 then //one item check:
return IsTerrainWalkable(x, y)
endif // for larger units: 5 item checks
return IsTerrainWalkable(x, y) and IsTerrainWalkable(x+32.00, y) and IsTerrainWalkable(x-32.00, y) and IsTerrainWalkable(x, y+32.00) and IsTerrainWalkable(x, y-32.00)
endfunction
//------------------------------------------------------------
//------------------------------------------------------------
function KB_GetBounceAngle takes real angle, real x, real y, integer id returns real
local real newAngleVer1 = ( - angle )
local real newAngleVer2 = ( - bj_PI - angle ) // for negative angles
if angle>0.00 then
set newAngleVer2 = (bj_PI - angle)
endif
//++++
if KB_IsPointWalkableForSize(x+kb_d1[id] * Cos(newAngleVer1), y+kb_d1[id] * Sin(newAngleVer1), kb_collision[id]) then
return newAngleVer1
elseif KB_IsPointWalkableForSize(x+kb_d1[id] * Cos(newAngleVer2), y+kb_d1[id] * Sin(newAngleVer2), kb_collision[id]) then
return newAngleVer2
else //3rd version - reverse direction:
set newAngleVer1 = (angle + bj_PI) // for negative angle
if angle>0.00 then
set newAngleVer1 = (angle - bj_PI)
endif
endif
return newAngleVer1
endfunction
//------------------------------------------------------------
//-----------------------------x/y = obstacleUnit X/Y
function KB_GetBounceAngle90 takes real angle, real x, real y, real unitX, real unitY returns real
local real newAnglePlus = ModuloReal((angle + KB_PI_DIVIDED_BY_2), KB_PI_MULTIPLIED_BY_2) // +90
local real newAngleMinus = ModuloReal((angle - KB_PI_DIVIDED_BY_2), KB_PI_MULTIPLIED_BY_2) // -90
local real x1 = x+32.00 * Cos(newAnglePlus)
local real y1 = y+32.00 * Sin(newAnglePlus)
local real x2 = x+32.00 * Cos(newAngleMinus)
local real y2 = y+32.00 * Sin(newAngleMinus)
//compare distances
if ((x1-unitX) * (x1-unitX) + (y1-unitY) * (y1-unitY)) > ((x2-unitX) * (x2-unitX) + (y2-unitY) * (y2-unitY)) then
return newAnglePlus
endif
return newAngleMinus
endfunction
//-------------------------------------------------------------------------------
//-------------Zwiebelchen:-------------------------------------------
// The difference between GroupEnumUnitsInRange and IsUnitInRangeXY is, that the former will only enumerate units
// whose coordinate center is inside the radius.
// The IsUnitInRange natives will already return true if only a part of the unit is inside the radius.
//--------------------------------------------------------
// KB_GetUnitCollisionSize checks up to 64 unit collision size // returns values from 8 ..to.. 64
//--------------------------------------------------------
function KB_GetUnitCollisionSize takes unit u, real unitX, real unitY returns real
local real i=0.00
local real size=64.00
loop
exitwhen i==64.00
if not IsUnitInRangeXY(u, (unitX+i), unitY, 0.00) then
set size = (i-1.00)
exitwhen true
endif
set i=i+1.00
endloop
if size<8.00 then
return 8.00
endif
return size
endfunction
//------------------------------------------------------------
function IsUnitAlive takes unit u returns boolean
return not (GetUnitTypeId(u) == 0 or IsUnitType(u, UNIT_TYPE_DEAD))
endfunction
//------------------------------------------------------------
// DisableUnitMovement /* v1.0.0.1
// * Disables unit movement. They can still turn, but will stay in
// * place. It simulates an ensnare-like effect, except that it will
// * not ground units, it does not have buffs, does not interrupt
// * channeled casts and appears to have no downsides.
// * Full credits to WaterKnight for discovering this technique.
//--------------------------------------------------------------------
function DisableUnitMovement takes unit u returns nothing
call SetUnitPropWindow(u, 0)
endfunction
//--------------------------------------------------------------------
function EnableUnitMovement takes unit u returns nothing
call SetUnitPropWindow(u, GetUnitDefaultPropWindow(u) * bj_DEGTORAD)
endfunction
//------------------------------------------------------------
function KBFiltr_1 takes unit u returns boolean
local integer a=1
local integer id = GetUnitUserData(u)
local boolean isKb = IsUnitInGroup(u, kb_group) // is knockbacked?
if IsUnitAlive(u) and (not IsUnitType(u, UNIT_TYPE_FLYING)) and (not IsUnitType(u, UNIT_TYPE_STRUCTURE)) and (IsUnitVisible(u, kb_player)) then
if not (isKb and ((kb_knockbackType[id]==KB_TYPE_SLIDE) or (kb_knockbackType[id]==KB_TYPE_NO_BOUNCE and kb_bounceFiltrType[id]==KB_FILTR_BOUNCE_NONE))) then
if not (isKb and ((IsUnitAlly(u, kb_player) and kb_bounceFiltrType[id]==KB_FILTR_BOUNCE_ENEMY_ONLY) or (IsUnitEnemy(u, kb_player) and kb_bounceFiltrType[id]==KB_FILTR_BOUNCE_ALLIED_ONLY))) then
loop
exitwhen a>kb_filterOutAbiInteger
if GetUnitAbilityLevel(u, kb_filterOutAbility[a]) > 0 then
return false
endif
set a=a+1
endloop
return true
endif
endif
endif
return false
endfunction
//--------
function KBFiltr_groundNotStruc takes nothing returns boolean
return KBFiltr_1(GetFilterUnit())
endfunction
// set kb_player before confirm this 2 checks!
function KBFiltr_groundNotStrucAlliedOnly takes nothing returns boolean
return KBFiltr_1(GetFilterUnit()) and IsUnitAlly(GetFilterUnit(), kb_player)
endfunction
function KBFiltr_groundNotStrucEnemyOnly takes nothing returns boolean
return KBFiltr_1(GetFilterUnit()) and IsUnitEnemy(GetFilterUnit(), kb_player)
endfunction
//------------------------------------------------------------------------
function KB_OnRemoveFromGame takes nothing returns nothing
call GroupRemoveUnit(kb_group, udg_UDexUnits[udg_UDex])
//clean:
if kb_trg_onHit[udg_UDex] != null then
call DestroyTrigger(kb_trg_onHit[udg_UDex])
set kb_trg_onHit[udg_UDex] = null
endif
set kb_effect[udg_UDex] = null
set kb_effectAttachPoint[udg_UDex] = null
if FirstOfGroup(kb_group)==null then
call PauseTimer(kb_timer)
endif
endfunction
//----------------------------------------------------------------------------
function KB_DestroyKnockbackOnUnit takes unit u returns nothing
local integer id = GetUnitUserData(u)
call GroupRemoveUnit(kb_group, u)
if kb_trg_onHit[id] != null then
call DestroyTrigger(kb_trg_onHit[id])
set kb_trg_onHit[id] = null
endif
call EnableUnitMovement(u)
set kb_effect[id] = null
set kb_effectAttachPoint[id] = null
if FirstOfGroup(kb_group)==null then
call PauseTimer(kb_timer)
endif
endfunction
//----------------------------------------------------------------------------
function KB_DestroyAllEnum takes nothing returns nothing
call KB_DestroyKnockbackOnUnit(GetEnumUnit())
endfunction
//----------------------------
function KB_DestroyAllKnockbacks takes nothing returns nothing
call ForGroup(kb_group, function KB_DestroyAllEnum)
endfunction
//----------------------------
//=======================================================
function KB_CheckAllowedTypes takes integer kbType, integer bounceTypeFiltr returns boolean
if kbType == KB_TYPE_NO_BOUNCE or kbType == KB_TYPE_SLIDE or kbType == KB_TYPE_STOP_ON_OBSTACLES or kbType == KB_TYPE_NORMAL then
if bounceTypeFiltr == KB_FILTR_BOUNCE_NONE or bounceTypeFiltr == KB_FILTR_BOUNCE_ENEMY_ONLY or bounceTypeFiltr == KB_FILTR_BOUNCE_ALLIED_ONLY or bounceTypeFiltr == KB_FILTR_BOUNCE_ALL then
return true
endif
endif
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Knockback error: wrong integer pass to function")
return false
endfunction
//-----------------------------------------------------------------------------------------
//-----main function --------------------------------------------------------------------
function KnockBack takes code onHitCode, unit u, real distance, real duration, real angle, boolean interruptSpells, boolean killTrees, boolean disableMovement, integer kbType, integer bounceTypeFiltr, string effects, string effectAttachPoint, real effectOccursDistance returns nothing
local integer id = GetUnitUserData(u)
local integer q = R2I(duration / KB_INTERVAL) // (Number of steps)
local real x = GetUnitX(u)
local real y = GetUnitY(u)
if GetUnitDefaultMoveSpeed(u) == 0.00 or (not KB_CheckAllowedTypes(kbType, bounceTypeFiltr)) then //protection
return
endif
set kb_effect[id] = null
set kb_effectAttachPoint[id] = null
if kb_trg_onHit[id] != null then
call DestroyTrigger(kb_trg_onHit[id])
set kb_trg_onHit[id] = null
endif
if onHitCode != null then
set kb_trg_onHit[id] = CreateTrigger()
call TriggerAddAction(kb_trg_onHit[id], onHitCode)
endif
set kb_distance[id] = distance
set kb_distanceLeft[id] = distance
set kb_time[id] = duration
set kb_timeLeft[id] = duration
set kb_hitCounter[id] = 0
set kb_angle[id] = angle
set kb_sin[id] = Sin(angle)
set kb_cos[id] = Cos(angle)
set kb_d1[id] = 2 * kb_distance[id] / (q + 1) // the "bit" in "moving a unit a bit a time"
set kb_d2[id] = kb_d1[id] / q // will decrease d1 with each execution
set kb_killTrees[id] = killTrees
set kb_interruptSpells[id] = interruptSpells
set kb_disableMovement[id] = disableMovement
set kb_knockbackType[id] = kbType
set kb_bounceFiltrType[id] = bounceTypeFiltr
if kb_interruptSpells[id] then
call SetUnitPosition(u, x, y)
endif
if kb_disableMovement[id] then
call DisableUnitMovement(u)
endif
if effects != null then
set kb_effect[id] = effects
endif
set kb_effectAttachPoint[id] = effectAttachPoint
set kb_lastDistanceEffect[id] = kb_distance[id]
set kb_effectOccursDistance[id] = effectOccursDistance
set kb_collision[id] = KB_GetUnitCollisionSize(u, x, y)
if FirstOfGroup(kb_group)==null then
call TimerStart(kb_timer, KB_INTERVAL, true, null)
endif
call GroupAddUnit(kb_group, u)
endfunction
// KBLOOP part =============================================
function KB_BounceEvent takes unit u, integer id, integer eventType returns nothing
if kb_trg_onHit[id] != null then
set kb_callback = eventType // KB_HIT_OBSTACLE_UNIT or KB_HIT_THE_WALL
set kb_unit = u
set kb_hitCounter[id] = kb_hitCounter[id] + 1
set kb_hitCount = kb_hitCounter[id]
call TriggerExecute(kb_trg_onHit[id])
endif
endfunction
//------------------------------------------------------------------------------------------------
// use this for bounce from structures/cliffs/doodads ONLY:
//------------------------------------------------------------------------------------------------
function KB_BounceUnit takes unit u, integer id, real unitX, real unitY returns nothing
set kb_angle[id] = KB_GetBounceAngle(kb_angle[id], unitX, unitY, id) //change angle
set kb_sin[id] = Sin(kb_angle[id])
set kb_cos[id] = Cos(kb_angle[id])
call SetUnitX(u, unitX + kb_d1[id] * kb_cos[id])
call SetUnitY(u, unitY + kb_d1[id] * kb_sin[id])
set kb_d1[id] = kb_d1[id] * kb_reduceSpeedOnHit // reducing distance kb_d1
call KB_BounceEvent(u, id, KB_HIT_THE_WALL) //fire hit event
endfunction
//------------------------------------------------------------------------------------------------
//-this for better visual effect --
//-KB_BounceEvent is not included here inside this func -----------
function KB_BounceUnitReverseWithMinSpeed takes unit u, integer id returns nothing
local real angle = (kb_angle[id] + bj_PI)
if kb_angle[id]>0.00 then // reverse direction:
set angle = (kb_angle[id] - bj_PI)
endif // initiate new kb, so old one will be ended:
call KnockBack(null, u, 25.00, 0.30, angle, false, kb_killTrees[id], kb_disableMovement[id], KB_TYPE_SLIDE, KB_FILTR_BOUNCE_NONE, null, null, 1.00)
endfunction
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
function KB_TwoUnitsHit takes unit mainUnit, integer id, unit obstacleUnit, integer obstacleId returns nothing
local integer kb1 = kb_knockbackType[id]
local integer kb2
if IsUnitInGroup(obstacleUnit, kb_group) then
set kb2 = kb_knockbackType[obstacleId]
if kb2 == KB_TYPE_NO_BOUNCE then
set kb_obstacle_unit = obstacleUnit
call KB_BounceEvent(mainUnit, id, KB_HIT_OBSTACLE_UNIT)
set kb_obstacle_unit = mainUnit
call KB_BounceEvent(obstacleUnit, obstacleId, KB_HIT_OBSTACLE_UNIT)
if kb2 == kb1 then // both "no-bounce"
call KB_BounceUnitReverseWithMinSpeed(mainUnit, id)
call KB_BounceUnitReverseWithMinSpeed(obstacleUnit, obstacleId)
endif
elseif (kb2 == KB_TYPE_NORMAL or kb2 == KB_TYPE_STOP_ON_OBSTACLES) and (kb1 == KB_TYPE_NORMAL or kb1 == KB_TYPE_STOP_ON_OBSTACLES or kb1 == KB_TYPE_SLIDE) then
set kb_obstacle_unit = mainUnit
call KB_BounceEvent(obstacleUnit, obstacleId, KB_HIT_OBSTACLE_UNIT)
set kb_obstacle_unit = obstacleUnit
call KB_BounceEvent(mainUnit, id, KB_HIT_OBSTACLE_UNIT)
endif
else // obstacle unit *not* in kb_group:
set kb_obstacle_unit = obstacleUnit
call KB_BounceEvent(mainUnit, id, KB_HIT_OBSTACLE_UNIT)
if kb1 == KB_TYPE_NO_BOUNCE then
call KB_BounceUnitReverseWithMinSpeed(mainUnit, id)
endif
endif
endfunction
//-------------------------------------------------------------------------------
// kb_u primary unit, unitX = GetUnitX(kb_u)
// bouncePrimaryUnit - if "true" will bounce kb_u in opposite direction to new unit on way
// bounceNewUnit -if "true" will bounce new unit in opposite direction to kb_u unit
function KB_CheckUnitsAroundAndBounce takes unit kb_u, integer kb_id, real unitX, real unitY, real targetX, real targetY, integer filtrNr, boolean bouncePrimaryUnit, boolean bounceNewUnit returns boolean
local unit obst_u
local integer obst_id
local real obstX
local real obstY
local integer foundUnits=0
local real angle
local integer t
local integer b
local real Tx
local real Ty
local real c
local real newDistance
set kb_player = GetOwningPlayer(kb_u)
call GroupEnumUnitsInRange(kb_ug, targetX, targetY, KB_DETECT_OBSTACLE_UNIT_RADIUS, kb_filtr[filtrNr])
loop
set obst_u = FirstOfGroup(kb_ug)
exitwhen obst_u == null
set obstX = GetUnitX(obst_u)
set obstY = GetUnitY(obst_u)
set c = KB_GetUnitCollisionSize(obst_u, obstX, obstY)
if (obst_u != kb_u) and IsUnitInRange(obst_u, kb_u, RMaxBJ(c, kb_collision[kb_id])) then //pick bigger collision
set foundUnits = 1
set obst_id = GetUnitUserData(obst_u)
call KB_TwoUnitsHit(kb_u, kb_id, obst_u, obst_id)
// if bounce primary unit:
if bouncePrimaryUnit then
set angle = Atan2(unitY - obstY, unitX - obstX) // reverse angle
set Tx = unitX+kb_d1[kb_id] * Cos(angle)
set Ty = unitY+kb_d1[kb_id] * Sin(angle)
if KB_IsPointWalkableForSize(Tx, Ty, kb_collision[kb_id]) then
call SetUnitX(kb_u, Tx)
call SetUnitY(kb_u, Ty)
set kb_angle[kb_id] = angle //change angle
set kb_sin[kb_id] = Sin(kb_angle[kb_id])
set kb_cos[kb_id] = Cos(kb_angle[kb_id])
set kb_d1[kb_id] = kb_d1[kb_id] * kb_reduceSpeedOnHit // reducing distance kb_d1
else // not walkable:
set kb_d1[kb_id] = 0.00 // end knockback
endif
elseif kb_knockbackType[kb_id] == KB_TYPE_SLIDE then // if not bounce, then move [for slide type only]:
call SetUnitX(kb_u, targetX)
call SetUnitY(kb_u, targetY)
endif
// if bounce obstacle unit:
if bounceNewUnit then
set angle = Atan2(obstY - unitY, obstX - unitX) // reverse angle
if IsUnitInGroup(obst_u, kb_group) then
if kb_knockbackType[kb_id] == KB_TYPE_SLIDE then // hit by sliding unit, initiate new slide, slide overwrites existing one
if kb_timeLeft[kb_id] * kb_distanceLeft[kb_id] > 1.00 then //don't run very low knockbacks! <---
set b = kb_bounceFiltrType[kb_id] // new bounce filter:
if kb_bounceFiltrType[kb_id] == KB_FILTR_BOUNCE_ENEMY_ONLY then
set b = KB_FILTR_BOUNCE_ALLIED_ONLY
endif
set angle = KB_GetBounceAngle90(kb_angle[kb_id], obstX, obstY, unitX, unitY) //angle 90 degrees
if KB_IsPointWalkableForSize((obstX+kb_d1[obst_id] * Cos(angle)), (obstY+kb_d1[obst_id] * Sin(angle)), c) then
call KnockBack(null, obst_u, kb_distanceLeft[kb_id], kb_timeLeft[kb_id], angle, kb_interruptSpells[kb_id], kb_killTrees[kb_id], kb_disableMovement[kb_id], kb_knockbackType[kb_id], b, kb_effect[kb_id], kb_effectAttachPoint[kb_id], kb_effectOccursDistance[kb_id])
endif
endif
else // hit by non-sliding unit, update existing kb:
set Tx = obstX+kb_d1[obst_id] * Cos(angle)
set Ty = obstY+kb_d1[obst_id] * Sin(angle)
if KB_IsPointWalkableForSize(Tx, Ty, c) then
call SetUnitX(obst_u, Tx)
call SetUnitY(obst_u, Ty)
set kb_angle[obst_id] = angle //change angle
set kb_sin[obst_id] = Sin(kb_angle[obst_id])
set kb_cos[obst_id] = Cos(kb_angle[obst_id])
set kb_d1[obst_id] = kb_d1[obst_id] * kb_reduceSpeedOnHit // reducing distance kb_d1
endif
endif
elseif (kb_timeLeft[kb_id] * kb_distanceLeft[kb_id]) > 1.00 then //unit NOT in kb_group, initial new kb; don't run very low knockbacks! <---
set b = kb_bounceFiltrType[kb_id] // new bounce filter:
if b == KB_FILTR_BOUNCE_ENEMY_ONLY then
set b = KB_FILTR_BOUNCE_ALLIED_ONLY
endif
if kb_knockbackType[kb_id] == KB_TYPE_SLIDE then // if obstacle hits by sliding unit, change angle to 90
set angle = KB_GetBounceAngle90(kb_angle[kb_id], obstX, obstY, unitX, unitY) //angle 90 degrees
endif // now calculate new distance to get the same speed as kb_u
set newDistance = (kb_d1[kb_id] * ((I2R(R2I(kb_timeLeft[kb_id] / KB_INTERVAL)) + 1))) / 2.00
if KB_IsPointWalkableForSize((obstX+kb_d1[obst_id] * Cos(angle)), (obstY+kb_d1[obst_id] * Sin(angle)), c) then
call KnockBack(null, obst_u, newDistance, kb_timeLeft[kb_id], angle, kb_interruptSpells[kb_id], kb_killTrees[kb_id], kb_disableMovement[kb_id], kb_knockbackType[kb_id], b, kb_effect[kb_id], kb_effectAttachPoint[kb_id], kb_effectOccursDistance[kb_id])
endif
endif
endif
//bounce obstacle unit:end
endif
call GroupRemoveUnit(kb_ug, obst_u)
endloop
call GroupClear (kb_ug)
set obst_u=null
return foundUnits > 0
endfunction
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
function KB_MoveUnit takes unit u, integer id, real unitX, real unitY, real targetX, real targetY returns nothing
local boolean isWalkable = KB_IsPointWalkableForSize(targetX, targetY, kb_collision[id])
if kb_knockbackType[id] == KB_TYPE_NO_BOUNCE then // no bounce at all
if not isWalkable then
call KB_BounceEvent(u, id, KB_HIT_THE_WALL) //fire hit event, obstacle
call KB_BounceUnitReverseWithMinSpeed(u, id)
elseif kb_bounceFiltrType[id] == KB_FILTR_BOUNCE_NONE then // walkable:
call SetUnitX(u, targetX)
call SetUnitY(u, targetY)
elseif (not KB_CheckUnitsAroundAndBounce(u, id, unitX, unitY, targetX, targetY, kb_bounceFiltrType[id], false, false)) then //3 other filters:
call SetUnitX(u, targetX)
call SetUnitY(u, targetY)
endif
//---------------------------------SLIDE:-------------------------------------------------
elseif kb_knockbackType[id] == KB_TYPE_SLIDE then
if not isWalkable then
call KB_BounceUnit(u, id, unitX, unitY) //fires hit event
elseif kb_bounceFiltrType[id] == KB_FILTR_BOUNCE_NONE then
call SetUnitX(u, targetX)
call SetUnitY(u, targetY)
elseif (not KB_CheckUnitsAroundAndBounce(u, id, unitX, unitY, targetX, targetY, kb_bounceFiltrType[id], false, true)) then //3 other filters:
call SetUnitX(u, targetX)
call SetUnitY(u, targetY)
endif
//--------------------------------- KB_TYPE_NORMAL / KB_TYPE_STOP_ON_OBSTACLES -------------------
elseif kb_knockbackType[id] == KB_TYPE_NORMAL or kb_knockbackType[id] == KB_TYPE_STOP_ON_OBSTACLES then
if not isWalkable then
if kb_knockbackType[id] == KB_TYPE_NORMAL then
call KB_BounceUnit(u, id, unitX, unitY)
elseif kb_knockbackType[id] == KB_TYPE_STOP_ON_OBSTACLES then
call KB_BounceEvent(u, id, KB_HIT_THE_WALL) //fire hit event, obstacle
call KB_BounceUnitReverseWithMinSpeed(u, id)
endif
elseif (kb_bounceFiltrType[id] == KB_FILTR_BOUNCE_NONE) then //walkable:
if (not (KB_CheckUnitsAroundAndBounce(u, id, unitX, unitY, targetX, targetY, KB_FILTR_BOUNCE_ALL, true, false))) then
call SetUnitX(u, targetX)
call SetUnitY(u, targetY)
endif
elseif (not (KB_CheckUnitsAroundAndBounce(u, id, unitX, unitY, targetX, targetY, kb_bounceFiltrType[id], true, true))) then //3 other filters
call SetUnitX(u, targetX)
call SetUnitY(u, targetY)
endif
endif
endfunction
//-----------------------------------------------------------------
function KB_KillTree takes nothing returns nothing
call KillTree(GetEnumDestructable())
endfunction
//------------------------------------------------------------------
function KB_ShowEffect takes unit u, integer id returns nothing
if kb_effect[id] != null and (kb_distanceLeft[id] < (kb_lastDistanceEffect[id] - kb_effectOccursDistance[id])) then
call DestroyEffect(AddSpecialEffectTarget(kb_effect[id], u, kb_effectAttachPoint[id]))
set kb_lastDistanceEffect[id] = kb_distanceLeft[id]
endif
endfunction
//------------------------------------------------------------------
function KB_LoopEnum takes nothing returns nothing
local unit u = GetEnumUnit()
local integer id = GetUnitUserData(u)
local real unitX = GetUnitX(u)
local real unitY = GetUnitY(u)
local real targetX = unitX + kb_d1[id] * kb_cos[id]
local real targetY = unitY + kb_d1[id] * kb_sin[id]
if (not IsUnitAlive(u)) or kb_d1[id] <= 0.00 then
call KB_DestroyKnockbackOnUnit(u)
set u=null
return
endif
if kb_killTrees[id] and ((kb_d1[id]*KB_STEPS_PER_SEC) > kb_minSpeedToKillTree) then
call MoveRectTo(kb_rect, targetX, targetY)
call EnumDestructablesInRect(kb_rect, null, function KB_KillTree)
endif
call KB_ShowEffect(u, id)
call KB_MoveUnit(u, id, unitX, unitY, targetX, targetY)
set kb_d1[id] = kb_d1[id] - kb_d2[id] // decrease speed
set kb_distanceLeft[id] = kb_distanceLeft[id] - kb_d1[id] // for additional kb-ed units
set kb_timeLeft[id] = kb_timeLeft[id] - KB_INTERVAL // for additional kb-ed units
set u=null
endfunction
//--------------------------------------------------------------------------
function KB_Loop takes nothing returns boolean
call ForGroup(kb_group, function KB_LoopEnum)
return false
endfunction
//=======================================================
//=======================================================
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
set kb_ug = CreateGroup()
set kb_group = CreateGroup()
set kb_timer = CreateTimer()
set kb_rect = Rect(0.0, 0.0, 256.0, 256.0)
set kb_trg_loop = CreateTrigger()
call TriggerRegisterTimerExpireEvent(kb_trg_loop, kb_timer) //timer kb_timer expires
call TriggerAddCondition(kb_trg_loop, Condition(function KB_Loop))
//----------------------------------------------------
call KB_AdvancedUserConfigurables()
set kb_minSpeedToKillTree = RMaxBJ(kb_minSpeedToKillTree, 0.00)
if kb_reduceSpeedOnHitFactor < 0.00 then
set kb_reduceSpeedOnHitFactor = 0.00
elseif kb_reduceSpeedOnHitFactor > 100.00 then
set kb_reduceSpeedOnHitFactor = 100.00
endif
set kb_reduceSpeedOnHit = 1.00 - (kb_reduceSpeedOnHitFactor / 100.00) // for kb_d1, range: 0.00 ... 1.00
//----------------------------------------------------
set kb_filtr[KB_FILTR_BOUNCE_NONE] = Condition(function KBFiltr_groundNotStruc)
set kb_filtr[KB_FILTR_BOUNCE_ALL] = Condition(function KBFiltr_groundNotStruc)
set kb_filtr[KB_FILTR_BOUNCE_ALLIED_ONLY] = Condition(function KBFiltr_groundNotStrucAlliedOnly)
set kb_filtr[KB_FILTR_BOUNCE_ENEMY_ONLY] = Condition(function KBFiltr_groundNotStrucEnemyOnly)
call TriggerRegisterVariableEvent( t, "udg_UnitIndexEvent", EQUAL, 2.00 ) // remove unit detection
call TriggerAddAction(t, function KB_OnRemoveFromGame)
set t=null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_updateLeaderB_Actions takes nothing returns nothing
local integer i = CountUnitsInGroup(kb_group)
call LeaderboardSetItemValue(bj_lastCreatedLeaderboard, LeaderboardGetPlayerIndex(bj_lastCreatedLeaderboard, Player(0)), i)
endfunction
//===========================================================================
function InitTrig_updateLeaderB takes nothing returns nothing
set gg_trg_updateLeaderB = CreateTrigger( )
call TriggerRegisterTimerEventPeriodic( gg_trg_updateLeaderB, 0.10 )
call TriggerAddAction( gg_trg_updateLeaderB, function Trig_updateLeaderB_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_001_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A002'
endfunction
//-----------------------------------------------------------------------
function OnBounce1 takes nothing returns nothing
local string s = I2S(kb_hitCount)
// avaiable vars inside this callback function, read-only:
// (unit) kb_unit = main unit connected with this function
// (integer) kb_hitCount counts all hits
// (unit) kb_obstacle_unit unit who was hit by kb_unit
// (integer) kb_callback use to determine event type: KB_HIT_OBSTACLE_UNIT or KB_HIT_THE_WALL
// KB_HIT_THE_WALL = structure or doodad or cliff or tree
if kb_callback == KB_HIT_OBSTACLE_UNIT then
call DisplayTextToForce(GetPlayersAll(), "[NORMAL] " + GetUnitName(kb_unit) + " hits the " + GetUnitName(kb_obstacle_unit) + " (" + s + ")")
call UnitDamageTargetBJ( kb_unit, kb_obstacle_unit, 50, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
elseif kb_callback == KB_HIT_THE_WALL then
call DisplayTextToForce(GetPlayersAll(), "[NORMAL] " + GetUnitName(kb_unit) + " hits the wall " + "(" + s + ")")
endif
set s=null
endfunction
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 2.00
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = true
local boolean killTrees = true
local boolean disableMovement = false
local integer kbType = KB_TYPE_NORMAL
local integer kbBounce = KB_FILTR_BOUNCE_NONE
local string efect = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 40.00
call KnockBack(function OnBounce1, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testNormal1 takes nothing returns nothing
set gg_trg_testNormal1 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testNormal1, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testNormal1, Condition( function Trig_Untitled_Trigger_001_Conditions ) )
call TriggerAddAction( gg_trg_testNormal1, function Trig_Untitled_Trigger_001_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_001_Conditions2 takes nothing returns boolean
return GetSpellAbilityId() == 'A00C'
endfunction
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_001_Actions2 takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 2.00
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = true
local boolean killTrees = true
local boolean disableMovement = false
local integer kbType = KB_TYPE_NORMAL
local integer kbBounce = KB_FILTR_BOUNCE_ENEMY_ONLY
local string efect = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 40.00
call KnockBack(function OnBounce1, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testNormal2 takes nothing returns nothing
set gg_trg_testNormal2 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testNormal2, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testNormal2, Condition( function Trig_Untitled_Trigger_001_Conditions2 ) )
call TriggerAddAction( gg_trg_testNormal2, function Trig_Untitled_Trigger_001_Actions2 )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_001_Conditions3 takes nothing returns boolean
return GetSpellAbilityId() == 'A00D'
endfunction
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_001_Actions3 takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 2.00
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = true
local boolean killTrees = true
local boolean disableMovement = false
local integer kbType = KB_TYPE_NORMAL
local integer kbBounce = KB_FILTR_BOUNCE_ALLIED_ONLY
local string efect = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 40.00
call KnockBack(function OnBounce1, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testNormal3 takes nothing returns nothing
set gg_trg_testNormal3 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testNormal3, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testNormal3, Condition( function Trig_Untitled_Trigger_001_Conditions3 ) )
call TriggerAddAction( gg_trg_testNormal3, function Trig_Untitled_Trigger_001_Actions3 )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_001_Conditions4 takes nothing returns boolean
return GetSpellAbilityId() == 'A00E'
endfunction
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_001_Actions4 takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 2.00
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = true
local boolean killTrees = true
local boolean disableMovement = false
local integer kbType = KB_TYPE_NORMAL
local integer kbBounce = KB_FILTR_BOUNCE_ALL
local string efect = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 40.00
call KnockBack(function OnBounce1, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testNormal4 takes nothing returns nothing
set gg_trg_testNormal4 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testNormal4, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testNormal4, Condition( function Trig_Untitled_Trigger_001_Conditions4 ) )
call TriggerAddAction( gg_trg_testNormal4, function Trig_Untitled_Trigger_001_Actions4 )
endfunction
//TESH.scrollpos=3
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_002_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A003'
endfunction
//-----------------------------------------------------------------------
function OnBounce2 takes nothing returns nothing
local string s = I2S(kb_hitCount)
if kb_callback == KB_HIT_OBSTACLE_UNIT then
call DisplayTextToForce(GetPlayersAll(), "[SLIDE] " + GetUnitName(kb_unit) + " hits the " + GetUnitName(kb_obstacle_unit) + " (" + s + ")")
elseif kb_callback == KB_HIT_THE_WALL then
call DisplayTextToForce(GetPlayersAll(), "[SLIDE] " + GetUnitName(kb_unit) + " hits the wall " + "(" + s + ")")
endif
set s=null
endfunction
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_002_Actions takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 1.50
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = false
local boolean killTrees = true
local boolean disableMovement = true
local integer kbType = KB_TYPE_SLIDE
local integer kbBounce = KB_FILTR_BOUNCE_NONE
local string efect = "Abilities\\Weapons\\FaerieDragonMissile\\FaerieDragonMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 20.00
call KnockBack(function OnBounce2, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testSlide1 takes nothing returns nothing
set gg_trg_testSlide1 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testSlide1, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testSlide1, Condition( function Trig_Untitled_Trigger_002_Conditions ) )
call TriggerAddAction( gg_trg_testSlide1, function Trig_Untitled_Trigger_002_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_002_Conditions2 takes nothing returns boolean
return GetSpellAbilityId() == 'A009'
endfunction
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_002_Actions2 takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 1.50
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = false
local boolean killTrees = true
local boolean disableMovement = true
local integer kbType = KB_TYPE_SLIDE
local integer kbBounce = KB_FILTR_BOUNCE_ENEMY_ONLY
local string efect = "Abilities\\Weapons\\FaerieDragonMissile\\FaerieDragonMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 20.00
call KnockBack(function OnBounce2, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testSlide2 takes nothing returns nothing
set gg_trg_testSlide2 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testSlide2, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testSlide2, Condition( function Trig_Untitled_Trigger_002_Conditions2 ) )
call TriggerAddAction( gg_trg_testSlide2, function Trig_Untitled_Trigger_002_Actions2 )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_002_Conditions3 takes nothing returns boolean
return GetSpellAbilityId() == 'A00A'
endfunction
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_002_Actions3 takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 1.50
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = false
local boolean killTrees = true
local boolean disableMovement = true
local integer kbType = KB_TYPE_SLIDE
local integer kbBounce = KB_FILTR_BOUNCE_ALLIED_ONLY
local string efect = "Abilities\\Weapons\\FaerieDragonMissile\\FaerieDragonMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 20.00
call KnockBack(function OnBounce2, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testSlide3 takes nothing returns nothing
set gg_trg_testSlide3 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testSlide3, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testSlide3, Condition( function Trig_Untitled_Trigger_002_Conditions3 ) )
call TriggerAddAction( gg_trg_testSlide3, function Trig_Untitled_Trigger_002_Actions3 )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_002_Conditions4 takes nothing returns boolean
return GetSpellAbilityId() == 'A00B'
endfunction
//-----------------------------------------------------------------------
function OnBounce2_1 takes nothing returns nothing
local string s = I2S(kb_hitCount)
if kb_callback == KB_HIT_OBSTACLE_UNIT then
call DisplayTextToForce(GetPlayersAll(), "[SLIDE] " + GetUnitName(kb_unit) + " hits the " + GetUnitName(kb_obstacle_unit) + " (" + s + ")")
elseif kb_callback == KB_HIT_THE_WALL then
call DisplayTextToForce(GetPlayersAll(), "[SLIDE] " + GetUnitName(kb_unit) + " hits the wall " + "(" + s + ")")
endif
set s=null
endfunction
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_002_Actions4 takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 1.50
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = false
local boolean killTrees = true
local boolean disableMovement = true
local integer kbType = KB_TYPE_SLIDE
local integer kbBounce = KB_FILTR_BOUNCE_ALL
local string efect = "Abilities\\Weapons\\FaerieDragonMissile\\FaerieDragonMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 20.00
call KnockBack(function OnBounce2_1, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testSlide4 takes nothing returns nothing
set gg_trg_testSlide4 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testSlide4, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testSlide4, Condition( function Trig_Untitled_Trigger_002_Conditions4 ) )
call TriggerAddAction( gg_trg_testSlide4, function Trig_Untitled_Trigger_002_Actions4 )
endfunction
//TESH.scrollpos=14
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_004_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A004'
endfunction
//-----------------------------------------------------------------------
function OnBounce4 takes nothing returns nothing
local string s = I2S(kb_hitCount)
if kb_callback == KB_HIT_OBSTACLE_UNIT then
call DisplayTextToForce(GetPlayersAll(), "[NO BOUNCE] " + GetUnitName(kb_unit) + " hits the " + GetUnitName(kb_obstacle_unit) + " (" + s + ")")
elseif kb_callback == KB_HIT_THE_WALL then
call DisplayTextToForce(GetPlayersAll(), "[NO BOUNCE] " + GetUnitName(kb_unit) + " hits the wall " + "(" + s + ")")
endif
set s=null
endfunction
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_004_Actions takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 1.00
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = true
local boolean killTrees = true
local boolean disableMovement = true
local integer kbType = KB_TYPE_NO_BOUNCE
local integer kbBounce = KB_FILTR_BOUNCE_NONE
local string efect = "Abilities\\Weapons\\BansheeMissile\\BansheeMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 15.00
call KnockBack(function OnBounce4, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testNoBounce1 takes nothing returns nothing
set gg_trg_testNoBounce1 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testNoBounce1, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testNoBounce1, Condition( function Trig_Untitled_Trigger_004_Conditions ) )
call TriggerAddAction( gg_trg_testNoBounce1, function Trig_Untitled_Trigger_004_Actions )
endfunction
//TESH.scrollpos=6
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_004_Conditions2 takes nothing returns boolean
return GetSpellAbilityId() == 'A006'
endfunction
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_004_Actions2 takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 1.00
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = true
local boolean killTrees = true
local boolean disableMovement = true
local integer kbType = KB_TYPE_NO_BOUNCE
local integer kbBounce = KB_FILTR_BOUNCE_ENEMY_ONLY
local string efect = "Abilities\\Weapons\\BansheeMissile\\BansheeMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 15.00
call KnockBack(function OnBounce4, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testNoBounce2 takes nothing returns nothing
set gg_trg_testNoBounce2 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testNoBounce2, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testNoBounce2, Condition( function Trig_Untitled_Trigger_004_Conditions2 ) )
call TriggerAddAction( gg_trg_testNoBounce2, function Trig_Untitled_Trigger_004_Actions2 )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_004_Conditions3 takes nothing returns boolean
return GetSpellAbilityId() == 'A007'
endfunction
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_004_Actions3 takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 1.00
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = true
local boolean killTrees = true
local boolean disableMovement = true
local integer kbType = KB_TYPE_NO_BOUNCE
local integer kbBounce = KB_FILTR_BOUNCE_ALLIED_ONLY
local string efect = "Abilities\\Weapons\\BansheeMissile\\BansheeMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 15.00
call KnockBack(function OnBounce4, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testNoBounce3 takes nothing returns nothing
set gg_trg_testNoBounce3 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testNoBounce3, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testNoBounce3, Condition( function Trig_Untitled_Trigger_004_Conditions3 ) )
call TriggerAddAction( gg_trg_testNoBounce3, function Trig_Untitled_Trigger_004_Actions3 )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_004_Conditions4 takes nothing returns boolean
return GetSpellAbilityId() == 'A008'
endfunction
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_004_Actions4 takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 1.00
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = true
local boolean killTrees = true
local boolean disableMovement = true
local integer kbType = KB_TYPE_NO_BOUNCE
local integer kbBounce = KB_FILTR_BOUNCE_ALL
local string efect = "Abilities\\Weapons\\BansheeMissile\\BansheeMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 15.00
call KnockBack(function OnBounce4, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testNoBounce4 takes nothing returns nothing
set gg_trg_testNoBounce4 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testNoBounce4, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testNoBounce4, Condition( function Trig_Untitled_Trigger_004_Conditions4 ) )
call TriggerAddAction( gg_trg_testNoBounce4, function Trig_Untitled_Trigger_004_Actions4 )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_005_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A005'
endfunction
//-----------------------------------------------------------------------
function OnBounce5 takes nothing returns nothing
local string s = I2S(kb_hitCount)
if kb_callback == KB_HIT_OBSTACLE_UNIT then
call DisplayTextToForce(GetPlayersAll(), "[STOP OBST] " + GetUnitName(kb_unit) + " hits the " + GetUnitName(kb_obstacle_unit) + " (" + s + ")")
elseif kb_callback == KB_HIT_THE_WALL then
call DisplayTextToForce(GetPlayersAll(), "[STOP OBST] " + GetUnitName(kb_unit) + " hits the wall " + "(" + s + ")")
call UnitDamageTargetBJ( kb_unit, kb_unit, 50, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
endif
set s=null
endfunction
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_005_Actions takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 1.50
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = true
local boolean killTrees = true
local boolean disableMovement = true
local integer kbType = KB_TYPE_STOP_ON_OBSTACLES
local integer kbBounce = KB_FILTR_BOUNCE_NONE
local string efect = "Abilities\\Weapons\\DragonHawkMissile\\DragonHawkMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 80.00
call KnockBack(function OnBounce5, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testStopOnOstacles1 takes nothing returns nothing
set gg_trg_testStopOnOstacles1 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testStopOnOstacles1, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testStopOnOstacles1, Condition( function Trig_Untitled_Trigger_005_Conditions ) )
call TriggerAddAction( gg_trg_testStopOnOstacles1, function Trig_Untitled_Trigger_005_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_005_Conditions2 takes nothing returns boolean
return GetSpellAbilityId() == 'A00F'
endfunction
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_005_Actions2 takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 1.50
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = true
local boolean killTrees = true
local boolean disableMovement = true
local integer kbType = KB_TYPE_STOP_ON_OBSTACLES
local integer kbBounce = KB_FILTR_BOUNCE_ENEMY_ONLY
local string efect = "Abilities\\Weapons\\DragonHawkMissile\\DragonHawkMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 80.00
call KnockBack(function OnBounce5, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testStopOnOstacles2 takes nothing returns nothing
set gg_trg_testStopOnOstacles2 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testStopOnOstacles2, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testStopOnOstacles2, Condition( function Trig_Untitled_Trigger_005_Conditions2 ) )
call TriggerAddAction( gg_trg_testStopOnOstacles2, function Trig_Untitled_Trigger_005_Actions2 )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_005_Conditions3 takes nothing returns boolean
return GetSpellAbilityId() == 'A00G'
endfunction
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_005_Actions3 takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 1.50
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = true
local boolean killTrees = true
local boolean disableMovement = true
local integer kbType = KB_TYPE_STOP_ON_OBSTACLES
local integer kbBounce = KB_FILTR_BOUNCE_ALLIED_ONLY
local string efect = "Abilities\\Weapons\\DragonHawkMissile\\DragonHawkMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 80.00
call KnockBack(function OnBounce5, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testStopOnOstacles3 takes nothing returns nothing
set gg_trg_testStopOnOstacles3 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testStopOnOstacles3, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testStopOnOstacles3, Condition( function Trig_Untitled_Trigger_005_Conditions3 ) )
call TriggerAddAction( gg_trg_testStopOnOstacles3, function Trig_Untitled_Trigger_005_Actions3 )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Untitled_Trigger_005_Conditions4 takes nothing returns boolean
return GetSpellAbilityId() == 'A00H'
endfunction
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
function Trig_Untitled_Trigger_005_Actions4 takes nothing returns nothing
local real Tx = GetSpellTargetX()
local real Ty = GetSpellTargetY()
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real distance = (SquareRoot((Tx - x) * (Tx - x) + (Ty - y) * (Ty - y)))
local real time = 1.50
local real angle = Atan2(Ty - y, Tx - x)
local boolean interruptSpells = true
local boolean killTrees = true
local boolean disableMovement = true
local integer kbType = KB_TYPE_STOP_ON_OBSTACLES
local integer kbBounce = KB_FILTR_BOUNCE_ALL
local string efect = "Abilities\\Weapons\\DragonHawkMissile\\DragonHawkMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 80.00
call KnockBack(function OnBounce5, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
endfunction
//===========================================================================
function InitTrig_testStopOnOstacles4 takes nothing returns nothing
set gg_trg_testStopOnOstacles4 = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_testStopOnOstacles4, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_testStopOnOstacles4, Condition( function Trig_Untitled_Trigger_005_Conditions4 ) )
call TriggerAddAction( gg_trg_testStopOnOstacles4, function Trig_Untitled_Trigger_005_Actions4 )
endfunction
//TESH.scrollpos=9
//TESH.alwaysfold=0
function Trig_tower_Cond takes nothing returns boolean
return GetSpellAbilityId() == 'A00I'
endfunction
//-----------------------------------------------------------------------
function OnBouncetower takes nothing returns nothing
if kb_hitCount==1 and kb_callback == KB_HIT_OBSTACLE_UNIT then
call UnitDamageTargetBJ( kb_unit, kb_obstacle_unit, 50, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
endif
endfunction
//-----------------------------------------------------------------------
function Trig_tower_Actions takes nothing returns nothing
local unit tower = GetTriggerUnit()
local real x = GetUnitX(tower)
local real y = GetUnitY(tower)
local real distance = 4000.00
local real time = 4.00
local unit u
local real angle
local boolean interruptSpells = true
local boolean killTrees = true
local boolean disableMovement = true
local integer kbType = KB_TYPE_NORMAL
local integer kbBounce = KB_FILTR_BOUNCE_ALL
local string efect = "Abilities\\Weapons\\DragonHawkMissile\\DragonHawkMissile.mdl"
local string efectPoint = "origin"
local real efectDistance = 80.00
local group g = CreateGroup()
call GroupEnumUnitsInRange(g, x, y, 400.00, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
set angle = Atan2(GetUnitY(u) - y, GetUnitX(u) - x)
call KnockBack(function OnBouncetower, u, distance, time, angle, interruptSpells, killTrees, disableMovement, kbType, kbBounce, efect, efectPoint, efectDistance)
call GroupRemoveUnit(g, u)
endloop
call GroupClear (g)
call DestroyGroup(g)
set g=null
endfunction
//===========================================================================
//===========================================================================
function InitTrig_tower takes nothing returns nothing
set gg_trg_tower = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_tower, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_tower, Condition( function Trig_tower_Cond ) )
call TriggerAddAction( gg_trg_tower, function Trig_tower_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_DestroyKB_Actions takes nothing returns nothing
call KB_DestroyAllKnockbacks()
call DisplayTextToForce(GetPlayersAll(), "all knockbacks destroyed")
endfunction
//===========================================================================
function InitTrig_DestroyKB takes nothing returns nothing
set gg_trg_DestroyKB = CreateTrigger( )
call TriggerRegisterPlayerEventEndCinematic( gg_trg_DestroyKB, Player(0) )
call TriggerAddAction( gg_trg_DestroyKB, function Trig_DestroyKB_Actions )
endfunction