How to make stamina Refill

09/26/2011 23:53 shadowman123#1
i wanted to write a code such that when i Sit with my horse stamina start refilling ..what came on my mind is smthing like that
Code:
if (attacker.Action == Enums.ConquerAction.Sit)
                        {
                            if (attacker.Stamina <= 0)
                            {
                                attacker.Stamina += 40;
                            }
                         }
but it doesnt Work ..Could sm1 help me in that ?
09/27/2011 01:04 Mr_PoP#2
you need a timer so the timer keeps looping and checking if u sit or not if sit then increase it

so the timer loop check
Code:
if(hero.Action == Sit) {
                if(hero.Stamina <= 95) {
                    hero.Stamina += 5;
                } else {
                    if(hero.Stamina <= 99) {
                        hero.Stamina += 1;
                    }
                }
note: u should change the Maximum of ur Stamina depending on if the Hero has Bless time or not.
09/27/2011 01:25 Spirited#3
"if (attacker.Stamina <= 0)"

How does that even remotely make any sense to you...
Seriously....
09/27/2011 01:28 pro4never#4
Timers are fine but I always cringe a bit when I hear them mentioned for a few reasons...

#1: timers as you are suggesting are PER client. This means each delayed action is a new timer for each person online... Timers aren't exactly inefficient by any means but the way you use them certainly can be.

#2: Disposal! What happens when the client disconnects, the timer elapses and tries to perform actions on something which is disposed or disconnected (IE: Sending stamina update packet to client). There's obviously ways around this and the issue comes up in any threading method but PLEASE be careful of it cause it's an annoying problem to try to debug sometimes.

#3: Related to point one but using a thread or a timer to control some extremely small, simple task such as boosting a value can run into inefficiencies when you start doing it too often... think through things (can I combine this with an existing thread/timer without losing efficiency?!)


I've tried a few methods to go about it and I don't see any of them as being the 'best' but they are options to think about.


1: Global thread which boosts ALL users stamina (can be combined with other threads... generally done in combination with boosting users XP bar). In this model you have a single thread which runs through all users connected, checks the time since last stamina gain (or xp gain), checks their conditions (sitting/laying or not) and then performs an action.

I like this option as it's not taking up many resources. A single thread doing all the work. The issue is if the thread dies for some reason (you coded it wrong for example) then no one on the server can gain stamina till you fix it usually by restarting the server.


2: Use a timer/thread per client.

I dislike this a little bit because of the increased (needless imo) cost of processing it for each user. It's small but lets say we start doing a stamina timer per client, xp timer per client, online training timer per client, auto attack timer per client.... etcetcetc.

How many timers do we really want running at once? Sooner or later that will impact our performance.


Ooh and as for actual code... i'd use something like...

var toUp = 1;
if(user.Action == ActionType.Sit || user.Action == ActionType.Lay)
if(DateTime.Now > user.SatAt.AddMilliseconds(200))//This is when they perform the sit action itself. Stops them from gaining stamina by holding sit key while jumping.
toUp = 6;
user.Stamina = Math.Min(user.Stamina + toUp, user.MaxStamina);
09/27/2011 01:46 BaussHacker#5
Quote:
Originally Posted by Fаng View Post
"if (attacker.Stamina <= 0)"

How does that even remotely make any sense to you...
Seriously....
Maybe he likes to have negative values rofl. However it's most likely a byte, which means it's unsigned, so it cannot have negative values, where signed bytes (sbyte) can have a negative value.

But in the end I don't think he knows what the operators mean.
09/27/2011 02:11 shadowman123#6
Quote:
Originally Posted by Fаng View Post
"if (attacker.Stamina <= 0)"

How does that even remotely make any sense to you...
Seriously....
Rofl ..my bad no1 ever could do that mistake ..but i didnt notice that Really..

Anyways Thx All Alot i Added what i need :)

#request Close
09/27/2011 02:58 Mr_PoP#7
Quote:
Originally Posted by pro4never View Post
Timers are fine but I always cringe a bit when I hear them mentioned for a few reasons...

