ifmapper 0.5 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,20 +2,22 @@
2
2
 
3
3
 
4
4
  require 'IFMapper/Map'
5
- require 'IFMapper/FXPage'
5
+ require 'IFMapper/FXSection'
6
6
  require 'IFMapper/FXMapDialogBox'
7
- require 'IFMapper/FXPageDialogBox'
7
+ require 'IFMapper/FXSectionDialogBox'
8
+ require 'IFMapper/AStar'
8
9
 
9
10
 
10
11
  class FXMap < Map
11
12
  FILE_FORMAT_VERSION = 1 # Upgrade this if incompatible changes are made
12
- # in the class so that file loading of old files can still
13
- # be checked against.
13
+ # in the class so that file loading of old files
14
+ # can still be checked against.
14
15
 
15
16
  attr_reader :zoom # Current zooming factor
16
17
  attr_accessor :filename # Filename of current map (if any)
17
18
  attr_reader :modified # Was map modified since being loaded?
18
- attr_accessor :navigation # Map is navigation mode (no new nodes can be created)
19
+ attr_accessor :navigation # Map is navigation mode (no new nodes can be
20
+ # created)
19
21
  attr_accessor :options # Map options
20
22
  attr_reader :window # Fox Window for this map
21
23
  attr :version # file format version
@@ -30,7 +32,14 @@ class FXMap < Map
30
32
 
31
33
  @@cursor_arrow = nil
32
34
  @@cursor_cross = nil
33
- @@cursor_updown = nil
35
+ @@cursor_n = nil
36
+ @@cursor_ne = nil
37
+ @@cursor_e = nil
38
+ @@cursor_se = nil
39
+ @@cursor_s = nil
40
+ @@cursor_sw = nil
41
+ @@cursor_w = nil
42
+ @@cursor_nw = nil
34
43
 
35
44
 
36
45
  def _changed
@@ -39,21 +48,23 @@ class FXMap < Map
39
48
  draw
40
49
  end
41
50
 
42
- def page=(x)
51
+ def section=(x)
43
52
  super
44
53
  @complexConnection = false
45
- create_pathmap
46
- update_title
54
+ if @window.shown?
55
+ create_pathmap
56
+ update_title
57
+ end
47
58
  end
48
59
 
49
60
 
50
- def previous_page
51
- self.page = @page - 1
61
+ def previous_section
62
+ self.section = @section - 1
52
63
  _changed
53
64
  end
54
65
 
55
- def next_page
56
- self.page = @page + 1
66
+ def next_section
67
+ self.section = @section + 1
57
68
  _changed
58
69
  end
59
70
 
@@ -62,22 +73,22 @@ class FXMap < Map
62
73
  _changed
63
74
  end
64
75
 
65
- def rename_page
66
- @pages[@page].properties(self)
76
+ def rename_section
77
+ @sections[@section].properties(self)
67
78
  modified = true
68
79
  end
69
80
 
70
- def delete_page
71
- w = FXWarningBox.new(@window, "Are you sure you want to delete this page?")
81
+ def delete_section
82
+ w = FXWarningBox.new(@window, "Are you sure you want to delete this section?")
72
83
  return if w.execute == 0
73
84
 
74
- delete_page_at(@page)
85
+ delete_section_at(@section)
75
86
  modified = true
76
87
  end
77
88
 
78
- def new_page
79
- @pages.push( FXPage.new )
80
- @page = @pages.size - 1
89
+ def new_section
90
+ @sections.push( FXSection.new )
91
+ @section = @sections.size - 1
81
92
  end
82
93
 
83
94
  #
@@ -85,11 +96,12 @@ class FXMap < Map
85
96
  # very simple ascii representation.
86
97
  #
87
98
  def dump_pathmap
88
- s = ' ' * @width + "\n"
99
+ s = ' ' + ' ' * @width + "\n"
89
100
  m = s * @height
90
101
  (0...@width).each { |x|
91
102
  (0...@height).each { |y|
92
- loc = y * (@width+1) + x
103
+ m[y * (@width+2)] = (y % 10).to_s
104
+ loc = y * (@width+2) + x + 1
93
105
  if @pmap[x][y].kind_of?(Connection)
94
106
  m[loc] = '-'
95
107
  elsif @pmap[x][y].kind_of?(Room)
@@ -97,6 +109,7 @@ class FXMap < Map
97
109
  end
98
110
  }
99
111
  }
