natural_20 0.1.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.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +6 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +7 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +99 -0
  9. data/Rakefile +6 -0
  10. data/bin/compute_lights +19 -0
  11. data/bin/console +19 -0
  12. data/bin/nat20 +135 -0
  13. data/bin/nat20.cmd +3 -0
  14. data/bin/nat20author +104 -0
  15. data/bin/setup +8 -0
  16. data/char_classes/fighter.yml +45 -0
  17. data/char_classes/rogue.yml +54 -0
  18. data/characters/halfling_rogue.yml +46 -0
  19. data/characters/high_elf_fighter.yml +49 -0
  20. data/fixtures/battle_sim.yml +58 -0
  21. data/fixtures/battle_sim_2.yml +30 -0
  22. data/fixtures/battle_sim_3.yml +26 -0
  23. data/fixtures/battle_sim_4.yml +26 -0
  24. data/fixtures/battle_sim_objects.yml +101 -0
  25. data/fixtures/corridors.yml +24 -0
  26. data/fixtures/elf_rogue.yml +39 -0
  27. data/fixtures/halfling_rogue.yml +41 -0
  28. data/fixtures/high_elf_fighter.yml +49 -0
  29. data/fixtures/human_fighter.yml +48 -0
  30. data/fixtures/path_finding_test.yml +11 -0
  31. data/fixtures/path_finding_test_2.yml +15 -0
  32. data/fixtures/path_finding_test_3.yml +26 -0
  33. data/fixtures/thin_walls.yml +53 -0
  34. data/fixtures/traps.yml +25 -0
  35. data/game.yml +20 -0
  36. data/items/equipment.yml +101 -0
  37. data/items/objects.yml +73 -0
  38. data/items/weapons.yml +297 -0
  39. data/lib/natural_20.rb +68 -0
  40. data/lib/natural_20/actions/action.rb +40 -0
  41. data/lib/natural_20/actions/attack_action.rb +372 -0
  42. data/lib/natural_20/actions/concerns/action_damage.rb +14 -0
  43. data/lib/natural_20/actions/dash_action.rb +46 -0
  44. data/lib/natural_20/actions/disengage_action.rb +53 -0
  45. data/lib/natural_20/actions/dodge_action.rb +45 -0
  46. data/lib/natural_20/actions/escape_grapple_action.rb +97 -0
  47. data/lib/natural_20/actions/first_aid_action.rb +109 -0
  48. data/lib/natural_20/actions/grapple_action.rb +185 -0
  49. data/lib/natural_20/actions/ground_interact_action.rb +74 -0
  50. data/lib/natural_20/actions/help_action.rb +56 -0
  51. data/lib/natural_20/actions/hide_action.rb +53 -0
  52. data/lib/natural_20/actions/interact_action.rb +91 -0
  53. data/lib/natural_20/actions/inventory_action.rb +23 -0
  54. data/lib/natural_20/actions/look_action.rb +63 -0
  55. data/lib/natural_20/actions/move_action.rb +254 -0
  56. data/lib/natural_20/actions/multiattack_action.rb +41 -0
  57. data/lib/natural_20/actions/prone_action.rb +38 -0
  58. data/lib/natural_20/actions/short_rest_action.rb +53 -0
  59. data/lib/natural_20/actions/shove_action.rb +142 -0
  60. data/lib/natural_20/actions/stand_action.rb +47 -0
  61. data/lib/natural_20/actions/use_item_action.rb +57 -0
  62. data/lib/natural_20/ai_controller/path_compute.rb +140 -0
  63. data/lib/natural_20/ai_controller/standard.rb +288 -0
  64. data/lib/natural_20/battle.rb +544 -0
  65. data/lib/natural_20/battle_map.rb +843 -0
  66. data/lib/natural_20/cli/builder/fighter_builder.rb +104 -0
  67. data/lib/natural_20/cli/builder/rogue_builder.rb +62 -0
  68. data/lib/natural_20/cli/character_builder.rb +210 -0
  69. data/lib/natural_20/cli/commandline_ui.rb +612 -0
  70. data/lib/natural_20/cli/inventory_ui.rb +136 -0
  71. data/lib/natural_20/cli/map_renderer.rb +165 -0
  72. data/lib/natural_20/concerns/container.rb +32 -0
  73. data/lib/natural_20/concerns/entity.rb +1213 -0
  74. data/lib/natural_20/concerns/evaluator/entity_state_evaluator.rb +59 -0
  75. data/lib/natural_20/concerns/fighter_actions/second_wind_action.rb +51 -0
  76. data/lib/natural_20/concerns/fighter_class.rb +35 -0
  77. data/lib/natural_20/concerns/health_flavor.rb +27 -0
  78. data/lib/natural_20/concerns/lootable.rb +94 -0
  79. data/lib/natural_20/concerns/movement_helper.rb +195 -0
  80. data/lib/natural_20/concerns/multiattack.rb +54 -0
  81. data/lib/natural_20/concerns/navigation.rb +87 -0
  82. data/lib/natural_20/concerns/notable.rb +37 -0
  83. data/lib/natural_20/concerns/rogue_class.rb +26 -0
  84. data/lib/natural_20/controller.rb +11 -0
  85. data/lib/natural_20/die_roll.rb +331 -0
  86. data/lib/natural_20/event_manager.rb +288 -0
  87. data/lib/natural_20/item_library/base_item.rb +27 -0
  88. data/lib/natural_20/item_library/chest.rb +230 -0
  89. data/lib/natural_20/item_library/door_object.rb +189 -0
  90. data/lib/natural_20/item_library/ground.rb +124 -0
  91. data/lib/natural_20/item_library/healing_potion.rb +51 -0
  92. data/lib/natural_20/item_library/object.rb +153 -0
  93. data/lib/natural_20/item_library/pit_trap.rb +69 -0
  94. data/lib/natural_20/item_library/stone_wall.rb +18 -0
  95. data/lib/natural_20/npc.rb +173 -0
  96. data/lib/natural_20/player_character.rb +414 -0
  97. data/lib/natural_20/session.rb +168 -0
  98. data/lib/natural_20/utils/cover.rb +35 -0
  99. data/lib/natural_20/utils/ray_tracer.rb +90 -0
  100. data/lib/natural_20/utils/static_light_builder.rb +72 -0
  101. data/lib/natural_20/utils/weapons.rb +78 -0
  102. data/lib/natural_20/version.rb +4 -0
  103. data/locales/en.yml +304 -0
  104. data/maps/game_map.yml +168 -0
  105. data/natural_20.gemspec +46 -0
  106. data/npcs/goblin.yml +64 -0
  107. data/npcs/human_guard.yml +48 -0
  108. data/npcs/ogre.yml +61 -0
  109. data/npcs/owlbear.yml +55 -0
  110. data/npcs/wolf.yml +46 -0
  111. data/races/elf.yml +44 -0
  112. data/races/halfling.yml +22 -0
  113. data/races/human.yml +13 -0
  114. metadata +373 -0
