CTF Sounds

Discussions about Coding and Scripting
User avatar
Sp0ngeb0b
Adept
Posts: 376
Joined: Wed Feb 13, 2008 9:16 pm
Location: Cologne

CTF Sounds

Post by Sp0ngeb0b »

I've learned a lot Uscript in the last months, but no way I can compare to you guys lol. So, a noob question, how can I change the CaptureSound and the Return sound in CTF games? (Without recoding the whole CTF-Gametype)
Website, Forum & UTStats

Image
******************************************************************************
Nexgen Server Controller || My plugins & mods on GitHub
******************************************************************************
User avatar
Feralidragon
Godlike
Posts: 5499
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: CTF Sounds

Post by Feralidragon »

Making something like this:

Code: Select all

var() sound NewCaptureSound[4];
var() sound NewReturnSound;
var() sound NewTakenSound[4];

function PostBeginPlay()
{
local byte i;
local FlagBase fb;

	if (Level.Game.IsA('CTFGame'))
	{
		for (i = 0; i < 4; i++)
		{
			if (NewCaptureSound[i] != None)
				CTFGame(Level.Game).CaptureSound[i] = NewCaptureSound[i];
		}
		
		if (NewReturnSound != None)
			CTFGame(Level.Game).ReturnSound = NewReturnSound;
	}
	
	ForEach AllActors(class'FlagBase', fb)
	{
		if (fb.Team < 4 && NewTakenSound[fb.Team] != None)
			fb.TakenSound = NewTakenSound[fb.Team];
	}
}
If you want to keep certain old sounds, just don't set them and this code won't set any new sound if no new sound is found. :agree1:
User avatar
Sp0ngeb0b
Adept
Posts: 376
Joined: Wed Feb 13, 2008 9:16 pm
Location: Cologne

Re: CTF Sounds

Post by Sp0ngeb0b »

You are awesome dude, thanks! :rock:
Website, Forum & UTStats

Image
******************************************************************************
Nexgen Server Controller || My plugins & mods on GitHub
******************************************************************************
User avatar
Sp0ngeb0b
Adept
Posts: 376
Joined: Wed Feb 13, 2008 9:16 pm
Location: Cologne

Re: CTF Sounds

Post by Sp0ngeb0b »

Is it also possible to play a certain sound to ALL players when the flag is taken?
Website, Forum & UTStats

Image
******************************************************************************
Nexgen Server Controller || My plugins & mods on GitHub
******************************************************************************
User avatar
Feralidragon
Godlike
Posts: 5499
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: CTF Sounds

Post by Feralidragon »

This what I came up with in some minutes, there might be another solution, but I think this one is the simplest and should work with no problems.

FIRST: You need to implement a total new class in your package, something like this:

Code: Select all

class CTFAllSoundPlayer extends Effects;

var sound TakenSound[4];

function Trigger( Actor Other, Pawn EventInstigator )
{
local PlayerPawn PP;

	ForEach AllActors (class'PlayerPawn', PP)
	{
		if (PP.PlayerReplicationInfo.Team < 4 && TakenSound[PP.PlayerReplicationInfo.Team])
			PP.ClientPlaySound(TakenSound[PP.PlayerReplicationInfo.Team]);
	}
}

defaultproperties
{
	bNetTemporary=False
	bHidden=True
}
But attention that you don't set any sounds in this actor.


SECOND: Well, there are 2 possibilities, depending on what you want to do. If you want everything in the same actor/mutator, the first code I shown to you regarding the CTFGame sounds will be like this instead:

Code: Select all

var() sound NewCaptureSound[4];
var() sound NewReturnSound;
var() sound NewTakenSound[4];

var() sound ALLPlayersTakenSound[4];

