ifmapper 0.7 → 0.8
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 +31 -0
- data/IFMapper.gemspec +3 -3
- data/{IFMapper.rb → IFMapper.rbw} +0 -0
- data/TODO.txt +7 -0
- data/lib/IFMapper/Connection.rb +5 -0
- data/lib/IFMapper/FXMap.rb +283 -128
- data/lib/IFMapper/FXMapperWindow.rb +31 -32
- data/lib/IFMapper/IFMReader.rb +5 -44
- data/lib/IFMapper/Map.rb +57 -0
- data/lib/IFMapper/PDFMapExporter.rb +70 -28
- data/lib/IFMapper/Room.rb +3 -0
- data/lib/IFMapper/Section.rb +30 -0
- data/lib/IFMapper/TranscriptReader.rb +748 -0
- metadata +13 -10
data/HISTORY.txt
CHANGED
@@ -1,4 +1,35 @@
|
|
1
1
|
|
2
|
+
v0.8 - Added the ability to create linked rooms using the Numeric Keypad.
|
3
|
+
Turn on NUM LOCK, select a single room and then use the numbers in
|
4
|
+
the keypad to move thru an exit or add a room in a certain direction.
|
5
|
+
|
6
|
+
Changed name of the main program from IFMapper.rb to IFMapper.rbw.
|
7
|
+
This helps on windows in not bringing up a dummy console window.
|
8
|
+
|
9
|
+
Added Home/End/PageUp/PageDown to move nodes diagonally. This
|
10
|
+
helps with the Keypad, when not in NUM LOCK mode.
|
11
|
+
|
12
|
+
Fixed a bug that effected IFMReader that I inadvertedly
|
13
|
+
introduced in v0.7.
|
14
|
+
|
15
|
+
Removed Postscript support. I just realized that GSview also reads
|
16
|
+
PDFs making Postscript really not needed.
|
17
|
+
|
18
|
+
Added splitting of huge sections into multiple pages when spitting
|
19
|
+
PDFs.
|
20
|
+
|
21
|
+
Fixed a bug that would result in a stack trace when loading an IFM
|
22
|
+
file that was pretty big onto an a very tiny empty map.
|
23
|
+
|
24
|
+
Added the ability to Automap a game from transcripts. Go to
|
25
|
+
your game, type 'script' and the filename to save your transcript to.
|
26
|
+
Then, go to IFMapper and go to Map->Automap->Start. Give it that
|
27
|
+
filename. Voila. IFMapper will start automapping the game.
|
28
|
+
Leave the transcript on and, as you play the game, IFMapper behind
|
29
|
+
the scenes will keep automapping.
|
30
|
+
|
31
|
+
# Added tooltip when zoomed out.
|
32
|
+
|
2
33
|
v0.7 - Fix the issue of users trying to fire up the application from another
|
3
34
|
directory, without cd'ing themselves to the IFMapper directory.
|
4
35
|
|
data/IFMapper.gemspec
CHANGED
@@ -2,19 +2,19 @@ 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.8'
|
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/'
|
9
9
|
spec.summary = 'Interactive Fiction Mapping Tool.'
|
10
10
|
spec.require_path = "lib"
|
11
|
-
spec.files = ['IFMapper.
|
11
|
+
spec.files = ['IFMapper.rbw'] + Dir.glob("lib/IFMapper/*.rb") + Dir.glob("maps/*.ifm") + Dir.glob("icons/*")
|
12
12
|
spec.description = <<-EOF
|
13
13
|
Interactive Fiction Mapping Tool.
|
14
14
|
EOF
|
15
15
|
spec.add_dependency("fxruby", ">= 1.2.6")
|
16
16
|
spec.add_dependency("pdf-writer", ">= 1.1.1")
|
17
|
-
spec.extra_rdoc_files = ["HISTORY.txt", "IFMapper.gemspec"]
|
17
|
+
spec.extra_rdoc_files = ["HISTORY.txt", "TODO.txt", "IFMapper.gemspec"]
|
18
18
|
spec.has_rdoc = true
|
19
19
|
spec.rubyforge_project = 'ifmapper'
|
20
20
|
spec.required_ruby_version = '>= 1.6.8'
|
File without changes
|
data/TODO.txt
ADDED
data/lib/IFMapper/Connection.rb
CHANGED
data/lib/IFMapper/FXMap.rb
CHANGED
@@ -29,7 +29,8 @@ class FXMap < Map
|
|
29
29
|
attr :pmap
|
30
30
|
|
31
31
|
@@win = nil
|
32
|
-
|
32
|
+
|
33
|
+
@@tooltip = nil
|
33
34
|
@@cursor_arrow = nil
|
34
35
|
@@cursor_cross = nil
|
35
36
|
@@cursor_n = nil
|
@@ -41,11 +42,23 @@ class FXMap < Map
|
|
41
42
|
@@cursor_w = nil
|
42
43
|
@@cursor_nw = nil
|
43
44
|
|
44
|
-
|
45
|
+
#
|
46
|
+
# Map has changed dramatically. Update pathmap, title and redraw
|
47
|
+
#
|
45
48
|
def _changed
|
46
49
|
create_pathmap
|
47
|
-
|
48
|
-
|
50
|
+
if @window and @window.shown?
|
51
|
+
update_title
|
52
|
+
draw
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# Fit all rooms in map, adjusting map size if needed
|
58
|
+
#
|
59
|
+
def fit
|
60
|
+
super
|
61
|
+
create_pathmap
|
49
62
|
end
|
50
63
|
|
51
64
|
#
|
@@ -54,10 +67,7 @@ class FXMap < Map
|
|
54
67
|
def section=(x)
|
55
68
|
super
|
56
69
|
@complexConnection = false
|
57
|
-
|
58
|
-
create_pathmap
|
59
|
-
update_title
|
60
|
-
end
|
70
|
+
_changed
|
61
71
|
end
|
62
72
|
|
63
73
|
#
|
@@ -195,7 +205,7 @@ class FXMap < Map
|
|
195
205
|
#
|
196
206
|
def create_pathmap
|
197
207
|
# First, create an empty grid of width x height
|
198
|
-
empty_pathmap
|
208
|
+
empty_pathmap
|
199
209
|
# Then, fill it in with all rooms...
|
200
210
|
@sections[@section].rooms.each { |r| @pmap[r.x][r.y] = r }
|
201
211
|
# And following, add all paths
|
@@ -356,6 +366,18 @@ class FXMap < Map
|
|
356
366
|
def new_room(x, y)
|
357
367
|
@modified = true
|
358
368
|
r = @sections[@section].new_room(x, y)
|
369
|
+
@automap.add(r) if @automap
|
370
|
+
return r
|
371
|
+
end
|
372
|
+
|
373
|
+
#
|
374
|
+
# Function used to add a new room. x and y are absolute pixel positions
|
375
|
+
# in canvas.
|
376
|
+
#
|
377
|
+
def new_xy_room(x, y)
|
378
|
+
x = x / WW
|
379
|
+
y = y / HH
|
380
|
+
r = new_room(x, y)
|
359
381
|
@pmap[x][y] = r
|
360
382
|
|
361
383
|
r.selected = true
|
@@ -370,16 +392,6 @@ class FXMap < Map
|
|
370
392
|
return r
|
371
393
|
end
|
372
394
|
|
373
|
-
#
|
374
|
-
# Function used to add a new room. x and y are absolute pixel positions
|
375
|
-
# in canvas.
|
376
|
-
#
|
377
|
-
def new_xy_room(x, y)
|
378
|
-
x = x / WW
|
379
|
-
y = y / HH
|
380
|
-
return new_room(x, y)
|
381
|
-
end
|
382
|
-
|
383
395
|
|
384
396
|
# Given a canvas (mouse) x/y position, return:
|
385
397
|
#
|
@@ -480,10 +492,16 @@ class FXMap < Map
|
|
480
492
|
return nil
|
481
493
|
end
|
482
494
|
|
495
|
+
#
|
496
|
+
# Update the map window's title
|
497
|
+
#
|
483
498
|
def update_title
|
484
499
|
title = @name.dup
|
485
500
|
if @navigation
|
486
|
-
title <<
|
501
|
+
title << ' [Read Only]'
|
502
|
+
end
|
503
|
+
if @automap
|
504
|
+
title << ' [Automap]'
|
487
505
|
end
|
488
506
|
title << " Zoom: %.3f" % @zoom
|
489
507
|
title << " Section #{@section+1} of #{@sections.size}"
|
@@ -673,13 +691,8 @@ class FXMap < Map
|
|
673
691
|
return unless a # User click outside map
|
674
692
|
|
675
693
|
if @options['Create on Connection']
|
676
|
-
unless roomA
|
677
|
-
|
678
|
-
end
|
679
|
-
|
680
|
-
unless roomB
|
681
|
-
roomB = new_xy_room( b[0], b[1] )
|
682
|
-
end
|
694
|
+
roomA = new_xy_room( a[0], a[1] ) unless roomA
|
695
|
+
roomB = new_xy_room( b[0], b[1] ) unless roomB
|
683
696
|
end
|
684
697
|
|
685
698
|
return nil unless roomA and roomB
|
@@ -701,8 +714,10 @@ class FXMap < Map
|
|
701
714
|
delete_connection(c) if c.roomB == nil
|
702
715
|
end
|
703
716
|
end
|
704
|
-
|
705
|
-
|
717
|
+
begin
|
718
|
+
new_connection( roomA, exitA, roomB )
|
719
|
+
rescue Section::ConnectionError
|
720
|
+
end
|
706
721
|
end
|
707
722
|
|
708
723
|
#
|
@@ -768,6 +783,15 @@ class FXMap < Map
|
|
768
783
|
end
|
769
784
|
end
|
770
785
|
|
786
|
+
#
|
787
|
+
# Based on mouse position on canvas, create a tooltip
|
788
|
+
#
|
789
|
+
def update_cb(sender, sel, event)
|
790
|
+
if sel == FXWindow::ID_QUERY_TIP
|
791
|
+
p "tooltip"
|
792
|
+
end
|
793
|
+
end
|
794
|
+
|
771
795
|
#
|
772
796
|
# Show some help status in status line based on cursor position
|
773
797
|
#
|
@@ -804,18 +828,12 @@ class FXMap < Map
|
|
804
828
|
# to cursor position
|
805
829
|
#
|
806
830
|
def mousewheel_cb(sender, sel, event)
|
807
|
-
# x = event.last_x / @zoom
|
808
|
-
# y = event.last_y / @zoom
|
809
831
|
case event.code
|
810
|
-
when -120
|
832
|
+
when -120 # Hmm, there does not seem to be constants for these
|
811
833
|
zoom_out
|
812
|
-
when 120
|
834
|
+
when 120 # Hmm, there does not seem to be constants for these
|
813
835
|
zoom_in
|
814
836
|
end
|
815
|
-
# x *= @zoom
|
816
|
-
# y *= @zoom
|
817
|
-
# center_view_on_xy(x.to_i, y.to_i)
|
818
|
-
# draw
|
819
837
|
end
|
820
838
|
|
821
839
|
#
|
@@ -828,8 +846,7 @@ class FXMap < Map
|
|
828
846
|
end
|
829
847
|
|
830
848
|
#
|
831
|
-
# Select all rooms within (drag) rectangle
|
832
|
-
# TODO: Should add connections too
|
849
|
+
# Select all rooms and connections within (drag) rectangle
|
833
850
|
#
|
834
851
|
def select_rectangle(x1, y1, x2, y2)
|
835
852
|
x1, x2 = x2, x1 if x2 < x1
|
@@ -1013,6 +1030,7 @@ class FXMap < Map
|
|
1013
1030
|
rmb_link_menu( submenu, c, a, idx, old_idx )
|
1014
1031
|
}
|
1015
1032
|
FXMenuCascade.new(menu, a.name, nil, submenu)
|
1033
|
+
next if not b
|
1016
1034
|
submenu = FXMenuPane.new(@window)
|
1017
1035
|
old_idx = b.exits.rindex(c)
|
1018
1036
|
0.upto(7) { |idx|
|
@@ -1119,7 +1137,10 @@ class FXMap < Map
|
|
1119
1137
|
draw(sender, sel, event)
|
1120
1138
|
end
|
1121
1139
|
|
1122
|
-
|
1140
|
+
#
|
1141
|
+
# Close the map. Pop up a warning box to allow saving
|
1142
|
+
# if map has been modified.
|
1143
|
+
#
|
1123
1144
|
def close_cb()
|
1124
1145
|
if @modified
|
1125
1146
|
dlg = FXDialogBox.new( @window.parent, "Warning",
|
@@ -1169,21 +1190,28 @@ class FXMap < Map
|
|
1169
1190
|
end
|
1170
1191
|
}
|
1171
1192
|
FXButton.new(buttons, "&No", nil, dlg, FXDialogBox::ID_ACCEPT,
|
1172
|
-
FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|
|
1193
|
+
FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|
|
1194
|
+
LAYOUT_RIGHT|LAYOUT_CENTER_Y)
|
1173
1195
|
|
1174
1196
|
# Cancel
|
1175
1197
|
FXButton.new(buttons, "&Cancel", nil, dlg, FXDialogBox::ID_CANCEL,
|
1176
|
-
FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|
|
1198
|
+
FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|
|
1199
|
+
LAYOUT_RIGHT|LAYOUT_CENTER_Y)
|
1177
1200
|
yes.setDefault
|
1178
1201
|
yes.setFocus
|
1179
1202
|
|
1180
1203
|
return false if dlg.execute == 0
|
1181
1204
|
end
|
1205
|
+
@automap.destroy if @automap
|
1206
|
+
@automap = nil
|
1182
1207
|
@window.close
|
1208
|
+
GC.start
|
1183
1209
|
return true
|
1184
1210
|
end
|
1185
1211
|
|
1186
|
-
|
1212
|
+
#
|
1213
|
+
# Create cursors
|
1214
|
+
#
|
1187
1215
|
def _make_cursors
|
1188
1216
|
pix = []
|
1189
1217
|
32.times { 32.times { pix << 255 << 255 << 255 << 255 } }
|
@@ -1208,6 +1236,9 @@ class FXMap < Map
|
|
1208
1236
|
@@cursor_cross.create
|
1209
1237
|
end
|
1210
1238
|
|
1239
|
+
#
|
1240
|
+
# Create widgets for this map window
|
1241
|
+
#
|
1211
1242
|
def _make_widgets
|
1212
1243
|
@scrollwindow = FXScrollWindow.new(@window,
|
1213
1244
|
SCROLLERS_NORMAL|SCROLLERS_TRACK)
|
@@ -1229,6 +1260,9 @@ class FXMap < Map
|
|
1229
1260
|
LAYOUT_TOP|LAYOUT_LEFT,
|
1230
1261
|
0, 0, width, height)
|
1231
1262
|
@dirty = true
|
1263
|
+
@canvas.connect(SEL_UPDATE, method(:update_cb))
|
1264
|
+
# FXMAPFUNC(SEL_UPDATE, FXWindow::ID_QUERY_TIP, 'tooltip_cb')
|
1265
|
+
|
1232
1266
|
@canvas.connect(SEL_PAINT, method(:draw))
|
1233
1267
|
@canvas.backColor = @options['BG Color']
|
1234
1268
|
|
@@ -1240,12 +1274,21 @@ class FXMap < Map
|
|
1240
1274
|
@canvas.connect(SEL_MIDDLEBUTTONRELEASE, method(:mmb_release_cb))
|
1241
1275
|
@canvas.connect(SEL_RIGHTBUTTONPRESS, method(:rmb_click_cb))
|
1242
1276
|
@canvas.connect(SEL_KEYPRESS, method(:keypress_cb))
|
1277
|
+
|
1278
|
+
if not @@tooltip
|
1279
|
+
@@tooltip = FXToolTip.new(@canvas.app, FXToolTip::TOOLTIP_PERMANENT)
|
1280
|
+
end
|
1243
1281
|
end
|
1244
|
-
|
1282
|
+
|
1283
|
+
#
|
1284
|
+
# Main constructor. Create the object, initialize the pathmap
|
1285
|
+
# and initialize the widgets and cursors if a parent window is passed.
|
1286
|
+
#
|
1245
1287
|
def initialize(name, parent = nil, default_options = nil,
|
1246
1288
|
icon = nil, menu = nil, mode = nil,
|
1247
1289
|
x = 0, y = 0, w = 0, h = 0)
|
1248
1290
|
super(name)
|
1291
|
+
@automap = nil
|
1249
1292
|
@navigation = false
|
1250
1293
|
if parent
|
1251
1294
|
@window = FXMDIChild.new(parent, name, icon, menu, mode, x, y, w, h)
|
@@ -1290,14 +1333,18 @@ class FXMap < Map
|
|
1290
1333
|
a = c.roomA
|
1291
1334
|
b = c.roomB
|
1292
1335
|
a[a.exits.index(c)] = nil
|
1293
|
-
|
1294
|
-
|
1336
|
+
if b
|
1337
|
+
idx = b.exits.rindex(c)
|
1338
|
+
b[idx] = nil if idx
|
1339
|
+
end
|
1295
1340
|
}
|
1296
1341
|
|
1297
1342
|
# Recreate pathmap. We need to recreate pathmap for all paths
|
1298
1343
|
# as the removal of one path may help shorten the path of another.
|
1299
1344
|
create_pathmap
|
1300
1345
|
|
1346
|
+
@automap.remove(rooms) if @automap
|
1347
|
+
|
1301
1348
|
draw()
|
1302
1349
|
end
|
1303
1350
|
|
@@ -1349,6 +1396,22 @@ class FXMap < Map
|
|
1349
1396
|
@modified = true
|
1350
1397
|
end
|
1351
1398
|
|
1399
|
+
|
1400
|
+
#
|
1401
|
+
# Return the current active room
|
1402
|
+
#
|
1403
|
+
def current_room
|
1404
|
+
rooms = @sections[@section].rooms.find_all { |r| r.selected }
|
1405
|
+
return nil if rooms.empty? or rooms.size > 1
|
1406
|
+
return rooms[0]
|
1407
|
+
end
|
1408
|
+
|
1409
|
+
def cannot_automap(why)
|
1410
|
+
w = FXWarningBox.new(@window, "Cannot automap.\n#{why}")
|
1411
|
+
w.execute
|
1412
|
+
end
|
1413
|
+
|
1414
|
+
|
1352
1415
|
#
|
1353
1416
|
# Give user some warning if he tries to modify a read-only mode.
|
1354
1417
|
#
|
@@ -1357,6 +1420,78 @@ class FXMap < Map
|
|
1357
1420
|
w.execute
|
1358
1421
|
end
|
1359
1422
|
|
1423
|
+
|
1424
|
+
#
|
1425
|
+
# Move selected rooms in one of the 8 cardinal directions.
|
1426
|
+
#
|
1427
|
+
def move_to(idx)
|
1428
|
+
return navigation_warning if @navigation
|
1429
|
+
selection = @sections[@section].rooms.find_all { |r| r.selected }
|
1430
|
+
return if selection.empty?
|
1431
|
+
clean_room_selection(selection)
|
1432
|
+
|
1433
|
+
|
1434
|
+
dx, dy = Room::DIR_TO_VECTOR[idx]
|
1435
|
+
|
1436
|
+
# Check that all nodes can be moved in the specified direction
|
1437
|
+
selection.each { |r|
|
1438
|
+
x = r.x + dx
|
1439
|
+
y = r.y + dy
|
1440
|
+
if x < 0 or y < 0 or x >= @width or y >= @height or
|
1441
|
+
@pmap[x][y].kind_of?(Room)
|
1442
|
+
store_room_selection(selection)
|
1443
|
+
dir = Room::DIRECTIONS[idx]
|
1444
|
+
status "Cannot move selection #{dir}."
|
1445
|
+
return
|
1446
|
+
end
|
1447
|
+
}
|
1448
|
+
selection.each { |r|
|
1449
|
+
r.x += dx
|
1450
|
+
r.y += dy
|
1451
|
+
}
|
1452
|
+
update_exits(selection)
|
1453
|
+
draw
|
1454
|
+
end
|
1455
|
+
|
1456
|
+
#
|
1457
|
+
# Move through an exit into another room. If exit is empty, create
|
1458
|
+
# a new neighboring room.
|
1459
|
+
#
|
1460
|
+
def move_thru(idx)
|
1461
|
+
room = current_room
|
1462
|
+
return if not room
|
1463
|
+
exit = room[idx]
|
1464
|
+
if exit
|
1465
|
+
room.selected = false
|
1466
|
+
if room == exit.roomA
|
1467
|
+
roomB = exit.roomB
|
1468
|
+
else
|
1469
|
+
roomB = exit.roomA
|
1470
|
+
end
|
1471
|
+
roomB.selected = true
|
1472
|
+
draw
|
1473
|
+
else
|
1474
|
+
return navigation_warning if @navigation
|
1475
|
+
x, y = room.x, room.y
|
1476
|
+
dx, dy = Room::DIR_TO_VECTOR[idx]
|
1477
|
+
x += dx
|
1478
|
+
y += dy
|
1479
|
+
x = 0 if x < 0
|
1480
|
+
y = 0 if y < 0
|
1481
|
+
x = @width-1 if x > @width-1
|
1482
|
+
y = @height-1 if y > @height-1
|
1483
|
+
if not @pmap[x][y].kind_of?(Room)
|
1484
|
+
room.selected = false
|
1485
|
+
roomB = new_xy_room(x * WW, y * HH)
|
1486
|
+
exitB = roomB.next_to?(room)
|
1487
|
+
if exitB and roomB.exits[exitB] == nil
|
1488
|
+
new_connection( roomB, exitB, room )
|
1489
|
+
end
|
1490
|
+
draw
|
1491
|
+
end
|
1492
|
+
end
|
1493
|
+
end
|
1494
|
+
|
1360
1495
|
#
|
1361
1496
|
# Handle a keypress
|
1362
1497
|
#
|
@@ -1394,82 +1529,38 @@ class FXMap < Map
|
|
1394
1529
|
else
|
1395
1530
|
complex_connection
|
1396
1531
|
end
|
1532
|
+
when KEY_KP_8
|
1533
|
+
move_thru(0)
|
1534
|
+
when KEY_KP_9
|
1535
|
+
move_thru(1)
|
1536
|
+
when KEY_KP_6
|
1537
|
+
move_thru(2)
|
1538
|
+
when KEY_KP_3
|
1539
|
+
move_thru(3)
|
1540
|
+
when KEY_KP_2
|
1541
|
+
move_thru(4)
|
1542
|
+
when KEY_KP_1
|
1543
|
+
move_thru(5)
|
1544
|
+
when KEY_KP_4
|
1545
|
+
move_thru(6)
|
1546
|
+
when KEY_KP_7
|
1547
|
+
move_thru(7)
|
1397
1548
|
when KEY_Up
|
1398
|
-
|
1399
|
-
selection = @sections[@section].rooms.find_all { |r| r.selected }
|
1400
|
-
return if selection.empty?
|
1401
|
-
clean_room_selection(selection)
|
1402
|
-
# Check that all nodes can be moved up
|
1403
|
-
selection.each { |r|
|
1404
|
-
if r.y == 0 or @pmap[r.x][r.y-1].kind_of?(Room)
|
1405
|
-
store_room_selection(selection)
|
1406
|
-
status "Cannot move selection up."
|
1407
|
-
return
|
1408
|
-
end
|
1409
|
-
}
|
1410
|
-
selection.each { |r|
|
1411
|
-
r.y -= 1
|
1412
|
-
@pmap[r.x][r.y] = r
|
1413
|
-
}
|
1414
|
-
update_exits(selection)
|
1415
|
-
draw
|
1549
|
+
move_to(0)
|
1416
1550
|
when KEY_Down
|
1417
|
-
|
1418
|
-
selection = @sections[@section].rooms.find_all { |r| r.selected }
|
1419
|
-
return if selection.empty?
|
1420
|
-
clean_room_selection(selection)
|
1421
|
-
# Check that all nodes can be moved up
|
1422
|
-
selection.each { |r|
|
1423
|
-
if r.y+1 == @height or @pmap[r.x][r.y+1].kind_of?(Room)
|
1424
|
-
store_room_selection(selection)
|
1425
|
-
status "Cannot move selection down."
|
1426
|
-
return
|
1427
|
-
end
|
1428
|
-
}
|
1429
|
-
selection.each { |r|
|
1430
|
-
r.y += 1
|
1431
|
-
@pmap[r.x][r.y] = r
|
1432
|
-
}
|
1433
|
-
update_exits(selection)
|
1434
|
-
draw
|
1551
|
+
move_to(4)
|
1435
1552
|
when KEY_Left
|
1436
|
-
|
1437
|
-
selection = @sections[@section].rooms.find_all { |r| r.selected }
|
1438
|
-
return if selection.empty?
|
1439
|
-
# Check that all nodes can be moved up
|
1440
|
-
clean_room_selection(selection)
|
1441
|
-
selection.each { |r|
|
1442
|
-
if r.x == 0 or @pmap[r.x-1][r.y].kind_of?(Room)
|
1443
|
-
store_room_selection(selection)
|
1444
|
-
status "Cannot move selection left."
|
1445
|
-
return
|
1446
|
-
end
|
1447
|
-
}
|
1448
|
-
selection.each { |r|
|
1449
|
-
r.x -= 1
|
1450
|
-
@pmap[r.x][r.y] = r
|
1451
|
-
}
|
1452
|
-
update_exits(selection)
|
1453
|
-
draw
|
1553
|
+
move_to(6)
|
1454
1554
|
when KEY_Right
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
return
|
1465
|
-
end
|
1466
|
-
}
|
1467
|
-
selection.each { |r|
|
1468
|
-
r.x += 1
|
1469
|
-
@pmap[r.x][r.y] = r
|
1470
|
-
}
|
1471
|
-
update_exits(selection)
|
1472
|
-
draw
|
1555
|
+
move_to(2)
|
1556
|
+
when KEY_End
|
1557
|
+
move_to(5)
|
1558
|
+
when KEY_Home
|
1559
|
+
move_to(7)
|
1560
|
+
when KEY_Page_Up
|
1561
|
+
move_to(1)
|
1562
|
+
when KEY_Page_Down
|
1563
|
+
move_to(3)
|
1473
1564
|
end
|
1474
1565
|
end
|
1475
1566
|
|
@@ -1567,7 +1658,7 @@ class FXMap < Map
|
|
1567
1658
|
#
|
1568
1659
|
# Draw template of room squares in background
|
1569
1660
|
#
|
1570
|
-
def draw_grid(dc, event)
|
1661
|
+
def draw_grid(dc, event = nil)
|
1571
1662
|
|
1572
1663
|
dc.foreground = "black"
|
1573
1664
|
dc.lineWidth = 0
|
@@ -1627,36 +1718,63 @@ class FXMap < Map
|
|
1627
1718
|
}
|
1628
1719
|
end
|
1629
1720
|
|
1721
|
+
#
|
1722
|
+
# Draw mapname
|
1723
|
+
#
|
1724
|
+
def draw_mapname(dc)
|
1725
|
+
fontsize = (24 * @zoom).to_i
|
1726
|
+
font = FXFont.new(@window.getApp, @options['Font Text'], fontsize)
|
1727
|
+
font.create
|
1728
|
+
|
1729
|
+
x = @width * WW / 2.0 - @name.size * 24
|
1730
|
+
dc.drawText(x, 30, @name)
|
1731
|
+
end
|
1732
|
+
|
1630
1733
|
#
|
1631
1734
|
# Print map
|
1632
1735
|
#
|
1633
1736
|
def print(printer)
|
1634
1737
|
# dc = FXDCPrint.new(@window.getApp)
|
1738
|
+
require 'IFMapper/MapPrinting'
|
1635
1739
|
require 'IFMapper/FXDCPostscript'
|
1636
1740
|
oldzoom = @zoom
|
1637
1741
|
oldsection = @section
|
1742
|
+
self.zoom = 1.0
|
1743
|
+
|
1744
|
+
num = pack_sections( @width, @height )
|
1745
|
+
puts "Would pack #{@sections.size} into #{num} pages."
|
1638
1746
|
begin
|
1639
1747
|
dc = FXDCPostscript.new(@window.getApp)
|
1640
1748
|
xmax = @width * WW
|
1641
1749
|
ymax = @height * HH
|
1642
|
-
@zoom = 1.0
|
1643
1750
|
dc.setContentRange(0, 0, xmax, ymax)
|
1644
1751
|
dc.beginPrint(printer) {
|
1752
|
+
page = -1
|
1645
1753
|
0.upto(@sections.size-1) { |p|
|
1646
1754
|
self.section = p
|
1647
1755
|
clear_selection
|
1648
|
-
|
1649
|
-
dc.
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1756
|
+
if page != sect.page
|
1757
|
+
dc.beginPage(sect.page)
|
1758
|
+
draw_mapname( dc )
|
1759
|
+
end
|
1760
|
+
|
1761
|
+
dc.lineCap = CAP_ROUND
|
1762
|
+
# draw_grid(dc)
|
1763
|
+
draw_connections(dc)
|
1764
|
+
draw_rooms(dc)
|
1765
|
+
|
1766
|
+
if page != sect.page
|
1767
|
+
page = sect.page
|
1768
|
+
dc.endPage()
|
1769
|
+
end
|
1653
1770
|
}
|
1654
1771
|
}
|
1655
1772
|
rescue => e
|
1656
1773
|
status "#{e}"
|
1657
1774
|
end
|
1658
1775
|
self.section = oldsection
|
1659
|
-
|
1776
|
+
self.zoom = oldzoom
|
1777
|
+
draw
|
1660
1778
|
end
|
1661
1779
|
|
1662
1780
|
#
|
@@ -1693,7 +1811,9 @@ class FXMap < Map
|
|
1693
1811
|
end
|
1694
1812
|
|
1695
1813
|
|
1696
|
-
|
1814
|
+
#
|
1815
|
+
# Perform the actual saving of the map
|
1816
|
+
#
|
1697
1817
|
def _save
|
1698
1818
|
if @complexConnection
|
1699
1819
|
# If we have an incomplete connection, remove it
|
@@ -1721,6 +1841,9 @@ class FXMap < Map
|
|
1721
1841
|
return true
|
1722
1842
|
end
|
1723
1843
|
|
1844
|
+
#
|
1845
|
+
# Save the map. If the map's filename is not defined, call save_as
|
1846
|
+
#
|
1724
1847
|
def save
|
1725
1848
|
unless @filename
|
1726
1849
|
save_as
|
@@ -1729,6 +1852,9 @@ class FXMap < Map
|
|
1729
1852
|
end
|
1730
1853
|
end
|
1731
1854
|
|
1855
|
+
#
|
1856
|
+
# Save the map under a new filename, bringing up a filerequester
|
1857
|
+
#
|
1732
1858
|
def save_as
|
1733
1859
|
file = FXMapFileDialog.new(@window, "Save Map #{@name}").filename
|
1734
1860
|
if file != ''
|
@@ -1738,7 +1864,9 @@ class FXMap < Map
|
|
1738
1864
|
return false
|
1739
1865
|
end
|
1740
1866
|
|
1741
|
-
|
1867
|
+
#
|
1868
|
+
# Open the map's property window
|
1869
|
+
#
|
1742
1870
|
def properties
|
1743
1871
|
if not @@win
|
1744
1872
|
@@win = FXMapDialogBox.new(@window)
|
@@ -1747,4 +1875,31 @@ class FXMap < Map
|
|
1747
1875
|
@@win.show
|
1748
1876
|
end
|
1749
1877
|
|
1878
|
+
def stop_automap
|
1879
|
+
return unless @automap
|
1880
|
+
@automap.destroy
|
1881
|
+
@automap = nil
|
1882
|
+
GC.start
|
1883
|
+
update_title
|
1884
|
+
end
|
1885
|
+
|
1886
|
+
def start_automap
|
1887
|
+
if @automap
|
1888
|
+
stop_automap
|
1889
|
+
end
|
1890
|
+
|
1891
|
+
file = FXMapFileDialog.new(@window, "Load Transcript",
|
1892
|
+
[
|
1893
|
+
"Transcript File (*.log)",
|
1894
|
+
"All Files (*)"
|
1895
|
+
]).filename
|
1896
|
+
return if file == ''
|
1897
|
+
require 'IFMapper/TranscriptReader'
|
1898
|
+
@automap = TranscriptReader.new(self, file)
|
1899
|
+
@automap.start
|
1900
|
+
create_pathmap
|
1901
|
+
draw
|
1902
|
+
update_title
|
1903
|
+
end
|
1904
|
+
|
1750
1905
|
end
|