Skip to content

Commit 72bb424

Browse files
authored
Siegecraft (#133)
1 parent 55e5411 commit 72bb424

36 files changed

+2471
-192
lines changed

client/src/advance_ui.rs

+18-62
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
use crate::client_state::{ActiveDialog, StateUpdate};
2-
use crate::dialog_ui::OkTooltip;
3-
use crate::layout_ui::{bottom_center_text, left_mouse_button_pressed_in_rect, top_centered_text};
2+
use crate::layout_ui::{left_mouse_button_pressed_in_rect, top_centered_text};
43
use crate::log_ui::break_text;
5-
use crate::payment_ui::{payment_dialog, HasPayment, Payment, ResourcePayment};
4+
use crate::payment_ui::{payment_model_dialog, PaymentModelEntry};
65
use crate::player_ui::player_color;
76
use crate::render_context::RenderContext;
8-
use crate::resource_ui::new_resource_map;
9-
use crate::select_ui::HasCountSelectableObject;
107
use crate::tooltip::show_tooltip_for_rect;
118
use macroquad::color::Color;
129
use macroquad::math::vec2;
@@ -21,9 +18,7 @@ use server::game::GameState;
2118
use server::payment::PaymentModel;
2219
use server::player::Player;
2320
use server::playing_actions::PlayingAction;
24-
use server::resource::ResourceType;
2521
use server::status_phase::StatusPhaseAction;
26-
use std::cmp::min;
2722
use std::ops::Rem;
2823

2924
const COLUMNS: usize = 6;
@@ -39,7 +34,6 @@ pub enum AdvanceState {
3934
pub struct AdvancePayment {
4035
pub name: String,
4136
model: PaymentModel,
42-
payment: Payment,
4337
}
4438

4539
impl AdvancePayment {
@@ -49,44 +43,9 @@ impl AdvancePayment {
4943
.get_advance_payment_options(name);
5044
AdvancePayment {
5145
name: name.to_string(),
52-
payment: AdvancePayment::new_payment(model.clone()),
5346
model,
5447
}
5548
}
56-
57-
pub fn new_payment(model: PaymentModel) -> Payment {
58-
let PaymentModel::Sum(a) = model;
59-
let left = a.left;
60-
61-
let mut resources: Vec<ResourcePayment> = new_resource_map(&a.default)
62-
.into_iter()
63-
.map(|e| ResourcePayment::new(e.0, e.1, 0, min(a.cost, e.1 + left.amount(e.0))))
64-
.collect();
65-
resources.sort_by_key(|r| r.resource);
66-
67-
Payment { resources }
68-
}
69-
70-
pub fn valid(&self) -> OkTooltip {
71-
let pile = self.payment.to_resource_pile();
72-
let valid = self.model.is_valid(&pile);
73-
74-
if valid {
75-
OkTooltip::Valid(format!("Pay {} to research {}", pile, self.name))
76-
} else {
77-
OkTooltip::Invalid(format!(
78-
"You don't have {} to research {}",
79-
self.model.default(),
80-
self.name
81-
))
82-
}
83-
}
84-
}
85-
86-
impl HasPayment for AdvancePayment {
87-
fn payment(&self) -> &Payment {
88-
&self.payment
89-
}
9049
}
9150

9251
pub fn show_paid_advance_menu(rc: &RenderContext) -> StateUpdate {
@@ -269,28 +228,25 @@ pub fn pay_advance_dialog(ap: &AdvancePayment, rc: &RenderContext) -> StateUpdat
269228
// select a different advance
270229
return update;
271230
};
272-
bottom_center_text(rc, &ap.name, vec2(-200., -50.));
273-
payment_dialog(
274-
ap,
275-
AdvancePayment::valid,
276-
|| {
231+
payment_model_dialog(
232+
rc,
233+
&[PaymentModelEntry {
234+
name: ap.name.clone(),
235+
model: ap.model.clone(),
236+
optional: false,
237+
}],
238+
|p| {
239+
ActiveDialog::AdvancePayment(AdvancePayment {
240+
name: ap.name.clone(),
241+
model: p[0].model.clone(),
242+
})
243+
},
244+
true,
245+
|pile| {
277246
StateUpdate::Execute(Action::Playing(PlayingAction::Advance {
278247
advance: ap.name.to_string(),
279-
payment: ap.payment.to_resource_pile(),
248+
payment: pile[0].clone(),
280249
}))
281250
},
282-
|ap, r| ap.payment.get(r).selectable.max > 0,
283-
|ap, r| add(ap, r, 1),
284-
|ap, r| add(ap, r, -1),
285-
rc,
286251
)
287252
}
288-
289-
fn add(ap: &AdvancePayment, r: ResourceType, i: i32) -> StateUpdate {
290-
let mut new = ap.clone();
291-
let p = new.payment.get_mut(r);
292-
293-
let c = p.counter_mut();
294-
c.current = (c.current as i32 + i) as u32;
295-
StateUpdate::OpenDialog(ActiveDialog::AdvancePayment(new))
296-
}

client/src/client.rs

+1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ fn render_active_dialog(rc: &RenderContext) -> StateUpdate {
160160
ActiveDialog::PlayActionCard => combat_ui::play_action_card_dialog(rc),
161161
ActiveDialog::Retreat => combat_ui::retreat_dialog(rc),
162162
ActiveDialog::RemoveCasualties(s) => combat_ui::remove_casualties_dialog(rc, s),
163+
ActiveDialog::SiegecraftPayment(p) => combat_ui::pay_siegecraft_dialog(p, rc),
163164
}
164165
}
165166

client/src/client_state.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use macroquad::prelude::*;
22
use server::action::Action;
33
use server::city::{City, MoodState};
44
use server::combat::{active_attackers, active_defenders, CombatPhase};
5-
use server::content::advances::{NAVIGATION, ROADS};
5+
use server::content::advances::{NAVIGATION, ROADS, SIEGECRAFT};
6+
use server::content::custom_phase_actions::CustomPhaseState;
67
use server::game::{CulturalInfluenceResolution, CurrentMove, Game, GameState};
78
use server::position::Position;
89
use server::status_phase::{StatusPhaseAction, StatusPhaseState};
@@ -12,7 +13,7 @@ use crate::assets::Assets;
1213
use crate::city_ui::building_name;
1314
use crate::client::{Features, GameSyncRequest};
1415
use crate::collect_ui::CollectResources;
15-
use crate::combat_ui::RemoveCasualtiesSelection;
16+
use crate::combat_ui::{RemoveCasualtiesSelection, SiegecraftPaymentModel};
1617
use crate::construct_ui::ConstructionPayment;
1718
use crate::happiness_ui::IncreaseHappinessConfig;
1819
use crate::layout_ui::FONT_SIZE;
@@ -56,6 +57,7 @@ pub enum ActiveDialog {
5657
PlaceSettler,
5758
Retreat,
5859
RemoveCasualties(RemoveCasualtiesSelection),
60+
SiegecraftPayment(SiegecraftPaymentModel),
5961
}
6062

6163
impl ActiveDialog {
@@ -87,6 +89,7 @@ impl ActiveDialog {
8789
ActiveDialog::PlaceSettler => "place settler",
8890
ActiveDialog::Retreat => "retreat",
8991
ActiveDialog::RemoveCasualties(_) => "remove casualties",
92+
ActiveDialog::SiegecraftPayment(_) => "siegecraft payment",
9093
}
9194
}
9295

@@ -174,6 +177,11 @@ impl ActiveDialog {
174177
r.needed
175178
)],
176179
ActiveDialog::WaitingForUpdate => vec!["Waiting for server update".to_string()],
180+
ActiveDialog::SiegecraftPayment(_) => {
181+
let mut result = vec![];
182+
advance_help(rc, &mut result, SIEGECRAFT);
183+
result
184+
}
177185
}
178186
}
179187

