Animal Companion for Paladins (alpha)

I tried to figure how to set up Animal Companion on Paladins for a fella, and got everything to work except the GUI that allows players to choose their companion’s type and name. So, long story short, there’s two scripts here. The first is a console script that needs to be run once, setting the companion’s type and name as variables on the currently controlled character. The second is an override spellscript for the Animal Companion spellability.

throw them both into a folder in /Override (and compile them) if you’re curious to try it …

This is alpha material. The only test that’s been done is - I pressed the feat button and an animal appeared.

// 'anico'
/*
    console script.
    Grants a Paladin the AnimalCompanion feat.

    NOTE: This requires a modified summoning script ( nw_s2_animalcom ) to work.

    - iType  : the type of companion as referenced by row in Hen_Companion.2da
    - sLabel : a first name for your animal companion

    Example ...

    `
    debugmode 1
    rs anico(0,"frank")
    debugmode 0
    `

    that's a badger by the name of frank


    To revert to a standard Animal Companion run this script like so:

    rs anico(-1,"")
*/

void main(int iType, string sLabel)
{
    object oPc = GetControlledCharacter(OBJECT_SELF);

    if (iType < 0) // clear the companion variables
    {
        if (GetLocalInt(oPc, "AniCoType"))
        {
            SendMessageToPC(oPc, "<c=green>NOTICE :</c> Your Animal Companion has been cleared.");

            DeleteLocalInt(oPc, "AniCoType");
            DeleteLocalString(oPc, "AniCoLabel");
        }
        else
            SendMessageToPC(oPc, "<c=green>NOTICE :</c> Your Animal Companion was not set so there's no point in clearing it.");
    }
    else if (GetLevelByClass(CLASS_TYPE_PALADIN, oPc))
    {
        SendMessageToPC(oPc, "<c=blue>WARNING :</c> What you have done will overrule any"
                + " Animal Companion that you can summon as a Druid or Ranger or Cleric."
                + " To revert that behavior rerun this script with parameters -1 and a"
                + " blank string. Your PC will however keep the Animal Companion feat"
                + " regardless of whether you had it before - but it won't work unless"
                + " your PC has a standard Animal Companion or you run this script to"
                + " reset your Paladin's companion.");

        if (!GetHasFeat(FEAT_ANIMAL_COMPANION, oPc))
            FeatAdd(oPc, FEAT_ANIMAL_COMPANION, FALSE, TRUE);

        iType += 1; // have to increment so that the spellscript doesn't think "0" (unset) is a badger

        SetLocalInt(oPc, "AniCoType", iType);
        SetLocalString(oPc, "AniCoLabel", sLabel);
    }
    else
        SendMessageToPC(oPc, "<c=red>ERROR :</c> ( anico ) You must have levels in the Paladin class.");
}

the spellscript:

//::///////////////////////////////////////////////
//:: Summon Animal Companion
//:: 'nw_s2_animalcom'
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This spellability summons an Animal Companion.
*/

int kL_GetAnimalTier(object oPC);
int kL_GetAssociateLevel(object oPC);

//
void main()
{
    object oCaster = OBJECT_SELF;

    int iType = GetLocalInt(oCaster, "AniCoType");
    if (iType)
    {
        iType -= 1; // incremented when set; decrement to get the true reference

        string sResref  = Get2DAString("hen_companion", "BASERESREF_PREFIX", iType);
               sResref += IntToString(kL_GetAnimalTier(oCaster));

        SummonAnimalCompanion(oCaster, sResref);

        object oAnico = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oCaster);
        if (GetIsObjectValid(oAnico))
        {
            string sLabel = GetLocalString(oCaster, "AniCoLabel");
            SetFirstName(oAnico, sLabel);
        }
        else
            SendMessageToPC(oCaster, "<c=red>ERROR :</c> ( nw_s2_animalcom ) Animal Companion is invalid. sResref= " + sResref);
    }
    else
        SummonAnimalCompanion(); // standard summon
}


//
int kL_GetAnimalTier(object oPC)
{
    return kL_GetAssociateLevel(oPC) / 3 + 1;
}

//
int kL_GetAssociateLevel(object oPC)
{
    int iLevel = 0;

    if (   GetHasFeat(1835, oPC) // Animal Domain Cleric (yep, all 3 of them.)
        || GetHasFeat( 312, oPC)
        || GetHasFeat(1520, oPC))
    {
        iLevel += GetLevelByClass(CLASS_TYPE_CLERIC, oPC);
    }

    int iClass = GetLevelByClass(CLASS_TYPE_RANGER, oPC);
    if (iClass > 3) iLevel += (iClass - 3);

    iLevel += GetLevelByClass(CLASS_TYPE_DRUID, oPC);

    iLevel += GetLevelByClass(CLASS_TYPE_PALADIN, oPC); // full Paladin levels

    return iLevel;
}
2 Likes

Is this so the Paladin can summon his Warhorse? If so that would be exciting news.:four_leaf_clover: In honor of my ancestor who was a Green man for St Paddy’s day.

it’s just for an Animal Companion. It’d take a lot more effort to implement a bona fide Paladin’s Warhorse.

btw, I suspect that with a simple modification (bypassing the CLASS_TYPE_PALADIN condition) in the console script, it can also be used by Druids/Rangers/Clerics to switch their animal’s type and name on a whim.

in fact, I believe that the only thing preventing any class from getting an Animal Companion like this is because the spellscript doesn’t consider levels in classes other than those mentioned; the animal would be stuck at level 1. just replace the routine with GetTotalLevels(oPC) …

it’s just a lark, but i admit in one of my tests, my Paladin summoned an Air Elemental - and suddenly the whole thing became believable (so to speak )

1 Like

That is very interesting.