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

Show all players #57

Merged
merged 9 commits into from
Sep 29, 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
23 changes: 12 additions & 11 deletions client/src/advance_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use server::playing_actions::PlayingAction;
use server::resource_pile::AdvancePaymentOptions;
use server::status_phase::{StatusPhaseAction, StatusPhaseState};

use crate::client_state::{can_play_action, ActiveDialog, StateUpdate};
use crate::client_state::{ActiveDialog, ShownPlayer, StateUpdate};
use crate::dialog_ui::dialog_window;
use crate::payment_ui::{payment_dialog, HasPayment, Payment, ResourcePayment};
use crate::resource_ui::{new_resource_map, ResourceType};
Expand Down Expand Up @@ -76,33 +76,33 @@ impl HasPayment for AdvancePayment {
}
}

pub fn show_advance_menu(game: &Game, player_index: usize) -> StateUpdate {
show_generic_advance_menu("Advances", game, player_index, true, |name| {
pub fn show_advance_menu(game: &Game, player: &ShownPlayer) -> StateUpdate {
show_generic_advance_menu("Advances", game, player, true, |name| {
StateUpdate::SetDialog(ActiveDialog::AdvancePayment(AdvancePayment::new(
game,
player_index,
player.index,
&name,
)))
})
}

pub fn show_free_advance_menu(game: &Game, player_index: usize) -> StateUpdate {
show_generic_advance_menu("Select a free advance", game, player_index, false, |name| {
pub fn show_free_advance_menu(game: &Game, player: &ShownPlayer) -> StateUpdate {
show_generic_advance_menu("Select a free advance", game, player, false, |name| {
StateUpdate::status_phase(StatusPhaseAction::FreeAdvance(name))
})
}

pub fn show_generic_advance_menu(
title: &str,
game: &Game,
player_index: usize,
player: &ShownPlayer,
close_button: bool,
new_update: impl Fn(String) -> StateUpdate,
) -> StateUpdate {
dialog_window(title, close_button, |ui| {
dialog_window(player, title, close_button, |ui| {
for a in get_all() {
let name = a.name;
let p = game.get_player(player_index);
let p = player.get(game);
if p.has_advance(&name) {
ui.label(None, &name);
} else {
Expand All @@ -112,7 +112,7 @@ pub fn show_generic_advance_menu(
) {
p.can_advance_free(&name)
} else {
can_play_action(game) && p.can_advance(&name)
player.can_control && p.can_advance(&name)
};
if can && ui.button(None, name.clone()) {
return new_update(name);
Expand All @@ -123,8 +123,9 @@ pub fn show_generic_advance_menu(
})
}

pub fn pay_advance_dialog(ap: &AdvancePayment) -> StateUpdate {
pub fn pay_advance_dialog(ap: &AdvancePayment, player: &ShownPlayer) -> StateUpdate {
payment_dialog(
player,
&format!("Pay for advance {}", ap.name),
ap,
AdvancePayment::valid,
Expand Down
29 changes: 12 additions & 17 deletions client/src/city_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use server::player::Player;
use server::position::Position;
use server::unit::Units;

use crate::client_state::{can_play_action, ActiveDialog, State, StateUpdate, StateUpdates};
use crate::client_state::{ActiveDialog, ShownPlayer, State, StateUpdate, StateUpdates};
use crate::collect_ui::{possible_resource_collections, CollectResources};
use crate::construct_ui::{add_construct_button, add_wonder_buttons};
use crate::hex_ui::draw_hex_center_text;
Expand All @@ -17,48 +17,44 @@ use crate::recruit_unit_ui::RecruitAmount;
use crate::{hex_ui, influence_ui, player_ui};

pub struct CityMenu {
pub player_index: usize,
pub player: ShownPlayer,
pub city_owner_index: usize,
pub city_position: Position,
}

impl CityMenu {
pub fn new(player_index: usize, city_owner_index: usize, city_position: Position) -> Self {
pub fn new(player: &ShownPlayer, city_owner_index: usize, city_position: Position) -> Self {
CityMenu {
player_index,
player: player.clone(),
city_owner_index,
city_position,
}
}

pub fn get_player<'a>(&self, game: &'a Game) -> &'a Player {
game.get_player(self.player_index)
}

pub fn get_city_owner<'a>(&self, game: &'a Game) -> &'a Player {
game.get_player(self.city_owner_index)
}

pub fn get_city<'a>(&self, game: &'a Game) -> &'a City {
return game.get_city(self.city_owner_index, self.city_position);
game.get_city(self.city_owner_index, self.city_position)
}

pub fn is_city_owner(&self) -> bool {
self.player_index == self.city_owner_index
self.player.index == self.city_owner_index
}
}

pub fn show_city_menu(game: &Game, menu: &CityMenu) -> StateUpdate {
let position = menu.city_position;
let city = menu.get_city(game);

show_generic_tile_menu(game, position, city_label(game, city), |ui| {
let can_play = can_play_action(game) && menu.is_city_owner() && city.can_activate();
show_generic_tile_menu(game, position, &menu.player, city_label(game, city), |ui| {
let can_play = menu.player.can_play_action && menu.is_city_owner() && city.can_activate();
if can_play {
if ui.button(None, "Collect Resources") {
return StateUpdate::SetDialog(ActiveDialog::CollectResources(
CollectResources::new(
menu.player_index,
menu.player.index,
menu.city_position,
possible_resource_collections(
game,
Expand All @@ -71,7 +67,7 @@ pub fn show_city_menu(game: &Game, menu: &CityMenu) -> StateUpdate {
if ui.button(None, "Recruit Units") {
return RecruitAmount::new_selection(
game,
menu.player_index,
menu.player.index,
menu.city_position,
Units::empty(),
None,
Expand Down Expand Up @@ -127,11 +123,10 @@ fn city_label(game: &Game, city: &City) -> Vec<String> {
}

fn add_building_actions(game: &Game, menu: &CityMenu, ui: &mut Ui) -> StateUpdate {
let closest_city_pos = influence_ui::closest_city(game, menu);

if !can_play_action(game) {
if !menu.player.can_play_action {
return StateUpdate::None;
}
let closest_city_pos = influence_ui::closest_city(game, menu);

let mut updates = StateUpdates::new();
for (building, name) in building_names() {
Expand Down
157 changes: 81 additions & 76 deletions client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use server::status_phase::StatusPhaseAction;

use crate::advance_ui::{pay_advance_dialog, show_advance_menu, show_free_advance_menu};
use crate::client_state::{
ActiveDialog, ControlPlayers, PendingUpdate, State, StateUpdate, StateUpdates,
ActiveDialog, PendingUpdate, ShownPlayer, State, StateUpdate, StateUpdates,
};
use crate::collect_ui::{click_collect_option, collect_resources_dialog};
use crate::construct_ui::pay_construction_dialog;
Expand All @@ -33,20 +33,6 @@ pub fn render_and_update(
sync_result: &GameSyncResult,
features: &Features,
) -> GameSyncRequest {
match state.control_players {
ControlPlayers::None => {
// todo add spectator mode
return GameSyncRequest::None;
}
ControlPlayers::All => {}
ControlPlayers::Own(p) => {
if game.active_player() != p {
// todo add spectator mode
return GameSyncRequest::None;
}
}
}

match sync_result {
GameSyncResult::None => {}
GameSyncResult::Update => {
Expand All @@ -63,82 +49,97 @@ pub fn render_and_update(

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

draw_map(game, state);
let mut updates = StateUpdates::new();
show_globals(game);
let update = show_globals(game, player);
updates.add(update);
show_resources(game, player_index);
show_wonders(game, player_index);

if root_ui().button(vec2(1200., 130.), "Log") {
return StateUpdate::OpenDialog(ActiveDialog::Log);
};
if root_ui().button(vec2(1200., 100.), "Advances") {
return StateUpdate::OpenDialog(ActiveDialog::AdvanceMenu);
};
if features.import_export {
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 let Some(u) = &state.pending_update {
updates.add(show_pending_update(u));
return updates.result();
if player.can_control {
if let Some(u) = &state.pending_update {
updates.add(show_pending_update(u, player));
return updates.result();
}
}

if game.state == server::game::GameState::Playing {
if player.can_play_action {
updates.add(show_increase_happiness(game, player_index));
}
updates.add(show_global_controls(game, state));

updates.add(match &state.active_dialog {
ActiveDialog::None => StateUpdate::None,
ActiveDialog::Log => show_log(game),
ActiveDialog::TileMenu(p) => show_tile_menu(game, *p),
ActiveDialog::TileMenu(p) => show_tile_menu(game, *p, player),
ActiveDialog::WaitingForUpdate => {
active_dialog_window("Waiting for update", |_ui| StateUpdate::None)
active_dialog_window(player, "Waiting for update", |_ui| StateUpdate::None)
}

// playing actions
ActiveDialog::IncreaseHappiness(h) => increase_happiness_menu(h),
ActiveDialog::AdvanceMenu => show_advance_menu(game, player_index),
ActiveDialog::AdvancePayment(p) => pay_advance_dialog(p),
ActiveDialog::ConstructionPayment(p) => pay_construction_dialog(game, p),
ActiveDialog::CollectResources(c) => collect_resources_dialog(game, c),
ActiveDialog::RecruitUnitSelection(s) => recruit_unit_ui::select_dialog(game, s),
ActiveDialog::ReplaceUnits(r) => recruit_unit_ui::replace_dialog(game, r),
ActiveDialog::MoveUnits(s) => move_ui::move_units_dialog(game, s),
ActiveDialog::IncreaseHappiness(h) => increase_happiness_menu(h, player),
ActiveDialog::AdvanceMenu => show_advance_menu(game, player),
ActiveDialog::AdvancePayment(p) => pay_advance_dialog(p, player),
ActiveDialog::ConstructionPayment(p) => pay_construction_dialog(game, p, player),
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)
influence_ui::cultural_influence_resolution_dialog(c, player)
}

//status phase
ActiveDialog::FreeAdvance => show_free_advance_menu(game, player_index),
ActiveDialog::RaseSize1City => status_phase_ui::raze_city_dialog(),
ActiveDialog::DetermineFirstPlayer => status_phase_ui::determine_first_player_dialog(game),
ActiveDialog::ChangeGovernmentType => status_phase_ui::change_government_type_dialog(game),
ActiveDialog::FreeAdvance => show_free_advance_menu(game, player),
ActiveDialog::RazeSize1City => status_phase_ui::raze_city_dialog(player),
ActiveDialog::DetermineFirstPlayer => {
status_phase_ui::determine_first_player_dialog(game, player)
}
ActiveDialog::ChangeGovernmentType => {
status_phase_ui::change_government_type_dialog(game, player)
}
ActiveDialog::ChooseAdditionalAdvances(a) => {
status_phase_ui::choose_additional_advances_dialog(game, a)
status_phase_ui::choose_additional_advances_dialog(game, a, player)
}

//combat
ActiveDialog::PlaceSettler => combat_ui::place_settler_dialog(),
ActiveDialog::Retreat => combat_ui::retreat_dialog(),
ActiveDialog::RemoveCasualties(s) => combat_ui::remove_casualties_dialog(game, s),
ActiveDialog::PlaceSettler => combat_ui::place_settler_dialog(player),
ActiveDialog::Retreat => combat_ui::retreat_dialog(player),
ActiveDialog::RemoveCasualties(s) => combat_ui::remove_casualties_dialog(game, s, player),
});

updates.add(try_click(game, state, player_index));
updates.add(try_click(game, state, player));

updates.result()
}

fn show_pending_update(update: &PendingUpdate) -> StateUpdate {
active_dialog_window("Are you sure?", |ui| {
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(", ")));
if ui.button(None, "OK") {
return StateUpdate::ResolvePendingUpdate(true);
Expand All @@ -150,7 +151,7 @@ fn show_pending_update(update: &PendingUpdate) -> StateUpdate {
})
}

pub fn try_click(game: &Game, state: &State, player_index: usize) -> StateUpdate {
pub fn try_click(game: &Game, state: &State, player: &ShownPlayer) -> StateUpdate {
if !is_mouse_button_pressed(MouseButton::Left) {
return StateUpdate::None;
}
Expand All @@ -161,38 +162,42 @@ pub fn try_click(game: &Game, state: &State, player_index: usize) -> StateUpdate
return StateUpdate::None;
}

match &state.active_dialog {
ActiveDialog::MoveUnits(s) => move_ui::click(pos, s),
ActiveDialog::ReplaceUnits(r) => recruit_unit_ui::click_replace(pos, r),
ActiveDialog::RemoveCasualties(_s) => StateUpdate::None,
ActiveDialog::CollectResources(col) => click_collect_option(col, pos),
ActiveDialog::RaseSize1City => {
if game.players[player_index].can_raze_city(pos) {
StateUpdate::status_phase(StatusPhaseAction::RaseSize1City(Some(pos)))
} else {
StateUpdate::None
if player.can_control {
match &state.active_dialog {
ActiveDialog::MoveUnits(s) => move_ui::click(pos, s),
ActiveDialog::ReplaceUnits(r) => recruit_unit_ui::click_replace(pos, r),
ActiveDialog::RemoveCasualties(_s) => StateUpdate::None,
ActiveDialog::CollectResources(col) => click_collect_option(col, pos),
ActiveDialog::RazeSize1City => {
if player.get(game).can_raze_city(pos) {
StateUpdate::status_phase(StatusPhaseAction::RaseSize1City(Some(pos)))
} else {
StateUpdate::None
}
}
}
ActiveDialog::PlaceSettler => {
if game.players[player_index].get_city(pos).is_some() {
StateUpdate::Execute(Action::PlaceSettler(pos))
} else {
StateUpdate::None
ActiveDialog::PlaceSettler => {
if player.get(game).get_city(pos).is_some() {
StateUpdate::Execute(Action::PlaceSettler(pos))
} else {
StateUpdate::None
}
}
}
ActiveDialog::IncreaseHappiness(h) => {
if let Some(city) = game.players[player_index].get_city(pos) {
StateUpdate::SetDialog(ActiveDialog::IncreaseHappiness(add_increase_happiness(
&game.players[player_index],
city,
pos,
h,
)))
} else {
StateUpdate::None
ActiveDialog::IncreaseHappiness(h) => {
if let Some(city) = player.get(game).get_city(pos) {
StateUpdate::SetDialog(ActiveDialog::IncreaseHappiness(add_increase_happiness(
player.get(game),
city,
pos,
h,
)))
} else {
StateUpdate::None
}
}
_ => StateUpdate::OpenDialog(ActiveDialog::TileMenu(pos)),
}
_ => StateUpdate::OpenDialog(ActiveDialog::TileMenu(pos)),
} else {
StateUpdate::OpenDialog(ActiveDialog::TileMenu(pos))
}
}

Expand Down
Loading
Loading