• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Mana-based shield system

Status
Not open for further replies.
Hello everyone.
I was wondering if anyone knows how to make a nice protoss-like shield system using mana points?

I was checking out this system for damage detection and manipulation:
http://www.wc3c.net/showthread.php?t=108009

But cant get it to work somehow, due to optional library requieries (at least one each of wich were implemented!)
I heard vexorian made a system like this, but i cant seem to find it.
Noone who could bother helping me out on making this?
I have basic knowledge of jass and vJass.
Thanks in advance.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
The version I had from vexorian was dated. It leaked and infact does not even work in version 1.24 (this was a very old one from pre 1.20 days).

I advise looking at my shield system in the spell section to see how damage prevention is done and then making your own system.
 
I checked your spell pack, really nice. But i cant actually find any damage detection in it; it is using the standard blizzard event "[specific unit] is damaged", and a trigger automatically created for each unit that has the shield. I thought that event was unsafe to use? Or is that "unit is attacked"?

Furthermore, i understand you are using an ability wich increases health by 2000 while it's applied. Though i found a smaller code snippet in wich a guy had used a similar way, resetting the units hp as soon as it was damaged, but comments suggested that healing up the unit wasn't a good option. Could you explain to me how this system works?

What i'm searching for is simply a way to detect the damage event, how much damage is dealt, and then stop it from happening. the rest i can do on my own.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
You have to use the even I used, even if for every unit on the map.
Basically my system detects when a unit takes damage, sets a certain ammount to reheal of the damage taken and makes it so that they can not die from the damage. It then waits 0 seconds via timer (yes 0 is a delay) and reheals the unit the damage it took so that it is back at normal HP.

My spell had 2 bugs in the maths, one of which I fixed in a non released update. It is still less buggy than a lot of less professional solutions which do not take into account the delay of the damage.
 
I altered your library a little, and here's how it turned out:

JASS:
library DamageShield requires Common, DamageShieldRegen
    //This system requires Dr Super Good's DamageShieldRegen system to opperate.

    globals
        //The system ID is used by the universal hash system to identify data stored on a non local source.
        //This is to prevent collisions with other spells.
        private constant integer SYSTEM_ID = StringHash("Damage Shield")
    endglobals
    
    struct DamageShield
        trigger DamageTrigger = CreateTrigger()
        unit Affected
        boolean ShowArt = false
        
        static method ondamage takes nothing returns boolean
            local real d = GetEventDamage()
            local unit u = GetTriggerUnit()
            if d > 0 then
            if d < GetUnitState(u, UNIT_STATE_MANA) then
            call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA)-d)
            call DamageShieldRegen_Add(u,0)
            else
            call DamageShieldRegen_Add(u,GetUnitState(u, UNIT_STATE_MANA)-d)
            call SetUnitState(u, UNIT_STATE_MANA, 0)
            endif
            endif 
            set u = null
            return false
        endmethod  
        
        
        
        
        static method get takes unit whichunit returns DamageShield
            //call BJDebugMsg("get")
            return LoadInteger(Chash,GetHandleId(whichunit),SYSTEM_ID)
        endmethod   
        
        
        
        static method create takes unit whichunit returns DamageShield
            local DamageShield shield = DamageShield.allocate()
            set shield.Affected = whichunit
            call TriggerRegisterUnitEvent(shield.DamageTrigger,whichunit,EVENT_UNIT_DAMAGED)
            call TriggerAddCondition(shield.DamageTrigger,Condition(function DamageShield.ondamage))
            call SaveInteger(Chash,GetHandleId(whichunit),SYSTEM_ID,shield)
            set whichunit = null
            return shield
        endmethod

    endstruct
    
    function AddShield takes unit u, boolean art returns nothing
                local DamageShield shield
                set shield = DamageShield.get(u)
                if shield == 0 then
                    set shield = DamageShield.create(u)
                endif
endfunction

endlibrary

It actually works!
I also have another trigger that uses the AddShield function on new units.

Thank you, and let me know if there are any flaws in my changes.


PS: I removed the "onDestroy" method, since the shield will not be destroyed anyways.
EDIT: just realized it will have to be, once the unit dies. Will fix that later.
 
Status
Not open for further replies.
Top