2020-09-13 14:23:52 +02:00
using System.Collections.Generic ;
2020-07-06 16:24:29 -05:00
using System.Linq ;
2020-09-01 01:36:49 +03:00
using Content.Server.GameObjects.Components.GUI ;
using Content.Server.GameObjects.Components.Items.Storage ;
using Content.Server.GameObjects.Components.PDA ;
2020-08-16 18:41:16 +02:00
using Content.Server.GameObjects.Components.Suspicion ;
2020-09-13 14:23:52 +02:00
using Content.Server.GameTicking.GameRules ;
using Content.Server.Interfaces.Chat ;
using Content.Server.Interfaces.GameTicking ;
2020-08-27 16:39:29 +02:00
using Content.Server.Mobs.Roles.Suspicion ;
2020-09-13 14:23:52 +02:00
using Content.Server.Players ;
2020-11-07 01:15:56 +01:00
using Content.Shared ;
2020-09-01 01:36:49 +03:00
using Content.Shared.GameObjects.Components.Inventory ;
using Content.Shared.GameObjects.Components.PDA ;
2020-08-13 14:40:27 +02:00
using Content.Shared.Roles ;
2021-02-11 01:13:03 -08:00
using Robust.Server.Player ;
using Robust.Shared.Configuration ;
2020-08-16 18:41:16 +02:00
using Robust.Shared.GameObjects ;
2020-09-13 14:23:52 +02:00
using Robust.Shared.IoC ;
2020-07-06 16:24:29 -05:00
using Robust.Shared.Log ;
2020-08-12 21:09:56 +02:00
using Robust.Shared.Maths ;
2020-09-13 14:23:52 +02:00
using Robust.Shared.Prototypes ;
using Robust.Shared.Random ;
2020-07-06 16:24:29 -05:00
2020-05-03 11:25:39 +02:00
namespace Content.Server.GameTicking.GamePresets
{
2021-02-14 15:39:24 +01:00
[GamePreset("suspicion")]
2020-05-03 11:25:39 +02:00
public class PresetSuspicion : GamePreset
{
2020-08-24 14:10:28 +02:00
[Dependency] private readonly IChatManager _chatManager = default ! ;
[Dependency] private readonly IGameTicker _gameTicker = default ! ;
[Dependency] private readonly IRobustRandom _random = default ! ;
[Dependency] private readonly IConfigurationManager _cfg = default ! ;
[Dependency] private readonly IPrototypeManager _prototypeManager = default ! ;
2020-05-03 11:25:39 +02:00
2020-08-20 22:04:55 +02:00
public int MinPlayers { get ; set ; }
public int MinTraitors { get ; set ; }
public int PlayersPerTraitor { get ; set ; }
2020-08-20 16:20:48 +02:00
2020-09-01 01:36:49 +03:00
public int TraitorStartingBalance { get ; set ; }
2020-08-20 16:20:48 +02:00
public override bool DisallowLateJoin = > true ;
2020-07-06 16:24:29 -05:00
private static string TraitorID = "SuspicionTraitor" ;
private static string InnocentID = "SuspicionInnocent" ;
2020-05-03 11:25:39 +02:00
2020-06-21 22:05:47 +02:00
public override bool Start ( IReadOnlyList < IPlayerSession > readyPlayers , bool force = false )
2020-05-03 11:25:39 +02:00
{
2020-12-01 17:05:19 +01:00
MinPlayers = _cfg . GetCVar ( CCVars . SuspicionMinPlayers ) ;
MinTraitors = _cfg . GetCVar ( CCVars . SuspicionMinTraitors ) ;
PlayersPerTraitor = _cfg . GetCVar ( CCVars . SuspicionPlayersPerTraitor ) ;
TraitorStartingBalance = _cfg . GetCVar ( CCVars . SuspicionStartingBalance ) ;
2020-08-20 22:04:55 +02:00
2020-06-21 22:05:47 +02:00
if ( ! force & & readyPlayers . Count < MinPlayers )
2020-05-03 11:25:39 +02:00
{
_chatManager . DispatchServerAnnouncement ( $"Not enough players readied up for the game! There were {readyPlayers.Count} players readied up out of {MinPlayers} needed." ) ;
return false ;
}
2020-08-16 19:35:50 +02:00
if ( readyPlayers . Count = = 0 )
{
2020-09-13 14:23:52 +02:00
_chatManager . DispatchServerAnnouncement ( "No players readied up! Can't start Suspicion." ) ;
2020-08-16 19:35:50 +02:00
return false ;
}
2020-05-03 11:25:39 +02:00
var list = new List < IPlayerSession > ( readyPlayers ) ;
2020-07-06 16:24:29 -05:00
var prefList = new List < IPlayerSession > ( ) ;
foreach ( var player in list )
{
2020-12-16 10:00:10 +01:00
if ( ! ReadyProfiles . ContainsKey ( player . UserId ) )
2020-07-06 16:24:29 -05:00
{
continue ;
}
2020-12-16 10:00:10 +01:00
var profile = ReadyProfiles [ player . UserId ] ;
2020-07-06 16:24:29 -05:00
if ( profile . AntagPreferences . Contains ( _prototypeManager . Index < AntagPrototype > ( TraitorID ) . Name ) )
{
prefList . Add ( player ) ;
}
2020-08-16 18:41:16 +02:00
player . AttachedEntity ? . EnsureComponent < SuspicionRoleComponent > ( ) ;
2020-07-06 16:24:29 -05:00
}
2020-08-20 20:34:32 +02:00
var numTraitors = MathHelper . Clamp ( readyPlayers . Count / PlayersPerTraitor ,
2020-06-21 22:05:47 +02:00
MinTraitors , readyPlayers . Count ) ;
2020-05-03 11:25:39 +02:00
2020-08-20 22:04:55 +02:00
var traitors = new List < SuspicionTraitorRole > ( ) ;
2020-05-03 11:25:39 +02:00
for ( var i = 0 ; i < numTraitors ; i + + )
{
2020-07-06 16:24:29 -05:00
IPlayerSession traitor ;
2020-08-16 01:12:30 +02:00
if ( prefList . Count = = 0 )
2020-07-06 16:24:29 -05:00
{
2020-08-20 22:16:34 +02:00
if ( list . Count = = 0 )
{
Logger . InfoS ( "preset" , "Insufficient ready players to fill up with traitors, stopping the selection." ) ;
break ;
}
2020-07-06 16:24:29 -05:00
traitor = _random . PickAndTake ( list ) ;
Logger . InfoS ( "preset" , "Insufficient preferred traitors, picking at random." ) ;
}
else
{
traitor = _random . PickAndTake ( prefList ) ;
list . Remove ( traitor ) ;
Logger . InfoS ( "preset" , "Selected a preferred traitor." ) ;
}
2020-05-03 11:25:39 +02:00
var mind = traitor . Data . ContentData ( ) . Mind ;
2020-07-06 16:24:29 -05:00
var antagPrototype = _prototypeManager . Index < AntagPrototype > ( TraitorID ) ;
2020-08-20 22:04:55 +02:00
var traitorRole = new SuspicionTraitorRole ( mind , antagPrototype ) ;
mind . AddRole ( traitorRole ) ;
traitors . Add ( traitorRole ) ;
2020-09-01 01:36:49 +03:00
// creadth: we need to create uplink for the antag.
// PDA should be in place already, so we just need to
// initiate uplink account.
var uplinkAccount =
new UplinkAccount ( mind . OwnedEntity . Uid ,
TraitorStartingBalance ) ;
var inventory = mind . OwnedEntity . GetComponent < InventoryComponent > ( ) ;
if ( ! inventory . TryGetSlotItem ( EquipmentSlotDefines . Slots . IDCARD , out ItemComponent pdaItem ) )
{
continue ;
}
var pda = pdaItem . Owner ;
var pdaComponent = pda . GetComponent < PDAComponent > ( ) ;
if ( pdaComponent . IdSlotEmpty )
{
continue ;
}
pdaComponent . InitUplinkAccount ( uplinkAccount ) ;
2020-05-03 11:25:39 +02:00
}
foreach ( var player in list )
{
var mind = player . Data . ContentData ( ) . Mind ;
2020-07-06 16:24:29 -05:00
var antagPrototype = _prototypeManager . Index < AntagPrototype > ( InnocentID ) ;
mind . AddRole ( new SuspicionInnocentRole ( mind , antagPrototype ) ) ;
2020-05-03 11:25:39 +02:00
}
2020-08-20 22:04:55 +02:00
foreach ( var traitor in traitors )
{
traitor . GreetSuspicion ( traitors , _chatManager ) ;
}
2020-05-03 11:25:39 +02:00
_gameTicker . AddGameRule < RuleSuspicion > ( ) ;
return true ;
}
public override string ModeTitle = > "Suspicion" ;
public override string Description = > "Suspicion on the Space Station. There are traitors on board... Can you kill them before they kill you?" ;
}
}