1 /*
2  *
3  *  Iter Vehemens ad Necem (IVAN)
4  *  Copyright (C) Timo Kiviluoto
5  *  Released under the GNU General
6  *  Public License
7  *
8  *  See LICENSING which should be included
9  *  along with this file for more details
10  *
11  */
12 
13 #ifndef __MATERIA_H__
14 #define __MATERIA_H__
15 
16 #include "script.h"
17 #include "ivandef.h"
18 
19 #define MAKE_MATERIAL material::MakeMaterial
20 
21 class entity;
22 class bodypart;
23 class materialprototype;
24 template <class type> class databasecreator;
25 
26 typedef material* (*materialspawner)(int, long, truth);
27 typedef material* (*materialcloner)(cmaterial*);
28 
29 struct materialdatabase : public databasebase
30 {
31   typedef materialprototype prototype;
32   void InitDefaults(const prototype*, int);
PostProcessmaterialdatabase33   void PostProcess() { }
34   const prototype* ProtoType;
35   ulong CategoryFlags;
36   ulong BodyFlags;
37   ulong InteractionFlags;
38   int StrengthValue;
39   int ConsumeType;
40   int Density;
41   int Color;
42   int RainColor;
43   long PriceModifier;
44   col24 Emitation;
45   int NutritionValue;
46   festring NameStem;
47   festring AdjectiveStem;
48   int Effect;
49   int ConsumeEndMessage;
50   int HitMessage;
51   long ExplosivePower;
52   alpha Alpha;
53   int Flexibility;
54   int SpoilModifier;
55   int EffectStrength;
56   int DigProductMaterial;
57   int ConsumeWisdomLimit;
58   int AttachedGod;
59   festring BreatheMessage;
60   int StepInWisdomLimit;
61   int RustModifier;
62   int Acidicity;
63   int Hotness;
64   contentscript<item> NaturalForm;
65   int HardenedMaterial;
66   int SoftenedMaterial;
67   int IntelligenceRequirement;
68   int Stickiness;
69   truth DisablesPanicWhenConsumed;
70   truth BlockESP;
71   int FireResistance;
72   int BurnModifier;
73 };
74 
75 class materialprototype
76 {
77  public:
78   friend class databasecreator<material>;
79   materialprototype(const materialprototype*, materialspawner, materialcloner, cchar*);
80   material* Spawn(int Config, long Volume = 0) const { return Spawner(Config, Volume, false); }
81   material* SpawnAndLoad(inputfile&) const;
Clone(cmaterial * Material)82   material* Clone(cmaterial* Material) const { return Cloner(Material); }
GetClassID()83   cchar* GetClassID() const { return ClassID; }
GetIndex()84   int GetIndex() const { return Index; }
GetBase()85   const materialprototype* GetBase() const { return Base; }
CreateSpecialConfigurations(materialdatabase **,int Configs,int)86   int CreateSpecialConfigurations(materialdatabase**, int Configs, int) { return Configs; }
ChooseBaseForConfig(materialdatabase ** TempConfig,int,int)87   const materialdatabase* ChooseBaseForConfig(materialdatabase** TempConfig, int, int) { return *TempConfig; }
GetConfigData()88   const materialdatabase*const* GetConfigData() const { return ConfigData; }
GetConfigSize()89   int GetConfigSize() const { return ConfigSize; }
90  private:
91   int Index;
92   const materialprototype* Base;
93   materialdatabase** ConfigData;
94   materialdatabase** ConfigTable[CONFIG_TABLE_SIZE];
95   int ConfigSize;
96   materialspawner Spawner;
97   materialcloner Cloner;
98   cchar* ClassID;
99 };
100 
101 class material
102 {
103  public:
104   friend class databasecreator<material>;
105   typedef materialprototype prototype;
106   typedef materialdatabase database;
107   material(int NewConfig, long InitVolume = 0, truth Load = false)
108   : MotherEntity(0) { Initialize(NewConfig, InitVolume, Load); }
material()109   material() : MotherEntity(0) { }
110   virtual ~material() = default;
111   void AddName(festring&, truth = false, truth = true) const;
112   festring GetName(truth = false, truth = true) const;
113   material* TakeDipVolumeAway(long MaxVolume = 500);
114   virtual void Save(outputfile&) const;
115   virtual void Load(inputfile&);
116   truth Effect(character*, int, long);
117   virtual material* EatEffect(character*, long);
118   truth HitEffect(character*, bodypart*);
GetSkinColor()119   virtual col16 GetSkinColor() const { return GetColor(); }
SetSkinColor(int)120   virtual void SetSkinColor(int) { }
121   long GetRawPrice() const;
122   truth CanBeDug(material* ShovelMaterial) const;
HasBe()123   virtual truth HasBe() const { return false; }
Be(ulong)124   virtual void Be(ulong) { }
GetType()125   int GetType() const { return GetProtoType()->GetIndex(); }
126   virtual void AddConsumeEndMessage(character*) const;
127   DATA_BASE_VALUE(const prototype*, ProtoType);
128   DATA_BASE_VALUE(int, Config);
129   DATA_BASE_VALUE(ulong, CommonFlags);
130   DATA_BASE_VALUE(ulong, NameFlags);
131   DATA_BASE_VALUE(ulong, CategoryFlags);
132   DATA_BASE_VALUE(ulong, BodyFlags);
133   DATA_BASE_VALUE(ulong, InteractionFlags);
134   virtual DATA_BASE_VALUE(int, StrengthValue);
135   DATA_BASE_VALUE(int, ConsumeType);
136   DATA_BASE_VALUE(int, Density);
137   DATA_BASE_VALUE(int, Color);
138   DATA_BASE_VALUE(int, RainColor);
139   DATA_BASE_VALUE(long, PriceModifier);
140   DATA_BASE_VALUE(col24, Emitation);
141   DATA_BASE_VALUE(int, NutritionValue);
142   DATA_BASE_VALUE(cfestring&, NameStem);
143   DATA_BASE_VALUE(cfestring&, AdjectiveStem);
144   DATA_BASE_VALUE(int, Effect);
145   DATA_BASE_VALUE(int, ConsumeEndMessage);
146   DATA_BASE_VALUE(int, HitMessage);
147   DATA_BASE_VALUE(long, ExplosivePower);
148   DATA_BASE_VALUE(alpha, Alpha);
149   DATA_BASE_VALUE(int, Flexibility);
150   DATA_BASE_VALUE(int, SpoilModifier);
151   DATA_BASE_VALUE(int, BurnModifier);
152   DATA_BASE_VALUE(int, EffectStrength);
153   DATA_BASE_VALUE(int, DigProductMaterial);
154   DATA_BASE_VALUE(int, ConsumeWisdomLimit);
155   DATA_BASE_VALUE(int, AttachedGod);
156   DATA_BASE_VALUE(int, RustModifier);
157   DATA_BASE_VALUE(int, Acidicity);
158   DATA_BASE_VALUE(int, Hotness);
159   DATA_BASE_VALUE(const contentscript<item>&, NaturalForm);
160   DATA_BASE_VALUE(int, IntelligenceRequirement);
161   DATA_BASE_VALUE(int, Stickiness);
GetDataBase()162   const database* GetDataBase() const { return DataBase; }
SpawnMore()163   material* SpawnMore() const { return GetProtoType()->Spawn(GetConfig(), Volume); }
SpawnMore(long Volume)164   material* SpawnMore(long Volume) const { return GetProtoType()->Spawn(GetConfig(), Volume); }
165   long GetTotalExplosivePower() const;
166   static material* MakeMaterial(int, long = 0);
IsFlesh()167   virtual truth IsFlesh() const { return false; }
IsLiquid()168   virtual truth IsLiquid() const { return false; }
IsGaseous()169   virtual truth IsGaseous() const { return false; }
170   virtual cchar* GetConsumeVerb() const;
GetMotherEntity()171   entity* GetMotherEntity() const { return MotherEntity; }
SetMotherEntity(entity * What)172   void SetMotherEntity(entity* What) { MotherEntity = What; }
IsSameAs(cmaterial * What)173   truth IsSameAs(cmaterial* What) const { return What->GetConfig() == GetConfig(); }
IsTransparent()174   truth IsTransparent() const { return GetAlpha() != 255; }
175   virtual long GetTotalNutritionValue() const;
IsVeryCloseToSpoiling()176   virtual truth IsVeryCloseToSpoiling() const { return false; }
IsVeryCloseToBurning()177   virtual truth IsVeryCloseToBurning() const { return false; }
AddWetness(long)178   virtual void AddWetness(long) { }
GetSpoilLevel()179   virtual int GetSpoilLevel() const { return 0; }
ResetSpoiling()180   virtual void ResetSpoiling() { }
ResetBurning()181   virtual void ResetBurning() { }
182   truth CanBeEatenByAI(ccharacter*) const;
SetSpoilCounter(int)183   virtual void SetSpoilCounter(int) { }
184   DATA_BASE_VALUE(cfestring&, BreatheMessage);
185   truth BreatheEffect(character*);
186   truth CauseExplosion(character*, long);
187   truth ExplosiveEffect(character*);
SkinColorIsSparkling()188   virtual truth SkinColorIsSparkling() const { return IsSparkling(); }
SetSkinColorIsSparkling(truth)189   virtual void SetSkinColorIsSparkling(truth) { }
190   DATA_BASE_VALUE(int, StepInWisdomLimit);
SetRustLevel(int)191   virtual void SetRustLevel(int) { }
GetRustLevel()192   virtual int GetRustLevel() const { return NOT_RUSTED; }
GetRustData()193   virtual int GetRustData() const { return NOT_RUSTED; }
194   virtual truth TryToRust(long, long = 0) { return false; }
195   static const database* GetDataBase(int);
CanSpoil()196   virtual truth CanSpoil() const { return false; }
IsSolid()197   truth IsSolid() const { return !IsLiquid() && !IsGaseous(); }
198   /* A dummy materialpredicate */
True()199   truth True() const { return true; }
200   void FinishConsuming(character*);
GetVolume()201   long GetVolume() const { return Volume; }
GetWeight()202   long GetWeight() const
203   {
204     return Volume ? long(double(Volume) * GetDensity() / 1000) : 0;
205   }
EditVolume(long What)206   void EditVolume(long What) { SetVolume(Volume + What); }
207   void SetVolume(long);
SetVolumeNoSignals(long What)208   void SetVolumeNoSignals(long What) { Volume = What; }
IsPowder()209   virtual truth IsPowder() const { return false; }
210   static item* CreateNaturalForm(int, long);
211   item* CreateNaturalForm(long) const;
IsInfectedByLeprosy()212   virtual truth IsInfectedByLeprosy() const { return false; }
SetIsInfectedByLeprosy(truth)213   virtual void SetIsInfectedByLeprosy(truth) { }
AddRustLevelDescription(festring &,truth)214   virtual truth AddRustLevelDescription(festring&, truth) const { return false; }
215   int GetHardenedMaterial(citem*) const;
216   int GetSoftenedMaterial(citem*) const;
217   int GetHardenModifier(citem*) const;
GetSpoilPercentage()218   virtual int GetSpoilPercentage() const { return 0; }
Spoils()219   virtual truth Spoils() const { return false; }
220   virtual truth IsExplosive() const;
221   virtual truth IsSparkling() const;
Duplicate()222   material* Duplicate() const { return DataBase->ProtoType->Clone(this); }
223   truth IsStuckTo(ccharacter*) const;
224   DATA_BASE_TRUTH(DisablesPanicWhenConsumed);
225   DATA_BASE_TRUTH(BlockESP);
226   DATA_BASE_VALUE(int, FireResistance);
SetIsBurning(int What)227   virtual void SetIsBurning(int What) { Burning = What; }
IsBurning()228   virtual int IsBurning() const { return Burning; }
AddBurnLevelDescription(festring &,truth)229   virtual truth AddBurnLevelDescription(festring&, truth) const { return false; }
SetBurnLevel(int,truth)230   virtual void SetBurnLevel(int, truth) { }
GetBurnData()231   virtual int GetBurnData() const { return NOT_BURNT; }
GetBurnLevel()232   virtual int GetBurnLevel() const { return NOT_BURNT; }
AddToThermalEnergy(int)233   virtual void AddToThermalEnergy(int) { }
AddToSteadyStateThermalEnergy(int)234   virtual void AddToSteadyStateThermalEnergy(int) { }
AddToTransientThermalEnergy(int)235   virtual void AddToTransientThermalEnergy(int) { }
RemoveFromThermalEnergy(int)236   virtual void RemoveFromThermalEnergy(int) { }
ResetThermalEnergies()237   virtual void ResetThermalEnergies() { }
GetTransientThermalEnergy()238   virtual int GetTransientThermalEnergy() const { return 0; }
239  protected:
PostConstruct()240   virtual void PostConstruct() { }
241   void Initialize(int, long, truth);
FindProtoType()242   virtual const prototype* FindProtoType() const { return &ProtoType; }
243   static const prototype ProtoType;
244   const database* DataBase;
245   entity* MotherEntity;
246   long Volume;
247   int Burning;
248 };
249 
250 template <class type, class base>
251 class materialsysbase : public base
252 {
253  public:
254   typedef materialsysbase<type, base> mybase;
255   static type* Spawn(int Config = 0, long Volume = 0, truth Load = false)
256   {
257     type* M = new type;
258     M->Initialize(Config, Volume, Load);
259     return M;
260   }
Clone(const type * T)261   static material* Clone(const type* T) { return new type(*T); }
FindProtoType()262   virtual const materialprototype* FindProtoType() const { return &ProtoType; }
263   static const materialprototype ProtoType;
264 };
265 
266 #ifdef __FILE_OF_STATIC_MATERIAL_PROTOTYPE_DEFINITIONS__
267 #define MATERIAL_PROTO(name, base)\
268 template<> const materialprototype\
269   name##sysbase::ProtoType(&base::ProtoType,\
270                            reinterpret_cast<materialspawner>(&name##sysbase::Spawn),\
271                            reinterpret_cast<materialcloner>(&name##sysbase::Clone), #name);
272 #else
273 #define MATERIAL_PROTO(name, base)
274 #endif
275 
276 #define MATERIAL(name, base)\
277 class name;\
278 typedef materialsysbase<name, base> name##sysbase;\
279 MATERIAL_PROTO(name, base)\
280 class name : public name##sysbase
281 
282 #endif
283