- Joined
- Jan 29, 2007
- Messages
- 98
Hi!
As I can't seem to get the help I want in my spell thread I thought I'd post here too
I've created this spell, which was working fine, though the mods here at wc3c wanted me to use xecollider for some stuff...
Basically the spell creates some explosions around the caster, then sends out "fireballs" arounds it, that crawl along the ground...
These deal dps, and when they reach a certain point, they create another explosion, and dissapear.
Here's the description:
A small description of the spell:
And here's the first, working code (Without xe...):
[JASS="Tormental Wrath"]scope TormentalWrath initializer Init
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//***********************************************************************************************************//
//@@//////////////////////////////////Tormental Wrath, Made by Komaqtion///////////////////////////////////@@//
//@@ TimerUtils Version @@//
//@@ How to import: @@//
//@@ @@//
//@@ ¤ First copy the ability "Tormental Wrath" and the unit "Dummy" and change the ID's in the @@//
//@@ constants below to the new ones. Then you need to import Vexorian's dummy.mdx file from @@//
//@@ this map, or another, and change "Dummy" unit's model to this one. Then, of course, you @@//
//@@ need to import the triggers, which are in the categories "The Spell" and @@//
//@@ "Required Systems". Then you're free to change any of the given global constants to suit @@//
//@@ your needs. @@//
//@@ @@//
//@@ Requirements: @@//
//@@ ¤ Patch 1.23b or newer. @@//
//@@ ¤ JASS Newgen Pack, version 5c or newer. @@//
//@@ ¤ This spell, of course ! @@//
//@@ ¤ TimerUtils, made by Vexorian
@@//
//@@ ¤ GroupUtils, made by Rising_Dusk
@@//
//@@ ¤ The dummy.mdx, made by Vexorian ! @@//
//@@ @@//
//@@ ¤ Credits to: @@//
//@@ * Vexorian, for the dummy.mdx file and TimerUtils! @@//
//@@ ¤ Rising_Dusk, for making GroupUtils! @@//
//@@ * Kingkingyyk3 (@ TheHelper.net), for his wonderfull help on this spell,! @@//
//@@ @@//
//@@ And, of course, so many thanks to all of the many helpfull people at TheHelper.net @@//
//@@ who has helped get is spell working! (kingkingyyk3 and WolfieNoCT especially
) @@//
//@@ @@//
//@@ @@//
//@@ Note: This is my very first fully working, and quite good, spell made completely in vJASS. @@//
//@@ @@//
//@@ So much feedback, and suggestions are very much welcome, and maybe some tips to make it @@//
//@@ even better would be nice
@@//
//@@ @@//
//@@///////////////////////////////////////////////////////////////////////////////////////////////////////@@//
//***********************************************************************************************************//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
globals
// Effects! Change as you'd like
\\
private constant string EFFECT_C = "Abilities\\Spells\\Demon\\DarkPortal\\DarkPortalTarget.mdl" // Effect on the caster!
private constant string EFFECT_1 = "Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl" // Effect 200 range from the caster!
private constant string EFFECT_2 = "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl" // Effect at the end!
private constant string DUMMY_EFFECT = "Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl" // Effect on the moving dummy!
private constant string ATTACH_POINT = "origin" // The attach point of the dummy effect!
// ID's! Change to the ID's on your map
\\
private constant integer SPELL_ID = '0000' // ID of the spell!
private constant integer DUMMY_ID = 'h000' // ID of the dummy unit!
private constant integer LOCUST = 'Aloc' // ID of the "Locust" ability! (Might not need changing)
private constant integer BUFF_ID = 'BTLF' // ID of the expiration buff on the dummy!
// Other constant integers! Change at will
\\
private constant real DAMAGE_FACTOR = 1. // Just a simple real to make it easy to change the damage!
private constant real RANGE_FACTOR = 15. // Just a simple real to make it easy to change the range!
private constant integer ANGLES = 16 // The number of agles the effects will show at! (360/ANGLES)
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL // Explains itself i think XD
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL // Same here
private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS// And same here
private constant real SLIDE_INTERVAL = .05 // How long an interval is!
private constant real SLIDE_SPEED = 200. // How much the dummy effect moves each second!
private constant real TIME = 2.5 // How long it takes for the spell to complete!
private constant integer DISTANCE = R2I(TIME/SLIDE_INTERVAL) // How long the dummy effects will travel!
private constant real EXPLOSION_OFFSET = 200 // How much range the first explosions are offset the casters porition!
endglobals
// Damage functions!\\
private function Damage_Small takes integer lv returns real
return DAMAGE_FACTOR * lv
endfunction
private function Damage_Medium takes integer lv returns real
return 50 + lv * DAMAGE_FACTOR * 25
endfunction
private function Damage_High takes integer lv returns real
return 50 + lv * DAMAGE_FACTOR * 50
endfunction
// Range functions!\\
private function Range_Small takes nothing returns real
return RANGE_FACTOR * 5
endfunction
private function Range_Medium takes nothing returns real
return RANGE_FACTOR * 10
endfunction
private function Range_High takes nothing returns real
return RANGE_FACTOR * RANGE_FACTOR
endfunction
// End of Configuration!\\
globals
private integer TempStructIndex
private group Temp
private unit temp = null
endglobals
private struct Data
unit array du [ANGLES]
unit cs
boolean b = false
player p
group g
integer lvl
effect array e [ANGLES]
integer ticks
timer t
integer stage
static method create takes unit u returns Data
local Data a = Data.allocate()
set a.cs = u
set a.p = GetOwningPlayer(u)
set a.lvl = GetUnitAbilityLevel(a.cs,SPELL_ID)
set a.g = NewGroup()
return a
endmethod
method onDestroy takes nothing returns nothing
call ReleaseGroup(.g)
endmethod
endstruct
private function Spell_Check takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID
endfunction
private function GroupEm takes nothing returns boolean
return GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitEnemy(GetFilterUnit(), Data(TempStructIndex).p) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitInGroup(GetFilterUnit(), Data(TempStructIndex).g) == false
endfunction
private function Smaller_GroupEm takes nothing returns boolean
return GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitEnemy(GetFilterUnit(), Data(TempStructIndex).p) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false
endfunction
private function Deal_Damage takes nothing returns nothing
local unit u = GetEnumUnit()
if Data(TempStructIndex).stage == 1 then
call UnitDamageTarget(Data(TempStructIndex).cs, u, Damage_Medium(Data(TempStructIndex).lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call GroupAddUnit(Data(TempStructIndex).g,u)
call GroupRemoveUnit(Temp,u)
endif
if Data(TempStructIndex).stage == 2 then
call UnitDamageTarget(Data(TempStructIndex).cs, u, Damage_Small(Data(TempStructIndex).lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call GroupAddUnit(Data(TempStructIndex).g,u)
call GroupRemoveUnit(Temp,u)
endif
if Data(TempStructIndex).stage == 3 then
call UnitDamageTarget(Data(TempStructIndex).cs, u, Damage_High(Data(TempStructIndex).lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call GroupRemoveUnit(Temp,u)
endif
endfunction
private function Move_Dummy takes nothing returns nothing
local Data a = GetTimerData(GetExpiredTimer())
local real xd
local real yd
local real xd2
local real yd2
local integer i = 0
set TempStructIndex = a
if a.ticks > 0 then
set a.ticks = a.ticks - 1
set a.stage = 2
loop
exitwhen i>=ANGLES
set xd = GetUnitX(a.du)
set yd = GetUnitY(a.du)
set xd2 = xd+(SLIDE_SPEED*SLIDE_INTERVAL)*Cos(I2R(i*(360/(ANGLES)))*bj_DEGTORAD)
set yd2 = yd+(SLIDE_SPEED*SLIDE_INTERVAL)*Sin(I2R(i*(360/(ANGLES)))*bj_DEGTORAD)
call GroupRefresh(Temp)
call GroupEnumUnitsInRange(Temp, xd2, yd2, Range_Small(), Condition(function Smaller_GroupEm))
call ForGroup(Temp, function Deal_Damage)
call SetUnitX(a.du,xd2)
call SetUnitY(a.du,yd2)
set i = i+1
endloop
else
set a.stage = 3
loop
exitwhen i >=ANGLES
set xd = GetUnitX(a.du)
set yd = GetUnitY(a.du)
call DestroyEffect(a.e)
call DestroyEffect(AddSpecialEffect(EFFECT_2,xd,yd))
call GroupEnumUnitsInRange(Temp, xd, yd, Range_High(), Condition(function Smaller_GroupEm))
call ForGroup(Temp, function Deal_Damage)
call RemoveUnit(a.du)
set i = i+1
endloop
call a.destroy()
call ReleaseTimer(a.t)
endif
endfunction
private function Effects takes nothing returns nothing
local Data a = Data.create(GetTriggerUnit())
local real xu = GetUnitX(a.cs)
local real yu = GetUnitY(a.cs)
local real dx
local real dy
local integer i = 0
set a.t = NewTimer()
set Temp = NewGroup()
call DestroyEffect(AddSpecialEffect(EFFECT_C,xu,yu))
set a.stage = 1
loop
exitwhen i>=ANGLES
set dx = xu+EXPLOSION_OFFSET*Cos(I2R(i*(360/(ANGLES)))*bj_DEGTORAD)
set dy = yu+EXPLOSION_OFFSET*Sin(I2R(i*(360/(ANGLES)))*bj_DEGTORAD)
set TempStructIndex = a
call DestroyEffect(AddSpecialEffect(EFFECT_1, dx, dy))
call GroupRefresh(Temp)
call GroupEnumUnitsInRange(Temp, dx, dy,Range_Medium(), Condition(function GroupEm))
call ForGroup(Temp, function Deal_Damage)
set a.du = CreateUnit(a.p,DUMMY_ID,xu,yu,bj_RADTODEG*Atan2(dy-yu,dx-xu))
call UnitAddAbility(a.du,LOCUST)
set a.e = AddSpecialEffectTarget(DUMMY_EFFECT,a.du,ATTACH_POINT)
set i = i+1
endloop
set a.ticks = DISTANCE
call SetTimerData(a.t,a)
call TimerStart(a.t, SLIDE_INTERVAL, true, function Move_Dummy)
call ReleaseGroup(Temp)
endfunction
private function Init takes nothing returns nothing
local trigger t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t,Condition(function Spell_Check))
call TriggerAddAction(t,function Effects)
endfunction
endscope[/code]
Though, as i said, I wanted to implement xe into this :S
Though I have no idea how it works, as this is my first vJASS spell ever, and I haven't looked into xe before :S
So, here's my "tried-to-implement-xecollider-script":
Though, I getting tons of errors, and as soon as I fix one of them, more appear
My current error is "Syntax Error" on the middle line here:
Any ideas ? :S
Btw, the normal spell thread is here:
http://www.wc3c.net/showthread.php?t=107076&page=4
As I can't seem to get the help I want in my spell thread I thought I'd post here too
I've created this spell, which was working fine, though the mods here at wc3c wanted me to use xecollider for some stuff...
Basically the spell creates some explosions around the caster, then sends out "fireballs" arounds it, that crawl along the ground...
These deal dps, and when they reach a certain point, they create another explosion, and dissapear.
Here's the description:
A small description of the spell:
The hero will create a series of explosion around himself, before letting out small "balls" of fire, tumbling and dealing damage to enemies they come across! As a finish, explosions will appear when the balls get destroyed.
Level 1 - 75 damage on first explosion, 20 damage per second at the fire balls and lastly, 100 damage on the final explosion.
Level 2 - 100 damage on first explosion, 40 damage per second at the fire balls and lastly, 150 damage on the final explosion.
Level 3 - 125 damage on first explosion, 60 damage per second at the fire balls and lastly, 200 damage on the final explosion.
Level 1 - 75 damage on first explosion, 20 damage per second at the fire balls and lastly, 100 damage on the final explosion.
Level 2 - 100 damage on first explosion, 40 damage per second at the fire balls and lastly, 150 damage on the final explosion.
Level 3 - 125 damage on first explosion, 60 damage per second at the fire balls and lastly, 200 damage on the final explosion.
And here's the first, working code (Without xe...):
[JASS="Tormental Wrath"]scope TormentalWrath initializer Init
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//***********************************************************************************************************//
//@@//////////////////////////////////Tormental Wrath, Made by Komaqtion///////////////////////////////////@@//
//@@ TimerUtils Version @@//
//@@ How to import: @@//
//@@ @@//
//@@ ¤ First copy the ability "Tormental Wrath" and the unit "Dummy" and change the ID's in the @@//
//@@ constants below to the new ones. Then you need to import Vexorian's dummy.mdx file from @@//
//@@ this map, or another, and change "Dummy" unit's model to this one. Then, of course, you @@//
//@@ need to import the triggers, which are in the categories "The Spell" and @@//
//@@ "Required Systems". Then you're free to change any of the given global constants to suit @@//
//@@ your needs. @@//
//@@ @@//
//@@ Requirements: @@//
//@@ ¤ Patch 1.23b or newer. @@//
//@@ ¤ JASS Newgen Pack, version 5c or newer. @@//
//@@ ¤ This spell, of course ! @@//
//@@ ¤ TimerUtils, made by Vexorian
//@@ ¤ GroupUtils, made by Rising_Dusk
//@@ ¤ The dummy.mdx, made by Vexorian ! @@//
//@@ @@//
//@@ ¤ Credits to: @@//
//@@ * Vexorian, for the dummy.mdx file and TimerUtils! @@//
//@@ ¤ Rising_Dusk, for making GroupUtils! @@//
//@@ * Kingkingyyk3 (@ TheHelper.net), for his wonderfull help on this spell,! @@//
//@@ @@//
//@@ And, of course, so many thanks to all of the many helpfull people at TheHelper.net @@//
//@@ who has helped get is spell working! (kingkingyyk3 and WolfieNoCT especially
//@@ @@//
//@@ @@//
//@@ Note: This is my very first fully working, and quite good, spell made completely in vJASS. @@//
//@@ @@//
//@@ So much feedback, and suggestions are very much welcome, and maybe some tips to make it @@//
//@@ even better would be nice
//@@ @@//
//@@///////////////////////////////////////////////////////////////////////////////////////////////////////@@//
//***********************************************************************************************************//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
globals
// Effects! Change as you'd like
private constant string EFFECT_C = "Abilities\\Spells\\Demon\\DarkPortal\\DarkPortalTarget.mdl" // Effect on the caster!
private constant string EFFECT_1 = "Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl" // Effect 200 range from the caster!
private constant string EFFECT_2 = "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl" // Effect at the end!
private constant string DUMMY_EFFECT = "Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl" // Effect on the moving dummy!
private constant string ATTACH_POINT = "origin" // The attach point of the dummy effect!
// ID's! Change to the ID's on your map
private constant integer SPELL_ID = '0000' // ID of the spell!
private constant integer DUMMY_ID = 'h000' // ID of the dummy unit!
private constant integer LOCUST = 'Aloc' // ID of the "Locust" ability! (Might not need changing)
private constant integer BUFF_ID = 'BTLF' // ID of the expiration buff on the dummy!
// Other constant integers! Change at will
private constant real DAMAGE_FACTOR = 1. // Just a simple real to make it easy to change the damage!
private constant real RANGE_FACTOR = 15. // Just a simple real to make it easy to change the range!
private constant integer ANGLES = 16 // The number of agles the effects will show at! (360/ANGLES)
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL // Explains itself i think XD
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL // Same here
private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS// And same here
private constant real SLIDE_INTERVAL = .05 // How long an interval is!
private constant real SLIDE_SPEED = 200. // How much the dummy effect moves each second!
private constant real TIME = 2.5 // How long it takes for the spell to complete!
private constant integer DISTANCE = R2I(TIME/SLIDE_INTERVAL) // How long the dummy effects will travel!
private constant real EXPLOSION_OFFSET = 200 // How much range the first explosions are offset the casters porition!
endglobals
// Damage functions!\\
private function Damage_Small takes integer lv returns real
return DAMAGE_FACTOR * lv
endfunction
private function Damage_Medium takes integer lv returns real
return 50 + lv * DAMAGE_FACTOR * 25
endfunction
private function Damage_High takes integer lv returns real
return 50 + lv * DAMAGE_FACTOR * 50
endfunction
// Range functions!\\
private function Range_Small takes nothing returns real
return RANGE_FACTOR * 5
endfunction
private function Range_Medium takes nothing returns real
return RANGE_FACTOR * 10
endfunction
private function Range_High takes nothing returns real
return RANGE_FACTOR * RANGE_FACTOR
endfunction
// End of Configuration!\\
globals
private integer TempStructIndex
private group Temp
private unit temp = null
endglobals
private struct Data
unit array du [ANGLES]
unit cs
boolean b = false
player p
group g
integer lvl
effect array e [ANGLES]
integer ticks
timer t
integer stage
static method create takes unit u returns Data
local Data a = Data.allocate()
set a.cs = u
set a.p = GetOwningPlayer(u)
set a.lvl = GetUnitAbilityLevel(a.cs,SPELL_ID)
set a.g = NewGroup()
return a
endmethod
method onDestroy takes nothing returns nothing
call ReleaseGroup(.g)
endmethod
endstruct
private function Spell_Check takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID
endfunction
private function GroupEm takes nothing returns boolean
return GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitEnemy(GetFilterUnit(), Data(TempStructIndex).p) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitInGroup(GetFilterUnit(), Data(TempStructIndex).g) == false
endfunction
private function Smaller_GroupEm takes nothing returns boolean
return GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitEnemy(GetFilterUnit(), Data(TempStructIndex).p) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false
endfunction
private function Deal_Damage takes nothing returns nothing
local unit u = GetEnumUnit()
if Data(TempStructIndex).stage == 1 then
call UnitDamageTarget(Data(TempStructIndex).cs, u, Damage_Medium(Data(TempStructIndex).lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call GroupAddUnit(Data(TempStructIndex).g,u)
call GroupRemoveUnit(Temp,u)
endif
if Data(TempStructIndex).stage == 2 then
call UnitDamageTarget(Data(TempStructIndex).cs, u, Damage_Small(Data(TempStructIndex).lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call GroupAddUnit(Data(TempStructIndex).g,u)
call GroupRemoveUnit(Temp,u)
endif
if Data(TempStructIndex).stage == 3 then
call UnitDamageTarget(Data(TempStructIndex).cs, u, Damage_High(Data(TempStructIndex).lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call GroupRemoveUnit(Temp,u)
endif
endfunction
private function Move_Dummy takes nothing returns nothing
local Data a = GetTimerData(GetExpiredTimer())
local real xd
local real yd
local real xd2
local real yd2
local integer i = 0
set TempStructIndex = a
if a.ticks > 0 then
set a.ticks = a.ticks - 1
set a.stage = 2
loop
exitwhen i>=ANGLES
set xd = GetUnitX(a.du)
set yd = GetUnitY(a.du)
set xd2 = xd+(SLIDE_SPEED*SLIDE_INTERVAL)*Cos(I2R(i*(360/(ANGLES)))*bj_DEGTORAD)
set yd2 = yd+(SLIDE_SPEED*SLIDE_INTERVAL)*Sin(I2R(i*(360/(ANGLES)))*bj_DEGTORAD)
call GroupRefresh(Temp)
call GroupEnumUnitsInRange(Temp, xd2, yd2, Range_Small(), Condition(function Smaller_GroupEm))
call ForGroup(Temp, function Deal_Damage)
call SetUnitX(a.du,xd2)
call SetUnitY(a.du,yd2)
set i = i+1
endloop
else
set a.stage = 3
loop
exitwhen i >=ANGLES
set xd = GetUnitX(a.du)
set yd = GetUnitY(a.du)
call DestroyEffect(a.e)
call DestroyEffect(AddSpecialEffect(EFFECT_2,xd,yd))
call GroupEnumUnitsInRange(Temp, xd, yd, Range_High(), Condition(function Smaller_GroupEm))
call ForGroup(Temp, function Deal_Damage)
call RemoveUnit(a.du)
set i = i+1
endloop
call a.destroy()
call ReleaseTimer(a.t)
endif
endfunction
private function Effects takes nothing returns nothing
local Data a = Data.create(GetTriggerUnit())
local real xu = GetUnitX(a.cs)
local real yu = GetUnitY(a.cs)
local real dx
local real dy
local integer i = 0
set a.t = NewTimer()
set Temp = NewGroup()
call DestroyEffect(AddSpecialEffect(EFFECT_C,xu,yu))
set a.stage = 1
loop
exitwhen i>=ANGLES
set dx = xu+EXPLOSION_OFFSET*Cos(I2R(i*(360/(ANGLES)))*bj_DEGTORAD)
set dy = yu+EXPLOSION_OFFSET*Sin(I2R(i*(360/(ANGLES)))*bj_DEGTORAD)
set TempStructIndex = a
call DestroyEffect(AddSpecialEffect(EFFECT_1, dx, dy))
call GroupRefresh(Temp)
call GroupEnumUnitsInRange(Temp, dx, dy,Range_Medium(), Condition(function GroupEm))
call ForGroup(Temp, function Deal_Damage)
set a.du = CreateUnit(a.p,DUMMY_ID,xu,yu,bj_RADTODEG*Atan2(dy-yu,dx-xu))
call UnitAddAbility(a.du,LOCUST)
set a.e = AddSpecialEffectTarget(DUMMY_EFFECT,a.du,ATTACH_POINT)
set i = i+1
endloop
set a.ticks = DISTANCE
call SetTimerData(a.t,a)
call TimerStart(a.t, SLIDE_INTERVAL, true, function Move_Dummy)
call ReleaseGroup(Temp)
endfunction
private function Init takes nothing returns nothing
local trigger t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t,Condition(function Spell_Check))
call TriggerAddAction(t,function Effects)
endfunction
endscope[/code]
Though, as i said, I wanted to implement xe into this :S
Though I have no idea how it works, as this is my first vJASS spell ever, and I haven't looked into xe before :S
So, here's my "tried-to-implement-xecollider-script":
JASS:
scope TormentalWrath initializer Init
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//***********************************************************************************************************//
//@@//////////////////////////////////Tormental Wrath, Made by Komaqtion///////////////////////////////////@@//
//@@ TimerUtils Version @@//
//@@ How to import: @@//
//@@ @@//
//@@ ¤ First copy the ability "Tormental Wrath" and the unit "Dummy" and change the ID's in the @@//
//@@ constants below to the new ones. Then you need to import Vexorian's dummy.mdx file from @@//
//@@ this map, or another, and change "Dummy" unit's model to this one. Then, of course, you @@//
//@@ need to import the triggers, which are in the categories "The Spell" and @@//
//@@ "Required Systems". Then you're free to change any of the given global constants to suit @@//
//@@ your needs. @@//
//@@ @@//
//@@ Requirements: @@//
//@@ ¤ Patch 1.23b or newer. @@//
//@@ ¤ JASS Newgen Pack, version 5c or newer. @@//
//@@ ¤ This spell, of course ! @@//
//@@ ¤ TimerUtils, made by Vexorian :D @@//
//@@ ¤ The dummy.mdx, made by Vexorian ! @@//
//@@ @@//
//@@ ¤ Credits to: @@//
//@@ * Vexorian, for the dummy.mdx file and TimerUtils @@//
//@@ * Kingkingyyk3 (@ TheHelper.net), for his wonderfull help on this spell,! @@//
//@@ @@//
//@@ And, of course, so many thanks to all of the many helpfull people at TheHelper.net @@//
//@@ who has helped get is spell working! (kingkingyyk3 and WolfieNoCT especially :D) @@//
//@@ @@//
//@@ @@//
//@@ Note: This is my very first fully working, and quite good, spell made completely in vJASS. @@//
//@@ @@//
//@@ So much feedback, and suggestions are very much welcome, and maybe some tips to make it @@//
//@@ even better would be nice :D @@//
//@@ @@//
//@@///////////////////////////////////////////////////////////////////////////////////////////////////////@@//
//***********************************************************************************************************//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
globals
// Effects! Change as you'd like ;)\\
private constant string EFFECT_C = "Abilities\\Spells\\Demon\\DarkPortal\\DarkPortalTarget.mdl" // Effect on the caster!
private constant string EFFECT_1 = "Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl" // Effect 200 range from the caster!
private constant string EFFECT_2 = "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl" // Effect at the end!
private constant string DUMMY_EFFECT = "Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl" // Effect on the moving dummy!
private constant string ATTACH_POINT = "origin" // The attach point of the dummy effect!
// ID's! Change to the ID's on your map :D\\
private constant integer SPELL_ID = '0000' // ID of the spell!
private constant integer DUMMY_ID = 'h000' // ID of the dummy unit!
private constant integer LOCUST = 'Aloc' // ID of the "Locust" ability! (Might not need changing)
private constant integer BUFF_ID = 'BTLF' // ID of the expiration buff on the dummy!
// Other constant integers! Change at will :P\\
private constant real DAMAGE_FACTOR = 1. // Just a simple real to make it easy to change the damage!
private constant real RANGE_FACTOR = 15. // Just a simple real to make it easy to change the range!
private constant integer ANGLES = 16 // The number of agles the effects will show at! (360/ANGLES)
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL // Explains itself i think XD
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL // Same here :P
private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS// And same here :D
private constant real SLIDE_INTERVAL = .05 // How long an interval is!
private constant real SLIDE_SPEED = 200. // How much the dummy effect moves each second!
private constant real TIME = 2.5 // How long it takes for the spell to complete!
private constant integer DISTANCE = R2I(TIME/SLIDE_INTERVAL) // How long the dummy effects will travel!
private constant real EXPLOSION_OFFSET = 200. // How much range the first explosions are offset the casters porition!
endglobals
// Damage functions!\\
private function Damage_Small takes integer lv returns real
return DAMAGE_FACTOR * lv
endfunction
private function Damage_Medium takes integer lv returns real
return 50 + lv * DAMAGE_FACTOR * 25
endfunction
private function Damage_High takes integer lv returns real
return 50 + lv * DAMAGE_FACTOR * 50
endfunction
// Range functions!\\
private function Range_Small takes nothing returns real
return RANGE_FACTOR * 5
endfunction
private function Range_Medium takes nothing returns real
return RANGE_FACTOR * 10
endfunction
private function Range_High takes nothing returns real
return RANGE_FACTOR * RANGE_FACTOR
endfunction
// End of Configuration!\\
globals
private integer TempStruct
private group Temp
private unit temp = null
endglobals
private struct Data
unit array du [ANGLES]
unit cs
boolean b = false
player p
group g
integer lvl
effect array e [ANGLES]
integer ticks
timer t
integer stage
static method create takes unit u returns Data
local Data a = Data.allocate()
set a.cs = u
set a.p = GetOwningPlayer(u)
set a.lvl = GetUnitAbilityLevel(a.cs,SPELL_ID)
set a.g = NewGroup()
return a
endmethod
method onDestroy takes nothing returns nothing
call ReleaseGroup(.g)
call ReleaseTimer(.t)
endmethod
endstruct
struct SpellData extends xecollider
xecollider array xe [ANGLES]
unit c
player p
integer lvl
static method create takes unit caster returns SpellData
local SpellData s = SpellData.allocate()
set s.c = caster
set s.p = GetOwningPlayer(caster)
set s.lvl = GetUnitAbilityLevel(s.c,SPELL_ID)
return s
endmethod
method onUnitHit takes unit target returns nothing
local real xd
local real xy
endmethod
method onDestroy takes nothing returns nothing
local real xd
local real yd
local integer i = 0
loop
exitwhen i >=ANGLES
call .flash(EFFECT_2)
call GroupRefresh(Temp)
call GroupEnumUnitsInRange(Temp, .x, .y, Range_High(), Condition(function Smaller_GroupEm))
call ForGroup(Temp, function Deal_Damage)
set i = i+1
endloop
endmethod
endstruct
// Filter! \\
private function Filters takes nothing returns boolean
return IsUnitType(u, UNIT_TYPE_DEAD) != true or GetUnitTypeId(u) != 0 and IsUnitEnemy(GetFilterUnit(), Data(TempStruct).p) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false
endfunction
// End of Configuration!\\
private function Spell_Check takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID
endfunction
private function Filters_Group takes nothing returns boolean
return Filters () and IsUnitInGroup(GetFilterUnit(), Data(TempStructIndex).g) == false
endfunction
private function Deal_Damage takes nothing returns nothing
local unit u = GetEnumUnit()
if Data(TempStruct).stage == 1 then
call UnitDamageTarget(Data(TempStruct).cs, u, Damage_Medium(Data(TempStruct).lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call GroupAddUnit(Data(TempStruct).g,u)
call GroupRemoveUnit(Temp,u)
endif
if Data(TempStruct).stage == 2 then
call UnitDamageTarget(Data(TempStruct).cs, u, Damage_Small(Data(TempStruct).lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call GroupAddUnit(Data(TempStruct).g,u)
call GroupRemoveUnit(Temp,u)
endif
if Data(TempStruct).stage == 3 then
call UnitDamageTarget(Data(TempStruct).cs, u, Damage_High(Data(TempStruct).lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call GroupRemoveUnit(Temp,u)
endif
endfunction
private function Move_Dummy takes nothing returns nothing
local Data S = GetTimerData(GetExpiredTimer())
local real xd
local real yd
local real xd2
local real yd2
local integer i = 0
set TempStruct = S
if S.ticks > 0 then
set S.ticks = S.ticks - 1
set S.stage = 2
loop
exitwhen i>=ANGLES
set xd = GetUnitX(S.du[i])
set yd = GetUnitY(S.du[i])
set xd2 = xd+(SLIDE_SPEED*SLIDE_INTERVAL)*Cos(I2R(i*(360/(ANGLES)))*bj_DEGTORAD)
set yd2 = yd+(SLIDE_SPEED*SLIDE_INTERVAL)*Sin(I2R(i*(360/(ANGLES)))*bj_DEGTORAD)
call GroupRefresh(Temp)
call GroupEnumUnitsInRange(Temp, xd2, yd2, Range_Small(), Condition(function Smaller_GroupEm))
call ForGroup(Temp, function Deal_Damage)
call SetUnitX(S.du[i],xd2)
call SetUnitY(S.du[i],yd2)
set i = i+1
endloop
else
set S.stage = 3
call S.destroy()
endif
endfunction
private function Effects takes nothing returns nothing
local Data a = Data.create(GetTriggerUnit())
local real xu = GetUnitX(a.cs)
local real yu = GetUnitY(a.cs)
local real dx
local real dy
local integer i = 0
local SpellData array S
set a.t = NewTimer()
set Temp = NewGroup()
call DestroyEffect(AddSpecialEffect(EFFECT_C,xu,yu))
set a.stage = 1
loop
exitwhen i>=ANGLES
set dx = xu+EXPLOSION_OFFSET*Cos(I2R(i*(360/(ANGLES)))*bj_DEGTORAD)
set dy = yu+EXPLOSION_OFFSET*Sin(I2R(i*(360/(ANGLES)))*bj_DEGTORAD)
set TempStruct = a
call DestroyEffect(AddSpecialEffect(EFFECT_1, dx, dy))
call GroupRefresh(Temp)
call GroupEnumUnitsInRange(Temp, dx, dy,Range_Medium(), Condition(function GroupEm))
call ForGroup(Temp, function Deal_Damage)
set S[i] = SpellData.create(GetTriggerUnit())
set S[i] = S[i].create(xu,yu,bj_RADTODEG * Atan2(dy - yu, dx - xu))
call UnitAddAbility(a.du[i],LOCUST)
set S[i].fxpath=(DUMMY_EFFECT)
set S[i].collisionSize=(Range_Small())
set S[i].setTargetPoint(xu+I2R(DISTANCE)*Cos(I2R(i*(360/(ANGLES)))*bj_DEGTORAD),yu+I2R(DISTANCE)*Sin(I2R(i*(360/(ANGLES)))*bj_DEGTORAD))
set i = i+1
endloop
set a.ticks = DISTANCE
call SetTimerData(a.t,a)
call TimerStart(a.t, SLIDE_INTERVAL, true, function Move_Dummy)
call ReleaseGroup(Temp)
endfunction
private function Init takes nothing returns nothing
local trigger t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t,Condition(function Spell_Check))
call TriggerAddAction(t,function Effects)
endfunction
endscope
Though, I getting tons of errors, and as soon as I fix one of them, more appear
My current error is "Syntax Error" on the middle line here:
JASS:
set S[i].collisionSize=(Range_Small())
set S[i].setTargetPoint(xu+I2R(DISTANCE)*Cos(I2R(i*(360/(ANGLES)))*bj_DEGTORAD),yu+I2R(DISTANCE)*Sin(I2R(i*(360/(ANGLES)))*bj_DEGTORAD))
set i = i+1
Any ideas ? :S
Btw, the normal spell thread is here:
http://www.wc3c.net/showthread.php?t=107076&page=4