Name | Type | is_array | initial_value |
//TESH.scrollpos=0
//TESH.alwaysfold=0
library RepeatData initializer RepeatInit
/*
-----------------------------------------------------------------------------------------------------------------------------------------------------------
*/
/*
____ _ ____ _
| _ \ ___ _ __ ___ __ _| |_| _ \ __ _| |_ __ _
| |_) / _ \ '_ \ / _ \/ _` | __| | | |/ _` | __/ _` |
| _ < __/ |_) | __/ (_| | |_| |_| | (_| | || (_| |
|_| \_\___| .__/ \___|\__,_|\__|____/ \__,_|\__\__,_|
|_|
---- version 0.1 ----
Write by Daric Nguyen"
=> Easy to use
=> Store data by Struct
=> MUI for spell
* HOW TO USE?
+ Method:
- method isStart takes nothing returns nothing
- method isLoop takes nothing returns nothing
- method isEnd takes nothing returns nothing
+ Example
"
library example initializer init requires RepeatData
private struct repeat extends RepeatData
// some variables
method whenLoop takes nothing returns nothing
// some actions when loop
endmethod
method whenStart takes nothing returns nothing
// some actions when start
endmethod
method whenEnd takes nothing returns nothing
// some actions when end
endmethod
endstruct
function init takes nothing returns nothing
local repeat t=repeat.create(0.05,0) // (real timeloop, real maxtimeloop) if real maxtimeloop equal to 0, struct will repeat until you use call this.stop() command in method Loop
endfunction
endlibrary
"
*/
/*
-----------------------------------------------------------------------------------------------------------------------------------------------------------
*/
private interface RepeatFace
method whenLoop takes nothing returns nothing defaults nothing
method whenStart takes nothing returns nothing defaults nothing
method whenEnd takes nothing returns nothing defaults nothing
endinterface
globals
private integer cn
private timer rTime
endglobals
/* Version 0.1 */
struct RepeatData extends RepeatFace
public real rL
public real nrL
public real mrL
public boolean rSt
public real rnL
private static thistype array rData
static method create takes real Loop, real maxLoop returns thistype
local thistype this=thistype.allocate()
set this.rL=Loop
set this.mrL=maxLoop
set this.rSt=true
set this.nrL=0
set this.rnL=0
set cn=cn+1
set .rData[cn]=this
if cn==1 then
call TimerStart(rTime,0.03,true,function RepeatData.rpLoop)
endif
return this
endmethod
method stop takes nothing returns nothing
set this.mrL=0.03
endmethod
static method rpLoop takes nothing returns nothing
local thistype this
local integer i=1
loop
exitwhen i>cn
set this=.rData[i]
if this.rL==0 then
call this.stop()
endif
if this.rSt==true then
set this.rSt=false
call this.whenStart()
endif
if this.mrL==0 then
set this.nrL=this.nrL+0.03
set this.rnL=this.rnL+0.03
if this.rnL>=this.rL then
call this.whenLoop()
set this.rnL=0
endif
else
if this.nrL>=this.mrL then
call this.whenEnd()
call this.destroy()
set .rData[i]=.rData[cn]
set i=i-1
set cn=cn-1
else
set this.nrL=this.nrL+0.03
set this.rnL=this.rnL+0.03
if this.rnL>=this.rL then
call this.whenLoop()
set this.rnL=0
endif
endif
endif
set i=i+1
endloop
if cn<=0 then
set cn=0
call PauseTimer(rTime)
endif
endmethod
endstruct
private function RepeatInit takes nothing returns nothing
set cn=0
set rTime=CreateTimer()
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library GroupUtils
//******************************************************************************
//* BY: Rising_Dusk
//*
//* This library is a simple implementation of a stack for groups that need to
//* be in the user's control for greater than an instant of time. Additionally,
//* this library provides a single, global group variable for use with user-end
//* enumerations. It is important to note that users should not be calling
//* DestroyGroup() on the global group, since then it may not exist for when it
//* it is next needed.
//*
//* The group stack removes the need for destroying groups and replaces it with
//* a recycling method.
//* function NewGroup takes nothing returns group
//* function ReleaseGroup takes group g returns boolean
//* function GroupRefresh takes group g returns nothing
//*
//* NewGroup grabs a currently unused group from the stack or creates one if the
//* stack is empty. You can use this group however you'd like, but always
//* remember to call ReleaseGroup on it when you are done with it. If you don't
//* release it, it will 'leak' and your stack may eventually overflow if you
//* keep doing that.
//*
//* GroupRefresh cleans a group of any shadow references which may be clogging
//* its hash table. If you remove a unit from the game who is a member of a unit
//* group, it will 'effectively' remove the unit from the group, but leave a
//* shadow in its place. Calling GroupRefresh on a group will clean up any
//* shadow references that may exist within it.
//*
globals
//* Group for use with all instant enumerations
group ENUM_GROUP = CreateGroup()
//* Temporary references for GroupRefresh
private boolean Flag = false
private group Refr = null
//* Assorted constants
private constant integer MAX_HANDLE_COUNT = 408000
private constant integer MIN_HANDLE_ID = 0x100000
//* Arrays and counter for the group stack
private group array Groups
private integer array Status[MAX_HANDLE_COUNT]
private integer Count = 0
endglobals
private function AddEx takes nothing returns nothing
if Flag then
call GroupClear(Refr)
set Flag = false
endif
call GroupAddUnit(Refr, GetEnumUnit())
endfunction
function GroupRefresh takes group g returns nothing
set Flag = true
set Refr = g
call ForGroup(Refr, function AddEx)
if Flag then
call GroupClear(g)
endif
endfunction
function NewGroup takes nothing returns group
if Count == 0 then
set Groups[0] = CreateGroup()
else
set Count = Count - 1
endif
set Status[GetHandleId(Groups[Count])-MIN_HANDLE_ID] = 1
return Groups[Count]
endfunction
function ReleaseGroup takes group g returns boolean
local integer stat = Status[GetHandleId(g)-MIN_HANDLE_ID]
local boolean b = true
if g == null then
debug call BJDebugMsg(SCOPE_PREFIX+" Error: Null groups cannot be released")
set b = false
elseif stat == 0 then
debug call BJDebugMsg(SCOPE_PREFIX+" Error: Group not part of stack")
set b = false
elseif stat == 2 then
debug call BJDebugMsg(SCOPE_PREFIX+" Error: Groups cannot be multiply released")
set b = false
elseif Count == 8191 then
debug call BJDebugMsg(SCOPE_PREFIX+" Error: Max groups achieved, destroying group")
call DestroyGroup(g)
set b = false
else
call GroupClear(g)
set Groups[Count] = g
set Count = Count + 1
set Status[GetHandleId(g)-MIN_HANDLE_ID] = 2
endif
return b
endfunction
endlibrary
//TESH.scrollpos=111
//TESH.alwaysfold=0
library Psychic initializer init requires RepeatData, GroupUtils
/*
spell Write by Daric Nguyen"
Requires RepeatData
GroupUtils
thanks to Rising_Dusk
*/
globals
private constant real DAMAGE=100 //Ability Damage
private constant real TIME=.03 //Time loop
private constant real RANGE=700 //Area of effect
private constant string FX="Models\\PsychicTarget.mdl" //Effect on target unit
private constant string SFX="Models\\GrandUndeadAura.mdl" // Effect on caster unit
private constant string SFX2="Models\\NewGroundEX.mdx" // Effect Explosion
private constant attacktype ATT=ATTACK_TYPE_HERO
private constant damagetype DMT=DAMAGE_TYPE_MAGIC
endglobals
function trig_con takes nothing returns boolean
return ( GetSpellAbilityId() == 'A000' )
endfunction
private struct Psychic extends RepeatData
unit caster
unit target
real fly
real mfly
boolean isfly
effect deff
real per
// variables
method whenLoop takes nothing returns nothing
local real x
local real y
local real dx
local real dy
set x=GetUnitX(this.target)
set y=GetUnitY(this.target)
set dx=x+GetRandomReal(0,5)*Cos((GetUnitFacing((this.target)))*bj_DEGTORAD)
set dy=y+GetRandomReal(0,5)*Sin((GetUnitFacing((this.target)))*bj_DEGTORAD)
call UnitAddAbility((this.target),'Amrf')
call SetUnitPosition((this.target),dx,dy)
call SetUnitFlyHeight((this.target),this.fly,0)
call UnitRemoveAbility((this.target),'Amrf')
if this.isfly==true then // check is unit fly up
if this.fly>=this.mfly then
set this.isfly=false
endif
set this.fly=this.fly+4
else
if this.fly<=0 then
call this.stop()
endif
set this.fly=this.fly-100
endif
endmethod
method whenStart takes nothing returns nothing
call PauseUnit(this.target,true)
call SetUnitTimeScalePercent(this.target,0) // stop target unit animation
set this.deff=AddSpecialEffectTarget(FX,this.target,"chest") // add effect on target
endmethod
method whenEnd takes nothing returns nothing
set this.per=(this.mfly / 500) // calculate damage increases percent or decreases percent follow max fly height
if this.per<=.5 then
set this.per=.5 // if decreases damage percent less than 50%, set it's 50%
endif
if this.per>=1.2 then
set this.per=1.2 // if increases damage percent greater than 120%, set it's 120%
endif
call DestroyEffect(this.deff) // destroy effect attackment in target unit
call UnitDamageTarget(this.caster,this.target,DAMAGE*this.per,false,false,ATT,DMT,null)
call PauseUnit(this.target,false) // deal damage and unpause target unit
call SetUnitTimeScalePercent(this.target,100) // unstop unit animation
call DestroyEffect(AddSpecialEffect(SFX2,GetUnitX(this.target),GetUnitY(this.target))) // create explosion effect
set this.target=null
set this.caster=null
endmethod
endstruct
private function PsychicAUnit takes unit source, unit t, real max returns nothing
local Psychic ps=Psychic.create(0.03,0)
set ps.caster=source
set ps.target=t
set ps.mfly=max
set ps.isfly=true
set ps.fly=0
endfunction
private struct Psychic2 extends RepeatData
unit caster
unit dum
effect deff
real nfly
real xx
real yy
real t1
real t2
real scale
group g
// variables
method whenLoop takes nothing returns nothing
local unit e
if this.t1<= 3.4 then
if this.t1==0 then
call SetUnitTimeScalePercent(this.caster,0)
endif
set this.t1=this.t1+0.06
// check unit around caster
call GroupEnumUnitsInRange(this.g,this.xx,this.yy,700,null)
loop
set e=FirstOfGroup(g)
exitwhen e==null
if IsUnitEnemy(e,GetOwningPlayer(this.caster)) and GetWidgetLife(e)>0.405 and IsUnitType(e,UNIT_TYPE_STRUCTURE)==false and IsUnitPaused(e)==false then
call PsychicAUnit(this.caster,e,(this.nfly+(GetRandomReal(-40,50)))) // pick up enum unit
endif
call GroupRemoveUnit(this.g,e)
endloop
call GroupRefresh(this.g)
set this.nfly=this.nfly-8
else
if this.t2 ==255 then
// unpause caster
call PauseUnit(this.caster,false)
call SetUnitTimeScalePercent(this.caster,100)
set this.caster=null
endif
set this.t2=this.t2-10
set this.scale=this.scale+0.02
endif
if this.t2<=0 then
call this.stop()
else
call SetUnitVertexColor(this.dum,R2I(this.t2),R2I(this.t2),R2I(this.t2),R2I(this.t2))
call SetUnitScale(this.dum, this.scale, this.scale, this.scale)
endif
set e=null
endmethod
method whenStart takes nothing returns nothing
call PauseUnit(this.caster,true)
set this.dum=CreateUnit(Player(15),'h000',this.xx,this.yy,0)
set this.deff=AddSpecialEffectTarget(SFX,this.dum,"origin")
endmethod
method whenEnd takes nothing returns nothing
// remove leak when method end
call DestroyEffect(this.deff)
call RemoveUnit(this.dum)
call ReleaseGroup(this.g)
set this.dum=null
endmethod
endstruct
function trig_act takes nothing returns nothing
local unit cast=GetTriggerUnit()
local real x=GetUnitX(cast)
local real y=GetUnitY(cast)
local Psychic2 this=Psychic2.create(0.05,0) // (0.05= time loop per 0.05s,0= never end if don't use call this.stop() in any method)
// now add some variables you need save in struct Psychic2
set this.caster=cast
set this.t1=0 // time tick one
set this.t2=255 // time tick two, also is alpha real
set this.yy=y // save Yof caster
set this.xx=x // save X of caster
set this.nfly=500 // save maximun fly height
set this.scale=1.00 // save scale
set this.g=NewGroup()
set cast=null
endfunction
//===========================================================================
function init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( trig, Condition( function trig_con ) )
call TriggerAddAction( trig, function trig_act )
set trig=null
endfunction
endlibrary