RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Confusion on pre AOS weapon damage...

Confusion on pre AOS weapon damage...

Good afternoon everyone:

My question is regarding pre age of shadows weapons. Pre age of shadows weapons use old weapon damage min max values to formulate the weapons damage. Now here is what is happening to me.

I've changed the core to Core.None
I take 2 mobiles, both set to 100 all skills
I give one a standard GM axe (and a valorite runic vanq for comparison)
I take 20 hits.

about 40 to 60% of the time the weapon hits for 1 damage, The other hits are normal. Now both players are naked, and in pre AOS the only thing that impacts weapon damage is Armor Rating, which the defender in this situation has 0 of.

So if the person has no armor, and the min damage of a double axe is 5 hp, then why am I doing 1 hp hits(even with a vanq)? Where is the min max damage values given to the weapon ( I know in baseweapon.cs, but its not using those values! ).

In the situation provided above you should NEVER do a hit less then 5 hit points, yet alone 40 to 60% of the time. needless to say this is completely unbalancing PvP and need to be resolved so any input on the situation would be greatly appriciated.

EDIT:

Yea, we were just doing some more testing, and what is odd is that the weapon high hits are there, every now and then you deliver some nice blows, so its not that the weapons arn't hitting hard enough, its the low end damage that is incorrect. we had a lumberjacker and fencer, both naked fighting for about 30 mins and about 45% of the time you would deliver a 1 hp hit with a vanq weapon against a naked enemy.....
 
there are other things that also effect it
magical resistence
plus i believe - even naked we have a little ar, and our dex changes it to (all monsters even have a base ar or some type)
our defense skill also effects ar to i do believe (the skill for the weapon we are holding, else wrestling)

so there are many other factors that can lower it down

also like many many many post in these threads have found out
to get pre aos to work right - takes a lot of mods to the scripts - runuo 1.0+ was not really ment for pre-aos, and they did not check it out completely
search for them - may help you out a lot more than what you may found writen here - because many of them are old, and includes words from people no longer active
 
Lord_Greywolf;786495 said:
there are other things that also effect it
magical resistence
plus i believe - even naked we have a little ar, and our dex changes it to (all monsters even have a base ar or some type)
our defense skill also effects ar to i do believe (the skill for the weapon we are holding, else wrestling)

so there are many other factors that can lower it down

also like many many many post in these threads have found out
to get pre aos to work right - takes a lot of mods to the scripts - runuo 1.0+ was not really ment for pre-aos, and they did not check it out completely
search for them - may help you out a lot more than what you may found writen here - because many of them are old, and includes words from people no longer active

there are other things that also effect it
magical resistence

This is not true in pre age of shadows. Magic resist only effects spell damage and has no effect on Armor Rating

plus i believe - even naked we have a little ar, and our dex changes it to (all monsters even have a base ar or some type)

I don't know what leads you to believe that dexterity changes armor rating, armor rating is just that, the amount of physical damage absorbed when struck. in pre aos there are only 2 forms of damage, physical and magical; elements do not apply. I think you are confusing hit success chance and AR as the same thing. However I do agree with you that monsters have a natural AR rating, but these test were done on playermobiles, which do not have a natural AR rating.

our defense skill also effects ar to i do believe (the skill for the weapon we are holding, else wrestling)

Again, I've found nothing in the code to support this statement. The only thing our defence skills effect (such as wrestling, swords, macing, etc) is the rate of successful hits, or hit accuracy; it should not effect your damage at all.

also like many many many post in these threads have found out
to get pre aos to work right - takes a lot of mods to the scripts - runuo 1.0+ was not really ment for pre-aos, and they did not check it out completely

This is definately the truth. Ive pretty much revisted most distro scripts since the system has been converted to pre aos to tweak little things here and their, but when it comes to this Im baffled. Below is everything from base weapon that has to do with weapon damage from retrieving the weapons minimum damage from the weapon class all the way to when the damage is delt to the player. Ive traced its patch, visited every method it calls to scale the damage, and no matter how many times I track the damage value I never find the location that is causing the weapons damage to be modified to 1hp. Under the conditions of our experiments this should not be possible.

Code:
		[CommandProperty( AccessLevel.GameMaster )]
		public int MinDamage
		{
			get{ return ( m_MinDamage == -1 ? Core.AOS ? AosMinDamage : OldMinDamage : m_MinDamage ); }
			set{ m_MinDamage = value; InvalidateProperties(); }
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public int MaxDamage
		{
			get{ return ( m_MaxDamage == -1 ? Core.AOS ? AosMaxDamage : OldMaxDamage : m_MaxDamage ); }
			set{ m_MaxDamage = value; InvalidateProperties(); }
		}

Code:
		public virtual int ComputeDamage( Mobile attacker, Mobile defender )
		{
			if ( Core.AOS )
				return ComputeDamageAOS( attacker, defender );

			// RETURNS ATTACKERS MIN MAX DAMAGE
			return (int)ScaleDamageOld( attacker, GetBaseDamage( attacker ), true );
		}

Code:
		public virtual double GetBaseDamage( Mobile attacker )
		{
			int min, max;

			GetBaseDamageRange( attacker, out min, out max );

			return Utility.RandomMinMax( min, max );
		}

Code:
		public virtual void GetBaseDamageRange( Mobile attacker, out int min, out int max )
		{
			if ( attacker is BaseCreature )
			{
				BaseCreature c = (BaseCreature)attacker;

				if ( c.DamageMin >= 0 )
				{
					min = c.DamageMin;
					max = c.DamageMax;
					return;
				}

				if ( this is Fists && !attacker.Body.IsHuman )
				{
					min = attacker.Str / 28;
					max = attacker.Str / 28;
					return;
				}
			}

			min = MinDamage;
			max = MaxDamage;
		}

Code:
		public virtual double ScaleDamageOld( Mobile attacker, double damage, bool checkSkills )
		{
			if ( checkSkills )
			{
				attacker.CheckSkill( SkillName.Tactics, 0.0, 100.0 ); // Passively check tactics for gain
				attacker.CheckSkill( SkillName.Anatomy, 0.0, 100.0 ); // Passively check Anatomy for gain

				if ( Type == WeaponType.Axe )
					attacker.CheckSkill( SkillName.Lumberjacking, 0.0, 100.0 ); // Passively check Lumberjacking for gain
			}

			/* Compute tactics modifier
			 * :   0.0 = 50% loss
			 * :  50.0 = unchanged
			 * : 100.0 = 50% bonus
			 */
			double tacticsBonus = (attacker.Skills[SkillName.Tactics].Value - 50.0) / 100.0;

			/* Compute strength modifier
			 * : 1% bonus for every 5 strength
			 */
			double strBonus = (attacker.Str / 5.0) / 100.0;

			/* Compute anatomy modifier
			 * : 1% bonus for every 5 points of anatomy
			 * : +10% bonus at Grandmaster or higher
			 */
			double anatomyValue = attacker.Skills[SkillName.Anatomy].Value;
			double anatomyBonus = (anatomyValue / 5.0) / 100.0;

			if ( anatomyValue >= 100.0 )
				anatomyBonus += 0.1;

			/* Compute lumberjacking bonus
			 * : 1% bonus for every 5 points of lumberjacking
			 * : +10% bonus at Grandmaster or higher
			 */
			double lumberBonus;

			if ( Type == WeaponType.Axe )
			{
				double lumberValue = attacker.Skills[SkillName.Lumberjacking].Value;

				lumberBonus = (lumberValue / 5.0) / 100.0;

				if ( lumberValue >= 100.0 )
					lumberBonus += 0.1;
			}
			else
			{
				lumberBonus = 0.0;
			}

			// New quality bonus:
			double qualityBonus = ((int)m_Quality - 1) * 0.2;

			// Apply bonuses
			damage += (damage * tacticsBonus) + (damage * strBonus) + (damage * anatomyBonus) + (damage * lumberBonus) + (damage * qualityBonus) + ((damage * VirtualDamageBonus) / 100);

			// Old quality bonus:
#if false
			/* Apply quality offset
			 * : Low         : -4
			 * : Regular     :  0
			 * : Exceptional : +4
			 */
			damage += ((int)m_Quality - 1) * 4.0;
#endif

			/* Apply damage level offset
			 * : Regular : 0
			 * : Ruin    : 1
			 * : Might   : 3
			 * : Force   : 5
			 * : Power   : 7
			 * : Vanq    : 9
			 */
			if ( m_DamageLevel != WeaponDamageLevel.Regular )
				damage += (2.0 * (int)m_DamageLevel) - 1.0;

			// Halve the computed damage and return
			damage /= 2.0;

			return ScaleDamageByDurability( (int)damage );
		}

Code:
		public virtual int AbsorbDamage( Mobile attacker, Mobile defender, int damage )
		{
			if ( Core.AOS )
				return AbsorbDamageAOS( attacker, defender, damage );

			double chance = Utility.RandomDouble();

			Item armorItem;

			if( chance < 0.07 )
				armorItem = defender.NeckArmor;
			else if( chance < 0.14 )
				armorItem = defender.HandArmor;
			else if( chance < 0.28 )
				armorItem = defender.ArmsArmor;
			else if( chance < 0.43 )
				armorItem = defender.HeadArmor;
			else if( chance < 0.65 )
				armorItem = defender.LegsArmor;
			else
				armorItem = defender.ChestArmor;

			IWearableDurability armor = armorItem as IWearableDurability;

			if ( armor != null )
				damage = armor.OnHit( this, damage );

			BaseShield shield = defender.FindItemOnLayer( Layer.TwoHanded ) as BaseShield;
			if ( shield != null )
				damage = shield.OnHit( this, damage );

			int virtualArmor = defender.VirtualArmor + defender.VirtualArmorMod;

			if ( virtualArmor > 0 )
			{
				double scalar;

				if ( chance < 0.14 )
					scalar = 0.07;
				else if ( chance < 0.28 )
					scalar = 0.14;
				else if ( chance < 0.43 )
					scalar = 0.15;
				else if ( chance < 0.65 )
					scalar = 0.22;
				else
					scalar = 0.35;

				int from = (int)(virtualArmor * scalar) / 2;
				int to = (int)(virtualArmor * scalar);

				damage -= Utility.Random( from, (to - from) + 1 );
			}

			return damage;
		}

Code:
		public virtual void OnHit( Mobile attacker, Mobile defender, double damageBonus )
		{
			if ( MirrorImage.HasClone( defender ) && (defender.Skills.Ninjitsu.Value / 150.0) > Utility.RandomDouble() )
			{
				Clone bc;

				foreach ( Mobile m in defender.GetMobilesInRange( 4 ) )
				{
					bc = m as Clone;

					if ( bc != null && bc.Summoned && bc.SummonMaster == defender )
					{
						attacker.SendLocalizedMessage( 1063141 ); // Your attack has been diverted to a nearby mirror image of your target!
						defender.SendLocalizedMessage( 1063140 ); // You manage to divert the attack onto one of your nearby mirror images.

						/*
						 * TODO: What happens if the Clone parries a blow?
						 * And what about if the attacker is using Honorable Execution
						 * and kills it?
						 */

						defender = m;
						break;
					}
				}
			}

			PlaySwingAnimation( attacker );
			PlayHurtAnimation( defender );

			attacker.PlaySound( GetHitAttackSound( attacker, defender ) );
			defender.PlaySound( GetHitDefendSound( attacker, defender ) );

			int damage = ComputeDamage( attacker, defender );

			#region Damage Multipliers
			/*
			 * The following damage bonuses multiply damage by a factor.
			 * Capped at x3 (300%).
			 */
			//double factor = 1.0;
			int percentageBonus = 0;

			WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
			SpecialMove move = SpecialMove.GetCurrentMove( attacker );

			if( a != null )
			{
				//factor *= a.DamageScalar;
				percentageBonus += (int)(a.DamageScalar * 100) - 100;
			}

			if( move != null )
			{
				//factor *= move.GetDamageScalar( attacker, defender );
				percentageBonus += (int)(move.GetDamageScalar( attacker, defender ) * 100) - 100;
			}

			//factor *= damageBonus;
			percentageBonus += (int)(damageBonus * 100) - 100;

			CheckSlayerResult cs = CheckSlayers( attacker, defender );

			if ( cs != CheckSlayerResult.None )
			{
				if ( cs == CheckSlayerResult.Slayer )
					defender.FixedEffect( 0x37B9, 10, 5 );

				//factor *= 2.0;
				percentageBonus += 100;
			}

			if ( !attacker.Player )
			{
				if ( defender is PlayerMobile )
				{
					PlayerMobile pm = (PlayerMobile)defender;

					if( pm.EnemyOfOneType != null && pm.EnemyOfOneType != attacker.GetType() )
					{
						//factor *= 2.0;
						percentageBonus += 100;
					}
				}
			}
			else if ( !defender.Player )
			{
				if ( attacker is PlayerMobile )
				{
					PlayerMobile pm = (PlayerMobile)attacker;

					if ( pm.WaitingForEnemy )
					{
						pm.EnemyOfOneType = defender.GetType();
						pm.WaitingForEnemy = false;
					}

					if ( pm.EnemyOfOneType == defender.GetType() )
					{
						defender.FixedEffect( 0x37B9, 10, 5, 1160, 0 );
						//factor *= 1.5;
						percentageBonus += 50;
					}
				}
			}

			int packInstinctBonus = GetPackInstinctBonus( attacker, defender );

			if( packInstinctBonus != 0 )
			{
				//factor *= 1.0 + (double)packInstinctBonus / 100.0;
				percentageBonus += packInstinctBonus;
			}

			if( m_InDoubleStrike )
			{
				//factor *= 0.9; // 10% loss when attacking with double-strike
				percentageBonus -= 10;
			}

			TransformContext context = TransformationSpellHelper.GetContext( defender );

			if( (m_Slayer == SlayerName.Silver || m_Slayer2 == SlayerName.Silver) && context != null && context.Spell is NecromancerSpell && context.Type != typeof( HorrificBeastSpell ) )
			{
				//factor *= 1.25; // Every necromancer transformation other than horrific beast takes an additional 25% damage
				percentageBonus += 25;
			}
// EDIT: Added for ren concencrate
			if ( m_Consecrated )
			{
				//factor *= 1.10; // 10% Damage bonus when a weapon is concencrated
				percentageBonus += 10;
			}
// EDIT
			if ( attacker is PlayerMobile && !(Core.ML && defender is PlayerMobile ))
			{
				PlayerMobile pmAttacker = (PlayerMobile) attacker;

				if( pmAttacker.HonorActive && pmAttacker.InRange( defender, 1 ) )
				{
					//factor *= 1.25;
					percentageBonus += 25;
				}

				if( pmAttacker.SentHonorContext != null && pmAttacker.SentHonorContext.Target == defender )
				{
					//pmAttacker.SentHonorContext.ApplyPerfectionDamageBonus( ref factor );
					percentageBonus += pmAttacker.SentHonorContext.PerfectionDamageBonus;
				}
			}

			//if ( factor > 3.0 )
			//	factor = 3.0;

			percentageBonus = Math.Min( percentageBonus, 300 );

			//damage = (int)(damage * factor);
			damage = AOS.Scale( damage, 100 + percentageBonus );
			#endregion

			if ( attacker is BaseCreature )
				((BaseCreature)attacker).AlterMeleeDamageTo( defender, ref damage );

			if ( defender is BaseCreature )
				((BaseCreature)defender).AlterMeleeDamageFrom( attacker, ref damage );

			damage = AbsorbDamage( attacker, defender, damage );

			if ( !Core.AOS && damage < 1 )
				damage = 1;
			else if ( Core.AOS && damage == 0 ) // parried
			{
				if ( a != null && a.Validate( attacker ) /*&& a.CheckMana( attacker, true )*/ ) // Parried special moves have no mana cost 
				{
					a = null;
					WeaponAbility.ClearCurrentAbility( attacker );

					attacker.SendLocalizedMessage( 1061140 ); // Your attack was parried!
				}
			}

			AddBlood( attacker, defender, damage );

			int phys, fire, cold, pois, nrgy;

			GetDamageTypes( attacker, out phys, out fire, out cold, out pois, out nrgy );

// Removed to edit this spell for Ren
/*
			if ( m_Consecrated )
			{
				phys = defender.PhysicalResistance;
				fire = defender.FireResistance;
				cold = defender.ColdResistance;
				pois = defender.PoisonResistance;
				nrgy = defender.EnergyResistance;

				int low = phys, type = 0;

				if ( fire < low ){ low = fire; type = 1; }
				if ( cold < low ){ low = cold; type = 2; }
				if ( pois < low ){ low = pois; type = 3; }
				if ( nrgy < low ){ low = nrgy; type = 4; }

				phys = fire = cold = pois = nrgy = 0;

				if ( type == 0 ) phys = 100;
				else if ( type == 1 ) fire = 100;
				else if ( type == 2 ) cold = 100;
				else if ( type == 3 ) pois = 100;
				else if ( type == 4 ) nrgy = 100;
			}
*/

			int damageGiven = damage;

			if ( a != null && !a.OnBeforeDamage( attacker, defender ) )
			{
				WeaponAbility.ClearCurrentAbility( attacker );
				a = null;
			}

			if ( move != null && !move.OnBeforeDamage( attacker, defender ) )
			{
				SpecialMove.ClearCurrentMove( attacker );
				move = null;
			}

			bool ignoreArmor = ( a is ArmorIgnore || (move != null && move.IgnoreArmor( attacker )) );

			damageGiven = AOS.Damage( defender, attacker, damage, ignoreArmor, phys, fire, cold, pois, nrgy );

			double propertyBonus = ( move == null ) ? 1.0 : move.GetPropertyBonus( attacker );

			if ( Core.AOS )
			{
				int lifeLeech = 0;
				int stamLeech = 0;
				int manaLeech = 0;
				int wraithLeech = 0;

				if ( (int)(m_AosWeaponAttributes.HitLeechHits * propertyBonus) > Utility.Random( 100 ) )
					lifeLeech += 30; // HitLeechHits% chance to leech 30% of damage as hit points

				if ( (int)(m_AosWeaponAttributes.HitLeechStam * propertyBonus) > Utility.Random( 100 ) )
					stamLeech += 100; // HitLeechStam% chance to leech 100% of damage as stamina

				if ( (int)(m_AosWeaponAttributes.HitLeechMana * propertyBonus) > Utility.Random( 100 ) )
					manaLeech += 40; // HitLeechMana% chance to leech 40% of damage as mana

				if ( m_Cursed )
					lifeLeech += 50; // Additional 50% life leech for cursed weapons (necro spell)

				context = TransformationSpellHelper.GetContext( attacker );

				if ( context != null && context.Type == typeof( VampiricEmbraceSpell ) )
					lifeLeech += 20; // Vampiric embrace gives an additional 20% life leech

				if ( context != null && context.Type == typeof( WraithFormSpell ) )
				{
					wraithLeech = (5 + (int)((15 * attacker.Skills.SpiritSpeak.Value) / 100)); // Wraith form gives an additional 5-20% mana leech

					// Mana leeched by the Wraith Form spell is actually stolen, not just leeched.
					defender.Mana -= AOS.Scale( damageGiven, wraithLeech );

					manaLeech += wraithLeech;
				}

				if ( lifeLeech != 0 )
					attacker.Hits += AOS.Scale( damageGiven, lifeLeech );

				if ( stamLeech != 0 )
					attacker.Stam += AOS.Scale( damageGiven, stamLeech );

				if ( manaLeech != 0 )
					attacker.Mana += AOS.Scale( damageGiven, manaLeech );

				if ( lifeLeech != 0 || stamLeech != 0 || manaLeech != 0 )
					attacker.PlaySound( 0x44D );
			}

			if ( m_MaxHits > 0 && ((MaxRange <= 1 && (defender is Slime || defender is ToxicElemental)) || Utility.Random( 25 ) == 0) ) // Stratics says 50% chance, seems more like 4%..
			{
				if ( MaxRange <= 1 && (defender is Slime || defender is ToxicElemental) )
					attacker.LocalOverheadMessage( MessageType.Regular, 0x3B2, 500263 ); // *Acid blood scars your weapon!*

				if ( Core.AOS && m_AosWeaponAttributes.SelfRepair > Utility.Random( 10 ) )
				{
					HitPoints += 2;
				}
				else
				{
					if ( m_Hits > 0 )
					{
						--HitPoints;
					}
					else if ( m_MaxHits > 1 )
					{
						--MaxHitPoints;

						if ( Parent is Mobile )
							((Mobile)Parent).LocalOverheadMessage( MessageType.Regular, 0x3B2, 1061121 ); // Your equipment is severely damaged.
					}
					else
					{
						Delete();
					}
				}
			}

			if ( attacker is VampireBatFamiliar )
			{
				BaseCreature bc = (BaseCreature)attacker;
				Mobile caster = bc.ControlMaster;

				if ( caster == null )
					caster = bc.SummonMaster;

				if ( caster != null && caster.Map == bc.Map && caster.InRange( bc, 2 ) )
					caster.Hits += damage;
				else
					bc.Hits += damage;
			}

			if ( Core.AOS )
			{
				int physChance = (int)(m_AosWeaponAttributes.HitPhysicalArea * propertyBonus);
				int fireChance = (int)(m_AosWeaponAttributes.HitFireArea * propertyBonus);
				int coldChance = (int)(m_AosWeaponAttributes.HitColdArea * propertyBonus);
				int poisChance = (int)(m_AosWeaponAttributes.HitPoisonArea * propertyBonus);
				int nrgyChance = (int)(m_AosWeaponAttributes.HitEnergyArea * propertyBonus);

				if ( physChance != 0 && physChance > Utility.Random( 100 ) )
					DoAreaAttack( attacker, defender, 0x10E,   50, 100, 0, 0, 0, 0 );

				if ( fireChance != 0 && fireChance > Utility.Random( 100 ) )
					DoAreaAttack( attacker, defender, 0x11D, 1160, 0, 100, 0, 0, 0 );

				if ( coldChance != 0 && coldChance > Utility.Random( 100 ) )
					DoAreaAttack( attacker, defender, 0x0FC, 2100, 0, 0, 100, 0, 0 );

				if ( poisChance != 0 && poisChance > Utility.Random( 100 ) )
					DoAreaAttack( attacker, defender, 0x205, 1166, 0, 0, 0, 100, 0 );

				if ( nrgyChance != 0 && nrgyChance > Utility.Random( 100 ) )
					DoAreaAttack( attacker, defender, 0x1F1,  120, 0, 0, 0, 0, 100 );

				int maChance = (int)(m_AosWeaponAttributes.HitMagicArrow * propertyBonus);
				int harmChance = (int)(m_AosWeaponAttributes.HitHarm * propertyBonus);
				int fireballChance = (int)(m_AosWeaponAttributes.HitFireball * propertyBonus);
				int lightningChance = (int)(m_AosWeaponAttributes.HitLightning * propertyBonus);
				int dispelChance = (int)(m_AosWeaponAttributes.HitDispel * propertyBonus);

				if ( maChance != 0 && maChance > Utility.Random( 100 ) )
					DoMagicArrow( attacker, defender );

				if ( harmChance != 0 && harmChance > Utility.Random( 100 ) )
					DoHarm( attacker, defender );

				if ( fireballChance != 0 && fireballChance > Utility.Random( 100 ) )
					DoFireball( attacker, defender );

				if ( lightningChance != 0 && lightningChance > Utility.Random( 100 ) )
					DoLightning( attacker, defender );

				if ( dispelChance != 0 && dispelChance > Utility.Random( 100 ) )
					DoDispel( attacker, defender );

				int laChance = (int)(m_AosWeaponAttributes.HitLowerAttack * propertyBonus);
				int ldChance = (int)(m_AosWeaponAttributes.HitLowerDefend * propertyBonus);

				if ( laChance != 0 && laChance > Utility.Random( 100 ) )
					DoLowerAttack( attacker, defender );

				if ( ldChance != 0 && ldChance > Utility.Random( 100 ) )
					DoLowerDefense( attacker, defender );
			}

			if ( attacker is BaseCreature )
				((BaseCreature)attacker).OnGaveMeleeAttack( defender );

			if ( defender is BaseCreature )
				((BaseCreature)defender).OnGotMeleeAttack( attacker );

			if ( a != null )
				a.OnHit( attacker, defender, damage );

			if ( move != null )
				move.OnHit( attacker, defender, damage );

			if ( defender is IHonorTarget && ((IHonorTarget)defender).ReceivedHonorContext != null )
				((IHonorTarget)defender).ReceivedHonorContext.OnTargetHit( attacker );

			if ( !(this is BaseRanged) )
			{
				if ( AnimalForm.UnderTransformation( attacker, typeof( GiantSerpent ) ) )
					defender.ApplyPoison( attacker, Poison.Lesser );

				if ( AnimalForm.UnderTransformation( defender, typeof( BullFrog ) ) )
					attacker.ApplyPoison( defender, Poison.Regular );
			}
		}

The only thing I have noticed is this in the OnHit method of baseweapon

Code:
			if ( !Core.AOS && damage < 1 )
				damage = 1;

Which leads me to believe that somewhere (unknown to me) the damage is being modifed to a value less then 0, which then is fixed and boosted to 1hp. The experiment can be repeated every time, and the target doesn't matter.. Monster, player, etc, you have about a 45% chance of dealing a 1hp damage hit.

Later this afternoon if I have the time Im going to unpack a brand new server and only chance the expansion to none to see if the problem is with the distrobution files or something ive unknowningly done. Let me know if you see anything that I dont, thank you in advance for any information you may be able to provide on this matter. Thank you in advance for your assistance.
 
i think it might be in here:

Code:
			int virtualArmor = defender.VirtualArmor + defender.VirtualArmorMod;

			if ( virtualArmor > 0 )
			{
				double scalar;

				if ( chance < 0.14 )
					scalar = 0.07;
				else if ( chance < 0.28 )
					scalar = 0.14;
				else if ( chance < 0.43 )
					scalar = 0.15;
				else if ( chance < 0.65 )
					scalar = 0.22;
				else
					scalar = 0.35;

				int from = (int)(virtualArmor * scalar) / 2;
				int to = (int)(virtualArmor * scalar);

				damage -= Utility.Random( from, (to - from) + 1 );
			}

dealing with the virtual armor mod

i do not understand how or what the deltas mean in mobile.cs in the core, but that is the basis for virtual armor mod - it could be something their raise it up
besides being on reward cloaks and certain other items

I do not deal with pre-aos - but i know and have tried to help many that have, and they have to do a lot of modifying to get it to work right (it is distro based)
 
Lord_Greywolf;786603 said:
dealing with the virtual armor mod

i do not understand how or what the deltas mean in mobile.cs in the core, but that is the basis for virtual armor mod - it could be something their raise it up
besides being on reward cloaks and certain other items

I do not deal with pre-aos - but i know and have tried to help many that have, and they have to do a lot of modifying to get it to work right (it is distro based)

I think the problem is elsewhere for one simple reason. In the method you posted above the if method is only executed when the int value VirtualArmor is greater then 0. Well the Virtual Armor is made of:

Code:
			int virtualArmor = defender.VirtualArmor + defender.VirtualArmorMod;

Well, I've done ALOT of testing with this problem and one of the things I've tested is exactly what you pointed out. in game I did a [get virtualarmor and [get virtualarmormod on the target I was attacking, and both returned 0. So if the person I am hitting has 0 virtual armor that entire IF statement is bypassed

Code:
			if ( virtualArmor > 0 )
			{

hence proving its not our problem. Thanks for the suggestion though, if you have any more please let me know.
 
Suil Ban;786641 said:
In stock RunUO, pre-AoS damage is halved too early in the formula. Zippy has confirmed this.

And Im okay with that, I noticed that inside the code aswell; but regardless the damage under the following circumstances should never return damage below 5hp, should it?

Weapon:
Double axe (store bought)
Code:
		public override int OldStrengthReq{ get{ return 45; } }
[color=red]		public override int OldMinDamage{ get{ return 5; } }[/color]
		public override int OldMaxDamage{ get{ return 35; } }
		public override int OldSpeed{ get{ return 37; } }

Attacker:
skills: all 100
stats: 90 str, 100 dex, 35 int

Defender:
skills: all 100
stats: 90 str, 35 dex, 100 int
Armor rating = 0
Virtual armor rating = 0
Virtual armor rating mod = 0

So, with no damage modifiers ( either amplifiers on the weapon, nor defence on the player) shouldn't no matter what the damage range be between 5hp and 35hp ( the range for this paticular weapon provided above ). It's only when armor is added, weapon damage levels are changed, etc. that you should see damage levels outside this range.

I think everyone who reads this can agree with me that no matter what the era, a 7x lumberjacker with a valorite runic double axe should never do a hit for 1hp, yet alone do hits like that 45% of the time. What makes it so confusing is the max damage is being calculated properly, just not the minumum damage.

Am I the only one who has suffered from this problem when reverting to pre aos? As I said before when I have a moment Im going to unpack a clean server and do some experiments to see if the problem persist.

Again thank you to anyone who is willing and able to provide me with any assistance on this subject. Have a wonderful day and an even better New Year!
 
Okay, so I've done a great deal of testing (3 solid days) and placed console writes in every method that weapon damage is handed to from when it retrieved from the weapons base values to when its applied to the player. As I traced everything seem fine, seemed fine, seemed fine, then bingo, I found the offending method:

Code:
		public virtual int AbsorbDamage( Mobile attacker, Mobile defender, int damage )

the damage was being handed to this method correctly but kept coming out of it as 0, so I littered this method will a million console writes to track exactly what each step is doing to the damage, here are the results (note: what is highlighted in red is where the damage in being loss)

Code:
Original damage: 31: Father Time
Damage after hitting armor: 31: Father Time
Damage after calculating ar levels: 31: Father Time

Original damage: 30: Father Time
[color=red]Damage after hitting armor: 30: Father Time[/color]
Damage after calculating ar levels: 30: Father Time

Original damage: 8: Father Time
Damage after hitting armor: 8: Father Time
Damage after calculating ar levels: 8: Father Time

Original damage: 23: Father Time
Damage after hitting armor: 23: Father Time
Damage after calculating ar levels: 23: Father Time

Original damage: 12: Father Time
Damage after hitting armor: 12: Father Time
Damage after calculating ar levels: 12: Father Time

Original damage: 13: Father Time
Damage after hitting armor: 13: Father Time
Damage after calculating ar levels: 13: Father Time

Original damage: 17: Father Time
[color=red]Damage after hitting armor: 10: Father Time[/color]
Damage after calculating ar levels: 10: Father Time

Original damage: 33: Father Time
[color=red]Damage after hitting armor: 22: Father Time[/color]
Damage after calculating ar levels: 22: Father Time

Original damage: 24: Father Time
Damage after hitting armor: 24: Father Time
Damage after calculating ar levels: 24: Father Time

Original damage: 21: Father Time
Damage after hitting armor: 21: Father Time
Damage after calculating ar levels: 21: Father Time

Original damage: 18: Father Time
Damage after hitting armor: 18: Father Time
Damage after calculating ar levels: 18: Father Time

Original damage: 8: Father Time
[color=red]Damage after hitting armor: 0: Father Time[/color]
Damage after calculating ar levels: 0: Father Time

Original damage: 4: Father Time
[color=red]Damage after hitting armor: 0: Father Time[/color]
Damage after calculating ar levels: 0: Father Time

Original damage: 23: Father Time
[color=red]Damage after hitting armor: 14: Father Time[/color]
Damage after calculating ar levels: 14: Father Time

Original damage: 34: Father Time
[color=red]Damage after hitting armor: 25: Father Time[/color]
Damage after calculating ar levels: 25: Father Time

Original damage: 19: Father Time
Damage after hitting armor: 19: Father Time
Damage after calculating ar levels: 19: Father Time

Original damage: 5: Father Time
Damage after hitting armor: 5: Father Time
Damage after calculating ar levels: 5: Father Time

Original damage: 13: Father Time
Damage after hitting armor: 13: Father Time
Damage after calculating ar levels: 13: Father Time

Original damage: 24: Father Time
Damage after hitting armor: 24: Father Time
Damage after calculating ar levels: 24: Father Time

Original damage: 6: Father Time
[color=red]Damage after hitting armor: 0: Father Time[/color]
Damage after calculating ar levels: 0: Father Time

Original damage: 19: Father Time
Damage after hitting armor: 19: Father Time
Damage after calculating ar levels: 19: Father Time

Original damage: 34: Father Time
Damage after hitting armor: 34: Father Time
Damage after calculating ar levels: 34: Father Time

Original damage: 35: Father Time
[color=red]Damage after hitting armor: 24: Father Time[/color]
Damage after calculating ar levels: 24: Father Time

Original damage: 34: Father Time
Damage after hitting armor: 34: Father Time
Damage after calculating ar levels: 34: Father Time

Original damage: 17: Father Time
Damage after hitting armor: 17: Father Time
Damage after calculating ar levels: 17: Father Time

Original damage: 34: Father Time
[color=red]Damage after hitting armor: 22: Father Time[/color]
Damage after calculating ar levels: 22: Father Time

Original damage: 24: Father Time
Damage after hitting armor: 24: Father Time
Damage after calculating ar levels: 24: Father Time

Original damage: 23: Father Time
Damage after hitting armor: 23: Father Time
Damage after calculating ar levels: 23: Father Time

Original damage: 19: Father Time
[color=red]Damage after hitting armor: 8: Father Time[/color]
Damage after calculating ar levels: 8: Father Time

Original damage: 6: Father Time
[color=red]Damage after hitting armor: 0: Father Time[/color]
Damage after calculating ar levels: 0: Father Time

Original damage: 16: Father Time
[color=red]Damage after hitting armor: 9: Father Time[/color]
Damage after calculating ar levels: 9: Father Time

Original damage: 5: Father Time
Damage after hitting armor: 5: Father Time
Damage after calculating ar levels: 5: Father Time

Original damage: 32: Father Time
Damage after hitting armor: 32: Father Time
Damage after calculating ar levels: 32: Father Time

Original damage: 15: Father Time
Damage after hitting armor: 15: Father Time
Damage after calculating ar levels: 15: Father Time

Original damage = the damage being passed to this method
Damage after hitting armor = There is a method called in the AbsorbDamage method that randomly selects a peice of armor from your body and delivers the damage to that peice of armor. Depending on that peices AR and durrability it absorves some of the damage here. This seems to be the offender.
Damage calculations = At the end of everything the AbsorbDamage method then AGAIN absorbs damage depending on the players overall AR. (which can futher drop the damage)

So it seems to me that what is happening is the damage is being calculated ( when it comes to determining the Weapon damage, slayers, etc. ), Then handed to this method, and then this method deducts the protection of armors AR twice, once when it damages the armor, and again when it finishes the absorbdamage method, am I correct in my thinking?

Anything on this guys would really help me, its such a fustrating problem because its not difficulty with code, but rather difficulty with logic. Thanks again all!
 
it is doing it twice i believe - because one is for the individual "striking point" and where it damages that armor
and the 2nd for the overall ar (accounts for less damage based on it glancing other parts 1st, getting to that part [i.e. past the shield or past chest/helm to gorget, etc]) and base "dodging" of the ar rating
 
Lord_Greywolf;786944 said:
it is doing it twice i believe - because one is for the individual "striking point" and where it damages that armor
and the 2nd for the overall ar (accounts for less damage based on it glancing other parts 1st, getting to that part [i.e. past the shield or past chest/helm to gorget, etc]) and base "dodging" of the ar rating

The more and more I research this, sadly the more it seems it's intentional. I pin pointed where the damage is being lost, its in the OnHit method in the BaseArmor class.

Code:
		public virtual int OnHit( BaseWeapon weapon, int damageTaken )
		{
			double HalfAr = ArmorRating / 2.0;
			int Absorbed = (int)(HalfAr + HalfAr*Utility.RandomDouble());

			damageTaken -= Absorbed;
			if ( damageTaken < 0 ) 
				damageTaken = 0;

			if ( Absorbed < 2 )
				Absorbed = 2;

			if ( 25 > Utility.Random( 100 ) ) // 25% chance to lower durability
			{
				if ( Core.AOS && m_AosArmorAttributes.SelfRepair > Utility.Random( 10 ) )
				{
					HitPoints += 2;
				}
				else
				{
					int wear;

					if ( weapon.Type == WeaponType.Bashing )
						wear = Absorbed / 2;
					else
						wear = Utility.Random( 2 );

					if ( wear > 0 && m_MaxHitPoints > 0 )
					{
						if ( m_HitPoints >= wear )
						{
							HitPoints -= wear;
							wear = 0;
						}
						else
						{
							wear -= HitPoints;
							HitPoints = 0;
						}

						if ( wear > 0 )
						{
							if ( m_MaxHitPoints > wear )
							{
								MaxHitPoints -= wear;

								if ( Parent is Mobile )
									((Mobile)Parent).LocalOverheadMessage( MessageType.Regular, 0x3B2, 1061121 ); // Your equipment is severely damaged.
							}
							else
							{
								Delete();
							}
						}
					}
				}
			}

			return damageTaken;
		}

Basically what is happening is its taking the armors base armor rating (which some reason by default is 13 for every peice of leather armor) and divides it by 2 which equals 6.5.

it then takes the 6.5 and 50% of the time doubles it, making it 13 again

it then takes the base damage being delt and subtracts the absorbed amount from above. Now seeing as most damage in in the teen range a great deal of the time it returns a 1 or less value.

Now this is just for a normal peice of leather armor, lets move this into an actual senario

A normal double axe can hit between 5 and 35 damage points. With 125 tactics (sumpremely accurate bonus) it goes up to a max of 52.5. Then vanq adds a max of 9 hp and exceptional adds 4 totaling 65.5 hp. Then add lumberjacking on top of that (10% in aos ) and you are talking an IDEAL (perfect hit) of 72 hp. Now granted this is the absolute best case senario.

So with a valorite crafted double axe, against a person with a valorite indestructable invulnerability plate tunic...

Tunic = 40 defence
Valorite + 14 defence
Exceptional + 4
Invul + 4 for invul
total = 72 defence

Which means that the minimum defence is 36 and a max of 72, which means you have a 50/50 chance of landing a max of a 35 damage (and this is a random dice roll, so most of the time its in the 5 to 20 range) and the other 50% of the time you are gurenteed a 0hp hit (which the on hit method converts to a 1hp hit).

Lucky armor isn't accumulative. When you are hit its a random dice roll of which layer you attack, so if someone is wearing all invulnerable head arms and gorget, but not a tunic or legs that they have a 40% chance of hitting the person as if they were naked, and another 60% chance to hit as if they were wearing a full invulnerable set.

Frankly I'm not a fan of this system.But I have to be very careful and do alot of research before rescripting it so I don't unbalance PvP.
 
also have to remember - what you modify here also effects CRITTERS attack and damage to them as well
they hit with "fists" which is also a base weapon, and they each have their own ar rating

this system is why on the old old shards, a dragon only needed 200 or so hp and would take a long while to take them down, because of their ar, and how the weapons worked with it
that is why val vang weapons, etc where so sought after, because you needed them to have a chance to bring down the big critters

and the val armor, etc was valued, because you took so much less damage, but need a smith to repair many many times

so yes be very very careful and test with both PvP and PvM - low, med & high values both ways (low weapon, high critter/armor and high weapon and low armor/ar and everywhere inbetween and matched values)

good luck with it
 
Lord_Greywolf;786952 said:
also have to remember - what you modify here also effects CRITTERS attack and damage to them as well
they hit with "fists" which is also a base weapon, and they each have their own ar rating

this system is why on the old old shards, a dragon only needed 200 or so hp and would take a long while to take them down, because of their ar, and how the weapons worked with it
that is why val vang weapons, etc where so sought after, because you needed them to have a chance to bring down the big critters

and the val armor, etc was valued, because you took so much less damage, but need a smith to repair many many times

so yes be very very careful and test with both PvP and PvM - low, med & high values both ways (low weapon, high critter/armor and high weapon and low armor/ar and everywhere inbetween and matched values)

good luck with it

Well lucky my research has show me that all formulas that calculated the total damage are done before the method that causes the armor to absorb the damage.

See the OnHit method is what determines how hard the hit will be, it considers pack instinct, skills, strength, etc. Then the on hit method calls the absorb damage method and sends it the damage parameter.

So by changing how the armor affects weapon strikes in essence won't affect monsters in any way, shape or form. The calculations for how the armor will defend against the monsters will stay the same, I am going only to modify the effects of the material and AR rating towards the calculations from a players hit.

To be honest Ill likely end up leaving it seeing as I've found complete logic in all aspects of the damage calculation, however I am going to write a custom OnHit and AbsorbDamage method for sh*ts and giggles to see if I like the level of gameplay better.

Thank you though for the friendly advice, As always I will do weeks worth of testing before releasing such a massive changes to the public. :D
 

gramps

Sorceror
i am having the same problem, even with the dice rolls set, lets say a war hammer does 7d5+1 the minimum dmg that a warhammer should do is 8, but i am still getting 1 dmg hits rather frequently regaurdless of the type of warhammer being used, whether it being a valorite runic, or gm i am still getting 1 dmg hits
 

Peoharen

Sorceror
Hmm, this didn't used to work like this in practice. Back in RC1 I wore ECP Invul Valorite with a Heater Shield (which alone is +33ar) and the cloak/robes. I'm unsure what my AR was but I'm thinking it was around 120.

Against an equal armored foe we could not die in PvP and not becuase we only dealt 1 to each other. But our at cap dex & healing was fast enough to set us back at full life before we dropped below 30HP.

It could very well be the damage was altered there. *shurgs*
 
Peoharen;813781 said:
Hmm, this didn't used to work like this in practice. Back in RC1 I wore ECP Invul Valorite with a Heater Shield (which alone is +33ar) and the cloak/robes. I'm unsure what my AR was but I'm thinking it was around 120.

Against an equal armored foe we could not die in PvP and not becuase we only dealt 1 to each other. But our at cap dex & healing was fast enough to set us back at full life before we dropped below 30HP.

It could very well be the damage was altered there. *shurgs*

This is exactly what I mean, even with a full suit of armor you should still take fair damage, just be able to overcome it with your dex and healing. Not only is the weapon/melee/armor damage completely off, but I just had a beta tester show me a simple explosion/Energybolt/purple pot combo and it EASILY dropped a player, and likely could have 3 times over. The damage should have just barely been enough to kill a player with the possibility of healing through it (Ive seen this combo done a million times on the UOGamers: Hybrid server ).

Does anyone know of a good source to locate more accurate damage for pre aos damage?
 

Murzin

Knight
vermillion2083;786687 said:
I think everyone who reads this can agree with me that no matter what the era, a 7x lumberjacker with a valorite runic double axe should never do a hit for 1hp, yet alone do hits like that 45% of the time.

valorite weapons were AOS
runic weaps were AOS
 
Murzin;817292 said:
valorite weapons were AOS
runic weaps were AOS

I don't understand your point... Yes they were AoS but a runic hammer can be added in pre AoS and the weapon damage is vanquishing damage with the damage bonus of a GM crafted weapon, meaning it is actually more destructive then a vanquish weapon.

Regardless, testing was done with store bought weapons, GM crafted weapons, vanquishing magic weapons, and runic made weapons, the results are consistently unbalanced across the board.
 
A nitpick: runic weapons were introduced with Publish 16, which was pushed in 2002--before AoS, which released in 2003.

Anyway, there are some bugs with pre-AoS weapon damage in RunUO. They're easy enough to track down if you compare the weapon and armor code with an archived version of Stratics.
 

Murzin

Knight
vermillion2083;817479 said:
I don't understand your point... Yes they were AoS but a runic hammer can be added in pre AoS and the weapon damage is vanquishing damage with the damage bonus of a GM crafted weapon, meaning it is actually more destructive then a vanquish weapon.

if that is the case, then that would mean that the code is not properly seperated as that bonus didnt exist pre AOS.


and its been known since even i think even 1.0 that pre-AOS damage code did not work properly.

its just another hurdle you have to get over when trying to make a non-AOS server.


if i remember right they said they never got around to fixing it because there were so many different versions of the pre-AOS damage code, no matter what you wanted to go with patch wise, you would have to re-write the code anyway.
 
Top