2025/09/07 Update
Added Amulet of Mighty Fists +1 thru +5. Added Greenbound template. Fixed Evolved & Paragon templates. Updated several area names.
This commit is contained in:
216
_module/nss/creature_copy.nss
Normal file
216
_module/nss/creature_copy.nss
Normal file
@@ -0,0 +1,216 @@
|
||||
#include "nw_inc_gff"
|
||||
#include "npc_template_inc"
|
||||
#include "prc_inc_spells"
|
||||
#include "prc_inc_util"
|
||||
#include "prc_inc_json"
|
||||
|
||||
//:: Adds Evolved SLA's to jCreature.
|
||||
//::
|
||||
json json_AddEvolvedPowers(json jCreature, int nBaseHD, int nCasterLevel, int iEvolution)
|
||||
{
|
||||
int nAttempts = 0;
|
||||
json jSpecAbilityList = GffGetList(jCreature, "SpecAbilityList");
|
||||
if (jSpecAbilityList == JsonNull()) jSpecAbilityList = JsonArray();
|
||||
|
||||
while (nAttempts < 20) // safety cap
|
||||
{
|
||||
nAttempts++;
|
||||
int nRandom = d12(1);
|
||||
json jSpecAbility = JsonObject();
|
||||
|
||||
switch(nRandom)
|
||||
{
|
||||
case 1:
|
||||
if (nBaseHD < 6) continue;
|
||||
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 18);
|
||||
break;
|
||||
case 2:
|
||||
if (nBaseHD < 5) continue;
|
||||
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 23);
|
||||
break;
|
||||
case 3:
|
||||
if (nBaseHD < 4) continue;
|
||||
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 25);
|
||||
break;
|
||||
case 4:
|
||||
if (nBaseHD < 3) continue;
|
||||
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 26);
|
||||
break;
|
||||
case 5:
|
||||
if (nBaseHD < 3) continue;
|
||||
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 27);
|
||||
break;
|
||||
case 6:
|
||||
if (nBaseHD < 7) continue;
|
||||
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 364);
|
||||
break;
|
||||
case 7:
|
||||
if (nBaseHD < 5) continue;
|
||||
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 67);
|
||||
break;
|
||||
case 8:
|
||||
if (nBaseHD < 4) continue;
|
||||
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 88);
|
||||
break;
|
||||
case 9:
|
||||
if (nBaseHD < 3) continue;
|
||||
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 78);
|
||||
break;
|
||||
case 10:
|
||||
if (nBaseHD < 4) continue;
|
||||
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 82);
|
||||
break;
|
||||
case 11:
|
||||
if (nBaseHD < 2) continue;
|
||||
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 157);
|
||||
break;
|
||||
case 12:
|
||||
if (nBaseHD < 5) continue;
|
||||
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 566);
|
||||
break;
|
||||
default:
|
||||
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 46); // Doom fallback
|
||||
break;
|
||||
}
|
||||
|
||||
// If jSpecAbility still empty for some reason, retry
|
||||
if (JsonGetType(jSpecAbility) != JSON_TYPE_OBJECT) continue;
|
||||
|
||||
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", PRCMax(nCasterLevel, nBaseHD));
|
||||
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
|
||||
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
|
||||
break;
|
||||
}
|
||||
|
||||
return 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;
|
||||
|
||||
GetObjectUUID(oBaseCreature);
|
||||
|
||||
int bIncorporeal = GetIsIncorporeal(oBaseCreature);
|
||||
int iBaseRace = MyPRCGetRacialType(oBaseCreature);
|
||||
int nCasterLevel = PRCGetCasterLevel(oBaseCreature);
|
||||
|
||||
int iEvolution = 1;
|
||||
int iOldEvolution = GetLocalInt(oBaseCreature, "UNDEAD_EVOLUTION");
|
||||
|
||||
//:: Creatures & NPCs only
|
||||
if ((GetObjectType(oBaseCreature) != OBJECT_TYPE_CREATURE) || (GetIsPC(oBaseCreature) == TRUE))
|
||||
{
|
||||
DoDebug("Not a creature");
|
||||
return;
|
||||
}
|
||||
|
||||
//:: Undead only
|
||||
if(iBaseRace != RACIAL_TYPE_UNDEAD)
|
||||
{
|
||||
//SendMessageToPC(GetFirstPC(), "make_evolved: Invalid racial type for template.");
|
||||
DoDebug("make_evolved: Invalid racial type for template.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* if(DEBUG) */DoDebug("make_evolved: Previous Evolution is: " +IntToString(iOldEvolution));
|
||||
|
||||
iEvolution = iEvolution + iOldEvolution;
|
||||
|
||||
/* if(DEBUG) */DoDebug("make_evolved: Evolution is: " +IntToString(iEvolution));
|
||||
|
||||
int nBaseHD = GetHitDice(oBaseCreature);
|
||||
int nBaseCR = FloatToInt(GetChallengeRating(oBaseCreature));
|
||||
|
||||
location lSpawnLoc = GetLocation(oBaseCreature);
|
||||
|
||||
json jBaseCreature = ObjectToJson(oBaseCreature, FALSE);
|
||||
json jNewCreature;
|
||||
json jFinalCreature;
|
||||
|
||||
//:: Update creature's name on first advancement
|
||||
string sBaseName = GetName(oBaseCreature);
|
||||
|
||||
//:: Add Spell-like abilities
|
||||
jNewCreature = json_AddEvolvedPowers(jBaseCreature, nBaseHD, nCasterLevel, iEvolution);
|
||||
|
||||
//:: Update stats
|
||||
if(bIncorporeal)
|
||||
{
|
||||
//:: Incorporeal = CHA only
|
||||
jNewCreature = json_UpdateCreatureStats(jNewCreature, oBaseCreature, 0, 0, 0, 0, 0, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
jNewCreature = json_UpdateCreatureStats(jNewCreature, oBaseCreature, 2, 0, 0, 0, 0, 2);
|
||||
}
|
||||
|
||||
//:: Apply effects
|
||||
ApplyEvolvedEffects(oNewCreature, nBaseHD, nCasterLevel, iEvolution);
|
||||
|
||||
|
||||
jFinalCreature = jNewCreature;
|
||||
|
||||
//:: Destroy Original creature
|
||||
DestroyObject(oBaseCreature, 0.0f);
|
||||
|
||||
//:: Update the creature
|
||||
oNewCreature = JsonToObject(jFinalCreature, lSpawnLoc);
|
||||
|
||||
if(DEBUG) DoDebug("make_evolved: Final evolution is: " +IntToString(iEvolution));
|
||||
if (iEvolution == 1)
|
||||
{
|
||||
SetName(oNewCreature, "Evolved " + sBaseName);
|
||||
}
|
||||
else if (iEvolution == 2)
|
||||
{
|
||||
SetName(oNewCreature, "Greater " + sBaseName);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetName(oNewCreature, sBaseName);
|
||||
}
|
||||
|
||||
//:: Update race field
|
||||
SetSubRace(oNewCreature, "Undead (Augmented)");
|
||||
|
||||
//:: Update Age
|
||||
SetAge(oNewCreature, GetAge(oNewCreature) + d100(1));
|
||||
|
||||
//:: Set variables
|
||||
SetLocalInt(oNewCreature, "UNDEAD_EVOLUTION", iEvolution);
|
||||
SetLocalInt(oNewCreature, "TEMPLATE_EVOLVED", 1);
|
||||
}
|
Reference in New Issue
Block a user