/*
Space Collapse 1.0 by Adiktuz
-Creates images of yourself around the target area to saturate the area with arcane energy
which causes spacial ruptures on the target area
Programs required to implement:
-NewGenWE with Jass Helper 0.A.2.A or up
How to use:
1)Copy the triggers named SpaceCollapse, T32 and Nova into your map
-you can just copy the whole folder for easier copying
2)Import the dummy.mdx into your map and create a dummy caster if you don't have one yet
3)Create another dummy for the image of the caster, use the same settings as your dummy caster
but set the model to the model of the unit that will have the spell
4)Copy the Ability into your map and give it to your caster, adjust the values to suit your needs
5)Adjust the global variables and the formulas below to your liking
-be sure to adjust the raw codes on this library and on the Nova library for the dummies
Credits to:
Vexorian - dummy.mdx
Jesus4Lyf - Timer32
*/
library SpaceCollapse requires Nova, T32
//By Adiktuz
globals
private constant integer SC_ID = 'A000' //rawcode of spell
private constant integer DUMMY_ID = 'h000' //rawcode of dummy caster
private constant integer CASTER_ID = 'h001' //rawcode of the caster images
private constant integer IMAGES = 5 //number of images created + the caster itself, don't set it to too high
private constant string CIRCLE_A = "Abilities\\Spells\\Undead\\RegenerationAura\\ObsidianRegenAura.mdl" //the path to the effect that will be shown below the caster and its images
private constant string CIRCLE_B = "Abilities\\Spells\\Undead\\UnholyAura\\UnholyAura.mdl" //the path to the effect that will be shown on the AoE
private constant string CIRCLE_C = "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAura.mdl" //the path to the effect that will be shown above CIRCLE_B
private constant string COLLAPSE = "Abilities\\Spells\\Other\\HowlOfTerror\\HowlCaster.mdl" //the path to the effect of the collapse, several of these could be made depending on the amount you set on a function below
private constant integer ANIMATION = 5 //the index of the animation to be used
private constant real DELAY = 1.50 //the duration of the spell animation or whatever animation you will be using
private constant real DELAY_C = 1.20 //the delay before the collapse happen, scale this depending on the collapse model that you will use
private constant real SCALE = 1.0 //the scale of CIRCLE_A
private constant real SCALE_COLLAPSE = .7 //the scale of teh collapse effects
private constant real OFFSET = 100.0 //the offset of the caster images from the radius of the AOE
private constant real HEIGHT = 300.0 //the height of CIRCLE_C
private constant attacktype AT = ATTACK_TYPE_MAGIC //the attack type of the spell
private constant damagetype DT = DAMAGE_TYPE_NORMAL //the damage type of the spell
private constant integer FLY = 'Amrf' //rawcode of Medivh's raven form
private constant integer CIRCLES = IMAGES + 1//do not edit
endglobals
//I suggest making the cast range to be equal to the radius + (50 to 100)
private function GetRadius takes integer level returns real
return 200.0*level
endfunction
//the radius of the damage of each
private function GetRadiusF takes integer level returns real
return 75.0*level
endfunction
//the function for setting the damage dealt by the spell
private function GetDamage takes integer level returns real
return 100.0*level
endfunction
//the function for getting the maximum number of the collapse effect that will be created around the AOE
private function GetEffectsMax takes integer level returns integer
return 6*level
endfunction
//the function for getting the minimum number of the collapse effect that will be created around the AOE
private function GetEffectsMin takes integer level returns integer
return 3*level
endfunction
//the function for setting the scale of CIRCLE_B and CIRCLE_C
//I've set CIRCLE_C to be half the scale of CIRCLE_B
private function GetScaleAB takes integer level returns real
return GetRadius(level)/100.0
endfunction
//the initializer Module
module init
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
exitwhen i > 15
call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set i = i + 1
endloop
call TriggerAddCondition(t, Condition(function thistype.SpaceCollapseAction))
set t = null
endmethod
endmodule
//the struct for the main part of the spell
struct SpaceCollapse
implement init
static unit caster
static integer level
static real x
static real y
static real x2
static real y2
static location TempLoc = Location(0,0)
real time
real xc
real yc
unit casterr
unit array images [IMAGES]
unit array circles [CIRCLES]
effect array effects [CIRCLES]
private method onDestroy takes nothing returns nothing
local integer i = 0
call SetUnitX(this.casterr, this.xc)
call SetUnitY(this.casterr, this.yc)
call SetUnitFlyHeight(this.caster, 0.0, 0.0)
loop
exitwhen i > CIRCLES
set this.images[i] = null
set this.circles[i] = null
call DestroyEffect(this.effects[i])
set this.effects[i] = null
set i = i + 1
endloop
endmethod
private method periodic takes nothing returns nothing
local integer i = 0
loop
exitwhen i > CIRCLES
if i != CIRCLES - 1 then
call SetUnitFacing(this.circles[i], this.time*12.0)
else
call SetUnitFacing(this.circles[i], this.time*-12.0)
endif
set i = i + 1
endloop
set this.time = this.time + T32_PERIOD
if this.time >= DELAY then
call this.stopPeriodic()
call this.destroy()
endif
endmethod
implement T32x
static method create takes player owner, real angle, real x2, real y2, integer level returns thistype
local thistype this = .allocate()
local real angle2 = (360.0/I2R(IMAGES))*.017453292
local integer i = 1
local real x = x2 + (GetRadius(level) + OFFSET )*Cos(angle)
local real y = y2 + (GetRadius(level) + OFFSET )*Sin(angle)
local real x3
local real y3
local real z
local real fz
local real scales = GetScaleAB(level)
set this.circles[0] = CreateUnit(owner, DUMMY_ID, x, y, 0.0)
set this.effects[0] = AddSpecialEffectTarget(CIRCLE_A, this.circles[0], "origin")
call UnitApplyTimedLife(this.circles[0], 'BTLF', DELAY + .2)
call SetUnitScale(this.circles[0], SCALE, SCALE, SCALE)
call SetUnitExploded(this.circles[0], true)
call MoveLocation(thistype.TempLoc, x2, y2)
set this.xc = thistype.x
set this.yc = thistype.y
call SetUnitX(thistype.caster, x )
call SetUnitY(thistype.caster, y )
set z = GetLocationZ(thistype.TempLoc)
call UnitAddAbility(this.circles[0], FLY)
call UnitRemoveAbility(this.circles[0], FLY)
call UnitAddAbility(this.caster, FLY)
call UnitRemoveAbility(this.caster, FLY)
call MoveLocation(thistype.TempLoc, x, y)
set fz = z - GetLocationZ(thistype.TempLoc)
call SetUnitFlyHeight(this.circles[0], fz, 0.0)
call SetUnitFlyHeight(thistype.caster, fz, 0.0)
set this.time = 0.0
loop
exitwhen i == IMAGES
set x3 = x2 + (GetRadius(level) + OFFSET )*Cos(angle + angle2*i)
set y3 = y2 + (GetRadius(level) + OFFSET )*Sin(angle + angle2*i)
set this.circles[i] = CreateUnit(owner, DUMMY_ID, x3, y3, 0.0)
call UnitAddAbility(this.circles[i], FLY)
call UnitRemoveAbility(this.circles[i], FLY)
set this.images[i] = CreateUnit(owner, CASTER_ID, x3, y3, (angle + angle2*i + 3.141592654)/.017453292)
call UnitAddAbility(this.images[i], FLY)
call UnitRemoveAbility(this.images[i], FLY)
call MoveLocation(thistype.TempLoc, x3, y3)
call SetUnitScale(this.circles[i], SCALE, SCALE, SCALE)
set fz = z - GetLocationZ(thistype.TempLoc)
call SetUnitFlyHeight(this.circles[i], fz, 0.0)
call SetUnitFlyHeight(this.images[i], fz, 0.0)
call SetUnitExploded(this.circles[i], true)
call SetUnitExploded(this.images[i], true)
call SetUnitAnimationByIndex(this.images[i], ANIMATION)
call UnitApplyTimedLife(this.circles[i], 'BTLF', DELAY + .1)
call UnitApplyTimedLife(this.images[i], 'BTLF', DELAY + .1)
set this.effects[i] = AddSpecialEffectTarget(CIRCLE_A, this.circles[i], "origin")
set i = i + 1
endloop
set this.circles[CIRCLES - 1] = CreateUnit(owner, DUMMY_ID, x2, y2, 0.0)
set this.effects[CIRCLES - 1] = AddSpecialEffectTarget(CIRCLE_B, this.circles[CIRCLES - 1], "origin")
set this.circles[CIRCLES] = CreateUnit(owner, DUMMY_ID, x2, y2, 0.0)
set this.effects[CIRCLES] = AddSpecialEffectTarget(CIRCLE_C, this.circles[CIRCLES], "origin")
call SetUnitScale(this.circles[CIRCLES - 1], scales, scales, scales)
call SetUnitScale(this.circles[CIRCLES], scales/2.0, scales/2.0, scales/2.0)
call SetUnitExploded(this.circles[CIRCLES - 1], true)
call SetUnitExploded(this.circles[CIRCLES], true)
call UnitAddAbility(this.circles[CIRCLES], FLY)
call UnitRemoveAbility(this.circles[CIRCLES], FLY)
call SetUnitFlyHeight(this.circles[CIRCLES], HEIGHT, 0.0)
call UnitApplyTimedLife(this.circles[CIRCLES - 1], 'BTLF', DELAY + .2)
call UnitApplyTimedLife(this.circles[CIRCLES], 'BTLF', DELAY + .2)
call this.startPeriodic()
set this.casterr = thistype.caster
return this
endmethod
static method SpaceCollapseAction takes nothing returns boolean
if GetSpellAbilityId() == SC_ID then
set thistype.caster = GetTriggerUnit()
set thistype.level = GetUnitAbilityLevel(thistype.caster, SC_ID)
call SetUnitAnimationByIndex(thistype.caster, ANIMATION)
set thistype.x = GetUnitX(thistype.caster)
set thistype.y = GetUnitY(thistype.caster)
set thistype.x2 = GetSpellTargetX()
set thistype.y2 = GetSpellTargetY()
call thistype.create(GetOwningPlayer(thistype.caster), Atan2(thistype.y-thistype.y2, thistype.x-thistype.x2), thistype.x2, thistype.y2, thistype.level)
call NovaSystem.create(thistype.caster, thistype.x2, thistype.y2, GetRadius(thistype.level) - 100.0*thistype.level, GetRadiusF(thistype.level), 0.0, GetEffectsMin(thistype.level),/*
*/GetEffectsMax(thistype.level), DELAY_C , DELAY_C, GetDamage(thistype.level), SCALE_COLLAPSE, SCALE_COLLAPSE, SCALE_COLLAPSE, false, false, false, COLLAPSE, AT, DT)
endif
return false
endmethod
endstruct
endlibrary