-
What do you want to achieve?
I am setting up a turn based combat system, where it is one player’s turn and once they attack it becomes the other player’s turn. Once a player’s HP reaches 0 the game ends and a victor is congratulated. -
What is the issue?
Everything works fine, except that once a player’s HP reaches 0 another turn is allowed by the now dead player. The turns then stop after that, there’s only one extra turn after the game should have ended. I need help as I don’t know how to fix this, I don’t even know why it’s happening, but I assume it has something to do with my logic as there are no errors displayed.
I have one localscript that is in starterplayer and I have one server script which handles most of the turn based system.
Server script:
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
Players.PlayerAdded:Connect(function(player)
local statsFolder = Instance.new("Folder")
statsFolder.Name = "Stats"
local strength = Instance.new("IntValue")
strength.Value = 10
strength.Name = "Strength"
local agility = Instance.new("IntValue")
agility.Value = 10
agility.Name = "Agility"
local defense = Instance.new("IntValue")
defense.Value = 10
defense.Name = "Defense"
local speed = Instance.new("IntValue")
speed.Value = math.random(5,10)
speed.Name = "Speed"
local hp = Instance.new("IntValue")
hp.Value = 10
hp.Name = "HP"
local mana = Instance.new("IntValue")
mana.Value = 10
mana.Name = "Mana"
local level = Instance.new("IntValue")
level.Value = 1
level.Name = "Level"
local xp = Instance.new("IntValue")
xp.Value = 0
xp.Name = "XP"
local gold = Instance.new("IntValue")
gold.Value = 0
gold.Name = "Gold"
local gems = Instance.new("IntValue")
gems.Value = 0
gems.Name = "Gems"
local weapon = Instance.new("IntValue")
weapon.Value = "sword"
weapon.Name = "Weapon"
strength.Parent = statsFolder
agility.Parent = statsFolder
defense.Parent = statsFolder
speed.Parent = statsFolder
hp.Parent = statsFolder
mana.Parent = statsFolder
level.Parent = statsFolder
xp.Parent = statsFolder
gold.Parent = statsFolder
gems.Parent = statsFolder
weapon.Parent = statsFolder
statsFolder.Parent = player
end)
local weapons = {
sword = {
minDamage = 10,
maxDamage = 20,
speedMod = 0
}
}
local turnStartEvent = Instance.new("RemoteEvent")
turnStartEvent.Name = "TurnStartEvent"
turnStartEvent.Parent = ReplicatedStorage
local attackEvent = Instance.new("RemoteEvent")
attackEvent.Name = "AttackEvent"
attackEvent.Parent = ReplicatedStorage
--Wait for two players to join the match
print("Wait started")
repeat
task.wait()
until #Players:GetChildren() == 2
print("Wait complete")
local pList = Players:GetChildren()
local player1 = pList[1]
local player2 = pList[2]
local player1Init = player1:WaitForChild("Stats"):WaitForChild("Speed").Value
local player2Init = player2:WaitForChild("Stats"):WaitForChild("Speed").Value
local gameOver = Instance.new("BoolValue")
gameOver.Name = "GameOver"
gameOver.Parent = ReplicatedStorage
gameOver.Value = false
local function gameOverFunction(winner, loser)
print(winner," wins!")
gameOver = true
-- execute victory screen and send player back to menu
end
local function turnHandler()
--decide whose turn it is
local turn
if player1Init > player2Init then
turn = player1
player1Init = player1Init*0.5
player2Init = player2Init*1.5
elseif player1Init < player2Init then
turn = player2
player2Init = player2Init*0.5
player1Init = player1Init*1.5
elseif player1Init == player2Init then
local random = math.random(1,2)
if random == 1 then
turn = player1
player1Init = player1Init*0.5
player2Init = player2Init*1.5
else
turn = player2
player2Init = player2Init*0.5
player1Init = player1Init*1.5
end
end
--remote event to receive player input
turnStartEvent:FireClient(turn)
--wait until turn finished to end function
attackEvent.OnServerEvent:Wait()
--
end
--receive player input
--attack function
local function attackFunction(attacker)
local target
if attacker == pList[1] then
target = pList[2]
elseif attacker == pList[2] then
target = pList[1]
else
print("attack function target assignment error")
end
local weaponDamage = math.random(weapons["sword"]["minDamage"], weapons["sword"]["maxDamage"])
local attackerStr = attacker.Stats.Strength.Value
local damageOutput = math.round(weaponDamage*(1+(attackerStr/100)))
local damageNegated = target.Stats.Defense.Value
local damageDealt = damageOutput - damageNegated
print(attacker," attacks ",target)
print(damageOutput," dmg output, ",damageNegated," dmg negated, ",damageDealt," total dmg dealt.")
print(target," HP Before attack: ",target.Stats.HP.Value)
target.Stats.HP.Value -= damageDealt
print(target," HP: ",target.Stats.HP.Value)
if target.Stats.HP.Value <= 0 then
gameOverFunction(attacker, target)
end
end
--wrap it all in a loop that ends when a player dies
attackEvent.OnServerEvent:Connect(attackFunction)
while gameOver.Value == false do
print("Turn start!")
turnHandler()
end
LocalScript
local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local attackButton = player.PlayerGui.ScreenGui.AttackButton
humanoid.WalkSpeed = 0
humanoid.JumpHeight = 0
local turnStartEvent = ReplicatedStorage:WaitForChild("TurnStartEvent")
local attackEvent = ReplicatedStorage:WaitForChild("AttackEvent")
local turnActive = false
local gameOver = ReplicatedStorage:WaitForChild("GameOver")
local function turnFunction()
if gameOver.Value == false then
print(player,"'s turn")
turnActive = true
end
end
local function attackButtonClicked()
if turnActive == true then
print("Attack!")
attackEvent:FireServer(player)
turnActive = false
else
print("It is not your turn.")
end
end
attackButton.MouseButton1Click:Connect(attackButtonClicked)
turnStartEvent.OnClientEvent:Connect(turnFunction)