<commit_before>from twisted.internet.defer import inlineCallbacks

from battlesnake.conf import settings
from battlesnake.outbound_commands import think_fn_wrappers
from battlesnake.outbound_commands import mux_commands
from battlesnake.outbound_commands import unit_manipulation
from battlesnake.plugins.contrib.arena_master.game_modes.wave_survival.wave_spawning import \
    spawn_wave
from battlesnake.plugins.contrib.arena_master.puppets.announcing import \
    announce_arena_state_change

from battlesnake.plugins.contrib.factions.defines import ATTACKER_FACTION_DBREF, \
    DEFENDER_FACTION_DBREF

from battlesnake.plugins.contrib.arena_master.powerups.fixers import \
    check_unit_for_fixer_use
from battlesnake.plugins.contrib.arena_master.puppets.units.unit_store import \
    ArenaMapUnitStore
from battlesnake.plugins.contrib.arena_master.puppets.strategic_logic import \
    move_idle_units, handle_ai_target_change

ARENA_DIFFICULTY_LEVELS = {
    'easy': {'modifier': 0.5},
    'normal': {'modifier': 0.8},
    'hard': {'modifier': 1.1},
    'overkill': {'modifier': 1.4},
}


class ArenaMasterPuppet(object):
    """
    Represents a single puppet.
    """

    def __init__(self, protocol, dbref, map_dbref, staging_dbref, leader_dbref,
                 map_height, map_width, arena_name, current_wave, game_mode,
                 game_state, difficulty_mod):
        self.protocol = protocol
        self.dbref = dbref
        self.map_dbref = map_dbref
        self.staging_dbref = staging_dbref
        self.leader_dbref = leader_dbref
        # A cache for all units in the arena, plus their states.
        self.unit_store = ArenaMapUnitStore(
            arena_master_puppet=self, unit_change_callback=self.handle_unit_change)
        self.map_width = int(map_width)
        self.map_height = int(map_height)
        self.arena_name = arena_name
        # Currently only 'wave'.
        self.game_mode = game_mode
        # One of: 'Staging', 'In-Between', 'Active', 'Finished'
        self.game_state = game_state
        self.difficulty_mod = float(difficulty_mod)

        ## Wave survival stuff.
        # This is the faction that the arena puppet has control of.
        self.attacking_faction_dbref = ATTACKER_FACTION_DBREF
        # And our protagonists.
        self.defending_faction_dbref = DEFENDER_FACTION_DBREF
        self.current_wave = int(current_wave)
        # This is used to stop the ActiveArenaChecksTimer from overzealously
        # declaring a match over before we either have unit data or before
        # a wave has spawned.
        self.wave_check_cooldown_counter = settings['arena_master']['wave_check_cooldown']

    def __str__(self):
        return u"<ArenaMasterPuppet: %s for map %s>" % (self.dbref, self.map_dbref)

    @property
    def id(self):
        """
        :returns: The arena ID, which is just the dbref without the # sign.
        """

        return self.dbref[1:]

    @property
    def difficulty_name(self):
        """
        Looks up the puppet's difficulty modifier and figures out which difficulty
        level name it falls under.

        :rtype: str
        :returns: The name that matches the difficulty mod.
        """

        for key, val in ARENA_DIFFICULTY_LEVELS.items():
            if self.difficulty_mod == val['modifier']:
                return key
        raise ValueError(
            "Invalid difficulty modifier during name looking: %f" % self.difficulty_mod)

    @inlineCallbacks
    def change_state_to_active(self, protocol):
        """
        This always gets called from the In-Between state. Changes to Active
        state, poops out a wave of units.
        """

        p = protocol
        assert self.game_state == 'In-Between', "Can only go Active from In-Between."
        self.save_defender_tics(protocol)
        yield self.change_game_state(p, 'Active')
        yield self.repair_all_defending_units(protocol)
        message = "%ch%crWARNING: %cwAttacker wave %cc{wave_num}%cw has arrived!%cn".format(
            wave_num=self.current_wave)
        self.pemit_throughout_zone(p, message)
        defenders_bv2 = self.calc_total_defending_units_bv2()
        yield spawn_wave(
            p, self.current_wave, defenders_bv2, self.difficulty_mod, self)

        message = (
            "{arena_name} %(ID: %cc{arena_id}%cw%) has started wave {wave_num}."
        ).format(
            arena_name=self.arena_name, arena_id=self.dbref[1:],
            wave_num=self.current_wave,
        )
        yield announce_arena_state_change(p, message)

    @inlineCallbacks
    def change_state_to_in_between(self, protocol):
        """
        The players have dispatched all attackers, move to the next wave's
        In-Between period.
        """

        p = protocol
        assert self.game_state == 'Active', "Can only go In-Between from Active."
        yield self.change_game_state(p, 'In-Between')
        message = (
            "%chWave %cc{wave_num}%cw complete! Re-opening spawning/de-spawning. "
            "The next wave will arrive when the arena leader types %cgcontinue%cw.%cn".format(
            wave_num=self.current_wave))
        self.pemit_throughout_zone(p, message)

        message = (
            "{arena_name} %(ID: %cc{arena_id}%cw%) has completed wave {wave_num}. "
            "If you'd like to join in, go to the Arena Nexus and: %cgajoin {arena_id}%cw"
        ).format(
            arena_name=self.arena_name, arena_id=self.dbref[1:],
            wave_num=self.current_wave,
        )
        yield announce_arena_state_change(p, message)

        next_wave = self.current_wave + 1
        yield self.set_current_wave(protocol, next_wave)

    @inlineCallbacks
    def change_state_to_finished(self, protocol):
        """
        Our players have all either died, or they're hanging it up from
        the In-Between state.
        """

        p = protocol
        yield self.change_game_state(p, 'Finished')
        message = "%chThe match has ended after %cc{wave_num}%cw wave(s).%cn".format(
            wave_num=self.current_wave - 1)
        self.pemit_throughout_zone(p, message)
        # TODO: Send match summary?
        mux_commands.trigger(p, self.map_dbref, 'DEST_ALL_MECHS.T')

        message = (
            "{arena_name} %(ID: %cc{arena_id}%cw%) has ended after "
            "surviving {wave_num} full waves."
        ).format(
            arena_name=self.arena_name, arena_id=self.dbref[1:],
            wave_num=self.current_wave - 1,
        )
        yield announce_arena_state_change(p, message)

    @inlineCallbacks
    def reset_arena(self, protocol):
        """
        Completely resets the arena back to its wave 1 initial state.
        """

        p = protocol
        yield self.change_game_state(p, 'Staging')
        message = (
            "%chThe arena has been restarted. The match will start when "
            "[name({leader_dbref})] types %cgbegin%cw.%cn".format(
            wave_num=self.current_wave - 1, leader_dbref=self.leader_dbref))
        self.pemit_throughout_zone(p, message)

        message = (
            "{arena_name} %(ID: %cc{arena_id}%cw%) has restarted at wave 1 in "
            "preparation for another match. If you'd like to join, go to the "
            "Arena Nexus and: %cgajoin {arena_id}%cw"
        ).format(
            arena_name=self.arena_name, arena_id=self.dbref[1:],
        )
        yield announce_arena_state_change(p, message)

    @inlineCallbacks<commit_msg>Make arena emits use IDs instead of names.<commit_after>from twisted.internet.defer import inlineCallbacks

from battlesnake.conf import settings
from battlesnake.outbound_commands import think_fn_wrappers
from battlesnake.outbound_commands import mux_commands
from battlesnake.outbound_commands import unit_manipulation
from battlesnake.plugins.contrib.arena_master.game_modes.wave_survival.wave_spawning import \
    spawn_wave
from battlesnake.plugins.contrib.arena_master.puppets.announcing import \
    announce_arena_state_change

from battlesnake.plugins.contrib.factions.defines import ATTACKER_FACTION_DBREF, \
    DEFENDER_FACTION_DBREF

from battlesnake.plugins.contrib.arena_master.powerups.fixers import \
    check_unit_for_fixer_use
from battlesnake.plugins.contrib.arena_master.puppets.units.unit_store import \
    ArenaMapUnitStore
from battlesnake.plugins.contrib.arena_master.puppets.strategic_logic import \
    move_idle_units, handle_ai_target_change

ARENA_DIFFICULTY_LEVELS = {
    'easy': {'modifier': 0.5},
    'normal': {'modifier': 0.8},
    'hard': {'modifier': 1.1},
    'overkill': {'modifier': 1.4},
}


class ArenaMasterPuppet(object):
    """
    Represents a single puppet.
    """

    def __init__(self, protocol, dbref, map_dbref, staging_dbref, leader_dbref,
                 map_height, map_width, arena_name, current_wave, game_mode,
                 game_state, difficulty_mod):
        self.protocol = protocol
        self.dbref = dbref
        self.map_dbref = map_dbref
        self.staging_dbref = staging_dbref
        self.leader_dbref = leader_dbref
        # A cache for all units in the arena, plus their states.
        self.unit_store = ArenaMapUnitStore(
            arena_master_puppet=self, unit_change_callback=self.handle_unit_change)
        self.map_width = int(map_width)
        self.map_height = int(map_height)
        self.arena_name = arena_name
        # Currently only 'wave'.
        self.game_mode = game_mode
        # One of: 'Staging', 'In-Between', 'Active', 'Finished'
        self.game_state = game_state
        self.difficulty_mod = float(difficulty_mod)

        ## Wave survival stuff.
        # This is the faction that the arena puppet has control of.
        self.attacking_faction_dbref = ATTACKER_FACTION_DBREF
        # And our protagonists.
        self.defending_faction_dbref = DEFENDER_FACTION_DBREF
        self.current_wave = int(current_wave)
        # This is used to stop the ActiveArenaChecksTimer from overzealously
        # declaring a match over before we either have unit data or before
        # a wave has spawned.
        self.wave_check_cooldown_counter = settings['arena_master']['wave_check_cooldown']

    def __str__(self):
        return u"<ArenaMasterPuppet: %s for map %s>" % (self.dbref, self.map_dbref)

    @property
    def id(self):
        """
        :returns: The arena ID, which is just the dbref without the # sign.
        """

        return self.dbref[1:]

    @property
    def difficulty_name(self):
        """
        Looks up the puppet's difficulty modifier and figures out which difficulty
        level name it falls under.

        :rtype: str
        :returns: The name that matches the difficulty mod.
        """

        for key, val in ARENA_DIFFICULTY_LEVELS.items():
            if self.difficulty_mod == val['modifier']:
                return key
        raise ValueError(
            "Invalid difficulty modifier during name looking: %f" % self.difficulty_mod)

    @inlineCallbacks
    def change_state_to_active(self, protocol):
        """
        This always gets called from the In-Between state. Changes to Active
        state, poops out a wave of units.
        """

        p = protocol
        assert self.game_state == 'In-Between', "Can only go Active from In-Between."
        self.save_defender_tics(protocol)
        yield self.change_game_state(p, 'Active')
        yield self.repair_all_defending_units(protocol)
        message = "%ch%crWARNING: %cwAttacker wave %cc{wave_num}%cw has arrived!%cn".format(
            wave_num=self.current_wave)
        self.pemit_throughout_zone(p, message)
        defenders_bv2 = self.calc_total_defending_units_bv2()
        yield spawn_wave(
            p, self.current_wave, defenders_bv2, self.difficulty_mod, self)

        message = (
            "Arena %cc{arena_id}%cw has started wave {wave_num}."
        ).format(
            arena_id=self.dbref[1:],
            wave_num=self.current_wave,
        )
        yield announce_arena_state_change(p, message)

    @inlineCallbacks
    def change_state_to_in_between(self, protocol):
        """
        The players have dispatched all attackers, move to the next wave's
        In-Between period.
        """

        p = protocol
        assert self.game_state == 'Active', "Can only go In-Between from Active."
        yield self.change_game_state(p, 'In-Between')
        message = (
            "%chWave %cc{wave_num}%cw complete! Re-opening spawning/de-spawning. "
            "The next wave will arrive when the arena leader types %cgcontinue%cw.%cn".format(
            wave_num=self.current_wave))
        self.pemit_throughout_zone(p, message)

        message = (
            "Arena %cc{arena_id}%cw has completed wave {wave_num}. "
            "If you'd like to join in, go to the Arena Nexus and: %cgajoin {arena_id}%cw"
        ).format(
            arena_id=self.dbref[1:],
            wave_num=self.current_wave,
        )
        yield announce_arena_state_change(p, message)

        next_wave = self.current_wave + 1
        yield self.set_current_wave(protocol, next_wave)

    @inlineCallbacks
    def change_state_to_finished(self, protocol):
        """
        Our players have all either died, or they're hanging it up from
        the In-Between state.
        """

        p = protocol
        yield self.change_game_state(p, 'Finished')
        message = "%chThe match has ended after %cc{wave_num}%cw wave(s).%cn".format(
            wave_num=self.current_wave - 1)
        self.pemit_throughout_zone(p, message)
        # TODO: Send match summary?
        mux_commands.trigger(p, self.map_dbref, 'DEST_ALL_MECHS.T')

        message = (
            "Arena %cc{arena_id}%cw has ended after "
            "surviving {wave_num} full waves."
        ).format(
            arena_id=self.dbref[1:],
            wave_num=self.current_wave - 1,
        )
        yield announce_arena_state_change(p, message)

    @inlineCallbacks
    def reset_arena(self, protocol):
        """
        Completely resets the arena back to its wave 1 initial state.
        """

        p = protocol
        yield self.change_game_state(p, 'Staging')
        message = (
            "%chThe arena has been restarted. The match will start when "
            "[name({leader_dbref})] types %cgbegin%cw.%cn".format(
            wave_num=self.current_wave - 1, leader_dbref=self.leader_dbref))
        self.pemit_throughout_zone(p, message)

        message = (
            "Arena %cc{arena_id}%cw has restarted at wave 1 in "
            "preparation for another match. If you'd like to join, go to the "
            "Arena Nexus and: %cgajoin {arena_id}%cw"
        ).format(
            arena_id=self.dbref[1:],
        )
        yield announce_arena_state_change(p, message)

    @inlineCallbacks
{'fraction_non_alphanumeric': 0.09052971663189069, 'fraction_numerical': 0.002961566938143636, 'mean_word_length': 2.6071862102452052, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2401097', 'n_tokens_mistral': 4712, 'n_tokens_neox': 4536, 'n_words': 1088}