ifmapper 0.9 → 0.9.5
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 +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
|