Jump to content

[WIPz] TES5Edit


zilav

Recommended Posts

1 hour ago, RavenMind said:

Strange, I've not had this problem - at all. Tried on Oblivion, SSE, & FO4. Checkboxes all appeared fine for me under Win10 Home, Anniversary Update & current Fall Creators Update 1709-16299.64. Glad they got it working for you Supierce! Sorry, Beermotor, to hear you had to go to those lengths only to have it fixed. :(

It only appeared after the Fall Creators Update, in the Windows Insider Preview builds. Consider yourself lucky!  :)

Link to comment
Share on other sites

8 hours ago, Supierce said:

This missing checkbox issue is fixed in the today's Windows Insider build. Microsoft didn't say much, only "We fixed an issue resulting in checkboxes being missing from certain win32 apps."  :)

Good to hear, thanks. Insider builds are nice for such cases, imagine that bug going into a live update and stay there for several months.

Link to comment
Share on other sites

Ah, for some reason I was thinking the same bug would appear in the public builds. Not sure what I was thinking there. Glad they got it fixed though! :)

I'm usually up for trying the latest/greatest, at least insofar as I know the programmers are top notch. Which is why I grab every latest build of xEdit & Wrye Bash. I have absolutely no faith in MS or their staff so I'm not about to be their guinea pig. Especially after they've become so invasive with their data harvesting. Hey Zilav, xEdit's not tracking me right? Right? :P

Link to comment
Share on other sites

1 hour ago, RavenMind said:

I'm usually up for trying the latest/greatest, at least insofar as I know the programmers are top notch. Which is why I grab every latest build of xEdit & Wrye Bash. I have absolutely no faith in MS or their staff so I'm not about to be their guinea pig. Especially after they've become so invasive with their data harvesting. Hey Zilav, xEdit's not tracking me right? Right? :P

Track what? Records you prefer to change, menu options you like to use or plugins you have installed? Can be done, but I just don't see how that information can be used for... anything :)

Link to comment
Share on other sites

@zilav I'm currently using this silly piece of code to get the display string value of the CTDA Type field.

function GetConditionType(const val: String): String;
var
	a, b, c, d, e: Boolean;
begin
	if Copy(val, 1, 1) = '1' then a := True; // equal to
	if Copy(val, 2, 1) = '1' then b := True; // greater than
	if Copy(val, 3, 1) = '1' then c := True; // less than
	if Copy(val, 4, 1) = '1' then d := True; // or
	if val = '00000000' then
		e := True;
	if e then
		Result := 'Not equal to';
	if a and not b and not c and not d then
		Result := 'Equal to';
	if b and not a and not c and not d then
		Result := 'Greater than';
	if c and not a and not b and not d then
		Result := 'Less than';
	if a and b and not c and not d then
		Result := 'Greater than or equal to';
	if a and c and not b and not d then
		Result := 'Less than or equal to';
	if a and d and not b and not c then
		Result := 'Equal to / Or';
	if b and d and not a and not c then
		Result := 'Greater than / Or';
	if c and d and not a and not b then
		Result := 'Less than / Or';
	if a and b and d and not c then
		Result := 'Greater than or equal to / Or';
	if a and c and d and not b then
		Result := 'Less than or equal to / Or';
end;

Is there a more straightforward way to get this value as the string that's displayed?

Link to comment
Share on other sites

41 minutes ago, fireundubh said:

Is there a more straightforward way to get this value as the string that's displayed?

xEdit does kind of the same, though it directly checks masked bit values of the CTDA's type field and uses case statement. So implement something similar I guess

unit test;

function CondType(aInt: Integer): string;
begin
  case aInt and $E0 of
    $00 : Result := 'Equal to';
    $20 : Result := 'Not equal to';
    $40 : Result := 'Greater than';
    $60 : Result := 'Greater than or equal to';
    $80 : Result := 'Less than';
    $A0 : Result := 'Less than or equal to';
  else
    Result := '<Unknown Compare operator>'
  end;

  if aInt and 1 = 1 then
    Result := Result + ' / Or';
end;

function Initialize: Integer;
begin
  AddMessage(CondType($60 + $1));
end;

end.

 

Link to comment
Share on other sites

Is it possible to add a feature to scale the whole program window? I'm running on 3860 x 1600 resolution with 125% scale on Windows 10 and XEdit is really tiny:

comparison.png

Just a comparison

Link to comment
Share on other sites

I'm curious, what's the process for decoding what the fields for records in FO4 mean? I found a wiki that describes ES5 records/fields, but it doesn't have things that are new in FO4. Just for example, TNAM in the TES4 record.

Is this something you guys do yourself? Is there some webpage I can't find?  Or do you have an inside source of Bethesda?

Link to comment
Share on other sites

58 minutes ago, StochasticTinker said:

I'm curious, what's the process for decoding what the fields for records in FO4 mean? Is this something you guys do yourself?

I "decoded" a lot of the fields for FO4. My process just involved past experience, data structure knowledge, and data transformations.

You can see at least the results of that process here.

Link to comment
Share on other sites

@zilav When I add a script fragment, I get an access violation error, although the fragment is still added.

I traced the error to here:

procedure TwbArrayDef.SetPrefixCount(aBasePtr: Pointer; aValue: Cardinal);
begin
  if arCount = -255 then
  else if arCount = -254 then
    WriteIntegerCounter(aBasePtr, aValue)
  else if Assigned(aBasePtr) then
    case GetPrefixlength(aBasePtr) of
      1: PByte(aBasePtr)^ := aValue;
      2: PWord(aBasePtr)^ := aValue; // this is where the error occurs
      4: PCardinal(aBasePtr)^ := aValue;
    end;
end;

This procedure is called from TwbArray.CheckCount which is called at the end of TwbArray.AssignInternal.

