mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-08-02 02:15:48 -04:00
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:
@@ -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
|
||||
+12
@@ -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)
|
||||
|
||||
+43
-111
@@ -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;
|
||||
}
|
||||
}
|
||||
+225
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user