Compare commits

...

6 Commits

99 changed files with 1369 additions and 1 deletions

8
.gitignore vendored
View File

@@ -20,6 +20,9 @@ target/
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
.idea
custom-bullshit
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
@@ -95,3 +98,8 @@ fabric.properties
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
# Added by cargo
/target

7
Cargo.lock generated Normal file
View File

@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "owlibou_tavern"
version = "0.1.0"

6
Cargo.toml Normal file
View File

@@ -0,0 +1,6 @@
[package]
name = "owlibou_tavern"
version = "0.1.0"
edition = "2024"
[dependencies]

108
README.md
View File

@@ -1,2 +1,108 @@
# owly_tavern
# Owlibou Tavern
Ein flexibles Management-Tool für Tabletop-RPGs (TTRPG), mit dem du Kampagnen-, Welt- und Spieldaten zentral verwaltest. Im Frontend kannst du Daten aus der Datenbank komfortabel anlegen, bearbeiten, importieren und exportieren ideal für Spielleitungen, Weltbauer:innen und Orga-Teams.
## Ziele und Nutzen
- Einheitliche Verwaltung von TTRPG-Daten wie Charaktere, NSCs, Orte, Items, Quests, Regeln und Sessions.
- Datenpflege direkt im Browser mit validierten Formularen und Listenansichten.
- Revisionssichere Änderungen sowie Import/Export für Backups, Systemwechsel oder öffentliche Datenpakete.
- Erweiterbar und systemagnostisch: nutzbar für verschiedene TTRPG-Systeme und Hausregeln.
## Hauptfunktionen (geplant/initial)
- Datenverwaltung
- CRUD für zentrale Entitäten (z. B. Charaktere, Orte, Items, Quests, Sessions)
- Tagging, Relationen und Referenzen (z. B. Item gehört zu Charakter, Quest findet in Ort statt)
- Versionierung/Änderungshistorie (optional)
- Import/Export
- JSON- und CSV-Importe mit Mapping/Validierung
- JSON- und CSV-Exporte (vollständig oder gefiltert)
- Vorlagen für gängige Datenstrukturen
- Qualität und Sicherheit
- Validierungen, Duplikat-Erkennung, Konfliktauflösungen beim Import
- Rollen-/Rechtekonzept für Lesende/Schreibende (optional)
- UX
- Filter, Suche, Sortierung, Paginierung
- Bulk-Aktionen (z. B. Massen-Tagging, Sammellöschung mit Undo)
## Architekturüberblick
- Frontend
- Web-App zur Verwaltung, Visualisierung und zum Import/Export von Daten
- Formulare mit Validierung, Listenansichten, Detailseiten
- API/Backend
- Endpunkte für CRUD, Batch-Operationen, Import/Export und Authentifizierung
- Datenvalidierung serverseitig und konfliktarme Merges bei Importen
- Datenbank
- Relational oder dokumentenorientiert, je nach finalem Design
- Migrationskonzept, Seeds und Beispiel-Datasets
- Authentifizierung/Autorisierung (optional)
- Nutzerkonten, Rollen, API-Tokens
Hinweis: Die konkrete Technologieauswahl kann projektabhängig variieren. Dieses README bleibt bewusst technologie-agnostisch.
## Datenmodell (Beispiel-Ideen)
- Kern-Entitäten: Character, NPC, Location, Item, Quest, Session, Faction, Rule
- Relationen: Character—Item (1:n), Location—Quest (n:m), Session—Participant (n:m)
- Metadaten: Tags, Notizen, Quellenangaben, Zeitstempel, Besitzer:in
## Import/Export
- Formate
- JSON: vollständige Strukturen inkl. Relationen
- CSV: tabellarische Views je Entität
- Import-Workflow
- Vorschau mit Validierungsfehlern und Warnungen
- Mapping-Assistent (z. B. Spaltenzuordnung bei CSV)
- Konflikt-Strategien: Überschreiben, Zusammenführen, Duplikate überspringen
- Export-Workflow
- Auswahl von Entitäten/Filtern, optional Anonymisierung bestimmter Felder
- Versionierte Exporte als Backup
## Entwicklungs-Setup
- Voraussetzungen
- Git, eine aktuelle Laufzeitumgebung für Frontend/Backend, Paketmanager, Datenbank-Server
- Quickstart (generisch)
1. Repository klonen
2. Umgebungsvariablen konfigurieren (z. B. DB-URL, Ports, Auth-Secret)
3. Abhängigkeiten installieren
4. Datenbank migrieren und Seed-Daten einspielen (optional)
5. Entwicklungsserver starten (Frontend und Backend)
- Skripte (Platzhalter)
- start-dev: Startet Frontend und Backend im Watch-Modus
- migrate: Führt Datenbankmigrationen aus
- seed: Spielt Beispiel-/Demo-Daten ein
- test: Führt Tests aus
- build: Erzeugt produktionsfertige Artefakte
Füge konkrete Befehle hinzu, sobald die Technologie-Stacks final sind.
## Deployment (Beispielfluss)
- Konfiguration über Umgebungsvariablen/Secrets
- Datenbank bereitstellen und Migrationen ausführen
- Backend deployen
- Frontend als statische App oder über denselben Server ausliefern
- Optional: Containerisierung und Orchestrierung
## Qualitätssicherung
- Tests: Unit-, Integrations- und E2E-Tests für Import/Export und CRUD
- Linting/Formatting und CI-Pipelines
- Backups: regelmäßige Exporte und DB-Snapshots
## Roadmap (Entwurf)
- M0: Basis-CRUD für zentrale Entitäten, einfache JSON-Exporte
- M1: CSV-Importe mit Mapping + Validierung, Filter/Suche im UI
- M2: Relationen-Management im UI, Konfliktauflösung beim Import
- M3: Rollen/Rechte, Änderungsverlauf, Bulk-Aktionen
- M4: Plugins/Erweiterungen für system-spezifische Felder und Regelwerke
## Beitragen
- Issues eröffnen: Bugreports, Featurewünsche, Fragen
- Pull Requests: Bitte mit kurzer Beschreibung, Repro-Schritten und Tests
- Coding Guidelines: Einheitlicher Stil, aussagekräftige Commits
## Lizenz
- AGPLv3
## Kontakt
- Projektpflege: bitte Kontaktmethode/Team hinzufügen
- Diskussionen/Ideen: Issue-Tracker oder Diskussionsforum verwenden
Viel Spaß beim Bauen deiner TTRPG-Welt mit Owlibou Tavern!

View File

@@ -0,0 +1,17 @@
create table alchemical_recipe
(
id INTEGER
primary key,
name TEXT not null
unique,
result_item_id INTEGER
references item,
herstellungs_talent_id INTEGER not null
references talent,
herstellungs_probe_mod INTEGER default 0,
labor_schwierigkeit TEXT,
rezept_kosten_heller INTEGER,
wirkungsbeschreibung TEXT,
wirkung_strukturiert TEXT
);

View File

@@ -0,0 +1,11 @@
create table ammunition
(
id INTEGER
primary key,
item_id INTEGER not null
unique
references item
on delete cascade,
passend_fuer_fk_waffe_typ TEXT
);

13
database/main/armor.sql Normal file
View File

@@ -0,0 +1,13 @@
create table armor
(
id INTEGER
primary key,
item_id INTEGER not null
unique
references item
on delete cascade,
ruestungsschutz INTEGER not null,
behaelinderung REAL not null,
zonen TEXT
);

View File

@@ -0,0 +1,9 @@
create table attribute
(
id INTEGER
primary key,
code TEXT
unique,
name TEXT
);

View File

@@ -0,0 +1,9 @@
create table availability_level
(
id INTEGER
primary key,
stufe INTEGER not null
unique,
beschreibung TEXT
);

20
database/main/book.sql Normal file
View File

@@ -0,0 +1,20 @@
create table book
(
id INTEGER
primary key,
code TEXT not null
unique,
title TEXT not null,
subtitle TEXT,
series TEXT,
volume TEXT,
edition TEXT,
isbn13 TEXT
unique,
publisher TEXT,
language TEXT,
published_at TEXT,
url TEXT,
license TEXT
);

View File

@@ -0,0 +1,17 @@
create table citation
(
id INTEGER
primary key,
book_id INTEGER not null
references book
on delete cascade,
page_start INTEGER not null,
page_end INTEGER,
section TEXT,
anchor TEXT,
note TEXT
);
create index idx_citation_book
on citation (book_id, page_start);

View File

@@ -0,0 +1,20 @@
create table crafting_recipe
(
id INTEGER
primary key,
result_item_id INTEGER not null
references item,
required_talent_id INTEGER not null
references talent,
required_fw INTEGER not null,
zeitaufwand_in_ze TEXT,
benoetigte_materialien TEXT,
anmerkung TEXT
);
create index idx_crafting_recipe_item
on crafting_recipe (result_item_id);
create index idx_crafting_recipe_talent
on crafting_recipe (required_talent_id);

View File

@@ -0,0 +1,27 @@
create table creature
(
id INTEGER
primary key,
optolith_key TEXT
unique,
name TEXT not null,
typ TEXT,
groessenkategorie TEXT,
attr_mu INTEGER,
attr_kl INTEGER,
attr_in INTEGER,
attr_ch INTEGER,
attr_ff INTEGER,
attr_ge INTEGER,
attr_ko INTEGER,
attr_kk INTEGER,
le_formel TEXT,
sk_wert INTEGER,
zk_wert INTEGER,
gs_wert INTEGER,
ini_formel TEXT,
rs_wert INTEGER,
beschreibung TEXT,
fluchtverhalten TEXT
);

