Skip to content

Commit

Permalink
Disable ray hit events when entities can't be damaged
Browse files Browse the repository at this point in the history
This is a Harmony patch on `ItemActionDynamic.hitTarget` to disable the firing of "onSelf[Primary|Secondary]Action[Ray|Graze]Hit" events if the holding entity can't damage the target entity.

This is the cause of the stun baton "shock" issue with friendly NPCs. The stun baton itself wasn't hitting or doing damage, but the baton was still charging, and when fully charged, it still shocked the friendly NPC.

I also refactored the logic to determine when an entity should use faction targeting. It was already repeated in two places in the code, and I would need to repeat it a third time in my patch.

I did test to make sure that there were no regressions. I tested with a friendly NPC (Baker), and enemy NPC (Harley), and animal (bear), and zombies (mainly Boe). I made sure that I could still shock everyone except the Baker, and that when they attacked each other, they did damage.
  • Loading branch information
kgiesing committed Sep 28, 2024
1 parent b7a62ad commit 362c8b7
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 29 deletions.
18 changes: 3 additions & 15 deletions Mods/0-SCore/Harmony/EAI/EAITarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,9 @@ public static void Postfix(ref bool __result, EAITarget __instance, global::Enti
return;
}

// allow an override for the action stuff. If its set here, then use faction targeting.
if (!EntityUtilities.CheckProperty(__instance.theEntity.entityId, "AllEntitiesUseFactionTargeting"))
{
// This patches the check for all entities, so if we're not supposed to use faction
// targeting for everything, stop now. Otherwise, do the faction check.
if (!Configuration.CheckFeatureStatus("AdvancedNPCFeatures", "AllEntitiesUseFactionTargeting"))
{
// Even if *all* entities don't use faction targeting, this entity still should
// if it has one of the UseFactions tags. Only stop now if it doesn't.
if (!EntityUtilities.UseFactions(__instance.theEntity))
{
return;
}
}
}
if (!EntityUtilities.UseFactionTargeting(__instance.theEntity))
return;

var myRelationship = FactionManager.Instance.GetRelationshipTier(__instance.theEntity, _e);
switch (myRelationship)
{
Expand Down
38 changes: 24 additions & 14 deletions Mods/0-SCore/Harmony/NPCFeatures/EntityAlivePatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,9 @@ public class EntityAliveDamageEntity
{
private static bool Prefix(global::EntityAlive __instance, ref int __result, DamageSource _damageSource)
{
if (!EntityUtilities.UseFactionTargeting(__instance))
return true;

// allow an override for the action stuff. If its set here, then use faction targeting.
if (!EntityUtilities.CheckProperty(__instance.entityId, "AllEntitiesUseFactionTargeting"))
{
// New feature flag, specific to this feature.
if (!Configuration.CheckFeatureStatus(AdvFeatureClass, "AllEntitiesUseFactionTargeting"))
{
// Even if *all* entities don't use faction damage rules, this entity should
// if it has one of the UseFactions tags. Only stop now if it doesn't.
if (!EntityUtilities.UseFactions(__instance))
{
return true;
}
}
}
if (_damageSource.damageType == EnumDamageTypes.Suicide)
return true;

Expand Down Expand Up @@ -132,6 +120,28 @@ private static bool Prefix(
}
}

/// <summary>
/// Harmony patch to disable the firing of "onSelf[Primary/Secondary]Action[Ray/Graze]Hit"
/// events if the holding entity can't damage the target entity.
/// </summary>
[HarmonyPatch(typeof(ItemActionDynamic))]
[HarmonyPatch(nameof(ItemActionDynamic.hitTarget))]
public class ItemActionDynamicHitTarget
{
private static bool Prefix(
ItemActionDynamic __instance,
ItemActionData _actionData,
WorldRayHitInfo hitInfo)
{
if (!EntityUtilities.UseFactionTargeting(_actionData.invData.holdingEntity))
return true;

return EntityTargetingUtilities.CanDamage(
_actionData.invData.holdingEntity,
ItemActionAttack.GetEntityFromHit(hitInfo));
}
}

[HarmonyPatch(typeof(global::EntityAlive))]
[HarmonyPatch("SetAttackTarget")]
public class EntityAliveSetAttackTarget
Expand Down
20 changes: 20 additions & 0 deletions Mods/0-SCore/Scripts/Entities/EntityUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,26 @@ public static bool UseFactions(EntityAlive entity)
return false;
}

/// <summary>
/// Returns true if this entity should use faction targeting, according to feature settings,
/// entity properties, or entity tags.
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public static bool UseFactionTargeting(EntityAlive entity)
{
return
// allow an override for the action stuff. If its set here, then use faction targeting.
CheckProperty(entity.entityId, "AllEntitiesUseFactionTargeting") ||

// New feature flag, specific to this feature.
Configuration.CheckFeatureStatus(AdvFeatureClass, "AllEntitiesUseFactionTargeting") ||

// Even if *all* entities don't use faction targeting rules, this entity should if it has
// one of the UseFactions tags.
UseFactions(entity);
}

public static void AddBuffToRadius(string strBuff, Vector3 position, int Radius)
{
// If there's no radius, pick 30 blocks.
Expand Down

0 comments on commit 362c8b7

Please sign in to comment.