Blows tables

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • wobbly
    Prophet
    • May 2012
    • 2631

    Blows tables

    Someone asked, so here they are. These are all from player-calcs.c, the multipliers & minimum weight are in class.txt

    As you can see there are instructions to read it, though how easy they are to follow...

    Code:
    /**
     * This table is used to help calculate the number of blows the player can
     * make in a single round of attacks (one player turn) with a normal weapon.
     *
     * This number ranges from a single blow/round for weak players to up to six
     * blows/round for powerful warriors.
     *
     * Note that certain artifacts and ego-items give "bonus" blows/round.
     *
     * First, from the player class, we extract some values:
     *
     *    Warrior --> num = 6; mul = 5; div = MAX(30, weapon_weight);
     *    Mage    --> num = 4; mul = 2; div = MAX(40, weapon_weight);
     *    Priest  --> num = 4; mul = 3; div = MAX(35, weapon_weight);
     *    Rogue   --> num = 5; mul = 4; div = MAX(30, weapon_weight);
     *    Ranger  --> num = 5; mul = 4; div = MAX(35, weapon_weight);
     *    Paladin --> num = 5; mul = 5; div = MAX(30, weapon_weight);
     * (all specified in class.txt now)
     *
     * To get "P", we look up the relevant "adj_str_blow[]" (see above),
     * multiply it by "mul", and then divide it by "div", rounding down.
     *
     * To get "D", we look up the relevant "adj_dex_blow[]" (see above).
     *
     * Then we look up the energy cost of each blow using "blows_table[P][D]".
     * The player gets blows/round equal to 100/this number, up to a maximum of
     * "num" blows/round, plus any "bonus" blows/round.
     */
    static const int blows_table[12][12] =
    {
    	/* P */
       /* D:   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11+ */
       /* DEX: 3,   10,  17,  /20, /40, /60, /80, /100,/120,/150,/180,/200 */
    
    	/* 0  */
    	{  100, 100, 95,  85,  75,  60,  50,  42,  35,  30,  25,  23 },
    
    	/* 1  */
    	{  100, 95,  85,  75,  60,  50,  42,  35,  30,  25,  23,  21 },
    
    	/* 2  */
    	{  95,  85,  75,  60,  50,  42,  35,  30,  26,  23,  21,  20 },
    
    	/* 3  */
    	{  85,  75,  60,  50,  42,  36,  32,  28,  25,  22,  20,  19 },
    
    	/* 4  */
    	{  75,  60,  50,  42,  36,  33,  28,  25,  23,  21,  19,  18 },
    
    	/* 5  */
    	{  60,  50,  42,  36,  33,  30,  27,  24,  22,  21,  19,  17 },
    
    	/* 6  */
    	{  50,  42,  36,  33,  30,  27,  25,  23,  21,  20,  18,  17 },
    
    	/* 7  */
    	{  42,  36,  33,  30,  28,  26,  24,  22,  20,  19,  18,  17 },
    
    	/* 8  */
    	{  36,  33,  30,  28,  26,  24,  22,  21,  20,  19,  17,  16 },
    
    	/* 9  */
    	{  35,  32,  29,  26,  24,  22,  21,  20,  19,  18,  17,  16 },
    
    	/* 10 */
    	{  34,  30,  27,  25,  23,  22,  21,  20,  19,  18,  17,  16 },
    
    	/* 11+ */
    	{  33,  29,  26,  24,  22,  21,  20,  19,  18,  17,  16,  15 },
       /* DEX: 3,   10,  17,  /20, /40, /60, /80, /100,/120,/150,/180,/200 */
    Code:
    /**
     * Stat Table (STR) -- help index into the "blow" table
     */
    const int adj_str_blow[STAT_RANGE] =
    {
    	3	/* 3 */,
    	4	/* 4 */,
    	5	/* 5 */,
    	6	/* 6 */,
    	7	/* 7 */,
    	8	/* 8 */,
    	9	/* 9 */,
    	10	/* 10 */,
    	11	/* 11 */,
    	12	/* 12 */,
    	13	/* 13 */,
    	14	/* 14 */,
    	15	/* 15 */,
    	16	/* 16 */,
    	17	/* 17 */,
    	20 /* 18/00-18/09 */,
    	30 /* 18/10-18/19 */,
    	40 /* 18/20-18/29 */,
    	50 /* 18/30-18/39 */,
    	60 /* 18/40-18/49 */,
    	70 /* 18/50-18/59 */,
    	80 /* 18/60-18/69 */,
    	90 /* 18/70-18/79 */,
    	100 /* 18/80-18/89 */,
    	110 /* 18/90-18/99 */,
    	120 /* 18/100-18/109 */,
    	130 /* 18/110-18/119 */,
    	140 /* 18/120-18/129 */,
    	150 /* 18/130-18/139 */,
    	160 /* 18/140-18/149 */,
    	170 /* 18/150-18/159 */,
    	180 /* 18/160-18/169 */,
    	190 /* 18/170-18/179 */,
    	200 /* 18/180-18/189 */,
    	210 /* 18/190-18/199 */,
    	220 /* 18/200-18/209 */,
    	230 /* 18/210-18/219 */,
    	240 /* 18/220+ */
    };
    Code:
    /**
     * Stat Table (DEX) -- index into the "blow" table
     */
    static const int adj_dex_blow[STAT_RANGE] =
    {
    	0	/* 3 */,
    	0	/* 4 */,
    	0	/* 5 */,
    	0	/* 6 */,
    	0	/* 7 */,
    	0	/* 8 */,
    	0	/* 9 */,
    	1	/* 10 */,
    	1	/* 11 */,
    	1	/* 12 */,
    	1	/* 13 */,
    	1	/* 14 */,
    	1	/* 15 */,
    	1	/* 16 */,
    	2	/* 17 */,
    	2	/* 18/00-18/09 */,
    	2	/* 18/10-18/19 */,
    	3	/* 18/20-18/29 */,
    	3	/* 18/30-18/39 */,
    	4	/* 18/40-18/49 */,
    	4	/* 18/50-18/59 */,
    	5	/* 18/60-18/69 */,
    	5	/* 18/70-18/79 */,
    	6	/* 18/80-18/89 */,
    	6	/* 18/90-18/99 */,
    	7	/* 18/100-18/109 */,
    	7	/* 18/110-18/119 */,
    	8	/* 18/120-18/129 */,
    	8	/* 18/130-18/139 */,
    	8	/* 18/140-18/149 */,
    	9	/* 18/150-18/159 */,
    	9	/* 18/160-18/169 */,
    	9	/* 18/170-18/179 */,
    	10	/* 18/180-18/189 */,
    	10	/* 18/190-18/199 */,
    	11	/* 18/200-18/209 */,
    	11	/* 18/210-18/219 */,
    	11	/* 18/220+ */
    };
  • gglibertine
    Adept
    • Dec 2007
    • 234

    #2
    Thanks for posting. I'm going to enlist my husband (who does code) to help me decipher this.

    Comment

    • AnonymousHero
      Veteran
      • Jun 2007
      • 1393

      #3
      Originally posted by gglibertine
      Thanks for posting. I'm going to enlist my husband (who does code) to help me decipher this.
      I hope he has the patience of a saint because it's infuriatingly indirect. Yes, it's "only" two levels at first sight, but then you realize that there are the two dimensions of STR/DEX... The quickest way (for me) was honestly just putting DEX+STR + the tables into a spreadsheet and doing the weird "indexing dance" from there. (That doesn't help you optimize, directly, but at least you can do hypotheticals pretty easily.)

      This mess could really stand to be simplified, especially given that these numbers seem quite arbitrary. (Of course, it might have been originally derived from a function, but saved as concrete numbers. Even if it happened in the 1980s I'm not sure if there's any excuse for not just having that in the code and pre-computing the tables on startup, so this parenthetical hypothesis seems kind of dubious...)

      Comment

      • Werbaer
        Adept
        • Aug 2014
        • 182

        #4
        Originally posted by AnonymousHero
        This mess could really stand to be simplified, especially given that these numbers seem quite arbitrary. (Of course, it might have been originally derived from a function, but saved as concrete numbers.
        Edit: Disregard this comment. As wobbly pointed out, i looked at the wrong table.

        Comment from an old version:
        Code:
         * This table allows quick conversion from "speed" to "energy"
         * The basic function WAS ((S>=110) ? (S-110) : (100 / (120-S)))
         * Note that table access is *much* quicker than computation.
         *
         * Note that the table has been changed at high speeds.  From
         * "Slow (-40)" to "Fast (+30)" is pretty much unchanged, but
         * at speeds above "Fast (+30)", one approaches an asymptotic
         * effective limit of 50 energy per turn.
        Last edited by Werbaer; September 27, 2018, 11:56.

        Comment

        • wobbly
          Prophet
          • May 2012
          • 2631

          #5
          That's the speed tables isn't it? A different table for showing how much energy you gain/turn at various speeds.

          Comment

          • Derakon
            Prophet
            • Dec 2009
            • 9022

            #6
            Ahh, the days when the performance implications of table lookup vs. doing division was an issue that deserved serious consideration.

            Comment

            • wobbly
              Prophet
              • May 2012
              • 2631

              #7
              Perhaps an example is helpful? A human warrior with recommended stats:
              18/20 str
              18/20 dex
              dagger weight is 12 deci-pounds, however Min warrior weight for calculations is 30.
              warrior class multiplier = 5

              Looking up 18/20 dex in the 3rd table (dex index) we get 3. That is the column number. Looking at table 1, column 3 you will see it's actually got 18/20 dex written on it.

              Looking up 18/20 str in the 2nd table we get 40.
              40 x 5 = 200 ( adj_str x class multiplier)
              200 / 30 = 6.66 (adj_str x class multiplier / weapon weight)
              we round down - row 6

              reading column 3, row 6 we get 33. This is energy/blow. 3 blows would take 99 energy.

              You get your turn when energy reaches 100 (You & all monsters gain energy every "game tick" depending on speed, this is the table Werbaer mentioned). So our warrior gets 3 blows spending 99 energy then waits for his/her energy to reach 100 again. If he/she kills something with 2 blows he/she spends 66 energy instead (I believe you don't get the final blow till you reach 100 again but would have to check)

              Note 1.5 blows (66 energy/turn) technically means 1 blow costing 66 energy. If you were dead on 100 energy, you'd hit once and spend 66 leaving 34 energy. You would then reach 100 energy (your next turn) sooner.
              Last edited by wobbly; September 27, 2018, 19:37.

              Comment

              • Pete Mack
                Prophet
                • Apr 2007
                • 6883

                #8
                I am not convinced that floating point would be better here: integer arithmetic has no pesky round-off issues, and working by percentages is certainly no real problem conceptually.


                Originally posted by Derakon
                Ahh, the days when the performance implications of table lookup vs. doing division was an issue that deserved serious consideration.

                Comment

                Working...
                😀
                😂
                🥰
                😘
                🤢
                😎
                😞
                😡
                👍
                👎