304 lines
5.9 KiB
Plaintext
304 lines
5.9 KiB
Plaintext
@using Sandbox
|
|
@using Sandbox.UI
|
|
@using Sasalka
|
|
@inherits PanelComponent
|
|
@namespace Sandbox
|
|
|
|
<root>
|
|
<div class="crosshair"></div>
|
|
<div class="@( HasWeapon ? "" : "hidden" )">
|
|
<div class="ammo-counter">
|
|
<div class="ammo-info">
|
|
<div class="current-ammo">@CurrentAmmo</div>
|
|
<div class="separator">/</div>
|
|
<div class="max-ammo">@TotalInInventory</div>
|
|
|
|
@* <div class="inventory-ammo">(@MaxAmmo - вместимость магазина)</div> *@
|
|
</div>
|
|
</div>
|
|
|
|
@if ( IsReloading )
|
|
{
|
|
<div class="reload-progress">
|
|
<div class="reload-bar" style="width: @( ReloadProgress * 100 )%"></div>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
<!-- Панель управления сохранением инвентаря -->
|
|
<div class="save-status">
|
|
<div class="save-indicator @( HasSaveFile ? "has-save" : "no-save" )">
|
|
<div class="save-text">@( HasSaveFile ? "Сохранение есть" : "Нет сохранения" )</div>
|
|
</div>
|
|
|
|
@if ( HasSaveFile )
|
|
{
|
|
<button class="load-button" onmousedown="LoadInventory">
|
|
<div class="button-text">Загрузить</div>
|
|
</button>
|
|
}
|
|
|
|
<button class="save-button" onmousedown="SaveInventory">
|
|
<div class="button-text">Сохранить</div>
|
|
</button>
|
|
|
|
@if ( HasSaveFile )
|
|
{
|
|
<button class="clear-button" onmousedown="ClearSave">
|
|
<div class="button-text">Очистить</div>
|
|
</button>
|
|
}
|
|
</div>
|
|
</root>
|
|
|
|
<style>
|
|
.crosshair {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
width: 4px;
|
|
height: 4px;
|
|
background-color: rgba(255, 255, 255, 0.5);
|
|
border-radius: 50%;
|
|
transform: translate(-50%, -50%);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.ammo-counter {
|
|
position: absolute;
|
|
bottom: 100px;
|
|
right: 50px;
|
|
background: rgba(0, 0, 0, 0.7);
|
|
border-radius: 8px;
|
|
padding: 10px 15px;
|
|
color: white;
|
|
font-family: 'Arial', sans-serif;
|
|
font-weight: bold;
|
|
font-size: 18px;
|
|
min-width: 80px;
|
|
text-align: center;
|
|
|
|
.ammo-info {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
gap: 5px;
|
|
|
|
.current-ammo {
|
|
color: #ff6b6b;
|
|
}
|
|
|
|
.separator {
|
|
color: #666;
|
|
}
|
|
|
|
.max-ammo {
|
|
color: #999;
|
|
}
|
|
|
|
.inventory-ammo {
|
|
color: #4CAF50;
|
|
font-size: 14px;
|
|
margin-left: 8px;
|
|
}
|
|
}
|
|
}
|
|
|
|
.reload-progress {
|
|
position: absolute;
|
|
bottom: 100px;
|
|
right: 50px;
|
|
height: 4px;
|
|
width: 50px;
|
|
background: rgba(255, 255, 255, 0.2);
|
|
border-radius: 2px;
|
|
overflow: hidden;
|
|
|
|
.reload-bar {
|
|
height: 100%;
|
|
background: linear-gradient(90deg, #ff6b6b, #ff8e8e);
|
|
transition: width 0.1s ease;
|
|
}
|
|
}
|
|
|
|
.hidden {
|
|
display: none;
|
|
}
|
|
|
|
.save-status {
|
|
position: absolute;
|
|
top: 20px;
|
|
right: 20px;
|
|
background: rgba(0, 0, 0, 0.8);
|
|
border-radius: 8px;
|
|
padding: 12px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
min-width: 200px;
|
|
|
|
.save-indicator {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
|
|
&.has-save {
|
|
background: rgba(76, 175, 80, 0.2);
|
|
color: #4CAF50;
|
|
border: 1px solid #4CAF50;
|
|
}
|
|
|
|
&.no-save {
|
|
background: rgba(244, 67, 54, 0.2);
|
|
color: #F44336;
|
|
border: 1px solid #F44336;
|
|
}
|
|
|
|
.save-text {
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
|
|
button {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 8px 12px;
|
|
border-radius: 4px;
|
|
border: none;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
transition: all 0.2s ease;
|
|
|
|
&:hover {
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
&.save-button {
|
|
background: #2196F3;
|
|
color: white;
|
|
|
|
&:hover {
|
|
background: #1976D2;
|
|
}
|
|
}
|
|
|
|
&.load-button {
|
|
background: #4CAF50;
|
|
color: white;
|
|
|
|
&:hover {
|
|
background: #388E3C;
|
|
}
|
|
}
|
|
|
|
&.clear-button {
|
|
background: #F44336;
|
|
color: white;
|
|
|
|
&:hover {
|
|
background: #D32F2F;
|
|
}
|
|
}
|
|
|
|
.button-text {
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
}
|
|
</style>
|
|
|
|
@code {
|
|
private int CurrentAmmo { get; set; } = 0;
|
|
private int MaxAmmo { get; set; } = 0;
|
|
private bool IsReloading { get; set; } = false;
|
|
private float ReloadProgress { get; set; } = 0f;
|
|
private int TotalInInventory { get; set; } = 0;
|
|
private bool HasWeapon { get; set; } = false;
|
|
|
|
// Переменные для системы сохранения
|
|
private bool HasSaveFile { get; set; } = false;
|
|
private TimeSince _lastCheck = 0f;
|
|
|
|
protected override void OnUpdate()
|
|
{
|
|
if ( Dedugan.Local == null ) return;
|
|
|
|
var ammoInfo = Dedugan.Local.GetAmmoInfo();
|
|
CurrentAmmo = ammoInfo.current;
|
|
MaxAmmo = ammoInfo.max;
|
|
TotalInInventory = ammoInfo.totalInInventory;
|
|
|
|
ReloadProgress = Dedugan.Local.GetReloadProgress();
|
|
IsReloading = ReloadProgress < 1f;
|
|
|
|
// Проверяем, есть ли оружие в руках (если MaxAmmo > 0, значит есть оружие)
|
|
HasWeapon = MaxAmmo > 0;
|
|
|
|
// Проверяем наличие файла сохранения каждые 2 секунды
|
|
if ( _lastCheck > 2f )
|
|
{
|
|
CheckSaveFile();
|
|
_lastCheck = 0f;
|
|
}
|
|
}
|
|
|
|
protected override void OnStart()
|
|
{
|
|
CheckSaveFile();
|
|
}
|
|
|
|
private void CheckSaveFile()
|
|
{
|
|
HasSaveFile = Sasalka.InventorySaveSystem.HasSaveFile();
|
|
}
|
|
|
|
private void SaveInventory()
|
|
{
|
|
if ( Dedugan.Local?.Inventory != null )
|
|
{
|
|
Sasalka.InventorySaveSystem.SaveInventory( Dedugan.Local.Inventory );
|
|
CheckSaveFile();
|
|
}
|
|
}
|
|
|
|
private void LoadInventory()
|
|
{
|
|
if ( Dedugan.Local?.Inventory != null )
|
|
{
|
|
Sasalka.InventorySaveSystem.LoadInventory( Dedugan.Local.Inventory );
|
|
CheckSaveFile();
|
|
}
|
|
}
|
|
|
|
private void ClearSave()
|
|
{
|
|
Sasalka.InventorySaveSystem.DeleteSaveFile();
|
|
CheckSaveFile();
|
|
}
|
|
|
|
protected override int BuildHash()
|
|
{
|
|
if ( Dedugan.Local == null || !HasWeapon )
|
|
return -1;
|
|
|
|
var hash = new System.HashCode();
|
|
hash.Add( CurrentAmmo );
|
|
hash.Add( MaxAmmo );
|
|
hash.Add( TotalInInventory );
|
|
hash.Add( IsReloading );
|
|
hash.Add( ReloadProgress );
|
|
hash.Add( HasWeapon );
|
|
hash.Add( HasSaveFile );
|
|
|
|
return hash.ToHashCode();
|
|
}
|
|
}
|