munchbacca Posted July 24, 2007 Share Posted July 24, 2007 hello. i'm playing KOTOR on my mac and i want to install a mod (super skip taris) to use with the game. the only problem is that it uses a tsl patcher to install it. i tried just dumping all the files into the override folder and that doesn't work, how do i manually install a mod that uses tsl patcher? Link to comment Share on other sites More sharing options...
RedHawke Posted July 24, 2007 Share Posted July 24, 2007 Moving to the T3-M4 A.D.C. Tools forum... Edit: And I do have a likely silly question, but why don't you just run the installer? Link to comment Share on other sites More sharing options...
munchbacca Posted July 24, 2007 Author Share Posted July 24, 2007 i would but it is a .exe... which means it no likey my mac. edit: oh yeah and thanks for moving this for me... i'm obviously new to the boards and don't know where everything goes. Link to comment Share on other sites More sharing options...
stoffe Posted July 24, 2007 Share Posted July 24, 2007 hello. i'm playing KOTOR on my mac and i want to install a mod (super skip taris) to use with the game. the only problem is that it uses a tsl patcher to install it. i tried just dumping all the files into the override folder and that doesn't work, how do i manually install a mod that uses tsl patcher? If you don't have the ability to run Win32 executables you'll need to duplicate the work that the patcher does by hand instead. That would require that there are some modding tools available that can be run on a mac (2DA editor, TLK editor, GFF editor and script compiler in particular, depending on what mods you try to install). I don't know if there are any since I haven't owned a mac in 8 years. The actual work you need to do depends on what mod it is and how complex the installer instructions for it are. If you have the necessary tools look inside the tslpatchdata folder for a file named changes.ini. This is a plain text file that contains work instructions for the TSLPatcher. There are usually five main sections in this file containing key/value pairs (and usually a fair number of sub-sections referenced by them): [TLKList], [2DAList], [GFFList], [installList], [CompileList]. Sometimes there is a [HACKList] section as well. The [TLKList] contains a list of tokens with their corresponding index value in the append.tlk file (that comes with the mod and should be in the tslpatchdata folder as well, if used). The patcher inserts these entries into the game's dialog.tlk file and then substitutes the StrRef# token with the dialog.tlk StrRef index the entry was inserted as, whenever the token is encountered in a 2DA, GFF or Script modifier below. The [2DAList] contains a list of table modifiers, specifying the name of 2DA file which needs to be changed by the mod. It looks for 2DA files in the override folder first, and if it already exists there it is modified. If it doesn't exist it's copied from the tslpatchdata folder to the override folder and then modified. Each value in the 2DAList (for example spells.2da) has a corresponding section (i.e. [spells.2da]) further down the changes.ini file. In this file-specific section is a list of modifier-types as key with a section name as value. There are three types of keys, AddRow#, ChangeRow# and CopyRow#, followed by a unique incrementing numerical index. They behave as could be expected, AddRow-modifiers add a new line at the end of the 2DA file, ChangeRow modifies a cell value of an existing line and CopyRow makes a copy of an existing row and adds it as a new line at the end of the file (usually modifying some of the cell values as well). The values of these keys is the name of another section further down the changes.ini file that describes what changes should be made. Most of the keys in these sections are just column heading labels in the 2DA file, with the value being what should be set in the cell for that column on the row being manipulated/added. There are a few exceptions though: For ChangeRow/CopyRow modifiers, the first line contains either a RowIndex, RowLabel or LabelIndex key to inform the patcher of which line to modify (or to make a copy of, in the latter case). RowIndex specifies the line number in the file, starting at 0 at the top and counting down. RowLabel specifies the Row Label value of the line, which is a separate column in the 2DA file LabelIndex looks for a label column and looks for a row with a value matching what's set in that column For AddRow/CopyRow modifiers the first row may optionally have an ExclusiveColumn key, which is set to the label of a column in which the value assigned to that column below in the section must not already exist for a line in the 2DA file. If it does the existing line will be modified rather than a new being inserted. In either of these cases the keys can also be one of the 2DAMEMORY# tokens, which are essentially memory slots where the patcher temporarily holds a value that might be assigned somewhere else later on. Those are usually used to keep track of the line number of a new row that has been created, so that it might be inserted into another 2DA, a GFF file or a script later on. There is also a special high() value that might be assigned, which will set the value in that column to the highest existing numerical value of all rows + 1. The [2DAList] contains a name of GFF files that should be modified, and each filename value here has a corresponding section below in the changes.ini file as well. This file-specific section they has a key that specifies a path/name of a field to set the value of, and the value to set to that key. For example, a key like PropertiesList\0\Subtype would modify the Subtype field inside the first struct inside the PropertiesList list field in the file. The [CompileList] holds a list of NSS script source files that the patcher should compile. It may also contain an optional first key, !DefaultDestination, which changes where the compiled scripts are installed. If left out they will be put in the override folder. The NSS scripts usually contains either a StrRef# or a 2DAMEMORY# token, which the patcher would substitute with the corresponding value before compiling. Thus you will need to replace them manually in the NSS file with the proper value before you compile the scripts. The [installList] contains a list of folder path/names within the game folder where files will just be copied unmodified. Each key in this list has an identically named section in changes.ini, which lists the files that should be copied to that folder, and how it should behave if the file already exists at the destination (overwrite/skip). The [HACKList] section, if present, contains a list of NCS compiled script filenames, which a correspondingly named section below. The section contains a list of byte offsets in the file, and a value to write to that offset. Link to comment Share on other sites More sharing options...
munchbacca Posted July 24, 2007 Author Share Posted July 24, 2007 wow thanks for that super detailed response! i don't know but i might be too stupid to know what exactly to do with all that information you just gave me though... so this is the changes.ini file: [settings] FileExists=1 WindowCaption=Install super skip Taris & Endar Spire ConfirmMessage=N/A LogLevel=4 InstallerMode=1 BackupFiles=1 PlaintextLog=0 LookupGameFolder=1 LookupGameNumber=1 SaveProcessedScripts=0 [TLKList] [installList] install_folder0=Override [2DAList] [GFFList] File0=end_trask01.dlg [CompileList] [sSFList] ; =================================================================== [end_trask01.dlg] AddField0=gff_end_trask01_RepliesList_2_0 AddField1=gff_end_trask01_RepliesList_3_0 AddField2=gff_end_trask01_RepliesList_4_0 AddField3=gff_end_trask01_ReplyList_93_0 AddField4=gff_end_trask01_ReplyList_94_0 AddField5=gff_end_trask01_ReplyList_95_0 AddField6=gff_end_trask01_EditorInfo_0 [gff_end_trask01_RepliesList_2_0] FieldType=Struct Path=EntryList\55\RepliesList Label= TypeId=2 AddField0=gff_end_trask01_Index_0 AddField1=gff_end_trask01_Active_0 AddField2=gff_end_trask01_IsChild_0 [gff_end_trask01_Index_0] FieldType=DWORD Label=Index Value=93 [gff_end_trask01_Active_0] FieldType=ResRef Label=Active Value= [gff_end_trask01_IsChild_0] FieldType=Byte Label=IsChild Value=0 [gff_end_trask01_RepliesList_3_0] FieldType=Struct Path=EntryList\55\RepliesList Label= TypeId=3 AddField0=gff_end_trask01_Index_1 AddField1=gff_end_trask01_Active_1 AddField2=gff_end_trask01_IsChild_1 [gff_end_trask01_Index_1] FieldType=DWORD Label=Index Value=94 [gff_end_trask01_Active_1] FieldType=ResRef Label=Active Value= [gff_end_trask01_IsChild_1] FieldType=Byte Label=IsChild Value=0 [gff_end_trask01_RepliesList_4_0] FieldType=Struct Path=EntryList\55\RepliesList Label= TypeId=4 AddField0=gff_end_trask01_Index_2 AddField1=gff_end_trask01_Active_2 AddField2=gff_end_trask01_IsChild_2 [gff_end_trask01_Index_2] FieldType=DWORD Label=Index Value=95 [gff_end_trask01_Active_2] FieldType=ResRef Label=Active Value= [gff_end_trask01_IsChild_2] FieldType=Byte Label=IsChild Value=0 [gff_end_trask01_ReplyList_93_0] FieldType=Struct Path=ReplyList Label= TypeId=93 AddField0=gff_end_trask01_Listener_0 AddField1=gff_end_trask01_AnimList_0 AddField2=gff_end_trask01_Text_0 AddField3=gff_end_trask01_VO_ResRef_0 AddField4=gff_end_trask01_Script_0 AddField5=gff_end_trask01_Delay_0 AddField6=gff_end_trask01_Comment_0 AddField7=gff_end_trask01_Sound_0 AddField8=gff_end_trask01_Quest_0 AddField9=gff_end_trask01_PlotIndex_0 AddField10=gff_end_trask01_PlotXPPercentage_0 AddField11=gff_end_trask01_WaitFlags_0 AddField12=gff_end_trask01_CameraAngle_0 AddField13=gff_end_trask01_FadeType_0 AddField14=gff_end_trask01_EntriesList_0 AddField15=gff_end_trask01_SoundExists_0 AddField16=gff_end_trask01_CameraID_0 [gff_end_trask01_Listener_0] FieldType=ExoString Label=Listener Value= [gff_end_trask01_AnimList_0] FieldType=List Label=AnimList [gff_end_trask01_Text_0] FieldType=ExoLocString Label=Text StrRef=-1 lang0=[skip Endar Spire] [gff_end_trask01_VO_ResRef_0] FieldType=ResRef Label=VO_ResRef Value= [gff_end_trask01_Script_0] FieldType=ResRef Label=Script Value=skip_spire [gff_end_trask01_Delay_0] FieldType=DWORD Label=Delay Value=4294967295 [gff_end_trask01_Comment_0] FieldType=ExoString Label=Comment Value= [gff_end_trask01_Sound_0] FieldType=ResRef Label=Sound Value= [gff_end_trask01_Quest_0] FieldType=ExoString Label=Quest Value= [gff_end_trask01_PlotIndex_0] FieldType=Int Label=PlotIndex Value=-1 [gff_end_trask01_PlotXPPercentage_0] FieldType=Float Label=PlotXPPercentage Value=1 [gff_end_trask01_WaitFlags_0] FieldType=DWORD Label=WaitFlags Value=0 [gff_end_trask01_CameraAngle_0] FieldType=DWORD Label=CameraAngle Value=0 [gff_end_trask01_FadeType_0] FieldType=Byte Label=FadeType Value=0 [gff_end_trask01_EntriesList_0] FieldType=List Label=EntriesList [gff_end_trask01_SoundExists_0] FieldType=Byte Label=SoundExists Value=0 [gff_end_trask01_CameraID_0] FieldType=Int Label=CameraID Value=-1 [gff_end_trask01_ReplyList_94_0] FieldType=Struct Path=ReplyList Label= TypeId=94 AddField0=gff_end_trask01_Listener_1 AddField1=gff_end_trask01_AnimList_1 AddField2=gff_end_trask01_Text_1 AddField3=gff_end_trask01_VO_ResRef_1 AddField4=gff_end_trask01_Script_1 AddField5=gff_end_trask01_Delay_1 AddField6=gff_end_trask01_Comment_1 AddField7=gff_end_trask01_Sound_1 AddField8=gff_end_trask01_Quest_1 AddField9=gff_end_trask01_PlotIndex_1 AddField10=gff_end_trask01_PlotXPPercentage_1 AddField11=gff_end_trask01_WaitFlags_1 AddField12=gff_end_trask01_CameraAngle_1 AddField13=gff_end_trask01_FadeType_1 AddField14=gff_end_trask01_EntriesList_1 AddField15=gff_end_trask01_SoundExists_1 AddField16=gff_end_trask01_CameraID_1 [gff_end_trask01_Listener_1] FieldType=ExoString Label=Listener Value= [gff_end_trask01_AnimList_1] FieldType=List Label=AnimList [gff_end_trask01_Text_1] FieldType=ExoLocString Label=Text StrRef=-1 lang0=[Light Side skip Taris] [gff_end_trask01_VO_ResRef_1] FieldType=ResRef Label=VO_ResRef Value= [gff_end_trask01_Script_1] FieldType=ResRef Label=Script Value=ls_skip_taris [gff_end_trask01_Delay_1] FieldType=DWORD Label=Delay Value=4294967295 [gff_end_trask01_Comment_1] FieldType=ExoString Label=Comment Value= [gff_end_trask01_Sound_1] FieldType=ResRef Label=Sound Value= [gff_end_trask01_Quest_1] FieldType=ExoString Label=Quest Value= [gff_end_trask01_PlotIndex_1] FieldType=Int Label=PlotIndex Value=-1 [gff_end_trask01_PlotXPPercentage_1] FieldType=Float Label=PlotXPPercentage Value=1 [gff_end_trask01_WaitFlags_1] FieldType=DWORD Label=WaitFlags Value=0 [gff_end_trask01_CameraAngle_1] FieldType=DWORD Label=CameraAngle Value=0 [gff_end_trask01_FadeType_1] FieldType=Byte Label=FadeType Value=0 [gff_end_trask01_EntriesList_1] FieldType=List Label=EntriesList [gff_end_trask01_SoundExists_1] FieldType=Byte Label=SoundExists Value=0 [gff_end_trask01_CameraID_1] FieldType=Int Label=CameraID Value=-1 [gff_end_trask01_ReplyList_95_0] FieldType=Struct Path=ReplyList Label= TypeId=95 AddField0=gff_end_trask01_Listener_2 AddField1=gff_end_trask01_AnimList_2 AddField2=gff_end_trask01_Text_2 AddField3=gff_end_trask01_VO_ResRef_2 AddField4=gff_end_trask01_Script_2 AddField5=gff_end_trask01_Delay_2 AddField6=gff_end_trask01_Comment_2 AddField7=gff_end_trask01_Sound_2 AddField8=gff_end_trask01_Quest_2 AddField9=gff_end_trask01_PlotIndex_2 AddField10=gff_end_trask01_PlotXPPercentage_2 AddField11=gff_end_trask01_WaitFlags_2 AddField12=gff_end_trask01_CameraAngle_2 AddField13=gff_end_trask01_FadeType_2 AddField14=gff_end_trask01_EntriesList_2 AddField15=gff_end_trask01_SoundExists_2 AddField16=gff_end_trask01_CameraID_2 [gff_end_trask01_Listener_2] FieldType=ExoString Label=Listener Value= [gff_end_trask01_AnimList_2] FieldType=List Label=AnimList [gff_end_trask01_Text_2] FieldType=ExoLocString Label=Text StrRef=-1 lang0=[Dark Side skip Taris] [gff_end_trask01_VO_ResRef_2] FieldType=ResRef Label=VO_ResRef Value= [gff_end_trask01_Script_2] FieldType=ResRef Label=Script Value=ds_skip_taris [gff_end_trask01_Delay_2] FieldType=DWORD Label=Delay Value=4294967295 [gff_end_trask01_Comment_2] FieldType=ExoString Label=Comment Value= [gff_end_trask01_Sound_2] FieldType=ResRef Label=Sound Value= [gff_end_trask01_Quest_2] FieldType=ExoString Label=Quest Value= [gff_end_trask01_PlotIndex_2] FieldType=Int Label=PlotIndex Value=-1 [gff_end_trask01_PlotXPPercentage_2] FieldType=Float Label=PlotXPPercentage Value=1 [gff_end_trask01_WaitFlags_2] FieldType=DWORD Label=WaitFlags Value=0 [gff_end_trask01_CameraAngle_2] FieldType=DWORD Label=CameraAngle Value=0 [gff_end_trask01_FadeType_2] FieldType=Byte Label=FadeType Value=0 [gff_end_trask01_EntriesList_2] FieldType=List Label=EntriesList [gff_end_trask01_SoundExists_2] FieldType=Byte Label=SoundExists Value=0 [gff_end_trask01_CameraID_2] FieldType=Int Label=CameraID Value=-1 [gff_end_trask01_EditorInfo_0] FieldType=ExoString Path= Label=EditorInfo Value=v2.2.8 May 11, 2006 LastEdit: 04-Sep-06 17:42:47 [install_folder0] File0=ds_skip_taris.ncs File1=ls_skip_taris.ncs File2=skip_spire.ncs so what am is supposed to do with this information?! Link to comment Share on other sites More sharing options...
stoffe Posted August 5, 2007 Share Posted August 5, 2007 wow thanks for that super detailed response! i don't know but i might be too stupid to know what exactly to do with all that information you just gave me though... so this is the changes.ini file: so what am is supposed to do with this information?! Sorry I didn't reply earlier, I must have overlooked this post. Anyway: That configuration is set up to make the patcher modify the end_trask01.dlg dialog file. AddField# is a special key word that causes the patcher to add a new field to the file, and it is followed by a section identifier which holds the data of the new field to be added. Looking from the start, the [GFFList] section is a list of the names of all GFF files to modify, where the file name also corresponds to a section name with instructions on what to to with the file, in this case [end_trask01.dlg]. This section contains 7 AddField directives, the value of each key is the name of a section, as said above. So, for the first you have the [gff_end_trask01_RepliesList_2_0] section containing the specifics for that field. Looking at this section you have the following keys FieldType - a mandatory key whose value is set to the GFF data type this field should be of (as listed in GFF editor utilities) Path - an optional key which specifies where in the GFF file tree hierarchy the field should be added. If this key is left out the new field will be added below the field whose section contain the AddField key. Label - mandatory key holding the name label of the field to add in the GFF file. All fields have a label except Struct fields below a List field. Since this is the case here the value is blank. TypeId - an optional key that is used for Struct fields, which sets the type-id value of the struct field. Aside from those you have another set of AddField keys, which like before the value points to the name of a section containing the specifics of the field to add. If you look inside the first, [gff_end_trask01_Index_0], you'll see that it only contains three keys: FieldType - as mentioned before, this key must always be present, telling the data type of the field to add. In this case it's a numeric DWORD field. Label - as above, specifies the name label of the new field to add, "Index" in this case. It's a text string that can be no more than 16 characters in length. Value - most fields that are data carriers (strings, numbers etc) rather than containers (structs, lists) have a value key that sets the value this particular field should be set to in the GFF file. As seen the "Path" key is missing, meaning that this new field will be added to the struct field created in the previous section, i.e. EntryList\55\RepliesList\?\Index (the ? is the index number of the new struct added to the RepliesList list field, which is the next free number in sequence and thus dynamic). The other sections are used similarily, to add a branch to a tree structure within a DLG file. For this to make any sense you need some basic idea of how DLG files are structured. There should be documentation for this in the tutorial section in Holowan or on bioware's NWN site's developer section. The very short version is: Two main LIST fields are used, EntryList and ReplyList. Unsurprisingly the EntryList holds all the Entry nodes representing what NPCs say, and the ReplyList holds all the Reply nodes holding the player response choices. These two are then interlinked to form a tree structure. The EntryList contains a number of Entry structs, one for each Entry node in the dialog file. Among other fields, this struct has a RepliesList field, which contains one struct for every player reponse available after this NPC line. These structs hold an Index field that points to the TypeId of a struct in the ReplyList that holds the data for that particular reply node. The ReplyList, in turn, contains one Reply struct for each player response node in the dialog file. Among its other fields it has an EntriesList field, which contains one struct for every NPC line this response directly leads to (usually just one, but can be several if conditional scripts are used to trigger different NPC responses under different circumstances). These structs also contain an Index field, which contains the TypeId of a struct in the EntryList of the entries it leads to. So, with this in mind, the config instructions would insert new fields into the GFF file's tree structure like: Root/top node List: EntryListStruct: 55List: RepliesListStruct: ? (typeid=2)Dword: Index = 93 ResRef: Active = '' Byte: IsChild = 0 [*]Struct: ? (typeid=3) Dword: Index = 94 ResRef: Active = '' Byte: IsChild = 0 [*]Struct: ? (typeid=4) Dword: Index = 95 ResRef: Active = '' Byte: IsChild = 0 [*]List: ReplyList Struct: ? (typeid=93)ExoString: Listener = '' List: AnimList (empty) ExoLocString: Text (strref=-1)Text English/Male: '[skip Endar Spire]' [*]ResRef: VO_ResRef = '' [*]ResRef: Script = 'skip_spire' [*]Dword: Delay = 4294967295 (which is 0xFFFFFFFF in hex, meaning -1) [*]ExoString: Comment = '' [*]ResRef: Sound = '' [*]ExoString: Quest = '' [*]Int: PlotIndex = -1 [*]Float: PlotXPPercentage = 1.0 [*]Dword: WaitFlags = 0 [*]Dword: CameraAngle = 0 [*]Byte: FadeType = 0 [*]List: EntriesList (empty) [*]Byte: SoundExists = 0 [*]Int: CameraID = -1 [*]Struct: ? (typeid=94) ExoString: Listener = '' List: AnimList (empty) ExoLocString: Text (strref=-1)Text English/Male: '[Light Side skip Taris]' [*]ResRef: VO_ResRef = '' [*]ResRef: Script = 'ls_skip_taris' [*]Dword: Delay = 4294967295 (which is 0xFFFFFFFF in hex, meaning -1) [*]ExoString: Comment = '' [*]ResRef: Sound = '' [*]ExoString: Quest = '' [*]Int: PlotIndex = -1 [*]Float: PlotXPPercentage = 1.0 [*]Dword: WaitFlags = 0 [*]Dword: CameraAngle = 0 [*]Byte: FadeType = 0 [*]List: EntriesList (empty) [*]Byte: SoundExists = 0 [*]Int: CameraID = -1 [*]Struct: ? (typeid=95) ExoString: Listener = '' List: AnimList (empty) ExoLocString: Text (strref=-1)Text English/Male: '[Dark Side skip Taris]' [*]ResRef: VO_ResRef = '' [*]ResRef: Script = 'ds_skip_taris' [*]Dword: Delay = 4294967295 (which is 0xFFFFFFFF in hex, meaning -1) [*]ExoString: Comment = '' [*]ResRef: Sound = '' [*]ExoString: Quest = '' [*]Int: PlotIndex = -1 [*]Float: PlotXPPercentage = 1.0 [*]Dword: WaitFlags = 0 [*]Dword: CameraAngle = 0 [*]Byte: FadeType = 0 [*]List: EntriesList (empty) [*]Byte: SoundExists = 0 [*]Int: CameraID = -1 [*]ExoString: EditorInfo = 'v2.2.8 May 11, 2006 LastEdit: 04-Sep-06 17:42:47' (? is the list index of the new struct, i.e. the next number in sequence in the list.) As an aside I noticed that the config file contains a few potential errors which will cause problems if the dlg file in question does not look like the mod author expected. The TypeID values for the structs (and the Index fields that point to them) should not have their values set directly, like was done, but rather be set to the same value as the List index the struct is added as (i.e. it's position within the List field, starting at 0 and counting down). Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.