Add FPS game example, auto-connect plugin, and Python injection tools

- Updated RobloxMCPPlugin with HTTP polling (auto-enables HttpService)
- Added 20-weapon FPS game example (CoD-style)
- Added Python studio-inject.py for command bar injection via Win32 API
- Added auto-connect setup scripts (VBS + PowerShell)
- Updated MCP server with all FPS game tools

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Admin
2026-03-31 16:57:35 +04:00
Unverified
parent 9c44cb514f
commit a66533206f
16 changed files with 3448 additions and 595 deletions

View File

@@ -0,0 +1,242 @@
-- ═══════════════════════════════════════════════════════════════════
-- MINI CALL OF DUTY - FPS Game Setup (Part 1: Map + Infrastructure)
-- Inject into Roblox Studio Command Bar
-- ═══════════════════════════════════════════════════════════════════
-- Clean workspace
for _, c in ipairs(workspace:GetChildren()) do
if not c:IsA("Terrain") and not c:IsA("Camera") then c:Destroy() end
end
-- Clean services
for _, c in ipairs(game:GetService("ReplicatedStorage"):GetChildren()) do c:Destroy() end
for _, c in ipairs(game:GetService("StarterGui"):GetChildren()) do c:Destroy() end
for _, c in ipairs(game:GetService("ServerScriptService"):GetChildren()) do c:Destroy() end
for _, s in ipairs({"StarterPlayerScripts", "StarterPlayer"}) do
local f = game:GetService("StarterPlayer"):FindFirstChild(s)
if f then for _, c in ipairs(f:GetChildren()) do c:Destroy() end end
end
local Lighting = game:GetService("Lighting")
for _, c in ipairs(Lighting:GetChildren()) do c:Destroy() end
-- ═══════════════════════════════════════════════════════════════
-- FOLDERS & REMOTES
-- ═══════════════════════════════════════════════════════════════
local RS = game:GetService("ReplicatedStorage")
local events = Instance.new("Folder") events.Name = "Events" events.Parent = RS
Instance.new("RemoteEvent", events).Name = "ShootEvent"
Instance.new("RemoteEvent", events).Name = "HitEvent"
Instance.new("RemoteEvent", events).Name = "KillEvent"
Instance.new("RemoteEvent", events).Name = "DamageEvent"
Instance.new("RemoteEvent", events).Name = "ReloadEvent"
Instance.new("RemoteFunction", events).Name = "GetGameData"
local shared = Instance.new("Folder") shared.Name = "Shared" shared.Parent = RS
local assets = Instance.new("Folder") assets.Name = "Assets" assets.Parent = RS
-- ═══════════════════════════════════════════════════════════════
-- MAP BUILDING - Urban Military Zone
-- ═══════════════════════════════════════════════════════════════
local mapModel = Instance.new("Model") mapModel.Name = "Map" mapModel.Parent = workspace
local function P(props)
local p = Instance.new("Part")
p.Anchored = true
p.TopSurface = Enum.SurfaceType.Smooth
p.BottomSurface = Enum.SurfaceType.Smooth
for k,v in pairs(props) do p[k] = v end
p.Parent = props.Parent or mapModel
return p
end
local function W(props)
local w = Instance.new("WedgePart")
w.Anchored = true
for k,v in pairs(props) do w[k] = v end
w.Parent = props.Parent or mapModel
return w
end
-- Ground
P({Name="Ground", Size=Vector3.new(400,2,400), Position=Vector3.new(0,-1,0),
Color=Color3.fromRGB(80,78,70), Material=Enum.Material.Asphalt})
-- Spawn area
P({Name="SpawnPad", Size=Vector3.new(20,1,20), Position=Vector3.new(0,0.5,-160),
Color=Color3.fromRGB(30,120,30), Material=Enum.Material.SmoothPlastic})
local spawnLoc = Instance.new("SpawnLocation")
spawnLoc.Name = "PlayerSpawn"
spawnLoc.Size = Vector3.new(8,1,8)
spawnLoc.Position = Vector3.new(0,1,-155)
spawnLoc.Anchored = true
spawnLoc.CanCollide = false
spawnLoc.Transparency = 0.5
spawnLoc.Color = Color3.fromRGB(0,255,0)
spawnLoc.Parent = mapModel
-- ─── BUILDINGS ───
local function makeBuilding(x, z, w, d, h, color)
local bldg = Instance.new("Model") bldg.Name = "Building" bldg.Parent = mapModel
-- Floor
P({Name="Floor", Size=Vector3.new(w,1,d), Position=Vector3.new(x,0.5,z),
Color=Color3.fromRGB(100,95,85), Material=Enum.Material.SmoothPlastic, Parent=bldg})
-- Walls
P({Name="WallN", Size=Vector3.new(w,h,1), Position=Vector3.new(x,h/2+1,z-d/2),
Color=color, Material=Enum.Material.Brick, Parent=bldg})
P({Name="WallS", Size=Vector3.new(w,h,1), Position=Vector3.new(x,h/2+1,z+d/2),
Color=color, Material=Enum.Material.Brick, Parent=bldg})
P({Name="WallE", Size=Vector3.new(1,h,d), Position=Vector3.new(x+w/2,h/2+1,z),
Color=color, Material=Enum.Material.Brick, Parent=bldg})
P({Name="WallW", Size=Vector3.new(1,h,d), Position=Vector3.new(x-w/2,h/2+1,z),
Color=color, Material=Enum.Material.Brick, Parent=bldg})
-- Roof
P({Name="Roof", Size=Vector3.new(w+2,1,d+2), Position=Vector3.new(x,h+1,z),
Color=Color3.fromRGB(60,55,50), Material=Enum.Material.CorrodedMetal, Parent=bldg})
-- Door opening (destroy wall segment)
-- Window holes
P({Name="WinN1", Size=Vector3.new(4,3,1.2), Position=Vector3.new(x+3,h/2,z-d/2),
Color=Color3.fromRGB(135,135,135), Material=Enum.Material.SmoothPlastic, Parent=bldg})
P({Name="WinN2", Size=Vector3.new(4,3,1.2), Position=Vector3.new(x-3,h/2,z-d/2),
Color=Color3.fromRGB(135,135,135), Material=Enum.Material.SmoothPlastic, Parent=bldg})
return bldg
end
-- Main buildings
makeBuilding(-50, -60, 30, 20, 12, Color3.fromRGB(140,130,120)) -- HQ building
makeBuilding(50, -60, 25, 25, 10, Color3.fromRGB(130,125,115)) -- Barracks
makeBuilding(-50, 40, 20, 30, 14, Color3.fromRGB(120,115,110)) -- Tower building
makeBuilding(50, 50, 28, 22, 10, Color3.fromRGB(125,120,110)) -- Warehouse
makeBuilding(0, 50, 22, 18, 8, Color3.fromRGB(145,135,125)) -- Center building
-- Ruined building (half walls)
P({Name="RuinedWall1", Size=Vector3.new(12,6,1), Position=Vector3.new(-20,3,0),
Color=Color3.fromRGB(100,95,85), Material=Enum.Material.Brick})
P({Name="RuinedWall2", Size=Vector3.new(1,4,8), Position=Vector3.new(-14,2,-4),
Color=Color3.fromRGB(100,95,85), Material=Enum.Material.Brick})
P({Name="RuinedFloor", Size=Vector3.new(15,1,10), Position=Vector3.new(-20,0.5,0),
Color=Color3.fromRGB(90,85,75), Material=Enum.Material.Concrete})
-- ─── COVER OBJECTS ───
local coverPositions = {
{-30,-120, 4,3,8}, {30,-120, 4,3,8}, {-10,-100, 6,2,4}, {10,-100, 6,2,4},
{-40,-30, 3,2,6}, {40,-30, 3,2,6}, {-25,10, 5,2,3}, {25,10, 5,2,3},
{0,-20, 4,3,4}, {-15,30, 3,2,5}, {15,30, 3,2,5},
{-60,0, 4,3,8}, {60,0, 4,3,8},
{-35,80, 5,2,4}, {35,80, 5,2,4}, {0,80, 3,2,6},
{-20,-50, 3,2,3}, {20,-50, 3,2,3},
{-70,-60, 4,3,6}, {70,-60, 4,3,6},
{0,120, 6,2,4}, {-40,120, 4,3,5}, {40,120, 4,3,5},
}
for i, pos in ipairs(coverPositions) do
P({Name="Cover_"..i, Size=Vector3.new(pos[4],pos[5],pos[6]),
Position=Vector3.new(pos[1],pos[5]/2+0.5,pos[2]),
Color=Color3.fromRGB(90+i*2,85+i*2,75+i*2), Material=Enum.Material.Concrete})
end
-- ─── SANDBAG WALLS ───
for i = 1, 20 do
local angle = (i/20) * math.pi * 2
local r = 85
P({Name="Sandbag_"..i, Size=Vector3.new(6,3,3),
Position=Vector3.new(math.cos(angle)*r, 1.5, math.sin(angle)*r),
Orientation=Vector3.new(0, math.deg(angle), 0),
Color=Color3.fromRGB(160,145,110), Material=Enum.Material.Slate})
end
-- ─── WATCHTOWER ───
local function makeTower(x, z)
P({Name="TowerBase_"..x, Size=Vector3.new(6,0.5,6), Position=Vector3.new(x,8,z),
Color=Color3.fromRGB(80,70,60), Material=Enum.Material.Wood})
-- Legs
P({Name="Leg1", Size=Vector3.new(1,16,1), Position=Vector3.new(x-2,8,z-2),
Color=Color3.fromRGB(70,60,50), Material=Enum.Material.Wood})
P({Name="Leg2", Size=Vector3.new(1,16,1), Position=Vector3.new(x+2,8,z-2),
Color=Color3.fromRGB(70,60,50), Material=Enum.Material.Wood})
P({Name="Leg3", Size=Vector3.new(1,16,1), Position=Vector3.new(x-2,8,z+2),
Color=Color3.fromRGB(70,60,50), Material=Enum.Material.Wood})
P({Name="Leg4", Size=Vector3.new(1,16,1), Position=Vector3.new(x+2,8,z+2),
Color=Color3.fromRGB(70,60,50), Material=Enum.Material.Wood})
-- Railing
P({Name="Rail1", Size=Vector3.new(6,2,0.3), Position=Vector3.new(x,9,z-2.85),
Color=Color3.fromRGB(70,60,50), Material=Enum.Material.Wood})
P({Name="Rail2", Size=Vector3.new(6,2,0.3), Position=Vector3.new(x,9,z+2.85),
Color=Color3.fromRGB(70,60,50), Material=Enum.Material.Wood})
end
makeTower(-70, -80)
makeTower(70, -80)
makeTower(-70, 90)
makeTower(70, 90)
-- ─── CRATES ───
for i = 1, 15 do
local cx = math.random(-80, 80)
local cz = math.random(-140, 140)
P({Name="Crate_"..i, Size=Vector3.new(3,3,3),
Position=Vector3.new(cx, 1.5, cz),
Orientation=Vector3.new(0, math.random(0,90), 0),
Color=Color3.fromRGB(140,110,60), Material=Enum.Material.Wood})
end
-- ─── BARRELS ───
for i = 1, 10 do
local bx = math.random(-90, 90)
local bz = math.random(-140, 140)
P({Name="Barrel_"..i, Shape=Enum.PartType.Cylinder, Size=Vector3.new(3,3,3),
Position=Vector3.new(bx, 1.5, bz),
Orientation=Vector3.new(0, math.random(0,180), 90),
Color=Color3.fromRGB(50,60,50), Material=Enum.Material.SmoothPlastic})
end
-- ─── MAP BOUNDARY WALLS ───
P({Name="BorderN", Size=Vector3.new(200,15,3), Position=Vector3.new(0,7.5,-180),
Color=Color3.fromRGB(60,60,60), Material=Enum.Material.Concrete})
P({Name="BorderS", Size=Vector3.new(200,15,3), Position=Vector3.new(0,7.5,180),
Color=Color3.fromRGB(60,60,60), Material=Enum.Material.Concrete})
P({Name="BorderE", Size=Vector3.new(3,15,200), Position=Vector3.new(98,7.5,0),
Color=Color3.fromRGB(60,60,60), Material=Enum.Material.Concrete})
P({Name="BorderW", Size=Vector3.new(3,15,200), Position=Vector3.new(-98,7.5,0),
Color=Color3.fromRGB(60,60,60), Material=Enum.Material.Concrete})
-- ═══════════════════════════════════════════════════════════════
-- LIGHTING - Dusk/Battle Atmosphere
-- ═══════════════════════════════════════════════════════════════
Lighting.Ambient = Color3.fromRGB(80,75,70)
Lighting.OutdoorAmbient = Color3.fromRGB(100,90,80)
Lighting.Brightness = 1.2
Lighting.ClockTime = 17.5 -- Dusk
Lighting.FogEnd = 400
Lighting.FogStart = 50
Lighting.FogColor = Color3.fromRGB(140,130,120)
local atmo = Instance.new("Atmosphere")
atmo.Density = 0.25
atmo.Color = Color3.fromRGB(180,165,145)
atmo.Decay = Color3.fromRGB(120,110,100)
atmo.Glare = 0.3
atmo.Haze = 1.5
atmo.Parent = Lighting
-- Sun rays
local sunRays = Instance.new("SunRaysEffect")
sunRays.Intensity = 0.04
sunRays.Spread = 0.6
sunRays.Parent = Lighting
-- Bloom
local bloom = Instance.new("BloomEffect")
bloom.Intensity = 0.3
bloom.Size = 24
bloom.Threshold = 1.5
bloom.Parent = Lighting
-- Color correction (warm wartime tones)
local cc = Instance.new("ColorCorrectionEffect")
cc.Brightness = 0.02
cc.Contrast = 0.1
cc.Saturation = -0.15
cc.TintColor = Color3.fromRGB(255,240,220)
cc.Parent = Lighting
print("[CoD FPS] Part 1/5 complete: Map built, lighting set.")

