Bug Fixes

- Secure settings for Guild now per EA, where it has to be owner of the house, and must be at least a member of the Guild
- Fixed issue with lower requirements and durability not counting as properties
- Fixed issue where anyone could removed items from a secured mailbox
This commit is contained in:
Dexter 2019-06-09 18:12:59 -07:00
parent 0319eda930
commit b9c0a5bc40
10 changed files with 164 additions and 213 deletions

View file

@ -1,4 +1,6 @@
using System;
using Server.Mobiles;
using Server.Guilds;
using Server.Multis;
using Server.Network;
@ -12,62 +14,63 @@ namespace Server.Gumps
public class SetSecureLevelGump : Gump
{
private readonly ISecurable m_Info;
public SetSecureLevelGump(Mobile owner, ISecurable info, BaseHouse house)
private ISecurable m_Info;
public SetSecureLevelGump(Mobile from, ISecurable info, BaseHouse house)
: base(50, 50)
{
this.m_Info = info;
m_Info = info;
Mobile owner = house.Owner;
this.AddPage(0);
AddPage(0);
int offset = (Guild.NewGuildSystem) ? 20 : 0;
this.AddBackground(0, 0, 220, 160 + offset, 5054);
AddBackground(0, 0, 220, 160 + offset, 5054);
this.AddImageTiled(10, 10, 200, 20, 5124);
this.AddImageTiled(10, 40, 200, 20, 5124);
this.AddImageTiled(10, 70, 200, 80 + offset, 5124);
AddImageTiled(10, 10, 200, 20, 5124);
AddImageTiled(10, 40, 200, 20, 5124);
AddImageTiled(10, 70, 200, 80 + offset, 5124);
this.AddAlphaRegion(10, 10, 200, 140 + offset);
AddAlphaRegion(10, 10, 200, 140 + offset);
this.AddHtmlLocalized(10, 10, 200, 20, 1061276, 32767, false, false); // <CENTER>SET ACCESS</CENTER>
this.AddHtmlLocalized(10, 40, 100, 20, 1041474, 32767, false, false); // Owner:
AddHtmlLocalized(10, 10, 200, 20, 1061276, 32767, false, false); // <CENTER>SET ACCESS</CENTER>
AddHtmlLocalized(10, 40, 100, 20, 1041474, 32767, false, false); // Owner:
this.AddLabel(110, 40, 1152, owner == null ? "" : owner.Name);
AddLabel(110, 40, 1152, owner == null ? "" : owner.Name);
this.AddButton(10, 70, this.GetFirstID(SecureLevel.Owner), 4007, 1, GumpButtonType.Reply, 0);
this.AddHtmlLocalized(45, 70, 150, 20, 1061277, this.GetColor(SecureLevel.Owner), false, false); // Owner Only
AddButton(10, 70, GetFirstID(SecureLevel.Owner), 4007, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 70, 150, 20, 1061277, GetColor(SecureLevel.Owner), false, false); // Owner Only
this.AddButton(10, 90, this.GetFirstID(SecureLevel.CoOwners), 4007, 2, GumpButtonType.Reply, 0);
this.AddHtmlLocalized(45, 90, 150, 20, 1061278, this.GetColor(SecureLevel.CoOwners), false, false); // Co-Owners
AddButton(10, 90, GetFirstID(SecureLevel.CoOwners), 4007, 2, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 90, 150, 20, 1061278, GetColor(SecureLevel.CoOwners), false, false); // Co-Owners
this.AddButton(10, 110, this.GetFirstID(SecureLevel.Friends), 4007, 3, GumpButtonType.Reply, 0);
this.AddHtmlLocalized(45, 110, 150, 20, 1061279, this.GetColor(SecureLevel.Friends), false, false); // Friends
AddButton(10, 110, GetFirstID(SecureLevel.Friends), 4007, 3, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 110, 150, 20, 1061279, GetColor(SecureLevel.Friends), false, false); // Friends
Mobile houseOwner = house.Owner;
if (Guild.NewGuildSystem && house != null && houseOwner != null && houseOwner.Guild != null && ((Guild)houseOwner.Guild).Leader == houseOwner) //Only the actual House owner AND guild master can set guild secures
if (Guild.NewGuildSystem && owner == from && from.Guild != null && ((PlayerMobile)from).GuildRank.Rank >= 1)
{
this.AddButton(10, 130, this.GetFirstID(SecureLevel.Guild), 4007, 5, GumpButtonType.Reply, 0);
this.AddHtmlLocalized(45, 130, 150, 20, 1063455, this.GetColor(SecureLevel.Guild), false, false); // Guild Members
AddButton(10, 130, GetFirstID(SecureLevel.Guild), 4007, 5, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 130, 150, 20, 1063455, GetColor(SecureLevel.Guild), false, false); // Guild Members
}
this.AddButton(10, 130 + offset, this.GetFirstID(SecureLevel.Anyone), 4007, 4, GumpButtonType.Reply, 0);
this.AddHtmlLocalized(45, 130 + offset, 150, 20, 1061626, this.GetColor(SecureLevel.Anyone), false, false); // Anyone
AddButton(10, 130 + offset, GetFirstID(SecureLevel.Anyone), 4007, 4, GumpButtonType.Reply, 0);
AddHtmlLocalized(45, 130 + offset, 150, 20, 1061626, GetColor(SecureLevel.Anyone), false, false); // Anyone
}
public int GetColor(SecureLevel level)
{
return (this.m_Info.Level == level) ? 0x7F18 : 0x7FFF;
return (m_Info.Level == level) ? 0x7F18 : 0x7FFF;
}
public int GetFirstID(SecureLevel level)
{
return (this.m_Info.Level == level) ? 4006 : 4005;
return (m_Info.Level == level) ? 4006 : 4005;
}
public override void OnResponse(NetState state, RelayInfo info)
{
SecureLevel level = this.m_Info.Level;
SecureLevel level = m_Info.Level;
switch ( info.ButtonID )
{
@ -88,15 +91,15 @@ namespace Server.Gumps
break;
}
if (this.m_Info.Level == level)
if (m_Info.Level == level)
{
state.Mobile.SendLocalizedMessage(1061281); // Access level unchanged.
}
else
{
this.m_Info.Level = level;
m_Info.Level = level;
state.Mobile.SendLocalizedMessage(1061280); // New access level set.
}
}
}
}
}

