Forum

Weapon Pickup

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

Weapon Pickup

Postby Ghost_Fang » Sat Jan 23, 2010 2:49 am

Could someone give me a general idea on how i can "categorize" weapons/make "weapon slots" so i only carry 1 of each "type"?

Example:
Only can carry
One melee
One Sidearm
One Primary

I think i might have a general idea how, i just need a little push and i might be able to fill in the blanks.

And the second part i want is manual weapon pickup, so when you are near it it wont auto place into your inventory. I want it so you can press "action" to pick up when your near, i honestly am stumped on this one, i would appreciate detailed info on this one.

Thanks in advance,
-Ghost
Ghost_Fang
 
Posts: 336
Joined: Thu Nov 12, 2009 4:37 am

Postby Arkage » Sat Jan 23, 2010 3:54 am

Check by the weapons name upon pick up. Then if a weapon of the same type is there already drop it and replace with the new one.

For pick up you could check if an impulse is pressed while touching the gun to pick up.
User avatar
Arkage
 
Posts: 66
Joined: Thu Nov 19, 2009 4:17 pm

Postby Ghost_Fang » Sat Jan 23, 2010 4:15 am

hmmmm
i THINK i understand, couldnt i give each weapon type a flag, like melee , side, and prime? and then only allow 1 each? and if impulse XX is press + weapon touch then pickup? And replace the weapon with the weapon of the same flag?
Ghost_Fang
 
Posts: 336
Joined: Thu Nov 12, 2009 4:37 am

Postby Baker » Sat Jan 23, 2010 4:17 am

Can't help with the manual pickup thing. Can help with the one type of weapon.

GROUP 1

#define IT_SHOTGUN 1
#define IT_SUPER_SHOTGUN 2
#define IT_NAILGUN 4

GROUP 2

#define IT_SUPER_NAILGUN 8
#define IT_GRENADE_LAUNCHER 16

GROUP 3

#define IT_ROCKET_LAUNCHER 32
#define IT_LIGHTNING 64
#define IT_SUPER_LIGHTNING 128

Here is an attempt to give you the idea of the logic when used in conjunction with the "onegun" answer I did ( viewtopic.php?t=1972 )...

Code: Select all
local float group1;
local float group2;
local float group3;
local float allweaps;
local float itemsnoguns;

group1 = IT_SHOTGUN  | IT_NAILGUN | IT_SUPERSHOTGUN;  // group1 guns ... 1 + 2 + 4 = 7 (see constants above)

group2 = IT_SUPER_NAILGUN | IT_GRENADE_LAUNCHER; // group2 guns

group3 = IT_ROCKET_LAUNCHER | IT_LIGHTNING | IT_SUPER_LIGHTNING;  // group3 guns

allweaps = other.items & (group1 | group2 | group3);
// allweaps will equal all items that are in group1 or group2 or group3 that you have now with none of the items.

itemsnoguns = other.items - allweaps;
// If you subtract those out, you have the itemsnoguns which is all the items you have right now that are not guns

if (new & group1) // If the new weapon matches a group 1 gun
   other.items = itemsnoguns | new | (allweaps & (group2 | group3)); // items = items without guns + new + the set of weapons you have that are in group2 or group 3

if (new & group2)
   other.items = itemsnoguns | new | (allweaps & (group1 | group3));

if (new & group3)
   other.items = itemsnoguns | new | (allweaps & (group2 | group3));


That's just about the limit of QuakeC capabilities right there ;) In fact, I'm surprised there have been questions I can partially answer in the last few days.
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 ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby Ghost_Fang » Sat Jan 23, 2010 5:00 am

Can you also explain it too?
your comments kind of help, but i dont know...
Im sorry, i just dont get it yet.... :?
Ghost_Fang
 
Posts: 336
Joined: Thu Nov 12, 2009 4:37 am

Postby Baker » Sat Jan 23, 2010 5:19 am

Probably works ... untested.

If it doesn't, well, then someone else will have to answer because I'm not Mr. QuakeC, haha ....

