using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(fileName = "Weapon", menuName = "SimpleSiege/Weapon")] public class Weapon : ScriptableObject { public enum EFacingDirection { Uniform, FaceVictim, FaceAttacker, Random } public enum EDamageAffectedByBlacksmithUpgrade { Null, MultiplyBy_MeleeDamage, MultiplyBy_RangedDamage, DivideBy_MeleeResistance, DivideBy_RangedResistance } [Header("Blacksmith Upgrades")] public EDamageAffectedByBlacksmithUpgrade blacksmithEffect; [Header("Aimbot Projectile Settings")] public EFacingDirection projectileFacingDirection; public float projectileSpeed; public float projectileParabulaFactor; public float projectileParabulaOffset; public GameObject projectileVisuals; public GameObject projectileImpactVisuals; public bool performRaycastWhenHittingEmptyPosition; public LayerMask emptyPositionRaycastLayerMask; public float raycastLength = 1f; public bool performRaycastBeforeShooting; public LayerMask raycastBeforeShootingLayerMask; public float maximumChaseRange = 10000f; public float shootWithoutTargetRange = 20f; public GameObject spawnOnGroundWhenTargetingGround; [Header("Melee Attack Setting")] public GameObject fxSpawnOnAttacker; public bool parentFxToAttacker; public GameObject fxSpawnOnVictim; [Header("Damage")] public bool isPlayerWeapon; public List directDamage; public List splashDamage; public float slowsFastEnemiesFor; private PlayerUpgradeManager playerUpgradeManager; private BlacksmithUpgrades blacksmithUpgrades; public void Attack(Vector3 _attackOrigin, Hp _target, Vector3 _attackDirection, TaggedObject _attacker, float _finalDamageMultiplyer = 1f) { playerUpgradeManager = PlayerUpgradeManager.instance; Vector3 vector = _attackOrigin + _attackDirection; if ((bool)_target) { vector = ((!(_target.TaggedObj.colliderForBigOjectsToMeasureDistance != null)) ? (_target.transform.position + _target.hitFeedbackHeight * Vector3.up) : _target.TaggedObj.colliderForBigOjectsToMeasureDistance.ClosestPoint(_attackOrigin)); } if (performRaycastBeforeShooting) { Physics.Raycast(_attackOrigin, vector - _attackOrigin, out var hitInfo, (vector - _attackOrigin).magnitude, raycastBeforeShootingLayerMask); if (hitInfo.collider != null) { Hp componentInParent = hitInfo.collider.GetComponentInParent(); if (!(componentInParent != null)) { return; } _target = componentInParent; vector = ((!(_target.TaggedObj.colliderForBigOjectsToMeasureDistance != null)) ? (_target.transform.position + _target.hitFeedbackHeight * Vector3.up) : _target.TaggedObj.colliderForBigOjectsToMeasureDistance.ClosestPoint(_attackOrigin)); } } if (projectileSpeed > 0f && projectileVisuals != null) { AimbotProjectile component = Object.Instantiate(projectileVisuals, _attackOrigin, Quaternion.identity).GetComponent(); Vector3 backupTarget = Vector3.zero; if (_target == null) { backupTarget = _attackOrigin + _attackDirection.normalized * shootWithoutTargetRange; } component.Fire(this, _target, maximumChaseRange, backupTarget, _attacker, _finalDamageMultiplyer); return; } if (fxSpawnOnAttacker != null) { SpawnAttackFx(fxSpawnOnAttacker, _attackOrigin, _attackOrigin, _target, vector, _attacker, _finalDamageMultiplyer, parentFxToAttacker); } if (fxSpawnOnVictim != null && _target != null) { SpawnAttackFx(fxSpawnOnVictim, vector, _attackOrigin, _target, vector, _attacker, _finalDamageMultiplyer); } DealDamage(_target, _finalDamageMultiplyer, _attacker); } private void SpawnAttackFx(GameObject _fxPrefab, Vector3 _spawnPosition, Vector3 _attackOrigin, Hp _target, Vector3 _attackPosition, TaggedObject _attacker, float _finalDamageMultiplyer = 1f, bool parentToAttacker = false) { Vector3 vector = _attackPosition - _attackOrigin; vector = new Vector3(vector.x, 0f, vector.z); Quaternion rotation = Quaternion.LookRotation(vector, Vector3.up); Transform parent = null; if (parentToAttacker) { parent = _attacker.transform; } GameObject fxWithSplashDamageAreas = Object.Instantiate(_fxPrefab, _spawnPosition, rotation, parent); DealSplashDamage(fxWithSplashDamageAreas, _attacker, _finalDamageMultiplyer); } public void DealSplashDamage(GameObject _fxWithSplashDamageAreas, TaggedObject _attacker, float _finalDamageMultiplyer) { if (splashDamage.Count <= 0) { return; } SplashDamageArea[] componentsInChildren = _fxWithSplashDamageAreas.GetComponentsInChildren(); if (componentsInChildren.Length != 0) { List list = new List(); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].AddReiveDamageHpScriptsInAreaToList(list); } for (int j = 0; j < list.Count; j++) { DealDamage(list[j], _finalDamageMultiplyer, _attacker, splashDamage: true); } } } public void DealDamage(Hp _target, float _finalDamageMultiplyer, TaggedObject _attacker, bool splashDamage = false) { if (!_target || !_target.TaggedObj) { return; } float num = _finalDamageMultiplyer; if (blacksmithUpgrades == null) { blacksmithUpgrades = BlacksmithUpgrades.instance; } switch (blacksmithEffect) { case EDamageAffectedByBlacksmithUpgrade.MultiplyBy_MeleeDamage: num *= blacksmithUpgrades.meleeDamage; break; case EDamageAffectedByBlacksmithUpgrade.MultiplyBy_RangedDamage: num *= blacksmithUpgrades.rangedDamage; break; case EDamageAffectedByBlacksmithUpgrade.DivideBy_MeleeResistance: num /= blacksmithUpgrades.meleeResistance; break; case EDamageAffectedByBlacksmithUpgrade.DivideBy_RangedResistance: num /= blacksmithUpgrades.rangedResistance; break; } float hpValue = _target.HpValue; if (splashDamage) { _target.TakeDamage(CalculateSplashDamageOnTarget(_target.TaggedObj, num), _attacker, isPlayerWeapon); } else { _target.TakeDamage(CalculateDirectDamageOnTarget(_target.TaggedObj, num), _attacker, isPlayerWeapon); } if (_target.TaggedObj.Tags.Contains(TagManager.ETag.Player) && playerUpgradeManager.magicArmor) { float num2 = hpValue - _target.HpValue; if (num2 > 0f && (bool)_attacker) { _attacker.Hp.TakeDamage(num2 * UpgradeMagicArmor.instance.damageMultiplyer, _target.TaggedObj, causedByPlayer: true); } } if (slowsFastEnemiesFor >= 0f && _target.TaggedObj.Tags.Contains(TagManager.ETag.FastMoving) && (bool)_target.PathfindMovement) { if (PerkManager.instance.IceMagicActive) { _target.PathfindMovement.Slow(slowsFastEnemiesFor * PerkManager.instance.iceMagic_SlowDurationMulti); } else { _target.PathfindMovement.Slow(slowsFastEnemiesFor); } } } public float CalculateDirectDamageOnTarget(TaggedObject _taggedObject, float _finalDamageMultiplyer = 1f) { return DamageModifyer.CalculateDamageOnTarget(_taggedObject, directDamage, _finalDamageMultiplyer); } public float CalculateSplashDamageOnTarget(TaggedObject _taggedObject, float _finalDamageMultiplyer = 1f) { return DamageModifyer.CalculateDamageOnTarget(_taggedObject, splashDamage, _finalDamageMultiplyer); } public static float CalculateDamageGeneral(TaggedObject _taggedObject, List directDamage, float _finalDamageMultiplyer = 1f) { return DamageModifyer.CalculateDamageOnTarget(_taggedObject, directDamage, _finalDamageMultiplyer); } }