//============================================================================== // Created on: 08/29/2003 // This panel contains in-game voice chat controls, such as banning controls, etc. // // Written by Ron Prestenback // © 2003, Epic Games, Inc. All Rights Reserved // TODO: Allow players to restrict speech based on type (taunt, order, etc.) //============================================================================== class UT2K4Tab_MidGameVoiceChat extends MidGamePanel; struct ChatItem { var int PlayerID; var bool bNoText; var bool bNoSpeech; var bool bNoVoice; var bool bBanned; var bool bDirty; }; var array ChatList; var automated GUISectionBackground sb_Players, sb_Specs, sb_Options; var automated GUIListBox lb_Players, lb_Specs; var automated GUIList li_Players, li_Specs; var automated moCheckbox ch_NoVoiceChat, ch_NoSpeech, ch_NoText, ch_Ban; // if _RO_ var GUIButton b_Reset; // else //var automated GUIButton b_Reset; // end if _RO_ var() int SelectIndex; var() localized string ApplySuccessText, ApplyFailText; var() editconst bool bTeamGame; var int RedTeamIndex, BlueTeamIndex; var localized string RedTeamDesc, BlueTeamDesc; function GameReplicationInfo GRI() { return PlayerOwner().GameReplicationInfo; } function InitComponent(GUIController MyController, GUIComponent MyOwner) { Super.InitComponent(MyController, MyOwner); // Tie lists together with buttons li_Players = lb_Players.List; li_Specs = lb_Specs.List; li_Players.bInitializeList = false; li_Specs.bInitializeList = false; sb_Players.ManageComponent( lb_Players ); sb_Specs.ManageComponent( lb_Specs ); sb_Options.ManageComponent( ch_NoText ); sb_Options.ManageComponent( ch_NoSpeech ); sb_Options.ManageComponent( ch_NoVoiceChat ); sb_Options.ManageComponent( ch_Ban ); AssociateButtons(); } function ShowPanel( bool bShow ) { Super.ShowPanel(bShow); if ( !bShow ) { ClearIndexes(None); SaveRestrictions(); } } event Closed( GUIComponent Sender, bool bCancelled ) { SaveRestrictions(); Super.Closed(Sender,bCancelled); } // ===================================================================================================================== // ===================================================================================================================== // GUI Interface // ===================================================================================================================== // ===================================================================================================================== function bool PreDraw(Canvas Canvas) { if ( GRI() != None ) { bTeamGame = GRI().bTeamGame; FillPlayerLists(); } return false; } function bool InternalOnClick(GUIComponent Sender) { if ( Sender == b_Reset ) { ResetRestrictions(); ChatList.Remove(0,ChatList.Length); } UpdateButtonStates(); return true; } // Called when an player's name is clicked on function ListChange( GUIComponent Sender ) { local int ID; local GUIList List; List = GUIListBox(Sender).List; if ( List == None ) return; ClearIndexes( List ); // grab the associated PlayerID from the selected player id = int(List.GetExtra()); if ( PlayerIDIsMine(id) ) { SelectedSelf(); return; } SelectIndex = FindChatListIndex(id); LoadRestrictions(SelectIndex); } function InternalOnChange(GUIComponent Sender) { local bool bResult; if ( !ValidIndex(SelectIndex) ) return; bResult = moCheckbox(Sender).IsChecked(); ChatList[SelectIndex].bDirty = true; switch (Sender) { case ch_NoText: ChatList[SelectIndex].bNoText = bResult; break; case ch_NoSpeech: ChatList[SelectIndex].bNoSpeech = bResult; break; case ch_NoVoiceChat: ChatList[SelectIndex].bNoVoice = bResult; break; case ch_Ban: ChatList[SelectIndex].bBanned = bResult; break; } if ( ChatList[SelectIndex].bDirty && ApplyRestriction(SelectIndex) ) { ModifiedChatRestriction(Self, ChatList[SelectIndex].PlayerID); ChatList[SelectIndex].bDirty = False; } UpdateButtonStates(); } // ===================================================================================================================== // ===================================================================================================================== // Implementation // ===================================================================================================================== // ===================================================================================================================== // Get a list of all players, and put them into the appropriate list function FillPlayerLists() { local string idx; if ( GRI() == None ) return; // if an item was selected, remember the selected PlayerID while we clear and refill the lists if ( li_Players.IsValid() ) idx = li_Players.GetExtra(); else if ( li_Specs.IsValid() ) idx = ""; // Disable all list notification while we're clearing and refilling the lists li_Players.bNotify = false; li_Specs.bNotify = false; ClearLists(); PopulateLists( GRI() ); // if we had a PlayerID selected, attempt to reselect that PlayerID in any list if ( idx != "" ) { if ( li_Players.Find(idx,false,true) != "" ) { if ( !PlayerIDIsMine(idx) ) li_Players.CheckLinkedObjects(li_Players); } else if ( li_Specs.Find(idx,false,true) != "" ) { if ( !PlayerIDIsMine(idx) ) li_Specs.CheckLinkedObjects(li_Specs); } } li_Players.bNotify = true; li_Specs.bNotify = true; } function PopulateLists(GameReplicationInfo GRI) { local int i; local PlayerReplicationInfo PRI; if (bTeamGame) { //li_Players.Add(RedTeamDesc,,,true); //li_Players.Add(BlueTeamDesc,,,True); BlueTeamIndex=1; } for ( i = 0; i < GRI.PRIArray.Length; i++ ) { PRI = GRI.PRIArray[i]; if ( PRI == None || PRI.bBot || xPlayerReplicationInfo(PRI) == none || (bTeamGame && PRI.Team==None && !PRI.bOnlySpectator) ) continue; // If this is the first time seeing this playerid, request the ban/ignore info from our ChatManager if ( FindChatListIndex(PRI.PlayerID) == -1 ) AddPlayerInfo(PRI.PlayerID); if ( PRI.bOnlySpectator ) li_Specs.Add(PRI.PlayerName,,string(PRI.PlayerID)); else AddtoPlayers(PRI); } } function AddToPlayers(PlayerReplicationInfo PRI) { if (bTeamGame ) { if ( PRI.Team.TeamIndex==0 ) // Red Team { if ( RedTeamIndex == -1 ) { li_Players.Add(RedTeamDesc,,,true); RedTeamIndex = 0; } if ( BlueTeamIndex < 0 ) li_Players.Add(PRI.PlayerName,,string(PRI.PlayerID)); else { li_Players.Insert(BlueTeamIndex,PRI.PlayerName,,string(PRI.PlayerID)); BlueTeamIndex++; } } else { if ( BlueTeamIndex == -1 ) { BlueTeamIndex = li_Players.ItemCount; li_Players.Add(BlueTeamDesc,,,true); } li_Players.Add(PRI.PlayerName,,string(PRI.PlayerID)); } } else li_Players.Add( PRI.PlayerName,,string(PRI.PlayerID) ); } // When a list item is selected, clear the indexes of the other lists function ClearIndexes( GUIList List ) { if ( List != li_Players) li_Players.SilentSetIndex(-1); if ( List != li_Specs ) li_Specs.SilentSetIndex(-1); if ( List == None ) SelectedSelf(); } // ===================================================================================================================== // ===================================================================================================================== // Chat Manager Interface // ===================================================================================================================== // ===================================================================================================================== // Set the checkboxes to the values associated with the given player function LoadRestrictions(int i) { if ( !ValidIndex(i) ) { ch_NoText.SetComponentValue(False, True); ch_NoSpeech.SetComponentValue(False, True); ch_NoVoiceChat.SetComponentValue(False, True); ch_Ban.SetComponentValue(False, True); } else { ch_NoText.SetComponentValue(ChatList[i].bNoText, True); ch_NoSpeech.SetComponentValue(ChatList[i].bNoSpeech, True); ch_NoVoiceChat.SetComponentValue(ChatList[i].bNoVoice, True); ch_Ban.SetComponentValue(ChatList[i].bBanned, True); } UpdateButtonStates(); } // Called when a new playerID is found while filling the lists // Request stored chat restrictions for this PlayerID from the ChatManager function int AddPlayerInfo(int PlayerID) { local int i; local PlayerController PC; local byte Restriction; PC = PlayerOwner(); if ( PC.ChatManager == None ) return -1; // Verify that we don't already have this player ID in the list i = FindChatListIndex( PlayerID ); if ( i == -1 ) { i = ChatList.Length; ChatList.Length = i+1; } ChatList[i].PlayerID = PlayerID; // Query the ChatManager for the settings for this player Restriction = PC.ChatManager.GetPlayerRestriction(PlayerID); UnpackRestriction(i, Restriction); return i; } function PackRestriction(int i, out byte Restriction) { Restriction = 0; if ( ValidIndex(i) ) { if ( ChatList[i].bNoText ) Restriction = Restriction | 1; if ( ChatList[i].bNoSpeech ) Restriction = Restriction | 2; if ( ChatList[i].bNoVoice ) Restriction = Restriction | 4; if ( ChatList[i].bBanned ) Restriction = Restriction | 8; } } function UnpackRestriction(int i, byte Restriction) { if ( ValidIndex(i) ) { ChatList[i].bNoText = bool(Restriction & 1); ChatList[i].bNoSpeech = bool(Restriction & 2); ChatList[i].bNoVoice = bool(Restriction & 4); ChatList[i].bBanned = bool(Restriction & 8); Chatlist[i].bDirty = false; } } function bool ApplyRestriction(int i) { local byte Restriction; // Send restrictions to player's chat manager if ( ValidIndex(i) ) { PackRestriction(i, Restriction); return PlayerOwner().ChatBan(ChatList[i].PlayerID, Restriction); } return false; } function SaveRestrictions() { local int i; for ( i = 0; i < ChatList.Length; i++ ) { if ( Chatlist[i].bDirty && ApplyRestriction(i) ) { ModifiedChatRestriction(Self, Chatlist[i].PlayerID); Chatlist[i].bDirty = false; } } } function ResetRestrictions() { local int i; local byte Restriction; for ( i = 0; i < ChatList.Length; i++ ) { PackRestriction(i, Restriction); if ( Restriction != 0 ) PlayerOwner().ChatBan(ChatList[i].PlayerID, 0); } PlayerOwner().ChatManager.ClearConfig(); } function UpdateChatRestriction( int PlayerID ) { local int i; Super.UpdateChatRestriction(PlayerID); i = FindChatListIndex(PlayerID); if ( ValidIndex(i) ) UnpackRestriction( i, PlayerOwner().ChatManager.GetPlayerRestriction(PlayerID) ); UpdateButtonStates(); } // ===================================================================================================================== // ===================================================================================================================== // Utility / Helper functions // ===================================================================================================================== // ===================================================================================================================== function UpdateButtonStates() { local int i; local PlayerController PC; PC = PlayerOwner(); for ( i = 0; i < ChatList.Length; i++ ) { if ( Chatlist[i].bDirty ) { EnableComponent(b_Reset); return; } } if ( PC != None && PC.ChatManager != None && PC.ChatManager.Count() > 0 ) { EnableComponent(b_Reset); return; } DisableComponent(b_Reset); } function ClearLists() { if ( li_Players.ItemCount > 0 ) li_Players.Clear(); if ( li_Specs.ItemCount > 0 ) li_Specs.Clear(); } // Disable/enable these components based on whether or not a list has a valid index function AssociateButtons() { LinkList(li_Players); LinkList(li_Specs); } function LinkList( GUIList List ) { if ( List == None ) return; List.AddLinkObject( ch_NoVoiceChat ); List.AddLinkObject( ch_NoSpeech ); List.AddLinkObject( ch_NoText ); List.AddLinkObject( ch_Ban ); } function int FindChatListIndex(int PlayerID) { local int i; for ( i = 0; i < ChatList.Length; i++ ) if ( PlayerID == ChatList[i].PlayerID ) return i; return -1; } function bool ValidIndex(int i) { return i >= 0 && i < ChatList.Length; } function SelectedSelf() { ch_NoText.SetComponentValue(False, True); ch_NoSpeech.SetComponentValue(False, True); ch_NoVoiceChat.SetComponentValue(False, True); ch_Ban.SetComponentValue(False, True); DisableComponent(ch_NoText); DisableComponent(ch_NoSpeech); DisableComponent(ch_NoVoiceChat); DisableComponent(ch_Ban); } // ===================================================================================================================== // ===================================================================================================================== // Defaults // ===================================================================================================================== // ===================================================================================================================== DefaultProperties { Begin Object Class=AltSectionBackground Name=PlayersBackground Caption="Players" LeftPadding=0.00000 RightPadding=0.00000 TopPadding=0.00000 BottomPadding=0.00000 WinWidth=0.462019 WinHeight=0.899506 WinLeft=0.019250 WinTop=0.030325 bBoundToParent=True bScaleToParent=True End Object sb_Players=PlayersBackground Begin Object Class=AltSectionBackground Name=SpecBackground Caption="Spectators" LeftPadding=0.00000 RightPadding=0.00000 TopPadding=0.00000 BottomPadding=0.00000 WinWidth=0.462019 WinHeight=0.468385 WinLeft=0.512544 WinTop=0.030325 bBoundToParent=True bScaleToParent=True End Object sb_Specs=SpecBackground Begin Object Class=AltSectionBackground Name=OptionBackground Caption="Voice Options" WinWidth=0.462019 WinHeight=0.394391 WinLeft=0.512544 WinTop=0.508063 TopPadding=0.04 BottomPadding=0.0 bBoundToParent=True bScaleToParent=True End Object sb_Options=OptionBackground Begin Object Class=GUIListBox Name=PlayersList WinWidth=0.431250 WinHeight=0.518750 WinLeft=0.056250 WinTop=0.041667 OnChange=ListChange bInitializeList=False TabOrder=0 StyleName="NoBackground" End Object lb_Players=PlayersList Begin Object Class=GUIListBox Name=SpecList WinWidth=0.431250 WinHeight=0.518750 WinLeft=0.531250 WinTop=0.041667 OnChange=ListChange bInitializeList=False TabOrder=1 StyleName="NoBackground" End Object lb_Specs=SpecList Begin Object Class=moCheckBox Name=NoText WinWidth=0.338524 WinHeight=0.049840 WinLeft=0.647884 WinTop=0.620670 Caption="Ignore Text" Hint="Do not receive any text messages from this player" OnChange=InternalOnChange TabOrder=2 MenuState=MSAT_Disabled End Object ch_NoText=NoText Begin Object Class=moCheckBox Name=NoSpeech WinWidth=0.338524 WinHeight=0.049840 WinLeft=0.647884 WinTop=0.685424 Caption="Ignore Speech" Hint="Do not receive any speech messages, such as \"Incoming!\" from this player" OnChange=InternalOnChange TabOrder=3 MenuState=MSAT_Disabled End Object ch_NoSpeech=NoSpeech Begin Object Class=moCheckBox Name=NoVoiceChat WinWidth=0.338524 WinHeight=0.049840 WinLeft=0.647884 WinTop=0.750178 Caption="Ignore Voice Chat" Hint="Do not receive any voice chat messages from this player, in any voice chat room" OnChange=InternalOnChange TabOrder=4 MenuState=MSAT_Disabled End Object ch_NoVoiceChat=NoVoiceChat Begin Object Class=moCheckBox Name=BanPlayer WinWidth=0.338524 WinHeight=0.049840 WinLeft=0.647884 WinTop=0.814932 Caption="Ban Player" Hint="Ban this player from your personal voice chat channel" OnChange=InternalOnChange TabOrder=5 MenuState=MSAT_Disabled End Object ch_Ban=BanPlayer // if _RO_ /* // end if _RO_ Begin Object Class=GUIButton Name=ResetButton WinWidth=0.120067 WinHeight=0.051836 WinLeft=0.682745 WinTop=0.899668 Caption="Reset" Hint="Reset & reload all player chat restrictions" OnClick=InternalOnClick TabOrder=7 bStandardized=true MenuState=MSAT_Disabled End Object b_Reset=ResetButton // if _RO_ */ // end if _RO_ OnPreDraw=PreDraw ApplySuccessText="Changes were saved successfully!" ApplyFailText="Changes could not be saved!" RedTeamDesc="RED TEAM" BlueTeamDesc="BLUE TEAM" RedTeamIndex=-1 BlueTeamIndex=-1 }