add weaponlist search, improve stats in planner

main
Bryce Allen 10 years ago
parent b244c7fa5e
commit 09009edbd7

@ -312,7 +312,11 @@ class Skill(RowModel):
class Weapon(RowModel):
_list_fields = ["id", "wtype", "name"]
_indexes = { "name": "id",
"wtype": ["id", "name"] }
"wtype": ["id", "name"],
# subset of all data that can be used for searching and
# not be too bloated
"id": ["name", "wtype", "final", "element", "element_2",
"awaken"] }
def __init__(self, weapon_item_row):
super(Weapon, self).__init__(weapon_item_row)

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1009 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -10,10 +10,29 @@
<script src="js/common.js"></script>
<script type="text/javascript">
$(document).ready(function(){
setup_item_autocomplete("#item");
setup_weapon_autocomplete("#weapon_type", "#weapon");
});
$(document).ready(function(){
setup_item_autocomplete("#item");
setup_weapon_autocomplete_by_type();
$("#weapon_type").change(function(evt) {
update_weapon_autocomplete("#weapon", autocomplete_predicate, null);
});
});
function autocomplete_predicate(weapon_data) {
var weapon_type = $("#weapon_type").val();
if (weapon_type != "All" && weapon_type != weapon_data["wtype"]) {
return false;
}
return true;
}
function setup_weapon_autocomplete_by_type() {
// the completion and change fn are null because the page uses a form
// and submits to the weapon planner page
setup_weapon_autocomplete("#weapon", autocomplete_predicate,
null, null);
}
</script>
<style>

