gamefic-standard 3.3.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -0
  3. data/Rakefile +6 -3
  4. data/gamefic-standard.gemspec +4 -4
  5. data/lib/{gamefic-standard → gamefic/standard}/actions/drop.rb +2 -2
  6. data/lib/{gamefic-standard → gamefic/standard}/actions/enter.rb +0 -8
  7. data/lib/gamefic/standard/actions/give.rb +38 -0
  8. data/lib/gamefic/standard/actions/look.rb +149 -0
  9. data/lib/gamefic/standard/actions/mount.rb +29 -0
  10. data/lib/gamefic/standard/actions/nil.rb +37 -0
  11. data/lib/{gamefic-standard → gamefic/standard}/actions/place.rb +2 -2
  12. data/lib/{gamefic-standard → gamefic/standard}/actions/pronouns.rb +5 -7
  13. data/lib/gamefic/standard/actions/quit.rb +24 -0
  14. data/lib/gamefic/standard/actions/repeat.rb +28 -0
  15. data/lib/{gamefic-standard → gamefic/standard}/actions/search.rb +9 -9
  16. data/lib/{gamefic-standard → gamefic/standard}/actions/take.rb +2 -1
  17. data/lib/{gamefic-standard → gamefic/standard}/actions/talk.rb +2 -2
  18. data/lib/gamefic/standard/actions.rb +57 -0
  19. data/lib/{gamefic-standard → gamefic/standard}/articles.rb +2 -0
  20. data/lib/gamefic/standard/entities/character.rb +14 -0
  21. data/lib/gamefic/standard/entities/container.rb +16 -0
  22. data/lib/gamefic/standard/entities/door.rb +46 -0
  23. data/lib/gamefic/standard/entities/fixture.rb +8 -0
  24. data/lib/gamefic/standard/entities/item.rb +11 -0
  25. data/lib/gamefic/standard/entities/portal.rb +50 -0
  26. data/lib/gamefic/standard/entities/receptacle.rb +9 -0
  27. data/lib/gamefic/standard/entities/room.rb +55 -0
  28. data/lib/gamefic/standard/entities/rubble.rb +16 -0
  29. data/lib/gamefic/standard/entities/scenery.rb +13 -0
  30. data/lib/gamefic/standard/entities/supporter.rb +9 -0
  31. data/lib/gamefic/standard/entities/thing.rb +9 -0
  32. data/lib/gamefic/standard/entities.rb +18 -0
  33. data/lib/{gamefic-standard → gamefic/standard}/lockable.rb +8 -0
  34. data/lib/{gamefic-standard → gamefic/standard}/openable.rb +2 -2
  35. data/lib/gamefic/standard/queries.rb +24 -0
  36. data/lib/{gamefic-standard → gamefic/standard}/version.rb +1 -1
  37. data/lib/gamefic/standard.rb +32 -0
  38. data/lib/gamefic-standard.rb +1 -34
  39. metadata +58 -56
  40. data/lib/gamefic-standard/actions/give.rb +0 -41
  41. data/lib/gamefic-standard/actions/look.rb +0 -152
  42. data/lib/gamefic-standard/actions/nil.rb +0 -70
  43. data/lib/gamefic-standard/actions/quit.rb +0 -20
  44. data/lib/gamefic-standard/actions/repeat.rb +0 -22
  45. data/lib/gamefic-standard/actions.rb +0 -56
  46. data/lib/gamefic-standard/entities/character.rb +0 -5
  47. data/lib/gamefic-standard/entities/container.rb +0 -8
  48. data/lib/gamefic-standard/entities/door.rb +0 -42
  49. data/lib/gamefic-standard/entities/fixture.rb +0 -4
  50. data/lib/gamefic-standard/entities/item.rb +0 -7
  51. data/lib/gamefic-standard/entities/portal.rb +0 -46
  52. data/lib/gamefic-standard/entities/receptacle.rb +0 -5
  53. data/lib/gamefic-standard/entities/room.rb +0 -61
  54. data/lib/gamefic-standard/entities/rubble.rb +0 -12
  55. data/lib/gamefic-standard/entities/scenery.rb +0 -9
  56. data/lib/gamefic-standard/entities/supporter.rb +0 -5
  57. data/lib/gamefic-standard/entities/thing.rb +0 -5
  58. data/lib/gamefic-standard/entities.rb +0 -12
  59. data/lib/gamefic-standard/queries.rb +0 -12
  60. /data/lib/{gamefic-standard → gamefic/standard}/actions/attack.rb +0 -0
  61. /data/lib/{gamefic-standard → gamefic/standard}/actions/close.rb +0 -0
  62. /data/lib/{gamefic-standard → gamefic/standard}/actions/go.rb +0 -0
  63. /data/lib/{gamefic-standard → gamefic/standard}/actions/insert.rb +0 -0
  64. /data/lib/{gamefic-standard → gamefic/standard}/actions/inventory.rb +0 -0
  65. /data/lib/{gamefic-standard → gamefic/standard}/actions/leave.rb +0 -0
  66. /data/lib/{gamefic-standard → gamefic/standard}/actions/lock.rb +0 -0
  67. /data/lib/{gamefic-standard → gamefic/standard}/actions/move.rb +0 -0
  68. /data/lib/{gamefic-standard → gamefic/standard}/actions/open.rb +0 -0
  69. /data/lib/{gamefic-standard → gamefic/standard}/actions/save-restore-undo.rb +0 -0
  70. /data/lib/{gamefic-standard → gamefic/standard}/actions/unlock.rb +0 -0
  71. /data/lib/{gamefic-standard → gamefic/standard}/actions/wait.rb +0 -0
  72. /data/lib/{gamefic-standard → gamefic/standard}/direction.rb +0 -0
  73. /data/lib/{gamefic-standard → gamefic/standard}/enterable.rb +0 -0
  74. /data/lib/{gamefic-standard → gamefic/standard}/introduction.rb +0 -0
  75. /data/lib/{gamefic-standard → gamefic/standard}/pathfinder.rb +0 -0
  76. /data/lib/{gamefic-standard → gamefic/standard}/standardized.rb +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83db9094673ea86b25db1d51bf9c06c62be6fadc7ed938f39c71b9c16cba9566
