2022-10-10 08:16:23 -04:00
|
|
|
//:://////////////////////////////////////////////////
|
|
|
|
//:: prc_pwonspawn
|
|
|
|
/*
|
|
|
|
PRC's OnSpawn event handler for NPCs.
|
|
|
|
|
|
|
|
*/
|
|
|
|
//:://////////////////////////////////////////////////
|
|
|
|
|
2023-10-26 22:05:43 -04:00
|
|
|
#include "NW_I0_GENERIC"
|
|
|
|
#include "nw_i0_plot"
|
|
|
|
#include "rd_level"
|
|
|
|
#include "inc_sqlite_time"
|
2024-11-08 18:54:51 -05:00
|
|
|
#include "inc_debug"
|
|
|
|
#include "prc_inc_racial"
|
|
|
|
#include "sd_lootsystem"
|
2024-11-12 15:25:30 -05:00
|
|
|
#include "prc_inc_spells"
|
2023-10-26 22:05:43 -04:00
|
|
|
|
|
|
|
void ReallyEquipItemInSlot(object oNPC, object oItem, int nSlot);
|
|
|
|
|
2024-10-30 13:07:27 -04:00
|
|
|
void ReallyEquipItemInSlot(object oNPC, object oItem, int nSlot)
|
|
|
|
{
|
|
|
|
if (GetItemInSlot(nSlot) != oItem)
|
|
|
|
{
|
|
|
|
//ClearAllActions();
|
|
|
|
AssignCommand(oNPC, ActionEquipItem(oItem, nSlot));
|
|
|
|
DelayCommand(0.5, ReallyEquipItemInSlot(oNPC, oItem, nSlot));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-13 14:05:19 -05:00
|
|
|
void EvolvedUndeadCheck(object oUndead)
|
|
|
|
{
|
|
|
|
// Check if the creature is undead and intelligent
|
|
|
|
if (MyPRCGetRacialType(oUndead) != RACIAL_TYPE_UNDEAD || !GetAbilityModifier(ABILITY_INTELLIGENCE, oUndead) > -1)
|
|
|
|
{
|
|
|
|
return; // Exit if not an intelligent undead
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the undead's area and its age
|
|
|
|
object oArea = GetArea(oUndead);
|
|
|
|
int iUndeadAge = GetAge(oUndead);
|
|
|
|
|
|
|
|
// Base evolution chance: 1% for every 100 years
|
|
|
|
int iBaseChance = iUndeadAge / 100;
|
|
|
|
|
|
|
|
// Add chance modifiers: ancient energy and previous evolutions
|
|
|
|
int iAncientBoost = GetLocalInt(oArea, "EVO_UNDEAD_BOOST"); // Area-specific boost
|
|
|
|
int iEvolutionCount = GetLocalInt(oUndead, "UNDEAD_EVOLUTION"); // Previous evolutions
|
|
|
|
int iChance = iBaseChance + iAncientBoost + iEvolutionCount;
|
|
|
|
|
|
|
|
// Roll the dice (1-100)
|
|
|
|
int iRoll = Random(100) + 1;
|
|
|
|
|
|
|
|
// Debug message to monitor rolls and chances
|
|
|
|
if(DEBUG)
|
|
|
|
{
|
|
|
|
DoDebug("Evolution Check: Roll = " + IntToString(iRoll) + ", Chance = " + IntToString(iChance));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if the undead evolves
|
|
|
|
if (iRoll <= iChance)
|
|
|
|
{
|
|
|
|
// Apply evolution template
|
|
|
|
ExecuteScript("make_evolved", oUndead); // Apply template script
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-10-10 08:16:23 -04:00
|
|
|
void main()
|
|
|
|
{
|
2023-10-26 22:05:43 -04:00
|
|
|
//:: Initialize Major Variables
|
|
|
|
effect eVFX;
|
|
|
|
|
|
|
|
int nTotalPCs;
|
|
|
|
int nTotalPCLevel;
|
|
|
|
int nAveragePCLevel;
|
2024-11-08 18:54:51 -05:00
|
|
|
int iRacial = GetRacialType(OBJECT_SELF);
|
2024-11-12 15:25:30 -05:00
|
|
|
int nCommoner = GetLevelByClass(CLASS_TYPE_COMMONER, OBJECT_SELF);
|
|
|
|
int nInt = GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE);
|
|
|
|
int nGhost = GetIsIncorporeal(OBJECT_SELF);
|
2023-10-26 22:05:43 -04:00
|
|
|
|
|
|
|
string sCurrentDate = SQLite_GetSystemDate();
|
|
|
|
string sMonthDay = GetSubString(sCurrentDate, 0, 5);
|
|
|
|
|
|
|
|
object oArea = GetArea(OBJECT_SELF);
|
|
|
|
object oSkelly;
|
|
|
|
object oPC = GetFirstObjectInArea(oArea);
|
2024-11-12 15:25:30 -05:00
|
|
|
|
|
|
|
//:: Check if the creature is an animal, beast, construct, or ooze, which should never carry treasure
|
2024-11-08 18:54:51 -05:00
|
|
|
if (iRacial == RACIAL_TYPE_ANIMAL ||
|
|
|
|
iRacial == RACIAL_TYPE_BEAST ||
|
|
|
|
iRacial == RACIAL_TYPE_CONSTRUCT ||
|
2024-11-12 15:25:30 -05:00
|
|
|
iRacial == RACIAL_TYPE_OOZE)
|
|
|
|
{
|
|
|
|
if (DEBUG) { FloatingTextStringOnCreature("Creature doesn't carry treasure", GetFirstPC(), FALSE); }
|
|
|
|
}
|
|
|
|
else if ((iRacial == RACIAL_TYPE_UNDEAD ||
|
|
|
|
iRacial == RACIAL_TYPE_PLANT ||
|
|
|
|
iRacial == RACIAL_TYPE_VERMIN) &&
|
|
|
|
nInt <= 4)
|
2024-11-08 18:54:51 -05:00
|
|
|
{
|
2024-11-12 15:25:30 -05:00
|
|
|
//:: If the creature is undead, plant, or vermin with intelligence 4 or less, it does not carry treasure
|
|
|
|
if (DEBUG) { FloatingTextStringOnCreature("Creature is not intelligent enough to carry treasure", GetFirstPC(), FALSE); }
|
|
|
|
}
|
|
|
|
else if(nGhost)
|
|
|
|
{
|
|
|
|
//:: If the creature is undead, plant, or vermin with intelligence 4 or less, it does not carry treasure
|
|
|
|
if (DEBUG) { FloatingTextStringOnCreature("Creature is incorporeal and can't carry treasure", GetFirstPC(), FALSE); }
|
2024-11-08 18:54:51 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-11-12 15:25:30 -05:00
|
|
|
//:: All other creatures, including undead, plants, and vermin with intelligence > 4, will drop loot
|
|
|
|
sd_droploot(OBJECT_SELF, OBJECT_SELF);
|
2024-11-08 18:54:51 -05:00
|
|
|
}
|
|
|
|
|
2023-10-26 22:05:43 -04:00
|
|
|
//:: Get average PC level for area
|
|
|
|
//:: Cycle through PCs in Area
|
|
|
|
|
|
|
|
while (oPC != OBJECT_INVALID)
|
|
|
|
{
|
|
|
|
if (GetIsPC(oPC) == TRUE)
|
|
|
|
{
|
|
|
|
nTotalPCs++;
|
|
|
|
nTotalPCLevel = nTotalPCLevel + GetHitDice(oPC);
|
|
|
|
}
|
|
|
|
|
|
|
|
oPC = GetNextObjectInArea(oArea);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nTotalPCs > 0)
|
|
|
|
{
|
2023-10-29 13:45:22 -04:00
|
|
|
nAveragePCLevel = (nTotalPCLevel / nTotalPCs) - 1;
|
2023-10-26 22:05:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
{
|
2023-10-29 13:45:22 -04:00
|
|
|
nAveragePCLevel = 2;
|
2023-10-26 22:05:43 -04:00
|
|
|
}
|
2024-12-13 19:40:24 -05:00
|
|
|
|
|
|
|
//:: Paragon Check
|
|
|
|
if (Random(9999) == 0)
|
|
|
|
{
|
|
|
|
if(GetLocalInt(OBJECT_SELF, "TEMPLATE_PARAGON") < 1)
|
|
|
|
{
|
|
|
|
ExecuteScript("make_paragon", OBJECT_SELF);
|
|
|
|
}
|
|
|
|
}
|
2024-12-13 14:05:19 -05:00
|
|
|
|
|
|
|
//:: Setup Evolved Undead
|
|
|
|
if(iRacial == RACIAL_TYPE_UNDEAD)
|
|
|
|
{
|
|
|
|
SetAge(OBJECT_SELF, d20(6));
|
|
|
|
|
|
|
|
EvolvedUndeadCheck(OBJECT_SELF);
|
|
|
|
}
|
|
|
|
|
|
|
|
//:: Set threatlevel name text
|
|
|
|
SetThreatLevel(OBJECT_SELF);
|
2023-10-26 22:05:43 -04:00
|
|
|
|
|
|
|
//:: Only active during Halloween week.
|
|
|
|
if ((sMonthDay == "10/24") ||
|
|
|
|
(sMonthDay == "10/25") ||
|
|
|
|
(sMonthDay == "10/26") ||
|
|
|
|
(sMonthDay == "10/27") ||
|
|
|
|
(sMonthDay == "10/28") ||
|
|
|
|
(sMonthDay == "10/29") ||
|
|
|
|
(sMonthDay == "10/30") ||
|
|
|
|
(sMonthDay == "10/31") ||
|
|
|
|
(sMonthDay == "11/01"))
|
2024-11-12 15:25:30 -05:00
|
|
|
{
|
|
|
|
//: Don't spawn skeletons from skeletons or commoners
|
|
|
|
if (GetResRef(OBJECT_SELF) == "pa_skeleton" || GetResRef(OBJECT_SELF) == "nw_skeleton" || nCommoner > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
//:: 33% chance to spawn
|
|
|
|
if ( Random(100) < 33 )
|
|
|
|
{
|
|
|
|
//:: Spawn Skeleton.
|
|
|
|
eVFX = EffectVisualEffect(VFX_IMP_EVIL_HELP);
|
|
|
|
oSkelly = CreateObject(OBJECT_TYPE_CREATURE, "nw_skeleton", GetLocation(OBJECT_SELF));
|
|
|
|
DelayCommand(0.0, ActionDoLevelUp(oSkelly, nAveragePCLevel));
|
2024-10-30 13:07:27 -04:00
|
|
|
|
|
|
|
//:: Assign Weapon
|
2024-11-12 15:25:30 -05:00
|
|
|
int nResult = d6(1);
|
|
|
|
int nStackSize = 1; // Create 1 items;
|
|
|
|
string sItem;
|
2023-10-26 22:05:43 -04:00
|
|
|
|
2024-11-12 15:25:30 -05:00
|
|
|
if (nResult == 1)
|
|
|
|
{
|
|
|
|
sItem = "nw_wplhb001"; //:: Halberd
|
2023-10-26 22:05:43 -04:00
|
|
|
}
|
2024-11-12 15:25:30 -05:00
|
|
|
else if(nResult == 2)
|
|
|
|
{
|
|
|
|
sItem = "nw_wplsc001"; //:: Scythe
|
|
|
|
}
|
|
|
|
else if(nResult == 3)
|
|
|
|
{
|
|
|
|
sItem = "nw_wplss001"; //:: Spear
|
|
|
|
}
|
|
|
|
else if(nResult ==4)
|
|
|
|
{
|
|
|
|
sItem = "nw_wblfh001"; //:: Heavy Flail
|
|
|
|
}
|
|
|
|
else if(nResult == 5)
|
|
|
|
{
|
|
|
|
sItem = "nw_wswgs001"; //:: Greatsword
|
|
|
|
}
|
|
|
|
else
|
|
|
|
|
|
|
|
sItem = "nw_waxgr001"; //:: Greataxe
|
|
|
|
|
|
|
|
object oWeapon = CreateItemOnObject(sItem, oSkelly, nStackSize);
|
|
|
|
ReallyEquipItemInSlot(oSkelly, oWeapon, INVENTORY_SLOT_RIGHTHAND);
|
|
|
|
|
|
|
|
//:: Apply VFX & Attack
|
|
|
|
AssignCommand(oSkelly, DetermineCombatRound(OBJECT_SELF));
|
|
|
|
DelayCommand(0.3, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oSkelly));
|
|
|
|
}
|
|
|
|
}
|
2024-10-30 13:07:27 -04:00
|
|
|
}
|