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


-- ═══════════════════════════════════════════════════════════
-- ЛАБОРАТОРИЯ ЧП — ПОЛНОСТЬЮ АВТОМАТИЧЕСКАЯ ВЕРСИЯ
-- Всё генерируется само, кроме R6 NPC из Toolbox
-- ═══════════════════════════════════════════════════════════

local C = {
    asphalt = Color3.fromRGB(90, 90, 95),
    asphalt_dark = Color3.fromRGB(70, 70, 75),
    grass = Color3.fromRGB(65, 130, 65),
    dirt = Color3.fromRGB(120, 100, 80),
    wall_white = Color3.fromRGB(230, 230, 235),
    wall_dirty = Color3.fromRGB(200, 200, 190),
    wall_grey = Color3.fromRGB(130, 130, 130),
    wall_concrete = Color3.fromRGB(160, 160, 160),
    roof_flat = Color3.fromRGB(45, 45, 50),
    roof_metal = Color3.fromRGB(60, 60, 70),
    door_metal = Color3.fromRGB(80, 60, 50),
    door_rust = Color3.fromRGB(100, 70, 50),
    window_glass = Color3.fromRGB(170, 220, 255),
    window_broken = Color3.fromRGB(100, 150, 180),
    fence_post = Color3.fromRGB(70, 70, 70),
    fence_chain = Color3.fromRGB(90, 90, 90),
    fence_rust = Color3.fromRGB(110, 80, 60),
    crate_wood = Color3.fromRGB(140, 90, 60),
    crate_metal = Color3.fromRGB(100, 100, 110),
    barrel_oil = Color3.fromRGB(50, 50, 55),
    barrel_fire = Color3.fromRGB(80, 50, 40),
    barrel_toxic = Color3.fromRGB(60, 100, 50),
    sign_warning = Color3.fromRGB(220, 180, 30),
    sign_danger = Color3.fromRGB(200, 50, 50),
    sign_bio = Color3.fromRGB(200, 50, 150),
    light_yellow = Color3.fromRGB(255, 240, 180),
    light_red = Color3.fromRGB(255, 80, 80),
    parasite_black = Color3.fromRGB(10, 10, 10),
    parasite_glow = Color3.fromRGB(255, 0, 50),
    blood = Color3.fromRGB(140, 30, 30),
    paper = Color3.fromRGB(240, 240, 230)
}

function part(name, size, pos, color, parent, transparency, material)
    local p = Instance.new("Part")
    p.Name = name
    p.Size = size
    p.CFrame = CFrame.new(pos)
    p.Color = color
    p.Material = material or Enum.Material.Plastic
    p.Anchored = true
    p.TopSurface = Enum.SurfaceType.Studs
    p.BottomSurface = Enum.SurfaceType.Inlet
    p.Transparency = transparency or 0
    p.Parent = parent
    return p
end

function wall(name, size, pos, color, parent)
    local w = part(name, size, pos, color, parent)
    w.TopSurface = Enum.SurfaceType.Smooth
    w.BottomSurface = Enum.SurfaceType.Smooth
    return w
end

-- ОЧИСТКА
for _, name in pairs({"Map", "NPCs", "Spawns", "GameLogic", "Effects", "Scripts", "RemoteEvents"}) do
    local old = workspace:FindFirstChild(name)
    if old then old:Destroy() end
    old = game.ReplicatedStorage:FindFirstChild(name)
    if old then old:Destroy() end
end

-- ПАПКИ
local map = Instance.new("Folder")
map.Name = "Map"
map.Parent = workspace

local npcs = Instance.new("Folder")
npcs.Name = "NPCs"
npcs.Parent = workspace

local spawns = Instance.new("Folder")
spawns.Name = "Spawns"
spawns.Parent = workspace

local gameLogic = Instance.new("Folder")
gameLogic.Name = "GameLogic"
gameLogic.Parent = workspace

local effects = Instance.new("Folder")
effects.Name = "Effects"
effects.Parent = workspace

local remoteEvents = Instance.new("Folder")
remoteEvents.Name = "RemoteEvents"
remoteEvents.Parent = game.ReplicatedStorage

-- Создаём RemoteEvents
local jumpEvent = Instance.new("RemoteEvent")
jumpEvent.Name = "JumpEvent"
jumpEvent.Parent = remoteEvents

local caughtEvent = Instance.new("RemoteEvent")
caughtEvent.Name = "CaughtEvent"
caughtEvent.Parent = remoteEvents

-- ═══════════════════════════════════════════════════════════
-- ОСВЕЩЕНИЕ (СУМЕРКИ, ТУМАН)
-- ═══════════════════════════════════════════════════════════

local lighting = game:GetService("Lighting")
lighting.Brightness = 0.4
lighting.ClockTime = 20
lighting.Ambient = Color3.fromRGB(60, 60, 80)
lighting.OutdoorAmbient = Color3.fromRGB(40, 50, 70)
lighting.FogColor = Color3.fromRGB(80, 90, 110)
lighting.FogStart = 50
lighting.FogEnd = 250

local atmosphere = Instance.new("Atmosphere")
atmosphere.Density = 0.4
atmosphere.Offset = 0.25
atmosphere.Color = Color3.fromRGB(120, 130, 150)
atmosphere.Decay = Color3.fromRGB(80, 90, 110)
atmosphere.Glare = 0.3
atmosphere.Haze = 0.5
atmosphere.Parent = lighting

-- ═══════════════════════════════════════════════════════════
-- ЗЕМЛЯ
-- ═══════════════════════════════════════════════════════════

part("GroundMain", Vector3.new(300, 2, 300), Vector3.new(0, -1, 0), C.asphalt, map)

for i = 1, 15 do
    local x = math.random(-140, 140)
    local z = math.random(-140, 140)
    part("Crack"..i, Vector3.new(math.random(10, 30), 0.1, math.random(1, 3)), Vector3.new(x, 0.05, z), C.asphalt_dark, map)
end

for i = 1, 8 do
    local x = math.random(-120, 120)
    local z = math.random(-120, 120)
    local puddle = part("Puddle"..i, Vector3.new(math.random(5, 15), 0.1, math.random(5, 15)), Vector3.new(x, 0.06, z), C.blood, map, 0.3, Enum.Material.Glass)
end

local grassN = part("GrassNorth", Vector3.new(300, 3, 40), Vector3.new(0, -1.5, -170), C.grass, map)
grassN.TopSurface = Enum.SurfaceType.Studs
local grassS = part("GrassSouth", Vector3.new(300, 3, 40), Vector3.new(0, -1.5, 170), C.grass, map)
grassS.TopSurface = Enum.SurfaceType.Studs
local grassE = part("GrassEast", Vector3.new(40, 3, 220), Vector3.new(170, -1.5, 0), C.grass, map)
grassE.TopSurface = Enum.SurfaceType.Studs
local grassW = part("GrassWest", Vector3.new(40, 3, 220), Vector3.new(-170, -1.5, 0), C.grass, map)
grassW.TopSurface = Enum.SurfaceType.Studs

part("DirtNorth", Vector3.new(300, 1, 5), Vector3.new(0, 0.5, -150), C.dirt, map)
part("DirtSouth", Vector3.new(300, 1, 5), Vector3.new(0, 0.5, 150), C.dirt, map)
part("DirtEast", Vector3.new(5, 1, 220), Vector3.new(150, 0.5, 0), C.dirt, map)
part("DirtWest", Vector3.new(5, 1, 220), Vector3.new(-150, 0.5, 0), C.dirt, map)

-- ═══════════════════════════════════════════════════════════
-- ЗАБОР
-- ═══════════════════════════════════════════════════════════

function createFenceSection(x, z, isHorizontal)
    if math.random() > 0.12 then
        wall("FencePost", Vector3.new(2, 10, 2), Vector3.new(x, 5, z), C.fence_post, map)
        if isHorizontal then
            local rail1 = wall("RailTop", Vector3.new(10, 1, 1), Vector3.new(x + 5, 9, z), C.fence_chain, map)
            rail1.Transparency = 0.3
            local rail2 = wall("RailBottom", Vector3.new(10, 1, 1), Vector3.new(x + 5, 3, z), C.fence_chain, map)
            rail2.Transparency = 0.3
        else
            local rail1 = wall("RailTop", Vector3.new(1, 1, 10), Vector3.new(x, 9, z + 5), C.fence_chain, map)
            rail1.Transparency = 0.3
            local rail2 = wall("RailBottom", Vector3.new(1, 1, 10), Vector3.new(x, 3, z + 5), C.fence_chain, map)
            rail2.Transparency = 0.3
        end
        for i = 1, 3 do
            part("Wire", Vector3.new(0.3, 2, 0.3), Vector3.new(x + (isHorizontal and math.random(-4, 4) or 0), 10, z + (isHorizontal and 0 or math.random(-4, 4))), C.fence_rust, map)
        end
    else
        for i = 1, 3 do
            local debris = part("Debris", Vector3.new(math.random(2, 4), math.random(1, 3), math.random(2, 4)), Vector3.new(x + math.random(-3, 3), 1, z + math.random(-3, 3)), C.fence_post, map)
            debris.Rotation = Vector3.new(math.random(-30, 30), math.random(-30, 30), math.random(-30, 30))
        end
    end
end

for x = -150, 150, 10 do
    createFenceSection(x, -150, true)
    createFenceSection(x, 150, true)
end

for z = -150, 150, 10 do
    createFenceSection(-150, z, false)
    createFenceSection(150, z, false)
end

-- ═══════════════════════════════════════════════════════════
-- РЕСЕПШН (ВЫСОТА 30)
-- ═══════════════════════════════════════════════════════════

local rx, rz = -80, -80
local reception = Instance.new("Folder")
reception.Name = "Reception"
reception.Parent = map

part("Foundation", Vector3.new(60, 3, 60), Vector3.new(rx, -1.5, rz), C.wall_concrete, reception)
part("Floor", Vector3.new(56, 1, 56), Vector3.new(rx, 0.5, rz), C.wall_dirty, reception)

wall("WallBack", Vector3.new(60, 30, 2), Vector3.new(rx, 15, rz - 30), C.wall_white, reception)
wall("WallLeft", Vector3.new(2, 30, 60), Vector3.new(rx - 30, 15, rz), C.wall_white, reception)
wall("WallRight", Vector3.new(2, 30, 60), Vector3.new(rx + 30, 15, rz), C.wall_white, reception)
wall("WallFrontLeft", Vector3.new(20, 30, 2), Vector3.new(rx - 20, 15, rz + 30), C.wall_white, reception)
wall("WallFrontRight", Vector3.new(20, 30, 2), Vector3.new(rx + 20, 15, rz + 30), C.wall_white, reception)

