using System; using System.Collections; using System.Collections.Generic; using Photon.Pun; using Sirenix.OdinInspector; using UnityEngine; using UnityEngine.Events; public class ProjectileHit : RayHit { [HideInInspector] public bool canPushBox = true; public float force; public float damage; public float stun; public float percentageDamage; public float movementSlow; public float shake; public ObjectsToSpawn[] objectsToSpawn; public PlayerSkin team; [HideInInspector] public Player ownPlayer; [HideInInspector] public GameObject ownWeapon; public AnimationCurve effectOverTimeCurve; [HideInInspector] public List effects; private List playersHit = new List(); public Color projectileColor = Color.black; private Action hitAction; private Action hitActionWithData; [HideInInspector] public bool unblockable; [HideInInspector] public bool fullSelfDamage; [FoldoutGroup("Special", 0)] public UnityEvent deathEvent; [FoldoutGroup("Special", 0)] public bool destroyOnBlock; [FoldoutGroup("Special", 0)] public float holdPlayerFor = 0.5f; [FoldoutGroup("Special", 0)] public string bulletImmunity = ""; private SpawnedAttack spawnedAttack; [HideInInspector] public float sinceReflect = 10f; [HideInInspector] public float dealDamageMultiplierr = 1f; internal bool hasControl; [HideInInspector] public PhotonView view; private MoveTransform move; [HideInInspector] public bool bulletCanDealDeamage = true; [HideInInspector] public bool isAllowedToSpawnObjects = true; public bool sendCollisions = true; public Dictionary customActions = new Dictionary(); public Dictionary> customActionsV2V2 = new Dictionary>(); private void Start() { move = GetComponent(); view = GetComponent(); effects.AddRange(GetComponentsInChildren()); effects.Sort((RayHitEffect p1, RayHitEffect p2) => p2.priority.CompareTo(p1.priority)); spawnedAttack = GetComponent(); if ((bool)spawnedAttack && !ownPlayer) { ownPlayer = spawnedAttack.spawner; } if ((bool)ownPlayer && !fullSelfDamage) { StartCoroutine(HoldPlayer(ownPlayer.GetComponent())); } damage *= base.transform.localScale.x; force *= Mathf.Pow(damage / 55f, 2f); } public void ResortHitEffects() { effects.Sort((RayHitEffect p1, RayHitEffect p2) => p2.priority.CompareTo(p1.priority)); } private IEnumerator HoldPlayer(HealthHandler player) { if ((bool)player) { playersHit.Add(player); } yield return new WaitForSeconds(holdPlayerFor); if (playersHit.Contains(player)) { playersHit.Remove(player); } } private void Update() { sinceReflect += TimeHandler.deltaTime; } public void AddPlayerToHeld(HealthHandler health) { StartCoroutine(HoldPlayer(health)); } public void RemoveOwnPlayerFromPlayersHit() { if ((bool)ownPlayer && playersHit.Contains(ownPlayer.GetComponent())) { playersHit.Remove(ownPlayer.GetComponent()); } } public override void Hit(HitInfo hit, bool forceCall = false) { int num = -1; if ((bool)hit.transform) { PhotonView component = hit.transform.root.GetComponent(); if ((bool)component) { num = component.ViewID; } } int num2 = -1; if (num == -1) { Collider2D[] componentsInChildren = MapManager.instance.currentMap.Map.GetComponentsInChildren(); for (int i = 0; i < componentsInChildren.Length; i++) { if (componentsInChildren[i] == hit.collider) { num2 = i; } } } HealthHandler healthHandler = null; if ((bool)hit.transform) { healthHandler = hit.transform.GetComponent(); } bool flag = false; if ((bool)healthHandler) { if (playersHit.Contains(healthHandler)) { return; } if (view.IsMine && healthHandler.GetComponent().IsBlocking()) { flag = true; } StartCoroutine(HoldPlayer(healthHandler)); } if (view.IsMine || forceCall) { if (sendCollisions) { view.RPC("RPCA_DoHit", RpcTarget.All, hit.point, hit.normal, (Vector2)move.velocity, num, num2, flag); } else { RPCA_DoHit(hit.point, hit.normal, move.velocity, num, num2, flag); } } } [PunRPC] public void RPCA_DoHit(Vector2 hitPoint, Vector2 hitNormal, Vector2 vel, int viewID = -1, int colliderID = -1, bool wasBlocked = false) { HitInfo hitInfo = new HitInfo(); if ((bool)move) { move.velocity = vel; } hitInfo.point = hitPoint; hitInfo.normal = hitNormal; hitInfo.collider = null; if (viewID != -1) { PhotonView photonView = PhotonNetwork.GetPhotonView(viewID); hitInfo.collider = photonView.GetComponentInChildren(); hitInfo.transform = photonView.transform; } else if (colliderID != -1) { hitInfo.collider = MapManager.instance.currentMap.Map.GetComponentsInChildren()[colliderID]; hitInfo.transform = hitInfo.collider.transform; } HealthHandler healthHandler = null; if ((bool)hitInfo.transform) { healthHandler = hitInfo.transform.GetComponent(); } if (isAllowedToSpawnObjects) { base.transform.position = hitInfo.point; } if ((bool)hitInfo.collider) { ProjectileHitSurface component = hitInfo.collider.GetComponent(); if ((bool)component && component.HitSurface(hitInfo, base.gameObject) == ProjectileHitSurface.HasToStop.HasToStop) { return; } } if ((bool)healthHandler) { Block component2 = healthHandler.GetComponent(); if (wasBlocked) { component2.DoBlock(base.gameObject, base.transform.forward, hitInfo.point); if (destroyOnBlock) { DestroyMe(); } sinceReflect = 0f; return; } CharacterStatModifiers component3 = healthHandler.GetComponent(); if (movementSlow != 0f && !wasBlocked) { component3.RPCA_AddSlow(movementSlow); } } float num = 1f; PlayerVelocity playerVelocity = null; if ((bool)hitInfo.transform) { playerVelocity = hitInfo.transform.GetComponentInParent(); } if ((bool)hitInfo.collider) { Damagable componentInParent = hitInfo.collider.GetComponentInParent(); if ((bool)componentInParent) { if ((bool)healthHandler && percentageDamage != 0f) { damage += healthHandler.GetComponent().maxHealth * percentageDamage; } if (hasControl) { if (bulletImmunity != "" && (bool)healthHandler) { healthHandler.GetComponent().IsImune(0.1f, (bulletCanDealDeamage ? damage : 1f) * dealDamageMultiplierr, bulletImmunity); } if ((bool)componentInParent.GetComponent()) { componentInParent.CallTakeDamage(base.transform.forward * damage * dealDamageMultiplierr, hitInfo.point, ownWeapon, ownPlayer); } else { componentInParent.CallTakeDamage(base.transform.forward * (bulletCanDealDeamage ? damage : 1f) * dealDamageMultiplierr, hitInfo.point, ownWeapon, ownPlayer); } } } } if ((bool)playerVelocity) { float num2 = 1f; float num3 = Mathf.Clamp(playerVelocity.mass / 100f * num2, 0f, 1f) * num2; float num4 = 1f; playerVelocity.AddForce(-playerVelocity.velocity * 0.1f * playerVelocity.mass, ForceMode2D.Impulse); if ((bool)healthHandler) { num *= 3f; if (hasControl) { healthHandler.CallTakeForce(base.transform.forward * num4 * num3 * force); } } } if (isAllowedToSpawnObjects && !wasBlocked) { GamefeelManager.GameFeel(base.transform.forward * num * shake); DynamicParticles.instance.PlayBulletHit(damage, base.transform, hitInfo, projectileColor); for (int i = 0; i < objectsToSpawn.Length; i++) { ObjectsToSpawn.SpawnObject(base.transform, hitInfo, objectsToSpawn[i], healthHandler, team, damage, spawnedAttack, wasBlocked); } base.transform.position = hitInfo.point + hitInfo.normal * 0.01f; } if ((bool)hitInfo.transform) { NetworkPhysicsObject component4 = hitInfo.transform.GetComponent(); if ((bool)component4 && canPushBox) { component4.BulletPush(base.transform.forward * (force * 0.5f + damage * 100f), hitInfo.transform.InverseTransformPoint(hitInfo.point), spawnedAttack.spawner.data); } } bool flag = false; if (effects != null && effects.Count != 0) { for (int j = 0; j < effects.Count; j++) { HasToReturn num5 = effects[j].DoHitEffect(hitInfo); if (num5 == HasToReturn.hasToReturn) { flag = true; } if (num5 == HasToReturn.hasToReturnNow) { return; } } } if (!flag) { if (hitAction != null) { hitAction(); } if (hitActionWithData != null) { hitActionWithData(hitInfo); } deathEvent.Invoke(); DestroyMe(); } } private void DestroyMe() { if ((bool)view) { if (view.IsMine) { PhotonNetwork.Destroy(base.gameObject); } } else { UnityEngine.Object.Destroy(base.gameObject); } } [PunRPC] public void RPCA_CallCustomAction(string actionKey) { customActions[actionKey](); } [PunRPC] public void RPCA_CallCustomActionV2V2(string actionKey, Vector2 v1, Vector2 v2) { customActionsV2V2[actionKey](v1, v2); } public void AddHitAction(Action action) { hitAction = (Action)Delegate.Combine(hitAction, action); } public void AddHitActionWithData(Action action) { hitActionWithData = (Action)Delegate.Combine(hitActionWithData, action); } }