Exemple #1
0
    def build(self, container):
        """
        Handle a build packet.

        Several things must happen. First, the packet's contents need to be
        examined to ensure that the packet is valid. A check is done to see if
        the packet is opening a windowed object. If not, then a build is
        run.
        """

        # Is the target within our purview? We don't do a very strict
        # containment check, but we *do* require that the chunk be loaded.
        bigx, smallx, bigz, smallz = split_coords(container.x, container.z)
        try:
            chunk = self.chunks[bigx, bigz]
        except KeyError:
            self.error("Couldn't select in chunk (%d, %d)!" % (bigx, bigz))
            return

        target = blocks[chunk.get_block((smallx, container.y, smallz))]

        # If it's a chest, hax.
        if target.name == "chest":
            from bravo.policy.windows import Chest
            w = Chest()
            self.windows[self.wid] = w

            w.open()
            self.write_packet("window-open", wid=self.wid, type=w.identifier,
                              title=w.title, slots=w.slots)

            self.wid += 1
            return
        elif target.name == "workbench":
            from bravo.policy.windows import Workbench
            w = Workbench()
            self.windows[self.wid] = w

            w.open()
            self.write_packet("window-open", wid=self.wid, type=w.identifier,
                              title=w.title, slots=w.slots)

            self.wid += 1
            return

        # Try to open it first
        for hook in self.open_hooks:
            window = yield maybeDeferred(hook.open_hook, self, container,
                           chunk.get_block((smallx, container.y, smallz)))
            if window:
                self.write_packet("window-open", wid=window.wid,
                    type=window.identifier, title=window.title,
                    slots=window.slots_num)
                packet = window.save_to_packet()
                self.transport.write(packet)
                # window opened
                return

        # Ignore clients that think -1 is placeable.
        if container.primary == -1:
            return

        # Special case when face is "noop": Update the status of the currently
        # held block rather than placing a new block.
        if container.face == "noop":
            return

        # If the target block is vanishable, then adjust our aim accordingly.
        if target.vanishes:
            container.face = "+y"
            container.y -= 1

        if container.primary in blocks:
            block = blocks[container.primary]
        elif container.primary in items:
            block = items[container.primary]
        else:
            log.err("Ignoring request to place unknown block %d" %
                container.primary)
            return

        # Run pre-build hooks. These hooks are able to interrupt the build
        # process.
        builddata = BuildData(block, 0x0, container.x, container.y,
            container.z, container.face)

        for hook in self.pre_build_hooks:
            cont, builddata, cancel = yield maybeDeferred(hook.pre_build_hook,
                self.player, builddata)
            if cancel:
                # Flush damaged chunks.
                for chunk in self.chunks.itervalues():
                    self.factory.flush_chunk(chunk)
                return
            if not cont:
                break

        # Run the build.
        try:
            yield maybeDeferred(self.run_build, builddata)
        except BuildError:
            return

        newblock = builddata.block.slot
        coords = adjust_coords_for_face(
            (builddata.x, builddata.y, builddata.z), builddata.face)

        # Run post-build hooks. These are merely callbacks which cannot
        # interfere with the build process, largely because the build process
        # already happened.
        for hook in self.post_build_hooks:
            yield maybeDeferred(hook.post_build_hook, self.player, coords,
                builddata.block)

        # Feed automatons.
        for automaton in self.factory.automatons:
            if newblock in automaton.blocks:
                automaton.feed(coords)

        # Re-send inventory.
        # XXX this could be optimized if/when inventories track damage.
        packet = self.inventory.save_to_packet()
        self.transport.write(packet)

        # Flush damaged chunks.
        for chunk in self.chunks.itervalues():
            self.factory.flush_chunk(chunk)
Exemple #2
0
 def test_verify_object(self):
     c = Chest()
     verifyObject(IWindow, c)
Exemple #3
0
 def test_damage_single(self):
     c = Chest()
     c.altered(17, None, None)
     self.assertTrue(17 in c.damaged())
Exemple #4
0
 def test_damage_single(self):
     c = Chest()
     c.altered(17, None, None)
     self.assertTrue(17 in c.damaged())