| 07-16-2008, 03:57 PM | #1 |
hi im new here, i usally hang out in THW but no one there could seem to solve my problem. well here's my problem when i first cast this spell it works perfectly but when i cast it a second time is just blows up directly(after end cast) at the casters position. i have tried to remove the lighting in case i leak one of those, that was not. i think it have to do with tabels im not sure. p.s, i have played some with the code that why it can look abit messed up JASS://!=============================================================================!\\ //! Orb of Zeus by Ciebron. !\\ //! Give Credits is you use this in your map !\\ //! --------------------------------------------------------------------------- !\\ //! Channels a orb made from the god Zeus him self. the long u channel !\\ //! the more the ball will grow, when release it will be such force that the !\\ //! ball will fly up in the air and strike lighting from above and when !\\ //! it lands it will deal damage to nearby units !\\ //! --------------------------------------------------------------------------- !\\ //! Requires: !\\ //! ¯¯¯¯¯¯¯¯¯ !\\ //! - Object Editor - A hero !\\ //! - Object Editor - The Orb of Zeuz ability !\\ //! - Object Editor - The Orb Dummy Unit !\\ //! - Trigger Editor - This Trigger !\\ //! - Trigger Editor - CSData - by Vexorian !\\ //! - Trigger Editor - CSSaftey - by Vexorian !\\ //! - Trigger Editor - Table - by Vexorian !\\ //! ([url]http://www.wc3campaigns.net/showthread.php?t=80534[/url]) !\\ //! --------------------------------------------------------------------------- !\\ scope OrbofZeus initializer Init //!=============================================================================!\\ //!=================================Setup Starts================================!\\ //!=============================================================================!\\ globals private constant integer Abil_id = 'A000' //!Ability rawcode private constant integer Dum_id = 'h000' //!Dummy rawcode private constant string ESFX = "Abilities\\Spells\\Items\\AIlb\\AIlbSpecialArt.mdl" //!SFX when the lightning hit the target private constant string GSFX = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl" //! Effect that gets created @ the ground when the ball hits it private constant string Lighttype = "FORK" //!lightning type private constant real LightningRange = 400. //! Range of the lightnings private constant integer MaximumTargets = 3 //! Maximum nr of target allowed (cant be 0 duh) private constant real Maxdist = 1500. //! distance the orb will move private constant real Time = 3. //! Time to Travel Maxdist private constant real Curve = 6. //! adjust this if the ball goes to high or to low for ur taste (lower, the higher the ball will get and the other way around) private constant string AttachPoint = "origin" //! dont touch these private group OrbofZeus = CreateGroup() private HandleTable activeTable endglobals private function SetDamage takes real a returns real return a*1.5 //!damage formula, a is based b.size (atm it deals 1.5*b.size) endfunction //!=============================================================================!\\ //!=================================Setup Ends==================================!\\ //!=============================================================================!\\ private struct Data unit caster unit dummy unit array victims [MaximumTargets] real cos real sin real size real z real dist real fulltime real time real dmg real distance real Movedist real lightningtime lightning array Lightning [MaximumTargets] integer count player play timer t static method create takes nothing returns Data local Data d = Data.allocate() local location loc = GetSpellTargetLoc() local real tx = GetLocationX(loc) local real ty = GetLocationY(loc) local real x local real y local real angle local real scale local integer index = 0 //! just for debugging loop exitwhen index >= MaximumTargets set d.Lightning[index] = null set index = index + 1 endloop //! setup stuff set d.caster = GetTriggerUnit() set x = GetUnitX(d.caster) set y = GetUnitY(d.caster) set angle = Atan2(ty-y,tx-x) set d.play = GetOwningPlayer(d.caster) set d.cos = Cos(angle) set d.sin = Sin(angle) set d.dummy = CreateUnit(d.play,Dum_id,x+100*d.cos,y+100*d.sin,0.) set d.size = 1 set scale = 1+(0.25*d.size) set d.Movedist = (Maxdist/Time)/(1./.035) set d.t = NewTimer() set d.count = 0 set d.z = 20 call SetUnitScale(d.dummy,scale,scale,scale) call SetCSData(d.t, d) call TimerStart(d.t,1.,true,function Data.OrbGrow) call RemoveLocation(loc) set loc = null return d endmethod static method OrbGrow takes nothing returns nothing local Data d = GetCSData(GetExpiredTimer()) local real scale //! make's the orb grow set d.size = d.size + 1 set scale = 1+(0.25*d.size) call SetUnitScale(d.dummy,scale,scale,scale) endmethod static method Move takes nothing returns nothing local Data d = GetCSData(GetExpiredTimer()) local real x = GetUnitX(d.dummy)+d.Movedist*d.cos // New Y cord local real y = GetUnitY(d.dummy)+d.Movedist*d.sin // New X cord local group g //group for picking units local unit victim //used in the loop to damage and create lightnings local integer index = 0 //used in the group to set array index set d.dist = d.dist + d.Movedist set d.z = JumpParabola(d.dist,Maxdist,Curve) call SetUnitFlyHeight(d.dummy,d.z,0.) //! check if the unit is @ the ground, if it is we make it blow up if d.z > 0. then //! if the lightning's have been alive for .25 sec we destroy them else we move them if d.lightningtime >= .25 then loop exitwhen index >= d.count if d.Lightning[index] != null then call DestroyLightning(d.Lightning[index]) set d.Lightning[index] = null else call BJDebugMsg("Tried to destroy a lightning that dont exist") endif set index = index + 1 endloop set d.count = 0 set index = 0 else loop exitwhen index >= d.count call MoveLightningEx(d.Lightning[index],true,x,y,GetUnitFlyHeight(d.dummy)+50,GetUnitX(d.victims[index]),GetUnitY(d.victims[index]),GetUnitFlyHeight(d.victims[index])+50) set index = index + 1 endloop set index = 0 endif //! check if the x & y cords isnt outside the mapbounds if MinX < x and MaxX > x and MinY < y and MaxY > y then call SetUnitX(d.dummy,x) call SetUnitY(d.dummy,y) endif //! if .5 sec have gone since the last lightning's we make new ones if d.lightningtime >= .5 then set g = NewGroup() call GroupEnumUnitsInRange(g,x,y,500,Filter(function Data.filter)) set d.count = 0 loop set victim = FirstOfGroup(g) exitwhen victim == null or index >= MaximumTargets call GroupRemoveUnit(g,victim) set d.victims[index] = null set d.victims[index] = victim set d.Lightning[index] = AddLightningEx("FORK",true,x,y,GetUnitFlyHeight(d.dummy)+50,GetUnitX(victim),GetUnitY(victim),GetUnitFlyHeight(victim)+50) call UnitDamageTarget(d.caster,victim,100.,false,false,ATTACK_TYPE_MAGIC,null,null) call DestroyEffect(AddSpecialEffectTarget(ESFX,victim,AttachPoint)) set index = index + 1 endloop set d.count = index set d.lightningtime = 0. call ReleaseGroup(g) endif else set g = NewGroup() call GroupEnumUnitsInRange(g,x,y,500,Filter(function Data.filter)) call DestroyEffect(AddSpecialEffect(GSFX,x,y)) //! dmg units where the orb blew up loop set victim = FirstOfGroup(g) exitwhen victim == null call GroupRemoveUnit(g,victim) call UnitDamageTarget(d.caster,victim,100.,false,false,ATTACK_TYPE_MAGIC,null,null) endloop call ReleaseGroup(g) call d.destroy() endif set d.time = d.time + .035 set d.lightningtime = d.lightningtime + .035 set g = null endmethod static method filter takes nothing returns boolean local Data d = GetCSData(GetExpiredTimer()) local unit f = GetFilterUnit() local boolean ok = GetWidgetLife(f) > .405 and not IsUnitType(f,UNIT_TYPE_STRUCTURE) and not IsUnitType(f,UNIT_TYPE_MAGIC_IMMUNE) and IsUnitEnemy(f,GetOwningPlayer(d.caster)) set f = null return ok endmethod method onDestroy takes nothing returns nothing local integer index = 0 //! destroys the lightning loop exitwhen index >= .count if .Lightning[index] != null then call DestroyLightning(.Lightning[index]) set .Lightning[index] = null else call BJDebugMsg("Tried to destroy a lightning that dont exist") endif set index = index + 1 endloop call KillUnit(.dummy) call ReleaseTimer(.t) endmethod endstruct private function PreLoad takes nothing returns nothing call Preload(GSFX) call Preload(ESFX) call RemoveUnit(CreateUnit(Player(15),Dum_id,0,0,0)) endfunction private function onend takes nothing returns boolean local Data d local unit u = GetTriggerUnit() if IsUnitInGroup(u,OrbofZeus) and activeTable.exists(u) then set d = activeTable[u] set d.dmg = SetDamage(d.size) call ReleaseTimer(d.t) set d.t = NewTimer() call SetCSData(d.t,d) call TimerStart(d.t,.035,true,function Data.Move) //! remove the caster from the group call GroupRemoveUnit(OrbofZeus,u) //! flush the caster's table call activeTable.flush(d.caster) endif set u = null return false endfunction private function conds takes nothing returns boolean local Data d if GetSpellAbilityId() == Abil_id then set d = Data.create() //! set a table to the caster set activeTable[d.caster] = d //! add the caster to a group for "caster" call GroupAddUnit(OrbofZeus,d.caster) endif return false endfunction private function Init takes nothing returns nothing local trigger t =CreateTrigger() local integer index = 0 loop call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null) set index = index + 1 exitwhen index == bj_MAX_PLAYER_SLOTS endloop call TriggerAddCondition(t,Condition( function conds ) ) set t = CreateTrigger() set index = 0 loop call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_ENDCAST,null) set index = index + 1 exitwhen index == bj_MAX_PLAYER_SLOTS endloop call TriggerAddCondition(t,Condition(function onend)) //! this spell use table to get rid of dynamic triggers set activeTable = Table.create() call PreLoad() set t = null endfunction endscope |
| 07-16-2008, 09:56 PM | #2 |
Don't use //! for comments, you are already using vJass and in vjass //! is for preprocessors. You should initialize the struct's members (they do not begin at 0.0 automatically) |
