1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. Travel to distant realms and encounter scenes unknown to the common folk. The Greatest of Adventures is upon us with the 8th Cinematic Contest. Join in on a fun ride.
    Dismiss Notice
  5. The 18th Icon Contest is ON! Choose any ingame unit and give him/her Hero abilities. Good luck to all.
    Dismiss Notice
  6. The Secrets of Warcraft 3 have revealed interesting works. The RESULTS for Abelhawk's Mini-Mapping Contest #15 have come out!
    Dismiss Notice
  7. Contestants are to create a scene set in the Stone Age. Come and see what you can come up with. We wish you the best of luck!
    Dismiss Notice
  8. Colour outside the lines! Techtree Contest #13 is a go. The contest is optionally paired.
    Dismiss Notice
  9. Night Rider gained several songs for his journey. The poll for the 12th Music Contest has started. Check it out!
    Dismiss Notice
  10. Greetings cerebrates, our Swarm needs new spawners that will have numerous children. Join the HIVE's 31st Modeling Contest - Spawners and Spawned! The contest is optionally paired.
    Dismiss Notice
  11. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

GUI Friendly Shield System 1.00b

Submitted by AutisticTenacity
This bundle is marked as approved. It works and satisfies the submission rules.
A shield system for someone with a fetish pure unadulterated love for shields.

Requirements:

Installation:
  • Install GUI Unit Indexer 1.4.0.0
  • Install Bribe's Damage Detection 5.4.2.2 or newer
  • Copy and paste the "ShieldSystem" folder in the triggers into your map

Features:
  • Easy creation of shields that can stack with each other, with one shield being evaluated before the next (rather than all of them being damaged at once).
  • Some control over which shields are damaged first.
  • Specific Shield events, set when creating a shield.
    • Expires
      • When the duration of the shield hits 0. Expiration also removes a shield.
    • Breaks
      • When a shield breaks from blocking damage. Breaking a shield usually causes it to be removed, but can be set so that the shield does not get removed upon breaking.
    • Damaged
      • When a shield is damaged (does not run if other shields block the damage)
    • UnitDamaged
      • Runs whenever the shielded unit is damaged, regardless of whether the damage was blocked or not.
    • Removed
      • Runs when the shield is removed.
    • Periodic
      • Runs 32 times a second
  • Checking if a unit has a specific type of shield (searches by shield type id value)
  • Custom block conditions, select or modify the conditions required for the shield to block damage.
  • General events
    • (v0.90)
    • Any shield added
    • Any shield removed
    • Unit with shield is done being evaluated for damage event
    • Unit with shield is done being evaluated for periodic event
    • (1.00)
    • Any shield has health/maxhealth modified (done via periodic check, not instant)
Not included:
  • Built in customizable displays for shields.
    • There's probably no universally good way to display shields, so I'll leave that to the user to implement.
    • There is however an example in the map for how one could potentially display shields of a unit, using features of the map.

Possible future additions:

  • Better documentation on how to use the system, but the examples in the map should be suffice for now.
  • All shield events
    • Things to run when any shield does something
      • could be useful for setting up your own visual displays e.g. Any Shield Damaged -> Update some special effect or texttag that displays shield health.
      • Maybe even global shield damage modifiers based on damage type.
    • Any Shield Created event, also useful for attaching UI effects to a unit, such as a health bar, etc.
  • Features that enough people request, assuming it's reasonable to include.

Somewhat Technical stuff:
  • Shield index of 0 means no shield, or a nonexistent shield.
  • Index 0 is also used to initialize shield stats, instead of having nearly a dozen extra globals to clog up the list.
  • Shields are stored as a very funky linked list of linked lists, which happens to also be sorted at the top.
    • Evaluation order: AAABBCDDEE
    • [​IMG]
  • Newest shields are added to the bottom, assuming there are shields of that type-id already.
    • If not, then it creates a new entry, wherever it should go, in order to keep it sorted.

