Jump to content

Allowing Druids using Small & Medium Shields


leania

Recommended Posts

Hello. I'm now studying about Weidu modding and I successfully made the component which allows Druids using Arrows/Bows.

 

Based on the source code, I modified it for the component what I mentioned at title as follows:

 

---------------------------------------------------------------------------------------------------------------------------------------

 

BEGIN ~Eased Equipment Restriction: Small & Medium Shields~

COPY_EXISTING_REGEXP GLOB ~.*\.itm~ ~override~ //copies all item files

PATCH_IF ("%SOURCE_SIZE%" > "0x71") BEGIN // avoid crashing on empty items

READ_BYTE "0x1F" "fighter" //reads the byte containing the fighter usability flag

PATCH_IF (("%fighter%" BAND "0b00001000") = "0b00000000") BEGIN // if it is usable by fighters

READ_BYTE "0x21" "druid" //reads the byte containing druid usability flag

READ_BYTE "0x1F" "druid/fighter" //reads the byte containing druid usability flag

READ_SHORT "0x1C" "type" //reads the byte containing item type

READ_SHORT "0x08" "name" //reads the byte containing unidentified name

PATCH_IF ("%type%" = "12") AND ("%name%" != "240") BEGIN // if it is a shield and not large shield

WRITE_BYTE "0x21" ("%druid%" BAND "0b10111111") // makes usable by druids

WRITE_BYTE "0x1F" ("%druid/fighter%" BAND "0b11101111") // makes usable by

 

druid/fighter

END

END

END

BUT_ONLY_IF_IT_CHANGES

---------------------------------------------------------------------------------------------------------------------------------------

 

