argent77 Posted July 20, 2017 Share Posted July 20, 2017 The majority of my own functions and macros are too specific to be of (general) use. But there is a small number of functions that might be helpful. TO_HEX_NUMBER: A decimal to hexadecimal number converter. May be useful when dealing with IDS or INI files. /** * Patch function. Converts any decimal number into a hexadecimal number. * INT_VAR value The decimal number to convert. * INT_VAR minDigits Minimum number of digits for the returned hex value. (default: 1) * INT_VAR prefix A flag that indicates whether the returned number will be prefixed with "0x". (default: 0) * RET hexNumber The converted hexadecimal number as string. */ DEFINE_PATCH_FUNCTION TO_HEX_NUMBER INT_VAR value = 0 minDigits = 1 prefix = 0 RET hexNumber BEGIN SET minDigits = (minDigits < 1) ? 1 : minDigits SET minDigits = (minDigits > 8) ? 8 : minDigits TEXT_SPRINT hexNumber ~~ PATCH_DEFINE_ARRAY digit BEGIN ~0~ ~1~ ~2~ ~3~ ~4~ ~5~ ~6~ ~7~ ~8~ ~9~ ~a~ ~b~ ~c~ ~d~ ~e~ ~f~ END PATCH_IF (value < 0) BEGIN SET signed = 1 SET value = 0 - value END ELSE BEGIN SET signed = 0 END WHILE (value != 0) BEGIN SET curDigit = value BAND 0xf SET value = value BLSR 4 TEXT_SPRINT hexDigit $EVAL digit(~%curDigit%~) TEXT_SPRINT hexNumber ~%hexDigit%%hexNumber%~ END WHILE (STRING_LENGTH ~%hexNumber%~ < minDigits) BEGIN TEXT_SPRINT hexNumber ~0%hexNumber%~ END PATCH_IF (prefix) BEGIN TEXT_SPRINT hexNumber ~0x%hexNumber%~ END PATCH_IF (signed) BEGIN TEXT_SPRINT hexNumber ~-%hexNumber%~ END END // Action version of TO_HEX_NUMBER DEFINE_ACTION_FUNCTION TO_HEX_NUMBER INT_VAR value = 0 minDigits = 1 prefix = 0 RET hexNumber BEGIN OUTER_PATCH ~~ BEGIN LPF TO_HEX_NUMBER INT_VAR value = value minDigits = minDigits prefix = prefix RET hexNumber END END END FIND_FREE_ANIM_SLOT: This function attempts to find a free creature animation slot in a given range, so that it can be used to install custom creature animations. I'm using it quite extensively in my Golem Construction mod (example code). This function requires EE games patched to v1.4 or higher. It also makes use of the function TO_HEX_NUMBER mentioned above. // Internally used: Animation slots reserved by vanilla or mod-added game creatures (in hexadecimal format) // Mods with fixed animation slots that are currently considered: // - Bearwalker + extended Werebear animation // - Pack Mule OUTER_TEXT_SPRINT animationSlots ~"0410" "1000" "1003" "1004" "1100" "1101" "1102" "1103" "1104" "1105" "1200" "1201" "1202" "1203" "1204" "1205" "1206" "1207" "1208" "1300" "2000" "2100" "2200" "2300" "3000" "3001" "4000" "4001" "4002" "4010" "4012" "4100" "4101" "4102" "4110" "4112" "4200" "4300" "4400" "4410" "4500" "4600" "4700" "4710" "4800" "5000" "5001" "5002" "5003" "5010" "5011" "5012" "5013" "5100" "5101" "5102" "5103" "5110" "5111" "5112" "5113" "5200" "5201" "5202" "5210" "5211" "5212" "5300" "5301" "5302" "5303" "5310" "5311" "5312" "5313" "6000" "6001" "6002" "6003" "6004" "6005" "6010" "6011" "6012" "6013" "6014" "6015" "6100" "6101" "6102" "6103" "6104" "6105" "6110" "6111" "6112" "6113" "6114" "6115" "6200" "6201" "6202" "6204" "6205" "6210" "6211" "6212" "6214" "6215" "6300" "6301" "6302" "6303" "6304" "6305" "6310" "6311" "6312" "6313" "6314" "6315" "6400" "6401" "6402" "6403" "6404" "6405" "6406" "6500" "6510" "6621" "7000" "7001" "7100" "7101" "7200" "7201" "7202" "7203" "7300" "7301" "7302" "7310" "7311" "7312" "7313" "7314" "7320" "7321" "7400" "7401" "7402" "7500" "7501" "7600" "7601" "7602" "7603" "7604" "7700" "7701" "7702" "7703" "7800" "7801" "7802" "7900" "7901" "7902" "7903" "7904" "7a00" "7a01" "7a02" "7a03" "7a04" "7b00" "7b01" "7b02" "7b03" "7b04" "7b05" "7b06" "7c00" "7c01" "7d00" "7d01" "7d02" "7d03" "7d04" "7d05" "7d06" "7d07" "7d08" "7e00" "7e01" "7f00" "7f01" "7f02" "7f03" "7f04" "7f05" "7f06" "7f07" "7f08" "7f09" "7f0a" "7f0b" "7f0c" "7f0d" "7f0e" "7f0f" "7f10" "7f11" "7f12" "7f13" "7f14" "7f15" "7f16" "7f17" "7f18" "7f19" "7f20" "7f21" "7f22" "7f23" "7f24" "7f27" "7f28" "7f29" "7f2a" "7f2b" "7f2c" "7f2d" "7f2e" "7f2f" "7f30" "7f31" "7f32" "7f33" "7f34" "7f35" "7f36" "7f37" "7f38" "7f39" "7f3a" "7f3b" "7f3c" "7f3d" "7f3e" "7f3f" "7f40" "7f41" "7f42" "7f43" "7f44" "7f45" "7f46" "7f47" "7f48" "7f49" "7f4a" "7f4b" "7f4c" "7f4d" "7f4e" "7f4f" "7f50" "7f51" "7f52" "7f53" "7f54" "7f55" "7f56" "7f57" "7f58" "7f59" "7f5a" "7f5b" "7f5c" "7f5d" "7f5e" "7f5f" "7f60" "7f61" "7f62" "8000" "8100" "8200" "9000" "a000" "a100" "a200" "a201" "a202" "b000" "b100" "b200" "b210" "b300" "b310" "b400" "b410" "b500" "b510" "b600" "b610" "b700" "c000" "c100" "c200" "c300" "c400" "c500" "c600" "c610" "c700" "c710" "c800" "c810" "c900" "c910" "ca00" "ca10" "cb00" "cc00" "cc01" "cc02" "cc04" "d000" "d100" "d200" "d300" "d400" "e000" "e010" "e020" "e040" "e050" "e060" "e070" "e080" "e090" "e0a0" "e0b0" "e0c0" "e0d0" "e0e0" "e0f0" "e0f1" "e0f2" "e200" "e210" "e220" "e230" "e240" "e241" "e242" "e243" "e244" "e245" "e246" "e247" "e248" "e249" "e24a" "e24b" "e24c" "e24d" "e24e" "e24f" "e250" "e251" "e252" "e253" "e254" "e255" "e256" "e257" "e258" "e259" "e25a" "e25b" "e25c" "e25d" "e25e" "e25f" "e260" "e261" "e262" "e263" "e264" "e265" "e266" "e267" "e26a" "e26b" "e26d" "e26e" "e26f" "e270" "e271" "e272" "e273" "e274" "e276" "e279" "e27d" "e27e" "e27f" "e280" "e281" "e282" "e283" "e288" "e289" "e28a" "e28b" "e28c" "e28d" "e28e" "e28f" "e290" "e291" "e292" "e293" "e294" "e300" "e310" "e320" "e330" "e400" "e410" "e420" "e430" "e440" "e441" "e442" "e443" "e444" "e500" "e510" "e520" "e600" "e610" "e6fe" "e700" "e710" "e720" "e800" "e810" "e820" "e830" "e840" "e900" "e910" "ea00" "ea10" "ea20" "eb00" "eb10" "eb20" "ec00" "ec10" "ec20" "ed00" "ed10" "ed20" "ee00" "ee10" "ef10" "f000" "f001" "f002" "f003" "f004" "f005" "f006" "f007" "f008" "f009" "f00a" "f00b" "f00c" "f00d" "f00e" "f00f" "f010" "f011" "f012" "f013" "f014" "f015" "f016" "f017" "f018" "f019" "f01a" "f01b" "f01c" "f01d" "f01e" "f01f" "f020" "f021" "f022" "f023" "f024" "f025" "f026" "f027" "f028" "f029" "f02a" "f02b" "f02c" "f02d" "f02e" "f02f" "f030" "f031" "f032" "f033" "f034" "f035" "f036" "f037" "f038" "f039" "f03a" "f03b" "f03c" "f03d" "f03e" "f03f" "f040" "f041" "f042" "f043" "f044" "f045" "f046" "f047" "f048" "f049" "f04a" "f04b" "f04c" "f04d" "f04e" "f04f" "f050" "f051" "f052" "f053" "f054" "f055" "f056" "f057" "f058" "f059" "f05a" "f05b" "f05c" "f05d" "f05e" "f05f" "f060" "f061" "f062" "f100" "f101" "f22e" "f80e"~ /** * Patch function. Returns the first free creature animation slot in the range defined by slotMin and slotMax. * INT_VAR slotMin Lowest available creature animation slot for the animation, inclusive. (Default: 0) * INT_VAR slotMax Highest available creature animation slot for the animation, exclusive. * (Default: highest value for slot type indicated by "slotMin") * INT_VAR slotSteps How many slots to skip after each iteration, starting from slotMin. * Setting this parameter is useful if compatible animation slots are always * a fixed distance apart (e.g. at a distance of 0x10 each). (Default: 1) * RET slot A free animation slot. Returns -1 if none are found in the given range. */ DEFINE_PATCH_FUNCTION FIND_FREE_ANIM_SLOT INT_VAR slotMin = 0 slotMax = (slotMin BAND 0xf000) + 0x1000 slotSteps = 1 RET slot BEGIN SET slot = "-1" SET slotSteps = (slotSteps < 1) ? 1 : slotSteps SET slotMin = (slotMin < 0) ? 0 : slotMin SET slotMax = (slotMax < 0) ? 0 : slotMax PATCH_IF (slotMax < slotMin) BEGIN SET tmp = slotMin SET slotMin = slotMax SET slotMax = tmp END INNER_PATCH ~%animationSlots%~ BEGIN FOR (idx = slotMin; idx < slotMax; idx += slotSteps) BEGIN LOOKUP_IDS_SYMBOL_OF_INT name ~animate~ idx PATCH_IF (~%name%~ STR_EQ ~%idx%~) BEGIN LPF TO_HEX_NUMBER INT_VAR value = idx minDigits = 4 RET hexNumber END PATCH_IF (NOT FILE_EXISTS_IN_GAME ~%hexNumber%.ini~ AND ~%slotList%~ STRING_CONTAINS_REGEXP ~"%hexNumber%"~ != 0) BEGIN SET slot = idx SET idx = slotMax END END END END END // Action version of FIND_FREE_ANIM_SLOT DEFINE_ACTION_FUNCTION FIND_FREE_ANIM_SLOT INT_VAR slotMin = 0 slotMax = (slotMin BAND 0xf000) + 0x1000 slotSteps = 1 RET slot BEGIN OUTER_PATCH ~~ BEGIN LPF FIND_FREE_ANIM_SLOT INT_VAR slotMin = slotMin slotMax = slotMax slotSteps = slotSteps RET slot END END END Quote Link to comment
K4thos Posted July 20, 2017 Share Posted July 20, 2017 (edited) TO_HEX_NUMBER:A decimal to hexadecimal number converter. May be useful when dealing with IDS or INI files. there is actually a hidden SPRINTF command in weidu that can do it. Example: SET dec_value = 3 SPRINTF hex_value ~%x~ (dec_value) PATCH_PRINT ~%hex_value%~ Edited July 20, 2017 by K4thos Quote Link to comment
argent77 Posted July 20, 2017 Share Posted July 20, 2017 You're right. There is a (patch-only) SPRINTF command available which supports %s, %d and %x format specifiers. However, the command doesn't properly convert negative values into hexadecimal format, always prefixes the result with "0x" and you can't specify minimum number of digits, which forces me to do a lot of editing either way for my purposes. Quote Link to comment
Angel Posted July 20, 2017 Share Posted July 20, 2017 FIND_FREE_ANIM_SLOT:This function attempts to find a free creature animation slot in a given range, so that it can be used to install custom creature animations. I'm using it quite extensively in my Golem Construction mod (example code). This function requires EE games patched to v1.4 or higher. It also makes use of the function TO_HEX_NUMBER mentioned above. Ah, if only I knew how to create new animations and add them to the game. It's been a long-time wish of mine to add griffins, (black) unicorns and nightmares, to name but a few. :-) Quote Link to comment
Gwendolyne Posted July 20, 2017 Share Posted July 20, 2017 (edited) FIND_FREE_ANIM_SLOT:This function attempts to find a free creature animation slot in a given range, so that it can be used to install custom creature animations. I'm using it quite extensively in my Golem Construction mod (example code). This function requires EE games patched to v1.4 or higher. It also makes use of the function TO_HEX_NUMBER mentioned above. Ah, if only I knew how to create new animations and add them to the game. It's been a long-time wish of mine to add griffins, (black) unicorns and nightmares, to name but a few. :-) Sorry for the off-topic, but you won't have to wait too long, at least for unicorns (regular and black ones) and nightmares. Edited July 20, 2017 by Gwendolyne Quote Link to comment
Angel Posted July 21, 2017 Share Posted July 21, 2017 FIND_FREE_ANIM_SLOT:This function attempts to find a free creature animation slot in a given range, so that it can be used to install custom creature animations. I'm using it quite extensively in my Golem Construction mod (example code). This function requires EE games patched to v1.4 or higher. It also makes use of the function TO_HEX_NUMBER mentioned above. Ah, if only I knew how to create new animations and add them to the game. It's been a long-time wish of mine to add griffins, (black) unicorns and nightmares, to name but a few. :-) Sorry for the off-topic, but you won't have to wait too long, at least for unicorns (regular and black ones) and nightmares. Interesting, I will certainly keep an eye on that. Please tell me they will work with non-EE games as well! And I'd pay you to make a griffin animation. (Seriously, I would.) Quote Link to comment
Gwendolyne Posted July 21, 2017 Share Posted July 21, 2017 End of the off-topic : my mod is written for BG2 and BGT and will be EE compatible. The ironic point is that I can use huge tarasque animations (640x640 px) with IA but not in BG2:EE because the enhanced dragon animation format seems to be buggy and does not allow to add new effective slots to ANIMATE.IDS. Quote Link to comment
jastey Posted July 25, 2017 Share Posted July 25, 2017 (edited) argent77 just posted a WeiDU function to to fetch a journal strref here. Thinking about all the instances where original game journal entries need to be erased by a mod which only works for exact matching strings but BGT / EET not having them at specified reference numbers, this is very cool to use especially across game platforms. Edited July 25, 2017 by jastey Quote Link to comment
K4thos Posted July 25, 2017 Share Posted July 25, 2017 but BGT / EET not having them at specified reference numbers actually EET handles BG1 strrefs in a static way. SAY is not used at all during installation. You can reference correct journal number by simply adding 200000 to the original strrefs. For example BG1 strrefs 27091 is 227091 in EET and that's always true regardless of mods you install before/after it. Quote Link to comment
jastey Posted July 25, 2017 Share Posted July 25, 2017 Ah, yes, I recall now that I knew this. That is a very good thing. Still, since my mods are compatible with BGT, as well, I'll always have the problem with floating strrefs. Quote Link to comment
K4thos Posted July 25, 2017 Share Posted July 25, 2017 (edited) the function is extremely useful, indeed. Even BG2 Fixpack 'Game Text Update' can brake journal erasing in mods that use exact match approach (and there are 2 versions of this component if I remember correctly). Then there is a problem with translation of strings (I remember tons of issues with erasing journal in Polish version of some older mods - most likely because translator didn't even know that the text was meant to be copied directly from TLK file rather than translated from scratch). Now I feel silly since I never thought about looking what IESDP has to say about DLG format (which turns out can be looped through like any other BG file format). For some reason I always considered it as a text file while decompiled and unreadable gibberlish after compiling Edited July 25, 2017 by K4thos Quote Link to comment
Gwendolyne Posted July 25, 2017 Share Posted July 25, 2017 Now I feel silly since I never thought about looking what IESDP has to say about DLG format (which turns out can be looped through like any other BG file format). For some reason I always considered it as a text file while decompiled and unreadable gibberlish after compiling You can loop through states and transitions. Here is a homemade function used to extend existing dlg: DEFINE_PATCH_FUNCTION ~GW_FIND_DLG_RESPONSE_STRING~ INT_VAR GW_string_dlg = 0 // string we are looking for RET GW_transition_found // Y = strref found GW_state_number GW_transition_number BEGIN SET GW_transition_number = "-99" SET GW_state_number = "-99" SPRINT GW_transition_found "N" READ_LONG 0x08 GW_numstates // Number of states READ_LONG 0x0c GW_offstates // Offset of state table from start of file READ_LONG 0x10 GW_numresponse // Number of transitions READ_LONG 0x14 GW_offresponse // Offset of transition table from start of file FOR (state = 0 ; state < GW_numstates ; ++state) BEGIN PATCH_IF ("%GW_transition_found%" STRING_COMPARE_CASE "Y") BEGIN READ_LONG ("%GW_offstates%" + (state * 0x10)) GW_state_string // Actor response text (i.e. what the non-player character says to the party) READ_LONG ("%GW_offstates%" + 0x4 + (state * 0x10)) GW_index_first_response // Index of the first transition corresponding to this state (i.e. the index in the transition table of the first potential response the party can make in this state). READ_LONG ("%GW_offstates%" + 0x8 + (state * 0x10)) GW_state_num_response // Number of transitions corresponding to this state (i.e. how many possible responses are there to this state). A consecutive range of transitions in the transition table are assigned to this state, starting from 'first', as given by the previous field, ranging up to (but not including) 'first'+'count'. FOR (response = 0 ; response < GW_state_num_response ; ++response) BEGIN READ_LONG ("%GW_offresponse%" + 0x4 + ("%GW_index_first_response%" * 0x20) + (response * 0x20)) GW_response_string PATCH_IF (GW_response_string = GW_string_dlg) BEGIN SET GW_transition_number = response SET GW_state_number = state SPRINT GW_transition_found "Y" END END // of Looping through responses END // PATCH_IF ("%GW_transition_found%" STRING_COMPARE_CASE "Y") END // of Looping through states END // of DEFINE_PATCH_FUNCTION Then: COPY_EXISTING - ~UHOGRE01.dlg~ ~override~ PATCH_IF (SOURCE_SIZE > 0x2f) THEN BEGIN // protects against invalid files // #33324 ~J'ai surtout décidé de mettre un terme à ton ignoble existence, sale monstre !~ // EN = ~I've actually decided to end your monstrous existence, creature!~ LPF ~GW_FIND_DLG_RESPONSE_STRING~ INT_VAR GW_string_dlg = 33324 RET GW_transition_found GW_state_number GW_transition_number END PATCH_IF ("%GW_transition_found%" STRING_EQUAL "Y") AND (GW_transition_number != "-99") BEGIN SET UHOGRE01_Transition16 = GW_transition_number SET UHOGRE01_State16 = GW_state_number END END // of PATCH_IF (SOURCE_SIZE > 0x2f) BUT_ONLY And actually in the d file: EXTEND_TOP UHOGRE01 %UHOGRE01_State16% #%UHOGRE01_Transition16% + ~Global("GWChevaucheuseKit","GLOBAL",2) Global("GWLyrielUmar","LOCALS",0)~ + @11100501 GOTO UhOgre01_Question // ~D'abord, j'aimerais que tu répondes à une question, Madulf.~ END Quote Link to comment
Jarno Mikkola Posted July 25, 2017 Share Posted July 25, 2017 (edited) Off topic, but have to ask, what's the difference ? PATCH_IF plah THEN BEGIN ... PATCH_IF plah BEGIN Edit: thanks for the conformation ... I write it too... but most of he time it's there cause of a copy-paste had it. Edited July 25, 2017 by Jarno Mikkola Quote Link to comment
Gwendolyne Posted July 25, 2017 Share Posted July 25, 2017 In WeiDU it seems: none! But as I am far away from being a programmer, I learned the IF THEN condition way of codding at my beginnings, a long time ago. After many years of modding, I know that THEN is not mandatory in WeiDU code but... the force of habit: sometimes I write it, sometimes not... Quote Link to comment
jastey Posted July 26, 2017 Share Posted July 26, 2017 Question to cd_extend_bg_area_script: If I have a script that uses tra strings, but from another file (with different name). Is that possible? Where would I put the USING ~path/blah.tra~? Quote Link to comment
Recommended Posts
Join the conversation
You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.