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,40 @@ 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" ) ,
127
+ city. position ,
128
+ ) ) ) ) ;
129
+ }
130
+ }
87
131
}
88
- }
89
132
90
- fn generic_custom_action ( custom_action_type : & CustomActionType ) -> Option < CustomAction > {
91
133
match custom_action_type {
92
134
CustomActionType :: ConstructWonder
135
+ | CustomActionType :: ArtsInfluenceCultureAttempt
93
136
| CustomActionType :: VotingIncreaseHappiness
94
- | CustomActionType :: FreeEconomyCollect => {
137
+ | CustomActionType :: FreeEconomyCollect
138
+ | CustomActionType :: Sports => {
95
139
// handled explicitly
96
140
None
97
141
}
98
- CustomActionType :: AbsolutePower => Some ( CustomAction :: ForcedLabor ) ,
142
+ CustomActionType :: AbsolutePower => Some ( StateUpdate :: execute ( Action :: Playing (
143
+ PlayingAction :: Custom ( CustomAction :: AbsolutePower ) ,
144
+ ) ) ) ,
145
+ CustomActionType :: Taxes => Some ( StateUpdate :: OpenDialog ( ActiveDialog :: Taxes (
146
+ Payment :: new_gain ( & tax_options ( rc. shown_player ) , "Collect taxes" ) ,
147
+ ) ) ) ,
148
+ CustomActionType :: Theaters => Some ( StateUpdate :: OpenDialog ( ActiveDialog :: Theaters (
149
+ Payment :: new_gain ( & theaters_options ( ) , "Convert Resources" ) ,
150
+ ) ) ) ,
99
151
}
100
152
}
101
153
@@ -108,8 +160,7 @@ pub fn base_or_custom_available(
108
160
|| ( rc. game . state == GameState :: Playing
109
161
&& rc
110
162
. game
111
- . get_available_custom_actions ( rc. shown_player . index )
112
- . contains ( custom) )
163
+ . is_custom_action_available ( rc. shown_player . index , custom) )
113
164
}
114
165
115
166
pub fn base_or_custom_action (
@@ -128,17 +179,14 @@ pub fn base_or_custom_action(
128
179
None
129
180
} ;
130
181
131
- let special = rc
132
- . game
133
- . get_available_custom_actions ( rc. shown_player . index )
182
+ let special = custom
134
183
. iter ( )
135
- . find ( |a| custom. iter ( ) . any ( |( _, b) | * * a == * b) )
136
- . map ( |a| {
137
- let advance = custom. iter ( ) . find ( |( _, b) | * b == * a) . unwrap ( ) . 0 ;
184
+ . find ( |( _, a) | rc. game . is_custom_action_available ( rc. shown_player . index , a) )
185
+ . map ( |( advance, a) | {
138
186
let dialog = execute ( BaseOrCustomDialog {
139
187
custom : BaseOrCustomAction :: Custom {
140
188
custom : a. clone ( ) ,
141
- advance : advance. to_string ( ) ,
189
+ advance : ( * advance) . to_string ( ) ,
142
190
} ,
143
191
title : format ! ( "{title} with {advance}" ) ,
144
192
} ) ;
0 commit comments