commit 14d3b7506e22b870dd5af6c25dc6d2ff257e8a34 Author: 0ceanSlim Date: Tue Jan 30 11:06:00 2024 -0500 first commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..69a955a --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [2024] [OceanSlim] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/app.py b/app.py new file mode 100644 index 0000000..41af75e --- /dev/null +++ b/app.py @@ -0,0 +1,95 @@ +from flask import Flask, render_template, g, abort, request, jsonify +import sqlite3 + +app = Flask(__name__) + +DATABASE = 'static/data/monsters.db' + +def connect_db(): + return sqlite3.connect(DATABASE) + +@app.before_request +def before_request(): + g.db = connect_db() + +@app.teardown_request +def teardown_request(exception): + if hasattr(g, 'db'): + g.db.close() + +@app.route("/") +def show_index(): + return render_template("index.html") + +@app.route('/get_families') +def get_families(): + cursor = g.db.cursor() + cursor.execute('SELECT DISTINCT name FROM families') + families = [row[0] for row in cursor.fetchall()] + return jsonify(families) + +@app.route('/get_monsters') +def get_monsters(): + selected_family = request.args.get('family') + cursor = g.db.cursor() + + if selected_family: + cursor.execute(''' + SELECT name FROM monsters + WHERE family_id = (SELECT id FROM families WHERE name = ?) + ''', (selected_family,)) + else: + cursor.execute('SELECT DISTINCT name FROM monsters') + + monsters = [row[0] for row in cursor.fetchall()] + return jsonify(monsters) + +@app.route('/monster/') +def monster_info(monster_name): + cursor = g.db.cursor() + + # Retrieve monster information from the database based on name + cursor.execute(''' + SELECT + monsters.id, monsters.name, families.name AS family, monsters.in_story, + monsters.agl, monsters.int, monsters.maxlvl, monsters.atk, monsters.mp, + monsters.exp, monsters.hp, monsters.def + FROM + monsters + JOIN families ON monsters.family_id = families.id + WHERE + monsters.name = ? + ''', (monster_name,)) + + monster_info = cursor.fetchone() + + if monster_info is None: + abort(404) + + # Retrieve skills for the monster + cursor.execute('SELECT skill FROM skills WHERE monster_id = ?', (monster_info[0],)) + skills = [row[0] for row in cursor.fetchall()] + + # Retrieve spawn locations for the monster + cursor.execute('SELECT map, description FROM spawn_locations WHERE monster_id = ?', (monster_info[0],)) + spawn_locations = [{'map': row[0], 'description': row[1]} for row in cursor.fetchall()] + + return render_template('monsters.html', monster={ + 'id': monster_info[0], + 'name': monster_info[1], + 'family': monster_info[2], + 'in_story': 'Yes' if monster_info[3] else 'No', + 'agl': monster_info[4], + 'int': monster_info[5], + 'maxlvl': monster_info[6], + 'atk': monster_info[7], + 'mp': monster_info[8], + 'exp': monster_info[9], + 'hp': monster_info[10], + 'def': monster_info[11], + 'skills': skills, + 'spawn_locations': spawn_locations + }) + +if __name__ == '__main__': + app.run(debug=True) diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..3d609b8 --- /dev/null +++ b/readme.md @@ -0,0 +1,72 @@ +# Dragon Warrior Monsters 2 App + +## Overview + +This Flask app is designed to use data from Dragon Warrior Monsters 2 to create an intuitive web UI. The app allows users to lookup monster information, and eventually breeding pairs and skills. Inspired by the [dwm2-tools](https://github.com/MetroWind/dwm2-tools) project. + +## Features + +- Efficiently parse and display Dragon Warrior Monsters 2 game data. +- Simple and accessible codebase for developers with basic web skills. +- Fast development with Flask, allowing real-time changes while running. +- Seamless integration with SQLite database for scalability. +- Designer friendly Tailwind Styling + +## Setup Instructions + +### Prerequisites + +- [Python](https://www.python.org/downloads/) +- [Tailwind CSS](https://github.com/tailwindlabs/tailwindcss/releases/latest) + +### Installation + +1. Clone the repository: + + ```bash + git clone https://github.com/0ceanslim/dwm2-app.git + cd dwm2-app + ``` +2. Install dependencies: + + ```bash + pip install -r requirements.txt + ``` +3. Run the Flask app: + + ```bash + python app.py + ``` + +4. Open your browser and navigate to http://127.0.0.1:5000/. + + +### Tailwind CSS +To rebuild the styles when making changes, use: + +```bash +tailwindcss -i static/style/input.css -o static/style/output.css --watch +``` + +## Development +Contributions and pull requests are welcome! + +Fork the repository. +Create a new branch for your feature or bug fix. +Submit a pull request. + +## To-Do List +- Add sprites for monsters. +- Enhance styling for a more polished appearance. +- Integrate a skills database with detailed descriptions. + +### Future Enhancements +Discuss any planned features or enhancements for future development. + +## License + +This repository is provided under the MIT License. Feel free to use, modify, and distribute these scripts as needed. Contributions and improvements are welcome. ❤️ +See the [LICENSE](LICENSE) file for details. + +Acknowledgments +Special thanks to dwm2-tools for inspiration. \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8ab6294 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +flask \ No newline at end of file diff --git a/static/data/monsters.db b/static/data/monsters.db new file mode 100644 index 0000000..ca7d0dd Binary files /dev/null and b/static/data/monsters.db differ diff --git a/static/js/index.js b/static/js/index.js new file mode 100644 index 0000000..2fc7ed7 --- /dev/null +++ b/static/js/index.js @@ -0,0 +1,67 @@ +// static/js/app.js + +document.addEventListener("DOMContentLoaded", function () { + const familyDropdown = document.getElementById("familyDropdown"); + const monsterDropdown = document.getElementById("monsterDropdown"); + const iframe = document.getElementById("monsterIframe"); + + // Initialize dropdowns and iframe + updateMonstersDropdown(); + updateIframe(); + + // Fetch families data from the server + fetch("/get_families") + .then(response => response.json()) + .then(data => { + populateDropdown(familyDropdown, data); + updateMonstersDropdown(); + updateIframe(); + }) + .catch(error => console.error("Error fetching families:", error)); + + familyDropdown.addEventListener("change", function () { + updateMonstersDropdown(); + updateIframe(); + }); + + monsterDropdown.addEventListener("change", function () { + updateIframe(); + }); + + function populateDropdown(dropdown, data) { + // Clear existing options + dropdown.innerHTML = ''; + + // Populate dropdown options + data.forEach(item => { + const option = document.createElement("option"); + option.value = item; + option.text = item; + dropdown.appendChild(option); + }); + } + + function updateMonstersDropdown() { + const selectedFamily = familyDropdown.value; + + // Fetch monsters data from the server based on the selected family + fetch(`/get_monsters?family=${selectedFamily}`) + .then(response => response.json()) + .then(data => populateDropdown(monsterDropdown, data)) + .catch(error => console.error("Error fetching monsters:", error)); + } + + function updateIframe() { + const selectedFamily = familyDropdown.value; + const selectedMonster = monsterDropdown.value; + + // Update iframe src based on selected family and monster + const iframeSrc = selectedMonster + ? `/monster/${selectedMonster}` + : selectedFamily + ? `/monster/${selectedFamily}` + : "about:blank"; + + iframe.src = iframeSrc; + } +}); diff --git a/static/style/input.css b/static/style/input.css new file mode 100644 index 0000000..598cc07 --- /dev/null +++ b/static/style/input.css @@ -0,0 +1,5 @@ +@config "tailwind.config.js"; + +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/static/style/output.css b/static/style/output.css new file mode 100644 index 0000000..374b9ac --- /dev/null +++ b/static/style/output.css @@ -0,0 +1,554 @@ +/* +! tailwindcss v3.3.6 | MIT License | https://tailwindcss.com +*/ + +/* +1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) +2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) +*/ + +*, +::before, +::after { + box-sizing: border-box; + /* 1 */ + border-width: 0; + /* 2 */ + border-style: solid; + /* 2 */ + border-color: #e5e7eb; + /* 2 */ +} + +::before, +::after { + --tw-content: ''; +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +5. Use the user's configured `sans` font-feature-settings by default. +6. Use the user's configured `sans` font-variation-settings by default. +*/ + +html { + line-height: 1.5; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -moz-tab-size: 4; + /* 3 */ + -o-tab-size: 4; + tab-size: 4; + /* 3 */ + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + /* 4 */ + font-feature-settings: normal; + /* 5 */ + font-variation-settings: normal; + /* 6 */ +} + +/* +1. Remove the margin in all browsers. +2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. +*/ + +body { + margin: 0; + /* 1 */ + line-height: inherit; + /* 2 */ +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ + border-top-width: 1px; + /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font-family by default. +2. Use the user's configured `mono` font-feature-settings by default. +3. Use the user's configured `mono` font-variation-settings by default. +4. Correct the odd `em` font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + /* 1 */ + font-feature-settings: normal; + /* 2 */ + font-variation-settings: normal; + /* 3 */ + font-size: 1em; + /* 4 */ +} + +/* +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ + border-collapse: collapse; + /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + /* 1 */ + font-feature-settings: inherit; + /* 1 */ + font-variation-settings: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + font-weight: inherit; + /* 1 */ + line-height: inherit; + /* 1 */ + color: inherit; + /* 1 */ + margin: 0; + /* 2 */ + padding: 0; + /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +button, +select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +button, +[type='button'], +[type='reset'], +[type='submit'] { + -webkit-appearance: button; + /* 1 */ + background-color: transparent; + /* 2 */ + background-image: none; + /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +:-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +:-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +[type='search'] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +fieldset { + margin: 0; + padding: 0; +} + +legend { + padding: 0; +} + +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Reset default styling for dialogs. +*/ + +dialog { + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +input::-moz-placeholder, textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +input::placeholder, +textarea::placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +:disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +img, +video { + max-width: 100%; + height: auto; +} + +/* Make elements with the HTML hidden attribute stay hidden by default */ + +[hidden] { + display: none; +} + +*, ::before, ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +.static { + position: static; +} + +.font-bold { + font-weight: 700; +} + +.text-blue-500 { + --tw-text-opacity: 1; + color: rgb(59 130 246 / var(--tw-text-opacity)); +} diff --git a/static/style/readme.md b/static/style/readme.md new file mode 100644 index 0000000..95e7eb5 --- /dev/null +++ b/static/style/readme.md @@ -0,0 +1,11 @@ +# Development + +For Tailwind to Rebuild the Output CSS, a watcher must be run to compile the new styling as pages are edited. + +To do this run: + +```bash +tailwindcss -i static/style/input.css -o static/style/output.css --watch +``` + +You must be in the `app` directory \ No newline at end of file diff --git a/static/style/tailwind.config.js b/static/style/tailwind.config.js new file mode 100644 index 0000000..edd33e2 --- /dev/null +++ b/static/style/tailwind.config.js @@ -0,0 +1,9 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["./**/*.{html,js}"], + theme: { + extend: {}, + }, + plugins: [], +} + diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..175523e --- /dev/null +++ b/templates/index.html @@ -0,0 +1,30 @@ + + + + + + DWM APP + + + + +

Welcome to the Dragon Warrior Monsters 2 App

+ +
+

Filter list by monster family
+ Display monster stats in embed below

+ + + + + + + + +
+ + diff --git a/templates/monsters.html b/templates/monsters.html new file mode 100644 index 0000000..1dff8aa --- /dev/null +++ b/templates/monsters.html @@ -0,0 +1,40 @@ + + + + + + Monster Information + + + +

Monster Information

+
+

{{ monster.name }}

+

Family: {{ monster.family }}

+

In Story: {{ monster.in_story }}

+

Stats:

+
    +
  • AGL: {{ monster.agl }}
  • +
  • INT: {{ monster.int }}
  • +
  • Max Level: {{ monster.maxlvl }}
  • +
  • ATK: {{ monster.atk }}
  • +
  • MP: {{ monster.mp }}
  • +
  • EXP: {{ monster.exp }}
  • +
  • HP: {{ monster.hp }}
  • +
  • DEF: {{ monster.def }}
  • +
+

Skills:

+
    + {% for skill in monster.skills %} +
  • {{ skill }}
  • + {% endfor %} +
+

Spawn Locations:

+
    + {% for location in monster.spawn_locations %} +
  • {{ location.map }} - {{ location.description }}
  • + {% endfor %} +
+
+ +