Jump to content

Search the Community

Showing results for tags 'lua'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Metin2 Dev
    • Announcements
  • Community
    • Member Representations
    • Off Topic
  • Miscellaneous
    • Metin2
    • Showcase
    • File Requests
    • Community Support - Questions & Answers
    • Paid Support / Searching / Recruiting
  • Metin2 Development
  • Metin2 Development
    • Basic Tutorials / Beginners
    • Guides & HowTo
    • Binaries
    • Programming & Development
    • Web Development & Scripts / Systems
    • Tools & Programs
    • Maps
    • Quests
    • 3D Models
    • 2D Graphics
    • Operating Systems
    • Miscellaneous
  • Private Servers
    • Private Servers
  • Uncategorized
    • Drafts
    • Trash
    • Archive
    • Temporary
    • Metin2 Download

Product Groups

  • Small Advertisement
  • Large Advertisement
  • Advertising

Categories

  • Third Party - Providers Directory

Categories

  • Feature Plan

Categories

  • Release Notes

Categories

  • Overview
  • Pages
    • Overview
    • File Formats
    • Network
    • Extensions

Calendars

  • Community Calendar

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Pillory


Marketplace


Game Server


Country


Nationality


Github


Gitlab


Discord


Skype


Website

  1. Hello. I saw a similar question earlier on this forum, and since it's not a big task, I quickly made this snippet. It doesn't require much explanation, you can send a whisper message from a guest using a function. Let's see: I. Open the "game/src/questlua_pc.cpp" and you have to look for the following function:: int pc_set_skill_level(lua_State* L) { ... } II. and after that whole function lines add the following function lines: int pc_send_whisper(lua_State* L) { LPCHARACTER lpCH = CQuestManager::instance().GetCurrentCharacterPtr(); int iArgIndex = 1; const char * c_szSenderName = "System"; if (lua_gettop(L) > 1) { if(!lua_isstring(L, iArgIndex)) { sys_err("QUEST : wrong argument"); lua_pushboolean(L, false); return 1; } c_szSenderName = lua_tostring(L, iArgIndex); if (strlen(c_szSenderName) == 0) { sys_err("QUEST : empty argument"); lua_pushboolean(L, false); return 1; } iArgIndex++; } if (!lua_isstring(L, iArgIndex)) { sys_err("QUEST : wrong argument"); lua_pushboolean(L, false); return 1; } const char * c_szMessage = lua_tostring(L, iArgIndex); const size_t c_size = (c_szMessage) ? strlen(c_szMessage) : 0; if (c_size == 0) { sys_err("QUEST : empty argument"); lua_pushboolean(L, false); return 1; } LPDESC lpDesc; if (!(lpDesc = lpCH->GetDesc())) { lua_pushboolean(L, false); return 1; } TPacketGCWhisper lPack; lPack.bHeader = HEADER_GC_WHISPER; lPack.wSize = sizeof(TPacketGCWhisper) + c_size; lPack.bType = WHISPER_TYPE_NORMAL; strlcpy(lPack.szNameFrom, c_szSenderName, sizeof(lPack.szNameFrom)); TEMP_BUFFER lTmpBuf; lTmpBuf.write(&lPack, sizeof(lPack)); lTmpBuf.write(c_szMessage, c_size); lpDesc->Packet(lTmpBuf.read_peek(), lTmpBuf.size()); lua_pushboolean(L, true); return 1; } III. and now, look for the following line in the "RegisterPCFunctionTable" function: { "set_skill_level", pc_set_skill_level }, IV. and before that line add the following line: { "send_whisper", pc_send_whisper }, We are done now ! Important: You have to check your own whisper packet structure, because mine and yours can be different maybe. Don't forget to add this new quest function name to the quest function list file! (If you have one, that is.) - pc.send_whisper Usage example: (The default whisper target is always the current selected player by the quest system.) -- To send message by default sender name as "System": pc.send_whisper("Hi there! :)") -- To send message by a given sender name: pc.send_whisper("Biologist", "Biolog cooldown is done, you can submit next item.") -- To check the success of send: if pc.send_whisper("Hi there! :)") then -- The whisper message has been sent successfully. else -- Failed to send the whisper message. end
  2. Hi guys. This is my goodbye, I had 10 years working for Metin2 but in the last days I finished my all contracts with Metin2. New year, new projects. I hope you continue to improve your codes. I give special thanks for my unic friend on Metin2 "Capone" because he was the one who showed me that true friendship exists. I know that Metin2 has nice people "Community Developers" and Big Developers: VegaS and Mali, you don't know about me, but I observed your works and is very cool. I wish you a beautiful new Year and good luck in your future projects. I leave with my last contribution "GIFT" for the community. Basic Dungeons: [C++] Nemere and Flame Dungeon like Official servers: Dungeons with Conqueror of Yohara stats: [C++] White Dragon [C++] Queen Nethis NOTE: If I forgot visuals parts, you can extract from the official client. Maybe I will have connections in the forum but just of curiosity. I love you guys, I hope you are very well with my gifts. Good bye.
  3. M2 Download Center Download Here ( Internal ) [Hidden Content] Client side is from 2018 official root. Mount transmutation 2018 didn't exist in root, I made minor edits. However, to use mount transmutation, you need to edit it according to your own mount system. I created a new slot effect so that it doesn't interfere with other systems (highlight) etc. You can use this sloteffect and the diffusecolor function elsewhere. ***Add this before adding this system:
  4. M2 Download Center Download Here ( Internal ) [Hidden Content] Video: Images: Client Side is from 2018 official root. Of course I've made minor changes for slot marking and cheque(if app. checks) You have to add slot marking too. Mysql used to retrieve data during game launch, and to backup(default 1 hour, you can change at conf.txt)
  5. M2 Download Center Download Here ( Internal ) Since i always get help from vegas and others, i wanted to give back something, maybe it helps someone. Here i have a system which is shared by a friend of another board, i made it like official and fixed the bugs. Download: [Hidden Content] Virustotal: [Hidden Content]
  6. M2 Download Center Download Here ( Internal ) [Hidden Content]- Images & Video: Some Informations From Black: If you have a problem, you can send me a private message. You know me, I reply to all private messages
  7. Hi This feature allows you to make an arena with a player from the target, not just from the NPC. The position of where they start the battle is also saved so that they return to the same place and not always next to Yu-Hwan. The code communicates quest/lua with client (python), and server (C++) with quest. GIF: [Hidden Content] Feature created by Camilo (caanmasu) [Hidden Content] This feature allows you to make an arena with a player from the target, not just from the NPC. The position of where they start the battle is also saved so that they return to the same place and not always next to Yu-Hwan. The code communicates quest/lua with Python, and server (C++) with quest. Clientside root: constinfo.py ENABLE_ARENA_MANAGER_TARGET = True if ENABLE_ARENA_MANAGER_TARGET: QUEST_arena_manager_INDEX = 0 QUEST_arena_manager_TARGET = 0 game.py 1: Above: self.serverCommander=stringCommander.Analyzer() Add: if constInfo.ENABLE_ARENA_MANAGER_TARGET: serverCommandList.update({"StartArenaManager" : self.QUEST_arena_manager}) serverCommandList.update({"GetTargetArenaManager" : self.QUEST_get_target_arena_manager}) 2: Add this functions: if constInfo.ENABLE_ARENA_MANAGER_TARGET: def QUEST_arena_manager(self, quest_index): constInfo.QUEST_arena_manager_INDEX = quest_index def QUEST_get_target_arena_manager(self): net.SendQuestInputStringPacket(str(constInfo.QUEST_arena_manager_TARGET)) uitarget.py 1: import event 2: Above: GRADE_NAME = { Add: if constInfo.ENABLE_ARENA_MANAGER_TARGET: BUTTON_NAME_LIST.append(localeInfo.TARGET_BUTTON_ARENA_MANAGER) 3: Above: self.buttonDict["VOTE_BLOCK_CHAT"].SetEvent(ui.__mem_func__(self.__OnVoteBlockChat)) Add: if constInfo.ENABLE_ARENA_MANAGER_TARGET: self.buttonDict[localeInfo.TARGET_BUTTON_ARENA_MANAGER].SAFE_SetEvent(self.__OnArena) 4: Above: if player.IsPartyMember(self.vid): Add: if constInfo.ENABLE_ARENA_MANAGER_TARGET: if player.GetStatus(player.LEVEL) >= constInfo.PVPMODE_PROTECTED_LEVEL: self.__ShowButton(localeInfo.TARGET_BUTTON_ARENA_MANAGER) 5: Add this function: if constInfo.ENABLE_ARENA_MANAGER_TARGET: def __OnArena(self): constInfo.QUEST_arena_manager_TARGET = chr.GetNameByVID(self.vid) event.QuestButtonClick(int(constInfo.QUEST_arena_manager_INDEX)) locale_game.txt TARGET_BUTTON_ARENA_MANAGER Arena If you do not have input ignore, then do it: constinfo.py Add anywhere: INPUT_IGNORE = 0 game.py 1: Find this function: def OpenQuestWindow(self, skin, idx): self.interface.OpenQuestWindow(skin, idx) Replace for: def OpenQuestWindow(self, skin, idx): if constInfo.INPUT_IGNORE == 1: return else: self.interface.OpenQuestWindow(skin, idx) 2: Below of: # PRIVATE_SHOP_PRICE_LIST "MyShopPriceList" : self.__PrivateShop_PriceList, # END_OF_PRIVATE_SHOP_PRICE_LIST Add: "quest_input_ignore" : self.questInputIgnore, Add this function: def questInputIgnore(self, var): constInfo.INPUT_IGNORE = int(var) interfacemondule.py Find: def OpenQuestWindow(self, skin, idx): wnds = () Replace for: def OpenQuestWindow(self, skin, idx): if constInfo.INPUT_IGNORE == 1: return else: wnds = () Quest: arena_manager.cpp 1: Add those when: when login begin cmdchat(string.format("StartArenaManager %s", q.currentquestindex())) end when logout begin -- if pc.get_map_index() == 112 then pc.delqf("saved_x") pc.delqf("saved_y") end end when button begin --clientside related cmdchat("quest_input_ignore 1") --Note: If you set my input_ignore then this is correct. If you already had your own input_ignore, put the correct command. local victim_name = input(cmdchat("GetTargetArenaManager")) cmdchat("quest_input_ignore 0") -- if game.get_event_flag("arena_close") > 0 then say(gameforge.arena_manager._30_say) --token 42 return end local useMinLevel = game.get_event_flag("arena_use_min_level") if useMinLevel == 0 then useMinLevel = 25 ; end if pc.get_level() < useMinLevel then say(string.format(gameforge.arena_manager._50_say, useMinLevel)) --token 44 return else local sname = victim_name local opp_vid = find_pc_by_name(sname) local old = pc.select(opp_vid , opp_vid) local opp_level = pc.level -- Save the position (opponent) from where the arena was started pc.setf("arena_manager", "saved_x", pc.x) --BUG FIXED: si no se especifica el nombre de la quest, se tomará la quest del id anterior (la quest que se compiló antes de ésta en el quest_list) pc.setf("arena_manager", "saved_y", pc.y) -- pc.select(old, old) if opp_level < useMinLevel then say(string.format(gameforge.arena_manager._110_say, useMinLevel)) --token 28 return end local a = arena.is_in_arena(opp_vid) if a == 0 then say_reward(string.format(gameforge.arena_manager._130_say, sname)) --token 30 return end chat(string.format(gameforge.arena_manager._85_say, pc.name, sname)) --token 48 local agree = confirm(opp_vid, string.format(gameforge.arena_manager._87_say, sname, pc.name), 30) --token 49 (text very long) if agree!= CONFIRM_OK then say(string.format(gameforge.arena_manager._150_say, sname)) --token 32 return end -- Save the position (current player) from where the arena was started pc.setqf("saved_x", pc.x) -- pc.setqf("saved_y", pc.y) -- local s = arena.start_duel(sname, 3) if s == 0 then say(gameforge.arena_manager._160_say) --token 33 elseif s == 2 then say(gameforge.arena_manager._170_say) --token 34 elseif s == 3 then say(gameforge.arena_manager._180_say) --token 35 end end end 2: Find: if table.getn(arena_observer) >= s then Add: -- Save the position (observer player) from where the arena was started pc.setqf("saved_x", pc.x) -- pc.setqf("saved_y", pc.y) -- Serverside arena.cpp 1. Find: LPCHARACTER playerB = GetPlayerB(); Add: quest::PC* pPC_A = quest::CQuestManager::instance().GetPC(playerA->GetPlayerID()); quest::PC* pPC_B = quest::CQuestManager::instance().GetPC(playerB->GetPlayerID()); int saved_A_x = pPC_A->GetFlag("arena_manager.saved_x"); int saved_A_y = pPC_A->GetFlag("arena_manager.saved_y"); int saved_B_x = pPC_B->GetFlag("arena_manager.saved_x"); int saved_B_y = pPC_B->GetFlag("arena_manager.saved_y"); 2: Find: playerA->WarpSet(ARENA_RETURN_POINT_X(playerA->GetEmpire()), ARENA_RETURN_POINT_Y(playerA->GetEmpire())); Replace for: if (saved_A_x != 0 && saved_A_y != 0) playerA->WarpSet(saved_A_x*100, saved_A_y*100); else playerA->WarpSet(ARENA_RETURN_POINT_X(playerA->GetEmpire()), ARENA_RETURN_POINT_Y(playerA->GetEmpire())); 3: Find: playerB->WarpSet(ARENA_RETURN_POINT_X(playerB->GetEmpire()), ARENA_RETURN_POINT_Y(playerB->GetEmpire())); Replace for: if (saved_B_x != 0 && saved_B_y != 0) playerB->WarpSet(saved_B_x*100, saved_B_y*100); else playerB->WarpSet(ARENA_RETURN_POINT_X(playerB->GetEmpire()), ARENA_RETURN_POINT_Y(playerB->GetEmpire())); 4: Find: LPCHARACTER pChar = CHARACTER_MANAGER::instance().FindByPID(iter->first); if (pChar != NULL) { pChar->WarpSet(ARENA_RETURN_POINT_X(pChar->GetEmpire()), ARENA_RETURN_POINT_Y(pChar->GetEmpire())); } Replace for: LPCHARACTER pChar = CHARACTER_MANAGER::instance().FindByPID(iter->first); if (pChar != NULL) { quest::PC* pPC = quest::CQuestManager::instance().GetPC(pChar->GetPlayerID()); int saved_x = pPC->GetFlag("arena_manager.saved_x"); int saved_y = pPC->GetFlag("arena_manager.saved_y"); if (saved_x != 0 && saved_y != 0) pChar->WarpSet(saved_x*100, saved_y*100); else pChar->WarpSet(ARENA_RETURN_POINT_X(pChar->GetEmpire()), ARENA_RETURN_POINT_Y(pChar->GetEmpire())); } Regards.
  8. M2 Download Center Download Here ( Internal ) Download Here ( GitHub )
  9. Hello, This tutorial will show you how to create a shop with an NPC. There are two types of shops: One shop: When you click on a NPC, a shop window opens. The first part will be enough for you to create a simple shop. Multi shop: Which consists of assigning several shops to an NPC using a quest. Prerequisites Own a Metin2 server with access to the database. Have an NPC available. Set up a quest. I. Create a shop or modify a shop II. Multi Shop Sincerly, ASIKOO
  10. M2 Download Center Download Here ( Internal ) Hello guys.. So much people got problem with this system then i do FULL TuT exclusive for metin2dev All is tested and all works TuT included in all FILES.. New Link: Pass: When you find some bug post it here.. I will try to fix it.. Have Fun //EnZi EDITED: #New Link UPDATE cmd_general.cpp - Added some new code char_battle.cpp - Added some new code ProtoReader.cpp - Added some new code questlua_pc - Repaired code item_proto - Query for navicat Quest added UP LINK UPDATED fixed quest: [Hidden Content]
  11. Some of the quests used in OLDSGODSMT2
  12. (This topic addresses to the most common crashes that occur using server_timers in dungeons) In this short tutorial i'm gonna explain why are the crashes happening and how we can deal with them along with a use case of this. The difference between the Normal Timers and Server Timers Normal Timers: - Directly tied to a character pointer. - Timer execution halts if the associated character logs out. - Implicitly dependent on the character's in-game presence. Server Timers: - Operate independently of character pointers. - Continue to execute even if the initiating character exits the game. - Offers persistent timing functionalities. You might ponder on the need for server timers, especially when normal timers are present. Here's why: 1. Party Dynamics: In a multiplayer setting, if a party member possessing the timer logs out, gameplay can be disrupted, leading to a halted dungeon instance. Server timers mitigate this risk. 2. Dungeon Persistence: Players often exit and re-enter dungeons. With a normal timer, exiting erases the timer, jeopardizing the dungeon's progression. Server timers ensure continuity. Why do crashes occur? Server timers, by virtue of their independence, lack character pointers upon invocation. This absence becomes problematic when: Distributing or dropping items. Executing specific chats or commands. Running functions reliant on character pointers. The game struggles to reference a non-existent character, which can either lead to functional anomalies or outright crashes. How can we solve the problem? My way of solving this issue is simple. I've created a global function that when called is selecting the character pointer of the specified PID and returns a boolean of whether it selected it or not. // questlua_global.cpp int _select_pid(lua_State* L) { DWORD dwPID = static_cast<DWORD>(lua_tonumber(L, 1)); quest::PC* pPC = CQuestManager::instance().GetPC(dwPID); if(pPC) { LPCHARACTER lpSelectedChar = CQuestManager::instance().GetCurrentCharacterPtr(); lua_pushboolean(L, (lpSelectedChar ? 1 : 0)); return 1; } lua_pushboolean(L, false); return 1; } { "select_pid", _select_pid }, Now we set the leaderPID as a dungeon flag upon entering the instance for the first time. (if it's not a group, it will set the pid of the player that entered) when login with <PC_IN_DUNGEON> begin if (((party.is_party() and party.is_leader()) or not party.is_party()) and d.getf("leaderPID") < 1) then d.setf("leaderPID", pc.get_player_id()) end end Now when we call the server_timer, we first select the leader and check if we succeeded or not. when give_item.server_timer begin if (d.select(get_server_timer_arg())) then if (select_pid(d.getf("leaderPID"))) then pc.give_item2(19, 1) else -- handle what happends if the selection was unsuccessful end end end That's basically it. You can now call any function in server_timer. How can this get very useful? Let's say we want to create an update timer that constantly updates different information on players client. I've made a function that is pushing each dungeon's member PID. (only if it's in dungeon) #include <functional> struct FDungeonPIDCollector { std::vector<DWORD> vecPIDs; void operator () (LPCHARACTER ch) { if (ch) vecPIDs.push_back(ch->GetPlayerID()); } }; int dungeon_get_member_pids(lua_State* L) { LPDUNGEON pDungeon = CQuestManager::instance().GetCurrentDungeon(); if (!pDungeon) return 0; FDungeonPIDCollector collector; pDungeon->ForEachMember(std::ref(collector)); for (const auto& pid : collector.vecPIDs) { lua_pushnumber(L, pid); } return collector.vecPIDs.size(); } { "get_member_pids", dungeon_get_member_pids }, Using this, we can just update each dungeon's member informations: when dungeon_update_info.server_timer begin if (d.select(get_server_timer_arg())) then local dungeonMemberIds = {d.get_member_pids()}; for index, value in ipairs(dungeonMemberIds) do if (select_pid(value)) then cmdchat(string.format("UpdateDungeonInformation %d %d", 1, 2)) -- pc.update_dungeon_info() else -- handle the negative outcome end end end end
  13. Hi, [Hidden Content] [Hidden Content] This quest is responsible for granting basic costumes to players when they reach certain levels in the game. The quest is triggered when a player logs in or levels up in the game. It checks the player's level and grants various cosmetic items if certain conditions are met. Basic Costume: Players receive a basic costume based on their gender. Basic Hairstyle: Players receive a basic hairstyle and an additional cosmetic item. Basic Pet: Players receive a basic pet at a certain level. Basic Weapon: Players receive a basic weapon based on their class. Basic Mount: Players receive a basic mount at a certain level.
  14. Download Alternative download links → Github Hi, This is all interface about SungmaHee Tower Like official servers and the first floor like Official Servers, In this files we have 2k or 3k LOC, maybe more, I'm tired and I don't have information about all floor's tower, but if you want complete this system, you can contact with some-developer and providing the information about the floors or modifying all floors like your concept for Metin2, you'll be a nice dungeon. I already did the hardest part. You can extract all visual part with the official patchs from this forum. This dungeon is Full C++, Python and SQL. PLEASE: Not more messages for my person if you don't want to pay money, I only sell systems "not personal systems" you need understand about my time, my help, code or resolve some problem, needs time. If you want something (not offlineshop, this world has different options with this system) you can contact me but, you will need understand that I will charge you. I'm a nice person (I think), but this world needs money and if I invest time in one project, I will cancel other projects and is overmoney.
  15. Hi, I've made a quest for the apprentice quest and I thought I'd leave it here because from what I've seen there are some pretty ugly quests. I'm attaching a model for a chest. Continue with what you want. [Hidden Content] quest apprentice_chest begin state start begin when 50187.use with pc.get_level() >= 1 begin if pc.get_empty_inventory_count() <= 9 then syschat("Your inventory is too full to open the chest.") return end if pc.getqf("apprentice_chest_lv1") == 1 then syschat("You have already opened a chest on this account.") return end local items = {{50188, 1}, {71027, 5}, {71028, 5}, {71029, 5}, {71030, 5}, {71044, 5}, {71045, 5}, {27102, 200}, {27105, 200} } for _, item in ipairs(items) do pc.give_item2(item[1], item[2]) end pc.remove_item(50187, 1) pc.setqf("apprentice_chest_lv1", 1) end end end
  16. M2 Download Center Download Here ( Internal ) Hi there Devs, I would like to share my "little" system. If you aren't interested in the introduction/preview etc. and you just want to download it and put in to your server, just scroll down until the "[How-To] Set up" subtitle. The story Firstly let me tell this system's story. I've got an idea one year before, that it would be good if the players would be able to put their items into a "global" system where they could see the other player's items, and they could buy it for DC or gold (that time I worked with the latest vanilla core (not with the source)). Then in the following 8 days I made it (it took about 80-90 working hours). Originally the system was created for one of my friend's server. but this server has never started, and nobody used this system. After some mounts I've decided to publish it on the Hungarian forum, because it won't worth to work on it for long hours if nobody uses it and its just collecting dust on my computer. Then I've published it on the 2nd of December, 2014. After some time I've decided to translate it into English and I've got a new idea for a new feature. This feature was: the trade system (I will explain its working later). This idea inspired by one of the players (from a server where this system was able to use). He told me that it would be better if they could set the gold price via an item (what's value is very high). Then with more than 180 working hours (totally) behind my back I'm here. Overview [How-To] Set up Customizing the tradehouse Questions and Answers Notes changelog: 19th of August, 2015: I publicated the tradehouse here. my toDo list: add logging for the system (the released version don't log the actions in the tradehouse) Thanks for reading the topic, if you have any problem/remark feel free to ask it here or write me a PM. Have a good day!
  17. Hello Metin2 Dev Community. I'm here to present a function to check and return the monster rank. I'm creating my biolog that's why i had to create this function, i know there are other ways to do this but i decided to do it this way. I'm sharing in case someone needs. With best regards, Doose.
  18. Download GitHub Repository Temporarily boosts the character's physical attack and / or skill damage. You can learn more about the system from the official wiki page. Thanks to @blackdragonx61 for the reversed effect position.
  19. M2 Download Center Download Here ( Internal ) Since some piece of shit ''developer'' decided that it's ok to resell my system, here you go. [Hidden Content] have fun.
  20. M2 Download Center Download Here ( Advance Refine Systems ) Download Here ( Cheque System ) Download Here ( Soul Bind System ) Hello everyone ! I've been away from metin2 for about 6 months and i've get back from less then a month and made thoes systems , i've start selling them but i didn't sell it to anyone and i got bored from metin2 again so i'm going to release it and go off from metin2 for ever . about the Advance Refine System here some info: so download and have fun [Hidden Content]
  21. M2 Download Center Download Here ( Internal ) Download
  22. Sharing a simple timer quest that send a notice_all when a preferred mob dies NOTE : This code will not work for really long respawn times NOTE : This code will not work for really long respawn times quest bosskillred begin state start begin when 2291.kill begin timer("spawn", 250) notice_all("Red Dragon has been killed") notice_all("Will be spawned again in 4 hours") end when spawn.timer begin notice_all("Red Dragon Spawned.") end end end Changing .kill with preferred mob Vnum & 250 is how many seconds to set the timer for the next notice. In case i scripted something wrong feel free to correct me
  23. Download [Hidden Content] Hello Metin2 Dev. I'm here to share 2 of my hunting missions. How do they work? The player receive a scroll with the mission details. It will give the player 2 options. After complete the mission, the player receives his reward. The second mission only appears after concluding the first one. It will show on mission panel how many left is there to kill. As always is a pleasure to work with this community. Any error or problem, text here or contact me in private. With best Regards, Doose.
  24. Hello I have reworked the get function calls without parameters. I mean when you use pc.empire instead of pc.get_empire() This time I have extended to more features and added the quest features. Tested in Marty Sama. Explanation: To add more functions you must know which ones. Functions must return a value and must not receive any parameters. pc.get_empire() is very simple, it returns a number and no parameter is sent. Its "alias" would be pc.empire or whatever name best suits it. item.get_value() does not work. Its alias would be item.value but the server will not know which value it refers to, since it needs to specify the index of that value. This structure does not work if the function requires parameters. When you need to use q.getcurrentquestindex(), you just put q.index. Now it's simpler. Steps: questlib.lua. Remove this code: Remove: npc_index_table = { ['race'] = npc.getrace, ['empire'] = npc.get_empire, } pc_index_table = { ['weapon'] = pc.getweapon, ['level'] = pc.get_level, ['hp'] = pc.gethp, ['maxhp'] = pc.getmaxhp, ['sp'] = pc.getsp, ['maxsp'] = pc.getmaxsp, ['exp'] = pc.get_exp, ['nextexp'] = pc.get_next_exp, ['job'] = pc.get_job, ['money'] = pc.getmoney, ['gold'] = pc.getmoney, ['name'] = pc.getname, ['playtime'] = pc.getplaytime, ['leadership'] = pc.getleadership, ['empire'] = pc.getempire, ['skillgroup'] = pc.get_skill_group, ['x'] = pc.getx, ['y'] = pc.gety, ['local_x'] = pc.get_local_x, ['local_y'] = pc.get_local_y, } item_index_table = { ['vnum'] = item.get_vnum, ['name'] = item.get_name, ['size'] = item.get_size, ['count'] = item.get_count, ['type'] = item.get_type, ['sub_type'] = item.get_sub_type, ['refine_vnum'] = item.get_refine_vnum, ['level'] = item.get_level, } function npc_index(t,i) local npit = npc_index_table if npit[i] then return npit[i]() else return rawget(t,i) end end function pc_index(t,i) local pit = pc_index_table if pit[i] then return pit[i]() else return rawget(t,i) end end function item_index(t, i) local iit = item_index_table if iit[i] then return iit[i]() else return rawget(t, i) end end setmetatable(pc,{__index=pc_index}) setmetatable(npc,{__index=npc_index}) setmetatable(item,{__index=item_index}) Add this code: index_tables = { pc = { ['weapon'] = pc.getweapon, ['level'] = pc.get_level, ['hp'] = pc.gethp, ['maxhp'] = pc.getmaxhp, ['sp'] = pc.getsp, ['maxsp'] = pc.getmaxsp, ['exp'] = pc.get_exp, ['nextexp'] = pc.get_next_exp, ['job'] = pc.get_job, ['money'] = pc.getmoney, ['gold'] = pc.getmoney, ['name'] = pc.getname, ['playtime'] = pc.getplaytime, ['leadership'] = pc.getleadership, ['empire'] = pc.getempire, ['skillgroup'] = pc.get_skill_group, ['x'] = pc.getx, ['y'] = pc.gety, ['local_x'] = pc.get_local_x, ['local_y'] = pc.get_local_y, ['mapindex'] = pc.get_map_index, ['guild'] = pc.get_guild, ['sex'] = pc.get_sex, ['gmlevel'] = pc.get_gm_level, ['ip'] = pc.get_ip0, ['hwid'] = pc.get_hwid, }, npc = { ['race'] = npc.getrace, ['empire'] = npc.get_empire, ['vid'] = npc.get_vid, ['level'] = npc.get_level0, ['name'] = npc.get_name0, ['pid'] = npc.get_pid0, ['type'] = npc.get_type0, ['hwid'] = npc.get_hwid, }, item = { ['id'] = item.get_id, ['cell'] = item.get_cell, ['vnum'] = item.get_vnum, ['name'] = item.get_name, ['size'] = item.get_size, ['count'] = item.get_count, ['type'] = item.get_type, ['sub_type'] = item.get_sub_type, ['refine_vnum'] = item.get_refine_vnum, ['level'] = item.get_level, ['levellimit'] = item.get_level_limit, ['wearflag'] = item.get_wearflag0, ['antiflag'] = item.get_antiflag0, ['immuneflag'] = item.get_immuneflag0, }, q = { ['index'] = q.getcurrentquestindex, ['name'] = q.getcurrentquestname, } --add your new space } function generic_index(t, i) local it = index_tables[t] return it[i] and it[i]() or rawget(t, i) end setmetatable(pc, { __index = function(t, i) return generic_index("pc", i) end }) setmetatable(npc, { __index = function(t, i) return generic_index("npc", i) end }) setmetatable(item, { __index = function(t, i) return generic_index("item", i) end }) setmetatable(q, { __index = function(t, i) return generic_index("q", i) end }) --quest --add your new space
×
×
  • 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.