Moving Actors to a Random Spot

Archive of the old editing forum
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. This forum is archived - please use this set of forums to ask new questions.
User avatar
peoplethought
Posts: 160
Joined: Mon Aug 25, 2008 3:38 am

Moving Actors to a Random Spot

Post by peoplethought »

I'm working on an enemy that will pop up somewhere near you. It randomly chooses a distance from your x,y position to reappear repeatedly. Can you check to see if a position is free for an actor to teleport to? I would want it to continually check random position around the player until it finds a free spot to set its position to.
User avatar
bagheadspidey
Posts: 1490
Joined: Sat Oct 20, 2007 10:31 pm
Contact:

Re: Moving Actors to a Random Spot

Post by bagheadspidey »

Code: Select all

function int SetPos(int tid, int /*fixed*/ x, int /*fixed*/ y, int /*fixed*/ z)
{
  SetActorPosition(tid, x, y, z, 0);
  if ( GetActorX(tid) == x && GetActorY(tid) == y && GetActorZ(tid) == z )
    return 1;
  return 0;
}
Something like this might work. It will return 0 if it isn't able to move there so you call this in a loop until it is able to move. Make sure the loop has a max number of tries in case there's no good spot near the actor to teleport to.
User avatar
peoplethought
Posts: 160
Joined: Mon Aug 25, 2008 3:38 am

Re: Moving Actors to a Random Spot

Post by peoplethought »

I don't need a max number of tries, the enemy will just wait until the player has moved to a position that will allow him to attack. Could you explain what is happening here? This is the monster calling the function right?

Tell me if this is right: If you set an actors position to a spot it can't move to (wall clipping or other solid objects in the way) then it wont go there? So I could simply store the location I want to check, attempt to set the monsters position to that location, then compare his position to that of the stored location to see if he actually moved?
User avatar
bagheadspidey
Posts: 1490
Joined: Sat Oct 20, 2007 10:31 pm
Contact:

Re: Moving Actors to a Random Spot

Post by bagheadspidey »

peoplethought wrote:I don't need a max number of tries, the enemy will just wait until the player has moved to a position that will allow him to attack.
Here's what I mean.. the actor will call an acs script to teleport right? The acs script might look something like this:

Code: Select all

script 99 (void)
{
  for(int tries = 0; tries < 10; tries++)
  {
    int x = GetActorX(PLAYER_TID) + (random (0,32.0) - 16.0);
    int y = GetActorY(PLAYER_TID) + (random (0,32.0) - 16.0);
    int z = GetActorZ(PLAYER_TID);
    if (SetPos(0,x,y,z)) break;
  } 
}
That way it won't keep trying and failing to teleport forever in an endless loop if your player is, say, noclipped in a wall somewhere.

Could you explain what is happening here? This is the monster calling the function right?
You tell me ;p that sounds right though.
Tell me if this is right: If you set an actors position to a spot it can't move to (wall clipping or other solid objects in the way) then it wont go there? So I could simply store the location I want to check, attempt to set the monsters position to that location, then compare his position to that of the stored location to see if he actually moved?
Yeah, that's exactly what that SetPos script is doing =)
User avatar
peoplethought
Posts: 160
Joined: Mon Aug 25, 2008 3:38 am

Re: Moving Actors to a Random Spot

Post by peoplethought »

Ok thanks I have it working, but I don't need to limit the number of tries in ACS because I have a short loop executing the script in Decorate. So it's already running the script continuously until it works, at which point I'll change its state. It's not essential that the monster find a place to pop up in one run of the function, there is supposed to be a delay between each appearance anyway. I get what you're saying though.

I am confused by this:

Code: Select all

if (SetPos(0,x,y,z)) break;
What exactly are you checking here?

getactory(1000)-random(0,600 * 66536)
Last edited by peoplethought on Sat Nov 01, 2008 7:23 pm, edited 2 times in total.
User avatar
bagheadspidey
Posts: 1490
Joined: Sat Oct 20, 2007 10:31 pm
Contact:

Re: Moving Actors to a Random Spot

Post by bagheadspidey »

peoplethought wrote:Ok thanks I have it working, but I don't need to limit the number of tries in ACS because I have a short loop executing the script in Decorate. So it's already running the script continuously until it works, at which point I'll change its state. It's not essential that the monster find a place to pop up in one run of the function, there is supposed to be a delay between each appearance anyway. I get what you're saying though.
If that's the case, why do you need to check if a spot is free? just try to teleport him to a random spot by the player; if it wasn't free, oh well better off next tic. Maybe I'm still confused =/
peoplethought wrote:I am confused by this:

Code: Select all

if (SetPos(0,x,y,z)) break;
What exactly are you checking here?
It's checking the return value of that SetPos function (1 if the thing is where you tried to put it, 0 if not). If the thing was placed successfully it stops looping. If you don't need to find the random spot in one tick I guess you don't need any of that?
User avatar
peoplethought
Posts: 160
Joined: Mon Aug 25, 2008 3:38 am

Re: Moving Actors to a Random Spot

Post by peoplethought »

Because I have to change it to its attack state once it has successfully moved to its new position.


Here is what I am using:

Code: Select all

