⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 magic.cpp

📁 网络游戏魔域的服务端与客户端完整源代码 包括详细的说明文档与开发日志
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		return;

	DWORD	dwProf = m_pOwner->GetProfession();
	for(int i = 0; i < m_setData->GetAmount(); i++)
	{
		IMagicData* pData = m_setData->GetObjByIndex(i);
		if(pData && pData->GetInt(MAGICDATA_NEED_EXP) == AUTOLEVELUP_EXP
				&& pData->GetInt(MAGICDATA_USE_XP) != TYPE_KONGFU
				&& nOwnerLev >= pData->GetInt(MAGICDATA_NEED_LEVEL)
				&& this->CheckProfession(dwProf, pData->GetInt(MAGICDATA_NEED_PROFMASK))
				&& !IsWeaponMagic(pData->GetInt(MAGICDATA_TYPE))
			)
		{
			int nNewLevel = pData->GetInt(MAGICDATA_LEVEL) + 1;

			pData->SetInt(MAGICDATA_LEVEL, nNewLevel);
			pData->Update();
//			ASSERT(pData->FindType());

			if ((pData->GetInt(MAGICDATA_AUTO_ACTIVE) & AUTOACTIVE_HIDDEN) == 0)
			{
				CMsgMagicInfo	msg;
				IF_OK(msg.Create(m_pOwner->GetID(), pData->GetInt(MAGICDATA_TYPE), nNewLevel, 0))
					m_pOwner->SendMsg(&msg);
			}
		}
	}
}

//////////////////////////////////////////////////////////////////////
void CMagic::UserWeaponSkillUpLevel(int nWeaponSkillType, int nWeaponSkillLevel)
{
	if(m_setData->GetAmount() == 0)
		return;

	DWORD	dwProf = m_pOwner->GetProfession();
	for(int i = 0; i < m_setData->GetAmount(); i++)
	{
		IMagicData* pData = m_setData->GetObjByIndex(i);
		if(pData && pData->GetInt(MAGICDATA_NEED_EXP) == AUTOLEVELUP_EXP
				&& pData->GetInt(MAGICDATA_USE_XP) == TYPE_KONGFU
				&& pData->GetInt(MAGICDATA_WEAPON_SUBTYPE) == nWeaponSkillType
				&& nWeaponSkillLevel >= pData->GetInt(MAGICDATA_NEED_LEVEL)
				&& this->CheckProfession(dwProf, pData->GetInt(MAGICDATA_NEED_PROFMASK))
				&& !IsWeaponMagic(pData->GetInt(MAGICDATA_TYPE))
			)
		{
			int nNewLevel = pData->GetInt(MAGICDATA_LEVEL) + 1;

			pData->SetInt(MAGICDATA_LEVEL, nNewLevel);
			pData->Update();
//			ASSERT(pData->FindType());

			if ((pData->GetInt(MAGICDATA_AUTO_ACTIVE) & AUTOACTIVE_HIDDEN) == 0)
			{
				CMsgMagicInfo	msg;
				IF_OK(msg.Create(m_pOwner->GetID(), pData->GetInt(MAGICDATA_TYPE), nNewLevel, 0))
					m_pOwner->SendMsg(&msg);
			}
		}
	}
}

