Page 1 of 1

Execute a custom FX on objective

Posted: Fri Sep 09, 2005 8:00 pm
by mcunha98
I have a curiousity.
How i put a additional fx (like a explosion or something like this) for a objective when it explode ?

Posted: Thu Nov 24, 2005 8:13 pm
by @(...:.:...)@
Hi :-)

I would make a custom dm_obj.scr (the bomb controller script) for your bomb. Then in the section of the script that spawns an explosion, just spawn another one of a differnt kind. Eg, this is a scripted aa gun to blow up from a sp conversion I made a while ago.

Some things have been given models and +dontdraw. That was for my testing, before I added dontdraw ;)

In your maps script under prespawn:

Code: Select all

	exec global/t1l3/obj_bomb.scr
	thread aa_gun_obj
Then in the maps script the aa_gun_obj thread:

Code: Select all

aa_gun_obj:

	//spawn our aa gun...

	//don't realy wan't a working aa gun, incase people camp on it :p
	//	spawn statweapons/P_aagun_base.tik "targetname" "aa1" "classname" "turretweapon_player_aagun"
	//	$aa1.origin = ( 2951 -2345 200 )
	//	$aa1.angles = (0 -77 0)
	
	//	spawn statweapons/P_aagun_cannon.tik "targetname" "aa1g" "classname" "ProjectileGenerator_gun"
	//	$aa1g.origin = ( 2951 -2345 200 ) + ( 0 0 222 )
	//	$aa1g.angles = (0 -77 100)
	//	$aa1g nodamage
	//	$aa1 nodamage

	//static aa gun (can't use it)

	local.aagun = spawn script_model "targetname" "aagun_base"
	local.aagun model "statweapons/P_aagun_base.tik"
	local.aagun.origin = ( 2951 -2345 118 )
	local.aagun.angles = ( 0 135 0 )
	local.aagun.scale = 1
	local.aagun solid

	local.aagun = spawn script_model "targetname" "aagun_gun"
	local.aagun model "statweapons/P_aagun_cannon.tik"
	local.aagun.origin = ( 2951 -2345 132 ) //+ ( 0 0 222 )
	local.aagun.angles = ( 0 135 0 )
	local.aagun.scale = 1
	local.aagun solid

//aa gun for camera to watch
	local.aagun = spawn script_model "targetname" "aagun_gun_w"
	local.aagun model "statweapons/P_aagun_cannon.tik"
	local.aagun.origin = ( 2951 -2345 132 ) //+ ( 0 0 222 )
	local.aagun.angles = ( 0 135 0 )
	local.aagun.scale = 1
	local.aagun notsolid
	$aagun_gun_w rendereffects "+dontdraw"

end
Finaly, the custom obj_dm.scr which in this case is global/t1l3/obj_bomb.scr (t1l3 was the name of the sp map)

Note, I also scripted a cinematic ending. When the bomb would normal blow up, the defusing is disabled, and all players screens fade to black. A camera is then activated for all players, and it moves allong a railway track, looking at the AA Gun. When the camera gets close to the gun, the AA gun blows up and the camera continues moving away down the track, and fades out while looking at the blown up gun.

I had to use a small 'hack' for the camera, as it just wouldent do what I wanted. I have a loop changing its origin to the origin of a moving object, and making it look at the aa gun. This is once a frame, or 20x per second which is as fast as movement can be scripted anyway from the server, so the client does not see lag. Also, because the players view is fixed, his fps can drop to 24 or so, and he will not perseve any lag, because he cannot move his view (camera is moved by the script).

At the top I spawn the use trigger for the bomb, the object which moves that the camera is fixed to, and the bomb model. I made some changes throughout the code for things like stopping being able to defuse the bomb once it starts to fade out, and other such things. Look towrds the bottom for the explosion effects.

Code: Select all

