Hi there!
I have a problem with this:
Orc/ATTACH/<xmldeathaction/action/@SETONTHIS/ADD/ScrollOfTranscendence,{RNDSTRLIST,Alchemy,Anatomy,Healing,Stealing},{RNDLIST,0.1,0.2,0.3,0.4,0.5}>

The orcs drop only scroll of trascendence with 1.0 to 5.0 and not 0.1 to 0.5. Only int number and not float or double
Why? What I have to check?
Thanks!
 
Hi there!
I have a problem with this:
Orc/ATTACH/<xmldeathaction/action/@SETONTHIS/ADD/ScrollOfTranscendence,{RNDSTRLIST,Alchemy,Anatomy,Healing,Stealing},{RNDLIST,0.1,0.2,0.3,0.4,0.5}>

The orcs drop only scroll of trascendence with 1.0 to 5.0 and not 0.1 to 0.5. Only int number and not float or double
Why? What I have to check?
Thanks!
Hi Will, SoTs are a bane...Universal Storage Keys cannot remove them properly, because of that decimal move. This is how they drop in a Champ:
C#:
private ScrollofTranscendence CreateRandomSoT(bool felucca)
{
    int level = Utility.RandomMinMax(1, 5);

    if (felucca)
    level += 5;

    return ScrollofTranscendence.CreateRandom(level, level);
}
Not a lot to mess with there. Even the script to create them has a lot of "Random" values attached to it as well.
My suggestion at this point would be to script each SoT. Basically just make a deed that adds the skills values from the SoT script and call it a Scroll of Transcendence, but give the script a name of like SoTAlc, or SoTAnat, so you can have multiples for each skill.

Or script an Abstract class of SoT, and each of the skills a sub-class of SoT. Then you can have the main Use function in the Abstract class and then make a bunch of "generic" items as a sub-class with the itemID of an SoT.

No idea if this is going to work, but it should put you on the right track:
C#:
public abstract class SoT : SpecialScroll
{
    public override int LabelNumber { get { return 1094934; } } // Scroll of Transcendence
    public override int Message { get { return 1094933; } } /*Using a Scroll of Transcendence for a given skill will permanently increase your current
                                                                *level in that skill by the amount of points displayed on the scroll.
                                                                *As you may not gain skills beyond your maximum skill cap, any excess points will be lost.*/
    [Constructable]
    public SoT() : base( 0x14EF )
    {
        Weight = 1;
        Hue = 0x490;
    }

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

    public override bool CanUse( Mobile from )
    {
        if ( !base.CanUse( from ) )
            return false;
        PlayerMobile pm = from as PlayerMobile;
        if ( pm == null )
            return false;

        #region Mondain's Legacy
        for (int i = pm.Quests.Count - 1; i >= 0; i--)
        {
            BaseQuest quest = pm.Quests[i];
            for (int j = quest.Objectives.Count - 1; j >= 0; j--)
            {
                BaseObjective objective = quest.Objectives[j];

                if (objective is ApprenticeObjective)
                {
                    from.SendMessage("You are already under the effect of an enhanced skillgain quest.");
                    return false;
                }
            }
        }
        #endregion

        #region Scroll of Alacrity
        if (pm.AcceleratedStart > DateTime.Now)
        {
            from.SendLocalizedMessage(1077951); // You are already under the effect of an accelerated skillgain scroll.
            return false;
        }
        #endregion

        return true;
    }
    
