hlockey 4 → 5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/election.yaml +2 -2
- data/data/information.yaml +5 -5
- data/data/league.yaml +962 -794
- data/data/previous_election_results.yaml +40 -34
- data/lib/hlockey/constants.rb +6 -0
- data/lib/hlockey/data.rb +1 -1
- data/lib/hlockey/game/actions.rb +8 -11
- data/lib/hlockey/game/fight.rb +7 -3
- 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 +27 -0
- data/lib/hlockey/game/weather/weatherable.rb +63 -0
- data/lib/hlockey/game/weather.rb +17 -0
- data/lib/hlockey/game.rb +73 -64
- data/lib/hlockey/league.rb +24 -29
- data/lib/hlockey/message.rb +8 -6
- data/lib/hlockey/team/player.rb +79 -0
- data/lib/hlockey/team/stadium.rb +49 -0
- data/lib/hlockey/team.rb +31 -5
- data/lib/hlockey/utils.rb +10 -2
- data/lib/hlockey/version.rb +1 -1
- metadata +13 -5
- data/lib/hlockey/player.rb +0 -73
- data/lib/hlockey/weather.rb +0 -168
@@ -1,59 +1,65 @@
|
|
1
1
|
---
|
2
|
-
:vote_amt:
|
2
|
+
:vote_amt: 239
|
3
3
|
:categories:
|
4
|
-
:Bribery (
|
4
|
+
:Bribery (73 votes):
|
5
5
|
:Winning bribe:
|
6
|
-
:winner:
|
7
|
-
:Treasure (
|
8
|
-
:Vengabus:
|
9
|
-
:winner: Pompei Eruptions (1 vote / 16 total)
|
10
|
-
:most_votes: Stony Brook Reapers (4 votes)
|
6
|
+
:winner: Stadiums (42 votes)
|
7
|
+
:Treasure (124 votes):
|
11
8
|
:Dave:
|
12
|
-
:winner:
|
13
|
-
:most_votes: Pompei Eruptions (9 votes)
|
9
|
+
:winner: Dawson City Impostors (16 votes / 38 total)
|
14
10
|
:Nice:
|
15
|
-
:winner:
|
16
|
-
|
17
|
-
|
18
|
-
:
|
19
|
-
|
11
|
+
:winner: Nice Backflippers (7 votes / 15 total)
|
12
|
+
:Vengabus:
|
13
|
+
:winner: Kyoto Payphones (1 vote / 46 total)
|
14
|
+
:most_votes: Sydney Thinkers (31 votes)
|
15
|
+
:Unvengabus:
|
16
|
+
:winner: Antalya Pirates (Wet Warm) (0 votes / 0 total)
|
17
|
+
:Shared Training:
|
18
|
+
:winner: Antalya Pirates (Wet Warm) (2 votes / 20 total)
|
19
|
+
:most_votes: Orcadas Base Fog (5 votes)
|
20
|
+
:Theft:
|
21
|
+
:winner: Manbij Fish (1 vote / 5 total)
|
22
|
+
:most_votes: Pica Acid (2 votes)
|
23
|
+
:Hidden Treasure - Evolve:
|
24
|
+
:winner: Sleepersz (0 votes / 0 total)
|
25
|
+
:Coaching (42 votes):
|
20
26
|
:Antalya Pirates:
|
21
|
-
:winner: Please
|
27
|
+
:winner: Please Block Shots (3 votes / 3 total)
|
22
28
|
:Baden Hallucinations:
|
23
|
-
:winner:
|
29
|
+
:winner: Clock Unwise (1 vote / 1 total)
|
24
30
|
:Kópavogur Seals:
|
25
|
-
:winner:
|
31
|
+
:winner: Big Gamble (0 votes / 0 total)
|
26
32
|
:Lagos Soup:
|
27
|
-
:winner:
|
33
|
+
:winner: Please Win Faceoffs (1 vote / 1 total)
|
28
34
|
:Pica Acid:
|
29
|
-
:winner:
|
35
|
+
:winner: Big Gamble (0 votes / 0 total)
|
30
36
|
:Dawson City Impostors:
|
31
|
-
:winner:
|
37
|
+
:winner: Draft (2 votes / 3 total)
|
32
38
|
:Erlangen Ohms:
|
33
|
-
:winner:
|
39
|
+
:winner: Please Win Faceoffs (2 votes / 2 total)
|
34
40
|
:Pompei Eruptions:
|
35
|
-
:winner: Please
|
41
|
+
:winner: Please Win Faceoffs (2 votes / 2 total)
|
36
42
|
:Rio de Janeiro Directors:
|
37
|
-
:winner:
|
43
|
+
:winner: Clock Wise (1 vote / 1 total)
|
38
44
|
:Wyrzysk Rockets:
|
39
|
-
:winner: Please Win Faceoffs (
|
45
|
+
:winner: Please Win Faceoffs (0 votes / 0 total)
|
40
46
|
:Cape Town Transplants:
|
41
|
-
:winner:
|
47
|
+
:winner: Please Block Shots (1 vote / 2 total)
|
42
48
|
:Manbij Fish:
|
43
|
-
:winner:
|
49
|
+
:winner: Please Block Shots (1 vote / 2 total)
|
44
50
|
:Nagqu Paint:
|
45
|
-
:winner:
|
51
|
+
:winner: Revolution (1 vote / 1 total)
|
46
52
|
:Nice Backflippers:
|
47
|
-
:winner:
|
53
|
+
:winner: Please Block Shots (7 votes / 7 total)
|
48
54
|
:Orcadas Base Fog:
|
49
|
-
:winner:
|
55
|
+
:winner: Please Win Faceoffs (2 votes / 2 total)
|
50
56
|
:Baghdad Abacuses:
|
51
|
-
:winner:
|
57
|
+
:winner: Please Win Faceoffs (0 votes / 0 total)
|
52
58
|
:Jakarta Architects:
|
53
|
-
:winner: Big Gamble (
|
59
|
+
:winner: Big Gamble (0 votes / 0 total)
|
54
60
|
:Kyoto Payphones:
|
55
|
-
:winner:
|
61
|
+
:winner: Clock Unwise (3 votes / 5 total)
|
56
62
|
:Stony Brook Reapers:
|
57
|
-
:winner:
|
63
|
+
:winner: Please Block Shots (1 vote / 2 total)
|
58
64
|
:Sydney Thinkers:
|
59
|
-
:winner:
|
65
|
+
:winner: Draft (6 votes / 7 total)
|
data/lib/hlockey/constants.rb
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
module Hlockey
|
2
2
|
UPDATE_FREQUENCY_SECONDS = 5
|
3
3
|
UPDATES_PER_HOUR = 3600 / UPDATE_FREQUENCY_SECONDS
|
4
|
+
|
5
|
+
ACTIONS_PER_PERIOD = 60
|
6
|
+
NON_OT_PERIODS = 3
|
7
|
+
NON_OT_ACTIONS = ACTIONS_PER_PERIOD * NON_OT_PERIODS
|
8
|
+
TOTAL_ACTIONS = UPDATES_PER_HOUR - ACTIONS_PER_PERIOD
|
9
|
+
TOTAL_PERIODS = TOTAL_ACTIONS / ACTIONS_PER_PERIOD
|
4
10
|
end
|
data/lib/hlockey/data.rb
CHANGED
data/lib/hlockey/game/actions.rb
CHANGED
@@ -2,19 +2,16 @@ module Hlockey
|
|
2
2
|
class Game
|
3
3
|
##
|
4
4
|
# For classes that deal with actions within a Hlockey game.
|
5
|
-
# Any class including this must have instance variables indicated by the readers
|
6
5
|
module Actions
|
7
|
-
|
8
|
-
attr_reader(:home, :away)
|
6
|
+
private
|
9
7
|
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
# @return [
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
attr_reader(:in_progress)
|
8
|
+
# For an event that should happen randomly about a certain amount of times per game,
|
9
|
+
# returns if the event should happen or not. Should be called once per action.
|
10
|
+
# @param times [Integer] the approximate amount of times the event should occur
|
11
|
+
# @return [Boolean] if the event should occur
|
12
|
+
def random_event_occurs?(times = 1)
|
13
|
+
@prng.rand(NON_OT_ACTIONS / times).zero?
|
14
|
+
end
|
18
15
|
|
19
16
|
# @param succeed_boost [Numeric] increases chance of action succeeding
|
20
17
|
# @param fail_boost [Numeric] decreases chance of action succeeding
|
data/lib/hlockey/game/fight.rb
CHANGED
@@ -11,6 +11,9 @@ module Hlockey
|
|
11
11
|
# @return [Hash<Symbol => Array<Player>>] the players in the fight
|
12
12
|
attr_reader(:players)
|
13
13
|
|
14
|
+
# @return [Hash<Symbol => Integer>] the amount of successful punches for each team
|
15
|
+
attr_reader(:score)
|
16
|
+
|
14
17
|
# @param game [Game] the game the fight is a part of
|
15
18
|
def initialize(game)
|
16
19
|
@home = game.home
|
@@ -22,7 +25,6 @@ module Hlockey
|
|
22
25
|
away: [@away.roster.values.sample(random: @prng)]
|
23
26
|
}
|
24
27
|
@score = { home: 0, away: 0 }
|
25
|
-
@in_progress = true
|
26
28
|
end
|
27
29
|
|
28
30
|
# @return [Message] the message to add to the game stream
|
@@ -46,14 +48,16 @@ module Hlockey
|
|
46
48
|
|
47
49
|
Message.PlayerJoinedFight(send(team_joining), player_joining)
|
48
50
|
else # fight ends
|
49
|
-
@in_progress = false
|
50
|
-
|
51
51
|
Message.FightEnded
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
55
|
private
|
56
56
|
|
57
|
+
# private readers so #send works
|
58
|
+
# @return [Team] a team in the fight
|
59
|
+
attr_reader(:home, :away)
|
60
|
+
|
57
61
|
# @return [Message] returned by #next_action for same purpose
|
58
62
|
def attack
|
59
63
|
attacking_team = rand_team
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require("hlockey/game/weather/weatherable")
|
2
|
+
require("hlockey/game/actions")
|
3
|
+
|
4
|
+
module Hlockey
|
5
|
+
class Game
|
6
|
+
module Weather
|
7
|
+
##
|
8
|
+
# Audacity weather
|
9
|
+
# Causes players to take shots regardless of the state of the game
|
10
|
+
class Audacity
|
11
|
+
include(Weatherable)
|
12
|
+
include(Actions)
|
13
|
+
|
14
|
+
def on_action
|
15
|
+
@game.send(:shoot, audacity: true) if random_event_occurs?(10)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require("hlockey/game/weather/weatherable")
|
2
|
+
require("hlockey/game/actions")
|
3
|
+
require("hlockey/message")
|
4
|
+
|
5
|
+
module Hlockey
|
6
|
+
class Game
|
7
|
+
module Weather
|
8
|
+
##
|
9
|
+
# Chicken weather
|
10
|
+
# Swaps a random roster player with a random shadow player for the rest of the game
|
11
|
+
class Chicken
|
12
|
+
include(Weatherable)
|
13
|
+
include(Actions)
|
14
|
+
|
15
|
+
def on_game_start
|
16
|
+
@chickened_out = { home: {}, away: {} }
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_action
|
20
|
+
return unless random_event_occurs?(5)
|
21
|
+
|
22
|
+
team = rand_team
|
23
|
+
pos, shadows_idx = get_swap(team)
|
24
|
+
if pos.nil? || shadows_idx.nil?
|
25
|
+
team = team == :home ? :away : :home
|
26
|
+
pos, shadows_idx = get_swap(team)
|
27
|
+
return if pos.nil? || shadows_idx.nil?
|
28
|
+
end
|
29
|
+
|
30
|
+
@chickened_out[team][pos] = shadows_idx
|
31
|
+
|
32
|
+
@game.stream << Message.ChickenedOut(*swap(team, pos, shadows_idx))
|
33
|
+
end
|
34
|
+
|
35
|
+
def on_game_end
|
36
|
+
@chickened_out.each do |team, swaps|
|
37
|
+
swaps.each { |pos, shadows_idx| swap(team, pos, shadows_idx) }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# @param team_sym [:home, :away]
|
44
|
+
# @return [Array<Symbol, Integer>]
|
45
|
+
def get_swap(team_sym)
|
46
|
+
team = @game.send(team_sym)
|
47
|
+
|
48
|
+
[
|
49
|
+
(team.roster.keys - @chickened_out[team_sym].keys).sample(random: @prng),
|
50
|
+
(team.shadows.each_index.to_a - @chickened_out[team_sym].values)
|
51
|
+
.sample(random: @prng)
|
52
|
+
]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require("hlockey/game/weather/weatherable")
|
2
|
+
require("hlockey/message")
|
3
|
+
|
4
|
+
module Hlockey
|
5
|
+
class Game
|
6
|
+
module Weather
|
7
|
+
##
|
8
|
+
# Incline weather
|
9
|
+
# Adds a random amount of score to a favored team's goals
|
10
|
+
class Incline
|
11
|
+
include(Weatherable)
|
12
|
+
|
13
|
+
def on_game_start
|
14
|
+
make_incline
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_goal(scoring_team)
|
18
|
+
return unless scoring_team == @favored_team
|
19
|
+
|
20
|
+
@game.score[scoring_team] += @prng.rand(0.1..0.5)
|
21
|
+
make_incline
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_action
|
25
|
+
return unless @incline_changed
|
26
|
+
|
27
|
+
@game.stream << Message.InclineFavors(@game.send(@favored_team))
|
28
|
+
@incline_changed = false
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def make_incline
|
34
|
+
new_favored_team = rand_team
|
35
|
+
return if new_favored_team == @favored_team
|
36
|
+
|
37
|
+
@favored_team = new_favored_team
|
38
|
+
@incline_changed = true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require("hlockey/game/weather/weatherable")
|
2
|
+
require("hlockey/message")
|
3
|
+
|
4
|
+
module Hlockey
|
5
|
+
class Game
|
6
|
+
module Weather
|
7
|
+
##
|
8
|
+
# Stars weather
|
9
|
+
# Gives the losing team +0.5 score at the end of each period
|
10
|
+
class Stars
|
11
|
+
include(Weatherable)
|
12
|
+
|
13
|
+
def on_period_end
|
14
|
+
return if @game.score[:home] == @game.score[:away]
|
15
|
+
|
16
|
+
team = @game.score.min_by { |_, v| v }.first
|
17
|
+
@game.score[team] += 0.5
|
18
|
+
@game.stream << Message.StarsAlign(@game.send(team))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require("hlockey/game/weather/weatherable")
|
2
|
+
|
3
|
+
module Hlockey
|
4
|
+
class Game
|
5
|
+
module Weather
|
6
|
+
##
|
7
|
+
# Sunset weather
|
8
|
+
# Makes each team's goals worth less the more the team scores
|
9
|
+
class Sunset
|
10
|
+
include(Weatherable)
|
11
|
+
|
12
|
+
def on_game_start
|
13
|
+
@score_amt = { home: 0, away: 0 }
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_goal(scoring_team)
|
17
|
+
@score_amt[scoring_team] += 1
|
18
|
+
@game.score[scoring_team] -= @score_amt[scoring_team] * 0.2
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require("hlockey/game/weather/weatherable")
|
2
|
+
require("hlockey/game/actions")
|
3
|
+
require("hlockey/message")
|
4
|
+
|
5
|
+
module Hlockey
|
6
|
+
class Game
|
7
|
+
module Weather
|
8
|
+
##
|
9
|
+
# Waves weather
|
10
|
+
# Swaps the worst roster player with a random shadow player permanently
|
11
|
+
class Waves
|
12
|
+
include(Weatherable)
|
13
|
+
include(Actions)
|
14
|
+
|
15
|
+
def on_action
|
16
|
+
return unless random_event_occurs?
|
17
|
+
|
18
|
+
team_sym = rand_team
|
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)))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require("hlockey/constants")
|
2
|
+
|
3
|
+
module Hlockey
|
4
|
+
class Game
|
5
|
+
module Weather
|
6
|
+
##
|
7
|
+
# Module with needed methods for weathers, that every weather includes
|
8
|
+
# All methods starting with "on" represent game events weathers may respond to
|
9
|
+
module Weatherable
|
10
|
+
def initialize(game)
|
11
|
+
@game = game
|
12
|
+
@home = @game.home
|
13
|
+
@away = @game.away
|
14
|
+
@prng = @game.prng
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
self.class.to_s.split("::").last
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_game_start() end
|
22
|
+
|
23
|
+
def on_game_end() end
|
24
|
+
|
25
|
+
def on_period_end() end
|
26
|
+
|
27
|
+
def on_action() end
|
28
|
+
|
29
|
+
def on_goal(scoring_team) end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Swaps a roster player with a shadows player
|
34
|
+
# @param team_sym [:home, :away]
|
35
|
+
# @param pos [Symbol] position of roster player swapped out
|
36
|
+
# @param shadows_idx [Integer] index of shadows player swapped in
|
37
|
+
# @return [Array<Player>] the players that were swapped
|
38
|
+
def swap(team_sym, pos, shadows_idx)
|
39
|
+
team = @game.send(team_sym)
|
40
|
+
|
41
|
+
prev_player = team.roster[pos]
|
42
|
+
next_player = team.shadows[shadows_idx]
|
43
|
+
team.roster[pos] = next_player
|
44
|
+
team.shadows[shadows_idx] = prev_player
|
45
|
+
|
46
|
+
unless @game.fight.nil?
|
47
|
+
player_array = @game.fight.players[team_sym]
|
48
|
+
player_idx = player_array.index(prev_player)
|
49
|
+
|
50
|
+
player_array[player_idx] = next_player unless player_idx.nil?
|
51
|
+
end
|
52
|
+
|
53
|
+
[prev_player, next_player]
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [:home, :away]
|
57
|
+
def rand_team
|
58
|
+
@prng.rand(2).zero? ? :home : :away
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require("hlockey/game/weather/audacity")
|
2
|
+
require("hlockey/game/weather/chicken")
|
3
|
+
require("hlockey/game/weather/incline")
|
4
|
+
require("hlockey/game/weather/stars")
|
5
|
+
require("hlockey/game/weather/sunset")
|
6
|
+
require("hlockey/game/weather/waves")
|
7
|
+
|
8
|
+
module Hlockey
|
9
|
+
class Game
|
10
|
+
##
|
11
|
+
# Weathers modify the mechanics of a Game
|
12
|
+
module Weather
|
13
|
+
# Every weather class
|
14
|
+
WEATHERS = [Audacity, Chicken, Incline, Stars, Sunset, Waves].freeze
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/hlockey/game.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require("hlockey/game/actions")
|
2
2
|
require("hlockey/game/fight")
|
3
|
+
require("hlockey/game/weather")
|
3
4
|
require("hlockey/constants")
|
4
5
|
require("hlockey/message")
|
5
6
|
require("hlockey/utils")
|
@@ -10,33 +11,42 @@ module Hlockey
|
|
10
11
|
class Game
|
11
12
|
include(Actions)
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
NON_OT_ACTIONS = ACTIONS_PER_PERIOD * NON_OT_PERIODS
|
16
|
-
TOTAL_ACTIONS = UPDATES_PER_HOUR - ACTIONS_PER_PERIOD
|
17
|
-
TOTAL_PERIODS = TOTAL_ACTIONS / ACTIONS_PER_PERIOD
|
14
|
+
# @return [Team] the teams in the game
|
15
|
+
attr_reader(:home, :away)
|
18
16
|
|
19
|
-
# @return [
|
17
|
+
# @return [Random] should be the same as the league's
|
18
|
+
attr_reader(:prng)
|
19
|
+
|
20
|
+
# @return [Team::Stadium] the stadium this game is located at
|
21
|
+
attr_reader(:stadium)
|
22
|
+
|
23
|
+
# @return [Weather::Weatherable] the weather effecting the game
|
20
24
|
attr_reader(:weather)
|
21
25
|
|
22
|
-
# @return [Array<Message>]
|
26
|
+
# @return [Array<Message>] messages about game events
|
23
27
|
attr_reader(:stream)
|
24
28
|
|
25
|
-
# @return [Integer]
|
26
|
-
attr_reader(:
|
29
|
+
# @return [Hash<Symbol => Integer>] the score of each team
|
30
|
+
attr_reader(:score)
|
31
|
+
|
32
|
+
# @return [Boolean] if the game is still in progress
|
33
|
+
attr_reader(:in_progress)
|
34
|
+
|
35
|
+
# @return [Integer] what period the game is in
|
36
|
+
attr_reader(:period)
|
27
37
|
|
28
|
-
# @return [Fight, nil]
|
38
|
+
# @return [Fight, nil] the current fight, if there is any
|
29
39
|
attr_reader(:fight)
|
30
40
|
|
31
41
|
# @param home [Team]
|
32
42
|
# @param away [Team]
|
33
43
|
# @param prng [Random] should be League#prng
|
34
|
-
|
35
|
-
def initialize(home, away, prng, weather)
|
44
|
+
def initialize(home, away, prng)
|
36
45
|
@home = home
|
37
46
|
@away = away
|
38
47
|
@prng = prng
|
39
|
-
@
|
48
|
+
@stadium = @home.stadium
|
49
|
+
@weather = Weather::WEATHERS.sample(random: prng).new(self)
|
40
50
|
@stream = [Message.StartOfGame]
|
41
51
|
@score = { home: 0, away: 0 }
|
42
52
|
@in_progress = true
|
@@ -61,24 +71,33 @@ module Hlockey
|
|
61
71
|
"#{Message.color(@home)} vs #{Message.color(@away)}"
|
62
72
|
end
|
63
73
|
|
64
|
-
#
|
74
|
+
# Update the game state by one action
|
65
75
|
def update
|
66
76
|
return unless @in_progress
|
67
77
|
|
78
|
+
do_action
|
79
|
+
handle_parties
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
# Does an action in the game
|
85
|
+
def do_action
|
68
86
|
@stream << Message.StartOfPeriod(@period) if @actions.zero?
|
69
87
|
@actions += 1
|
70
88
|
|
71
89
|
@weather.on_action
|
72
90
|
|
73
91
|
unless @fight.nil?
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
change_morale(@home, morale_change_amount)
|
78
|
-
change_morale(@away, -morale_change_amount)
|
92
|
+
fight_message = @fight.next_action
|
93
|
+
@stream << fight_message
|
94
|
+
return unless fight_message.event == :FightEnded
|
79
95
|
|
80
|
-
|
81
|
-
|
96
|
+
morale_change_amount = (@fight.score[:home] - @fight.score[:away]) / 10.0
|
97
|
+
change_morale(@home, morale_change_amount)
|
98
|
+
change_morale(@away, -morale_change_amount)
|
99
|
+
|
100
|
+
@fight = nil
|
82
101
|
return
|
83
102
|
end
|
84
103
|
|
@@ -99,8 +118,11 @@ module Hlockey
|
|
99
118
|
else
|
100
119
|
shoot
|
101
120
|
end
|
121
|
+
end
|
102
122
|
|
103
|
-
|
123
|
+
# Does the random chance of partying for teams in party time
|
124
|
+
def handle_parties
|
125
|
+
return unless @partying_teams.any? && random_event_occurs?(5)
|
104
126
|
|
105
127
|
@partying_teams.each do |team|
|
106
128
|
player = team.roster.values.sample(random: @prng)
|
@@ -113,33 +135,6 @@ module Hlockey
|
|
113
135
|
end
|
114
136
|
end
|
115
137
|
|
116
|
-
# Makes a player shoot in the game, regardless of if it would normally occur
|
117
|
-
# @param audacity [Boolean] if the function was called by Audacity weather
|
118
|
-
def shoot(audacity: false)
|
119
|
-
return if @puck_holder_pos.nil?
|
120
|
-
|
121
|
-
if @shooting_chance < 5 &&
|
122
|
-
try_block_shot(@prng.rand(2).zero? ? :ldef : :rdef, audacity: audacity)
|
123
|
-
return
|
124
|
-
end
|
125
|
-
return if try_block_shot(:goalie, audacity: audacity)
|
126
|
-
|
127
|
-
# Goal scored
|
128
|
-
|
129
|
-
scoring_team = @team_with_puck == @home ? :home : :away
|
130
|
-
@score[scoring_team] += 1
|
131
|
-
weather.on_goal(scoring_team)
|
132
|
-
|
133
|
-
@stream << Message.ShootScore(puck_holder, @home, @away, *@score.values, audacity)
|
134
|
-
|
135
|
-
start_fight if @prng.rand(3 + @fight_chance) > 3
|
136
|
-
|
137
|
-
start_faceoff
|
138
|
-
@actions = ACTIONS_PER_PERIOD - 1 if @period >= NON_OT_PERIODS # Sudden death OT
|
139
|
-
end
|
140
|
-
|
141
|
-
private
|
142
|
-
|
143
138
|
# Makes a player pass in the game, regardless of if it would normally occur
|
144
139
|
def pass
|
145
140
|
sender = puck_holder
|
@@ -170,6 +165,32 @@ module Hlockey
|
|
170
165
|
@fight_chance += 0.1
|
171
166
|
end
|
172
167
|
|
168
|
+
# Makes a player shoot in the game, regardless of if it would normally occur
|
169
|
+
# This is called outside of the class by Audacity weather (using #send)
|
170
|
+
# @param audacity [Boolean] if the function was called by Audacity weather
|
171
|
+
def shoot(audacity: false)
|
172
|
+
return if @puck_holder_pos.nil?
|
173
|
+
|
174
|
+
if @shooting_chance < 5 &&
|
175
|
+
try_block_shot(@prng.rand(2).zero? ? :ldef : :rdef, audacity: audacity)
|
176
|
+
return
|
177
|
+
end
|
178
|
+
return if try_block_shot(:goalie, audacity: audacity)
|
179
|
+
|
180
|
+
# Goal scored
|
181
|
+
|
182
|
+
scoring_team = @team_with_puck == @home ? :home : :away
|
183
|
+
@score[scoring_team] += 1
|
184
|
+
weather.on_goal(scoring_team)
|
185
|
+
|
186
|
+
@stream << Message.ShootScore(puck_holder, @home, @away, *@score.values, audacity)
|
187
|
+
|
188
|
+
start_fight if @prng.rand(3 + @fight_chance) > 3
|
189
|
+
|
190
|
+
start_faceoff
|
191
|
+
@actions = ACTIONS_PER_PERIOD - 1 if @period > NON_OT_PERIODS # Sudden death OT
|
192
|
+
end
|
193
|
+
|
173
194
|
def end_period
|
174
195
|
@weather.on_period_end
|
175
196
|
@stream << Message.EndOfPeriod(@period, @home, @away, *@score.values)
|
@@ -177,7 +198,7 @@ module Hlockey
|
|
177
198
|
@period += 1
|
178
199
|
start_faceoff
|
179
200
|
|
180
|
-
if @period
|
201
|
+
if @period > NON_OT_PERIODS &&
|
181
202
|
!(@score[:home] == @score[:away] && @period <= TOTAL_PERIODS)
|
182
203
|
# Game is over
|
183
204
|
@pre_morale_change_stats.each { |player, stats| player.stats = stats }
|
@@ -300,21 +321,9 @@ module Hlockey
|
|
300
321
|
# @return [Hash<Symbol => Integer>]
|
301
322
|
def weights(offensive)
|
302
323
|
if offensive
|
303
|
-
{
|
304
|
-
lwing: 2,
|
305
|
-
center: 2,
|
306
|
-
rwing: 2,
|
307
|
-
ldef: 1,
|
308
|
-
rdef: 1
|
309
|
-
}
|
324
|
+
{ lwing: 2, center: 2, rwing: 2, ldef: 1, rdef: 1 }
|
310
325
|
else
|
311
|
-
{
|
312
|
-
lwing: 1,
|
313
|
-
center: 1,
|
314
|
-
rwing: 1,
|
315
|
-
ldef: 3,
|
316
|
-
rdef: 3
|
317
|
-
}
|
326
|
+
{ lwing: 1, center: 1, rwing: 1, ldef: 3, rdef: 3 }
|
318
327
|
end
|
319
328
|
end
|
320
329
|
end
|