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/* Material definitions used by the landscape */
18
19#pragma once
20
21#include "C4ForwardDeclarations.h"
22#include <C4Id.h>
23#include <C4Shape.h>
24#include <C4Facet.h>
25#include <vector>
26
27#define C4MatOv_Default 0
28#define C4MatOv_Exact 1
29#define C4MatOv_None 2
30#define C4MatOv_HugeZoom 4
31#define C4MatOv_Monochrome 8
32
33enum MaterialInteractionEvent
34{
35 meePXSPos = 0, // PXS check before movement
36 meePXSMove = 1, // PXS movement
37 meeMassMove = 2, // MassMover-movement
38};
39
40typedef bool(*C4MaterialReactionFunc)(struct C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Fixed &fXDir, C4Fixed &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged);
41
42struct C4MaterialReaction
43{
44 static inline bool NoReaction(struct C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Fixed &fXDir, C4Fixed &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged) { return false; }
45
46 C4MaterialReactionFunc pFunc; // Guarantueed to be non-nullptr
47 bool fUserDefined; // false for internal reactions generated by material parameters
48 StdStrBuf TargetSpec; // target material specification
49 StdStrBuf ScriptFunc; // for reaction func 'script': Script func to be called for reaction evaluation
50 C4AulFunc *pScriptFunc; // resolved script function
51 uint32_t iExecMask; // execution mask: Bit mask with indices into MaterialInteractionEvent
52 bool fReverse; // if set, spec will be handled as if specified in target mat def
53 bool fInverseSpec; // if set, all mats except the given are used
54 bool fInsertionCheck; // if set, splash/slide checks are done prior to reaction execution
55 int32_t iDepth; // in mat conversion depth
56 StdStrBuf sConvertMat; // in mat conversion material (string)
57 int32_t iConvertMat; // in mat conversion material; evaluated in CrossMapMaterials
58 int32_t iCorrosionRate; // chance of doing a corrosion
59
60 C4MaterialReaction(C4MaterialReactionFunc pFunc) : pFunc(pFunc), fUserDefined(false), pScriptFunc(nullptr), iExecMask(~0u), fReverse(false), fInverseSpec(false), fInsertionCheck(true), iDepth(0), iConvertMat(-1), iCorrosionRate(100) {}
61 C4MaterialReaction() : pFunc(&NoReaction), fUserDefined(true), pScriptFunc(nullptr), iExecMask(~0u), fReverse(false), fInverseSpec(false), fInsertionCheck(true), iDepth(0), iConvertMat(-1), iCorrosionRate(100) {}
62
63 void CompileFunc(StdCompiler *pComp);
64 void ResolveScriptFuncs(const char *szMatName);
65
66 bool operator==(const C4MaterialReaction &rCmp) const { return false; } // never actually called; only comparing with empty vector of C4MaterialReactions
67};
68
69class C4MaterialCore
70{
71public:
72 C4MaterialCore();
73 ~C4MaterialCore() { Clear(); }
74
75public:
76 std::vector<C4MaterialReaction> CustomReactionList;
77
78public:
79 char Name[C4M_MaxName + 1];
80 uint32_t Color[C4M_ColsPerMat * 3];
81 uint32_t Alpha[C4M_ColsPerMat * 2];
82 int32_t MapChunkType;
83 int32_t Density;
84 int32_t Friction;
85 int32_t DigFree;
86 int32_t BlastFree;
87 C4ID Dig2Object;
88 int32_t Dig2ObjectRatio;
89 int32_t Dig2ObjectOnRequestOnly;
90 C4ID Blast2Object;
91 int32_t Blast2ObjectRatio;
92 int32_t Blast2PXSRatio;
93 int32_t Instable;
94 int32_t MaxAirSpeed;
95 int32_t MaxSlide;
96 int32_t WindDrift;
97 int32_t Inflammable;
98 int32_t Incindiary;
99 int32_t Extinguisher;
100 int32_t Corrosive;
101 int32_t Corrode;
102 int32_t Soil;
103 int32_t Placement; // placement order for landscape shading
104 StdStrBuf sTextureOverlay; // overlayed texture for this material
105 int32_t OverlayType; // defines the way in which the overlay texture is applied
106 StdStrBuf sPXSGfx; // newgfx: picture used for loose pxs
107 C4TargetRect PXSGfxRt; // newgfx: facet rect of pixture used for loose pixels
108 int32_t PXSGfxSize;
109 StdStrBuf sBlastShiftTo;
110 StdStrBuf sInMatConvert;
111 StdStrBuf sInMatConvertTo;
112 int32_t InMatConvertDepth; // material converts only if it finds the same material above
113 int32_t BelowTempConvert;
114 int32_t BelowTempConvertDir;
115 StdStrBuf sBelowTempConvertTo;
116 int32_t AboveTempConvert;
117 int32_t AboveTempConvertDir;
118 StdStrBuf sAboveTempConvertTo;
119 int32_t TempConvStrength;
120 int32_t MinHeightCount; // minimum material thickness in order for it to be counted
121 int32_t SplashRate;
122
123public:
124 void Clear();
125 bool Load(C4Group &hGroup, const char *szEntryName);
126 uint32_t GetDWordColor(int32_t iIndex); // get indexed material color as DWord
127 void CompileFunc(StdCompiler *pComp);
128};
129
130class C4Material : public C4MaterialCore
131{
132public:
133 C4Material();
134
135public:
136 // Cross-mapped material values
137 int32_t BlastShiftTo; // MatTex
138 int32_t InMatConvertTo; // Mat
139 int32_t BelowTempConvertTo; // MatTex
140 int32_t AboveTempConvertTo; // MatTex
141 int32_t DefaultMatTex; // texture used for single pixel values
142 CPattern MatPattern;
143 C4Facet PXSFace; // loose pixel facet
144
145 void UpdateScriptPointers(); // set all material script pointers
146};
147
148class C4MaterialMap
149{
150public:
151 C4MaterialMap();
152 ~C4MaterialMap();
153
154public:
155 int32_t Num;
156 C4Material *Map;
157 C4MaterialReaction **ppReactionMap;
158
159 C4MaterialReaction DefReactConvert, DefReactPoof, DefReactCorrode, DefReactIncinerate, DefReactInsert;
160
161public:
162 // default reactions
163 static bool mrfConvert (C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Fixed &fXDir, C4Fixed &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged);
164 static bool mrfPoof (C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Fixed &fXDir, C4Fixed &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged);
165 static bool mrfCorrode (C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Fixed &fXDir, C4Fixed &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged);
166 static bool mrfIncinerate(C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Fixed &fXDir, C4Fixed &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged);
167 static bool mrfInsert (C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Fixed &fXDir, C4Fixed &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged);
168 // user-defined actions
169 static bool mrfScript(C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Fixed &fXDir, C4Fixed &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged);
170
171public:
172 void Default();
173 void Clear();
174 int32_t Load(C4Group &hGroup, C4Group *OverloadFile = nullptr);
175 int32_t Get(const char *szMaterial);
176 bool SaveEnumeration(C4Group &hGroup);
177 bool LoadEnumeration(C4Group &hGroup);
178
179 C4MaterialReaction *GetReactionUnsafe(int32_t iPXSMat, int32_t iLandscapeMat)
180 {
181 assert(ppReactionMap); assert(Inside<int32_t>(iPXSMat, -1, Num - 1)); assert(Inside<int32_t>(iLandscapeMat, -1, Num - 1));
182 return ppReactionMap[(iLandscapeMat + 1) * (Num + 1) + iPXSMat + 1];
183 }
184
185 void UpdateScriptPointers(); // set all material script pointers
186 void CrossMapMaterials();
187
188protected:
189 void SetMatReaction(int32_t iPXSMat, int32_t iLSMat, C4MaterialReaction *pReact);
190 bool SortEnumeration(int32_t iMat, const char *szMatName);
191};
192
193const int32_t C4M_Flat = 0,
194 C4M_TopFlat = 1,
195 C4M_Smooth = 2,
196 C4M_Rough = 3,
197
198 // Material Density Levels
199
200 C4M_Vehicle = 100,
201 C4M_Solid = 50,
202 C4M_SemiSolid = 25,
203 C4M_Liquid = 25,
204 C4M_Background = 0;
205
206const int32_t MNone = -1;
207