added var getter (still untested); fixed 'go delay'
[k8-i-v-a-n.git] / src / game / dungeon.cpp
bloba052dfe9056095332f8263e700f7d079ba1a4c08
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"
22 dungeon::dungeon () {
26 dungeon::dungeon(int Index) : Index(Index) {
27 Initialize();
28 for (int c = 0; c < GetLevels(); ++c) Generated[c] = false;
32 dungeon::~dungeon () {
33 for (int c = 0; c < GetLevels(); ++c) delete Level[c];
34 delete [] Level;
35 delete [] Generated;
39 void dungeon::Initialize () {
40 std::map<int, dungeonscript>::const_iterator DungeonIterator = game::GetGameScript()->GetDungeon().find(Index);
41 if (DungeonIterator != game::GetGameScript()->GetDungeon().end()) {
42 DungeonScript = &DungeonIterator->second;
43 } else {
44 ABORT("Unknown dungeon #%d requested!", int(Index));
45 return;
47 Level = new level *[GetLevels()];
48 Generated = new truth[GetLevels()];
49 for (int c = 0; c < GetLevels(); ++c) Level[c] = 0;
53 const levelscript *dungeon::GetLevelScript (int I) {
54 std::map<int, levelscript>::const_iterator LevelIterator = DungeonScript->GetLevel().find(I);
55 const levelscript *LevelScript;
56 if (LevelIterator != DungeonScript->GetLevel().end()) LevelScript = &LevelIterator->second;
57 else LevelScript = DungeonScript->GetLevelDefault();
58 return LevelScript;
62 /* Returns whether the level has been visited before */
63 truth dungeon::PrepareLevel (int Index, truth Visual) {
64 if (Generated[Index]) {
65 level *NewLevel = LoadLevel(game::SaveName(), Index);
66 game::SetCurrentArea(NewLevel);
67 game::SetCurrentLevel(NewLevel);
68 game::SetCurrentLSquareMap(NewLevel->GetMap());
69 return true;
71 level *NewLevel = Level[Index] = new level;
72 NewLevel->SetDungeon(this);
73 NewLevel->SetIndex(Index);
74 const levelscript *LevelScript = GetLevelScript(Index);
75 NewLevel->SetLevelScript(LevelScript);
76 if (Visual) {
77 if (LevelScript->GetEnterImage()) {
78 cbitmap *EnterImage = new bitmap(game::GetGameDir() + "Graphics/" + *LevelScript->GetEnterImage());
79 game::SetEnterImage(EnterImage);
80 v2 Displacement = *LevelScript->GetEnterTextDisplacement();
81 game::SetEnterTextDisplacement(Displacement);
82 game::TextScreen(CONST_S("Entering ")+GetLevelDescription(Index)+CONST_S("...\n\nThis may take some time, please wait."), Displacement, WHITE, false, true, &game::BusyAnimation);
83 game::TextScreen(CONST_S("Entering ")+GetLevelDescription(Index)+CONST_S("...\n\nPress any key to continue."), Displacement, WHITE, true, false, &game::BusyAnimation);
84 game::SetEnterImage(0);
85 delete EnterImage;
86 } else {
87 game::TextScreen(CONST_S("Entering ")+GetLevelDescription(Index)+CONST_S("...\n\nThis may take some time, please wait."), ZERO_V2, WHITE, false, true, &game::BusyAnimation);
90 NewLevel->Generate(Index);
91 game::SetCurrentLSquareMap(NewLevel->GetMap());
92 Generated[Index] = true;
93 game::BusyAnimation();
94 if (*NewLevel->GetLevelScript()->GenerateMonsters()) NewLevel->GenerateNewMonsters(NewLevel->GetIdealPopulation(), false);
95 return false;
99 void dungeon::SaveLevel (cfestring &SaveName, int Number, truth DeleteAfterwards) {
100 outputfile SaveFile(SaveName+'.'+Index+Number);
101 SaveFile << Level[Number];
102 if (DeleteAfterwards) {
103 delete Level[Number];
104 Level[Number] = 0;
109 level *dungeon::LoadLevel(cfestring &SaveName, int Number) {
110 inputfile SaveFile(SaveName+'.'+Index+Number);
111 return LoadLevel(SaveFile, Number);
115 void dungeon::Save (outputfile &SaveFile) const {
116 SaveFile << Index << WorldMapPos;
117 for (int c = 0; c < GetLevels(); ++c) SaveFile << Generated[c];
121 void dungeon::Load (inputfile &SaveFile) {
122 SaveFile >> Index >> WorldMapPos;
123 Initialize();
124 for (int c = 0; c < GetLevels(); ++c) SaveFile >> Generated[c];
128 int dungeon::GetLevels () const {
129 return *DungeonScript->GetLevels();
133 festring dungeon::GetLevelDescription (int I) {
134 if (GetLevel(I)->GetLevelScript()->GetDescription()) return *GetLevel(I)->GetLevelScript()->GetDescription();
135 return *DungeonScript->GetDescription()+" level "+(I+1);
139 festring dungeon::GetShortLevelDescription (int I) {
140 if (GetLevel(I)->GetLevelScript()->GetShortDescription()) return *GetLevel(I)->GetLevelScript()->GetShortDescription();
141 return *DungeonScript->GetShortDescription()+" level "+(I+1);
145 outputfile &operator << (outputfile &SaveFile, const dungeon *Dungeon) {
146 if (Dungeon) {
147 SaveFile.Put(1);
148 Dungeon->Save(SaveFile);
149 } else {
150 SaveFile.Put(0);
152 return SaveFile;
156 inputfile &operator >> (inputfile &SaveFile, dungeon *&Dungeon) {
157 if (SaveFile.Get()) {
158 Dungeon = new dungeon;
159 Dungeon->Load(SaveFile);
161 return SaveFile;
165 level *dungeon::LoadLevel(inputfile &SaveFile, int Number) {
166 SaveFile >> Level[Number];
167 Level[Number]->SetDungeon(this);
168 Level[Number]->SetIndex(Number);
169 Level[Number]->SetLevelScript(GetLevelScript(Number));
170 return Level[Number];
174 int dungeon::GetLevelTeleportDestination (int From) const {
175 int To;
176 if (Index == ELPURI_CAVE) {
177 if (RAND_2) {
178 To = From+RAND_2+RAND_2+RAND_2+RAND_2+1;
179 if (To > DARK_LEVEL) To = From;
180 } else {
181 To = From-RAND_2-RAND_2-RAND_2-RAND_2-1;
182 if (To < 0) To = 0;
184 return To;
186 if (Index == UNDER_WATER_TUNNEL) return RAND_N(3);
187 return From;