261 lines
7.6 KiB
C#
261 lines
7.6 KiB
C#
using sodoffmmo.Data;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Numerics;
|
|
using System.Text;
|
|
|
|
namespace sodoffmmo.Core
|
|
{
|
|
public class SWRacingRoom : Room
|
|
{
|
|
|
|
class SWPlayerState
|
|
{
|
|
public int Index;
|
|
public Vector3 PosTransform = new();
|
|
public string Token = "";
|
|
public bool IsHost;
|
|
public bool IsReady;
|
|
public bool SceneLoaded;
|
|
public bool CountdownFinished;
|
|
public int ColorIndex;
|
|
public string VehicleResName = "";
|
|
public int CurrentLap;
|
|
public float FinishedTime = -1f;
|
|
public bool IsTrackPrebuilt;
|
|
public int TrackIdx;
|
|
public string TrackStatus = "ZR";
|
|
}
|
|
|
|
public SWRacingRoom() : base(null, "ShipWreckMPRoom", true)
|
|
{
|
|
}
|
|
|
|
public bool CountdownStarted { get; set; } = false;
|
|
public bool RaceOngoing { get; set; } = false;
|
|
public bool BuddiesOnly { get; set; } = false;
|
|
|
|
Dictionary<Client, SWPlayerState> Players = new();
|
|
Client? host = null;
|
|
int nextIndex = 1;
|
|
|
|
public void AddPlayer(Client client)
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
var state = new SWPlayerState { Index = nextIndex++ };
|
|
if(host is null)
|
|
{
|
|
host = client;
|
|
state.IsHost = true;
|
|
}
|
|
Players[client] = state;
|
|
}
|
|
}
|
|
|
|
public int GetIndex(Client client)
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
var state = Players[client];
|
|
return state.Index;
|
|
}
|
|
}
|
|
|
|
public int GetReadyCount()
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
int readyCount = 0;
|
|
foreach(var (client, s) in Players)
|
|
{
|
|
if (s.IsReady)
|
|
readyCount++;
|
|
}
|
|
return readyCount;
|
|
}
|
|
}
|
|
|
|
public IEnumerable<int> GetPlayersWithinRadius(Vector3 blast, float hitRadius, Client? excluding)
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
float targetRadiusSquared = hitRadius * hitRadius;
|
|
List<int> targetedPlayers = [];
|
|
|
|
foreach(var player in Players)
|
|
{
|
|
if (player.Key.ClientID == excluding?.ClientID) continue;
|
|
if (Vector3.DistanceSquared(player.Value.PosTransform, blast) < targetRadiusSquared)
|
|
targetedPlayers.Add(player.Value.Index);
|
|
}
|
|
|
|
return targetedPlayers;
|
|
}
|
|
}
|
|
|
|
public void SetPlayerPosition(Client client, float X, float Y, float Z)
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
var state = Players[client];
|
|
state.PosTransform.X = X;
|
|
state.PosTransform.Y = Y;
|
|
state.PosTransform.Z = Z;
|
|
}
|
|
}
|
|
|
|
public void SetReady(Client client, bool ready)
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
var state = Players[client];
|
|
state.IsReady = ready;
|
|
}
|
|
}
|
|
|
|
public void SetTrack(Client client, int trackId)
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
var state = Players[client];
|
|
state.TrackIdx = trackId;
|
|
}
|
|
}
|
|
|
|
public void SetTrackStatus(Client client, string statusCode)
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
var state = Players[client];
|
|
state.TrackStatus = statusCode;
|
|
}
|
|
}
|
|
|
|
public void SetIsPrebuiltTrack(Client client, bool isPrebuiltTrack)
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
var state = Players[client];
|
|
state.IsTrackPrebuilt = isPrebuiltTrack;
|
|
}
|
|
}
|
|
|
|
public void SetBoat(Client client, string boatRes, int colorIndex = 0)
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
var state = Players[client];
|
|
state.VehicleResName = boatRes;
|
|
state.ColorIndex = colorIndex;
|
|
}
|
|
}
|
|
|
|
public void SetToken(Client client, string token)
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
var state = Players[client];
|
|
state.Token = token;
|
|
}
|
|
}
|
|
|
|
public bool SetSceneLoaded(Client client)
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
Players[client].SceneLoaded = true;
|
|
foreach (var (_, s) in Players)
|
|
if (!s.SceneLoaded) return false;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public bool SetCountdownFinished(Client client)
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
Players[client].CountdownFinished = true;
|
|
foreach (var (_, s) in Players)
|
|
if (!s.CountdownFinished) return false;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public void SetPlayerLap(Client client, int lap)
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
var state = Players[client];
|
|
state.CurrentLap = lap;
|
|
}
|
|
}
|
|
|
|
public void SetFinishedTime(Client client, float time)
|
|
{
|
|
lock (roomLock)
|
|
{
|
|
var state = Players[client];
|
|
state.FinishedTime = time;
|
|
}
|
|
}
|
|
|
|
public NetworkPacket GetAMPacket()
|
|
{
|
|
List<string> info = [ "AM" ];
|
|
foreach(var (client, s) in Players)
|
|
{
|
|
info.Add(s.IsHost ? "ZJ" : "");
|
|
info.Add(client.PlayerData.UNToken);
|
|
info.Add(s.Index.ToString());
|
|
info.Add(s.ColorIndex.ToString());
|
|
info.Add(s.VehicleResName);
|
|
info.Add(s.IsReady ? "AN" : "");
|
|
info.Add(s.IsTrackPrebuilt ? "ZP" : "ZQ");
|
|
info.Add(s.TrackIdx.ToString());
|
|
info.Add(s.TrackStatus);
|
|
}
|
|
|
|
string joined = string.Join("|", info);
|
|
|
|
return Utils.ArrNetworkPacket(["AM", joined], "", Id);
|
|
}
|
|
|
|
System.Timers.Timer? countdownTimer;
|
|
int lobbyCounter;
|
|
|
|
public void TryStartLobbyCountdown()
|
|
{
|
|
Console.WriteLine($"Attempted To Start SWL Lobby Countdown On SWL {Id}. Player Count - {Players.Count}");
|
|
|
|
lock (roomLock)
|
|
{
|
|
if (Players.Count <= 1) return; // this is multiplayers, don't just start a singleplayer time trial lmao
|
|
if (CountdownStarted || GetReadyCount() < Players.Count) return;
|
|
|
|
string joined = string.Join("|", "AB", Players.Count.ToString(), "3");
|
|
Send(Utils.ArrNetworkPacket([joined], "", Id));
|
|
|
|
CountdownStarted = true;
|
|
Console.WriteLine($"Countdown Started On SWL {Id}");
|
|
}
|
|
|
|
lobbyCounter = 3;
|
|
countdownTimer = new(1000) { AutoReset = true };
|
|
countdownTimer.Elapsed += TickLobbyCountdown;
|
|
countdownTimer.Enabled = true;
|
|
}
|
|
|
|
private void TickLobbyCountdown(object? sender, System.Timers.ElapsedEventArgs e)
|
|
{
|
|
Console.WriteLine($"Lobby Countdown Tick TS - {DateTime.Now}");
|
|
if(--lobbyCounter <= 0)
|
|
{
|
|
countdownTimer!.Stop();
|
|
string joined = string.Join("|", "ZH", lobbyCounter.ToString());
|
|
Send(Utils.ArrNetworkPacket([joined], "", Id));
|
|
RaceOngoing = true;
|
|
}
|
|
}
|
|
}
|
|
} |