view skaapsteker/sprites/items.py @ 630:2707b33cbcb7

Unbreak breakable items
author Neil Muller <drnlmuller@gmail.com>
date Wed, 29 Jun 2011 18:30:50 +0200
parents da331c80ec08
children
line wrap: on
line source

from .. import engine, data, sound
from .base import Item, PC_LAYER, PROJECTILE_LAYER, notify

import time




class BreakableItem(Item):
    whole_image_file = None
    broken_image_file = None
    breaking_sound = None, None

    collides_with = set([PC_LAYER, PROJECTILE_LAYER])

    def setup(self, broken, **opts):
        super(BreakableItem, self).setup(**opts)
        self.broken = broken
        if self.breaking_sound[0] is not None:
            track, volume = self.breaking_sound
            sound.load_sound(track, track, volume)

    def setup_image_data(self, pos, **opts):
        self.image_file = self.broken_image_file if opts['broken'] else self.whole_image_file
        super(BreakableItem, self).setup_image_data(pos)


    def smash(self):
        if not self._me.broken:
            self._me.broken = True
            self.broken = True
            self.setup_image_data(self.get_tile_pos(), broken=self.broken)
            if self.breaking_sound[0] is not None:
                sound.play_sound(self.breaking_sound[0])

    def damage(self, damage):
        self.smash()


##################################################
# Collectibles

class Aburage(Item):
    image_file = 'props/tofu.png'

    def player_action(self, player):
        player.eat_aburage()
        self.remove()


class HaikuScroll(Item):
    image_file = 'props/haiku-scroll.png'

    def player_action(self, player):
        player.collect_scroll(self)
        notify("The scroll looks like a fragment of a haiku: '%s'" % self.text)
        self.remove()


    def setup(self, text, **opts):
        super(HaikuScroll, self).setup(**opts)
        self.text = text



##################################################
# Monk tea mission

class TeaCup(Item):
    image_file = 'props/teacup_empty.png'


class TeaLeaf(Item):
    image_file = 'props/tealeaf.png'


class TeaCupFull(Item):
    image_file = 'props/teacup_full.png'


class TeaPot(Item):
    image_file = 'props/teapot.png'

    def setup(self, brewed, **opts):
        super(TeaPot, self).setup(**opts)


    def player_action(self, player):
        if player.has_item('tealeaf'):
            self._me.brewed = True
            player.discard_item()
            notify("A nice cup of tea is brewing.")
            return
        if player.has_item('teacup'):
            if self._me.brewed:
                player.discard_item()
                player.take_item_by_name('teacupfull')
                self._me.brewed = False
                notify("You pour a cup of tea.")
            else:
                notify("Sadly, the teapot is empty.")
            return
        notify("A proper tea ceremony requires a cup.")



##################################################
# Guard seduction


class Fan(Item):
    image_file = 'props/fan.png'

    def player_action(self, player):
        player.get_fan(self)



##################################################
# Samurai distraction


class Kindling(Item):
    image_file = 'props/kindling.png'


class Oil(Item):
    image_file = 'props/oil.png'


class SignalFire(Item):
    image_file = 'props/signal_fire/signal_fire_unlit.png'

    animation_files = ['props/signal_fire/signal_fire_lit01.png',
            'props/signal_fire/signal_fire_lit02.png',
            'props/signal_fire/signal_fire_lit03.png',
            'props/signal_fire/signal_fire_lit04.png']

    wants_updates = True

    def setup(self, litness, **opts):
        super(SignalFire, self).setup(**opts)
        self._last_time = None
        self._frame = 0
        self.animations = [data.load_image(self.image_dir + x) for x in self.animation_files]


    def player_action(self, player):
        if self._me.litness == 'set':
            if player.has_item('kindling'):
                notify("You put the kindling in the signal fire.")
                self._me.litness = 'kindled'
            elif player.has_item('oil'):
                notify("You pour the oil on the signal fire.")
                self._me.litness = 'oiled'
            else:
                notify("This signal fire needs some oil and kindling before it can be lit.")
                return
            player.discard_item()

        elif self._me.litness in ['oiled', 'kindled']:
            if player.has_item('kindling'):
                notify("You put the kindling on the signal fire and light it.")
            elif player.has_item('oil'):
                notify("You pour the oil on the signal fire and light it.")
            else:
                if self._me.litness == 'oiled':
                    notify("This fire still needs some kindling before it can be lit.")
                else:
                    notify("This fire still needs some oil before it can be lit.")
                return
            player.discard_item()
            self._me.litness = 'burning'
            self.world.missions.fire_started_on_road = True

    def update(self):
        if self._me.litness != 'burning':
            return
        if self._last_time is None:
            self._last_time = time.time()
            return
        if time.time() - self._last_time > 0.1:
            self._last_time = time.time()
            self._frame += 1
            if self._frame >= len(self.animations):
                self._frame = 0
            pos = self.rect.midbottom
            self.image = self.animations[self._frame]
            self.rect = self.image.get_rect(midbottom=pos)
            self.collide_rect = self.rect.move(0, 0)


