Exemplo n.º 1
0
class GameVoting(dict):
    def __init__(self):
        super().__init__()

        self._votes_received = 0
        self._max_players = -1
        self._timeout_delay = None
        self._popup = None
        self.result = None

    def select_callback(self, popup, index, option):
        self._votes_received += 1

        if option.value != "WONT_PLAY":
            self[option.value] = self.get(option.value, 0) + 1

            player = player_manager[index]
            broadcast(strings_module['player_voted'].tokenize(
                player=player.name, choice=option.value.caption))

        if self._votes_received >= self._max_players:
            self.finish()

    def start(self, popup, targets, timeout):
        self._popup = popup
        self._max_players = len(targets)
        self._timeout_delay = Delay(timeout, self.finish)

        popup.send(*[player.index for player in targets])

    def finish(self):
        if self._popup is None:
            return

        if self._timeout_delay is not None:
            if self._timeout_delay.running:
                self._timeout_delay.cancel()

            self._timeout_delay = None

        self._popup.close()
        self._popup = None

        if not self:
            broadcast(strings_module['result no_game'])
            InternalEvent.fire('jail_games_voting_result', result=None)
            return

        top_games = sorted(
            self.keys(), key=lambda key: self[key], reverse=True)

        top_score = self[top_games[0]]
        top_games = list(filter(lambda key: self[key] == top_score, top_games))
        winner = choice(top_games)

        self.result = winner
        broadcast(strings_module['result chosen_game'], caption=winner.caption)
        InternalEvent.fire('jail_games_voting_result', result=winner)

        self.clear()
Exemplo n.º 2
0
class FallProtectedPlayer:
    def __init__(self, player):
        self.player = player
        self.p_player = protected_player_manager[player.index]

        self._delay = None
        self._counter = None

    def protect(self, seconds):
        if self._counter is not None:
            raise ValueError("Player {} already protected".format(
                self.player.userid))

        self._counter = self.p_player.new_counter(
            health=0, display=strings_module['health falldmg_protection'])

        def sub_hook(counter, info):
            self.p_player.delete_counter(counter)
            self.p_player.unset_protected()

            self._counter = None

            Shake(FALL_PROT_SHAKE_MAGNITUDE,
                  FALL_PROT_SHAKE_TIME).send(self.player.index)

            self._delay.cancel()

            return False

        self._counter.hook_hurt = get_hook('W', next_hook=sub_hook)

        def delay_callback():
            self.p_player.delete_counter(self._counter)
            self.p_player.unset_protected()

            self._counter = None

        self._delay = Delay(seconds, delay_callback)
        self.p_player.set_protected()

    def unprotect(self):
        if self._counter is None:
            raise ValueError("Player {} is not protected yet".format(
                self.player.userid))

        self.cancel_delay()

        self.p_player.delete_counter(self._counter)
        self.p_player.unset_protected()

        self._counter = None

    @property
    def protected(self):
        return self._counter is not None

    def cancel_delay(self):
        if self._delay is not None and self._delay.running:
            self._delay.cancel()
Exemplo n.º 3
0
class _PlayerEffect(object):
    """Class for player effects like freeze and burn."""

    def __init__(self, descriptor_obj, player):
        """Initialize a new effect for a player.

        This doesn't enable the effect yet, it simply prepares it.
        The effect can be enabled via the _enable method,
        or via parenthesis which invokes the __call__.
        """
        self._descriptor_obj = descriptor_obj
        self._player = player
        self._delay = None

    def _enable(self, duration=None, *args, **kwargs):
        """Enable the effect.

        Add the new effect to a player's effects and call
        the descriptor object's on function with the provided
        arguments and keyword arguments.

        If duration is a positive integer, adds a delay which
        automatically disables the effect after the duration.
        """
        if isinstance(duration, int) and duration > 0:
            self._delay = Delay(duration, self._disable)
        self._player._effects[self._descriptor_obj].append(self)
        self._descriptor_obj._on_f(self._player, *args, **kwargs)

    def __call__(self, duration=None, *args, **kwargs):
        """Override () to call the _enable method."""
        self._enable(duration, *args, **kwargs)
        return self

    def _disable(self, *args, **kwargs):
        """Disable the effect.

        Remove the effect from a player's effects and if there are
        no more effects of this type, calls the descriptor object's
        off function with the provided arguments.
        """
        self._player._effects[self._descriptor_obj].remove(self)
        if not self._player._effects[self._descriptor_obj]:
            self._descriptor_obj._off_f(self._player, *args, **kwargs)

    def cancel(self, *args, **kwargs):
        """Cancel the tick_delay and disable the effect."""
        if self._delay is not None:
            self._delay.cancel()
            self._delay = None
        self._disable(*args, **kwargs)
