Adding zest to your persistent world using DMFI languages
This scripting forum is to discuss scripting and for those needing help scripting to get help from others.

Moderators: Mermut, rdjparadis

Post Reply
User avatar
Winterhawk99
Posts: 1648
Joined: Thu Oct 08, 2009 12:00 am
ctp: Yes
nwnihof: Yes
Location: Pa.
Contact:

Adding zest to your persistent world using DMFI languages

Post by Winterhawk99 »

Adding languages to a world can be great fun and add so much to a persistent world. It also encourages parties because its hard to know all of them even if you are a mage with a lot of lore. I have put in several quests to many persistent worlds that are language specific to both encourage parties and add flavor to the module itself.

There are several ways to put them into the mod from a normal dialogue with a teacher to UserDefinedevents. My lead scripter Mermut choose to do everything in conversation with a teacher placed near the entrance area of the module. Mermut is a wonderful scripter/rper. She's one of a handful of the best scripters I ever worked with so I will be using her language scripts for this tutorial.

So you want to add languages: This will be about the easiest way to do it: the first thing you need to do is add a language teacher to the mod preferably in a library or other place you would find such a personage. Usually its an old guy with spectacles and wearing wizard robes.

Next you make your conversation text. I will be using the harvest moon conversation text from the mod. Not all of it just some so you get the gist of it.

PC: You've travelled a lot. Do you think I might be able to learn a language?

Npc: You look like you can learn a language or two. (set your conditional (text appears when))
No you need to study more

If pcs gets you look like you can learn

PC: Yes, I would like to learn.
This takes too much effort.

If PC says yes they would like to learn
Npc: Choose a language to learn

PC gets their choices:

