using System; using Microsoft.Xna.Framework.Input; using LiteNetLib; using Syntriax.Engine.Core; using Syntriax.Engine.Network; using Syntriax.Engine.Network.Abstract; namespace Pong.Behaviours; public class PongManagerBehaviour : BehaviourOverride { public Action? OnReset { get; set; } = null; public Action? OnFinished { get; set; } = null; public Action? OnScoresUpdated { get; set; } = null; public Action? OnScored { get; set; } = null; private INetworkCommunicator communicator = null!; public int ScoreLeft { get; private set; } = 0; public int ScoreRight { get; private set; } = 0; public int ScoreSum => ScoreLeft + ScoreRight; public int WinScore { get; } = 5; public PongManagerBehaviour() => WinScore = 5; public PongManagerBehaviour(int winScore) => WinScore = winScore; protected override void OnFirstActiveFrame() { KeyboardInputsBehaviour? buttonInputs = null!; if (!BehaviourController.TryGetBehaviour(out buttonInputs)) buttonInputs = BehaviourController.AddBehaviour(); if (!GameObject.GameManager.TryFindBehaviour(out INetworkCommunicator? foundCommunicator)) throw new Exception($"{nameof(INetworkCommunicator)} is missing on GameManager."); buttonInputs.RegisterOnRelease(Keys.Space, (_, _1) => Reset()); communicator = foundCommunicator; communicator.RegisterEntityListener(this, OnMessageReceived); } private void OnMessageReceived(NetPacketReader reader) { ScoreLeft = reader.GetInt(); ScoreRight = reader.GetInt(); OnScoresUpdated?.Invoke(this); CheckFinish(); } public void ScoreToLeft() { ScoreLeft++; OnScoresUpdated?.Invoke(this); OnScored?.Invoke(this); SendData(); CheckFinish(); } public void ScoreToRight() { ScoreRight++; OnScoresUpdated?.Invoke(this); OnScored?.Invoke(this); SendData(); CheckFinish(); } public void Reset() { ScoreLeft = ScoreRight = 0; OnScoresUpdated?.Invoke(this); OnReset?.Invoke(this); SendData(); } private void CheckFinish() { int halfwayScore = (int)(WinScore * .5f); if (ScoreLeft > halfwayScore || ScoreRight > halfwayScore) OnFinished?.Invoke(this); } private void SendData() { if (communicator is not INetworkServer server) return; LiteNetLib.Utils.NetDataWriter dataWriter = communicator.GetEntityWriter(this); dataWriter.Put(ScoreLeft); dataWriter.Put(ScoreRight); server.Manager.SendToAll(dataWriter, LiteNetLib.DeliveryMethod.ReliableOrdered); } }