Skip to content

Commit

Permalink
Payment options (#148)
Browse files Browse the repository at this point in the history
  • Loading branch information
zeitlinger authored Feb 3, 2025
1 parent 638166a commit 181dc6d
Show file tree
Hide file tree
Showing 24 changed files with 723 additions and 571 deletions.
4 changes: 2 additions & 2 deletions client/src/advance_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ pub enum AdvanceState {

fn new_advance_payment(rc: &RenderContext, name: &str) -> Payment {
let p = rc.shown_player;
let model = &p.advance_cost(name);
let options = &p.advance_cost(name);
let available = &p.resources;
Payment::new(model, available, name, false)
Payment::new(options, available, name, false)
}

pub fn show_paid_advance_menu(rc: &RenderContext) -> StateUpdate {
Expand Down
8 changes: 4 additions & 4 deletions client/src/client_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,17 +509,17 @@ impl State {
r.iter()
.map(|p| {
Payment::new(
&p.model,
&p.options,
&game.get_player(game.active_player()).resources,
&p.name,
p.optional,
)
})
.collect(),
),
CustomPhaseRequest::Reward(r) => ActiveDialog::CustomPhaseRewardRequest(
Payment::new_gain(r.model.clone(), &r.name),
),
CustomPhaseRequest::Reward(r) => {
ActiveDialog::CustomPhaseRewardRequest(Payment::new_gain(&r.options, &r.name))
}
};
}
match &game.state {
Expand Down
4 changes: 2 additions & 2 deletions client/src/construct_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use server::city::City;
use server::city_pieces::Building;
use server::content::custom_actions::CustomAction;
use server::map::Terrain;
use server::payment::PaymentModel;
use server::payment::PaymentOptions;
use server::playing_actions::{Construct, PlayingAction, Recruit};
use server::position::Position;
use server::unit::UnitType;
Expand Down Expand Up @@ -113,7 +113,7 @@ impl ConstructionPayment {
.unwrap()
.cost
.clone(),
ConstructionProject::Units(sel) => PaymentModel::resources(
ConstructionProject::Units(sel) => PaymentOptions::resources(
sel.amount
.units
.clone()
Expand Down
5 changes: 4 additions & 1 deletion client/src/happiness_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ impl IncreaseHappinessConfig {
let city = p.get_city(*pos).unwrap();
p.increase_happiness_cost(city, *steps).unwrap()
})
.reduce(|a, b| a + b)
.reduce(|mut a, b| {
a.default += b.default;
a
})
.unwrap();

let available = &p.resources;
Expand Down
144 changes: 23 additions & 121 deletions client/src/payment_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ use crate::resource_ui::{new_resource_map, resource_name};
use crate::select_ui;
use crate::select_ui::{CountSelector, HasCountSelectableObject};
use macroquad::math::{bool, vec2};
use server::payment::{PaymentModel, SumPaymentOptions};
use server::payment::PaymentOptions;
use server::resource::ResourceType;
use server::resource_pile::{PaymentOptions, ResourcePile};
use std::cmp;
use std::cmp::min;
use server::resource_pile::ResourcePile;

#[derive(PartialEq, Eq, Debug, Clone)]
pub struct ResourcePayment {
Expand All @@ -36,63 +34,32 @@ impl HasCountSelectableObject for ResourcePayment {
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct Payment {
pub name: String,
pub model: PaymentModel,
pub options: PaymentOptions,
pub available: ResourcePile,
pub optional: bool,
pub current: Vec<ResourcePayment>,
pub discount_used: u32,
}

impl Payment {
#[must_use]
pub fn new(
model: &PaymentModel,
model: &PaymentOptions,
available: &ResourcePile,
name: &str,
optional: bool,
) -> Payment {
let mut discount_used = 0;
let resources = match model {
PaymentModel::Sum(options) => sum_payment(options, available),
PaymentModel::Resources(a) => {
let options = a.get_payment_options(available);
discount_used = a.discount - options.discount_left;
resource_payment(&options)
}
};

Self {
name: name.to_string(),
model: model.clone(),
options: model.clone(),
available: available.clone(),
optional,
current: resources,
discount_used,
current: resource_payment(model, available),
}
}

#[must_use]
pub fn new_gain(model: PaymentModel, name: &str) -> Payment {
let sum = if let PaymentModel::Sum(m) = &model {
m.clone()
} else {
panic!("No trade route reward")
};
let available = sum
.types_by_preference
.iter()
.map(|t| ResourcePile::of(*t, sum.cost))
.reduce(|a, b| a + b)
.expect("sum");

Payment {
name: name.to_string(),
model,
optional: false,
current: sum_payment(&sum, &available),
available,
discount_used: 0,
}
pub fn new_gain(options: &PaymentOptions, name: &str) -> Payment {
Self::new(options, &options.default, name, false)
}

pub fn to_resource_pile(&self) -> ResourcePile {
Expand Down Expand Up @@ -157,12 +124,12 @@ pub fn multi_payment_dialog(

for (i, payment) in payments.iter().enumerate() {
let name = &payment.name;
let model = payment.model.clone();
let types = show_types(&model);
let options = payment.options.clone();
let types = options.possible_resource_types();
let offset = vec2(0., i as f32 * -100.);
bottom_centered_text_with_offset(
rc,
&format!("{name} for {model}"),
&format!("{name} for {options}"),
offset + vec2(0., -30.),
);
let result = select_ui::count_dialog(
Expand Down Expand Up @@ -218,17 +185,17 @@ fn ok_tooltip(payments: &[Payment], mut available: ResourcePile) -> OkTooltip {
let mut invalid: Vec<String> = vec![];

for payment in payments {
let model = &payment.model;
let options = &payment.options;
let pile = payment.to_resource_pile();
let name = &payment.name;
let tooltip = if payment.optional && pile.is_empty() {
OkTooltip::Valid(format!("Pay nothing for {name}"))
} else if model.can_afford(&available) && model.is_valid_payment(&pile) {
} else if options.can_afford(&available) && options.is_valid_payment(&pile) {
// make sure that we can afford all the payments
available -= payment.to_resource_pile();
OkTooltip::Valid(format!("Pay {pile} for {name}"))
} else {
OkTooltip::Invalid(format!("You don't have {:?} for {}", payment.model, name))
OkTooltip::Invalid(format!("You don't have {:?} for {}", payment.options, name))
};
match tooltip {
OkTooltip::Valid(v) => valid.push(v),
Expand All @@ -255,46 +222,18 @@ fn replace_updated_payment(payment: &Payment, all: &[Payment]) -> Vec<Payment> {
.collect::<Vec<_>>()
}

fn sum_payment(a: &SumPaymentOptions, available: &ResourcePile) -> Vec<ResourcePayment> {
let mut cost_left = a.cost;

a.types_by_preference
.iter()
.map(|t| {
let have = available.get(*t);
let used = min(have, cost_left);
cost_left -= used;
ResourcePayment::new(*t, used, 0, have)
})
.collect()
}

#[must_use]
fn resource_payment(options: &PaymentOptions) -> Vec<ResourcePayment> {
fn resource_payment(options: &PaymentOptions, available: &ResourcePile) -> Vec<ResourcePayment> {
let mut resources: Vec<ResourcePayment> = new_resource_map(&options.default)
.into_iter()
.map(|e| {
let resource_type = e.0;
let amount = e.1;
match resource_type {
ResourceType::Gold => ResourcePayment {
resource: resource_type,
selectable: CountSelector {
current: amount,
min: amount,
max: amount,
},
},
_ => ResourcePayment {
resource: resource_type,
selectable: CountSelector {
current: amount,
min: cmp::max(
0,
amount as i32 - options.discount_left as i32 - options.gold_left as i32,
) as u32,
max: amount,
},
ResourcePayment {
resource: resource_type,
selectable: CountSelector {
current: e.1,
min: 0,
max: available.get(&resource_type),
},
}
})
Expand All @@ -304,49 +243,12 @@ fn resource_payment(options: &PaymentOptions) -> Vec<ResourcePayment> {
resources
}

#[must_use]
pub fn show_types(model: &PaymentModel) -> Vec<ResourceType> {
match model {
PaymentModel::Sum(options) => options.types_by_preference.clone(),
PaymentModel::Resources(options) => options.cost.types(),
}
}

pub fn plus(mut payment: Payment, t: ResourceType) -> Payment {
match payment.model {
PaymentModel::Sum(_) => {
payment.get_mut(t).selectable.current += 1;
}
PaymentModel::Resources(_) => {
{
let gold = payment.get_mut(ResourceType::Gold);
if gold.selectable.current > 0 {
gold.selectable.current -= 1;
} else {
payment.discount_used += 1;
}
}
payment.get_mut(t).selectable.current += 1;
}
}
payment.get_mut(t).selectable.current += 1;
payment
}

pub fn minus(mut payment: Payment, t: ResourceType) -> Payment {
match payment.model {
PaymentModel::Sum(_) => {
payment.get_mut(t).selectable.current -= 1;
}
PaymentModel::Resources(_) => {
{
if payment.discount_used > 0 {
payment.discount_used -= 1;
} else {
payment.get_mut(ResourceType::Gold).selectable.current += 1;
}
}
payment.get_mut(t).selectable.current -= 1;
}
}
payment.get_mut(t).selectable.current -= 1;
payment
}
8 changes: 4 additions & 4 deletions server/src/ability_initializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ pub(crate) trait AbilityInitializerSetup: Sized {
for (request, payment) in requests.iter().zip(payments.iter()) {
let zero_payment = payment.is_empty() && request.optional;
assert!(
zero_payment || request.model.is_valid_payment(payment),
zero_payment || request.options.is_valid_payment(payment),
"Invalid payment"
);
game.players[player_index].loose_resources(payment.clone());
Expand Down Expand Up @@ -226,13 +226,13 @@ pub(crate) trait AbilityInitializerSetup: Sized {
move |game, player_index, _player_name| {
let req = request(game, player_index);
if let Some(r) = &req {
if r.model.possible_resource_types().len() == 1 {
if r.options.possible_resource_types().len() == 1 {
let player_name = game.players[player_index].get_name();
g(
game,
player_index,
&player_name,
&r.model.default_payment(),
&r.options.default_payment(),
false,
);
return None;
Expand All @@ -243,7 +243,7 @@ pub(crate) trait AbilityInitializerSetup: Sized {
move |game, player_index, player_name, action, request| {
if let CustomPhaseRequest::Reward(request) = &request {
if let CustomPhaseEventAction::Reward(reward) = action {
assert!(request.model.is_valid_payment(&reward), "Invalid payment");
assert!(request.options.is_valid_payment(&reward), "Invalid payment");
gain_reward(game, player_index, player_name, &reward, true);
return;
}
Expand Down
Loading

0 comments on commit 181dc6d

Please sign in to comment.