Author Topic: Prevent multiple parallel calls of OnDeath function?  (Read 1514 times)

0 Members and 1 Guest are viewing this topic.

Offline Luk | twitch.tv/doctorluk

  • Newbie
  • *
  • Posts: 40
  • Karma: 12
Prevent multiple parallel calls of OnDeath function?
« on: September 12, 2016, 10:49:24 AM »
Hello everyone!

I'm currently making a "Karma Betting" plugin for TTT.

Players who spectate or are dead can bet a portion of their karma for the innocent or traitor team and win/lose according to the outcome. The result is also saved in a MySQL database for bragging and stuff.

The problem I have is the following:
TTT - for some odd reason - does not reliably call "TTTRoundEnd" whenever a round ends. I have no idea why. So I tried using the "PlayerDeath" event which worked nicely until I noticed that when multiple players are killed simultanously, the function which gives out the rewards and saves them in the MySQL table is called the same amount of times and I can't seem to make it only run "once". Variables seem to be defined/changed in the exact same moment which is why none of the functions stops as "KARMABET_HAS_RUN" is being set to true initially when conditions are met.

Here is the function in question:
Code: [Select]
-- Act after a round has ended
function karmabet_onPotentialEnd( callback_data )

timer.Simple( 0.005, function()

if GetRoundState() == ROUND_ACTIVE or isnumber( callback_data ) and not KARMABET_HAS_RUN then

if karmabet_CheckForWin() == WIN_NONE then return end

KARMABET_HAS_RUN = true

timer.Remove( "karmabet_timer_timewarning" )
timer.Remove( "karmabet_timer" )

if isnumber(callback_data) then
ServerLog("TIMER KILLED + ROUND END!!\n")
else
ServerLog("TIMER KILLED + DEATH EVENT!!\n")
end

local winner = "innocent"
local loser_amount = t_bet_total

if karmabet_CheckForWin() == WIN_TRAITOR then
winner = "traitor"
loser_amount = i_bet_total
end

karmabet_winner = winner

ServerLog("KARMABET WINNER: " .. winner .. "\n")

-- PrintTable( tbl_betters )

-- Winners get their bet, and a bonus depending on the amount of bets against them
for id, entry in pairs( tbl_betters ) do

local ply = player.GetBySteamID( id )
if ply then
local amount = entry[1]
local target = entry[2]

if target == winner then

local karmaReturned = math.ceil( amount + ( amount * (math.random(10, 25) / 100) ) + ( loser_amount * (math.random(5, 15) / 100) ) )

tbl_results[id] = { karmaReturned, target }

ULib.tsayColor( nil, false,
Color( 50, 50, 50, 255 ), "[",
Color( 190, 40, 40, 255), "Karmabet",
Color( 50, 50, 50, 255), "] ",
Color( 255, 255, 0, 0 ), ply:Nick(),
Color( 0, 255, 0, 255), " gewinnt ",
Color( 255, 255, 255, 255), karmaReturned .. "",
Color( 0, 255, 0, 255), " Karma!" )

local newKarma = ply:GetLiveKarma() + karmaReturned
if newKarma > 1000 then
newKarma = 1000
end
ply:SetBaseKarma( newKarma )
ply:SetLiveKarma( newKarma )

else

ULib.tsayColor( nil, false,
Color( 50, 50, 50, 255 ), "[",
Color( 190, 40, 40, 255), "Karmabet",
Color( 50, 50, 50, 255), "] ",
Color( 255, 255, 0, 0 ), ply:Nick(),
Color( 255, 0, 0, 255), " verliert ",
Color( 255, 255, 255, 255), amount .. "",
Color( 255, 0, 0, 255), " Karma!" )

tbl_results[id] = { amount, target }
end
end
end

-- PrintTable( tbl_results )
karmabet_insertResultsMySQL()

table.Empty(tbl_betters)
karmabet_refresh()

-- Since we run our Hook AFTER karma has been saved, we have to save it again, otherwise the gained karma
-- is lost upon mapchange
KARMA.Rebase()
KARMA.RememberAll()
end
end)
end
hook.Add( "PlayerDeath", "karmabet_onPotentialEnd", karmabet_onPotentialEnd )
hook.Add( "TTTRoundEnd", "karmabet_onPotentialEnd", karmabet_onPotentialEnd )

Is there any other way to reliably react to a player's death or a reason why TTTRoundEnd sometimes does not trigger?
Host of Spielwiese der Erwachsenen, a German TTT Server for adults only.

Offline roastchicken

  • Respected Community Member
  • Sr. Member
  • *****
  • Posts: 476
  • Karma: 84
  • I write code
Re: Prevent multiple parallel calls of OnDeath function?
« Reply #1 on: September 12, 2016, 12:30:39 PM »
TTTRoundEnd is not a valid hook. I have no idea why your code even ran in the first place with this hook, as it isn't in the TTT gamemode nor anywhere in the default Garry's Mod files. The hook to be called when the round ends is TTTEndRound, as per the TTT Hooks List. Hopefully this solves your problem.
Give a man some code and you help him for a day; teach a man to code and you help him for a lifetime.

Offline Luk | twitch.tv/doctorluk

  • Newbie
  • *
  • Posts: 40
  • Karma: 12
Re: Prevent multiple parallel calls of OnDeath function?
« Reply #2 on: September 12, 2016, 12:40:51 PM »
Sometimes it's the most stupid mistakes one can make. No idea how I got that wrong. I'll be testing if all the PlayerDeath stuff is necessary now. Thank you very much!
Host of Spielwiese der Erwachsenen, a German TTT Server for adults only.