gamefic-standard 3.2.4 → 4.0.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 (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/Rakefile +11 -5
  4. data/gamefic-standard.gemspec +15 -13
  5. data/lib/gamefic/standard/actions/attack.rb +32 -0
  6. data/lib/gamefic/standard/actions/close.rb +24 -0
  7. data/lib/gamefic/standard/actions/drop.rb +39 -0
  8. data/lib/gamefic/standard/actions/enter.rb +34 -0
  9. data/lib/gamefic/standard/actions/give.rb +38 -0
  10. data/lib/gamefic/standard/actions/go.rb +63 -0
  11. data/lib/gamefic/standard/actions/insert.rb +53 -0
  12. data/lib/gamefic/standard/actions/inventory.rb +20 -0
  13. data/lib/gamefic/standard/actions/leave.rb +57 -0
  14. data/lib/gamefic/standard/actions/lock.rb +31 -0
  15. data/lib/gamefic/standard/actions/look.rb +149 -0
  16. data/lib/gamefic/standard/actions/mount.rb +29 -0
  17. data/lib/gamefic/standard/actions/move.rb +28 -0
  18. data/lib/gamefic/standard/actions/nil.rb +37 -0
  19. data/lib/gamefic/standard/actions/open.rb +39 -0
  20. data/lib/gamefic/standard/actions/place.rb +39 -0
  21. data/lib/gamefic/standard/actions/pronouns.rb +34 -0
  22. data/lib/gamefic/standard/actions/quit.rb +24 -0
  23. data/lib/gamefic/standard/actions/repeat.rb +28 -0
  24. data/lib/gamefic/standard/actions/save-restore-undo.rb +26 -0
  25. data/lib/gamefic/standard/actions/search.rb +36 -0
  26. data/lib/gamefic/standard/actions/take.rb +54 -0
  27. data/lib/gamefic/standard/actions/talk.rb +51 -0
  28. data/lib/gamefic/standard/actions/unlock.rb +35 -0
  29. data/lib/gamefic/standard/actions/wait.rb +17 -0
  30. data/lib/gamefic/standard/actions.rb +57 -0
  31. data/lib/gamefic/standard/articles.rb +52 -0
  32. data/lib/gamefic/standard/enterable.rb +13 -0
  33. data/lib/gamefic/standard/entities/character.rb +14 -0
  34. data/lib/gamefic/standard/entities/container.rb +16 -0
  35. data/lib/gamefic/standard/entities/door.rb +46 -0
  36. data/lib/gamefic/standard/entities/fixture.rb +8 -0
  37. data/lib/gamefic/standard/entities/item.rb +11 -0
  38. data/lib/gamefic/standard/entities/portal.rb +50 -0
  39. data/lib/gamefic/standard/entities/receptacle.rb +9 -0
  40. data/lib/gamefic/standard/entities/room.rb +55 -0
  41. data/lib/gamefic/standard/entities/rubble.rb +16 -0
  42. data/lib/gamefic/standard/entities/scenery.rb +13 -0
  43. data/lib/gamefic/standard/entities/supporter.rb +9 -0
  44. data/lib/gamefic/standard/entities/thing.rb +9 -0
  45. data/lib/gamefic/standard/entities.rb +18 -0
  46. data/lib/gamefic/standard/introduction.rb +18 -0
  47. data/lib/gamefic/standard/lockable.rb +44 -0
  48. data/lib/gamefic/standard/openable.rb +33 -0
  49. data/lib/gamefic/standard/pathfinder.rb +82 -0
  50. data/lib/gamefic/standard/queries.rb +24 -0
  51. data/lib/gamefic/standard/standardized.rb +65 -0
  52. data/lib/{gamefic-standard → gamefic/standard}/version.rb +1 -1
  53. data/lib/gamefic/standard.rb +32 -0
  54. data/lib/gamefic-standard.rb +1 -27
  55. metadata +83 -58
  56. data/lib/gamefic-standard/actions/attack.rb +0 -28
  57. data/lib/gamefic-standard/actions/close.rb +0 -18
  58. data/lib/gamefic-standard/actions/drop.rb +0 -24
  59. data/lib/gamefic-standard/actions/enter.rb +0 -36
  60. data/lib/gamefic-standard/actions/go.rb +0 -59
  61. data/lib/gamefic-standard/actions/insert.rb +0 -39
  62. data/lib/gamefic-standard/actions/inventory.rb +0 -15
  63. data/lib/gamefic-standard/actions/leave.rb +0 -50
  64. data/lib/gamefic-standard/actions/lock.rb +0 -25
  65. data/lib/gamefic-standard/actions/look.rb +0 -133
  66. data/lib/gamefic-standard/actions/move.rb +0 -24
  67. data/lib/gamefic-standard/actions/nil.rb +0 -60
  68. data/lib/gamefic-standard/actions/open.rb +0 -29
  69. data/lib/gamefic-standard/actions/place.rb +0 -24
  70. data/lib/gamefic-standard/actions/pronouns.rb +0 -28
  71. data/lib/gamefic-standard/actions/quit.rb +0 -10
  72. data/lib/gamefic-standard/actions/repeat.rb +0 -14
  73. data/lib/gamefic-standard/actions/save-restore-undo.rb +0 -18
  74. data/lib/gamefic-standard/actions/search.rb +0 -26
  75. data/lib/gamefic-standard/actions/take.rb +0 -40
  76. data/lib/gamefic-standard/actions/talk.rb +0 -37
  77. data/lib/gamefic-standard/actions/unlock.rb +0 -25
  78. data/lib/gamefic-standard/actions/wait.rb +0 -7
  79. data/lib/gamefic-standard/actions.rb +0 -23
  80. data/lib/gamefic-standard/articles.rb +0 -42
  81. data/lib/gamefic-standard/entities/character.rb +0 -2
  82. data/lib/gamefic-standard/entities/container.rb +0 -8
  83. data/lib/gamefic-standard/entities/door.rb +0 -42
  84. data/lib/gamefic-standard/entities/fixture.rb +0 -4
  85. data/lib/gamefic-standard/entities/item.rb +0 -7
  86. data/lib/gamefic-standard/entities/portal.rb +0 -46
  87. data/lib/gamefic-standard/entities/receptacle.rb +0 -5
  88. data/lib/gamefic-standard/entities/room.rb +0 -46
  89. data/lib/gamefic-standard/entities/rubble.rb +0 -12
  90. data/lib/gamefic-standard/entities/scenery.rb +0 -9
  91. data/lib/gamefic-standard/entities/supporter.rb +0 -5
  92. data/lib/gamefic-standard/entities/thing.rb +0 -9
  93. data/lib/gamefic-standard/entities.rb +0 -12
  94. data/lib/gamefic-standard/give.rb +0 -21
  95. data/lib/gamefic-standard/grammar/attributes.rb +0 -37
  96. data/lib/gamefic-standard/grammar/pronoun.rb +0 -101
  97. data/lib/gamefic-standard/grammar.rb +0 -2
  98. data/lib/gamefic-standard/introduction.rb +0 -8
  99. data/lib/gamefic-standard/modules/enterable.rb +0 -9
  100. data/lib/gamefic-standard/modules/lockable.rb +0 -34
  101. data/lib/gamefic-standard/modules/openable.rb +0 -19
  102. data/lib/gamefic-standard/modules/standardized.rb +0 -57
  103. data/lib/gamefic-standard/modules.rb +0 -6
  104. data/lib/gamefic-standard/pathfinder.rb +0 -62
  105. data/lib/gamefic-standard/queries.rb +0 -12
  106. data/spec-opal/spec_helper.rb +0 -32
  107. /data/lib/{gamefic-standard → gamefic/standard}/direction.rb +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 26551eefaf59857782cfe3e3037d201d5445211ff9982308bf3dd4dcb49ce8e0
4
- data.tar.gz: 372052d2f4974d266eeb48a624e6740a1f2d21d49577120f628846ece31e42f6
3
+ metadata.gz: 5ad2cabfd4a0d81673d3ec48454ea842e5d5f68b5bb621b7b685b9d01d20ad16
4
+ data.tar.gz: 32e4c483f7a04eebe5bdec3e85f37a90341f2a3afe8f2e879bcda9808956ee31
5
5
  SHA512:
6
- metadata.gz: 53a2ae91603d9a4fa76f904957da22154f8570d49f4d3367d828c5d0f6e900041b0574575c8aa40fe47feb8e6bbb82a906d210df9b04ce2ee13dd96afadef6c1
7
- data.tar.gz: bb11ebc79930b52e425dfab9ad6c2a145ab5b9054d927610d7ca350387d2344e66f530ef384ce0e23d05c56a3c1b4a4312d9db4480f19a6e8d68464df32b47f5
6
+ metadata.gz: 7c7cb2add780225ba638fba5d266abf2abdeabc4c01a5c0a55e6fdbd4c42a76d43c84f0ce20c8fc3807bb180553aa3570c448c1544b744e39ca06fbf392e8225
7
+ data.tar.gz: fe1479675ff888e72be337f5eb6f206b677a7fe5442cd343ed1442a48ef6079dcff3ddafce156e6e69c595282241133ccb7d6de3c99d1c2aed375144ebc177cf
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 4.0.0 - January 25, 2025
2
+ - Updates for Gamefic 4.0
3
+
4
+ ## 3.3.0 - October 5, 2024
5
+ - Include Pronoun and Give in Standard
6
+ - Add gamefic-what
7
+ - Standard::Actions namespace
8
+ - Room#connect accepts additional portal attributes
9
+ - Add gamefic-grammar
10
+
1
11
  ## 3.2.4 - September 10, 2024
2
12
  - Include Articles in Standard
3
13
 
data/Rakefile CHANGED
@@ -1,14 +1,20 @@
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
- Opal.append_path File.expand_path('../lib', __FILE__)
13
+ Opal.append_path File.join(__dir__, 'lib')
11
14
  Opal.use_gem('gamefic')
15
+ Opal.use_gem('gamefic-grammar')
16
+ Opal.use_gem('gamefic-what')
17
+ config.default_path = 'spec'
12
18
  config.pattern = 'spec/**/*_spec.rb'
13
- config.requires = ['spec_helper']
19
+ config.requires = ['opal_helper']
14
20
  end
@@ -1,17 +1,17 @@
1
- lib = File.expand_path("../lib", __FILE__)
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
- spec.name = "gamefic-standard"
6
+ spec.name = 'gamefic-standard'
7
7
  spec.version = Gamefic::Standard::VERSION
8
- spec.authors = ["Fred Snyder"]
9
- spec.email = ["fsnyder@castwide.com"]
8
+ spec.authors = ['Fred Snyder']
9
+ spec.email = ['fsnyder@castwide.com']
10
10
 
11
- spec.summary = %q{The Gamefic standard script library.}
12
- spec.description = %q{A collection of components for building games and interactive fiction in Gamefic.}
13
- spec.homepage = "http://gamefic.com"
14
- spec.license = "MIT"
11
+ spec.summary = 'The Gamefic standard script library.'
12
+ spec.description = 'A collection of components for building games and interactive fiction in Gamefic.'
13
+ spec.homepage = 'https://gamefic.com'
14
+ spec.license = 'MIT'
15
15
 
16
16
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
17
  # to allow pushing to a single host or delete this section to allow pushing to any host.
@@ -28,16 +28,18 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  # Specify which files should be added to the gem when it is released.
30
30
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
31
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
31
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
32
32
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
33
33
  end
34
- spec.bindir = "exe"
34
+ spec.bindir = 'exe'
35
35
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
- spec.require_paths = ["lib"]
36
+ spec.require_paths = ['lib']
37
37
 
38
38
  spec.required_ruby_version = '>= 2.7.0'
39
39
 
40
- spec.add_dependency 'gamefic', '~> 3.3'
40
+ spec.add_dependency 'gamefic', '~> 4.0'
41
+ spec.add_dependency 'gamefic-grammar', '~> 1.1'
42
+ spec.add_dependency 'gamefic-what', '~> 2.0'
41
43
 
42
44
  spec.add_development_dependency 'opal', '~> 1.7'
43
45
  spec.add_development_dependency 'opal-rspec', '~> 1.0'
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Attack
7
+ extend Gamefic::Scriptable
8
+
9
+ respond :attack do |actor|
10
+ actor.tell 'Violence is not the answer here.'
11
+ end
12
+
13
+ respond :attack, Thing do |actor, _thing|
14
+ actor.execute :attack
15
+ end
16
+
17
+ interpret 'fight', 'attack'
18
+ interpret 'battle', 'attack'
19
+ interpret 'kill', 'attack'
20
+ interpret 'punch', 'attack'
21
+ interpret 'kick', 'attack'
22
+ interpret 'hit', 'attack'
23
+ interpret 'fight :thing', 'attack :thing'
24
+ interpret 'battle :thing', 'attack :thing'
25
+ interpret 'kill :thing', 'attack :thing'
26
+ interpret 'punch :thing', 'attack :thing'
27
+ interpret 'kick :thing', 'attack :thing'
28
+ interpret 'hit :thing', 'attack :thing'
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Close
7
+ extend Gamefic::Scriptable
8
+
9
+ respond :close, available do |actor, thing|
10
+ actor.tell "You can't close #{the thing}."
11
+ end
12
+
13
+ respond :close, available(Openable) do |actor, thing|
14
+ if thing.open?
15
+ actor.tell "You close #{the thing}."
16
+ thing.open = false
17
+ else
18
+ actor.tell "#{The thing} is already closed."
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Drop
7
+ extend Gamefic::Scriptable
8
+
9
+ respond :drop, available do |actor, thing|
10
+ actor.tell "You're not carrying #{the thing}."
11
+ end
12
+
13
+ respond :drop, descendants do |actor, thing|
14
+ actor.execute :take, thing
15
+ next unless thing.parent == actor
16
+
17
+ thing.parent = actor.parent
18
+ actor.tell "You drop #{the thing}."
19
+ end
20
+
21
+ respond :drop, descendants do |actor, thing|
22
+ thing.parent = actor.parent
23
+ actor.tell "You drop #{the thing}."
24
+ end
25
+
26
+ respond :drop, plaintext(/^(all|everything)$/) do |actor, _all|
27
+ if actor.children.empty?
28
+ actor.tell "You're not carrying anything."
29
+ else
30
+ actor.children.each { |item| actor.execute :drop, item }
31
+ end
32
+ end
33
+
34
+ interpret 'put down :thing', 'drop :thing'
35
+ interpret 'put :thing down', 'drop :thing'
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Enter
7
+ extend Gamefic::Scriptable
8
+
9
+ respond :enter, siblings do |actor, thing|
10
+ actor.tell "#{The thing} can't accommodate you."
11
+ end
12
+
13
+ respond :enter, siblings(Enterable, proc(&:enterable?)) do |actor, supporter|
14
+ actor.parent = supporter
15
+ actor.tell "You get in #{the supporter}."
16
+ end
17
+
18
+ respond :enter, parent do |actor, container|
19
+ actor.tell "You're already in #{the container}."
20
+ end
21
+
22
+ respond :enter, siblings(Container, proc(&:enterable?), proc(&:closed?)) do |actor, container|
23
+ actor.tell "#{The container} is closed."
24
+ end
25
+
26
+ interpret 'get in :thing', 'enter :thing'
27
+ interpret 'get inside :thing', 'enter :thing'
28
+ interpret 'sit in :thing', 'enter :thing'
29
+ interpret 'lie in :thing', 'enter :thing'
30
+ interpret 'stand in :thing', 'enter :thing'
31
+ end
32
+ end
33
+ end
34
+ 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,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Go
7
+ extend Gamefic::Scriptable
8
+
9
+ respond :go, siblings(Portal) do |actor, portal|
10
+ if portal.destination.nil?
11
+ actor.tell 'That portal leads nowhere.'
12
+ else
13
+ actor.parent = portal.destination
14
+ actor.tell "You go #{portal.direction}." unless portal.direction.nil?
15
+ actor.execute :look
16
+ end
17
+ end
18
+
19
+ respond :go, plaintext do |actor, text|
20
+ if actor.parent == actor.room
21
+ actor.tell "I don't see any way to go \"#{text}\" from here."
22
+ else
23
+ actor.execute :leave
24
+ if actor.parent == actor.room
25
+ actor.perform "go #{text}"
26
+ else
27
+ actor.proceed
28
+ end
29
+ end
30
+ end
31
+
32
+ respond :go, available(Door) do |actor, door|
33
+ actor.execute :open, door unless door.open?
34
+ actor.proceed if door.open?
35
+ end
36
+
37
+ interpret 'north', 'go north'
38
+ interpret 'south', 'go south'
39
+ interpret 'west', 'go west'
40
+ interpret 'east', 'go east'
41
+ interpret 'up', 'go up'
42
+ interpret 'down', 'go down'
43
+ interpret 'northwest', 'go northwest'
44
+ interpret 'northeast', 'go northeast'
45
+ interpret 'southwest', 'go southwest'
46
+ interpret 'southeast', 'go southeast'
47
+
48
+ interpret 'n', 'go north'
49
+ interpret 's', 'go south'
50
+ interpret 'w', 'go west'
51
+ interpret 'e', 'go east'
52
+ interpret 'u', 'go up'
53
+ interpret 'd', 'go down'
54
+ interpret 'nw', 'go northwest'
55
+ interpret 'ne', 'go northeast'
56
+ interpret 'sw', 'go southwest'
57
+ interpret 'se', 'go southeast'
58
+
59
+ interpret 'go to :place', 'go :place'
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Insert
7
+ extend Gamefic::Scriptable
8
+
9
+ respond :insert, available, available do |actor, thing, target|
10
+ actor.tell "You can't put #{the thing} inside #{the target}."
11
+ end
12
+
13
+ respond :insert, available, available(Receptacle) do |actor, thing, receptacle|
14
+ actor.execute :take, thing unless thing.parent == actor
15
+ next unless thing.parent == actor
16
+
17
+ thing.parent = receptacle
18
+ actor.tell "You put #{the thing} in #{the receptacle}."
19
+ end
20
+
21
+ respond :insert, available, available(Container) do |actor, _thing, container|
22
+ if container.open?
23
+ actor.proceed
24
+ else
25
+ actor.tell "#{The container} is closed."
26
+ end
27
+ end
28
+
29
+ respond :insert, children, room do |actor, thing|
30
+ actor.execute :drop, thing
31
+ end
32
+
33
+ interpret 'drop :item in :container', 'insert :item :container'
34
+ interpret 'put :item in :container', 'insert :item :container'
35
+ interpret 'place :item in :container', 'insert :item :container'
36
+ interpret 'set :item in :container', 'insert :item :container'
37
+ interpret 'insert :item in :container', 'insert :item :container'
38
+
39
+ interpret 'drop :item inside :container', 'insert :item :container'
40
+ interpret 'put :item inside :container', 'insert :item :container'
41
+ interpret 'place :item inside :container', 'insert :item :container'
42
+ interpret 'set :item inside :container', 'insert :item :container'
43
+ interpret 'insert :item inside :container', 'insert :item :container'
44
+
45
+ interpret 'drop :item into :container', 'insert :item :container'
46
+ interpret 'put :item into :container', 'insert :item :container'
47
+ interpret 'place :item into :container', 'insert :item :container'
48
+ interpret 'set :item into :container', 'insert :item :container'
49
+ interpret 'insert :item into :container', 'insert :item :container'
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Inventory
7
+ extend Gamefic::Scriptable
8
+
9
+ respond :inventory do |actor|
10
+ if actor.children.length > 0
11
+ actor.tell "You are carrying #{actor.children.join_and}."
12
+ else
13
+ actor.tell "You aren't carrying anything."
14
+ end
15
+ end
16
+ interpret 'i', 'inventory'
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Leave
7
+ extend Gamefic::Scriptable
8
+
9
+ respond :leave, parent do |actor, thing|
10
+ actor.tell "There's no way out of #{the thing}."
11
+ end
12
+
13
+ respond :leave, parent(Enterable, proc(&:enterable?)) do |actor, thing|
14
+ actor.tell "You leave #{the thing}."
15
+ actor.parent = thing.parent
16
+ end
17
+
18
+ respond :leave, parent(Supporter, proc(&:enterable?)) do |actor, thing|
19
+ actor.tell "You get off #{the thing}."
20
+ actor.parent = thing.parent
21
+ end
22
+
23
+ respond :leave, room do |actor, room|
24
+ portals = room.children.that_are(Portal)
25
+ if portals.length == 0
26
+ actor.tell "You don't see any obvious exits."
27
+ elsif portals.length == 1
28
+ actor.execute :go, portals[0]
29
+ else
30
+ actor.tell "I don't know which way you want to go: #{portals.map(&:instruction).join_or}."
31
+ end
32
+ end
33
+
34
+ respond :leave do |actor|
35
+ if actor.parent
36
+ actor.execute :leave, actor.parent
37
+ else
38
+ actor.tell "You don't see any obvious exits."
39
+ end
40
+ end
41
+
42
+ respond :leave, parent(Container, proc(&:enterable?), proc(&:closed?)) do |actor, container|
43
+ actor.execute :open, container
44
+ actor.proceed if container.open?
45
+ end
46
+
47
+ interpret 'exit', 'leave'
48
+ interpret 'exit :supporter', 'leave :supporter'
49
+ interpret 'get on :supporter', 'enter :supporter'
50
+ interpret 'get off :supporter', 'leave :supporter'
51
+ interpret 'get out :container', 'leave :container'
52
+ interpret 'get out of :container', 'leave :container'
53
+ interpret 'out', 'leave'
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gamefic
4
+ module Standard
5
+ module Actions
6
+ module Lock
7
+ extend Gamefic::Scriptable
8
+
9
+ respond :lock, available do |actor, thing|
10
+ actor.tell "You can't lock #{the thing}."
11
+ end
12
+
13
+ respond :lock, available(Lockable, proc(&:has_lock_key?)), children do |actor, thing, key|
14
+ if thing.lock_key == key
15
+ thing.locked = true
16
+ actor.tell "You lock ##{the thing} with #{the key}."
17
+ else
18
+ actor.tell "You can't lock #{the thing} with #{the key}."
19
+ end
20
+ end
21
+
22
+ respond :lock, available(Lockable, proc(&:has_lock_key?)), available do |actor, thing, key|
23
+ actor.execute :take, key if key.parent != actor
24
+ actor.proceed if key.parent == actor
25
+ end
26
+
27
+ interpret "lock :container with :key", "lock :container :key"
28
+ end
29
+ end
30
+ end
31
+ 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