Shendare

Old vs. New EQEmu Damage Bonus Functions

Sep 19th, 2015
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 26.46 KB | None | 0 0
  1. // TempEQEmuDamageBonusComparison.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include <io.h>
  6. #include <stdio.h>
  7.  
  8. // "fprintf isn't secure, use fprintf_s instead" -- Visual Studio error being safe and enforcing functions with buffer override protection
  9. #pragma warning(disable : 4996)
  10.  
  11. typedef unsigned __int8 uint8;
  12.  
  13. enum ItemUseTypes : uint8
  14. {
  15.     /*9138*/    ItemType1HSlash = 0,
  16.     /*9141*/    ItemType2HSlash,
  17.     /*9140*/    ItemType1HPiercing,
  18.     /*9139*/    ItemType1HBlunt,
  19.     /*9142*/    ItemType2HBlunt,
  20.     /*5504*/    ItemTypeBow,
  21.     /*----*/    ItemTypeUnknown1,
  22.     /*----*/    ItemTypeLargeThrowing,
  23.     /*5505*/    ItemTypeShield,
  24.     /*5506*/    ItemTypeScroll,
  25.     /*5507*/    ItemTypeArmor,
  26.     /*5508*/    ItemTypeMisc,           // a lot of random crap has this item use.
  27.     /*7564*/    ItemTypeLockPick,
  28.     /*----*/    ItemTypeUnknown2,
  29.     /*5509*/    ItemTypeFood,
  30.     /*5510*/    ItemTypeDrink,
  31.     /*5511*/    ItemTypeLight,
  32.     /*5512*/    ItemTypeCombinable,     // not all stackable items are this use...
  33.     /*5513*/    ItemTypeBandage,
  34.     /*----*/    ItemTypeSmallThrowing,
  35.     /*----*/    ItemTypeSpell,          // spells and tomes
  36.     /*5514*/    ItemTypePotion,
  37.     /*----*/    ItemTypeUnknown3,
  38.     /*0406*/    ItemTypeWindInstrument,
  39.     /*0407*/    ItemTypeStringedInstrument,
  40.     /*0408*/    ItemTypeBrassInstrument,
  41.     /*0405*/    ItemTypePercussionInstrument,
  42.     /*5515*/    ItemTypeArrow,
  43.     /*----*/    ItemTypeUnknown4,
  44.     /*5521*/    ItemTypeJewelry,
  45.     /*----*/    ItemTypeSkull,
  46.     /*5516*/    ItemTypeBook,           // skill-up tomes/books? (would probably need a pp flag if true...)
  47.     /*5517*/    ItemTypeNote,
  48.     /*5518*/    ItemTypeKey,
  49.     /*----*/    ItemTypeCoin,
  50.     /*5520*/    ItemType2HPiercing,
  51.     /*----*/    ItemTypeFishingPole,
  52.     /*----*/    ItemTypeFishingBait,
  53.     /*5519*/    ItemTypeAlcohol,
  54.     /*----*/    ItemTypeKey2,           // keys and satchels?? (questable keys?)
  55.     /*----*/    ItemTypeCompass,
  56.     /*----*/    ItemTypeUnknown5,
  57.     /*----*/    ItemTypePoison,         // might be wrong, but includes poisons
  58.     /*----*/    ItemTypeUnknown6,
  59.     /*----*/    ItemTypeUnknown7,
  60.     /*5522*/    ItemTypeMartial,
  61.     /*----*/    ItemTypeUnknown8,
  62.     /*----*/    ItemTypeUnknown9,
  63.     /*----*/    ItemTypeUnknown10,
  64.     /*----*/    ItemTypeUnknown11,
  65.     /*----*/    ItemTypeSinging,
  66.     /*5750*/    ItemTypeAllInstrumentTypes,
  67.     /*5776*/    ItemTypeCharm,
  68.     /*----*/    ItemTypeDye,
  69.     /*----*/    ItemTypeAugmentation,
  70.     /*----*/    ItemTypeAugmentationSolvent,
  71.     /*----*/    ItemTypeAugmentationDistiller,
  72.     /*----*/    ItemTypeUnknown12,
  73.     /*----*/    ItemTypeFellowshipKit,
  74.     /*----*/    ItemTypeUnknown13,
  75.     /*----*/    ItemTypeRecipe,
  76.     /*----*/    ItemTypeAdvancedRecipe,
  77.     /*----*/    ItemTypeJournal,        // only one(1) database entry
  78.     /*----*/    ItemTypeAltCurrency,    // alt-currency (as opposed to coinage)
  79.     /*5881*/    ItemTypePerfectedAugmentationDistiller,
  80.     /*----*/    _ItemTypeCount
  81. };
  82.  
  83. uint8 GetWeaponDamageBonusOld(uint8 Level, uint8 ItemType, uint8 Delay)
  84. {
  85.     // This function calculates and returns the damage bonus for the weapon identified by the parameter "Weapon".
  86.     // Modified 9/21/2008 by Cantus
  87.  
  88.     // Assert: This function should only be called for hits by the mainhand, as damage bonuses apply only to the
  89.     // weapon in the primary slot. Be sure to check that Hand == MainPrimary before calling.
  90.  
  91.     // Assert: The caller should ensure that Weapon is actually a weapon before calling this function.
  92.     // The ItemInst::IsWeapon() method can be used to quickly determine this.
  93.  
  94.     // Assert: This function should not be called if the player's level is below 28, as damage bonuses do not begin
  95.     // to apply until level 28.
  96.  
  97.     // Assert: This function should not be called unless the player is a melee class, as casters do not receive a damage bonus.
  98.  
  99.     if (ItemType == ItemType1HSlash || ItemType == ItemType1HBlunt || ItemType == ItemTypeMartial || ItemType == ItemType1HPiercing)
  100.     {
  101.         // The weapon in the player's main (primary) hand is a one-handed weapon, or there is no item equipped at all.
  102.         //
  103.         // According to player posts on Allakhazam, 1H damage bonuses apply to bare fists (nothing equipped in the mainhand,
  104.         // as indicated by Weapon == nullptr).
  105.         //
  106.         // The following formula returns the correct damage bonus for all 1H weapons:
  107.  
  108.         return (uint8)((Level - 25) / 3);
  109.     }
  110.  
  111.     // If we've gotten to this point, the weapon in the mainhand is a two-handed weapon.
  112.     // Calculating damage bonuses for 2H weapons is more complicated, as it's based on PC level AND the delay of the weapon.
  113.     // The formula to calculate 2H bonuses is HIDEOUS. It's a huge conglomeration of ternary operators and multiple operations.
  114.     //
  115.     // The following is a hybrid approach. In cases where the Level and Delay merit a formula that does not use many operators,
  116.     // the formula is used. In other cases, lookup tables are used for speed.
  117.     // Though the following code may look bloated and ridiculous, it's actually a very efficient way of calculating these bonuses.
  118.  
  119.     // Player Level is used several times in the code below, so save it into a variable.
  120.     // If Level were an ordinary function, this would DEFINITELY make sense, as it'd cut back on all of the function calling
  121.     // overhead involved with multiple calls to Level. But in this case, Level is a simple, inline accessor method.
  122.     // So it probably doesn't matter. If anyone knows for certain that there is no overhead involved with calling Level,
  123.     // as I suspect, then please feel free to delete the following line, and replace all occurences of "ucPlayerLevel" with "Level".
  124.     uint8 ucPlayerLevel = (uint8)Level;
  125.  
  126.     // The following may look cleaner, and would certainly be easier to understand, if it was
  127.     // a simple 53x150 cell matrix.
  128.     //
  129.     // However, that would occupy 7,950 Bytes of memory (7.76 KB), and would likely result
  130.     // in "thrashing the cache" when performing lookups.
  131.     //
  132.     // Initially, I thought the best approach would be to reverse-engineer the formula used by
  133.     // Sony/Verant to calculate these 2H weapon damage bonuses. But the more than Reno and I
  134.     // worked on figuring out this formula, the more we're concluded that the formula itself ugly
  135.     // (that is, it contains so many operations and conditionals that it's fairly CPU intensive).
  136.     // Because of that, we're decided that, in most cases, a lookup table is the most efficient way
  137.     // to calculate these damage bonuses.
  138.     //
  139.     // The code below is a hybrid between a pure formulaic approach and a pure, brute-force
  140.     // lookup table. In cases where a formula is the best bet, I use a formula. In other places
  141.     // where a formula would be ugly, I use a lookup table in the interests of speed.
  142.  
  143.     if (Delay <= 27)
  144.     {
  145.         // Damage Bonuses for all 2H weapons with delays of 27 or less are identical.
  146.         // They are the same as the damage bonus would be for a corresponding 1H weapon, plus one.
  147.         // This formula applies to all levels 28-80, and will probably continue to apply if
  148.  
  149.         // the level cap on Live ever is increased beyond 80.
  150.  
  151.         return (ucPlayerLevel - 22) / 3;
  152.     }
  153.  
  154.     if (ucPlayerLevel == 65 && Delay <= 59)
  155.     {
  156.         // Consider these two facts:
  157.         // * Level 65 is the maximum level on many EQ Emu servers.
  158.         // * If you listed the levels of all characters logged on to a server, odds are that the number you'll
  159.         // see most frequently is level 65. That is, there are more level 65 toons than any other single level.
  160.         //
  161.         // Therefore, if we can optimize this function for level 65 toons, we're speeding up the server!
  162.         //
  163.         // With that goal in mind, I create an array of Damage Bonuses for level 65 characters wielding 2H weapons with
  164.         // delays between 28 and 59 (inclusive). I suspect that this one small lookup array will therefore handle
  165.         // many of the calls to this function.
  166.  
  167.         static const uint8 ucLevel65DamageBonusesForDelays28to59[] = { 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 42, 42, 42, 45, 45, 47, 48, 49, 49, 51, 51, 52, 53, 54, 54, 56, 56, 57, 58, 59 };
  168.  
  169.         return ucLevel65DamageBonusesForDelays28to59[Delay - 28];
  170.     }
  171.  
  172.     if (ucPlayerLevel > 65)
  173.     {
  174.         if (ucPlayerLevel > 80)
  175.         {
  176.             // As level 80 is currently the highest achievable level on Live, we only include
  177.             // damage bonus information up to this level.
  178.             //
  179.             // If there is a custom EQEmu server that allows players to level beyond 80, the
  180.             // damage bonus for their 2H weapons will simply not increase beyond their damage
  181.             // bonus at level 80.
  182.  
  183.             ucPlayerLevel = 80;
  184.         }
  185.  
  186.         // Lucy does not list a chart of damage bonuses for players levels 66+,
  187.         // so my original version of this function just applied the level 65 damage
  188.         // bonus for level 66+ toons. That sucked for higher level toons, as their
  189.         // 2H weapons stopped ramping up in DPS as they leveled past 65.
  190.         //
  191.         // Thanks to the efforts of two guys, this is no longer the case:
  192.         //
  193.         // Janusd (Zetrakyl) ran a nifty query against the PEQ item database to list
  194.         // the name of an example 2H weapon that represents each possible unique 2H delay.
  195.         //
  196.         // Romai then wrote an excellent script to automatically look up each of those
  197.         // weapons, open the Lucy item page associated with it, and iterate through all
  198.         // levels in the range 66 - 80. He saved the damage bonus for that weapon for
  199.         // each level, and that forms the basis of the lookup tables below.
  200.  
  201.         if (Delay <= 59)
  202.         {
  203.             static const uint8 ucDelay28to59Levels66to80[32][15] =
  204.             {
  205.                 /*                          Level:                              */
  206.                 /*   66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 */
  207.  
  208.                 { 36, 37, 38, 39, 41, 42, 43, 44, 45, 47, 49, 49, 49, 50, 53 }, /* Delay = 28 */
  209.                 { 36, 38, 38, 39, 42, 43, 43, 45, 46, 48, 49, 50, 51, 52, 54 }, /* Delay = 29 */
  210.                 { 37, 38, 39, 40, 43, 43, 44, 46, 47, 48, 50, 51, 52, 53, 55 }, /* Delay = 30 */
  211.                 { 37, 39, 40, 40, 43, 44, 45, 46, 47, 49, 51, 52, 52, 52, 54 }, /* Delay = 31 */
  212.                 { 38, 39, 40, 41, 44, 45, 45, 47, 48, 48, 50, 52, 53, 55, 57 }, /* Delay = 32 */
  213.                 { 38, 40, 41, 41, 44, 45, 46, 48, 49, 50, 52, 53, 54, 56, 58 }, /* Delay = 33 */
  214.                 { 39, 40, 41, 42, 45, 46, 47, 48, 49, 51, 53, 54, 55, 57, 58 }, /* Delay = 34 */
  215.                 { 39, 41, 42, 43, 46, 46, 47, 49, 50, 52, 54, 55, 56, 57, 59 }, /* Delay = 35 */
  216.                 { 40, 41, 42, 43, 46, 47, 48, 50, 51, 53, 55, 55, 56, 58, 60 }, /* Delay = 36 */
  217.                 { 40, 42, 43, 44, 47, 48, 49, 50, 51, 53, 55, 56, 57, 59, 61 }, /* Delay = 37 */
  218.                 { 41, 42, 43, 44, 47, 48, 49, 51, 52, 54, 56, 57, 58, 60, 62 }, /* Delay = 38 */
  219.                 { 41, 43, 44, 45, 48, 49, 50, 52, 53, 55, 57, 58, 59, 61, 63 }, /* Delay = 39 */
  220.                 { 43, 45, 46, 47, 50, 51, 52, 54, 55, 57, 59, 60, 61, 63, 65 }, /* Delay = 40 */
  221.                 { 43, 45, 46, 47, 50, 51, 52, 54, 55, 57, 59, 60, 61, 63, 65 }, /* Delay = 41 */
  222.                 { 44, 46, 47, 48, 51, 52, 53, 55, 56, 58, 60, 61, 62, 64, 66 }, /* Delay = 42 */
  223.                 { 46, 48, 49, 50, 53, 54, 55, 58, 59, 61, 63, 64, 65, 67, 69 }, /* Delay = 43 */
  224.                 { 47, 49, 50, 51, 54, 55, 56, 58, 59, 61, 64, 65, 66, 68, 70 }, /* Delay = 44 */
  225.                 { 48, 50, 51, 52, 56, 57, 58, 60, 61, 63, 65, 66, 68, 70, 72 }, /* Delay = 45 */
  226.                 { 50, 52, 53, 54, 57, 58, 59, 62, 63, 65, 67, 68, 69, 71, 74 }, /* Delay = 46 */
  227.                 { 50, 52, 53, 55, 58, 59, 60, 62, 63, 66, 68, 69, 70, 72, 74 }, /* Delay = 47 */
  228.                 { 51, 53, 54, 55, 58, 60, 61, 63, 64, 66, 69, 69, 71, 73, 75 }, /* Delay = 48 */
  229.                 { 52, 54, 55, 57, 60, 61, 62, 65, 66, 68, 70, 71, 73, 75, 77 }, /* Delay = 49 */
  230.                 { 53, 55, 56, 57, 61, 62, 63, 65, 67, 69, 71, 72, 74, 76, 78 }, /* Delay = 50 */
  231.                 { 53, 55, 57, 58, 61, 62, 64, 66, 67, 69, 72, 73, 74, 77, 79 }, /* Delay = 51 */
  232.                 { 55, 57, 58, 59, 63, 64, 65, 68, 69, 71, 74, 75, 76, 78, 81 }, /* Delay = 52 */
  233.                 { 57, 55, 59, 60, 63, 65, 66, 68, 70, 72, 74, 76, 77, 79, 82 }, /* Delay = 53 */
  234.                 { 56, 58, 59, 61, 64, 65, 67, 69, 70, 73, 75, 76, 78, 80, 82 }, /* Delay = 54 */
  235.                 { 57, 59, 61, 62, 66, 67, 68, 71, 72, 74, 77, 78, 80, 82, 84 }, /* Delay = 55 */
  236.                 { 58, 60, 61, 63, 66, 68, 69, 71, 73, 75, 78, 79, 80, 83, 85 }, /* Delay = 56 */
  237.  
  238.                 /* Important Note: Janusd's search for 2H weapons did not find  */
  239.                 /* any 2H weapon with a delay of 57. Therefore the values below */
  240.                 /* are interpolated, not exact!                                 */
  241.                 { 59, 61, 62, 64, 67, 69, 70, 72, 74, 76, 77, 78, 81, 84, 86 }, /* Delay = 57 INTERPOLATED */
  242.  
  243.                 { 60, 62, 63, 65, 68, 70, 71, 74, 75, 78, 80, 81, 83, 85, 88 }, /* Delay = 58 */
  244.  
  245.                 /* Important Note: Janusd's search for 2H weapons did not find  */
  246.                 /* any 2H weapon with a delay of 59. Therefore the values below */
  247.                 /* are interpolated, not exact!                                 */
  248.                 { 60, 62, 64, 65, 69, 70, 72, 74, 76, 78, 81, 82, 84, 86, 89 }, /* Delay = 59 INTERPOLATED */
  249.             };
  250.  
  251.             return ucDelay28to59Levels66to80[Delay - 28][ucPlayerLevel - 66];
  252.         }
  253.         else
  254.         {
  255.             // Delay is 60+
  256.  
  257.             const static uint8 ucDelayOver59Levels66to80[6][15] =
  258.             {
  259.                 /*                          Level:                              */
  260.                 /*   66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 */
  261.  
  262.                 { 61, 63, 65, 66, 70, 71, 73, 75, 77, 79, 82, 83, 85, 87, 90 },             /* Delay = 60 */
  263.                 { 65, 68, 69, 71, 75, 76, 78, 80, 82, 85, 87, 89, 91, 93, 96 },             /* Delay = 65 */
  264.  
  265.                 /* Important Note: Currently, the only 2H weapon with a delay   */
  266.                 /* of 66 is not player equippable (it's None/None). So I'm      */
  267.                 /* leaving it commented out to keep this table smaller.         */
  268.                 //{66, 68, 70, 71, 75, 77, 78, 81, 83, 85, 88, 90, 91, 94, 97},             /* Delay = 66 */
  269.  
  270.                 { 70, 72, 74, 76, 80, 81, 83, 86, 88, 88, 90, 95, 97, 99, 102 },                /* Delay = 70 */
  271.                 { 82, 85, 87, 89, 89, 94, 98, 101, 103, 106, 109, 111, 114, 117, 120 },     /* Delay = 85 */
  272.                 { 90, 93, 96, 98, 103, 105, 107, 111, 113, 116, 120, 122, 125, 128, 131 }/* Delay = 95 */
  273.  
  274.                 /* Important Note: Currently, the only 2H weapons with delay    */
  275.                 /* 100 are GM-only items purchased from vendors in Sunset Home  */
  276.                 /* (cshome). Because they are highly unlikely to be used in     */
  277.                 /* combat, I'm commenting it out to keep the table smaller.     */
  278.                 //{95, 98, 101, 103, 108, 110, 113, 116, 119, 122, 126, 128, 131, 134, 138},/* Delay = 100 */
  279.  
  280.                 { 136, 140, 144, 148, 154, 157, 161, 166, 170, 174, 179, 183, 187, 191, 196 }   /* Delay = 150 */
  281.             };
  282.  
  283.             if (Delay < 65)
  284.             {
  285.                 return ucDelayOver59Levels66to80[0][ucPlayerLevel - 66];
  286.             }
  287.             else if (Delay < 70)
  288.             {
  289.                 return ucDelayOver59Levels66to80[1][ucPlayerLevel - 66];
  290.             }
  291.             else if (Delay < 85)
  292.             {
  293.                 return ucDelayOver59Levels66to80[2][ucPlayerLevel - 66];
  294.             }
  295.             else if (Delay < 95)
  296.             {
  297.                 return ucDelayOver59Levels66to80[3][ucPlayerLevel - 66];
  298.             }
  299.             else if (Delay < 150)
  300.             {
  301.                 return ucDelayOver59Levels66to80[4][ucPlayerLevel - 66];
  302.             }
  303.             else
  304.             {
  305.                 return ucDelayOver59Levels66to80[5][ucPlayerLevel - 66];
  306.             }
  307.         }
  308.     }
  309.  
  310.     // If we've gotten to this point in the function without hitting a return statement,
  311.     // we know that the character's level is between 28 and 65, and that the 2H weapon's
  312.     // delay is 28 or higher.
  313.  
  314.     // The Damage Bonus values returned by this function (in the level 28-65 range) are
  315.     // based on a table of 2H Weapon Damage Bonuses provided by Lucy at the following address:
  316.     // http://lucy.allakhazam.com/dmgbonus.html
  317.  
  318.     if (Delay <= 39)
  319.     {
  320.         if (ucPlayerLevel <= 53)
  321.         {
  322.             // The Damage Bonus for all 2H weapons with delays between 28 and 39 (inclusive) is the same for players level 53 and below...
  323.             static const uint8 ucDelay28to39LevelUnder54[] = { 1, 1, 2, 3, 3, 3, 4, 5, 5, 6, 6, 6, 8, 8, 8, 9, 9, 10, 11, 11, 11, 12, 13, 14, 16, 17 };
  324.  
  325.             // As a note: The following formula accurately calculates damage bonuses for 2H weapons with delays in the range 28-39 (inclusive)
  326.             // for characters levels 28-50 (inclusive):
  327.             // return ( (ucPlayerLevel - 22) / 3 ) + ( (ucPlayerLevel - 25) / 5 );
  328.             //
  329.             // However, the small lookup array used above is actually much faster. So we'll just use it instead of the formula
  330.             //
  331.             // (Thanks to Reno for helping figure out the above formula!)
  332.  
  333.             return ucDelay28to39LevelUnder54[ucPlayerLevel - 28];
  334.         }
  335.         else
  336.         {
  337.             // Use a matrix to look up the damage bonus for 2H weapons with delays between 28 and 39 wielded by characters level 54 and above.
  338.             static const uint8 ucDelay28to39Level54to64[12][11] =
  339.             {
  340.                 /*                      Level:                  */
  341.                 /*   54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 */
  342.  
  343.                 { 17, 21, 21, 23, 25, 26, 28, 30, 31, 31, 33 }, /* Delay = 28 */
  344.                 { 17, 21, 22, 23, 25, 26, 29, 30, 31, 32, 34 }, /* Delay = 29 */
  345.                 { 18, 21, 22, 23, 25, 27, 29, 31, 32, 32, 34 }, /* Delay = 30 */
  346.                 { 18, 21, 22, 23, 25, 27, 29, 31, 32, 33, 34 }, /* Delay = 31 */
  347.                 { 18, 21, 22, 24, 26, 27, 30, 32, 32, 33, 35 }, /* Delay = 32 */
  348.                 { 18, 21, 22, 24, 26, 27, 30, 32, 33, 34, 35 }, /* Delay = 33 */
  349.                 { 18, 22, 22, 24, 26, 28, 30, 32, 33, 34, 36 }, /* Delay = 34 */
  350.                 { 18, 22, 23, 24, 26, 28, 31, 33, 34, 34, 36 }, /* Delay = 35 */
  351.                 { 18, 22, 23, 25, 27, 28, 31, 33, 34, 35, 37 }, /* Delay = 36 */
  352.                 { 18, 22, 23, 25, 27, 29, 31, 33, 34, 35, 37 }, /* Delay = 37 */
  353.                 { 18, 22, 23, 25, 27, 29, 32, 34, 35, 36, 38 }, /* Delay = 38 */
  354.                 { 18, 22, 23, 25, 27, 29, 32, 34, 35, 36, 38 }  /* Delay = 39 */
  355.             };
  356.  
  357.             return ucDelay28to39Level54to64[Delay - 28][ucPlayerLevel - 54];
  358.         }
  359.     }
  360.     else if (Delay <= 59)
  361.     {
  362.         if (ucPlayerLevel <= 52)
  363.         {
  364.             if (Delay <= 45)
  365.             {
  366.                 static const uint8 ucDelay40to45Levels28to52[6][25] =
  367.                 {
  368.                     /*                                              Level:                                                      */
  369.                     /*   28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52     */
  370.  
  371.                     { 2, 2, 3, 4, 4, 4, 5, 6, 6, 7, 7, 7, 9, 9, 9, 10, 10, 11, 12, 12, 12, 13, 14, 16, 18 },    /* Delay = 40 */
  372.                     { 2, 2, 3, 4, 4, 4, 5, 6, 6, 7, 7, 7, 9, 9, 9, 10, 10, 11, 12, 12, 12, 13, 14, 16, 18 },    /* Delay = 41 */
  373.                     { 2, 2, 3, 4, 4, 4, 5, 6, 6, 7, 7, 7, 9, 9, 9, 10, 10, 11, 12, 12, 12, 13, 14, 16, 18 },    /* Delay = 42 */
  374.                     { 4, 4, 5, 6, 6, 6, 7, 8, 8, 9, 9, 9, 11, 11, 11, 12, 12, 13, 14, 14, 14, 15, 16, 18, 20 }, /* Delay = 43 */
  375.                     { 4, 4, 5, 6, 6, 6, 7, 8, 8, 9, 9, 9, 11, 11, 11, 12, 12, 13, 14, 14, 14, 15, 16, 18, 20 }, /* Delay = 44 */
  376.                     { 5, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 10, 12, 12, 12, 13, 13, 14, 15, 15, 15, 16, 17, 19, 21 }   /* Delay = 45 */
  377.                 };
  378.  
  379.                 return ucDelay40to45Levels28to52[Delay - 40][ucPlayerLevel - 28];
  380.             }
  381.             else
  382.             {
  383.                 static const uint8 ucDelay46Levels28to52[] = { 6, 6, 7, 8, 8, 8, 9, 10, 10, 11, 11, 11, 13, 13, 13, 14, 14, 15, 16, 16, 16, 17, 18, 20, 22 };
  384.  
  385.                 return ucDelay46Levels28to52[ucPlayerLevel - 28] + ((Delay - 46) / 3);
  386.             }
  387.         }
  388.         else
  389.         {
  390.             // Player is in the level range 53 - 64
  391.  
  392.             // Calculating damage bonus for 2H weapons with a delay between 40 and 59 (inclusive) involves, unforunately, a brute-force matrix lookup.
  393.             static const uint8 ucDelay40to59Levels53to64[20][37] =
  394.             {
  395.                 /*                      Level:                          */
  396.                 /*   53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64     */
  397.  
  398.                 { 19, 20, 24, 25, 27, 29, 31, 34, 36, 37, 38, 40 }, /* Delay = 40 */
  399.                 { 19, 20, 24, 25, 27, 29, 31, 34, 36, 37, 38, 40 }, /* Delay = 41 */
  400.                 { 19, 20, 24, 25, 27, 29, 31, 34, 36, 37, 38, 40 }, /* Delay = 42 */
  401.                 { 21, 22, 26, 27, 29, 31, 33, 37, 39, 40, 41, 43 }, /* Delay = 43 */
  402.                 { 21, 22, 26, 27, 29, 32, 34, 37, 39, 40, 41, 43 }, /* Delay = 44 */
  403.                 { 22, 23, 27, 28, 31, 33, 35, 38, 40, 42, 43, 45 }, /* Delay = 45 */
  404.                 { 23, 24, 28, 30, 32, 34, 36, 40, 42, 43, 44, 46 }, /* Delay = 46 */
  405.                 { 23, 24, 29, 30, 32, 34, 37, 40, 42, 43, 44, 47 }, /* Delay = 47 */
  406.                 { 23, 24, 29, 30, 32, 35, 37, 40, 43, 44, 45, 47 }, /* Delay = 48 */
  407.                 { 24, 25, 30, 31, 34, 36, 38, 42, 44, 45, 46, 49 }, /* Delay = 49 */
  408.                 { 24, 26, 30, 31, 34, 36, 39, 42, 44, 46, 47, 49 }, /* Delay = 50 */
  409.                 { 24, 26, 30, 31, 34, 36, 39, 42, 45, 46, 47, 49 }, /* Delay = 51 */
  410.                 { 25, 27, 31, 33, 35, 38, 40, 44, 46, 47, 49, 51 }, /* Delay = 52 */
  411.                 { 25, 27, 31, 33, 35, 38, 40, 44, 46, 48, 49, 51 }, /* Delay = 53 */
  412.                 { 26, 27, 32, 33, 36, 38, 41, 44, 47, 48, 49, 52 }, /* Delay = 54 */
  413.                 { 27, 28, 33, 34, 37, 39, 42, 46, 48, 50, 51, 53 }, /* Delay = 55 */
  414.                 { 27, 28, 33, 34, 37, 40, 42, 46, 49, 50, 51, 54 }, /* Delay = 56 */
  415.                 { 27, 28, 33, 34, 37, 40, 43, 46, 49, 50, 52, 54 }, /* Delay = 57 */
  416.                 { 28, 29, 34, 36, 39, 41, 44, 48, 50, 52, 53, 56 }, /* Delay = 58 */
  417.                 { 28, 29, 34, 36, 39, 41, 44, 48, 51, 52, 54, 56 }  /* Delay = 59 */
  418.             };
  419.  
  420.             return ucDelay40to59Levels53to64[Delay - 40][ucPlayerLevel - 53];
  421.         }
  422.     }
  423.     else
  424.     {
  425.         // The following table allows us to look up Damage Bonuses for weapons with delays greater than or equal to 60.
  426.         //
  427.         // There aren't a lot of 2H weapons with a delay greater than 60. In fact, both a database and Lucy search run by janusd confirm
  428.         // that the only unique 2H delays greater than 60 are: 65, 70, 85, 95, and 150.
  429.         //
  430.         // To be fair, there are also weapons with delays of 66 and 100. But they are either not equippable (None/None), or are
  431.         // only available to GMs from merchants in Sunset Home (cshome). In order to keep this table "lean and mean", I will not
  432.         // include the values for delays 66 and 100. If they ever are wielded, the 66 delay weapon will use the 65 delay bonuses,
  433.         // and the 100 delay weapon will use the 95 delay bonuses. So it's not a big deal.
  434.         //
  435.         // Still, if someone in the future decides that they do want to include them, here are the tables for these two delays:
  436.         //
  437.         // {12, 12, 13, 14, 14, 14, 15, 16, 16, 17, 17, 17, 19, 19, 19, 20, 20, 21, 22, 22, 22, 23, 24, 26, 29, 30, 32, 37, 39, 42, 45, 48, 53, 55, 57, 59, 61, 64}     /* Delay = 66 */
  438.         // {24, 24, 25, 26, 26, 26, 27, 28, 28, 29, 29, 29, 31, 31, 31, 32, 32, 33, 34, 34, 34, 35, 36, 39, 43, 45, 48, 55, 57, 62, 66, 71, 77, 80, 83, 85, 89, 92}     /* Delay = 100 */
  439.         //
  440.         // In case there are 2H weapons added in the future with delays other than those listed above (and until the damage bonuses
  441.         // associated with that new delay are added to this function), this function is designed to do the following:
  442.         //
  443.         //      For weapons with delays in the range 60-64, use the Damage Bonus that would apply to a 2H weapon with delay 60.
  444.         //      For weapons with delays in the range 65-69, use the Damage Bonus that would apply to a 2H weapon with delay 65
  445.         //      For weapons with delays in the range 70-84, use the Damage Bonus that would apply to a 2H weapon with delay 70.
  446.         //      For weapons with delays in the range 85-94, use the Damage Bonus that would apply to a 2H weapon with delay 85.
  447.         //      For weapons with delays in the range 95-149, use the Damage Bonus that would apply to a 2H weapon with delay 95.
  448.         //      For weapons with delays 150 or higher, use the Damage Bonus that would apply to a 2H weapon with delay 150.
  449.  
  450.         static const uint8 ucDelayOver59Levels28to65[6][38] =
  451.         {
  452.             /*                                                                  Level:                                                                                  */
  453.             /*   28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64. 65 */
  454.  
  455.             { 10, 10, 11, 12, 12, 12, 13, 14, 14, 15, 15, 15, 17, 17, 17, 18, 18, 19, 20, 20, 20, 21, 22, 24, 27, 28, 30, 35, 36, 39, 42, 45, 49, 51, 53, 54, 57, 59 },     /* Delay = 60 */
  456.             { 12, 12, 13, 14, 14, 14, 15, 16, 16, 17, 17, 17, 19, 19, 19, 20, 20, 21, 22, 22, 22, 23, 24, 26, 29, 30, 32, 37, 39, 42, 45, 48, 52, 55, 57, 58, 61, 63 },     /* Delay = 65 */
  457.             { 14, 14, 15, 16, 16, 16, 17, 18, 18, 19, 19, 19, 21, 21, 21, 22, 22, 23, 24, 24, 24, 25, 26, 28, 31, 33, 35, 40, 42, 45, 48, 52, 56, 59, 61, 62, 65, 68 },     /* Delay = 70 */
  458.             { 19, 19, 20, 21, 21, 21, 22, 23, 23, 24, 24, 24, 26, 26, 26, 27, 27, 28, 29, 29, 29, 30, 31, 34, 37, 39, 41, 47, 49, 54, 57, 61, 66, 69, 72, 74, 77, 80 },     /* Delay = 85 */
  459.             { 22, 22, 23, 24, 24, 24, 25, 26, 26, 27, 27, 27, 29, 29, 29, 30, 30, 31, 32, 32, 32, 33, 34, 37, 40, 43, 45, 52, 54, 59, 62, 67, 73, 76, 79, 81, 84, 88 },     /* Delay = 95 */
  460.             { 40, 40, 41, 42, 42, 42, 43, 44, 44, 45, 45, 45, 47, 47, 47, 48, 48, 49, 50, 50, 50, 51, 52, 56, 61, 65, 69, 78, 82, 89, 94, 102, 110, 115, 119, 122, 127, 132 }   /* Delay = 150 */
  461.         };
  462.  
  463.         if (Delay < 65)
  464.         {
  465.             return ucDelayOver59Levels28to65[0][ucPlayerLevel - 28];
  466.         }
  467.         else if (Delay < 70)
  468.         {
  469.             return ucDelayOver59Levels28to65[1][ucPlayerLevel - 28];
  470.         }
  471.         else if (Delay < 85)
  472.         {
  473.             return ucDelayOver59Levels28to65[2][ucPlayerLevel - 28];
  474.         }
  475.         else if (Delay < 95)
  476.         {
  477.             return ucDelayOver59Levels28to65[3][ucPlayerLevel - 28];
  478.         }
  479.         else if (Delay < 150)
  480.         {
  481.             return ucDelayOver59Levels28to65[4][ucPlayerLevel - 28];
  482.         }
  483.         else
  484.         {
  485.             return ucDelayOver59Levels28to65[5][ucPlayerLevel - 28];
  486.         }
  487.     }
  488. }
  489.  
  490. uint8 GetWeaponDamageBonusNew(uint8 Level, uint8 ItemType, uint8 Delay, bool offhand)
  491. {
  492.     // dev quote with old and new formulas
  493.     // https://forums.daybreakgames.com/eq/index.php?threads/test-update-09-17-15.226618/page-5#post-3326194
  494.     //
  495.     // We assume that the level check is done before calling this function and sinister strikes is checked before
  496.     // calling for offhand DB
  497.     auto level = Level;
  498.     if (!ItemType)
  499.         return 1 + ((level - 28) / 3); // how does weaponless scale?
  500.  
  501.     auto delay = Delay;
  502.     if (ItemType == ItemType1HSlash || ItemType == ItemType1HBlunt ||
  503.         ItemType == ItemTypeMartial || ItemType == ItemType1HPiercing)
  504.     {
  505.         // we assume sinister strikes is checked before calling here
  506.         if (!offhand)
  507.         {
  508.             if (delay <= 39)
  509.                 return 1 + ((level - 28) / 3);
  510.             else if (delay < 43)
  511.                 return 2 + ((level - 28) / 3) + ((delay - 40) / 3);
  512.             else if (delay < 45)
  513.                 return 3 + ((level - 28) / 3) + ((delay - 40) / 3);
  514.             else if (delay >= 45)
  515.                 return 4 + ((level - 28) / 3) + ((delay - 40) / 3);
  516.         }
  517.         else
  518.         {
  519.             return 1 + ((level - 28) / 3) * (delay / 30);
  520.         }
  521.     }
  522.     else
  523.     {
  524.         // 2h damage bonus
  525.         if (delay <= 27)
  526.             return 1 + ((level - 28) / 3);
  527.         else if (delay < 40)
  528.             return 1 + ((level - 28) / 3) + ((level - 30) / 5);
  529.         else if (delay < 43)
  530.             return 2 + ((level - 28) / 3) + ((level - 30) / 5) + ((delay - 40) / 3);
  531.         else if (delay < 45)
  532.             return 3 + ((level - 28) / 3) + ((level - 30) / 5) + ((delay - 40) / 3);
  533.         else if (delay >= 45)
  534.             return 4 + ((level - 28) / 3) + ((level - 30) / 5) + ((delay - 40) / 3);
  535.     }
  536. }
  537.  
  538.  
  539. int _tmain(int argc, _TCHAR* argv[])
  540. {
  541.     FILE* _out = fopen("C:\\EQEmuServer\\Damage-Bonus-Comparison.csv", "wb");
  542.  
  543.     fprintf(_out, "Old");
  544.     for (int _delay = 28; _delay < 100; _delay += 2)
  545.     {
  546.         fprintf(_out, ",%u", _delay);
  547.     }
  548.     fprintf(_out, ",,New");
  549.     for (int _delay = 28; _delay < 100; _delay += 2)
  550.     {
  551.         fprintf(_out, ",%u", _delay);
  552.     }
  553.     fprintf(_out, "\r\n");
  554.  
  555.     for (int _level = 28; _level <= 65; ++_level)
  556.     {
  557.         fprintf(_out, "%u", _level);
  558.  
  559.         for (int _delay = 28; _delay < 100; _delay += 2)
  560.         {
  561.             fprintf(_out, ",%u", GetWeaponDamageBonusOld(_level, ItemType2HSlash, _delay));
  562.         }
  563.  
  564.         fprintf(_out, ",,%u", _level);
  565.  
  566.         for (int _delay = 28; _delay < 100; _delay += 2)
  567.         {
  568.             fprintf(_out, ",%u", GetWeaponDamageBonusNew(_level, ItemType2HSlash, _delay, false));
  569.         }
  570.  
  571.         fprintf(_out, "\r\n");
  572.     }
  573.  
  574.     fclose(_out);
  575.  
  576.     return 0;
  577. }
Advertisement
Add Comment
Please, Sign In to add comment