| 01-13-2008, 09:36 PM | #1 |
Hi everyone, I've been trying to create a spell called mana beam, which is nothing fancy, just shoots a beam. To better visualize it, I'm using a dummy unit with a large scaling value and the Avatar of Vengeance model. I'm using a timer to move it really fast by setting a new position as opposed to ordering it. There's no actual damage going on yet in the script, I didn't implement any yet. Trying to get the visual down first.... Here it is, it kinda works, but it shoots the beam in a random direction instead of where I'm casting it. The beam has to reach the target location (point of cast) + 1000 in order to be removed, so the map crashes after about 5-10 times casting as well. At least I think thats what's causing the crashes. Anyway, I've been staring at this for awhile, pretty tired atm and was wondering if anyone can point out where my math fails or could give me some advice on how to make this work, because I can't find my error. Thanks. Edit.. Boy I feel like a fool.. I fixed it with this new function.. I was using DistanceBetweenCoords where I should have been using Coords2Angle .. JASS:function Coords2Angle takes real x1, real y1, real x2, real y2 returns real return bj_RADTODEG * Atan2(y2 - y1, x2 - x1) endfunction function DistanceBetweenCoords takes real x1, real y1, real x2, real y2 returns real return SquareRoot((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1)) endfunction struct manabeam timer t = CreateTimer() unit u // Caster unit v // Mana Beam player p // Owner of Caster location e // End destination (Point of Cast) real a // Angle static method create takes nothing returns manabeam local manabeam data = manabeam.allocate() set data.u = GetSpellAbilityUnit() set data.p = GetOwningPlayer(data.u) set data.e = GetSpellTargetLoc() set data.v = CreateUnit(data.p, 'h009', GetUnitX(data.u), GetUnitY(data.u), 270) set data.a = Coords2Angle(GetUnitX(data.v), GetUnitY(data.v), GetLocationX(data.e), GetLocationY(data.e)) return data endmethod method onDestroy takes nothing returns nothing call RemoveUnit(.v) call FlushHandleLocals(.t) call PauseTimer(.t) call DestroyTimer(.t) call RemoveLocation(.e) endmethod endstruct function MageManaBeamCond takes nothing returns boolean return GetSpellAbilityId() == 'A00E' endfunction function StartBeam takes nothing returns nothing local timer t = GetExpiredTimer() local manabeam data = GetHandleInt(t, "beam") local real BeamX = GetUnitX(data.v) local real BeamY = GetUnitY(data.v) local real NewX = BeamX + 8 * Cos(data.a * bj_DEGTORAD) local real NewY = BeamY + 8 * Sin(data.a * bj_DEGTORAD) local real Dist = DistanceBetweenCoords(NewX, NewY, GetLocationX(data.e) + 1000, GetLocationY(data.e) + 1000) call SetUnitPosition(data.v, NewX, NewY) if Dist <= 100 then call data.destroy() endif set t = null endfunction function MageManaBeam takes nothing returns nothing local manabeam data = manabeam.create() call SetHandleInt(data.t, "beam", data) call TimerStart(data.t, .003, true, function StartBeam) endfunction function InitTrig_MageManaBeam takes nothing returns nothing set gg_trg_MageManaBeam = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(gg_trg_MageManaBeam, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(gg_trg_MageManaBeam, Condition(function MageManaBeamCond)) call TriggerAddAction(gg_trg_MageManaBeam, function MageManaBeam) endfunction |
| 01-13-2008, 10:12 PM | #2 |
JASS:local real Dist = Coords2Angle (NewX, NewY, GetLocationX(data.e), GetLocationY(data.e)) Didn't really see anything wrong with your angles, at least that would cause it to work incorrectly (plenty of ways to optimize though). But you're setting Distance to an angle, then checking if it's less than 100 o.o. |
| 01-13-2008, 11:27 PM | #3 |
Well I finally finished it and it actually works like i envisioned it. I do have one concern, something I still do not know about structs. There are two places I retrieve a struct from a handle, one a timer another a trigger. But, I only have destroy one time, because if I destroy it in the trigger then everything stops working. My questions are, am I destroying the structs properly, and is anything leaking here? JASS:library MageManaBeam initializer ManaVars globals integer array MANADMG endglobals function ManaVars takes nothing returns nothing set MANADMG[1] = 320 set MANADMG[2] = 680 set MANADMG[3] = 925 set MANADMG[4] = 1460 endfunction endlibrary function Coords2Angle takes real x1, real y1, real x2, real y2 returns real local real x = x2 - x1 local real y = y2 - y1 return bj_RADTODEG * Atan2(y, x) endfunction function DistanceBetweenCoords takes real x1, real y1, real x2, real y2 returns real local real x = x2 - x1 local real y = y2 - y1 return SquareRoot(x * x + y * y) endfunction struct manabeam timer t = CreateTimer() trigger z = CreateTrigger() unit u // Caster unit v // Mana Beam player p // Owner of Caster location e // End destination (Point of Cast) real a // Angle real x // X of location e real y // Y of location e integer i // Level of Ability boolean b // Allows the dying special effect only once. static method create takes nothing returns manabeam local manabeam data = manabeam.allocate() set data.b = true set data.u = GetSpellAbilityUnit() set data.p = GetOwningPlayer(data.u) set data.i = GetUnitAbilityLevel(data.u, 'A00E') set data.e = GetSpellTargetLoc() set data.x = GetLocationX(data.e) set data.y = GetLocationY(data.e) set data.v = CreateUnit(data.p, 'h009', GetUnitX(data.u), GetUnitY(data.u), 270) set data.a = Coords2Angle(GetUnitX(data.v), GetUnitY(data.v), data.x, data.y) return data endmethod method onDestroy takes nothing returns nothing call RemoveUnit(.v) call DestroyTrigger(.z) call FlushHandleLocals(.t) call PauseTimer(.t) call DestroyTimer(.t) call RemoveLocation(.e) endmethod endstruct function MageManaBeamCond takes nothing returns boolean return GetSpellAbilityId() == 'A00E' endfunction function ManaBeamDamage takes nothing returns nothing local trigger t = GetTriggeringTrigger() local manabeam data = GetHandleInt(t, "beam") local unit u = GetTriggerUnit() if IsUnitEnemy(u, data.p) then call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\ManaFlare\\ManaFlareBoltImpact.mdl", u, "origin")) call UnitDamageTarget(data.v, u, MANADMG[data.i], true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS) endif set t = null set u = null endfunction function StartBeam takes nothing returns nothing local timer t = GetExpiredTimer() local manabeam data = GetHandleInt(t, "beam") local real BeamX = GetUnitX(data.v) local real BeamY = GetUnitY(data.v) local real NewX = BeamX + 8 * Cos(data.a * bj_DEGTORAD) local real NewY = BeamY + 8 * Sin(data.a * bj_DEGTORAD) local real Dist = DistanceBetweenCoords(NewX, NewY, data.x, data.y) call SetUnitPosition(data.v, NewX, NewY) // Very cheesy attempt to try to line up the explode effect with beam death. if Dist <= 400 and data.b then call DestroyEffect(AddSpecialEffect("Units\\NightElf\\Wisp\\WispExplode.mdl", data.x, data.y)) set data.b = false endif if Dist <= 10 then call data.destroy() endif set t = null endfunction function MageManaBeam takes nothing returns nothing local manabeam data = manabeam.create() local trigger t = CreateTrigger() call SetHandleInt(data.t, "beam", data) call SetHandleInt(data.z, "beam", data) call TriggerRegisterUnitInRange(data.z, data.v, 250, null) call TriggerAddAction(data.z, function ManaBeamDamage) call TimerStart(data.t, .004, true, function StartBeam) set t = null endfunction function InitTrig_MageManaBeam takes nothing returns nothing set gg_trg_MageManaBeam = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(gg_trg_MageManaBeam, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(gg_trg_MageManaBeam, Condition(function MageManaBeamCond)) call TriggerAddAction(gg_trg_MageManaBeam, function MageManaBeam) endfunction |