main:




	local.wire = spawn script_model "targetname" "tub"
  	local.wire model "static/parachute_actors.tik"
  	local.wire.origin = ( 3150 292 245 ) 
  	local.wire.angles = ( 0 -90 0 )
  	local.wire.scale = 1
  	$tub notsolid
	$tub time 20
	$tub rendereffects "+dontdraw"

	level waittill spawn


	spawn trigger_use "targetname" "allied_bomb_use"
	$allied_bomb_use.origin = ( 2995 -2397 165 )
	$allied_bomb_use setsize ( -100 -100 -100 ) ( 100 100 100 )

	spawn script_model "model" "animate/pulse_radiobomb.tik" "targetname" "allied_base_bomb" 
	$allied_base_bomb.origin = ( 2995 -2397 165 )
	$allied_base_bomb.angles = ( 0 90 0 )
	$allied_base_bomb.trigger_name = allied_bomb_use
	$allied_base_bomb.target = $aagun_gun
	$allied_base_bomb.explosion_fx = animate/fx_explosion_tank.tik  
	$allied_base_bomb.explosion_sound = explode_tank



	$allied_base_bomb thread bomb_thinker

end



//***********************************************
// initialization thread... 
//***********************************************

bomb_thinker:
	// Steve says planting time = 6 seconds
	// defusing time = 12 second
	// tick time = 36 seconds

	level.bomb_defuse_time = 60 //tenths of a second
	level.bomb_set_time = 50  //tenths of a second
	level.bomb_tick_time = 60  //seconds (was 60 seconds, then 30 seconds)
	level.bomb_tick_timex = 45  //seconds (was 60 seconds, then 30 seconds)
//	level.wait_after_explode = 2  //seconds time after target is destroyed before the level ends (no longer used, done in code now)
	level.bomb_explosion_radius = 250  //quake units
	level.bomb_use_distance = 128 //quake units
	level.bomb_damage = 200
	level.bombusefov = 30

	level.subtitleX = 100
	level.subtitleY = 50

	if (0) {
		dprintln "----------------------Z-----------------------"
		dprintln "self = " self
		if (self.target != NIL && self.target != NULL && self.target != "")
		{
			dprintln "self.target (flak 88 or other) = " self.target
			dprintln "self.target.destroyed_model = " self.target.destroyed_model
			dprintln "self.target.target (collision entity) = " self.target.target
		}
		dprintln "self.trigger_name = " self.trigger_name
		dprintln "self.exploder_set = " self.exploder_set
		dprintln "self.explosion_fx = " self.explosion_fx
		dprintln "self.explosion_sound = " self.explosion_sound
		dprintln "self.killarea = " self.killarea
		dprintln "----------------------Z-----------------------"
	}
	
	if (self.target != NIL && self.target != NULL && self.target != "")
	{
		self.target.collisionent = self.target.target
		self.target notsolid
	}
	thread bomb_waittill_set
end

//***********************************************
// first thread... controls allies using the trigger
//***********************************************


bomb_waittill_set:

	self model animate/pulse_radiobomb.tik

	while ( $(self.trigger_name) )
	{
		//println "waittill trigger " self.trigger_name 
		self.trigger_name waittill trigger

		local.player = parm.other
		//"local.player.dmteam", can be 'spectator', 'freeforall', 'allies' or 'axis'
	        if (local.player.dmteam != allies) 
		{
			local.player iprint ( loc_convert_string "You're on the wrong team to set this bomb!" )
			goto bomb_waittill_set
		}
	
		local.counter = 0
		local.tickIndex = 0 //for the sounds

		while ( (Isalive local.player) && (local.player cansee $allied_base_bomb 180 65) && (local.player.useheld == 1) )
//		while ( (Isalive local.player) && (local.player.useheld == 1) )
		{
			if (local.counter == 0)
				local.player stopwatch (level.bomb_set_time * .1)
			
			local.counter++

			if( (local.counter % 10) == 0 )
			{
				switch( local.tickIndex )
				{
				case 0:
					self playsound bomb_prime1
					break;
				case 1:
					self playsound bomb_prime2
					break;
				case 2:
					self playsound bomb_prime3
					break;
				case 3:
					self playsound bomb_prime4
					break;
				case 4:
					self playsound bomb_prime5
					break;
				case 5:
					self playsound bomb_prime6
					break;
				}

				local.tickIndex++
			}

			//if ((local.counter % 5) == 0)
			//	locprint level.subtitleX level.subtitleY("set "+ local.counter)

			wait .1
			if (local.counter >= level.bomb_set_time)
			{
				if( self.bombName != NIL && self.bombName != NULL )
				{
					iprintlnbold ( loc_convert_string ( "A Bomb has been planted on the Flakvierling 38!" ) )
				}
				else
				{
					iprintlnbold ( loc_convert_string ( "A Bomb has been planted on the Flakvierling 38!" ) )
				}
			
				if (level.planting_team == "allies")
					self playsound dfr_objective_o
				else
					self playsound den_objective_o
				self thread bomb_waittill_defuse
				self thread bomb_waittill_explode
				self.live = 1
				level.bombs_planted ++
				end
			}
		}
		if (local.counter > 0)
			local.player stopwatch 0

	}
