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); 
					    }		
				    }
			    }
			}
		}
	}				
}
Esempio n. 2
0
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);
    }
}