Hi.
I need some help with this script. I don´t know why it´s not working.
The objective for this script it´s to prevent characters to recover stamina when running or if they are in warmode and focus is < 20).
So i used an override to the CanRegenStam method:

Code:
        public override bool CanRegenStam

        {
            get
            {
                if (  ( (Skills[SkillName.Focus].Value < 20) && (Warmode == true) ) || ( ((Direction & Direction.Running) != 0) && ( Core.TickCount - LastMoveTime < 400 ) )  )
                {
                    Emote("Stop");
                    return false;
                }
                else
                {
                    Emote("Recovering");
                    return base.CanRegenStam;
                }
            }
        }


This script works fine when i use a Owner account ( that´s because owners don´t have Stam Loss when moving )

I put the "emote" sentences to debug in game.

But when i use a normal account and for example, start running this happens :

* The script works fine and prevent stam regen ( because CanRegenStam goes false)
* But if the character loses a point of stamina and continues running, ( CanRegenStam goes false only one more time and then the core does not ask again for CanRegenStam method.

So that´s my bug, i don´t know why this is happening.
I checked in the core but found nothing.

Here is the CheckStatTimers method using canRegenStam in the core:

Code:
			if (Stam < StamMax)
			{
				if (CanRegenStam)
				{
					if (m_StamTimer == null)
					{
						m_StamTimer = new StamTimer(this);
					}

					m_StamTimer.Start();
				}
				else if (m_StamTimer != null)
				{
					m_StamTimer.Stop();
				}
			}

Any ideas?
 
Where are you overriding the method, PlayerMobile or elsewhere?

Maybe try placing your custom code in RegenRates.cs. That's where it tells how much to regen; simply place an if statement in the Stam regen method that returns 0 instead of a value and poof, no regen (it works in my head anyway). :D
 
i´m overriding the method in the PlayerMobile.cs in the Scripts/Mobiles/ file (not in the core)

Yes actually i have this code working in the RegenRates.cs,
but in the regenrates, you modify the rate not the ammount of stamina that the char recovers.

The ammount of stamina is hardcoded in the core.

Anyway i use this code and when the if goes true i made a : from.stam -- :p
So it makes not recovering .


but i think that overriding the canregenstam it would be more appropiate.
 
I see what you're getting at now, I misread.

You could also just modify the StamTimer in Mobile.cs with a check for running, etc etc. Currently it only checks whether CanRegenStam is true.

Change:

Code:
protected override void OnTick()
			{
				if (m_Owner.CanRegenStam) // m_Owner.Alive )
				{
					m_Owner.Stam++;
				}

				Delay = Interval = GetStamRegenRate(m_Owner);
			}

To something like (with the rest of your checks):

Code:
protected override void OnTick()
			{
				if (m_Owner.CanRegenStam && m_Owner.Direction != Direction.Running) // m_Owner.Alive )
				{
					m_Owner.Stam++;
				}

				Delay = Interval = GetStamRegenRate(m_Owner);
			}

Edit: Nevermind, you said "characters". This would affect all mobiles....I'm clearly too tired to help tonight!
 
Last edited:
Ok...last idea. You can override the CheckStatTimers in PlayerMobile.cs with a call to a new StamTimer which uses your arguments...
 
I got what you said about modifying OnTick in the Mobile. I think that should work but it means to modify the core. ( i m going to do it if it´s the best way)

But i don´t understand how can i make what you said abaut a call to a new stamTimer wich uses my arguments.
 
Basically, you'd override the entire method CheckStatTimers, from Mobile.cs in PlayerMobile.cs. You'll also recreate the other 2 timers for Mana and Hits, since they're private and you're looking to avoid core edits. Within the Stamina timer, you can add all your custom arguments for the PlayerMobile's checks on regeneration. So something like this added to PlayerMobile.cs:

Code:
private Timer m_ManaTimer, m_HitsTimer, m_StamTimer;

        public override void CheckStatTimers()
        {
            if (Deleted)
            {
                return;
            }

            if (Hits < HitsMax)
            {
                if (CanRegenHits)
                {
                    if (m_HitsTimer == null)
                    {
                        m_HitsTimer = new HitsTimer(this);
                    }

                    m_HitsTimer.Start();
                }
                else if (m_HitsTimer != null)
                {
                    m_HitsTimer.Stop();
                }
            }
            else
            {
                Hits = HitsMax;
            }

            if (Stam < StamMax)
            {
                if (CanRegenStam)
                {
                    if (m_StamTimer == null)
                    {
                        m_StamTimer = new StamTimer(this);
                    }

                    m_StamTimer.Start();
                }
                else if (m_StamTimer != null)
                {
                    m_StamTimer.Stop();
                }
            }
            else
            {
                Stam = StamMax;
            }

            if (Mana < ManaMax)
            {
                if (CanRegenMana)
                {
                    if (m_ManaTimer == null)
                    {
                        m_ManaTimer = new ManaTimer(this);
                    }

                    m_ManaTimer.Start();
                }
                else if (m_ManaTimer != null)
                {
                    m_ManaTimer.Stop();
                }
            }
            else
            {
                Mana = ManaMax;
            }
        }

        private class ManaTimer : Timer
        {
            private readonly Mobile m_Owner;

            public ManaTimer(Mobile m)
                : base(GetManaRegenRate(m), GetManaRegenRate(m))
            {
                Priority = TimerPriority.FiftyMS;
                m_Owner = m;
            }

            protected override void OnTick()
            {
                if (m_Owner.CanRegenMana)
                {
                    m_Owner.Mana++;
                }

                Delay = Interval = GetManaRegenRate(m_Owner);
            }
        }

        private class HitsTimer : Timer
        {
            private readonly Mobile m_Owner;

            public HitsTimer(Mobile m)
                : base(GetHitsRegenRate(m), GetHitsRegenRate(m))
            {
                Priority = TimerPriority.FiftyMS;
                m_Owner = m;
            }

            protected override void OnTick()
            {
                if (m_Owner.CanRegenHits)
                {
                    m_Owner.Hits++;
                }

                Delay = Interval = GetHitsRegenRate(m_Owner);
            }
        }

        private class StamTimer : Timer
        {
            private readonly Mobile m_Owner;

            public StamTimer(Mobile m)
                : base(GetStamRegenRate(m), GetStamRegenRate(m))
            {
                Priority = TimerPriority.FiftyMS;
                m_Owner = m;
            }

            protected override void OnTick()
            {
                if (((m_Owner.Skills[SkillName.Focus].Value < 20) && (m_Owner.Warmode == true)) || (((m_Owner.Direction & Direction.Running) != 0) && (Core.TickCount - m_Owner.LastMoveTime < 400)))
                {
                    Stop();
                    m_Owner.SendMessage("You can't regenerate Stamina right now.");//Debug message
                }
                else
                {
                    m_Owner.Stam++;
                    m_Owner.SendMessage("You're gaining Stamina back as intended.");//Debug message
                    Delay = Interval = GetStamRegenRate(m_Owner);
                }
            }
        }

Btw: Compiles fine, no errors in Visual Studio. Didn't test it, though.
 
Thank you very much for your support m309, i´m going to test all this and see what is the best thing to do.
:)

