Skip to content

Commit 9e9aabd

Browse files
authored
pestilence (#167)
1 parent 3a00e12 commit 9e9aabd

39 files changed

+2956
-1661
lines changed

client/src/event_ui.rs

+18-14
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,21 @@ use server::events::EventOrigin;
99

1010
#[must_use]
1111
pub fn event_help(rc: &RenderContext, origin: &EventOrigin, do_break: bool) -> Vec<String> {
12-
let h = match origin {
13-
EventOrigin::Advance(a) => get_advance(a).description,
14-
EventOrigin::Wonder(w) => get_wonder(w).description,
15-
EventOrigin::Builtin(b) => get_builtin(b).description,
12+
let mut h = vec![origin.name()];
13+
h.extend(match origin {
14+
EventOrigin::Advance(a) => vec![get_advance(a).description],
15+
EventOrigin::Wonder(w) => vec![get_wonder(w).description],
16+
EventOrigin::Builtin(b) => vec![get_builtin(b).description],
1617
EventOrigin::Incident(id) => get_incident(*id).description(),
17-
EventOrigin::Leader(l) => {
18+
EventOrigin::Leader(l) => vec![{
1819
let l = rc.shown_player.get_leader(l).unwrap();
1920
// todo: leader should have a 2 event sources - no each event source should have a description
2021
format!(
2122
"{}, {}",
2223
l.first_ability_description, l.second_ability_description
2324
)
24-
}
25-
EventOrigin::SpecialAdvance(s) => {
25+
}],
26+
EventOrigin::SpecialAdvance(s) => vec![{
2627
let s = rc
2728
.shown_player
2829
.civilization
@@ -31,15 +32,18 @@ pub fn event_help(rc: &RenderContext, origin: &EventOrigin, do_break: bool) -> V
3132
.find(|sa| &sa.name == s)
3233
.unwrap();
3334
s.description.clone()
34-
}
35-
};
36-
let h = format!("{}: {}", origin.name(), h);
35+
}],
36+
});
3737
if do_break {
38-
let mut result = vec![];
39-
break_text(&h, 30, &mut result);
40-
result
38+
h.iter()
39+
.flat_map(|s| {
40+
let mut result = vec![];
41+
break_text(s, 30, &mut result);
42+
result
43+
})
44+
.collect()
4145
} else {
42-
vec![h]
46+
h
4347
}
4448
}
4549

server/src/barbarians.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ pub(crate) fn set_info(
310310
let mut state = BarbariansEventState::new();
311311
init(&mut state, game, p.player);
312312
game.current_custom_phase_mut().barbarians = Some(state);
313-
game.add_to_last_log_item(&name);
313+
game.add_info_log_item(&format!("Base effect: {name}"));
314314
}
315315
},
316316
)

server/src/combat.rs

+1
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,7 @@ pub mod tests {
777777
wonders_left: Vec::new(),
778778
wonder_amount_left: 0,
779779
incidents_left: Vec::new(),
780+
permanent_incident_effects: Vec::new(),
780781
undo_context_stack: Vec::new(),
781782
}
782783
}

server/src/content.rs

+3
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,8 @@ pub mod civilizations;
1616
pub mod custom_actions;
1717
pub mod custom_phase_actions;
1818
pub mod incidents;
19+
mod incidents_1;
20+
mod incidents_2;
21+
mod incidents_5;
1922
pub mod trade_routes;
2023
pub mod wonders;