View file

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Server;
using Server.Items;
using Server.Misc;
@ -162,20 +164,12 @@ namespace Server.Mobiles
private void Teleport()
{
System.Collections.Generic.List<Mobile> toTele = new System.Collections.Generic.List<Mobile>();
IPooledEnumerable eable = this.GetMobilesInRange(StrikingRange);
foreach (Mobile mob in eable)
{
if (mob != this && mob.Alive && mob.Player && this.CanBeHarmful(mob, false))
toTele.Add(mob);
}
eable.Free();
var toTele = SpellHelper.AcquireIndirectTargets(this, Location, Map, StrikingRange).OfType<PlayerMobile>().ToList();
if (toTele.Count > 0)
{
Mobile from = toTele[Utility.Random(toTele.Count)];
var from = toTele[Utility.Random(toTele.Count)];
if (from != null)
{
Combatant = from;
@ -188,104 +182,105 @@ namespace Server.Mobiles
}
}
ColUtility.Free(toTele);
m_Teleport = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(40, 60));
}
public void ChangeOpponent()
{
Mobile agro, best = null;
double distance, random = Utility.RandomDouble();
if ( random < 0.75 )
{
// find random target relatively close
for ( int i = 0; i < Aggressors.Count && best == null; i ++ )
{
agro = Validate( Aggressors[ i ].Attacker );
if ( agro == null )
continue;
distance = StrikingRange - GetDistanceToSqrt( agro );
if ( distance > 0 && distance < StrikingRange - 2 && InLOS( agro.Location ) )
{
distance /= StrikingRange;
if ( random < distance )
best = agro;
}
}
}
else
{
int damage = 0;
// find a player who dealt most damage
for ( int i = 0; i < DamageEntries.Count; i ++ )
{
agro = Validate( DamageEntries[ i ].Damager );
if ( agro == null )
continue;
distance = GetDistanceToSqrt( agro );
if ( distance < StrikingRange && DamageEntries[ i ].DamageGiven > damage && InLOS( agro.Location ) )
{
best = agro;
damage = DamageEntries[ i ].DamageGiven;
}
}
}
if ( best != null )
{
// teleport
best.Location = BasePeerless.GetSpawnPosition( Location, Map, 1 );
best.FixedParticles( 0x376A, 9, 32, 0x13AF, EffectLayer.Waist );
best.PlaySound( 0x1FE );
Timer.DelayCall( TimeSpan.FromSeconds( 1 ), new TimerCallback( delegate()
{
// poison
best.ApplyPoison( this, HitPoison );
best.FixedParticles( 0x374A, 10, 15, 5021, EffectLayer.Waist );
best.PlaySound( 0x474 );
} ) );
m_Change = DateTime.UtcNow + TimeSpan.FromSeconds( Utility.RandomMinMax( 5, 10 ) );
}
}
public void ChangeOpponent()
{
Mobile agro, best = null;
double distance, random = Utility.RandomDouble();
if (random < 0.75)
{
// find random target relatively close
for (int i = 0; i < Aggressors.Count && best == null; i++)
{
agro = Validate(Aggressors[i].Attacker);
if (agro == null)
continue;
distance = StrikingRange - GetDistanceToSqrt(agro);
if (distance > 0 && distance < StrikingRange - 2 && InLOS(agro.Location))
{
distance /= StrikingRange;
if (random < distance)
best = agro;
}
}
}
else
{
int damage = 0;
// find a player who dealt most damage
for (int i = 0; i < DamageEntries.Count; i++)
{
agro = Validate(DamageEntries[i].Damager);
if (agro == null)
continue;
distance = GetDistanceToSqrt(agro);
if (distance < StrikingRange && DamageEntries[i].DamageGiven > damage && InLOS(agro.Location))
{
best = agro;
damage = DamageEntries[i].DamageGiven;
}
}
}
if (best != null)
{
// teleport
best.Location = BasePeerless.GetSpawnPosition(Location, Map, 1);
best.FixedParticles(0x376A, 9, 32, 0x13AF, EffectLayer.Waist);
best.PlaySound(0x1FE);
Timer.DelayCall(TimeSpan.FromSeconds(1), () =>
{
best.ApplyPoison(this, HitPoison);
best.FixedParticles(0x374A, 10, 15, 5021, EffectLayer.Waist);
best.PlaySound(0x474);
});
m_Change = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(5, 10));
}
}
public void HoofStomp()
{
IPooledEnumerable eable = this.GetMobilesInRange( StrikingRange );
foreach ( Mobile m in eable )
{
Mobile valid = Validate( m );
if (Map == null)
return;
if (valid != null && Affect(valid))
foreach (Mobile m in SpellHelper.AcquireIndirectTargets(this, Location, Map, StrikingRange).OfType<Mobile>())
{
if (m.GetStatMod("DreadHornStr") == null)
{
double percent = m.Skills.MagicResist.Value / 100;
double malas = -20 + (percent * 5.2);
int malas = (int)(-20 + (percent * 5.2));
m.AddStatMod(new StatMod(StatType.Str, "DreadHornStr", (int)malas, TimeSpan.FromSeconds(60)));
m.AddStatMod(new StatMod(StatType.Dex, "DreadHornDex", (int)malas, TimeSpan.FromSeconds(60)));
m.AddStatMod(new StatMod(StatType.Int, "DreadHornInt", (int)malas, TimeSpan.FromSeconds(60)));
valid.SendLocalizedMessage(1075081); // *Dreadhorn’s eyes light up, his mouth almost a grin, as he slams one hoof to the ground!*
m.AddStatMod(new StatMod(StatType.Str, "DreadHornStr", m.Str < malas ? m.Str / 2 : malas, TimeSpan.FromSeconds(60)));
m.AddStatMod(new StatMod(StatType.Dex, "DreadHornDex", m.Dex < malas ? m.Dex / 2 : malas, TimeSpan.FromSeconds(60)));
m.AddStatMod(new StatMod(StatType.Int, "DreadHornInt", m.Int < malas ? m.Int / 2 : malas, TimeSpan.FromSeconds(60)));
}
}
eable.Free();
m.SendLocalizedMessage(1075081); // *Dreadhorn’s eyes light up, his mouth almost a grin, as he slams one hoof to the ground!*
}
// earthquake
PlaySound( 0x2F3 );
Timer.DelayCall( TimeSpan.FromSeconds( 30 ), new TimerCallback( delegate{ StopAffecting(); } ) );
m_Stomp = DateTime.UtcNow + TimeSpan.FromSeconds( Utility.RandomMinMax( 60, 80 ) );
}
public static bool IsUnderInfluence(Mobile m)
{
return m.GetStatMod("DreadHornStr") != null;
}
public Mobile Validate( Mobile m )
{
@ -301,38 +296,5 @@ namespace Server.Mobiles
return agro;
}
private static Dictionary<Mobile,bool> m_Affected;
public static bool IsUnderInfluence( Mobile mobile )
{
if ( m_Affected != null )
{
if ( m_Affected.ContainsKey( mobile ) )
return true;
}
return false;
}
public static bool Affect( Mobile mobile )
{
if ( m_Affected == null )
m_Affected = new Dictionary<Mobile,bool>();
if ( !m_Affected.ContainsKey( mobile ) )
{
m_Affected.Add( mobile, true );
return true;
}
return false;
}
public static void StopAffecting()
{
if ( m_Affected != null )
m_Affected.Clear();
}
}
}

