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.
@@ -1,2 +1,3 @@
1
1
  require_relative 'monsters/monsters_manual'
2
2
  require_relative 'encounters/encounters'
3
+ require_relative 'encounters/lairs'
@@ -1,21 +1,28 @@
1
1
  class Encounter
2
2
 
3
- def initialize( monster, amount )
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
- # @party_xp_level = party_xp_level
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 encounter_xp_value
14
- 1.upto(@amount).map{ @monster.xp_value }.reduce(&:+) * get_encounter_multiplier
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/by_xp_encounters'
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 ByXpEncounters
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
- hero_level.each do |level|
30
- raise "Hero level should be an integer currently : #{level.class.to_s}" unless level.class == Integer
31
- raise "Bad hero level : #{level}. Should be between 1 .. 20" if level < 1 || level > 20
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
- private
26
+ def by_id( encounter_id )
27
+ @encounters[ encounter_id ]
28
+ end
40
29
 
41
- def get_encounter( min_xp, max_xp )
42
- raise 'Encounters not loaded' unless @by_xp_encounters
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
@@ -13,24 +13,17 @@ end
13
13
 
14
14
  class Monster
15
15
 
16
- attr_reader :challenge, :name, :type, :source, :key, :groups
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, groups: @groups }
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 'monsters_group'
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, :groups
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: 2.0.2
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-03-26 00:00:00.000000000 Z
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/by_xp_encounters.rb
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