home .. externals .. leech 2000 .. source code ..
Hack.py
# ######################################################################
# Copyright 2005 by Michael Alyn Miller.  All rights reserved.
# vi:et:sts=4
#

"""Code for the hacking portion of the game."""


# ######################################################################
# IMPORTS
#

# Hermes imports.
from hermes import *

# Leech imports.
import Leech



# ######################################################################
# Hack entry point.
#

def hackBbs(bbsNumber):
    
# Initialize the hacking variables.
    
instance.data.theirDrives = bbsNumber
    
instance.data.theirTotalMegs = bbsNumber * 7
    
instance.data.theirMegsLeft = instance.data.theirTotalMegs
    
instance.data.theirSoftwareStrength = bbsNumber
    
instance.data.theirBackupStrength = 1
    
instance.data.theirMoney = bbsNumber * 60

    
# Try and hack the BBS.
    
hack(userWonVsBbs, userLostVsBbs)

def userWonVsBbs():
    
# The user won the battle.
    
print
    
print Style(fgGreen)(
        
'Their computer is FRIED!')

    
# Give the user the BBS' money.
    
print Style(fgGreen)(
        
'And look, the BBS had a bank account with %s in it!' % (
            
formatCurrency(instance.data.theirMoney, 0)))
    
user.data.money += instance.data.theirMoney

    
# Deduct the number of drives destroyed from the user's counter.
    
user.data.drivesLeftToNextLevel -= instance.data.theirDrives

    
# Handle level-ups.
    
checkLevelUp()


def userLostVsBbs():
    
# The user lost the battle.
    
print
    
print Style(fgRed)('There goes your hard disk and half your money!')
    
print Style(fgRed)('Better luck next time...')

    
# Take half their money away.
    
user.data.money /= 2


def hackUser(otherUser):
    
# Initialize the hacking variables.
    
instance.data.otherUser = otherUser

    
instance.data.theirTotalMegs = otherUser.data.totalMegs
    
instance.data.theirMegsLeft = instance.data.theirTotalMegs
    
instance.data.theirSoftwareStrength \
        
= Leech.Software[otherUser.data.softwareType].strength
    
instance.data.theirBackupStrength \
        
= Leech.Backups[otherUser.data.backupType].strength

    
# Try and hack the BBS.
    
hack(userWonVsUser, userLostVsUser)

def userWonVsUser():
    
# Get the other user.
    
otherUser = instance.data.otherUser

    
# The user won the battle.
    
print
    
print Style(fgGreen)(
        
'Their computer is FRIED!')

    
# Give the user the other user's money.
    
print Style(fgGreen)(
        
'And look, the user had %s on them!' % (
            
formatCurrency(otherUser.data.money, 0)))
    
user.data.money += otherUser.data.money
    
otherUser.data.money = 0

    
# Level upgrades and such are handled based on whether or not the
    
# other user is of a higher level than the current user.
    
if user.data.level >= otherUser.data.level:
        
# This user is of a higher level than the other user.  We get
        
# credit for their killing the user (as well as any potential
        
# level upgrades), but nothing else.
        
user.data.drivesLeftToNextLevel -= otherUser.data.level * 3

        
# Handle any potential level-ups resulting from this battle.
        
checkLevelUp()
    
else:
        
# This user is of a lesser level than the other user.  As a
        
# result, the users swap levels as well as the number of drives
        
# left to the next level.
        
user.data.level, otherUser.data.level \
            
= otherUser.data.level, user.data.level
        
user.data.drivesLeftToNextLevel, otherUser.data.drivesLeftToNextLevel \
            
= otherUser.data.drivesLeftToNextLevel, \
                
user.data.drivesLeftToNextLevel

        
# Let the user know about the level swap.
        
print
        
print Style(fgGreen)('You defeated a higher-level leech!')
        
print Style(fgGreen)('The LLL promotes you to level %d.' % (
            
user.data.level))
        
print Style(fgGreen)('The other user is demoted to level %d.' % (
            
otherUser.data.level))

    
# Steal the other user's software if it is better than the software
    
# that this user has.
    
if otherUser.data.softwareType > user.data.softwareType:
        
# Swap software.
        
user.data.softwareType, otherUser.data.softwareType \
            
= otherUser.data.softwareType, user.data.softwareType

        
# Let the user know about the swap.
        
print
        
print Style(fgGreen)("You downloaded the other user's software!")

    
# Steal the other user's backup method if it is better than the
    
# backup method that this user has.
    
if otherUser.data.backupType > user.data.backupType:
        
# Swap backup methods.
        
user.data.backupType, otherUser.data.backupType \
            
= otherUser.data.backupType, user.data.backupType

        
# Let the user know about the swap.
        
print
        
print Style(fgGreen)("You stole the other user's backup method!")

def userLostVsUser():
    
# Get the other user.
    
otherUser = instance.data.otherUser

    
# The user lost the battle.
    
