Lua Tip: GetObjectHealth and GetObjectShield

In this forum you will find and post information regarding the modding of Star Wars Battlefront 2. DO NOT POST MOD IDEAS/REQUESTS.

Moderator: Moderators

Post Reply
Sporadia
Corporal
Corporal
Posts: 151
Joined: Thu Jan 24, 2019 11:02 pm
Projects :: No Mod project currently
Games I'm Playing :: None
xbox live or psn: No gamertag set

Lua Tip: GetObjectHealth and GetObjectShield

Post by Sporadia »

I'm posting this within about 5 minutes of discovering it. It might be something everybody else knows already but I haven't seen it pointed out before. I used to think GetObjectHealth only returned a number, because that's how it's used in every example I've seen. If you want to find a unit's current health, and you have the "charUnit" (the userdata that exists for an individual spawned unit), then you just do this:

Code: Select all

local currentHealth = GetObjectHealth(charUnit)
And that fetches the unit's current health as a number, and stores it in currentHealth. Some of the stock missions do this and it's all I thought the line was good for.

But I was playing around with something else and had the line print("GetObjectHealth(charUnit)", GetObjectHealth(charUnit)) inside an event. I was fully expecting it to just print individual numbers, but instead I was seeing things like this:

Code: Select all

GetObjectHealth(charUnit)        400        400        0
GetObjectHealth(charUnit)        234        400        0
GetObjectHealth(charUnit)        500        500        0
Turns out this function doesn't just fetch the current health. It actually fetches all three of the unit health values in a table (The current health, the max health and health regen: AddHealth). GetObjectShield does the same.

So if you ever want to find a unit's health regen, max health or shield regen etc, here's the proper way to code it:

Code: Select all

local charHealth = {GetObjectHealth(charUnit)}
local charShield = {GetObjectShield(charUnit)}
These lines will fetch all three health parameters and save them in the table charHealth, and fetch all three shield parameters and save them in the table charShield. The current health/shield would be inside the first element of the table. The max health/shield is in the second and the regen is in the third. So if you want the current health, it's stored inside of charHealth[1], the shield regen is in charShield[3] etc.

Since people might be asking what charUnit is, here's the run down on finding units with the lua.
Hidden/Spoiler:

Every human and AI player is assigned a number at the start of the match. This is called a 'character index'. It's a different number for each player. Normal matches go from 0 - 64 or 0 - 63 or something like that. The upper number is determined by the mission's player and AI limits. In singleplayer, the human is typically assigned the index 0.

When you have an event like CharacterDeath, these events will give you the character index so you can track what player died, what player killed them etc. OnCharacterDeath looks like this:

OnCharacterDeath(
function(player, killer)
-- put what you like here
end
)


In the above case, player and killer will contain the character indices of the person who died and person who killed them.

On top of this, every person on each team has an individual team member number. These typically go from 0 - 31 (so every member of the team has one). They always start at 0 (ie people on different teams can have the same team member numbers as each other, ie team 1 has a player 0 and team 2 has a different player 0). I don't use these very often, but you can use them to find a player's character index. Use GetTeamMember(team, num). team is the normal team number like team 1, team 2 etc. num is the team member number. This lua function returns the character index of that member of the team.

Here's how you would use it: If there was something you wanted to apply to every member of a team, you can cycle through them all with code like this (this is an example for team 2):

local team = 2
local teamSize = GetTeamSize(team) -- returns the number of team members on team 2

-- loop cycles through every member of the team
for i = 0, teamSize - 1 do

local charIndex = GetTeamMember(team, i) -- get this team member's character index

-- do something to the character here now that you have the character index

end -- end of loop


If a player/character has spawned, and only if they have spawned, that character will have a piece of userdata called a character unit. Characters don't have this when they're dead, so it's a good way of checking if a character is alive or not. If you have the character index, you can find the character unit with GetCharacterUnit(charIndex). If you do this command on a dead character, it will return nil. So you can do something like this:

local charUnit = GetCharacterUnit(charIndex)
if charUnit then
print("Character with index "..charIndex.." is alive. This is their unit:", charUnit) -- don't do ..charUnit because you can't truncate userdata
else
print("Character with index "..charIndex.." is dead")
end


And performing the code above on a living character will print this:
Character with index 4 is alive. This is their unit: userdata: XXXXXXXX

Some functions need to be provided with the character unit; most others need the character index. It varies. In the case of GetObjectHealth, it uses the character unit. SetProperty is a good line to know and that also uses the character unit.

Putting all of this together, this code will restore the health of every member of team 2. Imagine using it inside a timer or event or something:

local team = 2
local teamSize = GetTeamSize(team) -- returns the number of team members on team 2

-- loop cycles through every member of the team
for i = 0, teamSize - 1 do

local charIndex = GetTeamMember(team, i) -- get this team member's character index
local charUnit = GetCharacterUnit(charIndex) -- get this person's character unit

if charUnit then -- check for living characters
local charHealth = {GetObjectHealth(charUnit)}

if charHealth[1] < charHealth[2] then -- if the current health is less than the max health

SetProperty(charUnit, "CurHealth", charHealth[2]) -- heal the unit up to full

end
end

end -- end of loop


That's about it. The only other thing to be wary of is GetCharacterClass(charIndex). This doesn't give you string like you might expect, it gives you another number. But that number does tell you what class someone is playing as (in a round about way). If a team has 5 unit classes and a hero, the first class that gets added in the lua is class 0, the second unit is class 1... the hero is class 5 (immediately after the last unit). These numbers are independent for different teams again ie rep_inf_ep3_rifleman might be class 0, cis_inf_rifleman might also be class 0 and geo_inf_geonosian might also be class 0 since they're the first class added to 3 different teams.
MileHighGuy
Jedi
Jedi
Posts: 1194
Joined: Fri Dec 19, 2008 7:58 pm

Re: Lua Tip: GetObjectHealth and GetObjectShield

Post by MileHighGuy »

Thanks for taking the time to write all this out! This will make a very useful reference
Post Reply