Quake [Glass]

Discuss programming in the QuakeC language.
Max_Salivan
Posts: 96
Joined: Thu Dec 15, 2011 1:00 pm

Quake [Glass]

Post by Max_Salivan »

hello all)

how to make glass in quake?

if not difficult, give me instructions please :3
Sorry for my english :)
Nahuel
Posts: 495
Joined: Wed Jan 12, 2011 8:42 pm
Location: mar del plata

Re: Quake [Glass]

Post by Nahuel »

what engine are you using?
hi, I am nahuel, I love quake and qc.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Quake [Glass]

Post by Baker »

For an entity, like a door or lift or monster, add "alpha" "0.4" to it (you can do this in the map editor or in QuakeC).

With FitzQuake 0.85 and similar engines, the effect with take place automatically without QuakeC if using the default protocol 666.

For engines like DarkPlaces, I think you have to add a .alpha field in the QuakeC (defs) AND set the entity alpha like above. Transparency is not a feature of stock Quake, but it is supported in a number of engines.

[If this is what you are referring to ...]
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 ..
Max_Salivan
Posts: 96
Joined: Thu Dec 15, 2011 1:00 pm

Re: Quake [Glass]

Post by Max_Salivan »

Baker wrote:For an entity, like a door or lift or monster, add "alpha" "0.4" to it (you can do this in the map editor or in QuakeC).

With FitzQuake 0.85 and similar engines, the effect with take place automatically without QuakeC if using the default protocol 666.

For engines like DarkPlaces, I think you have to add a .alpha field in the QuakeC (defs) AND set the entity alpha like above. Transparency is not a feature of stock Quake, but it is supported in a number of engines.

[If this is what you are referring to ...]
I will try to do it)
Nahuel wrote:what engine are you using?
PSP Kurok Engine or i can use Pro Quake,but sounds on this engine in 11 khz...(kurok 22khz)
Sorry for my english :)
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Quake [Glass]

Post by Baker »

The above answer doesn't apply to any of the PSP engines.

None of the engines have entity alpha coded into the rendering, so it really can't be done.

(Mostly because about the only mainstream mod to ever use "glass" was Nehahra until somewhat recently.)


A way to maybe fake it in a PSP engine would be to use a texture like with the name starting with *water and then setting r_wateralpha 0.5, since the PSP engines do support water translucency. The texture would need to be a single color, otherwise Quake's water warping would be noticeable. Only 64x64 texture sizes would work for such a texture.
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 ..
Max_Salivan
Posts: 96
Joined: Thu Dec 15, 2011 1:00 pm

Re: Quake [Glass]

Post by Max_Salivan »

Baker wrote:The above answer doesn't apply to any of the PSP engines.

None of the engines have entity alpha coded into the rendering, so it really can't be done.

(Mostly because about the only mainstream mod to ever use "glass" was Nehahra until somewhat recently.)


A way to maybe fake it in a PSP engine would be to use a texture like with the name starting with *water and then setting r_wateralpha 0.5, since the PSP engines do support water translucency. The texture would need to be a single color, otherwise Quake's water warping would be noticeable. Only 64x64 texture sizes would work for such a texture.

oy yes,fake)
but what about this?

Code: Select all

//============================================================================
// Glass
//============================================================================
/* Breakaway walls QuickC program
   By Jim Dose'  9/11/96
	Modified by General WarT
	Modified by MDave
*/

float MULTI_USE = 1;
float INVISIBLE = 2;

void() damagethreshold_killed =
{
	self.health = self.max_health;

	activator = damage_attacker;
	self.takedamage = DAMAGE_NO;
	SUB_UseTargets ();
	self.takedamage = DAMAGE_YES;

	if ( !( self.spawnflags & MULTI_USE ) )
	{
		remove( self );
	}
};

void() damagethreshold_pain =
{
	self.health = self.max_health;
};

/*QUAKED trigger_damagethreshold (0 .5 .8) ? MULTI_USE INVISIBLE
Triggers only when a threshold of damage is exceeded.
When used in conjunction with func_breakawaywall, allows
walls that may be destroyed with a rocket blast.

MULTI_USE tells the trigger to not to remove itself after
being fired.  Allows the trigger to be used multiple times.

INVISIBLE tells the trigger to not be visible.

"health" specifies how much damage must occur before trigger fires.
Default is 60.

*/

void() trigger_damagethreshold =
{
	self.mangle = self.angles;
	self.angles = '0 0 0';

	self.classname = "damagethreshold";
	self.solid = SOLID_BSP;
	self.movetype = MOVETYPE_PUSH;
	setorigin (self, self.origin);
	setmodel (self, self.model);
	setsize (self, self.mins , self.maxs);
	if ( self.spawnflags & INVISIBLE )
	{
      self.model = string_null;
	}

	if (!self.health)
	{
		self.health = 60;
	}
	self.max_health = self.health;
	self.takedamage = DAMAGE_YES;

	self.blocked = SUB_Null;
	self.th_pain = damagethreshold_pain;
	self.th_die  = damagethreshold_killed;
};