part("SignBoard", Vector3.new(24, 6, 1), Vector3.new(rx, 27, rz + 30.5), C.sign_warning, reception)
part("SignText", Vector3.new(20, 4, 0.5), Vector3.new(rx, 27, rz + 31), C.wall_white, reception)

local doorL = part("DoorLeft", Vector3.new(8, 20, 2), Vector3.new(rx - 4.5, 10, rz + 30.5), C.door_metal, reception)
doorL.TopSurface = Enum.SurfaceType.Smooth
local doorR = part("DoorRight", Vector3.new(8, 20, 2), Vector3.new(rx + 4.5, 10, rz + 30.5), C.door_metal, reception)
doorR.TopSurface = Enum.SurfaceType.Smooth

wall("DoorFrameTop", Vector3.new(22, 2, 3), Vector3.new(rx, 21, rz + 30.5), C.fence_post, reception)
wall("DoorFrameLeft", Vector3.new(2, 20, 3), Vector3.new(rx - 11, 10, rz + 30.5), C.fence_post, reception)
wall("DoorFrameRight", Vector3.new(2, 20, 3), Vector3.new(rx + 11, 10, rz + 30.5), C.fence_post, reception)

part("RoofMain", Vector3.new(64, 2, 64), Vector3.new(rx, 31, rz), C.roof_flat, reception)
part("RoofParapet", Vector3.new(66, 3, 66), Vector3.new(rx, 33, rz), C.wall_concrete, reception)

for i = 1, 3 do
    local vent = part("Vent"..i, Vector3.new(4, 6, 4), Vector3.new(rx + math.random(-20, 20), 36, rz + math.random(-20, 20)), C.roof_metal, reception)
    vent.TopSurface = Enum.SurfaceType.Smooth
end

for floor = 1, 3 do
    local y = floor * 8
    part("WindowL"..floor, Vector3.new(1, 6, 12), Vector3.new(rx - 30.5, y, rz - 10 + (floor-1)*5), C.window_glass, reception, 0.4)
    part("WindowR"..floor, Vector3.new(1, 6, 12), Vector3.new(rx + 30.5, y, rz + 10 - (floor-1)*5), C.window_glass, reception, 0.4)
    part("WindowB"..floor, Vector3.new(12, 6, 1), Vector3.new(rx - 10 + (floor-1)*5, y, rz - 30.5), C.window_glass, reception, 0.4)
end

part("WindowBroken", Vector3.new(1, 6, 8), Vector3.new(rx - 30.5, 8, rz + 15), C.window_broken, reception, 0.6)

part("DeskMain", Vector3.new(18, 3, 8), Vector3.new(rx, 1.5, rz + 15), C.wall_grey, reception)
part("DeskTop", Vector3.new(20, 1, 10), Vector3.new(rx, 3.5, rz + 15), C.wall_white, reception)
part("DeskBack", Vector3.new(20, 5, 2), Vector3.new(rx, 5.5, rz + 10), C.wall_grey, reception)

part("Monitor", Vector3.new(3, 2, 1), Vector3.new(rx - 5, 5, rz + 14), C.fence_post, reception)
part("MonitorScreen", Vector3.new(2.5, 1.5, 0.1), Vector3.new(rx - 5, 5, rz + 13.4), C.light_yellow, reception, 0.2)

part("Chair", Vector3.new(3, 4, 3), Vector3.new(rx + 8, 2, rz + 15), C.door_metal, reception)
part("Bench", Vector3.new(12, 2, 3), Vector3.new(rx - 20, 1, rz + 35), C.door_metal, reception)

-- ═══════════════════════════════════════════════════════════
-- КЛАДОВКА
-- ═══════════════════════════════════════════════════════════

local kx, kz = 100, 100
local storage = Instance.new("Folder")
storage.Name = "Storage"
storage.Parent = map

part("Foundation", Vector3.new(40, 2, 40), Vector3.new(kx, -1, kz), C.wall_concrete, storage)

wall("WallBack", Vector3.new(40, 20, 2), Vector3.new(kx, 10, kz - 20), C.wall_grey, storage)
wall("WallLeft", Vector3.new(2, 20, 40), Vector3.new(kx - 20, 10, kz), C.wall_grey, storage)
wall("WallRight", Vector3.new(2, 20, 40), Vector3.new(kx + 20, 10, kz), C.wall_grey, storage)

wall("DoorFrameTop", Vector3.new(16, 2, 2), Vector3.new(kx, 19, kz + 20), C.fence_post, storage)
wall("DoorFrameLeft", Vector3.new(2, 16, 2), Vector3.new(kx - 8, 8, kz + 20), C.fence_post, storage)
wall("DoorFrameRight", Vector3.new(2, 16, 2), Vector3.new(kx + 8, 8, kz + 20), C.fence_post, storage)

part("Door", Vector3.new(12, 14, 2), Vector3.new(kx, 7, kz + 20.5), C.door_rust, storage)

part("Roof", Vector3.new(44, 3, 44), Vector3.new(kx, 21.5, kz), C.roof_metal, storage)
part("RoofPeak", Vector3.new(40, 2, 2), Vector3.new(kx, 23, kz), C.roof_metal, storage)

for i = 1, 12 do
    local cx = kx + math.random(-15, 15)
    local cz = kz + math.random(-15, 15)
    local size = math.random(3, 6)
    local crate = part("Crate"..i, Vector3.new(size, size, size), Vector3.new(cx, size/2, cz), i % 2 == 0 and C.crate_wood or C.crate_metal, storage)
    crate.Rotation = Vector3.new(0, math.random(-20, 20), 0)
