ifmapper 0.6 → 0.7
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 +68 -1
- data/IFMapper.gemspec +2 -2
- data/IFMapper.rb +5 -1
- data/lib/IFMapper/AStar.rb +7 -7
- data/lib/IFMapper/Connection.rb +2 -2
- data/lib/IFMapper/FXConnection.rb +7 -4
- data/lib/IFMapper/FXDCPostscript.rb +404 -0
- data/lib/IFMapper/FXDCPrint.rb +15 -0
- data/lib/IFMapper/FXMap.rb +271 -60
- data/lib/IFMapper/FXMapperSettings.rb +26 -7
- data/lib/IFMapper/FXMapperWindow.rb +209 -68
- data/lib/IFMapper/FXRoom.rb +8 -5
- data/lib/IFMapper/IFMReader.rb +4 -3
- data/lib/IFMapper/IFMWriter.rb +219 -0
- data/lib/IFMapper/Map.rb +23 -5
- data/lib/IFMapper/MapPrinting.rb +1 -0
- data/lib/IFMapper/PDFMapExporter.rb +11 -9
- data/lib/IFMapper/Room.rb +13 -9
- data/lib/IFMapper/Section.rb +2 -1
- metadata +17 -14
data/lib/IFMapper/FXRoom.rb
CHANGED
@@ -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
|
-
|
82
|
-
return
|
85
|
+
update_properties(map)
|
83
86
|
end
|
84
87
|
|
85
88
|
#
|
data/lib/IFMapper/IFMReader.rb
CHANGED
@@ -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
|
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
|
452
|
-
roomB.
|
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
|
data/lib/IFMapper/Map.rb
CHANGED
@@ -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
|
data/lib/IFMapper/MapPrinting.rb
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
|
2
|
-
|
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
|
-
|
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
|
18
|
-
PDF_ROOM_HEIGHT = H * PDF_ZOOM
|
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
|
data/lib/IFMapper/Room.rb
CHANGED
@@ -11,14 +11,14 @@ class Room
|
|
11
11
|
attr_accessor :x, :y
|
12
12
|
|
13
13
|
DIRECTIONS = [
|
14
|
-
'
|
15
|
-
'
|
16
|
-
'
|
17
|
-
'
|
18
|
-
'
|
19
|
-
'
|
20
|
-
'
|
21
|
-
'
|
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.
|
data/lib/IFMapper/Section.rb
CHANGED
@@ -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
|
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.
|
7
|
-
date: 2005-08-
|
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:
|
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/
|
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/
|
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
|