diff --git a/lang/Jailbreak.English/SpecialDay/SpeedrunDayLocale.cs b/lang/Jailbreak.English/SpecialDay/SpeedrunDayLocale.cs index b3ec791a..c5ff0498 100644 --- a/lang/Jailbreak.English/SpecialDay/SpeedrunDayLocale.cs +++ b/lang/Jailbreak.English/SpecialDay/SpeedrunDayLocale.cs @@ -69,7 +69,7 @@ public IView RunnerAssigned(CCSPlayerController player) { }; } - public IView RunnerReassigned(CCSPlayerController player) { + public IView RunnerLeftAndReassigned(CCSPlayerController player) { return new SimpleView { PREFIX, "The original speedrunner left, so", @@ -78,6 +78,15 @@ public IView RunnerReassigned(CCSPlayerController player) { }; } + public IView RunnerAFKAndReassigned(CCSPlayerController player) { + return new SimpleView { + PREFIX, + "The original speedrunner isn't moving, so", + player, + "is now the speedrunner!" + }; + } + public IView PlayerTime(CCSPlayerController player, int position, float time) { var place = position switch { diff --git a/lang/Jailbreak.English/SpecialDay/TeamDayLocale.cs b/lang/Jailbreak.English/SpecialDay/TeamDayLocale.cs index 54f09a74..1095e057 100644 --- a/lang/Jailbreak.English/SpecialDay/TeamDayLocale.cs +++ b/lang/Jailbreak.English/SpecialDay/TeamDayLocale.cs @@ -1,6 +1,7 @@ using CounterStrikeSharp.API.Modules.Utils; using Jailbreak.Formatting.Base; using Jailbreak.Formatting.Views.SpecialDay; +using Jailbreak.Public.Extensions; using Jailbreak.Public.Utils; namespace Jailbreak.English.SpecialDay; @@ -29,7 +30,13 @@ public virtual IView BeginsIn(int seconds) { } public IView GenerateStartMessage() { - var result = new SimpleView { PREFIX, { "Today is a", Name, "day!" } }; + // Put "an" if name starts with a vowel + var result = new SimpleView { + PREFIX, + { "Today is a" + (Name.ToLower()[0].IsVowel() ? "n" : ""), Name, "day!" } + }; + + // var result = new SimpleView { PREFIX, { "Today is a" + Name.ToLower()[0].), Name, "day!" } }; if (description.Length == 0) return result; diff --git a/mod/Jailbreak.SpecialDay/SpecialDays/GunGameDay.cs b/mod/Jailbreak.SpecialDay/SpecialDays/GunGameDay.cs index 2a034f04..e6c0e029 100644 --- a/mod/Jailbreak.SpecialDay/SpecialDays/GunGameDay.cs +++ b/mod/Jailbreak.SpecialDay/SpecialDays/GunGameDay.cs @@ -115,7 +115,8 @@ private HookResult OnDeath(EventPlayerDeath @event, GameEventInfo info) { int playerIndex; if (!progressions.TryGetValue(player.Slot, out playerIndex)) playerIndex = 0; - if (attacker == null || !attacker.IsValid || attacker.Slot == player.Slot) { + if (attacker == null || !attacker.IsValid) return HookResult.Continue; + if (attacker.Slot == player.Slot) { if (playerIndex <= 0) return HookResult.Continue; playerIndex--; msg.DemotedDueToSuicide.ToChat(player); @@ -167,7 +168,7 @@ private HookResult OnDeath(EventPlayerDeath @event, GameEventInfo info) { msg.PlayerOnLastPromotion(attacker).ToAllChat(); msg.PromotedTo(weaponProgression[attackerProgress].GetFriendlyWeaponName(), - weaponProgression.Count - attackerProgress - 1) + weaponProgression.Count - attackerProgress) .ToChat(attacker); attacker.RemoveWeapons(); diff --git a/mod/Jailbreak.SpecialDay/SpecialDays/SpeedrunDay.cs b/mod/Jailbreak.SpecialDay/SpecialDays/SpeedrunDay.cs index 57f16e9c..ff185eed 100644 --- a/mod/Jailbreak.SpecialDay/SpecialDays/SpeedrunDay.cs +++ b/mod/Jailbreak.SpecialDay/SpecialDays/SpeedrunDay.cs @@ -168,7 +168,7 @@ public override void Setup() { } speedrunner.SetColor(Color.DodgerBlue); - msg.RunnerReassigned(speedrunner).ToAllChat(); + msg.RunnerLeftAndReassigned(speedrunner).ToAllChat(); msg.YouAreRunner(CvInitialSpeedrunTime.Value).ToChat(speedrunner); } @@ -254,6 +254,42 @@ private ActivePlayerTrail createFirstTrail( var tps = 1 / trail.UpdateRate; var didntMoveSeconds = (int)Math.Ceiling(trail.DidntMoveTicks / tps); var thresholdTicks = (int)Math.Ceiling(tps * 3); + if (trail.GetTrailLengthSquared() < 500) { + if (trail.DidntMoveTicks <= tps * 10) return; + // If the player left mid-run, we need to pick the nearest player + // to continue the run + var end = trail.GetEndSegment()?.GetEnd() ?? start; + if (end == null) { + panic("Speedrunner is invalid, and we cannot find the start"); + return; + } + + var furthest = PlayerUtil.GetAlive() + .Where(p => p.Pawn.IsValid && p.Pawn.Value != null) + .Where(p => p.Pawn.Value!.IsValid && p.Pawn.Value.AbsOrigin != null) + .MinBy(p => p.Pawn.Value!.AbsOrigin!.DistanceSquared(end)); + + if (furthest == null) { + panic("Speedrunner is invalid, and we cannot find a new one"); + return; + } + + speedrunner = furthest; + foreach (var p in PlayerUtil.GetAlive()) { + if (p.Slot == speedrunner.Slot) continue; + p.Teleport(furthest); + } + + start = furthest.Pawn.Value?.AbsOrigin!.Clone(); + furthest.Pawn.Value?.Teleport(end); + furthest.SetColor(Color.DodgerBlue); + msg.RunnerAFKAndReassigned(furthest).ToAllChat(); + msg.YouAreRunner(RoundUtil.GetTimeRemaining()).ToChat(furthest); + trail.StartTracking(furthest); + + return; + } + if (trail.DidntMoveTicks < thresholdTicks) return; if (trail.DidntMoveTicks == thresholdTicks) msg.StayStillToSpeedup.ToChat(trail.Player); @@ -284,7 +320,7 @@ private ActivePlayerTrail createFirstTrail( speedrunner = nearest; nearest.Pawn.Value?.Teleport(end); nearest.SetColor(Color.DodgerBlue); - msg.RunnerReassigned(nearest).ToAllChat(); + msg.RunnerLeftAndReassigned(nearest).ToAllChat(); msg.YouAreRunner(RoundUtil.GetTimeRemaining()).ToChat(nearest); trail.StartTracking(nearest); }; diff --git a/mod/Jailbreak.Trail/ActivePlayerTrail.cs b/mod/Jailbreak.Trail/ActivePlayerTrail.cs index 4d0cb957..ee6445c7 100644 --- a/mod/Jailbreak.Trail/ActivePlayerTrail.cs +++ b/mod/Jailbreak.Trail/ActivePlayerTrail.cs @@ -42,7 +42,7 @@ virtual protected void Tick() { pos = pos.Clone(); var end = GetEndSegment(); var dist = end?.GetStart().DistanceSquared(pos) ?? float.MaxValue; - if (dist < 1000) { + if (dist < 2000) { // Still want to remove old segments Cleanup(); DidntMoveTicks++; diff --git a/public/Jailbreak.Formatting/Views/SpecialDay/ISpeedDayLocale.cs b/public/Jailbreak.Formatting/Views/SpecialDay/ISpeedDayLocale.cs index e3f60803..17b41c64 100644 --- a/public/Jailbreak.Formatting/Views/SpecialDay/ISpeedDayLocale.cs +++ b/public/Jailbreak.Formatting/Views/SpecialDay/ISpeedDayLocale.cs @@ -12,7 +12,8 @@ public interface ISpeedDayLocale : ISDInstanceLocale { public IView YouAreRunner(int seconds); - public IView RunnerReassigned(CCSPlayerController player); + public IView RunnerLeftAndReassigned(CCSPlayerController player); + public IView RunnerAFKAndReassigned(CCSPlayerController player); public IView RuntimeLeft(int seconds); diff --git a/public/Jailbreak.Public/Extensions/StringExtensions.cs b/public/Jailbreak.Public/Extensions/StringExtensions.cs index 192e6271..0b89d68e 100644 --- a/public/Jailbreak.Public/Extensions/StringExtensions.cs +++ b/public/Jailbreak.Public/Extensions/StringExtensions.cs @@ -7,10 +7,7 @@ public static string Sanitize(this string unknown) { return unknown.Replace("<", "<"); } - public static string Repeat(this string stringToRepeat, int repeat) { - var builder = new StringBuilder(repeat * stringToRepeat.Length); - for (var i = 0; i < repeat; i++) builder.Append(stringToRepeat); - - return builder.ToString(); + public static bool IsVowel(this char c) { + return "aeiouAEIOU".IndexOf(c) >= 0; } } \ No newline at end of file diff --git a/public/Jailbreak.Public/Mod/Trail/AbstractTrail.cs b/public/Jailbreak.Public/Mod/Trail/AbstractTrail.cs index 9fddff66..7c5519be 100644 --- a/public/Jailbreak.Public/Mod/Trail/AbstractTrail.cs +++ b/public/Jailbreak.Public/Mod/Trail/AbstractTrail.cs @@ -82,6 +82,10 @@ public virtual float GetTrailLength(float since, int max = 0) { return MathF.Sqrt(GetTrailLengthSquared(since, max)); } + public float GetTrailLengthSquared() { + return GetTrailLengthSquared(Lifetime); + } + public float GetTrailLengthSquared(float since, int max = 0) { var length = 0f; var last = default(Vector);