Simple Restore Health Trigger

Beetlebomb

New Member
Reaction score
43
Hey guys, I'm going to give this whole JASS thing another go-- and this time I won't give up!

I got a couple simple questions I'd like to ask.

This is the Original GUI Version I'm trying to convert:

Code:
Restore
    Events
        Player - Player 1 (Red) skips a cinematic sequence
    Conditions
    Actions
        Unit - Set life of Sorceress 0000 <gen> to 100.00%
        Unit - Set mana of Sorceress 0000 <gen> to 100.00%
        Special Effect - Create a special effect attached to the origin of Sorceress 0000 <gen> using Abilities\Spells\Human\Resurrect\ResurrectTarget.mdl
        Special Effect - Destroy (Last created special effect)

And this is the converted version:
JASS:
function Trig_Restore_Copy_Actions takes nothing returns nothing
    call SetUnitLifePercentBJ( gg_unit_H000_0000, 100 )
    call SetUnitManaPercentBJ( gg_unit_H000_0000, 100 )
    call AddSpecialEffectTargetUnitBJ( &quot;origin&quot;, gg_unit_H000_0000, &quot;Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl&quot; )
    call DestroyEffectBJ( GetLastCreatedEffectBJ() )
endfunction

//===========================================================================
function InitTrig_Restore_Copy takes nothing returns nothing
    set gg_trg_Restore_Copy = CreateTrigger(  )
    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Restore_Copy, Player(0) )
    call TriggerAddAction( gg_trg_Restore_Copy, function Trig_Restore_Copy_Actions )
endfunction


Now here's what I've done so far. As you must know, there are tons of syntax errors I'm getting, but I don't know enough to figure out what I'm missing. I'm writing this on JassCraft as well if that helps any.

JASS:
function Check takes real a, real b returns real
    if (a &lt; b) then
    return b
    else
    return a
    endif
    

function Heal takes nothing returns nothing
    local unit u = gg_unit_H000_0000
    local real a = 0
    local real b = 100
    call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_MAX_LIFE) * function Check(a, b) * 0.01) 
    call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MAX_MANA) * function Check(a, b) * 0.01)
    call AddSpecialEffectLoc(&quot;Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl&quot;, GetUnitLoc(u))
    call DestroyEffect(return bj_lastCreatedEffect)
endfunction

//===========================================================================
function Restore takes nothing returns nothing
    set Restore = CreateTrigger(  )
    call TriggerRegisterPlayerEventEndCinematic( Restore, Player(0) )
    call TriggerAddAction( Restore, function Heal )
endfunction


I created the Check function because I saw the SetUnitState had a BJ function called RMax something? I tried to manipulate and copy it, but...eh.

As usual, any attempts at helping me would be greatly apreciated! Thanks again guys!
 

Romek

Super Moderator
Reaction score
963
JASS:
function Check takes real a, real b returns real
    if (a &lt; b) then
    return b
    else
    return a
    endif


Needs an 'endfunction'

JASS:
    local real a = 0
    local real b = 100

I think reals need a decimal point in them. I don't know this for sure, as I just put the point there anyway.

So that should be:
JASS:
    local real a = 0.
    local real b = 100.



Should be:
JASS:
call DestroyEffect(j_lastCreatedEffect)


"return" is used to return something when the function is called from another function.

JASS:
set Restore = CreateTrigger(  )

I'm guessing that "Restore" is undeclared.
I suggest you use a local trigger.
 

Flare

Stops copies me!
Reaction score
662
I think reals need a decimal point in them. I don't know this for sure, as I just put the point there anyway.
That's only if you are doing something like
JASS:
set realVar = 10 / 3
//Or something or other
//That&#039;ll give 3.0 I think
//whereas
set realVar = 10. / 3.
//would give you 3.333...
//since integers and reals can be used together

//not sure what happens when you divide integers by reals and vice versa though

But if you're using a variable, the . isn't required unless you desperately want it (or, of course, you need a decimal part for your number e.g. 5.5

JASS:
    call AddSpecialEffectLoc(&quot;Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl&quot;, GetUnitLoc(u))
    call DestroyEffect(return bj_lastCreatedEffect)

Natives don't set a value for bj_last... variables, change it to
JASS:
call DestroyEffect (AddSpecialEffect (&quot;Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl&quot;, GetUnitX (u), GetUnitY (u)))
//Using the coordinate special effect native will get rid of the location leak removal <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite1" alt=":)" title="Smile    :)" loading="lazy" data-shortname=":)" />


JASS:
function Check takes real a, real b returns real
    if (a &lt; b) then
    return b
    else
    return a
    endif

1) Add the endfunction
2) There's already an RMaxBJ function, which is doing exactly that, why not use it?

