fix for https://github.com/Attnam/ivan/issues/119
[k8-i-v-a-n.git] / src / game / items / item_materialcontainer.cpp
blob708c939031919dc61d6c08ba500239c20efa71a0
1 #ifdef HEADER_PHASE
2 ITEM(materialcontainer, item)
4 public:
5 materialcontainer() { }
6 materialcontainer(const materialcontainer&);
7 virtual ~materialcontainer();
9 virtual material* GetSecondaryMaterial() const { return SecondaryMaterial; }
10 virtual void SetSecondaryMaterial(material*, int = 0);
11 virtual void ChangeSecondaryMaterial(material*, int = 0);
12 void InitMaterials(material*, material*, truth = true);
13 virtual void Save(outputfile&) const;
14 virtual void Load(inputfile&);
15 virtual int GetMaterials() const { return 2; }
16 virtual void SignalSpoil(material*);
17 virtual truth CanBePiledWith(citem*, ccharacter*) const;
18 virtual void Be();
19 virtual int GetSpoilLevel() const;
20 virtual material* GetMaterial(int) const;
21 virtual int GetAttachedGod() const;
22 virtual material* GetConsumeMaterial(ccharacter*, materialpredicate = TrueMaterialPredicate) const;
23 virtual material* RemoveMaterial(material*);
24 material* RemoveMainMaterial();
25 virtual material* RemoveSecondaryMaterial();
26 virtual void CalculateEmitation();
27 virtual void InitMaterials(const materialscript*, const materialscript*, truth);
28 virtual int GetSparkleFlags() const;
29 virtual truth DumpTo (character *dumper, v2 dest);
30 protected:
31 virtual sLong GetMaterialPrice() const;
32 virtual truth CalculateHasBe() const;
33 virtual void GenerateMaterials();
34 virtual col16 GetMaterialColorB(int) const;
35 virtual alpha GetAlphaB(int) const;
36 virtual int GetRustDataB() const;
37 material* SecondaryMaterial;
41 #else
45 void materialcontainer::SetSecondaryMaterial(material* What, int SpecialFlags) { SetMaterial(SecondaryMaterial, What, GetDefaultSecondaryVolume(), SpecialFlags); }
49 void materialcontainer::ChangeSecondaryMaterial(material* What, int SpecialFlags) { ChangeMaterial(SecondaryMaterial, What, GetDefaultSecondaryVolume(), SpecialFlags); }
53 void materialcontainer::InitMaterials(material* M1, material* M2, truth CUP) { ObjectInitMaterials(MainMaterial, M1, GetDefaultMainVolume(), SecondaryMaterial, M2, GetDefaultSecondaryVolume(), CUP); }
57 void materialcontainer::InitMaterials(const materialscript* M, const materialscript* C, truth CUP) { InitMaterials(M->Instantiate(), C->Instantiate(), CUP); }
61 truth materialcontainer::DumpTo (character *dumper, v2 dest) {
62 if (!dumper || (!IsCan() && !IsBottle()) || !GetSecondaryMaterial()) return false;
63 if (!dumper->GetArea()->IsValidPos(dest)) return false;
65 if (Item->IsOnGround()) {
66 room *Room = Item->GetRoom();
68 if (Room) Room->HostileAction(Char);
71 lsquare *sqr = dumper->GetNearLSquare(dest);
72 if (GetSecondaryMaterial()->IsLiquid()) {
73 liquid *Liquid = static_cast<liquid *>(RemoveSecondaryMaterial());
75 if (dumper->IsPlayer()) ADD_MESSAGE("Dumping %s.", Liquid->GetName(false, false).CStr());
76 sqr->SpillFluid(dumper, Liquid, false, true); // ForceHit, ShowMsg
77 } else {
78 item *Lump = lump::Spawn(0, NO_MATERIALS);
79 Lump->InitMaterials(RemoveSecondaryMaterial());
80 sqr->AddItem(Lump);
82 dumper->DexterityAction(10);
83 return true;
88 void materialcontainer::Save(outputfile& SaveFile) const
90 item::Save(SaveFile);
91 SaveFile << SecondaryMaterial;
96 void materialcontainer::Load(inputfile& SaveFile)
98 item::Load(SaveFile);
99 LoadMaterial(SaveFile, SecondaryMaterial);
104 material* materialcontainer::GetMaterial(int I) const
106 return !I ? MainMaterial : SecondaryMaterial;
111 col16 materialcontainer::GetMaterialColorB(int Frame) const
113 if(GetSecondaryMaterial())
114 return GetSecondaryMaterial()->GetColor();
115 else
116 return GetMaterialColorA(Frame);
121 alpha materialcontainer::GetAlphaB(int Frame) const
123 if(GetSecondaryMaterial() && GetSecondaryMaterial()->GetAlpha() > GetAlphaA(Frame))
124 return GetSecondaryMaterial()->GetAlpha();
125 else
126 return GetAlphaA(Frame);
131 void materialcontainer::GenerateMaterials()
133 int Chosen = RandomizeMaterialConfiguration();
134 const fearray<sLong>& MMC = GetMainMaterialConfig();
135 InitMaterial(MainMaterial,
136 MAKE_MATERIAL(MMC.Data[MMC.Size == 1 ? 0 : Chosen]),
137 GetDefaultMainVolume());
138 const fearray<sLong>& SMC = GetSecondaryMaterialConfig();
139 InitMaterial(SecondaryMaterial,
140 MAKE_MATERIAL(SMC.Data[SMC.Size == 1 ? 0 : Chosen]),
141 GetDefaultSecondaryVolume());
146 materialcontainer::~materialcontainer()
148 delete SecondaryMaterial;
153 materialcontainer::materialcontainer(const materialcontainer& MC) : mybase(MC)
155 CopyMaterial(MC.SecondaryMaterial, SecondaryMaterial);
160 void materialcontainer::SignalSpoil (material *Material) {
161 if (!Exists()) return;
162 if (Material == MainMaterial) {
163 if (CanBeSeenByPlayer()) ADD_MESSAGE("%s becomes so spoiled that it cannot hold its contents anymore.", CHAR_NAME(DEFINITE));
164 RemoveMainMaterial();
165 } else {
166 if (CanBeSeenByPlayer()) ADD_MESSAGE("The contents of %s spoil completely.", CHAR_NAME(DEFINITE));
167 delete RemoveSecondaryMaterial();
173 truth materialcontainer::CanBePiledWith(citem* Item, ccharacter* Viewer) const
175 if(!item::CanBePiledWith(Item, Viewer))
176 return false;
178 const materialcontainer* Weapon = static_cast<const materialcontainer*>(Item);
180 if(!SecondaryMaterial && !Weapon->SecondaryMaterial)
181 return true;
183 return SecondaryMaterial
184 && Weapon->SecondaryMaterial
185 && SecondaryMaterial->IsSameAs(Weapon->SecondaryMaterial)
186 && SecondaryMaterial->GetSpoilLevel() == Weapon->SecondaryMaterial->GetSpoilLevel();
191 void materialcontainer::Be()
193 item::Be();
195 if(Exists() && SecondaryMaterial)
196 SecondaryMaterial->Be(ItemFlags);
201 int materialcontainer::GetSparkleFlags() const
203 return (MainMaterial->IsSparkling() ? SPARKLING_A : 0)
204 | (SecondaryMaterial && SecondaryMaterial->IsSparkling() ? SPARKLING_B : 0);
209 int materialcontainer::GetSpoilLevel() const
211 return Max(MainMaterial->GetSpoilLevel(), SecondaryMaterial ? SecondaryMaterial->GetSpoilLevel() : 0);
216 int materialcontainer::GetAttachedGod() const
218 return DataBase->AttachedGod ? DataBase->AttachedGod : SecondaryMaterial ? SecondaryMaterial->GetAttachedGod() : MainMaterial->GetAttachedGod();
223 int materialcontainer::GetRustDataB() const
225 return SecondaryMaterial ? SecondaryMaterial->GetRustData() : GetRustDataA();
230 material* materialcontainer::GetConsumeMaterial(ccharacter* Consumer, materialpredicate Predicate) const
232 if(SecondaryMaterial
233 && (SecondaryMaterial->*Predicate)()
234 && Consumer->CanConsume(SecondaryMaterial))
235 return SecondaryMaterial;
236 else
237 return item::GetConsumeMaterial(Consumer, Predicate);
242 material* materialcontainer::RemoveMaterial(material* Material)
244 if(Material == MainMaterial)
245 return RemoveMainMaterial();
246 else
247 return RemoveSecondaryMaterial();
252 material* materialcontainer::RemoveMainMaterial()
254 truth Equipped = PLAYER->Equips(this);
256 if(!SecondaryMaterial)
257 RemoveFromSlot();
258 else if(SecondaryMaterial->IsLiquid())
260 if(!game::IsInWilderness())
262 lsquare* Square = GetLSquareUnder();
263 RemoveFromSlot();
264 Square->SpillFluid(0, static_cast<liquid*>(SecondaryMaterial));
265 SetSecondaryMaterial(0, NO_PIC_UPDATE|NO_SIGNALS);
267 else
268 RemoveFromSlot();
270 else
272 item* Lump = lump::Spawn(0, NO_MATERIALS);
273 Lump->InitMaterials(SecondaryMaterial);
274 DonateFluidsTo(Lump);
275 DonateIDTo(Lump);
276 DonateSlotTo(Lump);
277 SetSecondaryMaterial(0, NO_PIC_UPDATE|NO_SIGNALS);
280 SendToHell();
282 if(Equipped)
283 game::AskForEscPress(CONST_S("Equipment destroyed!"));
285 return 0;
290 material* materialcontainer::RemoveSecondaryMaterial()
292 material* Material = SecondaryMaterial;
293 SetSecondaryMaterial(0);
294 SendNewDrawAndMemorizedUpdateRequest();
295 return Material;
300 void materialcontainer::CalculateEmitation()
302 Emitation = GetBaseEmitation();
304 if(MainMaterial)
305 game::CombineLights(Emitation, MainMaterial->GetEmitation());
307 if(SecondaryMaterial)
308 game::CombineLights(Emitation, SecondaryMaterial->GetEmitation());
313 truth materialcontainer::CalculateHasBe() const
315 return LifeExpectancy
316 || (MainMaterial && MainMaterial->HasBe())
317 || (SecondaryMaterial && SecondaryMaterial->HasBe());
322 sLong materialcontainer::GetMaterialPrice() const
324 return MainMaterial->GetRawPrice()
325 + (SecondaryMaterial ? SecondaryMaterial->GetRawPrice() : 0);
327 #endif