Trying to boost heals based on item on layer & target bodyvalue

sahisahi

Knight
Jan 13, 2016
832
79
28
Puffffff struggling right here.

Im trying to boost greater heals if caster is carrying an staff and target bodyvalue is bear (under polymorph spell):

Code:
using System;
using Server.Misc;
using Server.Items;
using System.Collections.Generic;
using Server.Mobiles;
using Server.Network;
using Server.Custom.Polymorph;
using Server.Regions;
using Server.Targeting;

namespace Server.Spells.Fourth
{
    public class GreaterHealSpell : MagerySpell
    {
        public override SpellCircle Circle { get { return SpellCircle.Fourth; } }
        public override int Sound { get { return 0x202; } }

        private static readonly SpellInfo m_Info = new SpellInfo(
                "Greater Heal", "In Vas Mani",
                263,
                9061,
                Reagent.Garlic,
                Reagent.Ginseng,
                Reagent.MandrakeRoot,
                Reagent.SpidersSilk
            );

        public GreaterHealSpell( Mobile caster, Item scroll ) : base( caster, scroll, m_Info )
        {
        }

    //private readonly PolymorphEntry m_PolymorphEntry;
       
         public override TimeSpan GetCastDelay()
        {
                return TimeSpan.FromSeconds(2.80);
        }

        public override void OnPlayerCast()
        {
            if (SphereSpellTarget is Mobile)
                Target((Mobile)SphereSpellTarget);
            else if (SphereSpellTarget is BaseWand)
            {
                BaseWand bw = SphereSpellTarget as BaseWand;
                bw.RechargeWand(Caster, this);
            }
            else
            {
                DoFizzle();
            }
        }

        public override void OnCast()
        {
            Caster.Target = new InternalTarget( this );
        }

        public void Target( Mobile m )
        {
            if ( !Caster.CanSee( m ) )
            {
                Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
            }
            else if ( m is BaseCreature && ((BaseCreature)m).IsAnimatedDead )
            {
                Caster.SendLocalizedMessage( 1061654 ); // You cannot heal that which is not alive.
            }
            else if ( m is Golem )
            {
                Caster.LocalOverheadMessage( MessageType.Regular, 0x3B2, 500951 ); // You cannot heal that.
            }
            /*else if ( m.Poisoned || Server.Items.MortalStrike.IsWounded( m ) )
            {
                Caster.LocalOverheadMessage( MessageType.Regular, 0x22, (Caster == m) ? 1005000 : 1010398 );
            }*/
            else if (CheckBSequence(m))
            {
                       
                int healamount = 0;
           
                if (m.Poisoned)
                {
                    healamount = 0;
                    Caster.LocalOverheadMessage(MessageType.Regular, 0x22, true, "El veneno neutraliza la curacion!");
                }
                //Item bastond = Caster.FindItemOnLayer(Layer.TwoHanded);
                //if (m.BodyValue != 0xD5)
            //    {
    /*Item bastond = Caster.FindItemOnLayer(Layer.TwoHanded);
    if (Caster.Player && bastond != null && bastond is bastondruida )
    {
     if (m.BodyValue != 213)
                    
        healamount = 60;
        Caster.SendAsciiMessage (45,"Conjuras una poderosa Curacion!.");
    }*/
   
   
               
                if (Caster.Skills.Magery.Value ==105)
                {
                    healamount = 42;
                }
                if (Caster.Skills.Magery.Value ==110)
                {
                    healamount = 48;
                }   

    Item bastond = Caster.FindItemOnLayer(Layer.TwoHanded);
    if (Caster.Player && bastond != null && bastond is bastondruida )
    {
    // if (m.BodyValue == 213)
        //if ( m_PolymorphEntry.BodyID == 0xD5 )
        if (m.BodyValue != 213)
     {
   
                
        healamount = 60;
        Caster.SendAsciiMessage (45,"Conjuras una poderosa Curacion!.");
    }
    }
               
                else;
                    healamount = 38;
           
   
               
                if (Scroll != null)
                {
                    healamount -= 10;
                }


               
                m.Heal(healamount);

                m.FixedParticles(0x376A, 10, 15, 5030, EffectLayer.Waist);
                m.PlaySound(Sound);
            }   

            FinishSequence();
        }
           
           
           
           
       

        public class InternalTarget : Target
        {
            private readonly GreaterHealSpell m_Owner;

            public InternalTarget( GreaterHealSpell owner ) : base( 12, false, TargetFlags.Beneficial )
            {
                m_Owner = owner;
            }

            protected override void OnTarget( Mobile from, object o )
            {
                if ( o is Mobile )
                {
                    m_Owner.Target( (Mobile)o );
                }
            }

            protected override void OnTargetFinish( Mobile from )
            {
                m_Owner.FinishSequence();
            }
        }
    }
    }

