dd-next-encounters 2.0.2 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|