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

Health Reserve System v1.5

  • Like
Reactions: xxdingo93xx
Health Reserve System v1.0
by hell gate and Deaod

about the system:
this system creates a "ball" that follows physical correct a target unit with a constant garavitation. if it comes close to the target it heals x HP

how to use:
call NewHealthBall(X,Y,Z,Heal,SpeedX,SpeedY,SpeedZ,HealingUnit)

note:
you need BoundSentinel inside your map else this system can cause an fatal error!


v1.0 => Uploaded
v1.3 => added new options (Mana_Add,Red,Green,Blue,Scale); fixed Deaod's name :S
v1.5 => remove Red,Green,Blue bacause a bug, added dummy recycling, Deaod changes some movement things, now you can choose your model


JASS:
//=====================================================================================
//                         |      Health Reserve System      |
//                         |     by hell gate and Deaod      |  
//=====================================================================================
// how to use:
// Cnp this system in your map
// if you don't have BoundSentinel in your map also Cnp it else this system can cause a critical error!
// how to create a new Health Ball:
// call NewHealthBall(X     ,Y     ,Z      ,ModelPath  ,Heal   ,ManaHeal ,SpeedX ,SpeedY ,SpeedZ ,HealingUnit, Red      ,Green    ,Blue    ,Scale)
//                    real   real   real    string      real    real      real    real    real    unit         intger    intger    intger   real  
//=====================================================================================


library HealthReserve initializer Init //requires BoundSentinel
    globals
        private             real        SpeedIncraise   = 10.       //
        private             real        MaxSpeed        = 500.      //the maximum speed of a ball
        private constant    real        RopeLength      = 750.      //
        private constant    real        RefreshTime     = 1./40     //refresh intervall
        private constant    integer     DummyId         = 'h000'    //the health reserve dummy
        private constant    real        DistanceNeeded  = 100.      //how far away the ball have to be to heal
        private constant    string      HealEffect      = "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl"
    endglobals
    
    private struct HealthBalls
        real    x
        real    y
        real    z
        //----- vectors -----
        real    Heal
        real    Mana
        unit    Ball
        unit    Target
        effect  Model
        
        private integer i
        
        private static group RecycledDummys=CreateGroup()
        private static integer Count       =0
        
        private static timer Tim           = CreateTimer()
        private static integer Total       = 0
        private static thistype array Balls
        
        private static location LocZ=Location(0,0)
        
        private static method GetUnitZ takes unit u returns real
            call MoveLocation(LocZ, GetUnitX(u), GetUnitY(u))
            return GetLocationZ(LocZ)+GetUnitFlyHeight(u)
        endmethod
        
        private static method SetUnitZ takes unit u, real z returns nothing
            call MoveLocation(LocZ, GetUnitX(u), GetUnitY(u))
            call SetUnitFlyHeight(u, z-GetLocationZ(LocZ), 0)
        endmethod
        
        private method onDestroy takes nothing returns nothing
            set Total = Total - 1
            set Balls[i] = Balls[Total]
            set Balls[i].i=i
            if Total==0 then
                call PauseTimer(Tim)
            endif
        endmethod
        
        private static method BallLoop takes nothing returns nothing
        local thistype dat
        local integer i = Total-1
        local real x
        local real y
        local real z
        local real dx // delta x
        local real dy // delta y
        local real dz // delta z
        local real d // absolute distance
            loop
                exitwhen i < 0
                set dat = Balls[i]
                if IsUnitType(dat.Target, UNIT_TYPE_DEAD) == false then
                    set x=GetUnitX(dat.Ball)
                    set y=GetUnitY(dat.Ball)
                    set z=GetUnitZ(dat.Ball)
                    set dx=GetUnitX(dat.Target)-x
                    set dy=GetUnitY(dat.Target)-y
                    set dz=GetUnitZ(dat.Target)-z
                    set d=SquareRoot(dx*dx+dy*dy+dz*dz)
                    set dat.x=dat.x+dx/d*(SpeedIncraise*RopeLength/d)
                    set dat.y=dat.y+dy/d*(SpeedIncraise*RopeLength/d)
                    set dat.z=dat.z+dz/d*(SpeedIncraise*RopeLength/d)
                    // reuse d
                    if d <= DistanceNeeded then
                        call DestroyEffect(dat.Model)
                        call GroupAddUnit(RecycledDummys,dat.Ball)
                        set Count=Count+1
                        call SetWidgetLife(dat.Target,GetWidgetLife(dat.Target)+dat.Heal)
                        call SetUnitState(dat.Target, UNIT_STATE_MANA, GetUnitState(dat.Target,UNIT_STATE_MANA)+dat.Mana)
                        call DestroyEffect(AddSpecialEffectTarget(HealEffect,dat.Target,"origin"))
                        call dat.destroy()
                    else
                        set d=SquareRoot(dat.x*dat.x+dat.y*dat.y+dat.z*dat.z)
                        if d>MaxSpeed then
                            set dat.x=dat.x/d*MaxSpeed
                            set dat.y=dat.y/d*MaxSpeed
                            set dat.z=dat.z/d*MaxSpeed
                        endif
                        call SetUnitX(dat.Ball, x+dat.x)
                        call SetUnitY(dat.Ball, y+dat.y)
                        call SetUnitZ(dat.Ball, z+dat.z)
                    endif
                else
                    call RemoveUnit(dat.Ball)
                    call dat.destroy()
                endif
                set i = i-1
            endloop
        endmethod
        
        static method create takes real X, real Y, real Z, string modeleffect, real HP_Add, real Mana_Add, real vX, real vY, real vZ, unit TargetUnit, real Scale returns thistype
            local thistype dat = allocate()
            set Balls[Total] = dat
            if Total==0 then
                call TimerStart(Tim,RefreshTime,true,function thistype.BallLoop)
            endif
            set dat.i=Total
            set Total = Total+1
            set dat.Heal = HP_Add
            set dat.Mana = Mana_Add
            set dat.x = vX
            set dat.y = vY
            set dat.z = vZ
            set dat.Target = TargetUnit
            if Count == 0 then
                set dat.Ball=CreateUnit(Player(15),DummyId,X,Y,0.)
                call UnitAddAbility(dat.Ball,'Amrf')
                call UnitRemoveAbility(dat.Ball,'Amrf')
                call SetUnitPathing(dat.Ball,false)
            else
                set dat.Ball=FirstOfGroup(RecycledDummys)
                call GroupRemoveUnit(RecycledDummys,dat.Ball)
                set Count=Count-1
                call SetUnitX(dat.Ball,X)
                call SetUnitY(dat.Ball,Y)
            endif
            set dat.Model = AddSpecialEffectTarget(modeleffect,dat.Ball,"chest")
            call SetUnitFlyHeight(dat.Ball,Z,0.)
            call SetUnitScale(dat.Ball,Scale*0.01,Scale*0.01,Scale*0.01)
            return dat
        endmethod
    endstruct
    
    function NewHealthBall takes real X, real Y, real Z, string modeleffect, real HP_Add, real Mana_Add, real vX, real vY, real vZ, unit TargetUnit, real Scale returns nothing
        call HealthBalls.create( X, Y, Z, modeleffect, HP_Add, Mana_Add, vX, vY, vZ, TargetUnit, Scale)
    endfunction
    
    private function Init takes nothing returns nothing
        set SpeedIncraise = SpeedIncraise*RefreshTime
        set MaxSpeed = MaxSpeed*RefreshTime
    endfunction
