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

[JASS] Hero Revive System

Status
Not open for further replies.
Level 4
Joined
Sep 18, 2007
Messages
104
I am trying to make a hero revival system, but this is not working, can you show me why? And please acutally show me, not say something like "Use TimerUtils". The map saves fine, but the trigger doesn't seem to fire. I want the hero to be revived in the time specified as long as he doesn't belong to one of the neutral players.

And if it isn't obvious I am just learning JASS.

JASS:
function HeroReviveConditions takes nothing returns boolean
    if (IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) == true) and ((GetOwningPlayer(GetTriggerUnit()) != Player(PLAYER_NEUTRAL_AGGRESSIVE) ) or (GetOwningPlayer(GetTriggerUnit()) != Player(bj_PLAYER_NEUTRAL_VICTIM) ) or (GetOwningPlayer(GetTriggerUnit()) != Player(bj_PLAYER_NEUTRAL_EXTRA) ) or (GetOwningPlayer(GetTriggerUnit()) != Player(PLAYER_NEUTRAL_PASSIVE) ) ) then
        return true
    endif
    return false
endfunction

function HeroReviveActions takes nothing returns nothing
    local timerdialog Window
    local integer time
    local timer Timer
    local unit Hero
    local real x
    local real y
    call BJDebugMsg("Debug0")
    set Hero = GetTriggerUnit()
    set time = 30
    set Timer = CreateTimer()
    set x = 0
    set y = 0
    call StartTimerBJ(Timer, false, I2R(time))
    call CreateTimerDialogBJ(Timer, "Revive")
    set Window = GetLastCreatedTimerDialogBJ()
    call TimerDialogDisplay(Window, true)
    call PolledWait(time)
    call ReviveHero(Hero, x, y, false)
    set Hero = null
    set Timer = null
    set Window = null
    set time = 0
    set x = 0
    set y = 0
endfunction

//===========================================================================
function HeroReviveInit takes nothing returns nothing
    local trigger HeroRevive = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( HeroRevive, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( HeroRevive, Condition( function HeroReviveConditions ) )
    call TriggerAddAction( HeroRevive, function HeroReviveActions )
    set HeroRevive = null
endfunction

And I might as well ask, what is faster: StartTimerBJ or TimerStart?
 
Last edited:
Level 17
Joined
Jun 17, 2007
Messages
1,433
TimerStart is faster. Just look at the BJ:

JASS:
function StartTimerBJ takes timer t, boolean periodic, real timeout returns timer
    set bj_lastStartedTimer = t
    call TimerStart(t, timeout, periodic, null)
    return bj_lastStartedTimer
endfunction
I don't see any problems in your code at first code. What exactly do you mean by it not working? Do you receive any errors when trying to save, or does it simply not run?

Also, your conditions are quite messy. Replace the "if" in the first line with return, and then "then" in the line, and erase the endif and other return lines. I'd post what it should look like myself, but it only allows me to put so much on one line.

A few more tips:
When your initialize your variables, give them a value. e.g. instead of

JASS:
local integer time
  set time = 30
just have

JASS:
local integer time = 30
or

JASS:
local timer Timer
set Timer = CreateTimer()
into

JASS:
local timer Timer = CreateTimer
and

JASS:
call CreateTimerDialogBJ(Timer, "Revive")
set Window = GetLastCreatedTimerDialogBJ()
should be

JASS:
set Window = CreateTimerDialogBJ(Timer, "Revive")
Also, there is no reason to use your time variable as an integer. You need to convert it into a real anyway so you might as initialize it as such.

JASS:
local real time = 30.

 
Last edited:
Level 4
Joined
Sep 18, 2007
Messages
104
I want the trigger to revive a hero in the time specified, as long as the hero doesn't belong to one of the neutral players. It doesn't run, it saves fine, the Debug code doesn't appear so I know the trigger didn't fire. I will update first post and try your suggestions.

Edit: Ok I tested your suggestions, still no luck, but I didn't totally understand what you said about the conditions, I got the return part, but that was it.

JASS:
function HeroReviveConditions takes nothing returns boolean
    return (IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) == true) and ((GetOwningPlayer(GetTriggerUnit()) != Player(PLAYER_NEUTRAL_AGGRESSIVE) ) or (GetOwningPlayer(GetTriggerUnit()) != Player(bj_PLAYER_NEUTRAL_VICTIM) ) or (GetOwningPlayer(GetTriggerUnit()) != Player(bj_PLAYER_NEUTRAL_EXTRA) ) or (GetOwningPlayer(GetTriggerUnit()) != Player(PLAYER_NEUTRAL_PASSIVE) ) )
endfunction

