Skip to content

Commit 214724e

Browse files
authored
incidents & test cleanup (#174)
1 parent 6b34aeb commit 214724e

File tree

287 files changed

+6801
-737
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

287 files changed

+6801
-737
lines changed

client/src/city_ui.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ pub fn city_labels(game: &Game, city: &City) -> Vec<String> {
213213
[
214214
vec![format!(
215215
"City: {}, {}, {} {}",
216-
game.get_player(city.player_index).get_name(),
216+
game.player_name(city.player_index),
217217
city.size(),
218218
match city.mood_state {
219219
MoodState::Happy => "Happy",
@@ -234,7 +234,7 @@ pub fn city_labels(game: &Game, city: &City) -> Vec<String> {
234234
if city.player_index == *o {
235235
b.name().to_string()
236236
} else {
237-
format!("{} (owned by {})", b.name(), game.get_player(*o).get_name())
237+
format!("{} (owned by {})", b.name(), game.player_name(*o))
238238
}
239239
})
240240
})

server/src/ability_initializer.rs

+90-72
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ pub(crate) trait AbilityInitializerSetup: Sized {
150150
self
151151
}
152152

153-
fn add_player_event_listener<T, U, V, E, F>(self, event: E, listener: F, priority: i32) -> Self
153+
fn add_player_event_listener<T, U, V, E, F>(self, event: E, priority: i32, listener: F) -> Self
154154
where
155155
T: Clone + PartialEq,
156156
E: Fn(&mut PlayerEvents) -> &mut Event<T, U, V> + 'static + Clone,
@@ -190,16 +190,12 @@ pub(crate) trait AbilityInitializerSetup: Sized {
190190
F: Fn(&mut T, &U, &V) + 'static + Clone,
191191
{
192192
let id = self.get_key().id();
193-
self.add_player_event_listener(
194-
event,
195-
move |value, u, v| {
196-
if !get_info(value).contains_key(&id) {
197-
listener(value, u, v);
198-
get_info(value).insert(id.clone(), "used".to_string());
199-
}
200-
},
201-
priority,
202-
)
193+
self.add_player_event_listener(event, priority, move |value, u, v| {
194+
if !get_info(value).contains_key(&id) {
195+
listener(value, u, v);
196+
get_info(value).insert(id.clone(), "used".to_string());
197+
}
198+
})
203199
}
204200

205201
fn add_current_event_listener<E, V>(
@@ -217,72 +213,89 @@ pub(crate) trait AbilityInitializerSetup: Sized {
217213
E: Fn(&mut PlayerEvents) -> &mut CurrentEvent<V> + 'static + Clone,
218214
{
219215
let origin = self.get_key();
220-
self.add_player_event_listener(
221-
event,
222-
move |game, i, details| {
223-
let player_index = i.player;
224-
let player_name = game.players[player_index].get_name();
225-
226-
if let Some(mut phase) = game.current_events.pop() {
227-
if let Some(ref c) = phase.player.handler {
228-
if let Some(ref action) = c.response {
229-
if c.priority == priority {
230-
let mut current = phase.clone();
231-
current
232-
.player
233-
.handler
234-
.as_mut()
235-
.expect("current missing")
236-
.response = None;
237-
if can_undo(&current.event_type) {
238-
game.undo_context_stack
239-
.push(UndoContext::Event(Box::new(current)));
240-
}
241-
let r = c.request.clone();
242-
let a = action.clone();
243-
phase.player.handler = None;
244-
game.current_events.push(phase);
245-
end_custom_phase.clone()(
246-
game,
247-
player_index,
248-
&player_name,
249-
a,
250-
r,
251-
details,
252-
);
253-
return;
216+
self.add_player_event_listener(event, priority, move |game, i, details| {
217+
let player_index = i.player;
218+
let player_name = game.player_name(player_index);
219+
220+
if let Some(mut phase) = game.current_events.pop() {
221+
if let Some(ref c) = phase.player.handler {
222+
if let Some(ref action) = c.response {
223+
if c.priority == priority {
224+
let mut current = phase.clone();
225+
current
226+
.player
227+
.handler
228+
.as_mut()
229+
.expect("current missing")
230+
.response = None;
231+
if can_undo(&current.event_type) {
232+
game.undo_context_stack
233+
.push(UndoContext::Event(Box::new(current)));
254234
}
235+
let r = c.request.clone();
236+
let a = action.clone();
237+
phase.player.handler = None;
238+
game.current_events.push(phase);
239+
end_custom_phase.clone()(
240+
game,
241+
player_index,
242+
&player_name,
243+
a,
244+
r,
245+
details,
246+
);
247+
return;
255248
}
256249
}
257-
let is_current = phase.player.handler.is_some();
258-
game.current_events.push(phase);
259-
if is_current {
260-
return;
261-
}
262250
}
263-
264-
if game
265-
.current_event_player()
266-
.last_priority_used
267-
.is_some_and(|last| last < priority)
268-
{
269-
// already handled before
251+
let is_current = phase.player.handler.is_some();
252+
game.current_events.push(phase);
253+
if is_current {
270254
return;
271255
}
256+
}
257+
258+
if game
259+
.current_event_player()
260+
.last_priority_used
261+
.is_some_and(|last| last < priority)
262+
{
263+
// already handled before
264+
return;
265+
}
266+
267+
if let Some(request) = start_custom_phase(game, player_index, &player_name, details) {
268+
let s = game.current_event_mut();
269+
s.player.last_priority_used = Some(priority);
270+
s.player.handler = Some(CurrentEventHandler {
271+
priority,
272+
request: request.clone(),
273+
response: None,
274+
origin: origin.clone(),
275+
});
276+
};
277+
})
278+
}
272279

273-
if let Some(request) = start_custom_phase(game, player_index, &player_name, details)
274-
{
275-
let s = game.current_event_mut();
276-
s.player.last_priority_used = Some(priority);
277-
s.player.handler = Some(CurrentEventHandler {
278-
priority,
279-
request: request.clone(),
280-
response: None,
281-
origin: origin.clone(),
282-
});
283-
};
284-
},
280+
fn add_simple_current_event_listener<V, E, F>(
281+
self,
282+
event: E,
283+
priority: i32,
284+
listener: F,
285+
) -> Self
286+
where
287+
E: Fn(&mut PlayerEvents) -> &mut CurrentEvent<V> + 'static + Clone,
288+
F: Fn(&mut Game, usize, &str, &V) + 'static + Clone,
289+
{
290+
self.add_current_event_listener(
291+
event,
285292
priority,
293+
move |game, player_index, player_name, details| {
294+
// only for the listener
295+
listener(game, player_index, player_name, details);
296+
None
297+
},
298+
|_, _, _, _, _, _| {},
286299
)
287300
}
288301

@@ -300,7 +313,12 @@ pub(crate) trait AbilityInitializerSetup: Sized {
300313
event,
301314
priority,
302315
move |game, player_index, _player_name, details| {
303-
request(game, player_index, details).map(CurrentEventRequest::Payment)
316+
request(game, player_index, details)
317+
.filter(|r| {
318+
r.iter()
319+
.any(|r| game.get_player(player_index).can_afford(&r.cost))
320+
})
321+
.map(CurrentEventRequest::Payment)
304322
},
305323
move |game, player_index, player_name, action, request, details| {
306324
if let CurrentEventRequest::Payment(requests) = &request {
@@ -350,7 +368,7 @@ pub(crate) trait AbilityInitializerSetup: Sized {
350368
let req = request(game, player_index, details);
351369
if let Some(r) = &req {
352370
if r.reward.possible_resource_types().len() == 1 {
353-
let player_name = game.players[player_index].get_name();
371+
let player_name = game.player_name(player_index);
354372
let r = r.reward.default_payment();
355373
for log in g(
356374
game,
@@ -689,7 +707,7 @@ pub(crate) trait AbilityInitializerSetup: Sized {
689707
game,
690708
&SelectedChoice::new(
691709
player_index,
692-
&game.get_player(player_index).get_name(),
710+
&game.player_name(player_index),
693711
false,
694712
m.choices.clone(),
695713
details,

server/src/action.rs

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use crate::status_phase::play_status_phase;
2222
use crate::undo::{redo, undo, DisembarkUndoContext, UndoContext};
2323
use crate::unit::MovementAction::{Move, Stop};
2424
use crate::unit::{get_current_move, MovementAction};
25+
use crate::wonder::draw_wonder_card;
2526
use itertools::Itertools;
2627
use serde::{Deserialize, Serialize};
2728

@@ -124,6 +125,9 @@ pub(crate) fn execute_custom_phase_action(
124125
) {
125126
use CurrentEventType::*;
126127
match details {
128+
DrawWonderCard => {
129+
draw_wonder_card(game, player_index);
130+
}
127131
ExploreResolution(r) => {
128132
ask_explore_resolution(game, player_index, r);
129133
}

server/src/advance.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ impl Bonus {
139139
///
140140
/// Panics if advance does not exist
141141
pub fn do_advance(game: &mut Game, advance: &Advance, player_index: usize) {
142-
game.trigger_command_event(player_index, |e| &mut e.on_advance, &advance.name);
143142
(advance.listeners.initializer)(game, player_index);
144143
(advance.listeners.one_time_initializer)(game, player_index);
145144
let name = advance.name.clone();
@@ -190,7 +189,7 @@ pub(crate) fn advance_with_incident_token(
190189
pub(crate) fn gain_advance(game: &mut Game, player_index: usize, info: &AdvanceInfo) {
191190
if game.trigger_current_event(
192191
&[player_index],
193-
|e| &mut e.on_advance_custom_phase,
192+
|e| &mut e.on_advance,
194193
info,
195194
CurrentEventType::Advance,
196195
None,

server/src/barbarians.rs

+24-10
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,12 @@ pub(crate) fn barbarians_spawn(mut builder: IncidentBuilder) -> IncidentBuilder
101101
IncidentTarget::ActivePlayer,
102102
BASE_EFFECT_PRIORITY + 1,
103103
|game, _player_index, _i| {
104+
let r = possible_barbarians_reinforcements(game);
105+
if r.is_empty() {
106+
game.add_info_log_item("Barbarians cannot reinforce");
107+
}
104108
Some(new_position_request(
105-
possible_barbarians_reinforcements(game),
109+
r,
106110
1..=1,
107111
"Select a position for the additional Barbarian unit",
108112
))
@@ -140,7 +144,9 @@ pub(crate) fn barbarians_spawn(mut builder: IncidentBuilder) -> IncidentBuilder
140144

141145
pub(crate) fn barbarians_move(mut builder: IncidentBuilder) -> IncidentBuilder {
142146
builder = set_info(builder, "Barbarians move", |state, game, human| {
143-
if !get_movable_units(game, human, state).is_empty() {
147+
if get_movable_units(game, human, state).is_empty() {
148+
game.add_info_log_item("Barbarians cannot move - will try to spawn a new city instead");
149+
} else {
144150
state.move_units = true;
145151
}
146152
});
@@ -221,10 +227,10 @@ pub(crate) fn barbarians_move(mut builder: IncidentBuilder) -> IncidentBuilder {
221227
},
222228
);
223229
}
224-
builder.add_incident_listener(
230+
builder.add_simple_incident_listener(
225231
IncidentTarget::ActivePlayer,
226232
BASE_EFFECT_PRIORITY,
227-
|game, player| {
233+
|game, player, _| {
228234
let s = get_barbarian_state(game);
229235
if s.move_units && get_movable_units(game, player, &s).is_empty() {
230236
// after all moves are done
@@ -301,18 +307,18 @@ fn barbarian_march_steps(
301307
pub(crate) fn set_info(
302308
builder: IncidentBuilder,
303309
event_name: &str,
304-
init: impl Fn(&mut BarbariansEventState, &Game, usize) + 'static + Clone,
310+
init: impl Fn(&mut BarbariansEventState, &mut Game, usize) + 'static + Clone,
305311
) -> IncidentBuilder {
306312
let name = event_name.to_string();
307-
builder.add_incident_listener(
313+
builder.add_simple_incident_listener(
308314
IncidentTarget::ActivePlayer,
309315
BASE_EFFECT_PRIORITY + 200,
310-
move |game, player| {
316+
move |game, player, _| {
311317
if game.current_event().barbarians.is_none() {
318+
game.add_info_log_item(&format!("Base effect: {name}"));
312319
let mut state = BarbariansEventState::new();
313320
init(&mut state, game, player);
314321
game.current_event_mut().barbarians = Some(state);
315-
game.add_info_log_item(&format!("Base effect: {name}"));
316322
}
317323
},
318324
)
@@ -323,8 +329,16 @@ fn add_barbarians_city(builder: IncidentBuilder) -> IncidentBuilder {
323329
IncidentTarget::ActivePlayer,
324330
BASE_EFFECT_PRIORITY + 100,
325331
move |game, player_index, _i| {
326-
(!get_barbarian_state(game).move_units).then_some(new_position_request(
327-
possible_barbarians_spawns(game, game.get_player(player_index)),
332+
if get_barbarian_state(game).move_units {
333+
return None;
334+
}
335+
336+
let choices = possible_barbarians_spawns(game, game.get_player(player_index));
337+
if choices.is_empty() {
338+
game.add_info_log_item("Barbarians cannot spawn a new city");
339+
}
340+
Some(new_position_request(
341+
choices,
328342
1..=1,
329343
"Select a position for the new city and infantry unit",
330344
))

0 commit comments

Comments
 (0)