Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added miss & some random replies. #258

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 115 additions & 7 deletions modules/ducks.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,56 @@
import random, re, time
from src import EventManager, ModuleManager, utils

DUCK = "・゜゜・。。・゜゜\_o< QUACK!"
DUCK_TAILS = [
"・゜゜・。。・゜゜"
]

DUCK_BODIES = [
"\_o<",
"\_O<",
"\_0<",
"\___o<"
]

DUCK_PHRASES = [
"QUACK!",
"QUACK QUACK!",
"FLAPPITY FLAP!",
"DON'T SHOOT ME!",
"DUCK SEASON!",
"RABBIT SEASON!"
]

MISS_BEF = [
"The duck didn't want to be friends with you.",
"The duck is too busy right now.",
"The duck put you on ignore.",
"The duck is turning you in for stalking!"
]

MISS_TRAP = [
"The duck was too smart for your trap.",
"Your trap missed the duck.",
"You trapped a bear by accident.",
"You need to get your eyes checked.",
"Your trap didn't work."
]

USER_FLOODING = [
"Stop doing that so fast!",
"Are you mad? Slow down!",
"Calm down Road Runner.",
"Turn off your scripts please.",
"Hit the brakes!",
"That's enough, Mr. Trigger Finger."
]

DEFAULT_MIN_MESSAGES = 100

DEFAULT_MAX_COOLDOWN = 10

DEFAULT_CHANCE_MISS = 25

@utils.export("channelset", utils.BoolSetting("ducks-enabled",
"Whether or not to spawn ducks"))
@utils.export("channelset", utils.IntRangeSetting(50, 200, "ducks-min-messages",
Expand All @@ -16,11 +62,19 @@
"Whether or not to kick someone talking to non-existent ducks"))
@utils.export("channelset", utils.BoolSetting("ducks-prevent-highlight",
"Whether or not to prevent highlighting users with !friends/!enemies"))
@utils.export("channelset", utils.IntRangeSetting(5, 30, "ducks-max-cooldown",
"Maximum amount of time a cooldown can last in seconds."))
@utils.export("channelset", utils.IntRangeSetting(0, 100, "ducks-chance-miss",
"Percent chance that someone will miss."))
class Module(ModuleManager.BaseModule):
@utils.hook("new.channel")
def new_channel(self, event):
self.bootstrap_channel(event["channel"])

@utils.hook("new.user")
def new_user(self, event):
event["user"]._duck_cooldown = {}

def bootstrap_channel(self, channel):
if not hasattr(channel, "duck_active"):
channel.duck_active = None
Expand Down Expand Up @@ -61,6 +115,7 @@ def _send_duck(self, timer):
channel = timer.kwargs["channel"]
channel.duck_active = time.time()
channel.duck_lines = 0
DUCK = random.choice(DUCK_TAILS)+" "+random.choice(DUCK_BODIES)+" "+random.choice(DUCK_PHRASES)
channel.send_message(DUCK)

def _duck_action(self, channel, user, action, setting):
Expand Down Expand Up @@ -93,15 +148,50 @@ def _no_duck(self, channel, user, stderr):
else:
stderr.write("%s: %s" % (user.nickname, message))

def _miss_roll(self, channel, user):
try:
user_cd = user._duck_cooldown[channel]
except KeyError:
user_cd = 0
if user_cd < time.time():
percentage = channel.get_setting("ducks-chance-miss",
DEFAULT_CHANCE_MISS)
if random.randrange(0,100) <= percentage:
max_cooldown = channel.get_setting("ducks-max-cooldown",
DEFAULT_MAX_COOLDOWN)
cooldown = random.randrange(1,max_cooldown)
user._duck_cooldown[channel] = time.time()+cooldown
user_cd = user._duck_cooldown[channel]
else:
user._duck_cooldown[channel] = 0
user_cd = user._duck_cooldown[channel]
userflooding = False
else:
userflooding = True
if user_cd >= 0:
cooldown_rem = round((user_cd - time.time()),2)
else:
cooldown_rem = user_cd
return cooldown_rem, userflooding

@utils.hook("received.command.bef", alias_of="befriend")
@utils.hook("received.command.befriend")
@utils.kwarg("help", "Befriend a duck")
@utils.spec("!-channelonly")
def befriend(self, event):
if event["target"].duck_active:
action = self._duck_action(event["target"], event["user"],
"befriended", "ducks-befriended")
event["stdout"].write(action)
channel = event["target"]
user = event["user"]
cooldown_sec = self._miss_roll(channel, user)
if cooldown_sec[0] >= 0:
if cooldown_sec[1] == False:
event["stdout"].write(random.choice(MISS_BEF)+" You may try again in "+str(cooldown_sec[0])+" seconds.")
else:
event["stdout"].write(random.choice(USER_FLOODING)+" You may try again in "+str(cooldown_sec[0])+" seconds.")
else:
action = self._duck_action(event["target"], event["user"],
"befriended", "ducks-befriended")
event["stdout"].write(action)
else:
self._no_duck(event["target"], event["user"], event["stderr"])

Expand All @@ -110,12 +200,30 @@ def befriend(self, event):
@utils.spec("!-channelonly")
def trap(self, event):
if event["target"].duck_active:
action = self._duck_action(event["target"], event["user"],
"trapped", "ducks-shot")
event["stdout"].write(action)
channel = event["target"]
user = event["user"]
cooldown_sec = self._miss_roll(channel, user)
if cooldown_sec[0] >= 0:
if cooldown_sec[1] == False:
event["stdout"].write(random.choice(MISS_TRAP)+" You may try again in "+str(cooldown_sec[0])+" seconds.")
else:
event["stdout"].write(random.choice(USER_FLOODING)+" You may try again in "+str(cooldown_sec[0])+" seconds.")
else:
action = self._duck_action(event["target"], event["user"],
"trapped", "ducks-shot")
event["stdout"].write(action)
else:
self._no_duck(event["target"], event["user"], event["stderr"])

#TODO: Fix or destroy. Used for testing.
# @utils.hook("received.command.getduck")
# @utils.kwarg("help", "Get a duck delivered to the channel.")
# @utils.spec("!-channelonly")
# @utils.kwarg("require_access", "admin,ducks")
# def getduck(self, event):
# channel = event["target"]
# self._trigger_duck(channel)

def _target(self, target, is_channel, query):
if query:
if not query == "*":
Expand Down