• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Getting a hero's max HP

Status
Not open for further replies.
Level 5
Joined
Sep 19, 2007
Messages
97
I'm having trouble finding a WC3 trigger or Jass function that will allow me to get a hero's maximum hit points.

I want something like this..

GetUnitMaxLife(unit whichunit) return real

If my unit's life is 400/700, I'm looking for a function that would return 700.
 
Level 5
Joined
Sep 19, 2007
Messages
97
You dont 'get' values in GUI. But you can add it as a Condition. Everything with Life/mana/gold/lumber is called Property.

Go conditions-unit-property- and change it to 'max life' or such.

Please, rep, if this has helped.

Since Unholy Auras healing effects don't stack, I'm trying to create my own stacking healing item.

The item I want to create would add 1% to a players health per second.

So every second I want to do

Unitshealth = UnitsHealth + (MaximumHP/100)

Anyone know the jass code that could do this? I already have the conditions setup for checking if the player is holding the item. Just need the health code.
 
Level 5
Joined
Sep 19, 2007
Messages
97
IamtheRper's solution worked, but 0.01 (or 1%) is as low as the world editor will let me go for "Data - Ammount of HP regenerated". Unfortunately, I need it to be around .005 or lower (.5%) for it to be balanced on my map.

I guess I'm back to the jass option.

So every second I want to do

Unitshealth = UnitsHealth + (MaximumHP/200)

Anyone know the jass code that could do this?
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
Get the heroes max HP?
I mean come on you use the same native as for normal units and it automatically counts the heroes max HP. You simply get their max life state.
If it does not count the str bonous (which I am sure it does) you can get hero str and do maths based on that.

Remember that life and max life is a real.
 
Level 4
Joined
Nov 25, 2008
Messages
76
I'm not good at this whole deal yet but, wouldn't that be a bad idea? A trigger running every 0.1 seconds every time checking for a condition sounds bad in theory. Then again I have little experience.
 
Level 5
Joined
Sep 19, 2007
Messages
97
Ok, I think I'm close to figuring this out. Have an error I can't figure out though on the 1st if statement.

Error 9670: Invalid type for specified operator
udg_units01[] contains the hero unit ID for each player.
'I02R' is the item ID

JASS:
//===========================================================================
//Trigger:itemhealthgain
//===========================================================================
function Trig_itemhealthgain_Actions takes nothing returns nothing
	set bj_forLoopAIndex=1
	set bj_forLoopAIndexEnd=12
	loop
		exitwhen bj_forLoopAIndex>bj_forLoopAIndexEnd
		if(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],1)=='I02R')then
			set tempstr=GetHeroStatBJ(bj_HEROSTAT_STR, udg_units01[bj_forLoopAIndex],true)
			SetUnitLifeBJ(GetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE)+tempstr)
		endif
		if(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],2)=='I02R')then
			set tempstr=GetHeroStatBJ(bj_HEROSTAT_STR, udg_units01[bj_forLoopAIndex],true)
			SetUnitLifeBJ(GetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE)+tempstr)
		endif
		if(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],3)=='I02R')then
			set tempstr=GetHeroStatBJ(bj_HEROSTAT_STR, udg_units01[bj_forLoopAIndex],true)
			SetUnitLifeBJ(GetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE)+tempstr)
		endif
		if(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],4)=='I02R')then
			set tempstr=GetHeroStatBJ(bj_HEROSTAT_STR, udg_units01[bj_forLoopAIndex],true)
			SetUnitLifeBJ(GetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE)+tempstr)
		endif
		if(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],5)=='I02R')then
			set tempstr=GetHeroStatBJ(bj_HEROSTAT_STR, udg_units01[bj_forLoopAIndex],true)
			SetUnitLifeBJ(GetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE)+tempstr)
		endif
		if(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],6)=='I02R')then
			set tempstr=GetHeroStatBJ(bj_HEROSTAT_STR, udg_units01[bj_forLoopAIndex],true)
			SetUnitLifeBJ(GetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE)+tempstr)
		endif
		set bj_forLoopAIndex=bj_forLoopAIndex+1
	endloop
endfunction
 
Level 4
Joined
Nov 25, 2008
Messages
76
JASS:
function SetUnitLifeBJ takes unit whichUnit, real newValue returns nothing

JASS:
GetUnitState        takes unit whichUnit, unitstate whichUnitState returns real

Basically, get unitstate returns a real for SetUnitLifeBJ function's first parameter opposed to what you need, a unit.
 
Level 5
Joined
Nov 14, 2007
Messages
161
the native:
JASS:
SetUnitState takes unit whichUnit, unitstate whichUnitState, real newVal
is probably what u want


u is the unit you are effecting, change that depending on your global/local (globals use "udg_")
the unit state is the units life obviously thats the "UNIT_STATE_LIFE"
the * #.### is how much you want to change it. 1.005 is increasing 1/2%, 1.0 is no change, .995 is decreasing 1/2%, etc etc etc

JASS:
call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_LIFE) * 1.005)

i believe that is what you are wanting.

YO_MA_MA

EDIT: i first converted triggers like what you are doing, but learn what BJs are pointless (they just call the exact same function and waste time) and other ways to improve on your code. jass can be way more optimized then gui, but it just takes time.
 
Level 6
Joined
Mar 20, 2008
Messages
208
JASS:
function Trig_itemhealthgain_Actions takes nothing returns nothing	
    local integer s = 0        //start integer
    local integer e = 12      //when the loop ends
    local real temp = 0       //temporary to reduce system calls