server/src/content/advances_construction.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ fn engineering() -> AdvanceBuilder {
3131
fn sanitation() -> AdvanceBuilder {
3232
Advance::builder(
3333
"Sanitation",
34-
"When Recruiting, you may spend 1 mood token to pay for 1 Settler.",
34+
"When Recruiting, you may spend 1 mood token to pay for 1 Settler. Ignore Pestilence and Epidemics events.",
3535
)
3636
.with_advance_bonus(MoodToken)
3737
.add_player_event_listener(

server/src/content/advances_democracy.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ fn free_economy() -> AdvanceBuilder {
5656
.add_custom_action(FreeEconomyCollect)
5757
.add_player_event_listener(
5858
|event| &mut event.is_playing_action_available,
59-
|available, action_type, player| {
60-
if matches!(action_type, PlayingActionType::Collect) && player.played_once_per_turn_actions.contains(&FreeEconomyCollect) {
59+
|available, game, i| {
60+
let p = game.get_player(i.player);
61+
if matches!(i.action_type, PlayingActionType::Collect) && p.played_once_per_turn_actions.contains(&FreeEconomyCollect) {
6162
*available = false;
6263
}
6364
},

server/src/content/builtin.rs

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::barbarians::barbarians_bonus;
44
use crate::combat_listeners::{
55
choose_carried_units_casualties, choose_fighter_casualties, offer_retreat, place_settler,
66
};
7+
use crate::content::incidents_1::pestilence_permanent_effect;
78
use crate::events::EventOrigin;
89
use crate::pirates::{pirates_bonus, pirates_round_bonus};
910

@@ -65,6 +66,7 @@ pub fn get_all() -> Vec<Builtin> {
6566
barbarians_bonus(),
6667
pirates_bonus(),
6768
pirates_round_bonus(),
69+
pestilence_permanent_effect(),
6870
]
6971
}
7072

server/src/content/incidents.rs

+16-176
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
1-
use crate::content::custom_phase_actions::{PlayerRequest, PositionRequest, ResourceRewardRequest};
2-
use crate::game::Game;
3-
use crate::incident::{Incident, IncidentBaseEffect, IncidentBuilder};
4-
use crate::payment::PaymentOptions;
5-
use crate::player_events::IncidentTarget;
6-
use crate::resource::ResourceType;
7-
use crate::unit::UnitType;
1+
use crate::content::incidents_1::{good_year, pestilence};
2+
use crate::content::incidents_2::population_boom;
3+
use crate::content::incidents_5::successful_year;
4+
use crate::incident::Incident;
85
use itertools::Itertools;
96
use std::vec;
107

118
#[must_use]
129
pub(crate) fn get_all() -> Vec<Incident> {
13-
let all = vec![good_year(), population_boom(), successful_year()]
14-
.into_iter()
15-
.flatten()
16-
.collect_vec();
10+
let all = vec![
11+
// 1+
12+
pestilence(),
13+
good_year(),
14+
// 11+
15+
population_boom(),
16+
// 51+
17+
successful_year(),
18+
]
19+
.into_iter()
20+
.flatten()
21+
.collect_vec();
1722
assert_eq!(
1823
all.iter().unique_by(|i| i.id).count(),
1924
all.len(),
@@ -22,171 +27,6 @@ pub(crate) fn get_all() -> Vec<Incident> {
2227
all
2328
}
2429

25-
fn population_boom() -> Vec<Incident> {
26-
let mut b = Incident::builder(
27-
28,
28-
"Population Boom",
29-
"-",
30-
IncidentBaseEffect::BarbariansMove,
31-
);
32-
b = select_settler(b, 2, |game, _| {
33-
game.current_custom_phase().is_active_player()
34-
});
35-
b = b.add_incident_player_request(
36-
IncidentTarget::ActivePlayer,
37-
1,
38-
|game, player_index, _incident| {
39-
let choices = game
40-
.players
41-
.iter()
42-
.filter(|p| p.available_units().settlers > 0 && p.index != player_index)
43-
.map(|p| p.index)
44-
.collect_vec();
45-
46-
if choices.is_empty() {
47-
None
48-
} else {
49-
Some(PlayerRequest::new(
50-
choices,
51-
"Select a unit to gain 1 settler",
52-
))
53-
}
54-
},
55-
|game, c| {
56-
game.add_info_log_item(&format!(
57-
"{} was selected to gain 1 settler from Population Boom",
58-
game.get_player(c.choice).get_name()
59-
));
60-
game.current_custom_phase_mut().selected_player = Some(c.choice);
61-
},
62-
);
63-
b = select_settler(b, 0, |game, player| {
64-
let c = game.current_custom_phase();
65-
c.selected_player == Some(player)
66-
});
67-
vec![b.build()]
68-
}
69-
70-
fn select_settler(
71-
b: IncidentBuilder,
72-
priority: i32,
73-
pred: impl Fn(&Game, usize) -> bool + 'static + Clone,
74-
) -> IncidentBuilder {
75-
b.add_incident_position_request(
76-
IncidentTarget::AllPlayers,
77-
priority,
78-
move |game, player_index, _incident| {
79-
let p = game.get_player(player_index);
80-
if pred(game, player_index) && p.available_units().settlers > 0 {
81-
Some(PositionRequest::new(
82-
p.cities.iter().map(|c| c.position).collect(),
83-
Some("Select a city to gain 1 settler".to_string()),
84-
))
85-
} else {
86-
None
87-
}
88-
},
89-
|game, s| {
90-
game.add_info_log_item(&format!(
91-
"{} gained 1 settler in {}",
92-
s.player_name, s.choice
93-
));
94-
game.get_player_mut(s.player_index)
95-
.add_unit(s.choice, UnitType::Settler);
96-
},
97-
)
98-
}
99-
100-
fn successful_year() -> Vec<Incident> {
101-
vec![Incident::builder(
102-
54,
103-
"A successful year",
104-
"-",
105-
IncidentBaseEffect::PiratesSpawnAndRaid,
106-
)
107-
.add_incident_resource_request(
108-
IncidentTarget::AllPlayers,
109-
0,
110-
|game, player_index, _incident| {
111-
let player_to_city_num = game
112-
.players
113-
.iter()
114-
.map(|p| p.cities.len())
115-
.collect::<Vec<_>>();
116-
117-
let min_cities = player_to_city_num.iter().min().unwrap_or(&0);
118-
let max_cities = player_to_city_num.iter().max().unwrap_or(&0);
119-
if min_cities == max_cities {
120-
return Some(ResourceRewardRequest::new(
121-
PaymentOptions::sum(1, &[ResourceType::Food]),
122-
"-".to_string(),
123-
));
124-
}
125-
126-
let cities = game.players[player_index].cities.len();
127-
if cities == *min_cities {
128-
Some(ResourceRewardRequest::new(
129-
PaymentOptions::sum((max_cities - min_cities) as u32, &[ResourceType::Food]),
130-
"-".to_string(),
131-
))
132-
} else {
133-
None
134-
}
135-
},
136-
|_game, s| {
137-
vec![format!(
138-
"{} gained {} from A successful year",
139-
s.player_name, s.choice
140-
)]
141-
},
142-
)
143-
.build()]
144-
}
145-
146-
fn good_year() -> Vec<Incident> {
147-
vec![
148-
add_good_year(
149-
IncidentTarget::AllPlayers,
150-
Incident::builder(
151-
9,
152-
"A good year",
153-
"Every player gains 1 food",
154-
IncidentBaseEffect::BarbariansSpawn,
155-
),
156-
),
157-
add_good_year(
158-
IncidentTarget::ActivePlayer,
159-
Incident::builder(
160-
10,
161-
"A good year",
162-
"You gain 1 food",
163-
IncidentBaseEffect::BarbariansSpawn,
164-
),
165-
),
166-
]
167-
}
168-
169-
fn add_good_year(target: IncidentTarget, builder: IncidentBuilder) -> Incident {
170-
builder
171-
.add_incident_resource_request(
172-
target,
173-
0,
174-
|_game, _player_index, _incident| {
175-
Some(ResourceRewardRequest::new(
176-
PaymentOptions::sum(1, &[ResourceType::Food]),
177-
"Gain 1 food".to_string(),
178-
))
179-
},
180-
|_game, s| {
181-
vec![format!(
182-
"{} gained {} from A good year",
183-
s.player_name, s.choice
184-
)]
185-
},
186-
)
187-
.build()
188-
}
189-
19030
///
19131
/// # Panics
19232
/// Panics if incident does not exist

0 commit comments

Comments
 (0)