View File

@@ -0,0 +1,15 @@
create table creature_attack
(
id INTEGER
primary key,
creature_id INTEGER not null
references creature
on delete cascade,
name TEXT not null,
at_wert INTEGER,
pa_wert INTEGER,
tp_formel TEXT,
reichweite TEXT,
eigenschaften TEXT
);

View File

@@ -0,0 +1,14 @@
create table creature_attack_has_property
(
attack_id INTEGER not null
references creature_attack
on delete cascade,
property_id INTEGER not null
references creature_attack_property
on delete restrict,
primary key (attack_id, property_id)
);
create index idx_creature_attack_has_prop_prop
on creature_attack_has_property (property_id);

View File

@@ -0,0 +1,9 @@
create table creature_attack_property
(
id INTEGER
primary key,
name TEXT not null
unique,
beschreibung TEXT
);

View File

@@ -0,0 +1,14 @@
create table creature_special_ability
(
creature_id INTEGER not null
references creature
on delete cascade,
special_ability_id INTEGER not null
references special_ability
on delete restrict,
primary key (creature_id, special_ability_id)
);
create index idx_creature_sa_sa
on creature_special_ability (special_ability_id);

View File

@@ -0,0 +1,15 @@
create table creature_talent
(
creature_id INTEGER not null
references creature
on delete cascade,
talent_id INTEGER not null
references talent
on delete restrict,
fertigkeitswert INTEGER not null,
primary key (creature_id, talent_id)
);
create index idx_creature_talent_talent
on creature_talent (talent_id);

12
database/main/culture.sql Normal file
View File

@@ -0,0 +1,12 @@
create table culture
(
id INTEGER
primary key,
optolith_key TEXT not null
unique,
name TEXT not null
);
create index idx_culture_name
on culture (name);

View File

@@ -0,0 +1,14 @@
create table culture_citation
(
culture_id INTEGER not null
references culture
on delete cascade,
citation_id INTEGER not null
references citation
on delete cascade,
primary key (culture_id, citation_id)
);
create index idx_culture_citation_cit
on culture_citation (citation_id);

View File

@@ -0,0 +1,15 @@
create table culture_language
(
culture_id INTEGER not null
references culture
on delete cascade,
language_id INTEGER not null
references language
on delete restrict,
level TEXT,
primary key (culture_id, language_id)
);
create index idx_culture_language_lang
on culture_language (language_id);

View File

@@ -0,0 +1,14 @@
create table culture_profession
(
culture_id INTEGER not null
references culture
on delete cascade,
profession_id INTEGER not null
references profession
on delete restrict,
primary key (culture_id, profession_id)
);
create index idx_culture_profession_prof
on culture_profession (profession_id);

View File

@@ -0,0 +1,14 @@
create table culture_script
(
culture_id INTEGER not null
references culture
on delete cascade,
script_id INTEGER not null
references script
on delete restrict,
primary key (culture_id, script_id)
);
create index idx_culture_script_script
on culture_script (script_id);

View File

@@ -0,0 +1,18 @@
create table culture_trait
(
culture_id INTEGER not null
references culture
on delete cascade,
trait_id INTEGER not null
references trait
on delete restrict,
tag TEXT not null,
level INTEGER,
param_value TEXT,
primary key (culture_id, trait_id, tag),
check (tag IN ('TYPISCH', 'EMPFOHLEN'))
);
create index idx_culture_trait_trait
on culture_trait (trait_id);

11
database/main/deity.sql Normal file
View File

@@ -0,0 +1,11 @@
create table deity
(
id INTEGER
primary key,
name TEXT not null
unique,
aspekte TEXT,
herrschaftsbereich TEXT,
heiliges_tier TEXT
);

View File

@@ -0,0 +1,9 @@
create table exclusive_group
(
id INTEGER
primary key,
name TEXT not null,
scope TEXT not null,
check (scope IN ('TRAIT', 'SF', 'TALENT', 'SPELL', 'LITURGY'))
);

View File

@@ -0,0 +1,9 @@
create table exclusive_group_member
(
group_id INTEGER not null
references exclusive_group
on delete cascade,
owner_id INTEGER not null,
primary key (group_id, owner_id)
);

15
database/main/item.sql Normal file
View File

@@ -0,0 +1,15 @@
create table item
(
id INTEGER
primary key,
name TEXT not null,
typ TEXT not null,
gewicht_in_unzen INTEGER default 0,
preis_in_heller INTEGER default 0,
beschreibung TEXT,
verfuegbarkeit TEXT,
availability_id INTEGER
references availability_level,
check (typ IN ('WAFFE', 'RÜSTUNG', 'SCHILD', 'FERNKAMPFWAFFE', 'MUNITION', 'ALLGEMEIN', 'ALCHEMIKA'))
);

