I am working about map voting pad system

Sorry about my english grammar

  1. I am working about map voting pad system but i don’t know how to put my voting x2 gamepass in my script

  2. Picture of map voting model

  3. I tried every but is a lot of bug on map voting pad idk how to fix it

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

Here MapVotingScript module

local plrs = game:GetService("Players")
local rep = game:GetService("ReplicatedStorage")

local module = {}

local status = game.ReplicatedStorage.Values.Status

local mapVotes = {}

local Assets = rep:WaitForChild("Assets")
local maps = Assets:WaitForChild("Maps")
local Events = rep:WaitForChild("Events")
local Values = rep:WaitForChild("Values")

local x2VotesID = 166803693

-- Example:

--mapVotes = {
	---1;
	--Desert;
	--players = {
		--AnoB0t;
	--}
--}

local VotingPads = workspace:WaitForChild("VotingPads")

local skipTime = Values:WaitForChild("skipTime")

local function givePerk(plr)
	local plrSettings = plr:WaitForChild("PlayerSettings")
	if not plrSettings then return end

	plrSettings.multiplierVotes.Value = 2
end

Events.PlaceVote.OnServerEvent:Connect(function(player, padNumber)
	-- Check if player already voted
	for i,v in pairs(mapVotes) do
		for x,plr in pairs(v.players) do
			if plr == player.UserId then
				table.remove(v.players, x)
				break
			end
		end
	end
	
	-- Place vote
	for i,v in pairs(mapVotes) do
		-- Check which player voted on
		if v.order == padNumber then
			table.insert(v.players, player.UserId)
		end
	end
end)

