1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Dismiss Notice
  3. After a long wait, the results for Terraining Contest #18 are finally out! Drop by and congratulate the winners!
    Dismiss Notice
  4. The poll for Concept Art Contest #9 is up! Cast your vote for your favourite entry!
    Dismiss Notice
  5. Hero Contest #8 is up and running! This time it's a joint contest between artists and coders. Go here for team matchmaking.
    Dismiss Notice
  6. Our first StarCraft contest, The Galaxy Terraining Contest #1 - World Wonders has started. Enter to show off your Galaxy Editor skills and win a custom rank icon among other things.
    Dismiss Notice
  7. Ever wanted to get your sets ready for fast texturing while still having fun? Now it is possible with our newest Mini-Texturing Contest.
    The Skeleton Units need your dire help!
    Dismiss Notice
  8. The poll for Techtree Contest #11 is up! Cast your vote for your favorite entry.
    Dismiss Notice

Orb Stacking 1.8.1

Submitted by Deaod
A library to ease stacking orbs. And to add limitations to stacking orbs.

This uses vJass, DamageEvent, DamageModifiers, AutoIndex, Table and optionally GroupUtils.

In-Game commands
-reset: Spawns some footmen around you.
-level <level>: Sets the level of your hero to the specified level. Note that you cannot decrease your hero's level this way.
-handleid: Creates a location, displays its index - 0x1000001 and destroys it.
-commands: Shows this list.
-credits: Shows the credits.
-clear: Clears all text-messages.


Changelog
13/04/2009 - Version 1.0.0
- initial release

13/04/2009 - Version 1.0.1
- made removing the buff optional and moved it to the top to prevent recursion

16/04/2009 - Version 1.1.0
- changed internal handling of Item Orbs to Table for a performance gain
- each Orb now has a chance to be run. Refer to the manual for more information

16/04/2009 - Version 1.2.0
- added Category Types (if you have a more logical naming for those types, let me know)
- as a result of that, .AddToCategory()'s interface was changed.

23/04/2009 - Version 1.3.0
- each Category now has an execution limit, which can be adjusted
- backwards compatible

29/04/2009 - Version 1.3.1
- forgot to initialize the string table in the Category struct
- deleted irritating debug messages

29/04/2009 - Version 1.4.0
- reworked the way randomness is handled. 1.4.0 uses Ammorth's ChanceToProc library for that. Due to the severe performance impact i decided to keep 1.3.1 for those who are comfortable with the "spikes" the old way imposes on the chances

08/05/2009 - Version 1.5.0
- reworked the way randomness is handled (again). Removed the chance calculation on my side. The user decides whether the orb was applied or not with his own calculations
- as a result, the function interface was changed. You now have to return a boolean. For compatibility, use the constants provided by this library

22/05/2009 - Version 1.5.1
- deleted the superfluous H2I function
- minor other changes.

07/08/2009 - Version 1.5.2
- Compatibility with 1.24

06/11/2009 - Version 1.5.3
- fixed a few bugs by changing the ability the Generic Orb is based upon.
- Simplified implementation of the library and added a note that you have to add an ability to all units you want to have custom orbs.

06/02/2010 - Version 1.6.0
- Heavily optimized code run when a unit takes damage
- Made LightLeaklessDamageDetect exchangeable with IDDS by implementing an abstraction layer.

10/02/2010 - Version 1.6.1
- dramatically simplified importing this library. Now, you only need to copy over the code, everything else gets done automatically.
- removed the requirement of LightLeaklessDamageDetect, you can still use it, but its not required anymore.
- fixed Orbs for preplaced units.
- fixed destroying Orbs.
- clarified a few things in the documentation.

14/02/2010 - Version 1.6.2
- more bugfixes. Skilling the same ability multiple times no longer creates multiple UnitOrb instances.
- now supports adding Orbs via GUI.

15/02/2010 - Version 1.7.0
- breaks backwards compatibility in order to implement stacking priority. Orbs with higher priority get executed first. Only the interface of Orb.Create was changed.
- Allows changing the damage dealt to the damaged unit with the SetDamage(real new) function.

