hlockey 4 → 6
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 +4 -4
- data/data/election.json +20 -0
- data/data/information.json +5 -0
- data/data/league.json +1984 -0
- data/data/links.json +5 -0
- data/data/previous_election_results.json +98 -0
- data/lib/hlockey/actions.rb +22 -0
- data/lib/hlockey/constants.rb +6 -0
- data/lib/hlockey/data.rb +6 -5
- data/lib/hlockey/game/fight.rb +35 -20
- data/lib/hlockey/game/weather/audacity.rb +20 -0
- data/lib/hlockey/game/weather/chicken.rb +57 -0
- data/lib/hlockey/game/weather/incline.rb +43 -0
- data/lib/hlockey/game/weather/stars.rb +23 -0
- data/lib/hlockey/game/weather/sunset.rb +23 -0
- data/lib/hlockey/game/weather/waves.rb +33 -0
- data/lib/hlockey/game/weather/weatherable.rb +63 -0
- data/lib/hlockey/game/weather.rb +17 -0
- data/lib/hlockey/game.rb +123 -89
- data/lib/hlockey/league.rb +68 -76
- data/lib/hlockey/message.rb +62 -62
- data/lib/hlockey/mod/fencebuilder.rb +16 -0
- data/lib/hlockey/mod/fencedestroyer.rb +16 -0
- data/lib/hlockey/mod/handholding.rb +55 -0
- data/lib/hlockey/mod/immaterial.rb +26 -0
- data/lib/hlockey/mod/locked.rb +22 -0
- data/lib/hlockey/mod/moddable.rb +49 -0
- data/lib/hlockey/mod/nonconfrontational.rb +17 -0
- data/lib/hlockey/mod/powernapper.rb +46 -0
- data/lib/hlockey/mod/punchy.rb +17 -0
- data/lib/hlockey/mod.rb +25 -0
- data/lib/hlockey/selfdescribable.rb +9 -0
- data/lib/hlockey/team/player.rb +58 -0
- data/lib/hlockey/team/stadium.rb +52 -0
- data/lib/hlockey/team.rb +66 -25
- data/lib/hlockey/utils.rb +10 -2
- data/lib/hlockey/version.rb +1 -1
- metadata +37 -19
- data/data/election.yaml +0 -21
- data/data/external/names.txt +0 -19948
- data/data/information.yaml +0 -24
- data/data/league.yaml +0 -1526
- data/data/links.yaml +0 -3
- data/data/previous_election_results.yaml +0 -59
- data/lib/hlockey/game/actions.rb +0 -27
- data/lib/hlockey/player.rb +0 -73
- data/lib/hlockey/weather.rb +0 -168
data/lib/hlockey/message.rb
CHANGED
@@ -22,21 +22,23 @@ module Hlockey
|
|
22
22
|
end
|
23
23
|
|
24
24
|
class << self
|
25
|
-
# Variable
|
25
|
+
# Variable controlling how coloring players/teams is done
|
26
|
+
# Set this to a Proc that takes params `color` and `string`,
|
27
|
+
# and returns the colorized string.
|
28
|
+
# `color` will be in hex format, for example "#ffffff"
|
26
29
|
# The default is to not color things at all
|
27
|
-
|
28
30
|
attr_writer(:colorize)
|
29
31
|
|
30
|
-
#
|
32
|
+
# Colors Team/associated classes in their team color
|
33
|
+
# To control how this colors things, see #colorize=
|
34
|
+
# @param obj [Team, Team::Player, Team::Stadium]
|
31
35
|
# @return String
|
32
|
-
def color(obj)
|
33
|
-
|
34
|
-
|
35
|
-
@colorize.call(col, obj.to_s)
|
36
|
-
end
|
36
|
+
def color(obj) =
|
37
|
+
@colorize.call(obj.instance_of?(Team) ? obj.color : obj.team.color, obj.to_s)
|
37
38
|
|
38
|
-
# These are messages logged to game streams
|
39
|
+
# These are messages logged to game streams / league alerts
|
39
40
|
[
|
41
|
+
# Game stream messages
|
40
42
|
%i[StartOfGame],
|
41
43
|
%i[EndOfGame winning_team],
|
42
44
|
%i[StartOfPeriod period],
|
@@ -49,93 +51,96 @@ module Hlockey
|
|
49
51
|
%i[Partying player],
|
50
52
|
%i[FightStarted home_player away_player],
|
51
53
|
%i[FightAttack attacking_player defending_player blocked],
|
52
|
-
%i[PlayerJoinedFight
|
54
|
+
%i[PlayerJoinedFight player],
|
53
55
|
%i[FightEnded],
|
54
56
|
%i[MoraleChange team amount],
|
55
57
|
%i[ChickenedOut prev_player next_player],
|
56
58
|
%i[InclineFavors team],
|
57
59
|
%i[StarsAlign team],
|
58
|
-
%i[WavesWashedAway prev_player next_player]
|
60
|
+
%i[WavesWashedAway prev_player next_player],
|
61
|
+
%i[ImmaterialDodge player hitting_player],
|
62
|
+
# League alert messages
|
63
|
+
%i[SeasonChampion team]
|
59
64
|
].each do |event, *fields|
|
60
65
|
define_method(event) { |*data| new(event, fields, data) }
|
61
66
|
end
|
62
67
|
|
63
68
|
# These are messages used elsewhere
|
64
69
|
|
65
|
-
def SeasonDay(day)
|
66
|
-
"Season #{VERSION} day #{day}"
|
67
|
-
end
|
70
|
+
def SeasonDay(day) = "Season #{VERSION} day #{day}"
|
68
71
|
|
69
|
-
def SeasonStarts(time)
|
72
|
+
def SeasonStarts(time) =
|
70
73
|
time.strftime("Season #{VERSION} starts at %H:%M, %A, %B %d (%Z).")
|
71
|
-
end
|
72
|
-
|
73
|
-
def SeasonChampion(team)
|
74
|
-
"Your season #{VERSION} champions are the #{team}!"
|
75
|
-
end
|
76
74
|
|
77
|
-
def NoGames
|
75
|
+
def NoGames =
|
78
76
|
"no games right now. it is the offseason. join the Hlockey Discord for updates"
|
79
|
-
end
|
80
77
|
end
|
81
78
|
|
82
|
-
def to_s
|
79
|
+
def to_s(do_color: true)
|
80
|
+
c = -> { color(_1, do_color:) }
|
81
|
+
|
83
82
|
case @event
|
84
83
|
when :StartOfGame
|
85
84
|
"Hocky!"
|
86
85
|
when :EndOfGame
|
87
|
-
"Game over.\n#{
|
86
|
+
"Game over.\n#{c.call(@winning_team)} win!"
|
88
87
|
when :StartOfPeriod
|
89
88
|
"Start#{of_period}"
|
90
89
|
when :EndOfPeriod
|
91
|
-
"End#{of_period}#{score}"
|
90
|
+
"End#{of_period}#{score(do_color:)}"
|
92
91
|
when :FaceOff
|
93
|
-
"#{
|
92
|
+
"#{c.call(@winning_player)} wins the faceoff!#{possession_change(do_color:)}"
|
94
93
|
when :Hit
|
95
|
-
str = "#{
|
96
|
-
str += takes + score_chance if @puck_taken
|
94
|
+
str = "#{c.call(@defender)} hits #{c.call(@puck_holder)}"
|
95
|
+
str += takes(do_color:) + score_chance if @puck_taken
|
97
96
|
str
|
98
97
|
when :Pass
|
99
|
-
str = "#{
|
98
|
+
str = "#{c.call(@sender)} passes to #{c.call(@receiver)}."
|
100
99
|
unless @interceptor.nil?
|
101
|
-
str += "..\nIntercepted by #{
|
100
|
+
str += "..\nIntercepted by #{c.call(@interceptor)}!" +
|
101
|
+
possession_change(do_color:)
|
102
102
|
end
|
103
103
|
str += score_chance
|
104
104
|
str
|
105
105
|
when :ShootScore
|
106
|
-
"#{shot} and scores!#{score}"
|
106
|
+
"#{shot(do_color:)} and scores!#{score(do_color:)}"
|
107
107
|
when :ShootBlock
|
108
|
-
"#{shot}...\n#{
|
108
|
+
"#{shot(do_color:)}...\n#{c.call(@blocker)} blocks the shot" +
|
109
|
+
takes(do_color:) + score_chance
|
109
110
|
when :Partying
|
110
|
-
"#{
|
111
|
+
"#{c.call(@player)} is partying!"
|
111
112
|
when :FightStarted
|
112
|
-
"#{
|
113
|
+
"#{c.call(@home_player)} and #{c.call(@away_player)} " \
|
114
|
+
"start fighting!"
|
113
115
|
when :FightAttack
|
114
|
-
|
115
|
-
str
|
116
|
+
def_player = c.call(@defending_player)
|
117
|
+
str = "#{c.call(@attacking_player)} punches #{def_player}!"
|
118
|
+
str += "\n#{def_player} blocks the punch!" if @blocked
|
116
119
|
str
|
117
120
|
when :PlayerJoinedFight
|
118
|
-
"#{
|
121
|
+
"#{c.call(@player)} from #{c.call(@player.team)} joins the fight!"
|
119
122
|
when :FightEnded
|
120
123
|
"The fight has ended."
|
121
124
|
when :MoraleChange
|
122
|
-
"#{
|
125
|
+
"#{c.call(@team)} #{@amount.negative? ? "loses" : "gains"} #{@amount.abs} morale."
|
123
126
|
when :ChickenedOut
|
124
|
-
"#{
|
127
|
+
"#{c.call(@prev_player)} chickened out!#{replaces("game", do_color:)}"
|
125
128
|
when :InclineFavors
|
126
|
-
"The incline favors #{
|
129
|
+
"The incline favors #{c.call(@team)}."
|
127
130
|
when :StarsAlign
|
128
|
-
"The stars align for #{
|
131
|
+
"The stars align for #{c.call(@team)}. They get half a goal."
|
129
132
|
when :WavesWashedAway
|
130
|
-
"#{
|
133
|
+
"#{c.call(@prev_player)} is washed away by the waves...#{replaces(do_color:)}"
|
134
|
+
when :ImmaterialDodge
|
135
|
+
"#{c.call(@hitting_player)} goes right through #{c.call(@player)}!"
|
136
|
+
when :SeasonChampion
|
137
|
+
"Your season #{VERSION} champions are the #{c.call(@team)}!"
|
131
138
|
end
|
132
139
|
end
|
133
140
|
|
134
141
|
private
|
135
142
|
|
136
|
-
def color(obj)
|
137
|
-
self.class.color(obj)
|
138
|
-
end
|
143
|
+
def color(obj, do_color: true) = do_color ? self.class.color(obj) : obj.to_s
|
139
144
|
|
140
145
|
def score_chance
|
141
146
|
return "" if @shooting_chance.nil?
|
@@ -153,28 +158,23 @@ module Hlockey
|
|
153
158
|
"\nChance of scoring: #{chance_str} (#{@shooting_chance})"
|
154
159
|
end
|
155
160
|
|
156
|
-
def of_period
|
157
|
-
" of period #{@period}."
|
158
|
-
end
|
161
|
+
def of_period = " of period #{@period}."
|
159
162
|
|
160
|
-
def score
|
161
|
-
"\n#{color(@home)} #{@home_score.round(2)},
|
162
|
-
|
163
|
+
def score(do_color: true) =
|
164
|
+
"\n#{color(@home, do_color:)} #{@home_score.round(2)}, " \
|
165
|
+
"#{color(@away, do_color:)} #{@away_score.round(2)}"
|
163
166
|
|
164
|
-
def shot
|
165
|
-
"#{color(@shooter)} takes a#{"n audacious" if @audacity} shot"
|
166
|
-
end
|
167
|
+
def shot(do_color: true) =
|
168
|
+
"#{color(@shooter, do_color:)} takes a#{"n audacious" if @audacity} shot"
|
167
169
|
|
168
|
-
def takes
|
169
|
-
@puck_taken ? " and takes the puck!#{possession_change}" : "!"
|
170
|
-
end
|
170
|
+
def takes(do_color: true) =
|
171
|
+
@puck_taken ? " and takes the puck!#{possession_change(do_color:)}" : "!"
|
171
172
|
|
172
|
-
def possession_change
|
173
|
-
"\n#{color(@new_puck_team)} have possession."
|
174
|
-
end
|
173
|
+
def possession_change(do_color: true) =
|
174
|
+
"\n#{color(@new_puck_team, do_color:)} have possession."
|
175
175
|
|
176
|
-
def replaces(period = nil)
|
177
|
-
str = "\n#{color(@next_player)} replaces them"
|
176
|
+
def replaces(period = nil, do_color: true)
|
177
|
+
str = "\n#{color(@next_player, do_color:)} replaces them"
|
178
178
|
str += " for the rest of the #{period}." unless period.nil?
|
179
179
|
str
|
180
180
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require("hlockey/mod/moddable")
|
2
|
+
|
3
|
+
module Hlockey
|
4
|
+
module Mod
|
5
|
+
##
|
6
|
+
# The player this mod is applied to only gets swapped into offense
|
7
|
+
class Fencebuilder
|
8
|
+
include(Moddable)
|
9
|
+
|
10
|
+
DESCRIPTION = "This player can only play offense.".freeze
|
11
|
+
|
12
|
+
def on_swap(into_roster, pos, prev_pos, _prng) =
|
13
|
+
fence_swap(into_roster, pos, prev_pos)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require("hlockey/mod/moddable")
|
2
|
+
|
3
|
+
module Hlockey
|
4
|
+
module Mod
|
5
|
+
##
|
6
|
+
# The player this mod is applied to only gets swapped into defense
|
7
|
+
class Fencedestroyer
|
8
|
+
include(Moddable)
|
9
|
+
|
10
|
+
DESCRIPTION = "This player can only play defense.".freeze
|
11
|
+
|
12
|
+
def on_swap(into_roster, pos, prev_pos, _prng) =
|
13
|
+
fence_swap(into_roster, pos, prev_pos, type: :destroyer)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require("hlockey/mod/moddable")
|
2
|
+
|
3
|
+
module Hlockey
|
4
|
+
module Mod
|
5
|
+
##
|
6
|
+
# Specified player follows the player this mod is applied to
|
7
|
+
# when they are swapped in/out
|
8
|
+
class Handholding
|
9
|
+
include(Moddable)
|
10
|
+
|
11
|
+
DESCRIPTION = "This player is holding another player's hand.".freeze
|
12
|
+
|
13
|
+
# @param other_player [String] name of other player
|
14
|
+
def initialize(player, other_player)
|
15
|
+
super(player)
|
16
|
+
@other_player = other_player
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_data = [to_s, @other_player.to_s]
|
20
|
+
|
21
|
+
def on_swap(into_roster, pos, _prev_pos, prng)
|
22
|
+
unless @other_player.is_a?(Team::Player)
|
23
|
+
@other_player = @team.players.find { _1.name == @other_player }
|
24
|
+
end
|
25
|
+
|
26
|
+
if into_roster
|
27
|
+
prev_pos = @team.shadows.index(@other_player)
|
28
|
+
return if prev_pos.nil?
|
29
|
+
|
30
|
+
other_pos = with_deleted(@team.roster.keys, pos).sample(random: prng)
|
31
|
+
|
32
|
+
@team.shadows[prev_pos] = @team.roster[other_pos]
|
33
|
+
@team.roster[other_pos] = @other_player
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
prev_pos = @team.roster.key(@other_player)
|
38
|
+
return if prev_pos.nil?
|
39
|
+
|
40
|
+
other_pos = with_deleted(@team.shadows.each_index.to_a, pos).sample(random: prng)
|
41
|
+
|
42
|
+
@team.roster[prev_pos] = @team.shadows[other_pos]
|
43
|
+
@team.shadows[other_pos] = @other_player
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# For `on_swap`, because array.delete doesn't return the array for no reason
|
49
|
+
def with_deleted(array, object)
|
50
|
+
array.delete(object)
|
51
|
+
array
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require("hlockey/message")
|
2
|
+
require("hlockey/mod/moddable")
|
3
|
+
|
4
|
+
module Hlockey
|
5
|
+
module Mod
|
6
|
+
##
|
7
|
+
# The player this mod is applied to has a chance of avoiding hits
|
8
|
+
# by temporarily losing their physical form
|
9
|
+
class Immaterial
|
10
|
+
include(Moddable)
|
11
|
+
|
12
|
+
DESCRIPTION = "This player may be a hallucination.".freeze
|
13
|
+
|
14
|
+
def on_got_hit(game, hitting_player)
|
15
|
+
return if game.prng.rand(3).zero?
|
16
|
+
|
17
|
+
if game.pre_tmp_change_stats[@player].nil?
|
18
|
+
game.pre_tmp_change_stats[@player] = @player.stats.clone
|
19
|
+
end
|
20
|
+
@player.stats[:defense] += 0.5
|
21
|
+
|
22
|
+
Message.ImmaterialDodge(@player, hitting_player)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require("hlockey/mod/moddable")
|
2
|
+
|
3
|
+
module Hlockey
|
4
|
+
module Mod
|
5
|
+
##
|
6
|
+
# This player can not swap positions.
|
7
|
+
class Locked
|
8
|
+
include(Moddable)
|
9
|
+
|
10
|
+
DESCRIPTION = "This player can not swap positions.".freeze
|
11
|
+
|
12
|
+
def on_swap(into_roster, pos, prev_pos, _prng) =
|
13
|
+
if into_roster
|
14
|
+
@team.roster[pos] = @team.shadows[prev_pos]
|
15
|
+
@team.shadows[prev_pos] = @player
|
16
|
+
else
|
17
|
+
@team.shadows[pos] = @team.roster[prev_pos]
|
18
|
+
@team.roster[prev_pos] = @player
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require("hlockey/selfdescribable")
|
2
|
+
|
3
|
+
module Hlockey
|
4
|
+
module Mod
|
5
|
+
##
|
6
|
+
# Module with needed methods for mods, that every mod includes
|
7
|
+
# All methods starting with "on" represent player events
|
8
|
+
module Moddable
|
9
|
+
include(SelfDescribable)
|
10
|
+
|
11
|
+
DESCRIPTION = "A mod with no description.".freeze # Default description
|
12
|
+
|
13
|
+
# If the mod has no extra parameters, same as #to_s
|
14
|
+
# If it has extra parameters, returns an array with #to_s as the first element,
|
15
|
+
# and the other parameters as the rest of the elements.
|
16
|
+
# Mods that accept parameters should implement the array version themselves,
|
17
|
+
# as in the module here it is simply an alias.
|
18
|
+
alias to_data to_s
|
19
|
+
|
20
|
+
def initialize(player)
|
21
|
+
@player = player
|
22
|
+
@team = player.team
|
23
|
+
end
|
24
|
+
|
25
|
+
def on_swap(into_roster, pos, prev_pos, prng) end
|
26
|
+
|
27
|
+
def on_action(game) end
|
28
|
+
|
29
|
+
def on_got_hit(game, hitting_player) end
|
30
|
+
|
31
|
+
def on_join_fight() end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def fence_swap(into_roster, pos, prev_pos, type: :builder)
|
36
|
+
return unless into_roster
|
37
|
+
|
38
|
+
new_pos_hash = { ldef: :lwing, goalie: :center, rdef: :rwing }
|
39
|
+
new_pos_hash = new_pos_hash.invert unless type == :builder
|
40
|
+
new_pos = new_pos_hash[pos]
|
41
|
+
return if new_pos.nil?
|
42
|
+
|
43
|
+
@team.roster[pos] = @team.shadows[prev_pos]
|
44
|
+
@team.shadows[prev_pos] = @team.roster[new_pos]
|
45
|
+
@team.roster[new_pos] = @player
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require("hlockey/mod/moddable")
|
2
|
+
|
3
|
+
module Hlockey
|
4
|
+
module Mod
|
5
|
+
##
|
6
|
+
# The first player in the shadows will join fights instead of this player,
|
7
|
+
# if they do not also have the mod.
|
8
|
+
class Nonconfrontational
|
9
|
+
include(Moddable)
|
10
|
+
|
11
|
+
DESCRIPTION = "This player tries to avoid fights.".freeze
|
12
|
+
|
13
|
+
def on_join_fight =
|
14
|
+
@team.shadows.select { |player| player.mods.none? { _1.is_a?(self.class) } }.first
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require("hlockey/mod/moddable")
|
2
|
+
require("hlockey/actions")
|
3
|
+
|
4
|
+
module Hlockey
|
5
|
+
module Mod
|
6
|
+
##
|
7
|
+
# Player has James stats added to their own at random
|
8
|
+
class Powernapper
|
9
|
+
include(Moddable)
|
10
|
+
include(Actions)
|
11
|
+
|
12
|
+
DESCRIPTION = "This player gets temporary stat boosts by powernapping.".freeze
|
13
|
+
|
14
|
+
def initialize(player)
|
15
|
+
super
|
16
|
+
@currently_boosted_for = -1
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_action(game)
|
20
|
+
if @currently_boosted_for.negative?
|
21
|
+
return unless random_event_occurs?(prng: game.prng)
|
22
|
+
|
23
|
+
change_stats(game)
|
24
|
+
end
|
25
|
+
@currently_boosted_for += 1
|
26
|
+
return if @currently_boosted_for < 5
|
27
|
+
|
28
|
+
change_stats(game, reset: true)
|
29
|
+
@currently_boosted_for = -1
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def change_stats(game, reset: false)
|
35
|
+
stat_change = { offense: 0.5, defense: 1.0 } # James stats (excluding 0 agility)
|
36
|
+
stat_change.transform_values!(&:-@) if reset
|
37
|
+
|
38
|
+
pre_tmp_change_stats = game.pre_tmp_change_stats[@player]
|
39
|
+
stat_change.each do |stat, change|
|
40
|
+
@player.stats[stat] += change
|
41
|
+
pre_tmp_change_stats[stat] += change unless pre_tmp_change_stats.nil?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require("hlockey/mod/moddable")
|
2
|
+
|
3
|
+
module Hlockey
|
4
|
+
module Mod
|
5
|
+
##
|
6
|
+
# Player can get into a fight at any time
|
7
|
+
class Punchy
|
8
|
+
include(Moddable)
|
9
|
+
include(Actions)
|
10
|
+
|
11
|
+
DESCRIPTION = "This player may randomly start fights.".freeze
|
12
|
+
|
13
|
+
def on_action(game) =
|
14
|
+
random_event_occurs?(prng: game.prng) && game.start_fight(@player)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/hlockey/mod.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require("hlockey/mod/fencebuilder")
|
2
|
+
require("hlockey/mod/fencedestroyer")
|
3
|
+
require("hlockey/mod/handholding")
|
4
|
+
require("hlockey/mod/immaterial")
|
5
|
+
require("hlockey/mod/locked")
|
6
|
+
require("hlockey/mod/powernapper")
|
7
|
+
require("hlockey/mod/punchy")
|
8
|
+
require("hlockey/mod/nonconfrontational")
|
9
|
+
|
10
|
+
module Hlockey
|
11
|
+
##
|
12
|
+
# A mod changes how a Player interacts with/responds to events
|
13
|
+
module Mod
|
14
|
+
MODS = [
|
15
|
+
Fencebuilder,
|
16
|
+
Fencedestroyer,
|
17
|
+
Handholding,
|
18
|
+
Immaterial,
|
19
|
+
Locked,
|
20
|
+
Powernapper,
|
21
|
+
Punchy,
|
22
|
+
Nonconfrontational
|
23
|
+
].freeze
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require("hlockey/mod")
|
2
|
+
require("hlockey/utils")
|
3
|
+
|
4
|
+
module Hlockey
|
5
|
+
class Team
|
6
|
+
##
|
7
|
+
# A player on a team
|
8
|
+
class Player
|
9
|
+
attr_accessor(:team, :mods, :stats)
|
10
|
+
attr_reader(:name)
|
11
|
+
|
12
|
+
alias to_s name
|
13
|
+
|
14
|
+
# @param name [String]
|
15
|
+
# @param team [Team]
|
16
|
+
# @param stats [Hash<:offense, :defense, :agility => Numeric>]
|
17
|
+
# @param mods [Array]
|
18
|
+
def initialize(name:, team:, stats:, mods: [])
|
19
|
+
@name = name
|
20
|
+
@team = team
|
21
|
+
@stats = stats
|
22
|
+
@mods = mods.map do |mod|
|
23
|
+
if mod.is_a?(Array)
|
24
|
+
Mod::MODS.find { _1.to_s == "Hlockey::Mod::#{mod.first}" }.new(self,
|
25
|
+
*mod[1..])
|
26
|
+
else
|
27
|
+
Mod::MODS.find { _1.to_s == "Hlockey::Mod::#{mod}" }.new(self)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Hash]
|
33
|
+
def to_h(simple: false)
|
34
|
+
res = {
|
35
|
+
name: @name,
|
36
|
+
stats: @stats
|
37
|
+
}
|
38
|
+
res[:team] = @team.to_s unless simple
|
39
|
+
res[:mods] = @mods.map(&:to_data) unless simple && @mods.empty?
|
40
|
+
|
41
|
+
res
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [Hash<String => String>] #stats but better for displaying
|
45
|
+
def stat_display =
|
46
|
+
Utils.hash_display_keys(
|
47
|
+
@stats.transform_values { _1.round(2).to_s.ljust(4, "0") }
|
48
|
+
)
|
49
|
+
|
50
|
+
# @param action [Symbol] method to call on each mod
|
51
|
+
def mods_do(action, *args)
|
52
|
+
res = nil
|
53
|
+
@mods.each { res ||= _1.send(action, *args) }
|
54
|
+
res
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Hlockey
|
2
|
+
class Team
|
3
|
+
##
|
4
|
+
# A Team's stadium
|
5
|
+
class Stadium
|
6
|
+
# @return [String]
|
7
|
+
attr_reader(:full_name, :hlockey_type)
|
8
|
+
|
9
|
+
# @return [String, nil]
|
10
|
+
attr_reader(:nickname, :description)
|
11
|
+
|
12
|
+
# @return [Team]
|
13
|
+
attr_accessor(:team)
|
14
|
+
|
15
|
+
# @param full_name [String]
|
16
|
+
# @param hlockey_type [String]
|
17
|
+
# @param nickname [String, nil]
|
18
|
+
# @param description [String, nil]
|
19
|
+
# @param team [Team, nil]
|
20
|
+
def initialize(full_name:, hlockey_type:,
|
21
|
+
nickname: nil, description: nil, team: nil)
|
22
|
+
@full_name = full_name
|
23
|
+
@hlockey_type = hlockey_type
|
24
|
+
@nickname = nickname
|
25
|
+
@description = description
|
26
|
+
@team = team
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [Hash]
|
30
|
+
def to_h(simple: false)
|
31
|
+
res = {
|
32
|
+
nickname: @nickname,
|
33
|
+
full_name: @full_name,
|
34
|
+
description: @description,
|
35
|
+
hlockey_type: @hlockey_type
|
36
|
+
}
|
37
|
+
return res.compact if simple
|
38
|
+
|
39
|
+
res[:team] = @team.to_s
|
40
|
+
|
41
|
+
res
|
42
|
+
end
|
43
|
+
|
44
|
+
# The name (and nickname, if it exists) of the stadium
|
45
|
+
# Used for quickly showing which Stadium a Game is taking place at
|
46
|
+
# @return [String]
|
47
|
+
def to_s
|
48
|
+
@nickname.nil? ? @full_name : "#{@full_name} (\"#{@nickname}\")"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|