1/*
2 * LegacyClonk
3 *
4 * Copyright (c) 1998-2000, Matthes Bender (RedWolf Design)
5 * Copyright (c) 2017-2021, The LegacyClonk Team and contributors
6 *
7 * Distributed under the terms of the ISC license; see accompanying file
8 * "COPYING" for details.
9 *
10 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11 * See accompanying file "TRADEMARK" for details.
12 *
13 * To redistribute this file separately, substitute the full license texts
14 * for the above references.
15 */
16
17/* Structures for object and player info components */
18
19#pragma once
20
21#include "C4Constants.h"
22#include "C4ForwardDeclarations.h"
23#include <C4Id.h>
24#include <C4ValueMap.h>
25#include <Fixed.h>
26
27#include <vector>
28
29class C4RankSystem;
30
31const int32_t C4MaxPhysical = 100000,
32 C4MaxDeathMsg = 75;
33
34class C4PhysicalInfo
35{
36public:
37 C4PhysicalInfo();
38
39 typedef int32_t C4PhysicalInfo::*Offset;
40
41public:
42 int32_t Energy;
43 int32_t Breath;
44 int32_t Walk;
45 int32_t Jump;
46 int32_t Scale;
47 int32_t Hangle;
48 int32_t Dig;
49 int32_t Swim;
50 int32_t Throw;
51 int32_t Push;
52 int32_t Fight;
53 int32_t Magic;
54 int32_t CanScale;
55 int32_t CanHangle;
56 int32_t CanDig;
57 int32_t CanConstruct;
58 int32_t CanChop;
59 int32_t CanFly;
60 int32_t CorrosionResist;
61 int32_t BreatheWater;
62 int32_t Float;
63
64public:
65 void Default();
66 void PromotionUpdate(int32_t iRank, bool fUpdateTrainablePhysicals = false, class C4Def *pTrainDef = nullptr);
67 void CompileFunc(StdCompiler *pComp);
68
69 // conversion of physical names to member pointers and vice versa
70 static bool GetOffsetByName(const char *szPhysicalName, Offset *pmpiOut);
71 static const char *GetNameByOffset(Offset mpiOff);
72 const char *GetNameByIndex(int32_t iIdx, Offset *pmpiOut = nullptr);
73
74 // comparison
75 bool operator==(const C4PhysicalInfo &cmp) const;
76
77 // physical training
78protected:
79 static void TrainValue(int32_t *piVal, int32_t iTrainBy, int32_t iMaxTrain);
80
81public:
82 void Train(Offset mpiOffset, int32_t iTrainBy, int32_t iMaxTrain);
83};
84
85class C4PhysicalChange
86{
87public:
88 int32_t PrevVal;
89 C4PhysicalInfo::Offset mpiOffset;
90
91 C4PhysicalChange() : PrevVal(0), mpiOffset(nullptr) {}
92 C4PhysicalChange(int32_t iPrevVal, C4PhysicalInfo::Offset mpiOffset)
93 : PrevVal(iPrevVal), mpiOffset(mpiOffset) {}
94 C4PhysicalChange(const C4PhysicalChange &rCpy) : PrevVal(rCpy.PrevVal), mpiOffset(rCpy.mpiOffset) {}
95
96 bool operator==(const C4PhysicalChange &rCmp) const
97 {
98 return PrevVal == rCmp.PrevVal && mpiOffset == rCmp.mpiOffset;
99 }
100
101 C4PhysicalChange &operator=(const C4PhysicalChange &rSet)
102 {
103 PrevVal = rSet.PrevVal; mpiOffset = rSet.mpiOffset; return *this;
104 }
105
106 void CompileFunc(StdCompiler *pComp);
107};
108
109class C4TempPhysicalInfo : public C4PhysicalInfo
110{
111private:
112 // changes done to the original physicals; used for backtracing
113 std::vector<C4PhysicalChange> Changes;
114
115public:
116 void Clear()
117 {
118 Changes.clear();
119 }
120
121 void Default() { Clear(); C4PhysicalInfo::Default(); } // clears
122 void CompileFunc(StdCompiler *pComp);
123
124 void RegisterChange(C4PhysicalInfo::Offset mpiOffset); // append physical change to list
125 bool ResetPhysical(C4PhysicalInfo::Offset mpiOffset); // undo given physical change
126
127 bool HasChanges(C4PhysicalInfo *pRefPhysical); // return true if changes list is not empty
128
129 // also trains any change buffered physicals
130 void Train(Offset mpiOffset, int32_t iTrainBy, int32_t iMaxTrain);
131
132 C4PhysicalInfo &operator=(const C4PhysicalInfo &rSet)
133 {
134 Clear(); static_cast<C4PhysicalInfo &>(*this) = rSet; return *this;
135 }
136};
137
138class C4ObjectInfoCore
139{
140public:
141 C4ObjectInfoCore();
142
143public:
144 C4ID id;
145 char Name[C4MaxName + 1];
146 int32_t Participation;
147 int32_t Rank;
148 StdStrBuf sRankName;
149 StdStrBuf sNextRankName;
150 int32_t NextRankExp; // EXP_NoPromotion for no more promotion; 0 if standard rank system is used
151 int32_t Experience, Rounds;
152 int32_t DeathCount;
153 char TypeName[C4MaxName + 1 + 1];
154 int32_t Birthday, TotalPlayingTime;
155 int32_t Age;
156 char DeathMessage[C4MaxDeathMsg + 1];
157 char PortraitFile[C4MaxName + 2 + 4 + 1]; // used portrait
158 C4PhysicalInfo Physical;
159 C4ValueMapData ExtraData;
160
161public:
162 bool Save(C4Group &hGroup, class C4DefList *pDefs);
163 bool Load(C4Group &hGroup);
164 void Default(C4ID n_id = C4ID_None, class C4DefList *pDefs = nullptr, const char *cpNames = nullptr);
165 void Promote(int32_t iRank, C4RankSystem &rRanks, bool fForceRankName);
166 bool GetNextRankInfo(C4RankSystem &rDefaultRanks, int32_t *piNextRankExp, StdStrBuf *psNextRankName);
167 void CompileFunc(StdCompiler *pComp);
168
169protected:
170 bool Compile(const char *szSource);
171
172 void UpdateCustomRanks(C4DefList *pDefs); // sets NextRankName and NextRankExp
173};
174
175class C4RoundResult
176{
177public:
178 StdStrBuf Title{};
179 uint32_t Date{};
180 int32_t Duration{};
181 int32_t Won{};
182 int32_t Score{}, FinalScore{}, TotalScore{};
183 int32_t Bonus{};
184 int32_t Level{};
185
186public:
187 void Default();
188 void CompileFunc(StdCompiler *pComp);
189};
190
191class C4PlayerInfoCore
192{
193public:
194 C4PlayerInfoCore();
195
196public:
197 // Player Info
198 char PrefName[C4MaxName + 1];
199 char Comment[C4MaxComment + 1];
200 int32_t Rank;
201 char RankName[C4MaxName + 1];
202 int32_t Score;
203 int32_t Rounds, RoundsWon, RoundsLost;
204 int32_t TotalPlayingTime;
205 int32_t PrefMouse;
206 C4RoundResult LastRound;
207 C4ValueMapData ExtraData;
208 // Preferences
209 int32_t PrefColor;
210 uint32_t PrefColorDw, PrefColor2Dw;
211 int32_t PrefControl;
212 int32_t PrefPosition;
213 int32_t PrefControlStyle;
214 int32_t PrefAutoContextMenu; // enable automatically opened context menus in structures
215
216public:
217 void Default(C4RankSystem *pRanks = nullptr);
218 bool Load(C4Group &hGroup);
219 bool Save(C4Group &hGroup);
220 static uint32_t GetPrefColorValue(int32_t iPrefColor);
221 void CompileFunc(StdCompiler *pComp);
222};
223
224inline C4Fixed ValByPhysical(int32_t iPercent, int32_t iPhysical) // get percentage of max physical value
225{
226 return itofix(x: iPhysical * (iPercent / 5), prec: C4MaxPhysical * 20);
227}
228