Jump to content

Syreldar

Premium
  • Posts

    1295
  • Joined

  • Last visited

  • Days Won

    38
  • Feedback

    100%

Everything posted by Syreldar

  1. The change I posted has been tested on default mainlines, like all the releases I made. Also, I believe the code I changed is the same on every rev that has been leaked 9 years ago. In short, there's nothing wrong with my release. By the gif you just sent I believe the updatepacket is failing. Try to redo my changes except inside the RemoveAffect function use this code instead of the one you find in the release. if (single) if (AFFECT_REVIVE_INVISIBLE != pkAff->dwType) ComputePoints(); else UpdatePacket(); else UpdatePacket();
  2. I made 2 .gifs after coding the fix, you can find them in the topic. It shows that warrior skills clear just fine.
  3. The fix I posted 5 years ago has been thoroughly tested by many users, myself included. There's no problem whatsoever, but feel free to use whatever suits you best.
  4. 11/05/2023: Added color_str(color, text). Updated some global calls for the latest globals.lua update.
  5. 11/05/2023: Improvements to the overall structure of the globals. Added POINTS
  6. I was talking about your questcategory not behaving properly, not having a selection is also a quest issue, not the system's.
  7. No, you just had to use a letter. That visual error is due to your quest's string probably missing the format for the number.
  8. *10000, not 1000! These formalities can be avoided by using the InDungeon(MAP_INDEX) function from my function lib. Also care about the "elseif", you should remove the if's end for it to work.
  9. I mean.. In the first quest you're using pc.warp, not even using its index arg, meaning you make a simple warp to a map. Everyone can access that map, obviously. In the second quest you're warping into the same map always with pc.warp, starting a 3 seconds timer and then calling d.new_jump_all, meaning you send every person in your map, yourself included, inside an instanced version of the target map. The solution is to either use d.new_jump or d.new_jump party, the former warping only you, the latter warping you and your whole party if present. Also never use local timers within a dungeons, they're bound to pc instances, meaning if you crash the instance breaks even if you can rejoin to it. Also always make dungeon checks on triggers, when 2095.kill begin is nowhere near enough. you gotta check the map index, too. Also you are generating yet another dungeon instance when the baroness spawns via calling d.new_jump_all for absolutely no reason.
  10. That's none of his business. You simply set the item's size to 0. Your item_proto's fault.
  11. if d.unique_get_hp_perc("fake" .. i) < 50 then d.purge_unique("fake" .. i) change with: if not d.is_unique_dead("fake" .. i) and d.unique_get_hp_perc("fake" .. i) < 50 then d.purge_unique("fake" .. i) This way you check if the unique still exists before making operations and checks on it. Sadly the official quests are far from perfect. They work, but they lack safety checks like these. Anyway, this is the right way to do stuff with uniques, but despite this fix you will still get an 'error' that looks like this: IsUniqueDead: Unknown Key or Dead : fake3 Now this one actually makes no sense as an error, meaning it's not actually an error. I'll explain briefly: This triggers, like I show in the snippet below, when an unique is not found in the unique map. But that's exactly the point of the 'IsUniqueDead' function in the first place, to check if they're dead or not existing, so I suspect they just copypasted it from the other similiar methods and never doublechecked, but one thing for sure: this syserr definitely does not belong to this method and can safely be commented out, like this: bool CDungeon::IsUniqueDead(const std::string& key) { TUniqueMobMap::iterator it = m_map_UniqueMob.find(key); if (it == m_map_UniqueMob.end()) { //sys_err("Unknown Key or Dead : %s", key.c_str()); return true; } return it->second->IsDead(); } And now not only the quest's code will behave properly, but your syserr will also be clean from errors like this, assuming you haven't got any other quest that makes unique calls without checking for IsUniqueDead, in which case you'll have to add the check in each one of their occurrences, too.
  12. ..You really don't need that amount of code and states to make such a basic thing. define MAX_LEVEL 70 define PROG_LEVEL 10 define START_AVG_DMG 10 define PROG_AVG_DMG 3 define MAX_AVG_DMG 30 -- Needs: globals.lua, functions.lua, item.set_attribute(idx, type, value) quest young_heroes_weapons begin state start begin function IsYoungHeroLevel(pc_level) return pc_level >= PROG_LEVEL*pc.getqf("times") and pc_level <= MAX_LEVEL; end -- function function GetYoungHeroWeaponsPerJob(pc_job) local data = { [WARRIOR] = {21900, 21903}, [NINJA] = {21900, 21901, 21902}, [SURA] = {21900}, [SHAMAN] = {21904, 21905}, [WOLFMAN] = {21906} }; return data[pc_job]; end -- function when letter or levelup with young_heroes_weapons.IsYoungHeroLevel(pc.get_level()) begin send_letter("Young Heroes' Weapons"); end -- when when button or info with young_heroes_weapons.IsYoungHeroLevel(pc.get_level()) begin say_title("Young Heroes' Weapons:[ENTER]") say("Select your weapon:[ENTER]") local weapons_per_job = young_heroes_weapons.GetYoungHeroWeaponsPerJob(pc.get_job()); local choose_weapon_list_name = {}; for _, weapon_vnum in ipairs(weapons_per_job) do table.insert(choose_weapon_list_name, item_name(weapon_vnum + PROG_LEVEL*pc.getqf("times"))); end -- for table.insert(choose_weapon_list_name, "I'll choose later"); local selection = select_table(choose_weapon_list_name); if (selection == table.getn(choose_weapon_list_name)) then send_letter(letter_str); return; end -- if local weapon_to_receive = weapons_per_job[selection] + PROG_LEVEL*pc.getqf("times"); pc.give_item2_select(weapon_to_receive); -- Adds Average Damage like official. item.set_attribute(0, APPLY.NORMAL_HIT_DAMAGE_BONUS, math.min(MAX_AVG_DMG, START_AVG_DMG + PROG_AVG_DMG*pc.getqf("times"))); pc.setqf("times", pc.getqf("times")+1); q.done(); end -- when end -- state end -- quest
  13. 25/04/2023: Added SELECT_YES, SELECT_ENTER, SELECT_NO; Added EMPIRES; Added ARMED_HORSE_LEVEL, MILITARY_HORSE_LEVEL; Added STATUS_VIT, STATUS_INT, STATUS_STR, STATUS_DEX; Added ITEM_TYPES, ITEM_SUB_TYPES; Added AFFECT; Updated APPLY; Added JOB_TO_RACE, RACE_TO_JOB, RACE_TO_SEX; Changed RACE_NAME_LIST; Added PC_RACE_LIST, PC2_RACE_LIST, PC3_RACE_LIST; Added MALE_RACE_LIST, FEMALE_RACE_LIST; Added SEX_NAME_LIST Added STATUS_NAME_LIST; Added EMPIRE_NAME_LIST;
  14. 25/04/2023: Added table_get_count(table). Added is_valid_num_field(num). Added is_valid_table_field(table). Added is_valid_func_field(func). Added time_remaining_until(os.date("%H:%M")).
  15. Yeah, let's make 2 kilos of salad with 5% lettuce, 10% tomatoes, 40% pine nuts, 30% olive oil, 15% balsamic vinegar, in the end it's a lot of food, so I'm sure it'll be good!.. right?
  16. It means when you applied the change you saved the file in the wrong encoding. So now all the LC_TEXT calls are messed up. You need to revert the change and remake it, and save the file with the proper encoding this time.
  17. Nice job. If anybody wants the quest version of a mob_drop_item.txt that's easily customizeable: define TYPE_LIMIT_STATIC 1 define TYPE_LIMIT_DYNAMIC 2 define TYPE_KILL 3 quest drops begin state start begin function GetDropData(vnum) return ({ [8002] = { ["type"] = {TYPE_LIMIT_STATIC, 50}, ["drops"] = { {["vnum"] = 101051, ["quantity"] = 1, ["perc"] = 100}, {["vnum"] = 101001, ["quantity"] = 1, ["perc"] = 100}, {["vnum"] = 71151, ["quantity"] = 5, ["perc"] = 100}, -- more drops here. } }, -- more monsters here. })[vnum] or nil; end -- function when kill with not npc.is_pc() begin local npc_race = npc.get_race(); local drop_data = drops.GetDropData(npc_race); if (drop_data == nil) then return; end -- if local drop_type, drop_type_arg = drop_data["type"][1], drop_data["type"][2]; -- LIMIT_STATIC = Within 15 of a fixed level (defined in the limit's 2nd arg) -- LIMIT_DYNAMIC = Within 15 of target's level. if (drop_type == TYPE_LIMIT_STATIC or drop_type == TYPE_LIMIT_DYNAMIC) then local level_reference = (drop_type == TYPE_LIMIT_STATIC and drop_type_arg or npc.get_level()); if (math.abs(pc.get_level() - level_reference) > 15) then return; end -- if -- KILL = Kill a certain amount of enemies to have a chance to drop. elseif (drop_type == TYPE_KILL) then local qf_name = string.format("drop_%d_count", npc_race); pc.setqf(qf_name, pc.getqf(qf_name)+1); if (math.mod(pc.getqf(qf_name), drop_type_arg) ~= 0) then return; end -- if end -- if/elseif for _, item_data in ipairs(drop_data["drops"]) do if (math.random(100) <= item_data["perc"]) then game.drop_item_with_ownership(item_data["vnum"], item_data["quant"]); --break; -- Uncomment if you want to limit to one drop per monster kill. end -- if end -- for end -- when end -- state end -- quest
  18. 20/03/2023: Added get_random_number_within_except(range_min, range_max, except_table)
  19. The moment you stop spreading misinformation is the moment I stop commenting on your posts, simple as that. I don't talk about performance because performance is irrelevant on Metin2. If you think otherwise you're simply delusional.
  20. This is an example of a bad quest. You're running way more loops than necessary. It won't still lag your server. But for readability and maintenance purposes, I suggest you to let a professional do it for you.
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.