Tracking kills in Single Player

A refuge for those migrating from the fallen DXEditing.com and a place for general discussion relating to Deus Ex editing (coding, mapping, etc).
Post Reply
Whiplash
Thug
Posts: 29
Joined: Fri Jun 05, 2009 9:50 pm

Tracking kills in Single Player

Post by Whiplash »

Yo,

I'm currently working on a Single Player mod and while most of what I need is covered in tutorials or I've been able to glean from looking at DXSP maps in UnrealEd, there is one thing I can't find anywhere and need advice on urgently. I am hoping that some of the original TNM team are still here :)

Essentially my problem is this: for my mod, it's going to be a simple JC vs MJ12 in many respects. So the goals will generally revolve around "securing" an area, by that I mean eliminating all of MJ12s troops and robots.

The problem is that while I've seen instances where something happens when you kill a bunch of people in a group (like in vanilla DX you have to take down all the NSF in the subway, or Paul gets mad at you if you kill too many NSF on Liberty Island, or in TNM where King Kashue gets pissed off at you if you kill too many Goats in Goat City.

Essentially, I need to make something happen, such as a dispatcher trigger fire, when the player dismantles an entire enemy force. But there doesn't seem to be a tutorial covering this, examing the SP maps doesn't help much, and I don't know how to do this :( I would be grateful for any help.

Incidentally, but this is much less important, my mod will also have a training session during the game, I would like to one thing that the training maps in SP and TNM did, which is to give the player specific skill upgrades (as opposed to skill points) as part of an infolink message or other triggered action. You know, like Gunther Hermann did at the rifle range and one of the PDX mods did for Trestkon with the lethal gloves.
Cybernetic pig
Illuminati
Posts: 2284
Joined: Thu Mar 08, 2012 3:21 am

Re: Tracking kills in Single Player

Post by Cybernetic pig »

If you're a programmer look in the mission scripts to see how it was done vanilla. If you're just making your mod via unreal editor, use the counter trigger which you can use to count the number of killed/KO'ed enemies and fire an event upon reaching the desired count. Take note that the trigger has no means to determine whether lethal or non-lethal methods were used however, and it also cannot be used to trigger events in other maps without the use of flags (which require mission scripting).
Hanfling
MJ12
Posts: 406
Joined: Sun Oct 04, 2009 6:54 pm

Re: Tracking kills in Single Player

Post by Hanfling »

I use the following code in my GameInfo for HX to keep track of the leathel/non lethel kills. It might not handle indirect kills such as blowing up an explosive crate, but should be a start. You might want to extend the update of the PlayerReplicationInfo to also update an int flag in the Flagbase to keep track of it. However scoreboard alongside counting kills and non leathel kills did never had a high priority and thus the code might not be the best or working always right, so keep that in mind.

HXGameInfo.uc

Code: Select all

// ---------------------------------------------------------------------
// Killed()
// ---------------------------------------------------------------------

function Killed( pawn Killer, pawn Other, name damageType )
{
	local String Message;
	local Pawn CurPawn;

	if ( Other.bIsPlayer )
	{
		if ( Killer!=None && !Killer.bIsPlayer )
		{
			if ( Level.NetMode!=NM_Standalone )
			{
				Message = Other.PlayerReplicationInfo.PlayerName$Killer.KillMessage( DamageType, Other );
			}
		}

		if ( Killer==Other || Killer==None )
		{
			switch ( DamageType )
			{
				case 'Fell':
					Message = Other.PlayerReplicationInfo.PlayerName $ " left a small crater.";
					break;
				case 'Drowned':
					Message = Other.PlayerReplicationInfo.PlayerName $ " forgot to come up for air.";
					break;
				case 'Exploded':
					if ( Killer==None )
						Message = Other.PlayerReplicationInfo.PlayerName $ " was blown up.";
					else
						Message = Other.PlayerReplicationInfo.PlayerName $ " blow himself up.";
					break;
				case 'Burned':
				case 'Flamed':
					Message = Other.PlayerReplicationInfo.PlayerName $ " was incinerated.";
					break;
				case 'HeliBlade':
					Message = Other.PlayerReplicationInfo.PlayerName $ " jumped into a helicopter blade.";
					break;
				case 'AutoShot':
					Message = Other.PlayerReplicationInfo.PlayerName $ " ran into an AutoTurret.";
					break;
				case 'stomped':
					Message = Other.PlayerReplicationInfo.PlayerName $ " forgot to come up for air.";
					break;

				default:
					Message = Other.PlayerReplicationInfo.PlayerName $ " had a sudden heart attack.";
					break;
			}
		}
		else
		{
			if ( Killer.bIsPlayer )
			{
				if ( HXPlayerPawn(Other).KillProfile.MethodStr~="None" )
					Message = Killer.PlayerReplicationInfo.PlayerName$" killed "$Other.PlayerReplicationInfo.PlayerName$".";
				else
					Message = Killer.PlayerReplicationInfo.PlayerName$" killed "$Other.PlayerReplicationInfo.PlayerName $ HXPlayerPawn(Other).KillProfile.MethodStr;
			}
		}
	}

	if ( Message!="" )
	{
		//Add to console log as well (with pri id) so that kick/kickban can work better.
		Log( Message );
		
		for ( CurPawn = Level.PawnList; CurPawn != None; CurPawn = CurPawn.NextPawn )
			if ( CurPawn.IsA('HXPlayerPawn') && DeusExPlayer(CurPawn).bAdmin )
				HXPlayerPawn(CurPawn).LocalLog( Message );

		BroadCastMessage( Message, False, 'DeathMessage' );
	}

	//if ( Other.bIsPlayer )
		//HandleDeathNotification( Killer, Other );

	// death and streak counter
	Other.DieCount++;

	if ( Other.bIsPlayer )
	{
		Other.PlayerReplicationInfo.Deaths += 1;
	}

	// Suicide? (maybe killed by autoturret too).
	if ( Killer==Other || Killer==None )
	{
		if ( Other.isA('HXPlayerPawn') )
		{
			// Don't dock them if it nano exploded in their face
			if ( !(HXProjectile(HXPlayerPawn(Other).MyProjKiller)!=None && HXProjectile(HXPlayerPawn(Other).MyProjKiller).bAggressiveExploded ))
				Other.PlayerReplicationInfo.Score -= 1;
		}
	}
	// Player killed Player.
	else if ( Killer!=None && Other!=None && Killer.bIsPlayer && Other.bIsPlayer )
	{
		Killer.KillCount--;

		if ( Killer.PlayerReplicationInfo!=None )
		{
			Killer.PlayerReplicationInfo.Score -= 1;
		}
	}
	// Scriptedpawn killed ( or maybe even player by scripted pawn).
	else if ( Killer!=None )
	{
		if ( DamageType=='KnockedOut' || DamageType=='Stunned' )
		{
			if ( Killer.PlayerReplicationInfo!=None )	
				Killer.PlayerReplicationInfo.Streak += 1; // Streak is used for knocked out.
		}
		else
		{
			Killer.KillCount++;
			if ( Killer.PlayerReplicationInfo!=None )
				Killer.PlayerReplicationInfo.Score += 1;
		}
	}

	ScoreKill( Killer, Other );
}

