// Creates formatting tokens for skill popups TextFile.Token[] CreateSkillTokens(DFCareer.Skills skill) { List <TextFile.Token> tokens = new List <TextFile.Token>(); TextFile.Token skillNameToken = new TextFile.Token(); skillNameToken.text = DaggerfallUnity.Instance.TextProvider.GetSkillName(skill); skillNameToken.formatting = TextFile.Formatting.Text; TextFile.Token skillValueToken = new TextFile.Token(); skillValueToken.text = string.Format("{0}%", playerEntity.Skills.GetSkillValue(skill)); skillValueToken.formatting = TextFile.Formatting.Text; DFCareer.Stats primaryStat = DaggerfallSkills.GetPrimaryStat(skill); TextFile.Token skillPrimaryStatToken = new TextFile.Token(); skillPrimaryStatToken.text = DaggerfallUnity.Instance.TextProvider.GetAbbreviatedStatName(primaryStat); skillPrimaryStatToken.formatting = TextFile.Formatting.Text; TextFile.Token spacesToken = new TextFile.Token(); spacesToken.formatting = TextFile.Formatting.Text; spacesToken.text = " "; TextFile.Token tabToken = new TextFile.Token(); tabToken.formatting = TextFile.Formatting.PositionPrefix; // Add tokens in order tokens.Add(skillNameToken); tokens.Add(tabToken); tokens.Add(tabToken); tokens.Add(skillValueToken); tokens.Add(spacesToken); tokens.Add(skillPrimaryStatToken); return(tokens.ToArray()); }
private static bool CalculateEnemyPacification(PlayerEntity player, DFCareer.Skills languageSkill) { double chance = 0; if (languageSkill == DFCareer.Skills.Etiquette || languageSkill == DFCareer.Skills.Streetwise) { chance += player.Skills.GetLiveSkillValue(languageSkill) - 20; chance += (player.Stats.LivePersonality - 55) / 3; chance += (player.Stats.LiveIntelligence - 55) / 3; } else { chance += player.Skills.GetLiveSkillValue(languageSkill); chance += (player.Stats.LivePersonality - 50) / 5; } chance += GameManager.Instance.WeaponManager.Sheathed ? 10 : -25; chance += (player.Stats.LiveLuck - 50) / 5; // Add chance from Comprehend Languages effect if present ComprehendLanguages languagesEffect = (ComprehendLanguages)GameManager.Instance.PlayerEffectManager.FindIncumbentEffect <ComprehendLanguages>(); if (languagesEffect != null) { chance += languagesEffect.ChanceValue(); } int roll = UnityEngine.Random.Range(0, 130); bool success = (roll < chance); #if UNITY_EDITOR Debug.LogFormat("Archaeologists Pacification {3} using {0} skill: chance= {1} roll= {2}", languageSkill, chance, roll, success ? "success" : "failure"); #endif return(success); }
public override int GetTrainingMax(DFCareer.Skills skill) { // Language skill training is capped by char intelligence instead of default int playerINT = GameManager.Instance.PlayerEntity.Stats.PermanentIntelligence; return((DaggerfallSkills.IsLanguageSkill(skill)) ? playerINT : defaultTrainingMax); }
/// <summary> /// Tally skill usage. /// </summary> public override void TallySkill(DFCareer.Skills skill, short amount) { int skillId = (int)skill; try { skillUses[skillId] += amount; if (skillUses[skillId] > 20000) { skillUses[skillId] = 20000; } else if (skillUses[skillId] < 0) { skillUses[skillId] = 0; } } catch (Exception ex) { string error = string.Format("Caught exception {0} with skillId {1}.", ex.Message, skillId); if (skillUses == null || skillUses.Length == 0) { error += " skillUses is null or empty."; } Debug.Log(error); } }
private void TrainingSkill_OnItemPicked(int index, string skillName) { CloseWindow(); List <DFCareer.Skills> trainingSkills = GetTrainingSkills(); DFCareer.Skills skillToTrain = trainingSkills[index]; if (playerEntity.Skills.GetPermanentSkillValue(skillToTrain) > guild.GetTrainingMax(skillToTrain)) { // Inform player they're too skilled to train TextFile.Token[] tokens = DaggerfallUnity.Instance.TextProvider.GetRandomTokens(TrainingTooSkilledId); DaggerfallMessageBox messageBox = new DaggerfallMessageBox(uiManager, uiManager.TopWindow); messageBox.SetTextTokens(tokens, guild); messageBox.ClickAnywhereToClose = true; messageBox.Show(); } else { // Train the skill DaggerfallDateTime now = DaggerfallUnity.Instance.WorldTime.Now; playerEntity.TimeOfLastSkillTraining = now.ToClassicDaggerfallTime(); now.RaiseTime(DaggerfallDateTime.SecondsPerHour * 3); playerEntity.DeductGoldAmount(guild.GetTrainingPrice()); playerEntity.DecreaseFatigue(PlayerEntity.DefaultFatigueLoss * 180); int skillAdvancementMultiplier = DaggerfallSkills.GetAdvancementMultiplier(skillToTrain); short tallyAmount = (short)(UnityEngine.Random.Range(10, 20 + 1) * skillAdvancementMultiplier); playerEntity.TallySkill(skillToTrain, tallyAmount); DaggerfallUI.MessageBox(TrainSkillId); } }
protected void ChangeSkillMod(DFCareer.Skills skill, int amount) { if (skill == DFCareer.Skills.None) { return; } skillMods[(int)skill] += amount; }
/// <summary> /// Gets live skill value by enum, including effect mods. /// </summary> /// <param name="skill">Skill to get.</param> /// <returns>Skill value.</returns> public short GetLiveSkillValue(DFCareer.Skills skill) { int mod = mods[(int)skill]; int value = GetPermanentSkillValue(skill) + mod; // TODO: Any other clamping or processing return((short)value); }
protected void SetSkillMod(DFCareer.Skills skill, int value) { if (skill == DFCareer.Skills.None) { return; } skillMods[(int)skill] = value; }
/// <summary> /// Gets the skill modifier of the effect. /// </summary> /// <param name="skill">Skill to query.</param> /// <returns>Current skill modifier.</returns> protected int GetSkillMod(DFCareer.Skills skill) { if (skill == DFCareer.Skills.None) { return(0); } return(skillMods[(int)skill]); }
void FixedUpdate() { if (Player != null) { Vector3 toPlayer = Player.transform.position - transform.position; directionToPlayer = toPlayer.normalized; distanceToPlayer = toPlayer.magnitude; playerInSight = CanSeePlayer(); if (playerInSight) { detectedPlayer = true; } // Classic stealth mechanics would be interfered with by hearing, so only enable // hearing if the enemy has detected the player. If player has been seen we can omit hearing. if (detectedPlayer && !playerInSight) { playerInEarshot = CanHearPlayer(); } else { playerInEarshot = false; } if ((playerInEarshot || playerInSight) && !hasEncounteredPlayer) { hasEncounteredPlayer = true; // Check appropriate language skill to see if player can pacify enemy DaggerfallEntityBehaviour entityBehaviour = GetComponent <DaggerfallEntityBehaviour>(); EnemyMotor motor = GetComponent <EnemyMotor>(); if (entityBehaviour && motor && (entityBehaviour.EntityType == EntityTypes.EnemyMonster || entityBehaviour.EntityType == EntityTypes.EnemyClass)) { EnemyEntity enemyEntity = entityBehaviour.Entity as EnemyEntity; DFCareer.Skills languageSkill = enemyEntity.GetLanguageSkill(); if (languageSkill != DFCareer.Skills.None) { PlayerEntity player = GameManager.Instance.PlayerEntity; if (FormulaHelper.CalculateEnemyPacification(player, languageSkill)) { motor.IsHostile = false; DaggerfallUI.AddHUDText(HardStrings.languagePacified.Replace("%e", enemyEntity.Name).Replace("%s", languageSkill.ToString()), 5); player.TallySkill(languageSkill, 3); // BCHG: increased skill uses from (assumed) 1 in classic on success to make raising language skills easier } else if (languageSkill != DFCareer.Skills.Etiquette && languageSkill != DFCareer.Skills.Streetwise) { player.TallySkill(languageSkill, 1); } } } } } }
// Creates formatting tokens for skill popups TextFile.Token[] CreateSkillTokens(DFCareer.Skills skill, bool twoColumn = false, int startPosition = 0) { bool highlight = playerEntity.GetSkillRecentlyIncreased(skill); List <TextFile.Token> tokens = new List <TextFile.Token>(); TextFile.Formatting formatting = highlight ? TextFile.Formatting.TextHighlight : TextFile.Formatting.Text; TextFile.Token skillNameToken = new TextFile.Token(); skillNameToken.formatting = formatting; skillNameToken.text = DaggerfallUnity.Instance.TextProvider.GetSkillName(skill); TextFile.Token skillValueToken = new TextFile.Token(); skillValueToken.formatting = formatting; skillValueToken.text = string.Format("{0}%", playerEntity.Skills.GetLiveSkillValue(skill)); DFCareer.Stats primaryStat = DaggerfallSkills.GetPrimaryStat(skill); TextFile.Token skillPrimaryStatToken = new TextFile.Token(); skillPrimaryStatToken.formatting = formatting; skillPrimaryStatToken.text = DaggerfallUnity.Instance.TextProvider.GetAbbreviatedStatName(primaryStat); TextFile.Token positioningToken = new TextFile.Token(); positioningToken.formatting = TextFile.Formatting.PositionPrefix; TextFile.Token tabToken = new TextFile.Token(); tabToken.formatting = TextFile.Formatting.PositionPrefix; // Add tokens in order if (!twoColumn) { tokens.Add(skillNameToken); tokens.Add(tabToken); tokens.Add(tabToken); tokens.Add(tabToken); tokens.Add(skillValueToken); tokens.Add(tabToken); tokens.Add(skillPrimaryStatToken); } else // miscellaneous skills { if (startPosition != 0) // if this is the second column { positioningToken.x = startPosition; tokens.Add(positioningToken); } tokens.Add(skillNameToken); positioningToken.x = startPosition + 85; tokens.Add(positioningToken); tokens.Add(skillValueToken); positioningToken.x = startPosition + 112; tokens.Add(positioningToken); tokens.Add(skillPrimaryStatToken); } return(tokens.ToArray()); }
public override void RestoreSaveData(object dataIn) { if (dataIn == null) { return; } SaveData_v1 data = (SaveData_v1)dataIn; skill = (DFCareer.Skills)data.skill; }
public override void RestoreSaveData(object dataIn) { SaveData_v1 data = (SaveData_v1)dataIn; if (dataIn == null) { return; } minSkillValue = data.minSkillValue; skill = (DFCareer.Skills)data.skill; }
protected void TrainSkill(DFCareer.Skills skillToTrain) { DaggerfallDateTime now = DaggerfallUnity.Instance.WorldTime.Now; playerEntity.TimeOfLastSkillTraining = now.ToClassicDaggerfallTime(); now.RaiseTime(DaggerfallDateTime.SecondsPerHour * 3); playerEntity.DecreaseFatigue(PlayerEntity.DefaultFatigueLoss * 180); int skillAdvancementMultiplier = DaggerfallSkills.GetAdvancementMultiplier(skillToTrain); short tallyAmount = (short)(UnityEngine.Random.Range(10, 20 + 1) * skillAdvancementMultiplier); playerEntity.TallySkill(skillToTrain, tallyAmount); DaggerfallUI.MessageBox(TrainSkillId); }
public override bool IsValidForRepair(DaggerfallUnityItem item) { DFCareer.Skills skill = item.GetWeaponSkillID(); if (RepairTools.restrictedMaterialsCheck) { return(!item.IsEnchanted && !item.IsArtifact && item.NativeMaterialValue <= (int)WeaponMaterialTypes.Adamantium && (skill == DFCareer.Skills.ShortBlade || skill == DFCareer.Skills.LongBlade || skill == DFCareer.Skills.Axe)); } else { return(!item.IsEnchanted && !item.IsArtifact && (skill == DFCareer.Skills.ShortBlade || skill == DFCareer.Skills.LongBlade || skill == DFCareer.Skills.Axe)); } }
public override void TallySkill(DFCareer.Skills skill, short amount) { int skillId = (int)skill; try { Debug.Log("AHHHHHHHHHHHHHHHH!!!!!!!!!!"); if (skillId == 3) { Debug.Log("You just jumped! You idiot!"); } if (skillId == 0) { Debug.Log("You just slept for an hour! You coward!"); } if (skillId == 18) { Debug.Log("You just climbed! You monkey!"); } if (skillId != 27) { Debug.Log("You just did something other than Mysticism! You donkey!"); } skillUses[skillId] += amount; if (skillUses[skillId] > 20000) { skillUses[skillId] = 20000; } else if (skillUses[skillId] < 0) { skillUses[skillId] = 0; } } catch (Exception ex) { string error = string.Format("Caught exception {0} with skillId {1}.", ex.Message, skillId); if (skillUses == null || skillUses.Length == 0) { error += " skillUses is null or empty."; } Debug.Log(error); } }
void RemoveSkillPoint(DFCareer.Skills skill, LeftRightSpinner spinner) { // Working skill value cannot fall below rolled skill value int workingValue = workingSkills.GetSkillValue(skill); if (workingValue == startingSkills.GetSkillValue(skill)) { return; } // Remove a point from skill and assign to pool spinner.Value += 1; workingSkills.SetSkillValue(skill, (short)(workingValue - 1)); UpdateSkillValueLabels(); }
void AddSkillPoint(DFCareer.Skills skill, LeftRightSpinner spinner) { // Bonus point pool cannot fall below zero int workingValue = workingSkills.GetSkillValue(skill); if (spinner.Value == 0) { return; } // Remove a point from pool and assign to skill spinner.Value -= 1; workingSkills.SetSkillValue(skill, (short)(workingValue + 1)); UpdateSkillValueLabels(); }
protected void TrainSkillIntense(DFCareer.Skills skillToTrain) { DaggerfallDateTime now = DaggerfallUnity.Instance.WorldTime.Now; now.RaiseTime(DaggerfallDateTime.SecondsPerDay * 4); playerEntity.Skills.SetPermanentSkillValue(skillToTrain, (short)(playerEntity.Skills.GetPermanentSkillValue(skillToTrain) + 4)); TrainSkill(skillToTrain); TextFile.Token[] intenseTokens = { TextFile.CreateTextToken("You have spent the last 4 days intensively training your "), newLine, TextFile.CreateTextToken(skillToTrain + " skill, and have improved it significantly."), newLine,newLine, TextFile.CreateTextToken("Now it's time to begin your fifth and final session...") }; DaggerfallUI.MessageBox(intenseTokens); }
/// <summary> /// Heal skill damage by amount. /// Does nothing if this effect does not damage skills. /// Skill will not heal past 0. /// </summary> /// <param name="skill">Skill to heal.</param> /// <param name="amount">Amount to heal. Must be positive value.</param> public virtual void HealSkillDamage(DFCareer.Skills skill, int amount) { if (amount < 0) { Debug.LogWarning("EntityEffect.HealSkillDamage() received a negative value for amount - ignoring."); return; } int result = GetSkillMod(skill) + amount; if (result > 0) { result = 0; } SetSkillMod(skill, result); Debug.LogFormat("Healed {0}'s {1} by {2} points", GetPeeredEntityBehaviour(manager).name, skill.ToString(), amount); }
public TextFile.Token[] GetSkillSummary(DFCareer.Skills skill, int startPosition) { PlayerEntity playerEntity = GameManager.Instance.PlayerEntity; bool highlight = playerEntity.GetSkillRecentlyIncreased(skill); List <TextFile.Token> tokens = new List <TextFile.Token>(); TextFile.Formatting formatting = highlight ? TextFile.Formatting.TextHighlight : TextFile.Formatting.Text; TextFile.Token skillNameToken = new TextFile.Token(); skillNameToken.formatting = formatting; skillNameToken.text = DaggerfallUnity.Instance.TextProvider.GetSkillName(skill); TextFile.Token skillValueToken = new TextFile.Token(); skillValueToken.formatting = formatting; skillValueToken.text = string.Format("{0}%", playerEntity.Skills.GetLiveSkillValue(skill)); DFCareer.Stats primaryStat = DaggerfallSkills.GetPrimaryStat(skill); TextFile.Token skillPrimaryStatToken = new TextFile.Token(); skillPrimaryStatToken.formatting = formatting; skillPrimaryStatToken.text = DaggerfallUnity.Instance.TextProvider.GetAbbreviatedStatName(primaryStat); TextFile.Token positioningToken = new TextFile.Token(); positioningToken.formatting = TextFile.Formatting.PositionPrefix; TextFile.Token tabToken = new TextFile.Token(); tabToken.formatting = TextFile.Formatting.PositionPrefix; if (startPosition != 0) // if this is the second column { positioningToken.x = startPosition; tokens.Add(positioningToken); } tokens.Add(skillNameToken); positioningToken.x = startPosition + 85; tokens.Add(positioningToken); tokens.Add(skillValueToken); positioningToken.x = startPosition + 112; tokens.Add(positioningToken); tokens.Add(skillPrimaryStatToken); return(tokens.ToArray()); }
public static bool IsLanguageSkill(DFCareer.Skills skill) { switch (skill) { case DFCareer.Skills.Orcish: case DFCareer.Skills.Harpy: case DFCareer.Skills.Giantish: case DFCareer.Skills.Dragonish: case DFCareer.Skills.Nymph: case DFCareer.Skills.Daedric: case DFCareer.Skills.Spriggan: case DFCareer.Skills.Centaurian: case DFCareer.Skills.Impish: return(true); default: return(false); } }
public void TrainingSkill_OnItemPicked(int index, string skillName) { CloseWindow(); List <DFCareer.Skills> trainingSkills; if (guildTrainingSkills.TryGetValue(service, out trainingSkills)) { DFCareer.Skills skillToTrain = trainingSkills[index]; int maxTraining = 50; if (DaggerfallSkills.IsLanguageSkill(skillToTrain)) // BCHG: Language skill training is capped by char intelligence instead of 50% { maxTraining = playerEntity.Stats.PermanentIntelligence; } if (playerEntity.Skills.GetPermanentSkillValue(skillToTrain) > maxTraining) { // Inform player they're too skilled to train TextFile.Token[] tokens = DaggerfallUnity.Instance.TextProvider.GetRandomTokens(TrainingTooSkilledId); DaggerfallMessageBox messageBox = new DaggerfallMessageBox(uiManager, uiManager.TopWindow); messageBox.SetTextTokens(tokens, this); messageBox.ClickAnywhereToClose = true; uiManager.PushWindow(messageBox); } else { // Train the skill DaggerfallDateTime now = DaggerfallUnity.Instance.WorldTime.Now; playerEntity.TimeOfLastSkillTraining = now.ToClassicDaggerfallTime(); now.RaiseTime(DaggerfallDateTime.SecondsPerHour * 3); playerEntity.DeductGoldAmount(GetServicePrice()); playerEntity.DecreaseFatigue(PlayerEntity.DefaultFatigueLoss * 180); int skillAdvancementMultiplier = DaggerfallSkills.GetAdvancementMultiplier(skillToTrain); short tallyAmount = (short)(UnityEngine.Random.Range(10, 21) * skillAdvancementMultiplier); playerEntity.TallySkill(skillToTrain, tallyAmount); DaggerfallUI.MessageBox(TrainSkillId); } } else { Debug.LogError("Invalid skill selected for training."); } }
private static bool CalculateEnemyPacification(PlayerEntity player, DFCareer.Skills languageSkill) { double chance = 0; if (languageSkill == DFCareer.Skills.Etiquette || languageSkill == DFCareer.Skills.Streetwise) { chance += player.Skills.GetLiveSkillValue(languageSkill) / 2; chance += player.Stats.LivePersonality / 2; } else { chance += player.Skills.GetLiveSkillValue(languageSkill); chance += (player.Stats.LivePersonality - 50) / 5; } chance += GameManager.Instance.WeaponManager.Sheathed ? 10 : -25; chance += (player.Stats.LiveLuck - 50) / 5; // Add chance from Comprehend Languages effect if present ComprehendLanguages languagesEffect = (ComprehendLanguages)GameManager.Instance.PlayerEffectManager.FindIncumbentEffect <ComprehendLanguages>(); if (languagesEffect != null) { chance += languagesEffect.ChanceValue(); } int roll = UnityEngine.Random.Range(0, 130); bool success = (roll < chance); /* * if (success) * player.TallySkill(languageSkill, 3); // Increased skill uses from (assumed) 1 in classic on success to make raising language skills easier * else if (languageSkill != DFCareer.Skills.Etiquette && languageSkill != DFCareer.Skills.Streetwise) * player.TallySkill(languageSkill, 1); */ Debug.LogFormat("Archaeologists Pacification {3} using {0} skill: chance= {1} roll= {2}", languageSkill, chance, roll, success ? "success" : "failure"); return(success); }
// Calculate whether the player is successful at pacifying an enemy. public static bool CalculateEnemyPacification(Entity.PlayerEntity player, DFCareer.Skills languageSkill) { double chance = 0; if (languageSkill == DFCareer.Skills.Etiquette || languageSkill == DFCareer.Skills.Streetwise) { chance += player.Skills.GetLiveSkillValue(languageSkill) / 10; chance += player.Stats.LivePersonality / 5; } else { chance += player.Skills.GetLiveSkillValue(languageSkill); chance += player.Stats.LivePersonality / 10; } chance += GameManager.Instance.WeaponManager.Sheathed ? 10 : -25; chance += player.Stats.LiveLuck / 5; // BCHG: luck is not part of formula on uesp, not checked in classic code int roll = UnityEngine.Random.Range(0, 145); // Max ~96.5% chance for 100% skill + per + luck and sheathed weapon. Debug.LogFormat("Pacification {3} using {0} skill: chance= {1} roll= {2}", languageSkill, chance, roll, (roll < chance) ? "success" : "failure"); return(roll < chance); }
/// <summary> /// Outputs all variant settings for this enchantment. /// </summary> public override EnchantmentSettings[] GetEnchantmentSettings() { List <EnchantmentSettings> enchantments = new List <EnchantmentSettings>(); // Enumerate classic params for (int i = 0; i < DaggerfallSkills.Count; i++) { DFCareer.Skills skill = (DFCareer.Skills)i; EnchantmentSettings enchantment = new EnchantmentSettings() { Version = 1, EffectKey = EffectKey, ClassicType = EnchantmentTypes.EnhancesSkill, ClassicParam = (short)i, PrimaryDisplayName = GroupName, SecondaryDisplayName = DaggerfallUnity.Instance.TextProvider.GetSkillName(skill), EnchantCost = enchantCost, }; enchantments.Add(enchantment); } return(enchantments.ToArray()); }
protected virtual void TrainingSkill_OnItemPicked(int index, string skillName) { CloseWindow(); List <DFCareer.Skills> trainingSkills = GetTrainingSkills(); DFCareer.Skills skillToTrain = trainingSkills[index]; if (playerEntity.Skills.GetPermanentSkillValue(skillToTrain) > Guild.GetTrainingMax(skillToTrain)) { // Inform player they're too skilled to train TextFile.Token[] tokens = DaggerfallUnity.Instance.TextProvider.GetRandomTokens(TrainingTooSkilledId); DaggerfallMessageBox messageBox = new DaggerfallMessageBox(uiManager, uiManager.TopWindow); messageBox.SetTextTokens(tokens, Guild); messageBox.ClickAnywhereToClose = true; messageBox.Show(); } else { // Take payment. playerEntity.DeductGoldAmount(Guild.GetTrainingPrice()); // Train the skill TrainSkill(skillToTrain); } }
void FixedUpdate() { if (GameManager.Instance.DisableAI) { return; } targetPosPredictTimer += Time.deltaTime; if (targetPosPredictTimer >= predictionInterval) { targetPosPredictTimer = 0f; targetPosPredict = true; } else { targetPosPredict = false; } // Update whether enemy would be spawned or not in classic. // Only check if within the maximum possible distance (Just under 1094 classic units) if (GameManager.ClassicUpdate) { if (distanceToPlayer < 1094 * MeshReader.GlobalScale) { float upperXZ = 0; float upperY = 0; float lowerY = 0; bool playerInside = GameManager.Instance.PlayerGPS.GetComponent <PlayerEnterExit>().IsPlayerInside; if (!playerInside) { upperXZ = classicSpawnDespawnExterior; } else { if (!wouldBeSpawnedInClassic) { upperXZ = classicSpawnXZDist; upperY = classicSpawnYDistUpper; lowerY = classicSpawnYDistLower; } else { upperXZ = classicDespawnXZDist; upperY = classicDespawnYDist; } } float YDiffToPlayer = transform.position.y - Player.transform.position.y; float YDiffToPlayerAbs = Mathf.Abs(YDiffToPlayer); float distanceToPlayerXZ = Mathf.Sqrt(distanceToPlayer * distanceToPlayer - YDiffToPlayerAbs * YDiffToPlayerAbs); wouldBeSpawnedInClassic = true; if (distanceToPlayerXZ > upperXZ) { wouldBeSpawnedInClassic = false; } if (playerInside) { if (lowerY == 0) { if (YDiffToPlayerAbs > upperY) { wouldBeSpawnedInClassic = false; } } else if (YDiffToPlayer < lowerY || YDiffToPlayer > upperY) { wouldBeSpawnedInClassic = false; } } } else { wouldBeSpawnedInClassic = false; } } if (GameManager.ClassicUpdate) { classicTargetUpdateTimer += Time.deltaTime / systemTimerUpdatesDivisor; if (target != null && target.Entity.CurrentHealth <= 0) { target = null; } // Non-hostile mode if (GameManager.Instance.PlayerEntity.NoTargetMode || !motor.IsHostile) { if (target == Player) { target = null; } if (secondaryTarget == Player) { secondaryTarget = null; } } // Reset these values if no target if (target == null) { lastKnownTargetPos = ResetPlayerPos; predictedTargetPos = ResetPlayerPos; directionToTarget = ResetPlayerPos; lastDistanceToTarget = 0; targetRateOfApproach = 0; distanceToTarget = 0; targetSenses = null; // If we have a valid secondary target that we acquired when we got the primary, switch to it. // There will only be a secondary target if using enhanced combat AI. if (secondaryTarget != null && secondaryTarget.Entity.CurrentHealth > 0) { target = secondaryTarget; // If the secondary target was actually seen, use the last place we saw it to begin pursuit. if (sawSecondaryTarget) { lastKnownTargetPos = secondaryTargetPos; } awareOfTargetForLastPrediction = false; } } // Compare change in target position to give AI some ability to read opponent's movements if (target != null && target == targetOnLastUpdate) { if (DaggerfallUnity.Settings.EnhancedCombatAI) { targetRateOfApproach = (lastDistanceToTarget - distanceToTarget); } } else { lastDistanceToTarget = 0; targetRateOfApproach = 0; } if (target != null) { lastDistanceToTarget = distanceToTarget; targetOnLastUpdate = target; } } if (Player != null) { // Get distance to player Vector3 toPlayer = Player.transform.position - transform.position; distanceToPlayer = toPlayer.magnitude; // If out of classic spawn range, still check for direct LOS to player so that enemies who see player will // try to attack. if (!wouldBeSpawnedInClassic) { distanceToTarget = distanceToPlayer; directionToTarget = toPlayer.normalized; playerInSight = CanSeeTarget(Player); } if (classicTargetUpdateTimer > 5) { classicTargetUpdateTimer = 0f; // Is enemy in area around player or can see player? if (wouldBeSpawnedInClassic || playerInSight) { GetTargets(); if (target != null && target != Player) { targetSenses = target.GetComponent <EnemySenses>(); } else { targetSenses = null; } } // Make targeted character also target this character if it doesn't have a target yet. if (target != null && targetSenses && targetSenses.Target == null) { targetSenses.Target = entityBehaviour; } } if (target == null) { targetInSight = false; detectedTarget = false; return; } if (!wouldBeSpawnedInClassic && target == Player) { distanceToTarget = distanceToPlayer; directionToTarget = toPlayer.normalized; targetInSight = playerInSight; } else { Vector3 toTarget = ResetPlayerPos; toTarget = target.transform.position - transform.position; if (toTarget != ResetPlayerPos) { distanceToTarget = toTarget.magnitude; directionToTarget = toTarget.normalized; } targetInSight = CanSeeTarget(target); } // Classic stealth mechanics would be interfered with by hearing, so only enable // hearing if the enemy has detected the target. If target is visible we can omit hearing. if (detectedTarget && !targetInSight) { targetInEarshot = CanHearTarget(target); } else { targetInEarshot = false; } // Note: In classic an enemy can continue to track the player as long as their // giveUpTimer is > 0. Since the timer is reset to 200 on every detection this // would make chameleon and shade essentially useless, since the enemy is sure // to detect the player during one of the many AI updates. Here, the enemy has to // successfully see through the illusion spell each classic update to continue // to know where the player is. if (GameManager.ClassicUpdate) { blockedByIllusionEffect = BlockedByIllusionEffect(); if (lastHadLOSTimer > 0) { lastHadLOSTimer--; } } if (!blockedByIllusionEffect && (targetInSight || targetInEarshot)) { detectedTarget = true; lastKnownTargetPos = target.transform.position; lastHadLOSTimer = 200f; } else if (!blockedByIllusionEffect && StealthCheck()) { detectedTarget = true; // Only get the target's location from the stealth check if we haven't had // actual LOS for a while. This gives better pursuit behavior since enemies // will go to the last spot they saw the player instead of walking into walls. if (lastHadLOSTimer <= 0) { lastKnownTargetPos = target.transform.position; } } else { detectedTarget = false; } if (oldLastKnownTargetPos == ResetPlayerPos) { oldLastKnownTargetPos = lastKnownTargetPos; } if (predictedTargetPos == ResetPlayerPos || !DaggerfallUnity.Settings.EnhancedCombatAI) { predictedTargetPos = lastKnownTargetPos; } // Predict target's next position if (targetPosPredict && lastKnownTargetPos != ResetPlayerPos) { // Be sure to only take difference of movement if we've seen the target for two consecutive prediction updates if (!blockedByIllusionEffect && (targetInSight || targetInEarshot)) { if (awareOfTargetForLastPrediction) { lastPositionDiff = lastKnownTargetPos - oldLastKnownTargetPos; } // Store current last known target position for next prediction update oldLastKnownTargetPos = lastKnownTargetPos; awareOfTargetForLastPrediction = true; } else { awareOfTargetForLastPrediction = false; } if (DaggerfallUnity.Settings.EnhancedCombatAI) { float moveSpeed = (enemyEntity.Stats.LiveSpeed + PlayerSpeedChanger.dfWalkBase) * MeshReader.GlobalScale; predictedTargetPos = PredictNextTargetPos(moveSpeed); } } if (detectedTarget && !hasEncounteredPlayer && target == Player) { hasEncounteredPlayer = true; // Check appropriate language skill to see if player can pacify enemy if (!questBehaviour && entityBehaviour && motor && (entityBehaviour.EntityType == EntityTypes.EnemyMonster || entityBehaviour.EntityType == EntityTypes.EnemyClass)) { DFCareer.Skills languageSkill = enemyEntity.GetLanguageSkill(); if (languageSkill != DFCareer.Skills.None) { PlayerEntity player = GameManager.Instance.PlayerEntity; if (FormulaHelper.CalculateEnemyPacification(player, languageSkill)) { motor.IsHostile = false; DaggerfallUI.AddHUDText(HardStrings.languagePacified.Replace("%e", enemyEntity.Name).Replace("%s", languageSkill.ToString()), 5); player.TallySkill(languageSkill, 3); // BCHG: increased skill uses from 1 in classic on success to make raising language skills easier } else if (languageSkill != DFCareer.Skills.Etiquette && languageSkill != DFCareer.Skills.Streetwise) { player.TallySkill(languageSkill, 1); } } } } } }
public string GetSkillName(DFCareer.Skills skill) { switch (skill) { case DFCareer.Skills.Medical: return("Medical"); case DFCareer.Skills.Etiquette: return("Etiquette"); case DFCareer.Skills.Streetwise: return("Streetwise"); case DFCareer.Skills.Jumping: return("Jumping"); case DFCareer.Skills.Orcish: return("Orcish"); case DFCareer.Skills.Harpy: return("Harpy"); case DFCareer.Skills.Giantish: return("Giantish"); case DFCareer.Skills.Dragonish: return("Dragonish"); case DFCareer.Skills.Nymph: return("Nymph"); case DFCareer.Skills.Daedric: return("Daedric"); case DFCareer.Skills.Spriggan: return("Spriggan"); case DFCareer.Skills.Centaurian: return("Centaurian"); case DFCareer.Skills.Impish: return("Impish"); case DFCareer.Skills.Lockpicking: return("Lockpicking"); case DFCareer.Skills.Mercantile: return("Mercantile"); case DFCareer.Skills.Pickpocket: return("Pickpocket"); case DFCareer.Skills.Stealth: return("Stealth"); case DFCareer.Skills.Swimming: return("Swimming"); case DFCareer.Skills.Climbing: return("Climbing"); case DFCareer.Skills.Backstabbing: return("Backstabbing"); case DFCareer.Skills.Dodging: return("Dodging"); case DFCareer.Skills.Running: return("Running"); case DFCareer.Skills.Destruction: return("Destruction"); case DFCareer.Skills.Restoration: return("Restoration"); case DFCareer.Skills.Illusion: return("Illusion"); case DFCareer.Skills.Alteration: return("Alteration"); case DFCareer.Skills.Thaumaturgy: return("Thaumaturgy"); case DFCareer.Skills.Mysticism: return("Mysticism"); case DFCareer.Skills.ShortBlade: return("Short Blade"); case DFCareer.Skills.LongBlade: return("Long Blade"); case DFCareer.Skills.HandToHand: return("Hand-to-Hand"); case DFCareer.Skills.Axe: return("Axe"); case DFCareer.Skills.BluntWeapon: return("Blunt Weapon"); case DFCareer.Skills.Archery: return("Archery"); case DFCareer.Skills.CriticalStrike: return("Critical Strike"); default: return(string.Empty); } }
public static int GetAdvancementMultiplier(DFCareer.Skills skill) { switch (skill) { case DFCareer.Skills.Medical: return(12); case DFCareer.Skills.Etiquette: case DFCareer.Skills.Streetwise: return(1); case DFCareer.Skills.Jumping: return(5); case DFCareer.Skills.Orcish: case DFCareer.Skills.Harpy: case DFCareer.Skills.Giantish: case DFCareer.Skills.Dragonish: case DFCareer.Skills.Nymph: case DFCareer.Skills.Daedric: case DFCareer.Skills.Spriggan: case DFCareer.Skills.Centaurian: case DFCareer.Skills.Impish: return(15); case DFCareer.Skills.Lockpicking: return(2); case DFCareer.Skills.Mercantile: return(1); case DFCareer.Skills.Pickpocket: case DFCareer.Skills.Stealth: return(2); case DFCareer.Skills.Swimming: return(1); case DFCareer.Skills.Climbing: return(2); case DFCareer.Skills.Backstabbing: return(1); case DFCareer.Skills.Dodging: return(4); case DFCareer.Skills.Running: return(50); case DFCareer.Skills.Destruction: return(1); case DFCareer.Skills.Restoration: return(2); case DFCareer.Skills.Illusion: case DFCareer.Skills.Alteration: return(1); case DFCareer.Skills.Thaumaturgy: return(2); case DFCareer.Skills.Mysticism: return(1); case DFCareer.Skills.ShortBlade: case DFCareer.Skills.LongBlade: case DFCareer.Skills.HandToHand: case DFCareer.Skills.Axe: case DFCareer.Skills.BluntWeapon: return(2); case DFCareer.Skills.Archery: return(1); case DFCareer.Skills.CriticalStrike: return(8); default: return(0); } }