When I add another script fragment to the same array, I don't get an access violation error. Adding the second script fragment doesn't call AssignInternal, but I don't know why.

Link to comment
Share on other sites

6 hours ago, fireundubh said:

@zilav When I add a script fragment, I get an access violation error, although the fragment is still added.

In GUI? In xEdit's script? Need more details.

  • Like 1
Link to comment
Share on other sites

59 minutes ago, zilav said:

In GUI? In xEdit's script? Need more details.

In GUI.

...LOL. Does that reply count as more details? :teehee:

edit: Also in script.

Link to comment
Share on other sites

1 hour ago, fireundubh said:

In GUI.

...LOL. Does that reply count as more details? :teehee:

edit: Also in script.

I asked for details because I copied QUST and PERK records in FO4Edit without VMAD, added VMAD, added new fragment, no issues at all. That's why I need the exact record to reproduce the issue or xEdit script.

  • Like 1
Link to comment
Share on other sites

11 minutes ago, zilav said:

I asked for details because I copied QUST and PERK records in FO4Edit without VMAD, added VMAD, added new fragment, no issues at all. That's why I need the exact record to reproduce the issue or xEdit script.

You copied the record and then edited the fragments. Copying the record set whatever needed to be set for adding fragments to work without error.

Try:

  1. [FO4] Copy a TERM record with fragments.
  2. Save and exit.
  3. Load that plugin again.
  4. Try to add a fragment to that record.

Interestingly, I just tried those same steps with a QUST record and that did not yield an error.

Same steps with PERK, but that did yield an error.

Mark Modified seems to do something that prevents the error.

Link to comment
Share on other sites

@zilav It seems the solution is to add the "inherited" keyword before CheckCount in TwbArray.AssignInternal (line 14134 in wbImplementation.pas):

  inherited;

  CheckCount;
  CheckTerminator;
end;

However, I'm not really familiar with the "inherited" keyword, so while I know that CheckCount and CheckTerminator run, I don't know if those procedures are negatively impacted in any way.

If that's the real solution though, you can make the commit, or I can throw up a pull request - and then I can look at making it possible to add properties (zEdit can do this!)

Link to comment
Share on other sites

2 hours ago, fireundubh said:

Try:

  1. [FO4] Copy a TERM record with fragments.
  2. Save and exit.
  3. Load that plugin again.
  4. Try to add a fragment to that record.

I copied DN165_InfoDeskTerminalShopping "Information Desk Terminal" [TERM:00019C77], saved plugin, reloaded, added a new fragment - still no issues.

 

55 minutes ago, fireundubh said:

However, I'm not really familiar with the "inherited" keyword, so while I know that CheckCount and CheckTerminator run, I don't know if those procedures are negatively impacted in any way.

Inherited is used to access methods of the parent class. When name and arguments are omitted, it calls the same named method (AssignInternal in this case) using the same param values as provided to the calling function.

  • Like 1
Link to comment
Share on other sites

15 minutes ago, zilav said:

I copied DN165_InfoDeskTerminalShopping "Information Desk Terminal" [TERM:00019C77], saved plugin, reloaded, added a new fragment - still no issues.

Tested again with same record - as new and override.

  • If you hold Shift while loading the plugin to skip building references and then try to add a fragment, you'll get the error.
  • If you let xEdit build references, that process does something that prevents the error from occurring.

With the "inherited" keyword, the error won't occur regardless of whether you skipped building references and only one fragment will be added regardless of that second method call.

I hope we're narrowing the issue down!

Link to comment
Share on other sites

6 hours ago, fireundubh said:

Tested again with same record - as new and override.

  • If you hold Shift while loading the plugin to skip building references and then try to add a fragment, you'll get the error.
  • If you let xEdit build references, that process does something that prevents the error from occurring.

Alright I can reproduce this.

  • Like 1
Link to comment
Share on other sites

@zilav @hlp

Is there a better way to handle 00000014 than adding the Player as a string in wbInterface?

The current approach means that all IInterface functions do not work on the Player address; they also don't throw exceptions.

For example:

  • Signature returns an empty string
  • EditorID returns an empty string
  • LinksTo returns nothing
  • None of the ReferencedBy functions can return any results because the address is a string

Would it be possible to create a PLYR group and record type for use in the .dat files, and use that PLYR record?

edit: Looks like that's definitely possible.

  1. Created a wbRecord definition for PLYR with a wbEDID component.
  2. Modified a .dat file, added the PLYR group, and added a PLYR record with a Form ID of 00000014. (Used a script to change the Form ID.)
  3. Commented out almost all code where $14 was handled differently than other records. (Didn't touch the save editor. Left NewFormID handling alone.)

And it works.

AdGJAO7.jpg

I didn't comment out this because I'm not sure about the purpose:

              if wbUDRSetXESP and Supports(Add('XESP', True), IwbContainerElementRef, Cntr) then begin
                Cntr.ElementNativeValues['Reference'] := $14;
                Cntr.ElementNativeValues['Flags'] := 1;
              end;

Any reason why xEdit should not handle the Player as a record this way?

I uploaded a branch to GitHub with the above changes if you want to take a look. (Includes updated DAT files for all games.)

Link to comment
Share on other sites

3 hours ago, fireundubh said:

Any reason why xEdit should not handle the Player as a record this way?

Because it is not a record in real sense, and xEdit uses non-existing PLYR signature just to have a way of adding it in definitions where allowed. Theoretically it should be ACHR record with Player [NPC_:00000007] used as the base object. However there is no way of having a reference without CELL, so this will require to hardcode a cell record which can lead to conflicts in case of new game patches or mods using injection because such cell doesn't exist in the game engine.

Creating a fake record type is not the way I want it to see either personally.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...