/// <summary> /// Load monster record into memory and decompose it for use. /// </summary> /// <param name="monster">Monster index.</param> /// <returns>True if successful.</returns> public bool LoadMonster(int monster, out DFCareer monsterClassOut) { monsterClassOut = new DFCareer(); // Generate name from index string name = string.Format("ENEMY{0:000}.CFG", monster); // Attempt to load record int index = bsaFile.GetRecordIndex(name); if (index == -1) { return(false); } // Read monster class data ClassFile classFile = new ClassFile(); byte[] data = bsaFile.GetRecordBytes(index); MemoryStream stream = new MemoryStream(data); BinaryReader reader = new BinaryReader(stream); classFile.Load(reader); reader.Close(); // Set output class monsterClassOut = classFile.Career; return(true); }
public void Reroll(DFCareer dfClass) { // Assign base stats from class template DaggerfallStats rolledStats = CharacterDocument.GetClassBaseStats(dfClass); // Roll bonus value for each base stat // Using maxBonusRoll + 1 as Unity's Random.Range(int,int) is exclusive // of maximum value and we want to be inclusive of maximum value rolledStats.Strength += UnityEngine.Random.Range(minBonusRoll, maxBonusRoll + 1); rolledStats.Intelligence += UnityEngine.Random.Range(minBonusRoll, maxBonusRoll + 1); rolledStats.Willpower += UnityEngine.Random.Range(minBonusRoll, maxBonusRoll + 1); rolledStats.Agility += UnityEngine.Random.Range(minBonusRoll, maxBonusRoll + 1); rolledStats.Endurance += UnityEngine.Random.Range(minBonusRoll, maxBonusRoll + 1); rolledStats.Personality += UnityEngine.Random.Range(minBonusRoll, maxBonusRoll + 1); rolledStats.Speed += UnityEngine.Random.Range(minBonusRoll, maxBonusRoll + 1); rolledStats.Luck += UnityEngine.Random.Range(minBonusRoll, maxBonusRoll + 1); // Roll bonus pool for player to distribute // Using maxBonusPool + 1 for inclusive range as above int bonusPool = UnityEngine.Random.Range(minBonusPool, maxBonusPool + 1); // Apply stats to control SetStats(rolledStats, rolledStats, bonusPool); UpdateStatLabels(); // Play "rolling dice" sound DaggerfallUI.Instance.PlayOneShot(SoundClips.DiceRoll); }
protected override void Setup() { base.Setup(); // Read all CLASS*.CFG files and add to listbox string[] files = Directory.GetFiles(DaggerfallUnity.Instance.Arena2Path, "CLASS*.CFG"); if (files != null && files.Length > 0) { for (int i = 0; i < files.Length - 1; i++) { ClassFile classFile = new ClassFile(files[i]); if (classFile.Career.Name == "Spellsword") { DFCareer c = PopulateCareer(); classList.Add(c); listBox.AddItem(c.Name); } else { classList.Add(classFile.Career); listBox.AddItem(classFile.Career.Name); } } } // Last option is for creating custom classes listBox.AddItem("Custom"); OnItemPicked += DaggerfallClassSelectWindow_OnItemPicked; }
public CreateCharSpecialAdvantageWindow(IUserInterfaceManager uiManager, List <SpecialAdvDis> advDisList, DFCareer careerData, IUserInterfaceWindow previous = null, bool isDisadvantages = false) : base(uiManager, previous) { this.isDisadvantages = isDisadvantages; this.advDisList = advDisList; this.advantageData = careerData; }
void DaggerfallClassSelectWindow_OnItemPicked(int index, string className) { if (index == classList.Count) // "Custom" option selected { selectedClass = null; selectedClassIndex = -1; CloseWindow(); } else { selectedClass = classList[index]; selectedClassIndex = index; TextFile.Token[] textTokens = DaggerfallUnity.Instance.TextProvider.GetRSCTokens(startClassDescriptionID + index); DaggerfallMessageBox messageBox = new DaggerfallMessageBox(uiManager, this); messageBox.SetTextTokens(textTokens); messageBox.AddButton(DaggerfallMessageBox.MessageBoxButtons.Yes); Button noButton = messageBox.AddButton(DaggerfallMessageBox.MessageBoxButtons.No); noButton.ClickSound = DaggerfallUI.Instance.GetAudioClip(SoundClips.ButtonClick); messageBox.OnButtonClick += ConfirmClassPopup_OnButtonClick; uiManager.PushWindow(messageBox); AudioClip clip = DaggerfallUnity.Instance.SoundReader.GetAudioClip(SoundClips.SelectClassDrums); DaggerfallUI.Instance.AudioSource.PlayOneShot(clip, DaggerfallUnity.Settings.SoundVolume); } }
void OnGUI() { if (!IsReady()) { EditorGUILayout.HelpBox("DaggerfallUnity instance not ready. Have you set your Arena2 path?", MessageType.Info); return; } // Select class source EditorGUILayout.Space(); careerSource = (CareerSource)EditorGUILayout.EnumPopup(new GUIContent("Source"), (CareerSource)careerSource); // Select class from specified source selectedCareer = null; if (careerSource == CareerSource.PlayerClasses && classNames != null && classNames.Length > 0) { if (selectedTemplate > classNames.Length) { selectedTemplate = 0; } selectedTemplate = EditorGUILayout.Popup(new GUIContent("Class"), selectedTemplate, classNames); selectedCareer = classTemplates[selectedTemplate]; } else if (careerSource == CareerSource.Monsters && monsterNames != null && monsterNames.Length > 0) { if (selectedTemplate > monsterNames.Length) { selectedTemplate = 0; } selectedTemplate = EditorGUILayout.Popup(new GUIContent("Class"), selectedTemplate, monsterNames); selectedCareer = monsterTemplates[selectedTemplate]; } else { return; } // Show foldouts if (selectedCareer != null) { scrollPos = GUILayoutHelper.ScrollView(scrollPos, () => { ShowAdvancementGUI(); ShowAttributesGUI(); ShowSecondaryAttributesGUI(); ShowSkillsGUI(); ShowTolerancesGUI(); ShowProficienciesGUI(); ShowForbiddenMaterialsGUI(); ShowForbiddenArmorGUI(); ShowForbiddenShieldsGUI(); ShowMagickaGUI(); ShowMiscellaneousGUI(); //ShowUnknownGUI(); }); } }
// Set some default values for testing during development void SetDefaultValues() { race = GetRaceTemplate(Races.Breton); gender = Genders.Male; career = DaggerfallEntity.GetClassCareerTemplate(ClassCareers.Mage); name = "Nameless"; reflexes = PlayerReflexes.Average; workingSkills.SetDefaults(); workingStats.SetFromCareer(career); faceIndex = 0; }
void ConfirmClassPopup_OnButtonClick(DaggerfallMessageBox sender, DaggerfallMessageBox.MessageBoxButtons messageBoxButton) { if (messageBoxButton == DaggerfallMessageBox.MessageBoxButtons.Yes) { sender.CloseWindow(); CloseWindow(); } else if (messageBoxButton == DaggerfallMessageBox.MessageBoxButtons.No) { selectedClass = null; sender.CancelWindow(); } }
// Set some default values for testing during development void SetDefaultValues() { raceTemplate = GetRaceTemplate(Races.Breton); gender = Genders.Male; career = DaggerfallEntity.GetClassCareerTemplate(ClassCareers.Mage); name = "Nameless"; reflexes = PlayerReflexes.Average; workingSkills.SetDefaults(); workingStats.SetFromCareer(career); startingLevelUpSkillSum = 0; faceIndex = 0; skillUses = new short[DaggerfallSkills.Count]; }
/// <summary> /// Set permanent stat values from career, does not change effect mods. /// </summary> /// <param name="career">Career to set stats from.</param> public void SetPermanentFromCareer(DFCareer career) { if (career != null) { Strength = career.Strength; Intelligence = career.Intelligence; Willpower = career.Willpower; Agility = career.Agility; Endurance = career.Endurance; Personality = career.Personality; Speed = career.Speed; Luck = career.Luck; } }
public static DaggerfallStats GetClassBaseStats(DFCareer dfClass) { DaggerfallStats stats = new DaggerfallStats(); stats.SetPermanentStatValue(DFCareer.Stats.Strength, dfClass.Strength); stats.SetPermanentStatValue(DFCareer.Stats.Intelligence, dfClass.Intelligence); stats.SetPermanentStatValue(DFCareer.Stats.Willpower, dfClass.Willpower); stats.SetPermanentStatValue(DFCareer.Stats.Agility, dfClass.Agility); stats.SetPermanentStatValue(DFCareer.Stats.Endurance, dfClass.Endurance); stats.SetPermanentStatValue(DFCareer.Stats.Personality, dfClass.Personality); stats.SetPermanentStatValue(DFCareer.Stats.Speed, dfClass.Speed); stats.SetPermanentStatValue(DFCareer.Stats.Luck, dfClass.Luck); return(stats); }
public static DaggerfallStats GetClassBaseStats(DFCareer dfClass) { DaggerfallStats stats = new DaggerfallStats(); stats.Strength = dfClass.Strength; stats.Intelligence = dfClass.Intelligence; stats.Willpower = dfClass.Willpower; stats.Agility = dfClass.Agility; stats.Endurance = dfClass.Endurance; stats.Personality = dfClass.Personality; stats.Speed = dfClass.Speed; stats.Luck = dfClass.Luck; return(stats); }
public void SetClassSkills(DFCareer dfClass) { // Set primary, major, minor skills from class template primarySkills[0] = dfClass.PrimarySkill1; primarySkills[1] = dfClass.PrimarySkill2; primarySkills[2] = dfClass.PrimarySkill3; majorSkills[0] = dfClass.MajorSkill1; majorSkills[1] = dfClass.MajorSkill2; majorSkills[2] = dfClass.MajorSkill3; minorSkills[0] = dfClass.MinorSkill1; minorSkills[1] = dfClass.MinorSkill2; minorSkills[2] = dfClass.MinorSkill3; minorSkills[3] = dfClass.MinorSkill4; minorSkills[4] = dfClass.MinorSkill5; minorSkills[5] = dfClass.MinorSkill6; UpdateSkillLabels(); Reroll(); }
void DaggerfallClassSelectWindow_OnItemPicked(int index) { selectedClass = classList[index]; TextFile.Token[] textTokens = DaggerfallUnity.Instance.TextProvider.GetRSCTokens(startClassDescriptionID + index); DaggerfallMessageBox messageBox = new DaggerfallMessageBox(uiManager, this); messageBox.SetTextTokens(textTokens); messageBox.AddButton(DaggerfallMessageBox.MessageBoxButtons.Yes); Button noButton = messageBox.AddButton(DaggerfallMessageBox.MessageBoxButtons.No); noButton.ClickSound = DaggerfallUI.Instance.GetAudioClip(SoundClips.ButtonClick); messageBox.OnButtonClick += ConfirmClassPopup_OnButtonClick; uiManager.PushWindow(messageBox); AudioClip clip = DaggerfallUnity.Instance.SoundReader.GetAudioClip(SoundClips.SelectClassDrums); DaggerfallUI.Instance.AudioSource.PlayOneShot(clip); }
// Set some default values for testing during development void SetDefaultValues() { raceTemplate = GetRaceTemplate(Races.Breton); gender = Genders.Male; career = DaggerfallEntity.GetClassCareerTemplate(ClassCareers.Mage); name = "Nameless"; reflexes = PlayerReflexes.Average; workingSkills.SetDefaults(); workingStats.SetPermanentFromCareer(career); startingLevelUpSkillSum = 0; faceIndex = 0; skillUses = new short[DaggerfallSkills.Count]; skillsRaisedThisLevel1 = 0; skillsRaisedThisLevel2 = 0; for (int i = 0; i < armorValues.Length; i++) { armorValues[i] = 100; } }
private void SaveLoadManager_OnStartLoad(SaveData_v1 saveData) { PlayerEntityData_v1 pData = saveData.playerData.playerEntity; // sync health bar healthBarLoss.Amount = pData.currentHealth / (float)pData.maxHealth; healthBar.Amount = healthBarLoss.Amount; // sync fatigue bar int maxFatigue = (pData.stats.LiveStrength + pData.stats.LiveEndurance) * 64; fatigueBarLoss.Amount = pData.currentFatigue / (float)maxFatigue; fatigueBar.Amount = fatigueBarLoss.Amount; // sync magicka bar DFCareer career = pData.careerTemplate; int maxMagicka = FormulaHelper.SpellPoints(pData.stats.LiveIntelligence, career.SpellPointMultiplierValue); magickaBarLoss.Amount = pData.currentMagicka / (float)maxMagicka; magickaBar.Amount = magickaBarLoss.Amount; }
/// <summary> /// Sets enemy career and prepares entity settings. /// </summary> public void SetEnemyCareer(MobileEnemy mobileEnemy, EntityTypes entityType) { if (entityType == EntityTypes.EnemyMonster) { careerIndex = (int)mobileEnemy.ID; career = GetMonsterCareerTemplate((MonsterCareers)careerIndex); stats.SetFromCareer(career); // Enemy monster has predefined level and health level = career.HitPointsPerLevelOrMonsterLevel; maxHealth = UnityEngine.Random.Range(mobileEnemy.MinHealth, mobileEnemy.MaxHealth + 1); } else if (entityType == EntityTypes.EnemyClass) { careerIndex = (int)mobileEnemy.ID - 128; career = GetClassCareerTemplate((ClassCareers)careerIndex); stats.SetFromCareer(career); // Enemy class is levelled to player and uses same health rules level = GameManager.Instance.PlayerEntity.Level; maxHealth = FormulaHelper.RollMaxHealth(level, stats.Endurance, career.HitPointsPerLevelOrMonsterLevel); // Enemy class damage is temporarily set by a fudged level multiplier // This will change once full entity setup and items are available const float damageMultiplier = 4f; mobileEnemy.MinDamage = (int)(level * damageMultiplier); mobileEnemy.MaxDamage = (int)((level + 2) * damageMultiplier); } else { career = new DFCareer(); careerIndex = -1; return; } this.mobileEnemy = mobileEnemy; this.entityType = entityType; name = career.Name; FillVitalSigns(); }
/// <summary> /// Load monster record into memory and decompose it for use. /// </summary> /// <param name="monster">Monster index.</param> /// <returns>True if successful.</returns> public bool LoadMonster(int monster, out DFCareer monsterClassOut) { monsterClassOut = new DFCareer(); // Generate name from index string name = string.Format("ENEMY{0:000}.CFG", monster); // Attempt to load record int index = bsaFile.GetRecordIndex(name); if (index == -1) return false; // Read monster class data ClassFile classFile = new ClassFile(); byte[] data = bsaFile.GetRecordBytes(index); MemoryStream stream = new MemoryStream(data); BinaryReader reader = new BinaryReader(stream); classFile.Load(reader); reader.Close(); // Set output class monsterClassOut = classFile.Career; return true; }
void SetStartingSpells(PlayerEntity playerEntity) { if (characterDocument.classIndex > 6 && !characterDocument.isCustom) // Class does not have starting spells { return; } // Get starting set based on class int spellSetIndex = -1; if (characterDocument.isCustom) { DFCareer dfc = characterDocument.career; // Custom class uses Spellsword starting spells if it has at least 1 primary or major magic skill if (Enum.IsDefined(typeof(DFCareer.MagicSkills), (int)dfc.PrimarySkill1) || Enum.IsDefined(typeof(DFCareer.MagicSkills), (int)dfc.PrimarySkill2) || Enum.IsDefined(typeof(DFCareer.MagicSkills), (int)dfc.PrimarySkill3) || Enum.IsDefined(typeof(DFCareer.MagicSkills), (int)dfc.MajorSkill1) || Enum.IsDefined(typeof(DFCareer.MagicSkills), (int)dfc.MajorSkill2) || Enum.IsDefined(typeof(DFCareer.MagicSkills), (int)dfc.MajorSkill3)) { spellSetIndex = 1; } } else { spellSetIndex = characterDocument.classIndex; } if (spellSetIndex == -1) { return; } // Get the set's spell indices TextAsset spells = Resources.Load <TextAsset>("StartingSpells") as TextAsset; List <CareerStartingSpells> startingSpells = SaveLoadManager.Deserialize(typeof(List <CareerStartingSpells>), spells.text) as List <CareerStartingSpells>; List <StartingSpell> spellsToAdd = new List <StartingSpell>(); for (int i = 0; i < startingSpells[spellSetIndex].SpellsList.Length; i++) { spellsToAdd.Add(startingSpells[spellSetIndex].SpellsList[i]); } // Add spells to player from standard list foreach (StartingSpell spell in spellsToAdd) { SpellRecord.SpellRecordData spellData; GameManager.Instance.EntityEffectBroker.GetClassicSpellRecord(spell.SpellID, out spellData); if (spellData.index == -1) { Debug.LogError("Failed to locate starting spell in standard spells list."); continue; } EffectBundleSettings bundle; if (!GameManager.Instance.EntityEffectBroker.ClassicSpellRecordDataToEffectBundleSettings(spellData, BundleTypes.Spell, out bundle)) { Debug.LogError("Failed to create effect bundle for starting spell."); continue; } playerEntity.AddSpell(bundle); } }
protected override void Setup() { if (IsSetup) { return; } // Load native textures nativeTexture = DaggerfallUI.GetTextureFromImg(nativeImgName); nativeDaggerTexture = DaggerfallUI.GetTextureFromImg(nativeDaggerImgName); if (!nativeTexture || !nativeDaggerTexture) { throw new Exception("CreateCharCustomClass: Could not load native texture."); } // Setup native panel background NativePanel.BackgroundTexture = nativeTexture; // Add stats rollout statsRollout = new StatsRollout(false, true); statsRollout.Position = new Vector2(0, 0); NativePanel.Components.Add(statsRollout); // Add name textbox nameTextBox.Position = new Vector2(100, 5); nameTextBox.Size = new Vector2(214, 7); NativePanel.Components.Add(nameTextBox); // Initialize character class createdClass = new DFCareer(); createdClass.HitPointsPerLevel = defaultHpPerLevel; createdClass.SpellPointMultiplier = DFCareer.SpellPointMultipliers.Times_0_50; createdClass.SpellPointMultiplierValue = .5f; // Initiate UI components font = DaggerfallUI.DefaultFont; SetupButtons(); hpLabel = DaggerfallUI.AddTextLabel(font, new Vector2(285, 55), createdClass.HitPointsPerLevel.ToString(), NativePanel); daggerPanel.Size = new Vector2(24, 9); daggerPanel.BackgroundTexture = nativeDaggerTexture; NativePanel.Components.Add(daggerPanel); UpdateDifficulty(); // Setup help dictionary helpDict = new Dictionary <string, int> { { HardStrings.helpAttributes, 2402 }, { HardStrings.helpClassName, 2401 }, { HardStrings.helpGeneral, 2400 }, { HardStrings.helpReputations, 2406 }, { HardStrings.helpSkillAdvancement, 2407 }, { HardStrings.helpSkills, 2403 }, { HardStrings.helpSpecialAdvantages, 2404 }, { HardStrings.helpSpecialDisadvantages, 2405 } }; // Setup skills dictionary skillsDict = new Dictionary <string, DFCareer.Skills>(); foreach (DFCareer.Skills skill in Enum.GetValues(typeof(DFCareer.Skills))) { skillsDict.Add(DaggerfallUnity.Instance.TextProvider.GetSkillName(skill), skill); } skillsDict.Remove(string.Empty); // Don't include "none" skill value. skillsList = new List <string>(skillsDict.Keys); skillsList.Sort(); // Sort skills alphabetically a la classic. IsSetup = true; }
/// <summary> /// Sets enemy career and prepares entity settings. /// </summary> public void SetEnemyCareer(MobileEnemy mobileEnemy, EntityTypes entityType) { if (entityType == EntityTypes.EnemyMonster) { careerIndex = (int)mobileEnemy.ID; career = GetMonsterCareerTemplate((MonsterCareers)careerIndex); stats.SetFromCareer(career); // Enemy monster has predefined level, health and armor values. // Armor values can be modified below by equipment. level = mobileEnemy.Level; maxHealth = UnityEngine.Random.Range(mobileEnemy.MinHealth, mobileEnemy.MaxHealth + 1); for (int i = 0; i < ArmorValues.Length; i++) { ArmorValues[i] = (sbyte)(mobileEnemy.ArmorValue * 5); } } else if (entityType == EntityTypes.EnemyClass) { careerIndex = (int)mobileEnemy.ID - 128; career = GetClassCareerTemplate((ClassCareers)careerIndex); stats.SetFromCareer(career); // Enemy class is levelled to player and uses similar health rules level = GameManager.Instance.PlayerEntity.Level; maxHealth = FormulaHelper.RollEnemyClassMaxHealth(level, career.HitPointsPerLevel); } else { career = new DFCareer(); careerIndex = -1; return; } this.mobileEnemy = mobileEnemy; this.entityType = entityType; name = career.Name; minMetalToHit = mobileEnemy.MinMetalToHit; short skillsLevel = (short)((level * 5) + 30); if (skillsLevel > 100) { skillsLevel = 100; } for (int i = 0; i <= DaggerfallSkills.Count; i++) { skills.SetSkillValue(i, skillsLevel); } // Enemy classes and some monsters use equipment if (careerIndex == (int)MonsterCareers.Orc || careerIndex == (int)MonsterCareers.OrcShaman) { SetEnemyEquipment(0); } else if (careerIndex == (int)MonsterCareers.Centaur || careerIndex == (int)MonsterCareers.OrcSergeant) { SetEnemyEquipment(1); } else if (careerIndex == (int)MonsterCareers.OrcWarlord) { SetEnemyEquipment(2); } else if (entityType == EntityTypes.EnemyClass) { SetEnemyEquipment(UnityEngine.Random.Range(0, 2)); // 0 or 1 } FillVitalSigns(); }
/// <summary> /// Sets enemy career and prepares entity settings. /// </summary> public void SetEnemyCareer(MobileEnemy mobileEnemy, EntityTypes entityType) { // Try custom career first career = GetCustomCareerTemplate(mobileEnemy.ID); if (career != null) { // Custom enemy careerIndex = mobileEnemy.ID; stats.SetPermanentFromCareer(career); if (entityType == EntityTypes.EnemyMonster) { // Default like a monster level = mobileEnemy.Level; maxHealth = Random.Range(mobileEnemy.MinHealth, mobileEnemy.MaxHealth + 1); for (int i = 0; i < ArmorValues.Length; i++) { ArmorValues[i] = (sbyte)(mobileEnemy.ArmorValue * 5); } } else { // Default like a class enemy level = GameManager.Instance.PlayerEntity.Level; maxHealth = FormulaHelper.RollEnemyClassMaxHealth(level, career.HitPointsPerLevel); } } else if (entityType == EntityTypes.EnemyMonster) { careerIndex = mobileEnemy.ID; career = GetMonsterCareerTemplate((MonsterCareers)careerIndex); stats.SetPermanentFromCareer(career); // Enemy monster has predefined level, health and armor values. // Armor values can be modified below by equipment. level = mobileEnemy.Level; maxHealth = UnityEngine.Random.Range(mobileEnemy.MinHealth, mobileEnemy.MaxHealth + 1); for (int i = 0; i < ArmorValues.Length; i++) { ArmorValues[i] = (sbyte)(mobileEnemy.ArmorValue * 5); } } else if (entityType == EntityTypes.EnemyClass) { careerIndex = mobileEnemy.ID - 128; career = GetClassCareerTemplate((ClassCareers)careerIndex); stats.SetPermanentFromCareer(career); // Enemy class is levelled to player and uses similar health rules // City guards are 3 to 6 levels above the player level = GameManager.Instance.PlayerEntity.Level; if (careerIndex == (int)MobileTypes.Knight_CityWatch - 128) { level += UnityEngine.Random.Range(3, 7); } maxHealth = FormulaHelper.RollEnemyClassMaxHealth(level, career.HitPointsPerLevel); } else { career = new DFCareer(); careerIndex = -1; return; } this.mobileEnemy = mobileEnemy; this.entityType = entityType; name = career.Name; minMetalToHit = mobileEnemy.MinMetalToHit; team = mobileEnemy.Team; short skillsLevel = (short)((level * 5) + 30); if (skillsLevel > 100) { skillsLevel = 100; } for (int i = 0; i <= DaggerfallSkills.Count; i++) { skills.SetPermanentSkillValue(i, skillsLevel); } // Generate loot table items DaggerfallLoot.GenerateItems(mobileEnemy.LootTableKey, items); // Enemy classes and some monsters use equipment if (careerIndex == (int)MonsterCareers.Orc || careerIndex == (int)MonsterCareers.OrcShaman) { SetEnemyEquipment(0); } else if (careerIndex == (int)MonsterCareers.Centaur || careerIndex == (int)MonsterCareers.OrcSergeant) { SetEnemyEquipment(1); } else if (careerIndex == (int)MonsterCareers.OrcWarlord) { SetEnemyEquipment(2); } else if (entityType == EntityTypes.EnemyClass) { SetEnemyEquipment(UnityEngine.Random.Range(0, 2)); // 0 or 1 } // Assign spell lists if (entityType == EntityTypes.EnemyMonster) { if (careerIndex == (int)MonsterCareers.Imp) { SetEnemySpells(ImpSpells); } else if (careerIndex == (int)MonsterCareers.Ghost) { SetEnemySpells(GhostSpells); } else if (careerIndex == (int)MonsterCareers.OrcShaman) { SetEnemySpells(OrcShamanSpells); } else if (careerIndex == (int)MonsterCareers.Wraith) { SetEnemySpells(WraithSpells); } else if (careerIndex == (int)MonsterCareers.FrostDaedra) { SetEnemySpells(FrostDaedraSpells); } else if (careerIndex == (int)MonsterCareers.FireDaedra) { SetEnemySpells(FireDaedraSpells); } else if (careerIndex == (int)MonsterCareers.Daedroth) { SetEnemySpells(DaedrothSpells); } else if (careerIndex == (int)MonsterCareers.Vampire) { SetEnemySpells(VampireSpells); } else if (careerIndex == (int)MonsterCareers.DaedraSeducer) { SetEnemySpells(SeducerSpells); } else if (careerIndex == (int)MonsterCareers.VampireAncient) { SetEnemySpells(VampireAncientSpells); } else if (careerIndex == (int)MonsterCareers.DaedraLord) { SetEnemySpells(DaedraLordSpells); } else if (careerIndex == (int)MonsterCareers.Lich) { SetEnemySpells(LichSpells); } else if (careerIndex == (int)MonsterCareers.AncientLich) { SetEnemySpells(AncientLichSpells); } } else if (entityType == EntityTypes.EnemyClass && (mobileEnemy.CastsMagic)) { int spellListLevel = level / 3; if (spellListLevel > 6) { spellListLevel = 6; } SetEnemySpells(EnemyClassSpells[spellListLevel]); } // Chance of adding map DaggerfallLoot.RandomlyAddMap(mobileEnemy.MapChance, items); if (!string.IsNullOrEmpty(mobileEnemy.LootTableKey)) { // Chance of adding potion DaggerfallLoot.RandomlyAddPotion(3, items); // Chance of adding potion recipe DaggerfallLoot.RandomlyAddPotionRecipe(2, items); } OnLootSpawned?.Invoke(this, new EnemyLootSpawnedEventArgs { MobileEnemy = mobileEnemy, EnemyCareer = career, Items = items }); FillVitalSigns(); }
string[] GetClassSpecials() { List <string> specials = new List <string>(); DFCareer career = GameManager.Instance.PlayerEntity.Career; RaceTemplate race = GameManager.Instance.PlayerEntity.RaceTemplate; // Tolerances Dictionary <DFCareer.Tolerance, string> tolerances = new Dictionary <DFCareer.Tolerance, string> { { DFCareer.Tolerance.CriticalWeakness, TextManager.Instance.GetLocalizedText(HardStrings.criticalWeakness) }, { DFCareer.Tolerance.Immune, TextManager.Instance.GetLocalizedText(HardStrings.immunity) }, { DFCareer.Tolerance.LowTolerance, TextManager.Instance.GetLocalizedText(HardStrings.lowTolerance) }, { DFCareer.Tolerance.Resistant, TextManager.Instance.GetLocalizedText(HardStrings.resistance) } }; if (career.Paralysis != DFCareer.Tolerance.Normal) { specials.Add(tolerances[career.Paralysis] + " " + TextManager.Instance.GetLocalizedText(HardStrings.toParalysis)); } if (career.Magic != DFCareer.Tolerance.Normal) { specials.Add(tolerances[career.Magic] + " " + TextManager.Instance.GetLocalizedText(HardStrings.toMagic)); } if (career.Poison != DFCareer.Tolerance.Normal) { specials.Add(tolerances[career.Poison] + " " + TextManager.Instance.GetLocalizedText(HardStrings.toPoison)); } if (career.Fire != DFCareer.Tolerance.Normal) { specials.Add(tolerances[career.Fire] + " " + TextManager.Instance.GetLocalizedText(HardStrings.toFire)); } if (career.Frost != DFCareer.Tolerance.Normal) { specials.Add(tolerances[career.Frost] + " " + TextManager.Instance.GetLocalizedText(HardStrings.toFrost)); } if (career.Shock != DFCareer.Tolerance.Normal) { specials.Add(tolerances[career.Shock] + " " + TextManager.Instance.GetLocalizedText(HardStrings.toShock)); } if (career.Disease != DFCareer.Tolerance.Normal) { specials.Add(tolerances[career.Disease] + " " + TextManager.Instance.GetLocalizedText(HardStrings.toDisease)); } // Weapon Proficiencies Dictionary <DFCareer.Proficiency, string> profs = new Dictionary <DFCareer.Proficiency, string> { { DFCareer.Proficiency.Expert, TextManager.Instance.GetLocalizedText(HardStrings.expertiseIn) }, { DFCareer.Proficiency.Forbidden, TextManager.Instance.GetLocalizedText(HardStrings.forbiddenWeaponry) } }; if (career.ShortBlades != DFCareer.Proficiency.Normal) { specials.Add(profs[career.ShortBlades] + " " + TextManager.Instance.GetLocalizedText(HardStrings.shortBlade)); } if (career.LongBlades != DFCareer.Proficiency.Normal) { specials.Add(profs[career.LongBlades] + " " + TextManager.Instance.GetLocalizedText(HardStrings.longBlade)); } if (career.HandToHand != DFCareer.Proficiency.Normal) { specials.Add(profs[career.HandToHand] + " " + TextManager.Instance.GetLocalizedText(HardStrings.handToHand)); } if (career.Axes != DFCareer.Proficiency.Normal) { specials.Add(profs[career.Axes] + " " + TextManager.Instance.GetLocalizedText(HardStrings.axe)); } if (career.BluntWeapons != DFCareer.Proficiency.Normal) { specials.Add(profs[career.BluntWeapons] + " " + TextManager.Instance.GetLocalizedText(HardStrings.bluntWeapon)); } if (career.MissileWeapons != DFCareer.Proficiency.Normal) { specials.Add(profs[career.MissileWeapons] + " " + TextManager.Instance.GetLocalizedText(HardStrings.missileWeapon)); } // Attack modifiers Dictionary <DFCareer.AttackModifier, string> atkMods = new Dictionary <DFCareer.AttackModifier, string> { { DFCareer.AttackModifier.Bonus, TextManager.Instance.GetLocalizedText(HardStrings.bonusToHit) }, { DFCareer.AttackModifier.Phobia, TextManager.Instance.GetLocalizedText(HardStrings.phobia) } }; if (career.UndeadAttackModifier != DFCareer.AttackModifier.Normal) { specials.Add(atkMods[career.UndeadAttackModifier] + " " + TextManager.Instance.GetLocalizedText(HardStrings.undead)); } if (career.DaedraAttackModifier != DFCareer.AttackModifier.Normal) { specials.Add(atkMods[career.DaedraAttackModifier] + " " + TextManager.Instance.GetLocalizedText(HardStrings.daedra)); } if (career.HumanoidAttackModifier != DFCareer.AttackModifier.Normal) { specials.Add(atkMods[career.HumanoidAttackModifier] + " " + TextManager.Instance.GetLocalizedText(HardStrings.humanoid)); } if (career.AnimalsAttackModifier != DFCareer.AttackModifier.Normal) { specials.Add(atkMods[career.AnimalsAttackModifier] + " " + TextManager.Instance.GetLocalizedText(HardStrings.animals)); } // Darkness/light powered magery if (career.DarknessPoweredMagery != DFCareer.DarknessMageryFlags.Normal) { if ((career.DarknessPoweredMagery & DFCareer.DarknessMageryFlags.ReducedPowerInLight) == DFCareer.DarknessMageryFlags.ReducedPowerInLight) { specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.darknessPoweredMagery) + " " + TextManager.Instance.GetLocalizedText(HardStrings.lowerMagicAbilityDaylight)); } if ((career.DarknessPoweredMagery & DFCareer.DarknessMageryFlags.UnableToCastInLight) == DFCareer.DarknessMageryFlags.UnableToCastInLight) { specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.darknessPoweredMagery) + " " + TextManager.Instance.GetLocalizedText(HardStrings.unableToUseMagicInDaylight)); } } if (career.LightPoweredMagery != DFCareer.LightMageryFlags.Normal) { if ((career.LightPoweredMagery & DFCareer.LightMageryFlags.ReducedPowerInDarkness) == DFCareer.LightMageryFlags.ReducedPowerInDarkness) { specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.lightPoweredMagery) + " " + TextManager.Instance.GetLocalizedText(HardStrings.lowerMagicAbilityDarkness)); } if ((career.LightPoweredMagery & DFCareer.LightMageryFlags.UnableToCastInDarkness) == DFCareer.LightMageryFlags.UnableToCastInDarkness) { specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.lightPoweredMagery) + " " + TextManager.Instance.GetLocalizedText(HardStrings.unableToUseMagicInDarkness)); } } // Forbidden materials (multiple) if (career.ForbiddenMaterials != 0) { Dictionary <DFCareer.MaterialFlags, string> forbMaterials = new Dictionary <DFCareer.MaterialFlags, string> { { DFCareer.MaterialFlags.Adamantium, TextManager.Instance.GetLocalizedText(HardStrings.adamantium) }, { DFCareer.MaterialFlags.Daedric, TextManager.Instance.GetLocalizedText(HardStrings.daedric) }, { DFCareer.MaterialFlags.Dwarven, TextManager.Instance.GetLocalizedText(HardStrings.dwarven) }, { DFCareer.MaterialFlags.Ebony, TextManager.Instance.GetLocalizedText(HardStrings.ebony) }, { DFCareer.MaterialFlags.Elven, TextManager.Instance.GetLocalizedText(HardStrings.elven) }, { DFCareer.MaterialFlags.Iron, TextManager.Instance.GetLocalizedText(HardStrings.iron) }, { DFCareer.MaterialFlags.Mithril, TextManager.Instance.GetLocalizedText(HardStrings.mithril) }, { DFCareer.MaterialFlags.Orcish, TextManager.Instance.GetLocalizedText(HardStrings.orcish) }, { DFCareer.MaterialFlags.Silver, TextManager.Instance.GetLocalizedText(HardStrings.silver) }, { DFCareer.MaterialFlags.Steel, TextManager.Instance.GetLocalizedText(HardStrings.steel) } }; foreach (DFCareer.MaterialFlags flag in Enum.GetValues(typeof(DFCareer.MaterialFlags))) { if ((career.ForbiddenMaterials & flag) == flag) { specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.forbiddenMaterial) + " " + forbMaterials[flag]); } } } // Forbidden shields (multiple) if (career.ForbiddenShields != 0) { Dictionary <DFCareer.ShieldFlags, string> forbShields = new Dictionary <DFCareer.ShieldFlags, string> { { DFCareer.ShieldFlags.Buckler, TextManager.Instance.GetLocalizedText(HardStrings.buckler) }, { DFCareer.ShieldFlags.KiteShield, TextManager.Instance.GetLocalizedText(HardStrings.kiteShield) }, { DFCareer.ShieldFlags.RoundShield, TextManager.Instance.GetLocalizedText(HardStrings.roundShield) }, { DFCareer.ShieldFlags.TowerShield, TextManager.Instance.GetLocalizedText(HardStrings.towerShield) } }; foreach (DFCareer.ShieldFlags flag in Enum.GetValues(typeof(DFCareer.ShieldFlags))) { if ((career.ForbiddenShields & flag) == flag) { specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.forbiddenShieldTypes) + " " + forbShields[flag]); } } } // Forbidden armor (multiple) if (career.ForbiddenArmors != 0) { Dictionary <DFCareer.ArmorFlags, string> forbArmors = new Dictionary <DFCareer.ArmorFlags, string> { { DFCareer.ArmorFlags.Chain, TextManager.Instance.GetLocalizedText(HardStrings.chain) }, { DFCareer.ArmorFlags.Leather, TextManager.Instance.GetLocalizedText(HardStrings.leather) }, { DFCareer.ArmorFlags.Plate, TextManager.Instance.GetLocalizedText(HardStrings.plate) } }; foreach (DFCareer.ArmorFlags flag in Enum.GetValues(typeof(DFCareer.ArmorFlags))) { if ((career.ForbiddenArmors & flag) == flag) { specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.forbiddenArmorType) + " " + forbArmors[flag]); } } } // Forbidden proficiencies (flags) // Expert proficiencies (flags) // Omitted - redundant // Spell point multiplier if (career.SpellPointMultiplier != DFCareer.SpellPointMultipliers.Times_0_50) { Dictionary <DFCareer.SpellPointMultipliers, string> spellPtMults = new Dictionary <DFCareer.SpellPointMultipliers, string> { { DFCareer.SpellPointMultipliers.Times_1_00, TextManager.Instance.GetLocalizedText(HardStrings.intInSpellPoints) }, { DFCareer.SpellPointMultipliers.Times_1_50, TextManager.Instance.GetLocalizedText(HardStrings.intInSpellPoints15) }, { DFCareer.SpellPointMultipliers.Times_1_75, TextManager.Instance.GetLocalizedText(HardStrings.intInSpellPoints175) }, { DFCareer.SpellPointMultipliers.Times_2_00, TextManager.Instance.GetLocalizedText(HardStrings.intInSpellPoints2) }, { DFCareer.SpellPointMultipliers.Times_3_00, TextManager.Instance.GetLocalizedText(HardStrings.intInSpellPoints3) }, }; specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.increasedMagery) + " " + spellPtMults[career.SpellPointMultiplier]); } // Spell absorption if (career.SpellAbsorption != DFCareer.SpellAbsorptionFlags.None) { Dictionary <DFCareer.SpellAbsorptionFlags, string> absorbConds = new Dictionary <DFCareer.SpellAbsorptionFlags, string> { { DFCareer.SpellAbsorptionFlags.Always, TextManager.Instance.GetLocalizedText(HardStrings.general) }, { DFCareer.SpellAbsorptionFlags.InDarkness, TextManager.Instance.GetLocalizedText(HardStrings.inDarkness) }, { DFCareer.SpellAbsorptionFlags.InLight, TextManager.Instance.GetLocalizedText(HardStrings.inLight) } }; specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.spellAbsorption) + " " + absorbConds[career.SpellAbsorption]); } // Spell point regeneration if (career.NoRegenSpellPoints) { specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.inabilityToRegen)); } // Talents if (career.AcuteHearing) { specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.acuteHearing)); } if (career.Athleticism) { specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.athleticism)); } if (career.AdrenalineRush) { specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.adrenalineRush)); } // Regeneration and rapid healing if (career.Regeneration != DFCareer.RegenerationFlags.None) { Dictionary <DFCareer.RegenerationFlags, string> regenConds = new Dictionary <DFCareer.RegenerationFlags, string> { { DFCareer.RegenerationFlags.Always, TextManager.Instance.GetLocalizedText(HardStrings.general) }, { DFCareer.RegenerationFlags.InDarkness, TextManager.Instance.GetLocalizedText(HardStrings.inDarkness) }, { DFCareer.RegenerationFlags.InLight, TextManager.Instance.GetLocalizedText(HardStrings.inLight) }, { DFCareer.RegenerationFlags.InWater, TextManager.Instance.GetLocalizedText(HardStrings.whileImmersed) } }; specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.regenerateHealth) + " " + regenConds[career.Regeneration]); } if (career.RapidHealing != DFCareer.RapidHealingFlags.None) { Dictionary <DFCareer.RapidHealingFlags, string> rapidHealingConds = new Dictionary <DFCareer.RapidHealingFlags, string> { { DFCareer.RapidHealingFlags.Always, TextManager.Instance.GetLocalizedText(HardStrings.general) }, { DFCareer.RapidHealingFlags.InDarkness, TextManager.Instance.GetLocalizedText(HardStrings.inDarkness) }, { DFCareer.RapidHealingFlags.InLight, TextManager.Instance.GetLocalizedText(HardStrings.inLight) } }; specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.rapidHealing) + " " + rapidHealingConds[career.RapidHealing]); } // Damage if (career.DamageFromSunlight) { specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.damage) + " " + TextManager.Instance.GetLocalizedText(HardStrings.fromSunlight)); } if (career.DamageFromHolyPlaces) { specials.Add(TextManager.Instance.GetLocalizedText(HardStrings.damage) + " " + TextManager.Instance.GetLocalizedText(HardStrings.fromHolyPlaces)); } // Add racial tolerances and abilities Dictionary <DFCareer.EffectFlags, string> raceEffectMods = new Dictionary <DFCareer.EffectFlags, string> { { DFCareer.EffectFlags.Paralysis, TextManager.Instance.GetLocalizedText(HardStrings.toParalysis) }, { DFCareer.EffectFlags.Magic, TextManager.Instance.GetLocalizedText(HardStrings.toMagic) }, { DFCareer.EffectFlags.Poison, TextManager.Instance.GetLocalizedText(HardStrings.toPoison) }, { DFCareer.EffectFlags.Fire, TextManager.Instance.GetLocalizedText(HardStrings.toFire) }, { DFCareer.EffectFlags.Frost, TextManager.Instance.GetLocalizedText(HardStrings.toFrost) }, { DFCareer.EffectFlags.Shock, TextManager.Instance.GetLocalizedText(HardStrings.toShock) }, { DFCareer.EffectFlags.Disease, TextManager.Instance.GetLocalizedText(HardStrings.toDisease) }, }; foreach (DFCareer.EffectFlags effectFlag in Enum.GetValues(typeof(DFCareer.EffectFlags))) { if (effectFlag != DFCareer.EffectFlags.None) { // Resistances if ((race.ResistanceFlags & effectFlag) == effectFlag) { string toAdd = TextManager.Instance.GetLocalizedText(HardStrings.resistance) + " " + raceEffectMods[effectFlag]; if (!specials.Contains(toAdd)) // prevent duplicates from career { specials.Add(toAdd); } } // Immunities if ((race.ImmunityFlags & effectFlag) == effectFlag) { string toAdd = TextManager.Instance.GetLocalizedText(HardStrings.immunity) + " " + raceEffectMods[effectFlag]; if (!specials.Contains(toAdd)) { specials.Add(toAdd); } } // Low tolerances if ((race.LowToleranceFlags & effectFlag) == effectFlag) { string toAdd = TextManager.Instance.GetLocalizedText(HardStrings.lowTolerance) + " " + raceEffectMods[effectFlag]; if (!specials.Contains(toAdd)) { specials.Add(toAdd); } } // Critical weaknesses if ((race.CriticalWeaknessFlags & effectFlag) == effectFlag) { string toAdd = TextManager.Instance.GetLocalizedText(HardStrings.criticalWeakness) + " " + raceEffectMods[effectFlag]; if (!specials.Contains(toAdd)) { specials.Add(toAdd); } } } } Dictionary <DFCareer.SpecialAbilityFlags, string> raceAbilities = new Dictionary <DFCareer.SpecialAbilityFlags, string> { { DFCareer.SpecialAbilityFlags.AcuteHearing, TextManager.Instance.GetLocalizedText(HardStrings.acuteHearing) }, { DFCareer.SpecialAbilityFlags.Athleticism, TextManager.Instance.GetLocalizedText(HardStrings.acuteHearing) }, { DFCareer.SpecialAbilityFlags.AdrenalineRush, TextManager.Instance.GetLocalizedText(HardStrings.adrenalineRush) }, { DFCareer.SpecialAbilityFlags.NoRegenSpellPoints, TextManager.Instance.GetLocalizedText(HardStrings.inabilityToRegen) }, { DFCareer.SpecialAbilityFlags.SunDamage, TextManager.Instance.GetLocalizedText(HardStrings.damage) + " " + TextManager.Instance.GetLocalizedText(HardStrings.fromSunlight) }, { DFCareer.SpecialAbilityFlags.HolyDamage, TextManager.Instance.GetLocalizedText(HardStrings.damage) + " " + TextManager.Instance.GetLocalizedText(HardStrings.fromHolyPlaces) } }; foreach (DFCareer.SpecialAbilityFlags abilityFlag in Enum.GetValues(typeof(DFCareer.SpecialAbilityFlags))) { if (abilityFlag != DFCareer.SpecialAbilityFlags.None && (race.SpecialAbilities & abilityFlag) == abilityFlag) { string toAdd = raceAbilities[abilityFlag]; if (!specials.Contains(toAdd)) { specials.Add(toAdd); } } } return(specials.ToArray()); }
/// <summary> /// Sets enemy career and prepares entity settings. /// </summary> public void SetEnemyCareer(MobileEnemy mobileEnemy, EntityTypes entityType) { if (entityType == EntityTypes.EnemyMonster) { careerIndex = mobileEnemy.ID; career = GetMonsterCareerTemplate((MonsterCareers)careerIndex); stats.SetPermanentFromCareer(career); // Enemy monster has predefined level, health and armor values. // Armor values can be modified below by equipment. level = mobileEnemy.Level; maxHealth = UnityEngine.Random.Range(mobileEnemy.MinHealth, mobileEnemy.MaxHealth + 1); for (int i = 0; i < ArmorValues.Length; i++) { ArmorValues[i] = (sbyte)(mobileEnemy.ArmorValue * 5); } } else if (entityType == EntityTypes.EnemyClass) { careerIndex = mobileEnemy.ID - 128; career = GetClassCareerTemplate((ClassCareers)careerIndex); stats.SetPermanentFromCareer(career); // I may have a better way to alter the attributes of individual enemy entities, this seems to be where it originates from, will possibly alter later on. // Enemy class is levelled to player and uses similar health rules // City guards are 3 to 6 levels above the player //level = GameManager.Instance.PlayerEntity.Level; // Definitely going to want to mess with this a lot eventually, this is apparently what makes the human enemies equal to the player level, will alter that. level = UnityEngine.Random.Range(1, 31); if (careerIndex == (int)MobileTypes.Knight_CityWatch) { level += UnityEngine.Random.Range(3, 7); } maxHealth = FormulaHelper.RollEnemyClassMaxHealth(level, career.HitPointsPerLevel); } else { career = new DFCareer(); careerIndex = -1; return; } this.mobileEnemy = mobileEnemy; this.entityType = entityType; name = career.Name; minMetalToHit = mobileEnemy.MinMetalToHit; team = mobileEnemy.Team; short skillsLevel = (short)((level * 5) + 30); if (skillsLevel > 100) { skillsLevel = 100; } for (int i = 0; i <= DaggerfallSkills.Count; i++) { skills.SetPermanentSkillValue(i, skillsLevel); } int[] personalityTraits = DaggerfallWorkshop.Utility.EnemyBasics.EnemyPersonalityTraitGenerator(this); // May put the method for the "context based" inventory modifiers here, but first i'll have to figure out how i'm going to do that exactly first. DaggerfallLoot.GenerateEnemyItems(items, personalityTraits, this); // Enemy classes and some monsters use equipment if (EquipmentUser()) { SetEnemyEquipment(personalityTraits); } // Assign spell lists if (entityType == EntityTypes.EnemyMonster) { if (careerIndex == (int)MonsterCareers.Imp) { SetEnemySpells(ImpSpells); } else if (careerIndex == (int)MonsterCareers.Ghost) { SetEnemySpells(GhostSpells); } else if (careerIndex == (int)MonsterCareers.OrcShaman) { SetEnemySpells(OrcShamanSpells); } else if (careerIndex == (int)MonsterCareers.Wraith) { SetEnemySpells(WraithSpells); } else if (careerIndex == (int)MonsterCareers.FrostDaedra) { SetEnemySpells(FrostDaedraSpells); } else if (careerIndex == (int)MonsterCareers.FireDaedra) { SetEnemySpells(FireDaedraSpells); } else if (careerIndex == (int)MonsterCareers.Daedroth) { SetEnemySpells(DaedrothSpells); } else if (careerIndex == (int)MonsterCareers.Vampire) { SetEnemySpells(VampireSpells); } else if (careerIndex == (int)MonsterCareers.DaedraSeducer) { SetEnemySpells(SeducerSpells); } else if (careerIndex == (int)MonsterCareers.VampireAncient) { SetEnemySpells(VampireAncientSpells); } else if (careerIndex == (int)MonsterCareers.DaedraLord) { SetEnemySpells(DaedraLordSpells); } else if (careerIndex == (int)MonsterCareers.Lich) { SetEnemySpells(LichSpells); } else if (careerIndex == (int)MonsterCareers.AncientLich) { SetEnemySpells(AncientLichSpells); } } else if (entityType == EntityTypes.EnemyClass && (mobileEnemy.CastsMagic)) { int spellListLevel = level / 3; if (spellListLevel > 6) { spellListLevel = 6; } SetEnemySpells(EnemyClassSpells[spellListLevel]); } FillVitalSigns(); // Could use this to set enemies health and other vitals at a lower level when they first spawn, to simulate them being already wounded or something. }
void ReadFile(BinaryReader reader) { // Read class resist, etc. flags DFCareer.CFGData cfg = new DFCareer.CFGData(); cfg.ResistanceFlags = reader.ReadByte(); cfg.ImmunityFlags = reader.ReadByte(); cfg.LowToleranceFlags = reader.ReadByte(); cfg.CriticalWeaknessFlags = reader.ReadByte(); // Read class special ability and spell point bitfield cfg.AbilityFlagsAndSpellPointsBitfield = reader.ReadUInt16(); // Read rapid healing flags cfg.RapidHealing = reader.ReadByte(); // Read regeneration flags cfg.Regeneration = reader.ReadByte(); // Unknown value cfg.Unknown1 = reader.ReadByte(); // Spell absorption flags cfg.SpellAbsorptionFlags = reader.ReadByte(); // Attack modifier against major enemy groups cfg.AttackModifierFlags = reader.ReadByte(); // Read forbidden material flags cfg.ForbiddenMaterialsFlags = reader.ReadUInt16(); // Read weapon, armor, shields bitfield Byte a = reader.ReadByte(); Byte b = reader.ReadByte(); Byte c = reader.ReadByte(); cfg.WeaponArmorShieldsBitfield = (UInt32)((a << 16) | (c << 8) | b); // Read primary skills cfg.PrimarySkill1 = reader.ReadByte(); cfg.PrimarySkill2 = reader.ReadByte(); cfg.PrimarySkill3 = reader.ReadByte(); // Read major skills cfg.MajorSkill1 = reader.ReadByte(); cfg.MajorSkill2 = reader.ReadByte(); cfg.MajorSkill3 = reader.ReadByte(); // Read minor skills cfg.MinorSkill1 = reader.ReadByte(); cfg.MinorSkill2 = reader.ReadByte(); cfg.MinorSkill3 = reader.ReadByte(); cfg.MinorSkill4 = reader.ReadByte(); cfg.MinorSkill5 = reader.ReadByte(); cfg.MinorSkill6 = reader.ReadByte(); // Read class name cfg.Name = file.ReadCStringSkip(reader, 0, 16); // Read 8 unknown bytes cfg.Unknown2 = reader.ReadBytes(8); // Hit points per level cfg.HitPointsPerLevelOrMonsterLevel = reader.ReadUInt16(); // Read advancement multiplier cfg.AdvancementMultiplier = reader.ReadUInt32(); // Read attributes cfg.Attributes = new UInt16[8]; for (int i = 0; i < 8; i++) { cfg.Attributes[i] = reader.ReadUInt16(); } // Structure data career = new DFCareer(cfg); }
public static int GetClassAffinityIndex(DFCareer custom, List <DFCareer> classes) { int highestAffinity = 0; int selectedIndex = 0; for (int i = 0; i < classes.Count; i++) { int affinity = 0; List <DFCareer.Skills> classSkills = new List <DFCareer.Skills>(); classSkills.Add(classes[i].PrimarySkill1); classSkills.Add(classes[i].PrimarySkill2); classSkills.Add(classes[i].PrimarySkill3); classSkills.Add(classes[i].MajorSkill1); classSkills.Add(classes[i].MajorSkill2); classSkills.Add(classes[i].MajorSkill3); classSkills.Add(classes[i].MinorSkill1); classSkills.Add(classes[i].MinorSkill2); classSkills.Add(classes[i].MinorSkill3); classSkills.Add(classes[i].MinorSkill4); classSkills.Add(classes[i].MinorSkill5); classSkills.Add(classes[i].MinorSkill6); if (classSkills.Contains(custom.PrimarySkill1)) { affinity++; } if (classSkills.Contains(custom.PrimarySkill2)) { affinity++; } if (classSkills.Contains(custom.PrimarySkill3)) { affinity++; } if (classSkills.Contains(custom.MajorSkill1)) { affinity++; } if (classSkills.Contains(custom.MajorSkill2)) { affinity++; } if (classSkills.Contains(custom.MajorSkill3)) { affinity++; } if (classSkills.Contains(custom.MinorSkill1)) { affinity++; } if (classSkills.Contains(custom.MinorSkill2)) { affinity++; } if (classSkills.Contains(custom.MinorSkill3)) { affinity++; } if (classSkills.Contains(custom.MinorSkill4)) { affinity++; } if (classSkills.Contains(custom.MinorSkill5)) { affinity++; } if (classSkills.Contains(custom.MinorSkill6)) { affinity++; } if (affinity > highestAffinity) { highestAffinity = affinity; selectedIndex = i; } } return(selectedIndex); }
void ReadFile(BinaryReader reader) { // Read class resist, etc. flags DFCareer.CFGData cfg = new DFCareer.CFGData(); cfg.ResistanceFlags = reader.ReadByte(); cfg.ImmunityFlags = reader.ReadByte(); cfg.LowToleranceFlags = reader.ReadByte(); cfg.CriticalWeaknessFlags = reader.ReadByte(); // Read class special ability and spell point bitfield cfg.AbilityFlagsAndSpellPointsBitfield = reader.ReadUInt16(); // Read rapid healing flags cfg.RapidHealing = reader.ReadByte(); // Read regeneration flags cfg.Regeneration = reader.ReadByte(); // Unknown value cfg.Unknown1 = reader.ReadByte(); // Spell absorption flags cfg.SpellAbsorptionFlags = reader.ReadByte(); // Attack modifier against major enemy groups cfg.AttackModifierFlags = reader.ReadByte(); // Read forbidden material flags cfg.ForbiddenMaterialsFlags = reader.ReadUInt16(); // Read weapon, armor, shields bitfield Byte a = reader.ReadByte(); Byte b = reader.ReadByte(); Byte c = reader.ReadByte(); cfg.WeaponArmorShieldsBitfield = (UInt32)((a << 16) | (c << 8) | b); // Read primary skills cfg.PrimarySkill1 = reader.ReadByte(); cfg.PrimarySkill2 = reader.ReadByte(); cfg.PrimarySkill3 = reader.ReadByte(); // Read major skills cfg.MajorSkill1 = reader.ReadByte(); cfg.MajorSkill2 = reader.ReadByte(); cfg.MajorSkill3 = reader.ReadByte(); // Read minor skills cfg.MinorSkill1 = reader.ReadByte(); cfg.MinorSkill2 = reader.ReadByte(); cfg.MinorSkill3 = reader.ReadByte(); cfg.MinorSkill4 = reader.ReadByte(); cfg.MinorSkill5 = reader.ReadByte(); cfg.MinorSkill6 = reader.ReadByte(); // Read class name cfg.Name = file.ReadCStringSkip(reader, 0, 16); // Read 8 unknown bytes cfg.Unknown2 = reader.ReadBytes(8); // Hit points per level cfg.HitPointsPerLevel = reader.ReadUInt16(); // Read advancement multiplier cfg.AdvancementMultiplier = reader.ReadUInt32(); // Read attributes cfg.Attributes = new UInt16[8]; for (int i = 0; i < 8; i++) { cfg.Attributes[i] = reader.ReadUInt16(); } // Structure data career = new DFCareer(cfg); }
string[] GetClassSpecials() { List <string> specials = new List <string>(); DFCareer career = GameManager.Instance.PlayerEntity.Career; // Tolerances Dictionary <DFCareer.Tolerance, string> tolerances = new Dictionary <DFCareer.Tolerance, string> { { DFCareer.Tolerance.CriticalWeakness, HardStrings.criticalWeakness }, { DFCareer.Tolerance.Immune, HardStrings.immunity }, { DFCareer.Tolerance.LowTolerance, HardStrings.lowTolerance }, { DFCareer.Tolerance.Resistant, HardStrings.resistance } }; if (career.Paralysis != DFCareer.Tolerance.Normal) { specials.Add(tolerances[career.Paralysis] + " " + HardStrings.toParalysis); } if (career.Magic != DFCareer.Tolerance.Normal) { specials.Add(tolerances[career.Magic] + " " + HardStrings.toMagic); } if (career.Poison != DFCareer.Tolerance.Normal) { specials.Add(tolerances[career.Poison] + " " + HardStrings.toPoison); } if (career.Fire != DFCareer.Tolerance.Normal) { specials.Add(tolerances[career.Fire] + " " + HardStrings.toFire); } if (career.Frost != DFCareer.Tolerance.Normal) { specials.Add(tolerances[career.Frost] + " " + HardStrings.toFrost); } if (career.Shock != DFCareer.Tolerance.Normal) { specials.Add(tolerances[career.Shock] + " " + HardStrings.toShock); } if (career.Disease != DFCareer.Tolerance.Normal) { specials.Add(tolerances[career.Disease] + " " + HardStrings.toDisease); } // Weapon Proficiencies Dictionary <DFCareer.Proficiency, string> profs = new Dictionary <DFCareer.Proficiency, string> { { DFCareer.Proficiency.Expert, HardStrings.expertiseIn }, { DFCareer.Proficiency.Forbidden, HardStrings.forbiddenWeaponry } }; if (career.ShortBlades != DFCareer.Proficiency.Normal) { specials.Add(profs[career.ShortBlades] + " " + HardStrings.shortBlade); } if (career.LongBlades != DFCareer.Proficiency.Normal) { specials.Add(profs[career.LongBlades] + " " + HardStrings.longBlade); } if (career.HandToHand != DFCareer.Proficiency.Normal) { specials.Add(profs[career.HandToHand] + " " + HardStrings.handToHand); } if (career.Axes != DFCareer.Proficiency.Normal) { specials.Add(profs[career.Axes] + " " + HardStrings.axe); } if (career.BluntWeapons != DFCareer.Proficiency.Normal) { specials.Add(profs[career.BluntWeapons] + " " + HardStrings.bluntWeapon); } if (career.MissileWeapons != DFCareer.Proficiency.Normal) { specials.Add(profs[career.MissileWeapons] + " " + HardStrings.missileWeapon); } // Attack modifiers Dictionary <DFCareer.AttackModifier, string> atkMods = new Dictionary <DFCareer.AttackModifier, string> { { DFCareer.AttackModifier.Bonus, HardStrings.bonusToHit }, { DFCareer.AttackModifier.Phobia, HardStrings.phobia } }; if (career.UndeadAttackModifier != DFCareer.AttackModifier.Normal) { specials.Add(atkMods[career.UndeadAttackModifier] + " " + HardStrings.undead); } if (career.DaedraAttackModifier != DFCareer.AttackModifier.Normal) { specials.Add(atkMods[career.DaedraAttackModifier] + " " + HardStrings.daedra); } if (career.HumanoidAttackModifier != DFCareer.AttackModifier.Normal) { specials.Add(atkMods[career.HumanoidAttackModifier] + " " + HardStrings.humanoid); } if (career.AnimalsAttackModifier != DFCareer.AttackModifier.Normal) { specials.Add(atkMods[career.AnimalsAttackModifier] + " " + HardStrings.animals); } // Darkness/light powered magery if (career.DarknessPoweredMagery != DFCareer.DarknessMageryFlags.Normal) { if ((career.DarknessPoweredMagery & DFCareer.DarknessMageryFlags.ReducedPowerInLight) == DFCareer.DarknessMageryFlags.ReducedPowerInLight) { specials.Add(HardStrings.darknessPoweredMagery + " " + HardStrings.lowerMagicAbilityDaylight); } if ((career.DarknessPoweredMagery & DFCareer.DarknessMageryFlags.UnableToCastInLight) == DFCareer.DarknessMageryFlags.UnableToCastInLight) { specials.Add(HardStrings.darknessPoweredMagery + " " + HardStrings.unableToUseMagicInDaylight); } } if (career.LightPoweredMagery != DFCareer.LightMageryFlags.Normal) { if ((career.LightPoweredMagery & DFCareer.LightMageryFlags.ReducedPowerInDarkness) == DFCareer.LightMageryFlags.ReducedPowerInDarkness) { specials.Add(HardStrings.lightPoweredMagery + " " + HardStrings.lowerMagicAbilityDarkness); } if ((career.LightPoweredMagery & DFCareer.LightMageryFlags.UnableToCastInDarkness) == DFCareer.LightMageryFlags.UnableToCastInDarkness) { specials.Add(HardStrings.lightPoweredMagery + " " + HardStrings.unableToUseMagicInDarkness); } } // Forbidden materials (multiple) if (career.ForbiddenMaterials != 0) { Dictionary <DFCareer.MaterialFlags, string> forbMaterials = new Dictionary <DFCareer.MaterialFlags, string> { { DFCareer.MaterialFlags.Adamantium, HardStrings.adamantium }, { DFCareer.MaterialFlags.Daedric, HardStrings.daedric }, { DFCareer.MaterialFlags.Dwarven, HardStrings.dwarven }, { DFCareer.MaterialFlags.Ebony, HardStrings.ebony }, { DFCareer.MaterialFlags.Elven, HardStrings.elven }, { DFCareer.MaterialFlags.Iron, HardStrings.iron }, { DFCareer.MaterialFlags.Mithril, HardStrings.mithril }, { DFCareer.MaterialFlags.Orcish, HardStrings.orcish }, { DFCareer.MaterialFlags.Silver, HardStrings.silver }, { DFCareer.MaterialFlags.Steel, HardStrings.steel } }; foreach (DFCareer.MaterialFlags flag in Enum.GetValues(typeof(DFCareer.MaterialFlags))) { if ((career.ForbiddenMaterials & flag) == flag) { specials.Add(HardStrings.forbiddenMaterial + " " + forbMaterials[flag]); } } } // Forbidden shields (multiple) if (career.ForbiddenShields != 0) { Dictionary <DFCareer.ShieldFlags, string> forbShields = new Dictionary <DFCareer.ShieldFlags, string> { { DFCareer.ShieldFlags.Buckler, HardStrings.buckler }, { DFCareer.ShieldFlags.KiteShield, HardStrings.kiteShield }, { DFCareer.ShieldFlags.RoundShield, HardStrings.roundShield }, { DFCareer.ShieldFlags.TowerShield, HardStrings.towerShield } }; foreach (DFCareer.ShieldFlags flag in Enum.GetValues(typeof(DFCareer.ShieldFlags))) { if ((career.ForbiddenShields & flag) == flag) { specials.Add(HardStrings.forbiddenShieldTypes + " " + forbShields[flag]); } } } // Forbidden armor (multiple) if (career.ForbiddenArmors != 0) { Dictionary <DFCareer.ArmorFlags, string> forbArmors = new Dictionary <DFCareer.ArmorFlags, string> { { DFCareer.ArmorFlags.Chain, HardStrings.chain }, { DFCareer.ArmorFlags.Leather, HardStrings.leather }, { DFCareer.ArmorFlags.Plate, HardStrings.plate } }; foreach (DFCareer.ArmorFlags flag in Enum.GetValues(typeof(DFCareer.ArmorFlags))) { if ((career.ForbiddenArmors & flag) == flag) { specials.Add(HardStrings.forbiddenArmorType + " " + forbArmors[flag]); } } } // Forbidden proficiencies (flags) // Expert proficiencies (flags) // Omitted - redundant // Spell point multiplier if (career.SpellPointMultiplier != DFCareer.SpellPointMultipliers.Times_0_50) { Dictionary <DFCareer.SpellPointMultipliers, string> spellPtMults = new Dictionary <DFCareer.SpellPointMultipliers, string> { { DFCareer.SpellPointMultipliers.Times_1_00, HardStrings.intInSpellPoints }, { DFCareer.SpellPointMultipliers.Times_1_50, HardStrings.intInSpellPoints15 }, { DFCareer.SpellPointMultipliers.Times_1_75, HardStrings.intInSpellPoints175 }, { DFCareer.SpellPointMultipliers.Times_2_00, HardStrings.intInSpellPoints2 }, { DFCareer.SpellPointMultipliers.Times_3_00, HardStrings.intInSpellPoints3 }, }; specials.Add(HardStrings.increasedMagery + " " + spellPtMults[career.SpellPointMultiplier]); } // Spell absorption if (career.SpellAbsorption != DFCareer.SpellAbsorptionFlags.None) { Dictionary <DFCareer.SpellAbsorptionFlags, string> absorbConds = new Dictionary <DFCareer.SpellAbsorptionFlags, string> { { DFCareer.SpellAbsorptionFlags.Always, HardStrings.general }, { DFCareer.SpellAbsorptionFlags.InDarkness, HardStrings.inDarkness }, { DFCareer.SpellAbsorptionFlags.InLight, HardStrings.inLight } }; specials.Add(HardStrings.spellAbsorption + " " + absorbConds[career.SpellAbsorption]); } // Spell point regeneration if (career.NoRegenSpellPoints) { specials.Add(HardStrings.inabilityToRegen); } // Talents if (career.AcuteHearing) { specials.Add(HardStrings.acuteHearing); } if (career.Athleticism) { specials.Add(HardStrings.athleticism); } if (career.AdrenalineRush) { specials.Add(HardStrings.adrenalineRush); } // Regeneration and rapid healing if (career.Regeneration != DFCareer.RegenerationFlags.None) { Dictionary <DFCareer.RegenerationFlags, string> regenConds = new Dictionary <DFCareer.RegenerationFlags, string> { { DFCareer.RegenerationFlags.Always, HardStrings.general }, { DFCareer.RegenerationFlags.InDarkness, HardStrings.inDarkness }, { DFCareer.RegenerationFlags.InLight, HardStrings.inLight }, { DFCareer.RegenerationFlags.InWater, HardStrings.whileImmersed } }; specials.Add(HardStrings.regenerateHealth + " " + regenConds[career.Regeneration]); } if (career.RapidHealing != DFCareer.RapidHealingFlags.None) { Dictionary <DFCareer.RapidHealingFlags, string> rapidHealingConds = new Dictionary <DFCareer.RapidHealingFlags, string> { { DFCareer.RapidHealingFlags.Always, HardStrings.general }, { DFCareer.RapidHealingFlags.InDarkness, HardStrings.inDarkness }, { DFCareer.RapidHealingFlags.InLight, HardStrings.inLight } }; specials.Add(HardStrings.rapidHealing + " " + rapidHealingConds[career.RapidHealing]); } // Damage if (career.DamageFromSunlight) { specials.Add(HardStrings.damage + " " + HardStrings.fromSunlight); } if (career.DamageFromHolyPlaces) { specials.Add(HardStrings.damage + " " + HardStrings.fromHolyPlaces); } return(specials.ToArray()); }
void SetClass(DFCareer dfClass) { Setup(); this.dfClass = dfClass; skillsRollout.SetClassSkills(dfClass); }
/// <summary> /// Sets the career template for a custom (ie: mod-provided) enemy type. /// </summary> /// <param name="enemyId">ID, as defined in EnemyBasics.Enemies</param> /// <param name="career">The custom DFCareer template to register</param> public static void RegisterCustomCareerTemplate(int enemyId, DFCareer career) { // Use indexer so that mods can overwrite previous values added by mods // ex: mod 1 provides new enemies, mod 2 rebalances them CustomCareerTemplates[enemyId] = career; }
DFCareer PopulateCareer() { DFCareer c = new DFCareer { AcuteHearing = false, AdrenalineRush = false, AdvancementMultiplier = 1.546154f, Agility = 45, AnimalsAttackModifier = DFCareer.AttackModifier.Normal, Athleticism = false, Axes = DFCareer.Proficiency.Normal, BluntWeapons = DFCareer.Proficiency.Normal, DaedraAttackModifier = DFCareer.AttackModifier.Normal, DamageFromHolyPlaces = false, DamageFromSunlight = false, DarknessPoweredMagery = DFCareer.DarknessMageryFlags.Normal, Disease = DFCareer.Tolerance.Normal, Endurance = 40, Fire = DFCareer.Tolerance.Normal, ForbiddenMaterials = (DFCareer.MaterialFlags) 0, Frost = DFCareer.Tolerance.Normal, HandToHand = DFCareer.Proficiency.Normal, HitPointsPerLevel = 30, HumanoidAttackModifier = DFCareer.AttackModifier.Normal, Intelligence = 65, LightPoweredMagery = DFCareer.LightMageryFlags.Normal, LongBlades = DFCareer.Proficiency.Normal, Luck = 50, Magic = DFCareer.Tolerance.Normal, MajorSkill1 = DFCareer.Skills.Restoration, MajorSkill2 = DFCareer.Skills.Archery, MajorSkill3 = DFCareer.Skills.ShortBlade, MinorSkill1 = DFCareer.Skills.Alteration, MinorSkill2 = DFCareer.Skills.CriticalStrike, MinorSkill3 = DFCareer.Skills.Medical, MinorSkill4 = DFCareer.Skills.Illusion, MinorSkill5 = DFCareer.Skills.Mysticism, MinorSkill6 = DFCareer.Skills.Thaumaturgy, MissileWeapons = DFCareer.Proficiency.Normal, Name = "Spellsword", NoRegenSpellPoints = false, Paralysis = DFCareer.Tolerance.Normal, Personality = 35, Poison = DFCareer.Tolerance.Normal, PrimarySkill1 = DFCareer.Skills.Destruction, PrimarySkill2 = DFCareer.Skills.Daedric, PrimarySkill3 = DFCareer.Skills.LongBlade, RapidHealing = DFCareer.RapidHealingFlags.None, Regeneration = DFCareer.RegenerationFlags.None, Shock = DFCareer.Tolerance.Normal, ShortBlades = DFCareer.Proficiency.Normal, Speed = 50, SpellAbsorption = DFCareer.SpellAbsorptionFlags.None, SpellPointMultiplier = DFCareer.SpellPointMultipliers.Times_0_50, SpellPointMultiplierValue = 0.5f, Strength = 75, UndeadAttackModifier = DFCareer.AttackModifier.Normal, Willpower = 40 }; return(c); }
/// <summary> /// Sets enemy career and prepares entity settings. /// </summary> public void SetEnemyCareer(MobileEnemy mobileEnemy, EntityTypes entityType) { if (entityType == EntityTypes.EnemyMonster) { careerIndex = (int)mobileEnemy.ID; career = GetMonsterCareerTemplate((MonsterCareers)careerIndex); stats.SetFromCareer(career); // Enemy monster has predefined level, health and armor values level = mobileEnemy.Level; maxHealth = UnityEngine.Random.Range(mobileEnemy.MinHealth, mobileEnemy.MaxHealth + 1); // Monsters have the same armor value for all body parts for (int i = 0; i < ArmorValues.Length; i++) { ArmorValues[i] = (sbyte)(mobileEnemy.ArmorValue * 5); } } else if (entityType == EntityTypes.EnemyClass) { careerIndex = (int)mobileEnemy.ID - 128; career = GetClassCareerTemplate((ClassCareers)careerIndex); stats.SetFromCareer(career); // Enemy class is levelled to player and uses similar health rules level = GameManager.Instance.PlayerEntity.Level; maxHealth = FormulaHelper.RollEnemyClassMaxHealth(level, career.HitPointsPerLevel); // Enemy classes may be able to equip armor. Not sure yet how classic does this. // For now, using fudge value of 60. for (int i = 0; i < ArmorValues.Length; i++) { ArmorValues[i] = 60; } // Enemy class damage is temporarily set by a fudged level multiplier // This will change once full entity setup and items are available const float damageMultiplier = 4f; mobileEnemy.MinDamage = (int)(level * damageMultiplier); mobileEnemy.MaxDamage = (int)((level + 2) * damageMultiplier); } else { career = new DFCareer(); careerIndex = -1; return; } this.mobileEnemy = mobileEnemy; this.entityType = entityType; name = career.Name; short skillsLevel = (short)((level * 5) + 30); if (skillsLevel > 100) { skillsLevel = 100; } for (int i = 0; i <= DaggerfallSkills.Count; i++) { skills.SetSkillValue(i, skillsLevel); } FillVitalSigns(); }