- Joined
- Jun 21, 2012
- Messages
- 431
JASS:
library CoreDummy/*
***********************************************************************************************
*
* *******************************************************************************************
*
* */ uses /*
* */ optional ARGB /* wc3c.net/showthread.php?t=101858
*
* *******************************************************************************************
*
* CoreDummy
* ¯¯¯¯¯¯¯¯¯
* v0.1.1.1
* by Thelordmarshall
*
* Create dummies for your spells.
*
* Pros:
* ¯¯¯¯
* - reduce the loading time of your map (by using one or less dummies)
* - instant xy and z facing
* - not use SetUnitLookAt
* - all caster/dummy utilities in one library
* - disables your unit indexer system on create dummies to prevent unnecessary indexes
* - error message when dummy is killed/removed; only in DEBUB_MODE
*
* Cons:
* ¯¯¯¯
* - no GUI friendly
* - only 8191 instances (need more?)
*
* API:
* ¯¯¯
* struct Dummy extends array
*
* Creator/Destructor
* ------------------
* static method create takes player owner, real x, real y, real angle returns Dummy
* method destroy takes nothing returns nothing
*
* Operators/Configuration
* -----------------------
* public boolean hiddenDestroy
*
* method operator unit takes nothing returns unit
* method operator data takes nothing returns integer
* method operator data= takes integer d returns nothing
* method operator model= takes string fx returns nothing
* method operator scale takes nothing returns real
* method operator scale= takes real s returns nothing
* method operator x takes nothing returns real
* method operator y takes nothing returns real
* method operator z takes nothing returns real
* method operator x= takes real x returns nothing
* method operator y= takes real y returns nothing
* method operator z= takes real z returns nothing
* method operator xyAngle takes nothing returns real
* method operator zAngle takes nothing returns real
* method operator xyAngle= takes real a returns nothing
* method operator zAngle= takes real a returns nothing
* method operator owner takes nothing returns player
* method operator owner= takes player p returns nothing
* method operator playerColor= takes playercolor c returns nothing
* method operator color= takes ARGB c returns nothing
* - if library ARGB exist
*
* Methods
* -------
* method setColor takes integer r, integer g, integer b, integer a returns nothing
* - if library ARGB does not exist
* method flashTarget takes string fx returns nothing
* - create/destroy fx on dummy
* method flashPoint takes string fx returns nothing
* - create/destroy fx on dummy position
* method setPosition takes real x, real y returns nothing
* method setAbility takes integer abilId, integer lvl returns nothing
*
* Caster Methods
* --------------
* static method cast takes unit source, integer abilId, integer lvl, integer order returns boolean
* static method castTarget takes unit source, integer abilId, integer lvl, integer order, widget t returns boolean
* static method castPoint takes unit source, integer abilId, integer lvl, integer order, real x, real y returns boolean
*
* Credits:
* ¯¯¯¯¯¯¯
* - Vexorian: old CasterSystem, xedummy, the insert/remove angle methods
* and the dummy.mdx model
*
**********************************************************************************************/
//CONFIGURATION
//===============================================================================
globals
constant integer DUMMY_ID = 'e000'
private constant integer STACK_SIZE = 256
private constant real DEFAULT_DUMMY_SCALE = 1.00
private constant real DEFAULT_DUMMY_FLY_HEIGHT = 70.00
private constant real DUMMY_HIDDEN_FLY_HEIGHT = 9999.00
private constant real CASTER_REMOVE_DELAY = 0.50
endglobals
//put here the enable/disable function of your unit indexer system
//! textmacro UNIT_INDEXER_CONFIG takes ENABLED
set UnitIndexer.enabled = $ENABLED$ //enable/disable UnitIndexer, UnitDex, etc...
//! endtextmacro
private function FlyEnablerConfig takes unit u returns boolean
return UnitAddAbility(u, 'Amrf') and UnitRemoveAbility(u, 'Amrf')
endfunction
//===============================================================================
//ENDCONFIGURATION
globals
private timer delayTimer=CreateTimer()
private constant integer RESOLUTION=12
private constant player OWNER=Player(15)
private constant group STACK=CreateGroup()
private unit array stack
private unit array delay_unit
private real array angle
private integer array next
private integer array prev
private integer array size
private integer array first
private integer array last
private integer array list
private integer array dummy_next
private integer array delay_dummy
private integer delay_next=0
endglobals
//! textmacro Dummy_debug takes DEBUG,NATIVE,DEBUG_STR
debug function $DEBUG$ takes unit u returns nothing
debug if(IsUnitInGroup(u,STACK))then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"[CoreDummy] warning: a dummy "+"$DEBUG_STR$")
debug endif
debug endfunction
debug hook $NATIVE$ $DEBUG$
//! endtextmacro
//! runtextmacro Dummy_debug("KillDummy_debug","KillUnit","has been killed")
//! runtextmacro Dummy_debug("RemoveDummy_debug","RemoveUnit","has been removed from map")
struct Dummy extends array
public boolean hiddenDestroy
private unit dummy
private real zangle
private real d_scale
private effect effect
private integer ability
private static method operator alloc takes nothing returns integer
local thistype this=list[0]
if(0==list[this])then
set list[0]=this+1
else
set list[0]=list[this]
endif
return this
endmethod
private static method getIndex takes real a returns integer
if(a<0)then
set a=a+360
elseif(a>360)then
set a=360
endif
return R2I(a/360*RESOLUTION)+1
endmethod
private method insert takes integer a returns nothing
call SetUnitFacing(stack[this],angle[a])
if(0==size[a])then
set first[a]=this
else
set dummy_next[last[a]]=this
endif
set last[a]=this
set dummy_next[this]=0
if(size[a]>size[next[a]])then
set this=first[a]
set first[a]=dummy_next[this]
call .insert(next[a])
elseif(size[a]>size[prev[a]])then
set this=first[a]
set first[a]=dummy_next[this]
call .insert(prev[a])
else
set size[a]=size[a]+1
endif
endmethod
private static method remove takes integer a returns integer
local integer this
if(0==size[a])then
call newDummy(angle[a])
endif
if(size[a]<size[next[a]])then
set this=last[a]
set last[a]=remove(next[a])
set dummy_next[this]=last[a]
call SetUnitFacing(stack[last[a]],angle[a])
elseif(size[a]<size[prev[a]])then
set this=last[a]
set last[a]=remove(prev[a])
set dummy_next[this]=last[a]
call SetUnitFacing(stack[last[a]],angle[a])
else
set size[a]=size[a]-1
if(0==size[a])then
set last[a]=0
endif
endif
set this=first[a]
set first[a]=dummy_next[this]
set dummy_next[this]=0
return this
endmethod
private static method newDummy takes real a returns nothing
local thistype this=alloc
//! runtextmacro UNIT_INDEXER_CONFIG("false")
set stack[this]=CreateUnit(OWNER,DUMMY_ID,0,0,a)
//! runtextmacro UNIT_INDEXER_CONFIG("true")
call .insert(getIndex(a))
call UnitAddAbility(stack[this],'Aloc')
call FlyEnablerConfig(stack[this])
call GroupAddUnit(STACK,stack[this])
endmethod
//! textmacro DummyOperator takes METHOD,VAR_TYPE,RETURNED,ACTION,USE_STRING,EXTRA_SYMBOL,EXTRA_ACTION
method $METHOD$ takes $VAR_TYPE$ returns $RETURNED$
$ACTION$$USE_STRING$"origin")$EXTRA_SYMBOL$)
$EXTRA_ACTION$
endmethod
//! endtextmacro
//! runtextmacro DummyOperator("operator unit","nothing","unit","return .dummy","//","//","//")
//! runtextmacro DummyOperator("operator data","nothing","integer","return GetUnitUserData(.dummy)","//","//","//")
//! runtextmacro DummyOperator("operator data=","integer i","nothing","call SetUnitUserData(.dummy,i)","//","//","")
//! runtextmacro DummyOperator("operator model=","string s","nothing","set.effect=AddSpecialEffectTarget(s,.dummy,","","//","")
//! runtextmacro DummyOperator("operator scale","nothing","real","return .d_scale","//","//","//")
//! runtextmacro DummyOperator("operator scale=","real s","nothing","call SetUnitScale(.dummy,s,s,s)","//","//","set .d_scale=s")
//! runtextmacro DummyOperator("operator x","nothing","real","return GetUnitX(.dummy)","//","//","//")
//! runtextmacro DummyOperator("operator y","nothing","real","return GetUnitY(.dummy)","//","//","//")
//! runtextmacro DummyOperator("operator z","nothing","real","return GetUnitFlyHeight(.dummy)","//","//","//")
//! runtextmacro DummyOperator("operator x=","real x","nothing","call SetUnitX(.dummy,x)","//","//","//")
//! runtextmacro DummyOperator("operator y=","real y","nothing","call SetUnitY(.dummy,y)","//","//","//")
//! runtextmacro DummyOperator("operator z=","real z","nothing","call SetUnitFlyHeight(.dummy,z,0.)","//","//","//")
//! runtextmacro DummyOperator("operator xyAngle","nothing","real","return GetUnitFacing(.dummy)","//","//","//")
//! runtextmacro DummyOperator("operator xyAngle=","real a","nothing","call SetUnitFacing(.dummy,a)","//","//","//")
//! runtextmacro DummyOperator("operator zAngle","nothing","real","return .zangle","//","//","//")
//! runtextmacro DummyOperator("operator owner","nothing","player","return GetOwningPlayer(.dummy)","//","//","//")
//! runtextmacro DummyOperator("operator owner=","player p","nothing","call SetUnitOwner(.dummy,p,true)","//","//","//")
//! runtextmacro DummyOperator("operator playerColor=","playercolor c","nothing","call SetUnitColor(.dummy,c)","//","//","//")
//! runtextmacro DummyOperator("flashTarget","string fx","nothing","call DestroyEffect(AddSpecialEffectTarget(fx,.dummy,","","","//")
//! runtextmacro DummyOperator("flashPoint","string fx","nothing","call DestroyEffect(AddSpecialEffect(fx,GetUnitX(.dummy),GetUnitY(.dummy)))","//","//","//")
//! runtextmacro DummyOperator("setPosition","real x, real y","nothing","set .x=x","//","//","set .y=y")
static if(LIBRARY_ARGB)then
//! runtextmacro DummyOperator("operator color=","ARGB c","nothing","call c.recolorUnit(.dummy)","//","//","//")
else
//! runtextmacro DummyOperator("setColor","integer r, integer g, integer b, integer a","nothing","call SetUnitVertexColor(.dummy,r,g,b,a)","//","//","//")
endif
method operator zAngle= takes real a returns nothing
local integer i=R2I(a*bj_RADTODEG+90.5)
set .zangle=a
if(i>=180)then
set i=179
elseif(i<0)then
set i=0
endif
call SetUnitAnimationByIndex(.dummy,i)
endmethod
method setAbility takes integer abilId, integer lvl returns nothing
if(0!=.ability)then
call UnitRemoveAbility(.dummy,.ability)
endif
set .ability=abilId
call UnitAddAbility(.dummy,.ability)
call SetUnitAbilityLevel(.dummy,.ability,lvl)
endmethod
private static method onDelay takes nothing returns nothing
local integer i=delay_next
loop
if(null==delay_unit[i])then
call Dummy(delay_dummy[i]).destroy()
else
call IssueImmediateOrderById(delay_unit[i],851972)
call RemoveUnit(delay_unit[i])
set delay_unit[i]=null
endif
exitwhen(1==i)
set i=i-1
endloop
set delay_next=0
call PauseTimer(delayTimer)
endmethod
private static method startDelay takes Dummy d, unit u returns nothing
set delay_next=delay_next+1
set delay_unit[delay_next]=u
set delay_dummy[delay_next]=d
call TimerStart(delayTimer,CASTER_REMOVE_DELAY,false,function thistype.onDelay)
endmethod
//! textmacro Dummy_cast takes METHOD,ARGUMENTS,ORDER_FUNCTION
static method $METHOD$ takes $ARGUMENTS$ returns boolean
local Dummy d=create(GetOwningPlayer(source),GetUnitX(source),GetUnitY(source),0)
call d.setAbility(abilId,lvl)
call startDelay(d,null)
return $ORDER_FUNCTION$
endmethod
//! endtextmacro
//! runtextmacro Dummy_cast("cast","unit source, integer abilId, integer lvl, integer order","IssueImmediateOrderById(d.unit,order)")
//! runtextmacro Dummy_cast("castTarget","unit source, integer abilId, integer lvl, integer order, widget t","IssueTargetOrderById(d.unit,order,t)")
//! runtextmacro Dummy_cast("castPoint","unit source, integer abilId, integer lvl, integer order, real x, real y","IssuePointOrderById(d.unit,order,x,y)")
static method create takes player owner, real x, real y, real angle returns Dummy
local integer a=getIndex(angle)
local thistype this=remove(a)
set .dummy=stack[this]
call .setPosition(x,y)
call SetUnitFacing(.dummy,angle)
call SetUnitOwner(.dummy,owner,true)
set .z=DEFAULT_DUMMY_FLY_HEIGHT
set .scale=DEFAULT_DUMMY_SCALE
return this
endmethod
method destroy takes nothing returns nothing
local integer int
if(null!=.dummy)then
set list[this]=list[0]
set list[0]=this
set stack[this]=null
if(0!=.ability)then
call UnitRemoveAbility(.dummy,.ability)
endif
if(null!=.effect)then
call DestroyEffect(.effect)
set .effect=null
endif
if(integer(this)>STACK_SIZE)then
call GroupRemoveUnit(STACK,.dummy)
call startDelay(0,.dummy)
else
set int=alloc
set stack[int]=.dummy
call Dummy(int).insert(getIndex(GetUnitFacing(.dummy)))
call SetUnitOwner(.dummy,OWNER,true)
call SetUnitAnimationByIndex(.dummy,90)
call SetUnitVertexColor(.dummy,255,255,255,255)
if(.hiddenDestroy)then
set .z=DUMMY_HIDDEN_FLY_HEIGHT
set .hiddenDestroy=false
endif
endif
set .dummy=null
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"[CoreDummy] error: attempted to destroy null dummy")
endif
endmethod
private static method onInit takes nothing returns nothing
local integer i=0
local integer a=1
set list[0]=1
loop
exitwhen(RESOLUTION==i)
set i=i+1
set prev[i]=i-1
set next[i]=i+1
set angle[i]=(i-.5)*(360/RESOLUTION)
endloop
set prev[1]=i
set next[i]=1
set i=STACK_SIZE
loop
exitwhen(0==i)
call newDummy(angle[a])
set a=next[a]
set i=i-1
endloop
endmethod
endstruct
endlibrary