gamefic 0.1.1 → 0.2.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 +7 -6
- data/lib/gamefic/before.rb +12 -0
- data/lib/gamefic/character.rb +1 -1
- data/lib/gamefic/core_ext/array.rb +4 -0
- data/lib/gamefic/core_ext/string.rb +0 -31
- data/lib/gamefic/describable.rb +68 -8
- data/lib/gamefic/director.rb +108 -75
- data/lib/gamefic/engine.rb +74 -10
- data/lib/gamefic/entity.rb +3 -3
- data/lib/gamefic/import/basics/actions/close.rb +16 -0
- data/lib/gamefic/import/basics/actions/commands.rb +3 -0
- data/lib/gamefic/import/basics/actions/drop-in.rb +17 -0
- data/lib/gamefic/import/basics/actions/drop-on.rb +16 -0
- data/lib/gamefic/import/basics/actions/drop.rb +30 -0
- data/lib/gamefic/import/basics/actions/enter.rb +16 -0
- data/lib/gamefic/import/basics/actions/{traversal.rb → go.rb} +35 -35
- data/lib/gamefic/import/basics/actions/inventory.rb +8 -49
- data/lib/gamefic/import/basics/actions/leave.rb +29 -0
- data/lib/gamefic/import/basics/actions/look-in-at.rb +27 -0
- data/lib/gamefic/import/basics/actions/look-under.rb +3 -0
- data/lib/gamefic/import/basics/actions/look.rb +71 -67
- data/lib/gamefic/import/basics/actions/nil.rb +25 -0
- data/lib/gamefic/import/basics/actions/open.rb +23 -0
- data/lib/gamefic/import/basics/actions/quit.rb +3 -0
- data/lib/gamefic/import/basics/actions/take.rb +107 -0
- data/lib/gamefic/import/basics/entities/container.rb +8 -24
- data/lib/gamefic/import/basics/entities/entity.rb +11 -0
- data/lib/gamefic/import/basics/entities/fixture.rb +5 -5
- data/lib/gamefic/import/basics/entities/item.rb +5 -7
- data/lib/gamefic/import/basics/entities/portal.rb +40 -43
- data/lib/gamefic/import/basics/entities/room.rb +30 -24
- data/lib/gamefic/import/basics/entities/scenery.rb +5 -3
- data/lib/gamefic/import/basics/entities/supporter.rb +6 -0
- data/lib/gamefic/import/basics/entities/thing.rb +16 -0
- data/lib/gamefic/import/basics/queries/reachable.rb +38 -0
- data/lib/gamefic/import/basics/queries/room.rb +8 -0
- data/lib/gamefic/import/basics/queries/visible.rb +32 -0
- data/lib/gamefic/import/basics/rules/has-enough-light.rb +14 -0
- data/lib/gamefic/import/{basics → basics.old}/actions/container.rb +13 -12
- data/lib/gamefic/import/basics.old/actions/inventory.rb +50 -0
- data/lib/gamefic/import/basics.old/actions/look.rb +53 -0
- data/lib/gamefic/import/basics.old/actions/meta.rb +6 -0
- data/lib/gamefic/import/basics.old/actions/traversal.rb +35 -0
- data/lib/gamefic/import/{basics → basics.old}/actions.rb +0 -0
- data/lib/gamefic/import/basics.old/entities/container.rb +3 -0
- data/lib/gamefic/import/basics.old/entities/fixture.rb +3 -0
- data/lib/gamefic/import/basics.old/entities/item.rb +3 -0
- data/lib/gamefic/import/basics.old/entities/portal.rb +43 -0
- data/lib/gamefic/import/basics.old/entities/room.rb +27 -0
- data/lib/gamefic/import/basics.old/entities/scenery.rb +3 -0
- data/lib/gamefic/import/basics.old/entities/supporter.rb +3 -0
- data/lib/gamefic/import/{basics → basics.old}/entities.rb +0 -0
- data/lib/gamefic/import/basics.old/room_modes.rb +48 -0
- data/lib/gamefic/import/basics.rb +6 -2
- data/lib/gamefic/import/{basics/room_modes.rb → room_modes.rb} +6 -6
- data/lib/gamefic/import/standard.rb +1 -0
- data/lib/gamefic/meta.rb +12 -0
- data/lib/gamefic/optionset.rb +114 -0
- data/lib/gamefic/plot.rb +54 -21
- data/lib/gamefic/query.rb +214 -188
- data/lib/gamefic/requirement.rb +14 -0
- data/lib/gamefic/shell.rb +7 -4
- data/lib/gamefic/syntax.rb +35 -18
- data/lib/gamefic/thing.rb +7 -0
- data/lib/gamefic.rb +5 -1
- metadata +46 -12
- data/lib/gamefic/import/basics/actions/meta.rb +0 -6
- data/lib/gamefic/import/basics/entities/itemized.rb +0 -3
- data/lib/gamefic/import/basics/entities/portable.rb +0 -3
- data/lib/gamefic/user.rb +0 -66
@@ -7,11 +7,11 @@ module RoomModes
|
|
7
7
|
if value.kind_of?(Array)
|
8
8
|
@description_seen = value
|
9
9
|
else
|
10
|
-
raise "Character#
|
10
|
+
raise "Character#description_seen must be an Array"
|
11
11
|
end
|
12
12
|
end
|
13
13
|
def description_mode
|
14
|
-
@description_mode ||= "
|
14
|
+
@description_mode ||= "verbose"
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -19,13 +19,13 @@ class Character
|
|
19
19
|
include RoomModes
|
20
20
|
end
|
21
21
|
|
22
|
-
respond :go, Query.new(
|
22
|
+
respond :go, Query::Siblings.new(Portal) do |actor, portal|
|
23
23
|
actor.tell "You go #{portal.name}."
|
24
24
|
actor.parent = portal.destination
|
25
25
|
if actor.description_mode == "superbrief" or (actor.description_mode == "brief" and actor.description_seen.include?(actor.parent))
|
26
|
-
actor.
|
26
|
+
actor.tell actor.parent.name.cap_first
|
27
27
|
else
|
28
|
-
actor.perform "
|
28
|
+
actor.perform "look"
|
29
29
|
end
|
30
30
|
if actor.description_seen.include?(actor.parent) == false
|
31
31
|
actor.description_seen.push actor.parent
|
@@ -44,5 +44,5 @@ end
|
|
44
44
|
|
45
45
|
respond :superbrief do |actor|
|
46
46
|
actor.description_mode = "superbrief"
|
47
|
-
actor.tell "You are now in
|
47
|
+
actor.tell "You are now in SUPERBRIEF mode. Detailed room descriptions will never be displayed unless you LOOK AROUND. Other options are BRIEF and VERBOSE."
|
48
48
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
import 'basics'
|
data/lib/gamefic/meta.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
class OptionSet
|
2
|
+
attr_accessor :options
|
3
|
+
attr_reader :default
|
4
|
+
def initialize *args
|
5
|
+
@options = args
|
6
|
+
if @options.length == 0
|
7
|
+
raise "No options defined"
|
8
|
+
end
|
9
|
+
if @options.length == 1
|
10
|
+
raise "Option sets require at least 2 options"
|
11
|
+
end
|
12
|
+
@default = @options[0]
|
13
|
+
end
|
14
|
+
def default=(val)
|
15
|
+
if @options.include?(val) == false
|
16
|
+
raise "Option #{val} not available"
|
17
|
+
end
|
18
|
+
@default = val
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module OptionMap
|
23
|
+
def option_map
|
24
|
+
@option_map ||= Hash.new
|
25
|
+
end
|
26
|
+
def options cls, *args
|
27
|
+
os = OptionSet.new *args
|
28
|
+
option_map[cls] ||= {}
|
29
|
+
os.options.each { |o|
|
30
|
+
if option_map[cls][o] != nil
|
31
|
+
raise "Option #{o} already exists"
|
32
|
+
end
|
33
|
+
option_map[cls][o] = os
|
34
|
+
}
|
35
|
+
os
|
36
|
+
end
|
37
|
+
def get_default_for(cls, opt)
|
38
|
+
os = get_option_set_for(cls, opt)
|
39
|
+
if os == nil
|
40
|
+
raise "Option does not exist"
|
41
|
+
end
|
42
|
+
return os.default
|
43
|
+
end
|
44
|
+
def set_default_for(cls, opt)
|
45
|
+
os = get_option_set_for(cls, opt)
|
46
|
+
os.default = opt
|
47
|
+
end
|
48
|
+
def get_all_option_sets_for(cls)
|
49
|
+
all = []
|
50
|
+
option_map.each_value { |s|
|
51
|
+
s.each_key { |o|
|
52
|
+
set = get_option_set_for(cls, o, false)
|
53
|
+
if set != nil
|
54
|
+
all.push set
|
55
|
+
end
|
56
|
+
}
|
57
|
+
}
|
58
|
+
all.uniq
|
59
|
+
end
|
60
|
+
def get_option_set_for(cls, opt, create_if_inherited = true)
|
61
|
+
if option_map[cls] and option_map[cls][opt]
|
62
|
+
return option_map[cls][opt]
|
63
|
+
elsif cls.superclass
|
64
|
+
os = get_option_set_for(cls.superclass, opt, false)
|
65
|
+
if os != nil and create_if_inherited == true
|
66
|
+
os = options(cls, *os.options)
|
67
|
+
end
|
68
|
+
return os
|
69
|
+
end
|
70
|
+
return nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
module OptionSettings
|
75
|
+
attr_reader :option_mapper
|
76
|
+
def option_array
|
77
|
+
@option_array ||= []
|
78
|
+
end
|
79
|
+
def option_select(opt)
|
80
|
+
if option_array.include?(opt) == false
|
81
|
+
set = option_mapper.get_option_set_for(self.class, opt)
|
82
|
+
if set == nil
|
83
|
+
raise "Invalid option #{opt}"
|
84
|
+
end
|
85
|
+
(set.options - [opt]).each { |o|
|
86
|
+
option_array.delete o
|
87
|
+
}
|
88
|
+
option_array.push opt
|
89
|
+
end
|
90
|
+
end
|
91
|
+
def option_unselect(opt)
|
92
|
+
set = option_mapper.get_option_set_for(self.class, opt)
|
93
|
+
if set == nil
|
94
|
+
raise "Invalid option #{opt}"
|
95
|
+
end
|
96
|
+
option_array.delete opt
|
97
|
+
end
|
98
|
+
def option_selected?(opt)
|
99
|
+
set = option_mapper.get_option_set_for(self.class, opt)
|
100
|
+
return false if set.nil?
|
101
|
+
return true if option_array.include?(opt)
|
102
|
+
other = set.options & option_array
|
103
|
+
if other.length == 0 and set.default == opt
|
104
|
+
return true
|
105
|
+
end
|
106
|
+
return false
|
107
|
+
end
|
108
|
+
def is(opt)
|
109
|
+
option_select opt
|
110
|
+
end
|
111
|
+
def is?(opt)
|
112
|
+
option_selected?(opt)
|
113
|
+
end
|
114
|
+
end
|
data/lib/gamefic/plot.rb
CHANGED
@@ -11,6 +11,8 @@ module Gamefic
|
|
11
11
|
def self.method_missing(name, *args, &block)
|
12
12
|
if @@plot.respond_to?(name)
|
13
13
|
@@plot.send name, *args, &block
|
14
|
+
elsif Gamefic.respond_to?(name)
|
15
|
+
Gamefic.send name, *args, &block
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
@@ -18,13 +20,19 @@ module Gamefic
|
|
18
20
|
mod.get_binding
|
19
21
|
end
|
20
22
|
|
23
|
+
def self.safe_level
|
24
|
+
@@safe_level ||= (RUBY_VERSION.split('.')[0].to_i < 2 ? 2 : 3)
|
25
|
+
end
|
26
|
+
|
21
27
|
class Plot
|
22
|
-
attr_reader :scenes, :commands, :conclusions, :imported_scripts
|
28
|
+
attr_reader :scenes, :commands, :conclusions, :imported_scripts, :rules
|
23
29
|
attr_accessor :story
|
30
|
+
include OptionMap
|
24
31
|
def commandwords
|
25
32
|
words = Array.new
|
26
33
|
@syntaxes.each { |s|
|
27
|
-
|
34
|
+
word = s.template[0]
|
35
|
+
words.push(word) if !word.kind_of?(Symbol)
|
28
36
|
}
|
29
37
|
words.uniq
|
30
38
|
end
|
@@ -37,17 +45,27 @@ module Gamefic
|
|
37
45
|
@available_scripts = Hash.new
|
38
46
|
@imported_scripts = Array.new
|
39
47
|
@entities = Array.new
|
48
|
+
@rules = Hash.new
|
40
49
|
post_initialize
|
41
50
|
end
|
51
|
+
def assert name, &block
|
52
|
+
@rules[name] = Requirement.new self, name, &block
|
53
|
+
end
|
42
54
|
def post_initialize
|
43
55
|
# TODO: Should this method be required by extended classes?
|
44
56
|
end
|
57
|
+
def meta(command, *queries, &proc)
|
58
|
+
act = Meta.new(self, command, *queries, &proc)
|
59
|
+
end
|
45
60
|
def action(command, *queries, &proc)
|
46
61
|
act = Action.new(self, command, *queries, &proc)
|
47
62
|
end
|
48
63
|
def respond(command, *queries, &proc)
|
49
64
|
self.action(command, *queries, &proc)
|
50
65
|
end
|
66
|
+
def before(command, *queries, &proc)
|
67
|
+
bef = Before.new(self, command, *queries, &proc)
|
68
|
+
end
|
51
69
|
def make(cls, args = {})
|
52
70
|
ent = cls.new(self, args)
|
53
71
|
if ent.kind_of?(Entity) == false
|
@@ -56,6 +74,7 @@ module Gamefic
|
|
56
74
|
ent
|
57
75
|
end
|
58
76
|
def syntax(*args)
|
77
|
+
xlate *args
|
59
78
|
end
|
60
79
|
def xlate(*args)
|
61
80
|
syn = Syntax.new(self, *args)
|
@@ -97,6 +116,12 @@ module Gamefic
|
|
97
116
|
def passthru
|
98
117
|
Director::Delegate.passthru
|
99
118
|
end
|
119
|
+
def pass requirement
|
120
|
+
Director::Delegate.pass requirement
|
121
|
+
end
|
122
|
+
def deny requirement
|
123
|
+
Director::Delegate.deny requirement
|
124
|
+
end
|
100
125
|
def update
|
101
126
|
@update_procs.each { |p|
|
102
127
|
p.call
|
@@ -123,7 +148,7 @@ module Gamefic
|
|
123
148
|
end
|
124
149
|
get_scripts @source_directory + '/import'
|
125
150
|
proc {
|
126
|
-
$SAFE =
|
151
|
+
$SAFE = Gamefic.safe_level
|
127
152
|
eval code, ::Gamefic.bind(self), script, 1
|
128
153
|
}.call
|
129
154
|
end
|
@@ -149,7 +174,7 @@ module Gamefic
|
|
149
174
|
script_object = @available_scripts[resolved]
|
150
175
|
@available_scripts[resolved] = nil
|
151
176
|
proc {
|
152
|
-
$SAFE =
|
177
|
+
$SAFE = Gamefic.safe_level
|
153
178
|
@imported_scripts.push script_object
|
154
179
|
eval script_object.code, Gamefic.bind(self), script_object.filename, 1
|
155
180
|
}.call
|
@@ -186,8 +211,14 @@ module Gamefic
|
|
186
211
|
end
|
187
212
|
@syntaxes.unshift syntax
|
188
213
|
@syntaxes.sort! { |a, b|
|
189
|
-
al = a.template.
|
190
|
-
|
214
|
+
al = a.template.length
|
215
|
+
if (a.command.nil?)
|
216
|
+
al -= 1
|
217
|
+
end
|
218
|
+
bl = b.template.length
|
219
|
+
if (b.command.nil?)
|
220
|
+
bl -= 1
|
221
|
+
end
|
191
222
|
if al == bl
|
192
223
|
# For syntaxes of the same length, creation order takes precedence
|
193
224
|
0
|
@@ -210,21 +241,23 @@ module Gamefic
|
|
210
241
|
b.specificity <=> a.specificity
|
211
242
|
end
|
212
243
|
}
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
244
|
+
#if action.command != nil
|
245
|
+
user_friendly = action.command.to_s.sub(/_/, ' ')
|
246
|
+
args = Array.new
|
247
|
+
used_names = Array.new
|
248
|
+
action.queries.each { |c|
|
249
|
+
num = 1
|
250
|
+
new_name = "var"
|
251
|
+
while used_names.include? new_name
|
252
|
+
num = num + 1
|
253
|
+
new_name = "var#{num}"
|
254
|
+
end
|
255
|
+
used_names.push new_name
|
256
|
+
user_friendly += " :#{new_name}"
|
257
|
+
args.push new_name.to_sym
|
258
|
+
}
|
259
|
+
Syntax.new self, *[user_friendly.strip, action.command] + args
|
260
|
+
#end
|
228
261
|
end
|
229
262
|
def rem_action(action)
|
230
263
|
@commands[action.command].delete(action)
|