Skip to content

Commit

Permalink
fix: better instant update model
Browse files Browse the repository at this point in the history
  • Loading branch information
samyycX committed Dec 6, 2024
1 parent fdb97b2 commit 9b93526
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 55 deletions.
2 changes: 2 additions & 0 deletions Inspection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ public static void InspectModelForPlayer(CCSPlayerController player, string path
if (_cameraProp == null || !_cameraProp.IsValid) return;

_cameraProp.DispatchSpawn();
_cameraProp.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(_cameraProp.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));

_cameraProp.Collision.CollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_NEVER;
_cameraProp.Collision.SolidFlags = 12;
Expand Down Expand Up @@ -216,6 +217,7 @@ public static void InspectModelForPlayer(CCSPlayerController player, string path
}
}
prop.DispatchSpawn();
_cameraProp.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags = (uint)(_cameraProp.CBodyComponent!.SceneNode!.Owner!.Entity!.Flags & ~(1 << 2));
// not sure what the fuck is this but it can resolve model have weird pose
var angle = (180 / float.Pi) * float.Atan2(originLocClone.Y, originLocClone.X) + 180;
prop.Teleport(originLocClone, new QAngle(0, angle, 0));
Expand Down
53 changes: 36 additions & 17 deletions PlayerModelChanger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace PlayerModelChanger;
public partial class PlayerModelChanger : BasePlugin, IPluginConfig<ModelConfig>
{
public override string ModuleName => "Player Model Changer";
public override string ModuleVersion => "1.8.1";
public override string ModuleVersion => "1.8.2";

public override string ModuleAuthor => "samyyc";
public required ModelConfig Config { get; set; }
Expand Down Expand Up @@ -50,6 +50,10 @@ public override void Load(bool hotReload)
}
RegisterEventHandler<EventPlayerSpawn>(OnPlayerSpawnEvent);
RegisterListener<Listeners.OnTick>(OnTick);
RegisterListener<Listeners.OnMapEnd>(() =>
{
Service.ClearMapDefaultModel();
});

Utils.InitializeLangPrefix();

Expand Down Expand Up @@ -261,20 +265,26 @@ public HookResult OnPlayerSpawnEvent(EventPlayerSpawn @event, GameEventInfo info
}
}