function PostBeginPlay()
{
local byte i;
local FlagBase fb;
local CTFAllSoundPlayer csp;
local PlayerStart ps;
local bool bTaglessSpawned;

	if (Level.Game.IsA('CTFGame'))
	{
		for (i = 0; i < 4; i++)
		{
			if (NewCaptureSound[i] != None)
				CTFGame(Level.Game).CaptureSound[i] = NewCaptureSound[i];
		}
			  
		if (NewReturnSound != None)
			CTFGame(Level.Game).ReturnSound = NewReturnSound;
	}
   
	ForEach AllActors(class'FlagBase', fb)
	{
		if (fb.Team < 4 && NewTakenSound[fb.Team] != None)
			fb.TakenSound = NewTakenSound[fb.Team];
	}
   
	ForEach AllActors(class'PlayerStart', ps)
	{
		ForEach AllActors(class'FlagBase', fb)
		{
			if (fb.Event == '')
				fb.Event = 'CTFTakenTag';
			
			if ((fb.Event == 'CTFTakenTag' && !bTaglessSpawned) || fb.Event != 'CTFTakenTag')
			{
				csp = Spawn(class'CTFAllSoundPlayer',, fb.Event, ps.Location);
				
				for (i = 0; i < 4; i++)
					csp.TakenSound[i] = ALLPlayersTakenSound[i];
					
				if (fb.Event == 'CTFTakenTag')
					bTaglessSpawned = True;
			}
		}
		
		break;
	}
}

If not, if you want that feature in a seperate mutator or another actor, this is the actual new code:

Code: Select all

var() sound ALLPlayersTakenSound[4];

function PostBeginPlay()
{
local CTFAllSoundPlayer csp;
local PlayerStart ps;
local bool bTaglessSpawned;
local FlagBase fb;
local byte i;

	ForEach AllActors(class'PlayerStart', ps)
	{
		ForEach AllActors(class'FlagBase', fb)
		{
			if (fb.Event == '')
				fb.Event = 'CTFTakenTag';
			
			if ((fb.Event == 'CTFTakenTag' && !bTaglessSpawned) || fb.Event != 'CTFTakenTag')
			{
				csp = Spawn(class'CTFAllSoundPlayer',, fb.Event, ps.Location);
				
				for (i = 0; i < 4; i++)
					csp.TakenSound[i] = ALLPlayersTakenSound[i];
					
				if (fb.Event == 'CTFTakenTag')
					bTaglessSpawned = True;
			}
		}
		
		break;
	}
}
Basically this solution uses the trigger functionalities of the flag bases themselves, but still keeping the triggerings of any modified flag if there's any.
Perhaps there's a better solution, but this is what I came up with now.
User avatar
Sp0ngeb0b
Adept
Posts: 376
Joined: Wed Feb 13, 2008 9:16 pm
Location: Cologne

Re: CTF Sounds

Post by Sp0ngeb0b »

I did it like you mentioned - the compiler gave an error:

Code: Select all

\Classes\TakenSound.uc(11) : Error, Right type is incompatible with '&&'
Failed due to errors.
I changed the line from

Code: Select all

function Trigger( Actor Other, Pawn EventInstigator )
{
local PlayerPawn PP;

   ForEach AllActors (class'PlayerPawn', PP)
   {
      if (PP.PlayerReplicationInfo.Team < 4 && TakenSound[PP.PlayerReplicationInfo.Team])
         PP.ClientPlaySound(TakenSound[PP.PlayerReplicationInfo.Team]);
   }
}
TO:

Code: Select all

function Trigger( Actor Other, Pawn EventInstigator )
{
local PlayerPawn PP;

   ForEach AllActors (class'PlayerPawn', PP)
   {
      if (PP.PlayerReplicationInfo.Team < 4)
         PP.ClientPlaySound(TakenSound[PP.PlayerReplicationInfo.Team]);
   }
}
And compiled succesfully. But the sound doesn't play when the flag is Taken - it only playes when the flag is CAPTURED. :what:
I made a map once with special cap sounds using this method (with flag event).
Is it caused by the error or did you forget some things? :)
Website, Forum & UTStats

Image
******************************************************************************
Nexgen Server Controller || My plugins & mods on GitHub
******************************************************************************
User avatar
Feralidragon
Godlike
Posts: 5499
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: CTF Sounds

Post by Feralidragon »

Sorry, my bad there. :oops: That kind of code would only work with captured instead of taken indeed.

The taken sound needs another solution, which I thought a while ago, and basically it's this:

1) Forget that new class (CTFAllSoundPlayer), delete it, it's useless now for this solution;