4
- data.tar.gz: 579a371ef1c031b2b7bb2bf9d66831e7ce92ad04d3f7ec450dd183b1265e4f80
3
+ metadata.gz: 5ad2cabfd4a0d81673d3ec48454ea842e5d5f68b5bb621b7b685b9d01d20ad16
4
+ data.tar.gz: 32e4c483f7a04eebe5bdec3e85f37a90341f2a3afe8f2e879bcda9808956ee31
5
5
  SHA512:
6
- metadata.gz: beffd2638efbb5a61fe6f0605a59e7807045aa67705c1cf5a042c28cd279e8efe8b9146690a9e742a9ebc369db035b4ecefcf0b2ea2cdca288b9a68426f253d9
7
- data.tar.gz: 324c51c2f6eeec341ee26d81449949521f0cb51063f739fa319faf072abd090b18b31c92ed16e2855934cffadb088f98e6ba3a8a4f05b13e66fbc90b43601b15
6
+ metadata.gz: 7c7cb2add780225ba638fba5d266abf2abdeabc4c01a5c0a55e6fdbd4c42a76d43c84f0ce20c8fc3807bb180553aa3570c448c1544b744e39ca06fbf392e8225
7
+ data.tar.gz: fe1479675ff888e72be337f5eb6f206b677a7fe5442cd343ed1442a48ef6079dcff3ddafce156e6e69c595282241133ccb7d6de3c99d1c2aed375144ebc177cf
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 4.0.0 - January 25, 2025
2
+ - Updates for Gamefic 4.0
3
+
1
4
  ## 3.3.0 - October 5, 2024
2
5
  - Include Pronoun and Give in Standard
3
6
  - Add gamefic-what
data/Rakefile CHANGED
@@ -1,10 +1,13 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'bundler/gem_tasks'
5
+ require 'rspec/core/rake_task'
3
6
  require 'opal/rspec/rake_task'
4
7
 
5
8
  RSpec::Core::RakeTask.new(:spec)
6
9
 
7
- task :default => :spec
10
+ task default: :spec
8
11
 
9
12
  Opal::RSpec::RakeTask.new(:opal) do |_, config|
10
13
  Opal.append_path File.join(__dir__, 'lib')
