nonhumans separation
[k8-i-v-a-n.git] / src / game / materias.cpp
blob40ca0835771a135f9b2e9a5612e7206a10034135
1 /*
3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
6 * Public License
8 * See LICENSING which should be included
9 * along with this file for more details
13 /* Compiled through materset.cpp */
15 void organic::ResetSpoiling() { SpoilCounter = SpoilLevel = 0; }
17 cchar* liquid::GetConsumeVerb() const { return "drinking"; }
19 truth powder::IsExplosive() const { return !Wetness && material::IsExplosive(); }
21 truth ironalloy::IsSparkling() const { return material::IsSparkling() && GetRustLevel() == NOT_RUSTED; }
23 void organic::Be(feuLong Flags)
25 if(SpoilCheckCounter++ >= 50)
27 if(MotherEntity->AllowSpoil())
29 if(Flags & HASTE)
30 SpoilCounter += 125;
31 else if(Flags & SLOW)
32 SpoilCounter += 5;
33 else
34 SpoilCounter += 25;
36 if(SpoilCounter < GetSpoilModifier())
38 if(SpoilCounter << 1 >= GetSpoilModifier())
40 int NewSpoilLevel = ((SpoilCounter << 4) / GetSpoilModifier()) - 7;
42 if(NewSpoilLevel != SpoilLevel)
44 SpoilLevel = NewSpoilLevel;
45 MotherEntity->SignalSpoilLevelChange(this);
49 else
51 SpoilLevel = 8;
52 MotherEntity->SignalSpoil(this);
56 SpoilCheckCounter = 0;
60 void organic::Save(outputfile& SaveFile) const
62 material::Save(SaveFile);
63 SaveFile << SpoilCounter << SpoilCheckCounter << SpoilLevel;
66 void organic::Load(inputfile& SaveFile)
68 material::Load(SaveFile);
69 SaveFile >> SpoilCounter >> SpoilCheckCounter >> SpoilLevel;
72 void organic::PostConstruct()
74 SpoilLevel = SpoilCheckCounter = 0;
75 SpoilCounter = (RAND() % GetSpoilModifier()) >> 5;
78 void flesh::PostConstruct()
80 organic::PostConstruct();
81 SkinColorSparkling = InfectedByLeprosy = false;
82 SkinColor = GetColor();
85 void flesh::Save(outputfile& SaveFile) const
87 organic::Save(SaveFile);
88 SaveFile << SkinColor << SkinColorSparkling << InfectedByLeprosy;
91 void flesh::Load(inputfile& SaveFile)
93 organic::Load(SaveFile);
94 SaveFile >> SkinColor >> SkinColorSparkling >> InfectedByLeprosy;
97 void powder::Be(feuLong)
99 if(Wetness > 0)
100 --Wetness;
103 void powder::Save(outputfile& SaveFile) const
105 material::Save(SaveFile);
106 SaveFile << Wetness;
109 void powder::Load(inputfile& SaveFile)
111 material::Load(SaveFile);
112 SaveFile >> Wetness;
115 material* organic::EatEffect(character* Eater, sLong Amount)
117 Amount = Volume > Amount ? Amount : Volume;
118 GetMotherEntity()->SpecialEatEffect(Eater, Amount);
119 Effect(Eater, TORSO_INDEX, Amount);
120 Eater->ReceiveNutrition(GetNutritionValue() * Amount * 20 / (1000 * (GetSpoilLevel() + 1)));
122 if(IsInfectedByLeprosy() && Amount && !RAND_N(25000 / Amount))
123 Eater->GainIntrinsic(LEPROSY);
125 if(GetSpoilLevel() > 0)
127 Eater->BeginTemporaryState(CONFUSED, int(Amount * GetSpoilLevel() * sqrt(GetNutritionValue()) / 1000));
129 if(GetBodyFlags() & CAN_HAVE_PARASITE
130 && !(RAND() % (250 / GetSpoilLevel())))
131 Eater->GainIntrinsic(PARASITIZED);
134 if(GetSpoilLevel() > 4)
135 Eater->BeginTemporaryState(POISONED, int(Amount * (GetSpoilLevel() - 4) * sqrt(GetNutritionValue()) / 1000));
137 if(Volume != Amount)
139 EditVolume(-Amount);
140 return 0;
142 else
143 return MotherEntity->RemoveMaterial(this);
146 void organic::AddConsumeEndMessage(character* Eater) const
148 if(Eater->IsPlayer())
150 if(GetSpoilLevel() > 0 && GetSpoilLevel() <= 4)
151 ADD_MESSAGE("Ugh. This stuff was slightly spoiled.");
152 else if(GetSpoilLevel() > 4)
153 ADD_MESSAGE("Ugh. This stuff was terribly spoiled!");
156 material::AddConsumeEndMessage(Eater);
159 void organic::SetSpoilCounter(int What)
161 SpoilCounter = What;
163 if(SpoilCounter < GetSpoilModifier())
165 if(SpoilCounter << 1 >= GetSpoilModifier())
167 int NewSpoilLevel = ((SpoilCounter << 4) / GetSpoilModifier()) - 7;
169 if(NewSpoilLevel != SpoilLevel)
171 SpoilLevel = NewSpoilLevel;
172 MotherEntity->SignalSpoilLevelChange(this);
176 else
177 MotherEntity->SignalSpoil(this);
180 void ironalloy::SetRustLevel (int What) {
181 if (GetRustLevel() != What) {
182 if (!RustData) RustData = (RAND() & 0xFC) | What;
183 else if (!What) RustData = 0;
184 else RustData = (RustData & 0xFC) | What;
185 if (MotherEntity) MotherEntity->SignalRustLevelChange();
189 int ironalloy::GetStrengthValue() const
191 int Base = material::GetStrengthValue();
193 switch(GetRustLevel())
195 case NOT_RUSTED: return Base;
196 case SLIGHTLY_RUSTED: return ((Base << 3) + Base) / 10;
197 case RUSTED: return ((Base << 1) + Base) >> 2;
198 case VERY_RUSTED: return Base >> 1;
201 return 0; /* not possible */
204 truth ironalloy::AddRustLevelDescription(festring& Name, truth Articled) const
206 if(GetRustLevel() == NOT_RUSTED)
207 return false;
209 if(Articled)
210 Name << "a ";
212 switch(GetRustLevel())
214 case SLIGHTLY_RUSTED:
215 Name << "slightly rusted ";
216 break;
217 case RUSTED:
218 Name << "rusted ";
219 break;
220 case VERY_RUSTED:
221 Name << "very rusted ";
222 break;
225 return true;
228 void ironalloy::Save(outputfile& SaveFile) const
230 material::Save(SaveFile);
231 SaveFile << RustData;
234 void ironalloy::Load(inputfile& SaveFile)
236 material::Load(SaveFile);
237 SaveFile >> RustData;
240 void liquid::TouchEffect(item* Item, cfestring& LocationName)
242 if(GetRustModifier())
243 Item->TryToRust(GetRustModifier() * GetVolume());
245 if(GetAcidicity())
246 Item->ReceiveAcid(this, LocationName, Volume * GetAcidicity());
248 character* Char = Item->GetBodyPartMaster();
250 if(Char)
251 Effect(Char, Item->GetBodyPartIndex(), Volume >> 6);
254 void liquid::TouchEffect(lterrain* Terrain)
256 if(GetRustModifier())
257 Terrain->TryToRust(GetRustModifier() * GetVolume());
259 if(GetAcidicity())
260 Terrain->ReceiveAcid(this, Volume * GetAcidicity());
263 void liquid::TouchEffect(character* Char, int BodyPartIndex)
265 if(GetRustModifier())
266 Char->GetBodyPart(BodyPartIndex)->TryToRust(GetRustModifier() * GetVolume());
268 if(Char->IsEnabled() && GetAcidicity())
269 Char->GetBodyPart(BodyPartIndex)->ReceiveAcid(this, CONST_S(""), Volume * GetAcidicity() >> 1);
271 if(Char->IsEnabled())
272 Effect(Char, BodyPartIndex, Volume >> 9);
275 /* Doesn't do the actual rusting, just returns whether it should happen */
277 truth ironalloy::TryToRust(sLong Modifier, sLong Volume)
279 if(GetRustLevel() != VERY_RUSTED)
281 if(!Volume)
282 Volume = GetVolume();
284 sLong Chance = sLong(30000000. * sqrt(Volume) / (Modifier * GetRustModifier()));
286 if(Chance <= 1 || !(RAND() % Chance))
287 return true;
290 return false;
293 int organic::GetSpoilPercentage() const
295 return 100 * SpoilCounter / GetSpoilModifier();