That Restore variable hasn't be declared anywhere, simplest thing to do
JASS:
set Restore = CreateTrigger(  )

becomes
JASS:
local trigger Restore = CreateTrigger ()
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Adding onto what everyone above has said:

I created the Check function because I saw the SetUnitState had a BJ function called RMax something? I tried to manipulate and copy it, but...eh.

BJ functions are only bad when they don't do anything useful. Since you're just recreating it, it's smarter to just use the bj function, so that others who try to read your code can understand it better (without having to look at your created function to see what it does).

Therefore, it's smarter to change this:

JASS:
    call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_MAX_LIFE) * function Check(a, b) * 0.01)


into this:

JASS:
    call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_MAX_LIFE) * function RMaxBJ(a, b) * 0.01)



//not sure what happens when you divide integers by reals and vice versa though

The integer gets converted into a real, I'm pretty sure.

JASS:
    call AddSpecialEffectLoc(&quot;Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl&quot;, GetUnitLoc(u))
    call DestroyEffect(return bj_lastCreatedEffect)


This can all be combined into one line:

JASS:
call DestroyEffect(AddSpecialEffectLoc(&quot;Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl&quot;, GetUnitLoc(u)))


Also, technically the Max function is pointless in itself. Since you're simply setting the unit's hp/mana to its max, there isn't much point in multiplying 100 by 0.01, as that will always return 1.

This would be different if you were setting its hp to a number that could possible be higher than the max amount.

So this:

JASS:
    call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_MAX_LIFE) * function Check(a, b) * 0.01) 
    call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MAX_MANA) * function Check(a, b) * 0.01)


can become this:



This also means that you don't need to create the local reals 'a' and 'b'.

You also have a leak: GetUnitLoc(u). This creates a point, which you do not destroy.

Normally, in GUI you'd have to go about setting a location/point variable to this, but since we're working with JASS, we can use coordinates instead. The function AddSpecialEffect does the exact same thing, but instead of taking a location, it takes two reals: an X and a Y.

So we can just use GetUnitX(UNIT) and GetUnitY(UNIT) instead of GetUnitLoc(UNIT):

JASS:
    call DestroyEffect(AddSpecialEffect(&quot;Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl&quot;, GetUnitX(u), GetUnitY(u)))


The final thing you should be concerned with, is the local unit variable needs to be nulled after you're done with it:

JASS:
    set u = null


Finalized code:

JASS:
function Heal takes nothing returns nothing
    local unit u = gg_unit_H000_0000
    call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_MAX_LIFE)) 
    call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MAX_MANA))
    call DestroyEffect(AddSpecialEffect(&quot;Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl&quot;, GetUnitX(u), GetUnitY(u)))
    set u = null
endfunction

//===========================================================================
function Restore takes nothing returns nothing
    local trigger Restore = CreateTrigger(  )
    call TriggerRegisterPlayerEventEndCinematic( Restore, Player(0) )
    call TriggerAddAction( Restore, function Heal )
endfunction


Now you have an efficient, leak-free trigger. It took quite a bit of work, but a lot of the stuff I showed you isn't something extremely important for a beginner. If it seems complicated, ignore the part about the location and leaks, and nulling 'u'.
 

Beetlebomb

New Member
Reaction score
43
>If it seems complicated, ignore the part about the location and leaks, and nulling 'u'.

no no no, that is all very useful information. Thank you VERY much(the 3 of you) for taking the time and responding to my thread! I learned a lot!

I have some other questions that I had prior to recently getting back into JASS:
what is the difference between using a gamecache and structs?

I was speaking to a friend of mine who is taking programming as his major and he gave me a little information on what HE knows of structs. Is it like putting several bits of information into one variable that can be called for at any given time for any of the provided information inside of it?

I need a clear explanation of what structs are and how gamecaches differ.

I remember you, Flare, tried helping me with this a long time ago through PM's but I still haven't quite gotten the grasp for it-- I'm sorry. Do you mind trying one more time?

Once again, I always appreciate the effort this community puts forth in helping others, thank you.
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Structs are not really comparable to the GameCache.

The gamecache simply stores an integer or a real type variable onto your harddrive, with two keys, that you can use to get it back. Usually, it's used as a way to transfer local variables between functions.

A struct is like a wrapper for a bunch of objects. You can put a unit variable, a string array, even a timer and integer inside of it, and then pass it all along as one simple object.

The two go hand-in-hand:
The gamecache, when used to transfer local variables between functions, is being used as an Attachment System. There are many different ones, but this is the only one that is in the game by default. Others, such as PUI, CSData, HSAS, HAIL, and ABC are user-created.

