Executor
I see you
- Reaction score
- 57
Just updated my old Effect-library for my requirements.
Maybe someone else is interested in this too
Maybe someone else is interested in this too
JASS:
library Effect requires optional AutoFly
// ========== Effect ==========
// Introduces the type "Effect"
// This type allows you to color,scale,move,time and hide ground effects
// And to time widget-attached effects.
// IMPORTANT:
// If you want to destroy a non-timed effect use : RemoveEffect() / Instance.remove()
// If you want to destroy a timed effect use : RemoveTimedEffect() / Instance.removeTimed()
// Do not color,scale,move or hide widget-attached effects, but you may time em
// Author: Executor alias Lord_Executor
// ====== Implementation ======
// Make a new trigger called "Effect"
// Convert it to custom text
// Paste the whole code in the empty page
// IMPORTANT:
// Import Vexorian's dummy.mdx
// adjust the "war3mapImported\dummy.mdl" (beneath) to your custom import path
// finally save the map once, close it, reopen it and AFTER that remove the '!' of the '//!' beneath this line
// runtextmacro Effect_MergeDummy("Visible Dummy","vdum","war3mapImported\dummy.mdl")
// ========== Credits =========
// Vexorian: vJass & Dummy.mdx & recycle idea
// Azlier: Autofly
globals
private constant integer DUMMY_ID = 039;vdum039;
private constant real RECYCLE_DELAY = 2.
private player DUMMY_OWNER = Player(14) // neutral
private constant real RECYCLE_X = 5000.
private constant real RECYCLE_Y = 5000.
endglobals
struct Effect
private unit carrier
private effect sfx
private thistype next
private real schedule
private static group DUMMIES
private static timer NOW
private static timer recycleTimer
private static timer removeTimer
private static thistype recycleStart
private static thistype recycleEnd
private static thistype removeStart
private static thistype removeEnd
private static method onInit takes nothing returns nothing
set .DUMMIES = CreateGroup()
set .NOW = CreateTimer()
set .recycleTimer = CreateTimer()
set .removeTimer = CreateTimer()
set .recycleStart = 0
set .recycleEnd = 0
set .removeStart = 0
set .removeEnd = 0
call TimerStart(.NOW,999999999.,false,null)
endmethod
method scale takes real size returns nothing
call SetUnitScale(.carrier,size,size,size)
endmethod
method scalePercent takes real size returns nothing
set size = size * 0.01
call SetUnitScale(.carrier,size,size,size)
endmethod
method color takes integer r, integer g, integer b, integer alpha returns nothing
call SetUnitVertexColor(.carrier,r,g,b,alpha)
endmethod
method move takes real x, real y , real z returns nothing
call SetUnitX(.carrier,x)
call SetUnitY(.carrier,y)
call SetUnitFlyHeight(.carrier,z,0.)
endmethod
method operator dummy takes nothing returns unit
return .carrier
endmethod
method operator facing takes nothing returns real
return GetUnitFacing(.carrier)
endmethod
method operator x takes nothing returns real
return GetUnitX(.carrier)
endmethod
method operator y takes nothing returns real
return GetUnitY(.carrier)
endmethod
method operator z takes nothing returns real
return GetUnitFlyHeight(.carrier)
endmethod
method operator visibility takes nothing returns boolean
return not IsUnitHidden(.carrier)
endmethod
method operator facing= takes real f returns nothing
call SetUnitFacing(.carrier,f)
endmethod
method operator x= takes real x returns nothing
call SetUnitX(.carrier,x)
endmethod
method operator y= takes real y returns nothing
call SetUnitY(.carrier,y)
endmethod
method operator z= takes real z returns nothing
call SetUnitFlyHeight(.carrier,z,0.)
endmethod
method operator visibility= takes boolean vis returns nothing
call ShowUnit(.carrier,vis)
endmethod
method operator zAngleRad= takes real value returns nothing
local integer i=R2I(value*bj_RADTODEG+90.5)
if(i>=180) then
set i=179
elseif(i<0) then
set i=0
endif
call SetUnitAnimationByIndex(.carrier, i )
endmethod
method operator zAngleDeg= takes integer value returns nothing
set value = value + 90
if value >= 180 then
set value = 179
elseif value < 0 then
set value = 0
endif
call SetUnitAnimationByIndex(.carrier,value)
endmethod
method remove takes nothing returns nothing
call .recycle()
endmethod
method removeTimed takes nothing returns nothing
local thistype curr = .removeStart
local thistype next = .removeStart.next
loop
exitwhen next == 0
if next == this then
set curr.next = .next
exitwhen true
endif
set curr = next
set next = next.next
endloop
if .removeStart == this then
set .removeStart = .next
endif
if .removeEnd == this then
if .removeStart == 0 then
set .removeEnd = 0
else
set .removeEnd = curr
endif
endif
call .recycle()
endmethod
private method onDestroy takes nothing returns nothing
if .carrier != null then
call SetUnitScale(.carrier,1.,1.,1.)
call SetUnitVertexColor(.carrier,255,255,255,255)
call SetUnitX(.carrier,RECYCLE_X)
call SetUnitY(.carrier,RECYCLE_Y)
call GroupAddUnit(DUMMIES,.carrier)
set .carrier = null
endif
endmethod
private static method onRecycleTimer takes nothing returns nothing
local thistype this = .recycleStart
set .recycleStart = .recycleStart.next
call .destroy()
if .recycleStart != 0 then
call TimerStart(.recycleTimer,TimerGetRemaining(.NOW)-.recycleStart.schedule,false,function thistype.onRecycleTimer)
else
set .recycleEnd = 0
endif
endmethod
private method recycle takes nothing returns nothing
call DestroyEffect(.sfx)
set .sfx = null
set .schedule = TimerGetRemaining(.NOW)-RECYCLE_DELAY
if .recycleStart == 0 then
set .recycleStart = this
set .recycleEnd = this
call TimerStart(.recycleTimer,RECYCLE_DELAY,false,function thistype.onRecycleTimer)
else
set .recycleEnd.next = this
set .recycleEnd = this
endif
endmethod
private static method onRemoveTimer takes nothing returns nothing
local thistype this = .removeStart
set .removeStart = .removeStart.next
call DestroyEffect(.sfx)
call .recycle()
if .removeStart != 0 then
call TimerStart(.removeTimer,TimerGetRemaining(.NOW)-.removeStart.schedule,false,function thistype.onRemoveTimer)
else
set .removeEnd = 0
endif
endmethod
static method newGroundEffect takes string modelName, real x, real y, real z returns thistype
local thistype this = thistype.allocate()
set .next = 0
set .carrier = FirstOfGroup(DUMMIES)
if .carrier == null then
set .carrier = CreateUnit(DUMMY_OWNER,DUMMY_ID,x,y,0.)
call SetUnitPathing(.carrier,false)
static if not AutoFly then
call UnitAddAbility(.carrier,039;Amrf039;)
call UnitRemoveAbility(.carrier,039;Amrf039;)
endif
else
call GroupRemoveUnit(DUMMIES,.carrier)
endif
call SetUnitX(.carrier,x)
call SetUnitY(.carrier,y)
call SetUnitFlyHeight(.carrier, z, 0.)
set .sfx = AddSpecialEffectTarget(modelName,.carrier, "origin")
return this
endmethod
static method newTargetEffect takes string modelName, widget target, string attachPoint returns thistype
local thistype this = thistype.allocate()
set .next = 0
set .carrier = null
set .sfx = AddSpecialEffectTarget(modelName,target,attachPoint)
return this
endmethod
static method newTimedGroundEffect takes string modelName, real x, real y, real z, real duration returns thistype
local thistype this = .newGroundEffect(modelName,x,y,z)
call .limitEffectDuration(duration)
return this
endmethod
static method newTimedTargetEffect takes string modelName, widget target, string attachPoint, real duration returns thistype
local thistype this = .newTargetEffect(modelName,target,attachPoint)
call .limitEffectDuration(duration)
return this
endmethod
private method limitEffectDuration takes real duration returns thistype
local thistype curr = 0
local thistype next = 0
set .schedule = TimerGetRemaining(.NOW)-duration
if .removeStart == 0 then
set .removeStart = this
set .removeEnd = this
call TimerStart(.removeTimer,duration,false,function thistype.onRemoveTimer)
return this
elseif .removeStart.schedule<.schedule then
call PauseTimer(.removeTimer)
call TimerStart(.removeTimer,duration,false,function thistype.onRemoveTimer)
set .next = .removeStart
set .removeStart = this
return this
else
set curr = .removeStart
set next = .removeStart.next
loop
exitwhen next == 0
if next.schedule < .schedule then
set .next = next
set curr.next = this
return this
endif
set curr = next
set next = next.next
endloop
set .removeEnd.next = this
set .removeEnd = this
endif
return this
endmethod
//! textmacro Effect_MergeDummy takes NAME, ID, MODELPATH
//! external ObjectMerger w3u ushd $ID$ unam "$NAME$" uabi "Aeth,Avul,Aloc" umvs "520" umvr 1 umvt foot umvh -500 uhpm 99999 uhom 1 ucol -10 umdl "$MODELPATH$" ucbs 0 ucpt 0 ushu "" umvh 0 ufoo 0
//! endtextmacro
endstruct
function AddEffect takes string modelName, real x, real y, real z returns Effect
return Effect.newGroundEffect(modelName,x,y,z)
endfunction
function AddTimedEffect takes string modelName, real x, real y, real z, real duration returns Effect
return Effect.newTimedGroundEffect(modelName,x,y,z,duration)
endfunction
function AddEffectTarget takes string modelName, widget target, string attachPoint returns Effect
return Effect.newTargetEffect(modelName,target,attachPoint)
endfunction
function AddTimedEffectTarget takes string modelName, widget target, string attachPoint, real duration returns Effect
return Effect.newTimedTargetEffect(modelName,target,attachPoint,duration)
endfunction
function ScaleEffect takes Effect e, real scale returns nothing
call e.scale(scale)
endfunction
function ScaleEffectByPercent takes Effect e, real scale returns nothing
call e.scalePercent(scale)
endfunction
function ReColorEffect takes Effect e, integer r, integer g, integer b, integer alpha returns nothing
call e.color(r,g,b,alpha)
endfunction
function MoveEffect takes Effect e, real x, real y, real z returns nothing
call e.move(x,y,z)
endfunction
function HideEffect takes Effect e returns nothing
set e.visibility=false
endfunction
function ShowEffect takes Effect e returns nothing
set e.visibility=true
endfunction
function RemoveEffect takes Effect e returns nothing
call e.remove()
endfunction
function RemoveTimedEffect takes Effect e returns nothing
call e.removeTimed()
endfunction
endlibrary