Exemplo n.º 4
0
class _HostnameManager(object):
    """Class used to set the hostname."""
    def __init__(self):
        """Store the base delay."""
        self._convar = ConVar('hostname')
        self._original_hostname = self._convar.get_string()
        self.delay = Delay(0.1, self._set_hostname)

    def reset_hostname(self):
        """Sets the hostname back to the original value on unload."""
        self._convar.set_string(self._original_hostname)

    def set_hostname(self):
        """Delay changing the hostname."""
        # Is there currently a delay?
        if self.delay is not None:

            # Cancel the delay
            self.delay.cancel()

        # Delay before setting the hostname
        self.delay = Delay(0.2, self._set_hostname)

    def _set_hostname(self):
        """Set the hostname to show GunGame and Included/Custom Plugins."""
        # Set the delay back to None
        self.delay = None

        # Set the hostname to the new value
        self._convar.set_string(self.get_hostname_value())

    @staticmethod
    def get_hostname_value():
        """Return the full value of the new hostname."""
        # Get the basename
        value = database['Settings']['base_name']

        # Create an empty dictionary
        plugin_values = dict()

        # Loop through all plugins in the database
        for plugin_name, values in database.items():

            # Is the plugin loaded?
            if plugin_name in gg_plugin_manager:

                if (plugin_name == 'gg_bombing_objective'
                        and not len(EntityIter('func_bomb_target'))):
                    continue

                if (plugin_name == 'gg_hostage_objective'
                        and not len(EntityIter('func_hostage_rescue'))):
                    continue

                # Store the plugin's name and priority
                plugin_values[values['name']] = int(values['priority'])

        # Are there any plugins that are loaded?
        if plugin_values:

            # Add the base_break to the string
            value += database['Settings']['base_break']

            # Sort the loaded plugins by their priority
            plugins = sorted(
                plugin_values,
                key=lambda plugin: plugin_values[plugin],
            )

            # Add all loaded plugins to the string
            # Separate each with the feature_break
            value += database['Settings']['feature_break'].join(plugins)

        return value
Exemplo n.º 5
0
class SavedPlayer:
    def __init__(self, player):
        self._ammo_refill_delay = None
        self._nade_refill_delay = None
        self.player = player
        self.health = 0
        self.saved_weapons = []
        self.infinite_weapons = []

    def _nade_thrown(self, weapon_classname):
        if self._ammo_refill_delay is None:
            return

        if weapon_classname not in self.infinite_weapons:
            return

        self._nade_refill_delay = Delay(PROJECTILE_REFILL_DELAY,
                                        give_named_item, self.player,
                                        weapon_classname, 0)

    def save_health(self):
        self.health = self.player.health

    def save_weapons(self):
        self.saved_weapons = []

        for weapon in self.player.weapons():
            weapon_dict = {
                'classname': weapon.classname,
                'clip': weapon.clip,
                'subtype': weapon.get_property_int('m_iSubType'),
            }

            try:
                weapon_dict['ammo'] = weapon.ammo
            except ValueError:
                weapon_dict['ammo'] = None

            self.saved_weapons.append(weapon_dict)

        self.strip()

    def save_all(self):
        self.save_health()
        self.save_weapons()

    def strip(self):
        for weapon in self.player.weapons():
            self.player.drop_weapon(weapon.pointer, NULL_VECTOR, NULL_VECTOR)
            weapon.remove()

    def restore_health(self):
        self.player.health = self.health

    def restore_weapons(self):
        self.strip()
        for weapon_dict in self.saved_weapons:
            weapon = Weapon.create(weapon_dict['classname'])
            weapon.teleport(self.player.origin, None, None)
            weapon.spawn()

            weapon.clip = weapon_dict['clip']
            if weapon_dict['ammo'] is not None:
                weapon.ammo = weapon_dict['ammo']

    def restore_all(self):
        self.restore_health()
        self.restore_weapons()

    def max_ammo(self, weapon_classnames):
        for index in self.player.weapon_indexes():
            weapon_classname = edict_from_index(index).classname
            if weapon_classname not in weapon_classnames:
                continue

            if weapon_classname in PROJECTILE_CLASSNAMES:
                continue

            weapon_class = weapon_manager[weapon_classname]
            if weapon_class.maxammo > 0:
                Weapon(index).ammo = weapon_class.maxammo

    def _refill_infinite_ammo(self):
        self.max_ammo(self.infinite_weapons)
        self._ammo_refill_delay = Delay(INFINITE_AMMO_REFILL_INTERVAL,
                                        self._refill_infinite_ammo)

    def infinite_on(self):
        if (self._ammo_refill_delay is not None
                or self._nade_refill_delay is not None):

            raise ValueError("Infinite equipment is already turned on")

        new_infinite_weapons = []
        for weapon_classname in self.infinite_weapons:
            if weapon_manager[weapon_classname].maxammo > 0:
                new_infinite_weapons.append(weapon_classname)

        self.infinite_weapons = new_infinite_weapons

        self._refill_infinite_ammo()

    def infinite_off(self):
        if self._ammo_refill_delay is None:
            raise ValueError("Infinite equipment is already turned off")

        self._ammo_refill_delay.cancel()
        self._ammo_refill_delay = None

        if self._nade_refill_delay is not None:
            if self._nade_refill_delay.running:
                self._nade_refill_delay.cancel()

            self._nade_refill_delay = None
