Example #1
0
    def shoot(var, wrapper, message):
        """Use this to fire off a bullet at someone in the day if you have bullets."""
        if not GUNNERS[wrapper.source]:
            wrapper.pm(messages["no_bullets"])
            return

        target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="gunner_target_self")
        if not target:
            return

        target = try_misdirection(var, wrapper.source, target)
        if try_exchange(var, wrapper.source, target):
            return

        GUNNERS[wrapper.source] -= 1

        gun_evt = Event("gun_chances", {"hit": 0, "miss": 0, "headshot": 0})
        gun_evt.dispatch(var, wrapper.source, rolename)

        rand = random.random() # need to save it

        shoot_evt = Event("gun_shoot", {"hit": rand <= gun_evt.data["hit"], "kill": random.random() <= gun_evt.data["headshot"]})
        shoot_evt.dispatch(var, wrapper.source, target)

        realrole = get_main_role(target)
        targrole = get_reveal_role(target)

        if shoot_evt.data["hit"]:
            wrapper.send(messages["shoot_success"].format(wrapper.source, target))
            an = "n" if targrole.startswith(("a", "e", "i", "o", "u")) else ""
            if realrole in Wolf:
                if var.ROLE_REVEAL == "on":
                    wrapper.send(messages["gunner_victim_wolf_death"].format(target, an, targrole))
                else: # off and team
                    wrapper.send(messages["gunner_victim_wolf_death_no_reveal"].format(target))
                add_dying(var, target, killer_role=get_main_role(wrapper.source), reason="gunner_victim")
                if kill_players(var):
                    return
            elif shoot_evt.data["kill"]:
                accident = "accidentally "
                if gun_evt.data["headshot"] == 1: # would always headshot
                    accident = ""
                wrapper.send(messages["gunner_victim_villager_death"].format(target, accident))
                if var.ROLE_REVEAL in ("on", "team"):
                    wrapper.send(messages["gunner_victim_role"].format(an, targrole))
                add_dying(var, target, killer_role=get_main_role(wrapper.source), reason="gunner_victim")
                if kill_players(var):
                    return
            else:
                wrapper.send(messages["gunner_victim_injured"].format(target))
                add_absent(var, target, "wounded")
                from src.wolfgame import chk_decision, chk_win
                chk_decision()
                chk_win()

        elif rand <= gun_evt.data["hit"] + gun_evt.data["miss"]:
            wrapper.send(messages["gunner_miss"].format(wrapper.source))
        else: # BOOM! your gun explodes, you're dead
            if var.ROLE_REVEAL in ("on", "team"):
                wrapper.send(messages["gunner_suicide"].format(wrapper.source, get_reveal_role(wrapper.source)))
            else:
                wrapper.send(messages["gunner_suicide_no_reveal"].format(wrapper.source))
            add_dying(var, wrapper.source, killer_role="villager", reason="gunner_suicide") # blame explosion on villager's shoddy gun construction or something
            kill_players(var)
Example #2
0
    def shoot(var, wrapper, message):
        """Use this to fire off a bullet at someone in the day if you have bullets."""
        if not GUNNERS[wrapper.source]:
            wrapper.pm(messages["no_bullets"])
            return

        target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="gunner_target_self")
        if not target:
            return

        target = try_misdirection(var, wrapper.source, target)
        if try_exchange(var, wrapper.source, target):
            return

        GUNNERS[wrapper.source] -= 1

        gun_evt = Event("gun_chances", {"hit": 0, "miss": 0, "headshot": 0})
        gun_evt.dispatch(var, wrapper.source, rolename)

        rand = random.random() # need to save it

        shoot_evt = Event("gun_shoot", {"hit": rand <= gun_evt.data["hit"], "kill": random.random() <= gun_evt.data["headshot"]})
        shoot_evt.dispatch(var, wrapper.source, target)

        realrole = get_main_role(target)
        targrole = get_reveal_role(target)

        if shoot_evt.data["hit"]:
            wrapper.send(messages["shoot_success"].format(wrapper.source, target))
            an = "n" if targrole.startswith(("a", "e", "i", "o", "u")) else ""
            if realrole in Wolf:
                if var.ROLE_REVEAL == "on":
                    wrapper.send(messages["gunner_victim_wolf_death"].format(target, an, targrole))
                else: # off and team
                    wrapper.send(messages["gunner_victim_wolf_death_no_reveal"].format(target))
                add_dying(var, target, killer_role=get_main_role(wrapper.source), reason="gunner_victim")
                if kill_players(var):
                    return
            elif shoot_evt.data["kill"]:
                accident = "accidentally "
                if gun_evt.data["headshot"] == 1: # would always headshot
                    accident = ""
                wrapper.send(messages["gunner_victim_villager_death"].format(target, accident))
                if var.ROLE_REVEAL in ("on", "team"):
                    wrapper.send(messages["gunner_victim_role"].format(an, targrole))
                add_dying(var, target, killer_role=get_main_role(wrapper.source), reason="gunner_victim")
                if kill_players(var):
                    return
            else:
                wrapper.send(messages["gunner_victim_injured"].format(target))
                add_absent(var, target, "wounded")
                from src.votes import chk_decision
                from src.wolfgame import chk_win
                if not chk_win():
                    # game didn't immediately end due to injury, see if we should force through a vote
                    chk_decision(var)

        elif rand <= gun_evt.data["hit"] + gun_evt.data["miss"]:
            wrapper.send(messages["gunner_miss"].format(wrapper.source))
        else: # BOOM! your gun explodes, you're dead
            if var.ROLE_REVEAL in ("on", "team"):
                wrapper.send(messages["gunner_suicide"].format(wrapper.source, get_reveal_role(wrapper.source)))
            else:
                wrapper.send(messages["gunner_suicide_no_reveal"].format(wrapper.source))
            add_dying(var, wrapper.source, killer_role="villager", reason="gunner_suicide") # blame explosion on villager's shoddy gun construction or something
            kill_players(var)
Example #3
0
def chk_decision(var, *, timeout=False):
    with var.GRAVEYARD_LOCK:
        players = set(get_players()) - get_absent(var)
        avail = len(players)
        needed = avail // 2 + 1

        to_vote = []

        for votee, voters in VOTES.items():
            votes = (set(voters)
                     | get_forced_votes(var, votee)) - get_forced_abstains(var)
            if sum(get_vote_weight(var, x) for x in votes) >= needed:
                to_vote.append(votee)
                break

        behaviour_evt = Event("lynch_behaviour", {
            "num_lynches": 1,
            "kill_ties": False,
            "force": timeout
        },
                              votes=VOTES,
                              players=avail)
        behaviour_evt.dispatch(var)

        num_lynches = behaviour_evt.data["num_lynches"]
        kill_ties = behaviour_evt.data["kill_ties"]
        force = behaviour_evt.data["force"]

        abstaining = False
        if not to_vote:
            if len(ABSTAINS | get_forced_abstains(var)) >= avail / 2:
                abstaining = True
            elif force:
                voting = []
                if VOTES:
                    plurality = [(x, len(y)) for x, y in VOTES.items()]
                    plurality.sort(key=lambda x: x[1])
                    votee, value = plurality.pop()
                    max_value = value
                    # Fetch all of the highest ties, exit out if we find someone lower
                    # If everyone is tied, then at some point plurality will be empty,
                    # but the values will still be at the max. Everything's fine, just break
                    while value == max_value:
                        voting.append(votee)
                        if not plurality:
                            break
                        votee, value = plurality.pop()

                if len(voting) == 1:
                    to_vote.append(voting[0])
                elif voting and kill_ties:
                    if set(voting) == set(
                            get_players()
                    ):  # killing everyone off? have you considered not doing that
                        abstaining = True
                    else:
                        to_vote.extend(voting)
                else:
                    abstaining = True

        if abstaining:
            for forced_abstainer in get_forced_abstains(var):
                if forced_abstainer not in ABSTAINS:  # did not explicitly abstain
                    channels.Main.send(messages["player_meek_abstain"].format(
                        forced_abstainer))

            abstain_evt = Event("abstain", {})
            abstain_evt.dispatch(var, ABSTAINS | get_forced_abstains(var))

            global ABSTAINED
            ABSTAINED = True
            channels.Main.send(messages["village_abstain"])

            from src.wolfgame import transition_night
            transition_night()

        if to_vote:
            global LYNCHED
            LYNCHED += len(
                to_vote)  # track how many people we've lynched today

            if timeout:
                channels.Main.send(messages["sunset_lynch"])

            for votee in to_vote:
                voters = list(VOTES[votee])
                for forced_voter in get_forced_votes(var, votee):
                    if forced_voter not in voters:  # did not explicitly vote
                        channels.Main.send(messages["impatient_vote"].format(
                            forced_voter, votee))
                        voters.append(
                            forced_voter
                        )  # they need to be counted as voting for them still

                if not try_lynch_immunity(var, votee):
                    lynch_evt = Event("lynch", {}, players=avail)
                    if lynch_evt.dispatch(var, votee, voters):
                        if var.ROLE_REVEAL in ("on", "team"):
                            rrole = get_reveal_role(votee)
                            an = "n" if rrole.startswith(
                                ("a", "e", "i", "o", "u")) else ""
                            lmsg = random.choice(
                                messages["lynch_reveal"]).format(
                                    votee, an, rrole)
                        else:
                            lmsg = random.choice(
                                messages["lynch_no_reveal"]).format(votee)
                        channels.Main.send(lmsg)
                        add_dying(var, votee, "villager", "lynch")

            kill_players(var, end_game=False)  # FIXME

        elif timeout:
            channels.Main.send(messages["sunset"])

        from src.wolfgame import chk_win
        if chk_win():
            return  # game ended, just exit out

        if timeout or LYNCHED >= num_lynches:
            from src.wolfgame import transition_night
            transition_night()
