13 years
edited 13 years
Need Help debugging a system please test map,
I am having trouble with a spell called Meteor Shower, the first cast works the second cast buggs, it sends way to many meteors, the meteors don't deal damage and some of them don't move.
I am having trouble with a spell called Meteor Shower, the first cast works the second cast buggs, it sends way to many meteors, the meteors don't deal damage and some of them don't move.
1 library Effects uses Target
2 globals3 private force eval = CreateForce()
4 spelleffect RUNNING
5 spellprojectile PROJECTILE
6 private boolean FINISHED
7 endglobals8 function ReturnEffect takes boolean continue returns nothing
9 set FINISHED = continue
10 endfunction11 module Rarray12 real d0
13 real d1
14 real d2
15 real d3
16 method operator [] takes integer i returns real
17 if i < 2 then
18 if i == 0 then
19 return d020 endif21 return d122 endif23 if i == 2 then
24 return d225 endif26 return d327 endmethod28 method operator []= takes integer i, real r returns nothing
29 if i < 2 then
30 if i == 0 then
31 set d0 = r
32 return33 endif34 set d1 = r
35 return36 endif37 if i == 2 then
38 set d2 = r
39 return40 endif41 set d3 = r
42 return43 endmethod44 endmodule45 struct spelleffect_root extends array
46 static thistype array Rc
47 static integer c = 0
48 boolexpr action
49 integer instance
50 integer model
51 static method allocate takes nothing returns thistype
52 local thistype this = Rc[0]
53 if 0 == this then
54 set this = c+1
55 set c = this
56 else57 set Rc[0] = Rc[this]
58 endif59 return this
60 endmethod61 method deallocate takes nothing returns nothing
62 if 0 == this then
63 return64 endif65 set Rc[this]= Rc[0]
66 set Rc[0] = this
67 endmethod68 implement Rarray69 static method create takes nothing returns thistype
70 local thistype this = allocate()
71 return this
72 endmethod73 /*static method createEx takes boolexpr b, real d0, real d1, real d2, real d3 returns thistype74 local thistype this = allocate()75 set action = b76 set this[0]= d077 set this[1]= d178 set this[2] = d279 set this[3] = d380 set instance = 081 return this82 endmethod*/83 method unlock takes nothing returns nothing
84 if this!= 0 then
85 set instance = instance-1
86 if instance < 1 then
87 call this.deallocate()
88 endif89 endif90 endmethod91 method lock takes nothing returns nothing
92 set instance = instance+1
93 endmethod94 endstruct95 struct spelleffect extends array
96 static thistype array Rc
97 static integer c = 0
98 boolexpr action
99 Spell_Cast spell
100 integer next
101 integer model
102 Target caster
103 Target target
104 spelleffect master
105 static method allocate takes nothing returns thistype
106 local thistype this = Rc[0]
107 if 0 == this then
108 set this = c+1
109 set c = this
110 else111 set Rc[0] = Rc[this]
112 endif113 return this
114 endmethod115 method deallocate takes nothing returns nothing
116 set Rc[this]= Rc[0]
117 set Rc[0] = this
118 endmethod119 method destroy takes nothing returns nothing
120 if 0 == this then
121 return122 endif123 debug call BJDebugMsg("Destroying Effect "+I2S(this))
124 if this.isProxy then
125 call target.unlock()
126 call caster.unlock()
127 call spell.unlock()
128 endif129 set this.action = null
130 call this.deallocate()
131 endmethod132 method operator isProxy takes nothing returns boolean
133 return master != 0
134 endmethod135 implement Rarray136 static method create takes spelleffect_root root, Spell_Cast boss returns thistype
137 local thistype this = allocate()
138 set action = root.action
139 set this[0] = root[0]
140 set this[1] = root[1]
141 set this[2] = root[2]
142 set this[3] = root[3]
143 set this.spell = boss
144 set this.model = root.model
145 set this.target = boss.target
146 set this.master = 0
147 set this.caster = boss.caster
148 set boss[boss.effects]= this
149 set boss.effects = boss.effects+1
150 return this
151 endmethod152 method run takes nothing returns boolean
153 set RUNNING = this
154 set FINISHED = true
155 call ForceEnumPlayersCounted(eval,action,1)
156 return FINISHED157 endmethod158 static method createProxy takes spelleffect master,Target caster, Target t returns thistype
159 local thistype this = allocate()
160 set .action = master.action
161 set this[0]= master[0]
162 set this[1]= master[1]
163 set this[2]= master[2]
164 set this[3]= master[3]
165 set .next = master.next
166 set .master = master
167 set .target = t
168 set .spell = master.spell
169 set .model = master.model
170 set .caster = caster
171 call caster.lock()
172 call t.lock()
173 call .spell.lock()
174 return this
175 endmethod176 endstruct177 function CreateSpellEffect takes boolexpr b, real d0, real d1, real d2, real d3, integer model returns spelleffect_root
178 local spelleffect_root this = spelleffect_root.create()
179 set this.action = b
180 set this[0] = d0
181 set this[1] = d1
182 set this[2] = d2
183 set this[3] = d3
184 set this.model = model
185 return this
186 endfunction187 endlibrary
1 library SpellGenerator /* v0.2.3.0
2 *************************************************************************************3 *4 * Enables the generation of spells in game and can also be used 5 * to easily make new spells with just a few keystrokes6 *7 *************************************************************************************8 *9 * */uses /*
10 * */ Target /*
11 * */ SFX /*
12 * */ Effects /*
13 * */ SpellProjectile/*
14 ***************************************************************************************15 *16 * struct Spell extends array17 * boolean permanent whether to keep or destroy the spell when it has no instances18 *19 * method operator [] takes integer i returns integer20 * this retur21 * method operator []= takes integer i integer returns nothing22 * be warned you can leak effects if you do not unlock the effect first23 * method lock takes nothing returns nothing24 * locks the spell preventing it from getting destroyed25 * method unlock takes nothing returns nothing26 * when you are done with a spell you should unlock it27 * has no effect on permanent spells28 *29 * static method createEx takes nothing returns Spell30 * 31 *****/32 private module allocator
33 static integer array recycle
34 static integer c = 0
35 static method allocate takes nothing returns thistype
36 local thistype this = recycle[0]
37 if this == 0 then
38 set this = c+1
39 set c = this
40 else41 set recycle[0] = recycle[this]
42 endif43 endmodule44 private module deallocate
45 method deallocate takes nothing returns nothing
46 if 0 == this then
47 call BJDebugMsg("Attempted to deallocate a null struct")
48 return49 endif50 set recycle[this] = recycle[0]
51 set recycle[0] = this
52 endmethod53 endmodule54 private module serarray
55 spelleffect_root d0
56 spelleffect_root d1
57 spelleffect_root d2
58 spelleffect_root d3
59 method operator [] takes integer i returns spelleffect_root
60 if i < 2 then
61 if i == 0 then
62 return d063 endif64 return d165 endif66 if i == 2 then
67 return d268 endif69 return d370 endmethod71 method operator []= takes integer i, integer what returns nothing
72 if i < 2 then
73 if i ==0 then
74 set d0 = what
75 return76 endif77 set d1 = what
78 return79 endif80 if i == 2 then
81 set d2 = what
82 return83 endif84 set d3 = what
85 endmethod86 endmodule87 private module searray
88 spelleffect d0
89 spelleffect d1
90 spelleffect d2
91 spelleffect d3
92 method operator [] takes integer i returns spelleffect
93 if i < 2 then
94 if i == 0 then
95 return d096 endif97 return d198 endif99 if i == 2 then
100 return d2101 endif102 return d3103 endmethod104 method operator []= takes integer i, integer what returns nothing
105 if i < 2 then
106 if i ==1 then
107 set d1 = what
108 return109 endif110 set d0 = what
111 return112 endif113 if i == 2 then
114 set d2 = what
115 return116 endif117 set d3 = what
118 endmethod119 endmodule120
121 struct Spell_Cast extends array
122 Target caster
123 Target target
124 Spell root
125 //integer current126 integer instance
127 integer effects
128 implement searray129 implement allocator130 //set instance = 0131 set effects = 0
132 return this
133 endmethod134 implement deallocate135 method lock takes nothing returns nothing
136 set .instance = .instance+1
137 endmethod138 method destroy takes nothing returns nothing
139 debug call BJDebugMsg("Destroyed Spell"+I2S(this))
140 call this[0].destroy()
141 call this[1].destroy()
142 call this[2].destroy()
143 call this[3].destroy()
144 call root.unlock()
145 call target.unlock()
146 call caster.unlock()
147 call deallocate()
148 endmethod149 method unlock takes nothing returns nothing
150 if .instance > 0 then
151 set .instance = .instance-1
152 if .instance == 0 then
153 call destroy()
154 endif155 endif156 endmethod157 method core takes spelleffect current returns boolean
158 local spelleffect Snext = 0
159 local integer next
160 debug call BJDebugMsg("Running core for "+I2S(current))
161 if current < 0 then
162 set next = 1
163 set Snext = this[0]
164 elseif current == 0 then
165 call unlock()
166 return true
167 else168 set next = current.next
169 if current.isProxy then
170
171 debug call BJDebugMsg(I2S(current)+" is a Proxy")
172 if next != 0 then
173 debug call BJDebugMsg("creating new Proxy")
174 set Snext = spelleffect.createProxy(this[next],current.caster, current.target)
175 endif 176 call current.destroy()
177 else178 set Snext = this[next]
179 endif180 endif181 if next == 0 then
182 call unlock()
183 call BJDebugMsg("Next = 0 .instance ="+I2S(this.instance))
184 return true
185 endif186
187 if Snext.run() then
188 debug call BJDebugMsg("The effect ran, going to next effect")
189 call core(Snext)
190 return false
191 endif192 debug call BJDebugMsg("The effect ran, and is waiting to finish")
193 return false
194 endmethod195 static method create takes Spell root, Target t returns thistype
196 local thistype this = allocate()
197 local integer i = 0
198 set target = t
199 set instance = 1
200 call t.lock()
201 loop202 if root[i] == 0 then
203 set i = i -1
204 exitwhen true
205 endif206 set this[i] = spelleffect.create( root[i], this)
207 set this[i].next = i+1
208 set i = i+1
209 exitwhen i == 4
210 endloop211 set this[i].next = 0
212 set .root = root
213 return this
214 endmethod215 endstruct216 struct Spell extends array
217 boolean permanent
218 private integer instance
219 implement serarray220 implement allocator221 return this
222 endmethod223 implement deallocate224 method destroy takes nothing returns nothing
225 call deallocate()
226 call this[0].unlock()
227 call this[1].unlock()
228 call this[2].unlock()
229 call this[3].unlock()
230 endmethod231 static method create takes spelleffect_root first returns thistype
232 local thistype this = allocate()
233 set this[0] = first
234 return this
235 endmethod236 static method createEx takes spelleffect_root s0, spelleffect_root s1, spelleffect_root s2, spelleffect_root s3, boolean destroy returns thistype
237 local thistype this = allocate()
238 call s0.lock()
239 call s1.lock()
240 call s2.lock()
241 call s3.lock()
242 set this[0] = s0
243 set this[1] = s1
244 set this[2] = s2
245 set this[3] = s3
246 set permanent = not destroy
247 return this
248 endmethod249 method lock takes nothing returns nothing
250 set .instance = .instance+1
251 endmethod252 method unlock takes nothing returns nothing
253 set .instance = .instance-1
254 if not permanent and .instance < 0 then
255 call destroy()
256 endif257 endmethod258 method cast takes unit caster, Target target returns boolean // the return value is whether the spell completed every thing instantly, or if it is waiting.
259 local Spell_Cast cast = Spell_Cast.create(this,target)
260 call lock()
261 //call cast.lock()262 set cast.caster = Target[caster]
263 call cast.caster.lock()
264 //set cast.target = target265 //call cast.caster.lock()266 return cast.core(-1)
267 endmethod268 endstruct269 function CreateSpell takes spelleffect_root s0, spelleffect_root s1, spelleffect_root s2, spelleffect_root s3, boolean destroy returns Spell
270 local Spell this = Spell.allocate()
271 call s0.lock()
272 call s1.lock()
273 call s2.lock()
274 call s3.lock()
275 static if DEBUG_MOD then
276 if s0 == 0 then
277 call BJDebugMsg("Trying to create a spell with a null first effect")
278 return 0
279 endif280 endif281 set this[0] = s0
282 set this[1] = s1
283 set this[2] = s2
284 set this[3] = s3
285 set this.permanent = not destroy
286 return this
287 endfunction288 endlibrary
1 library LibraryOfEffects uses Effects, SpellGenerator
2 globals3 private boolexpr epcast
4 private spelleffect array next
5 private spelleffect array prev
6 private real array Sangle
7 private real array Eangle
8 private integer array left
9 private integer total = 0
10 private real array time
11 private real array distance
12 private timer EP_Timer = CreateTimer()
13 private constant real PERIOD = .0325000
14 endglobals15 private function ep takes nothing returns nothing
16 local spelleffect this = next[0]
17 local real angle
18 local real dis
19 call BJDebugMsg("its working total ="+I2S(total))
20 if total == 0 then
21 set next[0] = 0
22 set prev[0] = 0
23 return24 endif25 if this.spell[1].action == epcast then
26 call BJDebugMsg("Effect "+I2S(this.spell[1])+" has the wrong action")
27 endif28 loop29 exitwhen 0 == this
30 set time[this] = time[this]-PERIOD
31 if time[this]<= 0 then
32 set angle = GetRandomReal(Sangle[this],Eangle[this])
33 set dis = GetRandomReal(0,distance[this])
34 35 call this.spell.core(spelleffect.createProxy(this,this.caster, /*
36 */Target.create(this.target.x+Cos(angle)*dis,this.target.y+Sin(angle)*dis,0)))
37
38 set left[this] = left[this]-1
39 if left[this]<= 0 then
40 call BJDebugMsg("In EP periodic With next["+I2S(this)+"]="+I2S(next[this])+" and prev["+I2S(this)+"]="+I2S(prev[this]))
41 set next[prev[this]]=next[this]
42 set prev[next[this]]=prev[this]
43
44 45 set total = total-1
46 47 call this.spell.unlock()//this is neccessary as it always calls back to the core via proxy
48 if this.isProxy then
49 call this.destroy()//also neccessary to prevent leaks
50 endif51 if total == 0 then
52 set next[0] = 0
53 set prev[0] = 0
54 return55 endif56 57 else58 set time[this] = time[this]+this[1]
59 endif60 endif61
62 set this = next[this]
63 endloop64 call TimerStart(EP_Timer,PERIOD,false,function ep)
65 endfunction66 function ep_cast takes nothing returns boolean
67 local spelleffect this = RUNNING
68 local real face = GetUnitFacing(this.spell.caster.unit)
69 call BJDebugMsg("Running ep_Cast for "+I2S(RUNNING))
70 set epcast = Filter(function ep_cast)
71 //call BJDebugMsg("checking if it is already running")72 if total == 0 then
73 //call BJDebugMsg("Nope, it wasn't")74 set next[0] = this
75 set prev[0] = this
76 set next[this] = 0
77 set prev[this] = 0
78 call TimerStart(EP_Timer,PERIOD,false,function ep)
79 else80 //call BJDebugMsg("Still not broken yet")81 set next[this] = 0
82 set prev[this] = prev[0]
83 set next[prev[0]]=this
84 set prev[0] = this
85 endif86 set total = total +1
87 call this.spell.lock()
88 set distance[this] = this[2]
89 set Sangle[this] = (face-this[3])*bj_DEGTORAD
90 set Eangle[this] = (face+this[3])*bj_DEGTORAD
91 set left[this] = R2I(this[0])
92 //call BJDebugMsg("left[this]="+I2S(left[this]))93 call ReturnEffect(false)
94 return true
95 endfunction96 endlibrary
1 library SpellProjectile uses Missile Target Effects
2 globals3 boolexpr RegProjectile
4 boolexpr Meteor
5 endglobals6 struct spellprojectile extends array
7 static method onRemove takes Missile this returns boolean
8 local spelleffect se = this.data
9 debug call BJDebugMsg("Missile for Effect "+I2S(se)+" Calling core")
10 call se.spell.core(se)
11 return true
12 endmethod13
14 // meteor 0 is fall time, 1 is height, 2 makes it circle as it falls15 static method meteor takes nothing returns boolean
16 local Spell_Cast spell = RUNNING.spell
17 local real x = RUNNING.target.x
18 local real y = RUNNING.target.y
19 local integer i = 0
20 local real sp = 5/RUNNING[0]*0.0325000
21 local group g
22 local Target u23 local Missile new// = Missile.create(x,y,65,x+1000*Cos(a),y+1000*Sin(a),0)
24 debug call BJDebugMsg("Running Meteor RUNNING="+I2S(RUNNING)+"\nRUNNING[0]="+R2S(RUNNING[0])+"Target="+I2S(RUNNING.target))
25 if RUNNING.target.isGroup then
26 set g = CreateGroup()
27 call GroupAddGroup(g,RUNNING.target.group)
28 loop29 set u = Target[FirstOfGroup(g)]
30 exitwhen 0 == u
31 set new = Missile.createLoc(AdvLoc.create(u.x+5, u.y, u.z+RUNNING[1]),AdvLoc.create(u.x,u.z,u.z))
32 set new.target = u.unit
33 //set new.height = RUNNING[1]34 set new.open = RUNNING[2]
35 set new.speed=sp
36 set new.model=GetSFXPath(RUNNING.model)
37 set new.source=spell.caster.unit
38 set new.collision=80
39 //set new.distance = 20040 set new.data = spelleffect.createProxy(RUNNING, spell.caster, u)
41 call launch(new)
42 endloop43 call DestroyGroup(g)
44 set g =null
45 else46
47 set u = RUNNING.target
48 if RUNNING.target.isUnit then
49 set new = Missile.createLoc(AdvLoc.create(x+5, y, u.z+RUNNING[1]),AdvLoc.create(x,y,u.z))
50 set new.target = RUNNING.target.unit
51 else52
53 set new = Missile.createLoc(AdvLoc.create(x+5, y, 500/*+RUNNING[1]*/),AdvLoc.create(x,y,u.z))
54 endif55 //set new.arc= RUNNING[1]56 //set new.height = u.z+RUNNING[1]57 set new.speed=sp
58 set new.model=GetSFXPath(RUNNING.model)
59 set new.source=spell.caster.unit
60 //set new.distance = 20061 set new.open = RUNNING[2]
62 set new.collision=80
63 set new.data = RUNNING
64 call launch(new)
65 endif66 call ReturnEffect(false)
67 return true
68 endmethod69
70 implement MissileStruct71 static method onInit takes nothing returns nothing
72 set RegProjectile= Filter(function spellprojectile.reg)
73 set Meteor = Filter(function thistype.meteor)
74 endmethod75 endstruct76 endlibrary
1 scope SpellTest initializer init
2 private function test_cast takes nothing returns boolean
3 if GetSpellAbilityId() == 'A001' then
4 debug call BJDebugMsg("casting Spell")
5 call EffectDepository_pillaroffire.cast(GetTriggerUnit(),Target.create(GetSpellTargetX(),GetSpellTargetY(),0))
6 debug call BJDebugMsg("Spell cast")
7 elseif GetSpellAbilityId() == 'A002' then
8 debug call BJDebugMsg("castingMeteor")
9 call EffectDepository_MeteorShower.cast(GetTriggerUnit(),Target.create(GetSpellTargetX(),GetSpellTargetY(),0))
10 endif11 return false
12 endfunction13
14 function init takes nothing returns nothing
15 //debug call BJDebugMsg("Creating Spell PillarofFire")16 //set EffectDepository_pillaroffire = CreateSpell(CreateSpellEffect(RegProjectile, 900, 150, 35, 0,GetSFX(SFX_FIRE_EFFECTS, 1, 6)),CreateSpellEffect(Filter(function EffectDepository_pof_cast), 300, 15, 3, 0,GetSFX(SFX_FIRE_EFFECTS, 0, 4)),CreateSpellEffect(Filter(function EffectDepository_pof_cast),300,5,12,0,GetSFX(SFX_FIRE_EFFECTS, 1, 3)),0,false)17 //debug call BJDebugMsg("SpellCreated "+I2S(EffectDepository_pillaroffire))18 set EffectDepository_pillaroffire = CreateSpell(CreateSpellEffect(Filter(function spellprojectile.meteor), 1, 600, 0, 0,GetSFX(SFX_FIRE_EFFECTS, 1, 3)),CreateSpellEffect(Filter(function EffectDepository_pof_cast), 300, 15, 3, 0,GetSFX(SFX_FIRE_EFFECTS, 0, 6))/*
19 */,CreateSpellEffect(Filter(function EffectDepository_pof_cast),300,5,12,0,GetSFX(SFX_FIRE_EFFECTS, 0, 3)),0,false)
20 set EffectDepository_MeteorShower = CreateSpell(/*
21 */CreateSpellEffect(Filter(function ep_cast),12,.15,300,180,0),/*
22 */CreateSpellEffect(Filter(function spellprojectile.meteor),1,600,0,0,GetSFX(SFX_FIRE_EFFECTS, 1, 3)),/*
23 */CreateSpellEffect(Filter(function EffectDepository_Pure_Damage),125,25,0,0,GetSFX(SFX_MAGIC_EFFECTS, 0, 3)),/*
24 */0,false)
25 // set EffectDepository_MeteorShower = CreateSpell(/*26 // */CreateSpellEffect(Filter(function ep_cast),1,0.13,300,180,0),/*27 // */CreateSpellEffect(Filter(function spellprojectile.meteor),1,600,0,0,GetSFX(SFX_FIRE_EFFECTS, 1, 3)),/*28 // */0,0,false)29 call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_CAST,function test_cast)
30 endfunction31 endscope
1 library EffectDepository uses Effects SpellProjectile
2 3 globals4 public Spell pillaroffire5 public Spell MeteorShower6 private spelleffect array pof_next
7 private spelleffect array pof_prev
8 public boolexpr Damage
9 private integer pof_start = 0
10 private integer pof_t= 0
11 private timer pof = CreateTimer()
12 private group temp = CreateGroup()
13 private real pof_period = .5
14 endglobals15
16
17 private function forDamageGroup takes nothing returns nothing
18 call UnitDamageTarget(RUNNING.spell.caster.unit, GetEnumUnit(),RUNNING[1],false,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_ENHANCED,null)
19 call DestroyEffect( AddSpecialEffectTarget(GetSFXPath(RUNNING.model),GetEnumUnit(),"chest"))
20 endfunction21 public function Pure_Damage takes nothing returns boolean
22 local Target target = RUNNING.target
23 local unit u
24 if target.isUnit or target.isDestructable then
25 call DestroyEffect( AddSpecialEffectTarget(GetSFXPath(RUNNING.model),RUNNING.target.widget,"chest"))
26 call UnitDamageTarget(RUNNING.spell.caster.unit, target.widget,RUNNING[1],false,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_ENHANCED,null)
27 elseif target.isGroup then
28 call ForGroup(target.group,function Pure_Damage)
29 else30 call GroupEnumUnitsInRange(temp,target.x,target.y,RUNNING[0],null)
31 call DestroyEffect( AddSpecialEffect(GetSFXPath(RUNNING.model),target.x,target.y))
32 loop33 set u = FirstOfGroup(temp)
34 exitwhen null == u
35 call GroupRemoveUnit(temp,u)
36
37 call UnitDamageTarget(RUNNING.spell.caster.unit, u,RUNNING[1],false,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_ENHANCED,null)
38 endloop39 endif40 call ReturnEffect(true)
41 return true
42 endfunction43
44

