Skip to content

Commit ada2036

Browse files
authored
Seafearing (#150)
1 parent 800da80 commit ada2036

19 files changed

+2496
-178
lines changed

client/src/client_state.rs

+23-9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use server::content::custom_phase_actions::CustomPhaseRequest;
2222
use server::game::{CulturalInfluenceResolution, CurrentMove, Game, GameState};
2323
use server::position::Position;
2424
use server::status_phase::{StatusPhaseAction, StatusPhaseState};
25+
use server::unit::carried_units;
2526

2627
#[derive(Clone)]
2728
pub enum ActiveDialog {
@@ -177,7 +178,11 @@ impl ActiveDialog {
177178
ActiveDialog::Retreat => vec!["Do you want to retreat?".to_string()],
178179
ActiveDialog::RemoveCasualties(r) => vec![format!(
179180
"Remove {} units: click on a unit to remove it",
180-
r.needed
181+
if r.needed_carried > 0 {
182+
format!("{} ships and {} carried units", r.needed, r.needed_carried)
183+
} else {
184+
r.needed.to_string()
185+
}
181186
)],
182187
ActiveDialog::WaitingForUpdate => vec!["Waiting for server update".to_string()],
183188
ActiveDialog::CustomPhaseRewardRequest(_) => {
@@ -545,17 +550,22 @@ impl State {
545550
StatusPhaseState::DetermineFirstPlayer => ActiveDialog::DetermineFirstPlayer,
546551
},
547552
GameState::PlaceSettler { .. } => ActiveDialog::PlaceSettler,
548-
GameState::Combat(c) => match c.phase {
553+
GameState::Combat(c) => match &c.phase {
549554
CombatPhase::PlayActionCard(_) => ActiveDialog::PlayActionCard,
550-
CombatPhase::RemoveCasualties {
551-
player, casualties, ..
552-
} => {
553-
let (position, selectable) = if player == c.attacker {
555+
CombatPhase::RemoveCasualties(r) => {
556+
let (position, selectable) = if r.player == c.attacker {
554557
(
555558
c.attacker_position,
556-
active_attackers(game, c.attacker, &c.attackers, c.defender_position),
559+
active_attackers(game, c.attacker, &c.attackers, c.defender_position)
560+
.clone()
561+
.into_iter()
562+
.chain(c.attackers.iter().flat_map(|a| {
563+
let units = carried_units(*a, game.get_player(r.player));
564+
units
565+
}))
566+
.collect(),
557567
)
558-
} else if player == c.defender {
568+
} else if r.player == c.defender {
559569
(
560570
c.defender_position,
561571
active_defenders(game, c.defender, c.defender_position),
@@ -564,7 +574,11 @@ impl State {
564574
panic!("player should be either defender or attacker")
565575
};
566576
ActiveDialog::RemoveCasualties(RemoveCasualtiesSelection::new(
567-
position, casualties, selectable,
577+
r.player,
578+
position,
579+
r.casualties,
580+
r.carried_units_casualties,
581+
selectable,
568582
))
569583
}
570584
CombatPhase::Retreat => ActiveDialog::Retreat,

client/src/combat_ui.rs

+25-4
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,36 @@ fn retreat(retreat: bool) -> StateUpdate {
2525

2626
#[derive(Clone)]
2727
pub struct RemoveCasualtiesSelection {
28+
pub player: usize,
2829
pub position: Position,
2930
pub needed: u8,
31+
pub needed_carried: u8,
3032
pub selectable: Vec<u32>,
3133
pub units: Vec<u32>,
3234
}
3335

3436
impl RemoveCasualtiesSelection {
35-
pub fn new(position: Position, needed: u8, selectable: Vec<u32>) -> Self {
37+
pub fn new(
38+
player: usize,
39+
position: Position,
40+
needed: u8,
41+
needed_carried: u8,
42+
selectable: Vec<u32>,
43+
) -> Self {
3644
RemoveCasualtiesSelection {
45+
player,
3746
position,
3847
needed,
48+
needed_carried,
3949
units: Vec::new(),
4050
selectable,
4151
}
4252
}
53+
54+
#[must_use]
55+
pub fn total_needed(&self) -> u8 {
56+
self.needed + self.needed_carried
57+
}
4358
}
4459

4560
impl UnitSelection for RemoveCasualtiesSelection {
@@ -57,13 +72,19 @@ impl ConfirmSelection for RemoveCasualtiesSelection {
5772
None
5873
}
5974

60-
fn confirm(&self, _game: &Game) -> OkTooltip {
61-
if self.needed == self.units.len() as u8 {
75+
fn confirm(&self, game: &Game) -> OkTooltip {
76+
let units = self
77+
.units
78+
.iter()
79+
.map(|id| game.get_player(self.player).get_unit(*id).unwrap());
80+
let carried = units.filter(|u| u.carrier_id.is_some()).count() as u8;
81+
82+
if carried == self.needed_carried && self.units.len() as u8 == self.total_needed() {
6283
OkTooltip::Valid("Remove casualties".to_string())
6384
} else {
6485
OkTooltip::Invalid(format!(
6586
"Need to select {} units",
66-
self.needed - self.units.len() as u8
87+
self.total_needed() - self.units.len() as u8
6788
))
6889
}
6990
}

client/src/move_ui.rs

+9-19
Original file line numberDiff line numberDiff line change
@@ -80,28 +80,18 @@ pub fn possible_destinations(
8080
res
8181
}
8282

83-
fn move_destination(
84-
dest: &MoveDestination,
85-
pos: Position,
86-
unit: Option<u32>,
87-
) -> Option<(Position, Option<u32>, Option<PaymentOptions>)> {
88-
match dest {
89-
MoveDestination::Tile((p, cost)) if p == &pos => Some((*p, None, Some(cost.clone()))),
90-
MoveDestination::Carrier(id) if unit.is_some_and(|u| u == *id) => {
91-
Some((pos, Some(*id), None))
92-
}
93-
_ => None,
94-
}
95-
}
96-
9783
pub fn click(rc: &RenderContext, pos: Position, s: &MoveSelection, mouse_pos: Vec2) -> StateUpdate {
9884
let game = rc.game;
9985
let p = game.get_player(s.player_index);
10086
let carrier = click_unit(rc, pos, mouse_pos, p, false);
101-
if let Some((destination, embark_carrier_id, cost)) = s
102-
.destinations
103-
.iter()
104-
.find_map(|d| move_destination(d, pos, carrier))
87+
if let Some((destination, embark_carrier_id, cost)) =
88+
s.clone().destinations.into_iter().find_map(|d| match d {
89+
MoveDestination::Tile((p, cost)) if p == pos => Some((p, None, cost)),
90+
MoveDestination::Carrier(id) if carrier.is_some_and(|u| u == id) => {
91+
Some((pos, Some(id), PaymentOptions::free()))
92+
}
93+
_ => None,
94+
})
10595
{
10696
let units = s.units.clone();
10797
let action = MovementAction::Move(MoveUnits {
@@ -111,7 +101,7 @@ pub fn click(rc: &RenderContext, pos: Position, s: &MoveSelection, mouse_pos: Ve
111101
payment: ResourcePile::empty(),
112102
});
113103

114-
if let Some(cost) = cost {
104+
if !cost.is_free() {
115105
return StateUpdate::OpenDialog(ActiveDialog::MovePayment(MovePayment {
116106
action,
117107
payment: rc.new_payment(&cost, "Move units", true),

0 commit comments

Comments
 (0)