Anyhow, this is my first submission TheHiveWorkshop, and probably one of the few things I'd bother to submit, knowing the actual systems I use in my own maps tend to be less than sane and would probably not ever get approved.

As such, I also have no idea about most of the conventions for map submission, so if there's anything that needs to be changed for readability, or var name conflicts, I'll do my best to comply as it gets brought up.

Change log:
  • 0.80 First released
    • Missing some potentially useful features, but contains enough core features to warrant existing, probably.
  • 0.90 Shield visualization stuff
    • Added global/general events, and an example of potentially how to use them for displaying shield bars.
  • 0.90a Compatibility update for damage engine 5.4.2.0
    • Beware of unusual interactions with recursion (or lack of) if damage is done immediately in shield events.
    • Really, just delay damage by 0.00 seconds if you have to, or deal damage with custom projectiles.
    • Please don't use Waits, or Sleep.
  • 1.00a
    • Minor optimizations, converted some GUI triggers into JASS, but left behind a disabled GUI version in case someone cared about how it worked, but doesn't appreciate JASS.
    • Swapped ForGroup() with a BlzGroupUnitAt() loop in main periodic event, also left behind the pre 1.31+ compatible one in case someone cared about as well.
    • Changed to damage engine 5.4.2.2
  • 1.00b (basically a hotfix)
    • How did I let this happen. Everything actually broke around v0.90 and I didn't notice until now.
    • Removal queue fixed, things get removed properly now. Shields also shouldn't get put into the removal queue multiple times now.
    • Display system fixed to not break spells that might be using ForLoopIntegerA, or other variables.
Previews
Contents

GUIShieldSystem (Map)

