• 🏆 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!

shield system 3.0 doesnt work on my map

Status
Not open for further replies.

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
kruzerg, I am cleaning up his code a lot as he's using a bad damage detection method. I have re-coded it to work with DamageEngine and made it a lot more efficient:

JASS:
library ShieldSystem initializer Init

// The_Witcher's Shield System, modified by Bribe to work with DamageEngine
//
// This is an easy to use shield system.
// it allows you to add shield points to a unit
// the shield works like in the game halo:
// the attacked unit doesn't receive any dmg, the shield gets it
// when the shield is down the unit is damaged
// the shield can reload constantly or after some seconds of not beeing attacked
//
// to give a unit a shield just use (if duration is 0 the shield will stay without a time limit)
//
//  call AddShield( towhichunit, hitpoints, RegPerSec, TimeTillReg,  damage factor, colorcode, destroy when shieldhp = 0, show the bar, Duration  )
//                    unit         real       real        real         real           string       boolean                  boolean       real
//
// you can check whether a unit has already a shield with (it will return a boolean)
//  UnitHasShield( yourunit)
//                  unit
//
// to implement this system, just copy this trigger in your map
// it requires jngp to be edited/saved
//
// To get rid of a shield just use
//   call DestroyShield( which unit's)
//                         unit
//
// to show or hide the shield bar use
//   call ShowShield( WhichUnits, Show? )
//                      unit     boolean
//
// to get information about an existing shield use:
//    HP:           GetShieldHp(  unit  )
//    maxHP:        GetShieldMaxHp(  unit  )
//    percentHP:    GetShieldHpPercent(  unit  )
//    regeneration: GetShieldReg(  unit  )
//    TimeTillReg:  GetShieldTimeTillReg(  unit  )
//    DamageFactor: GetShieldDamageFactor(  unit  )
//
// to change the values of an existing shield use:
//    HP:           SetShieldHp(  unit, NewValue  )
//    maxHP:        SetShieldMaxHp(  unit, NewValue  )
//    percentHP:    SetShieldHpPercent(  unit, NewValue  )
//    regeneration: SetShieldReg(  unit, NewValue  )
//    TimeTillReg:  SetShieldTimeTillReg(  unit, NewValue  )
//    DamageFactor: SetShieldDamageFactor(  unit, NewValue  )
//
// have fun^^
// The (very small^^) Setup part
globals
    // the shieldbar's size (should be (7.5 * 0.023 / 10 - 0.00625) or 0.01(which isn't working for everyone) for a good result)
    private constant real size = 7.5 * 0.023 / 10 - 0.00625

    // the timer interval (should be 0.01 but if laggy then just change it)
    private constant real interval = 0.01

    //the path of the special effect for untis with a shield
    //another good effect: "Abilities\\Spells\\Human\\DivineShield\\DivineShieldTarget.mdl"
    private constant string sfx = "Abilities\\Spells\\NightElf\\Rejuvenation\\RejuvenationTarget.mdl"

    //the attachement point for sfx
    private constant string AtPoint = "chest"
endglobals
// end of Setup!!
private struct shield
unit u
real hp
real fullhp
real reg
real f
string code
texttag t
real r
effect fx
real remain
real time
boolean kill
integer i
boolean show
endstruct

globals
    private trigger trg = CreateTrigger()
    private integer array h
    private integer total = 0
    private unit array units
    private timer tim = CreateTimer()
    private real gameTime = 0.00
endglobals

function UnitHasShield takes unit u returns boolean
    return h[GetUnitUserData(u)] != 0
endfunction

function DestroyShield takes unit whichunits returns nothing
    local shield dat = h[GetUnitUserData(whichunits)]
    local shield dat2 = h[GetUnitUserData(units[total-1])]
    if dat != 0 then
        call DestroyTextTag(dat.t)
        call DestroyEffect(dat.fx)
        set h[GetUnitUserData(whichunits)] = 0
        set total = total - 1
        set units[dat.i] = units[total]
        set dat2.i = dat.i
        call dat.destroy()
    endif
    if total == 0 then
        call PauseTimer(tim)
        call DisableTrigger(trg)
    endif
endfunction

private function regeneration takes nothing returns nothing
    local shield dat
    local string s = "''''''''''''''''''''''''''''''''''''''''''''''''''"
    local integer k
    local integer i = 0
    set gameTime = gameTime + interval
    loop
        exitwhen i >= total
        set dat = h[GetUnitUserData(units[i])]
        if gameTime >= dat.time then
            if dat.hp < dat.fullhp then
                set dat.hp = dat.hp + dat.reg
            else
                set dat.hp = dat.fullhp
            endif
        endif
        if dat.remain > 0 then
            set dat.remain = dat.remain - interval
        elseif dat.remain != -100 then
            call DestroyShield(dat.u)
        endif
        set k = R2I(50 * (dat.hp / dat.fullhp))
        call SetTextTagText(dat.t, dat.code + SubString(s, 0, k ) + "|r"  + SubString(s, k + 1, StringLength(s)) , size)
        call SetTextTagPos(dat.t, GetUnitX(dat.u) -40, GetUnitY(dat.u), -100)
        if dat.hp <= 0 and dat.kill then
            call DestroyShield(dat.u)
            set i = i - 1
        endif
        set i = i + 1
    endloop
    set s = null
endfunction

private function attack takes nothing returns boolean
    local shield dat = h[GetUnitUserData(udg_DamageEventTarget)]
    if dat != 0 then
        if dat.hp > 0 then
            set udg_DamageEventAmount = udg_DamageEventAmount * dat.f
            if dat.hp > udg_DamageEventAmount then
                set dat.hp = dat.hp - udg_DamageEventAmount
                set udg_DamageEventAmount = 0.00
            else
                set udg_DamageEventAmount = (udg_DamageEventAmount - dat.hp) / dat.f
                set dat.hp = 0.00
            endif
        endif
        set dat.time = gameTime + dat.r
    endif
    return false
