Skip to content

Commit

Permalink
Show all players (#57)
Browse files Browse the repository at this point in the history
* show all players

* show all players

* settlers can't attack

* fix movement dialog, player status

* fix movement dialog, player status

* fix movement

* add "back to modal dialog"

* fmt
  • Loading branch information
zeitlinger authored Sep 29, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 22b52c7 commit 6d112e5
Showing 23 changed files with 467 additions and 270 deletions.
23 changes: 12 additions & 11 deletions client/src/advance_ui.rs
Original file line number Diff line number Diff line change
@@ -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};
@@ -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 {
@@ -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);
@@ -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,
29 changes: 12 additions & 17 deletions client/src/city_ui.rs
Original file line number Diff line number Diff line change
@@ -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;
@@ -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,
@@ -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,
@@ -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() {
157 changes: 81 additions & 76 deletions client/src/client.rs
Original file line number Diff line number Diff line change
@@ -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;
@@ -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 => {
@@ -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);
@@ -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;
}
@@ -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))
}
}

Loading

0 comments on commit 6d112e5

Please sign in to comment.