diff --git a/Assets/BossRoom/Scripts/Client/Game/Action/FXProjectileTargetedActionFX.cs b/Assets/BossRoom/Scripts/Client/Game/Action/FXProjectileTargetedActionFX.cs
index 68e56dd8f..0706399a7 100644
--- a/Assets/BossRoom/Scripts/Client/Game/Action/FXProjectileTargetedActionFX.cs
+++ b/Assets/BossRoom/Scripts/Client/Game/Action/FXProjectileTargetedActionFX.cs
@@ -28,17 +28,12 @@ public override bool Start()
bool wasAnticipated = Anticipated;
base.Start();
m_Target = GetTarget();
- if (HasTarget() && m_Target == null)
- {
- // target has disappeared! Abort.
- return false;
- }
if (Description.Projectiles.Length < 1 || Description.Projectiles[0].ProjectilePrefab == null)
throw new System.Exception($"Action {Description.ActionTypeEnum} has no valid ProjectileInfo!");
// animate shooting the projectile
- if( !wasAnticipated )
+ if (!wasAnticipated)
{
PlayFireAnim();
}
@@ -56,7 +51,7 @@ public override bool Update()
if (TimeRunning >= Description.ExecTimeSeconds && m_Projectile == null)
{
// figure out how long the pretend-projectile will be flying to the target
- Vector3 targetPos = HasTarget() ? m_Target.transform.position : m_Data.Position;
+ Vector3 targetPos = m_Target ? m_Target.transform.position : m_Data.Position;
float initialDistance = Vector3.Distance(targetPos, m_Parent.transform.position);
m_ProjectileDuration = initialDistance / Description.Projectiles[0].Speed_m_s;
@@ -100,14 +95,6 @@ private void PlayHitReact()
}
}
- ///
- /// Do we even have a target? (If false, it means player clicked on nothing, and we're rendering a "missed" fake bolt.)
- ///
- private bool HasTarget()
- {
- return Data.TargetIds != null && Data.TargetIds.Length > 0;
- }
-
private NetworkObject GetTarget()
{
if (Data.TargetIds == null || Data.TargetIds.Length == 0)
@@ -115,10 +102,16 @@ private NetworkObject GetTarget()
return null;
}
- NetworkObject obj;
- if (NetworkSpawnManager.SpawnedObjects.TryGetValue(Data.TargetIds[0], out obj) && obj != null)
+ if (NetworkSpawnManager.SpawnedObjects.TryGetValue(Data.TargetIds[0], out NetworkObject targetObject) && targetObject != null)
{
- return obj;
+ // make sure this isn't a friend (or if it is, make sure this is a friendly-fire action)
+ var targetable = targetObject.GetComponent();
+ if (targetable != null && targetable.IsNpc == (Description.IsFriendly ^ IsParentAnNPC()))
+ {
+ // not a valid target
+ return null;
+ }
+ return targetObject;
}
else
{
@@ -128,6 +121,16 @@ private NetworkObject GetTarget()
}
}
+ ///
+ /// Determines if the character playing this Action is an NPC (as opposed to a player)
+ ///
+ private bool IsParentAnNPC()
+ {
+ var targetable = m_Parent.Parent.GetComponent();
+ return targetable.IsNpc;
+ }
+
+
private FXProjectile SpawnAndInitializeProjectile()
{
GameObject projectileGO = Object.Instantiate(Description.Projectiles[0].ProjectilePrefab, m_Parent.transform.position, m_Parent.transform.rotation, null);
diff --git a/Assets/BossRoom/Scripts/Client/Game/Character/ClientInputSender.cs b/Assets/BossRoom/Scripts/Client/Game/Character/ClientInputSender.cs
index 22aeca15a..de7eaa04b 100644
--- a/Assets/BossRoom/Scripts/Client/Game/Character/ClientInputSender.cs
+++ b/Assets/BossRoom/Scripts/Client/Game/Character/ClientInputSender.cs
@@ -322,7 +322,7 @@ private void PopulateSkillRequest(Vector3 hitPoint, ActionType action, ref Actio
resultData.CancelMovement = true;
return;
case ActionLogic.RangedFXTargeted:
- if (resultData.TargetIds == null) { resultData.Position = hitPoint; }
+ resultData.Position = hitPoint;
return;
}
}
diff --git a/Assets/BossRoom/Scripts/Server/Game/Action/FXProjectileTargetedAction.cs b/Assets/BossRoom/Scripts/Server/Game/Action/FXProjectileTargetedAction.cs
index a4a26694d..838af5e54 100644
--- a/Assets/BossRoom/Scripts/Server/Game/Action/FXProjectileTargetedAction.cs
+++ b/Assets/BossRoom/Scripts/Server/Game/Action/FXProjectileTargetedAction.cs
@@ -22,14 +22,9 @@ public FXProjectileTargetedAction(ServerCharacter parent, ref ActionRequestData
public override bool Start()
{
m_Target = GetTarget();
- if (m_Target == null && HasTarget())
- {
- // target has disappeared! Abort.
- return false;
- }
// figure out where the player wants us to aim at...
- Vector3 targetPos = HasTarget() ? m_Target.transform.position : m_Data.Position;
+ Vector3 targetPos = m_Target != null ? m_Target.transform.position : m_Data.Position;
// then make sure we can actually see that point!
if (!ActionUtils.HasLineOfSight(m_Parent.transform.position, targetPos, out Vector3 collidePos))
@@ -76,14 +71,6 @@ public override void Cancel()
}
}
- ///
- /// Are we even supposed to have a target? (If not, we're representing a "missed" bolt that just hits nothing.)
- ///
- private bool HasTarget()
- {
- return Data.TargetIds != null && Data.TargetIds.Length > 0;
- }
-
///
/// Returns our intended target, or null if not found/no target.
///
@@ -97,6 +84,13 @@ private IDamageable GetTarget()
NetworkObject obj;
if (NetworkSpawnManager.SpawnedObjects.TryGetValue(Data.TargetIds[0], out obj) && obj != null)
{
+ // make sure this isn't a friend (or if it is, make sure this is a friendly-fire action)
+ var serverChar = obj.GetComponent();
+ if (serverChar && serverChar.IsNpc == (Description.IsFriendly ^ m_Parent.IsNpc))
+ {
+ // not a valid target
+ return null;
+ }
return obj.GetComponent();
}
else