Added Amulet of Mighty Fists +1 thru +5. Added Greenbound template. Fixed Evolved & Paragon templates. Updated several area names.
259 lines
8.8 KiB
Plaintext
259 lines
8.8 KiB
Plaintext
/* Greenbound Creature Template
|
|
|
|
By: Jaysyn
|
|
Created: 2025-09-06 22:24:15
|
|
|
|
A greenbound creature looks much like it did before
|
|
transformation, although certain changes are apparent.
|
|
The creature's flesh has been replaced by pulpy wood
|
|
and thickly corded creepers, and tiny branches stick
|
|
out from its torso, arms, and legs. Any feathers, hair,
|
|
or fur it once had have been replaced by some combination
|
|
of green vines, moss, flowers, and leaves.
|
|
|
|
Greenbound creatures speak any languages they knew before
|
|
transformation, although their voices are now deep and
|
|
gravelly.
|
|
|
|
/*///////////////////////////////////////////////////////////
|
|
|
|
#include "nw_inc_gff"
|
|
#include "prc_inc_spells"
|
|
#include "prc_inc_util"
|
|
#include "npc_template_inc"
|
|
#include "inc_debug"
|
|
#include "prc_inc_json"
|
|
|
|
//:: Adds Greenbound SLA's to jCreature.
|
|
//::
|
|
json json_AddGreenboundPowers(json jCreature)
|
|
{
|
|
// Get the existing SpecAbilityList (if it exists)
|
|
json jSpecAbilityList = GffGetList(jCreature, "SpecAbilityList");
|
|
|
|
//:: Get creature's HD
|
|
int iHD = json_GetCreatureHD(jCreature);
|
|
|
|
// Create the SpecAbilityList if it doesn't exist
|
|
if (jSpecAbilityList == JsonNull())
|
|
{
|
|
jSpecAbilityList = JsonArray();
|
|
}
|
|
|
|
//:: Add Entangle at will (capped @ 20)
|
|
int i;
|
|
for (i = 0; i < 20; i++)
|
|
{
|
|
json jSpecAbility = JsonObject();
|
|
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 53);
|
|
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", iHD);
|
|
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
|
|
|
|
// Manually add to the array
|
|
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
|
|
}
|
|
|
|
//:: Add Vine Mine 1x / Day
|
|
for (i = 0; i < 1; i++)
|
|
{
|
|
json jSpecAbility = JsonObject();
|
|
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 529);
|
|
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", iHD);
|
|
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
|
|
|
|
// Manually add to the array
|
|
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
|
|
}
|
|
|
|
//:: Add the list to the creature
|
|
jCreature = GffAddList(jCreature, "SpecAbilityList", jSpecAbilityList);
|
|
|
|
return jCreature;
|
|
}
|
|
|
|
//:: Apply Greenbound effects
|
|
void ApplyGreenboundEffects(object oCreature, int nBaseHD)
|
|
{
|
|
//:: Declare major variables
|
|
int nNewCR;
|
|
object oSkin = GetPCSkin(oCreature);
|
|
|
|
itemproperty ipIP;
|
|
|
|
effect eGreenbound;
|
|
|
|
//:: Give it a barkskin vfx
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectVisualEffect(VFX_DUR_PROT_BARKSKIN));
|
|
|
|
//:: Plant Immunities
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectImmunity(IMMUNITY_TYPE_STUN));
|
|
|
|
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);
|
|
|
|
//:: Set maximum hit points for each HD
|
|
int nMaxHP = GetMaxPossibleHP(oCreature);
|
|
SetCurrentHitPoints(oCreature, nMaxHP);
|
|
|
|
DoDebug("nMaxHP is: "+IntToString(nMaxHP)+",");
|
|
|
|
//:: Resistance to Cold and Electricity (Ex): A greenbound creature gains resistance 10 to cold and electricity.
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, 10));
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectDamageResistance(DAMAGE_TYPE_COLD, 10));
|
|
|
|
//:: Damage Reduction (Ex): A greenbound creature has damage reduction 10/magic and slashing.
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectDamageReduction(10, DAMAGE_POWER_PLUS_ONE));
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectDamageResistance(DAMAGE_TYPE_BLUDGEONING, 10));
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectDamageResistance(DAMAGE_TYPE_PIERCING, 10));
|
|
|
|
//:: Fast Healing (Ex): A greenbound creature heals 3 points of damage each round so long as it has at least 1 hit point.
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectRegenerate(3, 6.0f));
|
|
|
|
//:: Tremorsense (Ex): Greenbound creatures can automatically sense the location of
|
|
//:: anything within 60 feet that is in contact with the ground.
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectBonusFeat(488));
|
|
|
|
//:: Grapple Bonus (Ex): The thorny hooks on a greenbound creature's hands and feet
|
|
//:: grant it a +4 bonus on grapple checks. (Imp. Grapple)
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectBonusFeat(2804));
|
|
|
|
//:: Immunity to Critical Hits
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectBonusFeat(3585));
|
|
|
|
//:: Immunity to Sneak Attack
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectBonusFeat(3591));
|
|
|
|
//:: Immunity to Poison
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectBonusFeat(3590));
|
|
|
|
//:: Immunity to Mind Effects
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectBonusFeat(3588));
|
|
|
|
//:: Low-Light Vision
|
|
eGreenbound = EffectLinkEffects(eGreenbound, EffectBonusFeat(354));
|
|
|
|
//:: Make *really* permanent
|
|
eGreenbound = UnyieldingEffect(eGreenbound);
|
|
|
|
//:: Apply everything
|
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eGreenbound, oCreature);
|
|
|
|
//:: Add slam attack
|
|
string sResRef;
|
|
int nSize = PRCGetCreatureSize(oCreature);
|
|
//primary weapon
|
|
sResRef = "prc_warf_slam_";
|
|
sResRef += GetAffixForSize(nSize+1);
|
|
AddNaturalPrimaryWeapon(oCreature, sResRef, 1);
|
|
|
|
}
|
|
|
|
|
|
void main ()
|
|
{
|
|
//:: Declare major variables
|
|
object oBaseCreature = OBJECT_SELF;
|
|
object oNewCreature;
|
|
|
|
string sBaseName = GetName(oBaseCreature);
|
|
|
|
GetObjectUUID(oBaseCreature);
|
|
|
|
int nRacial = MyPRCGetRacialType(oBaseCreature);
|
|
|
|
//:: No Template Stacking
|
|
if(GetLocalInt(oBaseCreature, "TEMPLATE_GREENBOUND") > 0)
|
|
{
|
|
if(DEBUG) DoDebug("No Template Stacking");
|
|
return;
|
|
}
|
|
|
|
//:: Creatures & NPCs only
|
|
if ((GetObjectType(oBaseCreature) != OBJECT_TYPE_CREATURE) || (GetIsPC(oBaseCreature) == TRUE))
|
|
{
|
|
if(DEBUG) DoDebug("Not a creature");
|
|
return;
|
|
}
|
|
/*
|
|
|
|
A "greenbound creature" is an acquired template that can be added to
|
|
any animal, fey, giant, humanoid, monstrous humanoid, or vermin.
|
|
|
|
*/
|
|
if(nRacial == RACIAL_TYPE_ABERRATION || nRacial == RACIAL_TYPE_CONSTRUCT || nRacial == RACIAL_TYPE_DRAGON ||
|
|
nRacial == RACIAL_TYPE_ELEMENTAL || nRacial == RACIAL_TYPE_MAGICAL_BEAST || nRacial == RACIAL_TYPE_OOZE ||
|
|
nRacial == RACIAL_TYPE_OUTSIDER || nRacial == RACIAL_TYPE_PLANT || nRacial == RACIAL_TYPE_UNDEAD )
|
|
{
|
|
DoDebug("make_greenbound: Invalid racial type for template.");
|
|
return;
|
|
}
|
|
|
|
int nBaseHD = GetHitDice(oBaseCreature);
|
|
int nBaseCR = FloatToInt(GetChallengeRating(oBaseCreature));
|
|
|
|
location lSpawnLoc = GetLocation(oBaseCreature);
|
|
|
|
json jBaseCreature = ObjectToJson(oBaseCreature, TRUE);
|
|
json jNewCreature;
|
|
json jFinalCreature;
|
|
|
|
//:: The creature's type changes to plant with the appropriate augmented subtype.
|
|
//:: Hit Dice: Change all current Hit Dice to d8s.
|
|
jNewCreature = JsonModifyRacialType(jBaseCreature, RACIAL_TYPE_PLANT);
|
|
|
|
//:: Armor Class: A greenbound creature's natural armor bonus improves by 6 over that of the base creature.
|
|
jNewCreature = json_IncreaseBaseAC(jNewCreature, 6);
|
|
|
|
//:: Abilities: Increase from the base creature as follows: Str +6, Dex +2, Con +4, Cha +4.
|
|
jNewCreature = json_UpdateCreatureStats(jNewCreature, oBaseCreature, 6, 2, 4, 0, 0, 4);
|
|
|
|
if (GetIsObjectValid(oBaseCreature))
|
|
{
|
|
AssignCommand(oBaseCreature, ClearAllActions(TRUE));
|
|
|
|
// optional fade / vanish visuals
|
|
effect eBlank = EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY);
|
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlank, oBaseCreature, 6.0f);
|
|
|
|
DestroyObject(oBaseCreature, 0.1f);
|
|
}
|
|
|
|
//:: Spell-Like Abilities: At will - entangle, pass without trace, speak with plants; 1/day - wall of thorns.
|
|
jNewCreature = json_AddGreenboundPowers(jNewCreature);
|
|
|
|
//:: Hit Dice: Change all current Hit Dice to d8s.
|
|
jNewCreature = json_RecalcMaxHP(jNewCreature, 8);
|
|
|
|
//:: Challenge Rating: Same as the base creature +2
|
|
jFinalCreature = json_UpdateCR(jNewCreature, nBaseCR, 2);
|
|
|
|
//:: Update the creature
|
|
oNewCreature = JsonToObject(jFinalCreature, lSpawnLoc);
|
|
|
|
//:: Apply the non-json effects
|
|
ApplyGreenboundEffects(oNewCreature, nBaseHD);
|
|
|
|
//:: Update creature's name
|
|
SetName(oNewCreature, "Greenbound "+ sBaseName);
|
|
|
|
//:: Update race field
|
|
SetSubRace(oNewCreature, "Plant (Augmented)");
|
|
|
|
//:: Freshen Up
|
|
//DelayCommand(0.0f, PRCForceRest(oNewCreature));
|
|
|
|
//:: Set variables
|
|
SetLocalInt(oNewCreature, "TEMPLATE_GREENBOUND", 1);
|
|
} |