2022-10-23 19:02:39 +08:00
|
|
|
|
using System;
|
|
|
|
|
using GTA;
|
2022-05-22 15:55:26 +08:00
|
|
|
|
using GTA.Math;
|
2023-03-19 13:43:46 +08:00
|
|
|
|
using GTA.Native;
|
2022-09-06 21:46:35 +08:00
|
|
|
|
using Lidgren.Network;
|
2022-10-23 19:02:39 +08:00
|
|
|
|
using RageCoop.Client.Scripting;
|
2022-05-22 15:55:26 +08:00
|
|
|
|
using RageCoop.Core;
|
|
|
|
|
|
2022-07-20 17:50:01 +08:00
|
|
|
|
namespace RageCoop.Client
|
|
|
|
|
{
|
2022-05-22 15:55:26 +08:00
|
|
|
|
internal static class SyncEvents
|
|
|
|
|
{
|
|
|
|
|
#region TRIGGER
|
2022-10-23 19:02:39 +08:00
|
|
|
|
|
2022-05-22 15:55:26 +08:00
|
|
|
|
public static void TriggerPedKilled(SyncedPed victim)
|
|
|
|
|
{
|
2022-10-23 19:02:39 +08:00
|
|
|
|
Networking.SendSync(new Packets.PedKilled { VictimID = victim.ID }, ConnectionChannel.SyncEvents);
|
2022-05-22 15:55:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-13 16:14:18 +08:00
|
|
|
|
public static void TriggerChangeOwner(int vehicleID, int newOwnerID)
|
2022-05-22 15:55:26 +08:00
|
|
|
|
{
|
2022-10-23 19:02:39 +08:00
|
|
|
|
Networking.SendSync(new Packets.OwnerChanged
|
2022-05-23 15:48:02 +08:00
|
|
|
|
{
|
2022-09-06 21:46:35 +08:00
|
|
|
|
ID = vehicleID,
|
2022-10-23 19:02:39 +08:00
|
|
|
|
NewOwnerID = newOwnerID
|
2022-09-06 21:46:35 +08:00
|
|
|
|
}, ConnectionChannel.SyncEvents, NetDeliveryMethod.ReliableOrdered);
|
2022-05-22 15:55:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-20 17:50:01 +08:00
|
|
|
|
public static void TriggerNozzleTransform(int vehID, bool hover)
|
2022-05-29 18:16:32 +08:00
|
|
|
|
{
|
2022-10-23 19:02:39 +08:00
|
|
|
|
Networking.SendSync(new Packets.NozzleTransform { VehicleID = vehID, Hover = hover },
|
|
|
|
|
ConnectionChannel.SyncEvents);
|
2022-05-29 18:16:32 +08:00
|
|
|
|
}
|
2022-05-22 15:55:26 +08:00
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region HANDLE
|
|
|
|
|
|
2022-06-02 15:51:58 +08:00
|
|
|
|
public static ParticleEffectAsset CorePFXAsset = new ParticleEffectAsset("core");
|
2022-05-29 18:16:32 +08:00
|
|
|
|
|
2022-05-26 17:11:37 +08:00
|
|
|
|
private static void HandlePedKilled(Packets.PedKilled p)
|
2022-05-22 15:55:26 +08:00
|
|
|
|
{
|
|
|
|
|
EntityPool.GetPedByID(p.VictimID)?.MainPed?.Kill();
|
|
|
|
|
}
|
2022-10-23 19:02:39 +08:00
|
|
|
|
|
2022-05-26 17:11:37 +08:00
|
|
|
|
private static void HandleOwnerChanged(Packets.OwnerChanged p)
|
2022-05-22 15:55:26 +08:00
|
|
|
|
{
|
|
|
|
|
var v = EntityPool.GetVehicleByID(p.ID);
|
2022-10-23 19:02:39 +08:00
|
|
|
|
if (v == null) return;
|
2022-09-06 21:46:35 +08:00
|
|
|
|
v.OwnerID = p.NewOwnerID;
|
2022-12-04 19:34:54 +08:00
|
|
|
|
v.SetLastSynced(true);
|
2022-09-06 21:46:35 +08:00
|
|
|
|
v.Position = v.MainVehicle.Position;
|
|
|
|
|
v.Quaternion = v.MainVehicle.Quaternion;
|
2022-05-22 15:55:26 +08:00
|
|
|
|
}
|
2022-10-23 19:02:39 +08:00
|
|
|
|
|
2022-05-29 18:16:32 +08:00
|
|
|
|
private static void HandleNozzleTransform(Packets.NozzleTransform p)
|
|
|
|
|
{
|
|
|
|
|
EntityPool.GetVehicleByID(p.VehicleID)?.MainVehicle?.SetNozzleAngel(p.Hover ? 1 : 0);
|
|
|
|
|
}
|
2022-10-23 19:02:39 +08:00
|
|
|
|
|
2022-12-04 19:34:54 +08:00
|
|
|
|
private static void HandleBulletShot(int ownerID, uint weaponHash, Vector3 end)
|
2022-05-22 15:55:26 +08:00
|
|
|
|
{
|
2022-12-04 19:34:54 +08:00
|
|
|
|
var c = EntityPool.GetPedByID(ownerID);
|
|
|
|
|
var p = c?.MainPed;
|
2022-10-23 19:02:39 +08:00
|
|
|
|
if (p == null)
|
|
|
|
|
{
|
2022-12-04 19:34:54 +08:00
|
|
|
|
return;
|
|
|
|
|
// p = Game.Player.Character;
|
2023-02-13 17:51:18 +08:00
|
|
|
|
// Log.Warning("Failed to find owner for bullet");
|
2022-10-23 19:02:39 +08:00
|
|
|
|
}
|
2022-10-19 19:07:46 +08:00
|
|
|
|
|
|
|
|
|
var damage = (int)p.GetWeaponDamage(weaponHash);
|
2022-12-04 19:34:54 +08:00
|
|
|
|
|
|
|
|
|
// Some weapon hash has some firing issue, so we need to replace it with known good ones
|
2022-10-19 19:07:46 +08:00
|
|
|
|
weaponHash = WeaponUtil.GetWeaponFix(weaponHash);
|
|
|
|
|
|
2022-12-04 19:34:54 +08:00
|
|
|
|
// Request asset for muzzle flash
|
2022-10-23 19:02:39 +08:00
|
|
|
|
if (!CorePFXAsset.IsLoaded) CorePFXAsset.Request();
|
2022-12-04 19:34:54 +08:00
|
|
|
|
|
|
|
|
|
// Request asset for materialising the bullet
|
2022-10-19 19:07:46 +08:00
|
|
|
|
var asset = new WeaponAsset(weaponHash);
|
2022-10-23 19:02:39 +08:00
|
|
|
|
if (!asset.IsLoaded) asset.Request();
|
|
|
|
|
|
2023-03-19 13:43:46 +08:00
|
|
|
|
var vehWeap = p.VehicleWeapon;
|
|
|
|
|
bool isVeh = vehWeap != VehicleWeaponHash.Invalid;
|
|
|
|
|
var bone = isVeh ? c.MainPed.CurrentVehicle.GetMuzzleBone(vehWeap) : c.MainPed.GetMuzzleBone();
|
2023-03-19 15:22:38 +08:00
|
|
|
|
if (bone == null)
|
|
|
|
|
{
|
|
|
|
|
Log.Warning($"Failed to find muzzle bone for {(isVeh ? vehWeap : (WeaponHash)weaponHash)}, {(isVeh ? p.CurrentVehicle.DisplayName : "")}");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-12-04 19:34:54 +08:00
|
|
|
|
World.ShootBullet(bone.Position, end, p, asset, damage);
|
|
|
|
|
|
2022-09-06 21:46:35 +08:00
|
|
|
|
World.CreateParticleEffectNonLooped(CorePFXAsset,
|
2022-12-04 19:34:54 +08:00
|
|
|
|
!isVeh && p.Weapons.Current.Components.GetSuppressorComponent().Active
|
|
|
|
|
? "muz_pistol_silencer"
|
|
|
|
|
: ((WeaponHash)weaponHash).GetFlashFX(isVeh), bone.Position, isVeh ? bone.GetRotation() : bone.Owner.Rotation);
|
2022-05-22 15:55:26 +08:00
|
|
|
|
}
|
2022-10-23 19:02:39 +08:00
|
|
|
|
|
2022-09-08 12:41:56 -07:00
|
|
|
|
public static void HandleEvent(PacketType type, NetIncomingMessage msg)
|
2022-05-22 15:55:26 +08:00
|
|
|
|
{
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
2022-07-01 12:22:31 +08:00
|
|
|
|
case PacketType.BulletShot:
|
2022-12-04 19:34:54 +08:00
|
|
|
|
{
|
|
|
|
|
var p = msg.GetPacket<Packets.BulletShot>();
|
|
|
|
|
HandleBulletShot(p.OwnerID, p.WeaponHash, p.EndPosition);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-07-01 12:22:31 +08:00
|
|
|
|
case PacketType.OwnerChanged:
|
2022-12-04 19:34:54 +08:00
|
|
|
|
{
|
|
|
|
|
HandleOwnerChanged(msg.GetPacket<Packets.OwnerChanged>());
|
|
|
|
|
}
|
2022-05-22 15:55:26 +08:00
|
|
|
|
break;
|
2022-07-01 12:22:31 +08:00
|
|
|
|
case PacketType.PedKilled:
|
2022-12-04 19:34:54 +08:00
|
|
|
|
{
|
|
|
|
|
HandlePedKilled(msg.GetPacket<Packets.PedKilled>());
|
|
|
|
|
}
|
2022-05-22 15:55:26 +08:00
|
|
|
|
break;
|
2022-07-01 12:22:31 +08:00
|
|
|
|
case PacketType.NozzleTransform:
|
2022-12-04 19:34:54 +08:00
|
|
|
|
{
|
|
|
|
|
HandleNozzleTransform(msg.GetPacket<Packets.NozzleTransform>());
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-05-22 15:55:26 +08:00
|
|
|
|
}
|
2022-10-23 19:02:39 +08:00
|
|
|
|
|
2022-09-08 12:37:06 -07:00
|
|
|
|
Networking.Peer.Recycle(msg);
|
2022-05-22 15:55:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region CHECK EVENTS
|
|
|
|
|
|
|
|
|
|
public static void Check(SyncedPed c)
|
|
|
|
|
{
|
2022-10-23 19:02:39 +08:00
|
|
|
|
var subject = c.MainPed;
|
2022-05-31 09:55:54 +08:00
|
|
|
|
|
|
|
|
|
// Check bullets
|
2022-12-04 19:34:54 +08:00
|
|
|
|
if (subject.IsShooting && !subject.IsUsingProjectileWeapon())
|
2022-05-22 15:55:26 +08:00
|
|
|
|
{
|
2022-12-04 19:34:54 +08:00
|
|
|
|
|
|
|
|
|
var i = 0;
|
|
|
|
|
|
|
|
|
|
// Some weapon is not instant hit, so we may need to wait a few ticks to get the impact position
|
|
|
|
|
bool getBulletImpact()
|
2022-05-22 15:55:26 +08:00
|
|
|
|
{
|
2022-12-04 19:34:54 +08:00
|
|
|
|
var endPos = subject.LastWeaponImpactPosition;
|
2023-03-19 13:43:46 +08:00
|
|
|
|
var vehWeap = subject.VehicleWeapon;
|
|
|
|
|
if (vehWeap == VehicleWeaponHash.Invalid)
|
2022-05-22 15:55:26 +08:00
|
|
|
|
{
|
2023-03-19 13:43:46 +08:00
|
|
|
|
// Ped weapon sync
|
|
|
|
|
var pedWeap = subject.Weapons.Current.Hash;
|
|
|
|
|
if (endPos != default)
|
|
|
|
|
{
|
|
|
|
|
Networking.SendBullet(c.ID, (uint)pedWeap, endPos);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get impact in next tick
|
|
|
|
|
if (++i <= 5) return false;
|
|
|
|
|
|
|
|
|
|
// Exceeded maximum wait of 5 ticks, return (inaccurate) aim coordinate
|
|
|
|
|
endPos = subject.GetAimCoord();
|
|
|
|
|
Networking.SendBullet(c.ID, (uint)pedWeap, endPos);
|
2022-12-04 19:34:54 +08:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2023-03-19 13:43:46 +08:00
|
|
|
|
else
|
2022-12-04 19:34:54 +08:00
|
|
|
|
{
|
2023-03-19 13:43:46 +08:00
|
|
|
|
// Veh weapon sync
|
|
|
|
|
if (endPos == default)
|
|
|
|
|
{
|
2023-03-19 15:22:38 +08:00
|
|
|
|
var veh = c.MainPed.CurrentVehicle;
|
|
|
|
|
var b = veh.GetMuzzleBone(vehWeap);
|
|
|
|
|
if (b == null)
|
|
|
|
|
{
|
|
|
|
|
Log.Warning($"Failed to find muzzle bone for {vehWeap}, {veh.DisplayName}");
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2023-03-19 13:43:46 +08:00
|
|
|
|
endPos = b.Position + b.ForwardVector * 200;
|
|
|
|
|
}
|
|
|
|
|
Networking.SendBullet(c.ID, (uint)vehWeap, endPos);
|
2022-08-11 14:29:18 +02:00
|
|
|
|
return true;
|
2022-12-04 19:34:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-22 15:55:26 +08:00
|
|
|
|
}
|
2022-12-04 19:34:54 +08:00
|
|
|
|
|
|
|
|
|
if (!getBulletImpact()) API.QueueAction(getBulletImpact);
|
2022-05-22 15:55:26 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-20 17:50:01 +08:00
|
|
|
|
|
2022-05-29 18:16:32 +08:00
|
|
|
|
public static void Check(SyncedVehicle v)
|
|
|
|
|
{
|
2022-10-23 19:02:39 +08:00
|
|
|
|
if (v.MainVehicle == null || !v.MainVehicle.HasNozzle()) return;
|
2022-08-11 14:29:18 +02:00
|
|
|
|
|
2022-10-23 19:02:39 +08:00
|
|
|
|
if (v.LastNozzleAngle == 1 && v.MainVehicle.GetNozzleAngel() != 1)
|
2022-08-11 14:29:18 +02:00
|
|
|
|
TriggerNozzleTransform(v.ID, false);
|
2022-10-23 19:02:39 +08:00
|
|
|
|
else if (v.LastNozzleAngle == 0 && v.MainVehicle.GetNozzleAngel() != 0) TriggerNozzleTransform(v.ID, true);
|
2022-08-11 14:29:18 +02:00
|
|
|
|
v.LastNozzleAngle = v.MainVehicle.GetNozzleAngel();
|
2022-05-29 18:16:32 +08:00
|
|
|
|
}
|
2022-10-23 19:02:39 +08:00
|
|
|
|
|
2022-05-22 15:55:26 +08:00
|
|
|
|
#endregion
|
|
|
|
|
}
|
2022-10-23 19:02:39 +08:00
|
|
|
|
}
|