gamefic 0.0.5 → 0.1.1

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/bin/gamefic +7 -0
  3. data/lib/gamefic/character.rb +2 -0
  4. data/lib/gamefic/core_ext/string.rb +2 -2
  5. data/lib/gamefic/director.rb +36 -3
  6. data/lib/gamefic/engine.rb +9 -5
  7. data/lib/gamefic/entity.rb +1 -1
  8. data/lib/gamefic/import/basics.rb +2 -0
  9. data/lib/gamefic/import/basics/actions.rb +1 -0
  10. data/lib/gamefic/import/basics/actions/container.rb +111 -0
  11. data/lib/gamefic/import/basics/actions/inventory.rb +49 -0
  12. data/lib/gamefic/import/basics/actions/look.rb +67 -0
  13. data/lib/gamefic/import/basics/actions/meta.rb +6 -0
  14. data/lib/gamefic/import/basics/actions/traversal.rb +35 -0
  15. data/lib/gamefic/import/basics/entities.rb +1 -0
  16. data/lib/gamefic/import/basics/entities/container.rb +24 -0
  17. data/lib/gamefic/import/basics/entities/fixture.rb +5 -0
  18. data/lib/gamefic/import/basics/entities/item.rb +7 -0
  19. data/lib/gamefic/import/basics/entities/itemized.rb +3 -0
  20. data/lib/gamefic/import/basics/entities/portable.rb +3 -0
  21. data/lib/gamefic/import/basics/entities/portal.rb +43 -0
  22. data/lib/gamefic/import/basics/entities/room.rb +24 -0
  23. data/lib/gamefic/import/basics/entities/scenery.rb +3 -0
  24. data/lib/gamefic/import/basics/room_modes.rb +48 -0
  25. data/lib/gamefic/plot.rb +89 -16
  26. data/lib/gamefic/shell.rb +317 -0
  27. data/lib/gamefic/syntax.rb +1 -1
  28. data/lib/gamefic/user.rb +3 -3
  29. metadata +23 -18
  30. data/lib/gamefic/action_ext.rb +0 -7
  31. data/lib/gamefic/action_ext/container.rb +0 -114
  32. data/lib/gamefic/action_ext/inventory.rb +0 -53
  33. data/lib/gamefic/action_ext/look.rb +0 -52
  34. data/lib/gamefic/action_ext/meta.rb +0 -10
  35. data/lib/gamefic/action_ext/traversal.rb +0 -39
  36. data/lib/gamefic/entity_ext.rb +0 -7
  37. data/lib/gamefic/entity_ext/container.rb +0 -28
  38. data/lib/gamefic/entity_ext/fixture.rb +0 -9
  39. data/lib/gamefic/entity_ext/item.rb +0 -11
  40. data/lib/gamefic/entity_ext/itemized.rb +0 -7
  41. data/lib/gamefic/entity_ext/portable.rb +0 -33
  42. data/lib/gamefic/entity_ext/portal.rb +0 -47
  43. data/lib/gamefic/entity_ext/room.rb +0 -28
  44. data/lib/gamefic/entity_ext/scenery.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 20c3e34c3d13071e770eda8495d563a655dcbeb1
4
- data.tar.gz: e426f447d23f070f3e8ba86e53869dfd1a1bbbaf
3
+ metadata.gz: 0ebda04fc06a182081d6516d328bd23501586ecd
4
+ data.tar.gz: 1e8aa7db0b490b0f864071fb74317a7a2f1b330d
5
5
  SHA512:
6
- metadata.gz: e3021ba57098702d8432f469a5df40a69b18560cb51680bec94a5eae0dd55291432c1191faec2456554e42a53027f4a8e6439e5b7a5b509827181e34469228ca
7
- data.tar.gz: 83877a6aef2eb5150087840fdd4f8349bf489e21b3b0516484f6a25a3d07ecadf2861ddedc6192afdad9ebfe67ba5c0713e5dc711074c410b654dba12b9fa215
6
+ metadata.gz: 74a8a6dc8951a30802fb5bb8e6ee764525885572fc0fa18018ea4cd9890f48674830dc94274528ca4e1f0b58de2043d547f1f8e60f14d6e8cb1a41ce30f53d1c
7
+ data.tar.gz: 3181204289bc694587d60ffebf14f660a6c85d7f5140927f27f5e3c13fff60684f63c7fd59cf89d1acc8ac0ccaf85f5566f09f5d626a2a9d588518036acacc73
data/bin/gamefic ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'gamefic'
4
+ require 'gamefic/shell'
5
+
6
+ shell = Gamefic::Shell.new
7
+ shell.execute
@@ -2,6 +2,7 @@ module Gamefic
2
2
 
