Skip to content

Commit

Permalink
Add burst mod (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbatalov committed Aug 3, 2022
1 parent 3f9145b commit 3ccb087
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 34 deletions.
128 changes: 94 additions & 34 deletions src/combat.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ static int calledShotSelectHitLocation(Object* critter, int* hitLocation, int hi
static void criticalsInit();
static void criticalsReset();
static void criticalsExit();
static void burstModInit();
static int burstModComputeRounds(int totalRounds, int* centerRoundsPtr, int* leftRoundsPtr, int* rightRoundsPtr);

// 0x500B50
static char _a_1[] = ".";
Expand Down Expand Up @@ -1925,6 +1927,12 @@ static const char* gCritDataMemberKeys[CRIT_DATA_MEMBER_COUNT] = {
"FailMessage",
};

static bool gBurstModEnabled = false;
static int gBurstModCenterMultiplier = SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_MULTIPLIER;
static int gBurstModCenterDivisor = SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_DIVISOR;
static int gBurstModTargetMultiplier = SFALL_CONFIG_BURST_MOD_DEFAULT_TARGET_MULTIPLIER;
static int gBurstModTargetDivisor = SFALL_CONFIG_BURST_MOD_DEFAULT_TARGET_DIVISOR;

// combat_init
// 0x420CC0
int combatInit()
Expand Down Expand Up @@ -1965,6 +1973,7 @@ int combatInit()

// SFALL
criticalsInit();
burstModInit();

return 0;
}
Expand Down Expand Up @@ -3591,31 +3600,36 @@ static int _compute_spray(Attack* attack, int accuracy, int* a3, int* a4, int an
accuracy += 20;
}

int v31;
int v14;
int v33;
int v30;
int leftRounds;
int mainTargetRounds;
int centerRounds;
int rightRounds;
if (anim == ANIM_FIRE_BURST) {
v33 = ammoQuantity / 3;
if (v33 == 0) {
v33 = 1;
}
// SFALL: Burst mod.
if (gBurstModEnabled) {
mainTargetRounds = burstModComputeRounds(ammoQuantity, &centerRounds, &leftRounds, &rightRounds);
} else {
centerRounds = ammoQuantity / 3;
if (centerRounds == 0) {
centerRounds = 1;
}

v31 = ammoQuantity / 3;
v30 = ammoQuantity - v33 - v31;
v14 = v33 / 2;
if (v14 == 0) {
v14 = 1;
v33 -= 1;
leftRounds = ammoQuantity / 3;
rightRounds = ammoQuantity - centerRounds - leftRounds;
mainTargetRounds = centerRounds / 2;
if (mainTargetRounds == 0) {
mainTargetRounds = 1;
centerRounds -= 1;
}
}
} else {
v31 = 1;
v14 = 1;
v33 = 1;
v30 = 1;
leftRounds = 1;
mainTargetRounds = 1;
centerRounds = 1;
rightRounds = 1;
}

for (int index = 0; index < v14; index += 1) {
for (int index = 0; index < mainTargetRounds; index += 1) {
if (randomRoll(accuracy, 0, NULL) >= ROLL_SUCCESS) {
*a3 += 1;
}
Expand All @@ -3626,28 +3640,25 @@ static int _compute_spray(Attack* attack, int accuracy, int* a3, int* a4, int an
}

int range = _item_w_range(attack->attacker, attack->hitMode);
int v19 = _tile_num_beyond(attack->attacker->tile, attack->defender->tile, range);

*a3 += _shoot_along_path(attack, v19, v33 - *a3, anim);
int mainTargetEndTile = _tile_num_beyond(attack->attacker->tile, attack->defender->tile, range);
*a3 += _shoot_along_path(attack, mainTargetEndTile, centerRounds - *a3, anim);

int v20;
int centerTile;
if (objectGetDistanceBetween(attack->attacker, attack->defender) <= 3) {
v20 = _tile_num_beyond(attack->attacker->tile, attack->defender->tile, 3);
centerTile = _tile_num_beyond(attack->attacker->tile, attack->defender->tile, 3);
} else {
v20 = attack->defender->tile;
centerTile = attack->defender->tile;
}

int rotation = tileGetRotationTo(v20, attack->attacker->tile);
int v23 = tileGetTileInDirection(v20, (rotation + 1) % ROTATION_COUNT, 1);

int v25 = _tile_num_beyond(attack->attacker->tile, v23, range);
int rotation = tileGetRotationTo(centerTile, attack->attacker->tile);

*a3 += _shoot_along_path(attack, v25, v31, anim);
int leftTile = tileGetTileInDirection(centerTile, (rotation + 1) % ROTATION_COUNT, 1);
int leftEndTile = _tile_num_beyond(attack->attacker->tile, leftTile, range);
*a3 += _shoot_along_path(attack, leftEndTile, leftRounds, anim);

int v26 = tileGetTileInDirection(v20, (rotation + 5) % ROTATION_COUNT, 1);

int v28 = _tile_num_beyond(attack->attacker->tile, v26, range);
*a3 += _shoot_along_path(attack, v28, v30, anim);
int rightTile = tileGetTileInDirection(centerTile, (rotation + 5) % ROTATION_COUNT, 1);
int rightEndTile = _tile_num_beyond(attack->attacker->tile, rightTile, range);
*a3 += _shoot_along_path(attack, rightEndTile, rightRounds, anim);

if (roll != ROLL_FAILURE || (*a3 <= 0 && attack->extrasLength <= 0)) {
if (roll >= ROLL_SUCCESS && *a3 == 0 && attack->extrasLength == 0) {
Expand Down Expand Up @@ -6117,3 +6128,52 @@ void criticalsResetValue(int killType, int hitLocation, int effect, int dataMemb
gCriticalHitTables[killType][hitLocation][effect].values[dataMember] = gBaseCriticalHitTables[killType][hitLocation][effect].values[dataMember];
}
}

static void burstModInit()
{
configGetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_ENABLED_KEY, &gBurstModEnabled);

configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_CENTER_MULTIPLIER_KEY, &gBurstModCenterMultiplier);
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_CENTER_DIVISOR_KEY, &gBurstModCenterDivisor);
if (gBurstModCenterDivisor < 1) {
gBurstModCenterDivisor = 1;
}
if (gBurstModCenterMultiplier > gBurstModCenterDivisor) {
gBurstModCenterMultiplier = gBurstModCenterDivisor;
}

configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_TARGET_MULTIPLIER_KEY, &gBurstModTargetMultiplier);
configGetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_TARGET_DIVISOR_KEY, &gBurstModTargetDivisor);
if (gBurstModTargetDivisor < 1) {
gBurstModTargetDivisor = 1;
}
if (gBurstModTargetMultiplier > gBurstModTargetDivisor) {
gBurstModTargetMultiplier = gBurstModTargetDivisor;
}
}

