Snippet Simple Hero Revival [v1.1] - GUI FRIENDLY -

baassee

Member
Reaction score
5
Simple Hero Revival [v1.1b] - GUI FRIENDLY - [Includes vJASS and JASS versions]

A simple hero revival system, requires one call per hero to use. Got a very simple code so I guess this is a snippet (and not a system anyway). Special thanks goes to bribe for a recode of the system (changed the methods into functions for simpleness).

NO THIS DOESNT SHOW ANY KIND OF TIMER DIALOG I KEPT IT SIMPLE, MAKE ONE YOUR OWN. And no I don't got any interface like "onLoop" or a function "GetCurrentTime" I apologize for that.

Contains a formula functions so you can just put the "takes real time" to 0 and let the function to the time stuff. Also have a simple filter function that will protect the users from themselves.

THIS IS GUI FRIENDLY, I HAVE A GREAT EXAMPLE HOW TO USE THIS IN GUI AND IT IS VERY EASY. IF YOU ENCOUNTER ANY PROBLEMS PLEASE REPLY TO THIS THREAD OR PM/VM ME FOR HELP.

*Requirements*
TimerUtils by Vexorian

*HOW TO IMPORT*

1. Copy the library code or the trigger into your map.

2. If you dont have TimerUtils, copy that too.

3. You're good to go! Gui Users can copy my example

4. If you want, you can read the documentation and change the pancam constant, probably useful I guess, in my map it's 0.6 but in the script I changed it to 0.0.

Credits goes to Vexorian for JASSHelper and TimerUtils.

Please credit if used,

Enjoy!

~baassee

changelog

v1.0 release

v1.1 berbs fix and other fixes

v1.1b thanks to hell gate for noticing the problem, it revived the reverse

JASS:
library HeroRevival requires TimerUtils
//*******************************************************************************************************************************
//
// This is just a simple hero revival
//      by baassee
//      Credits are appreciated
//          and please credit bribe too for his brilliant remake.
//
//         *Requires:
//              TimerUtils by Vexorian
//              A vJass Compiler
//
//
//      Credits flies out to:
//              Axarion for showing me his scope
//              Hell Gate and Deaod for their Health Reserve system, taught me alot
//              Vexorian for TimerUtils, JassHelper and vJass
//              Bribe for recoding the system.
//
//  How to use:
//      This library provides you with these functions
//          function HeroRevive takes unit hero, real time, real x, real y, boolean eff
//          function HeroReviveLoc takes unit hero, real time, location loc, boolean eff
//
//          The unit hero is obviously the hero you are going to revive.
//          The real time is the time you want to revive your hero.
//              ps. you can set this to 0 and use the GetTime func to make your formula.
//          The real x states which x coordinate where you are going to revive your hero.
//          The real y states which y coordinate where you are going to revive your hero.
//          The location loc is for those who don't know to use coordinates.
//          The boolean eff is for show or not show rebirth effect.
//
//      Example 1:
//          call HeroRevive(GetTriggerUnit(), 30., 0., 0., true)
//
//      If you use this with an event "A Unit Dies" then it will
//          Revive the dying unit, revive it after 30 seconds at coord (0,0) showing revival effect
//
//      Example 2:
//          call HeroRevive(GetTriggerUnit(), 0., GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), false)
//
//      If you use this as said above it will
//          Revive the dying unit, it will USE the formula function so you better customize it there.
//          It will revive where it died and will not show revival effect.
//
//      Example 3:
//          call HeroReviveLoc(GetTriggerUnit(), 0., udg_TempLoc, true)
//
//      If you use this as said above with a location for all GUI users it will
//          Revive the dying unit, it will USE the formula function so you better customize it there.
//          It will revive the unit at a location you've set
//          Just remember to remove the location afterwards!
//
//      End of Documentation
//
//***************************************************************************************************************************
//
//      SETUP
//
//
globals
//
//*************GUI USERS LOOK BELOW HERE****************************
//
//      This variable is where you can set how fast the camera should pan to the revived unit.
//      As this usally is set to a low value, lower the greater the size is, you can set it
//      to 0. if you want to, then it will be panned instantly.
//
    private constant real PANCAM        = 0.6
    
endglobals
    
    private function GetAdjustedTime takes real time, integer herolvl returns real
        
        return time + 0. * herolvl
        
        //if you want something extra or you can set the time to 0
        //and use this for a formula instead
        //I call this function for the formula func in the documentation
    endfunction
    
    
    private function FilterHero takes unit u returns boolean
        
        return IsUnitType(u, UNIT_TYPE_HERO) and GetWidgetLife(u) < 0.405 and IsUnitType(u, UNIT_TYPE_DEAD)
        
        //just check if the unit is a hero
        //and to check if the unit is already dead (thanks to axarion for this one)
        //you can edit the filter if you want
    endfunction
                
