ifmapper 0.8.5 → 0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HISTORY.txt +110 -0
- data/IFMapper.gemspec +1 -1
- data/TODO.txt +6 -2
- data/lib/IFMapper/Connection.rb +2 -1
- data/lib/IFMapper/FXConnection.rb +36 -18
- data/lib/IFMapper/FXConnectionDialogBox.rb +10 -2
- data/lib/IFMapper/FXMap.rb +68 -28
- data/lib/IFMapper/FXMapFileDialog.rb +1 -1
- data/lib/IFMapper/FXMapperSettings.rb +15 -5
- data/lib/IFMapper/FXMapperWindow.rb +102 -8
- data/lib/IFMapper/FXRoom.rb +1 -3
- data/lib/IFMapper/FXRoomDialogBox.rb +52 -16
- data/lib/IFMapper/FXSection.rb +9 -0
- data/lib/IFMapper/IFMReader.rb +5 -3
- data/lib/IFMapper/InformReader.rb +803 -0
- data/lib/IFMapper/InformReaderOld.rb +778 -0
- data/lib/IFMapper/InformWriter.rb +349 -0
- data/lib/IFMapper/Map.rb +12 -0
- data/lib/IFMapper/PDFMapExporter.rb +35 -17
- data/lib/IFMapper/Room.rb +4 -1
- data/lib/IFMapper/Section.rb +17 -3
- data/lib/IFMapper/TADSReader.rb +832 -0
- data/lib/IFMapper/TADSWriter.rb +360 -0
- data/lib/IFMapper/TranscriptReader.rb +167 -49
- metadata +16 -11
data/HISTORY.txt
CHANGED
@@ -1,3 +1,113 @@
|
|
1
|
+
v0.9 - What's new:
|
2
|
+
|
3
|
+
- Fixed a very idiotic bug in Cut algorithm. It was basically destroying
|
4
|
+
all cut connections right after they were cut.
|
5
|
+
|
6
|
+
- Editing rooms' names or objects now results in a much, much
|
7
|
+
faster redraw of the map, even if map is very complex.
|
8
|
+
|
9
|
+
- You can now display and edit a location's description. This
|
10
|
+
description is often used by the the automapper during transcript
|
11
|
+
mapping to determine the uniqueness of a room, albeit the main
|
12
|
+
use of editing a room description is to allow creation of
|
13
|
+
new games (currently, Inform).
|
14
|
+
|
15
|
+
- You can now optionally avoid displaying the task or description
|
16
|
+
section on rooms.
|
17
|
+
This is mainly to allow you to read maps that have walkthru tasks
|
18
|
+
in them without giving away the game.
|
19
|
+
|
20
|
+
- IFMapper now supports the concept of closed but unlocked doors.
|
21
|
+
These will be displayed as a white square between connections.
|
22
|
+
The main interest of placing these doors is for creation
|
23
|
+
of new Inform games, not so much for solving games.
|
24
|
+
|
25
|
+
- You can now select exit stubs. Useful for deleting them when
|
26
|
+
automapper detects them incorrectly.
|
27
|
+
|
28
|
+
- Saving and Loading a map will now verify the integrity of the map
|
29
|
+
is correct. This prevets autosave from saving a corrupt map if
|
30
|
+
there is a bug in the program.
|
31
|
+
|
32
|
+
- CTRL-Selection is a toggle selection. That is, if you click once
|
33
|
+
on something already selected, it is deselected.
|
34
|
+
|
35
|
+
- Automapper improvements
|
36
|
+
* Automapper will now deal with complex commands involving 'then'
|
37
|
+
a tad better.
|
38
|
+
* An additional fix to dark rooms. Looking in a dark room would
|
39
|
+
result in the dark room being created, even if the room had
|
40
|
+
already been tagged as dark. Fixed.
|
41
|
+
* When choosing an up/down/in/out/random move direction, a new
|
42
|
+
connection will not be generated if there is already a similar
|
43
|
+
n/s/e/w/etc. link between the two rooms. This helps to simplify
|
44
|
+
some maps.
|
45
|
+
* Automapper now will try to automatically remove stub exits that
|
46
|
+
are not really exits if the user tries to move in that direction
|
47
|
+
and fails.
|
48
|
+
* Automapping was incorrectly reporting a maze when a new exit
|
49
|
+
would point in the same direction as a visited up/down or in/out
|
50
|
+
exit.
|
51
|
+
* Room descriptions are now compared (and stored) without \n at the
|
52
|
+
end of each line. This helps with comparing descriptions with any
|
53
|
+
description the user typed manually.
|
54
|
+
* Automapper will no longer crash if a link is attempted between
|
55
|
+
two rooms in different sections, nor will it corrupt your map as
|
56
|
+
it did before.
|
57
|
+
* Automapper is now a tad smarter in not considering words such
|
58
|
+
as open/close in descriptions. This helps the automapper not
|
59
|
+
get confused if a door which is part of the room description
|
60
|
+
changes state.
|
61
|
+
|
62
|
+
- Inform support.
|
63
|
+
|
64
|
+
* You can now read an inform file and automap it, with
|
65
|
+
some limitations.
|
66
|
+
The main limitation deals with how doors are handled, as Inform
|
67
|
+
offers an almost infinite number of ways of dealing with doors,
|
68
|
+
including the use of at least one of 4 popular libraries. Some
|
69
|
+
code will actually resolve issues of where doors lead to within,
|
70
|
+
for example, the "Enter" or "Exit" command, making parsing .inf
|
71
|
+
files impossible without writing a full inform compiler.
|
72
|
+
A second limitation is that Inform allows doors that exist only
|
73
|
+
on one "side" of a room. These exits will be ignored.
|
74
|
+
The inform automapper should prove compatible with most door
|
75
|
+
libraries, but will probably choke on a lot of hand-coded code.
|
76
|
+
|
77
|
+
* You can now export a map as an Inform .inf (source code) file.
|
78
|
+
This can be helpful at the beginning of designing a game to place
|
79
|
+
all objects/characters, doors and room descriptions easily.
|
80
|
+
Obviously, these source code files will later get hacked heavily
|
81
|
+
manually to provide the real game functionality.
|
82
|
+
IFMapper just gives you a start, helping you design
|
83
|
+
the landscape a tad more easily.
|
84
|
+
Doors are created in Inform using Andrew MacKinnon's easydoors
|
85
|
+
Inform extension.
|
86
|
+
|
87
|
+
NOTE: A word of warning about reading Inform or TADS maps.
|
88
|
+
Since these file formats have no concept of 'sections', they
|
89
|
+
can lead to some **HUGE** maps. The original Adventure, for
|
90
|
+
example, results in a 100x100 map. These huge maps may run
|
91
|
+
into memory issues and currently make the path-finding algorithm
|
92
|
+
work extremely slow.
|
93
|
+
|
94
|
+
- TADS 3 support
|
95
|
+
|
96
|
+
* NOTE: TADS 2 is currently *NOT* supported.
|
97
|
+
|
98
|
+
* You can now read a TADS 3 file and automap it, with some
|
99
|
+
limitations.
|
100
|
+
Basically, TADS 3 templates are currently *NOT* supported.
|
101
|
+
Instead, the standard library templates are kind of hard-coded
|
102
|
+
in the reader.
|
103
|
+
TADS 3's standard lib is more sensible than Inform when it
|
104
|
+
comes to doors, so it should hopefully lead to less
|
105
|
+
problems there.
|
106
|
+
|
107
|
+
* You can now export a TADS 3 (.t) file. Same concept as Inform,
|
108
|
+
albeit doors are created using TADS3 standard door classes.
|
109
|
+
|
110
|
+
|
1
111
|
|
2
112
|
v0.8.5 - This is mainly a bug fix release.
|
3
113
|
|
data/IFMapper.gemspec
CHANGED
@@ -2,7 +2,7 @@ require "rubygems"
|
|
2
2
|
|
3
3
|
spec = Gem::Specification.new do |spec|
|
4
4
|
spec.name = "ifmapper"
|
5
|
-
spec.version = '0.
|
5
|
+
spec.version = '0.9'
|
6
6
|
spec.author = "Gonzalo Garramuno"
|
7
7
|
spec.email = 'ggarram@advance.dsl.com.ar'
|
8
8
|
spec.homepage = 'http://www.rubyforge.org/projects/ifmapper/'
|
data/TODO.txt
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
|
2
|
+
- Ability to remove stub exits if moving in a certain direction fails.
|
3
|
+
Need to trap 'fail' messages for moving such as:
|
4
|
+
You can't go that way.
|
5
|
+
|
6
|
+
|
2
7
|
- Add SVG output
|
3
8
|
- Do Printing
|
4
|
-
- Cleanup code
|
5
|
-
between PDF/PS output)
|
9
|
+
- Cleanup code
|
6
10
|
- Improve window scrolling (seems like an FXRuby bug)
|
7
11
|
- Add Undo (at least for delete)
|
data/lib/IFMapper/Connection.rb
CHANGED
@@ -13,6 +13,7 @@ class Connection
|
|
13
13
|
FREE = 0
|
14
14
|
LOCKED_DOOR = 1
|
15
15
|
SPECIAL = 2
|
16
|
+
CLOSED_DOOR = 3
|
16
17
|
|
17
18
|
# Direction constants
|
18
19
|
BOTH = 0
|
@@ -73,7 +74,7 @@ class Connection
|
|
73
74
|
dirB = Room::DIRECTIONS[idx] if idx
|
74
75
|
end
|
75
76
|
end
|
76
|
-
"#{a} #{dirA
|
77
|
+
"#{a} #{dirA}<->#{b} #{dirB}"
|
77
78
|
end
|
78
79
|
end
|
79
80
|
|
@@ -60,7 +60,7 @@ class FXConnection < Connection
|
|
60
60
|
# window is open, copy the connection data to it.
|
61
61
|
#
|
62
62
|
def selected=(value)
|
63
|
-
@@win.copy_from(self) if value and @@win
|
63
|
+
@@win.copy_from(self) if value and @@win and @@win.shown?
|
64
64
|
@selected = value
|
65
65
|
end
|
66
66
|
|
@@ -205,6 +205,37 @@ class FXConnection < Connection
|
|
205
205
|
return dc.drawBSpline( p )
|
206
206
|
end
|
207
207
|
|
208
|
+
#
|
209
|
+
# Draw a door
|
210
|
+
#
|
211
|
+
def draw_door(dc, zoom, x1, y1, x2, y2)
|
212
|
+
v = [ (x2-x1), (y2-y1) ]
|
213
|
+
t = 10 * zoom / Math.sqrt(v[0]*v[0]+v[1]*v[1])
|
214
|
+
v = [ (v[0]*t).to_i, (v[1]*t).to_i ]
|
215
|
+
m = [ (x2+x1)/2, (y2+y1)/2 ]
|
216
|
+
x1, y1 = [m[0] + v[1], m[1] - v[0]]
|
217
|
+
x2, y2 = [m[0] - v[1], m[1] + v[0]]
|
218
|
+
if @type == LOCKED_DOOR
|
219
|
+
# Locked door
|
220
|
+
dc.drawLine(x1, y1, x2, y2)
|
221
|
+
else
|
222
|
+
# open door
|
223
|
+
v = [ v[0] / 3, v[1] / 3]
|
224
|
+
x1, y1 = x1.to_i, y1.to_i
|
225
|
+
x2, y2 = x2.to_i, y2.to_i
|
226
|
+
pts = []
|
227
|
+
pts << FXPoint.new(x1 - v[0], y1 - v[1])
|
228
|
+
pts << FXPoint.new(x1 + v[0], y1 + v[1])
|
229
|
+
pts << FXPoint.new(x2 + v[0], y2 + v[1])
|
230
|
+
pts << FXPoint.new(x2 - v[0], y2 - v[1])
|
231
|
+
pts << pts[0]
|
232
|
+
width = dc.lineWidth
|
233
|
+
dc.lineWidth = 0
|
234
|
+
dc.drawLines(pts)
|
235
|
+
dc.lineWidth = width
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
208
239
|
#
|
209
240
|
# Draw a complex connection
|
210
241
|
#
|
@@ -219,18 +250,11 @@ class FXConnection < Connection
|
|
219
250
|
x2, y2 = [p[-1].x, p[-1].y]
|
220
251
|
draw_arrow(dc, zoom, x1, y1, x2, y2)
|
221
252
|
|
222
|
-
if @type == LOCKED_DOOR
|
253
|
+
if @type == LOCKED_DOOR or @type == CLOSED_DOOR
|
223
254
|
t = p.size / 2
|
224
255
|
x1, y1 = [ p[t].x, p[t].y ]
|
225
256
|
x2, y2 = [ p[t-2].x, p[t-2].y ]
|
226
|
-
|
227
|
-
v = [ (x2-x1), (y2-y1) ]
|
228
|
-
t = 10 * zoom / Math.sqrt(v[0]*v[0]+v[1]*v[1])
|
229
|
-
v = [ (v[0]*t).to_i, (v[1]*t).to_i ]
|
230
|
-
m = [ (x2+x1)/2, (y2+y1)/2 ]
|
231
|
-
x1, y1 = [m[0] + v[1], m[1] - v[0]]
|
232
|
-
x2, y2 = [m[0] - v[1], m[1] + v[0]]
|
233
|
-
dc.drawLine(x1, y1, x2, y2)
|
257
|
+
draw_door(dc, zoom, x1, y1, x2, y2)
|
234
258
|
end
|
235
259
|
end
|
236
260
|
|
@@ -245,14 +269,8 @@ class FXConnection < Connection
|
|
245
269
|
x2, y2 = @roomB.corner(self, zoom)
|
246
270
|
dc.drawLine( x1, y1, x2, y2 )
|
247
271
|
draw_arrow(dc, zoom, x1, y1, x2, y2)
|
248
|
-
if @type == LOCKED_DOOR
|
249
|
-
|
250
|
-
t = 10 * zoom / Math.sqrt(v[0]*v[0]+v[1]*v[1])
|
251
|
-
v = [ (v[0]*t).to_i, (v[1]*t).to_i ]
|
252
|
-
m = [ (x2+x1)/2, (y2+y1)/2 ]
|
253
|
-
x1, y1 = [m[0] + v[1], m[1] - v[0]]
|
254
|
-
x2, y2 = [m[0] - v[1], m[1] + v[0]]
|
255
|
-
dc.drawLine(x1, y1, x2, y2)
|
272
|
+
if @type == LOCKED_DOOR or @type == CLOSED_DOOR
|
273
|
+
draw_door(dc, zoom, x1, y1, x2, y2)
|
256
274
|
end
|
257
275
|
else
|
258
276
|
# Complex connection in progress or "stub" exit
|
@@ -6,10 +6,18 @@ class FXConnectionDialogBox < FXDialogBox
|
|
6
6
|
|
7
7
|
TYPE_TEXT = [
|
8
8
|
'Free',
|
9
|
+
'Door',
|
9
10
|
'Locked',
|
10
11
|
'Special',
|
11
12
|
]
|
12
13
|
|
14
|
+
TYPE_NUM = [
|
15
|
+
Connection::FREE, # free
|
16
|
+
Connection::CLOSED_DOOR, # door
|
17
|
+
Connection::LOCKED_DOOR, # locked
|
18
|
+
Connection::SPECIAL, # special
|
19
|
+
]
|
20
|
+
|
13
21
|
DIR_TEXT = [
|
14
22
|
'Both',
|
15
23
|
'A to B',
|
@@ -28,7 +36,7 @@ class FXConnectionDialogBox < FXDialogBox
|
|
28
36
|
|
29
37
|
def copy_to()
|
30
38
|
@conn.dir = @dir.currentNo
|
31
|
-
@conn.type = @type.currentNo
|
39
|
+
@conn.type = TYPE_NUM[ @type.currentNo ]
|
32
40
|
@conn.exitAtext = @exitA.currentNo
|
33
41
|
@conn.exitBtext = @exitB.currentNo
|
34
42
|
|
@@ -41,7 +49,7 @@ class FXConnectionDialogBox < FXDialogBox
|
|
41
49
|
self.title = title
|
42
50
|
|
43
51
|
@dir.currentNo = conn.dir
|
44
|
-
@type.currentNo = conn.type || 0
|
52
|
+
@type.currentNo = TYPE_NUM.index(conn.type) || 0
|
45
53
|
@exitA.currentNo = conn.exitAtext
|
46
54
|
@exitB.currentNo = conn.exitBtext
|
47
55
|
@conn = conn
|
data/lib/IFMapper/FXMap.rb
CHANGED
@@ -53,13 +53,6 @@ class FXMap < Map
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
#
|
57
|
-
# Fit all rooms in map, adjusting map size if needed
|
58
|
-
#
|
59
|
-
def fit
|
60
|
-
super
|
61
|
-
create_pathmap
|
62
|
-
end
|
63
56
|
|
64
57
|
#
|
65
58
|
# Jump to a certain section #
|
@@ -241,10 +234,10 @@ class FXMap < Map
|
|
241
234
|
b = c.roomB
|
242
235
|
|
243
236
|
dirA = a.exits.index(c)
|
244
|
-
raise "connection not found #{c} at #{a}" unless dirA
|
237
|
+
raise "A connection not found #{c} at #{a}" unless dirA
|
245
238
|
|
246
239
|
dirB = b.exits.rindex(c)
|
247
|
-
raise "connection not found #{c} at #{b}" unless dirB
|
240
|
+
raise "B connection not found #{c} at #{b}" unless dirB
|
248
241
|
|
249
242
|
vA = FXRoom::DIR_TO_VECTOR[dirA]
|
250
243
|
vB = FXRoom::DIR_TO_VECTOR[dirB]
|
@@ -284,6 +277,12 @@ class FXMap < Map
|
|
284
277
|
return false
|
285
278
|
end
|
286
279
|
|
280
|
+
if (pA[0] - pB[0]).abs > 30 or
|
281
|
+
(pA[1] - pB[1]).abs > 30
|
282
|
+
c.failed = true
|
283
|
+
return
|
284
|
+
end
|
285
|
+
|
287
286
|
# No, okay, we need to do true A* path finding
|
288
287
|
c.failed = false
|
289
288
|
aStar = AStar.new
|
@@ -433,7 +432,7 @@ class FXMap < Map
|
|
433
432
|
@sections[@section].connections.each { |c|
|
434
433
|
a = c.roomA
|
435
434
|
b = c.roomB
|
436
|
-
next if not b
|
435
|
+
next if not b and @complexConnection
|
437
436
|
|
438
437
|
if c.gpts.size > 0
|
439
438
|
2.times { |t|
|
@@ -467,7 +466,15 @@ class FXMap < Map
|
|
467
466
|
}
|
468
467
|
else
|
469
468
|
x1, y1 = a.corner(c, 1, a.exits.index(c))
|
470
|
-
|
469
|
+
if b
|
470
|
+
x2, y2 = b.corner(c, 1, b.exits.rindex(c))
|
471
|
+
else
|
472
|
+
dir = a.exits.index(c)
|
473
|
+
v = FXRoom::DIR_TO_VECTOR[dir]
|
474
|
+
x2 = x1 + v[0] * WS
|
475
|
+
y2 = y1 + v[1] * HS
|
476
|
+
end
|
477
|
+
|
471
478
|
x1, x2 = x2, x1 if x2 < x1
|
472
479
|
y1, y2 = y2, y1 if y2 < y1
|
473
480
|
if x1 == x2
|
@@ -530,6 +537,7 @@ class FXMap < Map
|
|
530
537
|
# Then, create an off-screen image with that same size for double
|
531
538
|
# buffering
|
532
539
|
@image.destroy
|
540
|
+
GC.start
|
533
541
|
@image = FXBMPImage.new(@window.getApp, nil, IMAGE_SHMI|IMAGE_SHMP,
|
534
542
|
width, height)
|
535
543
|
@image.create
|
@@ -731,7 +739,7 @@ class FXMap < Map
|
|
731
739
|
|
732
740
|
# Self-explanatory.
|
733
741
|
def zoom_out
|
734
|
-
if @zoom > 0.
|
742
|
+
if @zoom > 0.1
|
735
743
|
self.zoom -= 0.1
|
736
744
|
end
|
737
745
|
end
|
@@ -1136,13 +1144,16 @@ class FXMap < Map
|
|
1136
1144
|
draw
|
1137
1145
|
return
|
1138
1146
|
else
|
1139
|
-
if event.state & SHIFTMASK == 0
|
1140
|
-
event.state & CONTROLMASK == 0
|
1147
|
+
if event.state & SHIFTMASK == 0
|
1141
1148
|
clear_selection
|
1142
1149
|
end
|
1143
1150
|
# Select the stuff
|
1144
1151
|
selection.update_properties(self)
|
1145
|
-
|
1152
|
+
if event.state & CONTROLMASK == 0
|
1153
|
+
selection.selected ^= true # toggle selection
|
1154
|
+
else
|
1155
|
+
selection.selected = true
|
1156
|
+
end
|
1146
1157
|
end
|
1147
1158
|
end
|
1148
1159
|
draw(sender, sel, event)
|
@@ -1315,11 +1326,10 @@ class FXMap < Map
|
|
1315
1326
|
self.zoom = 0.8
|
1316
1327
|
end
|
1317
1328
|
|
1318
|
-
|
1319
1329
|
#
|
1320
|
-
# Handle
|
1330
|
+
# Handle 'cutting' any selected rooms and/or connections
|
1321
1331
|
#
|
1322
|
-
def
|
1332
|
+
def _cut_selected
|
1323
1333
|
rooms = @sections[@section].rooms.find_all { |r| r.selected }
|
1324
1334
|
conns = @sections[@section].connections.find_all { |c| c.selected }
|
1325
1335
|
############################
|
@@ -1343,6 +1353,22 @@ class FXMap < Map
|
|
1343
1353
|
conns.each { |c| clean_path(c) }
|
1344
1354
|
# Remove connections from current section in map
|
1345
1355
|
@sections[@section].connections -= conns
|
1356
|
+
|
1357
|
+
return conns
|
1358
|
+
end
|
1359
|
+
|
1360
|
+
def cut_selected
|
1361
|
+
_cut_selected
|
1362
|
+
modified = true
|
1363
|
+
draw
|
1364
|
+
end
|
1365
|
+
|
1366
|
+
#
|
1367
|
+
# Handle deleting selected rooms and/or connections
|
1368
|
+
#
|
1369
|
+
def delete_selected
|
1370
|
+
conns = _cut_selected
|
1371
|
+
|
1346
1372
|
# Remove room exits pointing to any removed connection
|
1347
1373
|
conns.each { |c|
|
1348
1374
|
a = c.roomA
|
@@ -1354,10 +1380,8 @@ class FXMap < Map
|
|
1354
1380
|
end
|
1355
1381
|
}
|
1356
1382
|
|
1357
|
-
|
1358
|
-
|
1359
|
-
create_pathmap
|
1360
|
-
draw()
|
1383
|
+
modified = true
|
1384
|
+
draw
|
1361
1385
|
end
|
1362
1386
|
|
1363
1387
|
#
|
@@ -1705,12 +1729,7 @@ class FXMap < Map
|
|
1705
1729
|
#
|
1706
1730
|
def draw_background(dc, event = nil)
|
1707
1731
|
dc.foreground = @options['BG Color']
|
1708
|
-
|
1709
|
-
if event
|
1710
|
-
dc.fillRectangle(event.rect.x, event.rect.y, event.rect.w, event.rect.h)
|
1711
|
-
else
|
1712
|
-
dc.fillRectangle(0,0, @canvas.width, @canvas.height)
|
1713
|
-
end
|
1732
|
+
dc.fillRectangle(0,0, @canvas.width, @canvas.height)
|
1714
1733
|
end
|
1715
1734
|
|
1716
1735
|
#
|
@@ -1794,6 +1813,22 @@ class FXMap < Map
|
|
1794
1813
|
draw
|
1795
1814
|
end
|
1796
1815
|
|
1816
|
+
#
|
1817
|
+
# Draw a single room (callback used when editing room dialog box)
|
1818
|
+
#
|
1819
|
+
def draw_room(room)
|
1820
|
+
idx = @sections[@section].rooms.index(room)
|
1821
|
+
return unless idx
|
1822
|
+
|
1823
|
+
dc = FXDCWindow.new(@canvas)
|
1824
|
+
dc.font = @font
|
1825
|
+
data = { }
|
1826
|
+
data['font'] = @font
|
1827
|
+
data['objfont'] = @objfont
|
1828
|
+
room.draw(dc, @zoom, idx, @options, data)
|
1829
|
+
dc.end
|
1830
|
+
end
|
1831
|
+
|
1797
1832
|
#
|
1798
1833
|
# Draw map
|
1799
1834
|
#
|
@@ -1846,6 +1881,11 @@ class FXMap < Map
|
|
1846
1881
|
end
|
1847
1882
|
|
1848
1883
|
status "Saving '#{@filename}'..."
|
1884
|
+
|
1885
|
+
# Make sure we save a valid map. This is mainly a fail-safe
|
1886
|
+
# in case of an autosave due to a bug.
|
1887
|
+
verify_integrity
|
1888
|
+
|
1849
1889
|
@version = FILE_FORMAT_VERSION
|
1850
1890
|
begin
|
1851
1891
|
f = File.open(@filename, "wb")
|