170 lines
10 KiB
C#
170 lines
10 KiB
C#
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<TagGroup.Global> 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<EntityItem>();
|
|
if (!(bool)component1)
|
|
{
|
|
RootTransformRefEntity component2 = transform.GetComponent<RootTransformRefEntity>();
|
|
if ((bool)component2)
|
|
component1 = component2.RootTransform.GetComponent<EntityItem>();
|
|
}
|
|
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>() : (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<int, Explosion.DamageRecord> 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<TagGroup.Global>.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<ConnectionManager>.Instance.SendPackage((NetPackage)NetPackageManager.GetPackage<NetPackageMinEventFire>().Setup(entity1.entityId, entity2.entityId, MinEventTypes.onSelfKilledOther, _itemValueExplosionSource), _attachedToEntityId: entity1.entityId);
|
|
else
|
|
entity1.FireEvent(MinEventTypes.onSelfKilledOther);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!flag1 && entity1 != null)
|
|
{
|
|
if (entity1.isEntityRemote)
|
|
{
|
|
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage((NetPackage)NetPackageManager.GetPackage<NetPackageMinEventFire>().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;
|
|
}
|
|
}
|
|
}
|