ifmapper 0.6 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -69,17 +69,20 @@ class FXRoom < Room
69
69
  return true
70
70
  end
71
71
 
72
+ def update_properties(map)
73
+ return if not @@win or not @@win.shown?
74
+ @@win.map = map
75
+ @@win.setFocus
76
+ @@win.copy_from(self)
77
+ end
78
+
72
79
  # Open a new requester to change room properties
73
80
  def properties( map, event = nil )
74
81
  if not @@win
75
82
  @@win = FXRoomDialogBox.new(map, self, event, false)
76
- else
77
- @@win.map = map
78
83
  end
79
- @@win.setFocus
80
84
  @@win.show
81
- @@win.copy_from(self)
82
- return
85
+ update_properties(map)
83
86
  end
84
87
 
85
88
  #
@@ -202,7 +202,7 @@ class IFMReader
202
202
  tag, task = get_tag
203
203
  return @task if tag == 'last'
204
204
  if task and task.kind_of?(Room)
205
- raise ParseError, "Not an task tag <#{tag}:#{item}>"
205
+ raise ParseError, "Not a task tag <#{tag}:#{item}>"
206
206
  end
207
207
  return task
208
208
  end
@@ -448,8 +448,9 @@ class IFMReader
448
448
  }
449
449
 
450
450
  # Remember original room for connection
451
- roomB = @map.new_room( @x, @y )
452
- roomB.name = roomname
451
+ roomB = @map.new_room( @x, @y )
452
+ roomB.selected = false
453
+ roomB.name = roomname
453
454
  @rooms.push( roomB )
454
455
  end
455
456
 
@@ -0,0 +1,219 @@
1
+
2
+
3
+
4
+ class IFMWriter
5
+
6
+ def link(c)
7
+ return if @links.include?(c) # already spit out
8
+ a = c.roomA
9
+ return if not a
10
+ b = c.roomB
11
+ roomA = @elem[a]
12
+ roomB = @elem[b]
13
+ @f.puts
14
+ @f.print "link #{roomA} to #{roomB}"
15
+ directions(c, a, b)
16
+ @f.print ";\n"
17
+ end
18
+
19
+ def directions(c, a, b)
20
+ @links << c
21
+ if c.gpts.empty?
22
+ # simple connection
23
+ idx = a.next_to?(b)
24
+ dir = ' ' + Room::DIRECTIONS[idx]
25
+ else
26
+ # complex path
27
+ dir = ''
28
+ pts = c.gpts.dup
29
+ x = a.x
30
+ y = a.y
31
+ if c.roomA != a
32
+ pts.reverse!
33
+ end
34
+
35
+ pts.each { |p|
36
+ dx, dy = [ p[0] - x, p[1] - y ]
37
+ idx = Room::vector_to_dir(dx, dy)
38
+ dir += " #{Room::DIRECTIONS[idx]}"
39
+ x = p[0]
40
+ y = p[1]
41
+ }
42
+ dx, dy = [ b.x - x, b.y - y ]
43
+ idx = Room::vector_to_dir(dx, dy)
44
+ dir += " #{Room::DIRECTIONS[idx]}"
45
+ end
46
+ @f.print " dir#{dir}"
47
+
48
+ if c.exitAtext != 0
49
+ dir = Connection::EXIT_TEXT[c.exitAtext].downcase
50
+ @f.print " go #{dir}"
51
+ end
52
+
53
+ if c.dir == Connection::AtoB
54
+ @f.print " oneway"
55
+ end
56
+
57
+ if c.type == Connection::SPECIAL
58
+ @f.print " style special"
59
+ end
60
+ end
61
+
62
+ def get_tag(e, t)
63
+ return @elem[e] if @elem.has_key?(e)
64
+
65
+ tag = t.dup
66
+ tag.gsub!(/[\s,\.'"#$@\/\\-]+/, '_')
67
+ tagname = tag
68
+ idx = 2
69
+ while @tags.include?(tagname)
70
+ tagname = tag + '_' + idx.to_s
71
+ idx += 1
72
+ end
73
+ @tags << tagname
74
+ @elem[e] = tagname
75
+ return tagname
76
+ end
77
+
78
+ # hook up two rooms that are not linked
79
+ def nolink(a, b)
80
+ x = a.x
81
+ y = a.y
82
+
83
+ # find free room exit in a
84
+ exit = 0
85
+ a.exits.each_with_index { |e, idx|
86
+ next if e
87
+ exit = idx
88
+ break
89
+ }
90
+ dir = Room::DIRECTIONS[exit]
91
+ dx, dy = Room::DIR_TO_VECTOR[exit]
92
+ x += dx
93
+ y += dy
94
+ while x != b.x or y != b.y
95
+ dx = dy = 0
96
+ if b.x > x
97
+ dx = 1
98
+ elsif b.x < x
99
+ dx = -1
100
+ end
101
+ if b.y > y
102
+ dy = 1
103
+ elsif b.y < y
104
+ dy = -1
105
+ end
106
+ idx = Room::vector_to_dir(dx, dy)
107
+ dir += " #{Room::DIRECTIONS[idx]}"
108
+ x += dx
109
+ y += dy
110
+ end
111
+
112
+ @f.print " dir #{dir} nolink"
113
+ end
114
+
115
+ def room(r)
116
+ return if @rooms.include?(r)
117
+ @rooms << r
118
+ tag = get_tag(r, r.name)
119
+
120
+ @f.puts
121
+ @f.print "room \"#{r.name}\" tag #{tag}"
122
+ if @link
123
+ if @link[3]
124
+ nolink(@last_room, r)
125
+ else
126
+ directions(@link[0], @link[1], @link[2])
127
+ if @last_room and @link[1] != @last_room
128
+ tag = get_tag(@link[1], @link[1].name)
129
+ @f.print " from #{tag}"
130
+ end
131
+ end
132
+ end
133
+ @f.print ";\n"
134
+ @last_room = r
135
+
136
+ objs = r.objects.split("\n")
137
+ objs.each { |obj|
138
+ tag = get_tag(obj, obj)
139
+ @f.puts "\titem \"#{obj}\" tag #{tag};"
140
+ }
141
+ tasks = r.tasks.split("\n")
142
+ tasks.each { |task|
143
+ tag = get_tag(task, task)
144
+ @f.puts "\ttask \"#{task}\" tag #{tag};"
145
+ }
146
+
147
+ r.exits.each { |c|
148
+ next if not c or @links.include?(c)
149
+ if c.roomA == c.roomB
150
+ # self-link
151
+ link(c)
152
+ next
153
+ end
154
+ if r == c.roomA
155
+ @link = [c, c.roomA, c.roomB]
156
+ room(c.roomB) # Recurse along this branch...
157
+ else
158
+ @link = [c, c.roomB, c.roomA]
159
+ room(c.roomA) # Recurse along this branch...
160
+ end
161
+ }
162
+ end
163
+
164
+ def sections
165
+ old_section = @map.section
166
+ @map.sections.each_with_index { |section, idx|
167
+ @f.puts
168
+ @f.puts '#' * 79
169
+ @f.puts
170
+ @f.puts "map \"#{section.name}\";" if section.name != ''
171
+ @map.section = idx
172
+ @link = nil
173
+ section.rooms.each { |r|
174
+ room(r)
175
+ @link << 'nolink'
176
+ }
177
+ section.connections.each { |c|
178
+ link(c)
179
+ }
180
+ }
181
+ @map.section = old_section
182
+ end
183
+
184
+ def header
185
+ @f.puts <<-"HEADER"
186
+ #
187
+ # IFM map for #{@map.name}
188
+ # Created by #{@map.creator}
189
+ # #{Time.now}
190
+ #
191
+ # Map created using the Interactive Fiction Mapper
192
+ # (C) 2005 - Gonzalo Garramuno
193
+ #
194
+
195
+ title "#{@map.name}";
196
+
197
+ HEADER
198
+
199
+ end
200
+
201
+
202
+ def export(file)
203
+ @f = File.open(file, 'w')
204
+ header
205
+ sections
206
+ @f.close
207
+ end
208
+
209
+ def initialize(map, file)
210
+ @link = nil
211
+ @links = []
212
+ @rooms = []
213
+ @last_room = nil
214
+ @tags = []
215
+ @elem = {}
216
+ @map = map
217
+ export(file)
218
+ end
219
+ end
@@ -14,11 +14,6 @@ class Map
14
14
  attr_accessor :width
15
15
  attr_accessor :height
16
16
 
17
- def section=(x)
18
- x = 0 if x < 0
19
- x = @sections.size - 1 if x >= @sections.size
20
- @section = x
21
- end
22
17
 
23
18
  #
24
19
  # Used for loading class with Marshal
@@ -40,6 +35,29 @@ class Map
40
35
  [ @name, @creator, @date, @section, @sections, @width, @height ]
41
36
  end
42
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
+ end
56
+ }
57
+ }
58
+ }
59
+ end
60
+
43
61
  def initialize(name)
