1/*
2 * LegacyClonk
3 *
4 * Copyright (c) RedWolf Design
5 * Copyright (c) 2008, Sven2
6 * Copyright (c) 2017-2020, The LegacyClonk Team and contributors
7 *
8 * Distributed under the terms of the ISC license; see accompanying file
9 * "COPYING" for details.
10 *
11 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12 * See accompanying file "TRADEMARK" for details.
13 *
14 * To redistribute this file separately, substitute the full license texts
15 * for the above references.
16 */
17
18// Round result information to be displayed in game over dialog
19// Collects information from:
20// -Instances of C4Player as they are evaluated (EvaluatePlayer)
21// -Game evaluation (EvaluateGame)
22// -League evaluation (EvaluateLeague)
23// -Script calls to AddCustomEvaluationString
24
25#pragma once
26
27#include "C4Constants.h"
28#include "C4Components.h"
29#include "C4ForwardDeclarations.h"
30#include "C4IDList.h"
31#include "C4PacketBase.h"
32#include "C4FacetEx.h"
33
34// Contains additional data not present in C4PlayerInfo
35class C4RoundResultsPlayer
36{
37private:
38 // player ID of linked structure in Game.PlayerInfos
39 int32_t id;
40
41 // player icon
42 // not compiled, so it will be lost for eliminated players after savegame resume,
43 // or for runtime joiners
44 C4FacetExSurface fctBigIcon;
45
46 // game data
47 uint32_t iTotalPlayingTime; // total playing time in seconds
48 int32_t iScoreOld, iScoreNew;
49 StdStrBuf sCustomEvaluationStrings; // scenario specific
50
51 // league data
52 int32_t iLeagueScoreNew; // score on league server after this round - -1 for unknown
53 int32_t iLeagueScoreGain; // league score gained by this round - -1 for unknown
54 int32_t iLeagueRankNew; // rank on league server after this round
55 int32_t iLeagueRankSymbolNew; // rank symbol on league server after this round
56 int32_t iLeaguePerformance; // script-set performance value, effect league-dependent
57 StdStrBuf sLeagueProgressData; // scenario-specific data to store more proigress info (which levels were done, etc.)
58
59 enum LeagueStatus
60 {
61 RRPLS_Unknown = 0, RRPLS_Lost, RRPLS_Won
62 } eLeagueStatus; // whether player lost or won
63
64public:
65 C4RoundResultsPlayer() : id(0), iTotalPlayingTime(0), iScoreOld(-1), iScoreNew(-1), iLeagueScoreNew(-1), iLeagueScoreGain(0), iLeagueRankNew(0), iLeagueRankSymbolNew(0), iLeaguePerformance(0), sLeagueProgressData(), eLeagueStatus(RRPLS_Unknown) {}
66 C4RoundResultsPlayer(const C4RoundResultsPlayer &cpy) { *this = cpy; }
67
68 void CompileFunc(StdCompiler *pComp);
69
70 int32_t GetID() const { return id; }
71 C4FacetEx &GetBigIcon() { return fctBigIcon; }
72 uint32_t GetTotalPlayingTime() const { return iTotalPlayingTime; }
73 int32_t GetScoreOld() const { return iScoreOld; }
74 bool IsScoreNewValid() const { return iScoreNew >= 0; }
75 int32_t GetScoreNew() const { return iScoreNew; }
76 const char *GetCustomEvaluationStrings() { return sCustomEvaluationStrings.getData(); }
77 int32_t GetLeagueScoreNew() const { return iLeagueScoreNew; } // returns score number on league server after round evaluation (0 for not assigned)
78 bool IsLeagueScoreNewValid() const { return iLeagueScoreNew >= 0; }
79 int32_t GetLeagueScoreGain() const { return iLeagueScoreGain; }
80 int32_t GetLeagueRankSymbolNew() const { return iLeagueRankSymbolNew; }
81 int32_t GetLeaguePerformance() const { return iLeaguePerformance; }
82
83 void EvaluateLeague(C4RoundResultsPlayer *pLeaguePlayer); // called from league evaluation; set league fields
84 void EvaluatePlayer(C4Player *pPlr); // called from C4Player::Evaluate; set fields by player
85
86 void SetID(int32_t idNew) { id = idNew; }
87 void AddCustomEvaluationString(const char *szCustomString);
88 void SetLeaguePerformance(int32_t iNewPerf) { iLeaguePerformance = iNewPerf; }
89
90 bool operator==(const C4RoundResultsPlayer &cmp) const;
91 C4RoundResultsPlayer &operator=(const C4RoundResultsPlayer &cpy);
92};
93
94// player list in round results (std::vector<C4RoundResultsPlayer>...)
95class C4RoundResultsPlayers
96{
97private:
98 // players
99 C4RoundResultsPlayer **ppPlayers;
100 int32_t iPlayerCount, iPlayerCapacity;
101
102public:
103 C4RoundResultsPlayers() : ppPlayers(nullptr), iPlayerCount(0), iPlayerCapacity(0) {}
104 C4RoundResultsPlayers(const C4RoundResultsPlayers &cpy) : ppPlayers(nullptr), iPlayerCount(0), iPlayerCapacity(0) { *this = cpy; }
105 ~C4RoundResultsPlayers() { Clear(); }
106
107 void Clear();
108
109 void CompileFunc(StdCompiler *pComp);
110
111private:
112 void GrowList(size_t iByVal);
113
114public:
115 C4RoundResultsPlayer *GetByIndex(int32_t idx) const;
116 C4RoundResultsPlayer *GetByID(int32_t id) const;
117 int32_t GetCount() const { return iPlayerCount; }
118
119 void Add(C4RoundResultsPlayer *pNewPlayer);
120 C4RoundResultsPlayer *GetCreateByID(int32_t id);
121
122 bool operator==(const C4RoundResultsPlayers &cmp) const;
123 C4RoundResultsPlayers &operator=(const C4RoundResultsPlayers &cpy);
124};
125
126class C4RoundResults
127{
128public:
129 enum NetResult
130 {
131 NR_None = 0, // undefined
132 NR_LeagueOK, // league evaluated
133 NR_LeagueError, // league evaluation error
134 NR_NetError, // network disconnect
135 };
136
137private:
138 // player list
139 C4RoundResultsPlayers Players;
140
141 // game data
142 C4IDList Goals; // Goals at time of evaluation
143 C4IDList FulfilledGoals; // only those goals that are fulfilled
144 uint32_t iPlayingTime; // game time in seconds
145 int32_t iLeaguePerformance; // settlement league performance points
146 bool fHideSettlementScore; // to hide the score in the evaluation dialogue (for melees)
147
148 // league/network result
149 StdStrBuf sNetResult;
150 NetResult eNetResult;
151
152 // scenario-specific
153 StdStrBuf sCustomEvaluationStrings;
154
155public:
156 C4RoundResults() : iPlayingTime(0) {}
157 ~C4RoundResults() { Clear(); }
158
159 void Clear();
160 void Init();
161
162 void CompileFunc(StdCompiler *pComp);
163
164public:
165 // fill GoalList with current goal status - also called by goal menu!
166 static void EvaluateGoals(C4IDList &GoalList, C4IDList &FulfilledGoalList, int32_t iPlayerNumber);
167
168 // Evaluation called by C4Game::Evaluate
169 // Caution: This does script callbacks for goal fulfillment check and must be called in sync,
170 // i.e. even for dedicated server
171 void EvaluateGame();
172
173 // Evaluation called by league: Sets new league scores and ranks
174 void EvaluateLeague(const char *szResultMsg, bool fSuccess, const C4RoundResultsPlayers &rLeagueInfo);
175
176 // Evaluation called by player when it's evaluated
177 void EvaluatePlayer(C4Player *pPlr);
178
179 // Evaluation by network: Disconnect or league info
180 void EvaluateNetwork(NetResult eResult, const char *szResultsString);
181
182 // Set custom string to be shown in game over dialog
183 // idPlayer==0 for global strings
184 void AddCustomEvaluationString(const char *szCustomString, int32_t idPlayer);
185
186 // to hide the settlement score in melees
187 void HideSettlementScore(bool fHide = true);
188 bool SettlementScoreIsHidden();
189
190 // Set league performance
191 // Used for special league scenarios, e.g. settlement scenarios that wish to use a
192 // measure different from the elapsed game time
193 void SetLeaguePerformance(int32_t iNewPerf, int32_t idPlayer = 0);
194 int32_t GetLeaguePerformance(int32_t idPlayer = 0) const;
195
196 const C4RoundResultsPlayers &GetPlayers() const { return Players; }
197 const char *GetCustomEvaluationStrings() const { return sCustomEvaluationStrings.getData(); }
198 NetResult GetNetResult() const { return eNetResult; }
199 const char *GetNetResultString() const { return sNetResult.getData(); }
200 bool HasNetResult() const { return eNetResult != NR_None; }
201
202 bool Load(C4Group &hGroup, const char *szFilename = C4CFN_RoundResults);
203 bool Save(C4Group &hGroup, const char *szFilename = C4CFN_RoundResults);
204
205 const C4IDList &GetGoals() const { return Goals; }
206 const C4IDList &GetFulfilledGoals() const { return FulfilledGoals; }
207};
208
209// * PID_LeagueRoundResults
210// packet containing league round results for all participating players
211// sent from host to client after league evaluation
212class C4PacketLeagueRoundResults : public C4PacketBase
213{
214public:
215 C4RoundResultsPlayers Players; // league info for players
216 StdStrBuf sResultsString; // league result string - or error message
217 bool fSuccess; // whether result was successful or not
218
219 C4PacketLeagueRoundResults() : fSuccess(false) {}
220 C4PacketLeagueRoundResults(const char *szResultsString, bool fSuccess, const C4RoundResultsPlayers &Players) : Players(Players), sResultsString(szResultsString), fSuccess(fSuccess) {}
221 C4PacketLeagueRoundResults(const char *szResultsString, bool fSuccess) : sResultsString(szResultsString), fSuccess(fSuccess) {}
222
223 virtual void CompileFunc(StdCompiler *pComp) override;
224};
225