gamefic 0.2.0 → 0.6.0
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.
- checksums.yaml +4 -4
- data/lib/gamefic/action.rb +87 -56
- data/lib/gamefic/ansi.rb +55 -0
- data/lib/gamefic/character.rb +130 -76
- data/lib/gamefic/command.rb +19 -0
- data/lib/gamefic/core_ext/array.rb +51 -40
- data/lib/gamefic/core_ext/string.rb +4 -0
- data/lib/gamefic/describable.rb +108 -46
- data/lib/gamefic/direction.rb +46 -0
- data/lib/gamefic/director/delegate.rb +91 -0
- data/lib/gamefic/director/order.rb +10 -0
- data/lib/gamefic/director/parser.rb +119 -0
- data/lib/gamefic/director.rb +16 -197
- data/lib/gamefic/engine/cgi.rb +221 -0
- data/lib/gamefic/engine/tty.rb +237 -0
- data/lib/gamefic/engine.rb +88 -67
- data/lib/gamefic/entity.rb +96 -69
- data/lib/gamefic/grammar/conjugator.rb +20 -0
- data/lib/gamefic/grammar/gender.rb +11 -0
- data/lib/gamefic/grammar/person.rb +10 -0
- data/lib/gamefic/grammar/plural.rb +13 -0
- data/lib/gamefic/grammar/pronouns.rb +60 -0
- data/lib/gamefic/grammar/tense.rb +6 -0
- data/lib/gamefic/grammar/verb_set.rb +43 -0
- data/lib/gamefic/grammar/verbs.rb +25 -0
- data/lib/gamefic/grammar/word_adapter.rb +36 -0
- data/lib/gamefic/grammar.rb +13 -0
- data/lib/gamefic/html.rb +53 -0
- data/lib/gamefic/keywords.rb +51 -33
- data/lib/gamefic/node.rb +65 -58
- data/lib/gamefic/plot/article_mount.rb +22 -0
- data/lib/gamefic/plot/command_mount.rb +88 -0
- data/lib/gamefic/plot/entity_mount.rb +45 -0
- data/lib/gamefic/plot/query_mount.rb +9 -0
- data/lib/gamefic/plot/scene_mount.rb +181 -0
- data/lib/gamefic/plot/you_mount.rb +22 -0
- data/lib/gamefic/plot.rb +296 -247
- data/lib/gamefic/query/ambiguous_children.rb +5 -0
- data/lib/gamefic/query/base.rb +265 -0
- data/lib/gamefic/query/children.rb +10 -0
- data/lib/gamefic/query/expression.rb +47 -0
- data/lib/gamefic/query/family.rb +10 -0
- data/lib/gamefic/query/many_children.rb +7 -0
- data/lib/gamefic/query/matches.rb +11 -0
- data/lib/gamefic/query/parent.rb +10 -0
- data/lib/gamefic/query/plural_children.rb +14 -0
- data/lib/gamefic/query/self.rb +10 -0
- data/lib/gamefic/query/siblings.rb +10 -0
- data/lib/gamefic/query/text.rb +43 -0
- data/lib/gamefic/query.rb +19 -203
- data/lib/gamefic/rule.rb +18 -0
- data/lib/gamefic/scene/active.rb +25 -0
- data/lib/gamefic/scene/concluded.rb +22 -0
- data/lib/gamefic/scene/multiplechoice.rb +74 -0
- data/lib/gamefic/scene/paused.rb +26 -0
- data/lib/gamefic/scene/yesorno.rb +43 -0
- data/lib/gamefic/scene.rb +125 -0
- data/lib/gamefic/script/base.rb +33 -0
- data/lib/gamefic/script/file.rb +14 -0
- data/lib/gamefic/script/text.rb +14 -0
- data/lib/gamefic/script.rb +9 -0
- data/lib/gamefic/serialized.rb +24 -0
- data/lib/gamefic/shell.rb +9 -247
- data/lib/gamefic/snapshots.rb +134 -0
- data/lib/gamefic/source/base.rb +12 -0
- data/lib/gamefic/source/file.rb +23 -0
- data/lib/gamefic/source/text.rb +16 -0
- data/lib/gamefic/source.rb +9 -0
- data/lib/gamefic/stage.rb +75 -0
- data/lib/gamefic/syntax.rb +106 -124
- data/lib/gamefic/tester.rb +20 -0
- data/lib/gamefic/version.rb +3 -0
- data/lib/gamefic.rb +18 -12
- metadata +102 -70
- data/lib/gamefic/base.rb +0 -10
- data/lib/gamefic/before.rb +0 -12
- data/lib/gamefic/import/basics/actions/close.rb +0 -16
- data/lib/gamefic/import/basics/actions/commands.rb +0 -3
- data/lib/gamefic/import/basics/actions/drop-in.rb +0 -17
- data/lib/gamefic/import/basics/actions/drop-on.rb +0 -16
- data/lib/gamefic/import/basics/actions/drop.rb +0 -30
- data/lib/gamefic/import/basics/actions/enter.rb +0 -16
- data/lib/gamefic/import/basics/actions/go.rb +0 -35
- data/lib/gamefic/import/basics/actions/inventory.rb +0 -8
- data/lib/gamefic/import/basics/actions/leave.rb +0 -29
- data/lib/gamefic/import/basics/actions/look-in-at.rb +0 -27
- data/lib/gamefic/import/basics/actions/look-under.rb +0 -3
- data/lib/gamefic/import/basics/actions/look.rb +0 -71
- data/lib/gamefic/import/basics/actions/nil.rb +0 -25
- data/lib/gamefic/import/basics/actions/open.rb +0 -23
- data/lib/gamefic/import/basics/actions/quit.rb +0 -3
- data/lib/gamefic/import/basics/actions/take.rb +0 -107
- data/lib/gamefic/import/basics/entities/container.rb +0 -8
- data/lib/gamefic/import/basics/entities/entity.rb +0 -11
- data/lib/gamefic/import/basics/entities/fixture.rb +0 -5
- data/lib/gamefic/import/basics/entities/item.rb +0 -5
- data/lib/gamefic/import/basics/entities/portal.rb +0 -40
- data/lib/gamefic/import/basics/entities/room.rb +0 -30
- data/lib/gamefic/import/basics/entities/scenery.rb +0 -5
- data/lib/gamefic/import/basics/entities/supporter.rb +0 -6
- data/lib/gamefic/import/basics/entities/thing.rb +0 -16
- data/lib/gamefic/import/basics/queries/reachable.rb +0 -38
- data/lib/gamefic/import/basics/queries/room.rb +0 -8
- data/lib/gamefic/import/basics/queries/visible.rb +0 -32
- data/lib/gamefic/import/basics/rules/has-enough-light.rb +0 -14
- data/lib/gamefic/import/basics.old/actions/container.rb +0 -112
- data/lib/gamefic/import/basics.old/actions/inventory.rb +0 -50
- data/lib/gamefic/import/basics.old/actions/look.rb +0 -53
- data/lib/gamefic/import/basics.old/actions/meta.rb +0 -6
- data/lib/gamefic/import/basics.old/actions/traversal.rb +0 -35
- data/lib/gamefic/import/basics.old/actions.rb +0 -1
- data/lib/gamefic/import/basics.old/entities/container.rb +0 -3
- data/lib/gamefic/import/basics.old/entities/fixture.rb +0 -3
- data/lib/gamefic/import/basics.old/entities/item.rb +0 -3
- data/lib/gamefic/import/basics.old/entities/portal.rb +0 -43
- data/lib/gamefic/import/basics.old/entities/room.rb +0 -27
- data/lib/gamefic/import/basics.old/entities/scenery.rb +0 -3
- data/lib/gamefic/import/basics.old/entities/supporter.rb +0 -3
- data/lib/gamefic/import/basics.old/entities.rb +0 -1
- data/lib/gamefic/import/basics.old/room_modes.rb +0 -48
- data/lib/gamefic/import/basics.rb +0 -6
- data/lib/gamefic/import/room_modes.rb +0 -48
- data/lib/gamefic/import/standard.rb +0 -1
- data/lib/gamefic/meta.rb +0 -12
- data/lib/gamefic/optionset.rb +0 -114
- data/lib/gamefic/requirement.rb +0 -14
- data/lib/gamefic/story.rb +0 -14
- data/lib/gamefic/thing.rb +0 -7
data/lib/gamefic/shell.rb
CHANGED
|
@@ -1,23 +1,8 @@
|
|
|
1
|
-
require '
|
|
2
|
-
require 'rubygems/package'
|
|
3
|
-
require 'zlib'
|
|
1
|
+
require 'zip'
|
|
4
2
|
require 'tmpdir'
|
|
5
3
|
require 'getoptlong'
|
|
6
4
|
require 'gamefic/engine/tty'
|
|
7
5
|
|
|
8
|
-
# Crazy hack to set file mtimes in tar file
|
|
9
|
-
class Gem::Package::TarHeader
|
|
10
|
-
@@mtime = Time.now
|
|
11
|
-
def self.set_mtime(time)
|
|
12
|
-
@@mtime = time
|
|
13
|
-
end
|
|
14
|
-
alias :initialize_orig :initialize
|
|
15
|
-
def initialize(vals)
|
|
16
|
-
initialize_orig(vals)
|
|
17
|
-
@mtime = @@mtime
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
6
|
module Gamefic
|
|
22
7
|
|
|
23
8
|
class Shell
|
|
@@ -33,14 +18,6 @@ module Gamefic
|
|
|
33
18
|
case cmd
|
|
34
19
|
when 'play'
|
|
35
20
|
play ARGV.shift
|
|
36
|
-
when 'test'
|
|
37
|
-
test ARGV.shift
|
|
38
|
-
when 'init'
|
|
39
|
-
init ARGV.shift
|
|
40
|
-
when 'build'
|
|
41
|
-
build ARGV.shift
|
|
42
|
-
when 'fetch'
|
|
43
|
-
fetch ARGV.shift
|
|
44
21
|
when 'help'
|
|
45
22
|
help ARGV.shift
|
|
46
23
|
else
|
|
@@ -59,177 +36,20 @@ module Gamefic
|
|
|
59
36
|
end
|
|
60
37
|
Dir.mktmpdir 'gamefic_' do |dir|
|
|
61
38
|
puts "Loading..."
|
|
62
|
-
story =
|
|
39
|
+
story = Plot.new(Source.new(dir + '/scripts'))
|
|
63
40
|
begin
|
|
64
41
|
decompress file, dir
|
|
65
42
|
rescue Exception => e
|
|
66
43
|
puts "'#{file}' does not appear to be a valid Gamefic file."
|
|
67
|
-
puts
|
|
44
|
+
puts e.backtrace
|
|
68
45
|
exit 1
|
|
69
46
|
end
|
|
70
|
-
story.load dir + '/main
|
|
47
|
+
story.load dir + '/main'
|
|
71
48
|
engine = Tty::Engine.new story
|
|
72
49
|
puts "\n"
|
|
73
50
|
engine.run
|
|
74
51
|
end
|
|
75
52
|
end
|
|
76
|
-
def test path
|
|
77
|
-
puts "Loading..."
|
|
78
|
-
story = Story.new
|
|
79
|
-
#begin
|
|
80
|
-
if File.directory?(path)
|
|
81
|
-
if !File.file?(path + '/main.rb')
|
|
82
|
-
raise "#{path}/main.rb does not exist"
|
|
83
|
-
end
|
|
84
|
-
story.load path + '/main.rb', true
|
|
85
|
-
else
|
|
86
|
-
story.load path
|
|
87
|
-
end
|
|
88
|
-
#rescue Exception => e
|
|
89
|
-
# puts "An error occurred in #{path}:"
|
|
90
|
-
# puts "#{e.inspect}"
|
|
91
|
-
# exit 1
|
|
92
|
-
#end
|
|
93
|
-
engine = Tty::Engine.new story
|
|
94
|
-
puts "\n"
|
|
95
|
-
engine.run
|
|
96
|
-
end
|
|
97
|
-
def init directory
|
|
98
|
-
if directory.to_s == ''
|
|
99
|
-
puts "No directory specified."
|
|
100
|
-
exit 1
|
|
101
|
-
elsif File.exist?(directory)
|
|
102
|
-
if !File.directory?(directory)
|
|
103
|
-
files = Dir[directory + '/*']
|
|
104
|
-
if files.length > 0
|
|
105
|
-
puts "'#{directory}' is not an empty directory."
|
|
106
|
-
exit 1
|
|
107
|
-
end
|
|
108
|
-
else
|
|
109
|
-
puts "'#{directory}' is not an empty directory."
|
|
110
|
-
exit 1
|
|
111
|
-
end
|
|
112
|
-
else
|
|
113
|
-
Dir.mkdir(directory)
|
|
114
|
-
end
|
|
115
|
-
Dir.mkdir(directory + '/import')
|
|
116
|
-
main_rb = File.new(directory + '/main.rb', 'w')
|
|
117
|
-
main_rb.write <<EOS
|
|
118
|
-
import 'standard'
|
|
119
|
-
|
|
120
|
-
room = make Room, :name => 'room'
|
|
121
|
-
|
|
122
|
-
introduction do |player|
|
|
123
|
-
player.parent = room
|
|
124
|
-
player.perform "look"
|
|
125
|
-
end
|
|
126
|
-
EOS
|
|
127
|
-
main_rb.close
|
|
128
|
-
#fetch directory
|
|
129
|
-
puts "Game directory '#{directory}' initialized."
|
|
130
|
-
end
|
|
131
|
-
def fetch directory
|
|
132
|
-
if directory.to_s == ''
|
|
133
|
-
puts "No source directory was specified."
|
|
134
|
-
exit 1
|
|
135
|
-
end
|
|
136
|
-
if !File.directory?(directory)
|
|
137
|
-
puts "#{directory} is not a directory."
|
|
138
|
-
exit 1
|
|
139
|
-
end
|
|
140
|
-
puts "Loading game data..."
|
|
141
|
-
story = Story.new
|
|
142
|
-
begin
|
|
143
|
-
story.load directory + '/main.rb', true
|
|
144
|
-
rescue Exception => e
|
|
145
|
-
puts "'#{directory}' has errors or is not a valid source directory."
|
|
146
|
-
puts "#{e}"
|
|
147
|
-
exit 1
|
|
148
|
-
end
|
|
149
|
-
puts "Checking for external script references..."
|
|
150
|
-
fetched = 0
|
|
151
|
-
story.imported_scripts.each { |script|
|
|
152
|
-
if !script.filename.start_with?(directory)
|
|
153
|
-
base = script.filename[(script.filename.rindex('import/') + 7)..-1]
|
|
154
|
-
puts "Fetching #{base}"
|
|
155
|
-
FileUtils.mkdir_p directory + '/import/' + File.dirname(base)
|
|
156
|
-
FileUtils.copy script.filename, directory + '/import/' + base
|
|
157
|
-
fetched += 1
|
|
158
|
-
end
|
|
159
|
-
}
|
|
160
|
-
if fetched == 0
|
|
161
|
-
puts "Nothing to fetch."
|
|
162
|
-
else
|
|
163
|
-
puts "Done."
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
def build directory
|
|
167
|
-
if directory.to_s == ''
|
|
168
|
-
puts "No source directory was specified."
|
|
169
|
-
exit 1
|
|
170
|
-
end
|
|
171
|
-
if !File.directory?(directory)
|
|
172
|
-
puts "#{directory} is not a directory."
|
|
173
|
-
exit 1
|
|
174
|
-
end
|
|
175
|
-
filename = File.basename(directory) + '.gfic'
|
|
176
|
-
opts = GetoptLong.new(
|
|
177
|
-
[ '-o', '--output', GetoptLong::REQUIRED_ARGUMENT ]
|
|
178
|
-
)
|
|
179
|
-
opts.quiet = true
|
|
180
|
-
begin
|
|
181
|
-
opts.each { |opt, arg|
|
|
182
|
-
case opt
|
|
183
|
-
when '-o'
|
|
184
|
-
filename = arg
|
|
185
|
-
end
|
|
186
|
-
}
|
|
187
|
-
rescue Exception => e
|
|
188
|
-
puts "#{e}"
|
|
189
|
-
exit 1
|
|
190
|
-
end
|
|
191
|
-
if File.exist?(filename)
|
|
192
|
-
puts "The file #{filename} already exists."
|
|
193
|
-
exit 1
|
|
194
|
-
end
|
|
195
|
-
story = Story.new
|
|
196
|
-
puts "Loading game data..."
|
|
197
|
-
begin
|
|
198
|
-
story.load directory + '/main.rb', true
|
|
199
|
-
rescue Exception => e
|
|
200
|
-
puts "'#{directory}' has errors or is not a valid source directory."
|
|
201
|
-
puts "#{e}"
|
|
202
|
-
exit 1
|
|
203
|
-
end
|
|
204
|
-
puts "Building file..."
|
|
205
|
-
stream = StringIO.new("")
|
|
206
|
-
Gem::Package::TarWriter.new(stream) do |tar|
|
|
207
|
-
Gem::Package::TarHeader.set_mtime Time.now
|
|
208
|
-
tar.add_file('main.rb', 0600) do |io|
|
|
209
|
-
File.open(directory + '/main.rb', "rb") { |f| io.write f.read }
|
|
210
|
-
end
|
|
211
|
-
if story.imported_scripts.length > 0
|
|
212
|
-
Gem::Package::TarHeader.set_mtime Time.now
|
|
213
|
-
tar.mkdir('import', 0700)
|
|
214
|
-
story.imported_scripts.each { |script|
|
|
215
|
-
base = script.filename[script.filename.rindex('import/') + 7..-1]
|
|
216
|
-
Gem::Package::TarHeader.set_mtime Time.now
|
|
217
|
-
tar.add_file('import/' + base, 0700) do |io|
|
|
218
|
-
io.write script.code
|
|
219
|
-
end
|
|
220
|
-
}
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
gz = StringIO.new("")
|
|
224
|
-
z = Zlib::GzipWriter.new(gz)
|
|
225
|
-
z.mtime = Time.now
|
|
226
|
-
z.write stream.string
|
|
227
|
-
z.close
|
|
228
|
-
file = File.new(filename, "w")
|
|
229
|
-
file.write gz.string
|
|
230
|
-
file.close
|
|
231
|
-
puts "Gamefic file '#{filename}' complete."
|
|
232
|
-
end
|
|
233
53
|
def help command
|
|
234
54
|
shell_script = File.basename($0)
|
|
235
55
|
case command
|
|
@@ -237,40 +57,10 @@ EOS
|
|
|
237
57
|
puts <<EOS
|
|
238
58
|
#{shell_script} play [file]
|
|
239
59
|
Play a Gamefic file on the command line.
|
|
240
|
-
EOS
|
|
241
|
-
when "test"
|
|
242
|
-
puts <<EOS
|
|
243
|
-
#{shell_script} test [path]
|
|
244
|
-
Test a Gamefic source directory or script.
|
|
245
|
-
EOS
|
|
246
|
-
when "init"
|
|
247
|
-
puts <<EOS
|
|
248
|
-
#{shell_script} init [directory]
|
|
249
|
-
Initialize a Gamefic source directory. The resulting directory will contain
|
|
250
|
-
source files ready to build into a Gamefic file.
|
|
251
|
-
EOS
|
|
252
|
-
when "fetch"
|
|
253
|
-
puts <<EOS
|
|
254
|
-
#{shell_script} fetch [directory]
|
|
255
|
-
Copy shared scripts to the source directory.
|
|
256
|
-
If the specified game directory imnports external scripts, such as the ones
|
|
257
|
-
that are distributed with the Gamefic gem, this command will copy them into
|
|
258
|
-
the game's import directory. Fetching can be useful if you want to customize
|
|
259
|
-
common features.
|
|
260
|
-
EOS
|
|
261
|
-
when "build"
|
|
262
|
-
puts <<EOS
|
|
263
|
-
#{shell_script} build [directory] [-o | --output filename]
|
|
264
|
-
Build a distributable Gamefic file from the source directory. The default
|
|
265
|
-
filename is [directory].gfic. You can change the filename with the -o option.
|
|
266
60
|
EOS
|
|
267
61
|
when nil, "help"
|
|
268
62
|
puts <<EOS
|
|
269
63
|
#{shell_script} play [file] - play a Gamefic file
|
|
270
|
-
#{shell_script} init [dir] - initialize a Gamefic source directory
|
|
271
|
-
#{shell_script} test [path] - test a Gamefic source directory or script
|
|
272
|
-
#{shell_script} fetch [directory] - copy shared scripts into directory
|
|
273
|
-
#{shell_script} build [directory] - build a Gamefic file
|
|
274
64
|
#{shell_script} help - display this message
|
|
275
65
|
#{shell_script} help [command] - display info about command
|
|
276
66
|
EOS
|
|
@@ -279,39 +69,11 @@ EOS
|
|
|
279
69
|
exit 1
|
|
280
70
|
end
|
|
281
71
|
end
|
|
282
|
-
def decompress(
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
if entry.full_name == tar_longlink
|
|
288
|
-
dest = File.join destination, entry.read.strip
|
|
289
|
-
next
|
|
290
|
-
end
|
|
291
|
-
dest ||= File.join destination, entry.full_name
|
|
292
|
-
if entry.directory?
|
|
293
|
-
FileUtils.rm_rf dest unless File.directory? dest
|
|
294
|
-
FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false
|
|
295
|
-
elsif entry.file?
|
|
296
|
-
cur_stack = dest.split('/')
|
|
297
|
-
cur_stack.pop
|
|
298
|
-
cur_dir = ''
|
|
299
|
-
while cur_stack.length > 0
|
|
300
|
-
cur_dir += '/' + cur_stack.shift
|
|
301
|
-
if !File.exist?(destination + cur_dir)
|
|
302
|
-
FileUtils.mkdir_p dest, :mode => 0700, :verbose => false
|
|
303
|
-
end
|
|
304
|
-
end
|
|
305
|
-
FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false
|
|
306
|
-
FileUtils.rm_rf dest unless File.file? dest
|
|
307
|
-
File.open dest, "wb" do |f|
|
|
308
|
-
f.print entry.read
|
|
309
|
-
end
|
|
310
|
-
FileUtils.chmod entry.header.mode, dest, :verbose => false
|
|
311
|
-
elsif entry.header.typeflag == '2' #Symlink!
|
|
312
|
-
File.symlink entry.header.linkname, dest
|
|
313
|
-
end
|
|
314
|
-
dest = nil
|
|
72
|
+
def decompress(zipfile, destination)
|
|
73
|
+
Zip::File.open(zipfile) do |z|
|
|
74
|
+
z.each do |entry|
|
|
75
|
+
FileUtils.mkdir_p "#{destination}/#{File.dirname(entry.name)}"
|
|
76
|
+
entry.extract "#{destination}/#{entry.name}"
|
|
315
77
|
end
|
|
316
78
|
end
|
|
317
79
|
end
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
module Gamefic
|
|
4
|
+
class Snapshots
|
|
5
|
+
attr_accessor :history
|
|
6
|
+
def initialize entities
|
|
7
|
+
@history = []
|
|
8
|
+
@entities = entities
|
|
9
|
+
end
|
|
10
|
+
def save entities
|
|
11
|
+
store = []
|
|
12
|
+
index = 0
|
|
13
|
+
entities.each { |e|
|
|
14
|
+
hash = {}
|
|
15
|
+
e.serialized_attributes.each {|m|
|
|
16
|
+
con = m.to_s
|
|
17
|
+
if con.end_with?("?")
|
|
18
|
+
con = con[0..-2]
|
|
19
|
+
end
|
|
20
|
+
if e.respond_to?(m) == true
|
|
21
|
+
begin
|
|
22
|
+
xxx = e.send(m)
|
|
23
|
+
if xxx == false
|
|
24
|
+
hash[con] = false
|
|
25
|
+
elsif xxx
|
|
26
|
+
hash[con] = serialize_obj(xxx)
|
|
27
|
+
else
|
|
28
|
+
hash[con] = nil
|
|
29
|
+
end
|
|
30
|
+
rescue Exception => error
|
|
31
|
+
hash[con] = nil
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
}
|
|
35
|
+
hash[:session] = {}
|
|
36
|
+
e.session.each_pair { |k, v|
|
|
37
|
+
hash[:session][k] = serialize_obj(v)
|
|
38
|
+
}
|
|
39
|
+
store.push hash
|
|
40
|
+
index += 1
|
|
41
|
+
}
|
|
42
|
+
if @history.length > 10
|
|
43
|
+
@history.shift
|
|
44
|
+
end
|
|
45
|
+
json = JSON.generate(store)
|
|
46
|
+
#puts json
|
|
47
|
+
json
|
|
48
|
+
end
|
|
49
|
+
def restore snapshot
|
|
50
|
+
data = JSON.parse(snapshot)
|
|
51
|
+
index = 0
|
|
52
|
+
data.each { |hash|
|
|
53
|
+
hash.each_pair { |k, v|
|
|
54
|
+
@entities[index].send("#{k}=", unserialize(v)) if k.to_s != "session"
|
|
55
|
+
}
|
|
56
|
+
#unser = unserialize(hash["session"])
|
|
57
|
+
hash["session"].each_pair { |k, v|
|
|
58
|
+
@entities[index].session[k.to_sym] = unserialize(v)
|
|
59
|
+
}
|
|
60
|
+
index += 1
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
def blacklist
|
|
64
|
+
[:children, :session, :scene, :object_of_pronoun, :test_queue, :test_queue_scene, :test_queue_length, :testing]
|
|
65
|
+
end
|
|
66
|
+
private
|
|
67
|
+
def can_serialize? obj
|
|
68
|
+
return true if (obj == true or obj == false or obj.nil?)
|
|
69
|
+
allowed = [String, Fixnum, Float, Numeric, Entity, Direction, Hash, Array, Symbol]
|
|
70
|
+
allowed.each { |a|
|
|
71
|
+
return true if obj.kind_of?(a)
|
|
72
|
+
}
|
|
73
|
+
false
|
|
74
|
+
end
|
|
75
|
+
def serialize_obj obj
|
|
76
|
+
return nil if obj.nil?
|
|
77
|
+
return false if obj == false
|
|
78
|
+
if obj.kind_of?(Hash)
|
|
79
|
+
hash = {}
|
|
80
|
+
obj.each_pair { |k, v|
|
|
81
|
+
if can_serialize?(k) and can_serialize?(v)
|
|
82
|
+
hash[serialize_obj(k)] = serialize_obj(v)
|
|
83
|
+
end
|
|
84
|
+
}
|
|
85
|
+
return hash
|
|
86
|
+
elsif obj.kind_of?(Array)
|
|
87
|
+
arr = []
|
|
88
|
+
obj.each_index { |i|
|
|
89
|
+
if can_serialize?(obj[i])
|
|
90
|
+
arr[i] = serialize_obj(obj[i])
|
|
91
|
+
else
|
|
92
|
+
raise "Bad array in snapshot"
|
|
93
|
+
end
|
|
94
|
+
}
|
|
95
|
+
return arr
|
|
96
|
+
else
|
|
97
|
+
if obj.kind_of?(Entity)
|
|
98
|
+
return "#<EIN_#{@entities.index(obj)}>"
|
|
99
|
+
elsif obj.kind_of?(Direction)
|
|
100
|
+
return "#<DIR_#{obj.name}>"
|
|
101
|
+
#elsif obj.kind_of?(Symbol)
|
|
102
|
+
# return "#<SYM_#{obj.to_s}>"
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
return obj
|
|
106
|
+
end
|
|
107
|
+
def unserialize obj
|
|
108
|
+
if obj.kind_of?(Hash)
|
|
109
|
+
hash = {}
|
|
110
|
+
obj.each_pair { |k, v|
|
|
111
|
+
hash[unserialize(k)] = unserialize(v)
|
|
112
|
+
}
|
|
113
|
+
hash
|
|
114
|
+
elsif obj.kind_of?(Array)
|
|
115
|
+
arr = []
|
|
116
|
+
obj.each_index { |i|
|
|
117
|
+
arr[i] = unserialize(obj[i])
|
|
118
|
+
}
|
|
119
|
+
arr
|
|
120
|
+
else
|
|
121
|
+
if obj.to_s.match(/^#<EIN_[0-9]+>$/)
|
|
122
|
+
i = obj[6..-2].to_i
|
|
123
|
+
@entities[i]
|
|
124
|
+
elsif obj.to_s.match(/^#<DIR_[a-z]+>$/)
|
|
125
|
+
Direction.find(obj[6..-2])
|
|
126
|
+
#elsif obj.to_s.match(/^#<SYM_[a-z]+>$/)
|
|
127
|
+
# Direction.find(obj[6..-2].to_sym)
|
|
128
|
+
else
|
|
129
|
+
obj
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Gamefic
|
|
2
|
+
|
|
3
|
+
class Source::File < Source::Base
|
|
4
|
+
@@extensions = ['.plot.rb', '.plot', '.rb']
|
|
5
|
+
attr_reader :directories
|
|
6
|
+
attr_accessor :main_dir
|
|
7
|
+
def initialize(*directories)
|
|
8
|
+
@directories = directories || []
|
|
9
|
+
end
|
|
10
|
+
def export path
|
|
11
|
+
@directories.each { |directory|
|
|
12
|
+
@@extensions.each { |ext|
|
|
13
|
+
abs_file = directory + '/' + path + ext
|
|
14
|
+
if File.file?(abs_file)
|
|
15
|
+
return Script::File.new(abs_file, path)
|
|
16
|
+
end
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
raise "Script #{path} not found"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Gamefic
|
|
2
|
+
|
|
3
|
+
class Source::Text < Source::Base
|
|
4
|
+
def initialize scripts = {}
|
|
5
|
+
@scripts = scripts
|
|
6
|
+
end
|
|
7
|
+
def export path
|
|
8
|
+
if @scripts.has_key?(path)
|
|
9
|
+
Script::Text.new(path, @scripts[path])
|
|
10
|
+
else
|
|
11
|
+
raise "Script #{path} not found"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module Gamefic
|
|
2
|
+
|
|
3
|
+
module Stage
|
|
4
|
+
def stage *args, &block
|
|
5
|
+
s = generate_stage
|
|
6
|
+
|
|
7
|
+
if block.nil?
|
|
8
|
+
s.module_eval(*args)
|
|
9
|
+
else
|
|
10
|
+
s.module_exec(*args, &block)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
private
|
|
14
|
+
def generate_stage
|
|
15
|
+
return @stage if !@stage.nil?
|
|
16
|
+
|
|
17
|
+
exposed = self.class.exposed_methods.keys
|
|
18
|
+
mounted = self.class.mounted_modules.keys
|
|
19
|
+
instance = self
|
|
20
|
+
|
|
21
|
+
@stage = Module.new do
|
|
22
|
+
define_singleton_method(:__instance__) do
|
|
23
|
+
unless caller.length == 0 or caller[0].include?(__FILE__)
|
|
24
|
+
raise NoMethodError.new("Method __instance__ is not available from the stage.")
|
|
25
|
+
end
|
|
26
|
+
instance
|
|
27
|
+
end
|
|
28
|
+
exposed.each do |exposed_method|
|
|
29
|
+
define_singleton_method(exposed_method) do |*args, &block|
|
|
30
|
+
__instance__.public_send(exposed_method, *args, &block)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
mounted.each { |dsl|
|
|
34
|
+
dsl.public_instance_methods.each { |method|
|
|
35
|
+
define_singleton_method(method) do |*args, &block|
|
|
36
|
+
#puts "Calling a mounted method"
|
|
37
|
+
result = __instance__.public_send(method, *args, &block)
|
|
38
|
+
#puts "Done"
|
|
39
|
+
result
|
|
40
|
+
end
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
return @stage
|
|
46
|
+
end
|
|
47
|
+
module ClassMethods
|
|
48
|
+
def mount *args
|
|
49
|
+
args.each { |a|
|
|
50
|
+
include a
|
|
51
|
+
mounted_modules[a] = nil
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
def expose *args
|
|
55
|
+
args.each { |a|
|
|
56
|
+
exposed_methods[a] = nil
|
|
57
|
+
}
|
|
58
|
+
end
|
|
59
|
+
def exposed_methods
|
|
60
|
+
@@exposed_methods ||= from_superclass(:exposed_methods, {}).dup
|
|
61
|
+
end
|
|
62
|
+
def mounted_modules
|
|
63
|
+
@@mounted_modules ||= from_superclass(:mounted_modules, {}).dup
|
|
64
|
+
end
|
|
65
|
+
private
|
|
66
|
+
def from_superclass(m, default = nil)
|
|
67
|
+
superclass.respond_to?(m) ? superclass.send(m) : default
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
def self.included(base)
|
|
71
|
+
base.extend(ClassMethods)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|