Author Topic: On container searches, loops, vector distance, and named bricks  (Read 3267 times)

The onFire function does work and bottomprint works if I take it out of the loop. I'm trying to make a tool that shows the distance between the player and a named brick.

Code: [Select]
function brickDetector_OFF_Image::onFire(%this, %obj, %slot)
{
%obj.schedule(0,"playThread",2,shiftRight);
%obj.schedule(200,"playThread",1,armReadyRight);
%obj.unMountImage(0);
%obj.mountimage(brickDetector_ON_Image, 0);

%client=%obj.client; //%client refers to the client of the object that triggered this state
%name="_asd";
%radius=32; //32 Torque Units = 64 Studs

initContainerRadiusSearch(%pos, %radius, $TypeMasks::FxBrickObjectType); //Initialize container search
    
while (isObject(%obj = containerSearchNext()))
{
if (%obj.getName() $= %name)
{
commandToClient(%client,'bottomPrint',"<color:ffffff>Detecting: " @ %name @ " | Distance: " @ (vectorDist(%pos, %obj.getPosition)*2) @ " Bricks");
break; //End loop after finding a brick (closest)
}
}
}

Are there any obvious errors? I'm just prodding scripts that Port pastes into Steam chat.
« Last Edit: December 29, 2013, 06:11:16 AM by Demian »

I don't see anything obvious, but you must have the logic for the while loop or the if statement wrong. Try sticking an echo into the loop to figure out which it is.

TorqueScript what the forget are you doing.

I removed the comment after break; and suddenly bottom print is displayed:
Code: [Select]
function brickDetector_OFF_Image::onFire(%this, %obj, %slot)
{
%obj.schedule(0,"playThread",2,shiftRight);
%obj.schedule(200,"playThread",1,armReadyRight);
%obj.unMountImage(0);
%obj.mountimage(brickDetector_ON_Image, 0);

%client=%obj.client; //%client refers to the client of the object that triggered this state
%name="_asd";
%radius=32; //32 Torque Units = 64 Studs

//Initialize container search
initContainerRadiusSearch(%pos, %radius, $TypeMasks::FxBrickObjectType);
   
while (isObject(%obj = containerSearchNext()))
{
if (%obj.getName() $= %name)
{
commandToClient(%client,'bottomPrint',"<color:ffffff>Detecting: " @ %name @ " | Distance: " @ (vectorDist(%pos, %obj.getPosition)*2) @ " Bricks");
break;
}
}

}

Then I remove another comment and the bottom print does not display:
Code: [Select]
function brickDetector_OFF_Image::onFire(%this, %obj, %slot)
{
%obj.schedule(0,"playThread",2,shiftRight);
%obj.schedule(200,"playThread",1,armReadyRight);
%obj.unMountImage(0);
%obj.mountimage(brickDetector_ON_Image, 0);

%client=%obj.client; //%client refers to the client of the object that triggered this state
%name="_asd";
%radius=32; //32 Torque Units = 64 Studs

initContainerRadiusSearch(%pos, %radius, $TypeMasks::FxBrickObjectType);
   
while (isObject(%obj = containerSearchNext()))
{
if (%obj.getName() $= %name)
{
commandToClient(%client,'bottomPrint',"<color:ffffff>Detecting: " @ %name @ " | Distance: " @ (vectorDist(%pos, %obj.getPosition)*2) @ " Bricks");
break;
}
}

}

I removed a god damn comment. Why does that break the damn script.

The distance is still broken. It displays 0 at all times so I have no idea if the looping actually works.

FxDTSBrick::getPosition() is a method, not a variable.

Code: [Select]
Distance: " @ (vectorDist(%pos, %obj.getPosition)*2)

You need to add () to call it.

FxDTSBrick::getPosition() is a method, not a variable.

Code: [Select]
Distance: " @ (vectorDist(%pos, %obj.getPosition)*2)

