Jump to content

Home

Problems with GetNearestObjectToLocation


Achilles

Recommended Posts

I'm trying to put a lightsaber inside the footlocker in the secure cargo hold in 106PER.

 

First, I tried using Darth333's sample script posted here . Unfortunately, it doesn't work in this scenario. In fact, any variation that I try that includes conditionals won't work. So far, I've tried using just (GetIsObjectValid(oContainer)) and just ((GetTag(oContainer)) == "millowfootlker") (oContainer is declared and valid) but still no luck.

 

So that being the case, I thought maybe using the ugliest hack available might work. I resorted to using this:

 

// a_transformt3m4.nss
void sub1();

void sub1() {
SwitchPlayerCharacter(8);
SetGlobalFadeIn(0.0, 2.0, 0.0, 0.0, 0.0);
}

void main() {
object oEntering = GetEnteringObject();
if ((GetGlobalBoolean("PER_TURNINTO_T3M4") && GetIsPC(oEntering))) {
	SetGlobalBoolean("PER_TURNINTO_T3M4", 0);
	DelayCommand(1.0, sub1());
}

       //:: Here's where my code starts.
float x = 25.1;	
float y = 80.9;
float z = 9.3;

vector vContainer = Vector(x,y,z);
location lContainer = Location(vContainer, 0.0);
int nNth = 1;

object oContainer = GetNearestObjectToLocation(OBJECT_TYPE_PLACEABLE, lContainer, nNth);
object olsabre = CreateItemOnObject("g_w_lghtsbr13", oContainer);
       //:: Here's where my code ends.
}

The good news is that it works (it spawns the lightsaber). The bad news is that it creates 2 of them in the cylinder located at 13.3, 82.8, 9.3 rather than 1 in the footlocker at the vector shown above.

 

I know that is at least partially because I'm not using conditionals, however as I previously stated, I can't get the script to work with the conditionals used.

 

Could someone please help me understand what I'm missing? I've spent hours on this.

 

Thanks in advance.

Link to comment
Share on other sites

I sometimes put a user define on heartbeat script on some of my npc's:

 

void main () 
{
object oLeader = GetPartyMemberByIndex(0);
vector vPosition=Vector(25.1, 80.9, 9.3);
location lparts=Location(vPosition,0.0);
object oContainer = GetNearestObjectToLocation(64, lparts, 1);
location lcontainer = GetLocation(oContainer);
float float1 =GetDistanceBetween2D(oLeader, oContainer);
if (((GetIsObjectValid(oContainer))) && ((GetStringLowerCase(GetStringLeft(GetTag(oContainer)  , 3)) == "mil")) && (float1 <= 2.0)) {
CreateItemOnObject( "g_w_lghtsbr13", oContainer, 1 );      

}
}

 

 

Else this should work:

 

// Prototypes
void sub1();

void sub1() {
SwitchPlayerCharacter(8);
SetGlobalFadeIn(0.0, 2.0, 0.0, 0.0, 0.0);
}

void main() {
object oEntering = GetEnteringObject();
if ((GetGlobalBoolean("PER_TURNINTO_T3M4") && GetIsPC(oEntering))){
	vector vPosition=Vector(25.1, 80.9, 9.3);
               location lparts=Location(vPosition,0.0);
               object oContainer = GetNearestObjectToLocation(64, lparts, 1);		
	CreateItemOnObject( "g_w_lghtsbr13", oContainer, 1 ); 
	SetGlobalBoolean("PER_TURNINTO_T3M4", 0);		
	DelayCommand(1.0, sub1());

}
}

Link to comment
Share on other sites

Else this should work:

 

// Prototypes
void sub1();

void sub1() {
SwitchPlayerCharacter(8);
SetGlobalFadeIn(0.0, 2.0, 0.0, 0.0, 0.0);
}

void main() {
object oEntering = GetEnteringObject();
if ((GetGlobalBoolean("PER_TURNINTO_T3M4") && GetIsPC(oEntering))){
	vector vPosition=Vector(25.1, 80.9, 9.3);
               location lparts=Location(vPosition,0.0);
               object oContainer = GetNearestObjectToLocation(64, lparts, 1);		
	CreateItemOnObject( "g_w_lghtsbr13", oContainer, 1 ); 
	SetGlobalBoolean("PER_TURNINTO_T3M4", 0);		
	DelayCommand(1.0, sub1());

}
}

