Skip to content

Commit 3f3f53a

Browse files
authored
add rituals
1 parent 674c149 commit 3f3f53a

31 files changed

+2928
-172
lines changed

client/src/advance_ui.rs

+7-13
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::client_state::{ActiveDialog, StateUpdate};
22
use crate::layout_ui::{left_mouse_button_pressed_in_rect, top_centered_text};
33
use crate::log_ui::break_text;
4-
use crate::payment_ui::{new_payment, payment_model_dialog, Payment};
4+
use crate::payment_ui::{new_payment, payment_dialog, Payment};
55
use crate::player_ui::player_color;
66
use crate::render_context::RenderContext;
77
use crate::tooltip::show_tooltip_for_rect;
@@ -212,16 +212,10 @@ pub fn pay_advance_dialog(ap: &Payment, rc: &RenderContext) -> StateUpdate {
212212
// select a different advance
213213
return update;
214214
};
215-
payment_model_dialog(
216-
rc,
217-
&[ap.clone()],
218-
|p| ActiveDialog::AdvancePayment(p[0].clone()),
219-
true,
220-
|pile| {
221-
StateUpdate::Execute(Action::Playing(PlayingAction::Advance {
222-
advance: ap.name.to_string(),
223-
payment: pile[0].clone(),
224-
}))
225-
},
226-
)
215+
payment_dialog(rc, ap, ActiveDialog::AdvancePayment, true, |payment| {
216+
StateUpdate::Execute(Action::Playing(PlayingAction::Advance {
217+
advance: ap.name.to_string(),
218+
payment,
219+
}))
220+
})
227221
}

