Jump to content

Qwinn's WeiDU PS:T FixPack


Qwinn

Recommended Posts

Progress update, for those who are looking here for it:

 

Fixpack (including SKARDAVNELNATE's fixes) is 100% done with the initial coding (i.e. ready for testing). Dialogue file correction of typos and grammar mistakes is 100% done with systematic reviews, all that's left is to convert it to STRING_SETS now (which I'll do when I'm 100% done with everything). Restoration Pack is 75% done.

 

Unfinished Business is done with everything except possibly two things to be restored from the restoration pack (the Xixi quest, need to look at that to see if it's an actual quest, and getting the Githzerai respect variable working properly, basically you can become popular among the Githzerai and can have a tattoo from them become available if you treat them well).

 

What -is- 100% coded for Unfinished Business already is:

 

1. Restored Candlestick Quest by Platter

2. Restored Pendant of Yemeth Quest, by SKARDAVNELNATE

3. Restored Seven Curst Citizens, by SKARDAVNELNATE

4. Restored Elyce and Company Quest, by SKARDAVNELNATE

5. Restored Carl Parfidor, by SKARDAVNELNATE

6. Restored Deionnarra's Truth Conversations (note, this is SKARDAVNELNATE's version that only restores conversations that you could logically have at that point in the game, not the other version out there that lets you hear a conversation with Iannis you couldn't have because it contains details you don't know until you get to the Fortress).

 

I will also get my Restored Morte & Ingress's Teeth banter in before the first release.

 

I'll also have my own tweak pack, which will include my own versions of stacking and max hp, a tweak to make collecting the bounty on rat cranium tails less tedious by SKARDAVNELNATE and, if I can get that .bam for the scales in time, my Scale of Souls. Qwinn's Tweak Pack will likely expand greatly in future versions.

 

Already have forums set up over at Spellhold Studios for these mods, though they are private for the time being. Just thought that I'd let you guys know, since this is where I first announced the intent to work on this project, and where I've seen the most interest in it :crazyeyes:

 

Qwinn

Link to comment

Oh, I should add... there will also be a "Restored Items" component to Unfinished Business, mostly based on items restored by the Restoration Pack. Not -all- items restored in such a way in the Restoration Pack will be part of UB, some will be in the Fixpack because it appears they were meant to be included and a bug simply prevented it (for example, the Eye of Vecna appears to be one of those). Looking around for evidence of designer intent regarding these things is what's taking up the most time right now, actually.

 

Oh, and last but not least, I will in fact include Morte's Original Intro as an optional component in UB. I was looking at the wrong thing before, and mixed them up. Your initial conversation with Morte in the vanilla game is pretty much a railroad, only one option to each line by Morte. The "restored original intro" is much more like other conversations in the game, and I can see why people would like it much better. So, it'll be available.

 

Qwinn

Link to comment

Regarding your query about the impeded closed / open sections for doors (and keeping with the merry cross board cross contamination): they really aren't vertices (they're tilemap pointers) and they really are stored exactly as vertices are (as paired words in the vertices structure of an .are) - so neither the IESDP nor NI are wrong about that part.

Link to comment

Heh, okay.

 

NI is in general somewhat more trustworthy (since it's a file browser, typos are more catastrophic, and devSin's notably a perfectionist).

 

You can trim your macros a bit if you're interested in LOCAL_SET to prevent variable overlap. but if you're happy with how it runs, I'll stay out of your way :crazyeyes:

Link to comment
NI is in general somewhat more trustworthy (since it's a file browser, typos are more catastrophic, and devSin's notably a perfectionist).
Offsets and counts to separate structures like this are particularly touchy since NI uses the data to build its lists.

 

That said, I stay well away from walkmap/tilemap data ;-), so the labels could very well be reversed (the offset-count-count-offset is correct, but NI only uses it to build the correct list of tilemap indices of size count at location offset, so it's not like the open/close labels are guaranteed to be accurate).

Link to comment

Okay. I got a bear of a problem now, needing some help. Is there any way to do > or < string comparisons?

 

Here's the issue. PS:T has a variable file called VAR.VAR where all globals to be used in the game must be declared, and it's not just a straight text file. I know, I know, none of the other IE games need this, they just create variables on the fly. Anyways, I still have to deal with it. I would -like- to be able to add variables via WeiDU. And, I would -like- to insert my variables into the list alphabetically, which is how the file is organized (besides, appending them at the end of the file is problematic too, unless someone can tell me there's an APPEND_BYTES function out there, that would help too.. I would assume that INSERT_BYTES "SOURCE_SIZE" + 1 should and would return an out-of-range error).

 

Anyways. So what I really really really want to do is something like this, when I try to add a GLOBAL variable called Justifier to the file in it's proper alphabetical position. The alphabetical ordering is by type (such as "GLOBAL") and then by the variable name:

 

(Note - one full variable declaration is size 0x2c. The 8-byte ASCII type is at 0x0 within each declaration, and the 32-byte ASCII name is at 0x8. The value after that is -not- in ASCII form and that's why I can't edit this like a text file)

 

COPY_EXISTING ~VAR.VAR~ ~override~

SPRINT "NewType" "GLOBAL"

SPRINT "NewName" "Justifier"

READ_ASCII 0x0 "CurType" (8)

READ_ASCII 0x8 "CurName" (32)

WHILE "%CurType%" < "%NewType%" AND "%CurName%" < "%NewName%"

BEGIN

SET "Position" = "Position" + 0x2c

READ_ASCII "Position" + 0x0 "CurType" (8)

READ_ASCII "Position" + 0x8 "CurName" (32)

END

INSERT_BYTES "Position" 0x2c

WRITE_ASCII "Position" + 0x0 "GLOBAL" #8

WRITE_ASCII "Position" + 0x8 "Justifier" #32

WRITE_LONG "Position" + 0x28 0

END

 

The loop should end when it encounters it's first Type and Name that are alphabetically greater than my new variables, and I can get my proper insert-bytes position from that.

 

Or I -could-, if I could actually compare strings like I do in the WHILE condition. But I can't, and the only option for comparing strings out there that I can find seems to only return a TRUE if they're exactly equal and false otherwise. That doesn't help me here.

 

Any options, or am I out of luck? And if I am out of luck, any suggestions on how to handle this? I'll try sticking them at the end if I have to, although I have some reason to believe that wouldn't work, and if there's some non-torturous way of appending the bytes I need to the end. (Yes, I can think of torturous ways that involve temporarily butchering the last existing record in the file and then fixing it, and I'd really rather not do all that, I'd give up on WeiDUing it first).

 

Qwinn

Link to comment

Changed my mind on the Eye of Vecna, btw. Discovered enough problems with it that It's getting moved to UB Restored Items.

 

EDIT: NM about the price... turns out Resto Pack's documentation doesn't match what it actually did.

 

On the other hand, the Githzerai stuff, where the respect of githzerai is tracked and that can unlock the Tattoo of the Unbroken Circle, -was- definitely intended to be in game and just bugged, and it will be fixed in the fixpack.

 

Qwinn

Link to comment

INSERT_BYTES SOURCE_SIZE amount will write to the end of the file without trampling over the last value - though in this case you probably want

OUTER_PATCH ~this_is_not_a_variable~ BEGIN
 FOR (i = 0x0; i < 0x100; i += 0x1) BEGIN
WRITE_BYTE 0x0 i
READ_ASCII 0x0 c (0x1)
SPRINT $0t(~%i1%~) ~%c%~
 END
END

APPEND_OUTER var.var ~GLOBAL  Nameless_SelfInjuriousBehavior  %0t_1%%0t_0%%0t_0%%0t_0%~
UNLESS ~Nameless_SelfInjuriousBehavior~

 

There's no native STRING_FOLLOWS_ALPHABETICALLY predicate, though it's not too difficult to bodge a fake version together.

 

I don't think copying var.var into the override is what you want :crazyeyes:

 

/edit

 

This was vaguely amusing. I wonder if it works.

DEFINE_PATCH_MACRO alphabetize BEGIN
 LOCAL_SET loop_index = 0
 LOCAL_SET char	   = 0
 LOCAL_SET num_0	  = 0
 LOCAL_SPRINT which_follows no_value
 TO_UPPER input_string
 TO_UPPER match_string
 INNER_PATCH ~%input_string%~ BEGIN
FOR (loop_index = 0; loop_index < STRING_LENGTH EVALUATE_BUFFER ~%input_string%~; loop_index += 1) BEGIN
  READ_BYTE loop_index $EVALUATE_BUFFER ~input_%input_string%~(~%loop_index%~)
END
 END
 INNER_PATCH ~%match_string%~ BEGIN
FOR (loop_index = 0; loop_index < STRING_LENGTH EVALUATE_BUFFER ~%match_string%~; loop_index += 1) BEGIN
  READ_BYTE loop_index $EVALUATE_BUFFER ~match_%match_string%~(~%loop_index%~)
END
 END
 PHP_EACH ~input_%input_string%~ AS num => char BEGIN
PATCH_IF ~%which_follows%~ STRING_EQUAL no_value && IS_AN_INT char BEGIN
  PATCH_IF VARIABLE_IS_SET   $EVALUATE_BUFFER ~match_%match_string%~(~%num_0%~) &&
		   IS_AN_INT		 $EVALUATE_BUFFER ~match_%match_string%~(~%num_0%~) BEGIN
	PATCH_IF char		  > $EVALUATE_BUFFER ~match_%match_string%~(~%num_0%~) BEGIN
	  SPRINT which_follows input_string
	END ELSE PATCH_IF char < $EVALUATE_BUFFER ~match_%match_string%~(~%num_0%~) BEGIN
	  SPRINT which_follows match_string
	END
  END
END
 END
 PATCH_IF ~%which_follows%~ STRING_EQUAL no_value BEGIN
PHP_EACH ~match_%match_string%~ AS num => char BEGIN
  PATCH_IF ~%which_follows%~ STRING_EQUAL no_value && IS_AN_INT char BEGIN
	PATCH_IF VARIABLE_IS_SET   $EVALUATE_BUFFER ~input_%input_string%~(~%num_0%~) &&
			 IS_AN_INT		 $EVALUATE_BUFFER ~input_%input_string%~(~%num_0%~) BEGIN
	  PATCH_IF char		  > $EVALUATE_BUFFER ~input_%input_string%~(~%num_0%~) BEGIN
		SPRINT which_follows match_string
	  END ELSE PATCH_IF char < $EVALUATE_BUFFER ~input_%input_string%~(~%num_0%~) BEGIN
		SPRINT which_follows input_string
	  END
	END
  END
END
 END
 PATCH_IF ~%which_follows%~ STRING_EQUAL no_value BEGIN
PATCH_IF		  STRING_LENGTH EVALUATE_BUFFER ~%input_string%~ > 
				  STRING_LENGTH EVALUATE_BUFFER ~%match_string%~ BEGIN
  SPRINT which_follows input_string
END ELSE PATCH_IF STRING_LENGTH EVALUATE_BUFFER ~%input_string%~ < 
				  STRING_LENGTH EVALUATE_BUFFER ~%match_string%~ BEGIN
  SPRINT which_follows match_string
END ELSE BEGIN
  SPRINT which_follows either
END
 END
 SET match_string = (~%which_follows%~ STRING_EQUAL match_string) ? 0x01 : 0x00
 SET input_string = (~%which_follows%~ STRING_EQUAL input_string) ? 0x01 : 0x00
 CLEAR_ARRAY ~input_%input_string%~
 CLEAR_ARRAY ~match_%match_string%~
END
COPY_EXISTING var.var var.var
 DEFINE_ARRAY var_types_added BEGIN
AR0400 AR9999 GLOBAL
 END
 DEFINE_ASSOCIATIVE_ARRAY AR0400 BEGIN
~Grace_Fell_Comment			  ~ => 0
 END
 DEFINE_ASSOCIATIVE_ARRAY GLOBAL BEGIN
~2Devils						 ~ => 0
~Current_Lower_Planes			~ => 0
~Justifier					   ~ => 0
~Justifier_Lower_Planes		  ~ => 0
~Ratbone						 ~ => 0
~RB_Name						 ~ => 0
~RB_Quest						~ => 0
~RC_Expln						~ => 0
~RC_Pendant					  ~ => 0
~RChaser						 ~ => 0
~RChaser2						~ => 0
~TimeResearch_Incarnations	   ~ => 0
~TimeResearch_Language		   ~ => 0
~TimeResearch_Ravel			  ~ => 0
 END
 DEFINE_ASSOCIATIVE_ARRAY AR9999 BEGIN
~Chaotic_Toked_Up				~ => 0
~Evil_Kicked_Puppy			   ~ => 0
~Morte_You_Are_Dead_Please_STFU  ~ => 2147483647
 END
 FOR (i = 0x00; i < SOURCE_SIZE / 0x2c; i += 0x01) BEGIN
READ_ASCII i * 0x2c scope (0x06)
TO_UPPER scope
PATCH_IF NOT VARIABLE_IS_SET $scope(~%scope%~) BEGIN
  SET $scope(~%scope%~) = i
END
READ_ASCII i * 0x2c + 0x08 variable (0x20)
TO_UPPER variable
SET $EVALUATE_BUFFER ~variable_%scope%~(~%variable%~) = i
 END
 PHP_EACH var_types_added AS useless_int => var_type BEGIN
PHP_EACH ~%var_type%~ AS var => value BEGIN
  SPRINT   match ~%var_0%~
  TO_UPPER match
  PATCH_IF NOT VARIABLE_IS_SET $EVALUATE_BUFFER ~variable_%var_type%~(~%match%~) BEGIN
	PATCH_IF NOT VARIABLE_IS_SET $scope(~%var_type%~) BEGIN
	  PHP_EACH scope AS scope_type => scope_index BEGIN
		PATCH_IF NOT VARIABLE_IS_SET $scope(~%var_type%~) BEGIN
		  SPRINT input_string ~%var_type%~
		  SPRINT match_string ~%scope_type_0%~
		  INNER_PATCH_SAVE input_string ~%input_string%~ BEGIN
			REPLACE_TEXTUALLY ~_~ ~ ~
		  END
		  INNER_PATCH_SAVE match_string ~%match_string%~ BEGIN
			REPLACE_TEXTUALLY ~_~ ~ ~
		  END
		  LAUNCH_PATCH_MACRO alphabetize
		  PATCH_IF match_string = 0x01 BEGIN
			SET $EVALUATE_BUFFER ~variable_%var_type%~(~%match%~) = scope_index
			SET $scope(~%var_type%~) = scope_index
		  END
		END
	  END
	  PATCH_IF VARIABLE_IS_SET $scope(~%var_type%~) BEGIN
		PHP_EACH scope AS scope_type => scope_index BEGIN
		  PATCH_IF scope_index > $scope(~%var_type%~) ||
				   scope_index = $scope(~%var_type%~) && ~%var_type%~ STR_CMP ~%scope_type_0%~ BEGIN
			SET $scope(~%var_type%~) += 0x01
		  END
		END
	  END ELSE BEGIN
		SET $EVALUATE_BUFFER ~variable_%var_type%~(~%match%~) = SOURCE_SIZE / 0x2c
		SET $scope(~%var_type%~) = SOURCE_SIZE / 0x2c
	  END
	END ELSE BEGIN
	  PATCH_IF NOT VARIABLE_IS_SET $EVALUATE_BUFFER ~variable_%var_type%~(~%match%~) BEGIN
		SET insert = $scope(~%var_type%~)
		PHP_EACH ~variable_%var_type%~ AS existing_var => index BEGIN
		  PATCH_IF IS_AN_INT index BEGIN
			PATCH_IF NOT VARIABLE_IS_SET $EVALUATE_BUFFER ~variable_%var_type%~(~%match%~) BEGIN
			  SPRINT input_string ~%match%~
			  SPRINT match_string ~%existing_var_0%~
			  INNER_PATCH_SAVE input_string ~%input_string%~ BEGIN
				REPLACE_TEXTUALLY ~_~ ~ ~
			  END
			  INNER_PATCH_SAVE match_string ~%match_string%~ BEGIN
				REPLACE_TEXTUALLY ~_~ ~ ~
			  END
			  LAUNCH_PATCH_MACRO alphabetize
			  PATCH_IF match_string = 0x01 BEGIN
				SET $EVALUATE_BUFFER ~variable_%var_type%~(~%match%~) = $EVALUATE_BUFFER ~variable_%var_type%~(~%existing_var_0%~)
			  END
			END
			PATCH_IF IS_AN_INT index BEGIN
			  SET insert = index
			END
		  END
		END
		PATCH_IF NOT VARIABLE_IS_SET $EVALUATE_BUFFER ~variable_%var_type%~(~%match%~) BEGIN
		  SET $EVALUATE_BUFFER ~variable_%var_type%~(~%match%~) = insert + 0x01
		END
	  END
	END
	INSERT_BYTES $EVALUATE_BUFFER ~variable_%var_type%~(~%match%~) * 0x2c 0x2c
	SET SOURCE_SIZE += 0x2c
	PHP_EACH scope AS scope_type => whatever BEGIN
	  PHP_EACH ~variable_%scope_type_0%~ AS dont_care => here_either BEGIN
		PATCH_IF here_either > $EVALUATE_BUFFER ~variable_%var_type%~(~%match%~) ||
				 here_either = $EVALUATE_BUFFER ~variable_%var_type%~(~%match%~) &&
				 ~%match%~ STR_CMP ~%dont_care_0%~ BEGIN
		  SET $EVALUATE_BUFFER ~variable_%scope_type_0%~(~%dont_care_0%~) += 0x01
		END
	  END
	END
  END
  WRITE_ASCIIE $EVALUATE_BUFFER ~variable_%var_type%~(~%match%~) * 0x2c ~%var_type%  %var_0%~
  WRITE_LONG   $EVALUATE_BUFFER ~variable_%var_type%~(~%match%~) * 0x2c + 0x28 value
END
 END
BUT_ONLY

Link to comment

Hiya Nythrun,

 

Sorry for not responding earlier, I just saw this for the first time (didn't realize you'd edited that post).

 

Very interesting. I'm having a bit of difficulty reading it, as some of the commands you use a lot aren't very well documented, at least with the 206 documentation I've been using (like PHP_EACH, IS_AN_INT, WRITE_ASCIIE, etc.).

 

But I get the gist of what you're doing, I think - basically you're doing a read byte on each individual character of the string in question, and comparing them against one another that way. Makes sense, and should be workable. I'll try that concept with the WeiDU commands I grok. :crazyeyes: Thanks for the code! I'll post what I come up with, soon as I'm done with the huge dialog edit I'm working on.

 

And yeah, INNER_PATCH will be -very- handy for it, glad you did that, I wasn't aware of that one and it'll make this a whole lot easier.

 

Qwinn

Link to comment

Well, here's what I came up with. Did have to figure out what WRITE_ASCIIE was, heh, thankfully I never needed anything like EVALUATE_BUFFER on those Area Modding macros I wrote, having %strings% -not- resolve automatically was a new experience for me.

 

Anyways, so here's my version. Works perfectly (well, takes about 30 seconds to run, but considering it's adding 15 variables I figure that's not that bad). Thanks -tons- for your code, this would've taken me a whole hell of a lot longer without that to look at.

 

DEFINE_PATCH_MACRO Q_VarVar_MakeVarIntoByteArray
BEGIN
 DEFINE_ARRAY "Q_StringArray"
 BEGIN
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 END
 TO_UPPER "Q_VarType"
 TO_UPPER "Q_VarName"
 SET Q_Length = STRING_LENGTH EVALUATE_BUFFER ~%Q_VarType%~
 INNER_PATCH ~%Q_VarType%~
 BEGIN
FOR (i = 1; i <= 8; i += 1)
BEGIN
  PATCH_IF i <= Q_Length
	BEGIN READ_BYTE "i" - 1 "Q_Byte" END ELSE SET "Q_Byte" = 32
  PATCH_IF "Q_Byte" < 48 BEGIN SET "Q_Byte" = 32 END
  PATCH_IF "Q_Byte" > 90 BEGIN SET "Q_Byte" = 32 END
  SET $Q_StringArray("%i%") = "Q_Byte"
END
 END
 SET Q_Length = STRING_LENGTH EVALUATE_BUFFER ~%Q_VarName%~
 INNER_PATCH ~%Q_VarName%~
 BEGIN
FOR (i = 9; i <= 40; i += 1)
BEGIN
  PATCH_IF i - 8 <= Q_Length
	BEGIN READ_BYTE "i" - 9 "Q_Byte" END ELSE SET "Q_Byte" = 32
  PATCH_IF "Q_Byte" < 48 BEGIN SET "Q_Byte" = 32 END
  PATCH_IF "Q_Byte" > 90 BEGIN SET "Q_Byte" = 32 END
  SET $Q_StringArray("%i%") = "Q_Byte"
END
 END
END

DEFINE_PATCH_MACRO Q_VarVar_AddNewRecord
BEGIN
 SPRINT "Q_VarType" ~%Q_NewVarType%~
 SPRINT "Q_VarName" ~%Q_NewVarName%~
 LAUNCH_PATCH_MACRO Q_VarVar_MakeVarIntoByteArray
 DEFINE_ARRAY "Q_NewVarArray"
 BEGIN
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 END
 FOR (i = 1; i <= 40; i += 1) BEGIN SET $Q_NewVarArray("%i%") = $Q_StringArray("%i%") END
 SET FoundPos = 0
 SET CurPosition = 0x0
 WHILE CurPosition < %SOURCE_SIZE% AND FoundPos = 0
 BEGIN
 READ_ASCII "CurPosition"	   "Q_VarType" (8)
 READ_ASCII "CurPosition" + 0x8 "Q_VarName" (32)
 LAUNCH_PATCH_MACRO Q_VarVar_MakeVarIntoByteArray
 SET "StringPos" = 1
 SET "GotoNextRecord" = 0
 WHILE "StringPos" <= 40 AND "GotoNextRecord" = 0 AND "FoundPos" = 0
 BEGIN
	PATCH_IF $Q_StringArray("%StringPos%") = $Q_NewVarArray("%StringPos%")
	BEGIN SET "StringPos" = "StringPos" + 1 END
	ELSE
	BEGIN
	  PATCH_IF $Q_StringArray("%StringPos%") < $Q_NewVarArray("%StringPos%")
	  BEGIN
		SET "GotoNextRecord" = 1
		SET "CurPosition" = "CurPosition" + 0x2c
	  END
	  ELSE SET "FoundPos" = 1
	END
 END
 END
 PATCH_IF "FoundPos" = 1
 BEGIN
INSERT_BYTES "CurPosition" 0x2c
WRITE_ASCIIE "CurPosition" + 0x0 "%Q_NewVarType%" #8
WRITE_ASCIIE "CurPosition" + 0x8 "%Q_NewVarName%" #32
WRITE_LONG "CurPosition" + 0x28 "Q_NewVarValue"
 END
END

COPY_EXISTING ~VAR.VAR~ ~VAR.TMP~

 SPRINT "Q_NewVarType"  ~AR0400  ~
 SPRINT "Q_NewVarName"  ~Grace_Fell_Comment			  ~
 SET	"Q_NewVarValue" = 0
 LAUNCH_PATCH_MACRO Q_VarVar_AddNewRecord

 PATCH_FOR_EACH "S1" IN
~Grace_Fell_Comment			  ~
~2Devils						 ~
~Current_Lower_Planes			~
~Justifier					   ~
~Justifier_Lower_Planes		  ~
~Ratbone						 ~
~RB_Name						 ~
~RB_Quest						~
~RC_Expln						~
~RC_Pendant					  ~
~RChaser						 ~
~RChaser2						~
~TimeResearch_Incarnations	   ~
~TimeResearch_Language		   ~
~TimeResearch_Ravel			  ~
 BEGIN
SPRINT "Q_NewVarType"  ~GLOBAL  ~
SPRINT "Q_NewVarName"  ~%S1%~
SET	"Q_NewVarValue" = 0
LAUNCH_PATCH_MACRO Q_VarVar_AddNewRecord
 END
BUT_ONLY_IF_IT_CHANGES

COPY ~VAR.TMP~ ~VAR.VAR~

 

EDIT: Slight edit to the COPY statements to use an interim VAR.TMP file. Trying to

do it without that interim file, via COPY_EXISTING ~VAR.VAR~ ~~, resulted in "cannot access file" errors.

Link to comment

In the interests of speeding up the process, instead of looking through the entire VAR.VAR file one record at a time, this version of the Q_VarVar_AddRecord macro skips 50 records at a time looking for the first record that is alphabetically greater than the record to be added. Once it finds it (or it approaches the end of the file), it backs up 50 records and goes one by one from there. This dramatically speeds up the process, from over 30 seconds to about 2 seconds (for all 15 new variables).

 

EDIT: Streamlined some more. Also added Q_FileSize variable to keep track of dynamically changing size of the file (as SOURCE_SIZE doesn't update till the end) to deal with the case of adding new variables very close to the end of the file. Coder should set Q_FileSize = %SOURCE_SIZE% once after doing the COPY_EXISTING ~VAR.VAR~ ~VAR.TMP~ statement, otherwise everything outside of this macro stays the same.

 

// =========================== BEGIN Q_VarVar_AddNewRecord Definition ===========================

DEFINE_PATCH_MACRO Q_VarVar_AddNewRecord
BEGIN
 SPRINT "Q_VarType" ~%Q_NewVarType%~
 SPRINT "Q_VarName" ~%Q_NewVarName%~
 LAUNCH_PATCH_MACRO Q_VarVar_MakeVarIntoByteArray
 DEFINE_ARRAY "Q_NewVarArray"
 BEGIN
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 END
 FOR (i = 1; i <= 40; i += 1) BEGIN SET $Q_NewVarArray("%i%") = $Q_StringArray("%i%") END
 SET FoundPos = 0
 SET CurPosition = 0x0
 SET SkipFiftyTest = 1
 WHILE CurPosition < Q_FileSize AND FoundPos = 0
 BEGIN
 SET StringPos = 1
 SET GotoNextRecord = 0
 READ_ASCII "CurPosition"	   "Q_VarType" (8)
 READ_ASCII "CurPosition" + 0x8 "Q_VarName" (32)
 LAUNCH_PATCH_MACRO Q_VarVar_MakeVarIntoByteArray
 WHILE StringPos <= 40 AND GotoNextRecord = 0 AND FoundPos = 0
 BEGIN
	PATCH_IF $Q_StringArray("%StringPos%") = $Q_NewVarArray("%StringPos%")
	BEGIN SET StringPos = StringPos + 1 END
	ELSE
	BEGIN
	  PATCH_IF $Q_StringArray("%StringPos%") < $Q_NewVarArray("%StringPos%")
	  BEGIN
		PATCH_IF SkipFiftyTest = 1
		BEGIN
		   SET GotoNextRecord = 1
		   SET CurPosition = CurPosition + (0x2c * 50)
		   PATCH_IF CurPosition > Q_FileSize
		   BEGIN
			  SET SkipFiftyTest = 0
			  SET CurPosition = CurPosition - (0x2c * 50)
		   END
		END
		ELSE
		BEGIN
		   SET GotoNextRecord = 1
		   SET CurPosition = CurPosition + 0x2c
		END
	  END
	  ELSE PATCH_IF SkipFiftyTest = 1
	  BEGIN
		 SET SkipFiftyTest = 0
		 SET GotoNextRecord = 1
		 SET CurPosition = CurPosition - (0x2c * 50)
	  END
	  ELSE SET FoundPos = 1
	END
 END
 END
 PATCH_IF FoundPos = 1
 BEGIN
INSERT_BYTES "CurPosition" 0x2c
WRITE_ASCIIE "CurPosition" + 0x0 "%Q_NewVarType%" #8
WRITE_ASCIIE "CurPosition" + 0x8 "%Q_NewVarName%" #32
WRITE_LONG "CurPosition" + 0x28 "Q_NewVarValue"
SET Q_FileSize = Q_FileSize + 0x2c
 END
END

// ============================ END Q_VarVar_AddNewRecord Definition ============================

 

Fully tested and works great, even with records that need to be inserted very close to the beginning or end of the file (which is unlikely anyway). VAR.VAR won't be a barrier to modding PS:T anymore :crazyeyes:

 

Qwinn

Link to comment

Got a crapload done the last few days. Seriously wrapping up now. Think I can start my playtest tomorrow, yay.

 

My Scale of Souls is 99% done too. I think folks will like it. There's a couple of things I'd like to do, though, and I'm not sure I can.

 

1. Is it possible to have a conversable item that you can use (i.e. access it's dialogue) before it's been identified?

 

2. Is it possible to change an item's state to identified via dialogue?

 

Basically, what I want is that when you find the scales, you don't know what they are (unidentified), but you can use it and figure out what it is and how to use it through the dialogue, either by passing some stat checks or via Morte telling you if he's with you. Any way to accomplish this?

 

EDIT: Eureka! Two items, one with Lore Required 0 and usable but whose identified text is vague. When you are told what it is via dialogue, transform the item to a Lore Required 0 identified version. Only question is, will transforming the item -while I'm in dialogue attached to it- cause any problems? Both items would share the same dialog file.

 

Qwinn

Link to comment
Only question is, will transforming the item -while I'm in dialogue attached to it- cause any problems? Both items would share the same dialog file.
I dunno... any variables should probably be GLOBALs. Apart from that, you might actually have to *gulp* test (my least favourite word).

 

I see someone covered your BAM, which is probably better than what I could do and gives me one less BAM to make :crazyeyes:.

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...