static int burstModComputeRounds(int totalRounds, int* centerRoundsPtr, int* leftRoundsPtr, int* rightRoundsPtr)
{
int totalRoundsMultiplied = totalRounds * gBurstModCenterMultiplier;
int centerRounds = totalRoundsMultiplied / gBurstModCenterDivisor;
if ((totalRoundsMultiplied % gBurstModCenterDivisor) != 0) {
centerRounds++;
}

if (centerRounds == 0) {
centerRounds++;
}
*centerRoundsPtr = centerRounds;

int leftRounds = (totalRounds - centerRounds) / 2;
*leftRoundsPtr = leftRounds;
*rightRoundsPtr = totalRounds - centerRounds - leftRounds;

int centerRoundsMultiplied = centerRounds * gBurstModTargetMultiplier;
int mainTargetRounds = centerRoundsMultiplied / gBurstModTargetDivisor;
if ((centerRoundsMultiplied % gBurstModTargetDivisor) != 0) {
mainTargetRounds++;
}

return mainTargetRounds;
}
5 changes: 5 additions & 0 deletions src/sfall_config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ bool sfallConfigInit(int argc, char** argv)
configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_CONSOLE_OUTPUT_FILE_KEY, "");
configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_PREMADE_CHARACTERS_FILE_NAMES_KEY, "");
configSetString(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_PREMADE_CHARACTERS_FACE_FIDS_KEY, "");
configSetBool(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_ENABLED_KEY, false);
configSetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_CENTER_MULTIPLIER_KEY, SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_MULTIPLIER);
configSetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_CENTER_DIVISOR_KEY, SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_DIVISOR);
configSetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_TARGET_MULTIPLIER_KEY, SFALL_CONFIG_BURST_MOD_DEFAULT_TARGET_MULTIPLIER);
configSetInt(&gSfallConfig, SFALL_CONFIG_MISC_KEY, SFALL_CONFIG_BURST_MOD_TARGET_DIVISOR_KEY, SFALL_CONFIG_BURST_MOD_DEFAULT_TARGET_DIVISOR);

char path[COMPAT_MAX_PATH];
char* executable = argv[0];
Expand Down
10 changes: 10 additions & 0 deletions src/sfall_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@
#define SFALL_CONFIG_CONSOLE_OUTPUT_FILE_KEY "ConsoleOutputPath"
#define SFALL_CONFIG_PREMADE_CHARACTERS_FILE_NAMES_KEY "PremadePaths"
#define SFALL_CONFIG_PREMADE_CHARACTERS_FACE_FIDS_KEY "PremadeFIDs"
#define SFALL_CONFIG_BURST_MOD_ENABLED_KEY "ComputeSprayMod"
#define SFALL_CONFIG_BURST_MOD_CENTER_MULTIPLIER_KEY "ComputeSpray_CenterMult"
#define SFALL_CONFIG_BURST_MOD_CENTER_DIVISOR_KEY "ComputeSpray_CenterDiv"
#define SFALL_CONFIG_BURST_MOD_TARGET_MULTIPLIER_KEY "ComputeSpray_TargetMult"
#define SFALL_CONFIG_BURST_MOD_TARGET_DIVISOR_KEY "ComputeSpray_TargetDiv"

#define SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_MULTIPLIER 1
#define SFALL_CONFIG_BURST_MOD_DEFAULT_CENTER_DIVISOR 3
#define SFALL_CONFIG_BURST_MOD_DEFAULT_TARGET_MULTIPLIER 1
#define SFALL_CONFIG_BURST_MOD_DEFAULT_TARGET_DIVISOR 2

extern bool gSfallConfigInitialized;
extern Config gSfallConfig;
Expand Down

0 comments on commit 3ccb087

Please sign in to comment.