Page 1 of 3

How do I synchronize moving objects?

Posted: Sun Aug 29, 2004 11:56 am
by tltrude
In Atomic's new "Train to Hell" map, I have added three moving telephone poles. They worked fine untill I added wires to each pole and tried to synchronize their movement around a loop of four waypoints--two are underground.

This first method uses time and it worked well until the game was tested on a dedicated server with three players. The script_objects overlaped each other by about 64 unit.

Code: Select all

//------------------------------>
// Pole Threads
//------------------------------>

pole_prep:

	$pole time .001
	$pole2 time .001
	$pole3 time .001 
	$pole moveto $polewayA  
	$pole2 moveto $polewayA   
	$pole3 moveto $polewayA
	$pole move
	$pole2 move  
	$pole3 waitmove
	Thread pole1loop
	wait 2.4
	Thread pole2loop
	wait 2.405
	Thread pole3loop

end
	 
pole1loop: 

	$pole time 7.2  
	$pole moveto $polewayB 
	$pole waitmove
 
	$pole time .001
	$pole moveto $polewayC 
	$pole waitmove
 
	$pole moveto $polewayD  
	$pole waitmove

	$pole moveto $polewayA  
	$pole waitmove

	goto pole1loop

end

pole2loop: 

	$pole2 time 7.2  
	$pole2 moveto $polewayB 
	$pole2 waitmove
 
	$pole2 time .001
	$pole2 moveto $polewayC 
	$pole2 waitmove
 
	$pole2 moveto $polewayD  
	$pole2 waitmove

	$pole2 moveto $polewayA  
	$pole2 waitmove

	goto pole2loop

end

pole3loop: 

	$pole3 time 7.2  
	$pole3 moveto $polewayB 
	$pole3 waitmove
 
	$pole3 time .001
	$pole3 moveto $polewayC 
	$pole3 waitmove
 
	$pole3 moveto $polewayD  
	$pole3 waitmove
 
	$pole3 moveto $polewayA  
	$pole3 waitmove

	goto pole3loop

end
As you can see the timing depends on all three poles starting at timed intervals, without interruption. So, if there is a pause, like somone joinging the game, the synchronization goes out of wack.

Next I tried to use four poles and have one pole wait at the starting point (waypoint A) until the one before it got to a script_origin--exactly 1/3 the distance to the next point (waypoint B). Then it is glued to a script_origin bound to the end point of one before it. That worked fine in a test map, but fails in the real map. There is a gap of about 8 units between the wires and the next pole. And, if I lenghten the wires, the game crashes with infinite loop errors.

Code: Select all

//------------------------------>
// Pole Threads
//------------------------------>

pole_prep:

	$pole1 time .001
	$pole2 time .001
	$pole3 time .001 
	$pole4 time .001 
	$pole1 moveto $polewayA  
	$pole2 moveto $polewayA   
	$pole3 moveto $polewayA
	$pole4 moveto $polewayA
	$pole1 move
	$pole2 move
	$pole3 move  
	$pole4 waitmove
	$pole1 hide
	$pole2 hide  
	$pole3 hide
	$pole4 hide
	$pole1 time 7.18
	$pole2 time 7.18
	$pole3 time 7.18 
	$pole4 time 7.18
	$p1o bind $pole1
	$p2o bind $pole2
	$p3o bind $pole3
	$p4o bind $pole4
	wait 5
	thread pole_timer

end

pole_timer:

	Thread pole1loop
	while (int(vector_length ($pole1.origin - $go_point.origin) > 16))
		waitframe
	Thread pole2loop 
	while (int(vector_length ($pole2.origin - $go_point.origin) > 16))
		waitframe
	Thread pole3loop 
	while (int(vector_length ($pole3.origin - $go_point.origin) > 16))
		waitframe
	Thread pole4loop
	while (int(vector_length ($pole4.origin - $go_point.origin) > 16))
		waitframe
	thread pole_timer

end
	 
pole1loop: 

	$pole1 show
	$pole1 glue $p4o  
	$pole1 unglue $p4o
	$pole1 moveto $polewayB 
	$pole1 waitmove
 
	$pole1 hide
	$pole1 time .001
	$pole1 moveto $polewayC 
	$pole1 waitmove
 
	$pole1 moveto $polewayD  
	$pole1 waitmove

	$pole1 moveto $polewayA  
	$pole1 waitmove
	$pole1 time 7.18  

end

pole2loop: 

	$pole2 show
	$pole2 glue $p1o  
	$pole2 unglue $p1o 
	$pole2 moveto $polewayB 
	$pole2 waitmove
 
	$pole2 hide
	$pole2 time .001
	$pole2 moveto $polewayC 
	$pole2 waitmove
 
	$pole2 moveto $polewayD  
	$pole2 waitmove

	$pole2 moveto $polewayA  
	$pole2 waitmove
	$pole2 time 7.18

end

pole3loop: 

	$pole3 show
	$pole3 glue $p2o  
	$pole3 unglue $p2o
	$pole3 moveto $polewayB 
	$pole3 waitmove

	$pole3 hide
	$pole3 time .001
	$pole3 moveto $polewayC 
	$pole3 waitmove
 
	$pole3 moveto $polewayD  
	$pole3 waitmove
 
	$pole3 moveto $polewayA  
	$pole3 waitmove
	$pole3 time 7.18 

end

pole4loop: 

	$pole4 show
	$pole4 glue $p3o  
	$pole4 unglue $p3o
	$pole4 moveto $polewayB 
	$pole4 waitmove

	$pole4 hide
	$pole4 time .001
	$pole4 moveto $polewayC 
	$pole4 waitmove
 
	$pole4 moveto $polewayD  
	$pole4 waitmove
 
	$pole4 moveto $polewayA  
	$pole4 waitmove
	$pole4 time 7.18

end
Anyway, I am sure open to new ideas!!!!!!!!!!!

I know I can use streight wires that are fixed in place, but the sagging wires look so cool as they go by the train.

Any, help would be great!

Posted: Sun Aug 29, 2004 1:38 pm
by bdbodger
I think you need to move all the poles at once like a train . Then shift the front pole to the back like this

Code: Select all

level.pole[0]= $pole1
level.pole[1]= $pole2
level.pole[2]= $pole3
level.pole[3]= $pole4

level.way[0] = $way1
level.way[1] = $way2
level.way[2] = $way3
level.way[3] = $way4
level.way[4] = $way5

// setup poles

for(local.i=0;local.i < 4;local.i++) 
{
	level.pole[local.i].origin = level.way[local.i].origin
	level.pole[local.i] time 7.2 
}

// first pole to be shifted to back of line

level.shift_pole = 3

while(1)
{

	for(local.i=1;local.i< 5;local.i++) // move level.pole[0] to all the waypoints
	{
		waitthread bind_poles
		level.pole[0] moveto level.way[local.i];level.pole[0] waitmove
		waitthread unbind_poles
		waitthread shift_poles // shift front pole to back
	}
}
end	
	

bind_poles: // bind poles 1 to 3 to pole 0
{
	for(local.i=1;local.i< level.pole.size;local.i++)

		level.pole[local.i] bind level.pole[0]
}
end

unbind_poles:
{
	for(local.i=1;local.i< level.pole.size;local.i++)

		level.pole[local.i] unbind
}
end

shift_poles:

level.pole[level.shift_pole].origin = level.way[0].origin

if(level.shift_pole == 0)
	level.shift_pole = 3
else
	level.shift_pole--
end

Posted: Sun Aug 29, 2004 4:52 pm
by jv_map
I must be an idiot but can't you make all the poles and wires etc into one huge script_object? :?

Hmmm

Posted: Mon Aug 30, 2004 11:31 am
by tltrude
I will try your threads bdbodger, if I can figure out where the 5th waypoint goes!

Sorry jv_map, I should of explained how the map works a little better. The train stand still. The terrain, treelines, track, and road textures all scroll by to make the train look like it is moving. Everything else in the map (except the train) are script objects that loop around 4 waypoints, two of which are underground. They move at the same speed as the scrolling ground texture--while they are visible to the players.

Right now I am using three telephone pole script_objects. Each has it own set of sagging wires that trail behind the pole. So, if they are in sync, they look like a continous (unbroken) line of poles and wires. This screenshot shows the wires from two poles but, unfortunately, the pole is hidden inside the station, which is also moving.

Image

Posted: Mon Aug 30, 2004 11:54 am
by bdbodger
Ok give it a try anyway . The five way points are so you have 1 empty so you can shift the end one back to the start . I assume they are spaced so that the wires line up to the next pole . They move so that they start with waypoints 1 to 4 with poles on them then they shift over 1 waypoint so that waypoints 2 to 5 now have the poles on them then the pole from way 5 gets shifted to way 1 and it starts again .

