Announcement

Collapse
No announcement yet.

a mapping entity to spawn random weapons?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • a mapping entity to spawn random weapons?

    hey guys i was just curious if anyone could help me out i want to make a mapping entity that i can place that will spawn a weapon at random. ive been out of QC for a long time so ive been feeling a bit confused. i know i should probably start in items.qc but past that i'm drawing a blank any tips / pointers?

    currently this is what i have... but it does nothing...

    Code:
    void() weapon_rando =
    {
        local float r;
        r = random();
    
        if (r == 1)
        { weapon_lightning();}
        if (r == 2)
        { weapon_rocketlauncher();}
        if (r == 3)
        { weapon_grenadelauncher();}
        if (r == 4)
        { weapon_supernailgun();}
        if (r == 5)
        { weapon_nailgun();}
        if (r == 6)
        { weapon_supershotgun();}
        else return;
    
    };
    thanks to shpuld this has been addressed!

    <+Shpuld> random() returns a float between 0 and 1
    <+ceriux> so use decimals?
    <+ceriux> 0, 0.1, 0.2, 0.3 ect
    <+Shpuld> so you'd want to do r = random() * numberofweapons;
    <+Shpuld> and then if(r < 1) { ... } else if(r < 2) { ... } ...
    <+ceriux> ahh
    <+ceriux> okay lemme try that thanks
    <+Shpuld> you could use if(r<1/6) etc but that's not quite as readable if you ask me

    Last edited by ceriux; 08-28-2017, 12:44 AM.

  • #2
    Hello ceriux,

    The way you plan to do it will not work, as the weapons touch function needs the original .classname.
    So you have to add it into your code.
    Also, be careful with case sensitivity. It might bring issues with certain compilers....


    If you still need support, you can do it this way:

    Code:
    void () weapon_rando =
    {
        local float r;
        r = random ();
    
        if (r < 0.166)
        {
            self.classname = "weapon_lightning";
            weapon_lightning ();
        }
        else if (r < 0.333)
        {
            self.classname = "weapon_rocketlauncher";
            weapon_rocketlauncher ();
        }
        else if (r < 0.5)
        {
            self.classname = "weapon_grenadelauncher";
            weapon_grenadelauncher ();
        }
        else if (r < 0.666)
        {
            self.classname = "weapon_supernailgun";
            weapon_supernailgun ();
        }
        else if (r < 0.833)
        {
            self.classname = "weapon_nailgun";
            weapon_nailgun ();
        }
        else
        {
            self.classname = "weapon_supershotgun";
            weapon_supershotgun ();
        }
    };

    A quick map to test your code is attached to this post.

    All the Best for your project,
    Seven
    Attached Files

    Comment


    • #3
      yes seven you were correct with what i had posted, the weapons would spawn and i could "pick them up" but id get thrown an error and the weapons wouldn't be in my inventory.

      Comment


      • #4
        You could try to use this:

        void() weapon_touch2 =
        {
        local float hadammo, best, new, old;
        local entity stemp;
        local float leave;

        local float r;
        r = random();

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

        stemp = self;
        self = other;
        best = W_BestWeapon();
        self = stemp;

        if (deathmatch == 2 || coop)
        leave = 1;
        else
        leave = 0;

        if (r < 0.166)
        { 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;
        }
        if (r < 0.333)
        { 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;
        }
        if (r < 0.5)
        { 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;
        }
        if (r < 0.666)
        { 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;
        }
        if (r < 0.833)
        { 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
        { 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;
        }

        sprint (other, "You got the ");
        sprint (other, self.netname);
        sprint (other, "\n");

        sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
        stuffcmd (other, "bf\n");

        bound_other_ammo ();

        old = other.items;
        other.items = other.items | new;

        stemp = self;
        self = other;

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

        W_SetCurrentAmmo();

        self = stemp;

        if (leave)
        return;

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

        activator = other;
        SUB_UseTargets();
        };

        As you see it's a c&p of the original weapons pickup function, with the above rng stirred in. I pasted it under the W_BestWeapon(); prototype in the items.qc, directly above the original weapon_touch function. Maybe it works, at least the code compiles without complaining.
        I once was a Ranger like you. But then i took a rocket to the knee.
        My little gore mod : http://quakeone.com/forum/quake-mod-...76473-gore-mod

        Comment


        • #5
          TheKillingJoke

          You'll want to add an 'else' before your if statements, otherwise proceeding code will be run when it shouldn't. Example: if r ends up being 0.08, you'll end up with a grenade launcher and not a nailgun, because all of your if statements will hold true, and it will procedurally run through the code. Additionally, the final 'else' statement will only apply to the preceding if statement. So you should have:

          if (r < x.xxx)
          {}
          else if (r < x.xxx)
          {}
          else
          {}

          The other issue with a randomized touch function is that the weapon model will likely not correlate at all with the weapon the player receives when touching it. If the weapon is generated randomly like in Seven's code, then it will randomly spawn as one of the six weapons, and the model will match.

          "Maybe it works, at least the code compiles without complaining."

          Be very careful about this. The compiler will only catch code that breaks, not code that causes glitches or unwanted behavior. A rule of thumb: whenever you make even the slightest, most minute change to the code, play-test the hell out of it. Purposefully try to make your code crash the game or glitch out. Try, try, and try again. If nothing bad or unwanted happens, your code *might* be good...you'd be surprised how many little bugs you'll find after hours of play-testing a mod, because there are so many dependencies in QC. I remember I once coded underwater behavior for grenades. Through a very long chain of events, this sporatically altered the nailgun's nail behavior. I had to track down the bug one line of code at a time. It was frustrating because it was something internal, i.e. beyond QC and deeper into the engine. My workaround was a function re-write.
          Last edited by Dutch; 08-29-2017, 04:56 AM.
          'Replacement Player Models' Project

          Comment


          • #6
            *Blush*
            Still learning :-) Thanks for the advice!
            I once was a Ranger like you. But then i took a rocket to the knee.
            My little gore mod : http://quakeone.com/forum/quake-mod-...76473-gore-mod

            Comment


            • #7
              Dutch, my code works as is as far as i can tell. when i pick up a rocket launcher it's a rocket launcher ect...

              whoops i think you were just replying to TheKillingJoke in reguards to how he suggested doing things.

              this is my current function.

              Code:
              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();}
              
              
              };
              Last edited by ceriux; 08-29-2017, 07:29 PM.

              Comment


              • #8
                Originally posted by ceriux View Post
                Dutch, my code works as is as far as i can tell. when i pick up a rocket launcher it's a rocket launcher ect...
                You are a really funny man ceriux.

                Comment


                • #9
                  Originally posted by ceriux View Post
                  Dutch, my code works as is as far as i can tell. when i pick up a rocket launcher it's a rocket launcher ect...

                  whoops i think you were just replying to TheKillingJoke in reguards to how he suggested doing things.

                  this is my current function.

                  Code:
                  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();}
                  
                  
                  };
                  Yes sir, I was replying to TheKillingJoke.

                  Your code looks solid but you may want to replace "else if (r < 6)" with just "else". This achieves two things:

                  1. All other possibilities are eliminated, meaning that there will always be a satisfactory condition. It's likely this won't crash in game, but it's a good habit in my experience.
                  2. The random() function returns a value between 0 and 1, including the values 0 and 1. If the value is indeed 1 (small chance, but possible), and your if statements don't check for a value of 6 (only values below 6), this could cause a game crash.
                  'Replacement Player Models' Project

                  Comment


                  • #10
                    So i should do if (r =<6) ?

                    Comment


                    • #11
                      Well, you could. And it will definitely work, all of the time, because your range of possible values is 0 to 6, and all of your if statements cover this range if you include <= 6. But as good practice, whenever you use an 'else if' following an 'if', you want to wrap it all up with just a lone 'else'. This guarantees that you'll never get a value that doesn't satisfy, which could potentially cause a game crash or unexpected behavior. Example:

                      local float r;

                      r = random();

                      if (r < 0.5)
                      {}
                      else if (r < 0.75)
                      {}
                      else
                      {}

                      Obviously the final else covers the range of 0.75 to 1. But in more complicated situations, where you don't have absolute control over all resulting values, the lone else covers anything that you didn't implicitly define. Makes for better, more predictable code.
                      'Replacement Player Models' Project

                      Comment


                      • #12
                        @r =<6
                        r <= 6

                        Always put comparison operators before the equal.

                        Last edited by MadGypsy; 08-31-2017, 08:48 AM.
                        http://www.nextgenquake.com

                        Comment


                        • #13
                          Unless you're programming in Erlang, which has =< instead of <= (but still has >= the "right" way around).

                          Comment

                          Working...
                          X