fix: Fixes random bias & Adds back champion arties for UOML (#1235)

* Fixes RNG bias, we should never do `Utility.RandomDouble() <=`
* Adds back champion artifacts behind UOML flag.
This commit is contained in:
Kamron Batman 2022-11-09 16:33:27 -08:00 • committed by GitHub
parent 810061db8c
commit 8e01db8555
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 289 additions and 335 deletions

View file

@ -2248,7 +2248,7 @@ public abstract class BaseAI
if (blocked)
{
var offset = Utility.RandomDouble() >= 0.6 ? 1 : -1;
var offset = Utility.RandomDouble() < 0.4 ? 1 : -1;
for (var i = 0; i < 2; ++i)
{

View file

@ -8,7 +8,7 @@ namespace Server.Mobiles
Body = Utility.RandomList(0xE8, 0xE9);
BaseSoundID = 0x64;
if (Utility.RandomDouble() <= 0.5)
if (Utility.RandomBool())
{
Hue = 0x901;
}

View file

@ -103,7 +103,7 @@ public class LesserHiryu : BaseMount
{
var tamingChance = base.GetControlChance(m, useBaseSkill);
if (tamingChance >= 0.95)
if (tamingChance < 0.05)
{
return tamingChance;
}

View file

@ -52,7 +52,7 @@ namespace Server.Mobiles
public override string DefaultName => "a giant snake";
public override Poison PoisonImmune => Poison.Greater;
public override Poison HitPoison => Utility.RandomDouble() <= 0.8 ? Poison.Greater : Poison.Deadly;
public override Poison HitPoison => Utility.RandomDouble() < 0.8 ? Poison.Greater : Poison.Deadly;
public override bool DeathAdderCharmable => true;

View file

@ -2995,7 +2995,7 @@ namespace Server.Mobiles
{
PackItem(new ParagonChest(Name, treasureLevel));
}
else if ((Map == Map.Felucca || Map == Map.Trammel) && Utility.RandomDouble() <= TreasureMap.LootChance)
else if ((Map == Map.Felucca || Map == Map.Trammel) && Utility.RandomDouble() < TreasureMap.LootChance)
{
PackItem(new TreasureMap(treasureLevel, Map));
}
@ -4222,7 +4222,7 @@ namespace Server.Mobiles
{
for (var i = 0; i < amount; ++i)
{
if (m_Loyalty < MaxLoyalty && Utility.RandomDouble() <= 0.5)
if (m_Loyalty < MaxLoyalty && Utility.RandomBool())
{
m_Loyalty += 10;
}
@ -4799,7 +4799,7 @@ namespace Server.Mobiles
public void PackNecroScroll(int index)
{
if (!Core.AOS || Utility.RandomDouble() >= 0.05)
if (!Core.AOS || Utility.RandomDouble() < 0.95)
{
return;
}

View file

@ -37,7 +37,7 @@ namespace Server.Mobiles
public override string CorpseName => "a death adder corpse";
public override string DefaultName => "a death adder";
public override Poison HitPoison => Utility.RandomDouble() <= 0.8 ? Poison.Greater : Poison.Deadly;
public override Poison HitPoison => Utility.RandomDouble() < 0.8 ? Poison.Greater : Poison.Deadly;
public override void Serialize(IGenericWriter writer)
{

View file

@ -51,7 +51,7 @@ namespace Server.Mobiles
{
base.OnDeath(c);
if (Utility.RandomDouble() < 0.5)
if (Utility.RandomBool())
{
c.DropItem(new FragmentOfAMap());
}

View file

@ -191,18 +191,12 @@ namespace Server.Mobiles
}
var luck = LootPack.GetLuckChanceForKiller(boss);
int chance;
if (boss is DemonKnight)
return boss switch
{
chance = 1500 + luck / 5;
}
else
{
chance = 750 + luck / 10;
}
return chance;
DemonKnight => 1500 + luck / 5,
_ => 750 + luck / 10
};
}
public static bool CheckArtifactChance(Mobile boss) => GetArtifactChance(boss) > Utility.Random(100000);

View file

@ -53,7 +53,7 @@ namespace Server.Mobiles
public override bool Unprovokable => Core.SE;
public override bool AreaPeaceImmune => Core.SE;
public override Poison PoisonImmune => Poison.Lethal;
public override Poison HitPoison => Utility.RandomDouble() <= 0.8 ? Poison.Greater : Poison.Deadly;
public override Poison HitPoison => Utility.RandomDouble() < 0.8 ? Poison.Greater : Poison.Deadly;
public override int TreasureMapLevel => 1;

View file

@ -40,7 +40,7 @@ namespace Server.Mobiles
SolenHelper.PackPicnicBasket(this);
PackItem(new ZoogiFungus(Utility.RandomDouble() > 0.05 ? 5 : 25));
PackItem(new ZoogiFungus(Utility.RandomDouble() < 0.95 ? 5 : 25));
if (Utility.RandomDouble() < 0.05)
{

View file

@ -38,7 +38,7 @@ namespace Server.Mobiles
SolenHelper.PackPicnicBasket(this);
PackItem(new ZoogiFungus(Utility.RandomDouble() > 0.05 ? 4 : 16));
PackItem(new ZoogiFungus(Utility.RandomDouble() < 0.95 ? 4 : 16));
}
public RedSolenInfiltratorQueen(Serial serial) : base(serial)

View file

@ -38,7 +38,7 @@ namespace Server.Mobiles
SolenHelper.PackPicnicBasket(this);
PackItem(new ZoogiFungus(Utility.RandomDouble() > 0.05 ? 3 : 13));
PackItem(new ZoogiFungus(Utility.RandomDouble() < 0.95 ? 3 : 13));
}
public RedSolenInfiltratorWarrior(Serial serial) : base(serial)

View file

@ -39,7 +39,7 @@ namespace Server.Mobiles
SolenHelper.PackPicnicBasket(this);
PackItem(new ZoogiFungus(Utility.RandomDouble() > 0.05 ? 5 : 25));
PackItem(new ZoogiFungus(Utility.RandomDouble() < 0.95 ? 5 : 25));
if (Utility.RandomDouble() < 0.05)
{

View file

@ -38,7 +38,7 @@ namespace Server.Mobiles
VirtualArmor = 35;
SolenHelper.PackPicnicBasket(this);
PackItem(new ZoogiFungus(Utility.RandomDouble() > 0.05 ? 3 : 13));
PackItem(new ZoogiFungus(Utility.RandomDouble() < 0.95 ? 3 : 13));
if (Utility.RandomDouble() < 0.05)
{

View file

@ -105,7 +105,7 @@ namespace Server.Mobiles
m_Thrown++;
if (Utility.RandomDouble() <= 0.75 && m_Thrown % 2 == 1) // 75% chance to quickly throw another bomb
if (m_Thrown % 2 == 1 && Utility.RandomDouble() < 0.75) // 75% chance to quickly throw another bomb
{
m_NextBomb = Core.Now + TimeSpan.FromSeconds(3.0);
}

View file

@ -52,7 +52,7 @@ namespace Server.Mobiles
AddItem(new BoneArms());
AddItem(new BoneLegs());
if (Utility.RandomDouble() < 0.5)
if (Utility.RandomBool())
{
AddItem(new SavageMask());
}

View file

@ -75,7 +75,7 @@ namespace Server.Mobiles
{
base.OnGaveMeleeAttack(defender, damage);
if (Utility.RandomDouble() > 0.2)
if (Utility.RandomDouble() < 0.80)
{
return;
}

View file

@ -73,7 +73,7 @@ namespace Server.Mobiles
{
base.OnGaveMeleeAttack(defender, damage);
if (Utility.RandomDouble() >= 0.1)
if (Utility.RandomDouble() < 0.9)
{
return;
}

View file

@ -94,7 +94,7 @@ namespace Server.Mobiles
public void AreaPeace()
{
if (Combatant == null || Deleted || !Alive || m_NextPeace > Core.Now || Utility.RandomDouble() > 0.1)
if (Combatant == null || Deleted || !Alive || m_NextPeace > Core.Now || Utility.RandomDouble() < 0.9)
{
return;
}
@ -122,7 +122,7 @@ namespace Server.Mobiles
public void AreaUndress()
{
if (Combatant == null || Deleted || !Alive || m_NextUndress > Core.Now || Utility.RandomDouble() > 0.005)
if (Combatant == null || Deleted || !Alive || m_NextUndress > Core.Now || Utility.RandomDouble() >= 0.005)
{
return;
}

View file

@ -90,7 +90,7 @@ namespace Server.Mobiles
public void Peace(Mobile target)
{
if (target == null || Deleted || !Alive || m_NextPeace > Core.Now || Utility.RandomDouble() > 0.1)
if (target == null || Deleted || !Alive || m_NextPeace > Core.Now || Utility.RandomDouble() < 0.9)
{
return;
}
@ -111,7 +111,7 @@ namespace Server.Mobiles
public void Suppress(Mobile target)
{
if (target == null || m_Suppressed.ContainsKey(target) || Deleted || !Alive ||
m_NextSuppress > Core.Now || Utility.RandomDouble() > 0.1)
m_NextSuppress > Core.Now || Utility.RandomDouble() < 0.9)
{
return;
}
@ -160,7 +160,7 @@ namespace Server.Mobiles
public void Undress(Mobile target)
{
if (target == null || Deleted || !Alive || m_NextUndress > Core.Now || Utility.RandomDouble() > 0.005)
if (target == null || Deleted || !Alive || m_NextUndress > Core.Now || Utility.RandomDouble() >= 0.005)
{
return;
}
@ -193,7 +193,7 @@ namespace Server.Mobiles
public void Provoke(Mobile target)
{
if (target == null || Deleted || !Alive || m_NextProvoke > Core.Now || Utility.RandomDouble() > 0.05)
if (target == null || Deleted || !Alive || m_NextProvoke > Core.Now || Utility.RandomDouble() < 0.95)
{
return;
}

View file

@ -167,7 +167,7 @@ namespace Server.Mobiles
{
base.OnGaveMeleeAttack(defender, damage);
if (Utility.RandomDouble() <= 0.2)
if (Utility.RandomDouble() < 0.2)
{
Earthquake();
}

View file

@ -103,7 +103,7 @@ namespace Server.Mobiles
public override void AlterDamageScalarFrom(Mobile caster, ref double scalar)
{
if (Utility.RandomDouble() <= 0.1)
if (Utility.RandomDouble() < 0.1)
{
SpawnPixies(caster);
}
@ -122,7 +122,7 @@ namespace Server.Mobiles
{
base.OnGotMeleeAttack(attacker, damage);
if (Utility.RandomDouble() <= 0.1)
if (Utility.RandomDouble() < 0.1)
{
SpawnPixies(attacker);
}

View file

@ -100,7 +100,7 @@ namespace Server.Mobiles
{
base.OnGaveMeleeAttack(defender, damage);
if (Utility.RandomDouble() >= 0.1)
if (Utility.RandomDouble() < 0.9)
{
return;
}

View file

@ -122,16 +122,16 @@ namespace Server.Mobiles
{
base.OnGotMeleeAttack(attacker, damage);
if (Hits > HitsMax / 4)
if (Utility.RandomDouble() < 0.25)
{
if (Utility.RandomDouble() <= 0.25)
if (Hits > HitsMax / 4)
{
SpawnBogling(attacker);
}
}
else if (Utility.RandomDouble() <= 0.25)
{
EatBoglings();
else
{
EatBoglings();
}
}
}
}

View file

@ -40,7 +40,7 @@ namespace Server.Mobiles
PackReg(3);
PackItem(new FertileDirt(Utility.RandomMinMax(1, 10)));
if (Utility.RandomDouble() <= 0.2)
if (Utility.RandomDouble() < 0.2)
{
PackItem(new ExecutionersCap());
}

View file

@ -56,7 +56,7 @@ namespace Server.Mobiles
public override FoodType FavoriteFood => FoodType.Meat;
public override PackInstinct PackInstinct => PackInstinct.Arachnid;
public override Poison PoisonImmune => Poison.Greater;
public override Poison HitPoison => Utility.RandomDouble() <= 0.8 ? Poison.Greater : Poison.Deadly;
public override Poison HitPoison => Utility.RandomDouble() < 0.8 ? Poison.Greater : Poison.Deadly;
public override void GenerateLoot()
{

View file

@ -93,7 +93,7 @@ namespace Server.Mobiles
{
base.OnGaveMeleeAttack(defender, damage);
if (Utility.RandomDouble() >= 0.1)
if (Utility.RandomDouble() < 0.9)
{
return;
}

View file

@ -49,7 +49,7 @@ namespace Server.Mobiles
AddItem(new Tessen());
if (Utility.RandomDouble() <= 0.02)
if (Utility.RandomDouble() < 0.02)
{
PackItem(new OrigamiPaper());
}

View file

@ -77,7 +77,7 @@ namespace Server.Mobiles
{
base.OnGaveMeleeAttack(defender, damage);
if (Utility.RandomDouble() >= 0.1)
if (Utility.RandomDouble() < 0.9)
{
return;
}

View file

@ -60,7 +60,7 @@ namespace Server.Mobiles
{
base.OnGaveMeleeAttack(defender, damage);
if (Utility.RandomDouble() >= 0.1 || m_Table.Contains(defender))
if (Utility.RandomDouble() < 0.9 || m_Table.Contains(defender))
{
return;
}

View file

@ -75,7 +75,7 @@ namespace Server.Mobiles
break;
}
if (Utility.RandomDouble() > .2)
if (Utility.RandomDouble() < 0.80)
{
AddItem(new NoDachi());
}

View file

@ -99,7 +99,7 @@ namespace Server.Mobiles
{
base.OnGaveMeleeAttack(defender, damage);
if (Utility.RandomDouble() >= 0.05)
if (Utility.RandomDouble() < 0.95)
{
return;
}

View file

@ -82,7 +82,7 @@ namespace Server.Mobiles
{
base.OnGaveMeleeAttack(defender, damage);
if (Utility.RandomDouble() >= 0.1)
if (Utility.RandomDouble() < 0.9)
{
return;
}

View file

@ -185,12 +185,12 @@ namespace Server.Mobiles
return;
}
if (Utility.RandomDouble() <= 0.6) // 60% chance to polymorph attacker into a ratman
if (Utility.RandomDouble() < 0.6) // 60% chance to polymorph attacker into a ratman
{
Polymorph(target);
}
if (Utility.RandomDouble() <= 0.2) // 20% chance to more ratmen
if (Utility.RandomDouble() < 0.2) // 20% chance to spawn more ratmen
{
SpawnRatmen(target);
}

View file

@ -41,26 +41,14 @@ namespace Server.Mobiles
var version = reader.ReadInt();
}
public Item GetArtifact()
{
var random = Utility.RandomDouble();
if (random <= 0.05)
public Item GetArtifact() =>
Utility.RandomDouble() switch
{
return CreateArtifact(UniqueList);
}
if (random <= 0.15)
{
return CreateArtifact(SharedList);
}
if (random <= 0.30)
{
return CreateArtifact(DecorativeList);
}
return null;
}
< 0.05 => CreateArtifact(UniqueList),
< 0.15 => CreateArtifact(SharedList),
< 0.30 => CreateArtifact(DecorativeList),
_ => null
};
public Item CreateArtifact(Type[] list)
{
@ -82,23 +70,14 @@ namespace Server.Mobiles
return artifact;
}
private PowerScroll CreateRandomPowerScroll()
private static PowerScroll CreateRandomPowerScroll()
{
int level;
var random = Utility.RandomDouble();
if (random <= 0.05)
var level = Utility.RandomDouble() switch
{
level = 20;
}
else if (random <= 0.4)
{
level = 15;
}
else
{
level = 10;
}
< 0.05 => 20,
< 0.4 => 15,
_ => 10
};
return PowerScroll.CreateRandomNoCraft(level, level);
}
@ -226,16 +205,13 @@ namespace Server.Mobiles
{
prot.AddToBackpack(powerScroll);
}
else if (prot.Corpse?.Deleted == false)
{
prot.Corpse.DropItem(powerScroll);
}
else
{
if (prot.Corpse?.Deleted == false)
{
prot.Corpse.DropItem(powerScroll);
}
else
{
prot.AddToBackpack(powerScroll);
}
prot.AddToBackpack(powerScroll);
}
}
}
@ -342,49 +318,51 @@ namespace Server.Mobiles
g.MoveToWorld(new Point3D(m_X, m_Y, z), m_Map);
if (Utility.RandomDouble() <= 0.5)
if (Utility.RandomDouble() < 0.95)
{
switch (Utility.Random(3))
{
case 0: // Fire column
{
Effects.SendLocationParticles(
EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration),
0x3709,
10,
30,
5052
);
Effects.PlaySound(g, 0x208);
return;
}
break;
}
case 1: // Explosion
{
Effects.SendLocationParticles(
EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration),
0x36BD,
20,
10,
5044
);
Effects.PlaySound(g, 0x307);
switch (Utility.Random(3))
{
case 0: // Fire column
{
Effects.SendLocationParticles(
EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration),
0x3709,
10,
30,
5052
);
Effects.PlaySound(g, 0x208);
break;
}
case 2: // Ball of fire
{
Effects.SendLocationParticles(
EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration),
0x36FE,
10,
10,
5052
);
break;
}
case 1: // Explosion
{
Effects.SendLocationParticles(
EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration),
0x36BD,
20,
10,
5044
);
Effects.PlaySound(g, 0x307);
break;
}
}
break;
}
case 2: // Ball of fire
{
Effects.SendLocationParticles(
EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration),
0x36FE,
10,
10,
5052
);
break;
}
}
}
}

View file

@ -88,9 +88,9 @@ namespace Server.Mobiles
Instances.Add(this);
}
public Type[] UniqueList => new[] { typeof(AcidProofRobe) };
public Type[] SharedList => new[] { typeof(TheRobeOfBritanniaAri) };
public Type[] DecorativeList => new[] { typeof(EvilIdolSkull), typeof(SkullPole) };
public static Type[] UniqueList => new[] { typeof(AcidProofRobe) };
public static Type[] SharedList => new[] { typeof(TheRobeOfBritanniaAri) };
public static Type[] DecorativeList => new[] { typeof(EvilIdolSkull), typeof(SkullPole) };
public static List<Harrower> Instances { get; } = new();
@ -269,29 +269,14 @@ namespace Server.Mobiles
for (var i = 0; i < 16; ++i)
{
int level;
var random = Utility.RandomDouble();
if (random <= 0.1)
var level = Utility.RandomDouble() switch
{
level = 25;
}
else if (random <= 0.25)
{
level = 20;
}
else if (random <= 0.45)
{
level = 15;
}
else if (random <= 0.70)
{
level = 10;
}
else
{
level = 5;
}
< 0.1 => 25,
< 0.25 => 20,
< 0.45 => 15,
< 0.70 => 10,
_ => 5
};
var m = toGive[i % toGive.Count];
@ -482,9 +467,8 @@ namespace Server.Mobiles
}
else
{
to.SendLocalizedMessage(
1062317
); // For your valor in combating the fallen beast, a special artifact has been bestowed on you.
// For your valor in combating the fallen beast, a special artifact has been bestowed on you.
to.SendLocalizedMessage(1062317);
}
}
@ -492,26 +476,14 @@ namespace Server.Mobiles
m.Player && m.Alive && m.InRange(Location, 32) &&
m.Backpack?.CheckHold(m, artifact, false) == true;
public Item GetArtifact()
{
var random = Utility.RandomDouble();
if (random <= 0.05)
public Item GetArtifact() =>
Utility.RandomDouble() switch
{
return CreateArtifact(UniqueList);
}
if (random <= 0.15)
{
return CreateArtifact(SharedList);
}
if (random <= 0.30)
{
return CreateArtifact(DecorativeList);
}
return null;
}
< 0.05 => CreateArtifact(UniqueList),
< 0.15 => CreateArtifact(SharedList),
< 0.30 => CreateArtifact(DecorativeList),
_ => null
};
public Item CreateArtifact(Type[] list) => Loot.Construct(list.RandomElement());
@ -564,7 +536,7 @@ namespace Server.Mobiles
return;
}
if (Utility.RandomDouble() > 0.25)
if (Utility.RandomDouble() < 0.75)
{
return;
}
@ -678,49 +650,51 @@ namespace Server.Mobiles
g.MoveToWorld(new Point3D(m_X, m_Y, z), m_Map);
if (Utility.RandomDouble() <= 0.5)
if (Utility.RandomDouble() < 0.95)
{
switch (Utility.Random(3))
{
case 0: // Fire column
{
Effects.SendLocationParticles(
EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration),
0x3709,
10,
30,
5052
);
Effects.PlaySound(g, 0x208);
return;
}
break;
}
case 1: // Explosion
{
Effects.SendLocationParticles(
EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration),
0x36BD,
20,
10,
5044
);
Effects.PlaySound(g, 0x307);
switch (Utility.Random(3))
{
case 0: // Fire column
{
Effects.SendLocationParticles(
EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration),
0x3709,
10,
30,
5052
);
Effects.PlaySound(g, 0x208);
break;
}
case 2: // Ball of fire
{
Effects.SendLocationParticles(
EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration),
0x36FE,
10,
10,
5052
);
break;
}
case 1: // Explosion
{
Effects.SendLocationParticles(
EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration),
0x36BD,
20,
10,
5044
);
Effects.PlaySound(g, 0x307);
break;
}
}
break;
}
case 2: // Ball of fire
{
Effects.SendLocationParticles(
EffectItem.Create(g.Location, g.Map, EffectItem.DefaultDuration),
0x36FE,
10,
10,
5052
);
break;
}
}
}
}

