예제 #1
0
class PlayerPositionTool(EditorTool):
    surfaceBuild = True
    toolIconName = "player"
    tooltipText = "Players"
    movingPlayer = None
    recordMove = True

    def reloadTextures(self):
        self.charTex = loadPNGTexture('char.png')

    @alertException
    def addPlayer(self):
        op = PlayerAddOperation(self)

        self.editor.addOperation(op)
        if op.canUndo:
            self.editor.addUnsavedEdit()

    @alertException
    def removePlayer(self):
        player = self.panel.selectedPlayer

        if player != "[No players]":
            op = PlayerRemoveOperation(self, player)

            self.editor.addOperation(op)
            if op.canUndo:
                self.editor.addUnsavedEdit()

    @alertException
    def movePlayer(self):
        if self.panel.selectedPlayer != "[No players]":
            self.movingPlayer = self.panel.selectedPlayer
            if self.movingPlayer == "Player (Single Player)":
                self.movingPlayer = "Player"

    @alertException
    def movePlayerToCamera(self):
        player = self.panel.selectedPlayer
        if player == "Player (Single Player)":
            player = "Player"
        if player != "[No players]":
            pos = self.editor.mainViewport.cameraPosition
            y = self.editor.mainViewport.yaw
            p = self.editor.mainViewport.pitch

            op = PlayerMoveOperation(self, pos, player, (y, p))
            self.movingPlayer = None
            self.editor.addOperation(op)
            if op.canUndo:
                self.editor.addUnsavedEdit()

    def delete_skin(self, uuid):
        del self.playerTexture[uuid]
        self.playerTexture[uuid] = self.charTex

    @alertException
    def reloadSkins(self):
        #result = ask("This pulls skins from the online server, so this may take a while", ["Ok", "Cancel"])
        #if result == "Ok":
        try:
            for player in self.editor.level.players:
                if player != "Player" and player in self.playerTexture.keys():
                    del self.playerTexture[player]
#                     print 6
                    r = self.playercache.getPlayerSkin(player, force_download=True, instance=self)
                    if isinstance(r, (str, unicode)):
                        r = r.join()
                    self.playerTexture[player] = loadPNGTexture(r)
            #self.markerList.call(self._drawToolMarkers)
        except:
            raise Exception("Could not connect to the skins server, please check your Internet connection and try again.")

    def gotoPlayerCamera(self):
        player = self.panel.selectedPlayer
        if player == "Player (Single Player)":
            player = "Player"

        try:
            pos = self.editor.level.getPlayerPosition(player)
            y, p = self.editor.level.getPlayerOrientation(player)
            self.editor.gotoDimension(self.editor.level.getPlayerDimension(player))

            self.editor.mainViewport.cameraPosition = pos
            self.editor.mainViewport.yaw = y
            self.editor.mainViewport.pitch = p
            self.editor.mainViewport.stopMoving()
            self.editor.mainViewport.invalidate()
        except pymclevel.PlayerNotFound:
            pass

    def gotoPlayer(self):
        player = self.panel.selectedPlayer
        if player == "Player (Single Player)":
            player = "Player"

        try:
            if self.editor.mainViewport.pitch < 0:
                self.editor.mainViewport.pitch = -self.editor.mainViewport.pitch
                self.editor.mainViewport.cameraVector = self.editor.mainViewport._cameraVector()
            cv = self.editor.mainViewport.cameraVector

            pos = self.editor.level.getPlayerPosition(player)
            pos = map(lambda p, c: p - c * 5, pos, cv)
            self.editor.gotoDimension(self.editor.level.getPlayerDimension(player))

            self.editor.mainViewport.cameraPosition = pos
            self.editor.mainViewport.stopMoving()
        except pymclevel.PlayerNotFound:
            pass

    def __init__(self, *args):
        EditorTool.__init__(self, *args)
        self.reloadTextures()
        self.nonSavedPlayers = []

        textureVerticesHead = numpy.array(
            (
                # Backside of Head
                24, 16, # Bottom Left
                24, 8, # Top Left
                32, 8, # Top Right
                32, 16, # Bottom Right

                # Front of Head
                8, 16,
                8, 8,
                16, 8,
                16, 16,

                #
                24, 0,
                16, 0,
                16, 8,
                24, 8,

                #
                16, 0,
                8, 0,
                8, 8,
                16, 8,

                #
                8, 8,
                0, 8,
                0, 16,
                8, 16,

                16, 16,
                24, 16,
                24, 8,
                16, 8,

            ), dtype='f4')
        
        textureVerticesHat = numpy.array(
            (
                56, 16,
                56, 8,
                64, 8,
                64, 16,
                
                48, 16,
                48, 8,
                40, 8,
                40, 16,
                
                56, 0,
                48, 0,
                48, 8,
                56, 8,
                
                48, 0,
                40, 0,
                40, 8,
                48, 8,
                
                40, 8,
                32, 8,
                32, 16,
                40, 16,
                
                48, 16,
                56, 16,
                56, 8,
                48, 8,
                
            ), dtype='f4')
        

        textureVerticesHead.shape = (24, 2)
        textureVerticesHat.shape = (24, 2)

        textureVerticesHead *= 4
        textureVerticesHead[:, 1] *= 2
        
        textureVerticesHat *= 4
        textureVerticesHat[:, 1] *= 2

        self.texVerts = (textureVerticesHead, textureVerticesHat) 

        self.playerPos = {0:{}, -1:{}, 1:{}}
        self.playerTexture = {}
        self.revPlayerPos = {0:{}, -1:{}, 1:{}}
        self.inOtherDimension = {0: [], 1: [], -1: []}
        self.playercache = PlayerCache()

        self.markerList = DisplayList()

    panel = None

    def showPanel(self):
        if not self.panel:
            self.panel = PlayerPositionPanel(self)

        self.panel.centery = (self.editor.mainViewport.height - self.editor.toolbar.height) / 2 + self.editor.subwidgets[0].height
        self.panel.left = self.editor.left

        self.editor.add(self.panel)

    def hidePanel(self):
        if self.panel and self.panel.parent:
            self.panel.parent.remove(self.panel)
        self.panel = None

    def drawToolReticle(self):
        if self.movingPlayer is None:
            return

        pos, direction = self.editor.blockFaceUnderCursor
        dim = self.editor.level.getPlayerDimension(self.movingPlayer)
        pos = (pos[0], pos[1] + 2, pos[2])

        x, y, z = pos

        # x,y,z=map(lambda p,d: p+d, pos, direction)
        GL.glEnable(GL.GL_BLEND)
        GL.glColor(1.0, 1.0, 1.0, 0.5)
        self.drawCharacterHead(x + 0.5, y + 0.75, z + 0.5, self.revPlayerPos[dim][self.movingPlayer], dim)
        GL.glDisable(GL.GL_BLEND)

        GL.glEnable(GL.GL_DEPTH_TEST)
        self.drawCharacterHead(x + 0.5, y + 0.75, z + 0.5, self.revPlayerPos[dim][self.movingPlayer], dim)
        drawTerrainCuttingWire(BoundingBox((x, y, z), (1, 1, 1)))
        drawTerrainCuttingWire(BoundingBox((x, y - 1, z), (1, 1, 1)))
        #drawTerrainCuttingWire( BoundingBox((x,y-2,z), (1,1,1)) )
        GL.glDisable(GL.GL_DEPTH_TEST)

    markerLevel = None

    def drawToolMarkers(self):
        if not config.settings.drawPlayerHeads.get():
            return
        if self.markerLevel != self.editor.level:
            self.markerList.invalidate()
            self.markerLevel = self.editor.level
        self.markerList.call(self._drawToolMarkers)

    def _drawToolMarkers(self):
        GL.glColor(1.0, 1.0, 1.0, 0.5)

        GL.glEnable(GL.GL_DEPTH_TEST)
        GL.glMatrixMode(GL.GL_MODELVIEW)
        for player in self.editor.level.players:
            try:
                pos = self.editor.level.getPlayerPosition(player)
                yaw, pitch = self.editor.level.getPlayerOrientation(player)
                dim = self.editor.level.getPlayerDimension(player)
                
                self.inOtherDimension[dim].append(player)
                self.playerPos[dim][pos] = player
                self.revPlayerPos[dim][player] = pos
                
                if player != "Player" and config.settings.downloadPlayerSkins.get():
#                     print 7
                    r = self.playercache.getPlayerSkin(player, force_download=False)
                    if not isinstance(r, (str, unicode)):
                        r = r.join()
                    self.playerTexture[player] = loadPNGTexture(r)
                else:
                    self.playerTexture[player] = self.charTex
                    
                if dim != self.editor.level.dimNo:
                    continue

                x, y, z = pos
                GL.glPushMatrix()
                GL.glTranslate(x, y, z)
                GL.glRotate(-yaw, 0, 1, 0)
                GL.glRotate(pitch, 1, 0, 0)
                GL.glColor(1, 1, 1, 1)
                self.drawCharacterHead(0, 0, 0, (x,y,z), self.editor.level.dimNo)
                GL.glPopMatrix()
                # GL.glEnable(GL.GL_BLEND)
                drawTerrainCuttingWire(FloatBox((x - .5, y - .5, z - .5), (1, 1, 1)),
                                       c0=(0.3, 0.9, 0.7, 1.0),
                                       c1=(0, 0, 0, 0),
                )

                #GL.glDisable(GL.GL_BLEND)

            except Exception, e:
                print "Exception in editortools.player.PlayerPositionTool._drawToolMarkers:", repr(e)
                import traceback
                print traceback.format_exc()
                continue

        GL.glDisable(GL.GL_DEPTH_TEST)
예제 #2
0
class PlayerAddOperation(Operation):
    playerTag = None

    def __init__(self, tool):
        super(PlayerAddOperation, self).__init__(tool.editor, tool.editor.level)
        self.tool = tool
        self.level = self.tool.editor.level
        self.canUndo = False
        self.playercache = PlayerCache()

    def perform(self, recordUndo=True):
        initial = ""
        allowed_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
        while True:
            self.player = input_text_buttons("Enter a Player Name: ", 160, initial=initial, allowed_chars=allowed_chars)
            if self.player is None:
                return
            elif len(self.player) > 16:
                alert("Name too long. Maximum name length is 16.")
                initial = self.player
            elif len(self.player) < 1:
                alert("Name too short. Minimum name length is 1.")
                initial = self.player
            else:
                break
            
#         print 1
        data = self.playercache.getPlayerInfo(self.player)
        if "<Unknown UUID>" not in data and "Server not ready" not in data:
            self.uuid = data[0]
            self.player = data[1]
        else:
            action = ask("Could not get {}'s UUID. Please make sure that you are connected to the internet and that the player \"{}\" exists.".format(self.player, self.player), ["Enter UUID manually", "Cancel"])
            if action != "Enter UUID manually":
                return
            self.uuid = input_text_buttons("Enter a Player UUID: ", 160)
            if not self.uuid:
                return
#             print 2
            self.player = self.playercache.getPlayerInfo(self.uuid)
            if self.player == self.uuid.replace("-", ""):
                if ask("UUID was not found. Continue anyways?") == "Cancel":
                    return
#         print "PlayerAddOperation.perform::self.uuid", self.uuid
        if self.uuid in self.level.players:
            alert("Player already exists in this World.")
            return

        self.playerTag = self.newPlayer()

        #if self.tool.panel:
        #    self.tool.panel.players.append(self.player)

        if self.level.oldPlayerFolderFormat:
            self.level.playerTagCache[self.level.getPlayerPath(self.player)] = self.playerTag
            
            self.level.players.append(self.player)
            #if self.tool.panel:
                #self.tool.panel.player_UUID[self.player] = self.player

        else:
            self.level.playerTagCache[self.level.getPlayerPath(self.uuid)] = self.playerTag
            
            self.level.players.append(self.uuid)
            if self.tool.panel:
                self.tool.panel.player_UUID["UUID"].append(self.uuid)
                self.tool.panel.player_UUID["Name"].append(self.player)

        self.tool.playerPos[self.editor.level.dimNo][(0,0,0)] = self.uuid
        self.tool.revPlayerPos[self.editor.level.dimNo][self.uuid] = (0,0,0)
#         print 3
        r = self.playercache.getPlayerSkin(self.uuid, force_download=False)
        if not isinstance(r, (str, unicode)):
#             print 'r 1', r
            r = r.join()
#             print 'r 2', r
        self.tool.playerTexture[self.uuid] = loadPNGTexture(r)
        self.tool.markerList.invalidate()
        self.tool.recordMove = False
        self.tool.movingPlayer = self.uuid
        if self.tool.panel:
            self.tool.hidePanel()
            self.tool.showPanel()
        self.canUndo = True
        self.playerTag.save(self.level.getPlayerPath(self.uuid))
        self.tool.nonSavedPlayers.append(self.level.getPlayerPath(self.uuid))
        self.tool.inOtherDimension[self.editor.level.dimNo].append(self.uuid)

    def newPlayer(self):
        playerTag = nbt.TAG_Compound()

        playerTag['Air'] = nbt.TAG_Short(300)
        playerTag['AttackTime'] = nbt.TAG_Short(0)
        playerTag['DeathTime'] = nbt.TAG_Short(0)
        playerTag['Fire'] = nbt.TAG_Short(-20)
        playerTag['Health'] = nbt.TAG_Short(20)
        playerTag['HurtTime'] = nbt.TAG_Short(0)
        playerTag['Score'] = nbt.TAG_Int(0)
        playerTag['FallDistance'] = nbt.TAG_Float(0)
        playerTag['OnGround'] = nbt.TAG_Byte(0)
        playerTag['Dimension'] = nbt.TAG_Int(self.editor.level.dimNo)

        playerTag["Inventory"] = nbt.TAG_List()

        playerTag['Motion'] = nbt.TAG_List([nbt.TAG_Double(0) for i in xrange(3)])
        spawn = self.level.playerSpawnPosition()
        spawnX = spawn[0]
        spawnZ = spawn[2]
        blocks = [self.level.blockAt(spawnX, i, spawnZ) for i in xrange(self.level.Height)]
        i = self.level.Height
        done = False
        for index, b in enumerate(reversed(blocks)):
            if b != 0 and not done:
                i = index
                done = True
        spawnY = self.level.Height - i
        playerTag['Pos'] = nbt.TAG_List([nbt.TAG_Double([spawnX, spawnY, spawnZ][i]) for i in xrange(3)])
        playerTag['Rotation'] = nbt.TAG_List([nbt.TAG_Float(0), nbt.TAG_Float(0)])

        return playerTag

    def undo(self):
        self.level.players.remove(self.uuid)
        self.tool.movingPlayer = None
        if self.tool.panel:
            #self.tool.panel.players.remove(self.player)
            self.tool.panel.player_UUID["UUID"].remove(self.uuid)
            self.tool.panel.player_UUID["Name"].remove(self.player)
            self.tool.hidePanel()
            self.tool.showPanel()
        if self.tool.movingPlayer is None:
            del self.tool.playerPos[self.tool.revPlayerPos[self.uuid]]
        else:
            del self.tool.playerPos[(0,0,0)]
        del self.tool.revPlayerPos[self.uuid]
        del self.tool.playerTexture[self.uuid]
        os.remove(self.level.getPlayerPath(self.uuid))
        if self.level.getPlayerPath(self.uuid) in self.tool.nonSavedPlayers:
            self.tool.nonSavedPlayers.remove(self.level.getPlayerPath(self.uuid))

        self.tool.markerList.invalidate()

    def redo(self):
        if not (self.playerTag is None):
            self.level.playerTagCache[self.level.getPlayerPath(self.uuid)] = self.playerTag

            self.level.players.append(self.uuid)
            if self.tool.panel:
                #self.tool.panel.players.append(self.uuid)
                #self.tool.panel.player_UUID[self.player] = self.uuid
                self.tool.panel.player_UUID["UUID"].append(self.uuid)
                self.tool.panel.player_UUID["Name"].append(self.player)
#             print 4
            r = self.playercache.getPlayerSkin(self.uuid)
            if isinstance(r, (str, unicode)):
                r = r.join()
            self.tool.playerTexture[self.uuid] = loadPNGTexture(r)
            self.tool.playerPos[(0,0,0)] = self.uuid
            self.tool.revPlayerPos[self.uuid] = (0,0,0)
            self.playerTag.save(self.level.getPlayerPath(self.uuid))
            self.tool.nonSavedPlayers.append(self.level.getPlayerPath(self.uuid))

        self.tool.markerList.invalidate()
예제 #3
0
class PlayerAddOperation(Operation):
    playerTag = None

    def __init__(self, tool):
        super(PlayerAddOperation, self).__init__(tool.editor,
                                                 tool.editor.level)
        self.tool = tool
        self.level = self.tool.editor.level
        self.canUndo = False
        self.playercache = PlayerCache()

    def perform(self, recordUndo=True):
        initial = ""
        allowed_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
        while True:
            self.player = input_text_buttons("Enter a Player Name: ",
                                             160,
                                             initial=initial,
                                             allowed_chars=allowed_chars)
            if self.player is None:
                return
            elif len(self.player) > 16:
                alert("Name too long. Maximum name length is 16.")
                initial = self.player
            elif len(self.player) < 1:
                alert("Name too short. Minimum name length is 1.")
                initial = self.player
            else:
                break