class VoteProgressBar:
    def __init__(self):
        self._refresh_delay = None
        self._message = None
        self._players_total = 0
        self._players_voted = 0

    def count_vote(self, map_):
        self._players_voted += 1

        for exception in EXCLUDE_ENTRIES:
            if map_ is exception:
                return

        maps = list(
            filter(
                lambda map_: map_.votes,
                sorted(server_map_manager.values(),
                       key=lambda map_: map_.votes,
                       reverse=True)))

        map_tokens = {
            'map1': popups_strings['vote_progress_map_without_votes'],
            'map2': popups_strings['vote_progress_map_without_votes'],
            'map3': popups_strings['vote_progress_map_without_votes'],
        }
        if len(maps) > 0:
            map_tokens['map1'] = popups_strings[
                'vote_progress_map_with_votes'].tokenized(
                    map=maps[0].name,
                    votes=maps[0].votes,
                )
            if len(maps) > 1:
                map_tokens['map2'] = popups_strings[
                    'vote_progress_map_with_votes'].tokenized(
                        map=maps[1].name,
                        votes=maps[1].votes,
                    )
                if len(maps) > 2:
                    map_tokens['map3'] = popups_strings[
                        'vote_progress_map_with_votes'].tokenized(
                            map=maps[2].name,
                            votes=maps[2].votes,
                        )

        self._message = popups_strings['vote_progress'].tokenized(
            players_voted=self._players_voted,
            players_total=self._players_total,
            **map_tokens,
        )

        self.refresh()

    def refresh(self):
        if self._refresh_delay is not None and self._refresh_delay.running:
            self._refresh_delay.cancel()

        if not config_manager['votemap_show_progress']:
            return

        if self._message:
            time_left = int(status.vote_start_time +
                            config_manager['vote_duration'] - time())

            message_tokenized = self._message.tokenized(
                **self._message.tokens,
                time_left="{:02d}:{:02d}".format(*divmod(time_left, 60)))

            if config_manager['votemap_progress_use_hudmsg']:
                HudMsg(
                    message_tokenized,
                    color1=HUDMSG_MSG_COLOR,
                    x=HUDMSG_MSG_X,
                    y=HUDMSG_MSG_Y,
                    effect=HUDMSG_MSG_EFFECT,
                    fade_in=HUDMSG_MSG_FADEIN,
                    fade_out=HUDMSG_MSG_FADEOUT,
                    hold_time=HUDMSG_MSG_HOLDTIME,
                    fx_time=HUDMSG_MSG_FXTIME,
                    channel=HUDMSG_MSG_CHANNEL,
                ).send()
            else:
                HintText(message_tokenized).send()

        self._refresh_delay = Delay(REFRESH_INTERVAL, self.refresh)

    def start(self):
        self._players_total = len(mcplayers)
        self._players_voted = 0

        self._message = popups_strings['vote_progress'].tokenized(
            players_voted=self._players_voted,
            players_total=self._players_total,
            map1=popups_strings['vote_progress_map_without_votes'],
            map2=popups_strings['vote_progress_map_without_votes'],
            map3=popups_strings['vote_progress_map_without_votes'],
        )
        self.refresh()

    def stop(self):
        if self._refresh_delay is not None and self._refresh_delay.running:
            self._refresh_delay.cancel()
Exemplo n.º 7
0
class PrepareTime(JailGame):
    stage_groups = {
        'init': [
            "set-initial-status",
            "prepare-prepare",
        ],
        'destroy': [
            "prepare-cancel-delays",
            "unsend-popups",
            "destroy",
        ],
        'prepare-start': [
            "prepare-freeze",
            "prepare-register-event-handlers",
            "prepare-entry",
        ],
        'abort-prepare-interrupted': [
            "abort-prepare-interrupted",
        ],
        'prepare-continue': [
            "prepare-cancel-countdown",
            "prepare-undo-prepare-start",
            "register-event-handlers",
            "set-start-status",
            "start-notify",
            "basegame-entry",
        ],
    }

    def __init__(self, players, **kwargs):
        super().__init__(players, **kwargs)

        self._prepare_delay = None
        self._prepare_countdown = None

    @stage('prepare-prepare')
    def stage_prepare_prepare(self):
        if self._settings.get('prepare', True):
            indexes = list(player.index for player in self._players)

            def callback():
                self.undo_stages('prepare-start')
                self.set_stage_group('prepare-continue')

            self._prepare_delay = Delay(config_manager['prepare_timeout'],
                                        callback)

            def countdown(ticks_left):
                if (ticks_left > 3 or ticks_left < 1 or config_manager[
                        'countdown_{}_material'.format(ticks_left)] == ""):

                    TextMsg(str(ticks_left)).send(*indexes)

                else:
                    for player in self._players:
                        show_overlay(
                            player, config_manager[
                                'countdown_{}_material'.format(ticks_left)], 1)

                if config_manager['countdown_sound'] is not None:
                    config_manager['countdown_sound'].play(*indexes)

                self._prepare_countdown = Delay(1.0, countdown, ticks_left - 1)

            countdown(int(config_manager['prepare_timeout']))

            # TODO: Maybe better just tell prisoner and guard instead of
            # broadcasting?
            broadcast(strings_module['stage_prepare'])

            if config_manager['prepare_sound'] is not None:
                config_manager['prepare_sound'].play(*indexes)

            self.set_stage_group('prepare-start')

        else:
            self.set_stage_group('prepare-continue')

    def _prepare_event_handler_player_death(self, game_event):
        player = main_player_manager.get_by_userid(
            game_event.get_int('userid'))

        if player in self._players:
            self.set_stage_group('abort-prepare-interrupted')

    def _prepare_event_handler_main_player_deleted(self, event_var):
        player = event_var['player']
        if player in self._players:
            self.set_stage_group('abort-prepare-interrupted')

    def _prepare_event_handler_player_hurt(self, game_event):
        player = main_player_manager.get_by_userid(
            game_event.get_int('userid'))

        if player in self._players:
            self.set_stage_group('abort-prepare-interrupted')

    @stage('prepare-register-event-handlers')
    def stage_prepare_register_event_handlers(self):
        event_manager.register_for_event(
            'player_death', self._prepare_event_handler_player_death)

        event_manager.register_for_event(
            'player_hurt', self._prepare_event_handler_player_hurt)

        internal_event_manager.register_event_handler(
            'main_player_deleted',
            self._prepare_event_handler_main_player_deleted)

    @stage('undo-prepare-register-event-handlers')
    def stage_undo_prepare_register_event_handlers(self):
        event_manager.unregister_for_event(
            'player_death', self._prepare_event_handler_player_death)

        event_manager.unregister_for_event(
            'player_hurt', self._prepare_event_handler_player_hurt)

        internal_event_manager.unregister_event_handler(
            'main_player_deleted',
            self._prepare_event_handler_main_player_deleted)

    @stage('prepare-cancel-delays')
    def stage_prepare_cancel_delays(self):
        for delay in (self._prepare_delay, self._prepare_countdown):
            if delay is not None and delay.running:
                delay.cancel()

    @stage('prepare-cancel-countdown')
    def stage_prepare_cancel_countdown(self):
        if self._prepare_countdown is not None:
            self._prepare_countdown.cancel()

    @stage('prepare-undo-prepare-start')
    def stage_prepare_undo_prepare_start(self):
        self.undo_stages('prepare-start')

    @stage('prepare-entry')
    def stage_prepare_entry(self):
        pass

    def _prepare_freeze_tick_handler(self):
        for player in self._players:
            weapon = player.active_weapon
            if weapon is None:
                continue

            weapon.next_attack += 1
            weapon.next_secondary_fire_attack += 1

    @stage('prepare-freeze')
    def stage_prepare_freeze(self):
        on_tick_listener_manager.register_listener(
            self._prepare_freeze_tick_handler)

        for player in self._players:
            player.stuck = True

    @stage('undo-prepare-freeze')
    def stage_undo_prepare_freeze(self):
        on_tick_listener_manager.unregister_listener(
            self._prepare_freeze_tick_handler)

        for player in self._players:
            player.stuck = False

            weapon = player.active_weapon
            if weapon is None:
                continue

            weapon.next_attack = 0
            weapon.next_secondary_fire_attack = 0

    @stage('abort-prepare-interrupted')
    def stage_abort_prepare_interrupted(self):
        broadcast(strings_module['abort prepare_interrupted'])

        if config_manager['prepare_sound'] is not None:
            config_manager['prepare_sound'].stop()

        self.set_stage_group('destroy')
