1 /*
2 * OpenClonk, http://www.openclonk.org
3 *
4 * Copyright (c) 1998-2000, Matthes Bender
5 * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6 * Copyright (c) 2009-2016, The OpenClonk 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 /* Material definitions used by the landscape */
19
20 #ifndef INC_C4Material
21 #define INC_C4Material
22
23 #include "config/C4Constants.h"
24 #include "graphics/C4Facet.h"
25 #include "graphics/CSurface8.h"
26 #include "object/C4Id.h"
27 #include "object/C4Shape.h"
28
29 #define C4MatOv_Default 0
30 #define C4MatOv_Exact 1
31 #define C4MatOv_None 2
32 #define C4MatOv_HugeZoom 4
33
34 enum MaterialInteractionEvent
35 {
36 meePXSPos=0, // PXS check before movement
37 meePXSMove=1, // PXS movement
38 meeMassMove=2 // MassMover-movement
39 };
40
41 typedef bool (*C4MaterialReactionFunc)(struct C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Real &fXDir, C4Real &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged);
42
43 struct C4MaterialReaction
44 {
NoReactionC4MaterialReaction45 static inline bool NoReaction(struct C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Real &fXDir, C4Real &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged) { return false; }
46
47 C4MaterialReactionFunc pFunc; // Guarantueed to be non-nullptr
48 bool fUserDefined{true}; // false for internal reactions generated by material parameters
49 StdCopyStrBuf TargetSpec; // target material specification
50 StdCopyStrBuf ScriptFunc; // for reaction func 'script': Script func to be called for reaction evaluation
51 C4AulFunc *pScriptFunc{nullptr}; // resolved script function
52 uint32_t iExecMask; // execution mask: Bit mask with indices into MaterialInteractionEvent
53 bool fReverse{false}; // if set, spec will be handled as if specified in target mat def
54 bool fInverseSpec{false}; // if set, all mats except the given are used
55 bool fInsertionCheck{true}; // if set, splash/slide checks are done prior to reaction execution
56 int32_t iDepth{0}; // in mat conversion depth
57 StdCopyStrBuf sConvertMat;// in mat conversion material (string)
58 int32_t iConvertMat{-1}; // in mat conversion material; evaluated in CrossMapMaterials
59 int32_t iCorrosionRate{100}; // chance of doing a corrosion
60
C4MaterialReactionC4MaterialReaction61 C4MaterialReaction(C4MaterialReactionFunc pFunc) : pFunc(pFunc), fUserDefined(false), pScriptFunc(nullptr), iExecMask(~0u) {}
C4MaterialReactionC4MaterialReaction62 C4MaterialReaction() : pFunc(&NoReaction), iExecMask(~0u) { }
63
64 void CompileFunc(StdCompiler *pComp);
65
66 void ResolveScriptFuncs(const char *szMatName);
67
68 bool operator ==(const C4MaterialReaction &rCmp) const { return false; } // never actually called; only comparing with empty vector of C4MaterialReactions
69 };
70
71 enum C4MaterialCoreShape
72 {
73 C4M_Flat = 0,
74 C4M_TopFlat = 1,
75 C4M_Smooth = 2,
76 C4M_Rough = 3,
77 C4M_Octagon = 4,
78 C4M_Smoother= 5,
79 };
80
81 class C4MaterialCore
82 {
83 public:
84 C4MaterialCore();
~C4MaterialCore()85 ~C4MaterialCore() { Clear(); }
86
87 std::vector<C4MaterialReaction> CustomReactionList;
88
89 char Name[C4M_MaxName+1];
90
91 C4MaterialCoreShape MapChunkType;
92 int32_t Density;
93 int32_t Friction;
94 int32_t DigFree;
95 int32_t BlastFree;
96 C4ID Dig2Object;
97 int32_t Dig2ObjectRatio;
98 int32_t Dig2ObjectCollect;
99 C4ID Blast2Object;
100 int32_t Blast2ObjectRatio;
101 int32_t Blast2PXSRatio;
102 int32_t Instable;
103 int32_t MaxAirSpeed;
104 int32_t MaxSlide;
105 int32_t WindDrift;
106 int32_t Inflammable;
107 int32_t Incendiary;
108 int32_t Extinguisher;
109 int32_t Corrosive;
110 int32_t Corrode;
111 int32_t Soil;
112 int32_t Placement; // placement order for landscape shading
113 int32_t Light; // ambient light range for underground materials. currently only 1/0 for ambient light on/off
114 StdCopyStrBuf sTextureOverlay; // overlayed texture for this material
115 int32_t OverlayType; // defines the way in which the overlay texture is applied
116 StdCopyStrBuf sPXSGfx; // newgfx: picture used for loose pxs
117 C4TargetRect PXSGfxRt; // newgfx: facet rect of pixture used for loose pixels
118 int32_t PXSGfxSize;
119 StdCopyStrBuf sBlastShiftTo;
120 StdCopyStrBuf sInMatConvert;
121 StdCopyStrBuf sInMatConvertTo;
122 int32_t InMatConvertDepth; // material converts only if it finds the same material above
123 int32_t BelowTempConvert;
124 int32_t BelowTempConvertDir;
125 StdCopyStrBuf sBelowTempConvertTo;
126 int32_t AboveTempConvert;
127 int32_t AboveTempConvertDir;
128 StdCopyStrBuf sAboveTempConvertTo;
129 int32_t TempConvStrength;
130 int32_t MinHeightCount; // minimum material thickness in order for it to be counted
131 int32_t SplashRate;
132 bool KeepSinglePixels; // if true, single pixels are not destroyed (for vehicle)
133 int32_t AnimationSpeed; // frames per animation phase
134 int32_t LightAngle; // light angle at which we have maximum reflection
135 int32_t LightEmit[3]; // amount the material lights up itself
136 int32_t LightSpot[3]; // spot strength
137 int32_t MinShapeOverlap; // if drawn with a texture with custom shapes, minimum overlap of map pixels over shape blocks in percent to force them being drawn
138
139 void Clear();
140 void Default();
141 bool Load(C4Group &hGroup, const char *szEntryName);
142 void CompileFunc(StdCompiler *pComp);
143 };
144
145 class C4Material: public C4MaterialCore
146 {
147 public:
148 C4Material();
149 public:
150 // Cross-mapped material values
151 int32_t BlastShiftTo; // MatTex
152 int32_t InMatConvertTo; // Mat
153 int32_t BelowTempConvertTo; // MatTex
154 int32_t AboveTempConvertTo; // MatTex
155 int32_t DefaultMatTex; // texture used for single pixel values
156
157 C4Facet PXSFace; // loose pixel facet
158
159 void UpdateScriptPointers(); // set all material script pointers
160 };
161
162 class C4MaterialMap
163 {
164 public:
165 C4MaterialMap();
166 ~C4MaterialMap();
167 public:
168 int32_t Num;
169 C4Material *Map;
170 C4MaterialReaction **ppReactionMap;
171 int32_t max_shape_width,max_shape_height; // maximum size of the largest polygon in any of the used shapes
172
173 C4MaterialReaction DefReactConvert, DefReactPoof, DefReactCorrode, DefReactIncinerate, DefReactInsert;
174 public:
175 // default reactions
176 static bool mrfConvert(C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Real &fXDir, C4Real &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged);
177 static bool mrfPoof (C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Real &fXDir, C4Real &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged);
178 static bool mrfCorrode(C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Real &fXDir, C4Real &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged);
179 static bool mrfIncinerate(C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Real &fXDir, C4Real &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged);
180 static bool mrfInsert (C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Real &fXDir, C4Real &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged);
181 // user-defined actions
182 static bool mrfScript(C4MaterialReaction *pReaction, int32_t &iX, int32_t &iY, int32_t iLSPosX, int32_t iLSPosY, C4Real &fXDir, C4Real &fYDir, int32_t &iPxsMat, int32_t iLsMat, MaterialInteractionEvent evEvent, bool *pfPosChanged);
183 public:
184 void Default();
185 void Clear();
186 int32_t Load(C4Group &hGroup);
187 bool HasMaterials(C4Group &hGroup) const;
188 int32_t Get(const char *szMaterial);
189 bool SaveEnumeration(C4Group &hGroup);
190 bool LoadEnumeration(C4Group &hGroup);
GetReactionUnsafe(int32_t iPXSMat,int32_t iLandscapeMat)191 C4MaterialReaction *GetReactionUnsafe(int32_t iPXSMat, int32_t iLandscapeMat)
192 {
193 assert(ppReactionMap); assert(Inside<int32_t>(iPXSMat,-1,Num-1)); assert(Inside<int32_t>(iLandscapeMat,-1,Num-1));
194 return ppReactionMap[(iLandscapeMat+1)*(Num+1) + iPXSMat+1];
195 }
196 C4MaterialReaction *GetReaction(int32_t iPXSMat, int32_t iLandscapeMat);
197 void UpdateScriptPointers(); // set all material script pointers
198 bool CrossMapMaterials(const char* szEarthMaterial);
199 protected:
200 void SetMatReaction(int32_t iPXSMat, int32_t iLSMat, C4MaterialReaction *pReact);
201 bool SortEnumeration(int32_t iMat, const char *szMatName);
202 };
203
204 extern C4MaterialMap MaterialMap;
205
206 extern int32_t MVehic,MTunnel,MWater,MEarth; // presearched materials
207 extern BYTE MCVehic; // precalculated material color
208 extern BYTE MCHalfVehic; // precalculated material color
209
MatValid(int32_t mat)210 inline bool MatValid(int32_t mat)
211 {
212 return Inside<int32_t>(mat,0,::MaterialMap.Num-1);
213 }
214
MatVehicle(int32_t iMat)215 inline bool MatVehicle(int32_t iMat)
216 {
217 return iMat == MVehic;
218 }
219
IsMCVehicle(BYTE mat)220 inline bool IsMCVehicle(BYTE mat) {
221 return mat == MCVehic;
222 }
IsMCHalfVehicle(BYTE mat)223 inline bool IsMCHalfVehicle(BYTE mat) {
224 return mat == MCHalfVehic;
225 }
IsSomeVehicle(BYTE mat)226 inline bool IsSomeVehicle(BYTE mat) {
227 return IsMCVehicle(mat) || IsMCHalfVehicle(mat);
228 }
229
MatTex2PixCol(int32_t tex)230 inline BYTE MatTex2PixCol(int32_t tex)
231 {
232 return BYTE(tex);
233 }
234
Mat2PixColDefault(int32_t mat)235 inline BYTE Mat2PixColDefault(int32_t mat)
236 {
237 return ::MaterialMap.Map[mat].DefaultMatTex;
238 }
239
MatDensity(int32_t mat)240 inline int32_t MatDensity(int32_t mat)
241 {
242 if (!MatValid(mat)) return 0;
243 return ::MaterialMap.Map[mat].Density;
244 }
245
MatPlacement(int32_t mat)246 inline int32_t MatPlacement(int32_t mat)
247 {
248 if (!MatValid(mat)) return 0;
249 return ::MaterialMap.Map[mat].Placement;
250 }
251
MatDigFree(int32_t mat)252 inline int32_t MatDigFree(int32_t mat)
253 {
254 if (!MatValid(mat)) return 1;
255 return ::MaterialMap.Map[mat].DigFree;
256 }
257
258 #endif
259