Jump to content

Automation Tools for TES5Edit - Suggestions Thread


matortheeternal

Recommended Posts

  • Replies 446
  • Created
  • Last Reply

Top Posters In This Topic

 

 

 

But Is there a way to properly sort Z>A, like a reverse sort?
I am asking because the default reverse sorting is actually not proper, and does not seem to sort well across section.

 

You could sort A-Z then load the values into a stringlist backwards. So with slTest not yet sorted you'd have:

slTest.Sort;
for i := slTest.Count - 1 downto 0 do
  slBackwards.Add(slTest[i]);

Alternatively you could use Zilav's reverse sort function, which would save you a variable.

--
Of course, because of this you could also just use a downto for loop to effectively use the A-Z stringlist as a Z-A stringlist.

 

Btw, are there any resources to read about this? About the functions, commands and whatnot?
The TES5Edit Pascal seems a bit different from the regular Pascal from what I can see on the net.

 

TES5Edit pascal is almost exactly like regular pascal asides from the custom functions in it.

TES5Edit functions

General Pascal Resource

Basic Pascal Lessons

Free Pascal Wiki

Unfortunately I'm unable to write script "Copy from all records". I totally forgot Pascal syntax I studied at school and there is very little documentation about Tes5edit scripts except this single page
http://www.creationkit.com/TES5Edit_Scripting_Functions
So... I give up. Perhaps someone here may do this for me because it doesn't look difficult for someone who has some experience. Here is the algorithm I wanted to implement.
1)Ask user about path of the element which must be changed for every record;
2)Ask user about name of the file from which they must be copied.
3)A string "Celement" gets value of the needed element we want to copy (from the record with same FormID/EditorID, but from the other file).
4)Set edit value of the element we have to the "Celement"
Something like that.

 

That page is more than I had. Regain general pascal knowledge from the links I provided above, use existing scripts to familiarize yourself with syntax and how to write code, then start small and work your way up.

From what you've been wanting it'd probably be better if you copied elements from overriding records. So like:

1. User selects records in a file, then applies the script.
2. User inputs the name of the file they want to copy overriding values from.
3. User inputs path/s they want to copy values from.
4. See code.
5. Done.

unit userscript;

var
  filename: string;

function Initialize: integer;
begin
  // initialize your stuff here
  // use InputBox to accept user input for filename, then use a loop to find that file and store it in a variable.  I do this in several of my scripts.
  // use a looping InputBox until the input is empty to add paths the user wants to copy things from to a stringlist: slPaths
end;

function Process(e: IInterface): integer; 
var
  i: integer;
begin
  for i := 0 to OverrideCount(e) - 1 do begin
    if GetFile(OverrideByIndex(e, i)) = filename then begin
      ovrec := OverrideByIndex(e, i);
      Break;
    end;
  end;

  for i := 0 to slPaths.Count - 1 do begin
    wbCopyElementToRecord(e, ElementByPath(ovrec, slPaths[i]), True, True);
  end;
end;

Something like that. That code should get you started. I've done most of the hard parts for you.

 

 

If you're wondering why I'm having you guys learn code, here's some food for thought:

"Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime." --Chinese Proverb

 

 

 

I worked with it a little.

unit userscript;

var
 s1, slPath: string;
 i: integer;
 f, copyfile, ovrec: IInterface;
function Initialize: integer;
begin
  // initialize your stuff here
  // use InputBox to accept user input for filename, then use a loop to find that file and store it in a variable.  I do this in several of my scripts.
  // use a looping InputBox until the input is empty to add paths the user wants to copy things from to a stringlist: slPaths
   s1 := InputBox('File','Enter the name of the file containing the record you want to copy an element from, including the file extension','Skyrim.esm');
      for i := 0 to FileCount - 1 do begin
      f:= FileByIndex(i);
      if SameText(s1, GetFileName(f)) then begin
        copyfile := f;
        Break;
      end;
end;
slPath := InputBox('Path', 'Enter path you want to copy', '');
//here i have not array of pathes but only one. That's what i need
end;
function Process(e: IInterface): integer; 
begin
  for i := 0 to OverrideCount(e) - 1 do begin
    if Name(GetFile(OverrideByIndex(e, i))) = Name(copyfile) then then begin
      ovrec := OverrideByIndex(e, i);
      Break;
    end;
  end;
    wbCopyElementToRecord(e, ElementByPath(ovrec, slPath), False, True);
	//changeg first boolean to False because it is referred as "aAsNew"... And what i need is to replace old record (weight or price), not to add something new.
	//doesn't work both with True of False anyway
  end;
end.

Doesn't change anything. I cannot find any mistakes.

Could you please fix it?

Edited by DanielUA
Link to comment
Share on other sites

Thanks! I'll change code above. But still doesn't work.

  • You have two thens at line "if Name(..."
  • I don't think it's a good idea to use Name for filenames. Use GetFileName()
  • You don't need to store the copyfile as an IInterface object, you only need the file name, which should be a global string variable.
  • Fix your indentation, please, it's difficult to read because it's all wrong.
  • Put an empty line between functions, this also helps with readability.
  • Use an if Assigned(ovrec) line to skip the copying if ovrec isn't found.
  • Learn to troubleshoot your own code. This is actually pretty simple, just use AddMessage() to add messages when an if statement returns true or false, and when a variable should be assigned/found. This will let you troubleshoot exactly where in your code things aren't working. E.g.
      for i := 0 to OverrideCount(e) - 1 do begin
        AddMessage('Comparing filenames: '+GetFileName(GetFile(OverrideByIndex(e, i)))+' vs. '+GetFileName(copyfile));
        if GetFileName(GetFile(OverrideByIndex(e, i))) = GetFileName(copyfile) then begin
          ovrec := OverrideByIndex(e, i);
          AddMessage('ovrec assigned: '+GetElementEditValues(ovrec, 'EDID'));
          Break;
        end;
      end;
Edited by matortheeternal
Link to comment
Share on other sites

Mator, would you be able to give me access to the quick-change script? Need to sort through a bunch of containers so as to reduce the amount of items in a couple of containers; there's around 150 values to be changed total, and it's an absolute pain to go through them in the CK.

Link to comment
Share on other sites

Mator, would you be able to give me access to the quick-change script? Need to sort through a bunch of containers so as to reduce the amount of items in a couple of containers; there's around 150 values to be changed total, and it's an absolute pain to go through them in the CK.

https://github.com/matortheeternal/AutomationTools

 

 

NPC Generator 1.1 was just uploaded. Works with all races and genders now. Let me know how the generated NPCs look to you.

Link to comment
Share on other sites

Is there anything that will automatically count all the items in any list so I don't have to?
Annoying sometimes to have count each item myself sometimes to ensure i enter the correct number of items in a list.

Edited by JobVanDam
Link to comment
Share on other sites

Is there anything that will automatically count all the items in any list so I don't have to?

Annoying sometimes to have count each item myself sometimes to ensure i enter the correct number of items in a list.

 

When you say "List" what do you mean?

  • StringLists in pascal code?
  • Arrays in pascal code?
  • Records in a group (with a signature) in TES5Edit?
  • Elements in a container in TES5Edit?
  • Records after filtering?

 

- M

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...