Dan

Moderator
Before I script this from scratch was wondering if anyone has made anything similar in the past.

I want an item (mine is going to be the new Christmas tree) that on double click will reward a present every 24 hours. 1 per account. Adding a tag to the account to keep track.

I was just wondering if someone has anything like this before I start from scratch.

Thanks for your time.
 
I haven't seen anything, but here's the code you'll need, to lighten your load;

Code:
public bool GiveReward( Mobile m )
{
    if(m == null || !m.InRange(this, 2))
        return false;

    var acc = m.Account as Account;

    if(acc == null)
        return false;

    var tag = acc.GetTag("DailyGift");

    DateTime lastGift;

    if(String.IsNullOrWhiteSpace(tag) || !DateTime.TryParse(tag, out lastGift) || lastGift.AddHours(24) <= DateTime.UtcNow )
    {
        acc.SetTag("DailyGift", DateTime.UtcNow.ToString());

        m.Backpack.DropItem(new GiftBox());

        return true;
    }

    return false;
}
 
Okay so I had to edit the code a little.

Code:
using System;
using Server.Accounting;

namespace Server.Items
{
    public class GiftGivingChristmasTree : Item
    {
        [Constructable]
        public GiftGivingChristmasTree()
            : base(0x9DBE)
        {
            this.Movable = false;
            this.Name = "A Christmas Tree";
         
        }

        public GiftGivingChristmasTree(Serial serial)
            : base(serial)
        {
        }
       
        public override void OnDoubleClick(Mobile m)
        {   

            if(m == null || !m.InRange(this, 2))
            return;
 
            var acc = m.Account as Account;
 
            if(acc == null)
            return;
 
            var tag = acc.GetTag("GiftGivingTree2016");
 
            DateTime lastGift;
 
            if(String.IsNullOrWhiteSpace(tag) || !DateTime.TryParse(tag, out lastGift) || lastGift.AddHours(24) <= DateTime.UtcNow )
            {
                    acc.SetTag("DailyGift", DateTime.UtcNow.ToString());
 
                m.Backpack.DropItem(new RandomChristmasGift());
 
           
            }
                else
                 m.SendMessage("24 hours has not passed since your last present! ");
           
            }
       
       
        public override bool ForceShowProperties
        {
            get
            {
                return ObjectPropertyList.Enabled;
            }
        }
       
        public override void GetProperties( ObjectPropertyList list )
        {
            base.GetProperties( list );

            list.Add( "One Present Per Account Per Day<br>Starts December 5th and ends December 31st<br>Double Click This Tree Once Every 24 Hours To Get A Present" );
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }
}

Before I did it like this it would not load. Said the ondouble click could not be followed by a false statement.
[doublepost=1480964305][/doublepost]It compiles, gives the gift, and marks the account, but it does not stop from getting another and just allows to constantly double click to get more.
[doublepost=1480964596][/doublepost]if I add return false; or any of those statements to block it I get

Code:
CUSTOM/Holidays/Christmas/GiftGivingChristmasTree.cs:
    CS0127: Line 46: Since 'Server.Items.GiftGivingChristmasTree.OnDoubleClick(S
erver.Mobile)' returns void, a return keyword must not be followed by an object
expression
Scripts: One or more scripts failed to compile or no script files were found.
- Press return to exit, or R to try again.
 
Hi Tas.. been away for a bit.. would like to speak more but real quick..

if(String.IsNullOrWhiteSpace(tag) || !DateTime.TryParse(tag, out lastGift) || lastGift.AddHours(24) <= DateTime.UtcNow )

The || in this line, say if any one of these condition is true.. continue.
I'd have to check the return on IsNullOrWhiteSpace, and TryParse.. but most likely you'd want to form a line where all need to be true..
Try using && instead of ||, and have the WhiteSpace and TryParse become true. ie.. !TryParse or TryParse..

f(String.IsNullOrWhiteSpace(tag) && !DateTime.TryParse(tag, out lastGift) && lastGift.AddHours(24) <= DateTime.UtcNow )


As it stands if,
String.IsNullOrWhiteSpace(tag) (give a present)
!DateTime.TryParse(tag, out lastGift) (give a present)
lastGift.AddHours(24) <= DateTime.UtcNow (give a present)
 
Last edited:
Code:
var tag = acc.GetTag("GiftGivingTree2016");
 
            DateTime lastGift;
 
            if(String.IsNullOrWhiteSpace(tag) || !DateTime.TryParse(tag, out lastGift) || lastGift.AddHours(24) <= DateTime.UtcNow )
            {
                    acc.SetTag("DailyGift", DateTime.UtcNow.ToString());
 
                m.Backpack.DropItem(new RandomChristmasGift());
 
           
            }

Something I also missed was I had two different names -

Code:
var tag = acc.GetTag("GiftGivingTree2016");
Code:
acc.SetTag("DailyGift", DateTime.UtcNow.ToString());

