petli 0.0.2 → 0.0.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 65333f3864f90309c1fbcaab7bf7895ac0b9d8b60383cab06dbeb46a9e676de3
4
- data.tar.gz: 4bde0f8bcbe218e0003495601844612b3eecdae7ca9c58378658ee0138f567ca
3
+ metadata.gz: c9a8fbb01c6f383d9993c120cb0fd4d2305c82314baf400f4b74bfbee7c1cc81
4
+ data.tar.gz: 9dff8e3e65d3e93942c4a1fc8589206b740c26e1ac2bb385bf3132a249deb49d
5
5
  SHA512:
6
- metadata.gz: de4f1810aa3c2c7796285bb18d06e71a2047577df673b09223a93c3ae87aa86743b120f47c1203f11aafd4ab290300c7979c8b6f48b826f76cac01607dcb2ee4
7
- data.tar.gz: f8014e8e53caab3bd8e9a3a5363eddd15e9aa328254fc04fea61bece49a969ac62edfbd2254ad5b5d90984e370da2968a722e0a2abcba235d2c9e20672345c23
6
+ metadata.gz: ad282f370925d30eb0f04dc1a71a91e3300380b0f4d8b646b4c863d7917c0fb007353190ec35a73a844b67f03d6aff9becf150ea4a1b113a5aa6022ea78cb4aa
7
+ data.tar.gz: d5b3900600281412ba822dad13604fec9c1578e3621884116d5fe3e2e1b5daf07dca5ad48637877e729da0e73bb9894e8db41573b41edd37e020cc66921ede52
data/Gemfile.lock CHANGED
@@ -1,11 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- petli (0.0.1)
4
+ petli (0.0.2)
5
5
  pastel (~> 0.8.0)
6
6
  tty-box (~> 0.7.0)
7
7
  tty-color (~> 0.6.0)
8
- tty-config (~> 0.5.0)
9
8
  tty-cursor (~> 0.7.1)
10
9
  tty-platform (~> 0.3.0)
11
10
  tty-reader (~> 0.9.0)
@@ -26,7 +25,6 @@ GEM
26
25
  strings (~> 0.2.0)
27
26
  tty-cursor (~> 0.7)
28
27
  tty-color (0.6.0)
29
- tty-config (0.5.0)
30
28
  tty-cursor (0.7.1)
31
29
  tty-platform (0.3.0)
32
30
  tty-reader (0.9.0)
@@ -34,12 +32,13 @@ GEM
34
32
  tty-screen (~> 0.8)
35
33
  wisper (~> 2.0)
36
34
  tty-screen (0.8.1)
37
- unicode-display_width (2.0.0)
35
+ unicode-display_width (2.1.0)
38
36
  unicode_utils (1.4.0)
39
37
  wisper (2.0.1)
40
38
 
41
39
  PLATFORMS
42
40
  arm64-darwin-20
41
+ x86_64-darwin-20
43
42
 
44
43
  DEPENDENCIES
45
44
  petli!