You can see all the uncomment methods ive tried lol :D

Caster heals for 38, not for 60, idk whats wrong
Thanks!
 

Po0ka

Knight
Aug 19, 2014
733
93
28
Antarctica
I'm not sure why it would not work, the:
if (Caster.Player && bastond != null && bastond is bastondruida )
Seems to be the problem, as it is not reached.
To debug the problem, you can place some Caster.SendMessage("1, 2, 3, 4, 5 ...") or variables ex: "heal: " + healamount.

Also,
"... && bastond is bastondruida"
Normally a class name starts with a capital.
 

Po0ka

Knight
Aug 19, 2014
733
93
28
Antarctica
cheAlso, just checked back to be sure, but the way you did
"if (m.BodyValue != 213)"
Seems wrong, in your case, (assuming 213 is the bear) you would want to use "==".

Also this part of code:
121. }
122. }
123.
124. else;
125.
healamount = 38;

Seems wrong.

Remove the ";" after the else.

Also this is not related, but for your if (Caster.Skills.Magery.Value ==105) and if (Caster.Skills.Magery.Value ==110) your should opt for a different approach. Otherwise;
- A dude with 105 will heal of 42.
- A dude with 105.1 will heal of 38.
- A dude with 109.9 will heal of 38.
- A dude with 110 will heal of 48.

For that i would suggest checking reverse:
Code:
if (Caster.Skills.Magery.Value >= 110)
	healamount = 48;
else if (Caster.Skills.Magery.Value >= 105)
	healamount = 42;
Or actually doing a "+= 10" or "+= 4", so it won't mess with your staff buff.
 

sahisahi

Knight
Jan 13, 2016
832
79
28
Omg so many mistakes :D, Yes i changed it to if (m.BodyValue == 213) (yesterday before you even told me :p)

Thanks for the other fixes!!!!

Got one more question

-What i want to do:

A ring that makes monsters deal -10%: added this to basecreature.cs so it apply to every creature;



Code:
public virtual void AlterMeleeDamageTo(Mobile to, ref int damage)
        { //////////////ANTI PHYSICAL DAMAGE RING -5%damage +10%attack////////
            Item Ring = to.FindItemOnLayer(Layer.Ring);
            if (to is PlayerMobile)
            {
       if (Ring != null && Ring is Equiring)
          damage = (int)(damage * 0.95);
        }
        ///////////////////////////////////
        }
That method means any player carrying Equiring will take -5% damage from creatures

What if i want to add another jewler? lets say a necklace with -10% damage, how to make them stack? so player will take -15% damage in total?

------------------------------------

Also what this method does?


Code:
 public virtual void AlterDamageScalarFrom(Mobile caster, ref double scalar)
        {
        }
 
Last edited:

Po0ka

Knight
Aug 19, 2014
733
93
28
Antarctica
Well, there are many possible options.
Creating a new attribute in the jewels, armors etc. or doing direct checks like you are doing atm.
The first option would be the correct option, but that would require much more job.
The second job is already done, so i guess the best thing to do would be to check and note every place necessary to add a new attribute on armors/weapons/etc. And adding it once everything is prepared.

As for stacking, you would stack the amounts together.
Code:
if (!(to is PlayerMobile))
    return;

double percent = 1;

Item ring = to.FindItemOnLayer(Layer.Ring);
if (ring != null && Ring is Equiring)
    percent -= 0.05;

Item necklace = to.FindItemOnLayer(Layer.Neck);
if (necklace != null && necklace is NecklaceThing)
    percent -= 0.1;

damage = (int)(damage * percent);
Also, remember that variables must not start with a capital, to distinguish with a class name and function name.
As for the first check, it is preferrable to cancel the function if the criterias aren't met at first so te rest doesn't get checked for nothing.

Also note, this should work, but you should not rely on that in the long term. :p
 

sahisahi

Knight
Jan 13, 2016
832
79
28
Thanks!!!!!!!!!!!!!!!!!!! ill test later :)


Also, remember that variables must not start with a capital, to distinguish with a class name and function name.
Okey okeyyyy :)
[doublepost=1475693605][/doublepost]Basecreature.cs
Code:
 public virtual void AlterMeleeDamageFrom(Mobile from, ref int damage)
        {       //////////////equiring -10%damage +10%damage////////
   
       if (!(from is PlayerMobile))
    return;
     double percent = 1;
    Item ring = from.FindItemOnLayer(Layer.Ring);
if (ring != null && ring is Anilloequilibrio)
    percent += 0.1;
Item necklace = from.FindItemOnLayer(Layer.Neck);
if (necklace != null && necklace is Neckequilibrio)
    percent += 0.1;
damage = (int)(damage * percent);
       
            /////////////////////
            #region Mondain's Legacy
            if (from != null && from.Talisman is BaseTalisman)
            {
                BaseTalisman talisman = (BaseTalisman)from.Talisman;

                if (talisman.Killer != null && talisman.Killer.Type != null)
                {
                    Type type = talisman.Killer.Type;

                    if (type.IsAssignableFrom(GetType()))
                        damage = (int)(damage * (1 + (double)talisman.Killer.Amount / 100));
                }
            }
            #endregion
        }