@@ -1,6 +1,6 @@
1
1
  lib = File.expand_path('lib', __dir__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'gamefic-standard/version'
3
+ require 'gamefic/standard/version'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'gamefic-standard'
@@ -37,9 +37,9 @@ Gem::Specification.new do |spec|
37
37
 
38
38
  spec.required_ruby_version = '>= 2.7.0'
39
39
 
40
- spec.add_dependency 'gamefic', '~> 3.3'
41
- spec.add_dependency 'gamefic-grammar', '~> 1.0'
42
- spec.add_dependency 'gamefic-what', '~> 1.0'
40
+ spec.add_dependency 'gamefic', '~> 4.0'
41
+ spec.add_dependency 'gamefic-grammar', '~> 1.1'
42
+ spec.add_dependency 'gamefic-what', '~> 2.0'
43
43
 
44
44
  spec.add_development_dependency 'opal', '~> 1.7'
45
45
  spec.add_development_dependency 'opal-rspec', '~> 1.0'
@@ -10,7 +10,7 @@ module Gamefic
10
10
  actor.tell "You're not carrying #{the thing}."
11
11
  end
12
12
 
13
- respond :drop, children do |actor, thing|
13
+ respond :drop, descendants do |actor, thing|
14
14
  actor.execute :take, thing
15
15
  next unless thing.parent == actor
16
16
 
@@ -18,7 +18,7 @@ module Gamefic
18
18
  actor.tell "You drop #{the thing}."
19
19
  end
20
20
 
21
- respond :drop, children do |actor, thing|
21
+ respond :drop, descendants do |actor, thing|
22
22
  thing.parent = actor.parent
23
23
  actor.tell "You drop #{the thing}."
24
24
  end
@@ -19,22 +19,14 @@ module Gamefic
19
19
  actor.tell "You're already in #{the container}."
20
20
  end
21
21
 
22
- respond :enter, parent(Supporter) do |actor, supporter|
23
- actor.tell "You're inside #{the supporter} already."
24
- end
25
-
26
22
  respond :enter, siblings(Container, proc(&:enterable?), proc(&:closed?)) do |actor, container|
27
23
  actor.tell "#{The container} is closed."
28
24
  end
29
25
 
30
- interpret 'get on :thing', 'enter :thing'
31
26
  interpret 'get in :thing', 'enter :thing'
32
27
  interpret 'get inside :thing', 'enter :thing'
33
- interpret 'sit on :thing', 'enter :thing'
34
28
  interpret 'sit in :thing', 'enter :thing'
35
- interpret 'lie on :thing', 'enter :thing'
36
29
  interpret 'lie in :thing', 'enter :thing'
37
- interpret 'stand on :thing', 'enter :thing'
38
30
  interpret 'stand in :thing', 'enter :thing'
39
31
  end
40
32
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Give
7
+ extend Gamefic::Scriptable
8
+ include Gamefic::What
9
+
10
+ respond :give, available, children do |actor, _character, _gift|
11
+ actor.tell 'Nothing happens.'
12
+ end
13
+
14
+ respond :give, available(Character), available do |actor, character, gift|
15
+ actor.tell "#{The character} has no use for #{the gift}."
16
+ end
17
+
18
+ respond :give, available(Character), available do |actor, _character, gift|
19
+ actor.execute :take, gift if gift.parent != actor
20
+
21
+ actor.proceed if gift.parent == actor
22
+ end
23
+
24
+ respond :give, Thing do |actor, thing|
25
+ actor.tell "Who do you want to give #{the thing} to?"
26
+ actor.cue AskForWhat, template: "give #{the thing} to __what__"
27
+ end
28
+
29
+ respond :give, Character do |actor, character|
30
+ actor.tell "What do you want to give to #{the character}?"
31
+ actor.cue AskForWhat, template: "give __what__ to #{the character}"
32
+ end
33
+
34
+ interpret 'give :gift to :character', 'give :character :gift'
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Look
7
+ RELATION_PHRASES = {
8
+ in: 'inside',
9
+ on: 'on top of'
10
+ }.freeze
11
+
12
+ extend Gamefic::Scriptable
13
+
14
+ def itemize_room(actor)
15
+ return unless (room = actor.room)
16
+
17
+ siblings = room.children.select(&:itemized?).that_are_not(actor)
18
+
19
+ siblings.that_are(Character)
20
+ .reject(&:locale_description)
21
+ .tap do |list|
22
+ list.empty? or actor.tell "#{list.join_and.cap_first} #{list.one? ? 'is' : 'are'} here."
23
+ end
24
+
25
+ siblings.that_are_not(Character, Portal)
26
+ .reject(&:locale_description)
27
+ .tap do |list|
28
+ list.empty? or actor.tell "You see #{list.join_and}."
29
+ end
30
+
31
+ siblings.select(&:locale_description)
32
+ .each { |thing| actor.tell thing.locale_description }
33
+
34
+ itemize_explicit_portals(actor)
35
+ itemize_parent(actor) unless actor.parent == actor.room
36
+ end
37
+
38
+ def itemize_explicit_portals(actor)
39
+ return unless actor.room&.explicit_exits?
40
+
41
+ siblings = actor.room.children.select(&:itemized?).that_are_not(actor)
42
+ earlier = siblings.select(&:locale_description).that_are(Portal).any?
43
+ siblings.that_are(Portal)
44
+ .reject(&:locale_description)
45
+ .tap do |portals|
46
+ next if portals.empty?
47
+
48
+ if portals.one?
49
+ actor.tell "There is#{earlier ? ' also ' : ' '}an exit #{portals.first.instruction}."
50
+ else
51
+ order = %w[north northeast east southeast south southwest west northwest up down]
52
+ dirs = portals.map(&:instruction)
53
+ .map(&:to_s)
54
+ .sort { |a, b| order.index(a) || 0 <=> order.index(b) || 1 }
55
+ actor.tell "There are#{earlier ? ' also ' : ' '}exits #{dirs.join_and}."
56
+ end
57
+ end
58
+ end
59
+
60
+ def itemize_parent(actor)
61
+ return unless (parent = actor.parent)
62
+
63
+ siblings = parent.children.that_are_not(actor)
64
+ if siblings.empty?
65
+ actor.tell "You're #{RELATION_PHRASES[actor.relation]} #{the parent}."
66
+ else
67
+ actor.tell "You're #{RELATION_PHRASES[actor.relation]} #{the parent}, along with #{siblings.join_and}."
68
+ end
69
+ end
70
+
71
+ respond :look do |actor|
72
+ if actor.room
73
+ actor.execute :look, actor.room
74
+ else
75
+ actor.tell "You're in a featureless void."
76
+ end
77
+ end
78
+
79
+ respond :look, myself do |actor, _|
80
+ actor.tell actor.description
81
+ actor.execute :inventory
82
+ end
83
+
84
+ respond :look, available(Thing) do |actor, thing|
85
+ actor.tell thing.description
86
+ thing.children.that_are(proc(&:attached?)).that_are(proc(&:itemized?)).each do |item|
87
+ actor.tell "#{An item} is attached to #{the thing}."
88
+ end
89
+ end
90
+
91
+ respond :look, available(Supporter) do |actor, thing|
92
+ itemized = thing.children.that_are_not(proc(&:attached?)).that_are(proc(&:itemized?))
93
+ # If the supporter does not have a description but it does contain
94
+ # itemized things, avoid saying there's nothing special about it.
95
+ actor.proceed if thing.has_description? || itemized.empty?
96
+ actor.tell "You see #{itemized.join_and} on #{the thing}." unless itemized.empty?
97
+ end
98
+
99
+ respond :look, available(Receptacle) do |actor, thing|
100
+ actor.proceed
101
+ actor.tell "You're currently in #{the thing}." if actor.parent == thing
102
+ next unless actor.parent == thing
103
+
104
+ itemized = thing.accessible.that_are_not(actor, proc(&:attached?)).that_are(proc(&:itemized?))
105
+ next if itemized.empty?
106
+
107
+ if actor.parent == thing
108
+ actor.tell "You see #{itemized.join_and} here." unless itemized.empty?
109
+ else
110
+ actor.tell "You see #{itemized.join_and} in #{the thing}." unless itemized.empty?
111
+ end
112
+ end
113
+
114
+ respond :look, parent(Supporter, proc(&:enterable?)) do |actor, supporter|
115
+ actor.proceed
116
+ actor.tell "You are currently on #{the supporter}."
117
+ end
118
+
119
+ respond :look, available(Thing, Openable) do |actor, thing|
120
+ actor.tell thing.description if thing.has_description?
121
+ actor.tell "#{The thing} is #{thing.open? ? 'open' : 'closed'}."
122
+ next if thing.closed? || thing.children.empty?
123
+
124
+ actor.tell "You see #{thing.children.join_and}."
125
+ end
126
+
127
+ respond :look, room do |actor, room|
128
+ actor.tell "<strong>#{room.name.cap_first}</strong>"
129
+ actor.tell room.description if room.described?
130
+ itemize_room(actor)
131
+ end
132
+
133
+ interpret 'look around', 'look'
134
+ interpret 'look here', 'look'
135
+ interpret 'l', 'look'
136
+
137
+ interpret 'look at :thing', 'look :thing'
138
+ interpret 'look on :thing', 'look :thing'
139
+ interpret 'look under :thing', 'look :thing'
140
+ interpret 'look beneath :thing', 'look :thing'
141
+ interpret 'look around :thing', 'look :thing'
142
+ interpret 'l :thing', 'look :thing'
143
+ interpret 'examine :thing', 'look :thing'
144
+ interpret 'x :thing', 'look :thing'
145
+ interpret 'inspect :thing', 'look :thing'
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Mount
7
+ extend Gamefic::Scriptable
8
+
9
+ respond :mount, siblings do |actor, thing|
10
+ actor.tell "#{The thing} can't accommodate you."
11
+ end
12
+
13
+ respond :mount, siblings(Supporter, proc(&:enterable?)) do |actor, supporter|
14
+ actor.put supporter, :on
15
+ actor.tell "You get on #{the supporter}."
16
+ end
17
+
18
+ respond :mount, parent(Supporter) do |actor, supporter|
19
+ actor.tell "You're already on #{the supporter}."
20
+ end
21
+
22
+ interpret 'get on :thing', 'mount :thing'
23
+ interpret 'sit on :thing', 'mount :thing'
24
+ interpret 'lie on :thing', 'mount :thing'
25
+ interpret 'stand on :thing', 'mount :thing'
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Nil
7
+ extend Gamefic::Scriptable
8
+
9
+ meta nil, plaintext do |actor, string|
10
+ next if string.strip.empty?
11
+
12
+ words = string.keywords
13
+ if actor.can?(words[0])
14
+ if words.length > 1
15
+ possible = [actor] + available.span(actor)
16
+ result = Scanner.scan(possible, words[1..-1].join(' '))
17
+ if result.matched.empty?
18
+ actor.tell %(I recognize "#{words[0]}" as a verb but don't know what you mean by "#{words[1..-1].join(' ')}.")
19
+ elsif result.remainder != ''
20
+ actor.tell %(I recognize "#{string.sub(/#{result.remainder}$/,
21
+ '').strip}" as a command but was confused by "#{result.remainder}.")
22
+ elsif result.matched.one?
23
+ actor.tell %(I recognize "#{words[0]}" and "#{result.matched.first.name}" but could not understand them together.)
24
+ else
25
+ actor.tell %(I recognize "#{words[0]}" but I'm not sure if "#{words[1..-1].join(' ')}" means #{result.matched.map(&:definitely).join_or}.)
26
+ end
27
+ else
28
+ actor.tell %(I recognize "#{words[0]}" as a verb but could not understand it in this context.)
29
+ end
30
+ else
31
+ actor.tell %(I don't recognize "#{words[0]}" as a verb.)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -14,12 +14,12 @@ module Gamefic
14
14
  actor.execute :take, thing unless thing.parent == actor
15
15
  next unless thing.parent == actor
16
16
 
17
- thing.parent = supporter
17
+ thing.put supporter, :on
18
18
  actor.tell "You put #{the thing} on #{the supporter}."
19
19
  end
20
20
 
21
21
  respond :place, children, available(Supporter) do |actor, thing, supporter|
22
- thing.parent = supporter
22
+ thing.put supporter, :on
23
23
  actor.tell "You put #{the thing} on #{the supporter}."
24
24
  end
25
25
 
@@ -10,16 +10,15 @@ module Gamefic
10
10
  actor[:standard_pronoun_targets] = []
11
11
  end
12
12
 
13
- after_action do |action|
14
- next unless action.verb
13
+ after_command do |actor, command|
14
+ next unless command.verb
15
15
 
16
- action.actor[:standard_pronoun_targets].replace action.arguments.that_are(Thing)
16
+ actor[:standard_pronoun_targets].replace command.arguments.that_are(Thing)
17
17
  end
18
18
 
19
19
  meta nil, plaintext do |actor, string|
20
20
  keywords = string.keywords
21
- list = actor.epic.synonyms
22
- next actor.proceed unless list.include?(keywords.first&.to_sym)
21
+ next actor.proceed unless actor.can?(keywords.first)
23
22
 
24
23
  xlation = keywords[1..].map do |word|
25
24
  next word unless %w[him her it them].include?(word)
@@ -27,8 +26,7 @@ module Gamefic
27
26
  actor[:standard_pronoun_targets].find { |obj| obj.objective == word }
28
27
  end
29
28
  next actor.proceed if xlation.any?(&:nil?) || xlation.that_are(Thing).empty?
30
-
31
- actor.perform "#{keywords[0].to_sym} #{xlation.join(' ')}"
29
+ actor.perform "#{keywords[0]} #{xlation.join(' ')}"
32
30
  end
33
31
  end
34
32
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Quit
7
+ extend Gamefic::Scriptable
8
+
9
+ ConfirmQuit = yes_or_no do
10
+ on_start do |actor|
11
+ actor.tell 'Are you sure you want to quit?'
12
+ end
13
+ on_finish do |actor, props|
14
+ actor.cue default_conclusion if props.yes?
15
+ end
16
+ end
17
+
18
+ meta :quit do |actor|
19
+ actor.cue ConfirmQuit
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Repeat
7
+ extend Gamefic::Scriptable
8
+
9
+ after_command do |actor, command|
10
+ next if command.verb == :repeat || command.input.nil?
11
+
12
+ actor[:standard_repeatable_command] = command.input
13
+ end
14
+
15
+ meta :repeat do |actor|
16
+ if actor[:standard_repeatable_command]
17
+ actor.tell "Repeating <kbd>\"#{actor[:standard_repeatable_command]}\"</kbd>..."
18
+ actor.perform actor[:standard_repeatable_command]
19
+ else
20
+ actor.tell "You don't have a previous command to repeat right now."
21
+ end
22
+ end
23
+
24
+ interpret 'again', 'repeat'
25
+ end
26
+ end
27
+ end
28
+ end
@@ -11,21 +11,21 @@ module Gamefic
11
11
  end
12
12
 
13
13
  respond :search, available(Receptacle) do |actor, thing|
14
- if thing.accessible?
15
- itemized = thing.children.that_are_not(proc(&:attached?)).that_are(proc(&:itemized?))
16
- if itemized.empty?
17
- actor.tell "There's nothing inside #{the thing}."
18
- else
19
- actor.tell "You see #{itemized.join_and} in #{the thing}." unless itemized.empty?
20
- end
14
+ itemized = thing.accessible.that_are_not(proc(&:attached?)).that_are(proc(&:itemized?))
15
+ if itemized.empty?
16
+ actor.tell "There's nothing inside #{the thing}."
21
17
  else
22
- actor.tell "You can't see inside #{the thing}."
18
+ actor.tell "You see #{itemized.join_and} in #{the thing}." unless itemized.empty?
23
19
  end
24
20
  end
25
21
 
26
22
  respond :search, available(Container, proc(&:closed?)) do |actor, container|
27
23
  actor.execute :open, container
28
- actor.proceed if container.open?
24
+ if container.open?
25
+ actor.proceed
26
+ else
27
+ actor.tell "You can't see inside #{the container}."
28
+ end
29
29
  end
30
30
 
31
31
  interpret 'look inside :thing', 'search :thing'
@@ -30,7 +30,8 @@ module Gamefic
30
30
  end
31
31
 
32
32
  respond :take, plaintext(/^(all|everything)$/) do |actor, _all|
33
- items = Gamefic::Scope::Family.matches(actor)
33
+ items = Gamefic::Query::Family.new
34
+ .span(actor)
34
35
  .select(&:portable?)
35
36
  .reject { |item| actor.flatten.include?(item) }
36
37
  if items.empty?
@@ -7,11 +7,11 @@ module Gamefic
7
7
  extend Gamefic::Scriptable
8
8
 
9
9
  respond :talk do |actor|
10
- actor.tell 'You talk to yourself.'
10
+ actor.execute :talk, actor
11
11
  end
12
12
 
13
13
  respond :talk, myself do |actor, _yourself|
14
- actor.execute :talk
14
+ actor.tell 'You talk to yourself.'
15
15
  end
16
16
 
17
17
  respond :talk, available do |actor, _thing|
@@ -0,0 +1,57 @@
1
+ require 'gamefic/standard/actions/nil'
2
+ require 'gamefic/standard/actions/attack'
3
+ require 'gamefic/standard/actions/drop'
4
+ require 'gamefic/standard/actions/enter'
5
+ require 'gamefic/standard/actions/mount'
6
+ require 'gamefic/standard/actions/open'
7
+ require 'gamefic/standard/actions/close'
8
+ require 'gamefic/standard/actions/lock'
9
+ require 'gamefic/standard/actions/unlock'
10
+ require 'gamefic/standard/actions/go'
11
+ require 'gamefic/standard/actions/insert'
12
+ require 'gamefic/standard/actions/inventory'
13
+ require 'gamefic/standard/actions/leave'
14
+ require 'gamefic/standard/actions/look'
15
+ require 'gamefic/standard/actions/search'
16
+ require 'gamefic/standard/actions/place'
17
+ require 'gamefic/standard/actions/quit'
18
+ require 'gamefic/standard/actions/take'
19
+ require 'gamefic/standard/actions/move'
20
+ require 'gamefic/standard/actions/talk'
21
+ require 'gamefic/standard/actions/wait'
22
+ require 'gamefic/standard/actions/give'
23
+ require 'gamefic/standard/actions/repeat'
24
+ require 'gamefic/standard/actions/save-restore-undo'
25
+ require 'gamefic/standard/actions/pronouns'
26
+
27
+ module Gamefic
28
+ module Standard
29
+ module Actions
30
+ include Nil
31
+ include Attack
32
+ include Drop
33
+ include Enter
34
+ include Open
35
+ include Close
36
+ include Lock
37
+ include Unlock
38
+ include Go
39
+ include Insert
40
+ include Inventory
41
+ include Leave
42
+ include Look
43
+ include Search
44
+ include Place
45
+ include Quit
46
+ include Take
47
+ include Move
48
+ include Talk
49
+ include Wait
50
+ include Give
51
+ include Repeat
52
+ include SaveRestoreUndo
53
+ include Pronouns
54
+ include Gamefic::What
55
+ end
56
+ end
57
+ end
@@ -5,6 +5,8 @@ module Gamefic
5
5
  # Methods for adding definite and indefinite articles to entity names.
6
6
  #
7
7
  module Articles
8
+ extend Gamefic::Scriptable
9
+
8
10
  # Get a name for the entity with an indefinite article (unless the entity
9
11
  # has a proper name).
10
12
  #
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ Character = Gamefic::Actor
6
+ Character.set_default gender: :other
7
+
8
+ class Character
9
+ def accessible
10
+ children.select { |child| child.is_a?(Scenery) }
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ # An openable and lockable receptacle.
6
+ #
7
+ class Container < Receptacle
8
+ include Gamefic::Standard::Openable
9
+ include Gamefic::Standard::Lockable
10
+
11
+ def accessible
12
+ open? ? super : []
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ # An openable and lockable portal.
6
+ #
7
+ class Door < Portal
8
+ include Gamefic::Standard::Openable
9
+ include Gamefic::Standard::Lockable
10
+
11
+ def post_initialize
12
+ update_reverse_open
13
+ update_reverse_lock
14
+ end
15
+
16
+ def open=(bool)
17
+ super
18
+ reverse&.lock_key = lock_key
19
+ update_reverse_open
20
+ update_reverse_lock
21
+ end
22
+
23
+ def locked=(bool)
24
+ super
25
+ update_reverse_lock
26
+ end
27
+
28
+ def two_way_lock_key=(key)
29
+ self.lock_key = key
30
+ reverse&.lock_key = key
31
+ end
32
+
33
+ private
34
+
35
+ def update_reverse_open
36
+ rev = find_reverse
37
+ rev&.open = open? unless rev&.open? == open?
38
+ end
39
+
40
+ def update_reverse_lock
41
+ rev = find_reverse
42
+ rev&.locked = locked? unless rev&.locked? == locked?
43
+ end
44
+ end
45
+ end
46
+ end