Q2/3 Styled Armor Shards in Q1 mod...

Discuss programming in the QuakeC language.
enki
Posts: 10
Joined: Tue Nov 23, 2010 2:57 am

Q2/3 Styled Armor Shards in Q1 mod...

Post by enki »

I've been wracking my brain over how to get this to work all day, and can't make heads or tails of the proper way of doing it.

I have the model, sound, etc.... that's all well and good, everything is where it belongs. What I'm trying to do is build a function that will allow accumulative armor per shard pickup (with a maximum of 200 or 250, whatever). 10 per shard. I've tried this a multitude of different ways and can't seem to get it working. I'm attempting to keep this separate from the armor in items.qc obviously for ease of use (it has it's own models, sounds etc.). Here is the stripped down version before I started really cranking on it:

Code: Select all

defs.qc:

//for Armor Shards
float	IT_SHARD				= 16777216;


shard.qc

void() shard_touch;

void() shard_touch =
{
	local	float	type, value, bit;
	if (other.health <= 0)
		return;
	if (other.classname != "player")
		return;

	if (self.classname == "item_shard")
	{
		type = 0.2;
		value = 10;
		bit = IT_SHARD;
	}
	
	if (other.armortype*other.armorvalue >= type*value)
		return;
	else (self.armorvalue = value + bit);
		
	other.armortype = type;
	other.armorvalue = value;
	other.items = other.items - (other.items & (IT_SHARD | IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;

	self.solid = SOLID_NOT;
	self.model = string_null;
	if (deathmatch == 1)
		self.nextthink = time + 20;
	self.think = SUB_regen;

	sprint(other, "You got an armor shard\n");
//  touch sound
	sound(other, CHAN_ITEM, "items/shard.wav", 1, ATTN_NORM);
	stuffcmd (other, "bf\n");
	
	activator = other;
	SUB_UseTargets();				// fire all targets / killtargets
};

/*QUAKED item_shard (0 .5 .8) (-8 -8 0) (8 8 32)
*/

void() item_shard =
{
	precache_sound("items/shard.wav");
	self.touch = shard_touch;
	precache_model ("progs/shard.mdl");
	setmodel (self, "progs/shard.mdl");
	setsize (self, '-8 -8 0', '8 8 32');
	StartItem ();
};
The way it stands at this ^ point it adds 10 to the armor count then stops but fortunately doesn't continue picking up shards (which I guess is on the right track, but not working as intended). Any help with this would be extremely appreciated. Thanks guys.
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Post by r00k »

Lemme edit this a bit...
no idea if it will work... just compiling in my head ;)

You dont even need IT_SHARD actually...

shard.qc:

Code: Select all


void() shard_touch =
{
	if (other.health <= 0)
		return;
	
	if (other.classname != "player")
		return;
	
	other.armorvalue += self.armorvalue;	// this will also allow green and yellow armor to grow beyond normal limits.
	if (other.armorvalue > 250)
		other.armorvalue = 250;
	
	self.solid = SOLID_NOT;
	self.model = string_null;

	if (deathmatch && (deathmatch != 2))	//deathmatch 2 mean no respawn (silly)
	{
		self.nextthink = time + 20;
		self.think = SUB_regen;
	}
	
	sprint(other, "You got an armor shard\n");
	//  touch sound
	sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
	stuffcmd (other, "bf\n");
	
	activator = other;
	SUB_UseTargets();            // fire all targets / killtargets
};

/*
QUAKED item_shard (0 .5 .8) (-8 -8 0) (8 8 32)
*/

void() item_shard =
{
   precache_sound("items/shard.wav");
   self.noise = "items/shard.wav";
   self.touch = shard_touch;
   precache_model ("progs/shard.mdl");
   self.mdl = "progs/shard.mdl");	//must set this as SUB_regen uses this.
   setmodel (self, "progs/shard.mdl");
   setsize (self, '-8 -8 0', '8 8 32'); //could use VEC_HULL_MIN, VEC_HULL_MAX for easier pickups.
   self.armorvalue = 10;
   StartItem ();
};
Last edited by r00k on Tue Nov 23, 2010 6:17 am, edited 4 times in total.
gnounc
Posts: 428
Joined: Mon Apr 06, 2009 6:26 am

Post by gnounc »

i believe your problem is here :

Code: Select all

 if (other.armortype*other.armorvalue >= type*value)
      return;
   else (self.armorvalue = value + bit);
      
   other.armortype = type;
   other.armorvalue = value;
   other.items = other.items - (other.items & (IT_SHARD | IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
its weighing your armorvalue against the shards (very low) armor value. and if your current armor is more than the shard...calling the whole thing off.

you dont want it compared at all, what you want is the armor value to be added regardless, checking only that its below 200 or 250.

remove the if condition and return statement leaving only the else.. which leaves you with:

Code: Select all

self.armorvalue = value + bit);
      
   other.armortype = type;
   other.armorvalue = value;
   other.items = other.items - (other.items & (IT_SHARD | IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
and see if you're any closer to your objective
gnounc
Posts: 428
Joined: Mon Apr 06, 2009 6:26 am

Post by gnounc »

also in the else statement


you have you are directly setting
the armor value...

Code: Select all

 else (self.armor

value = value + bit); 
and then immediately ovverriding it

Code: Select all

     
   other.armortype = type;
   other.armorvalue = value;
   other.items = other.items - (other.items & (IT_SHARD | IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit; 
remove the else statement and change
the line that says
other.armorvalue = value;
to
other.armorvalue = other.armorvalue + value;[/code]

also, you are going to want to change the armor shard type based on what your current armor is...if you're lazy.

or do it the correcct way and make armor shard work as armor seperate from your normal armor count, because how you have it
overrides your current armor type (red yellow green) with your armor shard type every time you pick up an armor shard
enki
Posts: 10
Joined: Tue Nov 23, 2010 2:57 am

Post by enki »

Holy crapola, gnounc... I think this worked.

If not, it got me a hell of a lot closer. You're a genius, bro.

:lol:
enki
Posts: 10
Joined: Tue Nov 23, 2010 2:57 am

Post by enki »

gnounc wrote: also, you are going to want to change the armor shard type based on what your current armor is...if you're lazy.

or do it the correcct way and make armor shard work as armor seperate from your normal armor count, because how you have it
overrides your current armor type (red yellow green) with your armor shard type every time you pick up an armor shard
Ok well yes, this is the problem, it will go over 200+ and keep right on going the way it is now.

I'm not sure I follow how giving it a different type will add to armor count without replacing / overriding the type. Sorry for my noobness :S
gnounc
Posts: 428
Joined: Mon Apr 06, 2009 6:26 am

Post by gnounc »

Actually look at rooks code instead.
Its concise and to the point completely bypassing the need to
declare new armor types and worry about cludgy hangups.
enki
Posts: 10
Joined: Tue Nov 23, 2010 2:57 am

Post by enki »

r00k wrote:Lemme edit this a bit...
no idea if it will work... just compiling in my head ;)

You dont even need IT_SHARD actually...

shard.qc:

Code: Select all


void() shard_touch =
{
	if (other.health <= 0)
		return;
	
	if (other.classname != "player")
		return;
	
	other.armorvalue += self.armorvalue;	// this will also allow green and yellow armor to grow beyond normal limits.
	if (other.armorvalue > 250)
		other.armorvalue = 250;
	
	self.solid = SOLID_NOT;
	self.model = string_null;

	if (deathmatch && (deathmatch != 2))	//deathmatch 2 mean no respawn (silly)
	{
		self.nextthink = time + 20;
		self.think = SUB_regen;
	}
	
	sprint(other, "You got an armor shard\n");
	//  touch sound
	sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
	stuffcmd (other, "bf\n");
	
	activator = other;
	SUB_UseTargets();            // fire all targets / killtargets
};

/*
QUAKED item_shard (0 .5 .8) (-8 -8 0) (8 8 32)
*/

void() item_shard =
{
   precache_sound("items/shard.wav");
   self.noise = "items/shard.wav";
   self.touch = shard_touch;
   precache_model ("progs/shard.mdl");
   self.mdl = "progs/shard.mdl");	//must set this as SUB_regen uses this.
   setmodel (self, "progs/shard.mdl");
   setsize (self, '-8 -8 0', '8 8 32'); //could use VEC_HULL_MIN, VEC_HULL_MAX for easier pickups.
   self.armorvalue = 10;
   StartItem ();
};
This line:

Code: Select all

other.armorvalue += self.armorvalue;   // this will also allow green and yellow armor to grow beyond normal limits.
returns an error "type mismatch for =. Types float and pointer not allowed" ...
Sajt
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Post by Sajt »

Perhaps you aren't compiling with FTEQCC. In any case it's safer to do

other.armorvalue = other.armorvalue + self.armorvalue;
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
enki
Posts: 10
Joined: Tue Nov 23, 2010 2:57 am

Post by enki »

Booya. Thanks gentlemen.

This will work nicely:

Code: Select all

void() shard_touch =
{
    if (other.health <= 0)
		return;
   
    if (other.classname != "player")
		return;
   
    other.armorvalue = other.armorvalue + self.armorvalue;   	// this will also allow green and yellow armor to grow beyond normal limits.
    if (other.armorvalue > 250)
	other.armorvalue = 250;
   
    self.solid = SOLID_NOT;
    self.model = string_null;

    if (deathmatch && (deathmatch != 2))   //deathmatch 2 mean no respawn (silly)
    {
      self.nextthink = time + 20;
      self.think = SUB_regen;
    }
   
    sprint(other, "You got an armor shard\n");
    //  touch sound
    sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
    stuffcmd (other, "bf\n");
   
    activator = other;
    SUB_UseTargets();            // fire all targets / killtargets
};

/*
QUAKED item_shard (0 .5 .8) (-8 -8 0) (8 8 32)
*/

void() item_shard =
{
    precache_sound("items/shard.wav");
    self.noise = "items/shard.wav";
    self.touch = shard_touch;
    precache_model ("progs/shard.mdl");
    self.mdl = "progs/shard.mdl";   //must set this as SUB_regen uses this.
    setmodel (self, "progs/shard.mdl");
    setsize (self, '-8 -8 0', '8 8 32'); //could use VEC_HULL_MIN, VEC_HULL_MAX for easier pickups.
    self.armorvalue = 10;
    StartItem ();
}; 
Now picks up shards and doesn't exceed 250 armor count, but does continue to pick up shards after limit reached - I guess I'll have to figure a work around for that.

At any rate this has been a massive help in understanding exactly how that works - as usual I really overthought it :(
gnounc
Posts: 428
Joined: Mon Apr 06, 2009 6:26 am

Post by gnounc »

change

Code: Select all

  
 if (other.armorvalue > 250)
   other.armorvalue = 250; 
to

Code: Select all

  
 if (other.armorvalue > 250)
return;
[/code]
enki
Posts: 10
Joined: Tue Nov 23, 2010 2:57 am

Post by enki »

gnounc wrote:change

Code: Select all

  
 if (other.armorvalue > 250)
   other.armorvalue = 250; 
to

Code: Select all

  
 if (other.armorvalue > 250)
return;
[/code]
That should work, but resumes picking up the shards and adding to the count in excess of 250 :)
Urre
Posts: 1109
Joined: Fri Nov 05, 2004 2:36 am
Location: Moon
Contact:

Post by Urre »

Yes because you add the armor before that check, which is obviously a good way to combine adding the armor plus limiting it to a maximum of 250. But right now it will make shards disappear even if you're maxed out, so it depends on how you want that to work. Them disappearing no matter what is inconsistent with how Quake works otherwise, so if you're concerned with that you'd want to add a check for that right after checking if it's a player touching.
I was once a Quake modder
enki
Posts: 10
Joined: Tue Nov 23, 2010 2:57 am

Post by enki »

Urre wrote:Yes because you add the armor before that check, which is obviously a good way to combine adding the armor plus limiting it to a maximum of 250. But right now it will make shards disappear even if you're maxed out, so it depends on how you want that to work. Them disappearing no matter what is inconsistent with how Quake works otherwise, so if you're concerned with that you'd want to add a check for that right after checking if it's a player touching.
I'd honestly like to leave it the way it is right now. It's for a SP mod, and so it's a client calculation - knowing that's how the mod works. the player will have to move carefully to avoid exhausting the shards unnecessarily (if by teh grace of the god almighty they should have anywhere near 200+ armor, which is unlikely).
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Post by r00k »

What Urre said.

Code: Select all

if (other.classname != "player")
   return; 

if (other.armorvalue >= 250) // Urre
   return;

other.armorvalue = other.armorvalue + self.armorvalue; 

if (other.armorvalue > 250) 
   other.armorvalue = 250;

This wont pick up shard if you are full of armor, but if you have like 246 armor and u grab a shard it will still add the 4 units up to 250.

:D
Post Reply