@@ -541,6 +549,11 @@ impl State {
541549
rotation: r.block.position.rotation,
542550
})
543551
}
552+
GameState::CustomPhase(c) => match c {
553+
CustomPhaseState::SiegecraftPayment(_) => {
554+
ActiveDialog::SiegecraftPayment(SiegecraftPaymentModel::new(game))
555+
}
556+
},
544557
}
545558
}
546559

client/src/collect_ui.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use server::content::custom_actions::CustomAction;
2222
use server::game::Game;
2323
use server::playing_actions::{get_total_collection, Collect, PlayingAction};
2424
use server::position::Position;
25-
use server::resource::{resource_types, ResourceType};
25+
use server::resource::ResourceType;
2626
use server::resource_pile::ResourcePile;
2727

2828
#[derive(Clone)]
@@ -190,7 +190,7 @@ pub fn draw_resource_collect_tile(rc: &RenderContext, pos: Position) -> StateUpd
190190
}
191191

192192
let map = new_resource_map(pile);
193-
let m: Vec<(ResourceType, &u32)> = resource_types()
193+
let m: Vec<(ResourceType, &u32)> = ResourceType::all()
194194
.iter()
195195
.filter_map(|r| {
196196
let a = map.get(r);

client/src/combat_ui.rs

+56-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1-
use server::action::{Action, CombatAction, PlayActionCard};
2-
use server::game::Game;
3-
use server::position::Position;
4-
use server::unit::Unit;
5-
6-
use crate::client_state::StateUpdate;
1+
use crate::client_state::{ActiveDialog, StateUpdate};
72
use crate::dialog_ui::{cancel_button_with_tooltip, ok_button, OkTooltip};
3+
use crate::payment_ui::{payment_model_dialog, PaymentModelEntry};
84
use crate::render_context::RenderContext;
95
use crate::select_ui::ConfirmSelection;
106
use crate::unit_ui;
117
use crate::unit_ui::UnitSelection;
8+
use server::action::{Action, CombatAction, PlayActionCard};
9+
use server::content::custom_phase_actions::{
10+
CustomPhaseAction, SiegecraftPayment, SIEGECRAFT_EXTRA_DIE, SIEGECRAFT_IGNORE_HIT,
11+
};
12+
use server::game::Game;
13+
use server::payment::get_single_resource_payment_model;
14+
use server::position::Position;
15+
use server::unit::Unit;
1216

1317
pub fn retreat_dialog(rc: &RenderContext) -> StateUpdate {
1418
if ok_button(rc, OkTooltip::Valid("Retreat".to_string())) {
@@ -93,3 +97,49 @@ pub fn play_action_card_dialog(rc: &RenderContext) -> StateUpdate {
9397
}
9498
StateUpdate::None
9599
}
100+
101+
#[derive(Clone)]
102+
pub struct SiegecraftPaymentModel {
103+
extra_die: PaymentModelEntry,
104+
ignore_hit: PaymentModelEntry,
105+
}
106+
107+
impl SiegecraftPaymentModel {
108+
pub fn new(game: &Game) -> SiegecraftPaymentModel {
109+
let available = game.get_player(game.active_player()).resources.clone();
110+
SiegecraftPaymentModel {
111+
extra_die: PaymentModelEntry {
112+
name: "Cancel fortress extra die in first round of combat".to_string(),
113+
model: get_single_resource_payment_model(&available, &SIEGECRAFT_EXTRA_DIE),
114+
optional: true,
115+
},
116+
ignore_hit: PaymentModelEntry {
117+
name: "Cancel fortress ignore hit in first round of combat".to_string(),
118+
model: get_single_resource_payment_model(&available, &SIEGECRAFT_IGNORE_HIT),
119+
optional: true,
120+
},
121+
}
122+
}
123+
}
124+
125+
pub fn pay_siegecraft_dialog(p: &SiegecraftPaymentModel, rc: &RenderContext) -> StateUpdate {
126+
payment_model_dialog(
127+
rc,
128+
&vec![p.extra_die.clone(), p.ignore_hit.clone()],
129+
|p| {
130+
ActiveDialog::SiegecraftPayment(SiegecraftPaymentModel {
131+
extra_die: p[0].clone(),
132+
ignore_hit: p[1].clone(),
133+
})
134+
},
135+
false,
136+
|_| {
137+
StateUpdate::Execute(Action::CustomPhase(
138+
CustomPhaseAction::SiegecraftPaymentAction(SiegecraftPayment {
139+
extra_die: p.extra_die.model.default().clone(),
140+
ignore_hit: p.ignore_hit.model.default().clone(),
141+
}),
142+
))
143+
},
144+
)
145+
}

client/src/construct_ui.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use std::cmp;
22

3-
use macroquad::math::{i32, u32};
4-
53
use crate::client_state::{ActiveDialog, StateUpdate};
64
use crate::dialog_ui::OkTooltip;
75
use crate::payment_ui::{payment_dialog, HasPayment, Payment, ResourcePayment};
86
use crate::recruit_unit_ui::RecruitSelection;
97
use crate::render_context::RenderContext;
108
use crate::resource_ui::new_resource_map;
119
use crate::select_ui::CountSelector;
10+
use macroquad::math::{i32, u32};
11+
use macroquad::prelude::Vec2;
1212
use server::action::Action;
1313
use server::city::City;
1414
use server::city_pieces::Building;
@@ -112,6 +112,8 @@ pub fn pay_construction_dialog(rc: &RenderContext, cp: &ConstructionPayment) ->
112112
StateUpdate::OpenDialog(ActiveDialog::ConstructionPayment(new))
113113
},
114114
rc,
115+
Vec2::new(0., 0.),
116+
true,
115117
)
116118
}
117119