    public override void Use( Mobile from )
    {
        if ( !CanUse( from ) )
            return;

        double tskill = from.Skills[Skill].Base; // value of skill without item bonuses etc
        double tcap = from.Skills[Skill].Cap; // maximum value permitted
        bool canGain = false;
        double newValue = Value;
        if ( ( tskill + newValue ) > tcap )
            newValue = tcap - tskill;

        if ( tskill < tcap && from.Skills[Skill].Lock == SkillLock.Up )
        {
            if ( ( from.SkillsTotal + newValue * 10 ) > from.SkillsCap )
            {
                int ns = from.Skills.Length; // number of items in from.Skills[]
                for ( int i = 0; i < ns; i++ )
                {
                    // skill must point down and its value must be enough
                    if ( from.Skills[i].Lock == SkillLock.Down && from.Skills[i].Base >= newValue )
                    {
                        from.Skills[i].Base -= newValue;
                        canGain = true;
                        break;
                    }
                }
            }
            else
                canGain = true;
        }

        if ( !canGain )
        {
            from.SendLocalizedMessage( 1094935 );    /*You cannot increase this skill at this time. The skill may be locked or set to lower in your skill menu.
                                                    *If you are at your total skill cap, you must use a Powerscroll to increase your current skill cap.*/
            return;
        }

        from.SendLocalizedMessage( 1049513, GetNameLocalized() ); // You feel a surge of magic as the scroll enhances your ~1_type~!
        from.Skills[Skill].Base += newValue;
        Effects.PlaySound( from.Location, from.Map, 0x1F7 );
        Effects.SendTargetParticles( from, 0x373A, 35, 45, 0x00, 0x00, 9502, (EffectLayer)255, 0x100 );
        Effects.SendTargetParticles( from, 0x376A, 35, 45, 0x00, 0x00, 9502, (EffectLayer)255, 0x100 );

        Delete();
    }

    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 = ( InheritsItem ? 0 : reader.ReadInt() ); //Required for SpecialScroll insertion
        LootType = LootType.Cursed;
        Insured = false;

        if (Hue == 0x7E)
            Hue = 0x490;
    }
}

public class SoTAlch : SoT
{
    public override string DefaultTitle { get { return String.Format( "<basefont color=#FFFFFF>Scroll of Transcendence ({0} Skill):</basefont>", Value ); } }

    [Constructable]
    public SoTAlch()
    {
    }
    
    public SoTAlch( 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();
    }
}

The way those scrolls are generated makes them a pain to deal with outside of the creation system. An alternative would be to spawn an SoT and use an Xmlspawner or an XmlQuestNPC to set the props to match what you want. You could drop a deed players turn in and the NPC gives them the SoT (because the NPC can spawn it and Props it before giving it to the player). Feel free to PM if you would like more detailed help. :)
 
Hi Will, SoTs are a bane...Universal Storage Keys cannot remove them properly, because of that decimal move. This is how they drop in a Champ:
C#:
private ScrollofTranscendence CreateRandomSoT(bool felucca)
{
    int level = Utility.RandomMinMax(1, 5);

    if (felucca)
    level += 5;

    return ScrollofTranscendence.CreateRandom(level, level);
}
Not a lot to mess with there. Even the script to create them has a lot of "Random" values attached to it as well.
My suggestion at this point would be to script each SoT. Basically just make a deed that adds the skills values from the SoT script and call it a Scroll of Transcendence, but give the script a name of like SoTAlc, or SoTAnat, so you can have multiples for each skill.

Or script an Abstract class of SoT, and each of the skills a sub-class of SoT. Then you can have the main Use function in the Abstract class and then make a bunch of "generic" items as a sub-class with the itemID of an SoT.

No idea if this is going to work, but it should put you on the right track:
C#:
public abstract class SoT : SpecialScroll
{
    public override int LabelNumber { get { return 1094934; } } // Scroll of Transcendence
    public override int Message { get { return 1094933; } } /*Using a Scroll of Transcendence for a given skill will permanently increase your current
                                                                *level in that skill by the amount of points displayed on the scroll.
                                                                *As you may not gain skills beyond your maximum skill cap, any excess points will be lost.*/
    [Constructable]
    public SoT() : base( 0x14EF )
    {
        Weight = 1;
        Hue = 0x490;
    }

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

    public override bool CanUse( Mobile from )
    {
        if ( !base.CanUse( from ) )
            return false;
        PlayerMobile pm = from as PlayerMobile;
        if ( pm == null )
            return false;

        #region Mondain's Legacy
        for (int i = pm.Quests.Count - 1; i >= 0; i--)
        {
            BaseQuest quest = pm.Quests[i];
            for (int j = quest.Objectives.Count - 1; j >= 0; j--)
            {
                BaseObjective objective = quest.Objectives[j];

                if (objective is ApprenticeObjective)
                {
                    from.SendMessage("You are already under the effect of an enhanced skillgain quest.");
                    return false;
                }
            }
        }
        #endregion

        #region Scroll of Alacrity
        if (pm.AcceleratedStart > DateTime.Now)
        {
            from.SendLocalizedMessage(1077951); // You are already under the effect of an accelerated skillgain scroll.
            return false;
        }
        #endregion

        return true;
    }
  
