Modding with the extended palette
1ppv4 Extended palette entries component [102] adds new colour gradients to Infinity Engine games, raising the count of available colours from 116 to 256. It also includes a new random colour table making use of them for Baldur's Gate II and new colour set files for Icewind Dale II, giving you more skin/hair colour choices for the various races.
Keep in mind that if you include a new entry in a mod (120+) it *will* crash installs that do not have extended MPALETTE and MPAL256 files (the 1pp palette tool will also warn you if you are setting new gradients).
Since the content of these files is not touched by any other mods (that I am aware of) and replacing them is as non-intrusive as it gets the easiest way to avoid this is to include them with your mod and install them.
To avoid unnecessary overwriting of the files it would be best to add a simple file size check. If the file sizes are 9,272 bytes (MPALETTE) and 196,664 bytes (MPAL256) they already contain a full 256 colour set and need no further patching:
ACTION_FOR_EACH GWPalette IN MPALETTE MPAL256 BEGIN
ACTION_IF FILE_EXISTS_IN_GAME ~%GWPalette%.bmp~ BEGIN
COPY_EXISTING - ~%GWPalette%.bmp~ ~override~
PATCH_MATCH ~%GWPalette%~ WITH
MPALETTE BEGIN SET size1PP = 9272 END
DEFAULT SET size1PP = 196664
END
OUTER_SET sizePal = %SOURCE_SIZE%
PRINT ~CONTROL %GWPalette%.bmp palette size = %sizePal% - 1PP = %size1PP%~
ACTION_IF (sizePal != %size1PP%) BEGIN
PRINT ~Copying 1PP extended palette file %SOURCE_FILE%.~
COPY ~%MY_MOD%/resources/%GWPalette%.bmp~ ~override~
END
END
END
Of course, if you use them for a major character colour (and this is the only situation where it would be noticeable) this will not fix the dialogue font colour.
•BACK TO TOP
Patching Items and Spells
As of v4.2.0, the main 1pp update component [400] includes improved compatibility with third party mods. Modders are strongly recommended to borrow this simple way of coding to provide compatibility with 1pp, as Bolsa, Darron, Improved HaerDalis Swords, Rolles, Ruad, Song and Silence, Stuff of the Magi and The Unusual Oddities Shop mods already do.
Below is a brief step by step process to complete it.
⚠️ Warning: It will only work fine if 1pp components needed by your mod are installed.
➽ 1. Detecting 1pp
➽ 2. Loading macros and functions
➽ 3. Patching an item
a. Defining its own colors.
b. Using 1pp Staff of the Magi settings.
c. Using 1pp Glowing Staff of the Magi settings.
➽ 4. Customizing 1pp_compatibility library
➽ 5. Using new 1pp projectiles
a. Setting a new 1pp projectile to your itm or your spl if 1pp is installed.
b. Updating protection from projectiles with new 1pp projectiles.
➽ 6. Using Smart Avatar & Armour Switching component
1. Detecting 1pp
As 1pp update component patches items and provides additional content depending on which components are installed, detecting if 1pp is installed is not enough and you need to detect which components are installed to fine tune compatibility. Copy the following code in your ALWAYS block:
// 1ppv4: Additional Helmet Animations (core)
OUTER_SET is_1pp_helmet = (MOD_IS_INSTALLED ~1pp.tp2~ ~208~) ? 1 : 0
// 1ppv4: Additional Helmet Animations (core)
OUTER_SET is_1pp_helmet = (MOD_IS_INSTALLED ~1pp.tp2~ ~208~) ? 1 : 0
// 1ppv4: Increased paperdoll object variety (core) with Additional Shield Animations (core)
OUTER_SET is_1pp_shld = ((MOD_IS_INSTALLED ~1pp.tp2~ ~206~) AND (MOD_IS_INSTALLED ~1pp.tp2~ ~400~)) ? 1 : 0
// 1ppv4: Restored flame sword animations is installed
OUTER_SET is_1pp_fswords = (MOD_IS_INSTALLED ~1pp.tp2~ ~203~) ? 1 : 0
// 1ppv4: Wizards' Staves (core)
OUTER_SET is_1pp_staff = ((MOD_IS_INSTALLED ~1pp.tp2~ ~207~) AND (MOD_IS_INSTALLED ~1pp.tp2~ ~400~)) ? 1 : 0
// 1ppv4: Colourable Quarterstaves without 1ppv4: Wizards' Staves (core)
OUTER_SET is_1pp_staff0 = ((MOD_IS_INSTALLED ~1pp.tp2~ ~204~) AND (is_1pp_staff = 0)) ? 1 : 0
// 1ppv4: Increased paperdoll object variety (core)
OUTER_SET is_1pp_swblbw = ((MOD_IS_INSTALLED ~1pp.tp2~ ~210~) AND (MOD_IS_INSTALLED ~1pp.tp2~ ~400~)) ? 1 : 0
// 1ppv4: Core updates and item patches
OUTER_SET is_1pp_400 = (MOD_IS_INSTALLED ~1pp.tp2~ ~400~) ? 1 : 0
// 1ppv4: Improved projectile effects
OUTER_SET is_1pp_401 = (MOD_IS_INSTALLED ~1pp.tp2~ ~401~) ? 1 : 0
// 1ppv4: Smart Avatar & Armour Switching
OUTER_SET is_1pp_switch = (MOD_IS_INSTALLED ~1pp.tp2~ ~113~) ? 1 : 0
2. Loading macros and functions
Once it is done, you must load 3 libraries that will do the job:
ACTION_IF (is_1pp_helmet OR is_1pp_shld OR is_1pp_staff OR is_1pp_staff0 OR is_1pp_fswords OR is_1pp_swblbw OR is_1pp_400 OR is_1pp_401) BEGIN
INCLUDE ~%MOD_FOLDER%/lib/1pp_macros.tpa~
LAM ~Locations~ // DEFINES location field values to alter items' colors ⟺ MUST BE RUN ONLY ONCE
INCLUDE ~%MOD_FOLDER%/lib/1pp_compatibility.tph~
INCLUDE ~%MOD_FOLDER%/lib/1pp_functions.tpa~
END
with
- 1pp_macros.tpa: list of macros dealing with items coloring.
- 1pp_compatibility.tph: Loads functions restoring items coloration for EE games or if 1PP relevant components are installed.
- 1pp_functions.tpa: Loads miscellaneous macros and functions library used by 1pp v4.2.0.
3. Patching an item
Now comes the real part. If you want to create an item using 1pp features, let's say a special Staff of the Magi, the process is fairly simple: First, create it as a "normal" Staff of the Magi, and install it with your tp2:
COPY ~%MY_MOD%/itm/mystaff.itm~ ~override~
SAY NAME1 @1
SAY NAME2 @2
SAY UNIDENTIFIED_DESC @3
SAY DESC @4
Then you have three choices: modify its colors to fit your new icon or use the 1pp Staff of the Magi setting (using 1pp ISTAF11 icon).
a. Defining its own colors.
It is very easy: use 1pp homemade functions defined in 1pp_macros.tpa library.
COPY ~%MY_MOD%/itm/mystaff.itm~ ~override~
SAY NAME1 @1
SAY NAME2 @2
SAY UNIDENTIFIED_DESC @3
SAY DESC @4
PATCH_IF (SOURCE_SIZE > 0x71) BEGIN
PATCH_IF (is_1pp_staff0 OR is_1pp_staff) BEGIN
LPM ~clear~ // REMOVES all existing items' coloration opcodes before setting new ones
SET gradient = 112 // 112 SEA_FOAM
SET location = wgrey // location (Head/Blade/Staff major)
LPM ~colour~ // ADDS a new item global effect (op#7: Set Character colours by Palette)
SET gradient = 113 // sets colour index 113 FOG
SET location = wteal // location (Staff minor)
LPM ~colour~
SET gradient = 93 // sets colour index 93 DARK_CEMENT_GRAY
SET location = wpink // location (Bolt-Mace-Staff)
LPM ~colour~
SET gradient = 98 // sets colour index 98 LEAF_GREEN
SET location = wblue // location (Head/Blade minor)
LPM ~colour~
SET gradient = 27 // sets colour index 27 GRAY
SET location = wred // location * compatibility
LPM ~colour~
END
END
BUT_ONLY
b. Using 1pp Staff of the Magi settings.
It is very easy: use 1pp homemade functions defined in 1pp_compatibility.tph library.
COPY ~%MY_MOD%/itm/mystaff.itm~ ~override~
SAY NAME1 @1
SAY NAME2 @2
SAY UNIDENTIFIED_DESC @3
SAY DESC @4
PATCH_IF (SOURCE_SIZE > 0x71) BEGIN
PATCH_IF (is_1pp_staff0) BEGIN
LPF ~1pp_staf11_0~ END // Uses 1pp Colourable Quarterstaves settings (component 204)
END
END
BUT_ONLY
with
c. Using 1pp Glowing Staff of the Magi settings.
Always with 1pp homemade functions defined in 1pp_compatibility.tph library.
COPY ~%MY_MOD%/itm/mystaff.itm~ ~override~
SAY NAME1 @1
SAY NAME2 @2
SAY UNIDENTIFIED_DESC @3
SAY DESC @4
PATCH_IF (SOURCE_SIZE > 0x71) BEGIN
PATCH_IF (is_1pp_staff) BEGIN
LPF ~1pp_staf11~ END // Uses 1pp Wizards' Staves settings (component 207)
END
END
BUT_ONLY
with
Note: you can mix the last two options and even add EE compatibility:
COPY ~%MY_MOD%/itm/mystaff.itm~ ~override~
SAY NAME1 @1
SAY NAME2 @2
SAY UNIDENTIFIED_DESC @3
SAY DESC @4
PATCH_IF (SOURCE_SIZE > 0x71) BEGIN
PATCH_IF (is_ee OR is_1pp_staff) BEGIN
LPF ~1pp_staf11~ END // Uses 1pp Wizards' Staves settings (component 207)
END
PATCH_IF (is_1pp_staff0) BEGIN
LPF ~1pp_staf11_0~ END // Uses 1pp Colourable Quarterstaves settings (component 204)
END
END
BUT_ONLY
with is_ee defined like this in your ALWAYS block:
4. Customizing 1pp_compatibility library
As 1pp_compatibility library has been written to improve 1pp compatibility with a few mods installed before it (if ever!), it does not contain all patches and you may need to customize it to fit your needs.
Let's say you want to create an upgraded version or another version of Celestial Fury +3. All you have to do is to check the code used in 400_update_bgii_swords.tpa and copy-paste it in 1pp_compatibility.tph, like this:
// Celestial Fury +3
DEFINE_PATCH_FUNCTION ~1pp_sw1h51~ BEGIN
PATCH_IF (SOURCE_SIZE > 0x71) BEGIN
LPM ~clear~
SET gradient = 25 // sets colour index 25 DARK_PURE_GOLD
SET location = wgrey // location (Head/Blade/Staff major)
LPM ~colour~
SET gradient = 223 // 223 DROW_SKIN-MOSS_GREEN replaces colour index 16 SILVERISH_GOLD
SET location = wblue // location (Head/Blade minor)
LPM ~colour~
SET gradient = 47 // sets colour index 47 PURE_DARK_RED
SET location = wred // location (Grip/Staff minor - vanilla = whole staff)
LPM ~colour~
END
END
And install your sword like this:
COPY ~%MY_MOD%/itm/mysword.itm~ ~override~
SAY NAME1 @1
SAY NAME2 @2
SAY UNIDENTIFIED_DESC @3
SAY DESC @4
PATCH_IF (SOURCE_SIZE > 0x71) BEGIN
PATCH_IF (is_ee OR is_1pp_swblbw) BEGIN
LPF ~1pp_sw1h51~ END
END
END
BUT_ONLY
5. Using new 1pp projectiles
And now comes the easiest part of all: make your spells or items either using 1pp new projectiles or protecting from projectiles compatible with 1pp. In both cases, you can either use innate WeiDU functions or use 1pp_functions.tpa library that was written specially for 1pp Improved projectile effects component [401]. It includes:
- Function GW_DEF_OFFSETS_FILE: DEFINES the main offsets used to patch SPL, ITM and CRE files.
- Function GW_CLEAR_DUPLICATED_OPCODES: LOOKS for a specific opcode in a file and DELETES duplicated effects.
- Function GW_MODIFY_PROJ: MODIFIES an item's or spell's projectile.
a. Setting a new 1pp projectile to your itm or your spl if 1pp is installed.
You can use the way Rolles mod adds 1pp compatibility:
// Sling +4 Arla's Dragonbane
COPY ~rolles/itm/s#slng01.itm~ ~override~
SAY NAME2 @1000
SAY DESC @1001
PATCH_IF (is_ee OR is_1pp_401) BEGIN
LPF ALTER_ITEM_HEADER INT_VAR projectile = (IDS_OF_SYMBOL (projectl 1bull06) + 1) END
END
PATCH_IF (is_ee OR is_1pp_400) BEGIN
LPF ~1pp_slng05~ END
END
BUT_ONLY
// Battle Axe +4 Ice and Fire
COPY ~rolles/itm/s#ax1h01.itm~ ~override~
SAY NAME2 @1012
SAY DESC @1013
PATCH_IF (is_ee OR is_1pp_401) BEGIN
LPF ALTER_ITEM_HEADER INT_VAR header_type = 2 projectile = (IDS_OF_SYMBOL (projectl 1axe08) + 1) END
END
PATCH_IF (is_ee OR is_1pp_400) BEGIN
LPF ~1pp_ax1h13~ END
END
BUT_ONLY
or install them a la mode 1pp:
COPY ~%MY_MOD%/items/mydagger.itm~ ~override~
PATCH_IF (is_ee OR is_1pp_401) BEGIN
PATCH_IF (SOURCE_SIZE > 0x71) BEGIN // protects against invalid files
LPF ~GW_MODIFY_PROJ~ STR_VAR old_proj = "DAGGER" new_proj = "1dagg16" END
END
END
BUT_ONLY
COPY ~%MY_MOD%/spells/myspell.spl~ ~override~
PATCH_IF (is_ee OR is_1pp_401) BEGIN
PATCH_IF (SOURCE_SIZE > 0x71) BEGIN // protects against invalid files
LPF ~GW_MODIFY_PROJ~ STR_VAR old_proj = CLOUDKIL new_proj = 1pgspore END
END
END
BUT_ONLY
b. Updating protection from projectiles with new 1pp projectiles.
Once again, you can use 1pp homemade functions defined in 1pp_functions.tpa library:
// Added missing protections from new normal 1pp amo projectiles.
COPY ~%MOD_FOLDER%/items/%item%.itm~ ~override~
LPF ~GW_DEF_OFFSETS_FILE~ RET GW_oe GW_oc GW_al GW_fx GW_fi GW_fc GW_min_size END
PATCH_IF (is_ee OR is_1pp_401) BEGIN
LPF ~GW_CLEAR_DUPLICATED_OPCODES~ INT_VAR GW_opcode_to_check = 83 GW_effects_type = 2 RET GW_param2_55 END
PATCH_FOR_EACH proj IN 1arow01 1bolt01 1dagg05 1dart01 BEGIN
SET projnb = IDS_OF_SYMBOL (~projectl~ ~%proj%~)
PATCH_IF projnb > 0 BEGIN
LPF CLONE_EFFECT INT_VAR silent = 1 check_headers = 0 multi_match = 1 match_opcode = 83 parameter2 = projnb STR_VAR insert = last END
END
END
// Special case: SPEAR (55) needs a special treatment because some items do not bestow protection from spear projectile (used by the new javelin weapon).
PATCH_IF GW_param2_55 = 0 BEGIN
LPF CLONE_EFFECT INT_VAR silent = 1 check_headers = 0 multi_match = 1 match_opcode = 83 parameter2 = 55 STR_VAR insert = last END
END
END
END
BUT_ONLY
// Physical Mirror - Gwen fix: cleared duplicate entries and added SR compatibility (SR replaces opcode #197 with opcode #83).
COPY_EXISTING ~sppr613.spl~ ~override~
LPF ~GW_DEF_OFFSETS_FILE~ RET GW_oe GW_oc GW_al GW_fx GW_fi GW_fc GW_min_size END
PATCH_IF (is_ee OR is_1pp_401) BEGIN
PATCH_FOR_EACH GW_opcode IN 83 197 BEGIN
LPF ~GW_CLEAR_DUPLICATED_OPCODES~ INT_VAR GW_opcode_to_check = GW_opcode GW_effects_type = 2 RET GW_param2_55 END
PATCH_FOR_EACH proj IN // 1pp new projectiles
1arow01 1arow02 1arow03 1arow04 1arow05 1arow07 1arow10 1arow11 1arow15 1axe05 1axe08 1axe09 1axe10 1axe16
1bolt01 1bolt02 1bolt03 1bolt04 1bolt05 1bolt06 1bolt09 1bull02 1bull03 1bull04 1bull05 1bull06
1dagg05 1dagg11 1dagg12 1dagg16 1dart01 1dart02 1dart03 1dart04 1dart05 1dart08 BEGIN
SET projnb = IDS_OF_SYMBOL (~projectl~ ~%proj%~)
PATCH_IF projnb > 0 BEGIN
LPF CLONE_EFFECT INT_VAR silent = 1 check_globals = 0 multi_match = 1 match_opcode = GW_opcode parameter2 = projnb STR_VAR insert = last END
END
END
// Special case fix: SPEAR (55) needs a special treatment.
PATCH_IF GW_param2_55 = 0 BEGIN
LPF CLONE_EFFECT INT_VAR silent = 1 check_globals = 0 multi_match = 1 match_opcode = GW_opcode parameter2 = 55 STR_VAR insert = last END
END
END
END
BUT_ONLY
or use innate WeiDU functions:
// Enhanced Shield of Balduran (Rolles mod)
COPY ~rolles/itm/s#shld01.itm~ ~override~
SAY NAME2 @1002
SAY DESC @1003
PATCH_IF (is_ee OR is_1pp_401) BEGIN
PATCH_FOR_EACH proj IN // 1pp new projectiles
1arow01 1arow02 1arow03 1arow04 1arow05 1arow07 1arow10 1arow11 1arow15 1axe05 1axe08 1axe09 1axe10 1axe16
1bolt01 1bolt02 1bolt03 1bolt04 1bolt05 1bolt06 1bolt09 1bull02 1bull03 1bull04 1bull05 1bull06
1dagg05 1dagg11 1dagg12 1dagg16 1dart01 1dart02 1dart03 1dart04 1dart05 1dart08 BEGIN
SET projnb = IDS_OF_SYMBOL (~projectl~ ~%proj%~)
PATCH_IF projnb > 0 BEGIN
LPF CLONE_EFFECT INT_VAR silent = 1 check_headers = 0 multi_match = 1 match_opcode = 197 parameter2 = projnb STR_VAR insert = above END
END
END
END
PATCH_IF (is_ee OR is_1pp_shld) BEGIN
LPF ~1pp_wa2shiel~ END
END
PATCH_IF (is_1pp_shld0) BEGIN
LPF ~1pp_shld27_0~ END
END
BUT_ONLY
// Girdle of the Magi (Stuff of the Magi mod)
COPY ~%MOD_FOLDER%/items/wzrdbelt.itm~ ~override~
SAY NAME2 @141
SAY DESC @143
PATCH_IF (is_ee OR is_1pp_401) BEGIN
PATCH_FOR_EACH proj IN 1arow01 1bolt01 1dagg05 1dart01 // 1pp new projectiles
SET projnb = IDS_OF_SYMBOL (~projectl~ ~%proj%~)
PATCH_IF projnb > 0 BEGIN
LPF CLONE_EFFECT INT_VAR silent = 1 check_headers = 0 multi_match = 1 match_opcode = 83 parameter2 = projnb STR_VAR insert = last END
END
END
END
BUT_ONLY
6. Using Smart Avatar & Armour Switching component
If you want your robes and armors benefit from this component which allows armour and robes to properly show up for characters of any class when equipped, use the following code (from Darron mod):
// Aurumvorax Armor +2
COPY ~darron/item/esliarm0.itm~ ~override~
SAY NAME12 @108
SAY DESC @110
PATCH_IF (is_1pp_switch) BEGIN
// armor spell effect
LPF ADD_ITEM_EQEFFECT INT_VAR insert_point = "-1" opcode = 146 target = 1 timing = 2 parameter1 = 1 parameter2 = 1 STR_VAR resource = lcarmor END
END
BUT_ONLY
I guess now it's time to... Enjoy! 😉
•BACK TO TOP