typos
[k8-i-v-a-n.git] / src / game / lterra.cpp
blob3403d8689a16bf2b3cc9a5e2f9f26f0322962e23
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 levelset.cpp */
15 glterrainprototype::glterrainprototype(const glterrainprototype* Base, glterrainspawner Spawner, cchar* ClassID) : Base(Base), Spawner(Spawner), ClassID(ClassID) { Index = protocontainer<glterrain>::Add(this); }
16 olterrainprototype::olterrainprototype(const olterrainprototype* Base, olterrainspawner Spawner, cchar* ClassID) : Base(Base), Spawner(Spawner), ClassID(ClassID) { Index = protocontainer<olterrain>::Add(this); }
18 square* lterrain::GetSquareUnderEntity(int) const { return LSquareUnder; }
19 level* lterrain::GetLevel() const { return LSquareUnder->GetLevel(); }
20 lsquare* lterrain::GetNearLSquare(v2 Pos) const { return LSquareUnder->GetLevel()->GetLSquare(Pos); }
21 lsquare* lterrain::GetNearLSquare(int x, int y) const { return LSquareUnder->GetLevel()->GetLSquare(x, y); }
22 room* lterrain::GetRoom() const { return GetLSquareUnder()->GetRoom(); }
23 void lterrain::SetMainMaterial(material* NewMaterial, int SpecialFlags) { SetMaterial(MainMaterial, NewMaterial, 0, SpecialFlags); }
24 void lterrain::ChangeMainMaterial(material* NewMaterial, int SpecialFlags) { ChangeMaterial(MainMaterial, NewMaterial, 0, SpecialFlags); }
25 void lterrain::InitMaterials(const materialscript* M, const materialscript*, truth CUP) { InitMaterials(M->Instantiate(), CUP); }
27 void glterrain::InstallDataBase(int NewConfig) { databasecreator<glterrain>::InstallDataBase(this, NewConfig); }
28 void olterrain::InstallDataBase(int NewConfig) { databasecreator<olterrain>::InstallDataBase(this, NewConfig); }
29 int glterrain::GetGraphicsContainerIndex() const { return GR_GLTERRAIN; }
30 int olterrain::GetGraphicsContainerIndex() const { return GR_OLTERRAIN; }
32 truth olterraindatabase::AllowRandomInstantiation() const { return !(Config & S_LOCK_ID); }
34 festring olterrain::GetText() const { return ""; }
36 void lterrain::Load(inputfile& SaveFile)
38 LSquareUnder = static_cast<lsquare*>(game::GetSquareInLoad());
39 object::Load(SaveFile);
42 void glterrain::Save(outputfile& SaveFile) const
44 SaveFile << (uShort)GetType();
45 lterrain::Save(SaveFile);
46 SaveFile << (uShort)GetConfig();
49 void glterrain::Load(inputfile& SaveFile)
51 lterrain::Load(SaveFile);
52 databasecreator<glterrain>::InstallDataBase(this, ReadType(uShort, SaveFile));
55 void olterrain::Save(outputfile& SaveFile) const
57 SaveFile << (uShort)GetType();
58 lterrain::Save(SaveFile);
59 SaveFile << (uShort)GetConfig();
60 SaveFile << HP;
63 void olterrain::Load(inputfile& SaveFile)
65 lterrain::Load(SaveFile);
66 databasecreator<olterrain>::InstallDataBase(this, ReadType(uShort, SaveFile));
67 SaveFile >> HP;
70 v2 lterrain::GetPos() const
72 return LSquareUnder->GetPos();
75 truth lterrain::SitOn(character* Sitter)
77 if(GetSitMessage().GetSize())
79 ADD_MESSAGE("%s", GetSitMessage().CStr());
80 Sitter->EditAP(-1000);
81 return true;
83 else
84 return false;
87 void olterrain::Break()
89 lsquare* Square = GetLSquareUnder();
90 const fearray<contentscript<item> >& ItemArray = GetLeftOverItems();
92 for(uInt c1 = 0; c1 < ItemArray.Size; ++c1)
93 if(ItemArray[c1].IsValid())
95 const interval* TimesPtr = ItemArray[c1].GetTimes();
96 int Times = TimesPtr ? TimesPtr->Randomize() : 1;
98 for(int c2 = 0; c2 < Times; ++c2)
100 item* Item = ItemArray[c1].InstantiateBasedOnMaterial(GetMainMaterial()->GetDigProductMaterial());
102 if(Item)
104 Square->AddItem(Item);
105 Item->SpecialGenerationHandler();
110 Square->ChangeOLTerrainAndUpdateLights(0);
113 glterrain* glterrainprototype::SpawnAndLoad(inputfile& SaveFile) const
115 glterrain* Terrain = Spawner(0, LOAD);
116 Terrain->Load(SaveFile);
117 Terrain->CalculateAll();
118 return Terrain;
121 olterrain* olterrainprototype::SpawnAndLoad(inputfile& SaveFile) const
123 olterrain* Terrain = Spawner(0, LOAD);
124 Terrain->Load(SaveFile);
125 Terrain->CalculateAll();
126 return Terrain;
129 void lterrain::Initialize(int NewConfig, int SpecialFlags)
131 if(!(SpecialFlags & LOAD))
133 InstallDataBase(NewConfig);
134 RandomizeVisualEffects();
136 if(!(SpecialFlags & NO_MATERIALS))
137 GenerateMaterials();
140 if(!(SpecialFlags & LOAD))
142 PostConstruct();
143 RestoreHP();
146 if(!(SpecialFlags & LOAD))
148 if(!(SpecialFlags & NO_MATERIALS))
150 CalculateAll();
152 if(!(SpecialFlags & NO_PIC_UPDATE))
153 UpdatePictures();
158 truth lterrain::CanBeSeenByPlayer() const
160 return LSquareUnder->CanBeSeenByPlayer();
163 truth lterrain::CanBeSeenBy(character* Who) const
165 if(Who->IsPlayer())
166 return CanBeSeenByPlayer();
167 else
168 return LSquareUnder->CanBeSeenFrom(Who->GetPos(), Who->GetLOSRangeSquare());
171 void olterrain::ShowRestMessage(character*) const
173 if(GetRestMessage().GetSize())
174 ADD_MESSAGE("%s", GetRestMessage().CStr());
177 void lterrain::SignalEmitationIncrease(col24 EmitationUpdate)
179 if(game::CompareLights(EmitationUpdate, Emitation) > 0)
181 game::CombineLights(Emitation, EmitationUpdate);
183 if(LSquareUnder)
184 LSquareUnder->SignalEmitationIncrease(EmitationUpdate);
188 void lterrain::SignalEmitationDecrease(col24 EmitationUpdate)
190 if(game::CompareLights(EmitationUpdate, Emitation) >= 0 && Emitation)
192 col24 Backup = Emitation;
193 CalculateEmitation();
195 if(Backup != Emitation && LSquareUnder)
196 LSquareUnder->SignalEmitationDecrease(EmitationUpdate);
200 truth olterrain::Enter(truth DirectionUp) const
202 if(DirectionUp)
203 ADD_MESSAGE("You can't go up.");
204 else
205 ADD_MESSAGE("You can't go down.");
207 return false;
210 int olterrain::GetStrengthValue() const
212 return GetMainMaterial()->GetStrengthValue() / 20;
215 void olterrain::ReceiveDamage(character* Villain, int Damage, int)
217 if(CanBeDestroyed() && Damage > GetStrengthValue())
219 EditHP(GetStrengthValue() - Damage);
221 if(HP <= 0)
223 room* Room = GetRoom();
224 Break();
226 if(Room)
227 Room->DestroyTerrain(Villain);
232 void olterrain::BeKicked(character* Kicker, int Damage, int)
234 if(CanBeDestroyed() && Damage > GetMainMaterial()->GetStrengthValue() >> 1)
236 EditHP((GetMainMaterial()->GetStrengthValue() >> 1) - Damage);
238 if(HP <= 0)
240 room* Room = GetRoom();
242 if(CanBeSeenByPlayer())
243 ADD_MESSAGE("%s is shattered.", CHAR_NAME(DEFINITE));
245 Break();
247 if(Room)
248 Room->DestroyTerrain(Kicker);
251 else if(Kicker->IsPlayer())
252 ADD_MESSAGE("Your kick has no effect on %s.", CHAR_NAME(DEFINITE));
255 int olterrain::CalculateMaxHP()
257 if(GetMainMaterial())
259 sLong SV = GetMainMaterial()->GetStrengthValue();
260 return SV * SV * GetHPModifier() / 6000;
262 else
263 return 0;
266 int glterrain::GetAttachedGod() const
268 return DataBase->AttachedGod ? DataBase->AttachedGod : MainMaterial->GetAttachedGod();
271 int olterrain::GetAttachedGod() const
273 return DataBase->AttachedGod ? DataBase->AttachedGod : MainMaterial->GetAttachedGod();
276 void olterrain::SetConfig(int NewConfig, int SpecialFlags)
278 databasecreator<olterrain>::InstallDataBase(this, NewConfig);
280 if(!(SpecialFlags & NO_PIC_UPDATE))
281 UpdatePictures();
284 god* olterrain::GetMasterGod() const
286 return game::GetGod(GetConfig());
289 truth olterrain::CanBeDestroyed() const
291 return DataBase->CanBeDestroyed && ((GetPos().X && GetPos().Y && GetPos().X != GetLevel()->GetXSize() - 1 && GetPos().Y != GetLevel()->GetYSize() - 1) || GetLevel()->IsOnGround());
294 //extern itemprototype key_ProtoType;
296 int olterrainprototype::CreateSpecialConfigurations (olterraindatabase **TempConfig, int Configs, int Level) {
297 if (Level) return Configs;
299 if (TempConfig[0]->CreateDivineConfigurations) {
300 Configs = databasecreator<olterrain>::CreateDivineConfigurations(this, TempConfig, Configs);
303 /* Gum solution */
304 if (TempConfig[0]->CreateLockConfigurations) {
305 const item::database*const* KeyConfigData = key::ProtoType.GetConfigData();
306 int KeyConfigSize = key::ProtoType.GetConfigSize();
307 int OldConfigs = Configs;
308 for (int c1 = 0; c1 < OldConfigs; ++c1) {
309 if (!TempConfig[c1]->IsAbstract) {
310 festring lcfgname;
311 lcfgname << TempConfig[c1]->CfgStrName;
312 lcfgname << "|locked-broken";
313 int BaseConfig = TempConfig[c1]->Config;
314 int NewConfig = BaseConfig|BROKEN_LOCK;
315 olterraindatabase* ConfigDataBase = new olterraindatabase(*TempConfig[c1]);
316 ConfigDataBase->InitDefaults(this, NewConfig, lcfgname);
317 ConfigDataBase->PostFix << "with a broken lock";
318 TempConfig[Configs++] = ConfigDataBase;
319 for (int c2 = 0; c2 < KeyConfigSize; ++c2) {
320 festring xcfgname;
321 xcfgname << TempConfig[c1]->CfgStrName;
322 xcfgname << "|locked";
323 NewConfig = BaseConfig|KeyConfigData[c2]->Config;
324 ConfigDataBase = new olterraindatabase(*TempConfig[c1]);
325 ConfigDataBase->InitDefaults(this, NewConfig, xcfgname);
326 ConfigDataBase->PostFix << "with ";
327 if (KeyConfigData[c2]->UsesLongAdjectiveArticle) ConfigDataBase->PostFix << "an "; else ConfigDataBase->PostFix << "a ";
328 ConfigDataBase->PostFix << KeyConfigData[c2]->Adjective << " lock";
329 TempConfig[Configs++] = ConfigDataBase;
335 if (TempConfig[0]->CreateWindowConfigurations) {
336 int OldConfigs = Configs;
337 for (int c1 = 0; c1 < OldConfigs; ++c1) {
338 if (!TempConfig[c1]->IsAbstract) {
339 festring xcfgname;
340 xcfgname << TempConfig[c1]->CfgStrName;
341 xcfgname << "|window";
342 int NewConfig = TempConfig[c1]->Config|WINDOW;
343 olterraindatabase* ConfigDataBase = new olterraindatabase(*TempConfig[c1]);
344 ConfigDataBase->InitDefaults(this, NewConfig, xcfgname);
345 ConfigDataBase->PostFix << "with a window";
346 ConfigDataBase->IsAlwaysTransparent = true;
347 ConfigDataBase->BitmapPos = ConfigDataBase->WindowBitmapPos;
348 TempConfig[Configs++] = ConfigDataBase;
353 return Configs;
356 truth olterrain::IsTransparent() const
358 return IsAlwaysTransparent() || MainMaterial->IsTransparent();
361 void glterrain::ModifyAnimationFrames(int& AF) const
363 if(UseBorderTiles())
364 AF += AF << 3;
367 v2 glterrain::GetBorderBitmapPos(v2 BasePos, int I) const
369 if(UseBorderTiles())
371 int Index = I ? 8 - (I + (I << 3)) / GraphicData.AnimationFrames : 8;
372 v2 MV = game::GetMoveVector(Index);
374 if(VisualEffects & MIRROR)
375 MV.X = -MV.X;
377 if(VisualEffects & FLIP)
378 MV.Y = -MV.Y;
380 if(VisualEffects & ROTATE)
382 cint T = MV.Y;
383 MV.Y = -MV.X;
384 MV.X = T;
387 return BasePos + (MV << 4);
389 else
390 return BasePos;
393 void glterrain::Draw(blitdata& BlitData) const
395 if(UseBorderTiles())
397 cint TrueAF = GraphicData.AnimationFrames / 9;
398 int PictureIndex = (BlitData.CustomData & SQUARE_INDEX_MASK) * TrueAF;
400 if(BlitData.CustomData & ALLOW_ANIMATE && TrueAF != 1)
401 PictureIndex += GET_TICK() & (TrueAF - 1);
403 GraphicData.Picture[PictureIndex]->LuminanceMaskedBlit(BlitData);
405 else
407 cint AF = GraphicData.AnimationFrames;
408 cint F = !(BlitData.CustomData & ALLOW_ANIMATE) || AF == 1 ? 0 : GET_TICK() & (AF - 1);
409 GraphicData.Picture[F]->LuminanceBlit(BlitData);
413 void olterrain::ModifyAnimationFrames(int& AF) const
415 if(UseBorderTiles())
416 AF += AF << 3;
419 v2 olterrain::GetBorderBitmapPos(v2 BasePos, int I) const
421 if(UseBorderTiles())
423 int Index = I ? 8 - (I + (I << 3)) / GraphicData.AnimationFrames : 8;
424 v2 MV = game::GetMoveVector(Index);
426 if(VisualEffects & MIRROR)
427 MV.X = -MV.X;
429 if(VisualEffects & FLIP)
430 MV.Y = -MV.Y;
432 if(VisualEffects & ROTATE)
434 cint T = MV.Y;
435 MV.Y = -MV.X;
436 MV.X = T;
439 return BasePos + (MV << 4);
441 else
442 return BasePos;
445 void olterrain::Draw(blitdata& BlitData) const
447 if(UseBorderTiles())
449 cint TrueAF = GraphicData.AnimationFrames / 9;
450 int PictureIndex = (BlitData.CustomData & SQUARE_INDEX_MASK) * TrueAF;
452 if(BlitData.CustomData & ALLOW_ANIMATE && TrueAF != 1)
453 PictureIndex += GET_TICK() & (TrueAF - 1);
455 GraphicData.Picture[PictureIndex]->AlphaLuminanceBlit(BlitData);
457 else
459 cint AF = GraphicData.AnimationFrames;
460 cint F = !(BlitData.CustomData & ALLOW_ANIMATE) || AF == 1 ? 0 : GET_TICK() & (AF - 1);
461 GraphicData.Picture[F]->AlphaLuminanceBlit(BlitData);
465 void lterrain::SignalRustLevelChange()
467 UpdatePictures();
468 GetLSquareUnder()->SendMemorizedUpdateRequest();
469 GetLSquareUnder()->SendNewDrawRequest();
472 void olterrain::SignalRustLevelChange()
474 lterrain::SignalRustLevelChange();
475 HP = Min(HP, CalculateMaxHP());
478 void lterrain::TryToRust (sLong LiquidModifier) {
479 if (MainMaterial->TryToRust(LiquidModifier*10, 10000)) {
480 if (CanBeSeenByPlayer()) {
481 if (MainMaterial->GetRustLevel() == NOT_RUSTED) ADD_MESSAGE("%s rusts.", CHAR_NAME(DEFINITE));
482 else ADD_MESSAGE("%s rusts more.", CHAR_NAME(DEFINITE));
484 MainMaterial->SetRustLevel(MainMaterial->GetRustLevel()+1);
488 void olterrain::ReceiveAcid(material*, sLong Modifier)
490 if(GetMainMaterial()->GetInteractionFlags() & CAN_DISSOLVE)
492 int Damage = Modifier / 10000;
494 if(Damage)
496 Damage += RAND() % Damage;
497 ReceiveDamage(0, Damage, ACID);
502 void lterrain::InitMaterials(material* FirstMaterial, truth CallUpdatePictures)
504 InitMaterial(MainMaterial, FirstMaterial, 0);
505 SignalVolumeAndWeightChange();
507 if(CallUpdatePictures)
508 UpdatePictures();
511 void lterrain::GenerateMaterials()
513 int Chosen = RandomizeMaterialConfiguration();
514 const fearray<sLong>& MMC = GetMainMaterialConfig();
515 InitMaterial(MainMaterial,
516 MAKE_MATERIAL(MMC.Data[MMC.Size == 1 ? 0 : Chosen]),
520 void glterraindatabase::InitDefaults (const glterrainprototype *NewProtoType, int NewConfig, cfestring &acfgstrname)
522 IsAbstract = false;
523 ProtoType = NewProtoType;
524 Config = NewConfig;
525 CfgStrName = acfgstrname;
528 void olterraindatabase::InitDefaults (const olterrainprototype *NewProtoType, int NewConfig, cfestring &acfgstrname)
530 IsAbstract = false;
531 ProtoType = NewProtoType;
532 Config = NewConfig;
533 CfgStrName = acfgstrname;
536 truth olterrain::ShowThingsUnder() const
538 return DataBase->ShowThingsUnder || IsTransparent();
541 truth olterrain::WillBeDestroyedBy(ccharacter* Char) const
543 return IsWall() && CanBeDestroyed() && MainMaterial->GetStrengthValue() <= (Char->GetAttribute(ARM_STRENGTH) * 3);
546 v2 glterrain::GetBitmapPos(int I) const
548 return GetBorderBitmapPos(DataBase->BitmapPos, I);
551 v2 olterrain::GetBitmapPos(int I) const
553 return GetBorderBitmapPos(DataBase->BitmapPos, I);
556 truth glterrain::IsAnimated() const
558 return GraphicData.AnimationFrames > (UseBorderTiles() ? 9 : 1);
561 truth olterrain::IsAnimated() const
563 return GraphicData.AnimationFrames > (UseBorderTiles() ? 9 : 1);
566 void lterrain::AddLocationDescription(festring& String) const
568 String << " on the " << GetNameSingular();