Reviews
MyPad
A weird bug related to the Flame shield effect appears if you keep adding shields of different types, and that type to a certain unit. Otherwise, the system is functional, and works independently of these effects. Approved
  1. Devalut

    Devalut

    Joined:
    Feb 9, 2009
    Messages:
    770
    Resources:
    2
    Spells:
    2
    Resources:
    2
    Hot dang you posted it!

    Only the pure and righteous love shields...
     
  2. AutisticTenacity

    AutisticTenacity

    Joined:
    May 2, 2019
    Messages:
    11
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Updated to do more stuff, and also a basic shield display. Might look into aligning texttags and such, but I probably won't do that unless people decide to use my default shield visualization instead of making their own.
    [​IMG]
    A very safe peasant, hiding behind 9 shields, of 5 different types.
     
  3. Devalut

    Devalut

    Joined:
    Feb 9, 2009
    Messages:
    770
    Resources:
    2
    Spells:
    2
    Resources:
    2
    O n e
    B a r
    t o
    R u l e
    T h e m
    A l l
    a n d
    i n
    t h e
    i n d e x
    b i n d
    T h e m
     
    Last edited: Jun 17, 2019
  4. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,001
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    For mana bars, The Witcher's Shield System is the one to beat. Shield System v.3.0.

    That system itself is badly outdated and never used a damage processing system, so any change IT makes will be overwritten by any Damage Engine or vice versa. But it might be able to give you an idea of how such a shield could look.
     
  5. AutisticTenacity

    AutisticTenacity

    Joined:
    May 2, 2019
    Messages:
    11
    Resources:
    1
    Spells:
    1
    Resources:
    1
    From what I can tell of The Witcher's system though, is that a unit only ever has one shield at a time, adding another just causes it to remove the previous one.

    The difficulty is in designing something that can offer visual feedback of that shields on the unit. Since there are too many different ways one can go about designing and using shields, I've mostly left that as an exercise to the user - as one might wish to use special effects to visualize shield bars, not have a shield bar at all, or some other option that suits their map best.

    The real troublesome thing is that when people can go wild with stacking shields and such, it becomes difficult to offer a good solution that would adequately cover enough unusual use cases.


    For example, the shield system in the video above at 13:22 or so is only really applicable if shields always block all forms of damage, and that shields are always evaluated first applied, first damaged order. I think it looks nice though, but that could be my personal bias from having made it in the first place.

    Another potential option is to select a color for each type of blocking condition, and compress the visuals into a single bar above the unit, but even then it can be difficult to read, and I'm sure someone could think of a case where it wouldn't look right. This tends to be the common approach, as seen in games like League of Legends, and Heroes of the Storm - but they also only have at most, two different types of block conditions or so, blocking all damage, or blocking magic/spell damage.

    Hence, my reluctance to actually pursue a "standard" or "universal" type of shield display. If someone however has a specific display in mind for their maps and use cases, and needs help getting it implemented, I would be glad to help write something up though.

    But for now, the sideways-bar-graph look easily conveys a lot of information and is probably the most useful for debugging purposes too, even if it tends to blot out everything else around it, so it'll probably remain the default unless someone argues a convincing enough case to change it.
     
  6. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,001
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    In LoL when multiple shields are in-use I think it just increases the width of the shield bar. I don't think it's confusing to do such a thing.
     
  7. Devalut

    Devalut

    Joined:
    Feb 9, 2009
    Messages:
    770
    Resources:
    2
    Spells:
    2
    Resources:
    2
    I said the same thing and even did some fancy pants MSPaint pictures to nail it home, however Aten has a good point is that LOL has simplified shields into three damage types, but assuming an individual wants to add all damage specific shields (chaos, piercing, siege, etc) then the UI will become useless.

    Attached because I'm sure we'll spiral more into this discussion that I'm so favorable of~

    Example1
    Shield stack.png
    is stages has two examples:
    - the first four bars are stages from 1 - 4 (starting from the top), and then the final one cramming multipurpose shields in there as to maintain a universal bar size.

    Shield_bar_stacking (1).png
    shows an example that very much sits at the same size as the default health bar and reflects what it would be if the unit's health was at it's same value.(i.e. 110 shield on 220 hp peasant would result in 50% hp looking shield.)

    Shield_bar_stacking.png
    is addressing Aten's fear of shields in the previous scenario reaching above the unit's maximum hp, and echoing what Bribe has said about League's bar system, in particular lol has segments reflecting every 100 hp, meaning your bar would have 19 segments denoting 1900 hp.
    Taking this in mind every separated bar could result in a unit of maximum above the unit (Think metroid games and their energy tanks)


    Shield bar stacking.png
    Finally using the example from fungeon, example shows "shield 2" over lapping "shield 1" but as Aten has pointed out the scenario of a unique damage type shield blocking the view of generic type shields it would fall on behind the curtain.[/spoiler]
     
    Last edited: Jun 17, 2019
  8. AutisticTenacity

    AutisticTenacity

    Joined:
    May 2, 2019
    Messages:
    11
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Here's another shield onion, and the map with it.

    In this one, while it's less cluttered and shows distinct shields, and their types - the bar itself being fixed length doesn't easily convey how much health it has, since using additional dividers to show both health and different shields, gets messy quickly, and would also be a pain to implement mostly due to the thing being a texttag and a string. In the end though, it would basically boil down to a choice between dividers to show the distinct shields, or dividers to show health - assuming one is interested in maintaining some form of visual clarity.

    Also, here's a video of how peculiar it can look when some shields don't meet their conditions to be blocked under this display style.

    So, what I'm trying to say is that there are a lot of ways to display shield bars, and there may be some very unusual cases, that a typical display would not be appropriate for. So rather than thinking of the most messed up situations I can imagine under this system, and coming up a good way to reconcile all the options, I'd rather wait for someone to describe how they would like for their shields to be displayed, and I could help write that instead (assuming they don't already know how).

    Though I'm not sure whether I should add it to the main demo map, or add a separate map for a different style of shielding.
     

    Attached Files:

  9. Devalut

    Devalut

    Joined:
    Feb 9, 2009
    Messages:
    770
    Resources:
    2
    Spells:
    2
    Resources:
    2
    Looks awesome!
     
  10. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,001
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Not necessary at all. Instead of:

    • Shield Handling
      • Events
        • DamageModifierEvent becomes Equal to 4.00
      • Conditions
      • Actions
        • -------- Process shields --------
        • If (Conditions)
          • Then
            • Unit - Cause Target to damage Source
          • Else


    Do the following 3 triggers:
    • Shield Handling
      • Events
        • DamageModifierEvent becomes Equal to 4.00
      • Conditions
      • Actions
        • -------- Process shields --------
        • If (Conditions)
          • Then
            • Trigger - Turn on Shield damage <gen>
          • Else

    • Shield damage <initially off>
      • Events
        • DamageEvent becomes Equal to 1.00
      • Conditions
      • Actions
        • Unit - Cause Target to damage Source
        • Trigger - Turn off (this trigger)


    In case you want to make sure the DamageEvent trig is turned off in all scenarios, you can move the turn-off trigs to the AfterDamageEvent:

    Do the following two triggers:
    • Shield Handling
      • Events
        • DamageModifierEvent becomes Equal to 4.00
      • Conditions
      • Actions
        • -------- Process shields --------
        • If (Conditions)
          • Then
            • Trigger - Turn on Shield damage <gen>
            • Trigger - Turn on Shield after damage <gen>
          • Else

    • Shield damage <initially off>
      • Events
        • DamageEvent becomes Equal to 1.00
      • Conditions
      • Actions
        • Unit - Cause Target to damage Source


    • Shield after damage <initially off>
      • Events
        • AfterDamageEvent becomes Equal to 1.00
      • Conditions
      • Actions
        • Trigger - Turn off Shield damage <gen>
        • Trigger - Turn off Shield after damage <gen>


    The reason why this works is that the trigger whose event is detected to be problematic is the one that's frozen - all other events always run (unless otherwise turned off). In this example, trig 1 is never frozen, while trig2 will get ignored in the system once it hits recursion. The backup "AfterDamageEvent" trigger will also never be frozen.
     
    Last edited: Jul 7, 2019
  11. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,270
    Resources:
    6
    Models:
    1
    Icons:
    1
    Spells:
    3
    JASS:
    1
    Resources:
    6
    Quite a powerhouse of a Shield System (It even comes with its' own Shield Display).
    There are some lines which would need optimizing:

    Code (vJASS):

    exitwhen udg_ShieldIndex == 0  or udg_SystemShieldIterationStop == true
     


    There are instances where the Boolean variable
    SystemShieldIterationStop
    is being compared to the value
    true
    . The comparison can be removed, leaving only
    SystemShieldIterationStop


    The following triggers contain instances of these boolean assertions (usually within loops):
    • (Some Functions Disabled) ForAllShieldsOfUnit
    • (Some Functions Disabled) ForAllShieldsOfUnitDisplayOrder
    • (Some Functions Disabled) ForAllShieldsOfUnitBackward
    The trigger RemoveShield can benefit from being written in pure JASS instead, given the amount of conditions that would be generated.

    If the map is using a game version of 1.31 or higher, you can easily substitute
    • Unit Group - Pick every unit in SystemShieldedUnits and do (Actions)

    with a loop iteration based on
    BlzGroupUnitAt(group, index)
    and
    BlzGroupGetSize(group)
    .

    (The break condition is when the iterator index reaches the BlzGroupGetSize()'s value.)

    Since that trigger is expected to be executed 32 times every second, optimizing the iteration process may be necessary.
     
  12. AutisticTenacity

    AutisticTenacity

    Joined:
    May 2, 2019
    Messages:
    11
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Added those optimizations, but also included the older disabled GUI versions of the triggers in case someone unfamiliar with JASS wanted to look through it. Unlikely, but possible. Might rewrite more parts in JASS, but will probably also keep GUI variants around somewhere.

    There are probably more optimizations that could be possible, but would otherwise sacrifice some friendliness to more basic users snooping around trying to understand it.

    Also did some testing with the shield display. It was unbearably laggy with only 100 shields updating 32 times a second. Reduced bars from 66 characters to 50 characters (132 characters to 100 since '|' requires "||" to display), increased font size slightly to compensate. Changed around part of the shield system, added the "shield health modified" generic event, and updated the current default display system.

    You can see how laggy it is by typing "-shieldall" in chat. It's still very bad, but it stops lagging once the shield bars stop updating, due to now only updating the string/texttag when necessary, rather than all the time.

    Short of redoing everything in Lua, for faster string manipulation, and better data manipulation (no need for linked lists, dynamic arrays + cache benefits, etc), I can't think of other ways to get meaningful speed increases out of it.

    One such non Lua possibility was to do everything in trigger conditions, or rather, all the TriggerExecute() calls could be swapped for TriggerEvaluate() (which for whatever reason is faster), but GUI users can't actually do things in the condition part of a trigger, unfortunately.
     
    Last edited: Jul 19, 2019
  13. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,270
    Resources:
    6
    Models:
    1
    Icons:
    1
    Spells:
    3
    JASS:
    1
    Resources:
    6
    A weird bug related to the Flame shield effect appears if you keep adding shields of different types, and that type to a certain unit. Otherwise, the system is functional, and works independently of these effects.

    Approved
     
  14. AutisticTenacity

    AutisticTenacity

    Joined:
    May 2, 2019
    Messages:
    11
    Resources:
    1
    Spells:
    1
    Resources:
    1
    @MyPad Thanks for the report, and the approval
    Found the source of the bug, apparently the removal queue wasn't always working.

    Sometimes when multiple shields were broken, say because rifleman did 20 damage and broke two weak 10 hp flame shields shields in one attack, when the shields were queued to be removed, it'd remove the first, and the act of removing the shield caused it to iterate through shields again - but ended up breaking the recursion tracking so that it wasn't considered recursive iteration. This ended up resetting the queued shields count, and breaking out of the loop before all shields could be removed properly.

    With the subsequent shields not actually being removed , it wouldn't run the event for destroying the special effect as it should have (among other cleanup details). It was however still flagged as "should be removed" and thus ignored in the actual damage evaluation part the next time around, even without being actually removed.

    Will probably upload a fix soon, hopefully without breaking things.
     
  15. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,001
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    If you use Lua Damage Engine with Lua Fast Triggers, nothing will be evaluated or executed - only called.
     
  16. AutisticTenacity

    AutisticTenacity

    Joined:
    May 2, 2019
    Messages:
    11
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Made many minor but significant changes to the system. Removal queue should be working properly now.

    Found out the display system broke some of the spells, because it was using the same temp values as the abilities in some points, such as ForLoopIntegerA, and some TempReal values. Changed some of the events to not update immediately, but instead to update on the next update loop when drawing the shield bar, this should make sure the display doesn't override any of the values, at least until after they're done being used.

    This should make certain shields spells functional again, and ensure users do not need to worry about tracking what variables are used where, and how they might get accidentally overridden, at least until someone uses the "any shield" events without creating their own variables specifically for it.

    Will probably look into Lua at some point, but I'm curious as to whether GUI users will find it more convenient to swap to Lua mode, considering most resources out there are already in JASS, especially things that are unlikely to get updated. Perhaps at some point people will rewrite everything for those sweet performance boosts, and I'll have no excuse.
     
  17. _Duke

    _Duke

    Joined:
    Jul 19, 2019
    Messages:
    2
    Resources:
    0
    Resources:
    0
  18. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,001
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    I am writing all of my code into Lua, then I will move onto other common libraries. Coding is on pause while I am on vacation though. I'll pick it back up again in mid August.
     
  19. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,001
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Damage Engine has a Lua Unit Indexer included in the Lua demo map.