ifmapper 0.9 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.txt +132 -5
- data/IFMapper.gemspec +2 -2
- data/TODO.txt +0 -5
- data/lib/IFMapper/AStar.rb +15 -8
- data/lib/IFMapper/Connection.rb +137 -25
- data/lib/IFMapper/FXConnection.rb +54 -40
- data/lib/IFMapper/FXConnectionDialogBox.rb +12 -4
- data/lib/IFMapper/FXMap.rb +161 -60
- data/lib/IFMapper/FXMapperWindow.rb +205 -70
- data/lib/IFMapper/FXRoom.rb +7 -2
- data/lib/IFMapper/FXRoomDialogBox.rb +2 -1
- data/lib/IFMapper/FXRoomList.rb +95 -0
- data/lib/IFMapper/PDFMapExporter.rb +10 -1
- data/lib/IFMapper/Room.rb +22 -0
- data/lib/IFMapper/TranscriptDialogBox.rb +117 -0
- data/lib/IFMapper/TranscriptReader.rb +320 -96
- data/maps/AllRoads.map +0 -0
- data/maps/Bureaucracy.map +0 -0
- data/maps/CityOfSecrets.map +0 -0
- data/maps/DDIV.map +0 -0
- data/maps/Heroine.map +0 -0
- data/maps/SavoirFare.map +0 -0
- data/maps/Tangle.map +0 -0
- data/maps/anchor.map +0 -0
- data/maps/ballerina.map +0 -0
- data/maps/bluechairs.map +0 -0
- data/maps/break_in.map +0 -0
- data/maps/christminster.map +0 -0
- data/maps/deadline.map +0 -0
- data/maps/delusions.map +0 -0
- data/maps/dreamhold.map +0 -0
- data/maps/eas.map +0 -0
- data/maps/eas2.map +0 -0
- data/maps/eas3.map +0 -0
- data/maps/inhumane.map +0 -0
- data/maps/lurkinghorror.map +0 -0
- data/maps/metamorphoses.map +0 -0
- data/maps/moonmist.map +0 -0
- data/maps/muldoon_legacy.map +0 -0
- data/maps/pawn.map +0 -0
- data/maps/pytho.map +0 -0
- data/maps/risorgimento.map +0 -0
- data/maps/sherbet.map +0 -0
- data/maps/slouch.map +0 -0
- data/maps/spring.map +0 -0
- data/maps/trinity.map +0 -0
- data/maps/worlds.map +0 -0
- data/maps/zdungeon.map +0 -0
- metadata +42 -8
data/lib/IFMapper/FXRoom.rb
CHANGED
@@ -11,6 +11,10 @@ class FXRoom < Room
|
|
11
11
|
|
12
12
|
@@win = nil
|
13
13
|
|
14
|
+
def self.no_maps
|
15
|
+
@@win.hide if @@win
|
16
|
+
end
|
17
|
+
|
14
18
|
def marshal_dump
|
15
19
|
super + [ @selected ]
|
16
20
|
end
|
@@ -60,8 +64,8 @@ class FXRoom < Room
|
|
60
64
|
# Open a modal requester to change properties
|
61
65
|
#
|
62
66
|
def modal_properties(map)
|
63
|
-
|
64
|
-
|
67
|
+
if @@win and @@win.shown?
|
68
|
+
shown = @@win
|
65
69
|
@@win.hide
|
66
70
|
end
|
67
71
|
win = FXRoomDialogBox.new(map, self, nil, true)
|
@@ -142,6 +146,7 @@ class FXRoom < Room
|
|
142
146
|
# Main draw function for room
|
143
147
|
#
|
144
148
|
def draw(dc, zoom, idx, opt, data)
|
149
|
+
dc.font = data['objfont']
|
145
150
|
draw_box(dc, zoom, idx, opt)
|
146
151
|
return if zoom < 0.5
|
147
152
|
dc.font = data['font']
|
@@ -16,6 +16,7 @@ class FXRoomDialogBox < FXDialogBox
|
|
16
16
|
@room.desc = @desc.text
|
17
17
|
|
18
18
|
@map.draw_room(@room)
|
19
|
+
@map.update_roomlist
|
19
20
|
end
|
20
21
|
|
21
22
|
|
@@ -142,7 +143,7 @@ class FXRoomDialogBox < FXDialogBox
|
|
142
143
|
else
|
143
144
|
@name.connect(SEL_CHANGED) { copy_to() }
|
144
145
|
@objects.connect(SEL_CHANGED) { copy_to()}
|
145
|
-
@tasks.connect(SEL_CHANGED) {
|
146
|
+
@tasks.connect(SEL_CHANGED) { @room.tasks = @tasks.text }
|
146
147
|
@darkness.connect(SEL_COMMAND) { copy_to() }
|
147
148
|
@desc.connect(SEL_CHANGED) { @room.desc = @desc.text }
|
148
149
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Class that lists all rooms in a map and allows you to jump to them
|
4
|
+
#
|
5
|
+
class FXRoomList < FXDialogBox
|
6
|
+
|
7
|
+
def pick(sender, sel, ptr)
|
8
|
+
item = @box.currentItem
|
9
|
+
idx, r = @box.getItemData(item)
|
10
|
+
|
11
|
+
@map.section = idx
|
12
|
+
@map.clear_selection
|
13
|
+
r.selected = true
|
14
|
+
@map.center_view_on_room(r)
|
15
|
+
@map.draw
|
16
|
+
end
|
17
|
+
|
18
|
+
def copy_from(map)
|
19
|
+
@map = map
|
20
|
+
sort
|
21
|
+
end
|
22
|
+
|
23
|
+
def sort
|
24
|
+
item = @box.currentItem
|
25
|
+
room = nil
|
26
|
+
if item >= 0
|
27
|
+
idx, room = @box.getItemData(item)
|
28
|
+
end
|
29
|
+
|
30
|
+
@box.clearItems
|
31
|
+
|
32
|
+
rooms = []
|
33
|
+
@map.sections.each_with_index { |s, idx|
|
34
|
+
s.rooms.each { |r|
|
35
|
+
rooms << [idx, r]
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
dir = @box.header.getArrowDir(0)
|
40
|
+
if dir != MAYBE
|
41
|
+
rooms = rooms.sort_by { |r| r[0] }
|
42
|
+
else
|
43
|
+
dir = @box.header.getArrowDir(1)
|
44
|
+
if dir != MAYBE
|
45
|
+
rooms = rooms.sort_by { |r| r[1].name }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
if dir == Fox::TRUE
|
50
|
+
rooms.reverse!
|
51
|
+
end
|
52
|
+
|
53
|
+
rooms.each { |r|
|
54
|
+
item = "#{r[0]}\t#{r[1].name}"
|
55
|
+
@box.appendItem(item, nil, nil, r)
|
56
|
+
}
|
57
|
+
|
58
|
+
if room
|
59
|
+
rooms.each_with_index { |r, idx|
|
60
|
+
if r[1] == room
|
61
|
+
@box.currentItem = idx
|
62
|
+
break
|
63
|
+
end
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def initialize(map)
|
69
|
+
super(map.window.parent, "Locations", DECOR_ALL, 40, 40, 300, 400)
|
70
|
+
|
71
|
+
@box = FXIconList.new(self, nil, 0,
|
72
|
+
ICONLIST_BROWSESELECT|
|
73
|
+
LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
74
|
+
@box.appendHeader("Section", nil, 60)
|
75
|
+
@box.appendHeader("Name", nil, 200)
|
76
|
+
@box.header.connect(SEL_COMMAND) { |sender, sel, which|
|
77
|
+
if @box.header.arrowUp?(which)
|
78
|
+
dir = MAYBE
|
79
|
+
elsif @box.header.arrowDown?(which)
|
80
|
+
dir = TRUE
|
81
|
+
else
|
82
|
+
dir = FALSE
|
83
|
+
end
|
84
|
+
@box.header.setArrowDir(which, dir)
|
85
|
+
@box.header.setArrowDir(which ^ 1, MAYBE)
|
86
|
+
sort
|
87
|
+
}
|
88
|
+
|
89
|
+
@box.connect(SEL_COMMAND, method(:pick))
|
90
|
+
|
91
|
+
create
|
92
|
+
copy_from(map)
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -104,7 +104,16 @@ class FXConnection
|
|
104
104
|
|
105
105
|
def pdf_draw_complex( pdf, opts )
|
106
106
|
if opts['Paths as Curves']
|
107
|
-
|
107
|
+
if @room[0] == @room[1]
|
108
|
+
dirA, dirB = dirs
|
109
|
+
if dirA == dirB
|
110
|
+
p = pdf_draw_complex_as_lines( pdf, opts )
|
111
|
+
else
|
112
|
+
p = pdf_draw_complex_as_bspline( pdf, opts )
|
113
|
+
end
|
114
|
+
else
|
115
|
+
p = pdf_draw_complex_as_bspline( pdf, opts )
|
116
|
+
end
|
108
117
|
else
|
109
118
|
p = pdf_draw_complex_as_lines( pdf, opts )
|
110
119
|
end
|
data/lib/IFMapper/Room.rb
CHANGED
@@ -44,6 +44,7 @@ class Room
|
|
44
44
|
if not vars.empty? and vars[0].kind_of?(String)
|
45
45
|
@desc = vars.shift
|
46
46
|
@desc.sub!(/\n/, ' ')
|
47
|
+
@desc.strip!
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
@@ -59,6 +60,27 @@ class Room
|
|
59
60
|
@exits[dir] = connection
|
60
61
|
end
|
61
62
|
|
63
|
+
#
|
64
|
+
# Return the number of doors present in room
|
65
|
+
#
|
66
|
+
def num_doors
|
67
|
+
num = 0
|
68
|
+
@exits.each { |e|
|
69
|
+
next if not e
|
70
|
+
num += 1 if e.door?
|
71
|
+
}
|
72
|
+
return num
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Return the number of exits present in room
|
77
|
+
#
|
78
|
+
def num_exits
|
79
|
+
num = 0
|
80
|
+
@exits.each { |e| num += 1 if e }
|
81
|
+
return num
|
82
|
+
end
|
83
|
+
|
62
84
|
#
|
63
85
|
# Return a direction from the vector of the exit that would take
|
64
86
|
# us to the 'b' room more cleanly.
|
@@ -0,0 +1,117 @@
|
|
1
|
+
|
2
|
+
class TranscriptDialogBox < FXDialogBox
|
3
|
+
|
4
|
+
LOCATION_TEXT = [
|
5
|
+
"
|
6
|
+
West of House
|
7
|
+
You are standing in an open field west of a white house, with a boarded
|
8
|
+
front door.
|
9
|
+
",
|
10
|
+
"
|
11
|
+
(You are now in the driveway.)
|
12
|
+
(You're sitting in the sports car.)
|
13
|
+
You are by the front gate of the Tresyllian Castle. You can hear the ocean
|
14
|
+
beating urgently against the rocks far below.
|
15
|
+
",
|
16
|
+
"
|
17
|
+
You are now in the driveway entrance.
|
18
|
+
You are standing at the foot of the driveway, the entrance to the Linder
|
19
|
+
property. The entire lot is screened from the street and the neighbors by
|
20
|
+
a wooden fence, except on the east side, which fronts on dense
|
21
|
+
bamboo woods.
|
22
|
+
",
|
23
|
+
]
|
24
|
+
|
25
|
+
LOCATION2_TEXT = [
|
26
|
+
"
|
27
|
+
West of House
|
28
|
+
",
|
29
|
+
"
|
30
|
+
(You are in the driveway.)
|
31
|
+
",
|
32
|
+
"
|
33
|
+
(driveway entrance)
|
34
|
+
",
|
35
|
+
]
|
36
|
+
|
37
|
+
IDENTIFY_TYPE = [
|
38
|
+
'By Descriptions',
|
39
|
+
'By Short Name',
|
40
|
+
]
|
41
|
+
|
42
|
+
SHORTNAME_TYPE = [
|
43
|
+
'Classic',
|
44
|
+
'Moonmist Style',
|
45
|
+
'Witness Style',
|
46
|
+
]
|
47
|
+
|
48
|
+
def copy_from(transcript)
|
49
|
+
@transcript = transcript
|
50
|
+
@type.currentNo = transcript.identify
|
51
|
+
@short.currentNo = transcript.shortName
|
52
|
+
@show.text = LOCATION_TEXT[@short.currentNo]
|
53
|
+
@show2.text = LOCATION2_TEXT[@short.currentNo]
|
54
|
+
parent = transcript.map.window
|
55
|
+
end
|
56
|
+
|
57
|
+
def copy_to()
|
58
|
+
@transcript.identify = @type.currentNo
|
59
|
+
@transcript.shortName = @short.currentNo
|
60
|
+
@show.text = LOCATION_TEXT[@short.currentNo]
|
61
|
+
@show2.text = LOCATION2_TEXT[@short.currentNo]
|
62
|
+
end
|
63
|
+
|
64
|
+
def initialize(transcript)
|
65
|
+
map = transcript.map
|
66
|
+
pos = [40, 40]
|
67
|
+
maxW = map.window.width - 390
|
68
|
+
maxH = map.window.height - 300
|
69
|
+
pos[0] = maxW if pos[0] > maxW
|
70
|
+
pos[1] = maxH if pos[1] > maxH
|
71
|
+
|
72
|
+
decor = DECOR_TITLE|DECOR_BORDER|DECOR_CLOSE
|
73
|
+
super( map.window, 'Transcript Options', decor, pos[0], pos[1], 0, 0 )
|
74
|
+
|
75
|
+
mainFrame = FXVerticalFrame.new(self,
|
76
|
+
FRAME_SUNKEN|FRAME_THICK|
|
77
|
+
LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
78
|
+
|
79
|
+
frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
|
80
|
+
FXLabel.new(frame, "Identify Locations: ", nil, 0, LAYOUT_FILL_X)
|
81
|
+
pane = FXPopup.new(self)
|
82
|
+
IDENTIFY_TYPE.each { |t|
|
83
|
+
FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
|
84
|
+
}
|
85
|
+
@type = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
|
86
|
+
JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
|
87
|
+
LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
|
88
|
+
|
89
|
+
|
90
|
+
frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
|
91
|
+
FXLabel.new(frame, "Short Name Type: ", nil, 0, LAYOUT_FILL_X)
|
92
|
+
pane = FXPopup.new(self)
|
93
|
+
SHORTNAME_TYPE.each { |t|
|
94
|
+
FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
|
95
|
+
}
|
96
|
+
@short = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
|
97
|
+
JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
|
98
|
+
LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
|
99
|
+
|
100
|
+
frame = FXVerticalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
|
101
|
+
FXLabel.new(frame, "Sample Verbose Mode: ", nil, 0, LAYOUT_FILL_X)
|
102
|
+
@show = FXText.new(frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
103
|
+
@show.visibleRows = 7
|
104
|
+
@show.visibleColumns = 60
|
105
|
+
@show.disable
|
106
|
+
FXLabel.new(frame, "Sample Brief Mode: ", nil, 0, LAYOUT_FILL_X)
|
107
|
+
@show2 = FXText.new(frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
108
|
+
@show2.visibleRows = 3
|
109
|
+
@show2.visibleColumns = 60
|
110
|
+
@show2.disable
|
111
|
+
|
112
|
+
@type.connect(SEL_COMMAND) { copy_to }
|
113
|
+
@short.connect(SEL_COMMAND) { copy_to }
|
114
|
+
|
115
|
+
copy_from(transcript)
|
116
|
+
end
|
117
|
+
end
|
@@ -12,6 +12,8 @@
|
|
12
12
|
#
|
13
13
|
class TranscriptReader
|
14
14
|
|
15
|
+
TRANSCRIPT = /^(?:Start of a transcript of|Here begins a transcript of interation with (.*)|Here begins a transcript of interation with)/
|
16
|
+
|
15
17
|
PROMPT = /^>\s*/
|
16
18
|
LOOK = /^l(ook)?/i
|
17
19
|
UNDO = /^undo$/i
|
@@ -24,7 +26,7 @@ class TranscriptReader
|
|
24
26
|
TAKE = /^(take|get)\s+(a\s+|the\s+)?(.*)/i
|
25
27
|
DROP = /^(drop|leave)\s+()/i
|
26
28
|
STARTUP = /(^[A-Z]+$|Copyright|\([cC]\)\s*\d|Trademark|Release|Version|[Ss]erial [Nn]umber|Written by)/
|
27
|
-
DARKNESS = /^dark(ness)
|
29
|
+
DARKNESS = /^dark(ness)?$|^in the dark$|^It is pitch black|^It is too dark to see anything|^You stumble around in the dark/i
|
28
30
|
DEAD = /(You die|You have died|You are dead)/i
|
29
31
|
YES = /^y(es)/i
|
30
32
|
|
@@ -42,16 +44,21 @@ class TranscriptReader
|
|
42
44
|
"in" => 3, "out" => 4, 'enter' => 3, 'exit' => 4 }
|
43
45
|
|
44
46
|
DIR_REX = '(' + DIRMAP.keys.join('|') + '|' + ODIRMAP.keys.join('|') + ')'
|
45
|
-
GO = /^((walk|run|go)\s+)?#{DIR_REX}[.,\s]*\b/i
|
47
|
+
GO = /^((walk|run|go|drive|jump)\s+)?#{DIR_REX}[.,\s]*\b/i
|
46
48
|
|
47
49
|
# Direction list in order of positioning preference.
|
48
50
|
DIRLIST = [ 0, 4, 2, 6, 1, 3, 5, 7 ]
|
49
51
|
|
50
52
|
# No exit replies
|
51
53
|
NO_EXIT = [
|
52
|
-
|
53
|
-
|
54
|
-
|
54
|
+
/\byou\scan't\sgo\sthat\sway\b/i,
|
55
|
+
/\bdoorways\slead\s/i,
|
56
|
+
/\bthat's\sa\swall\b/i,
|
57
|
+
/\bno\sexit\b/i,
|
58
|
+
/\bthere's\s+nothing\sin\sthat\sdirection\b/i,
|
59
|
+
/\bblock\sthe\sway/i,
|
60
|
+
/\byou\scan\sonly\sgo\s/i,
|
61
|
+
/\byou\scan\sgo\sonly\s/i,
|
55
62
|
]
|
56
63
|
|
57
64
|
# Closed exit replies
|
@@ -59,11 +66,12 @@ class TranscriptReader
|
|
59
66
|
/door\s+is\s+closed/i,
|
60
67
|
]
|
61
68
|
|
62
|
-
|
63
|
-
|
64
|
-
|
69
|
+
# remove things like (on the bed)
|
70
|
+
NAME_REMOVE = /(\s+\(.+\)|,\s+[io]n\s+[^\,\.]+)/
|
71
|
+
NAME_INVALID = /[:;\*\[\]\|\+\=!\.\?\000]/
|
72
|
+
SALUTATIONS = /\b(Mr|Mr?s|Miss|Jr|Sr|St)\./
|
65
73
|
NAME_MAXWORDS = 20
|
66
|
-
NAME_MAXUNCAP = 4 # so that lowercase room
|
74
|
+
NAME_MAXUNCAP = 4 # so that lowercase "room" "end" "of" will be accepted
|
67
75
|
|
68
76
|
# Default room description recognition parameters.
|
69
77
|
DESC_MINWORDS = 10
|
@@ -73,10 +81,33 @@ class TranscriptReader
|
|
73
81
|
DESC_IGNORE = /(?:an|a|open(ed)?|closed?)/i
|
74
82
|
|
75
83
|
|
76
|
-
RESTORE_OK = /\b(Ok|completed
|
84
|
+
RESTORE_OK = /\b(Ok|completed?|Okay)\b/
|
85
|
+
|
86
|
+
##
|
87
|
+
THE = '(?:the|a|your|some of the|some)\s+'
|
88
|
+
|
89
|
+
## Regex to eliminate articles from get/take replies.
|
90
|
+
ARTICLE = /^#{THE}/i
|
91
|
+
|
92
|
+
## Possible nessages indicating get/take succeeded
|
93
|
+
TAKE_OBJ = '([\w\d\-\'\s]+)'
|
94
|
+
TAKE_FROM = '(?:\s+(up|from|out)\s+.*)?'
|
95
|
+
TAKE_ALIAS = '(?:grab|pick\s+up|pick|pilfer|take(?:\s+up)?)'
|
96
|
+
TAKE_OK = [
|
97
|
+
/\btaken\b/i,
|
98
|
+
/you\s+have\s+now\s+(?:got\s+)?(?:#{THE})?#{TAKE_OBJ}#{TAKE_FROM}/i,
|
99
|
+
/you\s+#{TAKE_ALIAS}\s+(?:#{THE})?#{TAKE_OBJ}#{TAKE_FROM}/i,
|
100
|
+
/you\s+now\s+have\s+(?:got\s+)?(?:#{THE})?#{TAKE_OBJ}/i,
|
101
|
+
/you\s+pick\s+up\s+(?:#{THE})?#{TAKE_OBJ}/i,
|
102
|
+
/you\s+are\s+now\s+holding\s+(?:#{THE})?#{TAKE_OBJ}/i,
|
103
|
+
]
|
104
|
+
|
105
|
+
IT = /^(it|them)$/i
|
106
|
+
|
107
|
+
@@win = nil
|
77
108
|
|
78
|
-
## Change this to non-
|
79
|
-
@@debug =
|
109
|
+
## Change this to non-nil to print out debugging info
|
110
|
+
@@debug = nil
|
80
111
|
|
81
112
|
def debug(*msg)
|
82
113
|
if @@debug
|
@@ -84,20 +115,15 @@ class TranscriptReader
|
|
84
115
|
end
|
85
116
|
end
|
86
117
|
|
87
|
-
|
88
|
-
|
118
|
+
IDENTIFY_BY_DESCRIPTION = 0
|
119
|
+
IDENTIFY_BY_SHORTNAME = 1
|
89
120
|
|
90
|
-
|
121
|
+
SHORTNAME_CLASSIC = 0
|
122
|
+
SHORTNAME_MOONMIST = 1
|
123
|
+
SHORTNAME_WITNESS = 2
|
91
124
|
|
92
|
-
|
93
|
-
TAKE_OK = [
|
94
|
-
/taken/i,
|
95
|
-
/you\s+pick\s+up\s+the\s+?/i,
|
96
|
-
/you\s+now\s+have\s+(got\s+)?/i,
|
97
|
-
/you\s+(grab|pick|take)\s+#{THE}\s+\w+/i
|
98
|
-
]
|
125
|
+
attr_accessor :identify, :shortName, :map
|
99
126
|
|
100
|
-
IT = /^(it|them)$/i
|
101
127
|
|
102
128
|
|
103
129
|
#
|
@@ -105,26 +131,47 @@ class TranscriptReader
|
|
105
131
|
#
|
106
132
|
def take(move, objs)
|
107
133
|
return unless @here
|
108
|
-
|
109
|
-
|
134
|
+
if @here.objects != '' and @here.objects[-1,1] != "\n"
|
135
|
+
@here.objects << "\n"
|
136
|
+
end
|
137
|
+
|
110
138
|
objs.each { |cmd, dummy, obj|
|
111
|
-
next if not obj
|
139
|
+
next if not obj or not move[:reply]
|
112
140
|
|
113
141
|
objlist = obj.split(',')
|
114
142
|
o = objlist[0]
|
115
143
|
if objlist.size == 1 and o != 'all'
|
116
144
|
# ignore 'get up'
|
117
|
-
next if cmd == 'get' and o == 'up'
|
145
|
+
next if cmd == 'get' and (o == 'up' or o == 'off')
|
118
146
|
o = @last_obj if o =~ IT
|
119
147
|
next if not o
|
148
|
+
if move[:reply][0] =~ /^\((.*)\)$/
|
149
|
+
nobj = $1
|
150
|
+
words = nobj.split(/\s+/)
|
151
|
+
if words.size < 7
|
152
|
+
# Acclaration, like:
|
153
|
+
# > get mask
|
154
|
+
# (the brown mask)
|
155
|
+
# Taken.
|
156
|
+
o = nobj
|
157
|
+
else
|
158
|
+
# too big of an aclaration... probably something like
|
159
|
+
# (putting the xxx in your bag to make room)
|
160
|
+
end
|
161
|
+
end
|
120
162
|
o.sub!(ARTICLE, '')
|
121
163
|
status = move[:reply].to_s
|
122
164
|
TAKE_OK.each { |re|
|
123
|
-
if status =~ re
|
124
|
-
|
125
|
-
|
126
|
-
@
|
127
|
-
|
165
|
+
if status =~ re then
|
166
|
+
obj = $1 || o
|
167
|
+
obj = o if obj =~ /\b(it|them)\b/
|
168
|
+
@last_obj = obj
|
169
|
+
# Take succeeded, change object o
|
170
|
+
if not @objects.has_key?(obj) and
|
171
|
+
not @here.objects =~ /\b#{obj}\b/
|
172
|
+
@here.objects << obj << "\n"
|
173
|
+
@objects[obj] = 1
|
174
|
+
end
|
128
175
|
break
|
129
176
|
end
|
130
177
|
}
|
@@ -133,17 +180,23 @@ class TranscriptReader
|
|
133
180
|
move[:reply].each { |reply|
|
134
181
|
o, status = reply.split(':')
|
135
182
|
next if not status
|
136
|
-
o
|
183
|
+
next if o.split(' ').size > 6 # ignore if too many words
|
137
184
|
o.sub!(ARTICLE, '')
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
185
|
+
TAKE_OK.each { |re|
|
186
|
+
if status =~ re then
|
187
|
+
if o and not @objects.has_key?(o) and
|
188
|
+
not @here.objects =~ /\b#{o}\b/
|
189
|
+
@here.objects << o << "\n"
|
190
|
+
@objects[o] = 1
|
191
|
+
end
|
192
|
+
@last_obj = o
|
193
|
+
break
|
194
|
+
end
|
195
|
+
}
|
144
196
|
}
|
145
197
|
end
|
146
198
|
}
|
199
|
+
@here.objects.squeeze("\n")
|
147
200
|
end
|
148
201
|
|
149
202
|
#
|
@@ -161,39 +214,29 @@ class TranscriptReader
|
|
161
214
|
end
|
162
215
|
|
163
216
|
|
164
|
-
def parse
|
165
|
-
# Find first command prompt
|
166
|
-
while line = @f.gets
|
167
|
-
break if PROMPT =~ line
|
168
|
-
end
|
169
|
-
parse_line(line)
|
170
|
-
end
|
171
|
-
|
172
217
|
#
|
173
218
|
# Given a room description, parse it to try to find out all exits
|
174
219
|
# from room.
|
175
220
|
#
|
176
221
|
|
177
222
|
DIRS = {
|
178
|
-
'north' => 0, 'northeast' => 1, 'east' => 2, 'southeast' => 3,
|
179
|
-
'southwest' => 5, 'west' => 6, 'northwest' => 7
|
223
|
+
'north' => 0, 'northeast' => 1, 'east' => 2, 'southeast' => 3,
|
224
|
+
'south' => 4, 'southwest' => 5, 'west' => 6, 'northwest' => 7
|
180
225
|
}
|
181
226
|
|
182
227
|
DIR = '(' + DIRS.keys.join('|') + ')'
|
183
|
-
OR = '(and|or)'
|
228
|
+
OR = '(?:and|or)'
|
184
229
|
|
185
230
|
EXITS_REGEX =
|
186
231
|
[
|
187
|
-
#
|
188
|
-
|
189
|
-
# You can go south
|
190
|
-
/you\s+can\s+go\s+#{DIR}\b/i,
|
232
|
+
# paths lead west and north
|
233
|
+
/(run|bears|lead|wander|winds|go)\s+#{DIR}\s+#{OR}\s+#{DIR}\b/i,
|
191
234
|
# to the east or west
|
192
235
|
/to\s+the\s+#{DIR}\s+#{OR}\s+(to\s+the\s+)?#{DIR}\b/i,
|
236
|
+
# You can go south
|
237
|
+
/you\s+can\s+go\s+#{DIR}\b/i,
|
193
238
|
# to the east
|
194
239
|
/to\s+the\s+#{DIR}\b/i,
|
195
|
-
# paths lead west and north
|
196
|
-
/(run|bears|lead|wander|winds)\s+#{DIR}\s+#{OR}\s+#{DIR}\b/i,
|
197
240
|
# east-west corridor
|
198
241
|
/[\.\s+]#{DIR}[\/-]#{DIR}\b/i,
|
199
242
|
# East is the postoffice
|
@@ -248,15 +291,34 @@ class TranscriptReader
|
|
248
291
|
# Add a 'stub' for the new connection
|
249
292
|
exits.each { |exit|
|
250
293
|
next if r[exit]
|
251
|
-
|
252
|
-
|
253
|
-
|
294
|
+
begin
|
295
|
+
c = @map.new_connection( r, exit, nil )
|
296
|
+
c.dir = Connection::AtoB
|
297
|
+
debug "\tADDED STUB #{c}"
|
298
|
+
rescue ConnectionError
|
299
|
+
end
|
254
300
|
}
|
255
301
|
end
|
256
302
|
|
303
|
+
|
257
304
|
def parse_line(line)
|
258
305
|
return unless line
|
306
|
+
@map.mutex.synchronize do
|
307
|
+
_parse_line(line)
|
308
|
+
end
|
309
|
+
|
310
|
+
if @map.kind_of?(FXMap)
|
311
|
+
@map.clear_selection
|
312
|
+
@here.selected = true if @here
|
313
|
+
@map.create_pathmap
|
314
|
+
@map.zoom = @map.zoom
|
315
|
+
puts 'transcript zoom done'
|
316
|
+
@map.center_view_on_room(@here) if @here
|
317
|
+
@map.draw
|
318
|
+
end
|
319
|
+
end
|
259
320
|
|
321
|
+
def _parse_line(line)
|
260
322
|
@moves.clear
|
261
323
|
|
262
324
|
#
|
@@ -286,7 +348,10 @@ class TranscriptReader
|
|
286
348
|
|
287
349
|
# Replace all 'THEN' in command for periods
|
288
350
|
cmd.sub!(THEN, '.')
|
289
|
-
|
351
|
+
# and all ANDs for commas
|
352
|
+
cmd.sub!(/\band\b/i,',')
|
353
|
+
# and multiple periods for just one
|
354
|
+
cmd.sub!(/\s*\.+\s*/, '.')
|
290
355
|
|
291
356
|
move[:cmd] = cmd
|
292
357
|
move[:reply] = reply
|
@@ -336,7 +401,6 @@ class TranscriptReader
|
|
336
401
|
startup = false
|
337
402
|
rooms = []
|
338
403
|
move[:reply].each { |r|
|
339
|
-
puts "LINE: #{r}"
|
340
404
|
tele = 1 if r =~ DEAD
|
341
405
|
|
342
406
|
if r =~ STARTUP
|
@@ -357,11 +421,11 @@ class TranscriptReader
|
|
357
421
|
next if startup and r !~ BLANK
|
358
422
|
startup = false
|
359
423
|
|
360
|
-
if not roomflag and r !~ BLANK and room_name(r)
|
361
|
-
debug "
|
424
|
+
if not roomflag and r !~ BLANK and n = room_name(r)
|
425
|
+
debug "Found room #{n}"
|
362
426
|
roomflag = true
|
363
427
|
desc_gap = false
|
364
|
-
name =
|
428
|
+
name = n
|
365
429
|
desc = ''
|
366
430
|
next
|
367
431
|
end
|
@@ -373,13 +437,11 @@ class TranscriptReader
|
|
373
437
|
|
374
438
|
|
375
439
|
if roomflag and r !~ BLANK
|
376
|
-
puts "ADD TO DESC: #{r}"
|
377
440
|
desc << r << "\n"
|
378
441
|
next
|
379
442
|
end
|
380
443
|
|
381
444
|
if r =~ BLANK and roomflag
|
382
|
-
puts "DONE DESC"
|
383
445
|
if desc.count("\n") == 1 and desc =~ /\?$/
|
384
446
|
# A "What next?" type of prompt, not a room description
|
385
447
|
desc = ''
|
@@ -388,9 +450,9 @@ class TranscriptReader
|
|
388
450
|
desc = nil
|
389
451
|
else
|
390
452
|
desc.gsub!(/\n/, ' ')
|
453
|
+
desc.strip!
|
391
454
|
end
|
392
455
|
|
393
|
-
puts "DESC: #{desc}"
|
394
456
|
rooms << {
|
395
457
|
:name => name,
|
396
458
|
:desc => desc,
|
@@ -403,6 +465,17 @@ class TranscriptReader
|
|
403
465
|
tele = nil
|
404
466
|
end
|
405
467
|
}
|
468
|
+
|
469
|
+
# Oops, there was no newline between room description and prompt and
|
470
|
+
# we missed the last room.
|
471
|
+
# This happens for example with Magnetic Scrolls transcripts.
|
472
|
+
if name
|
473
|
+
rooms << {
|
474
|
+
:name => name,
|
475
|
+
:desc => desc,
|
476
|
+
:tele => tele
|
477
|
+
}
|
478
|
+
end
|
406
479
|
|
407
480
|
if not rooms.empty?
|
408
481
|
move[:rooms] = rooms
|
@@ -439,7 +512,7 @@ class TranscriptReader
|
|
439
512
|
end
|
440
513
|
|
441
514
|
# Check if there is a closed door
|
442
|
-
if @here[dir].type == Connection::FREE
|
515
|
+
if @here[dir] and @here[dir].type == Connection::FREE
|
443
516
|
CLOSED_EXIT.each { |re|
|
444
517
|
if move[:reply][0] =~ re
|
445
518
|
# If so, flag it
|
@@ -512,6 +585,8 @@ class TranscriptReader
|
|
512
585
|
break
|
513
586
|
end
|
514
587
|
|
588
|
+
sect = @map.section
|
589
|
+
|
515
590
|
# Otherwise, assume we moved in some way. Try to find the new room.
|
516
591
|
if name =~ DARKNESS
|
517
592
|
idx = DIRMAP[dir] || ODIRMAP[dir]
|
@@ -556,7 +631,8 @@ class TranscriptReader
|
|
556
631
|
dir = choose_dir(@here, there, go)
|
557
632
|
else
|
558
633
|
# special move --- teleport/death/etc.
|
559
|
-
|
634
|
+
go = 0
|
635
|
+
dir = choose_dir(@here, there, go)
|
560
636
|
end
|
561
637
|
debug "MOVED IN DIR INDEX: #{dir}"
|
562
638
|
|
@@ -566,7 +642,9 @@ class TranscriptReader
|
|
566
642
|
@here = new_room(move, name, desc, dir, @here, go)
|
567
643
|
else
|
568
644
|
# Visited before -- new link
|
569
|
-
|
645
|
+
if sect == @map.section # don't conn
|
646
|
+
new_link(move, @here, there, dir, go)
|
647
|
+
end
|
570
648
|
@here = there
|
571
649
|
end
|
572
650
|
}
|
@@ -575,17 +653,80 @@ class TranscriptReader
|
|
575
653
|
@moves.clear
|
576
654
|
@map.fit
|
577
655
|
if @map.kind_of?(FXMap)
|
578
|
-
@map.clear_selection
|
579
|
-
@here.selected = true if @here
|
580
|
-
@map.create_pathmap
|
581
|
-
@map.zoom = @map.zoom
|
582
|
-
@map.center_view_on_room(@here) if @here
|
583
|
-
@map.verify_integrity
|
584
|
-
@map.draw
|
585
656
|
end
|
586
657
|
end
|
587
658
|
|
588
659
|
def find_room(name, desc)
|
660
|
+
case @identify
|
661
|
+
when IDENTIFY_BY_DESCRIPTION
|
662
|
+
return find_room_by_desc(name, desc)
|
663
|
+
when IDENTIFY_BY_SHORTNAME
|
664
|
+
return find_room_by_name(name, desc)
|
665
|
+
end
|
666
|
+
end
|
667
|
+
|
668
|
+
def find_room_by_name(name, desc)
|
669
|
+
bestscore = 0
|
670
|
+
best = nil
|
671
|
+
|
672
|
+
@map.sections.each_with_index { |sect, idx|
|
673
|
+
sect.rooms.each { |room|
|
674
|
+
score = 0
|
675
|
+
score += 1 if room.name == name
|
676
|
+
|
677
|
+
if score == 1 and desc and room.desc
|
678
|
+
# We have a description...
|
679
|
+
# Try exact description match first
|
680
|
+
score += 10 if room.desc == desc
|
681
|
+
|
682
|
+
# Try substring match
|
683
|
+
score += 5 if room.desc.index(desc)
|
684
|
+
|
685
|
+
# If we have a room where both name and desc match,
|
686
|
+
# we get a better score than just description only.
|
687
|
+
# This is to help, for example, Trinity, where two rooms have
|
688
|
+
# the exact description but different name.
|
689
|
+
score += 1 if room.name == name and score > 0
|
690
|
+
|
691
|
+
# If still no luck, try first N words
|
692
|
+
if score == 1
|
693
|
+
dwords = room.desc.split(' ')
|
694
|
+
words = desc.split(' ')
|
695
|
+
match = true
|
696
|
+
0.upto(DESC_MINWORDS) { |i|
|
697
|
+
# Ignore some words (like open/close, which may just mean
|
698
|
+
# some doors changed state)
|
699
|
+
next if words[i] =~ DESC_IGNORE
|
700
|
+
|
701
|
+
if words[i] != dwords[i]
|
702
|
+
match = false
|
703
|
+
break
|
704
|
+
end
|
705
|
+
}
|
706
|
+
|
707
|
+
score += 1 if match
|
708
|
+
end
|
709
|
+
end
|
710
|
+
next if score <= bestscore
|
711
|
+
bestscore = score
|
712
|
+
best = [room, idx]
|
713
|
+
}
|
714
|
+
}
|
715
|
+
|
716
|
+
return nil if not best
|
717
|
+
|
718
|
+
# Make sure we are in the right section
|
719
|
+
if best[1] != @map.section
|
720
|
+
@map.fit
|
721
|
+
@map.section = best[1]
|
722
|
+
end
|
723
|
+
if desc and (not best[0].desc or best[0].desc == '')
|
724
|
+
best[0].desc = desc
|
725
|
+
end
|
726
|
+
return best[0]
|
727
|
+
end
|
728
|
+
|
729
|
+
def find_room_by_desc(name, desc)
|
589
730
|
bestscore = 0
|
590
731
|
best = nil
|
591
732
|
|
@@ -642,32 +783,77 @@ class TranscriptReader
|
|
642
783
|
@map.fit
|
643
784
|
@map.section = best[1]
|
644
785
|
end
|
645
|
-
puts "DESC: #{desc} RDESC:#{best[0].desc}"
|
646
786
|
if desc and (not best[0].desc or best[0].desc == '')
|
647
787
|
best[0].desc = desc
|
648
|
-
puts "CHANGED: #{best[0].desc}"
|
649
788
|
end
|
650
789
|
return best[0]
|
651
790
|
end
|
791
|
+
|
792
|
+
def room_name(line)
|
793
|
+
case @shortName
|
794
|
+
when SHORTNAME_CLASSIC
|
795
|
+
return room_name_classic(line)
|
796
|
+
when SHORTNAME_MOONMIST
|
797
|
+
return room_name_moonmist(line)
|
798
|
+
when SHORTNAME_WITNESS
|
799
|
+
return room_name_witness(line)
|
800
|
+
end
|
801
|
+
end
|
802
|
+
|
803
|
+
def capitalize_room(line)
|
804
|
+
words = line.split(' ')
|
805
|
+
words.each { |w|
|
806
|
+
if w =~ /^(?:of|on|in|the|a)$/i
|
807
|
+
w.downcase!
|
808
|
+
else
|
809
|
+
w.capitalize!
|
810
|
+
end
|
811
|
+
}
|
812
|
+
return words.join(' ')
|
813
|
+
end
|
814
|
+
|
815
|
+
def room_name_witness(line)
|
816
|
+
if line =~ /^You\sare\s(?:now\s)?(?:[io]n\s)?(?:#{THE})?([\w'\d\s\-_]+)\.$/
|
817
|
+
return false if $1 =~ /own feet/
|
818
|
+
return $1
|
819
|
+
elsif line =~ /^\(([\w\d\s_]+)\)$/
|
820
|
+
return $1
|
821
|
+
else
|
822
|
+
return false
|
823
|
+
end
|
824
|
+
end
|
825
|
+
|
826
|
+
def room_name_moonmist(line)
|
827
|
+
return false if line =~ /^\(You are not holding it.\)$/
|
828
|
+
if line =~ /^\(You\sare\s(?:now\s)?(?:[io]n\s)?(?:#{THE})?([\w'\d\s\-_]+)\.\)$/
|
829
|
+
return capitalize_room( $1 )
|
830
|
+
else
|
831
|
+
return false
|
832
|
+
end
|
833
|
+
end
|
652
834
|
|
653
835
|
#
|
654
836
|
# Determine if line corresponds to a room name
|
655
837
|
#
|
656
|
-
def
|
838
|
+
def room_name_classic(line)
|
657
839
|
# Check if user/game has created a room with that name already
|
658
|
-
return
|
840
|
+
return line if find_room(line, nil)
|
841
|
+
|
842
|
+
# We have a room if we match darkness
|
843
|
+
return line if line =~ DARKNESS
|
659
844
|
|
660
845
|
# Remove unwanted stuff line (on the bed)
|
661
846
|
line.sub!(NAME_REMOVE, '')
|
662
847
|
|
663
848
|
# Check if user/game has created a room with that name already
|
664
|
-
return
|
849
|
+
return line if find_room(line, nil)
|
665
850
|
|
666
851
|
# Remove periods from salutations
|
667
852
|
line.sub!(SALUTATIONS, '\1')
|
668
853
|
|
669
854
|
# quick check for invalid format
|
670
855
|
return false if line =~ NAME_INVALID
|
856
|
+
|
671
857
|
# Qucik check for word characters
|
672
858
|
return false unless line =~ /\w/
|
673
859
|
|
@@ -676,8 +862,12 @@ class TranscriptReader
|
|
676
862
|
return false if words.size > NAME_MAXWORDS
|
677
863
|
|
678
864
|
# Check if we start line with uncapitalized words or symbols
|
679
|
-
return false if line =~ /^[ a-z\/\\\-\(\)'
|
865
|
+
return false if line =~ /^[ a-z\/\\\-\(\)']/
|
680
866
|
|
867
|
+
# Check if line holds only capitalized words or several spaces together
|
868
|
+
# or a quote or a 1) line. If so, not a room.
|
869
|
+
return false if line =~ /^[A-Z\d,\.\/\-"'\s]+$/ or line =~ /\s\s/ or
|
870
|
+
line =~ /^".*"$/ or line =~ /^"[^"]+$/ or line =~ /^\d+\)/
|
681
871
|
|
682
872
|
# If not, check all words of 4 chars or more are capitalized
|
683
873
|
# and that there are no 3 or more short letter words together
|
@@ -694,7 +884,7 @@ class TranscriptReader
|
|
694
884
|
}
|
695
885
|
|
696
886
|
# Okay, it is a room.
|
697
|
-
return
|
887
|
+
return line
|
698
888
|
end
|
699
889
|
|
700
890
|
#
|
@@ -752,6 +942,7 @@ class TranscriptReader
|
|
752
942
|
debug "\tUPDATE #{c}"
|
753
943
|
odir = (dir + 4) % 8
|
754
944
|
c.exitAtext = go if go
|
945
|
+
c.type = Connection::SPECIAL if go == 0
|
755
946
|
c.roomB = r
|
756
947
|
r[odir] = c
|
757
948
|
debug "\tNOW IT IS #{c}"
|
@@ -766,7 +957,8 @@ class TranscriptReader
|
|
766
957
|
begin
|
767
958
|
c = @map.new_connection( from, dir, r )
|
768
959
|
c.exitAtext = go if go
|
769
|
-
c.
|
960
|
+
c.type = Connection::SPECIAL if go == 0
|
961
|
+
c.dir = Connection::AtoB
|
770
962
|
rescue Section::ConnectionError
|
771
963
|
end
|
772
964
|
end
|
@@ -820,6 +1012,7 @@ class TranscriptReader
|
|
820
1012
|
# Stub connection, fill it
|
821
1013
|
c.roomB = to
|
822
1014
|
c.exitAtext = go if go
|
1015
|
+
c.type = Connection::SPECIAL if go == 0
|
823
1016
|
# we still need to check the destination to[odir]...
|
824
1017
|
if not to[odir]
|
825
1018
|
# nothing to do
|
@@ -830,7 +1023,7 @@ class TranscriptReader
|
|
830
1023
|
# this end cannot be deleted. we need to shift odir
|
831
1024
|
debug "\tCHOOSE NEW DIR for #{odir}"
|
832
1025
|
rgo = nil
|
833
|
-
if go
|
1026
|
+
if go and go > 0
|
834
1027
|
rgo = rgo % 2 == 0? go - 1 : go + 1
|
835
1028
|
end
|
836
1029
|
odir = choose_dir(to, from, rgo, dir)
|
@@ -849,7 +1042,7 @@ class TranscriptReader
|
|
849
1042
|
debug "\tVERIFIED EXIT BOTH WAYS"
|
850
1043
|
else
|
851
1044
|
debug "\tOTHER"
|
852
|
-
if c.roomA == from
|
1045
|
+
if c.roomA == from
|
853
1046
|
b = c.roomB
|
854
1047
|
if b.name =~ DARKNESS
|
855
1048
|
debug "*** REPLACING DARK ROOM ***"
|
@@ -859,15 +1052,17 @@ class TranscriptReader
|
|
859
1052
|
c = nil
|
860
1053
|
else
|
861
1054
|
if c.exitAtext != 0
|
1055
|
+
# if it was an up/down/in/out dir, we shift it
|
862
1056
|
shift_link(from, dir)
|
863
1057
|
c = nil
|
864
1058
|
else
|
1059
|
+
# else, we really have a problem in the map
|
865
1060
|
debug "*** CANNOT AUTOMAP --- MAZE ***"
|
866
1061
|
dir = Room::DIRECTIONS[dir]
|
867
1062
|
@map.cannot_automap "Maze detected.\n'#{from}' #{dir} leads to '#{c.roomB}',\nnot to this '#{to}'."
|
1063
|
+
# self.stop
|
1064
|
+
return nil
|
868
1065
|
end
|
869
|
-
# self.stop
|
870
|
-
return nil
|
871
1066
|
end
|
872
1067
|
else
|
873
1068
|
debug "SHIFT LINK #{from} #{dir}"
|
@@ -888,12 +1083,14 @@ class TranscriptReader
|
|
888
1083
|
from[dir] = c
|
889
1084
|
c.dir = Connection::BtoA
|
890
1085
|
c.exitBtext = go if go
|
1086
|
+
c.type = Connection::SPECIAL if go == 0
|
891
1087
|
elsif c.roomB == from
|
892
1088
|
c.exitBtext = go if go
|
1089
|
+
c.type = Connection::SPECIAL if go == 0
|
893
1090
|
else
|
894
1091
|
# We need to change odir to something else
|
895
1092
|
rgo = nil
|
896
|
-
if go
|
1093
|
+
if go and go > 0
|
897
1094
|
rgo = go % 2 == 0? go - 1 : go + 1
|
898
1095
|
end
|
899
1096
|
odir = choose_dir(to, from, rgo, dir)
|
@@ -918,6 +1115,7 @@ class TranscriptReader
|
|
918
1115
|
from[dir] = c
|
919
1116
|
c.dir = Connection::BOTH
|
920
1117
|
c.exitAtext = go if go
|
1118
|
+
c.type = Connection::SPECIAL if go == 0
|
921
1119
|
end
|
922
1120
|
end
|
923
1121
|
|
@@ -1018,7 +1216,23 @@ class TranscriptReader
|
|
1018
1216
|
GC.start
|
1019
1217
|
end
|
1020
1218
|
|
1219
|
+
|
1220
|
+
def properties(modal = false)
|
1221
|
+
require 'IFMapper/TranscriptDialogBox'
|
1222
|
+
if not @@win
|
1223
|
+
@@win = TranscriptDialogBox.new(self)
|
1224
|
+
else
|
1225
|
+
@@win.copy_from(self)
|
1226
|
+
end
|
1227
|
+
if modal
|
1228
|
+
@@win.execute
|
1229
|
+
end
|
1230
|
+
end
|
1231
|
+
|
1021
1232
|
def initialize(map, file)
|
1233
|
+
@shortName = 0
|
1234
|
+
@identify = 0
|
1235
|
+
|
1022
1236
|
@file = file
|
1023
1237
|
@map = map
|
1024
1238
|
@objects = {}
|
@@ -1026,12 +1240,6 @@ class TranscriptReader
|
|
1026
1240
|
@here = nil
|
1027
1241
|
@section = -1
|
1028
1242
|
@last_obj = nil
|
1029
|
-
|
1030
|
-
@f = File.open(@file, 'r')
|
1031
|
-
while line = @f.gets
|
1032
|
-
break if PROMPT =~ line
|
1033
|
-
end
|
1034
|
-
parse
|
1035
1243
|
end
|
1036
1244
|
|
1037
1245
|
# Step one user command at a time
|
@@ -1045,6 +1253,22 @@ class TranscriptReader
|
|
1045
1253
|
end
|
1046
1254
|
|
1047
1255
|
def start
|
1256
|
+
if not @f
|
1257
|
+
@f = File.open(@file, 'r')
|
1258
|
+
while line = @f.gets
|
1259
|
+
if @map.name =~ /^Empty Map/ and line =~ TRANSCRIPT
|
1260
|
+
if $1
|
1261
|
+
@map.name = $1
|
1262
|
+
else
|
1263
|
+
@map.name = @f.gets.strip
|
1264
|
+
end
|
1265
|
+
@map.name = capitalize_room(@map.name)
|
1266
|
+
end
|
1267
|
+
break if PROMPT =~ line
|
1268
|
+
end
|
1269
|
+
parse_line(line)
|
1270
|
+
end
|
1271
|
+
|
1048
1272
|
@t = Thread.new {
|
1049
1273
|
loop do
|
1050
1274
|
self.step
|