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