How should I create something like hunger or thirst?

This is pretty much one of those best way threads. Anyways, what would be a good way to achieve this without having idiots reconnecting to fill up the hunger/thirst bar?

My dumb way I would try to do it is keep a table and when they leave grab their steamid and find their spot in the table and change / add a variable in their little spot and put in their current hunger / thirst. Then when they join get their latest hunger / thirst and assign it to them then clean the variable out? Probably a much easier way to do it, just my thought :smiley:

In **[Gamemode.PlayerDisconnected

http://wiki.garrysmod.com/favicon.ico](wiki.garrysmod.com/?title=Gamemode.PlayerDisconnected)** save their hunger and thirst with **[Player.SetPData

http://wiki.garrysmod.com/favicon.ico](http://wiki.garrysmod.com/?title=Player.SetPData)** and then in **[Gamemode.PlayerConnect

http://wiki.garrysmod.com/favicon.ico](wiki.garrysmod.com/?title=Gamemode.PlayerConnect)** check to see if it has a value stored with **[Player.GetPData

http://wiki.garrysmod.com/favicon.ico](http://wiki.garrysmod.com/?title=Player.GetPData)** if it does, use that value if not give them the default values.

Do what he said but create metatables and timers to adjust when and how much hunger the player uses.

^ don’t do that, do curtime checks

This probably sounds like the best choice, thanks for the suggestion.

Edit:

Would it be a good idea to allow manual and auto saving just in case the server crashes?

I would do auto(on a 5 min timer that starts when the player connects) and have a command they can use when paranoid(just used all their resources to get full), but I’d also put a limit on how often they can save as to avoid server abuse.



-- This would be on initial spawn

if ( pl:GetPData("Hunger") == "Hungry" ) then
	timer.Create( "HungryKiller", 10, 0, function()
		if ( pl:GetPData("Hungry") == "NotHungry" ) then
				timer.Destroy("HungryKiller")
			elseif( pl:Health() - 15 > 0 ) then
			 pl:SetHealth( pl:Health() - 15 )
			else
			 pl:Kill()
		end
end )
else
	pl:SetPData("Hungry", "NotHungry")
	timer.Create( "MakeHungry", 1200, 0, function()
		ply:SetPData("Hungry", "Hungry")
			timer.Create( "HungryKiller", 10, 0, function()
		if ( pl:GetPData("Hungry") == "NotHungry" ) then
				timer.Destroy("HungryKiller")
			elseif( pl:Health() - 15 > 0 ) then
			 pl:SetHealth( pl:Health() - 15 )
			else
			 pl:Kill()
		end
end )
    end )
end

-- then you have a code in like a entity or something that sets pl:SetPData("Hungry", "NotHungry")



switch the two lines of text below this around, i’m too lazy to switch them myself…

also don’y do timer saving like in the post above, save it everytime the hunger/thirst updates
wooooo stoned code for the win! btw this mehod is like the worst way to do this so… just an idea

Wouldn’t it be better to have 100 for the hunger PData instead of “NotHungry”? Also, how could I save every time the hunger/thirst updates without it being a timer? The hunger loss is going to happen every X amount of seconds. The only way I can think of a way to do this is if your hunger reaches 75, 50, or 25 percent.

(Sorry for all the questions, I’m not a very good LUA coder.)

If the hunger changes every few seconds, my idea of a 5 min timer is a hell of a lot better.

I currently have a five minute time that saves all stats including hunger, thirst, and fatigue.

Do something like this
[lua]
function info:SetHunger(amt)
self.Hunger = amt
umsg.Start(“Hunger”,self)
umsg.Long(amt)
umsg.End()
self:SetPData(“Hunger”,amt)
end

function info:GetHunger()
	return self.Hunger or 0
end

function info:AddHunger(amt)
	self:SetHunger(self:GetHunger()+amt)
end

function info:TakeHunger(amt)
	self:SetHunger(math.Max(0,self:GetHunger()-amt))
end

[/lua]

So everytime you add/take hunger it saves itself making it so no timer is required to save anything.

Once again, if the hunger changes every few seconds, then you are saving the data every few seconds, eating up system resources, all you need is on disconnect to save and a timer that runs every 3-5+ minutes , any more often is unnecessary.

that idea I wrote was fueled by the bong.

by the way, in real life I don’t think about “Hm, I’m only 50 hungry I don’t need to eat.”.

I’m hungry or I’m not hungry.

Well gamemodes that are completely realistic aren’t always fun. Besides, a percent will hint to players that they need to get food or water ready.

True that.

By the way Gatekeeper, since using those PData methods error on client and all ( there your HUD ), why don’t you get just use a networked variable instead, create a function to save the data when they leave, or in an interval, etc… To save data using PData. It doesn’t seem like you’re doing that.

The PData is just for saving, I’m using another variable for hunger when the player is actually connected.

Example: A player joins and the game checks to see if that player has the PData saved, if not the player gets his/her PData set up. After that happens, the person gets another variable that will be the actual hunger meter. Every five minutes the hunger will save to PData. When that player disconnects, it gets the value of the variable and saves it to PData.

I know that receiving PData or changing it too much will probably not produce a good result.

Or use usermessages