Skip to content

Commit 8c7f3a4

Browse files
committed
Refactoring
1 parent 28d8885 commit 8c7f3a4

File tree

14 files changed

+400
-298
lines changed

14 files changed

+400
-298
lines changed

Source/diablo.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3224,9 +3224,6 @@ tl::expected<void, std::string> LoadGameLevelTown(bool firstflag, lvl_entry lvld
32243224
if (gbIsMultiplayer)
32253225
DeltaLoadLevel();
32263226

3227-
if (lvldir == ENTRY_TOWNSWITCH)
3228-
InitTownTriggers();
3229-
32303227
IncProgress();
32313228

32323229
for (int x = 0; x < DMAXX; x++)

Source/interfac.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,11 @@ void DoLoad(interface_mode uMsg)
473473
}
474474
IncProgress();
475475
FreeGameMem();
476+
if (!GetTownRegistry().HasTown(DestinationTownID)) {
477+
LogError("WM_DIABTOWNSWITCH: unknown town '{}'", DestinationTownID);
478+
loadResult = tl::make_unexpected<std::string>("Unknown destination town");
479+
break;
480+
}
476481
GetTownRegistry().SetCurrentTown(DestinationTownID);
477482

478483
if (MyPlayer != nullptr) {
@@ -595,6 +600,19 @@ void ProgressEventHandler(const SDL_Event &event, uint16_t modState)
595600

596601
} // namespace
597602

603+
void QueueTownSwitch()
604+
{
605+
if (MyPlayer != nullptr) {
606+
MyPlayer->_pInvincible = true;
607+
SDL_Event event;
608+
CustomEventToSdlEvent(event, WM_DIABTOWNSWITCH);
609+
if (!SDLC_PushEvent(&event)) {
610+
LogError("QueueTownSwitch: {}", SDL_GetError());
611+
SDL_ClearError();
612+
}
613+
}
614+
}
615+
598616
void RegisterCustomEvents()
599617
{
600618
#ifndef USE_SDL1

Source/interfac.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ enum Cutscenes : uint8_t {
7171
CutGate,
7272
};
7373

74+
/** @brief Queues WM_DIABTOWNSWITCH for the local player (invincible until load completes). */
75+
void QueueTownSwitch();
76+
7477
void interface_msg_pump();
7578
void IncProgress(uint32_t steps = 1);
7679
void CompleteProgress();

Source/levels/gendung.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,11 @@ bool IsNearThemeRoom(WorldTilePosition testPosition)
813813

814814
void InitLevels()
815815
{
816+
// Note: InitializeTristram overwrites any existing "tristram" registration.
817+
// Lua mods that called towns.register("tristram", ...) before InitLevels will
818+
// have their config replaced. There is intentionally no registry Reset() here;
819+
// mod-registered towns persist across new games and are re-populated by the
820+
// Lua runtime at mod load time.
816821
InitializeTristram();
817822
currlevel = 0;
818823
leveltype = DTYPE_TOWN;

Source/levels/town.cpp

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "player.h"
1414
#include "quests.h"
1515
#include "utils/endian_swap.hpp"
16+
#include "utils/log.hpp"
1617

1718
namespace devilution {
1819

@@ -200,33 +201,35 @@ void DrlgTPass3()
200201
}
201202
}
202203

203-
const TownConfig &config = GetTownRegistry().GetTown(GetTownRegistry().GetCurrentTown());
204+
const std::string &townId = GetTownRegistry().GetCurrentTown();
205+
if (!GetTownRegistry().HasTown(townId)) {
206+
LogError("DrlgTPass3: current town '{}' not registered", townId);
207+
return;
208+
}
209+
const TownConfig &config = GetTownRegistry().GetTown(townId);
204210
for (const auto &sector : config.sectors) {
205211
FillSector(sector.filePath.c_str(), sector.x, sector.y);
206212
}
207213

208-
if (GetTownRegistry().GetCurrentTown() == "tristram") {
214+
for (const TownWarpPatch &patch : config.warpClosedPatches) {
215+
if (IsWarpOpen(patch.requiredWarp))
216+
continue;
217+
for (const auto &[pos, cellVal] : patch.dungeonCells)
218+
dungeon[pos.x][pos.y] = static_cast<uint8_t>(cellVal);
219+
for (const TownWarpFillTile &ft : patch.fillTiles)
220+
FillTile(ft.x, ft.y, ft.tile);
221+
if (patch.randomGroundStrip.has_value()) {
222+
const TownWarpClosedRandomGroundStrip &strip = *patch.randomGroundStrip;
223+
for (int x = strip.xStart; x < strip.xEndExclusive; x++) {
224+
FillTile(x, strip.y, PickRandomlyAmong({ 1, 2, 3, 4 }));
225+
}
226+
}
227+
}
228+
229+
if (townId == TristramTownId) {
209230
auto dunData = LoadFileInMem<uint16_t>("levels\\towndata\\automap.dun");
210231
PlaceDunTiles(dunData.get(), { 0, 0 });
211232

212-
if (!IsWarpOpen(DTYPE_CATACOMBS)) {
213-
dungeon[20][7] = 10;
214-
dungeon[20][6] = 8;
215-
FillTile(48, 20, 320);
216-
}
217-
if (!IsWarpOpen(DTYPE_CAVES)) {
218-
dungeon[4][30] = 8;
219-
FillTile(16, 68, 332);
220-
FillTile(16, 70, 331);
221-
}
222-
if (!IsWarpOpen(DTYPE_HELL)) {
223-
dungeon[15][35] = 7;
224-
dungeon[16][35] = 7;
225-
dungeon[17][35] = 7;
226-
for (int x = 36; x < 46; x++) {
227-
FillTile(x, 78, PickRandomlyAmong({ 1, 2, 3, 4 }));
228-
}
229-
}
230233
if (gbIsHellfire) {
231234
if (IsWarpOpen(DTYPE_NEST)) {
232235
TownOpenHive();
@@ -361,7 +364,12 @@ void CleanTownFountain()
361364

362365
void CreateTown(lvl_entry entry)
363366
{
364-
const TownConfig &config = GetTownRegistry().GetTown(GetTownRegistry().GetCurrentTown());
367+
const std::string &townId = GetTownRegistry().GetCurrentTown();
368+
if (!GetTownRegistry().HasTown(townId)) {
369+
LogError("CreateTown: current town '{}' not registered", townId);
370+
return;
371+
}
372+
const TownConfig &config = GetTownRegistry().GetTown(townId);
365373
dminPosition = config.dminPosition;
366374
dmaxPosition = config.dmaxPosition;
367375
ViewPosition = config.GetEntryPoint(entry, TWarpFrom);

0 commit comments

Comments
 (0)