ifmapper 0.5 → 0.6

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.
@@ -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