Projectile refactor
This commit is contained in:
parent
4acf964f0a
commit
b5f6fc578d
@ -416,17 +416,17 @@ namespace RageCoop.Client
|
||||
var p = EntityPool.GetProjectileByID(packet.ID);
|
||||
if (p==null)
|
||||
{
|
||||
|
||||
if (packet.Exploded) { return; }
|
||||
if (packet.Flags.HasProjDataFlag(ProjectileDataFlags.Exploded)) { return; }
|
||||
// Main.Logger.Debug($"Creating new projectile: {(WeaponHash)packet.WeaponHash}");
|
||||
EntityPool.ThreadSafe.Add(p=new SyncedProjectile(packet.ID));
|
||||
}
|
||||
p.Flags=packet.Flags;
|
||||
p.Position=packet.Position;
|
||||
p.Rotation=packet.Rotation;
|
||||
p.Velocity=packet.Velocity;
|
||||
p.Hash=(WeaponHash)packet.WeaponHash;
|
||||
p.ShooterID=packet.ShooterID;
|
||||
p.Exploded=packet.Exploded;
|
||||
p.WeaponHash=(WeaponHash)packet.WeaponHash;
|
||||
p.Shooter= packet.Flags.HasProjDataFlag(ProjectileDataFlags.IsShotByVehicle) ?
|
||||
(SyncedEntity)EntityPool.GetVehicleByID(packet.ShooterID) : EntityPool.GetPedByID(packet.ShooterID);
|
||||
p.LastSynced=Main.Ticked;
|
||||
}
|
||||
}
|
||||
|
@ -164,17 +164,9 @@ namespace RageCoop.Client
|
||||
}
|
||||
public static void SendProjectile(SyncedProjectile sp)
|
||||
{
|
||||
var p = sp.MainProjectile;
|
||||
var packet = SendPackets.ProjectilePacket;
|
||||
packet.ID =sp.ID;
|
||||
packet.ShooterID=sp.ShooterID;
|
||||
packet.Rotation=p.Rotation;
|
||||
packet.Position=p.Position;
|
||||
packet.Velocity=p.Velocity;
|
||||
packet.WeaponHash=(uint)p.WeaponHash;
|
||||
packet.Exploded=p.IsDead;
|
||||
if (p.IsDead) { EntityPool.RemoveProjectile(sp.ID, "Dead"); }
|
||||
SendSync(packet, ConnectionChannel.ProjectileSync);
|
||||
sp.ExtractData(ref SendPackets.ProjectilePacket);
|
||||
if (sp.MainProjectile.IsDead) { EntityPool.RemoveProjectile(sp.ID, "Dead"); }
|
||||
SendSync(SendPackets.ProjectilePacket, ConnectionChannel.ProjectileSync);
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,7 +39,7 @@ namespace RageCoop.Client
|
||||
}
|
||||
}
|
||||
|
||||
internal Player Owner { get; private set; }
|
||||
internal virtual Player Owner { get; private set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
@ -667,9 +667,12 @@ namespace RageCoop.Client
|
||||
MainPed.PositionNoOffset=Position;
|
||||
return;
|
||||
}
|
||||
if (!(localRagdoll || MainPed.IsDead || IsAiming))
|
||||
if (!(localRagdoll || MainPed.IsDead))
|
||||
{
|
||||
MainPed.Heading=Heading;
|
||||
if (!IsAiming)
|
||||
{
|
||||
MainPed.Heading=Heading;
|
||||
}
|
||||
MainPed.Velocity=Velocity+5*dist*(Position-MainPed.ReadPosition());
|
||||
}
|
||||
else if (Main.Ticked-_lastRagdollTime<10)
|
||||
|
@ -1,61 +1,95 @@
|
||||
using GTA;
|
||||
using GTA.Math;
|
||||
using RageCoop.Core;
|
||||
using GTA.Native;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
internal class SyncedProjectile : SyncedEntity
|
||||
{
|
||||
public ProjectileDataFlags Flags { private get; set; }=ProjectileDataFlags.None;
|
||||
|
||||
public readonly Vector3 Origin;
|
||||
private bool _firstSend = false;
|
||||
|
||||
|
||||
public bool IsValid { get; private set; } = true;
|
||||
public new bool IsLocal { get; private set; } = false;
|
||||
public Projectile MainProjectile { get; set; }
|
||||
public SyncedEntity Shooter { get; set; }
|
||||
public bool Exploded => Flags.HasProjDataFlag(ProjectileDataFlags.Exploded);
|
||||
|
||||
/// <summary>
|
||||
/// Invalid property for projectile.
|
||||
/// </summary>
|
||||
private new int OwnerID { set { } }
|
||||
|
||||
internal override Player Owner => Shooter.Owner;
|
||||
public WeaponHash WeaponHash { get; set; }
|
||||
private WeaponAsset Asset { get; set; }
|
||||
public void ExtractData(ref Packets.ProjectileSync p)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
public SyncedProjectile(Projectile p)
|
||||
{
|
||||
var owner = p.OwnerEntity;
|
||||
if (owner==null) { IsValid=false;return; }
|
||||
ID=EntityPool.RequestNewID();
|
||||
MainProjectile = p;
|
||||
Origin=p.Position;
|
||||
var shooter = EntityPool.GetPedByHandle((p.OwnerEntity?.Handle).GetValueOrDefault());
|
||||
if (shooter==null)
|
||||
if(EntityPool.PedsByHandle.TryGetValue(owner.Handle,out var shooter))
|
||||
{
|
||||
// Owner will be the vehicle if projectile is shot with a vehicle
|
||||
var shooterVeh = EntityPool.GetVehicleByHandle((p.OwnerEntity?.Handle).GetValueOrDefault());
|
||||
if (shooterVeh!=null && shooterVeh.MainVehicle.Driver!=null)
|
||||
{
|
||||
shooter=shooterVeh.MainVehicle.Driver?.GetSyncEntity();
|
||||
}
|
||||
else
|
||||
{
|
||||
Main.Logger.Warning($"Could not find owner for projectile:{Hash}");
|
||||
}
|
||||
}
|
||||
if (shooter != null)
|
||||
{
|
||||
if (shooter.MainPed!=null && (p.AttachedEntity==shooter.MainPed.Weapons.CurrentWeaponObject || p.AttachedEntity== shooter.MainPed))
|
||||
if (shooter.MainPed!=null
|
||||
&& (p.AttachedEntity==shooter.MainPed.Weapons.CurrentWeaponObject
|
||||
|| p.AttachedEntity== shooter.MainPed))
|
||||
{
|
||||
// Reloading
|
||||
IsValid=false;
|
||||
return;
|
||||
}
|
||||
ShooterID=shooter.ID;
|
||||
Shooter=shooter;
|
||||
IsLocal=shooter.IsLocal;
|
||||
}
|
||||
|
||||
else if(EntityPool.VehiclesByHandle.TryGetValue(owner.Handle,out var shooterVeh))
|
||||
{
|
||||
Shooter=shooterVeh;
|
||||
IsLocal=shooterVeh.IsLocal;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsValid=false;
|
||||
}
|
||||
}
|
||||
public SyncedProjectile(int id)
|
||||
{
|
||||
ID= id;
|
||||
IsLocal=false;
|
||||
}
|
||||
public bool IsValid { get; private set; } = true;
|
||||
public new bool IsLocal { get; private set; } = false;
|
||||
public bool Exploded { get; set; } = false;
|
||||
public Projectile MainProjectile { get; set; }
|
||||
public int ShooterID { get; set; }
|
||||
private SyncedPed Shooter { get; set; }
|
||||
public Vector3 Origin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Invalid property for projectile.
|
||||
/// </summary>
|
||||
private new int OwnerID { set { } }
|
||||
public WeaponHash Hash { get; set; }
|
||||
private WeaponAsset Asset { get; set; }
|
||||
internal override void Update()
|
||||
{
|
||||
|
||||
@ -74,19 +108,20 @@ namespace RageCoop.Client
|
||||
|
||||
private void CreateProjectile()
|
||||
{
|
||||
Asset=new WeaponAsset(Hash);
|
||||
if (!Asset.IsLoaded) { Asset.Request(); }
|
||||
World.ShootBullet(Position, Position+Velocity, (Shooter=EntityPool.GetPedByID(ShooterID))?.MainPed, Asset, 0);
|
||||
Asset=new WeaponAsset(WeaponHash);
|
||||
if (!Asset.IsLoaded) { Asset.Request(); return; }
|
||||
if(Shooter == null) { return; }
|
||||
Entity owner;
|
||||
owner=(Shooter as SyncedPed)?.MainPed ?? (Entity)(Shooter as SyncedVehicle)?.MainVehicle;
|
||||
var end = Position+Velocity;
|
||||
Function.Call(Hash.SHOOT_SINGLE_BULLET_BETWEEN_COORDS_IGNORE_ENTITY, Position.X, Position.Y, Position.Z, end.X, end.Y, end.Z, 0, 1, WeaponHash, owner?.Handle ?? 0, 1, 0, -1,owner);
|
||||
var ps = World.GetAllProjectiles();
|
||||
MainProjectile=ps[ps.Length-1];
|
||||
if (Hash==(WeaponHash)VehicleWeaponHash.Tank)
|
||||
{
|
||||
var v = Shooter?.MainPed?.CurrentVehicle;
|
||||
if (v!=null)
|
||||
{
|
||||
World.CreateParticleEffectNonLooped(SyncEvents.CorePFXAsset, "muz_tank", v.Bones[v.GetMuzzleIndex()].Position, v.Bones[35].ForwardVector.ToEulerRotation(v.Bones[35].UpVector), 1);
|
||||
}
|
||||
}
|
||||
MainProjectile.IsCollisionEnabled=false;
|
||||
MainProjectile.Position=Position;
|
||||
MainProjectile.Rotation =Rotation;
|
||||
MainProjectile.Velocity=Velocity;
|
||||
Main.Delay(()=>MainProjectile.IsCollisionEnabled=true, 100);
|
||||
EntityPool.Add(this);
|
||||
}
|
||||
}
|
||||
|
@ -19,15 +19,15 @@ namespace RageCoop.Client
|
||||
#endif
|
||||
#region ACTIVE INSTANCES
|
||||
|
||||
private static Dictionary<int, SyncedPed> PedsByID = new Dictionary<int, SyncedPed>();
|
||||
private static Dictionary<int, SyncedPed> PedsByHandle = new Dictionary<int, SyncedPed>();
|
||||
public static Dictionary<int, SyncedPed> PedsByID = new Dictionary<int, SyncedPed>();
|
||||
public static Dictionary<int, SyncedPed> PedsByHandle = new Dictionary<int, SyncedPed>();
|
||||
|
||||
|
||||
private static Dictionary<int, SyncedVehicle> VehiclesByID = new Dictionary<int, SyncedVehicle>();
|
||||
private static Dictionary<int, SyncedVehicle> VehiclesByHandle = new Dictionary<int, SyncedVehicle>();
|
||||
public static Dictionary<int, SyncedVehicle> VehiclesByID = new Dictionary<int, SyncedVehicle>();
|
||||
public static Dictionary<int, SyncedVehicle> VehiclesByHandle = new Dictionary<int, SyncedVehicle>();
|
||||
|
||||
private static Dictionary<int, SyncedProjectile> ProjectilesByID = new Dictionary<int, SyncedProjectile>();
|
||||
private static Dictionary<int, SyncedProjectile> ProjectilesByHandle = new Dictionary<int, SyncedProjectile>();
|
||||
public static Dictionary<int, SyncedProjectile> ProjectilesByID = new Dictionary<int, SyncedProjectile>();
|
||||
public static Dictionary<int, SyncedProjectile> ProjectilesByHandle = new Dictionary<int, SyncedProjectile>();
|
||||
|
||||
public static Dictionary<int, SyncedProp> ServerProps = new Dictionary<int, SyncedProp>();
|
||||
public static Dictionary<int, Blip> ServerBlips = new Dictionary<int, Blip>();
|
||||
@ -62,7 +62,7 @@ namespace RageCoop.Client
|
||||
|
||||
foreach (var p in ProjectilesByID.Values)
|
||||
{
|
||||
if (p.ShooterID!=Main.LocalPlayerID && p.MainProjectile!=null && p.MainProjectile.Exists())
|
||||
if (p.Shooter.ID!=Main.LocalPlayerID && p.MainProjectile!=null && p.MainProjectile.Exists())
|
||||
{
|
||||
p.MainProjectile.Delete();
|
||||
}
|
||||
@ -242,6 +242,10 @@ namespace RageCoop.Client
|
||||
public static void Add(SyncedProjectile p)
|
||||
{
|
||||
if (!p.IsValid) { return; }
|
||||
if (p.WeaponHash==(WeaponHash)VehicleWeaponHash.Tank)
|
||||
{
|
||||
Networking.SendBullet(p.Position, p.Position+p.Velocity, (uint)VehicleWeaponHash.Tank, ((SyncedVehicle)p.Shooter).MainVehicle.Driver.GetSyncEntity().ID);
|
||||
}
|
||||
if (ProjectilesByID.ContainsKey(p.ID))
|
||||
{
|
||||
ProjectilesByID[p.ID]=p;
|
||||
@ -339,12 +343,10 @@ namespace RageCoop.Client
|
||||
if (p.MainProjectile.AttachedEntity==null)
|
||||
{
|
||||
// Prevent projectiles from exploding next to vehicle
|
||||
if (WeaponUtil.VehicleProjectileWeapons.Contains((VehicleWeaponHash)p.MainProjectile.WeaponHash) &&
|
||||
p.MainProjectile.WeaponHash != (WeaponHash)VehicleWeaponHash.Tank && p.Origin.DistanceTo(p.MainProjectile.Position) < 2)
|
||||
if (p.WeaponHash==(WeaponHash)VehicleWeaponHash.Tank )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Networking.SendProjectile(p);
|
||||
}
|
||||
}
|
||||
|
@ -305,6 +305,10 @@ namespace RageCoop.Core
|
||||
{
|
||||
return (flagToCheck & flag)!=0;
|
||||
}
|
||||
public static bool HasProjDataFlag(this ProjectileDataFlags flagToCheck, ProjectileDataFlags flag)
|
||||
{
|
||||
return (flagToCheck & flag)!=0;
|
||||
}
|
||||
|
||||
public static bool HasVehFlag(this VehicleDataFlags flagToCheck, VehicleDataFlags flag)
|
||||
{
|
||||
|
@ -97,6 +97,15 @@ namespace RageCoop.Core
|
||||
IsInCover = 1 << 10,
|
||||
IsFullSync = 1<<15 ,
|
||||
}
|
||||
|
||||
internal enum ProjectileDataFlags:byte
|
||||
{
|
||||
None = 0,
|
||||
Exploded = 1 << 0,
|
||||
IsAttached = 1 << 1,
|
||||
IsOrgin = 1 << 2,
|
||||
IsShotByVehicle = 1 << 3,
|
||||
}
|
||||
#region ===== VEHICLE DATA =====
|
||||
internal enum VehicleDataFlags:ushort
|
||||
{
|
||||
|
@ -22,7 +22,7 @@ namespace RageCoop.Core
|
||||
|
||||
public Vector3 Velocity { get; set; }
|
||||
|
||||
public bool Exploded { get; set; }
|
||||
public ProjectileDataFlags Flags { get; set; }
|
||||
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ namespace RageCoop.Core
|
||||
|
||||
// Write velocity
|
||||
byteArray.AddVector3(Velocity);
|
||||
byteArray.AddBool(Exploded);
|
||||
byteArray.Add((byte)Flags);
|
||||
|
||||
return byteArray.ToArray();
|
||||
|
||||
@ -76,7 +76,7 @@ namespace RageCoop.Core
|
||||
// Read velocity
|
||||
Velocity =reader.ReadVector3();
|
||||
|
||||
Exploded=reader.ReadBoolean();
|
||||
Flags=(ProjectileDataFlags)reader.ReadByte();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user