//////////////////////////////////////////////////////////////////////
bool CMagic::AutoLearnWeaponSkill(int nWeaponSkillType, int nWeaponSkillLevel, int nWeaponSkillExp/*=0*/)
{
	CMagicTypeData* pLearnMagic = NULL;
	for(int i = 0; i < AutoMagicTypeSet()->GetAmount(); i++)		//??? 可优化
	{
		CMagicTypeData* pData = AutoMagicTypeSet()->GetObjByIndex(i);
		if(pData && pData->GetInt(MAGICTYPEDATA_AUTO_LEARN)
				&& pData->GetInt(MAGICTYPEDATA_WEAPON_SUBTYPE) == nWeaponSkillType
				&& nWeaponSkillLevel >= pData->GetInt(MAGICTYPEDATA_LEARN_LEVEL)%100		// %100: min level of need, 1208->max=12,min=8
				&& FindMagic(pData->GetInt(MAGICTYPEDATA_TYPE)) == NULL )
		{
			int nMinLevel = pData->GetInt(MAGICTYPEDATA_LEARN_LEVEL) % 100;
			int nMaxLevel = pData->GetInt(MAGICTYPEDATA_LEARN_LEVEL) / 100;

			if(nMaxLevel == 0 || nWeaponSkillLevel >= nMaxLevel)
			{
				pLearnMagic = pData;
				break;
			}
			else if(nWeaponSkillExp > 0)
			{
				ASSERT(nMinLevel < nMaxLevel);
				int nExp = 0;
				for(int i = nMinLevel; i < nMaxLevel; i++)
				{
					CHECKF(i >= 1 && i < MAX_WEAPONSKILLLEVEL);
					nExp += nWeaponSkillLeveUpNeedExp[i];
				}

				const int nMaxRand = 30000;

				int nRand = (nExp / nWeaponSkillExp) / 2;
				if(nRand <= nMaxRand && ::RandGet(nRand) == 0 || nRand > nMaxRand && ::RandGet(nMaxRand) == 0 && ::RandGet(nRand/nMaxRand) == 0)
				{
					pLearnMagic = pData;
					break;
				}
			}
		}
	}

	if(pLearnMagic)
	{
		LearnMagic(pLearnMagic->GetInt(MAGICTYPEDATA_TYPE), pLearnMagic->GetInt(MAGICTYPEDATA_LEVEL));

		return true;
	}
	return false;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::UserKillTarget(IRole* pTarget)
{
	for(int i = 0; i < m_setData->GetAmount(); i++)
	{
		IMagicData* pData = m_setData->GetObjByIndex(i);
		if( pData && (pData->GetInt(MAGICDATA_AUTO_ACTIVE) & AUTOACTIVE_KILL)
				&& !m_pOwner->QueryTransformation()
				&& (!pData->GetInt(MAGICDATA_WEAPON_SUBTYPE) || m_pOwner->CheckWeaponSubType(pData->GetInt(MAGICDATA_WEAPON_SUBTYPE)))
				&& ::RandGet(100) < pData->GetInt(MAGICDATA_PERCENT) )
		{
			// backup
			IMagicData*	pMagic		= m_pMagic;
			OBJID		idTarget	= m_idTarget;
			POINT		pos;
			pos.x			= m_pos.x;
			pos.y			= m_pos.y;

			switch(pData->GetInt(MAGICDATA_SORT))
			{
			case	MAGICSORT_RECRUIT:
				{
					m_pMagic		= pData;
					m_idTarget		= m_pOwner->GetID();
					m_pos.x			= m_pOwner->GetPosX();
					m_pos.y			= m_pOwner->GetPosY();
					ProcessRecruit();
				}
				break;
			case	MAGICSORT_SERIALCUT:
				{
					m_pMagic		= pData;
					m_idTarget		= pTarget->GetID();
					m_pos.x			= pTarget->GetPosX();
					m_pos.y			= pTarget->GetPosY();
					ProcessSerialCut();
				}
				break;
			}

			// restore
			m_pMagic		= pMagic;
			m_idTarget		= idTarget;
			m_pos.x			= pos.x;
			m_pos.y			= pos.y;

			return true;
		}
	}

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::AutoAttackTarget(IRole* pTarget)
{
	int nPercentAdjust = 100;
	// 幻兽发动技能的概率调整
	CMonster* pMonster = NULL;
	if (m_pOwner->QueryObj(OBJ_MONSTER, IPP_OF(pMonster)) && pMonster->IsEudemon())
	{
		if (pMonster->GetFidelity() < 500)
			nPercentAdjust = 0;
		else
			nPercentAdjust = 150 + 5*((pMonster->GetFidelity()-500)/50);
	}
	
	for(int i = 0; i < m_setData->GetAmount(); i++)		//??? 可优化
	{
		IMagicData* pData = m_setData->GetObjByIndex(i);
		if( pData && (pData->GetInt(MAGICDATA_AUTO_ACTIVE) & AUTOACTIVE_RANDOM)
				&& !m_pOwner->QueryTransformation()
				&& (!pData->GetInt(MAGICDATA_WEAPON_SUBTYPE) 
					|| m_pOwner->CheckWeaponSubType(pData->GetInt(MAGICDATA_WEAPON_SUBTYPE))
					|| (pData->GetInt(MAGICDATA_SORT) == MAGICSORT_KO 
						&& pTarget->GetLife()*100/pTarget->GetMaxLife()<=MAGIC_KO_LIFE_PERCENT))
				&& ::RandGet(100) < (nPercentAdjust*pData->GetInt(MAGICDATA_PERCENT)/100))
		{
			
			return MagicAttack(pData->GetInt(MAGICDATA_TYPE), pTarget->GetID(), pTarget->GetPosX(), pTarget->GetPosY(), AUTOACTIVE_RANDOM);
		}
	}

	return false;
}

//////////////////////////////////////////////////////////////////////
// timer
//////////////////////////////////////////////////////////////////////
void CMagic::OnTimer(DWORD tCurr)
{
	if (!m_pMagic)
		return;
	switch (m_nMagicState)
	{
	case MAGICSTATE_INTONE:
		{
			if (!m_tIntone.IsActive() || m_tIntone.TimeOver())
			{
#ifdef ZLONG_DEBUG
				m_pOwner->SendSysMsg("DEBUG: 魔法吟唱结束");
#endif
				if (!Launch())	// 魔法执行失败就结束——这里包括目标死亡、目标消失等情况
				{
					LockTarget(false);
					m_tApply.Clear();
					ResetDelay();
					break;
				}

				m_nMagicState	= MAGICSTATE_LAUNCH;
				// 魔法作用的次数由轨迹数来决定
				// 为了允许没有轨迹的魔法执行,默认作用次数为1,无轨迹
				m_nApplyTimes	= __max(1, m_pMagic->GetSTrackAmount());
				m_tApply.Startup(m_pMagic->GetApplyMS());
			}
		}
		break;
	case MAGICSTATE_LAUNCH:
		{
			if (!m_tApply.IsActive() || m_tApply.IsTimeOut())
			{
#ifdef ZLONG_DEBUG
				m_pOwner->SendSysMsg("Debug: 魔法施展结束");
#endif
				// MAGICSORT_ATTACK类型的魔法留在攻击结束后Kill目标
				if (m_pMagic->GetInt(MAGICDATA_SORT) == MAGICSORT_ATTACK
					&& m_idTarget != ID_NONE)
				{
					IRole* pTarget = RoleManager()->QueryRole(m_idTarget);
					if(pTarget && !pTarget->IsAlive())
					{
						m_pOwner->Kill(pTarget, GetDieMode());
					}
				}

				// 怪物死亡需要查询是否处于锁定状态,因此这里必须在Kill怪物之后解锁
				// 否则将不出现尸体消失状态
				LockTarget(false);

				ResetDelay();
				// OnTimer的调用频率为0.5秒,
				// 为了及时执行NextMagic,这里直接进入MAGICSTATE_DELAY
			}
			else
			{
				break;
			}
		}
//		break;
	case MAGICSTATE_DELAY:
		{
			if (!m_tDelay.IsActive())
			{
				m_nMagicState	= MAGICSTATE_NONE;
				break;
			}
			if(m_bAutoAttack
				&& m_pMagic->GetInt(MAGICDATA_NEXT_MAGIC) != ID_NONE)
//				&& m_pMagic->GetInt(MAGICDATA_NEXT_MAGIC) != m_pMagic->GetInt(MAGICDATA_TYPE))
			{
				if (m_tDelay.IsActive() && !m_tDelay.TimeOver())	// 必须等到魔法延迟结束才可以执行下一个魔法
					break;
#ifdef ZLONG_DEBUG
				m_pOwner->SendSysMsg("Debug: 执行下一个魔法。");
#endif
				// may be no next magic
				if(!FindMagic(m_pMagic->GetInt(MAGICDATA_NEXT_MAGIC)))
				{
					ASSERT(EquipWeaponMagic(SpawnMagicID(), m_pMagic->GetInt(MAGICDATA_NEXT_MAGIC), 0));
					m_tDelay.Clear();
					break;
				}
				m_nMagicState	= MAGICSTATE_NONE;
//				m_pOwner->SetDelay(0);
				MagicAttack(m_pMagic->GetInt(MAGICDATA_NEXT_MAGIC), m_idTarget, m_pos.x, m_pos.y);
				break;
			}
			if (m_tDelay.IsActive() && m_tDelay.TimeOver())
			{
#ifdef ZLONG_DEBUG
				m_pOwner->SendSysMsg("Debug: 魔法延迟结束");
#endif
				m_nMagicState	= MAGICSTATE_NONE;
			}
		}
		break;
	case MAGICSTATE_NONE:
	default:
		break;
	}
}

//////////////////////////////////////////////////////////////////////
// task
//////////////////////////////////////////////////////////////////////
bool CMagic::CheckType(int nType)
{
	return FindMagic(nType) != NULL;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::CheckLevel(int nType, int nLevel)
{
	IMagicData* pData = FindMagic(nType);
	if(pData && pData->GetInt(MAGICDATA_LEVEL) == nLevel)
		return true;
	return false;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::UpLevelByTask(int nType)
{
	IMagicData* pData = FindMagic(nType);
	if(!pData)
		return false;
	CHECKF(!IsWeaponMagic(pData->GetInt(MAGICDATA_TYPE)));

	int	nNewLevel = pData->GetInt(MAGICDATA_LEVEL) + 1;
	CHECKF(CMagic::FindMagicType(nType, nNewLevel));

	pData->SetInt(MAGICDATA_EXP, 0);
	pData->SetInt(MAGICDATA_LEVEL, nNewLevel);
	pData->Update();

//	if(bSynchro)
	if ((pData->GetInt(MAGICDATA_AUTO_ACTIVE) & AUTOACTIVE_HIDDEN) == 0)
	{
		CMsgMagicInfo msg;
		IF_OK(msg.Create(m_pOwner->GetID(), pData->GetInt(MAGICDATA_TYPE), nNewLevel, 0))
			m_pOwner->SendMsg(&msg);
	}

//	CHECKF(pData->FindType());
	return true;
}

//////////////////////////////////////////////////////////////////////
OBJID CMagic::LearnMagic(int nType, int nLevel/*=0*/, bool bSaveMagic/*=true*/)
{
	CHECKF(CMagic::FindMagicType(nType, nLevel));

	if(FindMagic(nType))
	{
		return ID_NONE;
	}

	DWORD	dwExp	= 0;
	OBJID	idMagic	= ID_NONE;

	IMagicData* pData = NULL;
	if (bSaveMagic)
	{
		// check unlearn magic
		SQLBUF	szSQL;
		sprintf(szSQL, "SELECT id FROM %s WHERE ownerid=%u && type=%d", _TBL_MAGIC, m_pOwner->GetID(), nType);
		CAutoPtr<IRecordset> pRes = _Database(PID)->CreateNewRecordset(szSQL);
		if(pRes)
			idMagic = pRes->GetInt(0);

		pData = CMagicData::CreateNew();
		CHECKF(pData);
		IF_NOT(pData->Create(GameDataDefault()->GetMagicData(), idMagic))
			return ID_NONE;
	}
	else
	{
		// 临时学会魔法,仅仅保存在内存中
		pData = CMagicTempData::CreateNew();
		CHECKF (pData);
		ST_MAGIC_DATA data;
		memset(&data, 0L, sizeof(ST_MAGIC_DATA));
		data.idMagic	= CMagic::SpawnMagicID();
		IF_NOT (pData->Create(&data))
			return ID_NONE;
		idMagic	= data.idMagic;
	}

	pData->SetInt(MAGICDATA_OWNERID, m_pOwner->GetID());
	pData->SetInt(MAGICDATA_TYPE, nType);
	pData->SetInt(MAGICDATA_LEVEL, nLevel);
	pData->SetInt(MAGICDATA_EXP, dwExp);
	pData->SetInt(MAGICDATA_UNLEARN, false);
	if(idMagic != ID_NONE)
	{
		pData->Update();
	}
	else
	{
		pData->SetInt(MAGICDATA_OLD_LEVEL, 0);
		idMagic = pData->InsertRecord();
	}
	pData->FindType();
	pData->SetDelay();		// 设置延迟

	// synchro
	if ((pData->GetInt(MAGICDATA_AUTO_ACTIVE) & AUTOACTIVE_HIDDEN) == 0)
	{
		CMsgMagicInfo msg;
		IF_OK(msg.Create(m_pOwner->GetID(),
						pData->GetInt(MAGICDATA_TYPE),
						pData->GetInt(MAGICDATA_LEVEL),
						pData->GetInt(MAGICDATA_EXP)))
			m_pOwner->SendMsg(&msg);
	}

	m_setData->AddObj(pData);
	return idMagic;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::UnlearnMagic(int nType, bool bDrop)
{
	IMagicData* pData = FindMagic(nType);
	if(!pData)
		return false;

	if(bDrop)
	{
		ASSERT(pData->DeleteRecord());
	}
	else
	{
		pData->SetInt(MAGICDATA_OLD_LEVEL, pData->GetInt(MAGICDATA_LEVEL));
		pData->SetInt(MAGICDATA_UNLEARN, true);
		pData->Update();
	}

	if(m_pMagic && m_pMagic->GetID() == pData->GetID())
		m_pMagic = NULL;
	m_setData->DelObj(pData->GetID());

	// synchro
	CMsgAction	msg;
	IF_OK(msg.Create(m_pOwner->GetID(), m_pOwner->GetPosX(), m_pOwner->GetPosY(), m_pOwner->GetDir(), actionDropMagic, nType))
		m_pOwner->SendMsg(&msg);

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::EquipWeaponMagic(OBJID idMagic, int nType, int nLevel)
{
//	CHECKF(IsWeaponMagic(nType));

	CMagicTypeData* pType = CMagic::FindMagicType(nType, nLevel);
	CHECKF(pType);

	DWORD	dwExp = 0;

	IMagicData* pData = CMagicData::CreateNew();
	CHECKF(pData);
	IF_NOT(pData->Create(GameDataDefault()->GetMagicData(), idMagic))
		return false;

	pData->SetInt(MAGICDATA_ID_, idMagic);
	pData->SetInt(MAGICDATA_OWNERID, m_pOwner->GetID());
	pData->SetInt(MAGICDATA_TYPE, nType);
	pData->SetInt(MAGICDATA_LEVEL, nLevel);
	pData->SetInt(MAGICDATA_EXP, dwExp);
	pData->ClearUpdateFlags();
	pData->FindType();

	m_setData->DelObj(idMagic);		// 冲掉
	m_setData->AddObj(pData);

	return true;
}

//////////////////////////////////////////////////////////////////////
bool CMagic::UnequipWeaponMagic(OBJID idMagic)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -