1#!/usr/bin/env python
2
3# -*- coding: utf-8 -*-
4
5# ####################################################################
6#  Copyright (C) 2005-2019 by the FIFE team
7#  http://www.fifengine.net
8#  This file is part of FIFE.
9#
10#  FIFE is free software; you can redistribute it and/or
11#  modify it under the terms of the GNU Lesser General Public
12#  License as published by the Free Software Foundation; either
13#  version 2.1 of the License, or (at your option) any later version.
14#
15#  This library is distributed in the hope that it will be useful,
16#  but WITHOUT ANY WARRANTY; without even the implied warranty of
17#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18#  Lesser General Public License for more details.
19#
20#  You should have received a copy of the GNU Lesser General Public
21#  License along with this library; if not, write to the
22#  Free Software Foundation, Inc.,
23#  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24# ####################################################################
25from builtins import str
26from builtins import range
27import random
28from fife import fife
29from fife.extensions import pychan
30from fife.extensions.pychan.tools import callbackWithArguments as cbwa
31from fife.extensions.fife_timer import Timer
32
33import scripts.test as test
34
35class KeyListener(fife.IKeyListener):
36	def __init__(self, test):
37		self._engine = test._engine
38		self._test = test
39		self._eventmanager = self._engine.getEventManager()
40
41		fife.IKeyListener.__init__(self)
42
43	def keyPressed(self, evt):
44		keyval = evt.getKey().getValue()
45		keystr = evt.getKey().getAsString().lower()
46		if keystr == 't':
47			r = self._test._camera.getRenderer('GridRenderer')
48			r.setEnabled(not r.isEnabled())
49		elif keystr == 'c':
50			r = self._test._camera.getRenderer('CoordinateRenderer')
51			r.setEnabled(not r.isEnabled())
52
53	def keyReleased(self, evt):
54		pass
55
56class MouseListener(fife.IMouseListener):
57	def __init__(self, test):
58		self._engine = test._engine
59		self._test = test
60		self._eventmanager = self._engine.getEventManager()
61
62		fife.IMouseListener.__init__(self)
63
64	def mousePressed(self, event):
65		if event.isConsumedByWidgets():
66			return
67
68		clickpoint = fife.ScreenPoint(event.getX(), event.getY())
69
70		self._test.movePlayer(clickpoint)
71
72	def mouseReleased(self, event):
73		pass
74
75	def mouseMoved(self, event):
76		pass
77
78	def mouseEntered(self, event):
79		pass
80
81	def mouseExited(self, event):
82		pass
83
84	def mouseClicked(self, event):
85		pass
86
87	def mouseWheelMovedUp(self, event):
88		self._test.setZoom(0.0625)
89
90	def mouseWheelMovedDown(self, event):
91		self._test.setZoom(-0.0625)
92
93	def mouseDragged(self, event):
94		pass
95
96class InstanceActionListener(fife.InstanceActionListener):
97	def __init__(self, test):
98		self._engine = test._engine
99		self._test = test
100
101		fife.InstanceActionListener.__init__(self)
102
103	def onInstanceActionFinished(self, instance, action):
104		pass
105		# lets the skels dance ^^
106		#instance.actOnce("stand", instance.getRotation()+45)
107		# skels walk to random locations
108		#instance.move('walk', self._test.createRandomTarget(), 4.0)
109
110	def onInstanceActionCancelled(self, instance, action):
111		pass
112
113	def onInstanceActionFrame(self, instance, action, frame):
114		pass
115
116class BenchmarkTest(test.Test):
117
118	def create(self, engine, application):
119		self._application = application
120		self._engine = engine
121		self._running = False
122
123		self._loader = fife.MapLoader(self._engine.getModel(),
124									self._engine.getVFS(),
125									self._engine.getImageManager(),
126									self._engine.getRenderBackend())
127
128		self._eventmanager = self._engine.getEventManager()
129
130	def destroy(self):
131		#any left over cleanup here
132		pass
133
134	def run(self):
135		self._running = True
136
137		self._mouselistener = MouseListener(self)
138		self._eventmanager.addMouseListener(self._mouselistener)
139
140		self._keylistener = KeyListener(self)
141		self._eventmanager.addKeyListener(self._keylistener)
142
143		self._font = pychan.internal.get_manager().createFont("data/fonts/rpgfont.png")
144		if self._font is None:
145			raise InitializationError("Could not load font %s" % name)
146
147		self.loadMap("data/maps/benchmark.xml")
148
149	def stop(self):
150		self._running = False
151
152		self._engine.getModel().deleteMap(self._map)
153		self._engine.getModel().deleteObjects()
154
155		self._eventmanager.removeMouseListener(self._mouselistener)
156		self._eventmanager.removeKeyListener(self._keylistener)
157
158		del self._mouselistener
159		del self._keylistener
160
161	def isRunning(self):
162		return self._running
163
164	def getName(self):
165		return "BenchmarkTest"
166
167	def getAuthor(self):
168		return "helios"
169
170	def getDescription(self):
171		return "Simple benchmark test."
172
173	def getHelp(self):
174		return open( 'data/help/BenchmarkTest.txt', 'r' ).read()
175
176	def pump(self):
177		"""
178		This gets called every frame that the test is running.  We have nothing
179		to do here for this test.
180		"""
181		pass
182
183	def loadMap(self, filename):
184		"""
185		Simple function to load and display a map file. We could of course
186		have passed in the map filename but I'll leave that up to you.
187
188		@param filename The filename.
189		"""
190
191		self._mapfilename = filename
192
193		if self._loader.isLoadable(self._mapfilename):
194			self._map = self._loader.load(self._mapfilename)
195			self._mapLoaded = True
196
197		self._camera = self._map.getCamera("camera1")
198		self._actorlayer = self._map.getLayer("item_layer")
199		self._groundlayer = self._map.getLayer("ground_layer")
200		# sets ground static
201		self._groundlayer.setStatic(True)
202		self._player = self._actorlayer.getInstance("player")
203
204		gridrenderer = self._camera.getRenderer('GridRenderer')
205		gridrenderer.activateAllLayers(self._map)
206
207		coordrenderer = fife.CoordinateRenderer.getInstance(self._camera)
208		coordrenderer.setFont(self._font)
209		coordrenderer.clearActiveLayers()
210		coordrenderer.addActiveLayer(self._groundlayer)
211
212		self.min = fife.ModelCoordinate()
213		self.max = fife.ModelCoordinate()
214		self._groundlayer.getMinMaxCoordinates(self.min, self.max)
215		name = "skel"
216		self.obj = self._player.getObject()
217		# change pathfinder max ticks
218		#pather = self.obj.getPather()
219		#pather.setMaxTicks(1000)
220		self._actionlistener = InstanceActionListener(self)
221		for x in range(0, 1000):
222			loc = self.createRandomTarget()
223			i = self._actorlayer.createInstance(self.obj, loc.getLayerCoordinates(), name+str(x))
224			fife.InstanceVisual.create(i)
225			i.addActionListener(self._actionlistener)
226			i.actOnce("stand", i.getFacingLocation())
227
228
229	def getLocationAt(self, screenpoint):
230		"""
231		Query the main camera for the Map location (on the actor layer)
232		that a screen point refers to.
233
234		@param screenpoint A fife.ScreenPoint
235		"""
236
237		target_mapcoord = self._camera.toMapCoordinates(screenpoint, False)
238		target_mapcoord.z = 0
239		location = fife.Location(self._actorlayer)
240		location.setMapCoordinates(target_mapcoord)
241		return location
242
243	def movePlayer(self, screenpoint):
244		"""
245		Simple function that moves the player instance to the given screenpoint.
246
247		@param screenpoint A fife.ScreenPoint
248		"""
249
250		self._player.move('walk', self.getLocationAt(screenpoint), 4.0)
251
252	def setZoom(self, zoom):
253		z = self._camera.getZoom() + zoom
254		if z <= 0.0625:
255			z = 0.0625
256		self._camera.setZoom(z)
257
258	def createRandomTarget(self):
259		cache = self._actorlayer.getCellCache()
260		while 1:
261			x = random.randint(self.min.x, self.max.x)
262			y = random.randint(self.min.y, self.max.y)
263			mc = fife.ModelCoordinate(x,y)
264			c = cache.getCell(mc)
265			if c and c.getCellType() == fife.CTYPE_NO_BLOCKER:
266				break
267
268		location = fife.Location(self._actorlayer)
269		location.setLayerCoordinates(mc)
270		return location