Example #1
0
void __cdecl MonsterDie(LPOBJ lpObj, LPOBJ lpTargetObj)
{
    if(OBJECT_MAXRANGE(lpTargetObj->m_Index) == FALSE)
	{
        return;
	}

    if(OBJECT_MAXRANGE(lpObj->m_Index) == FALSE)
	{
        return;
	}

    PCPoint.RewardsPointsKillMob(lpTargetObj,lpObj,PCPOINT);
    PCPoint.RewardsPointsKillMob(lpTargetObj,lpObj,WCOIN);

    int Proc = 0;

    if( MapSystem.Maps[lpTargetObj->MapNumber].Drop )
    {
        Proc += MapSystem.Maps[lpObj->MapNumber].Drop;
    }

    int IsHappyHour = HappyHour.IsHappyHour(lpTargetObj->MapNumber);

    if(IsHappyHour)
    {
        Proc += HappyHour.HappyStruct[IsHappyHour].P_Drop;
    }

    Proc += PlayerSystem.GetBonus(lpTargetObj, b_DROP);

    if(Vip.Config.Enabled)
    {
        Proc += Vip.GetBonus(lpTargetObj, b_DROP);
    }

    lpObj->m_wItemDropRate += (lpObj->m_wItemDropRate*Proc)/100;

    if(lpObj->m_wItemDropRate > 100)
    {
        lpObj->m_wItemDropRate = 100;
    }

    gObjMonsterDieGiveItem(lpObj,lpTargetObj);
}
bool cDuelSystem::IsDuelEnable(int aIndex)
{
    OBJECTSTRUCT * gObj = (OBJECTSTRUCT*)OBJECT_POINTER(aIndex);

    if(OBJECT_MAXRANGE(aIndex) == FALSE)
    {
        return false;
    }

    if(Utilits.gObjIsConnected(aIndex) == TRUE)
    {
        if((gObj->m_Option & 2) == 2)
        {
            return true;
        }
    }

    return false;
}
void cDuelSystem::RecvDuelAnswer(LPOBJ lpObj, PMSG_DUEL_ANSWER_START* lpMsg)
{
    int iDuelIndex = -1;

    int aIndex = lpObj->m_Index;

    int iDuelRoom = AddTab[aIndex].DUEL_Room;

    PMSG_DUEL_START pMsgSend;

    pMsgSend.h.c		= 0xC1;
    pMsgSend.h.headcode = 0xAA;
    pMsgSend.h.subcode  = 0x01;
    pMsgSend.bDuelStart = 0;
    pMsgSend.h.size		= sizeof(pMsgSend);

    LPOBJ gObjg    = (LPOBJ)OBJECT_POINTER(aIndex);

    if(iDuelRoom < 0 || iDuelRoom > MAX_DUEL_ROOMS - 1)
    {
        return;
    }

    if(gObjg->CloseType != -1)
    {
        return;
    }

    iDuelIndex = MAKE_NUMBERW(lpMsg->NumberH, lpMsg->NumberL); // aIndex Packet C1 XX AA

    OBJECTSTRUCT *gObjs = (OBJECTSTRUCT*)OBJECT_POINTER(iDuelIndex);

    if(iDuelIndex <= 7999 || lpObj->m_Index <= 7999)
    {
        return;
    }

    if(OBJECT_MAXRANGE(iDuelIndex))
    {
        if(!Utilits.gObjIsConnected(iDuelIndex))
        {
            return;
        }

        if(gObjs->Type == OBJECT_MONSTER)
        {
            return;
        }

        if(gObjs->CloseCount >= 0)
        {
            return;
        }

        if(lpMsg->bDuelOK)
        {
            if
            (
                (gObjs->MapNumber >= 11 && gObjs->MapNumber <= 17) || gObjs->MapNumber == 52  ||
                (gObjs->MapNumber >= 18 && gObjs->MapNumber <= 23) || gObjs->MapNumber == 53 ||
                gObjs->MapNumber == 9 || gObjs->MapNumber == 32 ||
                (gObjs->MapNumber >= 45 && gObjs->MapNumber <= 50)
            )
            {
                GCServerMsgStringSend("Duels are not allowed in event maps.", lpObj->m_Index, 1);

                this->RoomReset(iDuelRoom, true, true);

                memcpy(pMsgSend.szName, lpObj->Name, sizeof(pMsgSend.szName));

                DataSend(iDuelIndex, (LPBYTE)&pMsgSend, pMsgSend.h.size);

                return;
            }
        }

        if(OBJECT_MAXRANGE(lpObj->m_iDuelUser))
        {
            GCServerMsgStringSend("You are already in a Duel.", lpObj->m_Index, 1);
            GCServerMsgStringSend("In order to issue a Duel, cancel the previous request.", lpObj->m_Index, 1);

            this->RoomReset(iDuelRoom, true, true);

            memcpy(pMsgSend.szName, lpObj->Name, sizeof(pMsgSend.szName));

            DataSend(iDuelIndex, (LPBYTE)&pMsgSend, pMsgSend.h.size);

            return;
        }

        if(OBJECT_MAXRANGE(lpObj->m_iDuelUserReserved))
        {
            GCServerMsgStringSend("You are already issuing a Duel challenge.", lpObj->m_Index, 1);

            this->RoomReset(iDuelRoom, true, true);

            memcpy(pMsgSend.szName, lpObj->Name, sizeof(pMsgSend.szName));

            DataSend(iDuelIndex, (LPBYTE)&pMsgSend, pMsgSend.h.size);

            return;
        }
        if(gObjs->m_iDuelUserReserved == lpObj->m_Index)
        {
            char szDuelName[MAX_ACCOUNT_LEN + 1]  = {0};
            char szDuelName2[MAX_ACCOUNT_LEN + 1] = {0};

            memcpy(szDuelName, gObjs->Name, MAX_ACCOUNT_LEN);

            szDuelName[MAX_ACCOUNT_LEN] = 0;

            memcpy(szDuelName2, lpMsg->szName, MAX_ACCOUNT_LEN);

            szDuelName2[MAX_ACCOUNT_LEN] = 0;

            if(!strcmp(szDuelName, szDuelName2))
            {
                if(lpMsg->bDuelOK == false)
                {
                    this->RoomReset(iDuelRoom, true, true);

                    pMsgSend.bDuelStart = 0x0F;

                    memcpy(pMsgSend.szName, lpObj->Name, sizeof(pMsgSend.szName));

                    DataSend(iDuelIndex, (LPBYTE)&pMsgSend, pMsgSend.h.size);
                }

                else if (lpMsg->bDuelOK == true)
                {
                    if(gObjMoveGate(lpObj->m_Index, g_DuelGates[iDuelRoom].Gate01) == false)
                    {
                        this->RoomReset(iDuelRoom, true, true);

                        return;
                    }

                    if(gObjMoveGate(iDuelIndex, g_DuelGates[iDuelRoom].Gate02) == false)
                    {
                        this->RoomReset(iDuelRoom, true, true);

                        return;
                    }

                    gObjs->m_iDuelUserReserved	= -1;
                    gObjs->m_btDuelScore		= 0;
                    gObjs->m_iDuelUser			= lpObj->m_Index;
                    gObjs->m_iDuelTickCount		= GetTickCount();

                    this->g_DuelRooms[iDuelRoom].dwStartTime	= GetTickCount();
                    this->g_DuelRooms[iDuelRoom].dwTicketCount  = GetTickCount() + (MAX_DUEL_TIME * 60000);

                    lpObj->m_iDuelUserRequested = -1;
                    lpObj->m_iDuelUserReserved  = -1;
                    lpObj->m_btDuelScore		= 0;
                    lpObj->m_iDuelUser			= iDuelIndex;
                    lpObj->m_iDuelTickCount		= GetTickCount();

                    this->g_DuelRooms[iDuelRoom].RoomFree		= FALSE;
                    this->g_DuelRooms[iDuelRoom].DuelWaiting	= FALSE;
                    this->g_DuelRooms[iDuelRoom].szWinner		= FALSE;

                    pMsgSend.bDuelStart		= 0;
                    pMsgSend.NumberH		= SET_NUMBERH(iDuelIndex);
                    pMsgSend.NumberL		= SET_NUMBERL(iDuelIndex);

                    memcpy(pMsgSend.szName, szDuelName, sizeof(pMsgSend.szName));

                    DataSend(lpObj->m_Index, (LPBYTE)&pMsgSend, pMsgSend.h.size);

                    pMsgSend.NumberH		= SET_NUMBERH(lpObj->m_Index);
                    pMsgSend.NumberL		= SET_NUMBERL(lpObj->m_Index);

                    memcpy(pMsgSend.szName, lpObj->Name, sizeof(pMsgSend.szName));

                    DataSend(iDuelIndex, (LPBYTE)&pMsgSend, pMsgSend.h.size);

                    this->UpdateDuelScore(iDuelRoom);

                    Chat.MessageAllLog(0, 0, c_Cyan, t_Duel, lpObj, "Duelo %s VS %s na sala %d!", lpObj->Name, gObjs->Name, iDuelRoom + 1);

                    Log.ConsoleOutPut(1, c_Blue,t_Duel,"[Duel System] Duel Started [%s][%s] VS [%s][%s] on Room[%d]",lpObj->AccountID, lpObj->Name, gObjs->AccountID, gObjs->Name, iDuelRoom + 1);
                }
            }
            else
            {
                this->RoomReset(iDuelRoom);
                DataSend(iDuelIndex, (LPBYTE)&pMsgSend, pMsgSend.h.size);

                return;
            }
        }
        else
        {
            this->RoomReset(iDuelRoom);
            DataSend(iDuelIndex, (LPBYTE)&pMsgSend, pMsgSend.h.size);

            return;
        }
    }
}
void cDuelSystem::RecvDuelRequest(LPOBJ lpObj, PMSG_DUEL_REQUEST_START* lpMsg)
{
    int iDuelIndex = MAKE_NUMBERW(lpMsg->NumberH, lpMsg->NumberL);

    OBJECTSTRUCT *gObjs = (OBJECTSTRUCT*)OBJECT_POINTER(iDuelIndex);

    if(!OBJECT_MAXRANGE(iDuelIndex))
    {
        Log.ConsoleOutPut(1, c_Blue, t_Duel,"[Duel System] [%s][%s] Try duel with NO_PLAYER object!", lpObj->AccountID, lpObj->Name);

        return;
    }

    if(iDuelIndex == lpObj->m_Index)
    {
        return;
    }

    if(iDuelIndex <= 7999 || lpObj->m_Index <= 7999)
    {
        return;
    }

    char Buff[256];

    if(lpObj->CloseType != -1)
    {
        return;
    }

    if(GetPrivateProfileInt("GameServerInfo", "NonPK", 0 , GS_CONFIG_FILE) == 1)
    {
        GCServerMsgStringSend("Dueling is not allowed in NON-PK servers.", lpObj->m_Index, 1);
        return;
    }

    if(GetPrivateProfileInt("GameServerInfo","PkLimitFree", 1, GS_CONFIG_FILE) == 0)
    {
        if(lpObj->m_PK_Level >= 6)
        {
            GCServerMsgStringSend("An outlaw can't issue a Duel challenge.", lpObj->m_Index, 1);
            return;
        }

        if(gObjs->m_PK_Level >= 6)
        {
            GCServerMsgStringSend("You cannot Duel with an Outlaw.", lpObj->m_Index, 1);
            return;
        }
    }

    if(OBJECT_MAXRANGE(lpObj->m_iDuelUser))
    {
        GCServerMsgStringSend("You are already in a Duel.", lpObj->m_Index, 1);
        GCServerMsgStringSend("In order to issue a Duel, cancel the previous request.", lpObj->m_Index, 1);
        return;
    }

    if(gObjs->MapNumber == 9 || gObjs->MapNumber == 32)
    {
        GCServerMsgStringSend("A duel is not allowed in Devil Square.", lpObj->m_Index, 1);
        return;
    }

    if((gObjs->MapNumber >= 11 && gObjs->MapNumber <= 17) || gObjs->MapNumber == 52)
    {
        GCServerMsgStringSend("You cannot Duel inside Blood Castle.", lpObj->m_Index, 1);
        return;
    }

    if((gObjs->MapNumber >= 18 && gObjs->MapNumber <= 23) || gObjs->MapNumber == 53)
    {
        GCServerMsgStringSend("Duels are not allowed within Chaos Castle.", lpObj->m_Index, 1);
        return;
    }

    if((gObjs->MapNumber >= 45 && gObjs->MapNumber <= 50))
    {
        GCServerMsgStringSend("Duels are not allowed in Illusion Temple", lpObj->m_Index, 1);
        return;
    }

    if(lpObj->Level < 30 || gObjs->Level < 30)
    {
        PMSG_DUEL_START pMsgSend;

        pMsgSend.h.c		= 0xC1;
        pMsgSend.h.headcode = 0xAA;
        pMsgSend.h.subcode  = 0x01;
        pMsgSend.bDuelStart = 0x0C;
        pMsgSend.h.size		= sizeof(pMsgSend);

        DataSend(lpObj->m_Index, (BYTE*)&pMsgSend, pMsgSend.h.size);

        return;
    }

    if(lpObj->Money < 30000 || gObjs->Money < 30000)
    {
        PMSG_DUEL_START pMsgSend;

        pMsgSend.h.c		= 0xC1;
        pMsgSend.h.headcode = 0xAA;
        pMsgSend.h.subcode  = 0x01;
        pMsgSend.bDuelStart = 0x1e;
        pMsgSend.h.size		= sizeof(pMsgSend);

        DataSend(lpObj->m_Index, (BYTE*)&pMsgSend, pMsgSend.h.size);

        return;
    }

    int iDuelRoom = this->GetFreeRoomIndex();

    if(iDuelRoom == -1)
    {
        PMSG_DUEL_START pMsgSend;

        pMsgSend.h.c		= 0xC1;
        pMsgSend.h.headcode = 0xAA;
        pMsgSend.h.subcode  = 0x01;
        pMsgSend.bDuelStart = 0x10;
        pMsgSend.h.size		= sizeof(pMsgSend);

        DataSend(lpObj->m_Index, (BYTE*)&pMsgSend, pMsgSend.h.size);

        return;
    }

    if((GetTickCount() - gObjs->m_PacketCheckTime) < 300)
    {
        return;
    }

    lpObj->m_PacketCheckTime = GetTickCount();

    char szDuelName[MAX_ACCOUNT_LEN + 1]  = {0};
    char szDuelName2[MAX_ACCOUNT_LEN + 1] = {0};

    memcpy(szDuelName, gObjs->Name, MAX_ACCOUNT_LEN);

    szDuelName[MAX_ACCOUNT_LEN]  = 0;

    memcpy(szDuelName2, lpMsg->szName, MAX_ACCOUNT_LEN);

    szDuelName2[MAX_ACCOUNT_LEN] = 0;

    if(strcmp(szDuelName, szDuelName2) != 0)
    {
        return;
    }

    if(this->IsDuelEnable(iDuelIndex) == FALSE)
    {
        GCServerMsgStringSend("Your challenge to Duel has been refused.", lpObj->m_Index, 1);
        return;
    }

    if(lpObj->lpGuild && lpObj->lpGuild->WarState == 1)
    {
        GCServerMsgStringSend("You cannot challenge someone to a duel while in a guild war.", lpObj->m_Index, 1);
        return;
    }

    if(gObjs->lpGuild && gObjs->lpGuild->WarState == 1)
    {
        GCServerMsgStringSend("Your opponent cannot duel while in a guild war.", lpObj->m_Index, 1);
        return;
    }

    if(Utilits.gObjIsConnected(iDuelIndex) == FALSE)
    {
        return;
    }

    if(gObjs->Type == OBJECT_MONSTER)
    {
        return;
    }

    if(gObjs->CloseCount >= 0)
    {
        return;
    }

    for(int n = 0; n < 5; n++)
    {
        if(lpObj->SelfDefense[n] >= 0 || gObjs->SelfDefense[n] >= 0)
        {
            GCServerMsgStringSend("Self-defense is active. You cannot Duel.", lpObj->m_Index, 1);

            return;
        }
    }

    if(lpObj->m_IfState.use > 0)
    {
        GCServerMsgStringSend("You cannot Duel while trading.", lpObj->m_Index, 1);

        return;
    }

    if(gObjs->m_IfState.use > 0)
    {
        wsprintf(Buff, "%s is trading an item.", gObjs->Name);

        GCServerMsgStringSend(Buff, lpObj->m_Index, 1);

        return;
    }

    if(OBJECT_MAXRANGE(gObjs->m_iDuelUserRequested))
    {
        wsprintf(Buff,"%s has already accepted a challenge to Duel.", gObjs->Name);

        GCServerMsgStringSend(Buff, lpObj->m_Index, 1);

        return;
    }

    if(OBJECT_MAXRANGE(gObjs->m_iDuelUserReserved))
    {
        wsprintf(Buff, "%s issues a Duel challenge.", gObjs->Name);

        GCServerMsgStringSend(Buff, lpObj->m_Index, 1);

        return;
    }

    if(OBJECT_MAXRANGE(gObjs->m_iDuelUser))
    {
        wsprintf(Buff, "%s is in a Duel.", gObjs->Name);

        GCServerMsgStringSend(Buff, lpObj->m_Index, 1);

        return;
    }

    lpObj->m_iDuelUser						 = -1;
    lpObj->m_iDuelUserReserved				 = iDuelIndex;
    gObjs->m_iDuelUserRequested				 = lpObj->m_Index;
    int aIndex								 = lpObj->m_Index;

    AddTab[aIndex].DUEL_Room	 = iDuelRoom;
    int uIndex								 = gObjs->m_Index;
    AddTab[uIndex].DUEL_Room	 = iDuelRoom;

    this->g_DuelRooms[iDuelRoom].szlpObjOne  = lpObj;
    this->g_DuelRooms[iDuelRoom].szlpObjTy   = gObjs;
    this->g_DuelRooms[iDuelRoom].DuelWaiting = TRUE;

    PMSG_DUEL_QUESTION_START pMsg;

    pMsg.h.c			= 0xC1;
    pMsg.h.headcode		= 0xAA;
    pMsg.h.subcode		= 0x02;
    pMsg.h.size			= sizeof(pMsg);
    pMsg.NumberH		= SET_NUMBERH(lpObj->m_Index);
    pMsg.NumberL		= SET_NUMBERL(lpObj->m_Index);

    memcpy(pMsg.szName, lpObj->Name, sizeof(pMsg.szName));

    DataSend(iDuelIndex, (LPBYTE)&pMsg, pMsg.h.size);

    wsprintf(Buff, "Challenged %s to a Duel.", gObjs->Name);

    GCServerMsgStringSend(Buff, lpObj->m_Index, 1);

    if(Config.Logging)
    {
        Log.ConsoleOutPut(1, c_Blue, t_Duel,"[Duel System][%s][%s] Requested to Start Duel to [%s][%s] on Room [%d]",lpObj->AccountID, lpObj->Name, gObjs->AccountID, gObjs->Name, iDuelRoom + 1);
    }
}