source: trunk/PARPG/scripts/engine.py @ 128

Revision 128, 6.7 KB checked in by maximinus_parpg, 10 years ago (diff)

Added meggies map changing code.

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
18# there should be NO references to FIFE here!
19from agents.hero import Hero
20from agents.npc import NPC
21from objects import GameObject
22from tele_tiles import TeleTile
23from objLoader import LocalXMLParser
24
25# design note:
26# there is a map file that FIFE reads. We use that file for half the map
27# format because the map editor in FIFE uses it, and secondly because it
28# save us writing a bunch of new code.
29# However, the objects and characters on a map are liable to change
30# whilst the game is being run, so when we change the map, we need to
31# to grab the objects and npc data EITHER from the engine state, or grab
32# from another file if in their initial state
33# This other file has the name AAA_objects.xml where AAA.xml is the name
34# of the original mapfile.
35
36class Engine:
37    """Engine holds the logic for the game
38       Since some data (object position and so forth) is held in the
39       fife, and would be pointless to replicate, we hold a instance of
40       the fife view here. This also prevents us from just having a
41       function heavy controller"""
42    def __init__(self, view):
43        # a World object
44        self.view = view
45        self.PC = None
46        self.npcs = []
47        self.objects = []
48        self.tele_tiles = []
49
50    def reset(self):
51        """Clears the data on a map reload so we don't have objects/npcs from
52           other maps hanging around. Right now I'm clearing the PC, but we'll
53           have to evaluate that when we get more details on how the stepping
54           on tiles works."""
55        self.PC = None
56        self.npcs = []
57        self.objects = []
58        self.tele_tiles = []
59
60    def loadObjects(self, filename):
61        """Load objects from the XML file
62           Returns True if it worked, False otherwise"""
63        try:
64            objects_file = open(filename, 'rt')
65        except(IOError):
66            sys.stderr.write("Error: Can't find objects file\n")
67            return False
68        # now open and read the XML file
69        cur_handler = LocalXMLParser()
70        parser = cur_handler.getParser()
71        parser.setContentHandler(cur_handler)
72        parser.parse(objects_file)
73        objects_file.close()
74        # must have at least 1 PC
75        if(cur_handler.pc == None):
76            sys.stderr.write("Error: No PC defined\n")
77            sys.exit(False)
78        # now add to the map and the engine
79        self.addPC(cur_handler.pc)
80        self.addNPCs(cur_handler.npcs)
81        self.addObjects(cur_handler.objects)
82        self.addTeleTiles(cur_handler.tele_tiles)
83        return True
84
85    def addPC(self,pc):
86        """Add the PC to the world"""
87        self.view.addObject(float(pc[0]), float(pc[1]),"PC","PC")
88        self.PC = Hero("PC", self.view.agent_layer)
89        # ensure the PC starts on a default action
90        self.PC.start()
91        self.view.addPC(self.PC.agent)
92
93    def addObjects(self,objects):
94        """Add all of the objects we found into the fife map
95           and into our class
96           An NPC is just an object to FIFE"""
97        for i in objects:
98            # is it visible?
99            if(i[0] == True):
100                self.view.addObject(float(i[1]), float(i[2]), i[3], i[4])
101            # now add it as an engine object
102            self.objects.append(GameObject(i))
103
104    def addNPCs(self,npcs):
105        """Add all of the NPCs we found into the fife map
106           and into this class"""
107        for i in npcs:
108            self.view.addObject(float(i[0]), float(i[1]), i[2], i[3])
109            # now add as engine data
110            self.npcs.append(NPC(i[4], str(i[3]), self.view.agent_layer))
111            self.npcs[-1].start()
112
113    def addTeleTiles(self, tiles):
114        """Add all of the teleportation tiles we found into this class"""
115        # we want to use the ground layer for now
116        layer = self.view.map.getLayer('GroundLayer')
117        for i in tiles:
118            self.tele_tiles.append(TeleTile(i[0], i[1], i[2], layer))
119
120    def objectActive(self, ident):
121        """Given the objects ID, pass back the object if it is active,
122           False if it doesn't exist or not displayed"""
123        for i in self.objects:
124            if((i.display == True)and(i.id == ident)):
125                # we found a match
126                return i
127        # now try NPC's
128        for i in self.npcs:
129            # all NPC's are deemed active
130            if(i.id == ident):
131                return i
132        # no match
133        return False
134
135    def getItemActions(self, obj_id):
136        """Given the objects ID, return the text strings and callbacks"""
137        actions=[]
138        # note: ALWAYS check NPC's first!
139        # is it an NPC?
140        for i in self.npcs:
141            if(obj_id == i.id):
142                # keep it simple for now
143                actions.append(("Talk",None))
144                actions.append(("Attack",None))
145        # is it in our objects?
146        for i in self.objects:
147            if(obj_id == i.id):
148                actions.append(("Examine",None))
149                # is it a container?
150                if(i.container == True):
151                    actions.append(("Open",None))
152                # can you pick it up?
153                if(i.carry == True):
154                    actions.append(("Pick Up",None))
155                return actions
156        return actions
157
158    def loadMap(self,map_file):
159        """Load a new map
160           TODO: needs some error checking"""
161        # first we let FIFE load the rest of the map
162        self.view.load(map_file)
163        # then we update FIFE with the PC, NPC and object details
164        self.reset()
165        self.loadObjects(map_file[:-4]+"_objects.xml")
166
167    def checkTeleTiles(self, location):
168        """Iterates through the possible teleportation tiles to see if the
169            given location is a teleportation tile
170        @param location: a fife.Location to check against the tiles
171        @return: the TeleTile if a tile is matched or False"""
172        for tile in self.tele_tiles:
173            if tile.matchLocation(location):
174                return tile
175        return False
176
177    def handleMouseClick(self,position):
178        self.PC.run(position)
179
Note: See TracBrowser for help on using the repository browser.