var model = Service.GetPlayerNowTeamModel(player);
if (model != null)
{
SetModelNextServerFrame(player, model, model.Disableleg);
}
else
Server.NextFrame(() =>
{
if (!Service.MapDefaultModelInitialized(player))
{
Service.SetMapDefaultModel(player, player.PlayerPawn.Value.CBodyComponent!.SceneNode!.GetSkeletonInstance().ModelState.ModelName);
}
Server.NextFrame(() =>
{
var originalRender = player.PlayerPawn.Value.Render;
player.PlayerPawn.Value.Render = Color.FromArgb(255, originalRender.R, originalRender.G, originalRender.B);
var model = Service.GetPlayerNowTeamModel(player);
if (model != null)
{
SetModelNextServerFrame(player, model, model.Disableleg);
}
else
{
var originalRender = player.PlayerPawn.Value.Render;
player.PlayerPawn.Value.Render = Color.FromArgb(255, originalRender.R, originalRender.G, originalRender.B);
}
});
}
});
}
catch (Exception ex)
{
Expand All @@ -284,19 +294,28 @@ public HookResult OnPlayerSpawnEvent(EventPlayerSpawn @event, GameEventInfo info
return HookResult.Continue;
}

public void SetModelNextServerFrame(CCSPlayerController player, Model model, bool disableleg)
public Task SetModelNextServerFrame(CCSPlayerController player, Model? model, bool disableleg)
{
Server.NextFrame(() =>
return Server.NextFrameAsync(() =>
{
var pawn = player.Pawn.Value!;
pawn.SetModel(model.Path);
var originalRender = pawn.Render;
pawn.Render = Color.FromArgb(disableleg ? 254 : 255, originalRender.R, originalRender.G, originalRender.B);

if (player.IsBot || pawn.CBodyComponent == null || pawn.CBodyComponent.SceneNode == null)
{
return;
}
if (model == null)
{
var defaultModel = Service.GetMapDefaultModel(player);
if (defaultModel != null)
{
pawn.SetModel(defaultModel);
}
return;
}
pawn.SetModel(model.Path);
var originalRender = pawn.Render;
pawn.Render = Color.FromArgb(disableleg ? 254 : 255, originalRender.R, originalRender.G, originalRender.B);


ulong meshgroupmask = pawn.CBodyComponent.SceneNode.GetSkeletonInstance().ModelState.MeshGroupMask;
if (Service.InitMeshgroupPreference(player, model, meshgroupmask))
Expand Down
66 changes: 62 additions & 4 deletions Service.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Extensions;
using CounterStrikeSharp.API.Modules.Utils;
using Microsoft.Extensions.Localization;

namespace PlayerModelChanger;

struct MapDefaultModel
{
public string? T { get; set; }
public string? CT { get; set; }
}

public class ModelService
{

Expand All @@ -17,6 +24,8 @@ public class ModelService

private ModelCacheManager _CacheManager;

private Dictionary<ulong, MapDefaultModel> _MapDefaultModels = new Dictionary<ulong, MapDefaultModel>();


private Dictionary<ulong, long> _ModelChangeCooldown = new Dictionary<ulong, long>();

Expand Down Expand Up @@ -91,7 +100,8 @@ public void SetPlayerModel(ulong steamid, string? modelIndex, Side side, bool pe
if (player == null) { return; }
if (Utils.CanPlayerSetModelInstantly(player, side))
{
Utils.RespawnPlayer(player, _Config.Inspection.Enable && modelIndex != "@random");
var model = GetPlayerModel(player, side);
Utils.InstantUpdatePlayer(player, model, _Config.Inspection.Enable && modelIndex != "@random");
}
}
}
Expand All @@ -110,8 +120,8 @@ public void SetPlayerAllModel(ulong steamid, string? tModel, string? ctModel, bo
if (player == null) { return; }
if (Utils.CanPlayerSetModelInstantly(player, Side.All))
{
var index = GetModel(player.Team == CsTeam.Terrorist ? tModel : ctModel)?.Index;
Utils.RespawnPlayer(player, inspection && _Config.Inspection.Enable && index != "@random");
var model = GetModel(player.Team == CsTeam.Terrorist ? tModel : ctModel);
Utils.InstantUpdatePlayer(player, model, inspection && _Config.Inspection.Enable && model?.Index != "@random");
}
}
}
Expand Down Expand Up @@ -396,8 +406,56 @@ public void MeshgroupUpdate(CCSPlayerController player)
{
if (Utils.CanPlayerSetModelInstantly(player, Side.All))
{
Utils.RespawnPlayer(player, _Config.Inspection.Enable);
var model = GetPlayerNowTeamModel(player);
Utils.InstantUpdatePlayer(player, model, _Config.Inspection.Enable);
}
}

public bool MapDefaultModelInitialized(CCSPlayerController player)
{
if (!_MapDefaultModels.ContainsKey(player.AuthorizedSteamID!.SteamId64))
{
return false;
}
MapDefaultModel model = _MapDefaultModels[player.AuthorizedSteamID!.SteamId64];
if (player.Team == CsTeam.None || player.Team == CsTeam.Spectator)
{
return true;
}
return player.Team == CsTeam.Terrorist ? model.T != null : model.CT != null;
}
public void SetMapDefaultModel(CCSPlayerController player, string model)
{
var m = _MapDefaultModels.GetValueOrDefault(player.AuthorizedSteamID!.SteamId64, new MapDefaultModel());
if (player.Team == CsTeam.CounterTerrorist)
{
m.CT = model;
}
else if (player.Team == CsTeam.Terrorist)
{
m.T = model;
}
_MapDefaultModels[player.AuthorizedSteamID!.SteamId64] = m;
}
public string? GetMapDefaultModel(CCSPlayerController player)
{
if (!_MapDefaultModels.ContainsKey(player.AuthorizedSteamID!.SteamId64))
{
return null;
}
if (player.Team == CsTeam.CounterTerrorist)
{
return _MapDefaultModels[player.AuthorizedSteamID!.SteamId64].CT;
}
else if (player.Team == CsTeam.Terrorist)
{
return _MapDefaultModels[player.AuthorizedSteamID!.SteamId64].T;
}
return null;
}
public void ClearMapDefaultModel()
{
_MapDefaultModels.Clear();
}

}
54 changes: 20 additions & 34 deletions Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,49 +124,35 @@ private static bool IsUpdatingSameTeam(CCSPlayerController player, Side side)
return (side == Side.T && player.Team == CsTeam.Terrorist) || (side == Side.CT && player.Team == CsTeam.CounterTerrorist);
}

public static void RespawnPlayer(CCSPlayerController player, bool enableThirdPersonPreview)
public static void InstantUpdatePlayer(CCSPlayerController player, Model? model, bool enableThirdPersonPreview)
{
if (player.PlayerPawn.Value == null || !player.PlayerPawn.Value.IsValid)
{
return;
}
Server.NextFrame(() =>
PlayerModelChanger.getInstance().SetModelNextServerFrame(player, model, model == null ? false : model.Disableleg).ContinueWith((_) =>
{
var playerPawn = player.PlayerPawn.Value!;
var absOrigin = new Vector(playerPawn.AbsOrigin?.X, playerPawn.AbsOrigin?.Y, playerPawn.AbsOrigin?.Z);
var absAngle = new QAngle(playerPawn.AbsRotation?.X, playerPawn.AbsRotation?.Y, playerPawn.AbsRotation?.Z);
var health = playerPawn.Health;
var armor = playerPawn.ArmorValue;
CCSPlayer_ItemServices services = new CCSPlayer_ItemServices(playerPawn.ItemServices!.Handle);
var armorHelmet = services.HasHelmet;
var defuser = services.HasDefuser;

player.Respawn();
playerPawn.Teleport(absOrigin, absAngle);
playerPawn.Health = health;
Utilities.SetStateChanged(playerPawn, "CBaseEntity", "m_iHealth");
playerPawn.ArmorValue = armor;
services.HasHelmet = armorHelmet;
services.HasDefuser = defuser;
Utilities.SetStateChanged(playerPawn, "CBasePlayerPawn", "m_pItemServices");
if (enableThirdPersonPreview)
Server.NextFrame(() =>
{
var model = PlayerModelChanger.getInstance().Service.GetPlayerNowTeamModel(player);
var path = "";
if (model == null || model.Path == "")
if (enableThirdPersonPreview)
{
path = playerPawn.CBodyComponent?.SceneNode?.GetSkeletonInstance().ModelState.ModelName;
}
else
{
path = model.Path;
}
if (path != null)
{
Inspection.InspectModelForPlayer(player, path, model);
var model = PlayerModelChanger.getInstance().Service.GetPlayerNowTeamModel(player);
var path = "";
if (model == null || model.Path == "")
{
path = player.PlayerPawn.Value.CBodyComponent?.SceneNode?.GetSkeletonInstance().ModelState.ModelName;
}
else
{
path = model.Path;
}
if (path != null)
{
Inspection.InspectModelForPlayer(player, path, model);
}
}
}
player.PrintToChat(PlayerModelChanger.getInstance().Localizer["command.model.instantsuccess"]);
player.PrintToChat(PlayerModelChanger.getInstance().Localizer["command.model.instantsuccess"]);
});
});
}

Expand Down
Binary file modified build/Release/PlayerModelChanger/PlayerModelChanger.dll
Binary file not shown.
Binary file modified build/Release/PlayerModelChanger/PlayerModelChanger.pdb
Binary file not shown.

0 comments on commit 9b93526

Please sign in to comment.