112
+ puts ' 0123456789' * (@width/10)
100
113
  puts m
101
114
  end
102
115
 
@@ -120,9 +133,9 @@ class FXMap < Map
120
133
  # First, create an empty grid of width x height
121
134
  empty_pathmap # Hmm... needed? Probably not.
122
135
  # Then, fill it in with all rooms...
123
- @pages[@page].rooms.each { |r| @pmap[r.x][r.y] = r }
136
+ @sections[@section].rooms.each { |r| @pmap[r.x][r.y] = r }
124
137
  # And following, add all paths
125
- @pages[@page].connections.each { |c| path_find(c) }
138
+ @sections[@section].connections.each { |c| path_find(c) }
126
139
  end
127
140
 
128
141
  #
@@ -136,7 +149,6 @@ class FXMap < Map
136
149
  # Remove a connection from map, since path creation failed.
137
150
  #
138
151
  def remove_connection(c)
139
- clean_path(c)
140
152
  c.failed = true
141
153
  status "Path for connection #{c} is blocked."
142
154
  end
@@ -188,121 +200,39 @@ class FXMap < Map
188
200
  return true
189
201
  end
190
202
 
191
-
203
+ # Now check if start or goal are fully blocked. If so,
204
+ # fail quickly
192
205
  if pA[0] < 0 or pA[0] >= @width or
193
206
  pB[0] < 0 or pB[0] >= @width or
194
207
  pA[1] < 0 or pA[1] >= @height or
195
- pB[1] < 0 or pB[1] >= @height
208
+ pB[1] < 0 or pB[1] >= @height or
209
+ @pmap[pA[0]][pA[1]].kind_of?(Room) or
210
+ @pmap[pB[0]][pB[1]].kind_of?(Room)
196
211
  remove_connection(c)
197
212
  return false
198
213
  end
199
214
 
215
+ # No, okay, we need to do true A* path finding
200
216
  c.failed = false
217
+ aStar = AStar.new
218
+ MapNode::map(@pmap)
219
+ start = MapNode.new( pA[0], pA[1] )
220
+ goal = MapNode.new( pB[0], pB[1] )
221
+ aStar.goals( start, goal )
222
+ while aStar.search_step == AStar::SEARCH_STATE_SEARCHING
223
+ end
201
224
 
202
- # We do two tries on path finding.
203
- # On first attempt, we try to avoid both rooms and paths.
204
- # That is, we always try to have no paths crossing each other.
205
- #
206
- # If this fails, we try a second time, but we try to avoid just
207
- # rooms. In this second attempt, paths are allowed to intercross.
208
- #
209
- pt = pA.dup
210
- 2.times { |try|
211
- c.gpts = []
212
-
213
- if try == 0
214
- next if @pmap[pA[0]][pA[1]] or @pmap[pB[0]][pB[1]] # try again
215
- else
216
- if @pmap[pA[0]][pA[1]].kind_of?(Room) or
217
- @pmap[pB[0]][pB[1]].kind_of?(Room)
218
- remove_connection(c)
219
- return false
220
- end
221
- end
222
-
223
- # Okay, now we begin the real path algorithm...
224
- # Add first point...
225
- add_path_pt(c, pA[0], pA[1])
226
-
227
- pt = pA.dup
228
-
229
- # Okay, now we begin a simple A* path algorithm.
230
- while pt[0] != pB[0] or pt[1] != pB[1]
231
- # From point pt, get a list of free nodes, by looking all around it.
232
- pts = []
233
- FXRoom::DIR_TO_VECTOR.each_value { |d|
234
- n = pt.dup
235
- n[0] += d[0]
236
- n[1] += d[1]
237
- # Don't add point to list if we go out of map
238
- if n[0] < 0 or n[0] >= @width or
239
- n[1] < 0 or n[1] >= @height
240
- next
241
- end
242
-
243
- # Now, check if pmap is an empty node.
244
- if try == 1
245
- next if @pmap[n[0]][n[1]].kind_of?(Room) or
246
- @pmap[n[0]][n[1]] == c
247
- else
248
- next if @pmap[n[0]][n[1]]
249
- end
250
-
251
- # Ok, we do have an empty node. Add to list.
252
- pts.push(n)
253
- }
254
-
255
- break if pts.empty?
256
-
257
- # Okay, from all possible nodes, calculate best one, using
258
- # the formula:
259
- # F = G + H
260
- # where G = movement cost to move from point to other point
261
- # (10 or 14, depending if move is straight or diagonal)
262
- # H = cost of square to shorten distance to destination.
263
- # (heuristic, in this case using Manhattan distance)
264
- # Next move is the grid node with lowest F cost.
265
-
266
- f = []
267
- pts.each { |x|
268
- dx = x[0] - pt[0]
269
- dy = x[1] - pt[1]
270
- g = 10 # straight move G cost = 10 (ie. prefer straight moves)
271
- if dx.abs + dy.abs > 1
272
- g = 14 # diagonal move G cost = 14
273
- end
274
-
275
- dx = pB[0] - x[0]
276
- dy = pB[1] - x[1]
277
- h = dx * dx + dy * dy
278
-
279
- f.push( h + g )
280
- }
281
-
282
- idx = f.index(f.min)
283
- pt = pts[idx]
284
- add_path_pt(c, pt[0], pt[1])
285
- end # while
286
-
287
-
288
- # Are we really there?
289
- if pt[0] != pB[0] or pt[1] != pB[1]
290
- # No, we must have failed...
291
- clean_path(c)
292
- c.gpts = []
293
- next # go for next try
294
- else
295
- break
296
- end
297
- }
298
-
299
- # If still not there, we cannot connect path, exit gracefully
300
- if pt[0] != pB[0] or pt[1] != pB[1]
301
- # If on second try, remove connection as invalid.
225
+ # Oops, AStar failed. Not a clean path
226
+ if aStar.state == AStar::SEARCH_STATE_FAILED
302
227
  remove_connection(c)
303
228
  return false
304
229
  end
305
230
 
231
+ # We succeeded. Get the path
232
+ c.failed = false
233
+ c.gpts = aStar.path
234
+ # Put path in pathmap so subsequent paths will avoid crossing it.
235
+ c.gpts.each { |p| @pmap[p[0]][p[1]] = c }
306
236
 
307
237
  # Okay, we have a valid path.
308
238
  # Create real path in display coordinates now...
@@ -317,7 +247,6 @@ class FXMap < Map
317
247
  }
318
248
  # And end with b's corner
319
249
  pt = b.corner(c, 1, dirB)
320
- c.failed = false
321
250
  return c.pts.push([pt[0], pt[1]])
322
251
  end
323
252
 
@@ -333,19 +262,10 @@ class FXMap < Map
333
262
  # Used for loading class with Marshal
334
263
  #
335
264
  def marshal_load(variables)
336
- # if variables[1].kind_of?(Map)
337
- # # old format
338
- # @zoom = variables[0]
339
- # tmpmap = variables[1]
340
- # copy(tmpmap)
341
- # @navigation = variables[2]
342
- # @options = variables[3] if variables[3]
343
- # else
344
- @zoom = variables.shift
345
- @navigation = variables.shift
346
- @options = variables.shift
347
- super
348
- # end
265
+ @zoom = variables.shift
266
+ @navigation = variables.shift
267
+ @options = variables.shift
268
+ super
349
269
  @modified = false
350
270
  end
351
271
 
@@ -376,7 +296,7 @@ class FXMap < Map
376
296
  @modified = true
377
297
  x = x / WW
378
298
  y = y / HH
379
- r = @pages[@page].new_room(x, y)
299
+ r = @sections[@section].new_room(x, y)
380
300
  @pmap[x][y] = r
381
301
 
382
302
  buf = FXMapperWindow::copy_buffer()
@@ -386,7 +306,7 @@ class FXMap < Map
386
306
 
387
307
  if @options['Edit on Creation']
388
308
  if not r.modal_properties(self)
389
- @pages[@page].delete_room(r)
309
+ @sections[@section].delete_room(r)
390
310
  @pmap[x][y] = nil
391
311
  return nil
392
312
  end
@@ -434,7 +354,7 @@ class FXMap < Map
434
354
  return @pmap[xx][yy]
435
355
  else
436
356
  # Possible arrow
437
- @pages[@page].connections.each { |c|
357
+ @sections[@section].connections.each { |c|
438
358
  a = c.roomA
439
359
  b = c.roomB
440
360
  next if not b # Complex connection in progress
@@ -497,8 +417,8 @@ class FXMap < Map
497
417
  title << " [Read Only]"
498
418
  end
499
419
  title << " Zoom: %.3f" % @zoom
500
- title << " Page #{@page+1} of #{@pages.size}"
501
- title << " #{@pages[@page].name}"
420
+ title << " Section #{@section+1} of #{@sections.size}"
421
+ title << " #{@sections[@section].name}"
502
422
  @window.title = title
503
423
  end
504
424
 
@@ -650,14 +570,14 @@ class FXMap < Map
650
570
  c = new_connection( roomA, exitA, nil )
651
571
  status "Click on other room exit in complex connection."
652
572
  else
653
- @pages[@page].delete_connection_at(-1)
573
+ @sections[@section].delete_connection_at(-1)
654
574
  c = new_connection( @complexConnection[0],
655
575
  @complexConnection[1], roomA, exitA )
656
576
  if path_find(c) # Do A* path finding to connect both exits
657
577
  @modified = true
658
578
  status "Complex connection done."
659
579
  else
660
- @pages[@page].delete_connection_at(-1)
580
+ @sections[@section].delete_connection_at(-1)
661
581
  end
662
582
  draw
663
583
  @complexConnection = nil
@@ -720,18 +640,6 @@ class FXMap < Map
720
640
  end
721
641
  end
722
642
 
723
- ZOOM_SEQUENCE = [
724
- 0.4,
725
- 0.5,
726
- 0.6,
727
- 0.7,
728
- 0.8,
729
- 0.9,
730
- 1.0,
731
- 1.1,
732
- 1.2,
733
- ]
734
-
735
643
  # Self-explanatory.
736
644
  def zoom_out
737
645
  if @zoom > 0.25
@@ -754,13 +662,45 @@ class FXMap < Map
754
662
  s.normalText = s.text = msg
755
663
  end
756
664
 
665
+ def cursor_switch(x, y)
666
+ if not @options['Use Room Cursor']
667
+ @canvas.defaultCursor = @@cursor_arrow
668
+ return
669
+ end
670
+ q = get_quadrant(x, y)
671
+ case q
672
+ when 0
673
+ @canvas.defaultCursor = @@cursor_n
674
+ when 1
675
+ @canvas.defaultCursor = @@cursor_ne
676
+ when 2
677
+ @canvas.defaultCursor = @@cursor_e
678
+ when 3
679
+ @canvas.defaultCursor = @@cursor_se
680
+ when 4
681
+ @canvas.defaultCursor = @@cursor_s
682
+ when 5
683
+ @canvas.defaultCursor = @@cursor_sw
684
+ when 6
685
+ @canvas.defaultCursor = @@cursor_w
686
+ when 7
687
+ @canvas.defaultCursor = @@cursor_nw
688
+ else
689
+ @canvas.defaultCursor = @@cursor_arrow
690
+ end
691
+ end
692
+
757
693
  #
758
694
  # Show some help status in status line based on cursor position
759
695
  #
760
696
  def help_cb(sender, sel, event)
761
- return if @complexConnection
697
+
762
698
  x = (event.last_x / @zoom).to_i
763
699
  y = (event.last_y / @zoom).to_i
700
+ if @complexConnection
701
+ cursor_switch(x,y)
702
+ return
703
+ end
764
704
 
765
705
  sel = to_object(x, y)
766
706
  if sel
@@ -775,14 +715,7 @@ class FXMap < Map
775
715
  @canvas.defaultCursor = @@cursor_cross
776
716
  status "Click to create new room."
777
717
  else
778
- q = get_quadrant(x, y)
779
- if q == 0 or q == 4
780
- @canvas.defaultCursor = @@cursor_updown
781
- elsif q == 2 or q == 6
782
- @canvas.defaultCursor = @@cursor_leftright
783
- else
784
- @canvas.defaultCursor = @@cursor_arrow
785
- end
718
+ cursor_switch(x, y)
786
719
  status "Click to create new connection."
787
720
  end
788
721
  end
@@ -858,7 +791,7 @@ class FXMap < Map
858
791
  x2 = (x2 / WW).ceil
859
792
  y2 = (y2 / HH).ceil
860
793
 
861
- @pages[@page].rooms.each { |r|
794
+ @sections[@section].rooms.each { |r|
862
795
  if r.x >= x1 and r.x <= x2 and
863
796
  r.y >= y1 and r.y <= y2
864
797
  r.selected = true
@@ -913,8 +846,8 @@ class FXMap < Map
913
846
  # Clear rooms/connections selected
914
847
  #
915
848
  def clear_selection
916
- @pages[@page].rooms.each { |r| r.selected = false }
917
- @pages[@page].connections.each { |r| r.selected = false }
849
+ @sections[@section].rooms.each { |r| r.selected = false }
850
+ @sections[@section].connections.each { |r| r.selected = false }
918
851
  end
919
852
 
920
853
  #
@@ -955,7 +888,7 @@ class FXMap < Map
955
888
  if click_type(x, y)
956
889
  return if @complexConnection
957
890
  # Add a new room
958
- roomB = @pages[@page].rooms[-1]
891
+ roomB = @sections[@section].rooms[-1]
959
892
  roomA = new_xy_room( x, y )
960
893
  if roomB and roomA and @options['Automatic Connection']
961
894
  # check to see if rooms are next to each other
@@ -1002,7 +935,7 @@ class FXMap < Map
1002
935
  selection.selected = true
1003
936
  end
1004
937
  end
1005
- draw(event)
938
+ draw(sender, sel, event)
1006
939
  end
1007
940
 
1008
941
 
@@ -1071,6 +1004,19 @@ class FXMap < Map
1071
1004
 
1072
1005
 
1073
1006
  def _make_cursors
1007
+ pix = []
1008
+ 32.times { 32.times { pix << 255 << 255 << 255 << 255 } }
1009
+ pix = pix.pack('c*')
1010
+ ['n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'].each { |d|
1011
+ eval(<<-"EOF")
1012
+ @@cursor_#{d} = FXGIFCursor.new(@window.getApp, pix)
1013
+ FXFileStream.open('icons/room_#{d}.gif', FXStreamLoad) { |stream|
1014
+ @@cursor_#{d}.loadPixels(stream)
1015
+ }
1016
+ @@cursor_#{d}.create
1017
+ EOF
1018
+ }
1019
+
1074
1020
  @@cursor_move = FXCursor.new(@window.getApp, CURSOR_MOVE)
1075
1021
  @@cursor_move.create
1076
1022
 
@@ -1079,12 +1025,6 @@ class FXMap < Map
1079
1025
 
1080
1026
  @@cursor_cross = FXCursor.new(@window.getApp, CURSOR_CROSS)
1081
1027
  @@cursor_cross.create
1082
-
1083
- @@cursor_updown = FXCursor.new(@window.getApp, CURSOR_UPDOWN)
1084
- @@cursor_updown.create
1085
-
1086
- @@cursor_leftright = FXCursor.new(@window.getApp, CURSOR_LEFTRIGHT)
1087
- @@cursor_leftright.create
1088
1028
  end
1089
1029
 
1090
1030
  def _make_widgets
@@ -1107,10 +1047,8 @@ class FXMap < Map
1107
1047
  LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT|
1108
1048
  LAYOUT_TOP|LAYOUT_LEFT,
1109
1049
  0, 0, width, height)
1110
-
1111
- @canvas.connect(SEL_PAINT) do |sender, sel, event|
1112
- draw(event)
1113
- end
1050
+ @dirty = true
1051
+ @canvas.connect(SEL_PAINT, method(:draw))
1114
1052
  @canvas.backColor = @options['BG Color']
1115
1053
 
1116
1054
  @canvas.connect(SEL_MOUSEWHEEL, method(:mousewheel_cb))
@@ -1134,7 +1072,7 @@ class FXMap < Map
1134
1072
  _make_widgets
1135
1073
  end
1136
1074
  empty_pathmap
1137
- self.zoom = 1
1075
+ self.zoom = 0.8
1138
1076
  end
1139
1077
 
1140
1078
 
@@ -1142,15 +1080,15 @@ class FXMap < Map
1142
1080
  # Handle deleting selected rooms and/or connections
1143
1081
  #
1144
1082
  def delete_selected
1145
- rooms = @pages[@page].rooms.find_all { |r| r.selected }
1146
- conns = @pages[@page].connections.find_all { |c| c.selected }
1083
+ rooms = @sections[@section].rooms.find_all { |r| r.selected }
1084
+ conns = @sections[@section].connections.find_all { |c| c.selected }
1147
1085
  ############################
1148
1086
  # First, handle rooms...
1149
1087
  ############################
1150
1088
  # Remove rooms from path map
1151
1089
  rooms.each { |r| @pmap[r.x][r.y] = nil }
1152
- # Remove rooms from current page in map
1153
- @pages[@page].rooms -= rooms
1090
+ # Remove rooms from current section in map
1091
+ @sections[@section].rooms -= rooms
1154
1092
  # Add any connections pointing to removed rooms as connection to remove
1155
1093
  rooms.each { |r|
1156
1094
  conns += r.exits.find_all { |e| e != nil }
@@ -1163,8 +1101,8 @@ class FXMap < Map
1163
1101
 
1164
1102
  # Remove connections from path map
1165
1103
  conns.each { |c| clean_path(c) }
1166
- # Remove connections from current page in map
1167
- @pages[@page].connections -= conns
1104
+ # Remove connections from current section in map
1105
+ @sections[@section].connections -= conns
1168
1106
  # Remove room exits pointing to any removed connection
1169
1107
  conns.each { |c|
1170
1108
  a = c.roomA
@@ -1225,24 +1163,15 @@ class FXMap < Map
1225
1163
  # Find and update all paths in path map for a room
1226
1164
  #
1227
1165
  def update_exits(selection)
1228
- # We have to path_find all connections in the same order
1229
- # as they are stored in map, and not in how they are in the room
1230
- # so that there is consistency in path finding
1231
- # conns = []
1232
- # selection.each { |room|
1233
- # room.exits.each { |c|
1234
- # conns << c
1235
- # }
1236
- # }
1237
-
1238
- # @pages[@page].connections.each { |c|
1239
- # next if not conns.include?(c)
1240
- # path_find(c)
1241
- # }
1242
1166
  create_pathmap
1243
1167
  @modified = true
1244
1168
  end
1245
1169
 
1170
+ def navigation_warning
1171
+ w = FXWarningBox.new(@window, "Map is in Read Only Mode. Go to Map Information to change this.")
1172
+ w.execute
1173
+ end
1174
+
1246
1175
  #
1247
1176
  # Handle a keypress
1248
1177
  #
@@ -1251,14 +1180,14 @@ class FXMap < Map
1251
1180
  when KEY_Escape
1252
1181
  if @complexConnection
1253
1182
  if @complexConnection.kind_of?(Array)
1254
- @pages[@page].delete_connection_at(-1)
1183
+ @sections[@section].delete_connection_at(-1)
1255
1184
  status "Complex connection aborted."
1256
1185
  draw
1257
1186
  end
1258
1187
  @complexConnection = false
1259
1188
  end
1260
1189
  when KEY_BackSpace, KEY_Delete
1261
- return if @navigation
1190
+ return navigation_warning if @navigation
1262
1191
  delete_selected
1263
1192
  when KEY_c
1264
1193
  if event.state & CONTROLMASK != 0
@@ -1272,7 +1201,7 @@ class FXMap < Map
1272
1201
  draw
1273
1202
  end
1274
1203
  when KEY_x
1275
- return if @navigation
1204
+ return navigation_warning if @navigation
1276
1205
  if event.state & CONTROLMASK != 0
1277
1206
  FXMapperWindow::cut_selected(self)
1278
1207
  @modified = true
@@ -1281,14 +1210,13 @@ class FXMap < Map
1281
1210
  complex_connection
1282
1211
  end
1283
1212
  when KEY_Up
1284
- return if @navigation
1285
- selection = @pages[@page].rooms.find_all { |r| r.selected }
1213
+ return navigation_warning if @navigation
1214
+ selection = @sections[@section].rooms.find_all { |r| r.selected }
1286
1215
  return if selection.empty?
1287
1216
  clean_room_selection(selection)
1288
1217
  # Check that all nodes can be moved up
1289
1218
  selection.each { |r|
1290
- n = @pmap[r.x][r.y-1]
1291
- if r.y == 0 or n.kind_of?(Room)
1219
+ if r.y == 0 or @pmap[r.x][r.y-1].kind_of?(Room)
1292
1220
  store_room_selection(selection)
1293
1221
  status "Cannot move selection up."
1294
1222
  return
@@ -1301,14 +1229,13 @@ class FXMap < Map
1301
1229
  update_exits(selection)
1302
1230
  draw
1303
1231
  when KEY_Down
1304
- return if @navigation
1305
- selection = @pages[@page].rooms.find_all { |r| r.selected }
1232
+ return navigation_warning if @navigation
1233
+ selection = @sections[@section].rooms.find_all { |r| r.selected }
1306
1234
  return if selection.empty?
1307
1235
  clean_room_selection(selection)
1308
1236
  # Check that all nodes can be moved up
1309
1237
  selection.each { |r|
1310
- n = @pmap[r.x][r.y+1]
1311
- if r.y+1 == @height or n.kind_of?(Room)
1238
+ if r.y+1 == @height or @pmap[r.x][r.y+1].kind_of?(Room)
1312
1239
  store_room_selection(selection)
1313
1240
  status "Cannot move selection down."
1314
1241
  return
@@ -1321,14 +1248,13 @@ class FXMap < Map
1321
1248
  update_exits(selection)
1322
1249
  draw
1323
1250
  when KEY_Left
1324
- return if @navigation
1325
- selection = @pages[@page].rooms.find_all { |r| r.selected }
1251
+ return navigation_warning if @navigation
1252
+ selection = @sections[@section].rooms.find_all { |r| r.selected }
1326
1253
  return if selection.empty?
1327
1254
  # Check that all nodes can be moved up
1328
1255
  clean_room_selection(selection)
1329
1256
  selection.each { |r|
1330
- n = @pmap[r.x-1][r.y]
1331
- if r.x == 0 or n.kind_of?(Room)
1257
+ if r.x == 0 or @pmap[r.x-1][r.y].kind_of?(Room)
1332
1258
  store_room_selection(selection)
1333
1259
  status "Cannot move selection left."
1334
1260
  return
@@ -1341,14 +1267,13 @@ class FXMap < Map
1341
1267
  update_exits(selection)
1342
1268
  draw
1343
1269
  when KEY_Right
1344
- return if @navigation
1345
- selection = @pages[@page].rooms.find_all { |r| r.selected }
1270
+ return navigation_warning if @navigation
1271
+ selection = @sections[@section].rooms.find_all { |r| r.selected }
1346
1272
  return if selection.empty?
1347
1273
  # Check that all nodes can be moved up
1348
1274
  clean_room_selection(selection)
1349
1275
  selection.each { |r|
1350
- n = @pmap[r.x+1][r.y]
1351
- if r.x+1 == @width or n.kind_of?(Room)
1276
+ if r.x+1 == @width or @pmap[r.x+1][r.y].kind_of?(Room)
1352
1277
  store_room_selection(selection)
1353
1278
  status "Cannot move selection right."
1354
1279
  return
@@ -1486,7 +1411,7 @@ class FXMap < Map
1486
1411
  # Clean background to solid color
1487
1412
  #
1488
1413
  def draw_background(dc, event = nil)
1489
- dc.foreground = @canvas.backColor
1414
+ dc.foreground = @options['BG Color']
1490
1415
 
1491
1416
  if event
1492
1417
  dc.fillRectangle(event.rect.x, event.rect.y, event.rect.w, event.rect.h)
@@ -1502,7 +1427,7 @@ class FXMap < Map
1502
1427
  dc.lineStyle = LINE_SOLID
1503
1428
  dc.lineWidth = 3 * @zoom
1504
1429
  dc.lineWidth = 3 if dc.lineWidth < 3
1505
- @pages[@page].connections.each { |c| c.draw(dc, @zoom, @options) }
1430
+ @sections[@section].connections.each { |c| c.draw(dc, @zoom, @options) }
1506
1431
  end
1507
1432
 
1508
1433
  #
@@ -1512,7 +1437,7 @@ class FXMap < Map
1512
1437
  data = { }
1513
1438
  data['font'] = @font
1514
1439
  data['objfont'] = @objfont
1515
- @pages[@page].rooms.each_with_index { |room, idx|
1440
+ @sections[@section].rooms.each_with_index { |room, idx|
1516
1441
  room.draw(dc, @zoom, idx, @options, data)
1517
1442
  }
1518
1443
  end
@@ -1526,7 +1451,7 @@ class FXMap < Map
1526
1451
  #
1527
1452
  # Draw map
1528
1453
  #
1529
- def draw(event = nil)
1454
+ def draw(sender = nil, sel = nil, event = nil)
1530
1455
  pos = @scrollwindow.position
1531
1456
  w = @scrollwindow.getViewportWidth
1532
1457
  h = @scrollwindow.getViewportHeight
@@ -1561,7 +1486,7 @@ class FXMap < Map
1561
1486
  def _save
1562
1487
  if @complexConnection
1563
1488
  # If we have an incomplete connection, remove it
1564
- @pages[@page].delete_connection_at(-1)
1489
+ @sections[@section].delete_connection_at(-1)
1565
1490
  end
1566
1491
 
1567
1492
  if @filename !~ /\.map$/i