def __init__(self, gm): self.mode = "move" # talk, fight MapManagerBase.__init__(self, gm) #self.map.water = True # player self.gameState = self.gm.gameState self.playerState = self.gm.playerState name = self.playerState.name sex = self.playerState.sex if sex == "male": modelPath = "models/characters/neoMale" else: modelPath = "models/characters/neoFemale" self.player = MapNPC(self, name, modelPath, "models/characters/female1.jpg", "player") self.player.addEquipment("models/characters/female_hair", "models/characters/female_hair.jpg") self.player.addEquipment("models/equipment/bag", "models/equipment/bag1.jpg") startX, startY = self.map.collisionGrid.getRandomTile() self.player.setTilePos(startX, startY) self.player.reparentTo(render) self.player.toggleLabel() # NPCs self.NPC = {} self.NPCAI = {} for name, sex in [("ula2", "female"), ("Kimmo", "male"), ("Drunkard", "male"), ("Camilla", "female")]: x, y = self.map.collisionGrid.getRandomTile() # yes, we will have to think about something smarter in the long run, i know... if sex == "female": self.addNPC(name, "models/characters/neoFemale", "models/characters/female1.jpg", x,y) else: self.addNPC(name, "models/characters/neoMale", "models/characters/neoMale.jpg", x,y) self.NPC["Camilla"].addEquipment("models/characters/female_hair", "models/characters/female_hair2.jpg") self.NPC["Camilla"].addEquipment("models/equipment/stick", "models/equipment/stick.jpg") self.NPC["ula2"].addEquipment("models/characters/female_hair", "models/characters/female_hair3.jpg") self.NPC["ula2"].addEquipment("models/equipment/bag", "models/equipment/bag1.jpg") self.NPC["Kimmo"].addEquipment("models/equipment/bag", "models/equipment/bag1.jpg") self.NPC["Drunkard"].addEquipment("models/equipment/stick", "models/equipment/stick.jpg") # monsters self.mobs = {} # drops self.drops = {} self.addDrop("machin", 5, self.player.getPos()+Vec3(4,0,0.25)) self.addDrop("machin", 5, self.player.getPos()+Vec3(0,2,0.25)) self.addDrop("machin", 5, self.player.getPos()+Vec3(4,2,0.25)) self.dialog = None # current dialog self.gui = GameGui(self) self.gui.hide()
class MapManager(MapManagerBase): def __init__(self, gm): self.mode = "move" # talk, fight MapManagerBase.__init__(self, gm) #self.map.water = True # player self.gameState = self.gm.gameState self.playerState = self.gm.playerState name = self.playerState.name sex = self.playerState.sex if sex == "male": modelPath = "models/characters/neoMale" else: modelPath = "models/characters/neoFemale" self.player = MapNPC(self, name, modelPath, "models/characters/female1.jpg", "player") self.player.addEquipment("models/characters/female_hair", "models/characters/female_hair.jpg") self.player.addEquipment("models/equipment/bag", "models/equipment/bag1.jpg") startX, startY = self.map.collisionGrid.getRandomTile() self.player.setTilePos(startX, startY) self.player.reparentTo(render) self.player.toggleLabel() # NPCs self.NPC = {} self.NPCAI = {} for name, sex in [("ula2", "female"), ("Kimmo", "male"), ("Drunkard", "male"), ("Camilla", "female")]: x, y = self.map.collisionGrid.getRandomTile() # yes, we will have to think about something smarter in the long run, i know... if sex == "female": self.addNPC(name, "models/characters/neoFemale", "models/characters/female1.jpg", x,y) else: self.addNPC(name, "models/characters/neoMale", "models/characters/neoMale.jpg", x,y) self.NPC["Camilla"].addEquipment("models/characters/female_hair", "models/characters/female_hair2.jpg") self.NPC["Camilla"].addEquipment("models/equipment/stick", "models/equipment/stick.jpg") self.NPC["ula2"].addEquipment("models/characters/female_hair", "models/characters/female_hair3.jpg") self.NPC["ula2"].addEquipment("models/equipment/bag", "models/equipment/bag1.jpg") self.NPC["Kimmo"].addEquipment("models/equipment/bag", "models/equipment/bag1.jpg") self.NPC["Drunkard"].addEquipment("models/equipment/stick", "models/equipment/stick.jpg") # monsters self.mobs = {} # drops self.drops = {} self.addDrop("machin", 5, self.player.getPos()+Vec3(4,0,0.25)) self.addDrop("machin", 5, self.player.getPos()+Vec3(0,2,0.25)) self.addDrop("machin", 5, self.player.getPos()+Vec3(4,2,0.25)) self.dialog = None # current dialog self.gui = GameGui(self) self.gui.hide() #self.map.collisionHide() #for obj in self.map.mapObjects.values(): # print "map manager init says : %s is at %s" % (obj.name, obj.getPos()) def start(self): self.gui.show() self.task = taskMgr.add(self.update, "MapManagerTask") self.startAccept() if self.map.bgMusic: self.map.bgMusic.play() #self.map.bgMusic.setVolume(0.4) if self.map.bgSound: self.map.bgSound.play() for NPCAI in self.NPCAI: self.NPCAI[NPCAI].request("Wander") def stop(self): self.gui.hide() taskMgr.remove(self.task) self.ignoreAll() if self.map.bgMusic: self.map.bgMusic.stop() #self.map.bgMusic.setVolume(0.4) if self.map.bgSound: self.map.bgSound.stop() for NPCAI in self.NPCAI: self.NPCAI[NPCAI].request("Pause") def startAccept(self): for key in [ "mouse1", "mouse3", FORWARD, BACKWARD, STRAFE_LEFT, STRAFE_RIGHT, TURN_LEFT, TURN_RIGHT, UP, DOWN,"h", "b", "t", "g" ]: self.keyDic[key] = 0 self.accept(key, self.setKey, [key, 1]) keyUp = key + "-up" self.accept(keyUp, self.setKey, [key, 0]) self.setMode(self.mode) # mouse click events self.accept(SAVE, self.save, [self.gameState.filename]) self.accept(OPEN, self.load, [self.gameState.filename]) self.accept(INVENTORY, self.gui.inventory.toggle) self.accept("mouse2", self.gm.gameCam.startDrag) self.accept("mouse2-up", self.gm.gameCam.stopDrag) self.accept("wheel_up", self.gm.gameCam.zoom, [1.0]) self.accept("wheel_down", self.gm.gameCam.zoom, [-1.0]) self.accept("playerDied", self.onPlayerDie) def onPlayerDie(self): print "Map Manager : the player has died, let's move to title screen..." def save(self, filename): #f = open(filename, 'w') #pickle.dump(self.gm.playerData, f) #f.close() self.gm.gameState.saveAs(filename) print "player data saved as %s" % (filename) def load(self, filename): f = open(filename, 'r') playerData = pickle.load(f) f.close() self.gm.playerData = playerData #for key in playerData: # self.gm.playerData[key] = playerData[key] print("player data loaded from file %s, data = %s" % (filename, self.gm.playerData)) self.playerData = self.gm.playerData def setMode(self, mode="move"): if mode == "move": #print "Map Manager switched to move mode" self.mode = "move" self.accept("mouse1", self.onClickObject) # left click #self.accept("mouse2", self.onClickObject2) # scroll click self.accept("mouse3", self.onClickObject3) # right click #self.accept("wheel_up", self.camHandler.moveHeight, [-0.02]) #self.accept("wheel_down", self.camHandler.moveHeight, [0.02]) elif mode == "talk": print "Map manager switched to talk mode" self.mode = "talk" self.ignore("mouse1") self.ignore("mouse2") self.ignore("mouse3") elif mode == "fight": print "Map Manager switched to fight mode" self.mode = "fight" self.accept("mouse1", self.onClickObject) # left click #self.accept("mouse2", self.onClickObject2) # scroll click #self.accept("mouse3", self.onClickObject3) # right click modeMsg = "Game mode : " + self.mode #self.msgTilePos.setText(modeMsg) self.gui.setInfo(modeMsg) def onClickObject(self): # click on MapObject : if self.dialog:return name = self.getHoverNPCName() if name is not None and not self.gui.inventory.visible and not self.dialog: print "map manager : left click on NPC : %s, opening dialog" % (name) if self.getPlayerDistToNPC(name)< 4.0: self.openDialog(name) else: x, y = self.map.getClosestOpenTile(self.NPC[name].getTilePos()[0], self.NPC[name].getTilePos()[1]) self.playerGoto(x, y) return name = self.getHoverObjectName() if name is not None and not self.gui.inventory.visible and not self.dialog: print "map manager : left click on map object : %s, position = %s" % (name, self.map.mapObjects[name].getPos()) return name = self.getHoverCreatureName() if name is not None: print "Click on %s" % (name) return if base.mouseWatcherNode.hasMouse() and not self.gui.inventory.visible and not self.dialog: mpos = base.mouseWatcherNode.getMouse() pos = self.clicker.getMouseTilePos(mpos) self.playerGoto(pos[0], pos[1]) print "Player goto %s/%s" % (pos[0], pos[1]) return # and this should never happen print "WARNING : map manager : left click on nothing?!" return False def onClickObject3(self): # click on MapObject : if self.dialog:return name = self.getHoverNPCName() if name is not None and not self.gui.inventory.visible and not self.dialog: print "map manager : right click on NPC : %s, label toggle" % (name) #self.NPC[name].toggleLabel() self.gui.objectMenu.rebuild(["look", "talk", "attack"]) self.gui.objectMenu.buttons[0].bind(DGG.B1PRESS, self.onTalkTo, [name]) self.gui.objectMenu.buttons[1].bind(DGG.B1PRESS, self.onTalkTo, [name]) self.gui.objectMenu.buttons[2].bind(DGG.B1PRESS, self.onTalkTo, [name]) self.gui.objectMenu.expand() if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.gui.objectMenu.setPos(mpos) self.gm.cursor.setMode() #self.openDialog(name) return name = self.getHoverObjectName() if name is not None and not self.gui.inventory.visible and not self.dialog: print "map manager : right click on map object : %s, position = %s" % (name, self.map.mapObjects[name].getPos()) return name = self.getHoverCreatureName() if name is not None and not self.gui.inventory.visible and not self.dialog: print "map manager : right click on map creature / drop : %s, position = %s" % (name, self.drops[name].getPos()) return if base.mouseWatcherNode.hasMouse() and not self.dialog: #mpos = base.mouseWatcherNode.getMouse() #pos = self.clicker.getMouseTilePos(mpos) #self.playerGoto(pos[0], pos[1]) #print "Player goto %s/%s" % (pos[0], pos[1]) #self.gm.cursor.setMode() self.gui.inventory.toggle() return # and this should never happen #print "WARNING : map manager : right click on nothing?!" return False def onTalkTo(self, name, extraArgs=[]): self.gui.closeMenu() # in case we asked the talk to from this context menu if self.getPlayerDistToNPC(name)< 4.0: self.openDialog(name) else: tile = self.map.getClosestOpenTile(self.NPC[name].getTilePos()[0], self.NPC[name].getTilePos()[1]) if tile: x, y = tile self.playerGoto(x, y) self.player.sequence.append(Func(self.onTalkTo, name)) self.player.sequence.resume() # ? #print "Appended talkTo %s to sequence %s" % (name, self.player.sequence) else: print "%s can't be reached." % (name) self.gm.cursor.setMode() def getDropNewName(self, genre): i = 1 tmpName = genre + "_" + str(i) while tmpName in self.drops: i = i+1 tmpName = genre + "_" + str(i) return tmpName def addDrop(self, genre, nb, pos): name = self.getDropNewName(genre) drop = MapDrop(self, name, genre, nb, pos) self.drops[name] = drop def addNPC(self, name, modelName, tex, x, y): npc = MapNPC(self, name, modelName, tex) npc.setTilePos(x, y) self.NPC[name] = npc npc.reparentTo(self.map.NPCroot) ai = NPCAI(self, name) self.NPCAI[name] = ai def removeNPC(self, name): if name in self.NPC: self.NPC[name].destroy() del self.NPC[name] if name in self.NPCAI: self.NPCAI[name].stop() del self.NPCAI[name] def removeAllNPC(self): for name in self.NPC.keys(): self.NPC[name].destroy() del self.NPC[name] if name in self.NPCAI: self.NPCAI[name].stop() del self.NPCAI[name] def playerGoto(self, x, y): start = (self.player.getTilePos()) end = (x, y) data = self.map.collisionGrid.data path = astar(start, end, data) if path is []: #print "... but no good path found" return False newPath = [] for tile in path: newPath.append((tile[0], tile[1], self.map.collisionGrid.getTileHeight(tile[0], tile[1]))) self.player.setPath(newPath) return True def getPlayerDistToNPC(self, name): return Vec3(self.NPC[name].getPos() - self.player.getPos()).length() def getPlayerDistToMapObject(self, name): return Vec3(self.map.mapObjects[name].getPos() - self.player.getPos()).length() def NPCGoto(self, name, x, y): #print "NPCGoto called!" if name not in self.NPC: #print "%s is not a known NPC" % (name) return False start = (self.NPC[name].getTilePos()) end = (x, y) data = self.map.collisionGrid.data path = astar(start, end, data) if path is []: #print "... but no good path found" return False #else: # print "NPCGoto : path found : %s" % (path) newPath = [] for tile in path: newPath.append((tile[0], tile[1], self.map.collisionGrid.getTileHeight(tile[0], tile[1]))) self.NPC[name].setPath(newPath) def openDialog(self, name, extraArgs=[]): if self.dialog: #print "There was dialog garbage left, %s got his/her dialog shut unpolitely." % (self.dialog.name) #self.dialog.destroy() print "... but a dialog is already open for %s, aborting." % self.dialog.name return False if name in self.NPC: self.NPC[name].stop() playerPos = self.player.getTilePos() npcPos = self.NPC[name].getTilePos() lookDirX, lookDirY = playerPos[0]-npcPos[0], playerPos[1]-npcPos[1] self.NPC[name].lookAt(lookDirX, lookDirY) self.player.stop() self.player.lookAt(-lookDirX, -lookDirY) if name in dialogDic: self.gui.openDialog(name) self.dialog = dialogDic[name](self, name) else: self.gui.openDialog(name) self.dialog = Dialog(self, name) else: print "Error, dialog called for unknown NPC : %s" % (name) def updateCam(self): self.gm.gameCam.update() def update(self, task): self.updateCam() if self.dialog: self.cursor.clear() return task.cont if self.gui.inventory.visible: #self.gui.clearObjInfo() #self.cursor.clear() #self.gm.cursor.setMode() return task.cont dt = globalClock.getDt() if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() pos = self.clicker.getMouseTilePos(mpos) else: mpos = None pos = None #return task.cont if self.mode == "move" and mpos is not None: name = self.getHoverObjectName() if name is not None: msg = "in game object : " + name + "\npos = " + str(self.map.mapObjects[name].getPos()) #self.gui.setObjInfo(mpos, msg) self.cursor.setMode("hand") self.cursor.setInfo(msg) return task.cont name = self.getHoverNPCName() if name is not None: msg = "talk to : " + name + "\npos = " + str(self.NPC[name].getPos()) #self.gui.setObjInfo(mpos, msg) self.cursor.setInfo(msg) if not self.gui.objectMenu.open: self.cursor.setMode("talk") return task.cont name = self.getHoverCreatureName() if name is not None: self.cursor.setMode("hand") msg = "drop : " + name self.cursor.setInfo(msg) #self.gui.setObjInfo(mpos, msg) return task.cont #self.gm.cursor.setMode("default") #self.gui.clearObjInfo() if self.cursor.item is None: self.cursor.clear() #if self.cursor.item is not None and self.cursor.mode is "default": else: self.cursor.setInfo(str(self.cursor.itemNb)) return task.cont return task.cont