Disease System and Cures

DiseaseSystemTesting.rbxl (24.7 KB)

ServerScriptService → Diseases

local Diseases = {
	["Flu"] = {
		["WalkspeedReduction"]=.1,
		["WalkspeedReductionInterval"] = 8,
		["HealthReduction"]=2.5,
		["HealthReductionInterval"]=1,
		["Duration"]=60,
	},
	["Tuberculosis"] = {
		["WalkspeedReduction"]=.4,
		["WalkspeedReductionInterval"] = 8,
		["HealthReduction"]=2.5,
		["HealthReductionInterval"]=0.6,
		["Duration"]=120,
	},
	["Cold"] = {
		["WalkspeedReduction"]=.2,
		["WalkspeedReductionInterval"] = 8,
		["HealthReduction"]=2.5,
		["HealthReductionInterval"]=1,
		["Duration"]=30,
	}
}


local PlayerInfections={}


function PickRandomDisease()
	local Disease = nil
	local DiseasesAmount = 0
	local DiseaseName = nil
	for i,v in pairs(Diseases) do
		DiseasesAmount += 1
	end
	local RandomNumber = math.random(1,DiseasesAmount)
	local Index = 0
	for i,v in pairs(Diseases) do
		Index += 1
		if Index == RandomNumber then
			Disease = Diseases[i]
			DiseaseName = i
			break
		end
	end
	return {Disease, DiseaseName}
end


function InfectPlayer(Player, Disease)
	-- {(PlayerObject)Player, (Table)DiseaseObjects}
	local Character = Player.Character or Player.CharacterAdded:Wait()
	repeat
		wait(0.25)
		Character = Player.Character or Player.CharacterAdded:Wait()
	until
		Character ~= nil
	
	local Found = nil
	for i,v in pairs(PlayerInfections) do
		if v[1] == Player then
			Found = PlayerInfections[i]
			break
		end
	end
	if Found ~= nil then
		table.insert(Found[2], Disease)
	else
		Disease.ContractionTime = tick()
		table.insert(PlayerInfections, {Player, {Disease}})
	end
end


