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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/lib/gamefic/action.rb +7 -6
  3. data/lib/gamefic/before.rb +12 -0
  4. data/lib/gamefic/character.rb +1 -1
  5. data/lib/gamefic/core_ext/array.rb +4 -0
  6. data/lib/gamefic/core_ext/string.rb +0 -31
  7. data/lib/gamefic/describable.rb +68 -8
  8. data/lib/gamefic/director.rb +108 -75
  9. data/lib/gamefic/engine.rb +74 -10
  10. data/lib/gamefic/entity.rb +3 -3
  11. data/lib/gamefic/import/basics/actions/close.rb +16 -0
  12. data/lib/gamefic/import/basics/actions/commands.rb +3 -0
  13. data/lib/gamefic/import/basics/actions/drop-in.rb +17 -0
  14. data/lib/gamefic/import/basics/actions/drop-on.rb +16 -0
  15. data/lib/gamefic/import/basics/actions/drop.rb +30 -0
  16. data/lib/gamefic/import/basics/actions/enter.rb +16 -0
  17. data/lib/gamefic/import/basics/actions/{traversal.rb → go.rb} +35 -35
  18. data/lib/gamefic/import/basics/actions/inventory.rb +8 -49
  19. data/lib/gamefic/import/basics/actions/leave.rb +29 -0
  20. data/lib/gamefic/import/basics/actions/look-in-at.rb +27 -0
  21. data/lib/gamefic/import/basics/actions/look-under.rb +3 -0
  22. data/lib/gamefic/import/basics/actions/look.rb +71 -67
  23. data/lib/gamefic/import/basics/actions/nil.rb +25 -0
  24. data/lib/gamefic/import/basics/actions/open.rb +23 -0
  25. data/lib/gamefic/import/basics/actions/quit.rb +3 -0
  26. data/lib/gamefic/import/basics/actions/take.rb +107 -0
  27. data/lib/gamefic/import/basics/entities/container.rb +8 -24
  28. data/lib/gamefic/import/basics/entities/entity.rb +11 -0
  29. data/lib/gamefic/import/basics/entities/fixture.rb +5 -5
  30. data/lib/gamefic/import/basics/entities/item.rb +5 -7
  31. data/lib/gamefic/import/basics/entities/portal.rb +40 -43
  32. data/lib/gamefic/import/basics/entities/room.rb +30 -24
  33. data/lib/gamefic/import/basics/entities/scenery.rb +5 -3
  34. data/lib/gamefic/import/basics/entities/supporter.rb +6 -0
  35. data/lib/gamefic/import/basics/entities/thing.rb +16 -0
  36. data/lib/gamefic/import/basics/queries/reachable.rb +38 -0
  37. data/lib/gamefic/import/basics/queries/room.rb +8 -0
  38. data/lib/gamefic/import/basics/queries/visible.rb +32 -0
  39. data/lib/gamefic/import/basics/rules/has-enough-light.rb +14 -0
  40. data/lib/gamefic/import/{basics → basics.old}/actions/container.rb +13 -12
  41. data/lib/gamefic/import/basics.old/actions/inventory.rb +50 -0
  42. data/lib/gamefic/import/basics.old/actions/look.rb +53 -0
  43. data/lib/gamefic/import/basics.old/actions/meta.rb +6 -0
  44. data/lib/gamefic/import/basics.old/actions/traversal.rb +35 -0
  45. data/lib/gamefic/import/{basics → basics.old}/actions.rb +0 -0
  46. data/lib/gamefic/import/basics.old/entities/container.rb +3 -0
  47. data/lib/gamefic/import/basics.old/entities/fixture.rb +3 -0
  48. data/lib/gamefic/import/basics.old/entities/item.rb +3 -0
  49. data/lib/gamefic/import/basics.old/entities/portal.rb +43 -0
  50. data/lib/gamefic/import/basics.old/entities/room.rb +27 -0
  51. data/lib/gamefic/import/basics.old/entities/scenery.rb +3 -0
  52. data/lib/gamefic/import/basics.old/entities/supporter.rb +3 -0
  53. data/lib/gamefic/import/{basics → basics.old}/entities.rb +0 -0
  54. data/lib/gamefic/import/basics.old/room_modes.rb +48 -0
  55. data/lib/gamefic/import/basics.rb +6 -2
  56. data/lib/gamefic/import/{basics/room_modes.rb → room_modes.rb} +6 -6
  57. data/lib/gamefic/import/standard.rb +1 -0
  58. data/lib/gamefic/meta.rb +12 -0
  59. data/lib/gamefic/optionset.rb +114 -0
  60. data/lib/gamefic/plot.rb +54 -21
  61. data/lib/gamefic/query.rb +214 -188
  62. data/lib/gamefic/requirement.rb +14 -0
  63. data/lib/gamefic/shell.rb +7 -4
  64. data/lib/gamefic/syntax.rb +35 -18
  65. data/lib/gamefic/thing.rb +7 -0
  66. data/lib/gamefic.rb +5 -1
  67. metadata +46 -12
  68. data/lib/gamefic/import/basics/actions/meta.rb +0 -6
  69. data/lib/gamefic/import/basics/entities/itemized.rb +0 -3
  70. data/lib/gamefic/import/basics/entities/portable.rb +0 -3
  71. 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#visited must be an Array"
10
+ raise "Character#description_seen must be an Array"
11
11
  end
12
12
  end
13
13
  def description_mode
14
- @description_mode ||= "brief"
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(:siblings, Portal) do |actor, portal|
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.perform "itemize room"
26
+ actor.tell actor.parent.name.cap_first
27
27
  else
28
- actor.perform "itemize room full"
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 VERBOSE mode. Detailed room descriptions will never be displayed unless you LOOK AROUND. Other options are BRIEF and VERBOSE."
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'
@@ -0,0 +1,12 @@
1
+ module Gamefic
2
+
3
+ class Meta < Action
4
+ def initialize *args
5
+ super
6
+ @plot.before @command, *@queries do |*args|
7
+ @plot.pass :everything
8
+ end
9
+ end
10
+ end
11
+
12
+ end
@@ -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
- words.push(s.template.split_words[0])
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 = 3
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 = 3
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.split_words.length
190
- bl = b.template.split_words.length
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
- user_friendly = action.command.to_s.sub(/_/, ' ')
214
- args = Array.new
215
- used_names = Array.new
216
- action.queries.each { |c|
217
- num = 1
218
- new_name = "var"
219
- while used_names.include? new_name
220
- num = num + 1
221
- new_name = "var#{num}"
222
- end
223
- used_names.push new_name
224
- user_friendly += " :#{new_name}"
225
- args.push new_name.to_sym
226
- }
227
- Syntax.new self, *[user_friendly, action.command] + args
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)