Browse Source

Initial commit

master
Brandon Cornejo 7 months ago
commit
b9ef801f77
3 changed files with 338 additions and 0 deletions
  1. 70
    0
      orna-tools.py
  2. 7
    0
      requirements.txt
  3. 261
    0
      templates/index.html

+ 70
- 0
orna-tools.py View File

@@ -0,0 +1,70 @@
1
+from flask import Flask, render_template, jsonify, request
2
+
3
+app = Flask(__name__)
4
+
5
+@app.route('/')
6
+def index():
7
+    return render_template('index.html')
8
+
9
+@app.route('/results', methods=['POST'])
10
+def results():
11
+    combinations = calculate_combinations(request.get_json())
12
+    return jsonify(combinations)
13
+
14
+
15
+# Data Methods
16
+def calculate_combinations(equipment, do_print=True):
17
+    # name, defense, resistance
18
+    eq_headware = equipment["head"]
19
+    eq_chestware = equipment["chest"]
20
+    eq_legwear = equipment["legs"]
21
+
22
+    # Create a list of all possible eq combinations
23
+    results = []
24
+    for hw in eq_headware:
25
+        print('Headware: {}'.format(hw))
26
+        for cw in eq_chestware:
27
+            print('Chestware: {}'.format(cw))
28
+            for lw in eq_legwear:
29
+                print('legware: {}'.format(lw))
30
+                result = {}
31
+                result["eq"] = [hw[0], cw[0], lw[0]]
32
+                result["def"] = hw[1] + cw[1] + lw[1]
33
+                result["res"] = hw[2] + cw[2] + lw[2]
34
+                results.append(result)
35
+
36
+    # Sort the combinations by combined total of def anf res
37
+    results.sort(key=lambda i: i["def"] + i["res"])
38
+
39
+    if do_print:
40
+        for result in results:
41
+            print("{} ({} def {} res) -".format(result["def"] + result["res"], result["def"], result["res"]))
42
+            for eq in result["eq"]:
43
+                print("\t{}".format(eq))
44
+
45
+    return results
46
+
47
+
48
+"""
49
+eq_headware = [
50
+    ["Ljosalfar Hood", 98, 510],
51
+    ["Kobold Hood", 0, 614],
52
+    ["Northern Cowl", 584, 130],
53
+    ["High Fomorian Hood", 487, 112]
54
+]
55
+
56
+eq_chestware = [
57
+    ["Ljosalfar Robe", 121, 528],
58
+    ["High Fomorian Garb", 544, 0],
59
+    ["Darkest Garb", 514, 169],
60
+    ["Northern Garb", 535, 119],
61
+    ["Northern Robe", 486, 108]
62
+]
63
+
64
+eq_legwear = [
65
+    ["Northern Boots", 636, 142],
66
+    ["Terra Boots", 129, 369],
67
+    ["High Fomorian Boots", 516, 0],
68
+    ["Ljosalfar Boots", 280, 280]
69
+]
70
+"""

+ 7
- 0
requirements.txt View File

@@ -0,0 +1,7 @@
1
+Click==7.0
2
+Flask==1.1.1
3
+itsdangerous==1.1.0
4
+Jinja2==2.11.1
5
+MarkupSafe==1.1.1
6
+pkg-resources==0.0.0
7
+Werkzeug==0.16.1

+ 261
- 0
templates/index.html View File