function InfectRandomPlayerWithRandomDisease()
	local Players = game.Players:GetPlayers()
	local RandomNumber = math.random(1,#Players)
	local Player = Players[RandomNumber]
	local Disease = PickRandomDisease()
	InfectPlayer(Player, Disease[1])
	return {Player, Disease}
end


function CurePlayer(Player, Disease)
	if type(Disease) == "string" then
		if Disease == "-all" then
			for i,v in pairs(PlayerInfections) do
				-- {(PlayerObject)Player, (Table)DiseaseObjects}
				if v[1] == Player then
					v[2] = {}					
					return true
				end
			end
		end
	end
	for i,v in pairs(PlayerInfections) do
		-- {(PlayerObject)Player, (Table)DiseaseObjects}
		if v[1] == Player then
			for x,c in pairs(v[2]) do
				if tostring(c) == tostring(Disease) then
					table.remove(v[2], x)
					return true
				end
			end
		end
	end
end



coroutine.wrap(function()
	while true do
		wait()
		for i,v in pairs(PlayerInfections) do
			-- {(PlayerObject)Player, (Table)DiseaseObjects}
			for x,c in pairs(v[2]) do
				if c.ContractionTime ~= nil then
					if tick() - c.ContractionTime >= c.Duration then
						CurePlayer(v[1], c)
						continue
					end
				else
					c.ContractionTime = tick()
				end
				if c.LastHealthReduction ~= nil then
					if tick() - c.LastHealthReduction >= c.HealthReductionInterval then
						c.LastHealthReduction = tick()
						local Character = v[1].Character
						if Character ~= nil then
							local Humanoid = Character["Humanoid"]
							if Humanoid ~= nil then
								Humanoid:TakeDamage(c.HealthReduction)
							end
						else
							CurePlayer(v[1], "-all")
							break
						end
					end
				else
					c.LastHealthReduction = tick()
					local Character = v[1].Character
					if Character ~= nil then
						local Humanoid = Character["Humanoid"]
						if Humanoid ~= nil then
							Humanoid:TakeDamage(c.HealthReduction)
						end
					else
						CurePlayer(v[1], "-all")
						break
					end
				end
				
				if c.LastWalkspeedReduction ~= nil then
					if tick() - c.LastWalkspeedReduction >= c.WalkspeedReductionInterval then
						c.LastWalkspeedReduction = tick()
						local Character = v[1].Character
						if Character ~= nil then
							local Humanoid = Character["Humanoid"]
							if Humanoid ~= nil then
								Humanoid.WalkSpeed -= c.WalkspeedReduction
							end
						else
							CurePlayer(v[1], "-all")
							break
						end
					end
				else
					c.LastWalkspeedReduction = tick()
					local Character = v[1].Character
					if Character ~= nil then
						local Humanoid = Character["Humanoid"]
						if Humanoid ~= nil then
							Humanoid.WalkSpeed -= c.WalkspeedReduction
						end
					else
						CurePlayer(v[1], "-all")
						break
					end
				end
			end
		end
	end
end)()


local CurePlayerBindableFunction = script:WaitForChild("CurePlayer")
CurePlayerBindableFunction.OnInvoke = function(Player, Disease)
	CurePlayer(Player, Disease)
	return true
end


while true do
	wait()
	if #game.Players:GetPlayers() > 0 then
		local Result = InfectRandomPlayerWithRandomDisease()
		--print("Infected "..Result[1].Name.." With "..Result[2][2])
		wait(180)
	end
end

StarterPack → Universal Cure → CureScript

local Tool = script.Parent
local Handle = Tool.Handle
local Needle = Tool.Needle
local Tank = Tool.Tank
local TotalUses = 1
local CureFunction = game.ServerScriptService:WaitForChild("Diseases").CurePlayer
local Uses = 0
local InUse = false
local Target = nil
local TargetSelectedPart = nil
local Cooldown = 1
local LocalPlayer = nil


Tool.Name = "Univseral Cure ("..TotalUses-Uses..")"


Needle.Touched:Connect(function(hit)
	local Player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if Player ~= LocalPlayer and LocalPlayer ~= nil and Player ~= nil then
		Target = {Player, Player.Character}
		TargetSelectedPart = hit
		Tool.Name = "UC ("..TotalUses-Uses..") - Inject: "..Player.Name
	end
end)


Needle.TouchEnded:Connect(function(hit)
	if Target ~= nil then
		if (Target[2].HumanoidRootPart.Position - Handle.Position).Magnitude < 5 and hit == TargetSelectedPart then
			Tool.Name = "UC ("..TotalUses-Uses..") - Inject: "..Target[1].Name
		else
			Target = nil
			Tool.Name = "Univseral Cure ("..TotalUses-Uses..")"
		end
	end
end)


Tool.Equipped:Connect(function()
	if LocalPlayer == nil then
		LocalPlayer = game.Players:GetPlayerFromCharacter(Tool.Parent)
	end
end)


Tool.Activated:Connect(function()
	if Target ~= nil and not InUse and Uses < TotalUses then
		InUse = true
		local Result = CureFunction:Invoke(Target[1], "-all")
		if Result ~= true then
			InUse = false
			return
		end
		Uses += 1
		Tool.Name = "Univseral Cure ("..TotalUses-Uses..")"
		if Uses >= TotalUses then
			Tank.Color = Color3.fromRGB(255,255,255)
		end
		wait(Cooldown)
		InUse = false
	elseif Target == nil and not InUse and Uses < TotalUses then
		InUse = true
		local Result = CureFunction:Invoke(LocalPlayer, "-all")
		if Result ~= true then
			InUse = false
			return
		end
		Uses += 1
		Tool.Name = "Univseral Cure ("..TotalUses-Uses..")"
		if Uses >= TotalUses then
			Tank.Color = Color3.fromRGB(255,255,255)
		end
		wait(Cooldown)
		InUse = false
	end
end)