Miloch Posted July 25, 2008 Share Posted July 25, 2008 Here is one I just wrote.Eh... ok. So I don't have to continue this project? I did ask whether you wanted just a blank value in missile.ids or a copy of the projectl.ids value (which I think is at least marginally more descriptive than "unnamed" or a blank) and never heard back from you... I should just stop coding for a while and ask for in-built WeiDU functions for everything... Link to comment
the bigg Posted July 25, 2008 Share Posted July 25, 2008 So, I need to run #2 to pad entries in MISSILE, and after that append to both projectil.ids and missile.ids? I can do both things in ADD_PROJECTILE just fine Link to comment
Miloch Posted July 25, 2008 Share Posted July 25, 2008 So, I need to run #2 to pad entries in MISSILE, and after that append to both projectil.ids and missile.ids? I can do both things in ADD_PROJECTILE just fine Sounds good to me. Edit: I'm going to copy Galactygon's other question from SHS here too. No sense in me trying to code a solution if bigg's willing to do it . Because various components use the same projectiles, and I would like to avoid adding a projectile that already exists, how would I determine if that projectile already exists in the PROJECTL.IDS? The other thing about projectiles, how would I assign projectiles based on finding the filename rather than the entry, as variables are lost when the user installs component A, quits, and goes back to install component B?Is there anti-redundancy code in ADD_PROJECTILE that will avoid adding duplicate projectiles? If not, can we add it? Link to comment
Galactygon Posted August 2, 2008 Share Posted August 2, 2008 Here is an update to the "Update missile.ids" macro I've written a week ago. Now it really makes sure that the projectl.ids and missile.ids are shifted by one entry, and accounts for an oversight with 2 hardcoded projectiles introduced in BGII. DEFINE_ACTION_MACRO ~UPDATE_MISSILE_AND_PROJECTL_IDS~ BEGIN COPY_EXISTING ~MISSILE.ids~ ~override~ COUNT_2DA_ROWS 1 missile_rowcount SET missile_rowcount -= 1 READ_2DA_ENTRY missile_rowcount 0 0 last_missile_entry BUT_ONLY_IF_IT_CHANGES COPY_EXISTING ~PROJECTL.ids~ ~override~ COUNT_2DA_ROWS 1 projectl_rowcount SET projectl_rowcount -= 1 READ_2DA_ENTRY projectl_rowcount 0 0 last_projectl_entry BUT_ONLY_IF_IT_CHANGES OUTER_WHILE ( last_projectl_entry < last_missile_entry - 1) BEGIN OUTER_SET last_projectl_entry = last_projectl_entry + 1 APPEND ~PROJECTL.IDS~ ~%last_projectl_entry% ~ END OUTER_WHILE ( last_projectl_entry > last_missile_entry - 1) BEGIN OUTER_SET last_missile_entry = last_missile_entry + 1 APPEND ~MISSILE.IDS~ ~%last_missile_entry% Unnamed~ END END -Galactygon Link to comment
aVENGER_(RR) Posted August 3, 2008 Share Posted August 3, 2008 The other thing about projectiles, how would I assign projectiles based on finding the filename rather than the entry, as variables are lost when the user installs component A, quits, and goes back to install component B? I ran into the same problem while working on RR v4.0 where several components use a new projectile which is added by the first component. Unfortunately, if I install the first component, quit the installer and then try to install another component which uses the new projectile I'll either duplicate the projectile entry (if I add it again) or my spell patching fails since the projectile variable is no longer in the buffer. For the moment, I've made a temporary workaround for this by recording the numeric IDs of all projectiles which I add to a custom 2DA file. I can then use READ_2DA_VALUE to turn this back into a variable and use it for spell patching at a later point. // Add new projectiles ADD_PROJECTILE ~RR/RR_CORE/PRO/RR#VRNP.PRO~ ADD_PROJECTILE ~RR/RR_CORE/PRO/RR#VRPO.PRO~ // Write the numeric projectile IDs to the 2DA so that they can be accessed at any time, for example, if a component which requires these numbers is installed at a later point when they are no longer inside the buffer COPY ~RR/LIB/RR#EVAL.2DA~ ~override~ APPEND ~RR#EVAL.2DA~ ~RR#VRNP %RR#VRNP%~ UNLESS ~RR#VRNP~ APPEND ~RR#EVAL.2DA~ ~RR#VRPO %RR#VRPO%~ UNLESS ~RR#VRPO~ With this, I can acccess the numeric IDs at a later point with relative ease: // Assign the new party-only projectile (RR#VRPO.PRO) to various Bard songs COPY_EXISTING ~RR#EVAL.2DA~ ~override~ READ_2DA_ENTRY 0 1 2 ~RR#VRNP~ // Get the numeric ID of RR#VRNP.PRO from the RR#EVAL.2DA READ_2DA_ENTRY 1 1 2 ~RR#VRPO~ // Get the numeric ID of RR#VRPO.PRO from the RR#EVAL.2DA COPY_EXISTING ~SPCL542A.SPL~ ~override~ // Skald's regular song ~RR#BDF02.SPL~ ~override~ // Default Bard's regular song ~RR#BBL02.SPL~ ~override~ // Blade's regular song READ_LONG 0x64 ab_off READ_SHORT 0x68 ab_num FOR(i=0; i<ab_num; i+=1) BEGIN WRITE_SHORT (ab_off+i*0x28+0x26) %RR#VRPO% END BUT_ONLY_IF_IT_CHANGES // Assign the new no-party projectile (RR#VRNP.PRO) to the regular Jester song and the Weapons Display ability COPY_EXISTING ~SPCL751A.SPL~ ~override~ // Jester's regular song ~RR#WDIS.SPL~ ~override~ // Blade's Weapon's display ability READ_LONG 0x64 ab_off READ_SHORT 0x68 ab_num FOR(i=0; i<ab_num; i+=1) BEGIN WRITE_SHORT (ab_off+i*0x28+0x26) %RR#VRNP% END BUT_ONLY_IF_IT_CHANGES Link to comment
Miloch Posted August 3, 2008 Share Posted August 3, 2008 I'm wondering if that could be done just by reading some unique binary data of your projectile or something. So any word on this (yes/no/maybe)? Is there anti-redundancy code in ADD_PROJECTILE that will avoid adding duplicate projectiles? If not, can we add it? Link to comment
Galactygon Posted August 4, 2008 Share Posted August 4, 2008 I have it easy because all of my components that use projectiles have a REQUIRE_COMPONENT ~0~ @x or something like that, so I can add projectiles in the zeroth component and find them in the other components. Usually I have the spells/items in bundles since the macro does not discard the last projectile_file it looked for unless the user re-sprints it. For spells: // Updating projectiles COPY_EXISTING ~SPPR218.spl~ ~override~ ~SPPR024A.spl~ ~override~ ~SPPR025A.spl~ ~override~ ~SPPR026A.spl~ ~override~ ~SPPR027A.spl~ ~override~ ~SPPR211A.spl~ ~override~ SPRINT projectile_file "LC_TRAV5" LAUNCH_PATCH_MACRO ~ADD_PROJECTILE_FILENAME_SPL~ Or if I want to patch each extended header a new projectile value: COPY_EXISTING ~SPWI614B.spl~ ~override~ SET ext_header_to_patch = 1 SPRINT projectile_file "LC_DFG01" LAUNCH_PATCH_MACRO ~ADD_PROJECTILE_FILENAME_SPL~ SET ext_header_to_patch = 2 SPRINT projectile_file "LC_DFG02" LAUNCH_PATCH_MACRO ~ADD_PROJECTILE_FILENAME_SPL~ ... For items it would be something like this: COPY_EXISTING ~SHAMMR.itm~ ~override~ ~SHAMMR2.itm~ ~override~ ~SHAMMR3.itm~ ~override~ SPRINT projectile_file "LC_TRAV5" LAUNCH_PATCH_MACRO ~ADD_PROJECTILE_FILENAME_ITM~ And here is the full macro. Finding the projectile entry in the projectl.ids can take some time: roughly 20 searches can take 2-3 seconds. So unless I bundle the spells/items, it will slow the installation by several seconds. I am thinking of having the searcher start from row 265 or something rather than 0, and then cycle through the projectl.ids so it's faster. Here is the full macro: // This patch macro adds a projectile to a spell file by looking for the filename of the .pro that is in the // PROJECTL.IDS. You have to specify (more accurately, SPRINTs) the variable "projectile_file" to the desired file, // and set the variable "ext_header_to_patch" to some value 0 or greater. If "ext_header_to_patch" is zero, or you // do not specify "ext_header_to_patch", all extended headers are patched. On the other hand, if you specify // some number like 1 instead to "ext_header_to_patch", it only patches that extended header. For example, setting // "ext_header_to_patch" to 1 beforehand only patches the first extended header. Note that you will have to set // "ext_header_to_patch" each time you run the macro if want to patch only a range of extended headers rather than all of // them. You will also have to set "projectile_file" each time you wish to change between different projectiles. DEFINE_PATCH_MACRO ~ADD_PROJECTILE_FILENAME_SPL~ BEGIN PATCH_IF ((SOURCE_SIZE > 0x71) AND (VARIABLE_IS_SET "%projectile_file%") ) THEN BEGIN // Just in case // If no variable is set by the user, there is no parse error, but instead there is a warning sign, and // this macro takes over and simply sets the projectile index in the specified header(s) to "1-None" PATCH_IF !( VARIABLE_IS_SET "%projectile_file%" ) BEGIN SET projectile_num = 0 SPRINT projectile_name "" PATCH_PRINT "Warning: no projectile filename was specified, so setting projectile index to None" END // If the last projectile is not what we are looking for, we launch this macro to look for it. // We often don't need it if we are copying and patching several spells that use the same projectile. // This radically cuts the installation time. PATCH_IF !( "%projectile_file%" STRING_COMPARE_CASE "%projectile_name%" = 0) BEGIN INNER_ACTION BEGIN LAUNCH_ACTION_MACRO ~GET_PROJECTILE_ENTRY~ END END PATCH_IF !( VARIABLE_IS_SET "%ext_header_to_patch%" ) BEGIN SET ext_header_to_patch = 0 END READ_LONG 0x64 ext_off READ_SHORT 0x68 ext_num FOR (outerloops = 0; outerloops < ext_num; outerloops += 1) BEGIN PATCH_IF ((outerloops + 1 = ext_header_to_patch) OR (ext_header_to_patch = 0)) BEGIN // We don't like redundancy READ_SHORT ( outerloops * 0x28 + ext_off + 0x26 ) to_patch_or_not_to_patch PATCH_IF (to_patch_or_not_to_patch != projectile_num + 1) BEGIN WRITE_SHORT ( outerloops * 0x28 + ext_off + 0x26 ) (projectile_num + 1) END END END SET ext_header_to_patch = 0 END END // This patch macro adds a projectile to an item file by looking for the filename of the .pro that is in the // PROJECTL.IDS. You have to specify (more accurately, SPRINTs) the variable "projectile_file" to the desired file, // and set the variable "ext_ability_to_patch" to some value 0 or greater. If "ext_ability_to_patch" is zero, or you // do not specify "ext_ability_to_patch", all extended abilities are patched. On the other hand, if you specify // some number like 1 instead to "ext_ability_to_patch", it only patches that extended ability. For example, setting // "ext_ability_to_patch" to 1 beforehand only patches the first extended ability. Note that you will have to set // "ext_ability_to_patch" each time you run the macro if want to patch only a range of extended abilities rather than all of // them. You will also have to set "projectile_file" each time you wish to change between different projectiles. DEFINE_PATCH_MACRO ~ADD_PROJECTILE_FILENAME_ITM~ BEGIN PATCH_IF ((SOURCE_SIZE > 0x71) AND (VARIABLE_IS_SET "%projectile_file%") ) THEN BEGIN // Just in case // If no variable is set by the user, there is no parse error, but instead there is a warning sign, and // this macro takes over and simply sets the projectile index in the specified header(s) to "1-None" PATCH_IF !( VARIABLE_IS_SET "%projectile_file%" ) BEGIN SET projectile_num = 0 SPRINT projectile_name "" PATCH_PRINT "Warning: no projectile filename was specified, so setting projectile index to None" END // If the last projectile is not what we are looking for, we launch this macro to look for it. // We often don't need it if we are copying and patching several items that use the same projectile. // This radically cuts the installation time. PATCH_IF !( "%projectile_file%" STRING_COMPARE_CASE "%projectile_name%" = 0) BEGIN INNER_ACTION BEGIN LAUNCH_ACTION_MACRO ~GET_PROJECTILE_ENTRY~ END END PATCH_IF !( VARIABLE_IS_SET "%ext_ability_to_patch%" ) BEGIN SET ext_ability_to_patch = 0 END READ_LONG 0x64 ext_off READ_SHORT 0x68 abil_num FOR (outerloops = 0; outerloops < abil_num; outerloops += 1) BEGIN PATCH_IF ((outerloops + 1 = ext_ability_to_patch) OR (ext_ability_to_patch = 0)) BEGIN // We don't like redundancy READ_SHORT ( outerloops * 0x38 + ext_off + 0x2a ) to_patch_or_not_to_patch PATCH_IF (to_patch_or_not_to_patch != projectile_num + 1) BEGIN WRITE_SHORT ( outerloops * 0x38 + ext_off + 0x2a ) (projectile_num + 1) END END END SET ext_ability_to_patch = 0 END END // This patch macro adds an explosion projectile to a projectile file by looking for the filename of the .pro that is in the // PROJECTL.IDS. You have to specify (more accurately, SPRINTs) the variable "projectile_file" to the desired file, // and set "projectile_file" each time you wish to change between different projectiles. DEFINE_PATCH_MACRO ~ADD_PROJECTILE_EXPLOSION_FILENAME_PRO~ BEGIN PATCH_IF ((SOURCE_SIZE > 0x2ff) AND (VARIABLE_IS_SET "%projectile_file%") ) THEN BEGIN // Just in case. There has to be an explosion for this to work. // If no variable is set by the user, there is no parse error, but instead there is a warning sign, and // this macro takes over and simply sets the projectile index in the specified header(s) to "1-None" PATCH_IF !( VARIABLE_IS_SET "%projectile_file%" ) BEGIN SET projectile_num = 0 SPRINT projectile_name "" PATCH_PRINT "Warning: no projectile filename was specified, so setting projectile index to None" END // If the last projectile is not what we are looking for, we launch this macro to look for it. // We often don't need it if we are copying and patching several items that use the same projectile. // This radically cuts the installation time. PATCH_IF !( "%projectile_file%" STRING_COMPARE_CASE "%projectile_name%" = 0) BEGIN INNER_ACTION BEGIN LAUNCH_ACTION_MACRO ~GET_PROJECTILE_ENTRY~ END END READ_SHORT 0x21a explosion_projectile PATCH_IF (explosion_projectile != projectile_num + 1) BEGIN WRITE_SHORT 0x21a (projectile_num + 1) END END END // This action macro looks for the projectile entry of the projectile "projectile_name".pro, where "projectile_name" is // some variable you SPRINT before launching the action macro. Since looking for projectiles slows down the installation // process, the macro does not reset the variable "projectile_name" each time it is launched unless the coder manually // tells it to reset the variable. If the coder specifies a projectile file not in the PROJECTL.IDS, "projectile_num" // returns a zero. This macro is used in conjunction with the two macros ADD_PROJECTILE_FILENAME_SPL and // ADD_PROJECTILE_FILENAME_ITM. DEFINE_ACTION_MACRO ~GET_PROJECTILE_ENTRY~ BEGIN COPY_EXISTING ~PROJECTL.IDS~ ~override~ COUNT_2DA_ROWS 0 "projectl_rowcount" SET we_are_done = 0 PATCH_IF (!( VARIABLE_IS_SET "%projectile_num%" ) OR !( VARIABLE_IS_SET "%projectile_name%" )) BEGIN SET projectile_num = 0 SPRINT projectile_name "" END PATCH_IF (("%projectile_file%" STRING_COMPARE_CASE "%projectile_name%" = 0) OR ("%projectile_file%" STRING_COMPARE_CASE "" = 0)) BEGIN SET we_are_done = 1 END FOR ( row=1; row<projectl_rowcount AND we_are_done = 0; row+=1 ) BEGIN READ_2DA_ENTRY row 0 2 projectile_num READ_2DA_ENTRY row 1 2 projectile_name PATCH_IF ( "%projectile_file%" STRING_COMPARE_CASE "%projectile_name%" = 0) BEGIN SET we_are_done = 1 END END PATCH_IF ( we_are_done = 0 ) BEGIN SET projectile_num = 0 SPRINT projectile_name "" END BUT_ONLY_IF_IT_CHANGES END -Galactygon Link to comment
Miloch Posted August 13, 2008 Share Posted August 13, 2008 WRITE_SOUNDSET does not appear to work in WeiDU v208. I believe it worked in Gort's library, so I don't know what changed. OUTER_SET overwrite = 0 OUTER_SPRINT npc ~edwin7.cre~ OUTER_SPRINT soundset ~bg2edwin~ LAUNCH_ACTION_MACRO READ_SOUNDSET OUTER_SPRINT npc ~_edwin2.cre~ OUTER_SPRINT soundset ~bg2edwin~ LAUNCH_ACTION_MACRO WRITE_SOUNDSET Generates: ERROR locating resource for 'COPY' Resource [^_edwin2.cre$] not found in KEY file: [./chitin.key] Stopping installation because of error. This is on Tutu, where _edwin2.cre exists obviously. More typos in the documentation too - there are misplaced \item flags around READ_SOUND\item SET etc. Link to comment
Taimon Posted August 13, 2008 Share Posted August 13, 2008 Typos are already fixed. Don't know why the macro uses the REGEXP variant. Can you check if a COPY_EXISTING_REGEXP ~^_edwin2.cre$~ ~override~ works on Tutu? This should be case insensitive, but also try uppercased if it fails. Link to comment
Miloch Posted August 13, 2008 Share Posted August 13, 2008 Don't know why the macro uses the REGEXP variant.I don't know either, and I just noticed that was in Gort's code too. It should almost certainly be just COPY_EXISTING ~%npc%~ ~override~.Can you check if a COPY_EXISTING_REGEXP ~^_edwin2.cre$~ ~override~ works on Tutu?It does not. Since all the Tutu resources are already in the override, GLOB would have to be enabled (and should've been anyway if you were doing a real regexp copy like this, but unnecessary in this case). While you're at it, you might want to put ELSEs between the PATCH_IFs in WRITE_SOUNDSET, since they are all mutually exclusive based on the value of %overwrite%. Might improve runtime by a trifling amount. Link to comment
Galactygon Posted August 16, 2008 Share Posted August 16, 2008 I have improved Gort's ADD_ITEM_EFFECT and ADD_SPELL_EFFECT macros, and unified them. Here are the imrovements: 1.) The macro is called ~ADD_EFFECT_EXTENDED_HEADER~, and may be used to patch both items and spells alike. 2.) You do not need to set variables before launching the macro, and they are remembered from the last use. The variables are automatically set to 0, except for probability1 which is set to 100. This kept bothering me, and it is more of a safety check than a new feature. 3.) The macro doesn't have to add the effect as the last effect in the header. This is crucial in places where opcode 206 is used to protect against cumulative effects. This can be set using a new variable called "index". Not setting "index", setting "index" to 0 or some value that is greater than the number of effects will simply add the new effect as the last effect. Setting "index" to some valid value will insert the effect between existing effects, bumping them by one when necessary. For example, if you set "index" to 1, this macro make sure the new effect is triggered first. For example, this piece of code would add Opcode #146 (Cast spell on creature), target self, timing mode permanent, etc. to STAF10.itm. The "header" variable is set to 2, and the "index" variable is set to 1, so it will add the effect as the first effect of the second extended header/ability (assuming the second header exists). COPY_EXISTING ~STAF10.itm~ ~override~ SET opcode = 146 SET target = 1 SET timing = 1 SET parameter1 = 1 SET parameter2 = 1 SPRINT resource ~CAS01~ SET header = 2 SET index = 1 LAUNCH_PATCH_MACRO ~ADD_EFFECT_EXTENDED_HEADER~ BUT_ONLY_IF_IT_CHANGES And below is the full macro. The formatting looks odd because the forum code cuts off the end of long lines, so you might have to copy and paste them in order to read what's happening -Galactygon // For any generic spell or item DEFINE_PATCH_MACRO ~ADD_EFFECT_EXTENDED_HEADER~ BEGIN PATCH_IF (SOURCE_SIZE > 0x71 AND ( "%SOURCE_FILE%" STRING_MATCHES_REGEXP "^.+\.itm" = 0 OR "%SOURCE_FILE%" STRING_MATCHES_REGEXP "^.+\.spl" = 0 ) ) THEN BEGIN // Just in case PATCH_IF ("%SOURCE_FILE%" STRING_MATCHES_REGEXP "^.+\.itm" = 0) BEGIN SET ___#header_size = 0x38 END ELSE PATCH_IF ("%SOURCE_FILE%" STRING_MATCHES_REGEXP "^.+\.spl" = 0) BEGIN SET ___#header_size = 0x28 END PATCH_IF !(VARIABLE_IS_SET "%header%") BEGIN SET header = 0 END PATCH_IF !(VARIABLE_IS_SET "%index%") BEGIN SET index = 0 END PATCH_IF !(VARIABLE_IS_SET "%opcode%") BEGIN SET opcode = 0 END PATCH_IF !(VARIABLE_IS_SET "%target%") BEGIN SET target = 0 END PATCH_IF !(VARIABLE_IS_SET "%timing%") BEGIN SET timing = 0 END PATCH_IF !(VARIABLE_IS_SET "%resist_dispel%") BEGIN SET resist_dispel = 0 END PATCH_IF !(VARIABLE_IS_SET "%power%") BEGIN SET power = 0 END PATCH_IF !(VARIABLE_IS_SET "%parameter1%") BEGIN SET parameter1 = 0 END PATCH_IF !(VARIABLE_IS_SET "%parameter2%") BEGIN SET parameter2 = 0 END PATCH_IF !(VARIABLE_IS_SET "%duration%") BEGIN SET duration = 0 END PATCH_IF !(VARIABLE_IS_SET "%probability1%") BEGIN SET probability1 = 100 END PATCH_IF !(VARIABLE_IS_SET "%probability2%") BEGIN SET probability2 = 0 END PATCH_IF !(VARIABLE_IS_SET "%resource%") BEGIN SPRINT resource "" END PATCH_IF !(VARIABLE_IS_SET "%dicenumber%") BEGIN SET dicenumber = 0 END PATCH_IF !(VARIABLE_IS_SET "%dicesize%") BEGIN SET dicesize = 0 END PATCH_IF !(VARIABLE_IS_SET "%savingthrow%") BEGIN SET savingthrow = 0 END PATCH_IF !(VARIABLE_IS_SET "%savebonus%") BEGIN SET savebonus = 0 END READ_LONG 0x64 ___#abil_off READ_SHORT 0x68 ___#abil_num READ_LONG 0x6a ___#fx_off FOR (___#index1 = 0; ___#index1 < ___#abil_num; ___#index1 += 1) BEGIN PATCH_IF (___#index1 = (header - 1)) OR (header = 0) BEGIN //header=1 means ___#index1=0 READ_SHORT (___#abil_off + 0x1e + (___#header_size * ___#index1)) ___#abil_fx_num READ_SHORT (___#abil_off + 0x20 + (___#header_size * ___#index1)) ___#abil_fx_idx WRITE_SHORT (___#abil_off + 0x1e + (___#header_size * ___#index1)) (___#abil_fx_num + 1) FOR (___#index2 = 0; ___#index2 < ___#abil_num; ___#index2 += 1) BEGIN READ_SHORT (___#abil_off + ___#index2 * ___#header_size + 0x20) ___#1effect_index PATCH_IF (___#1effect_index > ___#abil_fx_idx) BEGIN //if ability after current effect WRITE_SHORT (___#index2 * ___#header_size + ___#abil_off + 0x20) (___#1effect_index + 1) //increase 1 effect ___#index1 by 1 END END //no offsets to correct SET ___#tot_off = (___#fx_off + (___#abil_fx_num + ___#abil_fx_idx) * 0x30) INSERT_BYTES (___#tot_off) 0x30 PATCH_IF ( index = 0 OR index > ___#abil_fx_num + 1 ) THEN BEGIN SET ___#write_off = ___#tot_off END ELSE BEGIN SET ___#write_off = (___#fx_off + (index - 1 + ___#abil_fx_idx) * 0x30) FOR (___#index3 = ___#abil_fx_num; ___#index3 > index - 1; ___#index3 -= 1) BEGIN SET ___#old_off = (___#fx_off + (___#index3 - 1 + ___#abil_fx_idx) * 0x30) SET ___#new_off = (___#fx_off + (___#index3 + ___#abil_fx_idx) * 0x30) READ_SHORT (___#old_off) ___#opcode READ_BYTE (___#old_off + 0x02) ___#target READ_BYTE (___#old_off + 0x03) ___#power READ_LONG (___#old_off + 0x04) ___#parameter1 READ_LONG (___#old_off + 0x08) ___#parameter2 READ_BYTE (___#old_off + 0x0c) ___#timing READ_BYTE (___#old_off + 0x0d) ___#resist_dispel READ_LONG (___#old_off + 0x0e) ___#duration READ_BYTE (___#old_off + 0x12) ___#probability1 READ_BYTE (___#old_off + 0x13) ___#probability2 READ_ASCII (___#old_off + 0x14) ___#resource READ_LONG (___#old_off + 0x1c) ___#dicenumber READ_LONG (___#old_off + 0x20) ___#dicesize READ_LONG (___#old_off + 0x24) ___#savingthrow READ_LONG (___#old_off + 0x28) ___#savebonus WRITE_SHORT (___#new_off) ___#opcode WRITE_BYTE (___#new_off + 0x02) ___#target WRITE_BYTE (___#new_off + 0x03) ___#power WRITE_LONG (___#new_off + 0x04) ___#parameter1 WRITE_LONG (___#new_off + 0x08) ___#parameter2 WRITE_BYTE (___#new_off + 0x0c) ___#timing WRITE_BYTE (___#new_off + 0x0d) ___#resist_dispel WRITE_LONG (___#new_off + 0x0e) ___#duration WRITE_BYTE (___#new_off + 0x12) ___#probability1 WRITE_BYTE (___#new_off + 0x13) ___#probability2 WRITE_EVALUATED_ASCII (___#new_off + 0x14) "%___#resource%" (8) WRITE_LONG (___#new_off + 0x1c) ___#dicenumber WRITE_LONG (___#new_off + 0x20) ___#dicesize WRITE_LONG (___#new_off + 0x24) ___#savingthrow WRITE_LONG (___#new_off + 0x28) ___#savebonus END END WRITE_SHORT (___#write_off) opcode WRITE_BYTE (___#write_off + 0x02) target WRITE_BYTE (___#write_off + 0x03) power WRITE_LONG (___#write_off + 0x04) parameter1 WRITE_LONG (___#write_off + 0x08) parameter2 WRITE_BYTE (___#write_off + 0x0c) timing WRITE_BYTE (___#write_off + 0x0d) resist_dispel WRITE_LONG (___#write_off + 0x0e) duration WRITE_BYTE (___#write_off + 0x12) probability1 WRITE_BYTE (___#write_off + 0x13) probability2 WRITE_EVALUATED_ASCII (___#write_off + 0x14) ~%resource%~ (8) WRITE_LONG (___#write_off + 0x1c) dicenumber WRITE_LONG (___#write_off + 0x20) dicesize WRITE_LONG (___#write_off + 0x24) savingthrow WRITE_LONG (___#write_off + 0x28) savebonus END END END END Link to comment
Miloch Posted August 17, 2008 Share Posted August 17, 2008 I think you will need to invert your logic on the SPL/ITM check as discussed here (or better yet, use the newer SOURCE_EXT syntax). Link to comment
Taimon Posted August 17, 2008 Share Posted August 17, 2008 He explicitly checks for = 0 so his code is correct, I think. Link to comment
Galactygon Posted August 17, 2008 Share Posted August 17, 2008 Yes, I have confirmed it works for items and spells alike. The only limitations are it cannot patch casting feature blocks or equipped effects, and it can take a second or two to bump effects if they are in the hundreds (which is mainly something I have to deal with). Feel free to replace STRING_MATCHES_REGEXP with SOURCE_EXT. -Galactygon Link to comment
plainab Posted August 18, 2008 Share Posted August 18, 2008 I have created some patch code where after a list of SET's I can add a new ability header. For a single purpose I could just replace the variables with exact values and be done with it. But I'd like to turn it into a patch_macro for my use and the use of others. What else is needed to turn this into a macro? Do I need to make a bunch of null/zeroed LOCAL_SET's in case someone doesn't need to use a certain variable? Anything else I need to know? Has someone already done this? I assume that in the macro section of the tp2 I would put: DEFINE_PATCH_MACRO ~ADD_ABILITY_HEADER~ BEGIN my patches END and in the component section of the tp2 I would put my list of: SET variable = x LAUNCH_PATCH_MACRO ~ADD_ABILITY_HEADER~ Here is the current patch code: READ_LONG 0x64 ~abil_loc~ READ_SHORT 0x68 ~abil_num~ READ_SHORT 0x6a ~fx_loc~ SET abil_size = 56 SET new_abil_loc = (%abil_loc% +(%abil_num% *%abil_size)) //sets new header at end of existing header list if any SET new_fx_loc = (%fx_loc% + %abil_size%) //increases effects location by ability size INSERT_BYTES %new_abil_loc% %abil_size% //insert enough bytes for one ability at new location WRITE_SHORT 0x68 (%abil_num% + 1) //update number of headers in file WRITE_LONG 0x6a (%new_fx_loc%) //update effects location in file WRITE_BYTE (%new_abil_loc% + 0x0) ~%attack_type%~ // attack type WRITE_BYTE (%new_abil_loc% + 0x1) ~%id_req%~ // id required 0-yes 1-no WRITE_BYTE (%new_abil_loc% + 0x2) ~%use_location%~ // use location -- followed by a 3 byte unknown WRITE_EVALUATED_ASCII (%new_abil_loc% + 0x4) ~%use_icon%~ // use icon WRITE_BYTE (%new_abil_loc% + 0xc) ~%target_type%~ // type of target WRITE_BYTE (%new_abil_loc% + 0xd) ~%target_count%~ // target count WRITE_SHORT (%new_abil_loc% + 0xe) ~%range%~ // range WRITE_BYTE (%new_abil_loc% + 0x10) ~%proj_type%~ // projectile type WRITE_BYTE (%new_abil_loc% + 0x12) ~%speed%~ // speed WRITE_BYTE (%new_abil_loc% + 0x14) ~%thac0_bonus%~ // THAC0 bonus WRITE_BYTE (%new_abil_loc% + 0x16) ~%d_sides%~ // dice sides WRITE_SHORT (%new_abil_loc% + 0x18) ~%d_rolls%~ // dice rolls WRITE_SHORT (%new_abil_loc% + 0x1a) ~%damage_bonus%~ // damage_bonus WRITE_SHORT (%new_abil_loc% + 0x1c) ~%damage_type%~ // damage type WRITE_SHORT (%new_abil_loc% + 0x22) ~%charges%~ // charges WRITE_SHORT (%new_abil_loc% + 0x24) ~%charge_removal%~ // charge removal WRITE_SHORT (%new_abil_loc% + 0x26) ~%flag%~ // flag -- followed by a 2 byte unknown WRITE_SHORT (%new_abil_loc% + 0x2a) ~%proj_anim%~ // projectile animation WRITE_SHORT (%new_abil_loc% + 0x2c) ~%overhand%~ // overhand WRITE_SHORT (%new_abil_loc% + 0x2e) ~%backhand%~ // backhand WRITE_SHORT (%new_abil_loc% + 0x30) ~%thrust%~ // thrust WRITE_SHORT (%new_abil_loc% + 0x32) ~%bow%~ // bow WRITE_SHORT (%new_abil_loc% + 0x34) ~%xbow%~ // crossbow WRITE_SHORT (%new_abil_loc% + 0x36) ~%sling%~ // sling The reason I wanted to do this is that I am going to use Weidu's newly included ADD_ITEM_EFFECT macro from Gort, but the item I'm using doesn't have an ability header to begin with. Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.