You need to add () to call it.
Silly me. I should have noticed that. Okay now the bottom print is displayed but the distance does not update.
Code: [Select]
function brickDetector_OFF_Image::onFire(%this, %obj, %slot)
{
%obj.schedule(0,"playThread",2,shiftRight);
%obj.schedule(200,"playThread",1,armReadyRight);
%obj.unMountImage(0);
%obj.mountimage(brickDetector_ON_Image, 0);

%client=%obj.client; //%client refers to the client of the object that triggered this state
%name="_asd";
%radius=32; //32 Torque Units = 64 Studs

initContainerRadiusSearch(%pos, %radius, $TypeMasks::FxBrickObjectType);
   
while (isObject(%obj = containerSearchNext()))
{
if (%obj.getName() $= %name)
{
commandToClient(%client,'bottomPrint',"<color:ffffff>Detecting: " @ %name @ " | Distance: " @ (vectorDist(%pos, %obj.getPosition())*2) @ " Bricks");
break;
}
}
}
I'm fairly certain that it's calculating the distance between me and the center of the spawn point/infinite ground. What variable do I need to use to target the named brick with the specified name?


Warning - while you were reading a new reply has been posted. You may wish to review your post.

Damnit Pah, I was just about to point that out..

%pos isn't defined.
I really should have noticed that. I think this is how I should define it? With the echos in place I can see that the entire while loop is skipped. Any idea what could be wrong?
Code: [Select]
function brickDetector_OFF_Image::onFire(%this, %obj, %slot)
{
%obj.schedule(0,"playThread",2,shiftRight);
%obj.schedule(200,"playThread",1,armReadyRight);
%obj.unMountImage(0);
%obj.mountimage(brickDetector_ON_Image, 0);

%pos=%obj.player;
%client=%obj.client;
%name="_asd";
%radius=32; //32 Torque Units = 64 Studs
echo("1 vars defined");
initContainerRadiusSearch(%pos, %radius, $TypeMasks::FxBrickObjectType);
    echo("2 initialized");
while (isObject(%obj = containerSearchNext()))
{
echo("3 in the loop");
if (%obj.getName() $= %name)
{
echo("4 in the if");
commandToClient(%client,'bottomPrint',"<color:ffffff>Detecting: " @ %name @ " | Distance: " @ (vectorDist(%pos, %obj.getPosition())*2) @ " Bricks");
break;
}
}
echo("5 end");
}
« Last Edit: December 21, 2013, 09:18:53 AM by Demian »

You have a radius search at (insert player ID here) 0 0, for fxBricks with raycasting enabled.

Now your player's object ID is in the thousands at least, and you're near the origin, so there likely aren't any bricks out there.



%pos = %pl.getPosition();

You have a radius search at (insert player ID here) 0 0, for fxBricks with raycasting enabled.
Woah woah, what does ray casting have to do with this? I want to search for bricks with ray casting disabled too.

Now your player's object ID is in the thousands at least, and you're near the origin, so there likely aren't any bricks out there.
I have no idea what you mean. I'm looking for named bricks. When testing I plant a brick with the name I specified nearby.
« Last Edit: December 21, 2013, 10:46:47 AM by Demian »

Woah woah, what does ray casting have to do with this? I wan to search for bricks with ray casting disabled too.

Then use $Typemasks::fxBrickAlwaysObjectType instead


I have no idea what you mean. I'm looking for named bricks. When testing I plant a brick with the name I specified nearby.

%pos=%obj.player;

Then use $Typemasks::fxBrickAlwaysObjectType instead

%pos=%obj.player;
Thanks. The while is still being skipped entirely:

