Skip to content
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9d14ab5
Initial Sadhu skill's implementations
felipecastagnarodecarvalho Jul 27, 2024
0f1cfaa
[WIP] Sadhu skills
felipecastagnarodecarvalho Jul 28, 2024
8a0803a
Merge branch 'master' of https://github.com/NoCode-NoLife/melia into …
felipecastagnarodecarvalho Jul 28, 2024
cdf1740
Adding the first sadhu Skill - Prakriti
felipecastagnarodecarvalho Jul 29, 2024
01a2f3a
Polishing Prakriti
felipecastagnarodecarvalho Jul 29, 2024
bd6a41f
Adding Anila skill
felipecastagnarodecarvalho Jul 29, 2024
3c5e170
Adding Possession skill (sadhu) + skill base class inheritance
felipecastagnarodecarvalho Jul 29, 2024
80ff162
Adding Enira sadhu skill
felipecastagnarodecarvalho Jul 30, 2024
5aa0295
Working on the sadhu arts that creates clones
felipecastagnarodecarvalho Jul 30, 2024
020d514
Small Update (Sadhu)
felipecastagnarodecarvalho Jul 30, 2024
cef4651
Merge branch 'master' into sadhu_skills
felipecastagnarodecarvalho Jul 30, 2024
70535a7
[WIP] Sadhu skills tweek
felipecastagnarodecarvalho Jul 30, 2024
e2203f0
Messing up with the IA (for dummies)
felipecastagnarodecarvalho Jul 31, 2024
d3fba4d
Minor changes Sadhu
felipecastagnarodecarvalho Aug 12, 2024
60bc776
Minor update sadhu
felipecastagnarodecarvalho Aug 13, 2024
507317e
Merging master
felipecastagnarodecarvalho Aug 13, 2024
10cda3d
Updating sadhu dummy AI
felipecastagnarodecarvalho Aug 13, 2024
f2b09d5
Merging master
felipecastagnarodecarvalho Aug 15, 2024
2c6492c
Sadhu skills - Working on the hability skills
felipecastagnarodecarvalho Aug 15, 2024
9ede990
Adding last two Sadhu skills
felipecastagnarodecarvalho Aug 16, 2024
e6f87ac
Updating skill file names
felipecastagnarodecarvalho Aug 22, 2024
888b8d5
Merging master
felipecastagnarodecarvalho Sep 13, 2024
d55e4af
Merge branch 'master' into sadhu_skills
felipecastagnarodecarvalho Sep 17, 2024
73e8c55
[WIP
felipecastagnarodecarvalho Sep 17, 2024
1a49524
Resolving review conversations
felipecastagnarodecarvalho Sep 18, 2024
08bde3b
Merging Upstream Master
felipecastagnarodecarvalho Mar 6, 2025
a0075b3
[WIP] Fixing review issues
felipecastagnarodecarvalho Mar 7, 2025
86338ef
Fixing remaining review issues
felipecastagnarodecarvalho Mar 8, 2025
3c9ed92
Initial fixes for review
felipecastagnarodecarvalho Jun 21, 2025
579e41d
Merge branch 'master' of https://github.com/NoCode-NoLife/Melia into …
felipecastagnarodecarvalho Jun 21, 2025
9c4d791
Updating sadhu skills (2) - commiting before pulling from master
felipecastagnarodecarvalho Jul 14, 2025
adadead
Merge branch 'master' of https://github.com/NoCode-NoLife/Melia into …
felipecastagnarodecarvalho Jul 14, 2025
845a5f0
Ready for a new review - sadhu updates
felipecastagnarodecarvalho Jul 14, 2025
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
2 changes: 1 addition & 1 deletion src/Shared/Data/Database/SkillTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class SkillTreeDb : DatabaseJson<SkillTreeData>
/// level.
/// </summary>
/// <param name="jobId"></param>
/// <param name="circle"></param>
/// <param name="jobLevel"></param>
/// <returns></returns>
public SkillTreeData[] FindSkills(JobId jobId, int jobLevel)
{
Expand Down
1 change: 1 addition & 0 deletions src/Shared/Game/Const/HitType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ public enum HitType : short
KnockBack = 3,
KnockDown = 4,
Type18 = 18,
Type33 = 33,
}
}
3 changes: 3 additions & 0 deletions src/Shared/Network/NormalOp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public static class Zone
public const int PlayEffect = 0x16;
public const int PlayForceEffect = 0x17;
public const int UpdateSkillEffect = 0x1F;
public const int UpdateModelColor = 0x20;
public const int FadeOut = 0x38;
public const int BarrackSlotCount = 0x3C;
public const int AttackCancel = 0x41;
Expand Down Expand Up @@ -67,6 +68,8 @@ public static class Zone
public const int PlayTextEffect = 0xE3;
public const int Unknown_E4 = 0xE7;
public const int Unknown_EF = 0xF2;
public const int EnableUseSkillWhileOutOfBody = 0x10B;
public const int EndOutOfBodyBuff = 0x10C;
public const int ChannelTraffic = 0x12D;
public const int SetGreetingMessage = 0x136;
public const int Unk13E = 0x13E;
Expand Down
182 changes: 182 additions & 0 deletions src/ZoneServer/Buffs/Handlers/Clerics/Sadhu/OOBE_Anila_Buff.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
using System;
using Melia.Shared.Game.Const;
using Melia.Zone.Buffs.Base;
using Melia.Zone.Network;
using Melia.Zone.Skills.Combat;
using Melia.Zone.Skills;
using Melia.Zone.Skills.SplashAreas;
using Melia.Zone.World.Actors;
using Melia.Zone.World.Actors.Characters;
using Melia.Zone.World.Actors.Pads;
using Melia.Zone.World.Actors.Monsters;
using static Melia.Zone.Skills.SkillUseFunctions;
using Melia.Shared.World;

namespace Melia.Zone.Buffs.Handlers.Clerics.Sadhu
{
/// <summary>
/// Handler for the Out Of Body Experience (OOBE) Anila Buff
/// which makes the character go back to original position after a while
/// and leave an effect that damages enemies on hit by a wave effect
/// </summary>
[BuffHandler(BuffId.OOBE_Anila_Buff)]
public class OOBE_Anila_Buff : BuffHandler
{
public override void OnStart(Buff buff)
{
var caster = buff.Caster;

// [Arts] Spirit Expert: Wandering Soul
if (caster.IsAbilityActive(AbilityId.Sadhu35) || caster is not Character casterCharacter)
return;

var dummyCharacter = casterCharacter.Map.GetDummyCharacter((int)buff.NumArg2);

if (dummyCharacter != null)
{
dummyCharacter.Died += this.OnDummyDied;
}
}

public override void OnEnd(Buff buff)
{
var caster = buff.Caster;

if (caster is not Character casterCharacter)
return;

var skillCharacter = casterCharacter.IsDummy && casterCharacter.Owner.IsAbilityActive(AbilityId.Sadhu35)
? casterCharacter.Owner
: caster;

if (skillCharacter.TryGetSkill(SkillId.Sadhu_Anila, out var skill))
{
skillCharacter.SetAttackState(true);

var pad = new Pad(PadName.Sadhu_Anila_Effect_Pad, skillCharacter, skill, new Square(caster.Position, caster.Direction, 50, 65));

pad.Position = caster.Position;
pad.Trigger.MaxActorCount = 7;
pad.Trigger.LifeTime = TimeSpan.FromSeconds(10);
pad.Trigger.Subscribe(TriggerType.Enter, this.OnCollisionEnter);

caster.Map.AddPad(pad);

// [Arts] Spirit Expert: Wandering Soul
if (casterCharacter.IsDummy && casterCharacter.Owner.IsAbilityActive(AbilityId.Sadhu35))
{
Send.ZC_SKILL_READY(casterCharacter.Owner, caster, skill, caster.Position, caster.Position);
Send.ZC_NORMAL.UpdateSkillEffect(casterCharacter.Owner, caster.Handle, caster.Position, caster.Direction, Position.Zero);
Send.ZC_SKILL_MELEE_GROUND(casterCharacter.Owner, caster, skill, caster.Position, ForceId.GetNew(), null);
} else
{
skill.IncreaseOverheat();
}
}

// [Arts] Spirit Expert: Wandering Soul
if (casterCharacter.IsDummy && casterCharacter.Owner.IsAbilityActive(AbilityId.Sadhu35))
{
this.RemoveDummyCharacter(casterCharacter);
return;
}

casterCharacter.Properties.Modify(PropertyName.MSPD_BM, -buff.NumArg1);

Send.ZC_NORMAL.EndOutOfBodyBuff(casterCharacter, BuffId.OOBE_Anila_Buff);
Send.ZC_NORMAL.UpdateModelColor(casterCharacter, 255, 255, 255, 255, 0.01f);

Send.ZC_PLAY_SOUND(casterCharacter, "skl_eff_yuchae_end_2");

this.ReturnToBody(casterCharacter, (int)buff.NumArg2);
}

/// <summary>
/// Remove the dummy character from the map
/// </summary>
/// <param name="character"></param>
private void RemoveDummyCharacter(Character character)
{
if (character.Owner is Character ownerCharacter)
Send.ZC_OWNER(ownerCharacter, character, 0);

Send.ZC_LEAVE(character);

character.Map.RemoveDummyCharacter(character);
}

/// <summary>
/// Makes the chararacter returns to original position
/// and also get ride of the dummy character
/// </summary>
/// <param name="character"></param>
/// <param name="dummyHandle"></param>
private void ReturnToBody(Character character, int dummyHandle)
{
var dummyCharacter = character.Map.GetDummyCharacter(dummyHandle);

if (dummyCharacter == null)
return;

character.Position = dummyCharacter.Position;
character.Direction = dummyCharacter.Direction;

dummyCharacter.Died -= this.OnDummyDied;

Send.ZC_ROTATE(character);
Send.ZC_SET_POS(character, dummyCharacter.Position);
Send.ZC_OWNER(character, dummyCharacter, 0);
Send.ZC_LEAVE(dummyCharacter);

character.Map.RemoveDummyCharacter(dummyCharacter);
}

/// <summary>
/// Called when an actor enters the skill's pad area.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void OnCollisionEnter(object sender, PadTriggerActorArgs args)
{
var pad = args.Trigger;
var creator = args.Creator;
var target = args.Initiator;

if (pad.Trigger.AtCapacity)
return;

if (!creator.CanAttack(target))
return;

this.Attack(pad.Skill, creator, target);
}

/// <summary>
/// Attacks the target
/// </summary>
/// <param name="skill"></param>
/// <param name="caster"></param>
private void Attack(Skill skill, ICombatEntity caster, ICombatEntity target)
{
var modifier = SkillModifier.MultiHit(3);
var skillHitResult = SCR_SkillHit(caster, target, skill, modifier);

target.TakeDamage(skillHitResult.Damage, caster);

var hit = new HitInfo(caster, target, skill, skillHitResult, TimeSpan.FromMilliseconds(200));

Send.ZC_HIT_INFO(caster, target, hit);
}

/// <summary>
/// Called when the dummy character died
/// disappeared.
/// </summary>
/// <param name="character"></param>
/// <param name="killer"></param>
private void OnDummyDied(Character character, ICombatEntity killer)
{
character.Owner.StopBuff(BuffId.OOBE_Anila_Buff);
}
}
}
Loading