1212# Source.Python
1313from cvars import ConVar
1414from engines .server import engine_server
15- from menus import PagedMenu
16- from menus import PagedOption
15+ from menus import PagedMenu , SimpleMenu
16+ from menus import PagedOption , SimpleOption
1717from messages import SayText
1818from players .entity import Player
1919from players .helpers import uniqueid_from_index
@@ -55,20 +55,23 @@ def __new__(cls, name, default, text=None, *args):
5555 # Get the new object instance
5656 self = object .__new__ (cls )
5757
58- # Store the base attributes
58+ # Return the instance
59+ return self
60+
61+ def __init__ (self , name , default , text = None , * args ):
62+ """Store the base attributes and create the menu."""
5963 self .name = name
6064 self .default = default
6165 self .text = text
66+ self ._create_menu ()
6267
63- # Store a menu for the object
68+ def _create_menu ( self ):
6469 self .menu = PagedMenu (
6570 select_callback = self ._chosen_value ,
6671 build_callback = self ._menu_build ,
67- title = name if text is None else text ,
68- description = _settings_strings ['Description' ])
69-
70- # Return the instance
71- return self
72+ title = self .name if self .text is None else self .text ,
73+ description = _settings_strings ['Description' ]
74+ )
7275
7376 @property
7477 def convar (self ):
@@ -158,24 +161,117 @@ def _menu_build(self, menu, index):
158161
159162 def _chosen_value (self , menu , index , option ):
160163 """Store the player's chosen value for the setting."""
161- # Get the client's uniqueid
162- uniqueid = uniqueid_from_index (index )
163-
164164 # Set the player's setting
165+ uniqueid = uniqueid_from_index (index )
165166 _player_settings_storage [uniqueid ][self .convar ] = option .value
166167
167168 # Send the player a message about their changed setting
168169 _message .send (index , convar = self .convar , value = option .value )
169170
170171
171- class _NumericalSetting (SettingsType ):
172- """Class used to store integer/float settings with min/max values."""
172+ class IntegerSetting (SettingsType ):
173+ """Class used to store integer value settings."""
174+
175+ _type = int
173176
174177 def __init__ (
175- self , name , default , text = None , min_value = None , max_value = None ):
178+ self , name , default , text = None , min_value = None , max_value = None
179+ ):
176180 """Store the base attributes on instantiation."""
181+ super ().__init__ (name = name , default = default , text = text )
182+ if min_value is not None and max_value is not None :
183+ if min_value >= max_value :
184+ raise ValueError (
185+ 'min_value ({min_value}) must be less than max_value '
186+ '({max_value}).' .format (
187+ min_value = min_value ,
188+ max_value = max_value ,
189+ )
190+ )
177191 self .min = self ._type (min_value ) if min_value is not None else None
178192 self .max = self ._type (max_value ) if max_value is not None else None
193+ self .current_values = {}
194+
195+ def _create_menu (self ):
196+ self .menu = SimpleMenu (
197+ select_callback = self ._chosen_value ,
198+ build_callback = self ._menu_build ,
199+ )
200+
201+ def _menu_build (self , menu , index ):
202+ """Build the menu."""
203+ self .menu .clear ()
204+ self .menu .append (self .name if self .text is None else self .text )
205+
206+ # Get the player's information
207+ player = Player (index )
208+ uniqueid = player .uniqueid
209+ current_value = self .get_setting (index )
210+
211+ description = _settings_strings ['Description' ].get_string (
212+ language = player .language ,
213+ value = current_value ,
214+ )
215+ self .menu .append (description )
216+ self .menu .append ('-' * len (description ))
217+ counter = 1
218+ if self .min is None or self .max is None or self .max - self .min > 100 :
219+ for value in (100 , - 100 ):
220+ self ._add_option (choice_index = counter , value = value )
221+ counter += 1
222+
223+ if self .min is None or self .max is None or self .max - self .min > 10 :
224+ for value in (10 , - 10 ):
225+ self ._add_option (choice_index = counter , value = value )
226+ counter += 1
227+
228+ for value in (1 , - 1 ):
229+ self ._add_option (choice_index = counter , value = value )
230+ counter += 1
231+
232+ if uniqueid not in self .current_values :
233+ self .current_values [uniqueid ] = current_value
234+
235+ self .menu .append (
236+ SimpleOption (
237+ choice_index = counter ,
238+ text = 'Save ({current_value})' .format (
239+ current_value = self .current_values [uniqueid ],
240+ ),
241+ value = 'Save' ,
242+ )
243+ )
244+
245+ def _add_option (self , choice_index , value ):
246+ """Add the value to the menu."""
247+ self .menu .append (
248+ SimpleOption (
249+ choice_index = choice_index ,
250+ text = '{:+d}' .format (value ),
251+ value = value ,
252+ )
253+ )
254+
255+ def _chosen_value (self , menu , index , option ):
256+ """Store the player's chosen value for the setting."""
257+ uniqueid = uniqueid_from_index (index )
258+
259+ if option .value == 'Save' :
260+ value = self .current_values [uniqueid ]
261+
262+ # Set the player's setting
263+ _player_settings_storage [uniqueid ][self .convar ] = value
264+ _message .send (index , convar = self .convar , value = value )
265+ del self .current_values [uniqueid ]
266+ return
267+
268+ new_value = self .current_values [uniqueid ] + option .value
269+ if self .min is not None :
270+ new_value = max (new_value , self .min )
271+ if self .max is not None :
272+ new_value = min (new_value , self .max )
273+ self .current_values [uniqueid ] = new_value
274+ self .menu .send ()
179275
180276 def _is_valid_setting (self , value ):
181277 """Return whether the given value is a valid value for the setting."""
@@ -195,18 +291,6 @@ def _is_valid_setting(self, value):
195291 return True
196292
197293
198- class FloatSetting (_NumericalSetting ):
199- """Class used to store float value settings."""
200-
201- _type = float
202-
203-
204- class IntegerSetting (_NumericalSetting ):
205- """Class used to store integer value settings."""
206-
207- _type = int
208-
209-
210294class BoolSetting (SettingsType ):
211295 """Class used to store boolean value settings."""
212296
@@ -216,7 +300,10 @@ def __init__(self, *args, **kwargs):
216300 # TODO: add translations
217301 for value , name in enumerate (['Yes' , 'No' ]):
218302 self .menu .append (
219- PagedOption (name , not value )
303+ PagedOption (
304+ text = name ,
305+ value = not value ,
306+ )
220307 )
221308
222309 def _typecast_value (self , value ):
@@ -252,7 +339,9 @@ def add_option(self, name, text=None):
252339
253340 # Store the option
254341 option = self .options [name ] = PagedOption (
255- name if text is None else text , name )
342+ text = name if text is None else text ,
343+ value = name ,
344+ )
256345
257346 # Add the option to the menu
258347 self .menu .append (option )
@@ -267,6 +356,7 @@ def remove_option(self, name):
267356 'Given name "{0}" is not an option' .format (name ))
268357
269358 # Delete the option
359+ self .menu .remove (self .options [name ])
270360 del self .options [name ]
271361
272362 def _is_valid_setting (self , value ):
0 commit comments