.qc (dot qc) - the group for quake c coders of all denominations. If you make quake one mods and write code in quake c, join our group! I'll try to answer any quake c questions - please post your inquiry in the forums...

Forum Thread
  Posts  
Randomize weapons (Groups : qc : Forum : vault() : Randomize weapons) Post Reply
Thread Options
numbersix
numbersix quake-c coder++
Aug 29 2017 Anchor

A request for a short mod to randomize weapons.

This is probably of more interest in deathmatch, as it will unbalance singleplayer.
Either making SP easy or really hard.

/*
===============================================================================
 random weapon project

===============================================================================
*/

// put this in defs.qc
void() rnd_wep;

/// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// put cvar defines in autoexec.cfg or some other startup .cfg
// may not work on old q engines
/*

// sample breakdown - 15% supershot, no nailgun, 30% sng, 15% grenade, 10% rocket, 30% lightning

set		_rnd_ss				"150"
set		_rnd_ng				"-1"
set		_rnd_sng				"450"
set		_rnd_gl				"600"
set		_rnd_rl					"700"
set		_rnd_lg				"1000"

*/

/// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// put this code after void() weapon_lightning block and before ammo section in items.qc

// pick a random wep when called
// calls spawn fn for wep

/*
 uses cvar for percentages if cvar non 0 - value of 100 is 10%, 900 is 90%
 adds cvars up to 1000 - if 1000 is exceeded, rest of weps are excluded
 if a cvar is <= 0, wep is ignored -- but if they are all 0, default is used
 see default case below when all cvar are 0 for example
*/

// if you want a map spawned wep to ignore randomize, set its aflag in the wep setup
/*
{
"origin" "0 0 0"
"classname"	"weapon_rocketlauncher"
"aflag"  "1"
}
*/

// for this I reused the button* values darkplaces sets up for mouse button storage
// uncomment this if you dont have these defined

//.float button3, button4, button5, button6;

void() rnd_wep =
{
// get a random value from 0 - 1000
	self.cnt = random() * 1000;

	self.button0 = cvar("_rnd_ss");		// random code supershotgun
	self.button1 = cvar("_rnd_ng");		// random code nailgun
	self.button2 = cvar("_rnd_sng");		// random code supernailgun
	self.button3 = cvar("_rnd_gl");		// random code grenade
	self.button4 = cvar("_rnd_rl");		// random code rocket
	self.button5 = cvar("_rnd_lg");		// random code lightning gun

// test value for all 0 case
	self.button6 = self.button0 + self.button1 + self.button2 + self.button3 + self.button4 + self.button5;

// all values were 0 - use even probability default case
	if (!self.button6)
	{
		self.button0 = 166;
		self.button1 = 332;
		self.button2 = 498;
		self.button3 = 664;
		self.button4 = 830;
		self.button5 = 1000;
	}

	if ( (self.button0 > 0) && (self.cnt < self.button0) )
		weapon_supershotgun();
	else
	if ( (self.button1 > 0) && (self.cnt < self.button1) )
		weapon_nailgun();
	else
	if ( (self.button2 > 0) && (self.cnt < self.button2) )
		weapon_supernailgun();
	else
	if ( (self.button3 > 0) && (self.cnt < self.button3) )
		weapon_grenadelauncher();
	else
	if ( (self.button4 > 0) && (self.cnt < self.button4) )
		weapon_rocketlauncher();
	else
// if this last test fails the weapon will not spawn, this can be used to randomize out weapon spawns on a percentage
// just leave button5 value somewhere less than 1000 - thus (1000 - button5) / 10 will the the percent for no weapon at that spot
	if ( (self.button5 > 0) && (self.cnt < self.button5) )
		weapon_lightning();

/*
// uncomment this if you never want a rnd fail to not make a wep	
//	code to supply a base default if all tests fail

	if (self.netname = string_null)
		weapon_supernailgun();

*/
};


/// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// modify all weapon spawns by adding the call randomizer fragment shown
// make sure to copy the function name to the classname assign

/*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
*/

void() weapon_supershotgun =
{
// call randomizer
	if (!self.aflag)
	{
		self.aflag = 1; // allow weapon spawns to be called
		rnd_wep();
		return;
	}
	self.classname = "weapon_supershotgun"; // you MUST copy the function value here for this to work

	precache_model ("progs/g_shot.mdl");
	setmodel (self, "progs/g_shot.mdl");
	self.weapon = IT_SUPER_SHOTGUN;
	self.netname = "Double-barrelled Shotgun";
	self.touch = weapon_touch;
	setsize (self, '-16 -16 0', '16 16 56');
	StartItem ();
};


Note: you MUST add the classname assign after the randomizer call block in each weapon spawn.
And that classname assign must be the function name.

Enjoy random weapons!

Edited by: numbersix

Aug 30 2017 Anchor

hey, thanks for the reply. with some help i was able to come up with this:

what do you think ? it works pretty well as far as i can tell. plus it's short :) had a bit of help from the ppl over at quakeone.com
void() weapon_rando =
{
    local float r;
    r = random() * 6;

    if (r < 1)
    {
    self.classname = "weapon_lightning";
    weapon_lightning();}
    else if (r < 2)
    {
    self.classname = "weapon_rocketlauncher";
    weapon_rocketlauncher();}
    else if (r < 3)
    {
    self.classname = "weapon_grenadelauncher";
    weapon_grenadelauncher();}
    else if (r < 4)
    {
    self.classname = "weapon_supernailgun";
    weapon_supernailgun();}
    else if (r < 5)
    {
    self.classname = "weapon_nailgun";
    weapon_nailgun();}
    else if (r < 6)
    {
    self.classname = "weapon_supershotgun";
    weapon_supershotgun();}


};

Edited by: ceriux

numbersix
numbersix quake-c coder++
Aug 30 2017 Anchor

Yep that will work. You could even meld in the cvar percentage controls by using my if - else block tests in a similar way.

I had a thought about restricting this to deathmatch only.

For my code, add this to every weapon spawn to restrict this to deathmatch:

// call randomizer only in deathmatch
	if (!self.aflag && deathmatch)
	{
		self.aflag = 1; // allow weapon spawns to be called
		rnd_wep();
		return;
	}

For your code, I'm not sure where to put a deathmatch test if one is desired.

That would depend on how weapon_rando gets called.

Edited by: numbersix

Reply to thread
click to sign in and post

Only registered members can share their thoughts. So come on! Join the community today (totally free - or sign in with your social account on the right) and join in the conversation.