Elven Text appears script, Actions taken script.
Halfling
Draconic
etc
more ( opens up a new dialoge box for more languages

Npc if player chooses more option:

Player gets more choices

Animal
Thieves Cant
Celestrial
etc.

In the next post I'll show you the scripts used for the conversation file.
CTP team member
http://www.harvestmoonconsortium.com
Chief cook and bottle washer for Harvest Moon

User avatar
Winterhawk99
Posts: 1648
Joined: Thu Oct 08, 2009 12:00 am
ctp: Yes
nwnihof: Yes
Location: Pa.
Contact:

Re: Adding zest to your persistent world using DMFI language

Post by Winterhawk99 »

The first script we have is the conditional to see if a player has both the intelligence and lore to acquire another language. On harvest moon we used both the intelligence modifier and lore skill points to determine that. We also had several races that automatically acquired a language when they first came into the mod. This would be their native language or a language native to their non-human parent in the cases of Assimar, half-elf or say Triefling. This script will also have an include to which I will add on the post also so you can see how everything works.

First the script in the conversation file. This one is simple.

Code: Select all

Language learn more:

//::///////////////////////////////////////////////
//:: Name lang_learnmore
//:://////////////////////////////////////////////
/*
    Return TRUE if the PC can learn more languages
        else return FALSE
*/
//:://////////////////////////////////////////////
//:: Created By: Mermut
//:: Created On: August 3, 2007
//:://////////////////////////////////////////////
#include "lang_learn_inc"

int StartingConditional()
{
    object oPC = GetPCSpeaker();

    if (GetMaxLanguages(oPC) - GetNumLanguagesKnown(oPC) >= 1)
        return TRUE;
    else
        return FALSE;
Ok so very simple script that doesn't tell you much except it is determining if the pc can learn a language. Ah but it has an include what does the include say. Well here it is:

Code: Select all

include for conditional script can pc learn more languages.

//::///////////////////////////////////////////////
//:: Name lang_learn_inc
//:://////////////////////////////////////////////
/*
    Functions related to the learning langauge conversation

    LANGUAGE NUMBERS
    case 1: //Elven
    case 2: //Gnome
    case 3: //Halfling
    case 4: //Dwarf
    case 5: //Orc
    case 6: //Goblin
    case 7: //Draconic
    case 8: //Animal
    case 9: //Thieves Cant
    case 10: //Celestial
    case 11: //Abyssal
    case 12: //Infernal
    case 13: // Drow
    case 14: // Reptilian
    case 15: // Sylvan
    case 16: // Auran
    case 17: // Ignan
    case 18: // Aquan
    case 19: // Terran
*/
//:://////////////////////////////////////////////
//:: Created By: Mermut
//:: Created On: August 3, 2007
//:://////////////////////////////////////////////
#include "nw_i0_tool"

const int LORE_PER_LANGUAGE = 10;

const string DMFI_LANG = "hlslang_";

// return the number of bonus languages the PC currently knows
// Also sets known languages on PC as variables for use
// later in the conversation
int GetNumLanguagesKnown(object oPC);

// return the maximum bonus languages the PC can know
int GetMaxLanguages(object oPC);


int GetMaxLanguages(object oPC)
{
    int iInt = GetAbilityScore(oPC, ABILITY_INTELLIGENCE, TRUE);
    // get the intelligence ability modifier = # bonus languages from int
    int iIntMod = (iInt - 10)/2;
    int iLore = GetSkillRank(SKILL_LORE, oPC, TRUE) + iIntMod;
    // 1 bonus language for every 10 pts of lore
    int iLoreMod = iLore/10 + GetLevelByClass(CLASS_TYPE_BARD, oPC) +
                              GetLevelByClass(CLASS_TYPE_HARPER, oPC);

    return (iIntMod + iLoreMod);
}

int GetNumLanguagesKnown(object oPC)
{
    int iKnown = 0;
    string sLanguageToken;
    int i;

    for (i = 1; i <= 19; i++)
    {
        sLanguageToken = DMFI_LANG + IntToString(i);
        if (HasItem(oPC, sLanguageToken))
        {
            SetLocalInt(oPC, sLanguageToken, TRUE);
            iKnown++;

            // Special check for racial, subracial and class languages
            // the do not count as 'bonus' languages, subtract them from count
            int iRace = GetRacialType(oPC);
            string sSubrace = GetStringLowerCase(GetSubRace(oPC));
            switch (i)
            {
                case 1: //Elven
                    // if elf or half-elf and not drow
                    if ((iRace == RACIAL_TYPE_ELF || RACIAL_TYPE_HALFELF) &&
                        FindSubString(sSubrace, "drow") < 0)
                            iKnown--;
                break;
                case 2: //Gnome
                    if (iRace == RACIAL_TYPE_GNOME)
                        iKnown--;
                break;
                case 3: //Halfling
                    if (iRace == RACIAL_TYPE_HALFLING)
                        iKnown--;
                break;
                case 4: //Dwarf
                    if (iRace == RACIAL_TYPE_DWARF)
                        iKnown--;
                break;
                case 5: //Orc
                    if (iRace == RACIAL_TYPE_HALFORC)
                        iKnown--;
                break;
                case 6: //Goblin
                break;
                case 7: //Draconic
                    if (GetLevelByClass(CLASS_TYPE_DRAGONDISCIPLE, oPC) > 0 ||
                        GetLevelByClass(CLASS_TYPE_DRAGON_DISCIPLE, oPC) > 0)
                            iKnown--;
                    else if (iRace == RACIAL_TYPE_HUMAN &&
                        FindSubString(sSubrace, "draco") >= 0 ||
                        FindSubString(sSubrace, "dragon") >= 0)
                            iKnown--;
                break;
                case 8: //Animal
                    if (GetLevelByClass(CLASS_TYPE_DRUID, oPC) > 0 ||
                        GetLevelByClass(CLASS_TYPE_RANGER, oPC) > 5)
                            iKnown--;
                    else if (iRace == RACIAL_TYPE_HUMAN &&
                        FindSubString(sSubrace, "hengeyokai") >= 0)
                            iKnown--;
                break;
                case 9: //Thieves Cant
                    if (GetLevelByClass(CLASS_TYPE_ROGUE, oPC) > 0)
                        iKnown--;
                break;
                case 10: //Celestial
                    if (iRace == RACIAL_TYPE_HUMAN &&
                        FindSubString(sSubrace, "aasimar") >= 0)
                            iKnown--;
                break;
                case 11: //Abyssal
                    if (iRace == RACIAL_TYPE_HUMAN &&
                        FindSubString(sSubrace, "tiefling") >= 0)
                            iKnown--;
                    // make sure fey ri and not elder fey ri
                    else if ((iRace == RACIAL_TYPE_ELF || RACIAL_TYPE_HALFELF) &&
                        (FindSubString(sSubrace, "fey ri") >= 0 &&
                         FindSubString(sSubrace, "elder fey ri") < 0))
                            iKnown--;
                break;
                case 12: //Infernal
                    if ((iRace == RACIAL_TYPE_ELF || RACIAL_TYPE_HALFELF) &&
                        (FindSubString(sSubrace, "elder fey ri") >= 0))
                            iKnown--;
                break;
                case 13: // Drow
                    // if elf or half-elf and drow
                    if ((iRace == RACIAL_TYPE_ELF || RACIAL_TYPE_HALFELF) &&
                        FindSubString(sSubrace, "drow") >= 0)
                            iKnown--;
                break;
                case 14: // Reptilian
                break;
                case 15: // Sylvan
                break;
                case 16: // Auran
                break;
                case 17: // Ignan
                break;
                case 18: // Aquan
                break;
                case 19: // Terran
                break;
            }
        }
    }

    return iKnown;
}
As you can see that the include really has the meat of the script to it. It calculates how many languages a PC can learn It also sets languages for subraces and custom races with special concerns for say Elf vs Drow which use different languages, And Fey'ri vs Elder Fey'ri. One has a linage from the Abyss the other has a linage from Hell. The script also shows you how to add custom races such as Hengeyokai (These creatures are shapechanging animals that can transform into human form So they get the animal language for free)

Using the bread and butter of this script you can add custom languages for any custom race you want or customize the script to your specific persistent world. You can also change the conditions for learning a language customized for your specific world. We used lore and int modifier. Another pw owner may want to use some other way.

So Your pc can learn a language. How do they get it. That will be on the next post. [/color]
CTP team member
http://www.harvestmoonconsortium.com
Chief cook and bottle washer for Harvest Moon

User avatar
Winterhawk99
Posts: 1648
Joined: Thu Oct 08, 2009 12:00 am
ctp: Yes
nwnihof: Yes
Location: Pa.
Contact:

Re: Adding zest to your persistent world using DMFI language

Post by Winterhawk99 »

So, Your PC can learn a new language and they choose elven. I'm choosing elven here as an example. Each choice will have a text appears when and Actions taken script.

A Note here You can add custom languages. There are blank widgets on the Dmfi that you can rename to custom languages so Say you have a Dark Sun or Dragonlance server you can make a language widget in Kender, Minatour, Pterran, Mul, or Kolshet (Irda). If you run out of custom widgets however you will need to make a new alphabet in the dmfi language include.

Ok so when the PC picks a language say Elven on that choice you put a text appears when script like this:

Code: Select all

text appears:

//::///////////////////////////////////////////////
//:: Name lang_can_elven
//:://////////////////////////////////////////////
/*
    Returns FALSE if the PC has the language widget in
        inventory
    else return TRUE
*/
//:://////////////////////////////////////////////
//:: Created By: Mermut
//:: Created On: August 3, 2007
//:://////////////////////////////////////////////
int StartingConditional()
{
    object oPC = GetPCSpeaker();
    object oWidget = GetItemPossessedBy(oPC, "hlslang_1");

    if (GetIsObjectValid(oWidget))
        return FALSE;
    else
        return TRUE;
}


We put this in text appears so that if the PC already has that particular language there is no need to list it. So it will be thrown out of the conversation list.

Now that we know the PC does not speak elven (does not have the elven widget.) All we need to do is create the widget within the pcs inventory. By placing this next script onto Actions taken of the same convo choice we do just that.

Actions Taken:

Code: Select all

//::///////////////////////////////////////////////
//:: Name lang_lrn_elven
//:://////////////////////////////////////////////
/*
    Given PC the language token for elven
*/
//:://////////////////////////////////////////////
//:: Created By: Mermut
//:: Created On: August 3, 2007
//:://////////////////////////////////////////////
void main()
{
    object oPC = GetPCSpeaker();
    CreateItemOnObject("hlslang_1", oPC);
}

hlslang_1 is the tag of the widget for the standard elven Dmfi language. With that in your inventory you can speak and understand elven.

And that's it. Now you can add Dmfi languages or any other to your module. [/color]
CTP team member
http://www.harvestmoonconsortium.com
Chief cook and bottle washer for Harvest Moon

Post Reply