scope MathKills initializer ini/* v1.7
Made based on my over-hatred of mathematics
Throws away an over-heading mathematics onto the targeted point. The larger calculation done
within the throwing sequence, the larger damage will be dealt. Just like the fact, harder calculation
deals more damage to our brain (and often causes dizziness) Nuclear explosion shows how destructive
is that mathematics
This spell is just for fun, Im not really sure this spell is practical in any map. And sorry
that you cant configure the slow via trigger, you need to configure via Object Editor. Anyway
Enjoy..
Requires:
WorldBounds #github.com/nestharus/JASS/blob/master/jass/Systems/WorldBounds/script.j
How to import:
- Copy MathKills folder into your map
- Copy MathKills dummy unit, all dummy spells, and dummy buff
- Export dummy.mdx into your map
Credits
- NuclearExplosion.mdx by WILLTHEALMIGHTY
- WorldBounds by Nestharus
*/
globals
// Rawcode of main spell
private constant integer SPELL_ID = 'A000'
// Alpha channel of missile, max is 255
private constant integer MISSILE_ALPHA = 255
// Missile arcing
private constant real MISSILE_ARC = .75
// Additional chars before minor missiles integer
private constant string MISSILE_PREFIX = "+"
// Missile size
private constant real MISSILE_SIZE = .023
// Missile speed
private constant real MISSILE_SPEED = 10.
// How fast is the droppings
private constant real DROP_SPEED = 20.
// Low bound of dropped integer
private constant integer RANDOMINT_LOWBOUND = 5
// Upper bound of dropped integer
private constant integer RANDOMINT_UPPERBOUND = 30
// True if you want to make the distance constant
private constant boolean CONSTANT_DISTANCE = false
// Give random color to missile
private constant boolean COLOR_ENABLED = true
// Generate rainbow color on missile
private constant boolean COLOR_RAINBOW = true
// How fast is the color change
private constant integer RAINBOW_COLOR_RATE = 10
// Sfx created on main missile impact
private constant string EXPLODE_SFX_MAJOR = "war3mapImported\\NuclearExplosion.mdx"
// Sfx created on little missile impact
private constant string EXPLODE_SFX_MINOR = "Abilities\\Weapons\\FragDriller\\FragDriller.mdl"
// True will make the spell causes dizziness
private constant boolean DIZZINESS_ENABLED = true
// Dummy unit rawcode
private constant integer DIZZINESS_DUMMY_ID = 'h000'
// Dummy slow spell rawcode
private constant integer DIZZINESS_SPELL_ID = 'A001'
// Slow buff rawcode
private constant integer DIZZINESS_BUFF_ID = 'B000'
// Slow spell order string
private constant string DIZZINESS_ORDER_ID = "slow"
// Sfx for dizziness buff
private constant string DIZZINESS_SFX_PATH = "Abilities\\Spells\\Orc\\StasisTrap\\StasisTotemTarget.mdl"
// Dizziness sfx attach point
private constant string DIZZINESS_SFX_POINT = "overhead"
// Accuracy of loop triggers
private constant real ACCURACY = .03
// Initial amount damage for main missile
private constant real BASE_DAMAGE = 0.
// Attack type of dealt damage
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_HERO
// Damage type of dealt damage
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
// Weapon type of dealt damage
private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS
endglobals
// This is for constant max distance
private constant function MK_MaxDistance takes integer level returns real
return 1200.
endfunction
// Little missile drop rate
private constant function MK_DropRate takes integer level returns real
return .5 - .2 * (level - 1)
endfunction
// AoE of minor missile
private constant function MK_MinorAoE takes integer level returns real
return 100.
endfunction
// AoE of major missile
private constant function MK_MajorAoE takes integer level returns real
return 350.
endfunction
// Duration of dizziness. 0 for permanent
private constant function MK_Dizziness_Duration takes integer level returns real
return 5.
endfunction
// Custom filtration of target for this spell
private function extraFiltration takes unit u returns boolean
return not(IsUnitType(u, UNIT_TYPE_MECHANICAL) or IsUnitType(u, UNIT_TYPE_STRUCTURE) or IsUnitType(u, UNIT_TYPE_RESISTANT))
endfunction
/* 'END OF CONFIGURATION' */
globals
private effect array Dizziness_Sfx
private group DamageGroup = CreateGroup()
private integer Dizziness_Total = -1
private integer Major_Total = -1
private integer Minor_Total = -1
private integer array Major_Level
private integer array Minor_Level
private integer array Major_Red
private integer array Major_Green
private integer array Major_Blue
private integer array Major_RedR
private integer array Major_GreenR
private integer array Major_BlueR
private player array Major_Player
private player array Minor_Player
private real array Dizziness_Duration
private real array Major_Angle
private real array Major_Damage
private real array Major_DC
private real array Major_DX
private real array Major_Z
private real array Major_Delay
private real array Major_X
private real array Major_Y
private real array Minor_Damage
private real array Minor_X
private real array Minor_Y
private real array Minor_H
private texttag array Major_Missile
private texttag array Minor_Missile
private timer Dizziness_Timer = CreateTimer()
private timer Major_Timer = CreateTimer()
private timer Minor_Timer = CreateTimer()
private unit Dizziness_Dummy
private unit array Dizziness_Target
private unit array Major_Caster
private unit array Minor_Caster
endglobals
native UnitAlive takes unit id returns boolean
private function dizzinessLoop takes nothing returns nothing
local integer i = 0
loop
exitwhen i > Dizziness_Total
if Dizziness_Duration[i] > 0 then
set Dizziness_Duration[i] = Dizziness_Duration[i] - ACCURACY
if Dizziness_Duration[i] <= 0 or IsUnitType(Dizziness_Target[i], UNIT_TYPE_DEAD) then
call UnitRemoveAbility(Dizziness_Target[i], DIZZINESS_BUFF_ID)
call DestroyEffect(Dizziness_Sfx[i])
if i != Dizziness_Total then
set Dizziness_Duration[i] = Dizziness_Duration[Dizziness_Total]
set Dizziness_Sfx[i] = Dizziness_Sfx[Dizziness_Total]
set Dizziness_Target[i] = Dizziness_Target[Dizziness_Total]
endif
set Dizziness_Target[Dizziness_Total] = null
set Dizziness_Total = Dizziness_Total - 1
if Dizziness_Total < 0 then
call PauseTimer(Dizziness_Timer)
else
set i = i - 1
endif
endif
endif
set i = i + 1
endloop
endfunction
private function dealDamage takes unit c, player p, real d, integer l returns nothing
local unit u
loop
set u = FirstOfGroup(DamageGroup)
exitwhen u == null
if extraFiltration(u) then
if UnitAlive(u) and IsPlayerEnemy(GetOwningPlayer(u), p) then
call UnitDamageTarget(c, u, d, false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
static if DIZZINESS_ENABLED then
if GetUnitAbilityLevel(u, DIZZINESS_BUFF_ID) < 1 then
set Dizziness_Total = Dizziness_Total + 1
set Dizziness_Duration[Dizziness_Total] = MK_Dizziness_Duration(l)
set Dizziness_Target[Dizziness_Total] = u
set Dizziness_Sfx[Dizziness_Total] = AddSpecialEffectTarget(DIZZINESS_SFX_PATH, u, DIZZINESS_SFX_POINT)
call IssueTargetOrder(Dizziness_Dummy, DIZZINESS_ORDER_ID, u)
if Dizziness_Total == 0 then
call TimerStart(Dizziness_Timer, ACCURACY, true, function dizzinessLoop)
endif
endif
endif
endif
endif
call GroupRemoveUnit(DamageGroup, u)
endloop
endfunction
private function minorLoop takes nothing returns nothing
local integer i = 0
local integer i2
loop
exitwhen i > Minor_Total
set Minor_H[i] = Minor_H[i] - DROP_SPEED
call SetTextTagPos(Minor_Missile[i], Minor_X[i], Minor_Y[i], Minor_H[i])
set i2 = 0
loop
exitwhen i2 > 11
if GetLocalPlayer() == Player(i2) then
if IsVisibleToPlayer(Minor_X[i], Minor_Y[i], Player(i2)) then
call SetTextTagVisibility(Minor_Missile[i], true)
else
call SetTextTagVisibility(Minor_Missile[i], false)
endif
endif
set i2 = i2 + 1
endloop
if Minor_H[i] <= 0 then
call GroupEnumUnitsInRange(DamageGroup, Minor_X[i], Minor_Y[i], MK_MinorAoE(Minor_Level[i]), null)
call dealDamage(Minor_Caster[i], Minor_Player[i], Minor_Damage[i], Minor_Level[i])
call DestroyTextTag(Minor_Missile[i])
call DestroyEffect(AddSpecialEffect(EXPLODE_SFX_MINOR, Minor_X[i], Minor_Y[i]))
if i != Minor_Total then
set Minor_Missile[i] = Minor_Missile[Minor_Total]
set Minor_Damage[i] = Minor_Damage[Minor_Total]
set Minor_Caster[i] = Minor_Caster[Minor_Total]
set Minor_Player[i] = Minor_Player[Minor_Total]
set Minor_H[i] = Minor_H[Minor_Total]
set Minor_X[i] = Minor_X[Minor_Total]
set Minor_Y[i] = Minor_Y[Minor_Total]
endif
set Minor_Caster[Minor_Total] = null
set Minor_Missile[Minor_Total] = null
set Minor_Total = Minor_Total - 1
if Minor_Total < 0 then
call PauseTimer(Minor_Timer)
else
set i = i - 1
endif
endif
set i = i + 1
endloop
endfunction
private function majorLoop takes nothing returns nothing
local integer i = 0
local integer i2
local integer d
local real h
local real xt
local real yt
loop
exitwhen i > Major_Total
if Major_DC[i] >= Major_DX[i] then
call GroupEnumUnitsInRange(DamageGroup, Major_X[i], Major_Y[i], MK_MajorAoE(Major_Level[i]), null)
call dealDamage(Major_Caster[i], Major_Player[i], Major_Damage[i], Major_Level[i])
call DestroyTextTag(Major_Missile[i])
call DestroyEffect(AddSpecialEffect(EXPLODE_SFX_MAJOR, Major_X[i], Major_Y[i]))
if i != Major_Total then
set Major_Angle[i] = Major_Angle[Major_Total]
set Major_Caster[i] = Major_Caster[Major_Total]
set Major_Damage[i] = Major_Damage[Major_Total]
set Major_DC[i] = Major_DC[Major_Total]
set Major_DX[i] = Major_DX[Major_Total]
set Major_Delay[i] = Major_Delay[Major_Total]
set Major_Z[i] = Major_Z[Major_Total]
set Major_Level[i] = Major_Level[Major_Total]
set Major_Missile[i] = Major_Missile[Major_Total]
set Major_Player[i] = Major_Player[Major_Total]
set Major_Red[i] = Major_Red[Major_Total]
set Major_RedR[i] = Major_RedR[Major_Total]
set Major_Green[i] = Major_Green[Major_Total]
set Major_GreenR[i] = Major_GreenR[Major_Total]
set Major_Blue[i] = Major_Blue[Major_Total]
set Major_BlueR[i] = Major_BlueR[Major_Total]
set Major_X[i] = Major_X[Major_Total]
set Major_Y[i] = Major_Y[Major_Total]
endif
set Major_Caster[Major_Total] = null
set Major_Missile[Major_Total] = null
set Major_Total = Major_Total - 1
if Major_Total < 0 then
call PauseTimer(Major_Timer)
else
set i = i - 1
endif
else
set Major_DC[i] = Major_DC[i] + MISSILE_SPEED
set h = ((4. * Major_Z[i]) / Major_DX[i]) * (Major_DX[i] - Major_DC[i]) * (Major_DC[i] / Major_DX[i])
set xt = Major_X[i] + MISSILE_SPEED * Cos(Major_Angle[i])
set yt = Major_Y[i] + MISSILE_SPEED * Sin(Major_Angle[i])
if xt <= WorldBounds.maxX and xt >= WorldBounds.minX and yt <= WorldBounds.maxY and yt >= WorldBounds.minY then
set Major_X[i] = xt
set Major_Y[i] = yt
call SetTextTagPos(Major_Missile[i], xt, yt, h)
else
call SetTextTagPos(Major_Missile[i], Major_X[i], Major_Y[i], h)
endif
set i2 = 0
loop
exitwhen i2 > 11
if GetLocalPlayer() == Player(i2) then
if IsVisibleToPlayer(Major_X[i], Major_Y[i], Player(i2)) then
call SetTextTagVisibility(Major_Missile[i], true)
else
call SetTextTagVisibility(Major_Missile[i], false)
endif
endif
set i2 = i2 + 1
endloop
static if COLOR_RAINBOW then
if Major_Red[i] + Major_RedR[i] > 255 or Major_Red[i] + Major_RedR[i] < 0 then
set Major_RedR[i] = Major_RedR[i] * -1
endif
if Major_Green[i] + Major_GreenR[i] > 255 or Major_Green[i] + Major_GreenR[i] < 0 then
set Major_GreenR[i] = Major_GreenR[i] * -1
endif
if Major_Blue[i] + Major_BlueR[i] > 255 or Major_Blue[i] + Major_BlueR[i] < 0 then
set Major_BlueR[i] = Major_BlueR[i] * -1
endif
set Major_Red[i] = Major_Red[i] + Major_RedR[i]
set Major_Green[i] = Major_Green[i] + Major_GreenR[i]
set Major_Blue[i] = Major_Blue[i] + Major_BlueR[i]
call SetTextTagColor(Major_Missile[i], Major_Red[i], Major_Green[i], Major_Blue[i], MISSILE_ALPHA)
endif
if Major_Delay[i] > 0 then
set Major_Delay[i] = Major_Delay[i] - ACCURACY
if Major_Delay[i] <= 0 then
set Major_Delay[i] = MK_DropRate(Major_Level[i])
set d = GetRandomInt(RANDOMINT_LOWBOUND, RANDOMINT_UPPERBOUND)
set Major_Damage[i] = Major_Damage[i] + I2R(d)
call SetTextTagText(Major_Missile[i], I2S(R2I(Major_Damage[i])), MISSILE_SIZE)
set Minor_Total = Minor_Total + 1
set Minor_Player[Minor_Total] = Major_Player[i]
set Minor_Caster[Minor_Total] = Major_Caster[i]
set Minor_Level[Minor_Total] = Major_Level[i]
set Minor_Damage[Minor_Total] = I2R(d)
set Minor_X[Minor_Total] = Major_X[i]
set Minor_Y[Minor_Total] = Major_Y[i]
set Minor_H[Minor_Total] = h
set Minor_Missile[Minor_Total] = CreateTextTag()
call SetTextTagText(Minor_Missile[Minor_Total], MISSILE_PREFIX + I2S(R2I(Minor_Damage[Minor_Total])), MISSILE_SIZE)
call SetTextTagPos(Minor_Missile[Minor_Total], Minor_X[Minor_Total], Minor_Y[Minor_Total], h)
call SetTextTagColor(Minor_Missile[Minor_Total], Major_Red[i], Major_Green[i], Major_Blue[i], MISSILE_ALPHA)
if Minor_Total == 0 then
call TimerStart(Minor_Timer, ACCURACY, true, function minorLoop)
endif
endif
endif
endif
set i = i + 1
endloop
endfunction
private function onCast takes nothing returns boolean
local real xt
local real yt
if GetSpellAbilityId() == SPELL_ID then
set Major_Total = Major_Total + 1
set Major_Caster[Major_Total] = GetTriggerUnit()
set Major_X[Major_Total] = GetUnitX(Major_Caster[Major_Total])
set Major_Y[Major_Total] = GetUnitY(Major_Caster[Major_Total])
set xt = GetSpellTargetX()
set yt = GetSpellTargetY()
set Major_Damage[Major_Total] = BASE_DAMAGE
set Major_Angle[Major_Total] = Atan2(yt - Major_Y[Major_Total], xt - Major_X[Major_Total])
set Major_Player[Major_Total] = GetTriggerPlayer()
set Major_Level[Major_Total] = GetUnitAbilityLevel(Major_Caster[Major_Total], SPELL_ID)
set Major_Delay[Major_Total] = MK_DropRate(Major_Level[Major_Total])
set Major_DC[Major_Total] = 0
static if CONSTANT_DISTANCE then
set Major_DX[Major_Total] = MK_MaxDistance(Major_Level[Major_Total])
else
set Major_DX[Major_Total] = SquareRoot((xt - Major_X[Major_Total]) * (xt - Major_X[Major_Total]) + (yt - Major_Y[Major_Total]) * (yt - Major_Y[Major_Total]))
endif
set Major_Z[Major_Total] = MISSILE_ARC * Major_DX[Major_Total]
set Major_Missile[Major_Total] = CreateTextTag()
call SetTextTagText(Major_Missile[Major_Total], I2S(R2I(Major_Damage[Major_Total])), MISSILE_SIZE)
call SetTextTagPos(Major_Missile[Major_Total], Major_X[Major_Total], Major_Y[Major_Total], 0)
static if COLOR_ENABLED then
set Major_Red[Major_Total] = GetRandomInt(0, 255)
set Major_Green[Major_Total] = GetRandomInt(0, 255)
set Major_Blue[Major_Total] = GetRandomInt(0, 255)
call SetTextTagColor(Major_Missile[Major_Total], Major_Red[Major_Total], Major_Green[Major_Total], Major_Blue[Major_Total], MISSILE_ALPHA)
static if COLOR_RAINBOW then
set Major_RedR[Major_Total] = GetRandomInt(RAINBOW_COLOR_RATE * -1, RAINBOW_COLOR_RATE)
set Major_GreenR[Major_Total] = GetRandomInt(RAINBOW_COLOR_RATE * -1, RAINBOW_COLOR_RATE)
set Major_BlueR[Major_Total] = GetRandomInt(RAINBOW_COLOR_RATE * -1, RAINBOW_COLOR_RATE)
endif
else
set Major_Red[Major_Total] = 255
set Major_Green[Major_Total] = 255
set Major_Blue[Major_Total] = 255
call SetTextTagColor(Major_Missile[Major_Total], 255, 255, 255, MISSILE_ALPHA)
endif
if Major_Total == 0 then
call TimerStart(Major_Timer, ACCURACY, true, function majorLoop)
endif
endif
return false
endfunction
private function ini takes nothing returns nothing
local trigger t = CreateTrigger()
static if DIZZINESS_ENABLED then
set Dizziness_Dummy = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), DIZZINESS_DUMMY_ID, WorldBounds.maxX, WorldBounds.maxY, 270.)
call UnitAddAbility(Dizziness_Dummy, DIZZINESS_SPELL_ID)
endif
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST)
call TriggerAddCondition(t, Condition(function onCast))
endfunction
endscope