loop
     exitwhen s > e      //loops through 0 to 11

     if(UnitHasItem(udg_units01[start]), 'I02R') then
        set temp = GetUnitState(udg_units01[start], UNIT_STATE_LIFE)
        call SetUnitState(temp, temp + GetUnitState(udg_units01[start]), UNIT_STATE_MAX_LIFE)*.005 )
    endif
    //this checks if the unit has the item, if it does, it adds .5% 
    //of the units maximum life to its current life.

endloop

That should workout well, barring any spelling/coding errors.....But you should figure out how to get healing effects to stack for the sake of speed.

I'm not sure if it will take an integer instead of an item when it is checking the slots.
 
Level 5
Joined
Sep 19, 2007
Messages
97
Thank you all for you ideas and help!!!

Here is my final working code

JASS:
//===========================================================================
//Trigger:itemhealthgain
//===========================================================================
function Trig_itemhealthgain_Actions takes nothing returns nothing
	set bj_forLoopAIndex=1
	set bj_forLoopAIndexEnd=12
	loop
		exitwhen bj_forLoopAIndex>bj_forLoopAIndexEnd
		if(GetItemName(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],1))=="Dark Elven Blood Forged Guantlets")then
			call SetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE,GetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE) * 1.005)
		endif
		if(GetItemName(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],2))=="Dark Elven Blood Forged Guantlets")then
			call SetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE,GetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE) * 1.005)
		endif
		if(GetItemName(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],3))=="Dark Elven Blood Forged Guantlets")then
			call SetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE,GetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE) * 1.005)
		endif
		if(GetItemName(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],4))=="Dark Elven Blood Forged Guantlets")then
			call SetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE,GetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE) * 1.005)
		endif
		if(GetItemName(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],5))=="Dark Elven Blood Forged Guantlets")then
			call SetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE,GetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE) * 1.005)
		endif
		if(GetItemName(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],6))=="Dark Elven Blood Forged Guantlets")then
			call SetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE,GetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE) * 1.005)
		endif
	//	if(GetItemName(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],0))=="Dark Elven Blood Forged Guantlets")then
	//		call SetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE,GetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE) * 1.005)
	//	endif
		set bj_forLoopAIndex=bj_forLoopAIndex+1
	endloop
endfunction
//===========================================================================

EDIT: changed it to this, so it was linear

JASS:
//===========================================================================
//Trigger:itemhealthgain
//===========================================================================
function Trig_itemhealthgain_Actions takes nothing returns nothing
	set bj_forLoopAIndex=1
	set bj_forLoopAIndexEnd=12
	loop
		exitwhen bj_forLoopAIndex>bj_forLoopAIndexEnd
		set udg_tempmultiplier=0
		if(GetItemName(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],1))=="Dark Elven Blood Forged Guantlets")then
			set udg_tempmultiplier=udg_tempmultiplier+1
		endif
		if(GetItemName(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],2))=="Dark Elven Blood Forged Guantlets")then
			set udg_tempmultiplier=udg_tempmultiplier+1
		endif
		if(GetItemName(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],3))=="Dark Elven Blood Forged Guantlets")then
			set udg_tempmultiplier=udg_tempmultiplier+1
		endif
		if(GetItemName(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],4))=="Dark Elven Blood Forged Guantlets")then
			set udg_tempmultiplier=udg_tempmultiplier+1
		endif
		if(GetItemName(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],5))=="Dark Elven Blood Forged Guantlets")then
			set udg_tempmultiplier=udg_tempmultiplier+1
		endif
		if(GetItemName(UnitItemInSlotBJ(udg_units01[bj_forLoopAIndex],6))=="Dark Elven Blood Forged Guantlets")then
			set udg_tempmultiplier=udg_tempmultiplier+1
		endif
		call SetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE,GetUnitState(udg_units01[bj_forLoopAIndex],UNIT_STATE_LIFE) * (1+(.003*udg_tempmultiplier)))
		set bj_forLoopAIndex=bj_forLoopAIndex+1
	endloop
endfunction
//===========================================================================
 
Last edited:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
Unefficent code.

Possiable improvements are the removal of BJ functions and using only natives as they tend to be quite a bit faster as it avoids executing unneeded code.
Using a better loop method where the exit statement uses a constant and 1 variable as apposed to 2.
Also for neatness you could have a second loop that loops through each slot, but this may be slower than the current check each slot separatly.
And finally you could optimize the SetUnitState line a bit which actually makes little sense already. Why is the life regen rate exponential as currently it uses the units current health so it will regen less when the unit is at lower health than at max life? I thought you wanted to use UNIT_STATE_MAX_LIFE (or something simlar) to get the unit's maximum life and base it on that. Anyway with the formula remeber BODMAS as you might be able to remove a few brackets.
 
Last edited:
Level 6
Joined
Mar 20, 2008
Messages
208
Unefficent code.

Possiable improvements are the removal of BJ functions and using only natives as they tend to be quite a bit faster as it avoids executing unneeded code.
Using a better loop method where the exit statement uses a constant and 1 variable as apposed to 2.
Also for neatness you could have a second loop that loops through each slot, but this may be slower than the current check each slot separatly.
And finally you could optimize the SetUnitState line a bit which actually makes little sense already. Why is the life regen rate exponential as currently it uses the units current health so it will regen less when the unit is at lower health than at max life? I thought you wanted to use UNIT_STATE_MAX_LIFE (or something simlar) to get the unit's maximum life and base it on that. Anyway with the formula remeber BODMAS as you might be able to remove a few brackets.

I already rewrote it for him.....no one reads threads anymore :thumbs_up:
 
Status
Not open for further replies.
Top