This code should work, right?

Discuss programming in the QuakeC language.
ThePlasticBling
Posts: 51
Joined: Fri Jun 04, 2010 10:18 pm

This code should work, right?

Post by ThePlasticBling »

I want the game to give the player a random weapon when impulse 123 is entered. This should work, right?

Code: Select all

void () mystery_box =
{
    if ( (random () = 0.1) )
    {
      self.items = IT_ROCKET_LAUNCHER;
    }
    else
    {
      if ( (random () = 0.2) )
      {
	      self.items = IT_NAILGUN;
      }
      else
      {
	      if ( (random () = 0.3) )
	      {
		      self.items = IT_SUPER_SHOTGUN;
	      }
	      else
	      {
		      if ( (random () = 0.4) )
		      {
			      self.items = IT_SUPER_NAILGUN;
		      }
	      }
      }
      }
};
and then in impulse commands i set impulse 123 to mystery_box

do you guys think this will work?

thanx
scar3crow
InsideQC Staff
Posts: 1054
Joined: Tue Jan 18, 2005 8:54 pm
Location: Alabama

Post by scar3crow »

If I remember correctly, random returns a number from 0 to 1, so that code would in theory only apply 40% of the time, resulting in nothing if random returns 0.5, 0.6, 0.7, 0.8, 0.9, or 1. You should broaden the numeric range (from an equals to a less than of the max qualifier) for the weapons you want.
...and all around me was the chaos of battle and the reek of running blood.... and for the first time in my life I knew true happiness.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Post by Spike »

syntax error. assignment to read-only value.

random will not return 0.2. it'll return 0.200001 or 0.19999999 sure, but not 0.2. Okay, it might, but only really really rarely.
store it to a local and then check its value
or:
void() foo =
{
switch(random(0,4))
{
case 0 .. 0.25:
foo();
break;
case 0.25 .. 0.5:
foo();
break;
case 0.5 .. 0.75:
foo();
break;
default:
foo();
break;
};

also your function doesn't return a value. all it does is set an ent field.
ThePlasticBling
Posts: 51
Joined: Fri Jun 04, 2010 10:18 pm

Post by ThePlasticBling »

would this work:

so would this work:

Code: Select all

void () mystery_box =
{
    if ( (random () = 0.1) )
    {
      self.weapon = IT_ROCKET_LAUNCHER;
    }
    else
    {
      if ( (random () = 0.200001) )
      {
         self.weapon = IT_NAILGUN;
      }
      else
      {
         if ( (random () = 0.3) )
         {
            self.weapon = IT_SUPER_SHOTGUN;
         }
         else
         {
            if ( (random () = 0.4) )
            {
               self.weapon = IT_SUPER_NAILGUN;
            }
         }
      }
      }
};
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Post by frag.machine »

ThePlasticBling wrote:would this work:

so would this work:

Code: Select all

void () mystery_box =
{
    if ( (random () = 0.1) )
    {
      self.weapon = IT_ROCKET_LAUNCHER;
    }
    else
    {
      if ( (random () = 0.200001) )
      {
         self.weapon = IT_NAILGUN;
      }
      else
      {
         if ( (random () = 0.3) )
         {
            self.weapon = IT_SUPER_SHOTGUN;
         }
         else
         {
            if ( (random () = 0.4) )
            {
               self.weapon = IT_SUPER_NAILGUN;
            }
         }
      }
      }
};
First things first.

a) I strongly suggest you to read at least a bit about QuakeC syntax before trying to write any code:

Code: Select all

if ( (random () = 0.1) )
This won't work as you expect. "=" means attribution in QuakeC, and you can't assign a value to a function. So this is illegal code, and won't even compile (have you at least tried ?). For comparisons between values, you should be using "==";

b) as Spike said, random() is a function that returns a non-integer value between 0.00 and 1.00. As you may suspect, the chances to random() return exactly 0.10 or 0.20 are slim, so you should instead test if the returned value falls in a range (0.90 to 0.99, 0.80 to 0.89, etc):

Code: Select all

if (random () >= 0.9) {// do something... }
else if (random () >= 0.8) {// do something else...}
c) finally, if you call random () in every test it will return a different value, and you actually want to test only the first value, otherwise you may end passing by all the tests and never give a weapon to the player. So, you should do this instead:

Code: Select all

local float r;

r = random ();
if (r > 0.9) {// do something}
else if (r > 0.8) {// do something else}
(...)
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
dreadlorde
Posts: 268
Joined: Tue Nov 24, 2009 2:20 am
Contact:

Post by dreadlorde »

You don't need braces if there is only one statement in if.
Ken Thompson wrote:One of my most productive days was throwing away 1000 lines of code.
Get off my lawn!
ThePlasticBling
Posts: 51
Joined: Fri Jun 04, 2010 10:18 pm

Post by ThePlasticBling »

would this give me a random weapon? I have it set to impulse 123:

Code: Select all

void () mystery_box =
{
	local float r;
	
	r = random ();
	if (r > 0.9)
	{
		self.items = IT_ROCKET_LAUNCHER;
	}
	else if (r > 0.8)
	{
		self.items = IT_SUPER_SHOTGUN;
	}
	else if (r > 0.7)
	{
		self.items = IT_NAILGUN;
	}
	else if (r > 0.6)
	{
		self.items = IT_SUPER_NAILGUN;
	}
	else if (r > 0.5)
	{
		self.items = IT_GRENADE_LAUNCHER;
	}
	else if (r < 0.4)
	{
		self.items = IT_NAILGUN;
	}
	else if (r < 0.3)
	{
		self.items = IT_SUPER_NAILGUN;
	}
	else if (r < 0.2)
	{
		self.items = IT_ROCKET_LAUNCHER;
	}
	else if (r < 0.1)
	{
		self.items = IT_LIGHTNING;
	}
};
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Post by frag.machine »

ThePlasticBling wrote:would this give me a random weapon? I have it set to impulse 123:

Code: Select all

void () mystery_box =
{
	local float r;
	
	r = random ();
	if (r > 0.9)
	{
		self.items = IT_ROCKET_LAUNCHER;
	}
	else if (r > 0.8)
	{
		self.items = IT_SUPER_SHOTGUN;
	}
	else if (r > 0.7)
	{
		self.items = IT_NAILGUN;
	}
	else if (r > 0.6)
	{
		self.items = IT_SUPER_NAILGUN;
	}
	else if (r > 0.5)
	{
		self.items = IT_GRENADE_LAUNCHER;
	}
Up to this point it's similar to what I did, but...
ThePlasticBling wrote:

Code: Select all

	else if (r < 0.4)
	{
		self.items = IT_NAILGUN;
	}
	else if (r < 0.3)
	{
		self.items = IT_SUPER_NAILGUN;
	}
	else if (r < 0.2)
	{
		self.items = IT_ROCKET_LAUNCHER;
	}
	else if (r < 0.1)
	{
		self.items = IT_LIGHTNING;
	}
};
This block of code won't work as you expect. But I won't tell you what is wrong; compare both and you can tell youself what's the difference. ;)

Also, even fixing this, there's another flaw in your code: before you do this:

Code: Select all

self.items = IT_LIGHTNING;
You must remember that self.items is a bitflag actually - every bit, from bit 0 to bit 23 means something in the player's inventory. If you just set it directly with a value, you're actually clearing any other item in the player's inventory - the axe, the shotgun, the nailgun, etc. What you should do instead is just set the single bit referring the given weapon, like this:

Code: Select all

self.items = self.items | IT_LIGHTNING;
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
DusterdooSmock
Posts: 170
Joined: Thu Aug 19, 2010 9:58 pm

Post by DusterdooSmock »

AS ALMOST EVERYONE HAS SAID: LEARN QC BEFORE YOU TRY TO DO THIS!
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Post by frag.machine »

dreadlorde wrote:You don't need braces if there is only one statement in if.
They're indeed not required; I use to always put them so the code turns more easy to read.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
DusterdooSmock
Posts: 170
Joined: Thu Aug 19, 2010 9:58 pm

Post by DusterdooSmock »

frag.machine wrote:
dreadlorde wrote:You don't need braces if there is only one statement in if.
They're indeed not required; I use to always put them so the code turns more easy to read.
I use them too...makes everything easier to read and see what the function does.
Mexicouger
Posts: 514
Joined: Sat May 01, 2010 10:12 pm
Contact:

Post by Mexicouger »

Why don't you take someones suggestions and attempt to look at some tutorials and see how some stuff works. Stop asking a question about ever little thing. And Use the search bar for some things. I had a couple questions, and a quick search fixed my problem.
ThePlasticBling
Posts: 51
Joined: Fri Jun 04, 2010 10:18 pm

Post by ThePlasticBling »

Hmmmmm. I just dont get it. when impulse 123 is entered, i don't get a random weapon. here is my code:

Code: Select all

void () mystery_box =
{
	local float r;
	
	r = random ();
	if (r > 0.9)
	{
		self.items = self.items | IT_LIGHTNING;
	}
	else if (r > 0.8)
	{
		self.items = self.items | IT_SUPER_NAILGUN;
	}
	else if (r > 0.7)
	{
		self.items = self.items | IT_ROCKET_LAUNCHER;
	}
	else if (r > 0.6)
	{
		self.items = self.items | IT_GRENADE_LAUNCHER;
	}
	else if (r > 0.5)
	{
		self.items = self.items | IT_NAILGUN;
	}
	else if (r > 0.4)
	{
		self.items = self.items | IT_SUPER_SHOTGUN;
	}
	else if (r > 0.3)
	{
		self.items = self.items | IT_SUPER_SHOTGUN;
	}
	else if (r > 0.2)
	{
		self.items = self.items | IT_NAILGUN;
	}
	else if (r > 0.1)
	{
		self.items = self.items | IT_NAILGUN;
	}
};
and mexicugar, i am taking peoples advice. I've been looking at tutorials. it helps best if i try a code i made and if it doesnt work, I ask you guys so i can learn from my mistakes.
Mexicouger
Posts: 514
Joined: Sat May 01, 2010 10:12 pm
Contact:

Post by Mexicouger »

Try this:

Code: Select all

void () mystery_box =
{
   local float r;
   
   r = random ();
   if (r < 0.9)
   {
      self.items = self.items | IT_LIGHTNING;
   }
   else if (r < 0.8)
   {
      self.items = self.items | IT_SUPER_NAILGUN;
   }
   else if (r < 0.7)
   {
      self.items = self.items | IT_ROCKET_LAUNCHER;
   }
   else if (r < 0.6)
   {
      self.items = self.items | IT_GRENADE_LAUNCHER;
   }
   else if (r < 0.5)
   {
      self.items = self.items | IT_NAILGUN;
   }
   else if (r < 0.4)
   {
      self.items = self.items | IT_SUPER_SHOTGUN;
   }
   else if (r < 0.3)
   {
      self.items = self.items | IT_SUPER_SHOTGUN;
   }
   else if (r < 0.2)
   {
      self.items = self.items | IT_NAILGUN;
   }
   else if (r < 0.1)
   {
      self.items = self.items | IT_NAILGUN;
   }
};
ThePlasticBling
Posts: 51
Joined: Fri Jun 04, 2010 10:18 pm

Post by ThePlasticBling »

still doesn't work. what am i doing wrong?
Post Reply