//      END SETUP
//******************************************************************************************************************************
//

globals
//
//      To make sure that the users wont run several instances with the same unit
//
    private group NOSTACK   = CreateGroup()
    
endglobals
    

    private struct data
        unit    hero
        real    x
        real    y
        boolean eff
    endstruct
    
    
    private function finish takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local data dat = data(GetTimerData(t))
        call ReleaseTimer(t)                                //recycle timer
    
        call ReviveHero(dat.hero, dat.x, dat.y, dat.eff)    //revive hero
        call GroupRemoveUnit(NOSTACK, dat.hero)
        
        if GetLocalPlayer() == GetOwningPlayer(dat.hero) then
            call PanCameraToTimed(dat.x, dat.y, PANCAM)
            call ClearSelection()
            call SelectUnit(dat.hero, true)
        endif
        call dat.destroy()
    endfunction
    
    
    function HeroRevive takes unit hero, real time, real x, real y, boolean eff returns nothing
        local data dat
        local timer t
        
        if FilterHero(hero) and not IsUnitInGroup(hero, NOSTACK) then
            set dat = data.create()
            set t = NewTimer()
            
            set dat.hero = hero
            set dat.x = x
            set dat.y = y
            set dat.eff = eff
            
            call GroupAddUnit(NOSTACK, hero)
            call SetTimerData(t, dat)
            call TimerStart(t, GetAdjustedTime(time, GetHeroLevel(hero)), false, function finish)
            
        debug else
            debug call BJDebugMsg("HeroRevival Error: The unit is either alive or isn't a hero unit or is already in the system, please check your trigger calls.")
        endif
    endfunction
    
    
    function HeroReviveLoc takes unit hero, real time, location loc, boolean eff returns nothing
        call HeroRevive(hero, time, GetLocationX(loc), GetLocationY(loc), eff)
    endfunction
    
    
endlibrary


GUI example in the spoiler
Trigger:
  • Test GUI FRIENDLY
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
    • Actions
      • -------- This is the unit that will be Revived by the system --------
      • -------- set it to whatever unit you want to --------
      • -------- that you want the system to revive after set time --------
      • Set TempUnit = (Triggering unit)
      • -------- Here we get the location, where the unit will be revived at --------
      • -------- as we will use the "loc" function --------
      • -------- also more friendly for GUI users --------
      • Set TempLoc = (Position of TempUnit)
      • -------- This variable shouldn't be necessary but just for an example --------
      • -------- and to help GUI coders --------
      • -------- This value below will represent the revival time of the hero --------
      • Set TempReal = 7.00
      • -------- This variable below will tell the system that it should --------
      • -------- Show revival animations (birth animation) --------
      • -------- Set it to true and it will show, set it to false and it wont --------
      • Set TempEff = True
      • -------- That was it --------
      • -------- Now I will call the function below --------
      • -------- And it will start reviving the unit --------
      • Custom script: call HeroReviveLoc(udg_TempUnit, udg_TempReal, udg_TempLoc, udg_TempEff)
      • -------- Clear the point leak --------
      • Custom script: call RemoveLocation(udg_TempLoc)
      • -------- Just to show in-game that the unit will be revived soon. --------
      • Game - Display to (All players) the text: ((Proper name of (Triggering unit)) + will be revived in 7 seconds!)

I apologize for the grammar.

NEW FOR THOSE WHO DON'T WANT TO USE JNGP, PURE JASS, REQUIRES YOU TO CREATE THE VARIABLES BELOW, THE NAMES MUST FIT EXACTLY!

- A Hashtable variable named: SHRS_Hashtable
- An Integer variable named: SHRS_N
- A Timer Array variable named SHRS_Timers

Trigger:
  • SHRS Variables create
    • Events
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set SHRS_Hashtable = (Last created hashtable)
      • Set SHRS_N = 0
      • Set SHRS_Timers[0] = (Last started timer)


The jass script below, copy it into the trigger header.

JASS:
//just a standard timer recycler, credits goes to 
//for showing me this simple The_Reborn_Devil
function SHRS_GetTimer takes nothing returns timer
        if udg_SHRS_N == 0 then
            return CreateTimer()
        endif
        set udg_SHRS_N = udg_SHRS_N - 1
        return udg_SHRS_Timers[udg_SHRS_N]
endfunction

