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 :-)