going to try a few things.
 
but thats the point isnt it? since after that the tag will be set correctly.

And yes the 2 different tags would give you the issue since the old one would never get set.
 
Code:
using System;
using Server.Accounting;

namespace Server.Items
{
    public class GiftGivingChristmasTree : Item
    {
        [Constructable]
        public GiftGivingChristmasTree()
            : base(0x9DBE)
        {
            this.Movable = false;
            this.Name = "A Christmas Tree";
         
        }

        public GiftGivingChristmasTree(Serial serial)
            : base(serial)
        {
        }
       
        public override void OnDoubleClick(Mobile m)
        {   

            if(m == null || !m.InRange(this, 2))
            return;
 
            var acc = m.Account as Account;
 
            if(acc == null)
            return;
 
            var tag = acc.GetTag("GiftGivingTree2016");
 
            DateTime lastGift;
 
            if(String.IsNullOrWhiteSpace(tag) || !DateTime.TryParse(tag, out lastGift) || lastGift.AddHours(24) <= DateTime.UtcNow )
            {
                   acc.SetTag("GiftGivingTree2016", DateTime.UtcNow.ToString());
 
                m.Backpack.DropItem(new RandomChristmasGift());
                m.SendMessage("a present has been placed in your backpack. Come back in 24 hours to receive another one! ");
 
           
            }
            else
            {
                m.SendMessage("24 hours has not passed since you received your last present! ");

            }
        }
       
       
        public override bool ForceShowProperties
        {
            get
            {
                return ObjectPropertyList.Enabled;
            }
        }
       
        public override void GetProperties( ObjectPropertyList list )
        {
            base.GetProperties( list );

            list.Add( "One Present Per Account Per Day<br>Starts December 5th and ends December 31st<br>Double Click This Tree Once Every 24 Hours To Get A Present" );
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }
}

This actually works fine now. Will just need to see when 24 hours has passed.

Does anyone see an issue with the code? It compiles and seems to work as intended. Will need to see again in 24 hours.
 

Attachments

  • GiftGivingChristmasTree.cs
    2 KB · Views: 9
It still remains if..
String.IsNullOrWhiteSpace(tag) is true.. you get a gift regardless lastGift.AddHours(24) <= DateTime.UtcNow
!DateTime.TryParse(tag, out lastGift) is true.. you get a gift regardless lastGift.AddHours(24) <= DateTime.UtcNow

If those conditions are ever true.. I am not sure without looking at the code..
regardless it seems to me to be an error in logic.

So for example you will receive a gift with this code when TryParse fails..
 
It does seem the work as posted though? It will let me get one gift and then block saying 24 hours has not passed?
 
Correct.. until you run into whitespace or a failed parse, if that happens you'll get a gift.. which is probably not as intended.
 
in case they fail it would mean they didnt get any gift yet since it will be set and corrected with the date of when they got the gift afterwards
 
The correct line of code should probably read (I'd have to check later when free)..

if (!String.IsNullOrWhiteSpace(tag) && DateTime.TryParse(tag, out lastGift) && lastGift.AddHours(24) <= DateTime.UtcNow)

p.s.

That now reads as..
If there is no whitespace and
TryParse was succesful setting lastGift and
the time is correct...

Give a gift.

p.s.s lastGift would need preset coming into this scenario.. which may be why it was left open...
if no parse, then give gift.. I think that might be what Pyro was saying. then it gets set..

It comes to a matter of preference at that point.. both will do the job.
I prefer the solid, no chance for a bug approach.
Thats just my own personal preference when coding..

(not saying this will even encounter a bug!)

Just trying to help and figure out the problem from a glance.. sorry if I extended this past where it needed to go. :)
I wasn't sure of the design intention until discussing it.
 
Last edited:
Let's just stop here.

The reason 'tag' would be null or white space, or fail to parse, is if it was never set.
So it assumes this is the first time they're getting the gift...

Also, I posted the original code as a full method.

It should have been used like this;
Code:
public override void OnDoubleClick( Mobile m )
{
    if( GiveReward( m ) )
        m.SendMessage( "You receive a gift!" );
}

The problem was always that the tag key was changed and the second tag key was not.
 
Thanks @Voxpire for all your help! Based on my code above though, does it look okay? I have made no changes from the last bit I posted.
 
Yes, it looks fine :)

You can test it by reducing the delay to 1 minute temporarily, rather than waiting 24h, but you'll have to do the new test on a character that hasn't been tagged yet.
 
Thanks Voxpire.. I never did look at the original code you posted only what Tas had put up.
As I said before you replied.. 'if no parse, then give gift.. I think that might be what Pyro was saying. then it gets set..'

So no worries. I think we're all on the same page.
 

Active Shards

Donations

Total amount
$0.00
Goal
$1,000.00
Back