Source

Fat x Fast / FatxFast / modes / mode.py

# This file is part of FatxFast.
#
#    FatxFast is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    FatxFast is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with FatxFast.  If not, see <http://www.gnu.org/licenses/>.

# Versioning based on: 
# http://en.wikipedia.org/wiki/Versioning#Designating_development_stage
__author__ = "dryatu (c) 2013"
__version__ = "1.2.4"


from FatxFast import camera
from FatxFast.objects.buffs import BUFF_CLASSES
from FatxFast.objects.triggers import TRIGGER_CLASSES
from FatxFast.objects import triggers
from FatxFast.objects.player import Player
from FatxFast.physics.physics import Physics
from FatxFast import events
from FatxFast.gui.boxwidget import BoxWidget
from FatxFast.input import KeyListener, MouseListener
from FatxFast.events import CollisionEvent
from FatxFast.gametask import GameTask
import pygame


class GameMode(KeyListener, MouseListener):
    
    def __init__(self, scene, **kwargs):

        if scene.time is None:
            scene.time = 0 
        self.player1 = None
        self.scene = scene 
        self.camera = camera.Camera()
        self.scene.levelsystem.load_level()
        self.create_players()    
        self.hotkeys = scene.manager.game.config.hotkeys
        self._gametask_queue = []
        self.scene.paused = False

    def add_task(self, callback, *args, **kwargs):
        self._gametask_queue.append(GameTask(callback, *args, **kwargs))

    def _create_player(self, player_name, camera, add_to_world=True, 
        type=Player):
        x = self.scene.tilemap.properties.get("start_x", 64)
        y = self.scene.tilemap.properties.get("start_y", 64)
        player = self.scene.create_character(type, 
            pos=(x, y), add_to_world=add_to_world) 
        player.name = player_name
        player.register_collision_event(
            triggers.COFFEE_ID, 
            CollisionEvent(kill=True))
        player.register_collision_event(triggers.END_ID, 
            CollisionEvent(callback=self.level_up, callbackargs=[player]))
        getattr(camera, "follow_target")(player)
        self.scene.add_player(player,camera) 
        setattr(self, player_name, player)

    def create_players(self):
        self._create_player("player1", self.camera)
        self._load_player_assets(self.player1)

    def end(self, player, text=""):
        self.scene.game.config.games_played += 1
        self.scene.remove_players()
        self.scene.tilemap.unload_map()
        self.scene.playing = False
        
        self.scene.manager.clear()
        self.scene.manager.push_scene("introscene")
        self.scene.manager.push_scene("gameendscene", text=text,
            played_mode=self.__class__.__name__.lower())

    def key_pressed(self, key, utf, mod):
        if key == self.hotkeys["player1-map"]:
            self.open_map(self.player1)

    def keys_held(self):
        keys = super(GameMode, self).keys_held()
        player1 = self.player1
        if keys[self.hotkeys["player1-up"]]:
            player1.set_accel(y=-Physics.accelspeed)
        elif keys[self.hotkeys["player1-down"]]:
            player1.set_accel(y=Physics.accelspeed)
        else:
            player1.set_accel(y=0)
        if keys[self.hotkeys["player1-left"]]:
            player1.set_accel(x=-Physics.accelspeed)
        elif keys[self.hotkeys["player1-right"]]:
            player1.set_accel(x=Physics.accelspeed)
        else:
            player1.set_accel(x=0)
        if keys[self.hotkeys["player1-turbo"]]:
            player1.turbo()
        return keys

    def level_up(self, player): 
        for player in self.scene.players:
            self.scene.tilemap.world.remove(player)
            player.remove_and_kill_buffs()
        self.scene.tilemap.unload_map()
        self.add_task(self.reload_level)

    def _load_level_assets(self, player):
        if "maps_left" in self.scene.levelsystem.level_complexity["data"]:
            player.maps_left += self.scene.levelsystem.\
                level_complexity["data"]["maps_left"]

    def _load_player_assets(self, player):
        if not self._load_playerdata_from_save(player):
            self._load_level_assets(player)

    def _load_playerdata_from_save(self, player):
        if player.name in self.scene.save.playerdata:
            player_config = self.scene.save.playerdata[player.name]
            if "points" in player_config:
                player.points = player_config["points"]
            if "turbo" in player_config:
                player.set_turbo(player_config["turbo"])
            if "items" in player_config:
                for name, specs in player_config["items"].items():
                    item = BUFF_CLASSES[specs[0]](player, specs[1])
                    item.name = name
                    player.add_item(item)
            if "pos" in player_config:
                player.set_position(player_config["pos"])
            if "buffs" in player_config:
                for buff in player_config["buffs"].values():
                    buff = BUFF_CLASSES[buff[0]](player, buff[1])
                    player.buffs.add(buff)
                    buff.trigger()
            if "maps_left" in player_config:
                player.maps_left = player_config["maps_left"]
            self.scene.save.playerdata[player.name] = {}
            return True

    def open_map(self, player):
        if player.maps_left:
            player.maps_left -= 1
            self.scene.open_map()

    def pause(self):
        self.scene.game.input.remove_key_listener(self)
        self.scene.game.input.remove_mouse_listener(self)
  
    def reload_level(self):
        self.scene.levelsystem.load_level()
        x = self.scene.tilemap.properties.get("start_x", 64)
        y = self.scene.tilemap.properties.get("start_y", 64)
        for player in self.scene.players: 
            player.set_turbo(1)
            self._load_player_assets(player)
            player.set_position((x, y)) 
            self.scene.tilemap.world.add(player)

    def resume(self):
        self.scene.hud.remove_players() 
        self.scene.hud.add_player(self.player1, self.camera)
        self.scene.game.input.add_key_listener(self)
        self.scene.game.input.add_mouse_listener(self)

    def run_task(self): 
        if self._gametask_queue:
            self._gametask_queue.pop()()

    def start(self):
        self.scene.game.input.add_key_listener(self)
        self.scene.game.input.add_mouse_listener(self)
    
    def update(self, dt):
        self.run_task()
        self.keys_held()
        self.scene.tilemap.update(dt)
        self.camera.update()
        self.scene.levelsystem.leveltime += dt