function getMap()
	local randomMap = maps:GetChildren()[math.random(1,#maps:GetChildren())]
	
	for i,v in pairs(mapVotes) do
		-- if map exists in the table
		if v.name == randomMap.Name then
			return getMap()
		end
	end
	
	return randomMap.Name
end

function module.MapVoting(dur)

	-- Start the voting system
	mapVotes = {}
	
	for i,v in pairs(VotingPads:GetChildren()) do
		table.insert(mapVotes,{order = tonumber(v.Name:match("%d+")); name = getMap(); players = {};})
		
		v.Color = Color3.fromRGB(255,0,0)
	end
	
	Values.MapVotingProgress.Value = true
	
	local start = tick()
	
	while wait() do
		-- Check if number of seconds passed the maxDuration
		if not skipTime.Value then
			if tick()-start >= dur then break end

			status.Value = math.floor(dur-(tick()-start))

			-- Update the pads
			for i,v in pairs(VotingPads:GetChildren()) do
				local votes,mapName
				for x,map in pairs(mapVotes) do
					-- Check if the order match the pads number
					if map.order == tonumber(v.Name:match("%d+")) then
						votes = #map.players
						mapName = map.name
						break
					end
				end

				v.Display.SurfaceGui.MapName.Text = mapName
				v.Display.SurfaceGui.VoteCount.Text = votes
			end
		else
			skipTime.Value = false
			status.Value = 0
			break
		end
	end
	
	Values.MapVotingProgress.Value = false
	
	-- Sort the votes, we get the winner
	table.sort(mapVotes, function(a,b)	return #a.players > #b.players end)
	
	for i,v in pairs(VotingPads:GetChildren()) do
		v.Color = Color3.fromRGB(80,80,80)
	end
	
	--status.Value = mapVotes[1].name.." was chosen!"
	
	wait(3)
	
	return maps:FindFirstChild(mapVotes[1].name)
end

return module

local script

local plrs = game:GetService("Players")
local rep = game:GetService("ReplicatedStorage")
local runs = game:GetService("RunService")
local ts = game:GetService("TweenService")

local player = plrs.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hrp = char:WaitForChild("HumanoidRootPart", 5)

local currentVote = nil

local VotingPads = workspace:WaitForChild("VotingPads")

local Assets = rep:WaitForChild("Assets")
local Events = rep:WaitForChild("Events")
local Values = rep:WaitForChild("Values")
local Maps = Assets:WaitForChild("Maps")

--script.Parent:WaitForChild("INTRO").Enabled = true

-- When a voting starts or ends
Values.MapVotingProgress:GetPropertyChangedSignal("Value"):Connect(function()
	currentVote = nil
end)

runs.RenderStepped:Connect(function()
	-- Check if voting started
	if Values.MapVotingProgress.Value then
		local raycastParams = RaycastParams.new()
		raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
		raycastParams.FilterDescendantsInstances = {char:GetChildren()}

		local result = workspace:Raycast(hrp.CFrame.p, Vector3.new(0,-10000,0),raycastParams)

		if result then
			local object = result.Instance

			-- If player touch the pad
			if object and object.Name:match("Pad") then
				local padNumber = tonumber(object.Name:match("%d+"))

				Events.PlaceVote:FireServer(padNumber)

				if currentVote == nil or currentVote ~= padNumber then
					local sfx = Instance.new("Sound",script.Parent)
					sfx.SoundId = "rbxassetid://4676738150"
					sfx.Volume = 1; 
					sfx:Play()
					task.spawn(function() 
						task.wait(1) 
						sfx:Destroy() 
					end)
					
					currentVote = padNumber

					for i,v in pairs(VotingPads:GetChildren()) do
						v.Color = Color3.fromRGB(255,0,0)
					end
					
					Events:WaitForChild("TweenPads"):FireServer(object)

					object.Color = Color3.fromRGB(255,255,0)
				end
			end
		end
	end
end)

I get this script from youtube channel @Anobot I must thank you so him

3 Likes

If you guy reply or comment in here , I will answer at morning … i have to go bed now

1 Like

Can you send us the error?

it seems way too complicated just for a voting script from my view…

I think it could have been done in an easier way

It sent no error for me because idk how to put my game pass x2 voting I don’t know which line to put it in.

So what the easy way? Example?

I mean you can make the gamepass check on player join, or whenever player character added or even value change

since gamepass is permanent, you can make it change a value thats bound to datastore from 1 to 2 so uh… I think it can be really be made into something easier with touching buttons

I mean you can make a folder with players names like “Votes”

whenever player joins its created and whenever player leaves its deleted

then you can add vote buttons a script to grab button name and add it value under the name of player thats in the vote

you can make vote buttons change their names depending on the next map coming when choosing etc.

I reallly need a whole script to make this happen but I feel too lazy…
Think it in more simpler way, no need for complicated things just to vote map

1 Like

Ok i’ll try my best if I can on my map voting pad

If it don’t work I maybe look for another new map voting pad script in YouTube

The way you are getting the pad is inaccurate, with the system you have now, I suggest adding the player twice inside the table of the map he choose if he has the gamepass.

I suggest to abort this way tbh.

Do something like this

local Maps = {
["Desert"] = 0,

}
local Players = {

}

function AddPlayer(plr)
     local IsGamePass = false
 -- check if he has a gamepass and change the bool value
     Players[plr.UserId] = {
  ["Map"]  = "",
   ["IsGamePass"] = IsGamePass
} 
end

function VoteEvent(plr, Vote)
          Players[plr.Userid].Map = Vote
end


function GetVotedMap()        
        for i,v in pairs(Players) do
                 if v.IsGamePass then
                          Maps[v.Map] += 2
                        else
                            Maps[v.Map] += 1
                end
        end
           -- find the highest voted map inside the map Table and return it. / reset the map's table values
end

This is the main idea of the server sided script, for the client you would have to use something like.Touched or region3 you choose, But note that you have to check if the map they fired does exits so the script doesn’t error.

you can also just add +1 or +2 to the map’s table based on if he has a gamepass or not and then the function GetVoted maps would only get the highest value inside the map’s table. thus you wouldn’t need the
Players hashtable

Whenever the Player steps on the Button to Include a check for when they have the Pass purchased using UserOwnsGamePassAsync()

local Owned = MarketplaceService:UserOwnsGamePassAsync(UserId, PassId)
-- to check if they own the pass

local Amount = Owned and 2 or 1 -- another way of saying: if owned then give 2 else give 1
-- check if the Player Owns this pass and has pressed another button, and if so
-- Remove the Amount given, otherwise add to the said Voting Booth, and keep track
-- of which one they pressed.

I’ve implemented some of this functionality into the explanation below. If you want the voting system to be easier to manage, store the votes in an object-oriented system where each pad represents a voteCasting object and players can cast their votes to that object. You can then add up the votes for each object to see which one has the most.

Double-casted votes are accounted for on player-join, and they are validated with the userCanDoubleVote function.

local playersService = game:GetService('Players')
local marketplaceService = game:GetService('MarketplaceService')
local playersWithDoubleVote = {}

playersService.PlayerAdded:Connect(function(player: Player)
	local userOwnsGamepass = select(2, pcall(marketplaceService.UserOwnsGamePassAsync, marketplaceService, player.UserId, 166803693))

	if userOwnsGamepass == true then
		table.insert(playersWithDoubleVote, player.UserId)
	end
end)

local function userCanDoubleVote(player: Player)
	return table.find(playersWithDoubleVote, player.UserId) and true or false
end

local voteCasting = {}

function voteCasting.new()
	local self = {}
	local votesCasted = {}

	function self:CastVote(player: Player)
		if not votesCasted[player.UserId] then
			votesCasted[player.UserId] = userCanDoubleVote(player) and 2 or 1
		end
	end

	function self:RevokeVote(player: Player)
		if votesCasted[player.UserId] then
			votesCasted[player.UserId] = nil
		end
	end

	function self:GatherVotes()
		local totalVotes = 0

		for _, votes in pairs(votesCasted) do
			totalVotes = totalVotes + votes
		end

		return totalVotes
	end

	function self:ClearVotes()
		votesCasted = {}
	end

	return self
end

Now I’ll show you how you can use this code. I generated the next block of code with ChatGPT to provide you this example, I believe it is an okay example.

-- Create three different voting instances
local voteOne = voteCasting.new()
local voteTwo = voteCasting.new()
local voteThree = voteCasting.new()

-- Players cast different numbers of votes for each instance
voteOne:CastVote(player1)
voteOne:CastVote(player2)

voteTwo:CastVote(player3)
voteTwo:CastVote(player4)
voteTwo:CastVote(player5)

voteThree:CastVote(player6)
voteThree:CastVote(player7)
voteThree:CastVote(player8)
voteThree:CastVote(player9)

-- Gather and print the total votes for each voting instance
local totalVotesOne = voteOne:GatherVotes()  -- Total votes for VoteOne: 2
local totalVotesTwo = voteTwo:GatherVotes()  -- Total votes for VoteTwo: 3
local totalVotesThree = voteThree:GatherVotes()  -- Total votes for VoteThree: 4

I made a post thanks to you and to my motivation to make something useful, you can find it here.

Async without pcall not good scripting practice you should include it

You really don’t need a Complicated Script just to make a Map Voting system guys…

Here is something you can make:

image

When playerjoins, Clone Player1 and Change its name to player’s name

When they touch Change NowVote.Value (its a string value)
Change it to Map’s Name
Check CurrentVote
Whenever NowVote Changes
if CurrentVote.Value ~= NowVote.Value and CurrentVote.Value ~= Empty (or any value you put) then
Remove 1 vote from CurrentVote, Change value to NowVote
elseif CurrentVote.Value == NowVote.Value
print(“Already Voted Same Map”)
elseif CurrentVote.Value == Empty (or any value you put) then
Make CurrentVote.Value to NowVote.Value
then add 1 Vote to MapX

etc. etc.
its not that actually hard

when player removes remove Player from Votes Folder

its more like, thinking simple rather than making long long codes to check everything etc.

Sorry for answer late, I’ll try