Hiding spell feedback
System
Administrator Posts: 199
in UI Modding
This discussion was created from comments split from: The New UI System: How to Use It.
0
Comments
I am attempting to write a tweak that removes combat feedback from spellcasting much like IWD2 so that you will have to guess what your foes have cast. One way to do that is set the name to all spells to "" but that carries with the disadvantage of you not knowing the spell description from you abilities bar/spell book. I am thinking about using the currently unused "identified name" for spellbooks/ability selection.
Another alternative is modifying ENGINEST.2da's entry STRREF_FEEDBACK_CASTS but that does not seem to work as the strref itself does not include any tokens. You would still see "X - Stoneskin: X" instead of "X - Casts Stoneskin: X".
I know it's been a while, but I have found something that works, for spells at least:
It can't block the string for using innate abilities, because they aren't preceded with anything to match.
I just do not have the patience and energy to explore the possibilities of UI.menu modding; I will sooner figure out how to parse and replace blocks in UI.menu on the fly than figure out how the entire UI system works. May I borrow the code for inclusion of a future tweak pack? I will look into writing a function that can parse/replace blocks in the UI.menu with the help of INDEX_BUFFER.
Fortunately it is a case sensitive check, reducing the chance of it matching in dialog anywhere, but its still a slight possibility. This will get a more strict text match: and should be enough to avoid any normal dialog instance of the word "Casts" from triggering the replacement.
Now that I think more about it is it possible to exclude innates by specifying a list of innates in the string.gsub function if it works with regexps? i.e. by adding another line
text = string.gsub(text, ":[%w%p ]*(Cure Light Wounds|...|...)[%w%p ]*", ": Activates an ability")
I could theoretically scan all of the innate spells in the game, record their strings, and construct a monster regexp string that catches all the spells.
UI.Menu:
text = string.gsub(text, ":[%w%p ]*" .. STRREF_FEEDBACK_CASTS .. "[%w%p ]*", ": Casts a spell")
Sorry, misread your post, but the idea is similar, what I posted was to pull the "Casts" string from ENGINEST, instead of the TLK entry number. This version will enable you to reference a tlk entry. I also forgot that the message text contains color codes for the text, which was making it difficult to get specific matches, so again improved it a little:
the %^0x%w... is to match any hex color code that string contains. It may be replacable with an exact hex string, I just don't know how/where that color is determined or if its going to be the same across games.
Meanwhile I've made some progress with the "hide spell feedback" mod. I've got around the limitation of innate abilities with a trick by adding a marker in front of the name all spells i.e. "Armor" becomes "-:Armor" and so on. Note that spells cast from scrolls do not use the "Casts " so they appear as innates as well. This "marker" trick can fix that by applying a different set of markers to differenciate between spell types. I like this system because it's possible to refine it by spell type (i.e. "Uses a psionic ability" for a narrow class of spells) and spells that are not patched will still use the default feedback. The only missing part is now hiding those markers when you view your spellbooks/hover your mouse over the ability so that you see "Armor" instead of "-:Armor:-".
I'm attaching the entire code below so you can play around with it. It still generates text directly in the menu file but it has the basics of the "marker" concept working.
BEGIN "Hide spell feedback" DEFINE_PATCH_FUNCTION "INSERT_UI_BLOCK" INT_VAR added_ui_block = 0 STR_VAR new_block = "" find_block = "" RET added_ui_block // set to 1 if insertion is successful BEGIN SET added_ui_block = 0 // reset to default value // Truncate any blank spaces/lines at the end of input variable INNER_PATCH_SAVE new_block "%new_block%" BEGIN PATCH_IF BUFFER_LENGTH > 0 BEGIN // truncate at end READ_ASCII (BUFFER_LENGTH - 1) last (1) WHILE "%last%" STRING_MATCHES_REGEXP "[ %TAB%%LNL%%MNL%%WNL%]" = 0 AND BUFFER_LENGTH > 0 BEGIN DELETE_BYTES (BUFFER_LENGTH - 1) 1 READ_ASCII (BUFFER_LENGTH - 1) last (1) END END END // Set OS-specific newline variable PATCH_IF "%WEIDU_OS%" STRING_EQUAL_CASE "win32" BEGIN SPRINT NEWLINE "%WNL%" END ELSE PATCH_IF "%WEIDU_OS%" STRING_EQUAL_CASE "osx" BEGIN SPRINT NEWLINE "%MNL%" END ELSE BEGIN SPRINT NEWLINE "%LNL%" END PATCH_IF "%SOURCE_FILE%" STRING_MATCHES_REGEXP "^.+\.menu$" = 0 BEGIN // sanity check SET index_begin = INDEX_BUFFER ("%find_block%" 0) PATCH_IF index_begin >= 0 BEGIN // If found a result SET write_length = STRING_LENGTH "%new_block%" INSERT_BYTES index_begin (write_length + 2) WRITE_ASCIIE index_begin "%new_block%%NEWLINE%%NEWLINE%" (write_length + 2) SET added_ui_block = 1 END END END OUTER_SPRINT UI_casts_new_text ": *casts a spell*" OUTER_SPRINT UI_usesab_new_text ": *uses an ability*" // Pad name of every single spell with special characters (i.e. convert "Armor" into "-:Armor:-") OUTER_SPRINT begin_padsplname_new "-:" OUTER_SPRINT end_padsplname_new ":-" OUTER_SPRINT UI_casts_existing_text "Casts" // default value COPY_EXISTING "ENGINEST.2da" "override" REPLACE_EVALUATE "\(STRREF_FEEDBACK_CASTS[ %TAB%]+\)\([0]?[x]?[0-9]+\)" BEGIN PATCH_IF IS_AN_INT MATCH2 BEGIN GET_STRREF MATCH2 UI_casts_existing_text // Get string END END "%MATCH1%%MATCH2%" BUT_ONLY <<<<<<<< .../%MOD_FOLDER%-Inlined/RemoveSpellMessage.menu function removespellmessage() -- Replace casting text (i.e. "Edwin: Casts Armor" becomes "Edwin: *casts a spell*") -- Replace padded spell names (i.e. "Edwin: -:Armor:-" becomes "Edwin: *uses an ability*") local text = worldMessageBoxText text = string.gsub(text, ":[%w%p ]*%UI_casts_existing_text%[%w%p ]*", "%UI_casts_new_text%") text = string.gsub(text, ":[%w%p ]*%begin_padsplname_new%[%w%p ]*", "%UI_usesab_new_text%") text = string.gsub(text, ":%^0x%w%w%w%w%w%w%w%w", "^0xFFFFFFFF") return text end >>>>>>>> COPY - ".../%MOD_FOLDER%-Inlined/RemoveSpellMessage.menu" "" READ_ASCII 0 removespellmessage (BUFFER_LENGTH) // Insert function "RemoveSpellMessage" above "menu { name 'WORLD_MESSAGES'" COPY_EXISTING "UI.menu" "override" LPF "INSERT_UI_BLOCK" STR_VAR new_block = EVAL "%removespellmessage%" find_block = EVAL "[ %TAB%%LNL%%MNL%%WNL%]`[ %TAB%%LNL%%MNL%%WNL%]+menu[ %TAB%%LNL%%MNL%%WNL%]+{[ %TAB%%LNL%%MNL%%WNL%]+name 'WORLD_MESSAGES'" RET added_ui_block END PATCH_IF added_ui_block = 1 BEGIN // if function was successfully added REPLACE_TEXTUALLY ~\(name "worldMessageBox"[^{}]+\)\([%LNL%%MNL%%WNL%][ %TAB%]*\)\(text lua "worldMessageBoxText"\)~ ~\1\2\3\2text lua "removespellmessage()"~ END BUT_ONLY // Pad name of every single spell COPY_EXISTING_REGEXP GLOB "^.+\.spl$" "override" PATCH_IF SOURCE_SIZE > 0x71 BEGIN // Sanity check PATCH_IF LONG_AT 0x8 > 0 AND LONG_AT 0x8 < 1000000 BEGIN // If valid spell name READ_STRREF 0x8 spell_name_text PATCH_IF NOT "%spell_name_text%" STRING_EQUAL_CASE "" AND NOT "%spell_name_text%" STRING_MATCHES_REGEXP "<\(NO TEXT\|Not Available\|Invalid Reference\|Invalid Strref\).*>" = 0 BEGIN // If valid spell name INNER_PATCH_SAVE spell_name_text "%spell_name_text%" BEGIN // Pad beginning of spell name SPRINT begin_padsplname_existing "" PATCH_IF BUFFER_LENGTH >= STRING_LENGTH "%begin_padsplname_new%" BEGIN READ_ASCII 0 begin_padsplname_existing (STRING_LENGTH "%begin_padsplname_new%") END PATCH_IF NOT "%begin_padsplname_existing%" STRING_EQUAL_CASE "%begin_padsplname_new%" BEGIN INSERT_BYTES 0 (STRING_LENGTH "%begin_padsplname_new%") WRITE_ASCIIE 0 "%begin_padsplname_new%" (STRING_LENGTH "%begin_padsplname_new%") END // Pad end of spell name SPRINT end_padsplname_existing "" PATCH_IF BUFFER_LENGTH >= STRING_LENGTH "%end_padsplname_new%" BEGIN READ_ASCII (BUFFER_LENGTH - (STRING_LENGTH "%end_padsplname_new%")) end_padsplname_existing (STRING_LENGTH "%end_padsplname_new%") END PATCH_IF NOT "%begin_padsplname_existing%" STRING_EQUAL_CASE "%end_padsplname_new%" BEGIN INSERT_BYTES BUFFER_LENGTH (STRING_LENGTH "%end_padsplname_new%") WRITE_ASCIIE (BUFFER_LENGTH - (STRING_LENGTH "%end_padsplname_new%")) "%end_padsplname_new%" (STRING_LENGTH "%end_padsplname_new%") END END SAY_EVALUATED 0x8 "%spell_name_text%" END END END BUT_ONLY
I was using the color code as a marker, not trying to replace it. By not using the wildcard(*+-) matches, but instead getting exactly 11 characters matching the color code format, there is almost no risk of catching the text "Casts" somewhere *within* dialogue. My text was still off-white when I did this - not the white used by the game. I have since found the color the game uses for "white" text: 0xffbed7d7, so it can resume in proper color.
Some of your code is still more than I understand, but here are the parts I would alter for tra/tlk references.
Just comment/delete the forms you don't wish to use (str, tra, or tlk), and input proper @tra or #tlk reference numbers. replace with: and then changes to this section: These are the lines that get spellnames, to remove the "-: | :-" in the:
magebook:
text lua "Infinity_FetchString( bookSpells[rowNumber].name)"
->text lua "replacemagespellheader()"
priestscroll:
text lua "Infinity_FetchString( characters[id].priestSpells[currentSpellLevel][rowNumber].name)"
->text lua "replacepriestspellheader()"
I've applied your functions and patches and I've got all the issues fixed, the text *casts a spell* now correctly displays in white, and all markers are gone when viewing the priest/mage scroll. I did run into two issues:
1. *uses an ability* did not display correctly, possibly having to do with the number of spaces between "charname: abilityname" which is two spaces. I had to replace
text = string.gsub(text, ": %^0x%w%w%w%w%w%w%w%w%%begin_padsplname_new%[%w%p ]*", ": ^0xffbed7d7" .. UI_usesab_new_text)
withtext = string.gsub(text, ":[%w%p ]*%begin_padsplname_new%[%w%p ]*", ": ^0xffbed7d7" .. UI_usesab_new_text)
to fix the issue.2. The markers are still there when hovering your mouse over a spell or ability in the main game screen and the tooltip scroll appears. Do you know where in UI.menu the text from tooltips can be transformed?
menu "WORLD_ACTIONBAR"
There are 12 buttons(0-11), Button 0 has this line:
tooltip lua "actionBarTooltip[0]"
Button 1:tooltip lua "actionBarTooltip[1]"
etc...It could use a similar function, as the casters name is replaced with the function key, and there is no color code to worry about.
The new function would need to replace these lines: with: and replace:
tooltip lua "actionBarTooltip[0]"
with:tooltip lua "removetooltipmarker(0)"
for each button (0-11).See some examples on how it now works ingame:
I did run into one last problem: the spell markers are visible during character generation. Do you know where to replace them? I will post the full code once that remaining issue is fixed.
text lua "Infinity_FetchString(spellBook[chargen.currentSpellLevelChoice][chargen.choose_spell[rowNumber].key].name)"
with This is strange since the "hardcoded" lua functions work fine when called in all other applications of functions (tooltip, magebook, priest scroll).
text lua "replacechargenchoosespells()"
Need the quotes "", not that I know why.
This mod is pretty much complete except for the .traification and assigning categories to various groups of spells i.e. *uses breath weapon* and so on.
Here is the complete code:
BEGIN "Hide spell feedback" REQUIRE_PREDICATE (FILE_EXISTS_IN_GAME "UI.menu" AND FILE_EXISTS_IN_GAME "ENGINEST.2da") "Game must be EE" // Assign feedback text to spell types. // All spells matching conditions (left term) use the listed feedback (right term). // If a spell fulfills more than one condition the first valid item in the list is used. // Higher priority ...s are listed on top. // NOTE: Feedback text can be a string (i.e. "*uses psionics*") or a valid .tra entry (i.e. "100" or "@100" or "#100"). ACTION_DEFINE_ASSOCIATIVE_ARRAY "HIDE_SPELL_FEEDBACK" BEGIN "idsmask:.*PSIONIC.*" => "*uses psionics*" // Any spell where spell.ids symbol matches regexp "resmask:SPIN\(727\|834\|959\|97[45]\)" => "*uses psionics*" // Get remaining psionic spells "resmask:W_P.+" => "*uses psionics*" // Psionics Unleashed mod "spelltype:[12]" => "*launches a spell*" // Any wizard or priest spell "resmask:.*" => "*uses an ability*" // Catch all remaining spells END // Assign marker text to feedback text. // Higher priority text replacements are listed on top. // i.e. "*casts a spell*" text is overriden by anything above it. // NOTE: Feedback text can be a string (i.e. "*uses psionics*") or a valid .tra entry (i.e. "100" or "@100" or "#100"). ACTION_DEFINE_ASSOCIATIVE_ARRAY "HIDE_SPELL_FEEDBACK_MARKER" BEGIN "*uses psionics*" => ":PS:" // Psionics text is replaced before "X: Casts Y" text "*casts a spell*" => "STRREF_FEEDBACK_CASTS" // Replace "X: Casts Y" "*launches a spell*" => ":SP:" // If spell is cast via other means (i.e. ForceSpell(), scrolls, etc. that do not use "X: Casts Y") "*uses an ability*" => ":AB:" // Catch all remaining spells END DEFINE_PATCH_FUNCTION "STRING_TO_TRA" STR_VAR input_string = "" RET output_string BEGIN SPRINT output_string "" PATCH_IF "%input_string%" STRING_MATCHES_REGEXP "^[@#]\(0x\)?\([0-9]+\)$" = 0 BEGIN INNER_PATCH_SAVE input_string "%input_string%" BEGIN REPLACE_TEXTUALLY "[@#]" "" // Remove @/# symbol END END PATCH_IF IS_AN_INT input_string BEGIN PATCH_TRY SPRINT output_string (AT input_string) WITH DEFAULT SPRINT output_string "" END END ELSE BEGIN SPRINT output_string "" END END /** * Inserts a complete LUA function in *.menu or *.lua files. * STR_VAR new_block Insertion text. Two newlines are automatically added after the text. * STR_VAR find_block Text will be inserted before the following text (e.g. "function myFunctionToReplace(param1)"). * Match includes any whitespace found directly before the search text. * RET added_ui_block Returns 1 if the insertion was successful, 0 otherwise. * * Original author: Galactygon */ DEFINE_PATCH_FUNCTION INSERT_UI_BLOCK STR_VAR new_block = "" find_block = "" RET added_ui_block // set to 1 if insertion is successful BEGIN SET added_ui_block = 0 // reset to default value // Truncate any blank spaces/lines at the end of input variable INNER_PATCH_SAVE new_block "%new_block%" BEGIN PATCH_IF BUFFER_LENGTH > 0 BEGIN // truncate at end READ_ASCII (BUFFER_LENGTH - 1) last (1) WHILE "%last%" STRING_MATCHES_REGEXP "[ %TAB%%LNL%%MNL%%WNL%]" = 0 AND BUFFER_LENGTH > 0 BEGIN DELETE_BYTES (BUFFER_LENGTH - 1) 1 READ_ASCII (BUFFER_LENGTH - 1) last (1) END END END // Set OS-specific newline variable PATCH_IF "%WEIDU_OS%" STRING_EQUAL_CASE "unix" BEGIN SPRINT NEWLINE "%LNL%" END ELSE BEGIN SPRINT NEWLINE "%WNL%" END PATCH_IF ("%SOURCE_EXT%" STRING_EQUAL_CASE "menu" OR "%SOURCE_EXT%" STRING_EQUAL_CASE "lua") BEGIN // sanity check SET index_begin = INDEX_BUFFER ("[ %TAB%]*%find_block%" 0) PATCH_IF index_begin >= 0 BEGIN // If found a result SET write_length = STRING_LENGTH "%new_block%" INSERT_BYTES index_begin (write_length + 2) WRITE_ASCIIE index_begin "%new_block%%NEWLINE%%NEWLINE%" (write_length + 2) SET added_ui_block = 1 END END END <<<<<<<< .../%MOD_FOLDER%-Inlined/RemoveSpellMessage.menu function removespellmessage() local text = worldMessageBoxText temptext return text end >>>>>>>> COPY - ".../%MOD_FOLDER%-Inlined/RemoveSpellMessage.menu" "" PATCH_PHP_EACH "HIDE_SPELL_FEEDBACK_MARKER" AS input_feedback => input_marker BEGIN // Transform %input_feedback% variable if set to tra entry PATCH_IF "%input_feedback%" STRING_MATCHES_REGEXP "^[@#]?\(0x\)?\([0-9]+\)$" = 0 BEGIN LPF "STRING_TO_TRA" STR_VAR input_string = EVAL "%input_feedback%" RET use_feedback = output_string END END ELSE BEGIN SPRINT use_feedback "%input_feedback%" END SET UI_use_feedback = RESOLVE_STR_REF ("%use_feedback%") // Interpret %input_marker% and whether it exists in ENGINEST.2da PATCH_IF FILE_CONTAINS_EVALUATED ("ENGINEST.2da" "^%input_marker%[ %TAB%]+\(0x\)?[0-9]+") BEGIN INNER_PATCH_FILE "ENGINEST.2da" BEGIN // Record string from ENGINEST.2da as %UI_use_marker% REPLACE_EVALUATE "^%input_marker%[ %TAB%]+\([0]?[x]?[0-9]+\)" BEGIN PATCH_IF IS_AN_INT MATCH1 BEGIN SET UI_use_marker = MATCH1 END END "" END REPLACE_TEXTUALLY ~\([%LNL%%MNL%%WNL%]\)\([ %TAB%]*\)\(temptext\)~ ~\1\2local UI_use_marker = Infinity_FetchString(%UI_use_marker%)\1\2local UI_use_feedback = Infinity_FetchString(%UI_use_feedback%)\1\2text = string.gsub(text, ":[ ]*%^0x%w%w%w%w%w%w%w%w%" .. UI_use_marker .. "[%w%p ]*", ": ^0xffbed7d7" .. UI_use_feedback)\1\2\3~ END ELSE BEGIN SPRINT UI_use_marker "%input_marker%" REPLACE_TEXTUALLY ~\([%LNL%%MNL%%WNL%]\)\([ %TAB%]*\)\(temptext\)~ ~\1\2local UI_use_feedback = Infinity_FetchString(%UI_use_feedback%)\1\2text = string.gsub(text, ":[%w%p ]*%UI_use_marker%[%w%p ]*", ": ^0xffbed7d7" .. UI_use_feedback)\1\2\3~ END END // Remove tempstring REPLACE_TEXTUALLY "[%LNL%%MNL%%WNL%][ %TAB%]*temptext" "" // Record entire function as string %removespellmessage% READ_ASCII 0 removespellmessage (BUFFER_LENGTH) DEFINE_PATCH_MACRO "UI_SUBSTITUTE_LIST" BEGIN PATCH_PHP_EACH "HIDE_SPELL_FEEDBACK_MARKER" AS input_feedback => input_marker BEGIN // Interpret %input_marker% and whether it exists in ENGINEST.2da PATCH_IF NOT FILE_CONTAINS_EVALUATED ("ENGINEST.2da" "^%input_marker%[ %TAB%]+\(0x\)?[0-9]+") BEGIN REPLACE_TEXTUALLY ~\([%LNL%%MNL%%WNL%]\)\([ %TAB%]*\)\(temptext\)~ ~\1\2text = string.gsub(text, "%input_marker%", "")\1\2\3~ END END // Remove tempstring REPLACE_TEXTUALLY "[%LNL%%MNL%%WNL%][ %TAB%]*temptext" "" END // Remove markers in spell name when viewing mage book <<<<<<<< .../%MOD_FOLDER%-Inlined/ReplaceMageSpellHeader.menu function replacemagespellheader() local text = Infinity_FetchString( bookSpells[rowNumber].name) temptext return text end >>>>>>>> COPY - ".../%MOD_FOLDER%-Inlined/ReplaceMageSpellHeader.menu" "" LAUNCH_PATCH_MACRO "UI_SUBSTITUTE_LIST" // replace "temptext" with generated list of string.gsub() function calls READ_ASCII 0 replacemagespellheader (BUFFER_LENGTH) // Remove markers in spell name when viewing priest scroll <<<<<<<< .../%MOD_FOLDER%-Inlined/ReplacePriestSpellHeader.menu function replacepriestspellheader() local text = Infinity_FetchString( characters[id].priestSpells[currentSpellLevel][rowNumber].name) temptext return text end >>>>>>>> COPY - ".../%MOD_FOLDER%-Inlined/ReplacePriestSpellHeader.menu" "" LAUNCH_PATCH_MACRO "UI_SUBSTITUTE_LIST" // replace "temptext" with generated list of string.gsub() function calls READ_ASCII 0 replacepriestspellheader (BUFFER_LENGTH) // Remove markers in spell name during character generation choose spells <<<<<<<< .../%MOD_FOLDER%-Inlined/ReplaceCharGenChooseSpells.menu function replacechargenchoosespells() local text = Infinity_FetchString(spellBook[chargen.currentSpellLevelChoice][chargen.choose_spell[rowNumber].key].name) temptext return text end >>>>>>>> COPY - ".../%MOD_FOLDER%-Inlined/ReplaceCharGenChooseSpells.menu" "" LAUNCH_PATCH_MACRO "UI_SUBSTITUTE_LIST" // replace "temptext" with generated list of string.gsub() function calls READ_ASCII 0 replacechargenchoosespells (BUFFER_LENGTH) // Remove markers in spell name during character generation memorize mage spells <<<<<<<< .../%MOD_FOLDER%-Inlined/ReplaceCharGenMemorizeMage.menu function replacechargenmemorizemage() local text = Infinity_FetchString(mageSpells[chargen.currentSpellLevelChoice][chargen.choose_spell[rowNumber].key].name) temptext return text end >>>>>>>> COPY - ".../%MOD_FOLDER%-Inlined/ReplaceCharGenMemorizeMage.menu" "" LAUNCH_PATCH_MACRO "UI_SUBSTITUTE_LIST" // replace "temptext" with generated list of string.gsub() function calls READ_ASCII 0 replacechargenmemorizemage (BUFFER_LENGTH) // Remove markers in spell name during character generation memorize priest spells <<<<<<<< .../%MOD_FOLDER%-Inlined/ReplaceCharGenMemorizePriest.menu function replacechargenmemorizepriest() local text = Infinity_FetchString(priestSpells[chargen.currentSpellLevelChoice][chargen.choose_spell[rowNumber].key].name) temptext return text end >>>>>>>> COPY - ".../%MOD_FOLDER%-Inlined/ReplaceCharGenMemorizePriest.menu" "" LAUNCH_PATCH_MACRO "UI_SUBSTITUTE_LIST" // replace "temptext" with generated list of string.gsub() function calls READ_ASCII 0 replacechargenmemorizepriest (BUFFER_LENGTH) // Remove markers in spell name during character generation information <<<<<<<< .../%MOD_FOLDER%-Inlined/ReplaceCharGenInformation.menu function replacechargeninformation() local text = chargen.information temptext return text end >>>>>>>> COPY - ".../%MOD_FOLDER%-Inlined/ReplaceCharGenInformation.menu" "" LAUNCH_PATCH_MACRO "UI_SUBSTITUTE_LIST" // replace "temptext" with generated list of string.gsub() function calls READ_ASCII 0 replacechargeninformation (BUFFER_LENGTH) // Remove markers in spell name when tooltip hovering <<<<<<<< .../%MOD_FOLDER%-Inlined/RemoveTooltipMarker.menu function removetooltipmarker(num) local text = actionBarTooltip[num] temptext return text end >>>>>>>> COPY - ".../%MOD_FOLDER%-Inlined/RemoveTooltipMarker.menu" "" LAUNCH_PATCH_MACRO "UI_SUBSTITUTE_LIST" // replace "temptext" with generated list of string.gsub() function calls READ_ASCII 0 removetooltipmarker (BUFFER_LENGTH) // Remove markers in spell name when viewing ability description <<<<<<<< .../%MOD_FOLDER%-Inlined/RemoveAbilityNameMarker.menu function removeabilitynamemarker() local text = Infinity_FetchString(PopupDetails.name) temptext return text end >>>>>>>> COPY - ".../%MOD_FOLDER%-Inlined/RemoveAbilityNameMarker.menu" "" LAUNCH_PATCH_MACRO "UI_SUBSTITUTE_LIST" // replace "temptext" with generated list of string.gsub() function calls READ_ASCII 0 removeabilitynamemarker (BUFFER_LENGTH) // Insert function "RemoveSpellMessage" above "menu { name 'WORLD_MESSAGES'" COPY_EXISTING "UI.menu" "override" // Insert new UI block before "menu { name 'WORLD_MESSAGES'" LPF "INSERT_UI_BLOCK" STR_VAR new_block = EVAL "%removespellmessage%" find_block = EVAL "[ %TAB%%LNL%%MNL%%WNL%]`[ %TAB%%LNL%%MNL%%WNL%]*menu[ %TAB%%LNL%%MNL%%WNL%]*{[ %TAB%%LNL%%MNL%%WNL%]*name[ %TAB%]+'WORLD_MESSAGES'" RET added_ui_block END PATCH_IF added_ui_block = 1 BEGIN // if function was successfully added // Remove spell message in dialogue window/combat log REPLACE_TEXTUALLY ~\(name "worldMessageBox"[^{}]+\)\([%LNL%%MNL%%WNL%][ %TAB%]*\)\(text lua "worldMessageBoxText"\)~ ~\1\2\3\2text lua "removespellmessage()"~ // Remove added strings in mage book REPLACE_TEXTUALLY EXACT_MATCH ~text lua "Infinity_FetchString( bookSpells[rowNumber].name)"~ ~text lua "replacemagespellheader()"~ LPF "INSERT_UI_BLOCK" STR_VAR new_block = EVAL "%replacemagespellheader%" find_block = EVAL "function refreshMageBook()" END // Remove added strings in priest scroll REPLACE_TEXTUALLY EXACT_MATCH ~text lua "Infinity_FetchString( characters[id].priestSpells[currentSpellLevel][rowNumber].name)"~ ~text lua "replacepriestspellheader()"~ LPF "INSERT_UI_BLOCK" STR_VAR new_block = EVAL "%replacepriestspellheader%" find_block = EVAL "function refreshPriestBook()" END // Remove added strings in character generation choose spells REPLACE_TEXTUALLY EXACT_MATCH ~text lua "Infinity_FetchString(spellBook[chargen.currentSpellLevelChoice][chargen.choose_spell[rowNumber].key].name)"~ ~text lua "replacechargenchoosespells()"~ LPF "INSERT_UI_BLOCK" STR_VAR new_block = EVAL "%replacechargenchoosespells%" find_block = EVAL "`[ %TAB%%LNL%%MNL%%WNL%]*menu[ %TAB%%LNL%%MNL%%WNL%]*{[ %TAB%%LNL%%MNL%%WNL%]*name[ %TAB%]+'CHARGEN_CHOOSE_SPELLS'" END // Remove added strings in character generation memorize mage spells REPLACE_TEXTUALLY EXACT_MATCH ~text lua "Infinity_FetchString(mageSpells[chargen.currentSpellLevelChoice][chargen.choose_spell[rowNumber].key].name)"~ ~text lua "replacechargenmemorizemage()"~ LPF "INSERT_UI_BLOCK" STR_VAR new_block = EVAL "%replacechargenmemorizemage%" find_block = EVAL "`[ %TAB%%LNL%%MNL%%WNL%]*menu[ %TAB%%LNL%%MNL%%WNL%]*{[ %TAB%%LNL%%MNL%%WNL%]*name[ %TAB%]+'CHARGEN_MEMORIZE_MAGE'" END // Remove added strings in character generation memorize priest spells REPLACE_TEXTUALLY EXACT_MATCH ~text lua "Infinity_FetchString(priestSpells[chargen.currentSpellLevelChoice][chargen.choose_spell[rowNumber].key].name)"~ ~text lua "replacechargenmemorizepriest()"~ LPF "INSERT_UI_BLOCK" STR_VAR new_block = EVAL "%replacechargenmemorizepriest%" find_block = EVAL "`[ %TAB%%LNL%%MNL%%WNL%]*menu[ %TAB%%LNL%%MNL%%WNL%]*{[ %TAB%%LNL%%MNL%%WNL%]*name[ %TAB%]+'CHARGEN_MEMORIZE_PRIEST'" END // Remove added strings in character generation information REPLACE_TEXTUALLY EXACT_MATCH ~text lua "chargen.information"~ ~text lua "replacechargeninformation()"~ LPF "INSERT_UI_BLOCK" STR_VAR new_block = EVAL "%replacechargeninformation%" find_block = EVAL "`[ %TAB%%LNL%%MNL%%WNL%]*menu[ %TAB%%LNL%%MNL%%WNL%]*{[ %TAB%%LNL%%MNL%%WNL%]*name[ %TAB%]+'CHARGEN'" END // Remove added strings in ability description REPLACE_TEXTUALLY EXACT_MATCH ~text lua "Infinity_FetchString(PopupDetails.name)"~ ~text lua "removeabilitynamemarker()"~ LPF "INSERT_UI_BLOCK" STR_VAR new_block = EVAL "%removeabilitynamemarker%" find_block = EVAL ~`[ %TAB%%LNL%%MNL%%WNL%]*menu[ %TAB%%LNL%%MNL%%WNL%]*{[ %TAB%%LNL%%MNL%%WNL%]*name[ %TAB%]+'MAGE_CONTINGENCY'~ END // Remove added strings in tooltip FOR (button = 0; button < 12; button += 1) BEGIN REPLACE_TEXTUALLY EXACT_MATCH ~tooltip lua "actionBarTooltip[%button%]"~ ~tooltip lua "removetooltipmarker(%button%)"~ END LPF "INSERT_UI_BLOCK" STR_VAR new_block = EVAL "%removetooltipmarker%" find_block = EVAL ~`[ %TAB%%LNL%%MNL%%WNL%]*menu[ %TAB%%LNL%%MNL%%WNL%]*{[ %TAB%%LNL%%MNL%%WNL%]*name[ %TAB%]+"WORLD_ACTIONBAR"~ END END ELSE BEGIN PATCH_FAIL "Unable to patch UI.menu: component aborted" END BUT_ONLY // Pad name of every single spell COPY_EXISTING_REGEXP GLOB "^.+\.spl$" "override" PATCH_IF SOURCE_SIZE > 0x71 BEGIN // Sanity check PATCH_IF LONG_AT 0x8 > 0 AND LONG_AT 0x8 < 1000000 BEGIN // If valid spell name READ_STRREF 0x8 spell_name_text PATCH_IF NOT "%spell_name_text%" STRING_EQUAL_CASE "" AND NOT "%spell_name_text%" STRING_MATCHES_REGEXP "<\(NO TEXT\|Not Available\|Invalid Reference\|Invalid Strref\).*>" = 0 BEGIN // If valid spell name SPRINT pad_spl_name "" // Reset to default value PATCH_PHP_EACH "HIDE_SPELL_FEEDBACK" AS input_conditions => input_feedback BEGIN PATCH_IF VARIABLE_IS_SET $HIDE_SPELL_FEEDBACK_MARKER("%input_feedback%") AND "%pad_spl_name%" STRING_EQUAL_CASE "" BEGIN // Proceed only if corresponding variable is set in $HIDE_SPELL_FEEDBACK_MARKER & %pad_spl_name% is still undetermined // Extract input variables (i.e. %input_resmask% is set to regexp after "resmask:") PATCH_FOR_EACH input_type IN // list of possible inputs resmask idsmask spelltype spelllevel castinggraphics BEGIN PATCH_IF "%input_conditions%" STRING_CONTAINS_REGEXP "%input_type%:[^,; %TAB%%LNL%%MNL%%WNL%]+" = 0 BEGIN INNER_PATCH_SAVE EVAL "input_%input_type%" "%input_conditions%" BEGIN REPLACE_TEXTUALLY "^.*\(%input_type%:\)" "" // clear everything up to and including "resmask:" REPLACE_TEXTUALLY "[,; %TAB%%LNL%%MNL%%WNL%]+.*$" "" // clear everything after input regexp END END ELSE BEGIN SPRINT EVAL "input_%input_type%" ".*" // Set variable input_%input_type% to default value END END // Transform input feedback variable if set to tra entry PATCH_IF "%input_feedback%" STRING_MATCHES_REGEXP "^[@#]?\(0x\)?\([0-9]+\)$" = 0 BEGIN LPF "STRING_TO_TRA" STR_VAR input_string = EVAL "%input_feedback%" RET use_feedback = output_string END END ELSE BEGIN SPRINT use_feedback "%input_feedback%" END // Compare parameters of current spell if it matches SET matching_input = 0 // set to true by default // Check resmask PATCH_IF "%SOURCE_RES%" STRING_MATCHES_REGEXP "%input_resmask%" = 1 BEGIN // If regexp is not matching SET matching_input = 1 // set to false END // Check idsmask (if spell is SPPR/SPWI/SPIN/SPCL...) & is set PATCH_IF "%input_idsmask%" STRING_COMPARE_CASE ".*" = 1 AND matching_input = 0 BEGIN PATCH_IF "%SOURCE_RES%" STRING_MATCHES_REGEXP "^SP\(PR\|WI\|IN\|CL\)[0-9][0-9][0-9]$" = 0 BEGIN INNER_PATCH_SAVE ids_num "%SOURCE_RES%" BEGIN REPLACE_TEXTUALLY "SPPR" "1" REPLACE_TEXTUALLY "SPWI" "2" REPLACE_TEXTUALLY "SPIN" "3" REPLACE_TEXTUALLY "SPCL" "4" END PATCH_IF FILE_CONTAINS_EVALUATED ("SPELL.IDS" "^%ids_num%[ %TAB%]+.+") BEGIN INNER_PATCH_FILE "SPELL.IDS" BEGIN REPLACE_EVALUATE "^%ids_num%[ %TAB%]+\([^ %TAB%%LNL%%MNL%%WNL%]+\)" BEGIN SPRINT read_ids_symbol "%MATCH1%" END "" END PATCH_IF "%read_ids_symbol%" STRING_MATCHES_REGEXP "%input_idsmask%" = 1 BEGIN // If regexp is not matching SET matching_input = 1 // set to false END END ELSE BEGIN SET matching_input = 1 // set to false END END ELSE BEGIN SET matching_input = 1 // set to false END END // Check spell type (i.e. wizard/priest) READ_SHORT 0x1c read_spelltype PATCH_IF "%read_spelltype%" STRING_MATCHES_REGEXP "%input_spelltype%" = 1 // If regexp is not matching AND matching_input = 0 BEGIN SET matching_input = 1 // set to false END // Check spell level READ_LONG 0x34 read_spelllevel PATCH_IF "%read_spelllevel%" STRING_MATCHES_REGEXP "%input_spelllevel%" = 1 // If regexp is not matching AND matching_input = 0 BEGIN SET matching_input = 1 // set to false END // Check casting graphics READ_SHORT 0x22 read_castinggraphics PATCH_IF "%read_castinggraphics%" STRING_MATCHES_REGEXP "%input_castinggraphics%" = 1 // If regexp is not matching AND matching_input = 0 BEGIN SET matching_input = 1 // set to false END PATCH_IF matching_input = 0 BEGIN // Modify description if spell passed all tests SPRINT pad_spl_name $HIDE_SPELL_FEEDBACK_MARKER("%input_feedback%") INNER_PATCH_SAVE spell_name_text "%spell_name_text%" BEGIN // Pad beginning of spell name INSERT_BYTES 0 (STRING_LENGTH "%pad_spl_name%") WRITE_ASCIIE 0 "%pad_spl_name%" (STRING_LENGTH "%pad_spl_name%") END SAY_EVALUATED 0x8 "%spell_name_text%" END END END END END END BUT_ONLY