2025-10-15 20:28:33 +04:00

372 lines
10 KiB
C#

using UnityEngine;
using Fusion;
using TMPro;
using System.Threading.Tasks;
using System;
namespace TPSBR.UI
{
public class UIGameplayView : UIView
{
// PRIVATE MEMBERS
[SerializeField]
private UIPlayer _player;
[SerializeField]
private UICrosshair _crosshair;
[SerializeField]
private UIHealth _health;
[SerializeField]
private UIWeapons _weapons;
[SerializeField]
private UIGameplayInteractions _interactions;
[SerializeField]
private UIAgentEffects _effects;
[SerializeField]
private UIGameplayEvents _events;
[SerializeField]
private UIShrinkingArea _shrinkingArea;
[SerializeField]
private UIKillFeed _killFeed;
[SerializeField]
private UIBehaviour _spectatingGroup;
[SerializeField]
private TextMeshProUGUI _spectatingText;
[SerializeField]
private UIHitDamageIndicator _hitDamage;
[SerializeField]
private UIJetpack _jetpack;
[SerializeField]
private UIButton _menuButton;
[Header("Gameplay Modes")]
[SerializeField]
private UIBattleRoyale _battleRoyale;
[Header("Events Setup")]
[SerializeField]
private Color _enemyKilledColor = Color.red;
[SerializeField]
private Color _playerDeathColor = Color.yellow;
[SerializeField]
private AudioSetup _enemyKilledSound;
[SerializeField]
private AudioSetup _playerDeathSound;
[SerializeField]
private Color _interactionFailedColor = Color.white;
[SerializeField]
private AudioSetup _interactionFailedSound;
private Agent _localAgent;
private NetworkBehaviourId _localAgentId;
// UIView INTERFACE
protected override void OnInitialize()
{
base.OnInitialize();
ClearLocalAgent();
Context.GameplayMode.OnAgentDeath += OnAgentDeath;
Context.GameplayMode.OnPlayerEliminated += OnPlayerEliminated;
Context.GameplayMode.OnPlayerJoinedGame += OnPlayerJoined;
Context.GameplayMode.OnPlayerLeftGame += OnPlayerLeft;
if (Context.Announcer != null)
{
Context.Announcer.Announce += OnAnnounce;
}
_battleRoyale.SetActive(Context.GameplayMode is BattleRoyaleGameplayMode);
if ((Application.isMobilePlatform == false || Application.isEditor == true) && Context.Settings.SimulateMobileInput == false)
{
_menuButton.SetActive(false);
}
if (_menuButton != null)
{
_menuButton.onClick.AddListener(OnMenuButton);
}
}
protected override void OnDeinitialize()
{
base.OnDeinitialize();
Context.GameplayMode.OnAgentDeath -= OnAgentDeath;
Context.GameplayMode.OnPlayerEliminated -= OnPlayerEliminated;
Context.GameplayMode.OnPlayerJoinedGame -= OnPlayerJoined;
Context.GameplayMode.OnPlayerLeftGame -= OnPlayerLeft;
if (Context.Announcer != null)
{
Context.Announcer.Announce -= OnAnnounce;
}
if (_menuButton != null)
{
_menuButton.onClick.RemoveListener(OnMenuButton);
}
}
protected override void OnTick()
{
base.OnTick();
if (Context.Runner == null || Context.Runner.IsRunning == false)
return;
if (Context.GameplayMode == null || Context.Runner.Exists(Context.GameplayMode.Object) == false)
return;
if (_localAgent != Context.ObservedAgent || (Context.ObservedAgent != null && _localAgentId != Context.ObservedAgent.Id))
{
if (Context.ObservedAgent == null)
{
ClearLocalAgent();
}
else
{
var player = Context.NetworkGame.GetPlayer(Context.ObservedPlayerRef);
if (player == null)
{
ClearLocalAgent();
}
else
{
SetLocalAgent(SceneUI.Context.ObservedAgent, player, Context.LocalPlayerRef == Context.ObservedPlayerRef);
}
}
}
var shrinkingArea = Context.GameplayMode.ShrinkingArea;
if (shrinkingArea != null && shrinkingArea.IsActive == true && shrinkingArea.IsPaused == false)
{
_shrinkingArea.SetActive(true);
_shrinkingArea.UpdateArea(Context.Runner, shrinkingArea);
}
else
{
_shrinkingArea.SetActive(false);
}
if (_localAgent == null)
return;
_health.UpdateHealth(_localAgent.Health);
_effects.UpdateEffects(_localAgent);
_weapons.UpdateWeapons(_localAgent.Weapons, _localAgent.AgentInput);
_crosshair.UpdateCrosshair(_localAgent);
_interactions.UpdateInteractions(Context, _localAgent);
_jetpack.UpdateJetpack(_localAgent.Jetpack);
}
// PRIVATE MEMBERS
private void OnHitPerformed(HitData hitData)
{
_crosshair.HitPerformed(hitData);
_hitDamage.HitPerformed(hitData);
}
private void OnAgentDeath(KillData killData)
{
var victimPlayer = Context.NetworkGame.GetPlayer(killData.VictimRef);
var killerPlayer = Context.NetworkGame.GetPlayer(killData.KillerRef);
_killFeed.ShowFeed(new KillFeedData
{
Killer = killerPlayer != null ? killerPlayer.Nickname : "",
Victim = victimPlayer != null ? victimPlayer.Nickname : "",
IsHeadshot = killData.Headshot,
DamageType = killData.HitType,
VictimIsLocal = killData.VictimRef != PlayerRef.None && killData.VictimRef == Context.LocalPlayerRef,
KillerIsLocal = killData.KillerRef != PlayerRef.None && killData.KillerRef == Context.LocalPlayerRef,
});
if (killData.VictimRef == Context.ObservedPlayerRef)
{
bool eliminated = victimPlayer != null ? victimPlayer.Statistics.IsEliminated : false;
_events.ShowEvent(new GameplayEventData
{
Name = eliminated == true ? "YOU WERE ELIMINATED" : "YOU WERE KILLED",
Description = killerPlayer != null ? $"Eliminated by {killerPlayer.Nickname}" : "",
Color = _playerDeathColor,
Sound = _playerDeathSound,
});
}
//else if (killData.KillerRef == Context.ObservedPlayerRef)
//{
// bool eliminated = killerPlayer != null ? killerPlayer.Statistics.IsEliminated : false;
// _events.ShowEvent(new GameplayEventData
// {
// Name = eliminated == true ? "ENEMY ELIMINATED" : "ENEMY KILLED",
// Description = victimPlayer != null ? victimPlayer.Nickname : "",
// Color = _enemyKilledColor,
// Sound = _enemyKilledSound,
// });
//}
else if (killData.KillerRef == Context.ObservedPlayerRef)
{
bool eliminated = killerPlayer != null ? killerPlayer.Statistics.IsEliminated : false;
_events.ShowEvent(new GameplayEventData
{
Name = eliminated == true ? "ENEMY ELIMINATED" : "ENEMY KILLED",
Description = victimPlayer != null ? victimPlayer.Nickname : "",
Color = _enemyKilledColor,
Sound = _enemyKilledSound,
});
}
if (killData.KillerRef == Context.LocalPlayerRef)
{
_ = ReportKillAsync();
}
}
private async Task ReportKillAsync()
{
try
{
if (PlayerPrefs.HasKey("WALLET_ADDRESS") == false)
return;
var wallet = PlayerPrefs.GetString("WALLET_ADDRESS");
if (string.IsNullOrWhiteSpace(wallet) == true)
return;
await GameDb.AddKillAsync(wallet);
}
catch (Exception ex)
{
Debug.LogError($"[Supabase] Failed to report kill: {ex.Message}");
}
}
private void OnPlayerEliminated(PlayerRef playerRef)
{
var player = Context.NetworkGame.GetPlayer(playerRef);
if (player == null)
return;
_killFeed.ShowFeed(new EliminationFeedData
{
Nickname = player.Nickname,
});
}
private void OnPlayerJoined(PlayerRef playerRef)
{
var player = Context.NetworkGame.GetPlayer(playerRef);
if (player == null)
return;
_killFeed.ShowFeed(new JoinedLeftFeedData
{
Joined = true,
Nickname = player.Nickname,
});
}
private void OnPlayerLeft(string nickname)
{
_killFeed.ShowFeed(new JoinedLeftFeedData
{
Joined = false,
Nickname = nickname,
});
}
private void OnAnnounce(AnnouncementData announcement)
{
if (announcement.FeedMessage.HasValue() == false)
return;
_killFeed.ShowFeed(new AnnouncementFeedData
{
Announcement = announcement.FeedMessage,
Color = announcement.Color,
});
}
private void OnMenuButton()
{
Context.Input.TrigggerBackAction();
}
private void SetLocalAgent(Agent agent, Player player, bool isLocalPlayer)
{
if (_localAgent != null)
{
_localAgent.Health.HitPerformed -= OnHitPerformed;
_localAgent.Health.HitTaken -= OnHitTaken;
_localAgent.Interactions.InteractionFailed -= OnInteractionFailed;
}
_localAgent = agent;
_localAgentId = agent.Id;
_health.SetActive(true);
_crosshair.SetActive(true);
_interactions.SetActive(true);
_effects.SetActive(true);
_spectatingGroup.SetActive(isLocalPlayer == false);
_jetpack.SetActive(true);
_weapons.SetActive(true);
_player.SetData(Context, player);
if (isLocalPlayer == false)
{
_spectatingText.text = player.Nickname;
}
agent.Health.HitPerformed += OnHitPerformed;
agent.Health.HitTaken += OnHitTaken;
agent.Interactions.InteractionFailed += OnInteractionFailed;
}
private void ClearLocalAgent()
{
_health.SetActive(false);
_weapons.SetActive(false);
_crosshair.SetActive(false);
_interactions.SetActive(false);
_effects.SetActive(false);
_spectatingGroup.SetActive(false);
_jetpack.SetActive(false);
if (_localAgent != null)
{
_localAgent.Health.HitPerformed -= OnHitPerformed;
_localAgent.Health.HitTaken -= OnHitTaken;
_localAgent.Interactions.InteractionFailed -= OnInteractionFailed;
_localAgent = null;
_localAgentId = default;
}
}
private void OnHitTaken(HitData hitData)
{
_effects.OnHitTaken(hitData);
}
private void OnInteractionFailed(string reason)
{
_events.ShowEvent(new GameplayEventData
{
Name = string.Empty,
Description = reason,
Color = _interactionFailedColor,
Sound = _interactionFailedSound,
}, false, true);
}
}
}