2024-04-20 11:51:04 +03:00
using System.Linq ;
using Content.Shared._CP14.LockKey ;
2024-08-05 15:22:14 +03:00
using Content.Shared._CP14.LockKey.Components ;
2024-04-02 20:59:40 +03:00
using Content.Shared.Examine ;
2024-08-05 15:22:14 +03:00
using Content.Shared.GameTicking ;
2024-04-02 20:59:40 +03:00
using Robust.Shared.Prototypes ;
using Robust.Shared.Random ;
2024-04-20 11:51:04 +03:00
namespace Content.Server._CP14.LockKey ;
2024-04-02 20:59:40 +03:00
2024-04-20 11:51:04 +03:00
public sealed partial class CP14KeyholeGenerationSystem : EntitySystem
2024-04-02 20:59:40 +03:00
{
[Dependency] private readonly IPrototypeManager _proto = default ! ;
[Dependency] private readonly IRobustRandom _random = default ! ;
2024-04-20 11:51:04 +03:00
private Dictionary < ProtoId < CP14LockCategoryPrototype > , List < int > > _roundKeyData = new ( ) ;
2024-04-02 20:59:40 +03:00
public override void Initialize ( )
{
base . Initialize ( ) ;
2024-08-05 15:22:14 +03:00
SubscribeLocalEvent < RoundRestartCleanupEvent > ( OnRoundEnd ) ;
2024-04-02 20:59:40 +03:00
2024-04-20 11:51:04 +03:00
SubscribeLocalEvent < CP14LockComponent , MapInitEvent > ( OnLockInit ) ;
SubscribeLocalEvent < CP14KeyComponent , MapInitEvent > ( OnKeyInit ) ;
2024-04-02 20:59:40 +03:00
2024-04-20 11:51:04 +03:00
SubscribeLocalEvent < CP14KeyComponent , ExaminedEvent > ( OnKeyExamine ) ;
2024-04-02 20:59:40 +03:00
}
#region Init
2024-08-05 15:22:14 +03:00
private void OnRoundEnd ( RoundRestartCleanupEvent ev )
2024-04-02 20:59:40 +03:00
{
_roundKeyData = new ( ) ;
}
2024-04-20 11:51:04 +03:00
private void OnKeyInit ( Entity < CP14KeyComponent > keyEnt , ref MapInitEvent args )
2024-04-02 20:59:40 +03:00
{
if ( keyEnt . Comp . AutoGenerateShape ! = null )
{
keyEnt . Comp . LockShape = GetKeyLockData ( keyEnt . Comp . AutoGenerateShape . Value ) ;
}
}
2024-04-20 11:51:04 +03:00
private void OnLockInit ( Entity < CP14LockComponent > lockEnt , ref MapInitEvent args )
2024-04-02 20:59:40 +03:00
{
if ( lockEnt . Comp . AutoGenerateShape ! = null )
{
lockEnt . Comp . LockShape = GetKeyLockData ( lockEnt . Comp . AutoGenerateShape . Value ) ;
}
}
#endregion
2024-04-20 11:51:04 +03:00
private void OnKeyExamine ( Entity < CP14KeyComponent > key , ref ExaminedEvent args )
2024-04-02 20:59:40 +03:00
{
var parent = Transform ( key ) . ParentUid ;
if ( parent ! = args . Examiner )
return ;
if ( key . Comp . LockShape = = null )
return ;
2024-08-05 15:22:14 +03:00
var markup = Loc . GetString ( "cp14-lock-examine-key" , ( "item" , MetaData ( key ) . EntityName ) ) ;
2024-04-02 20:59:40 +03:00
markup + = " (" ;
foreach ( var item in key . Comp . LockShape )
{
markup + = $"{item} " ;
}
markup + = ")" ;
args . PushMarkup ( markup ) ;
}
2024-04-20 11:51:04 +03:00
private List < int > GetKeyLockData ( ProtoId < CP14LockCategoryPrototype > category )
2024-04-02 20:59:40 +03:00
{
if ( _roundKeyData . ContainsKey ( category ) )
return _roundKeyData [ category ] ;
2024-10-21 14:20:05 +03:00
var newData = GenerateNewUniqueLockData ( category ) ;
_roundKeyData [ category ] = newData ;
return newData ;
2024-04-02 20:59:40 +03:00
}
2024-04-20 11:51:04 +03:00
private List < int > GenerateNewUniqueLockData ( ProtoId < CP14LockCategoryPrototype > category )
2024-04-02 20:59:40 +03:00
{
2024-10-21 14:20:05 +03:00
List < int > newKeyData = new ( ) ;
2024-04-02 20:59:40 +03:00
var categoryData = _proto . Index ( category ) ;
var iteration = 0 ;
2024-10-21 14:20:05 +03:00
while ( true )
2024-04-02 20:59:40 +03:00
{
//Generate try
newKeyData = new List < int > ( ) ;
2024-10-21 14:20:05 +03:00
for ( var i = 0 ; i < categoryData . Complexity ; i + + )
2024-04-02 20:59:40 +03:00
{
2024-10-21 14:20:05 +03:00
newKeyData . Add ( _random . Next ( - SharedCP14LockKeySystem . DepthComplexity , SharedCP14LockKeySystem . DepthComplexity ) ) ;
2024-04-02 20:59:40 +03:00
}
2024-10-21 14:20:05 +03:00
// Identity Check shit code
// It is currently trying to generate a unique code. If it fails to generate a unique code 100 times, it will output the last generated non-unique code.
2024-04-02 20:59:40 +03:00
var unique = true ;
foreach ( var pair in _roundKeyData )
{
if ( newKeyData . SequenceEqual ( pair . Value ) )
{
unique = false ;
break ;
}
}
if ( unique )
return newKeyData ;
else
iteration + + ;
if ( iteration > 100 )
{
break ;
}
}
Log . Error ( "The unique key for CPLockSystem could not be generated!" ) ;
return newKeyData ; //FUCK
}
}