Example #4
0
def chk_decision(var, *, timeout=False):
    with var.GRAVEYARD_LOCK:
        players = set(get_players()) - get_absent(var)
        avail = len(players)
        needed = avail // 2 + 1

        to_vote = []

        for votee, voters in VOTES.items():
            votes = (set(voters) | get_forced_votes(var, votee)) - get_forced_abstains(var)
            if sum(get_vote_weight(var, x) for x in votes) >= needed:
                to_vote.append(votee)
                break

        behaviour_evt = Event("lynch_behaviour", {"num_lynches": 1, "kill_ties": False, "force": timeout}, votes=VOTES, players=avail)
        behaviour_evt.dispatch(var)

        num_lynches = behaviour_evt.data["num_lynches"]
        kill_ties = behaviour_evt.data["kill_ties"]
        force = behaviour_evt.data["force"]

        abstaining = False
        if not to_vote:
            if len(ABSTAINS | get_forced_abstains(var)) >= avail / 2:
                abstaining = True
            elif force:
                voting = []
                if VOTES:
                    plurality = [(x, len(y)) for x, y in VOTES.items()]
                    plurality.sort(key=lambda x: x[1])
                    votee, value = plurality.pop()
                    max_value = value
                    # Fetch all of the highest ties, exit out if we find someone lower
                    # If everyone is tied, then at some point plurality will be empty,
                    # but the values will still be at the max. Everything's fine, just break
                    while value == max_value:
                        voting.append(votee)
                        if not plurality:
                            break
                        votee, value = plurality.pop()

                if len(voting) == 1:
                    to_vote.append(voting[0])
                elif voting and kill_ties:
                    if set(voting) == set(get_players()): # killing everyone off? have you considered not doing that
                        abstaining = True
                    else:
                        to_vote.extend(voting)
                else:
                    abstaining = True

        if abstaining:
            for forced_abstainer in get_forced_abstains(var):
                if forced_abstainer not in ABSTAINS: # did not explicitly abstain
                    channels.Main.send(messages["player_meek_abstain"].format(forced_abstainer))

            abstain_evt = Event("abstain", {})
            abstain_evt.dispatch(var, ABSTAINS | get_forced_abstains(var))

            global ABSTAINED
            ABSTAINED = True
            channels.Main.send(messages["village_abstain"])

            from src.wolfgame import transition_night
            transition_night()

        if to_vote:
            global LYNCHED
            LYNCHED += len(to_vote) # track how many people we've lynched today

            if timeout:
                channels.Main.send(messages["sunset_lynch"])

            for votee in to_vote:
                voters = list(VOTES[votee])
                for forced_voter in get_forced_votes(var, votee):
                    if forced_voter not in voters: # did not explicitly vote
                        channels.Main.send(messages["impatient_vote"].format(forced_voter, votee))
                        voters.append(forced_voter) # they need to be counted as voting for them still

                if not try_lynch_immunity(var, votee):
                    lynch_evt = Event("lynch", {}, players=avail)
                    if lynch_evt.dispatch(var, votee, voters):
                        if var.ROLE_REVEAL in ("on", "team"):
                            rrole = get_reveal_role(votee)
                            an = "n" if rrole.startswith(("a", "e", "i", "o", "u")) else ""
                            lmsg = random.choice(messages["lynch_reveal"]).format(votee, an, rrole)
                        else:
                            lmsg = random.choice(messages["lynch_no_reveal"]).format(votee)
                        channels.Main.send(lmsg)
                        add_dying(var, votee, "villager", "lynch")

            kill_players(var, end_game=False) # FIXME

        elif timeout:
            channels.Main.send(messages["sunset"])

        from src.wolfgame import chk_win
        if chk_win():
            return # game ended, just exit out

        if timeout or LYNCHED >= num_lynches:
            from src.wolfgame import transition_night
            transition_night()