unnecessary messing with code
[k8-i-v-a-n.git] / src / game / lterra.cpp
blob7851c8dbc995d0300cf02a9cad79e0624376c977
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)
298 if(Level)
299 return Configs;
301 if(TempConfig[0]->CreateDivineConfigurations)
302 Configs = databasecreator<olterrain>::CreateDivineConfigurations(this, TempConfig, Configs);
304 /* Gum solution */
306 if(TempConfig[0]->CreateLockConfigurations)
308 const item::database*const* KeyConfigData = key::ProtoType.GetConfigData();
309 int KeyConfigSize = key::ProtoType.GetConfigSize();
310 int OldConfigs = Configs;
312 for(int c1 = 0; c1 < OldConfigs; ++c1)
313 if(!TempConfig[c1]->IsAbstract)
315 int BaseConfig = TempConfig[c1]->Config;
316 int NewConfig = BaseConfig | BROKEN_LOCK;
317 olterraindatabase* ConfigDataBase = new olterraindatabase(*TempConfig[c1]);
318 ConfigDataBase->InitDefaults(this, NewConfig);
319 ConfigDataBase->PostFix << "with a broken lock";
320 TempConfig[Configs++] = ConfigDataBase;
322 for(int c2 = 0; c2 < KeyConfigSize; ++c2)
324 NewConfig = BaseConfig | KeyConfigData[c2]->Config;
325 ConfigDataBase = new olterraindatabase(*TempConfig[c1]);
326 ConfigDataBase->InitDefaults(this, NewConfig);
327 ConfigDataBase->PostFix << "with ";
329 if(KeyConfigData[c2]->UsesLongAdjectiveArticle)
330 ConfigDataBase->PostFix << "an ";
331 else
332 ConfigDataBase->PostFix << "a ";
334 ConfigDataBase->PostFix << KeyConfigData[c2]->Adjective << " lock";
335 TempConfig[Configs++] = ConfigDataBase;
340 if(TempConfig[0]->CreateWindowConfigurations)
342 int OldConfigs = Configs;
344 for(int c1 = 0; c1 < OldConfigs; ++c1)
345 if(!TempConfig[c1]->IsAbstract)
347 int NewConfig = TempConfig[c1]->Config | WINDOW;
348 olterraindatabase* ConfigDataBase = new olterraindatabase(*TempConfig[c1]);
349 ConfigDataBase->InitDefaults(this, NewConfig);
350 ConfigDataBase->PostFix << "with a window";
351 ConfigDataBase->IsAlwaysTransparent = true;
352 ConfigDataBase->BitmapPos = ConfigDataBase->WindowBitmapPos;
353 TempConfig[Configs++] = ConfigDataBase;
357 return Configs;
360 truth olterrain::IsTransparent() const
362 return IsAlwaysTransparent() || MainMaterial->IsTransparent();
365 void glterrain::ModifyAnimationFrames(int& AF) const
367 if(UseBorderTiles())
368 AF += AF << 3;
371 v2 glterrain::GetBorderBitmapPos(v2 BasePos, int I) const
373 if(UseBorderTiles())
375 int Index = I ? 8 - (I + (I << 3)) / GraphicData.AnimationFrames : 8;
376 v2 MV = game::GetMoveVector(Index);
378 if(VisualEffects & MIRROR)
379 MV.X = -MV.X;
381 if(VisualEffects & FLIP)
382 MV.Y = -MV.Y;
384 if(VisualEffects & ROTATE)
386 cint T = MV.Y;
387 MV.Y = -MV.X;
388 MV.X = T;
391 return BasePos + (MV << 4);
393 else
394 return BasePos;
397 void glterrain::Draw(blitdata& BlitData) const
399 if(UseBorderTiles())
401 cint TrueAF = GraphicData.AnimationFrames / 9;
402 int PictureIndex = (BlitData.CustomData & SQUARE_INDEX_MASK) * TrueAF;
404 if(BlitData.CustomData & ALLOW_ANIMATE && TrueAF != 1)
405 PictureIndex += GET_TICK() & (TrueAF - 1);
407 GraphicData.Picture[PictureIndex]->LuminanceMaskedBlit(BlitData);
409 else
411 cint AF = GraphicData.AnimationFrames;
412 cint F = !(BlitData.CustomData & ALLOW_ANIMATE) || AF == 1 ? 0 : GET_TICK() & (AF - 1);
413 GraphicData.Picture[F]->LuminanceBlit(BlitData);
417 void olterrain::ModifyAnimationFrames(int& AF) const
419 if(UseBorderTiles())
420 AF += AF << 3;
423 v2 olterrain::GetBorderBitmapPos(v2 BasePos, int I) const
425 if(UseBorderTiles())
427 int Index = I ? 8 - (I + (I << 3)) / GraphicData.AnimationFrames : 8;
428 v2 MV = game::GetMoveVector(Index);
430 if(VisualEffects & MIRROR)
431 MV.X = -MV.X;
433 if(VisualEffects & FLIP)
434 MV.Y = -MV.Y;
436 if(VisualEffects & ROTATE)
438 cint T = MV.Y;
439 MV.Y = -MV.X;
440 MV.X = T;
443 return BasePos + (MV << 4);
445 else
446 return BasePos;
449 void olterrain::Draw(blitdata& BlitData) const
451 if(UseBorderTiles())
453 cint TrueAF = GraphicData.AnimationFrames / 9;
454 int PictureIndex = (BlitData.CustomData & SQUARE_INDEX_MASK) * TrueAF;
456 if(BlitData.CustomData & ALLOW_ANIMATE && TrueAF != 1)
457 PictureIndex += GET_TICK() & (TrueAF - 1);
459 GraphicData.Picture[PictureIndex]->AlphaLuminanceBlit(BlitData);
461 else
463 cint AF = GraphicData.AnimationFrames;
464 cint F = !(BlitData.CustomData & ALLOW_ANIMATE) || AF == 1 ? 0 : GET_TICK() & (AF - 1);
465 GraphicData.Picture[F]->AlphaLuminanceBlit(BlitData);
469 void lterrain::SignalRustLevelChange()
471 UpdatePictures();
472 GetLSquareUnder()->SendMemorizedUpdateRequest();
473 GetLSquareUnder()->SendNewDrawRequest();
476 void olterrain::SignalRustLevelChange()
478 lterrain::SignalRustLevelChange();
479 HP = Min(HP, CalculateMaxHP());
482 void lterrain::TryToRust (sLong LiquidModifier) {
483 if (MainMaterial->TryToRust(LiquidModifier*10, 10000)) {
484 if (CanBeSeenByPlayer()) {
485 if (MainMaterial->GetRustLevel() == NOT_RUSTED) ADD_MESSAGE("%s rusts.", CHAR_NAME(DEFINITE));
486 else ADD_MESSAGE("%s rusts more.", CHAR_NAME(DEFINITE));
488 MainMaterial->SetRustLevel(MainMaterial->GetRustLevel()+1);
492 void olterrain::ReceiveAcid(material*, sLong Modifier)
494 if(GetMainMaterial()->GetInteractionFlags() & CAN_DISSOLVE)
496 int Damage = Modifier / 10000;
498 if(Damage)
500 Damage += RAND() % Damage;
501 ReceiveDamage(0, Damage, ACID);
506 void lterrain::InitMaterials(material* FirstMaterial, truth CallUpdatePictures)
508 InitMaterial(MainMaterial, FirstMaterial, 0);
509 SignalVolumeAndWeightChange();
511 if(CallUpdatePictures)
512 UpdatePictures();
515 void lterrain::GenerateMaterials()
517 int Chosen = RandomizeMaterialConfiguration();
518 const fearray<sLong>& MMC = GetMainMaterialConfig();
519 InitMaterial(MainMaterial,
520 MAKE_MATERIAL(MMC.Data[MMC.Size == 1 ? 0 : Chosen]),
524 void glterraindatabase::InitDefaults(const glterrainprototype* NewProtoType, int NewConfig)
526 IsAbstract = false;
527 ProtoType = NewProtoType;
528 Config = NewConfig;
531 void olterraindatabase::InitDefaults(const olterrainprototype* NewProtoType, int NewConfig)
533 IsAbstract = false;
534 ProtoType = NewProtoType;
535 Config = NewConfig;
538 truth olterrain::ShowThingsUnder() const
540 return DataBase->ShowThingsUnder || IsTransparent();
543 truth olterrain::WillBeDestroyedBy(ccharacter* Char) const
545 return IsWall() && CanBeDestroyed() && MainMaterial->GetStrengthValue() <= (Char->GetAttribute(ARM_STRENGTH) * 3);
548 v2 glterrain::GetBitmapPos(int I) const
550 return GetBorderBitmapPos(DataBase->BitmapPos, I);
553 v2 olterrain::GetBitmapPos(int I) const
555 return GetBorderBitmapPos(DataBase->BitmapPos, I);
558 truth glterrain::IsAnimated() const
560 return GraphicData.AnimationFrames > (UseBorderTiles() ? 9 : 1);
563 truth olterrain::IsAnimated() const
565 return GraphicData.AnimationFrames > (UseBorderTiles() ? 9 : 1);
568 void lterrain::AddLocationDescription(festring& String) const
570 String << " on the " << GetNameSingular();