...
 
Commits (2)
......@@ -9,11 +9,12 @@ from model_transform.bac_position import transform_positions
from model_transform.util import read_flags, transform_time_element
def transform_script(data):
def transform_script(data, move_list_id, cancel_list_usage):
if data is None:
return None
idx = data["Index"]
res = {
"Index": data["Index"],
"Index": idx,
"Name": data["Name"],
"LastActionFrame": data["LastHitboxFrame"] if data["LastHitboxFrame"] >= 0 else None,
"InterruptFrame": data["InterruptFrame"] if data["InterruptFrame"] >= 0 else None,
......@@ -45,7 +46,7 @@ def transform_script(data):
res["Status"] = [transform_type1(t) for t in data["Type1s"] or []] or None
res["AutoCancels"] = [transform_autocancel(t) for t in data["AutoCancels"] or []] or None
res["Cancels"] = [transform_cancel(t) for t in data["Cancels"] or []] or None
res["Cancels"] = [transform_cancel(t, idx, move_list_id, cancel_list_usage) for t in data["Cancels"] or [] if t["CancelList"] >= 0] or None
res["Hitboxes"] = [transform_hitbox(t) for t in data["Hitboxes"] or []] or None
res["Hurtboxes"] = [transform_hurtbox(t) for t in data["Hurtboxes"] or []] or None
res["Pushboxes"] = [transform_box(t) for t in data["PhysicsBoxes"] or []] or None
......@@ -62,8 +63,8 @@ def transform_script(data):
return res
def transform_bac(data):
scripts = [{m["Index"]: transform_script(m) for m in ml["Moves"] if m is not None} for ml in data["MoveLists"]]
def transform_bac(data, cancel_lists_usage):
scripts = [{m["Index"]: transform_script(m, i, cancel_lists_usage) for m in ml["Moves"] if m is not None} for i, ml in enumerate(data["MoveLists"])]
return {
"Scripts": {
"Normal": scripts[0]
......
from model_transform.bcm import cancel_list_id
from model_transform.util import read_flags, transform_time_element
......@@ -17,9 +18,10 @@ def transform_type1(data):
return res
def transform_cancel(data):
def transform_cancel(data, idx, move_list_id, cancel_list_usage):
res = transform_time_element(data)
res["CancelList"] = data["CancelList"]
res["CancelList"] = cancel_list_id(data["CancelList"])
cancel_list_usage[res["CancelList"]].add((move_list_id, idx))
if data["Type"] == 0:
res["Type"] = "Buffer Always"
elif data["Type"] < 8:
......
......@@ -130,19 +130,20 @@ def transform_move(data, max_uk8):
return res
def cancel_list_id(idx):
if idx < 4:
return ["GROUND", "NEUTRAL JUMP", "FORWARD JUMP", "BACKWARD JUMP"][idx]
return str(idx)
def transform_bcm(bcm):
cancel_lists = dict()
if bcm["CancelLists"]:
cancel_lists = {
"GROUND": transform_cancel_list(bcm["CancelLists"][0]),
"NEUTRAL JUMP": transform_cancel_list(bcm["CancelLists"][1]),
"FORWARD JUMP": transform_cancel_list(bcm["CancelLists"][2]),
"BACKWARD JUMP": transform_cancel_list(bcm["CancelLists"][3]),
cancel_list_id(i): transform_cancel_list(c)
for i, c in enumerate(bcm["CancelLists"])
if c["Cancels"] is not None
}
for i, c in enumerate(bcm["CancelLists"][4:]):
if c["Cancels"] is None:
continue
cancel_lists["%d" % (i+4)] = transform_cancel_list(c)
max_uk8 = max(m["Unknown8"] for m in bcm["Moves"])
return {
"Charges": {i: elem for i, elem in enumerate(map(transform_charge, bcm["Charges"]))},
......
from collections import defaultdict
from model_transform.bac import transform_bac
from model_transform.bch import transform_bch
from model_transform.bcm import transform_bcm
......@@ -15,11 +17,14 @@ char_alias = {
def transform_data(BAC, BCM, BCH, BAC_eff, char, version):
return {
"BAC": transform_bac(BAC),
cancel_lists_usage = defaultdict(lambda: set())
result = {
"BAC": transform_bac(BAC, cancel_lists_usage),
"BCM": transform_bcm(BCM),
"BCH": transform_bch(BCH),
"BAC_eff": transform_bac(BAC_eff) if BAC_eff else None,
"BAC_eff": transform_bac(BAC_eff, None) if BAC_eff else None,
"char": char_alias.get(char, char),
"version": version
}
result["BCM"]["CancelListsUsage"] = cancel_lists_usage
return result
\ No newline at end of file
......@@ -199,7 +199,7 @@
.timeline-container {
width: 100%;
overflow-x: scroll;
overflow-x: auto;
height: 100%;
}
......@@ -373,6 +373,10 @@ dd ul {
padding: 5px;
border-radius: 5px;
}
.cancel-list hr {
margin: 5px;
border-top: 1px solid lightgray;
}
.cancel-list h4 {
margin: 0 1em 0 0;
display: inline-block;
......@@ -381,7 +385,17 @@ dd ul {
display: inline;
font-size: smaller;
}
.cancel-list > div > span {
.cancel-list > div > a {
border: 1px solid lightgray;
padding: 1px;
line-height: 20px;
border-radius: 5px;
}
.script-cancel-list h4 {
display: inline-block;
font-size: small;
}
.script-cancel-list a {
border: 1px solid lightgray;
padding: 1px;
line-height: 20px;
......
......@@ -112,7 +112,8 @@ $(".timeline").on("click", function(e) {
}
});
$(".property").on("click", function(e) { e.stopPropagation(); });
$(".timeline-container > div").prepend(grid);
$(".script-cancel-list").on("click", function(e) { e.stopPropagation(); });
$(".timeline-container > div:first-child").prepend(grid);
$(".unknown").hide();
$(function () {
$('[data-toggle="tooltip"]').tooltip({container: 'body'})
......
......@@ -16,6 +16,30 @@ from view.render.routing import he_path, script_path, move_path
from view.render.script import render_script
from view.render.version_menu import render_version_menu, char_label
from zipfile36 import ZipFile, ZIP_DEFLATED
class MockZip:
def __init__(self, *args, **kwargs):
return
@staticmethod
def open(path, mode="w"):
return open(path, "wb")
@staticmethod
def getinfo(path):
if os.path.exists(path):
return True
raise KeyError("File does not exists")
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
return
# output_path = "C:/Users/WydD/Desktop/export/"
output_path = "result/"
basepath = "D:/Steam/SteamApps/common/StreetFighterV/StreetFighterV/Content/Paks/moves/StreetFighterV/Content/Chara"
......@@ -90,9 +114,10 @@ def write_scripts(zf, menu_data, output, data, diff, before, path, **kwargs):
f.write(rendered.encode("utf-8"))
def get_output_dir(char, version):
def get_output_dir(char, version, zf):
output = output_path + char + "/" + version + "/"
return output
if type(zf) is ZipFile:
return output
if not os.path.exists(output_path + char):
os.mkdir(output_path + char)
......@@ -117,7 +142,7 @@ def write_version(char_path, char_versions, char, version, zf):
before = None
diff = {}
output = get_output_dir(data["char"], data["version"])
output = get_output_dir(data["char"], data["version"], zf)
menu_data = {
"char": data["char"],
......@@ -155,9 +180,11 @@ def write_version(char_path, char_versions, char, version, zf):
print(t, "seconds to write script")
from zipfile36 import ZipFile, ZIP_DEFLATED
with ZipFile("result/dump.zip", "w", compression=ZIP_DEFLATED) as zf:
with zf.open(output_path + "about.html", "w") as f:
f.write(render("about.html", title="", menu_data={}, chars=char_label).encode("utf-8"))
with zf.open(output_path + "help.html", "w") as f:
f.write(render("help.html", title="", menu_data={}, chars=char_label).encode("utf-8"))
with zf.open(output_path + "index.html", "w") as f:
f.write(render("main.html", title="", menu_data={}, chars=char_label).encode("utf-8"))
......
......@@ -3,8 +3,10 @@ import json
from view.force_simulation import simulate_positions
from view.render.box import render_boxes
from view.render.jinja import render
from view.render.routing import move_path
from view.render.timeline import render_all_timeline
from view.render.util import extract_diff_for_view
from view.render.version_menu import cancel_list_sort
def contains_unknown(diff):
......@@ -25,6 +27,7 @@ def contains_unknown(diff):
def render_script(script, diff, old_version, menu_data, **kwargs):
paths = ["Status", "Hitboxes", "Hurtboxes", "Pushboxes", "Cancels", "AutoCancels", "Commands", "Forces",
"Unknown"]
data = kwargs["data"]
left_panel = render_all_timeline(script, paths, diff, **kwargs)
right_panel, box_js = render_boxes(script, diff)
positions = simulate_positions(script)
......@@ -49,10 +52,15 @@ def render_script(script, diff, old_version, menu_data, **kwargs):
json.dumps(old_positions, default=float),
box_js
)
moves = data["BCM"]["Moves"]
cancel_lists = [
(cl, sorted([(m, move_path(moves[m])) for m in data["BCM"]["CancelLists"].get(cl, [])], key=lambda x: moves[x[0]]["Index"]))
for cl in sorted({c["CancelList"] for c in script.get("Cancels", [])}, key=lambda x: cancel_list_sort(x))
]
return render(
'script.html',
title="#%d - %s" % (script["Index"], script["Name"]),
menu_data=menu_data,
menu_data=menu_data, cancel_lists=cancel_lists,
timeline=left_panel, boxes=right_panel, js=js, script=script,
positions=positions, property_diff=property_diff
)
......
......@@ -80,12 +80,32 @@ def cancel_list_sort(cl_name):
return int(cl_name)
def cancel_list_usage_item(m, normal_scripts, alt_scripts, diffu):
script = (normal_scripts if m[0] == 0 else alt_scripts)[m[1]]
return script, script_path(script, m[0] == 1), extract_diff_for_view(diffu).get(m)
def as_cancel_list_list(data, diff):
moves = get_from_path(["BCM", "Moves"], data) or {}
cll = get_from_path(["BCM", "CancelLists"], data) or {}
diffu = get_from_path(["BCM", "CancelListsUsage"], diff) or {}
cllu = get_from_path(["BCM", "CancelListsUsage"], data) or {}
diff = get_from_path(["BCM", "CancelLists"], diff) or {}
normal_scripts = get_from_path(["BAC", "Scripts", "Normal"], data) or {}
alt_scripts = get_from_path(["BAC", "Scripts", "Alternate"], data) or {}
dict_diff = extract_diff_for_view(diff)
return sorted(((name, sorted([(m, extract_diff_for_view(diff.get(name, {})).get(m)) for m in cl], key=lambda x: moves[x[0]]["Index"]), dict_diff.get(name)) for name, cl in cll.items()), key=lambda x: cancel_list_sort(x[0]))
return sorted(
(
(
name,
sorted([(m, extract_diff_for_view(diff.get(name, {})).get(m), move_path(moves[m])) for m in cl], key=lambda x: moves[x[0]]["Index"]),
dict_diff.get(name),
sorted([cancel_list_usage_item(m, normal_scripts, alt_scripts, diffu.get(name, {})) for m in cllu.get(name, [])], key=lambda x: x[0]["Index"])
)
for name, cl in cll.items()
),
key=lambda x: cancel_list_sort(x[0])
)
def effects_map(scripts, diff, **kwargs):
......
......@@ -31,8 +31,8 @@
<ul class="nav navbar-nav navbar-right">
<li><a target="_blank" href="{{ relative_path }}help.html"><span class="glyphicon glyphicon-question-sign"></span> Help</a></li>
<li><a target="_blank" href="{{ relative_path }}about.html"><span class="glyphicon glyphicon-info-sign"></span> About</a></li>
<li><a target="_blank" href="https://sfvsim.com/donate.html"><span class="glyphicon glyphicon-usd"></span> Donate</a></li>
<li><a target="_blank" href="https://gitlab.com/loic.petit/sfvdiff/"><span class="glyphicon glyphicon-new-window"></span> Source code</a></li>
<li><a target="_blank" href="https://gitlab.com/loic.petit/sfvdiff/issues/"><span class="glyphicon glyphicon-new-window"></span> Issues</a></li>
</ul>
</div>
</div>
......
......@@ -52,6 +52,18 @@
<div class="col-md-8 col-lg-9">
<div class='timeline-container'>
{{ timeline }}
<div class="script-cancel-list">
<ul>
{%- for name, moves in cancel_lists %}
<li>
<h4>Cancel {{ name }}: </h4>
{%- for name, link in moves %}
<a href="../{{ link }}">{{ name }}</a>
{%- endfor %}
</li>
{%- endfor %}
</ul>
</div>
</div>
</div>
</div>
......
......@@ -68,10 +68,18 @@
<div class="row cancel-list {{ cl[2][0] }}">
<h4>{{ cl[0] }}</h4>
<div>
{%- for move, diff_class in cl[1] %}
<span{% if diff_class %} class="{{ diff_class[0] }}"{% endif %}>{{ move }}</span>
{%- for move, diff_class, link in cl[1] %}
<a href="{{ link }}"{% if diff_class %} class="{{ diff_class[0] }}"{% endif %}><b>{{ move }}</b></a>
{%- endfor %}
</div>
{%- if cl[3] %}<hr/>
<h4>Used in: </h4>
<div>
{%- for script, link, diff_class in cl[3] %}
<a href="{{ link }}"{% if diff_class %} class="{{ diff_class[0] }}"{% endif %}>#{{script["Index"]}} - <b>{{ script["Name"] }}</b></a>
{%- endfor %}
</div>
{%- endif %}
</div>
{%- endfor %}
</div>
......