endlibrary

Keywords:
Life, health, mana, gravitation, physik, heal, fly, orb monsters follow me!! help
Contents

Noch eine WARCRAFT-III-Karte (Map)

Reviews
12:21, 17th Jun 2010 TriggerHappy: The dummy player should be configurable and please try to use dummy recycling. Regardless it's good enough to be approved.

Moderator

M

Moderator

12:21, 17th Jun 2010
TriggerHappy:

The dummy player should be configurable and please try to use dummy recycling. Regardless it's good enough to be approved.
 
Level 25
Joined
Jun 5, 2008
Messages
2,572
You could use General's Frank blood orb model imo.

Also you could make it extend an interface with a onHit method if someone wants to make custom orbs.

Example:
JASS:
                        call RemoveUnit(dat.Ball)
                        call SetWidgetLife(dat.Target,GetWidgetLife(dat.Target)+dat.Heal)
                        call SetUnitState(dat.Target, UNIT_STATE_MANA, GetUnitState(dat.Target,UNIT_STATE_MANA)+dat.Mana)
                        call DestroyEffect(AddSpecialEffectTarget(HealEffect,dat.Target,"origin"))

This could be just moved to a onHit method which is extended by the struct HealthOrb or something.

It would provide great modification ability to the users, allowing them to make Exp orbs, mana orbs, damage orbs, etc...

Another Example(OrbEntity should represent your main struct):
JASS:
struct HealOrb extends OrbInterface

method onHit takes OrbEntity dat returns nothing defaults
      call RemoveUnit(dat.Ball)
      call SetWidgetLife(dat.Target,GetWidgetLife(dat.Target)+dat.Heal)
      call SetUnitState(dat.Target, UNIT_STATE_MANA, GetUnitState(dat.Target,UNIT_STATE_MANA)+dat.Mana)
      call DestroyEffect(AddSpecialEffectTarget(HealEffect,dat.Target,"origin"))
endmethod

endinterface

EDIT:

Interface could also consist of:
*Special effects on hit string variable
*OnSpawn method
*OnLoop method

Just to make it more customizable, if not nevermind, was just an idea.

EDIT2:

I didn't see a Timeout variable (a time after an orb dies/disapears) which could be quite handy in order to prevent, let's see i miss an orb and the system never stops running :p
 
Level 7
Joined
Dec 20, 2007
Messages
124
Reminds me of two things, neat spell by the way, I might use it if the code is confirmed to be flawless. I don't know any vJASS :) Anywya reminds me of 1.) Life steal from heroes of newerth and 2.) Onimusha's soul sucking system... 5/5 for the idea (does not rate code ^^) been looking for one for a long time already.
 
Top