View file

@ -4408,7 +4408,7 @@ namespace Server.Mobiles
{
get
{
int facetBonus = !Siege.SiegeShard && this.Map == Map.Felucca ? RandomItemGenerator.FeluccaLuckBonus : 250;
int facetBonus = !Siege.SiegeShard && this.Map == Map.Felucca ? RandomItemGenerator.FeluccaLuckBonus : 0;
return Luck + FountainOfFortune.GetLuckBonus(this) + facetBonus;
}

View file

@ -2587,7 +2587,7 @@ namespace Server.Multis
if (info != null)
{
m.CloseGump(typeof (SetSecureLevelGump));
m.SendGump(new Gumps.SetSecureLevelGump(m_Owner, info, this));
m.SendGump(new Gumps.SetSecureLevelGump(m, info, this));
}
else if (item.Parent != null)
{
@ -2643,7 +2643,7 @@ namespace Server.Multis
}
m.CloseGump(typeof (SetSecureLevelGump));
m.SendGump(new Gumps.SetSecureLevelGump(m_Owner, info, this));
m.SendGump(new Gumps.SetSecureLevelGump(m, info, this));
}
}
}
@ -5204,13 +5204,12 @@ namespace Server.Multis
}
ISecurable sec = GetSecurable(Owner.From, m_Item);
BaseHouse house = BaseHouse.FindHouseAt(m_Item);
if (sec != null)
if (house != null && sec != null)
{
Mobile owner = sec is SecureInfo ? ((SecureInfo)sec).Owner : Owner.From;
Owner.From.CloseGump(typeof (SetSecureLevelGump));
Owner.From.SendGump(new SetSecureLevelGump(owner, sec, BaseHouse.FindHouseAt(m_Item)));
Owner.From.SendGump(new SetSecureLevelGump(Owner.From, sec, house));
}
}
}