Posted: Mon Aug 30, 2004 12:35 pm
by jv_map
Yay! I get it now... :D the way bdbodger has it you'd need a waypoint for every pole and have them spaced along the track... right?

I'll throw another suggestion into the pot, see if you like it :)

Code: Select all

// required:
// $waypointA at start of track
// $waypointB at end of track

local.POLE_SEPERATION = 256.0 // distance between poles
local.SPEED = 200.0 // train speed

local.poles = $pole1::$pole2::$pole3 // etc

local.basepoint = $waypointA.origin
local.movevec = $waypointB.origin - local.basepoint
local.trackdist = vector_length local.movevec
local.dirvec = (1.0 / local.trackdist) * local.movevec // unit vector
local.offset = local.poles[1].origin - local.basepoint

local.dist = 0.0 // distance travelled

while(1)
{
	// space the poles along the track
	for(local.i = 1; local.i <= local.poles.size; local.i++)
	{
		local.pole = local.poles[local.i]
		local.dist_on_track = local.dist + local.POLE_SEPERATION * (local.i - 1)
		if(local.dist_on_track > local.trackdist)
		{
			// move back to the beginning
			local.dist_on_track -= local.trackdist
		}
		local.pole.origin = local.basepoint + local.offset + local.dist_on_track * local.dirvec
	}
	waitframe
	local.dist += local.SPEED * 0.05
	
	// this is only to prevent the dist variable from getting too large
	if(local.dist > local.trackdist)
		local.dist -= local.trackdist
}
:idea: :wink:

poles

Posted: Mon Aug 30, 2004 7:34 pm
by tltrude
A single pole and its wires is 3680 unit long (from the origin brush to the end of the wires). The distance between the two above ground waypoints is 11040 units. So, each pole is exactly 1/3 the distance. The speed of the terrain is 3 X 512 per second (tcmod scroll 3 0). To match the speed, the poles must travel the 11040 units in 7.18 seconds.

Testing bd's method, the poles look fine until pole4 shows up at way1. Then all the poles sink underground slowly while pole1 moves back to way5 (slowly) and up to way1 (fast). I have four waypoint above ground (way1-way4) and the fifth one (way5) is underground below way1. The poles are moveing way to slow. The targetnames are all correct.

Testing jv's thread, the poles worked after I added line to move the first pole to the starting point. However, when a pole goes back to the start, it is not hidden or does not move underground. Here are the two scripts.

Code: Select all

main:

// set scoreboard messages
setcvar "g_obj_alliedtext1" "test poles!"
setcvar "g_obj_alliedtext2" ""
setcvar "g_obj_alliedtext3" ""
setcvar "g_obj_axistext1" ""
setcvar "g_obj_axistext2" ""
setcvar "g_obj_axistext3" ""

setcvar "g_scoreboardpic" ""

	level waittill prespawn
 
	//***Precache Dm Stuff
	exec global/DMprecache.scr
	level.script = maps/dm/test_bpoles.scr
	exec global/ambient.scr m6l3a // for background sound

	thread pole_prep

	level waittill spawn 

end

//------------------------------>
// Pole Threads
//------------------------------>

pole_prep:

level.pole[0]= $pole1 
level.pole[1]= $pole2 
level.pole[2]= $pole3 
level.pole[3]= $pole4 

level.way[0] = $way1 
level.way[1] = $way2 
level.way[2] = $way3 
level.way[3] = $way4 
level.way[4] = $way5 

// setup poles 

for(local.i=0;local.i < 4;local.i++) 
{ 
   level.pole[local.i].origin = level.way[local.i].origin 
   level.pole[local.i] time 7.2 
} 

// first pole to be shifted to back of line 

level.shift_pole = 3 

while(1) 
{ 

   for(local.i=1;local.i< 5;local.i++) // move level.pole[0] to all the waypoints 
   { 
      waitthread bind_poles 
      level.pole[0] moveto level.way[local.i];level.pole[0] waitmove 
      waitthread unbind_poles 
      waitthread shift_poles // shift front pole to back 
   } 
} 
end    
    

bind_poles: // bind poles 1 to 3 to pole 0 
{ 
   for(local.i=1;local.i< level.pole.size;local.i++) 

      level.pole[local.i] bind level.pole[0] 
} 
end 