21/05/2010 - Version 1.8.0
- breaks backwards compatibility again. Ill get into that separately as basically the whole API changed. My aim was to reduce possibility of collision of names (eg. Category was far too general a name for a struct in a public library) (and i wanted to correct past mistakes).
- added missile modificators. Orbs can now change the missile a unit attacks with. Note that it doesnt take the target unit of an attack into account for speed reasons.

New API:
ABILITY_TYPE_SKILL --> ORB_TYPE_SKILL
ABILITY_TYPE_ITEM --> ORB_TYPE_ITEM
CATEGORY_TYPE_READ --> ORB_CATEGORY_TYPE_READ
CATEGORY_TYPE_WRITE --> ORB_CATEGORY_TYPE_WRITE
CATEGORY_TYPE_READWRITE --> ORB_CATEGORY_TYPE_READWRITE
Category --> OrbCategory
Orb_Callback --> OrbCallback
All members of publicly available structs now start with a lower-case-letter.

15/06/2010 - Version 1.8.1
- fixed OrbStacking for unit upgrading.
- did a few optimizations.
- added a few lines warning about using other orbs combined with this library (it just wont work the way you want it to).


[jass=Script Code]// *************************************************************
// * OrbStacking -- Version 1.8.1
// * by Deaod
// *************************************************************
// *
// * CREDITS:
// * - Anitarf (DamageEvent, DamageModifiers)
// * - grim001 (AutoIndex)
// * - Rising_Dusk (GroupUtils)
// * - Vexorian (JassHelper, Table)
// * - MindWorX and PitzerMike (JassNewGenPack)
// * - Pipedream (Grimoire)
// * - SFilip (TESH)
// *
// * HOW TO IMPORT:
// * * Copy over this library and save. Its that easy.
// *
// * HOW TO USE:
// * * use Orb.create(integer AID, integer Method, integer Priority, OrbCallback Func)
// * to create a new Orb.
// * - AID is the ID of the ability representing the orb
// * (in the case of an item representing the orb, pass
// * the rawcode of the item)
// * - Method is the type of ability triggerin the orb
// * (either ORB_TYPE_SKILL, if the ability is a
// * skill, or ORB_TYPE_ITEM, if an item triggers
// * the orb)
// * - Priority is the priority of the orb. When stacking
// * different orbs on the same unit, the orb with the
// * highest priority will get executed first.
// * If a unit has two orbs of equal priority, the one
// * acquired first will be executed first.
// * - Func is the function being run when the orb is
// * triggered. It has to follow the OrbCallback
// * interface defined below. A function following that
// * interface has to return a boolean, either
// * ORB_APPLIED or ORB_NOT_APPLIED.
// * If you return ORB_APPLIED, all Categories of type
// * WRITE will be written (their execution-count will
// * be increased)
// *
// * * add that Orb to a category using YourOrb.addToCategory(string Label, integer Type)
// * - Label is the label of the category you want to
// * add that orb to.
// * Every Orb can belong to up to MAX_CATEGORIES
// * categories
// * - Type defines the behaviour of the orb.
// * ORB_CATEGORY_TYPE_READ makes the orb only "read" from
// * the Category. That means it only checks whether
// * that category has been written in any orb before.
// * ORB_CATEGORY_TYPE_WRITE makes the orb only "write" to
// * the Category. That means it only marks the Category
// * as executed but does not depend on the Category not
// * being executed before.
// * ORB_CATEGORY_TYPE_READWRITE combines READ and WRITE.
// * That means, the orb will not be executed, if the
// * Category has been executed before and it will mark
// * the Category as executed when the orb is triggered
// *
// * * each Category has an execution limit and cant be executed
// * more often than that limit. You can change that limit
// * using this: set OrbCategory[label].execLimit=some_new_limit
// * - label is the label of the Category which's execution
// * limit you want to change
// *
// * * you can add a missile modifier to each Orb by using
// * YourOrb.setMissileModifier(integer Ability)
// * - Ability is the rawcode of an ability that places BID
// * on the attacked unit and modifies the missile.
// * You should base this ability off of AIcb for optimum
// * performance.
// * If a unit has an orb with a missile modifier, that
// * modifier gets used. If the unit has more than one, the
// * one of the orb with highest priority gets used.
// * Missile modifiers currently dont get added to units already
// * having the ability/item for the orb when the orb is created
// * in the code. Though i dont think this will ever be an issue
// * please tell me if you run into a situation where it is.
// * Note that you wont be able to change the missile if the
// * dummy ability isnt able to change the missile under the
// * given circumstances.
// *
// * * GetDamagingUnit(), GetDamagedUnit() and GetDamage() can be
// * used to access GetEventDamageSource(), GetTriggerUnit()
// * and GetEventDamage() inside OrbCallback functions
// * executed by this script
// *
// * * if you want to prevent damage or deal additional damage
// * through orbs, use the SetDamage(real new) function.
// * Pass the new amount of damage that attack should deal.
// * Using it outside Orb Callbacks wont have any effect.
// *
// * * by default, all units that get indexed by AutoIndex upon
// * entering the map, automatically get the dummy ability for
// * OrbStacking. If there are specific types you want to
// * exclude from acquiring orbs, filter them out using the
// * UnitFilter function right below the first globals block.
// * If you add the dummy ability to a unit, that unit wont
// * be able to use other orbs anymore. They also should not
// * be able to attack ground as that can cause crashes.
// *
// *************************************************************
library OrbStacking uses Table, DamageEvent, DamageModifiers, AutoIndex, optional GroupUtils