data/README.md CHANGED
@@ -1,15 +1,15 @@
1
- PETLI
2
- -----
3
-
4
- Pet line interface (look I know it should have been command line pet like Clipet? Clet? those just don't sound great)
5
-
6
- This is a little virtual pet that will live in your console. You must feed it, clean up after it, and play with it to keep it happy!
7
-
8
- ![image](https://user-images.githubusercontent.com/463193/127347754-a07f71a0-b8c4-4d73-a24f-0bf78fca22b9.png)
9
-
1
+ <p align="center">
2
+ <h1 align="center">Petli</h1>
3
+ <p align="center">Virtual Pet in your console. You must feed it, clean up after it, and play with it to keep it happy!</p>
4
+ <p align="center">
5
+ <img src="https://media.giphy.com/media/pwtUe2wVhgpQIK5puU/giphy.gif"/>
6
+ </p>
7
+ </p>
8
+
9
+ ---
10
10
  ### Usage
11
11
 
12
- Run `gem install petli` and then run `petli` in your command line
12
+ Run `gem install petli` and then run `petli` in your command line. Run `petli --help` for more information.
13
13
 
14
14
  ### Advanced usage
15
15
 
data/bin/petli CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'petli'
3
+ require 'tatty'
3
4
  require 'optparse'
4
5
 
5
6
  options = {}
@@ -12,7 +13,7 @@ OptionParser.new do |opts|
12
13
  opts.on("-m", "--medicine", "Feed your pet candy without viewing") {|v| options[:medicine] = v}
13
14
  opts.on("-l", "--clean", "Clean up any 'dirt' without viewing") {|v| options[:clean] = v}
14
15
  opts.on("-p", "--path [PATH]", "path to your pet data (defaults to system config dir)") do |v|
15
- $petlidboverride = v
16
+ $tattydboverridepath = v
16
17
  end
17
18
  end.parse!
18
19
 
@@ -20,10 +21,10 @@ pet = Petli::Pet.new
20
21
  pet.display # force pet to update first
21
22
 
22
23
  if options[:reset]
23
- Petli::DB.clear
24
+ Tatty::DB.clear
24
25
  puts "Goodbye. I hope you love your next pet!"
25
26
  elsif options[:status]
26
- puts Petli::DB.dump
27
+ puts Tatty::DB.dump
27
28
  elsif options[:bread]
28
29
  pet.feed!(food: :bread)
29
30
  elsif options[:candy]
@@ -33,5 +34,5 @@ elsif options[:medicine]
33
34
  elsif options[:clean]
34
35
  pet.clean
35
36
  else
36
- Petli::HUD.new.run
37
+ Tatty.run(Petli::Stages::Main, pet: pet)
37
38
  end
@@ -33,16 +33,16 @@ module Petli
33
33
  end
34
34
 
35
35
  def step
36
- self.add_frame
36
+ add_frame
37
37
  leftarm, rightarm = getit(:arms, 2)
38
38
  lefteye, righteye = getit(:eyes, 2)
39
39
  mouth = getit(:mouth)
40
40
  lefthead, righthead = getit(:head, 2)
41
41
  [leftarm,lefthead,lefteye,mouth,righteye,righthead,rightarm]
42
42
 
43
- food_peices = self.food.split('')
43
+ food_peices = food.split('')
44
44
 
45
- ANIMATIONS[self.action][self.frame]
45
+ ANIMATIONS[action][frame]
46
46
  .sub('a', leftarm.to_s).sub('a', rightarm.to_s)
47
47
  .sub('h', lefthead).sub('h', righthead)
48
48
  .sub('e', lefteye).sub('e', righteye)
@@ -93,9 +93,9 @@ module Petli
93
93
  private
94
94
 
95
95
  def add_frame
96
- frame_count = ANIMATIONS[self.action].count
96
+ frame_count = ANIMATIONS[action].count
97
97
  @frame += 1
98
- if self.frame == frame_count
98
+ if frame == frame_count
99
99
  @frame = 0
100
100
  @action_stack.shift if @action_stack.count > 0
101
101
  @mood_stack.shift if @mood_stack.count > 0
@@ -108,7 +108,7 @@ module Petli
108
108
  end
109
109
 
110
110
  def food
111
- self.data[@food]
111
+ data[@food]
112
112
  end
113
113
 
114
114
  def frame # to control framerate
@@ -116,8 +116,8 @@ module Petli
116
116
  end
117
117
 
118
118
  def getit(part, vals=1)
119
- mood_part = self.data[part][self.mood] || self.data[part][:default]
120
- part_frame = self.frame % mood_part.count
119
+ mood_part = data[part][mood] || data[part][:default]
120
+ part_frame = frame % mood_part.count
121
121
  result = mood_part[part_frame]
122
122
  if vals == 2 && result.is_a?(String)
123
123
  [result, result]
data/lib/petli/pet.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Petli
2
2
  class Pet
3
3
  include Watch
4
- extend DB::Attributes
4
+ extend Tatty::DB::Attributes
5
5
 
6
6
  MOOD_SCALE = [:angry, :annoyed, :normal, :happy, :great]
7
7
 
@@ -35,17 +35,19 @@ module Petli
35
35
  hours_past = hours_since(self.last_meal)
36
36
  self.last_meal = Time.now
37
37
  (0...hours_past).each do |i|
38
+ next if rand <= 0.3
38
39
  self.health = [1, self.health-1].max
39
40
  self.happiness = [1, self.happiness-1].max
40
- self.poop(hours_past - i) if rand <= 0.8
41
+ self.poops << hours_ago(i) if rand <= 0.8 && self.poops.count < Poop::LOCATIONS.count
41
42
  end
42
- self.sick = self.poops.filter{|poop| hours_since(poop.hatch) > 1 }.count
43
+ self.sick = self.poops.filter{|poop| hours_since(poop) > 1 }.count
43
44
  end
44
45
 
45
46
  if hours_since(self.last_play) > 1
46
47
  hours_past = hours_since(self.last_play)
47
48
  self.last_play = Time.now
48
49
  (0...hours_past).each do
50
+ next if rand <= 0.3
49
51
  self.happiness = [1, self.happiness-1].max
50
52
  end
51
53
  end
@@ -75,7 +77,7 @@ module Petli
75
77
  return self.embarass if ((food == :medicine && self.sick <= 0) || (self.health == 10 && food != :medicine))
76
78
  self.last_meal = Time.now unless food == :medicine
77
79
  @animation.eat(food: food) do
78
- self.feed!(food)
80
+ self.feed!(food: food)
79
81
  end
80
82
  end
81
83
 
@@ -98,10 +100,6 @@ module Petli
98
100
  @animation.action = :stand
99
101
  end
100
102
 
101
- def poop(hours_ago)
102
- self.poops = self.poops + [Poop.new(hours_ago)] if self.poops.count < Poop::LOCATIONS.count
103
- end
104
-
105
103
  def clean
106
104
  self.poops = []
107
105
  end
data/lib/petli/poop.rb CHANGED
@@ -1,26 +1,9 @@
1
1
  module Petli
2
- class Poop
3
- include Watch
4
-
2
+ class Poop < Tatty::Anim
5
3
  LOCATIONS = [[1,1], [1,4], [1,7], [11,1], [11,7], [20,1], [20,4], [20,7]]
6
4
  ANIMATION = ["ı ı ı\n༼ᵔ◡ᵔ༽", "ϟ ϟ ϟ\n༼ಠ益ಠ༽"]
7
-
8
- attr_accessor :hatch
9
-
10
- def initialize(hrsago)
11
- @frame = 0
12
- self.hatch = hours_ago(hrsago)
13
- end
14
-
15
- def step
16
- @frame += 1
17
- anim_fram = (@frame/2).ceil
18
- @frame = 0 if anim_fram >= ANIMATION.count
19
- ANIMATION[anim_fram]
20
- end
21
-
22
- def to_json(opts)
23
- self.hatch.to_json
5
+ def initialize()
6
+ super(ANIMATION)
24
7
  end
25
8
  end
26
9
  end
@@ -0,0 +1,76 @@
1
+ require 'pastel'
2
+
3
+ module Petli
4
+ module Stages
5
+ class Base < Tatty::Stage
6
+ GAME_WIDTH = 28
7
+ GAME_HEIGHT = 13
8
+
9
+ def initialize(pet:)
10
+ super()
11
+ @pet = pet
12
+ @poop = Poop.new
13
+ end
14
+
15
+ def keypress(event)
16
+ exit if event.value == "q" || event.value == "\e" || event.value == "x"
17
+ return if @pet.busy? || @pet.dead?
18
+ onkey(event)
19
+ end
20
+
21
+ def onkey(event)
22
+ end
23
+
24
+ def actions
25
+ %w()
26
+ end
27
+
28
+ def action_bar
29
+ return "" if @pet.dead?
30
+ p = Pastel.new
31
+ self.actions.map do |a|
32
+ key = p.bold("[#{a[0].capitalize}]")
33
+ "#{key}#{a[1..]}"
34
+ end.join(" ")
35
+ end
36
+
37
+ def left
38
+ ((screen_width-GAME_WIDTH)/2).round
39
+ end
40
+
41
+ def top
42
+ ((screen_height-GAME_HEIGHT)/2).round
43
+ end
44
+
45
+ def draw
46
+ p = Pastel.new
47
+ render_box(
48
+ title: {
49
+ top_left: p.bright_white.bold(" Petli "),
50
+ bottom_right: p.green(" #{@pet.lifetime} days "),
51
+ },
52
+ width: GAME_WIDTH,
53
+ height: GAME_HEIGHT,
54
+ left: left,
55
+ top: top,
56
+ )
57
+
58
+ poop = @poop.step
59
+ @pet.poops.each_with_index do |_, i|
60
+ x, y = Poop::LOCATIONS[i]
61
+ render_at(left+1+x, top+1+y, poop)
62
+ end
63
+
64
+ render_at(left+9, top+4, @pet.display)
65
+ sick = @pet.sick
66
+ if sick > 0 && !@pet.dead?
67
+ render_at(left+11-sick, top+4, "[#{'!'*sick}SICK#{'!'*sick}]")
68
+ end
69
+
70
+ render_at(left+1, top+1, "#{p.red("♥")*@pet.health}#{"♡"*(10-@pet.health)} #{"☺"*(10-@pet.happiness)}#{p.green("☻")*@pet.happiness}")
71
+ render_at(left+1, top+GAME_HEIGHT-2, self.action_bar)
72
+ render_at(left+GAME_WIDTH-2, top, p.bright_white.bold("[x]"))
73
+ end
74
+ end
75
+ end
76
+ end
@@ -1,10 +1,10 @@
1
1
  module Petli
2
- module Rooms
3
- class Dice < Room
2
+ module Stages
3
+ class Dice < Base
4
4
  Symbols = %w(⚀ ⚁ ⚂ ⚃ ⚄ ⚅)
5
5
 
6
- def initialize(pet)
7
- super(pet)
6
+ def initialize(pet:)
7
+ super(pet: pet)
8
8
  @value = rand(1..6)
9
9
  @countdown = -1
10
10
  end
@@ -14,17 +14,17 @@ module Petli
14
14
  end
15
15
 
16
16
  def enter
17
- pet.play(game: :guess)
17
+ @pet.play(game: :guess)
18
18
  end
19
19
 
20
20
  def leave
21
- pet.reset
21
+ @pet.reset
22
22
  end
23
23
 
24
24
  def roll
25
25
  end
26
26
 
27
- def keypress(event)
27
+ def onkey(event)
28
28
  return if event.value != "h" and event.value != "l"
29
29
  @pickedhigher = event.value == "h"
30
30
  @pick = (1..6).to_a.sample
@@ -33,19 +33,19 @@ module Petli
33
33
  @countdown = 20
34
34
  end
35
35
 
36
- def draw(ctx, ox, oy)
37
- ctx.render_at(ox+9, oy+4, @pet.display)
36
+ def draw
37
+ super
38
38
  if @countdown == -1
39
- ctx.render_at(ox+4, oy+6, @value.to_s)
40
- ctx.render_at(ox+23, oy+6, Symbols[(0..5).to_a.sample])
39
+ render_at(left+4, top+6, @value.to_s)
40
+ render_at(left+23, top+6, Symbols[(0..5).to_a.sample])
41
41
  elsif @countdown == 0
42
42
  @won ? @pet.win : @pet.lose
43
- goto("main")
43
+ goto(Main, pet: @pet)
44
44
  else
45
- ctx.render_at(ox+4, oy+5, "▲") if @pickedhigher
46
- ctx.render_at(ox+4, oy+6, @value.to_s)
47
- ctx.render_at(ox+23, oy+6, Symbols[@pick-1])
48
- ctx.render_at(ox+4, oy+7, "▼") unless @pickedhigher
45
+ render_at(left+4, top+5, "▲") if @pickedhigher
46
+ render_at(left+4, top+6, @value.to_s)
47
+ render_at(left+23, top+6, Symbols[@pick-1])
48
+ render_at(left+4, top+7, "▼") unless @pickedhigher
49
49
  @countdown -= 1
50
50
  end
51
51
  end
@@ -1,11 +1,11 @@
1
1
  module Petli
2
- module Rooms
3
- class Feed < Room
2
+ module Stages
3
+ class Feed < Base
4
4
  def actions
5
5
  %w(bread snack med)
6
6
  end
7
7
 
8
- def keypress(event)
8
+ def onkey(event)
9
9
  if event.value == "b"
10
10
  @pet.feed(food: :bread)
11
11
  elsif event.value == "s"
@@ -13,7 +13,7 @@ module Petli
13
13
  elsif event.value == "m"
14
14
  @pet.feed(food: :medicine)
15
15
  end
16
- goto("main")
16
+ goto(Main, pet: @pet)
17
17
  end
18
18
  end
19
19
  end
@@ -0,0 +1,51 @@
1
+ module Petli
2
+ module Stages
3
+ class Guess < Base
4
+ def initialize(pet:)
5
+ super(pet: pet)
6
+ @left = true
7
+ @countdown = -1
8
+ end
9
+
10
+ def actions
11
+ %w(left right)
12
+ end
13
+
14
+ def enter
15
+ pet.play(game: :guess)
16
+ end
17
+
18
+ def leave
19
+ @pet.reset
20
+ end
21
+
22
+ def onkey(event)
23
+ return if event.value != "l" and event.value != "r"
24
+ @petpickedleft = rand(1..2) == 1
25
+ @pickedleft = event.value == "l"
26
+ (@petpickedleft == @pickedleft) ? @pet.celebrate : @pet.embarass
27
+ @countdown = 20
28
+ end
29
+
30
+ def draw
31
+ super
32
+ if @countdown == -1
33
+ render_at(left+4, top+5, "☟") if @left
34
+ render_at(left+23, top+5, "☟") unless @left
35
+ render_at(left+4, top+6, "▒") if @left
36
+ render_at(left+23, top+6, "▒") unless @left
37
+ @left = !@left
38
+ elsif @countdown == 0
39
+ (@petpickedleft == @pickedleft) ? @pet.win : @pet.lose
40
+ goto(Main, pet: @pet)
41
+ else
42
+ render_at(left+4, top+5, "☟") if @pickedleft
43
+ render_at(left+23, top+5, "☟") unless @pickedleft
44
+ render_at(left+4, top+6, "▒") if @petpickedleft
45
+ render_at(left+23, top+6, "▒") unless @petpickedleft
46
+ @countdown -= 1
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,16 +1,16 @@
1
1
  module Petli
2
- module Rooms
3
- class Main < Room
2
+ module Stages
3
+ class Main < Base
4
4
  def actions
5
5
  acts = %w(play feed)
6
6
  acts << "clean" if @pet.poops.count > 0
7
7
  acts
8
8
  end
9
9
 
10
- def keypress(event)
11
- return goto("feed") if event.value == "f"
10
+ def onkey(event)
11
+ return goto(Feed, pet: @pet) if event.value == "f"
12
12
  return @pet.clean if event.value == "c"
13
- return goto("play") if event.value == "p"
13
+ return goto(Play, pet: @pet) if event.value == "p"
14
14
  end
15
15
  end
16
16
  end
@@ -0,0 +1,16 @@
1
+ module Petli
2
+ module Stages
3
+ class Play < Base
4
+ def actions
5
+ %w(guess dice)
6
+ end
7
+
8
+ def onkey(event)
9
+ return goto(Dice, pet: @pet) if event.value == "d"
10
+ return goto(Guess, pet: @pet) if event.value == "g"
11
+ goto(Main, pet: @pet)
12
+ end
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,10 @@
1
+ module Petli
2
+ module Stages
3
+ autoload :Base, "petli/stages/base"
4
+ autoload :Dice, "petli/stages/dice"
5
+ autoload :Feed, "petli/stages/feed"
6
+ autoload :Guess, "petli/stages/guess"
7
+ autoload :Main, "petli/stages/main"
8
+ autoload :Play, "petli/stages/play"
9
+ end
10
+ end
data/lib/petli/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Petli
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/petli.rb CHANGED
@@ -1,10 +1,9 @@
1
1
  module Petli
2
2
  autoload :Animator, "petli/animator"
3
- autoload :DB, "petli/db"
4
3
  autoload :HUD, "petli/hud"
5
4
  autoload :Pet, "petli/pet"
6
5
  autoload :Poop, "petli/poop"
7
- autoload :Rooms, "petli/rooms"
6
+ autoload :Stages, "petli/Stages"
8
7
  autoload :Watch, "petli/watch"
9
8
  autoload :VERSION, "petli/version"
10
9
  end
data/lib/tatty/anim.rb ADDED
@@ -0,0 +1,19 @@
1
+ module Tatty
2
+ class Anim
3
+ def initialize(atlas, frame: 0, rate: 2)
4
+ @atlas = atlas
5
+ @frame = frame
6
+ @rate = rate
7
+ end
8
+
9
+ def step
10
+ @frame += 1
11
+ @frame = 0 if self.frame >= @atlas.count
12
+ @atlas[self.frame]
13
+ end
14
+
15
+ def frame
16
+ (@frame/@rate).ceil
17
+ end
18
+ end
19
+ end
@@ -1,4 +1,4 @@
1
- module Petli
1
+ module Tatty
2
2
  require "pstore"
3
3
  require "forwardable"
4
4
  require "tty-platform"
@@ -18,9 +18,9 @@ module Petli
18
18
 
19
19
  attr_reader :db
20
20
 
21
- def initialize(path: "petli.pet")
22
- config_path = if !$petlidboverride.nil?
23
- $petlidboverride
21
+ def initialize
22
+ config_path = if !$tattydboverridepath.nil?
23
+ $tattydboverridepath
24
24
  elsif TTY::Platform.windows?
25
25
  File.join(ENV["APPDATA"], 'petli', 'data.pet')
26
26
  elsif TTY::Platform.linux?
@@ -75,4 +75,3 @@ module Petli
75
75
  end
76
76
  end
77
77
  end
78
-
@@ -0,0 +1,73 @@
1
+ module Tatty
2
+ require 'tty-cursor'
3
+ require 'tty-screen'
4
+ require 'tty-box'
5
+
6
+ class Stage
7
+ attr_accessor :framerate
8
+
9
+ def initialize
10
+ @cursor = TTY::Cursor
11
+ @framerate = 0.1
12
+ @buffer = ""
13
+ end
14
+
15
+ def leave
16
+ end
17
+
18
+ def goto(klass, **kargs)
19
+ ::Tatty.goto(klass, **kargs)
20
+ end
21
+
22
+ def screen_size
23
+ TTY::Screen.size
24
+ end
25
+
26
+ def screen_width
27
+ TTY::Screen.width
28
+ end
29
+
30
+ def screen_height
31
+ TTY::Screen.height
32
+ end
33
+
34
+ def move_to(x, y)
35
+ render @cursor.move_to(x, y)
36
+ end
37
+
38
+ def render(out)
39
+ @buffer += out
40
+ end
41
+
42
+ def render_at(x, y, out)
43
+ out.to_s.each_line do |line|
44
+ render @cursor.move_to(x, y)
45
+ render line
46
+ y += 1
47
+ end
48
+ end
49
+
50
+ def draw
51
+ render "not implemented"
52
+ end
53
+
54
+ def step
55
+ last_buffer = @buffer
56
+ @buffer = ""
57
+ render @cursor.clear_screen
58
+ move_to(0, 0)
59
+ self.draw
60
+ if last_buffer != @buffer
61
+ print @buffer
62
+ end
63
+ sleep(@framerate)
64
+ end
65
+
66
+ def render_box(*content, **kwargs, &block)
67
+ render @cursor.save
68
+ move_to(0, 0)
69
+ render TTY::Box.frame(*content, **kwargs, &block)
70
+ render @cursor.restore
71
+ end
72
+ end
73
+ end
data/lib/tatty.rb ADDED
@@ -0,0 +1,38 @@
1
+ module Tatty
2
+ require 'tty-reader'
3
+ require 'tty-cursor'
4
+
5
+ autoload :Anim, "tatty/anim"
6
+ autoload :DB, "tatty/db"
7
+ autoload :Stage, "tatty/stage"
8
+
9
+ def self.run(klass, **kargs)
10
+ self.goto(klass, **kargs)
11
+ @reader = TTY::Reader.new
12
+ @reader.on(:keypress) do |event|
13
+ self.stage.keypress(event)
14
+ end
15
+
16
+ begin
17
+ TTY::Cursor.invisible do
18
+ while true
19
+ @reader.read_keypress(nonblock: true)
20
+ @stage.step
21
+ end
22
+ end
23
+ rescue Interrupt => e
24
+ ensure
25
+ print TTY::Cursor.clear_screen
26
+ print TTY::Cursor.move_to(0, 0)
27
+ end
28
+ end
29
+
30
+ def self.stage
31
+ @stage
32
+ end
33
+
34
+ def self.goto(klass, **kargs)
35
+ @stage.leave unless @stage.nil?
36
+ @stage = klass.new(**kargs)
37
+ end
38
+ end
data/petli.gemspec CHANGED
@@ -33,7 +33,6 @@ Gem::Specification.new do |s|
33
33
 
34
34
  s.add_dependency("pastel", "~> 0.8.0")
35
35
  s.add_dependency("tty-cursor", "~> 0.7.1")
36
- s.add_dependency("tty-config", "~> 0.5.0")
37
36
  s.add_dependency("tty-screen", "~> 0.8.1")
38
37
  s.add_dependency("tty-reader", "~> 0.9.0")
39
38
  s.add_dependency("tty-color", "~> 0.6.0")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: petli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Anema
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-27 00:00:00.000000000 Z
11
+ date: 2021-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pastel
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.7.1
41
- - !ruby/object:Gem::Dependency
42
- name: tty-config
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: 0.5.0
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: 0.5.0
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: tty-screen
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -124,7 +110,7 @@ dependencies:
124
110
  version: 0.3.0
125
111
  description: 'A virtual pet that will live in your command line!
126
112
 
127
- '
113
+ '
128
114
  email:
129
115
  - timanema@gmail.com
130
116
  executables:
@@ -143,19 +129,21 @@ files:
143
129
  - data/face_ref
144
130
  - lib/petli.rb
145
131
  - lib/petli/animator.rb
146
- - lib/petli/db.rb
147
- - lib/petli/hud.rb
148
132
  - lib/petli/pet.rb
149
133
  - lib/petli/poop.rb
150
- - lib/petli/rooms.rb
151
- - lib/petli/rooms/dice.rb
152
- - lib/petli/rooms/feed.rb
153
- - lib/petli/rooms/guess.rb
154
- - lib/petli/rooms/main.rb
155
- - lib/petli/rooms/play.rb
134
+ - lib/petli/stages.rb
135
+ - lib/petli/stages/base.rb
136
+ - lib/petli/stages/dice.rb
137
+ - lib/petli/stages/feed.rb
138
+ - lib/petli/stages/guess.rb
139
+ - lib/petli/stages/main.rb
140
+ - lib/petli/stages/play.rb
156
141
  - lib/petli/version.rb
157
142
  - lib/petli/watch.rb
158
- - lib/tatty/game.rb
143
+ - lib/tatty.rb
144
+ - lib/tatty/anim.rb
145
+ - lib/tatty/db.rb
146
+ - lib/tatty/stage.rb
159
147
  - petli.gemspec
160
148
  homepage: https://github.com/tanema/petli
161
149
  licenses:
@@ -182,9 +170,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
170
  - !ruby/object:Gem::Version
183
171
  version: '0'
184
172
  requirements: []
185
- rubygems_version: 3.2.3
186
- signing_key:
173
+ rubygems_version: 3.0.3
174
+ signing_key:
187
175
  specification_version: 4
188
176
  summary: A little pet in your console
189
177
  test_files: []
190
- ...
data/lib/petli/hud.rb DELETED
@@ -1,44 +0,0 @@
1
- require_relative '../tatty/game'
2
- require 'pastel'
3
-
4
- module Petli
5
- class HUD < Tatty::Game
6
- GAME_WIDTH = 28
7
- GAME_HEIGHT = 13
8
-
9
- def initialize
10
- super()
11
- @pet = Pet.new
12
- Rooms.enter(@pet)
13
- end
14
-
15
- def keypress(event)
16
- exit if event.value == "q"
17
- return if @pet.busy? || @pet.dead?
18
- Rooms.current.keypress(event)
19
- end
20
-
21
- def draw
22
- h, w = self.screen_size
23
- left, top = ((w-GAME_WIDTH)/2).round, ((h-GAME_HEIGHT)/2).round
24
- render_box(
25
- title: {
26
- top_left: Pastel.new.bright_white.bold(" Petli "),
27
- bottom_right: Pastel.new.green(" #{@pet.lifetime} days "),
28
- },
29
- width: GAME_WIDTH,
30
- height: GAME_HEIGHT,
31
- left: left,
32
- top: top,
33
- )
34
- Rooms.current.draw(self, left, top)
35
- render_at(left+1, top+1, status_bar)
36
- render_at(left+1, top+GAME_HEIGHT-2, Rooms.current.action_bar)
37
- end
38
-
39
- def status_bar
40
- p = Pastel.new
41
- "#{p.red("♥")*@pet.health}#{"♡"*(10-@pet.health)} #{"☺"*(10-@pet.happiness)}#{p.green("☻")*@pet.happiness}"
42
- end
43
- end
44
- end
@@ -1,51 +0,0 @@
1
- module Petli
2
- module Rooms
3
- class Guess < Room
4
- def initialize(pet)
5
- super(pet)
6
- @left = true
7
- @countdown = -1
8
- end
9
-
10
- def actions
11
- %w(left right)
12
- end
13
-
14
- def enter
15
- pet.play(game: :guess)
16
- end
17
-
18
- def leave
19
- pet.reset
20
- end
21
-
22
- def keypress(event)
23
- return if event.value != "l" and event.value != "r"
24
- @petpickedleft = rand(1..2) == 1
25
- @pickedleft = event.value == "l"
26
- (@petpickedleft == @pickedleft) ? @pet.celebrate : @pet.embarass
27
- @countdown = 20
28
- end
29
-
30
- def draw(ctx, ox, oy)
31
- ctx.render_at(ox+9, oy+4, @pet.display)
32
- if @countdown == -1
33
- ctx.render_at(ox+4, oy+5, "☟") if @left
34
- ctx.render_at(ox+23, oy+5, "☟") unless @left
35
- ctx.render_at(ox+4, oy+6, "▒") if @left
36
- ctx.render_at(ox+23, oy+6, "▒") unless @left
37
- @left = !@left
38
- elsif @countdown == 0
39
- (@petpickedleft == @pickedleft) ? @pet.win : @pet.lose
40
- goto("main")
41
- else
42
- ctx.render_at(ox+4, oy+5, "☟") if @pickedleft
43
- ctx.render_at(ox+23, oy+5, "☟") unless @pickedleft
44
- ctx.render_at(ox+4, oy+6, "▒") if @petpickedleft
45
- ctx.render_at(ox+23, oy+6, "▒") unless @petpickedleft
46
- @countdown -= 1
47
- end
48
- end
49
- end
50
- end
51
- end
@@ -1,16 +0,0 @@
1
- module Petli
2
- module Rooms
3
- class Play < Room
4
- def actions
5
- %w(guess dice)
6
- end
7
-
8
- def keypress(event)
9
- return goto("dice") if event.value == "d"
10
- return goto("guess") if event.value == "g"
11
- goto("main")
12
- end
13
- end
14
- end
15
- end
16
-
data/lib/petli/rooms.rb DELETED
@@ -1,73 +0,0 @@
1
- module Petli
2
- module Rooms
3
- class Room
4
- attr_reader :pet
5
-
6
- def initialize(pet)
7
- @pet = pet
8
- end
9
-
10
- def enter
11
- end
12
-
13
- def goto(room_name)
14
- klass = ::Petli.const_get("Rooms::#{room_name.capitalize}")
15
- self.leave unless klass.nil?
16
- ::Petli::Rooms.goto(klass)
17
- end
18
-
19
- def leave
20
- end
21
-
22
- def actions
23
- %w()
24
- end
25
-
26
- def action_bar
27
- return "" if @pet.dead?
28
- p = Pastel.new
29
- self.actions.map do |a|
30
- key = p.bold("[#{a[0].capitalize}]")
31
- "#{key}#{a[1..]}"
32
- end.join(" ")
33
- end
34
-
35
- def keypress(event)
36
- end
37
-
38
- def draw(ctx, ox, oy)
39
- poops = @pet.poops
40
- poops.each_with_index do |poop, i|
41
- x, y = Poop::LOCATIONS[i]
42
- ctx.render_at(ox+1+x, oy+1+y, poop.step)
43
- end
44
- @pet.poops = poops
45
- ctx.render_at(ox+9, oy+4, @pet.display)
46
- sick = @pet.sick
47
- if sick > 0 && !@pet.dead?
48
- ctx.render_at(ox+11-sick, oy+4, "[#{'!'*sick}SICK#{'!'*sick}]")
49
- end
50
- end
51
- end
52
-
53
- autoload :Main, "petli/rooms/main"
54
- autoload :Feed, "petli/rooms/feed"
55
- autoload :Play, "petli/rooms/play"
56
- autoload :Guess, "petli/rooms/guess"
57
- autoload :Dice, "petli/rooms/dice"
58
-
59
- def self.current
60
- @room
61
- end
62
-
63
- def self.enter(pet)
64
- @pet = pet
65
- goto(Main)
66
- end
67
-
68
- def self.goto(klass)
69
- @room = klass.new(@pet)
70
- @room.enter
71
- end
72
- end
73
- end
data/lib/tatty/game.rb DELETED
@@ -1,80 +0,0 @@
1
- module Tatty
2
- require 'tty-cursor'
3
- require 'tty-config'
4
- require 'tty-screen'
5
- require 'tty-reader'
6
- require 'tty-box'
7
-
8
- class Game
9
- attr_accessor :framerate, :config
10
-
11
- def initialize
12
- @config = TTY::Config.new
13
- @cursor = TTY::Cursor
14
- @reader = TTY::Reader.new
15
- @framerate = 0.1
16
- @buffer = ""
17
-
18
- @reader.on(:keypress) do |event|
19
- self.keypress(event)
20
- end
21
- end
22
-
23
- def screen_size
24
- TTY::Screen.size
25
- end
26
-
27
- def move_to(x, y)
28
- render @cursor.move_to(x, y)
29
- end
30
-
31
- def render(out)
32
- @buffer += out
33
- end
34
-
35
- def render_at(x, y, out)
36
- out.to_s.each_line do |line|
37
- render @cursor.move_to(x, y)
38
- render line
39
- y += 1
40
- end
41
- end
42
-
43
- def keypress(event)
44
- end
45
-
46
- def draw
47
- render "not implemented"
48
- end
49
-
50
- def run
51
- begin
52
- @cursor.invisible do
53
- while true
54
- @reader.read_keypress(nonblock: true)
55
- last_buffer = @buffer
56
- @buffer = ""
57
- render @cursor.clear_screen
58
- move_to(0, 0)
59
- self.draw
60
- if last_buffer != @buffer
61
- print @buffer
62
- end
63
- sleep(@framerate)
64
- end
65
- end
66
- rescue Interrupt => e
67
- ensure
68
- print @cursor.clear_screen
69
- print @cursor.move_to(0, 0)
70
- end
71
- end
72
-
73
- def render_box(*content, **kwargs, &block)
74
- render @cursor.save
75
- move_to(0, 0)
76
- render TTY::Box.frame(*content, **kwargs, &block)
77
- render @cursor.restore
78
- end
79
- end
80
- end