Mike1072 Posted August 25, 2015 Share Posted August 25, 2015 I need to remove all flags from a single .spl. I think I can use WRITE_SHORT 0x18 0 to do so, since without any bits/bytes set, 0 is what it should add up too. My question is if I had to set flag 11 and flag 8 (the numbers are what they are called in NI, since these flags are presented as a byte/bit table in the IESDP I suspect they are identified differently.), what would I input in place of 0 in the code I wrote above? Is this another case of adding bytes and bits? 2^11+2^8 expressed in binary. Weidu supports bit shifting, so it can do the work for you with left shift and bitwise oring (something like 1 WeiDU even has variables defined for all of the bits. You can use (BIT11 | BIT8) if you like. Thank you Mike, that visual aid helped me a lot, as did Jarno's explanation of what he meant by +0 to the sum. Say you wish to know what the .spl file's second extended headers has at the offset 0x0000, it's not the spells offset zero, but the offset after the header(lenght of which is 0x072 bits) and the first extended header(lenght of which is 0x0028 bits) aka you are looking for the bit at offset 0x72+0x28, which is 0x9a or 154. But then, for what réver reason you wish to know what the headers has at offset 0x0000, then you are looking at files the offset zero. Just to be clear, the abilities don't have to come directly after the header. Sometimes the effects come before the abilities. To determine where abilities or effects start, you should always read the value from abilities_off (0x64) or effects_off (0x6a). Likewise, the global effects usually come before the feature blocks in the group of effects, but they don't have to. That is why there is an effects_ind (0x6e), so you'll know where they begin. Link to comment
JediMindTrix Posted August 26, 2015 Author Share Posted August 26, 2015 Would this do the job? WRITE_SHORT 0x18 BIT3 //Displayable Flag or does BIT3 need to be in paranthesis? Link to comment
Mike1072 Posted August 26, 2015 Share Posted August 26, 2015 That should work fine. Parentheses aren't strictly necessary even in the other example, but they help clarity there. Link to comment
JediMindTrix Posted August 27, 2015 Author Share Posted August 27, 2015 Does that act as a switch? So if bit3 is already set having Weidu set it again will turn it off? Link to comment
Mike1072 Posted August 27, 2015 Share Posted August 27, 2015 No. What that code does is set that bit to 1 and every other bit to 0. Repeating the procedure will have no effect. If your goal is to change only the value of that one bit and not any of the others, you need to use different code. WRITE_SHORT 0x18 (THIS | BIT3) Link to comment
subtledoctor Posted August 27, 2015 Share Posted August 27, 2015 If your goal is to change only the value of that one bit and not any of the others, you need to use different code. WRITE_SHORT 0x18 (THIS | BIT3) For my own benefit, if I'm reading that right, is | equal to BOR? Do you not have to define THIS first? (With "READ_SHORT 0x18 THIS") If not, does that mean I can contract COPY_EXISTING ~whatever.itm/cre/spl~ READ_SHORT 0x18 this WRITE_SHORT 0x18 (this BOR 0x00100000)to just COPY_EXISTING ~whatever.itm/cre/spl~ WRITE_SHORT 0x18 (this | BIT3)? Even assuming the READ is still necessary, that sure is prettier. Link to comment
Mike1072 Posted August 27, 2015 Share Posted August 27, 2015 For my own benefit, if I'm reading that right, is | equal to BOR? Yes. Check the WeiDU readme under the primary name (BOR) to find information on synonyms. THIS is a special variable. Whenever a WRITE_ is performed, a READ_ happens in the background, assigning the original value to the variable THIS. THIS is not the same as this. Link to comment
JediMindTrix Posted August 27, 2015 Author Share Posted August 27, 2015 Harking back to the header related questions, In order to create a header from scratch, would I first need to use ADD_ITEM_EFFECT (or CLONE_EFFECT) to create a new header, then use WRITE_xyz to set the various variables inside of the newly created header? For example: //Now we create a header where there was none before LPF ADD_ITEM_EFFECT INT_VAR header = 1 type = 0 opcode = ..... ...WRITE_BYTE 0x73 1 ///Identify To Use Additionally, do the BIT3/BIT4/BIT5, etc, work when called inside of an ADD_x_EFFECT command? Such as the one below: LPF ADD_ITEM_EFFECT //Level drain INT_VAR header = 1 type = 0 opcode = 216 target = 2 power = 1 parameter1 = 2 timing = 9 resist_dispel = 2 probability1 = 100 savingthrow = BIT0 END How would I set one to no saving throw? Just... savingthrow = 0? Link to comment
Mike1072 Posted August 27, 2015 Share Posted August 27, 2015 ADD_ITEM_EFFECT creates effects, not ability headers, and I don't think there is a built-in function to create an ability header (though there are some that modify and delete them).What exactly are you trying to do? Additionally, do the BIT3/BIT4/BIT5, etc, work when called inside of an ADD_x_EFFECT command? Such as the one below: LPF ADD_ITEM_EFFECT //Level drain INT_VAR header = 1 type = 0 opcode = 216 target = 2 power = 1 parameter1 = 2 timing = 9 resist_dispel = 2 probability1 = 100 savingthrow = BIT0 END Yes. When assigning INT_VAR variables, you can provide anything that is a value. Lots of things are values. 0 is a value. BIT0 is a variable, which is a value. (BIT0 + 10) is a value. (~%SOURCE_RES%~ STRING_EQUAL_CASE ~arow01~ ? 10 : 20) is a value. How would I set one to no saving throw? Just... savingthrow = 0? Yes. Link to comment
JediMindTrix Posted August 27, 2015 Author Share Posted August 27, 2015 Again, thanks for answering my questions. Saving Throw can have more than one type/flag selected so I believe the optimal choice for ease of coding would be to use BIT1 | BIT 2 in those cases. I am trying to use WeidU to patch an Item Ability (usable, not an on-equip) on an amulet that in vanilla BG does not have one. EDIT: The IESDP mentions 1 char as a type of information. Are these edited via WRITE_ASCII? Link to comment
Mike1072 Posted August 27, 2015 Share Posted August 27, 2015 I am trying to use WeidU to patch an Item Ability (usable, not an on-equip) on an amulet that in vanilla BG does not have one. I think you may need a function to add an ability header. I found some function that Ardanis added to Item Revisions. I have no idea what it does (it seems to either create or clone headers), but you're free to give it a try. DEFINE_PATCH_FUNCTION ~ADD_ITEM_HEADER~ INT_VAR type=3 required_id=0 location=3 alt_dicesize=0 target=1 target_count=0 range=0 projectile_type=0 alt_dicenumber=0 speed=0 alt_damage=0 thaco=0 dicesize=0 school=0 dicenumber=0 sectype=0 damage=0 damage_type=0 charges=0 depletion=0 flags=0 projectile=1 overhand=0 backhand=0 thrust=0 is_bow=0 is_xbow=0 is_sling=0 copy_header=0 insert_point=~-1~ STR_VAR icon=~~ RET insert_point BEGIN LPF ~FJ_SPL_ITM_REINDEX~ END hs=0x38 READ_LONG 0x64 ho READ_SHORT 0x68 hc READ_LONG 0x6a eo insert_point = (insert_point>hc || insert_point<0) ? hc : insert_point copy_header = (copy_header<0) ? 0 : copy_header PATCH_IF copy_header>hc BEGIN PATCH_WARN ~Unable to copy %copy_header%th header, %SOURCE_FILE% contains only %hc% headers!~ END ELSE BEGIN INSERT_BYTES ho+insert_point*hs hs hc+=1 eo+=hs PATCH_IF copy_header BEGIN READ_SHORT ho+(copy_header - 1)*hs+0x1e ec READ_SHORT ho+(copy_header - 1)*hs+0x20 ei READ_ASCII eo+ei*0x30 effs (ec*0x30) READ_ASCII ho+(copy_header - 1)*hs copy (hs) WRITE_ASCIIE ho+insert_point*hs ~%copy%~ (hs) END WRITE_SHORT 0x68 hc WRITE_LONG 0x6a eo READ_SHORT 0x70 ei // technically, it is a counter FOR (i=ho;i<ho+hc*hs;i+=hs) BEGIN READ_SHORT i+0x1e ec WRITE_SHORT i+0x20 ei ei+=ec END PATCH_IF copy_header BEGIN READ_SHORT ho+insert_point*hs+0x1e ec READ_SHORT ho+insert_point*hs+0x20 ei INSERT_BYTES eo+ei*0x30 ec*0x30 WRITE_ASCIIE eo+ei*0x30 ~%effs%~ (ec*0x30) END ELSE BEGIN off=ho+insert_point*hs WRITE_BYTE off type WRITE_BYTE off+0x1 required_id WRITE_BYTE off+0x2 location WRITE_BYTE off+0x3 alt_dicesize WRITE_ASCIIE off+0x4 ~%icon%~ (8) WRITE_BYTE off+0xc target WRITE_BYTE off+0xd target_count WRITE_SHORT off+0xe range WRITE_BYTE off+0x10 projectile_type WRITE_BYTE off+0x11 alt_dicenumber WRITE_BYTE off+0x12 speed WRITE_BYTE off+0x13 alt_damage WRITE_SHORT off+0x14 thaco WRITE_BYTE off+0x16 dicesize WRITE_BYTE off+0x17 school WRITE_BYTE off+0x18 dicenumber WRITE_BYTE off+0x19 sectype WRITE_SHORT off+0x1a damage WRITE_SHORT off+0x1c damage_type WRITE_SHORT off+0x22 charges WRITE_SHORT off+0x24 depletion WRITE_LONG off+0x26 flags WRITE_SHORT off+0x2a projectile WRITE_SHORT off+0x2c overhand WRITE_SHORT off+0x2e backhand WRITE_SHORT off+0x30 thrust WRITE_SHORT off+0x32 is_bow WRITE_SHORT off+0x34 is_xbow WRITE_SHORT off+0x36 is_sling END END END Oh, and it requires this function, too. // found by Ardanis in Rogue Rebalancing, had apparently been written by Nythrun // fixed two things, wrapped a function over it DEFINE_PATCH_FUNCTION ~FJ_SPL_ITM_REINDEX~ BEGIN PATCH_IF !(~%SOURCE_FILE%~ STRING_MATCHES_REGEXP ~^.+\.spl~) BEGIN hs = 0x28 WRITE_LONG 0xc ~-1~ //Identified name WRITE_LONG 0x54 ~-1~ //Identified description PATCH_FOR_EACH tz IN 0x44 0x48 0x58 0x5c BEGIN WRITE_LONG tz 0 END END ELSE PATCH_IF !(~%SOURCE_FILE%~ STRING_MATCHES_REGEXP ~^.+\.itm~) BEGIN hs = 0x38 END READ_LONG 0x64 hf //Extended header offset READ_SHORT 0x68 hc //Extended header count READ_LONG 0x6a fb //Feature block table offset READ_SHORT 0x70 fc //Feature block count PATCH_IF ((hf > fb) AND (hc > 0)) BEGIN // Ardanis: fixed "hc > 1" to "hc > 0" READ_ASCII hf ~eh~ ELSE ~fail~ (hs * hc) PATCH_IF (~%eh%~ STRING_EQUAL ~fail~) BEGIN WHILE ((~%eh%~ STRING_EQUAL ~fail~) AND (hc > 0)) BEGIN READ_ASCII hf ~eh~ ELSE ~fail~ (hs * hc) hc -= 1 END END DELETE_BYTES hf (hs * hc) hf = 0x72 WRITE_LONG 0x64 hf WRITE_SHORT 0x68 hc fb = (0x72 + (hs * hc)) WRITE_LONG 0x6a fb PATCH_IF !(~%eh%~ STRING_EQUAL ~fail~) BEGIN INSERT_BYTES hf (hs * hc) WRITE_ASCIIE hf ~%eh%~ END END ELSE PATCH_IF ((hf != 0x72) AND (hc = 0)) BEGIN hf = 0x72 WRITE_LONG 0x64 hf END FOR (i1 = 0; i1 < (hs * hc); i1 += hs) BEGIN WRITE_SHORT (hf + i1 + 0x20) fc READ_SHORT (hf + i1 + 0x1e) cx fc += cx END PATCH_IF (SOURCE_SIZE > (0x72 + (hs * hc) + (0x30 * fc))) BEGIN DELETE_BYTES (0x72 + (hs * hc) + (0x30 * fc)) (SOURCE_SIZE - (0x72 + (hs * hc) + (0x30 * fc))) END // added by Ardanis WRITE_SHORT 0x6e 0 END // end of function EDIT: The IESDP mentions 1 char as a type of information. Are these edited via WRITE_ASCII? No, not necessarily. Check the description to see what kind of data is held there. If it's a letter (this would be very unlikely), use WRITE_ASCII. If it's a number, use WRITE_BYTE. Link to comment
JediMindTrix Posted August 27, 2015 Author Share Posted August 27, 2015 EDIT: My questions were silly, please ignore this post. Sometimes you just have to read more carefully The function can both clone and add headers - to clone, set the variable copy_header=0 to whichever header you wish to copy, and set whichever variables you wish to change, otherwise do not define it. All variables are set to 0 by default except Type and Location (which are 3), target and projectile (which are both 1). I think the second DEFINE_FUNCTION you posted should actually be defined first, since the first DEFINE_FUNCTION you posted references it. This should be included in the next WeidU release! Next question: In Neverwinter Nights scripting, you can create a custom function in a separate script file then include the file in another script and be able to call the same custom function. Is this possible in WeidU? EDIT: Above question was answered while I was editing. Link to comment
Mike1072 Posted August 27, 2015 Share Posted August 27, 2015 You don't need to delete it and you can't delete it. If you want to put the code into a separate file, do so and then INCLUDE that file in any components that will use the function (before you try to use it). Or, INCLUDE it in your ALWAYS section so that it is available in all components. Link to comment
subtledoctor Posted August 27, 2015 Share Posted August 27, 2015 I am trying to use WeidU to patch an Item Ability (usable, not an on-equip) on an amulet that in vanilla BG does not have one. That's when I put Weidu down, and pick up NI or DLTCEP. Different tools for different jobs. (That "add/clone header" function is interesting, though.) Link to comment
Jarno Mikkola Posted August 27, 2015 Share Posted August 27, 2015 That's when I put Weidu down, and pick up NI or DLTCEP. Different tools for different jobs.But see you can't patch the existing file with Weidu if you need to use the NI or DLTCEP to make it. Well, ok, the DLTCEP actually has a weidu-tp2-fication of the actions took, but I have never used it, so I can't recommend it. Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.