//TESH.scrollpos=18
//TESH.alwaysfold=0
scope RESET initializer init
globals
private constant timer Tim = CreateTimer()
private constant group unitGroup = CreateGroup()
private boolean Power = false
private constant real interval = 0.03125
endglobals
private function unitDies takes nothing returns nothing
local unit u = GetTriggerUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
call SetUnitExploded(u, true)
call KillUnit(u)
call TriggerSleepAction(1)
set u = CreateUnit(GetTriggerPlayer(), GetUnitTypeId(u), x, y, 0)
call UnitRemoveAbility(u, 'Aatk')
endfunction
private function Timer takes nothing returns nothing
local unit j
call GroupEnumUnitsInRect(unitGroup, bj_mapInitialPlayableArea, null)
loop
set j = FirstOfGroup(unitGroup)
exitwhen j == null
call GroupRemoveUnit(unitGroup, j)
if GetOwningPlayer(j) == Player(0) then
call UnitResetCooldown(j)
//call SetUnitState(j, UNIT_STATE_LIFE, GetUnitState(j, UNIT_STATE_MAX_LIFE))
call SetUnitState(j, UNIT_STATE_MANA, GetUnitState(j, UNIT_STATE_MAX_MANA))
endif
endloop
endfunction
private function run takes nothing returns nothing
if not Power then
call TimerStart(Tim, interval, true, function Timer)
call DisplayTimedTextToPlayer(Player(0), 0, 0, 10, "WTF mode now is on!")
set Power = true
else
call PauseTimer(Tim)
call DisplayTimedTextToPlayer(Player(0), 0, 0, 10, "WTF mode now is off!")
set Power = false
endif
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local unit j
local integer index = 0
call TriggerRegisterPlayerChatEvent(t, Player(0), "-wtf", true )
call TriggerAddAction(t, function run)
set t = CreateTrigger()
loop
call TriggerRegisterPlayerUnitEvent(t, Player(index), EVENT_PLAYER_UNIT_DEATH, null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddAction(t, function unitDies)
call GroupEnumUnitsInRect(unitGroup, bj_mapInitialPlayableArea, null)
loop
set j = FirstOfGroup(unitGroup)
exitwhen j == null
call GroupRemoveUnit(unitGroup, j)
if GetOwningPlayer(j) == Player(0) then
else
call UnitRemoveAbility(j, 'Aatk')
endif
endloop
call FogModifierStart(CreateFogModifierRect(Player(0), FOG_OF_WAR_VISIBLE, bj_mapInitialPlayableArea, true, false))
call DisplayTimedTextToPlayer(Player(0), 0, 0, 10, "Fan of Toxic Knives made by KhaosMachine
If you want to enable/disable WTF mode type '-wtf' without the quotes!")
set t = null
endfunction
endscope
Name | Type | is_array | initial_value |
_pDistance | real | No | |
_pHeight | real | No | |
_pPos | real | No | |
_pReal | real | No | |
_pX | real | No | |
Parabola1_Distance | real | No | |
Parabola1_MaxHeight | real | No | |
Parabola1_Start | location | No | |
Parabola1_Unit | unit | Yes | |
Parabola2_Distance | real | No | |
Parabola2_MaxHeight | real | No | |
Parabola2_Start | location | No | |
Parabola2_Unit | unit | Yes | |
TempPoint | location | No |
//TESH.scrollpos=37
//TESH.alwaysfold=0
/*
Rain of Shards v1.1 MADE BY 'KhaosMachine'
IF YOU WANT TO IMPORT THIS SPELL INTO YOUR MAP YOU HAVE TO COPY THE NEXT THINGS:
*********************************************************************************
TRIGGER EDITOR:
FOLDERS: NONE
TRIGGERS: Rain of Shards
OBJECT EDITOR:
UNITS: Dummy ('u000') (Set the model of this unit to the dummy imported model)
ABILITIES: Rain Of Shards ('A000')
Rain Of Shards ('A001')
IMPORT MANAGER:
dummy.mdx | Model | 34 | war3mapImported\dummy.mdx
THEN YOU HAVE TO CONFIGURE THE SPELL:
OBVIOUSLY THINGS:
ABILITY_ID = RAWCODE OF THE SPELL
DUMMY_ID = RAWCODE OF THE DUMMY
********************************************************************************
UPDATES:
©Version 1.1:
-Added a semi-parabolas system for the arrow
-Changed the models of the arrow and the explosion
-Now the arrow damages all touched units in his way
©Version 1.0:
-First release
********************************************************************************
*/
scope rainOfShards initializer init
/*************************************************************
|*** ***|
|** **|
|* *|
|====> ¡¡¡START OF THE CONFIGURATION!!! <====|
|* *|
|** **|
|*** ***|
|************************************************************/
globals
private constant integer ABILITY_ID = 'A000'//ABILITY RAWCODE
private constant integer SLOW_ABILITY_ID = 'A001'//SLOW ABILITY RAWCODE
private constant string SLOW_ABILITY_ORDER = "slow"//SLOW ABILITY ORDER STRING
private constant integer DUMMY_ID = 'u000'//DUMMY RAWCODE
private constant string MISSILE_MODEL = "Abilities\\Weapons\\LichMissile\\LichMissile.mdl"//MISSILE MODEL STRING
private constant string DEAL_MODEL = "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathMissile.mdl"//DAMAGE POINT MODEL STRING
private constant real MISSILE_SCALE = 1.3//MISSILE SCALE
private constant real MISSILE_HEIGHT = 120//MISSILE HEIGHT
private constant real DM_SCALE = 1.4//DAMAGE POINT SPECIAL EFFECT SCALE
private constant integer ATTRIBUTE = 2//1 = STRENGHT 2 = AGILITY 3 = INTELLIGENCE
private constant boolean ADD_BONUSES = true//ADD BONUSES IF TRUE, OR NOT IF FALSE
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL//ATTACK TYPE
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL//DAMAGE TYPE
private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS//WEAPON TYPE
private constant string ANIMATION_NAME = "attack"//ANIMATION OF THE UNIT WHEN MAKE THE ARROW
private constant real ANIMATION_SPEED = 4//ANIMATION SPEED OF THE CASTER
private constant boolean DAMAGE_WHEN_IMPACT = true//TRUE = DAMAGE WHEN THE MISSILE IMPACTS (DAMAGE ON MOVEMENT + THIS)
private real SPEED = 2200//SPEED OF THE MISSILE
private real FPS = 60//FRAMES PER SECOND
endglobals
private function MISSILES takes integer level returns integer
return 20//COUNT OF ARROWS
endfunction
private function INTERVAL_PER_MISSILE takes integer level returns real
return .08//TIME WAIT PER MISSILE
endfunction
private function ATTRIBUTE_MULTIPLIER takes integer level returns real
return .05 + .04 * level//ATTRIBUTE MULTIPLIER
endfunction
private function AREA_OF_EFFECT takes integer level returns real
return 75. + 25. * level//AREA OF EFFECT OF THE ABILITY
endfunction
private function EXPLOSION_AREA_OF_EFFECT takes integer level returns real
return 150. + 30. * level//AREA OF EFFECT WHEN THE MISSILE EXPLODES
endfunction
private function MIN_DISTANCE takes integer level returns real
return 200.
endfunction
private function MAX_ANGLE takes nothing returns real
return 15.
endfunction
private function ANGLE_FACTOR takes nothing returns real
return 10.
endfunction
/*************************************************************
|*** ***|
|** **|
|* *|
|====> ¡¡¡END OF THE CONFIGURATION!!! <====|
|* *|
|** **|
|*** ***|
|************************************************************/
private struct rOSRun1
unit caster
integer level
integer missiles
real interval
real x
real y
real angle
boolean changeAngle
endstruct
private struct rOSRun2
unit caster
integer level
unit missile
real angle
real maxDis
real currentDis
effect fx
group g
endstruct
globals
private constant timer TIMER = CreateTimer()
private constant timer TIMER2 = CreateTimer()
private rOSRun1 array ARRAY
private integer TOTAL = 0
private rOSRun2 array ARRAY2
private integer TOTAL2 = 0
private constant player PLAYER = Player(PLAYER_NEUTRAL_AGGRESSIVE)
private constant group UNIT_GROUP = CreateGroup()
endglobals
private function missileAction takes nothing returns nothing
local rOSRun2 D
local boolean DESTROY_DATA
local unit j
local unit d
local integer i = 0
local real DAMAGE
local real x
local real y
loop
exitwhen i >= TOTAL2
set D = ARRAY2[i]
set x = GetUnitX(D.missile)
set y = GetUnitY(D.missile)
call GroupEnumUnitsInRange(UNIT_GROUP, x, y, EXPLOSION_AREA_OF_EFFECT(D.level), null)
loop
set j = FirstOfGroup(UNIT_GROUP)
exitwhen j == null
call GroupRemoveUnit(UNIT_GROUP, j)
if not IsUnitType(j, UNIT_TYPE_DEAD) and not IsUnitType(j, UNIT_TYPE_STRUCTURE) and not IsUnitType(j, UNIT_TYPE_MAGIC_IMMUNE) and IsUnitEnemy(j, GetOwningPlayer(D.caster)) and not IsUnitInGroup(j, D.g) then
if ATTRIBUTE == 1 then
set DAMAGE = GetHeroStr(D.caster, ADD_BONUSES)
elseif ATTRIBUTE == 2 then
set DAMAGE = GetHeroAgi(D.caster, ADD_BONUSES)
else
set DAMAGE = GetHeroInt(D.caster, ADD_BONUSES)
endif
call UnitDamageTarget(D.caster, j, DAMAGE, true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call GroupAddUnit(D.g, j)
set d = CreateUnit(GetOwningPlayer(D.caster), DUMMY_ID, GetUnitX(j), GetUnitY(j), 0)
call UnitAddAbility(d, SLOW_ABILITY_ID)
call SetUnitAbilityLevel(d, SLOW_ABILITY_ID, D.level)
call IssueTargetOrder(d, SLOW_ABILITY_ORDER, j)
call UnitApplyTimedLife(d, 'BTLF', .5)
endif
endloop
call SetUnitPosition(D.missile, x + SPEED * Cos(D.angle * bj_DEGTORAD), y + SPEED * Sin(D.angle * bj_DEGTORAD))
call SetUnitFlyHeight(D.missile, (((D.currentDis + D.maxDis) * (D.currentDis - D.maxDis)) * ((-1.00 * MISSILE_HEIGHT) / (D.maxDis * D.maxDis))), 0)
set DESTROY_DATA = D.currentDis >= D.maxDis
set D.currentDis = D.currentDis + SPEED
if DESTROY_DATA then
set j = CreateUnit(PLAYER, DUMMY_ID, x, y, 0)
call SetUnitScale(j, DM_SCALE, DM_SCALE, DM_SCALE)
call DestroyEffect(AddSpecialEffectTarget(DEAL_MODEL, j, "origin"))
call UnitApplyTimedLife(j, 'BTLF', 1)
call GroupEnumUnitsInRange(UNIT_GROUP, x, y, AREA_OF_EFFECT(D.level), null)
loop
set j = FirstOfGroup(UNIT_GROUP)
exitwhen j == null
call GroupRemoveUnit(UNIT_GROUP, j)
if DAMAGE_WHEN_IMPACT and not IsUnitType(j, UNIT_TYPE_DEAD) and not IsUnitType(j, UNIT_TYPE_STRUCTURE) and not IsUnitType(j, UNIT_TYPE_MAGIC_IMMUNE) and IsUnitEnemy(j, GetOwningPlayer(D.caster)) then
if ATTRIBUTE == 1 then
set DAMAGE = GetHeroStr(D.caster, ADD_BONUSES)
elseif ATTRIBUTE == 2 then
set DAMAGE = GetHeroAgi(D.caster, ADD_BONUSES)
else
set DAMAGE = GetHeroInt(D.caster, ADD_BONUSES)
endif
call UnitDamageTarget(D.caster, j, DAMAGE, true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
set d = CreateUnit(GetOwningPlayer(D.caster), DUMMY_ID, GetUnitX(j), GetUnitY(j), 0)
call UnitAddAbility(d, SLOW_ABILITY_ID)
call SetUnitAbilityLevel(d, SLOW_ABILITY_ID, D.level)
call IssueTargetOrder(d, SLOW_ABILITY_ORDER, j)
call UnitApplyTimedLife(d, 'BTLF', .5)
endif
endloop
call DestroyEffect(D.fx)
call UnitApplyTimedLife(D.missile, 'BTLF', 1)
set ARRAY2[i] = ARRAY2[TOTAL2 - 1]
set TOTAL2 = TOTAL2 - 1
call D.destroy()
endif
set i = i + 1
endloop
if TOTAL2 == 0 then
call PauseTimer(TIMER2)
endif
endfunction
private function action takes nothing returns nothing
local rOSRun1 D
local rOSRun2 A
local boolean DESTROY_DATA
local integer i = 0
local real x
local real y
local real dx
local real dy
local real angle
loop
exitwhen i >= TOTAL
set D = ARRAY[i]
if D.interval <= 0 then
set A = rOSRun2.create()
set x = GetUnitX(D.caster)
set y = GetUnitY(D.caster)
set dx = D.x - x
set dy = D.y - y
call SetUnitAnimation(D.caster, "stand")
call SetUnitAnimation(D.caster, ANIMATION_NAME)
set A.caster = D.caster
set A.level = D.level
set angle = Atan2(D.y - y, D.x - x) + bj_DEGTORAD * D.angle
set A.angle = angle * bj_RADTODEG
set A.missile = CreateUnit(PLAYER, DUMMY_ID, x, y, A.angle)
call SetUnitFlyHeight(A.missile, MISSILE_HEIGHT, 0)
set A.currentDis = 0
set A.maxDis = SquareRoot(dx * dx + dy * dy)
set A.g = CreateGroup()
call SetUnitScale(A.missile, MISSILE_SCALE, MISSILE_SCALE, MISSILE_SCALE)
set A.fx = AddSpecialEffectTarget(MISSILE_MODEL, A.missile, "origin")
call SetUnitFacing(D.caster, D.angle)
if D.changeAngle then
if D.angle < MAX_ANGLE() then
set D.angle = D.angle + ANGLE_FACTOR()
else
set D.changeAngle = FALSE
endif
else
if D.angle > - MAX_ANGLE() then
set D.angle = D.angle - ANGLE_FACTOR()
else
set D.changeAngle = TRUE
endif
endif
if TOTAL2 == 0 then
call TimerStart(TIMER2, FPS, true, function missileAction)
endif
set TOTAL2 = TOTAL2 + 1
set ARRAY2[TOTAL2 - 1] = A
set D.missiles = D.missiles - 1
set D.interval = INTERVAL_PER_MISSILE(D.level)
else
set D.interval = D.interval - FPS
endif
set DESTROY_DATA = IsUnitType(D.caster, UNIT_TYPE_DEAD) or D.missiles <= 0
if DESTROY_DATA then
call PauseUnit(D.caster, false)
call SetUnitTimeScale(D.caster, 1)
call IssueImmediateOrder(D.caster, "stop")
call SetUnitAnimation(D.caster, "stand")
set ARRAY[i] = ARRAY[TOTAL - 1]
set TOTAL = TOTAL - 1
call D.destroy()
endif
set i = i + 1
endloop
if TOTAL == 0 then
call PauseTimer(TIMER)
endif
endfunction
private function run takes nothing returns boolean
local rOSRun1 D
local unit caster
local real x
local real y
local real x1
local real y1
if GetSpellAbilityId() == ABILITY_ID then
set D = rOSRun1.create()
set caster = GetTriggerUnit()
set D.caster = caster
set D.level = GetUnitAbilityLevel(caster, ABILITY_ID)
set D.missiles = MISSILES(D.level)
set D.interval = 0
set x = GetUnitX(D.caster)
set y = GetUnitY(D.caster)
set D.x = GetSpellTargetX()
set D.y = GetSpellTargetY()
set D.changeAngle = FALSE
set D.angle = 0
if x == D.x and y == D.y then
set D.x = x + MIN_DISTANCE(D.level) * Cos(GetUnitFacing(D.caster) * bj_DEGTORAD)
set D.y = y + MIN_DISTANCE(D.level) * Sin(GetUnitFacing(D.caster) * bj_DEGTORAD)
endif
call PauseUnit(D.caster, true)
call SetUnitTimeScale(caster, ANIMATION_SPEED)
if TOTAL == 0 then
call TimerStart(TIMER, FPS, true, function action)
endif
set TOTAL = TOTAL + 1
set ARRAY[TOTAL - 1] = D
set caster = null
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
local unit d = CreateUnit(Player(0), DUMMY_ID, 0, 0, 0)
loop
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t, Condition(function run))
call UnitAddAbility(d, ABILITY_ID)
call UnitAddAbility(d, SLOW_ABILITY_ID)
call Preload(MISSILE_MODEL)
call Preload(DEAL_MODEL)
call RemoveUnit(d)
set FPS = 1 / FPS
set SPEED = SPEED * FPS
set t = null
set d = null
endfunction
endscope