View File

@@ -0,0 +1,383 @@
-- ═══════════════════════════════════════════════════════════════════
-- MINI CALL OF DUTY - FPS Game Setup (Part 2: Weapon System)
-- ═══════════════════════════════════════════════════════════════════
local RS = game:GetService("ReplicatedStorage")
-- ═══════════════════════════════════════════════════════════════
-- WEAPON DATA MODULE
-- ═══════════════════════════════════════════════════════════════
local weaponData = Instance.new("ModuleScript")
weaponData.Name = "WeaponData"
weaponData.Parent = RS:FindFirstChild("Shared")
weaponData.Source = [[
local Weapons = {
M4A1 = {
name = "M4A1",
displayName = "M4A1 Carbine",
damage = 25,
fireRate = 0.09, -- seconds between shots
reloadTime = 2.2,
magSize = 30,
maxAmmo = 210,
range = 300,
headshotMult = 2.5,
recoil = {x = 0.8, y = 1.2},
spread = {hip = 3, ads = 0.5},
aimSpeed = 0.15,
moveSpeedMult = 0.95,
automatic = true,
adsFOV = 50,
},
AK47 = {
name = "AK-47",
displayName = "AK-47",
damage = 33,
fireRate = 0.1,
reloadTime = 2.5,
magSize = 30,
maxAmmo = 210,
range = 280,
headshotMult = 2.0,
recoil = {x = 1.2, y = 1.8},
spread = {hip = 4, ads = 0.8},
aimSpeed = 0.18,
moveSpeedMult = 0.92,
automatic = true,
adsFOV = 48,
},
Sniper = {
name = "AWP",
displayName = "AWP Sniper",
damage = 95,
fireRate = 1.2,
reloadTime = 3.5,
magSize = 5,
maxAmmo = 30,
range = 800,
headshotMult = 3.0,
recoil = {x = 3, y = 5},
spread = {hip = 8, ads = 0.1},
aimSpeed = 0.25,
moveSpeedMult = 0.85,
automatic = false,
adsFOV = 20,
},
Shotgun = {
name = "SPAS-12",
displayName = "SPAS-12 Shotgun",
damage = 15, -- per pellet (8 pellets)
fireRate = 0.7,
reloadTime = 3.0,
magSize = 8,
maxAmmo = 40,
range = 50,
headshotMult = 1.5,
recoil = {x = 4, y = 6},
spread = {hip = 12, ads = 8},
aimSpeed = 0.15,
moveSpeedMult = 0.88,
automatic = false,
pellets = 8,
adsFOV = 55,
},
}
return Weapons
]]
-- ═══════════════════════════════════════════════════════════════
-- CLIENT WEAPON CONTROLLER (LocalScript)
-- ═══════════════════════════════════════════════════════════════
local weaponClient = Instance.new("LocalScript")
weaponClient.Name = "WeaponClient"
weaponClient.Parent = game:GetService("StarterPlayer"):FindFirstChild("StarterPlayerScripts")
weaponClient.Source = [[
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Events = RS:WaitForChild("Events")
local player = Players.LocalPlayer
local camera = workspace.CurrentCamera
local Weapons = require(RS:WaitForChild("Shared"):WaitForChild("WeaponData"))
-- State
local currentWeapon = "M4A1"
local weapon = Weapons[currentWeapon]
local ammo = weapon.magSize
local reserveAmmo = weapon.maxAmmo
local isReloading = false
local isADS = false
local isSprinting = false
local isFiring = false
local lastFireTime = 0
local canShoot = true
-- Recoil tracking
local recoilX = 0
local recoilY = 0
local recoilRecoverySpeed = 8
-- Functions
local function updateHUD()
local hud = player.PlayerGui:FindFirstChild("FPS_HUD")
if not hud then return end
local frame = hud:FindFirstChild("MainFrame")
if not frame then return end
local ammoText = frame:FindFirstChild("AmmoDisplay")
if ammoText then ammoText.Text = ammo .. " / " .. reserveAmmo end
local weaponText = frame:FindFirstChild("WeaponName")
if weaponText then weaponText.Text = weapon.displayName end
local healthBar = frame:FindFirstChild("HealthBar")
local healthFill = frame:FindFirstChild("HealthFill")
if healthBar and healthFill then
local char = player.Character
local hum = char and char:FindFirstChildOfClass("Humanoid")
if hum then
local pct = hum.Health / hum.MaxHealth
healthFill.Size = UDim2.new(pct * 0.18, 0, 0.025, 0)
if pct < 0.3 then
healthFill.BackgroundColor3 = Color3.fromRGB(200, 30, 30)
elseif pct < 0.6 then
healthFill.BackgroundColor3 = Color3.fromRGB(200, 180, 30)
else
healthFill.BackgroundColor3 = Color3.fromRGB(30, 200, 30)
end
end
end
local scoreText = frame:FindFirstChild("ScoreDisplay")
if scoreText then scoreText.Text = "KILLS: " .. tostring(player:GetAttribute("Kills") or 0) end
end
local function shoot()
if isReloading or ammo <= 0 or not canShoot then return end
if tick() - lastFireTime < weapon.fireRate then return end
lastFireTime = tick()
ammo = ammo - 1
canShoot = false
-- Fire raycast
local mousePos = UIS:GetMouseLocation()
local ray = camera:ViewportPointToRay(mousePos.X, mousePos.Y)
local spreadMult = isADS and weapon.spread.ads or weapon.spread.hip
local spread = CFrame.new(
math.random(-100, 100) / 100 * spreadMult,
math.random(-100, 100) / 100 * spreadMult,
math.random(-100, 100) / 100 * spreadMult
) * 0.01
local direction = (ray.Direction.Unit + spread.Position).Unit
local pellets = weapon.pellets or 1
for _ = 1, pellets do
local hitRay = RaycastParams.new()
hitRay.FilterDescendantsInstances = {player.Character or {}}
hitRay.FilterType = Enum.RaycastFilterType.Exclude
local result = workspace:Raycast(ray.Origin, direction * weapon.range, hitRay)
if result then
Events:FindFirstChild("ShootEvent"):FireServer({
origin = ray.Origin,
direction = direction * weapon.range,
hit = result.Instance,
hitPos = result.Position,
normal = result.Normal,
weapon = currentWeapon,
})
-- Muzzle flash visual
local flash = Instance.new("Part")
flash.Size = Vector3.new(0.3, 0.3, 0.3)
flash.Shape = Enum.PartType.Ball
flash.Color = Color3.fromRGB(255, 200, 50)
flash.Material = Enum.Material.Neon
flash.Anchored = true
flash.CanCollide = false
flash.Position = camera.CFrame.Position + camera.CFrame.LookVector * 3
flash.Parent = workspace
game:GetService("Debris"):AddItem(flash, 0.05)
-- Bullet trail
local trail = Instance.new("Part")
trail.Size = Vector3.new(0.1, 0.1, weapon.range)
trail.CFrame = CFrame.new(camera.CFrame.Position, result.Position) * CFrame.new(0, 0, -weapon.range/2)
trail.Anchored = true
trail.CanCollide = false
trail.Color = Color3.fromRGB(255, 220, 100)
trail.Material = Enum.Material.Neon
trail.Transparency = 0.5
trail.Parent = workspace
game:GetService("Debris"):AddItem(trail, 0.03)
-- Impact effect
local impact = Instance.new("Part")
impact.Size = Vector3.new(0.5, 0.5, 0.5)
impact.Shape = Enum.PartType.Ball
impact.Color = Color3.fromRGB(255, 150, 50)
impact.Material = Enum.Material.Neon
impact.Anchored = true
impact.CanCollide = false
impact.Position = result.Position
impact.Parent = workspace
game:GetService("Debris"):AddItem(impact, 0.1)
end
end
-- Apply recoil
if isADS then
recoilX = recoilX - weapon.recoil.x * 0.4
recoilY = recoilY + weapon.recoil.y * 0.4
else
recoilX = recoilX - weapon.recoil.x
recoilY = recoilY + weapon.recoil.y
end
-- Screen shake
local shake = isADS and 0.002 or 0.005
camera.CFrame = camera.CFrame * CFrame.new(
math.random(-100,100)/100 * shake,
math.random(-100,100)/100 * shake,
0
)
task.wait(weapon.fireRate)
canShoot = true
updateHUD()
if ammo <= 0 then
reload()
end
end
function reload()
if isReloading or reserveAmmo <= 0 then return end
isReloading = true
Events:FindFirstChild("ReloadEvent"):FireServer()
task.wait(weapon.reloadTime)
local needed = weapon.magSize - ammo
local available = math.min(needed, reserveAmmo)
ammo = ammo + available
reserveAmmo = reserveAmmo - available
isReloading = false
updateHUD()
end
-- Input handling
UIS.InputBegan:Connect(function(input, processed)
if processed then return end
if input.UserInputType == Enum.UserInputType.MouseButton2 then
isADS = true
if isSprinting then isSprinting = false end
end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
isFiring = true
if isSprinting then isSprinting = false end
end
if input.KeyCode == Enum.KeyCode.LeftShift then
if not isADS then isSprinting = true end
end
if input.KeyCode == Enum.KeyCode.LeftControl then
local char = player.Character
if char then
local hum = char:FindFirstChildOfClass("Humanoid")
if hum then hum.WalkSpeed = 8 end
end
end
if input.KeyCode == Enum.KeyCode.R then
reload()
end
-- Weapon switch: 1-4
if input.KeyCode == Enum.KeyCode.One then currentWeapon = "M4A1" end
if input.KeyCode == Enum.KeyCode.Two then currentWeapon = "AK47" end
if input.KeyCode == Enum.KeyCode.Three then currentWeapon = "Sniper" end
if input.KeyCode == Enum.KeyCode.Four then currentWeapon = "Shotgun" end
if input.KeyCode >= Enum.KeyCode.One and input.KeyCode <= Enum.KeyCode.Four then
weapon = Weapons[currentWeapon]
ammo = weapon.magSize
reserveAmmo = weapon.maxAmmo
isReloading = false
updateHUD()
end
end)
UIS.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton2 then
isADS = false
end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
isFiring = false
end
if input.KeyCode == Enum.KeyCode.LeftShift then
isSprinting = false
end
if input.KeyCode == Enum.KeyCode.LeftControl then
local char = player.Character
if char then
local hum = char:FindFirstChildOfClass("Humanoid")
if hum then hum.WalkSpeed = 20 end
end
end
end)
-- Main loop
RunService.RenderStepped:Connect(function()
-- Camera FOV for ADS
local targetFOV = isADS and weapon.adsFOV or 70
camera.FieldOfView = camera.FieldOfView + (targetFOV - camera.FieldOfView) * 0.2
-- Sprint speed
local char = player.Character
if char then
local hum = char:FindFirstChildOfClass("Humanoid")
if hum and hum.MoveDirection.Magnitude > 0 then
if isSprinting then
hum.WalkSpeed = 30
elseif not UIS:IsKeyDown(Enum.KeyCode.LeftControl) then
hum.WalkSpeed = 20
end
end
end
-- Auto-fire
if isFiring and weapon.automatic then
shoot()
end
-- Recoil recovery
recoilX = recoilX + (0 - recoilX) * math.clamp(recoilRecoverySpeed * 0.01, 0, 1)
recoilY = recoilY + (0 - recoilY) * math.clamp(recoilRecoverySpeed * 0.01, 0, 1)
updateHUD()
end)
-- Lock mouse for FPS
UIS.MouseIconEnabled = false
player.CharacterAdded:Connect(function()
ammo = weapon.magSize
reserveAmmo = weapon.maxAmmo
updateHUD()
end)
updateHUD()
print("[WeaponClient] Loaded - Controls: LMB=Shoot, RMB=ADS, Shift=Sprint, Ctrl=Crouch, R=Reload, 1-4=Switch weapon")
]]
print("[CoD FPS] Part 2/5 complete: Weapon system created.")

