Jump to content

[BUG]Mount wrong position slot and mount() bug


Recommended Posts

Hello, i added this mount system:

but i have a problem, because i have

mount  on slot sash and sash on mount.

Screen-Shot-07-16-19-at-09-08-AM.png

#2 bug is when i equip mount they don't summoned. only when i change character or change map mount is summoned

Client Binary:

GameLib/ItemData.h

Spoiler

      enum ECostumeSubTypes{
            COSTUME_BODY,                //0    갑옷(main look)
            COSTUME_HAIR,                //1    헤어(탈착가능)
            COSTUME_ACCE,                //2
            COSTUME_MOUNT,                //3
            COSTUME_WEAPON,                //4
            COSTUME_NUM_TYPES
        };

 

UserInterface/GameType.h

Spoiler

#ifdef ENABLE_NEW_EQUIPMENT_SYSTEM
    const DWORD c_New_Equipment_Start = c_Equipment_Start + 24;
    const DWORD c_New_Equipment_Count = 3;
    const DWORD c_Equipment_Ring1 = c_New_Equipment_Start + 0;//0
    const DWORD c_Equipment_Ring2 = c_New_Equipment_Start + 1;//1
    const DWORD c_Equipment_Belt  = c_New_Equipment_Start + 2;//2
#endif

#ifdef ENABLE_COSTUME_SYSTEM
    const DWORD c_Costume_Slot_Start    = c_Equipment_Start + 19;    // [주의] 숫자(19) 하드코딩 주의. 현재 서버에서 코스츔 슬롯은 19부터임. 서버 common/length.h 파일의 EWearPositions 열거형 참고.
    const DWORD    c_Costume_Slot_Body        = c_Costume_Slot_Start + 0;
    const DWORD    c_Costume_Slot_Hair        = c_Costume_Slot_Start + 1;
    const DWORD    c_Costume_Slot_Sash = c_Costume_Slot_Start + 2;
    const DWORD    c_Costume_Slot_Mount = c_Costume_Slot_Start + 3;
    const DWORD    c_Costume_Slot_Weapon = c_Costume_Slot_Start + 4;
    
    const DWORD c_Costume_Slot_Count = 5;
    
    const DWORD c_Costume_Slot_End        = c_Costume_Slot_Start + c_Costume_Slot_Count;
#endif

 

UserInterface/PythonItemModule.cpp

Spoiler

   // Item Sub Type
    PyModule_AddIntConstant(poModule, "COSTUME_TYPE_BODY",            CItemData::COSTUME_BODY);
    PyModule_AddIntConstant(poModule, "COSTUME_TYPE_HAIR",            CItemData::COSTUME_HAIR);
    PyModule_AddIntConstant(poModule, "COSTUME_TYPE_ACCE",            CItemData::COSTUME_ACCE);
    PyModule_AddIntConstant(poModule, "COSTUME_TYPE_MOUNT",            CItemData::COSTUME_MOUNT);
    PyModule_AddIntConstant(poModule, "COSTUME_TYPE_WEAPON",        CItemData::COSTUME_WEAPON);

    PyModule_AddIntConstant(poModule, "COSTUME_SLOT_START",            c_Costume_Slot_Start);
    PyModule_AddIntConstant(poModule, "COSTUME_SLOT_COUNT",            c_Costume_Slot_Count);
    PyModule_AddIntConstant(poModule, "COSTUME_SLOT_BODY",            c_Costume_Slot_Body);
    PyModule_AddIntConstant(poModule, "COSTUME_SLOT_HAIR",            c_Costume_Slot_Hair);
    PyModule_AddIntConstant(poModule, "COSTUME_SLOT_SASH",             c_Costume_Slot_Sash);
    PyModule_AddIntConstant(poModule, "COSTUME_SLOT_MOUNT",         c_Costume_Slot_Mount);
    PyModule_AddIntConstant(poModule, "COSTUME_SLOT_WEAPON",         c_Costume_Slot_Weapon);
    PyModule_AddIntConstant(poModule, "COSTUME_SLOT_END",            c_Costume_Slot_End);

 

 

Server:

common/item_lenght.h

Spoiler

enum ECostumeSubTypes
{
	COSTUME_BODY = ARMOR_BODY,			// [중요!!] ECostumeSubTypes enum value는  종류별로 EArmorSubTypes의 그것과 같아야 함.
	COSTUME_HAIR = ARMOR_HEAD,			// 이는 코스츔 아이템에 추가 속성을 붙이겠다는 사업부의 요청에 따라서 기존 로직을 활용하기 위함임.
	#ifdef __SASH_SYSTEM__
	COSTUME_ACCE,
	#endif
	#ifdef ENABLE_COSTUME_MOUNT_SYSTEM
	COSTUME_MOUNT,
	#endif
	COSTUME_WEAPON,
	COSTUME_NUM_TYPES,
};

 

common/length.h

Spoiler

enum EWearPositions
{
	WEAR_BODY,		// 0
	WEAR_HEAD,		// 1
	WEAR_FOOTS,		// 2
	WEAR_WRIST,		// 3
	WEAR_WEAPON,	// 4
	WEAR_NECK,		// 5
	WEAR_EAR,		// 6
	WEAR_UNIQUE1,	// 7
	WEAR_UNIQUE2,	// 8
	WEAR_ARROW,		// 9
	WEAR_SHIELD,	// 10
    WEAR_ABILITY1,  // 11
    WEAR_ABILITY2,  // 12
    WEAR_ABILITY3,  // 13
    WEAR_ABILITY4,  // 14
    WEAR_ABILITY5,  // 15
    WEAR_ABILITY6,  // 16
    WEAR_ABILITY7,  // 17
    WEAR_ABILITY8,  // 18
	WEAR_COSTUME_BODY,	// 19
	WEAR_COSTUME_HAIR,	// 20
	WEAR_COSTUME_SASH,	//21
	WEAR_COSTUME_MOUNT,	// 22
	WEAR_COSTUME_WEAPON,// 23
	
	WEAR_RING1,			// 24	: 신규 반지슬롯1 (왼쪽)
	WEAR_RING2,			// 25	: 신규 반지슬롯2 (오른쪽)
	
	WEAR_BELT,			// 26	: 신규 벨트슬롯

	WEAR_MAX = 32	// 
};

 

DB:

ProtoReader.cpp

Spoiler

    static string arSub28[] = {
                "COSTUME_BODY", 
                "COSTUME_HAIR",
#ifdef ENABLE_NEW_ITEM_PROTO_STRUCT
                "COSTUME_ACCE",
                "COSTUME_MOUNT",
                "COSTUME_WEAPON"
#endif
    };

 

    string arWearrFlag[] = {
                                "WEAR_BODY", 
                                "WEAR_HEAD", 
                                "WEAR_FOOTS", 
                                "WEAR_WRIST", 
                                "WEAR_WEAPON", 
                                "WEAR_NECK", 
                                "WEAR_EAR", 
                                "WEAR_SHIELD", 
                                "WEAR_UNIQUE",
                                "WEAR_ARROW", 
#ifdef ENABLE_NEW_ITEM_PROTO_STRUCT
                                "WEAR_HAIR", 
                                "WEAR_ABILITY",
                                "WEAR_PENDANT",
                                "WEAR_COSTUME_BODY", 
                                "WEAR_COSTUME_HAIR", 
                                "WEAR_COSTUME_SASH",
                                "WEAR_COSTUME_MOUNT",
                                "WEAR_COSTUME_WEAPON"
#endif
    };

 

Game:

char_battle.cpp

Spoiler

void CHARACTER::Dead(LPCHARACTER pkKiller, bool bImmediateDead)
{
	if (IsDead())
		return;

	{
		if (IsHorseRiding())
		{
			StopRiding();
		}
		else if (GetMountVnum())
		{
			RemoveAffect(AFFECT_MOUNT_BONUS);
			UpdatePacket();
		}
	}

 

char_item.cpp

Spoiler

     #ifdef __SASH_SYSTEM__
        else if ((item->GetType() == ITEM_COSTUME) && (item->GetSubType() == COSTUME_ACCE))
            this->EffectPacket(SE_EFFECT_SASH_EQUIP);
        #endif

        if (UNIQUE_SPECIAL_RIDE == item->GetSubType() && IS_SET(item->GetFlag(), ITEM_FLAG_QUEST_USE))
        {
            quest::CQuestManager::instance().UseItem(GetPlayerID(), item, false);
        }
        
        #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
        if (COSTUME_MOUNT == item->GetSubType())
        {
            quest::CQuestManager::instance().UseItem(GetPlayerID(), item, false);
        }
        #endif

            case POINT_COSTUME_ATTR_BONUS:
                {
                    #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
                    static BYTE abSlot[] = { WEAR_COSTUME_BODY, WEAR_COSTUME_HAIR, WEAR_COSTUME_SASH, WEAR_COSTUME_MOUNT };
                    #else
                    static BYTE abSlot[] = { WEAR_COSTUME_BODY, WEAR_COSTUME_HAIR };
                    #endif
                    static std::vector <BYTE> vec_slots (abSlot, abSlot + _countof(abSlot));
                    pBuff = M2_NEW CBuffOnAttributes(this, bType, &vec_slots);
                }
                break;

 

bool CHARACTER::IsEquipUniqueItem(DWORD dwItemVnum) const
{
    {
        LPITEM u = GetWear(WEAR_UNIQUE1);

        if (u && u->GetVnum() == dwItemVnum)
            return true;
    }

    {
        LPITEM u = GetWear(WEAR_UNIQUE2);

        if (u && u->GetVnum() == dwItemVnum)
            return true;
    }
    
    #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
    {
        LPITEM u = GetWear(WEAR_COSTUME_MOUNT);

        if (u && u->GetVnum() == dwItemVnum)
            return true;
    }
    #endif

    // 언어반지인 경우 언어반지(견본) 인지도 체크한다.
    if (dwItemVnum == UNIQUE_ITEM_RING_OF_LANGUAGE)
        return IsEquipUniqueItem(UNIQUE_ITEM_RING_OF_LANGUAGE_SAMPLE);

    return false;
}

 

bool CHARACTER::IsEquipUniqueGroup(DWORD dwGroupVnum) const
{
    {
        LPITEM u = GetWear(WEAR_UNIQUE1);

        if (u && u->GetSpecialGroup() == (int) dwGroupVnum)
            return true;
    }

    {
        LPITEM u = GetWear(WEAR_UNIQUE2);

        if (u && u->GetSpecialGroup() == (int) dwGroupVnum)
            return true;
    }
    #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
    {
        LPITEM u = GetWear(WEAR_COSTUME_MOUNT);

        if (u && u->GetSpecialGroup() == (int)dwGroupVnum)
            return true;
    }
    #endif
    
    return false;
}

bool CHARACTER::UnEquipSpecialRideUniqueItem()
{
    LPITEM Unique1 = GetWear(WEAR_UNIQUE1);
    LPITEM Unique2 = GetWear(WEAR_UNIQUE2);
    #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
    LPITEM Unique3 = GetWear(WEAR_COSTUME_MOUNT);
    #endif

    if( NULL != Unique1 )
    {
        if( UNIQUE_GROUP_SPECIAL_RIDE == Unique1->GetSpecialGroup() )
        {
            return UnequipItem(Unique1);
        }
    }

    if( NULL != Unique2 )
    {
        if( UNIQUE_GROUP_SPECIAL_RIDE == Unique2->GetSpecialGroup() )
        {
            return UnequipItem(Unique2);
        }
    }
    
    #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
    if (NULL != Unique3)
    {
        if (UNIQUE_GROUP_SPECIAL_RIDE == Unique3->GetSpecialGroup())
        {
            return UnequipItem(Unique3);
        }
    }
    #endif

    return true;
}

 

    if (item->GetWearFlag() & WEARABLE_UNIQUE)
    {
        #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
        if ((GetWear(WEAR_UNIQUE1) && GetWear(WEAR_UNIQUE1)->IsSameSpecialGroup(item)) ||
            (GetWear(WEAR_UNIQUE2) && GetWear(WEAR_UNIQUE2)->IsSameSpecialGroup(item)) ||
            (GetWear(WEAR_COSTUME_MOUNT) && GetWear(WEAR_COSTUME_MOUNT)->IsSameSpecialGroup(item)))
        #else
        if ((GetWear(WEAR_UNIQUE1) && GetWear(WEAR_UNIQUE1)->IsSameSpecialGroup(item)) ||
            (GetWear(WEAR_UNIQUE2) && GetWear(WEAR_UNIQUE2)->IsSameSpecialGroup(item)))
        #endif
        {
            ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Nie mo?esz wyposa?y? dwoch unikalnych przedmiotow tego samego typu w tym samym czasie"));//같은 종류의 유니크 아이템 두 개를 동시에 장착할 수 없습니다.
            return false;
        }

        if (marriage::CManager::instance().IsMarriageUniqueItem(item->GetVnum()) && 
            !marriage::CManager::instance().IsMarried(GetPlayerID()))
        {
            ChatPacket(CHAT_TYPE_INFO, LC_TEXT("결혼하지 않은 상태에서 예물을 착용할 수 없습니다."));
            return false;
        }

    }

 

cmd_general.cpp

Spoiler

ACMD(do_unmount)
{
    #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
    LPITEM item = ch->GetWear(WEAR_UNIQUE1);
    LPITEM item2 = ch->GetWear(WEAR_UNIQUE2);
    LPITEM item3 = ch->GetWear(WEAR_COSTUME_MOUNT);

    if (item && item->IsRideItem())
        ch->UnequipItem(item);

    if (item2 && item2->IsRideItem())
        ch->UnequipItem(item2);

    if (item3 && item3->IsRideItem())
        ch->UnequipItem(item3);
    #endif
    
    if (true == ch->UnEquipSpecialRideUniqueItem())
    {
        ch->RemoveAffect(AFFECT_MOUNT);
        ch->RemoveAffect(AFFECT_MOUNT_BONUS);

        if (ch->IsHorseRiding())
        {
            ch->StopRiding(); 
        }
    }
    else
    {
        ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("인벤토리가 꽉 차서 내릴 수 없습니다."));//인벤토리가 꽉 차서 내릴 수 없습니다.
    }

}

 

ACMD(do_ride){
    dev_log(LOG_DEB0, "[DO_RIDE] start");
    if (ch->IsDead() || ch->IsStun())
    return;

    // 내리기
    {
    if (ch->IsHorseRiding())
    {
        dev_log(LOG_DEB0, "[DO_RIDE] stop riding");
        ch->StopRiding(); 
        return;
    }

    if (ch->GetMountVnum())
    {
        dev_log(LOG_DEB0, "[DO_RIDE] unmount");
        do_unmount(ch, NULL, 0, 0);
        return;
    }
    }

    // 타기
    {
    if (ch->GetHorse() != NULL){
        dev_log(LOG_DEB0, "[DO_RIDE] start riding");
        ch->StartRiding();
        return;
    }
#ifdef EXTENDED_INVENTORY_PAGES
    for (int i=0; i<INVENTORY_MAX_NUM; ++i){
#else
    for (BYTE i=0; i<INVENTORY_MAX_NUM; ++i){
#endif
        LPITEM item = ch->GetInventoryItem(i);
        if (NULL == item)
        continue;

        // 유니크 탈것 아이템
        if (item->IsRideItem()){
            #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
            if (NULL==ch->GetWear(WEAR_UNIQUE1) || NULL==ch->GetWear(WEAR_UNIQUE2) || NULL==ch->GetWear(WEAR_COSTUME_MOUNT))
            #else
            if (NULL==ch->GetWear(WEAR_UNIQUE1) || NULL==ch->GetWear(WEAR_UNIQUE2))
            #endif
            {
                dev_log(LOG_DEB0, "[DO_RIDE] USE UNIQUE ITEM");
                ch->UseItem(TItemPos (INVENTORY, i));
                return;
            }
        }

        // 일반 탈것 아이템
        // TODO : 탈것용 SubType 추가
        switch (item->GetVnum()){
        case 71114:    // 저신이용권
        case 71116:    // 산견신이용권
        case 71118:    // 투지범이용권
        case 71120:    // 사자왕이용권
            dev_log(LOG_DEB0, "[DO_RIDE] USE QUEST ITEM");
            ch->UseItem(TItemPos (INVENTORY, i));
            return;
        }

        // GF mantis #113524, 52001~52090 번 탈것
        if( (item->GetVnum() > 52000) && (item->GetVnum() < 52091)){
            dev_log(LOG_DEB0, "[DO_RIDE] USE QUEST ITEM");
            ch->UseItem(TItemPos (INVENTORY, i));
            return;
        }
    }
    }

    // 타거나 내릴 수 없을때
    ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("말을 먼저 소환해주세요."));
}

 

item.cpp

Spoiler

bool CItem::IsRideItem()
{
    if (ITEM_UNIQUE == GetType() && UNIQUE_SPECIAL_RIDE == GetSubType())
        return true;
    if (ITEM_UNIQUE == GetType() && UNIQUE_SPECIAL_MOUNT_RIDE == GetSubType())
        return true;
    if (ITEM_COSTUME == GetType() && COSTUME_MOUNT == GetSubType())
        return true;
    
    return false;
}
 
 

int CItem::FindEquipCell(LPCHARACTER ch, int iCandidateCell)
{
    // 코스츔 아이템(ITEM_COSTUME)은 WearFlag 없어도 됨. (sub type으로 착용위치 구분. 귀찮게 또 wear flag 줄 필요가 있나..)
    // 용혼석(ITEM_DS, ITEM_SPECIAL_DS)도  SUB_TYPE으로 구분. 신규 반지, 벨트는 ITEM_TYPE으로 구분 -_-
    if ((0 == GetWearFlag() || ITEM_TOTEM == GetType()) && ITEM_COSTUME != GetType() && ITEM_DS != GetType() && ITEM_SPECIAL_DS != GetType() && ITEM_RING != GetType() && ITEM_BELT != GetType())
        return -1;

    // 용혼석 슬롯을 WEAR로 처리할 수가 없어서(WEAR는 최대 32개까지 가능한데 용혼석을 추가하면 32가 넘는다.)
    // 인벤토리의 특정 위치((INVENTORY_MAX_NUM + WEAR_MAX_NUM)부터 (INVENTORY_MAX_NUM + WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX - 1)까지)를
    // 용혼석 슬롯으로 정함.
    // return 할 때에, INVENTORY_MAX_NUM을 뺀 이유는,
    // 본래 WearCell이 INVENTORY_MAX_NUM를 빼고 return 하기 때문.
    if (GetType() == ITEM_DS || GetType() == ITEM_SPECIAL_DS)
    {
        if (iCandidateCell < 0)
        {
            return WEAR_MAX_NUM + GetSubType();
        }
        else
        {
            for (int i = 0; i < DRAGON_SOUL_DECK_MAX_NUM; i++)
            {
                if (WEAR_MAX_NUM + i * DS_SLOT_MAX + GetSubType() == iCandidateCell)
                {
                    return iCandidateCell;
                }
            }
            return -1;
        }
    }
    else if (GetType() == ITEM_COSTUME)
    {
        if (GetSubType() == COSTUME_BODY)
            return WEAR_COSTUME_BODY;
        else if (GetSubType() == COSTUME_HAIR)
            return WEAR_COSTUME_HAIR;
        #ifdef __SASH_SYSTEM__
        else if (GetSubType() == COSTUME_ACCE)
            return WEAR_COSTUME_SASH;
        #endif
        else if (GetSubType() == COSTUME_MOUNT)
            return WEAR_COSTUME_MOUNT;
        else if (GetSubType() == COSTUME_WEAPON)
            return WEAR_COSTUME_WEAPON;
    }
    else if (GetType() == ITEM_RING)
    {
        if (ch->GetWear(WEAR_RING1))
            return WEAR_RING2;
        else
            return WEAR_RING1;
    }
    else if (GetType() == ITEM_BELT)
        return WEAR_BELT;
    else if (GetWearFlag() & WEARABLE_BODY)
        return WEAR_BODY;
    else if (GetWearFlag() & WEARABLE_HEAD)
        return WEAR_HEAD;
    else if (GetWearFlag() & WEARABLE_FOOTS)
        return WEAR_FOOTS;
    else if (GetWearFlag() & WEARABLE_WRIST)
        return WEAR_WRIST;
    else if (GetWearFlag() & WEARABLE_WEAPON)
        return WEAR_WEAPON;
    else if (GetWearFlag() & WEARABLE_SHIELD)
        return WEAR_SHIELD;
    else if (GetWearFlag() & WEARABLE_NECK)
        return WEAR_NECK;
    else if (GetWearFlag() & WEARABLE_EAR)
        return WEAR_EAR;
    else if (GetWearFlag() & WEARABLE_ARROW)
        return WEAR_ARROW;
    else if (GetWearFlag() & WEARABLE_UNIQUE)
    {
        if (ch->GetWear(WEAR_UNIQUE1))
            return WEAR_UNIQUE2;
        else
            return WEAR_UNIQUE1;        
    }

    // 수집 퀘스트를 위한 아이템이 박히는곳으로 한번 박히면 절대 E수 없다.
    else if (GetWearFlag() & WEARABLE_ABILITY)
    {
        if (!ch->GetWear(WEAR_ABILITY1))
        {
            return WEAR_ABILITY1;
        }
        else if (!ch->GetWear(WEAR_ABILITY2))
        {
            return WEAR_ABILITY2;
        }
        else if (!ch->GetWear(WEAR_ABILITY3))
        {
            return WEAR_ABILITY3;
        }
        else if (!ch->GetWear(WEAR_ABILITY4))
        {
            return WEAR_ABILITY4;
        }
        else if (!ch->GetWear(WEAR_ABILITY5))
        {
            return WEAR_ABILITY5;
        }
        else if (!ch->GetWear(WEAR_ABILITY6))
        {
            return WEAR_ABILITY6;
        }
        else if (!ch->GetWear(WEAR_ABILITY7))
        {
            return WEAR_ABILITY7;
        }
        else if (!ch->GetWear(WEAR_ABILITY8))
        {
            return WEAR_ABILITY8;
        }
        else
        {
            return -1;
        }
    }
    return -1;
}

 

item_manager.cpp

Spoiler

    if (item->GetType() == ITEM_QUEST)
    {
        for (itertype (m_map_pkQuestItemGroup) it = m_map_pkQuestItemGroup.begin(); it != m_map_pkQuestItemGroup.end(); it++)
        {
            if (it->second->m_bType == CSpecialItemGroup::QUEST && it->second->Contains(vnum))
            {
                item->SetSIGVnum(it->first);
            }
        }
    }
    else if (item->GetType() == ITEM_UNIQUE)
    {
        for (itertype(m_map_pkSpecialItemGroup) it = m_map_pkSpecialItemGroup.begin(); it != m_map_pkSpecialItemGroup.end(); it++)
        {
            if (it->second->m_bType == CSpecialItemGroup::SPECIAL && it->second->Contains(vnum))
            {
                item->SetSIGVnum(it->first);
            }
        }
    }
    else if (item->GetType() == ITEM_UNIQUE || item->GetSubType() == COSTUME_MOUNT)
    {
        for (itertype(m_map_pkSpecialItemGroup) it = m_map_pkSpecialItemGroup.begin(); it != m_map_pkSpecialItemGroup.end(); it++)
        {
            if (it->second->m_bType == CSpecialItemGroup::SPECIAL && it->second->Contains(vnum))
            {
                item->SetSIGVnum(it->first);
            }
        }
    }

 

 

questlua_pc.cpp

Spoiler

    int pc_get_special_ride_vnum(lua_State* L)
    {
        LPCHARACTER pChar = CQuestManager::instance().GetCurrentCharacterPtr();

        if (NULL != pChar)
        {
            LPITEM Unique1 = pChar->GetWear(WEAR_UNIQUE1);
            LPITEM Unique2 = pChar->GetWear(WEAR_UNIQUE2);
            LPITEM Unique3 = pChar->GetWear(WEAR_COSTUME_MOUNT);

            if (NULL != Unique1)
            {
                if (UNIQUE_GROUP_SPECIAL_RIDE == Unique1->GetSpecialGroup())
                {
                    lua_pushnumber(L, Unique1->GetVnum());
                    lua_pushnumber(L, Unique1->GetSocket(2));
                    return 2;
                }
            }

            if (NULL != Unique2)
            {
                if (UNIQUE_GROUP_SPECIAL_RIDE == Unique2->GetSpecialGroup())
                {
                    lua_pushnumber(L, Unique2->GetVnum());
                    lua_pushnumber(L, Unique2->GetSocket(2));
                    return 2;
                }
            }

            if (NULL != Unique3)
            {
                if (UNIQUE_GROUP_SPECIAL_RIDE == Unique3->GetSpecialGroup())
                {
                    lua_pushnumber(L, Unique3->GetVnum());
                    lua_pushnumber(L, Unique3->GetSocket(2));
                    return 2;
                }
            }

        }

        lua_pushnumber(L, 0);
        lua_pushnumber(L, 0);

        return 2;
    }

 

DumpProto:

ItemCSVReader.cpp

Spoiler

    static string arSub28[] = {
                "COSTUME_BODY", 
                "COSTUME_HAIR",
#ifdef ENABLE_NEW_ITEM_PROTO_STRUCT
                "COSTUME_ACCE",
                "COSTUME_MOUNT",
                "COSTUME_WEAPON"
#endif
    };

int get_Item_WearFlag_Value(string inputString){
    string arWearrFlag[] = {
                                "WEAR_BODY", 
                                "WEAR_HEAD", 
                                "WEAR_FOOTS", 
                                "WEAR_WRIST", 
                                "WEAR_WEAPON", 
                                "WEAR_NECK", 
                                "WEAR_EAR", 
                                "WEAR_SHIELD", 
                                "WEAR_UNIQUE",
                                "WEAR_ARROW", 
#ifdef ENABLE_NEW_ITEM_PROTO_STRUCT
                                "WEAR_HAIR", 
                                "WEAR_ABILITY",
                                "WEAR_PENDANT",
                                "WEAR_COSTUME_SASH",
                                "WEAR_COSTUME_MOUNT",
                                "WEAR_COSTUME_WEAPON"
#endif
    };

 

 

 

 

 

Client: costumewindow.py

Spoiler

import uiScriptLocale
import item
import app

COSTUME_START_INDEX = item.COSTUME_SLOT_START

window = {
	"name" : "CostumeWindow",

	"x" : SCREEN_WIDTH - 175 - 140,
	"y" : SCREEN_HEIGHT - 37 - 565,

	"style" : ("movable", "float",),

	"width" : 140,
	"height" : (180 + 47), #기존보다 47 길어짐

	"children" :
	(
		{
			"name" : "board",
			"type" : "board",
			"style" : ("attach",),

			"x" : 0,
			"y" : 0,

			"width" : 140,
			"height" : (180 + 47),
		
			"children" :
			(
				## Title
				{
					"name" : "TitleBar",
					"type" : "titlebar",
					"style" : ("attach",),

					"x" : 6,
					"y" : 6,

					"width" : 130,
					"color" : "yellow",

					"children" :
					(
						{ "name":"TitleName", "type":"text", "x":60, "y":3, "text":uiScriptLocale.COSTUME_WINDOW_TITLE, "text_horizontal_align":"center" },
					),
				},

				## Equipment Slot
				{
					"name" : "Costume_Base",
					"type" : "image",

					"x" : 13,
					"y" : 38,
				
					"image" : uiScriptLocale.LOCALE_UISCRIPT_PATH + "costume/new_costume_bg.jpg",					

					"children" :
					(

						{
							"name" : "CostumeSlot",
							"type" : "slot",

							"x" : 3,
							"y" : 3,

							"width" : 127,
							"height" : 145 + 47,

							"slot" : (
										{"index":COSTUME_START_INDEX+0, "x":62, "y":45, "width":32, "height":64},#몸
										{"index":COSTUME_START_INDEX+1, "x":62, "y": 9, "width":32, "height":32},#머리
										{"index":COSTUME_START_INDEX+2, "x":13, "y":126, "width":32, "height":32},#마운트
										{"index":COSTUME_START_INDEX+3, "x":62, "y":126, "width":32, "height":32},#악세서리
										{"index":COSTUME_START_INDEX+4, "x":13, "y":13, "width":32, "height":96},#악세서리
										#{"index":item.COSTUME_SLOT_WEAPON, "x":13, "y":13, "width":32, "height":96},#무기
									),
						},
					),
				},
			),
		},
	),
}
	

 

 

Edited by Metin2 Dev
Core X - External 2 Internal
Link to comment
Share on other sites

  • Replies 3
  • Created
  • Last Reply

Top Posters In This Topic

To fix the position it's easy:


										{"index":COSTUME_START_INDEX+2, "x":13, "y":126, "width":32, "height":32},#마운트
										{"index":COSTUME_START_INDEX+3, "x":62, "y":126, "width":32, "height":32},#악세서리

on this too, just change the "x" with the other.

 

 

 

About summoning the mount when you use it, you will need to search when you use the item and equip it, the part where it's calling the mount you can have done something wrong.

It could also be something with the riding quests if you do not have the mount like horse system.

It's all lies

Link to comment
Share on other sites

15 godzin temu, displayjokes napisał:

To fix the position it's easy:



										{"index":COSTUME_START_INDEX+2, "x":13, "y":126, "width":32, "height":32},#마운트
										{"index":COSTUME_START_INDEX+3, "x":62, "y":126, "width":32, "height":32},#악세서리

on this too, just change the "x" with the other.

 

 

 

About summoning the mount when you use it, you will need to search when you use the item and equip it, the part where it's calling the mount you can have done something wrong.

It could also be something with the riding quests if you do not have the mount like horse system.

i added full code after channge to main post, everything is 1:1 to this tutorial

can you help me? i use the same quest from this thread.

Link to comment
Share on other sites

On 7/18/2019 at 9:06 AM, Traceur3RUN said:

i added full code after channge to main post, everything is 1:1 to this tutorial

can you help me? i use the same quest from this thread.

In the quest, you are sending the itemVnum to the Ride function and 0 remaining time, this means you are mounting for 0 seconds i believe, try to put something like 60, it should be mounting for 1 minute, then if it works, you can play with the value however you like

 

You have this when you use the item:

ride.Ride(item.vnum, 0)

And you have this when you login:


            local vnum, remain_time = pc.get_special_ride_vnum()

            if 0 != vnum then
                ride.Ride(vnum, remain_time)
            end

 

Maybe you can use the same method instead of forcing the time ;)

It's all lies

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

Announcements



×
×
  • 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.