@@ -0,0 +1,261 @@
1
+<!doctype html>
2
+<html>
3
+    <head>
4
+        <title>Orna Tools - atr0phy.net</title>
5
+
6
+        <meta charset="utf-8">
7
+        <meta name="viewport" contents="width=device-width, initial-scale=1">
8
+
9
+        <!-- <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}"> -->
10
+
11
+        <!-- UIkit CSS -->
12
+        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.2.4/dist/css/uikit.min.css" />
13
+
14
+        <!-- UIkit JS -->
15
+        <script src="https://cdn.jsdelivr.net/npm/uikit@3.2.4/dist/js/uikit.min.js"></script>
16
+        <script src="https://cdn.jsdelivr.net/npm/uikit@3.2.4/dist/js/uikit-icons.min.js"></script>
17
+        <script src="https://cdn.jsdelivr.net/combine/npm/tablesort@5.2.0,npm/tablesort@5.2.0/src/sorts/tablesort.number.min.js"></script>
18
+    </head>
19
+    <body>
20
+        <nav class="uk-navbar-container" uk-navbar>
21
+            <div class="uk-navbar-center">
22
+                <a href="" class="uk-navbar-item uk-logo">Orna Tools</a>
23
+            </div>
24
+        </nav>
25
+        <div class="uk-container">
26
+            <div id="equipment-container" class="uk-padding-large">
27
+                <ul class="uk-flex-center" uk-tab>
28
+                    <li class="uk-active"><a href="">Head</a></li>
29
+                    <li><a href="">Chest</a></li>
30
+                    <li><a href="">Leg</a></li>
31
+                </ul>
32
+                <ul class="uk-switcher">
33
+                    {% for slot in ["Head", "Chest", "Leg"] %}
34
+                        <li>
35
+                            <div class="uk-padding-large uk-padding-remove-vertical">
36
+                                <table id="{{ slot | lower }}-table" class="uk-table">
37
+                                    <caption>{{ slot }} Gear</caption>
38
+                                    <thead>
39
+                                        <tr>
40
+                                            <th class="uk-table-shrink"></th>
41
+                                            <th class="uk-table-expand">Item Name</th>
42
+                                            <th class="uk-table-shrink">Defense</th>
43
+                                            <th class="uk-table-shrink">Resistance</th>
44
+                                            <th class="uk-table-shring"></th>
45
+                                        </tr>
46
+                                    </thead>
47
+                                    <tbody>
48
+                                        <tr>
49
+                                            <td>1</td>
50
+                                            <td><input type="text" class="uk-input"/></td>
51
+                                            <td><input type="text" class="uk-input"/></td>
52
+                                            <td><input type="text" class="uk-input"/></td>
53
+                                            <td><a class="uk-icon-button del-row-button" uk-icon="icon:minus-circle;ratio:1"></a></td>
54
+                                        </tr>
55
+                                    </tbody>
56
+                                </table>
57
+                                <div class="uk-text-center">
58
+                                    <a id="{{ slot | lower }}-button" class="uk-icon-button add-row-button" uk-icon="icon:plus-circle;ratio:2"></a>
59
+                                </div>
60
+                            </div>
61
+                        </li>
62
+                    {% endfor %}
63
+                </ul>
64
+            </div>
65
+            <div class="uk-text-center uk-margin-bottom">
66
+                <button id="calculate-button" class="uk-button uk-button-primary">Calculate</button>
67
+            </div>
68
+
69
+            <div id="result-panel" class="uk-section">
70
+                <hr class="uk-divider-icon" />
71
+                <table id="results-table" class="uk-table uk-table-divider uk-table-striped uk-table-hover">
72
+                    <thead>
73
+                        <th>Total</th>
74
+                        <th>Defense</th>
75
+                        <th>Resistance</th>
76
+                        <th class="uk-table-expand">Head</th>
77
+                        <th class="uk-table-expand">Chest</th>
78
+                        <th class="uk-table-expand">Legs</th>
79
+                    </thead>
80
+                    <tbody></tbody>
81
+                </table>
82
+            </div>
83
+        </div>
84
+    </body>
85
+    <script>
86
+        // Support adding rows to the equipment tables
87
+        function addEquipmentTableRow() {
88
+            let input_element = document.createElement("input");
89
+            input_element.className="uk-input";
90
+            input_element.type = "text";
91
+
92
+            // Create the delete button
93
+            let delete_button = document.createElement("a");
94
+            delete_button.className="uk-icon-button del-row-button";
95
+            delete_button.setAttribute("uk-icon", "icon:minus-circle;ratio:1");
96
+            delete_button.addEventListener("click", deleteEquipmentTableRow, false);
97
+
98
+            let tbody = this.parentElement.previousElementSibling.children[2];
99
+            let new_row = tbody.insertRow(-1);
100
+
101
+            // Append all of the child cells needed
102
+            new_row.insertCell(0).appendChild(delete_button);
103
+            new_row.insertCell(0).appendChild(input_element.cloneNode());
104
+            new_row.insertCell(0).appendChild(input_element.cloneNode());
105
+            new_row.insertCell(0).appendChild(input_element.cloneNode());
106
+            new_row.insertCell(0).appendChild(document.createTextNode(tbody.children.length))
107
+        }
108
+
109
+        // Support deleting rows from the equipment table
110
+        function deleteEquipmentTableRow() {
111
+            this.parentElement.parentElement.remove();
112
+        }
113
+
114
+        // Process results and display table
115
+        function processEquipmentResults(results) {
116
+            var results_tbody = document.querySelector("table#results-table > tbody");
117
+            for(result of results) {
118
+                let new_row = results_tbody.insertRow(-1);
119
+
120
+                // Append all of the child cells
121
+                new_row.insertCell(0).appendChild(document.createTextNode(result['eq'][2]));
122
+                new_row.insertCell(0).appendChild(document.createTextNode(result['eq'][1]));
123
+                new_row.insertCell(0).appendChild(document.createTextNode(result['eq'][0]));
124
+                new_row.insertCell(0).appendChild(document.createTextNode(result['res']));
125
+                new_row.insertCell(0).appendChild(document.createTextNode(result['def']));
126
+                new_row.insertCell(0).appendChild(document.createTextNode(result['def'] + result['res']));
127
+            }
128
+            
129
+            table_sort.refresh();
130
+        }
131
+
132
+        // Send data to backend
133
+        function calculateEquipment() {
134
+            let data = gatherEquipmentData();
135
+
136
+            // Clear out existing table rows
137
+            for(let row of document.querySelectorAll("table#results-table > tbody > tr")) {
138
+                row.remove();
139
+            }
140
+
141
+            fetch('/results', {
142
+                method: 'POST',
143
+                headers: { 'Content-Type': 'application/json' },
144
+                body: JSON.stringify(data)
145
+            }).then((response) => response.json()).then((data) => {
146
+                processEquipmentResults(data)
147
+            }).catch((error) => {
148
+                console.log(error);
149
+                alert("There was a problem...");
150
+            });
151
+        }
152
+
153
+        function gatherEquipmentData() {
154
+            var eq_head = [], eq_chest = [], eq_legs = [];
155
+
156
+            // Gather head gear
157
+            for(let row of document.querySelectorAll("table#head-table > tbody > tr")) {
158
+                eq_head.push([
159
+                    row.children[1].firstChild.value,
160
+                    parseInt(row.children[2].firstChild.value) || 0,
161
+                    parseInt(row.children[3].firstChild.value) || 0
162
+                ]);
163
+            }
164
+
165
+            // Gather chest gear
166
+            for(let row of document.querySelectorAll("table#chest-table > tbody > tr")) {
167
+                eq_chest.push([
168
+                    row.children[1].firstChild.value,
169
+                    parseInt(row.children[2].firstChild.value) || 0,
170
+                    parseInt(row.children[3].firstChild.value) || 0
171
+                ]);
172
+            }
173
+
174
+            // Gather leg gear
175
+            for(let row of document.querySelectorAll("table#leg-table > tbody > tr")) {
176
+                eq_legs.push([
177
+                    row.children[1].firstChild.value,
178
+                    parseInt(row.children[2].firstChild.value) || 0,
179
+                    parseInt(row.children[3].firstChild.value) || 0
180
+                ]);
181
+            }
182
+
183
+            let data = {
184
+                "head": eq_head,
185
+                "chest": eq_chest,
186
+                "legs": eq_legs
187
+            };
188
+
189
+            return data;
190
+        }
191
+
192
+        // Add event listeners to our table buttons
193
+        const add_row_buttons = document.querySelectorAll("a.add-row-button");
194
+        for(let button of add_row_buttons) {
195
+            button.addEventListener("click", addEquipmentTableRow, false);
196
+        }
197
+        const del_row_buttons = document.querySelectorAll("a.del-row-button");
198
+        for(let button of del_row_buttons) {
199
+            button.addEventListener("click", deleteEquipmentTableRow, false);
200
+        }
201
+
202
+        // Add event listener to Calculate button, call backend
203
+        document.querySelector("#calculate-button").addEventListener("click", calculateEquipment, false);
204
+
205
+        // Enable sorting for our results table
206
+        var table_sort = new Tablesort(document.querySelector("table#results-table"));
207
+    </script>
208
+    <style type="text/css">
209
+        table:not(#results-table) > tbody > tr > td:first-child {
210
+            color: #999;
211
+        }
212
+
213
+        div > a.add-row-button {
214
+            color: #32d296;
215
+        }
216
+
217
+        table a.del-row-button {
218
+            color: #f0506e;
219
+        }
220
+
221
+        table#results-table > tbody > tr > td:first-child {
222
+            font-weight: bold;
223
+            color: #6c9f12;
224
+        }
225
+
226
+        /* Result Table from Tablesort.css */
227
+        th:not(.no-sort) {
228
+            cursor: pointer;
229
+        }
230
+
231
+        th[role=columnheader]:not(.no-sort):after {
232
+            content: '';
233
+            float: right;
234
+            margin-top: 7px;
235
+            border-width: 0 4px 4px;
236
+            border-style: solid;
237
+            border-color: #404040 transparent;
238
+            visibility: hidden;
239
+            opacity: 0;
240
+            -ms-user-select: none;
241
+            -webkit-user-select: none;
242
+            -moz-user-select: none;
243
+            user-select: none;
244
+        }
245
+
246
+        th[aria-sort=ascending]:not(.no-sort):after {
247
+            border-bottom: none;
248
+            border-width: 4px 4px 0;
249
+        }
250
+
251
+        th[aria-sort]:not(.no-sort):after {
252
+            visibility: visible;
253
+            opacity: 0.4;
254
+        }
255
+
256
+        th[role=columnheader]:not(.no-sort):hover:after {
257
+            visibility: visible;
258
+            opacity: 1;
259
+        }
260
+    </style>
261
+</html>

Loading…
Cancel
Save