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.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 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.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 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; } } }