Skip to content

Commit 9c89d73

Browse files
feature: homing and direct projectiles (AscensionGameDev#2263)
* adds the following options to projectile editor: - homing projectile shot - direct projectile shot - default (intersect legacy behavior)
1 parent 95dfa00 commit 9c89d73

15 files changed

Lines changed: 2861 additions & 805 deletions

File tree

Intersect (Core)/GameObjects/ProjectileBase.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ public string AnimationsJson
106106

107107
public int Range { get; set; } = 1;
108108

109+
public bool HomingBehavior { get; set; }
110+
111+
public bool DirectShotBehavior { get; set; }
112+
109113
[Column("SpawnLocations")]
110114
[JsonIgnore]
111115
public string SpawnsJson
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using MessagePack;
2+
3+
namespace Intersect.Network.Packets.Client;
4+
5+
[MessagePackObject]
6+
public partial class TargetPacket : IntersectPacket
7+
{
8+
//Parameterless Constructor for MessagePack
9+
public TargetPacket()
10+
{
11+
}
12+
13+
public TargetPacket(Guid targetId)
14+
{
15+
TargetId = targetId;
16+
}
17+
18+
[Key(0)]
19+
public Guid TargetId { get; set; }
20+
}

Intersect.Client/Entities/Animation.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ public partial class Animation : IAnimation
5454

5555
private long mUpperTimer;
5656

57+
private bool mUseExternalRotation;
58+
59+
private float mExternalRotation;
60+
5761
public AnimationBase MyBase { get; set; }
5862

5963
public Point Size => CalculateAnimationSize();
@@ -110,7 +114,13 @@ public void Draw(bool upper = false, bool alternate = false)
110114

111115
var rotationDegrees = 0f;
112116
var dontRotate = upper && MyBase.Upper.DisableRotations || !upper && MyBase.Lower.DisableRotations;
113-
if ((AutoRotate || mRenderDir != Direction.None) && !dontRotate)
117+
118+
if (mUseExternalRotation)
119+
{
120+
rotationDegrees = mExternalRotation;
121+
}
122+
123+
if ((AutoRotate || mRenderDir != Direction.None) && !dontRotate && !mUseExternalRotation)
114124
{
115125
switch (mRenderDir)
116126
{
@@ -465,6 +475,16 @@ public void SetDir(Direction dir)
465475
mRenderDir = dir;
466476
}
467477

478+
public void SetRotation(float angleInDegrees)
479+
{
480+
mUseExternalRotation = true;
481+
mExternalRotation = angleInDegrees;
482+
}
483+
484+
public void SetRotation(bool toggle)
485+
{
486+
mUseExternalRotation = toggle;
487+
}
468488
}
469489

470490
}

Intersect.Client/Entities/Player.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,7 @@ private void SetTargetBox(Entity en)
16371637
{
16381638
TargetBox?.SetEntity(null);
16391639
TargetBox?.Hide();
1640+
PacketSender.SendTarget(Guid.Empty);
16401641
return;
16411642
}
16421643

@@ -1654,6 +1655,7 @@ private void SetTargetBox(Entity en)
16541655
}
16551656

16561657
TargetBox?.Show();
1658+
PacketSender.SendTarget(en.Id);
16571659
}
16581660

16591661
private void AutoTurnToTarget(Entity en)

Intersect.Client/Entities/Projectiles/Projectile.cs

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System;
21
using Intersect.Client.Framework.Entities;
32
using Intersect.Client.General;
43
using Intersect.Enums;
@@ -41,6 +40,10 @@ public partial class Projectile : Entity
4140

4241
public Guid TargetId;
4342

43+
public int mLastTargetX = -1;
44+
45+
public int mLastTargetY = -1;
46+
4447
/// <summary>
4548
/// The constructor for the inherated projectile class
4649
/// </summary>
@@ -306,8 +309,34 @@ public override bool Update()
306309
{
307310
if (Spawns[s] != null && Maps.MapInstance.Get(Spawns[s].SpawnMapId) != null)
308311
{
309-
Spawns[s].OffsetX = GetRangeX(Spawns[s].Dir, GetDisplacement(Spawns[s].SpawnTime));
310-
Spawns[s].OffsetY = GetRangeY(Spawns[s].Dir, GetDisplacement(Spawns[s].SpawnTime));
312+
if (TargetId != Guid.Empty && Globals.Entities.ContainsKey(TargetId) && (mMyBase.HomingBehavior || mMyBase.DirectShotBehavior))
313+
{
314+
var target = Globals.Entities[TargetId];
315+
mLastTargetX = target.X;
316+
mLastTargetY = target.Y;
317+
318+
Spawns[s].OffsetX = GetProjectileX(Spawns[s], target.X, target.Y - Spawns[s].SpawnY);
319+
Spawns[s].OffsetY = GetProjectileY(Spawns[s], target.Y, target.X - Spawns[s].SpawnX);
320+
SetProjectileRotation(Spawns[s], target.X, target.Y);
321+
322+
if (mMyBase.DirectShotBehavior)
323+
{
324+
TargetId = Guid.Empty;
325+
}
326+
}
327+
else if(mLastTargetX != -1 && mLastTargetY != -1)
328+
{
329+
Spawns[s].OffsetX = GetProjectileX(Spawns[s], mLastTargetX, mLastTargetY - Spawns[s].SpawnY);
330+
Spawns[s].OffsetY = GetProjectileY(Spawns[s], mLastTargetY, mLastTargetX - Spawns[s].SpawnX);
331+
SetProjectileRotation(Spawns[s], mLastTargetX, mLastTargetY);
332+
}
333+
else
334+
{
335+
Spawns[s].OffsetX = GetRangeX(Spawns[s].Dir, GetDisplacement(Spawns[s].SpawnTime));
336+
Spawns[s].OffsetY = GetRangeY(Spawns[s].Dir, GetDisplacement(Spawns[s].SpawnTime));
337+
Spawns[s].Anim.SetRotation(false);
338+
}
339+
311340
Spawns[s]
312341
.Anim.SetPosition(
313342
Maps.MapInstance.Get(Spawns[s].SpawnMapId).GetX() +
@@ -333,6 +362,36 @@ public override bool Update()
333362
return true;
334363
}
335364

365+
private float GetProjectileX(ProjectileSpawns spawn, int targetX, float directionY)
366+
{
367+
float directionX = targetX - spawn.SpawnX;
368+
var length = (float)Math.Sqrt(directionX * directionX + directionY * directionY);
369+
directionX /= length;
370+
371+
var desiredX = GetDisplacement(spawn.SpawnTime) * directionX;
372+
var lerpFactor = 0.1f;
373+
return spawn.OffsetX + (desiredX - spawn.OffsetX) * lerpFactor;
374+
}
375+
376+
private float GetProjectileY(ProjectileSpawns spawn, int targetY, float directionX)
377+
{
378+
float directionY = targetY - spawn.SpawnY;
379+
var length = (float)Math.Sqrt(directionX * directionX + directionY * directionY);
380+
directionY /= length;
381+
382+
var desiredY = GetDisplacement(spawn.SpawnTime) * directionY;
383+
var lerpFactor = 0.1f;
384+
return spawn.OffsetY + (desiredY - spawn.OffsetY) * lerpFactor;
385+
}
386+
387+
private void SetProjectileRotation(ProjectileSpawns spawn, int targetX, int targetY)
388+
{
389+
var directionX = targetX - spawn.SpawnX;
390+
var directionY = targetY - spawn.SpawnY;
391+
var angle = (float)(Math.Atan2(directionY, directionX) * (180.0 / Math.PI) + 90);
392+
spawn.Anim.SetRotation(angle);
393+
}
394+
336395
public void CheckForCollision()
337396
{
338397
if (mSpawnCount != 0 || mQuantity < mMyBase.Quantity)

Intersect.Client/Networking/PacketSender.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,11 @@ public static void SendFadeCompletePacket()
498498
Network.SendPacket(new FadeCompletePacket());
499499
}
500500

501+
public static void SendTarget(Guid targetId)
502+
{
503+
Network.SendPacket(new TargetPacket(targetId));
504+
}
505+
501506
}
502507

503508
}

0 commit comments

Comments
 (0)