The difference is that GameCache is much slower than the other ones. But until you get to creating sliding/knockback triggers, it won't make a difference.

The reason the two objects go together well, is because structs are actually integers. You could do something like this, for example:

JASS:
struct Data
    unit Caster
    timer CB
endstruct

function Testfunc takes nothing returns nothing
    local Data d = Data.create()
    local integer i = d //This is valid, as d is simply an integer
endfunction


However, with the help of the preprocessor, JassHelper (Newgen), you can treat them as variables. In reality, structs are simply arrays of all the variable types inside, and the struct itself is an integer variable, which is used as an index when you want to refer to one of the variables the 'struct' contains.

Attachment systems and structs are very complicated systems, as structs have only been around since vJASS, whereas Attachment Systems have been around for much longer.

Before vJASS, people had to use the H2I bug, with gamecache (or another attachment system), just to be able to pass local variables to other functions.

What is the H2I bug you say?

JASS:
function H2I takes handle h returns integer
    return h
    return 0
endfunction


It doesn't make any sense, does it? That's why it's a bug. When the world editor saves, its syntax check has to make sure all functions that return something end up returning the right variable-type. In reality, it only checks the very last return of a function. However, when the code runs, it only returns the first thing it gets to.

When this function would be syntax checked, the editor would see that it returns 0, and ignore the fact that it's returning the wrong type first. When the code is run, it ends up trying to return a handle variable as an integer. This actually works, which lets you change any sort of handle into a unit, to use with game cache, or another attachment system, since game cache can store integers, but can't store any sort of handle variable.

However, now the idea of using arrays of objects, and simply passing an index through an attachment system has become more popular, which is what structs are based off of.

That's the run down of it all. :p

You'll understand more when you start wanting to make completely MUI spells, especially ones that use timers instead of periodic events.
 

Beetlebomb

New Member
Reaction score
43
I seem to be missing something because I still get 1 compile error using:

JASS:
function Heal takes nothing returns nothing
    local unit u = gg_unit_H000_0000  //the error is here. It says that gg_unit_H000_0000 is an unidentified variable.
    call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_MAX_LIFE))
    call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MAX_MANA))
    call DestroyEffect(AddSpecialEffect(&quot;Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl&quot;, GetUnitX(u), GetUnitY(u)))
    set u = null
endfunction

//===========================================================================
function Restore_Health takes nothing returns nothing
    local trigger Restore = CreateTrigger()
    call TriggerRegisterPlayerEventEndCinematic( Restore, Player(0) )
    call TriggerAddAction( Restore, function Heal )
endfunction


I checked to make sure that the unit I placed on the map really was named that, and it was, but still I receive this error.

I did this by creating a GUI trigger that requires selecting the unit and then converting it to see if It had the same unitID(Letting you know because that might be the problem).

Any Ideas?
 

Beetlebomb

New Member
Reaction score
43
It's still a hard thing to grasp, but It's definitely clearer-- thank you.


>You'll understand more when you start wanting to make completely MUI spells, especially ones that use timers instead of periodic events.

Yes, I've tried doing that with a tutorial off wc3campaigns. They had one for a stomp ability that knocks units back. I got it to work, however, I still had many questions I wanted to ask, but the thread hasn't been looked at for a long long time so I didn't bother posting.

Do you have any suggestions on where I could go to sharpen my knowledge of what I know thus far, and possibly slowly edge myself closer to using the more advanced attachment systems that you mentioned?
 

Flare

Stops copies me!
Reaction score
662
Do you have any suggestions on where I could go to sharpen my knowledge of what I know thus far
You could try and find some simple JASS spells (if such a thing exists in the Tutorials & Resources section :p) or snippets and take a look at the code to see how they work (and try to identify which part does what)

possibly slowly edge myself closer to using the more advanced attachment systems that you mentioned?
I'd suggest a simple DoT spell (since a very basic one can be done with just a few actions in a timer), both with and without an attachment system, so you'll understand how to do things in multiple ways. For doing it via attachment system, I'd suggest using CSData or TimerUtils - they are very simple and easy-to-use
 

Beetlebomb

New Member
Reaction score
43
Where could I go about looking up how to use the CSData method?

Also the previous code that I needed to figure out that I started this thread for is still not working. It says that my unit local is unidentified. Do you know what's wrong?

Here's the code:

JASS:
function Heal takes nothing returns nothing
    local unit u = gg_unit_H000_0000 //This is the one giving me the error. I checked to see if this was indeed the right unit I placed on the map, and it was. Am I supposed to be writing something else here?    
    call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_MAX_LIFE))
    call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MAX_MANA))
    call DestroyEffect(AddSpecialEffect(&quot;Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl&quot;, GetUnitX(u), GetUnitY(u)))
    set u = null
