Author Topic: Homing Script  (Read 917 times)

Code: [Select]
function svectorProjectile::changeForm(%db,%prj)
{
initContainerRadiusSearch(%prj.getPosition(),50,$TypeMasks::PlayerObjectType);
while(1)
{
%search=containerSearchNext();
if(%prj.client==%search.client)
{
continue;
}

%mg=%prj.client.minigame;
%mc=%search.client.minigame;
%mgo=isObject(%mg);
%mco=isObject(%mco);

if(%mgo == %mco == 1)
{
if(%mg!$=%mc)
{
continue;
}
}

if(isObject(%search))
{
%obj=%search;
}
break;

}
if(!isObject(%obj)) {%prj.delete();return;}

%pos=vectorAdd(%obj.getPosition(),"0 0 "@ getWord(%obj.getScale(),2)*1.8);

%vec=vectorSub(%pos,%prj.getPosition());
%vec=vectorScale(vectorNormalize(%vec),svectorProjectile.muzzleVelocity);

%p = new Projectile()
{
initialVelocity = %vec;
initialPosition = %prj.getPosition();
datablock = svectorProjectile;
sourceObject = %prj.client.player;
sourceSlot = %prj.sourceSlot;
client = %prj.client;
scale = %prj.getScale();
CNT = %prj.CNT++;
};
if(%prj.CNT<12) {svectorProjectile.schedule(getRandom(100,200),"ChangeForm",%p);}
%prj.delete();
}

So, this is the homing script from Bushido's old Homing Vector. I've been playing around with it to see what it is that's causing server instability, and I think I know what it is.

Say you were to fire the gun when two players were nearby. If those players happened to be exactly the same distance away from a projectile that was fired, what would happen? The engine won't know what to do. It will try to send it to two different places at once. This obviously wouldn't work, and the engine would crash.

I was trying to figure out a way to fix this. Ive never worked with containerSearches before, so please bear with me.

I was thinking of adding another if statement to the code to test for two vectors of the same length, and delete the projectile in this case. However, I don't know how I'd identify these in the script.
Code: [Select]

if (%vec1 == %vec2)
{
       %prj.delete();
}
But, I don't know how to identify %vec1 and %vec2 when the containerSearch starts.

Alternately, there could be an if statement that tests whether there are two playerObjects within the search radius, and if this is the case, randomly choose one of them. This wouldn't be as good, because you could be aiming at someone right in front of you and instead it goes after someone 10 feet away from you, but it's certainly better than crashing.


Any thoughts on how this can be done? I'm not trying to re-release the Vector, I just want to be able to use it in my own server without having to worry about random crashes.

if(%mgo == %mco == 1)

is that even a valid if statement or is this another weird torque syntax thing i dont know about

if(%mgo == %mco == 1)

is that even a valid if statement or is this another weird torque syntax thing i dont know about
What do you mean valid? You can perform multiple tests in one if statement if that's what you mean.

What do you mean valid? You can perform multiple tests in one if statement if that's what you mean.
Not that way (that I know of).

if(%mgo == %mco == 1)

is that even a valid if statement or is this another weird torque syntax thing i dont know about

I doubt it, nothing is wrong with

Code: [Select]
if(%mgo == 1 && %mco ==1)
Also, a while(1) loop should never be a real option.

Try to incorporate the conditions for the break into the test for the while loop instead, if you must.

Also, a while(1) loop should never be a real option.
There are plenty legitimate uses for a while(1) loop as long as you're positive it breaks at a certain point.
« Last Edit: January 22, 2012, 02:55:15 PM by Slicksilver »

I doubt it, nothing is wrong with

Code: [Select]
if(%mgo == 1 && %mco ==1)
Oh, I think I get it.


That  basically says
if((%mgo == %mco) == 1)

I'm not questioning the method, Im trying to fix the crashes it causes in-game.

What alternatives for while(1) are there, if that could be what's causing the crashes? If not, go back to what I was talking about with deleting the projectiles if they're their distance from two players is the same.

I'm not questioning the method, Im trying to fix the crashes it causes in-game.

What alternatives for while(1) are there, if that could be what's causing the crashes? If not, go back to what I was talking about with deleting the projectiles if they're their distance from two players is the same.
remove %search = containerSearchNext(); from the first line.

while(isObject(%search = containerSearchNext()))

It seems that'd work but it also seems that'd be what would be used unless there were an issue.

That  basically says
if((%mgo == %mco) == 1)
Pretty sure if(%mgo == %mco == 1) is the same as if(%mgo == %mco && %mgo == 1). It tests whether they are both 1.
if((%mgo == %mco) == 1) would be the same as if(%mgo == %mco).

I think.

if(%mgo == %mco == 1)

is that even a valid if statement or is this another weird torque syntax thing i dont know about

It is equally valid as something like this:

if( isFunction( %function = "func_" @ getRandom( 0, 5 ) ) )
        call( %function, collapseEscape( "\\x" @ %val SPC "\\\\" ) );
else
        %this.success = %this.parent.success = %success = false;


TorqueScript is a very "flexible" language.
« Last Edit: January 23, 2012, 02:52:09 AM by Port »

Code: [Select]
while(1)
{
%search=containerSearchNext();
if(%prj.client==%search.client)
{
continue;
}

%mg=%prj.client.minigame;
%mc=%search.client.minigame;
%mgo=isObject(%mg);
%mco=isObject(%mco);

if(%mgo == %mco == 1)
{
if(%mg!$=%mc)
{
continue;
}
}

if(isObject(%search))
{
%obj=%search;
}
break;

}

Looks excessively complicated, though it could have grown that way due to subtle unexpected engine behaviour. I highly doubt it, so would suggest the alternative:

Code: [Select]
   while((%found = containerSearchNext()))
    {
        if(%prj.client.minigame == %found.client.minigame)
        {
            %obj = %found;
            break;
        }
    }



"%mco=isObject(%mco);" is clearly a typo, intended to be "%mco=isObject(%mc);"
"%mgo == %mco == 1" is likely the same as "(%mgo == %mco) == 1", which is redundant. At first I thought it may have been an attempt to imitate a logical XOR through awkward syntax, but "%mg!$=%mc" clearly expects them to both either be objects or not objects.

Ah, but the layout of that makes me think that there was a problem with minigames  that no longer existed, and the solution used seems to be overly complex. So...


Code: [Select]
   while((%found = containerSearchNext()))
    {
        %mg = %prj.client.minigame;
        %mc = %found.client.minigame;

        if((!isObject(%mc) && !isObject(%mg)) || %mc == %mg)
        {
            %obj = %found;
            break;
        }
    }

Edit: Oops, missed the part about not targeting self, so it would be


Code: [Select]
    while((%search = containerSearchNext()))
    {
        if(%prj.client == %search.client)
        {
            continue;
        }

        %mg = %prj.client.minigame;
        %mc = %search.client.minigame;

        if((!isObject(%mc) && !isObject(%mg)) || %mc == %mg)
        {
            %obj = %search;
            break;
        }
    }
« Last Edit: January 23, 2012, 08:04:08 PM by Uristqwerty »