APPROVED: Powerscroll combine bag

LordGaav
Adept Scribe
Posts: 49
Joined: Fri Sep 12, 2008 4:09 pm

Re: APPROVED: Powerscroll combine bag

Post by LordGaav »

How about two seperate bags?
User avatar
Harabakc
Legendary Scribe
Posts: 467
Joined: Thu Jun 22, 2006 2:43 pm

Re: APPROVED: Powerscroll combine bag

Post by Harabakc »

I'm not the authority, but if that's easier to code, I think he'd be fine with that.

My original thought on this a couple years ago was the random in random out concept, but somewhere along the forum thing/moves etc that got chopped off. So obviously that's what I'd like to see, but I'm just 1 dude.
Llexa
Legendary Scribe
Posts: 294
Joined: Mon May 08, 2006 3:42 pm

Re: APPROVED: Powerscroll combine bag

Post by Llexa »

Naaaah, I don't think that would be a good idea. Should be one bag with a couple functions, imo.

The way I have seen it, is that you actually were not allowed to submit crafting scrolls to get any, but that you could end up with a crafting 120. (but, again, this can be seperated out, so crafting returns crafting)

So that's why I think it is best to only be able to submit non crafting scrolls to get a non crafting scroll, and all crafting scrolls to get a crafting scroll.. I would hate to put in magery 115, meditation 115, necromancy 115, etc, and end up with a carp 120.


So I think it is best to have the 2 broad categories: Crafting and Skills

This is how I have seen it done....

2 option:

Power scroll tokens (20 of them) found on a variety of creatures. You turn them into the powerscroll dealer and get a random 120 (Mind you it could take 1 week or more to find 20 of these tokens on any given creature.)

The other option for the Powerscroll dealer was: bring him 20 random scrolls (except crafting, and can be 110's, or 115's, it didn't matter) and get a random 120.

This really helps to keep the number of PS's in the world, in check, as far as the low level ones. And I loved this concept. Hence why I was excited about the powerscroll bag. I thought it would be the same concept: place set amount of random scrolls in the bag and you get a 120. Although it seems to be getting a lot more narrow with the, 'it has to be all of the same exact scroll ' stuff. (I don't mind the idea of splitting up the denominations though, all 110's, vs. all 115's.)

If the goal is to cut down on the hordes of lower level PS's, then making the parameters so narrow is not going to help anything. Setting it to random, and a higher number, like 20, would make it more of a chance game. Yes, you could sell these individual 115's and maybe make 400k off of 20 of them, OR, you can input them and hope for a scroll you need. There has to be some loss involved I think. Some kind of risk factor for using the PS bag. Some chance taking. :)
"We push and we push away,
For fear of facing our mistakes.
So we call it judgment,
And watch our friends, our world, ourselves... go comatose, inside."
User avatar
Harabakc
Legendary Scribe
Posts: 467
Joined: Thu Jun 22, 2006 2:43 pm

Re: APPROVED: Powerscroll combine bag

Post by Harabakc »

Given that we have higher end content now I think most of the established players don't bother with champs as much, I'm just too lazy to go do them personally. And with the other stuff available they're less necessary, I've got other things I can be doing.

But just due to how the drops end up happening there are still a ridiculous flood of 110s in the economy, I think people would generally rather pay for a 120 then mess around buying 110s then buying more to have to replace them.
User avatar
+Colibri
Administrator
Posts: 3958
Joined: Sat Feb 25, 2006 4:08 pm
Location: static void Main

Re: APPROVED: Powerscroll combine bag

Post by +Colibri »

Ok here's what we'll do:

1. Make it handle both OnDragDropInto and OnDragDrop
2. If there's already a powerscroll in there, you can only drop powerscrolls that are of the same power.
3. When you drop it in, it then checks how many you need to upgrade: either 5 or 7 depending on the power of the scrolls inside.
4. If it finds the appropriate amount of the same skill, it makes an upgraded version of that same skill. If it finds just crafting scrolls, then it makes a random crafting one. If it finds just non-crafting scrolls, it makes a random non-crafting one.

I suggest you use an array to define which ones are crafting and which ones aren't.
+Colibri, Administrator of UO Excelsior Shard

