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.
- data/HISTORY.txt +648 -627
- data/IFMapper.gemspec +29 -28
- data/IFMapper.rbw +31 -31
- data/TODO.txt +8 -7
- data/bin/IFMapper +31 -31
- data/docs/en/index.html +0 -0
- data/docs/en/start.html +3 -2
- data/docs/en/start.html~ +516 -0
- data/docs/es/index.html +0 -0
- data/docs/es/start.html +13 -14
- data/docs/es/start.html~ +1280 -0
- data/docs/images/IFMapper_main.gif +0 -0
- data/docs/images/automap.gif +0 -0
- data/docs/images/complex_connection.gif +0 -0
- data/docs/images/connection.gif +0 -0
- data/docs/images/connection_menu.gif +0 -0
- data/docs/images/room_description.gif +0 -0
- data/docs/images/room_small.gif +0 -0
- data/icons/copy.png +0 -0
- data/icons/cut.png +0 -0
- data/icons/filenew.png +0 -0
- data/icons/fileopen.png +0 -0
- data/icons/filesave.png +0 -0
- data/icons/filesaveas.png +0 -0
- data/icons/help.png +0 -0
- data/icons/kill.png +0 -0
- data/icons/nextpage.png +0 -0
- data/icons/paste.png +0 -0
- data/icons/prevpage.png +0 -0
- data/icons/printicon.png +0 -0
- data/icons/redo.png +0 -0
- data/icons/room_e.gif +0 -0
- data/icons/room_e.xpm +0 -0
- data/icons/room_n.gif +0 -0
- data/icons/room_n.xpm +0 -0
- data/icons/room_ne.gif +0 -0
- data/icons/room_ne.xpm +0 -0
- data/icons/room_nw.gif +0 -0
- data/icons/room_nw.xpm +0 -0
- data/icons/room_s.gif +0 -0
- data/icons/room_s.xpm +0 -0
- data/icons/room_se.gif +0 -0
- data/icons/room_se.xpm +0 -0
- data/icons/room_sw.gif +0 -0
- data/icons/room_sw.xpm +0 -0
- data/icons/room_w.gif +0 -0
- data/icons/room_w.xpm +0 -0
- data/icons/saveas.png +0 -0
- data/icons/undo.png +0 -0
- data/icons/winapp.png +0 -0
- data/icons/zoom.png +0 -0
- data/lib/IFMapper/AStar.rb +250 -250
- data/lib/IFMapper/Connection.rb +202 -202
- data/lib/IFMapper/FXAboutDialogBox.rb +32 -32
- data/lib/IFMapper/FXConnection.rb +364 -364
- data/lib/IFMapper/FXConnectionDialogBox.rb +124 -124
- data/lib/IFMapper/FXDCPostscript.rb +404 -404
- data/lib/IFMapper/FXDCPrint.rb +15 -15
- data/lib/IFMapper/FXItemList.rb +108 -0
- data/lib/IFMapper/FXMap.rb +2147 -2116
- data/lib/IFMapper/FXMapColorBox.rb +88 -88
- data/lib/IFMapper/FXMapDialogBox.rb +127 -127
- data/lib/IFMapper/FXMapFileDialog.rb +34 -34
- data/lib/IFMapper/FXMapperSettings.rb +206 -205
- data/lib/IFMapper/FXMapperWindow.rb +1592 -1571
- data/lib/IFMapper/FXPDFMapExporterOptionsDialogBox.rb +46 -0
- data/lib/IFMapper/FXRoom.rb +263 -263
- data/lib/IFMapper/FXRoomDialogBox.rb +159 -159
- data/lib/IFMapper/FXRoomList.rb +95 -95
- data/lib/IFMapper/FXSearchDialogBox.rb +51 -51
- data/lib/IFMapper/FXSection.rb +33 -33
- data/lib/IFMapper/FXSectionDialogBox.rb +38 -38
- data/lib/IFMapper/FXSpline.rb +52 -52
- data/lib/IFMapper/FXWarningBox.rb +51 -50
- data/lib/IFMapper/GUEReader.rb +445 -445
- data/lib/IFMapper/IFMReader.rb +584 -584
- data/lib/IFMapper/IFMWriter.rb +245 -227
- data/lib/IFMapper/Inform7Writer.rb +579 -573
- data/lib/IFMapper/InformReader.rb +478 -478
- data/lib/IFMapper/InformWriter.rb +364 -359
- data/lib/IFMapper/Map.rb +202 -200
- data/lib/IFMapper/MapPrinting.rb +162 -162
- data/lib/IFMapper/MapReader.rb +900 -900
- data/lib/IFMapper/PDFMapExporter.rb +526 -483
- data/lib/IFMapper/Room.rb +153 -151
- data/lib/IFMapper/Section.rb +234 -234
- data/lib/IFMapper/TADSReader.rb +474 -471
- data/lib/IFMapper/TADSWriter.rb +375 -370
- data/lib/IFMapper/TranscriptDialogBox.rb +0 -0
- data/lib/IFMapper/TranscriptReader.rb +1361 -1359
- data/lib/IFMapper/locales/en/Messages.rb +446 -435
- data/lib/IFMapper/locales/es/Messages.rb +451 -440
- data/lib/IFMapper/locales/es/Messages_iso-8859-1.rb +455 -440
- data/lib/IFMapper/locales/es/runme.sh +3 -3
- data/maps/A New Life.map b/data/maps/A New → Life.map +0 -0
- data/maps/AMFV.map +0 -0
- data/maps/AllRoads.map +0 -0
- data/maps/Aotearoa.map +0 -0
- data/maps/Bronze.map +0 -0
- data/maps/Bureaucracy.ifm +0 -0
- data/maps/Bureaucracy.map +0 -0
- data/maps/CityOfSecrets.map +0 -0
- data/maps/DDIV.map +0 -0
- data/maps/Following_A_Star.map +0 -0
- data/maps/Heated.map +0 -0
- data/maps/Heroine.map +0 -0
- data/maps/History Repeating.map b/data/maps/History → Repeating.map +0 -0
- data/maps/Hollywood_Hijinx.ifm +0 -0
- data/maps/Janitor.map +0 -0
- data/maps/Jigsaw.ifm +0 -0
- data/maps/Jigsaw.map +0 -0
- data/maps/LGOP.ifm +0 -0
- data/maps/Mercy.ifm +0 -0
- data/maps/Ninjas_Fate.map +0 -0
- data/maps/Pen_and_Paint.map +0 -0
- data/maps/Planetfall.ifm +0 -0
- data/maps/Planetfall.map +0 -0
- data/maps/Plundered_Hearts.ifm +0 -0
- data/maps/QuietEvening.map +0 -0
- data/maps/Ralph.ifm +0 -0
- data/maps/Reliques_of_Tolti_Alph.map +0 -0
- data/maps/Revolution.map +0 -0
- data/maps/Robots_of_Dawn.ifm +0 -0
- data/maps/SavoirFare.map +0 -0
- data/maps/Seastalker.ifm +0 -0
- data/maps/Seastalker.map +0 -0
- data/maps/Sherlock.ifm +0 -0
- data/maps/SoFar.ifm +0 -0
- data/maps/Starcross.ifm +0 -0
- data/maps/Suspended.ifm +0 -0
- data/maps/Tangle.map +0 -0
- data/maps/The_Lost_Sheep.map +0 -0
- data/maps/Unforgotten.map +0 -0
- data/maps/Warbler's Nest.map +0 -0
- data/maps/Warbler's_Nest.map +0 -0
- data/maps/Westminster_Abbey.map +0 -0
- data/maps/WinterWonderland.map +0 -0
- data/maps/Wishbringer.ifm +0 -0
- data/maps/Wishbringer2.ifm +0 -0
- data/maps/Zork1.ifm +0 -0
- data/maps/Zork2.ifm +0 -0
- data/maps/Zork3.ifm +0 -0
- data/maps/Zork_Zero.ifm +0 -0
- data/maps/anchor.ifm +0 -0
- data/maps/anchor.map +0 -0
- data/maps/atrox.ifm +0 -0
- data/maps/awaken.ifm +0 -0
- data/maps/babel.ifm +0 -0
- data/maps/balances.map +0 -0
- data/maps/ballerina.map +0 -0
- data/maps/bear.map +0 -0
- data/maps/bluechairs.map +0 -0
- data/maps/break_in.map +0 -0
- data/maps/bse.ifm +0 -0
- data/maps/building.map +0 -0
- data/maps/change.ifm +0 -0
- data/maps/christminster.map +0 -0
- data/maps/curses.ifm +0 -0
- data/maps/curves.ifm +0 -0
- data/maps/deadline.map +0 -0
- data/maps/delusions.map +0 -0
- data/maps/devours.map +0 -0
- data/maps/distress.map +0 -0
- data/maps/djinni.map +0 -0
- data/maps/dreamhold.map +0 -0
- data/maps/drift3.map +0 -0
- data/maps/eas.map +0 -0
- data/maps/eas2.map +0 -0
- data/maps/eas3.map +0 -0
- data/maps/edifice.ifm +0 -0
- data/maps/fallacy.map +0 -0
- data/maps/frozen.ifm +0 -0
- data/maps/gamlet.map +0 -0
- data/maps/glow.ifm +0 -0
- data/maps/guilty_bastards.map +0 -0
- data/maps/heist.map +0 -0
- data/maps/heroes.map +0 -0
- data/maps/inhumane.map +0 -0
- data/maps/kaged.map +0 -0
- data/maps/library.ifm +0 -0
- data/maps/lurkinghorror.map +0 -0
- data/maps/metamorphoses.map +0 -0
- data/maps/mindelec.ifm +0 -0
- data/maps/minster.ifm +0 -0
- data/maps/mite.map +0 -0
- data/maps/moonmist.map +0 -0
- data/maps/muldoon_legacy.map +0 -0
- data/maps/muse.ifm +0 -0
- data/maps/paperchase.ifm +0 -0
- data/maps/party.map +0 -0
- data/maps/pawn.map +0 -0
- data/maps/photograph.map +0 -0
- data/maps/pkgirl.map +0 -0
- data/maps/pytho.map +0 -0
- data/maps/risorgimento.map +0 -0
- data/maps/sherbet.map +0 -0
- data/maps/simple.map +0 -0
- data/maps/slouch.map +0 -0
- data/maps/space_st.ifm +0 -0
- data/maps/splashdown.map +0 -0
- data/maps/spring.map +0 -0
- data/maps/squarecircle.map +0 -0
- data/maps/stationfall.ifm +0 -0
- data/maps/theatre.ifm +0 -0
- data/maps/toonesia.ifm +0 -0
- data/maps/tortoise.ifm +0 -0
- data/maps/trinity.map +0 -0
- data/maps/vespers.map +0 -0
- data/maps/vgame.ifm +0 -0
- data/maps/wasp.map +0 -0
- data/maps/weather.ifm +0 -0
- data/maps/windhall.ifm +0 -0
- data/maps/worlds.map +0 -0
- data/maps/xtcontest.map +0 -0
- data/maps/zdungeon.map +0 -0
- data/maps/zebulon.ifm +0 -0
- data/maps/zerosum.map +0 -0
- metadata +226 -183
data/lib/IFMapper/Room.rb
CHANGED
|
@@ -1,151 +1,153 @@
|
|
|
1
|
-
|
|
2
|
-
#
|
|
3
|
-
# Class used to represent a Room or Location in a Map.
|
|
4
|
-
#
|
|
5
|
-
class Room
|
|
6
|
-
attr_accessor :name # Name of room
|
|
7
|
-
attr_accessor :objects # Objects found in room
|
|
8
|
-
attr_accessor :tasks # Tasks that need to be performed in room
|
|
9
|
-
attr_reader :exits # An array of 8 possible exits in room
|
|
10
|
-
attr_accessor :darkness #
|
|
11
|
-
attr_accessor :x, :y # Room location in grid
|
|
12
|
-
attr_accessor :desc # Room description
|
|
13
|
-
|
|
14
|
-
DIR_TO_VECTOR = {
|
|
15
|
-
0 => [ 0, -1 ],
|
|
16
|
-
1 => [ 1, -1 ],
|
|
17
|
-
2 => [ 1, 0 ],
|
|
18
|
-
3 => [ 1, 1 ],
|
|
19
|
-
4 => [ 0, 1 ],
|
|
20
|
-
5 => [ -1, 1 ],
|
|
21
|
-
6 => [ -1, 0 ],
|
|
22
|
-
7 => [ -1, -1 ]
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
def marshal_load(vars)
|
|
26
|
-
@name = vars.shift
|
|
27
|
-
@objects = vars.shift
|
|
28
|
-
@tasks = vars.shift
|
|
29
|
-
@exits = vars.shift
|
|
30
|
-
@darkness = vars.shift
|
|
31
|
-
@x = vars.shift
|
|
32
|
-
@y = vars.shift
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@desc.
|
|
36
|
-
@desc.
|
|
37
|
-
@desc.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return
|
|
84
|
-
return
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return
|
|
88
|
-
return
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
#
|
|
108
|
-
#
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
return
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
#
|
|
127
|
-
#
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
@
|
|
131
|
-
@
|
|
132
|
-
@
|
|
133
|
-
@
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
@
|
|
140
|
-
@
|
|
141
|
-
@
|
|
142
|
-
@
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
@
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
1
|
+
|
|
2
|
+
#
|
|
3
|
+
# Class used to represent a Room or Location in a Map.
|
|
4
|
+
#
|
|
5
|
+
class Room
|
|
6
|
+
attr_accessor :name # Name of room
|
|
7
|
+
attr_accessor :objects # Objects found in room
|
|
8
|
+
attr_accessor :tasks # Tasks that need to be performed in room
|
|
9
|
+
attr_reader :exits # An array of 8 possible exits in room
|
|
10
|
+
attr_accessor :darkness # Isxxxxxxxxxx room in darkness?
|
|
11
|
+
attr_accessor :x, :y # Room location in grid
|
|
12
|
+
attr_accessor :desc # Room description
|
|
13
|
+
|
|
14
|
+
DIR_TO_VECTOR = {
|
|
15
|
+
0 => [ 0, -1 ],
|
|
16
|
+
1 => [ 1, -1 ],
|
|
17
|
+
2 => [ 1, 0 ],
|
|
18
|
+
3 => [ 1, 1 ],
|
|
19
|
+
4 => [ 0, 1 ],
|
|
20
|
+
5 => [ -1, 1 ],
|
|
21
|
+
6 => [ -1, 0 ],
|
|
22
|
+
7 => [ -1, -1 ]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
def marshal_load(vars)
|
|
26
|
+
@name = vars.shift
|
|
27
|
+
@objects = vars.shift
|
|
28
|
+
@tasks = vars.shift
|
|
29
|
+
@exits = vars.shift
|
|
30
|
+
@darkness = vars.shift
|
|
31
|
+
@x = vars.shift
|
|
32
|
+
@y = vars.shift
|
|
33
|
+
@desc = nil
|
|
34
|
+
if not vars.empty? and vars[0].kind_of?(String)
|
|
35
|
+
@desc = vars.shift
|
|
36
|
+
@desc.gsub!(/(\w)\s*\n/, '\1 ')
|
|
37
|
+
@desc.sub!(/\n+$/, '')
|
|
38
|
+
@desc.strip!
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def marshal_dump
|
|
43
|
+
[ @name, @objects, @tasks, @exits, @darkness, @x, @y, @desc ]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def [](dir)
|
|
47
|
+
return @exits[dir]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def []=(dir, connection)
|
|
51
|
+
@exits[dir] = connection
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#
|
|
55
|
+
# Return the number of doors present in room
|
|
56
|
+
#
|
|
57
|
+
def num_doors
|
|
58
|
+
num = 0
|
|
59
|
+
@exits.each { |e|
|
|
60
|
+
next if not e
|
|
61
|
+
num += 1 if e.door?
|
|
62
|
+
}
|
|
63
|
+
return num
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
#
|
|
67
|
+
# Return the number of exits present in room
|
|
68
|
+
#
|
|
69
|
+
def num_exits
|
|
70
|
+
return @exits.nitems
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
#
|
|
74
|
+
# Return a direction from the vector of the exit that would take
|
|
75
|
+
# us to the 'b' room more cleanly.
|
|
76
|
+
#
|
|
77
|
+
def self.vector_to_dir(dx, dy)
|
|
78
|
+
if dx == 0
|
|
79
|
+
return 4 if dy > 0
|
|
80
|
+
return 0 if dy < 0
|
|
81
|
+
raise "vector_to_dir: dx == 0 and dy == 0"
|
|
82
|
+
elsif dx > 0
|
|
83
|
+
return 1 if dy < 0
|
|
84
|
+
return 2 if dy == 0
|
|
85
|
+
return 3
|
|
86
|
+
else
|
|
87
|
+
return 7 if dy < 0
|
|
88
|
+
return 6 if dy == 0
|
|
89
|
+
return 5
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def vector_to_dir(dx, dy)
|
|
94
|
+
return Room::vector_to_dir( dx, dy )
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
#
|
|
98
|
+
# Given an 'adjacent' room, return the most direct exit from this
|
|
99
|
+
# room to room b.
|
|
100
|
+
#
|
|
101
|
+
def exit_to(b)
|
|
102
|
+
dx = (b.x - @x)
|
|
103
|
+
dy = (b.y - @y)
|
|
104
|
+
return vector_to_dir(dx, dy)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Check if two rooms are next to each other. If so,
|
|
108
|
+
# return the exit that would take us from this room to the other.
|
|
109
|
+
# Otherwise, return nil
|
|
110
|
+
def next_to?(b)
|
|
111
|
+
if not b.kind_of?(Room)
|
|
112
|
+
raise "next_to?(b): #{b} is not a room."
|
|
113
|
+
end
|
|
114
|
+
if self == b
|
|
115
|
+
raise "next_to? comparing same room #{self}"
|
|
116
|
+
end
|
|
117
|
+
if b.x == @x and b.y == @y
|
|
118
|
+
raise "#{self} and #{b} in same location."
|
|
119
|
+
end
|
|
120
|
+
dx = (b.x - @x)
|
|
121
|
+
dy = (b.y - @y)
|
|
122
|
+
return nil if dx.abs > 1 or dy.abs > 1
|
|
123
|
+
return vector_to_dir(dx, dy)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
#
|
|
127
|
+
# Copy a room to another
|
|
128
|
+
#
|
|
129
|
+
def copy(b)
|
|
130
|
+
@name = b.name
|
|
131
|
+
@objects = b.objects
|
|
132
|
+
@tasks = b.tasks
|
|
133
|
+
@darkness = b.darkness
|
|
134
|
+
@desc = b.desc
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def initialize(x, y, name = 'Room')
|
|
139
|
+
@exits = Array.new( DIRECTIONS.size )
|
|
140
|
+
@darkness = false
|
|
141
|
+
@name = name
|
|
142
|
+
@x = x
|
|
143
|
+
@y = y
|
|
144
|
+
|
|
145
|
+
@desc = nil
|
|
146
|
+
@objects = ''
|
|
147
|
+
@tasks = ''
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def to_s
|
|
151
|
+
"\"#{@name}\""
|
|
152
|
+
end
|
|
153
|
+
end
|
data/lib/IFMapper/Section.rb
CHANGED
|
@@ -1,234 +1,234 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require 'IFMapper/Connection'
|
|
4
|
-
require 'IFMapper/Room'
|
|
5
|
-
|
|
6
|
-
class Section
|
|
7
|
-
attr_accessor :rooms
|
|
8
|
-
attr_accessor :connections
|
|
9
|
-
attr_accessor :name
|
|
10
|
-
|
|
11
|
-
class ConnectionError < StandardError; end
|
|
12
|
-
|
|
13
|
-
def marshal_load(v)
|
|
14
|
-
@rooms = v[0]
|
|
15
|
-
@connections = v[1]
|
|
16
|
-
@name = v[2]
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def marshal_dump
|
|
20
|
-
return [ @rooms, @connections, @name ]
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
#
|
|
24
|
-
# Return the number of rooms in width and height for this page
|
|
25
|
-
#
|
|
26
|
-
def rooms_width_height
|
|
27
|
-
minXY, maxXY = min_max_rooms
|
|
28
|
-
return [
|
|
29
|
-
maxXY[0] - minXY[0] + 1,
|
|
30
|
-
maxXY[1] - minXY[1] + 1
|
|
31
|
-
]
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
#
|
|
35
|
-
# Return the min and max coordinates of all rooms in page
|
|
36
|
-
#
|
|
37
|
-
def min_max_rooms
|
|
38
|
-
return [[0, 0],[0, 0]] if @rooms.empty?
|
|
39
|
-
|
|
40
|
-
minXY = [ @rooms[0].x, @rooms[0].y ]
|
|
41
|
-
maxXY = minXY.dup
|
|
42
|
-
@rooms.each { |r|
|
|
43
|
-
minXY[0] = r.x if r.x < minXY[0]
|
|
44
|
-
minXY[1] = r.y if r.y < minXY[1]
|
|
45
|
-
maxXY[0] = r.x if r.x > maxXY[0]
|
|
46
|
-
maxXY[1] = r.y if r.y > maxXY[1]
|
|
47
|
-
}
|
|
48
|
-
return [ minXY, maxXY ]
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
#
|
|
52
|
-
# Return true or false if map is free at location x,y
|
|
53
|
-
#
|
|
54
|
-
def free?(x,y)
|
|
55
|
-
@rooms.each { |r|
|
|
56
|
-
return false if r.x == x and r.y == y
|
|
57
|
-
}
|
|
58
|
-
return true
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
#
|
|
62
|
-
# Shift rooms in dx and dy direction from x,y position on.
|
|
63
|
-
#
|
|
64
|
-
def shift(x, y, dx, dy)
|
|
65
|
-
@rooms.each { |r|
|
|
66
|
-
ox = oy = 0
|
|
67
|
-
if (dx < 0 and r.x <= x) or
|
|
68
|
-
(dx > 0 and r.x >= x)
|
|
69
|
-
ox = dx
|
|
70
|
-
end
|
|
71
|
-
if (dy < 0 and r.y <= y) or
|
|
72
|
-
(dy > 0 and r.y >= y)
|
|
73
|
-
oy = dy
|
|
74
|
-
end
|
|
75
|
-
r.x += ox
|
|
76
|
-
r.y += oy
|
|
77
|
-
}
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
#
|
|
82
|
-
# Delete a connection from section
|
|
83
|
-
#
|
|
84
|
-
def delete_connection(c)
|
|
85
|
-
a = c.roomA
|
|
86
|
-
if a
|
|
87
|
-
e = a.exits.index(c)
|
|
88
|
-
a[e] = nil if e
|
|
89
|
-
end
|
|
90
|
-
b = c.roomB
|
|
91
|
-
if b
|
|
92
|
-
e = b.exits.rindex(c)
|
|
93
|
-
b[e] = nil if e
|
|
94
|
-
end
|
|
95
|
-
@connections.delete(c)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
#
|
|
99
|
-
# Delete a connection at a certain index location
|
|
100
|
-
#
|
|
101
|
-
def delete_connection_at( idx )
|
|
102
|
-
c = @connections[idx]
|
|
103
|
-
|
|
104
|
-
a = c.roomA
|
|
105
|
-
if a
|
|
106
|
-
e = a.exits.index(c)
|
|
107
|
-
a[e] = nil if e
|
|
108
|
-
end
|
|
109
|
-
b = c.roomB
|
|
110
|
-
if b
|
|
111
|
-
e = b.exits.rindex(c)
|
|
112
|
-
b[e] = nil if e
|
|
113
|
-
end
|
|
114
|
-
@connections.delete_at(idx)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
#
|
|
118
|
-
# Create a new connection among two rooms thru their exits
|
|
119
|
-
#
|
|
120
|
-
def new_connection( roomA, exitA, roomB, exitB = nil )
|
|
121
|
-
|
|
122
|
-
# Verify rooms exist in section (ie. don't allow links across
|
|
123
|
-
# sections)
|
|
124
|
-
if not @rooms.include?(roomA)
|
|
125
|
-
raise ConnectionError, "Room '#{roomA}' not in section #{self}"
|
|
126
|
-
end
|
|
127
|
-
if roomB and not @rooms.include?(roomB)
|
|
128
|
-
raise ConnectionError, "Room '#{roomB}' not in section #{self}"
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
c = Connection.new( roomA, roomB )
|
|
132
|
-
_new_connection( c, roomA, exitA, roomB, exitB )
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
#
|
|
136
|
-
# Delete a room at a certain index
|
|
137
|
-
#
|
|
138
|
-
def delete_room_at(idx)
|
|
139
|
-
r = @rooms[idx]
|
|
140
|
-
r.exits.each { |e|
|
|
141
|
-
next if not e
|
|
142
|
-
delete_connection(e)
|
|
143
|
-
}
|
|
144
|
-
@rooms.delete_at(idx)
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
#
|
|
148
|
-
# Delete a room, leaving its connections intact
|
|
149
|
-
#
|
|
150
|
-
def delete_room_only(r)
|
|
151
|
-
@rooms.delete(r)
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
#
|
|
155
|
-
# Delete a room and all of its connections
|
|
156
|
-
#
|
|
157
|
-
def delete_room(r)
|
|
158
|
-
r.exits.each { |e|
|
|
159
|
-
next if not e
|
|
160
|
-
delete_connection(e)
|
|
161
|
-
}
|
|
162
|
-
delete_room_only(r)
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
#
|
|
166
|
-
# Create a new room (note: FXSection overrides this creating an
|
|
167
|
-
# FXRoom instead).
|
|
168
|
-
#
|
|
169
|
-
def new_room( x, y )
|
|
170
|
-
r = Room.new( x, y, 'New Location' )
|
|
171
|
-
return _new_room(r, x, y)
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
def initialize()
|
|
175
|
-
@rooms = []
|
|
176
|
-
@connections = []
|
|
177
|
-
@name = ''
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
protected
|
|
181
|
-
|
|
182
|
-
def _new_room( r, x, y )
|
|
183
|
-
@rooms.push(r)
|
|
184
|
-
return r
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
def _new_connection(c, roomA, exitA, roomB, exitB)
|
|
188
|
-
exitA = roomA.exit_to(roomB) if not exitA
|
|
189
|
-
if not exitA
|
|
190
|
-
err = <<"EOF"
|
|
191
|
-
No exit given or guessed to connect:
|
|
192
|
-
Room #{roomA} (#{roomA.x}, #{roomA.y})
|
|
193
|
-
Room #{roomB} (#{roomB.x}, #{roomB.y})
|
|
194
|
-
EOF
|
|
195
|
-
raise ConnectionError, err
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
if roomA[exitA]
|
|
199
|
-
if not @connections.include?(roomA[exitA])
|
|
200
|
-
raise ConnectionError, "roomA exit #{exitA} for '#{roomA}' filled but not in section"
|
|
201
|
-
end
|
|
202
|
-
raise ConnectionError, "roomA exit #{exitA} for '#{roomA}' is filled"
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
roomA[exitA] = c
|
|
206
|
-
|
|
207
|
-
if roomB and not exitB
|
|
208
|
-
dx, dy = Room::DIR_TO_VECTOR[exitA]
|
|
209
|
-
x = roomA.x + dx
|
|
210
|
-
y = roomA.y + dy
|
|
211
|
-
if roomB.x == x and roomB.y == y
|
|
212
|
-
exitB = (exitA + 4) % 8
|
|
213
|
-
else
|
|
214
|
-
dx = x - roomB.x
|
|
215
|
-
dy = y - roomB.y
|
|
216
|
-
exitB = roomB.vector_to_dir(dx, dy)
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
if roomB and roomB[exitB] and roomB[exitB] != c
|
|
221
|
-
roomA[exitA] = nil
|
|
222
|
-
raise ConnectionError, "roomB exit #{exitB} for #{roomB} is filled with #{roomB[exitB]}"
|
|
223
|
-
end
|
|
224
|
-
roomB[exitB] = c if roomB
|
|
225
|
-
|
|
226
|
-
@connections.push( c )
|
|
227
|
-
return c
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
def to_s
|
|
231
|
-
return @name
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
end
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
require 'IFMapper/Connection'
|
|
4
|
+
require 'IFMapper/Room'
|
|
5
|
+
|
|
6
|
+
class Section
|
|
7
|
+
attr_accessor :rooms
|
|
8
|
+
attr_accessor :connections
|
|
9
|
+
attr_accessor :name
|
|
10
|
+
|
|
11
|
+
class ConnectionError < StandardError; end
|
|
12
|
+
|
|
13
|
+
def marshal_load(v)
|
|
14
|
+
@rooms = v[0]
|
|
15
|
+
@connections = v[1]
|
|
16
|
+
@name = v[2]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def marshal_dump
|
|
20
|
+
return [ @rooms, @connections, @name ]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
# Return the number of rooms in width and height for this page
|
|
25
|
+
#
|
|
26
|
+
def rooms_width_height
|
|
27
|
+
minXY, maxXY = min_max_rooms
|
|
28
|
+
return [
|
|
29
|
+
maxXY[0] - minXY[0] + 1,
|
|
30
|
+
maxXY[1] - minXY[1] + 1
|
|
31
|
+
]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# Return the min and max coordinates of all rooms in page
|
|
36
|
+
#
|
|
37
|
+
def min_max_rooms
|
|
38
|
+
return [[0, 0],[0, 0]] if @rooms.empty?
|
|
39
|
+
|
|
40
|
+
minXY = [ @rooms[0].x, @rooms[0].y ]
|
|
41
|
+
maxXY = minXY.dup
|
|
42
|
+
@rooms.each { |r|
|
|
43
|
+
minXY[0] = r.x if r.x < minXY[0]
|
|
44
|
+
minXY[1] = r.y if r.y < minXY[1]
|
|
45
|
+
maxXY[0] = r.x if r.x > maxXY[0]
|
|
46
|
+
maxXY[1] = r.y if r.y > maxXY[1]
|
|
47
|
+
}
|
|
48
|
+
return [ minXY, maxXY ]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
#
|
|
52
|
+
# Return true or false if map is free at location x,y
|
|
53
|
+
#
|
|
54
|
+
def free?(x,y)
|
|
55
|
+
@rooms.each { |r|
|
|
56
|
+
return false if r.x == x and r.y == y
|
|
57
|
+
}
|
|
58
|
+
return true
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
#
|
|
62
|
+
# Shift rooms in dx and dy direction from x,y position on.
|
|
63
|
+
#
|
|
64
|
+
def shift(x, y, dx, dy)
|
|
65
|
+
@rooms.each { |r|
|
|
66
|
+
ox = oy = 0
|
|
67
|
+
if (dx < 0 and r.x <= x) or
|
|
68
|
+
(dx > 0 and r.x >= x)
|
|
69
|
+
ox = dx
|
|
70
|
+
end
|
|
71
|
+
if (dy < 0 and r.y <= y) or
|
|
72
|
+
(dy > 0 and r.y >= y)
|
|
73
|
+
oy = dy
|
|
74
|
+
end
|
|
75
|
+
r.x += ox
|
|
76
|
+
r.y += oy
|
|
77
|
+
}
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
#
|
|
82
|
+
# Delete a connection from section
|
|
83
|
+
#
|
|
84
|
+
def delete_connection(c)
|
|
85
|
+
a = c.roomA
|
|
86
|
+
if a
|
|
87
|
+
e = a.exits.index(c)
|
|
88
|
+
a[e] = nil if e
|
|
89
|
+
end
|
|
90
|
+
b = c.roomB
|
|
91
|
+
if b
|
|
92
|
+
e = b.exits.rindex(c)
|
|
93
|
+
b[e] = nil if e
|
|
94
|
+
end
|
|
95
|
+
@connections.delete(c)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
#
|
|
99
|
+
# Delete a connection at a certain index location
|
|
100
|
+
#
|
|
101
|
+
def delete_connection_at( idx )
|
|
102
|
+
c = @connections[idx]
|
|
103
|
+
|
|
104
|
+
a = c.roomA
|
|
105
|
+
if a
|
|
106
|
+
e = a.exits.index(c)
|
|
107
|
+
a[e] = nil if e
|
|
108
|
+
end
|
|
109
|
+
b = c.roomB
|
|
110
|
+
if b
|
|
111
|
+
e = b.exits.rindex(c)
|
|
112
|
+
b[e] = nil if e
|
|
113
|
+
end
|
|
114
|
+
@connections.delete_at(idx)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
#
|
|
118
|
+
# Create a new connection among two rooms thru their exits
|
|
119
|
+
#
|
|
120
|
+
def new_connection( roomA, exitA, roomB, exitB = nil )
|
|
121
|
+
|
|
122
|
+
# Verify rooms exist in section (ie. don't allow links across
|
|
123
|
+
# sections)
|
|
124
|
+
if not @rooms.include?(roomA)
|
|
125
|
+
raise ConnectionError, "Room '#{roomA}' not in section #{self}"
|
|
126
|
+
end
|
|
127
|
+
if roomB and not @rooms.include?(roomB)
|
|
128
|
+
raise ConnectionError, "Room '#{roomB}' not in section #{self}"
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
c = Connection.new( roomA, roomB )
|
|
132
|
+
_new_connection( c, roomA, exitA, roomB, exitB )
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
#
|
|
136
|
+
# Delete a room at a certain index
|
|
137
|
+
#
|
|
138
|
+
def delete_room_at(idx)
|
|
139
|
+
r = @rooms[idx]
|
|
140
|
+
r.exits.each { |e|
|
|
141
|
+
next if not e
|
|
142
|
+
delete_connection(e)
|
|
143
|
+
}
|
|
144
|
+
@rooms.delete_at(idx)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
#
|
|
148
|
+
# Delete a room, leaving its connections intact
|
|
149
|
+
#
|
|
150
|
+
def delete_room_only(r)
|
|
151
|
+
@rooms.delete(r)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
#
|
|
155
|
+
# Delete a room and all of its connections
|
|
156
|
+
#
|
|
157
|
+
def delete_room(r)
|
|
158
|
+
r.exits.each { |e|
|
|
159
|
+
next if not e
|
|
160
|
+
delete_connection(e)
|
|
161
|
+
}
|
|
162
|
+
delete_room_only(r)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
#
|
|
166
|
+
# Create a new room (note: FXSection overrides this creating an
|
|
167
|
+
# FXRoom instead).
|
|
168
|
+
#
|
|
169
|
+
def new_room( x, y )
|
|
170
|
+
r = Room.new( x, y, 'New Location' )
|
|
171
|
+
return _new_room(r, x, y)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def initialize()
|
|
175
|
+
@rooms = []
|
|
176
|
+
@connections = []
|
|
177
|
+
@name = ''
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
protected
|
|
181
|
+
|
|
182
|
+
def _new_room( r, x, y )
|
|
183
|
+
@rooms.push(r)
|
|
184
|
+
return r
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def _new_connection(c, roomA, exitA, roomB, exitB)
|
|
188
|
+
exitA = roomA.exit_to(roomB) if not exitA
|
|
189
|
+
if not exitA
|
|
190
|
+
err = <<"EOF"
|
|
191
|
+
No exit given or guessed to connect:
|
|
192
|
+
Room #{roomA} (#{roomA.x}, #{roomA.y})
|
|
193
|
+
Room #{roomB} (#{roomB.x}, #{roomB.y})
|
|
194
|
+
EOF
|
|
195
|
+
raise ConnectionError, err
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
if roomA[exitA]
|
|
199
|
+
if not @connections.include?(roomA[exitA])
|
|
200
|
+
raise ConnectionError, "roomA exit #{exitA} for '#{roomA}' filled but not in section"
|
|
201
|
+
end
|
|
202
|
+
raise ConnectionError, "roomA exit #{exitA} for '#{roomA}' is filled"
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
roomA[exitA] = c
|
|
206
|
+
|
|
207
|
+
if roomB and not exitB
|
|
208
|
+
dx, dy = Room::DIR_TO_VECTOR[exitA]
|
|
209
|
+
x = roomA.x + dx
|
|
210
|
+
y = roomA.y + dy
|
|
211
|
+
if roomB.x == x and roomB.y == y
|
|
212
|
+
exitB = (exitA + 4) % 8
|
|
213
|
+
else
|
|
214
|
+
dx = x - roomB.x
|
|
215
|
+
dy = y - roomB.y
|
|
216
|
+
exitB = roomB.vector_to_dir(dx, dy)
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
if roomB and roomB[exitB] and roomB[exitB] != c
|
|
221
|
+
roomA[exitA] = nil
|
|
222
|
+
raise ConnectionError, "roomB exit #{exitB} for #{roomB} is filled with #{roomB[exitB]}"
|
|
223
|
+
end
|
|
224
|
+
roomB[exitB] = c if roomB
|
|
225
|
+
|
|
226
|
+
@connections.push( c )
|
|
227
|
+
return c
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def to_s
|
|
231
|
+
return @name
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
end
|