Not working why? damage doesnt get increased from players carrying that ring and necklace

Also :

Code:
  public virtual void AlterMeleeDamageTo(Mobile to, ref int damage)
        { //////////////eq jewlers testing////////
            if (!(to is PlayerMobile))
             return;
            double percent = 1;
        Item ring = to.FindItemOnLayer(Layer.Ring);
      if (ring != null && ring is Anilloequilibrio)
      percent -= 0.5;
        Item necklace = to.FindItemOnLayer(Layer.Neck);
        if (necklace != null && necklace is Neckequilibrio)
         percent -= 0.5;
       damage = (int)(damage * percent);
        ///////////////////////////////////
        }
Doesnt work either, no damage reduction

Weird :/

Ty
 

Po0ka

Knight
Aug 19, 2014
733
93
28
Antarctica
Be careful with the values you place, at m it would make 0 damage (which would convert to 1) due to 0.5.
0.5 is 50%, so "1 - (0.5 * 2) = 0".

As for the damage not changing, try placing some messages to see, ex:
Code:
public virtual void AlterMeleeDamageTo(Mobile to, ref int damage)
{
    //////////////eq jewlers testing////////
    to.SendMessage(String.Format("Damage before: {0}", damage));

    if (!(to is PlayerMobile))
        return;

    double percent = 1;

    Item ring = to.FindItemOnLayer(Layer.Ring);
    if (ring != null && ring is Anilloequilibrio)
        percent -= 0.5;
    Item necklace = to.FindItemOnLayer(Layer.Neck);
    if (necklace != null && necklace is Neckequilibrio)
        percent -= 0.5;

    damage = (int)(damage * percent);

    to.SendMessage(String.Format("Damage after: {0}", damage));
    ///////////////////////////////////
}
Tell me the results, if this doesn't work then i'm unsure of what would not work.
 

sahisahi

Knight
Jan 13, 2016
832
79
28
Ok im going to test, i know values are high, just wanted to make it more noticeable, since it was just 10% at first



*Testing*