end


//***********************************************
// second thread... controls axis using the trigger
//***********************************************
bomb_waittill_defuse:
	while ( $(self.trigger_name) )
	{
		self.trigger_name waittill trigger

		local.player = parm.other
	
		//"local.player.dmteam", can be 'spectator', 'freeforall', 'allies' or 'axis'
		if (local.player.dmteam != axis)
		{      
			local.player iprint ( loc_convert_string "You're on the wrong team to defuse this bomb!" )
			goto bomb_waittill_defuse
		}
	
		local.counter = 0
		while ( (Isalive local.player) && (local.player cansee $allied_base_bomb 180 65) && (local.player.useheld == 1) && (level.nomoredefuse != 1 ) )
	//	while ( (Isalive local.player) && (local.player.useheld == 1) )
		{
			if (local.counter == 0)
				local.player stopwatch (level.bomb_defuse_time * .1)
			
			local.counter++
			//if ((local.counter % 5) == 0)
			//	locprint level.subtitleX level.subtitleY ("defuse "+local.counter)

			wait .1
			if (local.counter >= level.bomb_defuse_time)
			{
				if( self.bombName != NIL && self.bombName != NULL )
				{
					iprintlnbold ( loc_convert_string ( "The Flakvierling 38 bomb has been defused!" ) )
				}
				else
				{
					iprintlnbold ( loc_convert_string ( "The Flakvierling 38 bomb has been defused!" ) )
				}
				
				if (level.defusing_team == "allies")
					self playsound dfr_diffused_d
				else
					self playsound den_diffused_d
				
				thread bomb_waittill_set //start first thread again
				self.live = 0
				level.bombs_planted --
				end
			}
		}
		if (local.counter > 0)
			local.player stopwatch 0
	}
end


//***********************************************
// third thread... times the bomb and makes it explode at the right time
//***********************************************
bomb_waittill_explode:

	self model animate/radiobomb.tik
//	self playsound plantbomb
	self playsound radiobomb


	self loopsound bombtick
	
	local.start_time = level.time
	while (level.time < (local.start_time + level.bomb_tick_timex) )
	{
		wait .1
		if (self.live != 1)
		{
			self stoploopsound
			end
		}
		if (level.time == (local.start_time + level.bomb_tick_timex - 10) )
		{
			self stoploopsound
			self loopsound final_countdown
		}
 	}

	//stop the bomb being defused...
	level.nomoredefuse = 1

 //	self stoploopsound
	thread allied_win_camera
end


//***********************************************
// fourth thread... controls the explosion 
//***********************************************
bomb_explode:
self stoploopsound
	self.trigger_name remove

	thread jitter_large 0
	
//	if (self.exploder_set != NIL)
		exec global/exploder.scr::explode self.exploder_set
	
