DEFINE_PATCH_MACRO ~identify_weapon~ BEGIN INNER_ACTION BEGIN ACTION_IF FILE_EXISTS_IN_GAME ~%weaponfile%.itm~ BEGIN COPY_EXISTING ~%weaponfile%.itm~ ~override~ SET ~type~=0 READ_BYTE 0x18 ~test~ SET ~test~ = BYTE_AT 0x18 BAND 0b00000010 PATCH_IF ~test~ = 0b00000010 BEGIN SET ~twohanded~=1 END ELSE BEGIN SET ~twohanded~=0 END READ_BYTE 0x31 ~proftype~ PATCH_IF ~proftype~=0 BEGIN SET ~skipme~=1 END SET ~type~=0 GET_OFFSET_ARRAY ab_off_array 0x64 4 0x68 2 0 0 0x38 PHP_EACH ab_off_array AS int => ab_off BEGIN READ_SHORT ab_off ab_type PATCH_IF ~ab_type~=1 AND ~type~=0 BEGIN SET ~type~=1 END PATCH_IF (~ab_type~=2 OR ~ab_type~=4) AND ~type~=0 BEGIN SET ~type~=2 END END BUT_ONLY END ELSE BEGIN OUTER_SET ~skipme~=1 END END END DEFINE_PATCH_MACRO ~set_fighter_profs~ BEGIN // initialise SET ~skipme~=0 SET ~hasmelee~=0 SET ~hasranged~=0 SET ~twohandedmelee~=0 SET ~twohandedranged~=0 SET ~offhandweapon~=0 SET ~shield~=0 SET ~noweapon~=1 // get weapon types and proficiencies GET_OFFSET_ARRAY item_off_array 0x2bc 4 0x2c0 4 0 0 0x14 PHP_EACH item_off_array AS int => item_off BEGIN READ_ASCII item_off item_name SPRINT $item_name_array(~%int%~) ~%item_name%~ END READ_LONG 0x2b8 ~slot_off~ FOR (i=0;i<3;i=i+1) BEGIN READ_SHORT ~slot_off~+(9+i)*2 ~weaponcode~ PATCH_IF !(~weaponcode~=65535) BEGIN SET ~noweapon~=0 SPRINT ~weaponfile~ $item_name_array(~%weaponcode%~) LAUNCH_PATCH_MACRO ~identify_weapon~ PATCH_IF ~type~=1 BEGIN PATCH_IF ~hasmelee~=0 THEN BEGIN SET ~hasmelee~=1 SET ~twohandedmelee~=~twohanded~ SET ~onhandproftype~=~proftype~ END END ELSE BEGIN PATCH_IF ~hasranged~=0 THEN BEGIN SET ~hasranged~=1 SET ~twohandedranged~=~twohanded~ SET ~rangedproftype~=~proftype~ END END END END // if skipme=0, continue PATCH_IF ~skipme~=0 AND ~noweapon~=0 THEN BEGIN //check for a shield/offhand weapon PATCH_IF !(~twohandedmelee~=1 OR ~twohandedranged~=1) BEGIN READ_SHORT ~slot_off~+0x4 ~shieldcode~ PATCH_IF !(~shieldcode~=65535) BEGIN SPRINT ~weaponfile~ $item_name_array(~%shieldcode%~) LAUNCH_PATCH_MACRO ~identify_weapon~ PATCH_IF ~type~=0 BEGIN SET ~shield~=1 END ELSE BEGIN SET ~offhandweapon~=1 SET ~offhandproftype~=~proftype~ END END END PATCH_IF ~kit~=0x401f0000 THEN BEGIN // barbarian SET ~profmax~=$prof_max(~900~) SET ~rangeprofmax~=$prof_max(~900~) END ELSE PATCH_IF ~kit~=0x40010000 THEN BEGIN // berserker SET ~profmax~=$prof_max(~800~) SET ~rangeprofmax~=1 END ELSE BEGIN SET ~profmax~=$prof_max(~%class%~) SET ~rangeprofmax~=$prof_max(~%class%~) END SET ~profs~=~level~/3+4 SET ~offhandprof~=0 SET ~onhandprof~=0 SET ~rangedprof~=0 SET ~styleprof~=0 PATCH_IF ~offhandweapon~=1 THEN BEGIN SET ~style~=114 // two-weapon SET ~profs~=~profs~-3 SET ~styleprof~=3 PATCH_IF ~offhandproftype~=~onhandproftype~ BEGIN PATCH_IF ~profs~>~profmax~ THEN BEGIN SET ~onhandprof~=~profmax~ END ELSE BEGIN SET ~onhandprof~=~profs~ END END ELSE BEGIN SET ~temp~=~profs~/2 PATCH_IF ~temp~>~profmax~ BEGIN SET ~onhandprof~=~profmax~ SET ~offhandprof~=~profmax~ END ELSE BEGIN SET ~offhandprof~=~temp~ SET ~onhandprof~=~profs~-~temp~ END END END ELSE PATCH_IF ~shield~=1 AND ~hasranged~=0 THEN BEGIN SET ~style~=112 // sword and shield PATCH_IF ~profs~<=~profmax~ BEGIN SET ~onhandprof~=~profs~ END ELSE BEGIN SET ~profs~=~profs~-~profmax~ SET ~onhandprof~=~profmax~ PATCH_IF ~profs~>2 THEN BEGIN SET ~styleprof~=2 END ELSE BEGIN SET ~styleprof~=~profs~ END END END ELSE PATCH_IF ~twohandedmelee~=1 AND ~hasranged~=0 THEN BEGIN SET ~style~=111 //two-handed SET ~profs~=~profs~-1 SET ~styleprof~=1 PATCH_IF ~profs~<=~profmax~ THEN BEGIN SET ~onhandprof~=~profs~ END ELSE BEGIN SET ~onhandprof~=~profmax~ SET ~profs~=~profs~-~profmax~ PATCH_IF ~profs~>0 THEN BEGIN SET ~styleprof~=2 END END END ELSE PATCH_IF ~twohandedmelee~=0 AND ~hasranged~=0 THEN BEGIN SET ~style~=113 //one-weapon SET ~profs~=~profs~-2 SET ~styleprof~=2 PATCH_IF ~profs~<=~profmax~ THEN BEGIN SET ~onhandprof~=~profs~ END ELSE BEGIN SET ~onhandprof~=~profmax~ END END ELSE PATCH_IF ~hasranged~=1 THEN BEGIN PATCH_IF ~twohandedmelee~=1 THEN BEGIN SET ~style~=111 END ELSE PATCH_IF ~shield~=1 THEN BEGIN SET ~style~=112 END ELSE BEGIN SET ~style~=113 END SET ~profs~=~profs~-2 SET ~onhandprof~=2 PATCH_IF ~profs~<=~rangeprofmax~ THEN BEGIN SET ~rangedprof~=~profs~ END ELSE BEGIN SET ~rangedprof~=~rangeprofmax~ SET ~profs~=~profs~-~rangeprofmax~ PATCH_IF ~profs~<=~profmax~ - 2 THEN BEGIN SET ~onhandprof~=~profs~+~onhandprof~ END ELSE BEGIN SET ~onhandprof~=~profmax~ SET ~profs~=~profs~-(~profmax~ - 2) PATCH_IF ~profs~>=2 THEN BEGIN SET ~styleprof~=2 END ELSE BEGIN SET ~styleprof~=~profs~ END END END END // hand out actual proficiencies PATCH_IF ~onhandprof~>0 BEGIN SET ~opcode~=233 SET ~proftype~=~onhandproftype~ SET ~proflevel~=~onhandprof~ LAUNCH_PATCH_MACRO ~add_proficiency~ END PATCH_IF ~offhandprof~>0 BEGIN SET ~opcode~=233 SET ~proftype~=~offhandproftype~ SET ~proflevel~=~offhandprof~ LAUNCH_PATCH_MACRO ~add_proficiency~ END PATCH_IF ~rangedprof~>0 BEGIN SET ~opcode~=233 SET ~proftype~=~rangedproftype~ SET ~proflevel~=~rangedprof~ LAUNCH_PATCH_MACRO ~add_proficiency~ END PATCH_IF ~styleprof~>0 BEGIN SET ~opcode~=233 SET ~proftype~=~style~ SET ~proflevel~=~styleprof~ LAUNCH_PATCH_MACRO ~add_proficiency~ END END END DEFINE_ACTION_MACRO ~fighter_core~ BEGIN // main code // load in some saving throws COPY_EXISTING ~savewar.2da~ ~override~ READ_2DA_ENTRIES_NOW ~fighter_save_array~ 10 BUT_ONLY // set some kits // barbarian ACTION_FOR_EACH ~barbarian~ IN tobpar02 firban04 firban05 fshorde4 gororc01 orc01 orc05 rorcl01 rorcs01 BEGIN ACTION_IF FILE_EXISTS_IN_GAME ~%barbarian%.cre~ BEGIN COPY_EXISTING ~%barbarian%.cre~ ~override~ WRITE_LONG 0x244 0x401f0000 READ_BYTE 0x273 ~extrahitpoints~ PATCH_IF ~extrahitpoints~>10 BEGIN SET ~extrahitpoints~=10 END READ_SHORT 0x24 ~hitpoints~ SET ~hitpoints~=~hitpoints~+~extrahitpoints~ WRITE_SHORT 0x24 ~hitpoints~ WRITE_SHORT 0x26 ~hitpoints~ BUT_ONLY END END // berserker ACTION_FOR_EACH ~berserker~ IN duecla01 duergar2 ar18fig bdturm01 cefgt03 chtaz01 gorsta07 gpfight1 hlolaf senorc01 senorc03 slaver1 tazok termer01 trskin06 ogregrsu bgtazok tazok2 _tazok _tazok2 BEGIN ACTION_IF FILE_EXISTS_IN_GAME ~%berserker%.cre~ BEGIN COPY_EXISTING ~%berserker%.cre~ ~override~ WRITE_LONG 0x244 0x40010000 BUT_ONLY END END // kensai ACTION_FOR_EACH ~kensai~ IN gorwom06 hlkoshi sarkis02 sarkis03 BEGIN ACTION_IF FILE_EXISTS_IN_GAME ~%kensai%.cre~ BEGIN COPY_EXISTING ~%kensai%.cre~ ~override~ WRITE_LONG 0x244 0x40030000 REMOVE_CRE_ITEM ~leat02~ PATCH_FOR_EACH ~offset~ IN 0x46 0x48 BEGIN READ_SHORT ~offset~ ~ac~ SET ~ac~=~ac~-2 WRITE_SHORT ~offset~ ~ac~ END BUT_ONLY END END COPY_EXISTING ~arntra03.cre~ ~override~ ~obshal04.cre~ ~override~ ~ppduelc.cre~ ~override~ WRITE_BYTE 0x52 11 COPY_EXISTING ~trfued10.cre~ ~override~ WRITE_BYTE 0x52 18 ACTION_FOR_EACH ~skipme~ IN BAZPAT c6CATTI C6CATTI2 C6DRIZZ C6DRIZZ2 C6DRIZZ3 C6BRUEN C6BRUEN2 FSSPIR1 KALWRK01 MDK2KURT MDK2DOC MDK2MAX QCIRC03 BEGIN OUTER_SPRINT ~temp~ ~%skipme%~ OUTER_INNER_PATCH ~~ BEGIN TO_LOWER ~temp~ END OUTER_SPRINT $fighter_prof_skip_list(~%temp%~) ~~ END // check for whether multi-classed characters and Barbarians are allowed to put more than two points into anything ACTION_DEFINE_ASSOCIATIVE_ARRAY class_id BEGIN 2 => ~FIGHTER~ 7 => ~FIGHTER_MAGE~ 8 => ~FIGHTER_CLERIC~ 9 => ~FIGHTER_THIEF~ 10=> ~FIGHTER_MAGE_THIEF~ 16=> ~FIGHTER_DRUID~ 17=> ~FIGHTER_MAGE_CLERIC~ 800=> ~BERSERKER~ 900=> ~BARBARIAN~ END COPY_EXISTING ~weapprof.2da~ ~override~ COUNT_2DA_COLS ~colcount~ PATCH_FOR_EACH ~idnum~ IN 2 7 8 9 10 16 17 173 181 800 900 BEGIN SET $prof_max(~%idnum%~)=5 SPRINT ~string_to_find~ $class_id(~%idnum%~) FOR (i=0;i<~colcount~-1;i=i+1) BEGIN READ_2DA_ENTRY 0 i 10 ~class_id_check~ PATCH_IF ~%class_id_check%~ STRING_EQUAL_CASE ~%string_to_find%~ BEGIN SET colnum=~i~+1 SET ~i~=~colcount~ READ_2DA_ENTRY 18 colnum 10 ~profnum~ SET $prof_max(~%idnum%~)=~profnum~ END END END BUT_ONLY COPY_EXISTING_REGEXP ~.*\.cre~ ~override~ //COPY_EXISTING ~ppsaem.cre~ ~override~ READ_BYTE 0x273 ~class~ READ_BYTE 0x272 ~race~ SET ~skipcheck~=0 SPRINT ~filename~ ~%SOURCE_RES%~ TO_LOWER ~filename~ PATCH_IF !(VARIABLE_IS_SET $fighter_prof_skip_list(EVALUATE_BUFFER ~%filename%~)) AND !(VARIABLE_IS_SET $script_name_pdialog(EVALUATE_BUFFER ~%filename%~)) AND (~class~=2 OR ~class~=7 OR ~class~=8 OR ~class~=9 OR ~class~=10 OR ~class~=16 OR ~class~=17 OR ~class~=181 OR ~class~=173) BEGIN // wipe residue of previous rules PATCH_IF ~race~<10 BEGIN WRITE_BYTE 0x53 1 END // wipe BG1-style proficiencies WRITE_LONG 0x6e 0x0 WRITE_LONG 0x72 0x0 // sort out THAC0 and level READ_BYTE 0x52 ~thac0~ READ_BYTE 0x234 ~level~ SET ~estthac0~=21 - ~level~ PATCH_IF ~estthac0~<~thac0~ THEN BEGIN WRITE_BYTE 0x52 ~estthac0~ END ELSE BEGIN SET ~level~=21 - ~thac0~ WRITE_BYTE 0x234 ~level~ END // sort out hit points PATCH_IF (~level~<10) THEN BEGIN SET ~esthitpoints~=6*~level~ END ELSE BEGIN SET ~esthitpoints~=3*~level~+30 END READ_SHORT 0x24 ~hp~ PATCH_IF ~hp~<~esthitpoints~ THEN BEGIN WRITE_SHORT 0x24 ~esthitpoints~ WRITE_SHORT 0x26 ~esthitpoints~ END // sort out saving throws FOR (i=1;i<6;i=i+1) BEGIN READ_BYTE 0x53+i ~save~ ag_level = level>40 ? 40 : level SET ~estsave~=$fighter_save_array(~%i%~ ~%ag_level%~) PATCH_IF ~estsave~<~save~ THEN BEGIN WRITE_BYTE 0x53+i ~estsave~ END END // read in kit READ_LONG 0x244 ~kit~ // if a Kensai, sort out bonuses PATCH_IF ~kit~=0x40030000 BEGIN SET ~opcode~=54 // thac0 bonus SET ~proftype~=0 // increment SET ~proflevel~=~level~/3 LAUNCH_PATCH_MACRO ~add_proficiency~ SET ~opcode~=73 // damage bonus - everything else unchanged LAUNCH_PATCH_MACRO ~add_proficiency~ SET ~opcode~=190 // speed factor bonus SET ~proftype~=~level~/4 // proftype slot used for amount in this case SET ~proflevel~=0 // this is zeroed for opcode 190 LAUNCH_PATCH_MACRO ~add_proficiency~ REMOVE_MEMORIZED_SPELL ~spcl144~ // reset Kai uses SET ~numkai~=(~level~ - 1)/4 + 1 ADD_MEMORIZED_SPELL ~spcl144~ #0 ~innate~ (~numkai~) END // if a Berserker, sort out Rages PATCH_IF ~kit~=0x40010000 BEGIN REMOVE_MEMORIZED_SPELL ~spcl321~ SET ~numberserk~=(~level~-1)/4+1 ADD_MEMORIZED_SPELL ~spcl321~ #0 ~innate~ (~numberserk~) END // if a Barbarian, sort out misc stuff PATCH_IF ~kit~=0x401f0000 BEGIN REMOVE_MEMORIZED_SPELL ~spcl152~ SET ~numrage~= (~level~-1)/4+1 ADD_MEMORIZED_SPELL ~spcl321~ #0 ~innate~ (~numrage~) SET ~opcode~=176 // movement speed increase SET ~proftype~=0 SET ~proflevel~=2 LAUNCH_PATCH_MACRO ~add_proficiency~ PATCH_IF ~level~>10 BEGIN PATCH_IF ~level~>18 BEGIN SET ~proflevel~=20 END ELSE PATCH_IF ~level~>14 BEGIN SET ~proflevel~=15 END ELSE BEGIN SET ~proflevel~=10 END PATCH_FOR_EACH ~code~ IN 86 87 88 89 BEGIN SET ~opcode~=~code~ SET ~proftype~=0 LAUNCH_PATCH_MACRO ~add_proficiency~ END END END LAUNCH_PATCH_MACRO ~set_fighter_profs~ /* PATCH_PRINT ~%hasmelee% %twohandedmelee% %onhandproftype% %hasranged% %twohandedranged% %rangedproftype%~ PATCH_PRINT ~%shield% %offhandweapon% %offhandproftype%~ PATCH_PRINT ~%onhandprof% %offhandprof% %rangedprof% %styleprof% %style%~ */ END BUT_ONLY END