end

for i = 1, 3 do
    part("Shelf"..i, Vector3.new(30, 1, 6), Vector3.new(kx, i * 5, kz - 10 + i * 3), C.fence_post, storage)
end

-- ═══════════════════════════════════════════════════════════
-- ВЫШКА
-- ═══════════════════════════════════════════════════════════

local vx, vz = 120, -120
local tower = Instance.new("Folder")
tower.Name = "Tower"
tower.Parent = map

part("Base", Vector3.new(20, 4, 20), Vector3.new(vx, -2, vz), C.wall_concrete, tower)

for i = 1, 20 do
    local y = i * 1.5
    part("Step"..i, Vector3.new(4, 0.5, 2), Vector3.new(vx + 12, y, vz), C.fence_post, tower)
    if i > 1 then
        wall("Rail"..i, Vector3.new(0.5, 1.5, 0.5), Vector3.new(vx + 14, y + 0.75, vz), C.fence_rust, tower)
    end
end

for _, offset in pairs({{-8, -8}, {8, -8}, {-8, 8}, {8, 8}}) do
    wall("Leg", Vector3.new(4, 35, 4), Vector3.new(vx + offset[1], 17.5, vz + offset[2]), C.fence_post, tower)
end

part("Platform", Vector3.new(24, 2, 24), Vector3.new(vx, 36, vz), C.fence_post, tower)
wall("RailingN", Vector3.new(24, 4, 1), Vector3.new(vx, 38, vz - 12), C.fence_rust, tower)
wall("RailingS", Vector3.new(24, 4, 1), Vector3.new(vx, 38, vz + 12), C.fence_rust, tower)
wall("RailingW", Vector3.new(1, 4, 24), Vector3.new(vx - 12, 38, vz), C.fence_rust, tower)
wall("RailingE", Vector3.new(1, 4, 24), Vector3.new(vx + 12, 38, vz), C.fence_rust, tower)

part("Cabin", Vector3.new(20, 8, 20), Vector3.new(vx, 41, vz), C.wall_grey, tower)
part("CabinRoof", Vector3.new(22, 2, 22), Vector3.new(vx, 46, vz), C.roof_metal, tower)

part("CabinWindow", Vector3.new(1, 4, 6), Vector3.new(vx + 10.5, 41, vz), C.window_glass, tower, 0.3)
part("CabinWindow2", Vector3.new(6, 4, 1), Vector3.new(vx, 41, vz + 10.5), C.window_glass, tower, 0.3)

local spotlight = part("Spotlight", Vector3.new(4, 4, 4), Vector3.new(vx, 48, vz), C.light_yellow, tower)
spotlight.Material = Enum.Material.Neon
local spotLight = Instance.new("SpotLight")
spotLight.Brightness = 10
spotLight.Range = 80
spotLight.Angle = 60
spotLight.Color = Color3.fromRGB(255, 255, 200)
spotLight.Parent = spotlight

for i = 1, 3 do
    wall("Antenna"..i, Vector3.new(1, 15, 1), Vector3.new(vx + math.random(-8, 8), 53, vz + math.random(-8, 8)), C.fence_rust, tower)
end

-- ═══════════════════════════════════════════════════════════
-- ДЕКОР УЛИЦЫ
-- ═══════════════════════════════════════════════════════════

