Exemplo n.º 1
0
    def pre_build_hook(self, player, builddata):
        item, metadata, x, y, z, face = builddata

        if item.slot != blocks["chest"].slot:
            returnValue((True, builddata, False))

        x, y, z = adjust_coords_for_face((x, y, z), face)
        bigx, smallx, bigz, smallz = split_coords(x, z)

        # chest orientation according to players position
        if face == "-y" or face == "+y":
            orientation = ('+x', '+z', '-x', '-z')[((int(player.location.yaw) \
                                                - 45 + 360) % 360) / 90]
        else:
            orientation = face

        # Chests have some restrictions on building:
        # you cannot connect more than two chests. (notchian)
        ccs = chestsAround(self.factory, (x, y, z))
        ccn = len(ccs)
        if ccn > 1:
            # cannot build three or more connected chests
            returnValue((False, builddata, True))

        chunk = yield self.factory.world.request_chunk(bigx, bigz)

        if ccn == 0:
            metadata = blocks["chest"].orientation(orientation)
        elif ccn == 1:
            # check gonna-be-connected chest is not connected already
            n = len(chestsAround(self.factory, ccs[0]))
            if n != 0:
                returnValue((False, builddata, True))

            # align both blocks correctly (since 1.8)
            # get second block
            x2, y2, z2 = ccs[0]
            bigx2, smallx2, bigz2, smallz2 = split_coords(x2, z2)
            # new chests orientation axis according to blocks position
            pair = x - x2, z - z2
            ornt = {(0, 1): "x", (0, -1): "x", (1, 0): "z", (-1, 0): "z"}[pair]
            # if player is faced another direction, fix it
            if orientation[1] != ornt:
                # same sign with proper orientation
                # XXX Probably notchian logic is different here
                #     but this one works well enough
                orientation = orientation[0] + ornt
            metadata = blocks["chest"].orientation(orientation)
            # update second block's metadata
            if bigx == bigx2 and bigz == bigz2:
                # both blocks are in same chunk
                chunk2 = chunk
            else:
                chunk2 = yield self.factory.world.request_chunk(bigx2, bigz2)
            chunk2.set_metadata((smallx2, y2, smallz2), metadata)

        # Not much to do, just tell the chunk about this tile.
        chunk.tiles[smallx, y, smallz] = ChestTile(smallx, y, smallz)
        builddata = builddata._replace(metadata=metadata)
        returnValue((True, builddata, False))
Exemplo n.º 2
0
    def open_hook(self, player, container, block):
        """
        The ``player`` is a Player's protocol
        The ``container`` is a 0x64 message
        The ``block`` is a block we trying to open
        :returns: None or window object
        """
        if block != blocks["chest"].slot:
            returnValue(None)

        bigx, smallx, bigz, smallz = split_coords(container.x, container.z)
        chunk = yield self.factory.world.request_chunk(bigx, bigz)

        chests_around = chestsAround(self.factory,
                                     (container.x, container.y, container.z))
        chests_around_num = len(chests_around)

        if chests_around_num == 0:  # small chest
            chest = self.get_chest_tile(chunk, (smallx, container.y, smallz))
            if chest is None:
                returnValue(None)
            coords = bigx, smallx, bigz, smallz, container.y
            window = ChestWindow(player.wid, player.player.inventory,
                                 chest.inventory, coords)
        elif chests_around_num == 1:  # large chest
            # process second chest coordinates
            x2, y2, z2 = chests_around[0]
            bigx2, smallx2, bigz2, smallz2 = split_coords(x2, z2)
            if bigx == bigx2 and bigz == bigz2:
                # both chest blocks are in same chunk
                chunk2 = chunk
            else:
                chunk2 = yield self.factory.world.request_chunk(bigx2, bigz2)

            chest1 = self.get_chest_tile(chunk, (smallx, container.y, smallz))
            chest2 = self.get_chest_tile(chunk2,
                                         (smallx2, container.y, smallz2))
            if chest1 is None or chest2 is None:
                returnValue(None)
            c1 = bigx, smallx, bigz, smallz, container.y
            c2 = bigx2, smallx2, bigz2, smallz2, container.y
            # We shall properly order chest inventories
            if c1 < c2:
                window = LargeChestWindow(player.wid, player.player.inventory,
                                          chest1.inventory, chest2.inventory,
                                          c1)
            else:
                window = LargeChestWindow(player.wid, player.player.inventory,
                                          chest2.inventory, chest1.inventory,
                                          c2)
        else:
            log.msg("Chest at (%d, %d, %d) have three chests connected" %
                    (container.x, container.y, container.z))
            returnValue(None)

        player.windows.append(window)
        returnValue(window)
