Skip to content

Commit 3f5a576

Browse files
committed
Refactor duckhunt attacks
1 parent 7d7d930 commit 3f5a576

1 file changed

Lines changed: 80 additions & 109 deletions

File tree

plugins/duckhunt.py

Lines changed: 80 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from cloudbot import hook
1111
from cloudbot.event import EventType
1212
from cloudbot.util import database
13+
from cloudbot.util.formatting import pluralize
1314

1415
duck_tail = "・゜゜・。。・゜゜"
1516
duck = ["\_o< ", "\_O< ", "\_0< ", "\_\u00f6< ", "\_\u00f8< ", "\_\u00f3< "]
@@ -123,7 +124,7 @@ def incrementMsgCounter(event, conn):
123124

124125

125126
@hook.command("starthunt", autohelp=False, permissions=["chanop", "op", "botcontrol"])
126-
def start_hunt(bot, chan, message, conn):
127+
def start_hunt(chan, message, conn):
127128
"""- This command starts a duckhunt in your channel, to stop the hunt use .stophunt"""
128129
global game_status
129130
if chan in opt_out:
@@ -166,7 +167,7 @@ def stop_hunt(chan, conn):
166167

167168

168169
@hook.command("duckkick", permissions=["chanop", "op", "botcontrol"])
169-
def no_duck_kick(text, chan, conn, notice):
170+
def no_duck_kick(text, chan, conn, notice_doc):
170171
"""<enable|disable> - If the bot has OP or half-op in the channel you can specify .duckkick enable|disable so that people are kicked for shooting or befriending a non-existent goose. Default is off."""
171172
global game_status
172173
if chan in opt_out:
@@ -178,7 +179,7 @@ def no_duck_kick(text, chan, conn, notice):
178179
game_status[conn.name][chan]['no_duck_kick'] = 0
179180
return "kicking for non-existent ducks has been disabled."
180181
else:
181-
notice(no_duck_kick.__doc__)
182+
notice_doc()
182183
return
183184

184185

@@ -192,11 +193,11 @@ def generate_duck():
192193
dnoise = random.choice(duck_noise)
193194
rn = random.randint(1, len(dnoise) - 1)
194195
dnoise = dnoise[:rn] + u'\u200b' + dnoise[rn:]
195-
return (dtail, dbody, dnoise)
196+
return dtail, dbody, dnoise
196197

197198

198199
@hook.periodic(11, initial_interval=11)
199-
def deploy_duck(message, bot):
200+
def deploy_duck(bot):
200201
global game_status
201202
for network in game_status:
202203
if network not in bot.connections:
@@ -210,17 +211,13 @@ def deploy_duck(message, bot):
210211
next_duck = game_status[network][chan]['next_duck_time']
211212
chan_messages = game_status[network][chan]['messages']
212213
chan_masks = game_status[network][chan]['masks']
213-
if active == 1 and duck_status == 0 and next_duck <= time() and chan_messages >= MSG_DELAY and len(chan_masks) >= MASK_REQ:
214+
if active == 1 and duck_status == 0 and next_duck <= time() and chan_messages >= MSG_DELAY and len(
215+
chan_masks) >= MASK_REQ:
214216
# deploy a duck to channel
215217
game_status[network][chan]['duck_status'] = 1
216218
game_status[network][chan]['duck_time'] = time()
217219
dtail, dbody, dnoise = generate_duck()
218220
conn.message(chan, "{}{}{}".format(dtail, dbody, dnoise))
219-
# Leave this commented out for now. I haven't decided how to make ducks leave.
220-
# if active == 1 and duck_status == 1 and game_status[network][chan]['flyaway'] <= int(time()):
221-
# conn.message(chan, "The duck flew away.")
222-
# game_status[network][chan]['duck_status'] = 2
223-
# set_ducktime(chan, conn)
224221
continue
225222
continue
226223

@@ -277,139 +274,113 @@ def dbupdate(nick, chan, db, conn, shoot, friend):
277274
db.commit()
278275

279276

