Forum

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

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

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

Postby enki » Tue Nov 23, 2010 4:14 am

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.
enki
 
Posts: 10
Joined: Tue Nov 23, 2010 2:57 am

Postby r00k » Tue Nov 23, 2010 5:32 am

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.
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Postby gnounc » Tue Nov 23, 2010 5:35 am

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
User avatar
gnounc
 
Posts: 424
Joined: Mon Apr 06, 2009 6:26 am

Postby gnounc » Tue Nov 23, 2010 5:58 am

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
User avatar
gnounc
 
Posts: 424
Joined: Mon Apr 06, 2009 6:26 am

Postby enki » Tue Nov 23, 2010 6:12 am

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

Postby enki » Tue Nov 23, 2010 6:30 am

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
enki
 
Posts: 10
Joined: Tue Nov 23, 2010 2:57 am

Postby gnounc » Tue Nov 23, 2010 6:33 am

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.
User avatar
gnounc
 
Posts: 424
Joined: Mon Apr 06, 2009 6:26 am

Postby enki » Tue Nov 23, 2010 6:51 am

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" ...
enki
 
Posts: 10
Joined: Tue Nov 23, 2010 2:57 am

Postby Sajt » Tue Nov 23, 2010 6:55 am

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.
Sajt
 
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Postby enki » Tue Nov 23, 2010 7:06 am

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 :(
enki
 
Posts: 10
Joined: Tue Nov 23, 2010 2:57 am

Postby gnounc » Tue Nov 23, 2010 7:12 am

change

Code: Select all
 
 if (other.armorvalue > 250)
   other.armorvalue = 250;


to

Code: Select all
 
 if (other.armorvalue > 250)
return;


[/code]
User avatar
gnounc
 
Posts: 424
Joined: Mon Apr 06, 2009 6:26 am

Postby enki » Tue Nov 23, 2010 7:18 am

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 :)
enki
 
Posts: 10
Joined: Tue Nov 23, 2010 2:57 am

Postby Urre » Tue Nov 23, 2010 8:22 am

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
User avatar
Urre
 
Posts: 1109
Joined: Fri Nov 05, 2004 2:36 am
Location: Moon

Postby enki » Tue Nov 23, 2010 8:27 am

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).
enki
 
Posts: 10
Joined: Tue Nov 23, 2010 2:57 am

Postby r00k » Tue Nov 23, 2010 9:07 am

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
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Next

Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest