Skip to content

Commit

Permalink
Fully functional projectile PD!
Browse files Browse the repository at this point in the history
  • Loading branch information
ari-steas committed Feb 2, 2024
1 parent 296de40 commit 40fec44
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Heart_Module.Data.Scripts.HeartModule.ErrorHandler;
using Heart_Module.Data.Scripts.HeartModule.Debug;
using Heart_Module.Data.Scripts.HeartModule.ErrorHandler;
using Heart_Module.Data.Scripts.HeartModule.Projectiles.GuidanceHelpers;
using Heart_Module.Data.Scripts.HeartModule.Projectiles.StandardClasses;
using Sandbox.ModAPI;
Expand Down Expand Up @@ -76,6 +77,7 @@ public Projectile(n_SerializableProjectile projectile)
Definition = ProjectileDefinitionManager.GetDefinition(projectile.DefinitionId.Value);
Firer = projectile.Firer.GetValueOrDefault(0);
IsHitscan = Definition.PhysicalProjectile.IsHitscan;
Health = Definition.PhysicalProjectile.Health;
if (!IsHitscan)
Velocity = Definition.PhysicalProjectile.Velocity;
else
Expand Down Expand Up @@ -125,6 +127,7 @@ public Projectile(int DefinitionId, Vector3D Position, Vector3D Direction, IMyCu
Definition.PhysicalProjectile.MaxLifetime = 1 / 60f;

RemainingImpacts = Definition.Damage.MaxImpacts;
Health = Definition.PhysicalProjectile.Health;

if (Definition.Guidance.Length > 0)
Guidance = new ProjectileGuidance(this);
Expand Down Expand Up @@ -180,43 +183,13 @@ public float CheckHits(float delta)
if (NextMoveStep == Vector3D.Zero)
return -1;

//List<MyLineSegmentOverlapResult<MyEntity>> intersects = new List<MyLineSegmentOverlapResult<MyEntity>>();
List<IHitInfo> intersects = new List<IHitInfo>();
MyAPIGateway.Physics.CastRay(Position, NextMoveStep, intersects);

//LineD ray = new LineD(Position, NextMoveStep);
//MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref ray, intersects); // TODO: This is causing problems with hitting own grid

double len = IsHitscan ? Definition.PhysicalProjectile.MaxTrajectory : Vector3D.Distance(Position, NextMoveStep);
double dist = -1;

foreach (var hitInfo in intersects)
if (RemainingImpacts > 0 && Definition.Damage.DamageToProjectiles > 0)
{
if (RemainingImpacts <= 0)
break;

if (hitInfo.HitEntity.EntityId == Firer)
continue; // Skip firer

dist = hitInfo.Fraction * len;

if (hitInfo.HitEntity is IMyCubeGrid)
DamageHandler.QueueEvent(new DamageEvent(hitInfo.HitEntity, DamageEvent.DamageEntType.Grid, this, hitInfo.Position, hitInfo.Normal));
else if (hitInfo.HitEntity is IMyCharacter)
DamageHandler.QueueEvent(new DamageEvent(hitInfo.HitEntity, DamageEvent.DamageEntType.Character, this, hitInfo.Position, hitInfo.Normal));

if (MyAPIGateway.Session.IsServer)
PlayImpactAudio(hitInfo.Position); // Audio is global
if (!MyAPIGateway.Utilities.IsDedicated)
DrawImpactParticle(hitInfo.Position, hitInfo.Normal); // Visuals are clientside
MyAPIGateway.Utilities.ShowNotification("RemI " + RemainingImpacts);

Definition.LiveMethods.OnImpact?.Invoke(Id, hitInfo.Position, hitInfo.Normal, (MyEntity) hitInfo.HitEntity);

RemainingImpacts--;
}

if (RemainingImpacts <= 0 && Definition.Damage.DamageToProjectiles > 0)
{
List<Projectile> hittableProjectiles = new List<Projectile>();
ProjectileManager.I.GetProjectilesInSphere(new BoundingSphereD(Position, len), ref hittableProjectiles, true);

Expand All @@ -228,18 +201,28 @@ public float CheckHits(float delta)

foreach (var projectile in hittableProjectiles)
{
if (RemainingImpacts <= 0 && projectile == this)
if (RemainingImpacts <= 0 || projectile == this)
continue;

Vector3D offset = Vector3D.Half * projectile.Definition.PhysicalProjectile.ProjectileSize;
BoundingBoxD box = new BoundingBoxD(projectile.Position - offset, projectile.Position + offset);

if (ray.Intersects(box) != null)
double? intersectDist = ray.Intersects(box);
if (intersectDist != null)
{
dist = intersectDist.Value;
projectile.Health -= Definition.Damage.DamageToProjectiles;

damageToProjectilesInAoE += Definition.Damage.DamageToProjectiles;

Vector3D hitPos = Position + Direction * dist;

if (MyAPIGateway.Session.IsServer)
PlayImpactAudio(hitPos); // Audio is global
if (!MyAPIGateway.Utilities.IsDedicated)
DrawImpactParticle(hitPos, Direction); // Visuals are clientside

Definition.LiveMethods.OnImpact?.Invoke(Id, hitPos, Direction, null);

RemainingImpacts--;
}
}
Expand All @@ -248,8 +231,41 @@ public float CheckHits(float delta)
foreach (var projectile in projectilesInAoE)
if (projectile != this)
projectile.Health -= damageToProjectilesInAoE;
}

if (RemainingImpacts > 0)
{
//List<MyLineSegmentOverlapResult<MyEntity>> intersects = new List<MyLineSegmentOverlapResult<MyEntity>>();
List<IHitInfo> intersects = new List<IHitInfo>();
MyAPIGateway.Physics.CastRay(Position, NextMoveStep, intersects);

//LineD ray = new LineD(Position, NextMoveStep);
//MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref ray, intersects); // TODO: This is causing problems with hitting own grid

foreach (var hitInfo in intersects)
{
if (RemainingImpacts <= 0)
break;

MyAPIGateway.Utilities.ShowNotification("Damaged " + projectilesInAoE.Count);
if (hitInfo.HitEntity.EntityId == Firer)
continue; // Skip firer

dist = hitInfo.Fraction * len;

if (hitInfo.HitEntity is IMyCubeGrid)
DamageHandler.QueueEvent(new DamageEvent(hitInfo.HitEntity, DamageEvent.DamageEntType.Grid, this, hitInfo.Position, hitInfo.Normal));
else if (hitInfo.HitEntity is IMyCharacter)
DamageHandler.QueueEvent(new DamageEvent(hitInfo.HitEntity, DamageEvent.DamageEntType.Character, this, hitInfo.Position, hitInfo.Normal));

if (MyAPIGateway.Session.IsServer)
PlayImpactAudio(hitInfo.Position); // Audio is global
if (!MyAPIGateway.Utilities.IsDedicated)
DrawImpactParticle(hitInfo.Position, hitInfo.Normal); // Visuals are clientside

Definition.LiveMethods.OnImpact?.Invoke(Id, hitInfo.Position, hitInfo.Normal, (MyEntity)hitInfo.HitEntity);

RemainingImpacts--;
}
}

if (RemainingImpacts <= 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ public override void UpdateAfterSimulation()
if (ProjectilesWithHealth.Contains(projectile))
ProjectilesWithHealth.Remove(projectile);
projectile.OnClose.Invoke(projectile);
if (projectile.Health < 0)
MyAPIGateway.Utilities.ShowNotification(projectile.Id + "");
}
QueuedCloseProjectiles.Clear();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ partial class HeartDefinitions
AreaDamage = 0,
AreaRadius = 0,
MaxImpacts = 1,
DamageToProjectiles = 10,
DamageToProjectilesRadius = 10,
DamageToProjectiles = 0.2f,
DamageToProjectilesRadius = 0.2f,
},
PhysicalProjectile = new PhysicalProjectile()
{
Expand Down Expand Up @@ -114,7 +114,7 @@ partial class HeartDefinitions
},
PhysicalProjectile = new PhysicalProjectile()
{
Velocity = 10,
Velocity = 800,
Acceleration = 1,
Health = 1,
MaxTrajectory = 4000,
Expand All @@ -124,13 +124,13 @@ partial class HeartDefinitions
},
Visual = new Visual()
{
//Model = "Models\\Weapons\\Projectile_Missile.mwm",
TrailTexture = MyStringId.GetOrCompute("WeaponLaser"),
TrailFadeTime = 0f,
TrailLength = 8,
TrailWidth = 0.5f,
TrailColor = new VRageMath.Vector4(61, 24, 24, 200),
//AttachedParticle = "Smoke_Missile",
Model = "Models\\Weapons\\Projectile_Missile.mwm",
//TrailTexture = MyStringId.GetOrCompute("WeaponLaser"),
//TrailFadeTime = 0f,
//TrailLength = 8,
//TrailWidth = 0.5f,
//TrailColor = new VRageMath.Vector4(61, 24, 24, 200),
AttachedParticle = "Smoke_Missile",
ImpactParticle = "MaterialHit_Metal",
VisibleChance = 1f,
},
Expand Down

0 comments on commit 40fec44

Please sign in to comment.