Advertisement
Delfigamer

Disgaea PC damage calculation

Oct 23rd, 2016
440
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.89 KB | None | 0 0
  1. enum class weapon_type_t: uint8_t
  2. {
  3.     bow = 4,
  4.     gun = 5,
  5.     staff = 7,
  6. };
  7.  
  8. enum class action_type_t: uint8_t
  9. {
  10.     physical_attack = 2,
  11.     magical_attack = 3,
  12.     healing_spell = 4,
  13. };
  14.  
  15. struct actiondef_t
  16. {
  17.     [  0x0] uint16_t us_id;
  18.     [  0x4] int16_t is_power;
  19.     [ 0x9a] int8_t aic_9a[];
  20.     [ 0xa0] uint8_t uc_element;
  21.     [ 0xa1] action_type_t action_type;
  22.     [ 0xa7] uint8_t auc_a7[];
  23.     [ 0xac]
  24. };
  25.  
  26. struct gamecell_t
  27. {
  28.     [   0x4] uint8_t uc_atk_p50_count;
  29.     [   0x5] uint8_t uc_atk_m50_count;
  30.     [   0x6] uint8_t uc_def_p50_count;
  31.     [   0x7] uint8_t uc_def_m50_count;
  32.  
  33.     [   0xb] uint8_t uc_enemy_p50_count;
  34.     [   0xc] uint8_t uc_enemy_t3_count;
  35.     [  0x20]
  36. };
  37.  
  38. struct gameunit_t
  39. {
  40.     [0x2ac] int16_t ais_2ac[];
  41.  
  42.     [0x400] bool b_damage_resistant;
  43.  
  44.     [0x4a4] uint16_t aus_learned_action_id[];
  45.  
  46.     [0x564] int8_t aic_learned_action_level[];
  47.  
  48.     [0x5c4] int32_t i_stat_hp;
  49.     [0x5c8] int32_t i_stat_sp;
  50.     [0x5cc] int32_t i_stat_hpmax;
  51.     [0x5d0] int32_t i_stat_spmax;
  52.     [0x5d4] int32_t i_stat_atk;
  53.     [0x5d8] int32_t i_stat_def;
  54.     [0x5dc] int32_t i_stat_int;
  55.     [0x5e0] int32_t i_stat_spd;
  56.     [0x5e4] int32_t i_stat_hit;
  57.     [0x5e8] int32_t i_stat_res;
  58.  
  59.     [0x64e] uint8_t ic_weapon_mastery_staff;
  60.  
  61.     [0x660] int16_t is_660;
  62.  
  63.     [0x664] int32_t i_classindex;
  64.  
  65.     [0x670] uint16_t us_670;
  66.  
  67.     [0x676] int8_t aic_element_resistance[];
  68.  
  69.     [0x681] int8_t ic_681;
  70.  
  71.     [0x689] weapon_type_t equip_weapon_type;
  72.  
  73.     [0x69f] bool b_magic_resistant;
  74. };
  75.  
  76. struct actioninfo_t
  77. {
  78.     [0x22e] uint16_t us_22e;
  79.     [0x26e] weapon_type_t weapon_type;
  80.     [0x284] gameunit_t* gameunit;
  81.     [0x3ee] uint16_t us_location;
  82.     [0x401] bool b_is_enemy;
  83. };
  84.  
  85. [0x532bf0] uint16_t g_action_power_factor[] = {
  86.     [  0] = 90,
  87.     [  1] = 100,
  88.     [  2] = 103,
  89.     [  3] = 106,
  90.     [  4] = 109,
  91.     [  5] = 112,
  92.     [  6] = 115,
  93.     [  7] = 118,
  94.     [  8] = 121,
  95.     [  9] = 124,
  96.     [ 10] = 127,
  97.     [ 11] = 130,
  98.     [ 12] = 133,
  99.     [ 13] = 136,
  100.     [ 14] = 139,
  101.     [ 15] = 142,
  102.     [ 16] = 145,
  103.     [ 17] = 148,
  104.     [ 18] = 151,
  105.     [ 19] = 154,
  106.     [ 20] = 157,
  107.     [ 21] = 160,
  108.     [ 22] = 162,
  109.     [ 23] = 164,
  110.     [ 24] = 166,
  111.     [ 25] = 168,
  112.     [ 26] = 170,
  113.     [ 27] = 172,
  114.     [ 28] = 174,
  115.     [ 29] = 176,
  116.     [ 30] = 178,
  117.     [ 31] = 180,
  118.     [ 32] = 182,
  119.     [ 33] = 184,
  120.     [ 34] = 186,
  121.     [ 35] = 188,
  122.     [ 36] = 190,
  123.     [ 37] = 192,
  124.     [ 38] = 194,
  125.     [ 39] = 196,
  126.     [ 40] = 198,
  127.     [ 41] = 200,
  128.     [ 42] = 202,
  129.     [ 43] = 204,
  130.     [ 44] = 206,
  131.     [ 45] = 208,
  132.     [ 46] = 210,
  133.     [ 47] = 212,
  134.     [ 48] = 214,
  135.     [ 49] = 216,
  136.     [ 50] = 218,
  137.     [ 51] = 220,
  138.     [ 52] = 222,
  139.     [ 53] = 224,
  140.     [ 54] = 226,
  141.     [ 55] = 228,
  142.     [ 56] = 230,
  143.     [ 57] = 232,
  144.     [ 58] = 234,
  145.     [ 59] = 236,
  146.     [ 60] = 238,
  147.     [ 61] = 240,
  148.     [ 62] = 242,
  149.     [ 63] = 244,
  150.     [ 64] = 246,
  151.     [ 65] = 248,
  152.     [ 66] = 250,
  153.     [ 67] = 252,
  154.     [ 68] = 254,
  155.     [ 69] = 256,
  156.     [ 70] = 258,
  157.     [ 71] = 260,
  158.     [ 72] = 262,
  159.     [ 73] = 264,
  160.     [ 74] = 266,
  161.     [ 75] = 268,
  162.     [ 76] = 270,
  163.     [ 77] = 272,
  164.     [ 78] = 274,
  165.     [ 79] = 276,
  166.     [ 80] = 278,
  167.     [ 81] = 280,
  168.     [ 82] = 282,
  169.     [ 83] = 284,
  170.     [ 84] = 286,
  171.     [ 85] = 288,
  172.     [ 86] = 290,
  173.     [ 87] = 292,
  174.     [ 88] = 294,
  175.     [ 89] = 296,
  176.     [ 90] = 298,
  177.     [ 91] = 300,
  178.     [ 92] = 305,
  179.     [ 93] = 310,
  180.     [ 94] = 315,
  181.     [ 95] = 320,
  182.     [ 96] = 325,
  183.     [ 97] = 330,
  184.     [ 98] = 340,
  185.     [ 99] = 350,
  186.     [100] = 400,
  187. };
  188.  
  189. [0x66402c] actiondef_t* g_actionlist_ptr;
  190. [0x664030] int32_t g_actionlist_length;
  191. [0x6640b0] gamecell_t g_gamefield[];
  192. [0x65db3a] uint8_t g_uc_65db3a;
  193. [0x6d4ac0] uint8_t g_auc_6d4ac0[];
  194. [0x6e57a8] uint8_t g_uc_6e57a8;
  195.  
  196. bool f_444e10( uint8_t arg_1, uint8_t arg_2 )
  197. {
  198.     if( g_uc_65db3a != 5 )
  199.     {
  200.         return false;
  201.     }
  202.     if( g_uc_6e57a8 == 0 )
  203.     {
  204.         return false;
  205.     }
  206.     if( arg_2 != 0 && arg_2 != 1 )
  207.     {
  208.         return false;
  209.     }
  210.     for( int i = 0; i < 5; ++i )
  211.     {
  212.         if( g_auc_6d4ac0[arg_2*5 + i] == arg_1 )
  213.         {
  214.             return true;
  215.         }
  216.     }
  217.     return false;
  218. }
  219.  
  220. int saturated_curve( int64_t x )
  221. {
  222.     if( x <= 500 )
  223.     {
  224.         return x;
  225.     }
  226.     else if( x <= 1000 )
  227.     {
  228.         return ( x - 500 ) / 2 + 500;
  229.     }
  230.     else
  231.     {
  232.         return ( x - 1000 ) / 5 + 750;
  233.     }
  234. }
  235.  
  236. void f_46fdc0( int32_t arg_1, void* arg_2,
  237.     actioninfo_t* source_info, actioninfo_t* target_info )
  238. {
  239.     gameunit_t* gameunit_source = source_info->gameunit;
  240.     gameunit_t* gameunit_target = target_info->gameunit;
  241.     uint32_t u_combo_counter = uint16_t( arg_2[0x170] );
  242.     int32_t i_combo_bonus;
  243.     if( source_info->b_is_enemy )
  244.     {
  245.         i_combo_bonus = u_combo_counter * 15;
  246.     }
  247.     else
  248.     {
  249.         i_combo_bonus = u_combo_counter * 10;
  250.     }
  251.     int32_t i_ebp_52 = ( gameunit_target->is_660 - gameunit_source->is_660 ) * 2;
  252.     if( i_ebp_52 < 0 )
  253.     {
  254.         i_ebp_52 = 0;
  255.     }
  256.     else if( i_ebp_52 > 90 )
  257.     {
  258.         i_ebp_52 = 90;
  259.     }
  260.     actiondef_t* actiondef;
  261.     for( int i = 0; i < g_actionlist_length; ++i )
  262.     {
  263.         if( g_actionlist_ptr[i].us_id == uint16_t( arg_2[0x158] ) )
  264.         {
  265.             actiondef = &g_actionlist_ptr[i];
  266.             goto cycle_break_fe89;
  267.         }
  268.     }
  269.     actiondef = 0;
  270. cycle_break_fe89:
  271.     int32_t i_action_level;
  272.     for( int i = 0; i < gameunit_source->ic_681; ++i )
  273.     {
  274.         if( gameunit_source->aus_learned_action_id[i] == uint16_t( arg_2[0x158] ) )
  275.         {
  276.             i_action_level = gameunit_source->aic_learned_action_level[i];
  277.             goto cycle_break_feb9;
  278.         }
  279.     }
  280.     i_action_level = 0;
  281. cycle_break_feb9:
  282.     uint32_t u_action_power_factor = g_action_power_factor[i_action_level];
  283.     int64_t il_defense_bonus = 0;
  284.     int64_t il_attack_bonus = 0;
  285.     if( u_combo_counter > 0 )
  286.     {
  287.         il_attack_bonus = i_combo_bonus;
  288.         il_defense_bonus = -i_combo_bonus;
  289.     }
  290.     int32_t i_source_location = source_info->us_location;
  291.     int32_t i_target_location = target_info->us_location;
  292.     il_attack_bonus += g_gamefield[i_source_location]->uc_atk_p50_count * 50 -
  293.         g_gamefield[i_source_location]->uc_atk_m50_count * 50;
  294.     il_defense_bonus += g_gamefield[i_target_location]->uc_def_p50_count * 50 -
  295.         g_gamefield[i_target_location]->uc_def_m50_count * 50;
  296.     if( source_info->b_is_enemy )
  297.     {
  298.         int32_t t3_boost =
  299.             g_gamefield[i_source_location]->uc_enemy_t3_count * 300 - 100;
  300.         if( t3_boost < 0 )
  301.         {
  302.             t3_boost = 0;
  303.         }
  304.         int64_t p50_boost =
  305.             g_gamefield[i_source_location]->uc_enemy_p50_count * 50;
  306.         il_attack_bonus += p50_boost + t3_boost;
  307.     }
  308.     if( target_info->b_is_enemy )
  309.     {
  310.         int32_t t3_boost =
  311.             g_gamefield[i_target_location]->uc_enemy_t3_count * 300 - 100;
  312.         if( t3_boost < 0 )
  313.         {
  314.             t3_boost = 0;
  315.         }
  316.         int64_t p50_boost =
  317.             g_gamefield[i_target_location]->uc_enemy_p50_count * 50;
  318.         il_defense_bonus += p50_boost + t3_boost;
  319.     }
  320.     if( gameunit_target->i_classindex / 10 == 106 )
  321.     {
  322.         int32_t hit_value = gameunit_source->i_stat_hit * random_range( 70, 100 );
  323.         int32_t spd_value = gameunit_target->i_stat_spd * random_range( 0, 30 );
  324.         if( spd_value > hit_value )
  325.         {
  326.             arg_2[arg_1*4+0x4] = 0;
  327.             uint16_t( arg_2[arg_1*2+0x114] ) = 0;
  328.             return;
  329.         }
  330.     }
  331.     for( int edi_index = 0; edi_index < 5; ++edi_index )
  332.     {
  333.         uint32_t u_ebp_44c = actiondef->auc_a7[edi_index];
  334.         switch( u_ebp_44c )
  335.         {
  336.             case 1:
  337.             {
  338.                 il_attack_bonus += actiondef->aic_9a[edi_index] * 10;
  339.                 break;
  340.             }
  341.             case 2:
  342.             {
  343.                 il_defense_bonus = actiondef->aic_9a[edi_index] * 10;
  344.                 break;
  345.             }
  346.             case 11:
  347.             case 12:
  348.             case 13:
  349.             case 14:
  350.             {
  351.                 uint32_t u_index = u_ebp_44c - 11;
  352.                 uint16_t us_mask = 1 << ( u_index + 6 );
  353.                 if( ( gameunit_target->us_670 & us_mask == 0 &&
  354.                         i_ebp_52 <= random_range( 0, 99 ) ) ||
  355.                      actiondef->aic_9a[edi_index] >= 0 )
  356.                 {
  357.                     int8_t( arg_2[0x17d + arg_1*16 + u_index + 7] ) =
  358.                         actiondef->aic_9a[edi_index];
  359.                 }
  360.                 break;
  361.             }
  362.             case 21:
  363.             case 22:
  364.             case 23:
  365.             case 24:
  366.             case 25:
  367.             {
  368.                 uint32_t u_index = u_ebp_44c - 21;
  369.                 uint16_t us_mask = 1 << u_index;
  370.                 if( gameunit_target->us_670 & us_mask != 0 )
  371.                 {
  372.                     break;
  373.                 }
  374.                 int32_t i_diff_660 =
  375.                     ( gameunit_target->is_660 - gameunit_source->is_660 ) / 2;
  376.                 if( i_diff_660 < 0 )
  377.                 {
  378.                     i_diff_660 = 0;
  379.                 }
  380.                 int32_t i_ebp_48c =
  381.                     random_range( 0, i_action_level + actiondef->aic_9a[edi_index] ) -
  382.                     random_range( 0, i_diff_660 + gameunit_target->ais_2ac[u_index] );
  383.                 if( i_ebp_48c > 100 )
  384.                 {
  385.                     i_ebp_48c = 100;
  386.                 }
  387.                 else if( i_ebp_48c <= 0 )
  388.                 {
  389.                     break;
  390.                 }
  391.                 int8_t( arg_2[0x17d + arg_1*16 + u_index] ) = i_ebp_48c;
  392.                 break;
  393.             }
  394.             case 101:
  395.             {
  396.                 memset( arg_2 + 0x17d + arg_1*16, 0x88, 5 );
  397.                 break;
  398.             }
  399.             case 102:
  400.             {
  401.                 al = actiondef->aic_9a[edi_index];
  402.                 int8_t( arg_2[0x37c] ) = actiondef->aic_9a[edi_index];
  403.                 break;
  404.             }
  405.             case 104:
  406.             {
  407.                 int16_t( arg_2[0x178] ) = actiondef->aic_9a[edi_index];
  408.                 break;
  409.             }
  410.         }
  411.     }
  412.     int64_t il_attack_power;
  413.     int32_t i_defense_power;
  414.     switch( actiondef->action_type )
  415.     {
  416.         case action_type_t::physical_attack:
  417.         {
  418.             uint16_t( arg_2[arg_1*2+0x114] ) = 1;
  419.             int32_t i_660_value = gameunit_source->is_660 + 100;
  420.             if( i_660_value <= 25 )
  421.             {
  422.                 i_660_value = 25;
  423.             }
  424.             else
  425.             {
  426.                 i_660_value = saturated_curve( i_660_value );
  427.             }
  428.             int64_t il_effective_stat_bonus =
  429.                 actiondef->is_power * i_660_value / 100;
  430.             switch( source_info->weapon_type )
  431.             {
  432.                 case weapon_type_t::bow:
  433.                 {
  434.                     int64_t il_effective_stat =
  435.                         gameunit_source->i_stat_hit + gameunit_source->i_stat_atk +
  436.                         il_effective_stat_bonus * 2;
  437.                     il_attack_power =
  438.                         il_effective_stat * random_range( 90, 110 ) / 40;
  439.                     i_defense_power =
  440.                         gameunit_target->i_stat_def * random_range( 45, 60 ) / 20;
  441.                     break;
  442.                 }
  443.                 case weapon_type_t::gun:
  444.                 {
  445.                     int64_t il_effective_stat =
  446.                         gameunit_source->i_stat_hit + il_effective_stat_bonus;
  447.                     il_attack_power =
  448.                         il_effective_stat * random_range( 90, 110 ) / 27;
  449.                     i_defense_power =
  450.                         gameunit_target->i_stat_def * random_range( 45, 60 ) / 27;
  451.                     break;
  452.                 }
  453.                 default:
  454.                 {
  455.                     int64_t il_effective_stat =
  456.                         gameunit_source->i_stat_atk + il_effective_stat_bonus;
  457.                     il_attack_power =
  458.                         il_effective_stat * random_range( 90, 110 ) / 20;
  459.                     i_defense_power =
  460.                         gameunit_target->i_stat_def * random_range( 45, 60 ) / 20;
  461.                     break;
  462.                 }
  463.             }
  464.             break;
  465.         }
  466.         case action_type_t::magical_attack:
  467.         {
  468.             int32_t i_660_value = gameunit_source->is_660 + 100;
  469.             if( i_660_value <= 25 )
  470.             {
  471.                 i_660_value = 25;
  472.             }
  473.             else
  474.             {
  475.                 i_660_value = saturated_curve( i_660_value );
  476.             }
  477.             int64_t il_effective_stat_bonus =
  478.                 actiondef->is_power * i_660_value / 100;
  479.             int64_t il_effective_stat =
  480.                 gameunit_source->i_stat_int + il_effective_stat_bonus;
  481.             il_attack_power =
  482.                 il_effective_stat * random_range( 90, 110 ) / 30;
  483.             i_defense_power =
  484.                 gameunit_target->i_stat_res * random_range( 45, 60 ) / 30;
  485.             if( gameunit_target->b_magic_resistant )
  486.             {
  487.                 il_attack_power /= 2;
  488.             }
  489.             if( gameunit_source->equip_weapon_type == weapon_type_t::staff )
  490.             {
  491.                 int32_t i_wml_bonus = gameunit_source->ic_weapon_mastery_staff * 3;
  492.                 if( i_wml_bonus > 100 )
  493.                 {
  494.                     i_wml_bonus = 100;
  495.                 }
  496.                 il_attack_bonus += i_wml_bonus;
  497.             }
  498.             break;
  499.         }
  500.         case action_type_t::healing_spell:
  501.         {
  502.             int16_t( arg_2[arg_1*2+0x114] ) = 1;
  503.             int32_t i_amount = gameunit_source->i_stat_int + 100;
  504.             if( i_amount <= 25 )
  505.             {
  506.                 i_amount = 25;
  507.             }
  508.             else
  509.             {
  510.                 i_amount = saturated_curve( i_amount );
  511.             }
  512.             int64_t il_base_heal_amount =
  513.                 i_amount * actiondef->is_power / 100;
  514.             if( gameunit_source->equip_weapon_type == weapon_type_t::staff )
  515.             {
  516.                 int32_t i_wml_bonus = gameunit_source->ic_weapon_mastery_staff * 3;
  517.                 if( i_wml_bonus > 100 )
  518.                 {
  519.                     i_wml_bonus = 100;
  520.                 }
  521.                 il_attack_bonus += edx:eax;
  522.             }
  523.             if( il_attack_bonus > 2000 )
  524.             {
  525.                 il_attack_bonus = 2000;
  526.             }
  527.             else if( il_attack_bonus < -100 )
  528.             {
  529.                 il_attack_bonus = -100;
  530.             }
  531.             int64_t il_damage_value =
  532.                 ( il_attack_bonus + 100 ) * il_base_heal_amount / -100;
  533.             int32_t( arg_2[arg_1*4+0x4] ) = il_damage_value;
  534.             return;
  535.         }
  536.         default:
  537.         {
  538.             int16_t( arg_2[arg_1*2+0x114] ) = 1;
  539.             arg_2[arg_1*4+0x4] = 0;
  540.             return;
  541.         }
  542.     }
  543.     if( il_attack_bonus > 2000 )
  544.     {
  545.         il_attack_bonus = 2000;
  546.     }
  547.     else if( il_attack_bonus <= -100 )
  548.     {
  549.         il_attack_bonus = -100;
  550.     }
  551.     if( il_defense_bonus > 2000 )
  552.     {
  553.         il_defense_bonus = 2000;
  554.     }
  555.     else if( il_defense_bonus <= -100 )
  556.     {
  557.         il_defense_bonus = -100;
  558.     }
  559.     int64_t il_defense_value =
  560.         ( il_defense_bonus + 100 ) * i_defense_power / 1000;
  561.     int64_t il_attack_value =
  562.         ( il_attack_bonus + 100 ) * i_attack_power / 1000;
  563.     int64_t il_damage_value = il_attack_value - il_defense_value;
  564.     if( target_info->b_damage_resistant )
  565.     {
  566.         il_damage_value /= 2;
  567.     }
  568.     il_damage_value = il_damage_value * u_action_power_factor / 100;
  569.     if( actiondef->uc_element >= 1 && actiondef->uc_element <= 3 )
  570.     {
  571.         int32_t i_factor =
  572.             100 - gameunit_target->aic_element_resistance[actiondef->uc_element];
  573.         if( i_factor < 10 )
  574.         {
  575.             i_factor = 10;
  576.         }
  577.         else if( i_factor > 200 )
  578.         {
  579.             i_factor = 200;
  580.         }
  581.         il_damage_value = il_damage_value * i_factor / 100;
  582.     }
  583.     int32_t i_damage = il_damage_value;
  584.     if( i_damage < 0 )
  585.     {
  586.         i_damage = 0;
  587.         u_action_power_factor = 0;
  588.     }
  589.     if( target_info->us_22e == 3200 ||
  590.         f_444e10( 2, target_info->b_is_enemy ) != 0 )
  591.     {
  592.         i_damage = 0;
  593.         u_action_power_factor = 0;
  594.     }
  595.     int32_t( arg_2[arg_1*4+0x4] ) = i_damage;
  596.     return;
  597. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement