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

moyack · 15738

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 SetWidgetLife(u, GetUnitState(u, UNIT_STATE_MAX_LIFE))
  129.     call PauseUnit(u, true)
  130.     call GroupAddUnit(Heaven, u)
  131. endfunction
  132.  
  133. private function MoveUnit takes unit u returns nothing
  134.     call SetUnitOwner(u, DUMMY_PLAYER, true)
  135.     call SetUnitX(u, GetLocationX(HEAVEN_POS))
  136.     call SetUnitY(u, GetLocationY(HEAVEN_POS))
  137. endfunction
  138.  
  139. private function PlaceDummy takes unit d, unit u returns nothing
  140.     call GroupAddUnit(Kill.corpse, d)
  141.     call SetUnitUseFood(d, false)
  142.     call SetUnitState(d, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA))
  143.     call SetUnitFlyHeight(d, GetUnitFlyHeight(u), 0.)
  144.     //call SetCSData(d, GetCSData(u)) //used to pass attached data via CSData to the corpse...
  145.     call SetUnitPathing(d, false)
  146.     call SetUnitX(d, GetUnitX(u))
  147.     call SetUnitY(d, GetUnitY(u))
  148. endfunction
  149. // end key functions...
  150.  
  151. private struct Trigger // struct to manage the EventRecycleUnit
  152.     private static integer i = 0
  153.     static unit R = null // recycled unit
  154.     static unit D = null // dummy unit
  155.     static unit A = null // attacker unit
  156.     trigger t
  157.    
  158.     static method AddTrigger takes trigger t returns nothing
  159.         local thistype T = thistype.allocate()
  160.         set T.t = t
  161.         set thistype.i = integer(T)
  162.     endmethod
  163.    
  164.     static method evaluate takes unit r, unit d, unit a returns nothing
  165.         local integer i = 1
  166.         local Trigger T
  167.         set thistype.R = r
  168.         set thistype.D = d
  169.         set thistype.A = a
  170.         loop
  171.             exitwhen i > Trigger.i
  172.             set T =thistype(i)
  173.             if T.t != null and TriggerEvaluate(T.t) then
  174.                 call TriggerExecute(T.t)
  175.             endif
  176.             set i = i + 1
  177.         endloop
  178.     endmethod
  179. endstruct
  180.  
  181. private struct Kill // struct used to manage the killed units...
  182.     static group corpse // group of units that won't be touched by the damage detection
  183.     //(corpses and dummy units for instance)
  184.    
  185.     static method Do takes unit u, unit killer returns nothing
  186.         local unit d = CreateUnit(GetOwningPlayer(u), GetUnitTypeId(u), GetUnitX(u), GetUnitY(u), GetUnitFacing(u))
  187.         call SetUnitInvulnerable(u, true)
  188.         call PlaceDummy(d, u)
  189.         call SetWidgetLife(d, 1.)
  190.         call Trigger.evaluate(u, d, killer)
  191.         call UnitDamageTarget(killer, d, 2., true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
  192.         call PrepareUnit(u)
  193.         call MoveUnit(u)
  194.         set d = null
  195.     endmethod
  196.    
  197.     private static method ManageSummoned takes nothing returns nothing
  198.         if IsUnitInGroup(GetSummonedUnit(), Kill.corpse) then
  199.             // this part will run when a corpse is resurrected, so this units are suitable to
  200.             // be controlled by the damage detection.
  201.             call GroupRemoveUnit(Kill.corpse, GetSummonedUnit())
  202.             call SetUnitPathing(GetSummonedUnit(), true)
  203.         endif
  204.     endmethod
  205.    
  206.     private static method onInit takes nothing returns nothing
  207.         local trigger t = CreateTrigger()
  208.         call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SUMMON)
  209.         call TriggerAddAction(t, function Kill.ManageSummoned)
  210.         set Kill.corpse = CreateGroup()
  211.         set t = null
  212.     endmethod
  213. endstruct
  214.  
  215. private struct DD // damage detection struct, because damage detection can be so easy...
  216.     static group D // group of unit that will have damage detection
  217.     static trigger T
  218.     static timer Tm = CreateTimer() // used to control the infinite looping when is used UnitDamageTarget over the same triggering unit
  219.    
  220.     // Add the attacked unit to the damage detection if the unit is not in the unit group
  221.     private static method AddUnit takes unit d returns nothing
  222.         if not IsUnitInGroup(d, thistype.D) and not IsUnitInGroup(d, Kill.corpse) then
  223.             debug call DisplayTimedTextToForce(bj_FORCE_ALL_PLAYERS,2,"Added " + GetUnitName(d) + " to the DD")
  224.             call TriggerRegisterUnitEvent(thistype.T, d, EVENT_UNIT_DAMAGED)
  225.             call GroupAddUnit(thistype.D, d)
  226.         endif
  227.     endmethod
  228.    
  229.     private static method Attacked takes nothing returns nothing
  230.         call thistype.AddUnit(GetTriggerUnit())
  231.     endmethod
  232.    
  233.     private static method Spelled takes nothing returns nothing
  234.         if GetSpellTargetUnit() != null then
  235.             call thistype.AddUnit(GetSpellTargetUnit())
  236.         endif
  237.     endmethod
  238.    
  239.     static method AntiLoop takes nothing returns nothing
  240.         call EnableTrigger(thistype.T)
  241.     endmethod
  242.    
  243.     private static method onInit takes nothing returns nothing
  244.         set thistype.T = CreateTrigger()
  245.         set thistype.D = CreateGroup()
  246.         call TriggerRegisterAnyUnitEventBJ(thistype.T, EVENT_PLAYER_UNIT_ATTACKED)
  247.         call TriggerAddAction(thistype.T, function thistype.Attacked)
  248.         set thistype.T = CreateTrigger()
  249.         call TriggerRegisterAnyUnitEventBJ(thistype.T, EVENT_PLAYER_UNIT_SPELL_EFFECT)
  250.         call TriggerAddAction(thistype.T, function thistype.Spelled)
  251.         set thistype.T = CreateTrigger()
  252.     endmethod
  253.  
  254. endstruct // you see, it's not bigger than this :)
  255.  
  256. private struct UR // unit recycling struct
  257.     static group Temp = CreateGroup()
  258.     static unit U = null
  259.    
  260.     static method FromDump takes nothing returns boolean
  261.         if IsUnitInGroup(GetFilterUnit(), Heaven) and IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD) == false then
  262.             set thistype.U = GetFilterUnit()
  263.         endif
  264.         return false
  265.     endmethod
  266.    
  267.     static method UseRecycled takes unit u returns unit
  268.         local real x = GetUnitX(u)
  269.         local real y = GetUnitY(u)
  270.         local real f = GetUnitFacing(u)
  271.         local real m = GetUnitState(u, UNIT_STATE_MANA)
  272.         local player p = GetOwningPlayer(u)
  273.         set thistype.U = null
  274.         call GroupEnumUnitsOfTypeCounted(thistype.Temp, UnitId2String(GetUnitTypeId(u)), Condition(function thistype.FromDump), 1)
  275.         if thistype.U != null then
  276.             debug call DisplayTimedTextToForce(bj_FORCE_ALL_PLAYERS,2, GetUnitName(thistype.U) + " is being reused...")
  277.             call SetUnitInvulnerable(thistype.U, false)
  278.             call GroupRemoveUnit(Heaven, thistype.U)
  279.             call PauseUnit(thistype.U, true)
  280.             call SetUnitPosition(thistype.U, x, y)
  281.             call SetUnitFacing(thistype.U, f)
  282.             call SetUnitOwner(thistype.U, p, true)
  283.             call SetUnitState(thistype.U, UNIT_STATE_MANA, m)
  284.             call SetUnitPathing(thistype.U, true)
  285.             call PauseUnit(thistype.U, false)
  286.             call RemoveUnit(u)
  287.             set u = null
  288.             return thistype.U
  289.         else
  290.             return u
  291.         endif
  292.     endmethod
  293.    
  294.     private static method onRecycle takes nothing returns boolean
  295.         local unit u = GetTriggerUnit()
  296.         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
  297.             call Kill.Do(u, GetEventDamageSource()) // place a dummy to replace the unit
  298.                                                        // and returns the corpse
  299.             debug call DisplayTimedTextFromPlayer(Player(15),0,0,2, GetUnitName(u) + " has been sent to the dump...")
  300.         endif
  301.         set u = null
  302.         return false
  303.     endmethod
  304.    
  305.     private static method onInit takes nothing returns nothing
  306.         local rect r = GetWorldBounds()
  307.         set Heaven = CreateGroup()
  308.         call TriggerAddCondition(DD.T, Condition(function thistype.onRecycle))
  309.         if AUTO_LOC then
  310.             call MoveLocation(HEAVEN_POS, GetRectMinX(r), GetRectMinY(r))
  311.         endif
  312.         call RemoveRect(r)
  313.         set r = null
  314.     endmethod
  315. endstruct
  316.  
  317. //*====================
  318. //* User functions... *
  319. //*====================
  320. function RecycleUnit takes unit u returns unit
  321.     return UR.UseRecycled(u)
  322. endfunction
  323.  
  324. function CreateUnitEx takes player p, integer id, real x, real y, real f returns unit
  325.     set UR.U = null
  326.     call GroupEnumUnitsOfTypeCounted(UR.Temp, UnitId2String(id), Condition(function UR.FromDump), 1)
  327.     if UR.U != null then
  328.         debug call DisplayTimedTextToForce(bj_FORCE_ALL_PLAYERS,2, GetUnitName(UR.U) + " is being reused...")
  329.         call SetUnitInvulnerable(UR.U, false)
  330.         call GroupRemoveUnit(Heaven, UR.U)
  331.         call PauseUnit(UR.U, true)
  332.         call SetUnitPosition(UR.U, x, y)
  333.         call SetUnitFacing(UR.U, f)
  334.         call SetUnitOwner(UR.U, p, true)
  335.         call SetUnitState(UR.U, UNIT_STATE_MANA, GetUnitState(UR.U, UNIT_STATE_MAX_MANA) * MANA_FACTOR)
  336.         call SetUnitPathing(UR.U, true)
  337.         call PauseUnit(UR.U, false)
  338.         return UR.U
  339.     endif
  340.     return CreateUnit(p, id, x, y, f)
  341. endfunction
  342.  
  343. function KillUnitEx takes unit u returns nothing
  344.     local unit d
  345.     if IsUnitType(u, UNIT_TYPE_HERO) == false and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false then
  346.         set d = CreateUnit(GetOwningPlayer(u), GetUnitTypeId(u), GetUnitX(u), GetUnitY(u), GetUnitFacing(u))
  347.         call Trigger.evaluate(u, d, null)
  348.         call PrepareUnit(u)
  349.         call PlaceDummy(d, u)
  350.         call KillUnit(d)
  351.         call MoveUnit(u)
  352.         else
  353.                 call KillUnit(u)
  354.     endif
  355.     set d = null
  356. endfunction
  357.  
  358. function RemoveUnitEx takes unit u returns nothing
  359.     if IsUnitType(u, UNIT_TYPE_HERO) == false and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false then
  360.         call Trigger.evaluate(u, null, null)
  361.         call PrepareUnit(u)
  362.         call MoveUnit(u)
  363.         else
  364.                 call RemoveUnit(u)
  365.     endif
  366. endfunction
  367.  
  368. function IsUnitDead takes unit u returns boolean
  369.     return IsUnitInGroup(u, Heaven)
  370. endfunction
  371.  
  372. function ReplaceDummy takes unit u returns unit
  373.     local unit d
  374.     if IsUnitType(u, UNIT_TYPE_HERO) == false and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false then
  375.         set d = CreateUnit(GetOwningPlayer(u), GetUnitTypeId(u), GetUnitX(u), GetUnitY(u), GetUnitFacing(u))
  376.         call PlaceDummy(d, u)
  377.         call SetWidgetLife(d, GetWidgetLife(u))
  378.         call PrepareUnit(u)
  379.         call MoveUnit(u)
  380.         call SetUnitPathing(d, true)
  381.     else
  382.         set d = null
  383.     endif
  384.     return d
  385. endfunction
  386.  
  387. function CreateDummy takes player p, integer id, real x, real y, real f returns unit
  388.     local unit u = CreateUnit(p, id, x, y, f)
  389.     call GroupAddUnit(Kill.corpse, u)
  390.     return u
  391. endfunction
  392.  
  393. // TriggerRecyclefunctions. this trigger happens before the triggered unit is going to die...
  394. function TriggerRegisterAnyUnitRecycleEvent takes trigger t returns nothing
  395.     call Trigger.AddTrigger(t)
  396. endfunction
  397.  
  398. constant function GetRecycledUnit takes nothing returns unit
  399.     // returns the recycled unit...
  400.     return Trigger.R
  401. endfunction
  402.  
  403. constant function GetRecycleDummyUnit takes nothing returns unit
  404.     // returns the dummy unit...
  405.     return Trigger.D
  406. endfunction
  407.  
  408. constant function GetRecycleAttacker takes nothing returns unit
  409.     // returns the attacker who "kills" the recycled unit...
  410.     return Trigger.A
  411. endfunction
  412.  
  413. constant function IsUnitDummy takes unit u returns boolean
  414.     // Checks if a unit can be recycled or not. Dummy units are not recycled, they're used as placeholder...
  415.     return IsUnitInGroup(u, Kill.corpse)
  416. endfunction
  417.  
  418. constant function GetUnitsInHeaven takes nothing returns group
  419.     // Checks if a unit can be recycled or not. Dummy units are not recycled, they're used as placeholder...
  420.     return Heaven
  421. endfunction
  422.  
  423. // Damage detection system functions...
  424. function AddDamageCondition takes boolexpr b returns nothing
  425.     call TriggerAddCondition(DD.T, b)
  426. endfunction
  427.  
  428. function DoNonDetectableDamage takes unit u, widget t, real damage, boolean attack, boolean ranged, attacktype AT, damagetype DT, weapontype WT returns boolean
  429.     call DisableTrigger(DD.T)
  430.     call TimerStart(DD.Tm, 0., false, function DD.AntiLoop)
  431.     return UnitDamageTarget(u, t, damage, attack, ranged, AT, DT, WT)
  432. endfunction
  433.  
  434. 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...


 

Chaos Realm - The world of Game modders and wc3 addicts     WC3JASS.com - The JASS Vault   Jetcraft - A Starcraft II mod