- Joined
- Sep 9, 2007
- Messages
- 6,759
Anachron said:No, it isn't allowed.
Rules said:You may use utilities that do small jobs for you, but you may not use large systems that do everything.
One Spell.
Doesn't need to follow any lore.
No cJass.
Zinc is fine.
But in a situation like mine I am not using the projectile engine for the back-bone of the spell, I am only using it to amplify the cool-level. I could simply detect nearby unit damage or something for the spell I am planning but there really isn't any reason why I shouldn't be able to use the library for creating ranged projectiles.
There is a significant difference between a physics engine/caster system and a knock back/jump system. There is no point in having to re-create knock back specifically for a single spell when something like knock back isn't a do everything for you system. If an ability is being solely based off of knock back or jump then the author of that ability should look into thinking of better ideas anyways.
What exactly am I to do? I made the projectiles library so I could quite easily create a memory duplicate of the code designed for this specific spell, but it is rather dumb that I have to waste my time with that when it is obvious I have done the work necessary for what I am using.
Obviously it affects the ability's credibility when you are using older code though, since there was no time-limit on any older code that may be included, but why is it that other people are able to spam their abilities with cool special effects that they downloaded (and did not put work into) while I am not even able to spruce up my ability with a custom library that I made myself.
This is what I'm making. I'll try and code it tonight, shouldn't be hard.
Forms two wormholes, one at the position of spell casting, and another that will follow the hero as he walks. After 5 seconds the wormholes will activate, transporting all units near the Protoss Templar to the original wormhole. Enemy units will be damaged during the transportation.
Level 1 - Wormhole has a 200 radius, and deals 100 damage to enemies.
Level 2 - Wormhole has a 275 radius, and deals 175 damage to enemies.
Level 3 - Wormhole has a 350 radius, and deals 250 damage to enemies.
function Trig_Futur_Spell_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A000'
endfunction
function Futur_Spell_Remove_Dmger takes nothing returns nothing
local unit u = LoadUnitHandle(udg_Hashtable,GetHandleId(GetExpiredTimer()),0)
call KillUnit(u)
call FlushChildHashtable(udg_Hashtable,GetHandleId(GetExpiredTimer()))
call DestroyTimer(GetExpiredTimer())
set u = null
endfunction
function Futur_Spell_Dmg_Filter takes nothing returns boolean
local unit u = GetFilterUnit()
local unit caster = LoadUnitHandle(udg_Hashtable,GetHandleId(GetExpiredTimer()),5)
local timer t
if IsUnitEnemy(u,GetOwningPlayer(caster)) == true then
set t = CreateTimer()
call IssueTargetOrderById(caster,852119,u)
call TimerStart(t,1,false,function Futur_Spell_Remove_Dmger)
call SaveUnitHandle(udg_Hashtable,GetHandleId(t),0,caster)
set t = null
endif
set u = null
set caster = null
return false
endfunction
function Futur_Spell_DamageEnemies takes nothing returns nothing
local real tx = LoadReal(udg_Hashtable,GetHandleId(GetExpiredTimer()),0)
local real ty = LoadReal(udg_Hashtable,GetHandleId(GetExpiredTimer()),1)
local group g = CreateGroup()
call SaveUnitHandle(udg_Hashtable,GetHandleId(GetExpiredTimer()),5,GetEnumUnit())
call GroupEnumUnitsInRange(g,tx,ty,400,Filter(function Futur_Spell_Dmg_Filter))
call GroupClear(g)
call DestroyGroup(g)
set g = null
endfunction
function Futur_Spell_CircleCreate takes nothing returns nothing
local timer t = GetExpiredTimer()
local real tx = LoadReal(udg_Hashtable,GetHandleId(t),0)
local real ty = LoadReal(udg_Hashtable,GetHandleId(t),1)
local real face = LoadReal(udg_Hashtable,GetHandleId(t),2)
local group g = LoadGroupHandle(udg_Hashtable,GetHandleId(t),3)
local real x = tx + 400 * Cos(face * 0.0174532)
local real y = ty + 400 * Sin(face * 0.0174532)
local unit caster = LoadUnitHandle(udg_Hashtable,GetHandleId(t),4)
call GroupAddUnit(g,CreateUnit(GetOwningPlayer(caster),'n002',x,y,0))
call SaveGroupHandle(udg_Hashtable,GetHandleId(t),3,g)
call SaveReal(udg_Hashtable,GetHandleId(t),2,face + 5)
if face >= 360 then
call ForGroup(g,function Futur_Spell_DamageEnemies)
call FlushChildHashtable(udg_Hashtable,GetHandleId(t))
call PauseTimer(t)
call DestroyTimer(t)
endif
set t = null
set caster = null
set g = null
endfunction
function Futur_Spell_Group takes nothing returns boolean
local unit u = GetFilterUnit()
local unit caster = LoadUnitHandle(udg_Hashtable,GetHandleId(GetExpiredTimer()),3)
if GetUnitFlyHeight(u) == 0 and IsUnitType(u,UNIT_TYPE_DEAD) == false and u != caster then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Orc\\Purge\\PurgeBuffTarget.mdl",u,"chest"))
call UnitDamageTarget(caster,u,5,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_LIGHTNING,WEAPON_TYPE_WHOKNOWS)
endif
set u = null
set caster = null
return false
endfunction
function Futur_Spell_Effects_Create takes nothing returns nothing
local timer t = GetExpiredTimer()
local real tx = LoadReal(udg_Hashtable,GetHandleId(t),0)
local real ty = LoadReal(udg_Hashtable,GetHandleId(t),1)
local integer i = GetRandomInt(50,400)
local real i2 = GetRandomReal(0,359) * 0.0174532
local real x = tx + i * Cos(i2)
local real y = ty + i * Sin(i2)
local integer count = LoadInteger(udg_Hashtable,GetHandleId(t),2)
local unit caster = LoadUnitHandle(udg_Hashtable,GetHandleId(t),3)
local group g = CreateGroup()
local timer t2
call GroupEnumUnitsInRange(g,tx,ty,400,Filter(function Futur_Spell_Group))
call GroupClear(g)
call DestroyGroup(g)
call SaveInteger(udg_Hashtable,GetHandleId(t),2,count + 1)
if count <= 20 then
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl",x,y))
else
call FlushChildHashtable(udg_Hashtable,GetHandleId(t))
set t2 = CreateTimer()
call SaveReal(udg_Hashtable,GetHandleId(t2),0,tx)
call SaveReal(udg_Hashtable,GetHandleId(t2),1,ty)
call SaveReal(udg_Hashtable,GetHandleId(t2),2,1)
call SaveGroupHandle(udg_Hashtable,GetHandleId(t2),3,CreateGroup())
call SaveUnitHandle(udg_Hashtable,GetHandleId(t2),4,caster)
call TimerStart(t2,0.04,true,function Futur_Spell_CircleCreate)
call PauseTimer(t)
call DestroyTimer(t)
set t2 = null
endif
set g = null
set t = null
set caster = null
endfunction
function Futur_Spell_Rocket_Move takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit caster = LoadUnitHandle(udg_Hashtable,GetHandleId(t),3)
local unit rocket = LoadUnitHandle(udg_Hashtable,GetHandleId(t),0)
local real rx = GetUnitX(rocket)
local real ry = GetUnitY(rocket)
local real tx = LoadReal(udg_Hashtable,GetHandleId(t),1)
local real ty = LoadReal(udg_Hashtable,GetHandleId(t),2)
local real a = GetUnitFacing(rocket) * 0.0174532
local real x = rx + 30 * Cos(a)
local real y = ry + 30 * Sin(a)
local timer t2
if SquareRoot((tx - rx) * (tx - rx) + (ty - ry) * (ty - ry)) <= 100 then
call FlushChildHashtable(udg_Hashtable,GetHandleId(t))
call KillUnit(rocket)
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl",tx,ty))
call PauseTimer(t)
call DestroyTimer(t)
set t2 = CreateTimer()
call SaveUnitHandle(udg_Hashtable,GetHandleId(t2),3,caster)
call SaveReal(udg_Hashtable,GetHandleId(t2),0,tx)
call SaveReal(udg_Hashtable,GetHandleId(t2),1,ty)
call TimerStart(t2,0.08,true,function Futur_Spell_Effects_Create)
set t2 = null
else
call SetUnitX(rocket,x)
call SetUnitY(rocket,y)
endif
set caster = null
set rocket = null
set t = null
endfunction
function Trig_Futur_Spell_Actions takes nothing returns nothing
local unit caster = GetTriggerUnit()
local real cx = GetUnitX(caster)
local real cy = GetUnitY(caster)
local real tx = GetSpellTargetX()
local real ty = GetSpellTargetY()
local real face = 57.295827 * Atan2(ty - cy,tx - cx)
local unit rocket = CreateUnit(GetOwningPlayer(caster),'n000',cx,cy,face)
local timer t = CreateTimer()
if udg_Hashtable == null then
set udg_Hashtable = InitHashtable()
endif
call SaveUnitHandle(udg_Hashtable,GetHandleId(t),0,rocket)
call SaveReal(udg_Hashtable,GetHandleId(t),1,tx)
call SaveReal(udg_Hashtable,GetHandleId(t),2,ty)
call SaveUnitHandle(udg_Hashtable,GetHandleId(t),3,caster)
call TimerStart(t,0.04,true,function Futur_Spell_Rocket_Move)
set caster = null
set rocket = null
set t = null
endfunction
//===========================================================================
function InitTrig_Futur_Spell takes nothing returns nothing
set gg_trg_Futur_Spell = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Futur_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Futur_Spell, Condition( function Trig_Futur_Spell_Conditions ) )
call TriggerAddAction( gg_trg_Futur_Spell, function Trig_Futur_Spell_Actions )
endfunction
So, here I go...
Hope my coding isn't very bad...
My spell is called "Multishock". Fires deadly rocket at the target point. When it reaches the point it blows and releases energetic shock that deals some damage to units in radius 400 from the target point. Also creates lightning circle that damages units inside it and vanishes.
[Warning: lightning spheres may not vanish. If so, cast the skill one more time]
| 1 lvl | 1 trigger | MUI | Leakless | non-import |
Coding:
JASS:function Trig_Futur_Spell_Conditions takes nothing returns boolean return GetSpellAbilityId() == 'A000' endfunction function Futur_Spell_Remove_Dmger takes nothing returns nothing local unit u = LoadUnitHandle(udg_Hashtable,GetHandleId(GetExpiredTimer()),0) call KillUnit(u) call FlushChildHashtable(udg_Hashtable,GetHandleId(GetExpiredTimer())) call DestroyTimer(GetExpiredTimer()) set u = null endfunction function Futur_Spell_Dmg_Filter takes nothing returns boolean local unit u = GetFilterUnit() local unit caster = LoadUnitHandle(udg_Hashtable,GetHandleId(GetExpiredTimer()),5) local timer t if IsUnitEnemy(u,GetOwningPlayer(caster)) == true then set t = CreateTimer() call IssueTargetOrderById(caster,852119,u) call TimerStart(t,1,false,function Futur_Spell_Remove_Dmger) call SaveUnitHandle(udg_Hashtable,GetHandleId(t),0,caster) set t = null endif set u = null set caster = null return false endfunction function Futur_Spell_DamageEnemies takes nothing returns nothing local real tx = LoadReal(udg_Hashtable,GetHandleId(GetExpiredTimer()),0) local real ty = LoadReal(udg_Hashtable,GetHandleId(GetExpiredTimer()),1) local group g = CreateGroup() call SaveUnitHandle(udg_Hashtable,GetHandleId(GetExpiredTimer()),5,GetEnumUnit()) call GroupEnumUnitsInRange(g,tx,ty,400,Filter(function Futur_Spell_Dmg_Filter)) call GroupClear(g) call DestroyGroup(g) set g = null endfunction function Futur_Spell_CircleCreate takes nothing returns nothing local timer t = GetExpiredTimer() local real tx = LoadReal(udg_Hashtable,GetHandleId(t),0) local real ty = LoadReal(udg_Hashtable,GetHandleId(t),1) local real face = LoadReal(udg_Hashtable,GetHandleId(t),2) local group g = LoadGroupHandle(udg_Hashtable,GetHandleId(t),3) local real x = tx + 400 * Cos(face * 0.0174532) local real y = ty + 400 * Sin(face * 0.0174532) local unit caster = LoadUnitHandle(udg_Hashtable,GetHandleId(t),4) call GroupAddUnit(g,CreateUnit(GetOwningPlayer(caster),'n002',x,y,0)) call SaveGroupHandle(udg_Hashtable,GetHandleId(t),3,g) call SaveReal(udg_Hashtable,GetHandleId(t),2,face + 5) if face >= 360 then call ForGroup(g,function Futur_Spell_DamageEnemies) call FlushChildHashtable(udg_Hashtable,GetHandleId(t)) call PauseTimer(t) call DestroyTimer(t) endif set t = null set caster = null set g = null endfunction function Futur_Spell_Group takes nothing returns boolean local unit u = GetFilterUnit() local unit caster = LoadUnitHandle(udg_Hashtable,GetHandleId(GetExpiredTimer()),3) if GetUnitFlyHeight(u) == 0 and IsUnitType(u,UNIT_TYPE_DEAD) == false and u != caster then call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Orc\\Purge\\PurgeBuffTarget.mdl",u,"chest")) call UnitDamageTarget(caster,u,5,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_LIGHTNING,WEAPON_TYPE_WHOKNOWS) endif set u = null set caster = null return false endfunction function Futur_Spell_Effects_Create takes nothing returns nothing local timer t = GetExpiredTimer() local real tx = LoadReal(udg_Hashtable,GetHandleId(t),0) local real ty = LoadReal(udg_Hashtable,GetHandleId(t),1) local integer i = GetRandomInt(50,400) local real i2 = GetRandomReal(0,359) * 0.0174532 local real x = tx + i * Cos(i2) local real y = ty + i * Sin(i2) local integer count = LoadInteger(udg_Hashtable,GetHandleId(t),2) local unit caster = LoadUnitHandle(udg_Hashtable,GetHandleId(t),3) local group g = CreateGroup() local timer t2 call GroupEnumUnitsInRange(g,tx,ty,400,Filter(function Futur_Spell_Group)) call GroupClear(g) call DestroyGroup(g) call SaveInteger(udg_Hashtable,GetHandleId(t),2,count + 1) if count <= 20 then call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl",x,y)) else call FlushChildHashtable(udg_Hashtable,GetHandleId(t)) set t2 = CreateTimer() call SaveReal(udg_Hashtable,GetHandleId(t2),0,tx) call SaveReal(udg_Hashtable,GetHandleId(t2),1,ty) call SaveReal(udg_Hashtable,GetHandleId(t2),2,1) call SaveGroupHandle(udg_Hashtable,GetHandleId(t2),3,CreateGroup()) call SaveUnitHandle(udg_Hashtable,GetHandleId(t2),4,caster) call TimerStart(t2,0.04,true,function Futur_Spell_CircleCreate) call PauseTimer(t) call DestroyTimer(t) set t2 = null endif set g = null set t = null set caster = null endfunction function Futur_Spell_Rocket_Move takes nothing returns nothing local timer t = GetExpiredTimer() local unit caster = LoadUnitHandle(udg_Hashtable,GetHandleId(t),3) local unit rocket = LoadUnitHandle(udg_Hashtable,GetHandleId(t),0) local real rx = GetUnitX(rocket) local real ry = GetUnitY(rocket) local real tx = LoadReal(udg_Hashtable,GetHandleId(t),1) local real ty = LoadReal(udg_Hashtable,GetHandleId(t),2) local real a = GetUnitFacing(rocket) * 0.0174532 local real x = rx + 30 * Cos(a) local real y = ry + 30 * Sin(a) local timer t2 if SquareRoot((tx - rx) * (tx - rx) + (ty - ry) * (ty - ry)) <= 100 then call FlushChildHashtable(udg_Hashtable,GetHandleId(t)) call KillUnit(rocket) call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl",tx,ty)) call PauseTimer(t) call DestroyTimer(t) set t2 = CreateTimer() call SaveUnitHandle(udg_Hashtable,GetHandleId(t2),3,caster) call SaveReal(udg_Hashtable,GetHandleId(t2),0,tx) call SaveReal(udg_Hashtable,GetHandleId(t2),1,ty) call TimerStart(t2,0.08,true,function Futur_Spell_Effects_Create) set t2 = null else call SetUnitX(rocket,x) call SetUnitY(rocket,y) endif set caster = null set rocket = null set t = null endfunction function Trig_Futur_Spell_Actions takes nothing returns nothing local unit caster = GetTriggerUnit() local real cx = GetUnitX(caster) local real cy = GetUnitY(caster) local real tx = GetSpellTargetX() local real ty = GetSpellTargetY() local real face = 57.295827 * Atan2(ty - cy,tx - cx) local unit rocket = CreateUnit(GetOwningPlayer(caster),'n000',cx,cy,face) local timer t = CreateTimer() if udg_Hashtable == null then set udg_Hashtable = InitHashtable() endif call SaveUnitHandle(udg_Hashtable,GetHandleId(t),0,rocket) call SaveReal(udg_Hashtable,GetHandleId(t),1,tx) call SaveReal(udg_Hashtable,GetHandleId(t),2,ty) call SaveUnitHandle(udg_Hashtable,GetHandleId(t),3,caster) call TimerStart(t,0.04,true,function Futur_Spell_Rocket_Move) set caster = null set rocket = null set t = null endfunction //=========================================================================== function InitTrig_Futur_Spell takes nothing returns nothing set gg_trg_Futur_Spell = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Futur_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Futur_Spell, Condition( function Trig_Futur_Spell_Conditions ) ) call TriggerAddAction( gg_trg_Futur_Spell, function Trig_Futur_Spell_Actions ) endfunction
Credit to the Blizzard ent. for the incredible game ^^
Download and enjoy!
Good luck to all of the contestants!
The contest concludes on April 30th.
(ok AutoIndex is quite a bit system but its not as if it writes a spell for me like a projectile system does?)
AutoIndex is 800 lines of code long and he can use that while I can't use my projectiles?
Whatever then I'm out this contest is stupid. I've given justification as to why there is no reason projectiles shouldn't be allowed and nobody has responded, and now people are being able to use AutoIndex but I can't even use a system I made myself. I'm out. I'm not for bullshit rules that favor a select few people.
In fact, i do. I find such posts to be a wonderful example of why prohibiting use of libraries is a bad idea.No one cares.
And also wish me luck.....
library SingularityAttack initializer Init requires OrbStacking, GroupUtils, optional GetProc
globals
private constant integer AID = 'A002' // Base if off of something like Hardened Skin
private constant integer ORB_PRIORITY = 0 // determines when to execute this orb, lower means later
private constant integer ORB_TYPE = ABILITY_TYPE_SKILL // if you want this ability to be an item ability, change to ABILITY_TYPE_ITEM
private real array PROC_CHANCE // 0..1 // Chance this effect gets activated.
private constant real PROC_WEIGHT = 0.5 // refer to GetProc's documentation for a description on what this does. Only has an effect if GetProc exists
private real array AOE //
private real array DURATION // in seconds
private real array MIN_PULL // speed per second at AOE[level] distance
private real array MAX_PULL // speed per second at 0 distance
private real array MIN_DAMAGE // per second
private real array MAX_DAMAGE // per second
private constant real MIN_DISTANCE = 0
private constant string TARGET_FX = "" // always get destroyed instantly (ie. only plays the death animation)
private constant string TARGET_FX_ATTPT = ""
private constant string PULL_FX = "" // lasts for however long the unit is pulled towards the unit targeted by the orb
private constant string PULL_FX_ATTPT = ""
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_MAGIC
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_MAGIC
private constant real TICK = 1./40
endglobals
private function Proc_Chance takes integer level returns real
return PROC_CHANCE[level]
endfunction
private function Aoe takes integer level returns real
return AOE[level]
endfunction
private function Duration takes integer level returns real
return DURATION[level]
endfunction
private function Min_Pull takes integer level returns real
return MIN_PULL[level]
endfunction
private function Max_Pull takes integer level returns real
return MAX_PULL[level]
endfunction
private function Min_Damage takes integer level returns real
return MIN_DAMAGE[level]
endfunction
private function Max_Damage takes integer level returns real
return MAX_DAMAGE[level]
endfunction
private function SetUpArrays takes nothing returns nothing
set PROC_CHANCE[1]=1.
set PROC_CHANCE[2]=1.
set PROC_CHANCE[3]=1.
set AOE[1]=250
set AOE[2]=250
set AOE[3]=250
set DURATION[1]=0.2
set DURATION[2]=0.3
set DURATION[3]=0.4
set MIN_PULL[1]=100
set MIN_PULL[2]=150
set MIN_PULL[3]=200
set MAX_PULL[1]=600
set MAX_PULL[2]=700
set MAX_PULL[3]=800
set MIN_DAMAGE[1]=10
set MIN_DAMAGE[2]=20
set MIN_DAMAGE[3]=30
set MAX_DAMAGE[1]=100
set MAX_DAMAGE[2]=200
set MAX_DAMAGE[3]=300
endfunction
private function ValidateTarget takes unit u, unit caster returns boolean
return not IsUnitType(u, UNIT_TYPE_DEAD) /*
*/ and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) /*
*/ and not IsUnitType(u, UNIT_TYPE_STRUCTURE) /*
*/ and IsUnitEnemy(u, GetOwningPlayer(caster)) /*
*/ and GetUnitMoveSpeed(u)>0 /*
*/
endfunction
//
globals
constant key PROC_CHANCE_KEY
endglobals
private struct Data
unit target // the unit being pulled to the caster
unit caster // the unit the target is being pulled to
unit attacker // the unit that launched the attack that spawned this instance
integer level // level of AID on attacker
effect pullfx
real elapsed=0
private integer i
private static thistype array Structs
private static timer T=CreateTimer()
private static integer Count=0
private method onDestroy takes nothing returns nothing
set target=null
set caster=null
set attacker=null
call DestroyEffect(pullfx)
set pullfx=null
set Count=Count-1
set Structs[i]=Structs[Count]
set Structs[i].i=i
if Count==0 then
call PauseTimer(T)
endif
endmethod
private static method Callback takes nothing returns nothing
local integer i=Count-1
local thistype s
local real x
local real y
local real dx
local real dy
local real d
local real ratio
local real pull
loop
exitwhen i<0
set s=.Structs[i]
if IsUnitType(s.target, UNIT_TYPE_DEAD) or IsUnitType(s.caster, UNIT_TYPE_DEAD) then
call s.destroy()
else
set x=GetUnitX(s.target)
set y=GetUnitY(s.target)
set dx=GetUnitX(s.caster)-x
set dy=GetUnitY(s.caster)-y
set d=SquareRoot(dx*dx+dy*dy)
set ratio=d/Aoe(s.level)
set pull=TICK*(Min_Pull(s.level)+ratio*(Max_Pull(s.level)-Min_Pull(s.level)))
call UnitDamageTarget(s.attacker, s.target, TICK*(Min_Damage(s.level)+ratio*(Max_Damage(s.level)-Min_Damage(s.level))), true, false, ATTACK_TYPE, DAMAGE_TYPE, null)
if d>MIN_DISTANCE and d>=pull then
call SetUnitX(s.target, x+(dx/d)*pull)
call SetUnitY(s.target, y+(dy/d)*pull)
endif
set s.elapsed=s.elapsed+TICK
if s.elapsed>=Duration(s.level) then
call s.destroy()
endif
endif
set i=i-1
endloop
endmethod
static method create takes unit target, unit caster, unit attacker returns thistype
local thistype s=allocate()
set s.target=target
set s.caster=caster
set s.attacker=attacker
set s.level=GetUnitAbilityLevel(attacker, AID)
set s.pullfx=AddSpecialEffectTarget(PULL_FX, target, PULL_FX_ATTPT)
set Structs[Count]=s
set s.i=Count
if Count==0 then
call TimerStart(T, TICK, true, function thistype.Callback)
endif
set Count=Count+1
return s
endmethod
endstruct
globals
private unit tmpt=null
private unit tmpc=null
endglobals
private function OnAttackCallback takes nothing returns boolean
local unit u=GetFilterUnit()
if u!=tmpt and ValidateTarget(u, tmpc) then
call Data.create(u, tmpt, tmpc)
endif
set u=null
return false
endfunction
private function Actions takes nothing returns boolean
local unit t=GetDamagedUnit()
local unit c=GetDamagingUnit()
local integer level=GetUnitAbilityLevel(c, AID)
set tmpt=t
set tmpc=c
call DestroyEffect(AddSpecialEffectTarget(TARGET_FX, t, TARGET_FX_ATTPT))
static if LIBRARY_GetProc then
if GetProc(PROC_CHANCE_KEY, c, Proc_Chance(level)) then
call GroupEnumUnitsInArea(ENUM_GROUP, GetUnitX(t), GetUnitY(t), Aoe(level), Condition(function OnAttackCallback))
set t=null
set c=null
return ORB_APPLIED
endif
else
if GetRandomReal(0., 1.)<=Proc_Chance(level) then
call GroupEnumUnitsInArea(ENUM_GROUP, GetUnitX(t), GetUnitY(t), Aoe(level), Condition(function OnAttackCallback))
set t=null
set c=null
return ORB_APPLIED
endif
endif
set t=null
set c=null
return ORB_NOT_APPLIED
endfunction
private function Init takes nothing returns nothing
local Orb o=Orb.create(AID, ORB_TYPE, ORB_PRIORITY, Actions)
static if LIBRARY_GetProc then
call SetProcWeight(PROC_CHANCE_KEY, PROC_WEIGHT)
endif
call SetUpArrays()
endfunction
endlibrary
@ Piranha89 I would say the concept is still rather imbalanced. Keep in mind that Mothership had some kind of void ability too which teleported away hostile units from the map for a short period (in case of unorginality, just saying=)?)
function SummonIntraNETACond takes nothing returns boolean
return GetSpellAbilityId() == 'A100'
endfunction
function SummonIntraNETHCond takes nothing returns boolean
return GetSpellAbilityId() == 'A101'
endfunction
function SummonIntraNETECond takes nothing returns boolean
return GetSpellAbilityId() == 'A102'
endfunction
function FindIntraNETCond takes nothing returns boolean
local unit u = GetFilterUnit()
local player p = GetOwningPlayer(u)
local player p2 = GetOwningPlayer(bj_lastCreatedUnit)
local boolean b = (GetUnitTypeId(u) == 'h100' or GetUnitTypeId(u) == 'h101' or GetUnitTypeId(u) == 'h102') and p == p2 and GetUnitState(u, UNIT_STATE_LIFE) > 1
set u = null
set p = null
set p2 = null
return b
endfunction
function SightTowerCond takes nothing returns boolean
local unit u = GetFilterUnit()
local player p = GetOwningPlayer(u)
local player p2 = GetOwningPlayer(bj_lastCreatedUnit)
local boolean b = (GetUnitTypeId(u) == 'h101' or GetUnitTypeId(u) == 'h102') and p == p2 and GetUnitState(u, UNIT_STATE_LIFE) > 1
set u = null
set p = null
set p2 = null
return b
endfunction
function HealTowerCond takes nothing returns boolean
local unit u = GetFilterUnit()
local player p = GetOwningPlayer(u)
local player p2 = GetOwningPlayer(bj_lastCreatedUnit)
local boolean b = (GetUnitTypeId(u) == 'h100' or GetUnitTypeId(u) == 'h102') and p == p2 and GetUnitState(u, UNIT_STATE_LIFE) > 1
set u = null
set p = null
set p2 = null
return b
endfunction
function ExplodeTowerCond takes nothing returns boolean
local unit u = GetFilterUnit()
local player p = GetOwningPlayer(u)
local player p2 = GetOwningPlayer(bj_lastCreatedUnit)
local boolean b = (GetUnitTypeId(u) == 'h100' or GetUnitTypeId(u) == 'h101') and p == p2 and GetUnitState(u, UNIT_STATE_LIFE) > 1
set u = null
set p = null
set p2 = null
return b
endfunction
function DestroyLightnings takes unit u returns nothing
local integer index = LoadInteger(udg_ht, GetHandleId(u), 0)
local lightning LFX
loop
exitwhen index < 1
set LFX = LoadLightningHandle( udg_ht, GetHandleId(u), index)
call DestroyLightning(LFX)
set index = index - 1
endloop
set LFX = null
endfunction
function CreateLightnings takes unit u, string LFXType returns integer
local boolexpr bx = Condition( function FindIntraNETCond )
local group g = CreateGroup()
local location l = GetUnitLoc(u)
local location l2
local lightning LFX
local integer index = 1
local unit u2
set bj_lastCreatedUnit = u
call GroupEnumUnitsInRangeOfLoc(g, l, 200, bx)
call GroupRemoveUnit(g, u)
loop
set u2 = FirstOfGroup(g)
exitwhen u2 == null
set l2 = GetUnitLoc(u2)
//Figure out what kind of lightning to add.
set LFX = AddLightningEx(LFXType, true, GetLocationX(l), GetLocationY(l), GetLocationZ(l)+10, GetLocationX(l2), GetLocationY(l2), GetLocationZ(l2)+10)
//Add it so that when it changes or dies, the lightning can be removed.
call SaveLightningHandle(udg_ht, GetHandleId(u), index, LFX)
call GroupRemoveUnit(g, u2)
set index = index + 1
endloop
//Cleanup
call DestroyBoolExpr(bx)
set bx = null
call DestroyGroup(g)
set g = null
set l = null
set l2 = null
set LFX = null
set u2 = null
return index
endfunction
function Death takes nothing returns nothing
local unit u = GetTriggerUnit()
local group g = CreateGroup()
local location l
local boolexpr bx = Condition( function FindIntraNETCond )
local timer ttimer
local trigger t = GetTriggeringTrigger()
//Clean up lightnings
call DestroyLightnings(u)
call GroupEnumUnitsInRangeOfLoc( g, l, 200, bx )
loop
set u = FirstOfGroup(g)
exitwhen u == null
call DestroyLightnings(u)
//Determine what kind of LFX Type / Boolexpr to use.
if GetUnitTypeId(u) == 'h100' then
call CreateLightnings(u, "AFOD")
elseif GetUnitTypeId(u) == 'h101' then
call CreateLightnings(u, "DRAM")
elseif GetUnitTypeId(u) == 'h102' then
call CreateLightnings(u, "CLPB")
endif
endloop
//Cleanup
set ttimer = null
set bx = null
call DestroyGroup(g)
set g = null
set l = null
call DestroyTrigger(t)
endfunction
function Change takes nothing returns nothing
local timer etimer = GetExpiredTimer()
local timer ttimer
local unit u = LoadUnitHandle(udg_ht, GetHandleId(etimer), 0)
local unit u2
local string LFXType
local integer index
local boolexpr bx
local group g = CreateGroup()
local location l
local player p
local trigger t
//Determine what kind of LFX Type / Boolexpr to use.
if GetUnitTypeId(u) == 'h100' then
set LFXType = "AFOD"
set bx = Condition( function SightTowerCond )
elseif GetUnitTypeId(u) == 'h101' then
set LFXType = "DRAM"
set bx = Condition( function HealTowerCond )
elseif GetUnitTypeId(u) == 'h102' then
set LFXType = "CLPB"
set bx = Condition( function ExplodeTowerCond )
endif
call DestroyLightnings(u)
set l = GetUnitLoc(u)
call GroupEnumUnitsInRangeOfLoc(g, l, 200, bx)
loop
set u2 = FirstOfGroup(g)
exitwhen u2 == null
//Clean up the current tower
set t = LoadTriggerHandle(udg_ht, GetHandleId(u2), 1000)
call DestroyTrigger(t)
set p = GetOwningPlayer(u2)
set l = GetUnitLoc(u2)
//Clean up lightnings
call DestroyLightnings( u2 )
call GroupRemoveUnit(g, u2)
call RemoveUnit(u2)
set u2 = CreateUnit(p, GetUnitTypeId(u), GetLocationX(l), GetLocationY(l), 0)
//Recreate the death trigger
set t = CreateTrigger()
call TriggerAddAction( t, function Death )
call TriggerRegisterUnitEvent( t, u2, EVENT_UNIT_DEATH )
call SaveTriggerHandle( udg_ht, GetHandleId(u2), 1000, t )
//Finally, allow a new change to occur.
set ttimer = CreateTimer()
call SaveUnitHandle(udg_ht, GetHandleId(ttimer), 0, u2)
call TimerStart( ttimer, 0.5, false, function Change )
endloop
//Create new units/lightning
set index = CreateLightnings( u, LFXType )
//Update the new tower's index
call SaveInteger(udg_ht, GetHandleId(u), 0, index)
call IssuePointOrderLoc( u, "selfdestruct", l) //Causes it to blow up if its an exploding tower.
call AttachSoundToUnit(gg_snd_StasisTotem, u) //EarCandy
call StartSound(gg_snd_StasisTotem) //EarCandy
//Cleanup
call DestroyBoolExpr(bx)
set u = null
set u2 = null
call DestroyGroup(g)
set g = null
set p = null
set l = null
set bx = null
set ttimer = null
set etimer = null
set t = null
endfunction
//Initializes the ward
function SummonIntraNET takes nothing returns nothing
//Local vars
local location l = GetSpellTargetLoc()
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(u)
local string LFXType
local trigger t = CreateTrigger()
local timer ttimer
//Figure out where we're supposed to place the node.
//Figure out what kind of unit to build
if GetSpellAbilityId() == 'A100' then
set LFXType = "AFOD"
set u = CreateUnitAtLoc( p, 'h100', l, 0 )
elseif GetSpellAbilityId() == 'A101' then
set LFXType = "DRAM"
set u = CreateUnitAtLoc( p, 'h101', l, 0 )
elseif GetSpellAbilityId() == 'A102' then
set LFXType = "CLPB"
set u = CreateUnitAtLoc( p, 'h102', l, 0 )
endif
//Make a trigger catching the unit's death
call TriggerAddAction( t, function Death )
call TriggerRegisterUnitEvent( t, u, EVENT_UNIT_DEATH )
call SaveTriggerHandle( udg_ht, GetHandleId(u), 1000, t )
//Ripple up a change
set ttimer = CreateTimer()
call SaveUnitHandle(udg_ht, GetHandleId(ttimer), 0, u)
call TimerStart( ttimer, 0.5, false, function Change )
//EarCandy
call AttachSoundToUnit(gg_snd_BuildingPlacement, u)
call StartSound(gg_snd_BuildingPlacement)
//Cleanup
set u = null
set p = null
set l = null
set ttimer = null
set t = null
endfunction
//===========================================================================
function InitTrig_IntraNET takes nothing returns nothing
local integer index
local trigger IntraNETHeal = CreateTrigger()
local trigger IntraNETExplode = CreateTrigger()
local conditionfunc Cond
local triggeraction Act
set gg_trg_IntraNET = CreateTrigger()
set Act = TriggerAddAction( gg_trg_IntraNET, function SummonIntraNET )
set Act = TriggerAddAction( IntraNETHeal, function SummonIntraNET )
set Act = TriggerAddAction( IntraNETExplode, function SummonIntraNET )
set Cond = Condition(function SummonIntraNETACond)
call TriggerAddCondition( gg_trg_IntraNET, Cond )
set Cond = Condition(function SummonIntraNETHCond)
call TriggerAddCondition( IntraNETHeal, Cond )
set Cond = Condition(function SummonIntraNETECond)
call TriggerAddCondition( IntraNETExplode, Cond )
//Let any unit do this.
set index = 0
set udg_ht = InitHashtable()
loop
call TriggerRegisterPlayerUnitEvent(gg_trg_IntraNET, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerRegisterPlayerUnitEvent(IntraNETHeal, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
call TriggerRegisterPlayerUnitEvent(IntraNETExplode, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
set Act = null
set Cond = null
endfunction