summaryrefslogtreecommitdiffhomepage
path: root/StarsEx
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2024-04-03 01:31:01 +0200
committerAki <please@ignore.pl>2024-04-03 01:31:01 +0200
commite0f9f411056c235947b809cb21c477aa5acca1b4 (patch)
tree1371e376659d66ec0c881032b6001630aa4f964b /StarsEx
parent7f1e5f578ec184ebcbbdcd9f7725619ea426d5e4 (diff)
downloadstarshatter-e0f9f411056c235947b809cb21c477aa5acca1b4.zip
starshatter-e0f9f411056c235947b809cb21c477aa5acca1b4.tar.gz
starshatter-e0f9f411056c235947b809cb21c477aa5acca1b4.tar.bz2
Fixed mission points reward calculation
Diffstat (limited to 'StarsEx')
-rw-r--r--StarsEx/CMakeLists.txt2
-rw-r--r--StarsEx/DebriefDlg.cpp13
-rw-r--r--StarsEx/Player.cpp71
-rw-r--r--StarsEx/Player.h3
-rw-r--r--StarsEx/Sim.cpp3
-rw-r--r--StarsEx/SimEvent.cpp52
-rw-r--r--StarsEx/SimEvent.h46
-rw-r--r--StarsEx/test/ShipStats.cpp29
-rw-r--r--StarsEx/test/dump_missions.cpp1
9 files changed, 134 insertions, 86 deletions
diff --git a/StarsEx/CMakeLists.txt b/StarsEx/CMakeLists.txt
index 6a6b4d6..3e9dc83 100644
--- a/StarsEx/CMakeLists.txt
+++ b/StarsEx/CMakeLists.txt
@@ -332,7 +332,9 @@ endif()
add_executable(
${PROJECT_NAME}_test
test/AudioConfig.cpp
+ test/ShipStats.cpp
test/Stardate.cpp
+ test/dump_missions.cpp
)
generate_emulator(${PROJECT_NAME}_test LIBS Opcode ArchiveEx)
target_link_libraries(${PROJECT_NAME}_test PRIVATE ${PROJECT_NAME} GTest::gtest_main)
diff --git a/StarsEx/DebriefDlg.cpp b/StarsEx/DebriefDlg.cpp
index 1cd919b..b613e3c 100644
--- a/StarsEx/DebriefDlg.cpp
+++ b/StarsEx/DebriefDlg.cpp
@@ -185,16 +185,9 @@ DebriefDlg::Show()
ShipStats* stats = ShipStats::GetStats(i);
if (stats && !strcmp(ship->Name(), stats->GetName())) {
stats->Summarize();
-
- Player* player = Player::GetCurrentPlayer();
- int points = stats->GetPoints() + stats->GetCommandPoints();
-
- if (player && sim)
- points = player->GetMissionPoints(stats, sim->StartTime()) + stats->GetCommandPoints();
-
- char score[32];
- sprintf_s(score, "%d %s", points, ContentBundle::GetInstance()->GetText("DebriefDlg.points").data());
- mission_score->SetText(score);
+ const auto points = stats->EffectivePoints();
+ mission_score->SetText(Text::format(
+ "%d %s", points, ContentBundle::GetInstance()->GetText("DebriefDlg.points").data()));
break;
}
}
diff --git a/StarsEx/Player.cpp b/StarsEx/Player.cpp
index 091c808..f299079 100644
--- a/StarsEx/Player.cpp
+++ b/StarsEx/Player.cpp
@@ -13,25 +13,25 @@
#include "Player.h"
+#include <algorithm>
#include <cstdint>
-#include "NetLobbyServer.h"
-#include "NetLayer.h"
-#include "Ship.h"
-#include "SimEvent.h"
+#include "Bitmap.h"
#include "Campaign.h"
#include "CampaignSaveGame.h"
-#include "Random.h"
-#include "HUDView.h"
-#include "Mfd.h"
-
+#include "Clock.h"
+#include "ContentBundle.h"
#include "DataLoader.h"
#include "Encrypt.h"
-#include "ParseUtil.h"
#include "FormatUtil.h"
-#include "Bitmap.h"
-#include "Clock.h"
-#include "ContentBundle.h"
+#include "HUDView.h"
+#include "Mfd.h"
+#include "NetLayer.h"
+#include "NetLobbyServer.h"
+#include "ParseUtil.h"
+#include "Random.h"
+#include "Ship.h"
+#include "SimEvent.h"
// +-------------------------------------------------------------------+
@@ -634,54 +634,19 @@ Player::CommandRankRequired(int ship_class)
// +-------------------------------------------------------------------+
-int
-Player::GetMissionPoints(ShipStats* s, std::int_fast32_t flight_time_)
-{
- int result = 0;
-
- if (s) {
- result = s->GetPoints();
-
- // if player survived mission, award one experience point
- // for each minute of action, in ten point blocks:
- if (!s->GetDeaths() && !s->GetColls()) {
- int minutes = flight_time_ / 60;
- minutes /= 10;
- minutes *= 10;
- result += minutes;
-
- if (s->HasEvent(SimEvent::DOCK))
- result += 100;
- }
- else {
- result -= (int) (2.5 * Ship::Value(s->GetShipClass()));
- }
-
- if (result < 0)
- result = 0;
- }
-
- return result;
-}
-
-// +-------------------------------------------------------------------+
-
void
-Player::ProcessStats(ShipStats* s, std::int_fast32_t flight_time_)
+Player::ProcessStats(ShipStats* s)
{
- if (!s) return;
-
+ if (!s)
+ return;
int old_rank = Rank();
- int pts = GetMissionPoints(s, flight_time_);
-
- AddPoints(pts);
- AddPoints(s->GetCommandPoints());
+ AddMissions(1);
+ AddPoints(s->EffectivePoints());
AddKills(s->GetGunKills());
AddKills(s->GetMissileKills());
AddLosses(s->GetDeaths());
AddLosses(s->GetColls());
- AddMissions(1);
- AddFlightTime(flight_time_);
+ AddFlightTime(s->FlightTime());
int rank = Rank();
diff --git a/StarsEx/Player.h b/StarsEx/Player.h
index 62e8700..867e2ca 100644
--- a/StarsEx/Player.h
+++ b/StarsEx/Player.h
@@ -116,8 +116,7 @@ public:
Text EncodeStats();
void DecodeStats(const char* stats);
- int GetMissionPoints(ShipStats* stats, std::int_fast32_t flight_time_);
- void ProcessStats(ShipStats* stats, std::int_fast32_t flight_time_);
+ void ProcessStats(ShipStats* stats);
bool EarnedAward(AwardInfo* a, ShipStats* s);
static const char* RankName(int rank);
diff --git a/StarsEx/Sim.cpp b/StarsEx/Sim.cpp
index f938b7a..5e49cb0 100644
--- a/StarsEx/Sim.cpp
+++ b/StarsEx/Sim.cpp
@@ -206,7 +206,8 @@ Sim::CommitMission()
if (s->IsPlayer()) {
Player* p = Player::GetCurrentPlayer();
- p->ProcessStats(s, starshatter::engine::MissionTime());
+ s->SetFlightTime(starshatter::engine::MissionTime());
+ p->ProcessStats(s);
if (mission && mission->Type() == Mission::TRAINING &&
s->GetDeaths() == 0 && s->GetColls() == 0)
diff --git a/StarsEx/SimEvent.cpp b/StarsEx/SimEvent.cpp
index 35eb117..42ce240 100644
--- a/StarsEx/SimEvent.cpp
+++ b/StarsEx/SimEvent.cpp
@@ -12,9 +12,11 @@
*/
#include "SimEvent.h"
-#include "Sim.h"
+
#include "Clock.h"
#include "ContentBundle.h"
+#include "Ship.h"
+#include "Sim.h"
// +====================================================================+
@@ -191,6 +193,52 @@ ShipStats::Summarize()
}
}
+
+long double
+ShipStats::FlightTime() const
+{
+ return flight_time;
+}
+
+
+void
+ShipStats::SetFlightTime(long double seconds)
+{
+ flight_time = seconds;
+}
+
+
+static int
+FlightTimeBonus(const ShipStats* stats)
+{
+ static constexpr long double TEN_MINUTES {600.0l};
+ return static_cast<int>(stats->FlightTime() / TEN_MINUTES) * 10;
+}
+
+
+static int
+DockBonus(const ShipStats* stats)
+{
+ return stats->HasEvent(SimEvent::DOCK) ? 100 : 0;
+}
+
+
+static int
+LossPenalty(const ShipStats* stats)
+{
+ return 2.5 * Ship::Value(stats->GetShipClass());
+}
+
+
+int
+ShipStats::EffectivePoints() const
+{
+ const auto whole {GetPoints() + GetCommandPoints()};
+ if (GetDeaths() > 0 || GetColls() > 0)
+ return std::max(0, whole - LossPenalty(this));
+ return whole + FlightTimeBonus(this) + DockBonus(this);
+}
+
// +--------------------------------------------------------------------+
SimEvent*
@@ -209,7 +257,7 @@ ShipStats::AddEvent(int event, const char* tgt, const char* info)
}
bool
-ShipStats::HasEvent(int event)
+ShipStats::HasEvent(int event) const
{
for (int i = 0; i < events.size(); i++)
if (events[i]->GetEvent() == event)
diff --git a/StarsEx/SimEvent.h b/StarsEx/SimEvent.h
index 66d6342..c8bd092 100644
--- a/StarsEx/SimEvent.h
+++ b/StarsEx/SimEvent.h
@@ -11,14 +11,11 @@
Simulation Universe and Region classes
*/
-#ifndef SimEvent_h
-#define SimEvent_h
+#pragma once
-#include "Types.h"
-#include "List.h"
-#include "Text.h"
+#include <List.h>
+#include <Text.h>
-// +--------------------------------------------------------------------+
class Sim;
class SimRegion;
@@ -28,19 +25,32 @@ class SimHyper;
class CombatGroup;
class CombatUnit;
-// +--------------------------------------------------------------------+
class SimEvent
{
public:
static const char* TYPENAME() { return "SimEvent"; }
- enum EVENT { LAUNCH=1, DOCK, LAND, EJECT, CRASH, COLLIDE, DESTROYED,
- MAKE_ORBIT, BREAK_ORBIT, QUANTUM_JUMP,
- LAUNCH_SHIP, RECOVER_SHIP,
- FIRE_GUNS, FIRE_MISSILE, DROP_DECOY,
- GUNS_KILL, MISSILE_KILL,
- LAUNCH_PROBE, SCAN_TARGET
+ enum EVENT {
+ LAUNCH=1,
+ DOCK,
+ LAND,
+ EJECT,
+ CRASH,
+ COLLIDE,
+ DESTROYED,
+ MAKE_ORBIT,
+ BREAK_ORBIT,
+ QUANTUM_JUMP,
+ LAUNCH_SHIP,
+ RECOVER_SHIP,
+ FIRE_GUNS,
+ FIRE_MISSILE,
+ DROP_DECOY,
+ GUNS_KILL,
+ MISSILE_KILL,
+ LAUNCH_PROBE,
+ SCAN_TARGET,
};
SimEvent(int event, const char* tgt=0, const char* info=0);
@@ -66,7 +76,6 @@ private:
int count;
};
-// +--------------------------------------------------------------------+
class ShipStats
{
@@ -104,6 +113,8 @@ public:
int GetGunHits() const { return gun_hits; }
int GetMissileShots() const { return missile_shots; }
int GetMissileHits() const { return missile_hits; }
+ long double FlightTime() const;
+ int EffectivePoints() const;
bool IsPlayer() const { return player; }
@@ -111,7 +122,7 @@ public:
GetEvents() { return events; }
SimEvent* AddEvent(SimEvent* e);
SimEvent* AddEvent(int event, const char* tgt=0, const char* info=0);
- bool HasEvent(int event);
+ bool HasEvent(int event) const;
void SetShipClass(int c) { ship_class = c; }
void SetIFF(int i) { iff = i; }
@@ -129,6 +140,7 @@ public:
void AddMissileHit() { missile_hits++; }
void AddPoints(int p) { points += p; }
void AddCommandPoints(int p) { cmd_points += p; }
+ void SetFlightTime(long double seconds);
private:
Text name;
@@ -155,8 +167,6 @@ private:
int points;
int cmd_points;
+ long double flight_time;
List<SimEvent> events;
};
-
-#endif // SimEvent_h
-
diff --git a/StarsEx/test/ShipStats.cpp b/StarsEx/test/ShipStats.cpp
new file mode 100644
index 0000000..1430573
--- /dev/null
+++ b/StarsEx/test/ShipStats.cpp
@@ -0,0 +1,29 @@
+#include <gtest/gtest.h>
+
+#include <Clock.h>
+#include <SimEvent.h>
+
+
+TEST(StarsEx, EffectivePoints)
+{
+ Clock::Init();
+ ShipStats::Initialize();
+ auto* first = ShipStats::Find("first");
+ ASSERT_NE(nullptr, first);
+ EXPECT_EQ(0, first->EffectivePoints());
+ first->SetFlightTime(590.0l);
+ EXPECT_EQ(0, first->EffectivePoints());
+ first->SetFlightTime(610.0l);
+ EXPECT_EQ(10, first->EffectivePoints());
+ first->SetFlightTime(1210.0l);
+ EXPECT_EQ(20, first->EffectivePoints());
+ const auto* destroyed = first->AddEvent(SimEvent::DESTROYED);
+ first->Summarize();
+ EXPECT_EQ(0, first->EffectivePoints());
+ auto* second = ShipStats::Find("second");
+ ASSERT_NE(nullptr, second);
+ const auto* docked = second->AddEvent(SimEvent::DOCK);
+ EXPECT_EQ(100, second->EffectivePoints());
+ ShipStats::Close();
+ Clock::Close();
+}
diff --git a/StarsEx/test/dump_missions.cpp b/StarsEx/test/dump_missions.cpp
new file mode 100644
index 0000000..a0e5ffc
--- /dev/null
+++ b/StarsEx/test/dump_missions.cpp
@@ -0,0 +1 @@
+int dump_missions = 0;