petli 0.0.2 → 0.0.3

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