endfunction

function AddShield takes unit towhich, real hp, real RegPerSec, real TimeTillReg, real dmgfactor, string colorcode, boolean destroy, boolean ShowBar, real Duration returns nothing
    local shield dat
    if h[GetUnitUserData(towhich)] != 0 then
        call DestroyShield(towhich)
    endif
    set dat = shield.create()
    set dat.u = towhich
    set dat.fullhp = hp
    set dat.hp = hp
    set dat.reg = RegPerSec / 100
    set dat.f = dmgfactor
    set dat.code = colorcode
    set dat.r = TimeTillReg
    set dat.time = gameTime + TimeTillReg
    set dat.kill = destroy
    set dat.t = CreateTextTag()
    set dat.show = ShowBar
    set dat.fx = AddSpecialEffectTarget(sfx, dat.u, AtPoint)
    set dat.remain = Duration
    if dat.remain == 0 then
        set dat.remain = -100
    endif
    call SetTextTagVisibility(dat.t,ShowBar)
    set dat.i = total
    set units[total] = dat.u
    set total = total + 1
    set h[GetUnitUserData(dat.u)] = dat
    if total == 1 then
        call TimerStart(tim,interval,true,function regeneration)
        call EnableTrigger(trg)
    endif
endfunction

private function kill takes nothing returns boolean
    call DestroyShield(GetTriggerUnit())
    return false
endfunction

function ShowShield takes unit u, boolean flag returns nothing
    local shield dat = h[GetUnitUserData(u)]
    if dat != 0 then
        set dat.show = flag
        call SetTextTagVisibility(dat.t,flag)
    endif
endfunction

function GetShieldHpPercent takes unit u returns real
    local shield dat = h[GetUnitUserData(u)]
    if dat != 0 then
        return dat.hp / dat.fullhp * 100.0
    endif
    return .0
endfunction

function GetShieldHp takes unit u returns real
    local shield dat = h[GetUnitUserData(u)]
    if dat != 0 then
        return dat.hp
    endif
    return .0
endfunction

function GetShieldMaxHp takes unit u returns real
    local shield dat = h[GetUnitUserData(u)]
    if dat != 0 then
        return dat.fullhp
    endif
    return .0
endfunction

function GetShieldReg takes unit u returns real
    local shield dat = h[GetUnitUserData(u)]
    if dat != 0 then
        return dat.reg*100
    endif
    return .0
endfunction

function GetShieldTimeTillReg takes unit u returns real
    local shield dat = h[GetUnitUserData(u)]
    if dat != 0 then
        return dat.r
    endif
    return .0
endfunction

function GetShieldDamageFactor takes unit u returns real
    local shield dat = h[GetUnitUserData(u)]
    if dat != 0 then
        return dat.f
    endif
    return .0
endfunction

function SetShieldHpPercent takes unit u, real new returns nothing
    local shield dat = h[GetUnitUserData(u)]
    if dat != 0 then
        set new = RMaxBJ(new, 1.00)
        set dat.hp = dat.fullhp * new
    endif
endfunction

function SetShieldHp takes unit u, real new returns nothing
    local shield dat = h[GetUnitUserData(u)]
    if dat != 0 then
        set dat.hp = RMaxBJ(new, dat.fullhp)
    endif
endfunction

function SetShieldMaxHp takes unit u, real new returns nothing
    local shield dat = h[GetUnitUserData(u)]
    if dat != 0 then
        set dat.fullhp = new
        if dat.fullhp < dat.hp then
            set dat.hp = dat.fullhp
        endif
    endif
endfunction

function SetShieldReg takes unit u, real new returns nothing
    local shield dat = h[GetUnitUserData(u)]
    if dat != 0 then
        set dat.reg = new/100
    endif
endfunction

function SetShieldTimeTillReg takes unit u, real new returns nothing
    local shield dat = h[GetUnitUserData(u)]
    if dat != 0 then
        set dat.r = new
        set dat.time = gameTime + new
    endif
endfunction

function SetShieldDamageFactor takes unit u, real new returns nothing
    local shield dat = h[GetUnitUserData(u)]
    if dat != 0 then
        set dat.f = new
    endif
endfunction

private function Init takes nothing returns nothing
    local trigger tt = CreateTrigger()
    call TriggerAddCondition(tt, Filter(function kill))
    call TriggerRegisterAnyUnitEventBJ(tt, EVENT_PLAYER_UNIT_DEATH)
    call TriggerAddCondition(trg, Filter(function attack))
    call TriggerRegisterVariableEvent(trg, "udg_DamageModifierEvent", EQUAL, 4.00)
    call DisableTrigger(trg)
endfunction

endlibrary

I was trying to find the code where you create the shield when an ability is cast, but I was unsuccessful. All you need to do is call AddShield when the ability is cast.
 
Last edited:
Level 6
Joined
Aug 5, 2015
Messages
202
bribe something is wrong with override function

  • unbreakble
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (DamageEventTarget has buff Unbreakable ) Equal to True
        • Then - Actions
          • Set DamageEventAmount = 0.00
          • Set DamageEventType = DamageTypeBlocked
        • Else - Actions
when i add OverRide equal to true on condition, the damageeventamount not working, but when i remove condition , its working, what happened?
i thought we set override equal to true when we set damageevent directly
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
You are never obligated to do it. The situation would have to be pretty unique - for example, if you have two different modifiers that convert the damage to a heal, the second one would reverse the heal and turn it back to damage. Most people will never run into this problem, so I recommend don't even use DamageEventOverride unless you are sure you need it (and it seems like it's not needed).
 
Status
Not open for further replies.
Top