View File

@@ -0,0 +1,19 @@
create table kampftechnik
(
id INTEGER
primary key,
optolith_key TEXT not null
unique,
name TEXT not null,
grundwert INTEGER default 6 not null,
probe_attr1_id INTEGER
references attribute,
probe_attr2_id INTEGER
references attribute,
probe_attr3_id INTEGER
references attribute,
beschreibung TEXT,
leiteigenschaft_id INTEGER
references attribute
);

View File

@@ -0,0 +1,10 @@
create table language
(
id INTEGER
primary key,
code TEXT
unique,
name TEXT not null
unique
);

22
database/main/liturgy.sql Normal file
View File

@@ -0,0 +1,22 @@
create table liturgy
(
id INTEGER
primary key,
optolith_key TEXT not null
unique,
name TEXT not null,
probe_attr1_id INTEGER not null
references attribute,
probe_attr2_id INTEGER not null
references attribute,
probe_attr3_id INTEGER not null
references attribute,
wirkung TEXT,
dauer TEXT,
kap_kosten TEXT,
reichweite TEXT,
wirkungsdauer TEXT,
steig_faktor TEXT not null,
check (steig_faktor IN ('A', 'B', 'C', 'D'))
);

View File

@@ -0,0 +1,14 @@
create table liturgy_citation
(
liturgy_id INTEGER not null
references liturgy
on delete cascade,
citation_id INTEGER not null
references citation
on delete cascade,
primary key (liturgy_id, citation_id)
);
create index idx_liturgy_citation_cit
on liturgy_citation (citation_id);

View File

@@ -0,0 +1,17 @@
create table liturgy_modification
(
id INTEGER
primary key,
liturgy_id INTEGER not null
references liturgy
on delete cascade,
name TEXT not null,
wirkung TEXT not null,
voraussetzung TEXT,
kosten_modifikation TEXT,
unique (liturgy_id, name)
);
create index idx_liturgy_mod_liturgy
on liturgy_modification (liturgy_id);

View File

@@ -0,0 +1,14 @@
create table liturgy_tradition
(
liturgy_id INTEGER not null
references liturgy
on delete cascade,
tradition_id INTEGER not null
references tradition
on delete restrict,
primary key (liturgy_id, tradition_id)
);
create index idx_liturgy_tradition_t
on liturgy_tradition (tradition_id);

View File

@@ -0,0 +1,14 @@
create table liturgy_zielkategorie
(
liturgy_id INTEGER not null
references liturgy
on delete cascade,
zielkategorie_id INTEGER not null
references zielkategorie
on delete restrict,
primary key (liturgy_id, zielkategorie_id)
);
create index idx_liturgy_zielkat_z
on liturgy_zielkategorie (zielkategorie_id);

View File

@@ -0,0 +1,8 @@
create table merkmal
(
id INTEGER
primary key,
name TEXT not null
unique
);

View File

@@ -0,0 +1,16 @@
create table poison_disease
(
id INTEGER
primary key,
name TEXT not null
unique,
typ TEXT not null,
art TEXT,
resistenz_probe_attr TEXT not null,
stufe INTEGER,
wirkungsbeginn TEXT,
schaden_wirkung TEXT,
dauer TEXT,
check (typ IN ('GIFT', 'KRANKHEIT'))
);

View File

@@ -0,0 +1,14 @@
create table profession
(
id INTEGER
primary key,
optolith_key TEXT not null
unique,
name TEXT not null,
typ TEXT,
beschreibung TEXT
);
create index idx_profession_name
on profession (name);

View File

@@ -0,0 +1,14 @@
create table profession_citation
(
profession_id INTEGER not null
references profession
on delete cascade,
citation_id INTEGER not null
references citation
on delete cascade,
primary key (profession_id, citation_id)
);
create index idx_profession_citation_cit
on profession_citation (citation_id);

View File

@@ -0,0 +1,14 @@
create table profession_special_ability
(
profession_id INTEGER not null
references profession
on delete cascade,
special_ability_id INTEGER not null
references special_ability
on delete restrict,
primary key (profession_id, special_ability_id)
);
create index idx_profession_sa_sa
on profession_special_ability (special_ability_id);

View File

@@ -0,0 +1,16 @@
create table profession_trait
(
profession_id INTEGER not null
references profession
on delete cascade,
trait_id INTEGER not null
references trait
on delete restrict,
level INTEGER,
param_value TEXT,
primary key (profession_id, trait_id)
);
create index idx_profession_trait_trait
on profession_trait (trait_id);

View File