// these are the objects required for this library to function
// you can deactivate these after saving and immediately reopening the map (by removing the ! or adding a / in the front).
//! external ObjectMerger w3a AIcb AOrb anam "Generic Orb" aart "" arac "0" amat "" asat "" aspt "" atat "" ata0 "" Iarp 1 0 Idic 1 0 Iob5 1 0 abuf 1 "BORB" ahdu 1 "0.01" adur 1 "0.01" aite "0"
//! external ObjectMerger w3h Bfro BORB fnam "Proxy Orb" ftat "" ftip "Proxy Orb" fube ""

globals
constant key ORB_TYPE_SKILL //
constant key ORB_TYPE_ITEM //

constant key ORB_CATEGORY_TYPE_READ // categories of this type for the orb must not have been written before
constant key ORB_CATEGORY_TYPE_WRITE // whenever an orb belonging to this type of category is triggered that category becomes unusable
constant key ORB_CATEGORY_TYPE_READWRITE // combines READ and WRITE

constant boolean ORB_APPLIED = true
constant boolean ORB_NOT_APPLIED = false

private constant integer AID = 'AOrb' // Based off of AIcb, places BID on attacked unit.
private constant integer BID = 'BORB' // the buff placed by the dummy orb ability // based on Orb of Corruption
private constant integer MAX_CATEGORIES = 5 // the maximum categories an orb can belong to
private constant integer DEFAULT_CATEGORY_EXEC_LIMIT = 1 // the default execution limit of a newly created OrbCategory
private constant boolean REMOVE_BUFF_BEFORE = true // change to false, if you need the buff in one of your callbacks
private constant integer ORB_PRIORITY = 0x7FFFFFFF // highest possible value, meaning all orbs will get executed before any other damage modifiers get a chance
endglobals

// If theres any specific unit-type you want to exclude from using Orbs at all, filter it out here.
// Note that AutoIndex already filters out xe's dummies, and that units not indexed by AutoIndex wont be able to use Orbs
private function UnitFilter takes unit u returns boolean
return true
endfunction

// Dont touch it, its just here for you to see
function interface OrbCallback takes nothing returns boolean

// Dont touch anything below.

globals
private unit Damaging
private unit Damaged
private real Damage
endglobals

struct OrbCategory
private integer execlimit

private static StringTable CategoryTable

method operator execLimit takes nothing returns integer
return execlimit
endmethod

method operator execLimit= takes integer new returns nothing
debug if new<=0 then
debug call BJDebugMsg("OrbCategory: New execution limit too low!")
debug return
debug endif
set execlimit=new
endmethod

private static method Create takes string label returns thistype
local thistype s=allocate()
set s.execLimit=DEFAULT_CATEGORY_EXEC_LIMIT
set CategoryTable[label]=s
return s
endmethod

static method create takes string label returns thistype
if CategoryTable.exists(label) then
return CategoryTable[label]
else
return Create(label)
endif
endmethod

