System Hero Revival System

wraithseeker

Tired.
Reaction score
122
JASS:
Hero Revival System by wraithseeker 
    v1.00
    
            Changelog v1.00
        - Initial release.
        

HRS is a system that behaves similarly like World of Warcraft 's' revival system added to the
system dies, a spirit and a corpse is created in place to fake the death and the spirit must go
to the spirit healer to revive and the time can vary depending on your globals.


Spirit healers

They are created through the usage of AddReviver(whichUnit) which takes a unit not a unit type
and when a unit comes within a range specified from your globals, they begin to revive with a
timeout depending on your globals again.

Heroes

Heroes must be added to the system with AddHero(HeroId) which takes a integer and not a unit.
When that happens, the HeroId will be registered to the system and the system will then function.

After learning objectmerger, I decided if possible, I will include them for users to use so
you can now use the objectmerger to generate the healers and spirit for the system.

Enjoy!.


JASS:
library HeroRevival initializer Init uses Table, TimerUtils, AutoIndex


// configurable globals
globals
    private constant integer SPIRIT = 'sPIR' // ID of spirit
    private constant integer AMOUNTOfEFFECT = 2 // Actual effect is 3, lowest amount of effect created is 1.
    // AMOUNTOFEFFECT is taken in seconds
    private constant real TIMEDMOVEMENT = 0. // how long the camera takes to pan?
    private constant real RANGE = 600. // the range to trigger revival
    private constant real RESPAWNTIME = 3 // The time you want each hero to respawn
    private boolean RespawnPoint = true // whether u want the unit to respawn at his corpse when spirit healer is reviving you.
    private boolean PauseSpirit = true // pause the spirit on reviving?
    private boolean ShowRespawnEyeCandy = false // show respawn SFX?
    private constant string EFFECT = "Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl" // effect when reviving
    private constant string OtherRespawnEyeCandy = "Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl" // other eyecandy?
endglobals

//Not configuarable
globals
    private Table HeroTable
    private integer Count = 0
    private trigger InRange = CreateTrigger()
    private boolexpr Spiritcheck
    private boolexpr Healercheck
    private group Healers = CreateGroup()
    private group CHECK = CreateGroup()
    private group GROUP = CreateGroup()
endglobals
// this is for spirit ( Uncomment them after creation )
//! external ObjectMerger w3u ewsp sPIR unam "Spirit" uabi Avul,Aeth usca "1.20" ussc "1.20" udty divine udup "0" umvs "350" ucol 0. ufoo 0 ubba 0 ubdi 0 ubsi 0 uhpm 150000 uhpr 0. uhrt none ubdg 1 urac human ugor 0 ubui _ upgr _    
// night elf healer
//! external ObjectMerger w3u ewsp lSHA unam "Spirit Healer" uabi Avul,Aeth usca "1.80" ussc "1.80" udty divine udup "0" umvs "350" ucol 0. ufoo 0 ubba 0 ubdi 0 ubsi 0 uhpm 150000 uhpr 0. uhrt none ubdg 1 urac human ugor 0 utyp _ uico "ReplaceableTextures\CommandButtons\BTNKeeperGhostBlue.blp" umdl "units\nightelf\HeroKeeperoftheGroveGhost\HeroKeeperoftheGroveGhost.mdl" uspa _ ubui _ upgr _    
// undead healer
//! external ObjectMerger w3u ewsp dSHA unam "Spirit Healer" uabi Avul,Aeth usca "1.80" ussc "1.80" udty divine udup "0" umvs "350" ucol 0. ufoo 0 ubba 0 ubdi 0 ubsi 0 uhpm 150000 uhpr 0. uhrt none ubdg 1 urac human ugor 0 utyp _ uico ReplaceableTextures\CommandButtons\BTNGhostOfKelThuzad.blp umdl "units\undead\KelThuzadGhost\KelThuzadGhost.mdl" uspa _ ubui _ upgr _


// no touch

private function Conditions takes nothing returns boolean
    local integer i = 0
    local unit u = GetTriggerUnit()
    loop
        exitwhen i >= Count // I know this is a o[n] search but it doesn't matter does it
        if GetUnitTypeId(u) == HeroTable<i> then
            set u = null
            return true
        endif
        set i = i + 1
    endloop
    set u = null
    return false
endfunction

private struct data // doesn&#039;t matter what I name right?
    unit hero // the dead hero
    unit spirit // self explainary
    unit corpse
    unit reviver
    timer t // used to display effects
    timer respawntime
    integer ticks // for timer t
    
