| 08-23-2009, 11:18 AM | #1 | |
Hi! As I can't seem to get the help I want in my spell thread I thought I'd post here too :D 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...): 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 :D @@// //@@ ¤ GroupUtils, made by Rising_Dusk :D @@// //@@ ¤ 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 :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 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[i]) set yd = GetUnitY(a.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(a.du[i],xd2) call SetUnitY(a.du[i],yd2) set i = i+1 endloop else set a.stage = 3 loop exitwhen i >=ANGLES set xd = GetUnitX(a.du[i]) set yd = GetUnitY(a.du[i]) call DestroyEffect(a.e[i]) 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[i]) 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[i] = CreateUnit(a.p,DUMMY_ID,xu,yu,bj_RADTODEG*Atan2(dy-yu,dx-xu)) call UnitAddAbility(a.du[i],LOCUST) set a.e[i] = AddSpecialEffectTarget(DUMMY_EFFECT,a.du[i],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 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 this line: 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 |
| 08-23-2009, 12:23 PM | #2 |
call, not set. Ayway, I wouldn't use .setTargetPoint for this, I would simply give the xecollider a starting speed (set S[i].speed = SLIDE_SPEED), direction (set S[i].direction = i*2*bj_PI/ANGLES) and duration (set S[i].expirationTime = TIME) and then let it go. Now that I look at your code, it's fairly complicated and there are plenty of confusing things happening (for example, why call GroupRefresh before a GroupEnum? That does nothing.), it might be easier to start from scratch than editing it. |
| 08-23-2009, 12:31 PM | #3 |
Ok :( EDIT: This seems to work, but I have not idea what to put in there :S JASS:static method create takes unit u returns Data local Data d = Data.allocate(1.,1.,1.) set d.caster = u set d.owner = GetOwningPlayer(d.caster) return d endmethod EDIT: Here's my current code... JASS:scope TormentalWrath initializer Init // requires GroupUtils, xebasic, xefx, xecollider, BoundSentinel /////////////////////////////////////////////////////////////////////////////////////////////////////////////// //***********************************************************************************************************// //@@//////////////////////////////////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 angles 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 globals // Don't touch these globals ! \\ private integer TempStruct = 0 endglobals // Don't touch these globals ! \\ private struct Data extends xecollider xecollider xe player play unit cast real cx real cy static method create takes unit u returns Data local Data d = Data.allocate(1.,1.,1.) set d.cast = u set d.play = GetOwningPlayer(d.cast) set d.cx = GetUnitX(d.cast) set d.cy = GetUnitY(d.cast) return d endmethod method onUnitHit takes unit target returns nothing endmethod method onDestroy takes nothing returns nothing endmethod endstruct // 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 // Filter! \\ private function Filters takes nothing returns boolean return IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD) != true or GetUnitTypeId(GetFilterUnit()) != 0 and IsUnitEnemy(GetFilterUnit(), Data(TempStruct).play) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false endfunction // End of Configuration!\\ private function Spell_Conditions takes nothing returns boolean return GetSpellAbilityId() == SPELL_ID endfunction private function Spell_Actions takes nothing returns nothing local Data d = Data.create(GetTriggerUnit()) local integer i = 0 local real angle = i*2*bj_PI/ANGLES loop exitwhen i == ANGLES set d.xe = xecollider.create(d.cx, d.cy, angle) set d.fxpath=(DUMMY_EFFECT) set d.collisionSize=(Range_Small()) set d.owner=(d.play) set d.speed = SLIDE_SPEED set d.expirationTime = TIME set i = i + 1 endloop 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_Conditions)) call TriggerAddAction(t,function Spell_Actions) endfunction endscope Right now, the fx's are created, but only 1 of them moves... The other ones are destroyed right after creation :( And also, I still don't know what to put in the local Data d = Data.allocate(1.,1.,1.) line :S Btw, how would I go about to use the onUnitHit method ? :S |
| 08-24-2009, 12:38 PM | #4 |
Bump ! C'mon ! :D Please help, I really need this, and for further work too :D |
| 08-24-2009, 01:01 PM | #5 |
Wel, for starters, the spell is fairly complicated, I still don't know how exactly it's supposed to work. In it's most simple form (just launching a bunch of projectiles outwards in a circle), all you need is one xecollider-extending struct of which you create N instances when the spell is cast. JASS:private struct Projectile extends xecollider unit caster // You will probably need this unit when dealing damage. method onUnitHit takes unit hitTarget returns nothing // The code you write here will run whenever the projectile hits a unit. endmethod method onDestroy takes nothing returns nothing // Do the end explosions stuff here. endmethod endstruct private function onSpellCast takes nothing returns nothing local integer i=0 local unit caster=GetTriggerUnit() local real x=GetUnitX(caster) local real y=GetUnitY(caster) local real a=GetUnitFacing(caster)*bj_DEGTORAD //Facing angle in radians. local Projectile p loop exitwhen i>=PROJECTILE_COUNT set p=Projectile.create(x,y,a) set p.caster=caster set p.direction=a set p.speed=SLIDE_SPEED set p.expirationTime=TIME set a=a+(2*bj_PI/PROJECTILE_COUNT) set i=i+1 endloop endfunction |
| 08-24-2009, 01:42 PM | #6 |
Ok... So this is the current code... But now absolutely nothing happens :( JASS:scope TormentalWrath initializer Init // requires GroupUtils, xebasic, xefx, xecollider, BoundSentinel /////////////////////////////////////////////////////////////////////////////////////////////////////////////// //***********************************************************************************************************// //@@//////////////////////////////////Tormental Wrath, Made by Komaqtion///////////////////////////////////@@// //@@ Now using XE! @@// //@@ @@// //@@ @@// //@@ How to import: @@// //@@ @@// //@@ ¤ First copy the ability "Tormental Wrath" and the unit "Dummy" and change the constant @@// //@@ "SPELL_ID" to the rawcode of the newly copied spell, then go into the trigger called @@// //@@ "xebasic", and change "XE_DUMMY_UNITID" to the Dummy's rawcode ! @@// //@@ Then you need to import Vexorian's dummy.mdx file from this map, or another, and change @@// //@@ the "Dummy" unit's model to it. 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 ! @@// //@@ ¤ The dummy.mdx, BoundSentinel and the XE libraries, all made by Vexorian ! @@// //@@ ¤ GroupUtils, made by Rising_Dusk ! @@// //@@ @@// //@@ @@// //@@ Credits to: @@// //@@ @@// //@@ * Vexorian, for the dummy.mdx file, BoundSentinel and the XE libraries ! @@// //@@ * Anitarf and Pyrogasm, for their help on the rewrite of it :D @@// //@@ * Rising_Dusk, for making GroupUtils, and helping me a bit on the forum ! @@// //@@ @@// //@@ And, of course, so many thanks to all of the many helpfull people at WC3C.net @@// //@@ who has helped get is spell working! @@// //@@ @@// //@@ @@// //@@ 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! // Rawcodes! Change these rawcodes to the ones on your map :D (Note: To change the Dummy unit's ID, you'll need to go into the trigger called "xebasic", and change "XE_DUMMY_UNITID" !)\\ private constant integer SPELL_ID = '0000' // ID of the spell! private constant integer LOCUST = 'Aloc' // ID of the "Locust" ability! (Might not need changing) // 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 angles 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!\\ // V // This one is for the DPS on the projectiles! \\ V \\ private function Damage_Small takes integer lv returns real return DAMAGE_FACTOR * lv endfunction // V // This one is for the explosions around the caster! \\ V \\ private function Damage_Medium takes integer lv returns real return 50 + lv * DAMAGE_FACTOR * 25 endfunction // V // This one is for the explosions at the very end! \\ V \\ private function Damage_High takes integer lv returns real return 50 + lv * DAMAGE_FACTOR * 50 endfunction // Range functions!\\ // V // This one is for the DPS on the projectiles! \\ V \\ private function Range_Small takes nothing returns real return RANGE_FACTOR * 5 endfunction // V // This one is for the explosions around the caster! \\ V \\ private function Range_Medium takes nothing returns real return RANGE_FACTOR * 10 endfunction // V // This one is for the explosions at the very end! \\ V \\ private function Range_High takes nothing returns real return RANGE_FACTOR * RANGE_FACTOR endfunction // V V !!!!! Filters are below these globals, and the struct !!!!! V V \\ globals // Don't touch these globals ! \\ private integer TempStruct = 0 private group Temp endglobals // Don't touch these globals ! \\ // V V !!!!! Filters are below these globals, and the struct !!!!! V V \\ private struct Data extends xecollider player play unit cast real cx real cy integer lvl integer stage group grp method onUnitHit takes unit hitTarget returns nothing if hitTarget != .cast and IsUnitAlly(hitTarget, .play) and GetUnitTypeId(hitTarget) != XE_DUMMY_UNITID then call UnitDamageTarget(Data(TempStruct).cast, hitTarget, Damage_Small(Data(TempStruct).lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE) call GroupAddUnit(Data(TempStruct).grp,hitTarget) call GroupRemoveUnit(Temp,hitTarget) endif endmethod method onDestroy takes nothing returns nothing set .stage = 3 call .flash(EFFECT_2) endmethod endstruct // V ! Filters ! V \\ // V ! Filters ! V \\ // V ! Filters ! V \\ // V ! Filters ! V \\ // V ! Filters ! V \\ // V ! Filters ! V \\ private function Filters takes nothing returns boolean return IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD) != true or GetUnitTypeId(GetFilterUnit()) != 0 and IsUnitEnemy(GetFilterUnit(), Data(TempStruct).play) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false endfunction // End of Configuration!\\ private function Deal_Damage takes nothing returns nothing local unit u = GetEnumUnit() if Data(TempStruct).stage == 1 then call UnitDamageTarget(Data(TempStruct).cast, u, Damage_Medium(Data(TempStruct).lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE) call GroupAddUnit(Data(TempStruct).grp,u) call GroupRemoveUnit(Temp,u) endif if Data(TempStruct).stage == 3 then call UnitDamageTarget(Data(TempStruct).cast, u, Damage_High(Data(TempStruct).lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE) call GroupRemoveUnit(Temp,u) endif endfunction private function Spell_Conditions takes nothing returns boolean return GetSpellAbilityId() == SPELL_ID endfunction private function Filters_Group takes nothing returns boolean return Filters() and IsUnitInGroup(GetFilterUnit(), Temp) endfunction private function Spell_Actions takes nothing returns nothing local Data d local integer i = 0 local unit u = GetTriggerUnit() local real x=GetUnitX(u) local real y=GetUnitY(u) local real x2 local real y2 local real a=GetUnitFacing(u)*bj_DEGTORAD set Temp = NewGroup() loop exitwhen i >= ANGLES set d = Data.create(d.cx, d.cy, a) set d.fxpath=(DUMMY_EFFECT) set d.collisionSize=(Range_Small()) set d.direction=a set d.speed = SLIDE_SPEED set d.expirationTime = TIME set d.play = GetOwningPlayer(u) set d.cast = u set d.cx = x set d.cy = y set d.lvl = GetUnitAbilityLevel(u, SPELL_ID) set d.stage = 1 set TempStruct = d set d.grp = NewGroup() set x2 = x+EXPLOSION_OFFSET*a set y2 = y+EXPLOSION_OFFSET*a call DestroyEffect(AddSpecialEffect(EFFECT_1, x2, y2)) call GroupEnumUnitsInRange(Temp, x2, y2,Range_Medium(), Condition(function Filters_Group)) call ForGroup(Temp, function Deal_Damage) set d.stage = 2 set a=a+(2*bj_PI/ANGLES) set i = i + 1 endloop 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_Conditions)) call TriggerAddAction(t,function Spell_Actions) endfunction endscope |
| 08-24-2009, 01:50 PM | #7 |
JASS:set d = Data.create(d.cx, d.cy, a) |
| 08-24-2009, 01:53 PM | #8 |
Thanks :D Just one more question... How would I go about changing this to be the same angles as the colliders ? :S (It's for the explosions a bit "nearer" the caster :D) JASS:set dx = xu+EXPLOSION_OFFSET*Cos(I2R(i*(360/(ANGLES)))*bj_DEGTORAD) set dy = yu+EXPLOSION_OFFSET*Sin(I2R(i*(360/(ANGLES)))*bj_DEGTORAD) |
| 08-24-2009, 11:47 PM | #9 | |
Quote:
JASS:set x2 = x+EXPLOSION_OFFSET*Cos(a) set y2 = y+EXPLOSION_OFFSET*Sin(a) |
| 08-25-2009, 06:07 AM | #10 |
Ok then :D Thanks !!! Just 1 more question... The projectiles no longer deal damage :( And this debug msg doesn't show :( ("Should dmg!") How would I go about making it damage all units near it ? :S Because it seems that this doesn't work: JASS:method onUnitHit takes unit hitTarget returns nothing //call BJDebugMsg("Might dmg!") if hitTarget != .cast and IsUnitAlly(hitTarget, .play) and GetUnitTypeId(hitTarget) != XE_DUMMY_UNITID then call UnitDamageTarget(.cast, hitTarget, Damage_Small(.lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE) call GroupAddUnit(.grp,hitTarget) call GroupRemoveUnit(Temp,hitTarget) call BJDebugMsg("Should dmg!") endif endmethod |
| 08-25-2009, 12:53 PM | #11 |
IsUnitAlly()? Should the spell only do damage to allied units? If not, that's where your problem is. |
| 08-25-2009, 01:12 PM | #12 |
Yeah XD Noticed that now XD It's supposed to be IsUnitAlly(hitTarget,.cast) != true XD EDIT: Ok... Think this is the final product ! Take a look, and see if there's something which can be improved ? :o I used the loopControl method from xecollider to do the periodic damage for the projectiles, and works great now :D Please, any notes and suggestions are very welcome !! Otherwise I'll submit this :D:D JASS:scope TormentalWrath initializer Init // requires GroupUtils, xebasic, xefx, xecollider, BoundSentinel /////////////////////////////////////////////////////////////////////////////////////////////////////////////// //***********************************************************************************************************// //@@//////////////////////////////////Tormental Wrath, Made by Komaqtion///////////////////////////////////@@// //@@ Now using XE! @@// //@@ @@// //@@ @@// //@@ How to import: @@// //@@ @@// //@@ ¤ First copy the ability "Tormental Wrath" and the unit "Dummy" and change the constant @@// //@@ "SPELL_ID" to the rawcode of the newly copied spell, then go into the trigger called @@// //@@ "xebasic", and change "XE_DUMMY_UNITID" to the Dummy's rawcode ! @@// //@@ Then you need to import Vexorian's dummy.mdx file from this map, or another, and change @@// //@@ the "Dummy" unit's model to it. 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 ! @@// //@@ ¤ The dummy.mdx, BoundSentinel and the XE libraries, all made by Vexorian ! @@// //@@ ¤ GroupUtils, made by Rising_Dusk ! @@// //@@ @@// //@@ @@// //@@ Credits to: @@// //@@ @@// //@@ * Vexorian, for the dummy.mdx file, BoundSentinel and the XE libraries ! @@// //@@ * Anitarf and Pyrogasm, for their help on the rewrite of it :D @@// //@@ * Rising_Dusk, for making GroupUtils, and helping me a bit on the forum ! @@// //@@ @@// //@@ And, of course, so many thanks to all of the many helpfull people at WC3C.net @@// //@@ who has helped get is spell working! @@// //@@ @@// //@@ @@// //@@ 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 EFFECT_T = "Abilities\\Spells\\Items\\AIfb\\AIfbSpecialArt.mdl" // Effect on the damaged units! private constant string DUMMY_EFFECT = "Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl" // Effect on the moving dummy! // Rawcodes! Change these rawcodes to the ones on your map :D (Note: To change the Dummy unit's ID, you'll need to go into the trigger called "xebasic", and change "XE_DUMMY_UNITID" !) \\ private constant integer SPELL_ID = '0000' // ID of the spell! // 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 = 1. // Just a simple real to make it easy to change the range! private constant integer ANGLES = 16 // The number of angles 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 TIME = 2.5 // How long it takes for the spell to complete! private constant real INTERVAL = XE_ANIMATION_PERIOD // How frequently the dummy moves! (This should be changed in the "xebasic" trigger instead of here! Change the constant called XE_ANIMATION_PERIOD ;)) private constant real SLIDE_SPEED = TIME/INTERVAL * TIME // How much the dummy effect moves each second! (It's 200. atm :D) private constant real EXPLOSION_OFFSET = 200. // How much range the first explosions are offset the casters porition! endglobals // Damage functions!\\ // V // This one is for the DPS on the projectiles! \\ V \\ private function Damage_Small takes integer lv returns real return DAMAGE_FACTOR * lv endfunction // V // This one is for the explosions around the caster! \\ V \\ private function Damage_Medium takes integer lv returns real return 50 + lv * DAMAGE_FACTOR * 25 endfunction // V // This one is for the explosions at the very end! \\ V \\ private function Damage_High takes integer lv returns real return 50 + lv * DAMAGE_FACTOR * 50 endfunction // Range functions!\\ // V // This one is for the DPS on the projectiles! \\ V \\ private function Range_Small takes nothing returns real return RANGE_FACTOR * 100 endfunction // V // This one is for the explosions around the caster! \\ V \\ private function Range_Medium takes nothing returns real return RANGE_FACTOR * 10 endfunction // V // This one is for the explosions at the very end! \\ V \\ private function Range_High takes nothing returns real return RANGE_FACTOR * RANGE_FACTOR endfunction // V V !!!!! Filters are below these globals, and the struct !!!!! V V \\ globals // Don't touch these globals ! \\ private integer TempStruct private group Temp = null private filterfunc Filterz private integer tempData endglobals // Don't touch these globals ! \\ // V V !!!!! Filters are below these globals and the struct !!!!! V V \\ private struct Data extends xecollider player play unit cast real cx real cy integer lvl group grp static method Deal_Damage takes nothing returns nothing local Data this = tempData local unit u = GetEnumUnit() call UnitDamageTarget(.cast, u, Damage_High(.lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE) call GroupRemoveUnit(Temp,u) set u = null endmethod // private method onUnitHit takes unit hitTarget returns nothing // if hitTarget != .cast and IsUnitAlly(hitTarget, .play) != true and GetUnitTypeId(hitTarget) != XE_DUMMY_UNITID then // call GroupAddUnit(.grp,hitTarget) // call GroupRemoveUnit(Temp,hitTarget) // endif // endmethod private method onDestroy takes nothing returns nothing call .flash(EFFECT_2) call GroupEnumUnitsInRange(Temp, .x, .y, Range_High(), Filterz) call ForGroup(Temp,function Data.Deal_Damage) call ReleaseGroup(.grp) endmethod private static method Fire_Damage takes nothing returns nothing local Data this = tempData call DestroyEffect(AddSpecialEffectTarget(EFFECT_T, GetEnumUnit(), "chest")) call UnitDamageTarget(.cast, GetEnumUnit(), Damage_Small(.lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE) call GroupRemoveUnit(.grp, GetEnumUnit()) endmethod private method loopControl takes nothing returns nothing set tempData = this call GroupEnumUnitsInRange(.grp, .x, .y, Range_Small(), Filterz) call ForGroup(.grp, function Data.Fire_Damage) endmethod endstruct // V ! Filters ! V \\ // V ! Filters ! V \\ // V ! Filters ! V \\ // V ! Filters ! V \\ // V ! Filters ! V \\ // V ! Filters ! V \\ private function Filters takes nothing returns boolean return IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD) != true or GetUnitTypeId(GetFilterUnit()) != 0 and IsUnitEnemy(GetFilterUnit(), Data(TempStruct).play) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false endfunction // End of Configuration!\\ private function Spell_Conditions takes nothing returns boolean return GetSpellAbilityId() == SPELL_ID endfunction private function Filters_Group takes nothing returns boolean return IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD) != true or GetUnitTypeId(GetFilterUnit()) != 0 and IsUnitEnemy(GetFilterUnit(), Data(TempStruct).play) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitInGroup(GetFilterUnit(), Temp) == false endfunction private function Deal_Damage takes nothing returns nothing local unit u = GetEnumUnit() call UnitDamageTarget(Data(TempStruct).cast, u, Damage_Medium(Data(TempStruct).lvl), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE) call GroupRemoveUnit(Temp,u) endfunction private function Spell_Actions takes nothing returns nothing local Data d local integer i = 0 local unit u = GetTriggerUnit() local real x=GetUnitX(u) local real y=GetUnitY(u) local real x2 local real y2 local real a=GetUnitFacing(u)*bj_DEGTORAD set Temp = NewGroup() loop exitwhen i >= ANGLES set d = Data.create(x, y, a) set d.fxpath=(DUMMY_EFFECT) set d.collisionSize=(Range_Small()) set d.direction=a set d.speed = SLIDE_SPEED set d.expirationTime = TIME set d.play = GetOwningPlayer(u) set d.cast = u set d.cx = x set d.cy = y set d.lvl = GetUnitAbilityLevel(u, SPELL_ID) set TempStruct = d set d.grp = NewGroup() set x2 = x+EXPLOSION_OFFSET*Cos(a) set y2 = y+EXPLOSION_OFFSET*Sin(a) call DestroyEffect(AddSpecialEffect(EFFECT_1, x2, y2)) call GroupEnumUnitsInRange(Temp, x2, y2,Range_Medium(),Condition(function Filters_Group) ) call ForGroup(Temp, function Deal_Damage) set a=a+(2*bj_PI/ANGLES) set i = i + 1 endloop 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_Conditions)) call TriggerAddAction(t,function Spell_Actions) set Filterz = Filter(function Filters) endfunction endscope |
| 08-26-2009, 01:39 PM | #13 |
BumP :P |
| 08-26-2009, 02:52 PM | #14 |
This is more an issue with the spell design than spell code, but I find it much more intuitive when spell projectiles deal their damage once when they hit a unit, instead of dealing damage over time as long as they are in contact with the unit. That way, the player has a much better idea of how much damage the spell will actually do. |
| 08-26-2009, 03:02 PM | #15 |
*In the documentation, you don't have to explain how to setup xebasic, you can assume people have already done that. *Get rid of the INTERVAL constant. *TIME/INTERVAL * TIME is always equal to time. *You could use xedamage to deal damage. Don't worry, it is not as hard as using xecollider. Just create one xedamage at map initialization and use it when needed. |
