fixed some bugs in new 'g'o system
[k8-i-v-a-n.git] / src / game / dungeon.cpp
blob3f6c0aac5e5e54659cf114b53362caf5586960f9
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
12 #include "dungeon.h"
13 #include "level.h"
14 #include "script.h"
15 #include "error.h"
16 #include "game.h"
17 #include "fesave.h"
18 #include "femath.h"
19 #include "bitmap.h"
20 #include "iconf.h"
23 dungeon::dungeon () {
27 dungeon::dungeon(int Index) : Index(Index) {
28 Initialize();
29 for (int c = 0; c < GetLevels(); ++c) Generated[c] = false;
33 dungeon::~dungeon () {
34 for (int c = 0; c < GetLevels(); ++c) delete Level[c];
35 delete [] Level;
36 delete [] Generated;
40 void dungeon::Initialize () {
41 std::map<int, dungeonscript>::const_iterator DungeonIterator = game::GetGameScript()->GetDungeon().find(Index);
42 if (DungeonIterator != game::GetGameScript()->GetDungeon().end()) {
43 DungeonScript = &DungeonIterator->second;
44 } else {
45 ABORT("Unknown dungeon #%d requested!", int(Index));
46 return;
48 Level = new level *[GetLevels()];
49 Generated = new truth[GetLevels()];
50 for (int c = 0; c < GetLevels(); ++c) Level[c] = 0;
54 const levelscript *dungeon::GetLevelScript (int I) {
55 std::map<int, levelscript>::const_iterator LevelIterator = DungeonScript->GetLevel().find(I);
56 const levelscript *LevelScript;
57 if (LevelIterator != DungeonScript->GetLevel().end()) LevelScript = &LevelIterator->second;
58 else LevelScript = DungeonScript->GetLevelDefault();
59 return LevelScript;
63 /* Returns whether the level has been visited before */
64 truth dungeon::PrepareLevel (int Index, truth Visual) {
65 if (Generated[Index]) {
66 level *NewLevel = LoadLevel(game::SaveName(), Index);
67 game::SetCurrentArea(NewLevel);
68 game::SetCurrentLevel(NewLevel);
69 game::SetCurrentLSquareMap(NewLevel->GetMap());
70 return true;
72 level *NewLevel = Level[Index] = new level;
73 NewLevel->SetDungeon(this);
74 NewLevel->SetIndex(Index);
75 const levelscript *LevelScript = GetLevelScript(Index);
76 NewLevel->SetLevelScript(LevelScript);
77 if (Visual) {
78 if (LevelScript->GetEnterImage()) {
79 cbitmap *EnterImage = new bitmap(game::GetGameDir() + "Graphics/" + *LevelScript->GetEnterImage());
80 game::SetEnterImage(EnterImage);
81 v2 Displacement = *LevelScript->GetEnterTextDisplacement();
82 game::SetEnterTextDisplacement(Displacement);
83 game::TextScreen(CONST_S("Entering ")+GetLevelDescription(Index)+CONST_S("...\n\nThis may take some time, please wait."), Displacement, WHITE, false, true, &game::BusyAnimation);
84 game::TextScreen(CONST_S("Entering ")+GetLevelDescription(Index)+CONST_S("...\n\nPress any key to continue."), Displacement, WHITE, true, false, &game::BusyAnimation);
85 game::SetEnterImage(0);
86 delete EnterImage;
87 } else {
88 game::TextScreen(CONST_S("Entering ")+GetLevelDescription(Index)+CONST_S("...\n\nThis may take some time, please wait."), ZERO_V2, WHITE, false, true, &game::BusyAnimation);
91 NewLevel->Generate(Index);
92 game::SetCurrentLSquareMap(NewLevel->GetMap());
93 Generated[Index] = true;
94 game::BusyAnimation();
95 if (*NewLevel->GetLevelScript()->GenerateMonsters()) NewLevel->GenerateNewMonsters(NewLevel->GetIdealPopulation(), false);
96 return false;
100 void dungeon::SaveLevel (cfestring &SaveName, int Number, truth DeleteAfterwards) {
101 outputfile SaveFile(SaveName+'.'+Index+Number, ivanconfig::GetUseMaximumCompression());
102 SaveFile << Level[Number];
103 if (DeleteAfterwards) {
104 delete Level[Number];
105 Level[Number] = 0;
110 level *dungeon::LoadLevel (cfestring &SaveName, int Number) {
111 inputfile SaveFile(SaveName+'.'+Index+Number);
112 return LoadLevel(SaveFile, Number);
116 void dungeon::Save (outputfile &SaveFile) const {
117 SaveFile << Index << WorldMapPos;
118 for (int c = 0; c < GetLevels(); ++c) SaveFile << Generated[c];
122 void dungeon::Load (inputfile &SaveFile) {
123 SaveFile >> Index >> WorldMapPos;
124 Initialize();
125 for (int c = 0; c < GetLevels(); ++c) SaveFile >> Generated[c];
129 int dungeon::GetLevels () const {
130 return *DungeonScript->GetLevels();
134 festring dungeon::GetLevelDescription (int I) {
135 if (GetLevel(I)->GetLevelScript()->GetDescription()) return *GetLevel(I)->GetLevelScript()->GetDescription();
136 return *DungeonScript->GetDescription()+" level "+(I+1);
140 festring dungeon::GetShortLevelDescription (int I) {
141 if (GetLevel(I)->GetLevelScript()->GetShortDescription()) return *GetLevel(I)->GetLevelScript()->GetShortDescription();
142 return *DungeonScript->GetShortDescription()+" level "+(I+1);
146 outputfile &operator << (outputfile &SaveFile, const dungeon *Dungeon) {
147 if (Dungeon) {
148 SaveFile.Put(1);
149 Dungeon->Save(SaveFile);
150 } else {
151 SaveFile.Put(0);
153 return SaveFile;
157 inputfile &operator >> (inputfile &SaveFile, dungeon *&Dungeon) {
158 if (SaveFile.Get()) {
159 Dungeon = new dungeon;
160 Dungeon->Load(SaveFile);
162 return SaveFile;
166 level *dungeon::LoadLevel (inputfile &SaveFile, int Number) {
167 SaveFile >> Level[Number];
168 Level[Number]->SetDungeon(this);
169 Level[Number]->SetIndex(Number);
170 Level[Number]->SetLevelScript(GetLevelScript(Number));
171 return Level[Number];
175 int dungeon::GetLevelTeleportDestination (int From) const {
176 int To;
177 if (Index == ELPURI_CAVE) {
178 if (RAND_2) {
179 To = From+RAND_2+RAND_2+RAND_2+RAND_2+1;
180 if (To > DARK_LEVEL) To = From;
181 } else {
182 To = From-RAND_2-RAND_2-RAND_2-RAND_2-1;
183 if (To < 0) To = 0;
185 return To;
187 if (Index == UNDER_WATER_TUNNEL) return RAND_N(3);
188 return From;