hlockey 5 → 7

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/data/election.json +23 -0
  3. data/data/infinileague.json +189 -0
  4. data/data/information.json +6 -0
  5. data/data/league.json +2042 -0
  6. data/data/links.json +5 -0
  7. data/data/messages.json +46 -0
  8. data/data/previous_election_results.json +91 -0
  9. data/lib/hlockey/actions.rb +22 -0
  10. data/lib/hlockey/data.rb +6 -5
  11. data/lib/hlockey/game/fight.rb +100 -40
  12. data/lib/hlockey/game/weather/audacity.rb +1 -1
  13. data/lib/hlockey/game/weather/chicken.rb +3 -2
  14. data/lib/hlockey/game/weather/incline.rb +2 -1
  15. data/lib/hlockey/game/weather/stars.rb +1 -1
  16. data/lib/hlockey/game/weather/sunset.rb +2 -4
  17. data/lib/hlockey/game/weather/waves.rb +9 -5
  18. data/lib/hlockey/game/weather/weatherable.rb +9 -9
  19. data/lib/hlockey/game.rb +182 -116
  20. data/lib/hlockey/league.rb +90 -73
  21. data/lib/hlockey/message.rb +23 -153
  22. data/lib/hlockey/mod/fencebuilder.rb +15 -0
  23. data/lib/hlockey/mod/fencedestroyer.rb +16 -0
  24. data/lib/hlockey/mod/handholding.rb +57 -0
  25. data/lib/hlockey/mod/immaterial.rb +28 -0
  26. data/lib/hlockey/mod/locked.rb +28 -0
  27. data/lib/hlockey/mod/moddable.rb +70 -0
  28. data/lib/hlockey/mod/nonconfrontational.rb +17 -0
  29. data/lib/hlockey/mod/powernapper.rb +50 -0
  30. data/lib/hlockey/mod/punchy.rb +21 -0
  31. data/lib/hlockey/mod.rb +25 -0
  32. data/lib/hlockey/selfdescribable.rb +7 -0
  33. data/lib/hlockey/team/player.rb +40 -58
  34. data/lib/hlockey/team/stadium.rb +10 -7
  35. data/lib/hlockey/team.rb +56 -41
  36. data/lib/hlockey/utils.rb +36 -4
  37. data/lib/hlockey/version.rb +1 -1
  38. data/lib/hlockey.rb +15 -0
  39. metadata +30 -18
  40. data/data/election.yaml +0 -21
  41. data/data/external/names.txt +0 -19948
  42. data/data/information.yaml +0 -24
  43. data/data/league.yaml +0 -1694
  44. data/data/links.yaml +0 -3
  45. data/data/previous_election_results.yaml +0 -65
  46. data/lib/hlockey/game/actions.rb +0 -24
