From 2b0d12d1b16fde83924af2c825103af3298091e4 Mon Sep 17 00:00:00 2001 From: Jaysyn904 <68194417+Jaysyn904@users.noreply.github.com> Date: Fri, 24 Oct 2025 07:31:39 -0400 Subject: [PATCH] 2025/10/24 Update Added CCOHEE. Updated PRC8 includes. Dragon fear update. Full compile. --- README.md | 4 +- nasher.cfg | 2 +- src/include/inc_dynconv.nss | 46 ++++++----- src/include/inc_item_props.nss | 55 ++++++++++++- src/include/inc_newspellbook.nss | 4 + src/include/inc_switch_setup.nss | 22 +++--- src/include/moi_inc_moifunc.nss | 5 +- src/include/prc_effect_inc.nss | 21 ++++- src/include/prc_getbest_inc.nss | 3 +- src/include/prc_inc_castlvl.nss | 62 ++++++++++++--- src/include/prc_inc_core.nss | 2 + src/include/prc_inc_fork.nss | 82 ++++++++++++++++++- src/include/prc_inc_function.nss | 2 +- src/include/prc_inc_json.nss | 122 ++++++++++++++++++++++++++--- src/include/prc_inc_material.nss | 4 +- src/include/prc_inc_nwscript.nss | 5 +- src/include/prc_inc_onhit.nss | 21 ++++- src/include/prc_inc_unarmed.nss | 4 +- src/include/prc_inc_wpnrest.nss | 66 +++++++++++++++- src/include/prc_nui_lv_inc.nss | 4 +- src/include/prc_sp_func.nss | 18 +++++ src/include/prc_spell_const.nss | 23 +++++- src/include/prc_x2_craft.nss | 6 ++ src/include/psi_inc_core.nss | 4 +- src/include/x3_inc_horse.nss | 5 +- src/module/ifo/module.ifo.json | 7 ++ src/module/nss/nw_s1_dragfeara.nss | 90 +++++++++++++++++++-- 27 files changed, 604 insertions(+), 85 deletions(-) diff --git a/README.md b/README.md index b4b5d56..ea2d517 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,6 @@ Repository for the development of the PRC8 version of Lord of Terror, by Tolitz 3.) [PRC8](https://gitea.raptio.us/Jaysyn/PRC8/releases) -4.) [CEP3](https://neverwintervault.org/project/nwnee/hakpak/combined/cep-3-community-expansion-pack) \ No newline at end of file +4.) [CCOHEE](https://neverwintervault.org/project/nwnee/hakpak/original-hakpak/customize-character-override-hak-extended-edition-ccohee) + +5.) [CEP3](https://neverwintervault.org/project/nwnee/hakpak/combined/cep-3-community-expansion-pack) \ No newline at end of file diff --git a/nasher.cfg b/nasher.cfg index 7101a90..d42bfe1 100644 --- a/nasher.cfg +++ b/nasher.cfg @@ -15,7 +15,7 @@ author = "Jaysyn904 <68194417+Jaysyn904@users.noreply.github.com>" [target] name = "default" -file = "The Lord of Terror [CCOH-PRC8-CEP3].mod" +file = "The Lord of Terror [PRC8-CEP3].mod" description = "PRC8 version of The Lord of Terror module." [target.sources] include = "src/module/**/*" diff --git a/src/include/inc_dynconv.nss b/src/include/inc_dynconv.nss index 4603fc4..a90a69c 100644 --- a/src/include/inc_dynconv.nss +++ b/src/include/inc_dynconv.nss @@ -4,8 +4,6 @@ //::////////////////////////////////////////////// /** @file - - @author Primogenitor @date 2005.09.23 - Rebuilt the system - Ornedan */ @@ -21,29 +19,29 @@ const int DYNCONV_EXITED = -2; const int DYNCONV_ABORTED = -3; const int DYNCONV_SETUP_STAGE = -1; -const int DYNCONV_TOKEN_HEADER = 99; -const int DYNCONV_TOKEN_REPLY_0 = 100; -const int DYNCONV_TOKEN_REPLY_1 = 101; -const int DYNCONV_TOKEN_REPLY_2 = 102; -const int DYNCONV_TOKEN_REPLY_3 = 103; -const int DYNCONV_TOKEN_REPLY_4 = 104; -const int DYNCONV_TOKEN_REPLY_5 = 105; -const int DYNCONV_TOKEN_REPLY_6 = 106; -const int DYNCONV_TOKEN_REPLY_7 = 107; -const int DYNCONV_TOKEN_REPLY_8 = 108; -const int DYNCONV_TOKEN_REPLY_9 = 109; -const int DYNCONV_TOKEN_EXIT = 110; -const int DYNCONV_TOKEN_WAIT = 111; -const int DYNCONV_TOKEN_NEXT = 112; -const int DYNCONV_TOKEN_PREV = 113; -const int DYNCONV_MIN_TOKEN = 99; -const int DYNCONV_MAX_TOKEN = 113; +const int DYNCONV_TOKEN_HEADER = 16183899; +const int DYNCONV_TOKEN_REPLY_0 = 161838100; +const int DYNCONV_TOKEN_REPLY_1 = 161838101; +const int DYNCONV_TOKEN_REPLY_2 = 161838102; +const int DYNCONV_TOKEN_REPLY_3 = 161838103; +const int DYNCONV_TOKEN_REPLY_4 = 161838104; +const int DYNCONV_TOKEN_REPLY_5 = 161838105; +const int DYNCONV_TOKEN_REPLY_6 = 161838106; +const int DYNCONV_TOKEN_REPLY_7 = 161838107; +const int DYNCONV_TOKEN_REPLY_8 = 161838108; +const int DYNCONV_TOKEN_REPLY_9 = 161838109; +const int DYNCONV_TOKEN_EXIT = 161838110; +const int DYNCONV_TOKEN_WAIT = 161838111; +const int DYNCONV_TOKEN_NEXT = 161838112; +const int DYNCONV_TOKEN_PREV = 161838113; +const int DYNCONV_MIN_TOKEN = 16183899; +const int DYNCONV_MAX_TOKEN = 161838113; -const int DYNCONV_STRREF_PLEASE_WAIT = 16824202; // "Please wait" -const int DYNCONV_STRREF_PREVIOUS = 16824203; // "Previous" -const int DYNCONV_STRREF_NEXT = 16824204; // "Next" -const int DYNCONV_STRREF_ABORT_CONVO = 16824212; // "Abort" -const int DYNCONV_STRREF_EXIT_CONVO = 78; // "Exit" +const int DYNCONV_STRREF_PLEASE_WAIT = 16824202; // "Please wait" +const int DYNCONV_STRREF_PREVIOUS = 16824203; // "Previous" +const int DYNCONV_STRREF_NEXT = 16824204; // "Next" +const int DYNCONV_STRREF_ABORT_CONVO = 16824212; // "Abort" +const int DYNCONV_STRREF_EXIT_CONVO = 16183878; // "Exit" const string DYNCONV_SCRIPT = "DynConv_Script"; const string DYNCONV_VARIABLE = "DynConv_Var"; diff --git a/src/include/inc_item_props.nss b/src/include/inc_item_props.nss index b1edfc2..2d30330 100644 --- a/src/include/inc_item_props.nss +++ b/src/include/inc_item_props.nss @@ -1643,7 +1643,60 @@ int GetIsMagicItem(object oItem) int FeatToIprop(int nFeat) { switch(nFeat) - {//: Weapon Focus + { + //:: Weapon Proficiencies + case FEAT_WEAPON_PROFICIENCY_SHORTSWORD: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SHORTSWORD; + case FEAT_WEAPON_PROFICIENCY_LONGSWORD: return IP_CONST_FEAT_WEAPON_PROFICIENCY_LONGSWORD; + case FEAT_WEAPON_PROFICIENCY_BATTLEAXE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_BATTLEAXE; + case FEAT_WEAPON_PROFICIENCY_BASTARD_SWORD: return IP_CONST_FEAT_WEAPON_PROFICIENCY_BASTARD_SWORD; + case FEAT_WEAPON_PROFICIENCY_LIGHT_FLAIL: return IP_CONST_FEAT_WEAPON_PROFICIENCY_LIGHT_FLAIL; + case FEAT_WEAPON_PROFICIENCY_WARHAMMER: return IP_CONST_FEAT_WEAPON_PROFICIENCY_WARHAMMER; + case FEAT_WEAPON_PROFICIENCY_LONGBOW: return IP_CONST_FEAT_WEAPON_PROFICIENCY_LONGBOW; + case FEAT_WEAPON_PROFICIENCY_LIGHT_MACE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_LIGHT_MACE; + case FEAT_WEAPON_PROFICIENCY_HALBERD: return IP_CONST_FEAT_WEAPON_PROFICIENCY_HALBERD; + case FEAT_WEAPON_PROFICIENCY_SHORTBOW: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SHORTBOW; + case FEAT_WEAPON_PROFICIENCY_TWO_BLADED_SWORD: return IP_CONST_FEAT_WEAPON_PROFICIENCY_TWO_BLADED_SWORD; + case FEAT_WEAPON_PROFICIENCY_GREATSWORD: return IP_CONST_FEAT_WEAPON_PROFICIENCY_GREATSWORD; + case FEAT_WEAPON_PROFICIENCY_GREATAXE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_GREATAXE; + case FEAT_WEAPON_PROFICIENCY_DART: return IP_CONST_FEAT_WEAPON_PROFICIENCY_DART; + case FEAT_WEAPON_PROFICIENCY_DIRE_MACE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_DIRE_MACE; + case FEAT_WEAPON_PROFICIENCY_DOUBLE_AXE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_DOUBLE_AXE; + case FEAT_WEAPON_PROFICIENCY_HEAVY_FLAIL: return IP_CONST_FEAT_WEAPON_PROFICIENCY_HEAVY_FLAIL; + case FEAT_WEAPON_PROFICIENCY_LIGHT_HAMMER: return IP_CONST_FEAT_WEAPON_PROFICIENCY_LIGHT_HAMMER; + case FEAT_WEAPON_PROFICIENCY_HANDAXE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_HANDAXE; + case FEAT_WEAPON_PROFICIENCY_KAMA: return IP_CONST_FEAT_WEAPON_PROFICIENCY_KAMA; + case FEAT_WEAPON_PROFICIENCY_KATANA: return IP_CONST_FEAT_WEAPON_PROFICIENCY_KATANA; + case FEAT_WEAPON_PROFICIENCY_KUKRI: return IP_CONST_FEAT_WEAPON_PROFICIENCY_KUKRI; + case FEAT_WEAPON_PROFICIENCY_MORNINGSTAR: return IP_CONST_FEAT_WEAPON_PROFICIENCY_MORNINGSTAR; + case FEAT_WEAPON_PROFICIENCY_RAPIER: return IP_CONST_FEAT_WEAPON_PROFICIENCY_RAPIER; + case FEAT_WEAPON_PROFICIENCY_SCIMITAR: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SCIMITAR; + case FEAT_WEAPON_PROFICIENCY_SCYTHE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SCYTHE; + case FEAT_WEAPON_PROFICIENCY_SHORTSPEAR: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SHORTSPEAR; + case FEAT_WEAPON_PROFICIENCY_SHURIKEN: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SHURIKEN; + case FEAT_WEAPON_PROFICIENCY_SICKLE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SICKLE; + case FEAT_WEAPON_PROFICIENCY_SLING: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SLING; + case FEAT_WEAPON_PROFICIENCY_THROWING_AXE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_THROWING_AXE; + case FEAT_WEAPON_PROFICIENCY_TRIDENT: return IP_CONST_FEAT_WEAPON_PROFICIENCY_TRIDENT; + case FEAT_WEAPON_PROFICIENCY_DWARVEN_WARAXE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_DWARVEN_WARAXE; + case FEAT_WEAPON_PROFICIENCY_WHIP: return IP_CONST_FEAT_WEAPON_PROFICIENCY_WHIP; + case FEAT_WEAPON_PROFICIENCY_ELVEN_LIGHTBLADE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_ELVEN_LIGHTBLADE; + case FEAT_WEAPON_PROFICIENCY_ELVEN_THINBLADE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_ELVEN_THINBLADE; + case FEAT_WEAPON_PROFICIENCY_ELVEN_COURTBLADE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_ELVEN_COURTBLADE; + case FEAT_WEAPON_PROFICIENCY_LIGHT_LANCE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_LIGHT_LANCE; + case FEAT_WEAPON_PROFICIENCY_HEAVY_PICK: return IP_CONST_FEAT_WEAPON_PROFICIENCY_HEAVY_PICK; + case FEAT_WEAPON_PROFICIENCY_LIGHT_PICK: return IP_CONST_FEAT_WEAPON_PROFICIENCY_LIGHT_PICK; + case FEAT_WEAPON_PROFICIENCY_SAI: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SAI; + case FEAT_WEAPON_PROFICIENCY_NUNCHUKU: return IP_CONST_FEAT_WEAPON_PROFICIENCY_NUNCHUKU; + case FEAT_WEAPON_PROFICIENCY_FALCHION: return IP_CONST_FEAT_WEAPON_PROFICIENCY_FALCHION; + case FEAT_WEAPON_PROFICIENCY_SAP: return IP_CONST_FEAT_WEAPON_PROFICIENCY_SAP; + case FEAT_WEAPON_PROFICIENCY_KATAR: return IP_CONST_FEAT_WEAPON_PROFICIENCY_KATAR; + case FEAT_WEAPON_PROFICIENCY_HEAVY_MACE: return IP_CONST_FEAT_WEAPON_PROFICIENCY_HEAVY_MACE; + case FEAT_WEAPON_PROFICIENCY_MAUL: return IP_CONST_FEAT_WEAPON_PROFICIENCY_MAUL; + case FEAT_WEAPON_PROFICIENCY_DOUBLE_SCIMITAR: return IP_CONST_FEAT_WEAPON_PROFICIENCY_DOUBLE_SCIMITAR; + case FEAT_WEAPON_PROFICIENCY_GOAD: return IP_CONST_FEAT_WEAPON_PROFICIENCY_GOAD; + case FEAT_WEAPON_PROFICIENCY_EAGLE_CLAW: return IP_CONST_FEAT_WEAPON_PROFICIENCY_EAGLE_CLAW; + + //: Weapon Focus case FEAT_WEAPON_FOCUS_BASTARD_SWORD: return IP_CONST_FEAT_WEAPON_FOCUS_BASTARD_SWORD; case FEAT_WEAPON_FOCUS_BATTLE_AXE: return IP_CONST_FEAT_WEAPON_FOCUS_BATTLE_AXE; case FEAT_WEAPON_FOCUS_CLUB: return IP_CONST_FEAT_WEAPON_FOCUS_CLUB; diff --git a/src/include/inc_newspellbook.nss b/src/include/inc_newspellbook.nss index 542e2d5..539b842 100644 --- a/src/include/inc_newspellbook.nss +++ b/src/include/inc_newspellbook.nss @@ -20,6 +20,8 @@ Add class to GetCasterLvl() in prc_inc_spells Add Practiced Spellcaster feat to feat.2da and to PracticedSpellcasting() in prc_inc_castlvl Run the assemble_spellbooks.bat file Make the prc_* scripts in newspellbook. The filenames can be found under the spell entries for the class in spells.2da. +Update the fileends for all relevant files in inc_switch_setup +Delete prc_data in the \database\ folder before testing new spells. Spont: Make cls_spgn_*.2da @@ -41,6 +43,8 @@ Add class to prc_amagsys_gain if(CheckMissingSpells(oPC, CLASS_TYPE_SORCERER, Mi Add class to ExecuteScript("prc_amagsys_gain", oPC) list in EvalPRCFeats in prc_inc_function Run the assemble_spellbooks.bat file Make the prc_* scripts in newspellbook +Update the fileends for all relevant files in inc_switch_setup +Delete prc_data in the \database\ folder before testing new spells. prc_classes.2da entry: Label - name for the class diff --git a/src/include/inc_switch_setup.nss b/src/include/inc_switch_setup.nss index d21b16c..15182a9 100644 --- a/src/include/inc_switch_setup.nss +++ b/src/include/inc_switch_setup.nss @@ -221,9 +221,9 @@ void SetDefaultFileEnds() SetPRCSwitch("PRC_FILE_END_cls_spcr_bard", 144); SetPRCSwitch("PRC_FILE_END_cls_spcr_beguil", 142); SetPRCSwitch("PRC_FILE_END_cls_spcr_blkgrd", 47); - SetPRCSwitch("PRC_FILE_END_cls_spcr_dnecro", 137); + SetPRCSwitch("PRC_FILE_END_cls_spcr_dnecro", 138); SetPRCSwitch("PRC_FILE_END_cls_spcr_duskbl", 69); - SetPRCSwitch("PRC_FILE_END_cls_spcr_favsol", 290); + SetPRCSwitch("PRC_FILE_END_cls_spcr_favsol", 300); SetPRCSwitch("PRC_FILE_END_cls_spcr_harper", 35); SetPRCSwitch("PRC_FILE_END_cls_spcr_healer", 77); SetPRCSwitch("PRC_FILE_END_cls_spcr_hexbl", 73); @@ -251,9 +251,9 @@ void SetDefaultFileEnds() SetPRCSwitch("PRC_FILE_END_cls_spell_bard", 169); SetPRCSwitch("PRC_FILE_END_cls_spell_beguil", 119); SetPRCSwitch("PRC_FILE_END_cls_spell_blkgrd", 163); - SetPRCSwitch("PRC_FILE_END_cls_spell_dnecro", 134); + SetPRCSwitch("PRC_FILE_END_cls_spell_dnecro", 135); SetPRCSwitch("PRC_FILE_END_cls_spell_duskbl", 84); - SetPRCSwitch("PRC_FILE_END_cls_spell_favsol", 363); + SetPRCSwitch("PRC_FILE_END_cls_spell_favsol", 373); SetPRCSwitch("PRC_FILE_END_cls_spell_harper", 21); SetPRCSwitch("PRC_FILE_END_cls_spell_healer", 271); SetPRCSwitch("PRC_FILE_END_cls_spell_hexbl", 79); @@ -267,7 +267,7 @@ void SetDefaultFileEnds() SetPRCSwitch("PRC_FILE_END_cls_spell_sod", 110); SetPRCSwitch("PRC_FILE_END_cls_spell_sohei", 131); SetPRCSwitch("PRC_FILE_END_cls_spell_sol", 114); - SetPRCSwitch("PRC_FILE_END_cls_spell_sorc", 541); + SetPRCSwitch("PRC_FILE_END_cls_spell_sorc", 550); SetPRCSwitch("PRC_FILE_END_cls_spell_suel", 160); SetPRCSwitch("PRC_FILE_END_cls_spell_templ", 95); SetPRCSwitch("PRC_FILE_END_cls_spell_tfshad", 70); @@ -355,7 +355,7 @@ void SetDefaultFileEnds() SetPRCSwitch("PRC_FILE_END_des_crft_poison", 100); SetPRCSwitch("PRC_FILE_END_des_crft_props", 27); SetPRCSwitch("PRC_FILE_END_des_crft_scroll", 3999); - SetPRCSwitch("PRC_FILE_END_des_crft_spells", 19348); + SetPRCSwitch("PRC_FILE_END_des_crft_spells", 20000); SetPRCSwitch("PRC_FILE_END_des_crft_weapon", 29); SetPRCSwitch("PRC_FILE_END_des_cutconvdur", 26); SetPRCSwitch("PRC_FILE_END_des_feat2item", 1000); @@ -423,7 +423,7 @@ void SetDefaultFileEnds() SetPRCSwitch("PRC_FILE_END_iprp_damvulcost", 7); SetPRCSwitch("PRC_FILE_END_iprp_decvalue1", 9); SetPRCSwitch("PRC_FILE_END_iprp_decvalue2", 9); - SetPRCSwitch("PRC_FILE_END_iprp_feats", 24819); + SetPRCSwitch("PRC_FILE_END_iprp_feats", 26999); SetPRCSwitch("PRC_FILE_END_iprp_immuncost", 7); SetPRCSwitch("PRC_FILE_END_iprp_immunity", 9); SetPRCSwitch("PRC_FILE_END_iprp_incvalue1", 9); @@ -458,11 +458,11 @@ void SetDefaultFileEnds() SetPRCSwitch("PRC_FILE_END_iprp_soakcost", 50); SetPRCSwitch("PRC_FILE_END_iprp_speed_dec", 9); SetPRCSwitch("PRC_FILE_END_iprp_speed_enh", 9); - SetPRCSwitch("PRC_FILE_END_iprp_spellcost", 243); + SetPRCSwitch("PRC_FILE_END_iprp_spellcost", 298); SetPRCSwitch("PRC_FILE_END_iprp_spellcstr", 42); SetPRCSwitch("PRC_FILE_END_iprp_spelllvcost", 9); SetPRCSwitch("PRC_FILE_END_iprp_spelllvlimm", 9); - SetPRCSwitch("PRC_FILE_END_iprp_spells", 1456); + SetPRCSwitch("PRC_FILE_END_iprp_spells", 1552); SetPRCSwitch("PRC_FILE_END_iprp_spellshl", 7); SetPRCSwitch("PRC_FILE_END_iprp_srcost", 99); SetPRCSwitch("PRC_FILE_END_iprp_staminacost", -1); @@ -492,9 +492,9 @@ void SetDefaultFileEnds() SetPRCSwitch("PRC_FILE_END_itmwizwands", 38); SetPRCSwitch("PRC_FILE_END_keymap", 70); SetPRCSwitch("PRC_FILE_END_lightcolor", 32); - SetPRCSwitch("PRC_FILE_END_loadhints", 88); + SetPRCSwitch("PRC_FILE_END_loadhints", 101); SetPRCSwitch("PRC_FILE_END_loadscreens", 259); - SetPRCSwitch("PRC_FILE_END_masterfeats", 113); + SetPRCSwitch("PRC_FILE_END_masterfeats", 125); SetPRCSwitch("PRC_FILE_END_materialcomp", 200); SetPRCSwitch("PRC_FILE_END_metamagic", 6); SetPRCSwitch("PRC_FILE_END_namefilter", 3); diff --git a/src/include/moi_inc_moifunc.nss b/src/include/moi_inc_moifunc.nss index a2b0a3b..62af858 100644 --- a/src/include/moi_inc_moifunc.nss +++ b/src/include/moi_inc_moifunc.nss @@ -1170,7 +1170,10 @@ int GetMaxEssentiaCapacityFeat(object oMeldshaper) { int nMax = 1; // Always can invest one int nHD = GetHitDice(oMeldshaper); - if (nHD >= 31) nMax = 5; + if (nHD >= 61) nMax = 8; + else if (nHD >= 51) nMax = 7; + else if (nHD >= 41) nMax = 6; + else if (nHD >= 31) nMax = 5; else if (nHD >= 18) nMax = 4; else if (nHD >= 12) nMax = 3; else if (nHD >= 6) nMax = 2; diff --git a/src/include/prc_effect_inc.nss b/src/include/prc_effect_inc.nss index 4552481..8a12d42 100644 --- a/src/include/prc_effect_inc.nss +++ b/src/include/prc_effect_inc.nss @@ -78,7 +78,7 @@ void PRCRemoveSpellEffects(int nSpell_ID, object oCaster, object oTarget); /** * Target is immune to gaze attacks * - * @return the Dazzle effect + * @return the Gaze Immunity effect */ effect EffectGazeImmune(); @@ -185,6 +185,7 @@ int GetIsShaken(object oTarget); ////////////////////////////////////////////////// #include "prc_inc_castlvl" // get prc_racial_const, prc_inc_nwscript, prc_inc_newip +#include "inc_epicspelldef" ////////////////////////////////////////////////// /* Internal functions */ @@ -746,7 +747,6 @@ effect EffectImmunityMiscAll() //:: Immunity to all gaze attacks effect EffectGazeImmune() { - effect eBlank; effect eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_CHARM); eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_CONFUSION); @@ -768,6 +768,23 @@ effect EffectGazeImmune() return eReturn; } +//:: Immunity to all perification attacks +effect EffectPetrificationImmune() +{ + effect eReturn = EffectSpellImmunity(SPELLABILITY_TOUCH_PETRIFY); + eReturn = EffectSpellImmunity(SPELLABILITY_BREATH_PETRIFY); + eReturn = EffectSpellImmunity(SPELL_FLESH_TO_STONE); + eReturn = EffectSpellImmunity(SPELL_STONEHOLD); + eReturn = EffectSpellImmunity(SPELL_EPIC_A_STONE); + eReturn = EffectSpellImmunity(POWER_CRYSTALLIZE); + eReturn = EffectSpellImmunity(MELD_BASILISK_MASK); + eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_PETRIFY); + + eReturn = TagEffect(eReturn, "PRCPetrificationImmune"); + + return eReturn; +} + int GetIsShaken(object oTarget) { effect eEffect = GetFirstEffect(oTarget); diff --git a/src/include/prc_getbest_inc.nss b/src/include/prc_getbest_inc.nss index a17eb0a..a0efeca 100644 --- a/src/include/prc_getbest_inc.nss +++ b/src/include/prc_getbest_inc.nss @@ -400,5 +400,4 @@ int GetBestAvailableSpell(object oTarget) if(nBestSpell == 99999) nBestSpell = GetBestL1Spell(oTarget, nBestSpell); if(nBestSpell == 99999) nBestSpell = GetBestL0Spell(oTarget, nBestSpell); return nBestSpell; -} - +} \ No newline at end of file diff --git a/src/include/prc_inc_castlvl.nss b/src/include/prc_inc_castlvl.nss index 8336a62..0c1a8be 100644 --- a/src/include/prc_inc_castlvl.nss +++ b/src/include/prc_inc_castlvl.nss @@ -3859,7 +3859,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster); if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_ARCHIVIST, oCaster)) - nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + + if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_ARCHIVIST, oCaster)) + nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster); if(GetHasFeat(FEAT_BFZ_SPELLCASTING_ARCHIVIST, oCaster)) nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2; @@ -4193,7 +4196,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster); if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_CLERIC, oCaster)) - nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + + if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_CLERIC, oCaster)) + nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster); if(GetHasFeat(FEAT_BFZ_SPELLCASTING_CLERIC, oCaster)) nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2; @@ -4309,9 +4315,12 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster); /* if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_DRUID, oCaster)) - nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); */ + + if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_DRUID, oCaster)) + nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster); - if(GetHasFeat(FEAT_BFZ_SPELLCASTING_DRUID, oCaster)) +/* if(GetHasFeat(FEAT_BFZ_SPELLCASTING_DRUID, oCaster)) nDivine += GetLevelByClass(CLASS_TYPE_BFZ, oCaster + 1) / 2 */ // if(GetHasFeat(FEAT_BRIMSTONE_SPEAKER_SPELLCASTING_DRUID, oCaster)) @@ -4421,7 +4430,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster); if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_FAVOURED_SOUL, oCaster)) - nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + + if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_FAVOURED_SOUL, oCaster)) + nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster); if(GetHasFeat(FEAT_BFZ_SPELLCASTING_FAVOURED_SOUL, oCaster)) nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2; @@ -4534,7 +4546,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); */ /* if(GetHasFeat(FEAT_BFZ_SPELLCASTING_HEALER, oCaster)) - nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2; */ + nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2; */ + + if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_HEALER, oCaster)) + nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster); if(GetHasFeat(FEAT_BRIMSTONE_SPEAKER_SPELLCASTING_HEALER, oCaster)) nDivine += (GetLevelByClass(CLASS_TYPE_BRIMSTONE_SPEAKER, oCaster) + 1) / 2; @@ -4641,7 +4656,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster); if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_JUSTICEWW, oCaster)) - nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + + if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_JOWAW, oCaster)) + nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster); if(GetHasFeat(FEAT_BFZ_SPELLCASTING_JUSTICEWW, oCaster)) nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2; @@ -4742,6 +4760,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) if(GetHasFeat(FEAT_SWIFT_WING_SPELLCASTING_KNIGHT_CHALICE, oCaster)) nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster); + + if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_KOTC, oCaster)) + nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster); /* if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_KNIGHT_CHALICE, oCaster)) nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); @@ -4849,6 +4870,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) if(GetHasFeat(FEAT_SWIFT_WING_SPELLCASTING_KNIGHT_MIDDLECIRCLE, oCaster)) nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster); + + if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_KOTMC, oCaster)) + nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster); /* if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_KNIGHT_MIDDLECIRCLE, oCaster)) nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); @@ -4962,6 +4986,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) if(GetHasFeat(FEAT_SWIFT_WING_SPELLCASTING_NENTYAR_HUNTER, oCaster)) nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster); + + if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_NENTYAR_HUNTER, oCaster)) + nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster); /* if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_NENTYAR_HUNTER, oCaster)) nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); */ @@ -5164,6 +5191,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) if(GetHasFeat(FEAT_SWIFT_WING_SPELLCASTING_PALADIN, oCaster)) nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster); + + if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_PALADIN, oCaster)) + nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster); /* if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_PALADIN, oCaster)) nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); @@ -5272,7 +5302,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster); if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_RANGER, oCaster)) - nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + + if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_RANGER, oCaster)) + nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster); if(GetHasFeat(FEAT_BFZ_SPELLCASTING_RANGER, oCaster)) nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2; @@ -5385,7 +5418,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster); if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_OASHAMAN, oCaster)) - nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + + if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_OASHAMAN, oCaster)) + nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster); if(GetHasFeat(FEAT_BFZ_SPELLCASTING_OASHAMAN, oCaster)) nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2; @@ -5599,7 +5635,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster); if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_SOHEI, oCaster)) - nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); + + if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_SOHEI, oCaster)) + nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster); if(GetHasFeat(FEAT_BFZ_SPELLCASTING_SOHEI, oCaster)) nDivine += (GetLevelByClass(CLASS_TYPE_BFZ, oCaster) + 1) / 2; @@ -5704,6 +5743,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID) if(GetHasFeat(FEAT_SWIFT_WING_SPELLCASTING_SOL, oCaster)) nDivine += GetLevelByClass(CLASS_TYPE_SWIFT_WING, oCaster); + + if(GetHasFeat(FEAT_VERDANT_LORD_SPELLCASTING_SOL, oCaster)) + nDivine += GetLevelByClass(CLASS_TYPE_VERDANT_LORD, oCaster); /* if(GetHasFeat(FEAT_TENEBROUS_APOSTATE_SPELLCASTING_SOL, oCaster)) nDivine += GetLevelByClass(CLASS_TYPE_TENEBROUS_APOSTATE, oCaster); diff --git a/src/include/prc_inc_core.nss b/src/include/prc_inc_core.nss index 099c3ac..91c5ba1 100644 --- a/src/include/prc_inc_core.nss +++ b/src/include/prc_inc_core.nss @@ -410,6 +410,8 @@ int PRCGetSpellLevelForClass(int nSpell, int nClass) sSpellLevel = Get2DACache("spells", "Cleric", nSpell); else if (nClass == CLASS_TYPE_BARD) sSpellLevel = Get2DACache("spells", "Bard", nSpell); + else if (nClass == CLASS_TYPE_ASSASSIN) + sSpellLevel = Get2DACache("spells", "Assassin", nSpell); else if (nClass == CLASS_TYPE_CULTIST_SHATTERED_PEAK) sSpellLevel = Get2DACache("spells", "Cultist", nSpell); else if (nClass == CLASS_TYPE_NENTYAR_HUNTER) diff --git a/src/include/prc_inc_fork.nss b/src/include/prc_inc_fork.nss index 2b19f97..5cefd1d 100644 --- a/src/include/prc_inc_fork.nss +++ b/src/include/prc_inc_fork.nss @@ -23,11 +23,14 @@ const int FEAT_TYPE_IMPROVED_CRITICAL = 5; const int FEAT_TYPE_OVERWHELMING_CRITICAL = 6; const int FEAT_TYPE_DEVASTATING_CRITICAL = 7; const int FEAT_TYPE_WEAPON_OF_CHOICE = 8; +const int FEAT_TYPE_WEAPON_PROFICIENCY = 9; ////////////////////////////////////////////////// /* Function prototypes */ ////////////////////////////////////////////////// + int GetProficiencyFeatOfWeaponType(int iWeaponType); + /** * Returns the appropriate weapon feat given a weapon type. * @@ -210,10 +213,85 @@ int GetFeatOfWeaponType(int iWeaponType, int iFeatType) case FEAT_TYPE_OVERWHELMING_CRITICAL: return GetOverwhelmingCriticalFeatOfWeaponType(iWeaponType); case FEAT_TYPE_DEVASTATING_CRITICAL: return GetDevastatingCriticalFeatOfWeaponType(iWeaponType); case FEAT_TYPE_WEAPON_OF_CHOICE: return GetWeaponOfChoiceFeatOfWeaponType(iWeaponType); + case FEAT_TYPE_WEAPON_PROFICIENCY: return GetProficiencyFeatOfWeaponType(iWeaponType); } return -1; } +int GetProficiencyFeatOfWeaponType(int iWeaponType) +{ + switch(iWeaponType) + { + case BASE_ITEM_CBLUDGWEAPON: + case BASE_ITEM_CPIERCWEAPON: + case BASE_ITEM_CSLASHWEAPON: + case BASE_ITEM_CSLSHPRCWEAP: return FEAT_WEAPON_PROFICIENCY_CREATURE; + case BASE_ITEM_INVALID: return FEAT_IMPROVED_UNARMED_STRIKE; + + case BASE_ITEM_BASTARDSWORD: return FEAT_WEAPON_PROFICIENCY_BASTARD_SWORD; + case BASE_ITEM_BATTLEAXE: return FEAT_WEAPON_PROFICIENCY_BATTLEAXE; + case BASE_ITEM_CLUB: return FEAT_WEAPON_PROFICIENCY_CLUB; + case BASE_ITEM_DAGGER: return FEAT_WEAPON_PROFICIENCY_DAGGER; + case BASE_ITEM_DART: return FEAT_WEAPON_PROFICIENCY_DART; + case BASE_ITEM_DIREMACE: return FEAT_WEAPON_PROFICIENCY_DIRE_MACE; + case BASE_ITEM_DOUBLEAXE: return FEAT_WEAPON_PROFICIENCY_DOUBLE_AXE; + case BASE_ITEM_DWARVENWARAXE: return FEAT_WEAPON_PROFICIENCY_DWARVEN_WARAXE; + case BASE_ITEM_GREATAXE: return FEAT_WEAPON_PROFICIENCY_GREATAXE; + case BASE_ITEM_GREATSWORD: return FEAT_WEAPON_PROFICIENCY_GREATSWORD; + case BASE_ITEM_HALBERD: return FEAT_WEAPON_PROFICIENCY_HALBERD; + case BASE_ITEM_HANDAXE: return FEAT_WEAPON_PROFICIENCY_HANDAXE; + case BASE_ITEM_HEAVYCROSSBOW: return FEAT_WEAPON_PROFICIENCY_HEAVY_XBOW; + case BASE_ITEM_HEAVYFLAIL: return FEAT_WEAPON_PROFICIENCY_HEAVY_FLAIL; + case BASE_ITEM_KAMA: return FEAT_WEAPON_PROFICIENCY_KAMA; + case BASE_ITEM_KATANA: return FEAT_WEAPON_PROFICIENCY_KATANA; + case BASE_ITEM_KUKRI: return FEAT_WEAPON_PROFICIENCY_KUKRI; + case BASE_ITEM_LIGHTCROSSBOW: return FEAT_WEAPON_PROFICIENCY_LIGHT_XBOW; + case BASE_ITEM_LIGHTFLAIL: return FEAT_WEAPON_PROFICIENCY_LIGHT_FLAIL; + case BASE_ITEM_LIGHTHAMMER: return FEAT_WEAPON_PROFICIENCY_LIGHT_HAMMER; + case BASE_ITEM_LIGHTMACE: return FEAT_WEAPON_PROFICIENCY_LIGHT_MACE; + case BASE_ITEM_LONGBOW: return FEAT_WEAPON_PROFICIENCY_LONGBOW; + case BASE_ITEM_LONGSWORD: return FEAT_WEAPON_PROFICIENCY_LONGSWORD; + case BASE_ITEM_MORNINGSTAR: return FEAT_WEAPON_PROFICIENCY_MORNINGSTAR; + case BASE_ITEM_QUARTERSTAFF: return FEAT_WEAPON_PROFICIENCY_QUARTERSTAFF; + case BASE_ITEM_MAGICSTAFF: return FEAT_WEAPON_PROFICIENCY_QUARTERSTAFF; + case BASE_ITEM_RAPIER: return FEAT_WEAPON_PROFICIENCY_RAPIER; + case BASE_ITEM_SCIMITAR: return FEAT_WEAPON_PROFICIENCY_SCIMITAR; + case BASE_ITEM_SCYTHE: return FEAT_WEAPON_PROFICIENCY_SCYTHE; + case BASE_ITEM_SHORTBOW: return FEAT_WEAPON_PROFICIENCY_SHORTBOW; + case BASE_ITEM_SHORTSPEAR: return FEAT_WEAPON_PROFICIENCY_SHORTSPEAR; + case BASE_ITEM_SHORTSWORD: return FEAT_WEAPON_PROFICIENCY_SHORTSWORD; + case BASE_ITEM_SHURIKEN: return FEAT_WEAPON_PROFICIENCY_SHURIKEN; + case BASE_ITEM_SICKLE: return FEAT_WEAPON_PROFICIENCY_SICKLE; + case BASE_ITEM_SLING: return FEAT_WEAPON_PROFICIENCY_SLING; + case BASE_ITEM_THROWINGAXE: return FEAT_WEAPON_PROFICIENCY_THROWING_AXE; + case BASE_ITEM_TRIDENT: return FEAT_WEAPON_PROFICIENCY_TRIDENT; + case BASE_ITEM_TWOBLADEDSWORD: return FEAT_WEAPON_PROFICIENCY_TWO_BLADED_SWORD; + case BASE_ITEM_WARHAMMER: return FEAT_WEAPON_PROFICIENCY_WARHAMMER; + case BASE_ITEM_WHIP: return FEAT_WEAPON_PROFICIENCY_WHIP; + + //:: new item types + case BASE_ITEM_DOUBLE_SCIMITAR: return FEAT_WEAPON_PROFICIENCY_DOUBLE_SCIMITAR; + case BASE_ITEM_EAGLE_CLAW: return FEAT_WEAPON_PROFICIENCY_EAGLE_CLAW; + case BASE_ITEM_ELVEN_COURTBLADE: return FEAT_WEAPON_PROFICIENCY_ELVEN_COURTBLADE; + case BASE_ITEM_ELVEN_LIGHTBLADE: return FEAT_WEAPON_PROFICIENCY_ELVEN_LIGHTBLADE; + case BASE_ITEM_ELVEN_THINBLADE: return FEAT_WEAPON_PROFICIENCY_ELVEN_THINBLADE; + case BASE_ITEM_FALCHION: return FEAT_WEAPON_PROFICIENCY_FALCHION; + case BASE_ITEM_GOAD: return FEAT_WEAPON_PROFICIENCY_GOAD; + case BASE_ITEM_HEAVY_MACE: return FEAT_WEAPON_PROFICIENCY_HEAVY_MACE; + case BASE_ITEM_HEAVY_PICK: return FEAT_WEAPON_PROFICIENCY_HEAVY_PICK; + case BASE_ITEM_KATAR: return FEAT_WEAPON_PROFICIENCY_KATAR; + case BASE_ITEM_LIGHT_LANCE: return FEAT_WEAPON_PROFICIENCY_LIGHT_LANCE; + case BASE_ITEM_LIGHT_PICK: return FEAT_WEAPON_PROFICIENCY_LIGHT_PICK; + case BASE_ITEM_MAUL: return FEAT_WEAPON_PROFICIENCY_MAUL; + case BASE_ITEM_NUNCHAKU: return FEAT_WEAPON_PROFICIENCY_NUNCHAKU; + case BASE_ITEM_SAI: return FEAT_WEAPON_PROFICIENCY_SAI; + case BASE_ITEM_SAP: return FEAT_WEAPON_PROFICIENCY_SAP; + } + + return -1; +} + + int GetFocusFeatOfWeaponType(int iWeaponType) { switch(iWeaponType) @@ -844,4 +922,6 @@ int PRCLargeWeaponCheck(int iBaseType, int nSize) } } return sTest != "" && sTest != IntToString(nSize); -} \ No newline at end of file +} + +//::void main(){} \ No newline at end of file diff --git a/src/include/prc_inc_function.nss b/src/include/prc_inc_function.nss index aa47614..f1a0fea 100644 --- a/src/include/prc_inc_function.nss +++ b/src/include/prc_inc_function.nss @@ -109,7 +109,7 @@ void SetupCharacterData(object oPC) case CLASS_TYPE_ARCANE_DUELIST: sScript = "prc_arcduel"; break; case CLASS_TYPE_ARCHIVIST: sScript = "prc_archivist"; iData |= 0x01; break; case CLASS_TYPE_ASSASSIN: break; - //case CLASS_TYPE_BAELNORN: sScript = "prc_baelnorn"; break; + //case CLASS_TYPE_BAELNORN: sScript = "prc_baelnorn"; break; case CLASS_TYPE_BARD: iData |= 0x07; break; case CLASS_TYPE_BATTLESMITH: sScript = "prc_battlesmith"; break; case CLASS_TYPE_BEGUILER: iData |= 0x03; break; diff --git a/src/include/prc_inc_json.nss b/src/include/prc_inc_json.nss index 749c551..e976ce1 100644 --- a/src/include/prc_inc_json.nss +++ b/src/include/prc_inc_json.nss @@ -97,10 +97,38 @@ struct SizeModifiers int dexSkillMod; }; +//:: Returns ability mod for score +int GetAbilityModFromValue(int nAbilityValue) +{ + int nMod = (nAbilityValue - 10) / 2; + + // Adjust if below 10 and odd + if (nAbilityValue < 10 && (nAbilityValue % 2) != 0) + { + nMod = nMod - 1; + } + return nMod; +} + + //::---------------------------------------------| //:: JSON functions | //::---------------------------------------------| +//:: Returns the Constitution value from a GFF creature UTC +int json_GetCONValue(json jCreature) +{ + int nCon = 0; // default if missing + + // Check if the Con field exists + if (GffGetFieldExists(jCreature, "Con")) + { + nCon = JsonGetInt(GffGetByte(jCreature, "Con")); + } + + return nCon; +} + //:: Returns the integer value of a VarTable entry named sVarName, or 0 if not found. int json_GetLocalIntFromVarTable(json jCreature, string sVarName) { @@ -141,12 +169,12 @@ int json_GetLocalIntFromVarTable(json jCreature, string sVarName) return 0; } -//:: Returns the total Hit Dice from a JSON creature GFF. -int json_GetCreatureHD(json jGff) +//:: Returns the total Hit Dice from a JSON'd creature GFF. +int json_GetCreatureHD(json jCreature) { int nHD = 0; - json jClasses = GffGetList(jGff, "ClassList"); + json jClasses = GffGetList(jCreature, "ClassList"); if (jClasses == JsonNull()) return 0; @@ -170,6 +198,30 @@ int json_GetCreatureHD(json jGff) return nHD; } + +json json_RecalcMaxHP(json jCreature, int iHitDieValue) +{ + int iHD = json_GetCreatureHD(jCreature); + int iCON = json_GetCONValue(jCreature); + int iMod = GetAbilityModFromValue(iCON); + + int nConBonusHP = iMod * iHD; + int iNewMaxHP = (iHitDieValue * iHD); /* nConBonusHP */ + + //jCreature = GffReplaceShort(jCreature, "MaxHitPoints", iNewMaxHP); + jCreature = GffReplaceShort(jCreature, "CurrentHitPoints", iNewMaxHP); + jCreature = GffReplaceShort(jCreature, "HitPoints", iNewMaxHP); + +/* SendMessageToPC(GetFirstPC(), "HD = " + IntToString(iHD)); + SendMessageToPC(GetFirstPC(), "HitDieValue = " + IntToString(iHitDieValue)); + SendMessageToPC(GetFirstPC(), "CON = " + IntToString(iCON)); + SendMessageToPC(GetFirstPC(), "Mod = " + IntToString(iMod)); + SendMessageToPC(GetFirstPC(), "New HP = " + IntToString(iNewMaxHP)); */ + + return jCreature; +} + + //:: Reads ABILITY_TO_INCREASE from creature's VarTable and applies stat boosts based on increased HD json json_ApplyAbilityBoostFromHD(json jCreature, int nOriginalHD, int nModifierCap) { @@ -180,7 +232,7 @@ json json_ApplyAbilityBoostFromHD(json jCreature, int nOriginalHD, int nModifier int nAbilityToIncrease = json_GetLocalIntFromVarTable(jCreature, "ABILITY_TO_INCREASE"); if (nAbilityToIncrease < 0 || nAbilityToIncrease > 5) { - if(DEBUG) DoDebug("json_ApplyAbilityBoostFromHD: Invalid ABILITY_TO_INCREASE value: " + IntToString(nAbilityToIncrease)); + DoDebug("json_ApplyAbilityBoostFromHD: Invalid ABILITY_TO_INCREASE value: " + IntToString(nAbilityToIncrease)); return jCreature; // Invalid ability index } @@ -188,7 +240,7 @@ json json_ApplyAbilityBoostFromHD(json jCreature, int nOriginalHD, int nModifier json jClassList = GffGetList(jCreature, "ClassList"); if (jClassList == JsonNull()) { - if(DEBUG) DoDebug("json_ApplyAbilityBoostFromHD: Failed to get ClassList"); + DoDebug("json_ApplyAbilityBoostFromHD: Failed to get ClassList"); return jCreature; } @@ -211,7 +263,7 @@ json json_ApplyAbilityBoostFromHD(json jCreature, int nOriginalHD, int nModifier if (nCurrentTotalHD <= 0) { - if(DEBUG) DoDebug("json_ApplyAbilityBoostFromHD: No valid Hit Dice found"); + DoDebug("json_ApplyAbilityBoostFromHD: No valid Hit Dice found"); return jCreature; } @@ -273,7 +325,7 @@ json json_ApplyAbilityBoostFromHD(json jCreature, int nOriginalHD, int nModifier return jCreature; } -//:: Adjust a skill by its ID (more efficient than name lookup) +//:: Adjust a skill by its ID json json_AdjustCreatureSkillByID(json jCreature, int nSkillID, int nMod) { // Get the SkillList @@ -470,7 +522,7 @@ int json_GetArraySize(json jArray) return iSize; } -//:: Directly modifies oCreature's Base Natural AC if iNewAC is higher. +//:: Directly updates oCreature's Base Natural AC if iNewAC is higher. //:: json json_UpdateBaseAC(json jCreature, int iNewAC) { @@ -493,6 +545,26 @@ json json_UpdateBaseAC(json jCreature, int iNewAC) } } +//:: Increases jCreature's Natural AC by iAddAC. +//:: +json json_IncreaseBaseAC(json jCreature, int iAddAC) +{ + json jBaseAC = GffGetByte(jCreature, "NaturalAC"); + + if (jBaseAC == JsonNull()) + { + return JsonNull(); + } + else + { + int nBaseAC = JsonGetInt(jBaseAC); // convert JSON number -> int + int nNewAC = nBaseAC + iAddAC; + + jCreature = GffReplaceByte(jCreature, "NaturalAC", nNewAC); + return jCreature; + } +} + //:: Directly modifies jCreature's Challenge Rating. //:: This is useful for most XP calculations. json json_UpdateCR(json jCreature, int nBaseCR, int nCRMod) @@ -510,8 +582,7 @@ json json_UpdateCR(json jCreature, int nBaseCR, int nCRMod) //:: Directly modifies ability scores in a creature's JSON GFF. //:: -json json_UpdateTemplateStats(json jCreature, int iModStr = 0, int iModDex = 0, int iModCon = 0, - int iModInt = 0, int iModWis = 0, int iModCha = 0) +json json_UpdateTemplateStats(json jCreature, int iModStr = 0, int iModDex = 0, int iModCon = 0, int iModInt = 0, int iModWis = 0, int iModCha = 0) { int iCurrent; @@ -745,6 +816,37 @@ json json_AdjustCreatureSize(json jCreature, int nSizeDelta) return jCreature; } +//:: Changes jCreature's creature type. +json JsonModifyRacialType(json jCreature, int nNewRacialType) +{ + if(DEBUG)DoDebug("prc_inc_function >> JsonModifyRacialType: Entering function"); + + // Retrieve the RacialType field + json jRacialTypeField = JsonObjectGet(jCreature, "Race"); + + if (JsonGetType(jRacialTypeField) == JSON_TYPE_NULL) + { + DoDebug("prc_inc_function >> JsonModifyRacialType: JsonGetType error 1: " + JsonGetError(jRacialTypeField)); + //SpeakString("JsonGetType error 1: " + JsonGetError(jRacialTypeField)); + return JsonNull(); + } + + // Retrieve the value to modify + json jRacialTypeValue = JsonObjectGet(jRacialTypeField, "value"); + + if (JsonGetType(jRacialTypeValue) != JSON_TYPE_INTEGER) + { + DoDebug("prc_inc_function >> JsonModifyRacialType: JsonGetType error 2: " + JsonGetError(jRacialTypeValue)); + //SpeakString("JsonGetType error 2: " + JsonGetError(jRacialTypeValue)); + return JsonNull(); + } + + jCreature = GffReplaceByte(jCreature, "Race", nNewRacialType); + + // Return the new creature object + return jCreature; +} + //:: Test void //:: void main (){} \ No newline at end of file diff --git a/src/include/prc_inc_material.nss b/src/include/prc_inc_material.nss index dc050aa..bb84f86 100644 --- a/src/include/prc_inc_material.nss +++ b/src/include/prc_inc_material.nss @@ -430,8 +430,8 @@ string GetMaterialName( int iMaterialType, int bLowerCase = FALSE) case IP_MATERIAL_ROPE_GIANT_HAIR: sName = IP_MATERIAL_NAME_ROPE_GIANT_HAIR; break; case IP_MATERIAL_OBSIDIAN: sName = IP_MATERIAL_NAME_OBSIDIAN; break; case IP_MATERIAL_BAMBOO: sName = IP_MATERIAL_NAME_BAMBOO; break; - case IP_MATERIAL_POTTERY: sName = IP_MATERIAL_NAME_POTTERY; break; - case IP_MATERIAL_GLASSTEEL: sName = IP_MATERIAL_NAME_GLASSTEEL; break; + case IP_MATERIAL_POTTERY: sName = IP_MATERIAL_NAME_POTTERY; break; + case IP_MATERIAL_GLASSTEEL: sName = IP_MATERIAL_NAME_GLASSTEEL; break; case IP_MATERIAL_HERB: sName = IP_MATERIAL_NAME_HERB; break; default: return ""; diff --git a/src/include/prc_inc_nwscript.nss b/src/include/prc_inc_nwscript.nss index 8ebc821..4671756 100644 --- a/src/include/prc_inc_nwscript.nss +++ b/src/include/prc_inc_nwscript.nss @@ -572,7 +572,10 @@ int GetMaxEssentiaCapacity(object oMeldshaper, int nClass, int nMeld) { int nMax = 1; // Always can invest one int nHD = GetHitDice(oMeldshaper); - if (nHD >= 31) nMax = 5; + if (nHD >= 61) nMax = 8; + else if (nHD >= 51) nMax = 7; + else if (nHD >= 41) nMax = 6; + else if (nHD >= 31) nMax = 5; else if (nHD >= 18) nMax = 4; else if (nHD >= 12) nMax = 3; else if (nHD >= 6) nMax = 2; diff --git a/src/include/prc_inc_onhit.nss b/src/include/prc_inc_onhit.nss index 3f0da67..ab68887 100644 --- a/src/include/prc_inc_onhit.nss +++ b/src/include/prc_inc_onhit.nss @@ -808,7 +808,24 @@ int GetIsOnHitCastSpell(object oSpellTarget = OBJECT_INVALID, object oSpellCastI if (DEBUG) DoDebug("GetIsOnHitCastSpell: item "+GetName(oSpellCastItem)+" is armor; attacker = "+GetName(oAttacker)+", defender = "+GetName(oDefender)); } // is the spell type item a weapon? - else if (iWeaponType == StringToInt(Get2DACache("baseitems", "WeaponType", iBaseType))) + int nWT = StringToInt(Get2DACache("baseitems", "WeaponType", iBaseType)); + if (nWT > 0) + { + if (oSpellTarget == OBJECT_INVALID) + oSpellTarget = PRCGetSpellTargetObject(oSpellOrigin); + + oAttacker = oSpellOrigin; + oDefender = oSpellTarget; + + if (DEBUG) DoDebug("GetIsOnHitCastSpell: item "+GetName(oSpellCastItem)+" is weapon [WT="+IntToString(nWT)+"]; attacker="+GetName(oAttacker)+", defender="+GetName(oDefender)); + } + else + { + if (DEBUG) DoDebug("GetIsOnHitCastSpell: item "+GetName(oSpellCastItem)+" is neither weapon nor armor; returning FALSE"); + return FALSE; + } + +/* else if (iWeaponType == StringToInt(Get2DACache("baseitems", "WeaponType", iBaseType))) { // determine the target, if not already given if (oSpellTarget == OBJECT_INVALID) @@ -823,7 +840,7 @@ int GetIsOnHitCastSpell(object oSpellTarget = OBJECT_INVALID, object oSpellCastI { if (DEBUG) DoDebug("GetIsOnHitCastSpell: item "+GetName(oSpellCastItem)+" is neither weapon nor armor; returning FALSE"); return FALSE; - } + } */ // the spell origin must possess the item that cast the spell (at least for the aurora engine, in prc_inc_combat that may differ) diff --git a/src/include/prc_inc_unarmed.nss b/src/include/prc_inc_unarmed.nss index a08f912..096b334 100644 --- a/src/include/prc_inc_unarmed.nss +++ b/src/include/prc_inc_unarmed.nss @@ -308,7 +308,7 @@ int FindUnarmedDamage(object oCreature) if (GetHasFeat(FEAT_INCREASE_DAMAGE2, oCreature)) iDieIncrease = 2; else if (GetHasFeat(FEAT_INCREASE_DAMAGE1, oCreature)) iDieIncrease = 1; - //:: Expansion / Compression powers +/* //:: Expansion / Compression powers (Double dipping?) int nExpansion = GetLocalInt(oCreature, "PRC_Power_Expansion_SizeIncrease"); int nCompression = GetLocalInt(oCreature, "PRC_Power_Compression_SizeReduction"); @@ -320,7 +320,7 @@ int FindUnarmedDamage(object oCreature) if (nCompression) { iSize -= nCompression; - } + } */ iMonkDamage += iDieIncrease; iShouDamage += iDieIncrease; diff --git a/src/include/prc_inc_wpnrest.nss b/src/include/prc_inc_wpnrest.nss index 9dcf65a..1734b3b 100644 --- a/src/include/prc_inc_wpnrest.nss +++ b/src/include/prc_inc_wpnrest.nss @@ -1,6 +1,6 @@ //:://///////////////////////////////////////////// //:: Weapon Restriction System Include -//:: prc_inc_restwpn.nss +//:: prc_inc_wpnrest.nss //:://///////////////////////////////////////////// /* Functions to support PnP Weapon Proficiency and @@ -23,6 +23,70 @@ * @param nHand The hand the weapon is wielded in. In the form of * ATTACK_BONUS_ONHAND or ATTACK_BONUS_OFFHAND. */ + +//:: returns TRUE if the wielded weapon works with the Swashbuckler's class abilities. +int GetHasSwashbucklerWeapon(object oPC) +{ + object oWeap = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC); + if (!GetIsObjectValid(oWeap)) return FALSE; + + int nType = GetBaseItemType(oWeap); + + switch (nType) + { + case BASE_ITEM_DAGGER: + case BASE_ITEM_KATAR: + case BASE_ITEM_HANDAXE: + case BASE_ITEM_KAMA: + case BASE_ITEM_KUKRI: + case BASE_ITEM_LIGHTHAMMER: + case BASE_ITEM_LIGHTMACE: + case BASE_ITEM_LIGHT_PICK: + case BASE_ITEM_RAPIER: + case BASE_ITEM_SHORTSWORD: + case BASE_ITEM_SICKLE: + case BASE_ITEM_WHIP: + case BASE_ITEM_SAI: + case BASE_ITEM_SAP: + case BASE_ITEM_NUNCHAKU: + case BASE_ITEM_GOAD: + case BASE_ITEM_ELVEN_LIGHTBLADE: + case BASE_ITEM_ELVEN_THINBLADE: + case BASE_ITEM_EAGLE_CLAW: + return TRUE; + } + + // Iaijutsu Master allows katana + if (GetLevelByClass(CLASS_TYPE_IAIJUTSU_MASTER, oPC) > 0) + { + if (nType == BASE_ITEM_KATANA) return TRUE; + } + + return FALSE; +} + +//:: returns TRUE if the wielded weapon works with the Champion of Corellon's Elegant Strike. +int GetHasCorellonWeapon(object oPC) +{ + object oWeap = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC); + if (!GetIsObjectValid(oWeap)) return FALSE; + + int nType = GetBaseItemType(oWeap); + + switch (nType) + { + case BASE_ITEM_SCIMITAR: + case BASE_ITEM_LONGSWORD: + case BASE_ITEM_RAPIER: + case BASE_ITEM_ELVEN_COURTBLADE: + case BASE_ITEM_ELVEN_LIGHTBLADE: + case BASE_ITEM_ELVEN_THINBLADE: + return TRUE; + } + + return FALSE; +} + void DoRacialEquip(object oPC, int nBaseType); //return if PC has proficiency in an item diff --git a/src/include/prc_nui_lv_inc.nss b/src/include/prc_nui_lv_inc.nss index bc10b28..9f9adb6 100644 --- a/src/include/prc_nui_lv_inc.nss +++ b/src/include/prc_nui_lv_inc.nss @@ -1539,8 +1539,8 @@ int GetRemainingSpellChoices(int nClass, int circleLevel, object oPC=OBJECT_SELF // default logic for spont casters totalSpellsKnown = GetSpellKnownMaxCount(casterLevel, circleLevel, nClass, oPC); // Favoured Soul has more 0 choices than there are spells for some reason - if (nClass == CLASS_TYPE_FAVOURED_SOUL && circleLevel == 0 && totalSpellsKnown > 6) - totalSpellsKnown = 6; + if (nClass == CLASS_TYPE_FAVOURED_SOUL && circleLevel == 0 && totalSpellsKnown > 7) + totalSpellsKnown = 7; // logic for spont casters json selectedCircle = JsonObjectGet(chosenSpells, IntToString(circleLevel)); diff --git a/src/include/prc_sp_func.nss b/src/include/prc_sp_func.nss index 233090f..c249c5f 100644 --- a/src/include/prc_sp_func.nss +++ b/src/include/prc_sp_func.nss @@ -180,6 +180,24 @@ void RunImpactScript(object oPC, int nSpellID, int nEventType) DeleteLocalInt(oPC, PRC_SPELLID_OVERRIDE); } +//Returns true if the spell is one of the repair spells +int IsRepair(int nSpellID) +{ + return ((nSpellID >= SPELL_REPAIR_MINOR_DAMAGE) && (nSpellID <= SPELL_REPAIR_CRITICAL_DAMAGE)); +} + +//Returns true if the spell is one of the mass repair spells +int IsMassRepair(int nSpellID) +{ + return ((nSpellID >= SPELL_MASS_REPAIR_LIGHT_DAMAGE) && (nSpellID <= SPELL_MASS_REPAIR_CRITICAL_DAMAGE)); +} + +//Returns true if the spell is one of the mass inflict damage spells +int IsMassInflictDamage(int nSpellID) +{ + return ((nSpellID >= SPELL_MASS_INFLICT_LIGHT_DAMAGE) && (nSpellID <= SPELL_MASS_INFLICT_CRITICAL_DAMAGE)); +} + //Returns true if the spell is one of the cure spells int IsCure(int nSpellID) { diff --git a/src/include/prc_spell_const.nss b/src/include/prc_spell_const.nss index 02a3a2f..1537b2f 100644 --- a/src/include/prc_spell_const.nss +++ b/src/include/prc_spell_const.nss @@ -1359,8 +1359,27 @@ const int SPELL_SUMMON_NATURES_ALLY_9_ARANEA = 17085; const int SPELL_CHASING_PERFECTION = 2479; //:: Spell Compendium Spells -const int SPELL_SPIRIT_WORM = 17248; -const int SPELL_FORCE_MISSILES = 2480; +const int SPELL_FORCE_MISSILES = 2480; +const int SPELL_REPAIR_MINOR_DAMAGE = 17094; +const int SPELL_REPAIR_LIGHT_DAMAGE = 17095; +const int SPELL_REPAIR_MODERATE_DAMAGE = 17096; +const int SPELL_REPAIR_SERIOUS_DAMAGE = 17097; +const int SPELL_REPAIR_CRITICAL_DAMAGE = 17098; +const int SPELL_INFLICT_LIGHT_DAMAGE = 17100; +const int SPELL_INFLICT_MODERATE_DAMAGE = 17101; +const int SPELL_INFLICT_SERIOUS_DAMAGE = 17102; +const int SPELL_INFLICT_CRITICAL_DAMAGE = 17103; +const int SPELL_SPIRIT_WORM = 17248; + +//:: Races of Eberron +const int SPELL_MASS_REPAIR_LIGHT_DAMAGE = 17105; +const int SPELL_MASS_REPAIR_MODERATE_DAMAGE = 17106; +const int SPELL_MASS_REPAIR_SERIOUS_DAMAGE = 17107; +const int SPELL_MASS_REPAIR_CRITICAL_DAMAGE = 17108; +const int SPELL_MASS_INFLICT_LIGHT_DAMAGE = 17110; +const int SPELL_MASS_INFLICT_MODERATE_DAMAGE = 17111; +const int SPELL_MASS_INFLICT_SERIOUS_DAMAGE = 17112; +const int SPELL_MASS_INFLICT_CRITICAL_DAMAGE = 17113; //:: Masters of the Wild Spells const int SPELL_FORESTFOLD = 17090; diff --git a/src/include/prc_x2_craft.nss b/src/include/prc_x2_craft.nss index ac1d795..608438a 100644 --- a/src/include/prc_x2_craft.nss +++ b/src/include/prc_x2_craft.nss @@ -529,6 +529,7 @@ object CICraftScribeScroll(object oCreator, int nSpellID) case CLASS_TYPE_WIZARD: case CLASS_TYPE_SORCERER: sClass = "Wiz_Sorc"; break; case CLASS_TYPE_CLERIC: + case CLASS_TYPE_OCULAR: case CLASS_TYPE_UR_PRIEST: sClass = "Cleric"; break; case CLASS_TYPE_PALADIN: sClass = "Paladin"; break; case CLASS_TYPE_DRUID: @@ -1476,6 +1477,10 @@ int InscribeRune(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALI if(!GetIsObjectValid(oTarget)) oTarget = PRCGetSpellTargetObject(); int nCaster = GetAlternativeCasterLevel(oCaster, PRCGetCasterLevel(oCaster)); + +//:: [TO DO] make Inscribe Epic Rune. + if(nCaster > 20) nCaster = 20; + int nDC = PRCGetSaveDC(oTarget, oCaster); if(!nSpell) nSpell = PRCGetSpellId(); int nSpellLevel = 0; @@ -1498,6 +1503,7 @@ int InscribeRune(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALI // Minimum level. if (nSpellLevel == 0) nSpellLevel = 1; + // This will be modified with Runecaster code later. int nCharges = 1; if (GetLocalInt(oCaster, "RuneCharges")) nCharges = nCount; diff --git a/src/include/psi_inc_core.nss b/src/include/psi_inc_core.nss index 9083bee..a7acfb4 100644 --- a/src/include/psi_inc_core.nss +++ b/src/include/psi_inc_core.nss @@ -520,9 +520,9 @@ void GainPsionicFocus(object oGainee = OBJECT_SELF) { int nPsySneak = 1; if(GetHasFeat(FEAT_PSY_SNEAK_ATTACK_2d6, oGainee)) - nPsySneak += 2; + nPsySneak += 1; if(GetHasFeat(FEAT_PSY_SNEAK_ATTACK_3d6, oGainee)) - nPsySneak += 3; + nPsySneak += 1; SetLocalInt(oGainee, "PsyRogueSneak",nPsySneak); DelayCommand(0.1, ExecuteScript("prc_sneak_att", oGainee)); diff --git a/src/include/x3_inc_horse.nss b/src/include/x3_inc_horse.nss index 65548a0..422e5c2 100644 --- a/src/include/x3_inc_horse.nss +++ b/src/include/x3_inc_horse.nss @@ -24,6 +24,7 @@ #include "x0_i0_position" #include "X0_INC_HENAI" #include "x3_inc_skin" +#include "prc_racial_const" /* @@ -638,7 +639,7 @@ int HorseGetMountTail(object oHorse); // FILE: x3_inc_horse FUNCTION: HorseGetMountFailureMessage() // This is a companion function to HorseGetCanBeMounted. If you need a text // message that explains why the horse cannot be mounted. -string HorseGetMountFailureMessage(object oTarget,object oRider=OBJECT_INVALID); +string HorseGetMountFailureMessage(object oHorse,object oRider=OBJECT_INVALID); // FILE: x3_inc_horse FUNCTION: HorseAddHorseMenu() @@ -1050,6 +1051,8 @@ void HORSE_SupportOriginalSpeed(object oRider) } // check to see if matches conditions eSearch=GetNextEffect(oRider); } // cycle through effects + + } // HORSE_SupportOriginalSpeed() diff --git a/src/module/ifo/module.ifo.json b/src/module/ifo/module.ifo.json index f3a53f5..c38b347 100644 --- a/src/module/ifo/module.ifo.json +++ b/src/module/ifo/module.ifo.json @@ -830,6 +830,13 @@ "Mod_HakList": { "type": "list", "value": [ + { + "__struct_id": 8, + "Mod_Hak": { + "type": "cexostring", + "value": "mk_ccoh8" + } + }, { "__struct_id": 8, "Mod_Hak": { diff --git a/src/module/nss/nw_s1_dragfeara.nss b/src/module/nss/nw_s1_dragfeara.nss index 2bb5009..3d4c30b 100644 --- a/src/module/nss/nw_s1_dragfeara.nss +++ b/src/module/nss/nw_s1_dragfeara.nss @@ -15,7 +15,85 @@ #include "NW_I0_SPELLS" //#include "wm_include" #include "prc_inc_spells" + void main() +{ + object oTarget = GetEnteringObject(); + object oCreator = GetAreaOfEffectCreator(); + + // Only apply special handling if the creator is a dragon + if (GetRacialType(oCreator) == RACIAL_TYPE_DRAGON) + { + if (MyPRCGetRacialType(oTarget) == RACIAL_TYPE_DRAGON) + return; + + string sDragonID = GetObjectUUID(oCreator); + string sVar = "DRAGON_FEAR_IMMUNE_" + sDragonID; + + // If target is already immune to this dragon’s aura, skip + if (GetLocalInt(oTarget, sVar)) + return; + + int nHD = GetHitDice(oCreator); + int nCHA = GetAbilityModifier(ABILITY_CHARISMA, oCreator); + int nDC = 10 + (nHD / 2) + nCHA; + int nDuration = GetScaledDuration(nHD, oTarget); + + if (GetIsEnemy(oTarget, oCreator)) + { + SignalEvent(oTarget, EventSpellCastAt(oCreator, SPELLABILITY_AURA_FEAR)); + + effect eVis = EffectVisualEffect(VFX_IMP_FEAR_S); + effect eDur = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_FEAR); + effect eDur2 = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE); + effect eFear = EffectFrightened(); + effect eLink = EffectLinkEffects(eFear, eDur); + eLink = EffectLinkEffects(eLink, eDur2); + + if (!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_FEAR)) + { + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nDuration)); + ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); + } + else + { + // Successful save grants 24-hour immunity to this dragon’s aura + SetLocalInt(oTarget, sVar, TRUE); + DelayCommand(HoursToSeconds(24), DeleteLocalInt(oTarget, sVar)); + } + } + } + else // non-dragon sources use normal aura behavior + { + int nHD = GetHitDice(oCreator); + int nCHA = GetAbilityModifier(ABILITY_CHARISMA, oCreator); + int nDC = 10 + (nHD / 2) + nCHA; + int nDuration = GetScaledDuration(nHD, oTarget); + + if (GetIsEnemy(oTarget, oCreator)) + { + SignalEvent(oTarget, EventSpellCastAt(oCreator, SPELLABILITY_AURA_FEAR)); + + effect eVis = EffectVisualEffect(VFX_IMP_FEAR_S); + effect eDur = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_FEAR); + effect eDur2 = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE); + effect eFear = EffectFrightened(); + effect eLink = EffectLinkEffects(eFear, eDur); + eLink = EffectLinkEffects(eLink, eDur2); + + if (!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_FEAR)) + { + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nDuration)); + ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); + } + } + } +} + + + + +/* void main() { //Declare major variables object oTarget = GetEnteringObject(); @@ -27,13 +105,15 @@ void main() effect eLink = EffectLinkEffects(eFear, eDur); eLink = EffectLinkEffects(eLink, eDur2); - int nHD = GetHitDice(GetAreaOfEffectCreator()); - int nDC = 10 + GetHitDice(GetAreaOfEffectCreator())/3; + object oCreator = GetAreaOfEffectCreator(); + int nHD = GetHitDice(oCreator); + int nCHA = GetAbilityModifier(ABILITY_CHARISMA, oCreator); + int nDC = 10 + nCHA + (nHD/2); int nDuration = GetScaledDuration(nHD, oTarget); - if(GetIsEnemy(oTarget, GetAreaOfEffectCreator())) + if(GetIsEnemy(oTarget, oCreator)) { //Fire cast spell at event for the specified target - SignalEvent(oTarget, EventSpellCastAt(GetAreaOfEffectCreator(), SPELLABILITY_AURA_FEAR)); + SignalEvent(oTarget, EventSpellCastAt(oCreator, SPELLABILITY_AURA_FEAR)); //Make a saving throw check if(!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, nDC, SAVING_THROW_TYPE_FEAR)) { @@ -42,4 +122,4 @@ void main() ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); } } -} +} */ \ No newline at end of file