gamefic 1.0.0 → 1.1.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 +11 -12
- data/lib/gamefic/director/delegate.rb +61 -48
- data/lib/gamefic/director/parser.rb +1 -1
- data/lib/gamefic/engine/tty.rb +2 -5
- data/lib/gamefic/plot.rb +9 -3
- data/lib/gamefic/plot/command_mount.rb +5 -2
- data/lib/gamefic/plot/snapshot.rb +121 -55
- data/lib/gamefic/subplot.rb +81 -0
- data/lib/gamefic/syntax.rb +1 -4
- data/lib/gamefic/version.rb +1 -1
- metadata +26 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b365a88c85293650a4450cb905443a222aa1fa23
|
4
|
+
data.tar.gz: 2e299521b31b1c357651c52b7d2978c69988f306
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5839d40d6211f3327e7f0d79667e591456e44a72da1f622f87af99127dcc97a207b6cefe06f6beb5edb75e135d85b1517a8731504b032fa706062f86d4c69e0b
|
7
|
+
data.tar.gz: 6ad1537348f09477915daab0a77b1709cea1380145323ab4d803565898f9ab693bd0fd065dd33eef57d94d09d104355d64e7119978e2f57fba359c58a599fde5
|
data/lib/gamefic/action.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
module Gamefic
|
2
2
|
|
3
|
+
# Exception raised when the Action's proc arity is not compatible with the
|
4
|
+
# number of queries
|
5
|
+
class ActionArgumentError < ArgumentError
|
6
|
+
end
|
7
|
+
|
3
8
|
# Actions manage the execution of commands that Characters can perform.
|
4
9
|
#
|
5
10
|
class Action
|
@@ -7,28 +12,24 @@ module Gamefic
|
|
7
12
|
attr_writer :meta
|
8
13
|
@@order_key_seed = 0
|
9
14
|
|
10
|
-
def initialize(
|
15
|
+
def initialize(verb, *queries, &proc)
|
11
16
|
if !verb.kind_of?(Symbol)
|
12
17
|
verb = verb.to_s
|
13
18
|
verb = nil if verb == ''
|
14
19
|
end
|
15
|
-
@plot = plot
|
16
20
|
@order_key = @@order_key_seed
|
17
21
|
@@order_key_seed += 1
|
18
22
|
@proc = proc
|
19
23
|
if (verb.kind_of?(Symbol) == false and !verb.nil?)
|
20
|
-
raise "Action verbs must be symbols"
|
24
|
+
raise "Action verbs must be symbols #{verb}"
|
21
25
|
end
|
22
26
|
if !@proc.nil?
|
23
|
-
if (queries.length + 1 != @proc.arity) and (
|
24
|
-
raise "Number of queries is not compatible with proc arguments"
|
27
|
+
if (queries.length + 1 != @proc.arity) and (@proc.arity > 0)
|
28
|
+
raise ActionArgumentError.new("Number of queries is not compatible with proc arguments")
|
25
29
|
end
|
26
30
|
end
|
27
31
|
@verb = verb
|
28
32
|
@queries = queries
|
29
|
-
if !plot.nil?
|
30
|
-
plot.send :add_action, self
|
31
|
-
end
|
32
33
|
end
|
33
34
|
|
34
35
|
# Get the specificity of the Action.
|
@@ -44,14 +45,12 @@ module Gamefic
|
|
44
45
|
if verb.nil?
|
45
46
|
spec = -100
|
46
47
|
end
|
47
|
-
magnitude = 1
|
48
48
|
@queries.each { |q|
|
49
49
|
if q.kind_of?(Query::Base)
|
50
|
-
spec +=
|
50
|
+
spec += q.specificity
|
51
51
|
else
|
52
|
-
spec +=
|
52
|
+
spec += 1
|
53
53
|
end
|
54
|
-
#magnitude = magnitude * 10
|
55
54
|
}
|
56
55
|
return spec
|
57
56
|
end
|
@@ -4,7 +4,7 @@ module Gamefic
|
|
4
4
|
# If we use Query::Base.new in the @disambiguator declaration, Opal
|
5
5
|
# passes the block to the query instead of the action.
|
6
6
|
base = Query::Base.new
|
7
|
-
@@disambiguator = Action.new nil,
|
7
|
+
@@disambiguator = Action.new nil, base do |actor, entities|
|
8
8
|
definites = []
|
9
9
|
entities.each { |entity|
|
10
10
|
definites.push entity.definitely
|
@@ -23,53 +23,7 @@ module Gamefic
|
|
23
23
|
while !executed
|
24
24
|
order = @orders.shift
|
25
25
|
break if order.nil?
|
26
|
-
|
27
|
-
final_arguments = []
|
28
|
-
order.arguments.each { |argument|
|
29
|
-
if argument.length > 1 and !order.action.queries[arg_i].allow_many?
|
30
|
-
if argument[0].kind_of?(Array)
|
31
|
-
# This thing refers to multiple items. Just keep going.
|
32
|
-
final_arguments = nil
|
33
|
-
break
|
34
|
-
else
|
35
|
-
ambiguous = argument
|
36
|
-
end
|
37
|
-
order = Order.new(@actor, @@disambiguator, [])
|
38
|
-
final_arguments = [ambiguous]
|
39
|
-
break
|
40
|
-
end
|
41
|
-
valid = []
|
42
|
-
if order.action.queries[arg_i].allow_ambiguous?
|
43
|
-
valid = argument.flatten
|
44
|
-
else
|
45
|
-
argument.each { |m|
|
46
|
-
if order.action.queries[arg_i].validate(@actor, m)
|
47
|
-
valid.push m
|
48
|
-
else
|
49
|
-
final_arguments = nil
|
50
|
-
break
|
51
|
-
end
|
52
|
-
}
|
53
|
-
end
|
54
|
-
if order.action == @@disambiguator or final_arguments.nil?
|
55
|
-
break
|
56
|
-
end
|
57
|
-
if order.action.queries[arg_i].allow_many?
|
58
|
-
final_arguments.push valid.flatten
|
59
|
-
elsif valid.length == 1
|
60
|
-
final_arguments.push valid[0]
|
61
|
-
else
|
62
|
-
final_arguments = nil
|
63
|
-
break
|
64
|
-
end
|
65
|
-
arg_i += 1
|
66
|
-
}
|
67
|
-
if !final_arguments.nil?
|
68
|
-
# The actor is always the first argument to an Action proc
|
69
|
-
final_arguments.unshift @actor
|
70
|
-
order.action.execute(*final_arguments)
|
71
|
-
executed = true
|
72
|
-
end
|
26
|
+
executed = try(order)
|
73
27
|
end
|
74
28
|
@actor.send(:delegate_stack).pop
|
75
29
|
end
|
@@ -86,6 +40,65 @@ module Gamefic
|
|
86
40
|
proceed
|
87
41
|
end
|
88
42
|
private
|
43
|
+
def try order
|
44
|
+
executed = false
|
45
|
+
arg_i = 0
|
46
|
+
final_arguments = []
|
47
|
+
order.arguments.each { |argument|
|
48
|
+
if argument.length > 1 and !order.action.queries[arg_i].allow_many?
|
49
|
+
if argument[0].kind_of?(Array)
|
50
|
+
# This thing refers to multiple items. Just keep going.
|
51
|
+
final_arguments = nil
|
52
|
+
break
|
53
|
+
else
|
54
|
+
ambiguous = argument
|
55
|
+
end
|
56
|
+
order = Order.new(@actor, @@disambiguator, [])
|
57
|
+
final_arguments = [ambiguous]
|
58
|
+
break
|
59
|
+
end
|
60
|
+
if order.action.queries[arg_i].allow_ambiguous?
|
61
|
+
valid = argument.flatten
|
62
|
+
else
|
63
|
+
valid = validate(argument, arg_i, order)
|
64
|
+
if valid.nil?
|
65
|
+
final_arguments = nil
|
66
|
+
break
|
67
|
+
end
|
68
|
+
end
|
69
|
+
if order.action == @@disambiguator or final_arguments.nil?
|
70
|
+
break
|
71
|
+
end
|
72
|
+
if order.action.queries[arg_i].allow_many?
|
73
|
+
final_arguments.push valid.flatten
|
74
|
+
elsif valid.length == 1
|
75
|
+
final_arguments.push valid[0]
|
76
|
+
else
|
77
|
+
final_arguments = nil
|
78
|
+
break
|
79
|
+
end
|
80
|
+
arg_i += 1
|
81
|
+
}
|
82
|
+
if !final_arguments.nil?
|
83
|
+
# The actor is always the first argument to an Action proc
|
84
|
+
final_arguments.unshift @actor
|
85
|
+
order.action.execute(*final_arguments)
|
86
|
+
executed = true
|
87
|
+
end
|
88
|
+
executed
|
89
|
+
end
|
90
|
+
def validate argument, arg_i, order
|
91
|
+
valid = []
|
92
|
+
argument.each { |m|
|
93
|
+
if order.action.queries[arg_i].validate(@actor, m)
|
94
|
+
valid.push m
|
95
|
+
else
|
96
|
+
valid = nil
|
97
|
+
break
|
98
|
+
end
|
99
|
+
}
|
100
|
+
valid
|
101
|
+
end
|
89
102
|
end
|
90
103
|
end
|
91
104
|
end
|
@@ -102,7 +102,7 @@ module Gamefic
|
|
102
102
|
objects.push Order.new(actor, action, prepared)
|
103
103
|
else
|
104
104
|
if !action.queries.last.allow_many? or action.queries.last.allow_ambiguous?
|
105
|
-
misunderstood = Action.new nil,
|
105
|
+
misunderstood = Action.new nil, Query::Text.new do |actor, text|
|
106
106
|
actor.tell "I understand the first part of your command but not \"#{text}.\""
|
107
107
|
end
|
108
108
|
misunderstood.meta = true
|
data/lib/gamefic/engine/tty.rb
CHANGED
@@ -33,10 +33,7 @@ module Gamefic
|
|
33
33
|
@stream.ansi
|
34
34
|
end
|
35
35
|
def save filename, snapshot
|
36
|
-
data =
|
37
|
-
:metadata => @character.plot.metadata,
|
38
|
-
:entities => snapshot
|
39
|
-
}
|
36
|
+
data = snapshot.merge(:metadata => @character.plot.metadata)
|
40
37
|
json = JSON.generate data
|
41
38
|
if json.nil?
|
42
39
|
@character.tell "Nothing to save."
|
@@ -63,7 +60,7 @@ module Gamefic
|
|
63
60
|
if (data[:metadata] != @character.plot.metadata)
|
64
61
|
@character.tell "The save file is not compatible with this version of the game."
|
65
62
|
else
|
66
|
-
return data
|
63
|
+
return data
|
67
64
|
end
|
68
65
|
else
|
69
66
|
@character.tell "File \"#{filename}\" not found."
|
data/lib/gamefic/plot.rb
CHANGED
@@ -5,6 +5,7 @@ require 'gamefic/tester'
|
|
5
5
|
require 'gamefic/source'
|
6
6
|
require 'gamefic/script'
|
7
7
|
require 'gamefic/query'
|
8
|
+
require 'gamefic/subplot'
|
8
9
|
|
9
10
|
module Gamefic
|
10
11
|
|
@@ -25,8 +26,11 @@ module Gamefic
|
|
25
26
|
# Gamefic Studio has a PlotStageMetaMapper that handles it, but it doesn't run if
|
26
27
|
# the plugin isn't activated.
|
27
28
|
#include Gamefic, Tester, SceneMount, CommandMount, EntityMount, QueryMount, ArticleMount, YouMount, Snapshot
|
28
|
-
mount Gamefic, Tester, SceneMount, CommandMount, EntityMount, QueryMount,
|
29
|
-
|
29
|
+
mount Gamefic, Tester, SceneMount, CommandMount, EntityMount, QueryMount,
|
30
|
+
ArticleMount, YouMount, Snapshot, Subplot::Host
|
31
|
+
expose :script, :introduction, :assert_action, :before_player_update,
|
32
|
+
:on_update, :on_player_update, :entities, :on_ready, :on_player_ready,
|
33
|
+
:players, :scenes, :metadata
|
30
34
|
|
31
35
|
# @param [Source::Base]
|
32
36
|
def initialize(source = nil)
|
@@ -44,6 +48,7 @@ module Gamefic
|
|
44
48
|
@players = []
|
45
49
|
@asserts = {}
|
46
50
|
@default_scene = :active
|
51
|
+
@subplots = []
|
47
52
|
post_initialize
|
48
53
|
end
|
49
54
|
|
@@ -165,6 +170,7 @@ module Gamefic
|
|
165
170
|
# Introduce a player to the game.
|
166
171
|
# This method is typically called by the Engine that manages game execution.
|
167
172
|
def introduce(player)
|
173
|
+
player.extend Subplot::Feature
|
168
174
|
@players.push player
|
169
175
|
if @introduction != nil
|
170
176
|
@introduction.call(player)
|
@@ -341,7 +347,7 @@ module Gamefic
|
|
341
347
|
user_friendly += " #{new_name}"
|
342
348
|
args.push new_name
|
343
349
|
}
|
344
|
-
Syntax.new
|
350
|
+
add_syntax Syntax.new(user_friendly.strip, "#{action.verb} #{args.join(' ')}")
|
345
351
|
end
|
346
352
|
def rem_action(action)
|
347
353
|
@commands[action.verb].delete(action)
|
@@ -24,7 +24,9 @@ module Gamefic
|
|
24
24
|
act
|
25
25
|
end
|
26
26
|
def action(command, *queries, &proc)
|
27
|
-
Action.new(
|
27
|
+
act = Action.new(command, *queries, &proc)
|
28
|
+
add_action act
|
29
|
+
act
|
28
30
|
end
|
29
31
|
# Create an Action that responds to a command.
|
30
32
|
# An Action uses the command argument to identify the imperative verb that
|
@@ -72,7 +74,8 @@ module Gamefic
|
|
72
74
|
xlate(*args)
|
73
75
|
end
|
74
76
|
def xlate(*args)
|
75
|
-
syn = Syntax.new(
|
77
|
+
syn = Syntax.new(*args)
|
78
|
+
add_syntax syn
|
76
79
|
syn
|
77
80
|
end
|
78
81
|
def commandwords
|
@@ -2,6 +2,10 @@ require 'json'
|
|
2
2
|
|
3
3
|
module Gamefic
|
4
4
|
module Plot::Snapshot
|
5
|
+
|
6
|
+
# Take a snapshot of the plot's current state.
|
7
|
+
#
|
8
|
+
# @return [Hash]
|
5
9
|
def save
|
6
10
|
store = []
|
7
11
|
index = 0
|
@@ -44,44 +48,59 @@ module Gamefic
|
|
44
48
|
else
|
45
49
|
store = reduce(store)
|
46
50
|
end
|
47
|
-
|
51
|
+
return {
|
52
|
+
entities: store,
|
53
|
+
subplots: save_subplots
|
54
|
+
}
|
48
55
|
end
|
56
|
+
|
57
|
+
# Restore the plot to the state of the provided snapshot.
|
58
|
+
#
|
59
|
+
# @param [Hash]
|
49
60
|
def restore snapshot
|
50
|
-
|
61
|
+
restore_initial_state
|
62
|
+
internal_restore snapshot[:entities]
|
63
|
+
restore_subplots snapshot[:subplots]
|
51
64
|
end
|
65
|
+
|
52
66
|
private
|
53
|
-
|
54
|
-
|
67
|
+
|
68
|
+
# Restore the plot to the state of its first snapshot.
|
69
|
+
#
|
70
|
+
def restore_initial_state
|
55
71
|
@entities[@initial_state.length..-1].each { |e|
|
56
72
|
e.parent = nil
|
57
73
|
}
|
58
74
|
@entities.slice! @initial_state.length..-1
|
59
|
-
internal_restore @initial_state
|
60
|
-
|
75
|
+
internal_restore @initial_state
|
76
|
+
end
|
77
|
+
|
78
|
+
def internal_restore snapshot
|
61
79
|
index = 0
|
62
80
|
snapshot.each { |hash|
|
63
81
|
if entities[index].nil?
|
64
|
-
|
65
|
-
|
66
|
-
entities[index] = make cls
|
67
|
-
else
|
68
|
-
break
|
69
|
-
end
|
82
|
+
cls = Kernel.const_get(hash[:class])
|
83
|
+
@entities[index] = make cls
|
70
84
|
end
|
71
|
-
hash
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
85
|
+
internal_restore_hash hash, index
|
86
|
+
index += 1
|
87
|
+
}
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
def internal_restore_hash hash, index
|
91
|
+
hash.each { |k, v|
|
92
|
+
if k == :scene
|
93
|
+
entities[index].cue v.to_sym
|
94
|
+
elsif (k != :session and k != :class)
|
95
|
+
entities[index].send("#{k}=", unserialize(v))
|
96
|
+
end
|
78
97
|
unless hash[:session].nil?
|
79
98
|
hash[:session].each_pair { |k, v|
|
80
99
|
entities[index].session[k.to_sym] = unserialize(v)
|
81
100
|
}
|
82
101
|
end
|
83
|
-
index += 1
|
84
102
|
}
|
103
|
+
nil
|
85
104
|
end
|
86
105
|
def reduce entities
|
87
106
|
reduced = []
|
@@ -98,7 +117,6 @@ module Gamefic
|
|
98
117
|
}
|
99
118
|
reduced
|
100
119
|
end
|
101
|
-
private
|
102
120
|
def can_serialize? obj
|
103
121
|
return true if (obj == true or obj == false or obj.nil?)
|
104
122
|
allowed = [String, Fixnum, Float, Numeric, Entity, Direction, Hash, Array, Symbol]
|
@@ -111,23 +129,9 @@ module Gamefic
|
|
111
129
|
return nil if obj.nil?
|
112
130
|
return false if obj == false
|
113
131
|
if obj.kind_of?(Hash)
|
114
|
-
|
115
|
-
obj.each_pair { |k, v|
|
116
|
-
if can_serialize?(k) and can_serialize?(v)
|
117
|
-
hash[serialize_obj(k)] = serialize_obj(v)
|
118
|
-
end
|
119
|
-
}
|
120
|
-
return hash
|
132
|
+
return serialize_hash obj
|
121
133
|
elsif obj.kind_of?(Array)
|
122
|
-
|
123
|
-
obj.each_index { |i|
|
124
|
-
if can_serialize?(obj[i])
|
125
|
-
arr[i] = serialize_obj(obj[i])
|
126
|
-
else
|
127
|
-
raise "Bad array in snapshot"
|
128
|
-
end
|
129
|
-
}
|
130
|
-
return arr
|
134
|
+
return serialize_array obj
|
131
135
|
else
|
132
136
|
if obj.kind_of?(Entity)
|
133
137
|
return "#<EIN_#{@entities.index(obj)}>"
|
@@ -137,29 +141,91 @@ module Gamefic
|
|
137
141
|
end
|
138
142
|
return obj
|
139
143
|
end
|
144
|
+
def serialize_hash obj
|
145
|
+
hash = {}
|
146
|
+
obj.each_pair { |k, v|
|
147
|
+
if can_serialize?(k) and can_serialize?(v)
|
148
|
+
hash[serialize_obj(k)] = serialize_obj(v)
|
149
|
+
end
|
150
|
+
}
|
151
|
+
return hash
|
152
|
+
end
|
153
|
+
def serialize_array obj
|
154
|
+
arr = []
|
155
|
+
obj.each_index { |i|
|
156
|
+
if can_serialize?(obj[i])
|
157
|
+
arr[i] = serialize_obj(obj[i])
|
158
|
+
else
|
159
|
+
raise "Bad array in snapshot"
|
160
|
+
end
|
161
|
+
}
|
162
|
+
return arr
|
163
|
+
end
|
140
164
|
def unserialize obj
|
141
165
|
if obj.kind_of?(Hash)
|
142
|
-
|
143
|
-
obj.each_pair { |k, v|
|
144
|
-
hash[unserialize(k)] = unserialize(v)
|
145
|
-
}
|
146
|
-
hash
|
166
|
+
unserialize_hash obj
|
147
167
|
elsif obj.kind_of?(Array)
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
168
|
+
unserialize_array obj
|
169
|
+
elsif obj.to_s.match(/^#<EIN_[0-9]+>$/)
|
170
|
+
i = obj[6..-2].to_i
|
171
|
+
@entities[i]
|
172
|
+
elsif obj.to_s.match(/^#<DIR_[a-z]+>$/)
|
173
|
+
Direction.find(obj[6..-2])
|
153
174
|
else
|
154
|
-
|
155
|
-
i = obj[6..-2].to_i
|
156
|
-
@entities[i]
|
157
|
-
elsif obj.to_s.match(/^#<DIR_[a-z]+>$/)
|
158
|
-
Direction.find(obj[6..-2])
|
159
|
-
else
|
160
|
-
obj
|
161
|
-
end
|
175
|
+
obj
|
162
176
|
end
|
163
177
|
end
|
178
|
+
def unserialize_hash obj
|
179
|
+
hash = {}
|
180
|
+
obj.each_pair { |k, v|
|
181
|
+
hash[unserialize(k)] = unserialize(v)
|
182
|
+
}
|
183
|
+
hash
|
184
|
+
end
|
185
|
+
def unserialize_array obj
|
186
|
+
arr = []
|
187
|
+
obj.each_index { |i|
|
188
|
+
arr[i] = unserialize(obj[i])
|
189
|
+
}
|
190
|
+
arr
|
191
|
+
end
|
192
|
+
def save_subplots
|
193
|
+
arr = []
|
194
|
+
subplots.each { |s|
|
195
|
+
hash = {}
|
196
|
+
hash[:class] = s.class.to_s
|
197
|
+
s.instance_variables.each { |k|
|
198
|
+
v = s.instance_variable_get(k)
|
199
|
+
if can_serialize?(v)
|
200
|
+
hash[k] = serialize_obj(v)
|
201
|
+
end
|
202
|
+
}
|
203
|
+
arr.push hash
|
204
|
+
}
|
205
|
+
arr
|
206
|
+
end
|
207
|
+
def restore_subplots arr
|
208
|
+
players.each { |p|
|
209
|
+
p.send(:p_subplots).clear
|
210
|
+
}
|
211
|
+
p_subplots.clear
|
212
|
+
arr.each { |hash|
|
213
|
+
cls = Kernel.const_get(hash[:class])
|
214
|
+
subplot = cls.new self
|
215
|
+
hash.each { |k, v|
|
216
|
+
if k != :class
|
217
|
+
subplot.instance_variable_set(k, unserialize(v))
|
218
|
+
end
|
219
|
+
}
|
220
|
+
subplot.players.each { |p|
|
221
|
+
p.send(:p_subplots).push subplot
|
222
|
+
}
|
223
|
+
subplot.entities.each { |e|
|
224
|
+
e.extend Subplot::Element
|
225
|
+
e.instance_variable_set(:@subplot, subplot)
|
226
|
+
}
|
227
|
+
p_subplots.push subplot
|
228
|
+
}
|
229
|
+
end
|
164
230
|
end
|
165
231
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Gamefic
|
2
|
+
|
3
|
+
class Subplot
|
4
|
+
module Element
|
5
|
+
attr_reader :subplot
|
6
|
+
end
|
7
|
+
module Feature
|
8
|
+
def subplots
|
9
|
+
p_subplots.clone
|
10
|
+
end
|
11
|
+
private
|
12
|
+
def p_subplots
|
13
|
+
@p_subplots ||= []
|
14
|
+
end
|
15
|
+
end
|
16
|
+
module Host
|
17
|
+
# Get an array of all the current subplots.
|
18
|
+
#
|
19
|
+
# @return [Array<Subplot>]
|
20
|
+
def subplots
|
21
|
+
p_subplots.clone
|
22
|
+
end
|
23
|
+
|
24
|
+
# Start a new subplot based on the provided class.
|
25
|
+
#
|
26
|
+
# @param [Class] The class of the subplot to be created (Subplot by default)
|
27
|
+
# @return [Subplot]
|
28
|
+
def branch subplot_class = Subplot, &block
|
29
|
+
subplot = subplot_class.new(self, &block)
|
30
|
+
p_subplots.push subplot
|
31
|
+
subplot
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def p_subplots
|
36
|
+
@p_subplots ||= []
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
attr_reader :plot, :entities, :players
|
41
|
+
|
42
|
+
def initialize plot
|
43
|
+
@plot = plot
|
44
|
+
@entities = []
|
45
|
+
@players = []
|
46
|
+
@concluded = false
|
47
|
+
post_initialize
|
48
|
+
yield(self) if block_given?
|
49
|
+
end
|
50
|
+
def post_initialize
|
51
|
+
end
|
52
|
+
def make *args
|
53
|
+
e = plot.make(*args)
|
54
|
+
e.extend Gamefic::Subplot::Element
|
55
|
+
e.instance_variable_set(:@subplot, self)
|
56
|
+
entities.push e
|
57
|
+
e
|
58
|
+
end
|
59
|
+
def introduce player
|
60
|
+
player.send(:p_subplots).push self
|
61
|
+
players.push player
|
62
|
+
end
|
63
|
+
def exeunt player
|
64
|
+
player.send(:p_subplots).delete self
|
65
|
+
players.delete player
|
66
|
+
end
|
67
|
+
def conclude
|
68
|
+
concluded = true
|
69
|
+
entities.each { |e|
|
70
|
+
e.destroy
|
71
|
+
}
|
72
|
+
players.each { |p|
|
73
|
+
exeunt p
|
74
|
+
}
|
75
|
+
end
|
76
|
+
def concluded?
|
77
|
+
@concluded
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
data/lib/gamefic/syntax.rb
CHANGED
@@ -6,7 +6,7 @@ module Gamefic
|
|
6
6
|
attr_reader :token_count, :first_word, :verb, :template, :command
|
7
7
|
@@phrase = '([\w\W\s\S]*?)'
|
8
8
|
|
9
|
-
def initialize
|
9
|
+
def initialize template, *command
|
10
10
|
command = command.join(' ')
|
11
11
|
words = template.split_words
|
12
12
|
@token_count = words.length
|
@@ -50,9 +50,6 @@ module Gamefic
|
|
50
50
|
}
|
51
51
|
@replace = subs.join(' ')
|
52
52
|
@regexp = Regexp.new("^#{tokens.join(' ')}$", Regexp::IGNORECASE)
|
53
|
-
if !plot.nil?
|
54
|
-
plot.send :add_syntax, self
|
55
|
-
end
|
56
53
|
end
|
57
54
|
|
58
55
|
# Convert a String into a Command.
|
data/lib/gamefic/version.rb
CHANGED
metadata
CHANGED
@@ -1,41 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gamefic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Snyder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: slop
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rubyzip
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
|
-
- -
|
31
|
+
- - '>='
|
18
32
|
- !ruby/object:Gem::Version
|
19
33
|
version: '0'
|
20
34
|
type: :runtime
|
21
35
|
prerelease: false
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
23
37
|
requirements:
|
24
|
-
- -
|
38
|
+
- - '>='
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rspec
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
|
-
- -
|
45
|
+
- - '>='
|
32
46
|
- !ruby/object:Gem::Version
|
33
47
|
version: '0'
|
34
48
|
type: :development
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
|
-
- -
|
52
|
+
- - '>='
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
41
55
|
description: An adventure game and interactive fiction framework
|
@@ -124,6 +138,7 @@ files:
|
|
124
138
|
- lib/gamefic/source/file.rb
|
125
139
|
- lib/gamefic/source/text.rb
|
126
140
|
- lib/gamefic/stage.rb
|
141
|
+
- lib/gamefic/subplot.rb
|
127
142
|
- lib/gamefic/syntax.rb
|
128
143
|
- lib/gamefic/tester.rb
|
129
144
|
- lib/gamefic/version.rb
|
@@ -137,18 +152,19 @@ require_paths:
|
|
137
152
|
- lib
|
138
153
|
required_ruby_version: !ruby/object:Gem::Requirement
|
139
154
|
requirements:
|
140
|
-
- -
|
155
|
+
- - '>='
|
141
156
|
- !ruby/object:Gem::Version
|
142
|
-
version:
|
157
|
+
version: 2.0.0
|
143
158
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
159
|
requirements:
|
145
|
-
- -
|
160
|
+
- - '>='
|
146
161
|
- !ruby/object:Gem::Version
|
147
162
|
version: '0'
|
148
163
|
requirements: []
|
149
164
|
rubyforge_project:
|
150
|
-
rubygems_version: 2.
|
165
|
+
rubygems_version: 2.6.8
|
151
166
|
signing_key:
|
152
167
|
specification_version: 4
|
153
168
|
summary: Gamefic
|
154
169
|
test_files: []
|
170
|
+
has_rdoc:
|