Most of the logic is, unfortunately, simple binary operations where | is OR and & is AND. Not so easy to explain in a post, but gist of it is that your inventory is something like 256 + 16 + 4 + 1 added together where each number represents an item. You can add them or subtract those numbers from your inventory to remove the item.

OR is the same as adding each number together if it doesn't exist. So 4 OR 2 OR 1 is expressed in C as 4 | 2 | 1 which is Group 1 (IT_SHOTGUN [1] | IT _ SUPERSHOT_GUN [2] | IT_NAILGUN [4])

http://www.computerhope.com/jargon/b/binary.htm


Code: Select all
/*
=============
weapon_touch
=============
*/
float() W_BestWeapon;

void() weapon_touch =
{
   local   float   hadammo, best, new; //, old;
   local   entity   stemp;
   local   float   leave;
   local float group1;
   local float group2;
   local float group3;
   local float allweaps;
   local float itemsnoguns;

group1 = IT_SHOTGUN  | IT_NAILGUN | IT_SUPERSHOTGUN;  // group1 guns ... 1 + 2 + 4 = 7 (see constants above)

group2 = IT_SUPER_NAILGUN | IT_GRENADE_LAUNCHER; // group2 guns

group3 = IT_ROCKET_LAUNCHER | IT_LIGHTNING | IT_SUPER_LIGHTNING;  // group3 guns

   if (!(other.flags & FL_CLIENT))
      return;

// if the player was using his best weapon, change up to the new one if better      
   stemp = self;
   self = other;
   best = W_BestWeapon();
   self = stemp;

   if (deathmatch == 2 || coop)
      leave = 1;
   else
      leave = 0;
   
   if (self.classname == "weapon_nailgun")
   {
      if (leave && (other.items & IT_NAILGUN) )
         return;
      hadammo = other.ammo_nails;         
      new = IT_NAILGUN;
      other.ammo_nails = other.ammo_nails + 30;
   }
   else if (self.classname == "weapon_supernailgun")
   {
      if (leave && (other.items & IT_SUPER_NAILGUN) )
         return;
      hadammo = other.ammo_rockets;         
      new = IT_SUPER_NAILGUN;
      other.ammo_nails = other.ammo_nails + 30;
   }
   else if (self.classname == "weapon_supershotgun")
   {
      if (leave && (other.items & IT_SUPER_SHOTGUN) )
         return;
      hadammo = other.ammo_rockets;         
      new = IT_SUPER_SHOTGUN;
      other.ammo_shells = other.ammo_shells + 5;
   }
   else if (self.classname == "weapon_rocketlauncher")
   {
      if (leave && (other.items & IT_ROCKET_LAUNCHER) )
         return;
      hadammo = other.ammo_rockets;         
      new = IT_ROCKET_LAUNCHER;
      other.ammo_rockets = other.ammo_rockets + 5;
   }
   else if (self.classname == "weapon_grenadelauncher")
   {
      if (leave && (other.items & IT_GRENADE_LAUNCHER) )
         return;
      hadammo = other.ammo_rockets;         
      new = IT_GRENADE_LAUNCHER;
      other.ammo_rockets = other.ammo_rockets + 5;
   }
   else if (self.classname == "weapon_lightning")
   {
      if (leave && (other.items & IT_LIGHTNING) )
         return;
      hadammo = other.ammo_rockets;         
      new = IT_LIGHTNING;
      other.ammo_cells = other.ammo_cells + 15;
   }
   else
      objerror ("weapon_touch: unknown classname");

   sprint (other, "You got the ");
   sprint (other, self.netname);
   sprint (other, "\n");
// weapon touch sound
   sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
   stuffcmd (other, "bf\n");

   bound_other_ammo ();

// change to the weapon

   allweaps = other.items & (group1 | group2 | group3);
   // allweaps will equal all items that are in group1 or group2 or group3 that you have now with none of the items.

   itemsnoguns = other.items - allweaps;
   // If you subtract those out, you have the itemsnoguns which is all the items you have right now that are not guns

   if (new & group1) // If the new weapon matches a group 1 gun
      other.items = itemsnoguns | new | (allweaps & (group2 | group3)); // items = items without guns + new + the set of weapons you have that are in group2 or group 3

   if (new & group2)
      other.items = itemsnoguns | new | (allweaps & (group1 | group3));

   if (new & group3)
      other.items = itemsnoguns | new | (allweaps & (group2 | group3));

   stemp = self;
   self = other;

//   if (!deathmatch)
      self.weapon = new;
//   else
//      Deathmatch_Weapon (old, new);

   W_SetCurrentAmmo();

   self = stemp;

   if (leave)
      return;

// remove it in single player, or setup for respawning in deathmatch
   self.model = string_null;
   self.solid = SOLID_NOT;
   if (deathmatch == 1)
      self.nextthink = time + 30;
   self.think = SUB_regen;
   
   activator = other;
   SUB_UseTargets();            // fire all targets / killtargets
};
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 ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby Wazat » Sat Jan 23, 2010 6:12 am

