Advertisement
KillianPGT

BuckShoot Roulette Script (made by MEEEE)

May 1st, 2025 (edited)
30
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.53 KB | Source Code | 0 0
  1. --!strict
  2. --!optimize 2
  3.  
  4. --[[
  5. This Lua script is designed for Roblox while basing a mini shooting game off of a shotgun (considered to be an XM1014). Russia's role of "Roulette" is reserved for two individual players (as well as a player and NPC). The contestants take turns at either shooting themselves or pointing the gun towards the other player. The code does declare a class "Buckshoot" that does care for all the game logic; the set-up of the game, managing ammo, shooting, updating the GUI, and when it’s over. Each time a new instance from the new function is created for a new game, it gives the two players no ammo and sets the AI default health to 100. The StartGame function chooses a random player; the original player is set as the owner. The original player is set before giving 1 to five real bullets, then the rest of the ten available bullets are filled with blanks. When the two players are real users (and not AI), and the script makes some extensions in their GUI, the names of the players are shown through PlayerGui and a remote event is sent to change the camera view with client-side visuals. Some RemoteEvents that the game servers include are StartEvent, SHOOT EVENT, and InitEvent for coordinating mission behavior between server and client. A 3D copy of the weapon is kept in game space and can be referenced through a specific position.
  6.  
  7. The AddAmmo and RemoveAmmo functions, as well as the SmartRemoveAmmo function, dynamically control the ammo during gameplay. When the bullet is “shot,” the system checks the existence of the bullet and performs the necessary actions: inflicting damage, executing a visual effect, and seamlessly ending the game if required. Other services in Roblox are used, including TweenService and Debris, for animation and deletion of game objects. Overall, the script is a chance based, suspenseful shooting game with tactical elements mingled in.
  8. ]]
  9.  
  10. local Buckshoot = {}
  11. Buckshoot.__index = function(self, key)
  12.     return Buckshoot[key]
  13. end
  14. Buckshoot.__newindex = function(t, k, v)
  15.     if k == "Owner" then print("Old Value:", v) end
  16.     return rawset(t, k, v)
  17. end
  18.  
  19. --// Export Type
  20.  
  21. export type Plr = Player | "AI"
  22. export type AmmoType = "Real" | "Blank"
  23. export type ShootType = "Ennemy" | "Himself"
  24. export type AmmoTable = {
  25.     ["Real"]: number,
  26.     ["Blank"]: number,
  27. }
  28. export type AIstats = {
  29.     ["Health"]: number,
  30. }
  31.  
  32. export type BuckshootClass = {
  33.     Players: {Plr},
  34.     Owner: Player?,
  35.     Ammo: AmmoTable,
  36.     AIstats: AIstats,
  37.     AI: boolean,
  38.  
  39.     new: (Player1: Plr, Player2: Plr, Owner: Player?) -> BuckshootClass,
  40.     EndGame: (self: BuckshootClass) -> (),
  41.     StartGame: (self: BuckshootClass) -> (),
  42.     AddAmmo: (self: BuckshootClass, type: AmmoType, amount: number) -> (),
  43.     RemoveAmmo: (self: BuckshootClass, type: AmmoType, amount: number) -> (),
  44.     GetRandomPlayer: (self: BuckshootClass) -> Plr,
  45.     GetRealPlayer: (self: BuckshootClass) -> (Player, number),
  46.     ShootEvent: (self: BuckshootClass, Type: ShootType) -> (),
  47.     SmartRemoveAmmo: (self: BuckshootClass, mode: string) -> AmmoType?,
  48.     GetEnnemy: (self: BuckshootClass) -> Plr,
  49. }
  50.  
  51. --// Service:
  52.  
  53. local ReplicatedStorage = game:GetService("ReplicatedStorage")
  54. local TweenService = game:GetService("TweenService")
  55. local Debris = game:GetService("Debris")
  56.  
  57. --// RemoteEvent
  58.  
  59. local StartEvent = ReplicatedStorage.StartEvent
  60. local ShootEvent = ReplicatedStorage.ShootEvent
  61. local InitEvent = ReplicatedStorage.InitPlayerEvent
  62.  
  63. --// Model Variable
  64.  
  65. local ShotgunModel = workspace.table.Gun["Meshes/XM1014"]
  66. local BasePosition = CFrame.new(-3.49698067, 3.09959221, -19.2551651, 0, 0.707106948, 0.707106948, -1, 0, 0, 0, -0.707106948, 0.707106948)
  67.  
  68. --// Player Stats
  69.  
  70. local RevHealth = 100/3 -- is for 3 life for the player
  71.  
  72. --// Func New
  73. function Buckshoot.new(Player1: Player, Player2: Player, Owner: Player?): BuckshootClass
  74.     local self = setmetatable({}, Buckshoot) :: BuckshootClass
  75.     self.Players = {Player1, Player2}
  76.     self.Owner = Owner or nil
  77.     self.AI = false
  78.     self.Ammo = {["Real"] = 0, ["Blank"] = 0}
  79.     self.AIstats = {["Health"] = 100}
  80.    
  81.     return self
  82. end
  83.  
  84. --// Func StartGame
  85. function Buckshoot:StartGame()
  86.  
  87.     --// Init of the game
  88.         --// Creating Stats
  89.     self.Owner = self.Owner or self:GetRandomPlayer()
  90.     self:AddAmmo("Real", math.random(1, 5))
  91.     self:AddAmmo("Blank", 10-self.Ammo.Real)
  92.    
  93.     if not (self.Players[1] == "AI" or self.Players[2] == "AI") then
  94.        
  95.         --// Visual Effect
  96.  
  97.         local Players = self.Players :: {Player}
  98.  
  99.         for i, player in ipairs(Players) do
  100.             local targetGui1 = player.PlayerGui:FindFirstChild("PlrGui1")
  101.             local targetGui2 = player.PlayerGui:FindFirstChild("PlrGui2")
  102.  
  103.             if targetGui1 and targetGui2 then
  104.                 targetGui1.TextLabel.Text = player.Name
  105.                 targetGui2.TextLabel.Text = Players[i % #Players + 1].Name
  106.             end
  107.         end
  108.  
  109.         StartEvent:FireAllClients(true) --\\ Camera Setup (why allClient? because the server is limited to 2 player)
  110.        
  111.     end
  112.    
  113.     local index = table.find(self.Players, "AI")
  114.    
  115.     if index then
  116.        
  117.         local AIplayer = self.Players[index] :: string
  118.         local RealPlayer: Player, IndexPlr: number = self:GetRealPlayer()
  119.        
  120.         --// Visual Effect
  121.         RealPlayer.PlayerGui["PlrGui"..IndexPlr].TextLabel.Text = RealPlayer.Name
  122.         RealPlayer.PlayerGui["PlrGui"..index].TextLabel.Text = AIplayer
  123.            
  124.         local textLab = workspace.table.AmmoGui.SurfaceGui.BillboardGui.TextLabel
  125.         textLab.Text = "Real Bullets: " .. self.Ammo.Real .. "\nBlank Bullets: " .. self.Ammo.Blank
  126.        
  127.         task.spawn(function()
  128.             task.wait(5)
  129.             textLab.Text = ""
  130.         end)
  131.        
  132.         StartEvent:FireClient(RealPlayer, true) --\\ Camera Setup
  133.        
  134.     end
  135.    
  136.     task.wait(.5)
  137.    
  138.     if self.Owner == "AI" then
  139.         self:ShootEvent()
  140.     end
  141.    
  142.     --print("Le jeu commence! Propri�taire: " .. self.Owner.Name)
  143.  
  144. end
  145.  
  146. --// Func EndGame
  147. function Buckshoot:EndGame()
  148.    
  149.     local Players = self.Players :: {Plr}
  150.    
  151.     for i, player in ipairs(Players) do
  152.        
  153.         if player ~= "AI" then
  154.            
  155.             local Humanoid = player.Character.Humanoid :: Humanoid
  156.             local PlayerGui = player.PlayerGui :: PlayerGui
  157.            
  158.             if Humanoid.Health == 0 then continue end
  159.            
  160.             -- Reset Camera:
  161.             StartEvent:FireClient(player, false)
  162.            
  163.             --Reset PlrGui:
  164.             local targetGui1 = PlayerGui:FindFirstChild("PlrGui1").TextLabel :: TextLabel
  165.             local targetGui2 = PlayerGui:FindFirstChild("PlrGui2").TextLabel :: TextLabel
  166.            
  167.             if targetGui1 and targetGui2 then
  168.                 targetGui1.Text = ""
  169.                 targetGui2.Text = ""
  170.             end
  171.            
  172.             --Reset Player's stat
  173.             Humanoid.WalkSpeed = 16
  174.             Humanoid.JumpPower = 50
  175.             Humanoid.Health = 100
  176.            
  177.             -- Reset ProximityPrompt:
  178.             for _, Proximity: ProximityPrompt in workspace.table.Players:GetDescendants() do
  179.                 if Proximity:IsA("ProximityPrompt") then
  180.                     Proximity.Enabled = true
  181.                 end
  182.             end
  183.            
  184.         end
  185.        
  186.     end
  187.    
  188.     ShotgunModel.CFrame = BasePosition -- just incase the shotgun won't be at his basePosition
  189.    
  190. end
  191.  
  192. --// Func ShootEvent
  193. function Buckshoot:ShootEvent(Type: ShootType)
  194.    
  195.     local AI = self.AI :: boolean
  196.     local UpPosition = BasePosition + Vector3.new(0, 5, 0)
  197.    
  198.     local index = table.find(self.Players, "AI") :: number
  199.     local AIplayer = self.Players[index] :: string
  200.  
  201.     local Owner = self.Owner :: Player | string
  202.     local OwnerHumanoid: Humanoid?
  203.     local OwnerHead = Owner.Character and Owner.Character:FindFirstChild("Head")
  204.    
  205.     local Ennemy = self:GetEnnemy()
  206.     local EnnemyHumanoid: Humanoid?
  207.  
  208.     local TweenInf = TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
  209.  
  210.     TweenService:Create(ShotgunModel, TweenInf, {CFrame = UpPosition}):Play()
  211.    
  212.     task.wait(1)
  213.    
  214.     local highlight = Instance.new("Highlight", ShotgunModel)
  215.     highlight.Adornee = ShotgunModel
  216.     highlight.OutlineColor = Color3.fromRGB(255, 255, 255)
  217.     highlight.FillTransparency = 1
  218.        
  219.         if Type == "Ennemy" then
  220.  
  221.             local lookAt = CFrame.new(ShotgunModel.Position, OwnerHead.Position * Vector3.new(-1, 1, 1))
  222.             TweenService:Create(ShotgunModel, TweenInf, {CFrame = lookAt}):Play()
  223.  
  224.             task.wait(1)
  225.  
  226.             local removedBullet = self:SmartRemoveAmmo("any")
  227.  
  228.             if removedBullet then
  229.                 local isReal = removedBullet == "Real"
  230.                 highlight.FillColor = isReal and Color3.new(1, 0, 0) or Color3.new(0.635294, 0.635294, 0.635294)
  231.                 highlight.FillTransparency = 0
  232.            
  233.                 if isReal then
  234.                     EnnemyHumanoid = self:GetEnnemy().Character.Humanoid
  235.                     EnnemyHumanoid:TakeDamage(RevHealth)
  236.                 end
  237.             end
  238.  
  239.         elseif Type == "Himself" then
  240.  
  241.             local lookAt = CFrame.new(ShotgunModel.Position, OwnerHead.Position)
  242.             TweenService:Create(ShotgunModel, TweenInf, {CFrame = lookAt}):Play()
  243.  
  244.             task.wait(1)
  245.  
  246.             local removedBullet = self:SmartRemoveAmmo("any")
  247.  
  248.             if removedBullet then
  249.                 local isReal = removedBullet == "Real"
  250.                 highlight.FillColor = isReal and Color3.new(1, 0, 0) or Color3.new(0.635294, 0.635294, 0.635294)
  251.                 highlight.FillTransparency = 0
  252.            
  253.             if isReal then
  254.                     OwnerHumanoid = Owner.Character.Humanoid
  255.                     OwnerHumanoid:TakeDamage(RevHealth)
  256.                 end
  257.             end
  258.  
  259.         end
  260.        
  261.     if AI and Owner == "AI" then
  262.        
  263.         local aiChoice: ShootType = (math.random(1, 2) == 1 and "Ennemy" or "Himself") :: ShootType
  264.         local target = self:GetEnnemy().Character["Head"].Position :: Vector3
  265.         local targetPosition = aiChoice == "Ennemy" and target or target * Vector3.new(-1, 1, 1)
  266.         local lookAt = CFrame.new(ShotgunModel.Position, targetPosition)
  267.  
  268.         TweenService:Create(ShotgunModel, TweenInf, {CFrame = lookAt}):Play()
  269.        
  270.         task.wait(1)
  271.  
  272.         local removedBullet = self:SmartRemoveAmmo("any")
  273.         local EnnemyHumanoid = Ennemy.Character.Humanoid :: Humanoid
  274.  
  275.         if removedBullet then
  276.            
  277.             local isReal = removedBullet == "Real"
  278.             highlight.FillColor = isReal and Color3.new(1, 0, 0) or Color3.new(0.635294, 0.635294, 0.635294)
  279.             highlight.FillTransparency = 0
  280.            
  281.             if isReal then
  282.                 if aiChoice == "Ennemy" then
  283.                     EnnemyHumanoid:TakeDamage(RevHealth)
  284.                 elseif aiChoice == "Himself" then
  285.                     self.AIstats.Health -= RevHealth
  286.                 end
  287.             end
  288.            
  289.         end
  290.        
  291.     end
  292.    
  293.     Debris:AddItem(highlight, .5)
  294.     TweenService:Create(ShotgunModel, TweenInf, {CFrame = BasePosition}):Play()
  295.    
  296.     self.Owner = Ennemy
  297.    
  298.     -- Check if one of the player die
  299.    
  300.     if not self.AI then
  301.         if (OwnerHumanoid and OwnerHumanoid.Health == 0) or
  302.             (EnnemyHumanoid and EnnemyHumanoid.Health == 0) then
  303.             self:EndGame()
  304.             return
  305.         end
  306.  
  307.     elseif self.AI then
  308.         local realPlayer, _ = self:GetRealPlayer()
  309.         if (self.AIstats.Health <= 0) or
  310.             (realPlayer.Character.Humanoid.Health == 0) then
  311.             self:EndGame()
  312.             return
  313.         end
  314.     end
  315.    
  316.     if self.Owner == "AI" then
  317.         task.wait(1)
  318.         self:ShootEvent()
  319.     elseif self.Owner ~= "AI" then
  320.         InitEvent:FireClient(self.Owner, self.Owner) -- make the Ennemy play
  321.     end
  322.    
  323. end
  324.  
  325.  
  326. function Buckshoot:AddAmmo(type: AmmoType, amount: number)
  327.     assert(amount >= 0, "Amount must be non-negative")
  328.     self.Ammo[type] = math.min(10, self.Ammo[type] :: number + amount)
  329.     print(string.format("Ajout� %d munitions %s (Total: %d)", amount, type, self.Ammo[type]))
  330. end
  331.  
  332. function Buckshoot:RemoveAmmo(type: AmmoType, amount: number)
  333.     assert(amount >= 0, "Amount must be non-negative")
  334.     self.Ammo[type] = math.max(0, self.Ammo[type] :: number - amount)
  335.     print(string.format("Retir� %d munitions %s (Total: %d)", amount, type, self.Ammo[type]))
  336. end
  337.  
  338. --// Func SmartRemoveAmmo
  339. function Buckshoot:SmartRemoveAmmo(mode: string): AmmoType?
  340.     --// mode: "real", "blank", "any"
  341.     local realAmmo = self.Ammo["Real"]
  342.     local blankAmmo = self.Ammo["Blank"]
  343.  
  344.     local canRemoveReal = realAmmo > 0
  345.     local canRemoveBlank = blankAmmo > 0
  346.  
  347.     if mode == "Real" and canRemoveBlank then
  348.        
  349.         self:RemoveAmmo("Blank", 1)
  350.         return "Blank"
  351.  
  352.     elseif mode == "Blank" and canRemoveReal then
  353.        
  354.         self:RemoveAmmo("Real", 1)
  355.         return "Real"
  356.  
  357.     elseif mode == "any" then
  358.        
  359.         local Options = {}
  360.  
  361.         if canRemoveReal then
  362.             table.insert(Options, "Real")
  363.         end
  364.  
  365.         if canRemoveBlank then
  366.             table.insert(Options, "Blank")
  367.         end
  368.  
  369.         if #Options > 0 then
  370.            
  371.             local Chosen = Options[math.random(1, #Options)] :: AmmoType
  372.             self:RemoveAmmo(Chosen, 1)
  373.             return Chosen
  374.            
  375.         end
  376.        
  377.     end
  378.     -- Nil = no more ammo
  379.     return nil
  380.    
  381. end
  382.  
  383. function Buckshoot:GetEnnemy(): Plr
  384.     for _, p in pairs(self.Players) do
  385.         if p ~= self.Owner then
  386.             return p
  387.         end
  388.     end
  389.     return self.Players[1] -- for error: Not all codepaths return 'Player'
  390. end
  391.  
  392. function Buckshoot:GetRandomPlayer(): Plr
  393.     return self.Players[math.random(1, 2)]
  394. end
  395.  
  396. function Buckshoot:GetRealPlayer(): (Player, number)
  397.     for _, p in ipairs(self.Players) do
  398.         if p ~= "AI" then
  399.             return p, _
  400.         end
  401.     end
  402.     return self.Players[1], 0 -- for error: Not all codepaths return 'Player'
  403. end
  404.  
  405. return Buckshoot
Tags: lua
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement