Jump to content
⚠ Known Issue: Media on User Profiles ×

boozehoundblue

Members
  • Posts

    9
  • Joined

  • Last visited

Everything posted by boozehoundblue

  1. Yes, I've compiled a modified xDump.exe. The advantage of an xEdit script in my case is the visual aspect and ability to arbitrarily select records. If nothing else, perhaps I can use an xEdit script to create an ini file the xDump can utilize. Thanks again for the pointers.
  2. Thanks for clearing that up! Got it working. According to the Wiki, Signature(e) is defined as returning a string. As far as the Case statement's purpose, I intend it as a means to operate on records individually. No, it doesn't serve a particular purpose in my posted script, but I plan to incorporate field exclusions from an ini to ultimately produce json (and other) files for different record types. The generic Write procedure(s) were mostly for me to have something to study. Since both 'Case int of' and 'if SigStr = 'ABCD' accomplish the same task, the choice comes down to which looks/performs better. Maybe the performance difference isn't worth the hassle or is negated by the cost of conversion. I see what you mean about being quite slow now, having run a working version over Fallout4.esm's Npcs. Yikes.
  3. True, I just thought an integer case would ultimately be more performant than comparing strings, as there's hundreds of unique signatures defined. (I also thought I'd have to nest those else ifs). Still, why can't I get a char from string? From my understanding of the Wiki and JvInterpreter, this functionality was made possible in 1.51.2(?)
  4. Thanks for the advice. I've spent the last month fumbling around in Python and the source code, then decided an xEdit Script would probably be most useful. However, I've hit a couple of errors that I can't figure my way around, trying to create a switch case from (integer representations of) record signatures. If you have a chance, could you have a look? https://forums.nexusmods.com/index.php?/topic/6611661-tes5edit-scripting-compiling-woes-enumeration-type-et-al/
  5. Removed TSig type entirely. Compiles, but execution in Editor now raises 'Array type required' when attempting to get a character from a string (i.e. ch := SigStr in SigtoInt function). Idk how to get a char otherwise. unit myEditScript; interface uses xEditAPI, Classes, SysUtils, StrUtils, Windows; // Global variables var List : TStringList; var aIndent : string; var Sig : integer; procedure WriteElement(e : IInterface; Sig : integer; aIndent: string = ''); procedure WriteContainer(e : IInterface; Sig : integer; aIndent: string = ''); function RemoveNumbering(str : string): string; function SigToInt(SigStr: string): integer; function SigSwitch(Sig: integer): integer; implementation function RemoveNumbering(str : string): string; var i : integer; begin Result := ''; i := Pos(' #', str); if (i = 0) then Result := str else Result := copy(str, 1, i-1); end; function SigToInt(SigStr: string): integer; var i, e, Sig : integer; c : string; ch : Char; begin e := 3; for i := 1 to 4 do ch := SigStr[i]; Case e of 0: Sig := Sig + ord(ch); 1: Sig := Sig + ord(ch)*100; 2: Sig := Sig + ord(ch)*10000; 3: Sig := Sig + ord(ch)*1000000; End; e := e - 1; Result := Sig; end; function SigSwitch(Sig: integer): integer; begin Result :=0; Case Sig of 78806795: begin Result := 1; List.Add('NPC_ found'); end; End; end; procedure WriteContainer(e : IInterface; Sig : integer; aIndent: string = ''); var i : Integer; begin for i := 0 to Pred(ElementCount(e)) do WriteElement(ElementByIndex(e, i), Sig, aIndent); end; procedure WriteElement(e : IInterface; Sig : integer; aIndent: string = ''); var Name : string; Value : string; Str : string; defTypeStr : string; eleTypeStr : string; SigStr : string; begin Name := ShortName(e); Value := GetEditValue(e); SigSwitch(Sig); if (Name <> 'Unused') then begin if (Name <> '')then Str := aIndent + RemoveNumbering(Name); if (Name <> '') or (Value <> '') then aIndent := aIndent + ' '; if (Value <> '') then begin Str := Str +': ' + Value; List.Add(Str) end else begin if (Name <> '') then List.Add(Str) end; end; WriteContainer(e, Sig, aIndent); end; // Called when the script starts function Initialize : integer; begin List := TStringList.Create; end; // Called for each selected record in the TES5Edit tree // If an entire plugin is selected then all records in the plugin will be processed function Process(e : IInterface) : integer; begin aIndent := ''; Sig := SigToInt(Signature(e)); WriteContainer(e, Sig, aIndent); end; // Called after the script has finished processing every record function Finalize : integer; var filename : string; begin filename := ProgramPath + 'Edit Scripts\Test.txt'; AddMessage('Saving to ' + filename); List.SaveToFile(filename); List.Free; end; end.
  6. I'm having a hard time getting a script together that will both compile in Delphi's Starter IDE and run in FO4Edit. It's typically one or the other, due to enums. For example, I can operate on DefType or ElementType returns, and have created a script that runs correctly, but it raises compile errors in IDE, which makes it difficult to check other syntax errors I may be making while trying to learn the language. That's a general problem I'm having. (But maybe I can add 'wbDefinitionsFO4' from source to uses to compile, then remove? Idk.) Now I have a script which doesn't (yet) utilize those type returns and which does compile correctly but raises "Class declaration expected but '(' found", due to my apparently otherwise seemingly correct implementation of my own enumeration type, based off Delphi's online and TES5Edit's source examples. The TES5 Scripting Functions Wiki notes that the 'type' keyword is unsupported but it can be used to "alias a class name" (whatever that means). I don't know how to define this enumeration otherwise, or if I'm even allowed to use it within the confines of the API. (It's all magic and a bunch of := and ; but not += to me. Yeesh.) Anyway, I'm trying to write a script that will write a collection of records to json(s). In order to do that, I first want to remove the numbering from things like 'Value #1' and otherwise put elements that are described as arrays (in 'wbDefinitionsFO4') into arrays (because ElementType doesn't tell the whole story in that regard). This entails pre-compiling lists (or delimited strings) of Names for each record type to search against as I cycle through the container(s) in order to format the json correctly. To do the search, I thought I'd grab the signature of the record and run it through a case statement, so I know which particular strings to search for. Can't do that for strings, and I don't want to write a bunch of if else statements if I can help it. So I figured I'd change to signature to its unique integer and run it through a case of similarly pre-determined signature enum integers and fork from there. Smart? Idk.(A timeit test in Python showed that, even with conversion cost, 'int in [ints]' was 2x+ faster than 'string in [strings]'. Python doesn't have cases, and from the Wiki, Edits scripts don't support 'in'. Yeesh.) I can't get my script to run in Editor, let alone set up some bench comparisons. (It did work before I added the enum/case stuff, and output in same format as an xDump, since my Write functions are adapted directly from it.) Rant over. Code with snipped enum below. Any insight/guidance would be appreciated. Thanks! unit myEditScript; interface uses xEditAPI, Classes, SysUtils, StrUtils, Windows, Math; type TSig = ( _AACT = 65656784, _NPC_ = 78806795 ); // Global variables var List : TStringList; var aIndent : string; procedure WriteElement(e : IInterface; aIndent: string = ''); procedure WriteContainer(e : IInterface; aIndent: string = ''); function RemoveNumbering(str : string): string; function SigToTSig(SigStr: string): TSig; function SigSwitch(Sig: TSig): integer; implementation function RemoveNumbering(str : string): string; var i : integer; begin Result := ''; i := Pos(' #', str); if (i = 0) then Result := str else Result := copy(str, 1, i-1); end; //idk if this works yet, different than my Python test function function SigToTSig(SigStr: string): TSig; var i, ch, e, Sig : integer; begin e := 3; for i := 1 to 4 do ch := ord(SigStr[i]); Sig := Sig + Round(ch*IntPower(100,e)); e := e - 1; Result := TSig(Sig); end; function SigSwitch(Sig: TSig): integer; begin Result :=0; Case Sig of _NPC_: Result:=1; End; end; procedure WriteContainer(e : IInterface; aIndent: string = ''); var i : Integer; begin for i := 0 to Pred(ElementCount(e)) do WriteElement(ElementByIndex(e, i), aIndent); end; procedure WriteElement(e : IInterface; aIndent: string = ''); var Name : string; Value : string; Str : string; defTypeStr : string; eleTypeStr : string; SigStr : string; begin Name := ShortName(e); Value := GetEditValue(e); SigStr := Signature(e); //first if just a test to see if it will catch if (SigSwitch(SigToTSig(SigStr)) = 1) then List.Add('Match'); if (Name <> 'Unused') then begin if (Name <> '')then Str := aIndent + RemoveNumbering(Name); if (Name <> '') or (Value <> '') then aIndent := aIndent + ' '; if (Value <> '') then begin Str := Str +': ' + Value; List.Add(Str) end else begin if (Name <> '') then List.Add(Str) end; end; WriteContainer(e, aIndent); end; // Called when the script starts function Initialize : integer; begin List := TStringList.Create; end; // Called for each selected record in the TES5Edit tree // If an entire plugin is selected then all records in the plugin will be processed function Process(e : IInterface) : integer; begin aIndent := ''; WriteContainer(e, aIndent); end; // Called after the script has finished processing every record function Finalize : integer; var filename : string; begin filename := ProgramPath + 'Edit Scripts\Test.txt'; AddMessage('Saving to ' + filename); List.SaveToFile(filename); List.Free; end; end.
  7. Thanks for the replies. I was leery about raising an issue on github if I was indeed making a simple mistake/misunderstanding. zilav asserts I am. Thanks for clearing that up. I guess -xcg:list doesn't serve a purpose if I'm interested in dumping specific groups, as each record has the same signature. I can just use -dg:list and -xr:TES4 (to at least remove the main file header, minus 2 lines of artifact). I was also wondering about the export option mentioned in the help screen (below). Couldn't figure out the proper syntax in my above command to export to Wiki Table format:Syntax: FO4Dump [options] inputfile or FO4Export [options] format Ultimately, I'm trying to cull and restructure the output to template a spreadsheet (for Articy:Draft) or xmls, json, whatever. Where might I look around in the source code to begin to understand how the esp/esm is read and how the dump structure is written? Is there any technical documentation about the file structure? For example, Bioware had a pretty comprehensive set of pdfs for NWN that I could follow to program reading/writing dialogues to json.
  8. FO4Dump I've been trying to dump an NPC_ group while excluding things like DNAM,OBND,DATA,Head Parts, etc; but I can't seem to get the child record exclusion list (-xcg:list) to work. For example: fo4dump.exe -dg:NPC_ -xcg:DNAM,OBND,DATA fallout4.esm >mydump.txt I can correctly dump the one group but all that data is still there. Am I making a trivial mistake or misunderstanding record child groups? Or do the options not work in this conjunction?
  9. Curious about the availability of using existing furniture models (such as the misc. bar, i think) or something like a floor mat as a store/emporium. I'd like to use different surfaces in actual custom built shops (interior/exterior) in addition to the vanilla models. I know the traders lean/clean the shop counter surface, so maybe furniture of that height, or disable those animations? Ideally just stand behind whatever 'counter' I place (i.e. a designated floor mat). Not finding anything like it. Any interest?
×
×
  • Create New...