Use PEP 8 naming conventions for templatesanalyzer
This commit is contained in:
parent
5bea0a0f97
commit
ccb1d747f0
@ -55,7 +55,7 @@ pipeline {
|
|||||||
stage("Template Analyzer") {
|
stage("Template Analyzer") {
|
||||||
steps {
|
steps {
|
||||||
ws("/zpool0/entity-docs"){
|
ws("/zpool0/entity-docs"){
|
||||||
sh "cd source/tools/templatesanalyzer/ && python3 unitTables.py"
|
sh "cd source/tools/templatesanalyzer/ && python3 unit_tables.py"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ This python tool has been written by wraitii and updated to 0ad A25 by hyiltiz.
|
|||||||
Its purpose is to help with unit and civ balancing by allowing quick comparison
|
Its purpose is to help with unit and civ balancing by allowing quick comparison
|
||||||
between important template data.
|
between important template data.
|
||||||
|
|
||||||
Run it using `python unitTables.py` or `pypy unitTables.py` (if you have pypy
|
Run it using `python unit_tables.py` or `pypy unit_tables.py` (if you have pypy
|
||||||
installed). The output will be located in an HTML file called
|
installed). The output will be located in an HTML file called
|
||||||
`unit_summary_table.html` in this folder.
|
`unit_summary_table.html` in this folder.
|
||||||
|
|
||||||
@ -17,15 +17,15 @@ The script generates 3 informative tables:
|
|||||||
|
|
||||||
You can customize the script by changing the units to include (loading all units
|
You can customize the script by changing the units to include (loading all units
|
||||||
might make it slightly unreadable). To change this, change the
|
might make it slightly unreadable). To change this, change the
|
||||||
`LoadTemplatesIfParent` variable. You can also consider only some civilizations.
|
`LOAD_TEMPLATES_IF_PARENT` constant. You can also consider only some civilizations.
|
||||||
You may also filter some templates based on their name, if you want to remove
|
You may also filter some templates based on their name, if you want to remove
|
||||||
specific templates. By default it loads all citizen soldiers and all champions,
|
specific templates. By default it loads all citizen soldiers and all champions,
|
||||||
and ignores non-interesting units for the comparison/efficienicy table (2nd
|
and ignores non-interesting units for the comparison/efficiency table (2nd
|
||||||
table).
|
table).
|
||||||
|
|
||||||
The HTML page comes with a JavaScript extension that allows to filter and sort
|
The HTML page comes with a JavaScript extension that allows to filter and sort
|
||||||
in-place, to help with comparisons. You can disable this by disabling javascript
|
in-place, to help with comparisons. You can disable this by disabling javascript
|
||||||
or by changing the `AddSortingOverlay` parameter in the script. This JS
|
or by changing the `ADD_SORTING_OVERLAY` constant in the script. This JS
|
||||||
extension, called TableFilter, is released under the MIT license. The version
|
extension, called TableFilter, is released under the MIT license. The version
|
||||||
used can be found at https://github.com/koalyptus/TableFilter/
|
used can be found at https://github.com/koalyptus/TableFilter/
|
||||||
|
|
||||||
@ -62,13 +62,13 @@ getting familiarized with the analyzer. Note that you'll need `dot` engine provi
|
|||||||
by the `graphviz` package. You can install `graphviz` using your system's package manager.
|
by the `graphviz` package. You can install `graphviz` using your system's package manager.
|
||||||
|
|
||||||
pip3 install pyan3==1.1.1
|
pip3 install pyan3==1.1.1
|
||||||
python3 -m pyan unitTables.py --uses --no-defines --colored \
|
python3 -m pyan unit_tables.py --uses --no-defines --colored \
|
||||||
--grouped --annotated --html > fundeps.html
|
--grouped --annotated --html > fundeps.html
|
||||||
|
|
||||||
Alternatively, only create the `.dot` file using the following line, and render
|
Alternatively, only create the `.dot` file using the following line, and render
|
||||||
it with an online renderer like http://viz-js.com/
|
it with an online renderer like http://viz-js.com/
|
||||||
|
|
||||||
python3 -m pyan unitTables.py --uses --no-defines --colored \
|
python3 -m pyan unit_tables.py --uses --no-defines --colored \
|
||||||
--grouped --annotated --dot > fundeps.dot
|
--grouped --annotated --dot > fundeps.dot
|
||||||
|
|
||||||
Enjoy!
|
Enjoy!
|
||||||
|
@ -34,14 +34,14 @@ sys.path.append("../entity")
|
|||||||
from scriptlib import SimulTemplateEntity
|
from scriptlib import SimulTemplateEntity
|
||||||
|
|
||||||
|
|
||||||
AttackTypes = ["Hack", "Pierce", "Crush", "Poison", "Fire"]
|
ATTACK_TYPES = ["Hack", "Pierce", "Crush", "Poison", "Fire"]
|
||||||
Resources = ["food", "wood", "stone", "metal"]
|
RESOURCES = ["food", "wood", "stone", "metal"]
|
||||||
|
|
||||||
# Generic templates to load
|
# Generic templates to load
|
||||||
# The way this works is it tries all generic templates
|
# The way this works is it tries all generic templates
|
||||||
# But only loads those who have one of the following parents
|
# But only loads those who have one of the following parents
|
||||||
# EG adding "template_unit.xml" will load all units.
|
# EG adding "template_unit.xml" will load all units.
|
||||||
LoadTemplatesIfParent = [
|
LOAD_TEMPLATES_IF_PARENT = [
|
||||||
"template_unit_infantry.xml",
|
"template_unit_infantry.xml",
|
||||||
"template_unit_cavalry.xml",
|
"template_unit_cavalry.xml",
|
||||||
"template_unit_champion.xml",
|
"template_unit_champion.xml",
|
||||||
@ -51,7 +51,7 @@ LoadTemplatesIfParent = [
|
|||||||
# Those describe Civs to analyze.
|
# Those describe Civs to analyze.
|
||||||
# The script will load all entities that derive (to the nth degree) from one of
|
# The script will load all entities that derive (to the nth degree) from one of
|
||||||
# the above templates.
|
# the above templates.
|
||||||
Civs = [
|
CIVS = [
|
||||||
"athen",
|
"athen",
|
||||||
"brit",
|
"brit",
|
||||||
"cart",
|
"cart",
|
||||||
@ -70,16 +70,16 @@ Civs = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Remote Civ templates with those strings in their name.
|
# Remote Civ templates with those strings in their name.
|
||||||
FilterOut = ["marian", "thureophoros", "thorakites", "kardakes"]
|
FILTER_OUT = ["marian", "thureophoros", "thorakites", "kardakes"]
|
||||||
|
|
||||||
# In the Civilization specific units table, do you want to only show the units
|
# In the Civilization specific units table, do you want to only show the units
|
||||||
# that are different from the generic templates?
|
# that are different from the generic templates?
|
||||||
showChangedOnly = True
|
SHOW_CHANGED_ONLY = True
|
||||||
|
|
||||||
# Sorting parameters for the "roster variety" table
|
# Sorting parameters for the "roster variety" table
|
||||||
ComparativeSortByCav = True
|
COMPARATIVE_SORT_BY_CAV = True
|
||||||
ComparativeSortByChamp = True
|
COMPARATIVE_SORT_BY_CHAMP = True
|
||||||
ClassesUsedForSort = [
|
CLASSES_USED_FOR_SORT = [
|
||||||
"Support",
|
"Support",
|
||||||
"Pike",
|
"Pike",
|
||||||
"Spear",
|
"Spear",
|
||||||
@ -92,16 +92,16 @@ ClassesUsedForSort = [
|
|||||||
|
|
||||||
# Disable if you want the more compact basic data. Enable to allow filtering and
|
# Disable if you want the more compact basic data. Enable to allow filtering and
|
||||||
# sorting in-place.
|
# sorting in-place.
|
||||||
AddSortingOverlay = True
|
ADD_SORTING_OVERLAY = True
|
||||||
|
|
||||||
# This is the path to the /templates/ folder to consider. Change this for mod
|
# This is the path to the /templates/ folder to consider. Change this for mod
|
||||||
# support.
|
# support.
|
||||||
modsFolder = Path(__file__).resolve().parents[3] / "binaries" / "data" / "mods"
|
mods_folder = Path(__file__).resolve().parents[3] / "binaries" / "data" / "mods"
|
||||||
basePath = modsFolder / "public" / "simulation" / "templates"
|
base_path = mods_folder / "public" / "simulation" / "templates"
|
||||||
|
|
||||||
# For performance purposes, cache opened templates files.
|
# For performance purposes, cache opened templates files.
|
||||||
globalTemplatesList = {}
|
global_templates_list = {}
|
||||||
sim_entity = SimulTemplateEntity(modsFolder, None)
|
sim_entity = SimulTemplateEntity(mods_folder, None)
|
||||||
|
|
||||||
|
|
||||||
def htbout(file, balise, value):
|
def htbout(file, balise, value):
|
||||||
@ -112,27 +112,27 @@ def htout(file, value):
|
|||||||
file.write("<p>" + value + "</p>\n")
|
file.write("<p>" + value + "</p>\n")
|
||||||
|
|
||||||
|
|
||||||
def fastParse(template_name):
|
def fast_parse(template_name):
|
||||||
"""Run ET.parse() with memoising in a global table."""
|
"""Run ET.parse() with memoising in a global table."""
|
||||||
if template_name in globalTemplatesList:
|
if template_name in global_templates_list:
|
||||||
return globalTemplatesList[template_name]
|
return global_templates_list[template_name]
|
||||||
parent_string = ET.parse(template_name).getroot().get("parent")
|
parent_string = ET.parse(template_name).getroot().get("parent")
|
||||||
globalTemplatesList[template_name] = sim_entity.load_inherited(
|
global_templates_list[template_name] = sim_entity.load_inherited(
|
||||||
"simulation/templates/", str(template_name), ["public"]
|
"simulation/templates/", str(template_name), ["public"]
|
||||||
)
|
)
|
||||||
globalTemplatesList[template_name].set("parent", parent_string)
|
global_templates_list[template_name].set("parent", parent_string)
|
||||||
return globalTemplatesList[template_name]
|
return global_templates_list[template_name]
|
||||||
|
|
||||||
|
|
||||||
def getParents(template_name):
|
def get_parents(template_name):
|
||||||
template_data = fastParse(template_name)
|
template_data = fast_parse(template_name)
|
||||||
parents_string = template_data.get("parent")
|
parents_string = template_data.get("parent")
|
||||||
if parents_string is None:
|
if parents_string is None:
|
||||||
return set()
|
return set()
|
||||||
parents = set()
|
parents = set()
|
||||||
for parent in parents_string.split("|"):
|
for parent in parents_string.split("|"):
|
||||||
parents.add(parent)
|
parents.add(parent)
|
||||||
for element in getParents(
|
for element in get_parents(
|
||||||
sim_entity.get_file("simulation/templates/", parent + ".xml", "public")
|
sim_entity.get_file("simulation/templates/", parent + ".xml", "public")
|
||||||
):
|
):
|
||||||
parents.add(element)
|
parents.add(element)
|
||||||
@ -140,18 +140,18 @@ def getParents(template_name):
|
|||||||
return parents
|
return parents
|
||||||
|
|
||||||
|
|
||||||
def ExtractValue(value):
|
def extract_value(value):
|
||||||
return float(value.text) if value is not None else 0.0
|
return float(value.text) if value is not None else 0.0
|
||||||
|
|
||||||
|
|
||||||
# This function checks that a template has the given parent.
|
# This function checks that a template has the given parent.
|
||||||
def hasParentTemplate(template_name, parentName):
|
def has_parent_template(template_name, parent_name):
|
||||||
return any(parentName == parent + ".xml" for parent in getParents(template_name))
|
return any(parent_name == parent + ".xml" for parent in get_parents(template_name))
|
||||||
|
|
||||||
|
|
||||||
def CalcUnit(UnitName, existingUnit=None):
|
def calc_unit(unit_name, existing_unit=None):
|
||||||
if existingUnit is not None:
|
if existing_unit is not None:
|
||||||
unit = existingUnit
|
unit = existing_unit
|
||||||
else:
|
else:
|
||||||
unit = {
|
unit = {
|
||||||
"HP": 0,
|
"HP": 0,
|
||||||
@ -180,177 +180,177 @@ def CalcUnit(UnitName, existingUnit=None):
|
|||||||
"Civ": None,
|
"Civ": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
Template = fastParse(UnitName)
|
template = fast_parse(unit_name)
|
||||||
|
|
||||||
# 0ad started using unit class/category prefixed to the unit name
|
# 0ad started using unit class/category prefixed to the unit name
|
||||||
# separated by |, known as mixins since A25 (rP25223)
|
# separated by |, known as mixins since A25 (rP25223)
|
||||||
# We strip these categories for now
|
# We strip these categories for now
|
||||||
# This can be used later for classification
|
# This can be used later for classification
|
||||||
unit["Parent"] = Template.get("parent").split("|")[-1] + ".xml"
|
unit["Parent"] = template.get("parent").split("|")[-1] + ".xml"
|
||||||
unit["Civ"] = Template.find("./Identity/Civ").text
|
unit["Civ"] = template.find("./Identity/Civ").text
|
||||||
unit["HP"] = ExtractValue(Template.find("./Health/Max"))
|
unit["HP"] = extract_value(template.find("./Health/Max"))
|
||||||
unit["BuildTime"] = ExtractValue(Template.find("./Cost/BuildTime"))
|
unit["BuildTime"] = extract_value(template.find("./Cost/BuildTime"))
|
||||||
unit["Cost"]["population"] = ExtractValue(Template.find("./Cost/Population"))
|
unit["Cost"]["population"] = extract_value(template.find("./Cost/Population"))
|
||||||
|
|
||||||
resource_cost = Template.find("./Cost/Resources")
|
resource_cost = template.find("./Cost/Resources")
|
||||||
if resource_cost is not None:
|
if resource_cost is not None:
|
||||||
for resource_type in list(resource_cost):
|
for resource_type in list(resource_cost):
|
||||||
unit["Cost"][resource_type.tag] = ExtractValue(resource_type)
|
unit["Cost"][resource_type.tag] = extract_value(resource_type)
|
||||||
|
|
||||||
if Template.find("./Attack/Melee") is not None:
|
if template.find("./Attack/Melee") is not None:
|
||||||
unit["RepeatRate"]["Melee"] = ExtractValue(Template.find("./Attack/Melee/RepeatTime"))
|
unit["RepeatRate"]["Melee"] = extract_value(template.find("./Attack/Melee/RepeatTime"))
|
||||||
unit["PrepRate"]["Melee"] = ExtractValue(Template.find("./Attack/Melee/PrepareTime"))
|
unit["PrepRate"]["Melee"] = extract_value(template.find("./Attack/Melee/PrepareTime"))
|
||||||
|
|
||||||
for atttype in AttackTypes:
|
for atttype in ATTACK_TYPES:
|
||||||
unit["Attack"]["Melee"][atttype] = ExtractValue(
|
unit["Attack"]["Melee"][atttype] = extract_value(
|
||||||
Template.find("./Attack/Melee/Damage/" + atttype)
|
template.find("./Attack/Melee/Damage/" + atttype)
|
||||||
)
|
)
|
||||||
|
|
||||||
attack_melee_bonus = Template.find("./Attack/Melee/Bonuses")
|
attack_melee_bonus = template.find("./Attack/Melee/Bonuses")
|
||||||
if attack_melee_bonus is not None:
|
if attack_melee_bonus is not None:
|
||||||
for Bonus in attack_melee_bonus:
|
for bonus in attack_melee_bonus:
|
||||||
Against = []
|
against = []
|
||||||
CivAg = []
|
civ_ag = []
|
||||||
if Bonus.find("Classes") is not None and Bonus.find("Classes").text is not None:
|
if bonus.find("Classes") is not None and bonus.find("Classes").text is not None:
|
||||||
Against = Bonus.find("Classes").text.split(" ")
|
against = bonus.find("Classes").text.split(" ")
|
||||||
if Bonus.find("Civ") is not None and Bonus.find("Civ").text is not None:
|
if bonus.find("Civ") is not None and bonus.find("Civ").text is not None:
|
||||||
CivAg = Bonus.find("Civ").text.split(" ")
|
civ_ag = bonus.find("Civ").text.split(" ")
|
||||||
Val = float(Bonus.find("Multiplier").text)
|
val = float(bonus.find("Multiplier").text)
|
||||||
unit["AttackBonuses"][Bonus.tag] = {
|
unit["AttackBonuses"][bonus.tag] = {
|
||||||
"Classes": Against,
|
"Classes": against,
|
||||||
"Civs": CivAg,
|
"Civs": civ_ag,
|
||||||
"Multiplier": Val,
|
"Multiplier": val,
|
||||||
}
|
}
|
||||||
|
|
||||||
attack_restricted_classes = Template.find("./Attack/Melee/RestrictedClasses")
|
attack_restricted_classes = template.find("./Attack/Melee/RestrictedClasses")
|
||||||
if attack_restricted_classes is not None:
|
if attack_restricted_classes is not None:
|
||||||
newClasses = attack_restricted_classes.text.split(" ")
|
new_classes = attack_restricted_classes.text.split(" ")
|
||||||
for elem in newClasses:
|
for elem in new_classes:
|
||||||
if elem.find("-") != -1:
|
if elem.find("-") != -1:
|
||||||
newClasses.pop(newClasses.index(elem))
|
new_classes.pop(new_classes.index(elem))
|
||||||
if elem in unit["Restricted"]:
|
if elem in unit["Restricted"]:
|
||||||
unit["Restricted"].pop(newClasses.index(elem))
|
unit["Restricted"].pop(new_classes.index(elem))
|
||||||
unit["Restricted"] += newClasses
|
unit["Restricted"] += new_classes
|
||||||
|
|
||||||
elif Template.find("./Attack/Ranged") is not None:
|
elif template.find("./Attack/Ranged") is not None:
|
||||||
unit["Ranged"] = True
|
unit["Ranged"] = True
|
||||||
unit["Range"] = ExtractValue(Template.find("./Attack/Ranged/MaxRange"))
|
unit["Range"] = extract_value(template.find("./Attack/Ranged/MaxRange"))
|
||||||
unit["Spread"] = ExtractValue(Template.find("./Attack/Ranged/Projectile/Spread"))
|
unit["Spread"] = extract_value(template.find("./Attack/Ranged/Projectile/Spread"))
|
||||||
unit["RepeatRate"]["Ranged"] = ExtractValue(Template.find("./Attack/Ranged/RepeatTime"))
|
unit["RepeatRate"]["Ranged"] = extract_value(template.find("./Attack/Ranged/RepeatTime"))
|
||||||
unit["PrepRate"]["Ranged"] = ExtractValue(Template.find("./Attack/Ranged/PrepareTime"))
|
unit["PrepRate"]["Ranged"] = extract_value(template.find("./Attack/Ranged/PrepareTime"))
|
||||||
|
|
||||||
for atttype in AttackTypes:
|
for atttype in ATTACK_TYPES:
|
||||||
unit["Attack"]["Ranged"][atttype] = ExtractValue(
|
unit["Attack"]["Ranged"][atttype] = extract_value(
|
||||||
Template.find("./Attack/Ranged/Damage/" + atttype)
|
template.find("./Attack/Ranged/Damage/" + atttype)
|
||||||
)
|
)
|
||||||
|
|
||||||
if Template.find("./Attack/Ranged/Bonuses") is not None:
|
if template.find("./Attack/Ranged/Bonuses") is not None:
|
||||||
for Bonus in Template.find("./Attack/Ranged/Bonuses"):
|
for bonus in template.find("./Attack/Ranged/Bonuses"):
|
||||||
Against = []
|
against = []
|
||||||
CivAg = []
|
civ_ag = []
|
||||||
if Bonus.find("Classes") is not None and Bonus.find("Classes").text is not None:
|
if bonus.find("Classes") is not None and bonus.find("Classes").text is not None:
|
||||||
Against = Bonus.find("Classes").text.split(" ")
|
against = bonus.find("Classes").text.split(" ")
|
||||||
if Bonus.find("Civ") is not None and Bonus.find("Civ").text is not None:
|
if bonus.find("Civ") is not None and bonus.find("Civ").text is not None:
|
||||||
CivAg = Bonus.find("Civ").text.split(" ")
|
civ_ag = bonus.find("Civ").text.split(" ")
|
||||||
Val = float(Bonus.find("Multiplier").text)
|
val = float(bonus.find("Multiplier").text)
|
||||||
unit["AttackBonuses"][Bonus.tag] = {
|
unit["AttackBonuses"][bonus.tag] = {
|
||||||
"Classes": Against,
|
"Classes": against,
|
||||||
"Civs": CivAg,
|
"Civs": civ_ag,
|
||||||
"Multiplier": Val,
|
"Multiplier": val,
|
||||||
}
|
}
|
||||||
if Template.find("./Attack/Melee/RestrictedClasses") is not None:
|
if template.find("./Attack/Melee/RestrictedClasses") is not None:
|
||||||
newClasses = Template.find("./Attack/Melee/RestrictedClasses").text.split(" ")
|
new_classes = template.find("./Attack/Melee/RestrictedClasses").text.split(" ")
|
||||||
for elem in newClasses:
|
for elem in new_classes:
|
||||||
if elem.find("-") != -1:
|
if elem.find("-") != -1:
|
||||||
newClasses.pop(newClasses.index(elem))
|
new_classes.pop(new_classes.index(elem))
|
||||||
if elem in unit["Restricted"]:
|
if elem in unit["Restricted"]:
|
||||||
unit["Restricted"].pop(newClasses.index(elem))
|
unit["Restricted"].pop(new_classes.index(elem))
|
||||||
unit["Restricted"] += newClasses
|
unit["Restricted"] += new_classes
|
||||||
|
|
||||||
if Template.find("Resistance") is not None:
|
if template.find("Resistance") is not None:
|
||||||
for atttype in AttackTypes:
|
for atttype in ATTACK_TYPES:
|
||||||
unit["Resistance"][atttype] = ExtractValue(
|
unit["Resistance"][atttype] = extract_value(
|
||||||
Template.find("./Resistance/Entity/Damage/" + atttype)
|
template.find("./Resistance/Entity/Damage/" + atttype)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
Template.find("./UnitMotion") is not None
|
template.find("./UnitMotion") is not None
|
||||||
and Template.find("./UnitMotion/WalkSpeed") is not None
|
and template.find("./UnitMotion/WalkSpeed") is not None
|
||||||
):
|
):
|
||||||
unit["WalkSpeed"] = ExtractValue(Template.find("./UnitMotion/WalkSpeed"))
|
unit["WalkSpeed"] = extract_value(template.find("./UnitMotion/WalkSpeed"))
|
||||||
|
|
||||||
if Template.find("./Identity/VisibleClasses") is not None:
|
if template.find("./Identity/VisibleClasses") is not None:
|
||||||
newClasses = Template.find("./Identity/VisibleClasses").text.split(" ")
|
new_classes = template.find("./Identity/VisibleClasses").text.split(" ")
|
||||||
for elem in newClasses:
|
for elem in new_classes:
|
||||||
if elem.find("-") != -1:
|
if elem.find("-") != -1:
|
||||||
newClasses.pop(newClasses.index(elem))
|
new_classes.pop(new_classes.index(elem))
|
||||||
if elem in unit["Classes"]:
|
if elem in unit["Classes"]:
|
||||||
unit["Classes"].pop(newClasses.index(elem))
|
unit["Classes"].pop(new_classes.index(elem))
|
||||||
unit["Classes"] += newClasses
|
unit["Classes"] += new_classes
|
||||||
|
|
||||||
if Template.find("./Identity/Classes") is not None:
|
if template.find("./Identity/Classes") is not None:
|
||||||
newClasses = Template.find("./Identity/Classes").text.split(" ")
|
new_classes = template.find("./Identity/Classes").text.split(" ")
|
||||||
for elem in newClasses:
|
for elem in new_classes:
|
||||||
if elem.find("-") != -1:
|
if elem.find("-") != -1:
|
||||||
newClasses.pop(newClasses.index(elem))
|
new_classes.pop(new_classes.index(elem))
|
||||||
if elem in unit["Classes"]:
|
if elem in unit["Classes"]:
|
||||||
unit["Classes"].pop(newClasses.index(elem))
|
unit["Classes"].pop(new_classes.index(elem))
|
||||||
unit["Classes"] += newClasses
|
unit["Classes"] += new_classes
|
||||||
|
|
||||||
return unit
|
return unit
|
||||||
|
|
||||||
|
|
||||||
def WriteUnit(Name, UnitDict):
|
def write_unit(name, unit_dict):
|
||||||
ret = "<tr>"
|
ret = "<tr>"
|
||||||
ret += '<td class="Sub">' + Name + "</td>"
|
ret += '<td class="Sub">' + name + "</td>"
|
||||||
ret += "<td>" + str("{:.0f}".format(float(UnitDict["HP"]))) + "</td>"
|
ret += "<td>" + str("{:.0f}".format(float(unit_dict["HP"]))) + "</td>"
|
||||||
ret += "<td>" + str("{:.0f}".format(float(UnitDict["BuildTime"]))) + "</td>"
|
ret += "<td>" + str("{:.0f}".format(float(unit_dict["BuildTime"]))) + "</td>"
|
||||||
ret += "<td>" + str("{:.1f}".format(float(UnitDict["WalkSpeed"]))) + "</td>"
|
ret += "<td>" + str("{:.1f}".format(float(unit_dict["WalkSpeed"]))) + "</td>"
|
||||||
|
|
||||||
for atype in AttackTypes:
|
for atype in ATTACK_TYPES:
|
||||||
PercentValue = 1.0 - (0.9 ** float(UnitDict["Resistance"][atype]))
|
percent_value = 1.0 - (0.9 ** float(unit_dict["Resistance"][atype]))
|
||||||
ret += (
|
ret += (
|
||||||
"<td>"
|
"<td>"
|
||||||
+ str("{:.0f}".format(float(UnitDict["Resistance"][atype])))
|
+ str("{:.0f}".format(float(unit_dict["Resistance"][atype])))
|
||||||
+ " / "
|
+ " / "
|
||||||
+ str("%.0f" % (PercentValue * 100.0))
|
+ str("%.0f" % (percent_value * 100.0))
|
||||||
+ "%</td>"
|
+ "%</td>"
|
||||||
)
|
)
|
||||||
|
|
||||||
attType = "Ranged" if UnitDict["Ranged"] is True else "Melee"
|
att_type = "Ranged" if unit_dict["Ranged"] is True else "Melee"
|
||||||
if UnitDict["RepeatRate"][attType] != "0":
|
if unit_dict["RepeatRate"][att_type] != "0":
|
||||||
for atype in AttackTypes:
|
for atype in ATTACK_TYPES:
|
||||||
repeatTime = float(UnitDict["RepeatRate"][attType]) / 1000.0
|
repeat_time = float(unit_dict["RepeatRate"][att_type]) / 1000.0
|
||||||
ret += (
|
ret += (
|
||||||
"<td>"
|
"<td>"
|
||||||
+ str("%.1f" % (float(UnitDict["Attack"][attType][atype]) / repeatTime))
|
+ str("%.1f" % (float(unit_dict["Attack"][att_type][atype]) / repeat_time))
|
||||||
+ "</td>"
|
+ "</td>"
|
||||||
)
|
)
|
||||||
|
|
||||||
ret += "<td>" + str("%.1f" % (float(UnitDict["RepeatRate"][attType]) / 1000.0)) + "</td>"
|
ret += "<td>" + str("%.1f" % (float(unit_dict["RepeatRate"][att_type]) / 1000.0)) + "</td>"
|
||||||
else:
|
else:
|
||||||
for _ in AttackTypes:
|
for _ in ATTACK_TYPES:
|
||||||
ret += "<td> - </td>"
|
ret += "<td> - </td>"
|
||||||
ret += "<td> - </td>"
|
ret += "<td> - </td>"
|
||||||
|
|
||||||
if UnitDict["Ranged"] is True and UnitDict["Range"] > 0:
|
if unit_dict["Ranged"] is True and unit_dict["Range"] > 0:
|
||||||
ret += "<td>" + str("{:.1f}".format(float(UnitDict["Range"]))) + "</td>"
|
ret += "<td>" + str("{:.1f}".format(float(unit_dict["Range"]))) + "</td>"
|
||||||
spread = float(UnitDict["Spread"])
|
spread = float(unit_dict["Spread"])
|
||||||
ret += "<td>" + str(f"{spread:.1f}") + "</td>"
|
ret += "<td>" + str(f"{spread:.1f}") + "</td>"
|
||||||
else:
|
else:
|
||||||
ret += "<td> - </td><td> - </td>"
|
ret += "<td> - </td><td> - </td>"
|
||||||
|
|
||||||
for rtype in Resources:
|
for rtype in RESOURCES:
|
||||||
ret += "<td>" + str("{:.0f}".format(float(UnitDict["Cost"][rtype]))) + "</td>"
|
ret += "<td>" + str("{:.0f}".format(float(unit_dict["Cost"][rtype]))) + "</td>"
|
||||||
|
|
||||||
ret += "<td>" + str("{:.0f}".format(float(UnitDict["Cost"]["population"]))) + "</td>"
|
ret += "<td>" + str("{:.0f}".format(float(unit_dict["Cost"]["population"]))) + "</td>"
|
||||||
|
|
||||||
ret += '<td style="text-align:left;">'
|
ret += '<td style="text-align:left;">'
|
||||||
for Bonus in UnitDict["AttackBonuses"]:
|
for bonus in unit_dict["AttackBonuses"]:
|
||||||
ret += "["
|
ret += "["
|
||||||
for classe in UnitDict["AttackBonuses"][Bonus]["Classes"]:
|
for classe in unit_dict["AttackBonuses"][bonus]["Classes"]:
|
||||||
ret += classe + " "
|
ret += classe + " "
|
||||||
ret += ": {}] ".format(UnitDict["AttackBonuses"][Bonus]["Multiplier"])
|
ret += ": {}] ".format(unit_dict["AttackBonuses"][bonus]["Multiplier"])
|
||||||
ret += "</td>"
|
ret += "</td>"
|
||||||
|
|
||||||
ret += "</tr>\n"
|
ret += "</tr>\n"
|
||||||
@ -358,37 +358,37 @@ def WriteUnit(Name, UnitDict):
|
|||||||
|
|
||||||
|
|
||||||
# Sort the templates dictionary.
|
# Sort the templates dictionary.
|
||||||
def SortFn(A):
|
def sort_fn(a):
|
||||||
sortVal = 0
|
sort_val = 0
|
||||||
for classe in ClassesUsedForSort:
|
for classe in CLASSES_USED_FOR_SORT:
|
||||||
sortVal += 1
|
sort_val += 1
|
||||||
if classe in A[1]["Classes"]:
|
if classe in a[1]["Classes"]:
|
||||||
break
|
break
|
||||||
if ComparativeSortByChamp is True and A[0].find("champion") == -1:
|
if COMPARATIVE_SORT_BY_CHAMP is True and a[0].find("champion") == -1:
|
||||||
sortVal -= 20
|
sort_val -= 20
|
||||||
if ComparativeSortByCav is True and A[0].find("cavalry") == -1:
|
if COMPARATIVE_SORT_BY_CAV is True and a[0].find("cavalry") == -1:
|
||||||
sortVal -= 10
|
sort_val -= 10
|
||||||
if A[1]["Civ"] is not None and A[1]["Civ"] in Civs:
|
if a[1]["Civ"] is not None and a[1]["Civ"] in CIVS:
|
||||||
sortVal += 100 * Civs.index(A[1]["Civ"])
|
sort_val += 100 * CIVS.index(a[1]["Civ"])
|
||||||
return sortVal
|
return sort_val
|
||||||
|
|
||||||
|
|
||||||
def WriteColouredDiff(file, diff, isChanged):
|
def write_coloured_diff(file, diff, is_changed):
|
||||||
"""Help to write coloured text.
|
"""Help to write coloured text.
|
||||||
|
|
||||||
diff value must always be computed as a unit_spec - unit_generic.
|
diff value must always be computed as a unit_spec - unit_generic.
|
||||||
A positive imaginary part represents advantageous trait.
|
A positive imaginary part represents advantageous trait.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def cleverParse(diff):
|
def clever_parse(diff):
|
||||||
if float(diff) - int(diff) < 0.001:
|
if float(diff) - int(diff) < 0.001:
|
||||||
return str(int(diff))
|
return str(int(diff))
|
||||||
return str(f"{float(diff):.1f}")
|
return str(f"{float(diff):.1f}")
|
||||||
|
|
||||||
isAdvantageous = diff.imag > 0
|
is_advantageous = diff.imag > 0
|
||||||
diff = diff.real
|
diff = diff.real
|
||||||
if diff != 0:
|
if diff != 0:
|
||||||
isChanged = True
|
is_changed = True
|
||||||
else:
|
else:
|
||||||
# do not change its value if one parameter is not changed (yet)
|
# do not change its value if one parameter is not changed (yet)
|
||||||
# some other parameter might be different
|
# some other parameter might be different
|
||||||
@ -396,32 +396,32 @@ def WriteColouredDiff(file, diff, isChanged):
|
|||||||
|
|
||||||
if diff == 0:
|
if diff == 0:
|
||||||
rgb_str = "200,200,200"
|
rgb_str = "200,200,200"
|
||||||
elif isAdvantageous and diff > 0 or (not isAdvantageous) and diff < 0:
|
elif is_advantageous and diff > 0 or (not is_advantageous) and diff < 0:
|
||||||
rgb_str = "180,0,0"
|
rgb_str = "180,0,0"
|
||||||
else:
|
else:
|
||||||
rgb_str = "0,150,0"
|
rgb_str = "0,150,0"
|
||||||
|
|
||||||
file.write(
|
file.write(
|
||||||
f"""<td><span style="color:rgb({rgb_str});">{cleverParse(diff)}</span></td>
|
f"""<td><span style="color:rgb({rgb_str});">{clever_parse(diff)}</span></td>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return isChanged
|
return is_changed
|
||||||
|
|
||||||
|
|
||||||
def computeUnitEfficiencyDiff(TemplatesByParent, Civs):
|
def compute_unit_efficiency_diff(templates_by_parent, civs):
|
||||||
efficiency_table = {}
|
efficiency_table = {}
|
||||||
for parent in TemplatesByParent:
|
for parent in templates_by_parent:
|
||||||
for template in [
|
for template in [
|
||||||
template for template in TemplatesByParent[parent] if template[1]["Civ"] not in Civs
|
template for template in templates_by_parent[parent] if template[1]["Civ"] not in civs
|
||||||
]:
|
]:
|
||||||
print(template)
|
print(template)
|
||||||
|
|
||||||
TemplatesByParent[parent] = [
|
templates_by_parent[parent] = [
|
||||||
template for template in TemplatesByParent[parent] if template[1]["Civ"] in Civs
|
template for template in templates_by_parent[parent] if template[1]["Civ"] in civs
|
||||||
]
|
]
|
||||||
TemplatesByParent[parent].sort(key=lambda x: Civs.index(x[1]["Civ"]))
|
templates_by_parent[parent].sort(key=lambda x: civs.index(x[1]["Civ"]))
|
||||||
|
|
||||||
for tp in TemplatesByParent[parent]:
|
for tp in templates_by_parent[parent]:
|
||||||
# HP
|
# HP
|
||||||
diff = -1j + (int(tp[1]["HP"]) - int(templates[parent]["HP"]))
|
diff = -1j + (int(tp[1]["HP"]) - int(templates[parent]["HP"]))
|
||||||
efficiency_table[(parent, tp[0], "HP")] = diff
|
efficiency_table[(parent, tp[0], "HP")] = diff
|
||||||
@ -436,7 +436,7 @@ def computeUnitEfficiencyDiff(TemplatesByParent, Civs):
|
|||||||
efficiency_table[(parent, tp[0], "WalkSpeed")] = diff
|
efficiency_table[(parent, tp[0], "WalkSpeed")] = diff
|
||||||
|
|
||||||
# Resistance
|
# Resistance
|
||||||
for atype in AttackTypes:
|
for atype in ATTACK_TYPES:
|
||||||
diff = -1j + (
|
diff = -1j + (
|
||||||
float(tp[1]["Resistance"][atype])
|
float(tp[1]["Resistance"][atype])
|
||||||
- float(templates[parent]["Resistance"][atype])
|
- float(templates[parent]["Resistance"][atype])
|
||||||
@ -444,35 +444,37 @@ def computeUnitEfficiencyDiff(TemplatesByParent, Civs):
|
|||||||
efficiency_table[(parent, tp[0], "Resistance/" + atype)] = diff
|
efficiency_table[(parent, tp[0], "Resistance/" + atype)] = diff
|
||||||
|
|
||||||
# Attack types (DPS) and rate.
|
# Attack types (DPS) and rate.
|
||||||
attType = "Ranged" if tp[1]["Ranged"] is True else "Melee"
|
att_type = "Ranged" if tp[1]["Ranged"] is True else "Melee"
|
||||||
if tp[1]["RepeatRate"][attType] != "0":
|
if tp[1]["RepeatRate"][att_type] != "0":
|
||||||
for atype in AttackTypes:
|
for atype in ATTACK_TYPES:
|
||||||
myDPS = float(tp[1]["Attack"][attType][atype]) / (
|
my_dps = float(tp[1]["Attack"][att_type][atype]) / (
|
||||||
float(tp[1]["RepeatRate"][attType]) / 1000.0
|
float(tp[1]["RepeatRate"][att_type]) / 1000.0
|
||||||
)
|
)
|
||||||
parentDPS = float(templates[parent]["Attack"][attType][atype]) / (
|
parent_dps = float(templates[parent]["Attack"][att_type][atype]) / (
|
||||||
float(templates[parent]["RepeatRate"][attType]) / 1000.0
|
float(templates[parent]["RepeatRate"][att_type]) / 1000.0
|
||||||
)
|
)
|
||||||
diff = -1j + (myDPS - parentDPS)
|
diff = -1j + (my_dps - parent_dps)
|
||||||
efficiency_table[(parent, tp[0], "Attack/" + attType + "/" + atype)] = diff
|
efficiency_table[(parent, tp[0], "Attack/" + att_type + "/" + atype)] = diff
|
||||||
diff = -1j + (
|
diff = -1j + (
|
||||||
float(tp[1]["RepeatRate"][attType]) / 1000.0
|
float(tp[1]["RepeatRate"][att_type]) / 1000.0
|
||||||
- float(templates[parent]["RepeatRate"][attType]) / 1000.0
|
- float(templates[parent]["RepeatRate"][att_type]) / 1000.0
|
||||||
)
|
)
|
||||||
efficiency_table[
|
efficiency_table[
|
||||||
(parent, tp[0], "Attack/" + attType + "/" + atype + "/RepeatRate")
|
(parent, tp[0], "Attack/" + att_type + "/" + atype + "/RepeatRate")
|
||||||
] = diff
|
] = diff
|
||||||
# range and spread
|
# range and spread
|
||||||
if tp[1]["Ranged"] is True:
|
if tp[1]["Ranged"] is True:
|
||||||
diff = -1j + (float(tp[1]["Range"]) - float(templates[parent]["Range"]))
|
diff = -1j + (float(tp[1]["Range"]) - float(templates[parent]["Range"]))
|
||||||
efficiency_table[(parent, tp[0], "Attack/" + attType + "/Ranged/Range")] = diff
|
efficiency_table[(parent, tp[0], "Attack/" + att_type + "/Ranged/Range")] = (
|
||||||
|
|
||||||
diff = float(tp[1]["Spread"]) - float(templates[parent]["Spread"])
|
|
||||||
efficiency_table[(parent, tp[0], "Attack/" + attType + "/Ranged/Spread")] = (
|
|
||||||
diff
|
diff
|
||||||
)
|
)
|
||||||
|
|
||||||
for rtype in Resources:
|
diff = float(tp[1]["Spread"]) - float(templates[parent]["Spread"])
|
||||||
|
efficiency_table[(parent, tp[0], "Attack/" + att_type + "/Ranged/Spread")] = (
|
||||||
|
diff
|
||||||
|
)
|
||||||
|
|
||||||
|
for rtype in RESOURCES:
|
||||||
diff = +1j + (
|
diff = +1j + (
|
||||||
float(tp[1]["Cost"][rtype]) - float(templates[parent]["Cost"][rtype])
|
float(tp[1]["Cost"][rtype]) - float(templates[parent]["Cost"][rtype])
|
||||||
)
|
)
|
||||||
@ -486,25 +488,25 @@ def computeUnitEfficiencyDiff(TemplatesByParent, Civs):
|
|||||||
return efficiency_table
|
return efficiency_table
|
||||||
|
|
||||||
|
|
||||||
def computeTemplates(LoadTemplatesIfParent):
|
def compute_templates(load_templates_if_parent):
|
||||||
"""Loops over template XMLs and selectively insert into templates dict."""
|
"""Loops over template XMLs and selectively insert into templates dict."""
|
||||||
pwd = os.getcwd()
|
pwd = os.getcwd()
|
||||||
os.chdir(basePath)
|
os.chdir(base_path)
|
||||||
templates = {}
|
templates = {}
|
||||||
for template in list(glob.glob("template_*.xml")):
|
for template in list(glob.glob("template_*.xml")):
|
||||||
if os.path.isfile(template):
|
if os.path.isfile(template):
|
||||||
found = False
|
found = False
|
||||||
for possParent in LoadTemplatesIfParent:
|
for poss_parent in load_templates_if_parent:
|
||||||
if hasParentTemplate(template, possParent):
|
if has_parent_template(template, poss_parent):
|
||||||
found = True
|
found = True
|
||||||
break
|
break
|
||||||
if found is True:
|
if found is True:
|
||||||
templates[template] = CalcUnit(template)
|
templates[template] = calc_unit(template)
|
||||||
os.chdir(pwd)
|
os.chdir(pwd)
|
||||||
return templates
|
return templates
|
||||||
|
|
||||||
|
|
||||||
def computeCivTemplates(Civs: list):
|
def compute_civ_templates(civs: list):
|
||||||
"""Load Civ specific templates.
|
"""Load Civ specific templates.
|
||||||
|
|
||||||
NOTE: whether a Civ can train a certain unit is not recorded in the unit
|
NOTE: whether a Civ can train a certain unit is not recorded in the unit
|
||||||
@ -518,87 +520,83 @@ def computeCivTemplates(Civs: list):
|
|||||||
up with the game engine.
|
up with the game engine.
|
||||||
"""
|
"""
|
||||||
pwd = os.getcwd()
|
pwd = os.getcwd()
|
||||||
os.chdir(basePath)
|
os.chdir(base_path)
|
||||||
|
|
||||||
CivTemplates = {}
|
civ_templates = {}
|
||||||
|
|
||||||
for Civ in Civs:
|
for civ in civs:
|
||||||
CivTemplates[Civ] = {}
|
civ_templates[civ] = {}
|
||||||
# Load all templates that start with that civ indicator
|
# Load all templates that start with that civ indicator
|
||||||
# TODO: consider adding mixin/civs here too
|
# TODO: consider adding mixin/civs here too
|
||||||
civ_list = list(glob.glob("units/" + Civ + "/*.xml"))
|
civ_list = list(glob.glob("units/" + civ + "/*.xml"))
|
||||||
for template in civ_list:
|
for template in civ_list:
|
||||||
if os.path.isfile(template):
|
if os.path.isfile(template):
|
||||||
# filter based on FilterOut
|
# filter based on FilterOut
|
||||||
breakIt = False
|
break_it = False
|
||||||
for civ_filter in FilterOut:
|
for civ_filter in FILTER_OUT:
|
||||||
if template.find(civ_filter) != -1:
|
if template.find(civ_filter) != -1:
|
||||||
breakIt = True
|
break_it = True
|
||||||
if breakIt:
|
if break_it:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# filter based on loaded generic templates
|
# filter based on loaded generic templates
|
||||||
breakIt = True
|
break_it = True
|
||||||
for possParent in LoadTemplatesIfParent:
|
for poss_parent in LOAD_TEMPLATES_IF_PARENT:
|
||||||
if hasParentTemplate(template, possParent):
|
if has_parent_template(template, poss_parent):
|
||||||
breakIt = False
|
break_it = False
|
||||||
break
|
break
|
||||||
if breakIt:
|
if break_it:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
unit = CalcUnit(template)
|
unit = calc_unit(template)
|
||||||
|
|
||||||
# Remove variants for now
|
# Remove variants for now
|
||||||
if unit["Parent"].find("template_") == -1:
|
if unit["Parent"].find("template_") == -1:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# load template
|
# load template
|
||||||
CivTemplates[Civ][template] = unit
|
civ_templates[civ][template] = unit
|
||||||
|
|
||||||
os.chdir(pwd)
|
os.chdir(pwd)
|
||||||
return CivTemplates
|
return civ_templates
|
||||||
|
|
||||||
|
|
||||||
def computeTemplatesByParent(templates: dict, Civs: list, CivTemplates: dict):
|
def compute_templates_by_parent(templates: dict, civs: list, civ_templates: dict):
|
||||||
"""Get them in the array."""
|
"""Get them in the array."""
|
||||||
# Civs:list -> CivTemplates:dict -> templates:dict -> TemplatesByParent
|
# civs:list -> civ_templates:dict -> templates:dict -> templates_by_parent
|
||||||
TemplatesByParent = {}
|
templates_by_parent = {}
|
||||||
for Civ in Civs:
|
for civ in civs:
|
||||||
for CivUnitTemplate in CivTemplates[Civ]:
|
for civ_unit_template in civ_templates[civ]:
|
||||||
parent = CivTemplates[Civ][CivUnitTemplate]["Parent"]
|
parent = civ_templates[civ][civ_unit_template]["Parent"]
|
||||||
|
|
||||||
# We have the following constant equality
|
# We have the following constant equality
|
||||||
# templates[*]["Civ"] === gaia
|
# templates[*]["Civ"] === gaia
|
||||||
# if parent in templates and templates[parent]["Civ"] == None:
|
# if parent in templates and templates[parent]["Civ"] == None:
|
||||||
if parent in templates:
|
if parent in templates:
|
||||||
if parent not in TemplatesByParent:
|
if parent not in templates_by_parent:
|
||||||
TemplatesByParent[parent] = []
|
templates_by_parent[parent] = []
|
||||||
TemplatesByParent[parent].append(
|
templates_by_parent[parent].append(
|
||||||
(CivUnitTemplate, CivTemplates[Civ][CivUnitTemplate])
|
(civ_unit_template, civ_templates[civ][civ_unit_template])
|
||||||
)
|
)
|
||||||
|
|
||||||
# debug after CivTemplates are non-empty
|
# debug after CivTemplates are non-empty
|
||||||
return TemplatesByParent
|
return templates_by_parent
|
||||||
|
|
||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
## Pre-compute all tables
|
## Pre-compute all tables
|
||||||
templates = computeTemplates(LoadTemplatesIfParent)
|
templates = compute_templates(LOAD_TEMPLATES_IF_PARENT)
|
||||||
CivTemplates = computeCivTemplates(Civs)
|
CivTemplates = compute_civ_templates(CIVS)
|
||||||
TemplatesByParent = computeTemplatesByParent(templates, Civs, CivTemplates)
|
TemplatesByParent = compute_templates_by_parent(templates, CIVS, CivTemplates)
|
||||||
|
|
||||||
# Not used; use it for your own custom analysis
|
# Not used; use it for your own custom analysis
|
||||||
efficiencyTable = computeUnitEfficiencyDiff(TemplatesByParent, Civs)
|
efficiency_table = compute_unit_efficiency_diff(TemplatesByParent, CIVS)
|
||||||
|
|
||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
def writeHTML():
|
def write_html():
|
||||||
"""Create the HTML file."""
|
"""Create the HTML file."""
|
||||||
f = open(
|
f = open(Path(__file__).parent / "unit_summary_table.html", "w", encoding="utf8")
|
||||||
os.path.realpath(__file__).replace("unitTables.py", "") + "unit_summary_table.html",
|
|
||||||
"w",
|
|
||||||
encoding="utf-8",
|
|
||||||
)
|
|
||||||
|
|
||||||
f.write(
|
f.write(
|
||||||
"""
|
"""
|
||||||
@ -639,7 +637,7 @@ def writeHTML():
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
for template in templates:
|
for template in templates:
|
||||||
f.write(WriteUnit(template, templates[template]))
|
f.write(write_unit(template, templates[template]))
|
||||||
f.write("</table>")
|
f.write("</table>")
|
||||||
|
|
||||||
# Write unit specialization
|
# Write unit specialization
|
||||||
@ -681,14 +679,10 @@ differences between the two.
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
for parent in TemplatesByParent:
|
for parent in TemplatesByParent:
|
||||||
TemplatesByParent[parent].sort(key=lambda x: Civs.index(x[1]["Civ"]))
|
TemplatesByParent[parent].sort(key=lambda x: CIVS.index(x[1]["Civ"]))
|
||||||
for tp in TemplatesByParent[parent]:
|
for tp in TemplatesByParent[parent]:
|
||||||
isChanged = False
|
is_changed = False
|
||||||
ff = open(
|
ff = open(Path(__file__).parent / ".cache", "w", encoding="utf8")
|
||||||
os.path.realpath(__file__).replace("unitTables.py", "") + ".cache",
|
|
||||||
"w",
|
|
||||||
encoding="utf-8",
|
|
||||||
)
|
|
||||||
|
|
||||||
ff.write("<tr>")
|
ff.write("<tr>")
|
||||||
ff.write(
|
ff.write(
|
||||||
@ -702,54 +696,56 @@ differences between the two.
|
|||||||
|
|
||||||
# HP
|
# HP
|
||||||
diff = -1j + (int(tp[1]["HP"]) - int(templates[parent]["HP"]))
|
diff = -1j + (int(tp[1]["HP"]) - int(templates[parent]["HP"]))
|
||||||
isChanged = WriteColouredDiff(ff, diff, isChanged)
|
is_changed = write_coloured_diff(ff, diff, is_changed)
|
||||||
|
|
||||||
# Build Time
|
# Build Time
|
||||||
diff = +1j + (int(tp[1]["BuildTime"]) - int(templates[parent]["BuildTime"]))
|
diff = +1j + (int(tp[1]["BuildTime"]) - int(templates[parent]["BuildTime"]))
|
||||||
isChanged = WriteColouredDiff(ff, diff, isChanged)
|
is_changed = write_coloured_diff(ff, diff, is_changed)
|
||||||
|
|
||||||
# walk speed
|
# walk speed
|
||||||
diff = -1j + (float(tp[1]["WalkSpeed"]) - float(templates[parent]["WalkSpeed"]))
|
diff = -1j + (float(tp[1]["WalkSpeed"]) - float(templates[parent]["WalkSpeed"]))
|
||||||
isChanged = WriteColouredDiff(ff, diff, isChanged)
|
is_changed = write_coloured_diff(ff, diff, is_changed)
|
||||||
|
|
||||||
# Resistance
|
# Resistance
|
||||||
for atype in AttackTypes:
|
for atype in ATTACK_TYPES:
|
||||||
diff = -1j + (
|
diff = -1j + (
|
||||||
float(tp[1]["Resistance"][atype])
|
float(tp[1]["Resistance"][atype])
|
||||||
- float(templates[parent]["Resistance"][atype])
|
- float(templates[parent]["Resistance"][atype])
|
||||||
)
|
)
|
||||||
isChanged = WriteColouredDiff(ff, diff, isChanged)
|
is_changed = write_coloured_diff(ff, diff, is_changed)
|
||||||
|
|
||||||
# Attack types (DPS) and rate.
|
# Attack types (DPS) and rate.
|
||||||
attType = "Ranged" if tp[1]["Ranged"] is True else "Melee"
|
att_type = "Ranged" if tp[1]["Ranged"] is True else "Melee"
|
||||||
if tp[1]["RepeatRate"][attType] != "0":
|
if tp[1]["RepeatRate"][att_type] != "0":
|
||||||
for atype in AttackTypes:
|
for atype in ATTACK_TYPES:
|
||||||
myDPS = float(tp[1]["Attack"][attType][atype]) / (
|
my_dps = float(tp[1]["Attack"][att_type][atype]) / (
|
||||||
float(tp[1]["RepeatRate"][attType]) / 1000.0
|
float(tp[1]["RepeatRate"][att_type]) / 1000.0
|
||||||
)
|
)
|
||||||
parentDPS = float(templates[parent]["Attack"][attType][atype]) / (
|
parent_dps = float(templates[parent]["Attack"][att_type][atype]) / (
|
||||||
float(templates[parent]["RepeatRate"][attType]) / 1000.0
|
float(templates[parent]["RepeatRate"][att_type]) / 1000.0
|
||||||
)
|
)
|
||||||
isChanged = WriteColouredDiff(ff, -1j + (myDPS - parentDPS), isChanged)
|
is_changed = write_coloured_diff(ff, -1j + (my_dps - parent_dps), is_changed)
|
||||||
isChanged = WriteColouredDiff(
|
is_changed = write_coloured_diff(
|
||||||
ff,
|
ff,
|
||||||
-1j
|
-1j
|
||||||
+ (
|
+ (
|
||||||
float(tp[1]["RepeatRate"][attType]) / 1000.0
|
float(tp[1]["RepeatRate"][att_type]) / 1000.0
|
||||||
- float(templates[parent]["RepeatRate"][attType]) / 1000.0
|
- float(templates[parent]["RepeatRate"][att_type]) / 1000.0
|
||||||
),
|
),
|
||||||
isChanged,
|
is_changed,
|
||||||
)
|
)
|
||||||
# range and spread
|
# range and spread
|
||||||
if tp[1]["Ranged"] is True:
|
if tp[1]["Ranged"] is True:
|
||||||
isChanged = WriteColouredDiff(
|
is_changed = write_coloured_diff(
|
||||||
ff,
|
ff,
|
||||||
-1j + (float(tp[1]["Range"]) - float(templates[parent]["Range"])),
|
-1j + (float(tp[1]["Range"]) - float(templates[parent]["Range"])),
|
||||||
isChanged,
|
is_changed,
|
||||||
|
)
|
||||||
|
my_spread = float(tp[1]["Spread"])
|
||||||
|
parent_spread = float(templates[parent]["Spread"])
|
||||||
|
is_changed = write_coloured_diff(
|
||||||
|
ff, +1j + (my_spread - parent_spread), is_changed
|
||||||
)
|
)
|
||||||
mySpread = float(tp[1]["Spread"])
|
|
||||||
parentSpread = float(templates[parent]["Spread"])
|
|
||||||
isChanged = WriteColouredDiff(ff, +1j + (mySpread - parentSpread), isChanged)
|
|
||||||
else:
|
else:
|
||||||
ff.write(
|
ff.write(
|
||||||
"<td><span style='color:rgb(200,200,200);'>-</span></td><td>"
|
"<td><span style='color:rgb(200,200,200);'>-</span></td><td>"
|
||||||
@ -758,39 +754,36 @@ differences between the two.
|
|||||||
else:
|
else:
|
||||||
ff.write("<td></td><td></td><td></td><td></td><td></td><td></td>")
|
ff.write("<td></td><td></td><td></td><td></td><td></td><td></td>")
|
||||||
|
|
||||||
for rtype in Resources:
|
for rtype in RESOURCES:
|
||||||
isChanged = WriteColouredDiff(
|
is_changed = write_coloured_diff(
|
||||||
ff,
|
ff,
|
||||||
+1j + (float(tp[1]["Cost"][rtype]) - float(templates[parent]["Cost"][rtype])),
|
+1j + (float(tp[1]["Cost"][rtype]) - float(templates[parent]["Cost"][rtype])),
|
||||||
isChanged,
|
is_changed,
|
||||||
)
|
)
|
||||||
|
|
||||||
isChanged = WriteColouredDiff(
|
is_changed = write_coloured_diff(
|
||||||
ff,
|
ff,
|
||||||
+1j
|
+1j
|
||||||
+ (
|
+ (
|
||||||
float(tp[1]["Cost"]["population"])
|
float(tp[1]["Cost"]["population"])
|
||||||
- float(templates[parent]["Cost"]["population"])
|
- float(templates[parent]["Cost"]["population"])
|
||||||
),
|
),
|
||||||
isChanged,
|
is_changed,
|
||||||
)
|
)
|
||||||
|
|
||||||
ff.write("<td>" + tp[1]["Civ"] + "</td>")
|
ff.write("<td>" + tp[1]["Civ"] + "</td>")
|
||||||
ff.write("</tr>\n")
|
ff.write("</tr>\n")
|
||||||
|
|
||||||
ff.close() # to actually write into the file
|
ff.close() # to actually write into the file
|
||||||
with open(
|
with open(Path(__file__).parent / ".cache", encoding="utf-8") as ff:
|
||||||
os.path.realpath(__file__).replace("unitTables.py", "") + ".cache",
|
unit_str = ff.read()
|
||||||
encoding="utf-8",
|
|
||||||
) as ff:
|
|
||||||
unitStr = ff.read()
|
|
||||||
|
|
||||||
if showChangedOnly:
|
if SHOW_CHANGED_ONLY:
|
||||||
if isChanged:
|
if is_changed:
|
||||||
f.write(unitStr)
|
f.write(unit_str)
|
||||||
else:
|
else:
|
||||||
# print the full table if showChangedOnly is false
|
# print the full table if SHOW_CHANGED_ONLY is false
|
||||||
f.write(unitStr)
|
f.write(unit_str)
|
||||||
|
|
||||||
f.write("<table/>")
|
f.write("<table/>")
|
||||||
|
|
||||||
@ -813,17 +806,17 @@ each loaded generic template.
|
|||||||
<th>Template </th>
|
<th>Template </th>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
for civ in Civs:
|
for civ in CIVS:
|
||||||
f.write('<td class="vertical-text">' + civ + "</td>\n")
|
f.write('<td class="vertical-text">' + civ + "</td>\n")
|
||||||
f.write("</tr>\n")
|
f.write("</tr>\n")
|
||||||
|
|
||||||
sortedDict = sorted(templates.items(), key=SortFn)
|
sorted_dict = sorted(templates.items(), key=sort_fn)
|
||||||
|
|
||||||
for tp in sortedDict:
|
for tp in sorted_dict:
|
||||||
if tp[0] not in TemplatesByParent:
|
if tp[0] not in TemplatesByParent:
|
||||||
continue
|
continue
|
||||||
f.write("<tr><td>" + tp[0] + "</td>\n")
|
f.write("<tr><td>" + tp[0] + "</td>\n")
|
||||||
for civ in Civs:
|
for civ in CIVS:
|
||||||
found = 0
|
found = 0
|
||||||
for temp in TemplatesByParent[tp[0]]:
|
for temp in TemplatesByParent[tp[0]]:
|
||||||
if temp[1]["Civ"] == civ:
|
if temp[1]["Civ"] == civ:
|
||||||
@ -841,7 +834,7 @@ each loaded generic template.
|
|||||||
'<tr style="margin-top:2px;border-top:2px #aaa solid;">\
|
'<tr style="margin-top:2px;border-top:2px #aaa solid;">\
|
||||||
<th style="text-align:right; padding-right:10px;">Total:</th>\n'
|
<th style="text-align:right; padding-right:10px;">Total:</th>\n'
|
||||||
)
|
)
|
||||||
for civ in Civs:
|
for civ in CIVS:
|
||||||
count = 0
|
count = 0
|
||||||
for _units in CivTemplates[civ]:
|
for _units in CivTemplates[civ]:
|
||||||
count += 1
|
count += 1
|
||||||
@ -853,7 +846,7 @@ each loaded generic template.
|
|||||||
|
|
||||||
# Add a simple script to allow filtering on sorting directly in the HTML
|
# Add a simple script to allow filtering on sorting directly in the HTML
|
||||||
# page.
|
# page.
|
||||||
if AddSortingOverlay:
|
if ADD_SORTING_OVERLAY:
|
||||||
f.write(
|
f.write(
|
||||||
"""
|
"""
|
||||||
<script src="tablefilter/tablefilter.js"></script>
|
<script src="tablefilter/tablefilter.js"></script>
|
||||||
@ -941,4 +934,4 @@ tf2.init();
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
writeHTML()
|
write_html()
|
Loading…
Reference in New Issue
Block a user