mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-01-15 23:04:31 -05:00
Fixes for NPC Spawning in/on Collidables (ref #301)
This commit is contained in:
@@ -713,69 +713,68 @@ public class groundquests extends script.base_script
|
||||
}
|
||||
public static location getRandom2DLocationAroundLocation(obj_id player, float relativeOffsetX, float relativeOffsetZ, float minimumDistance, float maximumDistance) throws InterruptedException
|
||||
{
|
||||
boolean onAFloor = isOnAFloor(player);
|
||||
location playerLocation = getLocation(player);
|
||||
boolean inACell = (playerLocation.cell != null) && (playerLocation.cell != obj_id.NULL_ID);
|
||||
final boolean onAFloor = isOnAFloor(player);
|
||||
final location playerLocation = getLocation(player);
|
||||
final boolean inACell = (playerLocation.cell != null) && (playerLocation.cell != obj_id.NULL_ID);
|
||||
location newLocation = new location(playerLocation);
|
||||
newLocation.x += relativeOffsetX;
|
||||
newLocation.z += relativeOffsetZ;
|
||||
newLocation = utils.getRandomLocationInRing(newLocation, minimumDistance, maximumDistance);
|
||||
if (!isValidQuestSpawnPoint(player, newLocation, onAFloor, inACell))
|
||||
{
|
||||
float xDelta = (playerLocation.x - newLocation.x) * 2;
|
||||
float zDelta = (playerLocation.z - newLocation.z) * 2;
|
||||
if (newLocation.x < playerLocation.x)
|
||||
{
|
||||
newLocation.x += xDelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
newLocation.x -= xDelta;
|
||||
}
|
||||
if (!isValidQuestSpawnPoint(player, newLocation, onAFloor, inACell))
|
||||
{
|
||||
if (newLocation.z < playerLocation.z)
|
||||
{
|
||||
newLocation.z += zDelta;
|
||||
// try to find a suitable location around the player relative to the requested params
|
||||
int count = 0;
|
||||
float xDelta = 0f;
|
||||
float zDelta = 0f;
|
||||
while(!isValidQuestSpawnPoint(player, newLocation, onAFloor, inACell) && count < 100) {
|
||||
if (count % 2 == 0) {
|
||||
xDelta = (playerLocation.x - newLocation.x) * 2f;
|
||||
if (newLocation.x < playerLocation.x) {
|
||||
newLocation.x += xDelta;
|
||||
} else {
|
||||
newLocation.x -= xDelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
zDelta = (playerLocation.z - newLocation.z) * 2f;
|
||||
if (newLocation.z < playerLocation.z) {
|
||||
newLocation.z += zDelta;
|
||||
} else {
|
||||
newLocation.z -= zDelta;
|
||||
}
|
||||
if (!isValidQuestSpawnPoint(player, newLocation, onAFloor, inACell))
|
||||
{
|
||||
if (newLocation.x < playerLocation.x)
|
||||
{
|
||||
newLocation.x += xDelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
newLocation.x -= xDelta;
|
||||
}
|
||||
if (!isValidQuestSpawnPoint(player, newLocation, onAFloor, inACell))
|
||||
{
|
||||
newLocation = (location)playerLocation.clone();
|
||||
}
|
||||
}
|
||||
if(getDistance(playerLocation, newLocation) > maximumDistance) {
|
||||
if(rand(0, 1) == 0) {
|
||||
newLocation.x = playerLocation.x + rand(minimumDistance, maximumDistance);
|
||||
} else {
|
||||
newLocation.z = playerLocation.z + rand(minimumDistance, maximumDistance);
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
if (onAFloor)
|
||||
{
|
||||
if(count >= 100) {
|
||||
// if we can't find a suitable location, return really close around the player, but still random for effect
|
||||
WARNING("groundquests.getRandom2DLocationAroundLocation() was unable to find a suitable location for "+player+" at "+playerLocation.area+" "+playerLocation.x+" "+playerLocation.z);
|
||||
newLocation = (location)playerLocation.clone();
|
||||
newLocation.x += rand(-2f, 2f);
|
||||
newLocation.z += rand(-2f, 2f);
|
||||
}
|
||||
if (onAFloor) {
|
||||
newLocation.y = getFloorHeightAtRelativePointOnSameFloorAsObject(player, newLocation.x - playerLocation.x, newLocation.z - playerLocation.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
newLocation.y = getHeightAtLocation(newLocation.x, newLocation.z);
|
||||
}
|
||||
return newLocation;
|
||||
}
|
||||
public static boolean isValidQuestSpawnPoint(obj_id player, location newLocation, boolean onAFloor, boolean inACell) throws InterruptedException
|
||||
{
|
||||
boolean validPoint = true;
|
||||
location playerLocation = getLocation(player);
|
||||
if (validPoint)
|
||||
{
|
||||
validPoint = !getCollidesWithObject(newLocation, 1.0f);
|
||||
final location playerLocation = getLocation(player);
|
||||
boolean validPoint = !getCollidesWithObject(newLocation, 2f); // FYI this method doesn't appear to do anything
|
||||
// prevent spawns inside building walls when location should be outside in world
|
||||
if(validPoint && !inACell) {
|
||||
obj_id[] objects = getNonCreaturesInRange(newLocation, 0.5f);
|
||||
for (obj_id o : objects) {
|
||||
if(getTemplateName(o).contains("building")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (validPoint && onAFloor)
|
||||
{
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package script.quest.task.ground;
|
||||
|
||||
import script.dictionary;
|
||||
import script.library.ai_lib;
|
||||
import script.library.create;
|
||||
import script.library.groundquests;
|
||||
import script.library.utils;
|
||||
import script.library.*;
|
||||
import script.location;
|
||||
import script.obj_id;
|
||||
|
||||
@@ -60,9 +57,11 @@ public class encounter extends script.quest.task.ground.base_task
|
||||
{
|
||||
location l = null;
|
||||
location locTest = getLocation(self);
|
||||
boolean inCell = false;
|
||||
if (!isIdValid(locTest.cell))
|
||||
{
|
||||
l = groundquests.getRandom2DLocationAroundLocation(self, relativeOffsetX, relativeOffsetZ, minRadius, maxRadius);
|
||||
inCell = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -72,6 +71,19 @@ public class encounter extends script.quest.task.ground.base_task
|
||||
}
|
||||
obj_id creature = create.createCreature(creatureType, l, true);
|
||||
if(isValidId(creature)) {
|
||||
if(!inCell)
|
||||
{
|
||||
location creatureLoc = getLocation(creature);
|
||||
int respawnCount = 0;
|
||||
while(respawnCount < 5 && creatureLoc.y != getHeightAtLocation(creatureLoc.x, creatureLoc.z)) {
|
||||
// creature is standing on something it shouldn't be
|
||||
destroyObject(creature);
|
||||
l = groundquests.getRandom2DLocationAroundLocation(self, relativeOffsetX, relativeOffsetZ, minRadius, maxRadius);
|
||||
creature = create.createCreature(creatureType, l, true);
|
||||
creatureLoc = getLocation(creature);
|
||||
respawnCount++;
|
||||
}
|
||||
}
|
||||
setObjVar(creature, objvarOnCreatureOwner, self);
|
||||
setObjVar(creature, objvarOnCreatureQuestCrc, questCrc);
|
||||
setObjVar(creature, objvarOnCreatureTaskId, taskId);
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package script.systems.npc_lair;
|
||||
|
||||
import script.dictionary;
|
||||
import script.*;
|
||||
import script.library.*;
|
||||
import script.location;
|
||||
import script.obj_id;
|
||||
import script.string_id;
|
||||
|
||||
public class npc_lair extends script.theme_park.poi.base
|
||||
{
|
||||
@@ -51,6 +48,22 @@ public class npc_lair extends script.theme_park.poi.base
|
||||
{
|
||||
removeObjVar(self, "npc_lair.target");
|
||||
}
|
||||
// fix for lairs that accidentally spawn inside quarantine zone walls because
|
||||
// the walls don't match the shape of the region and this is easier to fix than
|
||||
// relocating a ton of walls
|
||||
if(locTest.area.equalsIgnoreCase("dathomir")) {
|
||||
region[] regions = getRegionsAtPoint(locTest);
|
||||
for(region r : regions) {
|
||||
if(r.getName().equalsIgnoreCase("@dathomir_region_names:mountain_2")) {
|
||||
obj_id[] objects = getObjectsInRange(self, 15f);
|
||||
for (obj_id o : objects) {
|
||||
if(getTemplateName(o).contains("military_wall")) {
|
||||
destroyObject(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
initializePoi(self);
|
||||
return SCRIPT_CONTINUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user