void CStatusEffectContainer::RemoveStatusEffect(uint32 id, bool silent)
{
    CStatusEffect* PStatusEffect = m_StatusEffectList.at(id);

    if (PStatusEffect->GetStatusID() >= EFFECT_FIRE_MANEUVER &&
        PStatusEffect->GetStatusID() <= EFFECT_DARK_MANEUVER &&
        m_POwner->objtype == TYPE_PC)
    {
        puppetutils::CheckAttachmentsForManeuver((CCharEntity*)m_POwner, PStatusEffect->GetStatusID(), false);
    }

    m_StatusEffectList.erase(m_StatusEffectList.begin() + id);
    luautils::OnEffectLose(m_POwner, PStatusEffect);

    m_POwner->delModifiers(&PStatusEffect->modList);
    m_POwner->UpdateHealth();

    if (m_POwner->objtype == TYPE_PC)
    {
        CCharEntity* PChar = (CCharEntity*)m_POwner;

        if (PStatusEffect->GetIcon() != 0)
        {
            UpdateStatusIcons();
			if (silent == false)
			{
				PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, PStatusEffect->GetIcon(), 0, 206));
			}
        }
		//check for latents
		PChar->PLatentEffectContainer->CheckLatentsFoodEffect();
		PChar->PLatentEffectContainer->CheckLatentsStatusEffect();
        PChar->PLatentEffectContainer->CheckLatentsRollSong(HasStatusEffectByFlag(EFFECTFLAG_SONG | EFFECTFLAG_ROLL));
		PChar->UpdateHealth();

        PChar->pushPacket(new CCharHealthPacket(PChar));
        PChar->pushPacket(new CCharSyncPacket(PChar));
    }
	else
	{
		if (silent == false && PStatusEffect->GetIcon() != 0 && ((PStatusEffect->GetFlag() & EFFECTFLAG_NO_LOSS_MESSAGE) == 0) && !m_POwner->isDead())
		{
			m_POwner->loc.zone->PushPacket(m_POwner, CHAR_INRANGE, new CMessageBasicPacket(m_POwner, m_POwner, PStatusEffect->GetIcon(), 0, 206));
		}
	}
    delete PStatusEffect;
}
Exemple #2
0
void CParty::DisbandParty()
{
	DisableSync();
	SetQuaterMaster(NULL);

	m_PLeader = NULL;
	m_PAlliance	= NULL;

    if (m_PartyType == PARTY_PCS)
    {
        PushPacket(NULL, 0, new CPartyDefinePacket(NULL));

	    for (uint8 i = 0; i < members.size(); ++i)
	    {
		    CCharEntity* PChar = (CCharEntity*)members.at(i);

		    PChar->PParty = NULL;
			PChar->PLatentEffectContainer->CheckLatentsPartyJobs();
			PChar->PLatentEffectContainer->CheckLatentsPartyMembers(members.size());
			PChar->PLatentEffectContainer->CheckLatentsPartyAvatar();
		    PChar->pushPacket(new CPartyMemberUpdatePacket(PChar, 0, PChar->getZone()));

		    // TODO: TreasurePool должен оставаться у последнего персонажа, но сейчас это не критично

            if (PChar->PTreasurePool != NULL &&
                PChar->PTreasurePool->GetPoolType() != TREASUREPOOL_ZONE)
		    {
			    PChar->PTreasurePool->DelMember(PChar);
			    PChar->PTreasurePool = new CTreasurePool(TREASUREPOOL_SOLO);
			    PChar->PTreasurePool->AddMember(PChar);
                PChar->PTreasurePool->UpdatePool(PChar);
		    }
            CStatusEffect* sync = PChar->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
            if (sync && sync->GetDuration() == 0)
            {
    			PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 30, 553));
                sync->SetStartTime(gettick());
                sync->SetDuration(30000);
            }
	    }
        Sql_Query(SqlHandle,"UPDATE accounts_sessions SET partyid = %u WHERE partyid = %u", 0, m_PartyID);
    }
	delete this;
}
void CStatusEffectContainer::RemoveStatusEffect(uint32 id, bool silent)
{
    CStatusEffect* PStatusEffect = m_StatusEffectList.at(id);

    m_StatusEffectList.erase(m_StatusEffectList.begin() + id);
    luautils::OnEffectLose(m_POwner, PStatusEffect);

    m_POwner->delModifiers(&PStatusEffect->modList);
    m_POwner->UpdateHealth();

    if (m_POwner->objtype == TYPE_PC)
    {
        CCharEntity* PChar = (CCharEntity*)m_POwner;

        if (PStatusEffect->GetIcon() != 0)
        {
            UpdateStatusIcons();
			if (silent == false)
			{
				PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, PStatusEffect->GetIcon(), 0, 206));
			}
        }
		//check for latents
		CLatentEffectContainer* PLatentEffectContainer;
		PChar->PLatentEffectContainer->CheckLatentsFoodEffect();
		PChar->PLatentEffectContainer->CheckLatentsStatusEffect();
		PChar->UpdateHealth();

        if (PChar->status == STATUS_NORMAL) PChar->status = STATUS_UPDATE;

        PChar->pushPacket(new CCharHealthPacket(PChar));
        PChar->pushPacket(new CCharSyncPacket(PChar));
    }
	else
	{
		if (silent == false && PStatusEffect->GetIcon() != 0 && ((PStatusEffect->GetFlag() & EFFECTFLAG_NO_LOSS_MESSAGE) == 0) && !m_POwner->isDead())
		{
			m_POwner->loc.zone->PushPacket(m_POwner, CHAR_INRANGE, new CMessageBasicPacket(m_POwner, m_POwner, PStatusEffect->GetIcon(), 0, 206));
		}
	}
    delete PStatusEffect;
}
Exemple #4
0
void CParty::ReloadParty()
{

	//alliance
	if (this->m_PAlliance != NULL)
	{
		CAlliance* ourAlliance = this->m_PAlliance;

		for (uint8 a = 0; a < ourAlliance->partyList.size(); ++a)
		{
				for (uint8 i = 0; i < ourAlliance->partyList.at(a)->members.size(); ++i)
				{
					CCharEntity* PChar = (CCharEntity*)ourAlliance->partyList.at(a)->members.at(i);

					PChar->pushPacket(new CPartyDefinePacket(ourAlliance->partyList.at(a)));
						for (uint8 y = 0; y < ourAlliance->partyList.at(a)->members.size(); ++y)
						{
							PChar->pushPacket(new CPartyMemberUpdatePacket((CCharEntity*)ourAlliance->partyList.at(a)->members.at(y),y, PChar->getZone()));
						}
				}
		}
	return;
	}


	//regular party
	for (uint8 i = 0; i < members.size(); ++i)
	{
		CCharEntity* PChar = (CCharEntity*)members.at(i);

		PChar->PLatentEffectContainer->CheckLatentsPartyJobs();
		PChar->PLatentEffectContainer->CheckLatentsPartyMembers(members.size());
		PChar->PLatentEffectContainer->CheckLatentsPartyAvatar();
		PChar->pushPacket(new CPartyDefinePacket(this));
			for (uint8 y = 0; y < members.size(); ++y)
			{
				PChar->pushPacket(new CPartyMemberUpdatePacket((CCharEntity*)members.at(y), y, PChar->getZone()));
			}
	}

}
Exemple #5
0
void CZoneEntities::DespawnPC(CCharEntity* PChar)
{
	for (EntityList_t::const_iterator it = m_charList.begin(); it != m_charList.end(); ++it)
	{
		CCharEntity* PCurrentChar = (CCharEntity*)it->second;
		SpawnIDList_t::iterator PC = PCurrentChar->SpawnPCList.find(PChar->id);

		if (PC != PCurrentChar->SpawnPCList.end())
		{
			PCurrentChar->SpawnPCList.erase(PC);
			PCurrentChar->pushPacket(new CCharPacket(PChar, ENTITY_DESPAWN, 0));
		}
	}
}
Exemple #6
0
void CZone::SpawnPCs(CCharEntity* PChar)
{
	for (EntityList_t::const_iterator it = m_charList.begin() ; it != m_charList.end() ; ++it)
	{
		CCharEntity* PCurrentChar = (CCharEntity*)it->second;
		SpawnIDList_t::iterator PC = PChar->SpawnPCList.find(PCurrentChar->id);

		if (PChar != PCurrentChar)
		{
			if(distance(PChar->loc.p, PCurrentChar->loc.p) < 50)
			{
				if( PC == PChar->SpawnPCList.end() )
				{
					PChar->SpawnPCList[PCurrentChar->id] = PCurrentChar;
					PChar->pushPacket(new CCharPacket(PCurrentChar,ENTITY_SPAWN));
                    PChar->pushPacket(new CCharSyncPacket(PCurrentChar));

					PCurrentChar->SpawnPCList[PChar->id] = PChar;
					PCurrentChar->pushPacket(new CCharPacket(PChar,ENTITY_SPAWN));
                    PCurrentChar->pushPacket(new CCharSyncPacket(PChar));
				}else{
					PCurrentChar->pushPacket(new CCharPacket(PChar,ENTITY_UPDATE));
				}
			} else {
				if( PC != PChar->SpawnPCList.end() )
				{
					PChar->SpawnPCList.erase(PC);
					PChar->pushPacket(new CCharPacket(PCurrentChar,ENTITY_DESPAWN));

					PCurrentChar->SpawnPCList.erase(PChar->id);
					PCurrentChar->pushPacket(new CCharPacket(PChar,ENTITY_DESPAWN));
				}
			}
		}
	}
}
Exemple #7
0
void CState::PushMessage(MSGBASIC_ID msgID, int32 param, int32 value)
{

	CBattleEntity* PTarget = m_PTarget;
	// always need an entity sent
	if(PTarget == NULL)
	{
		PTarget = m_PEntity;
	}
	if(m_PEntity->objtype == TYPE_PC)
	{
		CCharEntity* PChar = (CCharEntity*)m_PEntity;
	PChar->pushPacket(new CMessageBasicPacket(PChar,PTarget,param,value,msgID));
	}
	m_PEntity->loc.zone->PushPacket(m_PEntity, CHAR_INRANGE, new CMessageBasicPacket(m_PEntity,PTarget,param,value,msgID));
}
Exemple #8
0
void CLinkshell::RemoveMemberByName(int8* MemberName)
{
	PROFILE_FUNC();
	for (uint32 i = 0; i < members.size(); ++i) 
	{
		if (strcmp(MemberName, members.at(i)->GetName()) == 0)
		{
            CCharEntity* PMember = (CCharEntity*)members.at(i);

            CItemLinkshell* PItemLinkshell = (CItemLinkshell*)PMember->getStorage(LOC_INVENTORY)->GetItem(PMember->equip[SLOT_LINK]);

            if (PItemLinkshell != NULL && PItemLinkshell->isType(ITEM_LINKSHELL))
            {
                linkshell::DelOnlineMember(PMember, PItemLinkshell);

                PItemLinkshell->setSubType(ITEM_UNLOCKED);

                PMember->equip[SLOT_LINK] = 0;
                PMember->nameflags.flags &= ~FLAG_LINKSHELL;

                PMember->pushPacket(new CInventoryAssignPacket(PItemLinkshell, INV_NORMAL));
                PMember->pushPacket(new CLinkshellEquipPacket(PMember));
            }

			CItemContainer* Inventory = PMember->getStorage(LOC_INVENTORY);
            for (uint8 SlotID = 0; SlotID < Inventory->GetSize(); ++SlotID)
            {
                    CItemLinkshell* PItemLinkshell = (CItemLinkshell*)Inventory->GetItem(SlotID);

					if (PItemLinkshell != NULL && PItemLinkshell->isType(ITEM_LINKSHELL) && PItemLinkshell->GetLSID() == m_id)
		            {
                        const int8* Query = "UPDATE char_inventory SET itemid = (itemid+2) WHERE charid = %u AND location = %u AND slot = %u LIMIT 1";

                        Sql_Query(SqlHandle, Query, PMember->id, LOC_INVENTORY, SlotID);

                        PItemLinkshell->SetLSID(0);
                        PItemLinkshell->setID(PItemLinkshell->getID() + 2);

                        PMember->pushPacket(new CInventoryItemPacket(PItemLinkshell, LOC_INVENTORY, SlotID));
		            }
            }
	        
            charutils::SaveCharStats(PMember);
            charutils::SaveCharEquip(PMember);

            if (PMember->status == STATUS_NORMAL) PMember->status = STATUS_UPDATE;

            PMember->pushPacket(new CInventoryFinishPacket());
            PMember->pushPacket(new CCharUpdatePacket(PMember));
            PMember->pushPacket(new CMessageSystemPacket(0,0,109));
			return;
		} 
	}
}
Exemple #9
0
void CState::PushError(MSGBASIC_ID msgID, int32 param, int32 value)
{
	PROFILE_FUNC();
	if(m_PEntity->objtype == TYPE_PC)
	{
		CCharEntity* PChar = (CCharEntity*)m_PEntity;

		CBattleEntity* PTarget = m_PTarget;

		// always need an entity sent
		if(PTarget == NULL)
		{
			PTarget = m_PEntity;
		}

		PChar->pushPacket(new CMessageBasicPacket(PChar,PTarget,param,value,msgID));
	}
}
Exemple #10
0
void CParty::PushPacket(CCharEntity* PPartyMember, uint8 ZoneID, CBasicPacket* packet)
{
	for (uint32 i = 0; i < members.size(); ++i)
	{
		if(members.at(i)->objtype != TYPE_PC) continue;

		CCharEntity* member = (CCharEntity*)members.at(i);

        if (member != PPartyMember &&
            member->status != STATUS_DISAPPEAR &&
             !jailutils::InPrison(member) )
		{
			if (ZoneID == 0 || member->getZone() == ZoneID)
			{
				member->pushPacket(new CBasicPacket(*packet));
			}
		}
	}
	delete packet;
}
Exemple #11
0
void CParty::RefreshSync()
{
    CCharEntity* sync = (CCharEntity*)m_PSyncTarget;
    uint8 syncLevel = sync->jobs.job[sync->GetMJob()];
    if (syncLevel < 10)
    {
        SetSyncTarget(NULL, 554);
    }
    for (uint32 i = 0; i < members.size(); ++i)
	{
		if(members.at(i)->objtype != TYPE_PC) continue;

		CCharEntity* member = (CCharEntity*)members.at(i);

        uint8 NewMLevel = 0;

		if (syncLevel < member->jobs.job[member->GetMJob()])
		{
			NewMLevel = syncLevel;
		}else{
			NewMLevel = member->jobs.job[member->GetMJob()];
		}

		if (member->GetMLevel() != NewMLevel)
		{
            charutils::RemoveAllEquipMods(member);
			member->SetMLevel(NewMLevel);
			member->SetSLevel(member->jobs.job[member->GetSJob()]);
            charutils::ApplyAllEquipMods(member);

            blueutils::ValidateBlueSpells(member);
			charutils::BuildingCharSkillsTable(member);
			charutils::CalculateStats(member);
			charutils::BuildingCharTraitsTable(member);
			charutils::BuildingCharAbilityTable(member);
			charutils::CheckValidEquipment(member); // Handles rebuilding weapon skills as well.
		}
        member->pushPacket(new CMessageBasicPacket(member, member, 0, syncLevel, 540));
	}
    m_PSyncTarget = sync;
}
Exemple #12
0
void CMagicState::CharAfterFinish()
{
    if(m_PEntity->objtype != TYPE_PC)
    {
        return;
    }

    CCharEntity* PChar = (CCharEntity*)m_PEntity;

    charutils::RemoveStratagems(PChar, m_PSpell);

    charutils::UpdateHealth(PChar);

    // only skill up if the effect landed
    if(m_PSpell->tookEffect()){
        charutils::TrySkillUP(PChar, (SKILLTYPE)m_PSpell->getSkillType(), m_PTarget->GetMLevel());
        if (m_PSpell->getSkillType() == SKILL_SNG)
        {
            CItemWeapon* PItem = (CItemWeapon*)PChar->getEquip(SLOT_RANGED);
            if (PItem && PItem->isType(ITEM_ARMOR))
            {
				SKILLTYPE Skilltype = (SKILLTYPE)PItem->getSkillType();
				if (Skilltype == SKILL_STR || Skilltype == SKILL_WND || Skilltype == SKILL_SNG)
				{
					charutils::TrySkillUP(PChar, Skilltype, m_PTarget->GetMLevel());
				}
            }
        }
    }

    PChar->pushPacket(new CCharUpdatePacket(PChar));

    // make wyvern use breath
    if(PChar->PPet!=NULL && ((CPetEntity*)PChar->PPet)->getPetType() == PETTYPE_WYVERN)
    {
        ((CAIPetDummy*)PChar->PPet->PBattleAI)->m_MasterCommand = MASTERCOMMAND_HEALING_BREATH;
        PChar->PPet->PBattleAI->SetCurrentAction(ACTION_MOBABILITY_START);
    }

    SetHiPCLvl(m_PTarget, PChar->GetMLevel());
}
Exemple #13
0
void CState::PushError(MSGBASIC_ID msgID, int32 param, int32 value, CBattleEntity* PTarget)
{
	if(m_PEntity->objtype == TYPE_PC)
	{
		CCharEntity* PChar = (CCharEntity*)m_PEntity;

		// always need an entity sent
		if(PTarget == nullptr)
		{
                    if(m_PTarget != nullptr)
                    {
                        PTarget = m_PTarget;
                    }
                    else
                    {
                        PTarget = m_PEntity;
                    }
		}

		PChar->pushPacket(new CMessageBasicPacket(PChar,PTarget,param,value,msgID));
	}
}
Exemple #14
0
void CZone::InsertPET(CBaseEntity* PPet)
{
	if ((PPet != NULL) && (PPet->objtype == TYPE_PET))
	{
        uint16 targid = 0x700;

        for (EntityList_t::const_iterator it = m_petList.begin() ; it != m_petList.end() ; ++it)
	    {
            if (targid != it->first)
            {
                break;
            }
		    targid++;
	    }
        if (targid >= 0x800)
        {
            ShowError(CL_RED"CZone::InsertPET : targid is high (03hX)\n" CL_RESET, targid);
            return;
        }
        PPet->id = 0x1000000 + (m_zoneID << 12) + targid;
        PPet->targid = targid;
        PPet->loc.zone = this;
		m_petList[PPet->targid] = PPet;

		for (EntityList_t::const_iterator it = m_charList.begin() ; it != m_charList.end() ; ++it)
		{
			CCharEntity* PCurrentChar = (CCharEntity*)it->second;

			if(distance(PPet->loc.p, PCurrentChar->loc.p) < 50)
			{
				PCurrentChar->SpawnPETList[PPet->id] = PPet;
				PCurrentChar->pushPacket(new CEntityUpdatePacket(PPet, ENTITY_SPAWN));
			}
		}
		return;
	}
	ShowError(CL_RED"CZone::InsertPET : entity is not pet\n" CL_RESET);
}
Exemple #15
0
void CZoneEntities::InsertPET(CBaseEntity* PPet)
{
	if (PPet != nullptr)
	{
		uint16 targid = 0x700;

		for (EntityList_t::const_iterator it = m_petList.begin(); it != m_petList.end(); ++it)
		{
			if (targid != it->first)
			{
				break;
			}
			targid++;
		}
		if (targid >= 0x800)
		{
			ShowError(CL_RED"CZone::InsertPET : targid is high (03hX)\n" CL_RESET, targid);
			return;
		}
		PPet->id = 0x1000000 + (m_zone->GetID() << 12) + targid;
		PPet->targid = targid;
		PPet->loc.zone = m_zone;
		m_petList[PPet->targid] = PPet;

		for (EntityList_t::const_iterator it = m_charList.begin(); it != m_charList.end(); ++it)
		{
			CCharEntity* PCurrentChar = (CCharEntity*)it->second;

			if (distance(PPet->loc.p, PCurrentChar->loc.p) < 50)
			{
				PCurrentChar->SpawnPETList[PPet->id] = PPet;
                PCurrentChar->pushPacket(new CEntityUpdatePacket(PPet, ENTITY_SPAWN, UPDATE_ALL_MOB));
			}
		}
		return;
	}
	ShowError(CL_RED"CZone::InsertPET : entity is null\n" CL_RESET);
}
Exemple #16
0
void TryLearningSpells(CCharEntity* PChar, CMobEntity* PMob) {

	if (PMob->m_UsedSkillIds.size() == 0) { // minor optimisation.
		return;
	}

	// prune the learnable blue spells
	std::vector<CSpell*> PLearnableSpells;
	for (std::map<uint16, uint16>::iterator i=PMob->m_UsedSkillIds.begin(); i != PMob->m_UsedSkillIds.end(); ++i) {
		CSpell* PSpell = spell::GetSpellByMonsterSkillId(i->first);
		if (PSpell != nullptr) {
			PLearnableSpells.push_back(PSpell);
		}
	}

	if (PLearnableSpells.size() == 0) {
		return;
	}

	std::vector<CCharEntity*> PBlueMages;

	// populate PBlueMages
	if (PChar->PParty != nullptr) {
        for (uint8 i = 0; i < PChar->PParty->members.size(); i++) {
			if (PChar->PParty->members[i]->GetMJob() == JOB_BLU && PChar->PParty->members[i]->objtype == TYPE_PC) {
				PBlueMages.push_back((CCharEntity*)PChar->PParty->members[i]);
			}
		}
	}
	else if (PChar->GetMJob() == JOB_BLU) {
		PBlueMages.push_back(PChar);
	}

	// loop through the list of BLUs and see if they can learn.
	for (size_t i = 0; i < PBlueMages.size(); i++) {
		CCharEntity* PBlueMage = PBlueMages[i];

		if (PBlueMage->isDead()) { // too dead to learn
			continue;
		}

		if (distance(PBlueMage->loc.p, PMob->loc.p) > 100) { // too far away to learn
			continue;
		}

		for (size_t spell = 0; spell < PLearnableSpells.size(); spell++) {
			CSpell* PSpell = PLearnableSpells[spell];

			if (charutils::hasSpell(PBlueMage, static_cast<uint16>(PSpell->getID()))) {
				continue;
			}

            // get the skill cap for the spell level
            auto skillLvlForSpell = battleutils::GetMaxSkill(SKILL_BLUE_MAGIC, JOB_BLU, PSpell->getJob(JOB_BLU));
            // get player skill level with bonus from gear
            auto playerSkillLvl = PBlueMage->GetSkill(SKILL_BLUE_MAGIC);

            // make sure the difference between spell skill and player is at most 31 points
            if (playerSkillLvl >= skillLvlForSpell - 31)
            {
                // TODO: check for blue learning bonus and adjust base percent
                if (dsprand::GetRandomNumber(100) < 33) {
					if (charutils::addSpell(PBlueMage, static_cast<uint16>(PSpell->getID()))) {
						PBlueMage->pushPacket(new CMessageBasicPacket(PBlueMage, PBlueMage, static_cast<uint16>(PSpell->getID()), 0, MSGBASIC_LEARNS_SPELL));
						charutils::SaveSpell(PBlueMage, static_cast<uint16>(PSpell->getID()));
						PBlueMage->pushPacket(new CCharSpellsPacket(PBlueMage));
					}
				}
				break; // only one attempt at learning a spell, regardless of learn or not.
			}
		}

	}
}
Exemple #17
0
void TryLearningSpells(CCharEntity* PChar, CMobEntity* PMob) {

	if (PMob->m_UsedSkillIds.size() == 0) { // minor optimisation.
		return;
	}

	// prune the learnable blue spells
	std::vector<CSpell*> PLearnableSpells;
	for (std::map<uint16, uint16>::iterator i=PMob->m_UsedSkillIds.begin(); i != PMob->m_UsedSkillIds.end(); ++i) {
		CSpell* PSpell = spell::GetSpellByMonsterSkillId(i->first);
		if (PSpell != NULL) {
			PLearnableSpells.push_back(PSpell);
		}
	}

	if (PLearnableSpells.size() == 0) {
		return;
	}

	std::vector<CCharEntity*> PBlueMages;

	// populate PBlueMages
	if (PChar->PParty != NULL) {
        for (uint8 i = 0; i < PChar->PParty->members.size(); i++) {
			if (PChar->PParty->members[i]->GetMJob() == JOB_BLU && PChar->PParty->members[i]->objtype == TYPE_PC) {
				PBlueMages.push_back((CCharEntity*)PChar->PParty->members[i]);
			}
		}
	}
	else if (PChar->GetMJob() == JOB_BLU) {
		PBlueMages.push_back(PChar);
	}

	// loop through the list of BLUs and see if they can learn.
	for (int i=0; i<PBlueMages.size(); i++) {
		CCharEntity* PBlueMage = PBlueMages[i];

		if (PBlueMage->isDead()) { // too dead to learn
			continue;
		}

		if (distance(PBlueMage->loc.p, PMob->loc.p) > 100) { // too far away to learn
			continue;
		}

		for (int spell=0; spell<PLearnableSpells.size(); spell++) {
			CSpell* PSpell = PLearnableSpells[spell];

			if (charutils::hasSpell(PBlueMage, PSpell->getID())) {
				continue;
			}

			uint8 learnableLevel = PSpell->getJob(JOB_BLU);
			if (learnableLevel > 0 && learnableLevel < PBlueMage->GetMLevel()+7) { // TODO: Use blue magic skill check rather than level
				if (rand()%100 < 33) {
					if (charutils::addSpell(PBlueMage, PSpell->getID())) {
						PBlueMage->pushPacket(new CMessageBasicPacket(PBlueMage, PBlueMage, PSpell->getID(), 0, MSGBASIC_LEARNS_SPELL));
						charutils::SaveSpells(PBlueMage);
						PBlueMage->pushPacket(new CCharSpellsPacket(PBlueMage));
					}
				}
				break; // only one attempt at learning a spell, regardless of learn or not.
			}
		}

	}
}
Exemple #18
0
void CParty::SetSyncTarget(CBattleEntity* PEntity, uint16 message)
{
    if (map_config.level_sync_enable)
    {
        if (PEntity && PEntity->objtype == TYPE_PC)
        {
            CCharEntity* PChar = (CCharEntity*)PEntity;
            //enable level sync
            if (PChar->GetMLevel() < 10 )
            {
                ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 10, 541));
                return;
            }
            else if (PChar->getZone() != GetLeader()->getZone())
            {
                ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 0, 542));
                return;
            }
            else
            {
                for (uint32 i = 0; i < members.size(); ++i)
                {
                    if(members.at(i)->StatusEffectContainer->HasStatusEffect(EFFECT_LEVEL_RESTRICTION))
                    {
                        ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 0, 543));
                        return;
                    }
                }
                m_PSyncTarget = PChar;
	            for (uint32 i = 0; i < members.size(); ++i)
	            {
		            if(members.at(i)->objtype != TYPE_PC) continue;

		            CCharEntity* member = (CCharEntity*)members.at(i);

                    if (member->status != STATUS_DISAPPEAR &&
                         member->getZone() == PChar->getZone() )
		            {
			            member->pushPacket(new CMessageStandardPacket(PChar->GetMLevel(), 0, 0, 0, message));
                        member->StatusEffectContainer->AddStatusEffect(new CStatusEffect(
                            EFFECT_LEVEL_SYNC,
                            EFFECT_LEVEL_SYNC,
                            PChar->GetMLevel(),
                            0,
                            0), true);
                        member->StatusEffectContainer->DelStatusEffectsByFlag(EFFECTFLAG_DISPELABLE);
                        member->loc.zone->PushPacket(member, CHAR_INRANGE, new CCharSyncPacket(member));
		            }
	            }
            }
        }
        else
        {
            if (m_PSyncTarget != NULL)
            {
                //disable level sync
                for (uint32 i = 0; i < members.size(); ++i)
	            {
		            if(members.at(i)->objtype != TYPE_PC) continue;

		            CCharEntity* member = (CCharEntity*)members.at(i);

                    if (member->status != STATUS_DISAPPEAR &&
                         member->getZone() == m_PSyncTarget->getZone() )
		            {
                        CStatusEffect* sync = member->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
                        if (sync && sync->GetDuration() == 0)
                        {
			                member->pushPacket(new CMessageBasicPacket(member, member, 10, 30, message));
                            sync->SetStartTime(gettick());
                            sync->SetDuration(30000);
                        }
		            }
	            }
            }
        }
    }
}
Exemple #19
0
void CZone::DecreaseZoneCounter(CCharEntity* PChar)
{
    DSP_DEBUG_BREAK_IF(PChar == NULL);
    DSP_DEBUG_BREAK_IF(PChar->loc.zone != this);

	//remove pets
	if(PChar->PPet != NULL)
    {
		charutils::BuildingCharPetAbilityTable(PChar,(CPetEntity*)PChar->PPet,0);//blank the pet commands
		if(PChar->PPet->isCharmed) {
			petutils::DespawnPet(PChar);
		}
		else {
			PChar->PPet->status = STATUS_DISAPPEAR;
			if( ((CPetEntity*)(PChar->PPet))->getPetType() == PETTYPE_AVATAR )
				PChar->setModifier(MOD_AVATAR_PERPETUATION, 0);
		}
		// It may have been nulled by DespawnPet
		if(PChar->PPet != NULL) {
			PChar->PPet->PBattleAI->SetCurrentAction(ACTION_NONE);
			DeletePET(PChar->PPet);//remove the TID for this pet

			for (EntityList_t::const_iterator it = m_charList.begin() ; it != m_charList.end() ; ++it)
			{
				//inform other players of the pets removal
				CCharEntity* PCurrentChar = (CCharEntity*)it->second;
				SpawnIDList_t::iterator PET = PCurrentChar->SpawnPETList.find(PChar->PPet->id);

				if( PET != PCurrentChar->SpawnPETList.end() )
				{
					PCurrentChar->SpawnPETList.erase(PET);
					PCurrentChar->pushPacket(new CEntityUpdatePacket(PChar->PPet, ENTITY_DESPAWN));
				}
			}
			PChar->PPet = NULL;
		}
	}

	//remove bcnm status
	if(m_InstanceHandler != NULL && PChar->StatusEffectContainer->HasStatusEffect(EFFECT_BATTLEFIELD))
    {
		if(m_InstanceHandler->disconnectFromBcnm(PChar)){
			ShowDebug("Removed %s from the BCNM they were in as they have left the zone.\n",PChar->GetName());
		}

		if(PChar->loc.destination==0){ //this player is disconnecting/logged out, so move them to the entrance
			//move depending on zone
			int pos[4] = {0,0,0,0};
			instanceutils::getStartPosition(m_zoneID,pos);
			if(pos!=NULL){
				PChar->loc.p.x = pos[0];
				PChar->loc.p.y = pos[1];
				PChar->loc.p.z = pos[2];
				PChar->loc.p.rotation = pos[3];
				charutils::SaveCharPosition(PChar);
			}
			else{
				ShowWarning("%s has disconnected from the BCNM but cannot move them to the lobby as the lobby position is unknown!\n",PChar->GetName());
			}
		}
	}
	else if(m_InstanceHandler != NULL && PChar->StatusEffectContainer->HasStatusEffect(EFFECT_DYNAMIS, 0))
    {
		if(m_InstanceHandler->disconnectFromDynamis(PChar)){
			ShowDebug("Removed %s from the BCNM they were in as they have left the zone.\n",PChar->GetName());
		}

		if(PChar->loc.destination==0){ //this player is disconnecting/logged out, so move them to the entrance
			//move depending on zone
			int pos[4] = {0,0,0,0};
			instanceutils::getStartPosition(m_zoneID,pos);
			if(pos!=NULL){
				PChar->loc.p.x = pos[0];
				PChar->loc.p.y = pos[1];
				PChar->loc.p.z = pos[2];
				PChar->loc.p.rotation = pos[3];
				charutils::SaveCharPosition(PChar);
			}
			else{
				ShowWarning("%s has disconnected from the BCNM but cannot move them to the lobby as the lobby position is unknown!\n",PChar->GetName());
			}
		}
	}

	for (EntityList_t::const_iterator it = m_mobList.begin() ; it != m_mobList.end() ; ++it)
	{
		CMobEntity* PCurrentMob = (CMobEntity*)it->second;
		PCurrentMob->PEnmityContainer->Clear(PChar->id);
		if(PCurrentMob->m_OwnerID.id == PChar->id){
			PCurrentMob->m_OwnerID.clean();
		}
	}

    // TODO: могут возникать проблемы с переходом между одной и той же зоной (zone == prevzone)

	m_charList.erase(PChar->targid);

	ShowDebug(CL_CYAN"CZone:: %s DecreaseZoneCounter <%u> %s\n" CL_RESET, GetName(), m_charList.size(),PChar->GetName());

	if (ZoneTimer && m_charList.empty())
	{
		ZoneTimer->m_type = CTaskMgr::TASK_REMOVE;
		ZoneTimer = NULL;

        HealAllMobs();
	}
	else
	{
		for (EntityList_t::const_iterator it = m_charList.begin() ; it != m_charList.end() ; ++it)
		{
			CCharEntity* PCurrentChar = (CCharEntity*)it->second;
			SpawnIDList_t::iterator PC = PCurrentChar->SpawnPCList.find(PChar->id);

			if( PC != PCurrentChar->SpawnPCList.end() )
			{
				PCurrentChar->SpawnPCList.erase(PC);
				PCurrentChar->pushPacket(new CCharPacket(PChar,ENTITY_DESPAWN));
			}
		}
	}
	if (PChar->m_LevelRestriction != 0)
	{
        if (PChar->PParty)
        {
            if (PChar->PParty->GetSyncTarget() == PChar || PChar->PParty->GetLeader() == PChar)
            {
                PChar->PParty->SetSyncTarget(NULL, 551);
            }
            if (PChar->PParty->GetSyncTarget() != NULL)
            {
                uint8 count = 0;
                for (uint32 i = 0; i < PChar->PParty->members.size(); ++i)
                {
                    if (PChar->PParty->members.at(i) != PChar && PChar->PParty->members.at(i)->getZone() == PChar->PParty->GetSyncTarget()->getZone())
                    {
                        count++;
                    }
                }
                if (count < 2) //3, because one is zoning out - thus at least 2 will be left
                {
                    PChar->PParty->SetSyncTarget(NULL, 552);
                }
            }
        }
		PChar->StatusEffectContainer->DelStatusEffectSilent(EFFECT_LEVEL_SYNC);
		PChar->StatusEffectContainer->DelStatusEffectSilent(EFFECT_LEVEL_RESTRICTION);
	}
	if (PChar->PTreasurePool != NULL) // TODO: условие для устранения проблем с MobHouse, надо блин решить ее раз и навсегда
	{
		PChar->PTreasurePool->DelMember(PChar);
	}
    for (regionList_t::const_iterator region = m_regionList.begin(); region != m_regionList.end(); ++region)
    {
        if ((*region)->GetRegionID() == PChar->m_InsideRegionID)
        {
            luautils::OnRegionLeave(PChar, *region);
            break;
        }
    }

    PChar->loc.zone = NULL;
    PChar->loc.prevzone = m_zoneID;

    PChar->SpawnPCList.clear();
	PChar->SpawnNPCList.clear();
	PChar->SpawnMOBList.clear();
	PChar->SpawnPETList.clear();
}
Exemple #20
0
void CTransportHandler::TransportTimer() 
{
	uint32 VanaTime = CVanaTime::getInstance()->getDate();

    // в портовых зонах необходимо написать макросы на случай, если персонаж вышел из игры в корабле. 
    // при входе в игру он должен оказаться на пристани

    for(uint32 i = 0; i < TransportList.size(); ++i)
    {
        Transport_t* PTransport = TransportList.at(i);

        uint16 ShipTimerOffset = ((VanaTime - PTransport->TimeOffset) % PTransport->TimeInterval);

        // корабль появляется на горизонте
        if (ShipTimerOffset == 0)
        {
            PTransport->PTransportNPC->status = STATUS_NORMAL;
            PTransport->PTransportNPC->animation = PTransport->AnimationArrive;
            PTransport->PTransportNPC->loc = PTransport->Dock;

            WBUFL(&PTransport->PTransportNPC->name[0],4) = CVanaTime::getInstance()->getVanaTime();

			PTransport->Dock.zone->PushPacket(NULL, CHAR_INZONE, new CEntityUpdatePacket(PTransport->PTransportNPC, ENTITY_SPAWN, UPDATE_ALL));
        }
        // персонажи видят корабль, иначе ждем следующего прибытия
        else if (PTransport->PTransportNPC->status == STATUS_NORMAL) 
        {
            // пора подтягивать пассажиров к выходу
            if (ShipTimerOffset ==  PTransport->TimeAnimationArrive - 10) 
            {
                PTransport->PTransportNPC->loc.boundary = 0;
                zoneutils::GetZone(PTransport->Dock.prevzone)->TransportDepart(PTransport->PTransportNPC);
            }
            // корабль причалил, открываем двери пассажирам
            else if (ShipTimerOffset == PTransport->TimeAnimationArrive)
            {
                PTransport->PDoorNPC->animation = ANIMATION_OPEN_DOOR;
				PTransport->Dock.zone->PushPacket(PTransport->PDoorNPC, CHAR_INRANGE, new CEntityUpdatePacket(PTransport->PDoorNPC, ENTITY_UPDATE, UPDATE_COMBAT));
            }
            //корабль отчаливает
            else if (ShipTimerOffset == PTransport->TimeAnimationArrive + PTransport->TimeWaiting)
            {
                PTransport->PDoorNPC->animation = ANIMATION_CLOSE_DOOR;
                PTransport->PTransportNPC->animation = PTransport->AnimationDepart;
                PTransport->PTransportNPC->loc.boundary = PTransport->Dock.boundary;

                WBUFL(&PTransport->PTransportNPC->name[0],4) = CVanaTime::getInstance()->getVanaTime();

                PTransport->Dock.zone->TransportDepart(PTransport->PTransportNPC);
				PTransport->Dock.zone->PushPacket(PTransport->PDoorNPC, CHAR_INRANGE, new CEntityUpdatePacket(PTransport->PDoorNPC, ENTITY_UPDATE, UPDATE_COMBAT));
				PTransport->Dock.zone->PushPacket(NULL, CHAR_INZONE, new CEntityUpdatePacket(PTransport->PTransportNPC, ENTITY_UPDATE, UPDATE_COMBAT));
            }
            //корабль исчезает
            else if (ShipTimerOffset == PTransport->TimeAnimationArrive + PTransport->TimeWaiting + PTransport->TimeAnimationDepart)
            {
                PTransport->PTransportNPC->status = STATUS_DISAPPEAR;
                PTransport->Dock.zone->PushPacket(NULL, CHAR_INZONE, new CEntityUpdatePacket(PTransport->PTransportNPC, ENTITY_DESPAWN,UPDATE_NONE));
            }
        }
    }

	for(uint32 i = 0; i < ElevatorList.size(); ++i) 
	{
		Elevator_t * elevator = &ElevatorList.at(i);

		if (elevator->isStarted)
		{
			uint16 TimerOffset = (VanaTime % elevator->interval);
			
			if (elevator->id == ELEVATOR_PORT_BASTOK_DRWBRDG)
			{
				TimerOffset = (VanaTime % INTERVAL_PORT_BASTOK_DRWBRDG);

				if (TimerOffset == 0 || TimerOffset == 76)
				{
					CZone* PZone = zoneutils::GetZone(elevator->zone);
					EntityList_t charList = PZone->GetCharList();

					if (!charList.empty())
					{
						for (EntityList_t::const_iterator it = charList.begin() ; it != charList.end() ; ++it)
						{
							CCharEntity* PChar = (CCharEntity*)it->second;
							if ((PChar->GetXPos() > 54 && PChar->GetXPos() < 66) && (PChar->GetZPos() > -160 && PChar->GetZPos() < -80))
							{
								PChar->pushPacket(new CEventPacket(PChar, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1));
							}
						}
					}
				}
				else if (TimerOffset == 4 || TimerOffset == 80)
				{
					elevator->isMoving = true;
					startElevator(elevator);
				}
				else if (TimerOffset == 8 || TimerOffset == 84)
				{
					elevator->isMoving = true;
					startElevator(elevator);
				}
				else if (TimerOffset == 12 || TimerOffset == 88)
				{
					elevator->isMoving = false;
					arriveElevator(elevator);
				}
			}
			else if (elevator->id == ELEVATOR_KUFTAL_TUNNEL_DSPPRNG_RCK)
			{
				TimerOffset = (VanaTime % INTERVAL_KUFTAL_TUNNEL_DSPPRNG_RCK);

				if (TimerOffset == 60)
				{
					elevator->isMoving = true;
					startElevator(elevator);
				}
			}
			else
			{
				if (TimerOffset == 0)
				{
					elevator->isMoving = true;
					startElevator(elevator);
				}
				else if (TimerOffset == elevator->movetime)
				{
					if (elevator->isMoving)
					{
						if (!elevator->isPermanent)
						{
							elevator->isStarted = false;
						}
						elevator->isMoving = false;
						arriveElevator(elevator);
					}
				}
			}
		}
	}
}
Exemple #21
0
void CParty::DelMember(CBattleEntity* PEntity)
{
	DSP_DEBUG_BREAK_IF(PEntity == NULL);
	DSP_DEBUG_BREAK_IF(PEntity->PParty != this);

	if (m_PLeader == PEntity)
	{
		RemovePartyLeader(PEntity);
	}
	else
	{
		for (uint32 i = 0; i < members.size(); ++i)
		{
			if (PEntity == members.at(i))
			{
				members.erase(members.begin() + i);

				if (m_PartyType == PARTY_PCS)
				{
					CCharEntity* PChar = (CCharEntity*)PEntity;

					if (m_PQuaterMaster == PChar)
					{
						SetQuarterMaster(NULL);
					}
					if (m_PSyncTarget == PChar)
					{
						SetSyncTarget(NULL, 553);
						CStatusEffect* sync = PChar->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
						if (sync && sync->GetDuration() == 0)
						{
							PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 30, 553));
							sync->SetStartTime(gettick());
							sync->SetDuration(30000);
						}
						DisableSync();
					}
					if (m_PSyncTarget != NULL && m_PSyncTarget != PChar)
					{
						if (PChar->status != STATUS_DISAPPEAR &&
							PChar->getZone() == m_PSyncTarget->getZone())
						{
							CStatusEffect* sync = PChar->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
							if (sync && sync->GetDuration() == 0)
							{
								PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 30, 553));
								sync->SetStartTime(gettick());
								sync->SetDuration(30000);
							}
						}
					}
					PChar->PLatentEffectContainer->CheckLatentsPartyMembers(members.size());

					PChar->pushPacket(new CPartyDefinePacket(NULL));
					PChar->pushPacket(new CPartyMemberUpdatePacket(PChar, 0, PChar->getZone()));
					PChar->pushPacket(new CCharUpdatePacket(PChar));
					PChar->PParty = NULL;

					if (PChar->PTreasurePool != NULL &&
						PChar->PTreasurePool->GetPoolType() != TREASUREPOOL_ZONE)
					{
						PChar->PTreasurePool->DelMember(PChar);
						PChar->PTreasurePool = new CTreasurePool(TREASUREPOOL_SOLO);
						PChar->PTreasurePool->AddMember(PChar);
						PChar->PTreasurePool->UpdatePool(PChar);
					}
				}
				break;
			}
		}
	}
}
Exemple #22
0
/************************************************************************
*                                                                       *
*  Creates up to many attacks for a particular hand.			        *
*                                                                       *
************************************************************************/
void CAttackRound::CreateAttacks(CItemWeapon* PWeapon, PHYSICAL_ATTACK_DIRECTION direction)
{
    uint8 num = 1;
    
    bool isPC = m_attacker->objtype == TYPE_PC;

    // Checking the players weapon hit count
    if (PWeapon->getReqLvl() <= m_attacker->GetMLevel())
    {
        num = PWeapon->getHitCount();
    }
    
    // If the attacker is a mobentity or derived from mobentity, check to see if it has any special mutli-hit capabilties
    if (dynamic_cast<CMobEntity*>(m_attacker))
    {
        auto multiHitMax = static_cast<CMobEntity*>(m_attacker)->getMobMod(MOBMOD_MULTI_HIT);
        
        if (multiHitMax > 0)
            num = 1 + battleutils::getHitCount(multiHitMax);
    }

    AddAttackSwing(PHYSICAL_ATTACK_TYPE::NORMAL, direction, num);

    // Checking the players triple, double and quadruple attack
    int16 tripleAttack = m_attacker->getMod(Mod::TRIPLE_ATTACK);
    int16 doubleAttack = m_attacker->getMod(Mod::DOUBLE_ATTACK);
    int16 quadAttack = m_attacker->getMod(Mod::QUAD_ATTACK);

    //check for merit upgrades
    if (isPC)
    {
        CCharEntity* PChar = (CCharEntity*)m_attacker;

        //merit chance only applies if player has the job trait
        if (charutils::hasTrait(PChar, TRAIT_TRIPLE_ATTACK)) tripleAttack += PChar->PMeritPoints->GetMeritValue(MERIT_TRIPLE_ATTACK_RATE, PChar);
        if (charutils::hasTrait(PChar, TRAIT_DOUBLE_ATTACK)) doubleAttack += PChar->PMeritPoints->GetMeritValue(MERIT_DOUBLE_ATTACK_RATE, PChar);
        // TODO: Quadruple attack merits when SE release them.
    }

    quadAttack = dsp_cap(quadAttack, 0, 100);
    doubleAttack = dsp_cap(doubleAttack, 0, 100);
    tripleAttack = dsp_cap(tripleAttack, 0, 100);

    // Checking Mikage Effect - Hits Vary With Num of Utsusemi Shadows for Main Weapon
    if (m_attacker->StatusEffectContainer->HasStatusEffect(EFFECT_MIKAGE) && m_attacker->m_Weapons[SLOT_MAIN]->getID() == PWeapon->getID())
    {
        int16 shadows = m_attacker->getMod(Mod::UTSUSEMI);
        //ShowDebug(CL_CYAN"Create Attacks: Mikage Active, Rolling Attack Chance for %d Shadowss...\n" CL_RESET, shadows);
        AddAttackSwing(PHYSICAL_ATTACK_TYPE::NORMAL, direction, shadows);
    }
    else if (num == 1 && dsprand::GetRandomNumber(100) < quadAttack)
        AddAttackSwing(PHYSICAL_ATTACK_TYPE::QUAD, direction, 3);

    else if (num == 1 && dsprand::GetRandomNumber(100) < tripleAttack)
        AddAttackSwing(PHYSICAL_ATTACK_TYPE::TRIPLE, direction, 2);

    else if (num == 1 && dsprand::GetRandomNumber(100) < doubleAttack)
        AddAttackSwing(PHYSICAL_ATTACK_TYPE::DOUBLE, direction, 1);

    // Ammo extra swing - players only
    if (isPC && m_attacker->getMod(Mod::AMMO_SWING) > 0)
    {
        // Check for ammo
        CCharEntity* PChar = (CCharEntity*)m_attacker;
        CItemArmor* PAmmo = PChar->getEquip(SLOT_AMMO);
        CItemArmor* PMain = PChar->getEquip(SLOT_MAIN);
        CItemArmor* PSub = PChar->getEquip(SLOT_SUB);
        uint8 slot = PChar->equip[SLOT_AMMO];
        uint8 loc = PChar->equipLoc[SLOT_AMMO];
        uint8 ammoCount = 0;

        // Handedness check, checking mod of the weapon for the purposes of level scaling
        if (battleutils::GetScaledItemModifier(PChar, PMain, Mod::AMMO_SWING_TYPE) == 2 &&
            dsprand::GetRandomNumber(100) < m_attacker->getMod(Mod::AMMO_SWING) && PAmmo != nullptr && ammoCount < PAmmo->getQuantity())
        {
            AddAttackSwing(PHYSICAL_ATTACK_TYPE::NORMAL, direction, 1);
            ammoCount += 1;
        }
        else
        {
            if (direction == RIGHTATTACK && battleutils::GetScaledItemModifier(PChar, PMain, Mod::AMMO_SWING_TYPE) == 1 &&
                dsprand::GetRandomNumber(100) < m_attacker->getMod(Mod::AMMO_SWING) && PAmmo != nullptr && ammoCount < PAmmo->getQuantity())
            {
                AddAttackSwing(PHYSICAL_ATTACK_TYPE::NORMAL, RIGHTATTACK, 1);
                ammoCount += 1;
            }
            if (direction == LEFTATTACK && PSub != nullptr && battleutils::GetScaledItemModifier(PChar, PSub, Mod::AMMO_SWING_TYPE) == 1 &&
                dsprand::GetRandomNumber(100) < m_attacker->getMod(Mod::AMMO_SWING) && PAmmo != nullptr && ammoCount < PAmmo->getQuantity())
            {
                AddAttackSwing(PHYSICAL_ATTACK_TYPE::NORMAL, LEFTATTACK, 1);
                ammoCount += 1;
            }
        }

        if (PAmmo != nullptr)
        {
            if (PAmmo->getQuantity() == ammoCount)
            {
                charutils::UnequipItem(PChar, SLOT_AMMO);
                charutils::SaveCharEquip(PChar);
            }
            charutils::UpdateItem(PChar, loc, slot, -ammoCount);
            PChar->pushPacket(new CInventoryFinishPacket());
        }
    }


    // TODO: Possible Lua function for the nitty gritty stuff below.

    // Iga mod: Extra attack chance whilst dual wield is on.
    if (direction == LEFTATTACK && dsprand::GetRandomNumber(100) < m_attacker->getMod(Mod::EXTRA_DUAL_WIELD_ATTACK))
        AddAttackSwing(PHYSICAL_ATTACK_TYPE::NORMAL, RIGHTATTACK, 1);

}
Exemple #23
0
void CParty::ReloadParty()
{
    //check if partyflags have changed
    int ret = Sql_Query(SqlHandle, "SELECT charid, partyflag FROM accounts_parties WHERE partyid = %d;", m_PartyID);

    if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) > 0)
    {
        uint8 j = 0;
        while (Sql_NextRow(SqlHandle) == SQL_SUCCESS)
        {
            uint32 charid = Sql_GetUIntData(SqlHandle, 0);
            uint16 memberflags = Sql_GetUIntData(SqlHandle, 1);

            if (memberflags & PARTY_LEADER)
            {
                bool found = false;
                for (auto member : members)
                {
                    if (member->id == charid)
                    {
                        m_PLeader = member;
                        found = true;
                    }
                }
                if (!found)
                {
                    m_PLeader = NULL;
                }
            }
            if (memberflags & PARTY_QM)
            {
                bool found = false;
                for (auto member : members)
                {
                    if (member->id == charid)
                    {
                        m_PQuaterMaster = member;
                        found = true;
                    }
                }
                if (!found)
                {
                    m_PQuaterMaster = NULL;
                }
            }
        }
    }
	//alliance
	if (this->m_PAlliance != NULL)
	{
		for (uint8 a = 0; a < m_PAlliance->partyList.size(); ++a)
		{
			for (uint8 i = 0; i < m_PAlliance->partyList.at(a)->members.size(); ++i)
			{
				CCharEntity* PChar = (CCharEntity*)m_PAlliance->partyList.at(a)->members.at(i);
                PChar->ReloadPartyDec();
				uint16 alliance = 0;
				PChar->pushPacket(new CPartyDefinePacket(m_PAlliance->partyList.at(a)));
				int ret = Sql_Query(SqlHandle, "SELECT chars.charid, chars.charname, partyflag, pos_zone, partyid FROM accounts_parties \
												LEFT JOIN chars ON accounts_parties.charid = chars.charid WHERE \
												allianceid = %d ORDER BY partyflag & %u, timestamp;",
												m_PAlliance->m_AllianceID, PARTY_SECOND | PARTY_THIRD);
				if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) > 0)
				{
					uint8 j = 0;
					while (Sql_NextRow(SqlHandle) == SQL_SUCCESS)
					{
						if (Sql_GetUIntData(SqlHandle, 2) & (PARTY_SECOND | PARTY_THIRD) != alliance)
						{
							alliance = Sql_GetUIntData(SqlHandle, 2) & (PARTY_SECOND | PARTY_THIRD);
							j = 0;
						}
						CCharEntity* PPartyMember = zoneutils::GetChar(Sql_GetUIntData(SqlHandle, 0));
						if (PPartyMember)
						{
							PChar->pushPacket(new CPartyMemberUpdatePacket(PPartyMember, j, PChar->getZone()));
						}
						else
						{
							PChar->pushPacket(new CPartyMemberUpdatePacket(
								Sql_GetUIntData(SqlHandle, 0), Sql_GetData(SqlHandle, 1),
								Sql_GetUIntData(SqlHandle, 2), Sql_GetUIntData(SqlHandle, 3)));
						}
						j++;
					}
				}
			}
		}
	}
	else

	//regular party
	for (uint8 i = 0; i < members.size(); ++i)
Exemple #24
0
void CParty::RemoveMember(CBattleEntity* PEntity)
{
    DSP_DEBUG_BREAK_IF(PEntity == nullptr);
    DSP_DEBUG_BREAK_IF(PEntity->PParty != this);

    if (m_PLeader == PEntity)
    {
        RemovePartyLeader(PEntity);
    }
    else
    {
        for (uint32 i = 0; i < members.size(); ++i)
        {
            if (PEntity == members.at(i))
            {
                members.erase(members.begin() + i);

                if (m_PartyType == PARTY_PCS)
                {
                    CCharEntity* PChar = (CCharEntity*)PEntity;

                    if (m_PQuaterMaster == PChar)
                    {
                        SetQuarterMaster(nullptr);
                    }
                    if (m_PSyncTarget == PChar)
                    {
                        SetSyncTarget(nullptr, 553);
                        CStatusEffect* sync = PChar->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
                        if (sync && sync->GetDuration() == 0)
                        {
                            PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 30, 553));
                            sync->SetStartTime(server_clock::now());
                            sync->SetDuration(30000);
                        }
                        DisableSync();
                    }
                    if (m_PSyncTarget != nullptr && m_PSyncTarget != PChar)
                    {
                        if (PChar->status != STATUS_DISAPPEAR)
                        {
                            CStatusEffect* sync = PChar->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
                            if (sync && sync->GetDuration() == 0)
                            {
                                PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 30, 553));
                                sync->SetStartTime(server_clock::now());
                                sync->SetDuration(30000);
                            }
                        }
                    }
                    PChar->PLatentEffectContainer->CheckLatentsPartyMembers(members.size());

                    PChar->pushPacket(new CPartyDefinePacket(nullptr));
                    PChar->pushPacket(new CPartyMemberUpdatePacket(PChar, 0, 0, PChar->getZone()));
                    PChar->pushPacket(new CCharUpdatePacket(PChar));
                    PChar->PParty = nullptr;

                    Sql_Query(SqlHandle, "DELETE FROM accounts_parties WHERE charid = %u;", PChar->id);

                    uint8 data[4] {};
                    ref<uint32>(data, 0) = m_PartyID;
                    message::send(MSG_PT_RELOAD, data, sizeof data, nullptr);

                    if (PChar->PTreasurePool != nullptr &&
                        PChar->PTreasurePool->GetPoolType() != TREASUREPOOL_ZONE)
                    {
                        PChar->PTreasurePool->DelMember(PChar);
                        PChar->PTreasurePool = new CTreasurePool(TREASUREPOOL_SOLO);
                        PChar->PTreasurePool->AddMember(PChar);
                        PChar->PTreasurePool->UpdatePool(PChar);
                    }
                }
                break;
            }
        }
    }
}
bool CStatusEffectContainer::AddStatusEffect(CStatusEffect* PStatusEffect, bool silent)
{
    if(PStatusEffect == nullptr){
        ShowWarning("status_effect_container::AddStatusEffect Status effect given was nullptr!\n");
        return false;
    }

    uint16 statusId = PStatusEffect->GetStatusID();

    if(statusId >= MAX_EFFECTID){
        ShowWarning("status_effect_container::AddStatusEffect statusId given is OVER limit %d\n", statusId);
        return false;
    }

	if(CanGainStatusEffect((EFFECT)statusId, PStatusEffect->GetPower()))
	{

            // check for minimum duration
            if(PStatusEffect->GetDuration() < effects::EffectsParams[statusId].MinDuration){
                PStatusEffect->SetDuration(effects::EffectsParams[statusId].MinDuration);
            }

        // remove clean up other effects
        OverwriteStatusEffect(PStatusEffect);

        PStatusEffect->SetOwner(m_POwner);

        SetEffectParams(PStatusEffect);

        // remove effects with same type
        DelStatusEffectsByType(PStatusEffect->GetType());

        PStatusEffect->SetStartTime(gettick());

        m_StatusEffectList.push_back(PStatusEffect);

        luautils::OnEffectGain(m_POwner, PStatusEffect);

        m_POwner->addModifiers(&PStatusEffect->modList);

        if (PStatusEffect->GetStatusID() >= EFFECT_FIRE_MANEUVER &&
            PStatusEffect->GetStatusID() <= EFFECT_DARK_MANEUVER &&
            m_POwner->objtype == TYPE_PC)
        {
            puppetutils::CheckAttachmentsForManeuver((CCharEntity*)m_POwner, PStatusEffect->GetStatusID(), true);
        }

        if( m_POwner->health.maxhp != 0) //make sure we're not in the middle of logging in
        {
            m_POwner->UpdateHealth();
        }

        if (m_POwner->objtype == TYPE_PC)
        {
            CCharEntity* PChar = (CCharEntity*)m_POwner;

            if (PStatusEffect->GetIcon() != 0)
            {
                UpdateStatusIcons();
            }

			if( m_POwner->health.maxhp != 0) //make sure we're not in the middle of logging in
			{
				//check for latents
				PChar->PLatentEffectContainer->CheckLatentsFoodEffect();
				PChar->PLatentEffectContainer->CheckLatentsStatusEffect();
                PChar->PLatentEffectContainer->CheckLatentsRollSong(PStatusEffect->GetFlag() & (EFFECTFLAG_SONG | EFFECTFLAG_ROLL));
				PChar->UpdateHealth();

				PChar->pushPacket(new CCharHealthPacket(PChar));
			}
            PChar->pushPacket(new CCharSyncPacket(PChar));
        }
        m_POwner->updatemask |= UPDATE_HP;

        return true;
	}

    return false;
}
Exemple #26
0
void CParty::ReloadParty()
{
    auto info = GetPartyInfo();

    //alliance
    if (this->m_PAlliance != nullptr)
    {
        for (auto&& party : m_PAlliance->partyList)
        {
            party->RefreshFlags(info);
            for (auto&& member : party->members)
            {
                CCharEntity* PChar = (CCharEntity*)member;
                PChar->ReloadPartyDec();
                uint16 alliance = 0;
                PChar->pushPacket(new CPartyDefinePacket(party));
                //auto effects = std::make_unique<CPartyEffectsPacket>();
                uint8 j = 0;
                for (auto&& memberinfo : info)
                {
                    if ((memberinfo.flags & (PARTY_SECOND | PARTY_THIRD)) != alliance)
                    {
                        alliance = memberinfo.flags & (PARTY_SECOND | PARTY_THIRD);
                        j = 0;
                    }
                    auto PPartyMember = zoneutils::GetChar(memberinfo.id);
                    if (PPartyMember)
                    {
                        PChar->pushPacket(new CPartyMemberUpdatePacket(PPartyMember, j, memberinfo.flags, PChar->getZone()));
                        //if (memberinfo.partyid == party->GetPartyID() && PPartyMember != PChar)
                        //    effects->AddMemberEffects(PChar);
                    }
                    else
                    {
                        uint16 zoneid = memberinfo.zone == 0 ? memberinfo.prev_zone : memberinfo.zone;
                        PChar->pushPacket(new CPartyMemberUpdatePacket(
                            memberinfo.id, (const int8*)memberinfo.name.c_str(),
                            memberinfo.flags, j, zoneid));
                    }
                    j++;
                }
                //PChar->pushPacket(effects.release());
            }
        }
    }
    else
    {
        RefreshFlags(info);
        //regular party
        for (uint8 i = 0; i < members.size(); ++i)
        {
            CCharEntity* PChar = (CCharEntity*)members.at(i);

            PChar->PLatentEffectContainer->CheckLatentsPartyJobs();
            PChar->PLatentEffectContainer->CheckLatentsPartyMembers(members.size());
            PChar->PLatentEffectContainer->CheckLatentsPartyAvatar();
            PChar->ReloadPartyDec();
            PChar->pushPacket(new CPartyDefinePacket(this));
            //auto effects = std::make_unique<CPartyEffectsPacket>();
            uint8 j = 0;
            for (auto&& memberinfo : info)
            {
                auto PPartyMember = zoneutils::GetChar(memberinfo.id);
                if (PPartyMember)
                {
                    PChar->pushPacket(new CPartyMemberUpdatePacket(PPartyMember, j, memberinfo.flags, PChar->getZone()));
                    //if (PPartyMember != PChar)
                    //    effects->AddMemberEffects(PChar);
                }
                else
                {
                    uint16 zoneid = memberinfo.zone == 0 ? memberinfo.prev_zone : memberinfo.zone;
                    PChar->pushPacket(new CPartyMemberUpdatePacket(
                        memberinfo.id, (const int8*)memberinfo.name.c_str(),
                        memberinfo.flags, j, zoneid));
                    //effects->AddMemberEffects(memberinfo.id);
                }
                j++;
            }
            //PChar->pushPacket(effects.release());
        }
    }
}
Exemple #27
0
void CZoneEntities::DecreaseZoneCounter(CCharEntity* PChar)
{
	DSP_DEBUG_BREAK_IF(PChar == nullptr);
	DSP_DEBUG_BREAK_IF(PChar->loc.zone != m_zone);

	//remove pets
	if (PChar->PPet != nullptr)
	{
		charutils::BuildingCharPetAbilityTable(PChar, (CPetEntity*)PChar->PPet, 0);//blank the pet commands
		if (PChar->PPet->isCharmed) {
			petutils::DespawnPet(PChar);
		}
		else {
			PChar->PPet->status = STATUS_DISAPPEAR;
			if (((CPetEntity*)(PChar->PPet))->getPetType() == PETTYPE_AVATAR)
				PChar->setModifier(MOD_AVATAR_PERPETUATION, 0);
		}
		// It may have been nullptred by DespawnPet
		if (PChar->PPet != nullptr) {
			PChar->PPet->PBattleAI->SetCurrentAction(ACTION_NONE);
			DeletePET(PChar->PPet);//remove the TID for this pet

			for (EntityList_t::const_iterator it = m_charList.begin(); it != m_charList.end(); ++it)
			{
				//inform other players of the pets removal
				CCharEntity* PCurrentChar = (CCharEntity*)it->second;
				SpawnIDList_t::iterator PET = PCurrentChar->SpawnPETList.find(PChar->PPet->id);

				if (PET != PCurrentChar->SpawnPETList.end())
				{
					PCurrentChar->SpawnPETList.erase(PET);
					PCurrentChar->pushPacket(new CEntityUpdatePacket(PChar->PPet, ENTITY_DESPAWN, UPDATE_NONE));
				}
			}
			PChar->PPet = nullptr;
		}
	}

	//remove bcnm status
	if (m_zone->m_BattlefieldHandler != nullptr && PChar->StatusEffectContainer->HasStatusEffect(EFFECT_BATTLEFIELD))
	{
		if (m_zone->m_BattlefieldHandler->disconnectFromBcnm(PChar)){
			ShowDebug("Removed %s from the BCNM they were in as they have left the zone.\n", PChar->GetName());
		}

		if (PChar->loc.destination == 0){ //this player is disconnecting/logged out, so move them to the entrance
			//move depending on zone
			int pos[4] = { 0, 0, 0, 0 };
			battlefieldutils::getStartPosition(m_zone->GetID(), pos);
			if (pos != nullptr){
				PChar->loc.p.x = pos[0];
				PChar->loc.p.y = pos[1];
				PChar->loc.p.z = pos[2];
				PChar->loc.p.rotation = pos[3];
                PChar->updatemask |= UPDATE_POS;
				charutils::SaveCharPosition(PChar);
			}
			else{
				ShowWarning("%s has disconnected from the BCNM but cannot move them to the lobby as the lobby position is unknown!\n", PChar->GetName());
			}
		}
	}
	else if (m_zone->m_BattlefieldHandler != nullptr && PChar->StatusEffectContainer->HasStatusEffect(EFFECT_DYNAMIS, 0))
	{
		if (m_zone->m_BattlefieldHandler->disconnectFromDynamis(PChar)){
			ShowDebug("Removed %s from the BCNM they were in as they have left the zone.\n", PChar->GetName());
		}

		if (PChar->loc.destination == 0){ //this player is disconnecting/logged out, so move them to the entrance
			//move depending on zone
			int pos[4] = { 0, 0, 0, 0 };
			battlefieldutils::getStartPosition(m_zone->GetID(), pos);
            if (!(pos[0] == 0 && pos[1] == 0 && pos[2] == 0 && pos[3] == 0)){
				PChar->loc.p.x = pos[0];
				PChar->loc.p.y = pos[1];
				PChar->loc.p.z = pos[2];
				PChar->loc.p.rotation = pos[3];
                PChar->updatemask |= UPDATE_POS;
				charutils::SaveCharPosition(PChar);
			}
			else{
				ShowWarning("%s has disconnected from the BCNM but cannot move them to the lobby as the lobby position is unknown!\n", PChar->GetName());
			}
		}
	}

    for (auto PCharIt : m_charList)
    {
        CCharEntity* PCurrentChar = (CCharEntity*)PCharIt.second;
        if (PCurrentChar->PBattleAI->m_PMagicState->GetTarget() == PChar)
        {
            PCurrentChar->PBattleAI->m_PMagicState->ClearTarget();
        }
    }

	for (auto PMobIt : m_mobList)
	{
        CMobEntity* PCurrentMob = (CMobEntity*)PMobIt.second;
		PCurrentMob->PEnmityContainer->Clear(PChar->id);
		if (PCurrentMob->m_OwnerID.id == PChar->id)
        {
			PCurrentMob->m_OwnerID.clean();
            PCurrentMob->updatemask |= UPDATE_STATUS;
		}
        if (PCurrentMob->PBattleAI->m_PMagicState->GetTarget() == PChar)
        {
            PCurrentMob->PBattleAI->m_PMagicState->ClearTarget();
        }
        if (PCurrentMob->PBattleAI->GetBattleSubTarget() == PChar)
        {
            PCurrentMob->PBattleAI->SetBattleSubTarget(nullptr);
        }
	}
    for (auto PPetIt : m_petList)
    {
        CPetEntity* PCurrentPet = (CPetEntity*)PPetIt.second;
        if (PCurrentPet->PBattleAI->m_PMagicState->GetTarget() == PChar)
        {
            PCurrentPet->PBattleAI->m_PMagicState->ClearTarget();
        }
        if (PCurrentPet->PBattleAI->GetBattleSubTarget() == PChar)
        {
            PCurrentPet->PBattleAI->SetBattleSubTarget(nullptr);
        }
    }

	// TODO: могут возникать проблемы с переходом между одной и той же зоной (zone == prevzone)

	m_charList.erase(PChar->targid);

	ShowDebug(CL_CYAN"CZone:: %s DecreaseZoneCounter <%u> %s\n" CL_RESET, m_zone->GetName(), m_charList.size(), PChar->GetName());
}
Exemple #28
0
void CParty::SetSyncTarget(int8* MemberName, uint16 message)
{
    CBattleEntity* PEntity = nullptr;
    if (MemberName)
    {
        PEntity = GetMemberByName(MemberName);
    }

    if (map_config.level_sync_enable)
    {
        if (PEntity && PEntity->objtype == TYPE_PC)
        {
            CCharEntity* PChar = (CCharEntity*)PEntity;
            //enable level sync
            if (PChar->GetMLevel() < 10)
            {
                ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 10, 541));
                return;
            }
            else if (PChar->getZone() != GetLeader()->getZone())
            {
                ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 0, 542));
                return;
            }
            else
            {
                for (uint8 i = 0; i < members.size(); ++i)
                {
                    if (members.at(i)->StatusEffectContainer->HasStatusEffect({EFFECT_LEVEL_RESTRICTION, EFFECT_LEVEL_SYNC}))
                    {
                        ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 0, 543));
                        return;
                    }
                }
                m_PSyncTarget = PChar;
                for (uint8 i = 0; i < members.size(); ++i)
                {
                    if (members.at(i)->objtype != TYPE_PC) continue;

                    CCharEntity* member = (CCharEntity*)members.at(i);

                    if (member->status != STATUS_DISAPPEAR &&
                        member->getZone() == PChar->getZone())
                    {
                        member->pushPacket(new CMessageStandardPacket(PChar->GetMLevel(), 0, 0, 0, message));
                        member->StatusEffectContainer->AddStatusEffect(new CStatusEffect(
                            EFFECT_LEVEL_SYNC,
                            EFFECT_LEVEL_SYNC,
                            PChar->GetMLevel(),
                            0,
                            0), true);
                        member->StatusEffectContainer->DelStatusEffectsByFlag(EFFECTFLAG_DISPELABLE | EFFECTFLAG_ON_ZONE);
                        member->loc.zone->PushPacket(member, CHAR_INRANGE, new CCharSyncPacket(member));
                    }
                }
                Sql_Query(SqlHandle, "UPDATE accounts_parties SET partyflag = partyflag & ~%d WHERE partyid = %u AND partyflag & %d", PARTY_SYNC, m_PartyID, PARTY_SYNC);
                Sql_Query(SqlHandle, "UPDATE accounts_parties SET partyflag = partyflag | %d WHERE partyid = %u AND charid = '%u';", PARTY_SYNC, m_PartyID, PChar->id);
            }
        }
        else
        {
            if (m_PSyncTarget != nullptr)
            {
                //disable level sync
                for (uint8 i = 0; i < members.size(); ++i)
                {
                    if (members.at(i)->objtype != TYPE_PC) continue;

                    CCharEntity* member = (CCharEntity*)members.at(i);

                    if (member->status != STATUS_DISAPPEAR)
                    {
                        CStatusEffect* sync = member->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
                        if (sync && sync->GetDuration() == 0)
                        {
                            member->pushPacket(new CMessageBasicPacket(member, member, 10, 30, message));
                            sync->SetStartTime(server_clock::now());
                            sync->SetDuration(30000);
                        }
                    }
                }
            }
            m_PSyncTarget = nullptr;
            Sql_Query(SqlHandle, "UPDATE accounts_parties SET partyflag = partyflag & ~%d WHERE partyid = %u AND partyflag & %d", PARTY_SYNC, m_PartyID, PARTY_SYNC);
        }
    }
}
Exemple #29
0
void CZoneEntities::PushPacket(CBaseEntity* PEntity, GLOBAL_MESSAGE_TYPE message_type, CBasicPacket* packet)
{
	// Do not send packets that are updates of a hidden GM..
	if (packet != nullptr && packet->id() == 0x00D && PEntity != nullptr && PEntity->objtype == TYPE_PC && ((CCharEntity*)PEntity)->m_isGMHidden)
	{
		// Ensure this packet is not despawning us..
		if (packet->ref<uint8>(0x0A) != 0x20)
		{
			delete packet;
			return;
		}
	}

	if (!m_charList.empty())
	{
		switch (message_type)
		{
			case CHAR_INRANGE_SELF:
			{
				if (PEntity->objtype == TYPE_PC)
				{
					((CCharEntity*)PEntity)->pushPacket(new CBasicPacket(*packet));
				}
			}
			case CHAR_INRANGE:
			{
				for (EntityList_t::const_iterator it = m_charList.begin(); it != m_charList.end(); ++it)
				{
					CCharEntity* PCurrentChar = (CCharEntity*)it->second;
					if (PEntity != PCurrentChar)
					{
						if (distance(PEntity->loc.p, PCurrentChar->loc.p) < 50 && 
                            ((PEntity->objtype != TYPE_PC) || (((CCharEntity*)PEntity)->m_moghouseID == PCurrentChar->m_moghouseID)))
						{
							if (packet != nullptr && packet->id() == 0x00E &&
                                (packet->ref<uint8>(0x0A) != 0x20 || packet->ref<uint8>(0x0A) != 0x0F))
							{
								uint32 id = packet->ref<uint32>(0x04);
                                uint16 targid = packet->ref<uint16>(0x08);

								CBaseEntity* entity = GetEntity(targid);

								SpawnIDList_t spawnlist;

								if (entity)
								{
									if (entity->targid < 0x400)
									{
										if (entity->objtype == TYPE_MOB)
										{
											spawnlist = PCurrentChar->SpawnMOBList;
										}
										else if (entity->objtype == TYPE_NPC)
										{
											spawnlist = PCurrentChar->SpawnNPCList;
										}
									}
									else if (entity->targid >= 0x700)
									{
										spawnlist = PCurrentChar->SpawnPETList;
									}
									else
									{
										entity = nullptr;
									}
								}
								if (!entity)
								{
									// got a char or nothing as the target of this entity update (which really shouldn't happen ever)
									// so we're just going to skip this packet
									break;
								}
								SpawnIDList_t::iterator iter = spawnlist.lower_bound(id);

								if (!(iter == spawnlist.end() ||
									spawnlist.key_comp()(id, iter->first)))
								{
									PCurrentChar->pushPacket(new CBasicPacket(*packet));
								}
							}
							else
							{
								PCurrentChar->pushPacket(new CBasicPacket(*packet));
							}
						}
					}
				}
			}
			break;
			case CHAR_INSHOUT:
			{
				for (EntityList_t::const_iterator it = m_charList.begin(); it != m_charList.end(); ++it)
				{
					CCharEntity* PCurrentChar = (CCharEntity*)it->second;
					if (PEntity != PCurrentChar)
					{
						if (distance(PEntity->loc.p, PCurrentChar->loc.p) < 180 && 
                            ((PEntity->objtype != TYPE_PC) || (((CCharEntity*)PEntity)->m_moghouseID == PCurrentChar->m_moghouseID)))
						{
							PCurrentChar->pushPacket(new CBasicPacket(*packet));
						}
					}
				}
			}
			break;
			case CHAR_INZONE:
			{
				for (EntityList_t::const_iterator it = m_charList.begin(); it != m_charList.end(); ++it)
				{
					CCharEntity* PCurrentChar = (CCharEntity*)it->second;

                    if (PCurrentChar->m_moghouseID == 0)
                    {
                        if (PEntity != PCurrentChar)
                        {
                            PCurrentChar->pushPacket(new CBasicPacket(*packet));
                        }
                    }
				}
			}
			break;
		}
	}
	delete packet;
}
Exemple #30
0
int32 map_cleanup(uint32 tick, CTaskMgr::CTask* PTask)
{
    map_session_list_t::iterator it = map_session_list.begin();

    while (it != map_session_list.end())
    {
        map_session_data_t* map_session_data = it->second;

        CCharEntity* PChar = map_session_data->PChar;

        if ((time(nullptr) - map_session_data->last_update) > 5)
        {
            if (PChar != nullptr && !(PChar->nameflags.flags & FLAG_DC))
            {

                PChar->nameflags.flags |= FLAG_DC;
                PChar->updatemask |= UPDATE_HP;
                if (PChar->status == STATUS_NORMAL)
                {
                    PChar->loc.zone->SpawnPCs(PChar);
                }
            }
            if ((time(nullptr) - map_session_data->last_update) > map_config.max_time_lastupdate)
            {
                if (PChar != nullptr)
                {
                    if (map_session_data->shuttingDown == 0)
                    {
                        //[Alliance] fix to stop server crashing:
                        //if a party within an alliance only has 1 char (that char will be party leader)
                        //if char then disconnects we need to tell the server about the alliance change
                        if (PChar->PParty != nullptr && PChar->PParty->m_PAlliance != nullptr && PChar->PParty->GetLeader() == PChar)
                        {
                            if (PChar->PParty->members.size() == 1)
                            {
                                if (PChar->PParty->m_PAlliance->partyList.size() == 1)
                                {
                                    PChar->PParty->m_PAlliance->dissolveAlliance();
                                }
                                else
                                {
                                    PChar->PParty->m_PAlliance->removeParty(PChar->PParty);
                                }
                            }
                        }


                        // uncharm pet if player d/c
                        if (PChar->PPet != nullptr && PChar->PPet->objtype == TYPE_MOB)
                        {
                            petutils::DespawnPet(PChar);
                        }

                        PChar->StatusEffectContainer->SaveStatusEffects(true);
                        ShowDebug(CL_CYAN"map_cleanup: %s timed out, closing session\n" CL_RESET, PChar->GetName());

                        PChar->status = STATUS_SHUTDOWN;
                        PacketParser[0x00D](map_session_data, PChar, 0);
                    }
                    else
                    {
                        map_session_data->PChar->StatusEffectContainer->SaveStatusEffects(true);
                        Sql_Query(SqlHandle, "DELETE FROM accounts_sessions WHERE charid = %u;", map_session_data->PChar->id);

                        aFree(map_session_data->server_packet_data);
                        delete map_session_data->PChar;
                        delete map_session_data;
                        map_session_data = nullptr;

                        map_session_list.erase(it++);
                        continue;
                    }
                }
                else if (map_session_data->shuttingDown == 0)
                {

                    ShowWarning(CL_YELLOW"map_cleanup: WHITHOUT CHAR timed out, session closed\n" CL_RESET);

                    const int8* Query = "DELETE FROM accounts_sessions WHERE client_addr = %u AND client_port = %u";
                    Sql_Query(SqlHandle, Query, map_session_data->client_addr, map_session_data->client_port);

                    aFree(map_session_data->server_packet_data);
                    map_session_list.erase(it++);
                    delete map_session_data;
                    continue;
                }
            }
        }
        else if (PChar != nullptr && (PChar->nameflags.flags & FLAG_DC))
        {
            PChar->nameflags.flags &= ~FLAG_DC;
            PChar->updatemask |= UPDATE_HP;
            PChar->pushPacket(new CCharUpdatePacket(PChar));

            if (PChar->status == STATUS_NORMAL)
            {
                PChar->loc.zone->SpawnPCs(PChar);
            }
            charutils::SaveCharStats(PChar);
        }
        ++it;
    }
    return 0;
}