An effort to improve episode 6 support for private servers

@Bowie

C++:
CUser::AddApplySkillBuff(user, skill);

Will this sends Packet 0x50D on its own or do I have to do it by myself?

I tried this

C++:
auto charName = args.at(0);  // character name
    auto skillId = std::stoi(args.at(1));
    auto skillLevel = std::stoi(args.at(2));

    auto user = CWorld::FindUser(charName.c_str());
    if (!user) {
        std::stringstream output_format;
        output_format << "Character " << charName << " not found";
        output = output_format.str();
        return 0; // Exit if user is not found
    }

    auto skill = CGameData::GetSkillInfo(skillId, skillLevel);
    if (!skill) {
        std::stringstream output_format;
        output_format << "Skill with ID " << skillId << " and level " << skillLevel << " not found";
        output = output_format.str();
        return 0; // Exit if skill is not found
    }

    // Prepare the SkillUseOutgoing packet
    SkillUseOutgoing outgoing{};
    outgoing.senderId = user->connection.object.id;
    outgoing.targetId = user->connection.object.id;
    outgoing.skillId = skill->skillId;
    outgoing.skillLv = skill->skillLv;

    // Send the skill usage packet to the user
    Helpers::Send(user, &outgoing, sizeof(SkillUseOutgoing));

    // Apply the skill buff
    CUser::AddApplySkillBuff(user, skill);

    EnterCriticalSection(&user->applySkills.cs);

    // Start from the first node after the sentinel tail
    auto node = user->applySkills.sentinel.tail;
    node = node->next;  // Move to the first node
    user->applySkills.sentinel.head = node;

    int index = 0; // Index to track the skill position in the list
    bool skillFound = false;

    while (node && node != user->applySkills.sentinel.tail)
    {
        auto skillIn = reinterpret_cast<CSkill*>(node);

        // Check if the skill matches
        if (skillIn->skillId == skill->skillId && skillIn->skillLv == skill->skillLv)
        {
            skillFound = true;

            // Correctly set the id for addBuff
            SkillApplyOutgoing addBuff{};
            addBuff.id = index; // Send the matching skill's index
            addBuff.skillId = skill->skillId;
            addBuff.skillLv = skill->skillLv;

            Helpers::Send(user, &addBuff, sizeof(SkillApplyOutgoing));
            break;
        }

        node = node->next;  // Move to the next node
        user->applySkills.sentinel.head = node;
        index++; // Increment index
    }

    LeaveCriticalSection(&user->applySkills.cs);

    if (!skillFound)
    {
        std::stringstream output_format;
        output_format << "Skill " << skillId << " (Level " << skillLevel << ") could not be applied for " << charName;
        output = output_format.str();
        return 0; // Exit after reporting error
    }

    // Output a success message
    std::stringstream output_format;
    output_format << "Skill " << skillId << " (Level " << skillLevel << ") triggered for " << charName;
    output = output_format.str();
    return 0;

Upon testing, it says Example

Code:
Skill 287 (Level 1) could not be applied for Character
 
Will this sends Packet 0x50D on its own or do I have to do it by myself?
I don't see it sending that packet.

I think you should use "nostrum" skills and do it this way:

C++:
auto charName = args.at(0);  // character name
auto skillId = std::stoi(args.at(1));
auto skillLevel = std::stoi(args.at(2));

auto user = CWorld::FindUser(charName.c_str());
if (!user) {
    std::stringstream output_format;
    output_format << "Character " << charName << " not found";
    output = output_format.str();
    return 0; // Exit if user is not found
}

auto skill = CGameData::GetSkillInfo(skillId, skillLevel);
if (!skill) {
    std::stringstream output_format;
    output_format << "Skill with ID " << skillId << " and level " << skillLevel << " not found";
    output = output_format.str();
    return 0; // Exit if skill is not found
}

if (!CUser::UseItemSkill(user, skill)) {
    std::stringstream output_format;
    output_format << "Skill " << skillId << " (Level " << skillLevel << ") could not be applied for " << charName;
    output = output_format.str();
    return 0; // Exit after reporting error
}

// Output a success message
std::stringstream output_format;
output_format << "Skill " << skillId << " (Level " << skillLevel << ") triggered for " << charName;
output = output_format.str();
return 0;

I had to update the return type of UseItemSkill, so please change it from void to bool in your code.
 
Last edited:
Back
Top