|
|
|
|
@@ -37,6 +37,9 @@ namespace WeaponPaints
|
|
|
|
|
|
|
|
|
|
weapon.AttributeManager.Item.ItemDefinitionIndex = (ushort)newDefIndex.Key;
|
|
|
|
|
weapon.AttributeManager.Item.EntityQuality = 3;
|
|
|
|
|
|
|
|
|
|
weapon.AttributeManager.Item.AttributeList.Attributes.RemoveAll();
|
|
|
|
|
weapon.AttributeManager.Item.NetworkedDynamicAttributes.Attributes.RemoveAll();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
@@ -96,9 +99,8 @@ namespace WeaponPaints
|
|
|
|
|
weapon.AttributeManager.Item.AttributeList.Attributes.RemoveAll();
|
|
|
|
|
weapon.AttributeManager.Item.NetworkedDynamicAttributes.Attributes.RemoveAll();
|
|
|
|
|
|
|
|
|
|
weapon.AttributeManager.Item.ItemID = 16384;
|
|
|
|
|
weapon.AttributeManager.Item.ItemIDLow = 16384 & 0xFFFFFFFF;
|
|
|
|
|
weapon.AttributeManager.Item.ItemIDHigh = weapon.AttributeManager.Item.ItemIDLow >> 32;
|
|
|
|
|
UpdatePlayerEconItemId(weapon.AttributeManager.Item);
|
|
|
|
|
|
|
|
|
|
weapon.AttributeManager.Item.CustomName = weaponInfo.Nametag;
|
|
|
|
|
weapon.FallbackPaintKit = weaponInfo.Paint;
|
|
|
|
|
|
|
|
|
|
@@ -137,27 +139,6 @@ namespace WeaponPaints
|
|
|
|
|
UpdatePlayerWeaponMeshGroupMask(player, weapon, isLegacyModel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// silly method to update sticker when call RefreshWeapons()
|
|
|
|
|
private void IncrementWearForWeaponWithStickers(CCSPlayerController player, CBasePlayerWeapon weapon)
|
|
|
|
|
{
|
|
|
|
|
int weaponDefIndex = weapon.AttributeManager.Item.ItemDefinitionIndex;
|
|
|
|
|
if (!HasChangedPaint(player, weaponDefIndex, out var weaponInfo) || weaponInfo == null ||
|
|
|
|
|
weaponInfo.Stickers.Count <= 0) return;
|
|
|
|
|
|
|
|
|
|
float wearIncrement = 0.001f;
|
|
|
|
|
float currentWear = weaponInfo.Wear;
|
|
|
|
|
|
|
|
|
|
var playerWear = _temporaryPlayerWeaponWear.GetOrAdd(player.Slot, _ => new ConcurrentDictionary<int, float>());
|
|
|
|
|
|
|
|
|
|
float incrementedWear = playerWear.AddOrUpdate(
|
|
|
|
|
weaponDefIndex,
|
|
|
|
|
currentWear + wearIncrement,
|
|
|
|
|
(_, oldWear) => Math.Min(oldWear + wearIncrement, 1.0f)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
weapon.FallbackWear = incrementedWear;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SetStickers(CCSPlayerController? player, CBasePlayerWeapon weapon)
|
|
|
|
|
{
|
|
|
|
|
if (player == null || !player.IsValid) return;
|
|
|
|
|
@@ -215,7 +196,7 @@ namespace WeaponPaints
|
|
|
|
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle,
|
|
|
|
|
"keychain slot 0 offset z", keyChain.OffsetZ);
|
|
|
|
|
CAttributeListSetOrAddAttributeValueByName.Invoke(weapon.AttributeManager.Item.NetworkedDynamicAttributes.Handle,
|
|
|
|
|
"keychain slot 0 seed", keyChain.Seed);
|
|
|
|
|
"keychain slot 0 seed", ViewAsFloat(keyChain.Seed));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void GiveKnifeToPlayer(CCSPlayerController? player)
|
|
|
|
|
@@ -285,7 +266,6 @@ namespace WeaponPaints
|
|
|
|
|
if (!weapon.Value.OwnerEntity.IsValid) continue;
|
|
|
|
|
if (gun.Entity == null) continue;
|
|
|
|
|
if (!gun.IsValid) continue;
|
|
|
|
|
if (!gun.VisibleinPVS) continue;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
@@ -351,8 +331,6 @@ namespace WeaponPaints
|
|
|
|
|
{
|
|
|
|
|
newWeapon.Clip1 = ammo.Item1;
|
|
|
|
|
newWeapon.ReserveAmmo[0] = ammo.Item2;
|
|
|
|
|
|
|
|
|
|
IncrementWearForWeaponWithStickers(player, newWeapon);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
@@ -397,16 +375,22 @@ namespace WeaponPaints
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
item.ItemDefinitionIndex = gloveId;
|
|
|
|
|
item.ItemIDLow = 16384 & 0xFFFFFFFF;
|
|
|
|
|
item.ItemIDHigh = 16384;
|
|
|
|
|
|
|
|
|
|
UpdatePlayerEconItemId(item);
|
|
|
|
|
|
|
|
|
|
item.NetworkedDynamicAttributes.Attributes.RemoveAll();
|
|
|
|
|
CAttributeListSetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle, "set item texture prefab", weaponInfo.Paint);
|
|
|
|
|
CAttributeListSetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle, "set item texture seed", weaponInfo.Seed);
|
|
|
|
|
CAttributeListSetOrAddAttributeValueByName.Invoke(item.NetworkedDynamicAttributes.Handle, "set item texture wear", weaponInfo.Wear);
|
|
|
|
|
|
|
|
|
|
item.AttributeList.Attributes.RemoveAll();
|
|
|
|
|
CAttributeListSetOrAddAttributeValueByName.Invoke(item.AttributeList.Handle, "set item texture prefab", weaponInfo.Paint);
|
|
|
|
|
CAttributeListSetOrAddAttributeValueByName.Invoke(item.AttributeList.Handle, "set item texture seed", weaponInfo.Seed);
|
|
|
|
|
CAttributeListSetOrAddAttributeValueByName.Invoke(item.AttributeList.Handle, "set item texture wear", weaponInfo.Wear);
|
|
|
|
|
|
|
|
|
|
item.Initialized = true;
|
|
|
|
|
|
|
|
|
|
SetBodygroup(pawn.Handle, "default_gloves", 1);
|
|
|
|
|
SetBodygroup(pawn, "default_gloves", 1);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception) { }
|
|
|
|
|
}, TimerFlags.STOP_ON_MAPCHANGE);
|
|
|
|
|
@@ -430,13 +414,15 @@ namespace WeaponPaints
|
|
|
|
|
return int.TryParse(randomWeapon["paint"]?.ToString(), out var paintValue) ? paintValue : 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void SubclassChange(CBasePlayerWeapon weapon, ushort itemD)
|
|
|
|
|
//xstage idea on css discord
|
|
|
|
|
public static void SubclassChange(CBasePlayerWeapon weapon, ushort itemD)
|
|
|
|
|
{
|
|
|
|
|
var subclassChangeFunc = VirtualFunction.Create<nint, string, int>(
|
|
|
|
|
GameData.GetSignature("ChangeSubclass")
|
|
|
|
|
);
|
|
|
|
|
weapon.AcceptInput("ChangeSubclass", value: itemD.ToString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
subclassChangeFunc(weapon.Handle, itemD.ToString());
|
|
|
|
|
public static void SetBodygroup(CCSPlayerPawn pawn, string group, int value)
|
|
|
|
|
{
|
|
|
|
|
pawn.AcceptInput("SetBodygroup", value:$"{group},{value}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void UpdateWeaponMeshGroupMask(CBaseEntity weapon, bool isLegacy = false)
|
|
|
|
|
@@ -454,13 +440,6 @@ namespace WeaponPaints
|
|
|
|
|
private static void UpdatePlayerWeaponMeshGroupMask(CCSPlayerController player, CBasePlayerWeapon weapon, bool isLegacy)
|
|
|
|
|
{
|
|
|
|
|
UpdateWeaponMeshGroupMask(weapon, isLegacy);
|
|
|
|
|
|
|
|
|
|
var viewModel = GetPlayerViewModel(player);
|
|
|
|
|
if (viewModel == null || viewModel.Weapon.Value == null ||
|
|
|
|
|
viewModel.Weapon.Value.Index != weapon.Index) return;
|
|
|
|
|
|
|
|
|
|
UpdateWeaponMeshGroupMask(viewModel, isLegacy);
|
|
|
|
|
Utilities.SetStateChanged(viewModel, "CBaseEntity", "m_CBodyComponent");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void GivePlayerAgent(CCSPlayerController player)
|
|
|
|
|
@@ -558,16 +537,6 @@ namespace WeaponPaints
|
|
|
|
|
return !Utility.IsPlayerValid(player) ? null : player;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static unsafe CBaseViewModel? GetPlayerViewModel(CCSPlayerController player)
|
|
|
|
|
{
|
|
|
|
|
if (player.PlayerPawn.Value == null || player.PlayerPawn.Value.ViewModelServices == null) return null;
|
|
|
|
|
CCSPlayer_ViewModelServices viewModelServices = new(player.PlayerPawn.Value.ViewModelServices!.Handle);
|
|
|
|
|
var ptr = viewModelServices.Handle + Schema.GetSchemaOffset("CCSPlayer_ViewModelServices", "m_hViewModel");
|
|
|
|
|
var references = MemoryMarshal.CreateSpan(ref ptr, 3);
|
|
|
|
|
var viewModel = (CHandle<CBaseViewModel>)Activator.CreateInstance(typeof(CHandle<CBaseViewModel>), references[0])!;
|
|
|
|
|
return viewModel.Value == null ? null : viewModel.Value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static bool HasChangedKnife(CCSPlayerController player, out string? knifeValue)
|
|
|
|
|
{
|
|
|
|
|
knifeValue = null;
|
|
|
|
|
|