-
Posts
656 -
Joined
-
Last visited
-
Days Won
187 -
Feedback
100%
Content Type
Forums
Store
Third Party - Providers Directory
Feature Plan
Release Notes
Docs
Events
Posts posted by VegaS™
-
-
I don't understand very well what you want, but you can try something like this.
static const DWORD COSTUME_EXTEND_TIME_LIMIT = 7 * 24 * 60 * 60; const DWORD remain_sec = item2->GetSocket(ITEM_SOCKET_REMAIN_SEC); if (remain_sec >= COSTUME_EXTEND_TIME_LIMIT) { ChatPacket(CHAT_TYPE_INFO, "COSTUME_EXTEND_TIME_LIMIT"); return false; }
- 3
-
-
On 11/3/2019 at 11:13 PM, Syriza said:
i hope I get some help @Syriza
slotIndex = Your index position from inventory.
Python
import player attrCount = 0 for i in xrange(player.ATTRIBUTE_SLOT_MAX_NUM): if player.GetItemAttribute(player.INVENTORY, slotIndex, i): attrCount += 1 print(attrCount)
C++
- 17
- 3
- 8
-
M2 Download Center
( Internal )
( GitHub )
Hello cowboys, since i was at job and i was bored while coding in other languages, i thought would be funny if i code something in Python, so an idea came in mind, doing a general text file loader for parsing different data, with different structs, normal variables, groups and lists, like ymir idea for parsing the files (.mse, .msa, .msm, .txt like mob_drop_item.txt, group.txt, etc)
This tool can be used everywhere, for metin2 or else, i wrote this from scratch using ymir idea, also you can run it in any version of Python.
If you use this for metin2, change USING_METIN2_CLIENT to True.SpoilerANDROID_LINK http://www.antutu.com/en/ranking/rank1.htm IOS_LINK http://www.antutu.com/en/ranking/ios1.htm DOWNLOAD_LINK http://www.antutu.com/en/download.htm Group Antutu_Benchmark_Android { LAST_UPDATED "September 2019" Group Device00 { NAME "ROG Phone 2" RAM_AND_STORAGE "8GB+128GB" CPU 127580 UX 81187 3D 173673 TOTAL_SCORE 396200 } Group Device01 { NAME "Asus ZenFone 6 2019" RAM_AND_STORAGE "6GB+128GB" CPU 115926 UX 72764 3D 175221 TOTAL_SCORE 377199 } Group Device02 { NAME "OnePlus 7 Pro" RAM_AND_STORAGE "8GB+256GB" CPU 122874 UX 77862 3D 157802 TOTAL_SCORE 373097 } }
Full source repository:
- 48
- 1
- 1
- 8
- 3
- 34
-
On 10/15/2019 at 1:30 PM, Mali61 said:
PythonPlayer.cpp:
bool CPythonPlayer::_IsDSPageFull(BYTE page) { if (page < 0 || page >= DS_DECK_MAX_NUM) return false; DWORD count = 0; DWORD startsize = c_DragonSoul_Equip_Start + c_DragonSoul_Equip_Slot_Max * page; const DWORD endsize = c_DragonSoul_Equip_Start + c_DragonSoul_Equip_Slot_Max * (page + 1); for (; startsize < endsize; ++startsize) if (GetItemIndex(TItemPos(INVENTORY, startsize))) count++; return count == c_DragonSoul_Equip_Slot_Max; }
@Mali61 Good idea, but what i did doesn't work like this.
You've to check each dragon soul from all pages if they aren't expired and the specific page is activated too.
- 21
- 5
- 13
-
You guys should pay a video editor for the trailer, we're in 2019 and the trailer looks like in 2009..
Good luck with it.- 2
-
I don't like so much Lua, but i did something fast, i hope that's what you wanted.
Replace npc.get_level() with npc.get_level0() if you use marty source.quest common_drop_quest begin state start begin function CanDrop(pc_level, npc_level, isPC) local DIFF_LEVEL_CONST = 10 return not isPC and math.abs(pc_level - npc_level) <= DIFF_LEVEL_CONST end function GetSettings() local PLAYER_MAX_LEVEL_CONST = 105 return { { 20, 40, {27001, 27001, 27001, 27001, 27001, 27001} }, -- from 20 to 39 { 40, 60, {27002, 27002, 27002, 27002, 27002, 27002} }, -- from 40 to 59 { 60, 80, {27003, 27003, 27003, 27003, 27003, 27003} }, -- from 60 to 79 { 80, 100, {27004, 27004, 27004, 27004, 27004, 27004} }, -- from 80 to 99 { 100, PLAYER_MAX_LEVEL_CONST + 1, {27005, 27005, 27005, 27005, 27005, 27005} }, -- from 100 to PLAYER_MAX_LEVEL_CONST } end when kill with common_drop_quest.CanDrop(pc.get_level(), npc.get_level(), npc.is_pc()) begin local common_drop_table = common_drop_quest.GetSettings() for i = 1, table.getn(common_drop_table) do local dropLevelMin, dropLevelMax, dropItemTable = unpack(common_drop_table[i]) local dropItemVnum = dropItemTable[number(1, table.getn(dropItemTable))] if pc.get_level() >= dropLevelMin and pc.get_level() < dropLevelMax then if number(1, 10000) <= 100 then game.drop_item_with_ownership(dropItemVnum) break end end end end end end
- 5
-
-
On 10/12/2019 at 10:04 PM, ALmutiri said:
2- how to make the time format 12 h with am and pm
@VegaS™- 1
- 2
- 3
-
42 minutes ago, ManiacRobert said:
I think it's needed to send via packet or cmdchat get_global_time() from server-side
Already app.GetGlobalTimeStamp() (#1 #2) doing that, returns the server timestamp (sent by TPacketGCTime to client) on each enter in game, you just need to convert the timestamp with a proper method.
cur_time_stamp = app.GetGlobalTimeStamp() seconds = cur_time_stamp % 60 minutes = (cur_time_stamp / 60) % 60 hours = (cur_time_stamp / 60) / 60 % 24 self.textLine.SetText("%02i:%02i:%02i" % (hours, minutes, seconds))
- 1
- 1
- 7
-
5 minutes ago, xP3NG3Rx said:
Why do you needed this?
I posted the code some months ago and i thought is fine to be here too, not just in category of q&a.
- 3
-
- Server\src\game\src\DragonSoul.h
Spoiler//1.1) Search for: bool DragonSoulItemInitialize(LPITEM pItem); //1.2) Add after: bool HasActivedAllSlotsByPage(const LPCHARACTER ch, const BYTE bPageIndex = DRAGON_SOUL_DECK_0) const;
- Server\src\game\src\DragonSoul.cpp
Spoiler//1.1) Search for: BYTE GetStrengthIdx(DWORD dwVnum) { return (dwVnum / 10) % 10; } //1.2) Add after: bool DSManager::HasActivedAllSlotsByPage(const LPCHARACTER ch, const uint8_t bPageIndex) const { if (!ch || bPageIndex >= DRAGON_SOUL_DECK_MAX_NUM) return false; const uint16_t iDragonSoulDeckAffectType = AFFECT_DRAGON_SOUL_DECK_0 + bPageIndex; // 540 + [0 or 1] if (!ch->FindAffect(iDragonSoulDeckAffectType)) return false; // start : 32 + ([0 or 1] * 6) = [32 or 38] // end : start + 6 const uint8_t iStartIndex = WEAR_MAX_NUM + (bPageIndex * DS_SLOT_MAX); const uint8_t iEndIndex = iStartIndex + DS_SLOT_MAX; uint8_t bSlotActive = 0; for (uint8_t bCell = iStartIndex; bCell < iEndIndex; ++bCell) // {0: 32-38, 1: 38-44} { const LPITEM pkItem = ch->GetWear(bCell); if (pkItem && pkItem->IsDragonSoul()) { if (IsTimeLeftDragonSoul(pkItem) && IsActiveDragonSoul(pkItem)) ++bSlotActive; } } return (bSlotActive == DS_SLOT_MAX); }
- How-To-How-To-How-To-Use-Ex:
- 30
- 7
- 27
-
That's what he requested in private, if someone need it, those are not my calculations/code.
void CItemAddonManager::ApplyAddonTo(int iAddonType, LPITEM pItem) { if (!pItem) { sys_err("ITEM pointer null"); return; } bool bCustomizedAddon = false; switch (pItem->GetVnum()) { case 1129: case 2129: case 3129: case 5129: bCustomizedAddon = true; break; } int iSkillBonus = MINMAX(-30, static_cast<int>(gauss_random(0, 5) + 0.5f), 30); int iNormalHitBonus = 0; if (bCustomizedAddon) { if (abs(iSkillBonus) <= 0) iNormalHitBonus = (-1 * iSkillBonus) / 2 + abs(number(-2, 2) + number(-2, 2)) + number(1, 2); else iNormalHitBonus = (-1 * iSkillBonus) / 2 + abs(number(-3, 6)); if (abs(iSkillBonus) <= 0) iSkillBonus = (1 * iSkillBonus) / 2 + abs(number(-1, 1) + number(-1, 1)) + number(1, 2); else iSkillBonus = (1 * iSkillBonus) / 2 + abs(number(-3, 1)); } else { if (abs(iSkillBonus) <= 20) iNormalHitBonus = -2 * iSkillBonus + abs(number(-8, 8) + number(-8, 8)) + number(1, 4); else iNormalHitBonus = -2 * iSkillBonus + number(1, 5); } pItem->RemoveAttributeType(APPLY_SKILL_DAMAGE_BONUS); pItem->RemoveAttributeType(APPLY_NORMAL_HIT_DAMAGE_BONUS); pItem->AddAttribute(APPLY_NORMAL_HIT_DAMAGE_BONUS, iNormalHitBonus); pItem->AddAttribute(APPLY_SKILL_DAMAGE_BONUS, iSkillBonus); }
- 4
-
V1
- You can use unlimited arguments on functions, now is using the apply method which returns the result of a function or class object called with supplied arguments, with the old structure you could use just one argument.
- You can lock/unlock an event for being processed, it's like a prevent in some actions, if the event is created and you want to do something, you should lock the event, do some actions then you can unlock it again and the process function will run where remained.
- Delete an event instantly and force it to stop the process.
- Adding return t.EXIT inside of the running function, will delete the event too.
- Functions to check if an event exists or is locked or not.
- Check if the function is a method type.
- Delete the events with a properly method.
- Using app.GetGlobalTimeStamp() now will give you the chance to run the event after teleport where timer remained instantly.
V2
- Fixed non-returning time for processing, if the specific event function has no value from returning, it runs continuously.
- Fixed the check if an event exist, now will be replaced with the new one.
- Removed library (i heard that some people don't have it) and using builtin functions, instead of types.MethodType now we're using callable(object), which check if the event function can be called, now you can insert classes and others callable methods, not just simple functions.
- Added a reset time event function.
Next update: (when i'll have some free time again)
- Insert a new type of event, which you can run an event by specific counter like:
t.AppendEvent(eventName='RUN', eventStartTime=5, eventRunCount=10, eventFunc=self.Run, eventFuncArgs=player.GetLevel())
The following things will happen:
- The function Run(args), will start to run in 5 seconds for 10 times.
PS: Check my first reply for code.
- 3
- 3
- 7
-
On 10/9/2019 at 11:44 PM, WeedHex said:
Was better with timer solution, mount begin load after other things so checking the login is useless cuz there isn't still mount at login
No, we don't need a timer for this, you're right that you can't do this inside of login because the POINT_MOUNT is seted after, so, this method is for all types of mounts/horses:
Not tested.
- 6
- 1
- 1
- 1
- 7
-
1 hour ago, Cripplez said:
I tried like this but when i'm riding a mount it still doesn't make me unmount it with the horse it is perfect
Then your problem is that you've costume mount slot, not the default mount, replace the code what i gave you with:
#ifdef ENABLE_BLOCK_RIDING_IN_DUNGEON if (ch && ch->GetDungeon()) { const LPITEM pMount = ch->GetWear(WEAR_COSTUME_MOUNT); if (pMount && pMount->IsEquipped()) ch->UnequipItem(pMount); if (ch->IsHorseRiding()) { ch->StopRiding(); ch->HorseSummon(false); } } #endif
Be careful to have on all of your vnums type: ITEM_COSTUME < 28, sub type: COSTUME_MOUNT < 2
- 1
-
2 hours ago, Cripplez said:
I'm not sure if i did this part as you write in your message, maybe the problem is here?
if (ch->GetHorseLevel() > 0) { DWORD pid = ch->GetPlayerID(); if (pid != 0 && CHorseNameManager::instance().GetHorseName(pid) == NULL) db_clientdesc->DBPacket(HEADER_GD_REQ_HORSE_NAME, 0, &pid, sizeof(DWORD)); //@fix horse_level update at login ch->SetHorseLevel(ch->GetHorseLevel()); ch->SkillLevelPacket(); #ifdef ENABLE_BLOCK_RIDING_IN_DUNGEON if (ch && ch->GetDungeon()) { if (ch->IsHorseRiding()) { ch->StopRiding(); ch->HorseSummon(false); } if (ch->FindAffect(AFFECT_MOUNT)) { ch->RemoveAffect(AFFECT_MOUNT); ch->RemoveAffect(AFFECT_MOUNT_BONUS); } } #endif }
You added it wrong, not inside of GetHorseLevel > 0, outside of condition.
Spoilerif (ch->GetHorseLevel() > 0) { DWORD pid = ch->GetPlayerID(); if (pid != 0 && CHorseNameManager::instance().GetHorseName(pid) == NULL) db_clientdesc->DBPacket(HEADER_GD_REQ_HORSE_NAME, 0, &pid, sizeof(DWORD)); //@fix horse_level update at login ch->SetHorseLevel(ch->GetHorseLevel()); ch->SkillLevelPacket(); } #ifdef ENABLE_BLOCK_RIDING_IN_DUNGEON if (ch && ch->GetDungeon()) { if (ch->IsHorseRiding()) { ch->StopRiding(); ch->HorseSummon(false); } if (ch->FindAffect(AFFECT_MOUNT)) { ch->RemoveAffect(AFFECT_MOUNT); ch->RemoveAffect(AFFECT_MOUNT_BONUS); } } #endif
-
Not tested, but you can try to do something like:
- Srcs/Server/game/src/questlua_horse.cpp
Spoiler// Search in horse_summon function: bool bFromFar = lua_isboolean(L, 1) ? lua_toboolean(L, 1) : false; // Add before: #ifdef ENABLE_BLOCK_RIDING_IN_DUNGEON if (ch && ch->GetDungeon()) return 0; #endif
- Srcs/Server/game/src/questlua_pc.cpp
Spoiler// Search in pc_mount_bonus and pc_mount function: LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); // Add after: #ifdef ENABLE_BLOCK_RIDING_IN_DUNGEON if (ch && ch->GetDungeon()) return 0; #endif
- Srcs/Server/game/src/input_login.cpp
Spoiler// Search in CInputLogin::Entergame(LPDESC d, const char * data) for: if (ch->GetHorseLevel() > 0) { DWORD pid = ch->GetPlayerID(); if (pid != 0 && CHorseNameManager::instance().GetHorseName(pid) == NULL) db_clientdesc->DBPacket(HEADER_GD_REQ_HORSE_NAME, 0, &pid, sizeof(DWORD)); } // Add after: #ifdef ENABLE_BLOCK_RIDING_IN_DUNGEON if (ch && ch->GetDungeon()) { if (ch->IsHorseRiding()) { ch->StopRiding(); ch->HorseSummon(false); } if (ch->FindAffect(AFFECT_MOUNT)) { ch->RemoveAffect(AFFECT_MOUNT); ch->RemoveAffect(AFFECT_MOUNT_BONUS); } } #endif
- Srcs/Server/game/service.h
Spoiler#define ENABLE_BLOCK_RIDING_IN_DUNGEON
-
Update (work arround) - Added all of the virtual-key codes from mouse & keyboard, by pressing any key now you'll skip the intro logo.
- 3
-
1 hour ago, Syriza said:
Can you maybe tell how to do the Video with escape key, like official ?
i mean being able to cancel the Video with escapekey
- 1
-
On 10/5/2019 at 2:19 AM, Syriza said:
Can you maybe tell how to do the Video with escape key, like official ?
I mean being able to cancel the Video with escape key.As the title says, here's the simple method how you can skip the video without waiting until is finished, like official did long time ago.
Here're the constants value for virtual-key codes (hexadecimal values), right now these are by default:- VK_LBUTTON 0x01 - Left mouse button
- VK_ESCAPE 0x1B - ESC key
- VK_SPACE 0x20 - SPACEBAR
Srcs/Client/UserInterface/Locale_inc.h
Spoiler#define ENABLE_SKIP_MOVIE
Srcs/Client/UserInterface/MovieMan.cpp
Spoiler// 1.0) Search the function: PlayMovie(pcszName); // 1.1) Replace with: #ifdef ENABLE_SKIP_MOVIE PlayMovie(pcszName, true); #else PlayMovie(pcszName); #endif
QuoteHow to do it when i press any key/mouse etc to skip it? Not only by specific keys, people don't know those keys maybe.
- 24
- 1
- 1
- 5
- 2
- 40
-
15 minutes ago, tmoitoi said:
Not any existence of any .AVI or logo1.avi in the source
- root/introLogo.py
self.videoList = ["logo1.avi", "logo2.avi"] [....] self.playingVideo = app.OnLogoOpen(self.videoList[self.nextLogoIndex])
- 2
-
9 minutes ago, glosteng4141 said:
collected codes from the garbage please learn how to code.
Instead of repeating yourself in every reply that the code is bullshit, how about showing us your coding skills and let us criticize it too?
I'm sure that i'll have a lot of fun, and not only me.Btw, is funny how you're talking about shit code and say to people 'learn how to code', when you do this:
Spoiler- 13
-
- 58
- 1
- 3
- 16
- 4
- 33
C++ Costume time extend
in Community Support - Questions & Answers
Posted
Just now arrived from work, sorry for late answer.
If he do what you said, 604800 - current_timestamp = > -1kkk.
The correct way and single way to do it properly, is the the next one: