2025/12/23 Update

Hooked up new GUI module event.
Removed CEP3 haks.
Updated PRC8 includes.
Updated readme.
This commit is contained in:
Jaysyn904
2025-12-23 00:58:00 -05:00
parent 4d7b6a0551
commit 1f20105930
89 changed files with 6841 additions and 1212 deletions

View File

@@ -61,6 +61,7 @@ const int X2_CI_CRAFTROD_EPIC_FEAT_ID = 3490;
const int X2_CI_CRAFTSTAFF_FEAT_ID = 2928;
const int X2_CI_CRAFTSTAFF_EPIC_FEAT_ID = 3491;
const int X2_CI_CREATEINFUSION_FEAT_ID = 25960;
const int X2_CI_CRAFTSCEPTER_FEAT_ID = 25962;
const string X2_CI_BREWPOTION_NEWITEM_RESREF = "x2_it_pcpotion"; // ResRef for new potion item
const string X2_CI_SCRIBESCROLL_NEWITEM_RESREF = "x2_it_pcscroll"; // ResRef for new scroll item
@@ -276,6 +277,7 @@ int CIGetIsCraftFeatBaseItem(object oItem)
nBt == BASE_ITEM_BLANK_WAND ||
nBt == BASE_ITEM_CRAFTED_ROD ||
nBt == BASE_ITEM_CRAFTED_STAFF ||
nBt == BASE_ITEM_CRAFTED_SCEPTER ||
nBt == BASE_ITEM_MUNDANE_HERB)
return TRUE;
else
@@ -302,7 +304,7 @@ object CICraftBrewPotion(object oCreator, int nSpellID )
return OBJECT_INVALID;
}
/* //just a tad retarded, don't you think? other crafting feats are not similarly restricted
/* //just a tad silly, don't you think? other crafting feats are not similarly restricted
//Uses per day
int nUsesAllowed;
@@ -529,6 +531,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:
@@ -709,6 +712,7 @@ object CICraftScribeScroll(object oCreator, int nSpellID)
return oTarget;
}
*/
// -----------------------------------------------------------------------------
// Returns TRUE if the player used the last spell to brew a potion
// -----------------------------------------------------------------------------
@@ -864,7 +868,6 @@ These dont work as IPs since they are hardcoded */
}
// -----------------------------------------------------------------------------
// Returns TRUE if the player used the last spell to create a scroll
// -----------------------------------------------------------------------------
@@ -1132,6 +1135,169 @@ These dont work as IPs since they are hardcoded */
return FALSE;
}
// -----------------------------------------------------------------------------
// Returns TRUE if the player used the last spell to craft a scepter
// -----------------------------------------------------------------------------
int CICraftCheckCraftScepter(object oSpellTarget, object oCaster, int nSpellID = 0)
{
if(nSpellID == 0) nSpellID = PRCGetSpellId();
int nCasterLevel = GetAlternativeCasterLevel(oCaster, PRCGetCasterLevel(oCaster));
int bSuccess = TRUE;
int nCount = 0;
itemproperty ip = GetFirstItemProperty(oSpellTarget);
int nMetaMagic = PRCGetMetaMagicFeat();
while(GetIsItemPropertyValid(ip))
{
if(GetItemPropertyType(ip) == ITEM_PROPERTY_CAST_SPELL)
nCount++;
ip = GetNextItemProperty(oSpellTarget);
}
if(nCount >= 2) //:: Scepters are limited to two spells
{
FloatingTextStringOnCreature("* Failure - Too many castspell itemproperties *", oCaster);
return TRUE;
}
if(!GetHasFeat(X2_CI_CRAFTSCEPTER_FEAT_ID, oCaster))
{
FloatingTextStrRefOnCreature(40487, oCaster); // Item Creation Failed - Don't know how to create that type of item
return TRUE; // tried item creation but do not know how to do it
}
if(CIGetIsSpellRestrictedFromCraftFeat(nSpellID, X2_CI_CRAFTSCEPTER_FEAT_ID))
{
FloatingTextStrRefOnCreature(16829169, oCaster); // can not be used with this feat
return TRUE;
}
// Get the base spell level (circle) before metamagic adjustments
int nBaseLevel = CIGetSpellInnateLevel(nSpellID, TRUE);
// Check if spell circle is 7th level or lower
if (nBaseLevel > 7)
{
//FloatingTextStrRefOnCreature(83623, oCaster); // Spell level too high
FloatingTextStringOnCreature("* Failure - scepters can not hold spells higher than level 7", oCaster);
return TRUE;
}
int nLevel = nBaseLevel;
if(GetPRCSwitch(PRC_CRAFT_SCEPTER_CASTER_LEVEL))
{
switch(nMetaMagic)
{
case METAMAGIC_EMPOWER:
nLevel += 2;
break;
case METAMAGIC_EXTEND:
nLevel += 1;
break;
case METAMAGIC_MAXIMIZE:
nLevel += 3;
break;
/* case METAMAGIC_QUICKEN:
nLevel += 1;
break;
case METAMAGIC_SILENT:
nLevel += 5;
break;
case METAMAGIC_STILL:
nLevel += 6;
break;
These dont work as IPs since they are hardcoded */
}
}
int nCostMod = GetPRCSwitch(PRC_X2_CRAFTSCEPTER_COSTMODIFIER);
if(!nCostMod) nCostMod = 750;
int nLvlRow = IPGetIPConstCastSpellFromSpellID(nSpellID);
int nCLevel = StringToInt(Get2DACache("iprp_spells","CasterLvl",nLvlRow));
int nCost = CIGetCraftGPCost(nLevel, nCostMod, PRC_CRAFT_SCEPTER_CASTER_LEVEL);
//discount for second spell
if(nCount+1 == 2)
nCost = (nCost/2);
//takes epic xp costs into account
struct craft_cost_struct costs = GetModifiedCostsFromBase(nCost, oCaster, FEAT_CRAFT_SCEPTER, (nMetaMagic > 0));
if(costs.nGoldCost < 1) costs.nXPCost = 1;
if(costs.nXPCost < 1) costs.nXPCost = 1;
//if(GetGold(oCaster) < nGoldCost) // enough gold?
if (!GetHasGPToSpend(oCaster, costs.nGoldCost))
{
FloatingTextStrRefOnCreature(3786, oCaster); // Item Creation Failed - not enough gold!
return TRUE;
}
int nHD = GetHitDice(oCaster);
int nMinXPForLevel = (nHD * (nHD - 1)) * 500;
int nNewXP = GetXP(oCaster) - costs.nXPCost;
//if (nMinXPForLevel > nNewXP || nNewXP == 0 )
if (!GetHasXPToSpend(oCaster, costs.nXPCost))
{
FloatingTextStrRefOnCreature(3785, oCaster); // Item Creation Failed - Not enough XP
return TRUE;
}
//check spell emulation
if(!CheckAlternativeCrafting(oCaster, nSpellID, costs))
{
FloatingTextStringOnCreature("*Crafting failed!*", oCaster, FALSE);
return TRUE;
}
int nPropID = IPGetIPConstCastSpellFromSpellID(nSpellID);
if (nPropID == 0 && nSpellID != 0)
{
FloatingTextStrRefOnCreature(84544,oCaster);
return TRUE;
}
if (nPropID != -1)
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyCastSpell(nPropID,IP_CONST_CASTSPELL_NUMUSES_1_CHARGE_PER_USE),oSpellTarget);
if(GetPRCSwitch(PRC_CRAFT_SCEPTER_CASTER_LEVEL))
{
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyCastSpellCasterLevel(nSpellID, nCasterLevel),oSpellTarget);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyCastSpellMetamagic(nSpellID, PRCGetMetaMagicFeat()),oSpellTarget);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyCastSpellDC(nSpellID, PRCGetSaveDC(PRCGetSpellTargetObject(), OBJECT_SELF)),oSpellTarget);
}
}
else
bSuccess = FALSE;
if(bSuccess)
{
//TakeGoldFromCreature(nGoldCost, oCaster, TRUE);
//SetXP(oCaster, nNewXP);
SpendXP(oCaster, costs.nXPCost);
SpendGP(oCaster, costs.nGoldCost);
//DestroyObject (oSpellTarget);
FloatingTextStrRefOnCreature(8502, oCaster); // Item Creation successful
//advance time here
if(!costs.nTimeCost) costs.nTimeCost = 1;
AdvanceTimeForPlayer(oCaster, RoundsToSeconds(costs.nTimeCost));
string sName;
sName = GetName(oCaster)+"'s Magic Scepter";
SetItemCharges(oSpellTarget, 50);
//sName = Get2DACache("spells", "Name", nID);
//sName = "Wand of "+GetStringByStrRef(StringToInt(sName));
SetName(oSpellTarget, sName);
SetItemCursedFlag(oSpellTarget, FALSE);
SetDroppableFlag(oSpellTarget, TRUE);
return TRUE;
}
else
{
FloatingTextStrRefOnCreature(76417, oCaster); // Item Creation Failed
return TRUE;
}
return TRUE;
}
// -----------------------------------------------------------------------------
// Returns TRUE if the player used the last spell to craft a staff
// -----------------------------------------------------------------------------
int CICraftCheckCraftStaff(object oSpellTarget, object oCaster, int nSpellID = 0)
{
@@ -1280,6 +1446,9 @@ These dont work as IPs since they are hardcoded */
return TRUE;
}
// -----------------------------------------------------------------------------
// Returns TRUE if the player used the last spell to craft a rod
// -----------------------------------------------------------------------------
int CICraftCheckCraftRod(object oSpellTarget, object oCaster, int nSpellID = 0)
{
@@ -1426,6 +1595,7 @@ These dont work as IPs since they are hardcoded */
return TRUE;
}
int InscribeRune(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALID, int nSpell = 0)
{
if(!GetIsObjectValid(oCaster)) oCaster = OBJECT_SELF;
@@ -1476,6 +1646,11 @@ int InscribeRune(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALI
if(!GetIsObjectValid(oTarget)) oTarget = PRCGetSpellTargetObject();
int nCaster = GetAlternativeCasterLevel(oCaster, PRCGetCasterLevel(oCaster));
//:: Check for Inscribe Epic Runes and cap CL at 20 if it doesn't exist.
int bEpicRunes = GetHasFeat(EPIC_FEAT_INSCRIBE_EPIC_RUNES, oCaster);
if (!bEpicRunes) { if(nCaster > 20) nCaster = 20; }
int nDC = PRCGetSaveDC(oTarget, oCaster);
if(!nSpell) nSpell = PRCGetSpellId();
int nSpellLevel = 0;
@@ -1498,6 +1673,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;
@@ -1606,9 +1782,14 @@ int InscribeRune(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALI
// If they have this active, the bonuses are already added, so skip
// If they don't, add the bonuses down below
if(GetHasSpellEffect(SPELL_RUNE_CHANT))
nRuneChant = 0;
nRuneChant = 0;
itemproperty ipLevel = ItemPropertyCastSpellCasterLevel(nSpell, PRCGetCasterLevel());
//:: Check for Inscribe Epic Runes and cap CL at 20 if it doesn't exist.
nCaster = PRCGetCasterLevel();
if (!bEpicRunes) { if(nCaster > 20) nCaster = 20; }
itemproperty ipLevel = ItemPropertyCastSpellCasterLevel(nSpell, nCaster);
AddItemProperty(DURATION_TYPE_PERMANENT,ipLevel,oRune);
itemproperty ipMeta = ItemPropertyCastSpellMetamagic(nSpell, PRCGetMetaMagicFeat());
AddItemProperty(DURATION_TYPE_PERMANENT,ipMeta,oRune);
@@ -1715,13 +1896,23 @@ int AttuneGem(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALID,
}
// oTarget here should be the gem. If it's not, fail.
if(!GetIsObjectValid(oTarget)) oTarget = PRCGetSpellTargetObject();
// Only accepts bioware gems
if (GetStringLeft(GetResRef(oTarget), 5) == "it_gem")
// Only accepts bioware gems & Craftable Natural Resources gems, but not gem dust.
int bIsBioGem = (GetStringLeft(GetResRef(oTarget), 5) == "it_gem");
int bIsCNRGem = (GetStringLeft(GetResRef(oTarget), 6) == "cnrgem");
int bIsDust = (GetStringLeft(GetResRef(oTarget), 10) == "cnrgemdust");
if (!(bIsBioGem || bIsCNRGem) || bIsDust)
{
FloatingTextStringOnCreature("Spell target is not a valid gem.", oCaster, FALSE);
return TRUE;
}
/* if ((GetStringLeft(GetResRef(oTarget), 5) == "it_gem") || (GetStringLeft(GetResRef(oTarget), 6) == "cnrgem") && (GetStringLeft(GetResRef(oTarget), 10) != "cnrgemdust"))
{
FloatingTextStringOnCreature("Spell target is not a valid gem.", oCaster, FALSE);
// And out we go
return TRUE;
}
} */
int nCaster = GetAlternativeCasterLevel(oCaster, PRCGetCasterLevel(oCaster));
int nDC = PRCGetSaveDC(oTarget, oCaster);
@@ -2117,6 +2308,13 @@ int CIGetSpellWasUsedForItemCreation(object oSpellTarget)
// -------------------------------------------------
nRet = CICraftCheckCraftStaff(oSpellTarget,oCaster);
break;
case BASE_ITEM_CRAFTED_SCEPTER :
// -------------------------------------------------
// Craft Scepter
// -------------------------------------------------
nRet = CICraftCheckCraftScepter(oSpellTarget,oCaster);
break;
case BASE_ITEM_MUNDANE_HERB :
// -------------------------------------------------
@@ -2916,7 +3114,12 @@ int GetMagicalArtisanFeat(int nCraftingFeat)
{
nReturn = FEAT_MAGICAL_ARTISAN_CREATE_INFUSION;
break;
}
}
case FEAT_CRAFT_SCEPTER:
{
nReturn = FEAT_MAGICAL_ARTISAN_CRAFT_SCEPTER;
break;
}
default:
{
if(DEBUG) DoDebug("GetMagicalArtisanFeat: invalid crafting feat");
@@ -3309,21 +3512,23 @@ object CICreateInfusion(object oCreator, int nSpellID)
// Keep the original spell id the engine gave us (may be a subradial)
int nSpellOriginal = nSpellID;
if (DEBUG) DoDebug("prc_x2_craft >> CICreateInfusion: nSpellOriginal is "+IntToString(nSpellOriginal)+".");
// Compute the master (one-step) if this is a subradial. Keep original intact.
int nSpellMaster = nSpellOriginal;
// Compute the master if this is a subradial. Keep original intact.
int nSpellMaster = nSpellOriginal;
if (GetIsSubradialSpell(nSpellOriginal))
{
nSpellMaster = GetMasterSpellFromSubradial(nSpellOriginal);
if (DEBUG) DoDebug("CICreateInfusion: detected subradial " + IntToString(nSpellOriginal) + " master -> " + IntToString(nSpellMaster));
}
if (DEBUG) DoDebug("prc_x2_craft >> CICreateInfusion: nSpellMaster is "+IntToString(nSpellMaster)+".");
// Try to find an iprp_spells row for the original subradial first (preferred).
int nPropID = IPGetIPConstCastSpellFromSpellID(nSpellOriginal);
int nSpellUsedForIP = nSpellOriginal;
// If not found for original, fall back to the master/base spell.
if (nPropID < 0)
if (nPropID < 0)
{
if (DEBUG) DoDebug("CICreateInfusion: no iprp row for original " + IntToString(nSpellOriginal) + ", trying master " + IntToString(nSpellMaster));
nPropID = IPGetIPConstCastSpellFromSpellID(nSpellMaster);