accessing the headshot and first blood messages

Discussions about Coding and Scripting
Post Reply
gopostal

accessing the headshot and first blood messages

Post by gopostal »

Like my topic says, is it possible to access the two messages via mutator? I've been revamping the MH controller and I wanted to change announcers. I got them all with the exception of those two, since the reside in "Killed". Using TakeDamage I can get a "sometimes" replacement but it's not really good enough. Is this possible?
User avatar
Feralidragon
Godlike
Posts: 5493
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: accessing the headshot and first blood messages

Post by Feralidragon »

Regarding the HeadShot message, I think the only way possible is only by making a new gametype, since when I developed a new announcer for a jet I saw that the HeadShot message is called directly by the gametype, unlike almost all the other messages which you can change since they use a message class (so you make your own message class and then change that gametype reference to your own with a mutator or another call from another object).

Regarding the First Blood I am not sure, since I don't remember if it was in the message class or in the gametype directly like HeadShot.
gopostal

Re: accessing the headshot and first blood messages

Post by gopostal »

Thanks Ferali. I was afraid of that. Scanning through the code I have decompiled over the years I couldn't find a solution either besides what you stated.
I'd "Grrrr..." but I'm too tired. Thanks for looking at it :thuup:
Darkness
Experienced
Posts: 81
Joined: Mon Mar 01, 2010 10:12 pm
Location: Brazil

Re: accessing the headshot and first blood messages

Post by Darkness »

I'm a little late, but I think the Headshot message can be changed manually, if you set a mutator to detect the damage types that make a headshot, and replace them by another damage type.

You could use either MutatorTakeDamage or PreventDeath functions for this, and by adding a condition to identify 'decapitated' damagetype, replacing them by a new one, and upon having that, getting the message/sound you wanted. Although it may not generate the heads, but I think the 'beheaded' damagetype might generate the head and not give the standard message.


I think it's possible to keep track of first blood as well... you could set the current gametype bFirstBlood boolean to true within the mutator when it's loaded (so it would ignore the gametype's standard first blood), and make a manual firstblood detector at the mutator (using PreventDeath as well), and handle it the way you want, with its own bFirstBlood boolean at the mutator to count that.


I haven't tested them out, but I really believe it's possible (at least logically, I can say that).
gopostal

Re: accessing the headshot and first blood messages

Post by gopostal »

I actually did just what you said originally in my tries and the best I could get was two messages: the original and a replacement. Without direct access to killed you just can't do this (as far as I can tell).
Darkness
Experienced
Posts: 81
Joined: Mon Mar 01, 2010 10:12 pm
Location: Brazil

Re: accessing the headshot and first blood messages

Post by Darkness »

gopostal wrote:I actually did just what you said originally in my tries and the best I could get was two messages: the original and a replacement. Without direct access to killed you just can't do this (as far as I can tell).
I'm afraid you're wrong :rock:

Code: Select all

class CustomMessagesMutator expands Mutator;

var bool bInitialized, bFirstBlood;

function PostBeginPlay()
{	
	if ( bInitialized )
		return;
	bInitialized = True;
	Level.Game.RegisterDamageMutator(Self);
	if ( Level.Game.IsA('DeathMatchPlus') )
		DeathMatchPlus(Level.Game).bFirstBlood = True; // Ignores the default first blood
}

function bool PreventDeath(Pawn Killed, Pawn Killer,name damageType,vector HitLocation)
{
	if ( damageType == 'cmheadshot' )
	{
		Killer.ClientMessage("HEADSHOT!!! YAY!",'pickup');
//		MaleBotPlus(Killed).Playdecap(); Careful with this, just make this kind of thing if you change the HitLocation at MutatorTakeDamage or you'll have two heads flying sometimes
	}
	if ( !bFirstBlood )
	{
		Killer.ClientMessage("FIRST BLOOD!!!LOLOLOL!",'pickup');
		bFirstBlood = True;
	}

	if ( NextMutator != None )
		return NextMutator.PreventDeath(Killed,Killer,damageType,HitLocation);
	return false;
}

function MutatorTakeDamage(out int ActualDamage,Pawn Victim,Pawn InstigatedBy,
							out Vector HitLocation,out Vector Momentum, name DamageType)
{
	local int i;

	if ( damageType == 'decapitated' || damageType == 'beheaded' )
	{
		if ( Victim.Health < ActualDamage )
		{
			i = ActualDamage - Victim.Health - 1;
			ActualDamage -= i;
		}
		Victim.TakeDamage(i,InstigatedBy,HitLocation,normal(Victim.Location)*0,'cmheadshot');
		Victim.TakeDamage(ActualDamage,InstigatedBy,HitLocation,normal(Victim.Location)*0,'cmheadshot');
		ActualDamage = 0; // So it won't cause the original damage that would headshot!
	}
	if ( NextDamageMutator != None )
		NextDamageMutator.MutatorTakeDamage(ActualDamage,Victim,InstigatedBy,HitLocation,Momentum,DamageType);
}
Just tested it out.

I did the extra damage calculation to avoid "instagib"... but as it is, sometimes the head won't fly. I think to make the head fly all the time, as intended, I should cause the new damage of cmheadshot elsewhere, not on hitlocation (like, victim.location), and then apply the corrent animation (otherwise you'll end up having two heads flying, as I had).

