rott/kf_sources/Engine/Classes/BroadcastHandler.uc
2026-07-14 20:27:09 +07:00

248 lines
8.4 KiB
Ucode

//=============================================================================
// BroadcastHandler
//
// Message broadcasting is delegated to BroadCastHandler by the GameInfo.
// The BroadCastHandler handles both text messages (typed by a player) and
// localized messages (which are identified by a LocalMessage class and id).
// GameInfos produce localized messages using their DeathMessageClass and
// GameMessageClass classes.
//
// This is a built-in Unreal class and it shouldn't be modified.
//=============================================================================
class BroadcastHandler extends Info
config;
// rjp -- Generally, you should only need to override the 'Accept' functions
var BroadcastHandler NextBroadcastHandler;
var class<BroadcastHandler> NextBroadcastHandlerClass;
// -- rjp
var int SentText;
var globalconfig bool bMuteSpectators; // Whether spectators are allowed to speak.
var globalconfig bool bPartitionSpectators; // Whether spectators are can only speak to spectators.
const PROPNUM = 2;
var localized string BHDisplayText[PROPNUM];
var localized string BHDescText[PROPNUM];
function UpdateSentText()
{
SentText = 0;
}
static function FillPlayInfo(PlayInfo PlayInfo)
{
Super.FillPlayInfo(PlayInfo); // Always begin with calling parent
PlayInfo.AddSetting(default.ChatGroup, "bMuteSpectators", default.BHDisplayText[0], 0, 1, "Check",,,True,True);
PlayInfo.AddSetting(default.ChatGroup, "bPartitionSpectators", default.BHDisplayText[1], 1, 1, "Check",,,True,True);
if ( default.NextBroadcastHandlerClass != None )
{
default.NextBroadcastHandlerClass.static.FillPlayInfo(PlayInfo);
PlayInfo.PopClass();
}
}
static event string GetDescriptionText(string PropName)
{
switch (PropName)
{
case "bMuteSpectators": return default.BHDescText[0];
case "bPartitionSpectators":return default.BHDescText[1];
}
return Super.GetDescriptionText(PropName);
}
/* Whether actor is allowed to broadcast messages now.
*/
function bool AllowsBroadcast( actor broadcaster, int Len )
{
if ( bMuteSpectators && (PlayerController(Broadcaster) != None)
&& !PlayerController(Broadcaster).PlayerReplicationInfo.bAdmin
//if _RO_
&& !PlayerController(Broadcaster).PlayerReplicationInfo.bSilentAdmin
//end _RO_
&& (PlayerController(Broadcaster).PlayerReplicationInfo.bOnlySpectator
|| PlayerController(Broadcaster).PlayerReplicationInfo.bOutOfLives) )
return false;
SentText += Len;
if ( NextBroadcastHandler != None && !NextBroadcastHandler.HandlerAllowsBroadcast(Broadcaster, SentText) )
return false;
return ( (Level.Pauser != None) || (SentText < 200) );
}
function bool HandlerAllowsBroadcast( Actor Broadcaster, int SentTextNum )
{
if ( NextBroadcastHandler != None )
return NextBroadcastHandler.HandlerAllowsBroadcast(Broadcaster, SentTextNum);
return true;
}
function BroadcastText( PlayerReplicationInfo SenderPRI, PlayerController Receiver, coerce string Msg, optional name Type )
{
if ( !AcceptBroadcastText(Receiver, SenderPRI, Msg, Type) )
return;
if ( NextBroadcastHandler != None )
NextBroadcastHandler.BroadcastText( SenderPRI, Receiver, Msg, Type );
else Receiver.TeamMessage( SenderPRI, Msg, Type );
}
function BroadcastLocalized( Actor Sender, PlayerController Receiver, class<LocalMessage> Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
{
if ( !AcceptBroadcastLocalized(Receiver, Sender, Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject) )
return;
if ( NextBroadcastHandler != None )
NextBroadcastHandler.BroadcastLocalized( Sender, Receiver, Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject );
else Receiver.ReceiveLocalizedMessage( Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject );
}
function Broadcast( Actor Sender, coerce string Msg, optional name Type )
{
local Controller C;
local PlayerController P;
local PlayerReplicationInfo PRI;
// see if allowed (limit to prevent spamming)
if ( !AllowsBroadcast(Sender, Len(Msg)) )
return;
if ( Pawn(Sender) != None )
PRI = Pawn(Sender).PlayerReplicationInfo;
else if ( Controller(Sender) != None )
PRI = Controller(Sender).PlayerReplicationInfo;
if ( bPartitionSpectators && !Level.Game.bGameEnded && (PRI != None) && !PRI.bAdmin && (PRI.bOnlySpectator || PRI.bOutOfLives) )
{
For ( C=Level.ControllerList; C!=None; C=C.NextController )
{
P = PlayerController(C);
if ( (P != None) && (P.PlayerReplicationInfo.bOnlySpectator || P.PlayerReplicationInfo.bOutOfLives) )
BroadcastText(PRI, P, Msg, Type);
}
}
else
{
For ( C=Level.ControllerList; C!=None; C=C.NextController )
{
P = PlayerController(C);
if ( P != None )
BroadcastText(PRI, P, Msg, Type);
}
}
}
function BroadcastTeam( Controller Sender, coerce string Msg, optional name Type )
{
local Controller C;
local PlayerController P;
// see if allowed (limit to prevent spamming)
if ( !AllowsBroadcast(Sender, Len(Msg)) )
return;
if ( bPartitionSpectators && !Level.Game.bGameEnded && (Sender != None) && !Sender.PlayerReplicationInfo.bAdmin && (Sender.PlayerReplicationInfo.bOnlySpectator || Sender.PlayerReplicationInfo.bOutOfLives) )
{
For ( C=Level.ControllerList; C!=None; C=C.NextController )
{
P = PlayerController(C);
if ( (P != None) && (P.PlayerReplicationInfo.Team == Sender.PlayerReplicationInfo.Team)
&& (P.PlayerReplicationInfo.bOnlySpectator || P.PlayerReplicationInfo.bOutOfLives) )
BroadcastText(Sender.PlayerReplicationInfo, P, Msg, Type);
}
}
else
{
For ( C=Level.ControllerList; C!=None; C=C.NextController )
{
P = PlayerController(C);
if ( (P != None) && (P.PlayerReplicationInfo.Team == Sender.PlayerReplicationInfo.Team) )
BroadcastText(Sender.PlayerReplicationInfo, P, Msg, Type);
}
}
}
/*
Broadcast a localized message to all players.
Most messages deal with 0 to 2 related PRIs.
The LocalMessage class defines how the PRI's and optional actor are used.
*/
event AllowBroadcastLocalized( actor Sender, class<LocalMessage> Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
{
local Controller C;
local PlayerController P;
For ( C=Level.ControllerList; C!=None; C=C.NextController )
{
P = PlayerController(C);
if ( P != None )
BroadcastLocalized(Sender, P, Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject);
}
}
// rjp --- Linked list for broadcast handlers
function RegisterBroadcastHandler(BroadcastHandler NewBH)
{
if ( NextBroadcastHandler == None )
{
NextBroadcastHandler = NewBH;
default.NextBroadcastHandlerClass = NewBH.Class;
}
else NextBroadcastHandler.RegisterBroadcastHandler(NewBH);
}
function bool AcceptBroadcastText( PlayerController Receiver, PlayerReplicationInfo SenderPRI, out string Msg, optional name Type )
{
if ( NextBroadcastHandler != None )
return NextBroadcastHandler.AcceptBroadcastText(Receiver, SenderPRI, Msg, Type);
return true;
}
function bool AcceptBroadcastLocalized(PlayerController Receiver, Actor Sender, class<LocalMessage> Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object Obj)
{
if ( NextBroadcastHandler != None )
return NextBroadcastHandler.AcceptBroadcastLocalized(Receiver, Sender, Message, Switch, RelatedPRI_1, RelatedPRI_2, Obj);
return true;
}
function bool AcceptBroadcastSpeech(PlayerController Receiver, PlayerReplicationInfo SenderPRI)
{
if ( NextBroadcastHandler != None )
return NextBroadcastHandler.AcceptBroadcastSpeech(Receiver, SenderPRI);
return true;
}
function bool AcceptBroadcastVoice(PlayerController Receiver, PlayerReplicationInfo SenderPRI)
{
if ( NextBroadcastHandler != None )
return NextBroadcastHandler.AcceptBroadcastVoice(Receiver, SenderPRI);
return true;
}
// --- rjp
event Destroyed()
{
default.NextBroadcastHandlerClass = None;
Super.Destroyed();
}
defaultproperties
{
BHDisplayText(0)="Mute Spectators"
BHDisplayText(1)="Partition Spectators"
BHDescText(0)="Check this option to prevent spectators from chatting during the game."
BHDescText(1)="Check this option to separate spectator chat from player chat."
}