local barrelTypes = {C.barrel_oil, C.barrel_fire, C.barrel_toxic, C.crate_wood}
for i = 1, 15 do
    local bx = math.random(-130, 130)
    local bz = math.random(-130, 130)
    if (math.abs(bx - rx) > 35 or math.abs(bz - rz) > 35) and (math.abs(bx - kx) > 25 or math.abs(bz - kz) > 25) then
        local barrel = part("Barrel"..i, Vector3.new(3, 5, 3), Vector3.new(bx, 2.5, bz), barrelTypes[math.random(1, #barrelTypes)], map)
        barrel.Rotation = Vector3.new(0, math.random(-30, 30), 0)
        if math.random() > 0.7 then
            barrel.Rotation = Vector3.new(90, 0, math.random(-30, 30))
            barrel.Position = Vector3.new(bx, 1.5, bz)
        end
    end
end

for i = 1, 4 do
    local tx = math.random(-110, 110)
    local tz = math.random(-110, 110)
    if math.abs(tx - rx) > 40 or math.abs(tz - rz) > 40 then
        part("TentBase"..i, Vector3.new(14, 1, 14), Vector3.new(tx, 0.5, tz), C.paper, map)
        part("TentRoof"..i, Vector3.new(16, 8, 16), Vector3.new(tx, 4, tz), C.paper, map)
        part("TentDoor"..i, Vector3.new(4, 6, 1), Vector3.new(tx, 3, tz + 8), C.paper, map, 0.5)
        part("TentTable"..i, Vector3.new(6, 2, 3), Vector3.new(tx, 1, tz), C.door_metal, map)
        part("TentChair"..i, Vector3.new(2, 3, 2), Vector3.new(tx + 4, 1.5, tz), C.door_metal, map)
    end
end

local signPositions = {{-50, -50}, {50, 50}, {-50, 50}, {50, -50}, {0, -80}, {0, 80}}
for i, pos in pairs(signPositions) do
    wall("SignPole"..i, Vector3.new(1, 10, 1), Vector3.new(pos[1], 5, pos[2]), C.fence_post, map)
    local signType = i % 3 == 1 and C.sign_warning or (i % 3 == 2 and C.sign_danger or C.sign_bio)
    part("SignBoard"..i, Vector3.new(5, 6, 1), Vector3.new(pos[1], 9, pos[2] + 1), signType, map)
    part("SignStripes"..i, Vector3.new(4, 5, 0.2), Vector3.new(pos[1], 9, pos[2] + 1.5), C.wall_white, map)
end

local carX, carZ = -70, 70
part("CarBody", Vector3.new(16, 5, 8), Vector3.new(carX, 2.5, carZ), C.wall_grey, map)
part("CarHood", Vector3.new(6, 2, 8), Vector3.new(carX - 10, 1, carZ), C.wall_grey, map)
part("CarTrunk", Vector3.new(5, 3, 8), Vector3.new(carX + 10, 2, carZ), C.wall_grey, map)
part("Wheel1", Vector3.new(3, 3, 1), Vector3.new(carX - 6, 1.5, carZ - 4), C.fence_post, map)
part("Wheel2", Vector3.new(3, 3, 1), Vector3.new(carX + 6, 1.5, carZ + 4), C.fence_post, map)
part("Wheel3", Vector3.new(2, 2, 1), Vector3.new(carX - 6, 1, carZ + 4), C.fence_post, map)
part("CarLightL", Vector3.new(1, 1, 1), Vector3.new(carX - 8, 3, carZ - 3), C.light_red, map, 0.3)
part("CarLightR", Vector3.new(1, 1, 1), Vector3.new(carX - 8, 3, carZ + 3), C.light_yellow, map, 0.3)

for i = 1, 20 do
    local mx = math.random(-130, 130)
    local mz = math.random(-130, 130)
    part("Trash"..i, Vector3.new(math.random(1, 3), 0.1, math.random(1, 3)), Vector3.new(mx, 0.1, mz), C.paper, map)
end

for i = 1, 5 do
    local sx = math.random(-100, 100)
    local sz = math.random(-100, 100)
    part("BloodTrail"..i, Vector3.new(math.random(5, 15), 0.1, math.random(2, 4)), Vector3.new(sx, 0.1, sz), C.blood, map, 0.4)
end

-- ═══════════════════════════════════════════════════════════
-- ФОНАРИ (МИГАЮЩИЕ)
-- ═══════════════════════════════════════════════════════════

local lampPositions = {{-100, -100}, {100, 100}, {-100, 100}, {100, -100}, {0, -100}, {0, 100}, {-100, 0}, {100, 0}}
for i, pos in pairs(lampPositions) do
    wall("LampPole"..i, Vector3.new(2, 20, 2), Vector3.new(pos[1], 10, pos[2]), C.fence_post, map)
    part("LampArm"..i, Vector3.new(4, 1, 1), Vector3.new(pos[1], 20, pos[2] + 2), C.fence_post, map)
    local lamp = part("LampHead"..i, Vector3.new(5, 3, 5), Vector3.new(pos[1], 21, pos[2] + 3), C.light_yellow, map)
    lamp.Material = Enum.Material.Neon
    
    local light = Instance.new("PointLight")
    light.Brightness = 10
    light.Range = 50
    light.Color = Color3.fromRGB(255, 240, 180)
    light.Parent = lamp
    
    if i % 3 == 0 then
        spawn(function()
            while true do
                wait(math.random(0.1, 2))
                lamp.Transparency = lamp.Transparency == 0 and 0.7 or 0
                light.Enabled = not light.Enabled
            end
        end)
    end
end

-- ═══════════════════════════════════════════════════════════
-- СПАВНЫ
-- ═══════════════════════════════════════════════════════════

local spawnData = {
    {"SpawnAlpha", Vector3.new(-140, 0.5, -140), Color3.fromRGB(75, 151, 75)},
    {"SpawnBravo", Vector3.new(-140, 0.5, 140), Color3.fromRGB(196, 40, 28)},
    {"SpawnCharlie", Vector3.new(140, 0.5, -140), Color3.fromRGB(13, 105, 172)},
    {"SpawnDelta", Vector3.new(140, 0.5, 140), Color3.fromRGB(245, 205, 48)}
}

for _, s in pairs(spawnData) do
    part(s[1].."Base", Vector3.new(12, 1, 12), Vector3.new(s[2].X, -0.5, s[2].Z), C.wall_concrete, map)
    
    local sp = Instance.new("SpawnLocation")
    sp.Name = s[1]
    sp.Size = Vector3.new(10, 1, 10)
    sp.CFrame = CFrame.new(s[2])
    sp.Color = s[3]
    sp.Material = Enum.Material.Plastic
    sp.TopSurface = Enum.SurfaceType.Studs
    sp.BottomSurface = Enum.SurfaceType.Inlet
    sp.Parent = spawns
    
    wall(s[1].."FlagPole", Vector3.new(1, 15, 1), Vector3.new(s[2].X + 8, 7.5, s[2].Z + 8), C.fence_post, map)
    part(s[1].."Flag", Vector3.new(6, 4, 1), Vector3.new(s[2].X + 11, 13, s[2].Z + 8), s[3], map)
    part(s[1].."Text", Vector3.new(8, 0.5, 2), Vector3.new(s[2].X, 0.6, s[2].Z - 4), C.wall_white, map)
end

-- ═══════════════════════════════════════════════════════════
-- ПАРАЗИТ
-- ═══════════════════════════════════════════════════════════

local parasite = Instance.new("Part")
parasite.Name = "Parasite"
parasite.Shape = Enum.PartType.Ball
parasite.Size = Vector3.new(3, 3, 3)
parasite.Position = Vector3.new(0, 60, 0)
parasite.Color = C.parasite_black
parasite.Material = Enum.Material.Neon
parasite.Transparency = 0.3
parasite.Anchored = true
parasite.Parent = gameLogic

local pLight = Instance.new("PointLight")
pLight.Color = C.parasite_glow
pLight.Brightness = 10
pLight.Range = 15
pLight.Parent = parasite

local attachment = Instance.new("Attachment")
attachment.Parent = parasite

local particle = Instance.new("ParticleEmitter")
particle.Texture = "rbxassetid://258128463"
particle.Color = ColorSequence.new(C.parasite_glow)
particle.Size = NumberSequence.new(1, 3)
particle.Transparency = NumberSequence.new(0, 1)
particle.Lifetime = NumberRange.new(0.5, 1)
particle.Rate = 20
particle.Speed = NumberRange.new(2, 5)
particle.Parent = attachment

-- ═══════════════════════════════════════════════════════════
-- ТОЧКИ NPC (16 ЗОН)
-- ═══════════════════════════════════════════════════════════

local npcZones = {
    {"Reception", -80, -80}, {"Street1", -60, 0}, {"Street2", 60, 0},
    {"Street3", 0, -60}, {"Street4", 0, 60}, {"Street5", -100, 100},
    {"Street6", 100, -100}, {"Storage", 100, 100}, {"Tower", 120, -120},
    {"Fence1", -140, 0}, {"Fence2", 140, 0}, {"Center", 0, 0},
    {"Corner1", -100, -100}, {"Corner2", 100, 100}, {"Corner3", -100, 100}, {"Corner4", 100, -100}
}

for _, zone in pairs(npcZones) do
    local f = Instance.new("Folder")
    f.Name = zone[1] .. "_Points"
    f.Parent = npcs
    
    for i = 1, 6 do
        local point = Instance.new("Part")
        point.Name = "Point" .. i
        point.Size = Vector3.new(1, 1, 1)
        point.CFrame = CFrame.new(zone[2] + math.random(-30, 30), 0.5, zone[3] + math.random(-30, 30))
        point.Transparency = 1
        point.CanCollide = false
        point.Anchored = true
        point.Parent = f
    end
end

-- ═══════════════════════════════════════════════════════════
-- ДЫМ
-- ═══════════════════════════════════════════════════════════

for i = 1, 3 do
    local smoke = Instance.new("Part")
    smoke.Name = "Smoke"..i
    smoke.Size = Vector3.new(2, 2, 2)
    smoke.Position = Vector3.new(rx + math.random(-20, 20), 35, rz + math.random(-20, 20))
    smoke.Color = Color3.fromRGB(100, 100, 100)
    smoke.Material = Enum.Material.Plastic
    smoke.Transparency = 0.7
    smoke.Anchored = true
    smoke.Parent = effects
    
    local att = Instance.new("Attachment", smoke)
    local particle = Instance.new("ParticleEmitter")
    particle.Texture = "rbxassetid://258128463"
    particle.Color = ColorSequence.new(Color3.fromRGB(150, 150, 150))
    particle.Size = NumberSequence.new(3, 8)
    particle.Transparency = NumberSequence.new(0.3, 1)
    particle.Lifetime = NumberRange.new(2, 4)
    particle.Rate = 10
    particle.Speed = NumberRange.new(1, 3)
    particle.VelocitySpread = 30
    particle.Parent = att
end

-- ═══════════════════════════════════════════════════════════
-- АВТО-СКРИПТЫ (СЕРВЕРНЫЕ)
-- ═══════════════════════════════════════════════════════════

-- 1. СКРИПТ ДВИЖЕНИЯ NPC (ПАНИКА)
local npcScript = Instance.new("Script")
npcScript.Name = "NPCPanic"
npcScript.Parent = ServerScriptService

npcScript.Source = [[
local npcs = workspace:WaitForChild("NPCs")

function setupPanic(npc)
    local humanoid = npc:WaitForChild("Humanoid")
    local torso = npc:WaitForChild("Torso")
    
    while true do
        if humanoid and humanoid.Health > 0 then
            local randomPos = torso.Position + Vector3.new(
                math.random(-30, 30),
                0,
                math.random(-30, 30)
            )
            humanoid:MoveTo(randomPos)
            humanoid.MoveToFinished:Wait()
            wait(math.random(0.1, 1))
        end
    end
end

wait(3)

for _, npc in pairs(npcs:GetChildren()) do
    if npc:IsA("Model") and npc:FindFirstChild("Humanoid") then
        setupPanic(npc)
    end
end

print("NPC в панике запущены!")
]]

-- 2. СКРИПТ СЕРВЕРА (ПРЫЖОК ПАРАЗИТА)
local serverScript = Instance.new("Script")
serverScript.Name = "ParasiteServer"
serverScript.Parent = ServerScriptService

serverScript.Source = [[
local jumpEvent = game.ReplicatedStorage.RemoteEvents:WaitForChild("JumpEvent")
local parasite = workspace.GameLogic:WaitForChild("Parasite")

jumpEvent.OnServerEvent:Connect(function(player, targetNPC)
    local owner = workspace:GetAttribute("ParasiteOwner")
    if player.Name ~= owner then return end
    
    local dist = (parasite.Position - targetNPC.Torso.Position).magnitude
    if dist > 30 then
        local sound = Instance.new("Sound")
        sound.SoundId = "rbxasset://sounds/uuhhh.mp3"
        sound.Parent = player
        sound:Play()
        return
    end
    
    parasite.Parent = targetNPC
    parasite.Position = targetNPC.Torso.Position - Vector3.new(0, 3, 0)
    workspace:SetAttribute("ParasiteNPC", targetNPC.Name)
    
    local sound = Instance.new("Sound")
    sound.SoundId = "rbxasset://sounds/button.wav"
    sound.Parent = targetNPC.Torso
    sound:Play()
end)
]]

-- 3. СКРИПТ РАУНДОВ
local roundScript = Instance.new("Script")
roundScript.Name = "RoundManager"
roundScript.Parent = ServerScriptService

roundScript.Source = [[
local players = game:GetService("Players")
local replicatedStorage = game:GetService("ReplicatedStorage")

local ROUND_TIME = 120
local PREP_TIME = 10
local gameRunning = false

function startRound()
    if gameRunning then return end
    gameRunning = true
    
    local allPlayers = players:GetPlayers()
    if #allPlayers < 2 then
        workspace:SetAttribute("GameStatus", "NEED 2+ PLAYERS")
        gameRunning = false
        return
    end
    
    local parasitePlayer = allPlayers[math.random(1, #allPlayers)]
    workspace:SetAttribute("ParasiteOwner", parasitePlayer.Name)
    workspace:SetAttribute("GameStatus", parasitePlayer.Name .. " IS PARASITE")
    
    local spawnPoints = workspace.Spawns:GetChildren()
    for i, player in pairs(allPlayers) do
        if player.Character and player.Character:FindFirstChild("Torso") then
            local spawn = spawnPoints[i] or spawnPoints[1]
            player.Character:SetPrimaryPartCFrame(spawn.CFrame + Vector3.new(0, 3, 0))
        end
    end
    
    for i = PREP_TIME, 1, -1 do
        workspace:SetAttribute("Timer", "PREP: " .. i)
        wait(1)
    end
    
    local parasitePart = workspace.GameLogic.Parasite
    local npcs = workspace.NPCs:GetChildren()
    local validNPCs = {}
    
    for _, npc in pairs(npcs) do
        if npc:IsA("Model") and npc:FindFirstChild("Humanoid") then
            table.insert(validNPCs, npc)
        end
    end
    
    if #validNPCs > 0 then
        local target = validNPCs[math.random(1, #validNPCs)]
        parasitePart.Position = target.Torso.Position - Vector3.new(0, 3, 0)
        parasitePart.Parent = target
        workspace:SetAttribute("ParasiteNPC", target.Name)
    end
    
    for i = ROUND_TIME, 0, -1 do
        workspace:SetAttribute("Timer", i)
        if workspace:GetAttribute("GameResult") == "hunters" then
            endRound("hunters")
            return
        end
        wait(1)
    end
    
    endRound("parasite")
end

function endRound(winner)
    workspace:SetAttribute("GameResult", winner)
    workspace:SetAttribute("GameStatus", winner == "hunters" and "HUNTERS WIN!" or "PARASITE WINS!")
    
    local sound = Instance.new("Sound")
    sound.SoundId = winner == "hunters" and "rbxasset://sounds/victory.mp3" or "rbxasset://sounds/lose.mp3"
    sound.Parent = workspace
    sound:Play()
    
    wait(5)
    
    workspace:SetAttribute("GameResult", nil)
    workspace:SetAttribute("ParasiteOwner", nil)
    workspace:SetAttribute("ParasiteNPC", nil)
    workspace:SetAttribute("Timer", 0)
    
    local parasite = workspace.GameLogic.Parasite
    parasite.Parent = workspace.GameLogic
    parasite.Position = Vector3.new(0, 60, 0)
    
    gameRunning = false
    wait(3)
    startRound()
end

replicatedStorage.RemoteEvents.CaughtEvent.OnServerEvent:Connect(function()
    workspace:SetAttribute("GameResult", "hunters")
end)

wait(5)
startRound()

players.PlayerAdded:Connect(function()
    if not gameRunning then
        wait(2)
        startRound()
    end
end)
]]

-- ═══════════════════════════════════════════════════════════
-- ЛОКАЛЬНЫЕ СКРИПТЫ (ИГРОК)
-- ═══════════════════════════════════════════════════════════

-- 1. УПРАВЛЕНИЕ ПАРАЗИТОМ
local localScript1 = Instance.new("LocalScript")
localScript1.Name = "ParasiteControl"
localScript1.Parent = game.StarterPlayer.StarterPlayerScripts

localScript1.Source = [[
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local jumpEvent = game.ReplicatedStorage.RemoteEvents:WaitForChild("JumpEvent")

mouse.KeyDown:Connect(function(key)
    if key == "e" or key == "E" then
        local target = mouse.Target
        if target and target.Parent then
            local parent = target.Parent
            if parent:FindFirstChild("Humanoid") and parent:FindFirstChild("Torso") then
                jumpEvent:FireServer(parent)
            end
        end
    end
end)

mouse.Move:Connect(function()
    local target = mouse.Target
    if target and target.Parent and target.Parent:FindFirstChild("Humanoid") then
        mouse.Icon = "rbxasset://textures/GunCursor.png"
    else
        mouse.Icon = ""
    end
end)
]]

-- 2. GUI
local guiScript = Instance.new("LocalScript")
guiScript.Name = "UIManager"
guiScript.Parent = game.StarterGui

-- Создаём GUI элементы
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "ClassicUI"
screenGui.Parent = guiScript

local timerFrame = Instance.new("Frame")
timerFrame.Name = "TimerFrame"
timerFrame.Size = UDim2.new(0, 200, 0, 50)
timerFrame.Position = UDim2.new(0.5, -100, 0, 20)
timerFrame.BackgroundColor3 = Color3.fromRGB(99, 95, 98)
timerFrame.BorderSizePixel = 2
timerFrame.Parent = screenGui

local timerText = Instance.new("TextLabel")
timerText.Name = "TimerText"
timerText.Size = UDim2.new(1, 0, 1, 0)
timerText.Text = "WAITING..."
timerText.Font = Enum.Font.Legacy
timerText.TextSize = 18
timerText.TextColor3 = Color3.fromRGB(255, 255, 255)
timerText.BackgroundTransparency = 1
timerText.Parent = timerFrame

local roleFrame = Instance.new("Frame")
roleFrame.Name = "RoleFrame"
roleFrame.Size = UDim2.new(0, 150, 0, 30)
roleFrame.Position = UDim2.new(0, 10, 0, 10)
roleFrame.BackgroundColor3 = Color3.fromRGB(27, 42, 53)
roleFrame.BorderSizePixel = 2
roleFrame.Parent = screenGui

local roleText = Instance.new("TextLabel")
roleText.Name = "RoleText"
roleText.Size = UDim2.new(1, 0, 1, 0)
roleText.Text = "HUNTER"
roleText.Font = Enum.Font.Legacy
roleText.TextSize = 16
roleText.TextColor3 = Color3.fromRGB(255, 255, 255)
roleText.Parent = roleFrame

guiScript.Source = [[
local player = game.Players.LocalPlayer
local timerText = script.Parent:WaitForChild("TimerFrame"):WaitForChild("TimerText")
local roleText = script.Parent:WaitForChild("RoleFrame"):WaitForChild("RoleText")

workspace:GetAttributeChangedSignal("Timer"):Connect(function()
    local time = workspace:GetAttribute("Timer")
    if type(time) == "number" then
        timerText.Text = "TIME: " .. time
    else
        timerText.Text = tostring(time)
    end
end)

workspace:GetAttributeChangedSignal("ParasiteOwner"):Connect(function()
    local owner = workspace:GetAttribute("ParasiteOwner")
    if owner == player.Name then
        roleText.Text = "PARASITE"
        roleText.TextColor3 = Color3.new(1, 0, 0)
        timerText.Text = "HIDE IN NPC! PRESS E"
    else
        roleText.Text = "HUNTER"
        roleText.TextColor3 = Color3.new(0, 1, 0)
        timerText.Text = "FIND PARASITE!"
    end
end)

workspace:GetAttributeChangedSignal("GameStatus"):Connect(function()
    timerText.Text = workspace:GetAttribute("GameStatus") or "WAITING..."
end)
]]

-- ═══════════════════════════════════════════════════════════
-- ФОНАРИК (TOOL)
-- ═══════════════════════════════════════════════════════════

local flashlight = Instance.new("Tool")
flashlight.Name = "Flashlight"
flashlight.Parent = game.StarterPack

local handle = Instance.new("Part")
handle.Name = "Handle"
handle.Size = Vector3.new(1, 4, 1)
handle.Color = Color3.fromRGB(163, 162, 165)
handle.Parent = flashlight

local head = Instance.new("Part")
head.Name = "Head"
head.Size = Vector3.new(2, 1, 2)
head.Position = Vector3.new(0, 2.5, 0)
head.Color = Color3.fromRGB(255, 255, 0)
head.Parent = flashlight

local weld = Instance.new("Weld")
weld.Part0 = head
weld.Part1 = handle
weld.C0 = CFrame.new(0, -2.5, 0)
weld.Parent = head

local spotLight = Instance.new("SpotLight")
spotLight.Brightness = 8
spotLight.Range = 25
spotLight.Angle = 45
spotLight.Color = Color3.fromRGB(255, 255, 200)
spotLight.Enabled = false
spotLight.Parent = head

local toolScript = Instance.new("LocalScript")
toolScript.Name = "FlashlightScript"
toolScript.Parent = flashlight

toolScript.Source = [[
local tool = script.Parent
local light = tool:WaitForChild("Head"):WaitForChild("SpotLight")

tool.Activated:Connect(function()
    light.Enabled = not light.Enabled
    local sound = Instance.new("Sound")
    sound.SoundId = "rbxasset://sounds/switch.wav"
    sound.Parent = tool.Handle
    sound:Play()
end)

tool.Equipped:Connect(function()
    game.Players.LocalPlayer:GetMouse().Icon = "rbxasset://textures/GunCursor.png"
end)

tool.Unequipped:Connect(function()
    game.Players.LocalPlayer:GetMouse().Icon = ""
end)
]]

print("═══════════════════════════════════════")
print("  КАРТА + СКРИПТЫ ГОТОВЫ!")
print("═══════════════════════════════════════")
print("Теперь сделай:")
print("1. Открой Toolbox (View → Toolbox)")
print("2. Найди 'R6 dummy' и вставь 8 штук")
print("3. Переименуй в NPC1-NPC8")
print("4. Размести по карте")
print("5. Добавь ClickDetector в Torso каждого")
print("6. Скопируй скрипт CheckNPC в каждого")
print("═══════════════════════════════════════")
print("Сохрани: Ctrl+S")