print
    
print Style(fgRed)('There goes your hard disk and ALL of your money!')

    
# Give the other user this user's money.
    
otherUser.data.money += user.data.money
    
user.data.money = 0

    
# Give the other user credit for winning this battle.
    
otherUser.data.drivesLeftToNextLevel -= user.data.level * 3

    
# See if the other user gets to level-up.
    
checkLevelUp(otherUser)

    
# Steal this user's software if it is better than the software that
    
# the other user has.
    
if user.data.softwareType > otherUser.data.softwareType:
        
# Swap software.
        
user.data.softwareType, otherUser.data.softwareType \
            
= otherUser.data.softwareType, user.data.softwareType

        
# Let the user know about the swap.
        
print
        
print Style(fgRed)('The other user downloaded your software!')

    
# Steal this user's backup method if it is better than the backup
    
# method that the other user has.
    
if user.data.backupType > otherUser.data.backupType:
        
# Swap backup methods.
        
user.data.backupType, otherUser.data.backupType \
            
= otherUser.data.backupType, user.data.backupType

        
# Let the user know about the swap.
        
print
        
print Style(fgRed)('The other user stole your backup method!')


def hackLLL():
    
# Initialize the hacking variables.  The LLL has 360 megs and uses
    
# the same software/backup that our user does.
    
instance.data.theirTotalMegs = 360
    
instance.data.theirMegsLeft = instance.data.theirTotalMegs
    
instance.data.theirSoftwareStrength \
        
= Leech.Software[user.data.softwareType].strength
    
instance.data.theirBackupStrength \
        
= Leech.Backups[user.data.backupType].strength

    
# Try and hack the BBS.
    
hack(userWonVsLLL, userLostVsLLL, userLostVsLLL)

def userWonVsLLL():
    
# The user won the battle.
    
print
    
print Style(fgGreen)("The LLL's computer is done for!")
    
print Style(fgGreen)('They enter you into the Leech Hall of Fame!')
    
print
    
print 'The game has been reset.  Thanks for playing Leech!'

    
# Add the user to the hall of fame.
    
bbs.data.highScores.append(user.name, time.localtime())

    
# Reset the game.
    
for u in external.users:
        
u.deleteData()

    
# End the user's turn.
    
instance.data.stillPlaying = False

    
# TODO What if there are other users playing?  The game has to end
    
# for them as well...  In fact, they all have to be kicked out,
    
# basically.

def userLostVsLLL():
    
# The user lost the battle.
    
print
    
print Style(fgRed)('The LLL is very upset.  You are demoted to level 30.')
    
print Style(fgRed)('Better luck next time...')

    
# Drop the user down to level 30.
    
user.data.level = 30
    
user.data.drivesLeftToNextLevel = user.data.level * 10

    
# Stop hacking.
    
instance.data.stillHacking = False


def checkLevelUp(u=user):
    
# Nothing to do if the user still has more drives to go.
    
if u.data.drivesLeftToNextLevel > 0:
        
return

    
# The user gets to go up to the next level.  Update their stats.
    
u.data.level += 1
    
u.data.totalMegs += 10
    
u.data.drivesLeftToNextLevel = u.data.level * 10

    
u.data.trojanHorses += 1
    
if u.data.trojanHorses < 0:
        
u.data.trojanHorses = 0
    
elif u.data.trojanHorses > 30:
        
u.data.trojanHorses = 30

    
u.data.fastBackups += 1
    
if u.data.fastBackups < 0:
        
u.data.fastBackups = 0
    
elif u.data.fastBackups > 30:
        
u.data.fastBackups = 30

    
# If the user that is being updated is the user that is currently
    
# playing Leech, then we also need to bump up their megs-left
    
# counter and let them know about the level-up.
    
if u == user:
        
# Increase the user's megs-left counter.
        
instance.data.megsLeft += 10

        
# Tell the user about the level-up.
        
print
        
print Style(fgGreen)(
            
'The LLL is pleased with your work.  You are now level %d!' % (
                
u.data.level))



# ######################################################################
# Hacking commands.
#

def disconnect():
    
# Print the disconnect message.
    
print
    
print 'You unplug your modem before any more damage was done...'

    
# Stop hacking.
    
instance.data.stillHacking = False


def backupFiles():
    
# Make sure the user has some Fast Backups.
    
if user.data.fastBackups <= 0:
        
print
        
print Style(fgRed)(
            
'You are out of Fast Backups, the files are gone for good!')
        
return

    
# One Fast Backup used...
    
user.data.fastBackups -= 1

    
# Recover the user's megs.  But don't recover more megs than the
    
# user's total.
    
megsRecovered \
        
= instance.randrange(1, 5) \
        
* Leech.Backups[user.data.backupType].strength

    
if megsRecovered >= user.data.totalMegs - instance.data.megsLeft:
        
allMegsRecovered = True
        
instance.data.megsLeft = user.data.totalMegs
    