2) Aplly this code (it has the first code I shown in this topic, plus the taken sound support), although I didn't test it, since I had no time and I don't have a compiler right now:

Code: Select all

var() sound NewCaptureSound[4];
var() sound NewReturnSound;
var() sound NewTakenSound[4];

var() sound ALLPlayersTakenSound[4];

struct FlagStruct
{
	var FlagBase FlagBaseSet;
	var bool bOldHome;
};

var FlagStruct FlagS[64];

function PostBeginPlay()
{
local byte i;
local FlagBase fb;
local PlayerStart ps;

	if (Level.Game.IsA('CTFGame'))
	{
		for (i = 0; i < 4; i++)
		{
			if (NewCaptureSound[i] != None)
				CTFGame(Level.Game).CaptureSound[i] = NewCaptureSound[i];
		}
          
		if (NewReturnSound != None)
			CTFGame(Level.Game).ReturnSound = NewReturnSound;
	}
   
	i = 0;
	ForEach AllActors(class'FlagBase', fb)
	{
		if (fb.Team < 4)
		{
			if (NewTakenSound[fb.Team] != None)
				fb.TakenSound = NewTakenSound[fb.Team];
		
			if (i < 64)
			{
				if (ALLPlayersTakenSound[fb.Team] != None)
					fb.TakenSound = None;
				
				FlagS[i].FlagBaseSet = fb;
				FlagS[i].bOldHome = True;
				i++;
			}
		}
	}
	
	SetTimer(0.15, True);
}


function Timer()
{
local byte i;
	
	while (i < 64 && FlagS[i].FlagBaseSet != None)
	{
		if (!FlagS[i].FlagBaseSet.bHome && FlagS[i].bOldHome)
			PlayTakenSoundForAll(FlagS[i].FlagBaseSet.Team);
		
		FlagS[i].bOldHome = FlagS[i].FlagBaseSet.bHome;
		i++;
	}
}

function PlayTakenSoundForAll(byte Team)
{
local Pawn P;

	for ( P=Level.PawnList; P!=None; P=P.nextPawn )
	{
		if (PlayerPawn(P) != None && P.PlayerReplicationInfo.Team < 4 && ALLPlayersTakenSound[Team] != None)
			PlayerPawn(P).ClientPlaySound(ALLPlayersTakenSound[Team]);
	}
}
And yeah, 64 structured arrays, since I know there are maps with over than 4 flags (wipeout for example), but if the map has only the nomal 2 flags, only 2 adresses will be used, so no worries there.
User avatar
Sp0ngeb0b
Adept
Posts: 376
Joined: Wed Feb 13, 2008 9:16 pm
Location: Cologne

Re: CTF Sounds

Post by Sp0ngeb0b »

Code: Select all

