Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Bold & Italics = being worked on.
- [ ] Profile implementation (DB)
- [ ] Points/Skill Groups (DB)
- [ ] Player settings (DB)
- [ ] Run replays
- [X] Run replays
- [X] Saveloc/Tele
- [ ] Style implementation (SW, HSW, BW)
- [ ] Paint (?)
2 changes: 1 addition & 1 deletion cfg/SurfTimer/server_settings.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ sv_staminalandcost 0
sv_timebetweenducks 0

// Some replay bot shit (took so fucking long to debug)
bot_quota 1 // This is gonna be used to change the amount of bots allowed (per stages/bonuses/etc) when stages/bonuses/etc added
// bot_quota 1 No need for this, because the server handles it
bot_quota_mode "normal"
bot_join_after_player 1
bot_join_team CT
Expand Down
206 changes: 192 additions & 14 deletions src/ST-Commands/PlayerCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public void PlayerGoToStage(CCSPlayerController? player, CommandInfo command)
return;

int stage = Int32.Parse(command.ArgByIndex(1)) - 1;
if (stage > CurrentMap.Stages - 1)
if (stage > CurrentMap.Stages - 1 && CurrentMap.Stages > 0)
stage = CurrentMap.Stages - 1;

// Must be 1 argument
Expand Down Expand Up @@ -84,7 +84,6 @@ public void PlayerGoToStage(CCSPlayerController? player, CommandInfo command)
player.PrintToChat($"{PluginPrefix} {ChatColors.Red}Invalid stage provided. Usage: {ChatColors.Green}!s <stage>");
}

// Test command
[ConsoleCommand("css_spec", "Moves a player automaticlly into spectator mode")]
public void MovePlayerToSpectator(CCSPlayerController? player, CommandInfo command)
{
Expand All @@ -94,31 +93,210 @@ public void MovePlayerToSpectator(CCSPlayerController? player, CommandInfo comma
player.ChangeTeam(CsTeam.Spectator);
}

/*
#########################
Reaplay Commands
#########################
*/
[ConsoleCommand("css_replaybotpause", "Pause the replay bot playback")]
[ConsoleCommand("css_rbpause", "Pause the replay bot playback")]
public void PauseReplay(CCSPlayerController? player, CommandInfo command)
{
if (player == null
|| player.Team != CsTeam.Spectator
|| CurrentMap.ReplayBot.Controller == null
|| !CurrentMap.ReplayBot.IsPlaying
|| CurrentMap.ReplayBot.Controller.Pawn.SerialNum != player.ObserverPawn.Value!.ObserverServices!.ObserverTarget.SerialNum)
if(player == null || player.Team != CsTeam.Spectator)
return;

CurrentMap.ReplayBot.Pause();
foreach(ReplayPlayer rb in CurrentMap.ReplayBots)
{
if(!rb.IsPlayable || !rb.IsPlaying || !playerList[player.UserId ?? 0].IsSpectating(rb.Controller!))
continue;

rb.Pause();
}
}

[ConsoleCommand("css_replaybotflip", "Flips the replay bot between Forward/Backward playback")]
[ConsoleCommand("css_rbflip", "Flips the replay bot between Forward/Backward playback")]
public void ReverseReplay(CCSPlayerController? player, CommandInfo command)
{
if (player == null
|| player.Team != CsTeam.Spectator
|| CurrentMap.ReplayBot.Controller == null
|| !CurrentMap.ReplayBot.IsPlaying
|| CurrentMap.ReplayBot.Controller.Pawn.SerialNum != player.ObserverPawn.Value!.ObserverServices!.ObserverTarget.SerialNum)
if(player == null || player.Team != CsTeam.Spectator)
return;

foreach(ReplayPlayer rb in CurrentMap.ReplayBots)
{
if(!rb.IsPlayable || !rb.IsPlaying || !playerList[player.UserId ?? 0].IsSpectating(rb.Controller!))
continue;

rb.FrameTickIncrement *= -1;
}
}

[ConsoleCommand("css_pbreplay", "Allows for replay of player's PB")]
public void PbReplay(CCSPlayerController? player, CommandInfo command)
{
if(player == null)
return;

int maptime_id = playerList[player!.UserId ?? 0].Stats.PB[playerList[player.UserId ?? 0].Timer.Style].ID;
if (command.ArgCount > 1)
{
try
{
maptime_id = int.Parse(command.ArgByIndex(1));
}
catch {}
}

if(maptime_id == -1 || !CurrentMap.ConnectedMapTimes.Contains(maptime_id))
{
player.PrintToChat($"{PluginPrefix} {ChatColors.Red}No time was found");
return;
}

for(int i = 0; i < CurrentMap.ReplayBots.Count; i++)
{
if(CurrentMap.ReplayBots[i].Stat_MapTimeID == maptime_id)
{
player.PrintToChat($"{PluginPrefix} {ChatColors.Red}A bot of this run already playing");
return;
}
}

CurrentMap.ReplayBots = CurrentMap.ReplayBots.Prepend(new ReplayPlayer() {
Stat_MapTimeID = maptime_id,
Stat_Prefix = "PB"
}).ToList();

Server.NextFrame(() => {
Server.ExecuteCommand($"bot_quota {CurrentMap.ReplayBots.Count}");
});
}

/*
########################
Saveloc Commands
########################
*/
[ConsoleCommand("css_saveloc", "Save current player location to be practiced")]
public void SavePlayerLocation(CCSPlayerController? player, CommandInfo command)
{
if(player == null || !player.PawnIsAlive || !playerList.ContainsKey(player.UserId ?? 0))
return;

Player p = playerList[player.UserId ?? 0];
if (!p.Timer.IsRunning)
{
p.Controller.PrintToChat($"{PluginPrefix} {ChatColors.Red}Cannot save location while not in run");
return;
}

var player_pos = p.Controller.Pawn.Value!.AbsOrigin!;
var player_angle = p.Controller.PlayerPawn.Value!.EyeAngles;
var player_velocity = p.Controller.PlayerPawn.Value!.AbsVelocity;

p.SavedLocations.Add(new SavelocFrame {
Pos = new Vector(player_pos.X, player_pos.Y, player_pos.Z),
Ang = new QAngle(player_angle.X, player_angle.Y, player_angle.Z),
Vel = new Vector(player_velocity.X, player_velocity.Y, player_velocity.Z),
Tick = p.Timer.Ticks
});
p.CurrentSavedLocation = p.SavedLocations.Count-1;

p.Controller.PrintToChat($"{PluginPrefix} {ChatColors.Green}Saved location! {ChatColors.Default} use !tele {p.SavedLocations.Count-1} to teleport to this location");
}

[ConsoleCommand("css_tele", "Teleport player to current saved location")]
public void TeleportPlayerLocation(CCSPlayerController? player, CommandInfo command)
{
if(player == null || !player.PawnIsAlive || !playerList.ContainsKey(player.UserId ?? 0))
return;

CurrentMap.ReplayBot.FrameTickIncrement *= -1;
Player p = playerList[player.UserId ?? 0];

if(p.SavedLocations.Count == 0)
{
p.Controller.PrintToChat($"{PluginPrefix} {ChatColors.Red}No saved locations");
return;
}

if(!p.Timer.IsRunning)
p.Timer.Start();

if (!p.Timer.IsPracticeMode)
{
p.Controller.PrintToChat($"{PluginPrefix} {ChatColors.Red}Timer now on practice");
p.Timer.IsPracticeMode = true;
}

if(command.ArgCount > 1)
try
{
int tele_n = int.Parse(command.ArgByIndex(1));
if (tele_n < p.SavedLocations.Count)
p.CurrentSavedLocation = tele_n;
}
catch { }
SavelocFrame location = p.SavedLocations[p.CurrentSavedLocation];
Server.NextFrame(() => {
p.Controller.PlayerPawn.Value!.Teleport(location.Pos, location.Ang, location.Vel);
p.Timer.Ticks = location.Tick;
});

p.Controller.PrintToChat($"{PluginPrefix} Teleported #{p.CurrentSavedLocation}");
}

[ConsoleCommand("css_teleprev", "Teleport player to previous saved location")]
public void TeleportPlayerLocationPrev(CCSPlayerController? player, CommandInfo command)
{
if(player == null || !player.PawnIsAlive || !playerList.ContainsKey(player.UserId ?? 0))
return;

Player p = playerList[player.UserId ?? 0];

if(p.SavedLocations.Count == 0)
{
p.Controller.PrintToChat($"{PluginPrefix} {ChatColors.Red}No saved locations");
return;
}

if(p.CurrentSavedLocation == 0)
{
p.Controller.PrintToChat($"{PluginPrefix} {ChatColors.Red}Already at first location");
}
else
{
p.CurrentSavedLocation--;
}

TeleportPlayerLocation(player, command);

p.Controller.PrintToChat($"{PluginPrefix} Teleported #{p.CurrentSavedLocation}");
}

[ConsoleCommand("css_telenext", "Teleport player to next saved location")]
public void TeleportPlayerLocationNext(CCSPlayerController? player, CommandInfo command)
{
if(player == null || !player.PawnIsAlive || !playerList.ContainsKey(player.UserId ?? 0))
return;

Player p = playerList[player.UserId ?? 0];

if(p.SavedLocations.Count == 0)
{
p.Controller.PrintToChat($"{PluginPrefix} {ChatColors.Red}No saved locations");
return;
}

if(p.CurrentSavedLocation == p.SavedLocations.Count-1)
{
p.Controller.PrintToChat($"{PluginPrefix} {ChatColors.Red}Already at last location");
}
else
{
p.CurrentSavedLocation++;
}

TeleportPlayerLocation(player, command);

p.Controller.PrintToChat($"{PluginPrefix} Teleported #{p.CurrentSavedLocation}");
}
}
33 changes: 22 additions & 11 deletions src/ST-Events/Players.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,36 @@ namespace SurfTimer;

public partial class SurfTimer
{
[GameEventHandler(HookMode.Post)]
[GameEventHandler]
public HookResult OnPlayerSpawn(EventPlayerSpawn @event, GameEventInfo info)
{
var controller = @event.Userid;
if(!controller.IsValid)
if(!controller.IsValid || !controller.IsBot)
return HookResult.Continue;

if (controller.IsBot && CurrentMap.ReplayBot.Controller == null)
for (int i = 0; i < CurrentMap.ReplayBots.Count; i++)
{
CurrentMap.ReplayBot.Controller = controller;
// CurrentMap.ReplayBot.Controller.PlayerName = $"[REPLAY] {CurrentMap.Name}";
if(CurrentMap.ReplayBots[i].IsPlayable)
continue;

Server.PrintToChatAll($"{ChatColors.Lime} Loading replay data..."); // WHY COLORS NOT WORKING AHHHHH!!!!!
int repeats = -1;
if(CurrentMap.ReplayBots[i].Stat_Prefix == "PB")
repeats = 3;

CurrentMap.ReplayBots[i].SetController(controller, repeats);
Server.PrintToChatAll($"{ChatColors.Lime} Loading replay data...");
AddTimer(2f, () => {
CurrentMap.ReplayBot.Controller.RemoveWeapons();
if(!CurrentMap.ReplayBots[i].IsPlayable)
return;

CurrentMap.ReplayBots[i].Controller!.RemoveWeapons();

CurrentMap.ReplayBot.LoadReplayData(DB!, CurrentMap);
CurrentMap.ReplayBots[i].LoadReplayData(DB!);

CurrentMap.ReplayBot.Start();
CurrentMap.ReplayBots[i].Start();
});

return HookResult.Continue;
}

return HookResult.Continue;
Expand Down Expand Up @@ -157,8 +167,9 @@ public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo
{
var player = @event.Userid;

if (CurrentMap.ReplayBot.Controller != null&& CurrentMap.ReplayBot.Controller.Equals(player))
CurrentMap.ReplayBot.Reset();
for (int i = 0; i < CurrentMap.ReplayBots.Count; i++)
if (CurrentMap.ReplayBots[i].IsPlayable && CurrentMap.ReplayBots[i].Controller!.Equals(player))
CurrentMap.ReplayBots[i].Reset();

if (player.IsBot || !player.IsValid)
{
Expand Down
25 changes: 21 additions & 4 deletions src/ST-Events/Tick.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using CounterStrikeSharp.API.Modules.Cvars;

namespace SurfTimer;

Expand All @@ -14,7 +13,25 @@ public void OnTick()
player.HUD.Display();
}

// Replay BOT Ticks
CurrentMap?.ReplayBot.Tick(); // When CurrentMap null the ? operator will terminate safely the operation
if (CurrentMap == null)
return;

// Need to disable maps from executing their cfgs. Currently idk how (But seriusly it a security issue)
ConVar? bot_quota = ConVar.Find("bot_quota");
if (bot_quota != null)
{
int cbq = bot_quota.GetPrimitiveValue<int>();
if(cbq != CurrentMap.ReplayBots.Count)
{
bot_quota.SetValue(CurrentMap.ReplayBots.Count);
}
}

for(int i = 0; i < CurrentMap!.ReplayBots.Count; i++)
{
CurrentMap.ReplayBots[i].Tick();
if (CurrentMap.ReplayBots[i].RepeatCount == 0)
CurrentMap.KickReplayBot(i);
}
}
}
4 changes: 2 additions & 2 deletions src/ST-Events/TriggerEndTouch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using CounterStrikeSharp.API;

namespace SurfTimer;

Expand Down Expand Up @@ -45,11 +44,12 @@ internal HookResult OnTriggerEndTouch(DynamicHook handler)
if(player.ReplayRecorder.IsRecording)
{
// Saveing 2 seconds before leaving the start zone
player.ReplayRecorder.Frames.RemoveRange(0, Math.Max(0, player.ReplayRecorder.Frames.Count - (64*2))); // Would like for someone to fact check the math :)
player.ReplayRecorder.Frames.RemoveRange(0, Math.Max(0, player.ReplayRecorder.Frames.Count - (64*2))); // Todo make a plugin convar for the time saved before start of run
}

// MAP START ZONE
player.Timer.Start();
player.ReplayRecorder.CurrentSituation = ReplayFrameSituation.START_RUN;

/* Revisit
// Wonky Prespeed check
Expand Down
Loading