Tero Posted October 12, 2023 Group: Members Topic Count: 8 Topics Per Day: 0.01 Content Count: 65 Reputation: 131 Joined: 10/01/22 Last Seen: March 27 Share Posted October 12, 2023 (edited) This has been a request that I think everyone has made at one point or another, but I initially looked at it and said "too complicated". Well, today I decided to finally code the thing. Basically, this is an adjustment to the Reset NPC that gives you the option to only reset your current class, leaving your previous classes untouched. This requires code changes to support it, and you'll have to recompile your server afterwards. A quick caveat, though this includes code to support third and fourth classes (for Renewal), that code is untested. It's similar to the second class logic so it should work, but if you have some kind of weird issue it's probably there. In pc.cpp, find the pc_resetskill method Find this line: int i, skill_point=0; Replace it with this: int i, j, k, l, baseClass, secondTransClass, thirdClass, currentClass, skid, skill_point = 0; bool previousClassSkill, isSecondClass = false, isThirdClass = false, isFourthClass = false; Find this line: if( flag&4 && (sd->class_&MAPID_UPPERMASK) != MAPID_BARDDANCER ) return 0; Insert this below it (don't replace the code above). If your server has fourth classes, uncomment that line. baseClass = pc_mapid2jobid(sd->class_ & MAPID_BASEMASK, sd->status.sex); secondTransClass = pc_mapid2jobid(sd->class_ & MAPID_UPPERMASK | JOBL_UPPER, sd->status.sex); thirdClass = pc_mapid2jobid(sd->class_ | JOBL_THIRD, sd->status.sex); currentClass = pc_mapid2jobid(sd->class_, sd->status.sex); if ((sd->class_ & MAPID_BASEMASK) != sd->class_ && (sd->class_ & MAPID_BASEMASK | JOBL_UPPER) != sd->class_ && (sd->class_ & MAPID_BASEMASK | JOBL_BABY) != sd->class_) isSecondClass = true; if ((sd->class_ | JOBL_THIRD) == sd->class_ && (sd->class_ & MAPID_BASEMASK) != sd->class_ && (sd->class_ & MAPID_UPPERMASK) != sd->class_) isThirdClass = true; //if ((sd->class_ | JOBL_FOURTH) == sd->class_ && (sd->class_ & MAPID_BASEMASK) != sd->class_ && (sd->class_ & MAPID_UPPERMASK) != sd->class_ && (sd->class_ | JOBL_THIRD) != sd->class_) isFourthClass = true; currentClass = pc_class2idx(currentClass); baseClass = pc_class2idx(baseClass); secondTransClass = pc_class2idx(secondTransClass); thirdClass = pc_class2idx(thirdClass); Find this line if (lv == 0 || skill_id == 0) continue; What you need to add next depends on your version of eathena. If you are on latest, which has the new skill tree, add this below that line: if (flag & 16) { previousClassSkill = false; if (baseClass != currentClass) { std::shared_ptr<s_skill_tree> firstTree = skill_tree_db.find(baseclass); if (tree != nullptr && !tree->skills.empty()) { for (const auto &it : tree->skills) { skid = skill_get_index(it.first); if (skid == skill_id) previousClassSkill = true; } } } if (isThirdClass) { std::shared_ptr<s_skill_tree> secondTree = skill_tree_db.find(secondTransClass); if (tree != nullptr && !tree->skills.empty()) { for (const auto &it : tree->skills) { skid = skill_get_index(it.first); if (skid == skill_id) previousClassSkill = true; } } } if (isFourthClass) { std::shared_ptr<s_skill_tree> thirdTree = skill_tree_db.find(thirdClass); if (tree != nullptr && !tree->skills.empty()) { for (const auto &it : tree->skills) { skid = skill_get_index(it.first); if (skid == skill_id) previousClassSkill = true; } } } } If you are on an older version, which has the old form of skill_tree, add this below that line instead: if (flag & 16) { previousClassSkill = false; if (baseClass != currentClass) { for (j = 0; j < MAX_SKILL_TREE && (skid = skill_tree[baseClass][j].skill_id) > 0; j++) { if (skid == skill_id) previousClassSkill = true; } } if (isThirdClass) { for (k = 0; k < MAX_SKILL_TREE && (skid = skill_tree[secondTransClass][k].skill_id) > 0; k++) { if (skid == skill_id) previousClassSkill = true; } } if (previousClassSkill) continue; } We're pretty much done with pc_resetskill, but if you want, you can add this to the comment at the top of the method, as the final line: * if flag&16, Only reset skills that the current class can learn Almost done with code changes, now we just need to add the script function. The remainder of the changes are in script.cpp: First, find the definitions of the script functions by searching for this: struct script_function buildin_func[] And add the following line somewhere, ideally below the one for resetskill BUILDIN_DEF(resetskillcurrentonly, "?"), Now add this method somewhere, ideally below resetskill but it can in theory go anywhere. /** * Reset player's skill, leaving previous classes untouched * resetskillcurrentonly({<char_id>}); **/ BUILDIN_FUNC(resetskillcurrentonly) { TBL_PC* sd; if (!script_charid2sd(2, sd)) return SCRIPT_CMD_FAILURE; pc_resetskill(sd, 17); return SCRIPT_CMD_SUCCESS; } With this done, you can recompile the client and everything should be set. Now all you need is the new version of the resetnpc script below and you'll have the new functionality. Man, this was a lot harder than it should have been. Rathena should really just add this option by default. resetnpc.txt Edited November 8, 2023 by Tero 3 Quote Link to comment Share on other sites More sharing options...
Nullifier Posted November 8, 2023 Group: Members Topic Count: 45 Topics Per Day: 0.01 Content Count: 140 Reputation: 11 Joined: 09/28/14 Last Seen: November 7, 2024 Share Posted November 8, 2023 Great job! Quote Link to comment Share on other sites More sharing options...
eleriaqueen Posted April 2, 2024 Group: Members Topic Count: 5 Topics Per Day: 0.00 Content Count: 53 Reputation: 20 Joined: 04/21/13 Last Seen: March 22 Share Posted April 2, 2024 (edited) I love this. And yeah this should be the default behavior of the reset npc! Could someone with good rA scripting knowledge check the script, could there be issues with 4th jobs ? Edited April 2, 2024 by eleriaqueen Quote Link to comment Share on other sites More sharing options...
Frost Diver Posted April 2, 2024 Group: Members Topic Count: 48 Topics Per Day: 0.02 Content Count: 189 Reputation: 7 Joined: 10/22/18 Last Seen: 2 hours ago Share Posted April 2, 2024 On 10/12/2023 at 9:00 AM, Tero said: * if flag&16, Only reset skills that the current class can learn i dont understand this part. where should i put this line? Quote Link to comment Share on other sites More sharing options...
Rynbef Posted April 2, 2024 Group: Forum Moderator Topic Count: 48 Topics Per Day: 0.01 Content Count: 940 Reputation: 125 Joined: 05/23/12 Last Seen: Tuesday at 07:40 PM Share Posted April 2, 2024 (edited) On 10/12/2023 at 3:00 AM, Tero said: We're pretty much done with pc_resetskill, but if you want, you can add this to the comment at the top of the method, as the final line: If u want and Tero already write where to add this line. It's just a comment for the method. It's do nothing. U can add it on the comments on top of pc_resetskill for explain reasons. Rynbef~ Edited April 2, 2024 by Rynbef Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.