@ -1,5 +1,9 @@
// maps name -> [id]
WEAPON_NAME_IDX = {};
WEAPON_TYPE_IDX = {};
// maps id -> dict with keys:
// ["name", "wtype", "final", "element", "element_2", "awaken"]
WEAPON_ID_IDX = {};
_ITEM_NAME_SPECIAL = {
"welldonesteak": "Well-done Steak",
@ -107,45 +111,50 @@ function setup_item_autocomplete(selector) {
}
function setup_weapon_autocomplete(type_selector, weapon_selector, ready_fn,
change_fn) {
function load_weapon_data(ready_fn) {
var DATA_PATH = get_base_path() + "/jsonapi/";
$.getJSON(DATA_PATH + "weapon/_index_name.json",
function(data) {
WEAPON_NAME_IDX = data;
$.getJSON(DATA_PATH + "weapon/_index_wtype.json",
$.getJSON(DATA_PATH + "weapon/_index_id.json",
function(data) {
WEAPON_TYPE_IDX = data;
if (ready_fn) {
ready_fn();
}
_setup_weapon_autocomplete(
$(type_selector).val(),
weapon_selector,
change_fn);
$(type_selector).change(function(evt) {
$(weapon_selector).val("");
_setup_weapon_autocomplete(
$(type_selector).val(),
weapon_selector, change_fn);
});
WEAPON_ID_IDX = data;
ready_fn();
});
});
}
function _setup_weapon_autocomplete(type, weapon_selector, change_fn) {
function setup_weapon_autocomplete(weapon_selector, predicate_fn, ready_fn,
change_fn) {
load_weapon_data(function() {
update_weapon_autocomplete(
weapon_selector,
predicate_fn,
change_fn);
if (ready_fn) {
ready_fn();
}
});
}
function update_weapon_autocomplete(weapon_selector, predicate_fn, change_fn) {
//alert("set weapon type " + type + " (" + weapon_selector + ")");
var source;
if (type == "All") {
source = Object.keys(WEAPON_NAME_IDX);
//alert(source[10]);
} else {
var object_list = WEAPON_TYPE_IDX[type];
source = [];
for (i=0; i<object_list.length; i++) {
source.push(object_list[i]["name"]);
source = [];
$.each(WEAPON_ID_IDX, function(weapon_id, weapons) {
var weapon_data = weapons[0];
if (predicate_fn(weapon_data)) {
var name = weapon_data["name"];
if (name) {
source.push(name);
} else {
console.log("WARN: weapon with no name '" + weapon_id + "'");
}
}
}
});
console.log("update weapon autocomplete len: " + source.length);
console.log("weapon_selector = '" + weapon_selector + "'");
$(weapon_selector).autocomplete(
{ source: source,
change: function (event, ui) {

@ -0,0 +1,49 @@
<tr>
<td><% if (final == 1) { %>
<strong>*</strong>
<% } else { %>
&nbsp;
<% } %>
</td>
<td>
<a href="weaponplanner.html?weapon=<%= encodeURIComponent(name) %>"
><%= name %></a>
</td>
<td><%= wtype %></td>
<td><%= attack %></td>
<td style="text-align:right"><% if (affinity) { %><%= affinity %>%<% } %></td>
<td>
<% if (awaken) { %>
[<%= awaken_attack %> <%= awaken %>]
<% } else if (element) { %>
(<%= element_attack %> <%= element %>
<% if (element_2) { %>
, <%= element_2_attack %> <%= element_2 %>
<% } %>)
<% } %>
</td>
<td><%= Array(num_slots + 1).join("o")
%><%= Array(3 - num_slots + 1).join("-") %></td>
<td>
<div class="sharpness-bar" title="<%= sharpness_title %>">
<span style="width:<%= sharpness[0] %>px" class="red"></span>
<span style="width:<%= sharpness[1] %>px" class="orange"></span>
<span style="width:<%= sharpness[2] %>px" class="yellow"></span>
<span style="width:<%= sharpness[3] %>px" class="green"></span>
<span style="width:<%= sharpness[4] %>px" class="blue"></span>
<span style="width:<%= sharpness[5] %>px" class="white"></span>
<span style="width:<%= sharpness[6] %>px" class="purple"></span>
</div>
<div class="sharpness-bar" title="<%= sharpness_plus_title %>">
<span style="width:<%= sharpness_plus[0] %>px" class="red"></span>
<span style="width:<%= sharpness_plus[1] %>px" class="orange"></span>
<span style="width:<%= sharpness_plus[2] %>px" class="yellow"></span>
<span style="width:<%= sharpness_plus[3] %>px" class="green"></span>
<span style="width:<%= sharpness_plus[4] %>px" class="blue"></span>
<span style="width:<%= sharpness_plus[5] %>px" class="white"></span>
<span style="width:<%= sharpness_plus[6] %>px" class="purple"></span>
</div>
</td>
<td><%= sharpness_title %></td>
<td>(<%= sharpness_plus_title %>)</td>
</tr>

@ -1,18 +1,37 @@
<table>
<tr>
<td><%= name %>:</td>
<td><%= attack %></td>
<td><%= name %></td>
<td>(<%= wtype %>)</td>
<td style="text-align:right"><% if (phial) { %>&lt;<%= phial %> Phial&gt;<% } %></td>
<td><%= Array(num_slots + 1).join("o")
%><%= Array(3 - num_slots + 1).join("-") %></td>
</tr>
</table>
<table>
<tr>
<td>Atk: <%= attack %></td>
<td style="text-align:right"><% if (affinity) { %><%= affinity %>%<% } %></td>
<td>
<% if (awaken) { %>
[<%= awaken_attack %> <%= awaken %>]
(<img style="height:.8em" title="Awaken <%= awaken %>"
src="img/<%= awaken %>.png" /><%= awaken_attack %> <%= awaken %>)
<% } else if (element) { %>
(<%= element_attack %> <%= element %>
<img style="height:.8em" title="<%= element %>"
src="img/<%= element %>.png" /> <%= element_attack %>
<%= element %>
<% if (element_2) { %>
, <%= element_2_attack %> <%= element_2 %>
<% } %>)
<img style="height:.8em" title="<%= element_2 %>"
src="img/<%= element_2 %>.png" /> <%= element_2_attack %>
<%= element_2 %>
<% } %>
<% } %>
</td>
<td><%= Array(num_slots + 1).join("\u26aa") %></td>
<td style="text-align:right"><% if (defense) { %>+<%= defense %> Def<% } %></td>
</tr>
</table>
<table>
<tr>
<td>
<div class="sharpness-bar" title="<%= sharpness_title %>">
<span style="width:<%= sharpness[0] %>px" class="red"></span>
@ -33,9 +52,12 @@
<span style="width:<%= sharpness_plus[6] %>px" class="purple"></span>
</div>
</td>
<td><%= sharpness_title %> (<%= sharpness_plus_title %>)</td>
<td><%= sharpness_title %></td>
<td>(<%= sharpness_plus_title %>)</td>
</tr>
</table>
<% if (children.length) { %>
<table>
<tr><td colspan="5"> -&gt;
<% for(var i=0; i<children.length; i++) { %>
<a href="weaponplanner.html?weapon=<%= encodeURIComponent(children[i]['name']) %>"
@ -43,5 +65,5 @@
<% if (i != children.length - 1) { %>|<% } %>
<% } %>
</td></tr>
</table>
<% } %>
</table>

@ -0,0 +1,285 @@
<html>
<head>
<title>Poogie's Weapon List</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/smoothness/jquery-ui.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script>
<script type="text/javascript" src="js/ejs_production.js"></script>
<script type="text/javascript" src="js/common.js"></script>
<style>
label {
font-weight: bold;
}
body {
font-family: sans, sans-serif;
}
td.plus {
background-color: LightCyan;
}
td.minus {
background-color: LightPink;
}
td.num {
text-align: right;
}
/*@media (max-width: 600) {*/
.flexbox {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.sharpness-bar {
border: 1px #d3d3d3 solid;
min-width: 92px;
height: 10px;
background-color: #d3d3d3;
float: left;
clear: both;
}
.sharpness-bar span {
display: inline-block;
height: 100%;
float: left;
}
.sharpness-bar .red {
background-color: #C00C38 !important;
}
.sharpness-bar .orange {
background-color: #E85018 !important;
}
.sharpness-bar .yellow {
background-color: #F0C830 !important;
}
.sharpness-bar .green {
background-color: #58D000 !important;
}
.sharpness-bar .blue {
background-color: #3068E8 !important;
}
.sharpness-bar .white {
background-color: #F0F0F0 !important;
}
.sharpness-bar .purple {
background-color: #c3c !important;
}
</style>
<script type="text/javascript">
var DATA_PATH = get_base_path() + "/jsonapi/";
var template_row = new EJS({ url: "templates/weaponrow.ejs" });
$(document).ready(function(){
load_weapon_data(init_page);
});
function init_page() {
load_qs();
$(window).on("popstate", function(e) {
var oe = e.originalEvent;
if (oe.state !== null) {
console.log("popState:" + JSON.stringify(oe.state));
update_weapon_list(oe.state);
}
});
$("#search").click(function(evt) {
var state = get_ui_state();
save_state(state);
update_weapon_list(state);
});
}
function load_qs() {
if ($.QueryString["weapon_type"]) {
load_state($.QueryString);
}
}
function get_ui_state() {
return { "weapon_type": $("#weapon_type").val(),
"weapon_element": $("#weapon_element").val(),
"weapon_final": $("#weapon_final").is(":checked"),
"weapon_name_text": $("#weapon_name_text").val(),
"weapon_component_text": $("#weapon_component_text").val() };
}
function load_state(state) {
$("#weapon_type").val(state["weapon_type"]);
$("#weapon_element").val(state["weapon_element"]);
$("#weapon_final").prop("checked", state["weapon_final"]);
$("#weapon_name_text").val(state["weapon_name_text"]);
$("#weapon_component_text").val(state["weapon_component_text"]);
}
function save_state(state, replace) {
var url = "weaponlist.html?" + encode_qs(state);
if (replace) {
window.history.replaceState(state, "", url);
} else {
window.history.pushState(state, "", url);
}
}
function weapon_predicate(state, weapon_data) {
var weapon_type = state["weapon_type"];
var weapon_element = state["weapon_element"];
var final_only = state["weapon_final"];
var weapon_names = state["weapon_name_text"].split("|");
if (weapon_type == "Bow" || weapon_type == "Light Bowgun"
|| weapon_type == "Heavy Bowgun") {
// we only support blademaster weapons for now
return false;
}
if (final_only && weapon_data["final"] != 1) {
return false;
}
if (weapon_type != "All" && weapon_type != weapon_data["wtype"]) {
return false;
}
if (weapon_element != "All"
&& weapon_element != weapon_data["element"]
&& weapon_element != weapon_data["element_2"]
&& weapon_element != weapon_data["awaken"]) {
return false;
}
if (weapon_names && !list_match(weapon_names, [weapon_data["name"]])) {
return false;
}
return true;
}
function list_match(needles, string_list) {
var found = false;
for (var i=0; i<string_list.length; i++) {
for (var j=0; j<needles.length; j++) {
if (string_list[i].search(needles[j]) >= 0) {
found = true;
break;
}
if (found) {
break;
}
}
}
return found;
}
function update_weapon_list(state) {
var match_count = 0;
var comps = state["weapon_component_text"].split("|");
console.log("updating weapon list: " + JSON.stringify(state));
$("#weapon_table").empty();
$.each(WEAPON_ID_IDX, function(weapon_id, weapon_list) {
var weapon_data = weapon_list[0];
if (weapon_predicate(state, weapon_data)) {
match_count += 1;
$.getJSON(DATA_PATH + "weapon/" + weapon_id + ".json",
function(data) {
if (comps
&& !list_match(comps,
Object.keys(data["create_components"]))
&& !list_match(comps,
Object.keys(data["upgrade_components"])))
{
console.log("skipping '"
+ data["name"]
+ "', failed component match");
return;
}
if (data["sharpness"]) {
data["sharpness_title"] =
data["sharpness"].join(",");
data["sharpness_plus_title"] =
data["sharpness_plus"].join(",");
} else {
// gunner weapons have no sharpness
data["sharpness_title"] = "";
data["sharpness_plus_title"] = "";
}
var html = template_row.render(data);
$("#weapon_table").append(html);
});
}
});
console.log("match count: " + match_count);
}
</script>
</head>
<body>
<div>
<table>
<tr>
<td><label for="weapon_type">Type:</label></td>
<td><select id="weapon_type">
<option value="All">All</option>
<option value="Great Sword">Great Sword</option>
<option value="Long Sword">Long Sword</option>
<option value="Sword and Shield">Sword and Shield</option>
<option value="Dual Blades">Dual Blades</option>
<option value="Hammer">Hammer</option>
<option value="Hunting Horn">Hunting Horn</option>
<option value="Lance">Lance</option>
<option value="Gunlance">Gunlance</option>
<option value="Switch Axe">Switch Axe</option>
<option value="Charge Blade">Charge Blade</option>
<option value="Insect Glaive">Insect Glaive</option>
<option value="Light Bowgun">Light Bowgun</option>
<option value="Heavy Bowgun">Heavy Bowgun</option>
<option value="Bow">Bow</option>
</select></td>
<td><label for="weapon_element">Element:</label></td>
<td><select id="weapon_element">
<option value="All">All</option>
<option value="Fire">Fire</option>
<option value="Water">Water</option>
<option value="Thunder">Thunder</option>
<option value="Ice">Ice</option>
<option value="Dragon">Dragon</option>
<option value="Poison">Poison</option>
<option value="Paralysis">Paralysis</option>
<option value="Sleep">Sleep</option>
<option value="Blastblight">Blast</option>
</select></td>
<td><label for="weapon_final">Final?</label></td>
<td><input id="weapon_final" type="checkbox" /></td>
<td><button id="search">Search</button></td>
</tr>
<tr>
<td colspan="7">
<label for="weapon_name_text">Name:</label>
<input id="weapon_name_text" size="15" />
<label for="weapon_component_text">Components:</label>
<input id="weapon_component_text" size="15" />
</td>
</tr>
</table>
</div>
<table id="weapon_table">
</table>
</body>

@ -91,7 +91,7 @@
var template_stats = new EJS({ url: "templates/weaponstats.ejs" });
$(document).ready(function(){
setup_weapon_autocomplete("#weapon_type", "#weapon",
setup_weapon_autocomplete("#weapon", autocomplete_predicate,
init_page, update_search);
});
@ -107,6 +107,11 @@
show_trees(oe.state["weapon"]);
}
});
$("#weapon_type").change(function(evt) {
update_weapon_autocomplete("#weapon", autocomplete_predicate,
update_search);
$("#weapon").val("");
});
}
function load_qs() {
@ -120,12 +125,16 @@
if (weapon) {
show_trees(weapon);
console.log("replaceState: " + weapon);
set_state(wtype, weapon, true);
save_state(get_state(), true);
}
}
function set_state(weapon_type, weapon, replace) {
var state = { "weapon": weapon, "weapon_type": weapon_type };
function get_state() {
return { "weapon": $("#weapon").val(),
"weapon_type": $("#weapon_type").val() };
}
function save_state(state, replace) {
var url = "/weaponplanner.html?" + encode_qs(state);
if (replace) {
window.history.replaceState(state, "", url);
@ -134,20 +143,30 @@
}
}
function autocomplete_predicate(weapon_data) {
var weapon_type = $("#weapon_type").val();
if (weapon_type != "All" && weapon_type != weapon_data["wtype"]) {
return false;
}
return true;
}
function update_search() {
var weapon_name = $("#weapon").val();
var wtype = $("#weapon_type").val();
if (!weapon_name) return;
if (window.history.state["weapon"] == weapon_name) {
if (window.history.state
&& window.history.state["weapon"] == weapon_name) {
console.log("weapon not changed, skipping update");
return;
}
show_trees(weapon_name);
console.log("pushState: " + weapon_name);
set_state(wtype, weapon_name, false);
save_state(get_state(), false);
}
function show_trees(weapon_name) {
@ -217,8 +236,8 @@
<div>
<table>
<tr>
<td><label for="type">Type:</label></td>
<td><select id="weapon_type" name="weapon_type">
<td><label for="weapon_type">Type:</label></td>
<td><select id="weapon_type">
<option value="All">All</option>
<option value="Great Sword">Great Sword</option>
<option value="Long Sword">Long Sword</option>
@ -238,7 +257,7 @@
</tr>
<tr>
<td><label for="weapon">Weapon:</label></td>
<td><input id="weapon" name="weapon" weapon="text" size="20" />
<td><input id="weapon" name="weapon" size="20" />
<button id="search">Ask Poogie</button></td>
</tr>
</table>
@ -246,4 +265,3 @@
<div id="weapon_stats"></div>
<div id="results" class="flexbox"></div>
</body>
</body>

Loading…
Cancel
Save