Skip to content

Commit

Permalink
tooltip and more (#94)
Browse files Browse the repository at this point in the history
* restore button

* fix arrow buttons

* status labels

* tooltip

* tooltip

* tooltip

* tooltip

* tooltip

* tooltip

* cleanup

* use font

* use font

* dialog help message

* move unit fix

* move unit fix

* move unit fix

* clippy

* fix capture

* move units without dialog

* move units without dialog

* move units without dialog

* unit tooltip

* unit tooltip

* unit tooltip

* icon

* unit tooltip

* let chain

* cleanup

* cleanup

* cleanup
  • Loading branch information
zeitlinger authored Jan 1, 2025
1 parent 5ebbc7d commit bd11ecb
Show file tree
Hide file tree
Showing 17 changed files with 520 additions and 283 deletions.
8 changes: 4 additions & 4 deletions client/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added client/assets/restore-svgrepo-com.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/assets/route-start-svgrepo-com.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed client/assets/walk-svgrepo-com.png
Binary file not shown.
24 changes: 14 additions & 10 deletions client/src/assets.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::client::Features;
use crate::resource_ui::ResourceType;
use macroquad::prelude::{load_texture, load_ttf_font, Color, Image, ImageFormat, RectOffset};
use macroquad::prelude::{
load_texture, load_ttf_font, Color, Font, Image, ImageFormat, RectOffset,
};
use macroquad::texture::Texture2D;
use macroquad::ui::{root_ui, Skin};
use server::map::Terrain;
Expand All @@ -11,6 +13,7 @@ pub struct Assets {
pub terrain: HashMap<Terrain, Texture2D>,
pub units: HashMap<UnitType, Texture2D>,
pub skin: Skin,
pub font: Font,

// mood icons
pub angry: Texture2D,
Expand All @@ -35,6 +38,7 @@ pub struct Assets {
pub right: Texture2D,
pub victory_points: Texture2D,
pub active_player: Texture2D,
pub restore_menu: Texture2D,

// Admin
pub import: Texture2D,
Expand All @@ -47,10 +51,12 @@ pub struct Assets {
impl Assets {
pub async fn new(features: &Features) -> Self {
let happy = load_png(include_bytes!("../assets/happy-emoji-svgrepo-com.png"));
let font_name = features.get_asset("HTOWERT.TTF");
Self {
font: load_ttf_font(&font_name).await.unwrap(), // can't share font - causes panic
terrain: Self::terrain(features).await,
units: HashMap::new(),
skin: Self::skin(features).await,
skin: Self::skin(&load_ttf_font(&font_name).await.unwrap()),

// mood icons
angry: load_png(include_bytes!("../assets/angry-face-svgrepo-com.png")),
Expand Down Expand Up @@ -93,7 +99,7 @@ impl Assets {
advances: load_png(include_bytes!("../assets/lab-svgrepo-com.png")),
end_turn: load_png(include_bytes!("../assets/hour-glass-svgrepo-com.png")),
log: load_png(include_bytes!("../assets/scroll-svgrepo-com.png")),
movement: load_png(include_bytes!("../assets/walk-svgrepo-com.png")),
movement: load_png(include_bytes!("../assets/route-start-svgrepo-com.png")),
redo: load_png(include_bytes!("../assets/redo-svgrepo-com.png")),
reset: load_png(include_bytes!("../assets/reset-svgrepo-com.png")),
undo: load_png(include_bytes!("../assets/undo-svgrepo-com.png")),
Expand All @@ -113,6 +119,7 @@ impl Assets {
)),
victory_points: load_png(include_bytes!("../assets/trophy-cup-svgrepo-com.png")),
active_player: load_png(include_bytes!("../assets/triangle-svgrepo-com.png")),
restore_menu: load_png(include_bytes!("../assets/restore-svgrepo-com.png")),

// Admin
import: load_png(include_bytes!("../assets/import-3-svgrepo-com.png")),
Expand All @@ -136,10 +143,7 @@ impl Assets {
map
}

async fn skin(features: &Features) -> Skin {
let font = load_ttf_font(&features.get_asset("HTOWERT.TTF"))
.await
.unwrap();
fn skin(font: &Font) -> Skin {
let image =
Image::from_file_with_format(include_bytes!("../assets/button_background.png"), None)
.unwrap();
Expand All @@ -148,7 +152,7 @@ impl Assets {
.background(image.clone())
.background_margin(RectOffset::new(37.0, 37.0, 5.0, 5.0))
.margin(RectOffset::new(10.0, 10.0, 0.0, 0.0))
.with_font(&font)
.with_font(font)
.unwrap()
.text_color(Color::from_rgba(180, 180, 120, 255))
.font_size(20)
Expand Down Expand Up @@ -186,7 +190,7 @@ impl Assets {
)
.unwrap(),
)
.with_font(&font)
.with_font(font)
.unwrap()
.text_color(Color::from_rgba(180, 180, 100, 255))
.font_size(20)
Expand All @@ -195,7 +199,7 @@ impl Assets {
let editbox_style = root_ui()
.style_builder()
.background_margin(RectOffset::new(0., 0., 0., 0.))
.with_font(&font)
.with_font(font)
.unwrap()
.text_color(Color::from_rgba(120, 120, 120, 255))
.color_selected(Color::from_rgba(190, 190, 190, 255))
Expand Down
26 changes: 11 additions & 15 deletions client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ use crate::log_ui::show_log;
use crate::map_ui::{draw_map, show_tile_menu};
use crate::player_ui::{player_select, show_global_controls, show_top_center, show_top_left};
use crate::status_phase_ui::raze_city_confirm_dialog;
use crate::{combat_ui, dialog_ui, influence_ui, move_ui, recruit_unit_ui, status_phase_ui};
use crate::{
combat_ui, dialog_ui, influence_ui, move_ui, recruit_unit_ui, status_phase_ui, tooltip,
};

pub async fn init(features: &Features) -> State {
let state = State::new(features).await;
Expand Down Expand Up @@ -47,6 +49,8 @@ pub fn render_and_update(
}

fn render(game: &Game, state: &mut State, features: &Features) -> StateUpdate {
tooltip::update(state);

clear_background(WHITE);

let player = &state.shown_player(game);
Expand All @@ -58,19 +62,13 @@ fn render(game: &Game, state: &mut State, features: &Features) -> StateUpdate {
offset: state.offset,
..Default::default()
};
set_camera(&state.camera);

if matches!(state.active_dialog, ActiveDialog::None) || state.active_dialog.is_map_dialog() {
draw_map(game, state);
}
draw_map(game, state);
let mut updates = StateUpdates::new();
show_top_left(game, player);
show_top_left(game, player, state);
show_top_center(game, player, state);
updates.add(player_select(game, player, state));
updates.add(show_global_controls(game, state, features));
if !matches!(state.active_dialog, ActiveDialog::None) || state.active_dialog.is_map_dialog() {
updates.clear();
}

if player.can_control {
if let Some(u) = &state.pending_update {
Expand All @@ -80,7 +78,7 @@ fn render(game: &Game, state: &mut State, features: &Features) -> StateUpdate {
}

updates.add(match &state.active_dialog {
ActiveDialog::None => StateUpdate::None,
ActiveDialog::None | ActiveDialog::MoveUnits(_) => StateUpdate::None,
ActiveDialog::Log => show_log(game, player),
ActiveDialog::TileMenu(p) => show_tile_menu(game, *p, player),
ActiveDialog::WaitingForUpdate => {
Expand All @@ -95,7 +93,6 @@ fn render(game: &Game, state: &mut State, features: &Features) -> StateUpdate {
ActiveDialog::CollectResources(c) => collect_resources_dialog(game, c, player),
ActiveDialog::RecruitUnitSelection(s) => recruit_unit_ui::select_dialog(game, s, player),
ActiveDialog::ReplaceUnits(r) => recruit_unit_ui::replace_dialog(game, r, player),
ActiveDialog::MoveUnits(s) => move_ui::move_units_dialog(game, s, player),
ActiveDialog::CulturalInfluenceResolution(c) => {
influence_ui::cultural_influence_resolution_dialog(c, player)
}
Expand Down Expand Up @@ -131,16 +128,15 @@ pub fn try_click(game: &Game, state: &State, player: &ShownPlayer) -> StateUpdat
return StateUpdate::None;
}
let (x, y) = mouse_position();
let pos = Position::from_coordinate(pixel_to_coordinate(
state.camera.screen_to_world(vec2(x, y)),
));
let mouse_pos = state.camera.screen_to_world(vec2(x, y));
let pos = Position::from_coordinate(pixel_to_coordinate(mouse_pos));
if !game.map.tiles.contains_key(&pos) {
return StateUpdate::None;
}

if player.can_control {
match &state.active_dialog {
ActiveDialog::MoveUnits(s) => move_ui::click(pos, s),
ActiveDialog::MoveUnits(s) => move_ui::click(pos, s, mouse_pos, game),
ActiveDialog::ReplaceUnits(r) => recruit_unit_ui::click_replace(pos, r),
ActiveDialog::RemoveCasualties(_s) => StateUpdate::None,
ActiveDialog::CollectResources(col) => click_collect_option(col, pos),
Expand Down
84 changes: 79 additions & 5 deletions client/src/client_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::collect_ui::CollectResources;
use crate::combat_ui::RemoveCasualtiesSelection;
use crate::construct_ui::ConstructionPayment;
use crate::happiness_ui::IncreaseHappiness;
use crate::layout_ui::FONT_SIZE;
use crate::move_ui::MoveSelection;
use crate::recruit_unit_ui::{RecruitAmount, RecruitSelection};
use crate::status_phase_ui::ChooseAdditionalAdvances;
Expand Down Expand Up @@ -81,6 +82,45 @@ impl ActiveDialog {
}
}

#[must_use]
pub fn help_message(&self) -> Option<&str> {
match self {
ActiveDialog::None => None,
ActiveDialog::TileMenu(_) => Some("Click on a tile to see options"),
ActiveDialog::Log => Some("Click on a log entry to see details"),
ActiveDialog::IncreaseHappiness(_) => Some("Click on a city to increase happiness"),
ActiveDialog::AdvanceMenu => Some("Click on an advance to see options"),
ActiveDialog::AdvancePayment(_) => Some("Click on an advance to pay"),
ActiveDialog::ConstructionPayment(_) => Some("Click on a city to pay for construction"),
ActiveDialog::CollectResources(_) => Some("Click on a city to collect resources"),
ActiveDialog::RecruitUnitSelection(_) => Some("Click on a unit to recruit"),
ActiveDialog::ReplaceUnits(_) => Some("Click on a unit to replace"),
ActiveDialog::MoveUnits(m) => {
if m.start.is_some() {
Some("Click on a highlighted tile to move units")
} else {
Some("Click on a unit to move")
}
}
ActiveDialog::CulturalInfluenceResolution(_) => {
Some("Click on a city to resolve cultural influence")
}
ActiveDialog::FreeAdvance => Some("Click on an advance to take it for free"),
ActiveDialog::RazeSize1City => Some("Click on a city to raze it"),
ActiveDialog::CompleteObjectives => Some("Click on an objective to complete it"),
ActiveDialog::DetermineFirstPlayer => {
Some("Click on a player to determine first player")
}
ActiveDialog::ChangeGovernmentType => Some("Click on a government type to change"),
ActiveDialog::ChooseAdditionalAdvances(_) => Some("Click on an advance to choose it"),
ActiveDialog::PlayActionCard => Some("Click on an action card to play it"),
ActiveDialog::PlaceSettler => Some("Click on a tile to place a settler"),
ActiveDialog::Retreat => Some("Click on a unit to retreat"),
ActiveDialog::RemoveCasualties(_) => Some("Click on a unit to remove it"),
ActiveDialog::WaitingForUpdate => panic!("no help message for dialog"),
}
}

#[must_use]
pub fn is_map_dialog(&self) -> bool {
matches!(
Expand All @@ -93,6 +133,14 @@ impl ActiveDialog {
| ActiveDialog::RazeSize1City
)
}

#[must_use]
pub fn can_restore(&self) -> bool {
!matches!(
self,
ActiveDialog::MoveUnits(_) | ActiveDialog::ReplaceUnits(_) | ActiveDialog::None
)
}
}

pub struct PendingUpdate {
Expand Down Expand Up @@ -206,10 +254,6 @@ impl StateUpdates {
}
}

pub fn clear(&mut self) {
self.updates.clear();
}

pub fn result(self) -> StateUpdate {
self.updates
.into_iter()
Expand All @@ -235,6 +279,11 @@ impl ShownPlayer {
}
}

pub struct MousePosition {
pub position: Vec2,
pub time: f64,
}

pub struct State {
pub assets: Assets,
pub control_player: Option<usize>,
Expand All @@ -245,6 +294,7 @@ pub struct State {
pub zoom: f32,
pub offset: Vec2,
pub screen_size: Vec2,
pub mouse_positions: Vec<MousePosition>,
}

pub const ZOOM: f32 = 0.001;
Expand All @@ -264,6 +314,7 @@ impl State {
zoom: ZOOM,
offset: OFFSET,
screen_size: vec2(0., 0.),
mouse_positions: vec![],
}
}

Expand Down Expand Up @@ -354,7 +405,11 @@ impl State {
}

fn close_dialog(&mut self) {
self.active_dialog = ActiveDialog::None;
if self.active_dialog.can_restore() {
self.active_dialog = ActiveDialog::None;
} else if let ActiveDialog::ReplaceUnits(r) = &mut self.active_dialog {
r.clear();
}
}

pub fn update_from_game(&mut self, game: &Game) -> GameSyncRequest {
Expand Down Expand Up @@ -415,6 +470,25 @@ impl State {
}
}

#[must_use]
pub fn measure_text(&self, text: &str) -> TextDimensions {
measure_text(text, Some(&self.assets.font), FONT_SIZE, 1.0)
}

pub fn draw_text(&self, text: &str, x: f32, y: f32) {
draw_text_ex(
text,
x,
y,
TextParams {
font: Some(&self.assets.font),
font_size: FONT_SIZE,
color: BLACK,
..Default::default()
},
);
}

// fn execute_status_phase(&mut self, game: &Game, action: StatusPhaseAction) -> ActiveDialog {
// self.update(game, StateUpdate::status_phase(action));
// ActiveDialog::None
Expand Down
Loading

0 comments on commit bd11ecb

Please sign in to comment.