Sorry for all the script lol I don't know wher it is. I am trying to make the script do actual damage to players.
if not script.Parent.Parent.Parent:FindFirstChild("Turret") then
repeat until script.Parent.Parent.Parent.ChildAdded:wait().Name == "Turret";
end
-- This finds the tank that we are controlling
parts = script.Parent.Parent.Parent.Turret.Value;
tankStats = parts.Stats;
-- Player's tank GUI
GUI = script.Parent.Parent.Parent.PlayerGui.TankGUI;
firingMg = false;
reloading = false;
currRound = tankStats.Round; -- Current loaded ammo (AP/HE)
myMouse = nil;
function updateAmmo()
GUI.Ammo.Text = tankStats.Round.Value .. " Ammo = " .. tankStats[tankStats.Round.Value .. "Ammo"].Value;
GUI.MG_Ammo.Text = "M2MG Ammo = " .. tankStats.CALAmmo.Value;
end
-- Reload animation
function reload()
if not reloading then
reloading=true;
local flash = parts.Parent.Gun.Flash;
flash.Transparency = 0;
-- Play sound
parts.Parent.Gun.Muzzle.Sound:Play();
local reloadTime = tankStats.ReloadTime.Value;
wait(1.1);
flash.Transparency = 0.2;
wait(0.1);
flash.Transparency = 0.4;
wait(0.1);
flash.Transparency = 0.2;
wait(0.1);
flash.Transparency = 0.4;
wait(0.1);
flash.Transparency = 1;
for i = 9, 1, -1 do
wait(reloadTime/8);
GUI["r" .. i].Visible = true;
end
wait(reloadTime/8);
for i = 1, 9 do
GUI["r" .. i].Visible = false;
end
reloading = false;
end
end
function fire()
if reloading then return end;
local BM48Ammo = tankStats.BM48Ammo;
local BK29MAmmo = tankStats.BK29MAmmo;
if currRound.Value == "BM48" and BM48Ammo.Value <= 0 then return end
if currRound.Value == "BK29M" and BK29MAmmo.Value <= 0 then return end
if currRound.Value == "BM48" then
BM48Ammo.Value = BM48Ammo.Value - 1;
else
BK29MAmmo.Value = BK29MAmmo.Value - 1;
end
local fireScript = tankStats["Fire" .. currRound.Value]:clone();
fireScript.Parent = parts;
fireScript.Disabled = false;
reload(GUI);
wait(3) parts.Parent.Gun.Muzzle.Reload:play()
end
-- When Clicked
function onButton1Down(mouse)
--print("Down");
--print(mouse.hit.p);
fire();
updateAmmo();
end
-- When mouse released
function onButton1Up(mouse)
--print("Up");
end
-- When tool is selected
function onSelected(mouse)
myMouse = mouse;
mouse.Icon = "rbxassetid://70288585";
mouse.Button1Down:connect(function() onButton1Down(mouse) end);
mouse.Button1Up:connect(function() onButton1Up(mouse) end);
mouse.KeyDown:connect(onKeyDown);
mouse.KeyUp:connect(onKeyUp);
updateAmmo();
end
-- When tool deselected
function onDeselected(mouse)
myMouse = nil
end
rayPart = Instance.new("Part")
rayPart.Name = "MG Ray"
rayPart.Transparency = 0.2
rayPart.Anchored = true
rayPart.CanCollide = false
rayPart.TopSurface = Enum.SurfaceType.Smooth
rayPart.BottomSurface = Enum.SurfaceType.Smooth
rayPart.formFactor = Enum.FormFactor.Custom
rayPart.BrickColor = BrickColor.new("Deep orange")
rayPart.Reflectance = 0
rayPart.Material = "Neon"
function fireCoax()
local CALAmmo = tankStats.CALAmmo;
if CALAmmo.Value <= 0 then
return false;
end;
local machineGun = parts.Parent.Gun["MG"];
CALAmmo.Value = CALAmmo.Value - 1;
machineGun.Sound:Play();
local offset = (parts.Parent.Gun.Muzzle.CFrame * CFrame.new(math.random(-5,5)/5,100,math.random(-5,5)/5).p
- parts.Parent.Gun.Muzzle.Position).unit * 999;
local ray = Ray.new(machineGun.Position, offset);
-- local hit, position = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
local hit, position = workspace:FindPartOnRay(ray, parts.Parent);
if hit then
if hit.Parent:IsA("Model") then
local player = game.Players:GetPlayerFromCharacter(hit.Parent);
local humanoid = hit.Parent:findFirstChild("Humanoid");
if player and humanoid then --It is a player
if player.TeamColor ~= parts.Parent.Tank.Value then --Not a teammate
humanoid:takeDamage(math.random(40,40));
end
end
end
end
local distance = (position - machineGun.Position).magnitude;
local distance = (position - machineGun.Position).magnitude;
local rayPart = rayPart:clone();
rayPart.Size = Vector3.new(0.2, distance, 0.2);
rayPart.CFrame = CFrame.new(position, machineGun.Position)
* CFrame.new(0, 0, -distance/2)
* CFrame.Angles(math.rad(90),0,0);
rayPart.Parent = workspace;
parts.Parent.Gun.MGFlash.Transparency = 0;
wait(0.1);
parts.Parent.Gun.MGFlash.Transparency = 1;
rayPart:remove();
wait();
return true;
end
-- When key pressed
function onKeyDown(key)
if key == nil then return end
key = key:lower()
-- Coaxial Machine Gun Control
if key == 'c' then
if firingMg then return end
firingMg = true;
while firingMg do
if not fireCoax() then
firingMg = false;
end
updateAmmo();
end
end
-- Switch ammo type
if key == 'e' then
if tankStats.Round.Value == "BM48" then
tankStats.Round.Value = "BK29M";
else
tankStats.Round.Value = "BM48";
end
updateAmmo();
end
end
-- When key released
function onKeyUp(key)
if key == nil then return end
key = key:lower()
-- Stop firing MG
if key == 'c' then
firingMg = false;
end
end
script.Parent.Selected:connect(onSelected)
script.Parent.Deselected:connect(onDeselected)
-- Set the tank's welds to face the right direction
function setTurretDirection(elevation, rotation)
parts.MantletBase.MainGunWeld.C1 = CFrame.new(0,0,0) * CFrame.fromEulerAnglesXYZ(0, elevation, 0);
parts.TurretRing2.TurretRingWeld.C1 = CFrame.new(0,0,0) * CFrame.fromEulerAnglesXYZ(0, 0, rotation);
end
-- Determine the gun elevation and tilt
function determineNewDirections(targetVector)
local targElev = 0;
local targRot = 0;
local turretMain = parts.TurretRing2;
-- Vector normal to the plane which is the turret ring
local turretNormal = turretMain.CFrame.lookVector;
local angleFromNormal = turretNormal:Dot(targetVector);
-- Determine gun elevation
targElev = math.pi/2 - math.acos(angleFromNormal);
-- Projection of target vector onto the turret plane
local targetProjection = (targetVector - (angleFromNormal*turretNormal)).unit;
local forwardVector = ( (turretMain.CFrame - turretMain.CFrame.p) -- Orientation only of brick
* CFrame.new(0, -1, 0)).p; -- Translated down 1
-- Determine angle between forward vector and the projected target vector
targRot = math.acos(forwardVector:Dot(targetProjection));
-- Determine the sign of the angle
local vectorCross = forwardVector:Cross(targetProjection);
-- If the cross product is opposite to the normal vector, make the angle negative
if (vectorCross:Dot(turretNormal) < 0) then
targRot = -targRot;
end
-- Put rotation and elevation into an array
local rotations = {};
rotations[1] = targElev;
rotations[2] = targRot;
return rotations;
end
function sign(input)
if (input < 0) then
return -1;
else
return 1;
end
end
-- Using the desired target rotation and elevation, determine where the gun should point right now (smoothly turn)
function getSmoothRotation(rotations)
local targElev = rotations[1];
local targRot = rotations[2];
local maxGunDepression = tankStats.GunDepression.Value;
-- Restrict the height of travel of the gun
if math.abs(targElev) > maxGunDepression then
targElev = maxGunDepression*sign(targElev);
end
-- Once target angles are set, slowly turn turret towards them
-- Elevation
local elevDiff = targElev - currentElev;
if math.abs(elevDiff) < 0.01 then -- If they're close
currentElev = targElev;
else -- Move towards it
currentElev = currentElev + 0.01*sign(elevDiff);
end
-- Rotation
local rotDiff = targRot - currentRot;
if rotDiff > math.pi then
rotDiff = rotDiff - 2*math.pi;
elseif rotDiff < -math.pi then
rotDiff = rotDiff + 2*math.pi;
end
local turretSpeed = tankStats.TurretSpeed.Value;
if math.abs(rotDiff) < turretSpeed then -- If they're close
currentRot = targRot;
else -- Move towards it
currentRot = currentRot + turretSpeed*sign(rotDiff);
end
-- Put rotation and elevation into an array
local rotations = {};
rotations[1] = targElev;
rotations[2] = targRot;
return rotations;
end
-- Infinitely update the target position for the tank
currentElev = 0;
currentRot = 0;
while wait() do
if (myMouse) then
-- Position of mouse in world
mousePoint = myMouse.Hit.p;
-- Vector from tank to mouse point
targetVector = (mousePoint - parts.GunBase.CFrame.p).unit;
-- Determine where the gun should point
targetRotations = determineNewDirections(targetVector);
-- For each time we do all that math to determine the angle, we will smoothly rotate the gun towards it in 4 increments
-- This means less lag (fewer calculations) but it's still smooth
for i = 1, 4 do
newRotations = getSmoothRotation(targetRotations);
setTurretDirection(currentElev, currentRot);
wait();
end
end
end
