source: trunk/game/scripts/world.py @ 327

Revision 327, 10.7 KB checked in by eliedebrauwer, 10 years ago (diff)

Patch by eliedebrauwer, forgot to remove some debug in ticket 117 fix, docstring formatting

  • Property svn:eol-style set to native
Line 
1#!/usr/bin/python
2
3#   This file is part of PARPG.
4
5#   PARPG is free software: you can redistribute it and/or modify
6#   it under the terms of the GNU General Public License as published by
7#   the Free Software Foundation, either version 3 of the License, or
8#   (at your option) any later version.
9
10#   PARPG is distributed in the hope that it will be useful,
11#   but WITHOUT ANY WARRANTY; without even the implied warranty of
12#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13#   GNU General Public License for more details.
14
15#   You should have received a copy of the GNU General Public License
16#   along with PARPG.  If not, see <http://www.gnu.org/licenses/>.
17
18import time
19import fife
20import pychan
21from sounds import SoundEngine
22from datetime import date
23from scripts.common.eventlistenerbase import EventListenerBase
24from local_loaders.loaders import loadMapFile
25from sounds import SoundEngine
26from settings import Setting
27from scripts import hud
28from scripts.popups import *
29from pychan.tools import callbackWithArguments as cbwa
30from map import Map
31
32TDS = Setting()
33
34# this file should be the meta-file for all FIFE-related code
35# engine.py handles is our data model, whilst this is our view
36# in order to not replicate data, some of our data model will naturally
37# reside on this side of the fence (PC xpos and ypos, for example).
38# we should aim to never replicate any data as this leads to maintenance
39# issues (and just looks plain bad).
40# however, any logic needed to resolve this should sit in engine.py
41
42class World(EventListenerBase):
43    """World holds the data needed by fife to render the engine
44       The engine keeps a copy of this class"""
45    def __init__(self, engine):
46        """Constructor for engine
47           @type engine: fife.Engine
48           @param engine: A fife.Engine instance
49           @return: None"""
50        super(World, self).__init__(engine, reg_mouse=True, reg_keys=True)
51        # self.engine is a fife.Engine object, not an Engine object
52        self.engine = engine
53        self.event_manager = engine.getEventManager()
54        self.quitFunction = None
55       
56        # self.data is an engine.Engine object, but is set in run.py
57        self.data = None
58        self.mouseCallback = None
59
60        # self.map is a Map object, set to none here
61        self.active_map = None
62        self.maps = {}
63
64        # setup the inventory model
65        # make slot 'A1' and 'A3' container daggers
66        inv_model = {'A1':'dagger01', 'A3':'dagger01'}
67
68        hud_callbacks = {
69            'saveGame': self.saveGame,
70            'loadGame': self.loadGame,
71            'quitGame': self.quitGame,
72        }
73        self.hud = hud.Hud(self.engine, TDS, inv_model, hud_callbacks)
74        self.action_number = 1
75
76        # init the sound
77        self.sounds = SoundEngine(engine)
78       
79        # don't force restart if skipping to new section
80        if (TDS.readSetting("PlaySounds") == "1"):
81            if(self.sounds.music_init == False):
82                self.sounds.playMusic("/music/preciouswasteland.ogg")
83               
84    def quitGame(self):
85        """Quits the game
86        @return: None"""
87        self.quitFunction()
88
89    def saveGame(self, *args, **kwargs):
90        """Saves the game state, delegates call to engine.Engine
91           @return: None"""
92        self.data.save(*args, **kwargs)
93
94    def loadGame(self, *args, **kwargs):
95        """Loads the game state, delegates call to engine.Engine
96           @return: None"""
97        self.data.load(*args, **kwargs)
98       
99    def loadMap(self, map_name, filename):
100        """Loads a map and stores it under the given name in the maps list.
101           @type map_name: text
102           @param map_name: The name of the map to load
103           @type filename: text
104           @param filename: File which contains the map to be loaded
105           @return: None
106        """
107        if not map_name in self.maps:
108            """Need to set active map before we load it because the map
109            loader uses call backs that expect to find an active map.
110            This needs to be reworked.
111            """
112            map = Map(self.engine, self.data)
113            self.maps[map_name] = map       
114            self.setActiveMap(map_name)
115            map.load(filename)
116   
117    def setActiveMap(self, map_name):
118        """Sets the active map that is to be rendered.
119           @type map_name: text
120           @param map_name: The name of the map to load
121           @return: None
122        """
123        self.active_map = self.maps[map_name]
124        self.active_map.makeActive()
125
126    def displayObjectText(self, obj, text):
127        """Display on screen the text of the object over the object.
128           @type obj: fife.instance
129           @param obj: object to draw over
130           @type text: text
131           @param text: text to display over object
132           @return: None"""
133        obj.say(str(text), 1000)
134
135    def keyPressed(self, evt):
136        """Whenever a key is pressed, fife calls this routine.
137           @type evt: fife.event
138           @param evt: The event that fife caught
139           @return: None"""
140        key = evt.getKey()
141        key_val = key.getValue()
142
143        if(key_val == key.Q):
144            # we need to quit the game
145            self.hud.quitGame()
146        if(key_val == key.T):
147            self.active_map.toggle_renderer('GridRenderer')
148        if(key_val == key.F1):
149            # display the help screen and pause the game
150            self.hud.displayHelp()
151        if(key_val == key.F5):
152            # logic would say we use similar code to above and toggle
153            # logic here does not work, my friend :-(
154            self.cord_render.setEnabled(not self.cord_render.isEnabled())
155        if(key_val == key.F7):
156            # F7 saves a screenshot to fife/clients/parpg/screenshots
157            t = "screenshots/screen-%s-%s.png" % \
158                    (date.today().strftime('%Y-%m-%d'),\
159                    time.strftime('%H-%M-%S'))
160            print "PARPG: Saved:",t
161            self.engine.getRenderBackend().captureScreen(t)
162        if(key_val == key.F10):
163            # F10 shows/hides the console
164            self.engine.getGuiManager().getConsole().toggleShowHide()
165        if(key_val == key.I):
166            # I opens and closes the inventory
167            self.hud.toggleInventory()
168        if(key_val == key.A):
169            # A adds a test action to the action box
170            # The test actions will follow this format: Action 1,
171            # Action 2, etc.
172            self.hud.addAction("Action " + str(self.action_number))
173            self.action_number += 1
174        if(key_val == key.ESCAPE):
175            # Escape brings up the main menu
176            self.hud.displayMenu()
177            # Hide the quit menu
178            self.hud.quit_window.hide()
179        if(key_val == key.M):
180            self.sounds.toggleMusic()
181
182    def mouseReleased(self, evt):
183        """If a mouse button is released, fife calls this routine.
184           We want to wait until the button is released, because otherwise
185           pychan captures the release if a menu is opened.
186           @type evt: fife.event
187           @param evt: The event that fife caught
188           @return: None"""
189        self.hud.hideContextMenu()
190        scr_point = fife.ScreenPoint(evt.getX(), evt.getY())
191        if(evt.getButton() == fife.MouseEvent.LEFT):
192            self.data.handleMouseClick(self.getCoords(scr_point))     
193        elif(evt.getButton() == fife.MouseEvent.RIGHT):
194            # is there an object here?
195            instances = self.active_map.cameras['main'].\
196                            getMatchingInstances(scr_point, \
197                                                 self.active_map.agent_layer)
198            info = None
199            for inst in instances:
200                # check to see if this is an active item
201                if(self.data.objectActive(inst.getId())):           
202                    # yes, get the data
203                    info = self.data.getItemActions(inst.getId())
204                    break
205               
206            # take the menu items returned by the engine or show a
207            # default menu if no items   
208            data = info or \
209                [["Walk", "Walk here", self.onWalk, self.getCoords(scr_point)]]
210            # show the menu
211            self.hud.showContextMenu(data, (scr_point.x, scr_point.y))
212
213    def onWalk(self, click):
214        """Callback sample for the context menu."""
215        self.hud.hideContainer()
216        self.data.game_state.PC.run(click)
217
218    def teleport(self, position):
219        """Called when a door is used that moves a player to a new
220           location on the same map. the setting of position may want
221           to be created as its own method down the road.
222           @type position: String Tuple
223           @param position: X,Y coordinates passed from engine.changeMap
224           @return: fife.Location
225        """
226        coord = fife.DoublePoint3D(float(position[0]), float(position[1]), 0)
227        location = fife.Location(self.active_map.agent_layer)
228        location.setMapCoordinates(coord)
229        self.data.game_state.PC.teleport(location)
230
231    def mouseMoved(self, evt):
232        """Called when the mouse is moved
233           @type evt: fife.event
234           @param evt: The event that fife caught
235           @return: None"""
236        click = fife.ScreenPoint(evt.getX(), evt.getY())
237        i=self.active_map.cameras['main'].getMatchingInstances(click, \
238                                                self.active_map.agent_layer)
239        # no object returns an empty tuple
240        if(i != ()):
241            for obj in i:
242                # check to see if this in our list at all
243                if(self.data.objectActive(obj.getId())):
244                    # yes, so outline
245                    self.active_map.outline_render.addOutlined(obj, 0, \
246                                                               137, 255, 2)
247                    # get the text
248                    item = self.data.objectActive(obj.getId())
249                    if(item is not None):
250                        self.displayObjectText(obj, item.name)
251        else:
252            # erase the outline
253            self.active_map.outline_render.removeAllOutlines()
254
255    def getCoords(self, click):
256        """Get the map location x, y coordinates from the screen coordinates
257           @type click: fife.ScreenPoint
258           @param click: Screen coordinates
259           @rtype: fife.Location
260           @return: The map coordinates"""
261        coord = self.active_map.cameras["main"].toMapCoordinates(click, False)
262        coord.z = 0
263        location = fife.Location(self.active_map.agent_layer)
264        location.setMapCoordinates(coord)
265        return location
266
267    def pump(self):
268        """Routine called during each frame. Our main loop is in ./run.py
269           We ignore this main loop (but FIFE complains if it is missing)."""
270        pass
Note: See TracBrowser for help on using the repository browser.