ifmapper 0.9.7 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.txt +32 -0
- data/bin/IFMapper +31 -0
- data/docs/images/IFMapper_main.gif +0 -0
- data/docs/images/automap.gif +0 -0
- data/docs/images/complex_connection.gif +0 -0
- data/docs/images/connection.gif +0 -0
- data/docs/images/connection_menu.gif +0 -0
- data/docs/images/room_description.gif +0 -0
- data/docs/images/room_small.gif +0 -0
- data/docs/index.html +24 -0
- data/docs/start.html +516 -0
- data/docs/start.html~ +516 -0
- data/lib/IFMapper/FXMap.rb +35 -0
- data/lib/IFMapper/FXMapperWindow.rb +25 -6
- data/lib/IFMapper/Map.rb +4 -0
- data/lib/IFMapper/PDFMapExporter.rb +20 -15
- data/lib/IFMapper/Section.rb +9 -2
- data/lib/IFMapper/TADSWriter.rb +1 -1
- data/lib/IFMapper/TranscriptDialogBox.rb +175 -175
- data/lib/IFMapper/TranscriptReader.rb +58 -22
- data/maps/anchor.map +0 -0
- data/maps/building.map +0 -0
- data/maps/distress.map +0 -0
- data/maps/gamlet.map +0 -0
- data/maps/guilty_bastards.map +0 -0
- data/maps/splashdown.map +0 -0
- data/maps/squarecircle.map +0 -0
- data/maps/vespers.map +0 -0
- data/maps/xtcontest.map +0 -0
- metadata +41 -13
- data/IFMapper.gemspec +0 -21
@@ -127,18 +127,18 @@ class FXConnection
|
|
127
127
|
|
128
128
|
if @type == LOCKED_DOOR or @type == CLOSED_DOOR
|
129
129
|
t = p.size / 2
|
130
|
-
x1, y1 = [ p[t]
|
131
|
-
x2, y2 = [ p[t-2]
|
130
|
+
x1, y1 = [ p[t][0], p[t][1] ]
|
131
|
+
x2, y2 = [ p[t-2][0], p[t-2][1] ]
|
132
132
|
pdf_draw_door(pdf, x1, y1, x2, y2)
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
136
136
|
def pdf_draw_simple(pdf, opts)
|
137
|
-
return if not @
|
137
|
+
return if not @room[1] # PDF does not print unfinished complex connections
|
138
138
|
|
139
|
-
dir = @
|
140
|
-
x1, y1 = @
|
141
|
-
x2, y2 = @
|
139
|
+
dir = @room[0].exits.index(self)
|
140
|
+
x1, y1 = @room[0].pdf_corner(opts, self, dir)
|
141
|
+
x2, y2 = @room[1].pdf_corner(opts, self)
|
142
142
|
pdf.move_to(x1, y1)
|
143
143
|
pdf.line_to(x2, y2).stroke
|
144
144
|
pdf_draw_arrow(pdf, opts, x1, y1, x2, y2)
|
@@ -174,17 +174,19 @@ class FXConnection
|
|
174
174
|
end
|
175
175
|
|
176
176
|
def pdf_draw_exit_text(pdf, opts)
|
177
|
-
|
178
|
-
|
179
|
-
|
177
|
+
|
178
|
+
if @exitText[0] != 0
|
179
|
+
dir = @room[0].exits.index(self)
|
180
|
+
x, y = @room[0].pdf_corner(opts, self, dir)
|
180
181
|
pdf_draw_text( pdf, x, y, dir,
|
181
|
-
EXIT_TEXT[@
|
182
|
+
EXIT_TEXT[@exitText[0]], @dir == BtoA)
|
182
183
|
end
|
183
|
-
|
184
|
-
|
185
|
-
|
184
|
+
|
185
|
+
if @exitText[1] != 0
|
186
|
+
dir = @room[1].exits.rindex(self)
|
187
|
+
x, y = @room[1].pdf_corner(opts, self, dir)
|
186
188
|
pdf_draw_text( pdf, x, y, dir,
|
187
|
-
EXIT_TEXT[@
|
189
|
+
EXIT_TEXT[@exitText[1]], @dir == AtoB)
|
188
190
|
end
|
189
191
|
end
|
190
192
|
|
@@ -467,12 +469,15 @@ class FXMap
|
|
467
469
|
num = pack_sections( pdf_options['width'] + 2,
|
468
470
|
pdf_options['height'] + 2 )
|
469
471
|
pdf_draw_sections(pdf, pdf_options)
|
472
|
+
if pdffile !~ /\.pdf$/
|
473
|
+
pdffile << ".pdf"
|
474
|
+
end
|
470
475
|
status "Exporting PDF file '#{pdffile}'"
|
471
476
|
pdf.save_as(pdffile)
|
472
477
|
rescue => e
|
473
478
|
p e
|
474
479
|
p e.backtrace
|
475
|
-
|
480
|
+
raise e
|
476
481
|
end
|
477
482
|
end
|
478
483
|
end
|
data/lib/IFMapper/Section.rb
CHANGED
@@ -145,14 +145,21 @@ class Section
|
|
145
145
|
end
|
146
146
|
|
147
147
|
#
|
148
|
-
# Delete a room
|
148
|
+
# Delete a room, leaving its connections intact
|
149
|
+
#
|
150
|
+
def delete_room_only(r)
|
151
|
+
@rooms.delete(r)
|
152
|
+
end
|
153
|
+
|
154
|
+
#
|
155
|
+
# Delete a room and all of its connections
|
149
156
|
#
|
150
157
|
def delete_room(r)
|
151
158
|
r.exits.each { |e|
|
152
159
|
next if not e
|
153
160
|
delete_connection(e)
|
154
161
|
}
|
155
|
-
|
162
|
+
delete_room_only(r)
|
156
163
|
end
|
157
164
|
|
158
165
|
#
|
data/lib/IFMapper/TADSWriter.rb
CHANGED
@@ -1,175 +1,175 @@
|
|
1
|
-
|
2
|
-
class TranscriptDialogBox < FXDialogBox
|
3
|
-
|
4
|
-
EXPLANATION_TEXT = [
|
5
|
-
"Classic Mode expects a short name description for all
|
6
|
-
locations, where all words of 5 or more characters to are
|
7
|
-
capitalized and where there is no period.
|
8
|
-
Commands always begin with a > prompt.",
|
9
|
-
"Capitalized Mode expects a short name description for all
|
10
|
-
locations, where only the first word needs to be capitalized
|
11
|
-
and there is no period.
|
12
|
-
Commands always begin with a > prompt.",
|
13
|
-
"Moonmist mode describes locations in parenthesis, with 'You
|
14
|
-
are...' prefixed and a period at the end, inside the parenthesis.
|
15
|
-
Commands always begin with a > prompt.",
|
16
|
-
"Witness mode expects locations described as normal prose, using
|
17
|
-
'You are...' as an introductory paragraph. When in brief mode,
|
18
|
-
locations are expected to be in parenthesis.
|
19
|
-
Commands always begin with a > prompt.",
|
20
|
-
"ADRIFT mode expects locations to be like in Classic Mode (short
|
21
|
-
names where all words of 5 or more characters are capitalized).
|
22
|
-
However, commands do not begin with any type of prompt but start
|
23
|
-
with a lowercase word without any margin.",
|
24
|
-
]
|
25
|
-
|
26
|
-
LOCATION_TEXT = [
|
27
|
-
"
|
28
|
-
> look
|
29
|
-
West of House
|
30
|
-
You are standing in an open field west of a white house, with a boarded
|
31
|
-
front door.
|
32
|
-
",
|
33
|
-
"
|
34
|
-
> look
|
35
|
-
Women's change room
|
36
|
-
Your heels click loudly on the tiles, echoing down the banks of lockers
|
37
|
-
that line the sides of the room.
|
38
|
-
",
|
39
|
-
"
|
40
|
-
> look
|
41
|
-
(You are now in the driveway.)
|
42
|
-
(You're sitting in the sports car.)
|
43
|
-
You are by the front gate of the Tresyllian Castle. You can hear the ocean
|
44
|
-
beating urgently against the rocks far below.
|
45
|
-
",
|
46
|
-
"
|
47
|
-
> look
|
48
|
-
You are now in the driveway entrance.
|
49
|
-
You are standing at the foot of the driveway, the entrance to the
|
50
|
-
Linder property. The entire lot is screened from the street and the
|
51
|
-
neighbors by a wooden fence, except on the east side, which fronts on
|
52
|
-
dense bamboo woods.
|
53
|
-
",
|
54
|
-
"
|
55
|
-
look
|
56
|
-
Front of Mall
|
57
|
-
Although four-wheeled vehicles do pass through, this autonomous
|
58
|
-
spot of pavement is too narrow a place for them to stall. It is just
|
59
|
-
right for bicycles and motorbikes such as yours.
|
60
|
-
",
|
61
|
-
]
|
62
|
-
|
63
|
-
LOCATION2_TEXT = [
|
64
|
-
"
|
65
|
-
West of House
|
66
|
-
",
|
67
|
-
"
|
68
|
-
Women's change room
|
69
|
-
",
|
70
|
-
"
|
71
|
-
(You are in the driveway.)
|
72
|
-
",
|
73
|
-
"
|
74
|
-
(driveway entrance)
|
75
|
-
",
|
76
|
-
"
|
77
|
-
Front of Mall
|
78
|
-
",
|
79
|
-
]
|
80
|
-
|
81
|
-
IDENTIFY_TYPE = [
|
82
|
-
'By Descriptions',
|
83
|
-
'By Short Name',
|
84
|
-
]
|
85
|
-
|
86
|
-
SHORTNAME_TYPE = [
|
87
|
-
'Classic',
|
88
|
-
'Capitalized',
|
89
|
-
'Moonmist',
|
90
|
-
'Witness',
|
91
|
-
'ADRIFT',
|
92
|
-
]
|
93
|
-
|
94
|
-
def copy_from(transcript)
|
95
|
-
@transcript = transcript
|
96
|
-
@type.currentNo = transcript.identify
|
97
|
-
@short.currentNo = transcript.shortName
|
98
|
-
@exp.text = EXPLANATION_TEXT[@short.currentNo]
|
99
|
-
@show.text = LOCATION_TEXT[@short.currentNo]
|
100
|
-
@show2.text = LOCATION2_TEXT[@short.currentNo]
|
101
|
-
parent = transcript.map.window
|
102
|
-
end
|
103
|
-
|
104
|
-
def copy_to()
|
105
|
-
@transcript.identify = @type.currentNo
|
106
|
-
@transcript.shortName = @short.currentNo
|
107
|
-
@exp.text = EXPLANATION_TEXT[@short.currentNo]
|
108
|
-
@show.text = LOCATION_TEXT[@short.currentNo]
|
109
|
-
@show2.text = LOCATION2_TEXT[@short.currentNo]
|
110
|
-
end
|
111
|
-
|
112
|
-
def initialize(transcript)
|
113
|
-
map = transcript.map
|
114
|
-
pos = [40, 40]
|
115
|
-
maxW = map.window.width - 390
|
116
|
-
maxH = map.window.height - 300
|
117
|
-
pos[0] = maxW if pos[0] > maxW
|
118
|
-
pos[1] = maxH if pos[1] > maxH
|
119
|
-
|
120
|
-
decor = DECOR_TITLE|DECOR_BORDER|DECOR_CLOSE
|
121
|
-
super( map.window, 'Transcript Options', decor, pos[0], pos[1], 0, 0 )
|
122
|
-
|
123
|
-
mainFrame = FXVerticalFrame.new(self,
|
124
|
-
FRAME_SUNKEN|FRAME_THICK|
|
125
|
-
LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
126
|
-
|
127
|
-
frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
|
128
|
-
FXLabel.new(frame, "Transcript Style: ", nil, 0, LAYOUT_FILL_X)
|
129
|
-
pane = FXPopup.new(self)
|
130
|
-
SHORTNAME_TYPE.each { |t|
|
131
|
-
FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
|
132
|
-
}
|
133
|
-
@short = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
|
134
|
-
JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
|
135
|
-
LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
|
136
|
-
|
137
|
-
|
138
|
-
frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
|
139
|
-
FXLabel.new(frame, "Identify Locations: ", nil, 0, LAYOUT_FILL_X)
|
140
|
-
pane = FXPopup.new(self)
|
141
|
-
IDENTIFY_TYPE.each { |t|
|
142
|
-
FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
|
143
|
-
}
|
144
|
-
@type = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
|
145
|
-
JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
|
146
|
-
LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
frame = FXVerticalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
|
151
|
-
FXLabel.new(frame, "Explanation: ", nil, 0, LAYOUT_FILL_X)
|
152
|
-
@exp = FXText.new(frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
153
|
-
@exp.visibleRows = 4
|
154
|
-
@exp.visibleColumns = 60
|
155
|
-
@exp.backColor = mainFrame.backColor
|
156
|
-
@exp.disable
|
157
|
-
|
158
|
-
frame = FXVerticalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
|
159
|
-
FXLabel.new(frame, "Sample Verbose Mode: ", nil, 0, LAYOUT_FILL_X)
|
160
|
-
@show = FXText.new(frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
161
|
-
@show.visibleRows = 9
|
162
|
-
@show.visibleColumns = 60
|
163
|
-
@show.disable
|
164
|
-
FXLabel.new(frame, "Sample Brief Mode: ", nil, 0, LAYOUT_FILL_X)
|
165
|
-
@show2 = FXText.new(frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
166
|
-
@show2.visibleRows = 3
|
167
|
-
@show2.visibleColumns = 60
|
168
|
-
@show2.disable
|
169
|
-
|
170
|
-
@type.connect(SEL_COMMAND) { copy_to }
|
171
|
-
@short.connect(SEL_COMMAND) { copy_to }
|
172
|
-
|
173
|
-
copy_from(transcript)
|
174
|
-
end
|
175
|
-
end
|
1
|
+
|
2
|
+
class TranscriptDialogBox < FXDialogBox
|
3
|
+
|
4
|
+
EXPLANATION_TEXT = [
|
5
|
+
"Classic Mode expects a short name description for all
|
6
|
+
locations, where all words of 5 or more characters to are
|
7
|
+
capitalized and where there is no period.
|
8
|
+
Commands always begin with a > prompt.",
|
9
|
+
"Capitalized Mode expects a short name description for all
|
10
|
+
locations, where only the first word needs to be capitalized
|
11
|
+
and there is no period.
|
12
|
+
Commands always begin with a > prompt.",
|
13
|
+
"Moonmist mode describes locations in parenthesis, with 'You
|
14
|
+
are...' prefixed and a period at the end, inside the parenthesis.
|
15
|
+
Commands always begin with a > prompt.",
|
16
|
+
"Witness mode expects locations described as normal prose, using
|
17
|
+
'You are...' as an introductory paragraph. When in brief mode,
|
18
|
+
locations are expected to be in parenthesis.
|
19
|
+
Commands always begin with a > prompt.",
|
20
|
+
"ADRIFT mode expects locations to be like in Classic Mode (short
|
21
|
+
names where all words of 5 or more characters are capitalized).
|
22
|
+
However, commands do not begin with any type of prompt but start
|
23
|
+
with a lowercase word without any margin.",
|
24
|
+
]
|
25
|
+
|
26
|
+
LOCATION_TEXT = [
|
27
|
+
"
|
28
|
+
> look
|
29
|
+
West of House
|
30
|
+
You are standing in an open field west of a white house, with a boarded
|
31
|
+
front door.
|
32
|
+
",
|
33
|
+
"
|
34
|
+
> look
|
35
|
+
Women's change room
|
36
|
+
Your heels click loudly on the tiles, echoing down the banks of lockers
|
37
|
+
that line the sides of the room.
|
38
|
+
",
|
39
|
+
"
|
40
|
+
> look
|
41
|
+
(You are now in the driveway.)
|
42
|
+
(You're sitting in the sports car.)
|
43
|
+
You are by the front gate of the Tresyllian Castle. You can hear the ocean
|
44
|
+
beating urgently against the rocks far below.
|
45
|
+
",
|
46
|
+
"
|
47
|
+
> look
|
48
|
+
You are now in the driveway entrance.
|
49
|
+
You are standing at the foot of the driveway, the entrance to the
|
50
|
+
Linder property. The entire lot is screened from the street and the
|
51
|
+
neighbors by a wooden fence, except on the east side, which fronts on
|
52
|
+
dense bamboo woods.
|
53
|
+
",
|
54
|
+
"
|
55
|
+
look
|
56
|
+
Front of Mall
|
57
|
+
Although four-wheeled vehicles do pass through, this autonomous
|
58
|
+
spot of pavement is too narrow a place for them to stall. It is just
|
59
|
+
right for bicycles and motorbikes such as yours.
|
60
|
+
",
|
61
|
+
]
|
62
|
+
|
63
|
+
LOCATION2_TEXT = [
|
64
|
+
"
|
65
|
+
West of House
|
66
|
+
",
|
67
|
+
"
|
68
|
+
Women's change room
|
69
|
+
",
|
70
|
+
"
|
71
|
+
(You are in the driveway.)
|
72
|
+
",
|
73
|
+
"
|
74
|
+
(driveway entrance)
|
75
|
+
",
|
76
|
+
"
|
77
|
+
Front of Mall
|
78
|
+
",
|
79
|
+
]
|
80
|
+
|
81
|
+
IDENTIFY_TYPE = [
|
82
|
+
'By Descriptions',
|
83
|
+
'By Short Name',
|
84
|
+
]
|
85
|
+
|
86
|
+
SHORTNAME_TYPE = [
|
87
|
+
'Classic',
|
88
|
+
'Capitalized',
|
89
|
+
'Moonmist',
|
90
|
+
'Witness',
|
91
|
+
'ADRIFT',
|
92
|
+
]
|
93
|
+
|
94
|
+
def copy_from(transcript)
|
95
|
+
@transcript = transcript
|
96
|
+
@type.currentNo = transcript.identify
|
97
|
+
@short.currentNo = transcript.shortName
|
98
|
+
@exp.text = EXPLANATION_TEXT[@short.currentNo]
|
99
|
+
@show.text = LOCATION_TEXT[@short.currentNo]
|
100
|
+
@show2.text = LOCATION2_TEXT[@short.currentNo]
|
101
|
+
parent = transcript.map.window
|
102
|
+
end
|
103
|
+
|
104
|
+
def copy_to()
|
105
|
+
@transcript.identify = @type.currentNo
|
106
|
+
@transcript.shortName = @short.currentNo
|
107
|
+
@exp.text = EXPLANATION_TEXT[@short.currentNo]
|
108
|
+
@show.text = LOCATION_TEXT[@short.currentNo]
|
109
|
+
@show2.text = LOCATION2_TEXT[@short.currentNo]
|
110
|
+
end
|
111
|
+
|
112
|
+
def initialize(transcript)
|
113
|
+
map = transcript.map
|
114
|
+
pos = [40, 40]
|
115
|
+
maxW = map.window.width - 390
|
116
|
+
maxH = map.window.height - 300
|
117
|
+
pos[0] = maxW if pos[0] > maxW
|
118
|
+
pos[1] = maxH if pos[1] > maxH
|
119
|
+
|
120
|
+
decor = DECOR_TITLE|DECOR_BORDER|DECOR_CLOSE
|
121
|
+
super( map.window, 'Transcript Options', decor, pos[0], pos[1], 0, 0 )
|
122
|
+
|
123
|
+
mainFrame = FXVerticalFrame.new(self,
|
124
|
+
FRAME_SUNKEN|FRAME_THICK|
|
125
|
+
LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
126
|
+
|
127
|
+
frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
|
128
|
+
FXLabel.new(frame, "Transcript Style: ", nil, 0, LAYOUT_FILL_X)
|
129
|
+
pane = FXPopup.new(self)
|
130
|
+
SHORTNAME_TYPE.each { |t|
|
131
|
+
FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
|
132
|
+
}
|
133
|
+
@short = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
|
134
|
+
JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
|
135
|
+
LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
|
136
|
+
|
137
|
+
|
138
|
+
frame = FXHorizontalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
|
139
|
+
FXLabel.new(frame, "Identify Locations: ", nil, 0, LAYOUT_FILL_X)
|
140
|
+
pane = FXPopup.new(self)
|
141
|
+
IDENTIFY_TYPE.each { |t|
|
142
|
+
FXOption.new(pane, t, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
|
143
|
+
}
|
144
|
+
@type = FXOptionMenu.new(frame, pane, FRAME_RAISED|FRAME_THICK|
|
145
|
+
JUSTIFY_HZ_APART|ICON_AFTER_TEXT|
|
146
|
+
LAYOUT_CENTER_X|LAYOUT_CENTER_Y)
|
147
|
+
|
148
|
+
|
149
|
+
|
150
|
+
frame = FXVerticalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
|
151
|
+
FXLabel.new(frame, "Explanation: ", nil, 0, LAYOUT_FILL_X)
|
152
|
+
@exp = FXText.new(frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
153
|
+
@exp.visibleRows = 4
|
154
|
+
@exp.visibleColumns = 60
|
155
|
+
@exp.backColor = mainFrame.backColor
|
156
|
+
@exp.disable
|
157
|
+
|
158
|
+
frame = FXVerticalFrame.new(mainFrame, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
|
159
|
+
FXLabel.new(frame, "Sample Verbose Mode: ", nil, 0, LAYOUT_FILL_X)
|
160
|
+
@show = FXText.new(frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
161
|
+
@show.visibleRows = 9
|
162
|
+
@show.visibleColumns = 60
|
163
|
+
@show.disable
|
164
|
+
FXLabel.new(frame, "Sample Brief Mode: ", nil, 0, LAYOUT_FILL_X)
|
165
|
+
@show2 = FXText.new(frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
166
|
+
@show2.visibleRows = 3
|
167
|
+
@show2.visibleColumns = 60
|
168
|
+
@show2.disable
|
169
|
+
|
170
|
+
@type.connect(SEL_COMMAND) { copy_to }
|
171
|
+
@short.connect(SEL_COMMAND) { copy_to }
|
172
|
+
|
173
|
+
copy_from(transcript)
|
174
|
+
end
|
175
|
+
end
|
@@ -12,7 +12,7 @@
|
|
12
12
|
#
|
13
13
|
class TranscriptReader
|
14
14
|
|
15
|
-
TRANSCRIPT = /^(?:Start of a transcript of|Here begins a transcript of
|
15
|
+
TRANSCRIPT = /^(?:Start of a transcript of|Here begins a transcript of interaction with (.*)|Here begins a transcript of interaction with)/
|
16
16
|
|
17
17
|
# PROMPT = /^>\s*/
|
18
18
|
LOOK = /^l(ook)?/i
|
@@ -60,6 +60,9 @@ class TranscriptReader
|
|
60
60
|
/\bblock\sthe\sway/i,
|
61
61
|
/\byou\scan\sonly\sgo\s/i,
|
62
62
|
/\byou\scan\sgo\sonly\s/i,
|
63
|
+
/\bimpenetrable\b/i,
|
64
|
+
/\bbars\syour\sway/i,
|
65
|
+
/\bthere's\s.*in\s(?:your|the)\sway/i
|
63
66
|
]
|
64
67
|
|
65
68
|
# Closed exit replies
|
@@ -67,15 +70,22 @@ class TranscriptReader
|
|
67
70
|
/door\s+is\s+closed/i,
|
68
71
|
]
|
69
72
|
|
70
|
-
# remove things like (on the bed)
|
73
|
+
# remove things like (on the bed) from short room name
|
71
74
|
PREPOSITION = "(?:in|on|under|behind|inside|\w+ing)"
|
72
75
|
NAME_REMOVE = /(\s+\(#{PREPOSITION}\s+.+\)|,\s+#{PREPOSITION}\s+[^\,\.]+)/
|
76
|
+
|
77
|
+
# not a room name if it has any of this.
|
73
78
|
NAME_INVALID = /--|[:;\*\[\]\|\+\=!\.\?\000<>]/
|
79
|
+
|
80
|
+
# Salutations and other words with periods that can appear as name of room
|
74
81
|
SALUT = '(Mr|Mr?s|Miss|Jr|Sr|St|Dr|Ave|Inc)'
|
75
82
|
SALUTATIONS = /\b#{SALUT}\./
|
83
|
+
|
84
|
+
# Maximum length of room name. Otherwise, a sentence we ignore.
|
76
85
|
NAME_MAXWORDS = 20
|
77
|
-
|
78
|
-
|
86
|
+
|
87
|
+
# word list that may be uncapitalized in room name
|
88
|
+
NAME_UNCAP = /^(?:of|on|to|with|by|a|in|the|at|under)$/i
|
79
89
|
|
80
90
|
# Default room description recognition parameters.
|
81
91
|
DESC_MINWORDS = 20
|
@@ -236,25 +246,32 @@ class TranscriptReader
|
|
236
246
|
#
|
237
247
|
|
238
248
|
DIRS = {
|
249
|
+
# SWD added variants used in e.g. YAGWAD
|
250
|
+
'north-east' => 1, 'south-east' => 3, 'south-west' => 5, 'north-west' => 7,
|
251
|
+
# Usual directions
|
239
252
|
'north' => 0, 'northeast' => 1, 'east' => 2, 'southeast' => 3,
|
240
|
-
'south' => 4, 'southwest' => 5, 'west' => 6, 'northwest' => 7
|
253
|
+
'south' => 4, 'southwest' => 5, 'west' => 6, 'northwest' => 7,
|
241
254
|
}
|
242
255
|
|
243
|
-
|
256
|
+
# SWD: hack: the variants with dashes must come first
|
257
|
+
# (so that regexes matches 'north-east' in preference to 'north'),
|
258
|
+
# so we manually prepend their names. The duplication is harmless,
|
259
|
+
# it just makes the regexes slightly slower in the non-match case.
|
260
|
+
DIR = '(' + DIRS.keys.join('\b|') + ')'
|
244
261
|
OR = '(?:and|or)'
|
245
262
|
|
246
263
|
EXITS_REGEX =
|
247
264
|
[
|
248
265
|
# paths lead west and north
|
249
|
-
/(run|bears|lead|wander|winds|go)\s+#{DIR}\s+#{OR}\s+#{DIR}\b/i,
|
266
|
+
/(run|bears|lead|wander|winds|go|continues)\s+#{DIR}\s+#{OR}\s+#{DIR}\b/i,
|
250
267
|
# to the east or west
|
251
|
-
/to\s+the
|
268
|
+
/to\s+the#{DIR}\s+#{OR}\s+(to\s+the\s+)?#{DIR}\b/i,
|
252
269
|
# You can go south
|
253
|
-
/you\s+can\s+go
|
270
|
+
/you\s+can\s+go#{DIR}\b/i,
|
254
271
|
# to the east
|
255
272
|
/to\s+the\s+#{DIR}\b/i,
|
256
273
|
# east-west corridor
|
257
|
-
/[\.\s+]#{DIR}[\/-]#{DIR}\
|
274
|
+
/[\.\s+]#{DIR}[\/-]#{DIR}\s+(passage|corridor)/i,
|
258
275
|
# East is the postoffice
|
259
276
|
/\b#{DIR}\s+is/i,
|
260
277
|
# Directly north
|
@@ -355,7 +372,11 @@ class TranscriptReader
|
|
355
372
|
end
|
356
373
|
|
357
374
|
if cmd =~ UNDO
|
358
|
-
@moves.
|
375
|
+
if @moves.size < 2
|
376
|
+
@here = nil # out of moves, no clue where we are
|
377
|
+
else
|
378
|
+
@moves.pop
|
379
|
+
end
|
359
380
|
else
|
360
381
|
move = { }
|
361
382
|
|
@@ -579,7 +600,7 @@ class TranscriptReader
|
|
579
600
|
# set current room.
|
580
601
|
if move[:look] or not @here
|
581
602
|
if move[:look] and name =~ DARKNESS
|
582
|
-
@here = find_room(name, desc)
|
603
|
+
@here = find_room(name, desc) if @here and not @here.darkness
|
583
604
|
else
|
584
605
|
@here = find_room(name, desc)
|
585
606
|
end
|
@@ -607,7 +628,7 @@ class TranscriptReader
|
|
607
628
|
idx = DIRMAP[dir] || ODIRMAP[dir]
|
608
629
|
# Moving to a dark room is special. We verify the exit to see
|
609
630
|
# if it was already moving to a dark room (in which case it
|
610
|
-
# becomes there) or if it was moving to some other room (in
|
631
|
+
# becomes "there") or if it was moving to some other room (in
|
611
632
|
# which case we flag it as dark and make it there)
|
612
633
|
if idx and @here[idx]
|
613
634
|
c = @here[idx]
|
@@ -831,8 +852,8 @@ class TranscriptReader
|
|
831
852
|
|
832
853
|
def capitalize_room(line)
|
833
854
|
words = line.split(' ')
|
834
|
-
words.
|
835
|
-
if w =~
|
855
|
+
words.each_with_index { |w, idx|
|
856
|
+
if idx > 0 and w =~ NAME_UNCAP
|
836
857
|
w.downcase!
|
837
858
|
else
|
838
859
|
w.capitalize!
|
@@ -931,6 +952,9 @@ class TranscriptReader
|
|
931
952
|
# Create a new room
|
932
953
|
#
|
933
954
|
def new_room( move, name, desc, dir = nil, from = nil, go = nil )
|
955
|
+
b = nil
|
956
|
+
dark = false
|
957
|
+
|
934
958
|
if not from
|
935
959
|
debug "FROM undefined. Increase section #{name}"
|
936
960
|
@section += 1
|
@@ -939,6 +963,7 @@ class TranscriptReader
|
|
939
963
|
r.name = name
|
940
964
|
else
|
941
965
|
|
966
|
+
darkexits = []
|
942
967
|
if name =~ DARKNESS
|
943
968
|
dark = true
|
944
969
|
else
|
@@ -946,11 +971,12 @@ class TranscriptReader
|
|
946
971
|
if from[dir]
|
947
972
|
# oops, we had a connection there.
|
948
973
|
c = from[dir]
|
949
|
-
b = c.
|
974
|
+
b = c.opposite(from)
|
950
975
|
if b and b.name =~ DARKNESS
|
951
976
|
# Was it a dark room that is now lit?
|
952
977
|
# if so, set dark flag and delete dark room
|
953
|
-
@map.
|
978
|
+
@map.delete_connection(c)
|
979
|
+
@map.delete_room_only(b)
|
954
980
|
dark = true
|
955
981
|
c = nil
|
956
982
|
end
|
@@ -962,16 +988,25 @@ class TranscriptReader
|
|
962
988
|
dx, dy = Room::DIR_TO_VECTOR[dir]
|
963
989
|
x += dx
|
964
990
|
y += dy
|
965
|
-
@map.shift(x, y, dx, dy) if not @map.free?(x, y)
|
991
|
+
@map.shift(x, y, dx, dy) if not @map.free?(x, y)
|
966
992
|
|
967
|
-
if not @map.free?(x, y)
|
968
|
-
raise "Error when shifting rooms"
|
969
|
-
end
|
970
993
|
|
971
994
|
debug "+++ New Room #{name} from #{from}"
|
972
995
|
r = @map.new_room(x, y)
|
973
996
|
r.name = name
|
974
997
|
r.darkness = dark
|
998
|
+
if b and dark
|
999
|
+
b.exits.each_with_index { |de, didx|
|
1000
|
+
next unless de
|
1001
|
+
@map.sections[@map.section].connections << de
|
1002
|
+
r[didx] = de
|
1003
|
+
if de.roomA == b
|
1004
|
+
de.roomA = r
|
1005
|
+
else
|
1006
|
+
de.roomB = r
|
1007
|
+
end
|
1008
|
+
}
|
1009
|
+
end
|
975
1010
|
c = nil
|
976
1011
|
if from[dir]
|
977
1012
|
# oops, we had a connection there.
|
@@ -1087,8 +1122,8 @@ class TranscriptReader
|
|
1087
1122
|
if b.name =~ DARKNESS
|
1088
1123
|
debug "*** REPLACING DARK ROOM ***"
|
1089
1124
|
@map.delete_connection(c)
|
1090
|
-
@map.delete_room(b)
|
1091
1125
|
to.darkness = true
|
1126
|
+
@map.delete_room(b)
|
1092
1127
|
c = nil
|
1093
1128
|
else
|
1094
1129
|
if c.exitAtext != 0
|
@@ -1314,6 +1349,7 @@ class TranscriptReader
|
|
1314
1349
|
loop do
|
1315
1350
|
self.step
|
1316
1351
|
Thread.pass
|
1352
|
+
sleep 3
|
1317
1353
|
end
|
1318
1354
|
}
|
1319
1355
|
@t.run
|
data/maps/anchor.map
CHANGED
Binary file
|
data/maps/building.map
ADDED
Binary file
|
data/maps/distress.map
ADDED
Binary file
|
data/maps/gamlet.map
ADDED
Binary file
|
Binary file
|
data/maps/splashdown.map
CHANGED
Binary file
|
Binary file
|
data/maps/vespers.map
ADDED
Binary file
|
data/maps/xtcontest.map
ADDED
Binary file
|