if admins could make a tutorial out of this post, it would appreciated. (if I could do this myself, I would. I don't know how) if you could correct the typos as well .... lol
---------------------
first off, let me thank all the folks here at modsonline.com that helped develop this script, especially sentchy. you're help was really appreciated.
secondly, I absolutly have no clue how this has been done in the past, nor how IW did it for SP. this idea spawned from my balding head.
HOW DOES IT WORK ?
when a player "injures" the barrel, it accumulates the damage taken. if the damage is higher than 80, the barrel catch fire and start to injure itself. when the damage reaches 200, either by itself, more shooting by players or by other barrels exploding near it, it'll first make a sound signaling imminent explosion, and then explode injuring every player, and other barrels, near it. after a waiting period of 2 minutes, the barrel will respawn.
if any of this doesn't exactly suits your need, feel free to modify the code.
RADIANT WORK
- start a new .map, this will become the barrel prefab, so save accordingly in the map_source/prefabs folder.
- make a script_model with the xmodel of any barrel you wish to use.
do not give it a targetname.
- make a trigger_damage that surrounds the barrel closely. tick the box "MELEE_NO" so it doesn't work by bashing the barrel (obviously). enter the following value :
"targetname" "barrel_trig"
-
select the trigger first then the barrel. press 'w' (to merge entities). if you've done it correctly, the barrel will have "auto1" has a targetname and the trigger will have "auto1" has a target. you will also see a red line in 3d window indicating that the targetting works correctly.
- make a script_brushmodel out of a clip brush that surrounds the barrel (same size of the trigger) and an origin brush that has its origin coincide with the origin of the script_model (the blue box at the bottow). this is to prevent player to walk thought the barrel. similarly to the trigger, enter the following value :
"targetname" "barrel_clip"
-
exactly like the trigger select the brushmodel first (alt+shift) and then the barrel. press 'w'. the brushmodel now targets the barrel just like the trigger does.
-
save that .map. whenever you want a barrel in your map, insert this prefab in. (r-click 2d window - misc/prefab)
and that's it for radiant. copy as many barrel prefabs as you wish. try putting them close to each other for cool effects.
OTHER NOTES
script_model creation :
right-click 2d window. script/model, enter the xmodel wanted and locate it where wanted
trigger_damage creation :
right-click 2d window. trigger/damage and give it the dimensions wanted (like any normal brush) and locate it where wanted
script_brushmodel creation :
create the brushes you want for this entity. every script_brushmodel needs an origin brush, find that texture in the tools submenu. selection all brushes, including the origin one. right-click 2d window. script/brushmodel. locate it where wanted. shift+alt+left-click to selection the whole entity. shift+left-click to selection only one brush of the entity.
adding values to entities:
simply press 'n' when you have the entity selected.
SCRIPTING
I've made it easy for you guys.
create a new text folder called barrels.gsc and put it in maps/mp. put the following code in it :
Quote:
barrelInit()
{
level._effect["barrel_fire"] = loadfx ("fx/fire/tank_fire_engine.efx");
level._effect["barrel_explosion"] = loadfx("fx/explosions/ammo_supply_exp.efx");
precacheModel("xmodel/prop_barrel_black");
barrel_trig = getentarray("barrel_trig", "targetname");
barrel_clip = getentarray("barrel_clip", "targetname");
//grab corresponding entities
for( k = 0 ; k < barrel_trig.size ; k++ ) {
barrel1 = getent(barrel_trig[k].target, "targetname");
barrel1.trig = barrel_trig[k];
level.barrels[k] = barrel1;
}
for( k = 0 ; k < barrel_clip.size ; k++ ) {
barrel2 = getent(barrel_clip[k].target, "targetname");
barrel2.clip = barrel_clip[k];
}
//records the name and state, then launch a thread for each barrel
for( k = 0 ; k < level.barrels.size ; k++ ) {
level.barrels[k].name = "barrel ^" + k + "#" + k;
level.barrels[k].exploded = false;
level.barrels[k].soundOrigin = spawn("script_origin", level.barrels[k].origin);
level.barrels[k] thread barrelThink();
}
}
barrelThink()
{
if (self.exploded == true)
wait(120);
self entityOn();
self.trig entityOn();
self.clip entityOn();
self.accDamage = 0;
self.onfire = false;
self.exploded = false;
while(isdefined (self))
{
self.trig waittill("damage", amount);
self.accDamage = self.accDamage + amount;
//iprintlnbold(self.name + " 's damage = " + self.accDamage);
if (self.exploded != true)
{
if (self.accDamage > 80 && self.onfire != true) //catch fire
{
self.onfire = true;
self thread barrelFire(); //fire start
self thread barrelFireDamage(); //self injury start
}
if (self.accDamage > 80 && self.onfire == true)
{
//nothing
}
if (self.accDamage > 200) //explosion
{
self.onfire = false;
self.exploded = true;
self.soundOrigin playsound("barrel_explosion_imminent");
wait(4); //lenght of sound file
self thread barrelExplode();
self.trig entityOff();
self.clip entityOff();
self entityOff();
self barrelThink();
break;
}
} else //(self.exploded == true)
break;
}
}
//injures itself until exploded. only one thread per barrel
barrelFireDamage()
{
while (self.exploded != true)
{
self.trig notify ("damage", 10);
wait(randomint(2)+1);
}
}
//play the fx. only one thread of it should exist per barrel
barrelFire()
{
while(self.exploded != true) //keeps playing the effect until exploded
{
self.soundOrigin playsound("barrel_fire");
playfx(level._effect["barrel_fire"], self.origin + (0,0,32));
radiusDamage(self.origin + (0,0,12), 75, 10, 0);
wait(2);
}
}
barrelExplode()
{
//inflict damage to adjacent barrels, linearly wrt distance
for (k = 0; k < level.barrels.size; k++)
{
if ( level.barrels[k].exploded != true && level.barrels[k] != self)
{
dist = distance(level.barrels[k].origin, self.origin);
if (dist < 100 && dist != 0)
level.barrels[k].trig notify("damage", ((1-(dist/100))*100)+100); // between 100 and 200 of damage
}
}
self.soundOrigin playsound("barrel_explosion");
playfx(level._effect["barrel_explosion"], self.origin);
//give lots of damage around self
radiusDamage(self.origin + (0,0,12), 400, 200, 30);
//self.trig notify ("damage", 5); //final blow
}
//barrel spawning functions. it just moves them away and back.
entityOff()
{
if (!isdefined (self.realOrigin))
self.realOrigin = self.origin;
if (self.origin == self.realorigin)
self.origin += (0, 0, -10000);
}
entityOn()
{
if (isDefined (self.realOrigin) )
self.origin = self.realOrigin;
}
now you need to kick this thread off by adding the following line to your mp_mapname.gsc :
Code:
maps\mp\barrels::barrelInit();
at the location specified below :
Code:
main()
{
maps\mp\mp_mapname_fx::main(); //if you have one
maps\mp\barrels::barrelInit();
maps\mp\_load::main();
//...
}
finally you need to add the lines to the soundaliases files in order for the sound to work (find more about the soundalias file
Here) :
barrel_explosion,,explosions/exp_armoredcar.wav,0.8,1,,,,50,1000,local,streamed,,,,mp_valley,,,,,,,,
barrel_explosion_imminent,,misc/metal_stress01.wav,0.6,1,,,,50,500,local,streamed,,,,mp_valley,,,,,,,,
barrel_fire,,fire/Fire_Sm_loop01.wav,0.01,1,,,,50,400,auto,streamed,,,,mp_valley,,,,,,,,
and that's it !! enjoy. feel free to ask me any questions you might have in the forums. also go in the forums to know how to change specific stuff, like respawing time.
-|HR|-.FlesyM.
edited on Aug. 6, 2006 08:58 pm by veef