@@ -0,0 +1,18 @@
create table ranged_weapon
(
id INTEGER
primary key,
item_id INTEGER not null
unique
references item
on delete cascade,
kampftechnik_id INTEGER not null
references kampftechnik
on delete restrict,
schaden_tp_formel TEXT not null,
ladezeit_in_aktionen INTEGER,
reichweite_nah INTEGER,
reichweite_mittel INTEGER,
reichweite_fern INTEGER
);

View File

@@ -0,0 +1,31 @@
create table requirement
(
id INTEGER
primary key,
owner_kind TEXT not null,
owner_id INTEGER not null,
group_no INTEGER default 1 not null,
negate INTEGER default 0 not null,
req_type TEXT not null,
req_id INTEGER,
req_level INTEGER,
req_optokey TEXT,
note TEXT,
check (negate IN (0, 1)),
check (owner_kind IN (
'TRAIT', 'SF', 'TALENT', 'SPELL', 'LITURGY', 'PROFESSION', 'SPECIES', 'CULTURE'
)),
check (req_type IN (
'TRAIT', 'TRAIT_LEVEL_MIN',
'ATTR_MIN', 'TALENT_MIN', 'SF',
'SPECIES', 'CULTURE', 'TRADITION', 'MERKMAL',
'EXCLUSIVE_GROUP'
))
);
create index idx_requirement_owner
on requirement (owner_kind, owner_id, group_no);
create index idx_requirement_ref
on requirement (req_type, req_id);

View File

@@ -0,0 +1,7 @@
create table sa_type
(
code TEXT
primary key,
name TEXT not null
);

10
database/main/script.sql Normal file
View File

@@ -0,0 +1,10 @@
create table script
(
id INTEGER
primary key,
code TEXT
unique,
name TEXT not null
unique
);

View File

@@ -0,0 +1,11 @@
create table service_cost
(
id INTEGER
primary key,
name TEXT not null,
kategorie TEXT,
preis_in_heller INTEGER,
preis_bemerkung TEXT,
beschreibung TEXT
);

17
database/main/shield.sql Normal file
View File

@@ -0,0 +1,17 @@
create table shield
(
id INTEGER
primary key,
item_id INTEGER not null
unique
references item
on delete cascade,
kampftechnik_id INTEGER not null
references kampftechnik
on delete restrict,
at_mod INTEGER default 0,
pa_mod INTEGER default 0,
zusatz_rs INTEGER default 0,
zusatz_be REAL default 0
);

View File

@@ -0,0 +1,10 @@
create table social_status
(
id INTEGER
primary key,
name TEXT not null
unique,
ap_kosten INTEGER not null,
beschreibung TEXT
);

View File

@@ -0,0 +1,15 @@
create table special_ability
(
id INTEGER
primary key,
optolith_key TEXT not null
unique,
name TEXT not null,
type_code TEXT
references sa_type
on update cascade,
ap_kosten INTEGER,
beschreibung TEXT,
benoetigt_parameter BOOLEAN default 0 not null
);

View File

@@ -0,0 +1,14 @@
create table special_ability_citation
(
special_ability_id INTEGER not null
references special_ability
on delete cascade,
citation_id INTEGER not null
references citation
on delete cascade,
primary key (special_ability_id, citation_id)
);
create index idx_special_ability_citation_cit
on special_ability_citation (citation_id);

17
database/main/species.sql Normal file
View File

@@ -0,0 +1,17 @@
create table species
(
id INTEGER
primary key,
optolith_key TEXT not null
unique,
name TEXT not null,
ap_kosten INTEGER,
le_grund INTEGER,
sk_grund INTEGER,
zk_grund INTEGER,
gs_grund INTEGER
);
create index idx_species_name
on species (name);

View File

@@ -0,0 +1,15 @@
create table species_attribute_mod
(
species_id INTEGER not null
references species
on delete cascade,
attribute_id INTEGER not null
references attribute
on delete restrict,
delta INTEGER not null,
primary key (species_id, attribute_id)
);
create index idx_species_attrmod_attr
on species_attribute_mod (attribute_id);

View File

@@ -0,0 +1,14 @@
create table species_citation
(
species_id INTEGER not null
references species
on delete cascade,
citation_id INTEGER not null
references citation
on delete cascade,
primary key (species_id, citation_id)
);
create index idx_species_citation_cit
on species_citation (citation_id);

View File

@@ -0,0 +1,18 @@
create table species_trait
(
species_id INTEGER not null
references species
on delete cascade,
trait_id INTEGER not null
references trait
on delete restrict,
source TEXT not null,
level INTEGER,
param_value TEXT,
primary key (species_id, trait_id, source),
check (source IN ('AUTOMATISCH', 'TYPISCH', 'EMPFOHLEN'))
);
create index idx_species_trait_trait
on species_trait (trait_id);

22
database/main/spell.sql Normal file
View File