##################################################
# Cannon destruction


class Cannon(BreakableItem):
    whole_image_file = 'props/cannon-whole.png'
    broken_image_file = 'props/cannon-broken.png'

    liftable = False

    def setup(self, block, **opts):
        super(Cannon, self).setup(**opts)
        self.block = block

    def smash(self):
        self._me.block = False
        self.block = False
        super(Cannon, self).smash()
        self.world.missions.cannon_destroyed = True


##################################################
# Geisha character assassination


class Vase(BreakableItem):
    whole_image_file = 'props/vase-whole.png'
    broken_image_file = 'props/vase-broken.png'
    breaking_sound = 'sounds/vase breaking.ogg', 0.1

    liftable = False

    def smash(self):
        if not self._me.broken:
            notify('Oh no, my beautiful vase! What will the businessman think '
                    'to see it broken on the floor?')
        super(Vase, self).smash()


class Salmon(Item):
    image_file = 'props/fish.png'

    def __init__(self, *args, **kw):
        super(Salmon, self).__init__(*args, **kw)
        if self._me.level == 'geisha_room':
            self.wants_updates = True

    def update(self):
        self.world.missions.fish_in_room = True
        self.remove()
        notify("What's that horrible smell?")



##################################################
# Theatrical debut


class NoMask(BreakableItem):
    whole_image_file = 'props/no-mask-whole.png'
    broken_image_file = 'props/no-mask-broken.png'

    liftable = False


    def smash(self):
        super(NoMask, self).smash()
        if self.world.items.no_costume.level == '_limbo':
            self.world.missions.masks_destroyed = True



class NoCostume(Item):
    image_file = 'props/no-costume.png'

    def player_action(self, player):
        self.remove()
        notify("I think I'll hide this away somewhere.")
        if self.world.items.no_mask.broken:
            self.world.missions.masks_destroyed = True


##################################################
# Big business


class Rice(BreakableItem):
    whole_image_file = 'props/rice-whole.png'
    broken_image_file = 'props/rice-broken.png'
    breaking_sound = 'sounds/tearing-rice bag.ogg', 0.2

    liftable = False

    def smash(self):
        super(Rice, self).smash()
        if self.world.items.documents.broken:
            self.world.missions.kanedas_agreement_disrupted = True


class Documents(BreakableItem):
    whole_image_file = 'props/documents.png'
    broken_image_file = 'props/documents.png'

    msg = "Let's see if they notice if I add a zero."

    def player_action(self, player):
        if not self._me.broken:
            notify(self.msg)
        super(Documents, self).smash()
        if self.world.items.rice.broken:
            self.world.missions.kanedas_agreement_disrupted = True


##################################################
# Tails

class Tail(Item):

    image_dir = 'icons/tails/'
    image_file = None
    tail_type = None
    help_msg = None

    def player_action(self, player):
        player.add_tail(self.tail_type)
        notify(self.help_msg)
        self.remove()


class ShapeshiftTail(Tail):
    image_file = 'shapeshift.png'
    tail_type = 'shapeshift'
    help_msg = "Shapeshifting tail. Press C to shape shift." \
               " Your powers are more limited while in human form."


class FireballTail(Tail):
    image_file = 'fireball.png'
    tail_type = 'fireball'
    help_msg = "Fireball tail. The X attack key now shoots fireballs."


class SprintTail(Tail):
    image_file = 'sprint.png'
    tail_type = 'sprint'
    help_msg = "Sprint tail. Double-tap the left or right arrow key to" \
               " sprint for a few seconds."


class InvisibilityTail(Tail):
    image_file = 'invisibility.png'
    tail_type = 'invisibility'
    help_msg = "Invisibility tail. Press V to become invisible for a few seconds." \
               " You become visible again if you attack or interact with others."


class FlightTail(Tail):
    image_file = 'flight.png'
    tail_type = 'flight'
    help_msg = "Flight tail. Double-tap up to fly. Press down while on the ground to land." \
               " If you stay in the air too long you'll tire and fall."


class ShieldTail(Tail):
    image_file = 'shield.png'
    tail_type = 'shield'
    help_msg = "Shield tail. If you get hit, your mystical shield will protect you for" \
               " one second. After that it'll need a little time to recharge."


class StealTail(Tail):
    image_file = 'steal.png'
    tail_type = 'steal'
    help_msg = "Life-stealing tail. If you projectiles hit your enemies, you steal some" \
               " of their life."


class LightningTail(Tail):
    image_file = 'lightning.png'
    tail_type = 'lightning'
    help_msg = "Lightning tail. The Z attack now shoots lightning bolts."