Edit: New code. Using the client to detect the player works better. Now the whole script runs except that the distance is still to the center of the spawn instead of the brick.
Code: [Select]
function brickDetector_OFF_Image::onFire(%this, %obj, %slot, %client)
{
%obj.schedule(0,"playThread",2,shiftRight);
%obj.schedule(200,"playThread",1,armReadyRight);
%obj.unMountImage(0);
%obj.mountimage(brickDetector_ON_Image, 0);

%pos=%client.player;
%name="_asd";
%radius=32;

echo("1 vars defined");

initContainerRadiusSearch(%pos, %radius, $TypeMasks::FxBrickAlwaysObjectType);

echo("2 initialized");

while (isObject(%obj = containerSearchNext()))
{
echo("3 in the loop");
if (%obj.getName() $= %name)
{
echo("4 in the if");
commandToClient(%obj.client,'bottomPrint',"<color:ffffff>Detecting: " @ %name @ " | Distance: " @ (vectorDist(%pos, %obj.getPosition())*2) @ " Bricks");
break;
}
}
echo("5 end");
}
« Last Edit: December 21, 2013, 11:07:21 AM by Demian »

It's not skipping it, it just doesn't find anything. You're using the player object's ID as a position, which will result in it searching at some far away point on the +X axis. Use %obj.player.getPosition(), not %obj.player.

It's not skipping it, it just doesn't find anything. You're using the player object's ID as a position, which will result in it searching at some far away point on the +X axis. Use %obj.player.getPosition(), not %obj.player.
Oh! I see. The distance was still wrong though:
Code: [Select]
function brickDetector_OFF_Image::onFire(%this, %obj, %slot)
{
%obj.schedule(0,"playThread",2,shiftRight);
%obj.schedule(200,"playThread",1,armReadyRight);
%obj.unMountImage(0);
%obj.mountimage(brickDetector_ON_Image, 0);

%pos=%obj.player.getPosition();
%name="_asd";
%radius=32;

echo("1 vars defined");

initContainerRadiusSearch(%pos, %radius, $TypeMasks::FxBrickAlwaysObjectType);

echo("2 initialized");

while (isObject(%obj = containerSearchNext()))
{
echo("3 in the loop");
if (%obj.getName() $= %name)
{
echo("4 in the if");
commandToClient(%obj.client,'bottomPrint',"<color:ffffff>Detecting: " @ %name @ " | Distance: " @ (vectorDist(%pos, %obj.getPosition())*2) @ " Bricks");
break;
}
}
echo("5 end");
}

Cool. Finally some errors in the log.
Quote
Add-Ons/Tool_BrickDetector/server.cs (137): Unable to find object: '' attempting to call function 'getPosition'
BackTrace: ->brickDetector_OFF_Image::onFire

Which is this line:
Code: [Select]
%pos=%obj.player.getPosition();
Edit: I got it working with the help of MABLE MAN. Posting final code later.
« Last Edit: December 21, 2013, 12:07:54 PM by Demian »

Well everything else works except my original issue. The looping. I think I should define the %pos inside the if since the player moves and the distance needs to recalculated each loop. Right?

Code: [Select]
function brickDetector_OFF_Image::onFire(%this, %player, %slot)
{
%player.schedule(0,"playThread",2,shiftRight);
%player.schedule(200,"playThread",1,armReadyRight);
%player.unMountImage(0);
%player.mountimage(brickDetector_ON_Image, 0);

%name="_asd";
%radius=32;

initContainerRadiusSearch(%pos, %radius, $TypeMasks::FxBrickAlwaysObjectType);

while (isObject(%obj = containerSearchNext()))
{
if (%obj.getName() $= %name)
{
%pos=%player.getPosition();
%detectorMsg="\c6Detecting: \c5" @ %name @ "\c6 | Distance: \c5" @ mFloatLength(vectorDist(%pos, %obj.getPosition()),0) @ " Bricks";
commandToClient(%player.client,'bottomPrint',%detectorMsg,0,0);
break;
}
}
}

The problem is that the while runs only once. I want it to run once every second. Apparently Blockland tends to run loops as fast as it can so leading to crashes so I believe I need to slow it down by adding some sort of a delay somewhere?