Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Outlaw's skills #333

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/ZoneServer/Buffs/Buff.cs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,17 @@ internal void ExtendDuration()
this.NextUpdateTime = DateTime.Now.Add(this.Data.UpdateTime);
}

/// <summary>
/// Increases the buff's duration by a given amount.
/// </summary>
internal void IncreaseDuration(TimeSpan amount)
Copy link
Contributor

@kenedos kenedos Nov 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably better to merge IncreaseDuration() and ExtendDuration() into a single method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree this is somewhat confusing and maybe the description should have been a little more clear, but ExtendDuration has several features we don't want here, most particularly that it resets the updatetime on the buff. We probably don't want to constantly call onExtend here either.

{
if (this.HasDuration)
{
this.RemovalTime = DateTime.Now.Add(amount);
}
}

/// <summary>
/// Executes the buff handler's end behavior. Does not actually
/// end or remove the buff.
Expand Down
19 changes: 19 additions & 0 deletions src/ZoneServer/Buffs/Handlers/Common/Common_Silence.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Melia.Shared.Game.Const;
using Melia.Zone.Buffs.Base;
using Melia.Zone.World.Actors;
using Melia.Zone.World.Actors.Components;

namespace Melia.Zone.Buffs.Handlers.Common
{
/// <summary>
/// Handle for the Silence Debuff, which prevents taking any action
/// </summary>
[BuffHandler(BuffId.Common_Silence)]
public class Common_Silence : BuffHandler
{
public override void OnExtend(Buff buff)
{
buff.Target.AddState(StateType.Stunned, buff.Duration);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Melia.Shared.Data.Database;
using Melia.Shared.Game.Const;
using Melia.Zone.Buffs.Base;
using Melia.Zone.Skills;
using Melia.Zone.Skills.Combat;
using Melia.Zone.World.Actors;

namespace Melia.Zone.Buffs.Handlers.Common
{
/// <summary>
/// Contains code related to the Momentary Block Buff
/// </summary>
/// <remarks>
/// This buff is granted by certain skills and causes you to always
/// evade for a duration.
/// </remarks>
[BuffHandler(BuffId.Skill_MomentaryEvasion_Buff)]
public class Skill_MomentaryEvasion_Buff : BuffHandler, IBuffCombatDefenseBeforeCalcHandler
{
/// <summary>
/// Applies the buff's effect during the combat calculations.
/// </summary>
/// <param name="buff"></param>
/// <param name="attacker"></param>
/// <param name="target"></param>
/// <param name="skill"></param>
/// <param name="modifier"></param>
/// <param name="skillHitResult"></param>
public void OnDefenseBeforeCalc(Buff buff, ICombatEntity attacker, ICombatEntity target, Skill skill, SkillModifier modifier, SkillHitResult skillHitResult)
{
modifier.ForcedEvade = true;
}
}
}
37 changes: 37 additions & 0 deletions src/ZoneServer/Buffs/Handlers/Scouts/OutLaw/Aggress_Buff.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Melia.Shared.Game.Const;
using Melia.Zone.Buffs.Base;
using Melia.Zone.Network;

namespace Melia.Zone.Buffs.Handlers.Scouts.OutLaw
{
/// <summary>
/// Handler for Aggress Buff, which massively increases movement speed
/// </summary>
[BuffHandler(BuffId.Aggress_Buff)]
public class Aggress_Buff : BuffHandler
{
private const float MspdBonus = 30f;

/// <summary>
/// Starts buff, modifying the movement speed
/// </summary>
/// <param name="buff"></param>
public override void OnActivate(Buff buff, ActivationType activationType)
{
var target = buff.Target;

AddPropertyModifier(buff, target, PropertyName.MSPD_BM, MspdBonus);
Send.ZC_MSPD(target);
}

/// <summary>
/// Ends the buff, resetting the movement speed
/// </summary>
/// <param name="buff"></param>
public override void OnEnd(Buff buff)
{
RemovePropertyModifier(buff, buff.Target, PropertyName.MSPD_BM);
Send.ZC_MSPD(buff.Target);
}
}
}
64 changes: 64 additions & 0 deletions src/ZoneServer/Buffs/Handlers/Scouts/OutLaw/Aggress_Debuff.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Melia.Shared.Game.Const;
using Melia.Zone.Buffs.Base;
using Melia.Zone.Network;

namespace Melia.Zone.Buffs.Handlers.Scouts.OutLaw
{
/// <summary>
/// Handler for Break Brick Debuff, which reduces Evasion
/// </summary>
/// <remarks>
/// NumArg1: Skill Level
/// NumArg2: Unhinge Level
/// This is related to Outlaw13, which changes the buff effect to
/// also increase movement speed but decrease accuracy
/// </remarks>
[BuffHandler(BuffId.Aggress_Debuff)]
internal class Aggress_Debuff : BuffHandler
{
private const float DRPenaltyPerLevel = 0.02f;
private const float HRPenaltyPerLevel = 0.03f;
private const float MspdBonus = 5f;

/// <summary>
/// Starts buff, reducing Dodge Rate
/// </summary>
/// <param name="buff"></param>
public override void OnActivate(Buff buff, ActivationType activationType)
{
var reduceDR = buff.Target.Properties.GetFloat(PropertyName.DR) * buff.NumArg1 * DRPenaltyPerLevel;

AddPropertyModifier(buff, buff.Target, PropertyName.DR_BM, -reduceDR);

if (buff.NumArg2 > 0)
{
var reduceHR = buff.Target.Properties.GetFloat(PropertyName.HR) * buff.NumArg2 * HRPenaltyPerLevel;

AddPropertyModifier(buff, buff.Target, PropertyName.HR_BM, -reduceHR);
AddPropertyModifier(buff, buff.Target, PropertyName.MSPD_BM, MspdBonus);
Send.ZC_MSPD(buff.Target);
}
}

/// <summary>
/// Ends the buff, resetting dodge rate.
/// </summary>
/// <param name="buff"></param>
public override void OnEnd(Buff buff)
{
RemovePropertyModifier(buff, buff.Target, PropertyName.DR_BM);

if (buff.NumArg2 > 0)
{
RemovePropertyModifier(buff, buff.Target, PropertyName.HR_BM);
RemovePropertyModifier(buff, buff.Target, PropertyName.MSPD_BM);
Send.ZC_MSPD(buff.Target);
}
}
}
}
43 changes: 43 additions & 0 deletions src/ZoneServer/Buffs/Handlers/Scouts/OutLaw/BreakBrick_Debuff.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Melia.Shared.Game.Const;
using Melia.Zone.Buffs.Base;

namespace Melia.Zone.Buffs.Handlers.Scouts.OutLaw
{
/// <summary>
/// Handler for Break Brick Debuff, which reduces Crit Chance
/// </summary>
/// <remarks>
/// NumArg1: Skill Level
/// NumArg2: None
/// </remarks>
[BuffHandler(BuffId.BreakBrick_Debuff)]
internal class BreakBrick_Debuff : BuffHandler
{
private const float CRTPenaltyPerLevel = 1f;

/// <summary>
/// Starts buff, reducing Crit rate
/// </summary>
/// <param name="buff"></param>
public override void OnActivate(Buff buff, ActivationType activationType)
{
var reduceCrt = buff.Target.Properties.GetFloat(PropertyName.CRTHR) * buff.NumArg1 * CRTPenaltyPerLevel;

AddPropertyModifier(buff, buff.Target, PropertyName.CRTHR_BM, -reduceCrt);
}

/// <summary>
/// Ends the buff, resetting Crit rate.
/// </summary>
/// <param name="buff"></param>
public override void OnEnd(Buff buff)
{
RemovePropertyModifier(buff, buff.Target, PropertyName.CRTHR_BM);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System;
using Melia.Shared.Game.Const;
using Melia.Zone.Buffs.Base;
using Melia.Zone.Scripting.AI;
using Melia.Zone.Skills;
using Melia.Zone.Skills.Combat;
using Melia.Zone.World.Actors;
using Melia.Zone.World.Actors.CombatEntities.Components;
using Melia.Zone.World.Actors.Monsters;

namespace Melia.Zone.Buffs.Handlers.Scouts.OutLaw
{
/// <summary>
/// Buff handler for Bully Pain Barrier Buff, which increases evasion
/// and adds threat on successful evade
/// It's completely identical to Bully Buff except that it also
/// grants immunity to knockback and Outlaw12's effect is nerfed
/// </summary>
/// <remarks>
/// NumArg1: Skill Level
/// NumArg2: None
/// </remarks>
[BuffHandler(BuffId.BullyPainBarrier_Buff)]
public class BullyPainBarrier_Buff : BuffHandler, IBuffCombatDefenseAfterCalcHandler
{
private const float DrBuffRateBase = 0.24f;
private const float DrBuffRatePerLevel = 0.04f;
private const float HatePerLevel = 3f;

/// <summary>
/// Starts buff, increasing dodge rate.
/// </summary>
/// <param name="buff"></param>
public override void OnActivate(Buff buff, ActivationType activationType)
{
var dr = buff.Target.Properties.GetFloat(PropertyName.DR);
var skillLevel = buff.NumArg1;
var rate = DrBuffRateBase + DrBuffRatePerLevel * skillLevel;
var bonus = dr * rate;

AddPropertyModifier(buff, buff.Target, PropertyName.DR_BM, bonus);
}

/// <summary>
/// Ends the buff, resetting dodge rate.
/// </summary>
/// <param name="buff"></param>
public override void OnEnd(Buff buff)
{
RemovePropertyModifier(buff, buff.Target, PropertyName.DR_BM);
}

/// <summary>
/// Applies the buff's effect during the combat calculations.
/// </summary>
/// <param name="buff"></param>
/// <param name="attacker"></param>
/// <param name="target"></param>
/// <param name="skill"></param>
/// <param name="modifier"></param>
/// <param name="skillHitResult"></param>
public void OnDefenseAfterCalc(Buff buff, ICombatEntity attacker, ICombatEntity target, Skill skill, SkillModifier modifier, SkillHitResult skillHitResult)
{
if (skillHitResult.Result == HitResultType.Dodge && attacker.Components.TryGet<AiComponent>(out var component))
{
component.Script.QueueEventAlert(new HateIncreaseAlert(target, buff.NumArg1 * HatePerLevel));

// Outlaw12 adds additional duration to the buff on successful evade
// For Pain Barrier buff, the maximum increase is 2 seconds
if (target.TryGetActiveAbilityLevel(AbilityId.Outlaw12, out var level))
{
buff.IncreaseDuration(TimeSpan.FromSeconds(Math.Max(level, 2)));
}
}
}
}
}
76 changes: 76 additions & 0 deletions src/ZoneServer/Buffs/Handlers/Scouts/OutLaw/Bully_Buff.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using Melia.Shared.Game.Const;
using Melia.Zone.Buffs.Base;
using Melia.Zone.Scripting.AI;
using Melia.Zone.Skills;
using Melia.Zone.Skills.Combat;
using Melia.Zone.World.Actors;
using Melia.Zone.World.Actors.CombatEntities.Components;
using Melia.Zone.World.Actors.Monsters;

namespace Melia.Zone.Buffs.Handlers.Scouts.OutLaw
{
/// <summary>
/// Buff handler for Bully Buff, which increases evasion
/// and adds threat on successful evade
/// </summary>
/// <remarks>
/// NumArg1: Skill Level
/// NumArg2: None
/// </remarks>
[BuffHandler(BuffId.Bully_Buff)]
public class Bully_Buff : BuffHandler, IBuffCombatDefenseAfterCalcHandler
{
private const float DrBuffRateBase = 0.24f;
private const float DrBuffRatePerLevel = 0.04f;
private const float HatePerLevel = 3f;

/// <summary>
/// Starts buff, increasing dodge rate.
/// </summary>
/// <param name="buff"></param>
public override void OnActivate(Buff buff, ActivationType activationType)
{
var dr = buff.Target.Properties.GetFloat(PropertyName.DR);
var skillLevel = buff.NumArg1;
var rate = DrBuffRateBase + DrBuffRatePerLevel * skillLevel;
var bonus = dr * rate;

AddPropertyModifier(buff, buff.Target, PropertyName.DR_BM, bonus);
}

/// <summary>
/// Ends the buff, resetting dodge rate.
/// </summary>
/// <param name="buff"></param>
public override void OnEnd(Buff buff)
{
RemovePropertyModifier(buff, buff.Target, PropertyName.DR_BM);
}

/// <summary>
/// Applies the buff's effect during the combat calculations.
/// </summary>
/// <param name="buff"></param>
/// <param name="attacker"></param>
/// <param name="target"></param>
/// <param name="skill"></param>
/// <param name="modifier"></param>
/// <param name="skillHitResult"></param>
public void OnDefenseAfterCalc(Buff buff, ICombatEntity attacker, ICombatEntity target, Skill skill, SkillModifier modifier, SkillHitResult skillHitResult)
{
if (skillHitResult.Result == HitResultType.Dodge && attacker.Components.TryGet<AiComponent>(out var component))
{
component.Script.QueueEventAlert(new HateIncreaseAlert(target, buff.NumArg1 * HatePerLevel));

// Outlaw12 adds additional duration to the buff on successful evade
// Note that it only applies to monster attacks, which is why
// it's done after the AI script check
if (target.TryGetActiveAbilityLevel(AbilityId.Outlaw12, out var level))
{
buff.IncreaseDuration(TimeSpan.FromSeconds(level));
}
}
}
}
}
Loading