data/data/links.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "Website": "https://hlockey.gay",
3
+ "Source Code": "https://codeberg.org/LavenderPerry/hlockey",
4
+ "Discord": "https://discord.gg/2N8VN8Q69E"
5
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "season_day": "Season %{season} day %{day}",
3
+ "season_starts": "Season %{season} starts at %{time}.",
4
+ "season_champion": "Your season %{season} champions are the %{team}!",
5
+ "season_off": "no games right now. it is the offseason. join the Hlockey Discord for updates.",
6
+
7
+ "game_start": "Hocky!",
8
+ "game_end": "Game over.\n%{winning_team} win!",
9
+ "game_score": "%{home} %{home_score}, %{away} %{away_score}",
10
+ "game_period_start": "Start of period %{period}.",
11
+ "game_period_end": "End of period %{period}.",
12
+ "game_faceoff": "%{winning_player} wins the faceoff!",
13
+ "game_pass": "%{sender} passes to %{receiver}.",
14
+ "game_pass_intercept": "%{sender}'s pass to %{receiver} is intercepted by %{interceptor}!",
15
+ "game_hit": "%{defender} hits %{puck_holder}.",
16
+ "game_shot": "%{shooter} takes a shot...",
17
+ "game_shot_audacious": "%{shooter} takes an audacious shot...",
18
+ "game_shot_scored": "%{shooter} scores!",
19
+ "game_shot_blocked": "%{blocker} blocks the shot.",
20
+ "game_partying": "%{player} is partying!",
21
+ "game_possession_change": "%{player} takes the puck!\n%{new_puck_team} have possession.",
22
+
23
+ "fight_start": "%{home_player} and %{away_player} start fighting!",
24
+ "fight_player_join": "%{player} from %{team} joins the fight!",
25
+ "fight_player_withdraw": "%{player} withdraws from the fight!",
26
+ "fight_attack": "%{player} is going for a punch...",
27
+ "fight_hit": "The punch lands to hit %{player}!",
28
+ "fight_block": "%{player} blocks the punch!",
29
+ "fight_dodge": "%{player} dodges the punch!",
30
+ "fight_end": "The fight has ended.",
31
+ "fight_end_morale_gain": "%{team} gains %{num} morale.",
32
+ "fight_end_morale_loss": "%{team} loses %{num} morale.",
33
+
34
+ "weather_chicken_event": "%{prev_player} chickened out!\nReplaced by %{next_player} for the game.",
35
+ "weather_incline_event": "The incline favors %{team}.",
36
+ "weather_stars_event": "The stars align for %{team}. They get half a goal.",
37
+ "weather_waves_event": "%{prev_player} is washed away by the waves...\nReplaced by %{next_player} for the season.",
38
+
39
+ "mod_immaterial_event": "%{hitting_player} goes right through %{player}!",
40
+ "mod_fence_event": "%{player} is a fence%{type}.\n%{player} swaps with %{swap_player} instead.",
41
+ "mod_handholding_event": "%{player} is holding %{other_player}'s hand.\n%{other_player} follows %{player} by swapping with %{swap_player}.",
42
+ "mod_locked_event": "%{player} is locked and does not get swapped with %{swap_player}",
43
+ "mod_powernap_start": "%{player} gets a boost from powernapping!",
44
+ "mod_powernap_end": "%{player}'s powernap boost has ended.",
45
+ "mod_punchy_event": "%{player} is looking for a fight..."
46
+ }
@@ -0,0 +1,91 @@
1
+ {
2
+ "vote_amt": 91,
3
+ "categories": {
4
+ "Treasure (64 votes)": {
5
+ "Dave": {
6
+ "winner": "Cape Town Transplants (2 votes / 7 total)"
7
+ },
8
+ "Nice": {
9
+ "winner": "Stony Brook Reapers (1 vote / 15 total)",
10
+ "most_votes": "Dawson City Impostors (9 votes)"
11
+ },
12
+ "Vengabus": {
13
+ "winner": "Stony Brook Reapers (1 vote / 11 total)",
14
+ "most_votes": "Rio de Janeiro Directors (4 votes)"
15
+ },
16
+ "Shared Training": {
17
+ "winner": "Pompei Eruptions (Dry Warm) (1 votes / 15 total)",
18
+ "most_votes": "Kyoto Payphones (3 votes)"
19
+ },
20
+ "Theft": {
21
+ "winner": "Baden Hallucinations (1 vote / 14 total)",
22
+ "most_votes": "Rio de Janeiro Directors (3 votes)"
23
+ },
24
+ "Shadow Lock": {
25
+ "winner": "Nagqu Paint (2 votes / 2 total)"
26
+ }
27
+ },
28
+ "Coaching (27 votes)": {
29
+ "Antalya Pirates": {
30
+ "winner": "Draft (1 vote / 1 total)"
31
+ },
32
+ "Baden Hallucinations": {
33
+ "winner": "Draft (2 votes / 2 total)"
34
+ },
35
+ "Kópavogur Seals": {
36
+ "winner": "Please Block Shots (0 votes / 0 total)"
37
+ },
38
+ "Lagos Soup": {
39
+ "winner": "Small Gamble (0 votes / 0 total)"
40
+ },
41
+ "Pica Acid": {
42
+ "winner": "Big Gamble (0 votes / 0 total)"
43
+ },
44
+ "Dawson City Impostors": {
45
+ "winner": "Please Block Shots (2 votes / 5 total)"
46
+ },
47
+ "Erlangen Ohms": {
48
+ "winner": "Clock Wise (1 vote / 1 total)"
49
+ },
50
+ "Pompei Eruptions": {
51
+ "winner": "Please Win Faceoffs (1 vote / 1 total)"
52
+ },
53
+ "Rio de Janeiro Directors": {
54
+ "winner": "Please Win Faceoffs (3 votes / 3 total)"
55
+ },
56
+ "Wyrzysk Rockets": {
57
+ "winner": "Revolution (0 votes / 0 total)"
58
+ },
59
+ "Cape Town Transplants": {
60
+ "winner": "Small Gamble (0 votes / 0 total)"
61
+ },
62
+ "Manbij Fish": {
63
+ "winner": "Clock Wise (0 votes / 0 total)"
64
+ },
65
+ "Nagqu Paint": {
66
+ "winner": "Please Win Faceoffs (1 vote / 1 total)"
67
+ },
68
+ "Nice Backflippers": {
69
+ "winner": "Please Block Shots (1 vote / 1 total)"
70
+ },
71
+ "Orcadas Base Fog": {
72
+ "winner": "Small Gamble (1 vote / 1 total)"
73
+ },
74
+ "Baghdad Abacuses": {
75
+ "winner": "Please Win Faceoffs (0 votes / 0 total)"
76
+ },
77
+ "Jakarta Architects": {
78
+ "winner": "Please Win Faceoffs (0 votes / 0 total)"
79
+ },
80
+ "Kyoto Payphones": {
81
+ "winner": "Big Gamble (6 votes / 6 total)"
82
+ },
83
+ "Stony Brook Reapers": {
84
+ "winner": "Clock Unwise (1 vote / 1 total)"
85
+ },
86
+ "Sydney Thinkers": {
87
+ "winner": "Draft (3 votes / 4 total)"
88
+ }
89
+ }
90
+ }
91
+ }
@@ -0,0 +1,22 @@
1
+ require("hlockey/constants")
2
+
3
+ module Hlockey
4
+ ##
5
+ # For classes that deal with actions within a Hlockey game.
6
+ module Actions
7
+ private
8
+
9
+ # For an event that should happen randomly about a certain amount of times per game,
10
+ # returns if the event should happen or not. Should be called once per action.
11
+ # @param times [Integer] the approximate amount of times the event should occur
12
+ # @return [Boolean] if the event should occur
13
+ def random_event_occurs?(times = 1, prng: @prng) =
14
+ prng.rand(NON_OT_ACTIONS / times).zero?
15
+
16
+ # @param succeed_boost [Numeric] increases chance of action succeeding
17
+ # @param fail_boost [Numeric] decreases chance of action succeeding
18
+ # @return [Boolean] if the action succeeded
19
+ def action_succeeds?(succeed_boost, fail_boost, prng: @prng) =
20
+ prng.rand(20) + (succeed_boost - fail_boost) > 9
21
+ end
22
+ end
data/lib/hlockey/data.rb CHANGED
@@ -1,5 +1,4 @@
1
- require("hlockey/team") # Classes stored in league data
2
- require("yaml")
1
+ require("json")
3
2
 
4
3
  module Hlockey
5
4
  ##
@@ -8,9 +7,11 @@ module Hlockey
8
7
  class << self
9
8
  data_dir = File.expand_path("../../data", __dir__)
10
9
 
11
- Dir.glob("*.yaml", base: data_dir).each do |data_file|
12
- category = File.basename(data_file, ".yaml")
13
- define_method(category) { YAML.unsafe_load_file("#{data_dir}/#{data_file}") }
10
+ Dir.glob("*.json", base: data_dir).each do |data_file|
11
+ # @return [Hash] loaded data
12
+ define_method(File.basename(data_file, ".json")) do
13
+ JSON.parse(File.read("#{data_dir}/#{data_file}"), symbolize_names: true)
14
+ end
14
15
  end
15
16
  end
16
17
  end
@@ -1,5 +1,6 @@
1
- require("hlockey/game/actions")
1
+ require("hlockey/actions")
2
2
  require("hlockey/message")
3
+ require("hlockey/mod/punchy")
3
4
 
4
5
  module Hlockey
5
6
  class Game
@@ -8,30 +9,43 @@ module Hlockey
8
9
  class Fight
9
10
  include(Actions)
10
11
 
11
- # @return [Hash<Symbol => Array<Player>>] the players in the fight
12
+ # @return [Hash<Symbol => Array<Team::Player>>] the players in the fight
12
13
  attr_reader(:players)
13
14
 
14
15
  # @return [Hash<Symbol => Integer>] the amount of successful punches for each team
15
16
  attr_reader(:score)
16
17
 
17
18
  # @param game [Game] the game the fight is a part of
18
- def initialize(game)
19
- @home = game.home
20
- @away = game.away
21
- @prng = game.prng
19
+ # @param starting_player [Team::Player] the player that started the fight, if any
20
+ def initialize(game, starting_player = nil)
21
+ @game = game
22
22
  @actions = 0
23
- @players = {
24
- home: [@home.roster.values.sample(random: @prng)],
25
- away: [@away.roster.values.sample(random: @prng)]
26
- }
23
+ @players = { home: [], away: [] }
24
+ @players.each_key do |team|
25
+ add_player(if @game.send(team).roster.value?(starting_player)
26
+ starting_player
27
+ else
28
+ get_joining_player(team)
29
+ end,
30
+ team)
31
+ end
32
+
27
33
  @score = { home: 0, away: 0 }
28
34
  end
29
35
 
30
- # @return [Message] the message to add to the game stream
31
36
  def next_action
32
37
  @actions += 1
33
38
 
34
- case @prng.rand(@actions)
39
+ # If fight has a single player on one side who is outnumbered,
40
+ # there is a chance that player will withdraw, ending the fight.
41
+ if @players[:home].length == 1
42
+ return if @players[:away].length > 1 && player_withdraws?(@players[:home].first,
43
+ :home)
44
+ elsif @players[:away].length == 1
45
+ return if player_withdraws?(@players[:away].first, :away)
46
+ end
47
+
48
+ case @game.prng.rand(@actions)
35
49
  when 0..3 # attack
36
50
  attack
37
51
  when 4..7 # player joins
@@ -41,62 +55,108 @@ module Hlockey
41
55
  if player_joining.nil?
42
56
  team_joining = opposite(team_joining)
43
57
  player_joining = get_joining_player(team_joining)
44
- return attack if player_joining.nil?
58
+ if player_joining.nil?
59
+ attack
60
+ return
61
+ end
45
62
  end
46
63
 
47
- @players[team_joining] << player_joining
48
-
49
- Message.PlayerJoinedFight(send(team_joining), player_joining)
64
+ add_player(player_joining, team_joining)
50
65
  else # fight ends
51
- Message.FightEnded
66
+ @game.stream << Message.new(:fight_end)
52
67
  end
53
68
  end
54
69
 
55
70
  private
56
71
 
57
- # private readers so #send works
58
- # @return [Team] a team in the fight
59
- attr_reader(:home, :away)
60
-
61
- # @return [Message] returned by #next_action for same purpose
62
72
  def attack
63
73
  attacking_team = rand_team
64
74
  defending_team = opposite(attacking_team)
65
75
 
66
- attacking_player = @players[attacking_team].sample(random: @prng)
67
- defending_player = @players[defending_team].sample(random: @prng)
76
+ attacking_player = @players[attacking_team].sample(random: @game.prng)
77
+ @game.stream << Message.new(:fight_attack, player: attacking_player)
78
+
79
+ defending_player = @players[defending_team].sample(random: @game.prng)
80
+
81
+ if action_succeeds?(defending_player.stats[:defense],
82
+ defending_player.stats[:agility],
83
+ prng: @game.prng)
84
+ # Try to block the punch
85
+ if action_succeeds?(defending_player.stats[:defense],
86
+ attacking_player.stats[:offense],
87
+ prng: @game.prng)
88
+ # Punch sucessfully blocked
89
+ @game.stream << Message.new(:fight_block, player: defending_player)
90
+ return
91
+ end
92
+ # Try to dodge the punch
93
+ elsif action_succeeds?(defending_player.stats[:agility],
94
+ attacking_player.stats[:offense],
95
+ prng: @game.prng)
96
+ # Punch sucessfully dodged
97
+ @game.stream << Message.new(:fight_dodge, player: defending_player)
98
+ return
99
+ end
68
100
 
69
- blocked = action_succeeds?(defending_player.stats[:defense],
70
- attacking_player.stats[:offense])
101
+ # Punch lands
102
+ @game.stream << Message.new(:fight_hit, player: defending_player)
103
+ @score[attacking_team] += 1
104
+ player_withdraws?(defending_player, defending_team)
105
+ end
71
106
 
72
- @score[attacking_team] += 1 unless blocked
107
+ # @param team [:home, :away]
108
+ # @return [Team::Player, nil]
109
+ def get_joining_player(team) =
110
+ (@game.send(team).roster.values - @players[team]).sample(random: @game.prng)
111
+
112
+ # @param player [Team::Player]
113
+ # @param team [:home, :away]
114
+ def add_player(player, team)
115
+ @game.stream << Message.new(:fight_player_join, player:, team: player.team)
116
+
117
+ mods_res = player.mods_do(:on_join_fight)
118
+ if mods_res # Mod would return a joining player to replace them
119
+ @game.stream << Message.new(:fight_player_withdraw, player:)
120
+ player = mods_res
121
+ @game.stream << Message.new(:fight_player_join, player:, team: player.team)
122
+ end
73
123
 
74
- Message.FightAttack(attacking_player, defending_player, blocked)
124
+ @players[team] << player
75
125
  end
76
126
 
127
+ # @param player [Team::Player]
77
128
  # @param team [:home, :away]
78
- # @return [Player, nil]
79
- def get_joining_player(team)
80
- (send(team).roster.values - @players[team]).sample(random: @prng)
129
+ # @return [Boolean] if the player withdrew
130
+ def player_withdraws?(player, team)
131
+ return false unless player.mods.none? { _1.is_a?(Mod::Punchy) } &&
132
+ @game.prng.rand(50).zero?
133
+
134
+ # Player withdraws
135
+ @game.stream << Message.new(:fight_player_withdraw, player:)
136
+ @players[team].delete(player)
137
+
138
+ if @players[team].empty?
139
+ @game.stream << Message.new(:fight_end)
140
+ @score[team] = 0
141
+ @score[opposite(team)] = 10
142
+ end
143
+
144
+ true
81
145
  end
82
146
 
83
147
  # @return [:home, :away] randomly selected based on amount of players in fight
84
- def rand_team
85
- rand_is_home? ? :home : :away
86
- end
148
+ def rand_team = rand_is_home? ? :home : :away
87
149
 
88
150
  # @param team [:home, :away]
89
151
  # @return [:home, :away] :away if `team` is :home, :home if `team` is :away
90
- def opposite(team)
91
- team == :home ? :away : :home
92
- end
152
+ def opposite(team) = team == :home ? :away : :home
93
153
 
94
154
  # @return [Boolean] if randomly selected team is home team
95
155
  def rand_is_home?
96
- home_player_amount = @home.roster.values.length
97
- away_player_amount = @away.roster.values.length
156
+ home_player_amount = @game.home.roster.values.length
157
+ away_player_amount = @game.away.roster.values.length
98
158
 
99
- @prng.rand(home_player_amount + away_player_amount) < home_player_amount
159
+ @game.prng.rand(home_player_amount + away_player_amount) < home_player_amount
100
160
  end
101
161
  end
102
162
  end
@@ -1,5 +1,5 @@
1
1
  require("hlockey/game/weather/weatherable")
2
- require("hlockey/game/actions")
2
+ require("hlockey/actions")
3
3
 
4
4
  module Hlockey
5
5
  class Game
@@ -1,5 +1,5 @@
1
1
  require("hlockey/game/weather/weatherable")
2
- require("hlockey/game/actions")
2
+ require("hlockey/actions")
3
3
  require("hlockey/message")
4
4
 
5
5
  module Hlockey
@@ -29,7 +29,8 @@ module Hlockey
29
29
 
30
30
  @chickened_out[team][pos] = shadows_idx
31
31
 
32
- @game.stream << Message.ChickenedOut(*swap(team, pos, shadows_idx))
32
+ @game.stream << Message.new(:weather_chicken_event,
33
+ **swap(team, pos, shadows_idx))
33
34
  end
34
35
 
35
36
  def on_game_end
@@ -24,7 +24,8 @@ module Hlockey
24
24
  def on_action
25
25
  return unless @incline_changed
26
26
 
27
- @game.stream << Message.InclineFavors(@game.send(@favored_team))
27
+ @game.stream << Message.new(:weather_incline_event,
28
+ team: @game.send(@favored_team))
28
29
  @incline_changed = false
29
30
  end
30
31
 
@@ -15,7 +15,7 @@ module Hlockey
15
15
 
16
16
  team = @game.score.min_by { |_, v| v }.first
17
17
  @game.score[team] += 0.5
18
- @game.stream << Message.StarsAlign(@game.send(team))
18
+ @game.stream << Message.new(:weather_stars_event, team: @game.send(team))
19
19
  end
20
20
  end
21
21
  end
@@ -9,13 +9,11 @@ module Hlockey
9
9
  class Sunset
10
10
  include(Weatherable)
11
11
 
12
- def on_game_start
13
- @score_amt = { home: 0, away: 0 }
14
- end
12
+ def on_game_start = @score_amt = { home: 0, away: 0 }
15
13
 
16
14
  def on_goal(scoring_team)
17
15
  @score_amt[scoring_team] += 1
18
- @game.score[scoring_team] -= @score_amt[scoring_team] * 0.2
16
+ @game.score[scoring_team] -= @score_amt[scoring_team] * 0.3
19
17
  end
20
18
  end
21
19
  end
@@ -1,5 +1,5 @@
1
1
  require("hlockey/game/weather/weatherable")
2
- require("hlockey/game/actions")
2
+ require("hlockey/actions")
3
3
  require("hlockey/message")
4
4
 
5
5
  module Hlockey
@@ -7,7 +7,7 @@ module Hlockey
7
7
  module Weather
8
8
  ##
9
9
  # Waves weather
10
- # Swaps the worst roster player with a random shadow player permanently
10
+ # Swaps a roster player (worst most likely) with a random shadow player permanently
11
11
  class Waves
12
12
  include(Weatherable)
13
13
  include(Actions)
@@ -17,9 +17,13 @@ module Hlockey
17
17
 
18
18
  team_sym = rand_team
19
19
  team = @game.send(team_sym)
20
- @game.stream << Message.WavesWashedAway(*swap(team_sym,
21
- team.worst_player_pos,
22
- @prng.rand(team.shadows.length)))
20
+ player_leaving_pos = if @prng.rand(5).zero?
21
+ team.roster.keys.sample(random: @prng)
22
+ else
23
+ team.worst_player_pos
24
+ end
25
+ swap_res = swap(team_sym, player_leaving_pos, @prng.rand(team.shadows.length))
26
+ @game.stream << Message.new(:weather_waves_event, **swap_res)
23
27
  end
24
28
  end
25
29
  end
@@ -1,4 +1,5 @@
1
1
  require("hlockey/constants")
2
+ require("hlockey/selfdescribable")
2
3
 
3
4
  module Hlockey
4
5
  class Game
@@ -7,6 +8,8 @@ module Hlockey
7
8
  # Module with needed methods for weathers, that every weather includes
8
9
  # All methods starting with "on" represent game events weathers may respond to
9
10
  module Weatherable
11
+ include(SelfDescribable)
12
+
10
13
  def initialize(game)
11
14
  @game = game
12
15
  @home = @game.home
@@ -14,10 +17,6 @@ module Hlockey
14
17
  @prng = @game.prng
15
18
  end
16
19
 
17
- def to_s
18
- self.class.to_s.split("::").last
19
- end
20
-
21
20
  def on_game_start() end
22
21
 
23
22
  def on_game_end() end
@@ -34,7 +33,7 @@ module Hlockey
34
33
  # @param team_sym [:home, :away]
35
34
  # @param pos [Symbol] position of roster player swapped out
36
35
  # @param shadows_idx [Integer] index of shadows player swapped in
37
- # @return [Array<Player>] the players that were swapped
36
+ # @return [Hash<[:prev_player, :next_player] => Team::Player>] the swapped players
38
37
  def swap(team_sym, pos, shadows_idx)
39
38
  team = @game.send(team_sym)
40
39
 
@@ -50,13 +49,14 @@ module Hlockey
50
49
  player_array[player_idx] = next_player unless player_idx.nil?
51
50
  end
52
51
 
53
- [prev_player, next_player]
52
+ prev_player.mods_do(:on_swap, false, shadows_idx, pos)
53
+ next_player.mods_do(:on_swap, true, pos, shadows_idx)
54
+
55
+ { prev_player:, next_player: }
54
56
  end
55
57
 
56
58
  # @return [:home, :away]
57
- def rand_team
58
- @prng.rand(2).zero? ? :home : :away
59
- end
59
+ def rand_team = @prng.rand(2).zero? ? :home : :away
60
60
  end
61
61
  end
62
62
  end