script 826 (void) {  //Move to random spot near player.

int XCheck = getactorx(1000)-random(0,600*66536);
int YCheck = getactory(1000)-random(0,600 * 66536);

setactorposition(0, XCheck, YCheck,getactorz(1000),0);

if(getactorx(0)==XCheck) 
if(getactory(0)==YCheck)setactorstate(0,"Missile");

}
(1000 is my player tid)
It's checking the return value of that SetPos function (1 if the thing is where you tried to put it, 0 if not). If the thing was placed successfully it stops looping. If you don't need to find the random spot in one tick I guess you don't need any of that?
So if you use SetPosition in a IF statement it returns a value based on wether or not the movement is succesfull? Sorry, but I earlier thought I would have to manually check this.

From the wiki:
The return value for this function is the number of actors that successfully changed state.
Ok, thanks for your help. :)
User avatar
bagheadspidey
Posts: 1490
Joined: Sat Oct 20, 2007 10:31 pm
Contact:

Re: Moving Actors to a Random Spot

Post by bagheadspidey »

Heh, ok, we are pretty much doing the same thing.

SetPos is a wrapper for SetActorPosition that returns a value. It attempts to move a thing somewhere, checks if it's really there, and then returns whether it was successful. Your code does pretty much the same thing (except not checking z)

Code: Select all

function int SetPos(int tid, int /*fixed*/ x, int /*fixed*/ y, int /*fixed*/ z)
{
  SetActorPosition(tid, x, y, z, 0);
  if ( GetActorX(tid) == x && GetActorY(tid) == y && GetActorZ(tid) == z )
    return 1;
  return 0;
}
Anyway, you could consider forgetting all that and just using SetActorPosition and then jumping to a custom state that decides what to do next with a JumpIfCloser =)
User avatar
HotWax
Posts: 10002
Joined: Fri Jul 18, 2003 6:18 pm
Location: Idaho Falls, ID

Re: Moving Actors to a Random Spot

Post by HotWax »

One thing you're going to run into is that the monster may end up being moved into the void. That is, space that is not enclosed by any sector. If you use SetActorPosition and try to move an actor into the same space as another solid actor or into the middle of a wall (or where the vertical space won't allow it), it'll fail. However, if you move it out into void space, ZDoom has no way of knowing that the position isn't valid and it will succeed.
User avatar
Captain Ventris
Posts: 4609
Joined: Mon Jul 31, 2006 4:25 pm
Location: San Antonio, TX

Re: Moving Actors to a Random Spot

Post by Captain Ventris »

HotWax wrote:One thing you're going to run into is that the monster may end up being moved into the void. That is, space that is not enclosed by any sector. If you use SetActorPosition and try to move an actor into the same space as another solid actor or into the middle of a wall (or where the vertical space won't allow it), it'll fail. However, if you move it out into void space, ZDoom has no way of knowing that the position isn't valid and it will succeed.
But it will theoretically try again and end up inside the level, hopefully. It could still be bad.

Would the monster in question be able to use the same behavior when infighting with other monsters, using the same scripts? Would a monster that had targeted it lose it's target whenever the monster teleported?

EDIT: Also, wouldn't the player, no matter how far he ran, be teleported at by this monster? Dang, that's invasive. So once it woke up, it would hound you until you killed it!
User avatar
bagheadspidey
Posts: 1490
Joined: Sat Oct 20, 2007 10:31 pm
Contact:

Re: Moving Actors to a Random Spot

Post by bagheadspidey »

hmm, good point HW.

You could make it not solid and invisible, teleport it to the exact location of the player, thrust it away in a random direction quickly, and make it visible and solid again... Yay hax =)
User avatar
peoplethought
Posts: 160
Joined: Mon Aug 25, 2008 3:38 am

Re: Moving Actors to a Random Spot

Post by peoplethought »

Yes it does hound you until you kill it. Yes it could use this attack on other monsters, I'd just have to adjust the script to use the target x,y instead of only the player x,y. I'm not skilled enough with Decorate to know if it could be done completely without ACS yet.

That's a brilliant way of dealing with the void problem baghead, I might just use that. I just have to make sure I check to see that the actor is at ground level still after being thrusted before making it reappear as the animation of him reappearing is of him breaking up out of the ground.
User avatar
Ichor
Posts: 1784
Joined: Wed Jul 23, 2003 9:22 pm

Re: Moving Actors to a Random Spot

Post by Ichor »

bagheadspidey wrote:hmm, good point HW.

You could make it not solid and invisible, teleport it to the exact location of the player, thrust it away in a random direction quickly, and make it visible and solid again... Yay hax =)
You might want to also throw in HEXENBOUNCE, SLIDESONWALLS, or something like that, because there might be the off chance of the monster trying to teleport to the player who happens to be near a wall. If the monster gets thrusted towards the wall and then solidifies, he could still get stuck in the player.
User avatar
peoplethought
Posts: 160
Joined: Mon Aug 25, 2008 3:38 am

Re: Moving Actors to a Random Spot

Post by peoplethought »

Another good point. If it's thrusted while unsolid it could solidify on top of another actor. But I could still check to see if it's on a free spot before solidfying it and if not make it thrust out again.

If I continue to do it how I'm doing now, even if the player where standing next to a wall with a void on the other side 50% of the monsters appearances would be inside the sector. That's enough to still be a nuisance I think.
User avatar
Captain Ventris
Posts: 4609
Joined: Mon Jul 31, 2006 4:25 pm
Location: San Antonio, TX

Re: Moving Actors to a Random Spot

Post by Captain Ventris »

What about other nearby monsters or decorations? Using Baghead's method, it could still get stuck in other actors, right?
Locked

Return to “Editing (Archive)”