44
62
  @section = 0
45
63
  @name = name
@@ -159,3 +159,4 @@ class Map
159
159
  return num
160
160
  end
161
161
  end
162
+
@@ -1,21 +1,23 @@
1
1
 
2
- begin
3
- require 'tmpdir'
4
- rescue => e
5
- raise "Please install 'tmpdir' library. This is needed for printing."
6
- end
2
+ require 'tmpdir'
7
3
 
8
4
  begin
9
5
  require 'pdf/writer'
10
- rescue => e
11
- raise "Please install 'pdf writer' library for Acrobat PDF support."
6
+ rescue LoadError => e
7
+ err = "PDF-Writer library not found. Please install it.\n"
8
+ if $rubygems
9
+ err += "You can usually do so if you do 'gem install pdf-writer'."
10
+ else
11
+ err += "You can download it from www.rubyforge.net."
12
+ end
13
+ raise LoadError, err
12
14
  end
13
15
 
14
16
  require 'IFMapper/MapPrinting'
15
17
 
16
18
  PDF_ZOOM = 0.5
17
- PDF_ROOM_WIDTH = W * PDF_ZOOM # 60
18
- PDF_ROOM_HEIGHT = H * PDF_ZOOM # 37.5
19
+ PDF_ROOM_WIDTH = W * PDF_ZOOM
20
+ PDF_ROOM_HEIGHT = H * PDF_ZOOM
19
21
  PDF_ROOM_WS = WS * PDF_ZOOM
20
22
  PDF_ROOM_HS = HS * PDF_ZOOM
21
23
  PDF_MARGIN = 20
@@ -11,14 +11,14 @@ class Room
11
11
  attr_accessor :x, :y
12
12
 
13
13
  DIRECTIONS = [
14
- 'N',
15
- 'NE',
16
- 'E',
17
- 'SE',
18
- 'S',
19
- 'SW',
20
- 'W',
21
- 'NW',
14
+ 'n',
15
+ 'ne',
16
+ 'e',
17
+ 'se',
18
+ 's',
19
+ 'sw',
20
+ 'w',
21
+ 'nw',
22
22
  ]
23
23
 
