One Time

One Time 1.0.0.15

No permission to download

Finaltwist

Squire
Sep 7, 2019
389
111
43
the circled is what i want a timer for ultimately. since its in a while loop, i don't want it to run superfast, instead id like to have a delay for each cycle of the loop.
also, that brings me to another question - if i wanted miliseconds, i can change the timer type, but how do i tell it to delay 500 ms?
Post automatically merged:

1595956141165.png
Post automatically merged:

1595956224183.png

we are using onetime on runuo for the healing orbs (you posted the fix to make it on time compatible and that works fine)
but its implemented in a different way there
Post automatically merged:

am i in the right direction here?
1595956341157.png
 

GoldDraco13

Squire
Aug 1, 2014
411
255
63
48
Canada
mycy4.com
Donate
Donate money to this user
One time is always running in the back ground so basically you are picking up on its tick cycle, the interface min interval is 1 second and goes up from there do to the cpu overload the millisecond and tick caused. The events allow millisecond and tick but as per your script you only were using one second so this was a better fit. By having the interface attached to the item, the method in that item will be called on tick, now if you want to further work with delays longer then the base time of the tick, use a counter and switch statements within that method to call on specific ticks! I hope that makes sense!
Post automatically merged:

hrm, I see what you mean, let me get my head around your methods, I didn't really dive into your logic, just replaced the implementation!
Post automatically merged:

ok I see what you were doing, you wanted a one second delay to revert the bool back to true, so I would add this to the onetime method

Code:
        private int Delay { get; set; }
        private void OneTimeTick() 
        {
            if (!draintimer)
            {
                if (Delay > 0)
                {
                    draintimer = true;
                    Delay = 0;
                }
                else
                {
                    Delay++;
                }
            }
            else
            {
                Delay = 0;
            }
        }
No need to do anything in the curesedrain method, this will trigger the true after one sec of it going false!!
 
Last edited:
  • Like
Reactions: Finaltwist

Vorspire

Vita-Nex: Core
Admin
ServUO Developer
Jul 29, 2013
1,168
272
83
33
United Kingdom
core.vita-nex.com
Shard Name
Ultima Shards: Multiverse
Donate
Donate money to this user
Simple delayed health drain mechanics traditional vs OneTime implementations...

Traditional: Initiating a local repeating timer, where 'from' is the drain target;
C#:
private Timer m_DrainTimer;
C#:
if (this.m_DrainTimer != null)
    this.m_DrainTimer.Stop();

this.m_DrainTimer = Timer.DelayCall(TimeSpan.Zero, TimeSpan.FromMilliseconds(500), this.CursedDrain, from);
C#:
private void CursedDrain(Mobile from)
{
    if (this.Deleted || this.Hits >= this.HitsMax || from == null || from.Deleted || !from.Alive || from.Hits <= 0)
    {
        this.m_DrainTimer.Stop();
        this.m_DrainTimer = null;
    }
    else
    {
        int drain = Math.Min(5, from.Hits);

        from.Hits -= drain;
        this.Hits += drain;
    }
}
OnTime: Subscribe to the milliseconds event and implement sub-second delay handling, where 'm_DrainFrom' is the drain target inferred by 'from';
C#:
private long m_NextDrain;
private Mobile m_DrainFrom;
C#:
if (this.m_DrainFrom != null)
    OneTimeMilliEvent.MilliTimerTick -= this.CursedDrainHandler;

this.m_DrainFrom = from;
this.m_NextDrain = 0;

OneTimeMilliEvent.MilliTimerTick += this.CursedDrainHandler;
C#:
private void CursedDrainHandler(object sender, EventArgs args)
{
    if (this.Deleted || this.Hits >= this.HitsMax || this.m_DrainFrom == null || this.m_DrainFrom.Deleted || !this.m_DrainFrom.Alive || this.m_DrainFrom.Hits <= 0)
    {
        OneTimeMilliEvent.MilliTimerTick -= this.CursedDrainHandler;
        this.m_DrainFrom = null;
    }
    else if (Core.TickCount >= this.m_NextDrain)
    {
        int drain = Math.Min(5, this.m_DrainFrom.Hits);

        this.m_DrainFrom.Hits -= drain;
        this.Hits += drain;

        this.m_NextDrain = Core.TickCount + 500;
    }
}
Note these examples were written entirely in the forum editor and I cannot guarantee their functionality.
They are not intended to be copy/pasted, but merely to give reference to both perspectives for implementation.

'this' represents the current BaseCursed mobile reference, the context of these examples is taken from the code being placed in BaseCursed itself.

The main difference with OneTime is that you must cache a reference to anything you want to use in your event handler, whereas traditional timers allow you to pass those references directly to the handler.
 

Finaltwist

Squire
Sep 7, 2019
389
111
43
Thanks for the thorough write-up!

MY issue is that i am running a while loop

e.g.
while ( from.Hits >0 && this.InLOS(from) )

inside the loop, i need to run the health drain every x intervals, with a delay between each drain.

Would i then put this inside the while loop?

OneTimeMilliEvent.MilliTimerTick -= this.CursedDrainHandler;

this.m_DrainFrom = from;
this.m_NextDrain = 0;

OneTimeMilliEvent.MilliTimerTick += this.CursedDrainHandler;