tormenta20 0.2.0 → 0.2.2

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 (471) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +27 -0
  3. data/README.md +203 -12
  4. data/Rakefile +9 -0
  5. data/db/schema.sql +382 -0
  6. data/db/seeds.rb +377 -0
  7. data/db/tormenta20.sqlite3 +0 -0
  8. data/docs/armaduras.md +72 -0
  9. data/docs/armas.md +95 -0
  10. data/docs/classes.md +105 -0
  11. data/docs/divindades.md +77 -0
  12. data/docs/escudos.md +49 -0
  13. data/docs/itens.md +59 -0
  14. data/docs/magias.md +157 -0
  15. data/docs/materiais_especiais.md +50 -0
  16. data/docs/melhorias.md +55 -0
  17. data/docs/origens.md +61 -0
  18. data/docs/poderes.md +98 -0
  19. data/docs/regras.md +51 -0
  20. data/examples/database_usage.rb +155 -0
  21. data/src/json/classes/arcanista.json +86 -0
  22. data/src/json/classes/barbaro.json +85 -0
  23. data/src/json/classes/bardo.json +91 -0
  24. data/src/json/classes/bucaneiro.json +96 -0
  25. data/src/json/classes/cacador.json +96 -0
  26. data/src/json/classes/cavaleiro.json +87 -0
  27. data/src/json/classes/clerigo.json +82 -0
  28. data/src/json/classes/druida.json +88 -0
  29. data/src/json/classes/guerreiro.json +90 -0
  30. data/src/json/classes/inventor.json +100 -0
  31. data/src/json/classes/ladino.json +96 -0
  32. data/src/json/classes/lutador.json +90 -0
  33. data/src/json/classes/nobre.json +100 -0
  34. data/src/json/classes/paladino.json +93 -0
  35. data/src/json/deuses/aharadak.json +26 -0
  36. data/src/json/deuses/allihanna.json +26 -0
  37. data/src/json/deuses/arsenal.json +28 -0
  38. data/src/json/deuses/azgher.json +28 -0
  39. data/src/json/deuses/hyninn.json +28 -0
  40. data/src/json/deuses/kallyadranoch.json +28 -0
  41. data/src/json/deuses/khalmyr.json +27 -0
  42. data/src/json/deuses/lena.json +28 -0
  43. data/src/json/deuses/lin_wu.json +28 -0
  44. data/src/json/deuses/marah.json +28 -0
  45. data/src/json/deuses/megalokk.json +28 -0
  46. data/src/json/deuses/nimb.json +27 -0
  47. data/src/json/deuses/oceano.json +26 -0
  48. data/src/json/deuses/sszzaas.json +28 -0
  49. data/src/json/deuses/tanna_toh.json +28 -0
  50. data/src/json/deuses/tenebra.json +26 -0
  51. data/src/json/deuses/thwor.json +27 -0
  52. data/src/json/deuses/thyatis.json +26 -0
  53. data/src/json/deuses/valkaria.json +30 -0
  54. data/src/json/deuses/wynna.json +25 -0
  55. data/src/json/equipamentos/armaduras/leves/armadura_acolchoada.json +15 -0
  56. data/src/json/equipamentos/armaduras/leves/armadura_de_couro.json +13 -0
  57. data/src/json/equipamentos/armaduras/leves/couraca.json +13 -0
  58. data/src/json/equipamentos/armaduras/leves/couro_batido.json +13 -0
  59. data/src/json/equipamentos/armaduras/leves/gibao_de_peles.json +13 -0
  60. data/src/json/equipamentos/armaduras/pesadas/armadura_completa.json +19 -0
  61. data/src/json/equipamentos/armaduras/pesadas/brunea.json +17 -0
  62. data/src/json/equipamentos/armaduras/pesadas/cota_de_malha.json +17 -0
  63. data/src/json/equipamentos/armaduras/pesadas/loriga_segmentada.json +17 -0
  64. data/src/json/equipamentos/armaduras/pesadas/meia_armadura.json +17 -0
  65. data/src/json/equipamentos/armas/exoticas/chicote.json +23 -0
  66. data/src/json/equipamentos/armas/exoticas/corrente_de_espinhos.json +23 -0
  67. data/src/json/equipamentos/armas/exoticas/espada_bastarda.json +19 -0
  68. data/src/json/equipamentos/armas/exoticas/katana.json +19 -0
  69. data/src/json/equipamentos/armas/exoticas/machado_anao.json +19 -0
  70. data/src/json/equipamentos/armas/exoticas/machado_taurico.json +17 -0
  71. data/src/json/equipamentos/armas/exoticas/rede.json +41 -0
  72. data/src/json/equipamentos/armas/fogo/mosquete.json +21 -0
  73. data/src/json/equipamentos/armas/fogo/pistola.json +21 -0
  74. data/src/json/equipamentos/armas/marciais/alabarda.json +17 -0
  75. data/src/json/equipamentos/armas/marciais/alfange.json +17 -0
  76. data/src/json/equipamentos/armas/marciais/arco_longo.json +22 -0
  77. data/src/json/equipamentos/armas/marciais/besta_pesada.json +21 -0
  78. data/src/json/equipamentos/armas/marciais/cimitarra.json +17 -0
  79. data/src/json/equipamentos/armas/marciais/espada_longa.json +17 -0
  80. data/src/json/equipamentos/armas/marciais/florete.json +17 -0
  81. data/src/json/equipamentos/armas/marciais/gadanho.json +17 -0
  82. data/src/json/equipamentos/armas/marciais/lanca_montada.json +20 -0
  83. data/src/json/equipamentos/armas/marciais/machadinha.json +19 -0
  84. data/src/json/equipamentos/armas/marciais/machado_de_batalha.json +17 -0
  85. data/src/json/equipamentos/armas/marciais/machado_de_guerra.json +17 -0
  86. data/src/json/equipamentos/armas/marciais/mangual.json +21 -0
  87. data/src/json/equipamentos/armas/marciais/marreta.json +17 -0
  88. data/src/json/equipamentos/armas/marciais/martelo_de_guerra.json +17 -0
  89. data/src/json/equipamentos/armas/marciais/montante.json +17 -0
  90. data/src/json/equipamentos/armas/marciais/picareta.json +17 -0
  91. data/src/json/equipamentos/armas/marciais/tridente.json +22 -0
  92. data/src/json/equipamentos/armas/simples/adaga.json +21 -0
  93. data/src/json/equipamentos/armas/simples/arco_curto.json +21 -0
  94. data/src/json/equipamentos/armas/simples/azagaia.json +20 -0
  95. data/src/json/equipamentos/armas/simples/besta_leve.json +21 -0
  96. data/src/json/equipamentos/armas/simples/bordao.json +17 -0
  97. data/src/json/equipamentos/armas/simples/clava.json +17 -0
  98. data/src/json/equipamentos/armas/simples/espada_curta.json +17 -0
  99. data/src/json/equipamentos/armas/simples/foice.json +17 -0
  100. data/src/json/equipamentos/armas/simples/funda.json +23 -0
  101. data/src/json/equipamentos/armas/simples/lanca.json +19 -0
  102. data/src/json/equipamentos/armas/simples/maca.json +17 -0
  103. data/src/json/equipamentos/armas/simples/pique.json +17 -0
  104. data/src/json/equipamentos/armas/simples/tacape.json +17 -0
  105. data/src/json/equipamentos/escudos/escudo_leve.json +22 -0
  106. data/src/json/equipamentos/escudos/escudo_pesado.json +22 -0
  107. data/src/json/equipamentos/itens/alimentacao/batata_valkariana.json +14 -0
  108. data/src/json/equipamentos/itens/alimentacao/gorad_quente.json +12 -0
  109. data/src/json/equipamentos/itens/alimentacao/macarrao_de_yuvalin.json +12 -0
  110. data/src/json/equipamentos/itens/alimentacao/prato_do_aventureiro.json +13 -0
  111. data/src/json/equipamentos/itens/alimentacao/racao_de_viagem.json +14 -0
  112. data/src/json/equipamentos/itens/alimentacao/refeicao_comum.json +9 -0
  113. data/src/json/equipamentos/itens/alimentacao/sopa_de_peixe.json +13 -0
  114. data/src/json/equipamentos/itens/alquimicos/catalisadores/baga_de_fogo.json +17 -0
  115. data/src/json/equipamentos/itens/alquimicos/catalisadores/dente_de_dragao.json +17 -0
  116. data/src/json/equipamentos/itens/alquimicos/catalisadores/essencia_abissal.json +22 -0
  117. data/src/json/equipamentos/itens/alquimicos/catalisadores/liquen_lilas.json +18 -0
  118. data/src/json/equipamentos/itens/alquimicos/catalisadores/musgo_purpura.json +18 -0
  119. data/src/json/equipamentos/itens/alquimicos/catalisadores/ossos_de_monstro.json +17 -0
  120. data/src/json/equipamentos/itens/alquimicos/catalisadores/po_de_cristal.json +18 -0
  121. data/src/json/equipamentos/itens/alquimicos/catalisadores/po_de_giz.json +18 -0
  122. data/src/json/equipamentos/itens/alquimicos/catalisadores/ramo_verdejante.json +16 -0
  123. data/src/json/equipamentos/itens/alquimicos/catalisadores/saco_de_sal.json +18 -0
  124. data/src/json/equipamentos/itens/alquimicos/catalisadores/seixo_de_ambar.json +18 -0
  125. data/src/json/equipamentos/itens/alquimicos/catalisadores/terra_de_cemiterio.json +18 -0
  126. data/src/json/equipamentos/itens/alquimicos/preparados/acido.json +19 -0
  127. data/src/json/equipamentos/itens/alquimicos/preparados/balsamo_restaurador.json +16 -0
  128. data/src/json/equipamentos/itens/alquimicos/preparados/bomba.json +30 -0
  129. data/src/json/equipamentos/itens/alquimicos/preparados/cosmetico.json +18 -0
  130. data/src/json/equipamentos/itens/alquimicos/preparados/elixir_do_amor.json +23 -0
  131. data/src/json/equipamentos/itens/alquimicos/preparados/essencia_de_mana.json +16 -0
  132. data/src/json/equipamentos/itens/alquimicos/preparados/fogo_alquimico.json +27 -0
  133. data/src/json/equipamentos/itens/alquimicos/preparados/po_do_desaparecimento.json +18 -0
  134. data/src/json/equipamentos/itens/alquimicos/venenos/beladona.json +22 -0
  135. data/src/json/equipamentos/itens/alquimicos/venenos/bruma_sonolenta.json +21 -0
  136. data/src/json/equipamentos/itens/alquimicos/venenos/cicuta.json +22 -0
  137. data/src/json/equipamentos/itens/alquimicos/venenos/essencia_de_sombra.json +20 -0
  138. data/src/json/equipamentos/itens/alquimicos/venenos/nevoa_toxica.json +22 -0
  139. data/src/json/equipamentos/itens/alquimicos/venenos/peconha_comum.json +24 -0
  140. data/src/json/equipamentos/itens/alquimicos/venenos/peconha_concentrada.json +22 -0
  141. data/src/json/equipamentos/itens/alquimicos/venenos/peconha_potente.json +22 -0
  142. data/src/json/equipamentos/itens/alquimicos/venenos/po_de_lich.json +23 -0
  143. data/src/json/equipamentos/itens/alquimicos/venenos/riso_de_nimb.json +21 -0
  144. data/src/json/equipamentos/itens/animais/alforje.json +11 -0
  145. data/src/json/equipamentos/itens/animais/cao_de_caca.json +18 -0
  146. data/src/json/equipamentos/itens/animais/cavalo.json +20 -0
  147. data/src/json/equipamentos/itens/animais/cavalo_de_guerra.json +17 -0
  148. data/src/json/equipamentos/itens/animais/estabulo.json +10 -0
  149. data/src/json/equipamentos/itens/animais/ponei.json +21 -0
  150. data/src/json/equipamentos/itens/animais/ponei_de_guerra.json +18 -0
  151. data/src/json/equipamentos/itens/animais/trobo.json +14 -0
  152. data/src/json/equipamentos/itens/aventura/agua_benta.json +23 -0
  153. data/src/json/equipamentos/itens/aventura/algemas.json +35 -0
  154. data/src/json/equipamentos/itens/aventura/arpeu.json +18 -0
  155. data/src/json/equipamentos/itens/aventura/bandoleira_de_pocoes.json +15 -0
  156. data/src/json/equipamentos/itens/aventura/barraca.json +14 -0
  157. data/src/json/equipamentos/itens/aventura/corda.json +26 -0
  158. data/src/json/equipamentos/itens/aventura/espelho.json +10 -0
  159. data/src/json/equipamentos/itens/aventura/lampiao.json +19 -0
  160. data/src/json/equipamentos/itens/aventura/mochila.json +12 -0
  161. data/src/json/equipamentos/itens/aventura/mochila_de_aventureiro.json +14 -0
  162. data/src/json/equipamentos/itens/aventura/oleo.json +19 -0
  163. data/src/json/equipamentos/itens/aventura/organizador_de_pergaminhos.json +14 -0
  164. data/src/json/equipamentos/itens/aventura/pe_de_cabra.json +18 -0
  165. data/src/json/equipamentos/itens/aventura/saco_de_dormir.json +13 -0
  166. data/src/json/equipamentos/itens/aventura/simbolo_sagrado.json +15 -0
  167. data/src/json/equipamentos/itens/aventura/tocha.json +28 -0
  168. data/src/json/equipamentos/itens/aventura/vara_de_madeira.json +12 -0
  169. data/src/json/equipamentos/itens/esotericos/bolsa_de_po.json +17 -0
  170. data/src/json/equipamentos/itens/esotericos/cajado_arcano.json +20 -0
  171. data/src/json/equipamentos/itens/esotericos/cetro_elemental.json +22 -0
  172. data/src/json/equipamentos/itens/esotericos/costela_de_lich.json +18 -0
  173. data/src/json/equipamentos/itens/esotericos/dedo_de_ente.json +21 -0
  174. data/src/json/equipamentos/itens/esotericos/luva_de_ferro.json +17 -0
  175. data/src/json/equipamentos/itens/esotericos/medalhao_de_prata.json +16 -0
  176. data/src/json/equipamentos/itens/esotericos/orbe_cristalino.json +15 -0
  177. data/src/json/equipamentos/itens/esotericos/tomo_hermetico.json +17 -0
  178. data/src/json/equipamentos/itens/esotericos/varinha_arcana.json +15 -0
  179. data/src/json/equipamentos/itens/ferramentas/alaude_elfico.json +16 -0
  180. data/src/json/equipamentos/itens/ferramentas/colecao_de_livros.json +16 -0
  181. data/src/json/equipamentos/itens/ferramentas/equipamento_de_viagem.json +19 -0
  182. data/src/json/equipamentos/itens/ferramentas/estojo_de_disfarces.json +18 -0
  183. data/src/json/equipamentos/itens/ferramentas/flauta_mistica.json +17 -0
  184. data/src/json/equipamentos/itens/ferramentas/gazua.json +18 -0
  185. data/src/json/equipamentos/itens/ferramentas/instrumento_musical.json +20 -0
  186. data/src/json/equipamentos/itens/ferramentas/instrumentos_de_oficio.json +21 -0
  187. data/src/json/equipamentos/itens/ferramentas/luneta.json +15 -0
  188. data/src/json/equipamentos/itens/ferramentas/maleta_de_medicamentos.json +17 -0
  189. data/src/json/equipamentos/itens/ferramentas/sela.json +19 -0
  190. data/src/json/equipamentos/itens/ferramentas/tambor_das_profundezas.json +17 -0
  191. data/src/json/equipamentos/itens/servicos/conducao.json +19 -0
  192. data/src/json/equipamentos/itens/servicos/curandeiro.json +9 -0
  193. data/src/json/equipamentos/itens/servicos/estadia.json +42 -0
  194. data/src/json/equipamentos/itens/servicos/magia.json +23 -0
  195. data/src/json/equipamentos/itens/servicos/mensageiro.json +10 -0
  196. data/src/json/equipamentos/itens/veiculos/balao_goblin.json +34 -0
  197. data/src/json/equipamentos/itens/veiculos/canoa.json +18 -0
  198. data/src/json/equipamentos/itens/veiculos/carroca.json +20 -0
  199. data/src/json/equipamentos/itens/veiculos/carruagem.json +21 -0
  200. data/src/json/equipamentos/itens/veiculos/veleiro.json +11 -0
  201. data/src/json/equipamentos/itens/vestuario/andrajos_de_aldeao.json +16 -0
  202. data/src/json/equipamentos/itens/vestuario/bandana.json +14 -0
  203. data/src/json/equipamentos/itens/vestuario/botas_reforcadas.json +15 -0
  204. data/src/json/equipamentos/itens/vestuario/camisa_bufante.json +14 -0
  205. data/src/json/equipamentos/itens/vestuario/capa_esvoacante.json +14 -0
  206. data/src/json/equipamentos/itens/vestuario/capa_pesada.json +14 -0
  207. data/src/json/equipamentos/itens/vestuario/casaco_longo.json +15 -0
  208. data/src/json/equipamentos/itens/vestuario/chapeu_arcano.json +15 -0
  209. data/src/json/equipamentos/itens/vestuario/enfeite_de_elmo.json +15 -0
  210. data/src/json/equipamentos/itens/vestuario/farrapos_de_ermitao.json +16 -0
  211. data/src/json/equipamentos/itens/vestuario/gorro_de_ervas.json +14 -0
  212. data/src/json/equipamentos/itens/vestuario/luva_de_pelica.json +14 -0
  213. data/src/json/equipamentos/itens/vestuario/manopla.json +15 -0
  214. data/src/json/equipamentos/itens/vestuario/manto_camuflado.json +20 -0
  215. data/src/json/equipamentos/itens/vestuario/manto_eclesiastico.json +14 -0
  216. data/src/json/equipamentos/itens/vestuario/robe_mistico.json +14 -0
  217. data/src/json/equipamentos/itens/vestuario/sapatos_de_camurca.json +14 -0
  218. data/src/json/equipamentos/itens/vestuario/tabardo.json +14 -0
  219. data/src/json/equipamentos/itens/vestuario/traje_da_corte.json +19 -0
  220. data/src/json/equipamentos/itens/vestuario/traje_de_viajante.json +13 -0
  221. data/src/json/equipamentos/itens/vestuario/veste_de_seda.json +14 -0
  222. data/src/json/equipamentos/municoes/balas.json +13 -0
  223. data/src/json/equipamentos/municoes/flechas.json +13 -0
  224. data/src/json/equipamentos/municoes/pedras.json +14 -0
  225. data/src/json/equipamentos/municoes/virotes.json +14 -0
  226. data/src/json/itens_superiores/materiais_especiais/aco_rubi.json +44 -0
  227. data/src/json/itens_superiores/materiais_especiais/adamante.json +35 -0
  228. data/src/json/itens_superiores/materiais_especiais/gelo_eterno.json +33 -0
  229. data/src/json/itens_superiores/materiais_especiais/madeira_tollon.json +31 -0
  230. data/src/json/itens_superiores/materiais_especiais/materia_vermelha.json +51 -0
  231. data/src/json/itens_superiores/materiais_especiais/mitral.json +38 -0
  232. data/src/json/itens_superiores/melhorias/armaduras_escudos/ajustada.json +11 -0
  233. data/src/json/itens_superiores/melhorias/armaduras_escudos/delicada.json +15 -0
  234. data/src/json/itens_superiores/melhorias/armaduras_escudos/espinhosa.json +15 -0
  235. data/src/json/itens_superiores/melhorias/armaduras_escudos/espinhoso.json +11 -0
  236. data/src/json/itens_superiores/melhorias/armaduras_escudos/polida.json +13 -0
  237. data/src/json/itens_superiores/melhorias/armaduras_escudos/reforcada.json +13 -0
  238. data/src/json/itens_superiores/melhorias/armaduras_escudos/selada.json +14 -0
  239. data/src/json/itens_superiores/melhorias/armaduras_escudos/sob_medida.json +13 -0
  240. data/src/json/itens_superiores/melhorias/armas/atroz.json +11 -0
  241. data/src/json/itens_superiores/melhorias/armas/certeira.json +11 -0
  242. data/src/json/itens_superiores/melhorias/armas/cruel.json +11 -0
  243. data/src/json/itens_superiores/melhorias/armas/equilibrada.json +11 -0
  244. data/src/json/itens_superiores/melhorias/armas/harmonizada.json +13 -0
  245. data/src/json/itens_superiores/melhorias/armas/injecao_alquimica.json +14 -0
  246. data/src/json/itens_superiores/melhorias/armas/macica.json +12 -0
  247. data/src/json/itens_superiores/melhorias/armas/mira_telescopica.json +16 -0
  248. data/src/json/itens_superiores/melhorias/armas/precisa.json +12 -0
  249. data/src/json/itens_superiores/melhorias/armas/pungente.json +11 -0
  250. data/src/json/itens_superiores/melhorias/esotericos/canalizador.json +11 -0
  251. data/src/json/itens_superiores/melhorias/esotericos/energetico.json +12 -0
  252. data/src/json/itens_superiores/melhorias/esotericos/harmonizado.json +16 -0
  253. data/src/json/itens_superiores/melhorias/esotericos/poderoso.json +11 -0
  254. data/src/json/itens_superiores/melhorias/esotericos/vigilante.json +11 -0
  255. data/src/json/itens_superiores/melhorias/ferramentas_vestuario/aprimorado.json +15 -0
  256. data/src/json/itens_superiores/melhorias/geral/banhado_a_ouro.json +17 -0
  257. data/src/json/itens_superiores/melhorias/geral/cravejado_de_gemas.json +12 -0
  258. data/src/json/itens_superiores/melhorias/geral/discreto.json +13 -0
  259. data/src/json/itens_superiores/melhorias/geral/macabro.json +12 -0
  260. data/src/json/itens_superiores/melhorias/geral/material_especial.json +13 -0
  261. data/src/json/origens/acolito.json +11 -0
  262. data/src/json/origens/amigo_dos_animais.json +11 -0
  263. data/src/json/origens/amnesico.json +10 -0
  264. data/src/json/origens/aristocrata.json +11 -0
  265. data/src/json/origens/artesao.json +11 -0
  266. data/src/json/origens/artista.json +11 -0
  267. data/src/json/origens/assistente_de_laboratorio.json +11 -0
  268. data/src/json/origens/batedor.json +11 -0
  269. data/src/json/origens/capanga.json +11 -0
  270. data/src/json/origens/charlatao.json +11 -0
  271. data/src/json/origens/circense.json +11 -0
  272. data/src/json/origens/criminoso.json +11 -0
  273. data/src/json/origens/curandeiro.json +11 -0
  274. data/src/json/origens/eremita.json +11 -0
  275. data/src/json/origens/escravo.json +11 -0
  276. data/src/json/origens/estudioso.json +11 -0
  277. data/src/json/origens/fazendeiro.json +11 -0
  278. data/src/json/origens/forasteiro.json +11 -0
  279. data/src/json/origens/gladiador.json +11 -0
  280. data/src/json/origens/guarda.json +11 -0
  281. data/src/json/origens/herdeiro.json +11 -0
  282. data/src/json/origens/heroi_campones.json +11 -0
  283. data/src/json/origens/marujo.json +11 -0
  284. data/src/json/origens/mateiro.json +11 -0
  285. data/src/json/origens/membro_de_guilda.json +11 -0
  286. data/src/json/origens/mercador.json +11 -0
  287. data/src/json/origens/minerador.json +11 -0
  288. data/src/json/origens/nomade.json +11 -0
  289. data/src/json/origens/pivete.json +11 -0
  290. data/src/json/origens/refugiado.json +11 -0
  291. data/src/json/origens/seguidor.json +11 -0
  292. data/src/json/origens/selvagem.json +11 -0
  293. data/src/json/origens/soldado.json +11 -0
  294. data/src/json/origens/taverneiro.json +11 -0
  295. data/src/json/origens/trabalhador.json +11 -0
  296. data/src/json/poderes/habilidades_unicas_de_origem/a_prova_de_tudo.json +14 -0
  297. data/src/json/poderes/habilidades_unicas_de_origem/agua_no_feijao.json +14 -0
  298. data/src/json/poderes/habilidades_unicas_de_origem/alpinista_social.json +9 -0
  299. data/src/json/poderes/habilidades_unicas_de_origem/amigo_especial.json +16 -0
  300. data/src/json/poderes/habilidades_unicas_de_origem/antigo_mestre.json +15 -0
  301. data/src/json/poderes/habilidades_unicas_de_origem/busca_interior.json +13 -0
  302. data/src/json/poderes/habilidades_unicas_de_origem/confissao.json +14 -0
  303. data/src/json/poderes/habilidades_unicas_de_origem/coracao_heroico.json +13 -0
  304. data/src/json/poderes/habilidades_unicas_de_origem/cultura_exotica.json +13 -0
  305. data/src/json/poderes/habilidades_unicas_de_origem/desejo_de_liberdade.json +12 -0
  306. data/src/json/poderes/habilidades_unicas_de_origem/detetive.json +14 -0
  307. data/src/json/poderes/habilidades_unicas_de_origem/dom_artistico.json +10 -0
  308. data/src/json/poderes/habilidades_unicas_de_origem/escavador.json +13 -0
  309. data/src/json/poderes/habilidades_unicas_de_origem/esforcado.json +13 -0
  310. data/src/json/poderes/habilidades_unicas_de_origem/esse_cheiro.json +14 -0
  311. data/src/json/poderes/habilidades_unicas_de_origem/estoico.json +16 -0
  312. data/src/json/poderes/habilidades_unicas_de_origem/frutos_do_trabalho.json +19 -0
  313. data/src/json/poderes/habilidades_unicas_de_origem/gororoba.json +12 -0
  314. data/src/json/poderes/habilidades_unicas_de_origem/heranca.json +13 -0
  315. data/src/json/poderes/habilidades_unicas_de_origem/influencia_militar.json +14 -0
  316. data/src/json/poderes/habilidades_unicas_de_origem/lembrancas_graduais.json +14 -0
  317. data/src/json/poderes/habilidades_unicas_de_origem/medico_de_campo.json +12 -0
  318. data/src/json/poderes/habilidades_unicas_de_origem/membro_da_igreja.json +14 -0
  319. data/src/json/poderes/habilidades_unicas_de_origem/mochileiro.json +9 -0
  320. data/src/json/poderes/habilidades_unicas_de_origem/negociacao.json +12 -0
  321. data/src/json/poderes/habilidades_unicas_de_origem/palpite_fundamentado.json +13 -0
  322. data/src/json/poderes/habilidades_unicas_de_origem/pao_e_circo.json +11 -0
  323. data/src/json/poderes/habilidades_unicas_de_origem/passagem_de_navio.json +13 -0
  324. data/src/json/poderes/habilidades_unicas_de_origem/punguista.json +15 -0
  325. data/src/json/poderes/habilidades_unicas_de_origem/quebra_galho.json +14 -0
  326. data/src/json/poderes/habilidades_unicas_de_origem/rede_de_contatos.json +14 -0
  327. data/src/json/poderes/habilidades_unicas_de_origem/sangue_azul.json +12 -0
  328. data/src/json/poderes/habilidades_unicas_de_origem/truque_de_magica.json +14 -0
  329. data/src/json/poderes/habilidades_unicas_de_origem/vendedor_de_carcacas.json +13 -0
  330. data/src/json/poderes/habilidades_unicas_de_origem/vida_rustica.json +13 -0
  331. data/src/json/poderes/poderes_concedidos/afinidade_com_a_tormenta.json +14 -0
  332. data/src/json/poderes/poderes_concedidos/almejar_o_impossivel.json +13 -0
  333. data/src/json/poderes/poderes_concedidos/anfibio.json +13 -0
  334. data/src/json/poderes/poderes_concedidos/apostar_com_o_trapaceiro.json +12 -0
  335. data/src/json/poderes/poderes_concedidos/armas_da_ambicao.json +12 -0
  336. data/src/json/poderes/poderes_concedidos/arsenal_das_profundezas.json +14 -0
  337. data/src/json/poderes/poderes_concedidos/astucia_da_serpente.json +14 -0
  338. data/src/json/poderes/poderes_concedidos/ataque_piedoso.json +13 -0
  339. data/src/json/poderes/poderes_concedidos/aura_de_medo.json +17 -0
  340. data/src/json/poderes/poderes_concedidos/aura_de_paz.json +18 -0
  341. data/src/json/poderes/poderes_concedidos/aura_restauradora.json +13 -0
  342. data/src/json/poderes/poderes_concedidos/bencao_do_mana.json +10 -0
  343. data/src/json/poderes/poderes_concedidos/caricia_sombria.json +26 -0
  344. data/src/json/poderes/poderes_concedidos/centelha_magica.json +13 -0
  345. data/src/json/poderes/poderes_concedidos/compreender_os_ermos.json +17 -0
  346. data/src/json/poderes/poderes_concedidos/conhecimento_enciclopedico.json +13 -0
  347. data/src/json/poderes/poderes_concedidos/conjurar_arma.json +19 -0
  348. data/src/json/poderes/poderes_concedidos/coragem_total.json +11 -0
  349. data/src/json/poderes/poderes_concedidos/cura_gentil.json +10 -0
  350. data/src/json/poderes/poderes_concedidos/curandeira_perfeita.json +15 -0
  351. data/src/json/poderes/poderes_concedidos/dedo_verde.json +14 -0
  352. data/src/json/poderes/poderes_concedidos/descanso_natural.json +10 -0
  353. data/src/json/poderes/poderes_concedidos/dom_da_esperanca.json +15 -0
  354. data/src/json/poderes/poderes_concedidos/dom_da_imortalidade.json +8 -0
  355. data/src/json/poderes/poderes_concedidos/dom_da_profecia.json +6 -0
  356. data/src/json/poderes/poderes_concedidos/dom_da_ressurreicao.json +8 -0
  357. data/src/json/poderes/poderes_concedidos/dom_da_verdade.json +15 -0
  358. data/src/json/poderes/poderes_concedidos/escamas_draconicas.json +13 -0
  359. data/src/json/poderes/poderes_concedidos/escudo_magico.json +12 -0
  360. data/src/json/poderes/poderes_concedidos/espada_justiceira.json +13 -0
  361. data/src/json/poderes/poderes_concedidos/espada_solar.json +16 -0
  362. data/src/json/poderes/poderes_concedidos/extase_da_loucura.json +12 -0
  363. data/src/json/poderes/poderes_concedidos/familiar_ofidico.json +13 -0
  364. data/src/json/poderes/poderes_concedidos/farsa_do_fingidor.json +14 -0
  365. data/src/json/poderes/poderes_concedidos/fe_guerreira.json +20 -0
  366. data/src/json/poderes/poderes_concedidos/forma_de_macaco.json +20 -0
  367. data/src/json/poderes/poderes_concedidos/fulgor_solar.json +18 -0
  368. data/src/json/poderes/poderes_concedidos/furia_divina.json +20 -0
  369. data/src/json/poderes/poderes_concedidos/golpista_divino.json +14 -0
  370. data/src/json/poderes/poderes_concedidos/habitante_do_deserto.json +14 -0
  371. data/src/json/poderes/poderes_concedidos/inimigo_de_tenebra.json +14 -0
  372. data/src/json/poderes/poderes_concedidos/kiai_divino.json +13 -0
  373. data/src/json/poderes/poderes_concedidos/liberdade_divina.json +12 -0
  374. data/src/json/poderes/poderes_concedidos/manto_da_penumbra.json +14 -0
  375. data/src/json/poderes/poderes_concedidos/mente_analitica.json +16 -0
  376. data/src/json/poderes/poderes_concedidos/mente_vazia.json +16 -0
  377. data/src/json/poderes/poderes_concedidos/mestre_dos_mares.json +18 -0
  378. data/src/json/poderes/poderes_concedidos/olhar_amedrontador.json +14 -0
  379. data/src/json/poderes/poderes_concedidos/palavras_de_bondade.json +14 -0
  380. data/src/json/poderes/poderes_concedidos/percepcao_temporal.json +17 -0
  381. data/src/json/poderes/poderes_concedidos/pesquisa_abencoada.json +15 -0
  382. data/src/json/poderes/poderes_concedidos/poder_oculto.json +21 -0
  383. data/src/json/poderes/poderes_concedidos/presas_primordiais.json +23 -0
  384. data/src/json/poderes/poderes_concedidos/presas_venenosas.json +16 -0
  385. data/src/json/poderes/poderes_concedidos/rejeicao_divina.json +13 -0
  386. data/src/json/poderes/poderes_concedidos/reparar_injustica.json +13 -0
  387. data/src/json/poderes/poderes_concedidos/sangue_de_ferro.json +13 -0
  388. data/src/json/poderes/poderes_concedidos/sangue_ofidico.json +14 -0
  389. data/src/json/poderes/poderes_concedidos/servos_do_dragao.json +24 -0
  390. data/src/json/poderes/poderes_concedidos/sopro_do_mar.json +25 -0
  391. data/src/json/poderes/poderes_concedidos/sorte_dos_loucos.json +13 -0
  392. data/src/json/poderes/poderes_concedidos/talento_artistico.json +14 -0
  393. data/src/json/poderes/poderes_concedidos/teurgista_mistico.json +11 -0
  394. data/src/json/poderes/poderes_concedidos/tradicao_de_lin_wu.json +14 -0
  395. data/src/json/poderes/poderes_concedidos/transmissao_da_loucura.json +17 -0
  396. data/src/json/poderes/poderes_concedidos/tropas_duyshidakk.json +24 -0
  397. data/src/json/poderes/poderes_concedidos/urro_divino.json +13 -0
  398. data/src/json/poderes/poderes_concedidos/visao_nas_trevas.json +10 -0
  399. data/src/json/poderes/poderes_concedidos/voz_da_civilizacao.json +10 -0
  400. data/src/json/poderes/poderes_concedidos/voz_da_natureza.json +18 -0
  401. data/src/json/poderes/poderes_concedidos/voz_dos_monstros.json +11 -0
  402. data/src/json/poderes/poderes_concedidos/zumbificar.json +18 -0
  403. data/src/json/poderes/poderes_da_tormenta/anatomia_insana.json +12 -0
  404. data/src/json/poderes/poderes_da_tormenta/antenas.json +18 -0
  405. data/src/json/poderes/poderes_da_tormenta/armamento_aberrante.json +14 -0
  406. data/src/json/poderes/poderes_da_tormenta/articulacoes_flexiveis.json +15 -0
  407. data/src/json/poderes/poderes_da_tormenta/asas_insetoides.json +17 -0
  408. data/src/json/poderes/poderes_da_tormenta/carapaca.json +12 -0
  409. data/src/json/poderes/poderes_da_tormenta/corpo_aberrante.json +13 -0
  410. data/src/json/poderes/poderes_da_tormenta/cuspir_enxame.json +20 -0
  411. data/src/json/poderes/poderes_da_tormenta/dentes_afiados.json +19 -0
  412. data/src/json/poderes/poderes_da_tormenta/desprezar_a_realidade.json +21 -0
  413. data/src/json/poderes/poderes_da_tormenta/empunhadura_rubra.json +13 -0
  414. data/src/json/poderes/poderes_da_tormenta/fome_de_mana.json +11 -0
  415. data/src/json/poderes/poderes_da_tormenta/larva_explosiva.json +17 -0
  416. data/src/json/poderes/poderes_da_tormenta/legiao_aberrante.json +19 -0
  417. data/src/json/poderes/poderes_da_tormenta/maos_membranosas.json +18 -0
  418. data/src/json/poderes/poderes_da_tormenta/membros_estendidos.json +12 -0
  419. data/src/json/poderes/poderes_da_tormenta/membros_extras.json +27 -0
  420. data/src/json/poderes/poderes_da_tormenta/mente_aberrante.json +20 -0
  421. data/src/json/poderes/poderes_da_tormenta/olhos_vermelhos.json +12 -0
  422. data/src/json/poderes/poderes_da_tormenta/pele_corrompida.json +13 -0
  423. data/src/json/poderes/poderes_da_tormenta/sangue_acido.json +13 -0
  424. data/src/json/poderes/poderes_da_tormenta/visco_rubro.json +15 -0
  425. data/src/json/regras/alcances.json +33 -0
  426. data/src/json/regras/carga.json +47 -0
  427. data/src/json/regras/critico.json +32 -0
  428. data/src/json/regras/dinheiro_inicial.json +27 -0
  429. data/src/json/regras/empunhaduras.json +22 -0
  430. data/src/json/regras/habilidades_armas.json +37 -0
  431. data/src/json/regras/itens_superiores.json +19 -0
  432. data/src/json/regras/limites_uso.json +22 -0
  433. data/src/json/regras/moedas.json +32 -0
  434. data/src/json/regras/passos_dano.json +20 -0
  435. data/src/json/regras/proficiencias.json +32 -0
  436. data/src/json/regras/propositos_armas.json +37 -0
  437. data/src/json/regras/tipos_dano.json +25 -0
  438. data/src/json/regras/venenos.json +45 -0
  439. data/src/ruby/tormenta20/database.rb +224 -0
  440. data/src/ruby/tormenta20/models/arma.rb +123 -0
  441. data/src/ruby/tormenta20/models/armadura.rb +96 -0
  442. data/src/ruby/tormenta20/models/base.rb +19 -0
  443. data/src/ruby/tormenta20/models/classe.rb +134 -0
  444. data/src/ruby/tormenta20/models/divindade.rb +98 -0
  445. data/src/ruby/tormenta20/models/escudo.rb +59 -0
  446. data/src/ruby/tormenta20/models/item.rb +61 -0
  447. data/src/ruby/tormenta20/models/magia.rb +226 -0
  448. data/src/ruby/tormenta20/models/material_especial.rb +52 -0
  449. data/src/ruby/tormenta20/models/melhoria.rb +52 -0
  450. data/src/ruby/tormenta20/models/origem.rb +71 -0
  451. data/src/ruby/tormenta20/models/poder.rb +120 -0
  452. data/src/ruby/tormenta20/models/regra.rb +47 -0
  453. data/src/ruby/tormenta20/seeder.rb +267 -0
  454. data/src/ruby/tormenta20/version.rb +1 -1
  455. data/src/ruby/tormenta20.rb +169 -7
  456. data/src/schema/magia.schema.json +277 -0
  457. data/src/schema/tormenta20.sql +433 -0
  458. data/tasks/jsonlint.rb +6 -4
  459. data/tools/pdf_extractor/README.md +171 -0
  460. data/tools/pdf_extractor/__init__.py +17 -0
  461. data/tools/pdf_extractor/pdf_extractor.py +441 -0
  462. data/tools/pdf_extractor/pipeline.py +450 -0
  463. data/tools/pdf_extractor/prompts.py +789 -0
  464. data/tools/pdf_extractor/requirements.txt +4 -0
  465. metadata +488 -12
  466. data/src/ruby/open_struct_json.rb +0 -35
  467. data/src/ruby/tormenta20/classes.rb +0 -0
  468. data/src/ruby/tormenta20/equipment.rb +0 -0
  469. data/src/ruby/tormenta20/magias.rb +0 -35
  470. data/src/ruby/tormenta20/origins.rb +0 -0
  471. data/src/ruby/tormenta20/races.rb +0 -0
