breakable glass

Discuss programming in the QuakeC language.
Post Reply
sniperz227
Posts: 112
Joined: Sat Apr 09, 2011 3:19 am

breakable glass

Post by sniperz227 »

hey sniperz 227 here i was trying to code in breakable glass but everytime i shoot the glass it does not play the animation it just sheds blood wtf?:P i made an entity called glass to represent the glass
here's my code

Code: Select all


void() item_bglass =
{

	glass.weaponframe = 0;
	precache_model (self.model);
	setmodel(self,self.model);	//precache model so it loads

	glass.health = 20; // give it health
	glass.takedamage = DAMAGE_AIM; // yes it can take damage
	glass.solid = SOLID_BBOX; // za box
	glass.movetype = MOVETYPE_NONE; // doesnt move
	if(glass.health == 0) // if statement to play breaking glass animation if glass is shot at and has no more health
	{
	glass_break_1();
	}
	if(glass.weaponframe == 7) // in animation the weapon frame is set to 7 so if the animations done then remove model
	{remove(self);};
	
}
silverjoel
Posts: 52
Joined: Thu Sep 30, 2010 6:46 am

Re: breakable glass

Post by silverjoel »

Try changing
glass.health == 0
to
glass.health <= 0
sniperz227
Posts: 112
Joined: Sat Apr 09, 2011 3:19 am

Re: breakable glass

Post by sniperz227 »

noep didn't work :(
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: breakable glass

Post by frag.machine »

item_bglass () is the entity constructor function - in other words, it's called only once when an item_bglass entity is created.

To verify what I am saying, add this simple line to the top of your function:

Code: Select all

bprint ("Hello from item_bglass()!\n");
Compile, and run your test map. You'll see the message appear once right after the map initialization, and not anymore.
Try shooting/breaking the glass. No messages, meaning this code is not executed when the entity receives damage.

What you want is to make something happen when the entity receives damage. And already there is an entity that works this way: the exploding boxes.

So, my advice is: read the code from the misc_explobox, and learn how things work on it. It's close enough to turn into breakable glass.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Nahuel
Posts: 495
Joined: Wed Jan 12, 2011 8:42 pm
Location: mar del plata

Re: breakable glass

Post by Nahuel »

first, is a very confused and strange code,
second, try with this

Code: Select all

void() glass_die =
 {
if  ( self.frame < 7)
{
self.frame = self.frame +1;
self.think = glass_die;
self.nextthink = time + 0.07;
}
else
{
self.think = remove(self);
self.nextthink = time ;
}
;}

void() item_bglass =
{

   precache_model (self.model);
   setmodel(self,self.model);   //precache model so it loads
   self.health = 20; // give it health
   self.takedamage = DAMAGE_YES; // yes it can take damage
   self.solid = SOLID_BBOX; // za box
   self.movetype = MOVETYPE_NONE; // doesnt move
  self.th_die = glass_die;    
};
hi, I am nahuel, I love quake and qc.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: breakable glass

Post by Baker »

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"
}
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Post Reply