From 37a5c2654c40227440e77939475f624aadeb3fc3 Mon Sep 17 00:00:00 2001 From: Aristeas <94058548+Jnick-24@users.noreply.github.com> Date: Tue, 20 Feb 2024 17:51:42 -0600 Subject: [PATCH] FREE lasers --- .../HeartModule/Projectiles/Projectile.cs | 6 +- .../Projectiles/ProjectileManager.cs | 31 ++------ .../HeartModule/Weapons/SorterWeaponLogic.cs | 74 +++++++++++++++---- 3 files changed, 69 insertions(+), 42 deletions(-) diff --git a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/Projectile.cs b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/Projectile.cs index 61046f7b..ef823449 100644 --- a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/Projectile.cs +++ b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/Projectile.cs @@ -206,6 +206,9 @@ public void TickUpdate(float delta) if (MaxBeamLength == -1) MaxBeamLength = Definition.PhysicalProjectile.MaxTrajectory; } + + DrawUpdate(); + QueueDispose(); } if (MyAPIGateway.Session.IsServer) UpdateAudio(); @@ -296,8 +299,7 @@ public float CheckHits() } if (RemainingImpacts <= 0) - if (!IsHitscan) - QueueDispose(); + QueueDispose(); return (float)dist; } diff --git a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/ProjectileManager.cs b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/ProjectileManager.cs index 539b9aae..3adeaa1c 100644 --- a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/ProjectileManager.cs +++ b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/ProjectileManager.cs @@ -123,14 +123,11 @@ public void UpdateProjectileSync(n_SerializableProjectile projectile) } } - public Projectile AddProjectile(int projectileDefinitionId, Vector3D position, Vector3D direction, IMyConveyorSorter sorterWep) + public Projectile AddProjectile(int projectileDefinitionId, Vector3D position, Vector3D direction, IMyConveyorSorter sorterWep, bool shouldSync = true) { try { - if (ProjectileDefinitionManager.GetDefinition(projectileDefinitionId)?.PhysicalProjectile.IsHitscan ?? false) - return AddHitscanProjectile(projectileDefinitionId, position, direction, sorterWep.EntityId); - else - return AddProjectile(new Projectile(projectileDefinitionId, position, direction, sorterWep)); + return AddProjectile(new Projectile(projectileDefinitionId, position, direction, sorterWep), shouldSync); } catch (Exception ex) { @@ -139,14 +136,11 @@ public Projectile AddProjectile(int projectileDefinitionId, Vector3D position, V } } - public Projectile AddProjectile(int projectileDefinitionId, Vector3D position, Vector3D direction, long firer, Vector3D initialVelocity) + public Projectile AddProjectile(int projectileDefinitionId, Vector3D position, Vector3D direction, long firer, Vector3D initialVelocity, bool shouldSync = true) { try { - if (ProjectileDefinitionManager.GetDefinition(projectileDefinitionId)?.PhysicalProjectile.IsHitscan ?? false) - return AddHitscanProjectile(projectileDefinitionId, position, direction, firer); - else - return AddProjectile(new Projectile(projectileDefinitionId, position, direction, firer, initialVelocity)); + return AddProjectile(new Projectile(projectileDefinitionId, position, direction, firer, initialVelocity), shouldSync); } catch (Exception ex) { @@ -155,7 +149,7 @@ public Projectile AddProjectile(int projectileDefinitionId, Vector3D position, V } } - internal Projectile AddProjectile(Projectile projectile) + internal Projectile AddProjectile(Projectile projectile, bool shouldSync = true) { if (projectile == null || projectile.DefinitionId == -1) return null; // Ensure that invalid projectiles don't get added @@ -166,7 +160,7 @@ internal Projectile AddProjectile(Projectile projectile) NextId++; projectile.SetId(NextId); ActiveProjectiles.Add(projectile.Id, projectile); - if (MyAPIGateway.Session.IsServer) + if (MyAPIGateway.Session.IsServer && shouldSync) Network.QueueSync_PP(projectile, 0); if (!MyAPIGateway.Utilities.IsDedicated) projectile.InitEffects(); @@ -176,19 +170,6 @@ internal Projectile AddProjectile(Projectile projectile) } Dictionary HitscanList = new Dictionary(); - private Projectile AddHitscanProjectile(int projectileDefinitionId, Vector3D position, Vector3D direction, long firer) - { - if (!HitscanList.ContainsKey(firer)) - { - Projectile p = new Projectile(projectileDefinitionId, position, direction, firer); - AddProjectile(p); - p.OnClose += (projectile) => HitscanList.Remove(firer); - HitscanList.Add(firer, p.Id); - } - Projectile outProjectile = GetProjectile(HitscanList[firer]); - outProjectile?.UpdateHitscan(position, direction); - return outProjectile; - } public Projectile GetProjectile(uint id) => ActiveProjectiles.GetValueOrDefault(id, null); public bool IsIdAvailable(uint id) => !ActiveProjectiles.ContainsKey(id); diff --git a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Weapons/SorterWeaponLogic.cs b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Weapons/SorterWeaponLogic.cs index 7122508d..850781f4 100644 --- a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Weapons/SorterWeaponLogic.cs +++ b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Weapons/SorterWeaponLogic.cs @@ -1,6 +1,7 @@ using Heart_Module.Data.Scripts.HeartModule; using Heart_Module.Data.Scripts.HeartModule.ErrorHandler; using Heart_Module.Data.Scripts.HeartModule.Projectiles; +using Heart_Module.Data.Scripts.HeartModule.Projectiles.StandardClasses; using Heart_Module.Data.Scripts.HeartModule.ResourceSystem; using Heart_Module.Data.Scripts.HeartModule.Utility; using Heart_Module.Data.Scripts.HeartModule.Weapons; @@ -89,10 +90,10 @@ public override void UpdateOnceBeforeFrame() return; // ignore ghost/projected grids // the bonus part, enforcing it to stay a specific value. - if (MyAPIGateway.Multiplayer.IsServer) // serverside only to avoid network spam - { + //if (MyAPIGateway.Multiplayer.IsServer) // serverside only to avoid network spam + //{ NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME; - } + //} if (Definition.Assignments.HasMuzzleSubpart) // Get muzzle dummies ((IMyEntity)SubpartManager.RecursiveGetSubpart(SorterWep, Definition.Assignments.MuzzleSubpart))?.Model?.GetDummies(MuzzleDummies); @@ -203,6 +204,7 @@ public virtual void TryShoot() while (lastShoot >= 60 && Magazines.ShotsInMag > 0) // Allows for firerates higher than 60 rps { + ProjectileDefinitionBase ammoDef = ProjectileDefinitionManager.GetDefinition(Magazines.SelectedAmmo); for (int i = 0; i < Definition.Loading.BarrelsPerShot; i++) { nextBarrel++; @@ -213,19 +215,28 @@ public virtual void TryShoot() for (int j = 0; j < Definition.Loading.ProjectilesPerBarrel; j++) { - SorterWep.CubeGrid.Physics?.ApplyImpulse(muzzleMatrix.Backward * ProjectileDefinitionManager.GetDefinition(Magazines.SelectedAmmo).Ungrouped.Recoil, muzzleMatrix.Translation); - // Use the effectiveInaccuracy instead of the original ShotInaccuracy - Projectile newProjectile = ProjectileManager.I.AddProjectile(Magazines.SelectedAmmo, muzzlePos, RandomCone(muzzleMatrix.Forward, effectiveInaccuracy), SorterWep); - - if (newProjectile == null) // Emergency failsafe - return; - - if (newProjectile.Guidance != null) // Assign target for self-guided projectiles + if (MyAPIGateway.Session.IsServer) + { + SorterWep.CubeGrid.Physics?.ApplyImpulse(muzzleMatrix.Backward * ammoDef.Ungrouped.Recoil, muzzleMatrix.Translation); + // Use the effectiveInaccuracy instead of the original ShotInaccuracy + // Don't sync hitscan projectiles! + Projectile newProjectile = ProjectileManager.I.AddProjectile(Magazines.SelectedAmmo, muzzlePos, RandomCone(muzzleMatrix.Forward, effectiveInaccuracy), SorterWep, !ammoDef.PhysicalProjectile.IsHitscan); + + if (newProjectile == null) // Emergency failsafe + return; + + if (newProjectile.Guidance != null) // Assign target for self-guided projectiles + { + if (this is SorterTurretLogic) + newProjectile.Guidance.SetTarget(((SorterTurretLogic)this).TargetEntity); + else + newProjectile.Guidance.SetTarget(WeaponManagerAi.I.GetTargeting(SorterWep.CubeGrid)?.PrimaryGridTarget); + } + } + else { - if (this is SorterTurretLogic) - newProjectile.Guidance.SetTarget(((SorterTurretLogic)this).TargetEntity); - else - newProjectile.Guidance.SetTarget(WeaponManagerAi.I.GetTargeting(SorterWep.CubeGrid)?.PrimaryGridTarget); + if (ammoDef.PhysicalProjectile.IsHitscan) + DrawHitscanBeam(ammoDef); } } @@ -249,6 +260,39 @@ public virtual void TryShoot() } } + /// + /// Fakes a hitscan beam, to lower network load. + /// + /// + private void DrawHitscanBeam(ProjectileDefinitionBase beam) + { + List intersects = new List(); + Vector3D pos = MuzzleMatrix.Translation; + Vector3D end = MuzzleMatrix.Translation + MuzzleMatrix.Forward * beam.PhysicalProjectile.MaxTrajectory; + MyAPIGateway.Physics.CastRay(pos, end, intersects); + + if (intersects.Count > 0) + { + Vector3D hitPos = intersects[0].Position; + GlobalEffects.AddLine(pos, hitPos, beam.Visual.TrailFadeTime, beam.Visual.TrailWidth, beam.Visual.TrailColor, beam.Visual.TrailTexture); + + MatrixD matrix = MatrixD.CreateWorld(hitPos, (Vector3D) intersects[0].Normal, Vector3D.CalculatePerpendicularVector(intersects[0].Normal)); + MyParticleEffect hitEffect; + if (MyParticlesManager.TryCreateParticleEffect(beam.Visual.ImpactParticle, ref matrix, ref hitPos, uint.MaxValue, out hitEffect)) + { + //MyAPIGateway.Utilities.ShowNotification("Spawned particle at " + hitEffect.WorldMatrix.Translation); + //hitEffect.Velocity = av.Hit.HitVelocity; + + if (hitEffect.Loop) + hitEffect.Stop(); + } + } + else + { + GlobalEffects.AddLine(pos, end, beam.Visual.TrailFadeTime, beam.Visual.TrailWidth, beam.Visual.TrailColor, beam.Visual.TrailTexture); + } + } + public void MuzzleFlash(bool increment = false) // GROSS AND UGLY AND STUPID { if (Definition.Visuals.HasShootParticle && !HeartData.I.DegradedMode)