| using System; |
| using System; |
| using System.Collections.Generic; |
| using System.Collections.Generic; |
| using UnityEngine; |
| using UnityEngine; |
| using UnityEngine.Serialization; |
| using UnityEngine.Serialization; |
| |
| |
| [Serializable] |
| [Serializable] |
| public class Attack |
| public class Attack |
| { |
| { |
| public bool StartDraw(Humanoid character, ItemDrop.ItemData weapon) |
| public bool StartDraw(Humanoid character, ItemDrop.ItemData weapon) |
| { |
| { |
| if (!Attack.HaveAmmo(character, weapon)) |
| if (!Attack.HaveAmmo(character, weapon)) |
| { |
| { |
| return false; |
| return false; |
| } |
| } |
| Attack.EquipAmmoItem(character, weapon); |
| Attack.EquipAmmoItem(character, weapon); |
| return true; |
| return true; |
| } |
| } |
| |
| |
| public bool Start(Humanoid character, Rigidbody body, ZSyncAnimation zanim, CharacterAnimEvent animEvent, VisEquipment visEquipment, ItemDrop.ItemData weapon, Attack previousAttack, float timeSinceLastAttack, float attackDrawPercentage) |
| public bool Start(Humanoid character, Rigidbody body, ZSyncAnimation zanim, CharacterAnimEvent animEvent, VisEquipment visEquipment, ItemDrop.ItemData weapon, Attack previousAttack, float timeSinceLastAttack, float attackDrawPercentage) |
| { |
| { |
| if (this.m_attackAnimation == "") |
| if (this.m_attackAnimation == "") |
| { |
| { |
| return false; |
| return false; |
| } |
| } |
| this.m_character = character; |
| this.m_character = character; |
| this.m_baseAI = this.m_character.GetComponent<BaseAI>(); |
| this.m_baseAI = this.m_character.GetComponent<BaseAI>(); |
| this.m_body = body; |
| this.m_body = body; |
| this.m_zanim = zanim; |
| this.m_zanim = zanim; |
| this.m_animEvent = animEvent; |
| this.m_animEvent = animEvent; |
| this.m_visEquipment = visEquipment; |
| this.m_visEquipment = visEquipment; |
| this.m_weapon = weapon; |
| this.m_weapon = weapon; |
| this.m_attackDrawPercentage = attackDrawPercentage; |
| this.m_attackDrawPercentage = attackDrawPercentage; |
| if (Attack.m_attackMask == 0) |
| if (Attack.m_attackMask == 0) |
| { |
| { |
| Attack.m_attackMask = LayerMask.GetMask(new string[] |
| Attack.m_attackMask = LayerMask.GetMask(new string[] |
| { |
| { |
| "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "character", "character_net", "character_ghost", "hitbox", "character_noenv", |
| "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "character", "character_net", "character_ghost", "hitbox", "character_noenv", |
| "vehicle" |
| "vehicle" |
| }); |
| }); |
| Attack.m_attackMaskTerrain = LayerMask.GetMask(new string[] |
| Attack.m_attackMaskTerrain = LayerMask.GetMask(new string[] |
| { |
| { |
| "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net", "character_ghost", "hitbox", |
| "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net", "character_ghost", "hitbox", |
| "character_noenv", "vehicle" |
| "character_noenv", "vehicle" |
| }); |
| }); |
| } |
| } |
| if (this.m_requiresReload && (!this.m_character.IsWeaponLoaded() || this.m_character.InMinorAction())) |
| if (this.m_requiresReload && (!this.m_character.IsWeaponLoaded() || this.m_character.InMinorAction())) |
| { |
| { |
| return false; |
| return false; |
| } |
| } |
| float attackStamina = this.GetAttackStamina(); |
| float attackStamina = this.GetAttackStamina(); |
| if (attackStamina > 0f && !character.HaveStamina(attackStamina + 0.1f)) |
| if (attackStamina > 0f && !character.HaveStamina(attackStamina + 0.1f)) |
| { |
| { |
| if (character.IsPlayer()) |
| if (character.IsPlayer()) |
| { |
| { |
| Hud.instance.StaminaBarEmptyFlash(); |
| Hud.instance.StaminaBarEmptyFlash(); |
| } |
| } |
| return false; |
| return false; |
| } |
| } |
| . | float attackEitr = this.GetAttackEitr(); |
| if (!character.TryUseEitr(this.GetAttackEitr())) |
| if (attackEitr > 0f) |
| |
| { |
| { |
| . | if (character.GetMaxEitr() == 0f) |
| return false; |
| { |
| |
| character.Message(MessageHud.MessageType.Center, "$hud_eitrrequired", 0, null); |
| |
| return false; |
| |
| } |
| |
| if (!character.HaveEitr(attackEitr + 0.1f)) |
| |
| { |
| |
| if (character.IsPlayer()) |
| |
| { |
| |
| Hud.instance.EitrBarEmptyFlash(); |
| |
| } |
| |
| return false; |
| |
| } |
| |
| } |
| } |
| float attackHealth = this.GetAttackHealth(); |
| float attackHealth = this.GetAttackHealth(); |
| . | if (attackHealth > 0f && !character.HaveHealth(attackHealth + 0.1f)) |
| if (attackHealth > 0f && !character.HaveHealth(attackHealth + 0.1f) && this.m_attackHealthLowBlockUse && character.IsPlayer()) |
| { |
| { |
| . | if (character.IsPlayer()) |
| Hud.instance.FlashHealthBar(); |
| { |
| |
| Hud.instance.FlashHealthBar(); |
| |
| } |
| |
| return false; |
| |
| } |
| } |
| if (!Attack.HaveAmmo(character, this.m_weapon)) |
| if (!Attack.HaveAmmo(character, this.m_weapon)) |
| { |
| { |
| return false; |
| return false; |
| } |
| } |
| Attack.EquipAmmoItem(character, this.m_weapon); |
| Attack.EquipAmmoItem(character, this.m_weapon); |
| if (this.m_attackChainLevels > 1) |
| if (this.m_attackChainLevels > 1) |
| { |
| { |
| if (previousAttack != null && previousAttack.m_attackAnimation == this.m_attackAnimation) |
| if (previousAttack != null && previousAttack.m_attackAnimation == this.m_attackAnimation) |
| { |
| { |
| this.m_currentAttackCainLevel = previousAttack.m_nextAttackChainLevel; |
| this.m_currentAttackCainLevel = previousAttack.m_nextAttackChainLevel; |
| } |
| } |
| if (this.m_currentAttackCainLevel >= this.m_attackChainLevels || timeSinceLastAttack > 0.2f) |
| if (this.m_currentAttackCainLevel >= this.m_attackChainLevels || timeSinceLastAttack > 0.2f) |
| { |
| { |
| this.m_currentAttackCainLevel = 0; |
| this.m_currentAttackCainLevel = 0; |
| } |
| } |
| this.m_zanim.SetTrigger(this.m_attackAnimation + this.m_currentAttackCainLevel.ToString()); |
| this.m_zanim.SetTrigger(this.m_attackAnimation + this.m_currentAttackCainLevel.ToString()); |
| } |
| } |
| else if (this.m_attackRandomAnimations >= 2) |
| else if (this.m_attackRandomAnimations >= 2) |
| { |
| { |
| int num = UnityEngine.Random.Range(0, this.m_attackRandomAnimations); |
| int num = UnityEngine.Random.Range(0, this.m_attackRandomAnimations); |
| this.m_zanim.SetTrigger(this.m_attackAnimation + num.ToString()); |
| this.m_zanim.SetTrigger(this.m_attackAnimation + num.ToString()); |
| } |
| } |
| else |
| else |
| { |
| { |
| this.m_zanim.SetTrigger(this.m_attackAnimation); |
| this.m_zanim.SetTrigger(this.m_attackAnimation); |
| } |
| } |
| . | if (character.IsPlayer() && this.m_attackType != Attack.AttackType.None && this.m_currentAttackCainLevel == 0 && (ZInput.IsMouseActive() || ZInput.IsGamepadActive() || this.m_attackType == Attack.AttackType.Projectile)) |
| if (character.IsPlayer() && this.m_attackType != Attack.AttackType.None && this.m_currentAttackCainLevel == 0 && (Player.m_localPlayer == null || !Player.m_localPlayer.AttackTowardsPlayerLookDir || this.m_attackType == Attack.AttackType.Projectile)) |
| { |
| { |
| character.transform.rotation = character.GetLookYaw(); |
| character.transform.rotation = character.GetLookYaw(); |
| this.m_body.rotation = character.transform.rotation; |
| this.m_body.rotation = character.transform.rotation; |
| } |
| } |
| weapon.m_lastAttackTime = Time.time; |
| weapon.m_lastAttackTime = Time.time; |
| this.m_animEvent.ResetChain(); |
| this.m_animEvent.ResetChain(); |
| return true; |
| return true; |
| } |
| } |
| |
| |
| private float GetAttackStamina() |
| private float GetAttackStamina() |
| { |
| { |
| if (this.m_attackStamina <= 0f) |
| if (this.m_attackStamina <= 0f) |
| { |
| { |
| return 0f; |
| return 0f; |
| } |
| } |
| float num = this.m_attackStamina; |
| float num = this.m_attackStamina; |
| float skillFactor = this.m_character.GetSkillFactor(this.m_weapon.m_shared.m_skillType); |
| float skillFactor = this.m_character.GetSkillFactor(this.m_weapon.m_shared.m_skillType); |
| . | if (this.m_isHomeItem) |
| Player player = this.m_character as Player; |
| |
| if (player != null) |
| { |
| { |
| . | Player player = this.m_character as Player; |
| if (this.m_isHomeItem) |
| if (player != null) |
| { |
| |
| num *= 1f + player.GetEquipmentHomeItemModifier(); |
| |
| } |
| |
| else |
| { |
| { |
| . | num *= 1f + player.GetEquipmentBaseItemModifier(); |
| num *= 1f + player.GetEquipmentAttackStaminaModifier(); |
| } |
| } |
| } |
| } |
| . | return num - num * 0.33f * skillFactor; |
| this.m_character.GetSEMan().ModifyAttackStaminaUsage(num, ref num, true); |
| |
| num -= num * 0.33f * skillFactor; |
| |
| if (this.m_staminaReturnPerMissingHP > 0f) |
| |
| { |
| |
| num -= (this.m_character.GetMaxHealth() - this.m_character.GetHealth()) * this.m_staminaReturnPerMissingHP; |
| |
| } |
| |
| return num; |
| } |
| } |
| |
| |
| private float GetAttackEitr() |
| private float GetAttackEitr() |
| { |
| { |
| if (this.m_attackEitr <= 0f) |
| if (this.m_attackEitr <= 0f) |
| { |
| { |
| return 0f; |
| return 0f; |
| } |
| } |
| float attackEitr = this.m_attackEitr; |
| float attackEitr = this.m_attackEitr; |
| float skillFactor = this.m_character.GetSkillFactor(this.m_weapon.m_shared.m_skillType); |
| float skillFactor = this.m_character.GetSkillFactor(this.m_weapon.m_shared.m_skillType); |
| return attackEitr - attackEitr * 0.33f * skillFactor; |
| return attackEitr - attackEitr * 0.33f * skillFactor; |
| } |
| } |
| |
| |
| private float GetAttackHealth() |
| private float GetAttackHealth() |
| { |
| { |
| if (this.m_attackHealth <= 0f && this.m_attackHealthPercentage <= 0f) |
| if (this.m_attackHealth <= 0f && this.m_attackHealthPercentage <= 0f) |
| { |
| { |
| return 0f; |
| return 0f; |
| } |
| } |
| float num = this.m_attackHealth + this.m_character.GetHealth() * this.m_attackHealthPercentage / 100f; |
| float num = this.m_attackHealth + this.m_character.GetHealth() * this.m_attackHealthPercentage / 100f; |
| float skillFactor = this.m_character.GetSkillFactor(this.m_weapon.m_shared.m_skillType); |
| float skillFactor = this.m_character.GetSkillFactor(this.m_weapon.m_shared.m_skillType); |
| return num - num * 0.33f * skillFactor; |
| return num - num * 0.33f * skillFactor; |
| } |
| } |
| |
| |
| public void Update(float dt) |
| public void Update(float dt) |
| { |
| { |
| if (this.m_attackDone) |
| if (this.m_attackDone) |
| { |
| { |
| return; |
| return; |
| } |
| } |
| this.m_time += dt; |
| this.m_time += dt; |
| bool flag = this.m_character.InAttack(); |
| bool flag = this.m_character.InAttack(); |
| if (flag) |
| if (flag) |
| { |
| { |
| if (!this.m_wasInAttack) |
| if (!this.m_wasInAttack) |
| { |
| { |
| . | |
| BaseAI baseAI = this.m_character.GetBaseAI(); |
| |
| if (baseAI != null) |
| |
| { |
| |
| baseAI.ChargeStop(); |
| |
| } |
| if (this.m_attackType != Attack.AttackType.Projectile || !this.m_perBurstResourceUsage) |
| if (this.m_attackType != Attack.AttackType.Projectile || !this.m_perBurstResourceUsage) |
| { |
| { |
| this.m_character.UseStamina(this.GetAttackStamina(), false); |
| this.m_character.UseStamina(this.GetAttackStamina(), false); |
| this.m_character.UseEitr(this.GetAttackEitr()); |
| this.m_character.UseEitr(this.GetAttackEitr()); |
| . | this.m_character.UseHealth(this.GetAttackHealth()); |
| this.m_character.UseHealth(Mathf.Min(this.m_character.GetHealth() - 1f, this.GetAttackHealth())); |
| } |
| } |
| Transform attackOrigin = this.GetAttackOrigin(); |
| Transform attackOrigin = this.GetAttackOrigin(); |
| this.m_weapon.m_shared.m_startEffect.Create(attackOrigin.position, this.m_character.transform.rotation, attackOrigin, 1f, -1); |
| this.m_weapon.m_shared.m_startEffect.Create(attackOrigin.position, this.m_character.transform.rotation, attackOrigin, 1f, -1); |
| this.m_startEffect.Create(attackOrigin.position, this.m_character.transform.rotation, attackOrigin, 1f, -1); |
| this.m_startEffect.Create(attackOrigin.position, this.m_character.transform.rotation, attackOrigin, 1f, -1); |
| this.m_character.AddNoise(this.m_attackStartNoise); |
| this.m_character.AddNoise(this.m_attackStartNoise); |
| this.m_nextAttackChainLevel = this.m_currentAttackCainLevel + 1; |
| this.m_nextAttackChainLevel = this.m_currentAttackCainLevel + 1; |
| if (this.m_nextAttackChainLevel >= this.m_attackChainLevels) |
| if (this.m_nextAttackChainLevel >= this.m_attackChainLevels) |
| { |
| { |
| this.m_nextAttackChainLevel = 0; |
| this.m_nextAttackChainLevel = 0; |
| } |
| } |
| this.m_wasInAttack = true; |
| this.m_wasInAttack = true; |
| } |
| } |
| if (this.m_isAttached) |
| if (this.m_isAttached) |
| { |
| { |
| this.UpdateAttach(dt); |
| this.UpdateAttach(dt); |
| } |
| } |
| } |
| } |
| this.UpdateProjectile(dt); |
| this.UpdateProjectile(dt); |
| if ((!flag && this.m_wasInAttack) || this.m_abortAttack) |
| if ((!flag && this.m_wasInAttack) || this.m_abortAttack) |
| { |
| { |
| this.Stop(); |
| this.Stop(); |
| } |
| } |
| } |
| } |
| |
| |
| public bool IsDone() |
| public bool IsDone() |
| { |
| { |
| return this.m_attackDone; |
| return this.m_attackDone; |
| } |
| } |
| |
| |
| public void Stop() |
| public void Stop() |
| { |
| { |
| if (this.m_attackDone) |
| if (this.m_attackDone) |
| { |
| { |
| return; |
| return; |
| } |
| } |
| if (this.m_loopingAttack) |
| if (this.m_loopingAttack) |
| { |
| { |
| this.m_zanim.SetTrigger("attack_abort"); |
| this.m_zanim.SetTrigger("attack_abort"); |
| } |
| } |
| if (this.m_isAttached) |
| if (this.m_isAttached) |
| { |
| { |
| this.m_zanim.SetTrigger("detach"); |
| this.m_zanim.SetTrigger("detach"); |
| this.m_isAttached = false; |
| this.m_isAttached = false; |
| this.m_attachTarget = null; |
| this.m_attachTarget = null; |
| } |
| } |
| if (this.m_wasInAttack) |
| if (this.m_wasInAttack) |
| { |
| { |
| if (this.m_visEquipment) |
| if (this.m_visEquipment) |
| { |
| { |
| this.m_visEquipment.SetWeaponTrails(false); |
| this.m_visEquipment.SetWeaponTrails(false); |
| } |
| } |
| this.m_wasInAttack = false; |
| this.m_wasInAttack = false; |
| } |
| } |
| this.m_attackDone = true; |
| this.m_attackDone = true; |
| . | |
| if (this.m_attackKillsSelf) |
| |
| { |
| |
| HitData hitData = new HitData(); |
| |
| hitData.m_point = this.m_character.GetCenterPoint(); |
| |
| hitData.m_damage.m_damage = 9999999f; |
| |
| hitData.m_hitType = HitData.HitType.Self; |
| |
| this.m_character.ApplyDamage(hitData, false, true, HitData.DamageModifier.Normal); |
| |
| } |
| } |
| } |
| |
| |
| public void Abort() |
| public void Abort() |
| { |
| { |
| this.m_abortAttack = true; |
| this.m_abortAttack = true; |
| } |
| } |
| |
| |
| public void OnAttackTrigger() |
| public void OnAttackTrigger() |
| { |
| { |
| if (!this.UseAmmo(out this.m_lastUsedAmmo)) |
| if (!this.UseAmmo(out this.m_lastUsedAmmo)) |
| { |
| { |
| return; |
| return; |
| } |
| } |
| switch (this.m_attackType) |
| switch (this.m_attackType) |
| { |
| { |
| case Attack.AttackType.Horizontal: |
| case Attack.AttackType.Horizontal: |
| case Attack.AttackType.Vertical: |
| case Attack.AttackType.Vertical: |
| this.DoMeleeAttack(); |
| this.DoMeleeAttack(); |
| break; |
| break; |
| case Attack.AttackType.Projectile: |
| case Attack.AttackType.Projectile: |
| this.ProjectileAttackTriggered(); |
| this.ProjectileAttackTriggered(); |
| break; |
| break; |
| case Attack.AttackType.None: |
| case Attack.AttackType.None: |
| this.DoNonAttack(); |
| this.DoNonAttack(); |
| break; |
| break; |
| case Attack.AttackType.Area: |
| case Attack.AttackType.Area: |
| this.DoAreaAttack(); |
| this.DoAreaAttack(); |
| break; |
| break; |
| } |
| } |
| if (this.m_toggleFlying) |
| if (this.m_toggleFlying) |
| { |
| { |
| if (this.m_character.IsFlying()) |
| if (this.m_character.IsFlying()) |
| { |
| { |
| this.m_character.Land(); |
| this.m_character.Land(); |
| } |
| } |
| else |
| else |
| { |
| { |
| this.m_character.TakeOff(); |
| this.m_character.TakeOff(); |
| } |
| } |
| } |
| } |
| if (this.m_recoilPushback != 0f) |
| if (this.m_recoilPushback != 0f) |
| { |
| { |
| this.m_character.ApplyPushback(-this.m_character.transform.forward, this.m_recoilPushback); |
| this.m_character.ApplyPushback(-this.m_character.transform.forward, this.m_recoilPushback); |
| } |
| } |
| if (this.m_selfDamage > 0) |
| if (this.m_selfDamage > 0) |
| { |
| { |
| HitData hitData = new HitData(); |
| HitData hitData = new HitData(); |
| hitData.m_damage.m_damage = (float)this.m_selfDamage; |
| hitData.m_damage.m_damage = (float)this.m_selfDamage; |
| this.m_character.Damage(hitData); |
| this.m_character.Damage(hitData); |
| } |
| } |
| if (this.m_consumeItem) |
| if (this.m_consumeItem) |
| { |
| { |
| this.ConsumeItem(); |
| this.ConsumeItem(); |
| } |
| } |
| if (this.m_requiresReload) |
| if (this.m_requiresReload) |
| { |
| { |
| this.m_character.ResetLoadedWeapon(); |
| this.m_character.ResetLoadedWeapon(); |
| } |
| } |
| } |
| } |
| |
| |
| private void ConsumeItem() |
| private void ConsumeItem() |
| { |
| { |
| if (this.m_weapon.m_shared.m_maxStackSize > 1 && this.m_weapon.m_stack > 1) |
| if (this.m_weapon.m_shared.m_maxStackSize > 1 && this.m_weapon.m_stack > 1) |
| { |
| { |
| this.m_weapon.m_stack--; |
| this.m_weapon.m_stack--; |
| return; |
| return; |
| } |
| } |
| this.m_character.UnequipItem(this.m_weapon, false); |
| this.m_character.UnequipItem(this.m_weapon, false); |
| this.m_character.GetInventory().RemoveItem(this.m_weapon); |
| this.m_character.GetInventory().RemoveItem(this.m_weapon); |
| } |
| } |
| |
| |
| private static ItemDrop.ItemData FindAmmo(Humanoid character, ItemDrop.ItemData weapon) |
| private static ItemDrop.ItemData FindAmmo(Humanoid character, ItemDrop.ItemData weapon) |
| { |
| { |
| if (string.IsNullOrEmpty(weapon.m_shared.m_ammoType)) |
| if (string.IsNullOrEmpty(weapon.m_shared.m_ammoType)) |
| { |
| { |
| return null; |
| return null; |
| } |
| } |
| ItemDrop.ItemData itemData = character.GetAmmoItem(); |
| ItemDrop.ItemData itemData = character.GetAmmoItem(); |
| if (itemData != null && (!character.GetInventory().ContainsItem(itemData) || itemData.m_shared.m_ammoType != weapon.m_shared.m_ammoType)) |
| if (itemData != null && (!character.GetInventory().ContainsItem(itemData) || itemData.m_shared.m_ammoType != weapon.m_shared.m_ammoType)) |
| { |
| { |
| itemData = null; |
| itemData = null; |
| } |
| } |
| if (itemData == null) |
| if (itemData == null) |
| { |
| { |
| itemData = character.GetInventory().GetAmmoItem(weapon.m_shared.m_ammoType, null); |
| itemData = character.GetInventory().GetAmmoItem(weapon.m_shared.m_ammoType, null); |
| } |
| } |
| return itemData; |
| return itemData; |
| } |
| } |
| |
| |
| private static bool EquipAmmoItem(Humanoid character, ItemDrop.ItemData weapon) |
| private static bool EquipAmmoItem(Humanoid character, ItemDrop.ItemData weapon) |
| { |
| { |
| Attack.FindAmmo(character, weapon); |
| Attack.FindAmmo(character, weapon); |
| if (!string.IsNullOrEmpty(weapon.m_shared.m_ammoType)) |
| if (!string.IsNullOrEmpty(weapon.m_shared.m_ammoType)) |
| { |
| { |
| ItemDrop.ItemData ammoItem = character.GetAmmoItem(); |
| ItemDrop.ItemData ammoItem = character.GetAmmoItem(); |
| if (ammoItem != null && character.GetInventory().ContainsItem(ammoItem) && ammoItem.m_shared.m_ammoType == weapon.m_shared.m_ammoType) |
| if (ammoItem != null && character.GetInventory().ContainsItem(ammoItem) && ammoItem.m_shared.m_ammoType == weapon.m_shared.m_ammoType) |
| { |
| { |
| return true; |
| return true; |
| } |
| } |
| ItemDrop.ItemData ammoItem2 = character.GetInventory().GetAmmoItem(weapon.m_shared.m_ammoType, null); |
| ItemDrop.ItemData ammoItem2 = character.GetInventory().GetAmmoItem(weapon.m_shared.m_ammoType, null); |
| if (ammoItem2.m_shared.m_itemType == ItemDrop.ItemData.ItemType.Ammo || ammoItem2.m_shared.m_itemType == ItemDrop.ItemData.ItemType.AmmoNonEquipable) |
| if (ammoItem2.m_shared.m_itemType == ItemDrop.ItemData.ItemType.Ammo || ammoItem2.m_shared.m_itemType == ItemDrop.ItemData.ItemType.AmmoNonEquipable) |
| { |
| { |
| return character.EquipItem(ammoItem2, true); |
| return character.EquipItem(ammoItem2, true); |
| } |
| } |
| } |
| } |
| return true; |
| return true; |
| } |
| } |
| |
| |
| private static bool HaveAmmo(Humanoid character, ItemDrop.ItemData weapon) |
| private static bool HaveAmmo(Humanoid character, ItemDrop.ItemData weapon) |
| { |
| { |
| if (string.IsNullOrEmpty(weapon.m_shared.m_ammoType)) |
| if (string.IsNullOrEmpty(weapon.m_shared.m_ammoType)) |
| { |
| { |
| return true; |
| return true; |
| } |
| } |
| ItemDrop.ItemData itemData = character.GetAmmoItem(); |
| ItemDrop.ItemData itemData = character.GetAmmoItem(); |
| if (itemData != null && (!character.GetInventory().ContainsItem(itemData) || itemData.m_shared.m_ammoType != weapon.m_shared.m_ammoType)) |
| if (itemData != null && (!character.GetInventory().ContainsItem(itemData) || itemData.m_shared.m_ammoType != weapon.m_shared.m_ammoType)) |
| { |
| { |
| itemData = null; |
| itemData = null; |
| } |
| } |
| if (itemData == null) |
| if (itemData == null) |
| { |
| { |
| itemData = character.GetInventory().GetAmmoItem(weapon.m_shared.m_ammoType, null); |
| itemData = character.GetInventory().GetAmmoItem(weapon.m_shared.m_ammoType, null); |
| } |
| } |
| if (itemData == null) |
| if (itemData == null) |
| { |
| { |
| character.Message(MessageHud.MessageType.Center, "$msg_outof " + weapon.m_shared.m_ammoType, 0, null); |
| character.Message(MessageHud.MessageType.Center, "$msg_outof " + weapon.m_shared.m_ammoType, 0, null); |
| return false; |
| return false; |
| } |
| } |
| return itemData.m_shared.m_itemType != ItemDrop.ItemData.ItemType.Consumable || character.CanConsumeItem(itemData, false); |
| return itemData.m_shared.m_itemType != ItemDrop.ItemData.ItemType.Consumable || character.CanConsumeItem(itemData, false); |
| } |
| } |
| |
| |
| private bool UseAmmo(out ItemDrop.ItemData ammoItem) |
| private bool UseAmmo(out ItemDrop.ItemData ammoItem) |
| { |
| { |
| this.m_ammoItem = null; |
| this.m_ammoItem = null; |
| ammoItem = null; |
| ammoItem = null; |
| if (string.IsNullOrEmpty(this.m_weapon.m_shared.m_ammoType)) |
| if (string.IsNullOrEmpty(this.m_weapon.m_shared.m_ammoType)) |
| { |
| { |
| return true; |
| return true; |
| } |
| } |
| ammoItem = this.m_character.GetAmmoItem(); |
| ammoItem = this.m_character.GetAmmoItem(); |
| if (ammoItem != null && (!this.m_character.GetInventory().ContainsItem(ammoItem) || ammoItem.m_shared.m_ammoType != this.m_weapon.m_shared.m_ammoType)) |
| if (ammoItem != null && (!this.m_character.GetInventory().ContainsItem(ammoItem) || ammoItem.m_shared.m_ammoType != this.m_weapon.m_shared.m_ammoType)) |
| { |
| { |
| ammoItem = null; |
| ammoItem = null; |
| } |
| } |
| if (ammoItem == null) |
| if (ammoItem == null) |
| { |
| { |
| ammoItem = this.m_character.GetInventory().GetAmmoItem(this.m_weapon.m_shared.m_ammoType, null); |
| ammoItem = this.m_character.GetInventory().GetAmmoItem(this.m_weapon.m_shared.m_ammoType, null); |
| } |
| } |
| if (ammoItem == null) |
| if (ammoItem == null) |
| { |
| { |
| this.m_character.Message(MessageHud.MessageType.Center, "$msg_outof " + this.m_weapon.m_shared.m_ammoType, 0, null); |
| this.m_character.Message(MessageHud.MessageType.Center, "$msg_outof " + this.m_weapon.m_shared.m_ammoType, 0, null); |
| return false; |
| return false; |
| } |
| } |
| if (ammoItem.m_shared.m_itemType == ItemDrop.ItemData.ItemType.Consumable) |
| if (ammoItem.m_shared.m_itemType == ItemDrop.ItemData.ItemType.Consumable) |
| { |
| { |
| bool flag = this.m_character.ConsumeItem(this.m_character.GetInventory(), ammoItem, false); |
| bool flag = this.m_character.ConsumeItem(this.m_character.GetInventory(), ammoItem, false); |
| if (flag) |
| if (flag) |
| { |
| { |
| this.m_ammoItem = ammoItem; |
| this.m_ammoItem = ammoItem; |
| } |
| } |
| return flag; |
| return flag; |
| } |
| } |
| this.m_character.GetInventory().RemoveItem(ammoItem, 1); |
| this.m_character.GetInventory().RemoveItem(ammoItem, 1); |
| this.m_ammoItem = ammoItem; |
| this.m_ammoItem = ammoItem; |
| return true; |
| return true; |
| } |
| } |
| |
| |
| private void ProjectileAttackTriggered() |
| private void ProjectileAttackTriggered() |
| { |
| { |
| Vector3 vector; |
| Vector3 vector; |
| Vector3 vector2; |
| Vector3 vector2; |
| this.GetProjectileSpawnPoint(out vector, out vector2); |
| this.GetProjectileSpawnPoint(out vector, out vector2); |
| this.m_weapon.m_shared.m_triggerEffect.Create(vector, Quaternion.LookRotation(vector2), null, 1f, -1); |
| this.m_weapon.m_shared.m_triggerEffect.Create(vector, Quaternion.LookRotation(vector2), null, 1f, -1); |
| this.m_triggerEffect.Create(vector, Quaternion.LookRotation(vector2), null, 1f, -1); |
| this.m_triggerEffect.Create(vector, Quaternion.LookRotation(vector2), null, 1f, -1); |
| if (this.m_weapon.m_shared.m_useDurability && this.m_character.IsPlayer()) |
| if (this.m_weapon.m_shared.m_useDurability && this.m_character.IsPlayer()) |
| { |
| { |
| this.m_weapon.m_durability -= this.m_weapon.m_shared.m_useDurabilityDrain; |
| this.m_weapon.m_durability -= this.m_weapon.m_shared.m_useDurabilityDrain; |
| } |
| } |
| if (this.m_projectileBursts == 1) |
| if (this.m_projectileBursts == 1) |
| { |
| { |
| this.FireProjectileBurst(); |
| this.FireProjectileBurst(); |
| return; |
| return; |
| } |
| } |
| this.m_projectileAttackStarted = true; |
| this.m_projectileAttackStarted = true; |
| } |
| } |
| |
| |
| private void UpdateProjectile(float dt) |
| private void UpdateProjectile(float dt) |
| { |
| { |
| if (this.m_projectileAttackStarted && this.m_projectileBurstsFired < this.m_projectileBursts) |
| if (this.m_projectileAttackStarted && this.m_projectileBurstsFired < this.m_projectileBursts) |
| { |
| { |
| this.m_projectileFireTimer -= dt; |
| this.m_projectileFireTimer -= dt; |
| if (this.m_projectileFireTimer <= 0f) |
| if (this.m_projectileFireTimer <= 0f) |
| { |
| { |
| this.m_projectileFireTimer = this.m_burstInterval; |
| this.m_projectileFireTimer = this.m_burstInterval; |
| this.FireProjectileBurst(); |
| this.FireProjectileBurst(); |
| this.m_projectileBurstsFired++; |
| this.m_projectileBurstsFired++; |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| |
| private Transform GetAttackOrigin() |
| private Transform GetAttackOrigin() |
| { |
| { |
| if (this.m_attackOriginJoint.Length > 0) |
| if (this.m_attackOriginJoint.Length > 0) |
| { |
| { |
| return Utils.FindChild(this.m_character.GetVisual().transform, this.m_attackOriginJoint, Utils.IterativeSearchType.DepthFirst); |
| return Utils.FindChild(this.m_character.GetVisual().transform, this.m_attackOriginJoint, Utils.IterativeSearchType.DepthFirst); |
| } |
| } |
| return this.m_character.transform; |
| return this.m_character.transform; |
| } |
| } |
| |
| |
| private void GetProjectileSpawnPoint(out Vector3 spawnPoint, out Vector3 aimDir) |
| private void GetProjectileSpawnPoint(out Vector3 spawnPoint, out Vector3 aimDir) |
| { |
| { |
| Transform attackOrigin = this.GetAttackOrigin(); |
| Transform attackOrigin = this.GetAttackOrigin(); |
| Transform transform = this.m_character.transform; |
| Transform transform = this.m_character.transform; |
| spawnPoint = attackOrigin.position + transform.up * this.m_attackHeight + transform.forward * this.m_attackRange + transform.right * this.m_attackOffset; |
| spawnPoint = attackOrigin.position + transform.up * this.m_attackHeight + transform.forward * this.m_attackRange + transform.right * this.m_attackOffset; |
| aimDir = this.m_character.GetAimDir(spawnPoint); |
| aimDir = this.m_character.GetAimDir(spawnPoint); |
| if (this.m_baseAI) |
| if (this.m_baseAI) |
| { |
| { |
| Character targetCreature = this.m_baseAI.GetTargetCreature(); |
| Character targetCreature = this.m_baseAI.GetTargetCreature(); |
| if (targetCreature) |
| if (targetCreature) |
| { |
| { |
| Vector3 normalized = (targetCreature.GetCenterPoint() - spawnPoint).normalized; |
| Vector3 normalized = (targetCreature.GetCenterPoint() - spawnPoint).normalized; |
| aimDir = Vector3.RotateTowards(this.m_character.transform.forward, normalized, 1.5707964f, 1f); |
| aimDir = Vector3.RotateTowards(this.m_character.transform.forward, normalized, 1.5707964f, 1f); |
| } |
| } |
| } |
| } |
| if (this.m_useCharacterFacing) |
| if (this.m_useCharacterFacing) |
| { |
| { |
| Vector3 forward = Vector3.forward; |
| Vector3 forward = Vector3.forward; |
| if (this.m_useCharacterFacingYAim) |
| if (this.m_useCharacterFacingYAim) |
| { |
| { |
| forward.y = aimDir.y; |
| forward.y = aimDir.y; |
| } |
| } |
| aimDir = transform.TransformDirection(forward); |
| aimDir = transform.TransformDirection(forward); |
| } |
| } |
| } |
| } |
| |
| |
| private void FireProjectileBurst() |
| private void FireProjectileBurst() |
| { |
| { |
| if (this.m_perBurstResourceUsage) |
| if (this.m_perBurstResourceUsage) |
| { |
| { |
| float attackStamina = this.GetAttackStamina(); |
| float attackStamina = this.GetAttackStamina(); |
| if (attackStamina > 0f) |
| if (attackStamina > 0f) |
| { |
| { |
| if (!this.m_character.HaveStamina(attackStamina)) |
| if (!this.m_character.HaveStamina(attackStamina)) |
| { |
| { |
| this.Stop(); |
| this.Stop(); |
| return; |
| return; |
| } |
| } |
| this.m_character.UseStamina(attackStamina, false); |
| this.m_character.UseStamina(attackStamina, false); |
| } |
| } |
| float attackEitr = this.GetAttackEitr(); |
| float attackEitr = this.GetAttackEitr(); |
| if (attackEitr > 0f) |
| if (attackEitr > 0f) |
| { |
| { |
| if (!this.m_character.HaveEitr(attackEitr)) |
| if (!this.m_character.HaveEitr(attackEitr)) |
| { |
| { |
| this.Stop(); |
| this.Stop(); |
| return; |
| return; |
| } |
| } |
| this.m_character.UseEitr(attackEitr); |
| this.m_character.UseEitr(attackEitr); |
| } |
| } |
| float attackHealth = this.GetAttackHealth(); |
| float attackHealth = this.GetAttackHealth(); |
| if (attackHealth > 0f) |
| if (attackHealth > 0f) |
| { |
| { |
| . | if (!this.m_character.HaveHealth(attackHealth)) |
| if (!this.m_character.HaveHealth(attackHealth) && this.m_attackHealthLowBlockUse) |
| { |
| { |
| this.Stop(); |
| this.Stop(); |
| return; |
| return; |
| } |
| } |
| . | this.m_character.UseHealth(attackHealth); |
| this.m_character.UseHealth(Mathf.Min(this.m_character.GetHealth() - 1f, attackHealth)); |
| } |
| } |
| } |
| } |
| ItemDrop.ItemData ammoItem = this.m_ammoItem; |
| ItemDrop.ItemData ammoItem = this.m_ammoItem; |
| GameObject gameObject = this.m_attackProjectile; |
| GameObject gameObject = this.m_attackProjectile; |
| float num = this.m_projectileVel; |
| float num = this.m_projectileVel; |
| float num2 = this.m_projectileVelMin; |
| float num2 = this.m_projectileVelMin; |
| float num3 = this.m_projectileAccuracy; |
| float num3 = this.m_projectileAccuracy; |
| float num4 = this.m_projectileAccuracyMin; |
| float num4 = this.m_projectileAccuracyMin; |
| float num5 = this.m_attackHitNoise; |
| float num5 = this.m_attackHitNoise; |
| . | |
| AnimationCurve animationCurve = this.m_drawVelocityCurve; |
| if (ammoItem != null && ammoItem.m_shared.m_attack.m_attackProjectile) |
| if (ammoItem != null && ammoItem.m_shared.m_attack.m_attackProjectile) |
| { |
| { |
| gameObject = ammoItem.m_shared.m_attack.m_attackProjectile; |
| gameObject = ammoItem.m_shared.m_attack.m_attackProjectile; |
| num += ammoItem.m_shared.m_attack.m_projectileVel; |
| num += ammoItem.m_shared.m_attack.m_projectileVel; |
| num2 += ammoItem.m_shared.m_attack.m_projectileVelMin; |
| num2 += ammoItem.m_shared.m_attack.m_projectileVelMin; |
| num3 += ammoItem.m_shared.m_attack.m_projectileAccuracy; |
| num3 += ammoItem.m_shared.m_attack.m_projectileAccuracy; |
| num4 += ammoItem.m_shared.m_attack.m_projectileAccuracyMin; |
| num4 += ammoItem.m_shared.m_attack.m_projectileAccuracyMin; |
| num5 += ammoItem.m_shared.m_attack.m_attackHitNoise; |
| num5 += ammoItem.m_shared.m_attack.m_attackHitNoise; |
| . | |
| animationCurve = ammoItem.m_shared.m_attack.m_drawVelocityCurve; |
| } |
| } |
| float num6 = this.m_character.GetRandomSkillFactor(this.m_weapon.m_shared.m_skillType); |
| float num6 = this.m_character.GetRandomSkillFactor(this.m_weapon.m_shared.m_skillType); |
| if (this.m_bowDraw) |
| if (this.m_bowDraw) |
| { |
| { |
| num3 = Mathf.Lerp(num4, num3, Mathf.Pow(this.m_attackDrawPercentage, 0.5f)); |
| num3 = Mathf.Lerp(num4, num3, Mathf.Pow(this.m_attackDrawPercentage, 0.5f)); |
| num6 *= this.m_attackDrawPercentage; |
| num6 *= this.m_attackDrawPercentage; |
| . | num = Mathf.Lerp(num2, num, this.m_attackDrawPercentage); |
| num = Mathf.Lerp(num2, num, animationCurve.Evaluate(this.m_attackDrawPercentage)); |
| Game.instance.IncrementPlayerStat(PlayerStatType.ArrowsShot, 1f); |
| Game.instance.IncrementPlayerStat(PlayerStatType.ArrowsShot, 1f); |
| } |
| } |
| else if (this.m_skillAccuracy) |
| else if (this.m_skillAccuracy) |
| { |
| { |
| float skillFactor = this.m_character.GetSkillFactor(this.m_weapon.m_shared.m_skillType); |
| float skillFactor = this.m_character.GetSkillFactor(this.m_weapon.m_shared.m_skillType); |
| num3 = Mathf.Lerp(num4, num3, skillFactor); |
| num3 = Mathf.Lerp(num4, num3, skillFactor); |
| } |
| } |
| Vector3 vector; |
| Vector3 vector; |
| Vector3 vector2; |
| Vector3 vector2; |
| this.GetProjectileSpawnPoint(out vector, out vector2); |
| this.GetProjectileSpawnPoint(out vector, out vector2); |
| if (this.m_launchAngle != 0f) |
| if (this.m_launchAngle != 0f) |
| { |
| { |
| Vector3 vector3 = Vector3.Cross(Vector3.up, vector2); |
| Vector3 vector3 = Vector3.Cross(Vector3.up, vector2); |
| vector2 = Quaternion.AngleAxis(this.m_launchAngle, vector3) * vector2; |
| vector2 = Quaternion.AngleAxis(this.m_launchAngle, vector3) * vector2; |
| } |
| } |
| if (this.m_burstEffect.HasEffects()) |
| if (this.m_burstEffect.HasEffects()) |
| { |
| { |
| this.m_burstEffect.Create(vector, Quaternion.LookRotation(vector2), null, 1f, -1); |
| this.m_burstEffect.Create(vector, Quaternion.LookRotation(vector2), null, 1f, -1); |
| } |
| } |
| for (int i = 0; i < this.m_projectiles; i++) |
| for (int i = 0; i < this.m_projectiles; i++) |
| { |
| { |
| if (this.m_destroyPreviousProjectile && this.m_weapon.m_lastProjectile) |
| if (this.m_destroyPreviousProjectile && this.m_weapon.m_lastProjectile) |
| { |
| { |
| ZNetScene.instance.Destroy(this.m_weapon.m_lastProjectile); |
| ZNetScene.instance.Destroy(this.m_weapon.m_lastProjectile); |
| this.m_weapon.m_lastProjectile = null; |
| this.m_weapon.m_lastProjectile = null; |
| } |
| } |
| Vector3 vector4 = vector2; |
| Vector3 vector4 = vector2; |
| . | |
| if (!this.m_bowDraw && this.m_randomVelocity) |
| |
| { |
| |
| num = UnityEngine.Random.Range(num2, num); |
| |
| } |
| Vector3 vector5 = Vector3.Cross(vector4, Vector3.up); |
| Vector3 vector5 = Vector3.Cross(vector4, Vector3.up); |
| Quaternion quaternion = Quaternion.AngleAxis(UnityEngine.Random.Range(-num3, num3), Vector3.up); |
| Quaternion quaternion = Quaternion.AngleAxis(UnityEngine.Random.Range(-num3, num3), Vector3.up); |
| . | |
| if (this.m_circularProjectileLaunch && !this.m_distributeProjectilesAroundCircle) |
| |
| { |
| |
| quaternion = Quaternion.AngleAxis(UnityEngine.Random.value * 360f, Vector3.up); |
| |
| } |
| |
| else if (this.m_circularProjectileLaunch && !this.m_distributeProjectilesAroundCircle) |
| |
| { |
| |
| quaternion = Quaternion.AngleAxis(UnityEngine.Random.Range(-num3, num3) + (float)(i * (360 / this.m_projectiles)), Vector3.up); |
| |
| } |
| vector4 = Quaternion.AngleAxis(UnityEngine.Random.Range(-num3, num3), vector5) * vector4; |
| vector4 = Quaternion.AngleAxis(UnityEngine.Random.Range(-num3, num3), vector5) * vector4; |
| vector4 = quaternion * vector4; |
| vector4 = quaternion * vector4; |
| GameObject gameObject2 = UnityEngine.Object.Instantiate<GameObject>(gameObject, vector, Quaternion.LookRotation(vector4)); |
| GameObject gameObject2 = UnityEngine.Object.Instantiate<GameObject>(gameObject, vector, Quaternion.LookRotation(vector4)); |
| HitData hitData = new HitData(); |
| HitData hitData = new HitData(); |
| hitData.m_toolTier = (short)this.m_weapon.m_shared.m_toolTier; |
| hitData.m_toolTier = (short)this.m_weapon.m_shared.m_toolTier; |
| hitData.m_pushForce = this.m_weapon.m_shared.m_attackForce * this.m_forceMultiplier; |
| hitData.m_pushForce = this.m_weapon.m_shared.m_attackForce * this.m_forceMultiplier; |
| hitData.m_backstabBonus = this.m_weapon.m_shared.m_backstabBonus; |
| hitData.m_backstabBonus = this.m_weapon.m_shared.m_backstabBonus; |
| hitData.m_staggerMultiplier = this.m_staggerMultiplier; |
| hitData.m_staggerMultiplier = this.m_staggerMultiplier; |
| hitData.m_damage.Add(this.m_weapon.GetDamage(), 1); |
| hitData.m_damage.Add(this.m_weapon.GetDamage(), 1); |
| . | hitData.m_statusEffectHash = (this.m_weapon.m_shared.m_attackStatusEffect ? this.m_weapon.m_shared.m_attackStatusEffect.NameHash() : 0); |
| hitData.m_statusEffectHash = ((this.m_weapon.m_shared.m_attackStatusEffect && (this.m_weapon.m_shared.m_attackStatusEffectChance == 1f || UnityEngine.Random.Range(0f, 1f) < this.m_weapon.m_shared.m_attackStatusEffectChance)) ? this.m_weapon.m_shared.m_attackStatusEffect.NameHash() : 0); |
| hitData.m_skillLevel = this.m_character.GetSkillLevel(this.m_weapon.m_shared.m_skillType); |
| hitData.m_skillLevel = this.m_character.GetSkillLevel(this.m_weapon.m_shared.m_skillType); |
| hitData.m_itemLevel = (short)this.m_weapon.m_quality; |
| hitData.m_itemLevel = (short)this.m_weapon.m_quality; |
| hitData.m_itemWorldLevel = (byte)this.m_weapon.m_worldLevel; |
| hitData.m_itemWorldLevel = (byte)this.m_weapon.m_worldLevel; |
| hitData.m_blockable = this.m_weapon.m_shared.m_blockable; |
| hitData.m_blockable = this.m_weapon.m_shared.m_blockable; |
| hitData.m_dodgeable = this.m_weapon.m_shared.m_dodgeable; |
| hitData.m_dodgeable = this.m_weapon.m_shared.m_dodgeable; |
| hitData.m_skill = this.m_weapon.m_shared.m_skillType; |
| hitData.m_skill = this.m_weapon.m_shared.m_skillType; |
| hitData.m_skillRaiseAmount = this.m_raiseSkillAmount; |
| hitData.m_skillRaiseAmount = this.m_raiseSkillAmount; |
| hitData.SetAttacker(this.m_character); |
| hitData.SetAttacker(this.m_character); |
| hitData.m_hitType = ((hitData.GetAttacker() is Player) ? HitData.HitType.PlayerHit : HitData.HitType.EnemyHit); |
| hitData.m_hitType = ((hitData.GetAttacker() is Player) ? HitData.HitType.PlayerHit : HitData.HitType.EnemyHit); |
| . | |
| hitData.m_healthReturn = this.m_attackHealthReturnHit; |
| if (ammoItem != null) |
| if (ammoItem != null) |
| { |
| { |
| hitData.m_damage.Add(ammoItem.GetDamage(), 1); |
| hitData.m_damage.Add(ammoItem.GetDamage(), 1); |
| hitData.m_pushForce += ammoItem.m_shared.m_attackForce; |
| hitData.m_pushForce += ammoItem.m_shared.m_attackForce; |
| . | if (ammoItem.m_shared.m_attackStatusEffect != null) |
| if (ammoItem.m_shared.m_attackStatusEffect != null && (ammoItem.m_shared.m_attackStatusEffectChance == 1f || UnityEngine.Random.Range(0f, 1f) < ammoItem.m_shared.m_attackStatusEffectChance)) |
| { |
| { |
| hitData.m_statusEffectHash = ammoItem.m_shared.m_attackStatusEffect.NameHash(); |
| hitData.m_statusEffectHash = ammoItem.m_shared.m_attackStatusEffect.NameHash(); |
| } |
| } |
| if (!ammoItem.m_shared.m_blockable) |
| if (!ammoItem.m_shared.m_blockable) |
| { |
| { |
| hitData.m_blockable = false; |
| hitData.m_blockable = false; |
| } |
| } |
| if (!ammoItem.m_shared.m_dodgeable) |
| if (!ammoItem.m_shared.m_dodgeable) |
| { |
| { |
| hitData.m_dodgeable = false; |
| hitData.m_dodgeable = false; |
| } |
| } |
| } |
| } |
| hitData.m_pushForce *= num6; |
| hitData.m_pushForce *= num6; |
| . | hitData.m_damage.Modify(this.m_damageMultiplier); |
| this.ModifyDamage(hitData, num6); |
| hitData.m_damage.Modify(num6); |
| |
| hitData.m_damage.Modify(this.GetLevelDamageFactor()); |
| |
| this.m_character.GetSEMan().ModifyAttack(this.m_weapon.m_shared.m_skillType, ref hitData); |
| this.m_character.GetSEMan().ModifyAttack(this.m_weapon.m_shared.m_skillType, ref hitData); |
| IProjectile component = gameObject2.GetComponent<IProjectile>(); |
| IProjectile component = gameObject2.GetComponent<IProjectile>(); |
| if (component != null) |
| if (component != null) |
| { |
| { |
| component.Setup(this.m_character, vector4 * num, num5, hitData, this.m_weapon, this.m_lastUsedAmmo); |
| component.Setup(this.m_character, vector4 * num, num5, hitData, this.m_weapon, this.m_lastUsedAmmo); |
| } |
| } |
| this.m_weapon.m_lastProjectile = gameObject2; |
| this.m_weapon.m_lastProjectile = gameObject2; |
| . | |
| if (this.m_spawnOnHitChance > 0f && this.m_spawnOnHit) |
| |
| { |
| |
| Projectile projectile = component as Projectile; |
| |
| if (projectile != null) |
| |
| { |
| |
| projectile.m_spawnOnHit = this.m_spawnOnHit; |
| |
| projectile.m_spawnOnHitChance = this.m_spawnOnHitChance; |
| |
| } |
| |
| } |
| |
| } |
| |
| } |
| |
| |
| |
| private void ModifyDamage(HitData hitData, float damageFactor = 1f) |
| |
| { |
| |
| if (this.m_damageMultiplier != 1f) |
| |
| { |
| |
| hitData.m_damage.Modify(this.m_damageMultiplier); |
| |
| } |
| |
| if (damageFactor != 1f) |
| |
| { |
| |
| hitData.m_damage.Modify(damageFactor); |
| |
| } |
| |
| hitData.m_damage.Modify(this.GetLevelDamageFactor()); |
| |
| if (this.m_damageMultiplierPerMissingHP > 0f) |
| |
| { |
| |
| hitData.m_damage.Modify(1f + (this.m_character.GetMaxHealth() - this.m_character.GetHealth()) * this.m_damageMultiplierPerMissingHP); |
| |
| } |
| |
| if (this.m_damageMultiplierByTotalHealthMissing > 0f) |
| |
| { |
| |
| hitData.m_damage.Modify(1f + (1f - this.m_character.GetHealthPercentage()) * this.m_damageMultiplierByTotalHealthMissing); |
| } |
| } |
| } |
| } |
| |
| |
| private void DoNonAttack() |
| private void DoNonAttack() |
| { |
| { |
| if (this.m_weapon.m_shared.m_useDurability && this.m_character.IsPlayer()) |
| if (this.m_weapon.m_shared.m_useDurability && this.m_character.IsPlayer()) |
| { |
| { |
| this.m_weapon.m_durability -= this.m_weapon.m_shared.m_useDurabilityDrain; |
| this.m_weapon.m_durability -= this.m_weapon.m_shared.m_useDurabilityDrain; |
| } |
| } |
| Transform attackOrigin = this.GetAttackOrigin(); |
| Transform attackOrigin = this.GetAttackOrigin(); |
| this.m_weapon.m_shared.m_triggerEffect.Create(attackOrigin.position, this.m_character.transform.rotation, attackOrigin, 1f, -1); |
| this.m_weapon.m_shared.m_triggerEffect.Create(attackOrigin.position, this.m_character.transform.rotation, attackOrigin, 1f, -1); |
| this.m_triggerEffect.Create(attackOrigin.position, this.m_character.transform.rotation, attackOrigin, 1f, -1); |
| this.m_triggerEffect.Create(attackOrigin.position, this.m_character.transform.rotation, attackOrigin, 1f, -1); |
| if (this.m_weapon.m_shared.m_consumeStatusEffect) |
| if (this.m_weapon.m_shared.m_consumeStatusEffect) |
| { |
| { |
| this.m_character.GetSEMan().AddStatusEffect(this.m_weapon.m_shared.m_consumeStatusEffect, true, 0, 0f); |
| this.m_character.GetSEMan().AddStatusEffect(this.m_weapon.m_shared.m_consumeStatusEffect, true, 0, 0f); |
| } |
| } |
| this.m_character.AddNoise(this.m_attackHitNoise); |
| this.m_character.AddNoise(this.m_attackHitNoise); |
| } |
| } |
| |
| |
| private float GetLevelDamageFactor() |
| private float GetLevelDamageFactor() |
| { |
| { |
| return 1f + (float)Mathf.Max(0, this.m_character.GetLevel() - 1) * 0.5f; |
| return 1f + (float)Mathf.Max(0, this.m_character.GetLevel() - 1) * 0.5f; |
| } |
| } |
| |
| |
| private void DoAreaAttack() |
| private void DoAreaAttack() |
| { |
| { |
| Transform transform = this.m_character.transform; |
| Transform transform = this.m_character.transform; |
| Transform attackOrigin = this.GetAttackOrigin(); |
| Transform attackOrigin = this.GetAttackOrigin(); |
| Vector3 vector = attackOrigin.position + Vector3.up * this.m_attackHeight + transform.forward * this.m_attackRange + transform.right * this.m_attackOffset; |
| Vector3 vector = attackOrigin.position + Vector3.up * this.m_attackHeight + transform.forward * this.m_attackRange + transform.right * this.m_attackOffset; |
| this.m_weapon.m_shared.m_triggerEffect.Create(vector, transform.rotation, attackOrigin, 1f, -1); |
| this.m_weapon.m_shared.m_triggerEffect.Create(vector, transform.rotation, attackOrigin, 1f, -1); |
| this.m_triggerEffect.Create(vector, transform.rotation, attackOrigin, 1f, -1); |
| this.m_triggerEffect.Create(vector, transform.rotation, attackOrigin, 1f, -1); |
| int num = 0; |
| int num = 0; |
| Vector3 vector2 = Vector3.zero; |
| Vector3 vector2 = Vector3.zero; |
| bool flag = false; |
| bool flag = false; |
| float randomSkillFactor = this.m_character.GetRandomSkillFactor(this.m_weapon.m_shared.m_skillType); |
| float randomSkillFactor = this.m_character.GetRandomSkillFactor(this.m_weapon.m_shared.m_skillType); |
| int num2 = (this.m_hitTerrain ? Attack.m_attackMaskTerrain : Attack.m_attackMask); |
| int num2 = (this.m_hitTerrain ? Attack.m_attackMaskTerrain : Attack.m_attackMask); |
| Collider[] array = Physics.OverlapSphere(vector, this.m_attackRayWidth, num2, QueryTriggerInteraction.UseGlobal); |
| Collider[] array = Physics.OverlapSphere(vector, this.m_attackRayWidth, num2, QueryTriggerInteraction.UseGlobal); |
| HashSet<GameObject> hashSet = new HashSet<GameObject>(); |
| HashSet<GameObject> hashSet = new HashSet<GameObject>(); |
| foreach (Collider collider in array) |
| foreach (Collider collider in array) |
| { |
| { |
| if (!(collider.gameObject == this.m_character.gameObject)) |
| if (!(collider.gameObject == this.m_character.gameObject)) |
| { |
| { |
| GameObject gameObject = Projectile.FindHitObject(collider); |
| GameObject gameObject = Projectile.FindHitObject(collider); |
| if (!(gameObject == this.m_character.gameObject) && !hashSet.Contains(gameObject)) |
| if (!(gameObject == this.m_character.gameObject) && !hashSet.Contains(gameObject)) |
| { |
| { |
| hashSet.Add(gameObject); |
| hashSet.Add(gameObject); |
| Vector3 vector3; |
| Vector3 vector3; |
| if (collider is MeshCollider) |
| if (collider is MeshCollider) |
| { |
| { |
| vector3 = collider.ClosestPointOnBounds(vector); |
| vector3 = collider.ClosestPointOnBounds(vector); |
| } |
| } |
| else |
| else |
| { |
| { |
| vector3 = collider.ClosestPoint(vector); |
| vector3 = collider.ClosestPoint(vector); |
| } |
| } |
| IDestructible component = gameObject.GetComponent<IDestructible>(); |
| IDestructible component = gameObject.GetComponent<IDestructible>(); |
| if (component != null) |
| if (component != null) |
| { |
| { |
| Vector3 vector4 = vector3 - vector; |
| Vector3 vector4 = vector3 - vector; |
| vector4.y = 0f; |
| vector4.y = 0f; |
| Vector3 vector5 = vector3 - transform.position; |
| Vector3 vector5 = vector3 - transform.position; |
| if (Vector3.Dot(vector5, vector4) < 0f) |
| if (Vector3.Dot(vector5, vector4) < 0f) |
| { |
| { |
| vector4 = vector5; |
| vector4 = vector5; |
| } |
| } |
| vector4.Normalize(); |
| vector4.Normalize(); |
| HitData hitData = new HitData(); |
| HitData hitData = new HitData(); |
| hitData.m_toolTier = (short)this.m_weapon.m_shared.m_toolTier; |
| hitData.m_toolTier = (short)this.m_weapon.m_shared.m_toolTier; |
| . | hitData.m_statusEffectHash = (this.m_weapon.m_shared.m_attackStatusEffect ? this.m_weapon.m_shared.m_attackStatusEffect.NameHash() : 0); |
| hitData.m_statusEffectHash = ((this.m_weapon.m_shared.m_attackStatusEffect && (this.m_weapon.m_shared.m_attackStatusEffectChance == 1f || UnityEngine.Random.Range(0f, 1f) < this.m_weapon.m_shared.m_attackStatusEffectChance)) ? this.m_weapon.m_shared.m_attackStatusEffect.NameHash() : 0); |
| hitData.m_skillLevel = this.m_character.GetSkillLevel(this.m_weapon.m_shared.m_skillType); |
| hitData.m_skillLevel = this.m_character.GetSkillLevel(this.m_weapon.m_shared.m_skillType); |
| hitData.m_itemLevel = (short)this.m_weapon.m_quality; |
| hitData.m_itemLevel = (short)this.m_weapon.m_quality; |
| hitData.m_itemWorldLevel = (byte)this.m_weapon.m_worldLevel; |
| hitData.m_itemWorldLevel = (byte)this.m_weapon.m_worldLevel; |
| hitData.m_pushForce = this.m_weapon.m_shared.m_attackForce * randomSkillFactor * this.m_forceMultiplier; |
| hitData.m_pushForce = this.m_weapon.m_shared.m_attackForce * randomSkillFactor * this.m_forceMultiplier; |
| hitData.m_backstabBonus = this.m_weapon.m_shared.m_backstabBonus; |
| hitData.m_backstabBonus = this.m_weapon.m_shared.m_backstabBonus; |
| hitData.m_staggerMultiplier = this.m_staggerMultiplier; |
| hitData.m_staggerMultiplier = this.m_staggerMultiplier; |
| hitData.m_dodgeable = this.m_weapon.m_shared.m_dodgeable; |
| hitData.m_dodgeable = this.m_weapon.m_shared.m_dodgeable; |
| hitData.m_blockable = this.m_weapon.m_shared.m_blockable; |
| hitData.m_blockable = this.m_weapon.m_shared.m_blockable; |
| hitData.m_skill = this.m_weapon.m_shared.m_skillType; |
| hitData.m_skill = this.m_weapon.m_shared.m_skillType; |
| hitData.m_skillRaiseAmount = this.m_raiseSkillAmount; |
| hitData.m_skillRaiseAmount = this.m_raiseSkillAmount; |
| hitData.m_damage.Add(this.m_weapon.GetDamage(), 1); |
| hitData.m_damage.Add(this.m_weapon.GetDamage(), 1); |
| hitData.m_point = vector3; |
| hitData.m_point = vector3; |
| hitData.m_dir = vector4; |
| hitData.m_dir = vector4; |
| hitData.m_hitCollider = collider; |
| hitData.m_hitCollider = collider; |
| hitData.SetAttacker(this.m_character); |
| hitData.SetAttacker(this.m_character); |
| hitData.m_hitType = ((hitData.GetAttacker() is Player) ? HitData.HitType.PlayerHit : HitData.HitType.EnemyHit); |
| hitData.m_hitType = ((hitData.GetAttacker() is Player) ? HitData.HitType.PlayerHit : HitData.HitType.EnemyHit); |
| . | hitData.m_damage.Modify(this.m_damageMultiplier); |
| hitData.m_healthReturn = this.m_attackHealthReturnHit; |
| hitData.m_damage.Modify(randomSkillFactor); |
| this.ModifyDamage(hitData, randomSkillFactor); |
| hitData.m_damage.Modify(this.GetLevelDamageFactor()); |
| this.SpawnOnHit(gameObject); |
| if (this.m_attackChainLevels > 1 && this.m_currentAttackCainLevel == this.m_attackChainLevels - 1 && this.m_lastChainDamageMultiplier > 1f) |
| if (this.m_attackChainLevels > 1 && this.m_currentAttackCainLevel == this.m_attackChainLevels - 1 && this.m_lastChainDamageMultiplier > 1f) |
| { |
| { |
| hitData.m_damage.Modify(this.m_lastChainDamageMultiplier); |
| hitData.m_damage.Modify(this.m_lastChainDamageMultiplier); |
| hitData.m_pushForce *= 1.2f; |
| hitData.m_pushForce *= 1.2f; |
| } |
| } |
| this.m_character.GetSEMan().ModifyAttack(this.m_weapon.m_shared.m_skillType, ref hitData); |
| this.m_character.GetSEMan().ModifyAttack(this.m_weapon.m_shared.m_skillType, ref hitData); |
| Character character = component as Character; |
| Character character = component as Character; |
| . | |
| bool flag2 = false; |
| if (character) |
| if (character) |
| { |
| { |
| . | bool flag2 = BaseAI.IsEnemy(this.m_character, character) || (character.GetBaseAI() && character.GetBaseAI().IsAggravatable() && this.m_character.IsPlayer()); |
| flag2 = BaseAI.IsEnemy(this.m_character, character) || (character.GetBaseAI() && character.GetBaseAI().IsAggravatable() && this.m_character.IsPlayer()); |
| if ((!this.m_character.IsPlayer() && !flag2) || (!this.m_weapon.m_shared.m_tamedOnly && this.m_character.IsPlayer() && !this.m_character.IsPVPEnabled() && !flag2) || (this.m_weapon.m_shared.m_tamedOnly && !character.IsTamed())) |
| if (((!this.m_hitFriendly || this.m_character.IsTamed()) && !this.m_character.IsPlayer() && !flag2) || (!this.m_weapon.m_shared.m_tamedOnly && this.m_character.IsPlayer() && !this.m_character.IsPVPEnabled() && !flag2) || (this.m_weapon.m_shared.m_tamedOnly && !character.IsTamed())) |
| { |
| { |
| . | goto IL_4F1; |
| goto IL_566; |
| } |
| } |
| if (hitData.m_dodgeable && character.IsDodgeInvincible()) |
| if (hitData.m_dodgeable && character.IsDodgeInvincible()) |
| { |
| { |
| . | goto IL_4F1; |
| goto IL_566; |
| } |
| } |
| } |
| } |
| else if (this.m_weapon.m_shared.m_tamedOnly) |
| else if (this.m_weapon.m_shared.m_tamedOnly) |
| { |
| { |
| . | goto IL_4F1; |
| goto IL_566; |
| |
| } |
| |
| if (this.m_attackHealthReturnHit > 0f && this.m_character && flag2) |
| |
| { |
| |
| this.m_character.Heal(this.m_attackHealthReturnHit, true); |
| } |
| } |
| component.Damage(hitData); |
| component.Damage(hitData); |
| if ((component.GetDestructibleType() & this.m_skillHitType) != DestructibleType.None) |
| if ((component.GetDestructibleType() & this.m_skillHitType) != DestructibleType.None) |
| { |
| { |
| flag = true; |
| flag = true; |
| } |
| } |
| } |
| } |
| num++; |
| num++; |
| vector2 += vector3; |
| vector2 += vector3; |
| } |
| } |
| } |
| } |
| . | IL_4F1:; |
| IL_566:; |
| } |
| } |
| if (num > 0) |
| if (num > 0) |
| { |
| { |
| vector2 /= (float)num; |
| vector2 /= (float)num; |
| this.m_weapon.m_shared.m_hitEffect.Create(vector2, Quaternion.identity, null, 1f, -1); |
| this.m_weapon.m_shared.m_hitEffect.Create(vector2, Quaternion.identity, null, 1f, -1); |
| this.m_hitEffect.Create(vector2, Quaternion.identity, null, 1f, -1); |
| this.m_hitEffect.Create(vector2, Quaternion.identity, null, 1f, -1); |
| if (this.m_weapon.m_shared.m_useDurability && this.m_character.IsPlayer()) |
| if (this.m_weapon.m_shared.m_useDurability && this.m_character.IsPlayer()) |
| { |
| { |
| this.m_weapon.m_durability -= 1f; |
| this.m_weapon.m_durability -= 1f; |
| } |
| } |
| this.m_character.AddNoise(this.m_attackHitNoise); |
| this.m_character.AddNoise(this.m_attackHitNoise); |
| if (flag) |
| if (flag) |
| { |
| { |
| this.m_character.RaiseSkill(this.m_weapon.m_shared.m_skillType, this.m_raiseSkillAmount); |
| this.m_character.RaiseSkill(this.m_weapon.m_shared.m_skillType, this.m_raiseSkillAmount); |
| } |
| } |
| } |
| } |
| if (this.m_spawnOnTrigger) |
| if (this.m_spawnOnTrigger) |
| { |
| { |
| IProjectile component2 = UnityEngine.Object.Instantiate<GameObject>(this.m_spawnOnTrigger, vector, Quaternion.identity).GetComponent<IProjectile>(); |
| IProjectile component2 = UnityEngine.Object.Instantiate<GameObject>(this.m_spawnOnTrigger, vector, Quaternion.identity).GetComponent<IProjectile>(); |
| if (component2 != null) |
| if (component2 != null) |
| { |
| { |
| component2.Setup(this.m_character, this.m_character.transform.forward, -1f, null, null, this.m_lastUsedAmmo); |
| component2.Setup(this.m_character, this.m_character.transform.forward, -1f, null, null, this.m_lastUsedAmmo); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| |
| private void GetMeleeAttackDir(out Transform originJoint, out Vector3 attackDir) |
| private void GetMeleeAttackDir(out Transform originJoint, out Vector3 attackDir) |
| { |
| { |
| originJoint = this.GetAttackOrigin(); |
| originJoint = this.GetAttackOrigin(); |
| Vector3 forward = this.m_character.transform.forward; |
| Vector3 forward = this.m_character.transform.forward; |
| Vector3 aimDir = this.m_character.GetAimDir(originJoint.position); |
| Vector3 aimDir = this.m_character.GetAimDir(originJoint.position); |
| aimDir.x = forward.x; |
| aimDir.x = forward.x; |
| aimDir.z = forward.z; |
| aimDir.z = forward.z; |
| aimDir.Normalize(); |
| aimDir.Normalize(); |
| attackDir = Vector3.RotateTowards(this.m_character.transform.forward, aimDir, 0.017453292f * this.m_maxYAngle, 10f); |
| attackDir = Vector3.RotateTowards(this.m_character.transform.forward, aimDir, 0.017453292f * this.m_maxYAngle, 10f); |
| } |
| } |
| |
| |
| private void AddHitPoint(List<Attack.HitPoint> list, GameObject go, Collider collider, Vector3 point, float distance, bool multiCollider) |
| private void AddHitPoint(List<Attack.HitPoint> list, GameObject go, Collider collider, Vector3 point, float distance, bool multiCollider) |
| { |
| { |
| Attack.HitPoint hitPoint = null; |
| Attack.HitPoint hitPoint = null; |
| for (int i = list.Count - 1; i >= 0; i--) |
| for (int i = list.Count - 1; i >= 0; i--) |
| { |
| { |
| if ((!multiCollider && list[i].go == go) || (multiCollider && list[i].collider == collider)) |
| if ((!multiCollider && list[i].go == go) || (multiCollider && list[i].collider == collider)) |
| { |
| { |
| hitPoint = list[i]; |
| hitPoint = list[i]; |
| break; |
| break; |
| } |
| } |
| } |
| } |
| if (hitPoint == null) |
| if (hitPoint == null) |
| { |
| { |
| hitPoint = new Attack.HitPoint(); |
| hitPoint = new Attack.HitPoint(); |
| hitPoint.go = go; |
| hitPoint.go = go; |
| hitPoint.collider = collider; |
| hitPoint.collider = collider; |
| hitPoint.firstPoint = point; |
| hitPoint.firstPoint = point; |
| list.Add(hitPoint); |
| list.Add(hitPoint); |
| } |
| } |
| hitPoint.avgPoint += point; |
| hitPoint.avgPoint += point; |
| hitPoint.count++; |
| hitPoint.count++; |
| if (distance < hitPoint.closestDistance) |
| if (distance < hitPoint.closestDistance) |
| { |
| { |
| hitPoint.closestPoint = point; |
| hitPoint.closestPoint = point; |
| hitPoint.closestDistance = distance; |
| hitPoint.closestDistance = distance; |
| } |
| } |
| } |
| } |
| |
| |
| private void DoMeleeAttack() |
| private void DoMeleeAttack() |
| { |
| { |
| Transform transform; |
| Transform transform; |
| Vector3 vector; |
| Vector3 vector; |
| this.GetMeleeAttackDir(out transform, out vector); |
| this.GetMeleeAttackDir(out transform, out vector); |
| Vector3 vector2 = this.m_character.transform.InverseTransformDirection(vector); |
| Vector3 vector2 = this.m_character.transform.InverseTransformDirection(vector); |
| Quaternion quaternion = Quaternion.LookRotation(vector, Vector3.up); |
| Quaternion quaternion = Quaternion.LookRotation(vector, Vector3.up); |
| this.m_weapon.m_shared.m_triggerEffect.Create(transform.position, quaternion, transform, 1f, -1); |
| this.m_weapon.m_shared.m_triggerEffect.Create(transform.position, quaternion, transform, 1f, -1); |
| this.m_triggerEffect.Create(transform.position, quaternion, transform, 1f, -1); |
| this.m_triggerEffect.Create(transform.position, quaternion, transform, 1f, -1); |
| Vector3 vector3 = transform.position + Vector3.up * this.m_attackHeight + this.m_character.transform.right * this.m_attackOffset; |
| Vector3 vector3 = transform.position + Vector3.up * this.m_attackHeight + this.m_character.transform.right * this.m_attackOffset; |
| float num = this.m_attackAngle / 2f; |
| float num = this.m_attackAngle / 2f; |
| float num2 = 4f; |
| float num2 = 4f; |
| float attackRange = this.m_attackRange; |
| float attackRange = this.m_attackRange; |
| List<Attack.HitPoint> list = new List<Attack.HitPoint>(); |
| List<Attack.HitPoint> list = new List<Attack.HitPoint>(); |
| HashSet<Skills.SkillType> hashSet = new HashSet<Skills.SkillType>(); |
| HashSet<Skills.SkillType> hashSet = new HashSet<Skills.SkillType>(); |
| int num3 = (this.m_hitTerrain ? Attack.m_attackMaskTerrain : Attack.m_attackMask); |
| int num3 = (this.m_hitTerrain ? Attack.m_attackMaskTerrain : Attack.m_attackMask); |
| for (float num4 = -num; num4 <= num; num4 += num2) |
| for (float num4 = -num; num4 <= num; num4 += num2) |
| { |
| { |
| Quaternion quaternion2 = Quaternion.identity; |
| Quaternion quaternion2 = Quaternion.identity; |
| if (this.m_attackType == Attack.AttackType.Horizontal) |
| if (this.m_attackType == Attack.AttackType.Horizontal) |
| { |
| { |
| quaternion2 = Quaternion.Euler(0f, -num4, 0f); |
| quaternion2 = Quaternion.Euler(0f, -num4, 0f); |
| } |
| } |
| else if (this.m_attackType == Attack.AttackType.Vertical) |
| else if (this.m_attackType == Attack.AttackType.Vertical) |
| { |
| { |
| quaternion2 = Quaternion.Euler(num4, 0f, 0f); |
| quaternion2 = Quaternion.Euler(num4, 0f, 0f); |
| } |
| } |
| Vector3 vector4 = this.m_character.transform.TransformDirection(quaternion2 * vector2); |
| Vector3 vector4 = this.m_character.transform.TransformDirection(quaternion2 * vector2); |
| Debug.DrawLine(vector3, vector3 + vector4 * attackRange); |
| Debug.DrawLine(vector3, vector3 + vector4 * attackRange); |
| RaycastHit[] array; |
| RaycastHit[] array; |
| if (this.m_attackRayWidth > 0f) |
| if (this.m_attackRayWidth > 0f) |
| { |
| { |
| array = Physics.SphereCastAll(vector3, this.m_attackRayWidth, vector4, Mathf.Max(0f, attackRange - this.m_attackRayWidth), num3, QueryTriggerInteraction.Ignore); |
| array = Physics.SphereCastAll(vector3, this.m_attackRayWidth, vector4, Mathf.Max(0f, attackRange - this.m_attackRayWidth), num3, QueryTriggerInteraction.Ignore); |
| } |
| } |
| else |
| else |
| { |
| { |
| array = Physics.RaycastAll(vector3, vector4, attackRange, num3, QueryTriggerInteraction.Ignore); |
| array = Physics.RaycastAll(vector3, vector4, attackRange, num3, QueryTriggerInteraction.Ignore); |
| } |
| } |
| Array.Sort<RaycastHit>(array, (RaycastHit x, RaycastHit y) => x.distance.CompareTo(y.distance)); |
| Array.Sort<RaycastHit>(array, (RaycastHit x, RaycastHit y) => x.distance.CompareTo(y.distance)); |
| foreach (RaycastHit raycastHit in array) |
| foreach (RaycastHit raycastHit in array) |
| { |
| { |
| if (!(raycastHit.collider.gameObject == this.m_character.gameObject)) |
| if (!(raycastHit.collider.gameObject == this.m_character.gameObject)) |
| { |
| { |
| Vector3 vector5 = raycastHit.point; |
| Vector3 vector5 = raycastHit.point; |
| if (raycastHit.normal == -vector4 && raycastHit.point == Vector3.zero) |
| if (raycastHit.normal == -vector4 && raycastHit.point == Vector3.zero) |
| { |
| { |
| if (raycastHit.collider is MeshCollider) |
| if (raycastHit.collider is MeshCollider) |
| { |
| { |
| vector5 = vector3 + vector4 * attackRange; |
| vector5 = vector3 + vector4 * attackRange; |
| } |
| } |
| else |
| else |
| { |
| { |
| vector5 = raycastHit.collider.ClosestPoint(vector3); |
| vector5 = raycastHit.collider.ClosestPoint(vector3); |
| } |
| } |
| } |
| } |
| if (this.m_attackAngle >= 180f || Vector3.Dot(vector5 - vector3, vector) > 0f) |
| if (this.m_attackAngle >= 180f || Vector3.Dot(vector5 - vector3, vector) > 0f) |
| { |
| { |
| GameObject gameObject = Projectile.FindHitObject(raycastHit.collider); |
| GameObject gameObject = Projectile.FindHitObject(raycastHit.collider); |
| if (!(gameObject == this.m_character.gameObject)) |
| if (!(gameObject == this.m_character.gameObject)) |
| { |
| { |
| Vagon component = gameObject.GetComponent<Vagon>(); |
| Vagon component = gameObject.GetComponent<Vagon>(); |
| if (!component || !component.IsAttached(this.m_character)) |
| if (!component || !component.IsAttached(this.m_character)) |
| { |
| { |
| Character component2 = gameObject.GetComponent<Character>(); |
| Character component2 = gameObject.GetComponent<Character>(); |
| if (component2 != null) |
| if (component2 != null) |
| { |
| { |
| bool flag = BaseAI.IsEnemy(this.m_character, component2) || (component2.GetBaseAI() && component2.GetBaseAI().IsAggravatable() && this.m_character.IsPlayer()); |
| bool flag = BaseAI.IsEnemy(this.m_character, component2) || (component2.GetBaseAI() && component2.GetBaseAI().IsAggravatable() && this.m_character.IsPlayer()); |
| . | if ((!this.m_character.IsPlayer() && !flag) || (!this.m_weapon.m_shared.m_tamedOnly && this.m_character.IsPlayer() && !this.m_character.IsPVPEnabled() && !flag) || (this.m_weapon.m_shared.m_tamedOnly && !component2.IsTamed())) |
| if (((!this.m_hitFriendly || this.m_character.IsTamed()) && !this.m_character.IsPlayer() && !flag) || (!this.m_weapon.m_shared.m_tamedOnly && this.m_character.IsPlayer() && !this.m_character.IsPVPEnabled() && !flag) || (this.m_weapon.m_shared.m_tamedOnly && !component2.IsTamed())) |
| { |
| { |
| . | goto IL_409; |
| goto IL_41E; |
| } |
| } |
| if (this.m_weapon.m_shared.m_dodgeable && component2.IsDodgeInvincible()) |
| if (this.m_weapon.m_shared.m_dodgeable && component2.IsDodgeInvincible()) |
| { |
| { |
| . | goto IL_409; |
| goto IL_41E; |
| } |
| } |
| } |
| } |
| else if (this.m_weapon.m_shared.m_tamedOnly) |
| else if (this.m_weapon.m_shared.m_tamedOnly) |
| { |
| { |
| . | goto IL_409; |
| goto IL_41E; |
| } |
| } |
| bool flag2 = this.m_pickaxeSpecial && (gameObject.GetComponent<MineRock5>() || gameObject.GetComponent<MineRock>()); |
| bool flag2 = this.m_pickaxeSpecial && (gameObject.GetComponent<MineRock5>() || gameObject.GetComponent<MineRock>()); |
| this.AddHitPoint(list, gameObject, raycastHit.collider, vector5, raycastHit.distance, flag2); |
| this.AddHitPoint(list, gameObject, raycastHit.collider, vector5, raycastHit.distance, flag2); |
| if (!this.m_hitThroughWalls) |
| if (!this.m_hitThroughWalls) |
| { |
| { |
| break; |
| break; |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| . | IL_409:; |
| IL_41E:; |
| } |
| } |
| } |
| } |
| int num5 = 0; |
| int num5 = 0; |
| Vector3 vector6 = Vector3.zero; |
| Vector3 vector6 = Vector3.zero; |
| bool flag3 = false; |
| bool flag3 = false; |
| Character character = null; |
| Character character = null; |
| bool flag4 = false; |
| bool flag4 = false; |
| foreach (Attack.HitPoint hitPoint in list) |
| foreach (Attack.HitPoint hitPoint in list) |
| { |
| { |
| GameObject go = hitPoint.go; |
| GameObject go = hitPoint.go; |
| Vector3 vector7 = hitPoint.avgPoint / (float)hitPoint.count; |
| Vector3 vector7 = hitPoint.avgPoint / (float)hitPoint.count; |
| Vector3 vector8 = vector7; |
| Vector3 vector8 = vector7; |
| switch (this.m_hitPointtype) |
| switch (this.m_hitPointtype) |
| { |
| { |
| case Attack.HitPointType.Closest: |
| case Attack.HitPointType.Closest: |
| vector8 = hitPoint.closestPoint; |
| vector8 = hitPoint.closestPoint; |
| break; |
| break; |
| case Attack.HitPointType.Average: |
| case Attack.HitPointType.Average: |
| vector8 = vector7; |
| vector8 = vector7; |
| break; |
| break; |
| case Attack.HitPointType.First: |
| case Attack.HitPointType.First: |
| vector8 = hitPoint.firstPoint; |
| vector8 = hitPoint.firstPoint; |
| break; |
| break; |
| } |
| } |
| num5++; |
| num5++; |
| vector6 += vector7; |
| vector6 += vector7; |
| this.m_weapon.m_shared.m_hitEffect.Create(vector8, Quaternion.identity, null, 1f, -1); |
| this.m_weapon.m_shared.m_hitEffect.Create(vector8, Quaternion.identity, null, 1f, -1); |
| this.m_hitEffect.Create(vector8, Quaternion.identity, null, 1f, -1); |
| this.m_hitEffect.Create(vector8, Quaternion.identity, null, 1f, -1); |
| IDestructible component3 = go.GetComponent<IDestructible>(); |
| IDestructible component3 = go.GetComponent<IDestructible>(); |
| if (component3 != null) |
| if (component3 != null) |
| { |
| { |
| DestructibleType destructibleType = component3.GetDestructibleType(); |
| DestructibleType destructibleType = component3.GetDestructibleType(); |
| Skills.SkillType skillType = this.m_weapon.m_shared.m_skillType; |
| Skills.SkillType skillType = this.m_weapon.m_shared.m_skillType; |
| if (this.m_specialHitSkill != Skills.SkillType.None && (destructibleType & this.m_specialHitType) != DestructibleType.None) |
| if (this.m_specialHitSkill != Skills.SkillType.None && (destructibleType & this.m_specialHitType) != DestructibleType.None) |
| { |
| { |
| skillType = this.m_specialHitSkill; |
| skillType = this.m_specialHitSkill; |
| hashSet.Add(this.m_specialHitSkill); |
| hashSet.Add(this.m_specialHitSkill); |
| } |
| } |
| else if ((destructibleType & this.m_skillHitType) != DestructibleType.None) |
| else if ((destructibleType & this.m_skillHitType) != DestructibleType.None) |
| { |
| { |
| hashSet.Add(skillType); |
| hashSet.Add(skillType); |
| } |
| } |
| float num6 = this.m_character.GetRandomSkillFactor(skillType); |
| float num6 = this.m_character.GetRandomSkillFactor(skillType); |
| if (this.m_multiHit && this.m_lowerDamagePerHit && list.Count > 1) |
| if (this.m_multiHit && this.m_lowerDamagePerHit && list.Count > 1) |
| { |
| { |
| num6 /= (float)list.Count * 0.75f; |
| num6 /= (float)list.Count * 0.75f; |
| } |
| } |
| HitData hitData = new HitData(); |
| HitData hitData = new HitData(); |
| hitData.m_toolTier = (short)this.m_weapon.m_shared.m_toolTier; |
| hitData.m_toolTier = (short)this.m_weapon.m_shared.m_toolTier; |
| . | hitData.m_statusEffectHash = (this.m_weapon.m_shared.m_attackStatusEffect ? this.m_weapon.m_shared.m_attackStatusEffect.NameHash() : 0); |
| hitData.m_statusEffectHash = ((this.m_weapon.m_shared.m_attackStatusEffect && (this.m_weapon.m_shared.m_attackStatusEffectChance == 1f || UnityEngine.Random.Range(0f, 1f) < this.m_weapon.m_shared.m_attackStatusEffectChance)) ? this.m_weapon.m_shared.m_attackStatusEffect.NameHash() : 0); |
| hitData.m_skillLevel = this.m_character.GetSkillLevel(this.m_weapon.m_shared.m_skillType); |
| hitData.m_skillLevel = this.m_character.GetSkillLevel(this.m_weapon.m_shared.m_skillType); |
| hitData.m_itemLevel = (short)this.m_weapon.m_quality; |
| hitData.m_itemLevel = (short)this.m_weapon.m_quality; |
| hitData.m_itemWorldLevel = (byte)this.m_weapon.m_worldLevel; |
| hitData.m_itemWorldLevel = (byte)this.m_weapon.m_worldLevel; |
| hitData.m_pushForce = this.m_weapon.m_shared.m_attackForce * num6 * this.m_forceMultiplier; |
| hitData.m_pushForce = this.m_weapon.m_shared.m_attackForce * num6 * this.m_forceMultiplier; |
| hitData.m_backstabBonus = this.m_weapon.m_shared.m_backstabBonus; |
| hitData.m_backstabBonus = this.m_weapon.m_shared.m_backstabBonus; |
| hitData.m_staggerMultiplier = this.m_staggerMultiplier; |
| hitData.m_staggerMultiplier = this.m_staggerMultiplier; |
| hitData.m_dodgeable = this.m_weapon.m_shared.m_dodgeable; |
| hitData.m_dodgeable = this.m_weapon.m_shared.m_dodgeable; |
| hitData.m_blockable = this.m_weapon.m_shared.m_blockable; |
| hitData.m_blockable = this.m_weapon.m_shared.m_blockable; |
| hitData.m_skill = skillType; |
| hitData.m_skill = skillType; |
| hitData.m_skillRaiseAmount = this.m_raiseSkillAmount; |
| hitData.m_skillRaiseAmount = this.m_raiseSkillAmount; |
| hitData.m_damage = this.m_weapon.GetDamage(); |
| hitData.m_damage = this.m_weapon.GetDamage(); |
| hitData.m_point = vector8; |
| hitData.m_point = vector8; |
| hitData.m_dir = (vector8 - vector3).normalized; |
| hitData.m_dir = (vector8 - vector3).normalized; |
| hitData.m_hitCollider = hitPoint.collider; |
| hitData.m_hitCollider = hitPoint.collider; |
| hitData.SetAttacker(this.m_character); |
| hitData.SetAttacker(this.m_character); |
| . | hitData.m_damage.Modify(this.m_damageMultiplier); |
| |
| hitData.m_damage.Modify(num6); |
| |
| hitData.m_damage.Modify(this.GetLevelDamageFactor()); |
| |
| hitData.m_hitType = ((hitData.GetAttacker() is Player) ? HitData.HitType.PlayerHit : HitData.HitType.EnemyHit); |
| hitData.m_hitType = ((hitData.GetAttacker() is Player) ? HitData.HitType.PlayerHit : HitData.HitType.EnemyHit); |
| . | |
| hitData.m_healthReturn = this.m_attackHealthReturnHit; |
| |
| this.ModifyDamage(hitData, num6); |
| |
| this.SpawnOnHit(go); |
| if (this.m_attackChainLevels > 1 && this.m_currentAttackCainLevel == this.m_attackChainLevels - 1) |
| if (this.m_attackChainLevels > 1 && this.m_currentAttackCainLevel == this.m_attackChainLevels - 1) |
| { |
| { |
| hitData.m_damage.Modify(2f); |
| hitData.m_damage.Modify(2f); |
| hitData.m_pushForce *= 1.2f; |
| hitData.m_pushForce *= 1.2f; |
| } |
| } |
| this.m_character.GetSEMan().ModifyAttack(skillType, ref hitData); |
| this.m_character.GetSEMan().ModifyAttack(skillType, ref hitData); |
| if (component3 is Character) |
| if (component3 is Character) |
| { |
| { |
| character = component3 as Character; |
| character = component3 as Character; |
| } |
| } |
| component3.Damage(hitData); |
| component3.Damage(hitData); |
| . | |
| if (this.m_attackHealthReturnHit > 0f && this.m_character && character) |
| |
| { |
| |
| this.m_character.Heal(this.m_attackHealthReturnHit, true); |
| |
| } |
| if ((destructibleType & this.m_resetChainIfHit) != DestructibleType.None) |
| if ((destructibleType & this.m_resetChainIfHit) != DestructibleType.None) |
| { |
| { |
| this.m_nextAttackChainLevel = 0; |
| this.m_nextAttackChainLevel = 0; |
| } |
| } |
| if (!this.m_multiHit) |
| if (!this.m_multiHit) |
| { |
| { |
| break; |
| break; |
| } |
| } |
| } |
| } |
| if (go.GetComponent<Heightmap>() != null && !flag3 && (!this.m_pickaxeSpecial || !flag4)) |
| if (go.GetComponent<Heightmap>() != null && !flag3 && (!this.m_pickaxeSpecial || !flag4)) |
| { |
| { |
| flag3 = true; |
| flag3 = true; |
| this.m_weapon.m_shared.m_hitTerrainEffect.Create(vector8, quaternion, null, 1f, -1); |
| this.m_weapon.m_shared.m_hitTerrainEffect.Create(vector8, quaternion, null, 1f, -1); |
| this.m_hitTerrainEffect.Create(vector8, quaternion, null, 1f, -1); |
| this.m_hitTerrainEffect.Create(vector8, quaternion, null, 1f, -1); |
| if (this.m_weapon.m_shared.m_spawnOnHitTerrain) |
| if (this.m_weapon.m_shared.m_spawnOnHitTerrain) |
| { |
| { |
| . | this.SpawnOnHitTerrain(vector8, this.m_weapon.m_shared.m_spawnOnHitTerrain); |
| Attack.SpawnOnHitTerrain(vector8, this.m_weapon.m_shared.m_spawnOnHitTerrain, this.m_character, this.m_attackHitNoise, this.m_weapon, this.m_lastUsedAmmo, false); |
| } |
| } |
| if (!this.m_multiHit) |
| if (!this.m_multiHit) |
| { |
| { |
| break; |
| break; |
| } |
| } |
| if (this.m_pickaxeSpecial) |
| if (this.m_pickaxeSpecial) |
| { |
| { |
| break; |
| break; |
| } |
| } |
| } |
| } |
| else |
| else |
| { |
| { |
| flag4 = true; |
| flag4 = true; |
| } |
| } |
| } |
| } |
| if (num5 > 0) |
| if (num5 > 0) |
| { |
| { |
| vector6 /= (float)num5; |
| vector6 /= (float)num5; |
| if (this.m_weapon.m_shared.m_useDurability && this.m_character.IsPlayer()) |
| if (this.m_weapon.m_shared.m_useDurability && this.m_character.IsPlayer()) |
| { |
| { |
| this.m_weapon.m_durability -= this.m_weapon.m_shared.m_useDurabilityDrain; |
| this.m_weapon.m_durability -= this.m_weapon.m_shared.m_useDurabilityDrain; |
| } |
| } |
| this.m_character.AddNoise(this.m_attackHitNoise); |
| this.m_character.AddNoise(this.m_attackHitNoise); |
| this.m_character.FreezeFrame(0.15f); |
| this.m_character.FreezeFrame(0.15f); |
| if (this.m_weapon.m_shared.m_spawnOnHit) |
| if (this.m_weapon.m_shared.m_spawnOnHit) |
| { |
| { |
| IProjectile component4 = UnityEngine.Object.Instantiate<GameObject>(this.m_weapon.m_shared.m_spawnOnHit, vector6, quaternion).GetComponent<IProjectile>(); |
| IProjectile component4 = UnityEngine.Object.Instantiate<GameObject>(this.m_weapon.m_shared.m_spawnOnHit, vector6, quaternion).GetComponent<IProjectile>(); |
| if (component4 != null) |
| if (component4 != null) |
| { |
| { |
| component4.Setup(this.m_character, Vector3.zero, this.m_attackHitNoise, null, this.m_weapon, this.m_lastUsedAmmo); |
| component4.Setup(this.m_character, Vector3.zero, this.m_attackHitNoise, null, this.m_weapon, this.m_lastUsedAmmo); |
| } |
| } |
| } |
| } |
| foreach (Skills.SkillType skillType2 in hashSet) |
| foreach (Skills.SkillType skillType2 in hashSet) |
| { |
| { |
| this.m_character.RaiseSkill(skillType2, this.m_raiseSkillAmount * ((character != null) ? 1.5f : 1f)); |
| this.m_character.RaiseSkill(skillType2, this.m_raiseSkillAmount * ((character != null) ? 1.5f : 1f)); |
| } |
| } |
| if (this.m_attach && !this.m_isAttached && character) |
| if (this.m_attach && !this.m_isAttached && character) |
| { |
| { |
| this.TryAttach(character, vector6); |
| this.TryAttach(character, vector6); |
| } |
| } |
| } |
| } |
| if (this.m_spawnOnTrigger) |
| if (this.m_spawnOnTrigger) |
| { |
| { |
| IProjectile component5 = UnityEngine.Object.Instantiate<GameObject>(this.m_spawnOnTrigger, vector3, Quaternion.identity).GetComponent<IProjectile>(); |
| IProjectile component5 = UnityEngine.Object.Instantiate<GameObject>(this.m_spawnOnTrigger, vector3, Quaternion.identity).GetComponent<IProjectile>(); |
| if (component5 != null) |
| if (component5 != null) |
| { |
| { |
| component5.Setup(this.m_character, this.m_character.transform.forward, -1f, null, this.m_weapon, this.m_lastUsedAmmo); |
| component5.Setup(this.m_character, this.m_character.transform.forward, -1f, null, this.m_weapon, this.m_lastUsedAmmo); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| |
| . | |
| private void SpawnOnHit(GameObject target) |
| |
| { |
| |
| if (this.m_spawnOnHitChance > 0f && this.m_spawnOnHit && UnityEngine.Random.Range(0f, 1f) < this.m_spawnOnHitChance) |
| |
| { |
| |
| IProjectile componentInChildren = UnityEngine.Object.Instantiate<GameObject>(this.m_spawnOnHit, target.transform.position, target.transform.rotation).GetComponentInChildren<IProjectile>(); |
| |
| if (componentInChildren != null) |
| |
| { |
| |
| componentInChildren.Setup(this.m_character, this.m_character.transform.forward, -1f, null, this.m_weapon, this.m_lastUsedAmmo); |
| |
| } |
| |
| } |
| |
| } |
| |
| |
| private bool TryAttach(Character hitCharacter, Vector3 hitPoint) |
| private bool TryAttach(Character hitCharacter, Vector3 hitPoint) |
| { |
| { |
| if (hitCharacter.IsDodgeInvincible()) |
| if (hitCharacter.IsDodgeInvincible()) |
| { |
| { |
| return false; |
| return false; |
| } |
| } |
| if (hitCharacter.IsBlocking()) |
| if (hitCharacter.IsBlocking()) |
| { |
| { |
| Vector3 vector = hitCharacter.transform.position - this.m_character.transform.position; |
| Vector3 vector = hitCharacter.transform.position - this.m_character.transform.position; |
| vector.y = 0f; |
| vector.y = 0f; |
| vector.Normalize(); |
| vector.Normalize(); |
| if (Vector3.Dot(vector, hitCharacter.transform.forward) < 0f) |
| if (Vector3.Dot(vector, hitCharacter.transform.forward) < 0f) |
| { |
| { |
| return false; |
| return false; |
| } |
| } |
| } |
| } |
| this.m_isAttached = true; |
| this.m_isAttached = true; |
| this.m_attachTarget = hitCharacter.transform; |
| this.m_attachTarget = hitCharacter.transform; |
| float num = hitCharacter.GetRadius() + this.m_character.GetRadius() + 0.1f; |
| float num = hitCharacter.GetRadius() + this.m_character.GetRadius() + 0.1f; |
| Vector3 vector2 = hitCharacter.transform.position - this.m_character.transform.position; |
| Vector3 vector2 = hitCharacter.transform.position - this.m_character.transform.position; |
| vector2.y = 0f; |
| vector2.y = 0f; |
| vector2.Normalize(); |
| vector2.Normalize(); |
| this.m_attachDistance = num; |
| this.m_attachDistance = num; |
| Vector3 vector3 = hitCharacter.GetCenterPoint() - vector2 * num; |
| Vector3 vector3 = hitCharacter.GetCenterPoint() - vector2 * num; |
| this.m_attachOffset = this.m_attachTarget.InverseTransformPoint(vector3); |
| this.m_attachOffset = this.m_attachTarget.InverseTransformPoint(vector3); |
| hitPoint.y = Mathf.Clamp(hitPoint.y, hitCharacter.transform.position.y + hitCharacter.GetRadius(), hitCharacter.transform.position.y + hitCharacter.GetHeight() - hitCharacter.GetRadius() * 1.5f); |
| hitPoint.y = Mathf.Clamp(hitPoint.y, hitCharacter.transform.position.y + hitCharacter.GetRadius(), hitCharacter.transform.position.y + hitCharacter.GetHeight() - hitCharacter.GetRadius() * 1.5f); |
| this.m_attachHitPoint = this.m_attachTarget.InverseTransformPoint(hitPoint); |
| this.m_attachHitPoint = this.m_attachTarget.InverseTransformPoint(hitPoint); |
| this.m_zanim.SetTrigger("attach"); |
| this.m_zanim.SetTrigger("attach"); |
| return true; |
| return true; |
| } |
| } |
| |
| |
| private void UpdateAttach(float dt) |
| private void UpdateAttach(float dt) |
| { |
| { |
| if (this.m_attachTarget) |
| if (this.m_attachTarget) |
| { |
| { |
| Character component = this.m_attachTarget.GetComponent<Character>(); |
| Character component = this.m_attachTarget.GetComponent<Character>(); |
| if (component != null) |
| if (component != null) |
| { |
| { |
| if (component.IsDead()) |
| if (component.IsDead()) |
| { |
| { |
| this.Stop(); |
| this.Stop(); |
| return; |
| return; |
| } |
| } |
| this.m_detachTimer += dt; |
| this.m_detachTimer += dt; |
| if (this.m_detachTimer > 0.3f) |
| if (this.m_detachTimer > 0.3f) |
| { |
| { |
| this.m_detachTimer = 0f; |
| this.m_detachTimer = 0f; |
| if (component.IsDodgeInvincible()) |
| if (component.IsDodgeInvincible()) |
| { |
| { |
| this.Stop(); |
| this.Stop(); |
| return; |
| return; |
| } |
| } |
| } |
| } |
| } |
| } |
| Vector3 vector = this.m_attachTarget.TransformPoint(this.m_attachOffset); |
| Vector3 vector = this.m_attachTarget.TransformPoint(this.m_attachOffset); |
| Vector3 vector2 = this.m_attachTarget.TransformPoint(this.m_attachHitPoint); |
| Vector3 vector2 = this.m_attachTarget.TransformPoint(this.m_attachHitPoint); |
| Vector3 vector3 = Vector3.Lerp(this.m_character.transform.position, vector, 0.1f); |
| Vector3 vector3 = Vector3.Lerp(this.m_character.transform.position, vector, 0.1f); |
| Vector3 vector4 = vector2 - vector3; |
| Vector3 vector4 = vector2 - vector3; |
| vector4.Normalize(); |
| vector4.Normalize(); |
| Quaternion quaternion = Quaternion.LookRotation(vector4); |
| Quaternion quaternion = Quaternion.LookRotation(vector4); |
| Vector3 vector5 = vector2 - vector4 * this.m_character.GetRadius(); |
| Vector3 vector5 = vector2 - vector4 * this.m_character.GetRadius(); |
| this.m_character.transform.position = vector5; |
| this.m_character.transform.position = vector5; |
| this.m_character.transform.rotation = quaternion; |
| this.m_character.transform.rotation = quaternion; |
| this.m_character.GetComponent<Rigidbody>().velocity = Vector3.zero; |
| this.m_character.GetComponent<Rigidbody>().velocity = Vector3.zero; |
| return; |
| return; |
| } |
| } |
| this.Stop(); |
| this.Stop(); |
| } |
| } |
| |
| |
| public bool IsAttached() |
| public bool IsAttached() |
| { |
| { |
| return this.m_isAttached; |
| return this.m_isAttached; |
| } |
| } |
| |
| |
| public bool GetAttachData(out ZDOID parent, out string attachJoint, out Vector3 relativePos, out Quaternion relativeRot, out Vector3 relativeVel) |
| public bool GetAttachData(out ZDOID parent, out string attachJoint, out Vector3 relativePos, out Quaternion relativeRot, out Vector3 relativeVel) |
| { |
| { |
| attachJoint = ""; |
| attachJoint = ""; |
| parent = ZDOID.None; |
| parent = ZDOID.None; |
| relativePos = Vector3.zero; |
| relativePos = Vector3.zero; |
| relativeRot = Quaternion.identity; |
| relativeRot = Quaternion.identity; |
| relativeVel = Vector3.zero; |
| relativeVel = Vector3.zero; |
| if (!this.m_isAttached || !this.m_attachTarget) |
| if (!this.m_isAttached || !this.m_attachTarget) |
| { |
| { |
| return false; |
| return false; |
| } |
| } |
| ZNetView component = this.m_attachTarget.GetComponent<ZNetView>(); |
| ZNetView component = this.m_attachTarget.GetComponent<ZNetView>(); |
| if (!component) |
| if (!component) |
| { |
| { |
| return false; |
| return false; |
| } |
| } |
| parent = component.GetZDO().m_uid; |
| parent = component.GetZDO().m_uid; |
| relativePos = component.transform.InverseTransformPoint(this.m_character.transform.position); |
| relativePos = component.transform.InverseTransformPoint(this.m_character.transform.position); |
| relativeRot = Quaternion.Inverse(component.transform.rotation) * this.m_character.transform.rotation; |
| relativeRot = Quaternion.Inverse(component.transform.rotation) * this.m_character.transform.rotation; |
| relativeVel = Vector3.zero; |
| relativeVel = Vector3.zero; |
| return true; |
| return true; |
| } |
| } |
| |
| |
| . | private void SpawnOnHitTerrain(Vector3 hitPoint, GameObject prefab) |
| public static GameObject SpawnOnHitTerrain(Vector3 hitPoint, GameObject prefab, Character character, float attackHitNoise, ItemDrop.ItemData weapon, ItemDrop.ItemData ammo, bool randomRotation = false) |
| { |
| { |
| TerrainModifier componentInChildren = prefab.GetComponentInChildren<TerrainModifier>(); |
| TerrainModifier componentInChildren = prefab.GetComponentInChildren<TerrainModifier>(); |
| if (componentInChildren) |
| if (componentInChildren) |
| { |
| { |
| if (!PrivateArea.CheckAccess(hitPoint, componentInChildren.GetRadius(), true, false)) |
| if (!PrivateArea.CheckAccess(hitPoint, componentInChildren.GetRadius(), true, false)) |
| { |
| { |
| . | return; |
| return null; |
| } |
| } |
| if (Location.IsInsideNoBuildLocation(hitPoint)) |
| if (Location.IsInsideNoBuildLocation(hitPoint)) |
| { |
| { |
| . | return; |
| return null; |
| } |
| } |
| } |
| } |
| TerrainOp componentInChildren2 = prefab.GetComponentInChildren<TerrainOp>(); |
| TerrainOp componentInChildren2 = prefab.GetComponentInChildren<TerrainOp>(); |
| if (componentInChildren2) |
| if (componentInChildren2) |
| { |
| { |
| if (!PrivateArea.CheckAccess(hitPoint, componentInChildren2.GetRadius(), true, false)) |
| if (!PrivateArea.CheckAccess(hitPoint, componentInChildren2.GetRadius(), true, false)) |
| { |
| { |
| . | return; |
| return null; |
| } |
| } |
| if (Location.IsInsideNoBuildLocation(hitPoint)) |
| if (Location.IsInsideNoBuildLocation(hitPoint)) |
| { |
| { |
| . | return; |
| return null; |
| } |
| } |
| } |
| } |
| TerrainModifier.SetTriggerOnPlaced(true); |
| TerrainModifier.SetTriggerOnPlaced(true); |
| . | GameObject gameObject = UnityEngine.Object.Instantiate<GameObject>(prefab, hitPoint, Quaternion.LookRotation(this.m_character.transform.forward)); |
| GameObject gameObject = UnityEngine.Object.Instantiate<GameObject>(prefab, hitPoint, randomRotation ? Quaternion.Euler(0f, (float)UnityEngine.Random.Range(0, 360), 0f) : ((character != null) ? Quaternion.LookRotation(character.transform.forward) : Quaternion.identity)); |
| TerrainModifier.SetTriggerOnPlaced(false); |
| TerrainModifier.SetTriggerOnPlaced(false); |
| IProjectile component = gameObject.GetComponent<IProjectile>(); |
| IProjectile component = gameObject.GetComponent<IProjectile>(); |
| if (component != null) |
| if (component != null) |
| { |
| { |
| . | component.Setup(this.m_character, Vector3.zero, this.m_attackHitNoise, null, this.m_weapon, this.m_lastUsedAmmo); |
| component.Setup(character, Vector3.zero, attackHitNoise, null, weapon, ammo); |
| } |
| } |
| . | |
| return gameObject; |
| } |
| } |
| |
| |
| public Attack Clone() |
| public Attack Clone() |
| { |
| { |
| return base.MemberwiseClone() as Attack; |
| return base.MemberwiseClone() as Attack; |
| } |
| } |
| |
| |
| public ItemDrop.ItemData GetWeapon() |
| public ItemDrop.ItemData GetWeapon() |
| { |
| { |
| return this.m_weapon; |
| return this.m_weapon; |
| } |
| } |
| |
| |
| public bool CanStartChainAttack() |
| public bool CanStartChainAttack() |
| { |
| { |
| return this.m_nextAttackChainLevel > 0 && this.m_animEvent.CanChain(); |
| return this.m_nextAttackChainLevel > 0 && this.m_animEvent.CanChain(); |
| } |
| } |
| |
| |
| public void OnTrailStart() |
| public void OnTrailStart() |
| { |
| { |
| if (this.m_attackType == Attack.AttackType.Projectile) |
| if (this.m_attackType == Attack.AttackType.Projectile) |
| { |
| { |
| Transform attackOrigin = this.GetAttackOrigin(); |
| Transform attackOrigin = this.GetAttackOrigin(); |
| this.m_weapon.m_shared.m_trailStartEffect.Create(attackOrigin.position, this.m_character.transform.rotation, this.m_character.transform, 1f, -1); |
| this.m_weapon.m_shared.m_trailStartEffect.Create(attackOrigin.position, this.m_character.transform.rotation, this.m_character.transform, 1f, -1); |
| this.m_trailStartEffect.Create(attackOrigin.position, this.m_character.transform.rotation, this.m_character.transform, 1f, -1); |
| this.m_trailStartEffect.Create(attackOrigin.position, this.m_character.transform.rotation, this.m_character.transform, 1f, -1); |
| return; |
| return; |
| } |
| } |
| Transform transform; |
| Transform transform; |
| Vector3 vector; |
| Vector3 vector; |
| this.GetMeleeAttackDir(out transform, out vector); |
| this.GetMeleeAttackDir(out transform, out vector); |
| Quaternion quaternion = Quaternion.LookRotation(vector, Vector3.up); |
| Quaternion quaternion = Quaternion.LookRotation(vector, Vector3.up); |
| this.m_weapon.m_shared.m_trailStartEffect.Create(transform.position, quaternion, this.m_character.transform, 1f, -1); |
| this.m_weapon.m_shared.m_trailStartEffect.Create(transform.position, quaternion, this.m_character.transform, 1f, -1); |
| this.m_trailStartEffect.Create(transform.position, quaternion, this.m_character.transform, 1f, -1); |
| this.m_trailStartEffect.Create(transform.position, quaternion, this.m_character.transform, 1f, -1); |
| } |
| } |
| |
| |
| public override string ToString() |
| public override string ToString() |
| { |
| { |
| return string.Format("{0}: {1}, {2}", "Attack", this.m_attackAnimation, this.m_attackType); |
| return string.Format("{0}: {1}, {2}", "Attack", this.m_attackAnimation, this.m_attackType); |
| } |
| } |
| |
| |
| [Header("Common")] |
| [Header("Common")] |
| public Attack.AttackType m_attackType; |
| public Attack.AttackType m_attackType; |
| |
| |
| public string m_attackAnimation = ""; |
| public string m_attackAnimation = ""; |
| |
| |
| . | |
| public string m_chargeAnimationBool = ""; |
| |
| |
| public int m_attackRandomAnimations; |
| public int m_attackRandomAnimations; |
| |
| |
| public int m_attackChainLevels; |
| public int m_attackChainLevels; |
| |
| |
| public bool m_loopingAttack; |
| public bool m_loopingAttack; |
| |
| |
| public bool m_consumeItem; |
| public bool m_consumeItem; |
| |
| |
| public bool m_hitTerrain = true; |
| public bool m_hitTerrain = true; |
| |
| |
| . | |
| public bool m_hitFriendly; |
| |
| |
| public bool m_isHomeItem; |
| public bool m_isHomeItem; |
| |
| |
| public float m_attackStamina = 20f; |
| public float m_attackStamina = 20f; |
| |
| |
| public float m_attackEitr; |
| public float m_attackEitr; |
| |
| |
| public float m_attackHealth; |
| public float m_attackHealth; |
| |
| |
| [Range(0f, 100f)] |
| [Range(0f, 100f)] |
| public float m_attackHealthPercentage; |
| public float m_attackHealthPercentage; |
| |
| |
| . | |
| public bool m_attackHealthLowBlockUse = true; |
| |
| |
| |
| public float m_attackHealthReturnHit; |
| |
| |
| |
| public bool m_attackKillsSelf; |
| |
| |
| public float m_speedFactor = 0.2f; |
| public float m_speedFactor = 0.2f; |
| |
| |
| public float m_speedFactorRotation = 0.2f; |
| public float m_speedFactorRotation = 0.2f; |
| |
| |
| public float m_attackStartNoise = 10f; |
| public float m_attackStartNoise = 10f; |
| |
| |
| public float m_attackHitNoise = 30f; |
| public float m_attackHitNoise = 30f; |
| |
| |
| public float m_damageMultiplier = 1f; |
| public float m_damageMultiplier = 1f; |
| |
| |
| . | |
| [global::Tooltip("For each missing health point, increase damage this much.")] |
| |
| public float m_damageMultiplierPerMissingHP; |
| |
| |
| |
| [global::Tooltip("At 100% missing HP the damage will increase by this much, and gradually inbetween.")] |
| |
| public float m_damageMultiplierByTotalHealthMissing; |
| |
| |
| |
| [global::Tooltip("For each missing health point, return one stamina point.")] |
| |
| public float m_staminaReturnPerMissingHP; |
| |
| |
| public float m_forceMultiplier = 1f; |
| public float m_forceMultiplier = 1f; |
| |
| |
| public float m_staggerMultiplier = 1f; |
| public float m_staggerMultiplier = 1f; |
| |
| |
| public float m_recoilPushback; |
| public float m_recoilPushback; |
| |
| |
| public int m_selfDamage; |
| public int m_selfDamage; |
| |
| |
| [Header("Misc")] |
| [Header("Misc")] |
| public string m_attackOriginJoint = ""; |
| public string m_attackOriginJoint = ""; |
| |
| |
| public float m_attackRange = 1.5f; |
| public float m_attackRange = 1.5f; |
| |
| |
| public float m_attackHeight = 0.6f; |
| public float m_attackHeight = 0.6f; |
| |
| |
| public float m_attackOffset; |
| public float m_attackOffset; |
| |
| |
| public GameObject m_spawnOnTrigger; |
| public GameObject m_spawnOnTrigger; |
| |
| |
| public bool m_toggleFlying; |
| public bool m_toggleFlying; |
| |
| |
| public bool m_attach; |
| public bool m_attach; |
| |
| |
| [Header("Loading")] |
| [Header("Loading")] |
| public bool m_requiresReload; |
| public bool m_requiresReload; |
| |
| |
| public string m_reloadAnimation = ""; |
| public string m_reloadAnimation = ""; |
| |
| |
| public float m_reloadTime = 2f; |
| public float m_reloadTime = 2f; |
| |
| |
| public float m_reloadStaminaDrain; |
| public float m_reloadStaminaDrain; |
| |
| |
| . | |
| public float m_reloadEitrDrain; |
| |
| |
| [Header("Draw")] |
| [Header("Draw")] |
| public bool m_bowDraw; |
| public bool m_bowDraw; |
| |
| |
| public float m_drawDurationMin; |
| public float m_drawDurationMin; |
| |
| |
| public float m_drawStaminaDrain; |
| public float m_drawStaminaDrain; |
| |
| |
| . | |
| public float m_drawEitrDrain; |
| |
| |
| public string m_drawAnimationState = ""; |
| public string m_drawAnimationState = ""; |
| |
| |
| . | |
| public AnimationCurve m_drawVelocityCurve = AnimationCurve.Linear(0f, 0f, 1f, 1f); |
| |
| |
| [Header("Melee/AOE")] |
| [Header("Melee/AOE")] |
| public float m_attackAngle = 90f; |
| public float m_attackAngle = 90f; |
| |
| |
| public float m_attackRayWidth; |
| public float m_attackRayWidth; |
| |
| |
| public float m_maxYAngle; |
| public float m_maxYAngle; |
| |
| |
| public bool m_lowerDamagePerHit = true; |
| public bool m_lowerDamagePerHit = true; |
| |
| |
| public Attack.HitPointType m_hitPointtype; |
| public Attack.HitPointType m_hitPointtype; |
| |
| |
| public bool m_hitThroughWalls; |
| public bool m_hitThroughWalls; |
| |
| |
| public bool m_multiHit = true; |
| public bool m_multiHit = true; |
| |
| |
| public bool m_pickaxeSpecial; |
| public bool m_pickaxeSpecial; |
| |
| |
| public float m_lastChainDamageMultiplier = 2f; |
| public float m_lastChainDamageMultiplier = 2f; |
| |
| |
| [BitMask(typeof(DestructibleType))] |
| [BitMask(typeof(DestructibleType))] |
| public DestructibleType m_resetChainIfHit; |
| public DestructibleType m_resetChainIfHit; |
| |
| |
| . | |
| [Header("Spawn on hit")] |
| |
| public GameObject m_spawnOnHit; |
| |
| |
| |
| public float m_spawnOnHitChance; |
| |
| |
| [Header("Skill settings")] |
| [Header("Skill settings")] |
| public float m_raiseSkillAmount = 1f; |
| public float m_raiseSkillAmount = 1f; |
| |
| |
| [BitMask(typeof(DestructibleType))] |
| [BitMask(typeof(DestructibleType))] |
| public DestructibleType m_skillHitType = DestructibleType.Character; |
| public DestructibleType m_skillHitType = DestructibleType.Character; |
| |
| |
| public Skills.SkillType m_specialHitSkill; |
| public Skills.SkillType m_specialHitSkill; |
| |
| |
| [BitMask(typeof(DestructibleType))] |
| [BitMask(typeof(DestructibleType))] |
| public DestructibleType m_specialHitType; |
| public DestructibleType m_specialHitType; |
| |
| |
| [Header("Projectile")] |
| [Header("Projectile")] |
| public GameObject m_attackProjectile; |
| public GameObject m_attackProjectile; |
| |
| |
| public float m_projectileVel = 10f; |
| public float m_projectileVel = 10f; |
| |
| |
| public float m_projectileVelMin = 2f; |
| public float m_projectileVelMin = 2f; |
| |
| |
| . | |
| [global::Tooltip("When not using Draw, randomize velocity between Velocity and Velocity Min")] |
| |
| public bool m_randomVelocity; |
| |
| |
| public float m_projectileAccuracy = 10f; |
| public float m_projectileAccuracy = 10f; |
| |
| |
| public float m_projectileAccuracyMin = 20f; |
| public float m_projectileAccuracyMin = 20f; |
| |
| |
| . | |
| public bool m_circularProjectileLaunch; |
| |
| |
| |
| public bool m_distributeProjectilesAroundCircle; |
| |
| |
| public bool m_skillAccuracy; |
| public bool m_skillAccuracy; |
| |
| |
| public bool m_useCharacterFacing; |
| public bool m_useCharacterFacing; |
| |
| |
| public bool m_useCharacterFacingYAim; |
| public bool m_useCharacterFacingYAim; |
| |
| |
| [FormerlySerializedAs("m_useCharacterFacingAngle")] |
| [FormerlySerializedAs("m_useCharacterFacingAngle")] |
| public float m_launchAngle; |
| public float m_launchAngle; |
| |
| |
| public int m_projectiles = 1; |
| public int m_projectiles = 1; |
| |
| |
| public int m_projectileBursts = 1; |
| public int m_projectileBursts = 1; |
| |
| |
| public float m_burstInterval; |
| public float m_burstInterval; |
| |
| |
| public bool m_destroyPreviousProjectile; |
| public bool m_destroyPreviousProjectile; |
| |
| |
| public bool m_perBurstResourceUsage; |
| public bool m_perBurstResourceUsage; |
| |
| |
| [Header("Attack-Effects")] |
| [Header("Attack-Effects")] |
| public EffectList m_hitEffect = new EffectList(); |
| public EffectList m_hitEffect = new EffectList(); |
| |
| |
| public EffectList m_hitTerrainEffect = new EffectList(); |
| public EffectList m_hitTerrainEffect = new EffectList(); |
| |
| |
| public EffectList m_startEffect = new EffectList(); |
| public EffectList m_startEffect = new EffectList(); |
| |
| |
| public EffectList m_triggerEffect = new EffectList(); |
| public EffectList m_triggerEffect = new EffectList(); |
| |
| |
| public EffectList m_trailStartEffect = new EffectList(); |
| public EffectList m_trailStartEffect = new EffectList(); |
| |
| |
| public EffectList m_burstEffect = new EffectList(); |
| public EffectList m_burstEffect = new EffectList(); |
| |
| |
| protected static int m_attackMask; |
| protected static int m_attackMask; |
| |
| |
| protected static int m_attackMaskTerrain; |
| protected static int m_attackMaskTerrain; |
| |
| |
| private Humanoid m_character; |
| private Humanoid m_character; |
| |
| |
| private BaseAI m_baseAI; |
| private BaseAI m_baseAI; |
| |
| |
| private Rigidbody m_body; |
| private Rigidbody m_body; |
| |
| |
| private ZSyncAnimation m_zanim; |
| private ZSyncAnimation m_zanim; |
| |
| |
| private CharacterAnimEvent m_animEvent; |
| private CharacterAnimEvent m_animEvent; |
| |
| |
| [NonSerialized] |
| [NonSerialized] |
| private ItemDrop.ItemData m_weapon; |
| private ItemDrop.ItemData m_weapon; |
| |
| |
| private VisEquipment m_visEquipment; |
| private VisEquipment m_visEquipment; |
| |
| |
| [NonSerialized] |
| [NonSerialized] |
| private ItemDrop.ItemData m_lastUsedAmmo; |
| private ItemDrop.ItemData m_lastUsedAmmo; |
| |
| |
| private float m_attackDrawPercentage; |
| private float m_attackDrawPercentage; |
| |
| |
| private const float m_freezeFrameDuration = 0.15f; |
| private const float m_freezeFrameDuration = 0.15f; |
| |
| |
| private const float m_chainAttackMaxTime = 0.2f; |
| private const float m_chainAttackMaxTime = 0.2f; |
| |
| |
| private int m_nextAttackChainLevel; |
| private int m_nextAttackChainLevel; |
| |
| |
| private int m_currentAttackCainLevel; |
| private int m_currentAttackCainLevel; |
| |
| |
| private bool m_wasInAttack; |
| private bool m_wasInAttack; |
| |
| |
| private float m_time; |
| private float m_time; |
| |
| |
| private bool m_abortAttack; |
| private bool m_abortAttack; |
| . | |
| |
| |
| private bool m_attackTowardsCameraDir = true; |
| |
| |
| private bool m_projectileAttackStarted; |
| private bool m_projectileAttackStarted; |
| |
| |
| private float m_projectileFireTimer = -1f; |
| private float m_projectileFireTimer = -1f; |
| |
| |
| private int m_projectileBurstsFired; |
| private int m_projectileBurstsFired; |
| |
| |
| [NonSerialized] |
| [NonSerialized] |
| private ItemDrop.ItemData m_ammoItem; |
| private ItemDrop.ItemData m_ammoItem; |
| |
| |
| private bool m_attackDone; |
| private bool m_attackDone; |
| |
| |
| private bool m_isAttached; |
| private bool m_isAttached; |
| |
| |
| private Transform m_attachTarget; |
| private Transform m_attachTarget; |
| |
| |
| private Vector3 m_attachOffset; |
| private Vector3 m_attachOffset; |
| |
| |
| private float m_attachDistance; |
| private float m_attachDistance; |
| |
| |
| private Vector3 m_attachHitPoint; |
| private Vector3 m_attachHitPoint; |
| |
| |
| private float m_detachTimer; |
| private float m_detachTimer; |
| |
| |
| private class HitPoint |
| private class HitPoint |
| { |
| { |
| public GameObject go; |
| public GameObject go; |
| |
| |
| public Vector3 avgPoint = Vector3.zero; |
| public Vector3 avgPoint = Vector3.zero; |
| |
| |
| public int count; |
| public int count; |
| |
| |
| public Vector3 firstPoint; |
| public Vector3 firstPoint; |
| |
| |
| public Collider collider; |
| public Collider collider; |
| |
| |
| public Dictionary<Collider, Vector3> allHits = new Dictionary<Collider, Vector3>(); |
| public Dictionary<Collider, Vector3> allHits = new Dictionary<Collider, Vector3>(); |
| |
| |
| public Vector3 closestPoint; |
| public Vector3 closestPoint; |
| |
| |
| public float closestDistance = 999999f; |
| public float closestDistance = 999999f; |
| } |
| } |
| |
| |
| public enum AttackType |
| public enum AttackType |
| { |
| { |
| Horizontal, |
| Horizontal, |
| Vertical, |
| Vertical, |
| Projectile, |
| Projectile, |
| None, |
| None, |
| Area, |
| Area, |
| TriggerProjectile |
| TriggerProjectile |
| } |
| } |
| |
| |
| public enum HitPointType |
| public enum HitPointType |
| { |
| { |
| Closest, |
| Closest, |
| Average, |
| Average, |
| First |
| First |
| } |
| } |
| } |
| } |
| |
| |