# ----------------------------
    # VILLAGER TRADING INTERFACE
    # ----------------------------
    def open_villager_trade(self, villager):
        """
        Opens a simple trade window for the given Villager instance.
        villager.trades is a dict {offer_item: cost_in_emeralds}
        """
        w = tk.Toplevel(self.root)
        w.title(f"Trade with {villager.prof.title()}")
        ttk.Label(w, text=f"Villager ({villager.prof}) Trades:", font=("Arial",12)).pack(pady=5)
        for offer, cost in villager.trades.items():
            btn = ttk.Button(
                w,
                text=f"{offer} for {cost} Emerald(s)",
                command=lambda o=offer, c=cost: self._execute_trade(villager, o, c, w)
            )
            btn.pack(fill=tk.X, padx=10, pady=2)
        ttk.Button(w, text="Close", command=w.destroy).pack(pady=5)

    def _execute_trade(self, villager, offer, cost, window):
        """
        Performs the trade if player has enough emeralds.
        """
        inv = self.player.inventory
        if inv.get("EMERALD", 0) >= cost:
            inv["EMERALD"] -= cost
            inv[offer] = inv.get(offer, 0) + 1
            self.status.set(f"Traded {cost} Emeralds for 1 {offer}")
        else:
            self.status.set("Not enough Emeralds")
        window.destroy()
        self.draw()

    # ----------------------------
    # REDSTONE & PISTON LOGIC
    # ----------------------------
    def place_redstone(self, x, y):
        if self.player.inventory.get("REDSTONE_DUST",0) > 0 and self.world[y][x] == "AIR":
            self.world[y][x] = "REDSTONE_DUST"
            self.player.inventory["REDSTONE_DUST"] -= 1

    def update_redstone(self):
        """
        Simplified power propagation: any dust next to a powered block becomes powered.
        """
        # (Implementation placeholder — extend as needed)
        pass

    def place_piston(self, x, y, sticky=False):
        if sticky and self.player.inventory.get("STICKY_PISTON",0) > 0:
            self.world[y][x] = "STICKY_PISTON"
            self.player.inventory["STICKY_PISTON"] -= 1
        elif self.player.inventory.get("PISTON",0) > 0:
            self.world[y][x] = "PISTON"
            self.player.inventory["PISTON"] -= 1

    # ----------------------------
    # MINECART & RAILS
    # ----------------------------
    def place_rail(self, x, y):
        if self.player.inventory.get("RAIL",0) > 0 and self.world[y][x] == "AIR":
            self.world[y][x] = "RAIL"
            self.player.inventory["RAIL"] -= 1

    def spawn_minecart(self):
        """
        Place a minecart at player position if rails are present.
        """
        px, py = self.player.x, self.player.y
        if self.world[py][px] == "RAIL":
            self.carts.append(Minecart(px, py))

    # ----------------------------
    # SAVE & LOAD (EXTENDED)
    # ----------------------------
    def save_game(self, event=None):
        data = {
            "player": self.player,
            "worlds": self.worlds,
            "dimension": self.dim,
            "spawners": self.spawners,
            "animals": self.animals,
            "villagers": self.villagers,
            "carts": self.carts
        }
        with open("savegame.dat", "wb") as f:
            pickle.dump(data, f)
        self.status.set("Game saved!")

    def load_game(self, event=None):
        try:
            with open("savegame.dat", "rb") as f:
                data = pickle.load(f)
            self.player    = data["player"]
            self.worlds    = data["worlds"]
            self.dim       = data["dimension"]
            self.world     = self.worlds[self.dim]
            self.spawners  = data["spawners"]
            self.animals   = data["animals"]
            self.villagers = data["villagers"]
            self.carts     = data["carts"]
            self.status.set("Game loaded!")
            self.draw()
        except Exception:
            self.status.set("Failed to load!")

    # ----------------------------
    # MAIN LOOP CONTINUED
    # ----------------------------
    def loop(self):
        # handle world events
        now = time.time() - START_T
        for t, ev in list(self.events):
            if now >= t:
                self._trigger_event(ev)
                self.events.remove((t, ev))

        # update redstone (if you’ve built circuits)
        self.update_redstone()

        # move minecarts
        for cart in self.carts:
            cart.move(self.world)

        # mob & animal logic
        for (sx, sy, kind) in self.spawners:
            if random.random() < 0.02:
                self.mobs.append(Mob(sx, sy, kind))

        # update mobs
        for m in list(self.mobs):
            dx = 1 if m.x < self.player.x else -1 if m.x > self.player.x else 0
            dy = 1 if m.y < self.player.y else -1 if m.y > self.player.y else 0
            if self.world[m.y][m.x] == "AIR":
                m.x += dx; m.y += dy
            # attack player
            if abs(m.x - self.player.x) <= 1 and abs(m.y - self.player.y) <= 1:
                damage = 5 if m.k == "wither" else 2
                self.player.health -= damage
                if self.player.health <= 0:
                    return self._game_over()

        # animal breeding cooldown
        for a in self.animals:
            a.age = max(0, a.age - 1)

        self.draw()
        self.root.after(200, self.loop)

    # ----------------------------
    # WORLD EVENT HANDLER
    # ----------------------------
    def _trigger_event(self, ev):
        if ev == "Blood Moon":
            self.status.set("Blood Moon! Mobs are stronger!")
            # e.g. double spawn rates
        elif ev == "Harvest Festival":
            self.status.set("Harvest Festival: free crops in villages!")
            # e.g. give players some wheat in village biomes

    # ----------------------------
    # GAME OVER & CLEANUP
    # ----------------------------
    def _game_over(self):
        self.canvas.delete("all")
        self.canvas.create_text(
            VIEW_W*CELL//2, VIEW_H*CELL//2,
            text="GAME OVER", fill="red", font=("Arial",32)
        )
        self.status.set("You died!")
        if self.player.hardcore:
            try: os.remove("savegame.dat")
            except: pass

# -----------------------------------------------------------------------------
# LAUNCHER
# -----------------------------------------------------------------------------
if __name__ == "__main__":
    root = tk.Tk()
    Game(root)
    root.mainloop()