Skip to content

Commit 640be29

Browse files
committed
Fix savegames
Maps are now recreated correctly if a savegame is loaded. Fixes #196.
1 parent e73d409 commit 640be29

File tree

3 files changed

+131
-16
lines changed

3 files changed

+131
-16
lines changed

src/CombatState.lua

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
local Object = require( 'src.Object' );
1010
local ProceduralMapGenerator = require( 'src.map.procedural.ProceduralMapGenerator' )
11-
local ProceduralMap = require( 'src.map.procedural.ProceduralMap' )
11+
local MapLoader = require( 'src.map.MapLoader' )
12+
local Map = require( 'src.map.Map' )
1213
local Factions = require( 'src.characters.Factions' );
1314
local ProjectileManager = require( 'src.items.weapons.ProjectileManager' );
1415
local ExplosionManager = require( 'src.items.weapons.ExplosionManager' );
@@ -49,19 +50,38 @@ function CombatState.new()
4950
local sadisticAIDirector
5051

5152
-- ------------------------------------------------
52-
-- Public Methods
53+
-- Local Methods
5354
-- ------------------------------------------------
5455

55-
function self:init( playerFaction, savegame )
56+
local function loadMap( savedMap )
57+
local loader = MapLoader.new()
58+
local tiles, mw, mh = loader:recreateMap( savedMap )
59+
map = Map.new()
60+
map:init( tiles, mw, mh )
61+
end
62+
63+
local function createMap()
5664
local generator = ProceduralMapGenerator.new()
5765
generator:init()
5866

5967
local tiles = generator:getTiles()
6068
local mw, mh = generator:getTileGridDimensions()
6169

62-
map = ProceduralMap.new( tiles, mw, mh )
63-
map:init()
70+
map = Map.new()
71+
map:init( tiles, mw, mh )
6472
map:setSpawnpoints( generator:getSpawnpoints() )
73+
end
74+
75+
-- ------------------------------------------------
76+
-- Public Methods
77+
-- ------------------------------------------------
78+
79+
function self:init( playerFaction, savegame )
80+
if savegame then
81+
loadMap( savegame.map )
82+
else
83+
createMap()
84+
end
6585

6686
factions = Factions.new( map );
6787
factions:addFaction( Faction.new( FACTIONS.ENEMY, true ))

src/map/procedural/ProceduralMap.lua renamed to src/map/Map.lua

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ local ItemFactory = require( 'src.items.ItemFactory' )
66
-- Module
77
-- ------------------------------------------------
88

9-
local ProceduralMap = {}
9+
local Map = {}
1010

1111
-- ------------------------------------------------
1212
-- Constants
@@ -18,13 +18,15 @@ local DIRECTION = require( 'src.constants.DIRECTION' )
1818
-- Constructor
1919
-- ------------------------------------------------
2020

21-
function ProceduralMap.new( tiles, width, height )
22-
local self = Observable.new():addInstance( 'ProceduralMap' )
21+
function Map.new()
22+
local self = Observable.new():addInstance( 'Map' )
2323

2424
-- ------------------------------------------------
2525
-- Private Attributes
2626
-- ------------------------------------------------
2727

28+
local tiles
29+
local width, height
2830
local spawnpoints
2931

3032
-- ------------------------------------------------
@@ -61,13 +63,9 @@ function ProceduralMap.new( tiles, width, height )
6163
-- Initialises the map by creating the Tiles, creating references to the
6264
-- neighbouring tiles and adding WorldObjects.
6365
--
64-
function self:init( savegame )
65-
-- TODO Fix savegames
66-
if savegame then
67-
error( 'Savegames are currently borked!' )
68-
return
69-
end
70-
66+
function self:init( ntiles, nwidth, nheight )
67+
tiles = ntiles
68+
width, height = nwidth, nheight
7169
addNeighbours()
7270
end
7371

@@ -211,4 +209,4 @@ function ProceduralMap.new( tiles, width, height )
211209
return self
212210
end
213211

214-
return ProceduralMap
212+
return Map

src/map/MapLoader.lua

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
---
2+
-- This module handles the loading of a map from a savefile and creating an
3+
-- actual Map object.
4+
-- @module MapLoader
5+
--
6+
7+
-- ------------------------------------------------
8+
-- Required Modules
9+
-- ------------------------------------------------
10+
11+
local Object = require( 'src.Object' )
12+
local TileFactory = require( 'src.map.tiles.TileFactory' )
13+
local WorldObjectFactory = require( 'src.map.worldobjects.WorldObjectFactory' )
14+
15+
-- ------------------------------------------------
16+
-- Module
17+
-- ------------------------------------------------
18+
19+
local MapLoader = {}
20+
21+
-- ------------------------------------------------
22+
-- Constructor
23+
-- ------------------------------------------------
24+
25+
function MapLoader.new()
26+
local self = Object.new():addInstance( 'MapLoader' )
27+
28+
-- ------------------------------------------------
29+
-- Private Methods
30+
-- ------------------------------------------------
31+
32+
local function recreateTile( x, y, id )
33+
return TileFactory.create( x, y, id )
34+
end
35+
36+
local function recreateWorldObject( id, hp, passable, blocksVision, inventory )
37+
local worldObject = WorldObjectFactory.create( id )
38+
worldObject:setHitPoints( hp )
39+
worldObject:setPassable( passable )
40+
worldObject:setBlocksVision( blocksVision )
41+
if worldObject:isContainer() and inventory then
42+
worldObject:getInventory():loadItems( inventory )
43+
end
44+
return worldObject
45+
end
46+
47+
local function loadSavedTiles( savedTiles )
48+
local loadedTiles = {}
49+
for _, tile in ipairs( savedTiles ) do
50+
-- Recreate the tile.
51+
local recreatedTile = recreateTile( tile.x, tile.y, tile.id )
52+
53+
-- Recreate any worldobject that was located on the tile.
54+
if tile.worldObject then
55+
local obj = tile.worldObject
56+
local worldObject = recreateWorldObject( obj.id, obj.hp, obj.passable, obj.blocksVision, obj.inventory )
57+
recreatedTile:addWorldObject( worldObject )
58+
end
59+
60+
-- Recreate the tile's inventory if it had one.
61+
if tile.inventory then
62+
recreatedTile:getInventory():loadItems( tile.inventory )
63+
end
64+
65+
-- Set the exploration info of each faction for this tile.
66+
if tile.explored then
67+
for i, v in pairs( tile.explored ) do
68+
recreatedTile:setExplored( i, v )
69+
end
70+
end
71+
72+
-- Store tile in the table.
73+
loadedTiles[tile.x] = loadedTiles[tile.x] or {}
74+
loadedTiles[tile.x][tile.y] = recreatedTile
75+
end
76+
return loadedTiles
77+
end
78+
79+
-- ------------------------------------------------
80+
-- Public Methods
81+
-- ------------------------------------------------
82+
83+
---
84+
-- Recreates a map from a savefile.
85+
-- @tparam table savedmap A table containing the saved map information.
86+
-- @treturn table A table containing the recreated tiles and world objects.
87+
-- @treturn number The width of the recreated map.
88+
-- @treturn number The height of the recreated map.
89+
--
90+
function self:recreateMap( savedmap )
91+
return loadSavedTiles( savedmap.tiles ), savedmap.width, savedmap.height
92+
end
93+
94+
return self
95+
end
96+
97+
return MapLoader

0 commit comments

Comments
 (0)