function SHRS_ReleaseTimer takes timer t returns nothing
    if t != null then
        call PauseTimer(t)
        set udg_SHRS_Timers[udg_SHRS_N] = t
        set udg_SHRS_N = udg_SHRS_N + 1
    else
        call BJDebugMsg("Tried to release a null timer!")
    endif
endfunction

function SHRS_Revive takes nothing returns nothing
    local integer id = GetHandleId(GetExpiredTimer()) //just for simpleness and no indexing
    local unit u = LoadUnitHandle(udg_SHRS_Hashtable, id, 1) //loads the hero
    local real x = LoadReal(udg_SHRS_Hashtable, id, 2) //loads the x coordinate
    local real y = LoadReal(udg_SHRS_Hashtable, id, 3) //loads the y coordinate
    local boolean b = LoadBoolean(udg_SHRS_Hashtable, id, 4) //loads the boolean
    local integer i = LoadInteger(udg_SHRS_Hashtable, StringHash("Instances"), 0) //loads the amount of instances
    //the revive part
    call ReviveHero(u, x, y, b)
    //recycle part below
    //restore the timer
    call SHRS_ReleaseTimer(GetExpiredTimer())
    //flush the child keys of the id
    call FlushChildHashtable(udg_SHRS_Hashtable, id)
    //this isn't a must I think but for the better
    //reduce amount of instances
    set i = i - 1
    //if it's 0 instances, we flush the whole table
    if i == 0 then
        call FlushParentHashtable(udg_SHRS_Hashtable)
    else
    //ekse we just save the new value
        call SaveInteger(udg_SHRS_Hashtable, StringHash("Instances"), 0, i)
    endif
    // null the local
    set u = null
endfunction

function SHRS_HeroRevive takes unit hero, real time, real x, real y, boolean eff returns nothing
    local timer t
    local integer id
    local integer i
    //the if below is just to protect the users from themselves
    if IsUnitType(hero, UNIT_TYPE_HERO) and IsUnitType(hero, UNIT_TYPE_DEAD) and GetWidgetLife(hero) < 0.405 then
        set t = SHRS_GetTimer()
        //load the amount of instances
        set i = LoadInteger(udg_SHRS_Hashtable, StringHash("Instances"), 0)
        // with this it could support unlimited instances although the timer stuff
        // have 8191 instances so that's the limit, it was much simplier than using hash
        set id = GetHandleId(t)
        // store unit
        call SaveUnitHandle(udg_SHRS_Hashtable, id, 1, hero)
        // store x coordinate
        call SaveReal(udg_SHRS_Hashtable, id, 2, x)
        // store y coordinate
        call SaveReal(udg_SHRS_Hashtable, id, 3, y)
        // store the boolean
        call SaveBoolean(udg_SHRS_Hashtable, id, 4, eff)
        //increase the amount of instances
        set i = i + 1
        //save the amount of instances
        call SaveInteger(udg_SHRS_Hashtable, StringHash("Instances"), 0, i)
        // fire the timer
        call TimerStart(t, time, false, function SHRS_Revive)
    else
        // just a simple error message for those who don't understand the words dead and hero
        call BJDebugMsg("SHRS Error - The unit is either not dead or is not a hero")
    endif
endfunction

// same function as above but with a location
function SHRS_HeroReviveLoc takes unit hero, real time, location loc, boolean eff returns nothing
    local timer t
    local integer id
    if IsUnitType(hero, UNIT_TYPE_HERO) and IsUnitType(hero, UNIT_TYPE_DEAD) and GetWidgetLife(hero) < 0.405 then
        set t = SHRS_GetTimer()
        set id = GetHandleId(t)
        call SaveUnitHandle(udg_SHRS_Hashtable, id, 1, hero)
        call SaveReal(udg_SHRS_Hashtable, id, 2, GetLocationX(loc))
        call SaveReal(udg_SHRS_Hashtable, id, 3, GetLocationY(loc))
        call SaveBoolean(udg_SHRS_Hashtable, id, 4, eff)
        call TimerStart(t, time, false, function SHRS_Revive)
    else
        call BJDebugMsg("SHRS Error - The unit is either not dead or is not a hero")
    endif
endfunction


changelog for the jass version

v1.0 released

v1.1 fixed the reverse death check, thanks to hell gate for noticing, also made the final flush of parent keys not depending on the timer recycle, now stores the amount of instances in the hashtable so you can use the timer recycle for what ever you want
 

Attachments

  • simpleherorevival.v1.0.jpg
    simpleherorevival.v1.0.jpg
    208.6 KB · Views: 376
  • baassee.SimpleHeroRevival.v1.1b.w3x
    23.5 KB · Views: 330
  • baassee.SimpleHeroRevival.v1.1[JASS].w3x
    16.3 KB · Views: 295

