ifmapper 1.0.0 → 1.0.6

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 (218) hide show
  1. data/HISTORY.txt +648 -627
  2. data/IFMapper.gemspec +29 -28
  3. data/IFMapper.rbw +31 -31
  4. data/TODO.txt +8 -7
  5. data/bin/IFMapper +31 -31
  6. data/docs/en/index.html +0 -0
  7. data/docs/en/start.html +3 -2
  8. data/docs/en/start.html~ +516 -0
  9. data/docs/es/index.html +0 -0
  10. data/docs/es/start.html +13 -14
  11. data/docs/es/start.html~ +1280 -0
  12. data/docs/images/IFMapper_main.gif +0 -0
  13. data/docs/images/automap.gif +0 -0
  14. data/docs/images/complex_connection.gif +0 -0
  15. data/docs/images/connection.gif +0 -0
  16. data/docs/images/connection_menu.gif +0 -0
  17. data/docs/images/room_description.gif +0 -0
  18. data/docs/images/room_small.gif +0 -0
  19. data/icons/copy.png +0 -0
  20. data/icons/cut.png +0 -0
  21. data/icons/filenew.png +0 -0
  22. data/icons/fileopen.png +0 -0
  23. data/icons/filesave.png +0 -0
  24. data/icons/filesaveas.png +0 -0
  25. data/icons/help.png +0 -0
  26. data/icons/kill.png +0 -0
  27. data/icons/nextpage.png +0 -0
  28. data/icons/paste.png +0 -0
  29. data/icons/prevpage.png +0 -0
  30. data/icons/printicon.png +0 -0
  31. data/icons/redo.png +0 -0
  32. data/icons/room_e.gif +0 -0
  33. data/icons/room_e.xpm +0 -0
  34. data/icons/room_n.gif +0 -0
  35. data/icons/room_n.xpm +0 -0
  36. data/icons/room_ne.gif +0 -0
  37. data/icons/room_ne.xpm +0 -0
  38. data/icons/room_nw.gif +0 -0
  39. data/icons/room_nw.xpm +0 -0
  40. data/icons/room_s.gif +0 -0
  41. data/icons/room_s.xpm +0 -0
  42. data/icons/room_se.gif +0 -0
  43. data/icons/room_se.xpm +0 -0
  44. data/icons/room_sw.gif +0 -0
  45. data/icons/room_sw.xpm +0 -0
  46. data/icons/room_w.gif +0 -0
  47. data/icons/room_w.xpm +0 -0
  48. data/icons/saveas.png +0 -0
  49. data/icons/undo.png +0 -0
  50. data/icons/winapp.png +0 -0
  51. data/icons/zoom.png +0 -0
  52. data/lib/IFMapper/AStar.rb +250 -250
  53. data/lib/IFMapper/Connection.rb +202 -202
  54. data/lib/IFMapper/FXAboutDialogBox.rb +32 -32
  55. data/lib/IFMapper/FXConnection.rb +364 -364
  56. data/lib/IFMapper/FXConnectionDialogBox.rb +124 -124
  57. data/lib/IFMapper/FXDCPostscript.rb +404 -404
  58. data/lib/IFMapper/FXDCPrint.rb +15 -15
  59. data/lib/IFMapper/FXItemList.rb +108 -0
  60. data/lib/IFMapper/FXMap.rb +2147 -2116
  61. data/lib/IFMapper/FXMapColorBox.rb +88 -88
  62. data/lib/IFMapper/FXMapDialogBox.rb +127 -127
  63. data/lib/IFMapper/FXMapFileDialog.rb +34 -34
  64. data/lib/IFMapper/FXMapperSettings.rb +206 -205
  65. data/lib/IFMapper/FXMapperWindow.rb +1592 -1571
  66. data/lib/IFMapper/FXPDFMapExporterOptionsDialogBox.rb +46 -0
  67. data/lib/IFMapper/FXRoom.rb +263 -263
  68. data/lib/IFMapper/FXRoomDialogBox.rb +159 -159
  69. data/lib/IFMapper/FXRoomList.rb +95 -95
  70. data/lib/IFMapper/FXSearchDialogBox.rb +51 -51
  71. data/lib/IFMapper/FXSection.rb +33 -33
  72. data/lib/IFMapper/FXSectionDialogBox.rb +38 -38
  73. data/lib/IFMapper/FXSpline.rb +52 -52
  74. data/lib/IFMapper/FXWarningBox.rb +51 -50
  75. data/lib/IFMapper/GUEReader.rb +445 -445
  76. data/lib/IFMapper/IFMReader.rb +584 -584
  77. data/lib/IFMapper/IFMWriter.rb +245 -227
  78. data/lib/IFMapper/Inform7Writer.rb +579 -573
  79. data/lib/IFMapper/InformReader.rb +478 -478
  80. data/lib/IFMapper/InformWriter.rb +364 -359
  81. data/lib/IFMapper/Map.rb +202 -200
  82. data/lib/IFMapper/MapPrinting.rb +162 -162
  83. data/lib/IFMapper/MapReader.rb +900 -900
  84. data/lib/IFMapper/PDFMapExporter.rb +526 -483
  85. data/lib/IFMapper/Room.rb +153 -151
  86. data/lib/IFMapper/Section.rb +234 -234
  87. data/lib/IFMapper/TADSReader.rb +474 -471
  88. data/lib/IFMapper/TADSWriter.rb +375 -370
  89. data/lib/IFMapper/TranscriptDialogBox.rb +0 -0
  90. data/lib/IFMapper/TranscriptReader.rb +1361 -1359
  91. data/lib/IFMapper/locales/en/Messages.rb +446 -435
  92. data/lib/IFMapper/locales/es/Messages.rb +451 -440
  93. data/lib/IFMapper/locales/es/Messages_iso-8859-1.rb +455 -440
  94. data/lib/IFMapper/locales/es/runme.sh +3 -3
  95. data/maps/A New Life.map b/data/maps/A New → Life.map +0 -0
  96. data/maps/AMFV.map +0 -0
  97. data/maps/AllRoads.map +0 -0
  98. data/maps/Aotearoa.map +0 -0
  99. data/maps/Bronze.map +0 -0
  100. data/maps/Bureaucracy.ifm +0 -0
  101. data/maps/Bureaucracy.map +0 -0
  102. data/maps/CityOfSecrets.map +0 -0
  103. data/maps/DDIV.map +0 -0
  104. data/maps/Following_A_Star.map +0 -0
  105. data/maps/Heated.map +0 -0
  106. data/maps/Heroine.map +0 -0
  107. data/maps/History Repeating.map b/data/maps/History → Repeating.map +0 -0
  108. data/maps/Hollywood_Hijinx.ifm +0 -0
  109. data/maps/Janitor.map +0 -0
  110. data/maps/Jigsaw.ifm +0 -0
  111. data/maps/Jigsaw.map +0 -0
  112. data/maps/LGOP.ifm +0 -0
  113. data/maps/Mercy.ifm +0 -0
  114. data/maps/Ninjas_Fate.map +0 -0
  115. data/maps/Pen_and_Paint.map +0 -0
  116. data/maps/Planetfall.ifm +0 -0
  117. data/maps/Planetfall.map +0 -0
  118. data/maps/Plundered_Hearts.ifm +0 -0
  119. data/maps/QuietEvening.map +0 -0
  120. data/maps/Ralph.ifm +0 -0
  121. data/maps/Reliques_of_Tolti_Alph.map +0 -0
  122. data/maps/Revolution.map +0 -0
  123. data/maps/Robots_of_Dawn.ifm +0 -0
  124. data/maps/SavoirFare.map +0 -0
  125. data/maps/Seastalker.ifm +0 -0
  126. data/maps/Seastalker.map +0 -0
  127. data/maps/Sherlock.ifm +0 -0
  128. data/maps/SoFar.ifm +0 -0
  129. data/maps/Starcross.ifm +0 -0
  130. data/maps/Suspended.ifm +0 -0
  131. data/maps/Tangle.map +0 -0
  132. data/maps/The_Lost_Sheep.map +0 -0
  133. data/maps/Unforgotten.map +0 -0
  134. data/maps/Warbler's Nest.map +0 -0
  135. data/maps/Warbler's_Nest.map +0 -0
  136. data/maps/Westminster_Abbey.map +0 -0
  137. data/maps/WinterWonderland.map +0 -0
  138. data/maps/Wishbringer.ifm +0 -0
  139. data/maps/Wishbringer2.ifm +0 -0
  140. data/maps/Zork1.ifm +0 -0
  141. data/maps/Zork2.ifm +0 -0
  142. data/maps/Zork3.ifm +0 -0
  143. data/maps/Zork_Zero.ifm +0 -0
  144. data/maps/anchor.ifm +0 -0
  145. data/maps/anchor.map +0 -0
  146. data/maps/atrox.ifm +0 -0
  147. data/maps/awaken.ifm +0 -0
  148. data/maps/babel.ifm +0 -0
  149. data/maps/balances.map +0 -0
  150. data/maps/ballerina.map +0 -0
  151. data/maps/bear.map +0 -0
  152. data/maps/bluechairs.map +0 -0
  153. data/maps/break_in.map +0 -0
  154. data/maps/bse.ifm +0 -0
  155. data/maps/building.map +0 -0
  156. data/maps/change.ifm +0 -0
  157. data/maps/christminster.map +0 -0
  158. data/maps/curses.ifm +0 -0
  159. data/maps/curves.ifm +0 -0
  160. data/maps/deadline.map +0 -0
  161. data/maps/delusions.map +0 -0
  162. data/maps/devours.map +0 -0
  163. data/maps/distress.map +0 -0
  164. data/maps/djinni.map +0 -0
  165. data/maps/dreamhold.map +0 -0
  166. data/maps/drift3.map +0 -0
  167. data/maps/eas.map +0 -0
  168. data/maps/eas2.map +0 -0
  169. data/maps/eas3.map +0 -0
  170. data/maps/edifice.ifm +0 -0
  171. data/maps/fallacy.map +0 -0
  172. data/maps/frozen.ifm +0 -0
  173. data/maps/gamlet.map +0 -0
  174. data/maps/glow.ifm +0 -0
  175. data/maps/guilty_bastards.map +0 -0
  176. data/maps/heist.map +0 -0
  177. data/maps/heroes.map +0 -0
  178. data/maps/inhumane.map +0 -0
  179. data/maps/kaged.map +0 -0
  180. data/maps/library.ifm +0 -0
  181. data/maps/lurkinghorror.map +0 -0
  182. data/maps/metamorphoses.map +0 -0
  183. data/maps/mindelec.ifm +0 -0
  184. data/maps/minster.ifm +0 -0
  185. data/maps/mite.map +0 -0
  186. data/maps/moonmist.map +0 -0
  187. data/maps/muldoon_legacy.map +0 -0
  188. data/maps/muse.ifm +0 -0
  189. data/maps/paperchase.ifm +0 -0
  190. data/maps/party.map +0 -0
  191. data/maps/pawn.map +0 -0
  192. data/maps/photograph.map +0 -0
  193. data/maps/pkgirl.map +0 -0
  194. data/maps/pytho.map +0 -0
  195. data/maps/risorgimento.map +0 -0
  196. data/maps/sherbet.map +0 -0
  197. data/maps/simple.map +0 -0
  198. data/maps/slouch.map +0 -0
  199. data/maps/space_st.ifm +0 -0
  200. data/maps/splashdown.map +0 -0
  201. data/maps/spring.map +0 -0
  202. data/maps/squarecircle.map +0 -0
  203. data/maps/stationfall.ifm +0 -0
  204. data/maps/theatre.ifm +0 -0
  205. data/maps/toonesia.ifm +0 -0
  206. data/maps/tortoise.ifm +0 -0
  207. data/maps/trinity.map +0 -0
  208. data/maps/vespers.map +0 -0
  209. data/maps/vgame.ifm +0 -0
  210. data/maps/wasp.map +0 -0
  211. data/maps/weather.ifm +0 -0
  212. data/maps/windhall.ifm +0 -0
  213. data/maps/worlds.map +0 -0
  214. data/maps/xtcontest.map +0 -0
  215. data/maps/zdungeon.map +0 -0
  216. data/maps/zebulon.ifm +0 -0
  217. data/maps/zerosum.map +0 -0
  218. metadata +226 -183