280-
@hook.command("bang", autohelp=False)
281-
def bang(nick, chan, message, db, conn, notice):
282-
"""- when there is a duck on the loose use this command to shoot it."""
283-
global game_status, scripters
284-
if chan in opt_out:
285-
return
286-
network = conn.name
287-
score = ""
288-
out = ""
289-
miss = ["WHOOSH! You missed the duck completely!", "Your gun jammed!", "Better luck next time.",
290-
"WTF?! Who are you, Kim Jong Un firing missiles? You missed."]
291-
if not game_status[network][chan]['game_on']:
292-
return "There is no activehunt right now. Use .starthunt to start a game."
293-
elif game_status[network][chan]['duck_status'] != 1:
294-
if game_status[network][chan]['no_duck_kick'] == 1:
295-
out = "KICK {} {} :There is no duck! What are you shooting at?".format(chan, nick)
296-
conn.send(out)
297-
return
298-
return "There is no duck. What are you shooting at?"
277+
def update_score(nick, chan, db, conn, shoot=0, friend=0):
278+
score = db.execute(select([table.c.shot, table.c.befriend])
279+
.where(table.c.network == conn.name)
280+
.where(table.c.chan == chan.lower())
281+
.where(table.c.name == nick.lower())).fetchone()
282+
if score:
283+
score = score[0]
284+
score += 1
285+
dbupdate(nick, chan, db, conn, score[0] + shoot, score[1] + friend)
299286
else:
300-
game_status[network][chan]['shoot_time'] = time()
301-
deploy = game_status[network][chan]['duck_time']
302-
shoot = game_status[network][chan]['shoot_time']
303-
if nick.lower() in scripters:
304-
if scripters[nick.lower()] > shoot:
305-
notice("You are in a cool down period, you can try again in {} seconds.".format(
306-
str(scripters[nick.lower()] - shoot)))
307-
return
308-
chance = hit_or_miss(deploy, shoot)
309-
if not random.random() <= chance and chance > .05:
310-
out = random.choice(miss) + " You can try again in 7 seconds."
311-
scripters[nick.lower()] = shoot + 7
312-
return out
313-
if chance == .05:
314-
out += "You pulled the trigger in {} seconds, that's mighty fast. Are you sure you aren't a script? Take a 2 hour cool down.".format(
315-
str(shoot - deploy))
316-
scripters[nick.lower()] = shoot + 7200
317-
if not random.random() <= chance:
318-
return random.choice(miss) + " " + out
319-
else:
320-
message(out)
321-
game_status[network][chan]['duck_status'] = 2
322-
try:
323-
score = db.execute(select([table.c.shot])
324-
.where(table.c.network == conn.name)
325-
.where(table.c.chan == chan.lower())
326-
.where(table.c.name == nick.lower())).fetchone()
327-
if score:
328-
score = score[0]
329-
score += 1
330-
dbupdate(nick, chan, db, conn, score, 0)
331-
else:
332-
score = 1
333-
dbadd_entry(nick, chan, db, conn, score, 0)
334-
except DatabaseError:
335-
game_status[network][chan]['duck_status'] = 1
336-
raise
337-
338-
timer = "{:.3f}".format(shoot - deploy)
339-
duck = "duck" if score == 1 else "ducks"
340-
message("{} you shot a duck in {} seconds! You have killed {} {} in {}.".format(nick, timer, score, duck, chan))
341-
set_ducktime(chan, conn.name)
287+
dbadd_entry(nick, chan, db, conn, shoot, friend)
342288

343289