@@ -0,0 +1,37 @@
1
+ {
2
+ "id": "propositos_armas",
3
+ "name": "Propósitos de Armas",
4
+ "description": "Armas são classificadas por propósito: corpo a corpo ou à distância.",
5
+ "tipos": [
6
+ {
7
+ "id": "corpo_a_corpo",
8
+ "name": "Corpo a Corpo",
9
+ "description": "Podem ser usadas para atacar alvos adjacentes.",
10
+ "teste": "Luta",
11
+ "bonus_dano": "Força"
12
+ },
13
+ {
14
+ "id": "distancia",
15
+ "name": "Ataque à Distância",
16
+ "description": "Podem ser usadas para atacar alvos adjacentes ou à distância.",
17
+ "teste": "Pontaria",
18
+ "subtipos": [
19
+ {
20
+ "id": "arremesso",
21
+ "name": "Arremesso",
22
+ "description": "A própria arma é atirada, como uma adaga ou azagaia.",
23
+ "sacar": "acao_movimento",
24
+ "bonus_dano": "Força"
25
+ },
26
+ {
27
+ "id": "disparo",
28
+ "name": "Disparo",
29
+ "description": "A arma dispara um projétil, como um arco atira flechas.",
30
+ "sacar_municao": "acao_livre",
31
+ "recarregar": "duas_maos",
32
+ "bonus_dano": null
33
+ }
34
+ ]
35
+ }
36
+ ]
37
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "id": "tipos_dano",
3
+ "name": "Tipos de Dano",
4
+ "description": "Armas tipicamente causam dano por corte, impacto ou perfuração.",
5
+ "tipos": [
6
+ {
7
+ "id": "corte",
8
+ "name": "Corte",
9
+ "symbol": "C",
10
+ "description": "Dano causado por lâminas afiadas."
11
+ },
12
+ {
13
+ "id": "impacto",
14
+ "name": "Impacto",
15
+ "symbol": "I",
16
+ "description": "Dano causado por golpes contundentes."
17
+ },
18
+ {
19
+ "id": "perfuracao",
20
+ "name": "Perfuração",
21
+ "symbol": "P",
22
+ "description": "Dano causado por pontas penetrantes."
23
+ }
24
+ ]
25
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "id": "venenos",
3
+ "name": "Regras de Venenos",
4
+ "description": "Venenos são classificados de acordo com o método de inoculação.",
5
+ "metodos_inoculacao": [
6
+ {
7
+ "id": "contato",
8
+ "name": "Contato",
9
+ "description": "Inoculados via um ataque que acerte (ou se a vítima toca o objeto envenenado).",
10
+ "aplicar": {
11
+ "acao": "movimento",
12
+ "teste_acidente": {
13
+ "dado": "1d6",
14
+ "resultado_acidente": 1,
15
+ "efeito": "se envenena acidentalmente"
16
+ }
17
+ },
18
+ "duracao": "até acertar um ataque ou fim da cena"
19
+ },
20
+ {
21
+ "id": "inalacao",
22
+ "name": "Inalação",
23
+ "description": "Inoculados via respiração. São armazenados em frascos que podem ser arremessados em alcance curto.",
24
+ "area": {
25
+ "forma": "cubo",
26
+ "lado": 3
27
+ },
28
+ "nota": "Prender a respiração não impede a inoculação"
29
+ },
30
+ {
31
+ "id": "ingestao",
32
+ "name": "Ingestão",
33
+ "description": "Inoculados através da ingestão de comida ou bebida."
34
+ }
35
+ ],
36
+ "resistencia": {
37
+ "teste": "Fortitude",
38
+ "cd": "definida pelo aplicador",
39
+ "atributo_chave": "Int"
40
+ },
41
+ "condicao": {
42
+ "nome": "envenenada",
43
+ "nota": "Curar esta condição encerra quaisquer efeitos de veneno (mas não recupera PV perdidos)"
44
+ }
45
+ }
@@ -0,0 +1,224 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
4
+ require "sqlite3"
5
+ require "fileutils"
6
+
7
+ module Tormenta20
8
+ # Database connection and setup management for Tormenta20.
9
+ #
10
+ # This module handles all database operations including connection management,
11
+ # schema creation, and data seeding.
12
+ #
13
+ # @example Setup with default options
14
+ # Tormenta20::Database.setup
15
+ #
16
+ # @example Setup with custom database path
17
+ # Tormenta20::Database.setup(db_path: "/custom/path/tormenta20.sqlite3")
18
+ module Database
19
+ class << self
20
+ # @!attribute [rw] mode
21
+ # @return [Symbol] Current database mode (:builtin, :build, or :lazy)
22
+ attr_accessor :mode
23
+
24
+ # @!attribute [rw] db_path
25
+ # @return [String] Path to the SQLite database file
26
+ attr_accessor :db_path
27
+
28
+ # Initialize and configure the database connection.
29
+ #
30
+ # @param mode [Symbol] Database initialization mode:
31
+ # - `:builtin` - Use pre-built database (connects immediately)
32
+ # - `:build` - Build database on load (creates if missing, then connects)
33
+ # - `:lazy` - Build database on first use (default)
34
+ # @param db_path [String, nil] Custom path to SQLite database file.
35
+ # If nil, uses the default path.
36
+ # @return [void]
37
+ # @raise [ArgumentError] If an invalid mode is provided
38
+ #
39
+ # @example Default lazy setup
40
+ # Database.setup
41
+ #
42
+ # @example Immediate connection with builtin database
43
+ # Database.setup(mode: :builtin)
44
+ def setup(mode: :lazy, db_path: nil)
45
+ @mode = mode
46
+ @db_path = db_path || default_db_path
47
+ @setup_done = true
48
+
49
+ case mode
50
+ when :builtin
51
+ connect_to_database
52
+ when :build
53
+ ensure_database_exists
54
+ connect_to_database
55
+ when :lazy
56
+ # Connection will be established on first use via ensure_connected
57
+ nil
58
+ else
59
+ raise ArgumentError, "Invalid mode: #{mode}. Use :builtin, :build, or :lazy"
60
+ end
61
+ end
62
+
63
+ # Ensure database is connected, setting up if needed.
64
+ #
65
+ # This method is called automatically when models are accessed.
66
+ # It handles lazy initialization of the database connection.
67
+ #
68
+ # @return [void]
69
+ def ensure_connected
70
+ setup unless @setup_done
71
+ connect_to_database unless connected?
72
+ end
73
+
74
+ # Establish connection to the SQLite database.
75
+ #
76
+ # Creates the database if it doesn't exist (in lazy mode) and
77
+ # establishes an ActiveRecord connection.
78
+ #
79
+ # @return [void]
80
+ def connect_to_database
81
+ return if connected?
82
+
83
+ ensure_database_exists if mode == :lazy
84
+
85
+ ActiveRecord::Base.establish_connection(
86
+ adapter: "sqlite3",
87
+ database: db_path,
88
+ pool: 5,
89
+ timeout: 5000
90
+ )
91
+
92
+ @connected = true
93
+ end
94
+
95
+ # Check if database connection is active.
96
+ #
97
+ # @return [Boolean] true if connected, false otherwise
98
+ def connected?
99
+ @connected == true && ActiveRecord::Base.connected?
100
+ rescue StandardError
101
+ false
102
+ end
103
+
104
+ # Ensure database file and schema exist.
105
+ #
106
+ # Creates the database directory, file, and runs the schema
107
+ # if the database doesn't exist.
108
+ #
109
+ # @return [void]
110
+ def ensure_database_exists
111
+ db_dir = File.dirname(db_path)
112
+ FileUtils.mkdir_p(db_dir) unless Dir.exist?(db_dir)
113
+
114
+ needs_seed = !File.exist?(db_path)
115
+
116
+ return unless needs_seed
117
+
118
+ # Create empty database
119
+ SQLite3::Database.new(db_path).close
120
+
121
+ # Run schema if available
122
+ run_schema if schema_exists?
123
+
124
+ # Seed data after schema creation
125
+ seed_database
126
+ end
127
+
128
+ # Seed database with data from JSON files.
129
+ #
130
+ # @return [void]
131
+ def seed_database
132
+ return if Seeder.seeded?
133
+
134
+ Seeder.seed_all(verbose: false)
135
+ end
136
+
137
+ # Run pending database migrations.
138
+ #
139
+ # @return [void]
140
+ def migrate
141
+ connect_to_database
142
+ ActiveRecord::MigrationContext.new(migrations_path, ActiveRecord::SchemaMigration).migrate
143
+ end
144
+
145
+ # Rollback database migrations.
146
+ #
147
+ # @param steps [Integer] Number of migrations to rollback
148
+ # @return [void]
149
+ def rollback(steps: 1)
150
+ connect_to_database
151
+ ActiveRecord::MigrationContext.new(migrations_path, ActiveRecord::SchemaMigration).rollback(steps)
152
+ end
153
+
154
+ # Get current database migration version.
155
+ #
156
+ # @return [Integer] Current migration version number
157
+ def version
158
+ connect_to_database
159
+ ActiveRecord::Base.connection.migration_context.current_version
160
+ end
161
+
162
+ # Reset database by dropping and recreating it.
163
+ #
164
+ # @return [void]
165
+ # @note This will delete all data in the database
166
+ def reset
167
+ disconnect
168
+ File.delete(db_path) if File.exist?(db_path)
169
+ ensure_database_exists
170
+ connect_to_database
171
+ end
172
+
173
+ # Disconnect from the database.
174
+ #
175
+ # @return [void]
176
+ def disconnect
177
+ ActiveRecord::Base.remove_connection if connected?
178
+ @connected = false
179
+ end
180
+
181
+ # Get the default database file path.
182
+ #
183
+ # @return [String] Absolute path to the default database file
184
+ def default_db_path
185
+ File.expand_path("../../../db/tormenta20.sqlite3", __dir__)
186
+ end
187
+
188
+ # Get the schema SQL file path.
189
+ #
190
+ # @return [String] Absolute path to the schema.sql file
191
+ def schema_path
192
+ File.expand_path("../../../db/schema.sql", __dir__)
193
+ end
194
+
195
+ # Get the migrations directory path.
196
+ #
197
+ # @return [String] Absolute path to the migrations directory
198
+ def migrations_path
199
+ File.expand_path("../../../db/migrate", __dir__)
200
+ end
201
+
202
+ private
203
+
204
+ # Check if schema file exists.
205
+ #
206
+ # @return [Boolean] true if schema.sql exists
207
+ # @api private
208
+ def schema_exists?
209
+ File.exist?(schema_path)
210
+ end
211
+
212
+ # Run schema SQL file to create database tables.
213
+ #
214
+ # @return [void]
215
+ # @api private
216
+ def run_schema
217
+ connect_to_database
218
+ sql = File.read(schema_path)
219
+ # Use execute_batch to handle multi-statement SQL including triggers
220
+ ActiveRecord::Base.connection.raw_connection.execute_batch(sql)
221
+ end
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
4
+ require "json"
5
+
6
+ module Tormenta20
7
+ module Models
8
+ # Model representing an Arma (Weapon) in Tormenta20.
9
+ #
10
+ # Weapons are categorized by type (simple, martial, exotic, firearm)
11
+ # and can be either melee or ranged.
12
+ #
13
+ # @example Find all martial weapons
14
+ # Tormenta20.armas.marciais
15
+ #
16
+ # @example Find ranged weapons
17
+ # Tormenta20.armas.ranged
18
+ #
19
+ # @example Find weapons by damage type
20
+ # Tormenta20.armas.by_damage_type("corte")
21
+ #
22
+ # @!attribute [rw] id
23
+ # @return [String] Unique identifier (e.g., "espada_longa")
24
+ # @!attribute [rw] name
25
+ # @return [String] Weapon name in Portuguese
26
+ # @!attribute [rw] category
27
+ # @return [String] Weapon category: "simples", "marciais", "exoticas", or "fogo"
28
+ # @!attribute [rw] price
29
+ # @return [String] Price in Tormenta currency
30
+ # @!attribute [rw] damage
31
+ # @return [String] Damage dice (e.g., "1d8")
32
+ # @!attribute [rw] damage_type
33
+ # @return [String] Type of damage: "corte", "perfuracao", "impacto"
34
+ # @!attribute [rw] critical
35
+ # @return [String] Critical hit modifier (e.g., "19/x2")
36
+ # @!attribute [rw] range
37
+ # @return [String, nil] Range for ranged weapons, nil for melee
38
+ # @!attribute [rw] weight
39
+ # @return [String] Weight in slots/spaces
40
+ # @!attribute [rw] properties
41
+ # @return [Array<String>] Special weapon properties
42
+ # @!attribute [rw] description
43
+ # @return [String, nil] Optional description
44
+ class Arma < Base
45
+ self.table_name = "armas"
46
+
47
+ # @return [Array<String>] Valid weapon categories
48
+ CATEGORIES = %w[simples marciais exoticas fogo].freeze
49
+
50
+ validates :id, presence: true, uniqueness: true
51
+ validates :name, presence: true
52
+ validates :category, presence: true, inclusion: { in: CATEGORIES }
53
+
54
+ # @!method simples
55
+ # Filter simple weapons only.
56
+ # @return [ActiveRecord::Relation<Arma>]
57
+ scope :simples, -> { where(category: "simples") }
58
+
59
+ # @!method marciais
60
+ # Filter martial weapons only.
61
+ # @return [ActiveRecord::Relation<Arma>]
62
+ scope :marciais, -> { where(category: "marciais") }
63
+
64
+ # @!method exoticas
65
+ # Filter exotic weapons only.
66
+ # @return [ActiveRecord::Relation<Arma>]
67
+ scope :exoticas, -> { where(category: "exoticas") }
68
+
69
+ # @!method fogo
70
+ # Filter firearms only.
71
+ # @return [ActiveRecord::Relation<Arma>]
72
+ scope :fogo, -> { where(category: "fogo") }
73
+
74
+ # @!method by_category(category)
75
+ # Filter weapons by category.
76
+ # @param category [String] Category to filter by
77
+ # @return [ActiveRecord::Relation<Arma>]
78
+ scope :by_category, ->(c) { where(category: c) }
79
+
80
+ # @!method by_damage_type(type)
81
+ # Filter weapons by damage type.
82
+ # @param type [String] Damage type: "corte", "perfuracao", or "impacto"
83
+ # @return [ActiveRecord::Relation<Arma>]
84
+ scope :by_damage_type, ->(t) { where(damage_type: t) }
85
+
86
+ # @!method ranged
87
+ # Filter ranged weapons only (weapons with a range value).
88
+ # @return [ActiveRecord::Relation<Arma>]
89
+ scope :ranged, -> { where.not(range: nil) }
90
+
91
+ # @!method melee
92
+ # Filter melee weapons only (weapons without a range value).
93
+ # @return [ActiveRecord::Relation<Arma>]
94
+ scope :melee, -> { where(range: nil) }
95
+
96
+ # Check if this weapon is ranged.
97
+ #
98
+ # @return [Boolean] true if the weapon has a range value
99
+ def ranged?
100
+ !range.nil?
101
+ end
102
+
103
+ # Convert the weapon to a hash representation.
104
+ #
105
+ # @return [Hash] Hash with all weapon attributes (nil values excluded)
106
+ def to_h
107
+ {
108
+ id: id,
109
+ name: name,
110
+ category: category,
111
+ price: price,
112
+ damage: damage,
113
+ damage_type: damage_type,
114
+ critical: critical,
115
+ range: range,
116
+ weight: weight,
117
+ properties: properties,
118
+ description: description
119
+ }.compact
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
4
+ require "json"
5
+
6
+ module Tormenta20
7
+ module Models
8
+ # Model representing an Armadura (Armor) in Tormenta20.
9
+ #
10
+ # Armors provide defense bonuses but may impose armor penalties.
11
+ # They are categorized as light (leve) or heavy (pesada).
12
+ #
13
+ # @example Find all light armors
14
+ # Tormenta20.armaduras.leves
15
+ #
16
+ # @example Find heavy armors sorted by defense
17
+ # Tormenta20.armaduras.pesadas.order(defense_bonus: :desc)
18
+ #
19
+ # @!attribute [rw] id
20
+ # @return [String] Unique identifier (e.g., "couro")
21
+ # @!attribute [rw] name
22
+ # @return [String] Armor name in Portuguese
23
+ # @!attribute [rw] category
24
+ # @return [String] Armor category: "leve" or "pesada"
25
+ # @!attribute [rw] price
26
+ # @return [String] Price in Tormenta currency
27
+ # @!attribute [rw] defense_bonus
28
+ # @return [Integer] Defense bonus provided by the armor
29
+ # @!attribute [rw] armor_penalty
30
+ # @return [Integer] Armor penalty for skill checks
31
+ # @!attribute [rw] weight
32
+ # @return [String] Weight in slots/spaces
33
+ # @!attribute [rw] properties
34
+ # @return [Array<String>] Special armor properties
35
+ # @!attribute [rw] description
36
+ # @return [String, nil] Optional description
37
+ class Armadura < Base
38
+ self.table_name = "armaduras"
39
+
40
+ # @return [Array<String>] Valid armor categories
41
+ CATEGORIES = %w[leve pesada].freeze
42
+
43
+ validates :id, presence: true, uniqueness: true
44
+ validates :name, presence: true
45
+ validates :category, presence: true, inclusion: { in: CATEGORIES }
46
+ validates :defense_bonus, presence: true
47
+
48
+ # @!method leves
49
+ # Filter light armors only.
50
+ # @return [ActiveRecord::Relation<Armadura>]
51
+ scope :leves, -> { where(category: "leve") }
52
+
53
+ # @!method pesadas
54
+ # Filter heavy armors only.
55
+ # @return [ActiveRecord::Relation<Armadura>]
56
+ scope :pesadas, -> { where(category: "pesada") }
57
+
58
+ # @!method by_category(category)
59
+ # Filter armors by category.
60
+ # @param category [String] Category: "leve" or "pesada"
61
+ # @return [ActiveRecord::Relation<Armadura>]
62
+ scope :by_category, ->(c) { where(category: c) }
63
+
64
+ # Check if this is a light armor.
65
+ #
66
+ # @return [Boolean] true if armor category is "leve"
67
+ def leve?
68
+ category == "leve"
69
+ end
70
+
71
+ # Check if this is a heavy armor.
72
+ #
73
+ # @return [Boolean] true if armor category is "pesada"
74
+ def pesada?
75
+ category == "pesada"
76
+ end
77
+
78
+ # Convert the armor to a hash representation.
79
+ #
80
+ # @return [Hash] Hash with all armor attributes (nil values excluded)
81
+ def to_h
82
+ {
83
+ id: id,
84
+ name: name,
85
+ category: category,
86
+ price: price,
87
+ defense_bonus: defense_bonus,
88
+ armor_penalty: armor_penalty,
89
+ weight: weight,
90
+ properties: properties,
91
+ description: description
92
+ }.compact
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
4
+
5
+ module Tormenta20
6
+ # Contains all ActiveRecord models for Tormenta20 data.
7
+ module Models
8
+ # Abstract base class for all Tormenta20 models.
9
+ #
10
+ # All models in this library inherit from this class, which itself
11
+ # inherits from ActiveRecord::Base. This provides common functionality
12
+ # and ensures all models share the same database connection.
13
+ #
14
+ # @abstract Subclass and set table_name to create a new model
15
+ class Base < ActiveRecord::Base
16
+ self.abstract_class = true
17
+ end
18
+ end
19
+ end