#1: timers as you are suggesting are PER client. This means each delayed action is a new timer for each person online... Timers aren't exactly inefficient by any means but the way you use them certainly can be.

#2: Disposal! What happens when the client disconnects, the timer elapses and tries to perform actions on something which is disposed or disconnected (IE: Sending stamina update packet to client). There's obviously ways around this and the issue comes up in any threading method but PLEASE be careful of it cause it's an annoying problem to try to debug sometimes.

#3: Related to point one but using a thread or a timer to control some extremely small, simple task such as boosting a value can run into inefficiencies when you start doing it too often... think through things (can I combine this with an existing thread/timer without losing efficiency?!)


I've tried a few methods to go about it and I don't see any of them as being the 'best' but they are options to think about.


1: Global thread which boosts ALL users stamina (can be combined with other threads... generally done in combination with boosting users XP bar). In this model you have a single thread which runs through all users connected, checks the time since last stamina gain (or xp gain), checks their conditions (sitting/laying or not) and then performs an action.

I like this option as it's not taking up many resources. A single thread doing all the work. The issue is if the thread dies for some reason (you coded it wrong for example) then no one on the server can gain stamina till you fix it usually by restarting the server.


2: Use a timer/thread per client.

I dislike this a little bit because of the increased (needless imo) cost of processing it for each user. It's small but lets say we start doing a stamina timer per client, xp timer per client, online training timer per client, auto attack timer per client.... etcetcetc.

How many timers do we really want running at once? Sooner or later that will impact our performance.


Ooh and as for actual code... i'd use something like...

var toUp = 1;
if(user.Action == ActionType.Sit || user.Action == ActionType.Lay)
if(DateTime.Now > user.SatAt.AddMilliseconds(200))//This is when they perform the sit action itself. Stops them from gaining stamina by holding sit key while jumping.
toUp = 6;
user.Stamina = Math.Min(user.Stamina + toUp, user.MaxStamina);
or you can have one Timer per player and that timer handles everything like (stamina/xpbar/flash name etc etc) << thats how am doing it , and when that Player disconnect the Function Dispose .
09/27/2011 10:40 BaussHacker#8
Quote:
Originally Posted by pro4never View Post
Wall of text
I would rather use threads than timers.

Also closing threads:
Code:
Thread.Join();
Thread.Abort();
;P
09/28/2011 00:58 pwerty#9
@pro4never
1 timer that goes over all clients and check for times and update them. But that would make delays for players. More clients, bigger gap ( if Im not wrong)

tho thread sounds more suitable for this (if coded right).
09/28/2011 03:50 pro4never#10
Quote:
Originally Posted by pwerty View Post
@pro4never
1 timer that goes over all clients and check for times and update them. But that would make delays for players. More clients, bigger gap ( if Im not wrong)

tho thread sounds more suitable for this (if coded right).
There's no real difference between timers and threads when it comes to purpose...

They both deal with delayed or timed actions.

Threads obviously server a better use in most 'constant' actions where threads are more often used in something that only happens periodically (many exceptions but that's how I think of it)


As for actual execution time though... when a timer executes its code it's running on a separate thread so there's no real differences there.

The only way you could 'load balance' the code would be to determine how long the code inside took to run and reduce the loop time by that amount.

EXAMPLE:


Code:
while (true)
            {
                System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                sw.Start();
                //RUN YOUR CODE
                sw.Stop();
                Thread.Sleep((int)Math.Max(10, 100 - sw.ElapsedMilliseconds));
            }
Obviously a rather trash example but what I'm saying is that if you have a thread which for some odd reason takes you.... 50 ms to process all of (seems a large amount of processing per thread loop imo... but to each his own!) then you reduce the final thread sleep by 50.

I suggest the Math.Max simply because what happens if you want the thread to run every 100 ms but this loop it fucks up and takes 500 ms to process... you could end up with a negative number and I have no idea what a negative number would do to a thread.sleep.
09/28/2011 08:48 BaussHacker#11
Quote:
Originally Posted by pro4never View Post
I have no idea what a negative number would do to a thread.sleep.
[Only registered and activated users can see links. Click Here To Register...]