View File

@@ -0,0 +1,542 @@
-- ═══════════════════════════════════════════════════════════════════
-- MINI CALL OF DUTY - FPS Game Setup (Part 3: Enemy AI + Server Handler)
-- ═══════════════════════════════════════════════════════════════════
local SSS = game:GetService("ServerScriptService")
local RS = game:GetService("ReplicatedStorage")
-- ═══════════════════════════════════════════════════════════════
-- SERVER GAME HANDLER
-- ═══════════════════════════════════════════════════════════════
local serverScript = Instance.new("Script")
serverScript.Name = "GameServer"
serverScript.Parent = SSS
serverScript.Source = [[
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local Events = RS:WaitForChild("Events")
local Shared = RS:WaitForChild("Shared")
local WeaponData = require(Shared:WaitForChild("WeaponData"))
local scores = {}
local killFeed = {}
-- Player setup
Players.PlayerAdded:Connect(function(player)
scores[player.UserId] = {kills = 0, deaths = 0, streak = 0}
player.CharacterAdded:Connect(function(char)
task.wait(0.5)
local hum = char:WaitForChild("Humanoid")
hum.MaxHealth = 100
hum.Health = 100
hum.WalkSpeed = 20
-- Give starter weapon visual
local tool = Instance.new("Tool")
tool.Name = "M4A1"
tool.RequiresHandle = true
tool.CanBeDropped = false
local handle = Instance.new("Part")
handle.Name = "Handle"
handle.Size = Vector3.new(0.5, 0.5, 3)
handle.Color = Color3.fromRGB(40, 40, 40)
handle.Material = Enum.Material.SmoothPlastic
handle.CanCollide = false
handle.Anchored = false
handle.Parent = tool
tool.Parent = player.Backpack
-- Gun body
local barrel = Instance.new("Part")
barrel.Name = "Barrel"
barrel.Size = Vector3.new(0.2, 0.2, 2)
barrel.Color = Color3.fromRGB(30, 30, 30)
barrel.Material = Enum.Material.Metal
barrel.CanCollide = false
barrel.Anchored = false
local weld = Instance.new("WeldConstraint")
weld.Part0 = handle
weld.Part1 = barrel
weld.Parent = barrel
barrel.CFrame = handle.CFrame * CFrame.new(0, 0.1, -2)
barrel.Parent = tool
-- Magazine
local mag = Instance.new("Part")
mag.Name = "Magazine"
mag.Size = Vector3.new(0.3, 0.8, 0.4)
mag.Color = Color3.fromRGB(35, 35, 35)
mag.Material = Enum.Material.SmoothPlastic
mag.CanCollide = false
mag.Anchored = false
local weld2 = Instance.new("WeldConstraint")
weld2.Part0 = handle
weld2.Part1 = mag
weld2.Parent = mag
mag.CFrame = handle.CFrame * CFrame.new(0, -0.5, -0.5)
mag.Parent = tool
-- Health regeneration
task.spawn(function()
while hum and hum.Health > 0 do
task.wait(3)
if hum.Health < hum.MaxHealth and hum.Health > 0 then
hum.Health = math.min(hum.MaxHealth, hum.Health + 5)
end
end
end)
-- Death handler
hum.Died:Connect(function()
scores[player.UserId].deaths = scores[player.UserId].deaths + 1
scores[player.UserId].streak = 0
-- Respawn after 5 seconds
task.delay(5, function()
if player then
player:LoadCharacter()
end
end)
end)
end)
end)
-- Handle hit events from clients
Events:WaitForChild("ShootEvent").OnServerEvent:Connect(function(player, data)
-- Validate the shot
if not data or not data.hit then return end
local hitObj = data.hit
local weaponName = data.weapon or "M4A1"
local weapon = WeaponData[weaponName]
if not weapon then return end
-- Check range
local char = player.Character
if not char then return end
local dist = (data.hitPos - char.Head.Position).Magnitude
if dist > weapon.range then return end
-- Find the humanoid of what was hit
local targetHum = nil
local isHeadshot = false
if hitObj:IsA("Model") then
targetHum = hitObj:FindFirstChildOfClass("Humanoid")
elseif hitObj.Parent and hitObj.Parent:IsA("Model") then
targetHum = hitObj.Parent:FindFirstChildOfClass("Humanoid")
elseif hitObj.Parent and hitObj.Parent.Parent and hitObj.Parent.Parent:IsA("Model") then
targetHum = hitObj.Parent.Parent:FindFirstChildOfClass("Humanoid")
end
-- Check headshot
if hitObj.Name == "Head" and targetHum then
isHeadshot = true
end
-- Apply damage
if targetHum then
local dmg = weapon.damage
if isHeadshot then dmg = dmg * weapon.headshotMult end
targetHum:TakeDamage(dmg)
-- Check if killed
if targetHum.Health <= 0 then
local victim = nil
for _, p in ipairs(Players:GetPlayers()) do
if p.Character and p.Character:FindFirstChildOfClass("Humanoid") == targetHum then
victim = p
break
end
end
if victim then
scores[player.UserId].kills = scores[player.UserId].kills + 1
scores[player.UserId].streak = scores[player.UserId].streak + 1
end
-- Fire kill event
Events:WaitForChild("KillEvent"):FireAllClients({
killer = player.Name,
victim = victim and victim.Name or "Enemy",
weapon = weaponName,
headshot = isHeadshot,
streak = scores[player.UserId].streak,
})
end
-- Fire damage indicator
Events:WaitForChild("DamageEvent"):FireClient(player, {
hit = true,
headshot = isHeadshot,
damage = dmg,
})
end
end)
-- Game data request
Events:WaitForChild("GetGameData").OnServerInvoke = function(player)
return {
scores = scores,
killFeed = killFeed,
}
end
-- Kill feed relay
Events:WaitForChild("KillEvent").OnServerEvent:Connect(function(player, data)
table.insert(killFeed, 1, data)
if #killFeed > 5 then table.remove(killFeed) end
end)
-- ═══════════════════════════════════════════════════════════════
-- ENEMY AI SYSTEM
-- ═══════════════════════════════════════════════════════════════
local enemySpawns = {
Vector3.new(60, 2, 80), Vector3.new(-60, 2, 80),
Vector3.new(70, 2, -80), Vector3.new(-70, 2, -80),
Vector3.new(0, 2, 100), Vector3.new(0, 2, -80),
Vector3.new(50, 2, 0), Vector3.new(-50, 2, 0),
Vector3.new(-40, 2, 50), Vector3.new(40, 2, -50),
Vector3.new(-80, 2, 30), Vector3.new(80, 2, -30),
}
local enemies = {}
local MAX_ENEMIES = 10
local SPAWN_INTERVAL = 8
local function createEnemy(pos)
local model = Instance.new("Model")
model.Name = "Enemy_" .. tostring(#enemies + 1)
-- Humanoid
local hum = Instance.new("Humanoid")
hum.MaxHealth = 80
hum.Health = 80
hum.WalkSpeed = 14
hum.Parent = model
-- Head
local head = Instance.new("Part")
head.Name = "Head"
head.Size = Vector3.new(1.5, 1.5, 1.5)
head.Color = Color3.fromRGB(180, 140, 110)
head.Material = Enum.Material.SmoothPlastic
head.CanCollide = true
head.Parent = model
local headMesh = Instance.new("SpecialMesh")
headMesh.MeshType = Enum.MeshType.Head
headMesh.Scale = Vector3.new(1.25, 1.25, 1.25)
headMesh.Parent = head
-- Torso
local torso = Instance.new("Part")
torso.Name = "HumanoidRootPart"
torso.Size = Vector3.new(2, 2, 1)
torso.Color = Color3.fromRGB(60, 80, 40) -- Military green
torso.Material = Enum.Material.SmoothPlastic
torso.CanCollide = true
torso.Parent = model
-- Legs
local lleg = Instance.new("Part")
lleg.Name = "Left Leg"
lleg.Size = Vector3.new(1, 2, 1)
lleg.Color = Color3.fromRGB(50, 55, 45)
lleg.Material = Enum.Material.SmoothPlastic
lleg.Parent = model
local rleg = Instance.new("Part")
rleg.Name = "Right Leg"
rleg.Size = Vector3.new(1, 2, 1)
rleg.Color = Color3.fromRGB(50, 55, 45)
rleg.Material = Enum.Material.SmoothPlastic
rleg.Parent = model
-- Arms
local larm = Instance.new("Part")
larm.Name = "Left Arm"
larm.Size = Vector3.new(1, 2, 1)
larm.Color = Color3.fromRGB(60, 80, 40)
larm.Material = Enum.Material.SmoothPlastic
larm.Parent = model
local rarm = Instance.new("Part")
rarm.Name = "Right Arm"
rarm.Size = Vector3.new(1, 2, 1)
rarm.Color = Color3.fromRGB(60, 80, 40)
rarm.Material = Enum.Material.SmoothPlastic
rarm.Parent = model
-- Motor6D connections
local function weld(part0, part1, c0, c1)
local m = Instance.new("Motor6D")
m.Part0 = part0
m.Part1 = part1
if c0 then m.C0 = c0 end
if c1 then m.C1 = c1 end
m.Parent = part0
end
weld(torso, head, CFrame.new(0, 1.5, 0), CFrame.new(0, 0, 0))
weld(torso, larm, CFrame.new(-1.5, 0, 0), CFrame.new(0.5, 0, 0))
weld(torso, rarm, CFrame.new(1.5, 0, 0), CFrame.new(-0.5, 0, 0))
weld(torso, lleg, CFrame.new(-0.5, -2, 0), CFrame.new(0, 1, 0))
weld(torso, rleg, CFrame.new(0.5, -2, 0), CFrame.new(0, 1, 0))
-- Beret/hat
local hat = Instance.new("Part")
hat.Name = "Hat"
hat.Size = Vector3.new(1.8, 0.5, 1.8)
hat.Color = Color3.fromRGB(40, 50, 30)
hat.Material = Enum.Material.SmoothPlastic
hat.CanCollide = false
hat.Parent = model
local hatWeld = Instance.new("WeldConstraint")
hatWeld.Part0 = head
hatWeld.Part1 = hat
hatWeld.Parent = hat
hat.CFrame = head.CFrame * CFrame.new(0, 0.9, 0)
-- Health bar above head
local billboard = Instance.new("BillboardGui")
billboard.Name = "HealthBar"
billboard.Size = UDim2.new(3, 0, 0.4, 0)
billboard.StudsOffset = Vector3.new(0, 3.5, 0)
billboard.AlwaysOnTop = true
billboard.Parent = head
local bg = Instance.new("Frame")
bg.Size = UDim2.new(1, 0, 1, 0)
bg.BackgroundColor3 = Color3.fromRGB(40, 40, 40)
bg.BorderSizePixel = 0
bg.Parent = billboard
local fill = Instance.new("Frame")
fill.Name = "Fill"
fill.Size = UDim2.new(1, 0, 1, 0)
fill.BackgroundColor3 = Color3.fromRGB(200, 30, 30)
fill.BorderSizePixel = 0
fill.Parent = bg
-- AI Script
local aiScript = Instance.new("Script")
aiScript.Source = [[
local humanoid = script.Parent:FindFirstChildOfClass("Humanoid")
local rootPart = script.Parent:FindFirstChild("HumanoidRootPart")
local head = script.Parent:FindFirstChild("Head")
local healthFill = script.Parent:FindFirstChild("Head"):FindFirstChild("HealthBar"):FindFirstChild("Frame"):FindFirstChild("Fill")
if not humanoid or not rootPart then return end
local state = "patrol"
local target = nil
local lastShot = 0
local fireRate = 1.2
local damage = 12
local detectionRange = 80
local attackRange = 60
local patrolPoints = {}
local currentPatrolIndex = 1
-- Generate patrol points
for i = 1, 6 do
local angle = math.rad(math.random(360))
local dist = math.random(15, 60)
table.insert(patrolPoints, rootPart.Position + Vector3.new(math.cos(angle)*dist, 0, math.sin(angle)*dist))
end
-- Find closest player
local function findTarget()
local closest = nil
local closestDist = detectionRange
for _, player in ipairs(game:GetService("Players"):GetPlayers()) do
if player.Character then
local hum = player.Character:FindFirstChildOfClass("Humanoid")
if hum and hum.Health > 0 then
local dist = (player.Character.Head.Position - rootPart.Position).Magnitude
if dist < closestDist then
closest = player
closestDist = dist
end
end
end
end
return closest, closestDist
end
-- Update health bar
humanoid.HealthChanged:Connect(function(health)
local pct = health / humanoid.MaxHealth
healthFill.Size = UDim2.new(pct, 0, 1, 0)
if pct < 0.3 then
healthFill.BackgroundColor3 = Color3.fromRGB(200, 30, 30)
else
healthFill.BackgroundColor3 = Color3.fromRGB(200, 60, 30)
end
end)
-- Main AI loop
while humanoid and humanoid.Health > 0 do
task.wait(0.3)
target, _ = findTarget()
if target and target.Character then
local targetHum = target.Character:FindFirstChildOfClass("Humanoid")
local targetHead = target.Character:FindFirstChild("Head")
if targetHum and targetHum.Health > 0 and targetHead then
local dist = (targetHead.Position - rootPart.Position).Magnitude
-- Face target
rootPart.CFrame = CFrame.new(rootPart.Position, Vector3.new(targetHead.Position.X, rootPart.Position.Y, targetHead.Position.Z))
if dist <= attackRange then
state = "attack"
-- Shoot at player
if tick() - lastShot > fireRate then
lastShot = tick()
-- Raycast to player
local direction = (targetHead.Position - head.Position).Unit
local spread = Vector3.new(math.random()-0.5, math.random()-0.5, math.random()-0.5) * 2
local hitResult = workspace:Raycast(head.Position, (direction + spread) * attackRange)
if hitResult then
-- Muzzle flash
local flash = Instance.new("Part")
flash.Size = Vector3.new(0.3, 0.3, 0.3)
flash.Shape = Enum.PartType.Ball
flash.Color = Color3.fromRGB(255, 200, 50)
flash.Material = Enum.Material.Neon
flash.Anchored = true
flash.CanCollide = false
flash.Position = head.Position + direction * 2
flash.Parent = workspace
game:GetService("Debris"):AddItem(flash, 0.08)
-- Bullet trail
local trail = Instance.new("Part")
trail.Size = Vector3.new(0.1, 0.1, (head.Position - hitResult.Position).Magnitude)
trail.CFrame = CFrame.new(head.Position, hitResult.Position) * CFrame.new(0, 0, -trail.Size.Z/2)
trail.Anchored = true
trail.CanCollide = false
trail.Color = Color3.fromRGB(255, 200, 100)
trail.Material = Enum.Material.Neon
trail.Transparency = 0.3
trail.Parent = workspace
game:GetService("Debris"):AddItem(trail, 0.1)
-- Check if hit player
local hitChar = hitResult.Instance
if hitChar then
local hitHum = nil
if hitChar.Parent and hitChar.Parent:FindFirstChildOfClass("Humanoid") then
hitHum = hitChar.Parent:FindFirstChildOfClass("Humanoid")
elseif hitChar.Parent and hitChar.Parent.Parent and hitChar.Parent.Parent:FindFirstChildOfClass("Humanoid") then
hitHum = hitChar.Parent.Parent:FindFirstChildOfClass("Humanoid")
end
if hitHum and hitHum ~= humanoid then
hitHum:TakeDamage(damage)
end
end
-- Impact effect
local impact = Instance.new("Part")
impact.Size = Vector3.new(0.5, 0.5, 0.5)
impact.Shape = Enum.PartType.Ball
impact.Color = Color3.fromRGB(255, 150, 50)
impact.Material = Enum.Material.Neon
impact.Anchored = true
impact.CanCollide = false
impact.Position = hitResult.Position
impact.Parent = workspace
game:GetService("Debris"):AddItem(impact, 0.15)
end
end
else
-- Move toward target
state = "chase"
humanoid:MoveTo(targetHead.Position)
end
end
else
-- Patrol
state = "patrol"
if #patrolPoints > 0 then
humanoid:MoveTo(patrolPoints[currentPatrolIndex])
humanoid.MoveToFinished:Connect(function(reached)
if reached then
currentPatrolIndex = (currentPatrolIndex % #patrolPoints) + 1
end
end)
end
end
end
-- Death effect
local root = script.Parent:FindFirstChild("HumanoidRootPart")
if root then
for _, v in ipairs(script.Parent:GetDescendants()) do
if v:IsA("BasePart") then
v.Anchored = false
v.BrickColor = BrickColor.new("Dark stone grey")
local bf = Instance.new("BodyForce")
bf.Force = Vector3.new(math.random(-50,50), 100, math.random(-50,50))
bf.Parent = v
game:GetService("Debris"):AddItem(v, 3)
end
end
end
task.delay(3, function()
if script.Parent then script.Parent:Destroy() end
end)
]]
aiScript.Parent = model
-- Position
local primary = torso
model.PrimaryPart = primary
primary.Position = pos
head.Position = pos + Vector3.new(0, 2.5, 0)
lleg.Position = pos + Vector3.new(-0.5, -1, 0)
rleg.Position = pos + Vector3.new(0.5, -1, 0)
larm.Position = pos + Vector3.new(-1.5, 0, 0)
rarm.Position = pos + Vector3.new(1.5, 0, 0)
model.Parent = workspace
table.insert(enemies, model)
return model
end
-- Enemy spawner loop
task.spawn(function()
task.wait(5) -- Initial delay
while true do
-- Remove dead enemies
for i = #enemies, 1, -1 do
if not enemies[i] or not enemies[i]:FindFirstChildOfClass("Humanoid")
or enemies[i]:FindFirstChildOfClass("Humanoid").Health <= 0 then
table.remove(enemies, i)
end
end
-- Spawn new enemies
if #enemies < MAX_ENEMIES then
local pos = enemySpawns[math.random(#enemySpawns)]
createEnemy(pos + Vector3.new(math.random(-5,5), 0, math.random(-5,5)))
end
task.wait(SPAWN_INTERVAL)
end
end)
print("[GameServer] Enemy AI system active. Spawning " .. MAX_ENEMIES .. " enemies.")
]]
print("[CoD FPS] Part 3/5 complete: Server handler + Enemy AI created.")

View File

@@ -0,0 +1,421 @@
-- ═══════════════════════════════════════════════════════════════════
-- MINI CALL OF DUTY - FPS Game Setup (Part 4: HUD + Player Scripts)
-- ═══════════════════════════════════════════════════════════════════
local SG = game:GetService("StarterGui")
local SP = game:GetService("StarterPlayer")
-- ═══════════════════════════════════════════════════════════════
-- HUD (ScreenGui + LocalScript)
-- ═══════════════════════════════════════════════════════════════
local hudGui = Instance.new("ScreenGui")
hudGui.Name = "FPS_HUD"
hudGui.ResetOnSpawn = false
hudGui.IgnoreGuiInset = true
hudGui.Parent = SG
-- Crosshair
local cross = Instance.new("Frame")
cross.Name = "Crosshair"
cross.Size = UDim2.new(0, 20, 0, 20)
cross.Position = UDim2.new(0.5, -10, 0.5, -10)
cross.BackgroundTransparency = 1
cross.Parent = hudGui
for _, dir in ipairs({{0,-12,0,4,"Top"},{0,4,0,12,"Bottom"},{-12,0,4,0,"Left"},{4,0,12,0,"Right"}}) do
local line = Instance.new("Frame")
line.Name = dir[5]
line.Size = UDim2.new(0, dir[3] == 0 and 2 or dir[3], 0, dir[4] == 0 and 2 or dir[4])
line.Position = UDim2.new(0, 9+dir[1], 0, 9+dir[2])
line.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
line.BackgroundTransparency = 0.2
line.BorderSizePixel = 0
line.Parent = cross
end
-- Center dot
local dot = Instance.new("Frame")
dot.Name = "CenterDot"
dot.Size = UDim2.new(0, 3, 0, 3)
dot.Position = UDim2.new(0, 8, 0, 8)
dot.BackgroundColor3 = Color3.fromRGB(255, 50, 50)
dot.BorderSizePixel = 0
dot.Parent = cross
-- Hit marker (appears on hit)
local hitMarker = Instance.new("Frame")
hitMarker.Name = "HitMarker"
hitMarker.Size = UDim2.new(0, 30, 0, 30)
hitMarker.Position = UDim2.new(0.5, -15, 0.5, -15)
hitMarker.BackgroundTransparency = 1
hitMarker.Visible = false
hitMarker.Parent = hudGui
for _, d in ipairs({{-8,-8,6,6,45},{2,-8,6,6,-45},{-8,2,6,6,-45},{2,2,6,6,45}}) do
local mark = Instance.new("Frame")
mark.Size = UDim2.new(0, d[3], 0, d[4])
mark.Position = UDim2.new(0, 12+d[1], 0, 12+d[2])
mark.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
mark.BorderSizePixel = 0
mark.Rotation = d[5]
mark.Parent = hitMarker
end
-- Damage vignette overlay
local dmgVignette = Instance.new("Frame")
dmgVignette.Name = "DamageVignette"
dmgVignette.Size = UDim2.new(1, 0, 1, 0)
dmgVignette.BackgroundColor3 = Color3.fromRGB(200, 0, 0)
dmgVignette.BackgroundTransparency = 1
dmgVignette.BorderSizePixel = 0
dmgVignette.ZIndex = 9
dmgVignette.Parent = hudGui
-- Kill feed frame (top right)
local killFeedFrame = Instance.new("Frame")
killFeedFrame.Name = "KillFeed"
killFeedFrame.Size = UDim2.new(0, 350, 0, 150)
killFeedFrame.Position = UDim2.new(1, -360, 0, 10)
killFeedFrame.BackgroundTransparency = 1
killFeedFrame.Parent = hudGui
-- Score display (top center)
local scoreFrame = Instance.new("Frame")
scoreFrame.Name = "ScoreFrame"
scoreFrame.Size = UDim2.new(0, 200, 0, 40)
scoreFrame.Position = UDim2.new(0.5, -100, 0, 10)
scoreFrame.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
scoreFrame.BackgroundTransparency = 0.5
scoreFrame.BorderSizePixel = 0
scoreFrame.Parent = hudGui
local scoreLabel = Instance.new("TextLabel")
scoreLabel.Name = "ScoreLabel"
scoreLabel.Size = UDim2.new(1, 0, 1, 0)
scoreLabel.BackgroundTransparency = 1
scoreLabel.Text = "KILLS: 0 | DEATHS: 0"
scoreLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
scoreLabel.TextSize = 18
scoreLabel.Font = Enum.Font.GothamBold
scoreLabel.Parent = scoreFrame
-- Killstreak banner (center)
local streakBanner = Instance.new("TextLabel")
streakBanner.Name = "StreakBanner"
streakBanner.Size = UDim2.new(0, 400, 0, 60)
streakBanner.Position = UDim2.new(0.5, -200, 0.3, 0)
streakBanner.BackgroundTransparency = 1
streakBanner.Text = ""
streakBanner.TextColor3 = Color3.fromRGB(255, 200, 50)
streakBanner.TextSize = 32
streakBanner.Font = Enum.Font.GothamBold
streakBanner.TextStrokeTransparency = 0
streakBanner.Visible = false
streakBanner.ZIndex = 10
streakBanner.Parent = hudGui
-- Minimap (top left)
local minimap = Instance.new("Frame")
minimap.Name = "Minimap"
minimap.Size = UDim2.new(0, 150, 0, 150)
minimap.Position = UDim2.new(0, 10, 0, 10)
minimap.BackgroundColor3 = Color3.fromRGB(30, 40, 30)
minimap.BackgroundTransparency = 0.3
minimap.BorderSizePixel = 0
minimap.Parent = hudGui
local mapCorner = Instance.new("UICorner")
mapCorner.CornerRadius = UDim.new(0, 75)
mapCorner.Parent = minimap
local playerDot = Instance.new("Frame")
playerDot.Name = "PlayerDot"
playerDot.Size = UDim2.new(0, 6, 0, 6)
playerDot.Position = UDim2.new(0.5, -3, 0.5, -3)
playerDot.BackgroundColor3 = Color3.fromRGB(0, 255, 0)
playerDot.BorderSizePixel = 0
playerDot.Parent = minimap
-- Weapon info panel (bottom right)
local weaponPanel = Instance.new("Frame")
weaponPanel.Name = "WeaponPanel"
weaponPanel.Size = UDim2.new(0, 250, 0, 80)
weaponPanel.Position = UDim2.new(1, -260, 1, -90)
weaponPanel.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
weaponPanel.BackgroundTransparency = 0.4
weaponPanel.BorderSizePixel = 0
weaponPanel.Parent = hudGui
local weaponLabel = Instance.new("TextLabel")
weaponLabel.Name = "WeaponName"
weaponLabel.Size = UDim2.new(1, -10, 0, 25)
weaponLabel.Position = UDim2.new(0, 5, 0, 5)
weaponLabel.BackgroundTransparency = 1
weaponLabel.Text = "M4A1 CARBINE"
weaponLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
weaponLabel.TextSize = 16
weaponLabel.Font = Enum.Font.GothamBold
weaponLabel.TextXAlignment = Enum.TextXAlignment.Right
weaponLabel.Parent = weaponPanel
local ammoLabel = Instance.new("TextLabel")
ammoLabel.Name = "AmmoLabel"
ammoLabel.Size = UDim2.new(1, -10, 0, 35)
ammoLabel.Position = UDim2.new(0, 5, 0, 25)
ammoLabel.BackgroundTransparency = 1
ammoLabel.Text = "30 / 210"
ammoLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
ammoLabel.TextSize = 28
ammoLabel.Font = Enum.Font.GothamBold
ammoLabel.TextXAlignment = Enum.TextXAlignment.Right
ammoLabel.Parent = weaponPanel
local reserveLabel = Instance.new("TextLabel")
reserveLabel.Name = "ReserveLabel"
reserveLabel.Size = UDim2.new(1, -10, 0, 15)
reserveLabel.Position = UDim2.new(0, 5, 0, 60)
reserveLabel.BackgroundTransparency = 1
reserveLabel.Text = ""
reserveLabel.TextColor3 = Color3.fromRGB(180, 180, 180)
reserveLabel.TextSize = 12
reserveLabel.Font = Enum.Font.Gotham
reserveLabel.TextXAlignment = Enum.TextXAlignment.Right
reserveLabel.Parent = weaponPanel
-- Reload bar
local reloadBar = Instance.new("Frame")
reloadBar.Name = "ReloadBar"
reloadBar.Size = UDim2.new(0, 200, 0, 8)
reloadBar.Position = UDim2.new(0.5, -100, 0.6, 0)
reloadBar.BackgroundColor3 = Color3.fromRGB(40, 40, 40)
reloadBar.BorderSizePixel = 0
reloadBar.Visible = false
reloadBar.Parent = hudGui
local reloadFill = Instance.new("Frame")
reloadFill.Name = "Fill"
reloadFill.Size = UDim2.new(0, 0, 1, 0)
reloadFill.BackgroundColor3 = Color3.fromRGB(255, 200, 50)
reloadFill.BorderSizePixel = 0
reloadFill.Parent = reloadBar
-- Controls hint (bottom center)
local controlsHint = Instance.new("TextLabel")
controlsHint.Name = "Controls"
controlsHint.Size = UDim2.new(0, 600, 0, 25)
controlsHint.Position = UDim2.new(0.5, -300, 1, -30)
controlsHint.BackgroundTransparency = 1
controlsHint.Text = "WASD=Move | LMB=Shoot | RMB=ADS | Shift=Sprint | Ctrl=Crouch | R=Reload | 1-4=Weapons"
controlsHint.TextColor3 = Color3.fromRGB(150, 150, 150)
controlsHint.TextSize = 12
controlsHint.Font = Enum.Font.Gotham
controlsHint.Parent = hudGui
-- ═══════════════════════════════════════════════════════════════
-- PLAYER SETUP SCRIPT (LocalScript in StarterPlayerScripts)
-- ═══════════════════════════════════════════════════════════════
local spScripts = SP:FindFirstChild("StarterPlayerScripts")
if not spScripts then
spScripts = Instance.new("Folder")
spScripts.Name = "StarterPlayerScripts"
spScripts.Parent = SP
end
local playerSetup = Instance.new("LocalScript")
playerSetup.Name = "PlayerSetup"
playerSetup.Parent = spScripts
playerSetup.Source = [[
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local Events = RS:WaitForChild("Events")
local player = Players.LocalPlayer
local camera = workspace.CurrentCamera
-- Force first person
player.CameraMode = Enum.CameraMode.LockFirstPerson
player.CameraMaxZoomDistance = 0.5
player.CameraMinZoomDistance = 0.5
-- Character setup on spawn
player.CharacterAdded:Connect(function(char)
task.wait(0.5)
local hum = char:WaitForChild("Humanoid")
hum.WalkSpeed = 20
hum.JumpPower = 40
-- Health regen
task.spawn(function()
while hum and hum.Health > 0 do
task.wait(2)
if hum.Health < hum.MaxHealth and hum.Health > 0 then
hum.Health = math.min(hum.MaxHealth, hum.Health + 3)
end
end
end)
-- Damage vignette on hit
hum.HealthChanged:Connect(function(health)
local lost = hum.MaxHealth - health
if lost > 0 then
local gui = player:FindFirstChild("PlayerGui")
if gui then
local hud = gui:FindFirstChild("FPS_HUD")
if hud then
local vignette = hud:FindFirstChild("DamageVignette")
if vignette then
local intensity = math.clamp(lost / hum.MaxHealth, 0, 0.6)
vignette.BackgroundTransparency = 1 - intensity
task.delay(0.3, function()
if vignette then
vignette.BackgroundTransparency = 1
end
end)
end
end
end
end
end)
end)
-- Kill feed listener
Events:WaitForChild("KillEvent").OnClientEvent:Connect(function(data)
local gui = player:FindFirstChild("PlayerGui")
if not gui then return end
local hud = gui:FindFirstChild("FPS_HUD")
if not hud then return end
local feed = hud:FindFirstChild("KillFeed")
if not feed then return end
-- Create kill feed entry
local entry = Instance.new("TextLabel")
entry.Size = UDim2.new(1, 0, 0, 25)
entry.BackgroundTransparency = 0.4
entry.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
entry.Text = " " .. data.killer .. " [" .. data.weapon .. "] " .. data.victim
.. (data.headshot and " ★" or "")
entry.TextColor3 = data.killer == player.Name and Color3.fromRGB(50, 255, 50)
or Color3.fromRGB(255, 255, 255)
entry.TextSize = 14
entry.Font = Enum.Font.GothamBold
entry.TextXAlignment = Enum.TextXAlignment.Right
entry.BorderSizePixel = 0
-- Headshot indicator color
if data.headshot then
entry.TextColor3 = Color3.fromRGB(255, 50, 50)
end
entry.Parent = feed
-- Shift older entries down
for i, child in ipairs(feed:GetChildren()) do
if child:IsA("TextLabel") then
child.Position = UDim2.new(0, 0, 0, (i-1) * 28)
end
end
-- Remove after 5 seconds
task.delay(5, function()
if entry then entry:Destroy() end
end)
-- Killstreak banner
if data.killer == player.Name and data.streak then
local banner = hud:FindFirstChild("StreakBanner")
if banner then
local streakNames = {
[3] = "TRIPLE KILL!",
[5] = "KILLING SPREE!",
[7] = "UNSTOPPABLE!",
[10] = "TACTICAL NUKE READY!",
}
local msg = streakNames[data.streak]
if msg then
banner.Text = msg
banner.Visible = true
task.delay(3, function()
if banner then banner.Visible = false end
end)
end
end
end
end)
-- Hit marker listener
Events:WaitForChild("DamageEvent").OnClientEvent:Connect(function(data)
local gui = player:FindFirstChild("PlayerGui")
if not gui then return end
local hud = gui:FindFirstChild("FPS_HUD")
if not hud then return end
-- Show hit marker
local hm = hud:FindFirstChild("HitMarker")
if hm and data.hit then
hm.Visible = true
-- Change color for headshots
for _, child in ipairs(hm:GetChildren()) do
if child:IsA("Frame") then
child.BackgroundColor3 = data.headshot
and Color3.fromRGB(255, 50, 50)
or Color3.fromRGB(255, 255, 255)
end
end
task.delay(0.15, function()
if hm then hm.Visible = false end
end)
end
end)
-- Minimap updater
task.spawn(function()
task.wait(3)
while true do
task.wait(0.5)
local char = player.Character
if char then
local gui = player:FindFirstChild("PlayerGui")
if gui then
local hud = gui:FindFirstChild("FPS_HUD")
if hud then
local map = hud:FindFirstChild("Minimap")
if map then
-- Update enemy dots
for _, child in ipairs(map:GetChildren()) do
if child.Name == "EnemyDot" then child:Destroy() end
end
for _, obj in ipairs(workspace:GetChildren()) do
if obj.Name:match("^Enemy_") then
local hum = obj:FindFirstChildOfClass("Humanoid")
if hum and hum.Health > 0 then
local root = obj:FindFirstChild("HumanoidRootPart")
if root and char:FindFirstChild("Head") then
local relPos = root.Position - char.Head.Position
local mapScale = 150 / 400 -- minimap size / map size
local mx = math.clamp(relPos.X * mapScale + 72, 5, 145)
local mz = math.clamp(relPos.Z * mapScale + 72, 5, 145)
local eDot = Instance.new("Frame")
eDot.Name = "EnemyDot"
eDot.Size = UDim2.new(0, 5, 0, 5)
eDot.Position = UDim2.new(0, mx, 0, mz)
eDot.BackgroundColor3 = Color3.fromRGB(255, 50, 50)
eDot.BorderSizePixel = 0
eDot.Parent = map
end
end
end
end
end
end
end
end
end
end)
print("[PlayerSetup] FPS player configured.)
]]
print("[CoD FPS] Part 4/5 complete: HUD + Player scripts created.")

View File

@@ -0,0 +1,371 @@
-- ═══════════════════════════════════════════════════════════════════
-- MINI CALL OF DUTY - FPS Game Setup (Part 5: Weapon Client Script)
-- ═══════════════════════════════════════════════════════════════════
local SG = game:GetService("StarterGui")
-- Get the HUD that was already created in Part 4
local hudGui = SG:FindFirstChild("FPS_HUD")
-- Add the weapon controller LocalScript
local weaponScript = Instance.new("LocalScript")
weaponScript.Name = "WeaponController"
weaponScript.Parent = hudGui
weaponScript.Source = [[
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local Events = RS:WaitForChild("Events")
local Shared = RS:WaitForChild("Shared")
local WeaponData = require(Shared:WaitForChild("WeaponData"))
local player = Players.LocalPlayer
local camera = workspace.CurrentCamera
local mouse = player:GetMouse()
-- Weapon state
local currentWeapon = "M4A1"
local weapon = WeaponData[currentWeapon]
local ammo = weapon.magSize
local reserveAmmo = weapon.maxAmmo
local isReloading = false
local lastShot = 0
local isADS = false
local isSprinting = false
local isFiring = false
local recoilX = 0
local recoilY = 0
-- UI references
local scriptParent = script.Parent
local crosshair = scriptParent:WaitForChild("Crosshair")
local hitMarker = scriptParent:WaitForChild("HitMarker")
local weaponPanel = scriptParent:WaitForChild("WeaponPanel")
local ammoLabel = weaponPanel:WaitForChild("AmmoLabel")
local weaponLabel = weaponPanel:WaitForChild("WeaponName")
local reserveLabel = weaponPanel:WaitForChild("ReserveLabel")
local reloadBar = scriptParent:WaitForChild("ReloadBar")
local reloadFill = reloadBar:WaitForChild("Fill")
local scoreLabel = scriptParent:WaitForChild("ScoreFrame"):WaitForChild("ScoreLabel")
local damageVignette = scriptParent:WaitForChild("DamageVignette")
local kills = 0
local deaths = 0
local function updateHUD()
if ammoLabel then
ammoLabel.Text = ammo .. " / " .. reserveAmmo
if ammo <= math.floor(weapon.magSize * 0.25) then
ammoLabel.TextColor3 = Color3.fromRGB(255, 80, 80)
else
ammoLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
end
end
if weaponLabel then
weaponLabel.Text = weapon.displayName:upper()
end
if reserveLabel then
reserveLabel.Text = isReloading and "RELOADING..." or ""
end
if scoreLabel then
scoreLabel.Text = "KILLS: " .. kills .. " | DEATHS: " .. deaths
end
end
local function shoot()
if isReloading then return end
if ammo <= 0 then
-- Auto reload
if reserveAmmo > 0 then
-- Play empty click sound via visual feedback
end
return
end
if tick() - lastShot < weapon.fireRate then return end
lastShot = tick()
ammo = ammo - 1
-- Recoil
recoilX = recoilX + (math.random() - 0.5) * weapon.recoil.x
recoilY = weapon.recoil.y * 0.3
camera.CFrame = camera.CFrame * CFrame.Angles(
math.rad(-recoilY),
math.rad(recoilX * 0.1),
0
)
-- Spread
local spreadAmount = isADS and weapon.spread.ads or weapon.spread.hip
local spread = Vector3.new(
(math.random() - 0.5) * spreadAmount * 0.01,
(math.random() - 0.5) * spreadAmount * 0.01,
0
)
-- Raycast
local rayDirection = (camera.CFrame.LookVector + spread) * weapon.range
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local char = player.Character
if char then raycastParams.FilterDescendantsInstances = {char} end
local result = workspace:Raycast(camera.CFrame.Position, rayDirection, raycastParams)
-- Muzzle flash
local flash = Instance.new("Part")
flash.Size = Vector3.new(0.3, 0.3, 0.3)
flash.Shape = Enum.PartType.Ball
flash.Color = Color3.fromRGB(255, 200, 50)
flash.Material = Enum.Material.Neon
flash.Anchored = true
flash.CanCollide = false
flash.Position = camera.CFrame.Position + camera.CFrame.LookVector * 3
flash.Parent = workspace
game:GetService("Debris"):AddItem(flash, 0.04)
if result then
-- Bullet trail
local trail = Instance.new("Part")
local trailLen = (camera.CFrame.Position - result.Position).Magnitude
trail.Size = Vector3.new(0.08, 0.08, trailLen)
trail.CFrame = CFrame.new(camera.CFrame.Position, result.Position)
* CFrame.new(0, 0, -trailLen / 2)
trail.Anchored = true
trail.CanCollide = false
trail.Color = Color3.fromRGB(255, 220, 100)
trail.Material = Enum.Material.Neon
trail.Transparency = 0.4
trail.Parent = workspace
game:GetService("Debris"):AddItem(trail, 0.06)
-- Impact spark
local spark = Instance.new("Part")
spark.Size = Vector3.new(0.4, 0.4, 0.4)
spark.Shape = Enum.PartType.Ball
spark.Color = Color3.fromRGB(255, 180, 50)
spark.Material = Enum.Material.Neon
spark.Anchored = true
spark.CanCollide = false
spark.Position = result.Position
spark.Parent = workspace
game:GetService("Debris"):AddItem(spark, 0.12)
-- Smoke puff at impact
local smoke = Instance.new("Part")
smoke.Size = Vector3.new(1, 1, 1)
smoke.Shape = Enum.PartType.Ball
smoke.Color = Color3.fromRGB(120, 120, 110)
smoke.Transparency = 0.5
smoke.Anchored = true
smoke.CanCollide = false
smoke.Position = result.Position
smoke.Parent = workspace
game:GetService("Debris"):AddItem(smoke, 0.3)
-- Send to server
Events:WaitForChild("ShootEvent"):FireServer({
origin = camera.CFrame.Position,
direction = rayDirection,
hit = result.Instance,
hitPos = result.Position,
normal = result.Normal,
weapon = currentWeapon,
})
else
-- Shot into air - just trail to max range
local endPoint = camera.CFrame.Position + rayDirection
local trail = Instance.new("Part")
local trailLen = weapon.range
trail.Size = Vector3.new(0.06, 0.06, trailLen)
trail.CFrame = CFrame.new(camera.CFrame.Position, endPoint)
* CFrame.new(0, 0, -trailLen / 2)
trail.Anchored = true
trail.CanCollide = false
trail.Color = Color3.fromRGB(255, 220, 100)
trail.Material = Enum.Material.Neon
trail.Transparency = 0.5
trail.Parent = workspace
game:GetService("Debris"):AddItem(trail, 0.04)
end
-- Auto reload when empty
if ammo <= 0 and reserveAmmo > 0 then
task.delay(0.3, function() reload() end)
end
updateHUD()
end
local function reload()
if isReloading then return end
if ammo >= weapon.magSize then return end
if reserveAmmo <= 0 then return end
isReloading = true
reloadBar.Visible = true
local startTime = tick()
local conn
conn = RunService.RenderStepped:Connect(function()
local elapsed = tick() - startTime
local pct = math.clamp(elapsed / weapon.reloadTime, 0, 1)
reloadFill.Size = UDim2.new(pct * 200, 0, 1, 0)
if pct >= 1 then
conn:Disconnect()
local needed = weapon.magSize - ammo
local toLoad = math.min(needed, reserveAmmo)
ammo = ammo + toLoad
reserveAmmo = reserveAmmo - toLoad
isReloading = false
reloadBar.Visible = false
reloadFill.Size = UDim2.new(0, 0, 1, 0)
updateHUD()
end
end)
updateHUD()
end
-- Input handling
UIS.InputBegan:Connect(function(input, processed)
if processed then return end
if input.UserInputType == Enum.UserInputType.MouseButton2 then
isADS = true
if isSprinting then isSprinting = false end
end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
isFiring = true
if not weapon.automatic then shoot() end
if isSprinting then isSprinting = false end
end
if input.KeyCode == Enum.KeyCode.LeftShift then
if not isADS then isSprinting = true end
end
if input.KeyCode == Enum.KeyCode.LeftControl then
local c = player.Character
if c then
local h = c:FindFirstChildOfClass("Humanoid")
if h then h.WalkSpeed = 8 end
end
end
if input.KeyCode == Enum.KeyCode.R then reload() end
-- Weapon switch
if input.KeyCode == Enum.KeyCode.One then currentWeapon = "M4A1"
elseif input.KeyCode == Enum.KeyCode.Two then currentWeapon = "AK47"
elseif input.KeyCode == Enum.KeyCode.Three then currentWeapon = "Sniper"
elseif input.KeyCode == Enum.KeyCode.Four then currentWeapon = "Shotgun" end
if input.KeyCode >= Enum.KeyCode.One and input.KeyCode <= Enum.KeyCode.Four then
weapon = WeaponData[currentWeapon]
ammo = weapon.magSize
reserveAmmo = weapon.maxAmmo
isReloading = false
reloadBar.Visible = false
updateHUD()
end
end)
UIS.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton2 then isADS = false end
if input.UserInputType == Enum.UserInputType.MouseButton1 then isFiring = false end
if input.KeyCode == Enum.KeyCode.LeftShift then isSprinting = false end
if input.KeyCode == Enum.KeyCode.LeftControl then
local c = player.Character
if c then
local h = c:FindFirstChildOfClass("Humanoid")
if h then h.WalkSpeed = 20 end
end
end
end)
-- Track kills/deaths from events
Events:WaitForChild("KillEvent").OnClientEvent:Connect(function(data)
if data.killer == player.Name then
kills = kills + 1
end
if data.victim == player.Name then
deaths = deaths + 1
end
updateHUD()
end)
-- Main loop
RunService.RenderStepped:Connect(function()
-- Camera FOV for ADS
local targetFOV = isADS and weapon.adsFOV or 70
camera.FieldOfView = camera.FieldOfView + (targetFOV - camera.FieldOfView) * 0.2
-- Sprint speed
local c = player.Character
if c then
local h = c:FindFirstChildOfClass("Humanoid")
if h and h.MoveDirection.Magnitude > 0 then
if isSprinting then
h.WalkSpeed = 30
elseif not UIS:IsKeyDown(Enum.KeyCode.LeftControl) then
h.WalkSpeed = 20
end
end
end
-- Auto-fire for automatic weapons
if isFiring and weapon.automatic then shoot() end
-- Recoil recovery
recoilX = recoilX * 0.9
recoilY = recoilY * 0.85
-- Crosshair spread
local spreadPx = isADS and 2 or (isSprinting and 15 or 6)
if isFiring then spreadPx = spreadPx + 4 end
for _, child in ipairs(crosshair:GetChildren()) do
if child.Name == "Top" then child.Position = UDim2.new(0, 9, 0, 9 - spreadPx)
elseif child.Name == "Bottom" then child.Position = UDim2.new(0, 9, 0, 9 + spreadPx)
elseif child.Name == "Left" then child.Position = UDim2.new(0, 9 - spreadPx, 0, 9)
elseif child.Name == "Right" then child.Position = UDim2.new(0, 9 + spreadPx, 0, 9)
end
end
end)
-- First person lock
UIS.MouseIconEnabled = false
player.CameraMode = Enum.CameraMode.LockFirstPerson
player.CharacterAdded:Connect(function()
ammo = weapon.magSize
reserveAmmo = weapon.maxAmmo
kills = 0
deaths = 0
isReloading = false
reloadBar.Visible = false
updateHUD()
end)
updateHUD()
print("═══════════════════════════════════════════")
print(" MINI CALL OF DUTY - LOADED!")
print(" Controls:")
print(" WASD = Move")
print(" LMB = Shoot")
print(" RMB = Aim Down Sights")
print(" Shift = Sprint")
print(" Ctrl = Crouch")
print(" R = Reload")
print(" 1-4 = Switch Weapon")
print(" Weapons: M4A1(1), AK-47(2), AWP Sniper(3), SPAS-12(4)")
print("═══════════════════════════════════════════")
]]
print("[CoD FPS] Part 5/5 complete: Weapon controller script created.")
print("═══════════════════════════════════════════")
print(" ALL PARTS COMPLETE! Press PLAY in Studio to start.")
print("═══════════════════════════════════════════")