Files
zzz_REBIRTH__Utils/Harmony/Harmony_MiniTurretFireController.cs
2025-06-04 16:44:53 +09:30

363 lines
20 KiB
C#

using Audio;
namespace Harmony.MiniTurretFireControllerPatches
{
[HarmonyPatch(typeof(MiniTurretFireController))]
[HarmonyPatch("shouldIgnoreTarget")]
public class shouldIgnoreTargetPatch
{
public static bool Prefix(MiniTurretFireController __instance, ref bool __result, Entity _target)
{
if (_target == null)
{
__result = true;
return false;
}
if (!_target.IsAlive())
{
__result = true;
return false;
}
if (_target.entityId == __instance.entityTurret.entityId)
{
__result = true;
return false;
}
bool shouldAttack = RebirthUtilities.VerifyFactionStanding(__instance.entityTurret, (EntityAlive)_target);
//Log.Out("MiniTurretFireControllerPatches-shouldIgnoreTarget shouldAttack: " + shouldAttack);
if (!shouldAttack)
{
__result = true;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(MiniTurretFireController))]
[HarmonyPatch("Update")]
public class UpdatePatch
{
//public static MethodInfo trackTarget = AccessTools.Method(typeof(MiniTurretFireController), "trackTarget", new Type[] { typeof(Entity), typeof(float), typeof(float), typeof(Vector3) });
private static bool trackTarget(Entity _target, ref float _yaw, ref float _pitch, out Vector3 _targetPos,
MiniTurretFireController __instance,
Vector2 ___pitchRange,
Vector2 ___yawRange,
float ___targetChestHeadPercent
)
{
_targetPos = Vector3.Lerp(_target.getChestPosition(), _target.getHeadPosition(), ___targetChestHeadPercent) - Origin.position;
Vector3 position = __instance.transform.position;
if (__instance.Laser != null)
{
position = __instance.Laser.transform.position;
}
Vector3 eulerAngles = Quaternion.LookRotation((_targetPos - position).normalized).eulerAngles;
float num = Mathf.DeltaAngle(__instance.entityTurret.transform.rotation.eulerAngles.y, eulerAngles.y);
float num2 = eulerAngles.x;
if (num2 > 180f)
{
num2 -= 360f;
}
float num3 = __instance.CenteredYaw % 360f;
float num4 = __instance.CenteredPitch % 360f;
if (num3 > 180f)
{
num3 -= 360f;
}
if (num4 > 180f)
{
num4 -= 360f;
}
if (num < num3 + ___yawRange.x || num > num3 + ___yawRange.y || num2 < num4 + ___pitchRange.x || num2 > num4 + ___pitchRange.y)
{
return false;
}
_yaw = num;
_pitch = num2;
return true;
}
public static MethodInfo shouldIgnoreTarget = AccessTools.Method(typeof(MiniTurretFireController), "shouldIgnoreTarget", new Type[] { typeof(Entity) });
public static MethodInfo findTarget = AccessTools.Method(typeof(MiniTurretFireController), "findTarget", new Type[] { });
public static MethodInfo updateLaser = AccessTools.Method(typeof(MiniTurretFireController), "updateLaser", new Type[] { });
private static bool Prefix(MiniTurretFireController __instance,
ref Handle ___turretSpinAudioHandle,
ref global::EntityAlive ___currentEntityTarget,
ref float ___targetChestHeadDelay,
ref float ___targetChestHeadPercent,
ref float ___burstFireRate,
ref float ___burstFireRateMax,
ref Vector2 ___yawRange,
float ___maxDistance,
MiniTurretFireController.TurretEntitySorter ___sorter,
string ___targetingSound,
Vector2 ___pitchRange
)
{
if (__instance.entityTurret == null)
{
return false;
}
if (!__instance.entityTurret.IsOn)
{
if (__instance.entityTurret.YawController.Yaw != __instance.CenteredYaw)
{
__instance.entityTurret.YawController.Yaw = __instance.CenteredYaw;
}
if (__instance.entityTurret.PitchController.Pitch != __instance.CenteredPitch + 35f)
{
__instance.entityTurret.PitchController.Pitch = __instance.CenteredPitch + 35f;
}
if (___turretSpinAudioHandle != null)
{
___turretSpinAudioHandle.Stop(__instance.entityTurret.entityId);
___turretSpinAudioHandle = null;
}
__instance.entityTurret.YawController.UpdateYaw();
__instance.entityTurret.PitchController.UpdatePitch();
return false;
}
if (SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer)
{
if (!__instance.hasTarget)
{
findTarget.Invoke(__instance, new object[] { });
}
else if ((bool)shouldIgnoreTarget.Invoke(__instance, new object[] { ___currentEntityTarget }))
{
___currentEntityTarget = null;
__instance.entityTurret.TargetEntityId = -1;
}
}
else if (__instance.entityTurret.TargetEntityId != -1)
{
___currentEntityTarget = (GameManager.Instance.World.GetEntity(__instance.entityTurret.TargetEntityId) as global::EntityAlive);
if (___currentEntityTarget == null || ___currentEntityTarget.IsDead())
{
___currentEntityTarget = null;
__instance.entityTurret.TargetEntityId = -1;
}
}
else
{
___currentEntityTarget = null;
__instance.entityTurret.TargetEntityId = -1;
}
if (__instance.entityTurret.IsTurning)
{
if (___turretSpinAudioHandle == null)
{
___turretSpinAudioHandle = Manager.Play(__instance.entityTurret, ___targetingSound, 1f, true);
}
}
else if (___turretSpinAudioHandle != null)
{
___turretSpinAudioHandle.Stop(__instance.entityTurret.entityId);
___turretSpinAudioHandle = null;
}
___targetChestHeadDelay -= Time.deltaTime;
if (___targetChestHeadDelay <= 0f)
{
___targetChestHeadDelay = 1f;
___targetChestHeadPercent = __instance.entityTurret.rand.RandomFloat;
}
___burstFireRate += Time.deltaTime;
if (__instance.hasTarget)
{
__instance.entityTurret.YawController.IdleScan = false;
float yaw = __instance.entityTurret.YawController.Yaw;
float pitch = __instance.entityTurret.PitchController.Pitch;
Vector3 vector;
if (trackTarget(___currentEntityTarget, ref yaw, ref pitch, out vector,
__instance,
___pitchRange,
___yawRange,
___targetChestHeadPercent
))
{
__instance.entityTurret.YawController.Yaw = yaw;
__instance.entityTurret.PitchController.Pitch = pitch;
global::EntityAlive entity = GameManager.Instance.World.GetEntity(__instance.entityTurret.belongsPlayerId) as global::EntityAlive;
FastTags<TagGroup.Global> tags = __instance.entityTurret.OriginalItemValue.ItemClass.ItemTags | __instance.entityTurret.EntityClass.Tags;
ItemValue itemValue = __instance.entityTurret.OriginalItemValue;
global::EntityAlive myOwner = GameManager.Instance.World.GetEntity(__instance.entityTurret.belongsPlayerId) as global::EntityAlive;
//Log.Out("MiniTurretFireControllerPatches-Update entityClassName: " + __instance.entityTurret.EntityClass.entityClassName);
if (__instance.entityTurret.EntityClass.entityClassName != "junkTurretGun" && __instance.entityTurret.EntityClass.entityClassName != "junkTurretSledge")
{
ItemValue getItemValue = null;
if (myOwner != null)
{
//Log.Out("JunkSledgeFireControllerPatches-Update A myOwner: " + myOwner.EntityClass.entityClassName);
getItemValue = RebirthUtilities.GetItemValue(myOwner, "JunkTurret", __instance.entityTurret.EntityClass.entityClassName);
}
else
{
//Log.Out("JunkSledgeFireControllerPatches-Update A myOwner == null");
}
if (getItemValue != null)
{
itemValue = getItemValue;
}
}
//Log.Out("MiniTurretFireControllerPatches-Update ___burstFireRateMax (BEFORE): " + ___burstFireRateMax);
//___burstFireRateMax = 60f / (EffectManager.GetValue(PassiveEffects.RoundsPerMinute, itemValue, ___burstFireRateMax, entity, null, tags, true, false, true, true, true, 1) + 1E-05f);
___burstFireRateMax = 60f / EffectManager.GetValue(PassiveEffects.RoundsPerMinute, itemValue, ___burstFireRateMax, entity);
//Log.Out("MiniTurretFireControllerPatches-Update ___burstFireRateMax (AFTER): " + ___burstFireRateMax);
if (___burstFireRate >= ___burstFireRateMax)
{
__instance.Fire();
___burstFireRate = 0f;
}
}
}
else
{
if (!__instance.entityTurret.YawController.IdleScan || (__instance.entityTurret.YawController.Yaw != ___yawRange.y && __instance.entityTurret.YawController.Yaw != ___yawRange.x))
{
__instance.entityTurret.YawController.IdleScan = true;
__instance.entityTurret.YawController.Yaw = ___yawRange.y;
}
float num = (___yawRange.y > 0f) ? ___yawRange.y : (360f + ___yawRange.y);
float num2 = (___yawRange.x > 0f) ? ___yawRange.x : (360f + ___yawRange.x);
if (Mathf.Abs(__instance.entityTurret.YawController.CurrentYaw - num) < 1f || Mathf.Abs(__instance.entityTurret.YawController.CurrentYaw - ___yawRange.y) < 1f)
{
__instance.entityTurret.YawController.Yaw = ___yawRange.x;
}
else if (Mathf.Abs(__instance.entityTurret.YawController.CurrentYaw - num2) < 1f || Mathf.Abs(__instance.entityTurret.YawController.CurrentYaw - ___yawRange.x) < 1f)
{
__instance.entityTurret.YawController.Yaw = ___yawRange.y;
}
__instance.entityTurret.PitchController.Pitch = __instance.CenteredPitch;
}
__instance.entityTurret.YawController.UpdateYaw();
__instance.entityTurret.PitchController.UpdatePitch();
if (__instance.Laser != null)
{
updateLaser.Invoke(__instance, new object[] { });
}
return false;
}
}
[HarmonyPatch(typeof(MiniTurretFireController))]
[HarmonyPatch("Fire")]
public class FirePatch
{
private static bool Prefix(MiniTurretFireController __instance)
{
//Log.Out("MiniTurretFireControllerPatches-Fire __instance.ammoItemName: " + ___ammoItemName);
//Log.Out("MiniTurretFireControllerPatches-Fire START");
//Log.Out("MiniTurretFireControllerPatches-Fire EntityName: " + __instance.entityTurret.EntityName);
if (!SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer || (UnityEngine.Object)__instance.entityTurret == (UnityEngine.Object)null || !__instance.entityTurret.IsOn)
{
//Log.Out("MiniTurretFireControllerPatches-Fire 1");
return false;
}
Vector3 position = __instance.Laser.transform.position;
EntityAlive entity = GameManager.Instance.World.GetEntity(__instance.entityTurret.belongsPlayerId) as EntityAlive;
GameRandom gameRandom = GameManager.Instance.World.GetGameRandom();
FastTags<TagGroup.Global> itemTags = __instance.entityTurret.OriginalItemValue.ItemClass.ItemTags;
int num1 = (int)EffectManager.GetValue(PassiveEffects.RoundRayCount, __instance.entityTurret.OriginalItemValue, (float)__instance.rayCount, entity, tags: __instance.entityTurret.OriginalItemValue.ItemClass.ItemTags, calcHoldingItem: false);
__instance.maxDistance = EffectManager.GetValue(PassiveEffects.MaxRange, __instance.entityTurret.OriginalItemValue, __instance.MaxDistance, entity, tags: __instance.entityTurret.OriginalItemValue.ItemClass.ItemTags, calcHoldingItem: false);
for (int index1 = 0; index1 < num1; ++index1)
{
Vector3 forward = __instance.Muzzle.transform.forward;
__instance.spreadHorizontal.x = (float)-((double)EffectManager.GetValue(PassiveEffects.SpreadDegreesHorizontal, __instance.entityTurret.OriginalItemValue, 22f, entity, tags: __instance.entityTurret.OriginalItemValue.ItemClass.ItemTags, calcHoldingItem: false) * 0.5);
__instance.spreadHorizontal.y = EffectManager.GetValue(PassiveEffects.SpreadDegreesHorizontal, __instance.entityTurret.OriginalItemValue, 22f, entity, tags: __instance.entityTurret.OriginalItemValue.ItemClass.ItemTags, calcHoldingItem: false) * 0.5f;
__instance.spreadVertical.x = (float)-((double)EffectManager.GetValue(PassiveEffects.SpreadDegreesVertical, __instance.entityTurret.OriginalItemValue, 22f, entity, tags: __instance.entityTurret.OriginalItemValue.ItemClass.ItemTags, calcHoldingItem: false) * 0.5);
__instance.spreadVertical.y = EffectManager.GetValue(PassiveEffects.SpreadDegreesVertical, __instance.entityTurret.OriginalItemValue, 22f, entity, tags: __instance.entityTurret.OriginalItemValue.ItemClass.ItemTags, calcHoldingItem: false) * 0.5f;
Vector3 direction = Quaternion.Euler(gameRandom.RandomRange(__instance.spreadHorizontal.x, __instance.spreadHorizontal.y), gameRandom.RandomRange(__instance.spreadVertical.x, __instance.spreadVertical.y), 0.0f) * forward;
Ray ray = new Ray(position + Origin.position, direction);
__instance.waterCollisionParticles.Reset();
__instance.waterCollisionParticles.CheckCollision(ray.origin, ray.direction, __instance.maxDistance);
int num2 = Mathf.FloorToInt(EffectManager.GetValue(PassiveEffects.EntityPenetrationCount, __instance.entityTurret.OriginalItemValue, _entity: entity, tags: __instance.entityTurret.OriginalItemValue.ItemClass.ItemTags, calcHoldingItem: false)) + 1;
int num3 = Mathf.FloorToInt(EffectManager.GetValue(PassiveEffects.BlockPenetrationFactor, __instance.entityTurret.OriginalItemValue, 1f, entity, tags: __instance.entityTurret.OriginalItemValue.ItemClass.ItemTags, calcHoldingItem: false));
EntityAlive entityAlive = (EntityAlive)null;
for (int index2 = 0; index2 < num2; ++index2)
{
if (Voxel.Raycast(GameManager.Instance.World, ray, __instance.maxDistance, -538750981, 8, 0.0f))
{
WorldRayHitInfo hitInfo = Voxel.voxelRayHitInfo.Clone();
if (hitInfo.tag.StartsWith("E_"))
{
EntityAlive entityNoTagCheck = ItemActionAttack.FindHitEntityNoTagCheck(hitInfo, out string _) as EntityAlive;
if ((UnityEngine.Object)entityAlive == (UnityEngine.Object)entityNoTagCheck)
{
ray.origin = hitInfo.hit.pos + ray.direction * 0.1f;
--index2;
continue;
}
entityAlive = entityNoTagCheck;
}
else
{
BlockValue blockHit = ItemActionAttack.GetBlockHit(GameManager.Instance.World, hitInfo);
index2 += Mathf.FloorToInt((float)blockHit.Block.MaxDamage / (float)num3);
}
ItemValue itemValue = __instance.entityTurret.OriginalItemValue;
//Log.Out("MiniTurretFireControllerPatches-Fire itemValue (BEFORE): " + itemValue.ItemClass.GetItemName());
global::EntityAlive myOwner = GameManager.Instance.World.GetEntity(__instance.entityTurret.belongsPlayerId) as global::EntityAlive;
ItemValue getItemValue = null;
if (myOwner != null)
{
//Log.Out("JunkSledgeFireControllerPatches-Update B myOwner: " + myOwner.EntityClass.entityClassName);
getItemValue = RebirthUtilities.GetItemValue(myOwner, "JunkTurret", __instance.entityTurret.EntityClass.entityClassName);
}
else
{
//Log.Out("JunkSledgeFireControllerPatches-Update B myOwner == null");
}
if (getItemValue != null)
{
itemValue = getItemValue;
}
//Log.Out("MiniTurretFireControllerPatches-Fire itemValue (AFTER): " + itemValue.ItemClass.GetItemName());
ItemActionAttack.Hit(hitInfo, __instance.entityTurret.belongsPlayerId, EnumDamageTypes.Piercing, __instance.GetDamageBlock(__instance.entityTurret.OriginalItemValue, BlockValue.Air, GameManager.Instance.World.GetEntity(__instance.entityTurret.belongsPlayerId) as EntityAlive, 1), __instance.GetDamageEntity(__instance.entityTurret.OriginalItemValue, GameManager.Instance.World.GetEntity(__instance.entityTurret.belongsPlayerId) as EntityAlive, 1), 1f, __instance.entityTurret.OriginalItemValue.PercentUsesLeft, 0.0f, 0.0f, "bullet", __instance.damageMultiplier, __instance.buffActions, new ItemActionAttack.AttackHitInfo(), ownedEntityId: __instance.entityTurret.entityId, damagingItemValue: __instance.entityTurret.OriginalItemValue);
}
}
}
if (!string.IsNullOrEmpty(__instance.muzzleFireParticle))
FireControllerUtils.SpawnParticleEffect(new ParticleEffect(__instance.muzzleFireParticle, __instance.Muzzle.position + Origin.position, __instance.Muzzle.rotation, 1f, Color.white, __instance.fireSound, (Transform)null), -1);
if (!string.IsNullOrEmpty(__instance.muzzleSmokeParticle))
{
float _lightValue = GameManager.Instance.World.GetLightBrightness(World.worldToBlockPos(__instance.TurretPosition)) / 2f;
FireControllerUtils.SpawnParticleEffect(new ParticleEffect(__instance.muzzleSmokeParticle, __instance.Muzzle.position + Origin.position, __instance.Muzzle.rotation, _lightValue, new Color(1f, 1f, 1f, 0.3f), (string)null, (Transform)null), -1);
}
++__instance.burstRoundCount;
if ((int)EffectManager.GetValue(PassiveEffects.MagazineSize, __instance.entityTurret.OriginalItemValue) > 0)
--__instance.entityTurret.AmmoCount;
__instance.entityTurret.OriginalItemValue.UseTimes += EffectManager.GetValue(PassiveEffects.DegradationPerUse, __instance.entityTurret.OriginalItemValue, 1f, entity, tags: __instance.entityTurret.OriginalItemValue.ItemClass.ItemTags, calcHoldingItem: false);
return false;
}
}
}