Jump to content

What do the elements of Chapterxxx.2da mean?


Recommended Posts

Posted

The following tests were performed on a self-created chapter sequence 2DA file. The SWITCH keyword was expected to define where which string appears. How this concrete works is not clear. For the purposes of testing it was assumed that if a particular race activated the sequence, e.g. Gnome, the text would change from DEFAULT to GNOME.

Test01

Spoiler
2DA V1.0
!_CHP0

            0           1           2
SWITCH      DEFAULT     DEFAULT     DEFAULT
DEFAULT     16202       18188       1099
GNOME       0           0           0

 

BG2:EE -> Works as expected. The last two strings with the strref 18188 and 1099 are printed in the chapter sequence screen.
SoD -> Works as expected. The last two strings with the strref 18188 and 1099 are printed in the chapter sequence screen.

Test02

Spoiler
2DA V1.0
!_CHP0
            0           1           2
SWITCH      DEFAULT     DEFAULT     GNOME
DEFAULT     16202       18188       1099
GNOME       0           0           1099

SoD -> Only string with strref 18188 shows up.

BG2:EE -> Only string with strref 18188 shows up.

You can find more tests here.

Questions:

  • How do race and class work here, what are they, what are they good for?
  • The CHPTXT0.2DA(SoD) hasthe row name "TICKS" rudimentary testing doesn't result in visible changes. What is it and how can it be used?

Example: 

Spoiler
2DA V1.0
NONE
                        0           1           2           3           4
SWITCH                  DEFAULT     DEFAULT     DEFAULT     DEFAULT     DEFAULT
TICKS                   100         0           0           0           0
DEFAULT                 16202       15879       15880       15896       15898

 

  • In the example above, there is the keyword “NONE” which actually serves as a reference for the MOS file.("First name (in our example ch05aund ) determines MOS reference for chapter screen." - iesdp), but why is there NONE here and in other Chapter 2da files?

Thank you for reading this comment. Any ideas for answer are welcome as I assume this is not common knowledge otherwise it would have already been included in iesdp.

Posted

NONE was just the chosen default value, every 2da has one.

I doubt race and class do anything, it's probably just a leftover.

Posted
Spoiler
CList<unsigned long>* CRuleTables::GetChapterText(CResRef* cResText, byte nRace, byte nClass, ushort nReputation, CResRef& cResPower)
{
    CList<unsigned long>* pList = new CList<unsigned long>{};

    C2DArray chptTxt2da{};
    chptTxt2da.Load(cResText);

    cResPower = "";

    if (chptTxt2da.pRes != nullptr)
    {
        cResPower = "NONE";

        int counter = 0;
        while (true)
        {
            CString sCounter{};
            CString::Format(&sCounter, "%d", counter++);

            CString sSwitchVal = chptTxt2da.GetAt(&sCounter, "SWITCH"); // column = <counter>, row = "SWITCH"

            if (sSwitchVal == "NONE")
            {
                break;
            }

            CString sKey{};

            if (sSwitchVal == "DEFAULT")
            {
                sKey = "DEFAULT";
            }
            else if (sSwitchVal == "RACE")
            {
                sKey = this->GetRaceString(nRace);
            }
            else if (sSwitchVal == "CLASS")
            {
                sKey = this->GetClassString(nClass, 0x4000);
            }
            else if (sSwitchVal == "REPUTATION")
            {
                sKey = nReputation < 10 ? "BAD_REPUTATION" : "GOOD_REPUTATION";
            }
            else
            {
                break;
            }

            int nStrref;
            CString temp = chptTxt2da.GetAt(&sCounter, &sKey); // column = <counter>, row = <sKey>
            sscanf(temp->m_pchData, "%d", &nStrref);

            pList->AddTail(nStrref);

            if (cResPower == "NONE")
            {
                CString sPower = nReputation < 10 ? "BAD_POWER" : "GOOD_POWER";
                cResPower = chptTxt2da.GetAt(&sCounter, &sPower); // column = <counter>, row = <sPower>
            }
        }

        if (cResPower == "NONE")
        {
            cResPower = "";
        }
    }

    return pList;
}

The SWITCH row determines which row label is used to pick each column's strref.

"DEFAULT" -> "DEFAULT" row label.

"RACE" -> Character's race string as row label.

"CLASS" -> Character's class string as row label (no kit).

"REPUTATION" -> Reputation < 10 then "BAD_REPUTATION", else "GOOD_REPUTATION".

Posted (edited)

First of all, thank you both for your contribution.

 

10 hours ago, Bubb said:
  Reveal hidden contents
