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 +4 -4
- data/Gemfile.lock +3 -4
- data/README.md +10 -10
- data/bin/petli +5 -4
- data/lib/petli/animator.rb +8 -8
- data/lib/petli/pet.rb +6 -8
- data/lib/petli/poop.rb +3 -20
- data/lib/petli/stages/base.rb +76 -0
- data/lib/petli/{rooms → stages}/dice.rb +16 -16
- data/lib/petli/{rooms → stages}/feed.rb +4 -4
- data/lib/petli/stages/guess.rb +51 -0
- data/lib/petli/{rooms → stages}/main.rb +5 -5
- data/lib/petli/stages/play.rb +16 -0
- data/lib/petli/stages.rb +10 -0
- data/lib/petli/version.rb +1 -1
- data/lib/petli.rb +1 -2
- data/lib/tatty/anim.rb +19 -0
- data/lib/{petli → tatty}/db.rb +4 -5
- data/lib/tatty/stage.rb +73 -0
- data/lib/tatty.rb +38 -0
- data/petli.gemspec +0 -1
- metadata +17 -30
- data/lib/petli/hud.rb +0 -44
- data/lib/petli/rooms/guess.rb +0 -51
- data/lib/petli/rooms/play.rb +0 -16
- data/lib/petli/rooms.rb +0 -73
- data/lib/tatty/game.rb +0 -80
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9a8fbb01c6f383d9993c120cb0fd4d2305c82314baf400f4b74bfbee7c1cc81
|
4
|
+
data.tar.gz: 9dff8e3e65d3e93942c4a1fc8589206b740c26e1ac2bb385bf3132a249deb49d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
$
|
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
|
-
|
24
|
+
Tatty::DB.clear
|
24
25
|
puts "Goodbye. I hope you love your next pet!"
|
25
26
|
elsif options[:status]
|
26
|
-
puts
|
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::
|
37
|
+
Tatty.run(Petli::Stages::Main, pet: pet)
|
37
38
|
end
|
data/lib/petli/animator.rb
CHANGED
@@ -33,16 +33,16 @@ module Petli
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def step
|
36
|
-
|
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 =
|
43
|
+
food_peices = food.split('')
|
44
44
|
|
45
|
-
ANIMATIONS[
|
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[
|
96
|
+
frame_count = ANIMATIONS[action].count
|
97
97
|
@frame += 1
|
98
|
-
if
|
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
|
-
|
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 =
|
120
|
-
part_frame =
|
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.
|
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
|
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
|
-
|
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
|
3
|
-
class Dice <
|
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
|
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
|
37
|
-
|
36
|
+
def draw
|
37
|
+
super
|
38
38
|
if @countdown == -1
|
39
|
-
|
40
|
-
|
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(
|
43
|
+
goto(Main, pet: @pet)
|
44
44
|
else
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
3
|
-
class Feed <
|
2
|
+
module Stages
|
3
|
+
class Feed < Base
|
4
4
|
def actions
|
5
5
|
%w(bread snack med)
|
6
6
|
end
|
7
7
|
|
8
|
-
def
|
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(
|
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
|
3
|
-
class Main <
|
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
|
11
|
-
return goto(
|
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(
|
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
|
+
|
data/lib/petli/stages.rb
ADDED
@@ -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
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 :
|
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
|
data/lib/{petli → tatty}/db.rb
RENAMED
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
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
|
22
|
-
config_path = if !$
|
23
|
-
$
|
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
|
-
|
data/lib/tatty/stage.rb
ADDED
@@ -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.
|
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-
|
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/
|
151
|
-
- lib/petli/
|
152
|
-
- lib/petli/
|
153
|
-
- lib/petli/
|
154
|
-
- lib/petli/
|
155
|
-
- lib/petli/
|
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
|
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.
|
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
|
data/lib/petli/rooms/guess.rb
DELETED
@@ -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
|
data/lib/petli/rooms/play.rb
DELETED
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
|