static method operator [] takes string label returns thistype // a cleaner wrapper
return create(label)
endmethod

private method destroy takes nothing returns nothing
// i hope this prevents idiots from destroying a Category
endmethod

private static method onInit takes nothing returns nothing
set OrbCategory.CategoryTable=StringTable.create()
endmethod
endstruct

private keyword UnitOrb
// the following are terrible hacks to create library-private struct members
private keyword aid
private keyword Method
private keyword Cat
private keyword CatType
private keyword CatCnt
private keyword cb
private keyword Priority
private keyword MissileModAbil

private struct OrbUnit extends DamageModifier
private unit self
private integer id
readonly UnitOrb missileMod

private static integer array OrbCount
private static thistype array UnitInstance

method destroy takes nothing returns nothing
set OrbCount[id]=OrbCount[id]-1
if OrbCount[id]==0 then
set self=null
set UnitInstance[id]=0
call deallocate()
endif
endmethod

method newMissileMod takes UnitOrb newmod returns nothing
call UnitRemoveAbility(self, missileMod.orb.MissileModAbil)
call UnitAddAbility(self, newmod.orb.MissileModAbil)
set missileMod=newmod
endmethod

method resetMissileMod takes nothing returns nothing
call UnitRemoveAbility(self, missileMod.orb.MissileModAbil)
call UnitAddAbility(self, AID)
set missileMod=UnitOrb[self]
endmethod

private method onDamageDealt takes unit target, real damage returns real
local integer i
local Orb s
local integer array b // counts the execution of each category
local boolean t
local UnitOrb o
if GetUnitAbilityLevel(target, BID)<=0 then
// not triggered by an attack.
return 0.
endif
static if REMOVE_BUFF_BEFORE then
call UnitRemoveAbility(target, BID)
endif
set Damaging=self
set Damaged=target
set Damage=damage
set o=UnitOrb[self]
loop
exitwhen o==0
set s=o.orb
set i=0
set t=true
loop
exitwhen i>=s.CatCnt
// lets see if were allowed to trigger the Orb
if (s.CatType==ORB_CATEGORY_TYPE_READ or s.CatType==ORB_CATEGORY_TYPE_READWRITE) and b[s.Cat]>=s.Cat.execLimit then
set t=false // we arent
exitwhen true
endif
set i=i+1
endloop
if t and s.cb.evaluate()==ORB_APPLIED then // additionally check if the Orb actually triggered (for chance based Orbs)
set i=0
loop
exitwhen i>=s.CatCnt
// now, lets mark the categories as execute once more
if s.CatType==ORB_CATEGORY_TYPE_WRITE or s.CatType==ORB_CATEGORY_TYPE_READWRITE then
set b[s.Cat]=b[s.Cat]+1
endif
set i=i+1
endloop
endif
set o=o[o.index+1] // and loop through the Orbs of the unit
endloop
return Damage-damage // return newdamage-olddamage
endmethod

static method create takes unit u returns thistype
local integer id=GetUnitId(u)
if UnitInstance[id]==0 then
set UnitInstance[id]=allocate(u, ORB_PRIORITY)
set UnitInstance[id].id=id
set UnitInstance[id].self=u
set UnitInstance[id].missileMod=AID
endif
set OrbCount[id]=OrbCount[id]+1
return UnitInstance[id]
endmethod
endstruct

private struct UnitOrb
Orb orb
OrbUnit orbunit

implement AutoDestroy

static method clear takes unit u returns nothing
local thistype o
local thistype p
set o=UnitOrb
loop
exitwhen o==0
set p=o[o.index+1]
call o.destroy()
set o=p
endloop
endmethod

private method onDestroy takes nothing returns nothing
local thistype o
if orbunit.missileMod==this then
set o=o[o.index+1] // start with the next orb in line
loop
exitwhen o==0
if o.orb.MissileModAbil!=AID then
call o.orbunit.newMissileMod(o)
endif
set o=o[o.index+1]
endloop
if o.orbunit.missileMod==this then
call o.orbunit.resetMissileMod()
endif
endif
call orbunit.destroy()
endmethod

static method create takes unit u, Orb orb returns thistype
local thistype s=allocate()
local thistype o
local boolean b // theres a missile modifier with higher priority or the orb does not have a missile modifier.
set s.orb=orb
set s.orbunit=OrbUnit.create(u)
set o=UnitOrb
set b=s.orb.MissileModAbil==AID
// search the right place to insert
loop
exitwhen o==0 or o.orb.Priority<orb.Priority
if not b and o.orb.MissileModAbil!=AID then
set b=true
endif
set o=o[o.index+1]
endloop
set s.me=u // insert at end
if not b then
// apply new Missile Modifier
call s.orbunit.newMissileMod(s)
endif
loop // shift instances moving new instance to the right place
exitwhen o==0
set o.me=u
set o=o[o.index+1]
endloop
return s
endmethod
endstruct

struct Orb
integer aid
integer Method
OrbCategory array Cat[MAX_CATEGORIES]
integer array CatType[MAX_CATEGORIES]
integer CatCnt=0
OrbCallback cb
integer Priority=0
integer MissileModAbil=AID

private integer i

private static thistype array Structs
private static integer Count=0

private static Table OrbTable

private static rect WorldRect
private static group InitGroup
private static thistype TempOrb

private static method OnDestroyCheck takes nothing returns boolean
local UnitOrb o
local UnitOrb next

set o=UnitOrb[GetFilterUnit()]
loop
exitwhen o<=0
if o.orb==TempOrb then
set next=o[o.index+1]
call o.destroy()
set o=next
else
set o=o[o.index+1]
endif
endloop

return false
endmethod

method onDestroy takes nothing returns nothing
set TempOrb=this
static if LIBRARY_GroupUtils then
call GroupEnumUnitsInRect(ENUM_GROUP, WorldRect, function thistype.OnDestroyCheck)
else
call GroupEnumUnitsInRect(InitGroup, WorldRect, function thistype.OnDestroyCheck)
endif
if Method==ORB_TYPE_SKILL then
set Count=Count-1
set Structs=Structs[Count]
set Structs.i=i
endif
call OrbTable.flush(.aid)
endmethod

private static method OnCreateCheck takes nothing returns boolean
local unit u=GetFilterUnit()
if UnitFilter(u) then
if TempOrb.Method==ORB_TYPE_SKILL and GetUnitAbilityLevel(u, TempOrb.aid)>0 then
call UnitOrb.create(u, TempOrb)
elseif TempOrb.Method==ORB_TYPE_ITEM and UnitHasItemOfTypeBJ(u, TempOrb.aid) then
call UnitOrb.create(u, TempOrb)
endif
endif
set u=null
return false
endmethod

static method create takes integer AID, integer Method, integer Priority, OrbCallback Func returns Orb
local thistype s=allocate()
set s.aid=AID
set s.cb=Func
if Method==ORB_TYPE_SKILL then
set Structs[Count]=s
set s.i=Count
set Count=Count+1
endif
set s.Method=Method
set s.Priority=Priority
set OrbTable[AID]=s
set TempOrb=s
static if LIBRARY_GroupUtils then
call GroupEnumUnitsInRect(ENUM_GROUP, WorldRect, function thistype.OnCreateCheck)
else
call GroupEnumUnitsInRect(InitGroup, WorldRect, function thistype.OnCreateCheck)
endif
return s
endmethod

method addToCategory takes string Label, integer Type returns nothing
debug if CatCnt>=MAX_CATEGORIES or Label=="" or Label==null or (Type!=ORB_CATEGORY_TYPE_READ and Type!=ORB_CATEGORY_TYPE_WRITE and Type!=ORB_CATEGORY_TYPE_READWRITE) then
debug call BJDebugMsg("OrbStacking: Can't add Orb["+I2S(this)+"] to another OrbCategory (wrong label, invalid type, or maximum categories exceeded)!")
debug return
debug endif
set Cat[CatCnt]=OrbCategory.create(Label)
set CatType[CatCnt]=Type
set CatCnt=CatCnt+1
endmethod

method setMissileModifier takes integer Ability returns nothing
set MissileModAbil=Ability
endmethod

private static method UnitCreated takes unit u returns nothing
local integer i=Orb.Count-1
local thistype s
if UnitFilter(u) then
call UnitAddAbility(u, AID)

loop
exitwhen i<0
set s=Structs
if GetUnitAbilityLevel(u, s.aid)>0 then
call UnitOrb.create(u, s)
endif
set i=i-1
endloop
endif
endmethod

private static method OnUpgrade takes nothing returns nothing
local unit u=GetTriggerUnit()
call UnitOrb.clear(u)
call UnitCreated(u)
set u=null
endmethod

private static method OnSkill takes nothing returns nothing
local thistype s=OrbTable[GetLearnedSkill()]
local UnitOrb o
if UnitFilter(GetTriggerUnit()) and s>0 and GetLearnedSkillLevel()==1 then
set o=UnitOrb.create(GetTriggerUnit(), s)
endif
endmethod

private static method OnItemPickup takes nothing returns nothing
local thistype s=OrbTable[GetItemTypeId(GetManipulatedItem())]
local UnitOrb o
if UnitFilter(GetTriggerUnit()) and s>0 then
set o=UnitOrb.create(GetTriggerUnit(), s)
endif
endmethod

private static method OnItemDrop takes nothing returns nothing
local thistype s=OrbTable[GetItemTypeId(GetManipulatedItem())]
local UnitOrb o
if s>0 then
set o=UnitOrb[GetTriggerUnit()]
loop
exitwhen o<=0
if o.orb==s then
call o.destroy()
return
endif
set o=o[o.index+1]
endloop
endif
endmethod

private static method OnUnitAddAbility takes unit u, integer aid returns nothing
local thistype s=OrbTable[aid]
local UnitOrb o
if UnitFilter(u) and s>0 and GetUnitAbilityLevel(u, aid)<=0 then
set o=UnitOrb.create(u, s)
endif
endmethod

private static method OnUnitAddAbilityBJ takes integer aid, unit u returns nothing
call OnUnitAddAbility(u, aid)
endmethod

private static method OnUnitRemoveAbility takes unit u, integer aid returns nothing
local thistype s=OrbTable[aid]
local UnitOrb o
if s>0 and GetUnitAbilityLevel(u, aid)>0 then
set o=UnitOrb
loop
exitwhen o<=0
if o.orb==s then
call o.destroy()
return
endif
set o=o[o.index+1]
endloop
endif
endmethod

private static method OnUnitRemoveAbilityBJ takes integer aid, unit u returns nothing
call OnUnitRemoveAbility(u, aid)
endmethod

private static method onInit takes nothing returns nothing
local trigger t
// Listener for units entering the map
call OnUnitIndexed(UnitCreated)
// Listener for upgrading a unit
set t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_UPGRADE_FINISH)
call TriggerAddAction(t, function thistype.OnUpgrade)
// Listener for learning an ability
set t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_SKILL)
call TriggerAddAction(t, function thistype.OnSkill)
// Listener for picking up and item
set t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_PICKUP_ITEM)
call TriggerAddAction(t, function thistype.OnItemPickup)
// Listener for dropping an item
set t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DROP_ITEM)
call TriggerAddAction(t, function thistype.OnItemDrop)

set OrbTable=Table.create()

set WorldRect=GetWorldBounds() // sadly, you cant initialize rects using this function inside the globals block, unless you want the game to crash
static if not LIBRARY_GroupUtils then
set InitGroup=CreateGroup() // only initialize if necessary.
endif
endmethod
endstruct

hook UnitAddAbility Orb.OnUnitAddAbility
hook UnitAddAbilityBJ Orb.OnUnitAddAbilityBJ
hook UnitRemoveAbility Orb.OnUnitRemoveAbility
hook UnitRemoveAbilityBJ Orb.OnUnitRemoveAbilityBJ
hook UnitRemoveBuffBJ Orb.OnUnitRemoveAbilityBJ

function GetDamagingUnit takes nothing returns unit
return Damaging
endfunction

function GetDamagedUnit takes nothing returns unit
return Damaged
endfunction

function GetDamage takes nothing returns real
return Damage
endfunction

function SetDamage takes real new returns nothing
set Damage=new
endfunction

endlibrary
[/jass]

I additionally attached a map with two samples.
Contents

