Skip to content
This repository has been archived by the owner on Oct 16, 2022. It is now read-only.

Commit

Permalink
Major Deathmatch rework
Browse files Browse the repository at this point in the history
  • Loading branch information
iamsilk committed Mar 1, 2022
1 parent de87857 commit 675bd69
Show file tree
Hide file tree
Showing 89 changed files with 1,759 additions and 1,296 deletions.
2 changes: 1 addition & 1 deletion Deathmatch.API/Deathmatch.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="OpenMod.Unturned" Version="3.1.2" />
<PackageReference Include="OpenMod.Unturned" Version="3.2.2" />
</ItemGroup>

</Project>
9 changes: 6 additions & 3 deletions Deathmatch.API/Loadouts/ILoadout.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
using Deathmatch.API.Players;
using Cysharp.Threading.Tasks;
using Deathmatch.API.Players;
using OpenMod.API.Permissions;
using System.Threading.Tasks;

namespace Deathmatch.API.Loadouts
{
public interface ILoadout
{
string Title { get; }

string? Permission { get; }
UniTask GiveToPlayer(IGamePlayer player);

void GiveToPlayer(IGamePlayer player);
Task<bool> IsPermitted(IPermissionActor actor);
}
}
15 changes: 9 additions & 6 deletions Deathmatch.API/Loadouts/ILoadoutCategory.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using OpenMod.API;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Deathmatch.API.Loadouts
{
Expand All @@ -11,12 +10,16 @@ public interface ILoadoutCategory
IReadOnlyCollection<string> Aliases { get; }

IOpenModComponent Component { get; }

IReadOnlyCollection<ILoadout> GetLoadouts();

Task SaveLoadouts();
ILoadout? GetDefaultLoadout();

void AddLoadout(ILoadout loadout);
bool RemoveLoadout(ILoadout loadout);
IReadOnlyCollection<ILoadout> GetLoadouts();
}

public interface ILoadoutCategory<out TLoadout> : ILoadoutCategory where TLoadout : ILoadout
{
new TLoadout? GetDefaultLoadout();

new IReadOnlyCollection<TLoadout> GetLoadouts();
}
}
6 changes: 3 additions & 3 deletions Deathmatch.API/Loadouts/ILoadoutSelector.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using Deathmatch.API.Players;
using OpenMod.API.Ioc;
using System.Threading.Tasks;

namespace Deathmatch.API.Loadouts
{
[Service]
public interface ILoadoutSelector
{
ILoadout? GetLoadout(IGamePlayer player, string category);
Task SetLoadout(IGamePlayer player, string category, string loadout);
ILoadout? GetSelectedLoadout(IGamePlayer player, ILoadoutCategory category);

void SetSelectedLoadout(IGamePlayer player, ILoadoutCategory category, ILoadout loadout);
}
}
23 changes: 22 additions & 1 deletion Deathmatch.API/Matches/IMatchExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,33 @@ namespace Deathmatch.API.Matches
[Service]
public interface IMatchExecutor
{
/// <summary>
/// The current running match.
/// </summary>
IMatch? CurrentMatch { get; }

/// <summary>
/// Gets all players in the current match pool.
/// </summary>
/// <returns>All players in the current match pool.</returns>
IReadOnlyCollection<IGamePlayer> GetParticipants();
UniTask AddParticipant(IGamePlayer player);

/// <summary>
/// Adds the player to the match pool and also the current match if one is running.
/// </summary>
/// <param name="player">The player to add.</param>
/// <returns><b>true</b> if the player was added to the match pool, <b>false</b> otherwise.</returns>
UniTask<bool> AddParticipant(IGamePlayer player);


UniTask RemoveParticipant(IGamePlayer user);

/// <summary>
/// Attempts to start a match.
/// </summary>
/// <param name="registration"></param>
/// <returns><b>true</b> when a match is started successfully. <b>false</b> if a match is already running.</returns>
/// <exception cref="OpenMod.API.Commands.UserFriendlyException">When a match could not be started due to user error.</exception>
UniTask<bool> StartMatch(IMatchRegistration? registration = null);
}
}
78 changes: 78 additions & 0 deletions Deathmatch.API/Matches/MatchExecutorExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using Deathmatch.API.Players;
using OpenMod.Unturned.Players;
using OpenMod.Unturned.Users;
using SDG.Unturned;
using Steamworks;
using System;
using System.Linq;

namespace Deathmatch.API.Matches
{
public static class MatchExecutorExtensions
{
public static IGamePlayer? GetParticipant(this IMatchExecutor matchExecutor, Predicate<IGamePlayer> predicate)
{
return matchExecutor.GetParticipants().FirstOrDefault(x => predicate(x));
}

public static IGamePlayer? GetParticipant(this IMatchExecutor matchExecutor, ulong steamId)
{
return matchExecutor.GetParticipants().FirstOrDefault(x => x.SteamId.m_SteamID == steamId);
}

public static IGamePlayer? GetParticipant(this IMatchExecutor matchExecutor, CSteamID steamId)
{
return matchExecutor.GetParticipants().FirstOrDefault(x => x.SteamId == steamId);
}

public static IGamePlayer? GetParticipant(this IMatchExecutor matchExecutor, Player player)
{
return matchExecutor.GetParticipants().FirstOrDefault(x => x.Player == player);
}

public static IGamePlayer? GetParticipant(this IMatchExecutor matchExecutor, UnturnedPlayer player)
{
return matchExecutor.GetParticipants().FirstOrDefault(x => x.SteamId == player.SteamId);
}

public static IGamePlayer? GetParticipant(this IMatchExecutor matchExecutor, UnturnedUser user)
{
return matchExecutor.GetParticipants().FirstOrDefault(x => x.SteamId == user.SteamId);
}

public static IGamePlayer? GetParticipant(this IMatchExecutor matchExecutor, IGamePlayer player)
{
return matchExecutor.GetParticipants().FirstOrDefault(x => x == player);
}

public static bool IsParticipant(this IMatchExecutor matchExecutor, ulong steamId)
{
return matchExecutor.GetParticipant(steamId) != null;
}

public static bool IsParticipant(this IMatchExecutor matchExecutor, CSteamID steamId)
{
return matchExecutor.GetParticipant(steamId) != null;
}

public static bool IsParticipant(this IMatchExecutor matchExecutor, Player player)
{
return matchExecutor.GetParticipant(player) != null;
}

public static bool IsParticipant(this IMatchExecutor matchExecutor, UnturnedPlayer player)
{
return matchExecutor.GetParticipant(player) != null;
}

public static bool IsParticipant(this IMatchExecutor matchExecutor, UnturnedUser user)
{
return matchExecutor.GetParticipant(user) != null;
}

public static bool IsParticipant(this IMatchExecutor matchExecutor, IGamePlayer player)
{
return matchExecutor.GetParticipant(player) != null;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Cysharp.Threading.Tasks;
using Deathmatch.API.Matches;
using Deathmatch.API.Players;
using OpenMod.Unturned.Players;
using OpenMod.Unturned.Users;
Expand All @@ -9,7 +8,7 @@
using System.Collections.Generic;
using System.Linq;

namespace Deathmatch.Core.Matches.Extensions
namespace Deathmatch.API.Matches
{
public static class MatchExtensions
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
using Deathmatch.API.Matches;
using Deathmatch.API.Matches.Registrations;
using Deathmatch.API.Matches.Registrations;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Deathmatch.Core.Matches.Extensions
namespace Deathmatch.API.Matches
{
public static class MatchManagerExtensions
{
Expand Down
11 changes: 8 additions & 3 deletions Deathmatch.API/Matches/MatchStatus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public enum MatchStatus
/// <summary>
/// Default value. Shouldn't be used.
/// </summary>
Uninitialized,
Unknown,

/// <summary>
/// When a match has been initialized but <see cref="IMatch.StartAsync"/> has not yet been called.
Expand Down Expand Up @@ -33,8 +33,13 @@ public enum MatchStatus
Ended,

/// <summary>
/// When an exception occurred either during <see cref="IMatch.StartAsync"/> or <see cref="IMatch.EndAsync"/>.
/// When an exception occurred during <see cref="IMatch.StartAsync"/>.
/// </summary>
Exception
ExceptionWhenStarting,

/// <summary>
/// When an exception occurred during <see cref="IMatch.EndAsync"/>.
/// </summary>
ExceptionWhenEnding
}
}
32 changes: 15 additions & 17 deletions Deathmatch.Core/Commands/CommandDMStart.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using Cysharp.Threading.Tasks;
using Deathmatch.API.Matches;
using Deathmatch.Core.Helpers;
using Deathmatch.API.Matches.Registrations;
using Microsoft.Extensions.Localization;
using OpenMod.API.Commands;
using OpenMod.Core.Commands;
using OpenMod.Unturned.Commands;
using System;
using Deathmatch.Core.Matches.Extensions;

namespace Deathmatch.Core.Commands
{
Expand All @@ -30,27 +30,25 @@ public CommandDMStart(IMatchManager matchManager,

protected override async UniTask OnExecuteAsync()
{
var title = await Context.Parameters.GetAsync<string>(0, null);
IMatchRegistration? registration = null;

var registration = string.IsNullOrWhiteSpace(title)
? _matchManager.GetMatchRegistrations().RandomElement()
: _matchManager.GetMatchRegistration(title!);

if (registration == null)
if (Context.Parameters.Length > 0)
{
await PrintAsync(_stringLocalizer["commands:dmstart:not_found"]);
return;
}
var title = await Context.Parameters.GetAsync<string>(0, null) ?? string.Empty;

if (await _matchExecutor.StartMatch(registration))
{
await PrintAsync(_stringLocalizer["commands:dmstart:success",
new { registration.Title }]);
registration = (string.IsNullOrEmpty(title) ? null : _matchManager.GetMatchRegistration(title))
?? throw new UserFriendlyException(_stringLocalizer["commands:dmstart:not_found"]);
}
else

if (!await _matchExecutor.StartMatch(registration))
{
await PrintAsync(_stringLocalizer["commands:dmstart:failure"]);
throw new UserFriendlyException(_stringLocalizer["commands:dmstart:match_running"]);
}

registration = _matchExecutor.CurrentMatch?.Registration ?? throw new Exception(
$"Match started but {nameof(IMatchExecutor)}.{nameof(IMatchExecutor.CurrentMatch)} or registration is null");

await PrintAsync(_stringLocalizer["commands:dmstart:success", new {registration.Title}]);
}
}
}
18 changes: 15 additions & 3 deletions Deathmatch.Core/Commands/CommandJoin.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Cysharp.Threading.Tasks;
using Deathmatch.API.Matches;
using Deathmatch.API.Players;
using Microsoft.Extensions.Localization;
using OpenMod.Core.Commands;
using OpenMod.Unturned.Commands;
using OpenMod.Unturned.Users;
Expand All @@ -16,20 +17,31 @@ public class CommandJoin : UnturnedCommand
{
private readonly IGamePlayerManager _playerManager;
private readonly IMatchExecutor _matchExecutor;
private readonly IStringLocalizer _stringLocalizer;

public CommandJoin(IGamePlayerManager playerManager,
public CommandJoin(IServiceProvider serviceProvider,
IGamePlayerManager playerManager,
IMatchExecutor matchExecutor,
IServiceProvider serviceProvider) : base(serviceProvider)
IStringLocalizer stringLocalizer) : base(serviceProvider)
{
_playerManager = playerManager;
_matchExecutor = matchExecutor;
_stringLocalizer = stringLocalizer;
}

protected override async UniTask OnExecuteAsync()
{
var player = _playerManager.GetPlayer((UnturnedUser)Context.Actor);

await _matchExecutor.AddParticipant(player);
if (await _matchExecutor.AddParticipant(player))
{
await player.PrintMessageAsync(_stringLocalizer["commands:join:success"]);
}
else
{

await player.PrintMessageAsync(_stringLocalizer["commands:join:failure"]);
}
}
}
}
Loading

0 comments on commit 675bd69

Please sign in to comment.