Moving Actors to a Random Spot
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.
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.
- peoplethought
- Posts: 160
- Joined: Mon Aug 25, 2008 3:38 am
Moving Actors to a Random Spot
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.
- bagheadspidey
- Posts: 1490
- Joined: Sat Oct 20, 2007 10:31 pm
- Contact:
Re: Moving Actors to a Random Spot
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;
}- peoplethought
- Posts: 160
- Joined: Mon Aug 25, 2008 3:38 am
Re: Moving Actors to a Random Spot
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?
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?
- bagheadspidey
- Posts: 1490
- Joined: Sat Oct 20, 2007 10:31 pm
- Contact:
Re: Moving Actors to a Random Spot
Here's what I mean.. the actor will call an acs script to teleport right? The acs script might look something like this: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.
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;
}
}
You tell me ;p that sounds right though.Could you explain what is happening here? This is the monster calling the function right?
Yeah, that's exactly what that SetPos script is doing =)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?
- peoplethought
- Posts: 160
- Joined: Mon Aug 25, 2008 3:38 am
Re: Moving Actors to a Random Spot
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:
What exactly are you checking here?
getactory(1000)-random(0,600 * 66536)
I am confused by this:
Code: Select all
if (SetPos(0,x,y,z)) break;getactory(1000)-random(0,600 * 66536)
Last edited by peoplethought on Sat Nov 01, 2008 7:23 pm, edited 2 times in total.
- bagheadspidey
- Posts: 1490
- Joined: Sat Oct 20, 2007 10:31 pm
- Contact:
Re: Moving Actors to a Random Spot
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: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.
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?peoplethought wrote:I am confused by this:
What exactly are you checking here?Code: Select all
if (SetPos(0,x,y,z)) break;
- peoplethought
- Posts: 160
- Joined: Mon Aug 25, 2008 3:38 am
Re: Moving Actors to a Random Spot
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:
(1000 is my player tid)
From the wiki:
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");
}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.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?
From the wiki:
Ok, thanks for your help.The return value for this function is the number of actors that successfully changed state.
- bagheadspidey
- Posts: 1490
- Joined: Sat Oct 20, 2007 10:31 pm
- Contact:
Re: Moving Actors to a Random Spot
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)
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 =)
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;
}Re: Moving Actors to a Random Spot
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.
- Captain Ventris
- Posts: 4609
- Joined: Mon Jul 31, 2006 4:25 pm
- Location: San Antonio, TX
Re: Moving Actors to a Random Spot
But it will theoretically try again and end up inside the level, hopefully. It could still be bad.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.
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!
- bagheadspidey
- Posts: 1490
- Joined: Sat Oct 20, 2007 10:31 pm
- Contact:
Re: Moving Actors to a Random Spot
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 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 =)
- peoplethought
- Posts: 160
- Joined: Mon Aug 25, 2008 3:38 am
Re: Moving Actors to a Random Spot
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.
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.
Re: Moving Actors to a Random Spot
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.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 =)
- peoplethought
- Posts: 160
- Joined: Mon Aug 25, 2008 3:38 am
Re: Moving Actors to a Random Spot
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.
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.
- Captain Ventris
- Posts: 4609
- Joined: Mon Jul 31, 2006 4:25 pm
- Location: San Antonio, TX
Re: Moving Actors to a Random Spot
What about other nearby monsters or decorations? Using Baghead's method, it could still get stuck in other actors, right?