#         print 1
        data = self.playercache.getPlayerInfo(self.player)
        if "<Unknown UUID>" not in data and "Server not ready" not in data:
            self.uuid = data[0]
            self.player = data[1]
        else:
            action = ask(
                "Could not get {}'s UUID. Please make sure that you are connected to the internet and that the player \"{}\" exists."
                .format(self.player,
                        self.player), ["Enter UUID manually", "Cancel"])
            if action != "Enter UUID manually":
                return
            self.uuid = input_text_buttons("Enter a Player UUID: ", 160)
            if not self.uuid:
                return
#             print 2
            self.player = self.playercache.getPlayerInfo(self.uuid)
            if self.player == self.uuid.replace("-", ""):
                if ask("UUID was not found. Continue anyways?") == "Cancel":
                    return
#         print "PlayerAddOperation.perform::self.uuid", self.uuid
        if self.uuid in self.level.players:
            alert("Player already exists in this World.")
            return

        self.playerTag = self.newPlayer()

        #if self.tool.panel:
        #    self.tool.panel.players.append(self.player)

        if self.level.oldPlayerFolderFormat:
            self.level.playerTagCache[self.level.getPlayerPath(
                self.player)] = self.playerTag

            self.level.players.append(self.player)
            #if self.tool.panel:
            #self.tool.panel.player_UUID[self.player] = self.player

        else:
            self.level.playerTagCache[self.level.getPlayerPath(
                self.uuid)] = self.playerTag

            self.level.players.append(self.uuid)
            if self.tool.panel:
                self.tool.panel.player_UUID["UUID"].append(self.uuid)
                self.tool.panel.player_UUID["Name"].append(self.player)

        self.tool.playerPos[self.editor.level.dimNo][(0, 0, 0)] = self.uuid
        self.tool.revPlayerPos[self.editor.level.dimNo][self.uuid] = (0, 0, 0)
        #         print 3
        r = self.playercache.getPlayerSkin(self.uuid, force_download=False)
        if not isinstance(r, (str, unicode)):
            #             print 'r 1', r
            r = r.join()
#             print 'r 2', r
        self.tool.playerTexture[self.uuid] = loadPNGTexture(r)
        self.tool.markerList.invalidate()
        self.tool.recordMove = False
        self.tool.movingPlayer = self.uuid
        if self.tool.panel:
            self.tool.hidePanel()
            self.tool.showPanel()
        self.canUndo = True
        self.playerTag.save(self.level.getPlayerPath(self.uuid))
        self.tool.nonSavedPlayers.append(self.level.getPlayerPath(self.uuid))
        self.tool.inOtherDimension[self.editor.level.dimNo].append(self.uuid)

    def newPlayer(self):
        playerTag = nbt.TAG_Compound()

        playerTag['Air'] = nbt.TAG_Short(300)
        playerTag['AttackTime'] = nbt.TAG_Short(0)
        playerTag['DeathTime'] = nbt.TAG_Short(0)
        playerTag['Fire'] = nbt.TAG_Short(-20)
        playerTag['Health'] = nbt.TAG_Short(20)
        playerTag['HurtTime'] = nbt.TAG_Short(0)
        playerTag['Score'] = nbt.TAG_Int(0)
        playerTag['FallDistance'] = nbt.TAG_Float(0)
        playerTag['OnGround'] = nbt.TAG_Byte(0)
        playerTag['Dimension'] = nbt.TAG_Int(self.editor.level.dimNo)

        playerTag["Inventory"] = nbt.TAG_List()

        playerTag['Motion'] = nbt.TAG_List(
            [nbt.TAG_Double(0) for i in xrange(3)])
        spawn = self.level.playerSpawnPosition()
        spawnX = spawn[0]
        spawnZ = spawn[2]
        blocks = [
            self.level.blockAt(spawnX, i, spawnZ)
            for i in xrange(self.level.Height)
        ]
        i = self.level.Height
        done = False
        for index, b in enumerate(reversed(blocks)):
            if b != 0 and not done:
                i = index
                done = True
        spawnY = self.level.Height - i
        playerTag['Pos'] = nbt.TAG_List(
            [nbt.TAG_Double([spawnX, spawnY, spawnZ][i]) for i in xrange(3)])
        playerTag['Rotation'] = nbt.TAG_List(
            [nbt.TAG_Float(0), nbt.TAG_Float(0)])

        return playerTag

    def undo(self):
        self.level.players.remove(self.uuid)
        self.tool.movingPlayer = None
        if self.tool.panel:
            #self.tool.panel.players.remove(self.player)
            self.tool.panel.player_UUID["UUID"].remove(self.uuid)
            self.tool.panel.player_UUID["Name"].remove(self.player)
            self.tool.hidePanel()
            self.tool.showPanel()
        if self.tool.movingPlayer is None:
            del self.tool.playerPos[self.tool.revPlayerPos[self.uuid]]
        else:
            del self.tool.playerPos[(0, 0, 0)]
        del self.tool.revPlayerPos[self.uuid]
        del self.tool.playerTexture[self.uuid]
        os.remove(self.level.getPlayerPath(self.uuid))
        if self.level.getPlayerPath(self.uuid) in self.tool.nonSavedPlayers:
            self.tool.nonSavedPlayers.remove(
                self.level.getPlayerPath(self.uuid))

        self.tool.markerList.invalidate()

    def redo(self):
        if not (self.playerTag is None):
            self.level.playerTagCache[self.level.getPlayerPath(
                self.uuid)] = self.playerTag

            self.level.players.append(self.uuid)
            if self.tool.panel:
                #self.tool.panel.players.append(self.uuid)
                #self.tool.panel.player_UUID[self.player] = self.uuid
                self.tool.panel.player_UUID["UUID"].append(self.uuid)
                self.tool.panel.player_UUID["Name"].append(self.player)


