ifmapper 0.6 → 0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|