System Hero Revival System

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'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'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

GetTriggerUnit-

DogEntrepreneur
>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
Staff member
>>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.
 
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
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.
 

WolfieeifloW

WEHZ Helper
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).
 
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.
 

Komaqtion

You can change this now in User CP.
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
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
Staff member
"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.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • C Cherry.Grove:
    So what's the whole reforged situation? Do we have to run the classic version bootleg now?
  • C Cherry.Grove:
    My boyfriend is super into Bethesda modding so I'm probably going to join him in that for a bit, then move on to making mobile/browser games.
  • C Cherry.Grove:
    I mostly just want to look at my old projects because I know I posted uploads on here somewhere.
  • C Cherry.Grove:
    My one game was basically Among Us but you sabotaged an entire medieval city simulated drastically inefficiently with dynamic NPCs :S
  • C Cherry.Grove:
    of course I never finished it x D
  • jonas jonas:
    xD
  • jonas jonas:
    I think you can still run the original game, just there's a chance your map won't work with the newer patches
  • jonas jonas:
    what development framework have you been looking at for mobile development?
  • jonas jonas:
    I'm currently creating (as a hobby) a space invaders like game for mobile using Xamarin, after starting a few larger projects that I also may not have finished :rolleyes::p
  • The Helper The Helper:
    Awesome! you should look at the Atari VCS platform it does not have a huge user base but the one it has is super active at around 11k and they have no games in there store
  • The Helper The Helper:
    basically it is linux
  • The Helper The Helper:
    OMG it is BanLord as Blackveiled on the forum
  • The Helper The Helper:
    what is up buddy
  • jonas jonas:
    thanks for the tip, that sounds cool. Never heard about the VCS before but seems like it should be a good match
  • tom_mai78101 tom_mai78101:
    The winter vacation left a toll on me. I missed staying up late and sleeping in late.
  • C Cherry.Grove:
    i haven't looked into it yet
  • C Cherry.Grove:
    If I could use something Python compatible it would save me some learning
  • C Cherry.Grove:
    But Unity might be easiest
  • C Cherry.Grove:
    looking at old posts here makes me happy. Makes me be all like "wow I was pretty smart in 2009"
  • C Cherry.Grove:
    mostly failing at life through adulthood really demotivated me for a while
  • C Cherry.Grove:
    ....what I don't get is why the fuck they would force us to permanently convert to a version of the game everyone fucking hated : \
  • C Cherry.Grove:
    Raid Shadow Legends texture pack smh
  • jonas jonas:
    Most people fail at life throughout their adulthood. Sometimes we get to learn from it. Usually it just feels like crap.
  • The Helper The Helper:
    What does not kill you makes you stronger is what they say

    Members online

    No members online now.

    Affiliates

    Hive Workshop NUON Dome
    Top