Health on kill [Solved]

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
Tempo
Recruit Womprat Killer
Posts: 12
Joined: Mon Jan 04, 2021 10:22 pm
Projects :: No Mod project currently.
xbox live or psn: No gamertag set

Health on kill [Solved]

Post by Tempo »

Can I add something to the mission script so that when a specific class kills an enemy they get a certain amount of health? There was an old post that felt close to this (http://www.gametoast.com/viewtopic.php? ... ll#p305671), but I couldn't quite figure it out based on that
Last edited by Tempo on Thu Apr 15, 2021 3:36 pm, edited 1 time in total.
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

Re: Health on kill

Post by Sporadia »

You can do it inside an OnCharacterDeath(function(charIndex, charIndex)) event:

Code: Select all

OnCharacterDeath(
	function(playerIndex, killerIndex)
		-- code here
	end
)
Then you do the following:
  1. Check that the killer is still alive.
  2. Check that the killer is on a specific team.
  3. Check that the dead character (player) was on a different team.
  4. Check that the killer is a specific class (has to be done after checking the killer's team).

Code: Select all

local killerTeam = GetCharacterTeam(killerIndex)
local killerData = GetCharacterUnit(killerIndex) -- returns nil if killer is dead, returns the killer's objectData if killer is alive
if killerData then -- check that the killer is alive
	if killerTeam == 1 then -- check the killer is on team 1
		if killerTeam != GetCharacterTeam(playerIndex) then -- check for a team kill
			if GetCharacterClass(killerIndex) == 5 then -- check that the killer is class 5
				-- code here
			end
		end
	end
end

Using GetCharacterClass(charIndex)
Hidden/Spoiler:
GetCharacterClass(charIndex) is a bit weird so I'll try explain how it works. Every class on each team is given a number, starting with 0. In the mission lua, you add the classes inside of ScriptInit(). You might do this with AddUnitClass() or you might do it with SetupTeams(). If you use AddUnitClass(), then the first line of AddUnitClass() will be class 0, the second line will be class 1, the next line will be class 2 and so on.

If you use SetupTeams(), it actually calls a bunch of AddUnitClass() functions, but it does it in this order: soldier, pilot, assault, sniper, marine, engineer, officer, special. These classes are always added in the same order, and any class that you don't add won't be given a number. So for example if you only had an assault, soldier and marine on a team: the soldier will be class 0, the assault will be class 1 and the marine will be class 2.

The hero is added last (normally) with SetHeroClass(). So a for a team with 3 regular units (class 0, 1, 2), the hero would be added as class 3. For a team with 6 regular units, the hero is added as class 6 etc. Each team has a separate set of class numbers, starting at 0. If you want to check what number a specific class is, you can also just count where it appears on the spawn select screen (class 0 is at the top of the screen).

GetCharacterClass(charIndex) returns the class number of a player, so you need to know what class number you're looking for. If you use it on a dead player, you might get the class number for the unit they just played as, or you might get the number of the unit they're going to play as when they next spawn. I think that's a but unreliable. But on living players it works fine.

Here's some example code for finding class numbers:

Code: Select all

SetupTeams{
	rep = {	
		team = REP,
		units = 32,
		reinforcements = 150,
		soldier  = { "rep_inf_ep3_rifleman", 7, 25}, -- rep class 0
		engineer = { "rep_inf_ep3_engineer", 1, 4}, -- rep class 1
		special  = { "rep_inf_ep3_jettrooper", 1, 4}, -- rep class 2
	},
	cis = {
		team = CIS,
		units = 32,
		reinforcements = 150,
		sniper   = { "cis_inf_sniper", 1, 4}, -- cis class 1
		soldier  = { "sep_inf_rifleman", 7, 25}, -- cis class 0
		special  = { "cis_inf_droideka", 1, 4}, -- cis class 3
		officer  = { "sep_inf_officer", 1, 4}, -- cis class 2
	}
}

AddUnitClass(REP, "rep_inf_ep3_rocketeer", 1, 4) -- rep class 3
AddUnitClass(CIS, "cis_inf_marine", 1, 4) -- cis class 4

SetHeroClass(REP, "rep_hero_macewindu") -- rep class 4
SetHeroClass(CIS, "cis_hero_darthmaul") -- cis class 5

Finally you add more health. I'd use GetObjectHealth(objectData) and SetProperty(objectData, odfparameters):

Code: Select all

local killerHealthTable = {GetObjectHealth(killerData)}
if killerHealthTable[1] <= (killerHealthTable[2] + 80) then -- if CurHealth is less than (MaxHealth + 80)
	local newHealth = killerHealthTable[1] + 80 -- add 80 health to CurHealth
	SetProperty(killerData, "CurHealth", newHealth)
elseif killerHealthTable[1] < killerHealthTable[2] then -- elseif CurHealth is only slightly less than MaxHealth
	SetProperty(killerData, "CurHealth", killerHealthTable[2]) -- set CurHealth to MaxHealth
end

To better explain GetObjectHealth() (I write charUnit instead of objectData in this post, but they're the same thing): http://www.gametoast.com/viewtopic.php?p=537695#p537695

Full thing looks something like this:

Code: Select all

OnCharacterDeath(
	function(playerIndex, killerIndex)
		local killerTeam = GetCharacterTeam(killerIndex)
		local killerData = GetCharacterUnit(killerIndex) -- returns nil if killer is dead, returns the killer's objectData if killer is alive
		
		-- filters
		if killerData then -- check that the killer is alive
			if killerTeam == 1 then -- check the killer is on team 1
				if killerTeam != GetCharacterTeam(playerIndex) then -- check for a team kill
					if GetCharacterClass(killerIndex) == 5 then	-- check that the killer is class 5
					
						local killerHealthTable = {GetObjectHealth(killerData)}
						if killerHealthTable[1] <= (killerHealthTable[2] + 80) then	-- if CurHealth is less than (MaxHealth + 80)
							local newHealth = killerHealthTable[1] + 80		-- CurHealth + 80
							SetProperty(killerData, "CurHealth", newHealth)
						elseif killerHealthTable[1] < killerHealthTable[2] then	-- elseif CurHealth is only slightly less than MaxHealth
							SetProperty(killerData, "CurHealth", killerHealthTable[2]) -- set CurHealth to MaxHealth
						end
						
					end -- filters
				end
			end
		end -- filters end
	end -- function end
) -- event end
Tempo
Recruit Womprat Killer
Posts: 12
Joined: Mon Jan 04, 2021 10:22 pm
Projects :: No Mod project currently.
xbox live or psn: No gamertag set

Re: Health on kill

Post by Tempo »

Every time I try munging this I get the error message " `then' expected near `!' ". And I have no experience with events so I'm not 100% sure where to put this in the script? I've tried a couple places but some other posts seem to suggest it's put at the end of function ScriptPostLoad(). But the failed munge seems to prevent it from working regardless.
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

Re: Health on kill

Post by Sporadia »

Oh there's just a syntax mistake in my example. I've used != as a not equal sign, but in lua the correct symbol is ~=

Edit: Also I've just seen on another thread that there's an alternative way to check the character's class. You can compare GetEntityClass(objectData) with FindEntityClass(string) because they both return the same kind of data. Like this:

Code: Select all

if GetEntityClass(killerData) == FindEntityClass("rep_inf_ep3_rifleman") then
    -- code here
end
This might be simpler than checking the class number.
Tempo
Recruit Womprat Killer
Posts: 12
Joined: Mon Jan 04, 2021 10:22 pm
Projects :: No Mod project currently.
xbox live or psn: No gamertag set

Re: Health on kill

Post by Tempo »

ah, ok. Yeah that worked. I know a little more about java than lua so I was really confused why it didn't like that. Thanks for the help! (But just in case someone else wants to know later, I had to change "if killerHealthTable[1] <= (killerHealthTable[2] + 80)" to "if killerHealthTable[1] <= (killerHealthTable[2] - 80)" unless you want your unit to be able to surpass their max health with the health steal.)
Post Reply