view gamelib/missions.py @ 35:2754c453b39b

Topple a government.
author Jeremy Thurgood <firxen@gmail.com>
date Sun, 06 May 2012 21:56:21 +0200
parents 20ed2843adec
children efc4f90cfd63
line wrap: on
line source

# -*- coding: utf-8 -*-
# vim:fileencoding=utf-8 ai ts=4 sts=4 et sw=4

from products import HAND_WEAPON, VEHICLE, PATHOGEN, DOOMSDAY_DEVICE

MAJOR_SETBACK, FAILURE, SUCCESS, MAJOR_SUCCESS, GAME_WIN = range(5)


class Result(object):
    """Results of a mission"""

    def __init__(self, outcome, money, reputation, msg):
        self.outcome = outcome
        self.money = money
        self.reputation = reputation
        self.message = msg
        self.applied = False

    def apply(self, state):
        if not self.applied:
            state.money += self.money
            state.reputation += self.reputation
            self.applied = True
            # FIXME: Hook up to the UI
            print self.message
        else:
            raise RuntimeError('attempted to apply result twice')


class Mission(object):
    """Base class for the mission objects.
       Missions have a name, short description (for list displays) and
       long description (which may contain clues about approaches)"""

    NAME = "Generic Mission"
    SHORT_DESCRIPTION = None
    LONG_DESCRIPTION = None
    MINIMUM_REPUTATION = None
    available = True

    def __init__(self, init_data=None):
        pass

    def save_data(self):
        """Serialize the mission state for saving, etc."""
        return []

    def attempt(self, equipment, state):
        """Attempt the mission with the given equipment list.

          Returns a result object with the results of the mission."""
        return Result(FAILURE, 0, 0, "You can't succceed at this mission")


class PlaygroundBully(Mission):

    NAME = "Rob kids in the playground"
    SHORT_DESCRIPTION = "Steal from those significantly weaker than yourself"
    LONG_DESCRIPTION = ("It's not menancing, or lucrative, but when the bills"
            " are due, no one cares how you earn the money")

    def attempt(self, equipment, state):
        return Result(SUCCESS, 100, -1, "You devote your resources to"
                " robbing kids in a playpark. It's not the finest moment"
                " in your reign of terror, but at least you walked away"
                " with a surprising amount of small change.")


class RansomChina(Mission):

    NAME = "Hold China to ransom"
    SHORT_DESCRIPTION = "Surely a path to riches and fame"
    LONG_DESCRIPTION = "Holding China to ransom. The rewards for" \
          " successfully threatening the largest country in the world" \
          " are great, but the risks are significant. Without " \
          "some serious firepower, the chances of success are small."
    MINIMUM_REPUTATION = 100

    def __init__(self, init_data=None):
        # Track prior approaches to this mission
        self._prior_attempts = set()
        if init_data:
            self._prior_attempts = set(init_data)

    def save_data(self):
        return self._prior_attempts

    def attempt(self, equipment, state):
        failures = []
        reputation = 0
        for item in equipment:
            if item.is_a(DOOMSDAY_DEVICE):
                if item.NAME not in self._prior_attempts:
                    self._prior_attempts.add(item.NAME)
                    return Result(SUCCESS, 1000000, 1, (
                            "Trembling at the threat of your doomsday virus,"
                            " the chinese government pays the ransom."))
                elif item.is_a(PATHOGEN):
                    reputation = -1
                    failures.append(
                        "'Hah, we've developed an antidote to your"
                        " pathogen, doctor. You cannot threaten us with that"
                        " again.'")
                else:
                    reputation = -1
                    failures.append(
                        "'Hah, we know how to deal with that particular"
                        " threat, doctor.'")
            else:
                failures.append("You fail to inspire fear with your %s"
                        % item.NAME)
        return Result(FAILURE, 0, reputation, "\n".join(failures))


class ToppleThirdWorldGovernment(Mission):

    NAME = "Topple a third-world government"
    SHORT_DESCRIPTION = "We could use a more amenable despot there"
    LONG_DESCRIPTION = (
        "It's a small and fairly useless country, but it's still an actual"
        " government that can be toppled. A good test bed for some of the"
        " larger toys in the armory.")
    MINIMUM_REPUTATION = 50

    def attempt(self, equipment, state):
        failures = []
        if not equipment:
            return Result(FAILURE, 0, 0, (
                    "The border post may be poorly guarded, but you need to"
                    " bring *some* kind of weaponry along. Your troops sulk"
                    " on the way home."))
        for item in equipment:
            if any(item.is_a(cat) for cat in (VEHICLE, HAND_WEAPON)):
                return Result(SUCCESS, 10000, 5, (
                        "The corruption and oppression continue, but at least"
                        " the proceeds are making their way into *your*"
                        " pockets. And you don't even have to dirty your own"
                        " jackboots."))
            else:
                failures.append("You fail to inspire fear with your %s"
                        % item.NAME)
        return Result(FAILURE, 0, 0, "\n".join(failures))


class RobBank(Mission):

    NAME = "Rob the local bank"
    SHORT_DESCRIPTION = "A trivial challenge, but easy money"
    LONG_DESCRIPTION = "The security guards and local police are of minor" \
          " concern. Walk in, clean out the vault, walk out. Couldn't be" \
          " simpler."

    def attempt(self, equipment, state):
        failures = []
        if not equipment:
            return Result(FAILURE, 0, 0, "Your attempt to rob the bank"
                    " barehanded is unsuccessful. Fortunately, everyone is"
                    " too stunned to impede your escape.")
        for item in equipment:
            if item.is_a(PATHOGEN):
                if state.reputation < 10:
                    failures.append("The clerk doesn't realise the threat of"
                            " the vial you hold, and, although watching him"
                            " die in agony would be statisfying, you decide"
                            " it's not worth wasting this on something so"
                            " trivial")
                else:
                    return Result(SUCCESS, 1000, 0, "Holding up a bank with"
                            " only a small vial of clear liquid. Now that"
                            " is power.")
            elif item.is_a(HAND_WEAPON):
                return Result(SUCCESS, 1000, 0, "The threat of your weapons is"
                    " enough to inspire an impressive level of cooperation")
            else:
                failures.append("You fail to inspire fear with your %s"
                        % item.NAME)
        return Result(FAILURE, 0, 0, "\n".join(failures))


class DestroyMountRushmore(Mission):

    NAME = "Destroy Mount Rushmore"
    SHORT_DESCRIPTION = "Monuments to other people? Intolerable"
    LONG_DESCRIPTION = "While potentially expensive, destroying" \
            " major monument is a good way to secure your reputation."
    MINIMUM_REPUTATION = 20

    def attempt(self, equipment, state):
        if not self.available:
            raise RuntimeError('Cannot attempt an unavailable mission')
        self.available = False
        return Result(SUCCESS, 0, 100,
            "Mount Rushmore is remarkably easy to destroy.")