Exemplo n.º 3
0
    def open_hook(self, player, container, block):
        """
        The ``player`` is a Player's protocol
        The ``container`` is a 0x64 message
        The ``block`` is a block we trying to open
        :returns: None or window object
        """
        if block != blocks["chest"].slot:
            returnValue(None)

        bigx, smallx, bigz, smallz = split_coords(container.x, container.z)
        chunk = yield self.factory.world.request_chunk(bigx, bigz)

        chests_around = chestsAround(self.factory,
                (container.x, container.y, container.z))
        chests_around_num = len(chests_around)

        if chests_around_num == 0: # small chest
            chest = self.get_chest_tile(chunk, (smallx, container.y, smallz))
            if chest is None:
                returnValue(None)
            coords = bigx, smallx, bigz, smallz, container.y
            window = ChestWindow(player.wid, player.player.inventory,
                                 chest.inventory, coords)
        elif chests_around_num == 1: # large chest
            # process second chest coordinates
            x2, y2, z2 = chests_around[0]
            bigx2, smallx2, bigz2, smallz2 = split_coords(x2, z2)
            if bigx == bigx2 and bigz == bigz2:
                # both chest blocks are in same chunk
                chunk2 = chunk
            else:
                chunk2 = yield self.factory.world.request_chunk(bigx2, bigz2)

            chest1 = self.get_chest_tile(chunk, (smallx, container.y, smallz))
            chest2 = self.get_chest_tile(chunk2, (smallx2, container.y, smallz2))
            if chest1 is None or chest2 is None:
                returnValue(None)
            c1 = bigx, smallx, bigz, smallz, container.y
            c2 = bigx2, smallx2, bigz2, smallz2, container.y
            # We shall properly order chest inventories
            if c1 < c2:
                window = LargeChestWindow(player.wid, player.player.inventory,
                        chest1.inventory, chest2.inventory, c1)
            else:
                window = LargeChestWindow(player.wid, player.player.inventory,
                        chest2.inventory, chest1.inventory, c2)
        else:
            log.msg("Chest at (%d, %d, %d) have three chests connected" %
                    (container.x, container.y, container.z))
            returnValue(None)

        player.windows.append(window)
        returnValue(window)
Exemplo n.º 4
0
    def pre_build_hook(self, player, builddata):
        item, metadata, x, y, z, face = builddata

        if item.slot != blocks["chest"].slot:
            returnValue((True, builddata, False))

        x, y, z = adjust_coords_for_face((x, y, z), face)
        bigx, smallx, bigz, smallz = split_coords(x, z)

        # chest orientation according to players position
        if face == "-y" or face == "+y":
            orientation = ('+x', '+z', '-x', '-z')[((int(player.location.yaw) \
                                                - 45 + 360) % 360) / 90]
        else:
            orientation = face

        # Chests have some restrictions on building:
        # you cannot connect more than two chests. (notchian)
        ccs = chestsAround(self.factory, (x, y, z))
        ccn = len(ccs)
        if ccn > 1:
            # cannot build three or more connected chests
            returnValue((False, builddata, True))

        chunk = yield self.factory.world.request_chunk(bigx, bigz)

        if ccn == 0:
            metadata = blocks["chest"].orientation(orientation)
        elif ccn == 1:
            # check gonna-be-connected chest is not connected already
            n = len(chestsAround(self.factory, ccs[0]))
            if n != 0:
                returnValue((False, builddata, True))

            # align both blocks correctly (since 1.8)
            # get second block
            x2, y2, z2 = ccs[0]
            bigx2, smallx2, bigz2, smallz2 = split_coords(x2, z2)
            # new chests orientation axis according to blocks position
            pair = x - x2, z - z2
            ornt = {(0, 1): "x", (0, -1): "x",
                    (1, 0): "z", (-1, 0): "z"}[pair]
            # if player is faced another direction, fix it
            if orientation[1] != ornt:
                # same sign with proper orientation
                # XXX Probably notchian logic is different here
                #     but this one works well enough
                orientation = orientation[0] + ornt
            metadata = blocks["chest"].orientation(orientation)
            # update second block's metadata
            if bigx == bigx2 and bigz == bigz2:
                # both blocks are in same chunk
                chunk2 = chunk
            else:
                chunk2 = yield self.factory.world.request_chunk(bigx2, bigz2)
            chunk2.set_metadata((smallx2, y2, smallz2), metadata)

        # Not much to do, just tell the chunk about this tile.
        chunk.tiles[smallx, y, smallz] = ChestTile(smallx, y, smallz)
        builddata = builddata._replace(metadata=metadata)
        returnValue((True, builddata, False))
