void CAIMobDummy::ActionDropItems() { if ((m_Tick - m_LastActionTime) > 1000 ) { m_ActionType = ACTION_DEATH; // TODO: условие не дописано. питомец персонажа тоже может убить монстра CCharEntity* PChar = (CCharEntity*)m_PMob->loc.zone->GetEntity(m_PMob->m_OwnerID & 0x0FFF, TYPE_PC); if (PChar != NULL) { // TODO: blu может выучить последнюю использованную монстром специальную атаку m_PMobSkill luautils::OnMobDeath(m_PMob, PChar); m_PMob->loc.zone->PushPacket(m_PMob, CHAR_INRANGE, new CMessageBasicPacket(PChar,m_PMob,0,0,6)); if (m_PMob->m_CallForHelp == 0) { uint32 exp = charutils::DistributeExperiencePoints(PChar, m_PMob); DropList_t* DropList = itemutils::GetDropList(m_PMob->m_DropID); if (DropList && DropList->size()) { for(DropList_t::const_iterator it = DropList->begin(); it != DropList->end(); ++it) { if(rand()%100 < it->DropRate) { PChar->PTreasurePool->AddItem(it->ItemID, m_PMob); } } } } } } }
void CMobEntity::DropItems() { CCharEntity* PChar = (CCharEntity*)GetEntity(m_OwnerID.targid, TYPE_PC); if (PChar != nullptr && PChar->id == m_OwnerID.id) { loc.zone->PushPacket(this, CHAR_INRANGE, new CMessageBasicPacket(PChar, this, 0, 0, MSGBASIC_DEFEATS_TARG)); if (!CalledForHelp()) { blueutils::TryLearningSpells(PChar, this); m_UsedSkillIds.clear(); if (m_giveExp) { charutils::DistributeExperiencePoints(PChar, this); } DropList_t* DropList = itemutils::GetDropList(m_DropID); //ShowDebug(CL_CYAN"DropID: %u dropping with TH Level: %u\n" CL_RESET, PMob->m_DropID, PMob->m_THLvl); if (DropList != nullptr && !getMobMod(MOBMOD_NO_DROPS) && DropList->size()) { for (uint8 i = 0; i < DropList->size(); ++i) { //THLvl is the number of 'extra chances' at an item. If the item is obtained, then break out. uint8 tries = 0; uint8 maxTries = 1 + (m_THLvl > 2 ? 2 : m_THLvl); uint8 bonus = (m_THLvl > 2 ? (m_THLvl - 2) * 10 : 0); while (tries < maxTries) { if (dsprand::GetRandomNumber(1000) < DropList->at(i).DropRate * map_config.drop_rate_multiplier + bonus) { PChar->PTreasurePool->AddItem(DropList->at(i).ItemID, this); break; } tries++; } } } // check for gil (beastmen drop gil, some NMs drop gil) if (CanDropGil() || (map_config.all_mobs_gil_bonus > 0 && getMobMod(MOBMOD_GIL_MAX) >= 0)) // Negative value of MOBMOD_GIL_MAX is used to prevent gil drops in Dynamis/Limbus. { charutils::DistributeGil(PChar, this); // TODO: REALISATION MUST BE IN TREASUREPOOL } //check for seal drops /* MobLvl >= 1 = Beastmen Seals ID=1126 >= 50 = Kindred Seals ID=1127 >= 75 = Kindred Crests ID=2955 >= 90 = High Kindred Crests ID=2956 */ uint16 Pzone = PChar->getZone(); bool validZone = ((Pzone > 0 && Pzone < 39) || (Pzone > 42 && Pzone < 134) || (Pzone > 135 && Pzone < 185) || (Pzone > 188 && Pzone < 255)); if (validZone && charutils::GetRealExp(PChar->GetMLevel(), GetMLevel()) > 0) { if (((PChar->StatusEffectContainer->HasStatusEffect(EFFECT_SIGNET) && conquest::GetInfluenceGraphics(PChar->loc.zone->GetRegionID()) < 64) || (PChar->StatusEffectContainer->HasStatusEffect(EFFECT_SANCTION) && PChar->loc.zone->GetRegionID() >= 28 && PChar->loc.zone->GetRegionID() <= 32) || (PChar->StatusEffectContainer->HasStatusEffect(EFFECT_SIGIL) && PChar->loc.zone->GetRegionID() >= 33 && PChar->loc.zone->GetRegionID() <= 40)) && m_Element > 0 && dsprand::GetRandomNumber(100) < 20) // Need to move to CRYSTAL_CHANCE constant { PChar->PTreasurePool->AddItem(4095 + m_Element, this); } // Todo: Avatarite and Geode drops during day/weather. Much higher chance during weather than day. // Item element matches day/weather element, not mob crystal. Lv80+ xp mobs can drop Avatarite. // Wiki's have conflicting info on mob lv required for Geodes. One says 50 the other 75. I think 50 is correct. if (dsprand::GetRandomNumber(100) < 20 && PChar->PTreasurePool->CanAddSeal() && !getMobMod(MOBMOD_NO_DROPS)) { //RULES: Only 1 kind may drop per mob if (GetMLevel() >= 75 && luautils::IsExpansionEnabled("ABYSSEA")) //all 4 types { switch (dsprand::GetRandomNumber(4)) { case 0: PChar->PTreasurePool->AddItem(1126, this); break; case 1: PChar->PTreasurePool->AddItem(1127, this); break; case 2: PChar->PTreasurePool->AddItem(2955, this); break; case 3: PChar->PTreasurePool->AddItem(2956, this); break; } } else if (GetMLevel() >= 70 && luautils::IsExpansionEnabled("ABYSSEA")) //b.seal & k.seal & k.crest { switch (dsprand::GetRandomNumber(3)) { case 0: PChar->PTreasurePool->AddItem(1126, this); break; case 1: PChar->PTreasurePool->AddItem(1127, this); break; case 2: PChar->PTreasurePool->AddItem(2955, this); break; } } else if (GetMLevel() >= 50) //b.seal & k.seal only { if (dsprand::GetRandomNumber(2) == 0) { PChar->PTreasurePool->AddItem(1126, this); } else { PChar->PTreasurePool->AddItem(1127, this); } } else { //b.seal only PChar->PTreasurePool->AddItem(1126, this); } } } } PChar->setWeaponSkillKill(false); StatusEffectContainer->KillAllStatusEffect(); // NOTE: this is called for all alliance / party members! luautils::OnMobDeath(this, PChar); } else { luautils::OnMobDeath(this, nullptr); } }