Exemplo n.º 8
0
class SavedPlayer:
    def __init__(self, player):
        self._ammo_refill_delay = None
        self._nade_refill_delay = None
        self.player = player
        self.health = 0
        self.saved_weapons = []
        self.infinite_weapons = []

    def _nade_thrown(self, weapon_classname):
        if self._ammo_refill_delay is None:
            return

        if weapon_classname not in self.infinite_weapons:
            return

        self._nade_refill_delay = Delay(PROJECTILE_REFILL_DELAY,
                                        self.player.give_named_item,
                                        weapon_classname)

    def save_health(self):
        self.health = self.player.health

    def save_weapons(self):
        self.saved_weapons = []

        for weapon in self.player.weapons():
            weapon_dict = {
                'classname': weapon.classname,
                'subtype': weapon.get_property_int('m_iSubType'),
                'ammo': weapon.ammo if weapon.has_ammo() else None,
                'clip': weapon.ammo if weapon.has_clip() else None
            }

            self.saved_weapons.append(weapon_dict)

        self.strip()

    def save_all(self):
        self.save_health()
        self.save_weapons()

    def strip(self):
        for weapon in self.player.weapons():
            self.player.drop_weapon(weapon.pointer, NULL_VECTOR, NULL_VECTOR)
            weapon.remove()

    def restore_health(self):
        self.player.health = self.health

    def restore_weapons(self):
        self.strip()
        for weapon_dict in self.saved_weapons:
            weapon = Weapon.create(weapon_dict['classname'])
            weapon.teleport(self.player.origin, None, None)
            weapon.spawn()

            if weapon_dict['clip'] is not None:
                weapon.clip = weapon_dict['clip']

            if weapon_dict['ammo'] is not None:
                weapon.ammo = weapon_dict['ammo']

    def restore_all(self):
        self.restore_health()
        self.restore_weapons()

    def max_ammo(self, weapon_classnames):
        maxed_weapons = []

        for weapon in self.player.weapons():
            if weapon.classname not in weapon_classnames:
                continue

            if weapon.classname in PROJECTILE_CLASSNAMES:
                continue

            weapon_class = weapon_manager[weapon.classname]
            if not weapon.has_ammo() or weapon_class.maxammo <= 0:
                continue

            weapon.ammo = weapon_class.maxammo
            maxed_weapons.append(weapon)

        return maxed_weapons

    def _refill_infinite_ammo(self):
        self.max_ammo(self.infinite_weapons)

        self._ammo_refill_delay = Delay(INFINITE_AMMO_REFILL_INTERVAL,
                                        self._refill_infinite_ammo)

    def infinite_on(self):
        if (self._ammo_refill_delay is not None
                or self._nade_refill_delay is not None):

            raise ValueError("Infinite equipment is already turned on")

        maxed_weapon_classnames = map(lambda weapon: weapon.classname,
                                      self.max_ammo(self.infinite_weapons))

        self.infinite_weapons = list(
            filter(
                lambda classname: classname in maxed_weapon_classnames or
                classname in PROJECTILE_CLASSNAMES, self.infinite_weapons))

        self._ammo_refill_delay = Delay(INFINITE_AMMO_REFILL_INTERVAL,
                                        self._refill_infinite_ammo)

    def infinite_off(self):
        if self._ammo_refill_delay is None:
            raise ValueError("Infinite equipment is already turned off")

        self._ammo_refill_delay.cancel()
        self._ammo_refill_delay = None

        if self._nade_refill_delay is not None:
            if self._nade_refill_delay.running:
                self._nade_refill_delay.cancel()

            self._nade_refill_delay = None