The pickup by button press stuff can be done by stealing code from my Monster Swarm mod. In the mod you have to aim your screen at a weapon, hold mouse 2, and press a number key. You can modify the code so that instead, they just have to aim at a weapon and press mouse2, and it auto-decides on a slot (melee goes to weapon key #1, pistol goes to weapon key #2, and main weapon to #3).

Also steal & modify the centerprint that tells the user what he's looking at and what he will be replacing:
"Press Mouse2 to swap Shotgun for Kitten Launcher 3000".



As for categorization, you can do a simple function and some defines for that:

untested code:
Code: Select all
At the bottom of defs.qc:

// these floats hold which weapon the player is currently using.  You no longer use the IT_ flags for weapons anymore, they're just for the HUD.

.float wpnMelee;
.float wpnPistol;
.float wpnMain;

// Category is also the weapon number they go to
float CATEGORY_MELEE = 1;
float CATEGORY_PISTOL = 2;
float CATEGORY_MAIN = 3;

float WP_AXE = 1;
float WP_CHAINSAW = 2;
float WP_HUNTING_KNIFE = 3;
// etc...

float WP_EAGLE = 7;
float WP_MAGNUM = 8;
// etc...

float WP_SHOTGUN = 13;
float WP_FLAK_CANNON = 14;
float WP_KITTEN_LAUNCHER = 15;

// IT_AXE etc floats can be renamed, if you like.  They only exist for graphical reasons now (make the hud show the weapon slot).
IT_MELEE = 4096;
IT_PISTOL = 1;
IT_MAIN = 2;




In weapons.qc:

float weaponCategory(float wpn) {
  if(wpn == WP_AXE)
    return CATEGORY_MELEE;
  if(wpn == WP_CHAINSAW)
    return CATEGORY_MELEE;
// More melee checks here

  if(wpn == WP_EAGLE)
    return CATEGORY_PISTOL;
// More pistol checks here

// everything else is a main weapon
    return CATEGORY_MAIN;
}


Now edit the weapon selection code so that it doesn't bother to check if they have the weapon (since I'm assuming a player always has 1 of each type), but it still checks ammo. The player should always spawn with IT_AXE | IT_SHOTGUN | IT_SUPER_SHOTGUN in his inventory (or whatever you renamed them to), so change setnewparms() to do that. Setnewparms and its companion functions should also use 3 of the 16 parms to store what the player's 3 weapons are.

That should get you started. I hope that helps!
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.
Wazat
 
Posts: 771
Joined: Fri Oct 15, 2004 9:50 pm
Location: Middle 'o the desert, USA

Postby Ghost_Fang » Sat Jan 23, 2010 6:13 am

Wow! I thought it was gona be simple lol....
Thanks Baker, but is there someway we can talk in real time so you can explain it better or is there a different way using like flags or something?
Maybe group wasnt a good term to use.

Lets say i have a shotty in hand and an Uzi on the ground, if i pick up the uzi i want it to drop the shotty and replace it with the uzi.

Is there a way where i can set a flag or even maybe a float that will overwrite each other?
I would use that Baker, but im going to be adding more weapons and editing some etc.
I am really sorry, i feel bad that you kinda wasted your time :cry: :oops:
Ghost_Fang
 
