2026/01/08 Update

Hexblade shouldn't get Medium Armor prof.
Weapon Specialization Whip isn't a Warblade bonus feat.
Reorganized packages.2da.
Fixed potential issue with SetCompositeBonusT().
Added materials iprops to material based crafting.
Fixed bug w/ DoTrip().
Added heartbeat script to Monk to properly handle monk sizes.
Cleaned up PRCGetCreatureSize().
Set Shielded Casting to use TagItemProperty().
Archivist now has a Lore check to learn spells from scrolls.
Set Dragonfire Strike to use TagItemProperty().
Setup Forsaker to use TagItemProperty().
Fixed distance mismatch with Necrocarnum Shroud.
Added too much debugging for the unarmed stuff.
Cloudkill now obeys Mastery of Shapes.
This commit is contained in:
Jaysyn904
2026-01-08 20:31:11 -05:00
parent 6ca160ca26
commit 6420e5dbb8
28 changed files with 1707 additions and 1117 deletions

View File

@@ -880,7 +880,8 @@ void SetCompositeBonusT(object oItem, string sBonus, int iVal, int iType, int iS
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyAttackBonusVsSAlign(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
//iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
@@ -888,7 +889,8 @@ void SetCompositeBonusT(object oItem, string sBonus, int iVal, int iType, int iS
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDamageBonusVsRace(iSubType, DAMAGE_TYPE_SLASHING, iCurVal + iChange), oItem);
//AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDamageBonusVsRace(iSubType, DAMAGE_TYPE_SLASHING, iCurVal + iChange), oItem);
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDamageBonusVsRace(iSubType, DAMAGE_TYPE_SLASHING, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_DECREASED_ABILITY_SCORE:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);

View File

@@ -40,6 +40,7 @@ struct ipstruct GetIpStructFromString(string sIp);
//#include "prc_inc_listener"
#include "prc_inc_chat"
#include "prc_x2_craft"
#include "prc_inc_material"
const int NUM_MAX_PROPERTIES = 200;
const int NUM_MAX_SUBTYPES = 256;
@@ -1861,6 +1862,9 @@ void MakeAdamantine(object oItem)
IPSafeAddItemProperty(oItem, ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_BLUDGEONING, nBonus), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_PIERCING, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_SLASHING, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
itemproperty ipAdamantine = ItemPropertyMaterial(IP_MATERIAL_ADAMANTINE);
IPSafeAddItemProperty(oItem, ipAdamantine, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
}
}
@@ -1883,6 +1887,9 @@ void MakeDarkwood(object oItem)
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_SET_TRAP, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_TUMBLE, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_JUMP, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
itemproperty ipDarkwood = ItemPropertyMaterial(IP_MATERIAL_WOOD_DARKWOOD_ZALANTAR);
IPSafeAddItemProperty(oItem, ipDarkwood, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
}
@@ -1911,33 +1918,44 @@ void MakeMithral(object oItem)
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_SET_TRAP, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_TUMBLE, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_JUMP, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_BALANCE, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_CLIMB, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_BALANCE, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_CLIMB, nBonus) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
if(GetItemBaseAC(oItem) == 1)
IPSafeAddItemProperty(oItem, ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_5_PERCENT), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
else
IPSafeAddItemProperty(oItem, ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_10_PERCENT), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
itemproperty ipMithral = ItemPropertyMaterial(IP_MATERIAL_MITHRAL);
IPSafeAddItemProperty(oItem, ipMithral, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
}
void MakeColdIron(object oItem)
{
//Does nothing so far
//Does nothing so far
itemproperty ipColdIron = ItemPropertyMaterial(IP_MATERIAL_COLD_IRON);
IPSafeAddItemProperty(oItem, ipColdIron, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
void MakeSilver(object oItem)
{
//Does nothing so far
//Does nothing so far
itemproperty ipSilver = ItemPropertyMaterial(IP_MATERIAL_SILVER);
IPSafeAddItemProperty(oItem, ipSilver, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
void MakeMundaneCrystal(object oItem)
{
//Does nothing so far
//Does nothing so far
itemproperty ipCrystal = ItemPropertyMaterial(IP_MATERIAL_GEM_CRYSTAL_MUNDANE);
IPSafeAddItemProperty(oItem, ipCrystal, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
void MakeDeepCrystal(object oItem)
{
//Does nothing so far
//Does nothing so far
itemproperty ipDeepCrystal = ItemPropertyMaterial(IP_MATERIAL_GEM_CRYSTAL_DEEP);
IPSafeAddItemProperty(oItem, ipDeepCrystal, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
//Creates an item on oOwner, from the baseitemtype and base AC (for armour)

View File

@@ -1324,7 +1324,7 @@ int DoTrip(object oPC, object oTarget, int nExtraBonus, int nGenerateAoO = TRUE,
}
else // If you fail, enemy gets a counter trip attempt, using Strength
{
if(!nCounterTrip)
if(nCounterTrip)
{
nTargetStat = GetAbilityModifier(ABILITY_STRENGTH, oTarget) + GetCombatMoveCheckBonus(oTarget, COMBAT_MOVE_TRIP, FALSE, TRUE);
FloatingTextStringOnCreature("You have failed on your Trip attempt",oPC, FALSE);

View File

@@ -187,6 +187,7 @@ void SetupCharacterData(object oPC)
case CLASS_TYPE_MASTER_OF_SHADOW: sScript = "shd_mastershadow"; break;
case CLASS_TYPE_MIGHTY_CONTENDER_KORD: sScript = "prc_contendkord"; break;
case CLASS_TYPE_MORNINGLORD: sScript = "prc_morninglord"; break;
case CLASS_TYPE_MONK: sScript = "prc_monk"; break;
case CLASS_TYPE_NIGHTSHADE: sScript = "prc_nightshade"; break;
case CLASS_TYPE_NINJA: sScript = "prc_ninjca"; break;
case CLASS_TYPE_OLLAM: sScript = "prc_ollam"; break;

View File

@@ -493,6 +493,29 @@ int PRCGetCreatureSize(object oObject = OBJECT_SELF, int nSizeMask = PRC_SIZEMAS
int nSize = StringToInt(Get2DAString("appearance", "SizeCategory", GetAppearanceType(oObject)));
if (DEBUG) DoDebug("Appearance-based GetCreatureSize, returning size: "+IntToString(nSize));
if (DEBUG) DoDebug("Bioware GetCreatureSize, returning size: "+IntToString(GetCreatureSize(oObject)));
// Check for racial size feats FIRST - these override appearance size
if(GetHasFeat(FEAT_TINY, oObject))
nSize = 3; // PRC Tiny
else if(GetHasFeat(FEAT_SMALL, oObject))
nSize = 4; // PRC Small
else if(GetHasFeat(FEAT_LARGE, oObject))
nSize = 6; // PRC Large
else if(GetHasFeat(FEAT_HUGE, oObject))
nSize = 7; // PRC Huge
else
{
// Map appearance sizes to PRC sizes when no racial feat present
if(nSize == 1) nSize = 3; // Tiny creatures
else if(nSize == 2) nSize = 4; // Small creatures
else if(nSize == 3) nSize = 5; // Medium creatures
else if(nSize == 4) nSize = 6; // Large creatures
else if(nSize == 5) nSize = 7; // Huge creatures
}
if (DEBUG) DoDebug("Has FEAT_LARGE: " + IntToString(GetHasFeat(FEAT_LARGE, oObject)));
if (DEBUG) DoDebug("PRCGetCreatureSize: After racial feats, nSize = " + IntToString(nSize));
//CEP adds other sizes, take them into account too
if(nSize == 20)
nSize = CREATURE_SIZE_DIMINUTIVE;

View File

@@ -276,7 +276,11 @@ void ApplyUnarmedAttackEffects(object oCreature)
// Frostrager: 1d6 at level 1, 1d8 at level 4
int FindUnarmedDamage(object oCreature)
{
int iDamage = 0;
DoDebug("FindUnarmedDamage: FUNCTION CALLED AT ALL");
if (DEBUG) DoDebug("=== FindUnarmedDamage DEBUG START ===");
if (DEBUG) DoDebug("Creature: " + GetName(oCreature));
int iDamage = 0;
int iMonk = GetLevelByClass(CLASS_TYPE_MONK, oCreature) + GetLocalInt(oCreature, "LiPengMonk");
int iShou = GetLevelByClass(CLASS_TYPE_SHOU, oCreature);
int iBrawler = GetLevelByClass(CLASS_TYPE_BRAWLER, oCreature);
@@ -299,7 +303,46 @@ int FindUnarmedDamage(object oCreature)
if (GetHasSpellEffect(VESTIGE_RONOVE, oCreature) && GetLevelByClass(CLASS_TYPE_BINDER, oCreature))
iRonove = GetLocalInt(oCreature, "RonovesFists");
//:: Determine creature size
//:: Determine creature size
if( GetIsPolyMorphedOrShifted(oCreature) || GetPRCSwitch(PRC_APPEARANCE_SIZE))
{
iSize = PRCGetCreatureSize(oCreature) - CREATURE_SIZE_MEDIUM + 5;
}
else
{
if (DEBUG) DoDebug("FindUnarmedDamage: Before size adjustment, iSize = " + IntToString(iSize));
// Start with feat-based size calculation
iSize = 5; // medium
if (GetHasFeat(FEAT_TINY, oCreature)) iSize = 3;
if (GetHasFeat(FEAT_SMALL, oCreature)) iSize = 4;
if (GetHasFeat(FEAT_LARGE, oCreature)) iSize = 6;
if (GetHasFeat(FEAT_HUGE, oCreature)) iSize = 7;
if (DEBUG) DoDebug("FindUnarmedDamage: After size adjustment, iSize = " + IntToString(iSize));
if (DEBUG) DoDebug("Has FEAT_LARGE: " + IntToString(GetHasFeat(FEAT_LARGE, oCreature)));
if (DEBUG) DoDebug("Size adjustment value: " + IntToString(PRCGetCreatureSize(oCreature) - PRCGetCreatureSize(oCreature, PRC_SIZEMASK_NONE)));
// Only apply size adjustment if no explicit size feat is present
// This prevents overriding racial size feats like Centaur's FEAT_LARGE
if (!GetHasFeat(FEAT_TINY, oCreature) &&
!GetHasFeat(FEAT_SMALL, oCreature) &&
!GetHasFeat(FEAT_LARGE, oCreature) &&
!GetHasFeat(FEAT_HUGE, oCreature))
{
iSize += PRCGetCreatureSize(oCreature) - PRCGetCreatureSize(oCreature, PRC_SIZEMASK_NONE);
}
if (iSize < 1) iSize = 1;
if (iSize > 9) iSize = 9;
if (DEBUG) DoDebug("FindUnarmedDamage: Final iSize = " + IntToString(iSize));
if (DEBUG) DoDebug("FindUnarmedDamage: iMonkDamage = " + IntToString(iMonkDamage));
if (DEBUG) DoDebug("FindUnarmedDamage: 2DA lookup result = " + IntToString(StringToInt(Get2DACache("unarmed_dmg","size" + IntToString(iSize), iMonkDamage))));
}
/* //:: Determine creature size
if( GetIsPolyMorphedOrShifted(oCreature) || GetPRCSwitch(PRC_APPEARANCE_SIZE))
{
iSize = PRCGetCreatureSize(oCreature) - CREATURE_SIZE_MEDIUM + 5;
@@ -314,7 +357,7 @@ int FindUnarmedDamage(object oCreature)
iSize += PRCGetCreatureSize(oCreature) - PRCGetCreatureSize(oCreature, PRC_SIZEMASK_NONE);
if (iSize < 1) iSize = 1;
if (iSize > 9) iSize = 9;
}
} */
// Sacred Fist code break protection
if (GetHasFeat(FEAT_SF_CODE, oCreature)) iSacredFist = 0;
@@ -347,6 +390,7 @@ int FindUnarmedDamage(object oCreature)
// Monk damage calculation (2DA row)
if (iMonk > 0) iMonkDamage = iMonk / 4 + 3;
if (DEBUG) DoDebug("iMonkDamage row = " + IntToString(iMonkDamage));
if (iSize == 5 && iMonkDamage == 7 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE))
iMonkDamage = 8;
@@ -403,6 +447,7 @@ int FindUnarmedDamage(object oCreature)
// Lookup monk damage in 2DA
iMonkDamage = StringToInt(Get2DACache("unarmed_dmg","size" + IntToString(iSize), iMonkDamage));
if (DEBUG) DoDebug("FindUnarmedDamage: Final damage value = " + IntToString(iMonkDamage));
// 3.0e monk special cases
if (iSize <= 5 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE))
@@ -426,8 +471,10 @@ int FindUnarmedDamage(object oCreature)
iDamage = (DamageAvg(iBrawlerDamage) > DamageAvg(iDamage)) ? iBrawlerDamage : iDamage;
if (DEBUG) DoDebug("prc_inc_unarmed: iDamage "+IntToString(iDamage));
return iDamage;
if (DEBUG) DoDebug("=== FindUnarmedDamage DEBUG END ===");
}