The component however didn't modify anything at all, that is, 0 itm files were copied into override folder. I've intended to use Unidentified Name field in itm format (referring to http://iesdp.gibberl...Header_ItemType) and I checked the byte of Large Shield using NI. Since the hex value of the Unidentified Name of Large Shield is "0xf0 19 00 00", the 0xf0 is 240 as decimal.

 

When I modify the value of "name" to "0x09" from "0x08" and compare this byte to 25 (0x19), it works fine as intended, i.e., only medium shields is usable by druids because small shields and large shields share the value.

 

This is really strange... How could I solve this problem? or any better way for implementing the component? Thank you in advance!

Link to comment

Item names are string references which are always 4 bytes long. You have to use READ_LONG if you want to evaluate the whole value. I wouldn't use the item name though, because you can't be sure that all (mod-provided) shields use the same string reference. Maybe the item animation field (offset 0x22) is a better alternative.

 

Another issue may be the variable name "druid/fighter". I don't know how tolerant WeiDU is regarding special characters in variable names, but I would remove the slash from the name.

Link to comment

Item names are string references which are always 4 bytes long. You have to use READ_LONG if you want to evaluate the whole value. I wouldn't use the item name though, because you can't be sure that all (mod-provided) shields use the same string reference. Maybe the item animation field (offset 0x22) is a better alternative.

 

Another issue may be the variable name "druid/fighter". I don't know how tolerant WeiDU is regarding special characters in variable names, but I would remove the slash from the name.

 

Thank you for the reply! Yes, you are right. I would remove the slash and use the item animation field instead of the name.

Link to comment

Aside from the animation field, there is a community list of shields here that can be used to determine what type a known shield is.

 

The animation field is probably easiest, but there's probably some reason we created a community list of shields instead of using it (I hope). Note that 1PP adds new animations for shields other than the ones listed in the IESDP (and the field is case insensitive).

Link to comment

The item animation is encoded as 2 ASCII characters, not a number. Therefore, it makes sense to use READ_ASCII 0x22 anim (2) instead of READ_SHORT. Then you can check the string contents of the anim variable using STRING_EQUAL, STRING_COMPARE, or STRING_COMPARE_REGEXP.

 

For example:

 

COPY_EXISTING_REGEXP GLOB ~.+\.itm~ ~override~ // copy all items
 PATCH_IF (SOURCE_SIZE > 0x71) BEGIN // avoid crashing on empty items
READ_SHORT 0x1C type
PATCH_IF (type == 0x0c && (BYTE_AT 0x1F BAND 0b00001000) == 0b00000000) BEGIN // shield usable by fighters
  READ_ASCII 0x22 anim (2)
  PATCH_IF ((~%anim%~ STRING_COMPARE_REGEXP ~D[23]~) == 0) BEGIN // animation is D2 or D3 = small or medium shield
	WRITE_BYTE 0x21 (THIS BAND 0b10111111) // make usable by druids
	WRITE_BYTE 0x1F (THIS BAND 0b11101111) // make usable by fighter/druids
  END
END
 END
 BUT_ONLY_IF_IT_CHANGES

Since you only use some variables once, I used the BYTE_AT command to save a few extra lines of code.

 

Edit: Updated to even nicer code using THIS.

Link to comment

Assuming you also want to update the "Usable by" descriptions, this is how I'd proceed within IR.

LOAD_TRA ~item_rev/languages/english/description_updates.tra~ // only @100400, @100401, @100403, @100411 and @100412 strings are required
INCLUDE ~item_rev/lib/descriptions.tpa~
INCLUDE ~item_rev/lib/common_shield_list.tpa~
INCLUDE ~item_rev/lib/usability_description.tpa~

DEFINE_PATCH_MACRO druid BEGIN
 SPRINT add_class @100411
 SPRINT catch_class @100412
 LPF usable_desc INT_VAR make_usable=1 STR_VAR add_class catch_class END
END

LAUNCH_ACTION_MACRO shields // label all known shields as buckler/small/medium/large

COPY_EXISTING_REGEXP GLOB ~.+\.itm~ override PATCH_IF SOURCE_SIZE>0x71 BEGIN
 READ_SHORT 0x1c type
 READ_ASCII 0x22 anim (2)
 PATCH_IF ((type=191) || (type=12 && ~%anim%~ STRING_EQUAL_CASE ~d2~))	  // small shields
   || ((type=192) || (type=12 && ~%anim%~ STRING_EQUAL_CASE ~d3~)) BEGIN // medium shields
WRITE_BYTE 0x21 (BYTE_AT 0x21 BAND 0b10111111) // make usable by druids
WRITE_BYTE 0x1F (BYTE_AT 0x1F BAND 0b11101111) // make usable by fighter/druids
SPRINT text_update druid
LPM update_item_descriptions
 END
 PATCH_IF type=190 || type=191 || type=192 || type=194 BEGIN
WRITE_SHORT 0x1c 12 // reset item type back to shield
 END
END BUT_ONLY

 

If you wish, feel free to borrow the files included from IR's package. Just keep in mind that "usability_description.tpa" is hardcoded to use @100400, @100401 and @100403 strings and that they should be exactly as they are in IR's "description_updates.tra".

Link to comment

Thank you for all of comments and advises!!!

 

By the way, Is the usability description embedded into each item itself in BG:EE, isn't it? I've checked the description changed when I modify the usability of an item.

 

Honestly, I'm not sure whether I can make the mod with providing compatibility for both BG:EE and BG2 (BGT) because I'm a super beginner of Weidu modding. :rolleyes: It is too hard to make the mod as I've thought... Haha.

Link to comment
By the way, Is the usability description embedded into each item itself in BG:EE, isn't it? I've checked the description changed when I modify the usability of an item.
Yes. I haven't updated the code to ignore BGEE engine, but all it needs is a ~PATCH_IF NOT (ENGINE_IS bgee) BEGIN ... END~ wrapped around everything inside the function. Actually, no, it is gonna work fine on BGEE as it is - there is no "(Un)Usable By:" header in BGEE descriptions, so the desc updater will not be able to change anything.

 

Honestly, I'm not sure whether I can make the mod with providing compatibility for both BG:EE and BG2 (BGT) because I'm a super beginner of Weidu modding. :rolleyes: It is too hard to make the mod as I've thought... Haha.
You seem to understand WeiDU pretty well for a beginner. Compared to the majority, anyway.
Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...