Don't know what the purpose of your life is? Well then make something up! ;)
(Old Colibrian proverb)
Zodart
Master Scribe
Posts: 60
Joined: Fri Mar 02, 2007 3:13 am

Re: APPROVED: Powerscroll combine bag

Post by Zodart »

Edit: Don't mind this space.
Last edited by Zodart on Tue Sep 30, 2008 3:53 pm, edited 1 time in total.
LordGaav
Adept Scribe
Posts: 49
Joined: Fri Sep 12, 2008 4:09 pm

Re: APPROVED: Powerscroll combine bag

Post by LordGaav »

Maybe you weren't aware, but the coding guidelines have been updated recently. See here. You should really test the code before posting.

Anyways, I have updated the PowerScrollBag to include the aforementioned functionalities. The bag now works in this way:
  1. You drop ANY powerscroll in the bag
  2. The bag records the power of the first scroll, and if it's crafting/noncrafting.
  3. Any scroll that is dropped into the bag that is NOT of the recorded power or crafting/noncrafting type is rejected, it will not enter the bag.
  4. When the threshold is reached, 7 for 105/110 and 5 for 115/120, the scroll is tranformed according to the following rules:
  5. If all scrolls are of the same type and power, so 7x 110 Blacksmithing, you get an upgraded version of the scroll, 1x 115 Blacksmithing in this case.
  6. If they are NOT all of the same type, but within one group (crafting/noncrafting), you get a random upgraded scroll withing that group. For example: 5x Swords 110 and 2x Fencing 110 may turn into a 1x Spirit Speak 115.
  7. To reset the bag, simply remove all scrolls from it.
And here is the code:

Code: Select all

using System;
using System.Collections;
using Server.Multis;
using Server.Mobiles;
using Server.Network;

namespace Server.Items
{
    public class PowerScrollBag : BaseContainer
    {
        private double currentPower = 0;
        private string currentSkillGroup = "";
        private SkillName[] currentAcceptedSkills = null;

        private SkillName[] craftSkills = new SkillName[] {
            SkillName.Alchemy,
            SkillName.Blacksmith,
            SkillName.Fletching,
            SkillName.Carpentry,
            SkillName.Cartography,
            SkillName.Cooking,
            SkillName.Fishing,
            SkillName.Inscribe,
            SkillName.Tailoring,
            SkillName.Tinkering,
            SkillName.Mining
        };

        private SkillName[] nonCraftSkills = new SkillName[] {
            SkillName.Anatomy,
            SkillName.AnimalLore,
            SkillName.ArmsLore,
            SkillName.Parry,
            SkillName.Peacemaking,
            SkillName.Discordance,
            SkillName.EvalInt,
            SkillName.Healing,
            SkillName.Hiding,
            SkillName.Provocation,
            SkillName.Lockpicking,
            SkillName.Magery,
            SkillName.MagicResist,
            SkillName.Tactics,
            SkillName.Musicianship,
            SkillName.Poisoning,
            SkillName.Archery,
            SkillName.SpiritSpeak,
            SkillName.Stealing,
            SkillName.AnimalTaming,
            SkillName.Veterinary,
            SkillName.Swords,
            SkillName.Macing,
            SkillName.Fencing,
            SkillName.Wrestling,
            SkillName.Lumberjacking,
            SkillName.Meditation,
            SkillName.Stealth,
            SkillName.RemoveTrap,
            SkillName.Necromancy,
            SkillName.Focus,
            SkillName.Chivalry,
            SkillName.Bushido,
            SkillName.Ninjitsu
        };

        #region default stuff
        public override int DefaultGumpID { get { return 0x3D; } }
        public override int DefaultDropSound { get { return 0x48; } }

        public override Rectangle2D Bounds
        {
            get { return new Rectangle2D(29, 34, 108, 94); }
        }

        [Constructable]
        public PowerScrollBag() : base(0xE76)
        {
            Weight = 2.0;
            Hue = 86;
            Name = "PowerScroll bag";
        }

        public PowerScrollBag(Serial serial) : base(serial)
        {
        }

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

            writer.Write((int)0); // version
        }

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

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

