Update for PRC 4.1.10a 2023/02/20
Update for PRC 4.1.10a 2023/02/20 + Jaysyn's latest PnP changes.
This commit is contained in:
83
trunk/scripts/prc_fm_deeproots.nss
Normal file
83
trunk/scripts/prc_fm_deeproots.nss
Normal file
@@ -0,0 +1,83 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Forest Master: Deep Roots
|
||||
//:: prc_fm_deeproots.nss
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Deep Roots (Su): Beginning at 8th level, once per day the forest
|
||||
master may sink roots into the ground in any natural surface
|
||||
place that can support at least some vegetation. While rooted, the
|
||||
forest master gains fast healing 5, but has an effective Dexterity
|
||||
score of 1 and may not move from the spot in which he stands.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Jaysyn
|
||||
//:: Created On: 20230107
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
void main()
|
||||
{
|
||||
//:: Declare major variables
|
||||
object oPC = OBJECT_SELF;
|
||||
object oArea = GetArea(oPC);
|
||||
|
||||
int bDeepRoots = GetLocalInt(oPC, "DeepRootsActive");
|
||||
int iNatural = GetIsAreaNatural(oArea);
|
||||
int iSurface = GetIsAreaAboveGround(oArea);
|
||||
|
||||
effect eRoots = EffectCutsceneImmobilize();
|
||||
effect eRegen = EffectRegenerate(4, 6.0f);
|
||||
effect eEntangle = EffectVisualEffect(VFX_DUR_ENTANGLE);
|
||||
effect eLink;
|
||||
effect eEffect;
|
||||
|
||||
//:: Deep Roots only works where trees can grow.
|
||||
if ((!iNatural) || (!iSurface))
|
||||
{
|
||||
SendMessageToPC(oPC, "You must be outdoors on fertile ground for this ability to function.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bDeepRoots)
|
||||
{
|
||||
//:: End & remove Deep Roots
|
||||
eEffect = GetFirstEffect(oPC);
|
||||
|
||||
while(GetIsEffectValid(eEffect))
|
||||
{
|
||||
if(GetEffectTag(eEffect) == "FM_DeepRoots")
|
||||
{
|
||||
RemoveEffect(oPC, eEffect);
|
||||
}
|
||||
|
||||
eEffect = GetNextEffect(oPC);
|
||||
}
|
||||
|
||||
SetLocalInt(oPC, "DeepRootsActive", 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//:: Link & tag effects
|
||||
eLink = EffectLinkEffects(eRoots, eRegen);
|
||||
eLink = EffectLinkEffects(eLink, eEntangle);
|
||||
eLink = SupernaturalEffect(eLink);
|
||||
eLink = TagEffect(eLink, "FM_DeepRoots");
|
||||
|
||||
//:: Clear the effect to be safe and prevent stacking
|
||||
effect eCheckEffect = GetFirstEffect(oPC);
|
||||
|
||||
while (GetIsEffectValid(eCheckEffect))
|
||||
{
|
||||
if (GetEffectTag(eCheckEffect) == "FM_DeepRoots")
|
||||
{
|
||||
RemoveEffect(oPC, eCheckEffect);
|
||||
}
|
||||
|
||||
eCheckEffect = GetNextEffect(oPC);
|
||||
|
||||
}
|
||||
//:: Apply effects & set int var
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oPC);
|
||||
SetLocalInt(oPC, "DeepRootsActive", 1);
|
||||
|
||||
}
|
250
trunk/scripts/prc_fm_forestdom.nss
Normal file
250
trunk/scripts/prc_fm_forestdom.nss
Normal file
@@ -0,0 +1,250 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Forest Dominion
|
||||
//:: prc_fm_forestdom.nss
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
At 2nd level, the forest master gains the ability to rebuke or command plants
|
||||
as an evil cleric can rebuke or command undead. His effective level for this
|
||||
ability is his class level, and he may use it a number of times perday equal
|
||||
to 3 + his Charisma modifier. If he already has this ability because he is a
|
||||
cleric with the Plant domain, these levels stack with his cleric levels and
|
||||
vice versa.
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Modified:
|
||||
//:: 20040101 by Cole Kleinschmit: for use as Command Spiders.
|
||||
//:: 22021020 by Jaysyn: Fixed to actually work on all spiders.
|
||||
//:: 20230107 by Jaysyn: for use as Command Plants.
|
||||
|
||||
#include "prc_class_const"
|
||||
#include "prc_alterations"
|
||||
|
||||
int CheckTargetName(object oTarget, string sName);
|
||||
|
||||
int GetIsPlant(object oCreature, int nAppearance);
|
||||
|
||||
int CanCommand(int nClassLevel, int nTargetHD)
|
||||
{
|
||||
int nSlots = GetLocalInt(OBJECT_SELF, "wb_clr_comm_slots");
|
||||
int nNew = nSlots+nTargetHD;
|
||||
//FloatingTextStringOnCreature("The variable is " + IntToString(nSlots), OBJECT_SELF);
|
||||
if(nClassLevel >= nNew)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void AddCommand(int nTargetHD)
|
||||
{
|
||||
int nSlots = GetLocalInt(OBJECT_SELF, "wb_clr_comm_slots");
|
||||
SetLocalInt(OBJECT_SELF, "wb_clr_comm_slots", nSlots + nTargetHD);
|
||||
}
|
||||
|
||||
void SubCommand(int nTargetHD)
|
||||
{
|
||||
int nSlots = GetLocalInt(OBJECT_SELF, "wb_clr_comm_slots");
|
||||
SetLocalInt(OBJECT_SELF, "wb_clr_comm_slots", nSlots - nTargetHD);
|
||||
}
|
||||
|
||||
void RebukePlant(int nTurnLevel, int nTurnHD, int nPlants, int nClassLevel)
|
||||
{
|
||||
//Gets all creatures in a 20m radius around the caster and rebukes them or not. If the creatures
|
||||
//HD are 1/2 or less of the nClassLevel then the creature is commanded (dominated).
|
||||
int nCnt = 1;
|
||||
int nHD, nRacial, nHDCount, bValid, nDamage;
|
||||
nHDCount = 0;
|
||||
effect eVis = EffectVisualEffect(VFX_IMP_PULSE_NEGATIVE);
|
||||
effect eVisTurn = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_DOMINATED);
|
||||
effect eDamage;
|
||||
effect eTurned = EffectCutsceneParalyze();
|
||||
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
|
||||
effect eLink = EffectLinkEffects(eVisTurn, eTurned);
|
||||
eLink = EffectLinkEffects(eLink, eDur);
|
||||
|
||||
effect eDeath = SupernaturalEffect(EffectCutsceneDominated());
|
||||
effect eDomin = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_NEGATIVE);
|
||||
effect eDeathLink = EffectLinkEffects(eDeath, eDomin);
|
||||
|
||||
effect eImpactVis = EffectVisualEffect(VFX_FNF_LOS_EVIL_30);
|
||||
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpactVis, GetLocation(OBJECT_SELF));
|
||||
|
||||
//Get nearest enemy within 20m (60ft)
|
||||
//Why are you using GetNearest instead of GetFirstObjectInShape
|
||||
// Because ability description says "gets closest first" :P
|
||||
object oTarget = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC , OBJECT_SELF, nCnt);
|
||||
|
||||
int nTargetAppearance = GetAppearanceType(oTarget);
|
||||
|
||||
while(GetIsObjectValid(oTarget) && nHDCount < nTurnHD && GetDistanceToObject(oTarget) <= 20.0)
|
||||
{
|
||||
if(!GetIsFriend(oTarget))
|
||||
{
|
||||
nHD = GetHitDice(oTarget) + GetTurnResistanceHD(oTarget);
|
||||
|
||||
if(nHD <= nTurnLevel && nHD <= (nTurnHD - nHDCount))
|
||||
{
|
||||
//:: Check for correct turning target.
|
||||
if(GetIsPlant(oTarget, nTargetAppearance))
|
||||
{
|
||||
bValid = TRUE;
|
||||
//debug
|
||||
SpeakString("Plant Found");
|
||||
}
|
||||
|
||||
//Apply results of the turn
|
||||
if( bValid == TRUE)
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||
//if(IntToFloat(nClassLevel)/2.0 >= IntToFloat(nHD))
|
||||
//{
|
||||
|
||||
if((nClassLevel/2) >= nHD && CanCommand(nClassLevel, nHD))
|
||||
{
|
||||
//Fire cast spell at event for the specified target
|
||||
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_FM_FORESTDOMINION));
|
||||
//Destroy the target
|
||||
DelayCommand(0.1f, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDeathLink, oTarget, RoundsToSeconds(nClassLevel + 5)));
|
||||
//AssignCommand(oTarget, ClearAllActions());
|
||||
//SetIsTemporaryFriend(oTarget, OBJECT_SELF, TRUE, RoundsToSeconds(nClassLevel + 5));
|
||||
AddCommand(nHD);
|
||||
DelayCommand(RoundsToSeconds(nClassLevel + 5), SubCommand(nHD));
|
||||
//debug
|
||||
SpeakString("Commanding Plant");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Turn the target
|
||||
//Fire cast spell at event for the specified target
|
||||
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_FM_FORESTDOMINION));
|
||||
//AssignCommand(oTarget, ActionMoveAwayFromObject(OBJECT_SELF, TRUE));
|
||||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nClassLevel + 5));
|
||||
//debug
|
||||
SpeakString("Rebuking Plant");
|
||||
}
|
||||
nHDCount = nHDCount + nHD;
|
||||
}
|
||||
}
|
||||
bValid = FALSE;
|
||||
}
|
||||
nCnt++;
|
||||
oTarget = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC, OBJECT_SELF, nCnt);
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
//:: Declare major variables
|
||||
int nFMLevel = GetLevelByClass(CLASS_TYPE_FORESTMASTER);
|
||||
int nCleric = GetLevelByClass(CLASS_TYPE_CLERIC);
|
||||
int nShaman = GetLevelByClass(CLASS_TYPE_SHAMAN);
|
||||
|
||||
int nTotalLevel;
|
||||
|
||||
//:: Check for Plant Domain & adust turning & class level.
|
||||
int nPlants = GetHasFeat(FEAT_PLANT_DOMAIN_POWER);
|
||||
|
||||
if (nPlants)
|
||||
{
|
||||
nTotalLevel = nFMLevel + nCleric + nShaman;
|
||||
}
|
||||
else
|
||||
{
|
||||
nTotalLevel = nFMLevel;
|
||||
}
|
||||
|
||||
int nTurnLevel = nTotalLevel;
|
||||
int nClassLevel = nTotalLevel;
|
||||
|
||||
//:: Make a turning check roll
|
||||
int nChrMod = GetAbilityModifier(ABILITY_CHARISMA);
|
||||
int nTurnCheck = d20() + nChrMod; //:: The roll to apply to the max HD of plants that can be commanded --> nTurnLevel
|
||||
int nTurnHD = d6(2) + nChrMod + nClassLevel; //:: The number of HD of plants that can be commanded.
|
||||
|
||||
//:: Determine the maximum HD of the plants that can be commanded.
|
||||
if(nTurnCheck <= 0)
|
||||
{
|
||||
nTurnLevel -= 4;
|
||||
}
|
||||
else if(nTurnCheck >= 1 && nTurnCheck <= 3)
|
||||
{
|
||||
nTurnLevel -= 3;
|
||||
}
|
||||
else if(nTurnCheck >= 4 && nTurnCheck <= 6)
|
||||
{
|
||||
nTurnLevel -= 2;
|
||||
}
|
||||
else if(nTurnCheck >= 7 && nTurnCheck <= 9)
|
||||
{
|
||||
nTurnLevel -= 1;
|
||||
}
|
||||
else if(nTurnCheck >= 10 && nTurnCheck <= 12)
|
||||
{
|
||||
//:: Stays the same
|
||||
}
|
||||
else if(nTurnCheck >= 13 && nTurnCheck <= 15)
|
||||
{
|
||||
nTurnLevel += 1;
|
||||
}
|
||||
else if(nTurnCheck >= 16 && nTurnCheck <= 18)
|
||||
{
|
||||
nTurnLevel += 2;
|
||||
}
|
||||
else if(nTurnCheck >= 19 && nTurnCheck <= 21)
|
||||
{
|
||||
nTurnLevel += 3;
|
||||
}
|
||||
else if(nTurnCheck >= 22)
|
||||
{
|
||||
nTurnLevel += 4;
|
||||
}
|
||||
|
||||
RebukePlant(nTurnLevel, nTurnHD, nPlants, nClassLevel);
|
||||
|
||||
}
|
||||
|
||||
int GetIsPlant(object oTarget, int nAppearance)
|
||||
{
|
||||
//:: No actual plants in vanilla NWN
|
||||
return (nAppearance == 1001 //:: [CEP3] Twig Blight* (Erendril)
|
||||
|| nAppearance == 1053 //:: [CEP3] Fungus: Shrieker 1* (Lathspell)
|
||||
|| nAppearance == 1055 //:: [CEP3] Myconid* (Schazzwozzer)
|
||||
|| nAppearance == 1056 //:: [CEP3] Myconid: Sprout* (Schazzwozzer)
|
||||
|| nAppearance == 1057 //:: [CEP3] Myconid: Elder* (Schazzwozzer)
|
||||
|| nAppearance == 1060 //:: [CEP3] Vegepygmy* (Lathspell)
|
||||
|| nAppearance == 1061 //:: [CEP3] Thorny* (Lathspell)
|
||||
|| nAppearance == 1062 //:: [CEP3] Vegepygmy: Thorny Rider T* (Lathspell)
|
||||
|| nAppearance == 1063 //:: [CEP3] Vegepygmy: Thorny Rider* (Lathspell)
|
||||
|| nAppearance == 1064 //:: [CEP3] Vegepygmy: Thorny Rider V* (Lathspell)
|
||||
|| nAppearance == 1492 //:: [CEP3] Treant 1* (DLA Team)
|
||||
|| nAppearance == 1496 //:: [CEP3] Assassin Vine: Horizontal* (ShadowM)
|
||||
|| nAppearance == 1497 //:: [CEP3] Assassin Vine: Vertical* (ShadowM)
|
||||
|| nAppearance == 2597 //:: [CEP3] Treant: Small*
|
||||
|| nAppearance == 3049 //:: [CEP3] Pumpkin* (CEP-Barry_1066)
|
||||
|| nAppearance == 3397 //:: [CEP3] Fungus: Mold: Brown* (CCP)
|
||||
|| nAppearance == 3398 //:: [CEP3] Fungus: Mold: Yellow* (CCP)
|
||||
|| nAppearance == 3399 //:: [CEP3] Fungus: Shrieker 2* (CCP)
|
||||
|| nAppearance == 3400 //:: [CEP3] Fungus: Violet* (CCP)
|
||||
|| nAppearance == 3471 //:: [CEP3] Shambling Mound 1* (CCP)
|
||||
|| nAppearance == 3480 //:: [CEP3] Strangle Weed* (CCP)
|
||||
|| nAppearance == 3492 //:: [CEP3] Treant 2* [WoW] (CCP)
|
||||
|| nAppearance == 3893 //:: [CEP3] Shambling Mound 2* (Hardpoints)
|
||||
|| nAppearance == 6409 //:: [CEP3] Fungus: Shrieker* (The Amethyst Dragon)
|
||||
|| nAppearance == 6410 //:: [CEP3] Fungus: Violet Fungus* (The Amethyst Dragon)
|
||||
|| nAppearance == 6417 //:: [CEP3] Treant: Wild Woods* (The Amethyst Dragon)
|
||||
|| nAppearance == 6437 //:: [CEP3] Forrestal: Runner* (CCC-Cestus Dei)
|
||||
|| nAppearance == 6438 //:: [CEP3] Forrestal: Strider* (CCC-Cestus Dei)
|
||||
|| nAppearance == 6439 //:: [CEP3] Forrestal: Walkabout* (CCC-Cestus Dei)
|
||||
|| nAppearance == 6440 //:: [CEP3] Forrestal: Elder* (CCC-Cestus Dei)
|
||||
|| nAppearance == 6441 //:: [CEP3] Forrestal: Dreamwalker* (CCC-Cestus Dei)
|
||||
|| nAppearance == 6468 //:: [CEP3] Topiary Guardian: Bear* (The Amethyst Dragon)
|
||||
|| nAppearance == 6469 //:: [CEP3] Topiary Guardian: Boar* (The Amethyst Dragon)
|
||||
|| nAppearance == 6470 //:: [CEP3] Topiary Guardian: Deer* (The Amethyst Dragon)
|
||||
|| nAppearance == 6471 //:: [CEP3] Topiary Guardian: Lion* (The Amethyst Dragon)
|
||||
|| nAppearance == 6472 //:: [CEP3] Topiary Guardian: Triceratops* (The Amethyst Dragon)
|
||||
|| nAppearance == 6473 //:: [CEP3] Topiary Guardian: Wolf* (The Amethyst Dragon)
|
||||
|| nAppearance == 6474 //:: [CEP3] Topiary Guardian: Horse* (The Amethyst Dragon)
|
||||
|| nAppearance == 6475 //:: [CEP3] Topiary Guardian: Woman* (The Amethyst Dragon)
|
||||
|| (MyPRCGetRacialType(oTarget) == RACIAL_TYPE_PLANT));
|
||||
|
||||
}
|
109
trunk/scripts/prc_fm_icy_mal.nss
Normal file
109
trunk/scripts/prc_fm_icy_mal.nss
Normal file
@@ -0,0 +1,109 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Forest Master: Shocking Great Mallet
|
||||
//:: prc_fm_icy_mal.nss
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Beginning at 2nd level, a forest master begins to awaken magical abilities
|
||||
within the wood and metal that make up his maul. Any maul used by a forest
|
||||
master is treated as if it were a +2 maul with either the frost or shock
|
||||
property (the forest master decides each round whether the weapon’s extra damage
|
||||
is cold or electricity). If the weapon has additional abilities (such as
|
||||
defending), these abilities still apply, and if the weapon has an enhancement
|
||||
bonus better than +2 the higher of the two bonuses is used. The maul does not
|
||||
gain these abilities if it is not wielded by the forest master. At 6th-level,
|
||||
the forest master’s maul acts as a +2 icy burst or +2 shocking burst weapon,
|
||||
with the forest master deciding each round what effect the weapon has. At 9th
|
||||
level, the forest master’s maul acts as a +3 mighty cleaving weapon in addition
|
||||
to its other properties (including its icy burst or shocking burst ability).
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Jaysyn
|
||||
//:: Created On: 20230106
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "prc_alterations"
|
||||
|
||||
void main()
|
||||
{
|
||||
//:: Declare major variables
|
||||
object oPC = OBJECT_SELF;
|
||||
|
||||
int iFMLevel = GetLevelByClass(CLASS_TYPE_FORESTMASTER, oPC);
|
||||
|
||||
itemproperty ipIP;
|
||||
|
||||
//:: Find a maul
|
||||
object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||||
int bHasMaul = (GetBaseItemType(oItem) == BASE_ITEM_MAUL);
|
||||
|
||||
//:: Need a maul
|
||||
if(!bHasMaul)
|
||||
{
|
||||
FloatingTextStringOnCreature(GetStringByStrRef(16548+0x01000000), oPC, FALSE);
|
||||
}
|
||||
|
||||
//:: Remove the Cleave or Great Cleave bonus feat from the maul being unequipped
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_BONUS_FEAT, DURATION_TYPE_TEMPORARY, IP_CONST_FEAT_GREAT_CLEAVE);
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_BONUS_FEAT, DURATION_TYPE_TEMPORARY, IP_CONST_FEAT_CLEAVE);
|
||||
|
||||
//:: Remove Great Mallet damage bonuses from maul being unequipped
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_DAMAGE_BONUS, DURATION_TYPE_TEMPORARY, IP_CONST_DAMAGETYPE_ELECTRICAL);
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_DAMAGE_BONUS, DURATION_TYPE_TEMPORARY, IP_CONST_DAMAGETYPE_COLD);
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_ENHANCEMENT_BONUS, DURATION_TYPE_TEMPORARY);
|
||||
|
||||
|
||||
//:: Setup damage bonuses
|
||||
if (iFMLevel >= 9)
|
||||
{
|
||||
if (GetHasFeat(FEAT_GREAT_CLEAVE,oPC))
|
||||
{
|
||||
ipIP = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1d8);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyEnhancementBonus(3);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
|
||||
else if (GetHasFeat(FEAT_CLEAVE, oPC))
|
||||
{
|
||||
ipIP = PRCItemPropertyBonusFeat(IP_CONST_FEAT_GREAT_CLEAVE);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1d8);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyEnhancementBonus(3);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ipIP = PRCItemPropertyBonusFeat(IP_CONST_FEAT_CLEAVE);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1d8);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyEnhancementBonus(3);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
else if (iFMLevel < 9 && iFMLevel > 5)
|
||||
{
|
||||
ipIP = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1d8);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyEnhancementBonus(2);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipIP = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_COLD, IP_CONST_DAMAGEBONUS_1d6);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyEnhancementBonus(2);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
|
||||
}
|
108
trunk/scripts/prc_fm_shock_mal.nss
Normal file
108
trunk/scripts/prc_fm_shock_mal.nss
Normal file
@@ -0,0 +1,108 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Forest Master: Shocking Great Mallet
|
||||
//:: prc_fm_shock_mal.nss
|
||||
//:://////////////////////////////////////////////
|
||||
/*
|
||||
Beginning at 2nd level, a forest master begins to awaken magical abilities
|
||||
within the wood and metal that make up his maul. Any maul used by a forest
|
||||
master is treated as if it were a +2 maul with either the frost or shock
|
||||
property (the forest master decides each round whether the weapon’s extra damage
|
||||
is cold or electricity). If the weapon has additional abilities (such as
|
||||
defending), these abilities still apply, and if the weapon has an enhancement
|
||||
bonus better than +2 the higher of the two bonuses is used. The maul does not
|
||||
gain these abilities if it is not wielded by the forest master. At 6th-level,
|
||||
the forest master’s maul acts as a +2 icy burst or +2 shocking burst weapon,
|
||||
with the forest master deciding each round what effect the weapon has. At 9th
|
||||
level, the forest master’s maul acts as a +3 mighty cleaving weapon in addition
|
||||
to its other properties (including its icy burst or shocking burst ability).
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Jaysyn
|
||||
//:: Created On: 20230106
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "prc_alterations"
|
||||
|
||||
void main()
|
||||
{
|
||||
//:: Declare major variables
|
||||
object oPC = OBJECT_SELF;
|
||||
|
||||
int iFMLevel = GetLevelByClass(CLASS_TYPE_FORESTMASTER, oPC);
|
||||
|
||||
itemproperty ipIP;
|
||||
|
||||
//:: Find a maul
|
||||
object oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||||
int bHasMaul = (GetBaseItemType(oItem) == BASE_ITEM_MAUL);
|
||||
|
||||
//:: Need a maul
|
||||
if(!bHasMaul)
|
||||
{
|
||||
FloatingTextStringOnCreature(GetStringByStrRef(16548+0x01000000), oPC, FALSE);
|
||||
}
|
||||
|
||||
//:: Remove the Cleave or Great Cleave bonus feat from the maul being unequipped
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_BONUS_FEAT, DURATION_TYPE_TEMPORARY, IP_CONST_FEAT_GREAT_CLEAVE);
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_BONUS_FEAT, DURATION_TYPE_TEMPORARY, IP_CONST_FEAT_CLEAVE);
|
||||
|
||||
//:: Remove Great Mallet damage bonuses from maul being unequipped
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_DAMAGE_BONUS, DURATION_TYPE_TEMPORARY, IP_CONST_DAMAGETYPE_ELECTRICAL);
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_DAMAGE_BONUS, DURATION_TYPE_TEMPORARY, IP_CONST_DAMAGETYPE_COLD);
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_ENHANCEMENT_BONUS, DURATION_TYPE_TEMPORARY);
|
||||
|
||||
//:: Setup damage bonuses
|
||||
if (iFMLevel >= 9)
|
||||
{
|
||||
if (GetHasFeat(FEAT_GREAT_CLEAVE,oPC))
|
||||
{
|
||||
ipIP = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1d8);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyEnhancementBonus(3);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
|
||||
else if (GetHasFeat(FEAT_CLEAVE, oPC))
|
||||
{
|
||||
ipIP = PRCItemPropertyBonusFeat(IP_CONST_FEAT_GREAT_CLEAVE);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1d8);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyEnhancementBonus(3);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ipIP = PRCItemPropertyBonusFeat(IP_CONST_FEAT_CLEAVE);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1d8);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyEnhancementBonus(3);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
else if (iFMLevel < 9 && iFMLevel > 5)
|
||||
{
|
||||
ipIP = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1d8);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyEnhancementBonus(2);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipIP = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ELECTRICAL, IP_CONST_DAMAGEBONUS_1d6);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyEnhancementBonus(2);
|
||||
IPSafeAddItemProperty(oItem, ipIP, 999999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
|
||||
}
|
131
trunk/scripts/prc_forestmaster.nss
Normal file
131
trunk/scripts/prc_forestmaster.nss
Normal file
@@ -0,0 +1,131 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: [Forest Master setup script]
|
||||
//:: [prc_forestmaster.nss]
|
||||
//:: [Jaysyn 20230106]
|
||||
//::///////////////////////////////////////////////
|
||||
|
||||
#include "prc_inc_combat"
|
||||
|
||||
void main()
|
||||
{
|
||||
//:: Declare major variables
|
||||
object oPC = OBJECT_SELF;
|
||||
object oSkin = GetPCSkin(oPC);
|
||||
object oItem = GetPCItemLastUnequipped();
|
||||
|
||||
int nFMLevel = GetLevelByClass(CLASS_TYPE_FORESTMASTER, oPC);
|
||||
int nEvent = GetRunningEvent();
|
||||
|
||||
effect eEffect;
|
||||
|
||||
itemproperty ipIP;
|
||||
|
||||
|
||||
//:: We aren't being called from onPlayerUnequipItem event, instead from the PRCEvalFeats
|
||||
if(nEvent == FALSE)
|
||||
{
|
||||
// :: Hook in the events
|
||||
if(DEBUG) DoDebug("Forest Master: Adding eventhooks");
|
||||
AddEventScript(oPC, EVENT_ONPLAYERUNEQUIPITEM, "prc_forestmaster", TRUE, FALSE);
|
||||
}
|
||||
|
||||
//:: We're being called from the onPlayerUnequipItem eventhook, so check or skip
|
||||
if(nEvent == EVENT_ONPLAYERUNEQUIPITEM)
|
||||
{
|
||||
//:: Remove Great Mallet damage bonuses from maul being unequipped
|
||||
int bHadMaul = (GetBaseItemType(oItem) == BASE_ITEM_MAUL);
|
||||
|
||||
if(bHadMaul)
|
||||
{
|
||||
|
||||
//:: Remove the Cleave or Great Cleave bonus feat from the maul being unequipped
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_BONUS_FEAT, DURATION_TYPE_TEMPORARY, IP_CONST_FEAT_GREAT_CLEAVE);
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_BONUS_FEAT, DURATION_TYPE_TEMPORARY, IP_CONST_FEAT_CLEAVE);
|
||||
|
||||
//:: Remove Great Mallet damage bonuses from maul being unequipped
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_DAMAGE_BONUS, DURATION_TYPE_TEMPORARY, IP_CONST_DAMAGETYPE_ELECTRICAL);
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_DAMAGE_BONUS, DURATION_TYPE_TEMPORARY, IP_CONST_DAMAGETYPE_COLD);
|
||||
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_ENHANCEMENT_BONUS, DURATION_TYPE_TEMPORARY);
|
||||
}
|
||||
|
||||
}
|
||||
//:: End if - Running OnPlayerUnequipItem event
|
||||
|
||||
|
||||
//:: Setup Oak Strength ////////////////////////////////////////////////////////
|
||||
/* Oak Strength (Ex): Beginning at 4th level, the forest master gains a +2
|
||||
bonus to Strength and the ability to make slam attacks. A Small creature’s
|
||||
slam attack deals 1d4 points of damage, one from a Medium-size creature
|
||||
deals 1d6 points of damage, and a Large forest master’s slam attack deals
|
||||
1d8 points of damage. Slam attacks are natural weapon attacks and do not
|
||||
provoke an attack of opportunity from the defender. A forest master can
|
||||
select Improved Critical (slam), Weapon Focus (slam), and (if a fighter of
|
||||
4th level or higher) Weapon Specialization (slam). Upon gaining this
|
||||
ability, the forest master’s hair takes on a green, leafy appearance. */
|
||||
//::////////////////////////////////////////////////////////////////////////////
|
||||
if (nFMLevel >= 4)
|
||||
{
|
||||
string sResRef;
|
||||
int nHair;
|
||||
int nHairSet = GetLocalInt(oPC, "FM_HAIR_INT");
|
||||
int nSize = PRCGetCreatureSize(oPC)+1;
|
||||
//primary weapon
|
||||
sResRef = "prc_warf_slam_";
|
||||
sResRef += GetAffixForSize(nSize);
|
||||
AddNaturalPrimaryWeapon(oPC, sResRef, 2);
|
||||
|
||||
if (!nHairSet)
|
||||
{
|
||||
switch (Random(6))
|
||||
{
|
||||
case 0: {nHair = 30; break;}
|
||||
case 1: {nHair = 31; break;}
|
||||
case 2: {nHair = 49 ; break;}
|
||||
case 3: {nHair = 106; break;}
|
||||
case 4: {nHair = 107; break;}
|
||||
case 5: {nHair = 152; break;}
|
||||
case 6: {nHair = 153; break;}
|
||||
}
|
||||
|
||||
SetColor(oPC, COLOR_CHANNEL_HAIR, nHair);
|
||||
SetLocalInt(oPC, "FM_HAIR_INT", nHair);
|
||||
}
|
||||
}
|
||||
|
||||
//:: Setup Oakheart ///////////////////////////////////////////////////////////////
|
||||
/* Oakheart (Ex): Upon reaching 7th level, a forest master’s body becomes a
|
||||
thing of wood and leaf rather than meat and bone. His type changes to plant.
|
||||
As such, he is immune to mind-affecting effects, poison, sleep, paralysis,
|
||||
stunning, and polymorphing. He is not subject to critical hits or sneak
|
||||
attacks. However, the forest master becomes vulnerable to fire, and suffers
|
||||
double damage from fire attacks if he fails a Reflex saving throw, or half
|
||||
damage if he succeeds. */
|
||||
//::///////////////////////////////////////////////////////////////////////////////
|
||||
if (nFMLevel >= 7)
|
||||
{
|
||||
effect eNoStun = EffectImmunity(IMMUNITY_TYPE_STUN);
|
||||
eNoStun = SupernaturalEffect(eNoStun);
|
||||
eNoStun = ExtraordinaryEffect(eNoStun);
|
||||
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eNoStun, oPC));
|
||||
|
||||
//:: These are handled via cls_feat_formast.2da
|
||||
/* ipIP =ItemPropertyImmunityMisc(IP_CONST_IMMUNITYMISC_PARALYSIS);
|
||||
IPSafeAddItemProperty(oSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP =ItemPropertyImmunityMisc(IP_CONST_IMMUNITYMISC_POISON);
|
||||
IPSafeAddItemProperty(oSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP =ItemPropertyImmunityMisc(IP_CONST_IMMUNITYMISC_MINDSPELLS);
|
||||
IPSafeAddItemProperty(oSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP =ItemPropertyImmunityMisc(IP_CONST_IMMUNITYMISC_CRITICAL_HITS);
|
||||
IPSafeAddItemProperty(oSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE); */
|
||||
|
||||
ipIP =ItemPropertyImmunityMisc(IP_CONST_IMMUNITYMISC_BACKSTAB);
|
||||
IPSafeAddItemProperty(oSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
|
||||
|
||||
ipIP = ItemPropertyDamageVulnerability(DAMAGE_TYPE_FIRE, IP_CONST_DAMAGEVULNERABILITY_50_PERCENT);
|
||||
IPSafeAddItemProperty(oSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
|
||||
} //:: End
|
@@ -142,7 +142,7 @@ void UpdateIPs(object oItem)
|
||||
else if(nClass == CLASS_TYPE_WIZARD || nClass == CLASS_TYPE_SORCERER)
|
||||
bAdd = RealSpellToSpellbookID(CLASS_TYPE_SORCERER, nSpellID) == -1 ? FALSE : TRUE;
|
||||
else if(nClass == CLASS_TYPE_CLERIC)
|
||||
bAdd = RealSpellToSpellbookID(CLASS_TYPE_MYSTIC, nSpellID) == -1 ? FALSE : TRUE;
|
||||
bAdd = Get2DACache("Spells", "Cleric", nSpellID) == "" ? FALSE : TRUE;
|
||||
else
|
||||
bAdd = RealSpellToSpellbookID(nClass, nSpellID) == -1 ? FALSE : TRUE;
|
||||
|
||||
|
Reference in New Issue
Block a user