Exemplo n.º 5
0
    def pre_build_hook(self, player, builddata):
        item, metadata, x, y, z, face = builddata

        if item.slot == items["sign"].slot:
            # Buildin' a sign, puttin' it on a wall...
            builddata = builddata._replace(block=blocks["wall-sign"])

            # Offset coords according to face.
            if face == "-x":
                builddata = builddata._replace(metadata=0x4)
                x -= 1
            elif face == "+x":
                builddata = builddata._replace(metadata=0x5)
                x += 1
            elif face == "-y":
                # Ceiling Sign is watching you read.
                returnValue((False, builddata, False))
            elif face == "+y":
                # Put +Y signs on signposts. We're fancy that way. Also,
                # calculate the proper orientation based on player
                # orientation.
                # 180 degrees around to orient the signs correctly, and then
                # 23 degrees to get the sign to midpoint correctly.
                metadata = ((player.location.yaw + 180) * 16 // 360) % 0xf
                builddata = builddata._replace(block=blocks["signpost"],
                    metadata=metadata)
                y += 1
            elif face == "-z":
                builddata = builddata._replace(metadata=0x2)
                z -= 1
            elif face == "+z":
                builddata = builddata._replace(metadata=0x3)
                z += 1

            bigx, smallx, bigz, smallz = split_coords(x, z)

            # Let's build a sign!
            chunk = yield factory.world.request_chunk(bigx, bigz)
            s = Sign(smallx, y, smallz)
            chunk.tiles[smallx, y, smallz] = s

        elif item.slot in self.block_to_tile:
            x, y, z = adjust_coords_for_face((x, y, z), face)
            bigx, smallx, bigz, smallz = split_coords(x, z)

            if item.slot == blocks["chest"].slot:
                # Chests have some restrictions on building:
                # you cannot connect more than two chests.
                # (notchian)
                ccs = chestsAround(factory, (x, y, z))
                ccn = len(ccs)
                if ccn == 1:
                    # check gonna-be-connected chest is not connected already
                    n = len(chestsAround(factory, ccs[0]))
                    if n != 0:
                        returnValue((False, builddata, True))
                elif ccn > 1:
                    # cannot build three or more connected chests
                    returnValue((False, builddata, True))
            elif item.slot == blocks["furnace"].slot:
                # the furnace cannot be oriented up or down
                if face == "-y" or face == "+y":
                    orientation = ('+x', '+z', '-x', '-z')[((int(player.location.yaw) \
                                                        - 45 + 360) % 360) / 90]
                    metadata = blocks["furnace"].orientation(orientation)
                    builddata = builddata._replace(metadata=metadata)

            chunk = yield factory.world.request_chunk(bigx, bigz)

            # Not much to do, just tell the chunk about this tile.
            tileClass = self.block_to_tile[item.slot]
            tile = tileClass(smallx, y, smallz)
            chunk.tiles[smallx, y, smallz] = tile

        returnValue((True, builddata, False))