// ---------------------------------------------------------------------------------------- void CDoubleGoer::CheckCanEnter(int aIndex) { LPOBJ lpObj = &gObj[aIndex]; // ---- if ( lpObj->Type != OBJ_USER ) { return; } if ( gDoubleGoer.Enabled == 0 ) { SendMsg.MessageOut(aIndex, 0x01, "[DoubleGoer]: Event is disabled"); return; } if ( gDoubleGoer.Running == 1 ) { SendMsg.MessageOut(aIndex, 0x01, "[DoubleGoer]: Event is running, please try later"); return; } if ( gObjGetItemCountInIventory(aIndex,14,111,0) < 1 ) { SendMsg.MessageOut(aIndex, 0x01, "[DoubleGoer]: Need Mirror of Dimensions to enter"); return; } gObjDelteItemCountInInventory(aIndex,14,111,1); gDoubleGoer.Teleport(aIndex); }
BYTE CQuestInfo::QuestClearConditionCheck(LPOBJ lpObj, int QuestIndex) { LPQUEST_INFO lpQuestInfo = this->GetQuestInfo(QuestIndex); if ( lpQuestInfo == NULL ) { return -1; } int subquestcount = lpQuestInfo->QuestSubInfoCount; int concount = lpQuestInfo->QuestConditionCount; LPQUEST_SUB_INFO lpSubInfo; BOOL bFoundSubQuest = FALSE; for ( int subquest=0;subquest<subquestcount;subquest++) { lpSubInfo = this->GetSubquestInfo(lpObj, lpQuestInfo, subquest); if ( lpSubInfo != NULL ) { bFoundSubQuest = TRUE; if ( lpSubInfo->QuestType == 1 ) { int NumberItemQuestFound = gObjGetItemCountInIventory(lpObj->m_Index, lpSubInfo->NeedType, lpSubInfo->NeedSubType, lpSubInfo->ItemLevel); if ( NumberItemQuestFound < lpSubInfo->NeedNumber) { return 1; } } else if ( lpSubInfo->QuestType == 2) { int NumberMonsterKillCount = this->GetQuestKillCount(lpObj, lpSubInfo->NeedType); if ( NumberMonsterKillCount < lpSubInfo->NeedNumber) { return 1; } } } } if ( bFoundSubQuest == FALSE ) { return -1; } return 0; }
int CJewelMixSystem::GetJewelCount(int iIndex, int iJewelType) { if ( !gObjIsConnected(iIndex) ) return -1; int iItemType; switch ( iJewelType ) { case 0: iItemType = ITEMGET(14,13); break; case 1: iItemType = ITEMGET(14,14); break; case 2: iItemType = ITEMGET(14,16); break; case 3: iItemType = ITEMGET(14,22); break; case 4: iItemType = ITEMGET(14,31); break; case 5: iItemType = ITEMGET(14,41); break; case 6: iItemType = ITEMGET(14,42); break; case 7: iItemType = ITEMGET(12,15); break; case 8: iItemType = ITEMGET(14,43); break; case 9: iItemType = ITEMGET(14,44); break; default: return -1; } int iItemCount = gObjGetItemCountInIventory(iIndex, iItemType); return iItemCount; }
int CJewelMixSystem::GetJewelCount(int iIndex, int iJewelType) { if ( !gObjIsConnected(iIndex) ) return -1; int iItemType; switch ( iJewelType ) { case 0: iItemType = ITEMGET(14,13); break; case 1: iItemType = ITEMGET(14,14); break; default: return -1; } int iItemCount = gObjGetItemCountInIventory(iIndex, iItemType); return iItemCount; }
BOOL CQuestInfo::MonsterItemDrop(LPOBJ lpObj) { int MaxHitUser = gObjMonsterTopHitDamageUser(lpObj); if ( MaxHitUser == -1 ) { return false; } int partycount = gParty.GetPartyCount(gObj[MaxHitUser].PartyNumber); if ( partycount > 0 ) { return false; } LPOBJ lpTarget = &gObj[MaxHitUser]; int questcount = this->GetQeustCount(); int foundquest = 0; LPQUEST_INFO lpQuestInfo; LPQUEST_SUB_INFO lpSubInfo; int type; int level; int x; int y; float dur = 0; int Option1 = 0; int Option2 = 0; int Option3 = 0; for ( int i=0;i<MAX_QUEST_INFO;i++) { lpQuestInfo = this->GetQuestInfo(i); if ( lpQuestInfo == NULL ) { continue; } for ( int n =0;n<lpQuestInfo->QuestSubInfoCount;n++) { lpSubInfo = this->GetSubquestInfo(lpTarget, lpQuestInfo, n); if ( lpSubInfo != NULL ) { if ( lpSubInfo->QuestType == 1 && lpSubInfo->NeedTargetMinLevel != -1 ) //Third Quest Fix, only READS Monster Level Min and Max if Level Min is != 1 { if ( lpObj->Level >= lpSubInfo->NeedTargetMinLevel) { if ( lpObj->Level <= lpSubInfo->NeedTargetMaxLevel ) { if ( this->GetQuestState(lpTarget, lpQuestInfo->QuestIndex) == TRUE ) { if ( (rand() % ITEM_QUEST_DROP_PROBABILITY) < lpSubInfo->NeedDropRate) { int itemcount = gObjGetItemCountInIventory(MaxHitUser, lpSubInfo->NeedType, lpSubInfo->NeedSubType, lpSubInfo->ItemLevel); if ( itemcount >= lpSubInfo->NeedNumber) { continue; } dur = 0; x = lpObj->X; y = lpObj->Y; level = lpSubInfo->ItemLevel; type = ItemGetNumberMake(lpSubInfo->NeedType, lpSubInfo->NeedSubType); ItemSerialCreateSend(lpObj->m_Index, lpObj->MapNumber, x, y, type, level, dur, Option1, Option2, Option3, MaxHitUser, 0, 0); LogAddTD("[Quest] Quest Item Drop [%s]: [%s][%s] (%s) (%d,%d)", lpObj->Name, lpTarget->AccountID, lpTarget->Name, lpQuestInfo->Name, lpSubInfo->NeedType, lpSubInfo->NeedSubType); qMsg->Msg(lpObj->m_Index, "@[Quest] Your item droped."); return true; } } } } } //Start of S3 Quest if ( lpSubInfo->QuestType == 1 && lpSubInfo->NeedTargetMinLevel == -1 ) //Third Quest { if ( lpObj->Class == lpSubInfo->NeedTargetMaxLevel) //READS Monster Class on TargetMax Level Category (for Original Quest.txt) { if ( this->GetQuestState(lpTarget, lpQuestInfo->QuestIndex) == TRUE ) { if ( (rand() % ITEM_QUEST_DROP_PROBABILITY) < lpSubInfo->NeedDropRate) { int itemcount = gObjGetItemCountInIventory(MaxHitUser, lpSubInfo->NeedType, lpSubInfo->NeedSubType, lpSubInfo->ItemLevel); if ( itemcount >= lpSubInfo->NeedNumber) { continue; } dur = 0; x = lpObj->X; y = lpObj->Y; level = lpSubInfo->ItemLevel; type = ItemGetNumberMake(lpSubInfo->NeedType, lpSubInfo->NeedSubType); ItemSerialCreateSend(lpObj->m_Index, lpObj->MapNumber, x, y, type, level, dur, Option1, Option2, Option3, MaxHitUser, 0, 0); LogAddTD("[Season3 Quest] Quest Item Drop [%s]: [%s][%s] (%s) (%d,%d)", lpObj->Name, lpTarget->AccountID, lpTarget->Name, lpQuestInfo->Name, lpSubInfo->NeedType, lpSubInfo->NeedSubType); return true; } } } } if ( lpSubInfo->QuestType == 2 && lpSubInfo->NeedTargetMinLevel == -1 ) //Third Quest for Kill Count { if ( lpObj->Class == lpSubInfo->NeedTargetMaxLevel) //READS Monster Class on TargetMax Level Category (for Original Quest.txt) { if ( this->GetQuestState(lpTarget, lpQuestInfo->QuestIndex) == TRUE ) { if( lpTarget->m_Quest[1] == 0xF6 && lpTarget->MapNumber == 41 ) { if( lpTarget->m_Quest[30] > 10) { lpTarget->m_Quest[30] = 0; } if( lpTarget->m_Quest[31] > 10 ) { lpTarget->m_Quest[31] = 0; } if( lpTarget->m_Quest[32] > 10 ) { lpTarget->m_Quest[32] = 0; } if(lpObj->Class == 409 && lpTarget->m_Quest[30] < 10) { lpTarget->m_Quest[30] += 1; MsgOutput(lpTarget->m_Index, "[Quest] (%d/10) Balram(Hero)", lpTarget->m_Quest[30]); } if(lpObj->Class == 410 && lpTarget->m_Quest[31] < 10) { lpTarget->m_Quest[31] += 1; MsgOutput(lpTarget->m_Index, "[Quest] (%d/10) Death Spirit(Hero)", lpTarget->m_Quest[31]); } if(lpObj->Class == 411 && lpTarget->m_Quest[32] < 10) { lpTarget->m_Quest[32] += 1; lpTarget->m_Quest[34] += 1; MsgOutput(lpTarget->m_Index, "[Quest] (%d/10) Soram(Hero).", lpTarget->m_Quest[32]); } } if( lpTarget->m_Quest[1] == 0xDA && lpTarget->MapNumber == 42 ) { if( lpTarget->m_Quest[34] > 1 ) { lpTarget->m_Quest[34] = 0; } if(lpObj->Class == 412 && lpTarget->m_Quest[34] < 1) { lpTarget->m_Quest[34] += 1; MsgOutput(lpTarget->m_Index, "[Quest] (%d/1) Dark Elf(Hero)", lpTarget->m_Quest[34]); } } //End of S3 Quest } } } // } } foundquest++; if ( foundquest == questcount ) { break; } } return false; }
BOOL CJewelMixSystem::MixJewel( int iIndex, int iJewelType, int iMixType) { if ( !gObjIsConnected(iIndex)) return FALSE; if ( gObjCheckInventorySerial0Item(&gObj[iIndex])) { MsgOutput(iIndex, lMsg.Get(MSGGET(13,26))); GCAnsJewelMix(iIndex, 4); LogAddTD("[ANTI-HACK][Serial 0 Item] [Mix Jewel] (%s)(%s)", gObj[iIndex].AccountID, gObj[iIndex].Name); return FALSE; } if ( gObj[iIndex].m_IfState.type == 1 ) { LogAddTD("[JewelMix] [%s][%s] Attempted ItemCopy using Trade Window", gObj[iIndex].AccountID, gObj[iIndex].Name); return FALSE; } if ( gObj[iIndex].ChaosLock == TRUE ) { LogAddTD("[JewelMix] [%s][%s] Chaos Mix is already working", gObj[iIndex].AccountID, gObj[iIndex].Name); GCAnsJewelMix(iIndex, 0); return FALSE; } gObj[iIndex].ChaosLock = TRUE; if ( !CHECK_LIMIT(iJewelType, 10) ) { LogAddTD("[JewelMix] [%s][%s] Mix iJewelType is out of bound : %d", gObj[iIndex].AccountID, gObj[iIndex].Name, iJewelType); gObj[iIndex].ChaosLock = FALSE; GCAnsJewelMix(iIndex, 2); return FALSE; } if ( !CHECK_LIMIT(iMixType, 3)) { LogAddTD("[JewelMix] [%s][%s] iMixType is out of bound : %d", gObj[iIndex].AccountID, gObj[iIndex].Name, iMixType); gObj[iIndex].ChaosLock = FALSE; GCAnsJewelMix(iIndex, 3); return FALSE; } int iItemType = g_JewelMixInfo[iJewelType][iMixType].m_iSourceType; int iJewelCount = g_JewelMixInfo[iJewelType][iMixType].m_iJewelCount; int iMixMoney = g_JewelMixInfo[iJewelType][iMixType].m_iMixMoney; int iChangeType = g_JewelMixInfo[iJewelType][iMixType].m_iChangeType; if ( iJewelCount <= 0 ) { gObj[iIndex].ChaosLock = FALSE; GCAnsJewelMix(iIndex, 0); return FALSE; } int iUserJewelCount = gObjGetItemCountInIventory(iIndex, iItemType); if ( iJewelCount > iUserJewelCount ) { LogAddTD("[JewelMix] [%s][%s] lack of jewel to mix : %d / %d", gObj[iIndex].AccountID, gObj[iIndex].Name, iUserJewelCount, iJewelCount); gObj[iIndex].ChaosLock = FALSE; GCAnsJewelMix(iIndex, 4); return FALSE; } if ( iMixMoney > gObj[iIndex].Money ) { LogAddTD("[JewelMix] [%s][%s] lack of money to mix : %d / %d", gObj[iIndex].AccountID, gObj[iIndex].Name, gObj[iIndex].Money, iMixMoney); gObj[iIndex].ChaosLock = FALSE; GCAnsJewelMix(iIndex, 5); return FALSE; } int iDelJewelCount = 0; BOOL bItemDelOK = FALSE; int invSize = MAIN_INVENTORY_SIZE; if( gObj[iIndex].pInventoryExtend <= 4 ) { invSize = (MAIN_INVENTORY_SIZE)-(32*(4-gObj[iIndex].pInventoryExtend)); } for ( int x= INVETORY_WEAR_SIZE ; x< invSize; x++) { if ( gObj[iIndex].pInventory[x].IsItem() == TRUE ) { if ( gObj[iIndex].pInventory[x].m_Type == iItemType ) { LogAddTD("[JewelMix] [%s][%s] Mix - Delete Jewel, Type:%d, Level:%d, Serial:%d", gObj[iIndex].AccountID, gObj[iIndex].Name, gObj[iIndex].pInventory[x].m_Type, gObj[iIndex].pInventory[x].m_Level, gObj[iIndex].pInventory[x].m_Number); gObjInventoryItemSet(iIndex, x, 0xFF); gObj[iIndex].pInventory[x].Clear(); iDelJewelCount++; if ( iJewelCount <= iDelJewelCount ) { bItemDelOK = TRUE; break; } } } } GCItemListSend(iIndex); if ( bItemDelOK == FALSE ) { LogAddTD("[JewelMix] [%s][%s] lack of jewel to mix (in deleting) : %d / %d", gObj[iIndex].AccountID, gObj[iIndex].Name, iDelJewelCount, iJewelCount); gObj[iIndex].ChaosLock = FALSE; GCAnsJewelMix(iIndex, 0); return FALSE; } ItemSerialCreateSend(iIndex, 235, gObj[iIndex].X, gObj[iIndex].Y, iChangeType, iMixType, 0, 0, 0, 0, iIndex, 0, 0); gObj[iIndex].ChaosLock = FALSE; gObj[iIndex].Money -= iMixMoney; GCMoneySend(iIndex, gObj[iIndex].Money); GCAnsJewelMix(iIndex, 1); LogAddTD("[JewelMix] [%s][%s] jewel mix succeed : ItemType:%d, JewelCount:%d", gObj[iIndex].AccountID, gObj[iIndex].Name, iItemType, iJewelCount); return TRUE; }
bool CQuest::NpcTalk(LPOBJ lpNpc, LPOBJ lpObj) { int iIndex = lpObj->m_Index; if( lpObj->q_QuestIndex == 0xFF) { this->SetQuestState(lpObj, 0 , QUEST_STATE_START); } int i = lpObj->q_QuestIndex; if(this->quests[i].npcID == lpNpc->Class) { if(lpObj->Level < this->quests[i].level) { wsprintf(szQuestTemp, " You're need be level %d for quest!",this->quests[i].level); ChatTargetSend(lpNpc,szQuestTemp, iIndex); return true; } if(lpObj->Money < this->quests[i].zen) { wsprintf(szQuestTemp, " you need zen %d for quest!",this->quests[i].zen); ChatTargetSend(lpNpc,szQuestTemp, iIndex); return true; } if(this->IsClass(i, lpObj->DbClass )) { for(int x = 0 ; x != this->quests->QuestsObjectCount ; x++) { switch(this->GetQuestType(i,x)) { case QUEST_OBJECT_TYPE_ITEM: { switch(lpObj->q_QuestState) { case QUEST_STATE_START: { int ItemType = this->quests[i].ItemsObject[x].itemType; int ItemSubType = this->quests[i].ItemsObject[x].itemSubType; LPITEM_ATTRIBUTE Item = &ItemAttribute[ITEMGET(ItemType, ItemSubType) ]; qMsg->Notice(iIndex , "[Quest] Quest Start. " ); qMsg->Notice(iIndex , "[Quest] %s go find %s !!!",this->quests[i].name,Item->Name); this->SetQuestState(lpObj, i , QUEST_STATE_ONGOING ); if(this->quests[i].zen > 0) { lpObj->Money -= this->quests[i].zen; GCMoneySend( iIndex , lpObj->Money ); } qMsg->PM( iIndex , "[Quest] Remmber you can do quest only without party"); qMsg->PM( iIndex , "[Quest] you need free slot in your invenotry for quest item"); return true; } case QUEST_STATE_ONGOING: { int ItemType = this->quests[i].ItemsObject[x].itemType; int ItemSubType = this->quests[i].ItemsObject[x].itemSubType; int GetCount = this->quests[i].ItemsObject[x].itemCount; LPITEM_ATTRIBUTE Item = &ItemAttribute[ITEMGET(ItemType, ItemSubType) ]; qMsg->PM(iIndex , "[Quest] You do not have enough required items"); qMsg->PM(iIndex , "[Quest] Search %d %s",GetCount,Item->Name); wsprintf(szQuestTemp, "Search %d %s",GetCount,Item->Name); ChatTargetSend(lpNpc , szQuestTemp , iIndex ); return true; } case QUEST_STATE_FINISH: { int ItemType = this->quests[i].ItemsObject[x].itemType; int ItemSubType = this->quests[i].ItemsObject[x].itemSubType; int Count = gObjGetItemCountInIventory(iIndex, ITEMGET(ItemType,ItemSubType)); int GetCount = this->quests[i].ItemsObject[x].itemCount; if(Count >= GetCount) { LPITEM_ATTRIBUTE Item = &ItemAttribute[ITEMGET(ItemType, ItemSubType) ]; qMsg->Notice(iIndex, "[Quest] You have been finished %s ",this->quests[i].name); gObjDelteItemCountInInventory(iIndex ,ItemType , ItemSubType , Count ); int PrizeCount = this->quests[i].ItemsObject[x].QuestPrizeCount; int uPoint = 0; int uClassUp = 0; for(int p = 0 ; p != PrizeCount ; p++) { int Points = this->quests[i].ItemsObject[x].QuestPrize[p].points; int ClassUp = this->quests[i].ItemsObject[x].QuestPrize[p].ClassUp; if(Points > 0) uPoint += Points; if(ClassUp > 0 ) uClassUp += ClassUp; } if(uPoint > 0) { qMsg->Msg(iIndex , "[Quest] you have received %d points",uPoint); lpObj->LevelUpPoint += uPoint; GCLevelUpMsgSend(iIndex, 201); this->SetQuestState(lpObj, lpObj->q_QuestIndex+1 , QUEST_STATE_START); } if(uClassUp > 0) { qMsg->PM(iIndex , "[Quest] congratulation you win Class up :)"); lpObj->ChangeUP += 1; lpObj->DbClass |= 1; gObjMakePreviewCharSet(lpObj->m_Index); BYTE btClass = (lpObj->Class * 32) & 224 ; btClass |= (lpObj->ChangeUP * 16) & 16; if(lpObj->ChangeUP == 1) GCSendQuestPrize(lpObj->m_Index, 201 , btClass); if(lpObj->ChangeUP == 2) GCSendQuestPrize(lpObj->m_Index, 204 , btClass); GCMagicAttackNumberSend(lpObj, 76 , lpObj->m_Index , 0 ); } } } } break; } } } } } return false; }