| 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 | |
| 41 | const 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 | |
| 80 | const 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 | |
| 111 | const int32_t C4D_VehicleControl_None = 0, |
| 112 | C4D_VehicleControl_Outside = 1, |
| 113 | C4D_VehicleControl_Inside = 2; |
| 114 | |
| 115 | const 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 | |
| 119 | const 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 | |
| 139 | const int32_t ActIdle = -1; |
| 140 | const int32_t ActHold = -2; |
| 141 | |
| 142 | class C4ActionDef |
| 143 | { |
| 144 | public: |
| 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 | |
| 177 | public: |
| 178 | C4ActionDef(); |
| 179 | void Default(); |
| 180 | void CompileFunc(StdCompiler *pComp); |
| 181 | }; |
| 182 | |
| 183 | class C4DefCore |
| 184 | { |
| 185 | public: |
| 186 | C4DefCore(); |
| 187 | |
| 188 | public: |
| 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 ; // 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 | |
| 277 | public: |
| 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 | |
| 302 | protected: |
| 303 | bool Compile(const char *szSource, const char *szName); |
| 304 | }; |
| 305 | |
| 306 | class C4Def : public C4DefCore |
| 307 | { |
| 308 | friend class C4DefList; |
| 309 | |
| 310 | public: |
| 311 | C4Def(); |
| 312 | ~C4Def(); |
| 313 | |
| 314 | public: |
| 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 | |
| 337 | protected: |
| 338 | // copy of the physical info used in FairCrew-mode |
| 339 | C4PhysicalInfo *pFairCrewPhysical; |
| 340 | |
| 341 | C4Facet MainFace; |
| 342 | |
| 343 | public: |
| 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 | |
| 357 | protected: |
| 358 | bool LoadPortraits(C4Group &hGroup); |
| 359 | bool ColorizeByMaterial(class C4MaterialMap &rMats, uint8_t bGBM); |
| 360 | bool LoadActMap(C4Group &hGroup); |
| 361 | void CrossMapActMap(); |
| 362 | |
| 363 | private: |
| 364 | C4ValueArray *GetCustomComponents(C4Value *pvArrayHolder, C4Object *pBuilder, C4Object *pObjInstance = nullptr); |
| 365 | |
| 366 | public: |
| 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 | |
| 378 | class C4DefList : public C4DelegatedIterable<C4DefList>, public CStdFont::CustomImages |
| 379 | { |
| 380 | public: |
| 381 | C4DefList(); |
| 382 | virtual ~C4DefList(); |
| 383 | |
| 384 | public: |
| 385 | bool LoadFailure; |
| 386 | |
| 387 | public: |
| 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 | |
| 417 | private: |
| 418 | std::vector<std::unique_ptr<C4Def>>::iterator FindDefByID(C4ID id); |
| 419 | |
| 420 | std::vector<std::unique_ptr<C4Def>> Defs; |
| 421 | bool Sorted; |
| 422 | |
| 423 | public: |
| 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 |
| 452 | extern const char *ProcedureName[C4D_MaxDFA]; |
| 453 | |