Skip to content

Commit

Permalink
consistent grenade/missile/plasma shooting rates (#417)
Browse files Browse the repository at this point in the history
* fix FramesFromNow usage

many frame number checks were of the form
    if (doSomething < frameNumber) {
        doSomething = FrameFromNow(3)
    }

For classic mode that means to doSomething at most every 4th frame.  But for high-FPS, this code would start
doing something on frame 13 instead of on frame 16... faster than classic.

Changing code to work across frame rates like this:
    if (doSomething <= frameNumber) {
        doSomething = FrameFromNow(3+1)
    }

* fix tests and bugs found by tests

The HECTOR.Boost* tests had to be fixed because they were actually boosting on frame 1 since boostEndFrame inits to 0.

* added 1 classic-frame limiter to the plasma shot

so that all frame rates behave the same on shooting rate
  • Loading branch information
tra authored Jul 10, 2024
1 parent 862a756 commit 056308d
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 23 deletions.
22 changes: 12 additions & 10 deletions src/game/CAbstractPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ void CAbstractPlayer::StartSystems() {

nextGrenadeLoad = 0;
nextMissileLoad = 0;
nextPlasmaShot = 0;

// variables in AdaptableSettings need to have "classic" counterparts in case they are changed in CWalkerActor::ReceiveConfig()
classicGeneratorPower = FIX3(30);
Expand Down Expand Up @@ -1144,12 +1145,12 @@ void CAbstractPlayer::ArmSmartMissile() {
}

if (!didDetach && oldKind != kweSmart && missileCount) {
if (nextMissileLoad < itsGame->frameNumber) {
if (nextMissileLoad <= itsGame->frameNumber) {
theWeapon = itsGame->itsDepot->AquireWeapon(kweSmart);
weaponIdent = theWeapon->Arm(viewPortPart);
if (weaponIdent) {
missileCount--;
nextMissileLoad = itsGame->FramesFromNow(3);
nextMissileLoad = itsGame->FramesFromNow(4);
}
} else
fireGun = false;
Expand Down Expand Up @@ -1177,12 +1178,12 @@ void CAbstractPlayer::ArmGrenade() {
}

if (!didDetach && oldKind != kweGrenade && grenadeCount) {
if (nextGrenadeLoad < itsGame->frameNumber) {
if (nextGrenadeLoad <= itsGame->frameNumber) {
theWeapon = itsGame->itsDepot->AquireWeapon(kweGrenade);
weaponIdent = theWeapon->Arm(viewPortPart);
if (weaponIdent) {
grenadeCount--;
nextGrenadeLoad = itsGame->FramesFromNow(2);
nextGrenadeLoad = itsGame->FramesFromNow(3);
}
} else
fireGun = false;
Expand Down Expand Up @@ -1294,11 +1295,11 @@ void CAbstractPlayer::KeyboardControl(FunctionTable *ft) {

FPS_DEBUG(" motors after keyb = " << FormatVector(motors, 2) << std::endl);

if (TESTFUNC(kfuBoostEnergy, ft->down) && boostsRemaining && (boostEndFrame < itsGame->frameNumber)) {
if (TESTFUNC(kfuBoostEnergy, ft->down) && boostsRemaining && (boostEndFrame <= itsGame->frameNumber)) {
CBasicSound *theSound;

boostsRemaining--;
boostEndFrame = itsGame->FramesFromNow(BOOSTLENGTH);
boostEndFrame = itsGame->FramesFromNow(BOOSTLENGTH+1);

if (!boostControlLink)
boostControlLink = gHub->GetSoundLink();
Expand Down Expand Up @@ -1715,7 +1716,8 @@ void CAbstractPlayer::GunActions() {
if (weapon) {
weapon->Fire();
weaponIdent = 0;
} else {
} else if (nextPlasmaShot <= itsGame->frameNumber) {
nextPlasmaShot = itsGame->FramesFromNow(1);
i = gunEnergy[0] < gunEnergy[1];
if (gunEnergy[i] >= activeGunEnergy) {
Vector missileSpeed;
Expand Down Expand Up @@ -1986,7 +1988,7 @@ bool CAbstractPlayer::ReincarnateComplete(CIncarnator* newSpot) {
LinkPartSpheres();

if (reEnergize) {
boostEndFrame = itsGame->FramesFromNow(MINIBOOSTTIME);
boostEndFrame = itsGame->FramesFromNow(MINIBOOSTTIME+1);
reEnergize = false;
if (shields < maxShields)
shields = maxShields;
Expand Down Expand Up @@ -2299,10 +2301,10 @@ void CAbstractPlayer::TakeGoody(GoodyRecord *gr) {
if (energy > maxEnergy)
energy = maxEnergy;

if (gr->boostTime > 0 && (boostEndFrame < itsGame->frameNumber)) {
if (gr->boostTime > 0 && (boostEndFrame <= itsGame->frameNumber)) {
CBasicSound *theSound;

boostEndFrame = itsGame->FramesFromNow(gr->boostTime);
boostEndFrame = itsGame->FramesFromNow(gr->boostTime+1);

if (!boostControlLink)
boostControlLink = gHub->GetSoundLink();
Expand Down
1 change: 1 addition & 0 deletions src/game/CAbstractPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class CAbstractPlayer : public CRealMovers {
short grenadeCount = 0;
FrameNumber nextGrenadeLoad = 0;
FrameNumber nextMissileLoad = 0;
FrameNumber nextPlasmaShot = 0;

short missileLimit = 0;
short grenadeLimit = 0;
Expand Down
8 changes: 4 additions & 4 deletions src/game/CBall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ void CBall::MagnetAction() {
Vector snapTo;
CSmartPart *newHost;

if ((theActor->ident != oldHost || looseFrame < thisFrame) &&
if ((theActor->ident != oldHost || looseFrame <= thisFrame) &&
!(theActor->maskBits & kPlayerBit && holdShieldLimit < shields && theActor->teamColor != teamColor)) {
snapCode = theActor->GetBallSnapPoint(group, location, snapTo, localSnap, &newHost);

Expand Down Expand Up @@ -495,7 +495,7 @@ void CBall::FrameAction() {
SecondaryDamage(teamColor, -1, ksiObjectCollision);
return; // *** return after dispose! ***
case kDoRelease:
looseFrame = itsGame->FramesFromNow(100);
looseFrame = itsGame->FramesFromNow(101);
oldHost = hostIdent;
case kDoReset: {
CSmartPart *savedHost;
Expand Down Expand Up @@ -532,7 +532,7 @@ long CBall::ReceiveSignal(long theSignal, void *miscData) {
case kBallReleaseSignal: {
CSmartPart *theBall = partList[0];

looseFrame = itsGame->FramesFromNow(32);
looseFrame = itsGame->FramesFromNow(33);
oldHost = hostIdent;
ReleaseAttachment();
speed[0] += FMul(pitchZ, theBall->itsTransform[2][0]) + FMul(pitchY, theBall->itsTransform[1][0]);
Expand Down Expand Up @@ -563,7 +563,7 @@ void CBall::ReleaseDamage(Fixed hitEnergy) {
if (hostPart && playerAttach) {
releaseHoldAccumulator += hitEnergy;
if (releaseHoldAccumulator > dropDamage) {
looseFrame = itsGame->FramesFromNow(10);
looseFrame = itsGame->FramesFromNow(11);
oldHost = hostIdent;
ReleaseAttachment();
}
Expand Down
18 changes: 9 additions & 9 deletions src/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,11 +468,11 @@ vector<HectorEnergyReadings> HectorEnergyRegen(int steps, bool useBoost, int fra
int ticksPerStep = GetTicksPerStep(frameTime);

scenario.hector->energy = scenario.hector->maxEnergy * 0.5;
if (useBoost) {
scenario.hector->itsManager->GetFunctions()->down = (1 << kfuBoostEnergy);
}

for (int i = 0; i < steps; i++) {
if (i == 1 && useBoost) {
scenario.hector->itsManager->GetFunctions()->down = (1 << kfuBoostEnergy);
}
HectorEnergyReadings current(scenario.hector);
energyValues.push_back(current);
for (int k = 0; k < ticksPerStep; k++) {
Expand All @@ -490,11 +490,11 @@ vector<HectorEnergyReadings> HectorPlasmaRegen(int steps, bool useBoost, int fra

scenario.hector->gunEnergy[0] = 0;
scenario.hector->gunEnergy[1] = 0;
if (useBoost) {
scenario.hector->itsManager->GetFunctions()->down = (1 << kfuBoostEnergy);
}

for (int i = 0; i < steps; i++) {
if (i == 1 && useBoost) {
scenario.hector->itsManager->GetFunctions()->down = (1 << kfuBoostEnergy);
}
HectorEnergyReadings current(scenario.hector);
energyValues.push_back(current);
for (int k = 0; k < ticksPerStep; k++) {
Expand All @@ -511,11 +511,11 @@ vector<HectorEnergyReadings> HectorShieldRegen(int steps, bool useBoost, int fra
int ticksPerStep = GetTicksPerStep(frameTime);

scenario.hector->shields = scenario.hector->maxShields * 0.5;
if (useBoost) {
scenario.hector->itsManager->GetFunctions()->down = (1 << kfuBoostEnergy);
}

for (int i = 0; i < steps; i++) {
if (i == 1 && useBoost) {
scenario.hector->itsManager->GetFunctions()->down = (1 << kfuBoostEnergy);
}
HectorEnergyReadings current(scenario.hector);
energyValues.push_back(current);
for (int k = 0; k < ticksPerStep; k++) {
Expand Down

0 comments on commit 056308d

Please sign in to comment.