static method create takes unit u returns data
    local data d = data.allocate()
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    set d.corpse = CreateCorpse(GetOwningPlayer(u),GetUnitTypeId(u),x,y,GetUnitFacing(u))
    set d.spirit = CreateUnit(GetOwningPlayer(u),SPIRIT,x,y,GetUnitFacing(u))
    call SetUnitAnimation(d.corpse,&quot;death&quot;) // when you create a corpse you set the animation to death to fake it
    set d.hero = u // initialization
    set d.ticks = 0
    set d.t = NewTimer()
    set d.respawntime = NewTimer()
    set data[d.spirit] = d
    return d
endmethod

method onDestroy takes nothing returns nothing
    local real x = GetUnitX(.corpse)
    local real y = GetUnitY(.corpse)
    local real sx = GetUnitX(.spirit)
    local real sy = GetUnitY(.spirit)
    if not RespawnPoint then
        if ShowRespawnEyeCandy then// some globals
            call ReviveHero(.hero,x,y,true)
        else
            call ReviveHero(.hero,x,y,false)
            if OtherRespawnEyeCandy != &quot;&quot; then
                call DestroyEffect(AddSpecialEffect(OtherRespawnEyeCandy,GetUnitX(.hero),GetUnitY(.hero)))
            endif
        endif
    else
        if ShowRespawnEyeCandy then
            call ReviveHero(.hero,sx,sy,true)
        else
            call ReviveHero(.hero,sx,sy,false)
            if OtherRespawnEyeCandy != &quot;&quot; then
                call DestroyEffect(AddSpecialEffect(OtherRespawnEyeCandy,GetUnitX(.hero),GetUnitY(.hero)))
            endif
        endif
    endif
    if GetLocalPlayer() == GetOwningPlayer(.spirit) then
        if RespawnPoint then
            call PanCameraToTimed(GetUnitX(.spirit),GetUnitY(.spirit),TIMEDMOVEMENT)
        else
            call PanCameraToTimed(x,y,TIMEDMOVEMENT)
        endif
    endif
    if PauseSpirit then
        call PauseUnit(.spirit,false)
    endif
    call KillUnit(.spirit) // kill the spirit after reviving, else it looks weird.
    call RemoveUnitEx(.corpse) // AutoIndex!
    call SetUnitAnimation(.reviver,&quot;stand&quot;) // revert animation?
endmethod

static method Revival takes nothing returns nothing
    call data(GetTimerData(GetExpiredTimer())).destroy()
endmethod

implement AutoData
endstruct

private function Respawn takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local data d = data.create(u) // start creation
    set u = null
endfunction

private function SpiritCheck takes nothing returns boolean
    return GetUnitTypeId(GetFilterUnit()) == SPIRIT
endfunction

function AddHero takes integer HeroId returns nothing
    set HeroTable[Count] = HeroId // adds it into the table array
    set Count = Count + 1 // increase count of heroIds
endfunction

function AddReviver takes unit u returns nothing
    call TriggerRegisterUnitInRange(InRange,u,RANGE,Spiritcheck)
    call GroupAddUnit(Healers,u)
endfunction

private function Effects takes nothing returns nothing
    local data d = GetTimerData(GetExpiredTimer())
    local real x = GetUnitX(d.spirit)
    local real y = GetUnitY(d.spirit)
    local boolean b = false
    if d.ticks &gt;= AMOUNTOfEFFECT then
        set b = true
        call ReleaseTimer(d.t)
    endif
    if not b then
        call DestroyEffect(AddSpecialEffect(EFFECT,x,y))
    endif
    set d.ticks = d.ticks + 1
endfunction

private function HealerCheck takes nothing returns boolean
    return IsUnitInGroup(GetFilterUnit(),Healers)
endfunction

private function GetNearestUnit takes unit target, boolexpr b returns unit// Had to use this as I can&#039;t detect spirit healer
    local real x = GetUnitX(target)
    local real y = GetUnitY(target)
    local real tx = 0. 
    local real ty = 0.
    local real ClosestDist = 99999999
    local real dist = 0.
    local unit u
    local unit Closest
        call GroupEnumUnitsInRect(GROUP,bj_mapInitialPlayableArea,b)
         loop
            set u = FirstOfGroup(GROUP)
            exitwhen u == null
            set tx = GetUnitX(u) - x
            set ty = GetUnitY(u) - y
            set dist = SquareRoot(tx*tx-ty*ty)
            if dist &lt;= ClosestDist then
                set Closest = u
                set ClosestDist = dist
            endif
            call GroupRemoveUnit(GROUP,u)
        endloop
    return Closest
endfunction

private function Revive takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local unit f
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local real angle = 0.
    local data d = data<u>
    set d.reviver = GetNearestUnit(u,Healercheck)
    set angle = Atan2(y-GetUnitY(d.reviver),x-GetUnitX(d.reviver)) * bj_RADTODEG
    call UnitRemoveType(d.reviver,UNIT_TYPE_STRUCTURE) // set the facing
    call SetUnitAnimation(d.reviver,&quot;stand channel&quot;)
    call SetUnitFacing(d.reviver,angle)
    call UnitAddType(d.reviver,UNIT_TYPE_STRUCTURE)
    if PauseSpirit then
        call PauseUnit(u,true)
    endif
    call DestroyEffect(AddSpecialEffect(EFFECT,x,y))
    call SetTimerData(d.t,d)
    call TimerStart(d.t,1,true,function Effects)
    call SetTimerData(d.respawntime,d)
    call TimerStart(d.respawntime,RESPAWNTIME,false,function data.Revival)
    // if you want it to depend on level then use this
    //call TimerStart(d.respawntime,GetHeroLevel(d.hero),false,function data.Revival)
    set u = null
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    set HeroTable = Table.create()
    set Spiritcheck = Filter(function SpiritCheck)
    set Healercheck = Filter(function HealerCheck)
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_DEATH)
    call TriggerAddCondition(t,Condition(function Conditions))
    call TriggerAddAction(t,function Respawn)
    call TriggerAddAction(InRange,function Revive)
endfunction
endlibrary</u></i>
 

Attachments

  • HRS v1.00.w3x
    77.2 KB · Views: 405
  • HRS.jpg
    HRS.jpg
    428.5 KB · Views: 513

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
>Simple
There must have atleast 200 lines of codes.

>Easy
Gui users won't be ables to use it if they don't know Jass.

Edit: Not enough customizable.
 

UndeadDragon

Super Moderator
Reaction score
447
>>Simple
>There must have atleast 200 lines of codes.

A lot of code doesn't mean it's not simple.

>>Easy
>Gui users won't be ables to use it if they don't know Jass.

I thought he explained how to use it well enough, even for GUI users. It just takes a bit of thought.

>Edit: Not enough customizable.

Not really much more to customize.
 

wraithseeker

Tired.
Reaction score
122
200 lines for a system is short and sweet enough for this kind of things.

I only gave people 2 functions, AddHero(heroId) and AddReviver(whichUnit) and then u configure the globals, very simple.
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
200 lines for a system is short and sweet enough for this kind of things.

Loool.

>Not enough customizable

I mean maybe someone wouldnt have wanted wisp, it's not a "respawn system" like dota or custom hero line war, for example.
 

wraithseeker

Tired.
Reaction score
122
JASS:
   private constant integer SPIRIT = &#039;sPIR&#039; // ID of spirit


Read the code and as I said, it is customizable for god sake, believe in vJASS.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
I agree with Jesus4Lyf.
And 'it's their problem' isn't really a viable answer :p .

There should be an option to revive them at their death spot or a specified region(s).
 

wraithseeker

Tired.
Reaction score
122
JASS:
   private boolean RespawnPoint = true // whether u want the unit to respawn at his corpse when spirit healer is reviving you.


There's a option to respawn at their death spot or at the position of the wisp but no specific region, I don't know why they would want to do that anyway.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
In an AoS, for example.
You'd have two regions (Assuming two teams) for units to spawn back at after their deaths.
 

Komaqtion

You can change this now in User CP.
Reaction score
469
I kinda agree with wraithseeker, because if they want to respawn at some region, then why not put the spirit healer at that region ?? :p
 

BlackRose

Forum User
Reaction score
239
Isn't this simliar to Halloween Map? Except more better? (The Revive Part), you bring your dead spirit to the body, and bam, revived :D
 

Andrewgosu

The Silent Pandaren Helper
Reaction score
716
"onDestroy" method:

if ShowRespawnEyeCandy then// some globals
- call ReviveHero(.hero,x,y,true)
else
- call ReviveHero(.hero,x,y,false)

can just be:

- call ReviveHero(.hero,x,y,ShowRespawnEyeCandy)


if PauseSpirit then
-call PauseUnit(.spirit,false)
endif

can just be:

- call PauseUnit(.spirit, not PauseSpirit)


"GetNearestUnit" function:

You can omit the square root call if you're doing a simple distance check:

- set dist = tx * tx + ty * ty
- if dist <= ClosestDist * ClosestDist then


Anyway, approved.
 

Andrewgosu

The Silent Pandaren Helper
Reaction score
716
I meant you're just checking the distance and you don't need the real value anywhere else.

e.g
"SquareRoot(25) < 6" boolean value is the same as "25 < 36" boolean value.

Saves you a function call.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/

      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