I put the "Killer.ClientMessage" thing to test out some input from those things... seems to work fine.


EDIT: Changed a few things:

Code: Select all

//=============================================================================
// CustomMessagesMutator.
//=============================================================================
class CustomMessagesMutator expands Mutator;

var bool bInitialized, bFirstBlood;

function PostBeginPlay()
{	
	if ( bInitialized )
		return;
	bInitialized = True;
	Level.Game.RegisterDamageMutator(Self);
	if ( Level.Game.IsA('DeathMatchPlus') )
		DeathMatchPlus(Level.Game).bFirstBlood = True; // Prevent default Firstblood message
}

function bool PreventDeath(Pawn Killed, Pawn Killer,name damageType,vector HitLocation)
{
	if ( damageType == 'cmheadshot' )
	{
		if ( Killed.IsA('MaleBotPlus') )
			MaleBotPlus(Killed).Playdecap();
		else if ( Killed.IsA('FemaleBotPlus') )
			FemaleBotPlus(Killed).Playdecap();
		else if ( Killed.IsA('TournamentMale') )
			TournamentMale(Killed).Playdecap();
		else if ( Killed.IsA('TournamentFemale') )
			TournamentFemale(Killed).Playdecap();
		// Force behead!!!
		HitLocation = Killed.Location; // Prevent standard random behead
		Killer.ClientMessage("HEADSHOT!!! YAY!",'pickup'); // Message you want
	}
	if ( !bFirstBlood )
	{
		Killer.ClientMessage("FIRST BLOOD!!!LOLOLOL!",'pickup'); // Message you want
		bFirstBlood = True;
	}

	if ( NextMutator != None )
		return NextMutator.PreventDeath(Killed,Killer,damageType,HitLocation);
	return false;
}

function MutatorTakeDamage(out int ActualDamage,Pawn Victim,Pawn InstigatedBy,out Vector HitLocation,out Vector Momentum,name DamageType)
{
	local int i;

	if ( damageType == 'decapitated' || damageType == 'beheaded' )
	{
		if ( ActualDamage > Victim.Health ) // Try to prevent Gibb...
		{
			i = ActualDamage - Victim.Health - 1;
			ActualDamage -= i;
			Victim.TakeDamage(i,InstigatedBy,HitLocation,normal(Victim.Location)*0,'cmheadshot');
		}
		if ( ActualDamage > 100 ) // Prevent Gibb once more...
		{
			Victim.TakeDamage(100,InstigatedBy,HitLocation,normal(Victim.Location)*0,'cmheadshot');
			ActualDamage -= 100;
		}
		Victim.TakeDamage(ActualDamage,InstigatedBy,HitLocation,normal(Victim.Location)*0,'cmheadshot');
		ActualDamage = 0;
	}
	if ( NextDamageMutator != None )
		NextDamageMutator.MutatorTakeDamage(ActualDamage,Victim,InstigatedBy,HitLocation,Momentum,DamageType);
}
As far as I've tested, beheading works fine now, and it's never gibbed too.

I've attached the mutator I've done. Try it out (although the last code here has 2 fixes the mutator hasn't, but are minor things).


EDIT2: well, sometimes it still gibs, sometimes it still drops two heads. Lol. I could get rid of the messages, BUT... I'm not sure how to fix this easily. To do that the MutatorTakeDamage should be really complete, including searching for armor and calculating if it would kill or not - if won't kill, hit at head (for hud hit display), otherwise hit elsewhere (and prevent in-game behead). Changing HitLocation at PreventDeath doesn't seem to do any good.
Attachments
CustomMessages.zip
(2.29 KiB) Downloaded 100 times
gopostal

Re: accessing the headshot and first blood messages

Post by gopostal »

Very interesting take on this, well done on the progress. Don't worry too much though. I'm going to go around all this and rework the central gametype so I can just use killed and be done with it :)
Post Reply