Borrow func_glass from Kurok ...
http://bladebattles.com/kurok/files/KurokQC.zip
misc.qc ... well in the QuakeC source Mdave has them all labelled .c so he could use Dev-C++ to edit QuakeC ... so see misc.c
Code: Select all
//============================================================================
//##########################################
//#### GLASS ####
//##########################################
// glass spawnflag constants
float GLASS_SMOOTH = 1;
float GLASS_BLOCKABLE = 2;
float GLASS_STARTOFF = 4;
float GLASS_ONEHIT = 8;
.float color;
void () blocker_use =
{
if ( !self.state )
{
self.state = 1;
setorigin( self, self.origin - '8000 8000 8000' );
sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
}
else
{
self.state = 0;
setorigin( self, self.origin + '8000 8000 8000' );
sound(self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
}
};
void(entity attacker, float damage) glass_pain =
{
sound (self, CHAN_VOICE, "weapons/ghit.wav", 1, ATTN_NORM);
// check if one hit is required to break it
if(self.spawnflags & GLASS_ONEHIT)
self.health = self.max_health;
};
void() glass_die=
{
local entity new;
local vector tmpvec;
local vector tmpmin, tmpmax, tmpsize;
while(self.color > 0)
{
new = spawn();
new.origin = self.origin;
if(random() < 0.33)
setmodel (new, "progs/glass3.mdl" );
else if(random() < 0.5)
setmodel (new, "progs/glass2.mdl" );
else
setmodel (new, "progs/glass1.mdl" );
setsize (new, '0 0 0', '0 0 0');
new.velocity_x = 70 * crandom();
new.velocity_y = 70 * crandom();
new.velocity_z = 140 + 70 * random();
new.movetype = MOVETYPE_BOUNCE;
new.solid = SOLID_BBOX;
new.avelocity_x = random()*600;
new.avelocity_y = random()*600;
new.avelocity_z = random()*600;
new.nextthink = time + 2 + random()*3;
new.think = SUB_Remove;
self.absmin = self.origin + self.mins;
self.absmax = self.origin + self.maxs;
tmpvec_x = self.absmin_x + (random() * (self.absmax_x - self.absmin_x));
tmpvec_y = self.absmin_y + (random() * (self.absmax_y - self.absmin_y));
tmpvec_z = self.absmin_z + (random() * (self.absmax_z - self.absmin_z));
setorigin(new, tmpvec);
self.color = self.color - 1;
}
if(self.noise2)
sound (self , CHAN_VOICE, self.noise2, 1, ATTN_NORM);
// if(self.event)
// SUB_UseName(self.event);
remove(self);
};
void() func_glass=
{
local vector tmpvec;
local float tmpflt;
/*
local entity glass;
glass = spawn();
glass.origin = self.origin;
glass.movetype = MOVETYPE_NONE;
glass.solid = SOLID_NOT;
glass.mdl = self.model;
setmodel (glass, self.model);
setsize (glass, self.mins, self.maxs);
setorigin (glass, self.origin);
makestatic (glass);
*/
self.movetype = MOVETYPE_PUSH;
self.solid = SOLID_BSP;
self.mdl = self.model;
setmodel (self, self.model);
setsize (self, self.mins, self.maxs);
setorigin (self, self.origin);
// self.model = string_null;
precache_sound ("misc/null.wav");
// setup stuff for the glass being broken
if(self.health > 0)
{
if(!self.color)
{
tmpvec = self.maxs - self.mins;
tmpvec = tmpvec * 0.031; //(divide by about 32)
if(tmpvec_x < 1)
tmpvec_x = 1;
if(tmpvec_y < 1)
tmpvec_y = 1;
if(tmpvec_z < 1)
tmpvec_z = 1;
self.color = tmpvec_x * tmpvec_y * tmpvec_z;
}
else if(self.color == -1)
self.color = 0;
if(self.color > 16) // max number of chunks
self.color = 16;
self.takedamage = DAMAGE_YES;
self.max_health = self.health;
self.th_die = glass_die;
self.th_pain = glass_pain;
precache_model( "progs/glass1.mdl" );
precache_model( "progs/glass2.mdl" );
precache_model( "progs/glass3.mdl" );
}
// setup as either moving or togglable
if(self.target) // move like a train
{
if (!self.speed)
self.speed = 100;
if (!self.dmg)
self.dmg = 2;
if (self.sounds == 1)
{
if(!self.noise)
self.noise = ("plats/train2.wav");
if(!self.noise1)
self.noise1 = ("plats/train1.wav");
precache_sound( self.noise );
precache_sound( self.noise1 );
}
self.cnt = 1;
self.blocked = train_blocked;
self.use = train_use;
/*
if(self.spawnflags & GLASS_SMOOTH)
{
self.classname = "smtrain";
self.think = func_smtrain_setup;
}
else
{ */
self.classname = "train";
self.think = func_train_find;
// }
self.nextthink = self.ltime + 0.6;
}
else // move like a togglable wall
{
self.use = blocker_use;
if ( self.spawnflags & GLASS_STARTOFF )
{
self.state = 0;
setorigin( self, self.origin + '8000 8000 8000' );
}
else
{
self.state = 1;
if(self.noise1)
sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
}
}
if ( !self.noise ) // move sound
self.noise = ("misc/null.wav");
if ( !self.noise1 ) // stop sound
self.noise1 = ("misc/null.wav");
if ( !self.noise2 ) // break sound
self.noise2 = ("misc/shatter.wav");
precache_sound( self.noise );
precache_sound( self.noise1 );
precache_sound( self.noise2 );
};
The Worldcraft entity defintion file provides some insight into the fields ...
@SolidClass base(Targetname) = func_glass : "Glass"
[
alpha(string) : "Transparency (0.1 - 1.0)"
spawnflags(flags) =
[
1: "Smooth Movement" : 0
2: "Blockable Smooth" : 0
4: "Start Off" : 0
8: "One Hit" : 0
]
sounds(choices) : "Sound" : 1 =
[
0: "None"
1: "Ratchet Metal"
]
health(integer) : "Health (0 for no break)"
noise(string) : "Stopping/Off Sound"
noise1(string) : "Moving/On Sound"
speed(integer) : "Speed (units per second)" : 64
duration(integer) : "Travel Time (0 if using speed)" : 0
target(target_source) : "First stop target"
dmg(integer) : "Damage on crush" : 0
deathtype(string) : "Death Message"
count(integer) : "Number of Clones"
killtarget(string) : "Killtarget"
killtarget2(string) : "Killtarget #2"
]
And a couple of examples of the entity within the entities data in a BSP
{
"classname" "func_glass"
"sounds" "1"
"health" "1"
"speed" "64"
"count" "2"
"model" "*24"
}
{
"classname" "func_glass"
"sounds" "1"
"health" "1"
"speed" "64"
"count" "2"
"model" "*25"
}