@@ -220,7 +222,7 @@ impl ConstructionPayment {
220222
}
221223

222224
impl HasPayment for ConstructionPayment {
223-
fn payment(&self) -> &Payment {
224-
&self.payment
225+
fn payment(&self) -> Payment {
226+
self.payment.clone()
225227
}
226228
}

client/src/dialog_ui.rs

+7
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,18 @@ use crate::render_context::RenderContext;
44
use macroquad::math::Vec2;
55
use server::content::custom_actions::CustomActionType;
66

7+
#[derive(Clone)]
78
pub enum OkTooltip {
89
Valid(String),
910
Invalid(String),
1011
}
1112

13+
impl OkTooltip {
14+
pub fn is_valid(&self) -> bool {
15+
matches!(self, OkTooltip::Valid(_))
16+
}
17+
}
18+
1219
#[derive(Clone)]
1320
pub enum BaseOrCustomAction {
1421
Base,

client/src/layout_ui.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,13 @@ pub fn bottom_center_texture(
5959
draw_icon(rc, texture, tooltip, anchor + p)
6060
}
6161

62-
pub fn bottom_centered_text(rc: &RenderContext, text: &str) {
62+
pub fn bottom_centered_text_with_offset(rc: &RenderContext, text: &str, offset: Vec2) {
6363
let dimensions = rc.state.measure_text(text);
64-
bottom_center_text(rc, text, vec2(-dimensions.width / 2., -50.));
64+
bottom_center_text(rc, text, vec2(-dimensions.width / 2., -50.) + offset);
65+
}
66+
67+
pub fn bottom_centered_text(rc: &RenderContext, text: &str) {
68+
bottom_centered_text_with_offset(rc, text, vec2(0., 0.));
6569
}
6670

6771
pub fn bottom_center_text(rc: &RenderContext, text: &str, p: Vec2) {

0 commit comments

Comments
 (0)