gamefic 0.1.1 → 0.2.0

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