Files
ClaudeCode-Roblox-Studio-MCP/examples/fps-game/part2_weapons.lua
Admin a66533206f 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>
2026-03-31 16:57:35 +04:00

384 lines
11 KiB
Lua

-- ═══════════════════════════════════════════════════════════════════
-- 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.")