Merge lp:~stefanor/ibid/mexican-shootout into lp:~ibid-core/ibid/old-trunk-pack-0.92

Proposed by Stefano Rivera
Status: Superseded
Proposed branch: lp:~stefanor/ibid/mexican-shootout
Merge into: lp:~ibid-core/ibid/old-trunk-pack-0.92
Diff against target: None lines
To merge this branch: bzr merge lp:~stefanor/ibid/mexican-shootout
Reviewer Review Type Date Requested Status
Jonathan Hitchcock Approve
Review via email: mp+7975@code.launchpad.net

This proposal has been superseded by a proposal from 2009-07-01.

To post a comment you must log in.
Revision history for this message
Stefano Rivera (stefanor) wrote :

Do we want this? The #compsci guys use it when drunk.

Revision history for this message
Jonathan Hitchcock (vhata) wrote :

<3

review: Approve
lp:~stefanor/ibid/mexican-shootout updated
664. By Stefano Rivera

Two common typo weapons

665. By Stefano Rivera

Whitespace

666. By Stefano Rivera

Allow Boolean responses when the bot wasn't addressed

667. By Stefano Rivera

Rework mexican shootout to require confirmation from both parties, draw before firing, and start on the stroke of a minute

668. By Stefano Rivera

Extend accept syntax

669. By Stefano Rivera

Draw weapons responses in incorrect places

670. By Stefano Rivera

Round start time to 30s

671. By Stefano Rivera

Fixes to shootout I'd missed

672. By Stefano Rivera

State the names on start

673. By Stefano Rivera

More acceptance commands

674. By Stefano Rivera

The agressor can't confirm

675. By Stefano Rivera

Spelling

676. By Stefano Rivera

Capitalise names on start

677. By Stefano Rivera

