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.Parse("primary") : FastTags.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.Instance.IsSinglePlayer) { if (entityTarget.EntityTags.Test_AnySet(FastTags.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(); if (refEntity != null && refEntity.RootTransform != null) { EntityAlive hitEntity = refEntity.RootTransform.GetComponent(); 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(); var targetColliders = entityAlive.GetComponentsInChildren(); 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 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; } } }