@@ -94,6 +94,8 @@ static int calledShotSelectHitLocation(Object* critter, int* hitLocation, int hi
94
94
static void criticalsInit ();
95
95
static void criticalsReset ();
96
96
static void criticalsExit ();
97
+ static void burstModInit ();
98
+ static int burstModComputeRounds (int totalRounds, int * centerRoundsPtr, int * leftRoundsPtr, int * rightRoundsPtr);
97
99
98
100
// 0x500B50
99
101
static char _a_1[] = " ." ;
@@ -1925,6 +1927,12 @@ static const char* gCritDataMemberKeys[CRIT_DATA_MEMBER_COUNT] = {
1925
1927
" FailMessage" ,
1926
1928
};
1927
1929
1930
+ static bool gBurstModEnabled = false ;
1931
+ static int gBurstModCenterMultiplier = SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_MULTIPLIER;
1932
+ static int gBurstModCenterDivisor = SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_DIVISOR;
1933
+ static int gBurstModTargetMultiplier = SFALL_CONFIG_BURST_MOD_DEFAULT_TARGET_MULTIPLIER;
1934
+ static int gBurstModTargetDivisor = SFALL_CONFIG_BURST_MOD_DEFAULT_TARGET_DIVISOR;
1935
+
1928
1936
// combat_init
1929
1937
// 0x420CC0
1930
1938
int combatInit ()
@@ -1965,6 +1973,7 @@ int combatInit()
1965
1973
1966
1974
// SFALL
1967
1975
criticalsInit ();
1976
+ burstModInit ();
1968
1977
1969
1978
return 0 ;
1970
1979
}
@@ -3591,31 +3600,36 @@ static int _compute_spray(Attack* attack, int accuracy, int* a3, int* a4, int an
3591
3600
accuracy += 20 ;
3592
3601
}
3593
3602
3594
- int v31 ;
3595
- int v14 ;
3596
- int v33 ;
3597
- int v30 ;
3603
+ int leftRounds ;
3604
+ int mainTargetRounds ;
3605
+ int centerRounds ;
3606
+ int rightRounds ;
3598
3607
if (anim == ANIM_FIRE_BURST) {
3599
- v33 = ammoQuantity / 3 ;
3600
- if (v33 == 0 ) {
3601
- v33 = 1 ;
3602
- }
3608
+ // SFALL: Burst mod.
3609
+ if (gBurstModEnabled ) {
3610
+ mainTargetRounds = burstModComputeRounds (ammoQuantity, ¢erRounds, &leftRounds, &rightRounds);
3611
+ } else {
3612
+ centerRounds = ammoQuantity / 3 ;
3613
+ if (centerRounds == 0 ) {
3614
+ centerRounds = 1 ;
3615
+ }
3603
3616
3604
- v31 = ammoQuantity / 3 ;
3605
- v30 = ammoQuantity - v33 - v31;
3606
- v14 = v33 / 2 ;
3607
- if (v14 == 0 ) {
3608
- v14 = 1 ;
3609
- v33 -= 1 ;
3617
+ leftRounds = ammoQuantity / 3 ;
3618
+ rightRounds = ammoQuantity - centerRounds - leftRounds;
3619
+ mainTargetRounds = centerRounds / 2 ;
3620
+ if (mainTargetRounds == 0 ) {
3621
+ mainTargetRounds = 1 ;
3622
+ centerRounds -= 1 ;
3623
+ }
3610
3624
}
3611
3625
} else {
3612
- v31 = 1 ;
3613
- v14 = 1 ;
3614
- v33 = 1 ;
3615
- v30 = 1 ;
3626
+ leftRounds = 1 ;
3627
+ mainTargetRounds = 1 ;
3628
+ centerRounds = 1 ;
3629
+ rightRounds = 1 ;
3616
3630
}
3617
3631
3618
- for (int index = 0 ; index < v14 ; index += 1 ) {
3632
+ for (int index = 0 ; index < mainTargetRounds ; index += 1 ) {
3619
3633
if (randomRoll (accuracy, 0 , NULL ) >= ROLL_SUCCESS) {
3620
3634
*a3 += 1 ;
3621
3635
}
@@ -3626,28 +3640,25 @@ static int _compute_spray(Attack* attack, int accuracy, int* a3, int* a4, int an
3626
3640
}
3627
3641
3628
3642
int range = _item_w_range (attack->attacker , attack->hitMode );
3629
- int v19 = _tile_num_beyond (attack->attacker ->tile , attack->defender ->tile , range);
3630
-
3631
- *a3 += _shoot_along_path (attack, v19, v33 - *a3, anim);
3643
+ int mainTargetEndTile = _tile_num_beyond (attack->attacker ->tile , attack->defender ->tile , range);
3644
+ *a3 += _shoot_along_path (attack, mainTargetEndTile, centerRounds - *a3, anim);
3632
3645
3633
- int v20 ;
3646
+ int centerTile ;
3634
3647
if (objectGetDistanceBetween (attack->attacker , attack->defender ) <= 3 ) {
3635
- v20 = _tile_num_beyond (attack->attacker ->tile , attack->defender ->tile , 3 );
3648
+ centerTile = _tile_num_beyond (attack->attacker ->tile , attack->defender ->tile , 3 );
3636
3649
} else {
3637
- v20 = attack->defender ->tile ;
3650
+ centerTile = attack->defender ->tile ;
3638
3651
}
3639
3652
3640
- int rotation = tileGetRotationTo (v20, attack->attacker ->tile );
3641
- int v23 = tileGetTileInDirection (v20, (rotation + 1 ) % ROTATION_COUNT, 1 );
3642
-
3643
- int v25 = _tile_num_beyond (attack->attacker ->tile , v23, range);
3653
+ int rotation = tileGetRotationTo (centerTile, attack->attacker ->tile );
3644
3654
3645
- *a3 += _shoot_along_path (attack, v25, v31, anim);
3655
+ int leftTile = tileGetTileInDirection (centerTile, (rotation + 1 ) % ROTATION_COUNT, 1 );
3656
+ int leftEndTile = _tile_num_beyond (attack->attacker ->tile , leftTile, range);
3657
+ *a3 += _shoot_along_path (attack, leftEndTile, leftRounds, anim);
3646
3658
3647
- int v26 = tileGetTileInDirection (v20, (rotation + 5 ) % ROTATION_COUNT, 1 );
3648
-
3649
- int v28 = _tile_num_beyond (attack->attacker ->tile , v26, range);
3650
- *a3 += _shoot_along_path (attack, v28, v30, anim);
3659
+ int rightTile = tileGetTileInDirection (centerTile, (rotation + 5 ) % ROTATION_COUNT, 1 );
3660
+ int rightEndTile = _tile_num_beyond (attack->attacker ->tile , rightTile, range);
3661
+ *a3 += _shoot_along_path (attack, rightEndTile, rightRounds, anim);
3651
3662
3652
3663
if (roll != ROLL_FAILURE || (*a3 <= 0 && attack->extrasLength <= 0 )) {
3653
3664
if (roll >= ROLL_SUCCESS && *a3 == 0 && attack->extrasLength == 0 ) {
@@ -6117,3 +6128,52 @@ void criticalsResetValue(int killType, int hitLocation, int effect, int dataMemb
6117
6128
gCriticalHitTables [killType][hitLocation][effect].values [dataMember] = gBaseCriticalHitTables [killType][hitLocation][effect].values [dataMember];
6118
6129
}
6119
6130
}
6131
+
6132
+ static void burstModInit ()
6133
+ {
6134
+ configGetBool (&gSfallConfig , SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_ENABLED_KEY, &gBurstModEnabled );
6135
+
6136
+ configGetInt (&gSfallConfig , SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_CENTER_MULTIPLIER_KEY, &gBurstModCenterMultiplier );
6137
+ configGetInt (&gSfallConfig , SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_CENTER_DIVISOR_KEY, &gBurstModCenterDivisor );
6138
+ if (gBurstModCenterDivisor < 1 ) {
6139
+ gBurstModCenterDivisor = 1 ;
6140
+ }
6141
+ if (gBurstModCenterMultiplier > gBurstModCenterDivisor ) {
6142
+ gBurstModCenterMultiplier = gBurstModCenterDivisor ;
6143
+ }
6144
+
6145
+ configGetInt (&gSfallConfig , SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_TARGET_MULTIPLIER_KEY, &gBurstModTargetMultiplier );
6146
+ configGetInt (&gSfallConfig , SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_TARGET_DIVISOR_KEY, &gBurstModTargetDivisor );
6147
+ if (gBurstModTargetDivisor < 1 ) {
6148
+ gBurstModTargetDivisor = 1 ;
6149
+ }
6150
+ if (gBurstModTargetMultiplier > gBurstModTargetDivisor ) {
6151
+ gBurstModTargetMultiplier = gBurstModTargetDivisor ;
6152
+ }
6153
+ }
6154
+
6155
+ static int burstModComputeRounds (int totalRounds, int * centerRoundsPtr, int * leftRoundsPtr, int * rightRoundsPtr)
6156
+ {
6157
+ int totalRoundsMultiplied = totalRounds * gBurstModCenterMultiplier ;
6158
+ int centerRounds = totalRoundsMultiplied / gBurstModCenterDivisor ;
6159
+ if ((totalRoundsMultiplied % gBurstModCenterDivisor ) != 0 ) {
6160
+ centerRounds++;
6161
+ }
6162
+
6163
+ if (centerRounds == 0 ) {
6164
+ centerRounds++;
6165
+ }
6166
+ *centerRoundsPtr = centerRounds;
6167
+
6168
+ int leftRounds = (totalRounds - centerRounds) / 2 ;
6169
+ *leftRoundsPtr = leftRounds;
6170
+ *rightRoundsPtr = totalRounds - centerRounds - leftRounds;
6171
+
6172
+ int centerRoundsMultiplied = centerRounds * gBurstModTargetMultiplier ;
6173
+ int mainTargetRounds = centerRoundsMultiplied / gBurstModTargetDivisor ;
6174
+ if ((centerRoundsMultiplied % gBurstModTargetDivisor ) != 0 ) {
6175
+ mainTargetRounds++;
6176
+ }
6177
+
6178
+ return mainTargetRounds;
6179
+ }
0 commit comments