Skip to content

Commit

Permalink
MiningComponent: scale build points provided by a miner with time
Browse files Browse the repository at this point in the history
  • Loading branch information
necessarily-equal committed Oct 25, 2021
1 parent 713b25f commit 44d52c9
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 5 deletions.
41 changes: 39 additions & 2 deletions src/sgame/components/MiningComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ MiningComponent::MiningComponent(Entity& entity, bool blueprint,
// Inform neighbouring miners so they can adjust their own predictions.
// Note that blueprint miners skip this.
InformNeighbors();

REGISTER_THINKER(Think, ThinkingComponent::SCHEDULER_AVERAGE, 250);
}

void MiningComponent::HandlePrepareNetCode() {
Expand Down Expand Up @@ -47,7 +49,25 @@ void MiningComponent::HandleDie(gentity_t* /*killer*/, meansOfDeath_t /*meansOfD
G_UpdateBuildPointBudgets();
}

float MiningComponent::InterferenceMod(float distance) {
float MiningComponent::AliveTimePercentage() const {
constexpr float fullyActiveTime = 3.0f * 60.0f * 1000.0f; // 3 minutes

Log::Warn("creation time: %i", entity.oldEnt->creationTime);
if (entity.oldEnt->creationTime < 1000)
return 1.0f; // spawned with world, can be considered alive since long

// TODO: use time after activating, and not after spawning
float activeTime = static_cast<float>(
level.time - entity.oldEnt->creationTime);

return Math::Clamp(activeTime / fullyActiveTime, 0.0f, 1.0f);
}

float MiningComponent::AliveTimeMod() const {
return AliveTimePercentage();
}

float MiningComponent::PredictedInterferenceMod(float distance) {
if (RGS_RANGE <= 0.0f) return 1.0f;
if (distance > 2.0f * RGS_RANGE) return 1.0f;

Expand Down Expand Up @@ -76,7 +96,7 @@ void MiningComponent::CalculateEfficiency() {
HealthComponent *healthComponent = other.Get<HealthComponent>();
if (healthComponent && !healthComponent->Alive()) return;

float interferenceMod = InterferenceMod(G_Distance(entity.oldEnt, other.oldEnt));
float interferenceMod = PredictedInterferenceMod(G_Distance(entity.oldEnt, other.oldEnt));

// TODO: Exclude enemy miners in construction from the prediction.

Expand All @@ -89,6 +109,7 @@ void MiningComponent::CalculateEfficiency() {
if (!miningComponent.Active()) return;

currentEfficiency *= interferenceMod;
currentEfficiency *= AliveTimeMod();
});
}

Expand All @@ -108,3 +129,19 @@ void MiningComponent::InformNeighbors() {
float MiningComponent::Efficiency(bool predict) {
return predict ? predictedEfficiency : currentEfficiency;
}

void MiningComponent::Think(int)
{
// Already calculate the predicted efficiency.
CalculateEfficiency();

// Inform neighbouring miners so they can adjust their own predictions.
// Note that blueprint miners skip this.
InformNeighbors();

// Update both team's budgets.
G_UpdateBuildPointBudgets();

// TODO: stop thinking after some time
//GetThinkingComponent().UnregisterActiveThinker();
}
19 changes: 17 additions & 2 deletions src/sgame/components/MiningComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ class MiningComponent: public MiningComponentBase {
* @param r_ThinkingComponent A ThinkingComponent instance that this component depends on.
* @note This method is an interface for autogenerated code, do not modify its signature.
*/
MiningComponent(Entity& entity, bool blueprint, ThinkingComponent& r_ThinkingComponent);
MiningComponent(Entity& entity, bool blueprint,
ThinkingComponent& r_ThinkingComponent);

/**
* @brief Handle the PrepareNetCode message.
Expand Down Expand Up @@ -45,7 +46,7 @@ class MiningComponent: public MiningComponentBase {
* @brief Calculates modifier for the efficiency of one miner when another one interferes at
* given distance.
*/
static float InterferenceMod(float distance);
static float PredictedInterferenceMod(float distance);

/**
* @return Whether the miner is currently mining (and interfering with other miners).
Expand All @@ -70,6 +71,8 @@ class MiningComponent: public MiningComponentBase {
int Budget(bool predict = false);

private:
void Think(int timeDelta);

/**
* @brief Whether the miner is currently mining (and interfering with other miners).
*/
Expand All @@ -94,6 +97,18 @@ class MiningComponent: public MiningComponentBase {
* @brief Adjust the rate of all other mining structures in range.
*/
void InformNeighbors();

/**
* @brief The percentage of time elasped before the drill
* works at full capacity
*/
float AliveTimePercentage() const;

/**
* @brief Calculates modifier for the efficiency of a miner
* given how long it lived.
*/
float AliveTimeMod() const;
};

#endif // MINING_COMPONENT_H_
2 changes: 1 addition & 1 deletion src/sgame/sg_buildpoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ float G_RGSPredictOwnEfficiency(vec3_t origin) {
static float RGSPredictEfficiencyLoss(Entity& miner, vec3_t newMinerOrigin) {
float distance = Distance(miner.oldEnt->s.origin, newMinerOrigin);
float oldPredictedEfficiency = miner.Get<MiningComponent>()->Efficiency(true);
float newPredictedEfficiency = oldPredictedEfficiency * MiningComponent::InterferenceMod(distance);
float newPredictedEfficiency = oldPredictedEfficiency * MiningComponent::PredictedInterferenceMod(distance);
float efficiencyLoss = newPredictedEfficiency - oldPredictedEfficiency;

buildpointLogger.Debug("Predicted efficiency loss of existing miner: %f - %f = %f.",
Expand Down

0 comments on commit 44d52c9

Please sign in to comment.