- Joined
- Oct 25, 2010
- Messages
- 11
Are those libraries supposed to do the same thing?
If they do the same thing, can i get rid of one of them?
If the response is yes, then which one do you recommend me to delete?
If the response is no, then I have another question... (I'm getting annoying, I know xD)
As you can see both of them use the library Table, but the problem is that they are not the same library
So the question is: Is there a chance to replace the Table From SpellEvent with the table made by Bribe? (The one from SpellEffectEvent)
Thanks and sorry for my bad english
EDIT: I forgot to say that SpellEffectEvent is used in this ability
and SpellEvent is used in this ability
JASS:
//============================================================================
// SpellEffectEvent
// - Version 1.0.0.1
//
// API
// ---
// RegisterSpellEffectEvent(integer abil, code onCast)
//
// Requires
// --------
// Table: hiveworkshop.com/forums/showthread.php?t=188084
// RegisterPlayerUnitEvent: hiveworkshop.com/forums/showthread.php?t=203338
//
library SpellEffectEvent requires RegisterPlayerUnitEvent, Table
globals
private Table tb
endglobals
//============================================================================
function RegisterSpellEffectEvent takes integer abil, code onCast returns nothing
if not tb.handle.has(abil) then
set tb.trigger[abil] = CreateTrigger()
endif
call TriggerAddCondition(tb.trigger[abil], Filter(onCast))
endfunction
//============================================================================
private module M
static method onCast takes nothing returns boolean
return TriggerEvaluate(tb.trigger[GetSpellAbilityId()])
endmethod
private static method onInit takes nothing returns nothing
set tb = Table.create()
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function thistype.onCast)
endmethod
endmodule
//============================================================================
private struct S extends array
implement M
endstruct
endlibrary
JASS:
library SpellEvent initializer Init requires Table
//*****************************************************************
//* SPELL EVENT LIBRARY
//*
//* written by: Anitarf
//* requires: -Table
//*
//* Maps with many triggered spells require many triggers that run
//* on spell events and whenever a spell is cast, all those
//* triggers need to be evaluated by the game even though only one
//* actually needs to run. This library has been written to reduce
//* the number of triggers in such maps; instead of having a
//* trigger per spell, you can use this library's single trigger
//* to only run the code associated with the spell that's actually
//* being cast.
//*
//* Perhaps more significant than the marginal speed gain is the
//* feature that allows you to access all the spell event
//* responses from all spell events, something that the native
//* functions senselessly do not support. With this system you can
//* for example easily get the target unit of the spell on the
//* casting finish event.
//*
//* All functions following the Response function interface that
//* is defined at the start of this library can be used to respond
//* to damage events. Simply put them on the call list for any of
//* the spell events using the appropriate function:
//*
//* function RegisterSpellChannelResponse takes integer spellId, Response r returns nothing
//* function RegisterSpellCastResponse takes integer spellId, Response r returns nothing
//* function RegisterSpellEffectResponse takes integer spellId, Response r returns nothing
//* function RegisterSpellFinishResponse takes integer spellId, Response r returns nothing
//* function RegisterSpellEndCastResponse takes integer spellId, Response r returns nothing
//*
//* The first event occurs at the very start of the spell, when
//* the spell's casting time begins; most spells have 0 casting
//* time, so in most cases this first event occurs at the same
//* time as the second one, which runs when the unit actually
//* begins casting a spell by starting it's spell animation. The
//* third event occurs when the spell effect actually takes place,
//* which happens sometime into the unit's spell animation
//* depending on the unit's Animation - Cast Point property.
//* The fourth event runs if the unit finishes casting the spell
//* uninterrupted, which might be important for channeling spells.
//* The last event runs when the unit stops casting the spell,
//* regardless of whether it finished casting or was interrupted.
//*
//* If you specify a spell id when registering a function then
//* that function will only run when that ability is cast; only
//* one function per ability per event is supported, if you
//* register more functions then only the last one registered will
//* be called. If, however, you pass 0 as the ability id parameter
//* then the registered function will run for all spells. Up to
//* 8190 functions can be registered this way for each event.
//* These functions will be called before the ability's specific
//* function in the order they were registered.
//*
//* This library provides it's own event responses that work
//* better than the Blizzard's bugged native cast event responses.
//* They still aren't guaranteed to work after a wait, but aside
//* from that they will work in response functions no matter what
//* event they are registered to.
//*
//* Here are usage examples for all event responses:
//*
//* local integer a = SpellEvent.AbilityId
//* local unit u = SpellEvent.CastingUnit
//* local unit t = SpellEvent.TargetUnit
//* local item i = SpellEvent.TargetItem
//* local destructable d = SpellEvent.TargetDestructable
//* local location l = SpellEvent.TargetLoc
//* local real x = SpellEvent.TargetX
//* local real y = SpellEvent.TargetY
//* local boolean b = SpellEvent.CastFinished
//*
//* SpellEvent.TargetLoc is provided for odd people who insist on
//* using locations, note that if you use it you have to cleanup
//* the returned location yourself.
//*
//* SpellEvent.CastFinished boolean is intended only for the
//* EndCast event as it tells you whether the spell finished or
//* was interrupted.
//*
//*****************************************************************
// use the RegisterSpell*Response functions to add spell event responses to the library
public function interface Response takes nothing returns nothing
// ================================================================
private keyword casterTable
private keyword effectDone
private keyword init
private keyword get
private struct spellEvent
static HandleTable casterTable
boolean effectDone=false
integer AbilityId
unit CastingUnit
unit TargetUnit
item TargetItem=null
destructable TargetDestructable=null
real TargetX=0.0
real TargetY=0.0
boolean CastFinished=false
method operator TargetLoc takes nothing returns location
return Location(.TargetX, .TargetY)
endmethod
private static method create takes nothing returns spellEvent
return spellEvent.allocate()
endmethod
static method init takes nothing returns spellEvent
local spellEvent s=spellEvent.allocate()
set s.AbilityId = GetSpellAbilityId()
set s.CastingUnit = GetTriggerUnit()
set s.TargetUnit = GetSpellTargetUnit()
if s.TargetUnit != null then
set s.TargetX = GetUnitX(s.TargetUnit)
set s.TargetY = GetUnitY(s.TargetUnit)
else
set s.TargetDestructable = GetSpellTargetDestructable()
if s.TargetDestructable != null then
set s.TargetX = GetDestructableX(s.TargetDestructable)
set s.TargetY = GetDestructableY(s.TargetDestructable)
else
set s.TargetItem = GetSpellTargetItem()
if s.TargetItem != null then
set s.TargetX = GetItemX(s.TargetItem)
set s.TargetY = GetItemY(s.TargetItem)
else
set s.TargetX = GetSpellTargetX()
set s.TargetY = GetSpellTargetY()
endif
endif
endif
set spellEvent.casterTable[s.CastingUnit]=integer(s)
return s
endmethod
static method get takes unit caster returns spellEvent
return spellEvent(spellEvent.casterTable[caster])
endmethod
method onDestroy takes nothing returns nothing
call spellEvent.casterTable.flush(.CastingUnit)
set .CastingUnit=null
endmethod
endstruct
globals
spellEvent SpellEvent=0
endglobals
// ================================================================
//! textmacro spellEvent_make takes name
globals
private Response array $name$CallList
private integer $name$CallCount=0
private Table $name$Table
endglobals
private function $name$Calls takes nothing returns nothing
local integer i=0
local integer id=GetSpellAbilityId()
local spellEvent previous=SpellEvent
set SpellEvent=spellEvent.get(GetTriggerUnit())
loop
exitwhen i>=$name$CallCount
call $name$CallList[i].evaluate()
set i=i+1
endloop
if $name$Table.exists(id) then
call Response($name$Table[id]).evaluate()
endif
set SpellEvent=previous
endfunction
function RegisterSpell$name$Response takes integer spellId, Response r returns nothing
if spellId==0 then
set $name$CallList[$name$CallCount]=r
set $name$CallCount=$name$CallCount+1
else
set $name$Table[spellId]=integer(r)
endif
endfunction
//! endtextmacro
//! runtextmacro spellEvent_make("Channel")
//! runtextmacro spellEvent_make("Cast")
//! runtextmacro spellEvent_make("Effect")
//! runtextmacro spellEvent_make("Finish")
//! runtextmacro spellEvent_make("EndCast")
private function Channel takes nothing returns nothing
call spellEvent.init()
call ChannelCalls()
endfunction
private function Cast takes nothing returns nothing
call CastCalls()
endfunction
private function Effect takes nothing returns nothing
local spellEvent s=spellEvent.get(GetTriggerUnit())
if s!=0 and not s.effectDone then
set s.effectDone=true
call EffectCalls()
endif
endfunction
private function Finish takes nothing returns nothing
set spellEvent.get(GetTriggerUnit()).CastFinished=true
call FinishCalls()
endfunction
private function EndCast takes nothing returns nothing
call EndCastCalls()
call spellEvent.get(GetTriggerUnit()).destroy()
endfunction
// ================================================================
private function InitTrigger takes playerunitevent e, code c returns nothing
local trigger t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, e )
call TriggerAddAction(t, c)
set t=null
endfunction
private function Init takes nothing returns nothing
set spellEvent.casterTable=HandleTable.create()
set ChannelTable=Table.create()
set CastTable=Table.create()
set EffectTable=Table.create()
set FinishTable=Table.create()
set EndCastTable=Table.create()
call InitTrigger(EVENT_PLAYER_UNIT_SPELL_CHANNEL, function Channel)
call InitTrigger(EVENT_PLAYER_UNIT_SPELL_CAST, function Cast)
call InitTrigger(EVENT_PLAYER_UNIT_SPELL_EFFECT, function Effect)
call InitTrigger(EVENT_PLAYER_UNIT_SPELL_FINISH, function Finish)
call InitTrigger(EVENT_PLAYER_UNIT_SPELL_ENDCAST, function EndCast)
endfunction
endlibrary
If they do the same thing, can i get rid of one of them?
If the response is yes, then which one do you recommend me to delete?
If the response is no, then I have another question... (I'm getting annoying, I know xD)
As you can see both of them use the library Table, but the problem is that they are not the same library
JASS:
library Table
//***************************************************************
//* Table object 3.0
//* ------------
//*
//* set t=Table.create() - instanceates a new table object
//* call t.destroy() - destroys it
//* t[1234567] - Get value for key 1234567
//* (zero if not assigned previously)
//* set t[12341]=32 - Assigning it.
//* call t.flush(12341) - Flushes the stored value, so it
//* doesn't use any more memory
//* t.exists(32) - Was key 32 assigned? Notice
//* that flush() unassigns values.
//* call t.reset() - Flushes the whole contents of the
//* Table.
//*
//* call t.destroy() - Does reset() and also recycles the id.
//*
//* If you use HandleTable instead of Table, it is the same
//* but it uses handles as keys, the same with StringTable.
//*
//* You can use Table on structs' onInit if the struct is
//* placed in a library that requires Table or outside a library.
//*
//* You can also do 2D array syntax if you want to touch
//* mission keys directly, however, since this is shared space
//* you may want to prefix your mission keys accordingly:
//*
//* set Table["thisstring"][ 7 ] = 2
//* set Table["thisstring"][ 5 ] = Table["thisstring"][7]
//*
//***************************************************************
//=============================================================
globals
private constant integer MAX_INSTANCES=8100 //400000
//Feel free to change max instances if necessary, it will only affect allocation
//speed which shouldn't matter that much.
//=========================================================
private hashtable ht
endglobals
private struct GTable[MAX_INSTANCES]
method reset takes nothing returns nothing
call FlushChildHashtable(ht, integer(this) )
endmethod
private method onDestroy takes nothing returns nothing
call this.reset()
endmethod
//=============================================================
// initialize it all.
//
private static method onInit takes nothing returns nothing
set ht = InitHashtable()
endmethod
endstruct
//Hey: Don't instanciate other people's textmacros that you are not supposed to, thanks.
//! textmacro Table__make takes name, type, key
struct $name$ extends GTable
method operator [] takes $type$ key returns integer
return LoadInteger(ht, integer(this), $key$)
endmethod
method operator []= takes $type$ key, integer value returns nothing
call SaveInteger(ht, integer(this) ,$key$, value)
endmethod
method flush takes $type$ key returns nothing
call RemoveSavedInteger(ht, integer(this), $key$)
endmethod
method exists takes $type$ key returns boolean
return HaveSavedInteger( ht, integer(this) ,$key$)
endmethod
static method flush2D takes string firstkey returns nothing
call $name$(- StringHash(firstkey)).reset()
endmethod
static method operator [] takes string firstkey returns $name$
return $name$(- StringHash(firstkey) )
endmethod
endstruct
//! endtextmacro
//! runtextmacro Table__make("Table","integer","key" )
//! runtextmacro Table__make("StringTable","string", "StringHash(key)" )
//! runtextmacro Table__make("HandleTable","handle","GetHandleId(key)" )
endlibrary
JASS:
library Table // made by Bribe, special thanks to Nestharus, version 3.0.0.0
/*
API
------------
struct Table
| static method create takes nothing returns Table
| create a new Table
|
| method destroy takes nothing returns nothing
| destroy it
|
| method flush takes nothing returns nothing
| flush all stored values inside of it
|
| method remove takes integer key returns nothing
| remove the value at index "key"
|
| method operator []= takes integer key, $TYPE$ value returns nothing
| assign "value" to index "key"
|
| method operator [] takes integer key returns $TYPE$
| load the value at index "key"
|
| method has takes integer key returns boolean
| whether or not the key was assigned
|
----------------
struct TableArray
| static method operator [] takes integer array_size returns TableArray
| create a new array of Tables of size "array_size"
|
| method destroy takes nothing returns nothing
| destroy it
|
| method flush takes nothing returns nothing
| flush and destroy it
|
| method operator size takes nothing returns integer
| returns the size of the TableArray
|
| method operator [] takes integer key returns Table
| returns a Table accessible exclusively to index "key"
*/
globals
private hashtable ht = InitHashtable() //The last hashtable you need
private integer more = 2 //Index generation for Tables (above 2)
private integer less = 0 //Index generation for TableArrays (below 0)
endglobals
private struct dex extends array
static method operator size takes nothing returns Table
return 1
endmethod
static method operator list takes nothing returns Table
return 2
endmethod
endstruct
private struct handles extends array
method has takes integer key returns boolean
return HaveSavedHandle(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSavedHandle(ht, this, key)
endmethod
endstruct
private struct agents extends array
method operator []= takes integer key, agent value returns nothing
call SaveAgentHandle(ht, this, key, value)
endmethod
endstruct
//! textmacro NEW_ARRAY_BASIC takes SUPER, FUNC, TYPE
private struct $TYPE$s extends array
method operator [] takes integer key returns $TYPE$
return Load$FUNC$(ht, this, key)
endmethod
method operator []= takes integer key, $TYPE$ value returns nothing
call Save$FUNC$(ht, this, key, value)
endmethod
method has takes integer key returns boolean
return HaveSaved$SUPER$(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSaved$SUPER$(ht, this, key)
endmethod
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//! textmacro NEW_ARRAY takes FUNC, TYPE
private struct $TYPE$s extends array
method operator [] takes integer key returns $TYPE$
return Load$FUNC$Handle(ht, this, key)
endmethod
method operator []= takes integer key, $TYPE$ value returns nothing
call Save$FUNC$Handle(ht, this, key, value)
endmethod
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//! runtextmacro NEW_ARRAY_BASIC("Real", "Real", "real")
//! runtextmacro NEW_ARRAY_BASIC("Boolean", "Boolean", "boolean")
//! runtextmacro NEW_ARRAY_BASIC("String", "Str", "string")
//! runtextmacro NEW_ARRAY("Player", "player")
//! runtextmacro NEW_ARRAY("Widget", "widget")
//! runtextmacro NEW_ARRAY("Destructable", "destructable")
//! runtextmacro NEW_ARRAY("Item", "item")
//! runtextmacro NEW_ARRAY("Unit", "unit")
//! runtextmacro NEW_ARRAY("Ability", "ability")
//! runtextmacro NEW_ARRAY("Timer", "timer")
//! runtextmacro NEW_ARRAY("Trigger", "trigger")
//! runtextmacro NEW_ARRAY("TriggerCondition", "triggercondition")
//! runtextmacro NEW_ARRAY("TriggerAction", "triggeraction")
//! runtextmacro NEW_ARRAY("TriggerEvent", "event")
//! runtextmacro NEW_ARRAY("Force", "force")
//! runtextmacro NEW_ARRAY("Group", "group")
//! runtextmacro NEW_ARRAY("Location", "location")
//! runtextmacro NEW_ARRAY("Rect", "rect")
//! runtextmacro NEW_ARRAY("BooleanExpr", "boolexpr")
//! runtextmacro NEW_ARRAY("Sound", "sound")
//! runtextmacro NEW_ARRAY("Effect", "effect")
//! runtextmacro NEW_ARRAY("UnitPool", "unitpool")
//! runtextmacro NEW_ARRAY("ItemPool", "itempool")
//! runtextmacro NEW_ARRAY("Quest", "quest")
//! runtextmacro NEW_ARRAY("QuestItem", "questitem")
//! runtextmacro NEW_ARRAY("DefeatCondition", "defeatcondition")
//! runtextmacro NEW_ARRAY("TimerDialog", "timerdialog")
//! runtextmacro NEW_ARRAY("Leaderboard", "leaderboard")
//! runtextmacro NEW_ARRAY("Multiboard", "multiboard")
//! runtextmacro NEW_ARRAY("MultiboardItem", "multiboarditem")
//! runtextmacro NEW_ARRAY("Trackable", "trackable")
//! runtextmacro NEW_ARRAY("Dialog", "dialog")
//! runtextmacro NEW_ARRAY("Button", "button")
//! runtextmacro NEW_ARRAY("TextTag", "texttag")
//! runtextmacro NEW_ARRAY("Lightning", "lightning")
//! runtextmacro NEW_ARRAY("Image", "image")
//! runtextmacro NEW_ARRAY("Ubersplat", "ubersplat")
//! runtextmacro NEW_ARRAY("Region", "region")
//! runtextmacro NEW_ARRAY("FogState", "fogstate")
//! runtextmacro NEW_ARRAY("FogModifier", "fogmodifier")
//! runtextmacro NEW_ARRAY("Hashtable", "hashtable")
struct Table extends array
// Implement modules for intuitive type-syntax
implement realm
implement booleanm
implement stringm
implement playerm
implement widgetm
implement destructablem
implement itemm
implement unitm
implement abilitym
implement timerm
implement triggerm
implement triggerconditionm
implement triggeractionm
implement eventm
implement forcem
implement groupm
implement locationm
implement rectm
implement boolexprm
implement soundm
implement effectm
implement unitpoolm
implement itempoolm
implement questm
implement questitemm
implement defeatconditionm
implement timerdialogm
implement leaderboardm
implement multiboardm
implement multiboarditemm
implement trackablem
implement dialogm
implement buttonm
implement texttagm
implement lightningm
implement imagem
implement ubersplatm
implement regionm
implement fogstatem
implement fogmodifierm
implement hashtablem
method operator handle takes nothing returns handles
return this
endmethod
method operator agent takes nothing returns agents
return this
endmethod
// set this = a[GetSpellAbilityId()]
method operator [] takes integer key returns Table
return LoadInteger(ht, this, key)
endmethod
// set a[389034] = 8192
method operator []= takes integer key, Table a returns nothing
call SaveInteger(ht, this, key, a)
endmethod
// set b = a.has(2493223)
method has takes integer key returns boolean
return HaveSavedInteger(ht, this, key)
endmethod
// call a.remove(294080)
method remove takes integer key returns nothing
call RemoveSavedInteger(ht, this, key)
endmethod
// Remove all data from a Table instance
method flush takes nothing returns nothing
call FlushChildHashtable(ht, this)
endmethod
// local Table a = Table.create()
static method create takes nothing returns Table
local Table this = dex.list[0]
if this == 0 then
set more = more + 1
set this = more
else
set dex.list[0] = dex.list[this]
call dex.list.remove(this)
endif
debug set dex.list[this] = -1
return this
endmethod
// Removes all data from a Table instance and recycles its index.
//
// call a.destroy()
//
method destroy takes nothing returns nothing
debug if dex.list[this] != -1 then
debug call BJDebugMsg("Table Error: Tried to double-free instance: " + I2S(this))
debug return
debug endif
call this.flush()
set dex.list[this] = dex.list[0]
set dex.list[0] = this
endmethod
endstruct
struct TableArray extends array
//Returns a new TableArray to do your bidding. Simply use:
//
// local TableArray ta = TableArray[array_size]
//
static method operator [] takes integer array_size returns TableArray
local Table a = dex.size[array_size] //Get the unique recycle list for this array size
local TableArray this = a[0] //The last-destroyed TableArray that had this array size
debug if array_size <= 0 then
debug call BJDebugMsg("TypeError: Invalid specified TableArray size: " + I2S(array_size))
debug return 0
debug endif
if this == 0 then
set less = less - array_size
set this = less
else
set a[0] = a[this] //Set the last destroyed to the last-last destroyed
call a.remove(this) //Clear hash memory
endif
set dex.size[this] = array_size //This remembers the array size
return this
endmethod
//Returns the size of the TableArray
method operator size takes nothing returns integer
return dex.size[this]
endmethod
//da[integer a].unit[integer b] = unit u
//da[integer a][integer c] = integer d
//
//Inline-friendly when not running in debug mode
//
method operator [] takes integer key returns Table
static if DEBUG_MODE then
local integer i = this.size
if i == 0 then
call BJDebugMsg("IndexError: Tried to get key from invalid TableArray instance: " + I2S(this))
return 0
elseif key < 0 or key >= i then
call BJDebugMsg("IndexError: Tried to get key [" + I2S(key) + "] from outside TableArray bounds: " + I2S(i))
return 0
endif
endif
return this + key
endmethod
//Destroys a TableArray without flushing it; assumed you'd call .flush()
//if you want it flushed too. This is public so that if you are flushing
//instances the whole time you don't waste efficiency when disposing the
//TableArray.
//
method destroy takes nothing returns nothing
local Table a = dex.size[this.size]
debug if this.size <= 0 then
debug call BJDebugMsg("TypeError: Tried to destroy an invalid TableArray: " + I2S(this))
debug return
debug endif
if a == 0 then
//Create an array to index recycled instances with their array size
set a = Table.create()
set dex.size[this.size] = a
endif
call dex.size.remove(this) //Clear the array size from hash memory
set a[this] = a[0]
set a[0] = this
endmethod
//All you need to know about this one is that it won't hit the op limit.
private static method clean takes Table a, integer end returns nothing
local integer i = a + 5000
if i < end then
call clean.evaluate(i, end)
set end = i
endif
loop
call a.flush()
set a = a + 1
exitwhen a == end
endloop
endmethod
//Flushes the TableArray and also destroys it. Doesn't get any more
//similar to the FlushParentHashtable native than this.
//
method flush takes nothing returns nothing
local integer end = this.size + this
debug if this == end then
debug call BJDebugMsg("TypeError: Tried to flush an invalid TableArray instance: " + I2S(this))
debug return
debug endif
call clean.evaluate(this, end)
call this.destroy()
endmethod
endstruct
endlibrary
So the question is: Is there a chance to replace the Table From SpellEvent with the table made by Bribe? (The one from SpellEffectEvent)
Thanks and sorry for my bad english
EDIT: I forgot to say that SpellEffectEvent is used in this ability
JASS:
library IllusoryOrb uses RegisterPlayerUnitEvent, SpellEffectEvent, Tt, WorldBounds
//===========================================================================
// CONFIGURABLES
//===========================================================================
globals
private constant integer ABIL_ID = 'A01Y' // raw code of ability "Illusory Orb"
private constant integer DUM_ABIL_ID = 'A01W' // raw code of ability "Ethereal Jaunt"
private constant integer DUMMY_ID = 'n001' // raw code of unit "Ilusory Orb Dummy"
private constant integer RED = 255 // red vertex color of DUMMY_ID
private constant integer GREEN = 255 // green vertex color of DUMMY_ID
private constant integer BLUE = 255 // blue vertex color of DUMMY_ID
private constant integer TRANS = 255 // transparency of DUMMY_ID, where 0 is fully transparent
private constant integer SCALE = 1 // scale size of DUMMY_ID
private constant real HEIGHT = 150. // height of DUMMY_ID
private constant real SPEED = 600. // distance travelled per second by orb
private constant real ENUM_RADIUS = 176. // max collision size of a unit in your map
private constant boolean PRELOAD = true // preloads resources if true
private constant attacktype ATK = ATTACK_TYPE_NORMAL // attack type
private constant damagetype DMG = DAMAGE_TYPE_MAGIC // damage type
endglobals
// area of effect
private constant function GetArea takes integer level returns real
return 300.0
endfunction
// damage dealt
private constant function GetDamage takes integer level returns real
return 70.0 * level
endfunction
// distance travelled by orb
private constant function GetDistance takes integer level returns real
return 600. + 150.0 * level
endfunction
// target types allowed for dealing damage
private constant function GetFilter takes unit caster, unit target returns boolean
return /*
*/ not IsUnitType(target, UNIT_TYPE_DEAD) and /* // target is alive
*/ IsUnitEnemy(target, GetOwningPlayer(caster)) and /* // target is an enemy of caster
*/ not IsUnitType(target, UNIT_TYPE_STRUCTURE) and /* // target is not a structure
*/ not IsUnitType(target, UNIT_TYPE_MECHANICAL) // target is not mechanic
endfunction
//===========================================================================
// END CONFIGURABLES
//===========================================================================
globals
private constant sound ERROR = CreateSoundFromLabel("InterfaceError", false, false, false, 10, 10)
private constant player NEUTRAL_PASSIVE = Player(PLAYER_NEUTRAL_PASSIVE)
private group G = bj_lastCreatedGroup
endglobals
private struct Main extends array
private group g
private unit u
private unit dummy
private real area
private real dmg
private real dist
private real sin
private real cos
private static integer array store
private static constant real TIMEOUT = 0.031250000
private static constant real TRUE_SPEED = SPEED * TIMEOUT
implement CTTC
local unit u
local real x
local real y
implement CTTCExpire
set x = GetUnitX(this.dummy) + this.cos
set y = GetUnitY(this.dummy) + this.sin
if x > WorldBounds.minX and y > WorldBounds.minY and x < WorldBounds.maxX and y < WorldBounds.maxY then
call SetUnitX(this.dummy, x)
call SetUnitY(this.dummy, y)
endif
set this.dist = this.dist - TRUE_SPEED
call GroupEnumUnitsInRange(G, x, y, this.area + ENUM_RADIUS, null)
loop
set u = FirstOfGroup(G)
exitwhen u == null
call GroupRemoveUnit(G, u)
if not IsUnitInGroup(u, this.g) and GetFilter(this.u, u) and IsUnitInRangeXY(u, x, y, this.area) then
call GroupAddUnit(this.g, u)
call UnitDamageTarget(this.u, u, this.dmg, true, false, ATK, DMG, null)
endif
endloop
if this.dist <= 0 then
if thistype.store[GetUnitUserData(this.u)] == this then
set thistype.store[GetUnitUserData(this.u)] = 0
endif
call GroupClear(this.g)
call DestroyGroup(this.g)
call KillUnit(this.dummy)
set this.g = null
call this.destroy()
endif
implement CTTCEnd
private static method onCast takes nothing returns boolean
local thistype this = thistype.create()
local integer level
local real a
set this.g = CreateGroup()
set this.u = GetTriggerUnit()
set a = Atan2(GetSpellTargetY() - GetUnitY(this.u), GetSpellTargetX() - GetUnitX(this.u))
set this.dummy = CreateUnit(NEUTRAL_PASSIVE, DUMMY_ID, GetUnitX(this.u), GetUnitY(this.u), a * bj_RADTODEG)
set level = GetUnitAbilityLevel(this.u, ABIL_ID)
set this.area = GetArea(level)
set this.dmg = GetDamage(level)
set this.dist = GetDistance(level)
set this.sin = TRUE_SPEED * Sin(a)
set this.cos = TRUE_SPEED * Cos(a)
set thistype.store[GetUnitUserData(this.u)] = this
call SetUnitVertexColor(this.dummy, RED, GREEN, BLUE, TRANS)
call SetUnitScale(this.dummy, SCALE, 0, 0)
call SetUnitFlyHeight(this.dummy, 100., 0)
return false
endmethod
private static method onDummyCast takes nothing returns boolean
local thistype this
if thistype.store[GetUnitUserData(GetTriggerUnit())] > 0 then
set this = thistype.store[GetUnitUserData(GetTriggerUnit())]
set thistype.store[GetUnitUserData(this.u)] = 0
call SetUnitX(this.u, GetUnitX(this.dummy))
call SetUnitY(this.u, GetUnitY(this.dummy))
call GroupClear(this.g)
call DestroyGroup(this.g)
call KillUnit(this.dummy)
set this.g = null
call this.destroy()
else
if GetLocalPlayer() == GetOwningPlayer(GetTriggerUnit()) then
call ClearTextMessages()
call StartSound(ERROR)
endif
call DisplayTimedTextToPlayer(GetOwningPlayer(GetTriggerUnit()), 0.52, -1., 2., "|cffffcc00No Illusory Orb found.|r")
endif
return false
endmethod
private static method onLearn takes nothing returns boolean
if GetLearnedSkill() == ABIL_ID and GetUnitAbilityLevel(GetTriggerUnit(), ABIL_ID) == 1 then
call UnitAddAbility(GetTriggerUnit(), DUM_ABIL_ID)
endif
return false
endmethod
private static method onInit takes nothing returns nothing
static if PRELOAD then
local unit u = CreateUnit(NEUTRAL_PASSIVE, DUMMY_ID, 0, 0, 0)
call UnitAddAbility(u, DUM_ABIL_ID)
call RemoveUnit(u)
set u = null
endif
call RegisterSpellEffectEvent(ABIL_ID, function thistype.onCast)
call RegisterSpellEffectEvent(DUM_ABIL_ID, function thistype.onDummyCast)
call RegisterPlayerUnitEvent(EVENT_PLAYER_HERO_SKILL, function thistype.onLearn)
endmethod
endstruct
endlibrary
and SpellEvent is used in this ability
JASS:
library Polarisation initializer Init needs TimerUtils, UnitStatus, SpellEvent
//*******************************************************************************************\\
//*******************************************************************************************\\
//* Polarisation By Inferior *\\
//* *\\
//* v1.0 *\\
//* *\\
//* ************************* *\\
//* * Requirements: * *\\
//* * - JassNewGenPack * *\\
//* * - TimerUtils * *\\
//* * - UnitStatus * *\\
//* * - SpellEvent * *\\
//* ************************* *\\
//* *\\
//* *\\
//* *\\
//* How To Import: *\\
//* - Copy the Spell called 'Polarisation' into your map *\\
//* - Copy the whole Triggerscript into your map *\\
//* - Now change the values of the 'ABILID' to the Rawcode of the Mainability in your map *\\
//* *\\
//* Spelldescription: *\\
//* The Caster creates a static link between the target and himself absorbing the *\\
//* Targets life and converting it to Mana. The Target and the caster are pulled *\\
//* to the middle between their positions, while the target is disabled. The Health is *\\
//* absorbed during the pullphase. After they reached each other the Caster keeps up the *\\
//* static link between him and the target. The target is now unable to move farther *\\
//* away than the link allows him. *\\
//* *\\
//*******************************************************************************************\\
//*******************************************************************************************\\
// Globals Setting
globals
private constant integer ABILID = 'A00H'
// The AbilityId of your Mainability
private constant string LIGHTNING = "CHIM"
// The Lightning Effect of the static link
private constant real DEFAULTHEIGHT = 50.
// The Height of the Lightning
private constant real DEFAULTDIST = 150.
// The Minimum Distance which has to be reached until the Pullphase is stopped
private constant real HEALTHTOMANA = 0.4
// The absorbed Health to Mana Factor
private constant real PULLPERIOD = 0.025
// The Timer Period of this Spell
// The 3 following variables are just important for the damage dealt in this spell
private constant attacktype ATKTYPE = ATTACK_TYPE_NORMAL
private constant damagetype DMGTYPE = DAMAGE_TYPE_UNIVERSAL
private constant weapontype WPNTYPE = WEAPON_TYPE_WHOKNOWS
private constant boolean PULLDOWNAIR = true
// Set this to true weather Air units shall be pulled down to the ground.
private constant boolean CASTERACTION = true
// Set this to false weather the caster should be disabled aswell duration the Pullphase
// For Descriptions for the following Variables see below
private real array PULLDURATION
private real array FIXDURATION
private real array MAXRANGE
private real array DAMAGEDEALT
endglobals
private function SetupSpellVariables takes nothing returns nothing
// The time in which the target is pulled in the direction of the caster
set PULLDURATION[1]=1.25
set PULLDURATION[2]=1.75
set PULLDURATION[3]=2.25
set PULLDURATION[4]=3.
// The time how long the target is fixed to the caster by the static link
set FIXDURATION[1]=1.5
set FIXDURATION[2]=2.
set FIXDURATION[3]=2.5
set FIXDURATION[4]=3.
// The Maximum range the target can move away from the caster with the static link
set MAXRANGE[1]=600.
set MAXRANGE[2]=500.
set MAXRANGE[3]=400.
set MAXRANGE[4]=300.
// The Damage dealt during the Pullphase
set DAMAGEDEALT[1]=60.
set DAMAGEDEALT[2]=125.
set DAMAGEDEALT[3]=185.
set DAMAGEDEALT[4]=250.
endfunction
// DO NOT TOUCH ANYTHING BELOW THIS COMMENT, ALTHOUGH YOU KNOW WHAT YOU DO.
// HERE BEGINS THE SPELLS SCRIPT.
private struct MagnetPull
unit caster
unit target
real castX
real castY
real targX
real targY
real duration
integer level
lightning light
static integer count=0
static timer MagnetTimer
static MagnetPull array Data
static boolean array done
// checks if the target is to far away from the caster
// stops the spell when the static link time expires
static method callback takes nothing returns nothing
local integer int=0
local MagnetPull data
local real dx
local real dy
loop
exitwhen int==.count
set data=.Data[int]
if data.duration>0 and not .done[int] and GetWidgetLife(data.target)>0.405 then
set dx=data.castX-data.targX
set dy=data.castY-data.targY
if SquareRoot(dx*dx+dy*dy)>MAXRANGE[data.level] then
set data.targX=data.castX-MAXRANGE[data.level]*Cos(Atan2(dy,dx))
set data.targY=data.castY-MAXRANGE[data.level]*Sin(Atan2(dy,dx))
call SetUnitX(data.target,data.targX)
call SetUnitY(data.target,data.targY)
else
set data.targX=GetUnitX(data.target)
set data.targY=GetUnitY(data.target)
endif
set data.castX=GetUnitX(data.caster)
set data.castY=GetUnitY(data.caster)
set data.duration=data.duration-PULLPERIOD
call MoveLightningEx(data.light,true,data.castX,data.castY,DEFAULTHEIGHT,data.targX,data.targY,DEFAULTHEIGHT)
elseif data.light!=null and not .done[int] or GetWidgetLife(data.target)<0.405 and not .done[int] then
call DestroyLightning(data.light)
if PULLDOWNAIR and IsUnitType(data.target,UNIT_TYPE_FLYING) then
call SetUnitFlyHeight(data.target,GetUnitDefaultFlyHeight(data.target),100)
endif
set .done[int]=true
call data.destroy()
endif
set int=int+1
endloop
endmethod
static method create takes nothing returns MagnetPull
local MagnetPull data=MagnetPull.allocate()
if .count==0 then
set .MagnetTimer=NewTimer()
call TimerStart(.MagnetTimer,PULLPERIOD,true,function MagnetPull.callback)
endif
set .Data[.count]=data
set .count=.count+1
return data
endmethod
endstruct
private struct PolarPull
unit caster
unit target
real castX
real castY
real targX
real targY
real velZ
real angle
real distance
real speed
integer level
lightning light
static integer count=0
static timer PullTimer
static PolarPull array Data
static boolean array done
// pulls the target and the caster to they position between each other
// Flying Units are pulled down if PULLDOWNAIR=true
// When the Pullphase is over Flying units regain their default height
static method callback takes nothing returns nothing
local integer int=0
local PolarPull data
local MagnetPull dat
loop
exitwhen int==.count
set data=.Data[int]
if data.distance>DEFAULTDIST and not .done[int] and GetWidgetLife(data.target)>0.405 then
set data.castX=data.castX-data.speed*Cos(data.angle)
set data.castY=data.castY-data.speed*Sin(data.angle)
call SetUnitX(data.caster,data.castX)
call SetUnitY(data.caster,data.castY)
set data.targX=data.targX+data.speed*Cos(data.angle)
set data.targY=data.targY+data.speed*Sin(data.angle)
call SetUnitX(data.target,data.targX)
call SetUnitY(data.target,data.targY)
call UnitDamageTarget(data.caster,data.target,(DAMAGEDEALT[data.level]/PULLDURATION[data.level])*PULLPERIOD,true,false,ATKTYPE,DMGTYPE,WPNTYPE)
call SetUnitState(data.caster,UNIT_STATE_MANA,GetUnitState(data.caster,UNIT_STATE_MANA)+(DAMAGEDEALT[data.level]*HEALTHTOMANA/PULLDURATION[data.level])*PULLPERIOD)
if PULLDOWNAIR and IsUnitType(data.target,UNIT_TYPE_FLYING) then
call SetUnitFlyHeight(data.target,GetUnitFlyHeight(data.target)-data.velZ,0)
call MoveLightningEx(data.light,true,data.castX,data.castY,DEFAULTHEIGHT,data.targX,data.targY,GetUnitFlyHeight(data.target)+DEFAULTHEIGHT)
else
call MoveLightningEx(data.light,true,data.castX,data.castY,DEFAULTHEIGHT,data.targX,data.targY,DEFAULTHEIGHT)
endif
set data.distance=data.distance-2*data.speed
elseif data.distance<=DEFAULTDIST and not .done[int] and GetWidgetLife(data.target)>0.405 then
set dat=MagnetPull.create()
set dat.caster=data.caster
set dat.target=data.target
set dat.castX=data.castX
set dat.castY=data.castY
set dat.targX=data.targX
set dat.targY=data.targY
set dat.light=data.light
set dat.level=data.level
set dat.duration=FIXDURATION[data.level]
if not CASTERACTION then
call DisableUnit(data.caster,false)
endif
call DisableUnit(data.target,false)
set .done[int]=true
call data.destroy()
elseif GetWidgetLife(data.target)<0.405 and not .done[int] then
call DestroyLightning(data.light)
if not CASTERACTION then
call DisableUnit(data.caster,false)
endif
call DisableUnit(data.target,false)
set .done[int]=true
call data.destroy()
endif
set int=int+1
endloop
endmethod
static method create takes nothing returns PolarPull
local PolarPull data=PolarPull.allocate()
if .count==0 then
set .PullTimer=NewTimer()
call TimerStart(.PullTimer,PULLPERIOD,true,function PolarPull.callback)
endif
set .Data[.count]=data
set .count=.count+1
return data
endmethod
endstruct
// Executed on Spellcast
// Disables the caster when CASTERACTION=false
private function PolarisationSpell takes nothing returns nothing
local unit caster=SpellEvent.CastingUnit
local unit target=SpellEvent.TargetUnit
local PolarPull data=PolarPull.create()
local real dx=0.
local real dy=0.
set data.caster=caster
set data.target=target
set data.castX=GetUnitX(caster)
set data.castY=GetUnitY(caster)
set data.targX=GetUnitX(target)
set data.targY=GetUnitY(target)
set dx=data.castX-data.targX
set dy=data.castY-data.targY
set data.angle=Atan2(dy,dx)
set data.distance=SquareRoot(dx*dx+dy*dy)
set data.level=GetUnitAbilityLevel(caster,ABILID)
set data.speed=(data.distance/PULLDURATION[data.level])*PULLPERIOD*0.5
call DisableUnit(data.target,true)
if not CASTERACTION then
call DisableUnit(data.caster,true)
endif
call SetUnitAnimation(data.caster,"spell channel")
if PULLDOWNAIR and IsUnitType(target,UNIT_TYPE_FLYING) then
set data.velZ=(GetUnitFlyHeight(target)/PULLDURATION[data.level])*PULLPERIOD
set data.light=AddLightningEx(LIGHTNING,true,data.castX,data.castY,DEFAULTHEIGHT,data.targX,data.targY,GetUnitFlyHeight(target)+DEFAULTHEIGHT)
else
set data.light=AddLightningEx(LIGHTNING,true,data.castX,data.castY,DEFAULTHEIGHT,data.targX,data.targY,DEFAULTHEIGHT)
set data.velZ=0
endif
set caster=null
set target=null
endfunction
private function Init takes nothing returns nothing
call RegisterSpellEffectResponse(ABILID,PolarisationSpell)
call SetupSpellVariables()
endfunction
endlibrary