Still spawning in Cylinder1 instead of millowfootlker :(

The think that doesn't make any sense is that I used the whereami armband right next to the placeable that I wanted, then used the coordinates to find the exact coordinates in the .git file. The vector used by the script is the same one used by the game. I can't understand why it's spawning the item in the next closest location.

 

Thanks for your help though :)

Link to comment
Share on other sites

Well, oddly enough your starting vector is too close to the container you are looking for. The game seems to consider all other containers to be closer. Moving that vector a bit "further away" from the desired container will place the lightsabre in the correct one.

 

Also, this is an onEnter script. It will execute and spawn a new lightsabre every time you enter the module. That also includes just loading a game. You should add a condition that the script should only place the item once, for example with a local variable.

 

// a_transformt3m4.nss
void sub1();

void sub1() {
SwitchPlayerCharacter(8);
SetGlobalFadeIn(0.0, 2.0, 0.0, 0.0, 0.0);
}

void main() {
object oEntering = GetEnteringObject();
if ((GetGlobalBoolean("PER_TURNINTO_T3M4") && GetIsPC(oEntering))) {
	SetGlobalBoolean("PER_TURNINTO_T3M4", 0);
	DelayCommand(1.0, sub1());
}

[color=Red]   
       //:: Here's where my code starts.
float x = 21.0;	
float y = 78.0;
float z = 9.3;
[/color]   
vector vContainer = Vector(x,y,z);
location lContainer = Location(vContainer, 0.0);
int nNth = 1;

object oContainer = GetNearestObjectToLocation(OBJECT_TYPE_PLACEABLE, lContainer, nNth);
[color=Red]   
while(GetIsObjectValid(oContainer)) {
	if (GetTag(oContainer) == "MilLowFootLker") {
		if(!GetLocalBoolean(oContainer, 40)) {
			CreateItemOnObject("g_w_lghtsbr13", oContainer);
			SetLocalBoolean(oContainer, 40, TRUE);
		}
		break;
	}
	oContainer = GetNearestObjectToLocation(OBJECT_TYPE_PLACEABLE, lContainer, ++nNth);
}[/color]   
//object olsabre = CreateItemOnObject("g_w_lghtsbr03", oContainer);
       //:: Here's where my code ends.
}

Link to comment
Share on other sites

Hmm, strange, if you are certain that the coordinates and tag is correct. At a quick glance I can't spot anything that seems to be wrong.

 

Make sure the coordinates don't exactly match that of the container though, since NWScript don't consider an object occupying the exact same space as "near". In case the GetNearestObjectToLoc function isn't reliable (which certainly wouldn't be unique in NWScript), you could try looping through the "nearest" placeables until you find one matching the desired tag, like:

 

// a_transformt3m4.nss

void SwitchToT3() {
   SwitchPlayerCharacter(NPC_T3_M4);
   SetGlobalFadeIn(0.0, 2.0);
}

void main() {
   object oEntering = GetEnteringObject();
   if (GetGlobalBoolean("PER_TURNINTO_T3M4") && GetIsPC(oEntering)) {
       SetGlobalBoolean("PER_TURNINTO_T3M4", FALSE);
       DelayCommand(1.0, SwitchToT3());
   }

   float x = 25.1f;    
   float y = 80.9f;
   float z = 9.3f;
   location lLoc = Location(Vector(x,y,z), 0.0);
   int nNth = 1;

   object oContainer = GetNearestObjectToLocation(OBJECT_TYPE_PLACEABLE, lLoc, nNth);
   while (GetIsObjectValid(oContainer)) {
       if (GetTag(oContainer) == "millowfootlker") {
           CreateItemOnObject("g_w_lghtsbr13", oContainer);
           break;
       }
       oContainer = GetNearestObjectToLocation(OBJECT_TYPE_PLACEABLE, lLoc, ++nNth);
   }
}

 

(As an aside, unless you want a new saber any time you enter the module you may want to set/check for LocalBoolean 57 before spawning the item. This boolean is used by the RandomLoot system to designate that a container has had loot spawned to make sure it only happens once.)

 

 

EDIT: Yes, to the faster Tupac Amaru you listen... :yodac::)

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...