CList<unsigned long>* CRuleTables::GetChapterText(CResRef* cResText, byte nRace, byte nClass, ushort nReputation, CResRef& cResPower)
{
    CList<unsigned long>* pList = new CList<unsigned long>{};

    C2DArray chptTxt2da{};
    chptTxt2da.Load(cResText);

    cResPower = "";

    if (chptTxt2da.pRes != nullptr)
    {
        cResPower = "NONE";

        int counter = 0;
        while (true)
        {
            CString sCounter{};
            CString::Format(&sCounter, "%d", counter++);

            CString sSwitchVal = chptTxt2da.GetAt(&sCounter, "SWITCH"); // column = <counter>, row = "SWITCH"

            if (sSwitchVal == "NONE")
            {
                break;
            }

            CString sKey{};

            if (sSwitchVal == "DEFAULT")
            {
                sKey = "DEFAULT";
            }
            else if (sSwitchVal == "RACE")
            {
                sKey = this->GetRaceString(nRace);
            }
            else if (sSwitchVal == "CLASS")
            {
                sKey = this->GetClassString(nClass, 0x4000);
            }
            else if (sSwitchVal == "REPUTATION")
            {
                sKey = nReputation < 10 ? "BAD_REPUTATION" : "GOOD_REPUTATION";
            }
            else
            {
                break;
            }

            int nStrref;
            CString temp = chptTxt2da.GetAt(&sCounter, &sKey); // column = <counter>, row = <sKey>
            sscanf(temp->m_pchData, "%d", &nStrref);

            pList->AddTail(nStrref);

            if (cResPower == "NONE")
            {
                CString sPower = nReputation < 10 ? "BAD_POWER" : "GOOD_POWER";
                cResPower = chptTxt2da.GetAt(&sCounter, &sPower); // column = <counter>, row = <sPower>
            }
        }

        if (cResPower == "NONE")
        {
            cResPower = "";
        }
    }

    return pList;
}

The SWITCH row determines which row label is used to pick each column's strref.

"DEFAULT" -> "DEFAULT" row label.

"RACE" -> Character's race string as row label.

"CLASS" -> Character's class string as row label (no kit).

"REPUTATION" -> Reputation < 10 then "BAD_REPUTATION", else "GOOD_REPUTATION".

This is very helpful and has resulted in further testing being successful (the only missing item is “TICKS”).

The following was tested wit Near Infinity and the game SoD:

  • CHPTXT1.2DA was manipulated as follows:
Spoiler
2DA V1.0
NONE
            0           1           2           3
SWITCH      DEFAULT     DEFAULT     DEFAULT     RACE
DEFAULT     16203       11898       16190       11899
GNOME       0           0           0           1099

 

  • A gnome main character was created and played to the point where CHPTXT1.2DA was needed (chapter sequence right after Gorion's death). The result was that the string for strref 1099 was printed correctly.
  • A script was used to activate CHPTXT1.2DA(source )
Spoiler
IF
	HotKey(D)
THEN
	RESPONSE #100
		ClearAllActions()		
		StartCutSceneMode()		
		CutSceneId(Player1)		
		FadeToColor([30.0],0)
		Wait(2)					
		MultiPlayerSync()		
		FadeFromColor([30.0],0)	
		TextScreen("CHPTXT1")		
		EndCutSceneMode()		
END

The following things should be taken into account when using the script:

  • The party AI must be activated, otherwise hotkey “D” will not trigger the script
  • Based on CutSceneId(Player1), the leader is checked for RACE. That is, if the leader is a human, DEFAULT strref from CHPTXT1.2DA is used, even if the script user (assigning AI script to a character) is a gnome.
  • The result was that the string for strref 1099 was printed correctly.

 

11 hours ago, lynx said:

NONE was just the chosen default value, every 2da has one.

So, based on testing, it seems that the system reads information from the CHPTXT1.2DA file when playing regularly and not using the custom script. Meaning a MOS background image is shown.

However, when activating CHPTXT1.2DA via script(TextScreen("CHPTXT1")) the background is black except for the scrolling text.

 

2 hours ago, lynx said:

Those are more useful (and used) in the dream screens.

Hmm, that's an argument on a creative level. Fortunately, the Chapter Sequence supports all of this, making it more powerful for the mod developer and allowing for more creativity.

 

Edited by Incrementis
fixing false smiley
Posted

I did some more simple tests on TICKS, which can be found here.

RESULT OVERALL:

The examination of TICKS is discontinued, because it raises too time-consuming questions such as:

  • Are the TICKS used in the game?
  • Can something else override the TICKS values?
  • Does TICKS directly affect visible behavior in the game?
  • What restrictions are there when using TICKS?

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...