endfunction

//===========================================================================
function Restore_Health takes nothing returns nothing
    local trigger Restore = CreateTrigger()
    call TriggerRegisterPlayerEventEndCinematic( Restore, Player(0) )
    call TriggerAddAction( Restore, function Heal )
endfunction


ty
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
CSData is a very lightweight attachment system, and that is the reason that I recommend it. Others might be a bit complicated to learn. I haven't tried them all, but HSAS, HAIL, PUI, and Game Cache all have a bigger learning curve.

CSData is actually part of the Caster System by Vexorian, although it can be used on its own. Here's the vJASS version of the system:

JASS:
library CSData

    //****************************************************************************************************
    // CSData 15.2
    // ¯¯¯¯¯¯¯¯¯¯¯
    // CSDatas are like UserData in units and items, they are faster than gamecache unless you have more
    // than 8191 handles in your map. In that case it would be a little slower but only for those
    // handles. And if you have more than 8191 handles your map is too slow already anyways.
    //
    // Notice that for public spells or systems to be distributed you should only use these
    // for private objects (those who the mapper would never have access to) If you are making something
    // for your map you can use them wherever you want.
    //
    // Best to be used in conjunction to CSArrays so you just specify an array id for a handle.
    //
    // DO NOT USE THIS ON THESE HANDLE TYPES: -lightning, -ubersplat, -image, -texttag,
    //                                        -any &#039;argument&#039; handle (like playerstate, damagetype, etc)
    //
    //****************************************************************************************************

    //====================================================================================================
    globals
        private constant integer MAX_HANDLE_ID_COUNT = 50000
        // values lower than 8191: very fast, but very unsafe.
        // values bigger than 8191: not that fast, the bigger the number is the slower the function gets
        // Most maps don&#039;t really need a value bigger than 50000 here, but if you are unsure, leave it
        // as the rather inflated value of 408000
    endglobals

    //=================================================================================================
    // a.k.a H2I, changed name to CS_H2I to prevent conflicts with other systems, it then stayed that
    // instead of changing to a private or public function since many outside spells use it.
    //
    function CS_H2I takes handle h returns integer
        return h
        return 0
    endfunction

    //==================================================================================================
    globals
        private integer array csdata[MAX_HANDLE_ID_COUNT]
        private constant integer MIN_HANDLE_ID=0x100000
    endglobals

    //It is dependent on jasshelper&#039;s recent inlining optimization in order to perform correctly.
    function SetCSData takes handle h, integer v returns nothing
        debug if(CS_H2I(h)-MIN_HANDLE_ID&gt;=MAX_HANDLE_ID_COUNT) then
        debug     call BJDebugMsg(&quot;SetCSData: Handle id too big, increase the max handle id count or use gamecache instead&quot;)
        debug endif
        set csdata[CS_H2I(h)-MIN_HANDLE_ID]=v
    endfunction

    function GetCSData takes handle h returns integer
        debug if(CS_H2I(h)-MIN_HANDLE_ID&gt;=MAX_HANDLE_ID_COUNT) then
        debug     call BJDebugMsg(&quot;SetCSData: Handle id too big, increase the max handle id count or use gamecache instead&quot;)
        debug endif
        return csdata[CS_H2I(h)-MIN_HANDLE_ID]
    endfunction

endlibrary


