+
Weight
{{ card.weight_display }}
- {% for t in card.weight_star_types %}
+ {% for t in card.weight_star_types_adj|default:card.weight_star_types %}
{% if t == 'empty' %}☆{% else %}★{% endif %}
{% endfor %}
-
+
Intelligence
{{ card.intelligence_display }}
- {% for t in card.intelligence_star_types %}
+ {% for t in card.intelligence_star_types_adj|default:card.intelligence_star_types %}
{% if t == 'empty' %}☆{% else %}★{% endif %}
{% endfor %}
-
+
Height
{{ card.height_display }}
- {% for t in card.height_star_types %}
+ {% for t in card.height_star_types_adj|default:card.height_star_types %}
{% if t == 'empty' %}☆{% else %}★{% endif %}
{% endfor %}
diff --git a/cards/templates/cards/_card_item.html b/cards/templates/cards/_card_item.html
index bb1154b..4f26ddb 100644
--- a/cards/templates/cards/_card_item.html
+++ b/cards/templates/cards/_card_item.html
@@ -34,7 +34,7 @@
{{ card.speed_display }}
-
{% for t in card.speed_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
+
{% for t in card.speed_star_types_adj|default:card.speed_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.speed_orig }})
@@ -44,7 +44,7 @@
{{ card.weight_display }}
-
{% for t in card.weight_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
+
{% for t in card.weight_star_types_adj|default:card.weight_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.weight_orig }})
@@ -53,7 +53,7 @@
Intelligence (score)
-
{% for t in card.intelligence_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
+
{% for t in card.intelligence_star_types_adj|default:card.intelligence_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.intelligence_orig }})
diff --git a/cards/templates/cards/_card_preview.html b/cards/templates/cards/_card_preview.html
index 06e55b1..7c6e442 100644
--- a/cards/templates/cards/_card_preview.html
+++ b/cards/templates/cards/_card_preview.html
@@ -41,20 +41,20 @@
Speed (km/h)
{{ card.speed_display }}
-
{% for t in card.speed_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.speed_orig }})
+
{% for t in card.speed_star_types_adj|default:card.speed_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.speed_orig }})
Weight (kg)
{{ card.weight_display }}
-
{% for t in card.weight_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.weight_orig }})
+
{% for t in card.weight_star_types_adj|default:card.weight_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.weight_orig }})
Intelligence (score)
-
{% for t in card.intelligence_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
+
{% for t in card.intelligence_star_types_adj|default:card.intelligence_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.intelligence_orig }})
@@ -62,7 +62,7 @@
Height (m)
{{ card.height_display }}
-
{% for t in card.height_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.height_orig }})
+
{% for t in card.height_star_types_adj|default:card.height_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.height_orig }})
diff --git a/cards/templates/cards/_card_stats_rows.html b/cards/templates/cards/_card_stats_rows.html
index 8bf31eb..e4cec92 100644
--- a/cards/templates/cards/_card_stats_rows.html
+++ b/cards/templates/cards/_card_stats_rows.html
@@ -3,28 +3,28 @@
Speed (km/h)
{{ card.speed_display }}
-
{% for t in card.speed_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.speed_orig }})
+
{% for t in card.speed_star_types_adj|default:card.speed_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.speed_orig }})
Weight (kg)
{{ card.weight_display }}
-
{% for t in card.weight_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.weight_orig }})
+
{% for t in card.weight_star_types_adj|default:card.weight_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.weight_orig }})
Intelligence (score)
{{ card.intelligence_display }}
-
{% for t in card.intelligence_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.intelligence_orig }})
+
{% for t in card.intelligence_star_types_adj|default:card.intelligence_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.intelligence_orig }})
Height (m)
{{ card.height_display }}
-
{% for t in card.height_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.height_orig }})
+
{% for t in card.height_star_types_adj|default:card.height_star_types %}{% if t == 'full' %}★{% else %}☆{% endif %}{% endfor %}
(orig: {{ card.height_orig }})
diff --git a/cards/views.py b/cards/views.py
index 4f10f61..8cbaa48 100644
--- a/cards/views.py
+++ b/cards/views.py
@@ -460,17 +460,100 @@ def print_preview(request):
# For each card compute its best stat percent (0-100) and the stat(s)
# that achieve that percent. Then find the global maximum best-value and
# mark any card whose best-value equals that maximum as a top-trump.
+ # Compute selection maxima for speed/weight/height/intelligence so we
+ # can scale these metrics relative to the selected cards. This prevents
+ # many large absolute values from all clamping to 100% and getting 5★.
+ max_speed = 0.0
+ max_weight = 0.0
+ max_height = 0.0
+ max_intel = 0.0
+ for c in ordered:
+ try:
+ sv = float(c.speed or 0)
+ except Exception:
+ sv = 0.0
+ try:
+ wv = float(c.weight or 0)
+ except Exception:
+ wv = 0.0
+ try:
+ hv = float(c.height or 0)
+ except Exception:
+ hv = 0.0
+ try:
+ iv = float(c.intelligence or 0)
+ except Exception:
+ iv = 0.0
+ if sv > max_speed:
+ max_speed = sv
+ if wv > max_weight:
+ max_weight = wv
+ if hv > max_height:
+ max_height = hv
+ if iv > max_intel:
+ max_intel = iv
+
all_best_values = []
for c in ordered:
- # compute percents using model helpers
- s = c.speed_percent()
- w = c.weight_percent()
- it = c.intelligence_percent()
- h = c.height_percent()
- # map names to values
+ # raw values
+ try:
+ raw_s = float(c.speed or 0)
+ except Exception:
+ raw_s = 0.0
+ try:
+ raw_w = float(c.weight or 0)
+ except Exception:
+ raw_w = 0.0
+ try:
+ raw_h = float(c.height or 0)
+ except Exception:
+ raw_h = 0.0
+ try:
+ raw_it = float(c.intelligence or 0)
+ except Exception:
+ raw_it = 0.0
+
+ # Compute selection-relative percents so the largest in the
+ # selection maps to 100% for each metric.
+ if max_speed > 0:
+ s = min(100, int(round((raw_s / max_speed) * 100)))
+ else:
+ s = 0
+ if max_weight > 0:
+ w = min(100, int(round((raw_w / max_weight) * 100)))
+ else:
+ w = 0
+ if max_height > 0:
+ h = min(100, int(round((raw_h / max_height) * 100)))
+ else:
+ h = 0
+ if max_intel > 0:
+ it = min(100, int(round((raw_it / max_intel) * 100)))
+ else:
+ it = 0
+
+ # Attach adjusted star visuals for the printable preview so
+ # templates reflect selection-relative scaling. These instance
+ # attributes shadow the class properties during template rendering.
+ setattr(c, 'speed_star_types_adj', c._star_types_from_percent(s))
+ setattr(c, 'speed_stars_adj', c._stars_string(s))
+ setattr(c, 'weight_star_types_adj', c._star_types_from_percent(w))
+ setattr(c, 'weight_stars_adj', c._stars_string(w))
+ setattr(c, 'height_star_types_adj', c._star_types_from_percent(h))
+ setattr(c, 'height_stars_adj', c._stars_string(h))
+ setattr(c, 'intelligence_star_types_adj', c._star_types_from_percent(it))
+ setattr(c, 'intelligence_stars_adj', c._stars_string(it))
+
+ setattr(c, 'speed_percent_adj', s)
+ setattr(c, 'weight_percent_adj', w)
+ setattr(c, 'height_percent_adj', h)
+ setattr(c, 'intelligence_percent_adj', it)
+
+ # map names to values (independent stats) using adjusted percents
stats = {'speed': s, 'weight': w, 'intelligence': it, 'height': h}
max_val = max(stats.values())
best_stats = [name for name, val in stats.items() if val == max_val]
+
# attach computed attributes so templates can read them
setattr(c, 'best_value', max_val)
setattr(c, 'best_stats', best_stats)