function HeroReviveActions takes nothing returns nothing
    local real time = 5
    local timer Timer = CreateTimer()
    local timerdialog Window = CreateTimerDialogBJ(Timer, "Revive")
    local unit Hero = GetTriggerUnit()
    local real x = 0
    local real y = 0
    call BJDebugMsg("Debug0")
    call StartTimerBJ(Timer, false, time)
    call TimerDialogDisplay(Window, true)
    call PolledWait(time)
    call ReviveHero(Hero, x, y, false)
    set Hero = null
    set Timer = null
    set Window = null
    set time = 0
    set x = 0
    set y = 0
endfunction

//===========================================================================
function HeroReviveInit takes nothing returns nothing
    local trigger HeroRevive = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( HeroRevive, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( HeroRevive, Condition( function HeroReviveConditions ) )
    call TriggerAddAction( HeroRevive, function HeroReviveActions )
    set HeroRevive = null
endfunction
 
Last edited:
Level 14
Joined
Nov 18, 2007
Messages
816
You obviously need JNGP for this script to work. I dont see any reason, why you shouldnt have it anyway.

And it uses TimerUtils.

If you dont understand what the codes doing, feel free to ask.

JASS:
library HeroRevive initializer Init uses TimerUtils

    private struct Data // noone outside this library should have access to it.
        private unit u
        private real x
        private real y
        private boolean b
        private timer t
        private timerdialog td
        
        private static method Callback takes nothing returns nothing // private, because we dont want anybody else to call this method directly
        local Data s=Data(GetTimerData(GetExpiredTimer())) // get the attached instance
            call ReviveHero(s.u, s.x, s.y, s.b)
            call s.destroy() // recycle this instance of struct "Data"
        endmethod
        
        static method Create takes unit hero, real x, real y, real time, boolean show_eyecandy returns nothing
        local Data s=Data.allocate()
            // save the parameters in struct members
            set s.u=hero
            set s.x=x
            set s.y=y
            set s.b=show_eyecandy
            set s.t=NewTimer() // get a new timer
            set s.td=CreateTimerDialog(s.t) // create the dialog
            call SetTimerData(s.t, integer(s)) // attach this instance to the timer
            call TimerStart(s.t, time, false, function Data.Callback) // run the timer // Data.Callback is the static method "Callback" of struct "Data"
            // display the dialog
            call TimerDialogSetTitle(s.td, GetPlayerName(GetOwningPlayer(u))+" revives in")
            call TimerDialogDisplay(s.td, true)
        endmethod
        
        method onDestroy takes nothing returns nothing
        // Yes. I do null globals, because WC3 doesnt recycle IDs when there are any variables still pointing to it.
            set this.u=null
            call ReleaseTimer(this.t) // this equals destroying timers
            set this.t=null
            call DestroyTimerDialog(this.td) // clean up
            set this.td=null
        endmethod
    endstruct

    private function Conditions takes nothing returns boolean
        return IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO)==true and GetPlayerId(GetOwningPlayer(GetTriggerUnit()))<12
    endfunction

    private function Actions takes nothing returns nothing
    // you could inline these locals, wouldnt make any difference
    local unit Hero = GetTriggerUnit()
    local real time = 30 // the hero gets revived after this many seconds
    local real x = 0 // this is the x-coordinate of the point where the hero gets revived.
    local real y = 0 // this is the y-coordinate ... bla bla
        debug call BJDebugMsg("Debug0") //  you need to activate debug-mode to see this message. remove "debug" at the start of the line and you will always see this message.
        call Data.Create(Hero, x, y, time, false) // this calls the static method "Create" of the struct "Data"
        set Hero = null // avoid leaks
        // primitive types dont have to be nulled
    endfunction

    //===========================================================================
    private function Init takes nothing returns nothing
    local trigger t=CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
        call TriggerAddCondition(t, Condition(function Conditions))
        call TriggerAddAction(t, function Actions)
    endfunction
    
endlibrary
 
Level 4
Joined
Sep 18, 2007
Messages
104
Yo_MA_MA I have already seen that, but thanks anyways.

Deaod thanks for the script, but that didn't answer my question (Why doesn't my script work?), and it led me to another one, as I said I am learning, so I don't know how to use structs and methods, but why would I want to use that script, if the one I wrote only had a small problem, I mean if they both worked, why would I use a much larger script.
 
Level 14
Joined
Nov 18, 2007
Messages
816
tbh, i dont know why your code doesnt work. But its using BJ's. I think you should keep the usage of BJ's at a minimum.

And why use a much larger script? Well, it's the right way to do it. Using TSA is deprecated (that includes PolledWait(), although PolledWait does have valid applications).
And you if you can figure out, how a more complex script works, you might learn a bit.
 
Status
Not open for further replies.
Top