Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Camera #66

Merged
merged 6 commits into from
Oct 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions client/src/advance_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use server::resource_pile::AdvancePaymentOptions;
use server::status_phase::{StatusPhaseAction, StatusPhaseState};

use crate::client_state::{ActiveDialog, ShownPlayer, StateUpdate};
use crate::dialog_ui::full_dialog;
use crate::dialog_ui::dialog;
use crate::payment_ui::{payment_dialog, HasPayment, Payment, ResourcePayment};
use crate::resource_ui::{new_resource_map, ResourceType};
use crate::select_ui::HasCountSelectableObject;
Expand Down Expand Up @@ -101,7 +101,7 @@ pub fn show_generic_advance_menu(
player: &ShownPlayer,
new_update: impl Fn(&str) -> StateUpdate,
) -> StateUpdate {
full_dialog(title, |ui| {
dialog(player, title, |ui| {
let p = player.get(game);
let mut update = StateUpdate::None;
let mut current_group = None;
Expand Down
59 changes: 19 additions & 40 deletions client/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use macroquad::input::{is_mouse_button_pressed, mouse_position, MouseButton};
use macroquad::prelude::{clear_background, vec2, WHITE};
use macroquad::ui::root_ui;
use macroquad::prelude::*;

use server::action::Action;
use server::game::Game;
Expand All @@ -12,13 +11,11 @@ use crate::client_state::{ActiveDialog, ShownPlayer, State, StateUpdate, StateUp
use crate::collect_ui::{click_collect_option, collect_resources_dialog};
use crate::construct_ui::pay_construction_dialog;
use crate::dialog_ui::active_dialog_window;
use crate::happiness_ui::{
add_increase_happiness, increase_happiness_menu, show_increase_happiness,
};
use crate::happiness_ui::{add_increase_happiness, increase_happiness_menu};
use crate::hex_ui::pixel_to_coordinate;
use crate::log_ui::show_log;
use crate::map_ui::{draw_map, show_tile_menu};
use crate::player_ui::{show_global_controls, show_globals, show_player_status, show_wonders};
use crate::player_ui::{show_global_controls, show_globals};
use crate::{combat_ui, dialog_ui, influence_ui, move_ui, recruit_unit_ui, status_phase_ui};

pub async fn init(features: &Features) -> State {
Expand All @@ -45,55 +42,36 @@ pub fn render_and_update(
state.update(game, update)
}

fn render(game: &Game, state: &State, features: &Features) -> StateUpdate {
let player_index = game.active_player();
fn render(game: &Game, state: &mut State, features: &Features) -> StateUpdate {
let player = &state.shown_player(game);
clear_background(WHITE);

draw_map(game, state);
state.camera = Camera2D {
zoom: vec2(state.zoom, state.zoom * screen_width() / screen_height()),
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);
}
let mut updates = StateUpdates::new();
let update = show_globals(game, player);
updates.add(update);
show_player_status(game, player_index);
show_wonders(game, player_index);

if root_ui().button(vec2(1200., 100.), "Advances") {
return StateUpdate::OpenDialog(ActiveDialog::AdvanceMenu);
};
if root_ui().button(vec2(1200., 130.), "Log") {
return StateUpdate::OpenDialog(ActiveDialog::Log);
};
let d = state.game_state_dialog(game, &ActiveDialog::None);
if !matches!(d, ActiveDialog::None)
&& d.title() != state.active_dialog.title()
&& root_ui().button(vec2(1200., 160.), format!("Back to {}", d.title()))
{
return StateUpdate::OpenDialog(d);
}

if features.import_export && player.can_control {
if root_ui().button(vec2(1200., 290.), "Import") {
return StateUpdate::Import;
};
if root_ui().button(vec2(1250., 290.), "Export") {
return StateUpdate::Export;
};
}
if player.can_control {
if let Some(u) = &state.pending_update {
updates.add(dialog_ui::show_pending_update(u, player));
return updates.result();
}
}

if player.can_play_action {
updates.add(show_increase_happiness(game, player_index));
}
updates.add(show_global_controls(game, state));
updates.add(show_global_controls(game, state, features));

updates.add(match &state.active_dialog {
ActiveDialog::None => StateUpdate::None,
ActiveDialog::Log => show_log(game),
ActiveDialog::Log => show_log(game, player),
ActiveDialog::TileMenu(p) => show_tile_menu(game, *p, player),
ActiveDialog::WaitingForUpdate => {
active_dialog_window(player, "Waiting for update", |_ui| StateUpdate::None)
Expand Down Expand Up @@ -143,8 +121,9 @@ 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(x, y));
let pos = Position::from_coordinate(pixel_to_coordinate(
state.camera.screen_to_world(vec2(x, y)),
));
if !game.map.tiles.contains_key(&pos) {
return StateUpdate::None;
}
Expand Down
43 changes: 31 additions & 12 deletions client/src/client_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,19 @@ impl ActiveDialog {
ActiveDialog::RemoveCasualties(_) => "remove casualties",
}
}

#[must_use]
pub fn is_map_dialog(&self) -> bool {
matches!(
self,
ActiveDialog::TileMenu(_)
| ActiveDialog::IncreaseHappiness(_)
| ActiveDialog::CollectResources(_)
| ActiveDialog::MoveUnits(_)
| ActiveDialog::PlaceSettler
| ActiveDialog::RazeSize1City
)
}
}

pub struct PendingUpdate {
Expand Down Expand Up @@ -181,6 +194,7 @@ pub struct ShownPlayer {
pub index: usize,
pub can_control: bool,
pub can_play_action: bool,
pub active_dialog: ActiveDialog,
}

impl ShownPlayer {
Expand All @@ -195,19 +209,28 @@ pub struct State {
pub control_player: Option<usize>,
pub show_player: usize,
pub active_dialog: ActiveDialog,
dialog_stack: Vec<ActiveDialog>,
pub pending_update: Option<PendingUpdate>,
pub camera: Camera2D,
pub zoom: f32,
pub offset: Vec2,
}

pub const ZOOM: f32 = 0.001;
pub const OFFSET: Vec2 = vec2(-0.8, 0.45);

impl State {
pub async fn new(features: &Features) -> State {
State {
active_dialog: ActiveDialog::None,
dialog_stack: vec![],
pending_update: None,
assets: Assets::new(features).await,
control_player: None,
show_player: 0,
camera: Camera2D {
..Default::default()
},
zoom: ZOOM,
offset: OFFSET,
}
}

Expand All @@ -219,12 +242,12 @@ impl State {
index: self.show_player,
can_control: control,
can_play_action: control && game.state == GameState::Playing && game.actions_left > 0,
active_dialog: self.active_dialog.clone(),
}
}

pub fn clear(&mut self) {
self.active_dialog = ActiveDialog::None;
self.dialog_stack.clear();
self.pending_update = None;
}

Expand Down Expand Up @@ -280,26 +303,22 @@ impl State {
}

fn open_dialog(&mut self, dialog: ActiveDialog) {
if matches!(self.active_dialog, ActiveDialog::TileMenu(_)) {
if self.active_dialog.title() == dialog.title() {
self.close_dialog();
return;
}
if !matches!(self.active_dialog, ActiveDialog::None) {
self.dialog_stack.push(self.active_dialog.clone());
if matches!(self.active_dialog, ActiveDialog::TileMenu(_)) {
self.close_dialog();
}
self.active_dialog = dialog;
}

pub fn set_dialog(&mut self, dialog: ActiveDialog) {
self.active_dialog = dialog;
self.dialog_stack.clear();
}

fn close_dialog(&mut self) {
if let Some(dialog) = self.dialog_stack.pop() {
self.active_dialog = dialog;
} else {
self.active_dialog = ActiveDialog::None;
}
self.active_dialog = ActiveDialog::None;
}

pub fn update_from_game(&mut self, game: &Game) -> GameSyncRequest {
Expand Down
40 changes: 24 additions & 16 deletions client/src/dialog_ui.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use crate::client_state::{PendingUpdate, ShownPlayer, StateUpdate};
use macroquad::hash;
use macroquad::math::{vec2, Vec2};
use macroquad::prelude::screen_height;
use macroquad::ui::widgets::Window;
use macroquad::ui::{root_ui, Ui};

use crate::client_state::{PendingUpdate, ShownPlayer, StateUpdate};
use macroquad::window::screen_width;

pub fn active_dialog_window<F>(player: &ShownPlayer, title: &str, f: F) -> StateUpdate
where
F: FnOnce(&mut Ui) -> StateUpdate,
{
dialog(title, |ui| {
dialog(player, title, |ui| {
if player.can_control {
f(ui)
} else {
Expand All @@ -18,18 +19,17 @@ where
})
}

pub fn dialog<F>(title: &str, f: F) -> StateUpdate
pub fn dialog<F>(player: &ShownPlayer, title: &str, f: F) -> StateUpdate
where
F: FnOnce(&mut Ui) -> StateUpdate,
{
custom_dialog(title, vec2(1100., 400.), vec2(800., 350.), f)
}

pub fn full_dialog<F>(title: &str, f: F) -> StateUpdate
where
F: FnOnce(&mut Ui) -> StateUpdate,
{
custom_dialog(title, vec2(100., 100.), vec2(1600., 800.), f)
let width = screen_width() - 20.;
let size = if player.active_dialog.is_map_dialog() {
vec2(width / 2.0, 100.)
} else {
vec2(width, screen_height() - 100.)
};
custom_dialog(title, vec2(10., 70.), size, f)
}

pub fn custom_dialog<F>(title: &str, position: Vec2, size: Vec2, f: F) -> StateUpdate
Expand All @@ -42,10 +42,7 @@ where
.label(title)
.close_button(true);

let ui = &mut root_ui();
let token = window.begin(ui);
let update = f(ui);
let open = token.end(ui);
let (update, open) = show_window(window, f);
if matches!(update, StateUpdate::None) {
if open {
StateUpdate::None
Expand All @@ -57,6 +54,17 @@ where
}
}

fn show_window<F, R>(window: Window, f: F) -> (R, bool)
where
F: FnOnce(&mut Ui) -> R,
{
let ui = &mut root_ui();
let token = window.begin(ui);
let update = f(ui);
let open = token.end(ui);
(update, open)
}

pub fn show_pending_update(update: &PendingUpdate, player: &ShownPlayer) -> StateUpdate {
active_dialog_window(player, "Are you sure?", |ui| {
ui.label(None, &format!("Warning: {}", update.warning.join(", ")));
Expand Down
25 changes: 9 additions & 16 deletions client/src/happiness_ui.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
use macroquad::math::vec2;
use macroquad::ui::root_ui;

use server::action::Action;
use server::city::City;
use server::game::Game;
Expand Down Expand Up @@ -103,17 +100,13 @@ pub fn increase_happiness_menu(h: &IncreaseHappiness, player: &ShownPlayer) -> S
})
}

pub fn show_increase_happiness(game: &Game, player_index: usize) -> StateUpdate {
if root_ui().button(vec2(1200., 60.), "Increase Happiness") {
return StateUpdate::SetDialog(ActiveDialog::IncreaseHappiness(IncreaseHappiness::new(
game.get_player(player_index)
.cities
.iter()
.map(|c| (c.position, 0))
.collect(),
ResourcePile::empty(),
)));
}

StateUpdate::None
pub fn start_increase_happiness(game: &Game, player: &ShownPlayer) -> StateUpdate {
StateUpdate::OpenDialog(ActiveDialog::IncreaseHappiness(IncreaseHappiness::new(
game.get_player(player.index)
.cities
.iter()
.map(|c| (c.position, 0))
.collect(),
ResourcePile::empty(),
)))
}
10 changes: 5 additions & 5 deletions client/src/hex_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::f32::consts::PI;

use hex2d::{Coordinate, Spacing};
use macroquad::color::Color;
use macroquad::math::{f32, i32, vec2};
use macroquad::math::{f32, i32, vec2, Vec2};
use macroquad::prelude::{
draw_text, draw_texture_ex, DrawTextureParams, Rect, Texture2D, BLACK, DARKGRAY, WHITE,
};
Expand Down Expand Up @@ -49,8 +49,8 @@ pub fn draw_hex_center_text(p: Position, text: &str) {
draw_text(text, c.x - 5., c.y + 6., 25.0, BLACK);
}

pub fn pixel_to_coordinate(x: f32, y: f32) -> Coordinate {
let p = Point::new(x, y).to_game();
pub fn pixel_to_coordinate(p: Vec2) -> Coordinate {
let p = Point::new(p.x, p.y).to_game();
Coordinate::from_pixel(p.x, p.y, SPACING)
}

Expand Down Expand Up @@ -89,5 +89,5 @@ impl Point {
}
}

const TOP_BORDER: f32 = 130.0;
const LEFT_BORDER: f32 = 90.0;
const TOP_BORDER: f32 = 0.0;
const LEFT_BORDER: f32 = 0.0;
5 changes: 2 additions & 3 deletions client/src/local_client/bin/main.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use client::client::Features;
use client::local_client;
use macroquad::window::set_fullscreen;
use server::game::Game;

#[macroquad::main("Clash")]
async fn main() {
set_fullscreen(true);
// set_fullscreen(true);

let features = Features {
import_export: false,
import_export: true,
assets_url: "assets/".to_string(),
};

Expand Down
6 changes: 3 additions & 3 deletions client/src/log_ui.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use macroquad::ui::Ui;
use server::game::Game;

use crate::client_state::StateUpdate;
use crate::client_state::{ShownPlayer, StateUpdate};
use crate::dialog_ui::dialog;

pub fn show_log(game: &Game) -> StateUpdate {
dialog("Log", |ui| {
pub fn show_log(game: &Game, player: &ShownPlayer) -> StateUpdate {
dialog(player, "Log", |ui| {
game.log.iter().for_each(|l| {
multiline(ui, l);
});
Expand Down
Loading