View file

@ -151,7 +151,7 @@ namespace Server.Mobiles
{
scalar *= 0.1;
if (Utility.RandomDouble() <= 0.1)
if (Utility.RandomDouble() < 0.1)
{
SpawnPixies(caster);
}
@ -173,7 +173,7 @@ namespace Server.Mobiles
CheckQueen();
if (m_Queen != null && Utility.RandomDouble() <= 0.1)
if (m_Queen != null && Utility.RandomDouble() < 0.1)
{
SpawnPixies(attacker);
}

View file

@ -144,7 +144,7 @@ namespace Server.Mobiles
{
base.OnGaveMeleeAttack(defender, damage);
if (Utility.RandomDouble() <= 0.1) // 10% chance to drop or throw an unholy bone
if (Utility.RandomDouble() < 0.1) // 10% chance to drop or throw an unholy bone
{
AddUnholyBone(defender, 0.25);
}
@ -156,7 +156,7 @@ namespace Server.Mobiles
{
base.OnGotMeleeAttack(attacker, damage);
if (Utility.RandomDouble() <= 0.1) // 10% chance to drop or throw an unholy bone
if (Utility.RandomDouble() < 0.1) // 10% chance to drop or throw an unholy bone
{
AddUnholyBone(attacker, 0.25);
}
@ -166,7 +166,7 @@ namespace Server.Mobiles
{
base.AlterDamageScalarFrom(caster, ref scalar);
if (Utility.RandomDouble() <= 0.1) // 10% chance to throw an unholy bone
if (Utility.RandomDouble() < 0.1) // 10% chance to throw an unholy bone
{
AddUnholyBone(caster, 1.0);
}

View file

@ -83,7 +83,7 @@ namespace Server.Mobiles
{
base.OnGaveMeleeAttack(defender, damage);
if (Utility.RandomDouble() <= 0.2)
if (Utility.RandomDouble() < 0.2)
{
Earthquake();
}

View file

@ -78,7 +78,7 @@ namespace Server.Mobiles
public override void AlterDamageScalarFrom(Mobile caster, ref double scalar)
{
if (Utility.RandomDouble() <= 0.1)
if (Utility.RandomDouble() < 0.1)
{
SpawnPixies(caster);
}
@ -97,7 +97,7 @@ namespace Server.Mobiles
{
base.OnGotMeleeAttack(attacker, damage);
if (Utility.RandomDouble() <= 0.1)
if (Utility.RandomDouble() < 0.1)
{
SpawnPixies(attacker);
}