//	if (self.explosion_fx != NIL)
//	{
//		self thread spawn_fx self.explosion_fx
//	}
	
	if (self.explosion_sound != NIL)
		self playsound self.explosion_sound

	if (self.target != NIL && self.target != NULL && self.target != "")
	{
		if (self.target.destroyed_model != NIL)
		{
			local.damaged = self.target thread spawn_damaged self.target.destroyed_model
		}
		self.target remove



//spawn explosion
	local.aagun_fx0 = spawn script_model "targetname" "aagun_gun_fx0"
	local.aagun_fx0 model "fx/fx_truck_explosion.tik"
	local.aagun_fx0.origin = ( 2951 -2345 132 ) //+ ( 0 0 222 )
	local.aagun_fx0.angles = ( 0 135 0 )
	local.aagun_fx0.scale = 1

//spawn first flame fx
	local.aagun_fx1 = spawn script_model "targetname" "aagun_gun_fx1"
	local.aagun_fx1 model "emitters/explosion_conflagration.tik"
	local.aagun_fx1.origin = ( 2951 -2345 132 ) //+ ( 0 0 222 )
	local.aagun_fx1.angles = ( 0 135 0 )
	local.aagun_fx1.scale = 1
	//local.aagun_fx1 solid


//spawn some more fire fx (lag2win) but it doesnt realy matter, as the clients will watch it through a camera, so they wont notice (unless there pc realy sucks x_x).
	local.aagun_fx2 = spawn script_model "targetname" "aagun_gun_fx2"
	local.aagun_fx2 model "fx/sustainedFire.tik"
	local.aagun_fx2.origin = ( 2951 -2345 132 ) //+ ( 0 0 222 )
	local.aagun_fx2.angles = ( 0 135 0 )
	local.aagun_fx2.scale = 1
	//local.aagun_fx2 solid

//spawn broken aa gun
	local.aagun_d = spawn script_model "targetname" "aagun_gun_d"
	local.aagun_d model "statweapons/P_aagun_d.tik"
	local.aagun_d.origin = ( 2951 -2345 132 ) //+ ( 0 0 222 )
	local.aagun_d.angles = ( 0 135 0 )
	local.aagun_d.scale = 1
	local.aagun_d solid

thread earthquake



		waitframe
	}

	//See if the bomb has it's own explions_radius set
	if( self.explosion_radius != NIL && self.explosion_radius != NULL )
	{
		radiusdamage self.origin level.bomb_damage self.explosion_radius
	}
	else
	{
		radiusdamage self.origin level.bomb_damage level.bomb_explosion_radius
	}
	
	if (self.killarea != NIL)
	{
		self.killarea volumedamage 1000
	}
	self hide

	self.live = 0
	
	self.exploded = 1
	level.targets_destroyed = level.targets_destroyed + 1

	if( self.objCvar != NIL && self.objCvar != NULL )
	{
		setcvar self.objCvar ""
	}



	// we delay the decrementing of	level.bombs_planted so that the script has
	// time to determin the winner before the timelimit gets checked and hit
	wait 0.5
	level.bombs_planted --


end

earthquake:
	waitexec global/earthquake.scr .35 10 0 0
	waitexec global/earthquake.scr .23 6 0 0
	waitexec global/earthquake.scr 1 1 0 0
	waitexec global/earthquake.scr 1.25 .3 0 1
	$aagun_gun_fx0 remove


end

allied_win_camera:
	fadeout 3.5 0 0 0 1
	wait 3.8

	local.camera = spawn func_camera origin ( 3150 292 245 ) angles ( 0 0 0 ) "targetname" "watch_camera"
	local.camera watch $aagun_gun_w
	local.camera cut
	cuecamera local.camera
	$watch_camera fov 80 2

	drawhud 0 // clear the screen
      letterbox 0.5
	//reset the clock for the movie

	level.dmroundlimit = (level.dmroundlimit + 1)

	$player nodamage
	$player hide
	freezeplayer
	wait 1
	fadein 3.5 0 0 0 1

thread cam_move
thread tub_move

//play some winning music or something

wait 3.5
thread bomb_explode
wait 7
	fadeout 5 0 0 0 1
	wait 5
	teamwin allies

end

tub_move:
while (1)
{

wait 1

$tub movesouth 6000
$tub waitmove
end
}

end

cam_move:

while(1)
{
$watch_camera movetopos $tub
waitframe
}

end
Bye :-)