Orb Stacking 1.8.0 (Map)

  1. 20:56, 4th Jun 2009
    hvo-busterkomo:
    It's well scripted, and definitely useful. The screenshot seems fine to me- after all, visual effects are hardly the aim of systems.
     
  2. aaron

    aaron
    Joined:
    Oct 18, 2008
    Messages:
    515
    really nice.
     
  3. Dr Super Good

    Dr Super Good
    Joined:
    Jan 18, 2005
    Messages:
    21,449
    I am sure this violates the spell recource image rule.
    Maybe a picture showing it in use simlar to what vexorian used for his stacking orbs may be reccomended.
     
  4. Kercyn

    Kercyn
    Joined:
    Feb 14, 2009
    Messages:
    850
    I'm sure lots of people will find this extremely useful. Great idea :)
     
  5. Deaod

    Deaod
    Joined:
    Nov 18, 2007
    Messages:
    807
    @DSG: you DO realize i cant capture an Orb Stacking library with a screenshot easily? I find it more descriptive to use the current screenshot (although, if you insist, i can change the image to one displaying this library in action).
     
  6. Deaod

    Deaod
    Joined:
    Nov 18, 2007
    Messages:
    807
    Version 1.5.2
     
  7. Deaod

    Deaod
    Joined:
    Nov 18, 2007
    Messages:
    807
    Version 1.6.0
     
  8. Forgotten_Warlord

    Forgotten_Warlord
    Joined:
    Nov 6, 2009
    Messages:
    1,381
    ... what does this system do?? What is orb stacking??
     
  9. Deaod

    Deaod
    Joined:
    Nov 18, 2007
    Messages:
    807
    Orbs are effects that trigger (or have a chance to trigger) every time a unit with an orb damages another unit. Life Steal granted by some item, armor reduction, mana burn (feedback, i think its called), those are all examples of orbs implemented by blizzard.
    Heres where the stacking part comes in: Stacking all those different orbs on one unit is not possible. The unit would have 2 Orbs at most (playdota.com has a good reference for what orbs stack with one another by default). This library essentially allows you to stack an infinite amount of orbs on one unit. Though its necessary to recode every orb to use this library (even blizzards hardcoded orbs).
     
  10. Kingz

    Kingz
    Joined:
    Jun 5, 2008
    Messages:
    2,475
    Correct me if wrong but all of this could have been done with only IDDS(intuitive damage detection system), no?

    Anyway nice system.
     
  11. Deaod

    Deaod
    Joined:
    Nov 18, 2007
    Messages:
    807
    Youre free to use IDDS inside your map. I should probably delete LLDD from the demo as its not a necessary requirement. But while IDDS does allow easy distinction between attacks and spells (at the cost of some effort, especially in already big maps), this library offers restriciting Orb stacking, which would be impossible with just responding to damage events. Its also more efficient to just execute the functions that need to be run, than executing every function whenever a unit takes damage to check if its an attack and then possibly execute the orb. This is meant to make stacking orbs easier.
     
  12. Kingz

    Kingz
    Joined:
    Jun 5, 2008
    Messages:
    2,475
    Good points, can't argue about that :)

    As i said it is a nice system ;)
     
  13. Deaod

    Deaod
    Joined:
    Nov 18, 2007
    Messages:
    807
    Version 1.6.1
     
  14. Raziel_br

    Raziel_br
    Joined:
    Oct 13, 2008
    Messages:
    548
    it works for custom items and custom abilities?
     
  15. Deaod

    Deaod
    Joined:
    Nov 18, 2007
    Messages:
    807
    Version 1.7.0

    Yes, it does.
     
  16. Nillere

    Nillere
    Joined:
    Aug 9, 2009
    Messages:
    213
    Hmm... nice, very useful indeed =)
     
  17. Raziel_br

    Raziel_br
    Joined:
    Oct 13, 2008
    Messages:
    548
    wow!!!

    Thanks!
     
  18. Deaod

    Deaod
    Joined:
    Nov 18, 2007
    Messages:
    807
    Version 1.8.0
     
  19. Anachron

    Anachron
    Joined:
    Sep 9, 2007
    Messages:
    6,122
    You don't even post a changelog what you changed.