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

Revision 310, 10.5 KB checked in by eliedebrauwer, 10 years ago (diff)

Ticket #66: Patch by saritor (& eliedebrauwer), implements saritors rework of teleporting, at this point it implements the within-a-map teleport successfully, but cross map teleport still has in issue which probably has to do with the setup of the PC. comment[s:trac, t:66]

  • 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        # 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
91           @return: None"""
92        self.data.save(*args, **kwargs)
93
94    def loadGame(self, *args, **kwargs):
95        """Loads the game state
96           @return: None"""
97        self.data.load(*args, **kwargs)
98
99    def loadMap(self, mapname, filename):
100        """Loads a map and stores it under the given name in the maps list.
101           @type mapname: text
102           @param mapname: 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 mapname 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[mapname] = map       
114            self.setActiveMap(mapname)
115            map.load(filename)
116   
117    def setActiveMap(self, mapname):
118        """Sets the active map that is to be rendered.
119           @type mapname: text
120           @param mapname: The name of the map to load
121           @return: None
122        """
123        self.activeMap = self.maps[mapname]
124        self.activeMap.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    # all key / mouse event handling routines go here
136    def keyPressed(self, evt):
137        """Whenever a key is pressed, fife calls this routine.
138           @type evt: fife.event
139           @param evt: The event that fife caught
140           @return: None"""
141        key = evt.getKey()
142        keyval = key.getValue()
143
144        if(keyval == key.Q):
145            # we need to quit the game
146            self.hud.quitGame()
147        if(keyval == key.T):
148            self.activeMap.toggle_renderer('GridRenderer')
149        if(keyval == key.F1):
150            # display the help screen and pause the game
151            self.hud.displayHelp()
152        if(keyval == key.F5):
153            # logic would say we use similar code to above and toggle
154            # logic here does not work, my friend :-(
155            self.cord_render.setEnabled(not self.cord_render.isEnabled())
156        if(keyval == key.F7):
157            # F7 saves a screenshot to fife/clients/parpg/screenshots
158            t = "screenshots/screen-%s-%s.png" % (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(keyval == key.F10):
163            # F10 shows/hides the console
164            self.engine.getGuiManager().getConsole().toggleShowHide()
165        if(keyval == key.I):
166            # I opens and closes the inventory
167            self.hud.toggleInventory()
168        if(keyval == key.A):
169            # A adds a test action to the action box
170            # The test actions will follow this format: Action 1, Action 2, etc.
171            self.hud.addAction("Action " + str(self.action_number))
172            self.action_number += 1
173        if(keyval == key.ESCAPE):
174            # Escape brings up the main menu
175            self.hud.displayMenu()
176            # Hide the quit menu
177            self.hud.quitWindow.hide()
178        if(keyval == key.M):
179            self.sounds.toggleMusic()
180
181    def mouseReleased(self, evt):
182        """If a mouse button is released, fife calls this routine.
183           We want to wait until the button is released, because otherwise
184           pychan captures the release if a menu is opened.
185           @type evt: fife.event
186           @param evt: The event that fife caught
187           @return: None"""
188        self.hud.hideContextMenu() # hide the context menu in case it is displayed
189        scr_point = fife.ScreenPoint(evt.getX(), evt.getY())
190        if(evt.getButton() == fife.MouseEvent.LEFT):
191            self.data.handleMouseClick(self.getCoords(scr_point))     
192        elif(evt.getButton() == fife.MouseEvent.RIGHT):
193            # is there an object here?
194            instances = self.activeMap.cameras['main'].getMatchingInstances(scr_point, self.activeMap.agent_layer)
195            info = None
196            for inst in instances:
197                # check to see if this is an active item
198                if(self.data.objectActive(inst.getId())):           
199                    # yes, get the data
200                    info = self.data.getItemActions(inst.getId())
201                    break
202               
203            # take the menu items returned by the engine or show a default menu if no items   
204            data = info or [["Walk", "Walk here", self.onWalk, self.getCoords(scr_point)]]
205            # show the menu
206            self.hud.showContextMenu(data, (scr_point.x, scr_point.y))
207
208    def onWalk(self, click):
209        """Callback sample for the context menu."""
210        self.hud.hideContainer()
211        self.data.gameState.PC.run(click)
212
213    def teleport(self, position):
214        """Called when a door is used that moves a player to a new
215           location on the same map. the setting of position may want
216           to be created as its own method down the road.
217           
218           @type position: String Tuple
219           @param position: X,Y coordinates passed from enigine.changeMap
220           @return: fife.Location
221        """
222        coord = fife.DoublePoint3D(float(position[0]), float(position[1]), 0)
223        location = fife.Location(self.activeMap.agent_layer)
224        location.setMapCoordinates(coord)
225        self.data.gameState.PC.teleport(location)
226
227    def mouseMoved(self, evt):
228        """Called when the mouse is moved
229           @type evt: fife.event
230           @param evt: The event that fife caught
231           @return: None"""
232        click = fife.ScreenPoint(evt.getX(), evt.getY())
233        i=self.activeMap.cameras['main'].getMatchingInstances(click, self.activeMap.agent_layer)
234        # no object returns an empty tuple
235        if(i != ()):
236            for obj in i:
237                # check to see if this in our list at all
238                if(self.data.objectActive(obj.getId())):
239                    # yes, so outline
240                    self.activeMap.outline_render.addOutlined(obj, 0, 137, 255, 2)
241                    # get the text
242                    item = self.data.objectActive(obj.getId())
243                    if(item):
244                        self.displayObjectText(obj, item.name)
245        else:
246            # erase the outline
247            self.activeMap.outline_render.removeAllOutlines()
248
249    def getCoords(self, click):
250        """Get the map location x, y cords from the screen co-ords
251           @type click: fife.ScreenPoint
252           @param click: Screen co-ords
253           @rtype: fife.Location
254           @return: The map co-ords"""
255        coord = self.activeMap.cameras["main"].toMapCoordinates(click, False)
256        coord.z = 0
257        location = fife.Location(self.activeMap.agent_layer)
258        location.setMapCoordinates(coord)
259        return location
260
261    def pump(self):
262        """Routine called during each frame. Our main loop is in ./run.py
263           We ignore this main loop (but FIFE complains if it is missing)."""
264        pass
Note: See TracBrowser for help on using the repository browser.