Skip to content

Commit

Permalink
Merge pull request #103 from MrDave1999/feat/FlagSystem
Browse files Browse the repository at this point in the history
feat: Implement the main mechanics for Capture the Flag mode
  • Loading branch information
MrDave1999 authored Sep 21, 2024
2 parents 857f65c + 64bdeff commit 6ee5bc7
Show file tree
Hide file tree
Showing 18 changed files with 453 additions and 6 deletions.
72 changes: 72 additions & 0 deletions src/Application/Common/Resources/Messages.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions src/Application/Common/Resources/Messages.resx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@
<data name="BetaIsWinner" xml:space="preserve">
<value>This round was won by the Beta team</value>
</data>
<data name="BlueFlagIsNotAtBasePosition" xml:space="preserve">
<value>~n~~n~~n~~b~The blue flag is not at its base position</value>
</data>
<data name="ConsecutiveKills" xml:space="preserve">
<value>{PlayerName} has had {Kills} consecutive kills without dying</value>
</data>
Expand Down Expand Up @@ -207,6 +210,24 @@
<data name="NoPermissions" xml:space="preserve">
<value>You do not have permissions to use this command</value>
</data>
<data name="OnFlagAtBasePosition" xml:space="preserve">
<value>~n~~n~~n~{GameText}Defend this flag from enemy capture!</value>
</data>
<data name="OnFlagCaptured" xml:space="preserve">
<value>{PlayerName} has captured the {TeamName} team's {ColorName} flag! Keep an eye on the score!</value>
</data>
<data name="OnFlagDropped" xml:space="preserve">
<value>{PlayerName} has dropped the {TeamName} team's {ColorName} flag! Retrieve it before the enemy does!</value>
</data>
<data name="OnFlagReturned" xml:space="preserve">
<value>{PlayerName} has returned the {TeamName} team's {ColorName} flag to its base! Keep up the defense!</value>
</data>
<data name="OnFlagScore" xml:space="preserve">
<value>{PlayerName} has brought the {ColorName} flag to the {TeamName} team's base. Point scored!</value>
</data>
<data name="OnFlagTaken" xml:space="preserve">
<value>{PlayerName} has taken the {TeamName} team's {ColorName} flag! Keep an eye on the score!</value>
</data>
<data name="PasswordCannotBeEmpty" xml:space="preserve">
<value>Password cannot be empty</value>
</data>
Expand All @@ -231,6 +252,9 @@
<data name="RedeemedPoints" xml:space="preserve">
<value>{PlayerName} redeemed their points for the combo: {ComboName}</value>
</data>
<data name="RedFlagIsNotAtBasePosition" xml:space="preserve">
<value>~n~~n~~n~~r~The red flag is not at its base position</value>
</data>
<data name="SpawnLocationFailure" xml:space="preserve">
<value>A spawn location can only be obtained for the alpha or beta team</value>
</data>
Expand Down
4 changes: 4 additions & 0 deletions src/Application/Maps/Services/MapRotationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,12 @@ private void OnLoadingMap()
_worldService.SendClientMessage(Color.Orange, message);
IMap nextMap = currentMap.NextMap;
_mapInfoService.Load(nextMap);
Team.Alpha.Flag.RemoveCarrier();
Team.Beta.Flag.RemoveCarrier();
_teamPickupService.DestroyAllPickups();
_teamPickupService.CreateFlagFromBasePosition(Team.Alpha);
_teamPickupService.CreateFlagFromBasePosition(Team.Beta);
_teamIconService.DestroyAll();
_teamIconService.CreateFromBasePosition(Team.Alpha);
_teamIconService.CreateFromBasePosition(Team.Beta);
_serverService.SendRconCommand($"loadfs {nextMap.Name}");
Expand Down
15 changes: 15 additions & 0 deletions src/Application/Teams/Flags/Events/OnFlagAtBasePosition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace CTF.Application.Teams.Flags.Events;

/// <summary>
/// This event occurs when a player attempts to pick up their own team's flag, which is currently at the base.
/// </summary>
public class OnFlagAtBasePosition : IFlagEvent
{
public FlagStatus FlagStatus => FlagStatus.InitialPosition;

public void Handle(Team team, Player player)
{
var text = Smart.Format(Messages.OnFlagAtBasePosition, team);
player.GameText(text, 5000, 3);
}
}
35 changes: 35 additions & 0 deletions src/Application/Teams/Flags/Events/OnFlagCaptured.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace CTF.Application.Teams.Flags.Events;

/// <summary>
/// This event occurs when a player has captured the opposing team's flag from their base.
/// </summary>
public class OnFlagCaptured(
IPlayerRepository playerRepository,
IWorldService worldService,
TeamPickupService teamPickupService,
TeamSoundsService teamSoundsService,
PlayerStatsRenderer playerStatsRenderer) : IFlagEvent
{
public FlagStatus FlagStatus => FlagStatus.Captured;

public void Handle(Team team, Player player)
{
teamPickupService.CreatePickupWithInfo(team);
teamPickupService.DestroyFlag(team);
teamSoundsService.PlayFlagTakenSound(team);
var message = Smart.Format(Messages.OnFlagCaptured, new
{
PlayerName = player.Name,
TeamName = team.Name,
ColorName = team.ColorName
});
worldService.SendClientMessage(team.ColorHex, message);
worldService.GameText($"~n~~n~~n~{team.GameText}{team.ColorName} flag captured!", 5000, 3);

PlayerInfo playerInfo = player.GetInfo();
playerInfo.StatsPerRound.AddPoints(5);
playerInfo.AddCapturedFlags();
playerRepository.UpdateCapturedFlags(playerInfo);
playerStatsRenderer.UpdateTextDraw(player);
}
}
32 changes: 32 additions & 0 deletions src/Application/Teams/Flags/Events/OnFlagDropped.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace CTF.Application.Teams.Flags.Events;

/// <summary>
/// This event occurs when a player has dropped the opposing team's flag.
/// </summary>
public class OnFlagDropped(
IPlayerRepository playerRepository,
IWorldService worldService,
TeamPickupService teamPickupService,
TeamSoundsService teamSoundsService) : IFlagEvent
{
public FlagStatus FlagStatus => FlagStatus.Dropped;

public void Handle(Team team, Player player)
{
teamPickupService.CreateFlagFromVector3(team, player.Position);
teamSoundsService.PlayFlagDroppedSound(team);
team.Flag.RemoveCarrier();
var message = Smart.Format(Messages.OnFlagDropped, new
{
PlayerName = player.Name,
TeamName = team.Name,
ColorName = team.ColorName
});
worldService.SendClientMessage(team.ColorHex, message);
worldService.GameText($"~n~~n~~n~{team.GameText}{team.ColorName} flag dropped!", 5000, 3);

PlayerInfo playerInfo = player.GetInfo();
playerInfo.AddDroppedFlags();
playerRepository.UpdateDroppedFlags(playerInfo);
}
}
35 changes: 35 additions & 0 deletions src/Application/Teams/Flags/Events/OnFlagReturned.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace CTF.Application.Teams.Flags.Events;

/// <summary>
/// This event occurs when a player has returned the flag to their team's base.
/// </summary>
public class OnFlagReturned(
IPlayerRepository playerRepository,
IWorldService worldService,
TeamPickupService teamPickupService,
TeamSoundsService teamSoundsService,
PlayerStatsRenderer playerStatsRenderer) : IFlagEvent
{
public FlagStatus FlagStatus => FlagStatus.Returned;

public void Handle(Team team, Player player)
{
teamPickupService.CreateFlagFromBasePosition(team);
teamPickupService.DestroyPickupWithInfo(team);
teamSoundsService.PlayFlagReturnedSound(team);
var message = Smart.Format(Messages.OnFlagReturned, new
{
PlayerName = player.Name,
TeamName = team.Name,
ColorName = team.ColorName
});
worldService.SendClientMessage(team.ColorHex, message);
worldService.GameText($"~n~~n~~n~{team.GameText}{team.ColorName} flag returned!", 5000, 3);

PlayerInfo playerInfo = player.GetInfo();
playerInfo.StatsPerRound.AddPoints(5);
playerInfo.AddReturnedFlags();
playerRepository.UpdateReturnedFlags(playerInfo);
playerStatsRenderer.UpdateTextDraw(player);
}
}
50 changes: 50 additions & 0 deletions src/Application/Teams/Flags/Events/OnFlagScore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
namespace CTF.Application.Teams.Flags.Events;

/// <summary>
/// This event occurs when a player has captured the opposing team's flag and brought it back to their own base.
/// </summary>
public class OnFlagScore(
IPlayerRepository playerRepository,
IWorldService worldService,
TeamPickupService teamPickupService,
TeamSoundsService teamSoundsService,
TeamTextDrawRenderer teamTextDrawRenderer,
PlayerStatsRenderer playerStatsRenderer) : IFlagEvent
{
public FlagStatus FlagStatus => FlagStatus.Brought;

public void Handle(Team team, Player player)
{
teamPickupService.CreateFlagFromBasePosition(team.RivalTeam);
teamPickupService.DestroyPickupWithInfo(team.RivalTeam);
teamSoundsService.PlayTeamScoresSound(team);
teamTextDrawRenderer.UpdateTeamScore(team);

var message = Smart.Format(Messages.OnFlagScore, new
{
PlayerName = player.Name,
TeamName = team.Name,
ColorName = team.RivalTeam.ColorName
});
worldService.SendClientMessage(team.ColorHex, message);
worldService.GameText($"~n~~n~~n~{team.GameText}{team.ColorName} team scores!", 5000, 3);

PlayerInfo playerInfo = player.GetInfo();
playerInfo.StatsPerRound.AddPoints(8);
playerInfo.AddBroughtFlags();
playerRepository.UpdateBroughtFlags(playerInfo);
GiveRewards(team);
}

private void GiveRewards(Team team)
{
TeamMembers teamMembers = team.Members;
foreach (Player player in teamMembers)
{
PlayerInfo playerInfo = player.GetInfo();
playerInfo.StatsPerRound.AddPoints(5);
player.AddHealth(10);
playerStatsRenderer.UpdateTextDraw(player);
}
}
}
26 changes: 26 additions & 0 deletions src/Application/Teams/Flags/Events/OnFlagTaken.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace CTF.Application.Teams.Flags.Events;

/// <summary>
/// This event occurs when a player has taken the flag from a position other than the base.
/// </summary>
public class OnFlagTaken(
IWorldService worldService,
TeamPickupService teamPickupService,
TeamSoundsService teamSoundsService) : IFlagEvent
{
public FlagStatus FlagStatus => FlagStatus.Taken;

public void Handle(Team team, Player player)
{
teamPickupService.DestroyFlag(team);
teamSoundsService.PlayFlagTakenSound(team);
var message = Smart.Format(Messages.OnFlagTaken, new
{
PlayerName = player.Name,
TeamName = team.Name,
ColorName = team.ColorName
});
worldService.SendClientMessage(team.ColorHex, message);
worldService.GameText($"~n~~n~~n~{team.GameText}{team.ColorName} flag taken!", 5000, 3);
}
}
Loading

0 comments on commit 6ee5bc7

Please sign in to comment.