Загрузка данных


import pygame
import sys
import random
import math

pygame.init()

# =========================
# BASIC SETTINGS
# =========================
WIDTH, HEIGHT = 1280, 720
TILE = 32
FPS = 60

screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Terrablock")
clock = pygame.time.Clock()

FONT = pygame.font.SysFont("Arial", 20)
BIG = pygame.font.SysFont("Arial", 44)
SMALL = pygame.font.SysFont("Arial", 16)

# =========================
# COLORS
# =========================
C = {
    "menu": (20, 20, 30),
    "panel": (35, 35, 50),
    "white": (255, 255, 255),
    "black": (0, 0, 0),
    "red": (220, 70, 70),
    "green": (80, 220, 120),
    "blue": (70, 120, 230),
    "yellow": (240, 220, 80),
    "grass": (80, 200, 120),
    "dirt": (139, 92, 52),
    "stone": (130, 130, 130),
    "wood": (120, 75, 35),
    "leaves": (40, 160, 70),
    "sand": (220, 210, 130),
    "netherrack": (140, 40, 40),
    "lava": (255, 90, 20),
    "endstone": (210, 210, 160),
    "portal": (120, 0, 255),
    "city": (180, 180, 220),
    "bedrock": (30, 30, 30),
    "village": (200, 170, 120),
    "spawner": (100, 0, 120),
    "trial": (70, 120, 180),
    "dragon_egg": (50, 0, 60),
    "player": (50, 100, 220),
    "hair": (60, 40, 20),
    "skin": (240, 200, 170),
    "shirt": (50, 120, 220),
    "pants": (70, 70, 150),
}

BLOCK_COLORS = {
    "grass": C["grass"], "dirt": C["dirt"], "stone": C["stone"], "wood": C["wood"],
    "leaves": C["leaves"], "sand": C["sand"], "netherrack": C["netherrack"],
    "lava": C["lava"], "endstone": C["endstone"], "portal": C["portal"],
    "city": C["city"], "bedrock": C["bedrock"], "village": C["village"],
    "spawner": C["spawner"], "trial": C["trial"], "dragon_egg": C["dragon_egg"]
}

# =========================
# GAME STATE
# =========================
class State:
    def __init__(self):
        self.mode = "menu"  # menu, play, skin, command, dead
        self.difficulty = "normal"
        self.menu_index = 0
        self.command_text = ""
        self.message = ""
        self.message_timer = 0

state = State()

# =========================
# INVENTORY
# =========================
class Inventory:
    def __init__(self):
        self.hotbar = [
            "wood_pickaxe", "wood_axe", "wood_shovel", "wood_hoe",
            "wood_spear", "wood_sword", "stone_pickaxe", "block_grass", "block_stone"
        ]
        self.selected = 0
        self.items = {
            "block_grass": 64,
            "block_dirt": 64,
            "block_stone": 64,
            "wood": 50,
            "iron_ingot": 20,
            "diamond": 10,
            "netherite_ingot": 5,
            "dragon_egg": 1,
            "spawner_item": 2,
            "trial_key": 2,
            "mace": 1,
            "spear": 1,
            "leather_helmet": 1, "leather_chest": 1, "leather_legs": 1, "leather_boots": 1,
            "iron_helmet": 1, "iron_chest": 1, "iron_legs": 1, "iron_boots": 1,
            "diamond_helmet": 1, "diamond_chest": 1, "diamond_legs": 1, "diamond_boots": 1,
            "netherite_helmet": 1, "netherite_chest": 1, "netherite_legs": 1, "netherite_boots": 1,
        }

    def add(self, item, n=1):
        self.items[item] = self.items.get(item, 0) + n

    def remove(self, item, n=1):
        if self.items.get(item, 0) >= n:
            self.items[item] -= n
            if self.items[item] <= 0:
                self.items.pop(item, None)
            return True
        return False

# =========================
# PLAYER
# =========================
ARMOR_DEF = {"leather": 1, "iron": 3, "diamond": 4, "netherite": 5}
SWORD_POWER = {"wood": 2, "stone": 3, "iron": 4, "diamond": 5, "netherite": 7}
TOOL_POWER = {"wood": 1, "stone": 2, "iron": 3, "diamond": 4, "netherite": 5}

class Player:
    def __init__(self, x, y):
        self.rect = pygame.Rect(x * TILE, y * TILE, 24, 30)
        self.vel_y = 0
        self.speed = 4
        self.jump_power = -11
        self.on_ground = False
        self.max_hp = 20
        self.hp = 20
        self.invuln = 0
        self.dead = False
        self.hunger = 20
        self.armor = {"helmet": None, "chest": None, "legs": None, "boots": None}
        self.skin = {"hair": C["hair"], "skin": C["skin"], "shirt": C["shirt"], "pants": C["pants"]}

    def armor_points(self):
        pts = 0
        for item in self.armor.values():
            if item:
                tier = item.split("_")[0]
                pts += ARMOR_DEF.get(tier, 0)
        return pts

    def equip_armor(self, item):
        if item.endswith("_helmet"):
            self.armor["helmet"] = item
        elif item.endswith("_chest"):
            self.armor["chest"] = item
        elif item.endswith("_legs"):
            self.armor["legs"] = item
        elif item.endswith("_boots"):
            self.armor["boots"] = item

    def take_damage(self, dmg):
        if self.invuln > 0:
            return
        reduced = max(1, dmg - self.armor_points() // 2)
        self.hp -= reduced
        self.invuln = 45
        if self.hp <= 0:
            self.dead = True

# =========================
# ENTITIES
# =========================
class Mob:
    def __init__(self, x, y, kind="zombie"):
        self.kind = kind
        self.rect = pygame.Rect(x * TILE, y * TILE, 24, 28)
        self.vel_y = 0
        self.hp = 10 if kind == "zombie" else 18
        self.speed = 1 if kind == "zombie" else 2

    def update(self, world, player):
        dx = 0
        if player.rect.centerx < self.rect.centerx:
            dx = -self.speed
        elif player.rect.centerx > self.rect.centerx:
            dx = self.speed

        self.rect.x += dx
        for (bx, by), block in world.blocks.items():
            br = pygame.Rect(bx * TILE, by * TILE, TILE, TILE)
            if self.rect.colliderect(br):
                if dx > 0:
                    self.rect.right = br.left
                elif dx < 0:
                    self.rect.left = br.right

        self.vel_y += 0.5
        self.rect.y += int(self.vel_y)
        for (bx, by), block in world.blocks.items():
            br = pygame.Rect(bx * TILE, by * TILE, TILE, TILE)
            if self.rect.colliderect(br):
                if self.vel_y > 0:
                    self.rect.bottom = br.top
                    self.vel_y = 0

        if self.rect.colliderect(player.rect):
            player.take_damage(1 if self.kind == "zombie" else 2)

class World:
    def __init__(