New screenshots; fit long button labels, no HUD behind the title's match page
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c7c3e979d6
commit
88061a8628
6 files changed
+36
-3
No files matched your search
@@ -128,6 +128,20 @@ caves, rival masters, and me, telling you the story. With tea.
|
|||||||
campaigns. *Open the demo* in the editor shows every trigger at work. Details: [docs/CAMPAIGN_EDITOR.md](docs/CAMPAIGN_EDITOR.md),
|
campaigns. *Open the demo* in the editor shows every trigger at work. Details: [docs/CAMPAIGN_EDITOR.md](docs/CAMPAIGN_EDITOR.md),
|
||||||
[docs/MISSION_SCRIPTING.md](docs/MISSION_SCRIPTING.md).
|
[docs/MISSION_SCRIPTING.md](docs/MISSION_SCRIPTING.md).
|
||||||
|
|
||||||
|
## Together
|
||||||
|
|
||||||
|
- **Versus** for 2-4 masters, with teams, gold for allies and fallen masters watching the rest of the match.
|
||||||
|
- **Co-op**: the 20-mission campaign *League against the Lightwatch*, the built-in missions or any editor campaign,
|
||||||
|
each master with an own dungeon; empty seats are played by the AI. Hero waves march on the strongest master.
|
||||||
|
- **Offline with an AI partner**: every co-op mission also runs without the server - the partner builds his own
|
||||||
|
dungeon, follows your attack flag and helps out with gold. Interrupted runs go on with *Continue*.
|
||||||
|
Details: [docs/MULTIPLAYER.md](docs/MULTIPLAYER.md).
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="docs/screenshots/coop-league.png" width="400" alt="The Match page with the co-op league and the AI partner">
|
||||||
|
<img src="docs/screenshots/languages.png" width="400" alt="The language dropdown with pixel flags for 18 languages">
|
||||||
|
</p>
|
||||||
|
|
||||||
## Meet the household
|
## Meet the household
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 685 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 853 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 966 KiB After Width: | Height: | Size: 945 KiB |
@@ -1894,6 +1894,7 @@ app.pending_briefing = briefing_of(&campaign, i);
|
|||||||
| Some(Page::Login)
|
| Some(Page::Login)
|
||||||
| Some(Page::Account)
|
| Some(Page::Account)
|
||||||
| Some(Page::Bestiary { from_title: true, .. })
|
| Some(Page::Bestiary { from_title: true, .. })
|
||||||
|
| Some(Page::Match { from_title: true })
|
||||||
);
|
);
|
||||||
music.update(&app.game, on_title, (app.cam.rx, app.cam.rz));
|
music.update(&app.game, on_title, (app.cam.rx, app.cam.rz));
|
||||||
for m in app.game.msgs.drain(..) {
|
for m in app.game.msgs.drain(..) {
|
||||||
@@ -1973,6 +1974,7 @@ fn draw_frame(app: &mut App, gfx: &Gfx, r3d: &mut R3d, ui: &mut Ui, menu: &mut M
|
|||||||
| Some(Page::Login)
|
| Some(Page::Login)
|
||||||
| Some(Page::Account)
|
| Some(Page::Account)
|
||||||
| Some(Page::Bestiary { from_title: true, .. })
|
| Some(Page::Bestiary { from_title: true, .. })
|
||||||
|
| Some(Page::Match { from_title: true })
|
||||||
);
|
);
|
||||||
if !title_screen {
|
if !title_screen {
|
||||||
let info = if over_ui || (touch && inp.inspect.is_none()) {
|
let info = if over_ui || (touch && inp.inspect.is_none()) {
|
||||||
|
|||||||
+20
-3
@@ -451,8 +451,24 @@ pub struct Menu {
|
|||||||
fn button(gfx: &Gfx, r: Rect, label: &str, hot: bool, accent: Color) {
|
fn button(gfx: &Gfx, r: Rect, label: &str, hot: bool, accent: Color) {
|
||||||
draw_rectangle(r.x, r.y, r.w, r.h, if hot { Color::new(0.35, 0.22, 0.1, 1.0) } else { Color::new(0.13, 0.09, 0.08, 1.0) });
|
draw_rectangle(r.x, r.y, r.w, r.h, if hot { Color::new(0.35, 0.22, 0.1, 1.0) } else { Color::new(0.13, 0.09, 0.08, 1.0) });
|
||||||
draw_rectangle_lines(r.x, r.y, r.w, r.h, 2.0, if hot { FRAME_HI } else { accent });
|
draw_rectangle_lines(r.x, r.y, r.w, r.h, 2.0, if hot { FRAME_HI } else { accent });
|
||||||
let s = S();
|
// a label too wide for the button gets the small font, and is cut short if that is not enough
|
||||||
gfx.text(label, r.x + (r.w - gfx.measure(label, s)) * 0.5, r.y + (r.h - GH * s) * 0.5, s, if hot { FRAME_HI } else { TXT });
|
let mut s = S();
|
||||||
|
let room = r.w - 8.0;
|
||||||
|
let mut text = label.to_string();
|
||||||
|
if gfx.measure(&text, s) > room {
|
||||||
|
s = SMALL();
|
||||||
|
while gfx.measure(&text, s) > room && text.chars().count() > 2 {
|
||||||
|
text.pop();
|
||||||
|
while text.ends_with(' ') {
|
||||||
|
text.pop();
|
||||||
|
}
|
||||||
|
if gfx.measure(&format!("{text}…"), s) <= room {
|
||||||
|
text.push('…');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gfx.text(&text, r.x + (r.w - gfx.measure(&text, s)) * 0.5, r.y + (r.h - GH * s) * 0.5, s, if hot { FRAME_HI } else { TXT });
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Menu {
|
impl Menu {
|
||||||
@@ -2034,7 +2050,8 @@ impl Menu {
|
|||||||
items.push((Btn::MatchLeave, tr("net.leave")));
|
items.push((Btn::MatchLeave, tr("net.leave")));
|
||||||
}
|
}
|
||||||
items.push((Btn::Back, tr("menu.back")));
|
items.push((Btn::Back, tr("menu.back")));
|
||||||
let bw = 14.0 * CW();
|
// three buttons a row over the whole width
|
||||||
|
let bw = ((w - 2.0 * CW()) / 3.0).max(14.0 * CW());
|
||||||
let shown = items.iter().take(9).count();
|
let shown = items.iter().take(9).count();
|
||||||
for (k, (b, label)) in items.iter().take(shown).enumerate() {
|
for (k, (b, label)) in items.iter().take(shown).enumerate() {
|
||||||
let r = Rect::new(ix + (k % 3) as f32 * (bw + CW()), yy + (k / 3) as f32 * CH() * 2.4, bw, CH() * 2.0);
|
let r = Rect::new(ix + (k % 3) as f32 * (bw + CW()), yy + (k / 3) as f32 * CH() * 2.4, bw, CH() * 2.0);
|
||||||
|
|||||||
Reference in new issue
Block a user