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

Revision 19, 10.6 KB checked in by barra_parpg, 10 years ago (diff)
  • SVN property fixes:
    • Flagged run.py and the .bat files as executables
    • Native EOL style for *.py & *.xml
  • Property svn:eol-style set to native
Line 
1import fife, math, random
2import pychan
3import pychan.widgets as widgets
4
5from scripts.common.eventlistenerbase import EventListenerBase
6from loaders import loadMapFile
7from savers import saveMapFile
8from agents.hero import Hero
9from agents.girl import Girl
10from agents.cloud import Cloud
11from agents.beekeeper import Beekeeper
12from agents.agent import create_anonymous_agents
13from settings import Setting
14
15TDS = Setting()
16
17class MapListener(fife.MapChangeListener):
18        def __init__(self, map):
19                fife.MapChangeListener.__init__(self)
20                map.addChangeListener(self)
21
22        def onMapChanged(self, map, changedLayers):
23                return
24                print "Changes on map ", map.getId()
25                for layer in map.getLayers():
26                        print layer.getId()
27                        print "    ", ["%s, %x" % (i.getObject().getId(), i.getChangeInfo()) for i in layer.getChangedInstances()]
28
29        def onLayerCreate(self, map, layer):
30                pass
31
32        def onLayerDelete(self, map, layer):
33                pass
34
35
36class World(EventListenerBase):
37        def __init__(self, engine):
38                super(World, self).__init__(engine, regMouse=True, regKeys=True)
39                self.engine = engine
40                self.eventmanager = engine.getEventManager()
41                self.model = engine.getModel()
42                self.view = self.engine.getView()
43                self.filename = ''
44                self.pump_ctr = 0 # for testing purposis
45                self.ctrldown = False
46                self.instancemenu = pychan.loadXML('gui/instancemenu.xml')
47                # we keep a copy of all possible buttons to avoid reloading of XML
48                self.all_btns = [btn for btn in self.instancemenu.children]
49                self.instance_to_agent = {}
50                # dynamic_widgets should no longer be necessary; commenting them out to be safe
51                #self.dynamic_widgets = {}   
52               
53        def show_instancemenu(self, clickpoint, instance):
54                """Handles the display of the right-click context menu."""
55                # IMPORTANT: We assume that the ALWAYS_PRESENT_BUTTONS are _NEVER_ removed from the instancemenu
56                # IMPORTANT: World and Agent functions that handle different actions
57                # must be named "buttonNameHandler", e.g. "talkButtonHandler"
58                # TODO: Add a range check; if we are out of range we should queue (get_in_range, perform_action)
59               
60                # no right-click menu for clicking on Hero
61                if instance.getFifeId() == self.hero.agent.getFifeId():
62                        return
63                # buttons that will always be available, regardless of the instance type
64                ALWAYS_PRESENT_BTNS = ('moveButton', 'inspectButton')
65                NAME_PATTERN = "%sHandler"
66               
67                if self.instance_to_agent.has_key(instance.getFifeId()):
68                        # we got an agent here; remove any actions that the agent cannot handle
69                        for btn in self.all_btns:
70                                #do we have this button in the current menu?
71                                btn_present = bool(self.instancemenu.findChild(name=btn.name))
72                                # do we need this button in the current menu?
73                                btn_needed = hasattr(self.instance_to_agent[instance.getFifeId()],NAME_PATTERN % btn.name) \
74                                           or btn.name in ALWAYS_PRESENT_BTNS
75                                if btn_needed and not btn_present:
76                                        self.instancemenu.addChild(btn)
77                                if not btn_needed and btn_present:
78                                        self.instancemenu.removeChild(btn)
79                else:
80                        # we got some other kind of object, so only leave always_present actions
81                        for btn in self.instancemenu.children[:]:
82                                if not btn.name in ALWAYS_PRESENT_BTNS:
83                                        self.instancemenu.removeChild(btn)
84
85                # map a dictionary of button names to their corresponding World fuctions
86                mapdict = dict([ (btn.name,getattr (self, NAME_PATTERN % btn.name)) for btn in self.instancemenu.children])
87                self.instancemenu.mapEvents (mapdict)
88               
89                # add some global data
90                self.instancemenu.clickpoint = clickpoint
91                self.instancemenu.instance = instance           
92                self.instancemenu.position = (clickpoint.x, clickpoint.y)
93                # show the menu
94                self.instancemenu.show()
95                return 
96
97        def hide_instancemenu(self):
98                if self.instancemenu:
99                        self.instancemenu.hide()
100
101        def reset(self):
102                self.map, self.agentlayer = None, None
103                self.cameras = {}
104                self.hero, self.girl, self.clouds, self.beekeepers = None, None, [], []
105                self.cur_cam2_x, self.initial_cam2_x, self.cam2_scrolling_right = 0, 0, True
106                self.target_rotation = 0
107                self.instance_to_agent = {}
108
109        def load(self, filename):
110                self.filename = filename
111                self.reset()
112                self.map = loadMapFile(filename, self.engine)
113                self.maplistener = MapListener(self.map)
114
115                self.agentlayer = self.map.getLayer('TechdemoMapGroundObjectLayer')
116                self.hero = Hero(self.model, 'PC', self.agentlayer)
117                self.instance_to_agent[self.hero.agent.getFifeId()] = self.hero
118                self.hero.start()
119
120                self.girl = Girl(self.model, 'NPC:girl', self.agentlayer)
121                self.instance_to_agent[self.girl.agent.getFifeId()] = self.girl
122                self.girl.start()
123
124                self.beekeepers = create_anonymous_agents(self.model, 'beekeeper', self.agentlayer, Beekeeper)
125                for beekeeper in self.beekeepers:
126                        self.instance_to_agent[beekeeper.agent.getFifeId()] = beekeeper
127                        beekeeper.start()
128
129                cloudlayer = self.map.getLayer('TechdemoMapTileLayer')
130                self.clouds = create_anonymous_agents(self.model, 'Cloud', cloudlayer, Cloud)
131                for cloud in self.clouds:
132                        cloud.start(0.1, 0.05)
133
134                for cam in self.view.getCameras():
135                        self.cameras[cam.getId()] = cam
136                self.cameras['main'].attach(self.hero.agent)
137
138                self.view.resetRenderers()
139                renderer = fife.FloatingTextRenderer.getInstance(self.cameras['main'])
140                textfont = self.engine.getGuiManager().createFont('fonts/rpgfont.png', 0, str(TDS.readSetting("FontGlyphs", strip=False)));
141                renderer.changeDefaultFont(textfont)
142
143                renderer = fife.FloatingTextRenderer.getInstance(self.cameras['small'])
144                renderer.changeDefaultFont(None)
145
146                renderer = self.cameras['main'].getRenderer('CoordinateRenderer')
147                renderer.clearActiveLayers()
148                renderer.addActiveLayer(self.map.getLayer(str(TDS.readSetting("CoordinateLayerName"))))
149
150                renderer = self.cameras['main'].getRenderer('QuadTreeRenderer')
151                renderer.setEnabled(True)
152                renderer.clearActiveLayers()
153                if str(TDS.readSetting("QuadTreeLayerName")):
154                        renderer.addActiveLayer(self.map.getLayer(str(TDS.readSetting("QuadTreeLayerName"))))
155
156                self.cameras['small'].getLocationRef().setExactLayerCoordinates( fife.ExactModelCoordinate( 40.0, 40.0, 0.0 ))
157                self.initial_cam2_x = self.cameras['small'].getLocation().getExactLayerCoordinates().x
158                self.cur_cam2_x = self.initial_cam2_x
159                self.cam2_scrolling_right = True
160                self.cameras['small'].setEnabled(False)
161
162                self.target_rotation = self.cameras['main'].getRotation()
163
164        def save(self, filename):
165                saveMapFile(filename, self.engine, self.map)
166
167        def keyPressed(self, evt):
168                keyval = evt.getKey().getValue()
169                keystr = evt.getKey().getAsString().lower()
170                if keystr == 't':
171                        r = self.cameras['main'].getRenderer('GridRenderer')
172                        r.setEnabled(not r.isEnabled())
173                elif keystr == 'c':
174                        r = self.cameras['main'].getRenderer('CoordinateRenderer')
175                        r.setEnabled(not r.isEnabled())
176                elif keystr == 's':
177                        c = self.cameras['small']
178                        c.setEnabled(not c.isEnabled())
179                elif keystr == 'r':
180                        pass
181#                       self.model.deleteMaps()
182#                       self.metamodel.deleteDatasets()
183#                       self.view.clearCameras()
184#                       self.load(self.filename)
185                elif keystr == 'o':
186                        self.target_rotation = (self.target_rotation + 90) % 360
187                elif keyval in (fife.Key.LEFT_CONTROL, fife.Key.RIGHT_CONTROL):
188                        self.ctrldown = True
189
190        def keyReleased(self, evt):
191                keyval = evt.getKey().getValue()
192                if keyval in (fife.Key.LEFT_CONTROL, fife.Key.RIGHT_CONTROL):
193                        self.ctrldown = False
194
195        def mouseWheelMovedUp(self, evt):
196                if self.ctrldown:
197                        self.cameras['main'].setZoom(self.cameras['main'].getZoom() * 1.05)
198
199        def mouseWheelMovedDown(self, evt):
200                if self.ctrldown:
201                        self.cameras['main'].setZoom(self.cameras['main'].getZoom() / 1.05)
202
203        def changeRotation(self):
204                currot = self.cameras['main'].getRotation()
205                if self.target_rotation != currot:
206                        self.cameras['main'].setRotation((currot + 5) % 360)
207
208        def mousePressed(self, evt):
209                if evt.isConsumedByWidgets():
210                        return
211
212                clickpoint = fife.ScreenPoint(evt.getX(), evt.getY())
213                if (evt.getButton() == fife.MouseEvent.LEFT):
214                        self.hide_instancemenu()
215                        target_mapcoord = self.cameras['main'].toMapCoordinates(clickpoint, False)
216                        target_mapcoord.z = 0
217                        l = fife.Location(self.agentlayer)
218                        l.setMapCoordinates(target_mapcoord)
219                        self.hero.run(l)
220
221                if (evt.getButton() == fife.MouseEvent.RIGHT):
222                        self.hide_instancemenu()
223                        instances = self.cameras['main'].getMatchingInstances(clickpoint, self.agentlayer)
224                        print "selected instances on agent layer: ", [i.getObject().getId() for i in instances]
225                        if instances:
226                                self.show_instancemenu(clickpoint, instances[0])
227
228        def mouseMoved(self, evt):
229                renderer = fife.InstanceRenderer.getInstance(self.cameras['main'])
230                renderer.removeAllOutlines()
231
232                pt = fife.ScreenPoint(evt.getX(), evt.getY())
233                instances = self.cameras['main'].getMatchingInstances(pt, self.agentlayer);
234                for i in instances:
235                        if i.getObject().getId() in ('girl', 'beekeeper'):
236                                renderer.addOutlined(i, 173, 255, 47, 2)
237
238        def onConsoleCommand(self, command):
239                result = ''
240                try:
241                        result = str(eval(command))
242                except:
243                        pass
244                return result
245
246        def moveButtonHandler(self):
247                self.hide_instancemenu()
248                self.hero.run(self.instancemenu.instance.getLocationRef())
249
250        def talkButtonHandler(self):
251                self.hide_instancemenu()
252                instance = self.instancemenu.instance
253                self.hero.talk(instance.getLocationRef())
254                if instance.getObject().getId() == 'beekeeper':
255                        beekeeperTexts = TDS.readSetting("beekeeperTexts", type='list', text=True)
256                        txtindex = random.randint(0, len(beekeeperTexts) - 1)
257                        instance.say(beekeeperTexts[txtindex], 5000)
258                if instance.getObject().getId() == 'girl':
259                        girlTexts = TDS.readSetting("girlTexts", type='list', text=True)
260                        txtindex = random.randint(0, len(girlTexts) - 1)
261                        instance.say(girlTexts[txtindex], 5000)
262
263        def kickButtonHandler(self):
264                self.hide_instancemenu()
265                self.hero.kick(self.instancemenu.instance.getLocationRef())
266                self.instancemenu.instance.say('Hey!', 1000)
267               
268        def kissButtonHandler(self):
269                self.hide_instancemenu()
270                self.instance_to_agent[self.instancemenu.instance.getFifeId()].kissButtonHandler (self.instancemenu.instance,self.hero)
271
272        def inspectButtonHandler(self):
273                self.hide_instancemenu()
274                inst = self.instancemenu.instance
275                saytext = ['Engine told me that this instance has']
276                if inst.getId():
277                        saytext.append(' name %s,' % inst.getId())
278                saytext.append(' ID %s and' % inst.getFifeId())
279                saytext.append(' object name %s' % inst.getObject().getId())
280                self.hero.agent.say('\n'.join(saytext), 3500)
281
282        def pump(self):
283                if self.cameras['small'].isEnabled():
284                        loc = self.cameras['small'].getLocation()
285                        c = loc.getExactLayerCoordinatesRef()
286                        if self.cam2_scrolling_right:
287                                self.cur_cam2_x = c.x = c.x+0.1
288                                if self.cur_cam2_x > self.initial_cam2_x+10:
289                                        self.cam2_scrolling_right = False
290                        else:
291                                self.cur_cam2_x = c.x = c.x-0.1
292                                if self.cur_cam2_x < self.initial_cam2_x-10:
293                                        self.cam2_scrolling_right = True
294                        self.cameras['small'].setLocation(loc)
295                self.changeRotation()
296                self.pump_ctr += 1
Note: See TracBrowser for help on using the repository browser.