unbind_poles: 
{ 
   for(local.i=1;local.i< level.pole.size;local.i++) 

      level.pole[local.i] unbind 
} 
end 

shift_poles: 

level.pole[level.shift_pole].origin = level.way[0].origin 

if(level.shift_pole == 0) 
   level.shift_pole = 3 
else 
   level.shift_pole-- 
end 

Code: Select all

main:

// set scoreboard messages
setcvar "g_obj_alliedtext1" "test poles!"
setcvar "g_obj_alliedtext2" ""
setcvar "g_obj_alliedtext3" ""
setcvar "g_obj_axistext1" ""
setcvar "g_obj_axistext2" ""
setcvar "g_obj_axistext3" ""

setcvar "g_scoreboardpic" ""

	level waittill prespawn
 
	//***Precache Dm Stuff
	exec global/DMprecache.scr
	level.script = maps/dm/test_jpoles.scr
	exec global/ambient.scr m6l3a // for background sound

	thread pole_prep

	level waittill spawn 

end

//------------------------------>
// Pole Thread
//------------------------------>

pole_prep:

// required: 
// $waypointA at start of track 
// $waypointB at end of track 

local.POLE_SEPERATION = 3680 // distance between poles 
local.SPEED = 1536.0 // terrain speed (3 X 512)

local.poles = $pole1::$pole2::$pole3::$pole4 

local.basepoint = $way1.origin 
local.movevec = $way4.origin - local.basepoint 
local.trackdist = vector_length local.movevec 
local.dirvec = (1.0 / local.trackdist) * local.movevec // unit vector
local.poles[1] time .005
local.poles[1] moveto $way1
local.poles[1] waitmove
local.offset = local.poles[1].origin - local.basepoint 

local.dist = 0.0 // distance travelled 

while(1) 
{ 
   // space the poles along the track 
   for(local.i = 1; local.i <= local.poles.size; local.i++) 
   { 
      local.pole = local.poles[local.i] 
      local.dist_on_track = local.dist + local.POLE_SEPERATION * (local.i - 1) 
      if(local.dist_on_track > local.trackdist) 
      { 
         // move back to the beginning 
         local.dist_on_track -= local.trackdist 
      } 
      local.pole.origin = local.basepoint + local.offset + local.dist_on_track * local.dirvec 
   } 
   waitframe 
   local.dist += local.SPEED * 0.05 
    
   // this is only to prevent the dist variable from getting too large 
   if(local.dist > local.trackdist) 
      local.dist -= local.trackdist 
} 
end
I don't understand how jv's "offset" works, or what it is for. But, the poles seem to move smoothly and at the correct speed to match the ground scroll speed.

Posted: Mon Aug 30, 2004 9:04 pm
by bdbodger
For what I posted all the way's have to be in a row evenly spaced it is like marbles in a tube you take one out of one end of the tube and put it in the other end of the tube and keep doing that . It is not going to work right unless way 5 is in inline the same as the other way's .

ok

Posted: Tue Aug 31, 2004 5:10 am
by tltrude
Ok, I deleted $way5 and spawned it in the script at a point that is ( -3680 0 0 ) from $way4. That point is outside the skybox, but it does not seem to matter. So, the poles are working, but they all "jerk" ahead about a foot when a pole returns to the starting pont. Also, the pole that returns is not hidden (or moved underground) on its way back to the start.

I had to adjust the time for the added waypoints.

level.pole[local.i] time 2.395

But, like I said, the whole string of poles jerks forward when a pole returns. So, they do not stay in one spot on the moving ground texture.

Re: poles

Posted: Tue Aug 31, 2004 9:37 am
by jv_map
tltrude wrote:Testing jv's thread, the poles worked after I added line to move the first pole to the starting point. However, when a pole goes back to the start, it is not hidden or does not move underground.
That's right... the pole is not hidden and it does not move underground... but does it look good?
I don't understand how jv's "offset" works, or what it is for. But, the poles seem to move smoothly and at the correct speed to match the ground scroll speed.
The offset was to allow the poles to move on a path that is not exactly between the 2 waypoints, but does have the same length and direction. For example you could have the waypoints at the center of the track and have the poles move next to the track. However as you moved the first pole to the starting position, the offset vector is (0 0 0) and can be omitted :)