Komaqtion

You can change this now in User CP.
Reaction score
469
If you take a look at the other GUI-Friendly Jass resources here on the site, you'll see that none of them actually even require Jasshelper... That is one thing that I would very much recommend you trying to achieve as GUI users don't usually have Jasshelper (Newgen) downloaded...
 

baassee

Member
Reaction score
5
Ah the common problem of installing JNGP.

I'll see what I can do but it would probably require some user defined globals (I don't like hashtables, that's why :p I usually index).

I put it as gui friendly as they can always use my example, copy it straigth away and read the comments, change the stuff and they're done :D
 

baassee

Member
Reaction score
5
Bump, new update!

Made a full JASS version, no need for JNGP now. Functions have almost the same names, just added prefix.

[ljass]function SHRS_HeroRevive takes unit hero, real time, real x, real y, boolean eff returns nothing[/ljass]

and

[ljass]function SHRS_HeroReviveLoc takes unit hero, real time, location loc, boolean eff returns nothing[/ljass]

Remember to create the 3 variables in the variable editor and make the "Create Hashtable" & "Set SHRS_Hashtable = Last Created Hashtable"

The code is in the main post.
 

rexpim

Member
Reaction score
8
Nice system for gui users
but can you change
Trigger:
  • -------- This value below will represent the revival time of the hero --------
    • Set TempReal = 7.00

to
Trigger:
  • set TempReal = ( I2R(GetHeroLevel(GetDyingUnit())) * 10.00 )

So people can add level of dying hero to the revival timer :D
 

baassee

Member
Reaction score
5
Can't they do that themselves? As said, it's just a value that I used to test the system although it is clearly stated that you can change it to whatever you want to. Thanks anyways!
 

Laiev

Hey Listen!!
Reaction score
188
I notice three things :x

1 - Your linkback of TimerUtils is wrong because the quote

2 - [ljass]local data dat = data(GetTimerData(t))[/ljass], this compile? Oo to me this should be [ljass]local data dat = GetTimerData(t)[/ljass]

3 - If the hero revive after it die (like resurrection), the system will fail in some point like revive nothing and move camera, select unit and so :p

Also I think you leak 2 locals in the timers :~

Sorry, don't looked at the Jass version because I don't use much hashtable and I'm not so familiar with it >.<


EDIT: Maybe an auto revive after hero die? (event/action)
 

baassee

Member
Reaction score
5
1. Fixed. Sometimes happen when you edit forums lol :p

2. Yes it does :)

3. Still it will not bug, just selects the unit and pans the camera :D that's the coders fault if the unit revives after a made call, would be kinda unnecessary to check if the unit is STILL dead as you did in the create.

4. What leak? I release the timers? and I just declare them at first, that's not a leak. Or you mean the JASS version? I made just a quick timer recycler there too :D

5. Auto revive? Nah I kept it simple :p
 

Laiev

Hey Listen!!
Reaction score
188
I'm not sure if timers need to be nulled too, is that what I mean.. you use 2 local variable type timer and don't null they
 

baassee

Member
Reaction score
5
I think not as you release them for reusing them again, nulling would just destroy that option wouldn't it? As TimerUtils have a debug message for releasing nulled timers I just guessed but I have never seen anyone before nulled a timer in vJASS using a timer recycler (although I have seen in JASS but that's when they destroyed the timer, just like you do with locations in JASS).
 

tooltiperror

Super Moderator
Reaction score
231
You should be making sequential timers for more efficiency. And make some commented out globals if someone wants to use vJASS and the JASS system. In the vJASS version, the convention is to name structs with capital letters and then the locals lowercase ([ljass]local Data data[/ljass]).

You also forgot to, you know, make a list of the variables in the JASS version. You should also have a function for the return time.

Edit: you need a variable creator.

EditEdit: This looks much nicer, and you shouldn't be checking if your own timers fail, afterall, we're assuming that you know what you're doing in your own system. You also had a lot of unneccassary comments (set u=null is nulling? orly?)

