PoA_PRC8/_module/nss/make_evolved.nss
Jaysyn904 855e99b13b Updated for updated PRC8 functions
Updated for updated PRC8 functions.  Full compile.  Updated spell & ability haks. Updated release archive.
2025-02-10 08:51:10 -05:00

414 lines
14 KiB
Plaintext

/* Evolved Undead
By: Jaysyn
Created: 2024-11-14 17:50:32
An evolved undead is an undead whose body is flushed with more negative
energy than normal due to an exceptionally long lifetime. Any undead
may gain this template, and in doing so, it retains all its previous
abilities, but becomes more powerful than before.
*/
#include "nw_inc_gff"
#include "npc_template_inc"
#include "prc_inc_spells"
#include "prc_inc_util"
//:: Adds Evolved SLA's to jCreature.
//::
json json_AddEvolvedPowers(json jCreature, int nBaseHD, int nCasterLevel, int iEvolution)
{
int nRandom = d12(1);
// Get the existing SpecAbilityList (if it exists)
json jSpecAbilityList = GffGetList(jCreature, "SpecAbilityList");
// Create the SpecAbilityList if it doesn't exist
if (jSpecAbilityList == JsonNull())
{
jSpecAbilityList = JsonArray();
}
/* 1 circle of death 6
2 cloudkill 5
3 cone of cold 4
4 confusion 3
5 contagion 27 - 3rd
6 creeping doom 364 - 7th
7 greater dispel magic 67 - 5th
8 greater invisibility 88 - 4th
9 haste 78 - 3rd
10 hold monster 82 - 4th
11 see invisibility 157 - 2nd
12 unholy blight 566 - 5th
*/
switch(nRandom)
{
case 1:
if (nBaseHD >= 6)
{
int i;
for (i = 0; i < 1; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 18);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", PRCMax(nCasterLevel, nBaseHD));
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
}
else
{
return json_AddEvolvedPowers(jCreature, nBaseHD, nCasterLevel, iEvolution);
}
break;
case 2:
if (nBaseHD >= 5)
{
int i;
for (i = 0; i < 1; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 23);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", PRCMax(nCasterLevel, nBaseHD));
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
}
else
{
return json_AddEvolvedPowers(jCreature, nBaseHD, nCasterLevel, iEvolution);
}
break;
case 3:
if (nBaseHD >= 4)
{
int i;
for (i = 0; i < 1; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 25);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", PRCMax(nCasterLevel, nBaseHD));
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
}
else
{
return json_AddEvolvedPowers(jCreature, nBaseHD, nCasterLevel, iEvolution);
}
break;
case 4:
if (nBaseHD >= 3)
{
int i;
for (i = 0; i < 1; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 26);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", PRCMax(nCasterLevel, nBaseHD));
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
}
else
{
return json_AddEvolvedPowers(jCreature, nBaseHD, nCasterLevel, iEvolution);
}
break;
case 5:
if (nBaseHD >= 3)
{
int i;
for (i = 0; i < 1; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 27);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", PRCMax(nCasterLevel, nBaseHD));
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
}
else
{
return json_AddEvolvedPowers(jCreature, nBaseHD, nCasterLevel, iEvolution);
}
break;
case 6:
if (nBaseHD >= 7)
{
int i;
for (i = 0; i < 1; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 364);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", PRCMax(nCasterLevel, nBaseHD));
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
}
else
{
return json_AddEvolvedPowers(jCreature, nBaseHD, nCasterLevel, iEvolution);
}
break;
case 7:
if (nBaseHD >= 5)
{
int i;
for (i = 0; i < 1; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 67);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", PRCMax(nCasterLevel, nBaseHD));
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
}
else
{
return json_AddEvolvedPowers(jCreature, nBaseHD, nCasterLevel, iEvolution);
}
break;
case 8:
if (nBaseHD >= 4)
{
int i;
for (i = 0; i < 1; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 88);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", PRCMax(nCasterLevel, nBaseHD));
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
}
else
{
return json_AddEvolvedPowers(jCreature, nBaseHD, nCasterLevel, iEvolution);
}
break;
case 9:
if (nBaseHD >= 3)
{
int i;
for (i = 0; i < 1; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 78);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", PRCMax(nCasterLevel, nBaseHD));
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
}
else
{
return json_AddEvolvedPowers(jCreature, nBaseHD, nCasterLevel, iEvolution);
}
break;
case 10:
if (nBaseHD >= 4)
{
int i;
for (i = 0; i < 1; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 82);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", PRCMax(nCasterLevel, nBaseHD));
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
}
else
{
return json_AddEvolvedPowers(jCreature, nBaseHD, nCasterLevel, iEvolution);
}
break;
case 11:
if (nBaseHD >= 2)
{
int i;
for (i = 0; i < 1; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 157);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", PRCMax(nCasterLevel, nBaseHD));
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
}
else
{
return json_AddEvolvedPowers(jCreature, nBaseHD, nCasterLevel, iEvolution);
}
break;
case 12:
if (nBaseHD >= 5)
{
int i;
for (i = 0; i < 1; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 566);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", PRCMax(nCasterLevel, nBaseHD));
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
}
else
{
return json_AddEvolvedPowers(jCreature, nBaseHD, nCasterLevel, iEvolution);
}
break;
default:
// Fallback to Doom for creatures with 1HD or less.
int i;
for (i = 0; i < 1; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 46); // Doom spell
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", PRCMax(nCasterLevel, nBaseHD));
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
break;
}
return jCreature = GffAddList(jCreature, "SpecAbilityList", jSpecAbilityList);
}
//:: Apply Evolved effects to a non-PC creature
void ApplyEvolvedEffects(object oCreature, int nBaseHD, int nCasterLevel, int iEvolution)
{
//:: Declare major variables
int bIncorporeal = GetIsIncorporeal(oCreature);
effect eVolved;
//:: Boost caster & SLA level
SetLocalInt(oCreature, PRC_CASTERLEVEL_ADJUSTMENT, PRCMax(nCasterLevel, nBaseHD));
//:: AC Bonuses: +1 natural or +1 deflection if Incorporal
if(bIncorporeal)
{
eVolved = EffectACIncrease(1+iEvolution, AC_DEFLECTION_BONUS);
}
else
{
eVolved = EffectACIncrease(1+iEvolution, AC_NATURAL_BONUS);
}
//:: Fast Healing 3
eVolved = EffectLinkEffects(eVolved, EffectRegenerate(3, 6.0f));
//:: Make *really* permanent
eVolved = UnyieldingEffect(eVolved);
//:: Apply everything
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVolved, oCreature);
}
void main()
{
//:: Declare major variables
object oBaseCreature = OBJECT_SELF;
object oNewCreature;
int bIncorporeal = GetIsIncorporeal(oBaseCreature);
int iBaseRace = MyPRCGetRacialType(oBaseCreature);
int nCasterLevel = PRCGetCasterLevel(oBaseCreature);
int iEvolution = GetLocalInt(oBaseCreature, "UNDEAD_EVOLUTION");
//:: Creatures & NPCs only
if ((GetObjectType(oBaseCreature) != OBJECT_TYPE_CREATURE) || (GetIsPC(oBaseCreature) == TRUE))
{
if(DEBUG) DoDebug("Not a creature");
return;
}
//:: Undead only
if(iBaseRace != RACIAL_TYPE_UNDEAD)
{
//SendMessageToPC(GetFirstPC(), "make_evolved: Invalid racial type for template.");
if(DEBUG) DoDebug("make_evolved: Invalid racial type for template.");
return;
}
int nBaseHD = GetHitDice(oBaseCreature);
int nBaseCR = FloatToInt(GetChallengeRating(oBaseCreature));
json jBaseCreature = ObjectToJson(oBaseCreature, TRUE);
json jNewCreature;
json jFinalCreature;
//:: Add Spell-like abilities
jNewCreature = json_AddEvolvedPowers(jBaseCreature, nBaseHD, nCasterLevel, iEvolution);
//:: Update stats
if(bIncorporeal)
{
//:: Incorporeal = CHA only
jNewCreature = json_UpdateStats(jNewCreature, oBaseCreature, 0, 0, 0, 0, 0, 2);
}
else
{
jNewCreature = json_UpdateStats(jNewCreature, oBaseCreature, 2, 0, 0, 0, 0, 2);
}
//:: Update CR
jFinalCreature = json_UpdateCR(jNewCreature, nBaseCR, 1);
//:: Update the creature
oNewCreature = JsonToObject(jFinalCreature, GetLocation(oBaseCreature));
DestroyObject(oBaseCreature, 0.0f);
//:: Apply effects
ApplyEvolvedEffects(oNewCreature, nBaseHD, nCasterLevel, iEvolution);
PRCForceRest(oNewCreature);
//:: Update creature's name on first advancement
string sBaseName = GetName(oNewCreature);
if(iEvolution < 1)
{
SetName(oNewCreature, "Evolved "+ sBaseName);
}
if(iEvolution < 4)
{
SetName(oNewCreature, "Greater "+ sBaseName);
}
//:: Update race field
SetSubRace(oNewCreature, "Undead (Augmented)");
SetAge(oNewCreature, GetAge(oNewCreature) + d100(1));
//:: Set variables
SetLocalInt(oNewCreature, "UNDEAD_EVOLUTION", iEvolution+1);
SetLocalInt(oNewCreature, "TEMPLATE_EVOLVED", 1);
}