View file

@ -169,9 +169,9 @@ namespace Server.Multis
{
ItemData data = TileData.ItemTable[entry.m_ItemID & TileData.MaxItemValue];
// door
if ((data.Flags & TileFlag.Door) != 0)
{
//doors.Add(entry);
AddDoor(entry.m_ItemID, entry.m_OffsetX, entry.m_OffsetY, entry.m_OffsetZ);
}
else
@ -211,6 +211,8 @@ namespace Server.Multis
AddTeleporters(kvp.Key, new Point3D(kvp.Value[0].m_OffsetX, kvp.Value[0].m_OffsetY, kvp.Value[0].m_OffsetZ), new Point3D(kvp.Value[1].m_OffsetX, kvp.Value[1].m_OffsetY, kvp.Value[1].m_OffsetZ));
}
teleporters.Clear();
}
public BaseContestHouse(Serial serial)

View file

@ -124,13 +124,13 @@ namespace Server.Items
public override bool TryDropItem(Mobile from, Item dropped, bool sendFullMessage)
{
BaseHouse house = BaseHouse.FindHouseAt(this);
if (!CheckHold(from, dropped, true, true))
{
return false;
}
BaseHouse house = BaseHouse.FindHouseAt(this);
if (house != null && IsLockedDown)
{
if (!house.CheckAccessibility(this, from))
@ -165,7 +165,7 @@ namespace Server.Items
BaseHouse house = BaseHouse.FindHouseAt(this);
if (house != null && IsLockedDown)
if (house != null && IsSecure)
{
var secure = house.GetSecureInfoFor(this);

View file

@ -315,9 +315,6 @@ namespace Server.Items
Register(23, new ItemPropertyInfo(AosAttribute.NightSight, 1015168, 50, typeof(MagicalResidue), typeof(Tourmaline), typeof(BottleIchor), 0, 1, 1, 1112004,
new PropInfo(3, 1, 1), new PropInfo(5, 1, 1), new PropInfo(6, 1, 1)));
Register(24, new ItemPropertyInfo(AosWeaponAttribute.LowerStatReq, 1079757, 100, typeof(EnchantedEssence), typeof(Amethyst), typeof(ElvenFletching), 10, 10, 100, 1111998,
new PropInfo(1, 0, 100), new PropInfo(2, 1, 1), new PropInfo(3, 0, 100), new PropInfo(4, 100, 100), new PropInfo(5, 0, 100)));
Register(25, new ItemPropertyInfo(AosWeaponAttribute.HitLeechHits, 1079698, 110, typeof(MagicalResidue), typeof(Ruby), typeof(VoidOrb), 1, 2, 50, 1111964,
new PropInfo(1, 10, 50, 50), new PropInfo(2, 10, 50, 50)));
@ -370,7 +367,16 @@ namespace Server.Items
new PropInfo(1, 10, 10, new int[] { 11, 12, 13, 14, 15 }), new PropInfo(2, 10, 10, new int[] { 11, 12, 13, 14, 15 })));
Register(42, new ItemPropertyInfo(AosWeaponAttribute.DurabilityBonus, 1017323, 100, typeof(EnchantedEssence), typeof(Diamond), typeof(PowderedIron), 10, 10, 100, 1111949,
new PropInfo(1, 0, 100, new int[] { 110, 120, 130, 140, 150 }), new PropInfo(2, 0, 100, new int[] { 110, 120, 130, 140, 150 }), new PropInfo(3, 0, 100, new int[] { 110, 120, 130, 140, 150 }), new PropInfo(4, 100, 100, new int[] { 110, 120, 130, 140, 150 }), new PropInfo(5, 0, 100, new int[] { 110, 120, 130, 140, 150 })));
new PropInfo(1, 0, 100, new int[] { 110, 120, 130, 140, 150 }), new PropInfo(2, 0, 100, new int[] { 110, 120, 130, 140, 150 })));
Register(43, new ItemPropertyInfo(AosArmorAttribute.DurabilityBonus, 1017323, 100, typeof(EnchantedEssence), typeof(Diamond), typeof(PowderedIron), 10, 10, 100, 1111949,
new PropInfo(3, 0, 100, new int[] { 110, 120, 130, 140, 150 }), new PropInfo(4, 100, 100, new int[] { 110, 120, 130, 140, 150 }), new PropInfo(5, 0, 100, new int[] { 110, 120, 130, 140, 150 })));
Register(44, new ItemPropertyInfo(AosWeaponAttribute.LowerStatReq, 1079757, 100, typeof(EnchantedEssence), typeof(Amethyst), typeof(ElvenFletching), 10, 10, 100, 1111998,
new PropInfo(1, 0, 100), new PropInfo(2, 0, 100)));
Register(45, new ItemPropertyInfo(AosArmorAttribute.LowerStatReq, 1079757, 100, typeof(EnchantedEssence), typeof(Amethyst), typeof(ElvenFletching), 10, 10, 100, 1111998,
new PropInfo(3, 0, 100), new PropInfo(4, 0, 100), new PropInfo(5, 0, 100)));
Register(49, new ItemPropertyInfo(AosArmorAttribute.MageArmor, 1079758, 0, typeof(EnchantedEssence), typeof(Diamond), typeof(AbyssalCloth), 0, 1, 1, 1112000,
new PropInfo(3, 1, 1)));
@ -915,12 +921,6 @@ namespace Server.Items
public static int GetIDForAttribute(AosArmorAttribute attr)
{
if (attr == AosArmorAttribute.LowerStatReq)
return GetIDForAttribute(AosWeaponAttribute.LowerStatReq);
if (attr == AosArmorAttribute.DurabilityBonus)
return GetIDForAttribute(AosWeaponAttribute.DurabilityBonus);
foreach (var kvp in Table)
{
var info = kvp.Value;
@ -1139,6 +1139,8 @@ namespace Server.Items
case 38:
case 39: // Hit Spell Cannot be applied if it already has one present
return item is BaseWeapon && !HasHitSpell((BaseWeapon)item);
case 49: // MageArmor cannot be applied if the armor is already meddable
return item is BaseArmor && ((BaseArmor)item).MeditationAllowance != ArmorMeditationAllowance.All;
case 208:
case 209:
case 210:

View file

@ -20,6 +20,10 @@ namespace Server.Gumps
InspiredArtifice = 0x00000040,
ExaltedArtifice = 0x00000080,
SublimeArtifice = 0x00000100,
PowerfulAndStructural = Powerful | Structural,
PowerfulAndFundamental = Powerful | Fundamental,
PowerfulStructuralAndFundamental = PowerfulAndStructural | Fundamental
}
public class RunicReforgingGump : Gump

View file

@ -1243,24 +1243,6 @@ namespace Server.Items
//new NamedInfoCol(SAAbsorptionAttribute.CastingFocus, ArmorCastingFocusTable),
},
};
/*m_PrefixSuffixInfo[250] = new NamedInfoCol[][] // Reforge Only
{
new NamedInfoCol[] // Weapon
{
new NamedInfoCol(AosWeaponAttribute.HitLowerDefend, HitWeaponTable2),
new NamedInfoCol(AosWeaponAttribute.UseBestSkill, 1),
},
new NamedInfoCol[] // armor
{
},
new NamedInfoCol[]
{
},
new NamedInfoCol[]
{
},
};*/
}
public class NamedInfoCol
@ -2403,10 +2385,11 @@ namespace Server.Items
public static bool ApplyProperty(Item item, int id, int perclow, int perchigh, ref int budget, int luckchance, bool reforged, bool powerful)
{
int min = ItemPropertyInfo.GetMinIntensity(item, id);
int max = ItemPropertyInfo.GetMaxIntensity(item, id);
int naturalMax = ItemPropertyInfo.GetMaxIntensity(item, id);
int max = naturalMax;
int[] overcap = null;
if (powerful && 0.25 > Utility.RandomDouble())
if (powerful)
{
overcap = ItemPropertyInfo.GetMaxOvercappedRange(item, id);
@ -2418,11 +2401,18 @@ namespace Server.Items
int value = CalculateValue(item, ItemPropertyInfo.GetAttribute(id), min, max, perclow, perchigh, ref budget, luckchance, reforged);
if (overcap != null && overcap.Length > 0 && value < max)
// We're using overcap, so the value must have gone over the natural max, but under the overrcap max
if (overcap != null && overcap.Length > 0 && value > naturalMax && value < max)
{
value = AdjustOvercap(overcap, value);
if (overcap.Length > 1)
{
value = AdjustOvercap(overcap, value);
}
else
{
value = naturalMax;
}
}
Imbuing.SetProperty(item, id, value);
budget -= Imbuing.GetIntensityForID(item, id, -1, value);
@ -2445,7 +2435,7 @@ namespace Server.Items
{
for (int i = overcap.Length - 1; i >= 0; i--)
{
if (value > overcap[i])
if (value >= overcap[i])
{
return overcap[i];
}

View file

@ -375,17 +375,6 @@ namespace Server.Items
public virtual void BeginSequence(Mobile from)
{
SpawnBoss();
// teleport fighters
/*Fighters.ForEach(x =>
{
int counter = 0;
if (x.InRange(from.Location, 15) && CanEnter(x))
{
Timer.DelayCall(TimeSpan.FromSeconds(counter++), () => { Enter(x); });
}
});*/
}
public virtual void SpawnBoss()