Перейти к содержимому
View in the app

A better way to browse. Learn more.

Zloplay community

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
Опубликовано:

Some time ago i was derping around with ffViewer and found this in mp_nightshift.ff:

http://pastebin.com/Yp8s327k

...train_setup()
{
       precacheItem( "train_mp" );    

       delay_until_first_train = 2;
       Units_per_second = 1200;// train speed
       train_cars = 24;
       distance_between_cars = 368;
       eq_radius = 900;//      radius of earthquakes broadcast from the train tracks

       min_time_between_trains = 100;
       max_time_between_trains = 200;...

idk if the train-model is even integrated in the map or scrapped earlier, i couldn't find any entities regarding this.

As you can see here, there were concrete plans to let the train spawn and move:

3C9CB06046314560A6BBE3063E0C3E336A447C82

34F8B4BA081EB7022F3A92026EC5D760A138EDF3

Is somebody here willing to give it a shot?

Featured Replies

Опубликовано:

_train.gsc

#include maps\mp\_utility;
#include common_scripts\utility;

SOUND_DELAY_MIN = 0.1;
SOUND_DELAY_MAX = 1;

init()
{
train = getEnt( "the_l_train", "targetname" );
assertex( isdefined( train ), "Calling to setup train in map without having the train in map! [targetname]" );
train thread train_setup();
}

train_setup()
{
precacheItem( "train_mp" );	

delay_until_first_train = 2;
Units_per_second = 1200;// train speed
train_cars = 24;
distance_between_cars = 368;
eq_radius = 900;// 	radius of earthquakes broadcast from the train tracks

min_time_between_trains = 100;
max_time_between_trains = 200;

lead_in_dist = 8000;
lead_out_dist = 4000;

train_car_sound_interval = 3;

flag_init( "train_running" );

yaw = self.angles[ 1 ];
while ( yaw >= 90 )
{
	yaw -= 90;
}
assertEx( yaw == 0, "Trains must have a yaw of 0, 90, 180, or 270 currently( for collision purposes )" );

wheels = getentarray( "wheel", "targetname" );
wheel_model = wheels[ 0 ].model;
wheel_offset = [];
foreach ( wheel in wheels )
{
	wheel linkto( self );
	wheel.offset = self.origin - wheel.origin;
}

// ****************
// Set up the other cars
// ****************	
forward = anglestoforward( self.angles );
forward *= distance_between_cars;
car_separation_vec = forward;
cars = [];
for ( i = 0; i < train_cars - 1; i++ )// - 1 car self is the lead car
{
	car = spawn( "script_model", self.origin - car_separation_vec );
	car.angles = self.angles;
	car setmodel( self.model );
	car linkto( self );
	car_separation_vec += forward;
	cars[ cars.size ] = car;
	car.wheels = [];

	foreach ( owner_wheel in wheels )
	{
		wheel = spawn( "script_model", car.origin + owner_wheel.offset );
		wheel setmodel( wheel_model );
		wheel.angles = owner_wheel.angles;
		wheel linkto( car );
		car.wheels[ car.wheels.size ] = wheel;
	}
}

// ****************
// The start and end points for the train, set from script origins
// ****************	
start = getent( self.target, "targetname" );
start.origin = ( start.origin[ 0 ], start.origin[ 1 ], self.origin[ 2 ] );

end = getent( start.target, "targetname" );
end.origin = ( end.origin[ 0 ], end.origin[ 1 ], self.origin[ 2 ] );
forward = anglestoforward( self.angles );
start.origin = start.origin - forward * lead_in_dist;
end.origin = end.origin + forward * lead_out_dist;

track_dist = distance( start.origin, end.origin );
travel_dist = track_dist + train_cars * distance_between_cars;
travel_time = travel_dist / Units_per_second;
track_time = track_dist / Units_per_second;
full_train_time = train_cars * distance_between_cars / Units_per_second;



// ****************
// set up the earthquakes that play to make the train tracks rattle
// ****************	
distance_between_eq_orgs = eq_radius * 0.5;
eq_count = track_dist / distance_between_eq_orgs;

// the amount of time it takes for all the EQs to start before the train moves in
delay_between_eqs = track_time / eq_count;
travel_time_segment = track_time / eq_count;
min_time_between_trains -= track_time;
if ( min_time_between_trains < 0.1 )
	min_time_between_trains = 0.1;
max_time_between_trains -= track_time;
if ( max_time_between_trains < min_time_between_trains )
	max_time_between_trains = min_time_between_trains + 0.1;

eq_points = [];
for ( i = 0; i < eq_count; i++ )
{
	progress = i / eq_count;
	eq_points[ i ] = start.origin * ( 1 - progress ) + end.origin * progress;
}

self.cars = cars;
self.wheels = wheels;

self.origin = start.origin;
wait( delay_until_first_train );

for ( ;; )
{
	hide_trains();
	wait( 0.05 );
	self.origin = start.origin;


	// First there is a lead in of small EQs to shake the platform
	timer = gettime();
	for ( i = 0; i < eq_count; i++ )
	{
		thread train_eq( eq_points[ i ], eq_radius, track_time, full_train_time );
		wait( delay_between_eqs );
	}

	show_trains();
	thread train_kills_players( train_cars, distance_between_cars );
	thread train_spawns_dust();

	// Now the train goes by
	self moveto( end.origin + car_separation_vec, travel_time );
	train_play_sounds( train_car_sound_interval );

	wait( travel_time );
	hide_trains();

	train_stop_sounds( train_car_sound_interval );

	flag_set( "train_running" );
	self notify( "train_stops_killing_players" );
	// Wait until the next train
	wait( randomfloatrange( min_time_between_trains, max_time_between_trains ) );
}
}

train_play_sound_delayed( alias )
{
wait( randomfloatrange( SOUND_DELAY_MIN, SOUND_DELAY_MAX ) );	
self playLoopSound( alias );
}

train_play_sounds( max )
{	
self thread train_play_sound_delayed( "veh_train_eng_dist1_loop" );
self thread train_play_sound_delayed( "veh_train_eng_dist2_loop" );
self thread train_play_sound_delayed( "veh_train_eng_mid_loop" );
self thread train_play_sound_delayed( "veh_train_eng_close1_loop" );
self thread train_play_sound_delayed( "veh_train_eng_close2_loop" );

// dont play sounds on every car
count = 0;
for ( i = 0; i < self.cars.size; i++ )
{
	count++;
	if ( count < max )
		continue;
	count = 0;

	self.cars[ i ] thread train_play_sound_delayed( "veh_train_car_dist_loop" );
	self.cars[ i ] thread train_play_sound_delayed( "veh_train_car_mid_loop" );
	self.cars[ i ] thread train_play_sound_delayed( "veh_train_car_close_loop" );
}
}

train_stop_sounds( max )
{
self stopLoopSound( "veh_train_eng_dist1_loop" );   
self stopLoopSound( "veh_train_eng_dist2_loop" );   
self stopLoopSound( "veh_train_eng_mid_loop" );     
self stopLoopSound( "veh_train_eng_close1_loop" );  
self stopLoopSound( "veh_train_eng_close2_loop" );  

count = 0;
for ( i = 0; i < self.cars.size; i++ )
{
	count++;
	if ( count < max )
		continue;
	count = 0;

	self.cars[ i ] stopLoopSound( "veh_train_car_dist_loop" );
	self.cars[ i ] stopLoopSound( "veh_train_car_mid_loop" );
	self.cars[ i ] stopLoopSound( "veh_train_car_close_loop" );
}
}

hide_trains()
{
// Hide the train while it warps to position
self hide();
foreach ( wheel in self.wheels )
{
	wheel hide();
}
foreach ( car in self.cars )
{
	car hide();
	foreach ( wheel in car.wheels )
	{
		wheel hide();
	}
}
}

show_trains()
{
// show the train while it warps to position
self show();
foreach ( wheel in self.wheels )
{
	wheel show();
}
foreach ( car in self.cars )
{
	car show();
	foreach ( wheel in car.wheels )
	{
		wheel show();
	}
}
}

train_spawns_dust()
{
if ( !isdefined( level._effect[ "train_dust" ] ) )
	return;

range = 40;
self endon( "train_stops_killing_players" );

for ( ;; )
{
	/*
	for ( i = 0; i < 10; i ++ )
	{
		x = randomfloatrange( self.min_x, self.max_x );
		y = randomfloatrange( self.min_y, self.max_y );
		PlayFX( level._effect[ "train_dust" ], ( x, y, self.origin[ 2 ] - 30 ) );
	}
	*/

	count = randomintrange( 1, 3 ); // which means 1 to 2 fx per frame
	for ( i = 0; i < count; i ++ )
	{
		x = randomfloatrange( self.min_x - range, self.max_x + range );
		y = randomfloatrange( self.min_y - range, self.max_y + range );
		PlayFX( level._effect[ "train_dust_linger" ], ( x, y, self.origin[ 2 ] - 10 ) );
	}
	wait( 0.05 );
}
}

train_kills_players( train_cars, distance_between_cars )
{
// find the extents of the train, presuming it is going straight n/s/e/w and then test vs player origins to see
// if they should be run over
train_width = 68;
self endon( "train_stops_killing_players" );

forward = anglestoforward( self.angles );
right = anglestoright( self.angles );
full_car_vec = forward * distance_between_cars;
half_car_vec = full_car_vec * 0.5;
train_width_vec = right * train_width;

sides = [];
sides[ "front" ] = self.origin + half_car_vec;
sides[ "rear" ] = self.origin + train_cars * full_car_vec * - 1;
sides[ "right" ] = self.origin + train_width_vec;
sides[ "left" ] = self.origin - train_width_vec;
start = self.origin;

max_x = sides[ "front" ][ 0 ];
min_x = sides[ "front" ][ 0 ];
max_y = sides[ "front" ][ 1 ];
min_y = sides[ "front" ][ 1 ];
foreach ( side in sides )
{
	if ( side[ 0 ] > max_x )
		max_x = side[ 0 ];
	if ( side[ 0 ] < min_x )
		min_x = side[ 0 ];
	if ( side[ 1 ] > max_y )
		max_y = side[ 1 ];
	if ( side[ 1 ] < min_y )
		min_y = side[ 1 ];
}

for ( ;; )
{
	dif = start - self.origin;
	start = self.origin;
	max_x -= dif[ 0 ];
	min_x -= dif[ 0 ];
	max_y -= dif[ 1 ];
	min_y -= dif[ 1 ];

	// store it for the dust fx
	self.min_x = min_x;
	self.max_x = max_x;
	self.min_y = min_y;
	self.max_y = max_y;

	//print3d( ( max_x, max_y, self.origin[ 2 ] ), " * " );
	//print3d( ( min_x, max_y, self.origin[ 2 ] ), " * " );
	//print3d( ( max_x, min_y, self.origin[ 2 ] ), " * " );
	//print3d( ( min_x, min_y, self.origin[ 2 ] ), " * " );

	hit_ents = [];

	foreach ( player in level.players )
	{
		if ( !isalive( player ) )
			continue;
		if ( player.sessionstate != "playing" )
			continue;
		if ( !train_hits( player, min_x, min_y, max_x, max_y ) )
			continue;

		player playsound( "melee_knife_hit_watermelon" );

		pos = get_damageable_player_pos( player );
		hit_ents[ hit_ents.size ] = get_damageable_player( player, pos );
	}

	grenades = getentarray( "grenade", "classname" );
	foreach ( grenade in grenades )
	{
		if ( !train_hits( grenade, min_x, min_y, max_x, max_y ) )
			continue;

		pos = get_damageable_grenade_pos( grenade );
		hit_ents[ hit_ents.size ] = get_damageable_grenade( grenade, pos );
	}

	foreach ( ent in hit_ents )
	{				
		ent.damage = 5000;
		ent.pos = self.origin;
		ent.damageOwner = self;
		ent.eInflictor = self;

		ent maps\mp\gametypes\_weapons::damageEnt(
			ent.eInflictor, // eInflictor = the entity that causes the damage (e.g. a claymore)
			ent.damageOwner, // eAttacker = the player that is attacking
			ent.damage, // iDamage = the amount of damage to do
			"MOD_PROJECTILE_SPLASH", // sMeansOfDeath = string specifying the method of death (e.g. "MOD_PROJECTILE_SPLASH")
			"train_mp", // sWeapon = string specifying the weapon used (e.g. "claymore_mp")
			ent.pos, // damagepos = the position damage is coming from
			vectornormalize(ent.damageCenter - ent.pos) // damagedir = the direction damage is moving in
		);			
	}

	wait( 0.05 );
}
}

train_hits( entity, min_x, min_y, max_x, max_y )
{
if ( entity.origin[ 2 ] < self.origin[ 2 ] - 5 )
	return false;

if ( entity.origin[ 2 ] > self.origin[ 2 ] + 162 )
	return false;

x = entity.origin[ 0 ];
y = entity.origin[ 1 ];
if ( x < min_x )
	return false;
if ( y < min_y )
	return false;
if ( x > max_x )
	return false;
if ( y > max_y )
	return false;
return true;
}


train_eq( origin, eq_radius, track_time, full_train_time )
{
train_eq_lerp_for_time( origin, 0.0, 0.09, eq_radius, track_time, 0.5 );
train_eq_for_time( origin, 0.17, eq_radius, full_train_time, 0.5 );
train_eq_lerp_for_time( origin, 0.09, 0, eq_radius, track_time, 0.5 );
//level notify( "stop_train_debug" + origin );
}

train_eq_for_time( origin, eq, eq_radius, eq_time, eq_time_slice )
{
// earthquake makes the quake taper off over time so we
// are going to do a lot of earthquakes to simulate a steady quake
//thread print3d_eq( origin, eq );
steps = int( eq_time / eq_time_slice );
for ( i = 0; i < steps; i++ )
{
	Earthquake( eq, eq_time_slice * 3, origin, eq_radius );
	wait( eq_time_slice );
}
remainder = eq_time - steps * eq_time_slice;
if ( remainder > 0 )
{
	wait( remainder );
}
}

train_eq_lerp_for_time( origin, eq1, eq2, eq_radius, eq_time, eq_time_slice )
{
// earthquake makes the quake taper off over time so we
// are going to do a lot of earthquakes to simulate a steady quake
//thread print3d_eq( origin, eq );
steps = int( eq_time / eq_time_slice );
for ( i = 0; i < steps; i++ )
{
	progress = i / steps;
	eq = eq2 * progress + eq1 * ( 1 - progress );
	if ( eq > 0 )
		Earthquake( eq, eq_time_slice * 3, origin, eq_radius );
	wait( eq_time_slice );
}
remainder = eq_time - steps * eq_time_slice;
if ( remainder > 0 )
{
	wait( remainder );
}
}

print3d_eq( origin, msg )
{
level notify( "stop_train_debug" + origin );
level endon( "stop_train_debug" + origin );
for ( ;; )
{
	Print3d( origin, msg );
	wait( 0.05 );
}
}

I was also curious about it... :P Would be pretty cool for zombies. Like, to buy a ticket to get away for some time. :P

Опубликовано:

Well, maybe someone could do with this idea and "make" a train.

I made a rough 'image' of what I'm thinking maybe someone could do. Although I couldn't get the model to spawn in the right spot, (I was using the Forge mod) its a little higher than I wanted it to be.

Make it where the front of the trucks are inside of the tarp (not really sure what else to call it), and so you'd just see one front part of the truck and then tarps for the rest.

 

Hopefully you'll get what I mean.

 

cc9d27ecad1eafba3449c24f45c1d754.png

Опубликовано:
JoeyB":2nc6u6o5]Well, maybe someone could do with this idea and "make" a train.

I made a rough 'image' of what I'm thinking maybe someone could do. Although I couldn't get the model to spawn in the right spot, (I was using the Forge mod) its a little higher than I wanted it to be.

Make it where the front of the trucks are inside of the tarp (not really sure what else to call it), and so you'd just see one front part of the truck and then tarps for the rest.

 

Hopefully you'll get what I mean.

 

cc9d27ecad1eafba3449c24f45c1d754.png

lol. I see you are liking momos mod. :P

Опубликовано:
JoeyB":2ew842zi]Well, maybe someone could do with this idea and "make" a train.

I made a rough 'image' of what I'm thinking maybe someone could do. Although I couldn't get the model to spawn in the right spot, (I was using the Forge mod) its a little higher than I wanted it to be.

Make it where the front of the trucks are inside of the tarp (not really sure what else to call it), and so you'd just see one front part of the truck and then tarps for the rest.

 

Hopefully you'll get what I mean.

 

cc9d27ecad1eafba3449c24f45c1d754.png

lol. I see you are liking momos mod. :P

I was going to photoshop a picture then I was like... hmm I can try this, it'd be faster lol.

Опубликовано:
Doesn't work, trust me.

 

The model and weapon isn't in-game.

Wait, what? You crashed our party...

 

Well, there really is a train_mp in the zone. At offset 54E10CB, but there is no the_l_train entity. Maybe if someone creates this entity, dumps (if necessary and possible) the train_mp and calls the train function somewhere, it might work, but I'm only supposing, I don't say that it works and I don't even think so, as the train_mp looks very incomplete (like rendy said, there is no model), but we never know :)

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Гость
Ответить в тему...

Сейчас на странице 0

  • Нет пользователей, просматривающих эту страницу

Важная информация

Используя этот сайт, вы соглашаетесь Условия использования.

Account

Navigation

Поиск

Поиск

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.