Warcraft 3 documentation
vJASS & Zinc Documentation
For the latest documentation about how it works vJASS and Zinc language layers for Warcraft III, please follow these links:
Jasshelper documentation - Zinc documentation - WC3 Optimizer documentation

[System] Unit Recycler & Simple Damage Detection System No New Posts Codes & Snippets

Started by
moyack

0 Members and 1 Guest are viewing this topic.

Rating

Average Score - 5 / 5

« Created: November 16, 2018, 12:10:03 AM by moyack »

Category: Units, System
Language: vJASS
Download Demo Map

Unit Recycler & Uber simple damage detection
By moyack - 2017


Introduction:

This system is the result of working with a damage detection system that actually can be safe (AKA avoid totally the DestroyTrigger() function), so one solution to this issue is to avoid as much as possible (hopefully completely) the destruction of units and therefore the EVENT_DAMAGED triggers related to them, and the only way to make it possible is by recycling the units. The current result is a system that recycle most type of units (summoned and buildings simply don't work for their harcoded properties).


Why is convenient this system?

because the game won't need to allocate memory creating units, instead, they'll be backed up for a later use, which can improve your map performance. This can be very useful in maps where the unit spawning is a very common task (like AoS, footies, etc).


What's the issue with buildings and summoned units??

Buildings have limitations in moving them (they can be moved but their basement remains in the original place, which won't allow the construction of new units in those places). About summoned units, their dead is totally harcoded by the summoning abilities and can't be stopped by detecting the damage, therefore they can't be recycled.


How it works?

This library takes into account units that are being damaged, and detects if they're going to die (if the damage dealt to a unit is enough to kill them), if that situation happens, then it will be moved to the heaven, a place that you define in your map where the units are restored, cleaned and left ready for later use. Additionally this system offer a set of replacement functions which will help to this system to recycle units more efficiently.


How to install & final comments

  • Create a trigger and call it "UnitRecycler" or whatever you consider it best.
  • Convert it to custom text
  • Paste the content below.
  • In the configuration globals, set the  AUTO_LOC = true if you want the system set automatically the Heaven location. Set it to false if you need to set it manually in the HEAVEN_POS variable.
  • That's all :)

That's all??? not actually. By doing only this the library will be able to add damage detection to units and store the fallen units into the heaven. But it's up to you to develop the code to recycle the units. How?? using the functions provided (you can see them in the library comments).

Core Library
Code: jass
  1. library UnitRecycler
  2. //******************************************************************************
  3. //*
  4. //* Unit Recycler
  5. //* By moyack. 2017
  6. //*
  7. //* ============================================================================
  8. //* Credits to Litany, DioD, Captain Griffen, Troll Brain and other nice guys  *
  9. //* for their suggestions, comments and ideas.                                 *
  10. //* ============================================================================
  11. //*
  12. //* This library allows to your map to reuse died units, which saves memory.
  13. //* It's very useful in AoS or footies games, where the unit spawning is a
  14. //* common task.
  15. //*
  16. //* How it works?
  17. //* =============
  18. //*
  19. //* The script detects if a unit reach the dying point (defined by the MIN_LIFE
  20. //* constant), and if the damage can kill the unit, then it is sent to the dump
  21. //* for further recycling. For custom situations like summoning or when a unit
  22. //* enters to the map, you just have to use the functions provided by this
  23. //* library.
  24. //*
  25. //* Functions
  26. //* =========
  27. //*
  28. //* in order to recycle a unit, you can use these function:
  29. //*
  30. //*  => RecycleUnit(<unit variable>) returns unit
  31. //*     -----------------------------------------
  32. //*     This function takes as argument a unit, and returns the unit recycled.
  33. //*     if there's a unit of the same typeid in the dump, it will use this unit
  34. //*     instead of the one from the function input, removing it immediately,
  35. //*     otherwise this script will return the same unit.
  36. //*
  37. //*  => CreateUnitEx(player, unitid, x, y, angle) returns unit
  38. //*     ------------------------------------------------------
  39. //*     Like the native function but tries to recycle the unit if avaliable in the dump
  40. //*
  41. //*  => KillUnitEx(<unit variable>) returns nothing
  42. //*     -------------------------------------------
  43. //*     Like the native function but it recycles the unit before killing it.
  44. //*
  45. //*  => RemoveUnitEx(<unit variable>) returns nothing
  46. //*     ---------------------------------------------
  47. //*     Like the native function but it recycles the unit.
  48. //*
  49. //*  => IsUnitDead(<unit variable>) returns boolean
  50. //*     -------------------------------------------
  51. //*     This function returns a boolean argument that indicates if the unit is dead or not.
  52. //*     Remember that a unit is dead if it's in the Heaven group.
  53. //*
  54. //*  => ReplaceDummy(<unit variable>) returns unit
  55. //*     -------------------------------------------
  56. //*     This function returns a replacement unit without killing the output unit.
  57. //*
  58. //*  => CreateDummy(player, unitid, x, y, angle) returns unit
  59. //*     ------------------------------------------------------
  60. //*     Like the CreateUnit function but the returned unit won't be affected by the damage
  61. //*     detection nor will be recycled automatically
  62. //*
  63. //*  => TriggerRegisterAnyUnitRecycleEvent(trigger t) returns nothing
  64. //*     -------------------------------------------------------------
  65. //*     All the trigger registered in this way will activate when a unit is about to be recycled
  66. //*     (in other words, it triggers before it dies). You can use this functions to retrieve the
  67. //*     the units involved in this event:
  68. //*
  69. //*      # GetRecycledUnit() returns the units that is going to be recycled
  70. //*      # GetRecycleDummyUnit() returns the dummy unit which will die instead of the recycled unit
  71. //*      # GetRecycleAttacker() returns the unit that "kills" the recycled unit
  72. //*
  73. //*  => IsUnitDummy(unit u) returns boolean
  74. //*     -----------------------------------
  75. //*     Checks if a unit can be recycled or not. Dummy units are not recycled, they're used as
  76. //*     placeholder of the unit about to die...
  77. //*
  78. //*  => GetUnitsInHeaven() returns group
  79. //*     --------------------------------
  80. //*     Returns the group which contains the units in the heaven. Useful to do checks and
  81. //*     operations on them.
  82. //*
  83. //*
  84. //* For Damage detection, you just need to use these functions:
  85. //*
  86. //*  => AddDamageCondition(<Boolexpr variable>) returns nothing
  87. //*     -------------------------------------------------------
  88. //*     Just add a condition function which manage the damaged unit and the script
  89. //*     will use it with all the the units in the DD.D group.
  90. //*
  91. //*  => DoNonDetectableDamage(unit, widget, damage, boolean_attack, boolean_ranged, attacktype, damagetype, weapontype) returns boolean
  92. //*     -------------------------------------------------------------------------------------------------------------------------------
  93. //*     Like the UnitDamageTarget function, but it can be used inside condition functions.
  94. //*     How to know if you need to use it? if you use UnitDamageTarget() inside a DD function and
  95. //*     it freezes the game until it kills the attacked unit(s), then you have to replace that
  96. //*     function by this custom one.
  97. //********************************************************************************
  98. //* CONFIGURATION PART
  99. globals
  100.     private constant real     MIN_LIFE = 0.405 // the experimental death value that will be used to activate
  101.                                          // the fake death of units. units that reach this value or less
  102.                                          // won't die and they will be recycled.
  103.     private constant boolean  AUTO_LOC = false// If it's set to true, it will place automatically the heaven in one
  104.                                               // non visible corner of the map, else, it will use the HEAVEN_POS
  105.                                               // as a heaven location
  106.     private constant player   DUMMY_PLAYER = Player(15) // sets the player owner of the unit's heaven
  107.     private constant real     MANA_FACTOR = 0.5 // sets the initial mana amount (as percentage of maximum mana)
  108.                                                 // to recycled units when they are just placed in the game.
  109.                                                 // This constant is used only by CreateUnitEx function.
  110.    
  111.     private location HEAVEN_POS = Location(-2500., 2700.) // Indicates the heaven's location.
  112. endglobals
  113. //* END CONFIGURATION PART
  114.  
  115. globals
  116.     private group Heaven // where worthy units go when they die...
  117. endglobals
  118.  
  119. // this is a key functions part just to make homogeneous the unit management, please don't edit this unless
  120. // you know what are you doing, ok??
  121. private keyword Kill
  122.  
  123. private function PrepareUnit takes unit u returns nothing
  124.     call SelectUnit(u, false)
  125.     call UnitRemoveBuffs(u, true, true)
  126.     call UnitResetCooldown(u)
  127.     call SetUnitInvulnerable(u, true)
  128.     call PauseUnit(u, true)
  129.     call GroupAddUnit(Heaven, u)
  130. endfunction
  131.  
  132. private function MoveUnit takes unit u returns nothing
  133.     call SetUnitOwner(u, DUMMY_PLAYER, true)
  134.     call SetUnitX(u, GetLocationX(HEAVEN_POS))
  135.     call SetUnitY(u, GetLocationY(HEAVEN_POS))
  136. endfunction
  137.  
  138. private function PlaceDummy takes unit d, unit u returns nothing
  139.     call GroupAddUnit(Kill.corpse, d)
  140.     call SetUnitUseFood(d, false)
  141.     call SetUnitFlyHeight(d, GetUnitFlyHeight(u), 0.)
  142.     //call SetCSData(d, GetCSData(u)) //used to pass attached data via CSData to the corpse...
  143.     call SetUnitPathing(d, false)
  144.     call SetUnitX(d, GetUnitX(u))
  145.     call SetUnitY(d, GetUnitY(u))
  146. endfunction
  147. // end key functions...
  148.  
  149. private struct Trigger // struct to manage the EventRecycleUnit
  150.     private static integer i = 0
  151.     static unit R = null // recycled unit
  152.     static unit D = null // dummy unit
  153.     static unit A = null // attacker unit
  154.     trigger t
  155.    
  156.     static method AddTrigger takes trigger t returns nothing
  157.         local thistype T = thistype.allocate()
  158.         set T.t = t
  159.         set thistype.i = integer(T)
  160.     endmethod
  161.    
  162.     static method evaluate takes unit r, unit d, unit a returns nothing
  163.         local integer i = 1
  164.         local Trigger T
  165.         set thistype.R = r
  166.         set thistype.D = d
  167.         set thistype.A = a
  168.         loop
  169.             exitwhen i > Trigger.i
  170.             set T =thistype(i)
  171.             if T.t != null and TriggerEvaluate(T.t) then
  172.                 call TriggerExecute(T.t)
  173.             endif
  174.             set i = i + 1
  175.         endloop
  176.     endmethod
  177. endstruct
  178.  
  179. private struct Kill // struct used to manage the killed units...
  180.     static group corpse // group of units that won't be touched by the damage detection
  181.     //(corpses and dummy units for instance)
  182.    
  183.     static method Do takes unit u, unit killer returns nothing
  184.         local unit d = CreateUnit(GetOwningPlayer(u), GetUnitTypeId(u), GetUnitX(u), GetUnitY(u), GetUnitFacing(u))
  185.         call SetUnitInvulnerable(u, true)
  186.         call PlaceDummy(d, u)
  187.         call SetWidgetLife(d, 1.)
  188.         call Trigger.evaluate(u, d, killer)
  189.         call UnitDamageTarget(killer, d, 2., true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
  190.         call PrepareUnit(u)
  191.         call MoveUnit(u)
  192.         set d = null
  193.     endmethod
  194.    
  195.     private static method ManageSummoned takes nothing returns nothing
  196.         if IsUnitInGroup(GetSummonedUnit(), Kill.corpse) then
  197.             // this part will run when a corpse is resurrected, so this units are suitable to
  198.             // be controlled by the damage detection.
  199.             call GroupRemoveUnit(Kill.corpse, GetSummonedUnit())
  200.             call SetUnitPathing(GetSummonedUnit(), true)
  201.         endif
  202.     endmethod
  203.    
  204.     private static method onInit takes nothing returns nothing
  205.         local trigger t = CreateTrigger()
  206.         call TriggerAddAction(t, function Kill.ManageSummoned)
  207.         set Kill.corpse = CreateGroup()
  208.         set t = null
  209.     endmethod
  210. endstruct
  211.  
  212. private struct DD // damage detection struct, because damage detection can be so easy...
  213.     static group D // group of unit that will have damage detection
  214.     static trigger T
  215.     static timer Tm = CreateTimer() // used to control the infinite looping when is used UnitDamageTarget over the same triggering unit
  216.    
  217.     // Add the attacked unit to the damage detection if the unit is not in the unit group
  218.     private static method AddUnit takes unit d returns nothing
  219.         if not IsUnitInGroup(d, thistype.D) and not IsUnitInGroup(d, Kill.corpse) then
  220.             debug call DisplayTimedTextToForce(bj_FORCE_ALL_PLAYERS,2,"Added " + GetUnitName(d) + " to the DD")
  221.             call TriggerRegisterUnitEvent(thistype.T, d, EVENT_UNIT_DAMAGED)
  222.             call GroupAddUnit(thistype.D, d)
  223.         endif
  224.     endmethod
  225.    
  226.     private static method Attacked takes nothing returns nothing
  227.         call thistype.AddUnit(GetTriggerUnit())
  228.     endmethod
  229.    
  230.     private static method Spelled takes nothing returns nothing
  231.         if GetSpellTargetUnit() != null then
  232.             call thistype.AddUnit(GetSpellTargetUnit())
  233.         endif
  234.     endmethod
  235.    
  236.     static method AntiLoop takes nothing returns nothing
  237.         call EnableTrigger(thistype.T)
  238.     endmethod
  239.    
  240.     private static method onInit takes nothing returns nothing
  241.         set thistype.T = CreateTrigger()
  242.         set thistype.D = CreateGroup()
  243.         call TriggerAddAction(thistype.T, function thistype.Attacked)
  244.         set thistype.T = CreateTrigger()
  245.         call TriggerAddAction(thistype.T, function thistype.Spelled)
  246.         set thistype.T = CreateTrigger()
  247.     endmethod
  248.  
  249. endstruct // you see, it's not bigger than this :)
  250.  
  251. private struct UR // unit recycling struct
  252.     static group Temp = CreateGroup()
  253.     static unit U = null
  254.    
  255.     static method FromDump takes nothing returns boolean
  256.         if IsUnitInGroup(GetFilterUnit(), Heaven) and IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD) == false then
  257.             set thistype.U = GetFilterUnit()
  258.         endif
  259.         return false
  260.     endmethod
  261.    
  262.     static method UseRecycled takes unit u returns unit
  263.         local real x = GetUnitX(u)
  264.         local real y = GetUnitY(u)
  265.         local real f = GetUnitFacing(u)
  266.         local real m = GetUnitState(u, UNIT_STATE_MANA)
  267.         local player p = GetOwningPlayer(u)
  268.         set thistype.U = null
  269.         call GroupEnumUnitsOfTypeCounted(thistype.Temp, UnitId2String(GetUnitTypeId(u)), Condition(function thistype.FromDump), 1)
  270.         if thistype.U != null then
  271.             debug call DisplayTimedTextToForce(bj_FORCE_ALL_PLAYERS,2, GetUnitName(thistype.U) + " is being reused...")
  272.             call SetUnitInvulnerable(thistype.U, false)
  273.             call GroupRemoveUnit(Heaven, thistype.U)
  274.             call PauseUnit(thistype.U, true)
  275.             call SetUnitPosition(thistype.U, x, y)
  276.             call SetUnitFacing(thistype.U, f)
  277.             call SetUnitOwner(thistype.U, p, true)
  278.             call SetUnitState(thistype.U, UNIT_STATE_MANA, m)
  279.             call SetUnitPathing(thistype.U, true)
  280.             call PauseUnit(thistype.U, false)
  281.             call RemoveUnit(u)
  282.             set u = null
  283.             return thistype.U
  284.         else
  285.             return u
  286.         endif
  287.     endmethod
  288.    
  289.     private static method onRecycle takes nothing returns boolean
  290.         local unit u = GetTriggerUnit()
  291.         if IsUnitType(u, UNIT_TYPE_HERO) == false and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and IsUnitType(u, UNIT_TYPE_SUMMONED) == false and GetWidgetLife(u) - GetEventDamage() <= MIN_LIFE then
  292.             call Kill.Do(u, GetEventDamageSource()) // place a dummy to replace the unit
  293.                                                        // and returns the corpse
  294.             debug call DisplayTimedTextFromPlayer(Player(15),0,0,2, GetUnitName(u) + " has been sent to the dump...")
  295.         endif
  296.         set u = null
  297.         return false
  298.     endmethod
  299.    
  300.     private static method onInit takes nothing returns nothing
  301.         local rect r = GetWorldBounds()
  302.         set Heaven = CreateGroup()
  303.         call TriggerAddCondition(DD.T, Condition(function thistype.onRecycle))
  304.         if AUTO_LOC then
  305.             call MoveLocation(HEAVEN_POS, GetRectMinX(r), GetRectMinY(r))
  306.         endif
  307.         call RemoveRect(r)
  308.         set r = null
  309.     endmethod
  310. endstruct
  311.  
  312. //*====================
  313. //* User functions... *
  314. //*====================
  315. function RecycleUnit takes unit u returns unit
  316.     return UR.UseRecycled(u)
  317. endfunction
  318.  
  319. function CreateUnitEx takes player p, integer id, real x, real y, real f returns unit
  320.     set UR.U = null
  321.     call GroupEnumUnitsOfTypeCounted(UR.Temp, UnitId2String(id), Condition(function UR.FromDump), 1)
  322.     if UR.U != null then
  323.         debug call DisplayTimedTextToForce(bj_FORCE_ALL_PLAYERS,2, GetUnitName(UR.U) + " is being reused...")
  324.         call SetUnitInvulnerable(UR.U, false)
  325.         call GroupRemoveUnit(Heaven, UR.U)
  326.         call PauseUnit(UR.U, true)
  327.         call SetUnitPosition(UR.U, x, y)
  328.         call SetUnitFacing(UR.U, f)
  329.         call SetUnitOwner(UR.U, p, true)
  330.         call SetUnitState(UR.U, UNIT_STATE_MANA, GetUnitState(UR.U, UNIT_STATE_MAX_MANA) * MANA_FACTOR)
  331.         call SetUnitPathing(UR.U, true)
  332.         call PauseUnit(UR.U, false)
  333.         return UR.U
  334.     endif
  335.     return CreateUnit(p, id, x, y, f)
  336. endfunction
  337.  
  338. function KillUnitEx takes unit u returns nothing
  339.     local unit d
  340.     if IsUnitType(u, UNIT_TYPE_HERO) == false and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false then
  341.         set d = CreateUnit(GetOwningPlayer(u), GetUnitTypeId(u), GetUnitX(u), GetUnitY(u), GetUnitFacing(u))
  342.         call Trigger.evaluate(u, d, null)
  343.         call PrepareUnit(u)
  344.         call PlaceDummy(d, u)
  345.         call KillUnit(d)
  346.         call MoveUnit(u)
  347.         else
  348.                 call KillUnit(u)
  349.     endif
  350.     set d = null
  351. endfunction
  352.  
  353. function RemoveUnitEx takes unit u returns nothing
  354.     if IsUnitType(u, UNIT_TYPE_HERO) == false and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false then
  355.         call Trigger.evaluate(u, null, null)
  356.         call PrepareUnit(u)
  357.         call MoveUnit(u)
  358.         else
  359.                 call RemoveUnit(u)
  360.     endif
  361. endfunction
  362.  
  363. function IsUnitDead takes unit u returns boolean
  364.     return IsUnitInGroup(u, Heaven)
  365. endfunction
  366.  
  367. function ReplaceDummy takes unit u returns unit
  368.     local unit d
  369.     if IsUnitType(u, UNIT_TYPE_HERO) == false and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false then
  370.         set d = CreateUnit(GetOwningPlayer(u), GetUnitTypeId(u), GetUnitX(u), GetUnitY(u), GetUnitFacing(u))
  371.         call PlaceDummy(d, u)
  372.         call SetWidgetLife(d, GetWidgetLife(u))
  373.         call PrepareUnit(u)
  374.         call MoveUnit(u)
  375.         call SetUnitPathing(d, true)
  376.     else
  377.         set d = null
  378.     endif
  379.     return d
  380. endfunction
  381.  
  382. function CreateDummy takes player p, integer id, real x, real y, real f returns unit
  383.     local unit u = CreateUnit(p, id, x, y, f)
  384.     call GroupAddUnit(Kill.corpse, u)
  385.     return u
  386. endfunction
  387.  
  388. // TriggerRecyclefunctions. this trigger happens before the triggered unit is going to die...
  389. function TriggerRegisterAnyUnitRecycleEvent takes trigger t returns nothing
  390.     call Trigger.AddTrigger(t)
  391. endfunction
  392.  
  393. constant function GetRecycledUnit takes nothing returns unit
  394.     // returns the recycled unit...
  395.     return Trigger.R
  396. endfunction
  397.  
  398. constant function GetRecycleDummyUnit takes nothing returns unit
  399.     // returns the dummy unit...
  400.     return Trigger.D
  401. endfunction
  402.  
  403. constant function GetRecycleAttacker takes nothing returns unit
  404.     // returns the attacker who "kills" the recycled unit...
  405.     return Trigger.A
  406. endfunction
  407.  
  408. constant function IsUnitDummy takes unit u returns boolean
  409.     // Checks if a unit can be recycled or not. Dummy units are not recycled, they're used as placeholder...
  410.     return IsUnitInGroup(u, Kill.corpse)
  411. endfunction
  412.  
  413. constant function GetUnitsInHeaven takes nothing returns group
  414.     // Checks if a unit can be recycled or not. Dummy units are not recycled, they're used as placeholder...
  415.     return Heaven
  416. endfunction
  417.  
  418. // Damage detection system functions...
  419. function AddDamageCondition takes boolexpr b returns nothing
  420.     call TriggerAddCondition(DD.T, b)
  421. endfunction
  422.  
  423. function DoNonDetectableDamage takes unit u, widget t, real damage, boolean attack, boolean ranged, attacktype AT, damagetype DT, weapontype WT returns boolean
  424.     call DisableTrigger(DD.T)
  425.     call TimerStart(DD.Tm, 0., false, function DD.AntiLoop)
  426.     return UnitDamageTarget(u, t, damage, attack, ranged, AT, DT, WT)
  427. endfunction
  428.  
  429. endlibrary

Changelog
(14/10/2008):
 - Small improvements in the core library
 - Developed a better example (a tiny AOS, much better than AotZ, DoE and ToB together :P)

(09/09/2008):
 - Added a custom trigger event so the system can detect when a unit is about to be recycled
 - Added some improvements

(31/12/2008):
 - Other minor and final improvements (hopefully)

(06/01/2009):
 - Now you can set up the system so it automatically set the heaven in a non playable area of the map (Thanks Troll brain for the idea)
 - Added IsUnitDummy function to define if a unit is a placeholder or not.
 - Added GetUnitsInHeaven function to retrieve the group that stores the units in Heaven. Useful to do operations with those units.
 - Improved the test map with a leaderboard which shows data about units killed per player, units in map, units taht are being recycled, and the percentage of units recycled respect the total of active units.

(29/01/2009):
 - Minor improvement in the DD code, now it's more efficient getting units in to the DD group.

(05/04/2009):
 - Fixed an unit leak (thanks a lot Litany :D) and improved the CreateUnitEx function.

(18/12/2017):
 - Redefined some variables, fixed some bugs with KillUnitEx()
 - Added demo map (an endless battle)

Please download the test map for further testing. (last updated: 05/04/2009)
« Last Edit: December 18, 2017, 12:28:18 PM by moyack »



Re: [System] Unit Recycler & Simple Damage Detection System
Reply #1 on: February 09, 2012, 12:53:14 PM

Cool, a unit recycler :D

I wish the overhead could be smaller :/

... I know! :D
How about only giving the units the locust ability so nothing could happen to them, and you can pause them so that they can't do anything :D



Re: [System] Unit Recycler & Simple Damage Detection System
Reply #2 on: August 19, 2012, 04:46:55 PM

Doing Unit Recycling and DDS in the same lib is a very bad idea. Have you ever heard of the term modularity?

I'd recommend that you split them up into two different libraries.

edit
Also, your DDS leaks mass events.



Re: [System] Unit Recycler & Simple Damage Detection System
Reply #3 on: August 20, 2012, 12:40:47 AM

Doing Unit Recycling and DDS in the same lib is a very bad idea. Have you ever heard of the term modularity?
Yes, I know the term, but one of the reason I could do it in that way was the fact I needed internal and private stuff from the damage detection that should be called into the unit recycling.

Quote
I'd recommend that you split them up into two different libraries.
Hmm, I think this code should be revised, with the new knowledge in vJASS.

Quote
edit
Also, your DDS leaks mass events.
I'll check it out.


Re: [System] Unit Recycler & Simple Damage Detection System
Reply #4 on: August 20, 2012, 12:47:46 AM

This is the DDS I wrote

http://www.hiveworkshop.com/forums/jass-resources-412/snippet-damageevent-186829/

And here is the Dummy lib I wrote

http://www.hiveworkshop.com/forums/jass-resources-412/system-dummy-213908/


This is before you take the next naive approach of mass refreshes on the DDS and no accounting for unit facing on the dummy recycle ; ).



Re: [System] Unit Recycler & Simple Damage Detection System
Reply #5 on: August 20, 2012, 01:02:03 AM

Would you mind in share your scripts here :) So I can link the requirements in this site.

Hugss :D


[System] Unit Recycler & Simple Damage Detection System
Reply #6 on: June 25, 2013, 08:50:33 PM

Added download link and preview image...


 

Started by moyack

Replies: 1
Views: 23871
Jass Tutorials

Started by Vexorian

Replies: 0
Views: 1269
Codes & Snippets

Started by cohadar

Replies: 0
Views: 1215
Codes & Snippets

Started by ashujon

Replies: 0
Views: 1766
Warcraft III Spells and Systems

Started by azlier

Replies: 0
Views: 928
Codes & Snippets
Vivir aprendiendo.co - A place for learning stuff, in Spanish   Chaos Realm - The world of Game modders and wc3 addicts   Diplo, a gaming community   Power of Corruption, an altered melee featuring Naga and Demon. Play it now!!!   WC3JASS.com - The JASS Vault + vJASS and Zinc   Jetcraft - A Starcraft II mod   WormTastic Clan (wTc)   Warcraft RESOURCES Reforged: Modelos, mapas, proyectos y mas...