        public override bool OnDragDropInto(Mobile from, Item item, Point3D p)
        {
            // Check if this action passes BaseContainer's check
            if (!base.OnDragDropInto(from, item, p))
                return false;

            // Recast Item
            PowerScroll scroll = (PowerScroll)item;
            if (scroll == null)
                return false;

            int power = (int)Math.Round(scroll.Value);

            // If scroll value is withing normal values
            if (!(power == 105 || power == 110 || power == 115 || power == 120))
                return false;

            // Start counting
            return this.countPowerScrolls(from, scroll.Skill, scroll.Value);
        }

        public override bool OnDragDrop(Mobile from, Item dropped)
        {
            return this.OnDragDropInto(from, dropped, new Point3D());
        }

        /**
         * Count all PowerScrolls of a given type.
         */
        private bool countPowerScrolls(Mobile from, SkillName skill, double power)
        {
            // Loop through all Items in this Bag
            int count = 0;

            count = this.Items.Count;

            if (count == 0 || count == 1)
            {
                this.currentPower = power;
                if (Array.IndexOf(this.craftSkills, skill) > -1)
                {
                    this.currentSkillGroup = "crafting";
                    this.currentAcceptedSkills = this.craftSkills;
                    Say("The bag now accepts all crafting scrolls with power " + power);
                }
                else
                {
                    this.currentSkillGroup = "non-crafting";
                    this.currentAcceptedSkills = this.nonCraftSkills;
                    Say("The bag now accepts all non-crafting scrolls with power " + power);
                }
            } else {
                if (this.currentPower != power || Array.IndexOf(this.currentAcceptedSkills, skill) == -1) {
                    return false;
                }
            }

            // Check if transformation threshold has been reached
            this.transformPowerScrolls(from, skill, power, count);
            return true;
        }

        /**
         * Transforms lesser PowerScrolls into greater ones, if the threshold has been reached.
         *
         * Transformation thresholds:
         * 105 -> 110 PS: 7x
         * 110 -> 115 PS: 7x
         * 115 -> 120 PS: 5x
         * 120 -> 125 PS: 5x
         */
        private void transformPowerScrolls(Mobile from, SkillName skill, double power, int count)
        {
            // We don't care about doubles
            switch ((int)(Math.Round(power)))
            {
                case 105:
                case 110:
                    if (count >= 7)
                    {
                        from.SendMessage("Upgrading power scrolls with the power of " + power);
                        if (countSameSkills(skill, power, count))
                        {
                            this.DropItem(new PowerScroll(skill, ((int)power) + 5));                            
                            this.removePowerScrolls(from, skill, power, 7);
                        }
                        else
                        {
                            this.DropItem(this.randomScroll(this.currentAcceptedSkills, ((int)power + 5)));
                            this.removePowerScrollsByGroup(from, this.currentAcceptedSkills, power, 7);
                        }
                    }
                    else
                    {
                        Say("Add " + (7 - count) + " more " + this.currentSkillGroup + " scrolls with power of " + this.currentPower + ".");
                    }
                    break;
                case 115:
                case 120:
                    if (count >= 5)
                    {
                        from.SendMessage("Upgrading power scrolls with the power of " + power);
                        if (countSameSkills(skill, power, count))
                        {
                            this.DropItem(new PowerScroll(skill, ((int)power) + 5));                            
                            this.removePowerScrolls(from, skill, power, 5);
                        }
                        else
                        {
                            this.DropItem(this.randomScroll(this.currentAcceptedSkills, ((int)power + 5)));
                            this.removePowerScrollsByGroup(from, this.currentAcceptedSkills, power, 5);
                        } 
                    }
                    else
                    {
                        Say("Add " + (5 - count) + " more " + this.currentSkillGroup + " scrolls with power of " + this.currentPower + ".");
                    }
                    break;
                default:
                    break;
            }
        }

