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

Revision 270, 10.7 KB checked in by orlandov, 10 years ago (diff)

Fix Issue #78

  • Fully move the inventory display logic from World to Hud.
  • World will pass Hud an inventory model which will be passed to the Hud's Inventory object at creation time.
  • 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 fife, time
19import pychan
20from sounds import SoundEngine
21from datetime import date
22from scripts.common.eventlistenerbase import EventListenerBase
23from local_loaders.loaders import loadMapFile
24from sounds import SoundEngine
25from settings import Setting
26from scripts import hud
27from scripts.popups import *
28from pychan.tools import callbackWithArguments as cbwa
29from map import Map
30
31TDS = Setting()
32
33# this file should be the meta-file for all FIFE-related code
34# engine.py handles is our data model, whilst this is our view
35# in order to not replicate data, some of our data model will naturally
36# reside on this side of the fence (PC xpos and ypos, for example).
37# we should aim to never replicate any data as this leads to maintainance
38# issues (and just looks plain bad).
39# however, any logic needed to resolve this should sit in engine.py
40
41class World(EventListenerBase):
42    """World holds the data needed by fife to render the engine
43       The engine keeps a copy of this class"""
44    def __init__(self, engine):
45        """Constructor for engine
46           @type engine: fife.Engine
47           @param engine: A fife.Engine instance
48           @return: None"""
49        super(World, self).__init__(engine, regMouse = True, regKeys = True)
50        # self.engine is a fife.Engine object, not an Engine object
51        self.engine = engine
52        self.eventmanager = engine.getEventManager()
53        self.quitFunction = None
54       
55        # self.data is an engine.Engine object, but is set in run.py
56        self.data = None
57        self.mouseCallback = None
58        self.obj_hash={}
59
60        # self.map is a Map object, set to none here
61        self.activeMap = 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        self.boxOpen = False
77        self.boxCreated = False
78       
79        # init the sound
80        self.sounds = SoundEngine(engine)
81       
82        # don't force restart if skipping to new section
83        if (TDS.readSetting("PlaySounds") == "1"):
84            if(self.sounds.music_init == False):
85                self.sounds.playMusic("/music/preciouswasteland.ogg")
86               
87    def quitGame(self):
88        """Quits the game
89        @return: None"""
90        self.quitFunction()
91
92    def saveGame(self, *args, **kwargs):
93        """Saves the game state
94           @return: None"""
95        self.data.save(*args, **kwargs)
96
97    def loadGame(self, *args, **kwargs):
98        """Loads the game state
99           @return: None"""
100        self.data.load(*args, **kwargs)
101
102    def loadMap(self, mapname, filename):
103        """Loads a map an stores it under the given name in the maps list.
104        """
105        map = Map(self.engine, self.data)
106       
107        """Need to set active map before we load it because the map
108        loader uses call backs that expect to find an active map.
109        This needs to be reworked.
110        """
111        self.maps[mapname] = map
112        self.setActiveMap(mapname)
113
114        map.load(filename)
115
116   
117    def setActiveMap(self, mapname):
118        """Sets the active map that is to be rendered.
119        """
120        self.activeMap = self.maps[mapname]
121        self.activeMap.makeActive()
122
123    def displayObjectText(self, obj, text):
124        """Display on screen the text of the object over the object.
125           @type obj: fife.instance
126           @param obj: object to draw over
127           @type text: text
128           @param text: text to display over object
129           @return: None"""
130        obj.say(str(text), 1000)
131
132    # all key / mouse event handling routines go here
133    def keyPressed(self, evt):
134        """Whenever a key is pressed, fife calls this routine.
135           @type evt: fife.event
136           @param evt: The event that fife caught
137           @return: None"""
138        key = evt.getKey()
139        keyval = key.getValue()
140
141        if(keyval == key.Q):
142            # we need to quit the game
143            self.hud.quitGame()
144        if(keyval == key.T):
145            self.activeMap.toggle_renderer('GridRenderer')
146        if(keyval == key.F1):
147            # display the help screen and pause the game
148            self.hud.displayHelp()
149        if(keyval == key.F5):
150            # logic would say we use similar code to above and toggle
151            # logic here does not work, my friend :-(
152            self.cord_render.setEnabled(not self.cord_render.isEnabled())
153        if(keyval == key.F7):
154            # F7 saves a screenshot to fife/clients/parpg/screenshots
155            t = "screenshots/screen-%s-%s.png" % (date.today().strftime('%Y-%m-%d'),
156                                                  time.strftime('%H-%M-%S'))
157            print "PARPG: Saved:",t
158            self.engine.getRenderBackend().captureScreen(t)
159        if(keyval == key.F10):
160            # F10 shows/hides the console
161            self.engine.getGuiManager().getConsole().toggleShowHide()
162        if(keyval == key.I):
163            # I opens and closes the inventory
164            self.hud.toggleInventory()
165        if(keyval == key.A):
166            # A adds a test action to the action box
167            # The test actions will follow this format: Action 1, Action 2, etc.
168            self.hud.addAction("Action " + str(self.action_number))
169            self.action_number += 1
170        if(keyval == key.ESCAPE):
171            # Escape brings up the main menu
172            self.hud.displayMenu()
173        if(keyval == key.M):
174            self.sounds.toggleMusic()
175
176    def mouseReleased(self, evt):
177        """If a mouse button is released, fife calls this routine.
178           We want to wait until the button is released, because otherwise
179           pychan captures the release if a menu is opened.
180           @type evt: fife.event
181           @param evt: The event that fife caught
182           @return: None"""
183        self.hud.hideContextMenu() # hide the context menu in case it is displayed
184        scr_point = fife.ScreenPoint(evt.getX(), evt.getY())
185        if(evt.getButton() == fife.MouseEvent.LEFT):
186            self.data.handleMouseClick(self.getCoords(scr_point))     
187        elif(evt.getButton() == fife.MouseEvent.RIGHT):
188            # is there an object here?
189            instances = self.activeMap.cameras['main'].getMatchingInstances(scr_point, self.activeMap.agent_layer)
190            info = None
191            for inst in instances:
192                # check to see if this is an active item
193                if(self.data.objectActive(inst.getId())):           
194                    # yes, get the data
195                    info = self.data.getItemActions(inst.getId())
196                    break
197               
198            # take the menu items returned by the engine or show a default menu if no items   
199            data = info or [["Walk", "Walk here", self.onWalk, self.getCoords(scr_point)]]
200            # show the menu
201            self.hud.showContextMenu(data, (scr_point.x, scr_point.y))
202
203    def onWalk(self, click):
204        """Callback sample for the context menu.
205        """
206        self.hud.hideContainer()
207        self.data.gameState.PC.run(click)
208
209    def mouseMoved(self, evt):
210        """Called when the mouse is moved
211           @type evt: fife.event
212           @param evt: The event that fife caught
213           @return: None"""
214        click = fife.ScreenPoint(evt.getX(), evt.getY())
215        i=self.activeMap.cameras['main'].getMatchingInstances(click, self.activeMap.agent_layer)
216        # no object returns an empty tuple
217        if(i != ()):
218            for obj in i:
219                # check to see if this in our list at all
220                if(self.data.objectActive(obj.getId())):
221                    # yes, so outline
222                    self.activeMap.outline_render.addOutlined(obj, 0, 137, 255, 2)
223                    # get the text
224                    item = self.data.objectActive(obj.getId())
225                    if(item):
226                        self.displayObjectText(obj, item.name)
227        else:
228            # erase the outline
229            self.activeMap.outline_render.removeAllOutlines()
230
231    def getCoords(self, click):
232        """Get the map location x, y cords from the screen co-ords
233           @type click: fife.ScreenPoint
234           @param click: Screen co-ords
235           @rtype: fife.Location
236           @return: The map co-ords"""
237        coord = self.activeMap.cameras["main"].toMapCoordinates(click, False)
238        coord.z = 0
239        location = fife.Location(self.activeMap.agent_layer)
240        location.setMapCoordinates(coord)
241        return location
242
243    def createBoxGUI(self, title):
244        """
245        Creates a window to display the contents of a box
246
247        @type title: string
248        @param title: The title for the window
249        @return: None
250        """
251        if ((self.boxCreated == True) and (self.boxOpen == False)):
252            # if it has already been created, just show it
253            self.box_container.showContainer()
254            self.boxOpen = True
255        else:
256            # otherwise create it then show it
257            data = ["dagger01", "empty", "empty", "empty", "empty",
258                    "empty", "empty", "empty", "empty"]
259            self.box_container = ContainerGUI(self.engine, unicode(title), data)
260            def close_and_delete():
261                self.box_container.hideContainer()
262                self.boxOpen = False
263            events = {'takeAllButton':close_and_delete,
264                      'closeButton':close_and_delete}
265            self.box_container.container_gui.mapEvents(events)
266            self.box_container.showContainer()
267            self.boxOpen = True
268            self.boxCreated = True
269
270    def createExamineBox(self, title, desc):
271        self.examineBox = ExaminePopup(self.engine, title, desc)
272        self.examineBox.showPopUp()
273
274    def pump(self):
275        """Routine called during each frame. Our main loop is in ./run.py
276           We ignore this main loop (but FIFE complains if it is missing)."""
277        pass
Note: See TracBrowser for help on using the repository browser.