Example #1
0
    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);
    }
Example #2
0
    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));
    }