data/items/objects.yml ADDED
@@ -0,0 +1,73 @@
1
+ ---
2
+ barrel:
3
+ color: brown
4
+ cover: half
5
+ default_ac: 15
6
+ hp_die: 4d8
7
+ interactable: true
8
+ max_hp: 18
9
+ name: Barrel
10
+ token:
11
+ - o
12
+ bottomless_pit:
13
+ color: black
14
+ jump: true
15
+ opaque: false
16
+ passable: true
17
+ placeable: false
18
+ token:
19
+ - ▓
20
+ brazier:
21
+ color: yellow
22
+ default_ac: 17
23
+ max_hp: 27
24
+ passable: true
25
+ placeable: false
26
+ light:
27
+ bright: 20
28
+ dim: 10
29
+ token:
30
+ - Ý
31
+ chest:
32
+ color: yellow
33
+ item_class: 'ItemLibrary::Chest'
34
+ name: Treasure Chest
35
+ passable: true
36
+ placeable: false
37
+ pit_trap:
38
+ damage_die: 1d10
39
+ damage_type: piercing
40
+ item_class: 'ItemLibrary::PitTrap'
41
+ name: Pit Trap
42
+ notes:
43
+ - highlight: true
44
+ note: Pit Trap
45
+ perception_dc: 10
46
+ stone_wall:
47
+ color: light_magenta
48
+ default_ac: 17
49
+ item_class: 'ItemLibrary::StoneWall'
50
+ max_hp: 27
51
+ name: Stone Wall
52
+ opaque: true
53
+ passable: false
54
+ token:
55
+ - null
56
+ wall: true
57
+ water:
58
+ color: blue
59
+ movement_cost: 2
60
+ name: Water
61
+ passable: true
62
+ token:
63
+ - ^
64
+ wooden_door:
65
+ color: magenta
66
+ default_ac: 15
67
+ hp_die: 4d8
68
+ interactable: true
69
+ item_class: 'ItemLibrary::DoorObject'
70
+ max_hp: 18
71
+ name: Wooden Door
72
+ token:
73
+ - '='
data/items/weapons.yml ADDED
@@ -0,0 +1,297 @@
1
+ ---
2
+ dagger:
3
+ cost: 2
4
+ damage: 1d4
5
+ damage_type: piercing
6
+ meta:
7
+ noise_source: 5
8
+ noise_target: 5
9
+ modifiers: null
10
+ name: Dagger
11
+ proficiency_type:
12
+ - simple
13
+ properties:
14
+ - light
15
+ - thrown
16
+ - finesse
17
+ range: 5
18
+ subtype: weapon
19
+ thrown:
20
+ range: 30
21
+ range_max: 120
22
+ type: melee_attack
23
+ weight: 10
24
+ greatclub:
25
+ cost: 2sp
26
+ damage: 1d8
27
+ damage_type: bludgeoning
28
+ meta:
29
+ noise_source: 5
30
+ noise_target: 5
31
+ modifiers: null
32
+ name: Greatclub
33
+ proficiency_type:
34
+ - simple
35
+ properties:
36
+ - two_handed
37
+ range: 5
38
+ subtype: weapon
39
+ type: melee_attack
40
+ weight: 10
41
+ hand_crossbow:
42
+ ammo: bolts
43
+ cost: 75
44
+ damage: 1d6
45
+ damage_type: piercing
46
+ meta:
47
+ noise_source: 5
48
+ noise_target: 5
49
+ modifiers: null
50
+ name: Hand Crossbow
51
+ proficiency_type:
52
+ - martial
53
+ properties:
54
+ - loading
55
+ - ammunition
56
+ - ranged
57
+ - light
58
+ range: 30
59
+ range_max: 120
60
+ subtype: weapon
61
+ type: ranged_attack
62
+ weight: 3
63
+ handaxe:
64
+ cost: 5
65
+ damage: 1d6
66
+ damage_type: slashing
67
+ meta:
68
+ noise_source: 5
69
+ noise_target: 5
70
+ modifiers: null
71
+ name: Handaxe
72
+ proficiency_type:
73
+ - simple
74
+ properties:
75
+ - light
76
+ - thrown
77
+ range: 5
78
+ subtype: weapon
79
+ thrown:
80
+ range: 30
81
+ range_max: 60
82
+ type: melee_attack
83
+ weight: 10
84
+ javelin:
85
+ cost: 5sp
86
+ damage: 1d6
87
+ damage_type: piercing
88
+ meta:
89
+ noise_source: 5
90
+ noise_target: 5
91
+ modifiers: null
92
+ name: Javelin
93
+ proficiency_type:
94
+ - simple
95
+ properties:
96
+ - thrown
97
+ range: 5
98
+ subtype: weapon
99
+ thrown:
100
+ range: 30
101
+ range_max: 120
102
+ type: melee_attack
103
+ weight: 2
104
+ light_crossbow:
105
+ ammo: bolts
106
+ cost: 25
107
+ damage: 1d8
108
+ damage_type: piercing
109
+ meta:
110
+ noise_source: 5
111
+ noise_target: 5
112
+ modifiers: null
113
+ name: Light Crossbow
114
+ proficiency_type:
115
+ - simple
116
+ properties:
117
+ - loading
118
+ - ammunition
119
+ - ranged
120
+ - two_handed
121
+ range: 80
122
+ range_max: 320
123
+ subtype: weapon
124
+ type: ranged_attack
125
+ weight: 2
126
+ longbow:
127
+ ammo: arrows
128
+ cost: 50
129
+ damage: 1d8
130
+ damage_type: piercing
131
+ meta:
132
+ noise_source: 5
133
+ noise_target: 5
134
+ modifiers: null
135
+ name: Longbow
136
+ proficiency_type:
137
+ - martial
138
+ properties:
139
+ - heavy
140
+ - ammunition
141
+ - ranged
142
+ range: 150
143
+ range_max: 600
144
+ subtype: weapon
145
+ type: ranged_attack
146
+ weight: 2
147
+ longsword:
148
+ cost: 15gp
149
+ damage: 1d8
150
+ damage_2: 1d10
151
+ damage_type: slashing
152
+ meta:
153
+ noise_source: 5
154
+ noise_target: 5
155
+ modifiers: null
156
+ name: Longsword
157
+ proficiency_type:
158
+ - martial
159
+ properties:
160
+ - versatile
161
+ range: 5
162
+ subtype: weapon
163
+ type: melee_attack
164
+ weight: 3
165
+ rapier:
166
+ cost: 25
167
+ damage: 1d8
168
+ damage_type: piercing
169
+ meta:
170
+ noise_source: 5
171
+ noise_target: 5
172
+ modifiers: null
173
+ name: Rapier
174
+ proficiency_type:
175
+ - martial
176
+ properties:
177
+ - finesse
178
+ range: 5
179
+ subtype: weapon
180
+ type: melee_attack
181
+ weight: 2
182
+ scimitar:
183
+ cost: 25
184
+ damage: 1d6
185
+ damage_type: slashing
186
+ meta:
187
+ noise_source: 5
188
+ noise_target: 5
189
+ modifiers: null
190
+ name: Scimitar
191
+ proficiency_type:
192
+ - martial
193
+ properties:
194
+ - finesse
195
+ - light
196
+ range: 5
197
+ subtype: weapon
198
+ type: melee_attack
199
+ weight: 3
200
+ shortbow:
201
+ ammo: arrows
202
+ cost: 25
203
+ damage: 1d6
204
+ damage_type: piercing
205
+ meta:
206
+ noise_source: 5
207
+ noise_target: 5
208
+ modifiers: null
209
+ name: Shortbow
210
+ proficiency_type:
211
+ - martial
212
+ properties:
213
+ - ammunition
214
+ - ranged
215
+ range: 80
216
+ range_max: 320
217
+ subtype: weapon
218
+ type: ranged_attack
219
+ weight: 2
220
+ spear:
221
+ cost: 5sp
222
+ damage: 1d6
223
+ damage_2: 1d8
224
+ damage_type: piercing
225
+ meta:
226
+ noise_source: 5
227
+ noise_target: 5
228
+ modifiers: null
229
+ name: Spear
230
+ proficiency_type:
231
+ - simple
232
+ properties:
233
+ - thrown
234
+ - versatile
235
+ range: 5
236
+ subtype: weapon
237
+ thrown:
238
+ range: 20
239
+ range_max: 60
240
+ type: melee_attack
241
+ weight: 2
242
+ torch:
243
+ cost: 0
244
+ damage: 1
245
+ damage_type: fire
246
+ description: Provides bright light in a 20-foot radius and dim light for an additional 20 feet. If you make a melee attack with a burning torch and hit, it deals 1 fire damage
247
+ light:
248
+ bright: 20
249
+ dim: 20
250
+ meta:
251
+ noise_source: 5
252
+ noise_target: 5
253
+ modifiers: null
254
+ name: Torch
255
+ proficiency_type:
256
+ - martial
257
+ properties: null
258
+ range: 5
259
+ subtype: weapon
260
+ type: melee_attack
261
+ weight: 0
262
+ unarmed_attack:
263
+ cost: 0
264
+ damage: 1
265
+ damage_type: bludgeoning
266
+ meta:
267
+ noise_source: 5
268
+ noise_target: 5
269
+ modifiers: null
270
+ name: Unarmed Attack
271
+ properties: null
272
+ range: 5
273
+ subtype: weapon
274
+ type: melee_attack
275
+ weight: 0
276
+ vicious_rapier:
277
+ bonus:
278
+ additional:
279
+ die: 2d6
280
+ restriction: nat20_attack
281
+ cost: 10
282
+ damage: 1d8
283
+ damage_type: piercing
284
+ meta:
285
+ noise_source: 5
286
+ noise_target: 5
287
+ modifiers: null
288
+ name: Vicious Rapier
289
+ proficiency_type:
290
+ - martial
291
+ properties:
292
+ - finesse
293
+ range: 5
294
+ rarity: very_rare
295
+ subtype: weapon
296
+ type: melee_attack
297
+ weight: 2
data/lib/natural_20.rb ADDED
@@ -0,0 +1,68 @@
1
+ # typed: strict
2
+ require 'natural_20/version'
3
+ require 'natural_20/session'
4
+ require 'colorize'
5
+ require 'natural_20/die_roll'
6
+ require 'natural_20/concerns/notable'
7
+ require 'natural_20/concerns/container'
8
+ require 'natural_20/concerns/lootable'
9
+ require 'natural_20/concerns/evaluator/entity_state_evaluator'
10
+ require 'natural_20/concerns/entity'
11
+ require 'natural_20/item_library/object'
12
+ require 'natural_20/concerns/movement_helper'
13
+ require 'natural_20/utils/cover'
14
+ require 'natural_20/utils/weapons'
15
+ require 'natural_20/concerns/navigation'
16
+ require 'natural_20/actions/action'
17
+ require 'natural_20/concerns/fighter_class'
18
+ require 'natural_20/concerns/rogue_class'
19
+ require 'natural_20/actions/concerns/action_damage'
20
+ require 'natural_20/actions/look_action'
21
+ require 'natural_20/actions/attack_action'
22
+ require 'natural_20/actions/multiattack_action'
23
+ require 'natural_20/actions/dodge_action'
24
+ require 'natural_20/actions/short_rest_action'
25
+ require 'natural_20/actions/help_action'
26
+ require 'natural_20/actions/disengage_action'
27
+ require 'natural_20/actions/move_action'
28
+ require 'natural_20/actions/dash_action'
29
+ require 'natural_20/actions/use_item_action'
30
+ require 'natural_20/actions/interact_action'
31
+ require 'natural_20/actions/inventory_action'
32
+ require 'natural_20/actions/hide_action'
33
+ require 'natural_20/actions/prone_action'
34
+ require 'natural_20/actions/stand_action'
35
+ require 'natural_20/actions/grapple_action'
36
+ require 'natural_20/actions/escape_grapple_action'
37
+ require 'natural_20/actions/ground_interact_action'
38
+ require 'natural_20/actions/first_aid_action'
39
+ require 'natural_20/actions/shove_action'
40
+ require 'natural_20/battle'
41
+ require 'natural_20/utils/ray_tracer'
42
+ require 'natural_20/battle_map'
43
+ require 'natural_20/cli/map_renderer'
44
+ require 'natural_20/event_manager'
45
+ require 'natural_20/concerns/health_flavor'
46
+ require 'natural_20/concerns/multiattack'
47
+ require 'natural_20/player_character'
48
+ require 'natural_20/npc'
49
+ require 'natural_20/controller'
50
+ require 'natural_20/ai_controller/path_compute'
51
+ require 'natural_20/ai_controller/standard'
52
+ require 'natural_20/item_library/base_item'
53
+ require 'natural_20/item_library/healing_potion'
54
+ require 'natural_20/item_library/door_object'
55
+ require 'natural_20/item_library/pit_trap'
56
+ require 'natural_20/item_library/stone_wall'
57
+ require 'natural_20/item_library/chest'
58
+ require 'natural_20/item_library/ground'
59
+ require 'natural_20/utils/static_light_builder'
60
+ require 'active_support'
61
+ require 'active_support/all'
62
+ require 'yaml'
63
+
64
+ module Natural20
65
+ class Error < StandardError; end
66
+
67
+ # Your code goes here...
68
+ end
@@ -0,0 +1,40 @@
1
+ # typed: true
2
+ module Natural20
3
+ class Action
4
+ attr_reader :action_type, :result, :source, :session, :errors
5
+
6
+ def initialize(session, source, action_type, opts = {})
7
+ @source = source
8
+ @session = session
9
+ @action_type = action_type
10
+ @errors = []
11
+ @result = []
12
+ @opts = opts
13
+ end
14
+
15
+ def name
16
+ @action_type.to_s
17
+ end
18
+
19
+ def to_s
20
+ @action_type.to_s.humanize
21
+ end
22
+
23
+ def label
24
+ I18n.t(:"action.#{action_type}")
25
+ end
26
+
27
+ def validate
28
+ end
29
+
30
+ def apply!(battle); end
31
+
32
+ def resolve(session, map, opts = {}); end
33
+
34
+ protected
35
+
36
+ def t(k, options = {})
37
+ I18n.t(k, options)
38
+ end
39
+ end
40
+ end