@@ -0,0 +1,22 @@
create table spell
(
id INTEGER
primary key,
optolith_key TEXT not null
unique,
name TEXT not null,
probe_attr1_id INTEGER not null
references attribute,
probe_attr2_id INTEGER not null
references attribute,
probe_attr3_id INTEGER not null
references attribute,
wirkung TEXT,
zauberdauer TEXT,
asp_kosten TEXT,
reichweite TEXT,
wirkungsdauer TEXT,
steig_faktor TEXT not null,
check (steig_faktor IN ('A', 'B', 'C', 'D'))
);

View File

@@ -0,0 +1,14 @@
create table spell_citation
(
spell_id INTEGER not null
references spell
on delete cascade,
citation_id INTEGER not null
references citation
on delete cascade,
primary key (spell_id, citation_id)
);
create index idx_spell_citation_cit
on spell_citation (citation_id);

View File

@@ -0,0 +1,14 @@
create table spell_merkmal
(
spell_id INTEGER not null
references spell
on delete cascade,
merkmal_id INTEGER not null
references merkmal
on delete restrict,
primary key (spell_id, merkmal_id)
);
create index idx_spell_merkmal_m
on spell_merkmal (merkmal_id);

View File

@@ -0,0 +1,17 @@
create table spell_modification
(
id INTEGER
primary key,
spell_id INTEGER not null
references spell
on delete cascade,
name TEXT not null,
wirkung TEXT not null,
voraussetzung TEXT,
kosten_modifikation TEXT,
unique (spell_id, name)
);
create index idx_spell_mod_spell
on spell_modification (spell_id);

View File

@@ -0,0 +1,14 @@
create table spell_tradition
(
spell_id INTEGER not null
references spell
on delete cascade,
tradition_id INTEGER not null
references tradition
on delete restrict,
primary key (spell_id, tradition_id)
);
create index idx_spell_tradition_t
on spell_tradition (tradition_id);

View File

@@ -0,0 +1,14 @@
create table spell_zielkategorie
(
spell_id INTEGER not null
references spell
on delete cascade,
zielkategorie_id INTEGER not null
references zielkategorie
on delete restrict,
primary key (spell_id, zielkategorie_id)
);
create index idx_spell_zielkat_z
on spell_zielkategorie (zielkategorie_id);

View File

@@ -0,0 +1,10 @@
create table status_effect
(
id INTEGER
primary key,
name TEXT not null
unique,
max_stufen INTEGER,
regel_beschreibung TEXT
);

24
database/main/talent.sql Normal file
View File

@@ -0,0 +1,24 @@
create table talent
(
id INTEGER
primary key,
optolith_key TEXT not null
unique,
name TEXT not null,
group_code TEXT
references talent_group
on update cascade,
probe_attr1_id INTEGER not null
references attribute,
probe_attr2_id INTEGER not null
references attribute,
probe_attr3_id INTEGER not null
references attribute,
steig_faktor TEXT not null,
beschreibung TEXT,
check (steig_faktor IN ('A', 'B', 'C', 'D'))
);
create index idx_talent_group
on talent (group_code);

View File

@@ -0,0 +1,14 @@
create table talent_citation
(
talent_id INTEGER not null
references talent
on delete cascade,
citation_id INTEGER not null
references citation
on delete cascade,
primary key (talent_id, citation_id)
);
create index idx_talent_citation_cit
on talent_citation (citation_id);

View File

@@ -0,0 +1,7 @@
create table talent_group
(
code TEXT
primary key,
name TEXT not null
);

View File

@@ -0,0 +1,8 @@
create table tradition
(
id INTEGER
primary key,
name TEXT not null
unique
);

View File

@@ -0,0 +1,14 @@
create table tradition_has_deity
(
tradition_id INTEGER not null
references tradition
on delete cascade,
deity_id INTEGER not null
references deity
on delete restrict,
primary key (tradition_id, deity_id)
);
create index idx_trad_deity_deity
on tradition_has_deity (deity_id);

26
database/main/trait.sql Normal file
View File

@@ -0,0 +1,26 @@
create table trait
(
id INTEGER
primary key,
optolith_key TEXT not null
unique,
name TEXT not null,
kind TEXT not null,
is_leveled INTEGER default 0 not null,
level_min INTEGER,
level_max INTEGER,
level_step INTEGER,
ap_cost_mode TEXT default 'FIXED' not null,
ap_wert INTEGER,
ap_per_level INTEGER,
ap_formula TEXT,
beschreibung TEXT,
benoetigt_parameter BOOLEAN default 0 not null,
check (ap_cost_mode IN ('FIXED', 'PER_LEVEL', 'TABLE', 'FORMULA')),
check (is_leveled IN (0, 1)),
check (kind IN ('VORTEIL', 'NACHTEIL'))
);
create index idx_trait_kind
on trait (kind);

View File

@@ -0,0 +1,14 @@
create table trait_citation
(
trait_id INTEGER not null
references trait
on delete cascade,
citation_id INTEGER not null
references citation
on delete cascade,
primary key (trait_id, citation_id)
);
create index idx_trait_citation_cit
on trait_citation (citation_id);

View File

@@ -0,0 +1,11 @@
create table trait_conflict
(
trait_id INTEGER not null
references trait
on delete cascade,
incompatible_trait_id INTEGER not null
references trait
on delete cascade,
primary key (trait_id, incompatible_trait_id)
);

View File

@@ -0,0 +1,12 @@
create table trait_level
(
trait_id INTEGER not null
references trait
on delete cascade,
level INTEGER not null,
ap_cost INTEGER,
label TEXT,
note TEXT,
primary key (trait_id, level)
);

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_attr_insert
BEFORE INSERT ON requirement
WHEN NEW.req_type = 'ATTR_MIN'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM attribute WHERE id = NEW.req_id)
THEN RAISE(ABORT, 'requirement.req_id must reference attribute.id for ATTR_MIN')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_attr_update
BEFORE UPDATE ON requirement
WHEN NEW.req_type = 'ATTR_MIN'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM attribute WHERE id = NEW.req_id)
THEN RAISE(ABORT, 'requirement.req_id must reference attribute.id for ATTR_MIN (UPDATE)')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_culture_insert
BEFORE INSERT ON requirement
WHEN NEW.req_type='CULTURE'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM culture WHERE id=NEW.req_id)
THEN RAISE(ABORT,'requirement.req_id must reference culture.id for CULTURE')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_culture_update
BEFORE UPDATE ON requirement
WHEN NEW.req_type='CULTURE'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM culture WHERE id=NEW.req_id)
THEN RAISE(ABORT,'requirement.req_id must reference culture.id for CULTURE (UPDATE)')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_exclgrp_insert
BEFORE INSERT ON requirement
WHEN NEW.req_type='EXCLUSIVE_GROUP'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM exclusive_group WHERE id=NEW.req_id)
THEN RAISE(ABORT,'requirement.req_id must reference exclusive_group.id for EXCLUSIVE_GROUP')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_exclgrp_update
BEFORE UPDATE ON requirement
WHEN NEW.req_type='EXCLUSIVE_GROUP'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM exclusive_group WHERE id=NEW.req_id)
THEN RAISE(ABORT,'requirement.req_id must reference exclusive_group.id for EXCLUSIVE_GROUP (UPDATE)')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_merk_insert
BEFORE INSERT ON requirement
WHEN NEW.req_type='MERKMAL'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM merkmal WHERE id=NEW.req_id)
THEN RAISE(ABORT,'requirement.req_id must reference merkmal.id for MERKMAL')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_merk_update
BEFORE UPDATE ON requirement
WHEN NEW.req_type='MERKMAL'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM merkmal WHERE id=NEW.req_id)
THEN RAISE(ABORT,'requirement.req_id must reference merkmal.id for MERKMAL (UPDATE)')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_sf_insert
BEFORE INSERT ON requirement
WHEN NEW.req_type='SF'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM special_ability WHERE id=NEW.req_id)
THEN RAISE(ABORT,'requirement.req_id must reference special_ability.id for SF')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_sf_update
BEFORE UPDATE ON requirement
WHEN NEW.req_type='SF'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM special_ability WHERE id=NEW.req_id)
THEN RAISE(ABORT,'requirement.req_id must reference special_ability.id for SF (UPDATE)')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_species_insert
BEFORE INSERT ON requirement
WHEN NEW.req_type='SPECIES'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM species WHERE id=NEW.req_id)
THEN RAISE(ABORT,'requirement.req_id must reference species.id for SPECIES')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_species_update
BEFORE UPDATE ON requirement
WHEN NEW.req_type='SPECIES'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM species WHERE id=NEW.req_id)
THEN RAISE(ABORT,'requirement.req_id must reference species.id for SPECIES (UPDATE)')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_talent_insert
BEFORE INSERT ON requirement
WHEN NEW.req_type='TALENT_MIN'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM talent WHERE id=NEW.req_id)
THEN RAISE(ABORT,'requirement.req_id must reference talent.id for TALENT_MIN')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_talent_update
BEFORE UPDATE ON requirement
WHEN NEW.req_type='TALENT_MIN'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM talent WHERE id=NEW.req_id)
THEN RAISE(ABORT,'requirement.req_id must reference talent.id for TALENT_MIN (UPDATE)')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_trad_insert
BEFORE INSERT ON requirement
WHEN NEW.req_type='TRADITION'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM tradition WHERE id=NEW.req_id)
THEN RAISE(ABORT,'requirement.req_id must reference tradition.id for TRADITION')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_trad_update
BEFORE UPDATE ON requirement
WHEN NEW.req_type='TRADITION'
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM tradition WHERE id=NEW.req_id)
THEN RAISE(ABORT,'requirement.req_id must reference tradition.id for TRADITION (UPDATE)')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_trait_insert
BEFORE INSERT ON requirement
WHEN NEW.req_type IN ('TRAIT','TRAIT_LEVEL_MIN')
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM trait WHERE id = NEW.req_id)
THEN RAISE(ABORT, 'requirement.req_id must reference trait.id for TRAIT/TRAIT_LEVEL_MIN')
END;
END;

