Skip to content

Commit 95a7537

Browse files
authored
QtFRED mission stats dialog (scp-fs2open#7333)
* qtfred mission stats dialog * clang * fix float division
1 parent cc26887 commit 95a7537

9 files changed

Lines changed: 768 additions & 0 deletions

File tree

qtfred/source_groups.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ add_file_folder("Source/Mission/Dialogs"
6464
src/mission/dialogs/MissionEventsDialogModel.h
6565
src/mission/dialogs/MissionGoalsDialogModel.cpp
6666
src/mission/dialogs/MissionGoalsDialogModel.h
67+
src/mission/dialogs/MissionStatsDialogModel.cpp
68+
src/mission/dialogs/MissionStatsDialogModel.h
6769
src/mission/dialogs/MissionSpecDialogModel.cpp
6870
src/mission/dialogs/MissionSpecDialogModel.h
6971
src/mission/dialogs/MusicPlayerDialogModel.cpp
@@ -142,6 +144,8 @@ add_file_folder("Source/UI"
142144
add_file_folder("Source/UI/Dialogs"
143145
src/ui/dialogs/AboutDialog.cpp
144146
src/ui/dialogs/AboutDialog.h
147+
src/ui/dialogs/MissionStatsDialog.cpp
148+
src/ui/dialogs/MissionStatsDialog.h
145149
src/ui/dialogs/AsteroidEditorDialog.cpp
146150
src/ui/dialogs/AsteroidEditorDialog.h
147151
src/ui/dialogs/BackgroundEditorDialog.h
@@ -309,6 +313,7 @@ add_file_folder("UI"
309313
ui/MissionCutscenesDialog.ui
310314
ui/MissionEventsDialog.ui
311315
ui/MissionGoalsDialog.ui
316+
ui/MissionStatsDialog.ui
312317
ui/MissionSpecDialog.ui
313318
ui/MusicPlayerDialog.ui
314319
ui/ObjectOrientationDialog.ui
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
//
2+
3+
#include "MissionStatsDialogModel.h"
4+
5+
#include <ship/ship.h>
6+
#include <object/waypoint.h>
7+
#include <object/object.h>
8+
#include <mission/missionmessage.h>
9+
#include <mission/missiongoals.h>
10+
#include <parse/sexp.h>
11+
#include <parse/sexp_container.h>
12+
#include <iff_defs/iff_defs.h>
13+
#include <jumpnode/jumpnode.h>
14+
#include <prop/prop.h>
15+
#include <globalincs/globals.h>
16+
#include <globalincs/linklist.h>
17+
18+
namespace fso::fred::dialogs {
19+
20+
MissionStatsDialogModel::MissionStatsDialogModel(QObject* parent, EditorViewport* viewport)
21+
: AbstractDialogModel(parent, viewport)
22+
{
23+
}
24+
25+
bool MissionStatsDialogModel::apply()
26+
{
27+
return true;
28+
}
29+
30+
void MissionStatsDialogModel::reject()
31+
{
32+
}
33+
34+
int MissionStatsDialogModel::getNumObjects()
35+
{
36+
return Num_objects;
37+
}
38+
39+
int MissionStatsDialogModel::getMaxObjects()
40+
{
41+
return MAX_OBJECTS;
42+
}
43+
44+
int MissionStatsDialogModel::getShipCount()
45+
{
46+
return ship_get_num_ships();
47+
}
48+
49+
int MissionStatsDialogModel::getMaxShips()
50+
{
51+
return MAX_SHIPS;
52+
}
53+
54+
int MissionStatsDialogModel::getPropCount()
55+
{
56+
int count = 0;
57+
for (const auto& p : Props) {
58+
if (p.has_value())
59+
count++;
60+
}
61+
return count;
62+
}
63+
64+
int MissionStatsDialogModel::getWingCount()
65+
{
66+
return Num_wings;
67+
}
68+
69+
int MissionStatsDialogModel::getWaypointPathCount()
70+
{
71+
return static_cast<int>(Waypoint_lists.size());
72+
}
73+
74+
int MissionStatsDialogModel::getJumpNodeCount()
75+
{
76+
return static_cast<int>(Jump_nodes.size());
77+
}
78+
79+
int MissionStatsDialogModel::getMessageCount()
80+
{
81+
return Num_messages;
82+
}
83+
84+
int MissionStatsDialogModel::getEventCount()
85+
{
86+
return static_cast<int>(Mission_events.size());
87+
}
88+
89+
int MissionStatsDialogModel::getGoalCount()
90+
{
91+
return static_cast<int>(Mission_goals.size());
92+
}
93+
94+
int MissionStatsDialogModel::getVariableCount()
95+
{
96+
return sexp_variable_count();
97+
}
98+
99+
int MissionStatsDialogModel::getContainerCount()
100+
{
101+
return static_cast<int>(get_all_sexp_containers().size());
102+
}
103+
104+
SCP_vector<std::pair<SCP_string, MissionStatsDialogModel::IFFShipCounts>> MissionStatsDialogModel::getShipsByIFF()
105+
{
106+
SCP_map<int, IFFShipCounts> iffCounts;
107+
108+
for (auto* objp = GET_FIRST(&obj_used_list); objp != END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp)) {
109+
if (objp->type != OBJ_SHIP && objp->type != OBJ_START)
110+
continue;
111+
112+
const ship* shipp = &Ships[objp->instance];
113+
const ship_info& sip = Ship_info[shipp->ship_info_index];
114+
int iff = shipp->team;
115+
116+
IFFShipCounts& rc = iffCounts[iff];
117+
if (sip.flags[Ship::Info_Flags::Fighter]) {
118+
rc.fighter++;
119+
} else if (sip.flags[Ship::Info_Flags::Bomber]) {
120+
rc.bomber++;
121+
} else if (sip.flags[Ship::Info_Flags::Capital] ||
122+
sip.flags[Ship::Info_Flags::Supercap] ||
123+
sip.flags[Ship::Info_Flags::Cruiser] ||
124+
sip.flags[Ship::Info_Flags::Corvette]) {
125+
rc.capital++;
126+
} else {
127+
rc.other++;
128+
}
129+
}
130+
131+
SCP_vector<std::pair<SCP_string, IFFShipCounts>> result;
132+
for (int i = 0; i < static_cast<int>(Iff_info.size()); ++i) {
133+
auto it = iffCounts.find(i);
134+
if (it == iffCounts.end())
135+
continue;
136+
result.emplace_back(Iff_info[i].iff_name, it->second);
137+
}
138+
return result;
139+
}
140+
141+
SCP_vector<MissionStatsDialogModel::EscortEntry> MissionStatsDialogModel::getEscortList()
142+
{
143+
SCP_vector<EscortEntry> result;
144+
145+
for (auto* objp = GET_FIRST(&obj_used_list); objp != END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp)) {
146+
if (objp->type != OBJ_SHIP && objp->type != OBJ_START)
147+
continue;
148+
const ship* shipp = &Ships[objp->instance];
149+
if (shipp->flags[Ship::Ship_Flags::Escort]) {
150+
result.push_back({ shipp->ship_name, shipp->escort_priority });
151+
}
152+
}
153+
154+
return result;
155+
}
156+
157+
SCP_map<int, SCP_vector<SCP_string>> MissionStatsDialogModel::getHotkeyMap()
158+
{
159+
SCP_map<int, SCP_vector<SCP_string>> result;
160+
161+
for (auto& wing : Wings) {
162+
if (wing.wave_count > 0 && wing.hotkey >= 0) {
163+
result[wing.hotkey].emplace_back(SCP_string(wing.name) + " (wing)");
164+
}
165+
}
166+
167+
for (auto* objp = GET_FIRST(&obj_used_list); objp != END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp)) {
168+
if (objp->type != OBJ_SHIP && objp->type != OBJ_START)
169+
continue;
170+
const ship* shipp = &Ships[objp->instance];
171+
if (shipp->hotkey >= 0) {
172+
result[shipp->hotkey].emplace_back(shipp->ship_name);
173+
}
174+
}
175+
176+
return result;
177+
}
178+
179+
} // namespace fso::fred::dialogs
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#pragma once
2+
3+
#include <mission/EditorViewport.h>
4+
#include "AbstractDialogModel.h"
5+
6+
#include <globalincs/pstypes.h>
7+
8+
namespace fso::fred::dialogs {
9+
10+
class MissionStatsDialogModel : public AbstractDialogModel {
11+
Q_OBJECT
12+
13+
public:
14+
struct IFFShipCounts {
15+
int fighter = 0;
16+
int bomber = 0;
17+
int capital = 0;
18+
int other = 0;
19+
int total() const { return fighter + bomber + capital + other; }
20+
};
21+
22+
struct EscortEntry {
23+
SCP_string name;
24+
int priority = 0;
25+
};
26+
27+
MissionStatsDialogModel(QObject* parent, EditorViewport* viewport);
28+
29+
bool apply() override;
30+
void reject() override;
31+
32+
// Summary counts
33+
static int getNumObjects();
34+
static int getMaxObjects();
35+
static int getShipCount();
36+
static int getMaxShips();
37+
static int getPropCount();
38+
static int getWingCount();
39+
static int getWaypointPathCount();
40+
static int getJumpNodeCount();
41+
static int getMessageCount();
42+
static int getEventCount();
43+
static int getGoalCount();
44+
static int getVariableCount();
45+
static int getContainerCount();
46+
47+
static SCP_vector<std::pair<SCP_string, IFFShipCounts>> getShipsByIFF();
48+
49+
static SCP_vector<EscortEntry> getEscortList();
50+
51+
static SCP_map<int, SCP_vector<SCP_string>> getHotkeyMap();
52+
};
53+
54+
} // namespace fso::fred::dialogs

qtfred/src/ui/FredView.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <ui/dialogs/MissionCutscenesDialog.h>
2828
#include <ui/dialogs/FormWingDialog.h>
2929
#include <ui/dialogs/AboutDialog.h>
30+
#include <ui/dialogs/MissionStatsDialog.h>
3031
#include <ui/dialogs/BackgroundEditorDialog.h>
3132
#include <ui/dialogs/ShieldSystemDialog.h>
3233
#include <ui/dialogs/GlobalShipFlagsDialog.h>
@@ -1368,6 +1369,11 @@ void FredView::on_actionAbout_triggered(bool) {
13681369
dialog->setAttribute(Qt::WA_DeleteOnClose);
13691370
dialog->show();
13701371
}
1372+
void FredView::on_actionMission_Statistics_triggered(bool) {
1373+
auto dialog = new dialogs::MissionStatsDialog(this, _viewport);
1374+
dialog->setAttribute(Qt::WA_DeleteOnClose);
1375+
dialog->show();
1376+
}
13711377

13721378
void FredView::on_actionBackground_triggered(bool) {
13731379
auto dialog = new dialogs::BackgroundEditorDialog(this, _viewport);

qtfred/src/ui/FredView.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ class FredView: public QMainWindow, public IDialogProvider {
151151
void on_actionError_Checker_triggered(bool);
152152

153153
void on_actionAbout_triggered(bool);
154+
void on_actionMission_Statistics_triggered(bool);
154155
void on_actionBackground_triggered(bool);
155156
void on_actionShield_System_triggered(bool);
156157
void on_actionSet_Global_Ship_Flags_triggered(bool);

0 commit comments

Comments
 (0)