| 12-04-2007, 01:14 AM | #1 |
Here it is. The demo is lame but it gets the point across. Try making your own effects then tell me if you find any bugs. Someone tell me if the documentation makes it understandable or not. Library code: JASS:library DummyEffect requires TimedEvent globals //*** Configuration *** private integer DummyUnitID = 'e000' private real UpdatesPerSecond = 40. endglobals //========================================================= private keyword DummyScaler private keyword DummyFader globals private location Loc1 = Location(0., 0.) private location Loc2 = Location(0., 0.) private timer AttachTimer = CreateTimer() private DummyEffect array AttachedDummies private integer AttachedDummies_N = -1 private timer ScaleTimer = CreateTimer() private DummyScaler array DummyScalers private integer DummyScalers_N = -1 private timer FadeTimer = CreateTimer() private DummyFader array DummyFaders private integer DummyFaders_N = -1 endglobals private function DummyEffectExpired takes integer de returns boolean call DummyEffect(de).onExpire() return false endfunction private function DummyEffectDied takes integer de returns boolean call DummyEffect(de).remove() return false endfunction private function MoveAttachedDummies takes nothing returns nothing local integer c = AttachedDummies_N local DummyEffect de local unit u local real x local real y loop exitwhen c < 0 set de = AttachedDummies[c] set u = de.attachedto if de.attached and GetUnitTypeId(de.u) != 0. then set x = GetUnitX(u) set y = GetUnitY(u) call MoveLocation(Loc1, x, y) call SetUnitX(de.u, x + de.XOffset) call SetUnitY(de.u, y + de.YOffset) call MoveLocation(Loc2, x + de.XOffset, y + de.YOffset) call SetUnitFlyHeight(de.u, GetUnitFlyHeight(u) + de.ZOffset + GetLocationZ(Loc1) - GetLocationZ(Loc2), 0.) else set de.attachedto = null set AttachedDummies[c] = AttachedDummies[AttachedDummies_N] set AttachedDummies_N = AttachedDummies_N - 1 if de.attached then call de.destroy() endif if AttachedDummies_N == -1 then call PauseTimer(AttachTimer) return endif endif set c = c - 1 endloop set u = null endfunction private function ScaleDummies takes nothing returns nothing local integer c = DummyScalers_N local DummyScaler ds local DummyEffect de loop exitwhen c < 0 set ds = DummyScalers[c] set de = ds.de if ds.count > 0 and GetUnitTypeId(de.u) != 0. then set de.scale = de.scale + ds.scalerate set ds.count = ds.count - 1 call SetUnitScale(de.u, de.scale, de.scale, de.scale) else call ds.destroy() set DummyScalers[c] = DummyScalers[DummyScalers_N] set DummyScalers_N = DummyScalers_N - 1 if DummyScalers_N == -1 then call PauseTimer(ScaleTimer) return endif endif set c = c - 1 endloop endfunction private function FadeDummies takes nothing returns nothing local integer c = DummyFaders_N local DummyFader df local DummyEffect de loop exitwhen c < 0 set df = DummyFaders[c] set de = df.de if df.count > 0 and GetUnitTypeId(de.u) != 0. then set de.red = de.red + df.redrate set de.green = de.green + df.greenrate set de.blue = de.blue + df.bluerate set de.alpha = de.alpha + df.alpharate set df.count = df.count - 1 call SetUnitVertexColor(de.u, R2I(de.red*255+0.5), R2I(de.green*255+0.5), R2I(de.blue*255+0.5), R2I(de.alpha*255+0.5)) else call df.destroy() set DummyFaders[c] = DummyFaders[DummyFaders_N] set DummyFaders_N = DummyFaders_N - 1 if DummyFaders_N == -1 then call PauseTimer(FadeTimer) return endif endif set c = c - 1 endloop endfunction //========================================================= private struct DummyScaler DummyEffect de real scalerate integer count static method create takes DummyEffect de, real scaleBy, real time returns DummyScaler local DummyScaler ds = DummyScaler.allocate() set ds.de = de set ds.scalerate = scaleBy / UpdatesPerSecond / time set ds.count = R2I(time * UpdatesPerSecond + 0.5) set DummyScalers_N = DummyScalers_N + 1 set DummyScalers[DummyScalers_N] = ds if DummyScalers_N == 0 then call TimerStart(ScaleTimer, 1./UpdatesPerSecond, true, function ScaleDummies) endif return ds endmethod endstruct private struct DummyFader DummyEffect de real redrate real greenrate real bluerate real alpharate integer count static method create takes DummyEffect de, real redBy, real greenBy, real blueBy, real alphaBy, real time returns DummyFader local DummyFader df = DummyFader.allocate() set df.de = de set df.redrate = redBy / UpdatesPerSecond / time set df.greenrate = greenBy / UpdatesPerSecond / time set df.bluerate = blueBy / UpdatesPerSecond / time set df.alpharate = alphaBy / UpdatesPerSecond / time set df.count = R2I(time * UpdatesPerSecond + 0.5) set DummyFaders_N = DummyFaders_N + 1 set DummyFaders[DummyFaders_N] = df if DummyFaders_N == 0 then call TimerStart(FadeTimer, 1./UpdatesPerSecond, true, function FadeDummies) endif return df endmethod endstruct //========================================================= private interface DummyEffectInterface string ModelPath = "" real XOffset = 0. real YOffset = 0. real ZOffset = 0. real DeathDuration = 5. method onCreate takes nothing returns nothing defaults nothing method onKill takes nothing returns nothing defaults nothing method onExpire takes nothing returns nothing defaults nothing endinterface struct DummyEffect extends DummyEffectInterface unit u effect e unit attachedto = null boolean attached = false real scale = 1. real red real green real blue real alpha static method makeType takes integer typeid, real x, real y, real height returns DummyEffect local DummyEffect de = DummyEffectInterface.create(typeid) set de.u = CreateUnit(Player(15), DummyUnitID, 0., 0., 0.) call SetUnitPathing(de.u, false) call UnitAddAbility(de.u, 'Amrf') call UnitAddAbility(de.u, 'Aloc') call SetUnitX(de.u, x) call SetUnitY(de.u, y) call SetUnitFlyHeight(de.u, height, 0.) set de.e = AddSpecialEffectTarget(de.ModelPath, de.u, "origin") call de.onCreate() return de endmethod static method makeTypeOn takes integer typeid, unit u returns DummyEffect local DummyEffect de = DummyEffect.makeType(typeid, GetUnitX(u), GetUnitY(u), GetUnitFlyHeight(u)) call de.attachTo(u) return de endmethod method attachTo takes unit u returns nothing set .attached = true if .attachedto != null then set .attachedto = u else set .attachedto = u set AttachedDummies_N = AttachedDummies_N + 1 set AttachedDummies[AttachedDummies_N] = this if AttachedDummies_N == 0 then call TimerStart(AttachTimer, 1./UpdatesPerSecond, true, function MoveAttachedDummies) endif endif endmethod method unattach takes nothing returns nothing set .attached = false endmethod method addExpiration takes real time returns nothing call TimedEvent(time, this, Callback.DummyEffectExpired) endmethod method scaleTo takes real scaleTo returns nothing set .scale = scaleTo call SetUnitScale(.u, scaleTo, scaleTo, scaleTo) endmethod method scaleToTimed takes real scaleTo, real time returns nothing call DummyScaler.create(this, scaleTo - .scale, time) endmethod method scaleBy takes real scaleBy returns nothing set .scale = .scale + scaleBy call SetUnitScale(.u, .scale, .scale, .scale) endmethod method scaleByTimed takes real scaleBy, real time returns nothing call DummyScaler.create(this, scaleBy, time) endmethod method fadeTo takes real redTo, real greenTo, real blueTo, real alphaTo returns nothing set .red = redTo set .green = greenTo set .blue = blueTo set .alpha = alphaTo call SetUnitVertexColor(.u, R2I(redTo*255+0.5), R2I(greenTo*255+0.5), R2I(blueTo*255+0.5), R2I(alphaTo*255+0.5)) endmethod method fadeToTimed takes real redTo, real greenTo, real blueTo, real alphaTo, real time returns nothing call DummyFader.create(this, redTo - .red, greenTo - .green, blueTo - .blue, alphaTo - .alpha, time) endmethod method fadeBy takes real redBy, real greenBy, real blueBy, real alphaBy returns nothing set .red = .red + redBy set .green = .green + greenBy set .blue = .blue + blueBy set .alpha = .alpha + alphaBy call SetUnitVertexColor(.u, R2I(.red*255+0.5), R2I(.green*255+0.5), R2I(.blue*255+0.5), R2I(.alpha*255+0.5)) endmethod method fadeByTimed takes real redBy, real greenBy, real blueBy, real alphaBy, real time returns nothing call DummyFader.create(this, redBy, greenBy, blueBy, alphaBy, time) endmethod method kill takes nothing returns nothing if .e != null then call DestroyEffect(.e) set .e = null endif if .u != null then call KillUnit(.u) call TimedEvent(.DeathDuration, this, Callback.DummyEffectDied) endif call .onKill() endmethod method remove takes nothing returns nothing if .e != null then call DestroyEffect(.e) set .e = null endif if .u != null then call RemoveUnit(.u) set .u = null endif if not .attached then call .destroy() endif endmethod method onExpire takes nothing returns nothing call .kill() endmethod endstruct //! textmacro DEInit takes NAME static method make takes real x, real y, real z returns $NAME$ return DummyEffect.makeType($NAME$.typeid, x, y, z) endmethod static method makeOn takes unit u returns $NAME$ return DummyEffect.makeTypeOn($NAME$.typeid, u) endmethod //! endtextmacro endlibrary Demo code: JASS:// Most of these examples are pretty stupid but they get the point across. //========================================================= struct Web extends DummyEffect //! runtextmacro DEInit("Web") string ModelPath = "Abilities\\Spells\\Undead\\Web\\Web_AirTarget.mdl" real XOffset = 32. method onCreate takes nothing returns nothing call .scaleToTimed(3., 1.) call .addExpiration(1.) endmethod method onExpire takes nothing returns nothing call .fadeToTimed(GetRandomReal(0., 1.), GetRandomReal(0., 1.), GetRandomReal(0., 1.), GetRandomReal(0., 1.), 1.) call .addExpiration(1.) endmethod endstruct //========================================================= struct RedOrb extends DummyEffect //! runtextmacro DEInit("RedOrb") string ModelPath = "Abilities\\Spells\\Orc\\Bloodlust\\BloodlustTarget.mdl" boolean grow = true method onCreate takes nothing returns nothing call .addExpiration(1.) endmethod method onExpire takes nothing returns nothing if .grow then call .scaleToTimed(GetRandomReal(5., 10.), 1.) set .grow = false else call .scaleToTimed(GetRandomReal(0., 5.), 1.) set .grow = true endif call .addExpiration(1.) endmethod endstruct //========================================================= struct Shell extends DummyEffect //! runtextmacro DEInit("Shell") string ModelPath = "Abilities\\Spells\\Undead\\AntiMagicShell\\AntiMagicShell.mdl" method onCreate takes nothing returns nothing call .fadeTo(1., 1., 1., 0.5) call .scaleTo(2.5) call .addExpiration(0.) endmethod method onExpire takes nothing returns nothing call .scaleToTimed(GetRandomReal(-5., 5.), GetRandomReal(1., 6.)) call .addExpiration(GetRandomReal(0., 3.)) endmethod endstruct //========================================================= struct FollowOrb extends DummyEffect //! runtextmacro DEInit("FollowOrb") string ModelPath = "Abilities\\Weapons\\WitchDoctorMissile\\WitchDoctorMissile.mdl" real XOffset = 150. real YOffset = 150. real ZOffset = 150. real DeathDuration = 1. method onCreate takes nothing returns nothing call .scaleByTimed(5., 15.) call .addExpiration(15.) endmethod method onKill takes nothing returns nothing call .scaleByTimed(100., 1.) endmethod endstruct //========================================================= function InitTrig_Test takes nothing returns nothing call SetCameraPosition(0., 0.) call CreateFogModifierRectBJ(true, Player(0), FOG_OF_WAR_VISIBLE, bj_mapInitialPlayableArea) call Web.makeOn(gg_unit_hfoo_0001) call RedOrb.make(0., 0., 100.) call Shell.make(500., 0., 500.) call FollowOrb.makeOn(gg_unit_hfoo_0001) endfunction New version posted. Again. |