// ### Added feature for Custents
// allows the break down of walls using the func_counter and also
// the make the breakawaywalls optionally trigger another entity and/or
// blow up when they are triggered.
void() func_breakawaywall_use =
{
	local float which, index;

	if(self.cnt != 0)
	{
		if(counter_GetCount (other) != self.cnt)
			return;
	}

	// positions it for correct placement of explosion stuff
	self.use = SUB_Null;
	self.movetype = MOVETYPE_NONE;
	self.solid = SOLID_NOT;
	setorigin(self, self.neworigin);

	if (self.spawnflags & 2) // use particles
	{
		WriteByte (MSG_BROADCAST,SVC_TEMPENTITY);
		WriteByte (MSG_BROADCAST,TE_EXPLOSION);
		WriteCoord (MSG_BROADCAST,self.origin_x);
		WriteCoord (MSG_BROADCAST,self.origin_y);
		WriteCoord (MSG_BROADCAST,self.origin_z);
		WriteCoord (MSG_BROADCAST, 1.0); // Red explosion colour
		WriteCoord (MSG_BROADCAST, 0.5); // Green explosion colour
		WriteCoord (MSG_BROADCAST, 0.0); // Blue explosion colour
	}

	if(self.target)
		SUB_UseTargets();

//	allows it to throw rubble when it explodes.
	if(self.count)
	{
		self.cnt = 0;
		rubble_use();
	}

	if (self.spawnflags & 1) // become explosion
	{
//		BecomeBigExplosion();
//		BecomeExplosion();
		sound (self, CHAN_VOICE, "misc/shortexp.wav", 1, ATTN_NORM);
	}
	else
		remove(self);
};
// ###

/*QUAKED func_breakawaywall (0 .5 .8) ?
Special walltype that removes itself when triggered.
*/

void() func_breakawaywall =
{
	self.mangle = self.angles;
	self.angles = '0 0 0';

	self.classname = "breakaway";
	self.solid = SOLID_BSP;
	self.movetype = MOVETYPE_PUSH;
	setorigin (self, self.origin);
	setmodel (self, self.model);
	setsize (self, self.mins , self.maxs);
// ### Added features for Custents
	self.use = func_breakawaywall_use;

	// the origin in the center for explosion stuff
	self.neworigin = (self.absmin + self.absmax)*0.5;


	if (self.spawnflags & 1) // become explosion
		precache_sound ("misc/shortexp.wav");

// allows it to throw rubble when it is triggered.
	if(self.count)
	{
		precache_model ("progs/rubble1.mdl");
		precache_model ("progs/rubble2.mdl");
		precache_model ("progs/rubble3.mdl");
		precache_sound ("zombie/z_hit.wav");
		if(self.skin < 0)
			self.skin = floor(random()*14);
	}
// ###
};

//============================================================================

//##########################################
//#### 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 );
};
Sorry for my english :)
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Quake [Glass]

Post by Baker »

If you just want to be able to break a window (and don't care if it is see-through), that QuakeC you have there will do the trick.
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 ..
Max_Salivan
Posts: 96
Joined: Thu Dec 15, 2011 1:00 pm

Re: Quake [Glass]

Post by Max_Salivan »

Baker wrote:If you just want to be able to break a window (and don't care if it is see-through), that QuakeC you have there will do the trick.
I do not need to break the glass)

i need a glass)

and i dont know how to do it((
Sorry for my english :)
Max_Salivan
Posts: 96
Joined: Thu Dec 15, 2011 1:00 pm

Re: Quake [Glass]

Post by Max_Salivan »

r_wateralpha 0.1 give nice fake glass)
but it is moving:D (waaateer)
Sorry for my english :)
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Quake [Glass]

Post by Baker »

Max_Salivan wrote:r_wateralpha 0.1 give nice fake glass)
but it is moving:D (waaateer)
Knowing you would ask that question, I time travelled to the past and told you how to avoid that a few posts ago :D

But alas, I failed proving once again you can't change the future. For reference, what I think you might have missing was ...
Baker's second post in the thread above wrote:The texture would need to be a single color, otherwise Quake's water warping would be noticeable. Only 64x64 texture sizes would work for such a texture.
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 ..
Blackstar1000
Posts: 52
Joined: Mon Sep 13, 2010 5:16 pm

Re: Quake [Glass]

Post by Blackstar1000 »

Hey guys. I figured out how to do this about a year ago and have since forgot. I'm using Clean QuakeC. And am using the quake modified worldcraft. I did it originally using qc I think.

Could you point me at the exact file that holds these material properties? I remember it being a pain to find the first time?

I guess what I'm asking is to please be more specific. :lol:
Knives out. Catch the mouse. Squash his head. Put him in your mouth.
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Re: Quake [Glass]

Post by r00k »

What Baker is saying is that, in your map editor, create a brush, select it then create a func_wall, func_illusionary, or func_whatever, fromt hat brush, then depending on the editor, (i use BSP), change the parameters for that brush to include
keyword alpha, value 0.5. This will make that entire brush transparent in FitzQuake, (hmm note to self fix this in Qrack). No QuakeC required. I just double checked and in FitzQuake 0.85 it worked.
Nahuel
Posts: 495
Joined: Wed Jan 12, 2011 8:42 pm
Location: mar del plata

Re: Quake [Glass]

Post by Nahuel »

In darkplaces you can get nice effects for glasses with simple shaders :)
http://www.youtube.com/watch?v=EVoWPvh01ds
hi, I am nahuel, I love quake and qc.
Ghost_Fang
Posts: 336
Joined: Thu Nov 12, 2009 4:37 am

Re: Quake [Glass]

Post by Ghost_Fang »

Baker wrote:The above answer doesn't apply to any of the PSP engines.

None of the engines have entity alpha coded into the rendering, so it really can't be done.
I'm almost certain i remember seeing transparent, breakable glass in default Kurok PSP. I'm sure it was done with a combination of engine and QC, but none the less, i think the PSP can do it.
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: Quake [Glass]

Post by frag.machine »

Poor man's fake glass: use a oriented sprite. Will work even in software DOSQuake.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Post Reply