tormenta20 0.2.2 → 0.2.5

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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/db/schema.sql +30 -0
  3. data/db/seeds.rb +2 -1
  4. data/db/tormenta20.sqlite3 +0 -0
  5. data/exe/tormenta20 +377 -0
  6. data/src/json/poderes/habilidades_de_raca/aggelus/heranca_divina.json +11 -0
  7. data/src/json/poderes/habilidades_de_raca/aggelus/luz_sagrada.json +14 -0
  8. data/src/json/poderes/habilidades_de_raca/anao/conhecimento_das_rochas.json +14 -0
  9. data/src/json/poderes/habilidades_de_raca/anao/devagar_e_sempre.json +12 -0
  10. data/src/json/poderes/habilidades_de_raca/anao/duro_como_pedra.json +10 -0
  11. data/src/json/poderes/habilidades_de_raca/anao/tradicao_de_heredrimm.json +11 -0
  12. data/src/json/poderes/habilidades_de_raca/dahllan/amiga_das_plantas.json +11 -0
  13. data/src/json/poderes/habilidades_de_raca/dahllan/armadura_de_allihanna.json +15 -0
  14. data/src/json/poderes/habilidades_de_raca/dahllan/empatia_selvagem_dahllan.json +12 -0
  15. data/src/json/poderes/habilidades_de_raca/elfo/graca_de_glorienn.json +10 -0
  16. data/src/json/poderes/habilidades_de_raca/elfo/sangue_magico.json +10 -0
  17. data/src/json/poderes/habilidades_de_raca/elfo/sentidos_elficos.json +14 -0
  18. data/src/json/poderes/habilidades_de_raca/goblin/engenhoso.json +11 -0
  19. data/src/json/poderes/habilidades_de_raca/goblin/espelunqueiro.json +11 -0
  20. data/src/json/poderes/habilidades_de_raca/goblin/peste_esguia.json +11 -0
  21. data/src/json/poderes/habilidades_de_raca/goblin/rato_das_ruas.json +11 -0
  22. data/src/json/poderes/habilidades_de_raca/golem/chassi.json +14 -0
  23. data/src/json/poderes/habilidades_de_raca/golem/criatura_artificial.json +14 -0
  24. data/src/json/poderes/habilidades_de_raca/golem/fonte_elemental.json +12 -0
  25. data/src/json/poderes/habilidades_de_raca/golem/proposito_de_criacao.json +11 -0
  26. data/src/json/poderes/habilidades_de_raca/humano/versatil.json +11 -0
  27. data/src/json/poderes/habilidades_de_raca/hynne/arremessador.json +11 -0
  28. data/src/json/poderes/habilidades_de_raca/hynne/pequeno_e_rechonchudo.json +13 -0
  29. data/src/json/poderes/habilidades_de_raca/hynne/sorte_salvadora.json +11 -0
  30. data/src/json/poderes/habilidades_de_raca/kliren/engenhosidade.json +13 -0
  31. data/src/json/poderes/habilidades_de_raca/kliren/hibrido.json +10 -0
  32. data/src/json/poderes/habilidades_de_raca/kliren/ossos_frageis.json +12 -0
  33. data/src/json/poderes/habilidades_de_raca/kliren/vanguardista.json +12 -0
  34. data/src/json/poderes/habilidades_de_raca/lefou/cria_da_tormenta.json +11 -0
  35. data/src/json/poderes/habilidades_de_raca/lefou/deformidade.json +11 -0
  36. data/src/json/poderes/habilidades_de_raca/medusa/cria_de_megalokk.json +11 -0
  37. data/src/json/poderes/habilidades_de_raca/medusa/natureza_venenosa.json +15 -0
  38. data/src/json/poderes/habilidades_de_raca/medusa/olhar_atordoante.json +16 -0
  39. data/src/json/poderes/habilidades_de_raca/minotauro/chifres.json +11 -0
  40. data/src/json/poderes/habilidades_de_raca/minotauro/couro_rigido.json +10 -0
  41. data/src/json/poderes/habilidades_de_raca/minotauro/faro.json +14 -0
  42. data/src/json/poderes/habilidades_de_raca/minotauro/medo_de_altura.json +11 -0
  43. data/src/json/poderes/habilidades_de_raca/osteon/armadura_ossea.json +10 -0
  44. data/src/json/poderes/habilidades_de_raca/osteon/memoria_postuma.json +10 -0
  45. data/src/json/poderes/habilidades_de_raca/osteon/natureza_esqueletica.json +14 -0
  46. data/src/json/poderes/habilidades_de_raca/osteon/preco_da_nao_vida.json +12 -0
  47. data/src/json/poderes/habilidades_de_raca/qareen/desejos.json +11 -0
  48. data/src/json/poderes/habilidades_de_raca/qareen/resistencia_elemental.json +12 -0
  49. data/src/json/poderes/habilidades_de_raca/qareen/tatuagem_mistica.json +13 -0
  50. data/src/json/poderes/habilidades_de_raca/sereia_tritao/cancao_dos_mares.json +13 -0
  51. data/src/json/poderes/habilidades_de_raca/sereia_tritao/mestre_do_tridente.json +11 -0
  52. data/src/json/poderes/habilidades_de_raca/sereia_tritao/transformacao_anfibia.json +13 -0
  53. data/src/json/poderes/habilidades_de_raca/silfide/asas_de_borboleta.json +15 -0
  54. data/src/json/poderes/habilidades_de_raca/silfide/espirito_da_natureza.json +12 -0
  55. data/src/json/poderes/habilidades_de_raca/silfide/magia_das_fadas.json +13 -0
  56. data/src/json/poderes/habilidades_de_raca/sulfure/sombras_profanas.json +14 -0
  57. data/src/json/poderes/habilidades_de_raca/trog/mau_cheiro.json +17 -0
  58. data/src/json/poderes/habilidades_de_raca/trog/mordida.json +17 -0
  59. data/src/json/poderes/habilidades_de_raca/trog/reptiliano.json +13 -0
  60. data/src/json/poderes/habilidades_de_raca/trog/sangue_frio.json +12 -0
  61. data/src/json/racas/aggelus.json +14 -0
  62. data/src/json/racas/anao.json +14 -0
  63. data/src/json/racas/dahllan.json +14 -0
  64. data/src/json/racas/elfo.json +14 -0
  65. data/src/json/racas/goblin.json +14 -0
  66. data/src/json/racas/golem.json +14 -0
  67. data/src/json/racas/humano.json +14 -0
  68. data/src/json/racas/hynne.json +14 -0
  69. data/src/json/racas/kliren.json +14 -0
  70. data/src/json/racas/lefou.json +14 -0
  71. data/src/json/racas/medusa.json +14 -0
  72. data/src/json/racas/minotauro.json +14 -0
  73. data/src/json/racas/osteon.json +14 -0
  74. data/src/json/racas/qareen.json +14 -0
  75. data/src/json/racas/sereia_tritao.json +14 -0
  76. data/src/json/racas/silfide.json +14 -0
  77. data/src/json/racas/sulfure.json +14 -0
  78. data/src/json/racas/trog.json +14 -0
  79. data/src/ruby/tormenta20/database.rb +78 -142
  80. data/src/ruby/tormenta20/models/poder.rb +1 -0
  81. data/src/ruby/tormenta20/models/raca.rb +56 -0
  82. data/src/ruby/tormenta20/seeder.rb +68 -1
  83. data/src/ruby/tormenta20/version.rb +1 -1
  84. data/src/ruby/tormenta20.rb +17 -11
  85. metadata +78 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 775c13dccef6b13bcd76ea3efc8e2cf8b4c5221faf4fb73dffce3ce9b265a101
4
- data.tar.gz: 88618dbc1c4c5d1e6c6e9127e39b1c2726423bf79b0c8229452dc5c767273d0f
3
+ metadata.gz: b24c5c0b45a93669579cee0ee5400058204694646c0851be0aef6b51b3caac7d
4
+ data.tar.gz: eb227d9f765054b9185ef4ad087444750e341f251b7c48327d7f13a160ac96a6
5
5
  SHA512:
6
- metadata.gz: 759238af753ee81ef3619f372a7938c6a8a656988d63dca357bf997fdbe2dea6df45a2a1dbda5fc5374a4e49f52cb07c71f30d1ce33435e86a88332da4aa8f39
7
- data.tar.gz: d3ead8b84ef084bdd77c6399d1b92fcafb8773cacd0b6a965bab9437356657246121ff880af605172baf6f2e129956a235ea8fc9566b6b21e37bcd01557ce91e
6
+ metadata.gz: f9766b54c3bfb6497a3d00275fdb9d2e451516dbfa9963a90e4eba90e867c40a98d9f00715e14c7953b48f1476683e8467563d4a4843f401c583d416fd5fee86
7
+ data.tar.gz: dbb192885cc775992d888de4f357812d9609a8b2ce5237cca68bbd759fdd0795f6a32983293c619e444378d50be2b0eaedb9c1948401a0f8ee4459aed099c730
data/db/schema.sql CHANGED
@@ -38,6 +38,7 @@ CREATE TABLE IF NOT EXISTS poderes (
38
38
  'poder_concedido',
39
39
  'poder_tormenta',
40
40
  'poder_classe',
41
+ 'habilidade_de_raca',
41
42
  'poder_geral',
42
43
  'poder_combate',
43
44
  'poder_destino',
@@ -47,6 +48,7 @@ CREATE TABLE IF NOT EXISTS poderes (
47
48
  effects JSON DEFAULT '{}',
48
49
  prerequisites JSON DEFAULT '[]',
49
50
  origin_id TEXT,
51
+ class_id TEXT,
50
52
  deities JSON DEFAULT '[]',
51
53
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
52
54
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
@@ -345,6 +347,34 @@ BEGIN
345
347
  UPDATE regras SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
346
348
  END;
347
349
 
350
+ -- -----------------------------------------------------------------------------
351
+ -- RAÇAS (Playable Races)
352
+ -- -----------------------------------------------------------------------------
353
+ CREATE TABLE IF NOT EXISTS racas (
354
+ id TEXT PRIMARY KEY,
355
+ name TEXT NOT NULL,
356
+ description TEXT,
357
+ size TEXT NOT NULL DEFAULT 'médio',
358
+ movement INTEGER NOT NULL DEFAULT 9,
359
+ vision TEXT DEFAULT 'normal',
360
+ vision_range INTEGER,
361
+ attribute_bonuses JSON DEFAULT '{}',
362
+ skill_bonuses JSON DEFAULT '[]',
363
+ racial_abilities JSON DEFAULT '[]',
364
+ chosen_abilities_amount INTEGER DEFAULT 0,
365
+ available_chosen_abilities JSON DEFAULT '[]',
366
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
367
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
368
+ );
369
+
370
+ CREATE INDEX IF NOT EXISTS idx_racas_name ON racas(name);
371
+
372
+ CREATE TRIGGER IF NOT EXISTS update_racas_timestamp
373
+ AFTER UPDATE ON racas
374
+ BEGIN
375
+ UPDATE racas SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
376
+ END;
377
+
348
378
  -- =============================================================================
349
379
  -- VIEWS ÚTEIS
350
380
  -- =============================================================================
data/db/seeds.rb CHANGED
@@ -372,6 +372,7 @@ end
372
372
 
373
373
  # Run seeds if this file is executed directly
374
374
  if __FILE__ == $PROGRAM_NAME
375
- Tormenta20::Database.setup(mode: :build)
375
+ ENV["TORMENTA20_DB_MODE"] = "create_on_build"
376
+ Tormenta20::Database.setup
376
377
  Tormenta20::Seeds.import_all
377
378
  end
Binary file
data/exe/tormenta20 ADDED
@@ -0,0 +1,377 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "optparse"
5
+ require "fileutils"
6
+
7
+ # CLI for managing the Tormenta20 database
8
+ module Tormenta20CLI
9
+ class << self
10
+ def run(args)
11
+ options = parse_options(args)
12
+ command = args.shift || "help"
13
+
14
+ case command
15
+ when "build"
16
+ build_database(options)
17
+ when "seed"
18
+ seed_data(options)
19
+ when "reset"
20
+ reset_database(options)
21
+ when "info"
22
+ show_info(options)
23
+ when "export"
24
+ export_json(options)
25
+ when "import"
26
+ import_json(options)
27
+ when "help", "--help", "-h"
28
+ show_help
29
+ else
30
+ puts "Unknown command: #{command}"
31
+ show_help
32
+ exit 1
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def parse_options(args)
39
+ options = {}
40
+
41
+ OptionParser.new do |opts|
42
+ opts.banner = "Usage: tormenta20 <command> [options]"
43
+
44
+ opts.on("-p", "--path PATH", "Database path") do |path|
45
+ options[:path] = path
46
+ end
47
+
48
+ opts.on("-t", "--tables TABLES", "Comma-separated tables to seed") do |tables|
49
+ options[:tables] = tables.split(",").map(&:strip)
50
+ end
51
+
52
+ opts.on("-j", "--json PATH", "JSON file or directory path") do |path|
53
+ options[:json_path] = path
54
+ end
55
+
56
+ opts.on("-o", "--output PATH", "Output path for export") do |path|
57
+ options[:output] = path
58
+ end
59
+
60
+ opts.on("-v", "--verbose", "Verbose output") do
61
+ options[:verbose] = true
62
+ end
63
+
64
+ opts.on("-f", "--force", "Force overwrite") do
65
+ options[:force] = true
66
+ end
67
+ end.parse!(args)
68
+
69
+ options
70
+ end
71
+
72
+ def setup_env(options)
73
+ if options[:path]
74
+ ENV["TORMENTA20_DB_MODE"] = "path"
75
+ ENV["TORMENTA20_DB_PATH"] = File.expand_path(options[:path])
76
+ else
77
+ ENV["TORMENTA20_DB_MODE"] = "create_on_build"
78
+ end
79
+
80
+ require "tormenta20"
81
+ end
82
+
83
+ def build_database(options)
84
+ puts "Building database..."
85
+
86
+ if options[:path]
87
+ path = File.expand_path(options[:path])
88
+ FileUtils.rm_f(path) if options[:force] && File.exist?(path)
89
+
90
+ if File.exist?(path) && !options[:force]
91
+ puts "Database already exists at #{path}"
92
+ puts "Use --force to overwrite"
93
+ exit 1
94
+ end
95
+
96
+ ENV["TORMENTA20_DB_MODE"] = "path"
97
+ ENV["TORMENTA20_DB_PATH"] = path
98
+ else
99
+ ENV["TORMENTA20_DB_MODE"] = "create_on_build"
100
+ end
101
+
102
+ require "tormenta20"
103
+
104
+ # Force rebuild
105
+ Tormenta20::Database.disconnect if Tormenta20::Database.connected?
106
+ FileUtils.rm_f(Tormenta20::Database.db_path) if options[:force]
107
+
108
+ Tormenta20::Database.send(:ensure_database_exists)
109
+ Tormenta20::Database.send(:connect_to_database)
110
+
111
+ puts "Database built at: #{Tormenta20::Database.db_path}"
112
+ show_summary
113
+ end
114
+
115
+ def seed_data(options)
116
+ setup_env(options)
117
+
118
+ tables = options[:tables] || all_tables
119
+
120
+ puts "Seeding tables: #{tables.join(", ")}"
121
+
122
+ tables.each do |table|
123
+ seed_table(table, options)
124
+ end
125
+
126
+ show_summary
127
+ end
128
+
129
+ def reset_database(options)
130
+ setup_env(options)
131
+
132
+ puts "Resetting database..."
133
+ Tormenta20::Database.reset
134
+ puts "Database reset complete."
135
+ show_summary
136
+ end
137
+
138
+ def show_info(options)
139
+ setup_env(options)
140
+
141
+ puts "Tormenta20 Database Info"
142
+ puts "=" * 40
143
+ puts "Mode: #{Tormenta20::Database.mode}"
144
+ puts "Path: #{Tormenta20::Database.db_path}"
145
+ puts "Connected: #{Tormenta20::Database.connected?}"
146
+ puts ""
147
+ show_summary
148
+ end
149
+
150
+ def export_json(options)
151
+ setup_env(options)
152
+
153
+ output_dir = options[:output] || "./export"
154
+ tables = options[:tables] || all_tables
155
+
156
+ FileUtils.mkdir_p(output_dir)
157
+
158
+ tables.each do |table|
159
+ export_table(table, output_dir, options)
160
+ end
161
+
162
+ puts "Exported to: #{output_dir}"
163
+ end
164
+
165
+ def import_json(options)
166
+ setup_env(options)
167
+
168
+ json_path = options[:json_path]
169
+ unless json_path
170
+ puts "Error: --json PATH is required"
171
+ exit 1
172
+ end
173
+
174
+ if File.directory?(json_path)
175
+ import_directory(json_path, options)
176
+ elsif File.file?(json_path)
177
+ import_file(json_path, options)
178
+ else
179
+ puts "Error: Path not found: #{json_path}"
180
+ exit 1
181
+ end
182
+ end
183
+
184
+ def show_help
185
+ puts <<~HELP
186
+ Tormenta20 Database CLI
187
+
188
+ Usage: tormenta20 <command> [options]
189
+
190
+ Commands:
191
+ build Build/rebuild the database from JSON files
192
+ seed Seed specific tables
193
+ reset Reset the database (delete and rebuild)
194
+ info Show database information
195
+ export Export data to JSON files
196
+ import Import JSON file(s) into the database
197
+ help Show this help
198
+
199
+ Options:
200
+ -p, --path PATH Custom database path
201
+ -t, --tables TABLES Comma-separated tables (origens,classes,magias,...)
202
+ -j, --json PATH JSON file or directory to import
203
+ -o, --output PATH Output directory for export
204
+ -v, --verbose Verbose output
205
+ -f, --force Force overwrite existing files
206
+
207
+ Tables:
208
+ origens, poderes, divindades, classes, magias,
209
+ armas, armaduras, escudos, itens,
210
+ materiais_especiais, melhorias, regras
211
+
212
+ Examples:
213
+ tormenta20 build # Build with default path
214
+ tormenta20 build -p ./my.db -f # Build at custom path
215
+ tormenta20 seed -t magias,classes # Seed only specific tables
216
+ tormenta20 import -j ./custom_spell.json # Import a JSON file
217
+ tormenta20 export -o ./backup # Export all to JSON
218
+ tormenta20 info # Show database info
219
+ HELP
220
+ end
221
+
222
+ def all_tables
223
+ %w[origens poderes divindades classes magias armas armaduras escudos itens materiais_especiais melhorias regras]
224
+ end
225
+
226
+ def seed_table(table, options)
227
+ print " Seeding #{table}..."
228
+
229
+ case table
230
+ when "origens"
231
+ Tormenta20::Seeder.send(:seed_origens)
232
+ when "poderes"
233
+ Tormenta20::Seeder.send(:seed_poderes_habilidades_unicas)
234
+ Tormenta20::Seeder.send(:seed_poderes_concedidos)
235
+ Tormenta20::Seeder.send(:seed_poderes_tormenta)
236
+ when "divindades"
237
+ Tormenta20::Seeder.send(:seed_divindades)
238
+ when "classes"
239
+ Tormenta20::Seeder.send(:seed_classes)
240
+ when "magias"
241
+ Tormenta20::Seeder.send(:seed_magias)
242
+ when "armas"
243
+ Tormenta20::Seeder.send(:seed_armas)
244
+ when "armaduras"
245
+ Tormenta20::Seeder.send(:seed_armaduras)
246
+ when "escudos"
247
+ Tormenta20::Seeder.send(:seed_escudos)
248
+ when "itens"
249
+ Tormenta20::Seeder.send(:seed_itens)
250
+ when "materiais_especiais"
251
+ Tormenta20::Seeder.send(:seed_materiais_especiais)
252
+ when "melhorias"
253
+ Tormenta20::Seeder.send(:seed_melhorias)
254
+ when "regras"
255
+ Tormenta20::Seeder.send(:seed_regras)
256
+ else
257
+ puts " unknown table"
258
+ return
259
+ end
260
+
261
+ puts " done"
262
+ end
263
+
264
+ def export_table(table, output_dir, options)
265
+ model = table_to_model(table)
266
+ return unless model
267
+
268
+ table_dir = File.join(output_dir, table)
269
+ FileUtils.mkdir_p(table_dir)
270
+
271
+ count = 0
272
+ model.find_each do |record|
273
+ file_path = File.join(table_dir, "#{record.id}.json")
274
+ File.write(file_path, JSON.pretty_generate(record.to_h))
275
+ count += 1
276
+ end
277
+
278
+ puts " Exported #{count} #{table}" if options[:verbose]
279
+ end
280
+
281
+ def import_directory(dir_path, options)
282
+ Dir.glob(File.join(dir_path, "**/*.json")).each do |file|
283
+ import_file(file, options)
284
+ end
285
+ end
286
+
287
+ def import_file(file_path, options)
288
+ data = JSON.parse(File.read(file_path), symbolize_names: true)
289
+
290
+ # Try to determine the table from the file path or data
291
+ table = detect_table(file_path, data)
292
+ model = table_to_model(table)
293
+
294
+ unless model
295
+ puts " Skipping #{file_path}: unknown table"
296
+ return
297
+ end
298
+
299
+ record = model.find_or_initialize_by(id: data[:id])
300
+ data.each do |key, value|
301
+ record.send("#{key}=", value) if record.respond_to?("#{key}=")
302
+ end
303
+ record.save!
304
+
305
+ puts " Imported #{data[:id]} into #{table}" if options[:verbose]
306
+ rescue StandardError => e
307
+ puts " Error importing #{file_path}: #{e.message}"
308
+ end
309
+
310
+ def detect_table(file_path, data)
311
+ # Try to detect from path
312
+ path_parts = file_path.split("/")
313
+ possible_tables = all_tables
314
+
315
+ path_parts.each do |part|
316
+ return part if possible_tables.include?(part)
317
+ end
318
+
319
+ # Try to detect from data structure
320
+ return "magias" if data[:circle] && data[:school]
321
+ return "classes" if data[:hit_points] && data[:abilities]
322
+ return "divindades" if data[:energy] && data[:granted_powers]
323
+ return "origens" if data[:benefits] && data[:unique_power]
324
+ return "armas" if data[:damage] && data[:critical]
325
+ return "armaduras" if data[:defense_bonus] && data[:category]
326
+ return "escudos" if data[:defense_bonus] && !data[:category]
327
+
328
+ nil
329
+ end
330
+
331
+ def table_to_model(table)
332
+ case table
333
+ when "origens" then Tormenta20::Models::Origem
334
+ when "poderes" then Tormenta20::Models::Poder
335
+ when "divindades" then Tormenta20::Models::Divindade
336
+ when "classes" then Tormenta20::Models::Classe
337
+ when "magias" then Tormenta20::Models::Magia
338
+ when "armas" then Tormenta20::Models::Arma
339
+ when "armaduras" then Tormenta20::Models::Armadura
340
+ when "escudos" then Tormenta20::Models::Escudo
341
+ when "itens" then Tormenta20::Models::Item
342
+ when "materiais_especiais" then Tormenta20::Models::MaterialEspecial
343
+ when "melhorias" then Tormenta20::Models::Melhoria
344
+ when "regras" then Tormenta20::Models::Regra
345
+ end
346
+ end
347
+
348
+ def show_summary
349
+ puts ""
350
+ puts "Database Summary:"
351
+ puts "-" * 40
352
+
353
+ {
354
+ "Origens" => Tormenta20::Models::Origem,
355
+ "Poderes" => Tormenta20::Models::Poder,
356
+ "Divindades" => Tormenta20::Models::Divindade,
357
+ "Classes" => Tormenta20::Models::Classe,
358
+ "Magias" => Tormenta20::Models::Magia,
359
+ "Armas" => Tormenta20::Models::Arma,
360
+ "Armaduras" => Tormenta20::Models::Armadura,
361
+ "Escudos" => Tormenta20::Models::Escudo,
362
+ "Itens" => Tormenta20::Models::Item,
363
+ "Materiais Especiais" => Tormenta20::Models::MaterialEspecial,
364
+ "Melhorias" => Tormenta20::Models::Melhoria,
365
+ "Regras" => Tormenta20::Models::Regra
366
+ }.each do |name, model|
367
+ printf " %-20s %d\n", "#{name}:", model.count
368
+ rescue StandardError
369
+ printf " %-20s %s\n", "#{name}:", "N/A"
370
+ end
371
+
372
+ puts "-" * 40
373
+ end
374
+ end
375
+ end
376
+
377
+ Tormenta20CLI.run(ARGV)
@@ -0,0 +1,11 @@
1
+ {
2
+ "id": "heranca_divina",
3
+ "name": "Herança Divina",
4
+ "type": "habilidade_de_raca",
5
+ "race": "suraggel",
6
+ "description": "Você é uma criatura do tipo espírito e recebe visão no escuro.",
7
+ "effects": {
8
+ "creature_type": "espírito",
9
+ "vision": "visao_no_escuro"
10
+ }
11
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "id": "luz_sagrada",
3
+ "name": "Luz Sagrada",
4
+ "type": "habilidade_de_raca",
5
+ "race": "aggelus",
6
+ "description": "Você recebe +2 em Diplomacia e Intuição. Além disso, pode lançar Luz (como uma magia divina; atributo-chave Carisma). Caso aprenda novamente essa magia, seu custo diminui em –1 PM.",
7
+ "effects": {
8
+ "skill_bonus": { "diplomacia": 2, "intuicao": 2 },
9
+ "spell": "luz",
10
+ "spell_type": "divina",
11
+ "spellcasting_attribute": "carisma",
12
+ "pm_discount_if_relearned": 1
13
+ }
14
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "id": "conhecimento_das_rochas",
3
+ "name": "Conhecimento das Rochas",
4
+ "type": "habilidade_de_raca",
5
+ "race": "anao",
6
+ "description": "Você recebe visão no escuro e +2 em testes de Percepção e Sobrevivência realizados no subterrâneo.",
7
+ "effects": {
8
+ "vision": "visao_no_escuro",
9
+ "skill_bonus": [
10
+ { "skill": "percepcao", "value": 2, "condition": "subterraneo" },
11
+ { "skill": "sobrevivencia", "value": 2, "condition": "subterraneo" }
12
+ ]
13
+ }
14
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "id": "devagar_e_sempre",
3
+ "name": "Devagar e Sempre",
4
+ "type": "habilidade_de_raca",
5
+ "race": "anao",
6
+ "description": "Seu deslocamento é 6m (em vez de 9m). Porém, seu deslocamento não é reduzido por uso de armadura ou excesso de carga.",
7
+ "effects": {
8
+ "movement_override": 6,
9
+ "ignore_armor_movement_penalty": true,
10
+ "ignore_encumbrance_movement_penalty": true
11
+ }
12
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "duro_como_pedra",
3
+ "name": "Duro como Pedra",
4
+ "type": "habilidade_de_raca",
5
+ "race": "anao",
6
+ "description": "Você recebe +3 pontos de vida no 1º nível e +1 por nível seguinte.",
7
+ "effects": {
8
+ "hp_bonus": { "at_level_1": 3, "per_level_after": 1 }
9
+ }
10
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "id": "tradicao_de_heredrimm",
3
+ "name": "Tradição de Heredrimm",
4
+ "type": "habilidade_de_raca",
5
+ "race": "anao",
6
+ "description": "Para você, todos os machados, martelos, marretas e picaretas são armas simples. Você recebe +2 em ataques com essas armas.",
7
+ "effects": {
8
+ "weapon_proficiency": ["machados", "martelos", "marretas", "picaretas"],
9
+ "attack_bonus": { "value": 2, "weapon_types": ["machados", "martelos", "marretas", "picaretas"] }
10
+ }
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "id": "amiga_das_plantas",
3
+ "name": "Amiga das Plantas",
4
+ "type": "habilidade_de_raca",
5
+ "race": "dahllan",
6
+ "description": "Você pode lançar a magia Controlar Plantas (atributo-chave Sabedoria). Caso aprenda novamente essa magia, seu custo diminui em –1 PM.",
7
+ "effects": {
8
+ "innate_spell": { "spell": "controlar_plantas", "attribute": "sabedoria" },
9
+ "spell_cost_reduction": { "spell": "controlar_plantas", "value": 1, "condition": "learned_again" }
10
+ }
11
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "id": "armadura_de_allihanna",
3
+ "name": "Armadura de Allihanna",
4
+ "type": "habilidade_de_raca",
5
+ "race": "dahllan",
6
+ "description": "Você pode gastar uma ação de movimento e 1 PM para transformar sua pele em casca de árvore, recebendo +2 na Defesa até o fim da cena.",
7
+ "effects": {
8
+ "activated": {
9
+ "action": "movimento",
10
+ "cost_pm": 1,
11
+ "defense_bonus": 2,
12
+ "duration": "cena"
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "id": "empatia_selvagem_dahllan",
3
+ "name": "Empatia Selvagem",
4
+ "type": "habilidade_de_raca",
5
+ "race": "dahllan",
6
+ "description": "Você pode se comunicar com animais por meio de linguagem corporal e vocalizações. Você pode usar Adestramento para mudar atitude e persuasão com animais. Caso receba esta habilidade novamente, recebe +2 em Adestramento.",
7
+ "effects": {
8
+ "animal_communication": true,
9
+ "skill_use": { "skill": "adestramento", "for": "animais" },
10
+ "stackable_bonus": { "skill": "adestramento", "value": 2, "condition": "received_again" }
11
+ }
12
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "graca_de_glorienn",
3
+ "name": "Graça de Glórienn",
4
+ "type": "habilidade_de_raca",
5
+ "race": "elfo",
6
+ "description": "Seu deslocamento é 12m (em vez de 9m).",
7
+ "effects": {
8
+ "movement_override": 12
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "sangue_magico",
3
+ "name": "Sangue Mágico",
4
+ "type": "habilidade_de_raca",
5
+ "race": "elfo",
6
+ "description": "Você recebe +1 ponto de mana por nível.",
7
+ "effects": {
8
+ "mp_bonus_per_level": 1
9
+ }
10
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "id": "sentidos_elficos",
3
+ "name": "Sentidos Élficos",
4
+ "type": "habilidade_de_raca",
5
+ "race": "elfo",
6
+ "description": "Você recebe visão na penumbra e +2 em Misticismo e Percepção.",
7
+ "effects": {
8
+ "vision": "visao_na_penumbra",
9
+ "skill_bonus": [
10
+ { "skill": "misticismo", "value": 2 },
11
+ { "skill": "percepcao", "value": 2 }
12
+ ]
13
+ }
14
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "id": "engenhoso",
3
+ "name": "Engenhoso",
4
+ "type": "habilidade_de_raca",
5
+ "race": "goblin",
6
+ "description": "Você não sofre penalidades em testes de perícia por não usar ferramentas. Se usar a ferramenta necessária, recebe +2 no teste de perícia.",
7
+ "effects": {
8
+ "ignore_no_tool_penalty": true,
9
+ "tool_bonus": 2
10
+ }
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "id": "espelunqueiro",
3
+ "name": "Espelunqueiro",
4
+ "type": "habilidade_de_raca",
5
+ "race": "goblin",
6
+ "description": "Você recebe visão no escuro e deslocamento de escalada igual ao seu deslocamento terrestre.",
7
+ "effects": {
8
+ "vision": "visao_no_escuro",
9
+ "climb_speed": "equal_to_land_speed"
10
+ }
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "id": "peste_esguia",
3
+ "name": "Peste Esguia",
4
+ "type": "habilidade_de_raca",
5
+ "race": "goblin",
6
+ "description": "Seu tamanho é Pequeno, mas seu deslocamento se mantém 9m.",
7
+ "effects": {
8
+ "size": "pequeno",
9
+ "movement_override": 9
10
+ }
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "id": "rato_das_ruas",
3
+ "name": "Rato das Ruas",
4
+ "type": "habilidade_de_raca",
5
+ "race": "goblin",
6
+ "description": "Você recebe +2 em Fortitude e sua recuperação de PV e PM nunca é inferior ao seu nível.",
7
+ "effects": {
8
+ "skill_bonus": [{ "skill": "fortitude", "value": 2 }],
9
+ "hp_pm_recovery_minimum": "character_level"
10
+ }
11
+ }