# ----------------------------
# 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()