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

Revision 261, 10.3 KB checked in by b0rland_parpg, 10 years ago (diff)

Ticket #78, #80: Patch by superfluid. Moving the hud events and context menu code (and inventory code) from world.py to hud.py

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