Files
RAGECOOP-V/Client/Scripts/Sync/Entities/SyncedProjectile.cs

138 lines
4.5 KiB
C#
Raw Normal View History

2022-07-20 17:50:01 +08:00
using GTA;
using GTA.Math;
2022-08-14 17:08:43 +08:00
using GTA.Native;
2022-09-06 21:46:35 +08:00
using RageCoop.Core;
2022-05-23 19:19:56 +08:00
namespace RageCoop.Client
{
internal class SyncedProjectile : SyncedEntity
{
2022-08-14 17:08:43 +08:00
public readonly Vector3 Origin;
2022-10-23 19:02:39 +08:00
private bool _firstSend;
2022-08-14 17:08:43 +08:00
2022-10-23 19:02:39 +08:00
public SyncedProjectile(Projectile p)
2022-08-14 17:08:43 +08:00
{
2022-10-23 19:02:39 +08:00
var owner = p.OwnerEntity;
if (owner == null)
2022-08-14 17:08:43 +08:00
{
2022-10-23 19:02:39 +08:00
IsValid = false;
return;
2022-08-14 17:08:43 +08:00
}
2022-09-06 21:46:35 +08:00
ID = EntityPool.RequestNewID();
MainProjectile = p;
2022-09-06 21:46:35 +08:00
Origin = p.Position;
if (EntityPool.PedsByHandle.TryGetValue(owner.Handle, out var shooter))
2022-05-26 17:11:37 +08:00
{
2022-09-06 21:46:35 +08:00
if (shooter.MainPed != null
&& (p.AttachedEntity == shooter.MainPed.Weapons.CurrentWeaponObject
2022-10-23 19:02:39 +08:00
|| p.AttachedEntity == shooter.MainPed))
2022-06-17 11:33:53 +08:00
{
// Reloading
2022-09-06 21:46:35 +08:00
IsValid = false;
2022-08-14 17:08:43 +08:00
return;
2022-06-17 11:33:53 +08:00
}
2022-10-23 19:02:39 +08:00
2022-09-06 21:46:35 +08:00
Shooter = shooter;
IsLocal = shooter.IsLocal;
2022-06-17 11:33:53 +08:00
}
2022-09-06 21:46:35 +08:00
else if (EntityPool.VehiclesByHandle.TryGetValue(owner.Handle, out var shooterVeh))
2022-08-14 17:08:43 +08:00
{
2022-09-06 21:46:35 +08:00
Shooter = shooterVeh;
IsLocal = shooterVeh.IsLocal;
2022-08-14 17:08:43 +08:00
}
else
{
2022-09-06 21:46:35 +08:00
IsValid = false;
2022-08-14 17:08:43 +08:00
}
}
2022-10-23 19:02:39 +08:00
public SyncedProjectile(int id)
{
2022-09-06 21:46:35 +08:00
ID = id;
IsLocal = false;
}
2022-10-23 19:02:39 +08:00
public ProjectileDataFlags Flags { private get; set; } = ProjectileDataFlags.None;
public bool IsValid { get; } = true;
public new bool IsLocal { get; }
public Projectile MainProjectile { get; set; }
public SyncedEntity Shooter { get; set; }
public bool Exploded => Flags.HasProjDataFlag(ProjectileDataFlags.Exploded);
internal override Player Owner => Shooter.Owner;
/// <summary>
/// Invalid property for projectile.
/// </summary>
private new int OwnerID
{
set { }
}
public WeaponHash WeaponHash { get; set; }
private WeaponAsset Asset { get; set; }
public void ExtractData(ref Packets.ProjectileSync p)
{
2022-10-23 19:02:39 +08:00
p.Position = MainProjectile.Position;
p.Velocity = MainProjectile.Velocity;
p.Rotation = MainProjectile.Rotation;
p.ID = ID;
p.ShooterID = Shooter.ID;
p.WeaponHash = (uint)MainProjectile.WeaponHash;
p.Flags = ProjectileDataFlags.None;
if (MainProjectile.IsDead) p.Flags |= ProjectileDataFlags.Exploded;
if (MainProjectile.AttachedEntity != null) p.Flags |= ProjectileDataFlags.IsAttached;
if (Shooter is SyncedVehicle) p.Flags |= ProjectileDataFlags.IsShotByVehicle;
if (_firstSend)
{
p.Flags |= ProjectileDataFlags.IsAttached;
_firstSend = false;
}
}
2022-10-23 19:02:39 +08:00
internal override void Update()
{
// Skip update if no new sync message has arrived.
2022-10-23 19:02:39 +08:00
if (!NeedUpdate) return;
2022-05-23 19:19:56 +08:00
if (MainProjectile == null || !MainProjectile.Exists())
{
2022-05-23 19:19:56 +08:00
CreateProjectile();
return;
}
2022-10-23 19:02:39 +08:00
2022-09-08 12:41:56 -07:00
MainProjectile.Velocity = Velocity + 10 * (Predict(Position) - MainProjectile.Position);
2022-09-06 21:46:35 +08:00
MainProjectile.Rotation = Rotation;
2023-02-13 20:44:50 +08:00
LastUpdated = Ticked;
2022-05-23 19:19:56 +08:00
}
private void CreateProjectile()
{
2022-09-06 21:46:35 +08:00
Asset = new WeaponAsset(WeaponHash);
2022-10-23 19:02:39 +08:00
if (!Asset.IsLoaded)
{
Asset.Request();
return;
}
if (Shooter == null) return;
2022-08-14 17:08:43 +08:00
Entity owner;
2022-09-06 21:46:35 +08:00
owner = (Shooter as SyncedPed)?.MainPed ?? (Entity)(Shooter as SyncedVehicle)?.MainVehicle;
2022-10-23 19:02:39 +08:00
Position = (Owner.PacketTravelTime + 0.001f * LastSyncedStopWatch.ElapsedMilliseconds) * Shooter.Velocity +
Position;
2022-09-06 21:46:35 +08:00
var end = Position + Velocity;
Call(SHOOT_SINGLE_BULLET_BETWEEN_COORDS_IGNORE_ENTITY, Position.X, Position.Y, Position.Z,
2022-10-23 19:02:39 +08:00
end.X, end.Y, end.Z, 0, 1, WeaponHash, owner?.Handle ?? 0, 1, 0, -1);
var ps = World.GetAllProjectiles();
2022-09-06 21:46:35 +08:00
MainProjectile = ps[ps.Length - 1];
MainProjectile.Position = Position;
MainProjectile.Rotation = Rotation;
MainProjectile.Velocity = Velocity;
EntityPool.Add(this);
}
}
2022-10-23 19:02:39 +08:00
}