1/*
2 * LegacyClonk
3 *
4 * Copyright (c) 1998-2000, Matthes Bender (RedWolf Design)
5 * Copyright (c) 2017-2022, 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/* Object definition */
18
19#pragma once
20
21#include <C4Shape.h>
22#include <C4InfoCore.h>
23#include <C4IDList.h>
24#include <C4ValueMap.h>
25#include <C4Facet.h>
26#include <C4Surface.h>
27#include <C4ComponentHost.h>
28#include <C4ScriptHost.h>
29#include <C4DefGraphics.h>
30#include "C4LangStringTable.h"
31
32#include "C4DelegatedIterable.h"
33
34#include "StdFont.h"
35
36#include <cstddef>
37#include <cstdint>
38#include <memory>
39#include <vector>
40
41const int32_t C4D_None = 0,
42 C4D_All = ~C4D_None,
43
44 C4D_StaticBack = 1 << 0,
45 C4D_Structure = 1 << 1,
46 C4D_Vehicle = 1 << 2,
47 C4D_Living = 1 << 3,
48 C4D_Object = 1 << 4,
49
50 C4D_SortLimit = C4D_StaticBack | C4D_Structure | C4D_Vehicle | C4D_Living | C4D_Object,
51
52 C4D_Goal = 1 << 5,
53 C4D_Environment = 1 << 6,
54
55 C4D_SelectBuilding = 1 << 7,
56 C4D_SelectVehicle = 1 << 8,
57 C4D_SelectMaterial = 1 << 9,
58 C4D_SelectKnowledge = 1 << 10,
59 C4D_SelectHomebase = 1 << 11,
60 C4D_SelectAnimal = 1 << 12,
61 C4D_SelectNest = 1 << 13,
62 C4D_SelectInEarth = 1 << 14,
63 C4D_SelectVegetation = 1 << 15,
64
65 C4D_TradeLiving = 1 << 16,
66 C4D_Magic = 1 << 17,
67 C4D_CrewMember = 1 << 18,
68
69 C4D_Rule = 1 << 19,
70
71 C4D_Background = 1 << 20,
72 C4D_Parallax = 1 << 21,
73 C4D_MouseSelect = 1 << 22,
74 C4D_Foreground = 1 << 23,
75 C4D_MouseIgnore = 1 << 24,
76 C4D_IgnoreFoW = 1 << 25,
77
78 C4D_BackgroundOrForeground = (C4D_Background | C4D_Foreground);
79
80const int32_t C4D_Grab_Put = 1,
81 C4D_Grab_Get = 2,
82
83 C4D_Border_Sides = 1,
84 C4D_Border_Top = 2,
85 C4D_Border_Bottom = 4,
86 C4D_Border_Layer = 8,
87
88 C4D_Line_Power = 1,
89 C4D_Line_Source = 2,
90 C4D_Line_Drain = 3,
91 C4D_Line_Lightning = 4,
92 C4D_Line_Volcano = 5,
93 C4D_Line_Rope = 6,
94 C4D_Line_Colored = 7,
95 C4D_Line_Vertex = 8,
96
97 C4D_Power_Input = 1,
98 C4D_Power_Output = 2,
99 C4D_Liquid_Input = 4,
100 C4D_Liquid_Output = 8,
101 C4D_Power_Generator = 16,
102 C4D_Power_Consumer = 32,
103 C4D_Liquid_Pump = 64,
104 C4D_Connect_Rope = 128,
105 C4D_EnergyHolder = 256,
106
107 C4D_Place_Surface = 0,
108 C4D_Place_Liquid = 1,
109 C4D_Place_Air = 2;
110
111const int32_t C4D_VehicleControl_None = 0,
112 C4D_VehicleControl_Outside = 1,
113 C4D_VehicleControl_Inside = 2;
114
115const int32_t C4D_Sell = C4D_StaticBack | C4D_Structure | C4D_Vehicle | C4D_Object | C4D_TradeLiving,
116 C4D_Get = C4D_Sell,
117 C4D_Activate = C4D_Get;
118
119const uint32_t C4D_Load_None = 0,
120 C4D_Load_Picture = 1,
121 C4D_Load_Bitmap = 2,
122 C4D_Load_Script = 4,
123 C4D_Load_Desc = 8,
124 C4D_Load_ActMap = 16,
125 C4D_Load_Image = 32,
126 C4D_Load_Sounds = 64,
127 C4D_Load_ClonkNames = 128,
128 C4D_Load_RankNames = 256,
129 C4D_Load_RankFaces = 512,
130 C4D_Load_RX = C4D_Load_Bitmap | C4D_Load_Script | C4D_Load_ClonkNames | C4D_Load_Desc | C4D_Load_ActMap | C4D_Load_Sounds | C4D_Load_RankNames | C4D_Load_RankFaces;
131
132#define C4D_Blit_Normal 0
133#define C4D_Blit_Additive 1
134#define C4D_Blit_ModAdd 2
135
136#define C4DGFXMODE_NEWGFX 1
137#define C4DGFXMODE_OLDGFX 2
138
139const int32_t ActIdle = -1;
140const int32_t ActHold = -2;
141
142class C4ActionDef
143{
144public:
145 char Name[C4D_MaxIDLen + 1]{};
146 char ProcedureName[C4D_MaxIDLen + 1]{};
147 int32_t Procedure; // Mapped by C4Def::Load
148 int32_t Directions{1};
149 int32_t FlipDir{};
150 int32_t Length{1};
151 int32_t Delay{};
152 int32_t Attach{};
153 char NextActionName[C4D_MaxIDLen + 1]{};
154 int32_t NextAction{ActIdle}; // Mapped by C4Def::Load
155 char InLiquidAction[C4D_MaxIDLen + 1]{};
156 char TurnAction[C4D_MaxIDLen + 1]{};
157 int32_t FacetBase{};
158 C4TargetRect Facet{};
159 int32_t FacetTopFace{};
160 int32_t NoOtherAction{};
161 int32_t Disabled{};
162 int32_t DigFree{};
163 int32_t FacetTargetStretch{};
164 char Sound[C4D_MaxIDLen + 1]{};
165 int32_t EnergyUsage{};
166 int32_t Reverse{};
167 int32_t Step{1};
168 char SStartCall[C4D_MaxIDLen + 1]{};
169 char SEndCall[C4D_MaxIDLen + 1]{};
170 char SAbortCall[C4D_MaxIDLen + 1]{};
171 char SPhaseCall[C4D_MaxIDLen + 1]{};
172 class C4AulScriptFunc *StartCall{};
173 C4AulScriptFunc *EndCall{};
174 C4AulScriptFunc *AbortCall{};
175 C4AulScriptFunc *PhaseCall{};
176
177public:
178 C4ActionDef();
179 void Default();
180 void CompileFunc(StdCompiler *pComp);
181};
182
183class C4DefCore
184{
185public:
186 C4DefCore();
187
188public:
189 C4ID id;
190 int32_t rC4XVer[5];
191 StdStrBuf Name;
192 C4IDList RequireDef;
193 C4PhysicalInfo Physical;
194 C4Shape Shape;
195 C4Rect Entrance;
196 C4Rect Collection;
197 C4Rect PictureRect;
198 C4TargetRect SolidMask;
199 C4TargetRect TopFace;
200 C4IDList Component;
201 C4ID BurnTurnTo;
202 C4ID BuildTurnTo;
203 int32_t GrowthType;
204 int32_t Basement;
205 int32_t CanBeBase;
206 int32_t CrewMember;
207 int32_t NativeCrew;
208 int32_t Mass;
209 int32_t Value;
210 int32_t Exclusive;
211 int32_t Category;
212 int32_t Growth;
213 int32_t Rebuyable;
214 int32_t ContactIncinerate; // 0 off 1 high - 5 low
215 int32_t BlastIncinerate; // 0 off 1 - x if > damage
216 int32_t Constructable;
217 int32_t Grab; // 0 not 1 push 2 grab only
218 int32_t Carryable;
219 int32_t Rotateable;
220 int32_t Chopable;
221 int32_t Float;
222 int32_t ColorByOwner;
223 int32_t NoHorizontalMove;
224 int32_t BorderBound;
225 int32_t LiftTop;
226 int32_t CollectionLimit;
227 int32_t GrabPutGet;
228 int32_t ContainBlast;
229 int32_t UprightAttach;
230 int32_t ContactFunctionCalls;
231 int32_t MaxUserSelect;
232 int32_t Line;
233 int32_t LineConnect;
234 int32_t LineIntersect;
235 int32_t NoBurnDecay;
236 int32_t IncompleteActivity;
237 int32_t Placement;
238 int32_t Prey;
239 int32_t Edible;
240 int32_t AttractLightning;
241 int32_t Oversize;
242 int32_t Fragile;
243 int32_t Projectile;
244 int32_t Explosive;
245 int32_t NoPushEnter;
246 int32_t DragImagePicture;
247 int32_t VehicleControl;
248 int32_t Pathfinder;
249 int32_t MoveToRange;
250 int32_t Timer;
251 int32_t NoComponentMass;
252 int32_t NoStabilize;
253 char STimerCall[C4D_MaxIDLen];
254 char ColorByMaterial[C4M_MaxName + 1];
255 int32_t ClosedContainer; // if set, contained objects are not damaged by lava/acid etc. 1: Contained objects can't view out; 2: They can
256 int32_t SilentCommands; // if set, no command failure messages are printed
257 int32_t NoBurnDamage; // if set, the object won't take damage when burning
258 int32_t TemporaryCrew; // if set, info objects are not written into regular player files
259 int32_t SmokeRate; // amount of smoke produced when on fire. 100 is default
260 int32_t BlitMode; // special blit mode for objects of this def. C4D_Blit_X
261 int32_t NoBreath; // object does not need to breath, although it's living
262 int32_t ConSizeOff; // number of pixels to be subtracted from the needed height for this building
263 int32_t NoSell; // if set, object can't be sold (doesn't even appear in sell-menu)
264 int32_t NoGet; // if set, object can't be taken out of a containers manually (doesn't appear in get/activate-menus)
265 int32_t NoFight; // if set, object is never OCF_FightReady
266 int32_t RotatedSolidmasks; // if set, solidmasks can be rotated
267 int32_t NeededGfxMode; // if set, the def will only be loaded in given gfx mode
268 int32_t RotatedEntrance; // 0 entrance not rotateable, 1 entrance always, 2-360 entrance within this rotation
269 int32_t NoTransferZones;
270 int32_t AutoContextMenu; // automatically open context menu for this object
271 int32_t AllowPictureStack; // allow stacking of multiple items in menus even if some attributes do not match. APS_*-values
272 int32_t HideHUDBars; // A bit mask to selectively hide some of the Energy, Magic Energy and Breath bars.
273 int32_t HideHUDElements; // A bit mask to selectively hide clonk portrait, clonk name, clonk rank, clonk rank image, captain icon
274 uint32_t Scale; // graphics scale
275 bool BaseAutoSell; // if set, the object will automatically be sold in a base if the corresponding base functionality is enabled
276
277public:
278 enum HideBar
279 {
280 HB_Energy = 0x1,
281 HB_MagicEnergy = 0x2,
282 HB_Breath = 0x4,
283 HB_All = HB_Energy | HB_MagicEnergy | HB_Breath
284 };
285
286 enum HideHud
287 {
288 HH_Portrait = 0x1,
289 HH_Captain = 0x2,
290 HH_Name = 0x4,
291 HH_Rank = 0x8,
292 HH_RankImage = 0x10,
293 HH_Inventory = 0x20,
294 HH_All = HH_Portrait | HH_Captain | HH_Name | HH_Rank | HH_RankImage | HH_Inventory
295 };
296
297 void Default();
298 bool Load(C4Group &hGroup);
299 void CompileFunc(StdCompiler *pComp);
300 const char *GetName() const { return Name.getData(); }
301
302protected:
303 bool Compile(const char *szSource, const char *szName);
304};
305
306class C4Def : public C4DefCore
307{
308 friend class C4DefList;
309
310public:
311 C4Def();
312 ~C4Def();
313
314public:
315 int32_t ActNum; C4ActionDef *ActMap;
316 char Maker[C4MaxName + 1];
317 char Filename[_MAX_FNAME + 1];
318 int32_t Creation;
319 int32_t Count; // number of instantiations
320 C4AulScriptFunc *TimerCall;
321 C4ComponentHost Desc;
322 C4DefScriptHost Script;
323 C4LangStringTable StringTable;
324
325 // clonknames are simply not needed in frontend
326 C4ComponentHost *pClonkNames; bool fClonkNamesOwned;
327
328 // neither are ranknames nor the symbols...yet!
329 C4RankSystem *pRankNames; bool fRankNamesOwned;
330 C4FacetExSurface *pRankSymbols; bool fRankSymbolsOwned;
331 int32_t iNumRankSymbols; // number of rank symbols available, if loaded
332 C4DefGraphics Graphics; // base graphics. points to additional graphics
333 int32_t PortraitCount;
334 C4PortraitGraphics *Portraits; // Portraits (linked list of C4AdditionalDefGraphics)
335 float Scale;
336
337protected:
338 // copy of the physical info used in FairCrew-mode
339 C4PhysicalInfo *pFairCrewPhysical;
340
341 C4Facet MainFace;
342
343public:
344 void Clear();
345 void Default();
346 bool Load(C4Group &hGroup,
347 uint32_t dwLoadWhat, const char *szLanguage,
348 class C4SoundSystem *pSoundSystem = nullptr);
349 void Draw(C4Facet &cgo, bool fSelected = false, uint32_t iColor = 0, C4Object *pObj = nullptr, int32_t iPhaseX = 0, int32_t iPhaseY = 0);
350 inline C4Facet &GetMainFace(C4DefGraphics *pGraphics, uint32_t dwClr = 0) { MainFace.Surface = pGraphics->GetBitmap(dwClr); return MainFace; }
351 int32_t GetValue(C4Object *pInBase, int32_t iBuyPlayer); // get value of def; calling script functions if defined
352 C4PhysicalInfo *GetFairCrewPhysicals(); // get fair crew physicals at current fair crew strength
353 void ClearFairCrewPhysicals(); // remove cached fair crew physicals, will be created fresh on demand
354 void Synchronize();
355 const char *GetDesc() { return Desc.GetData(); }
356
357protected:
358 bool LoadPortraits(C4Group &hGroup);
359 bool ColorizeByMaterial(class C4MaterialMap &rMats, uint8_t bGBM);
360 bool LoadActMap(C4Group &hGroup);
361 void CrossMapActMap();
362
363private:
364 C4ValueArray *GetCustomComponents(C4Value *pvArrayHolder, C4Object *pBuilder, C4Object *pObjInstance = nullptr);
365
366public:
367 // return def components - may be overloaded by script callback
368 int32_t GetComponentCount(C4ID idComponent, C4Object *pBuilder = nullptr);
369 C4ID GetIndexedComponent(int32_t idx, C4Object *pBuilder = nullptr);
370 void GetComponents(C4IDList *pOutList, C4Object *pObjInstance = nullptr, C4Object *pBuilder = nullptr);
371
372 void IncludeDefinition(C4Def *pIncludeDef); // inherit components from other definition
373 void ResetIncludeDependencies(); // resets all pointers into foreign definitions caused by include chains
374
375 void Picture2Facet(C4FacetExSurface &cgo, uint32_t color = 0, int32_t xPhase = 0);
376};
377
378class C4DefList : public C4DelegatedIterable<C4DefList>, public CStdFont::CustomImages
379{
380public:
381 C4DefList();
382 virtual ~C4DefList();
383
384public:
385 bool LoadFailure;
386
387public:
388 void Clear();
389 int32_t Load(C4Group &hGroup,
390 uint32_t dwLoadWhat, const char *szLanguage,
391 C4SoundSystem *pSoundSystem = nullptr,
392 bool fOverload = false,
393 bool fSearchMessage = false, int32_t iMinProgress = 0, int32_t iMaxProgress = 0, bool fLoadSysGroups = true);
394 int32_t Load(const char *szSearch,
395 uint32_t dwLoadWhat, const char *szLanguage,
396 C4SoundSystem *pSoundSystem = nullptr,
397 bool fOverload = false, int32_t iMinProgress = 0, int32_t iMaxProgress = 0);
398 C4Def *ID2Def(C4ID id);
399 C4Def *GetDef(std::size_t index, std::uint32_t category = C4D_All);
400 C4Def *GetByPath(const char *szPath);
401 int32_t GetIndex(C4ID id);
402 int32_t ColorizeByMaterial(C4MaterialMap &rMats, uint8_t bGBM);
403 int32_t CheckEngineVersion(int32_t ver1, int32_t ver2, int32_t ver3, int32_t ver4, int32_t ver5);
404 int32_t CheckRequireDef();
405 void Draw(C4ID id, C4Facet &cgo, bool fSelected, int32_t iColor);
406 void Remove(C4Def *def);
407 bool Remove(C4ID id);
408 bool Reload(C4Def *pDef, uint32_t dwLoadWhat, const char *szLanguage, C4SoundSystem *pSoundSystem = nullptr);
409 bool Add(C4Def *ndef, bool fOverload);
410 void ResetIncludeDependencies(); // resets all pointers into foreign definitions caused by include chains
411 void SortByID();
412 void Synchronize();
413
414 // callback from font renderer: get ID image
415 virtual bool GetFontImage(const char *szImageTag, C4Facet &rOutImgFacet) override;
416
417private:
418 std::vector<std::unique_ptr<C4Def>>::iterator FindDefByID(C4ID id);
419
420 std::vector<std::unique_ptr<C4Def>> Defs;
421 bool Sorted;
422
423public:
424 using Iterable = ConstIterableMember<&C4DefList::Defs>;
425};
426
427// Default Action Procedures
428
429#define DFA_NONE -1
430#define DFA_WALK 0
431#define DFA_FLIGHT 1
432#define DFA_KNEEL 2
433#define DFA_SCALE 3
434#define DFA_HANGLE 4
435#define DFA_DIG 5
436#define DFA_SWIM 6
437#define DFA_THROW 7
438#define DFA_BRIDGE 8
439#define DFA_BUILD 9
440#define DFA_PUSH 10
441#define DFA_CHOP 11
442#define DFA_LIFT 12
443#define DFA_FLOAT 13
444#define DFA_ATTACH 14
445#define DFA_FIGHT 15
446#define DFA_CONNECT 16
447#define DFA_PULL 17
448
449#define C4D_MaxDFA 18
450
451// procedure name table
452extern const char *ProcedureName[C4D_MaxDFA];
453