24
24
  DIR_TO_VECTOR = {
@@ -44,7 +44,7 @@ class Room
44
44
  # Return a direction from the vector of the exit that would take
45
45
  # us to the 'b' room more cleanly.
46
46
  #
47
- def vector_to_dir(dx, dy)
47
+ def self.vector_to_dir(dx, dy)
48
48
  if dx == 0
49
49
  return 4 if dy > 0
50
50
  return 0 if dy < 0
@@ -60,6 +60,10 @@ class Room
60
60
  end
61
61
  end
62
62
 
63
+ def vector_to_dir(dx, dy)
64
+ return Room::vector_to_dir( dx, dy )
65
+ end
66
+
63
67
  #
64
68
  # Given an 'adjacent' room, return the most direct exit from this
65
69
  # room to room b.
@@ -149,7 +149,7 @@ EOF
149
149
 
150
150
  if roomA[exitA]
151
151
  if not @connections.include?(roomA[exitA])
152
- raise ConnectionError, "room exit filled but not in page"
152
+ raise ConnectionError, "room exit #{exitA} for #{roomA} filled but not in section"
153
153
  end
154
154
  raise ConnectionError, "room exit #{exitA} for #{roomA} is filled"
155
155
  end
@@ -170,6 +170,7 @@ EOF
170
170
  end
171
171
 
172
172
  if roomB and roomB[exitB] and roomB[exitB] != c
173
+ roomA[exitA] = nil
173
174
  raise ConnectionError, "room exit #{exitB} for #{roomB} is filled"
174
175
  end
175
176
  roomB[exitB] = c if roomB
metadata CHANGED
@@ -3,12 +3,12 @@ rubygems_version: 0.8.10
3
3
  specification_version: 1
4
4
  name: ifmapper
5
5
  version: !ruby/object:Gem::Version
6
- version: "0.6"
7
- date: 2005-08-14
6
+ version: "0.7"
7
+ date: 2005-08-17
8
8
  summary: Interactive Fiction Mapping Tool.
9
9
  require_paths:
10
10
  - lib
11
- email: GGarramuno@aol.com or ggarram@advance.dsl.com.ar
11
+ email: ggarram@advance.dsl.com.ar
12
12
  homepage: http://www.rubyforge.org/projects/ifmapper/
13
13
  rubyforge_project: ifmapper
14
14
  description: Interactive Fiction Mapping Tool.
@@ -28,30 +28,33 @@ authors:
28
28
  - Gonzalo Garramuno
29
29
  files:
30
30
  - IFMapper.rb
31
- - lib/IFMapper/FXMap.rb
32
- - lib/IFMapper/Map.rb
31
+ - lib/IFMapper/Section.rb
33
32
  - lib/IFMapper/FXSpline.rb
34
33
  - lib/IFMapper/FXSection.rb
35
- - lib/IFMapper/FXRoom.rb
36
34
  - lib/IFMapper/FXMapDialogBox.rb
37
35
  - lib/IFMapper/FXSectionDialogBox.rb
38
- - lib/IFMapper/FXMapperWindow.rb
39
- - lib/IFMapper/Room.rb
40
- - lib/IFMapper/Section.rb
41
- - lib/IFMapper/FXConnection.rb
42
- - lib/IFMapper/IFMReader.rb
36
+ - lib/IFMapper/IFMWriter.rb
43
37
  - lib/IFMapper/FXWarningBox.rb
44
38
  - lib/IFMapper/FXMapColorBox.rb
45
- - lib/IFMapper/PDFMapExporter.rb
46
- - lib/IFMapper/MapPrinting.rb
47
39
  - lib/IFMapper/FXMapperSettings.rb
40
+ - lib/IFMapper/FXMap.rb
41
+ - lib/IFMapper/FXRoom.rb
42
+ - lib/IFMapper/FXConnection.rb
43
+ - lib/IFMapper/AStar.rb
44
+ - lib/IFMapper/FXMapperWindow.rb
48
45
  - lib/IFMapper/Connection.rb
46
+ - lib/IFMapper/FXDCPostscript.rb
47
+ - lib/IFMapper/MapPrinting.rb
48
+ - lib/IFMapper/FXDCPrint.rb
49
+ - lib/IFMapper/Map.rb
50
+ - lib/IFMapper/Room.rb
51
+ - lib/IFMapper/IFMReader.rb
52
+ - lib/IFMapper/PDFMapExporter.rb
49
53
  - lib/IFMapper/FXAboutDialogBox.rb
50
54
  - lib/IFMapper/FXSearchDialogBox.rb
51
55
  - lib/IFMapper/FXMapFileDialog.rb
52
56
  - lib/IFMapper/FXRoomDialogBox.rb
53
57
  - lib/IFMapper/FXConnectionDialogBox.rb
54
- - lib/IFMapper/AStar.rb
55
58
  - maps/Zork_Zero.ifm
56
59
  - maps/anchor.ifm
57
60
  - maps/atrox.ifm