else:
        
allMegsRecovered = False
        
instance.data.megsLeft += megsRecovered

    
# Run the backup program.
    
print
    
print 'You run a backup program',
    
for i in range(5):
        
print '.',
        
time.sleep(0.5)
    
print

    
# Let the user know what we were able to do.
    
if allMegsRecovered:
        
print Style(fgGreen)('All of your megs were recovered!')
    
else:
        
print Style(fgGreen)('You recovered %d megs.' % (megsRecovered))


def trashFiles():
    
# Determine how many of their megs were destroyed and update their
    
# stats.
    
myAttackRoll = instance.randrange(1, 10)
    
theirMegsDestroyed \
        
= (Leech.Software[user.data.softwareType].strength * myAttackRoll) \
        
/ instance.data.theirBackupStrength
    
instance.data.theirMegsLeft -= theirMegsDestroyed

    
# Determine how many of my megs were destroyed and update the user's
    
# stats.
    
theirAttackRoll = instance.randrange(1, 10)
    
myMegsDestroyed \
        
= (instance.data.theirSoftwareStrength * theirAttackRoll) \
        
/ Leech.Backups[user.data.backupType].strength
    
instance.data.megsLeft -= myMegsDestroyed

    
# Print the outcome of the attack.
    
print

    
if theirMegsDestroyed:
        
print Style(fgGreen)(
            
'You trash %s megs!' % (theirMegsDestroyed))
    
else:
        
print Style(fgRed)(
            
'You got line noise!  None of their megs were destroyed.')

    
if myMegsDestroyed:
        
print Style(fgRed)(
            
'They purge %d megs!' % (myMegsDestroyed))
    
else:
        
print Style(fgGreen)(
            
'They deleted an EMPTY directory!  None of your megs were destroyed.')

    
# See if a bug in our software caused us to lose any of our own
    
# megs.
    
if instance.randrange(20) == 0:
        
# A bug in our software was uncovered.  Find out how much damage
        
# was done and update our stats.
        
bugMegs \
            
= instance.randrange(1, 5) \
            
* Leech.Software[user.data.softwareType].strength
        
instance.data.megsLeft -= bugMegs

        
# Let the user know about the problem.
        
print Style(fgRed)(
            
'There was a bug in your software!  %d megs were destroyed.' % (
                
bugMegs))


def uploadTrojanHorse():
    
# Make sure the user has some Trojan Horses.
    
if user.data.trojanHorses <= 0:
        
print
        
print Style(fgRed)('You are out of Trojan Horses!')
        
return

    
# One Trojan Horse used...
    
user.data.trojanHorses -= 1

    
# Find out how many megs our trojan horse destroyed and update our
    
# opponents status.
    
megsDestroyed \
        
= instance.randrange(1, 5) \
        
* Leech.Software[user.data.softwareType].strength
    
instance.data.theirMegsLeft -= megsDestroyed

    
# Upload the trojan horse.
    
print
    
print 'You upload a trojan horse',
    
for i in range(5):
        
print '.',
        
time.sleep(0.5)
    
print

    
# Let the user know what we were able to do.
    
print Style(fgGreen)(
        
'The idiot runs it!  %d megs are trashed!' % (megsDestroyed))



# ######################################################################
# Hacking menu.
#

def hack(wonFunc, lostFunc, disconnectFunc=disconnect):
    
"""Menu for the hacking portion of the game.

    The wonFunc will be called if the user wins, lostFunc will be called
    if the opponent wins.

    If both sides have all of their megs destroyed, then user is
    considered to have lost.
    """


    
# Let the hacking begin...
    
print
    
print 'You begin to hack!'

    
# Keep going until someone loses or the leech runs away.
    
instance.data.stillHacking = True
    
while instance.data.stillHacking:
        
# Print the current stats.
        
print
        
print 'You have %d megs left.' % (instance.data.megsLeft)
        
print 'They have %d megs left.' % (instance.data.theirMegsLeft)

        
# Find out what the user wants to do.
        
cmd = multipleChoicePrompt(
            
'[T]rash Files, [D]isconnect, [U]pload Trojan or [B]ackup Files: ',
            
choiceList={
                
'T': ('Trash Files', trashFiles),
                
'D': ('Disconnect', disconnectFunc),
                
'U': ('Upload Trojan', uploadTrojanHorse),
                
'B': ('Backup Files', backupFiles),
            
})

        
# Run the command.
        
cmd()

        
# See if the battle is over.
        
if instance.data.megsLeft <= 0:
            
# Let the caller's function decide what to do.
            
lostFunc()

            
# We're done hacking.  In fact, this play is over (since the
            
# user lost).
            
instance.data.stillHacking = False
            
instance.data.stillPlaying = False
        
elif instance.data.theirMegsLeft <= 0:
            
# Let the caller's function decide what to do.
            
wonFunc()

            
# We're done hacking.
            
instance.data.stillHacking = False