"""Code for the LLL BBS.
The Lame Local Leeches (LLL) BBS provides all sorts of tools for helping
users through the game. Software and backup methods can be bought/sold
here, the user can gamble away their money (not wise) or even try and
hack the LLL bank (even less wise).
Various user-to-user interaction features are available on LLL as well.
Players can see the list of leeches registered with the game, look at
another leech's stats and post bulletins for all to see.
"""
import time
from hermes import *
import Leech
phoneNumber='5551212'
def menu():
"""Entry point for the LLL menu."""
clearScreen()
print PromptHeaderStyle('Dialing LLL...')
Leech.dialModem(phoneNumber, 2400)
print
runMenu('LLL', clearOnFirstPrint=False)
print
print 'Thanks for calling the LLL BBS! Call again soon...'
print
Leech.hangupModem()
def buySellBackup():
"""Lets users buy and sell backup methods."""
listBackupMethods()
while True:
print
print 'Current backup: %s' % (
Leech.Backups[user.data.backupType].name)
print PromptHeaderStyle(
'You have %s on you (%s in the bank).' % (
formatCurrency(user.data.money, 0),
formatCurrency(user.data.moneyInBank, 0)))
cmd = multipleChoicePrompt(
'Backups Menu (B>uy, S>ell, L>ist, Q>uit): ',
defaultChar='L',
choiceList = {
'B': ('Buy Backup', buyBackup),
'S': ('Sell Backup', sellBackup),
'L': ('List Backup Methods', listBackupMethods),
'Q': ('Quit', None),
})
if not cmd:
break
cmd()
def buyBackup():
"""Lets the users buy a new backup method."""
newBackupType = numericPrompt(
'Which backup method do you want to buy? ',
minValue=1, maxValue=15, autoAccept=False, requireResponse=False)
if newBackupType is None:
print 'Aborted.'
return
newBackup = Leech.Backups[newBackupType - 1]
if newBackup.price > user.data.money:
print
print NoticeStyle('That backup method costs more than you have.')
return
user.data.money -= newBackup.price
user.data.backupType = newBackup.id
print
print 'You bought %s.' % (newBackup.name)
def sellBackup():
"""Lets the user sell their current backup method."""
curBackup = Leech.Backups[user.data.backupType]
print
print 'You can sell your %s for %s.' % (
curBackup.name, curBackup.salePriceString)
if yesNoPrompt('Do you want to sell? '):
user.data.money += curBackup.salePrice
user.data.backupType = 0
print 'Backup sold.'
else:
print 'Aborted.'
def listBackupMethods():
"""List the available backup methods.
The user's current backup method is marked with an asterisk.
"""
clearScreen()
print Leech.HeaderStyle('=' * 78)
print 'BACKUP METHODS'
print Leech.HeaderStyle('-' * 78)
backupMethods = Leech.Backups.items()
backupMethods.sort(lambda a, b: a[1].id - b[1].id)
for id, item in backupMethods:
if id == user.data.backupType:
print '*',
else:
print ' ',
for name, value in (
('Number:', '%2d' % (id + 1)),
('Strength:', '%2d' % item.strength),
('Price:', '%11s' % item.priceString),
('Backup:', '%s' % item.name)):
print '%s %2s ' % (Leech.NameStyle(name), Leech.ValueStyle(value)),
print
def buySellSoftware():
"""Lets users buy and sell software."""
listSoftware()
while True:
print
print 'Current software: %s' % (
Leech.Software[user.data.softwareType].name)
print PromptHeaderStyle(
'You have %s on you (%s in the bank).' % (
formatCurrency(user.data.money, 0),
formatCurrency(user.data.moneyInBank, 0)))
cmd = multipleChoicePrompt(
'Software Menu (B>uy, S>ell, L>ist, Q>uit): ',
defaultChar='L',
choiceList = {
'B': ('Buy Software', buySoftware),
'S': ('Sell Software', sellSoftware),
'L': ('List Software', listSoftware),
'Q': ('Quit', None),
})
if not cmd:
break
cmd()
def buySoftware():
"""Lets the users buy new software."""
newSoftwareType = numericPrompt(
'Which software do you want to buy? ',
minValue=1, maxValue=15, autoAccept=False, requireResponse=False)
if newSoftwareType is None:
print 'Aborted.'
return
newSoftware = Leech.Software[newSoftwareType - 1]
if newSoftware.price > user.data.money:
print
print NoticeStyle('That software costs more than you have.')
return
user.data.money -= newSoftware.price
user.data.softwareType = newSoftware.id
print
print 'You bought %s.' % (newSoftware.name)
def sellSoftware():
"""Lets the user sell their current software."""
curSoftware = Leech.Software[user.data.softwareType]
print
print 'You can sell your %s for %s.' % (
curSoftware.name, curSoftware.salePriceString)
if yesNoPrompt('Do you want to sell? '):
user.data.money += curSoftware.salePrice
user.data.softwareType = 0
print 'Software sold.'
else:
print 'Aborted.'
def listSoftware():
"""List the available software.
The user's current software is marked with an asterisk.
"""
clearScreen()
print Leech.HeaderStyle('=' * 78)
print 'SOFTWARE PROGRAMS'
print Leech.HeaderStyle('-' * 78)
software = Leech.Software.items()
software.sort(lambda a, b: a[1].id - b[1].id)
for id, item in software:
if id == user.data.softwareType:
print '*',
else:
print ' ',
for name, value in (
('Number:', '%2d' % (id + 1)),
('Strength:', '%2d' % item.strength),
('Price:', '%11s' % item.priceString),
('Software:', '%s' % item.name)):
print '%s %2s ' % (Leech.NameStyle(name), Leech.ValueStyle(value)),
print
def examineLeech():
"""Lets the user take a look at another leech's stats.
It costs $10 per level of the player to examine another leech's
stats. This is to increase the difficulty of the game as the leech
increases in level. We don't want high-level players to be able to
pick off the n00bs.
"""
cost = user.data.level * 10
if cost > user.data.money:
print
print 'It costs %s to examine another leech; you only have %s.' % (
formatCurrency(cost, 0), formatCurrency(user.data.money, 0))
return
print
name = textPrompt(
'Enter the name of the leech to examine: ', 32, forceUppercase=True)
if not name:
print 'Aborted.'
return
try:
u = bbs.users[name]
except KeyError:
print 'Unknown user.'
return
if not u.data:
print 'That user is not playing Leech!'
return
if not yesNoPrompt(
'It costs %s to examine a user. Still want to do it? ' % (
formatCurrency(cost, 0))):
print 'Aborted.'
return
user.data.money -= cost
Leech.printStats(u)
def gamble():
"""Gives the user a chance to gamble away all of their money, or as
much as they are willing to part with.
The user has a 20% chance of success. Not exactly great odds, but
what do you expect, the LLL BBS is run by leeches.
"""
if user.data.money <= 0:
print
print 'You do not have any money. What were you planning on'
print 'gambling with?'
return
print
print PromptHeaderStyle(
'You have %s on you.' % formatCurrency(user.data.money, 0))
amount = numericPrompt(
'How much do you want to gamble? ',
minValue=0, maxValue=user.data.money,
autoAccept=False, requireResponse=False)
print
if not amount:
print 'Nothing at all? Pretty safe bet...'
return
if instance.randrange(5):
user.data.money -= amount
print NoticeStyle('You lost! Better luck next time...')
return
user.data.money += amount
print Style(fgGreen)('You won %s!' % formatCurrency(amount, 0))
def hackBank():
"""Offers the user the chance to steal all of the money in the LLL
bank; at very high risk, of course.
The hack's chance of success is based on the ratio of the number of
drives the user has left to hack before they get to the next level
and their software power. Users with incredibly powerful software
and very few drives to crack will have a much better chance at
hacking the bank.
If the hack fails, then we increase their drives-to-next-level
counter by five times the user's level. So although powerful users
are more likely to be successful at hacking the bank (they tend to
have more powerful software, for example), the risks to them for
failing are very high.
If the hack succeeds, the user gets all of the money in the bank.
"""
if instance.data.bankHacks >= prefs.data.bankHacksPerPlay:
print
print 'Sorry, you can only try to hack the bank %d times per play.' % (
prefs.data.bankHacksPerPlay)
return
print
print 'The LLL will be *MAD* if they catch you hacking their bank...'
if not yesNoPrompt('Are you sure you want to try and hack the bank? '):
print 'Probably a good choice...'
return
instance.data.bankHacks += 1
print
print 'Trying to hack the LLL bank',
for i in range(5):
print '.',
time.sleep(0.5)
print
rangeMax = (user.data.drivesLeftToNextLevel * 10) \
/ (user.data.softwareType+1)
if rangeMax < 2:
rangeMax = 2
result = instance.randrange(rangeMax)
if result:
extraHardDrives = user.data.level * 5
user.data.drivesLeftToNextLevel += extraHardDrives
print NoticeStyle(
'You were caught! The LLL now requires you to crash an\n'
'extra %d hard drives to make it to the next level.' % (
extraHardDrives))
return
moneyInAllAccounts = 0
for u in external.users:
moneyInAllAccounts += u.data.moneyInBank
u.data.moneyInBank = 0
user.data.moneyInBank = moneyInAllAccounts
print Style(fgGreen)(
"You successfully hacked the LLL bank! Everyone's\n"
"money is now in your account. You now have %s in"
"the LLL bank." % formatCurrency(user.data.moneyInBank, 0))
def viewChangeBulletin():
"""Displays the current LLL bulletin and lets the user change it."""
clearScreen()
Leech.printBulletin()
print
if not yesNoPrompt('Do you want to change the bulletin? '):
return
print
print PromptStyle('Enter four lines of text:')
line1 = textPrompt('1: ', 72, inputStyle=InputLineStyle)
line2 = textPrompt('2: ', 72, inputStyle=InputLineStyle)
line3 = textPrompt('3: ', 72, inputStyle=InputLineStyle)
line4 = textPrompt('4: ', 72, inputStyle=InputLineStyle)
newBulletin = '%s\n%s\n%s\n%s' % (line1, line2, line3, line4)
print
print PromptHeaderStyle('Here is how your bulletin will look:')
print
Leech.printBulletin(user.name, newBulletin)
print
if not yesNoPrompt('Do you want to post this bulletin? '):
print 'Bulletin cancelled.'
return
bbs.data.lllBulletin = newBulletin
bbs.data.lllBulletinByline = user.name
print 'Your bulletin was saved.'