diff --git a/Hybrasyl.Tests/Hybrasyl.Tests.csproj b/Hybrasyl.Tests/Hybrasyl.Tests.csproj index 9079aea3..7526d422 100644 --- a/Hybrasyl.Tests/Hybrasyl.Tests.csproj +++ b/Hybrasyl.Tests/Hybrasyl.Tests.csproj @@ -8,10 +8,10 @@ - + - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/hybrasyl/Hybrasyl.csproj b/hybrasyl/Hybrasyl.csproj index 3f570a25..18c8a26f 100644 --- a/hybrasyl/Hybrasyl.csproj +++ b/hybrasyl/Hybrasyl.csproj @@ -48,25 +48,25 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + @@ -75,7 +75,7 @@ - + diff --git a/hybrasyl/Objects/ConditionInfo.cs b/hybrasyl/Objects/ConditionInfo.cs index 2720d66b..6932bf9a 100644 --- a/hybrasyl/Objects/ConditionInfo.cs +++ b/hybrasyl/Objects/ConditionInfo.cs @@ -59,7 +59,7 @@ public bool CastingAllowed { get { - var conditionCheck = Asleep || Frozen || Comatose; + var conditionCheck = Asleep || Stunned || Comatose; if (User != null) conditionCheck = conditionCheck || Flags.HasFlag(PlayerFlags.ProhibitCast); @@ -71,7 +71,7 @@ public bool MovementAllowed { get { - var conditionCheck = Asleep || Frozen || Paralyzed || Comatose; + var conditionCheck = Asleep || Stunned || Rooted || Comatose; return !conditionCheck; } } @@ -99,15 +99,15 @@ public bool Alive } } - public bool Frozen + public bool Stunned { - get => Conditions.HasFlag(CreatureCondition.Freeze); + get => Conditions.HasFlag(CreatureCondition.Stun); set { if (value == false) - Conditions &= ~CreatureCondition.Freeze; + Conditions &= ~CreatureCondition.Stun; else - Conditions |= CreatureCondition.Freeze; + Conditions |= CreatureCondition.Stun; } } @@ -119,19 +119,19 @@ public bool Asleep if (value == false) Conditions &= ~CreatureCondition.Sleep; else - Conditions |= CreatureCondition.Freeze; + Conditions |= CreatureCondition.Stun; } } - public bool Paralyzed + public bool Rooted { - get => Conditions.HasFlag(CreatureCondition.Paralyze); + get => Conditions.HasFlag(CreatureCondition.Root); set { if (value == false) - Conditions &= ~CreatureCondition.Paralyze; + Conditions &= ~CreatureCondition.Root; else - Conditions |= CreatureCondition.Paralyze; + Conditions |= CreatureCondition.Root; } } @@ -225,9 +225,9 @@ public bool Disoriented set { if (value == false) - Conditions &= ~CreatureCondition.Invulnerable; + Conditions &= ~CreatureCondition.Disoriented; else - Conditions |= CreatureCondition.Invulnerable; + Conditions |= CreatureCondition.Disoriented; } } @@ -360,6 +360,72 @@ public bool IsEquipmentChangeProhibited } } + public bool IsHpIncreaseProhibited + { + get => User != null && Conditions.HasFlag(CreatureCondition.ProhibitHpIncrease); + set + { + if (User == null) return; + if (value == false) + Conditions &= CreatureCondition.ProhibitHpIncrease; + else + Conditions |= CreatureCondition.ProhibitHpIncrease; + } + } + + public bool IsMpIncreaseProhibited + { + get => User != null && Conditions.HasFlag(CreatureCondition.ProhibitMpIncrease); + set + { + if (User == null) return; + if (value == false) + Conditions &= CreatureCondition.ProhibitMpIncrease; + else + Conditions |= CreatureCondition.ProhibitMpIncrease; + } + } + + public bool IsMpDecreaseProhibited + { + get => User != null && Conditions.HasFlag(CreatureCondition.ProhibitMpDecrease); + set + { + if (User == null) return; + if (value == false) + Conditions &= CreatureCondition.ProhibitMpDecrease; + else + Conditions |= CreatureCondition.ProhibitMpDecrease; + } + } + + public bool IsHpRegenProhibited + { + get => User != null && Conditions.HasFlag(CreatureCondition.ProhibitHpRegen); + set + { + if (User == null) return; + if (value == false) + Conditions &= CreatureCondition.ProhibitHpRegen; + else + Conditions |= CreatureCondition.ProhibitHpRegen; + } + } + + public bool IsMpRegenProhibited + { + get => User != null && Conditions.HasFlag(CreatureCondition.ProhibitMpRegen); + set + { + if (User == null) return; + if (value == false) + Conditions &= CreatureCondition.ProhibitMpRegen; + else + Conditions |= CreatureCondition.ProhibitMpRegen; + } + } + + public bool NoFlags => Flags == PlayerFlags.Alive; public void ClearFlags() diff --git a/hybrasyl/Objects/Creature.cs b/hybrasyl/Objects/Creature.cs index 941dabda..dbb6bb7c 100644 --- a/hybrasyl/Objects/Creature.cs +++ b/hybrasyl/Objects/Creature.cs @@ -962,6 +962,8 @@ public virtual void Motion(byte motion, short speed) public virtual void Heal(double heal, Creature source = null, Castable castable = null) { + if (Condition.IsHpIncreaseProhibited) + return; var bonusHeal = heal * Stats.BaseInboundHealModifier + (heal * source?.Stats.BaseOutboundHealModifier ?? 0.0); heal += bonusHeal; @@ -982,7 +984,7 @@ public virtual void Heal(double heal, Creature source = null, Castable castable public virtual void RegenerateMp(double mp, Creature regenerator = null) { - if (AbsoluteImmortal) + if (AbsoluteImmortal || Condition.IsMpIncreaseProhibited) return; if (Stats.Mp == Stats.MaximumMp || mp > Stats.MaximumMp) @@ -1176,7 +1178,7 @@ public virtual void Damage(double damage, ElementType element = ElementType.None { case DamageType.Physical when AbsoluteImmortal || PhysicalImmortal || Condition.IsInvulnerable: case DamageType.Magical when AbsoluteImmortal || MagicalImmortal || Condition.IsInvulnerable: - case DamageType.Direct when AbsoluteImmortal || Condition.IsInvulnerable: + case DamageType.Direct when AbsoluteImmortal: damageEvent.Applied = false; return; } @@ -1261,10 +1263,7 @@ public virtual void Damage(double damage, ElementType element = ElementType.None }); } - if ((MagicalImmortal && damageType != DamageType.Magical) || - (PhysicalImmortal && damageType != DamageType.Physical) || - !AbsoluteImmortal) - Stats.Hp = (int)Stats.Hp - normalized < 0 ? 0 : Stats.Hp - normalized; + Stats.Hp = (int)Stats.Hp - normalized < 0 ? 0 : Stats.Hp - normalized; SendDamageUpdate(this); diff --git a/hybrasyl/Objects/User.cs b/hybrasyl/Objects/User.cs index ee518a6b..16330454 100644 --- a/hybrasyl/Objects/User.cs +++ b/hybrasyl/Objects/User.cs @@ -1319,6 +1319,9 @@ public bool ProcessCastingCost(Castable castable, Creature target, out string me // Check that all requirements are met first. Note that a spell cannot be cast if its HP cost would result // in the caster's HP being reduced to zero. + if (Condition.IsMpDecreaseProhibited) + cost.Mp = 0; + if (cost.Hp >= Stats.Hp) message = "You lack the required vitality."; @@ -2627,7 +2630,9 @@ public override void Damage(double damage, ElementType element = ElementType.Non public override void Heal(double heal, Creature source = null, Castable castable = null) { base.Heal(heal, source, castable); - if (this is User) UpdateAttributes(StatUpdateFlags.Current); + if (Condition.IsHpIncreaseProhibited) + SendSystemMessage("You cannot currently receive healing."); + UpdateAttributes(StatUpdateFlags.Current); } private bool CheckCastableRestriction(EquipmentRestriction restriction, out string message) diff --git a/hybrasyl/Servers/World.cs b/hybrasyl/Servers/World.cs index 6a7c3207..01bf31c3 100644 --- a/hybrasyl/Servers/World.cs +++ b/hybrasyl/Servers/World.cs @@ -1378,7 +1378,7 @@ private void ControlMessage_MonolithControl(HybrasylControlMessage message) // Don't handle control messages for dead/removed mobs, or mobs that cannot move or attack if (!monster.Condition.Alive || monster.DeathProcessed || monster.Id == 0 || monster.Map == null || - monster.Condition.Asleep || monster.Condition.Frozen) return; + monster.Condition.Asleep || monster.Condition.Stunned) return; monster.NextAction(); monster.ProcessActions(); @@ -1479,10 +1479,26 @@ private void ControlMessage_RegenerateUser(HybrasylControlMessage message) break; } - GameLog.UserActivityInfo( - $"User {user.Name}: regen HP {hpRegen}, MP {mpRegen}, regen bonus {user.Stats.Regen}%"); - user.Stats.Hp = Math.Min(user.Stats.Hp + hpRegen, user.Stats.MaximumHp); - user.Stats.Mp = Math.Min(user.Stats.Mp + mpRegen, user.Stats.MaximumMp); + if (!user.Condition.IsHpRegenProhibited) + { + user.Stats.Hp = Math.Min(user.Stats.Hp + hpRegen, user.Stats.MaximumHp); + GameLog.UserActivityInfo( + $"User {user.Name}: regen HP {hpRegen}, regen bonus {user.Stats.Regen}%"); + } + else + user.SendSystemMessage("You cannot regenerate health at this time."); + + if (!user.Condition.IsMpRegenProhibited) + { + user.Stats.Mp = Math.Min(user.Stats.Mp + mpRegen, user.Stats.MaximumMp); + GameLog.UserActivityInfo( + $"User {user.Name}: regen MP {mpRegen},regen bonus {user.Stats.Regen}%"); + + } + else + user.SendSystemMessage("You cannot regenerate mana at this time."); + + user.UpdateAttributes(StatUpdateFlags.Current); } @@ -1738,6 +1754,7 @@ private void PacketHandler_0x05_RequestMap(object obj, ClientPacket packet) { var x3C = new ServerPacket(0x3C); x3C.WriteUInt16(row); + x3C.WriteUInt16(row); for (var col = 0; col < user.Map.X * 6; col += 2) { x3C.WriteByte(user.Map.RawData[index + 1]); @@ -1750,7 +1767,7 @@ private void PacketHandler_0x05_RequestMap(object obj, ClientPacket packet) } [PacketHandler(0x06)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze, CreatureCondition.Paralyze, + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun, CreatureCondition.Root, PlayerFlags.InDialog)] private void PacketHandler_0x06_Walk(object obj, ClientPacket packet) { @@ -1762,7 +1779,7 @@ private void PacketHandler_0x06_Walk(object obj, ClientPacket packet) } [PacketHandler(0x07)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze, PlayerFlags.InDialog)] + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun, PlayerFlags.InDialog)] [Required(PlayerFlags.Alive)] private void PacketHandler_0x07_PickupItem(object obj, ClientPacket packet) { @@ -1897,7 +1914,7 @@ private void PacketHandler_0x07_PickupItem(object obj, ClientPacket packet) } [PacketHandler(0x08)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze, PlayerFlags.InDialog)] + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun, PlayerFlags.InDialog)] [Required(PlayerFlags.Alive)] private void PacketHandler_0x08_DropItem(object obj, ClientPacket packet) { @@ -2028,7 +2045,7 @@ private void PacketHandler_0x0E_Talk(object obj, ClientPacket packet) } [PacketHandler(0x0F)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze, CreatureCondition.Paralyze, + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun, CreatureCondition.Root, PlayerFlags.InDialog)] [Required(PlayerFlags.Alive)] private void PacketHandler_0x0F_UseSpell(object obj, ClientPacket packet) @@ -2222,7 +2239,7 @@ private void PacketHandler_0x10_ClientJoin(object obj, ClientPacket packet) } [PacketHandler(0x11)] - [Prohibited(CreatureCondition.Freeze, PlayerFlags.InDialog)] + [Prohibited(CreatureCondition.Stun, PlayerFlags.InDialog)] private void PacketHandler_0x11_Turn(object obj, ClientPacket packet) { var user = (User)obj; @@ -2233,7 +2250,7 @@ private void PacketHandler_0x11_Turn(object obj, ClientPacket packet) } [PacketHandler(0x13)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze, CreatureCondition.Paralyze, + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun, CreatureCondition.Root, PlayerFlags.InDialog)] private void PacketHandler_0x13_Attack(object obj, ClientPacket packet) { @@ -2445,7 +2462,7 @@ private void PacketHandler_0x1B_Settings(object obj, ClientPacket packet) } [PacketHandler(0x1C)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze, + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun, PlayerFlags.InDialog)] [Required(PlayerFlags.Alive)] private void PacketHandler_0x1C_UseItem(object obj, ClientPacket packet) @@ -2623,7 +2640,7 @@ private void PacketHandler_0x1C_UseItem(object obj, ClientPacket packet) } [PacketHandler(0x1D)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze)] + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun)] [Required(PlayerFlags.Alive)] private void PacketHandler_0x1D_Emote(object obj, ClientPacket packet) { @@ -2637,7 +2654,7 @@ private void PacketHandler_0x1D_Emote(object obj, ClientPacket packet) } [PacketHandler(0x24)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze, PlayerFlags.InDialog)] + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun, PlayerFlags.InDialog)] [Required(PlayerFlags.Alive)] private void PacketHandler_0x24_DropGold(object obj, ClientPacket packet) { @@ -2868,7 +2885,7 @@ private void PacketHandler_0x2F_GroupToggle(object obj, ClientPacket packet) } [PacketHandler(0x2A)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze, PlayerFlags.InDialog)] + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun, PlayerFlags.InDialog)] [Required(PlayerFlags.Alive)] private void PacketHandler_0x2A_DropGoldOnCreature(object obj, ClientPacket packet) { @@ -2923,7 +2940,7 @@ private void PacketHandler_0x2A_DropGoldOnCreature(object obj, ClientPacket pack } [PacketHandler(0x29)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze, PlayerFlags.InDialog)] + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun, PlayerFlags.InDialog)] [Required(PlayerFlags.Alive)] private void PacketHandler_0x29_DropItemOnCreature(object obj, ClientPacket packet) { @@ -3113,7 +3130,7 @@ private void PacketHandler_0x3B_AccessMessages(object obj, ClientPacket packet) } [PacketHandler(0x3E)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze, CreatureCondition.Paralyze, + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun, CreatureCondition.Root, PlayerFlags.InDialog)] [Required(PlayerFlags.Alive)] private void PacketHandler_0x3E_UseSkill(object obj, ClientPacket packet) @@ -3125,7 +3142,7 @@ private void PacketHandler_0x3E_UseSkill(object obj, ClientPacket packet) } [PacketHandler(0x3F)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze, PlayerFlags.InDialog)] + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun, PlayerFlags.InDialog)] private void PacketHandler_0x3F_MapPointClick(object obj, ClientPacket packet) { var user = (User)obj; @@ -3158,7 +3175,7 @@ private void PacketHandler_0x38_Refresh(object obj, ClientPacket packet) } [PacketHandler(0x39)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze)] + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun)] private void PacketHandler_0x39_NPCMainMenu(object obj, ClientPacket packet) { var user = (User)obj; @@ -3248,7 +3265,7 @@ private void PacketHandler_0x39_NPCMainMenu(object obj, ClientPacket packet) } [PacketHandler(0x3A)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze)] + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun)] private void PacketHandler_0x3A_DialogUse(object obj, ClientPacket packet) { var user = (User)obj; @@ -3498,7 +3515,7 @@ private void PacketHandler_0x3A_DialogUse(object obj, ClientPacket packet) } [PacketHandler(0x43)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze, PlayerFlags.InDialog)] + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun, PlayerFlags.InDialog)] private void PacketHandler_0x43_PointClick(object obj, ClientPacket packet) { var user = (User)obj; @@ -3582,7 +3599,7 @@ private void PacketHandler_0x43_PointClick(object obj, ClientPacket packet) } [PacketHandler(0x44)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze, PlayerFlags.InDialog)] + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun, PlayerFlags.InDialog)] [Required(PlayerFlags.Alive)] private void PacketHandler_0x44_EquippedItemClick(object obj, ClientPacket packet) { @@ -3641,7 +3658,7 @@ private void PacketHandler_0x45_ByteHeartbeat(object obj, ClientPacket packet) } [PacketHandler(0x47)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze, PlayerFlags.InDialog)] + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun, PlayerFlags.InDialog)] [Required(PlayerFlags.Alive)] private void PacketHandler_0x47_StatPoint(object obj, ClientPacket packet) { @@ -3680,7 +3697,7 @@ private void PacketHandler_0x47_StatPoint(object obj, ClientPacket packet) } [PacketHandler(0x4A)] - [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Freeze)] + [Prohibited(CreatureCondition.Coma, CreatureCondition.Sleep, CreatureCondition.Stun)] [Required(PlayerFlags.Alive)] private void PacketHandler_0x4A_Trade(object obj, ClientPacket packet) { diff --git a/hybrasyl/Subsystems/Scripting/HybrasylMonster.cs b/hybrasyl/Subsystems/Scripting/HybrasylMonster.cs index 97f62194..3b53d841 100644 --- a/hybrasyl/Subsystems/Scripting/HybrasylMonster.cs +++ b/hybrasyl/Subsystems/Scripting/HybrasylMonster.cs @@ -98,6 +98,18 @@ public void SetCreatureDisplaySprite(int displaySprite) Monster.Sprite = (ushort)displaySprite; } + /// + /// Directly damage the monster for the specified amount. + /// + /// Amount of damage + public void DirectDamage(int damage) => Monster.Damage(damage); + + /// + /// Directly heal the monster for the specified amount. + /// + /// Amount of damage + public void DirectHeal(int heal) => Monster.Heal(heal); + public int GetCreatureDisplaySprite() => Monster.Sprite; diff --git a/hybrasyl/Subsystems/Scripting/HybrasylUser.cs b/hybrasyl/Subsystems/Scripting/HybrasylUser.cs index c6b9134a..5f0cbdc9 100644 --- a/hybrasyl/Subsystems/Scripting/HybrasylUser.cs +++ b/hybrasyl/Subsystems/Scripting/HybrasylUser.cs @@ -996,6 +996,21 @@ public bool AddSkill(string skillname) return false; } + public void DirectDamage(int damage) + { + if (User.AbsoluteImmortal) return; + User.Damage(damage); + } + + public void DirectHeal(int heal) + { + if (User.Condition.IsHpIncreaseProhibited) + User.SendSystemMessage("You cannot be healed at this time."); + else + User.Heal(heal); + + } + /// /// Check to see if the specified skill exists in the user's skill book. diff --git a/hybrasyl/Subsystems/Scripting/HybrasylWorldObject.cs b/hybrasyl/Subsystems/Scripting/HybrasylWorldObject.cs index be1bc0ce..efc8c1af 100644 --- a/hybrasyl/Subsystems/Scripting/HybrasylWorldObject.cs +++ b/hybrasyl/Subsystems/Scripting/HybrasylWorldObject.cs @@ -58,7 +58,6 @@ public string LocationDescription public string Name => WorldObject.Name; public string Type => Obj.GetType().Name; - /// /// The current X coordinate location of the object. ///