        /**
         * Removes all PowerScrolls of a given group
         */
        private void removePowerScrollsByGroup(Mobile from, SkillName[] skills, double power, int number)
        {
            int count = 0;

            for (int i = (this.Items.Count - 1); i >= 0; i--)
            {
                Item item = (Item)this.Items[i];
                if (!(item is PowerScroll))
                    continue;

                PowerScroll scroll = (PowerScroll)item;
                if ((Array.IndexOf(skills, scroll.Skill) > -1) && scroll.Value == power && count < number)
                {
                    count++;
                    item.Delete();
                }
            }


            Effects.SendLocationParticles(EffectItem.Create(from.Location, from.Map, EffectItem.DefaultDuration), 0, 0, 0, 0, 0, 5060, 0);
            Effects.PlaySound(from.Location, from.Map, 0x243);

            Effects.SendMovingParticles(new Entity(Serial.Zero, new Point3D(from.X - 6, from.Y - 6, from.Z + 15), from.Map), from, 0x36D4, 7, 0, false, true, 0x497, 0, 9502, 1, 0, (EffectLayer)255, 0x100);
            Effects.SendMovingParticles(new Entity(Serial.Zero, new Point3D(from.X - 4, from.Y - 6, from.Z + 15), from.Map), from, 0x36D4, 7, 0, false, true, 0x497, 0, 9502, 1, 0, (EffectLayer)255, 0x100);
            Effects.SendMovingParticles(new Entity(Serial.Zero, new Point3D(from.X - 6, from.Y - 4, from.Z + 15), from.Map), from, 0x36D4, 7, 0, false, true, 0x497, 0, 9502, 1, 0, (EffectLayer)255, 0x100);

            Effects.SendTargetParticles(from, 0x375A, 35, 90, 0x00, 0x00, 9502, (EffectLayer)255, 0x100);
        }
        
        /**
         * Removes all PowerScrolls of a given type
         */
        private void removePowerScrolls(Mobile from, SkillName skill, double power, int number)
        {
            this.removePowerScrollsByGroup(from, new SkillName[] { skill }, power, number);
        }