Image

offset

Posted: Tue Aug 31, 2004 6:03 pm
by tltrude
No, it does not look good to see the end pole wiz by on its way back to the starting point.

I don't know what has become of pole4 because I only see three when using your method, jv--I think it is overlapping pole1. The origin brush for each pole is already offset by the correct amount, so I will try to remove your offset feature.

I like Bdbodger's "spawned waypoint that is outside the skybox" idea because it makes it harder for players to see the pole and wires vanish at that end of the map. That waypoint is actually spawning beyond the limits of the grid and it still works.

My original waypoints ($polewayA thru $polewayD) are used by other moving script_objects as well. C and D are below ground. And, There is another set of 4 waypoints on the other side of the train which are even farther apart ($wayA thru $wayD).

cool

Posted: Wed Sep 01, 2004 12:49 am
by tltrude
Ok, I spawned a new waypoint that is four pole lenghts away from the start waypoint and I can now see the forth pole. I took out the offset stuff too. So, if anyone can suggest how to make the returning pole invisible, jv-map's method will be perfect.

In this screenshot, the forth pole's wires can be seen closest to the camera. The lean is caused by the camera angle and they do not lean like that in the game.

Image

Here is the latest script.

Code: Select all

main:

// set scoreboard messages
setcvar "g_obj_alliedtext1" "test poles!"
setcvar "g_obj_alliedtext2" ""
setcvar "g_obj_alliedtext3" ""
setcvar "g_obj_axistext1" ""
setcvar "g_obj_axistext2" ""
setcvar "g_obj_axistext3" ""

setcvar "g_scoreboardpic" ""

	level waittill prespawn
 
	//***Precache Dm Stuff
	exec global/DMprecache.scr
	level.script = maps/dm/test_jpoles.scr
	exec global/ambient.scr m6l3a // for background sound

	spawn info_waypoint targetname "polewayB2"
	$polewayB2.origin = ($polewayB.origin + ( -3680 0 0 ))

	thread pole_prep

	level waittill spawn 

end

//------------------------------>
// Pole Thread
//------------------------------>

pole_prep:

local.POLE_SEPERATION = 3680 // distance between poles 
local.SPEED = 1536.0 // terrain speed (3 X 512)

local.poles = $pole1::$pole2::$pole3::$pole4 

local.basepoint = $polewayA.origin 
local.movevec = $polewayB2.origin - local.basepoint 
local.trackdist = vector_length local.movevec 
local.dirvec = (1.0 / local.trackdist) * local.movevec // unit vector
local.poles[1] time .005
local.poles[1] moveto $polewayA
local.poles[1] waitmove
local.dist = 0.0 // distance travelled

//pole movement loop 

while(1) 
{ 
   // space the poles along the track 
   for(local.i = 1; local.i <= local.poles.size; local.i++) 
   { 
      local.pole = local.poles[local.i] 
      local.dist_on_track = local.dist + local.POLE_SEPERATION * (local.i - 1) 
      if(local.dist_on_track > local.trackdist) 
      { 
         // move back to the beginning 
         local.dist_on_track -= local.trackdist 
      } 
      local.pole.origin = local.basepoint + local.dist_on_track * local.dirvec 
   } 
   waitframe 
   local.dist += local.SPEED * 0.05 
    
   // this is only to prevent the dist variable from getting too large 
   if(local.dist > local.trackdist) 
      local.dist -= local.trackdist 
}
 
end

Posted: Wed Sep 01, 2004 12:38 pm
by jv_map
Funny... can you actually see them move back? :? They're supposed to be kind of teleported back to their starting position...

yes

Posted: Wed Sep 01, 2004 12:59 pm
by tltrude
Yes, I do see it. It is very fast, but it flickers about three times on its way back. I guess it has something to do with framerate or video settings. The poles are 445 units tall, and the wires are 3680 units long. So, the size of the object may have something to do with it.

If need be, I can add a fifth pole, so that one is always waiting below while the four above are moving. But, I don't know how to add the other two waypoint to your loop.

Posted: Wed Sep 01, 2004 1:05 pm
by jv_map
Strange... I wouldn't expect that to happen :?

Does it help if you change this:

Code: Select all

local.poles[1] time .005
local.poles[1] moveto $polewayA
local.poles[1] waitmove 
into:

Code: Select all

local.poles[1].origin = $polewayA.origin
:?: