Beiträge von tetjnetjn

    After the installation (everything successfully compiled etc) game starts, but after the loading screen I only see the map and get this error knocked out.

    Bitte melden Sie sich an, um diesen Anhang zu sehen.


    Would be very grateful if someone can explain to me why the error appears or can fix it.

    Bitte melden Sie sich an, um diesen Link zu sehen.

    If you want to hide the existing refined effects when setting new shining:



    C
    1. for(int i = 0; i < 3; i++)
    2. {
    3. if (m_swordShiningRight[i] != 0 || m_swordShiningLeft[i] != 0) {
    4. return 0;
    5. }
    6. }


    it would look like this:

    Bitte melden Sie sich an, um diesen Link zu sehen.



    same for armors:

    C
    1. for(int i = 0; i < 2; i++)
    2. {
    3. if (m_armorShining[i] != 0 || m_specialShining[i] != 0) {
    4. return 0;
    5. }
    6. }


    Bitte melden Sie sich an, um diesen Link zu sehen.




    Then, change ChangeWeapon:

    and in change armor:

    C
    1. if (dwArmor == m_dwArmorID)
    2.         return false;

    replace that with:

    Then open NetworkActorManager.cpp and in void CNetworkActorManager::UpdateActor(const SNetworkUpdateActorData& c_rkNetUpdateActorData) you have to put the setshining part before changearmor and changeweapon:

    Bitte melden Sie sich an, um diesen Link zu sehen.

    Does anyone know how to fix the problem with the specular on armors? I was able to force the specular to 1.0f for weapons (therefore they are displayed correctly, without any transparency or some other bullshit), but this happens with amors (or costume with alpha channels for specular):

    Bitte melden Sie sich an, um dieses Bild zu sehen.


    EDIT: Found a solution:

    in

    C: CrenderTarget.cpp
    1. void CRenderTarget::UpdateModel()


    add at the end:

    C: CrenderTarget.cpp
    1. m_pModel->SetAlpha(0.99f);

    Bitte melden Sie sich an, um diesen Link zu sehen.


    This happens if you remove -DNDEBUG from the makefile (useful to debug some hidden errors, like this one, 'cause it's a big one). Despite me "using a net.SendChatPaclet("")", this happens on DungeonInfo::instance().Update(ch);


    Just add


    #include "dungeoninfo.h"


    on main.cpp and

    DungeonInfo dungeon_info;


    in int main(int argc, char **argv), before


    Code
    1. if (!start(argc, argv)) {
    2. CleanUpForEarlyExit();
    3. return 0;
    4. }

    If you wanna pickup items for other players in a party:



    It should look like this:


    Bitte melden Sie sich an, um diesen Link zu sehen.



    If you don't have it, launcher->PythonItem.cpp

    add the include:

    Code
    1. #include "PythonPlayer.h"

    and on bool CPythonItem::GetCloseItemVector


    inside the for cycle, in the if condition, if not present, add:

    C
    1. || CPythonPlayer::Instance().IsPartyMemberByName(pInstance->stOwnership.c_str()))

    It should look like this:

    Bitte melden Sie sich an, um diesen Link zu sehen.

    For a system I had to add to new horse skills and they had to be levelled to P. At the end of doing this, I got "stuck" for a moment on how the charge horse skill didn't load the animation over the level 19 and trying to search online, seems no one bothered to make them working in a good way. Somehow I found people saying they don't do damage. Honestly, no idea how, probably very old kraizy super bugged files, but can't check that rn.


    But let's say they do damage, but you'll notice the animation is always the same, effects too. What if you made new ones, how can they be read? Well, you might encounter two problems while doing it:


    1: you will get disconnected for skill hack

    2: the charge skill (it's the only one affected by this) won't do the horse animation if the level is over 20


    To fix the first, we need to change char_skill.cpp and go to:

    C
    1. { 2, 137, 140, 0, 0}, // 121
    2. { 1, 138, 0, 0, 0}, // 122
    3. { 1, 139, 0, 0, 0}, // 123


    Probably line: 3345

    so, now you have to add multiple lines just:

    C
    1. { 0, 0, 0, 0, 0}, //

    maybe adding the motion index on the right (so 124 125 ecc. for every line)

    every +25 you add again:

    C
    1. { 2, 137, 140, 0, 0}, // 146
    2. { 1, 138, 0, 0, 0}, // 147
    3. { 1, 139, 0, 0, 0}, // 148

    so, it will be something like:

    But why we did this? Someone might say "but won't be the motion index always be the same from playersettingsmodule.py?". Right, except, we said we wanted to put new effects and animations.


    And we get to the second problem.

    Let's say you already made all the effects, and you have your skill_splash_2.msa skill_splash_3.msa skill_splash_4.msa ecc.

    So, we open playersettingsmodule.py and first we edit:

    Python
    1. HORSE_SKILL_WILDATTACK = chr.MOTION_SKILL+121
    2. HORSE_SKILL_CHARGE = chr.MOTION_SKILL+122
    3. HORSE_SKILL_SPLASH = chr.MOTION_SKILL+123

    into:

    Python
    1. HORSE_SKILL_WILDATTACK = 121
    2. HORSE_SKILL_CHARGE = 122
    3. HORSE_SKILL_SPLASH = 123

    and then for every character we need to edit:

    Python
    1. chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, HORSE_SKILL_CHARGE, "skill_charge.msa")

    and

    Python
    1. chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, HORSE_SKILL_WILDATTACK, "skill_wildattack.msa")
    2. chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, HORSE_SKILL_SPLASH, "skill_splash.msa")

    and


    Python
    1. chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_TWOHAND_SWORD, HORSE_SKILL_WILDATTACK, "skill_wildattack.msa")
    2. chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_TWOHAND_SWORD, HORSE_SKILL_SPLASH, "skill_splash.msa")

    for the Assassin we'll have:

    Python
    1. chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_DUALHAND_SWORD, HORSE_SKILL_WILDATTACK, "skill_wildattack.msa")
    2. chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_DUALHAND_SWORD, HORSE_SKILL_SPLASH, "skill_splash.msa")
    Python
    1. chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BOW, HORSE_SKILL_WILDATTACK, "skill_wildattack.msa")
    2. chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BOW, HORSE_SKILL_SPLASH, "skill_splash.msa")

    well, you got the idea.


    Now, how do we make it that it reads the new effects and animations? Now, for the effects, it's pretty simple. All those lines need to be changed into (skill charge example):


    Python
    1. for i in xrange(skill.SKILL_EFFECT_COUNT):
    2. END_STRING = ""
    3. if i != 0: END_STRING = "_%d" % (i+1)
    4. #HORSE SKILLS
    5. chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+HORSE_SKILL_CHARGE, "skill_charge" + END_STRING + ".msa")

    What's changed? We added: chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+ before the name of the skill, and edited the name files with "name_file" + END_STRING + ".msa")

    Now, repeat that for every horse skill, and now you'll have your new effects, except, try to do the charge skill and, well, the horse will run, but then it will just stop, the character will do the animation, there will be your new effect and you get there wondering why the f the horse does nothing. Where's that animation in the first place? Obviously in the horse folder, right? Right

    It should be in:

    D:\ymir work\npc\horse and horse2 and opening motlist.txt we find:

    GENERAL SKILL2 25.msa 100

    If we open the model of the horse with granny viewer and load the 25.gr2 animation, well, we found the animation, it's there! What's happening?

    Well, in RaceManager.cpp in the launcher, we'll find:

    C
    1. s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SKILL2", CRaceMotionData::NAME_SKILL + 122));

    That's the "malicious" line who will link the "SKILL2" (charge) to his motion index, 122. Right, but at M/G/P we'll have a different motion index.

    Now, it might not be elegant, but, what can you do?

    I added three new lines (for the skill charge):

    C
    1. s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SKILL2M", CRaceMotionData::NAME_SKILL + 147));
    2. s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SKILL2G", CRaceMotionData::NAME_SKILL + 172));
    3. s_kMap_stType_dwIndex.insert(std::map<std::string, DWORD>::value_type("SKILL2P", CRaceMotionData::NAME_SKILL + 197));

    and slapped it in the motlist.txt of every horse:

    Code
    1. GENERAL SKILL2M 25.msa 100
    2. GENERAL SKILL2G 25.msa 100
    3. GENERAL SKILL2P 25.msa 100

    et voilà, every level of the skill, it loads the animation with the effect you wanted (and animation, but in that case, you'll need to change the msa for the level you wanted to change).

    Sure, for a few bosses, maybe. I just think it's more practical for future cases, you might need it for other aspects and not only for a dungeon ranking list. I mean, at the end it obviously depends on your needs.

    You can do this from the source of the game to count how many times you have killed the boss.

    the duration and maximum damage they have been able to do to the boss.:thumbup:

    Yeah, I am just saying, a well designed structure + functions to register the damage dealt/taken can be useful so that you can use it afterwards for whatever you want (which is not the case of the one shared in this topic, that, as you say, can be avoided with a few lines of code in the source, completely agree).

    But you don't need to edit the quests for the remaining time, I am not saying that, I was just saying for the damage dealt, somehow you have to register the damage dealt to a specific vid

    It is also not necessary to edit quest for the damage inflicted. You can do this from the source.

    Sure, for a few bosses, maybe. I just think it's more practical for future cases, you might need it for other aspects and not only for a dungeon ranking list. I mean, at the end it obviously depends on your needs.

    s-sure, except AFAIK the time remaining and time/dmg ranking, you can just already have the list in the client and update it with the infos you must obtain from the server.

    Everything can be opted out without editing quest.

    and I use it this way.

    All information directly to the database, without the need to edit quest files.

    But you don't need to edit the quests for the remaining time, I am not saying that, I was just saying for the damage dealt, somehow you have to register the damage dealt to a specific vid

    s-sure, except AFAIK the time remaining and time/dmg ranking, you can just already have the list in the client and update it with the infos you must obtain from the server.

    It is incomplete.

    It is always better to invest in a complete user-friendly development.

    That part is impossible to be completely user-friendly, unless everyone posts his dungeontable array and their dungeon quests and I'll make the function for every one of them.

    Then, the next step is to just get the value the functions return and add another variable to the existing function

    In my example I just used another method to send the infos, but I thought I was pretty clear why and what my edits were and what the basic logic was. Then, if anyone asks for more infos or w/e, they can always do that, I certainly won't bite ^^


    Manwhile the python part, where you actually wanna show the time remaining, that stays the same, you just need to change the name of the list (and again, It was pretty clear in the comments) and, if you use OP's method, ignore the parts outside dungeoninfo.py:

    Maybe I was too naive to think anyone would understand that? Probably, but honestly, wouldn't hurt to challenge yourselves sometimes >.>

    "/*I think you got it ahah basically if you have weird exceptions for your dungeons, edit the code accordingly*/"

    It's a condition for my dungeon list, but the logic stays ^^

    If you don't have weird stuff and the dungeons are all private instances, you just need to get the flags used to store the remaining time and send the value to the client.

    Declare a vector of string where u store all the names with the same IP

    Then u iterate the vector where u disconnect all the players found (with FindPC(const char* name))


    Out of the blue:char szQuery[512];

    Or just find the pg where I wrote "player_names.emplace_back(row[0]);" replacing it with the FindPC function, getting the name string here, copy it in a char array and put that in CHARACTER_MANAGER::instance().FindPC() function, assigning it to LPCHARACTER ch, and then the disconnect function, and then you can remove the rest of my code and delete the declaration of the vector. I made all that workaround just because when I tried to "test it", while testing on VS, there are some fuckeries between char[], char* and std::string and VS is pretty sensitive about some functions like snprintf or strcpy but at the end of the day, the logic stays. Query, take the name from ip, get the character from the name with CHARACTER_MANAGER::instance().FindPC(name); and disconnect that character (in a loop)

    Hi. I am having an issue with my files compiled with gcc7 (-std=gnu++17)

    this is what ldd displays in my compile machine:

    Bitte melden Sie sich an, um diesen Link zu sehen.


    (yes, mysqlclient is linked statically)


    This is what ldd32 (on freebsd 11.3 64bit) shows of the file db:

    Bitte melden Sie sich an, um diesen Link zu sehen.

    This is my libmap32.conf:

    Code
    1. # $FreeBSD: releng/11.3/etc/libmap.conf 253853 2013-08-01 05:50:42Z jlh $
    2. includedir /usr/local/etc/libmap.d
    3. libgomp.so.1 /usr/local/lib32/compat/libgomp.so.1
    4. libobjc.so.3 /usr/local/lib32/compat/libobjc.so.4
    5. libssp.so.0 /usr/local/lib32/compat/libssp.so.0
    6. libstdc++.so.6 /usr/local/lib/gcc7/libstdc++.so.6



    This is what gdb (version 712 in freebsd 9.3 32bit) shows:

    Bitte melden Sie sich an, um diesen Link zu sehen.


    gcc7 version in FreeBSD 11.3 64bit: 7.5.0

    gcc7 version in FreeBSD 9.2 32bit: 7.0.0 20161225 (this machine is from blackdragonx61)

    And the code, you can definitely look at what you have, since that part, is completely the same:

    Does anyone know what can cause this segmentation fault?


    Additional info, my Makefile:

    Eine der wichtigsten Funktionen hat das System nicht?


    Ich finde der Sinn hinter so einem System ist zu sehen wie lange man noch Cooldown hat auf den jeweiligen Dungeon, was man nicht sieht.

    Open dungeoninfo.cpp and add this function (READ CAREFULLY THE COMMENTS):


    Now, let's change the other function:

    void DungeonInfo::Update(LPCHARACTER ch)


    Now, a few things before just blindly copy pasting. Yeah, you can use the original file method and use the command chat, or use a buffered packet (I wanted to remove the ranking, but if you wanna keep it, it's fine)

    Also, looking back at it, I wonder why the f I made that vector..but oh well

    Obviously, we should edit our array, right? So edit, accordingly

    Code
    1. DungeonInfoTable dungeonTable[2] = {
    2. {2, 3, 60, 8, 66, "Demon Tower", "Hwang Temple" , {5906, 1108}, 0, 0, 0, 1093, "None"}, // Index 0
    3. {2, 3, 75, 8, 220, "Dragon Lair", "Grotto of Exile" , {5906, 1108}, 1200, 1200, 100, 2430, "dragon_lair_time"}, // Index 1
    4. };

    And also, copy the struct, and put it all in dungeoninfo.h Yours will be different but the key is: std::string flag_string_time;

    and under void Update add:

    Code
    1. int GetRemainTime(LPCHARACTER ch, int dungeonID);

    So, let's head to packet.h (again, add w/e variable you wanna use)


    and obviously add the HEADER_GC_DUNGEON_INFO to the list


    Now go to cmd_gm.cpp and add:

    Code
    1. #include "dungeoninfo.h"
    2. ACMD(do_send_dungeon_info)
    3. {
    4. DungeonInfo::instance().Update(ch);
    5. }

    then add in cmd.cpp:

    Code
    1. ACMD (do_send_dungeon_info);
    Code
    1. { "send_dungeon_info", do_send_dungeon_info, 0, POS_DEAD, GM_PLAYER },

    So then, client part, Packet.h, again, add HEADER_GC_DUNGEON_INFO (same numbers, remember, obviously) and well, you know, the structs:

    PythonNetworkStream.cpp:

    Code
    1. Set(HEADER_GC_DUNGEON_INFO, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSendDungeonInfo), DYNAMIC_SIZE_PACKET));

    PythonNetworkStreamPhaseGame.cpp:

    Code
    1. case HEADER_GC_DUNGEON_INFO:
    2. ret = RecvDungeonsInformation();
    3. break;


    Here, remember, your variables that you wanted to have and I didn't

    and PythonNetworkStream.h we should declase that function:

    Code
    1. bool RecvDungeonsInformation(); //under, idfk, bool RecvCreateFlyFreeEnumPacket(); is fine

    Client, root->game.py under def AnswerGuildInvite:

    Code
    1. def __LoadDungeonInfo(self):
    2. net.SendChatPacket("/send_dungeon_info")


    Under BINARY_RecvMssysData

    Code
    1. def BINARY_DungeonsInformation(self, info):
    2. uiDungeonInfo.DUNGEON_INFO_LIST = info ##o constinfo.dungeonInfo = info but I don't get why people keep using constinfo
    3. self.interface.ShowDungeonInfoInterface()

    And then, in uidungeoninfo, declare an empty dict, under def __init__(self): e def __del__(self):

    Code
    1. self.dungeonCanEnter = {}
    2. self.realPos = 0 ##add also this

    under __init__ also add:

    Code
    1. self.receivedTime = app.GetTime()


    now, in def OnScroll(self): at the end, outside the for cycle add:

    Code
    1. self.realPos = realPos

    At the end of AppendDungeonButton put:

    Code
    1. self.CanEnterText(index)

    Now, my CanEnterText function (revisioned because I have a different kind of "remaintime" for the raids) looks like this:

    obviously, edit DUNGEON_INFO_LIST with constinfo.dungeonInfo or w/e and careful at the missing strings in locale_interface.txt

    If you use datetime.timedelta on top the file add

    Code
    1. import datetime

    Otherwise use w/e function you think suits best your interface (even the one FormatTimeString already included in the file)


    now, we need a new function (actually no, I had to delete the old OnUpdate function)

    ok, so, just add in the OnUpdate function:

    Python
    1. if app.GetTime() <= self.lastCountDownRefresh + 1.0:
    2. return
    3. self.lastCountDownRefresh = app.GetTime()
    4. count = len(DUNGEON_INFO_LIST)
    5. for i in xrange(min(count, self.MIN_SCROLLBAR_LIST)):
    6. j = self.realPos + i
    7. self.CanEnterText(j)

    There's another function to add:

    Python
    1. def GetRemainTime(self, index):
    2. return DUNGEON_INFO_LIST[index]['remainTime'] - (app.GetTime() - self.receivedTime)

    as usual: DUNGEON_INFO_LIST -> constinfo.dungeonInfo or w/e


    and I think that's it, I shouldn't be missing more (but I doubt it, I am so tired). I am still working on adding some stuff, like check of level for the teleport and pricing + maybe a Group Search for dungeons that need or can have a group