        /**
         * Checks if all the scrolls are of the given skill and power, and if there are enough available.
         * Returns true if conditions are met, false if not
         */
        private bool countSameSkills(SkillName skill, double power, int needed)
        {
            int count = 0;
            foreach (Item i in this.Items)
            {
                // If this item is a PowerScroll
                if (i is PowerScroll)
                {
                    // Recast Item
                    PowerScroll scroll = (PowerScroll)i;
                    // If this PowerScroll is the same as the one that was dropped
                    if (scroll.Skill == skill && scroll.Value == power)
                    {
                        // Add one
                        count++;
                    }

                    if (count >= needed)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        /**
         * Generate a random scroll with the given power, and picking its skill from the given list.
         */
        private PowerScroll randomScroll(SkillName[] skills, double power)
        {
            return new PowerScroll(this.currentAcceptedSkills[Utility.Random(skills.Length)], power);
        }

        /**
         * Make the bag say the string.
         */
        public void Say(string args)
        {
            PublicOverheadMessage(MessageType.Regular, 0x3B2, false, args);
        }

    }
}
Only thing left to do is checking if the grouped skills are correct and reflect the ones available on the shard.
User avatar
leehovan
Master Scribe
Posts: 69
Joined: Tue Oct 23, 2007 7:22 am
Location: Sesame Street

Re: APPROVED: Powerscroll combine bag

Post by leehovan »

From what i read, it looks good.

Now let's wait and see what happen next ^^
Elf aka Elmo
I love Sesame Street!!!
User avatar
Harabakc
Legendary Scribe
Posts: 467
Joined: Thu Jun 22, 2006 2:43 pm

Re: APPROVED: Powerscroll combine bag

Post by Harabakc »

I'm reasonably sure Lockpicking counts as crafting, it drops off Master of the Arts which drops crafting scrolls(could be wrong, anyone able to verify?).

Going through my powerscroll book the ones that we don't have on server are:
Item Identification
Arms Lore
Begging
Camping
Detecting Hidden
Forensic Evaluation
Herding
Hiding
Snooping
Poisoning
Taste Identification
Tracking
Remove Trap

And just as a regular old player, thanks man for working on this. I know you get class credit but it's nice to see progress on this.
LordGaav
Adept Scribe
Posts: 49
Joined: Fri Sep 12, 2008 4:09 pm

Re: APPROVED: Powerscroll combine bag

Post by LordGaav »

Alright, so according to your list, the craft/nocraft groups are as follows:

Code: Select all

        private SkillName[] craftSkills = new SkillName[] {
            SkillName.Alchemy,
            SkillName.Blacksmith,
            SkillName.Fletching,
            SkillName.Carpentry,
            SkillName.Cartography,
            SkillName.Cooking,
            SkillName.Fishing,
            SkillName.Inscribe,
            SkillName.Tailoring,
            SkillName.Tinkering,
            SkillName.Mining,
            SkillName.Lockpicking
        };

        private SkillName[] nonCraftSkills = new SkillName[] {
            SkillName.Anatomy,
            SkillName.AnimalLore,
            SkillName.Parry,
            SkillName.Peacemaking,
            SkillName.Discordance,
            SkillName.EvalInt,
            SkillName.Healing,
            SkillName.Provocation,
            SkillName.Magery,
            SkillName.MagicResist,
            SkillName.Tactics,
            SkillName.Musicianship,
            SkillName.Archery,
            SkillName.SpiritSpeak,
            SkillName.Stealing,
            SkillName.AnimalTaming,
            SkillName.Veterinary,
            SkillName.Swords,
            SkillName.Macing,
            SkillName.Fencing,
            SkillName.Wrestling,
            SkillName.Lumberjacking,
            SkillName.Meditation,
            SkillName.Stealth,
            SkillName.Necromancy,
            SkillName.Focus,
            SkillName.Chivalry,
            SkillName.Bushido,
            SkillName.Ninjitsu
        };
Harabakc wrote:I'm reasonably sure Lockpicking counts as crafting, it drops off Master of the Arts which drops crafting scrolls(could be wrong, anyone able to verify?).

Going through my powerscroll book the ones that we don't have on server are:
Item Identification
Arms Lore
Begging
Camping
Detecting Hidden
Forensic Evaluation
Herding
Hiding
Snooping
Poisoning
Taste Identification
Tracking
Remove Trap

And just as a regular old player, thanks man for working on this. I know you get class credit but it's nice to see progress on this.
thanks, I find it marvelous that I get to play UO for class credit xD. Although I might have started working on stuff like this had I found it earlier.
User avatar
+Colibri
Administrator
Posts: 3958
Joined: Sat Feb 25, 2006 4:08 pm
Location: static void Main

Re: APPROVED: Powerscroll combine bag

Post by +Colibri »

It is great right :)

Btw it's fine if any of the nonexistant scrolls drop. I'll make them drop from a custom champ, like maybe the frost giant. There won't be much use for them, but maybe over time we'll enhance even those skills.
+Colibri, Administrator of UO Excelsior Shard

Don't know what the purpose of your life is? Well then make something up! ;)
(Old Colibrian proverb)
LordGaav
Adept Scribe
Posts: 49
Joined: Fri Sep 12, 2008 4:09 pm

Re: APPROVED: Powerscroll combine bag

Post by LordGaav »

+Colibri wrote:It is great right :)

Btw it's fine if any of the nonexistant scrolls drop. I'll make them drop from a custom champ, like maybe the frost giant. There won't be much use for them, but maybe over time we'll enhance even those skills.
Do you mean that this bag will drop from the custom champ, or the non-existent scrolls?
User avatar
+Colibri
Administrator
Posts: 3958
Joined: Sat Feb 25, 2006 4:08 pm
Location: static void Main

Re: APPROVED: Powerscroll combine bag

Post by +Colibri »

Well, say you put in random noncrafting scrolls, it might drop a hiding scroll. And i intend to make so that one of the champs will drop those scrolls that currently don't exist yet.
+Colibri, Administrator of UO Excelsior Shard

Don't know what the purpose of your life is? Well then make something up! ;)
(Old Colibrian proverb)
LordGaav
Adept Scribe
Posts: 49
Joined: Fri Sep 12, 2008 4:09 pm

Re: APPROVED: Powerscroll combine bag

Post by LordGaav »

Hmm, 120 begging. High level groveling xD

How's the script?
User avatar
+Colibri
Administrator
Posts: 3958
Joined: Sat Feb 25, 2006 4:08 pm
Location: static void Main

Re: APPROVED: Powerscroll combine bag

Post by +Colibri »

Well just putting it in... i'm not sure how much you tested this but server crash here we come :lol:
I'll rewrite it so that it works well.
+Colibri, Administrator of UO Excelsior Shard

Don't know what the purpose of your life is? Well then make something up! ;)
(Old Colibrian proverb)
Locked