#             print 4
            r = self.playercache.getPlayerSkin(self.uuid)
            if isinstance(r, (str, unicode)):
                r = r.join()
            self.tool.playerTexture[self.uuid] = loadPNGTexture(r)
            self.tool.playerPos[(0, 0, 0)] = self.uuid
            self.tool.revPlayerPos[self.uuid] = (0, 0, 0)
            self.playerTag.save(self.level.getPlayerPath(self.uuid))
            self.tool.nonSavedPlayers.append(
                self.level.getPlayerPath(self.uuid))

        self.tool.markerList.invalidate()
예제 #4
0
class PlayerPositionTool(EditorTool):
    surfaceBuild = True
    toolIconName = "player"
    tooltipText = "Players"
    movingPlayer = None
    recordMove = True

    def reloadTextures(self):
        self.charTex = loadPNGTexture('char.png')

    @alertException
    def addPlayer(self):
        op = PlayerAddOperation(self)

        self.editor.addOperation(op)
        if op.canUndo:
            self.editor.addUnsavedEdit()

    @alertException
    def removePlayer(self):
        player = self.panel.selectedPlayer

        if player != "[No players]":
            op = PlayerRemoveOperation(self, player)

            self.editor.addOperation(op)
            if op.canUndo:
                self.editor.addUnsavedEdit()

    @alertException
    def movePlayer(self):
        if self.panel.selectedPlayer != "[No players]":
            self.movingPlayer = self.panel.selectedPlayer
            if self.movingPlayer == "Player (Single Player)":
                self.movingPlayer = "Player"

    @alertException
    def movePlayerToCamera(self):
        player = self.panel.selectedPlayer
        if player == "Player (Single Player)":
            player = "Player"
        if player != "[No players]":
            pos = self.editor.mainViewport.cameraPosition
            y = self.editor.mainViewport.yaw
            p = self.editor.mainViewport.pitch

            op = PlayerMoveOperation(self, pos, player, (y, p))
            self.movingPlayer = None
            self.editor.addOperation(op)
            if op.canUndo:
                self.editor.addUnsavedEdit()

    def delete_skin(self, uuid):
        del self.playerTexture[uuid]
        self.playerTexture[uuid] = self.charTex

    @alertException
    def reloadSkins(self):
        #result = ask("This pulls skins from the online server, so this may take a while", ["Ok", "Cancel"])
        #if result == "Ok":
        try:
            for player in self.editor.level.players:
                if player != "Player" and player in self.playerTexture.keys():
                    del self.playerTexture[player]
                    #                     print 6
                    r = self.playercache.getPlayerSkin(player,
                                                       force_download=True,
                                                       instance=self)
                    if isinstance(r, (str, unicode)):
                        r = r.join()
                    self.playerTexture[player] = loadPNGTexture(r)
            #self.markerList.call(self._drawToolMarkers)
        except:
            raise Exception(
                "Could not connect to the skins server, please check your Internet connection and try again."
            )

    def gotoPlayerCamera(self):
        player = self.panel.selectedPlayer
        if player == "Player (Single Player)":
            player = "Player"

        try:
            pos = self.editor.level.getPlayerPosition(player)
            y, p = self.editor.level.getPlayerOrientation(player)
            self.editor.gotoDimension(
                self.editor.level.getPlayerDimension(player))

            self.editor.mainViewport.cameraPosition = pos
            self.editor.mainViewport.yaw = y
            self.editor.mainViewport.pitch = p
            self.editor.mainViewport.stopMoving()
            self.editor.mainViewport.invalidate()
        except pymclevel.PlayerNotFound:
            pass

    def gotoPlayer(self):
        player = self.panel.selectedPlayer
        if player == "Player (Single Player)":
            player = "Player"

        try:
            if self.editor.mainViewport.pitch < 0:
                self.editor.mainViewport.pitch = -self.editor.mainViewport.pitch
                self.editor.mainViewport.cameraVector = self.editor.mainViewport._cameraVector(
                )
            cv = self.editor.mainViewport.cameraVector

            pos = self.editor.level.getPlayerPosition(player)
            pos = map(lambda p, c: p - c * 5, pos, cv)
            self.editor.gotoDimension(
                self.editor.level.getPlayerDimension(player))

            self.editor.mainViewport.cameraPosition = pos
            self.editor.mainViewport.stopMoving()
        except pymclevel.PlayerNotFound:
            pass

    def __init__(self, *args):
        EditorTool.__init__(self, *args)
        self.reloadTextures()
        self.nonSavedPlayers = []

        textureVerticesHead = numpy.array(
            (
                # Backside of Head
                24,
                16,  # Bottom Left
                24,
                8,  # Top Left
                32,
                8,  # Top Right
                32,
                16,  # Bottom Right

                # Front of Head
                8,
                16,
                8,
                8,
                16,
                8,
                16,
                16,

                #
                24,
                0,
                16,
                0,
                16,
                8,
                24,
                8,

                #
                16,
                0,
                8,
                0,
                8,
                8,
                16,
                8,

                #
                8,
                8,
                0,
                8,
                0,
                16,
                8,
                16,
                16,
                16,
                24,
                16,
                24,
                8,
                16,
                8,
            ),
            dtype='f4')

        textureVerticesHat = numpy.array((
            56,
            16,
            56,
            8,
            64,
            8,
            64,
            16,
            48,
            16,
            48,
            8,
            40,
            8,
            40,
            16,
            56,
            0,
            48,
            0,
            48,
            8,
            56,
            8,
            48,
            0,
            40,
            0,
            40,
            8,
            48,
            8,
            40,
            8,
            32,
            8,
            32,
            16,
            40,
            16,
            48,
            16,
            56,
            16,
            56,
            8,
            48,
            8,
        ),
                                         dtype='f4')

        textureVerticesHead.shape = (24, 2)
        textureVerticesHat.shape = (24, 2)

        textureVerticesHead *= 4
        textureVerticesHead[:, 1] *= 2

        textureVerticesHat *= 4
        textureVerticesHat[:, 1] *= 2

        self.texVerts = (textureVerticesHead, textureVerticesHat)

        self.playerPos = {0: {}, -1: {}, 1: {}}
        self.playerTexture = {}
        self.revPlayerPos = {0: {}, -1: {}, 1: {}}
        self.inOtherDimension = {0: [], 1: [], -1: []}
        self.playercache = PlayerCache()

        self.markerList = DisplayList()

    panel = None

    def showPanel(self):
        if not self.panel:
            self.panel = PlayerPositionPanel(self)

        self.panel.centery = (
            self.editor.mainViewport.height -
            self.editor.toolbar.height) / 2 + self.editor.subwidgets[0].height
        self.panel.left = self.editor.left

        self.editor.add(self.panel)

    def hidePanel(self):
        if self.panel and self.panel.parent:
            self.panel.parent.remove(self.panel)
        self.panel = None

    def drawToolReticle(self):
        if self.movingPlayer is None:
            return

        pos, direction = self.editor.blockFaceUnderCursor
        dim = self.editor.level.getPlayerDimension(self.movingPlayer)
        pos = (pos[0], pos[1] + 2, pos[2])

        x, y, z = pos

        # x,y,z=map(lambda p,d: p+d, pos, direction)
        GL.glEnable(GL.GL_BLEND)
        GL.glColor(1.0, 1.0, 1.0, 0.5)
        self.drawCharacterHead(x + 0.5, y + 0.75, z + 0.5,
                               self.revPlayerPos[dim][self.movingPlayer], dim)
        GL.glDisable(GL.GL_BLEND)

        GL.glEnable(GL.GL_DEPTH_TEST)
        self.drawCharacterHead(x + 0.5, y + 0.75, z + 0.5,
                               self.revPlayerPos[dim][self.movingPlayer], dim)
        drawTerrainCuttingWire(BoundingBox((x, y, z), (1, 1, 1)))
        drawTerrainCuttingWire(BoundingBox((x, y - 1, z), (1, 1, 1)))
        #drawTerrainCuttingWire( BoundingBox((x,y-2,z), (1,1,1)) )
        GL.glDisable(GL.GL_DEPTH_TEST)

    markerLevel = None

    def drawToolMarkers(self):
        if not config.settings.drawPlayerHeads.get():
            return
        if self.markerLevel != self.editor.level:
            self.markerList.invalidate()
            self.markerLevel = self.editor.level
        self.markerList.call(self._drawToolMarkers)

    def _drawToolMarkers(self):
        GL.glColor(1.0, 1.0, 1.0, 0.5)

        GL.glEnable(GL.GL_DEPTH_TEST)
        GL.glMatrixMode(GL.GL_MODELVIEW)
        for player in self.editor.level.players:
            try:
                pos = self.editor.level.getPlayerPosition(player)
                yaw, pitch = self.editor.level.getPlayerOrientation(player)
                dim = self.editor.level.getPlayerDimension(player)

                self.inOtherDimension[dim].append(player)
                self.playerPos[dim][pos] = player
                self.revPlayerPos[dim][player] = pos

                if player != "Player" and config.settings.downloadPlayerSkins.get(
                ):
                    #                     print 7
                    r = self.playercache.getPlayerSkin(player,
                                                       force_download=False)
                    if not isinstance(r, (str, unicode)):
                        r = r.join()
                    self.playerTexture[player] = loadPNGTexture(r)
                else:
                    self.playerTexture[player] = self.charTex

                if dim != self.editor.level.dimNo:
                    continue

                x, y, z = pos
                GL.glPushMatrix()
                GL.glTranslate(x, y, z)
                GL.glRotate(-yaw, 0, 1, 0)
                GL.glRotate(pitch, 1, 0, 0)
                GL.glColor(1, 1, 1, 1)
                self.drawCharacterHead(0, 0, 0, (x, y, z),
                                       self.editor.level.dimNo)
                GL.glPopMatrix()
                # GL.glEnable(GL.GL_BLEND)
                drawTerrainCuttingWire(
                    FloatBox((x - .5, y - .5, z - .5), (1, 1, 1)),
                    c0=(0.3, 0.9, 0.7, 1.0),
                    c1=(0, 0, 0, 0),
                )

                #GL.glDisable(GL.GL_BLEND)

            except Exception, e:
                print "Exception in editortools.player.PlayerPositionTool._drawToolMarkers:", repr(
                    e)
                import traceback
                print traceback.format_exc()
                continue

        GL.glDisable(GL.GL_DEPTH_TEST)
