Files
test/Assets/PerfectWorld/Scripts/Skills/FLOW_COMBO_SKILL_CLICK.md
2026-01-23 18:01:15 +07:00

6.7 KiB

Comparison: OnMsgPlayerCastSkill - C++ vs C# Conversion

Summary

The conversion from C++ to C# is mostly complete but has some missing elements and commented-out code that should be reviewed.

All Switch Cases Present

All 9 switch cases are present in both versions:

  1. OBJECT_CAST_SKILL
  2. SKILL_PERFORM
  3. HOST_STOP_SKILL
  4. SELF_SKILL_INTERRUPTED
  5. OBJECT_CAST_INSTANT_SKILL
  6. OBJECT_CAST_POS_SKILL
  7. PLAYER_CAST_RUNE_SKILL
  8. PLAYER_CAST_RUNE_INSTANT_SKILL
  9. ERROR_MESSAGE
  10. default case

Missing/Incomplete Elements

1. Missing Assertion Check in OBJECT_CAST_SKILL

C++ (line 5876):

ASSERT(pCmd->caster == m_PlayerInfo.cid);

C# (line 916):

// MISSING: No assertion check for pCmd.caster == m_PlayerInfo.cid

Impact: Medium - This is a safety check that validates the caster ID matches the player's ID.

2. Commented Out AP_ActionEvent in HOST_STOP_SKILL ⚠️

C++ (line 5958):

AP_ActionEvent(AP_EVENT_STOPSKILL);

C# (line 1025):

//AP_ActionEvent(AP_EVENT_STOPSKILL);

Impact: Medium - Action event notification is disabled. May affect auto-policy or other systems that listen to this event.

3. Commented Out AP_ActionEvent in SELF_SKILL_INTERRUPTED ⚠️

C++ (line 6005):

AP_ActionEvent(AP_EVENT_STOPSKILL);

C# (line 1084):

//AP_ActionEvent(AP_EVENT_STOPSKILL);

Impact: Medium - Same as above.

4. Missing Fixed Message in SELF_SKILL_INTERRUPTED ⚠️

C++ (line 6003):

g_pGame->GetGameRun()->AddFixedMessage(FIXMSG_SKILLINTERRUPT);

C# (line 1081):

// g_pGame.GetGameRun().AddFixedMessage(FIXMSG_SKILLINTERRUPT);
Debug.Log("Skill interrupted!");

Impact: Low - Replaced with Debug.Log, but the fixed message system might be needed for UI notifications.

5. Missing Auto-Policy Event in SELF_SKILL_INTERRUPTED ⚠️

C++ (line 6008):

CECAutoPolicy::GetInstance().SendEvent_SkillInterrupt(skill_id);

C# (line 1087):

// CECAutoPolicy::GetInstance().SendEvent_SkillInterrupt(skill_id);

Impact: Medium - Auto-policy system won't be notified of skill interruptions, which may affect automated gameplay features.

6. Commented Out Camera Update in OBJECT_CAST_POS_SKILL ⚠️

C++ (line 6080):

UpdateFollowCamera(false, 10);

C# (line 1165):

//UpdateFollowCamera(false, 10);

Impact: Low - Camera update is disabled. May affect camera behavior for certain skills.

Differences That Are Acceptable

1. Logging System Differences

C++:

g_pGame->RuntimeDebugInfo(0xffffffff, _AL("Cast skill(%d): %s"), ...);

C#:

Debug.Log($"Cast skill({m_pCurSkill.GetSkillID()})");

Status: Acceptable - Different logging systems, functionality preserved.

2. Additional Logging in C#

C# has extra logging for return-to-town skill (ID 167):

if (m_pCurSkill.GetSkillID() == ID_RETURNTOWN_SKILL)
{
    Debug.Log($"Return-to-town skill (167) cast - State2 should trigger SetReturntown(1) on server");
}

Status: Acceptable - Additional debugging/logging is fine.

3. Memory Management Differences

C++:

if(m_pTargetItemSkill)
{
    delete m_pTargetItemSkill;
    m_pTargetItemSkill = NULL;
}

C#:

if (m_pTargetItemSkill != null)
{
    m_pTargetItemSkill = null; // GC will handle cleanup
}

Status: Acceptable - C# uses garbage collection, no explicit delete needed.

4. Type Casting Differences

C++:

cmd_object_cast_skill* pCmd = (cmd_object_cast_skill*)Msg.dwParam1;

C#:

cmd_object_cast_skill pCmd = GPDataTypeHelper.FromBytes<cmd_object_cast_skill>((byte[])Msg.dwParam1);

Status: Acceptable - Different serialization approach, functionality preserved.

5. Switch Statement Syntax

C++:

switch (Msg.dwParam2)
{
case OBJECT_CAST_SKILL:

C#:

switch (Convert.ToInt32(Msg.dwParam2))
{
case int value2 when value2 == CommandID.OBJECT_CAST_SKILL:

Status: Acceptable - C# pattern matching syntax, functionality preserved.

Post-Switch Code Comparison

Action Start Event

C++ (line 6241-6242):

if( bActionStartSkill )
    AP_ActionEvent(AP_EVENT_STARTSKILL, iActionTime);

C# (line 1338-1339):

if (bActionStartSkill)
    AP.AP_ActionEvent((int)AP_EVENT.AP_EVENT_STARTSKILL, iActionTime);

Status: Complete - Properly converted and active.

Do Other Thing Logic

C++ (line 6244-6258):

if (bDoOtherThing)
{
    if (m_pComboSkill && !m_pComboSkill->IsStop())
    {
        if( CECAutoPolicy::GetInstance().IsAutoPolicyEnabled() )
            g_pGame->GetGameRun()->PostMessage(MSG_HST_CONTINUECOMBOSKILL, MAN_PLAYER, 0, 0, m_pComboSkill->GetGroupIndex());
        else
            m_pComboSkill->Continue(false);
    }
    else
    {
        if( idTarget && idTarget != m_PlayerInfo.cid )
            NormalAttackObject(idTarget, true);
    }
}

C# (line 1341-1357):

if (bDoOtherThing)
{
    if (m_pComboSkill != null && !m_pComboSkill.IsStop())
    {
        if (CECAutoPolicy.GetInstance().IsAutoPolicyEnabled())
            EC_ManMessage.PostMessage(EC_MsgDef.MSG_HST_CONTINUECOMBOSKILL, MANAGER_INDEX.MAN_PLAYER, 0, 0, m_pComboSkill.GetGroupIndex());
        else
            m_pComboSkill.Continue(false);
    }
    else
    {
        if (idTarget != 0 && idTarget != m_PlayerInfo.cid)
            NormalAttackObject(idTarget, true);
    }
}

Status: Complete - Properly converted with equivalent logic.

Recommendations

High Priority

  1. Add missing assertion check in OBJECT_CAST_SKILL case:
    Debug.Assert(pCmd.caster == m_PlayerInfo.cid, "Caster ID mismatch");
    

Medium Priority

  1. Uncomment and verify AP_ActionEvent(AP_EVENT_STOPSKILL) calls if the AP system is implemented in C#.
  2. Uncomment CECAutoPolicy::GetInstance().SendEvent_SkillInterrupt(skill_id) if auto-policy is needed.

Low Priority

  1. Review if UpdateFollowCamera is needed for OBJECT_CAST_POS_SKILL case.
  2. Consider implementing AddFixedMessage system if UI notifications are needed for skill interruptions.

Conclusion

Conversion Completeness: ~90%

The conversion is functionally complete with all major logic paths implemented. However, several safety checks and event notifications are commented out or missing, which may affect:

  • Auto-policy system integration
  • UI notifications for skill interruptions
  • Camera behavior for position-based skills
  • Safety validation (caster ID check)

These should be reviewed and either implemented or confirmed as intentionally disabled.