tormenta20 0.2.11 → 0.2.12
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.
- checksums.yaml +4 -4
- data/README.md +141 -40
- data/db/schema.sql +44 -0
- data/db/tormenta20.sqlite3 +0 -0
- data/docs/armaduras.md +13 -13
- data/docs/armas.md +14 -14
- data/docs/condicoes.md +77 -0
- data/docs/divindades.md +14 -14
- data/docs/escudos.md +12 -12
- data/docs/indice_remissivo.md +105 -0
- data/docs/itens.md +9 -9
- data/docs/livros.md +43 -0
- data/docs/magias.md +41 -41
- data/docs/materiais_especiais.md +11 -11
- data/docs/melhorias.md +12 -12
- data/docs/poderes.md +12 -12
- data/docs/racas.md +68 -0
- data/docs/regras.md +7 -7
- data/src/json/indice_remissivo/t20_eja.json +1100 -0
- data/src/json/livros/t20_eja.json +5 -0
- data/src/ruby/tormenta20/concerns/book_referenceable.rb +52 -0
- data/src/ruby/tormenta20/database.rb +1 -0
- data/src/ruby/tormenta20/models/base.rb +2 -0
- data/src/ruby/tormenta20/models/indice_remissivo.rb +57 -0
- data/src/ruby/tormenta20/models/livro.rb +28 -0
- data/src/ruby/tormenta20/version.rb +1 -1
- data/src/ruby/tormenta20.rb +17 -0
- metadata +10 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1f886f621c00e35038fde523eacced3f4175b13e8bab3bd074bfab3f9637dffb
|
|
4
|
+
data.tar.gz: e9e38bcbda3848467cc947012f8e199fd837041e600f96c5731541d3ad28d3a6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: af7f1457d16363868626614eab6cb5e029d84d961e602daf4328f8e10eaaec00c4cab3a5c3a5310274355bb9f4fcd0f6c442def10c651055145f33594f951113
|
|
7
|
+
data.tar.gz: dd0aad7e3d8f04ff788621acdcac1101da78ee064f70770a7da8b5b6226b2e760b07f589246852f2975b4cc9833f682653dc943e0afe853a43b9a81cb70165c1
|
data/README.md
CHANGED
|
@@ -2,11 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
Uma biblioteca Ruby com dados do RPG de mesa brasileiro Tormenta20.
|
|
4
4
|
|
|
5
|
-
A gem inclui um banco de dados SQLite pré-populado com informações sobre magias, classes, origens, divindades, poderes e
|
|
5
|
+
A gem inclui um banco de dados SQLite pré-populado com informações sobre magias, classes, origens, divindades, poderes, equipamentos, raças e condições do sistema Tormenta20. Todos os registros expõem referências de livro e página via o concern `BookReferenceable`.
|
|
6
|
+
|
|
7
|
+
## Dependências do Sistema
|
|
8
|
+
|
|
9
|
+
A gem usa SQLite3 para armazenar os dados. O driver Ruby (`sqlite3` gem) vem com binaries pré-compilados, mas em ambientes Linux (incluindo Docker) a biblioteca de runtime precisa estar presente:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Debian/Ubuntu
|
|
13
|
+
apt-get install libsqlite3-0
|
|
14
|
+
|
|
15
|
+
# Alpine
|
|
16
|
+
apk add sqlite-libs
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
No Dockerfile da sua aplicação:
|
|
20
|
+
|
|
21
|
+
```dockerfile
|
|
22
|
+
RUN apt-get install --no-install-recommends -y libsqlite3-0
|
|
23
|
+
```
|
|
6
24
|
|
|
7
25
|
## Installation
|
|
8
26
|
|
|
9
|
-
Adicione ao Gemfile da sua
|
|
27
|
+
Adicione ao Gemfile da sua aplicação:
|
|
10
28
|
|
|
11
29
|
```ruby
|
|
12
30
|
gem 'tormenta20'
|
|
@@ -26,7 +44,7 @@ gem install tormenta20
|
|
|
26
44
|
|
|
27
45
|
## Usage
|
|
28
46
|
|
|
29
|
-
A gem
|
|
47
|
+
A gem já vem com o banco de dados populado. Basta fazer require e usar:
|
|
30
48
|
|
|
31
49
|
```ruby
|
|
32
50
|
require 'tormenta20'
|
|
@@ -35,18 +53,22 @@ require 'tormenta20'
|
|
|
35
53
|
Tormenta20.magias.count # => 198
|
|
36
54
|
Tormenta20.magias.arcanas # Magias arcanas
|
|
37
55
|
Tormenta20.magias.divinas # Magias divinas
|
|
38
|
-
Tormenta20.magias.by_circle("3") # Magias do
|
|
39
|
-
Tormenta20.magias.by_school('evoc') # Magias de
|
|
56
|
+
Tormenta20.magias.by_circle("3") # Magias do 3º círculo
|
|
57
|
+
Tormenta20.magias.by_school('evoc') # Magias de evocação
|
|
40
58
|
Tormenta20.magias.arcanas.by_circle("1") # Combinar filtros
|
|
41
59
|
|
|
42
60
|
# Classes
|
|
43
61
|
Tormenta20.classes.all
|
|
44
62
|
Tormenta20.classes.conjuradores # Classes com magia
|
|
45
63
|
|
|
64
|
+
# Raças
|
|
65
|
+
Tormenta20.racas.all
|
|
66
|
+
Tormenta20.racas.find('anao')
|
|
67
|
+
|
|
46
68
|
# Origens
|
|
47
69
|
Tormenta20.origens.all
|
|
48
70
|
Tormenta20.origens.find('soldado')
|
|
49
|
-
Tormenta20.origens.with_unique_power # Origens com poder
|
|
71
|
+
Tormenta20.origens.with_unique_power # Origens com poder único
|
|
50
72
|
|
|
51
73
|
# Divindades
|
|
52
74
|
Tormenta20.divindades.all
|
|
@@ -55,10 +77,16 @@ Tormenta20.divindades.energia_negativa # Deuses de energia negativa
|
|
|
55
77
|
|
|
56
78
|
# Poderes
|
|
57
79
|
Tormenta20.poderes.all
|
|
58
|
-
Tormenta20.poderes.habilidades_unicas # Habilidades
|
|
80
|
+
Tormenta20.poderes.habilidades_unicas # Habilidades únicas de origem
|
|
59
81
|
Tormenta20.poderes.poderes_concedidos # Poderes concedidos por divindades
|
|
60
82
|
Tormenta20.poderes.poderes_tormenta # Poderes da Tormenta
|
|
61
83
|
|
|
84
|
+
# Condições
|
|
85
|
+
Tormenta20.condicoes.all
|
|
86
|
+
Tormenta20.condicoes.by_type('medo')
|
|
87
|
+
Tormenta20.condicoes.medo
|
|
88
|
+
Tormenta20.condicoes.mental
|
|
89
|
+
|
|
62
90
|
# Equipamentos
|
|
63
91
|
Tormenta20.armas.all
|
|
64
92
|
Tormenta20.armas.simples # Armas simples
|
|
@@ -69,17 +97,24 @@ Tormenta20.escudos.all
|
|
|
69
97
|
|
|
70
98
|
# Itens Superiores
|
|
71
99
|
Tormenta20.materiais_especiais.all
|
|
100
|
+
Tormenta20.melhorias.all
|
|
72
101
|
|
|
73
102
|
# Regras
|
|
74
103
|
Tormenta20.regras.all
|
|
104
|
+
|
|
105
|
+
# Índice Remissivo
|
|
106
|
+
Tormenta20.livros.all
|
|
107
|
+
Tormenta20.indice_remissivo.do_livro('t20_eja')
|
|
108
|
+
Tormenta20.indice_remissivo.para_tabela('classes')
|
|
109
|
+
Tormenta20.indice_remissivo.buscar_termo('Fúria')
|
|
75
110
|
```
|
|
76
111
|
|
|
77
112
|
### Query Interface
|
|
78
113
|
|
|
79
|
-
A gem oferece uma interface de consulta simplificada. Todos os
|
|
114
|
+
A gem oferece uma interface de consulta simplificada. Todos os métodos retornam modelos ActiveRecord, permitindo encadeamento de scopes e queries:
|
|
80
115
|
|
|
81
116
|
```ruby
|
|
82
|
-
# Accessors
|
|
117
|
+
# Accessors disponíveis
|
|
83
118
|
Tormenta20.origens # => Tormenta20::Models::Origem
|
|
84
119
|
Tormenta20.poderes # => Tormenta20::Models::Poder
|
|
85
120
|
Tormenta20.divindades # => Tormenta20::Models::Divindade
|
|
@@ -92,67 +127,128 @@ Tormenta20.itens # => Tormenta20::Models::Item
|
|
|
92
127
|
Tormenta20.materiais_especiais # => Tormenta20::Models::MaterialEspecial
|
|
93
128
|
Tormenta20.melhorias # => Tormenta20::Models::Melhoria
|
|
94
129
|
Tormenta20.regras # => Tormenta20::Models::Regra
|
|
130
|
+
Tormenta20.racas # => Tormenta20::Models::Raca
|
|
131
|
+
Tormenta20.condicoes # => Tormenta20::Models::Condicao
|
|
132
|
+
Tormenta20.livros # => Tormenta20::Models::Livro
|
|
133
|
+
Tormenta20.indice_remissivo # => Tormenta20::Models::IndiceRemissivo
|
|
95
134
|
|
|
96
135
|
# Exemplos de queries ActiveRecord
|
|
97
136
|
Tormenta20.magias.where(type: 'arcana')
|
|
98
137
|
Tormenta20.magias.where(school: 'evoc').order(:name)
|
|
99
|
-
Tormenta20.poderes.where("name LIKE ?", "%
|
|
138
|
+
Tormenta20.poderes.where("name LIKE ?", "%Fúria%")
|
|
100
139
|
```
|
|
101
140
|
|
|
102
|
-
### Models
|
|
141
|
+
### Models Disponíveis
|
|
103
142
|
|
|
104
|
-
| Model |
|
|
143
|
+
| Model | Descrição | Quantidade | Documentação |
|
|
105
144
|
|-------|-----------|------------|--------------|
|
|
106
145
|
| `Magia` | Magias arcanas, divinas e universais | 198 | [docs/magias.md](docs/magias.md) |
|
|
107
146
|
| `Classe` | Classes de personagem | 14 | [docs/classes.md](docs/classes.md) |
|
|
108
147
|
| `Origem` | Origens de personagem | 35 | [docs/origens.md](docs/origens.md) |
|
|
109
|
-
| `Divindade` | Deuses do
|
|
110
|
-
| `Poder` | Poderes (habilidades
|
|
148
|
+
| `Divindade` | Deuses do Panteão | 20 | [docs/divindades.md](docs/divindades.md) |
|
|
149
|
+
| `Poder` | Poderes (habilidades únicas, concedidos, tormenta, classe, raça) | 518 | [docs/poderes.md](docs/poderes.md) |
|
|
150
|
+
| `Raca` | Raças jogáveis | 18 | [docs/racas.md](docs/racas.md) |
|
|
151
|
+
| `Condicao` | Condições de status | 35 | [docs/condicoes.md](docs/condicoes.md) |
|
|
111
152
|
| `Arma` | Armas | - | [docs/armas.md](docs/armas.md) |
|
|
112
153
|
| `Armadura` | Armaduras | - | [docs/armaduras.md](docs/armaduras.md) |
|
|
113
154
|
| `Escudo` | Escudos | 2 | [docs/escudos.md](docs/escudos.md) |
|
|
114
155
|
| `Item` | Itens gerais | - | [docs/itens.md](docs/itens.md) |
|
|
115
156
|
| `MaterialEspecial` | Materiais especiais | 6 | [docs/materiais_especiais.md](docs/materiais_especiais.md) |
|
|
116
|
-
| `Melhoria` | Melhorias
|
|
117
|
-
| `Regra` | Regras e dados de
|
|
157
|
+
| `Melhoria` | Melhorias mágicas | - | [docs/melhorias.md](docs/melhorias.md) |
|
|
158
|
+
| `Regra` | Regras e dados de referência | 14 | [docs/regras.md](docs/regras.md) |
|
|
159
|
+
| `Livro` | Livros indexados | 1 | [docs/livros.md](docs/livros.md) |
|
|
160
|
+
| `IndiceRemissivo` | Entradas do índice remissivo | 1098 | [docs/indice_remissivo.md](docs/indice_remissivo.md) |
|
|
161
|
+
|
|
162
|
+
### Referência de Livro e Página
|
|
163
|
+
|
|
164
|
+
Todos os modelos incluem o concern `BookReferenceable`. Se o registro estiver indexado no índice remissivo, os seguintes métodos ficam disponíveis:
|
|
118
165
|
|
|
119
|
-
|
|
166
|
+
```ruby
|
|
167
|
+
guerreiro = Tormenta20.classes.find('guerreiro')
|
|
168
|
+
|
|
169
|
+
guerreiro.book_reference # => "T20 - EJA, p. 64"
|
|
170
|
+
guerreiro.page # => 64
|
|
171
|
+
guerreiro.book # => "T20 - EJA"
|
|
172
|
+
guerreiro.full_book # => "Tormenta 20 - Edição Jogo do Ano"
|
|
173
|
+
|
|
174
|
+
# Retorna nil se o registro não estiver no índice
|
|
175
|
+
item_sem_indice = Tormenta20.itens.first
|
|
176
|
+
item_sem_indice.book_reference # => nil
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
O resultado é memoizado por instância — o banco é consultado apenas uma vez por objeto.
|
|
180
|
+
|
|
181
|
+
Os dados do índice remissivo são carregados de `src/json/indice_remissivo/<livro_id>.json`. Atualmente inclui o índice de **Tormenta 20 - Edição Jogo do Ano** (`t20_eja`) com mais de 1000 entradas.
|
|
182
|
+
|
|
183
|
+
### Índice Remissivo
|
|
184
|
+
|
|
185
|
+
O model `IndiceRemissivo` permite buscar entradas por livro, tabela ou termo:
|
|
186
|
+
|
|
187
|
+
```ruby
|
|
188
|
+
# Todas as entradas de um livro
|
|
189
|
+
Tormenta20.indice_remissivo.do_livro('t20_eja')
|
|
190
|
+
|
|
191
|
+
# Entradas vinculadas a uma tabela específica
|
|
192
|
+
Tormenta20.indice_remissivo.para_tabela('classes')
|
|
193
|
+
|
|
194
|
+
# Entradas vinculadas a registros concretos
|
|
195
|
+
Tormenta20.indice_remissivo.associados
|
|
196
|
+
|
|
197
|
+
# Entradas sem vínculo a registro
|
|
198
|
+
Tormenta20.indice_remissivo.nao_associados
|
|
199
|
+
|
|
200
|
+
# Busca por termo
|
|
201
|
+
Tormenta20.indice_remissivo.buscar_termo('Fúria')
|
|
202
|
+
|
|
203
|
+
# Consultar o livro de uma entrada
|
|
204
|
+
entrada = Tormenta20.indice_remissivo.first
|
|
205
|
+
entrada.livro.nome # => "Tormenta 20 - Edição Jogo do Ano"
|
|
206
|
+
entrada.livro.nome_curto # => "T20 - EJA"
|
|
207
|
+
```
|
|
120
208
|
|
|
121
209
|
### Exemplos
|
|
122
210
|
|
|
123
211
|
```ruby
|
|
124
|
-
# Buscar uma magia
|
|
212
|
+
# Buscar uma magia específica
|
|
125
213
|
bola_de_fogo = Tormenta20.magias.find('bola_de_fogo')
|
|
126
|
-
puts bola_de_fogo.name
|
|
127
|
-
puts bola_de_fogo.circle
|
|
128
|
-
puts bola_de_fogo.school
|
|
129
|
-
puts bola_de_fogo.
|
|
214
|
+
puts bola_de_fogo.name # => "Bola de Fogo"
|
|
215
|
+
puts bola_de_fogo.circle # => "3"
|
|
216
|
+
puts bola_de_fogo.school # => "evoc"
|
|
217
|
+
puts bola_de_fogo.book_reference # => "T20 - EJA, p. ..."
|
|
130
218
|
|
|
131
219
|
# Listar poderes de uma divindade
|
|
132
220
|
khalmyr = Tormenta20.divindades.find('khalmyr')
|
|
133
221
|
puts khalmyr.name # => "Khalmyr"
|
|
134
222
|
puts khalmyr.granted_powers # => ["coragem_total", "espada_justiceira", ...]
|
|
223
|
+
puts khalmyr.book_reference # => "T20 - EJA, p. 99"
|
|
135
224
|
|
|
136
|
-
#
|
|
137
|
-
Tormenta20.poderes.poderes_concedidos.each do |poder|
|
|
138
|
-
puts "#{poder.name}: #{poder.deities.join(', ')}"
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
# Classe com informacoes de magia
|
|
225
|
+
# Classe com informações de magia e referência de livro
|
|
142
226
|
mago = Tormenta20.classes.find('arcanista')
|
|
143
227
|
puts mago.initial_hp # PV inicial
|
|
144
|
-
puts mago.mp_per_level # PM por
|
|
228
|
+
puts mago.mp_per_level # PM por nível
|
|
145
229
|
puts mago.conjurador? # => true
|
|
230
|
+
puts mago.book_reference # => "T20 - EJA, p. 36"
|
|
231
|
+
|
|
232
|
+
# Raça com bônus de atributo
|
|
233
|
+
anao = Tormenta20.racas.find('anao')
|
|
234
|
+
puts anao.attribute_bonus_for('constituicao') # => 2
|
|
235
|
+
puts anao.visao_no_escuro? # => true
|
|
236
|
+
puts anao.book_reference # => "T20 - EJA, p. 20"
|
|
146
237
|
|
|
147
|
-
# Filtrar magias arcanas do
|
|
238
|
+
# Filtrar magias arcanas do 1º círculo da escola de evocação
|
|
148
239
|
Tormenta20.magias.arcanas.by_circle("1").by_school("evoc").each do |magia|
|
|
149
|
-
puts "#{magia.name} - #{magia.
|
|
240
|
+
puts "#{magia.name} - #{magia.book_reference}"
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Condições de medo
|
|
244
|
+
Tormenta20.condicoes.medo.each do |c|
|
|
245
|
+
puts "#{c.name}: #{c.escalates_to ? "escala para #{c.escalates_to}" : 'não escala'}"
|
|
150
246
|
end
|
|
151
247
|
```
|
|
152
248
|
|
|
153
249
|
## Development
|
|
154
250
|
|
|
155
|
-
###
|
|
251
|
+
### Pré-requisitos
|
|
156
252
|
|
|
157
253
|
- Ruby >= 3.0.0
|
|
158
254
|
- Bundler
|
|
@@ -167,7 +263,7 @@ bundle install
|
|
|
167
263
|
|
|
168
264
|
### Construir o Banco de Dados
|
|
169
265
|
|
|
170
|
-
O banco de dados SQLite
|
|
266
|
+
O banco de dados SQLite é construído a partir dos arquivos JSON em `src/json/`:
|
|
171
267
|
|
|
172
268
|
```bash
|
|
173
269
|
# Construir apenas o banco
|
|
@@ -193,16 +289,21 @@ tormenta20/
|
|
|
193
289
|
│ │ │ └── poderes_da_tormenta/
|
|
194
290
|
│ │ ├── equipamentos/
|
|
195
291
|
│ │ ├── itens_superiores/
|
|
196
|
-
│ │
|
|
197
|
-
│
|
|
292
|
+
│ │ ├── regras/
|
|
293
|
+
│ │ ├── condicoes/
|
|
294
|
+
│ │ ├── racas/
|
|
295
|
+
│ │ ├── livros/
|
|
296
|
+
│ │ └── indice_remissivo/ # Índice por livro (ex: t20_eja.json)
|
|
297
|
+
│ └── ruby/ # Código Ruby
|
|
198
298
|
│ └── tormenta20/
|
|
199
299
|
│ ├── models/ # ActiveRecord models
|
|
200
|
-
│ ├──
|
|
300
|
+
│ ├── concerns/ # Mixins (BookReferenceable)
|
|
301
|
+
│ ├── database.rb # Conexão com banco
|
|
201
302
|
│ └── seeder.rb # Import de dados
|
|
202
303
|
├── db/
|
|
203
304
|
│ ├── schema.sql # Schema SQLite
|
|
204
305
|
│ ├── seeds.rb # Script de seed (desenvolvimento)
|
|
205
|
-
│ └── tormenta20.sqlite3 # Banco
|
|
306
|
+
│ └── tormenta20.sqlite3 # Banco pré-construído (gerado)
|
|
206
307
|
└── bin/
|
|
207
308
|
└── build_db # Script de build do banco
|
|
208
309
|
```
|
|
@@ -221,12 +322,12 @@ rake rubocop
|
|
|
221
322
|
|
|
222
323
|
## Contributing
|
|
223
324
|
|
|
224
|
-
Bug reports e pull requests
|
|
325
|
+
Bug reports e pull requests são bem-vindos em https://github.com/LuanGB/tormenta20.
|
|
225
326
|
|
|
226
327
|
## License
|
|
227
328
|
|
|
228
|
-
|
|
329
|
+
Disponível como open source sob os termos da [MIT License](https://opensource.org/licenses/MIT).
|
|
229
330
|
|
|
230
331
|
## Aviso Legal
|
|
231
332
|
|
|
232
|
-
Tormenta20
|
|
333
|
+
Tormenta20 é uma marca registrada da Jambô Editora. Esta biblioteca é um projeto de fã não oficial e não é afiliada, endossada ou patrocinada pela Jambô Editora.
|
data/db/schema.sql
CHANGED
|
@@ -399,6 +399,50 @@ BEGIN
|
|
|
399
399
|
UPDATE condicoes SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
|
|
400
400
|
END;
|
|
401
401
|
|
|
402
|
+
-- -----------------------------------------------------------------------------
|
|
403
|
+
-- LIVROS (Books) — fonte bibliográfica dos dados
|
|
404
|
+
-- -----------------------------------------------------------------------------
|
|
405
|
+
CREATE TABLE IF NOT EXISTS livros (
|
|
406
|
+
id TEXT PRIMARY KEY, -- slug do livro, ex: "t20_eja"
|
|
407
|
+
nome TEXT NOT NULL, -- nome completo
|
|
408
|
+
nome_curto TEXT NOT NULL, -- abreviação exibida, ex: "T20 - EJA"
|
|
409
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
410
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
411
|
+
);
|
|
412
|
+
|
|
413
|
+
CREATE TRIGGER IF NOT EXISTS update_livros_timestamp
|
|
414
|
+
AFTER UPDATE ON livros
|
|
415
|
+
BEGIN
|
|
416
|
+
UPDATE livros SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
|
|
417
|
+
END;
|
|
418
|
+
|
|
419
|
+
-- -----------------------------------------------------------------------------
|
|
420
|
+
-- INDICE_REMISSIVO — entradas do índice remissivo dos livros
|
|
421
|
+
-- Cada linha é um termo do índice associado a uma página.
|
|
422
|
+
-- Os campos `tabela` e `registro_id` são preenchidos quando o termo é
|
|
423
|
+
-- associado a um registro de outra tabela (ex: classes, poderes, magias…).
|
|
424
|
+
-- -----------------------------------------------------------------------------
|
|
425
|
+
CREATE TABLE IF NOT EXISTS indice_remissivo (
|
|
426
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
427
|
+
livro_id TEXT NOT NULL REFERENCES livros(id),
|
|
428
|
+
termo TEXT NOT NULL, -- termo exatamente como aparece no índice
|
|
429
|
+
pagina INTEGER NOT NULL, -- número da página
|
|
430
|
+
tabela TEXT, -- tabela associada (ex: "classes", "poderes")
|
|
431
|
+
registro_id TEXT, -- id do registro associado (ex: "guerreiro")
|
|
432
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
433
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
434
|
+
);
|
|
435
|
+
|
|
436
|
+
CREATE INDEX IF NOT EXISTS idx_indice_termo ON indice_remissivo(termo);
|
|
437
|
+
CREATE INDEX IF NOT EXISTS idx_indice_livro ON indice_remissivo(livro_id);
|
|
438
|
+
CREATE INDEX IF NOT EXISTS idx_indice_registro ON indice_remissivo(tabela, registro_id);
|
|
439
|
+
|
|
440
|
+
CREATE TRIGGER IF NOT EXISTS update_indice_remissivo_timestamp
|
|
441
|
+
AFTER UPDATE ON indice_remissivo
|
|
442
|
+
BEGIN
|
|
443
|
+
UPDATE indice_remissivo SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
|
|
444
|
+
END;
|
|
445
|
+
|
|
402
446
|
-- =============================================================================
|
|
403
447
|
-- VIEWS ÚTEIS
|
|
404
448
|
-- =============================================================================
|
data/db/tormenta20.sqlite3
CHANGED
|
Binary file
|
data/docs/armaduras.md
CHANGED
|
@@ -4,17 +4,17 @@ Acesso: `Tormenta20.armaduras`
|
|
|
4
4
|
|
|
5
5
|
## Atributos
|
|
6
6
|
|
|
7
|
-
| Atributo | Tipo |
|
|
7
|
+
| Atributo | Tipo | Descrição |
|
|
8
8
|
|----------|------|-----------|
|
|
9
|
-
| `id` | String | Identificador
|
|
9
|
+
| `id` | String | Identificador único |
|
|
10
10
|
| `name` | String | Nome da armadura |
|
|
11
11
|
| `category` | String | Categoria: `leve`, `pesada` |
|
|
12
|
-
| `price` | String |
|
|
13
|
-
| `defense_bonus` | Integer |
|
|
12
|
+
| `price` | String | Preço |
|
|
13
|
+
| `defense_bonus` | Integer | Bônus de defesa |
|
|
14
14
|
| `armor_penalty` | Integer | Penalidade de armadura |
|
|
15
|
-
| `weight` | String | Peso/
|
|
15
|
+
| `weight` | String | Peso/espaços |
|
|
16
16
|
| `properties` | Array | Propriedades especiais |
|
|
17
|
-
| `description` | String |
|
|
17
|
+
| `description` | String | Descrição |
|
|
18
18
|
|
|
19
19
|
## Scopes (Filtros)
|
|
20
20
|
|
|
@@ -26,15 +26,15 @@ Tormenta20.armaduras.pesadas # Armaduras pesadas
|
|
|
26
26
|
Tormenta20.armaduras.by_category("leve")
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
##
|
|
29
|
+
## Métodos de Instância
|
|
30
30
|
|
|
31
31
|
```ruby
|
|
32
32
|
armadura = Tormenta20.armaduras.find("couro")
|
|
33
33
|
|
|
34
|
-
armadura.leve? # Verifica se
|
|
34
|
+
armadura.leve? # Verifica se é armadura leve
|
|
35
35
|
# => true
|
|
36
36
|
|
|
37
|
-
armadura.pesada? # Verifica se
|
|
37
|
+
armadura.pesada? # Verifica se é armadura pesada
|
|
38
38
|
# => false
|
|
39
39
|
|
|
40
40
|
armadura.to_h # Converte para Hash completo
|
|
@@ -53,18 +53,18 @@ Tormenta20.armaduras.leves.each do |a|
|
|
|
53
53
|
puts "#{a.name} - #{a.price}"
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
# Armaduras pesadas ordenadas por
|
|
56
|
+
# Armaduras pesadas ordenadas por bônus de defesa
|
|
57
57
|
Tormenta20.armaduras.pesadas.order(defense_bonus: :desc).each do |a|
|
|
58
58
|
puts "#{a.name}: +#{a.defense_bonus}"
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
# Buscar armadura
|
|
61
|
+
# Buscar armadura específica
|
|
62
62
|
brunea = Tormenta20.armaduras.find("brunea")
|
|
63
63
|
puts brunea.name # => "Brunea"
|
|
64
|
-
puts brunea.defense_bonus #
|
|
64
|
+
puts brunea.defense_bonus # Bônus de defesa
|
|
65
65
|
puts brunea.armor_penalty # Penalidade
|
|
66
66
|
|
|
67
|
-
# Armadura com maior
|
|
67
|
+
# Armadura com maior bônus de defesa
|
|
68
68
|
Tormenta20.armaduras.order(defense_bonus: :desc).first
|
|
69
69
|
|
|
70
70
|
# Armaduras sem penalidade
|
data/docs/armas.md
CHANGED
|
@@ -4,19 +4,19 @@ Acesso: `Tormenta20.armas`
|
|
|
4
4
|
|
|
5
5
|
## Atributos
|
|
6
6
|
|
|
7
|
-
| Atributo | Tipo |
|
|
7
|
+
| Atributo | Tipo | Descrição |
|
|
8
8
|
|----------|------|-----------|
|
|
9
|
-
| `id` | String | Identificador
|
|
9
|
+
| `id` | String | Identificador único |
|
|
10
10
|
| `name` | String | Nome da arma |
|
|
11
11
|
| `category` | String | Categoria: `simples`, `marciais`, `exoticas`, `fogo` |
|
|
12
|
-
| `price` | String |
|
|
12
|
+
| `price` | String | Preço |
|
|
13
13
|
| `damage` | String | Dano (ex: "1d8") |
|
|
14
|
-
| `damage_type` | String | Tipo de dano (corte,
|
|
15
|
-
| `critical` | String |
|
|
16
|
-
| `range` | String | Alcance (para armas de
|
|
17
|
-
| `weight` | String | Peso/
|
|
14
|
+
| `damage_type` | String | Tipo de dano (corte, perfuração, etc) |
|
|
15
|
+
| `critical` | String | Crítico (ex: "19/x2") |
|
|
16
|
+
| `range` | String | Alcance (para armas de distância) |
|
|
17
|
+
| `weight` | String | Peso/espaços |
|
|
18
18
|
| `properties` | Array | Propriedades especiais |
|
|
19
|
-
| `description` | String |
|
|
19
|
+
| `description` | String | Descrição |
|
|
20
20
|
|
|
21
21
|
## Scopes (Filtros)
|
|
22
22
|
|
|
@@ -25,7 +25,7 @@ Acesso: `Tormenta20.armas`
|
|
|
25
25
|
```ruby
|
|
26
26
|
Tormenta20.armas.simples # Armas simples
|
|
27
27
|
Tormenta20.armas.marciais # Armas marciais
|
|
28
|
-
Tormenta20.armas.exoticas # Armas
|
|
28
|
+
Tormenta20.armas.exoticas # Armas exóticas
|
|
29
29
|
Tormenta20.armas.fogo # Armas de fogo
|
|
30
30
|
Tormenta20.armas.by_category("simples")
|
|
31
31
|
```
|
|
@@ -41,16 +41,16 @@ Tormenta20.armas.by_damage_type("impacto")
|
|
|
41
41
|
### Por Alcance
|
|
42
42
|
|
|
43
43
|
```ruby
|
|
44
|
-
Tormenta20.armas.ranged # Armas de
|
|
44
|
+
Tormenta20.armas.ranged # Armas de distância (com alcance)
|
|
45
45
|
Tormenta20.armas.melee # Armas corpo a corpo (sem alcance)
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
##
|
|
48
|
+
## Métodos de Instância
|
|
49
49
|
|
|
50
50
|
```ruby
|
|
51
51
|
arma = Tormenta20.armas.find("espada_longa")
|
|
52
52
|
|
|
53
|
-
arma.ranged? # Verifica se
|
|
53
|
+
arma.ranged? # Verifica se é arma de distância
|
|
54
54
|
# => false
|
|
55
55
|
|
|
56
56
|
arma.to_h # Converte para Hash completo
|
|
@@ -69,7 +69,7 @@ Tormenta20.armas.simples.each do |a|
|
|
|
69
69
|
puts "#{a.name} - #{a.price}"
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
-
# Armas de
|
|
72
|
+
# Armas de distância
|
|
73
73
|
Tormenta20.armas.ranged.each do |a|
|
|
74
74
|
puts "#{a.name}: alcance #{a.range}"
|
|
75
75
|
end
|
|
@@ -79,7 +79,7 @@ Tormenta20.armas.by_damage_type("corte").each do |a|
|
|
|
79
79
|
puts "#{a.name}: #{a.damage}"
|
|
80
80
|
end
|
|
81
81
|
|
|
82
|
-
# Buscar arma
|
|
82
|
+
# Buscar arma específica
|
|
83
83
|
espada = Tormenta20.armas.find("espada_longa")
|
|
84
84
|
puts espada.name # => "Espada Longa"
|
|
85
85
|
puts espada.damage # => "1d8"
|
data/docs/condicoes.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Condições
|
|
2
|
+
|
|
3
|
+
Acesso: `Tormenta20.condicoes`
|
|
4
|
+
|
|
5
|
+
## Atributos
|
|
6
|
+
|
|
7
|
+
| Atributo | Tipo | Descrição |
|
|
8
|
+
|----------|------|-----------|
|
|
9
|
+
| `id` | String | Identificador único (ex: `"abalado"`) |
|
|
10
|
+
| `name` | String | Nome da condição |
|
|
11
|
+
| `description` | String | Descrição completa da condição |
|
|
12
|
+
| `effects` | Array | Lista de efeitos mecânicos |
|
|
13
|
+
| `condition_type` | String / nil | Categoria da condição (ver abaixo) |
|
|
14
|
+
| `escalates_to` | String / nil | ID da condição para a qual esta escala ao ser reaplicada |
|
|
15
|
+
|
|
16
|
+
### Tipos de Condição (`condition_type`)
|
|
17
|
+
|
|
18
|
+
| Tipo | Descrição |
|
|
19
|
+
|------|-----------|
|
|
20
|
+
| `medo` | Condições de medo (abalado, apavorado) |
|
|
21
|
+
| `mental` | Condições mentais (fascinado, confuso) |
|
|
22
|
+
| `metabolismo` | Condições metabólicas (envenenado, doente) |
|
|
23
|
+
| `movimento` | Condições de movimento (lento, imóvel, paralisado) |
|
|
24
|
+
| `veneno` | Condições de veneno |
|
|
25
|
+
| `sentidos` | Condições de sentido (cego, surdo) |
|
|
26
|
+
| `cansaco` | Condições de fadiga (fatigado, exausto) |
|
|
27
|
+
| `metamorfose` | Condições de metamorfose (petrificado) |
|
|
28
|
+
|
|
29
|
+
## Scopes (Filtros)
|
|
30
|
+
|
|
31
|
+
```ruby
|
|
32
|
+
Tormenta20.condicoes.by_type("medo") # Filtro genérico por tipo
|
|
33
|
+
Tormenta20.condicoes.medo # Condições de medo
|
|
34
|
+
Tormenta20.condicoes.mental # Condições mentais
|
|
35
|
+
Tormenta20.condicoes.metabolismo # Condições metabólicas
|
|
36
|
+
Tormenta20.condicoes.movimento # Condições de movimento
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Métodos de Instância
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
condicao = Tormenta20.condicoes.find("abalado")
|
|
43
|
+
|
|
44
|
+
condicao.name # => "Abalado"
|
|
45
|
+
condicao.description # Texto completo
|
|
46
|
+
condicao.effects # => ["...", "..."]
|
|
47
|
+
condicao.condition_type # => "medo"
|
|
48
|
+
condicao.escalates_to # => "apavorado" (ou nil)
|
|
49
|
+
|
|
50
|
+
condicao.to_h # Hash completo
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Exemplos
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
# Listar todas as condições
|
|
57
|
+
Tormenta20.condicoes.all.each do |c|
|
|
58
|
+
puts c.name
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Condições que escalam para outra
|
|
62
|
+
Tormenta20.condicoes.select { |c| c.escalates_to.present? }.each do |c|
|
|
63
|
+
puts "#{c.name} → #{c.escalates_to}"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Condições de medo em ordem de gravidade
|
|
67
|
+
Tormenta20.condicoes.medo.each do |c|
|
|
68
|
+
puts "#{c.name}: #{c.effects.first}"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Efeitos de uma condição específica
|
|
72
|
+
paralisado = Tormenta20.condicoes.find("paralisado")
|
|
73
|
+
paralisado.effects.each { |e| puts "- #{e}" }
|
|
74
|
+
|
|
75
|
+
# Referência de livro
|
|
76
|
+
Tormenta20.condicoes.find("abalado").book_reference # => "T20 - EJA, p. 394"
|
|
77
|
+
```
|
data/docs/divindades.md
CHANGED
|
@@ -4,19 +4,19 @@ Acesso: `Tormenta20.divindades`
|
|
|
4
4
|
|
|
5
5
|
## Atributos
|
|
6
6
|
|
|
7
|
-
| Atributo | Tipo |
|
|
7
|
+
| Atributo | Tipo | Descrição |
|
|
8
8
|
|----------|------|-----------|
|
|
9
|
-
| `id` | String | Identificador
|
|
9
|
+
| `id` | String | Identificador único |
|
|
10
10
|
| `name` | String | Nome da divindade |
|
|
11
|
-
| `title` | String |
|
|
12
|
-
| `description` | String |
|
|
13
|
-
| `beliefs_objectives` | String |
|
|
14
|
-
| `holy_symbol` | String |
|
|
11
|
+
| `title` | String | Título/epíteto |
|
|
12
|
+
| `description` | String | Descrição |
|
|
13
|
+
| `beliefs_objectives` | String | Crenças e objetivos |
|
|
14
|
+
| `holy_symbol` | String | Símbolo sagrado |
|
|
15
15
|
| `energy` | String | Tipo de energia: `positiva`, `negativa`, `qualquer` |
|
|
16
16
|
| `preferred_weapon` | String | Arma preferida |
|
|
17
|
-
| `devotees` | Hash | Devotos
|
|
17
|
+
| `devotees` | Hash | Devotos típicos (races, classes) |
|
|
18
18
|
| `granted_powers` | Array | Lista de poderes concedidos |
|
|
19
|
-
| `obligations_restrictions` | String |
|
|
19
|
+
| `obligations_restrictions` | String | Obrigações e restrições |
|
|
20
20
|
|
|
21
21
|
## Scopes (Filtros)
|
|
22
22
|
|
|
@@ -29,12 +29,12 @@ Tormenta20.divindades.energia_qualquer # Deuses de energia neutra
|
|
|
29
29
|
Tormenta20.divindades.by_energy("positiva")
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## Métodos de Instância
|
|
33
33
|
|
|
34
34
|
```ruby
|
|
35
35
|
divindade = Tormenta20.divindades.find("khalmyr")
|
|
36
36
|
|
|
37
|
-
divindade.races #
|
|
37
|
+
divindade.races # Raças devotas
|
|
38
38
|
# => ["humano", "anao"]
|
|
39
39
|
|
|
40
40
|
divindade.classes # Classes devotas
|
|
@@ -56,14 +56,14 @@ Tormenta20.divindades.energia_positiva.each do |d|
|
|
|
56
56
|
puts "#{d.name}: #{d.granted_powers.join(', ')}"
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
# Buscar divindade
|
|
59
|
+
# Buscar divindade específica
|
|
60
60
|
khalmyr = Tormenta20.divindades.find("khalmyr")
|
|
61
61
|
puts khalmyr.name # => "Khalmyr"
|
|
62
|
-
puts khalmyr.title # => "O Deus da
|
|
62
|
+
puts khalmyr.title # => "O Deus da Justiça"
|
|
63
63
|
puts khalmyr.preferred_weapon # => "Espada longa"
|
|
64
64
|
puts khalmyr.granted_powers # Lista de poderes concedidos
|
|
65
65
|
|
|
66
|
-
# Divindades que concedem um poder
|
|
66
|
+
# Divindades que concedem um poder específico
|
|
67
67
|
Tormenta20.divindades.select do |d|
|
|
68
68
|
d.granted_powers&.include?("cura_pelas_maos")
|
|
69
69
|
end
|
|
@@ -72,6 +72,6 @@ end
|
|
|
72
72
|
Tormenta20.divindades.group(:energy).count
|
|
73
73
|
# => {"positiva"=>12, "negativa"=>6, "qualquer"=>2}
|
|
74
74
|
|
|
75
|
-
# Divindades adoradas por uma
|
|
75
|
+
# Divindades adoradas por uma raça
|
|
76
76
|
Tormenta20.divindades.select { |d| d.races.include?("elfo") }
|
|
77
77
|
```
|