Skip to content

Commit 64fe466

Browse files
authored
cultural influence (#158)
1 parent 2f340f6 commit 64fe466

25 files changed

+1411
-254
lines changed

client/src/influence_ui.rs

+31-33
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use server::city::City;
1616
use server::content::custom_actions::CustomAction;
1717
use server::game::CulturalInfluenceResolution;
1818
use server::player::Player;
19+
use server::player_events::InfluenceCulturePossible;
1920
use server::playing_actions::{InfluenceCultureAttempt, PlayingAction};
2021
use server::position::Position;
2122
use server::resource::ResourceType;
@@ -77,46 +78,43 @@ fn show_city(
7778
closest_city_pos
7879
};
7980

80-
if let Some(cost) = rc.game.influence_culture_boost_cost(
81+
let info = rc.game.influence_culture_boost_cost(
8182
player.index,
8283
start_position,
8384
city.player_index,
8485
city.position,
8586
*b,
86-
) {
87-
if player.can_afford(&cost) {
88-
let name = b.name();
89-
let _ = rc.with_camera(CameraMode::World, |rc| {
90-
draw_circle_lines(center.x, center.y, BUILDING_SIZE, 1., WHITE);
91-
show_tooltip_for_circle(
92-
rc,
93-
&format!("Attempt Influence {name} for {cost}"),
94-
center.to_vec2(),
95-
BUILDING_SIZE,
96-
);
97-
StateUpdate::None
98-
});
87+
);
88+
if !matches!(info.possible, InfluenceCulturePossible::Impossible) {
89+
let name = b.name();
90+
let _ = rc.with_camera(CameraMode::World, |rc| {
91+
draw_circle_lines(center.x, center.y, BUILDING_SIZE, 1., WHITE);
92+
show_tooltip_for_circle(
93+
rc,
94+
&format!("Attempt Influence {name} for {}", info.range_boost_cost),
95+
center.to_vec2(),
96+
BUILDING_SIZE,
97+
);
98+
StateUpdate::None
99+
});
99100

100-
if is_in_circle(mouse_pos, center, BUILDING_SIZE)
101-
&& is_mouse_button_pressed(MouseButton::Left)
102-
{
103-
let attempt = InfluenceCultureAttempt {
104-
starting_city_position: start_position,
105-
target_player_index: city.player_index,
106-
target_city_position: city.position,
107-
city_piece: *b,
108-
};
109-
let action = match custom.custom {
110-
BaseOrCustomAction::Base => {
111-
PlayingAction::InfluenceCultureAttempt(attempt)
112-
}
113-
BaseOrCustomAction::Custom { .. } => PlayingAction::Custom(
114-
CustomAction::ArtsInfluenceCultureAttempt(attempt),
115-
),
116-
};
101+
if is_in_circle(mouse_pos, center, BUILDING_SIZE)
102+
&& is_mouse_button_pressed(MouseButton::Left)
103+
{
104+
let attempt = InfluenceCultureAttempt {
105+
starting_city_position: start_position,
106+
target_player_index: city.player_index,
107+
target_city_position: city.position,
108+
city_piece: *b,
109+
};
110+
let action = match custom.custom {
111+
BaseOrCustomAction::Base => PlayingAction::InfluenceCultureAttempt(attempt),
112+
BaseOrCustomAction::Custom { .. } => PlayingAction::Custom(
113+
CustomAction::ArtsInfluenceCultureAttempt(attempt),
114+
),
115+
};
117116

118-
return Some(StateUpdate::Execute(Action::Playing(action)));
119-
}
117+
return Some(StateUpdate::Execute(Action::Playing(action)));
120118
}
121119
}
122120

server/src/content/advances_autocracy.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,41 @@ use crate::content::custom_actions::CustomActionType::{AbsolutePower, ForcedLabo
66
pub(crate) fn autocracy() -> AdvanceGroup {
77
advance_group_builder(
88
"Autocracy",
9-
vec![nationalism(), absolute_power(), forced_labor()],
9+
vec![
10+
nationalism(),
11+
totalitarianism(),
12+
absolute_power(),
13+
forced_labor(),
14+
],
1015
)
1116
}
1217

1318
fn nationalism() -> AdvanceBuilder {
1419
Advance::builder("Nationalism", "todo")
1520
}
1621

22+
fn totalitarianism() -> AdvanceBuilder {
23+
Advance::builder(
24+
"Totalitarianism",
25+
"Attempts to influence your cities with Army Units may not be boosted by culture tokens",
26+
)
27+
.add_player_event_listener(
28+
|event| &mut event.on_influence_culture_attempt,
29+
|info, city, game| {
30+
if info.is_defender
31+
&& game
32+
.get_player(city.player_index)
33+
.get_units(city.position)
34+
.iter()
35+
.any(|u| u.unit_type.is_army_unit())
36+
{
37+
info.set_no_boost();
38+
}
39+
},
40+
0,
41+
)
42+
}
43+
1744
fn absolute_power() -> AdvanceBuilder {
1845
Advance::builder(
1946
"Absolute Power",

server/src/content/advances_construction.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub(crate) fn construction() -> AdvanceGroup {
2424
fn engineering() -> AdvanceBuilder {
2525
Advance::builder(
2626
"Engineering",
27-
"Immediately draw 1 wonder, May Construct wonder happy cities",
27+
"Immediately draw 1 wonder card. May Construct wonders in happy cities",
2828
)
2929
.add_one_time_ability_initializer(Game::draw_wonder_card)
3030
.add_custom_action(ConstructWonder)

server/src/content/advances_culture.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::resource_pile::ResourcePile;
1414
use std::vec;
1515

1616
pub(crate) fn culture() -> AdvanceGroup {
17-
advance_group_builder("Culture", vec![arts(), sports(), theaters()])
17+
advance_group_builder("Culture", vec![arts(), sports(), monuments(), theaters()])
1818
}
1919

2020
fn arts() -> AdvanceBuilder {
@@ -30,6 +30,21 @@ fn sports() -> AdvanceBuilder {
3030
.add_custom_action(CustomActionType::Sports)
3131
}
3232

33+
fn monuments() -> AdvanceBuilder {
34+
Advance::builder("Monuments", "Immediately draw 1 wonder card. Your cities with wonders may not be the target of influence culture attempts")
35+
.add_one_time_ability_initializer(Game::draw_wonder_card)
36+
.with_advance_bonus(CultureToken)
37+
.add_player_event_listener(
38+
|event| &mut event.on_influence_culture_attempt,
39+
|info, city, _| {
40+
if info.is_defender && !city.pieces.wonders.is_empty() {
41+
info.set_impossible();
42+
}
43+
},
44+
1,
45+
)
46+
}
47+
3348
fn theaters() -> AdvanceBuilder {
3449
Advance::builder("Theaters",
3550
"Once per turn, as a free action, you may convert 1 culture token into 1 mood token, or 1 mood token into 1 culture token")

server/src/content/advances_democracy.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
use crate::ability_initializer::AbilityInitializerSetup;
22
use crate::advance::{Advance, AdvanceBuilder};
3+
use crate::city::MoodState;
34
use crate::content::advances::{advance_group_builder, AdvanceGroup};
45
use crate::content::custom_actions::CustomActionType::{
56
CivilRights, FreeEconomyCollect, VotingIncreaseHappiness,
67
};
78
use crate::playing_actions::PlayingActionType;
89

910
pub(crate) fn democracy() -> AdvanceGroup {
10-
advance_group_builder("Democracy", vec![voting(), civil_rights(), free_economy()])
11+
advance_group_builder(
12+
"Democracy",
13+
vec![
14+
voting(),
15+
separation_of_power(),
16+
civil_rights(),
17+
free_economy(),
18+
],
19+
)
1120
}
1221

1322
fn voting() -> AdvanceBuilder {
@@ -18,6 +27,22 @@ fn voting() -> AdvanceBuilder {
1827
.add_custom_action(VotingIncreaseHappiness)
1928
}
2029

30+
fn separation_of_power() -> AdvanceBuilder {
31+
Advance::builder(
32+
"Separation of Power",
33+
"Attempts to influence your happy cities may not be boosted by culture tokens",
34+
)
35+
.add_player_event_listener(
36+
|event| &mut event.on_influence_culture_attempt,
37+
|info, city, _| {
38+
if matches!(city.mood_state, MoodState::Happy) {
39+
info.set_no_boost();
40+
}
41+
},
42+
0,
43+
)
44+
}
45+
2146
fn civil_rights() -> AdvanceBuilder {
2247
Advance::builder(
2348
"Civil Rights",

server/src/content/advances_theocracy.rs

+45-7
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,48 @@ pub(crate) fn theocracy() -> AdvanceGroup {
1010
"Theocracy",
1111
vec![
1212
dogma(),
13-
Advance::builder("Dedication", "todo"),
14-
Advance::builder("Conversion", "todo"),
13+
devotion(),
14+
conversion(),
1515
Advance::builder("Fanaticism", "todo"),
1616
],
1717
)
1818
}
1919

20+
fn conversion() -> AdvanceBuilder {
21+
Advance::builder("Conversion", "You add +1 to your Influence Culture roll and gain 1 culture token when you make a successful Influence Culture attempt.")
22+
.add_player_event_listener(
23+
|event| &mut event.on_influence_culture_attempt,
24+
|info, _, _| {
25+
if !info.is_defender {
26+
info.roll_boost += 1;
27+
info.info.log.push("Player gets +1 to Influence Culture roll for Conversion Advance".to_string());
28+
}
29+
},
30+
0,
31+
)
32+
.add_player_event_listener(
33+
|event| &mut event.on_influence_culture_success,
34+
|c, _, ()| {
35+
c.gain_resources(ResourcePile::culture_tokens(1));
36+
c.add_info_log_item("Player gained 1 culture token for a successful Influence Culture attempt for Conversion Advance");
37+
},
38+
0,
39+
)
40+
}
41+
2042
fn dogma() -> AdvanceBuilder {
2143
Advance::builder("Dogma", "Whenever you Construct a new Temple, either through the Construct Action or through playing of cards, you may immediately get a Theocracy Advance for free, marking it with a cube from your Event tracker as normal.
2244
You are now limited to a maximum of 2 ideas. If you have more than 2 ideas when
2345
getting this Advance, you must immediately reduce down to 2.
2446
Note: Dogma Advance does not apply when you conquer a city with a Temple.")
2547
.add_one_time_ability_initializer(|game, player_index| {
26-
let p = & mut game.players[player_index];
48+
let p = &mut game.players[player_index];
2749
p.resource_limit.ideas = 2;
2850
p.gain_resources(ResourcePile::ideas(0)); // to trigger the limit
29-
})
30-
.add_ability_undo_deinitializer(|game, player_index| {
31-
game.players[player_index].resource_limit.ideas = 7;
32-
})
51+
})
52+
.add_ability_undo_deinitializer(|game, player_index| {
53+
game.players[player_index].resource_limit.ideas = 7;
54+
})
3355
.add_advance_reward_request_listener(
3456
|event| &mut event.on_construct,
3557
0,
@@ -63,3 +85,19 @@ fn dogma() -> AdvanceBuilder {
6385
},
6486
)
6587
}
88+
89+
fn devotion() -> AdvanceBuilder {
90+
Advance::builder(
91+
"Devotion",
92+
"Attempts to influence your cities with a Temple may not be boosted by culture tokens",
93+
)
94+
.add_player_event_listener(
95+
|event| &mut event.on_influence_culture_attempt,
96+
|info, city, _| {
97+
if info.is_defender && city.pieces.temple.is_some() {
98+
info.set_no_boost();
99+
}
100+
},
101+
0,
102+
)
103+
}

server/src/content/custom_actions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ impl CustomAction {
172172
CustomAction::CivilRights =>
173173
format!("{player_name} gained 3 mood tokens using Civil Rights"),
174174
CustomAction::ArtsInfluenceCultureAttempt(c) =>
175-
format!("{} using Arts", format_cultural_influence_attempt_log_item(game, player_name, c)),
175+
format!("{} using Arts", format_cultural_influence_attempt_log_item(game, player.index, player_name, c)),
176176
CustomAction::VotingIncreaseHappiness(i) =>
177177
format!("{} using Voting", format_happiness_increase(player, player_name, i)),
178178
CustomAction::FreeEconomyCollect(c) =>

0 commit comments

Comments
 (0)