예제 #5
0
class PlayerPositionTool(EditorTool):
    surfaceBuild = True
    toolIconName = "player"
    tooltipText = "Players"
    movingPlayer = None
    recordMove = True

    def reloadTextures(self):
        self.charTex = loadPNGTexture('char.png')

    @alertException
    def addPlayer(self):
        op = PlayerAddOperation(self)

        self.editor.addOperation(op)
        if op.canUndo:
            self.editor.addUnsavedEdit()

    @alertException
    def removePlayer(self):
        player = self.panel.selectedPlayer

        if player != "[No players]":
            op = PlayerRemoveOperation(self, player)

            self.editor.addOperation(op)
            if op.canUndo:
                self.editor.addUnsavedEdit()

    @alertException
    def movePlayer(self):
        if self.panel.selectedPlayer != "[No players]":
            self.movingPlayer = self.panel.selectedPlayer
            if self.movingPlayer == "Player (Single Player)":
                self.movingPlayer = "Player"

    @alertException
    def movePlayerToCamera(self):
        player = self.panel.selectedPlayer
        if player == "Player (Single Player)":
            player = "Player"
        if player != "[No players]":
            pos = self.editor.mainViewport.cameraPosition
            y = self.editor.mainViewport.yaw
            p = self.editor.mainViewport.pitch

            op = PlayerMoveOperation(self, pos, player, (y, p))
            self.movingPlayer = None
            self.editor.addOperation(op)
            if op.canUndo:
                self.editor.addUnsavedEdit()

    def delete_skin(self, uuid):
        del self.playerTexture[uuid]
        self.playerTexture[uuid] = self.charTex

    @alertException
    def reloadSkins(self):
        # result = ask("This pulls skins from the online server, so this may take a while", ["Ok", "Cancel"])
        # if result == "Ok":
        try:
            for player in self.editor.level.players:
                if player != "Player" and player in list(self.playerTexture.keys()):
                    del self.playerTexture[player]
                    #                     print 6
                    r = self.playercache.getPlayerSkin(player, force_download=True, instance=self)
                    if isinstance(r, str):
                        r = r.join()
                    self.playerTexture[player] = loadPNGTexture(r)
            # self.markerList.call(self._drawToolMarkers)
        except:
            raise Exception("Could not connect to the skins server, please check your Internet connection and try again.")

    def gotoPlayerCamera(self):
        player = self.panel.selectedPlayer
        if player == "Player (Single Player)":
            player = "Player"

        try:
            pos = self.editor.level.getPlayerPosition(player)
            y, p = self.editor.level.getPlayerOrientation(player)
            self.editor.gotoDimension(self.editor.level.getPlayerDimension(player))

            self.editor.mainViewport.cameraPosition = pos
            self.editor.mainViewport.yaw = y
            self.editor.mainViewport.pitch = p
            self.editor.mainViewport.stopMoving()
            self.editor.mainViewport.invalidate()
        except pymclevel.PlayerNotFound:
            pass

    def gotoPlayer(self):
        player = self.panel.selectedPlayer
        if player == "Player (Single Player)":
            player = "Player"

        try:
            if self.editor.mainViewport.pitch < 0:
                self.editor.mainViewport.pitch = -self.editor.mainViewport.pitch
                self.editor.mainViewport.cameraVector = self.editor.mainViewport._cameraVector()
            cv = self.editor.mainViewport.cameraVector

            pos = self.editor.level.getPlayerPosition(player)
            pos = list(map(lambda p, c: p - c * 5, pos, cv))
            self.editor.gotoDimension(self.editor.level.getPlayerDimension(player))

            self.editor.mainViewport.cameraPosition = pos
            self.editor.mainViewport.stopMoving()
        except pymclevel.PlayerNotFound:
            pass

    def __init__(self, *args):
        EditorTool.__init__(self, *args)
        self.reloadTextures()
        self.nonSavedPlayers = []

        textureVerticesHead = numpy.array(
            (
                # Backside of Head
                24, 16,  # Bottom Left
                24, 8,  # Top Left
                32, 8,  # Top Right
                32, 16,  # Bottom Right

                # Front of Head
                8, 16,
                8, 8,
                16, 8,
                16, 16,

                #
                24, 0,
                16, 0,
                16, 8,
                24, 8,

                #
                16, 0,
                8, 0,
                8, 8,
                16, 8,

                #
                8, 8,
                0, 8,
                0, 16,
                8, 16,

                16, 16,
                24, 16,
                24, 8,
                16, 8,

            ), dtype='f4')

        textureVerticesHat = numpy.array(
            (
                56, 16,
                56, 8,
                64, 8,
                64, 16,

                48, 16,
                48, 8,
                40, 8,
                40, 16,

                56, 0,
                48, 0,
                48, 8,
                56, 8,

                48, 0,
                40, 0,
                40, 8,
                48, 8,

                40, 8,
                32, 8,
                32, 16,
                40, 16,

                48, 16,
                56, 16,
                56, 8,
                48, 8,

            ), dtype='f4')

        textureVerticesHead.shape = (24, 2)
        textureVerticesHat.shape = (24, 2)

        textureVerticesHead *= 4
        textureVerticesHead[:, 1] *= 2

        textureVerticesHat *= 4
        textureVerticesHat[:, 1] *= 2

        self.texVerts = (textureVerticesHead, textureVerticesHat)

        self.playerPos = {0: {}, -1: {}, 1: {}}
        self.playerTexture = {}
        self.revPlayerPos = {0: {}, -1: {}, 1: {}}
        self.inOtherDimension = {0: [], 1: [], -1: []}
        self.playercache = PlayerCache()

        self.markerList = DisplayList()

    panel = None

    def showPanel(self):
        if not self.panel:
            self.panel = PlayerPositionPanel(self)

        self.panel.centery = (self.editor.mainViewport.height - self.editor.toolbar.height) / 2 + self.editor.subwidgets[0].height
        self.panel.left = self.editor.left

        self.editor.add(self.panel)

    def hidePanel(self):
        if self.panel and self.panel.parent:
            self.panel.parent.remove(self.panel)
        self.panel = None

    def drawToolReticle(self):
        if self.movingPlayer is None:
            return

        pos, direction = self.editor.blockFaceUnderCursor
        dim = self.editor.level.getPlayerDimension(self.movingPlayer)
        pos = (pos[0], pos[1] + 2, pos[2])

        x, y, z = pos

        # x,y,z=map(lambda p,d: p+d, pos, direction)
        GL.glEnable(GL.GL_BLEND)
        GL.glColor(1.0, 1.0, 1.0, 0.5)
        self.drawCharacterHead(x + 0.5, y + 0.75, z + 0.5, self.revPlayerPos[dim][self.movingPlayer], dim)
        GL.glDisable(GL.GL_BLEND)

        GL.glEnable(GL.GL_DEPTH_TEST)
        self.drawCharacterHead(x + 0.5, y + 0.75, z + 0.5, self.revPlayerPos[dim][self.movingPlayer], dim)
        drawTerrainCuttingWire(BoundingBox((x, y, z), (1, 1, 1)))
        drawTerrainCuttingWire(BoundingBox((x, y - 1, z), (1, 1, 1)))
        # drawTerrainCuttingWire( BoundingBox((x,y-2,z), (1,1,1)) )
        GL.glDisable(GL.GL_DEPTH_TEST)

    markerLevel = None

    def drawToolMarkers(self):
        if not config.settings.drawPlayerHeads.get():
            return
        if self.markerLevel != self.editor.level:
            self.markerList.invalidate()
            self.markerLevel = self.editor.level
        self.markerList.call(self._drawToolMarkers)

    def _drawToolMarkers(self):
        GL.glColor(1.0, 1.0, 1.0, 0.5)

        GL.glEnable(GL.GL_DEPTH_TEST)
        GL.glMatrixMode(GL.GL_MODELVIEW)
        for player in self.editor.level.players:
            try:
                pos = self.editor.level.getPlayerPosition(player)
                yaw, pitch = self.editor.level.getPlayerOrientation(player)
                dim = self.editor.level.getPlayerDimension(player)

                self.inOtherDimension[dim].append(player)
                self.playerPos[dim][pos] = player
                self.revPlayerPos[dim][player] = pos

                if player != "Player" and config.settings.downloadPlayerSkins.get():
                    #                     print 7
                    r = self.playercache.getPlayerSkin(player, force_download=False)
                    if not isinstance(r, str):
                        r = r.join()
                    self.playerTexture[player] = loadPNGTexture(r)
                else:
                    self.playerTexture[player] = self.charTex

                if dim != self.editor.level.dimNo:
                    continue

                x, y, z = pos
                GL.glPushMatrix()
                GL.glTranslate(x, y, z)
                GL.glRotate(-yaw, 0, 1, 0)
                GL.glRotate(pitch, 1, 0, 0)
                GL.glColor(1, 1, 1, 1)
                self.drawCharacterHead(0, 0, 0, (x, y, z), self.editor.level.dimNo)
                GL.glPopMatrix()
                # GL.glEnable(GL.GL_BLEND)
                drawTerrainCuttingWire(FloatBox((x - .5, y - .5, z - .5), (1, 1, 1)),
                                       c0=(0.3, 0.9, 0.7, 1.0),
                                       c1=(0, 0, 0, 0),
                                       )

                # GL.glDisable(GL.GL_BLEND)

            except Exception as e:
                print("Exception in editortools.player.PlayerPositionTool._drawToolMarkers:", repr(e))
                import traceback
                print(traceback.format_exc())
                continue

        GL.glDisable(GL.GL_DEPTH_TEST)

    def drawCharacterHead(self, x, y, z, realCoords=None, dim=0):
        GL.glEnable(GL.GL_CULL_FACE)
        origin = (x - 0.25, y - 0.25, z - 0.25)
        size = (0.5, 0.5, 0.5)
        box = FloatBox(origin, size)

        hat_origin = (x - 0.275, y - 0.275, z - 0.275)
        hat_size = (0.55, 0.55, 0.55)
        hat_box = FloatBox(hat_origin, hat_size)

        if realCoords is not None and self.playerPos[dim][realCoords] != "Player" and config.settings.downloadPlayerSkins.get():
            drawCube(box,
                     texture=self.playerTexture[self.playerPos[dim][realCoords]], textureVertices=self.texVerts[0])
            GL.glEnable(GL.GL_BLEND)
            GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)
            drawCube(hat_box,
                     texture=self.playerTexture[self.playerPos[dim][realCoords]], textureVertices=self.texVerts[1])
            GL.glDisable(GL.GL_BLEND)
        else:
            drawCube(box,
                     texture=self.charTex, textureVertices=self.texVerts[0])
        GL.glDisable(GL.GL_CULL_FACE)

    # @property
    # def statusText(self):
    #    if not self.panel:
    #        return ""
    #    player = self.panel.selectedPlayer
    #    if player == "Player":
    #        return "Click to move the player"
    #
    #    return _("Click to move the player \"{0}\"").format(player)

    @alertException
    def mouseDown(self, evt, pos, direction):
        if self.movingPlayer is None:
            return

        pos = (pos[0] + 0.5, pos[1] + 2.75, pos[2] + 0.5)

        op = PlayerMoveOperation(self, pos, self.movingPlayer)
        self.movingPlayer = None

        if self.recordMove:
            self.editor.addOperation(op)
            addingMoving = False
        else:
            self.editor.performWithRetry(op)  # Prevent recording of Undo when adding player
            self.recordMove = True
            addingMoving = True
        if op.canUndo and not addingMoving:
            self.editor.addUnsavedEdit()

    def keyDown(self, evt):
        keyname = evt.dict.get('keyname', None) or self.editor.get_root().getKey(evt)
        if not self.recordMove:
            if not pygame.key.get_focused():
                return

            if keyname == "Escape":
                self.recordMove = True
        if self.panel and self.panel.__class__ == PlayerPositionPanel:
            self.panel.key_down(evt)

    def keyUp(self, evt):
        pass

    def levelChanged(self):
        self.markerList.invalidate()

    @alertException
    def toolSelected(self):
        self.showPanel()
        self.movingPlayer = None

    @alertException
    def toolReselected(self):
        if self.panel:
            self.gotoPlayer()