Announcement

Collapse
No announcement yet.

Progs.dat Help

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

  • #16
    ok, that makes sense BUT those constants are all named after entities so it's pretty safe to assume if entities are being represented with float values that those values must represent an ID (of sorts). That being assumed - how can entities share values with entities of a different "type". Entities of the same type (ie.. IT_) all have different float values assigned to them but by simply changing the "type" to (ex IT2_) you can start re-using floats.

    I think I found the answer:

    real rogue code:
    float(float w) RankForWeapon =
    {
    if (w == IT_PLASMA_GUN)
    return 1;
    if (w == IT_LIGHTNING)
    return 2;
    if (w == IT_MULTI_ROCKET)
    return 3;
    if (w == IT_ROCKET_LAUNCHER)
    return 4;
    if (w == IT_LAVA_SUPER_NAILGUN)
    return 5;
    if (w == IT_SUPER_NAILGUN)
    return 6;
    if (w == IT_MULTI_GRENADE)
    return 7;
    if (w == IT_GRENADE_LAUNCHER)
    return 8;
    if (w == IT_LAVA_NAILGUN)
    return 9;
    if (w == IT_SUPER_SHOTGUN)
    return 10;
    if (w == IT_NAILGUN)
    return 11;
    return 12;
    };

    RankForWeapon is a function that accepts and returns a float. It is super safe to assume that ONLY a weapon can access this function. So therefore as long as all the weapons have a unique float, it doesn't matter if every other type of entitity had overlapping floats (in contrast to this group) because every different entity type (weapons, items, etc) will have their own sequestered functions. So, in short - all the float is is an ID. It's used as a comparison value in order to process inventory (and maybe some other "state machine" style functions).

    Gypsy
    http://www.nextgenquake.com

    Comment


    • #17
      That's a very ropey conclusion you've come to. Shall we start at the beginning?

      Go find yourself a jar of pennies (or other low value coins, depending on your local currency). Lay out 23 of them in a row, all of them with the tails side up. Below the coin on the far right, write down the number "1". Now, working right to left, write down a number below each coin that is twice the number of the coin to the right. Feel free to use a calculator if necessary. If the left-most coin doesn't have the number "4194304" below it, then check that you haven't made a mistake. If it's a very different number, then check that you have the correct number of coins.

      These 23 coins represent the .items field of the player. Whenever a coin is tails, ignore the number below it. The number that is in the .items field is equal to the sum of the numbers below coins that are showing heads. Now, to give these numbers some meaning, open defs.qc from the id1 source, and scroll down to the part where all of the IT_ variables are set. Now, each of these numbers will be assigned to one IT_(something) variable. Write down the variable name (feel free to drop the IT_ part or use shorthand) below each value.

      At this point, you're possibly wondering what all of these mean. Why is there ammo in the items field? To answer this question, it's necessary to think about the Quake hud. Most of these flags will be read by the engine, to show something on the hud. For the coins that correspond to weapons, it makes these weapons show up on the hud. For the powerups and the keys, it makes them show up on the hud as well. For the powerups, it also makes the special screen effects happen (as well as the changes to the Quakeguy's face; the pentagram also changes the armor display). The three armor coins tell the engine which icon to display next to how much armor you have. The four ammo coins tell the engine which ammo icon to display next to the large ammo counter. This leaves three that don't appear to do anything to the hud, but possibly did at some point during the development. IT_AXE is the axe, which isn't shown on the hud. IT_EXTRA_WEAPON is there because maybe at some point, they planned for you to have a ninth weapon. IT_SUPERHEALTH is used to show an active mega health, although the hud doesn't display this either.

      (For completion, you're wondering what sets all of the numbers on the hud. .ammo_shells _nails _rockets and _cells set the ammo counters along the top. .health is the health number, .armorvalue is the armor number, .currentammo is the ammo number. The runes are done in a rather complicated way, that's beyond the scope of this lesson.)

      There is one other variable that the engine looks at to set the hud. .weapon controls which weapon icon in the hud is highlighted as the current weapon. If .weapon doesn't match any of the numbers that its expecting, then it won't hightlight one.

      Note that this is what happens in id1. The missionpacks do subtly different things (which mostly involves a second row of coins called .items2 and coin labels in variable names that begin IT2_, and only the coins numbered "1" to "256" are looked at by the engine; I believe that .weapon is handled slightly differenly as well, but I don't have the engine source code handy at the moment to check this), but follow the same principles.

      Now, here are some immutable rules. You cannot add any more coins to any of those rows. You cannot change the numbers under any of coins. You can change the labels, but this may cause the engine hud to display things incorrectly. Trying to "add" or "flip" a coin with another number, will actually affect all coins with numbers that add up to the number that you are using (37 will affect the "32" "4" and "1" coins, for example).

      What you can do, is use variables (and rows of coins) that the engine isn't paying attention to for hud, but when doing this, you will be starting on a long journey. That's not to say that this is impossible, or even overly complicated. But make sure that you're drawing a map as you travel. You never know when you might need it...
      16:03:04 <gb> when I put in a sng, I think I might need nails
      16:03:30 <gb> the fact that only playtesting tells me that probably means that my mind is a sieve

      Comment


      • #18
        Wow, ..thank you. That really put it in perspective for me. I wasn't entirely wrong though. The numbers do represent a state machine. I've only been messing with Quake C for a whole 3 days, I have a lot to learn.

        AS3 has a similar system converting #hex to int when dealing with colors. The red channel is 0 to 255, the green channel is 256 * (1 to 256) and the blue channel is (256�) * (1 to 256 ) +1. It's the same concept. The resulting number can only be one possible combination of the RGB channels. Your tutorial absolutely explains why they chose to double preceding numbers. This way, one number code gives an absolute definition of the entire state of your inventory.

        Maybe you could give me a brief on what this is all about:
        ex. float() random = #7;

        I don't get the #NUM part.

        Thank you for taking the time to explain this to me,
        Gypsy

        P.S. I love this forum. Everyone is very responsive and helpful. I intend to take all of this knowledge and make a (hopefully) remarkable contribution to this community. I haven't met a program language that I am unable to learn. I don't see QuakeC being the first. Overall this doesn't even seem that complicated. I just don't have a full mental scope of progs.dat yet.
        Last edited by MadGypsy; 02-06-2011, 10:09 PM.
        http://www.nextgenquake.com

        Comment


        • #19
          The numbers do represent a state machine. - The general term used for this is "bit flags", but yes, I think you get the idea.

          float() random = #7; - There are often times when the QuakeC needs to use a function that is defined by the engine, as opposed to one that it defines itself. These functions are called builtin functions. Rather than a normal function definition, they have a definition like that one. Screwy things can happen if the QuakeC tries to call a builtin function that doesn't exist in the engine, (mostly in the form of crashing) but this isn't something that you'll need to worry about if you're not changing that part of the code.

          There's a post I wrote at Inside3d a while ago, that covers in a little bit of depth the general program flow. It covers think functions a lot more than touch functions (think and touch are the two main ways that stuff happens in the code), but both have their uses.

          One quirk that you will possibly have noticed if you've looked at items.qc for more than a few seconds: In the item pickup functions, self is the item being touched, other is what touched it (and one of the first things they do, is check that other is a player, and if not, it stops doing the rest of the function).
          16:03:04 <gb> when I put in a sng, I think I might need nails
          16:03:30 <gb> the fact that only playtesting tells me that probably means that my mind is a sieve

          Comment


          • #20
            This way, one number code gives an absolute definition of the entire state of your inventory.
            Yes.

            The other major thing where this is used are spawnflags (.spawnflags field).
            Scout's Journey
            Rune of Earth Magic

            Comment


            • #21
              Originally posted by Lardarse View Post

              float() random = #7; - There are often times when the QuakeC needs to use a function that is defined by the engine, as opposed to one that it defines itself. These functions are called builtin functions. Rather than a normal function definition, they have a definition like that one.
              Hmm.. where can I obtain a list of the functions that each #NUM correspond to? OR are you saying that this system (ex #NUM) tells the engine to use it's built-in random() function and the #NUM is "somewhat" arbritrary? For instance if the call to a "built-in" function preceding this one was float() foo = #10 then the example above could work just as well as float() random = #11?

              Originally posted by Lardarse View Post
              Screwy things can happen if the QuakeC tries to call a builtin function that doesn't exist in the engine, (mostly in the form of crashing) but this isn't something that you'll need to worry about if you're not changing that part of the code.
              I intend to change everything. More for the purpose of mastering QuakeC as opposed to reaching some definitive end. Because of this thread I've already scrapped my current map and created an entirely new idea for an episode pack. I already know what new models I intend to introduce, what 2 weapons I intend to introduce and I have a vision of the first two maps in my head. I already started making the first model. I'm sure I will "break" Quake 1000 times before I get everything to work. I'm fine with that.

              The only thing I am not confident of is my ability to make quake-like skins for my models. But maybe if I get a bunch done I can beg Fragger to do my skins for me.

              Gypsy
              Last edited by MadGypsy; 02-07-2011, 03:40 PM.
              http://www.nextgenquake.com

              Comment


              • #22
                I think I get this now. I have been studying the Quake Specs (defs.qc primarily). I noticed that it says (ex #50 was removed) when i couple this info with the fact that you said they were built into the engine. I come to this conclusion... When I asked you where I could get a list of the functions that #NUM correspond to.. That is the list. So in a sense (or maybe literally) somewhere in the engine is the C equivalent of:

                public function #7 ():int {
                (Math.random() > .50) ? return 1 : return 0;
                }

                and quake makes a prototype of it with

                float() random = #7;

                is this correct?

                Gypsy
                Last edited by MadGypsy; 02-07-2011, 10:36 PM.
                http://www.nextgenquake.com

                Comment


                • #23
                  void PF_random (void)
                  {
                  float num;
                  num = (rand ()&0x7fff) / ((float)0x7fff);
                  G_FLOAT(OFS_RETURN) = num;
                  }

                  and:

                  builtin_t pr_builtin[] =
                  {
                  <stripped entries 0 through 6>
                  PF_random, // float() random = #7;
                  <stripped 8 through whatever the highest is>
                  };


                  seriously though, the 7 is just a magic number, its what makes random random, and there's nothing more random than magic numbers.
                  Some Game Thing

                  Comment


                  • #24
                    So float() random = #7 = builtin_t pr_builtin[7]?

                    I'm assuming that's an array since the square brackets and the fact that you started your <strip> at 0.

                    Gypsy
                    Last edited by MadGypsy; 02-08-2011, 09:46 PM.
                    http://www.nextgenquake.com

                    Comment

                    Working...
                    X