Ancordia_PRC8/_module/nss/execute_onenter.nss
Jaysyn904 102ba7dab6 Initial Commit
Initial Commit
2023-09-21 19:51:32 -04:00

212 lines
8.2 KiB
Plaintext

#include "_sh_inc_list"
#include "events_inc"
//A function to spawn enemies
void SpawnRandomEnemies(object oPC, string sAreaString, int nEncounterType)
{
//Identify a region by the area string
string sRegionString = GetStringLeft(sAreaString, 1);
//Get PC's level to determine enemies to spawn
int nLevel = GetHitDice(oPC);
//Modify the level to spawn weaker enemies for encounters other than with a "mini-boss"
if (nEncounterType != ENCOUNTER_TYPE_MINIBOSS)
{
if (nLevel == 1) nLevel = 0;
else if (nLevel <= 3) nLevel = 1;
else if (nLevel <= 20) nLevel = nLevel - 2;
else nLevel = nLevel - 3;
//30% of the time (unless it's an encounter with a mini-boss) the PC will find weaker enemies
if (Random(100) <= 29 && nLevel >= 4)
{
if (nLevel <= 20) nLevel = Random(nLevel-1);
else nLevel = Random(21);
}
}
//Select possible enemies
SelectEnemies(sRegionString, nLevel, oPC, nEncounterType);
string sEnemy1 = GetLocalString(oPC, "sEnemy1");
string sEnemy2 = GetLocalString(oPC, "sEnemy2");
string sEnemy3 = GetLocalString(oPC, "sEnemy3");
string sEnemy4 = GetLocalString(oPC, "sEnemy4");
string sEnemy5 = GetLocalString(oPC, "sEnemy5");
string sEnemy6 = GetLocalString(oPC, "sEnemy6");
string sAdd1 = GetLocalString(oPC, "sAdd1");
string sAdd2 = GetLocalString(oPC, "sAdd2");
string sAdd3 = GetLocalString(oPC, "sAdd3");
string sAdd4 = GetLocalString(oPC, "sAdd4");
DeleteEnemyVar(oPC);
//Spawn 2 enemies for ENCOUNTER_TYPE_FEW, 3 for ENCOUNTER_TYPE_NORMAL and 4 for ENCOUNTER_TYPE_MANY if there are no adds
location lWaypoint;
string sWayTag;
int nWayNumber;
int i;
object oCreature;
if (sAdd1 == "")
{
//Spawning main enemies
if (nEncounterType == ENCOUNTER_TYPE_FEW) nWayNumber = 2;
if (nEncounterType == ENCOUNTER_TYPE_NORMAL) nWayNumber = 3;
if (nEncounterType == ENCOUNTER_TYPE_MANY) nWayNumber = 4;
if (nEncounterType == ENCOUNTER_TYPE_MINIBOSS) nWayNumber = 1;
for (i = 1; i <= nWayNumber; i++)
{
sWayTag = "rand_wp_" + sAreaString + "_" + IntToString(i);
lWaypoint = GetLocation(GetWaypointByTag(sWayTag));
oCreature = CreateObject(OBJECT_TYPE_CREATURE, SelectMain(sEnemy1, sEnemy2, sEnemy3, sEnemy4, sEnemy5, sEnemy6), lWaypoint);
ScaleCreature(oCreature, nLevel);
AssignCommand(oCreature, ActionRandomWalk());
}
}
//Spawn 4 enemies (3 adds) for ENCOUNTER_TYPE_FEW, 5 (3 adds) for ENCOUNTER_TYPE_NORMAL and 6 (4 adds) for ENCOUNTER_TYPE_MANY if there are no adds
else
{
//Spawning main enemies
if (nEncounterType == ENCOUNTER_TYPE_FEW) nWayNumber = 1;
if (nEncounterType == ENCOUNTER_TYPE_NORMAL) nWayNumber = 2;
if (nEncounterType == ENCOUNTER_TYPE_MANY) nWayNumber = 2;
if (nEncounterType == ENCOUNTER_TYPE_MINIBOSS) nWayNumber = 1;
for (i = 1; i <= nWayNumber; i++)
{
sWayTag = "rand_wp_" + sAreaString + "_" + IntToString(i);
lWaypoint = GetLocation(GetWaypointByTag(sWayTag));
oCreature = CreateObject(OBJECT_TYPE_CREATURE, SelectMain(sEnemy1, sEnemy2, sEnemy3, sEnemy4, sEnemy5, sEnemy6), lWaypoint);
AssignCommand(oCreature, ActionRandomWalk());
}
//Spawning adds
if (nEncounterType == ENCOUNTER_TYPE_FEW) nWayNumber = i+3;
if (nEncounterType == ENCOUNTER_TYPE_NORMAL) nWayNumber = i+3;
if (nEncounterType == ENCOUNTER_TYPE_MANY) nWayNumber = i+4;
if (nEncounterType == ENCOUNTER_TYPE_MINIBOSS) nWayNumber = 0;
for (i = i; i <= nWayNumber; i++)
{
if (nWayNumber == 0) break; //Nothing to do here if it's a mini-boss encounter
sWayTag = "rand_wp_" + sAreaString + "_" + IntToString(i);
lWaypoint = GetLocation(GetWaypointByTag(sWayTag));
oCreature = CreateObject(OBJECT_TYPE_CREATURE, SelectAdd(sAdd1, sAdd2, sAdd3, sAdd4), lWaypoint);
AssignCommand(oCreature, ActionRandomWalk());
}
}
}
void main()
{
//Get the area we're in from the area variable, get the PC and declare some variables
string sAreaString = GetLocalString(OBJECT_SELF, "AreaString");
object oPC = GetLocalObject(GetModule(), "TravellingPC");
int nEncounterType;
//Sanity check
if (!GetIsPC(oPC)) return;
//Determine whether a chest/village/dungeon should be possible to discover
int nCanDiscover = GetLocalInt(oPC, "CanDiscover");
//Do nothing if there is already another PC in the area (and the area integer is TRUE) or try a spot/listen check if an ambush is prepared
if (GetLocalInt(OBJECT_SELF, "IsPopulated") == TRUE)
{
int nDC = GetLocalInt(OBJECT_SELF, "Level");
if (nDC == 0) return;
int nSkillRoll;
string sString;
nSkillRoll = GetSkillRank(SKILL_SPOT, oPC) + d20();
if (nSkillRoll >= nDC) sString = "[Spot] Ambush detected!";
else
{
nSkillRoll = GetSkillRank(SKILL_LISTEN, oPC) + d20();
if (nSkillRoll >= nDC) sString = "[Listen] Ambush detected!";
}
FloatingTextStringOnCreature(sString, oPC, FALSE);
return;
}
//Otherwise flag this area as populated, so that no event is generated for next players entering it
SetLocalInt(OBJECT_SELF, "IsPopulated", TRUE);
//Delete this area from the list of free areas
string sRegionString = GetStringLeft(sAreaString, 1);
string sList = "sList"+sRegionString;
object oList = GetLocalObject(GetModule(), sList);
int i;
for (i = 1; i <= ListGetElementCount(oList); i++)
{
if (ListGetString(oList, i) == sAreaString) ListRemoveElement(oList, i);
}
int nRandom = Random(100)+1;
FloatingTextStringOnCreature(IntToString(nRandom), oPC); //TEST
//Spawn a random chest 5% of the time on one of three chest waypoints (only if CanDiscover is TRUE)
int nChestWaypoint;
string sChestWaypoint;
object oChestWp;
if (Random(20) == 0 && nCanDiscover > 1)
{
nChestWaypoint = Random(3)+1;
sChestWaypoint = IntToString(nChestWaypoint);
oChestWp = GetWaypointByTag("chest_wp_"+sAreaString+"_"+sChestWaypoint);
SpawnTreasureChest(oPC, oChestWp);
}
//Determine whether a PC encounters a village/dungeon at the end of the area
if (nCanDiscover > 1)
{
if (Random(10) == 0) SetLocalInt(OBJECT_SELF, "DiscoveredVillage", TRUE);
if (Random(20) == 0) SetLocalInt(OBJECT_SELF, "DiscoveredDungeon", TRUE);
}
//Nothing in particular happens 40% of the time
if (nRandom <= 40) return;
//Regular enemies encountered 40% of the time
if (nRandom <= 80)
{
nRandom = Random(100)+1;
//A single strong opponent is encountered 20% of the time
if (nRandom <= 20) nEncounterType = ENCOUNTER_TYPE_MINIBOSS;
//A few regular enemies are encountered 20% of the time
else if (nRandom <= 40) nEncounterType = ENCOUNTER_TYPE_FEW;
//Many regular enemies are encountered 20% of the time
else if (nRandom <= 60) nEncounterType = ENCOUNTER_TYPE_MANY;
//An average number of regular enemies is encountered 40% of the time
else nEncounterType = ENCOUNTER_TYPE_NORMAL;
}
//An event occurs 20% of the time
else
{
switch (Random(10))
{
case 0: SpawnNemesisEvent(oPC); break;
case 1: SpawnEscortEvent(oPC); break;
case 2: SpawnTributeEvent(oPC); break;
case 3: SpawnAmbushEvent(oPC); break;
case 4: SpawnAdventurerEvent(oPC); break;
case 5: SpawnDemonEvent(oPC); break;
case 6: SpawnBulliedEvent(oPC); break;
case 7: SpawnMerchantEvent(oPC); break;
case 8: SpawnBossEvent(oPC); break;
case 9: SpawnFriendlyEvent(oPC); break;
}
}
//If it's a regular enemy encounter, spawn them
SpawnRandomEnemies(oPC, sAreaString, nEncounterType);
}