📄 magic_process.cpp
字号:
IRole* pRole = m_pOwner->FindAroundRole(idTarget);
CNpc* pNpc;
if(!pRole || !pRole->IsAlive() || pRole->QueryObj(OBJ_NPC, IPP_OF(pNpc)))
continue;
setRole.push_back(pRole);
if (m_pOwner->GetID() != pRole->GetID())
m_setTargetLocked.push_back(pRole->GetID());
}
}
else
{
IRole* pRole = m_pOwner->FindAroundRole(m_idTarget);
if(!pRole || !pRole->IsAlive())
return false;
setRole.push_back(pRole);
m_setTargetLocked.push_back(pRole->GetID());
}
if (m_pMagic->GetSTrackAmount() > 0)
LockTarget(true);
int nExp = 0;
for (int k=0; k<m_nApplyTimes; k++)
{
// 广播法术效果
CMsgMagicEffect msg;
IF_OK(msg.Create(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), m_idTarget, m_pOwner->GetDir()))
{
for(int i = 0; i < setRole.size(); i++)
{
IRole* pRole = setRole[i];
if (pRole && pRole->IsAlive())
{
int nPower = GetPower(k);
if (nPower == ADJUST_FULL)
nPower = pRole->GetMaxLife() - pRole->GetLife();
// 超级回复
if(m_pMagic && m_pMagic->GetInt(MAGICDATA_TYPE)>=SUPER_MAGIC_RECRUIT)
nPower *= m_pOwner->GetSoulSum();
setPower.push_back(nPower);
msg.AppendRole(setRole[i]->GetID(), nPower);
}
else
setPower.push_back(0);
}
m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
}
for(int i = 0; i < setRole.size(); i++)
{
if (!setRole[i]->IsAlive())
continue;
int nAddLife = ::CutOverflow(setPower[i], ::CutTrail(0, (int)(setRole[i]->GetMaxLife()-setRole[i]->GetLife())));
if(nAddLife > 0)
{
setRole[i]->AddAttrib(_USERATTRIB_LIFE, nAddLife, SYNCHRO_TRUE);
CUser* pUser=NULL;
if(setRole[i]->QueryObj(OBJ_USER, IPP_OF(pUser)))
pUser->BroadcastTeamLife();
}
CNpc* pNpc = NULL;
if (setRole[i])
{
setRole[i]->QueryObj(OBJ_NPC, IPP_OF(pNpc));
if(pNpc && pNpc->IsGoal())
{
nAddLife = nAddLife*GOAL_EXP_PERCENT/100;
}
}
nExp += nAddLife;
}
if (m_pMagic->GetSTrackAmount() > 0)
AdjustPosByTrack(k);
}
this->AwardExp(0);
return true;
}
//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessCross()
{
CHECKF(m_pMagic);
int nRange1 = m_pMagic->GetInt(MAGICDATA_RANGE) % 100;
int nRange2 = m_pMagic->GetInt(MAGICDATA_RANGE) / 100;
int nSize = nRange1*2 + 1;
int nBufSize = nSize * nSize;
MAPTHING_SET setTarget;
vector<IRole*> setRole;
vector<int> setPower;
POINT pos;
int nExp = 0;
int nPowerSum = 0;
for (int k=0; k<m_nApplyTimes; k++)
{
// 搜索目标集
{
m_setTargetLocked.clear();
setTarget.clear();
setRole.clear();
setPower.clear();
int nDir = ::GetDirByPos(m_pOwner->GetPosX(), m_pOwner->GetPosY(), m_pos.x, m_pos.y);
pos.x = m_pOwner->GetPosX();
pos.y = m_pOwner->GetPosY();
m_pOwner->GetMap()->CollectMapThing(setTarget, pos, nRange1, OBJ_USER|OBJ_MONSTER|OBJ_NPC);
int nThisDir = nDir;
for(int i = 0; i < 4; i++)
{
POINT posThis = pos;
for(int j = 0; j < (i%2 ? nRange1 : nRange2); j++)
{
MovePos(&posThis, nThisDir);
if(!m_pOwner->GetMap()->IsValidPoint(posThis))
continue;
if(!m_pOwner->GetMap()->IsAltEnable(pos, posThis, MAGICDAMAGE_ALT))
continue;
int idx = POS2INDEX(posThis.x - pos.x + nRange1, posThis.y - pos.y + nRange1, nSize, nSize);
ASSERT(idx>=0 && idx<setTarget.size());
if(setTarget[idx])
{
IRole* pRole = NULL;
if(setTarget[idx]->QueryRole(IPP_OF(pRole)) && pRole->IsAlive() && !IsImmunity(pRole))
{
//if(nLoseLife)
{
setRole.push_back(pRole);
// 只锁定一个攻击目标
if (pRole->GetID() == m_idTarget)
m_setTargetLocked.push_back(pRole->GetID());
}
}
}
}
nThisDir = (nThisDir+2) % 8;
}
}
// 锁定目标
if (m_pMagic->GetSTrackAmount() > 0)
LockTarget(true);
// 广播法术效果
CMsgMagicEffect msg;
IF_OK(msg.CreateByPos(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), pos.x, pos.y, m_pOwner->GetDir()))
{
for(int i = 0; i < setRole.size(); i++)
{
IRole* pRole = setRole[i];
if (pRole && pRole->IsAlive())
{
int nPower = CBattleSystem::CalcPower(HitByMagic(), m_pOwner, pRole, GetPower(k));
setPower.push_back(nPower);
msg.AppendRole(pRole->GetID(), nPower);
}
else
setPower.push_back(0);
}
m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
}
// set crime status
CheckCrime(&setRole);
for (int i = 0; i < setRole.size(); i++)
{
if (!setRole[i]->IsAlive())
continue;
nPowerSum += setPower[i];
CNpc* pNpc = NULL;
int nLifeLost = setPower[i];
if (setPower[i] && setRole[i]->TransferShield(HitByMagic(), m_pOwner, setPower[i]))
{
}
else
{
nLifeLost = __min(setRole[i]->GetLife(), setPower[i]);
setRole[i]->AddAttrib(_USERATTRIB_LIFE, -1*nLifeLost, SYNCHRO_TRUE);
if(setRole[i]->QueryObj(OBJ_NPC, IPP_OF(pNpc)) && pNpc->IsAwardScore())
m_pOwner->AwardSynWarScore(pNpc, nLifeLost);
setRole[i]->BeAttack(HitByMagic(), m_pOwner, setPower[i]);
}
if (setRole[i]->IsMonster() || pNpc && pNpc->IsGoal() && m_pOwner->GetLev() >= pNpc->GetLev())
{
nExp += m_pOwner->AdjustExp(setRole[i], nLifeLost);
if (!setRole[i]->IsAlive())
{
// 有组队,并且队伍中有其他队员,则奖励其他队员经验
int nBonusExp = setRole[i]->GetMaxLife()*KILLBONUS_PERCENT/100;
OtherMemberAwardExp(setRole[i], nBonusExp);
nExp += m_pOwner->AdjustExp(setRole[i], nBonusExp, true);
}
}
}
if (m_pMagic->GetSTrackAmount() > 0)
AdjustPosByTrack(k);
// 必须先发轨迹后发kill消息
for (i = 0; i < setRole.size(); i++)
{
if(!setRole[i]->IsAlive())
m_pOwner->Kill(setRole[i], GetDieMode());
}
}
IStatus* pStatus = m_pOwner->QueryStatus(STATUS_DMG2LIFE);
if (pStatus)
{
int nLifeGot = ::CutTrail(0, MulDiv(nPowerSum, pStatus->GetPower(), 100));
if (nLifeGot > 0)
m_pOwner->AddAttrib(_USERATTRIB_LIFE, nLifeGot, SYNCHRO_TRUE);
}
AwardExp(nExp);
return true;
}
//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessLine()
{
CHECKF(m_pMagic);
vector<IRole*> setTarget;
vector<int> setPower;
vector<POINT> setPoint;
int nExp = 0;
int nPowerSum = 0;
bool bAtkerPenetrable = (m_pMagic->GetInt(MAGICDATA_SORT) == MAGICSORT_LINE_PENETRABLE);
for (int k=0; k<m_nApplyTimes; k++)
{
// 搜索目标集
{
m_setTargetLocked.clear();
setTarget.clear();
setPower.clear();
setPoint.clear();
POINT pos;
pos.x = m_pOwner->GetPosX();
pos.y = m_pOwner->GetPosY();
DDALine(pos.x, pos.y, m_pos.x, m_pos.y, m_pMagic->GetInt(MAGICDATA_RANGE), setPoint);
for(int i = 0; i < setPoint.size(); i++)
{
POINT posThis = setPoint[i];
if(!m_pOwner->GetMap()->IsValidPoint(posThis))
continue;
if(!m_pOwner->GetMap()->IsAltEnable(pos, posThis, MAGICDAMAGE_ALT))
continue;
IRole* pTarget = m_pOwner->GetMap()->QueryRole(setPoint[i].x, setPoint[i].y, ID_NONE);
if(!pTarget || !pTarget->IsAlive() || this->IsImmunity(pTarget))
continue;
// attack now
setTarget.push_back(pTarget);
if (m_pOwner->GetID() != pTarget->GetID())
m_setTargetLocked.push_back(pTarget->GetID());
}
}
// 锁定目标
if (m_pMagic->GetSTrackAmount() > 0)
LockTarget(true);
// 广播法术效果
CMsgMagicEffect msg;
IF_OK(msg.CreateByPos(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), m_pos.x, m_pos.y, m_pOwner->GetDir()))
{
for(int i = 0; i < setTarget.size(); i++)
{
IRole* pRole = setTarget[i];
if (pRole && pRole->IsAlive())
{
int nPower = CBattleSystem::CalcPower(HitByMagic(), m_pOwner, pRole, GetPower(k));
setPower.push_back(nPower);
msg.AppendRole(pRole->GetID(), nPower);
}
else
setPower.push_back(0);
}
m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
}
// set crime status
CheckCrime(&setTarget);
for (int i = 0; i < setTarget.size(); i++)
{
if (!setTarget[i]->IsAlive())
continue;
nPowerSum += setPower[i];
CNpc* pNpc = NULL;
int nLifeLost = setPower[i];
if (setPower[i] && setTarget[i]->TransferShield(HitByMagic(), m_pOwner, setPower[i]))
{
}
else
{
nLifeLost = __min(setTarget[i]->GetLife(), setPower[i]);
setTarget[i]->AddAttrib(_USERATTRIB_LIFE, -1*nLifeLost, SYNCHRO_TRUE);
if(setTarget[i]->QueryObj(OBJ_NPC, IPP_OF(pNpc)) && pNpc->IsAwardScore())
m_pOwner->AwardSynWarScore(pNpc, nLifeLost);
setTarget[i]->BeAttack(HitByMagic(), m_pOwner, setPower[i]);
}
if (setTarget[i]->IsMonster() || pNpc && pNpc->IsGoal() && m_pOwner->GetLev() >= pNpc->GetLev())
{
nExp += this->m_pOwner->AdjustExp(setTarget[i], nLifeLost);
if (!setTarget[i]->IsAlive())
{
// 有组队,并且队伍中有其他队员,则奖励其他队员经验
int nBonusExp = setTarget[i]->GetMaxLife()*KILLBONUS_PERCENT/100;
OtherMemberAwardExp(setTarget[i], nBonusExp);
nExp += m_pOwner->AdjustExp(setTarget[i], nBonusExp, true);
}
}
}
if (m_pMagic->GetSTrackAmount() > 0)
AdjustPosByTrack(k, bAtkerPenetrable);
// 必须先发轨迹后发kill消息
for (i = 0; i < setTarget.size(); i++)
{
if(!setTarget[i]->IsAlive())
m_pOwner->Kill(setTarget[i], GetDieMode());
}
}
if(HitByWeapon() && !m_pOwner->GetMap()->IsTrainMap())
{
m_pOwner->AddEquipmentDurability(ITEMPOSITION_WEAPONR, -1*LINE_WEAPON_DURABILITY);
m_pOwner->AddEquipmentDurability(ITEMPOSITION_WEAPONL, -1*LINE_WEAPON_DURABILITY);
}
IStatus* pStatus = m_pOwner->QueryStatus(STATUS_DMG2LIFE);
if (pStatus)
{
int nLifeGot = ::CutTrail(0, MulDiv(nPowerSum, pStatus->GetPower(), 100));
if (nLifeGot > 0)
m_pOwner->AddAttrib(_USERATTRIB_LIFE, nLifeGot, SYNCHRO_TRUE);
}
AwardExp(nExp);
return true;
}
//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessFan()
{
CHECKF(m_pMagic);
MAPTHING_SET setTarget;
vector<IRole*> setRole;
vector<int> setPower;
POINT pos; // source of fan
int nRange = m_pMagic->GetInt(MAGICDATA_RANGE)+MAX_SIZEADD;
int nWidth = m_pMagic->GetInt(MAGICDATA_WIDTH);
if(!nWidth)
nWidth = DEFAULT_MAGIC_FAN;
int nSize = nRange*2 + 1;
int nBufSize = nSize * nSize;
int nExp = 0;
int nPowerSum = 0;
for (int k=0; k<m_nApplyTimes; k++)
{
// 搜索目标集
{
m_setTargetLocked.clear();
setTarget.clear();
setRole.clear();
setPower.clear();
if(m_pMagic->GetInt(MAGICDATA_GROUND))
{
pos.x = m_pOwner->GetPosX();
pos.y = m_pOwner->GetPosY();
}
else
{
IRole* pTarget = m_pOwner->FindAroundRole(m_idTarget);
if(!pTarget || !pTarget->IsAlive())
return false;
pos.x = pTarget->GetPosX();
pos.y = pTarget->GetPosY();
// 只锁定一个攻击目标
setRole.push_back(pTarget);
m_setTargetLocked.push_back(pTarget->GetID());
}
m_pOwner->GetMap()->CollectMapThing(setTarget, pos, nRange, OBJ_USER|OBJ_MONSTER|OBJ_NPC);
for(int i = ::CutTrail(pos.x-nRange, 0); i <= pos.x+nRange && i < m_pOwner->GetMap()->GetWidth(); i++)
{
for(int j = ::CutTrail(pos.y-nRange, 0); j <= pos.y+nRange && j < m_pOwner->GetMap()->GetHeight(); j++)
{
POINT posThis;
posThis.x = i;
posThis.y = j;
if(!m_pOwner->IsInFan(posThis, pos, nRange, nWidth, m_pos)) // m_pos: target pos
continue;
int idx = POS2INDEX(posThis.x - pos.x + nRange, posThis.y - pos.y + nRange, nSize, nSize);
ASSERT(idx>=0 && idx<setTarget.size());
if(setTarget[idx])
{
IRole* pRole = NULL;
if(setTarget[idx]->QueryRole(IPP_OF(pRole)) && pRole->IsAlive() && !IsImmunity(pRole)
) //&& m_pOwner->GetDistance(pRole->QueryMapThing()) <= m_pOwner->GetAttackRange(pRole->GetSizeAdd()))
{
//if(nLoseLife)
{
if (pRole->GetID() != m_idTarget) // m_idTarget如果存在前面已经push到setRole中了
setRole.push_back(pRole);
}
}
}
}
}
}
// 锁定目标
if (m_pMagic->GetSTrackAmount() > 0)
LockTarget(true);
// 广播法术效果
CMsgMagicEffect msg;
IF_OK(msg.CreateByPos(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), pos.x, pos.y, m_pOwner->GetDir()))
{
for(int i = 0; i < setRole.size(); i++)
{
IRole* pRole = setRole[i];
if (pRole && pRole->IsAlive())
{
int nPower = CBattleSystem::CalcPower(HitByMagic(), m_pOwner, pRole, GetPower(k));
setPower.push_back(nPower);
msg.AppendRole(pRole->GetID(), nPower);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -