private static bool Prefix(PlayableScps.Scp096 __instance, PlayerStats.HitInfo info) { try { if (info == null || info.RHub == null) { return(false); } var player = info.RHub.GetPlayer(); if (player.Invisible || Server.Get.Configs.SynapseConfiguration.CantRage096.Contains(player.RoleID)) { return(false); } if (player.RealTeam == Team.SCP && !Server.Get.Configs.SynapseConfiguration.ScpTrigger096) { return(false); } Server.Get.Events.Scp.Scp096.InvokeScpTargetEvent(player, __instance.GetPlayer(), __instance.PlayerState, out var allow); return(allow); } catch (Exception e) { Synapse.Api.Logger.Get.Error($"Synapse-Event: Scp096AddTargetEvent failed!!\n{e}"); return(true); } }
public static bool Prefix(PlayableScps.Scp096 __instance, VisionInformation info) { PlayableScpsController playableScpsController; bool whitelisted = info.Source.GetComponent <AdditionalPlayerAbilities>() != null && info.Source.GetComponent <AdditionalPlayerAbilities>().scp096whitelisted; Exiled.API.Features.Log.Info("Патчим агр скромника, результат: " + whitelisted); if (!info.Looking || !info.RaycastHit || !info.RaycastResult.transform.gameObject.TryGetComponent <PlayableScpsController>(out playableScpsController) || playableScpsController.CurrentScp == null || playableScpsController.CurrentScp != __instance || whitelisted) { return(false); } float delay = (1f - info.DotProduct) / 0.25f * (Vector3.Distance(info.Source.transform.position, info.Target.transform.position) * 0.1f); if (!__instance.Calming) { __instance.AddTarget(info.Source); } if (__instance.CanEnrage && info.Source != null) { __instance.PreWindup(delay); if (NetworkServer.active) { NetworkServer.SendToAll <Scp096TriggerMessage>(new Scp096TriggerMessage(info.Target, info.Source), 0); } } return(false); }
private static float GetRageTime(Scp096 scp096) { bool isValidTimeAddition = scp096.PlayerState == Scp096PlayerState.Docile || scp096.PlayerState == Scp096PlayerState.TryNotToCry || scp096.PlayerState == Scp096PlayerState.Enraging; return(isValidTimeAddition ? scp096.EnrageTimePerReset : 0f); }
private static bool Prefix(PlayableScps.Scp096 __instance, PryableDoor gate) { if (__instance.Charging && __instance.Enraged && (!gate.TargetState /* && gate.doorType == Door.DoorTypes.HeavyGate */)) { var ev = new StartPryingGateEventArgs(API.Features.Player.Get(__instance.Hub.gameObject), gate); Exiled.Events.Handlers.Scp096.OnStartPryingGate(ev); return(ev.IsAllowed); } return(false); }
private static bool Prefix(PlayableScps.Scp096 __instance) { try { if (__instance._flash.Enabled) { return(false); } var vector = __instance.Hub.transform.TransformPoint(PlayableScps.Scp096._headOffset); foreach (var player in Server.Get.Players) { var characterClassManager = player.ClassManager; if (characterClassManager.CurClass != RoleType.Spectator && !(player.Hub == __instance.Hub) && !characterClassManager.IsAnyScp() && Vector3.Dot((player.CameraReference.position - vector).normalized, __instance.Hub.PlayerCameraReference.forward) >= 0.1f) { var visionInformation = VisionInformation.GetVisionInformation(player.Hub, vector, -0.1f, 60f, true, true, __instance.Hub.localCurrentRoomEffects); if (visionInformation.IsLooking) { float delay = visionInformation.LookingAmount / 0.25f * (visionInformation.Distance * 0.1f); if (!__instance.Calming) { if (player.Invisible || Server.Get.Configs.SynapseConfiguration.CantRage096.Contains(player.RoleID)) { continue; } if (player.RealTeam == Team.SCP && !Server.Get.Configs.SynapseConfiguration.ScpTrigger096) { continue; } Server.Get.Events.Scp.Scp096.InvokeScpTargetEvent(player, __instance.GetPlayer(), __instance.PlayerState, out var allow); __instance.AddTarget(player.gameObject); if (!allow) { continue; } } if (__instance.CanEnrage && player.gameObject != null) { __instance.PreWindup(delay); } } } } return(false); } catch (Exception e) { Synapse.Api.Logger.Get.Error($"Synapse-Event: Scp096AddTargetEvent failed!!\n{e}\nStackTrace:\n{e.StackTrace}"); return(true); } }
public void Postfix(PlayableScps.Scp096 __instance, VisionInformation __result, GameObject source) { VisionInformation visionInformation = new VisionInformation { Source = source, Target = __instance.Hub.gameObject, RaycastHit = false, Looking = false }; if (source == __instance.Hub.gameObject) { __result = visionInformation; return; } Transform playerCameraReference = ReferenceHub.GetHub(source).PlayerCameraReference; Vector3 position = __instance.Hub.PlayerCameraReference.position; Vector3 position2 = playerCameraReference.position; visionInformation.Distance = Vector3.Distance(position2, position); float num = -Vector3.Dot((position2 - position).normalized, playerCameraReference.forward); float num2 = -Vector3.Dot((position - position2).normalized, __instance.Hub.PlayerCameraReference.forward); visionInformation.DotProduct = num; visionInformation.Looking = true; if (num < MoreConfig.singleton.Config.Scp096Config.triggerBounds1 || num2 < MoreConfig.singleton.Config.Scp096Config.triggerBounds2) { visionInformation.Looking = false; __result = visionInformation; return; } if (visionInformation.Distance > ((__instance.Hub.transform.position.y > 980f) ? MoreConfig.singleton.Config.Scp096Config.surfaceTriggerDistance : MoreConfig.singleton.Config.Scp096Config.triggerDistance)) { __result = visionInformation; return; } RaycastHit raycastResult; if (!Physics.Raycast(visionInformation.Source.transform.position, (visionInformation.Target.transform.position - visionInformation.Source.transform.position).normalized, out raycastResult, MoreConfig.singleton.Config.Scp096Config.surfaceTriggerDistance, PlayableScps.Scp096.VisionLayerMask)) { __result = visionInformation; return; } visionInformation.RaycastHit = true; visionInformation.RaycastResult = raycastResult; __result = visionInformation; }
private static bool Damage(PlayableScps.Scp096 __instance, PlayerStatsSystem.DamageHandlerBase handler) { try { AttackerDamageHandler attackerDamageHandler = handler as AttackerDamageHandler; if (attackerDamageHandler == null || attackerDamageHandler.Attacker.Hub == null || !__instance.CanEnrage) { return(false); } var player = attackerDamageHandler.Attacker.Hub.GetPlayer(); if (player.Invisible || Server.Get.Configs.synapseConfiguration.CantRage096.Contains(player.RoleID)) { return(false); } if (player.RealTeam == Team.SCP && !Server.Get.Configs.synapseConfiguration.ScpTrigger096) { return(false); } Server.Get.Events.Scp.Scp096.InvokeScpTargetEvent(player, __instance.GetPlayer(), __instance.PlayerState, out var allow); if (allow) { __instance.AddTarget(attackerDamageHandler.Attacker.Hub.gameObject); __instance.Windup(false); } return(allow); } catch (Exception e) { Synapse.Api.Logger.Get.Error($"Synapse-Event: Scp096AddTargetEvent failed!!\n{e}"); return(true); } }
public static bool Prefix(PlayableScps.Scp096 __instance) { if (((PlayableScp)__instance).isLocalPlayer) { __instance._abilityManager.RunInputs(); CursorManager.ChangeMouseVisibility(LockReason.Scp096, (__instance.Charging || (__instance.TryingNotToCry || __instance.PryingGate)) ? MouseVisibilityType.InvisibleButCantMove : MouseVisibilityType.Invisible, false); if (!__instance.PlayerState.IsOffensive() && !__instance._visionTargets.IsEmpty <TargetComponent>()) { foreach (TargetComponent component in __instance._visionTargets) { if (component != null) { component.IsTarget = false; } } __instance._visionTargets.Clear(); } if (__instance.TryingNotToCry && (__instance.Hub.fpc.PlySpeed != Vector2.zero)) { Scp096InputMessage message = new Scp096InputMessage { InputState = Scp096InputState.None }; NetworkClient.Send <Scp096InputMessage>(message, 0); } } if (NetworkServer.active) { __instance.UpdateShield(); __instance.UpdateEnrage(); __instance.UpdateCharging(); __instance.UpdatePry(); foreach (GameObject obj2 in PlayerManager.players) { CharacterClassManager manager = obj2.GetComponent <CharacterClassManager>(); if (manager == null || ((manager.CurClass != RoleType.Spectator) && !manager.IsAnyScp())) { Player player = Player.Get(obj2); if (player != null && Tracking.PlayersWithSubclasses.ContainsKey(player) && Tracking.PlayersWithSubclasses[player].Abilities.Contains(AbilityType.Disable096Trigger)) { continue; } VisionInformation visionInformation = __instance.GetVisionInformation(obj2); if (visionInformation.Looking) { __instance.ParseVisionInformation(visionInformation); } } } foreach (KeyValuePair <GameObject, Door> pair in PlayableScps.Scp096.takenDoors) { if (pair.Value.isOpen) { PlayableScps.Scp096 scp = PlayableScps.Scp096.Get096FromPlayerObject(pair.Key); if (scp != null) { if (pair.Key == null) { PlayableScps.Scp096.takenDoors.Remove(pair.Key); } else { scp.ResetState(); } break; } } } } return(false); }
// Called every 1 second according to the player's Update function. This is way more efficient than the old way of doing a forloop for every player. // Also, since the gameObject for the player is deleted when they disconnect, we don't need to worry about cleaning any variables :) private void AFKChecker() { //Log.Info($"AFK Time: {this.AFKTime} AFK Count: {this.AFKCount}"); if (this.ply.Team == Team.RIP || Player.List.Count() <= plugin.Config.MinPlayers || (plugin.Config.IgnoreTut && this.ply.Team == Team.TUT)) { return; } bool isScp079 = (this.ply.Role == RoleType.Scp079) ? true : false; bool scp096TryNotToCry = false; // When SCP096 is in the state "TryNotToCry" he cannot move or it will cancel, // therefore, we don't want to AFK check 096 while he's in this state. if (this.ply.Role == RoleType.Scp096) { PlayableScps.Scp096 scp096 = this.ply.ReferenceHub.scpsController.CurrentScp as PlayableScps.Scp096; scp096TryNotToCry = (scp096.PlayerState == Scp096PlayerState.TryNotToCry) ? true : false; } Vector3 CurrentPos = this.ply.Position; Vector3 CurrentAngle = (isScp079) ? this.ply.Camera.targetPosition.position : this.ply.Rotation; if (CurrentPos != this.AFKLastPosition || CurrentAngle != this.AFKLastAngle || scp096TryNotToCry) { this.AFKLastPosition = CurrentPos; this.AFKLastAngle = CurrentAngle; this.AFKTime = 0; PlayerToReplace = null; return; } // The player hasn't moved past this point. this.AFKTime++; // If the player hasn't reached the time yet don't continue. if (this.AFKTime < plugin.Config.AfkTime) { return; } // Check if we're still in the "grace" period int secondsuntilspec = (plugin.Config.AfkTime + plugin.Config.GraceTime) - this.AFKTime; if (secondsuntilspec > 0) { string warning = plugin.Config.MsgGrace; warning = warning.Replace("%timeleft%", secondsuntilspec.ToString()); this.ply.ClearBroadcasts(); this.ply.Broadcast(1, $"{plugin.Config.MsgPrefix} {warning}"); return; } // The player is AFK and action will be taken. Log.Info($"{this.ply.Nickname} ({this.ply.UserId}) was detected as AFK!"); this.AFKTime = 0; // Let's make sure they are still alive before doing any replacement. if (this.ply.Team == Team.RIP) { return; } if (plugin.Config.TryReplace && !IsPastReplaceTime()) { Assembly easyEvents = Loader.Plugins.FirstOrDefault(pl => pl.Name == "EasyEvents")?.Assembly; var roleEasyEvents = easyEvents?.GetType("EasyEvents.Util")?.GetMethod("GetRole")?.Invoke(null, new object[] { this.ply }); // SCP035 Support (Credit DCReplace) bool is035 = false; try { is035 = this.ply.Id == TryGet035()?.Id; } catch (Exception e) { Log.Debug($"SCP-035 is not installed, skipping method call: {e}"); } // Credit: DCReplace :) // I mean at this point 90% of this has been rewritten lol... var inventory = this.ply.Inventory.items.Select(x => x.id).ToList(); RoleType role = this.ply.Role; Vector3 pos = this.ply.Position; float health = this.ply.Health; // New strange ammo system because the old one was f****d. uint ammo1 = this.ply.Ammo[(int)AmmoType.Nato556]; uint ammo2 = this.ply.Ammo[(int)AmmoType.Nato762]; uint ammo3 = this.ply.Ammo[(int)AmmoType.Nato9]; // Stuff for 079 byte Level079 = 0; float Exp079 = 0f, AP079 = 0f; if (isScp079) { Level079 = this.ply.Level; Exp079 = this.ply.Experience; AP079 = this.ply.Energy; } PlayerToReplace = Player.List.FirstOrDefault(x => x.Role == RoleType.Spectator && x.UserId != string.Empty && !x.IsOverwatchEnabled && x != this.ply); if (PlayerToReplace != null) { // Make the player a spectator first so other plugins can do things on player changing role with uAFK. this.ply.Inventory.Clear(); // Clear their items to prevent dupes. this.ply.SetRole(RoleType.Spectator); this.ply.Broadcast(30, $"{plugin.Config.MsgPrefix} {plugin.Config.MsgFspec}"); PlayerToReplace.SetRole(role); Timing.CallDelayed(0.3f, () => { if (is035) { try { TrySpawn035(PlayerToReplace); } catch (Exception e) { Log.Debug($"SCP-035 is not installed, skipping method call: {e}"); } } PlayerToReplace.Position = pos; PlayerToReplace.ClearInventory(); PlayerToReplace.ResetInventory(inventory); PlayerToReplace.Health = health; PlayerToReplace.Ammo[(int)AmmoType.Nato556] = ammo1; PlayerToReplace.Ammo[(int)AmmoType.Nato762] = ammo2; PlayerToReplace.Ammo[(int)AmmoType.Nato9] = ammo3; if (isScp079) { PlayerToReplace.Level = Level079; PlayerToReplace.Experience = Exp079; PlayerToReplace.Energy = AP079; } PlayerToReplace.Broadcast(10, $"{plugin.Config.MsgPrefix} {plugin.Config.MsgReplace}"); if (roleEasyEvents != null) { easyEvents?.GetType("EasyEvents.CustomRoles")?.GetMethod("ChangeRole")?.Invoke(null, new object[] { PlayerToReplace, roleEasyEvents }); } PlayerToReplace = null; }); } else { // Couldn't find a valid player to spawn, just ForceToSpec anyways. ForceToSpec(this.ply); } } else { // Replacing is disabled, just ForceToSpec ForceToSpec(this.ply); } // If it's -1 we won't be kicking at all. if (plugin.Config.NumBeforeKick != -1) { // Increment AFK Count this.AFKCount++; if (this.AFKCount >= plugin.Config.NumBeforeKick) { // Since this.AFKCount is greater than the config we're going to kick that player for being AFK too many times in one match. ServerConsole.Disconnect(this.gameObject, plugin.Config.MsgKick); } } }
// Called every 1 second according to the player's Update function. This is way more efficient than the old way of doing a forloop for every player. // Also, since the gameObject for the player is deleted when they disconnect, we don't need to worry about cleaning any variables :) private void AFKChecker() { //Log.Info($"AFK Time: {this.AFKTime} AFK Count: {this.AFKCount}"); if (this.ply.Team == Team.RIP) { return; } bool isScp079 = (this.ply.Role == RoleType.Scp079) ? true : false; bool scp096TryNotToCry = false; // When SCP096 is in the state "TryNotToCry" he cannot move or it will cancel, // therefore, we don't want to AFK check 096 while he's in this state. if (this.ply.Role == RoleType.Scp096) { PlayableScps.Scp096 scp096 = this.ply.ReferenceHub.scpsController.CurrentScp as PlayableScps.Scp096; scp096TryNotToCry = (scp096.PlayerState == Scp096PlayerState.TryNotToCry) ? true : false; } Vector3 CurrentPos = this.ply.Position; Vector3 CurrentAngle = (isScp079) ? this.ply.Camera.targetPosition.position : this.ply.Rotation; if (CurrentPos != this.AFKLastPosition || CurrentAngle != this.AFKLastAngle || scp096TryNotToCry) { this.AFKLastPosition = CurrentPos; this.AFKLastAngle = CurrentAngle; this.AFKTime = 0; return; } // The player hasn't moved past this point. this.AFKTime++; // If the player hasn't reached the time yet don't continue. if (this.AFKTime < plugin.Config.AfkTime) { return; } // Check if we're still in the "grace" period int secondsuntilspec = (plugin.Config.AfkTime + plugin.Config.GraceTime) - this.AFKTime; if (secondsuntilspec > 0) { string warning = plugin.Config.MsgGrace; warning = warning.Replace("%timeleft%", secondsuntilspec.ToString()); this.ply.ClearBroadcasts(); this.ply.Broadcast(1, $"{plugin.Config.MsgPrefix} {warning}"); return; } // The player is AFK and action will be taken. Log.Info($"{this.ply.Nickname} ({this.ply.UserId}) was detected as AFK!"); this.AFKTime = 0; // Let's make sure they are still alive before doing any replacement. if (this.ply.Team == Team.RIP) { return; } if (plugin.Config.TryReplace && !this.IsPastReplaceTime()) { var roleEasyEvents = Loader.Plugins.FirstOrDefault(pl => pl.Name == "EasyEvents")?.Assembly.GetType("EasyEvents.Util")?.GetMethod("GetRole")?.Invoke(null, new object[] { this.ply }); // SCP035 Support (Credit DCReplace) bool is035 = false; try { is035 = this.ply.Id == TryGet035()?.Id; } catch (Exception e) { Log.Debug($"SCP-035 is not installed, skipping method call: {e}"); } // Credit: DCReplace :) // I mean at this point 90% of this has been rewritten lol... Inventory.SyncListItemInfo items = this.ply.Inventory.items; RoleType role = this.ply.Role; Vector3 pos = this.ply.Position; float health = this.ply.Health; // New strange ammo system because the old one was f****d. Dictionary <Exiled.API.Enums.AmmoType, uint> ammo = new Dictionary <Exiled.API.Enums.AmmoType, uint>(); foreach (Exiled.API.Enums.AmmoType atype in (Exiled.API.Enums.AmmoType[])Enum.GetValues(typeof(Exiled.API.Enums.AmmoType))) { ammo.Add(atype, this.ply.Ammo[(int)atype]); this.ply.Ammo[(int)atype] = 0; // We remove the ammo so the player doesn't drop it (duplicate ammo) } // Stuff for 079 byte Level079 = 0; float Exp079 = 0f, AP079 = 0f; if (isScp079) { Level079 = this.ply.Level; Exp079 = this.ply.Experience; AP079 = this.ply.Energy; } Player player = Player.List.FirstOrDefault(x => x.Role == RoleType.Spectator && x.UserId != string.Empty && !x.IsOverwatchEnabled && x != this.ply); if (player != null) { player.SetRole(role); Timing.CallDelayed(0.3f, () => { if (is035) { try { TrySpawn035(player); } catch (Exception e) { Log.Debug($"SCP-035 is not installed, skipping method call: {e}"); } } player.Position = pos; player.Inventory.Clear(); foreach (Inventory.SyncItemInfo item in items) { player.Inventory.AddNewItem(item.id, item.durability, item.modSight, item.modBarrel, item.modOther); } player.Health = health; foreach (Exiled.API.Enums.AmmoType atype in (Exiled.API.Enums.AmmoType[])Enum.GetValues(typeof(Exiled.API.Enums.AmmoType))) { uint amount; if (ammo.TryGetValue(atype, out amount)) { this.ply.Ammo[(int)atype] = amount; } else { Log.Error($"[uAFK] ERROR: Tried to get a value from dict that did not exist! (Ammo)"); } } if (isScp079) { player.Level = Level079; player.Experience = Exp079; player.Energy = AP079; } player.Broadcast(10, $"{plugin.Config.MsgPrefix} {plugin.Config.MsgReplace}"); if (roleEasyEvents != null) { Loader.Plugins.FirstOrDefault(pl => pl.Name == "EasyEvents")?.Assembly.GetType("EasyEvents.CustomRoles")?.GetMethod("ChangeRole")?.Invoke(null, new object[] { player, roleEasyEvents }); } this.ply.Inventory.Clear(); // Clear their items to prevent dupes. this.ply.SetRole(RoleType.Spectator); this.ply.Broadcast(30, $"{plugin.Config.MsgPrefix} {plugin.Config.MsgFspec}"); }); } else { // Couldn't find a valid player to spawn, just ForceToSpec anyways. this.ForceToSpec(this.ply); } } else { // Replacing is disabled, just ForceToSpec this.ForceToSpec(this.ply); } // If it's -1 we won't be kicking at all. if (plugin.Config.NumBeforeKick != -1) { // Increment AFK Count this.AFKCount++; if (this.AFKCount >= plugin.Config.NumBeforeKick) { // Since AFKCount is greater than the config we're going to kick that player for being AFK too many times in one match. ServerConsole.Disconnect(this.gameObject, plugin.Config.MsgKick); } } }