    public override void Use( Mobile from )
    {
        if ( !CanUse( from ) )
            return;

        double tskill = from.Skills[Skill].Base; // value of skill without item bonuses etc
        double tcap = from.Skills[Skill].Cap; // maximum value permitted
        bool canGain = false;
        double newValue = Value;
        if ( ( tskill + newValue ) > tcap )
            newValue = tcap - tskill;

        if ( tskill < tcap && from.Skills[Skill].Lock == SkillLock.Up )
        {
            if ( ( from.SkillsTotal + newValue * 10 ) > from.SkillsCap )
            {
                int ns = from.Skills.Length; // number of items in from.Skills[]
                for ( int i = 0; i < ns; i++ )
                {
                    // skill must point down and its value must be enough
                    if ( from.Skills[i].Lock == SkillLock.Down && from.Skills[i].Base >= newValue )
                    {
                        from.Skills[i].Base -= newValue;
                        canGain = true;
                        break;
                    }
                }
            }
            else
                canGain = true;
        }

        if ( !canGain )
        {
            from.SendLocalizedMessage( 1094935 );    /*You cannot increase this skill at this time. The skill may be locked or set to lower in your skill menu.
                                                    *If you are at your total skill cap, you must use a Powerscroll to increase your current skill cap.*/
            Restituzione;
        }

        from.SendLocalizedMessage( 1049513, GetNameLocalized() ); // Provi un'ondata di magia mentre la pergamena migliora il tuo ~1_tipo~!
        from.Skills[Skill].Base += nuovoValore;
        Effects.PlaySound (da.Location, from.Map, 0x1F7);
        Effects.SendTargetParticles (da, 0x373A, 35, 45, 0x00, 0x00, 9502, (EffectLayer)255, 0x100);
        Effects.SendTargetParticles (da, 0x376A, 35, 45, 0x00, 0x00, 9502, (EffectLayer)255, 0x100);

        Eliminare();
    }

    public override void Serialize(GenericWriter writer)
    {
        base.Serialize(scrittore);
        writer.Write( (int) 0 ); // versione         
    }
  
    public override void Deserialize (lettore GenericReader)
    {
        base.Deserialize(lettore);
        int versione = ( InheritsItem ? 0 : reader.ReadInt() ); //Obbligatorio per l'inserimento di SpecialScroll
        LootType = LootType.Cursed;
        Assicurato = falso;

        se (tonalità == 0x7E)
            Tonalità = 0x490;
    }
}

classe pubblica SoTAlch : SoT
{
    public override string DefaultTitle { get { return String.Format( "<basefont color=#FFFFFF>Scroll of Transcendence ({0} Skill):</basefont>", Value ); } }

    [costruibile]
    public SoTalch()
    {
    }
  
    public SoTalch( Serial serial ): base( serial )
    {
    }
  
    public override void Serialize(GenericWriter writer)
    {
        base.Serialize(scrittore);
        writer.Write( (int) 0 ); // versione
    }
  
    public override void Deserialize (lettore GenericReader)
    {
        base.Deserializza (lettore);
        int versione = reader.ReadInt();
    }
}[/CODICE]

Il modo in cui vengono generate quelle pergamene le rende difficili da affrontare al di fuori del sistema di creazione. Un'alternativa sarebbe generare un SoT e utilizzare un Xmlspawner o un XmlQuestNPC per impostare gli oggetti di scena in modo che corrispondano a ciò che desideri. Potresti lasciare un atto che i giocatori si consegnano e l'NPC dà loro il SoT (perché l'NPC può generarlo e Props prima di darlo al giocatore). Sentiti libero di scrivere in PM se desideri un aiuto più dettagliato.:)
[/QUOTE]
Thank you Tass23, I will try!
 
Back