/// <summary> /// Handle shared logic when player attacks entity. /// </summary> public void HandleAttackFromSource(DaggerfallEntityBehaviour sourceEntityBehaviour) { // Break "normal power" concealment effects on source if (sourceEntityBehaviour && sourceEntityBehaviour.Entity.IsMagicallyConcealedNormalPower) { EntityEffectManager.BreakNormalPowerConcealmentEffects(sourceEntityBehaviour); } // When source is player if (sourceEntityBehaviour == GameManager.Instance.PlayerEntityBehaviour) { PlayerEntity playerEntity = GameManager.Instance.PlayerEntity; // Handle civilian NPC crime reporting if (EntityType == EntityTypes.CivilianNPC) { MobilePersonNPC mobileNpc = transform.GetComponent <MobilePersonNPC>(); if (mobileNpc) { // Handle assault or murder if (Entity.CurrentHealth > 0) { playerEntity.CrimeCommitted = PlayerEntity.Crimes.Assault; playerEntity.SpawnCityGuards(true); } else { if (!mobileNpc.IsGuard) { playerEntity.TallyCrimeGuildRequirements(false, 5); playerEntity.CrimeCommitted = PlayerEntity.Crimes.Murder; playerEntity.SpawnCityGuards(true); } else { playerEntity.CrimeCommitted = PlayerEntity.Crimes.Assault; playerEntity.SpawnCityGuard(mobileNpc.transform.position, mobileNpc.transform.forward); } // Disable when dead mobileNpc.Motor.gameObject.SetActive(false); } } } // Handle equipped Azura's Star trapping slain enemy monsters // This is always successful if Azura's Star is empty and equipped if (EntityType == EntityTypes.EnemyMonster && playerEntity.IsAzurasStarEquipped && entity.CurrentHealth <= 0) { EnemyEntity enemyEntity = entity as EnemyEntity; if (SoulTrap.FillEmptyTrapItem((MobileTypes)enemyEntity.MobileEnemy.ID, true)) { DaggerfallUI.AddHUDText(TextManager.Instance.GetText("ClassicEffects", "trapSuccess"), 1.5f); } } // Handle mobile enemy aggro if (EntityType == EntityTypes.EnemyClass || EntityType == EntityTypes.EnemyMonster) { // Make enemy aggressive to player EnemyMotor enemyMotor = transform.GetComponent <EnemyMotor>(); if (enemyMotor) { if (!enemyMotor.IsHostile) { GameManager.Instance.MakeEnemiesHostile(); } enemyMotor.MakeEnemyHostileToAttacker(GameManager.Instance.PlayerEntityBehaviour); } // Handle killing guards EnemyEntity enemyEntity = entity as EnemyEntity; if (enemyEntity.MobileEnemy.ID == (int)MobileTypes.Knight_CityWatch && entity.CurrentHealth <= 0) { playerEntity.TallyCrimeGuildRequirements(false, 1); playerEntity.CrimeCommitted = PlayerEntity.Crimes.Murder; } } } }
public override void Start(EntityEffectManager manager, DaggerfallEntityBehaviour caster = null) { base.Start(manager, caster); CacheReferences(); }
public override void Resume(EntityEffectManager.EffectSaveData_v1 effectData, EntityEffectManager manager, DaggerfallEntityBehaviour caster = null) { base.Resume(effectData, manager, caster); CacheReferences(); }
public override void Start(EntityEffectManager manager, DaggerfallEntityBehaviour caster = null) { base.Start(manager, caster); StartWaitingForDoor(); }
public override PayloadCallbackResults?EnchantmentPayloadCallback(EnchantmentPayloadFlags context, EnchantmentParam?param = null, DaggerfallEntityBehaviour sourceEntity = null, DaggerfallEntityBehaviour targetEntity = null, DaggerfallUnityItem sourceItem = null, int sourceDamage = 0) { base.EnchantmentPayloadCallback(context, param, sourceEntity, targetEntity, sourceItem); // Validate if (context != EnchantmentPayloadFlags.Used || sourceEntity == null || param == null) { return(null); } // Get caster effect manager EntityEffectManager effectManager = sourceEntity.GetComponent <EntityEffectManager>(); if (!effectManager) { return(null); } // Do not activate enchantment if broken // But still return durability loss so "item has broken" message displays // If AllowMagicRepairs enabled then item will not disappear if (sourceItem != null && sourceItem.currentCondition <= 0) { return new PayloadCallbackResults() { durabilityLoss = durabilityLossOnUse } } ; // Cast when used enchantment prepares a new ready spell if (!string.IsNullOrEmpty(param.Value.CustomParam)) { // TODO: Ready a custom spell bundle } else { // Ready a classic spell bundle SpellRecord.SpellRecordData spell; EffectBundleSettings bundleSettings; EntityEffectBundle bundle; if (GameManager.Instance.EntityEffectBroker.GetClassicSpellRecord(param.Value.ClassicParam, out spell)) { if (GameManager.Instance.EntityEffectBroker.ClassicSpellRecordDataToEffectBundleSettings(spell, BundleTypes.Spell, out bundleSettings)) { // Self-cast spells are all assigned directly to self, "click to cast" spells are loaded to ready spell // TODO: Support multiple ready spells so all loaded spells are launched on click bundle = new EntityEffectBundle(bundleSettings, sourceEntity); bundle.CastByItem = sourceItem; if (bundle.Settings.TargetType == TargetTypes.CasterOnly) { effectManager.AssignBundle(bundle, AssignBundleFlags.BypassSavingThrows | AssignBundleFlags.BypassChance); } else { effectManager.SetReadySpell(bundle, true); } } } } return(new PayloadCallbackResults() { durabilityLoss = durabilityLossOnUse }); }
public override void Resume(EntityEffectManager.EffectSaveData_v1 effectData, EntityEffectManager manager, DaggerfallEntityBehaviour caster = null) { base.Resume(effectData, manager, caster); StartConcealment(); }
protected void CacheReferences() { entityBehaviour = GetComponent <DaggerfallEntityBehaviour>(); entityEffectManager = GetComponent <EntityEffectManager>(); meshRenderer = GetComponentInChildren <MeshRenderer>(); }
// Returns true if hit an enemy entity public bool WeaponDamage(DaggerfallUnityItem strikingWeapon, bool arrowHit, Transform hitTransform, Vector3 impactPosition, Vector3 direction) { DaggerfallEntityBehaviour entityBehaviour = hitTransform.GetComponent <DaggerfallEntityBehaviour>(); var entityMobileUnit = hitTransform.GetComponentInChildren <MobileUnit>(); EnemyMotor enemyMotor = hitTransform.GetComponent <EnemyMotor>(); EnemySounds enemySounds = hitTransform.GetComponent <EnemySounds>(); // Check if hit a mobile NPC MobilePersonNPC mobileNpc = hitTransform.GetComponent <MobilePersonNPC>(); if (mobileNpc) { if (!mobileNpc.IsGuard) { EnemyBlood blood = hitTransform.GetComponent <EnemyBlood>(); if (blood) { blood.ShowBloodSplash(0, impactPosition); } mobileNpc.Motor.gameObject.SetActive(false); playerEntity.TallyCrimeGuildRequirements(false, 5); playerEntity.CrimeCommitted = PlayerEntity.Crimes.Murder; playerEntity.SpawnCityGuards(true); // Allow custom race handling of weapon hit against mobile NPCs, e.g. vampire feeding or lycanthrope killing if (entityBehaviour) { entityBehaviour.Entity.SetHealth(0); RacialOverrideEffect racialOverride = GameManager.Instance.PlayerEffectManager.GetRacialOverrideEffect(); if (racialOverride != null) { racialOverride.OnWeaponHitEntity(GameManager.Instance.PlayerEntity, entityBehaviour.Entity); } } } else { playerEntity.CrimeCommitted = PlayerEntity.Crimes.Assault; GameObject guard = playerEntity.SpawnCityGuard(mobileNpc.transform.position, mobileNpc.transform.forward); entityBehaviour = guard.GetComponent <DaggerfallEntityBehaviour>(); entityMobileUnit = guard.GetComponentInChildren <MobileUnit>(); enemyMotor = guard.GetComponent <EnemyMotor>(); enemySounds = guard.GetComponent <EnemySounds>(); } mobileNpc.Motor.gameObject.SetActive(false); } // Check if hit an entity and remove health if (entityBehaviour) { if (entityBehaviour.EntityType == EntityTypes.EnemyMonster || entityBehaviour.EntityType == EntityTypes.EnemyClass) { EnemyEntity enemyEntity = entityBehaviour.Entity as EnemyEntity; // Calculate damage int animTime = (int)(ScreenWeapon.GetAnimTime() * 1000); // Get animation time, converted to ms. bool isEnemyFacingAwayFromPlayer = entityMobileUnit.IsBackFacing && entityMobileUnit.EnemyState != MobileStates.SeducerTransform1 && entityMobileUnit.EnemyState != MobileStates.SeducerTransform2; int damage = FormulaHelper.CalculateAttackDamage(playerEntity, enemyEntity, isEnemyFacingAwayFromPlayer, animTime, strikingWeapon); // Break any "normal power" concealment effects on player if (playerEntity.IsMagicallyConcealedNormalPower && damage > 0) { EntityEffectManager.BreakNormalPowerConcealmentEffects(GameManager.Instance.PlayerEntityBehaviour); } // Play arrow sound and add arrow to target's inventory if (arrowHit) { DaggerfallUnityItem arrow = ItemBuilder.CreateItem(ItemGroups.Weapons, (int)Weapons.Arrow); enemyEntity.Items.AddItem(arrow); } // Play hit sound and trigger blood splash at hit point if (damage > 0) { if (usingRightHand) { enemySounds.PlayHitSound(currentRightHandWeapon); } else { enemySounds.PlayHitSound(currentLeftHandWeapon); } EnemyBlood blood = hitTransform.GetComponent <EnemyBlood>(); if (blood) { blood.ShowBloodSplash(enemyEntity.MobileEnemy.BloodIndex, impactPosition); } // Knock back enemy based on damage and enemy weight if (enemyMotor) { if (enemyMotor.KnockbackSpeed <= (5 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10)) && entityBehaviour.EntityType == EntityTypes.EnemyClass || enemyEntity.MobileEnemy.Weight > 0) { float enemyWeight = enemyEntity.GetWeightInClassicUnits(); float tenTimesDamage = damage * 10; float twoTimesDamage = damage * 2; float knockBackAmount = ((tenTimesDamage - enemyWeight) * 256) / (enemyWeight + tenTimesDamage) * twoTimesDamage; float KnockbackSpeed = (tenTimesDamage / enemyWeight) * (twoTimesDamage - (knockBackAmount / 256)); KnockbackSpeed /= (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10); if (KnockbackSpeed < (15 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10))) { KnockbackSpeed = (15 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10)); } enemyMotor.KnockbackSpeed = KnockbackSpeed; enemyMotor.KnockbackDirection = direction; } } if (DaggerfallUnity.Settings.CombatVoices && entityBehaviour.EntityType == EntityTypes.EnemyClass && Dice100.SuccessRoll(40)) { Genders gender; if (entityMobileUnit.Enemy.Gender == MobileGender.Male || enemyEntity.MobileEnemy.ID == (int)MobileTypes.Knight_CityWatch) { gender = Genders.Male; } else { gender = Genders.Female; } bool heavyDamage = damage >= enemyEntity.MaxHealth / 4; enemySounds.PlayCombatVoice(gender, false, heavyDamage); } } else { if ((!arrowHit && !enemyEntity.MobileEnemy.ParrySounds) || strikingWeapon == null) { ScreenWeapon.PlaySwingSound(); } else if (enemyEntity.MobileEnemy.ParrySounds) { enemySounds.PlayParrySound(); } } // Handle weapon striking enchantments - this could change damage amount if (strikingWeapon != null && strikingWeapon.IsEnchanted) { EntityEffectManager effectManager = GetComponent <EntityEffectManager>(); if (effectManager) { damage = effectManager.DoItemEnchantmentPayloads(EnchantmentPayloadFlags.Strikes, strikingWeapon, GameManager.Instance.PlayerEntity.Items, enemyEntity.EntityBehaviour, damage); } strikingWeapon.RaiseOnWeaponStrikeEvent(entityBehaviour, damage); } // Remove health enemyEntity.DecreaseHealth(damage); // Handle attack from player enemyEntity.EntityBehaviour.HandleAttackFromSource(GameManager.Instance.PlayerEntityBehaviour); // Allow custom race handling of weapon hit against enemies, e.g. vampire feeding or lycanthrope killing RacialOverrideEffect racialOverride = GameManager.Instance.PlayerEffectManager.GetRacialOverrideEffect(); if (racialOverride != null) { racialOverride.OnWeaponHitEntity(GameManager.Instance.PlayerEntity, entityBehaviour.Entity); } return(true); } } return(false); }
public override void Start(EntityEffectManager manager, DaggerfallEntityBehaviour caster = null) { base.Start(manager, caster); StartFreeAction(); }
private int ApplyDamageToPlayer(Items.DaggerfallUnityItem weapon) { const int doYouSurrenderToGuardsTextID = 15; EnemyEntity entity = entityBehaviour.Entity as EnemyEntity; PlayerEntity playerEntity = GameManager.Instance.PlayerEntity; // Calculate damage damage = FormulaHelper.CalculateAttackDamage(entity, playerEntity, false, 0, weapon); // Break any "normal power" concealment effects on enemy if (entity.IsMagicallyConcealedNormalPower && damage > 0) { EntityEffectManager.BreakNormalPowerConcealmentEffects(entityBehaviour); } // Tally player's dodging skill playerEntity.TallySkill(DFCareer.Skills.Dodging, 1); // Handle Strikes payload from enemy to player target - this could change damage amount if (damage > 0 && weapon != null && weapon.IsEnchanted) { EntityEffectManager effectManager = GetComponent <EntityEffectManager>(); if (effectManager) { damage = effectManager.DoItemEnchantmentPayloads(EnchantmentPayloadFlags.Strikes, weapon, entity.Items, playerEntity.EntityBehaviour, damage); } } if (damage > 0) { if (entity.MobileEnemy.ID == (int)MobileTypes.Knight_CityWatch) { // If hit by a guard, lower reputation and show the surrender dialogue if (!playerEntity.HaveShownSurrenderToGuardsDialogue && playerEntity.CrimeCommitted != PlayerEntity.Crimes.None) { playerEntity.LowerRepForCrime(); DaggerfallMessageBox messageBox = new DaggerfallMessageBox(DaggerfallUI.UIManager); messageBox.SetTextTokens(DaggerfallUnity.Instance.TextProvider.GetRSCTokens(doYouSurrenderToGuardsTextID)); messageBox.ParentPanel.BackgroundColor = Color.clear; messageBox.AddButton(DaggerfallMessageBox.MessageBoxButtons.Yes); messageBox.AddButton(DaggerfallMessageBox.MessageBoxButtons.No); messageBox.OnButtonClick += SurrenderToGuardsDialogue_OnButtonClick; messageBox.Show(); playerEntity.HaveShownSurrenderToGuardsDialogue = true; } // Surrender dialogue has been shown and player refused to surrender // Guard damages player if player can survive hit, or if hit is fatal but guard rejects player's forced surrender else if (playerEntity.CurrentHealth > damage || !playerEntity.SurrenderToCityGuards(false)) { SendDamageToPlayer(); } } else { SendDamageToPlayer(); } } else { sounds.PlayMissSound(weapon); } return(damage); }
public override void Resume(EntityEffectManager.EffectSaveData_v1 effectData, EntityEffectManager manager, DaggerfallEntityBehaviour caster = null) { base.Resume(effectData, manager, caster); // Refresh head texture after effect resumes DaggerfallUI.RefreshLargeHUDHeadTexture(); }
// Returns true if hit an enemy entity public bool WeaponDamage(RaycastHit hit, Vector3 direction, Collider arrowHitCollider = null, bool arrowHit = false) { DaggerfallUnityItem strikingWeapon = usingRightHand ? currentRightHandWeapon : currentLeftHandWeapon; if (arrowHit) { strikingWeapon = lastBowUsed; } else { // Check if hit has an DaggerfallAction component DaggerfallAction action = hit.transform.gameObject.GetComponent <DaggerfallAction>(); if (action) { action.Receive(player, DaggerfallAction.TriggerTypes.Attack); } // Check if hit has an DaggerfallActionDoor component DaggerfallActionDoor actionDoor = hit.transform.gameObject.GetComponent <DaggerfallActionDoor>(); if (actionDoor) { actionDoor.AttemptBash(true); return(false); } // Check if player hit a static exterior door if (GameManager.Instance.PlayerActivate.AttemptExteriorDoorBash(hit)) { return(false); } } // Set up for use below Transform transform = arrowHit ? arrowHitCollider.gameObject.transform : hit.transform; DaggerfallEntityBehaviour entityBehaviour = transform.GetComponent <DaggerfallEntityBehaviour>(); DaggerfallMobileUnit entityMobileUnit = transform.GetComponentInChildren <DaggerfallMobileUnit>(); EnemyMotor enemyMotor = transform.GetComponent <EnemyMotor>(); EnemySounds enemySounds = transform.GetComponent <EnemySounds>(); // Check if hit a mobile NPC MobilePersonNPC mobileNpc = transform.GetComponent <MobilePersonNPC>(); if (mobileNpc) { if (!mobileNpc.Billboard.IsUsingGuardTexture) { EnemyBlood blood = transform.GetComponent <EnemyBlood>(); if (blood) { if (!arrowHit) { blood.ShowBloodSplash(0, hit.point); } else { blood.ShowBloodSplash(0, arrowHitCollider.gameObject.transform.position); } } mobileNpc.Motor.gameObject.SetActive(false); playerEntity.TallyCrimeGuildRequirements(false, 5); playerEntity.CrimeCommitted = PlayerEntity.Crimes.Murder; playerEntity.SpawnCityGuards(true); // Allow custom race handling of weapon hit against mobile NPCs, e.g. vampire feeding or lycanthrope killing if (entityBehaviour) { entityBehaviour.Entity.SetHealth(0); RacialOverrideEffect racialOverride = GameManager.Instance.PlayerEffectManager.GetRacialOverrideEffect(); if (racialOverride != null) { racialOverride.OnWeaponHitEntity(GameManager.Instance.PlayerEntity, entityBehaviour.Entity); } } } else { playerEntity.CrimeCommitted = PlayerEntity.Crimes.Assault; GameObject guard = playerEntity.SpawnCityGuard(mobileNpc.transform.position, mobileNpc.transform.forward); entityBehaviour = guard.GetComponent <DaggerfallEntityBehaviour>(); entityMobileUnit = guard.GetComponentInChildren <DaggerfallMobileUnit>(); enemyMotor = guard.GetComponent <EnemyMotor>(); enemySounds = guard.GetComponent <EnemySounds>(); } mobileNpc.Motor.gameObject.SetActive(false); } // Check if hit an entity and remove health if (entityBehaviour) { if (entityBehaviour.EntityType == EntityTypes.EnemyMonster || entityBehaviour.EntityType == EntityTypes.EnemyClass) { EnemyEntity enemyEntity = entityBehaviour.Entity as EnemyEntity; // Calculate damage int animTime = (int)(ScreenWeapon.GetAnimTime() * 1000); // Get animation time, converted to ms. int damage = FormulaHelper.CalculateAttackDamage(playerEntity, enemyEntity, entityMobileUnit.Summary.AnimStateRecord, animTime, strikingWeapon); // Break any "normal power" concealment effects on player if (playerEntity.IsMagicallyConcealedNormalPower && damage > 0) { EntityEffectManager.BreakNormalPowerConcealmentEffects(GameManager.Instance.PlayerEntityBehaviour); } // Play arrow sound and add arrow to target's inventory if (arrowHit) { DaggerfallUnityItem arrow = ItemBuilder.CreateItem(ItemGroups.Weapons, (int)Weapons.Arrow); enemyEntity.Items.AddItem(arrow); } // Play hit sound and trigger blood splash at hit point if (damage > 0) { if (usingRightHand) { enemySounds.PlayHitSound(currentRightHandWeapon); } else { enemySounds.PlayHitSound(currentLeftHandWeapon); } EnemyBlood blood = transform.GetComponent <EnemyBlood>(); if (blood) { blood.ShowBloodSplash(enemyEntity.MobileEnemy.BloodIndex, hit.point); } // Knock back enemy based on damage and enemy weight if (enemyMotor) { if (enemyMotor.KnockbackSpeed <= (5 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10)) && entityBehaviour.EntityType == EntityTypes.EnemyClass || enemyEntity.MobileEnemy.Weight > 0) { float enemyWeight = enemyEntity.GetWeightInClassicUnits(); float tenTimesDamage = damage * 10; float twoTimesDamage = damage * 2; float knockBackAmount = ((tenTimesDamage - enemyWeight) * 256) / (enemyWeight + tenTimesDamage) * twoTimesDamage; float KnockbackSpeed = (tenTimesDamage / enemyWeight) * (twoTimesDamage - (knockBackAmount / 256)); KnockbackSpeed /= (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10); if (KnockbackSpeed < (15 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10))) { KnockbackSpeed = (15 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10)); } enemyMotor.KnockbackSpeed = KnockbackSpeed; enemyMotor.KnockbackDirection = direction; } } if (DaggerfallUnity.Settings.CombatVoices && entityBehaviour.EntityType == EntityTypes.EnemyClass && Dice100.SuccessRoll(40)) { Genders gender; if (entityMobileUnit.Summary.Enemy.Gender == MobileGender.Male || enemyEntity.MobileEnemy.ID == (int)MobileTypes.Knight_CityWatch) { gender = Genders.Male; } else { gender = Genders.Female; } bool heavyDamage = damage >= enemyEntity.MaxHealth / 4; enemySounds.PlayCombatVoice(gender, false, heavyDamage); } } else { if ((!arrowHit && !enemyEntity.MobileEnemy.ParrySounds) || strikingWeapon == null) { ScreenWeapon.PlaySwingSound(); } else if (enemyEntity.MobileEnemy.ParrySounds) { enemySounds.PlayParrySound(); } } // Handle weapon striking enchantments - this could change damage amount if (strikingWeapon != null && strikingWeapon.IsEnchanted) { EntityEffectManager effectManager = GetComponent <EntityEffectManager>(); if (effectManager) { damage = effectManager.DoItemEnchantmentPayloads(EnchantmentPayloadFlags.Strikes, strikingWeapon, GameManager.Instance.PlayerEntity.Items, enemyEntity.EntityBehaviour, damage); } strikingWeapon.RaiseOnWeaponStrikeEvent(entityBehaviour, damage); } // Remove health enemyEntity.DecreaseHealth(damage); // Make foe attack their aggressor // Currently this is just player, but should be expanded later // for a wider variety of behaviours if (enemyMotor) { // Make enemies in an area aggressive if player attacked a non-hostile one. if (!enemyMotor.IsHostile) { GameManager.Instance.MakeEnemiesHostile(); } enemyMotor.MakeEnemyHostileToAttacker(GameManager.Instance.PlayerEntityBehaviour); } if (enemyEntity.MobileEnemy.ID == (int)MobileTypes.Knight_CityWatch && enemyEntity.CurrentHealth <= 0) { playerEntity.TallyCrimeGuildRequirements(false, 1); playerEntity.CrimeCommitted = PlayerEntity.Crimes.Murder; } // Allow custom race handling of weapon hit against enemies, e.g. vampire feeding or lycanthrope killing RacialOverrideEffect racialOverride = GameManager.Instance.PlayerEffectManager.GetRacialOverrideEffect(); if (racialOverride != null) { racialOverride.OnWeaponHitEntity(GameManager.Instance.PlayerEntity, entityBehaviour.Entity); } return(true); } } return(false); }
public override void Resume(EntityEffectManager.EffectSaveData_v1 effectData, EntityEffectManager manager, DaggerfallEntityBehaviour caster = null) { base.Resume(effectData, manager, caster); isIncumbent = effectData.isIncumbent; }
public override void Start(EntityEffectManager manager, DaggerfallEntityBehaviour caster = null) { base.Start(manager, caster); AttachHost(); }
public override void Start(EntityEffectManager manager, DaggerfallEntityBehaviour caster = null) { base.Start(manager, caster); DaggerfallUI.Instance.DaggerfallHUD.HUDCompass.RegisterDetector(this); }
private int ApplyDamageToNonPlayer(Items.DaggerfallUnityItem weapon, Vector3 direction, bool bowAttack = false) { if (entityBehaviour.Target == null) { return(0); } // TODO: Merge with hit code in WeaponManager to eliminate duplicate code EnemyEntity entity = entityBehaviour.Entity as EnemyEntity; EnemyEntity targetEntity = entityBehaviour.Target.Entity as EnemyEntity; EnemySounds targetSounds = entityBehaviour.Target.GetComponent <EnemySounds>(); EnemyMotor targetMotor = entityBehaviour.Target.transform.GetComponent <EnemyMotor>(); // Calculate damage damage = FormulaHelper.CalculateAttackDamage(entity, targetEntity, weapon, -1); // Break any "normal power" concealment effects on enemy if (entity.IsMagicallyConcealedNormalPower && damage > 0) { EntityEffectManager.BreakNormalPowerConcealmentEffects(entityBehaviour); } // Play hit sound and trigger blood splash at hit point if (damage > 0) { targetSounds.PlayHitSound(weapon); EnemyBlood blood = entityBehaviour.Target.transform.GetComponent <EnemyBlood>(); Vector3 bloodPos = entityBehaviour.Target.transform.position; CharacterController targetController = entityBehaviour.Target.transform.GetComponent <CharacterController>(); bloodPos.y += targetController.height / 8; if (blood) { blood.ShowBloodSplash(targetEntity.MobileEnemy.BloodIndex, bloodPos); } // Knock back enemy based on damage and enemy weight if (targetMotor) { if (targetMotor.KnockBackSpeed <= (5 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10)) && entityBehaviour.EntityType == EntityTypes.EnemyClass || targetEntity.MobileEnemy.Weight > 0) { float enemyWeight = targetEntity.GetWeightInClassicUnits(); float tenTimesDamage = damage * 10; float twoTimesDamage = damage * 2; float knockBackAmount = ((tenTimesDamage - enemyWeight) * 256) / (enemyWeight + tenTimesDamage) * twoTimesDamage; float knockBackSpeed = (tenTimesDamage / enemyWeight) * (twoTimesDamage - (knockBackAmount / 256)); knockBackSpeed /= (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10); if (knockBackSpeed < (15 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10))) { knockBackSpeed = (15 / (PlayerSpeedChanger.classicToUnitySpeedUnitRatio / 10)); } targetMotor.KnockBackSpeed = knockBackSpeed; targetMotor.KnockBackDirection = direction; } } if (DaggerfallUnity.Settings.CombatVoices && entityBehaviour.Target.EntityType == EntityTypes.EnemyClass && Random.Range(1, 101) <= 40) { DaggerfallMobileUnit targetMobileUnit = entityBehaviour.Target.GetComponentInChildren <DaggerfallMobileUnit>(); Genders gender; if (targetMobileUnit.Summary.Enemy.Gender == MobileGender.Male || targetEntity.MobileEnemy.ID == (int)MobileTypes.Knight_CityWatch) { gender = Genders.Male; } else { gender = Genders.Female; } bool heavyDamage = damage >= targetEntity.MaxHealth / 4; targetSounds.PlayCombatVoice(gender, false, heavyDamage); } } else { WeaponTypes weaponType = WeaponTypes.Melee; if (weapon != null) { weaponType = DaggerfallUnity.Instance.ItemHelper.ConvertItemToAPIWeaponType(weapon); } if ((!bowAttack && !targetEntity.MobileEnemy.ParrySounds) || weaponType == WeaponTypes.Melee) { sounds.PlayMissSound(weapon); } else if (targetEntity.MobileEnemy.ParrySounds) { targetSounds.PlayParrySound(); } } targetEntity.DecreaseHealth(damage); // Assign "cast when strikes" to target entity if (weapon != null && weapon.IsEnchanted) { EntityEffectManager enemyEffectManager = targetEntity.EntityBehaviour.GetComponent <EntityEffectManager>(); if (enemyEffectManager) { enemyEffectManager.StrikeWithItem(weapon, entityBehaviour); } } if (targetMotor) { targetMotor.MakeEnemyHostileToAttacker(entityBehaviour); } return(damage); }
public override void Start(EntityEffectManager manager, DaggerfallEntityBehaviour caster = null) { base.Start(manager, caster); StartConcealment(); }
public override void Start(EntityEffectManager manager, DaggerfallEntityBehaviour caster = null) { base.Start(manager, caster); StartWaterBreathing(); }
public override void Start(EntityEffectManager manager, DaggerfallEntityBehaviour caster = null) { base.Start(manager, caster); PlayerAggro(); }
public override void Resume(EntityEffectManager.EffectSaveData_v1 effectData, EntityEffectManager manager, DaggerfallEntityBehaviour caster = null) { base.Resume(effectData, manager, caster); // Capture rest and travel events for disease progression on Resume if (IsIncumbent) { DaggerfallRestWindow.OnSleepTick += ProgressDiseaseAfterSleepOrTravel; DaggerfallTravelPopUp.OnPostFastTravel += ProgressDiseaseAfterSleepOrTravel; } }