3
3
  class Character < Entity
4
4
  attr_reader :state, :queue, :user, :last_command
5
+ attr_accessor :object_of_pronoun
5
6
  def initialize(plot, args = {})
6
7
  @state = CharacterState.new(self)
7
8
  @queue = Array.new
@@ -78,4 +79,5 @@ module Gamefic
78
79
  "GAME OVER"
79
80
  end
80
81
  end
82
+
81
83
  end
@@ -20,7 +20,7 @@ class String
20
20
  lines.each { |line|
21
21
  if line.size > 79
22
22
  while (line.size > 79)
23
- offset = line.rindex(/[\s\W]/, 79)
23
+ offset = line.rindex(/[\s\-]/, 79)
24
24
  if (offset == 0 or offset == nil)
25
25
  output = output + line + "\n"
26
26
  line = ''
@@ -34,7 +34,7 @@ class String
34
34
  output = output + line + "\n"
35
35
  end
36
36
  }
37
- return output.strip
37
+ return output
38
38
  end
39
39
  def split_words
40
40
  self.gsub(/ +/, ' ').strip.split
@@ -3,6 +3,26 @@ module Gamefic
3
3
  class Director
4
4
  def self.dispatch(actor, command)
5
5
  command.strip!
6
+ verbs = actor.plot.commandwords
7
+ first = command.split(' ')[0].downcase
8
+ if verbs.include?(first) == false
9
+ possibles = []
10
+ verbs.each { |v|
11
+ if v.start_with?(first)
12
+ possibles.push v
13
+ end
14
+ }
15
+ if possibles.length == 1
16
+ command = possibles[0] + command[first.length..-1]
17
+ else
18
+ if possibles.length > 1
19
+ actor.tell "'#{first.cap_first}' is ambiguous."
20
+ else
21
+ actor.tell "I don't understand '#{first}' as a command."
22
+ end
23
+ return
24
+ end
25
+ end
6
26
  handlers = Syntax.match(command, actor.plot.syntaxes)
7
27
  options = Array.new
8
28
  handlers.each { |handler|
@@ -31,7 +51,7 @@ module Gamefic
31
51
  }
32
52
  options.push([
33
53
  Proc.new { |actor|
34
- first = Keywords.new(command)[0]
54
+ first = command.split(' ')[0].downcase
35
55
  if actor.plot.commandwords.include?(first)
36
56
  actor.tell "I know the verb '#{first}' but couldn't understand the rest of your sentence."
37
57
  else
@@ -63,9 +83,17 @@ module Gamefic
63
83
  valid = false
64
84
  next
65
85
  end
66
- result = context.execute(last[0], arg)
86
+ if arg == 'it' and actor.object_of_pronoun != nil
87
+ result = context.execute(last[0], "#{actor.object_of_pronoun.longname}")
88
+ else
89
+ result = context.execute(last[0], arg)
90
+ end
67
91
  else
68
- result = context.execute(actor, arg)
92
+ if arg == 'it' and actor.object_of_pronoun != nil
93
+ result = context.execute(actor, "#{actor.object_of_pronoun.longname}")
94
+ else
95
+ result = context.execute(actor, arg)
96
+ end
69
97
  end
70
98
  if result.objects.length == 0
71
99
  valid = false
@@ -104,6 +132,11 @@ module Gamefic
104
132
  if opt[1].length == 1
105
133
  opt[0].call(opt[1][0])
106
134
  else
135
+ if opt[1].length == 2 and opt[1][1].kind_of?(Entity)
136
+ opt[1][0].object_of_pronoun = opt[1][1]
137
+ else
138
+ opt[1][0].object_of_pronoun = nil
139
+ end
107
140
  opt[0].call(opt[1])
108
141
  end
109
142
  end
@@ -6,11 +6,15 @@ module Gamefic
6
6
  end
7
7
  def run
8
8
  user = User.new @plot
9
- @plot.introduce user.character
10
- while true
11
- user.stream.select user.character.state.prompt
12
- user.state.update
13
- @plot.update
9
+ @plot.introduce user.character
10
+ while user.character.state.kind_of?(GameOverState) == false
11
+ proc {
12
+ $SAFE = 3
13
+ user.stream.select user.character.state.prompt
14
+ print "\n"
15
+ user.state.update
16
+ @plot.update
17
+ }.call
14
18
  end
15
19
  end
16
20
  end
@@ -4,7 +4,7 @@ require "gamefic/describable"
4
4
  require "gamefic/plot"
5
5
 
6
6
  module Gamefic
7
-
7
+
8
8
  class Entity
9
9
  include Branch
10
10
  include Describable
@@ -0,0 +1,2 @@
1
+ import 'basics/entities'
2
+ import 'basics/*'
@@ -0,0 +1 @@
1
+ import 'basics/actions/*'
@@ -0,0 +1,111 @@
1
+ respond :look, Query.new(:family, Container) do |actor, thing|
2
+ passthru
3
+ if thing.closeable?
4
+ actor.tell "#{thing.longname.specify.cap_first} is #{thing.closed? ? 'closed' : 'open'}."
5
+ end
6
+ end
7
+
8
+ respond :look_inside, Query.new(:family, Container) do |actor, container|
9
+ if container.closed?
10
+ actor.tell "#{container.longname.cap_first.specify} is closed."
11
+ else
12
+ if container.children.length == 0
13
+ actor.tell "You don't find anything."
14
+ else
15
+ if container.children.length == 1
16
+ actor.tell "#{container.longname.specify.cap_first} contains #{container.children[0].longname}."
17
+ else
18
+ actor.tell "#{container.longname.specify.cap_first} contains: #{container.children.join_and(', ')}."
19
+ end
20
+ end
21
+ end
22
+ end
23
+ xlate "look inside :container", :look_inside, :container
24
+ xlate "search :container", :look_inside, :container
25
+ xlate "look in :container", :look_inside, :container
26
+
27
+ respond :look_in_at, Query.new(:family, Container), Subquery.new(:children, Entity) do |actor, container, item|
28
+ if container.closed?
29
+ actor.tell "#{container.longname.cap_first.specify} is closed."
30
+ else
31
+ actor.tell item.description
32
+ end
33
+ end
34
+
35
+ respond :look_in_at, Query.new(:family, Container), Query.new(:string) do |actor, container, item|
36
+ if container.closed?
37
+ actor.tell "#{container.longname.cap_first.specify} is closed."
38
+ else
39
+ passthru
40
+ end
41
+ end
42
+
43
+ xlate "look at :item in :container", :look_in_at, :container, :item
44
+ xlate "look :item in :container", :look_in_at, :container, :item
45
+
46
+ respond :take_from, Query.new(:family, Container), Subquery.new(:children, Portable) do |actor, container, item|
47
+ if container.closed?
48
+ actor.tell "#{container.longname.cap_first.specify} is closed."
49
+ else
50
+ item.parent = actor
51
+ actor.tell "You take #{item.longname} from #{container.longname.specify}."
52
+ end
53
+ end
54
+ xlate "take :item from :container", :take_from, :container, :item
55
+ xlate "get :item from :container", :take_from, :container, :item
56
+ xlate "remove :item from :container", :take_from, :container, :item
57
+
58
+ respond :drop_in, Query.new(:family, Container), Query.new(:children) do |actor, container, item|
59
+ if container.closed?
60
+ actor.tell "#{container.longname.cap_first.specify} is closed."
61
+ else
62
+ item.parent = container
63
+ actor.tell "You put #{item.longname} in #{container.longname}."
64
+ end
65
+ end
66
+ xlate "drop :item in :container", :drop_in, :container, :item
67
+ xlate "put :item in :container", :drop_in, :container, :item
68
+ xlate "place :item in :container", :drop_in, :container, :item
69
+
70
+ respond :open, Query.new(:string) do |actor, string|
71
+ actor.tell "You don't see any \"#{string}\" here."
72
+ end
73
+
74
+ respond :open, Query.new(:family, Entity) do |actor, thing|
75
+ actor.tell "You can't open #{thing.longname.specify}."
76
+ end
77
+
78
+ respond :open, Query.new(:family, Container) do |actor, container|
79
+ if container.closeable?
80
+ if container.closed?
81
+ actor.tell "You open #{container.longname.specify}."
82
+ container.closed = false
83
+ actor.perform "look inside #{container.longname}"
84
+ else
85
+ actor.tell "It's already open."
86
+ end
87
+ else
88
+ actor.tell "You can't open #{container.longname.specify}."
89
+ end
90
+ end
91
+
92
+ respond :close, Query.new(:string) do |actor, string|
93
+ actor.tell "You don't see any \"#{string}\" here."
94
+ end
95
+
96
+ respond :close, Query.new(:family, Entity) do |actor, thing|
97
+ actor.tell "You can't close #{thing.longname.specify}."
98
+ end
99
+
100
+ respond :close, Query.new(:family, Container) do |actor, container|
101
+ if container.closeable?
102
+ if container.closed?
103
+ actor.tell "It's already closed."
104
+ else
105
+ actor.tell "You close #{container.longname.specify}."
106
+ container.closed = true
107
+ end
108
+ else
109
+ actor.tell "You can't close #{container.longname.specify}."
110
+ end
111
+ end
@@ -0,0 +1,49 @@
1
+ respond :inventory do |actor|
2
+ if actor.children.length > 0
3
+ actor.tell actor.children.join(', ')
4
+ else
5
+ actor.tell "You aren't carrying anything."
6
+ end
7
+ end
8
+ xlate "i", :inventory
9
+
10
+ respond :take, Query.new(:siblings, Portable) do |actor, thing|
11
+ thing.parent = actor
12
+ actor.tell "You take #{thing.longname.specify}.", true
13
+ end
14
+
15
+ respond :take, Query.new(:siblings) do |actor, thing|
16
+ actor.tell "You can't carry #{thing.longname.specify}."
17
+ end
18
+
19
+ respond :take, Query.new(:string) do |actor, thing|
20
+ containers = actor.children.that_are(Container)
21
+ containers = containers + actor.parent.children.that_are(Container)
22
+ found = false
23
+ containers.each { |container|
24
+ if container.closed? == false
25
+ query = Query.new(:children, Portable)
26
+ result = query.execute(container, thing)
27
+ if result.objects.length == 1
28
+ found = true
29
+ actor.perform "take #{result.objects[0].longname} from #{container.longname}"
30
+ break
31
+ end
32
+ end
33
+ }
34
+ if found == false
35
+ actor.tell "You don't see any \"#{thing}\" here."
36
+ end
37
+ end
38
+
39
+ respond :drop, Query.new(:children) do |actor, thing|
40
+ thing.parent = actor.parent
41
+ actor.tell "You drop #{thing.longname.specify}.", true
42
+ end
43
+
44
+ xlate "get :thing", :take, :thing
45
+ xlate "pick :thing up", :take, :thing
46
+ xlate "pick up :thing", :take, :thing
47
+
48
+ xlate "put down :thing", :drop, :thing
49
+ xlate "put :thing down", :drop, :thing
@@ -0,0 +1,67 @@
1
+ respond :look do |actor|
2
+ actor.perform "itemize room full"
3
+ end
4
+
5
+ respond :look_around do |actor|
6
+ actor.perform "look"
7
+ end
8
+
9
+ respond :itemize_room, Query.new(:string) do |actor, option|
10
+ actor.tell "## #{actor.parent.longname.cap_first}"
11
+ if option == "full"
12
+ actor.tell actor.parent.description
13
+ end
14
+ chars = actor.parent.children.that_are(Character) - [actor]
15
+ if chars.length > 0
16
+ actor.tell "Others here: #{chars.join(", ")}"
17
+ end
18
+ #items = actor.parent.children.that_are(Itemized) - [chars] - [actor] - actor.parent.children.that_are(Portal)
19
+ items = actor.parent.children.that_are(Itemized)
20
+ if items.length > 0
21
+ actor.tell "Visible items: #{items.join(", ")}"
22
+ end
23
+ portals = actor.parent.children.that_are(Portal)
24
+ if portals.length > 0
25
+ actor.tell "Obvious exits: #{portals.join(', ')}"
26
+ else
27
+ actor.tell "Obvious exits: none"
28
+ end
29
+ end
30
+ xlate "itemize room", :itemize_room, "short"
31
+ xlate "itemize room :option", :itemize_room, :option
32
+
33
+ respond :look, Query.new(:family) do |actor, thing|
34
+ actor.tell thing.description
35
+ end
36
+
37
+ respond :look, Query.new(:parent) do |actor, thing|
38
+ actor.perform "look"
39
+ end
40
+
41
+ respond :look, String do |actor, string|
42
+ containers = actor.children.that_are(Container)
43
+ containers = containers + actor.parent.children.that_are(Container)
44
+ found = false
45
+ containers.each { |container|
46
+ if container.closed? == false
47
+ query = Query.new(:children, Portable)
48
+ result = query.execute(container, string)
49
+ if result.objects.length == 1
50
+ found = true
51
+ actor.tell "You look at #{result.objects[0].longname.specify} in #{container.longname.specify}."
52
+ actor.perform "look #{result.objects[0].longname} in #{container.longname}"
53
+ break
54
+ end
55
+ end
56
+ }
57
+ if found == false
58
+ actor.tell "You don't see any \"#{string}\" here."
59
+ end
60
+ end
61
+
62
+ xlate "look at :thing", :look, :thing
63
+ xlate "l", :look
64
+ xlate "l :thing", :look, :thing
65
+ xlate "examine :thing", :look, :thing
66
+ xlate "exam :thing", :look, :thing
67
+ xlate "x :thing", :look, :thing
@@ -0,0 +1,6 @@
1
+ respond :quit do |actor|
2
+ actor.destroy
3
+ end
4
+ respond :commands do |actor|
5
+ actor.tell actor.plot.commandwords.sort.join(", ")
6
+ end
@@ -0,0 +1,35 @@
1
+ respond :go, Query.new(:siblings, Portal) do |actor, portal|
2
+ actor.parent = portal.destination
3
+ actor.tell "You go #{portal.name}."
4
+ actor.perform "itemize room"
5
+ end
6
+
7
+ respond :go, String do |actor, string|
8
+ actor.tell "You don't see any exit \"#{string}\" from here."
9
+ end
10
+
11
+ respond :go do |actor|
12
+ actor.tell "Where do you want to go?"
13
+ end
14
+
15
+ xlate "north", :go, "north"
16
+ xlate "south", :go, "south"
17
+ xlate "west", :go, "west"
18
+ xlate "east", :go, "east"
19
+ xlate "up", :go, "up"
20
+ xlate "down", :go, "down"
21
+ xlate "northwest", :go, "northwest"
22
+ xlate "northeast", :go, "northeast"
23
+ xlate "southwest", :go, "southwest"
24
+ xlate "southeast", :go, "southeast"
25
+
26
+ xlate "n", :go, "north"
27
+ xlate "s", :go, "south"
28
+ xlate "w", :go, "west"
29
+ xlate "e", :go, "east"
30
+ xlate "u", :go, "up"
31
+ xlate "d", :go, "down"
32
+ xlate "nw", :go, "northwest"
33
+ xlate "ne", :go, "northeast"
34
+ xlate "sw", :go, "southwest"
35
+ xlate "se", :go, "southeast"
@@ -0,0 +1 @@
1
+ import 'basics/entities/*'
@@ -0,0 +1,24 @@
1
+ import 'basics/entities/itemized'
2
+
3
+ class Container < Entity
4
+ include Itemized
5
+ def closeable=(bool)
6
+ @closeable = bool
7
+ end
8
+ def closeable?
9
+ @closeable ||= false
10
+ if (@closeable == true && @closed == nil)
11
+ @closed = false
12
+ end
13
+ @closeable
14
+ end
15
+ def closed?
16
+ (@closed == true)
17
+ end
18
+ def closed=(bool)
19
+ if bool == true
20
+ @closeable = true
21
+ end
22
+ @closed = bool
23
+ end
24
+ end