3 spelling errors

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'ibid/plugins/games.py'
2--- ibid/plugins/games.py 1970-01-01 00:00:00 +0000
3+++ ibid/plugins/games.py 2009-06-24 14:33:02 +0000
4@@ -0,0 +1,222 @@
5+import logging
6+from random import choice, gauss, random
7+import re
8+from time import sleep
9+
10+import ibid
11+from ibid.plugins import Processor, match, handler
12+from ibid.config import Option, IntOption, BoolOption, FloatOption
13+from ibid.utils import ibid_version
14+
15+help = {}
16+log = logging.getLogger('plugins.games')
17+
18+help['shootout'] = u"Mexcan Shootout between channel members"
19+class Shootout(Processor):
20+ u"""[mexican] shootout [between] <user> [and] <user>
21+ bang|kapow|pewpew|holyhandgrenadeofantioch"""
22+ feature = 'shootout'
23+
24+ addressed = BoolOption('addressed', 'Must the bot be addressed', True)
25+
26+ extremities = Option('extremities', u'Extremities that can be hit', (
27+ u'toe', u'foot', u'leg', u'thigh', u'finger', u'hand', u'arm',
28+ u'elbow', u'shoulder', u'ear', u'nose', u'stomach',
29+ ))
30+
31+ vitals = Option('vitals', 'Vital parts of the body that can be hit', (
32+ u'head', u'groin', u'chest', u'heart', u'neck',
33+ ))
34+
35+ happy_endings = Option('happy_endings', 'Both survive', (
36+ u'walk off into the sunset', u'go for a beer', u'call it quits',
37+ ))
38+
39+ weapons = Option('weapons', 'Weapons that can be used: name: (chance, damage)', {
40+ u'bang': (0.75, 70),
41+ u'kapow': (0.75, 90),
42+ u'pewpew': (0.75, 110),
43+ u'holyhandgrenadeofantioch': (1.0, 200),
44+ })
45+
46+ timeout = FloatOption('timeout', 'How long is a duel on for', 10.0)
47+ extratime = FloatOption('extratime', 'How much more time to grant after every shot fire', 1.0)
48+ delay = FloatOption('delay', 'Countdown time', 3.0)
49+
50+ duels = {}
51+
52+ class Duel(object):
53+ pass
54+
55+ @match(r'^(?:mexican\s+)?(?:shootout|standoff|du[ae]l)\s+(?:between\s+)?(\S+)\s+(?:and\s+)?(\S+)$')
56+ def initiate(self, event, a, b):
57+ if not event.addressed:
58+ return
59+
60+ if (event.source, event.channel) in self.duels:
61+ event.addresponse(u"We already have a war in here. Take your fight outside")
62+ return
63+
64+ if a.lower() == b.lower():
65+ # Yes I know schizophrenia isn't the same as DID, but this sounds better :P
66+ event.addresponse(u"Is %s schizophrenic?", a)
67+ return
68+
69+ if [True for name in ibid.config.plugins['core']['names'] if name.lower() in (a.lower(), b.lower())]:
70+ event.addresponse(choice((
71+ u"I'm a peaceful bot",
72+ u"The ref can't take part in the battle",
73+ u"You just want me to die. No way",
74+ )))
75+ return
76+
77+ duel = self.Duel()
78+ self.duels[(event.source, event.channel)] = duel
79+
80+ duel.hp = {a.lower(): 100.0, b.lower(): 100.0}
81+ duel.names = {a.lower(): a, b.lower(): b}
82+
83+ duel.started = False
84+ delay = self.delay and max(gauss(self.delay, self.delay / 2), 0) or 0.0
85+
86+ if self.delay:
87+ duel.start_callback = ibid.dispatcher.call_later(delay, self.start_duel, event)
88+ event.addresponse(True)
89+ else:
90+ self.start_duel(event)
91+
92+ duel.timeout = ibid.dispatcher.call_later(self.timeout + delay, self.end_duel, event)
93+
94+ def start_duel(self, event):
95+ self.duels[(event.source, event.channel)].started = True
96+
97+ event.addresponse(choice((
98+ u'aaaand ... go!',
99+ u'5 ... 4 ... 3 ... 2 ... 1 ... fire!',
100+ u'match on!',
101+ u'ready ... aim ... fire!'
102+ )))
103+
104+ def setup(self):
105+ self.fire.im_func.pattern = re.compile(r'^(%s)(?:[\s,.!:;].*)?$' % '|'.join(self.weapons.keys()), re.I | re.DOTALL)
106+
107+ @handler
108+ def fire(self, event, weapon):
109+ shooter = event.sender['nick']
110+ if (event.source, event.channel) not in self.duels:
111+ return
112+
113+ duel = self.duels[(event.source, event.channel)]
114+
115+ if shooter.lower() not in duel.names:
116+ event.addresponse(choice((
117+ u"You aren't in a war",
118+ u'You are a non-combatant',
119+ u'You are a spectator',
120+ )))
121+ return
122+
123+ # Correct capitalisation from shooter's nick
124+ duel.names[shooter.lower()] = shooter
125+ shooter = shooter.lower()
126+
127+ enemy = set(duel.names.keys())
128+ enemy.remove(shooter)
129+ enemy = enemy.pop()
130+
131+ if not duel.started:
132+ event.addresponse(choice((
133+ u"FOUL! %(shooter)s fired before my mark. Just as well you didn't hit anything. I refuse to referee under these conditions",
134+ u"FOUL! %(shooter)s injures %(enemy)s before the match started and is marched away in handcuffs",
135+ u"FOUL! %(shooter)s killed %(enemy)s before the match started and was shot by the referee before he could hurt anyone else",
136+ )), {
137+ 'shooter': duel.names[shooter],
138+ 'enemy': duel.names[enemy],
139+ })
140+ del self.duels[(event.source, event.channel)]
141+ duel.timeout.cancel()
142+ if duel.start_callback:
143+ duel.start_callback.cancel()
144+ return
145+
146+ chance, power = self.weapons[weapon.lower()]
147+
148+ if random() < chance:
149+ damage = max(gauss(power, power/2.0), 0)
150+ duel.hp[enemy] -= damage
151+ if duel.hp[enemy] <= 0.0:
152+ del self.duels[(event.source, event.channel)]
153+ duel.timeout.cancel()
154+ else:
155+ duel.timeout.delay(self.extratime)
156+
157+ if damage > 100.0:
158+ event.addresponse(u'VICTORY: ' +
159+ choice((
160+ u'%(winner)s blows %(loser)s away',
161+ u'%(winner)s destroys %(loser)s',
162+ )), {
163+ 'winner': duel.names[shooter],
164+ 'loser': duel.names[enemy],
165+ })
166+ elif duel.hp[enemy] <= 0.0:
167+ event.addresponse(u'VICTORY: ' +
168+ choice((
169+ u'%(winner)s kills %(loser)s with a shot to the %(part)s',
170+ u'%(winner)s shoots %(loser)s killing him with a fatal shot to the %(part)s',
171+ )), {
172+ 'winner': duel.names[shooter],
173+ 'loser': duel.names[enemy],
174+ 'part': choice(self.vitals),
175+ })
176+ else:
177+ event.addresponse(
178+ choice((
179+ u'%(winner)s hits %(loser)s in the %(part)s, wounding him',
180+ u'%(winner)s shoots %(loser)s in the %(part)s, but %(loser)s can still fight',
181+ )), {
182+ 'winner': duel.names[shooter],
183+ 'loser': duel.names[enemy],
184+ 'part': choice(self.extremities),
185+ })
186+
187+ else:
188+ event.addresponse(choice((
189+ u'%s misses',
190+ u'%s aims wide',
191+ u'%s is useless with a weapon'
192+ )), duel.names[shooter])
193+
194+ def end_duel(self, event):
195+ duel = self.duels[(event.source, event.channel)]
196+ del self.duels[(event.source, event.channel)]
197+
198+ winner, loser = duel.names.keys()
199+ if duel.hp[winner] < duel.hp[loser]:
200+ winner, loser = loser, winner
201+
202+ if duel.hp[loser] == 100.0:
203+ event.addresponse(u"DRAW: %(a)s and %(b)s shake hands and %(ending)s", {
204+ 'a': duel.names[winner],
205+ 'b': duel.names[loser],
206+ 'ending': choice(self.happy_endings)
207+ })
208+ elif duel.hp[winner] < 50.0:
209+ event.addresponse(u"DRAW: %(a)s and %(b)s bleed to death together", {
210+ 'a': duel.names[winner],
211+ 'b': duel.names[loser],
212+ })
213+ elif duel.hp[loser] < 50.0:
214+ event.addresponse(u"VICTORY: %s bleeds to death", duel.names[loser])
215+ elif duel.hp[winner] < 100.0:
216+ event.addresponse(u"DRAW: %(a)s and %(b)s hobble off together", {
217+ 'a': duel.names[winner],
218+ 'b': duel.names[loser],
219+ })
220+ else:
221+ event.addresponse(u"VICTORY: %(loser)s hobbles off while %(winner)s looks victorious", {
222+ 'loser': duel.names[loser],
223+ 'winner': duel.names[winner],
224+ })
225+
226+# vi: set et sta sw=4 ts=4:

Subscribers

People subscribed via source and target branches