Not recieving any message when hit :(
--------------------------------------

I have this on some creature;


Code:
    public override void AlterMeleeDamageFrom( Mobile from, ref int damage )
        {
     
            //////////damage test modifier///////////
            if (from is PlayerMobile)
            {
            Item yummuh = from.FindItemOnLayer(Layer.Helm);
    if (from.Player && yummuh != null && yummuh is YummuMask )
        from.SendMessage(String.Format("Damage before: {0}", damage));
        damage = (int)(damage * 1.3);
        }
        ////////////////////////////////////
        }
It is working, im even recieving the message ''Damage Before: ''

Why the percent method doesnt work at Basecreature.cs?

I added the code above to Basecreature and it works, but then i wont be able to STACK more damage items...

Very weird, will post results tomorrow
 
Last edited:

Po0ka

Knight
Aug 19, 2014
733
93
28
Antarctica
It's important to check what gets executed in the scope.
Try to think manually where each code will pass in any given situation.

Also, remember that the two functions you posted are different, one is a modifier for "To" and the other for "From", both are opposite.
 

sahisahi

Knight
Jan 13, 2016
832
79
28
It's important to check what gets executed in the scope.
Try to think manually where each code will pass in any given situation.

Also, remember that the two functions you posted are different, one is a modifier for "To" and the other for "From", both are opposite.
It worked finally, i messed utp my basecreature, also i was testing it vs a mobile that already had publicoverridevoid AlterMeleeDamageFrom, big fail

Now Im trying to make a ring that gives +10% damage boost to ONE HANDED swords and a necklace that gives bonus damage to AncientLich.



BaseWeapon.cs:

Code:
   public virtual void OnHit(Mobile attacker, Mobile defender, double damageBonus)
        {
            Item Cloak = attacker.FindItemOnLayer(Layer.Cloak);
            if (attacker.Player && defender is BaseCreature)
{
    if (Cloak != null && Cloak is Huntercloak)
        damageBonus += .5;

}
    /////////////////SWORDSMANSHIP RING ONE HANDED ONLY//////////
         Item ring = attacker.FindItemOnLayer(Layer.Ring);
         BaseWeapon weapon = attacker.Weapon as BaseWeapon;
    if (attacker.Player && defender is BaseCreature)


            if ( weapon == null || weapon is BaseSword )
            {
        if (ring != null && ring is Swordsmanshipring)
        damageBonus += .1;
    //////////////////////////////////////////////////////
/////////////////LichNecklace//////////
		 Item necklace = attacker.FindItemOnLayer(Layer.Neck);
	if (attacker.Player && defender is BaseCreature && defender is AncientLich)
				
		if (necklace != null && necklace is Lichnecklace)
        damageBonus += .2;


}
Seems to work, i wonder if it will mess up something else.

Thanks!
 
Last edited:

Po0ka

Knight
Aug 19, 2014
733
93
28
Antarctica
Just be careful with your indentation tho :p
The presentation might be different in the IDE you are using.

As for messing things up, be careful when you place codes into virtual methods, since they are pretty much made to be overriden in subclasses, so you must remember to place a "base.OnHit(attacker, defender, damageBonus);"
 

sahisahi

Knight
Jan 13, 2016
832
79
28
Just be careful with your indentation tho :p
The presentation might be different in the IDE you are using.

As for messing things up, be careful when you place codes into virtual methods, since they are pretty much made to be overriden in subclasses, so you must remember to place a "base.OnHit(attacker, defender, damageBonus);"
Indentation lol.

What do u mean by place a ''base.OnHit(attacker, defender, damageBonus);'' , Where do i have to place that ?
 
Last edited:

Po0ka

Knight
Aug 19, 2014
733
93
28
Antarctica
The "base" code snippet thing goes in the subclasses, so that way the npcs that override the method will execute the code of the BaseCreature.
If you do not add that base, when you override, the effects will simply be overriden.
 

sahisahi

Knight
Jan 13, 2016
832
79
28
My english is not good enough to fully understand what you are saying.Can you give me an example? Sorry for being annoying XD
 

Po0ka

Knight
Aug 19, 2014
733
93
28
Antarctica
BaseCreature
Code:
public virtual void Stuff()
{
	show("bla");
}
SomeCreature
Code:
public override void Stuff()
{
	show("blop");
}
calling Stuff() on SomeCreature will only show "blop".
In your case, you would want to have "bla" also showing up.

The solution is to add a base call to the super class so you don't have to copy paste your code.
Code:
public override void Stuff()
{
	base.Stuff();
	show("blop");
}
With that, it will show "bla" then "blop".

So if you re-use the same concept and apply it to your existing npcs that override those methods, you can make your code work with every npcs.
 

sahisahi

Knight
Jan 13, 2016
832
79
28
Ok i got it, i understand, thats great.

Thanks!!!! im just very scared of crashes :p
 

sahisahi

Knight
Jan 13, 2016
832
79
28
Right now im trying to give damageboost to Players in a Order guild/Chaos guild

is not working so far

Baseweapon.cs
Inside public virtual void OnHit(Mobile attacker, Mobile defender, double damageBonus)
I added the next 2 lines:

Code:
     Guild guild = attacker.Guild as Guild;       
        if (attacker.Player && defender is PlayerMobile)
        if( attacker.Guild != null && attacker.Guild.Type == GuildType.Order);
        {
         damageBonus +=.2;
     }
        if (attacker.Player && defender is PlayerMobile)
        if( attacker.Guild != null && attacker.Guild.Type == GuildType.Chaos);
    {
         damageBonus +=.2;
     }
Damage is not increasing, ive been testing it
 

Po0ka

Knight
Aug 19, 2014
733
93
28
Antarctica
First, the code structure could be improved to one of these:
Code:
Guild guild = attacker.Guild as Guild;

if (guild != null && attacker.Player && defender is PlayerMobile)
{
    if (attacker.Guild.Type == GuildType.Chaos)
        damageBonus *= 1.2;
    else if (attacker.Guild.Type == GuildType.Order)
        damageBonus *= 1.2;
}
or

Code:
Guild guild = attacker.Guild as Guild;

if (guild != null && attacker.Player && defender is PlayerMobile)
{
    switch (attacker.Guild.Type)
    {
        case GuildType.Chaos: damageBonus *= 1.2; break;
        case GuildType.Order: damageBonus *= 1.2; break;
    }
}
As for the damage modifier, i ould suggest changing it for "percentageBonus", since most of the modifiers are modifying this value instead of the other.
In your case you would simply do "percentageBonus += 20;".

For the player thing, remember that you can turn a simple ophidian into a Player by doing "[set player true".
Furthermore, i'm not quite sure of the exact logic you want to happen, would it be:
PlayerMobile attacks PlayerMobile in a different guild = 20% damage bonus to him?
 
  • Like
Reactions: sahisahi

sahisahi

Knight
Jan 13, 2016
832
79
28
Hello, thanks for enlighten me once again Po0ka, i just want to give players inside order/chaos guild type a 20% damageboost.

Server crashed xD


Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
at Server.Items.BaseWeapon.OnHit(Mobile attacker, Mobile defender, Double damageBonus)
at Server.Timer.Slice()
at Server.Core.Main(String[] args)