\Classes\GrappleSounds.uc(72) : Error, Unrecognized member 'bHome' in class 'FlagBase'
:(

Maybe it helps, bHome is located in CTFFlag.

[But I already changed this and compiled succesfully, the sound just plays when the game initializes]
Website, Forum & UTStats

Image
******************************************************************************
Nexgen Server Controller || My plugins & mods on GitHub
******************************************************************************
User avatar
Feralidragon
Godlike
Posts: 5499
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: CTF Sounds

Post by Feralidragon »

Sorry again, this is the result of me not compiling things first. :oops:

This one I compiled (so it really compiles now), it's now up to you to test the sounds playing again:

Code: Select all

var() sound NewCaptureSound[4];
var() sound NewReturnSound;
var() sound NewTakenSound[4];

var() sound ALLPlayersTakenSound[4];

struct FlagStruct
{
	var CTFFlag FlagSet;
	var bool bOldHome;
};

var FlagStruct FlagS[64];

function PostBeginPlay()
{
local byte i;
local FlagBase fb;
local PlayerStart ps;
local CTFFlag flg;

	if (Level.Game.IsA('CTFGame'))
	{
		for (i = 0; i < 4; i++)
		{
			if (NewCaptureSound[i] != None)
				CTFGame(Level.Game).CaptureSound[i] = NewCaptureSound[i];
		}
          
		if (NewReturnSound != None)
			CTFGame(Level.Game).ReturnSound = NewReturnSound;
	}
   
	ForEach AllActors(class'FlagBase', fb)
	{
		if (fb.Team < 4)
		{
			if (ALLPlayersTakenSound[fb.Team] != None)
				fb.TakenSound = None;
			else if (NewTakenSound[fb.Team] != None)
				fb.TakenSound = NewTakenSound[fb.Team];
		}
	}
	
	i = 0;
	ForEach AllActors(class'CTFFlag', flg)
	{
		if (i < 64)
		{
			FlagS[i].FlagSet = flg;
			FlagS[i].bOldHome = True;
			i++;
		}
		else
			break;
	}
	
	SetTimer(0.15, True);
}


function Timer()
{
local byte i;
	
	while (i < 64 && FlagS[i].FlagSet != None)
	{
		if (!FlagS[i].FlagSet.bHome && FlagS[i].bOldHome)
			PlayTakenSoundForAll(FlagS[i].FlagSet.Team);
		
		FlagS[i].bOldHome = FlagS[i].FlagSet.bHome;
		i++;
	}
}

function PlayTakenSoundForAll(byte Team)
{
local Pawn P;

	for ( P=Level.PawnList; P!=None; P=P.nextPawn )
	{
		if (PlayerPawn(P) != None && P.PlayerReplicationInfo.Team < 4 && ALLPlayersTakenSound[Team] != None)
			PlayerPawn(P).ClientPlaySound(ALLPlayersTakenSound[Team]);
	}
}
User avatar
Sp0ngeb0b
Adept
Posts: 376
Joined: Wed Feb 13, 2008 9:16 pm
Location: Cologne

Re: CTF Sounds

Post by Sp0ngeb0b »

Working! Thanks again :tu:

And one more question - is it also possible to play the ALLPlayersTakenSound when the flag is dropped and picked up again?
[Just say if I ask to much, I feel some kind of outrageous atm.]
Website, Forum & UTStats

Image
******************************************************************************
Nexgen Server Controller || My plugins & mods on GitHub
******************************************************************************
User avatar
Feralidragon
Godlike
Posts: 5499
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: CTF Sounds

Post by Feralidragon »

Yes, it just took a small adjustment, and it has a new boolean variable to enable or disable that feature:

Code: Select all

var() sound NewCaptureSound[4];
var() sound NewReturnSound;
var() sound NewTakenSound[4];

var() sound ALLPlayersTakenSound[4];
var() config bool bPlayAlwaysWhenPickedUp;

struct FlagStruct
{
	var CTFFlag FlagSet;
	var bool bOldHome;
	var bool bOldHeld;
};

var FlagStruct FlagS[64];

function PostBeginPlay()
{
local byte i;
local FlagBase fb;
local PlayerStart ps;
local CTFFlag flg;

	if (Level.Game.IsA('CTFGame'))
	{
		for (i = 0; i < 4; i++)
		{
			if (NewCaptureSound[i] != None)
				CTFGame(Level.Game).CaptureSound[i] = NewCaptureSound[i];
		}
          
		if (NewReturnSound != None)
			CTFGame(Level.Game).ReturnSound = NewReturnSound;
	}
   
	ForEach AllActors(class'FlagBase', fb)
	{
		if (fb.Team < 4)
		{
			if (ALLPlayersTakenSound[fb.Team] != None)
				fb.TakenSound = None;
			else if (NewTakenSound[fb.Team] != None)
				fb.TakenSound = NewTakenSound[fb.Team];
		}
	}
	
	i = 0;
	ForEach AllActors(class'CTFFlag', flg)
	{
		if (i < 64)
		{
			FlagS[i].FlagSet = flg;
			FlagS[i].bOldHome = True;
			i++;
		}
		else
			break;
	}
	
	SetTimer(0.15, True);
}


function Timer()
{
local byte i;
	
	while (i < 64 && FlagS[i].FlagSet != None)
	{
		if ( (bPlayAlwaysWhenPickedUp && !FlagS[i].FlagSet.bHome && FlagS[i].FlagSet.bHeld && !FlagS[i].bOldHeld)
		|| (!FlagS[i].FlagSet.bHome && FlagS[i].bOldHome))
			PlayTakenSoundForAll(FlagS[i].FlagSet.Team);
		
		FlagS[i].bOldHome = FlagS[i].FlagSet.bHome;
		FlagS[i].bOldHeld = FlagS[i].FlagSet.bHeld;
		i++;
	}
}

function PlayTakenSoundForAll(byte Team)
{
local Pawn P;

	for ( P=Level.PawnList; P!=None; P=P.nextPawn )
	{
		if (PlayerPawn(P) != None && P.PlayerReplicationInfo.Team < 4 && ALLPlayersTakenSound[Team] != None)
			PlayerPawn(P).ClientPlaySound(ALLPlayersTakenSound[Team]);
	}
}

defaultproperties
{
	bPlayAlwaysWhenPickedUp=True
}
User avatar
Sp0ngeb0b
Adept
Posts: 376
Joined: Wed Feb 13, 2008 9:16 pm
Location: Cologne

Re: CTF Sounds

Post by Sp0ngeb0b »

Thanks again Image

You gave me a really good example and helped me a lot for future projects!
I also extended your code with Dropped and Returned announcers!

Here's the full code:

Code: Select all

// Adds special CTF sounds
// Thanks to Feralidragon aka xXx
class GrappleSounds extends Mutator;

#exec AUDIO IMPORT FILE="Resources\Cap-r.wav" NAME="Cap-r"
#exec AUDIO IMPORT FILE="Resources\Cap-b.wav" NAME="Cap-b"
#exec AUDIO IMPORT FILE="Resources\return.wav" NAME="Return"
#exec AUDIO IMPORT FILE="Resources\Taken-r.wav" NAME="Taken-r"
#exec AUDIO IMPORT FILE="Resources\Taken-b.wav" NAME="Taken-b"
#exec AUDIO IMPORT FILE="Resources\Dropped-r.wav" NAME="Dropped-r"
#exec AUDIO IMPORT FILE="Resources\Dropped-b.wav" NAME="Dropped-b"
#exec AUDIO IMPORT FILE="Resources\Returned-r.wav" NAME="Returned-r"
#exec AUDIO IMPORT FILE="Resources\Returned-b.wav" NAME="Returned-b"

var() sound NewCaptureSound[4];
var() sound NewReturnSound;
var() sound NewTakenSound[4];
var() sound ALLPlayersTakenSound[4];
var() sound DroppedSound[4];
var() sound ALLPlayersReturnedSound[4];
var() config bool bPlayAlwaysWhenPickedUp;
var() config bool bPlayDroppedSound;
var() config bool bPlayReturnedSound;

struct FlagStruct
{
   var CTFFlag FlagSet;
   var bool bOldHome;
   var bool bOldHeld;
};

var FlagStruct FlagS[64];

function PostBeginPlay()
{
local byte i;
local FlagBase fb;
local PlayerStart ps;
local CTFFlag flg;

   if (Level.Game.IsA('CTFGame'))
   {
      for (i = 0; i < 4; i++)
      {
         if (NewCaptureSound[i] != None)
            CTFGame(Level.Game).CaptureSound[i] = NewCaptureSound[i];
      }

      if (NewReturnSound != None)
         CTFGame(Level.Game).ReturnSound = NewReturnSound;
   }

   ForEach AllActors(class'FlagBase', fb)
   {
      if (fb.Team < 4)
      {
         //if (ALLPlayersTakenSound[fb.Team] != None)
         //   fb.TakenSound = None;
         if (NewTakenSound[fb.Team] != None)
            fb.TakenSound = NewTakenSound[fb.Team];
      }
   }

   i = 0;
   ForEach AllActors(class'CTFFlag', flg)
   {
      if (i < 64)
      {
         FlagS[i].FlagSet = flg;
         FlagS[i].bOldHome = True;
         i++;
      }
      else
         break;
   }

   SetTimer(0.15, True);
}


function Timer()
{
local byte i;

   while (i < 64 && FlagS[i].FlagSet != None)
   {
      if ( (bPlayAlwaysWhenPickedUp && !FlagS[i].FlagSet.bHome && FlagS[i].FlagSet.bHeld && !FlagS[i].bOldHeld)
      || (!FlagS[i].FlagSet.bHome && FlagS[i].bOldHome))
         PlayTakenSoundForAll(FlagS[i].FlagSet.Team);
         
      if ( (bPlayDroppedSound && !FlagS[i].FlagSet.bHome && !FlagS[i].FlagSet.bHeld && FlagS[i].bOldHeld))
         PlayDroppedSound(FlagS[i].FlagSet.Team);
         
      if ( (bPlayReturnedSound && FlagS[i].FlagSet.bHome && !FlagS[i].FlagSet.bHeld && !FlagS[i].bOldHome && !FlagS[i].bOldHeld))
         PlayReturnedSound(FlagS[i].FlagSet.Team);

      FlagS[i].bOldHome = FlagS[i].FlagSet.bHome;
      FlagS[i].bOldHeld = FlagS[i].FlagSet.bHeld;
      i++;
   }
}

function PlayTakenSoundForAll(byte Team)
{
local Pawn P;

   for ( P=Level.PawnList; P!=None; P=P.nextPawn )
   {
      if (PlayerPawn(P) != None && P.PlayerReplicationInfo.Team < 4 && ALLPlayersTakenSound[Team] != None)
         PlayerPawn(P).ClientPlaySound(ALLPlayersTakenSound[Team]);
   }
}

function PlayDroppedSound(byte Team)
{
local Pawn P;

   for ( P=Level.PawnList; P!=None; P=P.nextPawn )
   {
      if (PlayerPawn(P) != None && P.PlayerReplicationInfo.Team < 4 && DroppedSound[Team] != None)
         PlayerPawn(P).ClientPlaySound(DroppedSound[Team]);
   }
}


function PlayReturnedSound(byte Team)
{
local Pawn P;

   for ( P=Level.PawnList; P!=None; P=P.nextPawn )
   {
      if (PlayerPawn(P) != None && P.PlayerReplicationInfo.Team < 4 && ALLPlayersReturnedSound[Team] != None)
         PlayerPawn(P).ClientPlaySound(ALLPlayersReturnedSound[Team]);
   }
}


defaultproperties
{
    bPlayAlwaysWhenPickedUp=True
    bPlayDroppedSound=True
    bPlayReturnedSound=True
    NewCaptureSound(0)=Sound'UrSGrappleS.Cap-r'
    NewCaptureSound(1)=Sound'UrSGrappleS.Cap-b'
    NewCaptureSound(2)=
    NewCaptureSound(3)=
    NewReturnSound=Sound'UrSGrappleS.Return'
    NewTakenSound(0)=
    NewTakenSound(1)=
    NewTakenSound(2)=
    NewTakenSound(3)=
    ALLPlayersTakenSound(0)=Sound'UrSGrappleS.Taken-r'
    ALLPlayersTakenSound(1)=Sound'UrSGrappleS.Taken-b'
    ALLPlayersTakenSound(2)=
    ALLPlayersTakenSound(3)=
    DroppedSound(0)=Sound'UrSGrappleS.Dropped-r'
    DroppedSound(1)=Sound'UrSGrappleS.Dropped-b'
    DroppedSound(2)=
    DroppedSound(3)=
    ALLPlayersReturnedSound(0)=Sound'UrSGrappleS.Returned-r'
    ALLPlayersReturnedSound(1)=Sound'UrSGrappleS.Returned-b'
    ALLPlayersReturnedSound(2)=
    ALLPlayersReturnedSound(3)=
}

You'll soon see this in action at my Grapple Server :)
Website, Forum & UTStats

Image
******************************************************************************
Nexgen Server Controller || My plugins & mods on GitHub
******************************************************************************
User avatar
Feralidragon
Godlike
Posts: 5499
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: CTF Sounds

Post by Feralidragon »

:gj: on the new code
Cool :tu: The grapple server owns btw, specially when played on face (I think you should do a Face ONLY grapple server, or Faces (I and II), since both the insta and grapple are very usefull and fun there, while in certain maps like woot the grapple is almost useless, and it turns into a normal insta, just my 2 cents though).