client/src/city_ui.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ fn increase_happiness_button<'a>(rc: &'a RenderContext, city: &'a City) -> Optio
5858
open_increase_happiness_dialog(rc, |mut happiness| {
5959
let mut target = city.mood_state.clone();
6060
while target != MoodState::Happy {
61-
happiness = add_increase_happiness(city, &happiness);
61+
happiness = add_increase_happiness(rc, city, happiness);
6262
target = target.clone().add(1);
6363
}
6464
happiness

client/src/combat_ui.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::client_state::{ActiveDialog, StateUpdate};
22
use crate::dialog_ui::{cancel_button_with_tooltip, ok_button, OkTooltip};
3-
use crate::payment_ui::{new_payment, payment_model_dialog, Payment};
3+
use crate::payment_ui::{multi_payment_dialog, new_payment, payment_dialog, Payment};
44
use crate::render_context::RenderContext;
55
use crate::select_ui::ConfirmSelection;
66
use crate::unit_ui;
@@ -125,7 +125,7 @@ impl SiegecraftPaymentDialog {
125125
}
126126

127127
pub fn pay_siegecraft_dialog(p: &SiegecraftPaymentDialog, rc: &RenderContext) -> StateUpdate {
128-
payment_model_dialog(
128+
multi_payment_dialog(
129129
rc,
130130
&[p.extra_die.clone(), p.ignore_hit.clone()],
131131
|p| {
@@ -159,23 +159,23 @@ pub(crate) fn pay_steel_weapons_dialog(
159159
) -> StateUpdate {
160160
let attacker = dialog.attacker;
161161

162-
payment_model_dialog(
162+
payment_dialog(
163163
rc,
164-
&[dialog.payment.clone()],
164+
&dialog.payment.clone(),
165165
|p| {
166166
let mut n = dialog.clone();
167-
n.payment = p[0].clone();
167+
n.payment = p;
168168
ActiveDialog::SteelWeaponPayment(n)
169169
},
170170
false,
171171
|p| {
172172
if attacker {
173173
StateUpdate::Execute(Action::CustomPhase(
174-
CustomPhaseAction::SteelWeaponsAttackerAction(p[0].clone()),
174+
CustomPhaseAction::SteelWeaponsAttackerAction(p),
175175
))
176176
} else {
177177
StateUpdate::Execute(Action::CustomPhase(
178-
CustomPhaseAction::SteelWeaponsDefenderAction(p[0].clone()),
178+
CustomPhaseAction::SteelWeaponsDefenderAction(p),
179179
))
180180
}
181181
},

client/src/construct_ui.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::client_state::{ActiveDialog, StateUpdate};
2-
use crate::payment_ui::{new_payment, payment_model_dialog, Payment};
2+
use crate::payment_ui::{new_payment, payment_dialog, Payment};
33
use crate::recruit_unit_ui::RecruitSelection;
44
use crate::render_context::RenderContext;
55
use server::action::Action;
@@ -37,21 +37,21 @@ pub fn new_building_positions(
3737

3838
pub fn pay_construction_dialog(rc: &RenderContext, cp: &ConstructionPayment) -> StateUpdate {
3939
let city = rc.game.get_any_city(cp.city_position).unwrap();
40-
payment_model_dialog(
40+
payment_dialog(
4141
rc,
42-
&[cp.payment.clone()],
42+
&cp.payment.clone(),
4343
|p| {
4444
let mut new = cp.clone();
45-
new.payment = p[0].clone();
45+
new.payment = p;
4646
ActiveDialog::ConstructionPayment(new)
4747
},
4848
true,
49-
|p| match &cp.project {
49+
|payment| match &cp.project {
5050
ConstructionProject::Building(b, pos) => StateUpdate::execute_activation(
5151
Action::Playing(PlayingAction::Construct(Construct {
5252
city_position: cp.city_position,
5353
city_piece: *b,
54-
payment: p[0].clone(),
54+
payment,
5555
port_position: *pos,
5656
temple_bonus: None,
5757
})),
@@ -61,7 +61,7 @@ pub fn pay_construction_dialog(rc: &RenderContext, cp: &ConstructionPayment) ->
6161
ConstructionProject::Wonder(w) => StateUpdate::execute_activation(
6262
Action::Playing(PlayingAction::Custom(CustomAction::ConstructWonder {
6363
city_position: cp.city_position,
64-
payment: p[0].clone(),
64+
payment,
6565
wonder: w.clone(),
6666
})),
6767
vec![],
@@ -71,7 +71,7 @@ pub fn pay_construction_dialog(rc: &RenderContext, cp: &ConstructionPayment) ->
7171
Action::Playing(PlayingAction::Recruit(Recruit {
7272
city_position: cp.city_position,
7373
units: r.amount.units.clone().to_vec(),
74-
payment: p[0].clone(),
74+
payment,
7575
replaced_units: r.replaced_units.clone(),
7676
leader_name: r.amount.leader_name.clone(),
7777
})),

client/src/happiness_ui.rs

+61-67
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
use crate::action_buttons::{base_or_custom_action, base_or_custom_available};
22
use crate::client_state::{ActiveDialog, StateUpdate};
3-
use crate::dialog_ui::{
4-
cancel_button, ok_button, BaseOrCustomAction, BaseOrCustomDialog, OkTooltip,
5-
};
3+
use crate::dialog_ui::{BaseOrCustomAction, BaseOrCustomDialog};
4+
use crate::payment_ui::{new_payment, payment_dialog, Payment};
65
use crate::render_context::RenderContext;
7-
use crate::resource_ui::show_resource_pile;
86
use server::action::Action;
97
use server::city::City;
108
use server::content::custom_actions::{CustomAction, CustomActionType};
119
use server::player::Player;
1210
use server::playing_actions::{IncreaseHappiness, PlayingAction, PlayingActionType};
1311
use server::position::Position;
14-
use server::resource::ResourceType;
15-
use server::resource_pile::ResourcePile;
1612

1713
#[derive(Clone)]
1814
pub struct IncreaseHappinessConfig {
1915
pub steps: Vec<(Position, u32)>,
20-
pub cost: ResourcePile,
16+
pub payment: Payment,
2117
pub custom: BaseOrCustomDialog,
2218
}
2319

@@ -26,10 +22,23 @@ impl IncreaseHappinessConfig {
2622
let steps = p.cities.iter().map(|c| (c.position, 0)).collect();
2723
IncreaseHappinessConfig {
2824
steps,
29-
cost: ResourcePile::empty(),
25+
payment: Self::happiness_payment(p, &[(p.cities[0].position, 0)]),
3026
custom,
3127
}
3228
}
29+
30+
fn happiness_payment(p: &Player, new_steps: &[(Position, u32)]) -> Payment {
31+
let payment = new_steps
32+
.iter()
33+
.map(|(pos, steps)| {
34+
let city = p.get_city(*pos).unwrap();
35+
p.increase_happiness_cost(city, *steps).unwrap()
36+
})
37+
.reduce(|a, b| a + b)
38+
.unwrap();
39+
40+
new_payment(&payment, &p.resources, "Increase happiness", false)
41+
}
3342
}
3443

3544
pub fn can_play_increase_happiness(rc: &RenderContext) -> bool {
@@ -65,95 +74,80 @@ pub fn increase_happiness_click(
6574
) -> StateUpdate {
6675
if let Some(city) = rc.shown_player.get_city(pos) {
6776
StateUpdate::OpenDialog(ActiveDialog::IncreaseHappiness(add_increase_happiness(
68-
city, h,
77+
rc,
78+
city,
79+
h.clone(),
6980
)))
7081
} else {
7182
StateUpdate::None
7283
}
7384
}
7485

7586
pub fn add_increase_happiness(
87+
rc: &RenderContext,
7688
city: &City,
77-
increase_happiness: &IncreaseHappinessConfig,
89+
mut increase_happiness: IncreaseHappinessConfig,
7890
) -> IncreaseHappinessConfig {
79-
let mut total_cost = increase_happiness.cost.clone();
80-
let new_steps = increase_happiness
91+
let new_steps: Vec<(Position, u32)> = increase_happiness
8192
.steps
8293
.iter()
8394
.map(|(p, steps)| {
8495
let old_steps = *steps;
8596
if *p == city.position {
86-
if let Some(r) = increase_happiness_steps(city, &total_cost, old_steps) {
87-
total_cost = r.1;
88-
return (*p, r.0);
97+
if let Some(r) = increase_happiness_steps(rc, city, old_steps) {
98+
return (*p, r);
8999
};
90100
}
91101
(*p, old_steps)
92102
})
93103
.collect();
94104

95-
IncreaseHappinessConfig {
96-
steps: new_steps,
97-
cost: total_cost,
98-
custom: increase_happiness.custom.clone(),
99-
}
105+
increase_happiness.payment =
106+
IncreaseHappinessConfig::happiness_payment(rc.shown_player, &new_steps);
107+
increase_happiness.steps = new_steps;
108+
increase_happiness
100109
}
101110

102-
fn increase_happiness_steps(
103-
city: &City,
104-
total_cost: &ResourcePile,
105-
old_steps: u32,
106-
) -> Option<(u32, ResourcePile)> {
107-
if let Some(value) = increase_happiness_new_steps(city, total_cost, old_steps, old_steps + 1) {
111+
fn increase_happiness_steps(rc: &RenderContext, city: &City, old_steps: u32) -> Option<u32> {
112+
if let Some(value) = increase_happiness_new_steps(rc, city, old_steps + 1) {
108113
return Some(value);
109114
}
110-
if let Some(value) = increase_happiness_new_steps(city, total_cost, old_steps, 0) {
115+
if let Some(value) = increase_happiness_new_steps(rc, city, 0) {
111116
return Some(value);
112117
}
113118
None
114119
}
115120

116-
fn increase_happiness_new_steps(
117-
city: &City,
118-
total_cost: &ResourcePile,
119-
old_steps: u32,
120-
new_steps: u32,
121-
) -> Option<(u32, ResourcePile)> {
122-
if let Some(new_cost) = city.increase_happiness_cost(new_steps) {
123-
let mut new_total = total_cost.clone();
124-
if old_steps > 0 {
125-
new_total -= city
126-
.increase_happiness_cost(old_steps)
127-
.expect("invalid steps");
128-
}
129-
new_total += new_cost;
130-
return Some((new_steps, new_total));
131-
}
132-
None
121+
fn increase_happiness_new_steps(rc: &RenderContext, city: &City, new_steps: u32) -> Option<u32> {
122+
rc.shown_player
123+
.increase_happiness_cost(city, new_steps)
124+
.map(|_| new_steps)
133125
}
134126

135127
pub fn increase_happiness_menu(rc: &RenderContext, h: &IncreaseHappinessConfig) -> StateUpdate {
136-
show_resource_pile(rc, &h.cost, &[ResourceType::MoodTokens]);
137-
138-
let tooltip = if rc.shown_player.resources.can_afford(&h.cost) {
139-
OkTooltip::Valid("Increase happiness".to_string())
140-
} else {
141-
OkTooltip::Invalid("Not enough resources".to_string())
142-
};
143-
if ok_button(rc, tooltip) {
144-
let i = IncreaseHappiness {
145-
happiness_increases: h.steps.clone(),
146-
};
147-
let action = match &h.custom.custom {
148-
BaseOrCustomAction::Base => PlayingAction::IncreaseHappiness(i),
149-
BaseOrCustomAction::Custom { .. } => {
150-
PlayingAction::Custom(CustomAction::VotingIncreaseHappiness(i))
151-
}
152-
};
153-
return StateUpdate::Execute(Action::Playing(action));
154-
}
155-
if cancel_button(rc) {
156-
return StateUpdate::Cancel;
157-
}
158-
StateUpdate::None
128+
payment_dialog(
129+
rc,
130+
&h.payment,
131+
|payment| {
132+
ActiveDialog::IncreaseHappiness(IncreaseHappinessConfig {
133+
steps: h.steps.clone(),
134+
payment,
135+
custom: h.custom.clone(),
136+
})
137+
},
138+
true,
139+
|payment| {
140+
let i = IncreaseHappiness {
141+
happiness_increases: h.steps.clone(),
142+
payment,
143+
};
144+
let action = match &h.custom.custom {
145+
BaseOrCustomAction::Base => PlayingAction::IncreaseHappiness(i),
146+
BaseOrCustomAction::Custom { .. } => {
147+
PlayingAction::Custom(CustomAction::VotingIncreaseHappiness(i))
148+
}
149+
};
150+
StateUpdate::execute(Action::Playing(action))
151+
},
152+
)
159153
}

client/src/influence_ui.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ fn show_city(rc: &RenderContext, mouse_pos: Vec2, city: &City) -> Option<StateUp
7777
city.position,
7878
*b,
7979
) {
80-
if player.resources.can_afford(&cost) {
80+
if player.can_afford_resources(&cost) {
8181
let name = building_name(*b);
8282
let _ = rc.with_camera(CameraMode::World, |rc| {
8383
draw_circle_lines(center.x, center.y, BUILDING_SIZE, 1., WHITE);

client/src/payment_ui.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,25 @@ impl Payment {
7676
}
7777
}
7878

79-
pub fn payment_model_dialog(
79+
pub fn payment_dialog(
8080
rc: &RenderContext,
81-
payments: &[Payment], // None means the player can pay nothing
81+
payments: &Payment,
82+
to_dialog: impl FnOnce(Payment) -> ActiveDialog,
83+
may_cancel: bool,
84+
execute_action: impl FnOnce(ResourcePile) -> StateUpdate,
85+
) -> StateUpdate {
86+
multi_payment_dialog(
87+
rc,
88+
&[payments.clone()],
89+
|v| to_dialog(v[0].clone()),
90+
may_cancel,
91+
|v| execute_action(v[0].clone()),
92+
)
93+
}
94+
95+
pub fn multi_payment_dialog(
96+
rc: &RenderContext,
97+
payments: &[Payment],
8298
to_dialog: impl FnOnce(Vec<Payment>) -> ActiveDialog,
8399
may_cancel: bool,
84100
execute_action: impl FnOnce(Vec<ResourcePile>) -> StateUpdate,
@@ -202,6 +218,7 @@ fn sum_payment(a: &SumPaymentOptions, available: &ResourcePile) -> Vec<ResourceP
202218
.collect()
203219
}
204220

221+
// todo: move to Payment::new
205222
#[must_use]
206223
pub fn new_payment(
207224
model: &PaymentModel,

0 commit comments

Comments
 (0)