2024-04-20 11:51:04 +03:00
using System.Linq ;
2024-04-02 20:59:40 +03:00
using Content.Server.GameTicking.Events ;
2024-04-20 11:51:04 +03:00
using Content.Shared._CP14.LockKey ;
2024-04-02 20:59:40 +03:00
using Content.Shared.Containers.ItemSlots ;
using Content.Shared.Examine ;
using Content.Shared.Lock ;
2024-04-20 11:51:04 +03:00
using Content.Shared.Popups ;
2024-04-02 20:59:40 +03:00
using Robust.Shared.Prototypes ;
using Robust.Shared.Random ;
2024-04-20 11:51:04 +03:00
using CP14KeyComponent = Content . Shared . _CP14 . LockKey . Components . CP14KeyComponent ;
using CP14LockComponent = Content . Shared . _CP14 . LockKey . Components . CP14LockComponent ;
2024-04-02 20:59:40 +03:00
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 ! ;
[Dependency] private readonly SharedPopupSystem _popup = default ! ;
[Dependency] private readonly ItemSlotsSystem _itemSlots = default ! ;
[Dependency] private readonly LockSystem _lock = 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
private const int DepthCompexity = 2 ;
public override void Initialize ( )
{
base . Initialize ( ) ;
SubscribeLocalEvent < RoundStartingEvent > ( OnRoundStart ) ;
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
private void OnRoundStart ( RoundStartingEvent ev )
{
_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 ;
var markup = Loc . GetString ( "cp-lock-examine-key" , ( "item" , MetaData ( key ) . EntityName ) ) ;
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 ] ;
else
{
var newData = GenerateNewUniqueLockData ( category ) ;
_roundKeyData [ category ] = newData ;
return newData ;
}
}
2024-04-20 11:51:04 +03:00
private List < int > GenerateNewUniqueLockData ( ProtoId < CP14LockCategoryPrototype > category )
2024-04-02 20:59:40 +03:00
{
List < int > newKeyData = new List < int > ( ) ;
var categoryData = _proto . Index ( category ) ;
var ready = false ;
var iteration = 0 ;
while ( ! ready )
{
//Generate try
newKeyData = new List < int > ( ) ;
for ( int i = 0 ; i < categoryData . Complexity ; i + + )
{
newKeyData . Add ( _random . Next ( - DepthCompexity , DepthCompexity ) ) ;
}
//Identity Check shitcode
// Н а текущий момент он пытается сгенерировать уникальный код. Если он 100 раз не смог сгенерировать уникальный код, он выдаст последний сгенерированный неуникальный.
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
}
}