- Joined
- Jul 6, 2009
- Messages
- 889
Hi,
Does anyone want to handle this request to fix the following maps to work on v1.24+ (or whatever oldest version that is compatible with... everything)?
They're pretty old spells from wc3c. I think it's old enough that there is Katanna's local handle vars and H2I().
Rolling Boulder: http://www.wc3c.net/showthread.php?t=82894
Custom Script Code
Rolling Boulder
Tremor: http://www.wc3c.net/showthread.php?t=84022
Disco Inferno: http://www.wc3c.net/showthread.php?t=87003
Uses Caster System as well.
Boulder Roll: http://www.wc3c.net/showthread.php?t=83005
Uses Return Bug.
Optimisation or full rewriting isn't necessary. I think it should just be fixing the systems and making it compatible with latest patch.
Well, how it's done doesn't really matter.
Thanks.
Does anyone want to handle this request to fix the following maps to work on v1.24+ (or whatever oldest version that is compatible with... everything)?
They're pretty old spells from wc3c. I think it's old enough that there is Katanna's local handle vars and H2I().
Rolling Boulder: http://www.wc3c.net/showthread.php?t=82894
Custom Script Code
JASS:
//**********************************************************************************
//* *
//* Caster System 13.3 *
//* *
//* Manual and Newest version on ([url]http://wc3campaigns.net/vexorian[/url] ) *
//* *
//**********************************************************************************
//##Start##
//Caster System 13.3 ( [url]http://wc3campaigns.net/vexorian[/url] )
//====================================================================================================================================================================
constant function Caster_UnitId takes nothing returns integer
return 'e000' //// Caster Unit type rawcode (changes betwen maps, always use it inside '')
endfunction
constant function Caster_DefaultAttackType takes nothing returns attacktype
return ATTACK_TYPE_CHAOS // Default attack type used by the old functions and when you use 0 as DamageOptions
endfunction
constant function Caster_DefaultDamageType takes nothing returns damagetype
return DAMAGE_TYPE_UNIVERSAL // Default damage type used by the old functions and when you use 0 as DamageOptions
endfunction
constant function DamageTreeDetectorId takes nothing returns integer
return 'Aeat' /// The eat tree ability, don't need to change this rawcode unless you modiffied that ability in your map, in that case copy it, reset the copied one and use its rawcode here.
endfunction
constant function ChangeableFlyingHeightAllowerId takes nothing returns integer
return 'Amrf' /// Medivh's Crow form ability, don't need to change this rawcode unless you modiffied that ability in your map, in that case copy it, reset the copied one and use its rawcode here.
endfunction
constant function CS_MaxCollisionSize takes nothing returns real
return 55. //Maximum collision size in your map
endfunction
constant function CS_Cycle takes nothing returns real
return 0.04 // Cycle value for the projectile movement in seconds (Each 0.04 the projectiles get moved)
// 0.01 looks smooth but is lag friendly
// 0.1 looks horrible but is not laggy
// 0.04 is decent for the human eye and quite efficient.
// 0.05 would be an improvement in efficiency but probably doesn't look too well
endfunction
function CS_InventoryId takes nothing returns integer
return 'AInv' //Rawcode of any inventory ability, prefferably one with 6 slots
//Currently it is Inventory (Hero)
endfunction
//=================================================================================================
function CS_Rawcode2Real takes integer i returns real
return i
return 0.
endfunction
function CS_LoadRawcodeFromReal takes integer n returns integer
return udg_castervars[n]
return 0
endfunction
function CS_CopyGroup takes group g returns group
set bj_groupAddGroupDest=CreateGroup()
call ForGroup(g, function GroupAddGroupEnum)
return bj_groupAddGroupDest
endfunction
function CS_IsUnitVisible takes unit u, player p returns boolean
return IsUnitVisible(u,Player(bj_PLAYER_NEUTRAL_VICTIM)) or IsUnitVisible(u,p)
endfunction
constant function CS_RectLimitOffSet takes nothing returns real
return 50.0
endfunction
function CS_SafeX takes real x returns real
local rect r=bj_mapInitialPlayableArea
local real t=GetRectMinX(r)+CS_RectLimitOffSet()
if (x<t) then
set x=t
else
set t=GetRectMaxX(r)-CS_RectLimitOffSet()
if (x>t) then
set x=t
endif
endif
set r=null
return(x)
endfunction
function CS_SafeY takes real y returns real
local rect r=bj_mapInitialPlayableArea
local real t=GetRectMinY(r)+CS_RectLimitOffSet()
if (y<t) then
set y=t
else
set t=GetRectMaxY(r)-CS_RectLimitOffSet()
if (y>t) then
set y=t
endif
endif
set r=null
return(y)
endfunction
function CS_MoveUnit takes unit u, real x, real y returns boolean
local rect r=bj_mapInitialPlayableArea
local real t=GetRectMinX(r)+CS_RectLimitOffSet()
local boolean b=true
if (x<t) then
set x=t
set b=false
else
set t=GetRectMaxX(r)-CS_RectLimitOffSet()
if (x>t) then
set b=false
set x=t
endif
endif
set t=GetRectMinY(r)+CS_RectLimitOffSet()
if (y<t) then
set y=t
set b=false
else
set t=GetRectMaxY(r)-CS_RectLimitOffSet()
if (y>t) then
set y=t
set b=false
endif
endif
if (b) then
call SetUnitX(u, x)
call SetUnitY(u, y)
endif
set r=null
return b
endfunction
function CS_MoveUnitLoc takes unit u, location loc returns boolean
return CS_MoveUnit(u,GetLocationX(loc),GetLocationY(loc))
endfunction
//==================================================================================================
function CS_EnumUnitsInAOE_Filter takes nothing returns boolean
return IsUnitInRangeLoc(GetFilterUnit(), bj_enumDestructableCenter ,bj_enumDestructableRadius)
endfunction
//==================================================================================================
// Use this version when you only have coordinates of the point.
//
function CS_EnumUnitsInAOE takes group g, real x, real y, real area, boolexpr bx returns nothing
local boolexpr cond
local boolexpr aux=Condition(function CS_EnumUnitsInAOE_Filter)
if (bx==null) then
set cond=aux
else
set cond=And(aux,bx)
endif
set bj_enumDestructableCenter=Location(x,y)
set bj_enumDestructableRadius=area
call GroupEnumUnitsInRange(g,x,y,CS_MaxCollisionSize()+area,cond)
call DestroyBoolExpr(cond)
if (bx!=null) then
call DestroyBoolExpr(aux)
endif
call RemoveLocation(bj_enumDestructableCenter)
set aux=null
set cond=null
endfunction
//==================================================================================================
// Use this version whenever you already have a location for that point, to save some steps
//
function CS_EnumUnitsInAOELoc takes group g, location loc, real area, boolexpr bx returns nothing
local boolexpr cond
local boolexpr aux=Condition(function CS_EnumUnitsInAOE_Filter)
if (bx==null) then
set cond=aux
else
set cond=And(aux,bx)
endif
set bj_enumDestructableCenter=loc
set bj_enumDestructableRadius=area
call GroupEnumUnitsInRangeOfLoc(g,loc,CS_MaxCollisionSize()+area,cond)
call DestroyBoolExpr(cond)
if (bx!=null) then
call DestroyBoolExpr(aux)
endif
set aux=null
set cond=null
endfunction
//##Begin of CS Gamecache engine##
//=================================================================================================
// GameCache - Return bug module : Without gamecache or return bug, JASS would be a
// retarded-limited scripting language.
//
//=================================================================================================
// a.k.a H2I, changed name to CS_H2I to prevent conflicts with other systems (I intended this
// system to be easy to copy
//
function CS_H2I takes handle h returns integer
return h
return 0
endfunction
//=================================================================================================
// Main Gamecache handler
//
function CSCache takes nothing returns gamecache
if udg_cscache==null then
call FlushGameCache(InitGameCache("CasterSystem.vx"))
set udg_cscache=InitGameCache("CasterSystem.vx")
call StoreInteger(udg_cscache,"misc","TableMaxReleasedIndex",100)
endif
return udg_cscache
endfunction
//==================================================================================================
// Attachable vars : Attacheable variables are what most other people call Handle Variables, they
// allow to relate data with any handle, using a label, and its value, the stuff auto flushes if
// the value is 0, false, "", or null .
//
// Differences between Attacheable variables and "Local Handle Variables" :
// - The names of the functions
// - The name of the function group does not cause confusion, it is difficult to say:
// "you should set local handle variables to null at the end of a function" since
// it sounds as if you were talking about the "Local Handle Variables"
// - Also Have Attacheable Sets.
// - And can work together with Tables.
//
// Notes: don't "attach" variables on texttags nor those handle types used mostly for parameters
// (for example damagetype) , Although there is no reason to do so anyways
//
// Gamecache stuff are NOT Case Sensitive, don't ever use "" for label (Crashes game!)
//
//============================================================================================================
// For integers
//
function AttachInt takes handle h, string label, integer x returns nothing
local string k=I2S(CS_H2I(h))
if x==0 then
call FlushStoredInteger(CSCache(),k,label)
else
call StoreInteger(CSCache(),k,label,x)
endif
endfunction
function GetAttachedInt_FromSet takes handle h, gamecache g returns integer
return GetStoredInteger(g,I2S(CS_H2I(h))+";"+GetStoredString(g,"argpass","set"),GetStoredString(g,"argpass","seti"))
endfunction
function GetAttachedInt takes handle h, string label returns integer
if (label=="") then
return GetAttachedInt_FromSet(h,CSCache())
endif
return GetStoredInteger(CSCache(), I2S(CS_H2I(h)), label)
endfunction
//=============================================================================================================
function AttachReal takes handle h, string label, real x returns nothing
local string k=I2S(CS_H2I(h))
if x==0 then
call FlushStoredReal(CSCache(),k,label)
else
call StoreReal(CSCache(),k,label,x)
endif
endfunction
function GetAttachedReal takes handle h, string label returns real
return GetStoredReal(CSCache(),I2S(CS_H2I(h)),label)
endfunction
//=============================================================================================================
function AttachBoolean takes handle h, string label, boolean x returns nothing
local string k=I2S(CS_H2I(h))
if not x then
call FlushStoredBoolean(CSCache(),k,label)
else
call StoreBoolean(CSCache(),k,label,x)
endif
endfunction
function GetAttachedBoolean takes handle h, string label returns boolean
return GetStoredBoolean(CSCache(),I2S(CS_H2I(h)),label)
endfunction
//=============================================================================================================
function AttachString takes handle h, string label, string x returns nothing
local string k=I2S(CS_H2I(h))
if x=="" then
call FlushStoredString(CSCache(),k,label)
else
call StoreString(CSCache(),k,label,x)
endif
endfunction
function GetAttachedString takes handle h, string label returns string
return GetStoredString(CSCache(),I2S(CS_H2I(h)),label)
endfunction
//=============================================================================================================
function AttachObject takes handle h, string label, handle x returns nothing
local string k=I2S(CS_H2I(h))
if (x==null) then
call FlushStoredInteger(CSCache(),k,label)
else
call StoreInteger(CSCache(),k,label,CS_H2I(x))
endif
endfunction
function GetAttachedObject takes handle h, string label returns handle
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedWidget takes handle h, string label returns widget
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedRect takes handle h, string label returns rect
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedRegion takes handle h, string label returns region
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedTimerDialog takes handle h, string label returns timerdialog
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedUnit takes handle h, string label returns unit
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedItem takes handle h, string label returns item
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedEffect takes handle h, string label returns effect
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedDestructable takes handle h, string label returns destructable
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedTrigger takes handle h, string label returns trigger
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedTimer takes handle h, string label returns timer
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedGroup takes handle h, string label returns group
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedTriggerAction takes handle h, string label returns triggeraction
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedLightning takes handle h, string label returns lightning
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedImage takes handle h, string label returns image
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedUbersplat takes handle h, string label returns ubersplat
return GetAttachedInt(h,label)
return null
endfunction
function GetAttachedSound takes handle h, string label returns sound
return GetAttachedInt(h,label)
return null
endfunction
//============================================================================================================
// Attached Sets: Attachable Sets are handy in some situations and are a part of attachable variables,
// you can add integers or objects to a set, order doesn't matter and adding the same object twice is
// meaningless. CleanAttachedVars is always ready to clean every set owned by the handle.
//
//============================================================================================================
function AttachedSetAddInt takes handle h, string setn, integer int returns nothing
local gamecache g=CSCache()
local string k=I2S(CS_H2I(h))
local integer n
local integer x=GetStoredInteger(g,k,"#setnumberof;"+setn)
local integer y
if x==0 then
set y=GetStoredInteger(g,k,"#totalsets")+1
call StoreInteger(g,k,"#totalsets",y)
call StoreInteger(g,k,"#setnumberof;"+setn,y)
call StoreString(g,k,"#setName;"+I2S(y),setn)
endif
set k=k+";"+setn
if not HaveStoredInteger(g,k,"Pos"+I2S(int)) then
set n=GetStoredInteger(g,k,"n")+1
call StoreInteger(g,k,"n",n)
call StoreInteger(g,k,I2S(n),int)
call StoreInteger(g,k,"Pos"+I2S(int),n)
endif
set g=null
endfunction
function AttachedSetAddObject takes handle h, string setn, handle val returns nothing
call AttachedSetAddInt(h,setn,CS_H2I(val))
endfunction
//============================================================================================================
function AttachedSetHasInt takes handle h, string setn, integer int returns boolean
return HaveStoredInteger(CSCache(),I2S(CS_H2I(h))+";"+setn,"Pos"+I2S(int))
endfunction
function AttachedSetHasObject takes handle h, string setn, handle val returns boolean
return AttachedSetHasInt(h,setn,CS_H2I(val))
endfunction
//============================================================================================================
function GetAttachedSetSize takes handle h, string setn returns integer
return GetStoredInteger(CSCache(),I2S(CS_H2I(h))+";"+setn,"n")
endfunction
//============================================================================================================
function AttachedSetRemInt takes handle h, string setn, integer int returns nothing
local gamecache g=CSCache()
local string k=I2S(CS_H2I(h))+";"+setn
local integer n
local integer x
local integer y
if HaveStoredInteger(g,k,"Pos"+I2S(int)) then
set x=GetStoredInteger(g,k,"Pos"+I2S(int))
set n=GetStoredInteger(g,k,"n")
if x!=n then
set y=GetStoredInteger(g,k,I2S(n))
call StoreInteger(g,k,I2S(x),y)
call StoreInteger(g,k,"Pos"+I2S(y),x)
endif
call FlushStoredInteger(g,k,"Pos"+I2S(int))
call FlushStoredInteger(g,k,I2S(n))
call StoreInteger(g,k,"n",n-1)
endif
set g=null
endfunction
function AttachedSetRemObject takes handle h, string setn, handle val returns nothing
call AttachedSetRemInt(h,setn,CS_H2I(val))
endfunction
//============================================================================================================
function FromSetElement takes string setn, integer index returns string
local gamecache g=CSCache()
call StoreString(g,"argpass","set",setn)
call StoreString(g,"argpass","seti",I2S(index))
set g=null
return ""
endfunction
//============================================================================================================
function ClearAttachedSet takes handle h, string setn returns nothing
call FlushStoredMission(CSCache(),I2S(CS_H2I(h))+";"+setn)
endfunction
function CleanAttachedVars takes handle h returns nothing
local gamecache g=CSCache()
local string k=I2S(CS_H2I(h))
local integer n=GetStoredInteger(g,k,"#totalsets")
local integer i=1
loop
exitwhen i>n
call FlushStoredMission(g,k+";"+GetStoredString(g,k,"#setName;"+I2S(i)))
set i=i+1
endloop
call FlushStoredMission(g, k )
set g=null
endfunction
function CleanAttachedVars_NoSets takes handle h returns nothing
call FlushStoredMission(CSCache(), I2S(CS_H2I(h)) )
endfunction
//=============================================================================================
// Tables
//
// Tables are lame, the real name would be hash tables, they are just abbreviated usage
// of gamecache natives with the addition that you can also Copy the values of a table to
// another one, but don't expect it to be automatic, it must use a FieldData object to know
// which fields and of wich types to copy, Copying a table to another, with a lot of Fields,
// should surelly be lag friendly.
//
// The other thing about tables is that I can say that the Attached variables of a handle work
// inside a table and GetAttachmentTable which is just return bug and I2S , works to allow you
// to manipulate a handle's attached variables through a table.
//
// NewTable and DestroyTable were created to allow to create tables in the fly, but you can
// simply use strings for tables, but place the table names should be between "("")" for example
// "(mytable)" to avoid conflicts with other caster system stuff.
//
function NewTableIndex takes nothing returns integer
local gamecache g=CSCache()
local integer n=GetStoredInteger(g,"misc","FreeTableTotal")
local integer i
if (n>0) then
set i=GetStoredInteger(g,"misc","FreeTable1")
if (n>1) then
call StoreInteger(g,"misc","FreeTable1", GetStoredInteger(g,"misc","FreeTable"+I2S(n)) )
call FlushStoredInteger(g,"misc","FreeTable"+I2S(n))
endif
call StoreInteger(g,"misc","FreeTableTotal", n-1)
else
set i=GetStoredInteger(g,"misc","TableMaxReleasedIndex")+1
call StoreInteger(g,"misc","TableMaxReleasedIndex",i)
endif
call StoreBoolean(g,"misc","Created"+I2S(i),true)
set g=null
return i
endfunction
function NewTable takes nothing returns string
return I2S(NewTableIndex())
endfunction
function GetAttachmentTable takes handle h returns string
return I2S(CS_H2I(h))
endfunction
//============================================================================================================
function DestroyTable takes string table returns nothing
local gamecache g=CSCache()
local integer i=S2I(table)
local integer n
if (i!=0) and (GetStoredBoolean(g,"misc","Created"+table)) then
call FlushStoredBoolean(g,"misc","Created"+table)
set n=GetStoredInteger(g,"misc","FreeTableTotal")+1
call StoreInteger(g,"misc","FreeTableTotal",n)
call StoreInteger(g,"misc","FreeTable"+I2S(n),i)
endif
call FlushStoredMission(g,table)
set g=null
endfunction
//============================================================================================================
function ClearTable takes string table returns nothing
call FlushStoredMission(CSCache(),table)
endfunction
//============================================================================================================
function SetTableInt takes string table, string field, integer val returns nothing
local gamecache g=CSCache()
if (val==0) then
call FlushStoredInteger(g,table,field)
else
call StoreInteger(g,table,field,val)
endif
set g=null
endfunction
function GetTableInt takes string table, string field returns integer
return GetStoredInteger(CSCache(),table,field)
endfunction
//============================================================================================================
function SetTableReal takes string table, string field, real val returns nothing
local gamecache g=CSCache()
if (val==0) then
call FlushStoredReal(g,table,field)
else
call StoreReal(g,table,field,val)
endif
set g=null
endfunction
function GetTableReal takes string table, string field returns real
return GetStoredReal(CSCache(),table,field)
endfunction
//============================================================================================================
function SetTableBoolean takes string table, string field, boolean val returns nothing
local gamecache g=CSCache()
if (not(val)) then
call FlushStoredBoolean(g,table,field)
else
call StoreBoolean(g,table,field,val)
endif
set g=null
endfunction
function GetTableBoolean takes string table, string field returns boolean
return GetStoredBoolean(CSCache(),table,field)
endfunction
//============================================================================================================
function SetTableString takes string table, string field, string val returns nothing
local gamecache g=CSCache()
if (val=="") or (val==null) then
call FlushStoredString(g,table,field)
else
call StoreString(g,table,field,val)
endif
set g=null
endfunction
function GetTableString takes string table, string field returns string
return GetStoredString(CSCache(),table,field)
endfunction
//============================================================================================================
// You may ask why am I using thousands of functions instead of multi-use return bug exploiters? Well,
// these make the thing much easier to read (in my opinion) and it is also better in performance since we
// have less function calls (H2U(GetTableObject("table","unit"))) would be worse than GetTableUnit that is
// quite direct.
//
function SetTableObject takes string table, string field, handle val returns nothing
local gamecache g=CSCache()
if (val==null) then
call FlushStoredInteger(g,table,field)
else
call StoreInteger(g,table,field,CS_H2I(val))
endif
set g=null
endfunction
function GetTableObject takes string table, string field returns handle
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableWidget takes string table, string field returns widget
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableRect takes string table, string field returns rect
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableRegion takes string table, string field returns region
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableTimerDialog takes string table, string field returns timerdialog
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableUnit takes string table, string field returns unit
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableItem takes string table, string field returns item
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableEffect takes string table, string field returns effect
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableDestructable takes string table, string field returns destructable
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableTrigger takes string table, string field returns trigger
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableTimer takes string table, string field returns timer
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableGroup takes string table, string field returns group
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableTriggerAction takes string table, string field returns triggeraction
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableLightning takes string table, string field returns lightning
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableImage takes string table, string field returns image
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableUbersplat takes string table, string field returns ubersplat
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
function GetTableSound takes string table, string field returns sound
return GetStoredInteger(CSCache(),table,field)
return null
endfunction
//============================================================================================================
// Returns true if the fiel contains a value different from 0, false, null, or "" (depending on the type)
// it is worthless to use this with boolean, since it would be the same as reading the boolean value
//
function HaveSetField takes string table, string field, integer fieldType returns boolean
if (fieldType == bj_GAMECACHE_BOOLEAN) then
return HaveStoredBoolean(CSCache(),table,field)
elseif (fieldType == bj_GAMECACHE_INTEGER) then
return HaveStoredInteger(CSCache(),table,field)
elseif (fieldType == bj_GAMECACHE_REAL) then
return HaveStoredReal(CSCache(),table,field)
elseif (fieldType == bj_GAMECACHE_STRING) then
return HaveStoredString(CSCache(),table,field)
endif
return false
endfunction
//============================================================================================================
// Allows to copy a table to another one, but it needs a FieldData object to know which fields of which type
// it is supposed to copy.
//
function CopyTable takes integer FieldData, string sourceTable, string destTable returns nothing
local gamecache g=CSCache()
local integer i=1
local string k=I2S(FieldData)
local string k2
local string k3
local integer n=GetStoredInteger(g,k,"N")
local integer t
loop
exitwhen (i>n)
set k2=I2S(i)
set t=GetStoredInteger(g,k,k2)
set k3=GetStoredString(g,k,k2)
if (t==bj_GAMECACHE_BOOLEAN) then
if (HaveStoredBoolean(g,sourceTable,k3)) then
call StoreBoolean(g,destTable,k3,GetStoredBoolean(g,sourceTable,k3))
else
call FlushStoredBoolean(g,destTable,k3)
endif
elseif (t==bj_GAMECACHE_INTEGER) then
if (HaveStoredInteger(g,sourceTable,k3)) then
call StoreInteger(g,destTable,k3,GetStoredInteger(g,sourceTable,k3))
else
call FlushStoredInteger(g,destTable,k3)
endif
elseif (t==bj_GAMECACHE_REAL) then
if (HaveStoredReal(g,sourceTable,k3)) then
call StoreReal(g,destTable,k3,GetStoredReal(g,sourceTable,k3))
else
call FlushStoredReal(g,destTable,k3)
endif
elseif (t==bj_GAMECACHE_STRING) then
if (HaveStoredString(g,sourceTable,k3)) then
call StoreString(g,destTable,k3,GetStoredString(g,sourceTable,k3))
else
call FlushStoredString(g,destTable,k3)
endif
endif
set i=i+1
endloop
set g=null
endfunction
//=============================================================================================
// FieldData inherits from Table, was just designed to be used by CopyTable.
//
function FieldData_Create takes nothing returns integer
return NewTableIndex()
endfunction
//============================================================================================================
// valueType uses the same integer variables from blizzard.j :
// bj_GAMECACHE_BOOLEAN, bj_GAMECACHE_INTEGER, bj_GAMECACHE_REAL and bj_GAMECACHE_STRING
//
function FieldData_AddField takes integer fielddata, string field, integer valueType returns nothing
local gamecache g=CSCache()
local string k=I2S(fielddata)
local integer n=GetStoredInteger(g,k,"N")+1
local string k2=I2S(n)
call StoreString(g,k,k2,field)
call StoreInteger(g,k,k2,valueType)
call StoreInteger(g,k,"N",n)
set g=null
endfunction
//=============================================================================================
// Destroys Field Data
function FieldData_Destroy takes integer fielddata returns nothing
call DestroyTable(I2S(fielddata))
endfunction
//##End of CS Gamecache engine##
//==================================================================================================
// Angle Calculations
//
// I decided to add them to the caster system, because I found myself using them everytime, I am
// trying to convert the caster system into a Spell Development Framework (hehe)
//
//=================================================================================================
// Returns the angle distance between angles a1 and a2 (For example: a1=30 , a2=60 , return= 30 )
//
function Angles_GetAngleDifference takes real a1, real a2 returns real
local real x
set a1=ModuloReal(a1,360)
set a2=ModuloReal(a2,360)
if a1>a2 then
set x=a1
set a1=a2
set a2=x
endif
set x=a2-360
if a2-a1 > a1-x then
set a2=x
endif
return RAbsBJ(a1-a2)
endfunction
//=================================================================================================
// Returns the mid angle between a1 and a2 (For example: a1=30 , a2=60 , return= 45 )
//
function Angles_GetMidAngle takes real a1, real a2 returns real
local real x
set a1=ModuloReal(a1,360)
set a2=ModuloReal(a2,360)
if a1>a2 then
set x=a1
set a1=a2
set a2=x
endif
set x=a2-360
if a2-a1 > a1-x then
set a2=x
endif
return (a1+a2)/2
endfunction
//=================================================================================================
// Makes angle a1 advance i units towards angle a2 (For Example: a1=30, a2=60, i=10, return=40 )
//
function Angles_MoveAngleTowardsAngle takes real a1, real a2, real i returns real
local real x
set a1=ModuloReal(a1,360)
set a2=ModuloReal(a2,360)
if a1>a2 then
set x=a1-360
if a1-a2 > a2-x then
set a1=x
endif
else
set x=a2-360
if a2-a1 > a1-x then
set a2=x
endif
endif
if a1>a2 then
set x=a1-i
if x<=a2 then
return a2
endif
return x
endif
set x=a1+i
if x>=a2 then
return a2
endif
return x
endfunction
//=================================================================================================
// Returns true if the angle 'angle' is between 'angle1' and 'angle2'
//
function Angles_IsAngleBetweenAngles takes real angle, real angle1, real angle2 returns boolean
local real x
set angle=ModuloReal(angle,360)
set angle1=ModuloReal(angle1,360)
set angle2=ModuloReal(angle2,360)
if (angle1>angle2) then
set x=angle1
set angle1=angle2
set angle2=x
endif
if (angle2-angle1)>(angle1 - (angle2-360)) then
set angle2=angle2-360
if angle > 180 then
set angle=angle-360
endif
return angle>=angle2 and angle<=angle1
endif
return (angle>=angle1) and (angle<=angle2)
endfunction
//====================================================================================================================================================================
function CreateCaster takes real fac, real x , real y returns unit
local unit m
if (x!=0) then
set x=CS_SafeX(x)
endif
if (y!=0) then
set y=CS_SafeY(y)
endif
set m=CreateUnit( Player(15), Caster_UnitId(), x ,y ,fac)
call UnitAddAbility(m, 'Aloc')
call UnitAddAbility(m, ChangeableFlyingHeightAllowerId())
call UnitRemoveAbility(m, ChangeableFlyingHeightAllowerId())
set udg_currentcaster=m
set m=null
return udg_currentcaster
endfunction
function AddCasterFacing takes real fac returns unit
return CreateCaster(fac,0,0)
endfunction
function AddCaster takes nothing returns unit
return CreateCaster(0,0,0)
endfunction
//====================================================================================================================================================================
function CS_KillTrigger takes trigger t returns nothing
if (t!=null) then
call TriggerRemoveAction(t,GetAttachedTriggerAction(t,"ac"))
call CleanAttachedVars(t)
call DestroyTrigger(t)
endif
endfunction
function CS_KillTimer takes timer t returns nothing
if (t!=null) then
call PauseTimer(t)
call CleanAttachedVars(t)
call DestroyTimer(t)
endif
endfunction
//====================================================================================================================================================================
function CreateCasters takes integer n returns nothing
local integer a=0
local unit c
set udg_castervars[100]=-1
set udg_castervars[101]=-1
set udg_castervars[102]=-1
set udg_castervars[103]=-1
set udg_castervars[104]=-1
loop
exitwhen a>=n
set c=AddCaster()
call GroupAddUnit( udg_casters, c)
set a=a+1
endloop
set c=null
call RemoveLocation(udg_sourcehack)
set udg_sourcehack=null
endfunction
//====================================================================================================================================================================
function GetACaster takes nothing returns unit
set udg_currentcaster=FirstOfGroup( udg_casters)
if udg_currentcaster == null then
set udg_currentcaster=AddCaster()
endif
call GroupRemoveUnit( udg_casters,udg_currentcaster)
call SetUnitState( udg_currentcaster, UNIT_STATE_MANA, 1000)
return udg_currentcaster
endfunction
//====================================================================================================================================================================
function Caster_SetZAngle takes unit caster, real ang returns nothing
local real a=(ModuloReal(GetUnitFacing(caster),360)*bj_DEGTORAD)
local real x
set ang=ModuloReal(ang,360)
if ( ang == 90 ) then
set ang = 89
endif
if ( ang == 270 ) then
set ang = 271
endif
if (ang>90) and (ang<270) then
set x=-1
else
set x=1
endif
set ang=ang*bj_DEGTORAD
call SetUnitLookAt(caster,"Bone_Chest",caster, 10000.0*Cos(a)*Cos(ang), 10000.0*Sin(a)*Cos(ang), x*(10000.0*Tan(ang)+90.0) )
endfunction
//====================================================================================================================================================================
function RecicleCaster takes unit caster returns nothing
if not IsUnitDeadBJ(caster) then
call ResetUnitLookAt(caster)
call SetUnitOwner( caster, Player(15), true)
call SetUnitVertexColor( caster, 255,255,255,255)
call SetUnitScale( caster, 1,1,1)
call SetUnitTimeScale( caster, 1)
call SetUnitMoveSpeed( caster, 522)
call SetUnitFlyHeight( caster, 0,0)
call UnitAddAbility(caster, 'Aloc')
call SetUnitTurnSpeed( caster, 0.6)
call GroupAddUnit( udg_casters, caster)
endif
endfunction
function CasterRecycleTimed_X takes nothing returns nothing
local timer t=GetExpiredTimer()
local string k=GetAttachmentTable(t)
local unit c=GetTableUnit(k,"c")
local integer a=GetTableInt(k,"a")
if (a!=0) then
call UnitRemoveAbility(c,a)
endif
call RecicleCaster(c)
call ClearTable(k)
call DestroyTimer(t)
set c=null
set t=null
endfunction
function CasterRecycleTimed takes unit caster, integer abi, real delay returns nothing
local timer t=CreateTimer()
local string k=GetAttachmentTable(t)
call SetTableObject(k,"c",caster)
if (abi!=0) then
call SetTableInt(k,"a",abi)
endif
call TimerStart(t,delay,false,function CasterRecycleTimed_X)
set t=null
endfunction
function CasterWaitForEndCast takes nothing returns nothing
local unit caster=udg_currentcaster
local integer abilid=udg_currentabi
local real delay=udg_castervars[0]
local boolean activeability=(udg_castervars[1]>0)
loop
exitwhen GetUnitCurrentOrder(caster) == 0
call TriggerSleepAction(0)
endloop
if (delay>0) then
if activeability then
call CasterRecycleTimed(caster,abilid,delay)
else
call UnitRemoveAbility( caster, abilid)
call CasterRecycleTimed(caster,0,delay)
endif
else
call UnitRemoveAbility( caster, abilid)
call RecicleCaster(caster)
endif
set caster=null
endfunction
function RecicleCasterAfterCastEx takes unit caster, real delaytime, integer abilid, boolean activeability returns nothing
set udg_castervars[0]=delaytime
set udg_castervars[1]=IntegerTertiaryOp(activeability,1,0)
set udg_currentabi=abilid
set udg_currentcaster=caster
call ExecuteFunc("CasterWaitForEndCast" )
endfunction
function RecicleCasterAfterCast takes unit caster, integer abilid returns nothing
call RecicleCasterAfterCastEx(caster,udg_delayhack,abilid,false)
endfunction
//====================================================================================================================================================================
function PreloadAbility takes integer abilid returns integer
local unit u=FirstOfGroup(udg_casters)
if u==null then
set u=GetACaster()
call UnitAddAbility(u, abilid)
call UnitRemoveAbility(u, abilid)
call RecicleCaster( u)
else
call UnitAddAbility(u, abilid)
call UnitRemoveAbility(u, abilid)
endif
set u=null
return abilid
endfunction
//====================================================================================================================================================================
function CasterCastAbilityEx takes player owner, real x, real y, real z, integer abilid, integer level, string order, widget target, real delay returns unit
local unit caster=GetACaster()
local boolean done=false
call SetUnitOwner( caster, owner, false)
call UnitAddAbility( caster, abilid)
call SetUnitAbilityLevel(caster,abilid,level)
call CS_MoveUnit( caster, x,y)
call SetUnitFlyHeight(caster,z,0)
if S2I(order) != 0 then
set done=IssueTargetOrderById( caster, S2I(order), target )
else
set done=IssueTargetOrder( caster, order, target )
endif
if (delay<=0) or not(done) then
call UnitRemoveAbility( caster, abilid)
call RecicleCaster( caster)
else
call RecicleCasterAfterCastEx(caster, delay, abilid, true)
endif
set udg_currentcaster=caster
set caster=null
return udg_currentcaster
endfunction
//====================================================================================================================================================================
function CasterCastAbilityExLoc takes player owner, location loc, real z, integer abilid, integer level, string order, widget target, real delay returns unit
return CasterCastAbilityEx(owner,GetLocationX(loc),GetLocationY(loc),z,abilid,level,order,target,delay)
endfunction
//====================================================================================================================================================================
function CasterCastAbilityLevel takes player owner, integer abilid, integer level, string order, widget target, boolean instant returns unit
local real x
local real y
local real d
if udg_sourcehack!=null then
set x=GetLocationX(udg_sourcehack)
set y=GetLocationY(udg_sourcehack)
else
set x=GetWidgetX(target)
set y=GetWidgetY(target)
endif
if not(instant) then
set d=udg_delayhack+0.01
else
set d=0
endif
return CasterCastAbilityEx(owner,x,y,0,abilid,level,order,target,d)
endfunction
//====================================================================================================================================================================
function CasterCastAbility takes player owner, integer abilid, string order, widget target, boolean instant returns unit
return CasterCastAbilityLevel( owner, abilid, 1, order, target, instant )
endfunction
//====================================================================================================================================================================
function CasterCastAbilityPointEx takes player owner, real x1, real y1, real z1, integer abilid, integer level, string order, real x2, real y2, real delay returns unit
local unit caster=GetACaster()
call SetUnitOwner( caster, owner, false)
call UnitAddAbility( caster, abilid)
call SetUnitAbilityLevel(caster,abilid,level)
call CS_MoveUnit( caster, x1, y1)
call SetUnitFlyHeight(caster,z1,0)
if S2I(order) != 0 then
if not IssuePointOrderById( caster, S2I(order), x2,y2 ) then
call IssueImmediateOrderById( caster, S2I(order) )
endif
else
if not IssuePointOrder( caster, order, x2,y2 ) then
call IssueImmediateOrder( caster, order )
endif
endif
if (delay<=0) then
call UnitRemoveAbility( caster, abilid)
call RecicleCaster( caster)
else
call RecicleCasterAfterCastEx(caster, delay, abilid, true)
endif
set udg_currentcaster=caster
set caster=null
return udg_currentcaster
endfunction
//====================================================================================================================================================================
function CasterCastAbilityPointExLoc takes player owner, location loc1, real z1, integer abilid, integer level, string order, location loc2, real delay returns unit
return CasterCastAbilityPointEx(owner,GetLocationX(loc1),GetLocationY(loc1),z1,abilid,level,order,GetLocationX(loc2),GetLocationY(loc2),delay)
endfunction
//====================================================================================================================================================================
function CasterCastAbilityLevelPoint takes player owner, integer abilid, integer level, string order, real x, real y, boolean instant returns unit
local real sx
local real sy
local real d
if udg_sourcehack!=null then
set sx=GetLocationX(udg_sourcehack)
set sy=GetLocationY(udg_sourcehack)
else
set sx=x
set sy=y
endif
if instant then
set d=0
else
set d=udg_delayhack+0.01
endif
return CasterCastAbilityPointEx(owner,sx,sy,0,abilid,level,order,x,y,d)
endfunction
function CasterCastAbilityPoint takes player owner, integer abilid, string order, real x, real y, boolean instant returns unit
return CasterCastAbilityLevelPoint(owner,abilid,1,order,x,y,instant)
endfunction
function CasterCastAbilityPointLoc takes player owner, integer abilid, string order, location loc, boolean instant returns unit
return CasterCastAbilityLevelPoint( owner, abilid, 1,order, GetLocationX(loc), GetLocationY(loc), instant )
endfunction
function CasterCastAbilityLevelPointLoc takes player owner, integer abilid, integer level, string order, location loc, boolean instant returns unit
return CasterCastAbilityLevelPoint( owner, abilid, level,order, GetLocationX(loc), GetLocationY(loc), instant )
endfunction
//====================================================================================================================================================================
function CasterUseAbilityLevelStatic_Rec takes nothing returns nothing
local timer t=GetExpiredTimer()
local string k=GetAttachmentTable(t)
call RecicleCaster(GetTableUnit(k,"c"))
call ClearTable(k)
call DestroyTimer(t)
set t=null
endfunction
function CasterUseAbilityLevelStatic_X takes nothing returns nothing
local timer t=GetExpiredTimer()
local string k=GetAttachmentTable(t)
call DestroyEffect(GetTableEffect(k,"fx") )
call UnitRemoveAbility(GetTableUnit(k,"c"),GetTableInt(k,"a"))
call TimerStart(t,2,false, function CasterUseAbilityLevelStatic_Rec)
set t=null
endfunction
function CasterUseAbilityLevelStatic takes player owner, string modelpath, integer abilityid, integer level, real duration, real x, real y returns unit
local timer t=CreateTimer()
local string k=GetAttachmentTable(t)
local unit c=GetACaster()
call SetUnitPosition( c, x, y)
call SetTableObject(k,"fx", AddSpecialEffectTarget( modelpath, c,"origin" ))
call SetTableObject(k,"c",c)
call SetTableInt(k,"a",abilityid)
call TimerStart(t,duration,false,function CasterUseAbilityLevelStatic_X)
call SetUnitOwner(c, owner, true)
call UnitAddAbility(c, abilityid)
call SetUnitAbilityLevel(c, abilityid, level)
set udg_currentcaster=c
set t=null
set c=null
return udg_currentcaster
endfunction
function CasterUseAbilityStatic takes player owner, string modelpath, integer abilityid, real duration, real x, real y returns unit
return CasterUseAbilityLevelStatic(owner,modelpath,abilityid,1,duration,x,y)
endfunction
function CasterUseAbilityStaticLoc takes player owner, string modelpath, integer abilityid, real duration, location loc returns unit
return CasterUseAbilityLevelStatic(owner,modelpath,abilityid,1,duration, GetLocationX(loc), GetLocationY(loc))
endfunction
function CasterUseAbilityLevelStaticLoc takes player owner, string modelpath, integer abilityid, integer level,real duration, location loc returns unit
return CasterUseAbilityLevelStatic(owner,modelpath,abilityid,level,duration, GetLocationX(loc), GetLocationY(loc))
endfunction
//====================================================================================================================================================================
function CasterCastAbilityLevelGroup takes player owner, integer abilid, integer level,string order, group targetgroup, boolean instant returns nothing
local group affected
local unit tempunit
local unit caster=null
if bj_wantDestroyGroup then
set bj_wantDestroyGroup=false
set affected=targetgroup
else
set affected=CreateGroup()
call GroupAddGroup( targetgroup, affected)
endif
loop
set tempunit=FirstOfGroup(affected)
exitwhen tempunit == null
if instant then
if caster==null then
set caster=GetACaster()
call SetUnitOwner( caster, owner, false)
call UnitAddAbility( caster, abilid)
call SetUnitAbilityLevel( caster, abilid,level)
endif
if udg_sourcehack != null then
call CS_MoveUnit(caster,GetLocationX(udg_sourcehack),GetLocationY(udg_sourcehack))
else
call CS_MoveUnit( caster, GetUnitX(tempunit), GetUnitY(tempunit))
endif
if S2I(order) != 0 then
call IssueTargetOrderById( caster, S2I(order), tempunit )
else
call IssueTargetOrder( caster, order, tempunit )
endif
else
call CasterCastAbilityLevel( owner, abilid,level, order, tempunit, false)
endif
call GroupRemoveUnit(affected, tempunit)
endloop
if caster != null then
call UnitRemoveAbility( caster, abilid)
call RecicleCaster(caster)
endif
call DestroyGroup(affected)
set affected=null
set tempunit=null
set caster=null
endfunction
function CasterCastAbilityGroup takes player owner, integer abilid, string order, group targetgroup, boolean instant returns nothing
call CasterCastAbilityLevelGroup(owner,abilid,1,order,targetgroup,instant)
endfunction
//====================================================================================================================================================================
function CasterAOE_IsFilterEnemy takes nothing returns boolean
return IsUnitEnemy( GetFilterUnit(), bj_groupEnumOwningPlayer ) and not(IsUnitDeadBJ(GetFilterUnit()))
endfunction
function CasterAOE_IsFilterAlly takes nothing returns boolean
return IsUnitAlly( GetFilterUnit(), bj_groupEnumOwningPlayer ) and not(IsUnitDeadBJ(GetFilterUnit()))
endfunction
//====================================================================================================================================================================
function CasterCastAbilityLevelAOE takes player owner, integer abilid, integer level, string order, real x, real y, real radius, boolean goodeffect, boolean instant returns nothing
local boolexpr b
local group aoe=CreateGroup()
set bj_groupEnumOwningPlayer=owner
if goodeffect then
set b=Condition(function CasterAOE_IsFilterAlly)
else
set b=Condition(function CasterAOE_IsFilterEnemy)
endif
call CS_EnumUnitsInAOE(aoe, x,y, radius, b)
set bj_wantDestroyGroup=true
call CasterCastAbilityLevelGroup( owner, abilid, level, order, aoe, instant)
call DestroyBoolExpr(b)
set b=null
set aoe=null
endfunction
function CasterCastAbilityAOE takes player owner, integer abilid, string order, real x, real y, real radius, boolean goodeffect, boolean instant returns nothing
call CasterCastAbilityLevelAOE(owner,abilid,1,order,x,y,radius,goodeffect,instant)
endfunction
function CasterCastAbilityAOELoc takes player owner, integer abilid, string order, location center, real radius, boolean goodeffect, boolean instant returns nothing
call CasterCastAbilityLevelAOE(owner, abilid,1, order, GetLocationX(center), GetLocationY(center), radius, goodeffect, instant)
endfunction
function CasterCastAbilityLevelAOELoc takes player owner, integer abilid, integer level, string order, location center, real radius, boolean goodeffect, boolean instant returns nothing
call CasterCastAbilityLevelAOE(owner, abilid,level, order, GetLocationX(center), GetLocationY(center), radius, goodeffect, instant)
endfunction
//====================================================================================================================================================================
function ResetSourceHack takes nothing returns nothing
call RemoveLocation(udg_sourcehack)
set udg_sourcehack=null
call DestroyTimer(GetExpiredTimer() )
endfunction
function CasterSetCastSource takes real x, real y returns nothing
set udg_sourcehack=Location(x,y)
call TimerStart(CreateTimer(),0,false,function ResetSourceHack)
endfunction
function CasterSetCastSourceLoc takes location loc returns nothing
call CasterSetCastSource( GetLocationX(loc), GetLocationY(loc) )
endfunction
function ResetDelayHack takes nothing returns nothing
set udg_delayhack=0
call DestroyTimer(GetExpiredTimer() )
endfunction
//====================================================================================================================================================================
function CasterSetRecycleDelay takes real Delay returns nothing
set udg_delayhack=Delay
call TimerStart(CreateTimer(),0,false,function ResetDelayHack)
endfunction
//====================================================================================================================================================================
function DamageTypes takes attacktype attT, damagetype dmgT returns integer
set udg_castervars[100] = CS_H2I(attT)
set udg_castervars[101] = CS_H2I(dmgT)
return 1
endfunction
function DamageException takes unittype Exception, real ExceptionFactor returns integer
set udg_castervars[102] = CS_H2I(Exception)
set udg_castervars[103] = ExceptionFactor
return 2
endfunction
function DamageOnlyTo takes unittype ThisUnitType returns integer
set udg_castervars[104] = CS_H2I(ThisUnitType)
return 4
endfunction
constant function DontDamageSelf takes nothing returns integer
return 8
endfunction
constant function DamageTrees takes nothing returns integer
return 16
endfunction
constant function DamageOnlyVisibles takes nothing returns integer
return 32
endfunction
function DamageOnlyEnemies takes nothing returns integer
set udg_castervars[105]=0
return 64
endfunction
function ForceDamageAllies takes nothing returns integer
set udg_castervars[105]=1
return 64
endfunction
function DamageOnlyAllies takes nothing returns integer
set udg_castervars[105]=2
return 64
endfunction
function DamageFactorAbility1 takes integer spellid, real factor returns integer
set udg_castervars[106]=CS_Rawcode2Real(spellid)
set udg_castervars[107]=factor
return 128
endfunction
function DamageFactorAbility2 takes integer spellid, real factor returns integer
set udg_castervars[108]=CS_Rawcode2Real(spellid)
set udg_castervars[109]=factor
return 256
endfunction
function DamageFactorAbility3 takes integer spellid, real factor returns integer
set udg_castervars[110]=CS_Rawcode2Real(spellid)
set udg_castervars[111]=factor
return 512
endfunction
function DamageIgnore takes unittype ThisUnitType returns integer
set udg_castervars[112] = CS_H2I(ThisUnitType)
return 1024
endfunction
function DamageAlliedFactor takes real fct returns integer
set udg_castervars[113] = fct
return 2048
endfunction
constant function ConsiderOnlyDeadUnits takes nothing returns integer
return 4096
endfunction
constant function IgnoreDeadState takes nothing returns integer
return 8192
endfunction
//===============================================================================================
function IsDamageOptionIncluded takes integer DamageOptions, integer whichDamageOption returns boolean
local integer i=8192
if (DamageOptions==0) then
return false
endif
loop
exitwhen (i<=whichDamageOption)
if (DamageOptions>=i) then
set DamageOptions=DamageOptions-i
endif
set i=i/2
endloop
return (DamageOptions>=whichDamageOption)
endfunction
//=================================================================================================
function GetDamageFactor takes unit u,attacktype a, damagetype d returns real
local real hp=GetWidgetLife(u)
local real mana=GetUnitState(u,UNIT_STATE_MANA)
local real r
local unit caster=GetACaster()
call UnitRemoveAbility(caster,'Aloc') //Otherwise the units would flee like crazy
call CS_MoveUnit(caster,GetUnitX(u),GetUnitY(u))
call SetUnitOwner(caster,GetOwningPlayer(u),false)
set r=hp
if (hp<1) then
call SetWidgetLife(u,1)
set r=1
endif
call UnitDamageTarget(caster,u,0.01,true,false,a,d,null)
call RecicleCaster(caster)
if (mana>GetUnitState(u,UNIT_STATE_MANA)) then
//Unit had mana shield, return 1 and restore mana too.
call SetUnitState(u,UNIT_STATE_MANA,mana)
set r=1
else
set r= (r-GetWidgetLife(u))*100
endif
call SetWidgetLife(u,hp)
set caster=null
return r
endfunction
//======================================================================================================
// Fix for the unit type bugs from blizzard, amphibious units aren't considered ground for some reason
// so this considers any non flying unit as ground.
//
// Also heroes are resistant too, so in case UNIT_TYPE_RESISTANT is used it will return true in case the
// unit is a hero too.
//
function CS_IsUnitType takes unit u, unittype ut returns boolean
if (ut==UNIT_TYPE_GROUND) then
return not(IsUnitType(u,UNIT_TYPE_FLYING))
elseif (ut==UNIT_TYPE_RESISTANT) then
return IsUnitType(u,ut) or IsUnitType(u,UNIT_TYPE_HERO)
endif
return IsUnitType(u,ut)
endfunction
function GetDamageFactorByOptions takes unit hurter, unit target, integer d returns real
local real r=1
if (d>=8192) then
set d=d-8192
elseif (d>=4096) then
if (GetWidgetLife(target)>0.405) then
return 0.0
endif
set d=d-4096
elseif (GetWidgetLife(target)<=0.405) then
return 0.0
endif
if d>=2048 then
if IsUnitAlly(target,GetOwningPlayer(hurter)) then
set r=r*udg_castervars[113]
endif
set d=d-2048
endif
if d>=1024 then
if CS_IsUnitType(target, ConvertUnitType(R2I(udg_castervars[112])) ) then
return 0.0
endif
set d=d-1024
endif
if d>=512 then
if GetUnitAbilityLevel(target,CS_LoadRawcodeFromReal(110))>0 then
set r=r*udg_castervars[111]
endif
set d=d-512
endif
if d>=256 then
if GetUnitAbilityLevel(target,CS_LoadRawcodeFromReal(108))>0 then
set r=r*udg_castervars[109]
endif
set d=d-256
endif
if d>=128 then
if GetUnitAbilityLevel(target,CS_LoadRawcodeFromReal(106))>0 then
set r=r*udg_castervars[107]
endif
set d=d-128
endif
if d>=64 then
if (udg_castervars[105]==0) and IsUnitAlly(target,GetOwningPlayer(hurter)) then
return 0.0
elseif (udg_castervars[105]==2) and IsUnitEnemy(target,GetOwningPlayer(hurter)) then
return 0.0
endif
set d=d-64
endif
if d>=32 then
set d=d-32
if not CS_IsUnitVisible(target,GetOwningPlayer(hurter)) then
return 0.0
endif
endif
if d>=16 then
set d=d-16
endif
if d>=8 then
set d=d-8
if hurter==target then
return 0.0
endif
endif
if d>=4 then
set d=d-4
if not CS_IsUnitType( target, ConvertUnitType(R2I(udg_castervars[104])) ) then
return 0.0
endif
endif
if d>=2 then
set d=d-2
if CS_IsUnitType( target, ConvertUnitType(R2I(udg_castervars[102])) ) then
set r=r*udg_castervars[103]
endif
endif
if d>=1 then
set d=d-1
set r=r*GetDamageFactor(target,ConvertAttackType(R2I(udg_castervars[100])),ConvertDamageType(R2I(udg_castervars[101])))
endif
return r
endfunction
//======================================================================================================================
// This used to be needed because in 1.17 UnitDamageTarget didn't consider the damagetype argument, this bug
// was fixed in 1.18, and we no longer need this function, left for compatibility.
//
function DamageUnitByTypes takes unit hurter, unit target, real dmg, attacktype attT, damagetype dmgT returns boolean
return UnitDamageTarget(hurter,target,dmg,true,false,attT,dmgT,null)
endfunction
//=============================================================================================================================
function DamageUnitByOptions takes unit hurter, unit target, real dmg, integer DamageOptions returns boolean
local real f=GetDamageFactorByOptions(hurter,target,DamageOptions)
if (f==0) then
return false
endif
return UnitDamageTarget(hurter,target,dmg*f,true,false,null,null,null)
endfunction
//=============================================================================================================================
function DamageUnit takes player hurter, real damage, unit victim returns boolean
local unit caster=GetACaster()
call UnitRemoveAbility(caster,'Aloc') //Otherwise the units would flee like crazy
call CS_MoveUnit(caster,GetUnitX(victim),GetUnitY(victim))
call SetUnitOwner(caster,hurter,false)
call DamageUnitByTypes(caster,victim,damage,Caster_DefaultAttackType(),Caster_DefaultDamageType())
call RecicleCaster(caster)
return GetWidgetLife(victim)<=0 // I thought UnitDamageTarget returned true when it killed the unit, but nope, it returns true when it was able to do the damage.
endfunction
//====================================================================================================================================================================
function UnitDamageUnitTimed_Child takes nothing returns nothing
local real damage = udg_castervars[0]
local real damageperiod= udg_castervars[2]
local effect fx=bj_lastCreatedEffect
local timer t=CreateTimer()
local unit hurter=udg_currenthurter
local real next=0
local integer i=0
local real c
local unit target=udg_currentcaster
local damagetype dmgT=ConvertDamageType(R2I(udg_castervars[4]))
local attacktype attT=ConvertAttackType(R2I(udg_castervars[3]))
call TimerStart(t, udg_castervars[1]-0.01, false,null)
loop
if TimerGetElapsed(t) >= next then
exitwhen not UnitDamageTarget(hurter, target, damage,true,false, attT, dmgT,null)
exitwhen IsUnitDeadBJ(target)
set i=i+1
set next=i*damageperiod
endif
exitwhen (TimerGetRemaining(t) <= 0) or IsUnitDeadBJ(target)
call TriggerSleepAction(0)
endloop
call DestroyEffect(fx)
call DestroyTimer(t)
set t=null
set fx=null
set dmgT=null
set attT=null
endfunction
function UnitDamageUnitTimed takes unit hurter, real damageps, real damageperiod, real duration, unit target, string modelpath, string attachPointName, attacktype attT, damagetype dmgT returns nothing
local unit c=udg_currentcaster
set bj_lastCreatedEffect=AddSpecialEffectTarget( modelpath, target,attachPointName )
set udg_currentcaster=target
set udg_castervars[0]=damageps
set udg_castervars[1]=duration
set udg_castervars[2]=damageperiod
set udg_castervars[3]=CS_H2I(attT)
set udg_castervars[4]=CS_H2I(dmgT)
set udg_currenthurter=hurter
call ExecuteFunc("UnitDamageUnitTimed_Child")
set udg_currentcaster=c
set c=null
endfunction
//=============================================================================================================
// Left for compatibility
//
function DamageUnitTimedEx_Child takes nothing returns nothing
local real damage = udg_castervars[0]
local real damageperiod= udg_castervars[2]
local effect fx=bj_lastCreatedEffect
local timer t=CreateTimer()
local integer id=udg_currentabi
local real next=0
local integer i=0
local real c
local unit target=udg_currentcaster
call TimerStart(t, udg_castervars[1]-0.01, false,null)
loop
if TimerGetElapsed(t) >= next then
exitwhen DamageUnit( Player(id), damage, target)
set i=i+1
set next=i*damageperiod
endif
exitwhen (TimerGetRemaining(t) <= 0) or IsUnitDeadBJ(target)
call TriggerSleepAction(0)
endloop
call DestroyEffect(fx)
call DestroyTimer(t)
set t=null
set fx=null
endfunction
function DamageUnitTimedEx takes player owner, real damageps, real damageperiod, real duration, unit target, string modelpath, string attachPointName returns nothing
local unit c=udg_currentcaster
set bj_lastCreatedEffect=AddSpecialEffectTarget( modelpath, target,attachPointName )
set udg_currentcaster=target
set udg_castervars[0]=damageps
set udg_castervars[1]=duration
set udg_castervars[2]=damageperiod
set udg_currentabi=GetPlayerId( owner )
call ExecuteFunc("DamageUnitTimedEx_Child")
set udg_currentcaster=c
set c=null
endfunction
function DamageUnitTimed takes player owner, real damageps, real duration, unit target, string modelpath, string attachPointName returns nothing
call DamageUnitTimedEx(owner , damageps, 1, duration, target, modelpath, attachPointName )
endfunction
function SetDamageOptions_i takes gamecache g, integer n, integer DamageOptions returns nothing
local string key="DOPT"+I2S(n)
local integer d=DamageOptions
call StoreInteger(g,key,"value",d)
if (d>=8192) then
set d=d-8192
endif
if (d>=4096) then
set d=d-4096
endif
if d>=2048 then
call StoreReal(g,key,"allf",udg_castervars[113])
set d=d-2048
endif
if d>=1024 then
call StoreInteger(g,key,"ign",R2I(udg_castervars[112]))
set d=d-1024
endif
if d>=512 then
call StoreInteger(g,key,"ab3",CS_LoadRawcodeFromReal(110))
call StoreReal(g,key,"fc3",udg_castervars[111])
set d=d-512
endif
if d>=256 then
call StoreInteger(g,key,"ab2",CS_LoadRawcodeFromReal(108))
call StoreReal(g,key,"fc2",udg_castervars[109])
set d=d-256
endif
if d>=128 then
call StoreInteger(g,key,"ab1",CS_LoadRawcodeFromReal(106))
call StoreReal(g,key,"fc1",udg_castervars[107])
set d=d-128
endif
if d >= 64 then
set d=d-64
call StoreInteger(g,key,"allied",R2I(udg_castervars[105]))
endif
if d >= 32 then
set d=d-32
endif
if d >= 16 then
set d=d-16
endif
if d >= 8 then
set d=d-8
endif
if d >= 4 then
call StoreInteger(g,key,"only",R2I(udg_castervars[104]))
set d=d-4
endif
if d >= 2 then
call StoreInteger(g,key,"excp",R2I(udg_castervars[102]))
call StoreReal(g,key,"excf",udg_castervars[103])
set d=d-2
endif
if d >= 1 then
call StoreInteger(g,key,"attT",R2I(udg_castervars[100]))
call StoreInteger(g,key,"dmgT",R2I(udg_castervars[101]))
endif
endfunction
function SetDamageOptions takes integer id, integer DamageOptions returns nothing
call SetDamageOptions_i(CSCache(),id,DamageOptions)
endfunction
function CreateDamageOptions takes integer DamageOptions returns integer
local gamecache g=CSCache()
local integer n=GetStoredInteger(g,"misc","DOPTn")+1
call StoreInteger(g,"misc","DOPTn",n)
call SetDamageOptions_i(g,n,DamageOptions)
set g=null
return n
endfunction
function DestroyDamageOptions takes integer id returns nothing
call FlushStoredMission(CSCache(),"DOPT"+I2S(id))
endfunction
function LoadDamageOptions takes integer id returns integer
local gamecache g=CSCache()
local string key="DOPT"+I2S(id)
local integer opt=GetStoredInteger(g,key,"value")
local integer v=opt
if v>=8192 then
set v=v-8192
endif
if v>=4096 then
set v=v-4096
endif
if v>=2048 then
set udg_castervars[113]=GetStoredReal(g,key,"allf")
set v=v-2028
endif
if v>=1024 then
set udg_castervars[112]= GetStoredInteger(g,key,"ign")
set v=v-1024
endif
if v>=512 then
set udg_castervars[110]=CS_Rawcode2Real(GetStoredInteger(g,key,"ab3"))
set udg_castervars[111]=GetStoredReal(g,key,"fc3")
set v=v-512
endif
if v>=256 then
set udg_castervars[108]=CS_Rawcode2Real(GetStoredInteger(g,key,"ab2"))
set udg_castervars[109]=GetStoredReal(g,key,"fc2")
set v=v-256
endif
if v>=128 then
set udg_castervars[106]=CS_Rawcode2Real(GetStoredInteger(g,key,"ab1"))
set udg_castervars[107]=GetStoredReal(g,key,"fc1")
set v=v-128
endif
if v >= 64 then
set v=v-64
set udg_castervars[105]= GetStoredInteger(g,key,"allied")
endif
if v >= 32 then
set v=v-32
endif
if v >= 16 then
set v=v-16
endif
if v >= 8 then
set v=v-8
endif
if v >= 4 then
set udg_castervars[104]=GetStoredInteger(g,key,"only")
set v=v-4
endif
if v >= 2 then
set udg_castervars[102]=GetStoredInteger(g,key,"excp")
set udg_castervars[103]=GetStoredReal(g,key,"excf")
set v=v-2
endif
if v >= 1 then
set udg_castervars[100]=GetStoredInteger(g,key,"attT")
set udg_castervars[101]=GetStoredInteger(g,key,"dmgT")
endif
set g=null
return opt
endfunction
//==================================================================================================
function IsDestructableTree_withcs takes destructable d returns boolean
local unit c=GetACaster()
local boolean b
local boolean i=IsDestructableInvulnerable(d)
local integer s=DamageTreeDetectorId()
if i then
call SetDestructableInvulnerable(d,false)
endif
call UnitAddAbility(c,s)
call CS_MoveUnit(c,GetWidgetX(d),GetWidgetY(d))
set b=(IssueTargetOrder(c,"eattree",d))
call UnitRemoveAbility(c,s)
call RecicleCaster(c)
set c=null
if i then
call SetDestructableInvulnerable(d,true)
endif
return b
endfunction
function IsDestructableTree takes destructable d returns boolean
local gamecache g=CSCache()
local string k=I2S(GetDestructableTypeId(d))
local boolean b
if HaveStoredBoolean(g,"trees",k) then
set b=GetStoredBoolean(g,"trees",k)
set g=null
return b
else
set b=IsDestructableTree_withcs(d)
call StoreBoolean(g,"trees",k,b)
endif
set g=null
return b
endfunction
//===============================================================================================
function DamageDestructablesInCircleEnum takes nothing returns nothing
local destructable d=GetEnumDestructable()
local unit u=udg_currentcaster
if (GetWidgetLife(d)>0) and not(IsDestructableInvulnerable(d)) and ((Pow(GetDestructableX(d)-udg_castervars[200],2)+Pow(GetDestructableY(d)-udg_castervars[201],2)) <= udg_castervars[202]) then
call SetWidgetLife(d,GetWidgetLife(d)-udg_castervars[203])
endif
set udg_currentcaster=u
set u=null
set d=null
endfunction
function DamageDestructablesInCircle takes real x, real y, real radius, real dmg returns nothing
local rect r=Rect(x - radius,y - radius,x + radius,y + radius)
set udg_castervars[200]=x
set udg_castervars[201]=y
set udg_castervars[202]=radius*radius
set udg_castervars[203]=dmg
call EnumDestructablesInRect(r,null,function DamageDestructablesInCircleEnum)
call RemoveRect(r)
set r=null
endfunction
function DamageDestructablesInCircleLoc takes location loc, real radius, real dmg returns nothing
call DamageDestructablesInCircle(GetLocationX(loc),GetLocationY(loc),radius,dmg)
endfunction
function DamageTreesInCircleEnum takes nothing returns nothing
local destructable d=GetEnumDestructable()
if (GetWidgetLife(d)>0) and not(IsDestructableInvulnerable(d)) and ((Pow(GetDestructableX(d)-udg_castervars[200],2)+Pow(GetDestructableY(d)-udg_castervars[201],2)) <= udg_castervars[202]) and (IsDestructableTree(d)) then
call KillDestructable(d)
endif
set d=null
endfunction
function DamageTreesInCircle takes real x, real y, real radius returns nothing
local rect r=Rect(x - radius,y - radius,x + radius,y + radius)
set udg_castervars[200]=x
set udg_castervars[201]=y
set udg_castervars[202]=radius*radius
call EnumDestructablesInRect(r,null,function DamageTreesInCircleEnum)
call RemoveRect(r)
set r=null
endfunction
function DamageTreesInCircleLoc takes location loc, real radius returns nothing
call DamageTreesInCircle(GetLocationX(loc),GetLocationY(loc),radius)
endfunction
function DamageUnitGroupEx takes unit hurter, real damage, group targetgroup, integer DamageOptions returns nothing
local group affected
local unit p
if bj_wantDestroyGroup then
set bj_wantDestroyGroup=false
set affected=targetgroup
else
set affected=CreateGroup()
call GroupAddGroup( targetgroup, affected)
endif
loop
set p=FirstOfGroup(affected)
exitwhen p==null
call DamageUnitByOptions(hurter,p,damage,DamageOptions)
call GroupRemoveUnit(affected,p)
endloop
call DestroyGroup(affected)
set affected=null
set p=null
endfunction
function DamageUnitsInAOEEx takes unit hurter, real damage, real x, real y, real radius, boolean affectallied, integer DamageOptions returns nothing
local boolexpr b=null
local group aoe=CreateGroup()
local integer d=DamageOptions
set bj_groupEnumOwningPlayer=GetOwningPlayer(hurter)
if d>=8192 then
set d=d-8192
endif
if d>=4096 then
set d=d-4096
endif
if d>=2048 then
set d=d-2048
endif
if d>=1024 then
set d=d-1024
endif
if d>=512 then
set d=d-512
endif
if d>=256 then
set d=d-256
endif
if d>=128 then
set d=d-128
endif
if d>=64 then
if (udg_castervars[105]==2) then
set b=Condition(function CasterAOE_IsFilterAlly)
elseif (udg_castervars[105]==1) then
else
set b=Condition(function CasterAOE_IsFilterEnemy)
endif
set d=d-64
elseif not(affectallied) then
set b=Condition(function CasterAOE_IsFilterEnemy)
endif
if d>=32 then
set d=d-32
endif
if d>=16 then
call DamageTreesInCircle(x,y,radius)
endif
call CS_EnumUnitsInAOE(aoe, x,y, radius, b)
set bj_wantDestroyGroup=true
call DamageUnitGroupEx( hurter, damage, aoe,DamageOptions)
call DestroyBoolExpr(b)
set b=null
set aoe=null
endfunction
function DamageUnitsInAOEExLoc takes unit hurter, real damage, location loc, real radius, boolean affectallied, integer DamageOptions returns nothing
call DamageUnitsInAOEEx(hurter,damage, GetLocationX(loc), GetLocationY(loc), radius, affectallied,DamageOptions)
endfunction
function DamageUnitGroup takes player hurter, real damage, group targetgroup returns nothing
local unit caster=GetACaster()
call UnitRemoveAbility(caster,'Aloc') //Otherwise the units would flee like crazy
call SetUnitOwner(caster,hurter,false)
call DamageUnitGroupEx(caster,damage,targetgroup,0)
call RecicleCaster(caster)
set caster=null
endfunction
//====================================================================================================================================================================
function DamageUnitsInAOE takes player hurter, real damage, real x, real y, real radius, boolean affectallied returns nothing
local unit caster=GetACaster()
call UnitRemoveAbility(caster,'Aloc') //Otherwise the units would flee like crazy
call SetUnitOwner(caster,hurter,false)
call DamageUnitsInAOEEx(caster,damage,x,y,radius,affectallied,0)
call RecicleCaster(caster)
set caster=null
endfunction
function DamageUnitsInAOELoc takes player hurter, real damage, location loc, real radius, boolean affectallied returns nothing
call DamageUnitsInAOE( hurter, damage, GetLocationX(loc), GetLocationY(loc), radius, affectallied)
endfunction
//====================================================================================================================================================================
function AddAreaDamagerForUnit_Child takes nothing returns nothing
local real D
local real damageps = udg_castervars[0]
local real area = udg_castervars[2]
local real damageperiod = udg_castervars[3]
local real excd=udg_castervars[8]
local boolean affectallies = (udg_castervars[4]>=1)
local boolean onlyallies = (udg_castervars[4]==2)
local boolean self = (udg_castervars[5]==1)
local unit hurter=udg_currenthurter
local unit fire = udg_currentcaster
local player owner = GetOwningPlayer(fire)
local timer t = CreateTimer()
local real next = 0
local integer a = 0
local group inrange = CreateGroup()
local string c
local string art=bj_lastPlayedMusic
local string attach=""
local unit picked
local boolean recicled=false
local unittype only=null
local unittype ign=null
local unittype exce=null
local attacktype attT
local damagetype dmgT
local boolean trees=(udg_castervars[11]==1)
local boolean inv=(udg_castervars[12]==1)
local integer a1=0
local integer a2=0
local integer a3=0
local real f1=udg_castervars[107]
local real f2=udg_castervars[109]
local real f3=udg_castervars[111]
local real allf=udg_castervars[113]
local effect array fx
local integer deadcond=R2I(udg_castervars[114])
local boolean deadeval=false
local integer fxn=0
set fx[0]=bj_lastCreatedEffect
if f1!=1 then
set a1=CS_LoadRawcodeFromReal(106)
endif
if f2!=1 then
set a2=CS_LoadRawcodeFromReal(108)
endif
if f3!=1 then
set a3=CS_LoadRawcodeFromReal(110)
endif
if udg_castervars[112]!=-1 then
set ign=ConvertUnitType(R2I(udg_castervars[112]))
endif
if udg_castervars[6]!=-1 then
set only=ConvertUnitType(R2I(udg_castervars[6]))
endif
if udg_castervars[7]!=-1 then
set exce=ConvertUnitType(R2I(udg_castervars[7]))
endif
if udg_castervars[9]!=-1 then
set attT=ConvertAttackType(R2I(udg_castervars[9]))
else
set attT=Caster_DefaultAttackType()
endif
if udg_castervars[10]!=-1 then
set dmgT=ConvertDamageType(R2I(udg_castervars[10]))
else
set dmgT=Caster_DefaultDamageType()
endif
loop
set c=SubString(art,a,a+1)
exitwhen c=="!" or c==""
set attach=attach+c
set a=a+1
endloop
set art=SubString(art,a+1,10000)
call TimerStart(t, udg_castervars[1]-0.01, false,null)
set a=0
loop
loop
exitwhen fxn<=0
call DestroyEffect(fx[fxn])
set fx[fxn]=null
set fxn=fxn-1
endloop
if IsUnitInGroup( fire, udg_casters) then
set recicled=true
call GroupRemoveUnit( udg_casters,fire)
endif
exitwhen recicled
if TimerGetElapsed(t) >= next then
set a=a+1
set next=a*damageperiod
call CS_EnumUnitsInAOE(inrange, GetUnitX(fire), GetUnitY(fire), area, null )
if trees then
call DamageTreesInCircle(GetUnitX(fire), GetUnitY(fire), area)
endif
loop
set picked=FirstOfGroup(inrange)
exitwhen picked==null
if (deadcond==0) then
set deadeval=(GetWidgetLife(picked)>0.405)
elseif(deadcond==1)then
set deadeval=(GetWidgetLife(picked)<=0.405)
else
set deadeval=true
endif
if (self or picked!=hurter) and not(IsUnitDeadBJ(picked)) and ( ((affectallies or onlyallies) and IsUnitAlly(picked, owner)) or (not(onlyallies) and IsUnitEnemy(picked, owner)) ) and (only==null or CS_IsUnitType(picked,only)) and (ign==null or not(CS_IsUnitType(picked,ign))) then
set D=damageps
if (allf!=1) and IsUnitAlly(picked, owner) then
set D=D*allf
endif
if (exce!=null) and CS_IsUnitType(picked,exce) then
set D=D*excd
endif
if inv and not(CS_IsUnitVisible(picked,owner)) then
set D=0
endif
if (a1!=0) and (GetUnitAbilityLevel(picked,a1)>0) then
set D=D*f1
endif
if (a2!=0) and (GetUnitAbilityLevel(picked,a2)>0) then
set D=D*f2
endif
if (a3!=0) and (GetUnitAbilityLevel(picked,a3)>0) then
set D=D*f3
endif
if D!=0 then
call DamageUnitByTypes(hurter,picked,D,attT,dmgT )
if (art!="") and (art!=null) then
set fxn=fxn+1
set fx[fxn]=AddSpecialEffectTarget(art,picked,attach)
endif
endif
endif
call GroupRemoveUnit(inrange,picked)
endloop
endif
exitwhen TimerGetRemaining(t)<=0
call TriggerSleepAction(0)
endloop
call DestroyGroup(inrange)
call DestroyEffect(fx[0])
call TriggerSleepAction(2)
call RecicleCaster(fire)
call DestroyTimer(t)
set inrange=null
set fire=null
set t=null
set owner=null
set fx[0]=null
set picked=null
set hurter=null
set only=null
set ign=null
set exce=null
set attT=null
set dmgT=null
endfunction
function AddAreaDamagerForUnit takes unit hurter, string modelpath, string targetart, string targetattach, real x, real y, real damage , real damageperiod, real duration, real area, boolean affectallies, integer DamageOptions returns unit
local string s=bj_lastPlayedMusic
local integer v=DamageOptions
set bj_lastPlayedMusic=targetattach+"!"+targetart
set udg_currentcaster=GetACaster()
call SetUnitPosition( udg_currentcaster, x, y)
set bj_lastCreatedEffect = AddSpecialEffectTarget( modelpath, udg_currentcaster,"origin" )
set udg_castervars[0]=damage
set udg_castervars[1]=duration
set udg_castervars[2]=area
set udg_castervars[3]=damageperiod
if(v>=8192)then
set udg_castervars[114]=2
set v=v-8192
elseif (v>=4096)then
set udg_castervars[114]=1
set v=v-4096
else
set udg_castervars[114]=0
endif
if v>=2048 then
set v=v-2048
else
set udg_castervars[113]=1
endif
if v >= 1024 then
set v=v-1024
else
set udg_castervars[112]=-1
endif
if v >= 512 then
set v=v-512
else
set udg_castervars[111]=0
endif
if v >= 256 then
set v=v-256
else
set udg_castervars[109]=0
endif
if v >= 128 then
set v=v-128
else
set udg_castervars[107]=0
endif
if v >= 64 then
set v=v-64
set udg_castervars[4]=udg_castervars[105]
else
set udg_castervars[4]=IntegerTertiaryOp(affectallies,1,0)
endif
if v >= 32 then
set udg_castervars[12]=1
set v=v-32
else
set udg_castervars[12]=0
endif
if v >= 16 then
set udg_castervars[11]=1
set v=v-16
else
set udg_castervars[11]=0
endif
if v >= 8 then
set udg_castervars[5]=0
set v=v-8
else
set udg_castervars[5]=1
endif
if v >= 4 then
set udg_castervars[6]=udg_castervars[104]
set v=v-4
else
set udg_castervars[6]=-1
endif
if v >= 2 then
set udg_castervars[7]=udg_castervars[102]
set udg_castervars[8]=damage*udg_castervars[103]
set v=v-2
else
set udg_castervars[7]=-1
set udg_castervars[8]=-1
endif
if v >= 1 then
set udg_castervars[9]=udg_castervars[100]
set udg_castervars[10]=udg_castervars[101]
else
set udg_castervars[9]=-1
set udg_castervars[10]=-1
endif
set udg_currenthurter=hurter
call SetUnitOwner( udg_currentcaster, GetOwningPlayer(hurter), true)
call ExecuteFunc("AddAreaDamagerForUnit_Child")
set bj_lastPlayedMusic=s
return udg_currentcaster
endfunction
function AddAreaDamagerForUnitLoc takes unit hurter, string modelpath, string targetart, string targetattach, location loc, real damage , real damageperiod, real duration, real area, boolean affectallies, integer DamageOptions returns unit
return AddAreaDamagerForUnit(hurter,modelpath,targetart,targetattach,GetLocationX(loc),GetLocationY(loc), damage , damageperiod, duration, area,affectallies, DamageOptions)
endfunction
function AddDamagingEffectEx takes player owner, string modelpath, string targetart, string targetattach, real x, real y, real damage , real damageperiod, real duration, real area, boolean affectallies returns unit
local string s=bj_lastPlayedMusic
set bj_lastPlayedMusic=targetattach+"!"+targetart
set udg_currentcaster=GetACaster()
call SetUnitPosition( udg_currentcaster, x, y)
set bj_lastCreatedEffect = AddSpecialEffectTarget( modelpath, udg_currentcaster,"origin" )
set udg_castervars[0]=damage
set udg_castervars[1]=duration
set udg_castervars[2]=area
set udg_castervars[3]=damageperiod
set udg_castervars[4]=IntegerTertiaryOp(affectallies,1,0)
set udg_castervars[5]=1
set udg_castervars[6]=-1
set udg_castervars[7]=-1
set udg_castervars[8]=-1
set udg_castervars[9]=-1
set udg_castervars[10]=-1
set udg_castervars[107]=0
set udg_castervars[109]=0
set udg_castervars[111]=0
set udg_castervars[112]=-1
set udg_castervars[113]=1
set udg_currenthurter=udg_currentcaster
call SetUnitOwner( udg_currentcaster, owner, true)
call ExecuteFunc("AddAreaDamagerForUnit_Child")
set bj_lastPlayedMusic=s
return udg_currentcaster
endfunction
function AddDamagingEffectExLoc takes player owner, string modelpath, string targetart, string targetattach, location loc, real damage , real damageperiod, real duration, real area, boolean affectallies returns unit
return AddDamagingEffectEx( owner, modelpath, targetart, targetattach, GetLocationX(loc), GetLocationY(loc), damage , damageperiod, duration, area, affectallies )
endfunction
function AddDamagingEffect takes player owner, string modelpath, real x, real y, real damageps , real duration, real area, boolean affectallies returns unit
return AddDamagingEffectEx( owner, modelpath, "", "", x, y, damageps , 1, duration, area, affectallies )
endfunction
function AddDamagingEffectLoc takes player owner, string modelpath, location loc, real damageps , real duration, real area, boolean affectallies returns unit
return AddDamagingEffectEx( owner, modelpath, "", "", GetLocationX(loc), GetLocationY(loc), damageps ,1, duration, area, affectallies)
endfunction
//============================================================================================================
function UnitMoveToAsProjectileAnySpeed_Target takes gamecache H, string a, string b returns unit
return GetStoredInteger(H,a,b)
return null
endfunction
function UnitMoveToAsProjectileAnySpeed_Move takes gamecache H, unit m, string k returns boolean
local boolean tounit = GetStoredBoolean(H,k,"unit")
local unit tg
local real x2
local real y2
local real z2
local real x1=GetUnitX(m)
local real y1=GetUnitY(m)
local real z1=GetUnitFlyHeight(m)
local real g
local real d
local real od
local real v
local real time
local integer n
local boolean done=false
local effect fx
if tounit then
set tg=UnitMoveToAsProjectileAnySpeed_Target(H,k,"tg")
if (GetWidgetLife(tg)<=0.405) then
set tounit=false
call StoreBoolean(H,k,"unit",false)
else
set x2=GetUnitX(tg)
set y2=GetUnitY(tg)
set z2=GetUnitFlyHeight(tg)+GetStoredReal(H,k,"z2o")
set n=GetStoredInteger(H,k,"N")
set n=n+1
if (n==0) then
//I have the tilt writing on gamecache is slower than reading, in that case I prevent writting
// these 3 reals, but use a counter so each second they are backuped.
// They are needed because if the unit dies or is removed, they would otherwise go to the
// center of the map, and that is not something nice.
call StoreReal(H,k,"z2",z2)
call StoreReal(H,k,"x2",x2) // Backup stuff just in case
call StoreReal(H,k,"y2",y2)
elseif (n==25) then
set n=0
endif
call StoreInteger(H,k,"N",n)
endif
set tg=null
endif
if not(tounit) then
set z2=GetStoredReal(H,k,"z2")
set x2=GetStoredReal(H,k,"x2")
set y2=GetStoredReal(H,k,"y2")
endif
set g=Atan2(y2-y1,x2-x1)
call SetUnitFacing(m,g*bj_RADTODEG)
set v=GetStoredReal(H,k,"speed")
set d= v * CS_Cycle()
set od=SquareRoot(Pow(x1-x2,2) + Pow(y1-y2,2))
if( od <=d )then
call CS_MoveUnit(m , x2, y2 )
set done=true
else
call CS_MoveUnit(m , x1+d*Cos(g), y1+d*Sin(g) )
endif
set g=GetStoredReal(H,k,"acel")
set time= od / v
set v=(z2-z1+0.5*g*time*time)/time //z speed
call SetUnitFlyHeight(m,z1+v*CS_Cycle(),0)
set d=( Pow(GetUnitX(m)-x2,2) + Pow(GetUnitY(m)-y2,2) )
if (done or (d<=400)) then //So the actual distance is less than or equal to 20
set done=true
call StoreBoolean(H,k,"done",true)
set fx=GetTableEffect(k,"fx")
if (fx!=null) then
call DestroyEffect(fx)
set fx=null
endif
endif
return done
endfunction
function CollisionMissile_Destroyer takes gamecache H, unit m, string k, trigger T returns nothing
local effect fx=GetTableEffect(k,"fx")
call TriggerExecute(T)
if (fx!=null) then
call DestroyEffect(fx)
set fx=null
endif
call FlushStoredInteger(H,"MOVEMENT_TABLES",GetAttachmentTable(m))
call FlushStoredInteger(H,"MOVEMENT_TABLES",GetAttachmentTable(T))
if GetTableBoolean(k,"new") then
call ExplodeUnitBJ(m)
else
call RecicleCasterAfterCastEx(m,4,0,true)
endif
call DestroyTable(k)
call TriggerRemoveAction(T,GetTableTriggerAction(k,"ac"))
call CleanAttachedVars(T)
call DestroyTrigger(T)
endfunction
function GetTriggerCollisionMissile takes nothing returns unit
return GetStoredInteger( CSCache(), GetAttachmentTable(GetTriggeringTrigger()), "m" )
return null
endfunction
function CollisionMissile_Move takes gamecache g, unit m, string k returns boolean
local integer state=GetStoredInteger(g,k,"state")
local boolean done=(state==2)
local real d
local real F
local real asp
local real x
local real nx
local real y
local real ny
local integer tt
local widget wd
if not(done) then
if (state==1) then
call TriggerRegisterUnitInRange(GetTableTrigger(k,"T"),m,GetStoredReal(g,k,"collision"),null)
call FlushStoredInteger(g,k,"state")
endif
set d=GetStoredReal(g,k,"speed") * CS_Cycle()
set F=GetStoredReal(g,k,"F")
set asp=GetStoredReal(g,k,"aspeed")
set x=GetUnitX(m)
set y=GetUnitY(m)
if (asp!=0) then
set tt=GetStoredInteger(g,k,"TType")
if (tt==1) or (tt==2) then
if (tt==1) then
set nx=GetStoredReal(g,k,"Tx")
set ny=GetStoredReal(g,k,"Ty")
else
set wd=GetTableWidget(k,"Tw")
if (GetWidgetLife(wd)<=0.405) then
call StoreInteger(g,k,"TType",0)
set nx=x+0.001
set ny=y+0.001
else
set nx=GetWidgetX(wd)
set ny=GetWidgetY(wd)
endif
set wd=null
endif
set F=Angles_MoveAngleTowardsAngle(F,Atan2BJ(ny-y,nx-x), asp * CS_Cycle())
else
set F=F+ asp * CS_Cycle()
endif
call StoreReal(g,k,"F",F)
call SetUnitFacing(m,F)
endif
set F=F*bj_DEGTORAD
set nx=x+d*Cos(F)
set ny=y+d*Sin(F)
set d=GetStoredReal(g,k,"maxd")-d
call StoreReal(g,k,"maxd",d)
set done=(d<=0)
if not(CS_MoveUnit(m,nx,ny)) then
call SetUnitX(m,x)
call SetUnitY(m,y)
set done=true
elseif (GetStoredBoolean(g,k,"pfx")) then
set F=GetStoredReal(g,k,"pfx_current")+CS_Cycle()
if (F>=GetStoredReal(g,k,"pfx_dur")) then
call DestroyEffect(AddSpecialEffectTarget(GetStoredString(g,k,"pfx_path"), m, "origin" ))
call StoreReal(g,k,"pfx_current",0)
else
call StoreReal(g,k,"pfx_current",F)
endif
endif
endif
if done then
call CollisionMissile_Destroyer(g,m,k,GetTableTrigger(k,"T"))
endif
set g=null
return done
endfunction
function CasterSystemMovementTimer takes nothing returns nothing
local timer t=GetExpiredTimer()
local group g=GetTableGroup("CasterSystem","MOVEMENT_GROUP")
local group x=CreateGroup()
local unit p
local string k
local gamecache H=CSCache()
call GroupAddUnit(g,null) //Sometimes removed / exploded units may be in a group, and FirstOfGroup wouldn't
//return null but a invalid pointer
loop
set p=FirstOfGroup(g)
exitwhen (p==null)
call GroupRemoveUnit(g,p)
set k=I2S(GetStoredInteger(H,"MOVEMENT_TABLES",GetAttachmentTable(p)) )
if (k!=null) and (k!="") then
if GetStoredBoolean(H,k,"IsCollisionMissile") then
if not(CollisionMissile_Move(H,p,k)) then
call GroupAddUnit(x,p)
endif
elseif GetStoredBoolean(H,k,"IsProjectile") then
if not(UnitMoveToAsProjectileAnySpeed_Move(H,p,k )) then
call GroupAddUnit(x,p)
endif
else
endif
else
call BJDebugMsg("Caster System: Unexpected Error (2)")
endif
endloop
if (FirstOfGroup(x)==null) then
call SetTableObject("CasterSystem","MOVEMENT_TIMER",null)
call SetTableObject("CasterSystem","MOVEMENT_GROUP",null)
call CleanAttachedVars(t)
call DestroyTimer(t)
call DestroyGroup(x)
else
call SetTableObject("CasterSystem","MOVEMENT_GROUP",x)
endif
call DestroyGroup(g)
set p=null
set x=null
set g=null
set t=null
set H=null
endfunction
function UnitMoveToAsProjectileAnySpeed_Effect takes unit m, effect fx, real speed, real arc, real x2, real y2, unit target, real z2 returns nothing
//
// The internal projectile system used by all the projectile functions
//
local timer t //=GetTableTimer("CasterSystem","MOVEMENT_TIMER")
local gamecache H=CSCache()
local string k
local string km
local integer ki
local group g
if (HaveStoredInteger(H,"CasterSystem","MOVEMENT_TIMER")) then
set g=GetTableGroup("CasterSystem","MOVEMENT_GROUP")
else
set t=CreateTimer()
set g=CreateGroup()
call SetTableObject("CasterSystem","MOVEMENT_GROUP",g)
call SetTableObject("CasterSystem","MOVEMENT_TIMER",t)
call TimerStart(t,CS_Cycle(),true,function CasterSystemMovementTimer)
set t=null
endif
set km=GetAttachmentTable(m)
set k=I2S(GetTableInt("MOVEMENT_TABLES",km))
if (k!=null) and (k!="") then
call SetTableBoolean(k,"done",true)
endif
set ki=NewTableIndex()
set k=I2S(ki)
call SetTableInt("MOVEMENT_TABLES",km,ki)
call GroupAddUnit(g,m)
call StoreBoolean(H,k,"IsProjectile",true)
if (target!=null) then
call StoreBoolean(H,k,"unit",true)
call StoreInteger(H,k,"tg",CS_H2I(target) )
call StoreReal(H,k,"x2",GetUnitX(target))
call StoreReal(H,k,"y2",GetUnitY(target))
call StoreReal(H,k,"z2o",z2)
else
call StoreReal(H,k,"x2",x2)
call StoreReal(H,k,"y2",y2)
endif
call StoreReal(H,k,"z2",z2)
call StoreReal(H,k,"speed",speed)
call StoreReal(H,k,"acel",arc*8000)
if (fx!=null) then
call SetTableObject(k,"fx",fx)
set fx=null
endif
loop
exitwhen GetStoredBoolean(H,k,"done")
call TriggerSleepAction(0)
endloop
call SetTableInt("MOVEMENT_TABLES",km,0)
set H=null
set g=null
endfunction
function UnitMoveToAsProjectileAnySpeed takes unit m, real speed, real arc, real x2, real y2, unit target, real z2 returns nothing
//Left for compat
call UnitMoveToAsProjectileAnySpeed_Effect(m,null,speed,arc,x2,y2,target,z2)
endfunction
//========================================================================================================================
function UnitMoveToAsProjectileGen takes unit m, real arc, real x2, real y2, unit target, real z2 returns nothing
//
// The internal projectile system used by all the projectile functions
//
local real x1=GetUnitX(m)
local real y1=GetUnitY(m)
local real acel=arc*1600
local real speed=GetUnitMoveSpeed(m)
local real z1=GetUnitFlyHeight(m)
local real d
local real d1
local real d2
local real t
local real vel
local real dif=0
local boolean tounit= (target!=null)
local boolean b=false
local boolean mode=false
if tounit then
set x2=GetUnitX(target)
set y2=GetUnitY(target)
set z2=GetUnitFlyHeight(target)+z2
endif
set mode=(z2>z1)
set d=SquareRoot(Pow(x2-x1,2)+Pow(y2-y1,2))
set d1=1000000
set d2=0
set t=d/speed
if t==0 then
set t=0.001
endif
set vel=(z2-z1+0.5*acel*t*t)/t
call SetUnitFacing( m, Atan2BJ(y2 - y1, x2 - x2) )
call IssuePointOrder( m, "move", x2,y2)
set t=0
loop
set d2=d1
if tounit then
if IsUnitDeadBJ(target) then
set tounit=false
else
set x2=GetUnitX(target)
set y2=GetUnitY(target)
endif
endif
set d1=SquareRoot(Pow(x2-GetUnitX(m),2)+Pow(y2-GetUnitY(m),2))
exitwhen b or d1==0
set b=(d1<=speed*(t-dif))
exitwhen (mode and b) or (GetUnitCurrentOrder(m) != OrderId("move"))
if tounit then
call IssuePointOrder( m, "move", x2,y2)
endif
set dif=t
if dif==0.001 then
set t=0.1
else
set t= (d-d1)/speed
endif
set t= 2*t-dif
call SetUnitFlyHeight( m, z1+(vel*t-0.5*acel*t*t), RAbsBJ( vel-acel*(t+dif)/2) )
set t=(t+dif)/2
call TriggerSleepAction(0)
endloop
if tounit then
set x2=GetUnitX(target)
set y2=GetUnitY(target)
endif
call SetUnitFlyHeight( m,z2,0)
call CS_MoveUnit(m,x2,y2)
endfunction
function UnitMoveToAsProjectile takes unit m, real arc, real x2, real y2, real z2 returns nothing
call UnitMoveToAsProjectileGen(m, arc,x2,y2,null,z2)
endfunction
//============================================================================================================
function ProjectileLaunchEx takes player owner, string modelpath, real scale, integer red, integer green, integer blue, integer alpha, real speed, real arc,real x1, real y1, real z1, real x2, real y2, real z2 returns nothing
local unit m=CreateCaster( Atan2BJ(y2 - y1, x2 - x1),x1,y1 )
local effect fx=null
call SetUnitScale( m, scale, scale, scale)
call SetUnitVertexColor(m, red, green, blue, alpha)
call SetUnitFlyHeight( m, z1, 0)
set fx= AddSpecialEffectTarget( modelpath, m,"origin" )
call SetUnitOwner( m, owner, true)
if (speed<=522) then
call SetUnitMoveSpeed(m, speed)
call UnitMoveToAsProjectile(m, arc, x2, y2, z2)
call DestroyEffect(fx)
else
call UnitMoveToAsProjectileAnySpeed_Effect(m,fx,speed,arc,x2,y2,null,z2)
endif
call ExplodeUnitBJ(m)
set owner=null
set fx=null
set m=null
endfunction
function ProjectileLaunchExLoc takes player owner, string modelpath, real scale, integer red, integer green, integer blue, integer alpha, real speed, real arc, location loc1, real z1, location loc2, real z2 returns nothing
call ProjectileLaunchEx( owner, modelpath, scale, red, green, blue, alpha, speed, arc,GetLocationX(loc1), GetLocationY(loc1), z1, GetLocationX(loc2), GetLocationY(loc2), z2)
endfunction
//============================================================================================================
function ProjectileLaunch takes string modelpath, real speed, real arc,real x1, real y1, real z1, real x2, real y2, real z2 returns nothing
call ProjectileLaunchEx( Player(15), modelpath, 1, 255, 255, 255, 255, speed, arc,x1,y1,z1,x2,y2,z2)
endfunction
function ProjectileLaunchLoc takes string modelpath, real speed, real arc, location loc1, real z1, location loc2, real z2 returns nothing
call ProjectileLaunchExLoc( Player(15), modelpath, 1,255,255,255,255,speed,arc,loc1,z1,loc2,z2)
endfunction
//============================================================================================================
function DamagingProjectileLaunchAOE_Child takes nothing returns nothing
local unit m=udg_currentcaster
local effect fx=bj_lastCreatedEffect
local real x2=udg_castervars[0]
local real y2=udg_castervars[1]
local real aoeradius=udg_castervars[3]
local real damage=udg_castervars[4]
local boolean affectallied=bj_isUnitGroupInRectResult
local integer V=CreateDamageOptions(R2I(udg_castervars[5]))
local unit hurter=udg_currenthurter
local real speed=udg_castervars[6]
if (speed<=522) then
call SetUnitMoveSpeed(m, speed)
call UnitMoveToAsProjectile(m, bj_meleeNearestMineDist, udg_castervars[0], udg_castervars[1], udg_castervars[2])
call DestroyEffect(fx)
else
call UnitMoveToAsProjectileAnySpeed_Effect(m,fx,speed,bj_meleeNearestMineDist, udg_castervars[0], udg_castervars[1],null, udg_castervars[2])
endif
call DamageUnitsInAOEEx(hurter,damage,x2,y2,aoeradius,affectallied,LoadDamageOptions(V))
call DestroyDamageOptions(V)
call ExplodeUnitBJ(m)
set m=null
set fx=null
endfunction
function DamagingProjectileLaunchAOE takes unit hurter, string modelpath, real speed, real arc, real x1, real y1, real z1, real x2, real y2, real z2, real aoeradius, real damage, boolean affectallied, integer DamageOptions returns unit
local unit m=CreateCaster( Atan2BJ(y2 - y1, x2 - x1) ,x1,y1)
call SetUnitFlyHeight( m, z1, 0)
set udg_currentcaster=m
set bj_lastCreatedEffect=AddSpecialEffectTarget( modelpath, m,"origin" )
call SetUnitOwner( m, GetOwningPlayer(hurter), true)
set bj_meleeNearestMineDist = arc
set udg_castervars[0] = x2
set udg_castervars[1] = y2
set udg_castervars[2] = z2
set udg_castervars[3] =aoeradius
set udg_castervars[4] =damage
set udg_castervars[5] =DamageOptions
set udg_castervars[6] =speed
set udg_currenthurter=hurter
set bj_isUnitGroupInRectResult=affectallied
call ExecuteFunc("DamagingProjectileLaunchAOE_Child")
set m=null
return udg_currentcaster
endfunction
function DamagingProjectileLaunchAOELoc takes unit hurter, string modelpath, real speed, real arc, location loc1, real z1, location loc2, real z2, real aoeradius, real damage, boolean affectallied, integer DamageOptions returns unit
return DamagingProjectileLaunchAOE(hurter,modelpath,speed,arc,GetLocationX(loc1),GetLocationY(loc1),z1,GetLocationX(loc2),GetLocationY(loc2),z2, aoeradius, damage, affectallied, DamageOptions )
endfunction
function ProjectileLaunchDamage takes player owner, string modelpath, real speed, real arc, real x1, real y1, real z1, real x2, real y2, real z2, real aoeradius, real damage, boolean affectallied returns unit
local unit m=CreateCaster( Atan2BJ(y2 - y1, x2 - x1) ,x1,y1 )
call SetUnitFlyHeight( m, z1, 0)
set udg_currentcaster=m
set bj_lastCreatedEffect=AddSpecialEffectTarget( modelpath, m,"origin" )
call SetUnitOwner( m, owner, true)
set bj_meleeNearestMineDist = arc
set udg_castervars[0] = x2
set udg_castervars[1] = y2
set udg_castervars[2] = z2
set udg_castervars[3] =aoeradius
set udg_castervars[4] =damage
set udg_castervars[5] =0
set udg_castervars[6]= speed
set bj_isUnitGroupInRectResult=affectallied
set udg_currenthurter=m
call ExecuteFunc("DamagingProjectileLaunchAOE_Child")
set m=null
return udg_currentcaster
endfunction
function ProjectileLaunchDamageLoc takes player owner, string modelpath, real speed, real arc, location loc1, real z1, location loc2, real z2, real aoeradius, real damage, boolean affectallied returns unit
return ProjectileLaunchDamage( owner, modelpath, speed, arc, GetLocationX(loc1), GetLocationY(loc1), z1, GetLocationX(loc2), GetLocationY(loc2), z2, aoeradius, damage, affectallied)
endfunction
//============================================================================================================
function ProjectileLaunchKill_Child takes nothing returns nothing
local unit m=udg_currentcaster
local effect fx=bj_lastCreatedEffect
local real x2=udg_castervars[0]
local real y2=udg_castervars[1]
local real speed=udg_castervars[3]
if (speed<=522) then
call SetUnitMoveSpeed( m, speed)
call UnitMoveToAsProjectile(m, bj_meleeNearestMineDist, udg_castervars[0], udg_castervars[1], udg_castervars[2])
call DestroyEffect( fx)
else
call UnitMoveToAsProjectileAnySpeed_Effect(m,fx,speed, bj_meleeNearestMineDist, udg_castervars[0], udg_castervars[1], null, udg_castervars[2])
endif
call ExplodeUnitBJ(m)
set m=null
set fx=null
endfunction
function ProjectileLaunchKill takes player owner, string modelpath, real speed, real arc, real x1, real y1, real z1, real x2, real y2, real z2 returns unit
local unit m=CreateCaster( Atan2BJ(y2 - y1, x2 - x1),x1,y1 )
call SetUnitFlyHeight( m, z1, 0)
set udg_currentcaster=m
set bj_lastCreatedEffect=AddSpecialEffectTarget( modelpath, m,"origin" )
call SetUnitOwner( m, owner, true)
set bj_meleeNearestMineDist = arc
set udg_castervars[0] = x2
set udg_castervars[1] = y2
set udg_castervars[2] = z2
set udg_castervars[3] = speed
call ExecuteFunc("ProjectileLaunchKill_Child")
set m=null
return udg_currentcaster
endfunction
function ProjectileLaunchKillLoc takes player owner, string modelpath, real speed, real arc, location loc1, real z1, location loc2, real z2 returns unit
return ProjectileLaunchKill( owner, modelpath, speed, arc, GetLocationX(loc1), GetLocationY(loc1), z1, GetLocationX(loc2), GetLocationY(loc2), z2)
endfunction
//====================================================================================================================================================================
function UnitMoveToUnitAsProjectile takes unit m, real arc, unit target, real zoffset returns nothing
call UnitMoveToAsProjectileGen(m, arc,0,0,target,zoffset)
endfunction
//====================================================================================================================================================================
function ProjectileLaunchToUnitEx takes player owner, string modelpath, real scale, integer red, integer green, integer blue, integer alpha, real speed, real arc, real x1, real y1, real z1, unit target, real zoffset returns nothing
local unit m=CreateCaster( Atan2BJ(GetUnitY(target) - y1, GetUnitX(target) - x1),x1,y1 )
local effect fx=null
call SetUnitFlyHeight( m, z1, 0)
call SetUnitScale( m, scale, scale, scale)
call SetUnitVertexColor(m, red, green, blue, alpha)
set fx=AddSpecialEffectTarget( modelpath, m,"origin" )
call SetUnitOwner( m , owner, true)
if (speed<=522) then
call SetUnitMoveSpeed( m, speed)
call UnitMoveToUnitAsProjectile(m,arc,target, zoffset)
call DestroyEffect(fx)
else
call UnitMoveToAsProjectileAnySpeed_Effect(m,fx,speed, arc,0,0,target,zoffset)
endif
call ExplodeUnitBJ(m)
set m=null
set fx=null
endfunction
function ProjectileLaunchToUnitExLoc takes player owner, string modelpath, real scale, integer red, integer green, integer blue, integer alpha, real speed, real arc, location loc1, real z1, unit target, real zoffset returns nothing
call ProjectileLaunchToUnitEx( owner, modelpath, scale, red, green, blue, alpha, speed, arc, GetLocationX(loc1),GetLocationY(loc1), z1, target, zoffset)
endfunction
function ProjectileLaunchToUnit takes string modelpath, real speed, real arc,real x1, real y1, real z1, unit target, real zoffset returns nothing
call ProjectileLaunchToUnitEx( Player(15), modelpath, 1, 255,255,255,255,speed,arc,x1,y1,z1,target,zoffset)
endfunction
function ProjectileLaunchToUnitLoc takes string modelpath, real speed, real arc, location loc1, real z1, unit target, real zoffset returns nothing
call ProjectileLaunchToUnitExLoc( Player(15), modelpath, 1, 255,255,255,255, speed, arc, loc1, z1, target,zoffset)
endfunction
//====================================================================================================================================================================
function DamagingProjectileLaunchTarget_Child takes nothing returns nothing
local unit m=udg_currentcaster
local unit target=bj_meleeNearestMine
local effect fx=bj_lastCreatedEffect
local real damage=udg_castervars[4]
local damagetype dmgT=ConvertDamageType(R2I(udg_castervars[6]))
local attacktype attT=ConvertAttackType(R2I(udg_castervars[5]))
local unit hurter=udg_currenthurter
local real speed=udg_castervars[7]
if (speed<=522) then
call SetUnitMoveSpeed( m, speed)
call UnitMoveToUnitAsProjectile(m, bj_meleeNearestMineDist, target, udg_castervars[2])
call DestroyEffect( fx)
else
call UnitMoveToAsProjectileAnySpeed_Effect(m,fx,speed, bj_meleeNearestMineDist,0,0,target,udg_castervars[2])
endif
call DamageUnitByTypes(hurter,target,damage,attT,dmgT)
call ExplodeUnitBJ(m)
set m=null
set hurter=null
set target=null
set fx=null
set dmgT=null
set attT=null
endfunction
function DamagingProjectileLaunchTarget takes unit hurter, string modelpath, real speed, real arc, real x1, real y1, real z1, unit target, real zoffset, real damage, attacktype attT, damagetype dmgT returns unit
local unit m=CreateCaster( Atan2BJ(GetUnitY(target) - y1, GetUnitX(target) - x1),x1,y1 )
set udg_castervars[7]=speed
call SetUnitFlyHeight( m, z1, 0)
set udg_currentcaster=m
set bj_lastCreatedEffect=AddSpecialEffectTarget( modelpath, m,"origin" )
call SetUnitOwner( m, GetOwningPlayer(hurter), true)
set bj_meleeNearestMineDist = arc
set udg_castervars[2]= zoffset
set bj_meleeNearestMine=target
set udg_castervars[4]=damage
set udg_castervars[5]=CS_H2I(attT)
set udg_castervars[6]=CS_H2I(dmgT)
set udg_currenthurter=hurter
call ExecuteFunc("DamagingProjectileLaunchTarget_Child")
set m=null
return udg_currentcaster
endfunction
function DamagingProjectileLaunchTargetLoc takes unit hurter, string modelpath, real speed, real arc, location loc, real z1, unit target, real zoffset, real damage, attacktype attT, damagetype dmgT returns unit
return DamagingProjectileLaunchTarget(hurter,modelpath,speed,arc,GetLocationX(loc),GetLocationY(loc), z1, target, zoffset, damage, attT, dmgT)
endfunction
function ProjectileLaunchToUnitDamage takes player owner, string modelpath, real speed, real arc, real x1, real y1, real z1, unit target, real zoffset, real damage returns unit
local unit m=CreateCaster( Atan2BJ(GetUnitY(target) - y1, GetUnitX(target) - x1),x1,y1 )
set udg_castervars[7]=speed
call SetUnitFlyHeight( m, z1, 0)
set udg_currentcaster=m
set bj_lastCreatedEffect=AddSpecialEffectTarget( modelpath, m,"origin" )
call SetUnitOwner( m, owner, true)
set bj_meleeNearestMineDist = arc
set udg_castervars[2]= zoffset
set bj_meleeNearestMine=target
set udg_castervars[4]=damage
set udg_castervars[5]=CS_H2I(Caster_DefaultAttackType())
set udg_castervars[6]=CS_H2I(Caster_DefaultDamageType())
set udg_currenthurter=m
call ExecuteFunc("DamagingProjectileLaunchTarget_Child")
set m=null
return udg_currentcaster
endfunction
function ProjectileLaunchToUnitDamageLoc takes player owner, string modelpath, real speed, real arc, location loc1, real z1, unit target, real zoffset, real damage returns unit
return ProjectileLaunchToUnitDamage( owner, modelpath, speed, arc,GetLocationX(loc1),GetLocationY(loc1),z1,target,zoffset,damage)
endfunction
//==============================================================================================================================================================================
// Caster System Class: CollisionMissile
//
function CollisionMissile_Destroy takes unit m returns nothing
local gamecache H=CSCache()
local string k=I2S(GetStoredInteger(H,"MOVEMENT_TABLES",GetAttachmentTable(m)))
local trigger T=GetTableTrigger(k,"T")
local effect fx=GetTableEffect(k,"fx")
if (fx!=null) then
call DestroyEffect(fx)
set fx=null
endif
if (T==GetTriggeringTrigger()) or (GetTriggerUnit()!=null) then
call StoreInteger(H,k,"state",2)
else
call GroupRemoveUnit( GetTableGroup("CasterSystem","MOVEMENT_GROUP"),m )
call CollisionMissile_Destroyer(H,m,k,T)
endif
set T=null
set H=null
endfunction
function CollisionMissile_Create takes string MissileModelPath, real x, real y, real dirangle, real speed, real AngleSpeed, real MaxDist, real height, boolean UseNewCaster, real Collision, code OnImpact returns unit
local timer t
local gamecache H=CSCache()
local string k
local integer ki
local trigger R
local group g
local unit m
if (HaveStoredInteger(H,"CasterSystem","MOVEMENT_TIMER")) then
set g=GetTableGroup("CasterSystem","MOVEMENT_GROUP")
else
set t=CreateTimer()
set g=CreateGroup()
call SetTableObject("CasterSystem","MOVEMENT_TIMER",t)
call SetTableObject("CasterSystem","MOVEMENT_GROUP",g)
call TimerStart(t,CS_Cycle(),true,function CasterSystemMovementTimer)
endif
set ki=NewTableIndex()
set k=I2S(ki)
if UseNewCaster then
set m=CreateCaster(dirangle,x,y)
call StoreBoolean(H,k,"new",true)
else
set m=GetACaster()
call SetUnitFacing(m,dirangle)
call SetUnitPosition(m,CS_SafeX(x),CS_SafeY(y))
endif
call StoreInteger(H,"MOVEMENT_TABLES",GetAttachmentTable(m),ki)
call StoreBoolean(H,k,"IsCollisionMissile",true)
call StoreReal(H,k,"speed",speed)
call StoreReal(H,k,"aspeed",AngleSpeed)
call StoreReal(H,k,"F",dirangle)
call StoreReal(H,k,"maxd",MaxDist)
call SetUnitFlyHeight(m,height,0)
call GroupAddUnit(g,m)
set R=CreateTrigger()
call AttachObject(R,"m",m)
call StoreReal(H,k,"collision",Collision)
call StoreInteger(H,k,"state",1)
call SetTableObject(k,"T",R)
call StoreInteger(H,"MOVEMENT_TABLES",GetAttachmentTable(R),ki)
call SetTableObject(k,"fx", AddSpecialEffectTarget(MissileModelPath,m,"origin") )
call SetTableObject(k,"m",m)
call SetTableObject(k,"ac",TriggerAddAction(R,OnImpact))
set t=null
set g=null
set R=null
set udg_currentcaster=m
set m=null
set H=null
return udg_currentcaster
endfunction
function CollisionMissile_CreateLoc takes string MissileModelPath, location loc, real dirangle, real speed, real AngleSpeed, real MaxDist, real height, boolean UseNewCaster, real Collision, code OnImpact returns unit
return CollisionMissile_Create(MissileModelPath,GetLocationX(loc),GetLocationY(loc),dirangle,speed,AngleSpeed,MaxDist,height,UseNewCaster,Collision,OnImpact)
endfunction
//=========================================================================================================================================================
function CollisionMissile_SetAngleSpeed takes unit m, real newAspeed returns nothing
local gamecache H=CSCache()
local string k=I2S( GetStoredInteger(H,"MOVEMENT_TABLES",GetAttachmentTable(m)) )
call StoreReal(H,k,"aspeed",newAspeed )
set H=null
endfunction
//=========================================================================================================================================================
function CollisionMissile_SetSpeed takes unit m, real newspeed returns nothing
local gamecache H=CSCache()
local string k=I2S( GetStoredInteger(H,"MOVEMENT_TABLES",GetAttachmentTable(m)) )
call StoreReal(H,k,"speed",newspeed )
set H=null
endfunction
//=========================================================================================================================================================
function CollisionMissile_SetTargetPoint takes unit m, real tx, real ty returns nothing
local gamecache H=CSCache()
local string k=I2S( GetStoredInteger(H,"MOVEMENT_TABLES",GetAttachmentTable(m)) )
call StoreReal(H,k,"Tx",tx )
call StoreReal(H,k,"Ty",ty )
call StoreInteger(H,k,"TType",1)
set H=null
endfunction
function CollisionMissile_SetTargetPointLoc takes unit m, location tloc returns nothing
call CollisionMissile_SetTargetPoint(m,GetLocationX(tloc),GetLocationY(tloc))
endfunction
//=========================================================================================================================================================
function CollisionMissile_SetTarget takes unit m, widget Target returns nothing
local gamecache H=CSCache()
local string k=I2S( GetStoredInteger(H,"MOVEMENT_TABLES",GetAttachmentTable(m)) )
call SetTableObject(k,"Tw",Target)
call StoreInteger(H,k,"TType",2)
set H=null
endfunction
//=========================================================================================================================================================
function CollisionMissile_ForgetTarget takes unit m returns nothing
local gamecache H=CSCache()
local string k=I2S( GetStoredInteger(H,"MOVEMENT_TABLES",GetAttachmentTable(m)) )
call StoreInteger(H,k,"TType",0)
set H=null
endfunction
//=========================================================================================================================================================
function CollisionMissile_SetDirAngle takes unit m, real f returns nothing
local gamecache H=CSCache()
local string k=I2S( GetStoredInteger(H,"MOVEMENT_TABLES",GetAttachmentTable(m)) )
call StoreReal(H,k,"F",f)
call SetUnitFacing(m,f)
set H=null
endfunction
//=========================================================================================================================================================
function CollisionMissile_ResetMaxDist takes unit m, real maxdist returns nothing
local gamecache H=CSCache()
local string k=I2S( GetStoredInteger(H,"MOVEMENT_TABLES",GetAttachmentTable(m)) )
call StoreReal(H,k,"maxd",maxdist)
set H=null
endfunction
//=========================================================================================================================================================
function CollisionMissile_PeriodicFX takes unit m, string fx, real dur returns nothing
local gamecache H=CSCache()
local string k=I2S( GetStoredInteger(H,"MOVEMENT_TABLES",GetAttachmentTable(m)) )
call StoreBoolean(H,k,"pfx",true)
call StoreString(H,k,"pfx_path",fx)
call StoreReal(H,k,"pfx_dur",dur)
call StoreReal(H,k,"pfx_current",0)
set H=null
endfunction
//==============================================================================================================================================================================
// Caster System Class: Damager
//
function Damager_SetAbility takes unit Damager, integer abilid, integer l returns nothing
local string k=GetAttachmentTable(Damager)
local integer i
if (GetTableBoolean(k,"CS_IsDamager")) then
set i=GetTableInt(k,"CS_abil")
if (i!=0) then
call UnitRemoveAbility(Damager,i)
endif
call UnitAddAbility(Damager,abilid)
call SetUnitAbilityLevel(Damager,abilid,l)
call SetTableInt(k,"CS_abil",abilid)
endif
endfunction
function Damager_Removage takes unit u, timer t, group g returns nothing
local string k=GetAttachmentTable(u)
call PauseTimer(t)
call CleanAttachedVars(t)
call DestroyTimer(t)
call GroupRemoveUnit(g,u)
call DestroyEffect( GetTableEffect(k,"CS_fx") )
call RecicleCasterAfterCastEx(u,4,GetTableInt(k,"CS_abil"),false)
call ClearTable(k)
endfunction
function Damager_Remove takes unit Damager returns nothing
local string k=GetAttachmentTable(Damager)
local timer dg
local group g
if (GetTableBoolean(k,"CS_IsDamager")) then
set g=GetTableGroup(I2S( GetTableInt(k,"CS_DG") ),"G")
if (IsUnitInGroup(Damager,g)) then
call Damager_Removage(Damager,GetTableTimer(k,"CS_t"),g)
endif
endif
set g=null
set dg=null
endfunction
function Damager_Expire takes nothing returns nothing
local timer t=GetExpiredTimer()
local unit u=GetAttachedUnit(t,"u")
call Damager_Removage(u,t, GetAttachedGroup( GetAttachedObject(u,"CS_DG") ,"G") )
set t=null
set u=null
endfunction
function Damager_SetLifeSpan takes unit Damager, real lifespan returns nothing
local timer t
if (GetAttachedBoolean(Damager,"CS_IsDamager")) then
set t=GetAttachedTimer(Damager,"CS_t")
if (lifespan==0) then
call PauseTimer(t)
else
call TimerStart(t,lifespan,false, function Damager_Expire)
endif
set t=null
endif
endfunction
//============================================================================================================
// Caster System Class: DamagerGroup
//
function DamagerGroup_Destroy takes timer DamagerGroup returns nothing
local string k=I2S(CS_H2I(DamagerGroup))
local gamecache H=CSCache()
local group g=GetTableGroup(k,"G")
local unit p
call DestroyDamageOptions(GetStoredInteger(H,k,"dop") )
call CS_KillTimer( GetTableTimer(k,"lifespan") )
loop
set p=FirstOfGroup(g)
exitwhen (p==null)
call Damager_Removage(p, GetAttachedTimer(p,"CS_t") ,g)
endloop
call DestroyGroup(g)
call FlushStoredMission(H,k)
call PauseTimer(DamagerGroup)
call DestroyTimer(DamagerGroup)
set g=null
set H=null
endfunction
function DamagerGroup_Enum takes nothing returns nothing
call GroupAddUnit(bj_groupAddGroupDest, GetFilterUnit() )
endfunction
function DamagerGroup_DoDamage takes nothing returns nothing
local timer t=GetExpiredTimer()
local string k=I2S(CS_H2I(t))
local gamecache H=CSCache()
local group g=CreateGroup()
local group a=CS_CopyGroup(GetTableGroup(k,"G"))
local group arg=CreateGroup()
local unit p
local unit u=GetTableUnit(k,"hur")
local real x=GetStoredReal(H,k,"are")
local real dm
local integer d
local boolean trees=GetStoredBoolean(H,k,"trees")
local boolexpr bex=Condition(function DamagerGroup_Enum)
set bj_groupAddGroupDest=g
if (FirstOfGroup(a)!=null) then
loop
set p=FirstOfGroup(a)
exitwhen (p==null)
call GroupRemoveUnit(a,p)
call CS_EnumUnitsInAOE(arg,GetUnitX(p),GetUnitY(p),x,bex)
if trees then
call DamageTreesInCircle(GetUnitX(p),GetUnitY(p),x)
endif
endloop
if (FirstOfGroup(g)!=null) then
set d=LoadDamageOptions( GetStoredInteger(H,k,"dop") )
set dm=GetStoredReal(H,k,"dmg")
loop
set p=FirstOfGroup(g)
exitwhen (p==null)
set x=GetDamageFactorByOptions(u,p,d)
if (x!=0) then
call UnitDamageTarget(u,p,dm*x,true,false,null,null,null)
endif
call GroupRemoveUnit(g,p)
endloop
endif
elseif GetStoredBoolean(H,k,"autodestruct") then
call DamagerGroup_Destroy(t)
endif
call DestroyBoolExpr(bex)
call DestroyGroup(g)
call DestroyGroup(arg)
call DestroyGroup(a)
set bex=null
set t=null
set g=null
set arg=null
set a=null
set u=null
set H=null
endfunction
function DamagerGroup_Create takes unit hurter, real damage, real damageperiod, real area, integer DamageOptions returns timer
local gamecache g=CSCache()
local timer t=CreateTimer()
local integer i=CS_H2I(t)
local string k=I2S(i)
if (damageperiod<0.01) then
set damageperiod=0.01
endif
call StoreInteger(g,k,"dop",CreateDamageOptions(DamageOptions))
call StoreInteger(g,k,"hur",CS_H2I(hurter))
call StoreReal(g,k,"dmg",damage)
call StoreReal(g,k,"are",area)
call StoreInteger(g,k,"G",CS_H2I(CreateGroup()))
if IsDamageOptionIncluded(DamageOptions, DamageTrees() ) then
call StoreBoolean(g,k,"trees", true )
endif
call TimerStart(t,damageperiod,true,function DamagerGroup_DoDamage)
set i=CS_H2I(t)
set t=null
return i
return null
endfunction
function DamagerGroup_Update takes timer DamagerGroup, unit hurter, real damage, real damageperiod, real area, integer DamageOptions returns nothing
local integer i
local string k=GetAttachmentTable(DamagerGroup)
local unit p=GetTableUnit(k,"hur")
local player ow
local group g
if (damageperiod<0.01) then
set damageperiod=0.01
endif
if (p!=hurter) then
set g=CS_CopyGroup( GetTableGroup(k,"G") )
call SetTableObject(k,"hur",hurter)
set ow=GetOwningPlayer(hurter)
loop
set p=FirstOfGroup(g)
exitwhen (p==null)
call GroupRemoveUnit(g,p)
call SetUnitOwner(p,ow,true)
endloop
call DestroyGroup(g)
set g=null
set ow=null
endif
call SetTableBoolean(k,"trees",IsDamageOptionIncluded(DamageOptions, DamageTrees() ) )
call SetDamageOptions(GetTableInt(k,"dop") , DamageOptions )
call SetTableReal(k,"dmg",damage)
call SetTableReal(k,"are",area)
call TimerStart(DamagerGroup,damageperiod,true,function DamagerGroup_DoDamage)
set p=null
endfunction
function DamagerGroup_AddDamager takes timer DamagerGroup, string modelpath, real x, real y, real LifeSpan returns unit
local unit c=GetACaster()
local string k=GetAttachmentTable(c)
local string dk=GetAttachmentTable(DamagerGroup)
local timer t=CreateTimer()
call SetUnitPosition(c,x,y)
call SetTableObject(k,"CS_fx",AddSpecialEffectTarget( modelpath,c,"origin") )
call SetTableObject(k,"CS_t", t)
call SetTableObject(k,"CS_DG", DamagerGroup)
call AttachObject(t,"u", c)
if (LifeSpan>0) then
call TimerStart(t,LifeSpan,false, function Damager_Expire)
endif
call SetUnitOwner(c,GetOwningPlayer(GetTableUnit(dk,"hur")),true)
call GroupAddUnit(GetTableGroup(dk,"G"),c)
call SetTableBoolean(k,"CS_IsDamager",true)
set udg_currentcaster=c
set c=null
set t=null
return udg_currentcaster
endfunction
function DamagerGroup_AddDamagerLoc takes timer DamagerGroup, string modelpath, location loc, real LifeSpan returns unit
return DamagerGroup_AddDamager(DamagerGroup,modelpath,GetLocationX(loc),GetLocationY(loc),LifeSpan)
endfunction
function DamagerGroup_OnLifeSpanExpire takes nothing returns nothing
call DamagerGroup_Destroy( GetAttachedTimer(GetExpiredTimer() , "t") )
endfunction
function DamagerGroup_SetLifeSpan takes timer DamagerGroup, real lifespan returns nothing
local string k=GetAttachmentTable(DamagerGroup)
local timer t=GetAttachedTimer(DamagerGroup,"lifespan")
if (HaveSetField(k,"lifespan",bj_GAMECACHE_INTEGER)) then
set t=GetTableTimer(k,"lifespan")
else
set t=CreateTimer()
call SetTableObject(k,"lifespan",t)
set k=GetAttachmentTable(t)
call AttachObject(t,"t",DamagerGroup)
endif
call TimerStart(t,lifespan,false, function DamagerGroup_OnLifeSpanExpire)
set t=null
endfunction
function DamagerGroup_AutoDestruct takes timer DamagerGroup, boolean auto returns nothing
call AttachBoolean(DamagerGroup,"autodestruct",auto)
endfunction
//**************************************************************************************************
//*
//* Caster System Special Events:
//*
//*
//**************************************************************************************************
//==================================================================================================
// Event: OnAbilityLearn
//
function Event_OnLearn1 takes nothing returns nothing
local gamecache g=CSCache()
local integer s=GetLearnedSkill()
local string k=I2S(s)
if HaveStoredString( g, "events_onlearn",k) then
call ExecuteFunc( GetStoredString( g, "events_onlearn",k) )
endif
set g=null
endfunction
function Event_OnLearn2 takes nothing returns nothing
local gamecache g=CSCache()
local integer s=GetLearnedSkill()
local string k=I2S(s)
if HaveStoredString( g, "events_onlearn",k) then
call StoreInteger(g,"events_variables","unit",CS_H2I(GetTriggerUnit()))
call StoreInteger(g,"events_variables","current",s)
call ExecuteFunc( GetStoredString( g, "events_onlearn",k) )
endif
set g=null
endfunction
function InitLearnEvent takes gamecache g, integer i returns nothing
local trigger t=CreateTrigger()
local integer j=0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(j),EVENT_PLAYER_HERO_SKILL, null)
set j=j+1
exitwhen j==bj_MAX_PLAYER_SLOTS
endloop
if (i==1) then
call StoreInteger(g,"Events_ProbablyTemp","learntrig",CS_H2I(t))
call StoreInteger(g,"Events_ProbablyTemp","learntriga",CS_H2I(TriggerAddAction(t, function Event_OnLearn1)))
else
call TriggerAddAction(t, function Event_OnLearn2)
endif
call StoreInteger(g,"eventhandlers","learn",i)
set t=null
endfunction
function OnAbilityLearn takes integer abilid, string funcname returns nothing
local gamecache g=CSCache()
if (not HaveStoredInteger(g,"eventhandlers","learn")) then
call InitLearnEvent(g,1)
endif
call StoreString( g,"events_onlearn", I2S(abilid), funcname)
set g=null
endfunction
//==================================================================================================
// Event: OnAbilityGet
//
function GetAbilityAcquiringUnit takes nothing returns unit
return GetStoredInteger(CSCache(),"events_variables","unit")
return null
endfunction
function GetAcquiredAbilityId takes nothing returns integer
return GetStoredInteger(CSCache(),"events_variables","current")
endfunction
function UnitAddAbility_ConsiderEvent takes unit whichUnit, integer abilid, integer level returns nothing
local gamecache g=CSCache()
local string k=I2S(abilid)
call UnitAddAbility(whichUnit,abilid)
call SetUnitAbilityLevel(whichUnit,abilid,level)
if (HaveStoredString(g,"events_onlearn",k)) then
call StoreInteger(g,"events_variables","units",CS_H2I(whichUnit))
call StoreInteger(g,"events_variables","current",abilid)
call ExecuteFunc(GetStoredString(g,"events_onlearn",k))
endif
set g=null
endfunction
function Event_OnPassive_Browse takes gamecache g, unit u, string k returns nothing
local integer n=GetStoredInteger(g,"events_passives","n")
local integer un=0
local integer i=1
local integer s
loop
exitwhen (i>n)
set s=GetStoredInteger(g,"events_passives",I2S(i))
if (GetUnitAbilityLevel(u,s)>0) then
if (un==0) then
set un=1
call StoreInteger(g,"events_variables","unit",CS_H2I(u))
else
set un=un+1
endif
call StoreInteger(g,"events_unit_passive"+I2S(un),k,s)
call StoreInteger(g,"events_variables","current",s)
call ExecuteFunc(GetStoredString(g,"events_onlearn",I2S(s)))
endif
set i=i+1
endloop
if (un==0) then
set un=-1
endif
call StoreInteger(g,"events_unit_passives",k,un)
endfunction
function Event_OnPassive_Do takes gamecache g, unit u, string k, integer n returns nothing
local integer i=1
local integer s
call StoreInteger(g,"events_variables","unit",CS_H2I(u))
loop
exitwhen (i>n)
set s=GetStoredInteger(g,"events_unit_passive"+I2S(i),k)
if (GetUnitAbilityLevel(u,s)>0) then
call StoreInteger(g,"events_variables","current",s)
call ExecuteFunc(GetStoredString(g,"events_onlearn",I2S(s)))
endif
set i=i+1
endloop
endfunction
function Event_OnPassive_EnterRect takes nothing returns nothing
local gamecache g=CSCache()
local unit u=GetTriggerUnit()
local string k=I2S(GetUnitTypeId(u))
local integer n=GetStoredInteger(g,"events_unit_passives",k)
if (n>0) then
call Event_OnPassive_Do(g,u,k,n)
elseif (n==0) then
call Event_OnPassive_Browse(g,u,k)
endif
set g=null
set u=null
endfunction
function Event_OnPassive_NoCasters takes nothing returns boolean
return (GetUnitTypeId(GetTriggerUnit())!=Caster_UnitId())
endfunction
function Event_OnPassive_InitEnum takes nothing returns nothing
local gamecache g=CSCache()
local trigger t
local integer n=GetStoredInteger(g,"events_passives","n")
local integer i=1
local integer array p
local string array s
local unit u
local group a=CreateGroup()
local boolean saved
call DestroyTimer(GetExpiredTimer())
loop
exitwhen (i>n)
set p[i]=GetStoredInteger(g,"events_passives",I2S(i))
set s[i]=GetStoredString(g,"events_onlearn", I2S(p[i]))
set i=i+1
endloop
call GroupEnumUnitsInRect(a,bj_mapInitialPlayableArea,null)
loop
set u=FirstOfGroup(a)
exitwhen (u==null)
set i=1
set saved=false
loop
exitwhen (i>n)
if (GetUnitAbilityLevel(u,p[i])>0) then
if (not saved) then
set saved=true
call StoreInteger(g,"events_variables","unit",CS_H2I(u))
endif
call StoreInteger(g,"events_variables","current",p[i])
call ExecuteFunc(s[i])
endif
set i=i+1
endloop
call GroupRemoveUnit(a,u)
endloop
set t=CreateTrigger()
call TriggerRegisterEnterRectSimple(t,bj_mapInitialPlayableArea)
call TriggerAddAction(t,function Event_OnPassive_EnterRect)
call TriggerAddCondition(t,Condition(function Event_OnPassive_NoCasters))
call DestroyGroup(a)
set t=null
set a=null
endfunction
function InitPassiveEvent takes gamecache g returns nothing
local trigger t
call TimerStart(CreateTimer(),0,false,function Event_OnPassive_InitEnum)
call StoreInteger(g,"eventhandlers","passives",1)
if (not HaveStoredInteger(g,"eventhandlers","learn")) then
call InitLearnEvent(g,2)
else
set t=GetTableTrigger("Events_ProbablyTemp","learntrig")
call TriggerRemoveAction(t,GetTableTriggerAction("Events_ProbablyTemp","learntriga") )
call FlushStoredMission(g,"Events_ProbablyTemp")
set t=CreateTrigger()
call TriggerAddAction(t, function Event_OnLearn2)
call StoreInteger(g,"eventhandlers","learn",2)
set t=null
endif
endfunction
function OnAbilityGet takes integer abilid, string funcname returns nothing
local gamecache g=CSCache()
local integer n=GetStoredInteger(g,"events_passives","n")+1
if (not HaveStoredInteger(g,"eventhandlers","passives")) then
call InitPassiveEvent(g)
endif
call StoreString( g,"events_onlearn", I2S(abilid), funcname)
call StoreInteger(g,"events_passives","n",n)
call StoreInteger(g,"events_passives",I2S(n),abilid)
set g=null
endfunction
//==================================================================================================
// Event: OnAbilityEffect
//
function Event_OnEffect takes nothing returns nothing
local string k=I2S(GetSpellAbilityId())
local gamecache g=CSCache()
if HaveStoredString(g, "events_oneffect",k) then
call ExecuteFunc( GetStoredString(g, "events_oneffect",k))
endif
set g=null
endfunction
function InitEffectEvent takes gamecache g returns nothing
local trigger t=CreateTrigger()
local integer i = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set i=i+1
exitwhen i==bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddAction(t,function Event_OnEffect)
call StoreInteger(g,"eventhandlers","effect",1)
set t=null
endfunction
function OnAbilityEffect takes integer abilid, string funcname returns nothing
local gamecache g=CSCache()
if (not HaveStoredInteger(g,"eventhandlers","effect")) then
call InitEffectEvent(g)
endif
call StoreString(g,"events_oneffect",I2S(abilid),funcname)
set g=null
endfunction
//==================================================================================================
// Event: OnAbilityCast
//
function Event_OnCast takes nothing returns nothing
local string k=I2S(GetSpellAbilityId())
local gamecache g=CSCache()
if HaveStoredString(g, "events_oncast",k) then
call ExecuteFunc( GetStoredString(g, "events_oncast",k))
endif
set g=null
endfunction
function InitCastEvent takes gamecache g returns nothing
local trigger t=CreateTrigger()
local integer i = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(i),EVENT_PLAYER_UNIT_SPELL_CAST, null)
set i=i+1
exitwhen i==bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddAction(t,function Event_OnCast)
call StoreInteger(g,"eventhandlers","cast",1)
set t=null
endfunction
function OnAbilityPreCast takes integer abilid, string funcname returns nothing
local gamecache g=CSCache()
if (not HaveStoredInteger(g,"eventhandlers","cast")) then
call InitCastEvent(g)
endif
call StoreString(g,"events_oncast",I2S(abilid),funcname)
set g=null
endfunction
//==================================================================================================
// Event: OnAbilityEndCast
//
function Event_OnEndCast takes nothing returns nothing
local string k=I2S(GetSpellAbilityId())
local gamecache g=CSCache()
if HaveStoredString(g, "events_onendcast",k) then
call ExecuteFunc( GetStoredString(g, "events_onendcast",k))
endif
set g=null
endfunction
function InitEndCastEvent takes gamecache g returns nothing
local trigger t=CreateTrigger()
local integer i = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(i),EVENT_PLAYER_UNIT_SPELL_ENDCAST, null)
set i=i+1
exitwhen i==bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddAction(t,function Event_OnEndCast)
call StoreInteger(g,"eventhandlers","endcast",1)
set t=null
endfunction
function OnAbilityEndCast takes integer abilid, string funcname returns nothing
local gamecache g=CSCache()
if (not HaveStoredInteger(g,"eventhandlers","endcast")) then
call InitEndCastEvent(g)
endif
call StoreString(g,"events_onendcast",I2S(abilid),funcname)
set g=null
endfunction
//==================================================================================================
// Spell Helpers
//
function IsPointWater takes real x, real y returns boolean
return IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY) and not(IsTerrainPathable(x,y,PATHING_TYPE_AMPHIBIOUSPATHING))
endfunction
function IsPointWaterLoc takes location loc returns boolean
return IsPointWater(GetLocationX(loc),GetLocationY(loc))
endfunction
//==================================================================================================
function IsUnitSpellImmune takes unit u returns boolean
return IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE)
endfunction
function IsUnitImmuneToPhisical takes unit u returns boolean
return (GetDamageFactor(u,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_DEMOLITION)==0)
endfunction
function IsUnitInvulnerable takes unit u returns boolean
return (GetDamageFactor(u,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNIVERSAL)==0)
endfunction
//## Utility functions ##
//====================================================================================================
// Mimic an interface error message
// ForPlayer : The player to show the error
// msg : The error
//
function CS_Error takes player ForPlayer, string msg returns nothing
local sound error=CreateSoundFromLabel( "InterfaceError",false,false,false,10,10)
if (GetLocalPlayer() == ForPlayer) then
if (msg!="") and (msg!=null) then
call ClearTextMessages()
call DisplayTimedTextToPlayer( ForPlayer, 0.52, -1.00, 2.00, "|cffffcc00"+msg+"|r" )
endif
call StartSound( error )
endif
call KillSoundWhenDone( error)
set error=null
endfunction
//## Safe item hiding system ##
//===============================
// Hides an item, it keeps it safe while leaving other units unable to use it
// (unless an (attached) variable / table field points to it and user does
// something with it) - THIS IS HIGHLY DISCOURAGED
//
// * Don't use it with tomes that increase hero stats
// * Make triggers with item acquire/lose events ignore when a
// Caster is triggering unit.
//
function CS_HideItem takes item i returns integer
local gamecache g=CSCache()
local unit s
local group gr=GetTableGroup("CSItemStorage","gr")
local integer k=NewTableIndex()
local string ks=I2S(k)
if (gr==null) then
set gr=CreateGroup()
call StoreInteger(g,"CSItemStorage","gr",CS_H2I(gr))
endif
set s=FirstOfGroup(gr)
if (s==null) then
set s=GetACaster()
call UnitAddAbility(s,CS_InventoryId())
call GroupAddUnit(gr,s)
endif
call UnitAddItem(s,i)
call StoreInteger(g,ks,"s",CS_H2I(s))
call StoreInteger(g,ks,"i",CS_H2I(i))
if(UnitInventorySize(s)==UnitInventoryCount(s)) then
call GroupRemoveUnit(gr,s)
endif
set s=null
set g=null
set gr=null
return (k)
endfunction
function CS_FromIntegerToItem takes integer i returns item
return i
return null
endfunction
//===============================
// Restores an item
//
function CS_RestoreItem takes integer hiddenindex, real x, real y returns item
local gamecache g=CSCache()
local group gr=GetTableGroup("CSItemStorage","gr")
local string k=I2S(hiddenindex)
local unit s=GetTableUnit(k,"s")
local integer r=GetStoredInteger(g,k,"i")
local item i=CS_FromIntegerToItem(r)
local integer c
call UnitRemoveItem(s,i)
set c=UnitInventoryCount(s)
if (c==0) then
call UnitRemoveAbility(s,CS_InventoryId())
call GroupRemoveUnit(gr,s)
call RecicleCaster(s)
else
call GroupAddUnit(gr,s)
endif
call SetItemPosition(i,x,y)
call DestroyTable(k)
set i=null
set s=null
set g=null
return r
return null
endfunction
function CS_RestoreItemLoc takes integer hiddenindex, location loc returns item
return CS_RestoreItem(hiddenindex,GetLocationX(loc),GetLocationY(loc))
endfunction
//=============================================================================================================
// Obsolette functions: (Left for compatibility)
//
constant function WaterDetectorId takes nothing returns integer
return 'Asb2' //Left for compat
endfunction
function SpellEffectModelPath takes integer abilityid, effecttype t returns string
return GetAbilityEffectById(abilityid,t, 0)
endfunction
//##End##
Rolling Boulder
JASS:
//********************************************************************************************************
//* A JESP Spell by Vexorian
//* Codename: RollingBoulder
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* Requirements:
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯
//* - The RollingBoulder ability
//* - The RollingBoulder Stun ability (should be based from storm bolt, and able to have as many levels as RollingBoulder)
//* (To base it from a different ability change the order id bellow.)
//* - The Caster System ( [url]http://wc3campaigns.net/vexorian/[/url] )
//* - This Trigger (MAKE SURE TO change the rawcodes in the trigger to the correct ones of your map)
//*
//* Object Editor fields
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//* - Art - Missile art : Boulder Model
//* - Art - Special : Sink effect
//* - Art - Area Effect : Impact effect (on cliffs/ ground)
//*
//********************************************************************************************************
//========================================================================================================
// RollingBoulder Spell Configuration:
//
//
////
// Main (Must change to the correct ones in your map)
// ¯¯¯¯
// _SpellId : Rawcode of the RollingBoulder Ability
// _StunSpellId : Rawcode of the RollingBoulder Stun Ability
// _StunOrderID : Order ID of the Stun ability, you can change this one so it uses another kind of
// effect instead of stun
//
constant function RollingBoulder_SpellId takes nothing returns integer
return 'A008'
endfunction
constant function RollingBoulder_StunSpellId takes nothing returns integer
return 'A00E'
endfunction
constant function RollingBoulder_StunOrderId takes nothing returns integer
return OrderId("thunderbolt")
endfunction
////
// Damage
// ¯¯¯¯¯¯
// _Damage : Impact Damage done by the Boulder
// _ExtraDamagePerSecond : Damage per second done against the unit during the knockback
//
constant function RollingBoulder_Damage takes real level returns real
return 30+15*level
endfunction
constant function RollingBoulder_ExtraDamagePerSecond takes real level returns real
return 10+5*level
endfunction
////
// Boulder Stats
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
// _BoulderSpeed : Movement speed of the boulder
// _BoulderDuration : Maximum Duration of the boulder (notice that speed and duration determine the area)
// _ImpactRange : How close should a boulder be in order to do damage/knockback=
// _BoulderScale : Model scale for the boulder
//
constant function RollingBoulder_BoulderSpeed takes nothing returns real
return 800.0
endfunction
constant function RollingBoulder_BoulderDuration takes real level returns real
return 41+10*level
endfunction
constant function RollingBoulder_ImpactRange takes real level returns real
return 80+level*10
endfunction
constant function RollingBoulder_BoulderScale takes real level returns real
return 0.90+level*0.1
endfunction
////
// DestructableHit
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// Determines how the spel behaves against destructables
// 0 : Don't harm destructables
// 1 : Kill trees
// 2 : Do damage to destructables
// 3 : Do damage to destructables and Kill trees
//
constant function RollingBoulder_DestructableHit takes nothing returns integer
return 3
endfunction
////
// NOTE: In order to configure next options you'll need to know about Caster System's damage and target options.
// Check out the caster system's documentation for more information.
//
////
// KnockbackOptions
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
// If these options return 0 as factor for a unit, then the boulder will be unable to knockback it
//
function RollingBoulder_KnockbackOptions takes integer level returns integer
return ForceDamageAllies() + DamageIgnore(UNIT_TYPE_STRUCTURE) + DamageOnlyTo(UNIT_TYPE_GROUND)
//
// Knockback any (enemy or allied) non-flying unit that is not a structure besides the golem.
//
endfunction
////
// DamageOptions
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
// Control the damage factors. Notice that depending on the options a unit can be affected by knockback
// but not suffer from damage.
//
function RollingBoulder_DamageOptions takes integer level returns integer
return DamageTypes(ATTACK_TYPE_NORMAL,DAMAGE_TYPE_FORCE) + DamageOnlyEnemies() + DamageOnlyTo(UNIT_TYPE_GROUND) + DamageException(UNIT_TYPE_STRUCTURE,4)
//
// do force(magical) spell damage, don't damage allies, and only affect ground units.
// do 4x damage to buildings.
//
endfunction
////
// Timer
// ¯¯¯¯¯
// Configures the spell's timer.
// - Lower == Looks better
// - Higher == Lags less.
//
// I recommend it to stay on 0.04
//
constant function RollingBoulder_Timer takes nothing returns real
return 0.04
endfunction
//========================================================================================================
// RollingBoulder Script:
//
function RollingBoulder_Conditions takes nothing returns boolean
return (GetSpellAbilityId() == RollingBoulder_SpellId())
endfunction
function RollingBoulder_GetTerrainHeight takes real x, real y returns integer
local location loc=Location(x,y)
local integer h=R2I(GetLocationZ(loc))
call RemoveLocation(loc)
set loc=null
return h
endfunction
function RollingBoulder_Final takes string k,unit m,integer l,timer t,group g, boolean water returns nothing
local real d
local integer i=0
local real x=GetUnitX(m)
local real y=GetUnitY(m)
local real h
call SetTableBoolean(k,"mainended",true)
call DestroyEffect(GetTableEffect(k,"fx"))
if water then
call DestroyEffect( AddSpellEffectById(RollingBoulder_SpellId(),EFFECT_TYPE_SPECIAL,x,y) )
call RemoveUnit(m)
else
call ExplodeUnitBJ(m)
endif
endfunction
function RollingBoulder_CloseToOther takes string k,unit m, integer l returns boolean
local boolean r=GetTableBoolean(k,"RollingBoulder_Die")
local group g=CreateGroup()
local unit p
local real rn
if not(r) then
call GroupAddGroup(GetTableGroup("[RollingBoulder]","g"),g)
set rn=RollingBoulder_ImpactRange(l)
endif
loop
set p=FirstOfGroup(g)
exitwhen r or (p==null)
call GroupRemoveUnit(g,p)
if (p!=m) then
if (IsUnitInRange(p,m, rn ) ) then
call SetTableBoolean(I2S(GetTableInt("[RollingBoulder]",GetAttachmentTable(p))),"RollingBoulder_Die",true)
set r=true
endif
endif
endloop
call DestroyGroup(g)
set g=null
set p=null
return r
endfunction
function RollingBoulder_DoDestructables takes real x, real y, integer l,real d, real f returns nothing
local integer i=RollingBoulder_DestructableHit()
local real r=RollingBoulder_ImpactRange(l)
set f=f*bj_DEGTORAD
set x=x+d*Cos(f)
set y=y+d*Sin(f)
if (i>=2) then
set i=i-1
call DamageDestructablesInCircle(x,y,r,RollingBoulder_Damage(l))
endif
if (i>=1) then
call DamageTreesInCircle(x,y,r)
endif
endfunction
function RollingBoulder_GetI takes nothing returns nothing
set bj_rescueChangeColorUnit = bj_rescueChangeColorUnit or (GetEnumItem()!=bj_itemRandomCurrentPick)
endfunction
function RollingBoulder_ItemCheck takes item p, real x, real y returns boolean
local integer i=30
local rect r
local real dx
local real dy
call SetItemPosition(p,x,y)
set dx=GetItemX(p)-x
set dy=GetItemY(p)-y
if (dx*dx+dy*dy<=100) then
return true
endif
set r=Rect(x-i,y-i,x+i,y+i)
set bj_itemRandomCurrentPick=p
set bj_rescueChangeColorUnit=false
call EnumItemsInRect(r,null,function RollingBoulder_GetI)
call RemoveRect(r)
set r=null
return bj_rescueChangeColorUnit
endfunction
function RollingBoulder_GuessBounce takes item p,real f, real x, real y returns real
local integer i=128
local real h= 1.4142136*i //SquareRoot(2)
local real r
local boolean b1
local boolean b2
local boolean b3
local boolean b4
local boolean b5
set f=ModuloReal(f,6.283185) //360ª
if (f>=4.712389) then //270º
set r=4.712389
elseif (f>=bj_PI) then //180º
set r=bj_PI
elseif (f>=1.570796) then //90º
set r=1.570796
else
set r=0
endif
set b1=not RollingBoulder_ItemCheck(p,x+h*Cos(r-0.785398 ),y+h*Sin(r-0.785398 )) //-45º
set b2=not RollingBoulder_ItemCheck(p,x+i*Cos( r ),y+i*Sin( r ))
set b3=not RollingBoulder_ItemCheck(p,x+h*Cos(r+0.785398 ),y+h*Sin(r+0.785398 )) //+45º
set b4=not RollingBoulder_ItemCheck(p,x+i*Cos( r+1.570796 ),y+i*Sin( r+1.570796 )) //+90º
set b5=not RollingBoulder_ItemCheck(p,x+h*Cos(r+2.356194),y+h*Sin(r+2.356194)) //+135º
if b2 and b3 and b4 then
set r=f+bj_PI
elseif (b3 and b4 and b5) or (b1 and b2 and b3) then
set r=-f+bj_PI
else
set r=GetRandomReal(0.00001,bj_PI*2)
endif
return r+GetRandomReal(-0.01,0.01)
endfunction
function RollingBoulder_BoulderMov takes string k, unit m,integer l, timer t,group g,string k returns boolean
local integer error=0
local item p
local real x=GetUnitX(m)
local real y=GetUnitY(m)
local real i=0
local real f=GetTableReal(k,"f")
local real d=RollingBoulder_BoulderSpeed()*RollingBoulder_Timer()
local real nx
local real ny
local real ix
local real iy
local integer max=200
local real cd
local real a=f
local real b
local real add=IntegerTertiaryOp(GetRandomInt(0,1)==0,-1,1)* 10
local boolean wa=false
local integer ig
call RollingBoulder_DoDestructables(x,y,l,d,f)
if (RollingBoulder_CloseToOther(k,m,l)) then
call RollingBoulder_Final(k,m,l,t,g,false)
return false
endif
set p=CreateItem('ciri',0,0)
set ig=GetTableInt(k,"Ign")
if ig >0 then
set nx=x+d*Cos(f)
set ny=y+d*Sin(f)
call SetTableInt(k,"Ign",ig-1)
call DestroyEffect( AddSpellEffectById(RollingBoulder_SpellId(),EFFECT_TYPE_AREA_EFFECT,x,y) )
else
loop
set nx=x+d*Cos(f)
set ny=y+d*Sin(f)
exitwhen RollingBoulder_ItemCheck(p,nx,ny)
if error==0 then
set a=RollingBoulder_GetTerrainHeight(x,y)
set b=RollingBoulder_GetTerrainHeight(nx,ny)
set cd=d
loop
exitwhen (a!=b) or (cd>max) or wa
set cd=cd+d
set b=RollingBoulder_GetTerrainHeight(x+cd*Cos(f),y+cd*Sin(f))
set wa=(IsPointWater(x+cd*Cos(f),y+cd*Sin(f)))
endloop
exitwhen wa
if (a>b) then
call SetTableInt(k,"Ign", R2I(cd/d)*2)
exitwhen true
endif
set a=f
endif
set error=error+1
exitwhen (error>4)
if (error>2) then
set f=-a+GetRandomReal(-0.01,0.01)
elseif error>1 then
set f=GetRandomReal(0.001,bj_PI*2)
else
set f=RollingBoulder_GuessBounce(p,f,x,y)
endif
endloop
endif
call SetTableReal(k,"f",f)
call SetUnitFacing(m,f*bj_RADTODEG)
call SetItemVisible(p,false)
//take that! python fans
call RemoveItem(p)
set p=null
if (error>4) then
call RollingBoulder_Final(k,m,l,t,g,false)
return false
else
if (error>0) then
call DestroyEffect( AddSpellEffectById(RollingBoulder_SpellId(),EFFECT_TYPE_AREA_EFFECT,x,y) )
endif
call SetUnitPosition(m,nx,ny)
set ig=GetTableInt(k,"water")
if ig==1 then
if IsPointWater(nx,ny) then
call RollingBoulder_Final(k,m,l,t,g,true)
else
call SetTableInt(k,"water",0)
endif
elseif ig>1 then
call SetTableInt(k,"water",ig-1)
elseif wa then
call SetTableInt(k,"water",R2I((cd+RollingBoulder_ImpactRange(l))/d))
endif
endif
return true
endfunction
function RollingBoulder_Mov takes nothing returns nothing
local timer t=GetExpiredTimer()
local string k=I2S(GetTableInt("[RollingBoulder]",GetAttachmentTable(t)))
local group g=GetTableGroup(k,"g")
local group a
local unit m
local unit o
local unit u
local real f
local real inc
local real x
local real y
local real nx
local real ny
local real px
local real py
local real d
local integer tms
local integer l=GetTableInt(k,"l")
local integer num=GetTableInt(k,"num")+1
local real dir
local real dx
local real dy
if GetTableBoolean(k,"mainended") then
call DestroyGroup(g)
call PauseTimer(t)
set t=null
set g=null
set a=null
set m=null
return
endif
call SetTableInt(k,"num",num)
set o=GetTableUnit(k,"m")
set u=GetTableUnit(k,"u")
set x=GetUnitX(o)
set y=GetUnitY(o)
set a=CreateGroup()
call GroupAddGroup(g,a)
set inc=RollingBoulder_Timer()
set d=RollingBoulder_ExtraDamagePerSecond(l)*inc
set inc=RollingBoulder_BoulderSpeed()*inc
loop
set m=FirstOfGroup(a)
exitwhen m==null
set nx=GetUnitX(m)
set ny=GetUnitY(m)
if IsUnitInRange(m,o,RollingBoulder_ImpactRange(l)) and not(IsUnitType(m,UNIT_TYPE_DEAD)) then
call DamageUnitByOptions(u,m,d,RollingBoulder_DamageOptions(l))
set f=Atan2(ny-y,nx-x)
set px=nx+inc*Cos(f)
set py=ny+inc*Sin(f)
call SetUnitPosition(m,px,py)
set dx=GetUnitX(m)-px
set dy=GetUnitY(m)-py
if (dx*dx+dy*dy>400) then
call SetUnitPosition(m,nx,ny)
endif
else
call GroupRemoveUnit(g,m)
endif
call GroupRemoveUnit(a,m)
endloop
if not(RollingBoulder_BoulderMov(k,o,l,t,g,k)) then
call SetTableBoolean(k,"mainended",true)
endif
set t=null
set g=null
set a=null
set m=null
endfunction
function RollingBoulder_ValidBoulderImpact takes string k, unit u, unit m, unit ow returns nothing
local integer l=GetTableInt(k,"l")
local integer i=0
local real x=GetUnitX(m)
local real y=GetUnitY(m)
local real d
if ((ow!=u) or GetTableBoolean(k,"RegEnded")) and (GetDamageFactorByOptions(ow,u,RollingBoulder_KnockbackOptions(l))!=0) then
call CasterCastAbilityLevel(GetOwningPlayer(ow),RollingBoulder_StunSpellId(),l,I2S(RollingBoulder_StunOrderId()),u,true)
call GroupAddUnit(GetTableGroup(k,"g"),u)
endif
call DamageUnitByOptions(ow,u,RollingBoulder_Damage(l),RollingBoulder_DamageOptions(l))
endfunction
function RollingBoulder_BoulderImpact takes nothing returns nothing
local string k=I2S(GetTableInt("[RollingBoulder]",GetAttachmentTable(GetTriggeringTrigger())))
local unit u=GetTriggerUnit()
local unit ow=GetTableUnit(k,"u")
if (u==null) then
call SetTableBoolean(k,"RegEnded",true)
elseif (ow!=null) then
call RollingBoulder_ValidBoulderImpact(k,u,GetTableUnit(k,"m"),ow)
set ow=null
endif
set u=null
set ow=null
endfunction
function RollingBoulder_ActionsT takes timer t returns nothing
local unit u=GetTriggerUnit()
local integer s=GetSpellAbilityId()
local integer l=GetUnitAbilityLevel(u,s)
local location loc=GetSpellTargetLoc()
local real x=GetUnitX(u)
local real y=GetUnitY(u)
local real f=Atan2(GetLocationY(loc)-y,GetLocationX(loc)-x)
local unit m=AddCasterFacing(f)
local group g=CreateGroup()
local group G
local trigger ran=CreateTrigger()
local triggeraction ac=TriggerAddAction(ran,function RollingBoulder_BoulderImpact)
local integer ki=NewTableIndex()
local string k=I2S(ki)
local integer N=GetTableInt("[RollingBoulder]","N")
if (N==0) then
call SetTableInt("[RollingBoulder]","N",1)
set G=CreateGroup()
call SetTableObject("[RollingBoulder]","g",G)
else
set G=GetTableGroup("[RollingBoulder]","g")
call SetTableInt("[RollingBoulder]","N",N+1)
endif
call SetUnitPosition(m,x,y)
set x=RollingBoulder_BoulderScale(l)
call SetUnitScale(m,x,x,x)
call SetTableInt(k,"l",l)
call SetTableObject(k,"u",u)
call SetTableObject(k,"m",m)
call SetTableObject(k,"g",g)
call GroupAddUnit(GetTableGroup("[RollingBoulder]","g") , m)
call SetUnitFlyHeight(m,150,0)
call SetUnitFlyHeight(m,50,100)
call SetTableReal(k,"f",f)
call SetTableInt("[RollingBoulder]",GetAttachmentTable(ran),ki)
call SetTableInt("[RollingBoulder]",GetAttachmentTable(m),ki)
call SetTableInt("[RollingBoulder]",GetAttachmentTable(t),ki)
call SetTableInt("[RollingBoulder]",GetAttachmentTable(ran),ki)
call TriggerRegisterUnitInRange(ran,m,RollingBoulder_ImpactRange(l),null)
call SetTableObject(k,"fx",AddSpellEffectTargetById(s,EFFECT_TYPE_MISSILE,m,"origin"))
call SetUnitOwner(m,GetOwningPlayer(u),true)
call RemoveLocation(loc)
call TimerStart(t,RollingBoulder_Timer(),true,function RollingBoulder_Mov)
call TriggerRegisterTimerEvent(ran,0.5,false)
call PolledWait(RollingBoulder_BoulderDuration(l))
if not(GetTableBoolean(k,"sp")) then
call RollingBoulder_Final(k,m,l,t,g,false)
endif
call TriggerSleepAction(0)
set N=GetTableInt("[RollingBoulder]","N")-1
if (N==0) then
call DestroyGroup(G)
call ClearTable("[RollingBoulder]")
else
call SetTableInt("[RollingBoulder]","N",N)
endif
call DestroyTable(k)
call DestroyTimer(t)
call TriggerRemoveAction(ran,ac)
call DestroyTrigger(ran)
set u=null
set loc=null
set m=null
set g=null
set ran=null
set ac=null
endfunction
function RollingBoulder_Actions takes nothing returns nothing
call RollingBoulder_ActionsT(CreateTimer())
endfunction
//========================================================================================================
function InitTrig_RollingBoulder takes nothing returns nothing
call PreloadAbility(RollingBoulder_StunSpellId())
call OnAbilityEffect(RollingBoulder_SpellId(),"RollingBoulder_Actions")
endfunction
Tremor: http://www.wc3c.net/showthread.php?t=84022
JASS:
//Return Bug
function H2I takes handle h returns integer
return h
return 0
endfunction
function I2H takes integer i returns handle
return i
return null
endfunction
function I2U takes integer i returns unit
return i
return null
endfunction
function I2G takes integer i returns group
return i
return null
endfunction
function I2E takes integer i returns effect
return i
return null
endfunction
function I2T takes integer i returns timer
return i
return null
endfunction
function I2TD takes integer i returns terraindeformation
return i
return null
endfunction
//End Return Bug
JASS:
//Spell Contest 4 Entry
//Spell: Tremor
//Created by: Tim.
//www.Wc3Campaigns.net
//Below are all the settings you can customize.
function TremorTim_Dummy takes integer i returns integer
if i == 1 then
set i = 'h002' //Normal dummy
elseif i == 2 then
set i = 'h003' //Special hand dummy
endif
return i
endfunction
function TremorTim_SpellID takes integer i returns integer
if i == 1 then
set i = 'A000' //Your dummy spell
elseif i == 2 then
set i = 'A000' //Reserved
elseif i == 3 then
set i = 'A002' //Your stun ability (Impale based)
elseif i == 4 then
set i = 'B001' //Your stunned buff (Impale based)
endif
return i
endfunction
function TremorTim_Real takes integer i returns real
if i == 1 then
return 50.00 //Damage on the charge (10xSpell's Level will be added to this value)
elseif i == 2 then
return 100.00 //AoE Slam Damage below the palm (10xSpell's Level will be added to this value)
elseif i == 3 then
return 25.00 //Damage in the area of the final ripple (10xSpell's Level will be added to this value)
elseif i == 4 then
return 4.00 //Time in seconds for the stuns (1 second per level is added to this value)
endif
return 0.00 //Nothing goes here, just leave it
endfunction
function TremorTim_String takes integer i returns string
if i == 1 then
return "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl" //Effect played as bump moves through the ground
elseif i == 2 then
return "origin" //This is the attachment point of your dummy unit
elseif i == 3 then
return "war3mapImported\\SanExplosion2.mdx" //Effect played on impact of the hand
elseif i == 4 then
return "war3mapImported\\ImpaleHitTarget.mdx" //Effect used by the Variable Stun's buff
endif
return null
endfunction
function TremorTim_Gamecache takes nothing returns gamecache
return udg_AbilityCache //This is your global cache you are using
endfunction
//End customization functions
function TremorTim_Blood takes unit u returns string
local race r = GetUnitRace(u)
local string s
local integer i
if r == RACE_HUMAN then
set s = "Objects\\spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl"
elseif r == RACE_NIGHTELF then
set s = "Objects\\Spawnmodels\\NightElf\\NightElfLargeDeathExplode\\NightElfLargeDeathExplode.mdl"
elseif r == RACE_ORC then
set s = "Objects\\Spawnmodels\\Orc\\OrcLargeDeathExplode\\OrcLargeDeathExplode.mdl"
elseif r == RACE_UNDEAD then
set s = "Objects\\Spawnmodels\\Undead\\UndeadLargeDeathExplode\\UndeadLargeDeathExplode.mdl"
elseif r == RACE_DEMON then
set s = "Objects\\Spawnmodels\\Demon\\DemonLargeDeathExplode\\DemonLargeDeathExplode.mdl"
elseif r == RACE_OTHER then
set i = GetRandomInt(1,3)
if i == 1 then
set s = "Objects\\spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl"
elseif i == 2 then
set s = "Objects\\Spawnmodels\\NightElf\\NightElfLargeDeathExplode\\NightElfLargeDeathExplode.mdl"
elseif i == 3 then
set s = "Objects\\Spawnmodels\\Orc\\OrcLargeDeathExplode\\OrcLargeDeathExplode.mdl"
endif
else
set s = "Objects\\spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl"
endif
return s
endfunction
function TremorTim_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A000'
endfunction
/////////////////////////////////////////////////////////////////
//Modified Variable Stun System with permission from blu_da_noob/
//Created by blu_da_noob modoified by Tim.///////////////////////
//http://www.wc3campaigns.net/showthread.php?t=83383/////////////
/////////////////////////////////////////////////////////////////
function TremorTim_Cache takes nothing returns gamecache
return TremorTim_Gamecache()
endfunction
function TremorTim_MinimumStunDuration takes nothing returns real
return 0.2 //Do not modify
endfunction
function TremorTim_GetUnit takes string mission, string key returns unit
return GetStoredInteger(TremorTim_Cache(),mission,key)
return null
endfunction
function TremorTim_GetTimer takes string mission, string key returns timer
return GetStoredInteger(TremorTim_Cache(),mission,key)
return null
endfunction
function TremorTim_GetGroup takes string mission, string key returns group
return GetStoredInteger(TremorTim_Cache(),mission,key)
return null
endfunction
function TremorTim_GetStunDummy takes unit target returns unit
local gamecache gc = TremorTim_Cache()
local group g
local unit dummy
local integer temp
set g = TremorTim_GetGroup("CustomStunSystem","StunDummyGroup")
if g == null then
set g = CreateGroup()
call StoreInteger(gc,"CustomStunSystem","StunDummyGroup",H2I(g))
endif
set dummy = FirstOfGroup(g)
if dummy == null then
set dummy = CreateUnit(GetOwningPlayer(target),TremorTim_Dummy(1),GetUnitX(target),GetUnitY(target),0)
else
call SetUnitX(dummy,GetUnitX(target))
call SetUnitY(dummy,GetUnitY(target))
call SetUnitOwner(dummy,GetOwningPlayer(target),false)
call GroupRemoveUnit(g,dummy)
endif
call UnitAddAbility(dummy,'Aloc')
call UnitAddAbility(dummy,TremorTim_SpellID(3))
set temp = H2I(dummy)
set gc = null
set g = null
set dummy = null
return temp
return null
endfunction
function TremorTim_ReturnStunDummy takes nothing returns nothing
local unit dummy = bj_groupRandomCurrentPick
call TriggerSleepAction(10)
call GroupAddUnit(TremorTim_GetGroup("CustomStunSystem","StunDummyGroup"),dummy)
set dummy = null
endfunction
function TremorTim_RemoveUnitStun takes unit u returns boolean
return UnitRemoveAbility(u,TremorTim_SpellID(4))
endfunction
function TremorTim_TimedRemoveStun takes nothing returns nothing
local string timertable
local unit target
local string targettable
local gamecache gc = TremorTim_Cache()
set bj_crippledTimer[21] = GetExpiredTimer()
set timertable = I2S(H2I(bj_crippledTimer[21]))
set target = TremorTim_GetUnit(timertable,"stuntarget")
set targettable = I2S(H2I(target))
call UnitRemoveAbility(target,TremorTim_SpellID(4))
call FlushStoredMission(gc,timertable)
call DestroyTimer(bj_crippledTimer[21])
call FlushStoredInteger(gc,targettable,"stuntimer")
set target = null
set gc = null
endfunction
function TremorTim_StunUnit takes unit target, real duration, boolean ignoremagicimmunity returns boolean
local boolean immune = IsUnitType(target,UNIT_TYPE_MAGIC_IMMUNE)
local boolean stun = (not immune) or ignoremagicimmunity
local unit dummy
local string targettable
local string timertable
local gamecache gc
if stun then
set dummy = TremorTim_GetStunDummy(target)
set stun = IssueTargetOrder(dummy,"impale",target)
if stun then
set gc = TremorTim_Cache()
set duration = RMaxBJ(duration,TremorTim_MinimumStunDuration())
set targettable = I2S(H2I(target))
set bj_crippledTimer[21] = TremorTim_GetTimer(targettable,"stuntimer")
if bj_crippledTimer[21] == null then
set bj_crippledTimer[21] = CreateTimer()
call StoreInteger(gc,targettable,"stuntimer",H2I(bj_crippledTimer[21]))
endif
set timertable = I2S(H2I(bj_crippledTimer[21]))
call StoreInteger(gc,timertable,"stuntarget",H2I(target))
call TimerStart(bj_crippledTimer[21],RMaxBJ(duration,TimerGetRemaining(bj_crippledTimer[21])),false,function TremorTim_TimedRemoveStun)
endif
set bj_groupRandomCurrentPick = dummy
call ExecuteFunc("TremorTim_ReturnStunDummy")
endif
set dummy = null
set gc = null
return stun
endfunction
/////////////////////////////////////////////////////////////////
//End of the Variable Stun System////////////////////////////////
/////////////////////////////////////////////////////////////////
function TremorTim_Finale takes nothing returns nothing
local gamecache gc = TremorTim_Gamecache()
local timer t = GetExpiredTimer()
local string s = I2S(H2I(t))
local unit c = I2U(GetStoredInteger(gc, s, "c"))
call SelectUnitAddForPlayer(c, GetOwningPlayer(c))
call SetUnitTimeScale(c, -1)
call TriggerSleepAction (3.2)
call SetUnitTimeScale(c, 1)
call SetUnitAnimation(c, "stand")
call PauseUnit(c, false)
call SetUnitInvulnerable(c, false)
set gc = null
set c = null
call PauseTimer(t)
call DestroyTimer(t)
set t = null
endfunction
function TremorTim_Timer takes nothing returns nothing
local gamecache gc = TremorTim_Gamecache()
local string s = I2S(H2I(GetExpiredTimer()))
local unit c = I2U(GetStoredInteger(gc, s, "c"))
local player pc = GetOwningPlayer(c)
local unit t = I2U(GetStoredInteger(gc, s, "t"))
local integer l = GetStoredInteger(gc, s, "l")
local integer hide = GetStoredInteger(gc, s, "h")
local integer stg = GetStoredInteger(gc, s, "s")
local real a = GetStoredReal(gc, s, "a")
local real x = GetStoredReal(gc, s, "bx")
local real y = GetStoredReal(gc, s, "by")
local real dx
local real dy
local integer z = GetStoredInteger(gc, s, "z")
local integer s2 = GetStoredInteger(gc, s, "s2")
local integer en = GetStoredInteger(gc, s, "en")
local group g = CreateGroup()
local group g2 = I2G(GetStoredInteger(gc, s, "g2"))
local unit f
local integer dn = GetStoredInteger(gc, s, "dn")
local real r = GetStoredReal(gc, s, "r")
if stg == 1 then //Stage 1:1
if s2 == 0 then
set dx = GetUnitX(t) - x
set dy = GetUnitY(t) - y
if dx*dx + dy*dy > 2500 then
//Move mound to unit
call StoreInteger(gc, s, "d" + I2S(dn), H2I(TerrainDeformCrater(x, y, 70, -40, 600, false)))
call StoreInteger(gc, s, "dn", dn + 1)
call GroupEnumUnitsInRange(g, x, y, 80, null)
loop
set f = FirstOfGroup(g)
exitwhen f == null
if GetUnitState(f, UNIT_STATE_LIFE) > 0.405 and IsUnitEnemy( f, pc) and not IsUnitType(f, UNIT_TYPE_FLYING) and not IsUnitInGroup(f, g2) then
call UnitDamageTarget(c, f, TremorTim_Real(1) + 10*l, true, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
call TremorTim_RemoveUnitStun(f)
call TremorTim_StunUnit(f, TremorTim_Real(4) + l, true)
call GroupAddUnit(g2, f)
endif
call GroupRemoveUnit(g, f)
endloop
set a = Atan2(dy, dx)
call StoreReal(gc, s, "a", a)
call StoreReal(gc, s, "bx", x + 40 * Cos(a))
call StoreReal(gc, s, "by", y + 40 * Sin(a))
call StoreInteger(gc, s, "e" + I2S(en), H2I(AddSpecialEffect(TremorTim_String(1), x, y)))
call StoreInteger(gc, s, "en", en + 1)
else
//Stun the target and go to Stage 1:2
call TremorTim_RemoveUnitStun(t)
call TremorTim_StunUnit(t, 4.00, true)
call StoreReal(gc, s, "x2", GetUnitX(t) + Cos(a) * 700)
call StoreReal(gc, s, "y2", GetUnitY(t) + Sin(a) * 700)
call StoreReal(gc, s, "ca", Cos(a))
call StoreReal(gc, s, "sa", Sin(a))
call StoreInteger(gc, s, "s2", 1)
endif
elseif s2 == 1 then //Stage 1:2
//Move 500 past target
set dx = GetStoredReal(gc, s, "x2") - x
set dy = GetStoredReal(gc, s, "y2") - y
if dx*dx + dy*dy > 2500 then
call StoreInteger(gc, s, "d" + I2S(dn), H2I(TerrainDeformCrater(x, y, 70, -40, 600, false)))
call StoreInteger(gc, s, "dn", dn + 1)
call GroupEnumUnitsInRange(g, x, y, 80, null)
loop
set f = FirstOfGroup(g)
exitwhen f == null
if GetUnitState(f, UNIT_STATE_LIFE) > 0.405 and IsUnitEnemy( f, pc) and not IsUnitType(f, UNIT_TYPE_FLYING) and not IsUnitInGroup(f, g2) then
call UnitDamageTarget(c, f, TremorTim_Real(1) + 10*l, true, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
call TremorTim_RemoveUnitStun(f)
call TremorTim_StunUnit(f, TremorTim_Real(4) + l, true)
call GroupAddUnit(g2, f)
endif
call GroupRemoveUnit(g, f)
endloop
call StoreReal(gc, s, "bx", x + 40 * GetStoredReal(gc, s, "ca"))
call StoreReal(gc, s, "by", y + 40 * GetStoredReal(gc, s, "sa"))
call StoreInteger(gc, s, "e" + I2S(en), H2I(AddSpecialEffect(TremorTim_String(1), x, y)))
call StoreInteger(gc, s, "en", en + 1)
else
//500 offset reached, on to Stage 2
set x = GetUnitX(t)
set y = GetUnitY(t)
set dx = GetUnitX(c) - x
set dy = GetUnitY(c) - y
set a = Atan2(dy, dx)
call StoreInteger(gc, s, "dh", H2I(CreateUnit(pc, TremorTim_Dummy(2), x, y, a * 57.2958)))
call StoreReal(gc, s, "bx", x)
call StoreReal(gc, s, "by", y)
call StoreReal(gc, s, "a", 30)
call StoreInteger(gc, s, "s", 2)
call GroupClear(g2)
endif
endif
elseif stg == 2 then
if a <= 0 then
//We have hand impact!
call DestroyEffect(AddSpecialEffect(TremorTim_String(3), x, y))
call DestroyEffect(AddSpecialEffect(TremorTim_String(3), x, y))
call StoreInteger(gc, s, "d" + I2S(dn), H2I(TerrainDeformRipple(GetUnitX(t), GetUnitY(t), 512, 128, 2000, 1, 1.00, 1.50, 3.125, false)))
call StoreInteger(gc, s, "dn", dn + 1)
call StoreInteger(gc, s, "s", 3)
call StoreReal(gc, s, "a", 30)
call GroupEnumUnitsInRange(g, x, y, 128, null)
//Smash units under palm
loop
set f = FirstOfGroup(g)
exitwhen f == null
if GetUnitState(f, UNIT_STATE_LIFE) > 0.405 and IsUnitEnemy( f, pc) and not IsUnitType(f, UNIT_TYPE_FLYING) then
call UnitDamageTarget(c, f, TremorTim_Real(2) + 10*l, true, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
call DestroyEffect(AddSpecialEffectTarget(TremorTim_Blood(f), f, TremorTim_String(2)))
endif
call GroupRemoveUnit(g, f)
endloop
else
//Subtract 1
call StoreReal(gc, s, "a", a - 1)
endif
elseif stg == 3 then
if a <= 0 then
//End of the ripple!
call StoreInteger(gc, s, "s", 4)
else
//Knock units in an expanding ring
call GroupEnumUnitsInRange(g, x, y, r, null)
loop
set f = FirstOfGroup(g)
exitwhen f == null
if GetUnitState(f, UNIT_STATE_LIFE) > 0.405 and IsUnitEnemy( f, pc) and not IsUnitType(f, UNIT_TYPE_FLYING) and not IsUnitInGroup(f, g2) then
call UnitDamageTarget(c, f, TremorTim_Real(3) + 10*l, true, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
call TremorTim_RemoveUnitStun(f)
call TremorTim_StunUnit(f, TremorTim_Real(4) + l, true)
call GroupAddUnit(g2, f)
endif
call GroupRemoveUnit(g, f)
endloop
//Subtract 1
call StoreReal(gc, s, "r", r + 10)
call StoreReal(gc, s, "a", a - 1)
endif
elseif stg == 4 then
//Being hero back and clean up
call ExecuteFunc("TremorTim_Finale")
call RemoveUnit(I2U(GetStoredInteger(gc, s, "dh")))
set en = en - 1
loop
exitwhen en <= 0
call DestroyEffect(I2E(GetStoredInteger(gc, s, "e" + I2S(en))))
set en = en - 1
endloop
set dn = dn - 1
loop
exitwhen dn <= 0
call TerrainDeformStop(I2TD(GetStoredInteger(gc, s, "d" + I2S(dn))), 5000)
set dn = dn - 1
endloop
call DestroyGroup(g2)
call FlushStoredMission(gc, s)
call DestroyTimer(GetExpiredTimer())
endif
set gc = null
set c = null
set t = null
call DestroyGroup(g)
set g = null
set g2 = null
set f = null
endfunction
function TremorTim_Begin takes nothing returns nothing
local timer t = GetExpiredTimer()
local gamecache gc = TremorTim_Gamecache()
local string s = I2S(H2I(t))
local unit c = I2U(GetStoredInteger(gc, s, "c"))
call SetUnitTimeScale(c, 0)
call TimerStart(t, 0.04, true, function TremorTim_Timer)
set gc = null
set c = null
set t = null
endfunction
function TremorTim_Actions takes nothing returns nothing
local timer t = CreateTimer()
local gamecache gc = TremorTim_Gamecache()
local string s = I2S(H2I(t))
local unit c = GetTriggerUnit()
call StoreInteger(gc, s, "l", GetUnitAbilityLevel(c, TremorTim_SpellID(1)))
call StoreInteger(gc, s, "g2", H2I(CreateGroup()))
call StoreInteger(gc, s, "c", H2I(c))
call StoreInteger(gc, s, "t", H2I(GetSpellTargetUnit()))
call StoreInteger(gc, s, "s", 1)
call StoreReal(gc, s, "bx", GetUnitX(c))
call StoreReal(gc, s, "by", GetUnitY(c))
call StoreInteger(gc, s, "z", 40)
call StoreInteger(gc, s, "h", 255)
call PauseUnit(c, true)
call SetUnitInvulnerable(c, true)
call TriggerSleepAction (0.00)
call SetUnitTimeScale(c, 2 )
call SetUnitAnimation(c, "death")
call TimerStart(t, 1.7, false, function TremorTim_Begin)
set c = null
set gc = null
set t = null
endfunction
//===========================================================================
function InitTrig_TremorTim takes nothing returns nothing
set gg_trg_TremorTim = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_TremorTim, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_TremorTim, Condition( function TremorTim_Conditions ) )
call TriggerAddAction( gg_trg_TremorTim, function TremorTim_Actions )
call RemoveUnit(CreateUnit(Player(15), TremorTim_Dummy(1), 0, 0, 0))
call RemoveUnit(CreateUnit(Player(15), TremorTim_Dummy(2), 0, 0, 0))
call Preload(TremorTim_String(1))
call Preload(TremorTim_String(3))
call Preload(TremorTim_String(4))
call Preload("Objects\\spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl")
call Preload("Objects\\Spawnmodels\\NightElf\\NightElfLargeDeathExplode\\NightElfLargeDeathExplode.mdl")
call Preload("Objects\\Spawnmodels\\Orc\\OrcLargeDeathExplode\\OrcLargeDeathExplode.mdl")
call Preload("Objects\\Spawnmodels\\Undead\\UndeadLargeDeathExplode\\UndeadLargeDeathExplode.mdl")
call Preload("Objects\\Spawnmodels\\Demon\\DemonLargeDeathExplode\\DemonLargeDeathExplode.mdl")
endfunction
Disco Inferno: http://www.wc3c.net/showthread.php?t=87003
Uses Caster System as well.
Boulder Roll: http://www.wc3c.net/showthread.php?t=83005
Uses Return Bug.
Optimisation or full rewriting isn't necessary. I think it should just be fixing the systems and making it compatible with latest patch.
Well, how it's done doesn't really matter.
Thanks.
Attachments
Last edited: