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

Cataphract Skills #315

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Melia.Shared.Game.Const;
using Melia.Zone.Buffs.Base;

namespace Melia.Zone.Buffs.Handlers.Common
{
/// <summary>
/// Handle for the Warrior_EnableMovingShot Buff, which
/// gives moving shot with a given value
/// </summary>
/// <remarks>
/// NumArg1: MovingShot_BM value
/// NumArg2: None
/// </remarks>
[BuffHandler(BuffId.Warrior_EnableMovingShot_Buff)]
public class Warrior_EnableMovingShot_Buff : BuffHandler
{
public override void OnStart(Buff buff)
{
AddPropertyModifier(buff, buff.Target, PropertyName.MovingShot_BM, buff.NumArg1);
}

public override void OnEnd(Buff buff)
{
RemovePropertyModifier(buff, buff.Target, PropertyName.MovingShot_BM);
}
}
}
52 changes: 52 additions & 0 deletions src/ZoneServer/Buffs/Handlers/Swordsmen/Cataphract/Impaler_Buff.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using Melia.Shared.Game.Const;
using Melia.Shared.L10N;
using Melia.Zone.Buffs.Base;
using Melia.Zone.Network;
using Melia.Zone.Skills;
using Melia.Zone.Skills.Combat;
using Melia.Zone.World.Actors;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Melia.Zone.Buffs.Handlers.Swordsmen.Cataphract
{
/// <summary>
/// Buff handler for Impaler Buff, which triggers the slam portion of Impaler.
/// It needs to end if the skewered monster dies
/// </summary>
/// <remarks>
/// caster in this case is the skewer monster
/// </remarks>
[BuffHandler(BuffId.Impaler_Buff)]
public class Impaler_Buff : BuffHandler
{
/// <summary>
/// Ends the buff, activating the overheat
/// </summary>
/// <param name="buff"></param>
public override void OnEnd(Buff buff)
{
var target = buff.Target;

if (target.TryGetSkill(SkillId.Cataphract_Impaler, out var skill))
{
skill.IncreaseOverheat();
}
}


/// <summary>
/// Checks to see if the entity died
/// </summary>
/// <param name="buff"></param>
public override void WhileActive(Buff buff)
{
var caster = buff.Caster;
var target = buff.Target;

if (caster.IsDead)
target.StopBuff(BuffId.Impaler_Buff);
}
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Melia.Shared.Game.Const;
using Melia.Shared.L10N;
using Melia.Zone.Buffs.Base;
using Melia.Zone.Network;
using Melia.Zone.Skills;
using Melia.Zone.Skills.Combat;
using Melia.Zone.World.Actors;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Melia.Zone.Buffs.Handlers.Swordsmen.Cataphract
{
/// <summary>
/// Buff handler for Impaler Debuff, which reduces def and makes it
/// impossible to block or dodge.
/// This also needs to prevent you from taking any action
/// </summary>
/// <remarks>
/// NumArg1: Skill Level
/// NumArg2: None
/// </remarks>
[BuffHandler(BuffId.Impaler_Debuff)]
public class Impaler_Debuff : BuffHandler, IBuffCombatDefenseBeforeCalcHandler
{
public const float DefPenalty = 0.3f;

/// <summary>
/// Starts buff, attaching the entity to the spear
/// </summary>
/// <param name="buff"></param>
public override void OnStart(Buff buff)
{
var target = buff.Target;
var caster = buff.Caster;

var reduceDef = target.Properties.GetFloat(PropertyName.DEF) * DefPenalty;

AddPropertyModifier(buff, target, PropertyName.DEF_BM, -reduceDef);

Send.ZC_ATTACH_TO_OBJ(target, caster, "Dummy_Impaler", "", 0.01f, 1, 1, "", 1, 0, 1);
}

/// <summary>
/// Ends the buff, freeing the entity
/// </summary>
/// <param name="buff"></param>
public override void OnEnd(Buff buff)
{
var target = buff.Target;
var caster = buff.Caster;

RemovePropertyModifier(buff, target, PropertyName.DEF_BM);

Send.ZC_DETACH_FROM_OBJ(target, caster);
}


/// <summary>
/// Applies the debuff'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.Unblockable = true;
modifier.ForcedHit = true;
}
}
}
74 changes: 74 additions & 0 deletions src/ZoneServer/Buffs/Handlers/Swordsmen/Cataphract/Trot_Buff.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Melia.Shared.Game.Const;
using Melia.Shared.L10N;
using Melia.Zone.Buffs.Base;
using Melia.Zone.Network;
using Melia.Zone.Skills;
using Melia.Zone.Skills.Combat;
using Melia.Zone.World.Actors;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Melia.Zone.Buffs.Handlers.Swordsmen.Cataphract
{
/// <summary>
/// Buff handler for Trot, which increases movement speed while riding
/// </summary>
/// <remarks>
/// NumArg1: Skill Level
/// NumArg2: None
/// </remarks>
[BuffHandler(BuffId.Trot_Buff)]
public class Trot_Buff : BuffHandler
{
/// <summary>
/// Starts buff, increasing movement speed
/// </summary>
/// <param name="buff"></param>
public override void OnStart(Buff buff)
{
var target = buff.Target;

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

/// <summary>
/// Ends the buff, resetting 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);
}


/// <summary>
/// Returns the speed bonus granted by the buff.
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
private float GetSpeedBonus(Buff buff)
{
return 5 + buff.NumArg1;
}


/// <summary>
/// Drains SP over time to keep the buff active
/// </summary>
/// <param name="buff"></param>
public override void WhileActive(Buff buff)
{
if (!buff.Target.IsBuffActive(BuffId.RidingCompanion))
{
buff.Target.StopBuff(buff.Id);
return;
}
if (!buff.Target.TrySpendSp(20))
{
buff.Target.StopBuff(buff.Id);
return;
}
}
}
}
90 changes: 89 additions & 1 deletion src/ZoneServer/Network/Send.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using Melia.Zone.World.Items;
using Melia.Zone.World.Maps;
using Yggdrasil.Extensions;
using Yggdrasil.Logging;
using Yggdrasil.Util;

namespace Melia.Zone.Network
Expand Down Expand Up @@ -2256,6 +2257,34 @@ public static void ZC_OWNER(Character character, IActor actor)
character.Connection.Send(packet);
}

/// <summary>
/// Tells the client that a monster is a Summoned monster
/// </summary>
/// <param name="character"></param>
/// <param name="isSummon"></param>
public static void ZC_IS_SUMMONING_MONSTER(IActor actor, bool isSummon)
{
var packet = new Packet(Op.ZC_IS_SUMMONING_MONSTER);
packet.PutInt(actor.Handle);
packet.PutByte(isSummon);

actor.Map.Broadcast(packet, actor);
}

/// <summary>
/// Tells the client that a monster is a Sorcerer Summon
/// </summary>
/// <param name="character"></param>
/// <param name="isSummon"></param>
public static void ZC_IS_SUMMON_SORCERER_MONSTER(IActor actor, bool isSummon)
{
var packet = new Packet(Op.ZC_IS_SUMMON_SORCERER_MONSTER);
packet.PutInt(actor.Handle);
packet.PutByte(isSummon);

actor.Map.Broadcast(packet, actor);
}

/// <summary>
/// Draws circle area on ground at position for characters in range
/// of the caster.
Expand Down Expand Up @@ -3188,7 +3217,7 @@ public static void ZC_PLAY_ANI(IActor actor, string animationName, bool stopOnLa
packet.PutByte(stopOnLastFrame);
packet.PutByte(0);
packet.PutFloat(0);
packet.PutFloat(1);
packet.PutFloat(1); // animation speed

// [i373230] Maybe added earlier
{
Expand All @@ -3199,6 +3228,65 @@ public static void ZC_PLAY_ANI(IActor actor, string animationName, bool stopOnLa
actor.Map.Broadcast(packet, actor);
}

/// <summary>
/// Attaches an entity to an object
/// </summary>
/// <param name="actor"></param>
/// <param name="attachToEntity"></param>
/// <param name="nodeName"></param>
/// <param name="packetString1"></param>
/// <param name="attachDelay"></param>
/// <param name="l1"></param>
/// <param name="l2"></param>
/// <param name="packetString2"></param>
/// <param name="b1"></param>
/// <param name="b2"></param>
/// <param name="b3"></param>
public static void ZC_ATTACH_TO_OBJ(IActor actor, IActor attachToEntity, string nodeName,
string packetString1, float attachDelay, long l1, long l2, string packetString2, byte b1, byte b2, byte b3)
{
if (!ZoneServer.Instance.Data.PacketStringDb.TryFind(nodeName, out var nodeNameData))
throw new ArgumentException($"Unknown packet string '{nodeName}'.");

if (!ZoneServer.Instance.Data.PacketStringDb.TryFind(packetString1, out var packetStringData1))
throw new ArgumentException($"Unknown packet string '{packetString1}'.");

if (!ZoneServer.Instance.Data.PacketStringDb.TryFind(packetString2, out var packetStringData2))
throw new ArgumentException($"Unknown packet string '{packetString2}'.");

var packet = new Packet(Op.ZC_ATTACH_TO_OBJ);

packet.PutInt(actor?.Handle ?? 0);
packet.PutInt(attachToEntity?.Handle ?? 0);
packet.PutInt(nodeNameData?.Id ?? 0);
packet.PutInt(packetStringData1?.Id ?? 0);
packet.PutFloat(attachDelay);
packet.PutLong(l1);
packet.PutLong(l2);
packet.PutInt(packetStringData2?.Id ?? 0);
packet.PutByte(b1);
packet.PutByte(b2);
packet.PutByte(b3);

actor.Map.Broadcast(packet);
}


/// <summary>
/// Detach from another object (usually another actor).
/// </summary>
/// <param name="actor"></param>
/// <param name="detachFromActor"></param>
public static void ZC_DETACH_FROM_OBJ(IActor actor, IActor detachFromActor)
{
var packet = new Packet(Op.ZC_DETACH_FROM_OBJ);

packet.PutInt(actor.Handle);
packet.PutInt(detachFromActor?.Handle ?? 0);

actor.Map.Broadcast(packet);
}

/// <summary>
/// Sends ZC_COMMON_SKILL_LIST to character (dummy).
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Melia.Shared.Game.Const;
using Melia.Zone.Network;
using Melia.Zone.Skills;
using Melia.Zone.World.Actors.Monsters;

namespace Melia.Zone.Pads.Handlers.Swordsman.Cataphract
{
/// <summary>
/// Handler for the Arditi_TreGranata pad, creates and disables the effect
/// </summary>
[PadHandler(PadName.Cataphract_SteedCharge)]
public class Cataphract_SteedCharge : ICreatePadHandler, IDestroyPadHandler
{
/// <summary>
/// Called when the pad is created.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
public void Created(object sender, PadTriggerArgs args)
{
var pad = args.Trigger;
var creator = args.Creator;

Send.ZC_NORMAL.PadUpdate(creator, pad, "Cataphract_SteedCharge", 0, 0, 150, true);
}

/// <summary>
/// Called when the pad is destroyed.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
public void Destroyed(object sender, PadTriggerArgs args)
{
var pad = args.Trigger;
var creator = args.Creator;

Send.ZC_NORMAL.PadUpdate(creator, pad, "Cataphract_SteedCharge", 0, 0, 150, false);
}
}
}
Loading