Posts: 336
Joined: Thu Nov 12, 2009 4:37 am

Postby ceriux » Sat Jan 23, 2010 6:30 am

what i did, was assign classes, remove the pickup code for weapons give the players they're weapon sets using a customized "setnewparms" then after finished with all of that, i changed the keys assignment of all primary weapons to 2 (which is what the shotgun is " look up just about any new weapon code in the tutorial section which doesnt replace a preexisting one to learn how to do that") and finally set all of the primary weapons ammo type to shells, and all secondary weapon types to nails.
User avatar
ceriux
 
Posts: 2223
Joined: Sat Sep 06, 2008 3:30 pm
Location: Indiana, USA

Postby Baker » Sat Jan 23, 2010 3:18 pm

Ghost_Fang wrote:Wow! I thought it was gona be simple lol....
Thanks Baker, but is there someway we can talk in real time so you can explain it better or is there a different way using like flags or something?


I'd be the wrong guy to learn from. I suck at QuakeC because that isn't where my interests lie. [Btw, I'm known to dislike real time communcation like IRC or IM and prefer asynchronous stuff such as forums].

p.s. It is simple. It's very, very simple. It only seems not because you don't understand "OR" and "AND". They aren't much more complicated than knowing if a number is even or odd.

For Reference wrote:#define IT_SHOTGUN 1
#define IT_SUPER_SHOTGUN 2
#define IT_NAILGUN 4
#define IT_SUPER_NAILGUN 8
#define IT_GRENADE_LAUNCHER 16
#define IT_ROCKET_LAUNCHER 32
#define IT_LIGHTNING 64
#define IT_SUPER_LIGHTNING 128



Binary 0001 = 1 You have IT_SHOTGUN
Binary 0010 = 2 You have IT_SUPER_SHOTGUN
Binary 0011 = 3 You have IT_SHOTGUN + IT_SUPER_SHOTGUN
Binary 0100 = 4 You have IT_NAILGUN
Binary 0101 = 5 You have IT_NAILGUN + IT_SHOTGUN
Binary 0110 = 6 You have IT_NAILGUN + IT_SUPER_SHOTGUN
Binary 1001 = 9 ... what guns do you have?

IT_SUPER_NAILGUN + IT_SHOTGUN

Bitwise AND

Your inventory is Binary 0110. You know you have 2 items because there are 2 ones.

A bitwise AND allows you to test for the existence of a gun.

Binary 1111 "AND" 0001 IT_SHOTGUN = 0001 // Match!
Binary 0110 "AND" 0001 IT_SHOTGUN = 0 // No match!
Binary 1110 "AND" 0100 IT_NAILGUN = 0100 // Match!
Binary 1011 "AND" 0100 IT_NAILGUN = 0 // No match!

Bitwise OR

A bitwise OR allows you to set a gun

Binary 0110 = 6 = 4 + 2 = You have nailgun + supershotgun

To add the super nail gun which is 8 which is Binary 1000, you perform a bitwise "OR". Or just adds whatever bits, represented by the ones, into the number.

Binary 0110 "OR" 1000 = Binary 1110
Binary 1111 "OR" 1000 = Binary 1111 // Already there!
Binary 1001 "OR" 1000 = Binary 1001 // Already there

There are very high qualities of bitwise operations in Quake --- and in fact most games -- because a single number can represent your inventory.

In C and therefore QuakeC

In C, a bitwise "OR" is "|" so you have expressions like

Code: Select all
other.items = other.items| new; // Add whatever the new gun is


In C, a bitwise "AND" is "&" so you have expressions like

Code: Select all
if (other.items & IT_GRENADE_LAUNCHER) {
      // You already have the grenade launcher
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 ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby SamUK » Sat Jan 23, 2010 11:17 pm

Baker wrote:Btw, I'm known to dislike real time communcation like IRC or IM and prefer asynchronous stuff such as forums.


Yes... I will change your mind on real time communication. Eventually.
Working on Solitude
SamUK
 
Posts: 101
Joined: Wed Dec 17, 2008 6:47 pm
Location: United Kingdom


Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest