dd-next-encounters 2.0.2 → 3.0.0
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/README.md +38 -1
- data/lib/data/encounters_data.rb +636 -0
- data/lib/data/lairs_data.rb +230 -0
- data/lib/data/monsters_manual_content.rb +1620 -1642
- data/lib/dd-next-encounters.rb +1 -0
- data/lib/encounters/encounter.rb +11 -4
- data/lib/encounters/encounters.rb +14 -29
- data/lib/encounters/lairs.rb +52 -0
- data/lib/monsters/monster.rb +2 -9
- data/lib/monsters/monsters_manual.rb +3 -16
- metadata +5 -4
- data/lib/data/by_xp_encounters.rb +0 -98
- data/lib/monsters/monsters_group.rb +0 -30
data/lib/dd-next-encounters.rb
CHANGED
data/lib/encounters/encounter.rb
CHANGED
@@ -1,21 +1,28 @@
|
|
1
1
|
class Encounter
|
2
2
|
|
3
|
-
|
3
|
+
attr_reader :xp_value, :id
|
4
|
+
|
5
|
+
def initialize( monster, amount, id = nil, xp_value = nil )
|
4
6
|
@monster = monster
|
5
7
|
@amount = amount
|
6
|
-
|
8
|
+
@xp_value = xp_value ? xp_value : encounter_xp_value.to_i
|
9
|
+
@id = id ? id : ( monster.key.to_s + '_' + amount.to_s ).to_sym
|
7
10
|
end
|
8
11
|
|
9
12
|
def to_s
|
10
13
|
"#{@amount} #{@monster.name}"
|
11
14
|
end
|
12
15
|
|
13
|
-
def
|
14
|
-
|
16
|
+
def to_hash
|
17
|
+
{ id: @id, monster_key: @monster.key, amount: @amount, xp_value: @xp_value }
|
15
18
|
end
|
16
19
|
|
17
20
|
private
|
18
21
|
|
22
|
+
def encounter_xp_value
|
23
|
+
1.upto(@amount).map{ @monster.xp_value }.reduce(&:+) * get_encounter_multiplier
|
24
|
+
end
|
25
|
+
|
19
26
|
def get_encounter_multiplier
|
20
27
|
count = @amount
|
21
28
|
mul = 1
|
@@ -1,49 +1,34 @@
|
|
1
|
-
require_relative '../data/
|
1
|
+
require_relative '../data/encounters_data'
|
2
2
|
require_relative '../data/xp_difficulty_table'
|
3
3
|
require_relative '../../lib/monsters/monsters_manual'
|
4
4
|
require_relative 'encounter'
|
5
5
|
|
6
6
|
class Encounters
|
7
7
|
|
8
|
-
include
|
8
|
+
include EncountersData
|
9
9
|
include XpDifficultyTable
|
10
10
|
AVAILABLE_ENCOUNTER_LEVEL = REVERSED_XP_DIFFICULTY_TABLE.keys
|
11
|
-
@@by_xp_encounters = nil
|
12
11
|
|
13
12
|
def initialize
|
14
13
|
@monster_manual = MonstersManual.new
|
15
14
|
@monster_manual.load
|
16
|
-
@by_xp_encounters = {}
|
17
|
-
BY_XP_ENCOUNTERS.each do |k, v|
|
18
|
-
@by_xp_encounters[ k ] = v.map{ |e| Encounter.new( @monster_manual.get( e[:monster_key] ), e[:amount] ) }
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# encounter_level : :easy, :medium, :hard, :deadly
|
23
|
-
def get_party_encounter( encounter_level, *hero_level )
|
24
|
-
raise 'Empty party is not valid. Please provide at least one hero' if hero_level.empty?
|
25
|
-
|
26
|
-
raise "Bad encounter level : #{encounter_level.inspect}. Available encounter level : #{AVAILABLE_ENCOUNTER_LEVEL.inspect}" unless AVAILABLE_ENCOUNTER_LEVEL.include?( encounter_level )
|
27
|
-
raise 'Party too weak. Minimum 3 members' if hero_level.count < 3
|
28
15
|
|
29
|
-
|
30
|
-
|
31
|
-
|
16
|
+
@encounters = {}
|
17
|
+
@by_monster_encounters = {}
|
18
|
+
ENCOUNTERS.each do |e|
|
19
|
+
encounter = Encounter.new( @monster_manual.get( e[:monster_key] ), e[:amount], e[:id], e[:xp_value] )
|
20
|
+
@encounters[e[:id]] = encounter
|
21
|
+
@by_monster_encounters[e[:monster_key]] ||= []
|
22
|
+
@by_monster_encounters[e[:monster_key]] << encounter
|
32
23
|
end
|
33
|
-
|
34
|
-
party_xp_level = hero_level.map{ |hl| XP_DIFFICULTY_TABLE[hl][encounter_level] }.reduce(&:+)
|
35
|
-
|
36
|
-
get_encounter( party_xp_level*0.6, party_xp_level*1.2 )
|
37
24
|
end
|
38
25
|
|
39
|
-
|
26
|
+
def by_id( encounter_id )
|
27
|
+
@encounters[ encounter_id ]
|
28
|
+
end
|
40
29
|
|
41
|
-
def
|
42
|
-
|
43
|
-
encounters = @by_xp_encounters.map{ |k_value, encounters| encounters if k_value <= max_xp && k_value >= min_xp }
|
44
|
-
encounters = encounters.compact.flatten
|
45
|
-
# p encounters.map{ |e| e.to_s }
|
46
|
-
encounters.sample
|
30
|
+
def by_monster( monster_key )
|
31
|
+
@by_monster_encounters[monster_key]
|
47
32
|
end
|
48
33
|
|
49
34
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative '../data/lairs_data'
|
2
|
+
require_relative 'encounters'
|
3
|
+
require_relative '../data/xp_difficulty_table'
|
4
|
+
|
5
|
+
class Lairs
|
6
|
+
include LairsData
|
7
|
+
include XpDifficultyTable
|
8
|
+
AVAILABLE_ENCOUNTER_LEVEL = REVERSED_XP_DIFFICULTY_TABLE.keys
|
9
|
+
|
10
|
+
MIN_PARTY_LEVEL_MUL = 0.4
|
11
|
+
|
12
|
+
# encounter_level : :easy, :medium, :hard, :deadly
|
13
|
+
def initialize( encounter_level, hero_levels )
|
14
|
+
|
15
|
+
@encounters = Encounters.new
|
16
|
+
@encounter_level = encounter_level
|
17
|
+
@hero_levels = hero_levels
|
18
|
+
check_params
|
19
|
+
|
20
|
+
@party_xp_level = hero_levels.map{ |hl| XP_DIFFICULTY_TABLE[hl][@encounter_level] }.reduce(&:+)
|
21
|
+
|
22
|
+
@lair_type = get_available_lairs.sample
|
23
|
+
end
|
24
|
+
|
25
|
+
def encounter
|
26
|
+
encounter_id = get_available_encounters.sample
|
27
|
+
@encounters.by_id encounter_id
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def get_available_lairs
|
33
|
+
LAIRS_DATA[:by_xp_lair].select{ |k, _| k >= @party_xp_level*MIN_PARTY_LEVEL_MUL && k <= @party_xp_level }.values.flatten.uniq
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_available_encounters
|
37
|
+
LAIRS_DATA[:lairs][@lair_type][:by_encounters_xp].select{ |k, _| k >= @party_xp_level*MIN_PARTY_LEVEL_MUL && k <= @party_xp_level }.values.flatten.uniq
|
38
|
+
end
|
39
|
+
|
40
|
+
def check_params
|
41
|
+
raise 'Empty party is not valid. Please provide at least one hero' if @hero_levels.empty?
|
42
|
+
|
43
|
+
raise "Bad encounter level : #{@encounter_level.inspect}. Available encounter level : #{AVAILABLE_ENCOUNTER_LEVEL.inspect}" unless AVAILABLE_ENCOUNTER_LEVEL.include?( @encounter_level )
|
44
|
+
raise 'Party too weak. Minimum 3 members' if @hero_levels.count < 3
|
45
|
+
|
46
|
+
@hero_levels.each do |level|
|
47
|
+
raise "Hero level should be an integer currently : #{level.class.to_s}" unless level.class == Integer
|
48
|
+
raise "Bad hero level : #{level}. Should be between 1 .. 20" if level < 1 || level > 20
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
data/lib/monsters/monster.rb
CHANGED
@@ -13,24 +13,17 @@ end
|
|
13
13
|
|
14
14
|
class Monster
|
15
15
|
|
16
|
-
attr_reader :challenge, :name, :type, :source, :key
|
16
|
+
attr_reader :challenge, :name, :type, :source, :key
|
17
17
|
attr_accessor :xp_value, :boss
|
18
18
|
|
19
19
|
def initialize( challenge, name, type, source )
|
20
20
|
set_instance_variables(binding, *local_variables)
|
21
21
|
@key = @name.gsub( /[ -]/, '_' ).gsub( 'é', 'e' ).delete( "()'’“”" ).downcase.to_sym
|
22
|
-
@groups = []
|
23
|
-
@accepted_bosses = []
|
24
22
|
@boss = false
|
25
23
|
end
|
26
24
|
|
27
|
-
def add_groups( groups )
|
28
|
-
@groups ||= []
|
29
|
-
@groups += groups
|
30
|
-
end
|
31
|
-
|
32
25
|
def to_hash
|
33
|
-
{ key: @key, challenge: @challenge, name: @name, type: @type, source: @source, xp_value: @xp_value, boss: @boss
|
26
|
+
{ key: @key, challenge: @challenge, name: @name, type: @type, source: @source, xp_value: @xp_value, boss: @boss }
|
34
27
|
end
|
35
28
|
|
36
29
|
end
|
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'pp'
|
3
3
|
require_relative 'monster'
|
4
|
-
require_relative '
|
5
|
-
require_relative '../../lib/data/monsters_manual_content'
|
4
|
+
require_relative '../data/monsters_manual_content'
|
6
5
|
|
7
6
|
class MonstersManual
|
8
7
|
|
9
|
-
attr_reader :monsters
|
8
|
+
attr_reader :monsters
|
10
9
|
|
11
10
|
include MonstersManualContent
|
12
11
|
|
@@ -15,7 +14,6 @@ class MonstersManual
|
|
15
14
|
@sources = {}
|
16
15
|
@challenges = {}
|
17
16
|
@types = {}
|
18
|
-
@groups = {}
|
19
17
|
end
|
20
18
|
|
21
19
|
def load
|
@@ -24,7 +22,6 @@ class MonstersManual
|
|
24
22
|
monster = Monster.new( m[:challenge], m[:name], m[:type], m[:source] )
|
25
23
|
monster.xp_value = m[:xp_value]
|
26
24
|
monster.boss = m[:boss]
|
27
|
-
monster.add_groups( m[:groups] )
|
28
25
|
@monsters[ monster.key ] = monster
|
29
26
|
end
|
30
27
|
|
@@ -32,11 +29,6 @@ class MonstersManual
|
|
32
29
|
@challenges = MONSTERS_MANUAL_CONTENT[:challenges]
|
33
30
|
@types = MONSTERS_MANUAL_CONTENT[:types]
|
34
31
|
|
35
|
-
MONSTERS_MANUAL_CONTENT[:groups].each do |k, group_hash|
|
36
|
-
group = MonstersGroup.new
|
37
|
-
group.from_hash( @monsters, group_hash )
|
38
|
-
@groups[k] = group
|
39
|
-
end
|
40
32
|
end
|
41
33
|
|
42
34
|
def save( filename )
|
@@ -44,8 +36,7 @@ class MonstersManual
|
|
44
36
|
monsters: @monsters.map{ |_, m| m.to_hash },
|
45
37
|
sources: @sources,
|
46
38
|
challenges: @challenges,
|
47
|
-
types: @types
|
48
|
-
groups: Hash[ @groups.map{ |k, g| [ k, g.to_hash ] } ]
|
39
|
+
types: @types
|
49
40
|
}
|
50
41
|
File.open( filename, 'w' ) do |f|
|
51
42
|
f.puts 'module MonstersManualContent'
|
@@ -99,10 +90,6 @@ class MonstersManual
|
|
99
90
|
@types[monster.type] ||= []
|
100
91
|
@types[monster.type] << monster.key
|
101
92
|
|
102
|
-
monster.groups.each do |group|
|
103
|
-
@groups[group] ||= MonstersGroup.new
|
104
|
-
@groups[group].add_monster( monster )
|
105
|
-
end
|
106
93
|
end
|
107
94
|
|
108
95
|
def validate_loaded
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dd-next-encounters
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cédric Zuger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-04-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hazard
|
@@ -31,14 +31,15 @@ extensions: []
|
|
31
31
|
extra_rdoc_files: []
|
32
32
|
files:
|
33
33
|
- README.md
|
34
|
-
- lib/data/
|
34
|
+
- lib/data/encounters_data.rb
|
35
|
+
- lib/data/lairs_data.rb
|
35
36
|
- lib/data/monsters_manual_content.rb
|
36
37
|
- lib/data/xp_difficulty_table.rb
|
37
38
|
- lib/dd-next-encounters.rb
|
38
39
|
- lib/encounters/encounter.rb
|
39
40
|
- lib/encounters/encounters.rb
|
41
|
+
- lib/encounters/lairs.rb
|
40
42
|
- lib/monsters/monster.rb
|
41
|
-
- lib/monsters/monsters_group.rb
|
42
43
|
- lib/monsters/monsters_manual.rb
|
43
44
|
homepage: https://github.com/czuger/dd-next-encounters
|
44
45
|
licenses:
|
@@ -1,98 +0,0 @@
|
|
1
|
-
module ByXpEncounters
|
2
|
-
BY_XP_ENCOUNTERS =
|
3
|
-
{50=>
|
4
|
-
[{:amount=>1, :monster_key=>:skeleton}, {:amount=>1, :monster_key=>:goblin}],
|
5
|
-
150=>
|
6
|
-
[{:amount=>2, :monster_key=>:skeleton}, {:amount=>2, :monster_key=>:goblin}],
|
7
|
-
300=>
|
8
|
-
[{:amount=>3, :monster_key=>:skeleton},
|
9
|
-
{:amount=>2, :monster_key=>:shadow},
|
10
|
-
{:amount=>3, :monster_key=>:goblin},
|
11
|
-
{:amount=>2, :monster_key=>:hobgoblin},
|
12
|
-
{:amount=>2, :monster_key=>:orc}],
|
13
|
-
400=>
|
14
|
-
[{:amount=>4, :monster_key=>:skeleton}, {:amount=>4, :monster_key=>:goblin}],
|
15
|
-
500=>
|
16
|
-
[{:amount=>5, :monster_key=>:skeleton}, {:amount=>5, :monster_key=>:goblin}],
|
17
|
-
600=>
|
18
|
-
[{:amount=>6, :monster_key=>:skeleton},
|
19
|
-
{:amount=>2, :monster_key=>:ghoul},
|
20
|
-
{:amount=>3, :monster_key=>:shadow},
|
21
|
-
{:amount=>2, :monster_key=>:specter},
|
22
|
-
{:amount=>6, :monster_key=>:goblin},
|
23
|
-
{:amount=>3, :monster_key=>:hobgoblin},
|
24
|
-
{:amount=>2, :monster_key=>:bugbear},
|
25
|
-
{:amount=>3, :monster_key=>:orc}],
|
26
|
-
200=>
|
27
|
-
[{:amount=>1, :monster_key=>:ghoul},
|
28
|
-
{:amount=>1, :monster_key=>:specter},
|
29
|
-
{:amount=>1, :monster_key=>:bugbear}],
|
30
|
-
1200=>
|
31
|
-
[{:amount=>3, :monster_key=>:ghoul},
|
32
|
-
{:amount=>6, :monster_key=>:shadow},
|
33
|
-
{:amount=>3, :monster_key=>:specter},
|
34
|
-
{:amount=>6, :monster_key=>:hobgoblin},
|
35
|
-
{:amount=>3, :monster_key=>:bugbear},
|
36
|
-
{:amount=>6, :monster_key=>:orc}],
|
37
|
-
1600=>
|
38
|
-
[{:amount=>4, :monster_key=>:ghoul},
|
39
|
-
{:amount=>4, :monster_key=>:specter},
|
40
|
-
{:amount=>4, :monster_key=>:bugbear}],
|
41
|
-
2000=>
|
42
|
-
[{:amount=>5, :monster_key=>:ghoul},
|
43
|
-
{:amount=>5, :monster_key=>:specter},
|
44
|
-
{:amount=>5, :monster_key=>:bugbear}],
|
45
|
-
2400=>
|
46
|
-
[{:amount=>6, :monster_key=>:ghoul},
|
47
|
-
{:amount=>6, :monster_key=>:specter},
|
48
|
-
{:amount=>6, :monster_key=>:bugbear}],
|
49
|
-
100=>
|
50
|
-
[{:amount=>1, :monster_key=>:shadow},
|
51
|
-
{:amount=>1, :monster_key=>:hobgoblin},
|
52
|
-
{:amount=>1, :monster_key=>:orc}],
|
53
|
-
800=>
|
54
|
-
[{:amount=>4, :monster_key=>:shadow},
|
55
|
-
{:amount=>4, :monster_key=>:hobgoblin},
|
56
|
-
{:amount=>4, :monster_key=>:orc}],
|
57
|
-
1000=>
|
58
|
-
[{:amount=>5, :monster_key=>:shadow},
|
59
|
-
{:amount=>5, :monster_key=>:hobgoblin},
|
60
|
-
{:amount=>5, :monster_key=>:orc}],
|
61
|
-
450=>
|
62
|
-
[{:amount=>1, :monster_key=>:ghast},
|
63
|
-
{:amount=>1, :monster_key=>:minotaur_skeleton}],
|
64
|
-
1350=>
|
65
|
-
[{:amount=>2, :monster_key=>:ghast},
|
66
|
-
{:amount=>2, :monster_key=>:minotaur_skeleton}],
|
67
|
-
2700=>
|
68
|
-
[{:amount=>3, :monster_key=>:ghast},
|
69
|
-
{:amount=>3, :monster_key=>:minotaur_skeleton}],
|
70
|
-
3600=>
|
71
|
-
[{:amount=>4, :monster_key=>:ghast},
|
72
|
-
{:amount=>4, :monster_key=>:minotaur_skeleton}],
|
73
|
-
4500=>
|
74
|
-
[{:amount=>5, :monster_key=>:ghast},
|
75
|
-
{:amount=>5, :monster_key=>:minotaur_skeleton}],
|
76
|
-
5400=>
|
77
|
-
[{:amount=>6, :monster_key=>:ghast},
|
78
|
-
{:amount=>6, :monster_key=>:minotaur_skeleton},
|
79
|
-
{:amount=>2, :monster_key=>:vampire_spawn}],
|
80
|
-
700=>[{:amount=>1, :monster_key=>:mummy}],
|
81
|
-
2100=>[{:amount=>2, :monster_key=>:mummy}],
|
82
|
-
4200=>[{:amount=>3, :monster_key=>:mummy}],
|
83
|
-
13000=>
|
84
|
-
[{:amount=>1, :monster_key=>:mummy_lord},
|
85
|
-
{:amount=>1, :monster_key=>:vampire_spellcaster},
|
86
|
-
{:amount=>1, :monster_key=>:vampire_warrior}],
|
87
|
-
10000=>[{:amount=>1, :monster_key=>:vampire}],
|
88
|
-
30000=>[{:amount=>2, :monster_key=>:vampire}],
|
89
|
-
60000=>[{:amount=>3, :monster_key=>:vampire}],
|
90
|
-
1800=>[{:amount=>1, :monster_key=>:vampire_spawn}],
|
91
|
-
10800=>[{:amount=>3, :monster_key=>:vampire_spawn}],
|
92
|
-
39000=>
|
93
|
-
[{:amount=>2, :monster_key=>:vampire_spellcaster},
|
94
|
-
{:amount=>2, :monster_key=>:vampire_warrior}],
|
95
|
-
78000=>
|
96
|
-
[{:amount=>3, :monster_key=>:vampire_spellcaster},
|
97
|
-
{:amount=>3, :monster_key=>:vampire_warrior}]}
|
98
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
class MonstersGroup
|
2
|
-
|
3
|
-
attr_reader :troops, :bosses
|
4
|
-
|
5
|
-
def initialize
|
6
|
-
@troops = []
|
7
|
-
@bosses = []
|
8
|
-
# This mean that this group is inferior to the listed groups. They wont accept
|
9
|
-
@groups_inferiority = []
|
10
|
-
end
|
11
|
-
|
12
|
-
def add_monster( monster )
|
13
|
-
@troops << monster unless monster.boss
|
14
|
-
@bosses << monster if monster.boss
|
15
|
-
end
|
16
|
-
|
17
|
-
# def to_s
|
18
|
-
# { troops: @troops.map{ |m| m.key }, bosses: @bosses.map{ |m| m.key } }
|
19
|
-
# end
|
20
|
-
|
21
|
-
def to_hash
|
22
|
-
{ troops: @troops.map{ |m| m.key }, bosses: @bosses.map{ |m| m.key } }
|
23
|
-
end
|
24
|
-
|
25
|
-
def from_hash( monsters, hash )
|
26
|
-
@troops = hash[:troops].map{ |tk| monsters[tk] }
|
27
|
-
@bosses = hash[:bosses].map{ |tk| monsters[tk] }
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|