Basically, you can store one struct attached to a handle. This makes it not so useful for storing on units, if you have multiple spells (it was also considered unsafe in some tests, though I've never had the errors).

However, it's great for timers that are created for every instance of a spell.

Import (copy&paste) this library into a trigger called "CSData".

Then, when you want to attach a struct to a handle, simply use the SetCSData function like so:

JASS:
call SetCSData(MyObject,MyStruct)


Then, when you want to get the struct back from the handle, use the GetCSData function like so:

JASS:
local STRUCT s = GetCSData(MyObject)


I still had many questions I wanted to ask, but the thread hasn't been looked at for a long long time so I didn't bother posting.

Go ahead and post them here. Reviving an old thread that is yours is also fine, considering your questions were never answered, and you were the original poster.

JASS:
Do you have any suggestions on where I could go to sharpen my knowledge of what I know thus far, and possibly slowly edge myself closer to using the more advanced attachment systems that you mentioned?


I'm not too sure of where you are at as far as JASS goes. The best way would be to start with a basic version of what you want to make. If you want to make spells, start with a very basic spell: one that creates a stomp affect at the caster, for instance.

Then, move on, with one that is a bit more complicated, such as one that decreases a unit's health to 0 over time. It doesn't have to be realistic, it's just practice. (Or you could be a little creative and make it better). You can do this by using a repeating Timer, and using the TimerStart function. This lets you start a timer that runs a function every time it expires.

The TimerStart function is actually the key to replacing waits and periodic events, as it allows you to attach a struct you create at the first cast of the spell to the timer, and the get the attached struct back with the "GetExpiredTimer()" function.

Here's a Sample Spell Template for you to look at:

JASS:
scope SampleSpell initializer Init

private struct Data //Just a sample struct, for an example
    unit c
    timer t
endstruct

private function Callback takes nothing returns nothing
    local Data d = GetCSData(GetExpiredTimer())
//Since the timer caused this function to run, we can get it with &quot;GetExpiredTimer()
//And use it to get the attached struct.
    //Do some stuff with the data.  This will happen every 0.05 seconds
endfunction

private function Actions takes nothing returns nothing
    local Data d = Data.create()
    set d.c = GetTriggerUnit()
    set d.t = CreateTimer()
    call SetCSData(d.t,d) //We&#039;re attaching the data struct to the timer
    call TimerStart(d.t,0.05,true,function Callback)
//The timer d.t will repeatedly start for 0.05 seconds, and run function Callback
endfunction

private function Conditions takes nothing returns boolean
    return true
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t,Condition(function Conditions))
    call TriggerAddAction(t,function Actions)
endfunction

endscope


It says that gg_unit_H000_0000 is an unidentified variable.

I don't know why. Try using the unit in a GUI trigger, converting it, and then making sure that that is right. Besides that, the trigger worked just fine in JASSCraft syntax checking.
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
ehh, you must type udg_blablabla for a global variable

Only for a User Defined Global (udg). Preplaced units have gg_TYPE_TYPEID_InstanceCount (Such as gg_unit_H000_0000), if it's a unit, item, or destructible. If it's a rect/region, camera, or something similar, it is:
gg_TYPE_NAME (Such as gg_rct_MY_RECT).

As Flare mentioned, you can also declare global blocks and globals with any name you desire, so the 'udg_' is no longer needed with vJASS.

TriggerHappy said:
You might wanna use GetWidgetLife() instead.

It is supposed to be faster. Cohadar once told me that it was the fastest native.

However, in this situation you didn't use GetUnitState(u,UNIT_STATE_LIFE). You only set currently life, and got the max life, so this does not apply.
 

Beetlebomb

New Member
Reaction score
43
Not to be too forward, but that still doesn't explain why my unit isn't recognized in the trigger.

Shes been preplaced on the map, and I've checked dozens of times by switching a trigger from GUI to JASS to see if I had the right Unit code(or unitid), but still got an error with it being an undeclared variable.

Here's the trigger:

JASS:
function Heal takes nothing returns nothing
    local unit u = gg_unit_H000_0000
    call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_MAX_LIFE))
    call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MAX_MANA))
    call DestroyEffect(AddSpecialEffect(&quot;Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl&quot;, GetUnitX(u), GetUnitY(u)))
    set u = null
endfunction

//===========================================================================
function Restore_Health takes nothing returns nothing
    local trigger Restore = CreateTrigger()
    call TriggerRegisterPlayerEventEndCinematic( Restore, Player(0) )
    call TriggerAddAction( Restore, function Heal )
endfunction


It's a simple trigger, but doesn't work because of it not knowing who it's working on.
 

emjlr3

Change can be a good thing
Reaction score
395
first off there is not need to use a local unit there - its just added fluff

secondly, in GUI, have a trigger where you just kill your preplaced unit, or something like that - convert it to custom script, and copy and paste the correct variable name from that to here, and see if it works (there is not reason that it should not)

though it seems like you have already done that - so I suggest posting the map and letting one of us have a look see

another option, when setting to max life, use some large value, like 9999., that a unit would never have in your map - it saves a function call - and does the same thing in the end
 

Beetlebomb

New Member
Reaction score
43
Ok, I did as you said and converted a trigger that would kill my preplaced unit. It came back with the same code.

I removed the local variable and just replaced everything with gg_unit_H000_0000.

For some strange bizarre reason, it's still not working.

So here's the map. Hopefully this strange problem can be solved.

P.s. I realize there are leaks on the map-- I created this map a lonnng time ago--back before I knew better.
 

Attachments

  • Sorceress.w3x
    149.2 KB · Views: 99

Azlier

Old World Ghost
Reaction score
461
Non vJass triggers require an InitTrig function.

JASS:
Restore_Health


Try changing it to InitTrig_Restore_Health?
 
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