344-
@hook.command("befriend", autohelp=False)
345-
def befriend(nick, chan, message, db, conn, notice):
346-
"""- when there is a duck on the loose use this command to befriend it before someone else shoots it."""
290+
def attack(nick, chan, message, db, conn, notice, attack):
347291
global game_status, scripters
348292
if chan in opt_out:
349293
return
294+
350295
network = conn.name
296+
status = game_status[network][chan]
297+
351298
out = ""
352-
score = ""
353-
miss = ["The duck didn't want to be friends, maybe next time.",
299+
if attack == "shoot":
300+
miss = [
301+
"WHOOSH! You missed the duck completely!", "Your gun jammed!",
302+
"Better luck next time.",
303+
"WTF?! Who are you, Kim Jong Un firing missiles? You missed."
304+
]
305+
no_duck = "There is no duck! What are you shooting at?"
306+
msg = "{} you shot a duck in {:.3f} seconds! You have killed {} in {}."
307+
scripter_msg = "You pulled the trigger in {:.3f} seconds, that's mighty fast. Are you sure you aren't a script? Take a 2 hour cool down."
308+
attack_type = "shoot"
309+
else:
310+
miss = [
311+
"The duck didn't want to be friends, maybe next time.",
354312
"Well this is awkward, the duck needs to think about it.",
355313
"The duck said no, maybe bribe it with some pizza? Ducks love pizza don't they?",
356-
"Who knew ducks could be so picky?"]
357-
if not game_status[network][chan]['game_on']:
314+
"Who knew ducks could be so picky?"
315+
]
316+
no_duck = "You tried befriending a non-existent duck. That's freaking creepy."
317+
msg = "{} you befriended a duck in {:.3f} seconds! You have made friends with {} in {}."
318+
scripter_msg = "You tried friending that duck in {:.3f} seconds, that's mighty fast. Are you sure you aren't a script? Take a 2 hour cool down."
319+
attack_type = "friend"
320+
321+
if not status['game_on']:
358322
return "There is no hunt right now. Use .starthunt to start a game."
359-
elif game_status[network][chan]['duck_status'] != 1:
360-
if game_status[network][chan]['no_duck_kick'] == 1:
361-
out = "KICK {} {} :You tried befriending a non-existent duck. That's fucking creepy.".format(chan, nick)
362-
conn.send(out)
323+
elif status['duck_status'] != 1:
324+
if status['no_duck_kick'] == 1:
325+
conn.cmd("KICK", chan, nick, no_duck)
363326
return
364-
return "You tried befriending a non-existent duck. That's freaking creepy."
327+
328+
return no_duck
365329
else:
366-
game_status[network][chan]['shoot_time'] = time()
367-
deploy = game_status[network][chan]['duck_time']
368-
shoot = game_status[network][chan]['shoot_time']
330+
status['shoot_time'] = time()
331+
deploy = status['duck_time']
332+
shoot = status['shoot_time']
369333
if nick.lower() in scripters:
370334
if scripters[nick.lower()] > shoot:
371-
notice("You are in a cool down period, you can try again in {} seconds.".format(
372-
str(scripters[nick.lower()] - shoot)))
335+
notice(
336+
"You are in a cool down period, you can try again in {:.3f} seconds.".format(
337+
scripters[nick.lower()] - shoot
338+
)
339+
)
373340
return
341+
374342
chance = hit_or_miss(deploy, shoot)
375343
if not random.random() <= chance and chance > .05:
376344
out = random.choice(miss) + " You can try again in 7 seconds."
377345
scripters[nick.lower()] = shoot + 7
378346
return out
347+
379348
if chance == .05:
380-
out += "You tried friending that duck in {} seconds, that's mighty fast. Are you sure you aren't a script? Take a 2 hour cool down.".format(
381-
str(shoot - deploy))
349+
out += scripter_msg.format(shoot - deploy)
382350
scripters[nick.lower()] = shoot + 7200
383351
if not random.random() <= chance:
384352
return random.choice(miss) + " " + out
385353
else:
386354
message(out)
387355

388-
game_status[network][chan]['duck_status'] = 2
356+
status['duck_status'] = 2
389357
try:
390-
score = db.execute(select([table.c.befriend])
391-
.where(table.c.network == conn.name)
392-
.where(table.c.chan == chan.lower())
393-
.where(table.c.name == nick.lower())).fetchone()
394-
if score:
395-
score = score[0]
396-
score += 1
397-
dbupdate(nick, chan, db, conn, 0, score)
398-
else:
399-
score = 1
400-
dbadd_entry(nick, chan, db, conn, 0, score)
358+
score = 1
359+
args = {
360+
attack_type: score
361+
}
362+
363+
update_score(nick, chan, db, conn, **args)
401364
except DatabaseError:
402-
game_status[network][chan]['duck_status'] = 1
365+
status['duck_status'] = 1
403366
raise
404367

405-
duck = "duck" if score == 1 else "ducks"
406-
timer = "{:.3f}".format(shoot - deploy)
407-
message(
408-
"{} you befriended a duck in {} seconds! You have made friends with {} {} in {}.".format(nick, timer, score,
409-
duck, chan))
368+
message(msg.format(nick, shoot - deploy, pluralize(score, "duck"), chan))
410369
set_ducktime(chan, conn.name)
411370

412371

372+
@hook.command("bang", autohelp=False)
373+
def bang(nick, chan, message, db, conn, notice):
374+
"""- when there is a duck on the loose use this command to shoot it."""
375+
return attack(nick, chan, message, db, conn, notice, "shoot")
376+
377+
378+
@hook.command("befriend", autohelp=False)
379+
def befriend(nick, chan, message, db, conn, notice):
380+
"""- when there is a duck on the loose use this command to befriend it before someone else shoots it."""
381+
return attack(nick, chan, message, db, conn, notice, "befriend")
382+
383+
413384
def smart_truncate(content, length=320, suffix='...'):
414385
if len(content) <= length:
415386
return content

0 commit comments

Comments
 (0)