// ----------------------------------------------------------------------
// ScoreKill()
// ----------------------------------------------------------------------

function ScoreKill( Pawn Killer, Pawn Other )
{
	BaseMutator.ScoreKill( Killer, Other );
}
I demand my DXE User ID back. Launcher for DeusEx, Rune, Nerf, Unreal & Botpack. HX on Mod DB. Revision on Steam.
Whiplash
Thug
Posts: 29
Joined: Fri Jun 05, 2009 9:50 pm

Re: Tracking kills in Single Player

Post by Whiplash »

I'm afraid my scripting skills are limited to copying scripts and hoping I put them in the right place :oops:

So that Counter thing sounds like what I need to be using. I assume that's in the actors menu *Triggers > *Counter

Next dumb question, how do I actually use the counter? My team of enemies will comprise of troops, commandos M/WIBs and MJ12-allied robots. So the player will have to disable all of them, the means are not important, I could live with the limitation of not being able to distinguish between lethal/non-lethal takedowns. Would I need different counters for the troops and the bots? Or can I "attach" enemies by alliance to the counters? Is the counter mechanism foolproof, e.g. if the enemies dies in some weird way, like drowning, crusing, secondary explosion, or in the case of bots, EMP damage, does that have any

I manipulate flags entirely in conedit files, and use conversations as dispatchers too (probably not the best practice but it works) I'm not worried about anything else other than triggering something (dispatcher trigger, infolink trigger) on the system picking up that the levels' goal has been accomplished.

If I did want to look at the original script (e.g. the Subway/NSF mission) how would I get to that?
Cybernetic pig
Illuminati
Posts: 2284
Joined: Thu Mar 08, 2012 3:21 am

Re: Tracking kills in Single Player

Post by Cybernetic pig »

Whiplash wrote: So that Counter thing sounds like what I need to be using. I assume that's in the actors menu *Triggers > *Counter
Yes.
Next dumb question, how do I actually use the counter?
Place counter in the world if you haven't already.
Right click the counter.
Properties.
Tag = "Counterx" (type "counterx" (without quotes) in the tag property/variable).

Right click the desired NPC.
Properties.
Event = "Counterx"

when the NPC dies it will send an event to the counter, defined by the counter's tag. Match the event of the sender to the tag of the receiver. This is the basics of the trigger system. Note that "counterx" doesn't have to be used, it can be any string as long as they match.

Now click on the counter and adjust it's "counter" properties. Should be simple to understand. Get it to fire it's own event when it has received enough events of its own (from the NPC deaths).

The NPCs only fire their event upon death/K.O. so you'll be fine in that regard. However, it won't account for the event instigator (so if someone else were to kill the NPC it will still count), and as for bots I'm not certain if EMP disabling will count, as I think the event for pawns (NPCs) is only fired upon destroy()/death, but you can test that for yourself easily.

You can get creative with triggers/events to achieve your goal via unconventional means, but they are generally very limiting and if you're making your own missions that intend to imitate Deus Ex's depth to even half that extreme it is best you learn coding or find someone who codes.
If I did want to look at the original script (e.g. the Subway/NSF mission) how would I get to that?
Export all classes via UnrealEd and then look at the contents of Mission02.uc in notepad OR right click on the mission02 class in UnrealEd if you manage to find it (it is a child of MissionScript), although be warned the vanilla method for tracking non-lethal/lethal was bugged/inconsistent. It has been fixed in my mod, however.

Also, to learn all the basics/intermediate stuff of the unreal editor (with DX's features) follow Tack's tutorials.
Post Reply