1
+ use crate :: city_ui:: { IconAction , IconActionVec } ;
1
2
use crate :: client_state:: { ActiveDialog , StateUpdate } ;
2
3
use crate :: dialog_ui:: { BaseOrCustomAction , BaseOrCustomDialog } ;
3
- use crate :: happiness_ui:: { can_play_increase_happiness, open_increase_happiness_dialog} ;
4
+ use crate :: event_ui:: event_help;
5
+ use crate :: happiness_ui:: {
6
+ can_play_increase_happiness, can_play_influence_culture, open_increase_happiness_dialog,
7
+ } ;
4
8
use crate :: layout_ui:: { bottom_left_texture, icon_pos} ;
5
9
use crate :: move_ui:: MoveIntent ;
10
+ use crate :: payment_ui:: Payment ;
6
11
use crate :: render_context:: RenderContext ;
7
12
use server:: action:: Action ;
8
- use server:: content:: advances:: get_advance;
13
+ use server:: city:: City ;
14
+ use server:: content:: advances_culture:: { sports_options, theaters_options} ;
15
+ use server:: content:: advances_economy:: tax_options;
9
16
use server:: content:: custom_actions:: { CustomAction , CustomActionType } ;
10
17
use server:: game:: GameState ;
11
18
use server:: playing_actions:: { PlayingAction , PlayingActionType } ;
@@ -36,35 +43,64 @@ pub fn action_buttons(rc: &RenderContext) -> StateUpdate {
36
43
{
37
44
return StateUpdate :: OpenDialog ( ActiveDialog :: AdvanceMenu ) ;
38
45
}
39
- if rc . can_play_action ( PlayingActionType :: InfluenceCultureAttempt )
46
+ if can_play_influence_culture ( rc )
40
47
&& bottom_left_texture (
41
48
rc,
42
49
& assets. resources [ & ResourceType :: CultureTokens ] ,
43
50
icon_pos ( 1 , -2 ) ,
44
51
"Cultural Influence" ,
45
52
)
46
53
{
47
- return StateUpdate :: OpenDialog ( ActiveDialog :: CulturalInfluence ) ;
54
+ return base_or_custom_action (
55
+ rc,
56
+ PlayingActionType :: InfluenceCultureAttempt ,
57
+ "Influence culture" ,
58
+ & [ ( "Arts" , CustomActionType :: ArtsInfluenceCultureAttempt ) ] ,
59
+ ActiveDialog :: CulturalInfluence ,
60
+ ) ;
48
61
}
49
- for ( i, a) in game
50
- . get_available_custom_actions ( rc. shown_player . index )
51
- . iter ( )
52
- . enumerate ( )
53
- {
54
- if let Some ( action) = generic_custom_action ( a) {
62
+ let mut i = 0 ;
63
+ for ( a, origin) in & game. get_available_custom_actions ( rc. shown_player . index ) {
64
+ if let Some ( action) = generic_custom_action ( rc, a, None ) {
55
65
if bottom_left_texture (
56
66
rc,
57
67
& assets. custom_actions [ a] ,
58
68
icon_pos ( i as i8 , -1 ) ,
59
- & custom_action_tooltip ( a ) ,
69
+ & event_help ( rc , origin , false ) [ 0 ] ,
60
70
) {
61
- return StateUpdate :: execute ( Action :: Playing ( PlayingAction :: Custom ( action) ) ) ;
71
+ return action;
62
72
}
73
+ i += 1 ;
74
+ }
75
+ }
76
+ for ( i, ( icon, tooltip, action) ) in custom_action_buttons ( rc, None ) . iter ( ) . enumerate ( ) {
77
+ if bottom_left_texture ( rc, icon, icon_pos ( i as i8 , -1 ) , tooltip) {
78
+ return action ( ) ;
63
79
}
64
80
}
65
81
StateUpdate :: None
66
82
}
67
83
84
+ pub fn custom_action_buttons < ' a > (
85
+ rc : & ' a RenderContext ,
86
+ city : Option < & ' a City > ,
87
+ ) -> IconActionVec < ' a > {
88
+ rc. game
89
+ . get_available_custom_actions ( rc. shown_player . index )
90
+ . into_iter ( )
91
+ . filter_map ( |( a, origin) | {
92
+ generic_custom_action ( rc, & a, city) . map ( |action| {
93
+ let a: IconAction < ' a > = (
94
+ & rc. assets ( ) . custom_actions [ & a] ,
95
+ event_help ( rc, & origin, false ) [ 0 ] . clone ( ) ,
96
+ Box :: new ( move || action. clone ( ) ) ,
97
+ ) ;
98
+ a
99
+ } )
100
+ } )
101
+ . collect ( )
102
+ }
103
+
68
104
fn global_move ( rc : & RenderContext ) -> StateUpdate {
69
105
let pos = rc. state . focused_tile ;
70
106
StateUpdate :: move_units (
@@ -78,24 +114,39 @@ fn global_move(rc: &RenderContext) -> StateUpdate {
78
114
)
79
115
}
80
116
81
- fn custom_action_tooltip ( custom_action_type : & CustomActionType ) -> String {
82
- match custom_action_type {
83
- CustomActionType :: ConstructWonder => "Construct a wonder" . to_string ( ) ,
84
- CustomActionType :: AbsolutePower => get_advance ( "Absolute Power" ) . description ,
85
- CustomActionType :: VotingIncreaseHappiness => get_advance ( "Voting" ) . description ,
86
- CustomActionType :: FreeEconomyCollect => get_advance ( "Free Economy" ) . description ,
117
+ fn generic_custom_action (
118
+ rc : & RenderContext ,
119
+ custom_action_type : & CustomActionType ,
120
+ city : Option < & City > ,
121
+ ) -> Option < StateUpdate > {
122
+ if let Some ( city) = city {
123
+ if matches ! ( custom_action_type, CustomActionType :: Sports ) {
124
+ if let Some ( options) = sports_options ( city) {
125
+ return Some ( StateUpdate :: OpenDialog ( ActiveDialog :: Sports (
126
+ ( Payment :: new_gain ( & options, "Increase happiness using sports" ) , city. position ) ,
127
+ ) ) ) ;
128
+ }
129
+ }
87
130
}
88
- }
89
131
90
- fn generic_custom_action ( custom_action_type : & CustomActionType ) -> Option < CustomAction > {
91
132
match custom_action_type {
92
133
CustomActionType :: ConstructWonder
134
+ | CustomActionType :: ArtsInfluenceCultureAttempt
93
135
| CustomActionType :: VotingIncreaseHappiness
94
- | CustomActionType :: FreeEconomyCollect => {
136
+ | CustomActionType :: FreeEconomyCollect
137
+ | CustomActionType :: Sports => {
95
138
// handled explicitly
96
139
None
97
140
}
98
- CustomActionType :: AbsolutePower => Some ( CustomAction :: ForcedLabor ) ,
141
+ CustomActionType :: AbsolutePower => Some ( StateUpdate :: execute ( Action :: Playing (
142
+ PlayingAction :: Custom ( CustomAction :: AbsolutePower ) ,
143
+ ) ) ) ,
144
+ CustomActionType :: Taxes => Some ( StateUpdate :: OpenDialog ( ActiveDialog :: Taxes (
145
+ Payment :: new_gain ( & tax_options ( rc. shown_player ) , "Collect taxes" ) ,
146
+ ) ) ) ,
147
+ CustomActionType :: Theaters => Some ( StateUpdate :: OpenDialog ( ActiveDialog :: Theaters (
148
+ Payment :: new_gain ( & theaters_options ( ) , "Convert Resources" ) ,
149
+ ) ) ) ,
99
150
}
100
151
}
101
152
@@ -108,8 +159,7 @@ pub fn base_or_custom_available(
108
159
|| ( rc. game . state == GameState :: Playing
109
160
&& rc
110
161
. game
111
- . get_available_custom_actions ( rc. shown_player . index )
112
- . contains ( custom) )
162
+ . is_custom_action_available ( rc. shown_player . index , custom) )
113
163
}
114
164
115
165
pub fn base_or_custom_action (
@@ -128,13 +178,9 @@ pub fn base_or_custom_action(
128
178
None
129
179
} ;
130
180
131
- let special = rc
132
- . game
133
- . get_available_custom_actions ( rc. shown_player . index )
134
- . iter ( )
135
- . find ( |a| custom. iter ( ) . any ( |( _, b) | * * a == * b) )
136
- . map ( |a| {
137
- let advance = custom. iter ( ) . find ( |( _, b) | * b == * a) . unwrap ( ) . 0 ;
181
+ let special =
182
+ custom. iter ( ) . find ( |( _, a) | rc. game . is_custom_action_available ( rc. shown_player . index , a) )
183
+ . map ( |( advance, a) | {
138
184
let dialog = execute ( BaseOrCustomDialog {
139
185
custom : BaseOrCustomAction :: Custom {
140
186
custom : a. clone ( ) ,
0 commit comments