JASS:
.
    //globals
    //    private hashtable udg_SHRS_Hashtable=InitHashtable()
    //    private timer array udg_SHRS_Timers[8191]
    //	  private integer udg_SHRS_N=0
    //globals

    function SHRS_GetTimer takes nothing returns timer
    	if udg_SHRS_N == 0 then
            return CreateTimer()
        endif
        set udg_SHRS_N = udg_SHRS_N - 1
        return udg_SHRS_Timers[udg_SHRS_N]
    endfunction

    function SHRS_ReleaseTimer takes timer t returns nothing
        call PauseTimer(t)
        set udg_SHRS_Timers[udg_SHRS_N] = t
        set udg_SHRS_N = udg_SHRS_N + 1
    endfunction

    function SHRS_Revive takes nothing returns nothing
        local integer id = GetHandleId(GetExpiredTimer())
        local unit u = LoadUnitHandle(udg_SHRS_Hashtable, id, 1)                              // Loads the Hero
        local real x = LoadReal(udg_SHRS_Hashtable, id, 2)                                    // Loads the X Coordinate
        local real y = LoadReal(udg_SHRS_Hashtable, id, 3)                                    // Loads the Y Coordinate
        local boolean b = LoadBoolean(udg_SHRS_Hashtable, id, 4)                              // Loads the Boolean
        local integer instances = LoadInteger(udg_SHRS_Hashtable, StringHash(&quot;Instances&quot;), 0) // Loads the amount of instances
        call ReviveHero(u,x,y,b)
        call SHRS_ReleaseTimer(GetExpiredTimer())
        call FlushChildHashtable(udg_SHRS_Hashtable, id)
        set instances=instances-1
        if instances == 0 then
             call FlushParentHashtable(udg_SHRS_Hashtable)
        else
             call SaveInteger(udg_SHRS_Hashtable,StringHash(&quot;Instances&quot;),0,instances)
        endif
        set u = null
    endfunction

    function SHRS_HeroRevive takes unit hero, real time, real x, real y, boolean eff returns nothing
        local timer t
        local integer id
        local integer i
        // Protecting the users from themselves: 
        if IsUnitType(hero, UNIT_TYPE_HERO) and IsUnitType(hero, UNIT_TYPE_DEAD) and GetWidgetLife(hero) &lt; 0.405 then
            set t = SHRS_GetTimer()
            set i = LoadInteger(udg_SHRS_Hashtable, StringHash(&quot;Instances&quot;), 0)
            set id = GetHandleId(t)
            call SaveUnitHandle(udg_SHRS_Hashtable, id, 1, hero)
            call SaveReal(udg_SHRS_Hashtable, id, 2, x)
            call SaveReal(udg_SHRS_Hashtable, id, 3, y)
            call SaveBoolean(udg_SHRS_Hashtable, id, 4, eff)
            set i = i + 1
            call SaveInteger(udg_SHRS_Hashtable, StringHash(&quot;Instances&quot;), 0, i)
            call TimerStart(t, time, false, function SHRS_Revive)
        else
            call BJDebugMsg(&quot;SHRS Error - The unit is either not dead or is not a hero&quot;)
        endif
    endfunction


Why are you even using a hashtable? :p
 

baassee

Member
Reaction score
5
You should be making sequential timers for more efficiency.

Doesn't really matter as I guess you wont run as many revivals as its needed to notice the performance difference.

And make some commented out globals if someone wants to use vJASS and the JASS system.

Why would you use a JASS system when you use vJASS that is more efficient? I don't see the point in this although I get what you mean. And this didn't work for me for another system (Weep's DD).

In the vJASS version, the convention is to name structs with capital letters and then the locals lowercase (local Data data).

Yes I know this but that part was changed when Bribe fixed it. I guess it wont matter either.

You also forgot to, you know, make a list of the variables in the JASS version.

NEW FOR THOSE WHO DON'T WANT TO USE JNGP, PURE JASS, REQUIRES YOU TO CREATE THE VARIABLES BELOW, THE NAMES MUST FIT EXACTLY!

- A Hashtable variable named: SHRS_Hashtable
- An Integer variable named: SHRS_N
- A Timer Array variable named SHRS_Timers

Trigger:
  • SHRS Variables create
    • Events
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set SHRS_Hashtable = (Last created hashtable)
      • Set SHRS_N = 0
      • Set SHRS_Timers[0] = (Last started timer)

You should also have a function for the return time.

I'll add that to both versions.

This looks much nicer, and you shouldn't be checking if your own timers fail, afterall, we're assuming that you know what you're doing in your own system. You also had a lot of unneccassary comments (set u=null is nulling? orly?)

also made the final flush of parent keys not depending on the timer recycle, now stores the amount of instances in the hashtable so you can use the timer recycle for what ever you want

That's why I check if the timers fail.

It's normal documentation, for experienced it's a pain but for the inexperienced it might be the key.

Thanks for the reply. I'll update it as soon as I can.
 

tooltiperror

Super Moderator
Reaction score
231
Why are you letting users use your own timer system that is for private use? That's horribly illogical. And you still didn't even mention a variable creator. And if it's in every other GUI friendly system, you can add commented globals.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top