Added new Patrol Spawner mechanism and added it to the Dantooine Imperial Outpost fixing issues with respawns and overall patrols themselves.

This commit is contained in:
Cekis
2016-07-30 16:43:49 +01:00
parent aaeeddd6b5
commit 2d2f49aedc
6 changed files with 367 additions and 131 deletions
@@ -0,0 +1,24 @@
faction leader squadClass template minSpawnChance maxSpawnChance
s i s s i i
imperial 0 armored stormtrooper 0 50
imperial 1 armored stormtrooper_squad_leader 51 75
imperial 0 armored stormtrooper_captain 76 85
imperial 0 armored stormtrooper_major 86 90
imperial 0 armored stormtrooper_medic 91 100
imperial 0 plain imperial_private 0 50
imperial 0 plain imperial_corporal 51 75
imperial 0 plain imperial_sergeant_major 76 85
imperial 0 plain imperial_staff_sergeant 86 90
imperial 1 plain imperial_master_sergeant 91 100
rebel 0 armored rebel_scout 0 50
rebel 1 armored rebel_trooper 51 75
rebel 0 armored rebel_commando 76 85
rebel 0 armored rebel_major 86 90
rebel 0 armored rebel_medic 91 100
rebel 0 plain rebel_corporal 0 50
rebel 0 plain rebel_lance_corporal 51 75
rebel 0 plain rebel_sergeant 76 85
rebel 0 plain rebel_staff_sergeant 86 90
rebel 1 plain rebel_master_sergeant 91 100
neutral 0 armored mercenary 0 50
neutral 1 armored mercenary_aggro 51 100
@@ -0,0 +1,12 @@
@base object/tangible/poi/base/poi_base.iff
@class tangible_object_template 0
@class object_template 8
visibleFlags = [VF_gm]
persistByDefault = false
scripts =+ [ "theme_park.patrols.patrol_controller"]
@@ -63,18 +63,19 @@ public class spawner_patrol extends script.base_script
if ((strSpawns == null) || (strSpawns.length == 0))
{
LOG("spawning", "NO SPAWNS IN FILE " + strFileName);
setName(self, "Mangled spawner. strFileName is " + strFileName + " I couldnt find any spawns in that file.");
setName(self, "Mangled spawner: strFileName is " + strFileName + " I couldnt find any spawns in that file.");
return SCRIPT_CONTINUE;
}
if (fltSizes.length == 0)
{
LOG("spawning", "BAD NUMBER OF SIZES !@!@@ IN FILE " + strFileName);
setName(self, "BAD NUMBER OF SIZES !@!@@ IN FILE " + strFileName);
setName(self, "Mangled spawner: BAD NUMBER OF SIZES !@!@@ IN FILE " + strFileName);
return SCRIPT_CONTINUE;
}
if (fltSizes.length != strSpawns.length)
{
LOG("spawning", "Missing either spawns or sizes in " + strFileName);
setName(self, "Missing either spawns or sizes in " + strFileName);
setName(self, "Mangled spawner: Missing either spawns or sizes in " + strFileName);
return SCRIPT_CONTINUE;
}
}
@@ -82,12 +83,14 @@ public class spawner_patrol extends script.base_script
if (patrolPoints == null)
{
LOG("spawning", "ERROR: patrolArray script var not defined.");
setName(self, "Mangled spawner: no patrol points could be identified via patrolArray.");
return SCRIPT_CONTINUE;
}
int maxSpawns = getIntObjVar(self, "intSpawnCount");
if (maxSpawns >= patrolPoints.length)
{
LOG("spawning", "ERROR: Attempting to spawn more creatures than patrol points.");
setName(self, "Mangled spawner: there are more creatures than patrol points.");
return SCRIPT_CONTINUE;
}
Vector goodSpawns = new Vector();
@@ -113,7 +116,7 @@ public class spawner_patrol extends script.base_script
if (goodSpawns.size() == 0)
{
LOG("spawning", "All entries in table " + strFileName + " are bad!!!");
setName(self, "No valid spawners!");
setName(self, "Mangled spawner: No valid spawners!");
return SCRIPT_CONTINUE;
}
}
@@ -128,36 +131,43 @@ public class spawner_patrol extends script.base_script
return SCRIPT_CONTINUE;
}
int intGoodLocationSpawner = getIntObjVar(self, "intGoodLocationSpawner");
float fltRadius = getFloatObjVar(self, "fltRadius");
String strSpawnType = getStringObjVar(self, "strSpawns");
float fltSize = 8.0f;
String strSpawn = strSpawnType;
String strFileName = "datatables/spawning/ground_spawning/types/" + strSpawnType + ".iff";
float fltSize;
String strSpawn = getStringObjVar(self, "strSpawns");
if (strSpawn == null || strSpawn.length() < 1)
{
setName(self, "Mangled spawner: strSpawn is null or empty.");
return SCRIPT_CONTINUE;
}
String strFileName = "datatables/spawning/ground_spawning/types/" + strSpawn + ".iff";
if (dataTableOpen(strFileName))
{
String[] strSpawns = dataTableGetStringColumnNoDefaults(strFileName, "strItem");
float[] fltSizes = dataTableGetFloatColumn(strFileName, "fltSize");
if ((strSpawns == null) || (strSpawns.length == 0))
{
setName(self, "Mangled spawner. strFileName is " + strFileName + " I couldn't find any spawns in that file.");
setName(self, "Mangled spawner: strFileName is " + strFileName + " I couldn't find any spawns in that file.");
return SCRIPT_CONTINUE;
}
else if (fltSizes.length == 0)
{
setName(self, "Mangled spawner: BAD NUMBER OF SIZES !@!@@ IN FILE " + strFileName);
return SCRIPT_CONTINUE;
}
else if (fltSizes.length != strSpawns.length)
{
setName(self, "Mangled spawner: Missing either spawns or sizes in " + strFileName);
return SCRIPT_CONTINUE;
}
int intRoll = rand(0, strSpawns.length - 1);
if (fltSizes.length == 0)
{
setName(self, "BAD NUMBER OF SIZES !@!@@ IN FILE " + strFileName);
}
if (fltSizes.length != strSpawns.length)
{
setName(self, "Missing either spawns or sizes in " + strFileName);
}
fltSize = fltSizes[intRoll];
strSpawn = strSpawns[intRoll];
}
if (strSpawn == null || strSpawn.length() < 1)
else
{
setName(self, "Mangled spawner. strSpawn is " + strSpawn + ".");
setName(self, "Mangled spawner: strSpawn is " + strSpawn + " and datatable could not be opened.");
return SCRIPT_CONTINUE;
}
float fltRadius = getFloatObjVar(self, "fltRadius");
location locTest = spawning.getRandomLocationInCircle(getLocation(self), fltRadius);
fltSize = getClosestSize(fltSize);
if (intGoodLocationSpawner > 0)
@@ -46,6 +46,22 @@ public class masterspawner extends script.base_script
{-4173.8f, 3.0f, -2407.9f},
{-4160.9f, 3.0f, -2407.9f}
};
private float[][] smallSquadThreePoints = {
{-4287.9f, 3.0f, -2407.9f},
{-4277.5f, 3.0f, -2407.9f},
{-4272.7f, 3.0f, -2395.9f},
{-4232.2f, 3.0f, -2395.9f},
{-4204.6f, 3.0f, -2387.4f},
{-4204.6f, 3.0f, -2349.8f}
};
private float[][] smallSquadFourPoints = {
{-4160.9f, 3.0f, -2407.9f},
{-4173.8f, 3.0f, -2407.9f},
{-4176.7f, 3.0f, -2396.0f},
{-4216.5f, 3.0f, -2396.0f},
{-4253.7f, 3.0f, -2379.9f},
{-4253.7f, 3.0f, -2349.8f}
};
private float[][] largeSquadOnePoints = {
{-4272.7f, 3.0f, -2395.1f},
{-4272.7f, 3.0f, -2407.1f},
@@ -76,7 +92,6 @@ public class masterspawner extends script.base_script
{-4272.7f, 3.0f, -2407.1f},
{-4272.7f, 3.0f, -2395.1f}
};
private location[] patrolPoints;
// These are the different types of droids that can spawn.
// The secondary value is the speed at which the droid travels
@@ -89,32 +104,6 @@ public class masterspawner extends script.base_script
{"r4","1.1"},
{"r5","1.2"}
};
// These are the different types of NPC's that can be spawned
// into a patrol. The second value is a lower bound for the
// random number, the third value is an upper bound for the
// random number.
private String[][] patrolNpcTypes = {
{"stormtrooper", "0", "50"},
{"stormtrooper_squad_leader", "51", "75"},
{"stormtrooper_captain", "76", "85"},
{"stormtrooper_major", "86", "90"},
{"stormtrooper_medic", "91", "100"}
};
private String[][] officerPatrolTypes = {
{"stormtrooper", "0", "25"},
{"imperial_private", "26", "50"},
{"imperial_sergeant", "51", "60"},
{"imperial_staff_sergeant", "61", "68"},
{"imperial_staff_corporal", "69", "75"},
{"imperial_first_lieutenant", "76", "81"},
{"imperial_second_lieutenant", "82", "86"},
{"imperial_major", "87", "90"},
{"imperial_colonel", "91", "93"},
{"imperial_brigadier_general", "94", "96"},
{"imperial_major_general", "97", "98"},
{"imperial_lieutenant_general", "99", "100"},
{"imperial_general", "101", "101"}
};
public masterspawner()
{
@@ -134,19 +123,17 @@ public class masterspawner extends script.base_script
{
spawnCommoners();
spawnRecruiters();
spawnGuardPatrol(self, "officers", new location(-4272.7f, 3.0f, -2397.1f), 3, getPatrolPoints(officerPatrolPoints), "officer", false);
spawnGuardPatrol(self, "squadOne", new location(-4272.7f, 3.0f, -2397.1f), 3, getPatrolPoints(smallSquadOnePoints), "trooper", true);
spawnGuardPatrol(self, "squadTwo", new location(-4272.7f, 3.0f, -2397.1f), 3, getPatrolPoints(smallSquadTwoPoints), "trooper", true);
spawnGuardPatrol(self, "squadThree", new location(-4277.5f, 3.0f, -2407.9f), 3, getPatrolPoints(smallSquadOnePoints), "trooper", true);
spawnGuardPatrol(self, "squadFour", new location(-4176.7f, 3.0f, -2405.1f), 3, getPatrolPoints(smallSquadTwoPoints), "trooper", true);
spawnGuardPatrol(self, "largeSquadOne", new location(-4272.7f, 3.0f, -2395.1f), 5, getPatrolPoints(largeSquadOnePoints), "trooper", false);
spawnGuardPatrol(self, "largeSquadTwo", new location(-4176.7f, 3.0f, -2395.1f), 5, getPatrolPoints(largeSquadTwoPoints), "trooper", false);
spawnGuardPatrol(self, "officers", new location(-4272.7f, 3.0f, -2397.1f), 3, getPatrolPoints(officerPatrolPoints), "plain", false);
spawnGuardPatrol(self, "squadOne", new location(-4272.7f, 3.0f, -2397.1f), 3, getPatrolPoints(smallSquadOnePoints), "armored", true);
spawnGuardPatrol(self, "squadTwo", new location(-4272.7f, 3.0f, -2397.1f), 3, getPatrolPoints(smallSquadTwoPoints), "armored", true);
spawnGuardPatrol(self, "squadThree", new location(-4277.5f, 3.0f, -2407.9f), 3, getPatrolPoints(smallSquadThreePoints), "armored", true);
spawnGuardPatrol(self, "squadFour", new location(-4176.7f, 3.0f, -2405.1f), 3, getPatrolPoints(smallSquadFourPoints), "armored", true);
spawnGuardPatrol(self, "largeSquadOne", new location(-4272.7f, 3.0f, -2395.1f), 5, getPatrolPoints(largeSquadOnePoints), "armored", false);
spawnGuardPatrol(self, "largeSquadTwo", new location(-4176.7f, 3.0f, -2395.1f), 5, getPatrolPoints(largeSquadTwoPoints), "armored", false);
spawnSG567();
spawnLX466();
//spawnSocialGroups(self);
patrolPoints = getPatrolPoints(droidPatrolCoords);
messageTo(self, "spawnDroidPatrol", null, 10, false);
}
private void spawnSG567() throws InterruptedException{
@@ -200,6 +187,7 @@ public class masterspawner extends script.base_script
// Sets the number of droids that will spawn on the outpost grounds.
int maxDroids = 4;
int currentDroids = getIntObjVar(self, "current.droids");
location[] points = getPatrolPoints(droidPatrolCoords);
if(currentDroids < maxDroids){
int spawnPoint = 1;
@@ -207,12 +195,12 @@ public class masterspawner extends script.base_script
String [] droid = droidTypes[rand(0, droidTypes.length - 1)];
// spawn the droid and assign the obj_id to the droidSpawn var.
obj_id droidSpawn = spawn(droid[0], patrolPoints[spawnPoint].x, patrolPoints[spawnPoint].y, patrolPoints[spawnPoint].z, 0, null, "", true);
obj_id droidSpawn = spawn(droid[0], points[spawnPoint].x, points[spawnPoint].y, points[spawnPoint].z, 0, null, "", true);
// handle AI features - make the droid movable, set their speed and set their path.
setCreatureStatic(droidSpawn, false);
setMovementPercent(droidSpawn, Float.parseFloat(droid[1]));
ai_lib.setPatrolPath(droidSpawn, patrolPoints);
ai_lib.setPatrolPath(droidSpawn, points);
setObjVar(self, "current.droids", currentDroids + 1);
}
@@ -222,66 +210,23 @@ public class masterspawner extends script.base_script
private void spawnGuardPatrol(obj_id self, String patrolName, location spawnLocation, int totalMembers, location [] patrolPoints, String npcType, boolean flip) throws InterruptedException{
String pName = "patrols." + patrolName;
setObjVar(self, pName + ".startLocation", spawnLocation);
setObjVar(self, pName + ".totalMembers", totalMembers);
setObjVar(self, pName + ".points", patrolPoints);
setObjVar(self, pName + ".flipPaths", flip);
setObjVar(self, pName + ".types", npcType);
spawnGuardPatrolMember(self, pName);
//spawnGuardPatrolMember(self, pName);
obj_id patrolSpawnEgg = createObject("object/tangible/poi/spawnegg/patrol_spawnegg.iff", spawnLocation);
dictionary params = new dictionary();
params.put("name", pName);
params.put("size", totalMembers);
params.put("type", npcType);
messageTo(self, "spawnMoreGuards", params, 10, false);
setObjVar(patrolSpawnEgg, "name", patrolName);
setObjVar(patrolSpawnEgg, "size", totalMembers);
setObjVar(patrolSpawnEgg, "patrolPoints", patrolPoints);
setObjVar(patrolSpawnEgg, "flipPaths", flip);
setObjVar(patrolSpawnEgg, "faction", "imperial");
setObjVar(patrolSpawnEgg, "invulnerable", false);
setObjVar(patrolSpawnEgg, "respawnTime", 5.0f);
setObjVar(patrolSpawnEgg, "patrolLevel", 66);
setObjVar(patrolSpawnEgg, "squadClass", npcType);
messageTo(patrolSpawnEgg, "beginSpawn", null, 10, false);
}
private void spawnGuardPatrolMember(obj_id self, String patrolName) throws InterruptedException{
location start = getLocationObjVar(self, patrolName + ".startLocation");
obj_id guardSpawn = spawn(npcToSpawn(getStringObjVar(self, patrolName + ".types")), start.x, start.y, start.z, 0f, null, null, false);
if(getBooleanObjVar(self, patrolName + ".flipPaths"))
ai_lib.setPatrolFlipPath(guardSpawn, getLocationArrayObjVar(self, patrolName + ".points"));
else
ai_lib.setPatrolPath(guardSpawn, getLocationArrayObjVar(self, patrolName + ".points"));
int currentPop = getIntObjVar(self, patrolName + ".current.guards") + 1;
if (currentPop == 1)
{
setObjVar(self, patrolName + ".leader", guardSpawn);
}
else
{
obj_id leader = getObjIdObjVar(self, patrolName + ".leader");
ai_lib.followInFormation(guardSpawn, leader, ai_lib.FORMATION_COLUMN, currentPop - 1);
setMovementPercent(guardSpawn, 1.2f);
}
setCreatureStatic(guardSpawn, false);
setObjVar(self, patrolName + ".current.guards", currentPop);
}
public int spawnMoreGuards(obj_id self, dictionary params) throws InterruptedException{
String patrolName = params.getString("name");
int maxGuardsToSpawn = params.getInt("size");
String currentPopulation = patrolName + ".current.guards";
if (!hasObjVar(self, currentPopulation))
{
setObjVar(self, currentPopulation, 0);
spawnGuardPatrolMember(self, patrolName);
}
else
{
if (getIntObjVar(self, currentPopulation) < maxGuardsToSpawn)
{
spawnGuardPatrolMember(self, patrolName);
}
}
messageTo(self, "spawnMoreGuards", params, 10, false);
return SCRIPT_CONTINUE;
}
private location[] getPatrolPoints(float[][] patrolCoords){
public location[] getPatrolPoints(float[][] patrolCoords){
location[] patrolPoints = new location[patrolCoords.length];
// take the patrol coordinates and turn them into location objects such that we can
// pass the location objects to the AI and have it traverse those locations.
@@ -291,22 +236,6 @@ public class masterspawner extends script.base_script
return patrolPoints;
}
public String npcToSpawn(String npcType){
// get NPC type:
int roll = rand(0,100);
String [][] npcTypes = patrolNpcTypes;
if(npcType != null && npcType.equals("officer")){
npcTypes = officerPatrolTypes;
}
for(String[] npcConfig : npcTypes){
if(roll >= Integer.parseInt(npcConfig[1]) && roll <= Integer.parseInt(npcConfig[2]))
return npcConfig[0];
}
return patrolNpcTypes[0][0];
}
public obj_id spawn(String obj, float x, float y, float z, float yaw, obj_id cell, String mood, boolean invuln) throws InterruptedException{
obj_id spawnedObject;
@@ -316,6 +245,9 @@ public class masterspawner extends script.base_script
else{
spawnedObject = create.object(obj, new location(x, y, z, "dantooine", cell));
}
setObjVar(spawnedObject, "spawner", getSelf());
attachScript(spawnedObject, "theme_park.patrol_member");
setCreatureStatic(spawnedObject, true);
setInvulnerable(spawnedObject, invuln);
setLevel(spawnedObject, rand(65,69));
@@ -0,0 +1,33 @@
package script.theme_park;
import script.dictionary;
import script.library.ai_lib;
import script.location;
import script.obj_id;
public class patrol_member extends script.base_script
{
public patrol_member(){}
public void startPatrol(obj_id self, dictionary params) throws InterruptedException{
if(!isValidId(self) || !exists(self) || !getBooleanObjVar(self, "isLeader")) return;
location[] patrolPts = params.getLocationArray("patrolPoints");
if(params.getBoolean("flipPaths")){
ai_lib.setPatrolFlipPath(self, patrolPts);
}
else {
ai_lib.setPatrolPath(self, patrolPts);
}
}
public int OnDestroy(obj_id self) throws InterruptedException
{
obj_id spawner = getObjIdObjVar(self, "spawner");
dictionary dict = new dictionary();
dict.put("isLeader", getBooleanObjVar(self, "isLeader"));
dict.put("self", self);
messageTo(spawner, "patrolMemberDied", dict, 20, true);
return SCRIPT_CONTINUE;
}
}
@@ -0,0 +1,225 @@
package script.theme_park.patrols;
import script.dictionary;
import script.library.ai_lib;
import script.library.create;
import script.location;
import script.obj_id;
public class patrol_controller extends script.base_script {
private obj_id[] formationSlots;
public String faction = "neutral";
public String strFileName = "datatables/spawning/patrol_spawner.iff";
// type is the type of the squad.
// "plain" type indicates unarmored npcs () of the given faction (irrelevant for neutral)
// "armored" type indicates armored npcs (troopers) only of the given faction.
// "mixed" type indicates a mixture of officers and troopers
private String squadClass = "armored";
private int patrolLevel = 25;
// patrolLevelTolerance is the span above the patrol level that members can be.
// for example, if the patrolLevel is set to 66 and the patrolLevelTolerance is 2, patrol
// members can be 2 levels above level 66. Therefore, patrol members
// will be in the range of 66 and 68.
private int patrolLevelTolerance = 3;
public patrol_controller(){}
public int OnAttach(obj_id self) throws InterruptedException{
setObjVar(self, "currentSize", 0);
return SCRIPT_CONTINUE;
}
public int OnInitialize(obj_id self) throws InterruptedException {
setObjVar(self, "currentSize", 0);
return SCRIPT_CONTINUE;
}
public int beginSpawn(obj_id self, dictionary params) throws InterruptedException{
messageTo(self, "spawnGuardPatrol", null, 2, false);
return SCRIPT_CONTINUE;
}
public int spawnGuardPatrol(obj_id self, dictionary params) throws InterruptedException{
String patrolName = getStringObjVar(self, "name");
int maxSize = getIntObjVar(self, "size");
int currentSize = getIntObjVar(self, "currentSize");
location spawnStart = getLocationArrayObjVar(self, "patrolPoints")[0];
if(hasObjVar(self, "patrolLevel")) patrolLevel = getIntObjVar(self, "patrolLevel");
if(hasObjVar(self, "patrolLevelTolerance")) patrolLevelTolerance = getIntObjVar(self, "patrolLevelTolerance");
if(hasObjVar(self, "faction")) faction = getStringObjVar(self, "faction");
formationSlots = new obj_id[getIntObjVar(self, "size")];
setObjVar(self, "formationSlots", formationSlots);
float respawnTime = getFloatObjVar(self, "respawnTime");
squadClass = getStringObjVar(self, "squadClass");
setName(self, patrolName);
formationSlots = getObjIdArrayObjVar(getSelf(), "formationSlots");
for (int i = currentSize; i < maxSize; i++) {
spawnPatrolMember(self, getOpenFormationPosition(maxSize), i, spawnStart);
}
setObjVar(self, "formationSlots", formationSlots);
messageTo(self, "spawnGuardPatrol", null, respawnTime, false);
return SCRIPT_CONTINUE;
}
private int getOpenFormationPosition(int maxSize){
for(int i = 0; i < formationSlots.length; i++){
if(formationSlots[i] == null || formationSlots[i] == obj_id.NULL_ID){
return i;
}
}
return maxSize - 1;
}
private void spawnPatrolMember(obj_id self, int position, int currentSize, location spawnStart) throws InterruptedException{
obj_id patrolMember;
String memberTemplate = npcToSpawn(self);
if(memberTemplate == null){
setName(self, "BROKEN SPAWNER: Can't get squad member template!");
return;
}
if(currentSize == 0 || needsLeader()){
String npc = getLeaderTemplate(self);
if(npc == null){
setName(self, "BROKEN SPAWNER: Can't get squad leader template!");
return;
}
patrolMember = spawn(npc, spawnStart.x, spawnStart.y, spawnStart.z, 0f, null, null);
setObjVar(patrolMember, "isLeader", true);
dictionary params = new dictionary();
params.put("patrolPoints", getLocationArrayObjVar(self, "patrolPoints"));
params.put("flipPaths", getBooleanObjVar(self, "flipPaths"));
messageTo(patrolMember, "startPatrol", params, 60, false);
}
else{
// spawn member
patrolMember = spawn(memberTemplate, spawnStart.x, spawnStart.y, spawnStart.z, 0f, null, null);
ai_lib.followInFormation(patrolMember, formationSlots[0], ai_lib.FORMATION_COLUMN, position);
setMovementPercent(patrolMember, 1.2f);
setObjVar(patrolMember, "isLeader", false);
}
formationSlots[position] = patrolMember;
setLevel(patrolMember, rand(patrolLevel, patrolLevel + patrolLevelTolerance));
setObjVar(self, "currentSize", currentSize + 1);
}
private boolean needsLeader() throws InterruptedException {
obj_id leader = formationSlots[0];
return leader == null || leader == obj_id.NULL_ID || isDead(leader) || isIncapacitated(leader) || !isIdValid(leader) || !exists(leader);
}
public void patrolMemberDied(obj_id self, dictionary params) throws InterruptedException{
// drop the size of the patrol by one.
int currentSize = getIntObjVar(self, "currentSize");
if(currentSize <= 0) currentSize = 1;
setObjVar(self, "currentSize", currentSize - 1);
obj_id deadMember = params.getObjId("self");
formationSlots = getObjIdArrayObjVar(self, "formationSlots");
// check if this patrol member was a leader or not. Spawn new leader if so.
if(params.getBoolean("isLeader")){
setObjVar(self, "leader", obj_id.NULL_ID);
spawnPatrolMember(self, 0, 0, getLocationArrayObjVar(self, "patrolPoints")[0]);
tellSquadAboutNewLeader();
}
else{
for(int i=0; i < formationSlots.length; i++){
if(formationSlots[i] == deadMember){
formationSlots[i] = obj_id.NULL_ID;
break;
}
}
setObjVar(self, "formationSlots", formationSlots);
}
}
private void tellSquadAboutNewLeader() throws InterruptedException{
for(int i = 1; i < formationSlots.length; i++){
ai_lib.followInFormation(formationSlots[i], formationSlots[0], ai_lib.FORMATION_COLUMN, i);
setMovementPercent(formationSlots[i], 1.2f);
}
}
private String getLeaderTemplate(obj_id self){
if(!dataTableOpen(strFileName)){
setName(self, "BROKEN SPAWNER: Can't open datatable to retrieve Squad Leader Template!");
return null;
}
int rowCount = dataTableGetNumRows(strFileName);
squadClass = getStringObjVar(self, "squadClass");
String tempSquadClass = squadClass;
dictionary row;
for(int i=0; i < rowCount; i++){
row = dataTableGetRow(strFileName, i);
if(row.getInt("leader") != 1 || !row.getString("faction").equals(faction)){
continue;
}
if(squadClass.equals("mixed") && rand(1,2) == 2) tempSquadClass = "plain";
if(row.getString("faction").equals(faction) && row.getInt("leader") == 1 && row.getString("squadClass").equals(tempSquadClass)){
return row.getString("template");
}
}
return null;
}
public String npcToSpawn(obj_id self){
// get NPC type:
int roll = rand(1,100);
if(!dataTableOpen(strFileName)){
setName(self, "BROKEN SPAWNER: Can't open datatable!");
return null;
}
int rowCount = dataTableGetNumRows(strFileName);
if (rowCount <= 0)
{
setName(self, "BROKEN SPAWNER: Can't get datatable rows!");
return null;
}
dictionary row;
squadClass = getStringObjVar(self, "squadClass");
String tempSquadClass = squadClass;
for(int i=0; i < rowCount; i++){
row = dataTableGetRow(strFileName, i);
if(!row.getString("faction").equals(faction)){
continue;
}
if(squadClass.equals("mixed") && rand(1,2) == 2) tempSquadClass = "plain";
if(row.getString("faction").equals(faction) && row.getString("squadClass").equals(tempSquadClass) && roll >= row.getInt("minSpawnChance") && roll <= row.getInt("maxSpawnChance")){
return row.getString("template");
}
}
return null;
}
public obj_id spawn(String obj, float x, float y, float z, float yaw, obj_id cell, String mood) throws InterruptedException{
obj_id spawnedObject;
String area = getLocation(getSelf()).area;
if(obj.contains(".iff")){
spawnedObject = createObject(obj, new location(x, y, z, area, cell));
}
else{
spawnedObject = create.object(obj, new location(x, y, z, area, cell));
}
obj_id self = getSelf();
setObjVar(spawnedObject, "spawner", self);
attachScript(spawnedObject, "theme_park.patrol_member");
setCreatureStatic(spawnedObject, false);
setInvulnerable(spawnedObject, getBooleanObjVar(self, "invulnerable"));
setLevel(spawnedObject, rand(65,69));
if(yaw > 0){
setYaw(spawnedObject, yaw);
}
ai_lib.setDefaultCalmMood(spawnedObject, mood);
return spawnedObject;
}
}