public static int ArcaneSpellLevelCanCast(this GameObject obj) { var spellLvlMax = 0; foreach (var classEnum in D20ClassSystem.Classes.Keys) { if (D20ClassSystem.IsArcaneCastingClass(classEnum)) { spellLvlMax = Math.Max(spellLvlMax, GameSystems.Spell.GetMaxSpellLevel(obj, classEnum, 0)); } } return(spellLvlMax); }
public void Activate() { var partyAlignment = GameSystems.Party.PartyAlignment; _partyAlignmentLabel.Text = "#{pc_creation:16000} @1" + GameSystems.Stat.GetAlignmentName(partyAlignment); foreach (var(alignment, button) in _alignmentButtons) { // TODO: We should show a tooltip explaining WHY a certain alignment is unavailable var compatibleWithParty = IsCompatibleAlignment(partyAlignment, alignment); var compatibleWithClass = D20ClassSystem.IsCompatibleAlignment(_pkt.classCode, alignment); button.SetDisabled(!compatibleWithParty || !compatibleWithClass); } UpdateSelection(); }
public int LevelUpApply(GameObject obj, LevelupPacket levelUpPacket) { var numLvls = obj.GetArrayLength(obj_f.critter_level_idx); obj.SetInt32(obj_f.critter_level_idx, numLvls, (int)levelUpPacket.classCode); if ((levelUpPacket.flags & 1) == 0) { // Raise stat var scoreRaised = levelUpPacket.abilityScoreRaised; if (scoreRaised >= Stat.strength && scoreRaised <= Stat.charisma) { var currentValue = obj.GetBaseStat(levelUpPacket.abilityScoreRaised); GameSystems.Stat.SetBasicStat(obj, levelUpPacket.abilityScoreRaised, currentValue + 1); } foreach (var feat in levelUpPacket.feats) { if (feat != FeatId.NONE) { GameSystems.Feat.AddFeat(obj, feat); } if (feat == FeatId.SKILL_MASTERY) { GameUiBridge.ApplySkillMastery(obj); } } foreach (var kvp in levelUpPacket.skillPointsAdded) { GameSystems.Skill.AddSkillRanks(obj, kvp.Key, kvp.Value); } var spellClassCode = ((int)levelUpPacket.classCode & 0x7F) | 0x80; var spellToRemove = levelUpPacket.spellEnumToRemove; if (spellToRemove != 0) { var spellLevel = GameSystems.Spell.GetSpellLevelBySpellClass(spellToRemove, spellClassCode); GameSystems.Spell.SpellKnownRemove(obj, levelUpPacket.spellEnumToRemove, spellLevel, spellClassCode); } foreach (var spellEnum in levelUpPacket.spellEnums) { var spellLevel = GameSystems.Spell.GetSpellLevelBySpellClass(spellEnum, spellClassCode); GameSystems.Spell.SpellKnownAdd(obj, spellEnum, spellClassCode, spellLevel, 1, 0); } var conMod = obj.GetBaseStat(Stat.con_mod); var classHitDie = D20ClassSystem.GetClassHitDice(levelUpPacket.classCode); var hpRolled = classHitDie.Roll(); if (hpRolled + conMod < 1) { hpRolled = 1 - conMod; } var maxHp = obj.GetBaseStat(Stat.hp_max); GameSystems.Stat.SetBasicStat(obj, Stat.hp_max, maxHp + hpRolled); GameSystems.D20.Status.D20StatusRefresh(obj); GameSystems.Critter.BuildRadialMenu(obj); } return(obj.GetBaseStat(levelUpPacket.classCode)); }
public bool CanSelect(GameObject playerObj, DeityId deityId) { var deity = DeitiesById[deityId]; if (!deity.IsSelectable) { return(false); } var race = playerObj.GetRace(); if (D20RaceSystem.UseBaseRaceForDeity(race)) { race = D20RaceSystem.GetBaseRace(race); } var alignment = playerObj.GetAlignment(); var classEnum = (Stat)playerObj.GetInt32(obj_f.critter_level_idx, 0); var deityClass = D20ClassSystem.GetDeityClass(classEnum); var isCleric = deityClass == Stat.level_cleric; if (isCleric) { if (deityId == DeityId.NONE) { // Clerics MUST have a deity. return(false); } } var hasRace = deity.FavoredRaces.Contains(race); if (hasRace && !isCleric) // can't have Clerics casting spells of opposed alignments { return(true); } // doesn't have race automatic, so check the supported calsses var hasClass = deity.FavoredClasses.Count == 0 || deity.FavoredClasses.Contains(deityClass); if (!hasClass && !isCleric) { return(false); } // special casing - probably buggy but that's how it was in the original if (deity.FavoredRaces.Count > 0) { var isException = false; if (deityId == DeityId.CORELLON_LARETHIAN) { // Corellon Larethian for Bards isException = deityClass == Stat.level_bard; } else if (deityId == DeityId.EHLONNA) { // Ehlonna isException = deityClass == Stat.level_cleric; } if (!isException && !hasRace) { return(false); } } // check alignment if (deityId == DeityId.ST_CUTHBERT) // St. Cuthbert special case { return(alignment == Alignment.LAWFUL_GOOD || alignment == Alignment.LAWFUL); } var deityAlignment = deity.Alignment; if (deityAlignment == Alignment.NEUTRAL && !isCleric) { return(true); } if (alignment == deityAlignment) { return(true); } return(GameSystems.Stat.AlignmentsUnopposed(alignment, deityAlignment, true)); }