ifmapper 0.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.
Files changed (87) hide show
  1. data/HISTORY.txt +2 -0
  2. data/IFMapper.gemspec +21 -0
  3. data/IFMapper.rb +27 -0
  4. data/icons/copy.png +0 -0
  5. data/icons/cut.png +0 -0
  6. data/icons/filenew.png +0 -0
  7. data/icons/fileopen.png +0 -0
  8. data/icons/filesave.png +0 -0
  9. data/icons/filesaveas.png +0 -0
  10. data/icons/help.png +0 -0
  11. data/icons/kill.png +0 -0
  12. data/icons/nextpage.png +0 -0
  13. data/icons/paste.png +0 -0
  14. data/icons/prevpage.png +0 -0
  15. data/icons/printicon.png +0 -0
  16. data/icons/redo.png +0 -0
  17. data/icons/saveas.png +0 -0
  18. data/icons/undo.png +0 -0
  19. data/icons/winapp.png +0 -0
  20. data/icons/zoom.png +0 -0
  21. data/lib/IFMapper/Connection.rb +63 -0
  22. data/lib/IFMapper/FXAboutDialogBox.rb +32 -0
  23. data/lib/IFMapper/FXConnection.rb +283 -0
  24. data/lib/IFMapper/FXConnectionDialogBox.rb +126 -0
  25. data/lib/IFMapper/FXMap.rb +1614 -0
  26. data/lib/IFMapper/FXMapDialogBox.rb +51 -0
  27. data/lib/IFMapper/FXMapFileDialog.rb +29 -0
  28. data/lib/IFMapper/FXMapperSettings.rb +45 -0
  29. data/lib/IFMapper/FXMapperWindow.rb +1051 -0
  30. data/lib/IFMapper/FXPage.rb +24 -0
  31. data/lib/IFMapper/FXPageDialogBox.rb +38 -0
  32. data/lib/IFMapper/FXRoom.rb +218 -0
  33. data/lib/IFMapper/FXRoomDialogBox.rb +119 -0
  34. data/lib/IFMapper/FXSearchDialogBox.rb +51 -0
  35. data/lib/IFMapper/FXSpline.rb +54 -0
  36. data/lib/IFMapper/FXWarningBox.rb +45 -0
  37. data/lib/IFMapper/IFMReader.rb +613 -0
  38. data/lib/IFMapper/Map.rb +110 -0
  39. data/lib/IFMapper/PDFMapExporter.rb +315 -0
  40. data/lib/IFMapper/Page.rb +158 -0
  41. data/lib/IFMapper/Room.rb +104 -0
  42. data/maps/Bureaucracy.ifm +75 -0
  43. data/maps/Hollywood_Hijinx.ifm +149 -0
  44. data/maps/Jigsaw.ifm +806 -0
  45. data/maps/LGOP.ifm +705 -0
  46. data/maps/Mercy.ifm +76 -0
  47. data/maps/Planetfall.ifm +186 -0
  48. data/maps/Plundered_Hearts.ifm +251 -0
  49. data/maps/Ralph.ifm +50 -0
  50. data/maps/Robots_of_Dawn.ifm +224 -0
  51. data/maps/Seastalker.ifm +149 -0
  52. data/maps/Sherlock.ifm +209 -0
  53. data/maps/SoFar.ifm +72 -0
  54. data/maps/Starcross.ifm +170 -0
  55. data/maps/Suspended.ifm +82 -0
  56. data/maps/Wishbringer.ifm +277 -0
  57. data/maps/Wishbringer2.ifm +246 -0
  58. data/maps/Zork1.ifm +410 -0
  59. data/maps/Zork2.ifm +150 -0
  60. data/maps/Zork3.ifm +136 -0
  61. data/maps/Zork_Zero.ifm +557 -0
  62. data/maps/anchor.ifm +645 -0
  63. data/maps/atrox.ifm +134 -0
  64. data/maps/awaken.ifm +116 -0
  65. data/maps/babel.ifm +279 -0
  66. data/maps/bse.ifm +150 -0
  67. data/maps/change.ifm +128 -0
  68. data/maps/curses.ifm +307 -0
  69. data/maps/curves.ifm +529 -0
  70. data/maps/edifice.ifm +158 -0
  71. data/maps/frozen.ifm +126 -0
  72. data/maps/glow.ifm +101 -0
  73. data/maps/library.ifm +93 -0
  74. data/maps/mindelec.ifm +89 -0
  75. data/maps/minster.ifm +234 -0
  76. data/maps/muse.ifm +154 -0
  77. data/maps/paperchase.ifm +110 -0
  78. data/maps/space_st.ifm +104 -0
  79. data/maps/stationfall.ifm +320 -0
  80. data/maps/theatre.ifm +182 -0
  81. data/maps/toonesia.ifm +54 -0
  82. data/maps/tortoise.ifm +72 -0
  83. data/maps/vgame.ifm +219 -0
  84. data/maps/weather.ifm +98 -0
  85. data/maps/windhall.ifm +154 -0
  86. data/maps/zebulon.ifm +68 -0
  87. metadata +144 -0
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'IFMapper/Room'
4
+ require 'IFMapper/Page'
5
+
6
+ class Map
7
+ attr_accessor :name
8
+ attr_accessor :creator
9
+ attr_accessor :date
10
+
11
+ attr_reader :page
12
+ attr_accessor :pages
13
+
14
+ attr_accessor :width
15
+ attr_accessor :height
16
+
17
+ def page=(x)
18
+ x = 0 if x < 0
19
+ x = @pages.size - 1 if x >= @pages.size
20
+ @page = x
21
+ end
22
+
23
+ #
24
+ # Used for loading class with Marshal
25
+ #
26
+ def marshal_load(v)
27
+ @name = v.shift
28
+ @creator = v.shift
29
+ @date = v.shift
30
+ @page = v.shift
31
+ @pages = v.shift
32
+ @width = v.shift
33
+ @height = v.shift
34
+ end
35
+
36
+ #
37
+ # Used for saving class with Marshal
38
+ #
39
+ def marshal_dump
40
+ [ @name, @creator, @date, @page, @pages, @width, @height ]
41
+ end
42
+
43
+ def initialize(name)
44
+ @page = 0
45
+ @name = name
46
+ @creator = ''
47
+
48
+ # if printing sideways
49
+ @width = 20
50
+ @height = 20
51
+
52
+ # Add at least one page
53
+ @pages = []
54
+ new_page
55
+ end
56
+
57
+ def copy(b)
58
+ @page = b.page
59
+ @pages = b.pages
60
+ @name = b.name
61
+ @creator = b.creator
62
+ @width = b.width
63
+ @height = b.height
64
+ @date = b.date
65
+ end
66
+
67
+ def delete_connection(c)
68
+ @pages[@page].delete_connection(c)
69
+ end
70
+
71
+ def delete_connection_at( idx )
72
+ @pages[@page].delete_connection_at(idx)
73
+ end
74
+
75
+
76
+ def new_connection( roomA, exitA, roomB, exitB = nil )
77
+ @pages[@page].new_connection(roomA, exitA, roomB, exitB)
78
+ end
79
+
80
+
81
+ def delete_room_at(idx)
82
+ @pages[@page].delete_room_at(idx)
83
+ end
84
+
85
+ def delete_room(r)
86
+ @pages[@page].delete_room(r)
87
+ end
88
+
89
+ def new_room( x, y )
90
+ @pages[@page].new_room(x, y)
91
+ end
92
+
93
+ def new_page
94
+ @pages.push( Page.new )
95
+ @page = @pages.size - 1
96
+ end
97
+
98
+ def _check_page
99
+ @page = @pages.size - 1 if @page >= @pages.size
100
+ new_page if @pages.size == 0
101
+ end
102
+
103
+ def delete_page_at(idx)
104
+ @pages.delete_at(idx)
105
+ _check_page
106
+ end
107
+
108
+ end
109
+
110
+
@@ -0,0 +1,315 @@
1
+
2
+ begin
3
+ require 'tmpdir'
4
+ rescue => e
5
+ raise "Please install 'tmpdir' library. This is needed for printing."
6
+ end
7
+
8
+ begin
9
+ require 'pdf/writer'
10
+ rescue => e
11
+ raise "Please install 'pdf writer' library for Acrobat PDF support."
12
+ end
13
+
14
+ PDF_ZOOM = 0.5
15
+ PDF_ROOM_WIDTH = W * PDF_ZOOM # 60
16
+ PDF_ROOM_HEIGHT = H * PDF_ZOOM # 37.5
17
+ PDF_ROOM_WS = WS * PDF_ZOOM
18
+ PDF_ROOM_HS = HS * PDF_ZOOM
19
+ PDF_MARGIN = 20
20
+
21
+
22
+ #
23
+ # Open all the map class and add all pdf methods there
24
+ # Gotta love Ruby's flexibility to just inject in new methods.
25
+ #
26
+ class FXConnection
27
+ def _cvt_pt(p, opts)
28
+ x = (p[0] - WW / 2.0) / WW.to_f
29
+ y = (p[1] - HH / 2.0) / HH.to_f
30
+ x = x * opts['ww'] + opts['ws_2'] + opts['margin_2'] + opts['w'] / 2.0
31
+ y = (opts['height'] - y) * opts['hh'] + opts['hs_2'] + opts['margin_2'] + opts['hs']
32
+ return [x, y]
33
+ end
34
+
35
+ def pdf_draw_arrow(pdf, opts, x1, y1, x2, y2)
36
+ return if @dir == BOTH
37
+
38
+ pt1, d = _arrow_info( x1, y1, x2, y2, 0.5 )
39
+
40
+ p = []
41
+ p << PDF::Writer::PolygonPoint.new( pt1[0], pt1[1] )
42
+ p << PDF::Writer::PolygonPoint.new( pt1[0] + d[0], pt1[1] - d[1] )
43
+ p << PDF::Writer::PolygonPoint.new( pt1[0] + d[1], pt1[1] + d[0] )
44
+ pdf.fill_color Color::RGB::Black
45
+ pdf.polygon(p).fill
46
+ end
47
+
48
+ def pdf_draw_complex_as_bspline( pdf, opts )
49
+ p = []
50
+ p << _cvt_pt(@pts[0], opts)
51
+ p << p[0]
52
+ p << p[0]
53
+ @pts.each { |pt|
54
+ p << _cvt_pt(pt, opts)
55
+ }
56
+ p << p[-1]
57
+ p << p[-1]
58
+ p << p[-1]
59
+ return FXSpline::bspline(p)
60
+ end
61
+
62
+ def pdf_draw_complex_as_lines( pdf, opts )
63
+ p = []
64
+ maxy = opts['height'] * opts['hh'] + opts['hs_2'] + opts['margin_2']
65
+ @pts.each { |pt|
66
+ p << [ pt[0] * PDF_ZOOM, maxy - pt[1] * PDF_ZOOM ]
67
+ }
68
+ return p
69
+ end
70
+
71
+ def pdf_draw_complex( pdf, opts )
72
+ if opts['Paths as Curves']
73
+ p = pdf_draw_complex_as_bspline( pdf, opts )
74
+ else
75
+ p = pdf_draw_complex_as_lines( pdf, opts )
76
+ end
77
+ pdf.move_to( p[0][0], p[0][1] )
78
+ p.each { |pt| pdf.line_to( pt[0], pt[1] ) }
79
+ pdf.stroke
80
+
81
+ x1, y1 = [p[0][0], p[0][1]]
82
+ x2, y2 = [p[-1][0], p[-1][1]]
83
+ pdf_draw_arrow(pdf, opts, x1, y1, x2, y2)
84
+ end
85
+
86
+ def pdf_draw_simple(pdf, opts)
87
+ return if not @roomB # PDF does not print unfinished complex connections
88
+
89
+ dir = @roomA.exits.index(self)
90
+ x1, y1 = @roomA.pdf_corner(pdf, opts, self, dir)
91
+ x2, y2 = @roomB.pdf_corner(pdf, opts, self)
92
+ pdf.move_to(x1, y1)
93
+ pdf.line_to(x2, y2).stroke
94
+ pdf_draw_arrow(pdf, opts, x1, y1, x2, y2)
95
+ if @type == LOCKED_DOOR
96
+ v = [ (x2-x1)*0.25, (y2-y1)*0.25 ]
97
+ m = [ (x2+x1)/2, (y2+y1)/2 ]
98
+ x1, y1 = [m[0] + v[1], m[1] - v[0]]
99
+ x2, y2 = [m[0] - v[1], m[1] + v[0]]
100
+ pdf.move_to(x1, y1)
101
+ pdf.line_to(x2, y2).stroke
102
+ end
103
+ end
104
+
105
+ def pdf_draw(pdf, opts)
106
+ # pdf_draw_exit_text(pdf, opts)
107
+ if @type == SPECIAL
108
+ s = PDF::Writer::StrokeStyle.new(2, :dash => {
109
+ :pattern => [2],
110
+ :phase => [1]
111
+ } )
112
+ else
113
+ s = PDF::Writer::StrokeStyle.new(2,
114
+ :cap => :butt,
115
+ :join => :miter,
116
+ :dash => PDF::Writer::StrokeStyle::SOLID_LINE )
117
+ end
118
+ pdf.stroke_style( s )
119
+ pdf.stroke_color Color::RGB::Black
120
+ pdf.fill_color Color::RGB::White
121
+ if @pts.size > 0
122
+ pdf_draw_complex(pdf, opts)
123
+ else
124
+ pdf_draw_simple(pdf, opts)
125
+ end
126
+ end
127
+ end
128
+
129
+
130
+ class FXRoom
131
+ def pdf_corner( pdf, opts, c, idx = nil )
132
+ x, y = _corner(c, idx)
133
+ y = -y
134
+
135
+ ww = opts['ww']
136
+ hh = opts['hh']
137
+ w = opts['w']
138
+ h = opts['h']
139
+
140
+ ry = opts['height'] - @y
141
+ x = @x * ww + opts['ws_2'] + opts['margin_2'] + x * w
142
+ y = ry * hh + opts['hs_2'] + h + opts['margin_2'] + y * h
143
+ return [x, y]
144
+ end
145
+
146
+
147
+ def pdf_draw_box( pdf, opts )
148
+ x = @x * opts['ww'] + opts['ws_2'] + opts['margin_2']
149
+ y = (opts['height'] - @y) * opts['hh'] + opts['hs_2'] + opts['margin_2']
150
+
151
+ s = PDF::Writer::StrokeStyle::DEFAULT
152
+ pdf.stroke_style( s )
153
+
154
+ if @darkness
155
+ pdf.fill_color( Color::RGB::Gray )
156
+ else
157
+ pdf.fill_color( Color::RGB::White )
158
+ end
159
+
160
+ pdf.rectangle(x, y, opts['w'], opts['h']).fill_stroke
161
+ end
162
+
163
+ def pdf_draw_name(pdf, opts)
164
+ # We could also use pdf_corner(7) here
165
+ x = @x * opts['ww'] + opts['margin_2'] + opts['ws_2'] + 2
166
+ y = opts['height'] - @y
167
+ y = y * opts['hh'] + opts['margin_2'] + opts['hs_2'] + opts['h'] - 10
168
+ font_size = 8
169
+ pdf.stroke_color(Color::RGB::Black)
170
+ pdf.fill_color(Color::RGB::Black)
171
+ text = @name
172
+ while text != ''
173
+ text = pdf.add_text_wrap(x, y, opts['w'], text, font_size)
174
+ y -= font_size
175
+ end
176
+ end
177
+
178
+ def pdf_draw( pdf, opts, idx )
179
+ pdf_draw_box( pdf, opts )
180
+ pdf_draw_name( pdf, opts )
181
+ end
182
+ end
183
+
184
+
185
+
186
+ class FXPage
187
+
188
+ def pdf_draw_grid(pdf, opts, w, h )
189
+ (0...w).each { |xx|
190
+ (0...h).each { |yy|
191
+ x = xx * opts['ww'] + opts['ws_2'] + opts['margin_2']
192
+ y = yy * opts['hh'] + opts['hs_2'] + opts['margin_2']
193
+ pdf.rectangle(x, y, opts['w'], opts['h']).stroke
194
+ }
195
+ }
196
+ end
197
+
198
+ def pdf_draw_mapname( pdf, opts, mapname )
199
+ return if not mapname or mapname == ''
200
+ pdf.text( mapname,
201
+ :font_size => 24,
202
+ :justification => :center
203
+ )
204
+ end
205
+
206
+ def pdf_draw_pagename( pdf, opts )
207
+ return if not @name or @name == ''
208
+ pdf.text( @name,
209
+ :font_size => 16,
210
+ :justification => :center
211
+ )
212
+ end
213
+
214
+
215
+ def pdf_draw(pdf, opts, mapname )
216
+ width, height = rooms_width_height
217
+
218
+ #
219
+ # Determine if better to print page in landscape mode
220
+ #
221
+ landscape = false
222
+ if landscape
223
+ pdf.rotate_axis(90.0)
224
+ pdf.translate_axis( 0, -pdf.page_width )
225
+ end
226
+
227
+ # Use times-roman as font
228
+ pdf.select_font 'Times-Roman'
229
+ pdf.stroke_color(Color::RGB::Black)
230
+ pdf.fill_color(Color::RGB::Black)
231
+
232
+ pdf_draw_mapname( pdf, opts, mapname )
233
+ pdf_draw_pagename( pdf, opts )
234
+
235
+ # For testing purposes only, draw grid of boxes
236
+ # pdf_draw_grid( pdf, opts, width, height )
237
+
238
+ @connections.each { |c| c.pdf_draw( pdf, opts ) }
239
+ @rooms.each_with_index { |r, idx| r.pdf_draw( pdf, opts, idx) }
240
+ end
241
+ end
242
+
243
+
244
+ class FXMap
245
+
246
+ def pdf_draw_pages( pdf, opts )
247
+ old_page = @page
248
+ @pages.each_with_index { |p, idx|
249
+ pdf.start_new_page if idx > 0
250
+ @page = idx
251
+ # For each page, we need to regenerate the pathmap so that complex
252
+ # paths will come out ok.
253
+ create_pathmap
254
+ # Now, we draw it
255
+ p.pdf_draw(pdf, opts, @name)
256
+ }
257
+
258
+ # Restore original viewing page
259
+ @page = old_page
260
+ create_pathmap
261
+ end
262
+
263
+ def pdf_export(pdffile = Dir::tmpdir + "/ifmap.pdf", printer = nil)
264
+
265
+ paper = 'LETTER'
266
+ if printer
267
+ case printer.mediasize
268
+ when FXPrinter::MEDIA_LEGAL
269
+ paper = 'LEGAL'
270
+ when FXPrinter::MEDIA_A4
271
+ paper = 'A4'
272
+ when FXPrinter::MEDIA_ENVELOPE
273
+ paper = 'ENVELOPE'
274
+ when FXPrinter::MEDIA_CUSTOM
275
+ raise "Sorry, custom paper not supported"
276
+ end
277
+ end
278
+
279
+ # Open a new PDF writer with paper selected
280
+ pdf = PDF::Writer.new :paper => paper
281
+
282
+
283
+ pdf_options = @options.dup
284
+ pdf_options.merge!(
285
+ {
286
+ 'ww' => PDF_ROOM_WIDTH + PDF_ROOM_WS,
287
+ 'hh' => PDF_ROOM_HEIGHT + PDF_ROOM_HS,
288
+ 'w' => PDF_ROOM_WIDTH,
289
+ 'h' => PDF_ROOM_HEIGHT,
290
+ 'ws' => PDF_ROOM_WS,
291
+ 'hs' => PDF_ROOM_HS,
292
+ 'ws_2' => PDF_ROOM_WS / 2.0,
293
+ 'hs_2' => PDF_ROOM_HS / 2.0,
294
+ 'margin' => PDF_MARGIN,
295
+ 'margin_2' => PDF_MARGIN / 2.0,
296
+ 'width' => @width - 1,
297
+ 'height' => @height - 1,
298
+ }
299
+ )
300
+
301
+
302
+ begin
303
+ # See if it is possible to pack several map sections (pages) into
304
+ # a single print page.
305
+ # pack_sections
306
+ pdf_draw_pages(pdf, pdf_options)
307
+ p "Saving pdf to '#{pdffile}'..."
308
+ pdf.save_as(pdffile)
309
+ rescue => e
310
+ p e
311
+ p e.backtrace
312
+ # raise e
313
+ end
314
+ end
315
+ end
@@ -0,0 +1,158 @@
1
+
2
+
3
+ require 'IFMapper/Connection'
4
+ require 'IFMapper/Room'
5
+
6
+ class Page
7
+ attr_accessor :rooms
8
+ attr_accessor :connections
9
+ attr_accessor :name
10
+
11
+ def marshal_load(v)
12
+ @rooms = v[0]
13
+ @connections = v[1]
14
+ @name = v[2]
15
+ end
16
+
17
+ def marshal_dump
18
+ return [ @rooms, @connections, @name ]
19
+ end
20
+
21
+ #
22
+ # Return the number of rooms in width and height for this page
23
+ #
24
+ def rooms_width_height
25
+ minXY, maxXY = min_max_rooms
26
+ return [
27
+ maxXY[0] - minXY[0] + 1,
28
+ maxXY[1] - minXY[1] + 1
29
+ ]
30
+ end
31
+
32
+ #
33
+ # Return the min and max coordinates of all rooms in page
34
+ #
35
+ def min_max_rooms
36
+ return [0, 0] if @rooms.empty?
37
+
38
+ minXY = [ @rooms[0].x, @rooms[0].y ]
39
+ maxXY = minXY.dup
40
+ @rooms.each { |r|
41
+ minXY[0] = r.x if r.x < minXY[0]
42
+ minXY[1] = r.y if r.y < minXY[1]
43
+ maxXY[0] = r.x if r.x > maxXY[0]
44
+ maxXY[1] = r.y if r.y > maxXY[1]
45
+ }
46
+ return [ minXY, maxXY ]
47
+ end
48
+
49
+
50
+ def delete_connection(c)
51
+ a = c.roomA
52
+ if a
53
+ e = a.exits.index(c)
54
+ a[e] = nil if e
55
+ end
56
+ b = c.roomB
57
+ if b
58
+ e = b.exits.rindex(c)
59
+ b[e] = nil if e
60
+ end
61
+ @connections.delete(c)
62
+ end
63
+
64
+ def delete_connection_at( idx )
65
+ c = @connections[idx]
66
+
67
+ a = c.roomA
68
+ if a
69
+ e = a.exits.index(c)
70
+ a[e] = nil if e
71
+ end
72
+ b = c.roomB
73
+ if b
74
+ e = b.exits.rindex(c)
75
+ b[e] = nil if e
76
+ end
77
+ @connections.delete_at(idx)
78
+ end
79
+
80
+ def _new_connection(c, roomA, exitA, roomB, exitB)
81
+ exitA = roomA.exit_to(roomB) if not exitA
82
+ if not exitA
83
+ err = <<"EOF"
84
+ No exit given or guessed to connect:
85
+ Room #{roomA} (#{roomA.x}, #{roomA.y})
86
+ Room #{roomB} (#{roomB.x}, #{roomB.y})
87
+ EOF
88
+ raise err
89
+ end
90
+
91
+ if roomA[exitA]
92
+ if not @connections.include?(roomA[exitA])
93
+ raise "room exit filled but not in page"
94
+ end
95
+ raise "room exit #{exitA} for #{roomA} is filled"
96
+ end
97
+
98
+ roomA[exitA] = c
99
+
100
+ if roomB and not exitB
101
+ dx, dy = Room::DIR_TO_VECTOR[exitA]
102
+ x = roomA.x + dx
103
+ y = roomA.y + dy
104
+ if roomB.x == x and roomB.y == y
105
+ exitB = (exitA + 4) % 8
106
+ else
107
+ dx = x - roomB.x
108
+ dy = y - roomB.y
109
+ exitB = roomB.vector_to_dir(dx, dy)
110
+ end
111
+ end
112
+
113
+ if roomB and roomB[exitB] and roomB[exitB] != c
114
+ raise "room exit #{exitB} for #{roomB} is filled"
115
+ end
116
+ roomB[exitB] = c if roomB
117
+
118
+ @connections.push( c )
119
+ return c
120
+ end
121
+
122
+ def new_connection( roomA, exitA, roomB, exitB = nil )
123
+ c = Connection.new( roomA, roomB )
124
+ _new_connection(c, roomA, exitA, roomB, exitB )
125
+ end
126
+
127
+ def delete_room_at(idx)
128
+ r = @rooms[idx]
129
+ r.exits.each { |e|
130
+ next if not e
131
+ delete_connection(e)
132
+ }
133
+ @rooms.delete_at(idx)
134
+ end
135
+
136
+ def delete_room(r)
137
+ r.exits.each { |e|
138
+ next if not e
139
+ delete_connection(e)
140
+ }
141
+ @rooms.delete(r)
142
+ end
143
+
144
+ def _new_room( r, x, y )
145
+ @rooms.push(r)
146
+ return r
147
+ end
148
+
149
+ def new_room( x, y )
150
+ r = Room.new( x, y, 'New Location' )
151
+ return _new_room(r, x, y)
152
+ end
153
+
154
+ def initialize()
155
+ @rooms = []
156
+ @connections = []
157
+ end
158
+ end