data/lib/IFMapper/Map.rb CHANGED
@@ -1,200 +1,202 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'IFMapper/Room'
4
- require 'IFMapper/Section'
5
-
6
- class Map
7
- attr_accessor :name
8
- attr_accessor :creator
9
- attr_accessor :date
10
-
11
- attr_reader :section
12
- attr_accessor :sections
13
-
14
- attr_accessor :width
15
- attr_accessor :height
16
-
17
-
18
- #
19
- # Used for loading class with Marshal
20
- #
21
- def marshal_load(v)
22
- @name = v.shift
23
- @creator = v.shift
24
- @date = v.shift
25
- @section = v.shift
26
- @sections = v.shift
27
- @width = v.shift
28
- @height = v.shift
29
- end
30
-
31
- #
32
- # Used for saving class with Marshal
33
- #
34
- def marshal_dump
35
- [ @name, @creator, @date, @section, @sections, @width, @height ]
36
- end
37
-
38
- def section=(x)
39
- x = 0 if x < 0
40
- x = @sections.size - 1 if x >= @sections.size
41
- @section = x
42
- end
43
-
44
- #
45
- # Auxiliary debugging function to verify the integrity of the map
46
- #
47
- def verify_integrity
48
- @sections.each { |sect|
49
- sect.rooms.each { |r|
50
- r.exits.each_with_index { |e, idx|
51
- next if not e
52
- if not sect.connections.include?(e)
53
- $stderr.puts "Exit #{e} in room, but not in section #{sect.name}."
54
- r.exits[idx] = nil
55
- sect.connections.delete(e)
56
- end
57
- }
58
- }
59
-
60
- sect.connections.each { |c|
61
- a = c.roomA
62
- b = c.roomB
63
- if not a.exits.index(c) or
64
- (b and not b.exits.rindex(c))
65
- $stderr.puts "Exit #{c} not present in room."
66
- sect.connections.delete(c)
67
- end
68
- }
69
- }
70
- end
71
-
72
- #
73
- # Change map's width and height to make sure all rooms and connections
74
- # will fit in map
75
- #
76
- def fit
77
- # First, adjust map's width and height
78
- @width = @height = 3
79
- minXY = []
80
- maxXY = []
81
-
82
- @sections.each { |section|
83
- next if section.rooms.empty?
84
-
85
- sizes = section.min_max_rooms
86
- minXY.push sizes[0]
87
- maxXY.push sizes[1]
88
-
89
- w = maxXY[-1][0] - minXY[-1][0]
90
- h = maxXY[-1][1] - minXY[-1][1]
91
-
92
- # We store +3 to allow for complex connections if needed.
93
- @width = w + 3 if w >= @width - 2
94
- @height = h + 3 if h >= @height - 2
95
- }
96
-
97
-
98
- # Okay, minXY[]/maxXY[] contains all the minXY/maxXY positions of
99
- # each section. With that info and @weight/@height, we can
100
- # start shifting all nodes in the section so that they will fit.
101
- idx = 0
102
- @sections.each { |p|
103
- next if p.rooms.size == 0
104
- x = y = 0
105
- x = 1 - minXY[idx][0] if minXY[idx][0] < 1
106
- y = 1 - minXY[idx][1] if minXY[idx][1] < 1
107
- x = @width - maxXY[idx][0] - 2 if maxXY[idx][0] >= @width - 1
108
- y = @height - maxXY[idx][1] - 2 if maxXY[idx][1] >= @height - 1
109
- idx += 1
110
- next if x == 0 and y == 0 # nothing to shift
111
- p.rooms.each { |r|
112
- r.x += x
113
- r.y += y
114
- }
115
- }
116
- end
117
-
118
- def initialize(name)
119
- @section = 0
120
- @name = name
121
- @creator = ''
122
-
123
- @width = 8
124
- @height = 11
125
-
126
- # Add at least one section
127
- @sections = []
128
- new_section
129
- end
130
-
131
- def copy(b)
132
- @section = b.section
133
- @sections = b.sections
134
- @name = b.name
135
- @creator = b.creator
136
- @width = b.width
137
- @height = b.height
138
- @date = b.date
139
- end
140
-
141
- #
142
- # Return true or false if map is free at location x,y
143
- #
144
- def free?(x, y)
145
- return @sections[@section].free?(x,y)
146
- end
147
-
148
- def shift(x, y, dx, dy)
149
- @sections[@section].shift(x, y, dx, dy)
150
- end
151
-
152
- def delete_connection(c)
153
- @sections[@section].delete_connection(c)
154
- end
155
-
156
- def delete_connection_at( idx )
157
- @sections[@section].delete_connection_at(idx)
158
- end
159
-
160
-
161
- def new_connection( roomA, exitA, roomB, exitB = nil )
162
- @sections[@section].new_connection(roomA, exitA, roomB, exitB)
163
- end
164
-
165
-
166
- def delete_room_at(idx)
167
- @sections[@section].delete_room_at(idx)
168
- end
169
-
170
- def delete_room_only(r)
171
- @sections[@section].delete_room_only(r)
172
- end
173
-
174
- def delete_room(r)
175
- @sections[@section].delete_room(r)
176
- end
177
-
178
- def new_room( x, y )
179
- @sections[@section].new_room(x, y)
180
- end
181
-
182
- def new_section
183
- @sections.push( Section.new )
184
- @section = @sections.size - 1
185
- end
186
-
187
- def _check_section
188
- @section = @sections.size - 1 if @section >= @sections.size
189
- new_section if @sections.size == 0
190
- end
191
-
192
- def delete_section_at(idx)
193
- @sections.delete_at(idx)
194
- _check_section
195
- end
196
-
197
-
198
- end
199
-
200
-
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'IFMapper/Room'
4
+ require 'IFMapper/Section'
5
+
6
+ class Map
7
+ attr_accessor :name
8
+ attr_accessor :creator
9
+ attr_accessor :date
10
+
11
+ attr_reader :section
12
+ attr_accessor :sections
13
+
14
+ attr_accessor :width
15
+ attr_accessor :height
16
+
17
+
18
+ #
19
+ # Used for loading class with Marshal
20
+ #
21
+ def marshal_load(v)
22
+ @name = v.shift
23
+ @creator = v.shift
24
+ @date = v.shift
25
+ @section = v.shift
26
+ @sections = v.shift
27
+ @width = v.shift
28
+ @height = v.shift
29
+ end
30
+
31
+ #
32
+ # Used for saving class with Marshal
33
+ #
34
+ def marshal_dump
35
+ [ @name, @creator, @date, @section, @sections, @width, @height ]
36
+ end
37
+
38
+ def section=(x)
39
+ x = 0 if x < 0
40
+ x = @sections.size - 1 if x >= @sections.size
41
+ @section = x
42
+ end
43
+
44
+ #
45
+ # Auxiliary debugging function to verify the integrity of the map
46
+ #
47
+ def verify_integrity
48
+ @sections.each { |sect|
49
+ sect.rooms.each { |r|
50
+ r.exits.each_with_index { |e, idx|
51
+ next if not e
52
+ if not sect.connections.include?(e)
53
+ $stderr.puts "Exit #{e} in room, but not in section #{sect.name}."
54
+ r.exits[idx] = nil
55
+ sect.connections.delete(e)
56
+ end
57
+ }
58
+ }
59
+
60
+ sect.connections.each { |c|
61
+ a = c.roomA
62
+ b = c.roomB
63
+ if not a.exits.index(c) or
64
+ (b and not b.exits.rindex(c))
65
+ $stderr.puts "Exit #{c} not present in room."
66
+ sect.connections.delete(c)
67
+ end
68
+ }
69
+ }
70
+ end
71
+
72
+ #
73
+ # Change map's width and height to make sure all rooms and connections
74
+ # will fit in map
75
+ #
76
+ def fit
77
+ # First, adjust map's width and height
78
+ @width = @height = 3
79
+ minXY = []
80
+ maxXY = []
81
+
82
+ @sections.each { |section|
83
+ next if section.rooms.empty?
84
+
85
+ sizes = section.min_max_rooms
86
+ minXY.push sizes[0]
87
+ maxXY.push sizes[1]
88
+
89
+ w = maxXY[-1][0] - minXY[-1][0]
90
+ h = maxXY[-1][1] - minXY[-1][1]
91
+
92
+ # We store +3 to allow for complex connections if needed.
93
+ @width = w + 3 if w >= @width - 2
94
+ @height = h + 3 if h >= @height - 2
95
+ }
96
+
97
+
98
+ # Okay, minXY[]/maxXY[] contains all the minXY/maxXY positions of
99
+ # each section. With that info and @weight/@height, we can
100
+ # start shifting all nodes in the section so that they will fit.
101
+ idx = 0
102
+ @sections.each { |p|
103
+ next if p.rooms.size == 0
104
+ x = y = 0
105
+ x = 1 - minXY[idx][0] if minXY[idx][0] < 1
106
+ y = 1 - minXY[idx][1] if minXY[idx][1] < 1
107
+ x = @width - maxXY[idx][0] - 2 if maxXY[idx][0] >= @width - 1
108
+ y = @height - maxXY[idx][1] - 2 if maxXY[idx][1] >= @height - 1
109
+ idx += 1
110
+ next if x == 0 and y == 0 # nothing to shift
111
+ p.rooms.each { |r|
112
+ r.x += x
113
+ r.y += y
114
+ }
115
+ }
116
+ end
117
+
118
+ def initialize(name)
119
+ @section = 0
120
+ @name = name
121
+ @creator = ''
122
+
123
+ @width = 8
124
+ @height = 11
125
+
126
+ @date = nil
127
+
128
+ # Add at least one section
129
+ @sections = []
130
+ new_section
131
+ end
132
+
133
+ def copy(b)
134
+ @section = b.section
135
+ @sections = b.sections
136
+ @name = b.name
137
+ @creator = b.creator
138
+ @width = b.width
139
+ @height = b.height
140
+ @date = b.date
141
+ end
142
+
143
+ #
144
+ # Return true or false if map is free at location x,y
145
+ #
146
+ def free?(x, y)
147
+ return @sections[@section].free?(x,y)
148
+ end
149
+
150
+ def shift(x, y, dx, dy)
151
+ @sections[@section].shift(x, y, dx, dy)
152
+ end
153
+
154
+ def delete_connection(c)
155
+ @sections[@section].delete_connection(c)
156
+ end
157
+
158
+ def delete_connection_at( idx )
159
+ @sections[@section].delete_connection_at(idx)
160
+ end
161
+
162
+
163
+ def new_connection( roomA, exitA, roomB, exitB = nil )
164
+ @sections[@section].new_connection(roomA, exitA, roomB, exitB)
165
+ end
166
+
167
+
168
+ def delete_room_at(idx)
169
+ @sections[@section].delete_room_at(idx)
170
+ end
171
+
172
+ def delete_room_only(r)
173
+ @sections[@section].delete_room_only(r)
174
+ end
175
+
176
+ def delete_room(r)
177
+ @sections[@section].delete_room(r)
178
+ end
179
+
180
+ def new_room( x, y )
181
+ @sections[@section].new_room(x, y)
182
+ end
183
+
184
+ def new_section
185
+ @sections.push( Section.new )
186
+ @section = @sections.size - 1
187
+ end
188
+
189
+ def _check_section
190
+ @section = @sections.size - 1 if @section >= @sections.size
191
+ new_section if @sections.size == 0
192
+ end
193
+
194
+ def delete_section_at(idx)
195
+ @sections.delete_at(idx)
196
+ _check_section
197
+ end
198
+
199
+
200
+ end
201
+
202
+
@@ -1,162 +1,162 @@
1
-
2
- # Common printing add-ons
3
- class FXSection
4
- attr_accessor :xoff, :yoff, :page, :pxlen, :pylen, :rotate
5
- end
6
-
7
- class Page
8
- attr_accessor :xlen, :ylen, :sections, :rotate
9
- def initialize(xlen = 0, ylen = 0)
10
- @xlen = xlen
11
- @ylen = ylen
12
- @rotate = false
13
- @sections = []
14
- end
15
- end
16
-
17
- class Map
18
- #
19
- # This code section is largely a copy of similar code used in
20
- # IFM's C code.
21
- # It tries to pack multiple map sections into a single page.
22
- #
23
- def pack_sections(xmax, ymax)
24
- spacing = 0.0
25
-
26
- # initialize -- one section per page
27
- pages = []
28
- @sections.each { |sect|
29
- xlen, ylen = sect.rooms_width_height
30
- sect.xoff = 0.0
31
- sect.yoff = 0.0
32
-
33
- page = Page.new(xlen+2, ylen+2)
34
- pages.push page
35
- page.sections << sect
36
- }
37
-
38
- ratio = xmax.to_f / ymax
39
-
40
- packed = 1
41
- while packed > 0
42
- newpages = []
43
- pos = packed = 0
44
- while pos < pages.size
45
- p1 = pages[pos]
46
- x1 = p1.xlen
47
- y1 = p1.ylen
48
-
49
- # Check if it's better off rotated
50
- p1.rotate = ((x1 < y1 and xmax > ymax) or
51
- (x1 > y1 and xmax < ymax))
52
-
53
- # Check if this is the last page
54
- if pos + 1 == pages.size
55
- newpages.push p1
56
- break
57
- end
58
-
59
- # Get following page
60
- p2 = pages[pos+1]
61
- x2 = p2.xlen
62
- y2 = p2.ylen
63
-
64
- # Try combining pages in X direction
65
- xc1 = x1 + x2 + spacing
66
- yc1 = [y1, y2].max
67
- v1 = (xc1 <= xmax and yc1 <= ymax)
68
- r1 = xc1.to_f / yc1
69
-
70
- # Try combining pages in Y direction
71
- xc2 = [x1, x2].max
72
- yc2 = y1 + y2 + spacing
73
- v2 = (xc2 <= xmax and yc2 <= ymax)
74
- r2 = xc2.to_f / yc2
75
-
76
- # See which is best
77
- if v1 and v2
78
- if (ratio - r1).abs < (ratio - r2).abs
79
- v2 = false
80
- else
81
- v1 = false
82
- end
83
- end
84
-
85
- # Just copy page if nothing can be done
86
- if not v1 and not v2
87
- newpages.push(p1)
88
- pos += 1
89
- next
90
- end
91
-
92
- # Create merged page
93
- page = Page.new
94
- xo1 = yo1 = xo2 = yo2 = 0
95
-
96
- if v1
97
- page.xlen = xc1
98
- page.ylen = yc1
99
- xo2 = x1 + spacing
100
-
101
- if y1 < y2
102
- yo1 = (yc1 - y1) / 2
103
- else
104
- yo2 = (yc1 - y2) / 2
105
- end
106
- end
107
-
108
- if v2
109
- page.xlen = xc2
110
- page.ylen = yc2
111
- yo1 = y2 + spacing
112
-
113
- if x1 < x2
114
- xo1 = (xc2 - x1) / 2
115
- else
116
- xo2 = (xc2 - x2) / 2
117
- end
118
- end
119
-
120
- # Copy sections to new page, updating offsets
121
- opsects = p1.sections
122
- opsects.each { |sect|
123
- page.sections.push sect
124
- sect.xoff += xo1
125
- sect.yoff += yo1
126
- }
127
-
128
- opsects = p2.sections
129
- opsects.each { |sect|
130
- page.sections.push sect
131
- sect.xoff += xo2
132
- sect.yoff += yo2
133
- }
134
-
135
- # Add merged page to list and go to next page pair
136
- newpages.push page
137
- pos += 2
138
- packed += 1
139
- end
140
- pages = newpages
141
- end
142
-
143
- # Give each section its page info and clean up
144
- num = 0
145
- pages.each { |page|
146
- psects = page.sections
147
- xlen = page.xlen
148
- ylen = page.ylen
149
- rflag = page.rotate
150
-
151
- num += 1
152
- psects.each { |sect|
153
- sect.page = num
154
- sect.pxlen = xlen
155
- sect.pylen = ylen
156
- sect.rotate = rflag
157
- }
158
- }
159
- return num
160
- end
161
- end
162
-
1
+
2
+ # Common printing add-ons
3
+ class FXSection
4
+ attr_accessor :xoff, :yoff, :page, :pxlen, :pylen, :rotate
5
+ end
6
+
7
+ class Page
8
+ attr_accessor :xlen, :ylen, :sections, :rotate
9
+ def initialize(xlen = 0, ylen = 0)
10
+ @xlen = xlen
11
+ @ylen = ylen
12
+ @rotate = false
13
+ @sections = []
14
+ end
15
+ end
16
+
17
+ class Map
18
+ #
19
+ # This code section is largely a copy of similar code used in
20
+ # IFM's C code.
21
+ # It tries to pack multiple map sections into a single page.
22
+ #
23
+ def pack_sections(xmax, ymax)
24
+ spacing = 0.0
25
+
26
+ # initialize -- one section per page
27
+ pages = []
28
+ @sections.each { |sect|
29
+ xlen, ylen = sect.rooms_width_height
30
+ sect.xoff = 0.0
31
+ sect.yoff = 0.0
32
+
33
+ page = Page.new(xlen+2, ylen+2)
34
+ pages.push page
35
+ page.sections << sect
36
+ }
37
+
38
+ ratio = xmax.to_f / ymax
39
+
40
+ packed = 1
41
+ while packed > 0
42
+ newpages = []
43
+ pos = packed = 0
44
+ while pos < pages.size
45
+ p1 = pages[pos]
46
+ x1 = p1.xlen
47
+ y1 = p1.ylen
48
+
49
+ # Check if it's better off rotated
50
+ p1.rotate = ((x1 < y1 and xmax > ymax) or
51
+ (x1 > y1 and xmax < ymax))
52
+
53
+ # Check if this is the last page
54
+ if pos + 1 == pages.size
55
+ newpages.push p1
56
+ break
57
+ end
58
+
59
+ # Get following page
60
+ p2 = pages[pos+1]
61
+ x2 = p2.xlen
62
+ y2 = p2.ylen
63
+
64
+ # Try combining pages in X direction
65
+ xc1 = x1 + x2 + spacing
66
+ yc1 = [y1, y2].max
67
+ v1 = (xc1 <= xmax and yc1 <= ymax)
68
+ r1 = xc1.to_f / yc1
69
+
70
+ # Try combining pages in Y direction
71
+ xc2 = [x1, x2].max
72
+ yc2 = y1 + y2 + spacing
73
+ v2 = (xc2 <= xmax and yc2 <= ymax)
74
+ r2 = xc2.to_f / yc2
75
+
76
+ # See which is best
77
+ if v1 and v2
78
+ if (ratio - r1).abs < (ratio - r2).abs
79
+ v2 = false
80
+ else
81
+ v1 = false
82
+ end
83
+ end
84
+
85
+ # Just copy page if nothing can be done
86
+ if not v1 and not v2
87
+ newpages.push(p1)
88
+ pos += 1
89
+ next
90
+ end
91
+
92
+ # Create merged page
93
+ page = Page.new
94
+ xo1 = yo1 = xo2 = yo2 = 0
95
+
96
+ if v1
97
+ page.xlen = xc1
98
+ page.ylen = yc1
99
+ xo2 = x1 + spacing
100
+
101
+ if y1 < y2
102
+ yo1 = (yc1 - y1) / 2
103
+ else
104
+ yo2 = (yc1 - y2) / 2
105
+ end
106
+ end
107
+
108
+ if v2
109
+ page.xlen = xc2
110
+ page.ylen = yc2
111
+ yo1 = y2 + spacing
112
+
113
+ if x1 < x2
114
+ xo1 = (xc2 - x1) / 2
115
+ else
116
+ xo2 = (xc2 - x2) / 2
117
+ end
118
+ end
119
+
120
+ # Copy sections to new page, updating offsets
121
+ opsects = p1.sections
122
+ opsects.each { |sect|
123
+ page.sections.push sect
124
+ sect.xoff += xo1
125
+ sect.yoff += yo1
126
+ }
127
+
128
+ opsects = p2.sections
129
+ opsects.each { |sect|
130
+ page.sections.push sect
131
+ sect.xoff += xo2
132
+ sect.yoff += yo2
133
+ }
134
+
135
+ # Add merged page to list and go to next page pair
136
+ newpages.push page
137
+ pos += 2
138
+ packed += 1
139
+ end
140
+ pages = newpages
141
+ end
142
+
143
+ # Give each section its page info and clean up
144
+ num = 0
145
+ pages.each { |page|
146
+ psects = page.sections
147
+ xlen = page.xlen
148
+ ylen = page.ylen
149
+ rflag = page.rotate
150
+
151
+ num += 1
152
+ psects.each { |sect|
153
+ sect.page = num
154
+ sect.pxlen = xlen
155
+ sect.pylen = ylen
156
+ sect.rotate = rflag
157
+ }
158
+ }
159
+ return num
160
+ end
161
+ end
162
+