Files
7d2dXG/Mods/zzz_REBIRTH__Utils/Scripts/ItemAction/ItemActionMeleeRebirth.cs
Nathaniel Cosford 062dfab2cd Patched
2025-05-30 01:04:40 +09:30

402 lines
20 KiB
C#

using System.Collections.Generic;
using static RebirthManager;
// Replaces ItemActionMelee
public class ItemActionMeleeRebirth : ItemActionMelee
{
public override void OnHoldingUpdate(ItemActionData _actionData)
{
InventoryDataMelee inventoryDataMelee = (InventoryDataMelee)_actionData;
EntityAlive holdingEntity = _actionData.invData.holdingEntity;
AvatarZombieController AvController = holdingEntity.emodel.avatarController as AvatarZombieController;
EntityZombieSDX eZombieSdx = holdingEntity as EntityZombieSDX;
//if (AvController == null)
//Log.Out($"holdingEntity: {holdingEntity} - emodel: {holdingEntity.emodel}");
//if (holdingEntity.emodel != null && AvController == null)
//Log.Out($"holdingEntity: {holdingEntity} - avatarController: {holdingEntity.emodel.avatarController}");
if (holdingEntity.IsDead())
return;
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth OnHoldingUpdate entity: {holdingEntity}");
if (RebirthUtilities.canAttack2(holdingEntity))
{
//Log.Out("ItemActionMeleeRebirth-OnHoldingUpdate CANNOT ATTACK");
return;
}
if (AvController == null)
{
if (!inventoryDataMelee.bAttackStarted || Time.time - inventoryDataMelee.lastUseTime < rayCastDelay)
{
return;
}
if (rayCastDelay <= 0f && !holdingEntity.IsAttackImpact())
{
return;
}
if (!holdingEntity.IsAttackValid())
{
return;
}
}
else if (!AvController.isAttackImpact || !inventoryDataMelee.bAttackStarted)
{
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth OnHoldingUpdate is not impact yet {holdingEntity}, bAttackStarted: {inventoryDataMelee.bAttackStarted}");
return;
}
long LastHit = (eZombieSdx == null) ? 0L : eZombieSdx.LastHit;
TimeSpan tsLastHit = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - LastHit);
float HitDelay = Delay * 1000.0f;
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth entity: {holdingEntity}, Delay: {Delay}, HitDelay: {HitDelay}, tsLastHit. milliseconds: {tsLastHit.TotalMilliseconds}");
inventoryDataMelee.bAttackStarted = false;
if (tsLastHit.TotalMilliseconds < HitDelay)
{
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth entity: {holdingEntity} - too soon to hit");
ResetImpact(AvController);
return;
}
inventoryDataMelee.bAttackStarted = false;
ItemActionAttackData.HitDelegate hitDelegate = inventoryDataMelee.hitDelegate;
inventoryDataMelee.hitDelegate = null;
float value = EffectManager.GetValue(PassiveEffects.StaminaLoss, inventoryDataMelee.invData.itemValue, 0f, holdingEntity, null, (_actionData.indexInEntityOfAction == 0) ? FastTags<TagGroup.Global>.Parse("primary") : FastTags<TagGroup.Global>.Parse("secondary"));
holdingEntity.AddStamina(0f - value);
float damageScale = 1f;
WorldRayHitInfo worldRayHitInfo = ((hitDelegate == null) ? GetExecuteActionTarget(_actionData) : hitDelegate(out damageScale));
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth entity: {holdingEntity} - hitDelegate: {hitDelegate}, worldRayHitInfo: {worldRayHitInfo}, AttackTarget: {holdingEntity.GetAttackTarget()}");
//if (worldRayHitInfo != null && ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth entity: {holdingEntity} - worldRayHitInfo hit valid: {worldRayHitInfo.bHitValid}, tag: {worldRayHitInfo.tag}, hit dist: {worldRayHitInfo.hit.distanceSq}, collider: {worldRayHitInfo.hitCollider}");
/*if (worldRayHitInfo != null && worldRayHitInfo.bHitValid)
{
string bodyPartName;
Entity entityNoTagCheck = ItemActionAttack.FindHitEntityNoTagCheck(worldRayHitInfo, out bodyPartName);
EntityAlive entityTarget = entityNoTagCheck as EntityAlive;
if (entityTarget != null)
{
if (!SingletonMonoBehaviour<ConnectionManager>.Instance.IsSinglePlayer)
{
if (entityTarget.EntityTags.Test_AnySet(FastTags<TagGroup.Global>.Parse("allyanimal,animal")))
{
Range = 1.6f;
}
}
}
}*/
if (worldRayHitInfo != null && worldRayHitInfo.bHitValid &&
(worldRayHitInfo.tag == null || !GameUtils.IsBlockOrTerrain(worldRayHitInfo.tag) || !(worldRayHitInfo.hit.distanceSq > BlockRange * BlockRange)) &&
(worldRayHitInfo.tag == null || !worldRayHitInfo.tag.StartsWith("E_") || !(worldRayHitInfo.hit.distanceSq > Range * Range)))
{
//Log.Out("ItemActionMeleeRebirth-OnHoldingUpdate Range: " + Range);
// npc weapons should not break
/*if (inventoryDataMelee.invData.itemValue.MaxUseTimes > 0)
{
_actionData.invData.itemValue.UseTimes += EffectManager.GetValue(PassiveEffects.DegradationPerUse, inventoryDataMelee.invData.itemValue, 1f, holdingEntity, null, _actionData.invData.itemValue.ItemClass.ItemTags);
HandleItemBreak(_actionData);
}*/
//if (ItemAction.ShowDebugDisplayHit)
//DebugLines.Create("MeleeHit", holdingEntity.RootTransform, holdingEntity.position, worldRayHitInfo.hit.pos, new Color(0.7f, 0f, 0f), new Color(1f, 1f, 0f), 0.05f, 0.02f, 1f);
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth hit Target this entity: {holdingEntity}");
hitTheTarget(inventoryDataMelee, worldRayHitInfo, damageScale);
if (eZombieSdx != null)
eZombieSdx.LastHit = DateTime.UtcNow.Ticks;
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth OnHoldingUpdate after hit target this entity: {holdingEntity}");
if (inventoryDataMelee.bFirstHitInARow)
{
inventoryDataMelee.bFirstHitInARow = false;
}
}
/* debug testing stuff
else
{
if (ItemAction.ShowDebugDisplayHit)
{
Log.Out($"Rebirth Else Failed to obtain worldRayHitInfo this entity: {holdingEntity}");
int layerMask = ~(1 << 2 | 1 << 4 | 1 << 12 | 1 << 13 | 1 << 14 | 1 << 15 | 1 << 16 | 1 << 18 | 1 << 19 | 1 << 20);
//holdingEntity.SetModelLayer(2);
var allColliders = Physics.OverlapSphere(holdingEntity.transform.position, 2f, layerMask, QueryTriggerInteraction.Ignore);
//holdingEntity.SetModelLayer(0);
Log.Out($"Rebirth layerMask: {layerMask}, allColliders: {allColliders.Length}, voxelRayHitInfo bValid: {Voxel.voxelRayHitInfo.bHitValid}, tag: {Voxel.voxelRayHitInfo.tag}, transform: {Voxel.voxelRayHitInfo.transform}");
foreach (var c in allColliders)
{
Log.Out($"Rebirth coll: {c}, layer: {c.gameObject.layer}, tag: {c.tag}, pos: {c.transform.position}, root: {c.transform.root}");
RootTransformRefEntity refEntity = c.gameObject.GetComponent<RootTransformRefEntity>();
if (refEntity != null && refEntity.RootTransform != null)
{
EntityAlive hitEntity = refEntity.RootTransform.GetComponent<EntityAlive>();
if (hitEntity != null)
{
Log.Out($"Rebirth ref Entity: {hitEntity}");
}
}
}
}
}*/
ResetImpact(AvController);
}
public override WorldRayHitInfo GetExecuteActionTarget(ItemActionData _actionData)
{
InventoryDataMelee inventoryDataMelee = (InventoryDataMelee)_actionData;
EntityAlive holdingEntity = inventoryDataMelee.invData.holdingEntity;
inventoryDataMelee.ray = holdingEntity.GetLookRay();
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth ItemActionMelee::GetExecuteActionTarget - holdingEntity: {holdingEntity} My Position: {holdingEntity.position}, AttackTarget: {holdingEntity.GetAttackTarget()}");
//if (holdingEntity.GetAttackTarget() == null)
//Log.Out($"Rebirth ItemActionMelee::GetExecuteActionTarget - holdingEntity: {holdingEntity}, AttackTarget NULL: {holdingEntity.GetAttackTarget()}");
if (holdingEntity.IsBreakingBlocks)
{
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth ItemActionMelee::GetExecuteActionTarget - holdingEntity: {holdingEntity} IsBreakingBlocks");
if (inventoryDataMelee.ray.direction.y < 0f)
{
inventoryDataMelee.ray.direction = new Vector3(inventoryDataMelee.ray.direction.x, 0f, inventoryDataMelee.ray.direction.z);
inventoryDataMelee.ray.origin += new Vector3(0f, -0.7f, 0f);
}
}
else if (holdingEntity.GetAttackTarget() != null)
{
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth ItemActionMelee::GetExecuteActionTarget - holdingEntity: {holdingEntity} My Position: {holdingEntity.position}, AttackTarget: {holdingEntity.GetAttackTarget()}, Target HitPosition: {holdingEntity.GetAttackTargetHitPosition()}, dist apart: {holdingEntity.GetDistance(holdingEntity.GetAttackTarget())}");
Vector3 direction = holdingEntity.GetAttackTargetHitPosition() - inventoryDataMelee.ray.origin;
inventoryDataMelee.ray = new Ray(inventoryDataMelee.ray.origin, direction);
}
inventoryDataMelee.ray.origin -= 0.15f * inventoryDataMelee.ray.direction;
int modelLayer = holdingEntity.GetModelLayer();
holdingEntity.SetModelLayer(2);
float distance = Utils.FastMax(Range, BlockRange) + 0.15f;
if (holdingEntity is EntityEnemy && holdingEntity.IsBreakingBlocks)
{
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth ItemActionMelee - holdingEntity: {holdingEntity}, EntityEnemy && holdingEntity.IsBreakingBlocks - calling Voxel.Raycast");
bool blockHit = Voxel.Raycast(inventoryDataMelee.invData.world, inventoryDataMelee.ray, distance, 1073807360, 128, 0.4f);
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth ItemActionMelee - holdingEntity: {holdingEntity}, EntityEnemy && holdingEntity.IsBreakingBlocks - after Voxel.Raycast, blockHit: {blockHit}");
}
else
{
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth ItemActionMelee - holdingEntity: {holdingEntity}, else EntityAlive - calling Voxel.Raycast target: {holdingEntity.GetAttackTarget()}");
EntityAlive entityAlive = null;
int layerMask = -538767381;
if (Voxel.Raycast(inventoryDataMelee.invData.world, inventoryDataMelee.ray, distance, layerMask, 128, SphereRadius))
{
entityAlive = ItemActionAttack.GetEntityFromHit(Voxel.voxelRayHitInfo) as EntityAlive;
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth ItemActionMelee - holdingEntity: {holdingEntity}, entityAlive: {entityAlive} Voxel.Raycast success");
if (entityAlive == null)
{
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth Entity: {holdingEntity}, First raycast voxelRayHitInfo bValid: {Voxel.voxelRayHitInfo.bHitValid}, tag: {Voxel.voxelRayHitInfo.tag}, transform: {Voxel.voxelRayHitInfo.transform}");
if (Voxel.voxelRayHitInfo.bHitValid && Voxel.voxelRayHitInfo.transform != null && Voxel.voxelRayHitInfo.transform.name.Contains("Hips") && Voxel.voxelRayHitInfo.hitCollider.transform.CompareTag("Untagged"))
{
//Log.Out($"Rebirth Entity: {holdingEntity}, closest player: {holdingEntity.aiClosestPlayer}, dist: {holdingEntity.aiClosestPlayerDistSq}, First raycast success, entity null - voxelRayHitInfo bValid: {Voxel.voxelRayHitInfo.bHitValid}, tag: {Voxel.voxelRayHitInfo.tag}, transform: {Voxel.voxelRayHitInfo.transform}, layer: {Voxel.voxelRayHitInfo.hitCollider.gameObject.layer}, collider hit pos: {Voxel.voxelRayHitInfo.hit.pos}");
var entityUp = RebirthUtilities.FindEntityUp(Voxel.voxelRayHitInfo.hitCollider.transform);
if (entityUp != null)
{
entityAlive = entityUp.GetComponent<EntityAlive>();
var targetColliders = entityAlive.GetComponentsInChildren<Collider>();
foreach (var targC in targetColliders)
{
if (targC.CompareTag("E_BP_Body"))
{
Voxel.voxelRayHitInfo.tag = "E_BP_Body";
Voxel.voxelRayHitInfo.transform = targC.transform;
Voxel.voxelRayHitInfo.hit.pos = targC.transform.position + Origin.position;
Voxel.voxelRayHitInfo.hit.distanceSq = ((Voxel.voxelRayHitInfo.hit.pos != Vector3.zero) ? (holdingEntity.getChestPosition() - Voxel.voxelRayHitInfo.hit.pos).sqrMagnitude : float.MaxValue);
Voxel.voxelRayHitInfo.fmcHit = Voxel.voxelRayHitInfo.hit;
//Log.Out($"Rebirth Found Body Collider: {Voxel.voxelRayHitInfo.transform}, pos: {Voxel.voxelRayHitInfo.hit.pos}, distanceSq: {Voxel.voxelRayHitInfo.hit.distanceSq}");
break;
}
}
}
}
}
}
if (entityAlive == null)
{
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth ItemActionMelee - holdingEntity: {holdingEntity}, entityAlive == null - calling Second Voxel.Raycast");
bool didHit = Voxel.Raycast(inventoryDataMelee.invData.world, inventoryDataMelee.ray, distance, -538488837, 128, SphereRadius);
entityAlive = ItemActionAttack.GetEntityFromHit(Voxel.voxelRayHitInfo) as EntityAlive;
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth ItemActionMelee - holdingEntity: {holdingEntity}, - after Second Voxel.Raycast didHit: {didHit}");
if (entityAlive == null)// && didHit && ItemAction.ShowDebugDisplayHit)
{
//Log.Out($"Rebirth Entity: {holdingEntity}, Second raycast voxelRayHitInfo bValid: {Voxel.voxelRayHitInfo.bHitValid}, tag: {Voxel.voxelRayHitInfo.tag}, transform: {Voxel.voxelRayHitInfo.transform}");
layerMask = ~(1 << 2 | 1 << 4 | 1 << 12 | 1 << 13 | 1 << 14 | 1 << 15 | 1 << 16 | 1 << 18 | 1 << 19 | 1 << 20);
RebirthUtilities.FindEntityOverlap(holdingEntity.GetAttackTarget(), holdingEntity.transform.position, layerMask, 2f);
}
}
}
holdingEntity.SetModelLayer(modelLayer);
return _actionData.GetUpdatedHitInfo();
}
public override void ExecuteAction(ItemActionData _actionData, bool _bReleased)
{
//Log.Out("ItemActionMeleeRebirth-ExecuteAction START");
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth ItemActionMelee::ExecuteAction - entity: {_actionData.invData.holdingEntity}, bReleased: {_bReleased}");
InventoryDataMelee inventoryDataMelee = (InventoryDataMelee)_actionData;
if (_bReleased)
{
inventoryDataMelee.bFirstHitInARow = true;
}
else
{
if (Time.time - inventoryDataMelee.lastUseTime < Delay)
{
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth ItemActionMelee::ExecuteAction - inventoryDataMelee.lastUseTime: {inventoryDataMelee.lastUseTime}, Delay: {Delay}");
return;
}
inventoryDataMelee.lastUseTime = Time.time;
/*
if (inventoryDataMelee.invData.itemValue.MaxUseTimes > 0 && inventoryDataMelee.invData.itemValue.UseTimes >= (float)inventoryDataMelee.invData.itemValue.MaxUseTimes)
{
EntityPlayerLocal player = _actionData.invData.holdingEntity as EntityPlayerLocal;
if (item.Properties.Values.ContainsKey(ItemClass.PropSoundJammed))
{
Manager.PlayInsidePlayerHead(item.Properties.Values[ItemClass.PropSoundJammed]);
}
GameManager.ShowTooltip(player, "ttItemNeedsRepair");
return;
}*/
_actionData.invData.holdingEntity.RightArmAnimationAttack = true;
/*
inventoryDataMelee.bHarvesting = CheckHarvesting(_actionData, out var _);
if (inventoryDataMelee.bHarvesting)
{
_actionData.invData.holdingEntity.HarvestingAnimation = true;
}*/
if (soundStart != null)
{
_actionData.invData.holdingEntity.PlayOneShot(soundStart);
}
inventoryDataMelee.bAttackStarted = true;
if ((double)inventoryDataMelee.invData.holdingEntity.speedForward > 0.009)
{
rayCastDelay = AnimationDelayData.AnimationDelay[inventoryDataMelee.invData.item.HoldType.Value].RayCastMoving;
}
else
{
rayCastDelay = AnimationDelayData.AnimationDelay[inventoryDataMelee.invData.item.HoldType.Value].RayCast;
}
}
}
public bool CheckHarvesting(ItemActionData _actionData, out AttackHitInfo myAttackHitInfo)
{
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth ItemActionMelee::CheckHarvesting {_actionData.invData.holdingEntity}");
WorldRayHitInfo executeActionTarget = GetExecuteActionTarget(_actionData);
ItemValue itemValue = _actionData.invData.itemValue;
myAttackHitInfo = new AttackHitInfo { WeaponTypeTag = ItemActionAttack.MeleeTag };
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth ItemActionMelee::CheckHarvesting {_actionData.invData.holdingEntity}");
ItemActionAttack.Hit(executeActionTarget, _actionData.invData.holdingEntity.entityId, (DamageType == EnumDamageTypes.None) ? EnumDamageTypes.Bashing : DamageType, GetDamageBlock(itemValue, ItemActionAttack.GetBlockHit(_actionData.invData.world, executeActionTarget), _actionData.invData.holdingEntity, _actionData.indexInEntityOfAction), GetDamageEntity(itemValue, _actionData.invData.holdingEntity, _actionData.indexInEntityOfAction), 1f, 1f, 0f, ItemAction.GetDismemberChance(_actionData, executeActionTarget), item.MadeOfMaterial.id, damageMultiplier, getBuffActions(_actionData), myAttackHitInfo, 1, ActionExp, ActionExpBonusMultiplier, this, ToolBonuses, EnumAttackMode.Simulate);
if (myAttackHitInfo.bKilled)
{
return false;
}
if (myAttackHitInfo.itemsToDrop != null && myAttackHitInfo.itemsToDrop.ContainsKey(EnumDropEvent.Harvest))
{
List<Block.SItemDropProb> list = myAttackHitInfo.itemsToDrop[EnumDropEvent.Harvest];
for (int i = 0; i < list.Count; i++)
{
if (list[i].toolCategory != null && ToolBonuses != null && ToolBonuses.ContainsKey(list[i].toolCategory))
{
return true;
}
}
}
return false;
}
void ResetImpact(AvatarZombieController AvController)
{
if (AvController != null)
{
//if (ItemAction.ShowDebugDisplayHit)
//Log.Out($"Rebirth ResetImpact setting isAttackImpact to false");
AvController.isAttackImpact = false;
AvController.attackPlayingTime = 0f;
}
}
}