View File

@@ -0,0 +1,10 @@
CREATE TRIGGER trg_requirement_check_trait_update
BEFORE UPDATE ON requirement
WHEN NEW.req_type IN ('TRAIT','TRAIT_LEVEL_MIN')
BEGIN
SELECT CASE
WHEN NEW.req_id IS NULL OR NOT EXISTS (SELECT 1 FROM trait WHERE id = NEW.req_id)
THEN RAISE(ABORT, 'requirement.req_id must reference trait.id for TRAIT/TRAIT_LEVEL_MIN (UPDATE)')
END;
END;

View File

@@ -0,0 +1,7 @@
CREATE TRIGGER trg_trait_conflict_order
BEFORE INSERT ON trait_conflict
WHEN NEW.trait_id > NEW.incompatible_trait_id
BEGIN
SELECT RAISE(ABORT, 'Insert smaller id first (trait_id < incompatible_trait_id)');
END;

View File

@@ -0,0 +1,17 @@
CREATE VIEW v_book_index AS
SELECT 'TRAIT' AS kind, t.name, b.code, c.page_start, c.page_end
FROM trait t JOIN trait_citation tc ON tc.trait_id=t.id
JOIN citation c ON c.id=tc.citation_id JOIN book b ON b.id=c.book_id
UNION ALL
SELECT 'SPECIES', s.name, b.code, c.page_start, c.page_end
FROM species s JOIN species_citation sc ON sc.species_id=s.id
JOIN citation c ON c.id=sc.citation_id JOIN book b ON b.id=c.book_id
UNION ALL
SELECT 'CULTURE', cu.name, b.code, c.page_start, c.page_end
FROM culture cu JOIN culture_citation cc ON cc.culture_id=cu.id
JOIN citation c ON c.id=cc.citation_id JOIN book b ON b.id=c.book_id
UNION ALL
SELECT 'PROFESSION', p.name, b.code, c.page_start, c.page_end
FROM profession p JOIN profession_citation pc ON pc.profession_id=p.id
JOIN citation c ON c.id=pc.citation_id JOIN book b ON b.id=c.book_id;

View File

@@ -0,0 +1,13 @@
CREATE VIEW v_requirement_debug AS
SELECT
owner_kind,
owner_id,
group_no,
CASE negate WHEN 1 THEN 'NOT ' ELSE '' END || req_type AS req_op,
req_id,
req_level,
req_optokey,
note
FROM requirement
ORDER BY owner_kind, owner_id, group_no, negate DESC, req_type, req_id;

View File

@@ -0,0 +1,7 @@
CREATE VIEW v_species_auto_traits AS
SELECT s.id AS species_id, s.name AS species,
t.id AS trait_id, t.name AS trait, st.level, st.param_value
FROM species s
JOIN species_trait st ON st.species_id = s.id AND st.source = 'AUTOMATISCH'
JOIN trait t ON t.id = st.trait_id;

18
database/main/weapon.sql Normal file
View File

@@ -0,0 +1,18 @@
create table weapon
(
id INTEGER
primary key,
item_id INTEGER not null
unique
references item
on delete cascade,
kampftechnik_id INTEGER not null
references kampftechnik
on delete restrict,
schaden_tp_formel TEXT not null,
tp_kk_schwelle INTEGER,
tp_kk_schritt INTEGER,
at_mod INTEGER default 0,
pa_mod INTEGER default 0
);

View File

@@ -0,0 +1,14 @@
create table weapon_has_property
(
weapon_id INTEGER not null
references weapon
on delete cascade,
property_id INTEGER not null
references weapon_property
on delete restrict,
primary key (weapon_id, property_id)
);
create index idx_weapon_has_property_prop
on weapon_has_property (property_id);

View File

@@ -0,0 +1,9 @@
create table weapon_property
(
id INTEGER
primary key,
name TEXT not null
unique,
beschreibung TEXT
);

View File

@@ -0,0 +1,8 @@
create table zielkategorie
(
id INTEGER
primary key,
name TEXT not null
unique
);

BIN
rules.db Normal file

Binary file not shown.

BIN
rules.db.empty Normal file

Binary file not shown.

3
src/main.rs Normal file
View File

@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}