Thanks again
 
I tried to override the entire method CheckStatTimers in PlayerMobile.cs.
But it´s like the override is beeing ignored.
None of the changes are applied when the server is started.
 
Nope, don´t know why im not beeing able to override this method.

Anyway i did those changes directly in the core.
As a result i´m having the same problem that i had when i overrided the CanRegenStam method :S
It seems that when losing stamina the stamTimer is not starting again

To make the script working i made this change:

Code:
			protected override void OnTick()
			{
                if (((m_Owner.Skills[SkillName.Focus].Value < 20) && (m_Owner.Warmode == true)) || (((m_Owner.Direction & Direction.Running) != 0) && (Core.TickCount - m_Owner.LastMoveTime < 400)))
                {
                    Stop();
                    m_Owner.SendMessage("You can't regenerate Stamina right now.");//Debug message
                    Start();                          // this makes the timer start again
                }
                else
                {
                    m_Owner.Stam++;
                    m_Owner.SendMessage("You're gaining Stamina back as intended.");//Debug message
                    Delay = Interval = GetStamRegenRate(m_Owner);
                }
			}

I think there should be something to make CANREGENSTAM work fine but i´m not finding the answer.
 
Maybe the problem it´s here:

Code:
			if (Stam < StamMax)
			{
				if (CanRegenStam)
				{
					if (m_StamTimer == null)
					{
						m_StamTimer = new StamTimer(this);
					}

					m_StamTimer.Start();
				}
				else if (m_StamTimer != null)
				{
					m_StamTimer.Stop();                          // this is stoppig the timer when canregen goes false
				}
			}
			else
			{
				Stam = StamMax;
			}

For some reason if there´s a stam loss the timer does not start again.
 
Back