Qwinn Posted April 29, 2008 Author Share Posted April 29, 2008 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 Qwinn Link to comment
Qwinn Posted April 29, 2008 Author Share Posted April 29, 2008 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
Nythrun Posted April 30, 2008 Share Posted April 30, 2008 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
Qwinn Posted April 30, 2008 Author Share Posted April 30, 2008 Oh, I didn't think I'd suggested that that part was wrong. That all seems accurate to me... it's just the which specific offsets contains which values part that I felt should be corrected. Qwinn Link to comment
Nythrun Posted April 30, 2008 Share Posted April 30, 2008 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 Link to comment
devSin Posted April 30, 2008 Share Posted April 30, 2008 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
Qwinn Posted April 30, 2008 Author Share Posted April 30, 2008 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
Qwinn Posted April 30, 2008 Author Share Posted April 30, 2008 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
Nythrun Posted May 1, 2008 Share Posted May 1, 2008 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 /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
Qwinn Posted May 3, 2008 Author Share Posted May 3, 2008 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. 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
Qwinn Posted May 3, 2008 Author Share Posted May 3, 2008 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
Qwinn Posted May 3, 2008 Author Share Posted May 3, 2008 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 Qwinn Link to comment
Qwinn Posted May 6, 2008 Author Share Posted May 6, 2008 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
Miloch Posted May 6, 2008 Share Posted May 6, 2008 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 . Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.