using System.Collections.Generic; using Twitch; namespace Harmony.ExplosionPatches { [HarmonyPatch(typeof(Explosion))] [HarmonyPatch("AttackEntites")] public class AttackEntitesPatch { public static bool Prefix(Explosion __instance, int _entityThatCausedExplosion, ItemValue _itemValueExplosionSource, EnumDamageTypes damageType) { EntityAlive entity1 = __instance.world.GetEntity(_entityThatCausedExplosion) as EntityAlive; FastTags explosionTag = Explosion.explosionTag; if (_itemValueExplosionSource != null) { ItemClass itemClass = _itemValueExplosionSource.ItemClass; explosionTag |= itemClass.ItemTags; } float num1 = EffectManager.GetValue(PassiveEffects.ExplosionEntityDamage, _itemValueExplosionSource, __instance.explosionData.EntityDamage, entity1, tags: explosionTag); float radius = EffectManager.GetValue(PassiveEffects.ExplosionRadius, _itemValueExplosionSource, (float)__instance.explosionData.EntityRadius, entity1, tags: explosionTag); Collider[] colliderArray = Physics.OverlapSphere(__instance.worldPos - Origin.position, radius, -538480645); bool flag1 = false; Vector3i blockPos = World.worldToBlockPos(__instance.worldPos); foreach (Collider collider in colliderArray) { if ((bool)collider) { Transform transform = collider.transform; if (transform.CompareTag("Item")) { EntityItem component1 = transform.GetComponent(); if (!(bool)component1) { RootTransformRefEntity component2 = transform.GetComponent(); if ((bool)component2) component1 = component2.RootTransform.GetComponent(); } if ((bool)component1 && !component1.IsDead() && !Explosion.hitEntities.ContainsKey(component1.entityId)) { Explosion.hitEntities.Add(component1.entityId, new Explosion.DamageRecord()); component1.OnDamagedByExplosion(); component1.SetDead(); } } else { string tag = transform.tag; if (tag.StartsWith("E_BP_")) { flag1 = true; Transform hitRootTransform = GameUtils.GetHitRootTransform(tag, transform); EntityAlive component = (bool)hitRootTransform ? hitRootTransform.GetComponent() : (EntityAlive)null; if ((bool)component) { component.ConditionalTriggerSleeperWakeUp(); Vector3 direction = transform.position + Origin.position - __instance.worldPos; float magnitude = direction.magnitude; direction.Normalize(); if (!Voxel.Raycast(__instance.world, new Ray(__instance.worldPos, direction), magnitude, 65536, 66, 0.0f)) { EntityClass entityClass = EntityClass.list[component.entityClass]; float num2 = transform.CompareTag("E_BP_LArm") || transform.CompareTag("E_BP_RArm") ? entityClass.ArmsExplosionDamageMultiplier : (transform.CompareTag("E_BP_LLeg") || transform.CompareTag("E_BP_RLeg") ? entityClass.LegsExplosionDamageMultiplier : (!transform.CompareTag("E_BP_Head") ? entityClass.ChestExplosionDamageMultiplier : entityClass.HeadExplosionDamageMultiplier)); float num3 = (float)(int)EffectManager.GetValue(PassiveEffects.ExplosionIncomingDamage, _originalValue: num1 * num2 * (float)(1.0 - (double)magnitude / (double)radius), _entity: component); if ((double)num3 >= 3.0) { Explosion.DamageRecord damageRecord; if (!Explosion.hitEntities.TryGetValue(component.entityId, out damageRecord)) damageRecord.entity = component; EnumBodyPartHit bodyPart = DamageSource.TagToBodyPart(tag); if ((double)num3 > (double)damageRecord.damage) { damageRecord.damage = num3; damageRecord.dir = direction; damageRecord.hitTransform = transform; damageRecord.mainPart = bodyPart; } damageRecord.parts |= bodyPart; Explosion.hitEntities[component.entityId] = damageRecord; } } } } } } } foreach (KeyValuePair hitEntity in Explosion.hitEntities) { EntityAlive entity2 = hitEntity.Value.entity; if (entity2 != null) { bool flag2 = entity2.IsDead(); int health = entity2.Health; bool _criticalHit = (double)hitEntity.Value.damage > (double)entity2.GetMaxHealth() * 0.10000000149011612; EnumBodyPartHit mainPart = hitEntity.Value.mainPart; EnumBodyPartHit enumBodyPartHit = hitEntity.Value.parts & ~mainPart; float num4 = flag2 ? 0.85f : 0.6f; for (int index = 0; index < 11; ++index) { int num5 = 1 << index; if ((enumBodyPartHit & (EnumBodyPartHit)num5) != EnumBodyPartHit.None && (double)entity2.rand.RandomFloat <= (double)num4) enumBodyPartHit &= (EnumBodyPartHit)~num5; } DamageSourceEntity _damageSource = new DamageSourceEntity(EnumDamageSource.External, damageType, _entityThatCausedExplosion, hitEntity.Value.dir, hitEntity.Value.hitTransform.name, Vector3.zero, Vector2.zero); _damageSource.bodyParts = mainPart | enumBodyPartHit; _damageSource.AttackingItem = _itemValueExplosionSource; _damageSource.DismemberChance = _criticalHit ? 0.5f : 0.0f; _damageSource.BlockPosition = blockPos; entity2.DamageEntity((DamageSource)_damageSource, (int)hitEntity.Value.damage, _criticalHit, 1f); if (entity1 != null) { MinEventTypes _eventType = health != entity2.Health ? MinEventTypes.onSelfExplosionDamagedOther : MinEventTypes.onSelfExplosionAttackedOther; entity1.MinEventContext.Self = entity1; entity1.MinEventContext.Other = entity2; entity1.MinEventContext.ItemValue = _itemValueExplosionSource; _itemValueExplosionSource?.FireEvent(_eventType, entity1.MinEventContext); entity1.FireEvent(_eventType, false); } if (__instance.explosionData.BuffActions != null) { for (int index = 0; index < __instance.explosionData.BuffActions.Count; ++index) { BuffClass buff = BuffManager.GetBuff(__instance.explosionData.BuffActions[index]); if (buff != null) { float num6 = EffectManager.GetValue(PassiveEffects.BuffProcChance, _originalValue: 1f, _entity: entity1, tags: FastTags.Parse(buff.Name)); if ((double)entity2.rand.RandomFloat <= (double)num6) { int num7 = (int)entity2.Buffs.AddBuff(__instance.explosionData.BuffActions[index]); } } } } if (!flag2 && entity2.IsDead()) { EntityPlayer entityPlayer = entity1 as EntityPlayer; if ((bool)entityPlayer) entityPlayer.AddKillXP(entity2); if (entity2 is EntityPlayer player) TwitchManager.Current.CheckKiller(player, entity1, blockPos); if (entity1 != null) { if (entity1.isEntityRemote) SingletonMonoBehaviour.Instance.SendPackage((NetPackage)NetPackageManager.GetPackage().Setup(entity1.entityId, entity2.entityId, MinEventTypes.onSelfKilledOther, _itemValueExplosionSource), _attachedToEntityId: entity1.entityId); else entity1.FireEvent(MinEventTypes.onSelfKilledOther); } } } } if (!flag1 && entity1 != null) { if (entity1.isEntityRemote) { SingletonMonoBehaviour.Instance.SendPackage((NetPackage)NetPackageManager.GetPackage().Setup(entity1.entityId, -1, MinEventTypes.onSelfExplosionMissEntity, _itemValueExplosionSource), _attachedToEntityId: entity1.entityId); } else { entity1.MinEventContext.Self = entity1; entity1.MinEventContext.Other = (EntityAlive)null; entity1.MinEventContext.ItemValue = _itemValueExplosionSource; entity1.FireEvent(MinEventTypes.onSelfExplosionMissEntity); } } Explosion.hitEntities.Clear(); return false; } } }