3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
8 * See LICENSING which should be included
9 * along with this file for more details
28 dungeon::dungeon(int Index
) : Index(Index
) {
30 for (int c
= 0; c
< GetLevels(); ++c
) Generated
[c
] = false;
34 dungeon::~dungeon () {
35 for (int c
= 0; c
< GetLevels(); ++c
) delete Level
[c
];
41 void dungeon::Initialize () {
42 std::map
<int, dungeonscript
>::const_iterator DungeonIterator
= game::GetGameScript()->GetDungeon().find(Index
);
43 if (DungeonIterator
!= game::GetGameScript()->GetDungeon().end()) {
44 DungeonScript
= &DungeonIterator
->second
;
46 ABORT("Unknown dungeon #%d requested!", int(Index
));
49 Level
= new level
*[GetLevels()];
50 Generated
= new truth
[GetLevels()];
51 for (int c
= 0; c
< GetLevels(); ++c
) Level
[c
] = 0;
55 const levelscript
*dungeon::GetLevelScript (int I
) {
56 std::map
<int, levelscript
>::const_iterator LevelIterator
= DungeonScript
->GetLevel().find(I
);
57 const levelscript
*LevelScript
;
58 if (LevelIterator
!= DungeonScript
->GetLevel().end()) LevelScript
= &LevelIterator
->second
;
59 else LevelScript
= DungeonScript
->GetLevelDefault();
64 /* Returns whether the level has been visited before */
65 truth
dungeon::PrepareLevel (int Index
, truth Visual
) {
66 if (Generated
[Index
]) {
67 level
*NewLevel
= LoadLevel(game::SaveName(), Index
);
68 game::SetCurrentArea(NewLevel
);
69 game::SetCurrentLevel(NewLevel
);
70 game::SetCurrentLSquareMap(NewLevel
->GetMap());
73 truth enterImageShown
= false;
74 for (int tries
= 100; tries
> 0; --tries
) {
75 level
*NewLevel
= Level
[Index
] = new level
;
76 NewLevel
->SetDungeon(this);
77 NewLevel
->SetIndex(Index
);
78 const levelscript
*LevelScript
= GetLevelScript(Index
);
79 NewLevel
->SetLevelScript(LevelScript
);
80 if (!enterImageShown
&& Visual
) {
81 enterImageShown
= true;
82 if (LevelScript
->GetEnterImage()) {
83 cbitmap
*EnterImage
= new bitmap(game::GetGameDir()+"graphics/" + *LevelScript
->GetEnterImage());
84 game::SetEnterImage(EnterImage
);
85 v2 Displacement
= *LevelScript
->GetEnterTextDisplacement();
86 game::SetEnterTextDisplacement(Displacement
);
87 game::TextScreen(CONST_S("Entering ")+GetLevelDescription(Index
)+CONST_S("...\n\nThis may take some time, please wait."), Displacement
, WHITE
, false, true, &game::BusyAnimation
);
88 game::TextScreen(CONST_S("Entering ")+GetLevelDescription(Index
)+CONST_S("...\n\nPress any key to continue."), Displacement
, WHITE
, true, false, &game::BusyAnimation
);
89 game::SetEnterImage(0);
92 game::TextScreen(CONST_S("Entering ")+GetLevelDescription(Index
)+CONST_S("...\n\nThis may take some time, please wait."), ZERO_V2
, WHITE
, false, true, &game::BusyAnimation
);
95 if (!NewLevel
->Generate(Index
)) {
101 game::SetCurrentLSquareMap(NewLevel
->GetMap());
102 Generated
[Index
] = true;
103 game::BusyAnimation();
104 if (*NewLevel
->GetLevelScript()->GenerateMonsters()) NewLevel
->GenerateNewMonsters(NewLevel
->GetIdealPopulation(), false);
107 ABORT("Oops. Cannot generate level. Something is VERY wrong with level scripts.");
112 void dungeon::SaveLevel (cfestring
&SaveName
, int Number
, truth DeleteAfterwards
) {
113 outputfile
SaveFile(SaveName
+'.'+Index
+Number
, ivanconfig::GetUseMaximumCompression());
114 SaveFile
<< Level
[Number
];
115 if (DeleteAfterwards
) {
116 delete Level
[Number
];
122 level
*dungeon::LoadLevel (cfestring
&SaveName
, int Number
) {
123 inputfile
SaveFile(SaveName
+'.'+Index
+Number
);
124 return LoadLevel(SaveFile
, Number
);
128 void dungeon::Save (outputfile
&SaveFile
) const {
129 SaveFile
<< Index
<< WorldMapPos
;
130 for (int c
= 0; c
< GetLevels(); ++c
) SaveFile
<< Generated
[c
];
134 void dungeon::Load (inputfile
&SaveFile
) {
135 SaveFile
>> Index
>> WorldMapPos
;
137 for (int c
= 0; c
< GetLevels(); ++c
) SaveFile
>> Generated
[c
];
141 int dungeon::GetLevels () const {
142 return *DungeonScript
->GetLevels();
146 festring
dungeon::GetLevelDescription (int I
) {
147 if (GetLevel(I
)->GetLevelScript()->GetDescription()) return *GetLevel(I
)->GetLevelScript()->GetDescription();
148 return *DungeonScript
->GetDescription()+" level "+(I
+1);
152 festring
dungeon::GetShortLevelDescription (int I
) {
153 if (GetLevel(I
)->GetLevelScript()->GetShortDescription()) return *GetLevel(I
)->GetLevelScript()->GetShortDescription();
154 return *DungeonScript
->GetShortDescription()+" level "+(I
+1);
158 outputfile
&operator << (outputfile
&SaveFile
, const dungeon
*Dungeon
) {
161 Dungeon
->Save(SaveFile
);
169 inputfile
&operator >> (inputfile
&SaveFile
, dungeon
*&Dungeon
) {
170 if (SaveFile
.Get()) {
171 Dungeon
= new dungeon
;
172 Dungeon
->Load(SaveFile
);
178 level
*dungeon::LoadLevel (inputfile
&SaveFile
, int Number
) {
179 SaveFile
>> Level
[Number
];
180 Level
[Number
]->SetDungeon(this);
181 Level
[Number
]->SetIndex(Number
);
182 Level
[Number
]->SetLevelScript(GetLevelScript(Number
));
183 return Level
[Number
];
187 int dungeon::GetLevelTeleportDestination (int From
) const {
189 if (Index
== ELPURI_CAVE
) {
191 To
= From
+RAND_2
+RAND_2
+RAND_2
+RAND_2
+1;
192 if (To
> DARK_LEVEL
) To
= From
;
194 To
= From
-RAND_2
-RAND_2
-RAND_2
-RAND_2
-1;
199 if (Index
== UNDER_WATER_TUNNEL
) return RAND_N(3);
200 if (Index
== ALIEN_VESSEL
) return RAND_N(3);