gamefic 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|