Self-cast skills

Lullz

Pirate
Registered
LV
0
 
Joined
Feb 11, 2026
Messages
7
Reaction score
2
Points
5
Hello,

Is it possible to use keyboard shortcuts (F1–F12, etc.) to self-cast skills (heal, buffs, recovery)?
The idea is to allow Cleric/SM players to use support skills on themselves more quickly, without having to click on their character or the UI.

Thank you !
 
This is set by the chApplyTarget field (in skillinfo.txt, Process target column 18).
The chApplyTarget specifies values from
C++:
enum ESkillObjType
{
    // Main skill target type:
    // 1 - self, 2 - team, 3 - scene/ground point, 4 - enemy, 5 - any target.

    enumSKILL_TYPE_SELF          = 1,    // Self
    enumSKILL_TYPE_TEAM        = 2,    // Teammate / party member
    enumSKILL_TYPE_SCENE       = 3,    // Ground point (area target)
    enumSKILL_TYPE_ENEMY      = 4,    // Hostile target
    enumSKILL_TYPE_ALL            = 5,    // Any target
    enumSKILL_TYPE_PLAYER_DIE    = 6,    // Dead player (resurrection target)
    enumSKILL_TYPE_EXCEPT_SELF  = 7,    // Any target except self

    // Special targets (profession/interactive objects):
    enumSKILL_TYPE_REPAIR      = 17,    // Repairable object
    enumSKILL_TYPE_TREE          = 18,    // Tree
    enumSKILL_TYPE_MINE         = 19,    // Ore vein
    enumSKILL_TYPE_TRADE       = 22,    // Trade object
    enumSKILL_TYPE_FISH           = 28,    // Fishing spot
    enumSKILL_TYPE_SALVAGE    = 29,    // Salvage object
};
To cast a skill on yourself, set this field to 1 (enumSKILL_TYPE_SELF), but this skill cannot be used on other characters.
 
Thank you Luke for your response,

But what I meant was more tricky:
- No change in skills
- Tweaking the client to add a shortcut for self-casting,
- Still allowing the same skill to be cast on other players (using another shortcut).

Example:
Skill: Heal
F1: Heal by selecting a target
F2: Seal-heal (without selecting a target)
 
After making these changes to the client code, the skills defined in IsRightClickSelfCastSkill will be cast on your character when you right-click on the quick access panel. The behavior of the left mouse button will not change, and you will be able to apply buffs to other characters.

Add to Client/src/UISkillCommand.h:13
C++:
bool IsRightClickSelfCastSkill(int skillId);

Client/src/UISkillCommand.cpp after string 23 add code:
C++:
bool IsRightClickSelfCastSkill(int skillId)
{
    switch (skillId)
    {
    case 100: // Spiritual Fire
    case 102: // Tornado Swirl

        return true;
    default:
        return false;
    }
}

static bool CanForceSelfCast(CSkillRecord* pSkill)
{
    if (!pSkill)
        return false;

    if (!IsRightClickSelfCastSkill(pSkill->nID))
        return false;

    if (!pSkill->GetIsHelpful())
        return false;

    switch (pSkill->chApplyTarget)
    {
    case enumSKILL_TYPE_SELF:
    case enumSKILL_TYPE_TEAM:
    case enumSKILL_TYPE_ALL:
        return true;
    default:
        return false;
    }
}

Add to IsRightClickSelfCastSkill skills that you want to apply to yourself by right-clicking

Replace the
CSkillCommand::UseCommand in file Client/src/UISkillCommand.cpp function completely with:
C++:
bool CSkillCommand::UseCommand(bool value)
{
    CCharacter* pCha = CGameScene::GetMainCha();
    if( !pCha ) return false;

    const bool isRightClick = value;

    if( !_pSkill->GetIsUse() )
        return false;

    if( _pSkill->IsReadingSkill() )
    {
        CReadingState* reading = new CReadingState( pCha->GetActor() );
        return pCha->GetActor()->SwitchState( reading );
    }

    if( _pSkill->GetIsActive() )
    {
        int nState = _pSkill->nStateID;
        if( nState>0 )
        {
            CS_BeginAction( pCha, enumACTION_STOP_STATE, &nState );
        }
        return nState>0;
    }

    if( isRightClick && CanForceSelfCast(_pSkill) )
    {
        if( !g_SkillUse.IsUse(_pSkill, pCha, pCha) )
        {
            g_pGameApp->SysInfo( "%s", g_SkillUse.GetError() );
            return false;
        }

        CAttackState* attack = new CAttackState(pCha->GetActor());
        attack->SetSkill( _pSkill );
        attack->SetTarget( pCha );
        attack->SetCommand( this );
        return pCha->GetActor()->SwitchState(attack);
    }

    if( _pSkill->GetDistance()<=0 )
    {
        CAttackState* attack = new CAttackState(pCha->GetActor());
        attack->SetSkill( _pSkill );
        attack->SetTarget( pCha );
        attack->SetCommand( this );
        return pCha->GetActor()->SwitchState(attack);
    }

    return false;
}

Add to Client/src/UIFastCommand.cpp:9
C++:
#include "uiskillcommand.h"

Replace the CFastCommand::Exec in file Client/src/UIFastCommand.cpp function completely with:
C++:
void CFastCommand::Exec(bool rightclick){
    if(_pCommand == nullptr){
        return;
    }
    char type;
    short grid;
    g_stUIEquip._GetCommandShortCutType( _pCommand, type, grid );
    
    if(type != defItemShortCutType){
        if(rightclick){
            CSkillCommand* pSkillCommand = dynamic_cast<CSkillCommand*>(_pCommand);
            if(pSkillCommand && IsRightClickSelfCastSkill(pSkillCommand->GetSkillID())){
                _pCommand->ExecRightClick();
            }else{
                // Non-whitelisted skills must keep the exact old behavior.
                _pCommand->Exec();
            }
        }else{
            _pCommand->Exec();
        }
    }else{
        if(_pCommand2 != nullptr){
            _pCommand2->ExecRightClick();
            _pCommand->Exec();
        }else{
            CItemCommand* pFastItem = dynamic_cast<CItemCommand*>(_pCommand);
            int fastItemType = pFastItem->GetItemInfo()->sType;
            int equipItemType = 0;
            SItemGrid grdItem  = g_stUIBoat.GetHuman()->GetPart().SLink[enumEQUIP_LHAND];
            if(grdItem.sID != 0){
                CItemRecord* pEquipItem = GetItemRecordInfo( grdItem.sID);
                if(pEquipItem){
                    equipItemType = pEquipItem->sType;
                }
            }
            if((equipItemType == 11 && fastItemType == 1) || rightclick){
                _pCommand->ExecRightClick();
            }else{
                _pCommand->Exec();
            }
        }
    }
}

Replace the CCommandObj::ExecRightClick in file Client/src/UICommand.cpp function completely with:
C++:
bool CCommandObj::ExecRightClick(){
    if( !CGameApp::GetCurScene() || !CGameScene::GetMainCha() ){
        return false;
    }

    _pCommand = nullptr;
    if ( IsAllowUse() ){
        bool isUse = true;
        if( GetParent() ){
            UseComandEvent pEvent = GetParent()->GetUseCommantEvent();
            if( pEvent ){
                pEvent( this, isUse );
            }
        }

        if( !isUse ){
            return false;
        }

        return UseCommand(true);
    }

    Error();
    return false;
}

Attention. This functionality has been tested very little, so there may be errors. Please keep a backup of the files you are changing.
 
That's awesome !
Is it possible to do it using keyboard shortcut ?
Maybe by configuring a keybind to be a self-cast shortcut
 
To be honest, I haven't delved into this yet. In the future, I plan to modify the quick key system by customizing shortcuts, but I haven't reached that point yet.
 
  • Like
Reactions: Lullz