scope Barrier initializer I
// The_Witcher's Shield System
//
// 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 shield points just use
//
// call AddShield( yourunit, shieldHP, shieldreg per second, shielddamagefactor, show the bar, colorcode, time till reg starts, destroy when shieldhp = 0 )
// unit real real real boolean string real boolean
//
// 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
private constant integer CloudStrifeShield = 'A09J'//Cloud's Barrier AbilityId
private constant real size = 0.01 // the shieldbar's size (should be 0.01 for best result)
private constant integer lifeabi = 'A001' // A ability which gives a high instant life bonus
private constant real interval = 0.01 // the timer interval (should be 0.01 but if laggy then just change it)
endglobals
// end of Setup!!
private struct shield
unit u
real hp
real fullhp
real reg
real f
string code
texttag t
real r
timer time
boolean kill
integer i
real damage = 0
boolean show
endstruct
globals
private trigger trg = CreateTrigger()
private group g = CreateGroup()
private hashtable h = InitHashtable()
private integer total = 0
private unit array units
private timer tim = CreateTimer()
endglobals
function UnitHasShield takes unit u returns boolean
return LoadInteger(h,GetHandleId(u),0) != 0
endfunction
function DestroyShield takes unit whichunits returns nothing
local shield dat = LoadInteger(h,GetHandleId(whichunits),0)
local shield dat2 = LoadInteger(h,GetHandleId(units[total-1]),0)
if dat != 0 then
call DestroyTextTag(dat.t)
call DestroyTimer(dat.time)
call FlushChildHashtable(h,GetHandleId(whichunits))
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)
endif
endfunction
private function regeneration takes nothing returns nothing
local shield dat
local string s = "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"
local integer k
local integer i = 0
loop
exitwhen i >= total
set dat = LoadInteger(h,GetHandleId(units[i]),0)
if TimerGetRemaining(dat.time) == 0 then
if dat.hp < dat.fullhp then
set dat.hp = dat.hp + dat.reg
else
set dat.hp = dat.fullhp
endif
endif
set k = IMinBJ(R2I(100 * dat.hp / dat.fullhp),100)
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.damage != 0 then
if dat.hp > (dat.damage * dat.f) then
set dat.hp = dat.hp - (dat.damage * dat.f)
call SetWidgetLife( dat.u,GetWidgetLife(dat.u) + dat.damage)
else
call SetWidgetLife( dat.u,GetWidgetLife(dat.u) + dat.hp)
set dat.hp = 0
endif
set dat.damage = 0
endif
call UnitRemoveAbility(dat.u,lifeabi)
if dat.hp <= 0 and dat.kill == true 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 nothing
local shield dat = LoadInteger(h,GetHandleId(GetTriggerUnit()),0)
local timer t
if dat != 0 then
if dat.hp > 0 then
set dat.damage = dat.damage + GetEventDamage()
endif
call TimerStart(dat.time,dat.r,false,null)
endif
endfunction
function AddShield takes unit towhich, real hp, real RegPerSec, real TimeTillReg, real dmgfactor, string colorcode, boolean destroy, boolean ShowBar returns nothing
local shield dat
if LoadInteger(h,GetHandleId(towhich),0) != 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.kill = destroy
set dat.time = CreateTimer()
set dat.t = CreateTextTag()
set dat.show = ShowBar
call SetTextTagVisibility(dat.t,ShowBar)
set dat.i = total
if not IsUnitInGroup(dat.u,g) then
call GroupAddUnit(g,dat.u)
call TriggerRegisterUnitEvent( trg, towhich, EVENT_UNIT_DAMAGED )
endif
set units[total] = dat.u
set total = total + 1
call SaveInteger(h,GetHandleId(dat.u),0,dat)
if total == 1 then
call TimerStart(tim,interval,true,function regeneration)
endif
endfunction
private function kill takes nothing returns nothing
call DestroyShield(GetTriggerUnit())
endfunction
function ShowShield takes unit u, boolean flag returns nothing
local shield dat = LoadInteger(h,GetHandleId(u),0)
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 = LoadInteger(h,GetHandleId(u),0)
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 = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
return dat.hp
endif
return .0
endfunction
function GetShieldMaxHp takes unit u returns real
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
return dat.fullhp
endif
return .0
endfunction
function GetShieldReg takes unit u returns real
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
return dat.reg*100
endif
return .0
endfunction
function GetShieldTimeTillReg takes unit u returns real
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
return dat.r
endif
return .0
endfunction
function GetShieldDamageFactor takes unit u returns real
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
return dat.f
endif
return .0
endfunction
function SetShieldHpPercent takes unit u, real new returns nothing
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
set dat.hp = dat.fullhp * new
if dat.fullhp < dat.hp then
set dat.hp = dat.fullhp
endif
endif
endfunction
function SetShieldHp takes unit u, real new returns nothing
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
set dat.hp = new
if dat.fullhp < dat.hp then
set dat.hp = dat.fullhp
endif
endif
endfunction
function SetShieldMaxHp takes unit u, real new returns nothing
local shield dat = LoadInteger(h,GetHandleId(u),0)
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 = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
set dat.reg = new/100
endif
endfunction
function SetShieldTimeTillReg takes unit u, real new returns nothing
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
set dat.r = new
call TimerStart(dat.time,dat.r,false,null)
endif
endfunction
function SetShieldDamageFactor takes unit u, real new returns nothing
local shield dat = LoadInteger(h,GetHandleId(u),0)
if dat != 0 then
set dat.f = new
endif
endfunction
//thought about modifying the shield to the below...haven't really used it though...
function AddShieldTAF takes unit u, real realhp, real realregen returns nothing
if UnitHasShield(u) then
call DestroyShield(u)
endif
call AddShield(u, realhp,realregen,1.0,1.0,"|cff0000ff",true,false)
//function AddShield takes unit towhich, real hp, real RegPerSec, real TimeTillReg, real dmgfactor, string colorcode, boolean destroy, boolean ShowBar returns nothing
endfunction
//modified the shield to be like ff7 barrier spell like you see below
function AddShieldCloudStrife takes unit u, real realwidgetlifehp, real realnegativedecimalregen returns nothing
if UnitHasShield(u) then
call DestroyShield(u)
endif
call AddShield(u, realwidgetlifehp,realwidgetlifehp * realnegativedecimalregen,3.0,1.0,"|cff0000ff",true,false)
//function AddShield takes unit towhich, real hp, real RegPerSec, real TimeTillReg, real dmgfactor, string colorcode, boolean destroy, boolean ShowBar returns nothing
endfunction
private function f takes nothing returns boolean
local unit tu = GetSpellTargetUnit()
local unit ut = GetTriggerUnit()
local integer lvl = GetUnitAbilityLevel(ut,CloudStrifeShield)
local real lifehp = GetWidgetLife(tu)
call AddShieldCloudStrife(tu,lifehp*(0.40+(0.20*lvl)),-1.00/(-5.00 +(15.00*lvl)))
//DESCRIPTION:
//FIRST OF ALL NOTICE THAT THE SHOW BAR FUNCTION SEEMS TO NOT WORK
//SO DON'T USE TRUE IN THAT FIELD
//THE ONLY OTHER BOOLEAN YOU NEED TO WORRY ABOUT IS WHETHER THE SHIELD IS LIKE
//A ONE TIME CAST OR IF IT IS A PASSIVE SHIELD FOR GENERAL COMBAT LIKE PROTOSS SHIELDS
//IN THIS ABILITY'S CASE IT IS THE FORMER, A ONE TIME CAST OF A SHIELD, CALLED BARRIER
//
//AT EACH LEVEL NONCOMBAT (DELAY OF 3 SECONDS) DEGENERATION OF SHIELD
//REGENERATION IS... NEGATIVE 1 DIVIDED BY NEGATIVE 5 PLUS 15 TIMES LEVEL OF THE ABILITY
//SO... LEVEL 1, REGENERATION OF -1 DIVIDED BY TEN, OR 1/10 DEGENERATION
//LEVEL 2, REGENERATION OF -1 DIVIDED BY TWENTY FIVE, OR 1/25 DEGENERATION
//LEVEL 3, REGENERATION OF -1 DIVIDED BY TWENTY FIVE, OR 1/40 DEGENERATION
//LEVEL 4, REGENERATION OF -1 DIVIDED BY TWENTY FIVE, OR 1/55 DEGENERATION
//IN OTHER WORDS...IF NO DAMAGE IS TAKEN, THE SHIELD DISSIPATES IN...
//LEVEL 1: 10 SECONDS
//LEVEL 2: 25 SECONDS
//LEVEL 3: 40 SECONDS
//LEVEL 4: 55 SECONDS
//IF DAMAGE IS TAKEN EVERY LESS THAN 3 SECONDS THE SHIELD WILL NOT REGENERATE NEGATIVELY
//TO EDIT DURATION OF SHIELD CHANGE: -5.00+(15.00*lvl
//LEVEL 1: SHIELD STRENGTH EQUAL TO 60 PERCENT OF CURRENT LIFE
//LEVEL 2: SHIELD STRENGTH EQUAL TO 80 PERCENT OF CURRENT LIFE
//LEVEL 3: SHIELD STRENGTH EQUAL TO 100 PERCENT OF CURRENT LIFE
//LEVEL 4: SHIELD STRENGTH EQUAL TO 120 PERCENT OF CURRENT LIFE
//TO EDIT SHIELD STRENGTH ACCORDING TO THE CURRENT LIFE CHANGE: 0.40+(0.20*lvl
set ut=null
set tu=null
return false
endfunction
private function I takes nothing returns nothing
local trigger tt = CreateTrigger()
call TriggerAddAction(tt, function kill)
call TriggerRegisterAnyUnitEventBJ( tt, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddAction(trg, function attack)
call GT_AddStartsEffectAction(function f, CloudStrifeShield)
endfunction
endscope