📄 magic_process.cpp
字号:
// if (!(m_pOwner->GetPosX() == m_pos.x && m_pOwner->GetPosY() == m_pos.y))
{
m_pOwner->ProcessOnMove(MOVEMODE_COLLIDE);
m_pOwner->MoveToward(nDir);
}
return true;
}
//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessCollide()
{
CHECKF(m_pMagic);
CHECKF(m_pOwner);
m_setTargetLocked.clear();
// check syn of user
IF_NOT(m_pOwner->SynPosition(m_pos.x, m_pos.y))
{
CUser* pUser = NULL;
if (m_pOwner->QueryObj(OBJ_USER, IPP_OF(pUser)))
UserManager()->KickOutSocket(pUser->GetSocketID(), "ProcessCollide SynPosition");
return false;
}
// target data is dir
int nDir = m_nData;
int nTargetX = m_pos.x+_DELTA_X[nDir];
int nTargetY = m_pos.y+_DELTA_Y[nDir];
IF_NOT(m_pOwner->GetMap()->IsStandEnable(nTargetX, nTargetY))
{
m_pOwner->SendSysMsg(STR_INVALID_MSG);
CUser* pUser = NULL;
if (m_pOwner->QueryObj(OBJ_USER, IPP_OF(pUser)))
UserManager()->KickOutSocket(pUser->GetSocketID(), "COLLIDE coord!");
return false;
}
// search the target
bool bSuc = true;
IRole* pTarget = m_pOwner->GetMap()->QueryRole(nTargetX, nTargetY, ID_NONE);
if(!pTarget || !pTarget->IsAlive())
bSuc = false;
if (!pTarget || this->IsImmunity(pTarget))
bSuc = false;
//if (m_pOwner->GetDistance(nTargetX, nTargetY) > m_pMagic->GetInt(MAGICDATA_DISTANCE))
// bSuc = false;
int nPower = 0;
bool bBackEnable = false;
OBJID idTarget = ID_NONE;
CNpc* pNpc = NULL;
if (pTarget)
{
pTarget->QueryObj(OBJ_NPC, IPP_OF(pNpc));
// int nHitRate = 100;
// if (::RandGet(100) >= nHitRate)
// bSuc = false;
if (bSuc)
{
bBackEnable = pTarget->GetMap()->IsStandEnable(nTargetX+_DELTA_X[nDir], nTargetY+_DELTA_Y[nDir]);
if(pNpc)
bBackEnable = false;
if (!bBackEnable)
nDir = MAX_DIRSIZE;
if (HitByWeapon()) // && !CBattleSystem::IsTargetDodged(m_pOwner, pTarget))
{
nPower += CBattleSystem::CalcAttackPower(m_pOwner, pTarget);
if(bBackEnable || pNpc)
nPower = MulDiv(nPower, COLLIDE_POWER_PERCENT, 100);
else
nPower = m_pOwner->AdjustData(nPower, GetPower());
}
if(!m_pOwner->GetMap()->IsTrainMap())
m_pOwner->AddEquipmentDurability(ITEMPOSITION_WEAPONL, -1*COLLIDE_SHIELD_DURABILITY);
}
idTarget = pTarget->GetID();
// m_setTargetLocked.push_back(idTarget);
}
CMsgInteract msg;
DWORD dwData = nDir*0x01000000+nPower;
if (!bBackEnable)
dwData += 1*0x10000000;
IF_OK (msg.Create(INTERACT_BUMP, m_pOwner->GetID(), idTarget, nTargetX, nTargetY, dwData))
m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
if (m_pOwner->IsPM())
{
CUser* pUser = NULL;
if (m_pOwner->QueryObj(OBJ_USER, IPP_OF(pUser)))
pUser->SendSysMsg(_TXTATR_NORMAL, "bump move:(%u, %u)->(%u, %u)",
pUser->GetPosX(), pUser->GetPosY(),
nTargetX, nTargetY);
}
// move now...
// if (!(m_pOwner->GetPosX() == m_pos.x && m_pOwner->GetPosY() == m_pos.y))
if (bBackEnable)
{
m_pOwner->ProcessOnMove(MOVEMODE_COLLIDE);
m_pOwner->MoveToward(nDir);
}
if (pTarget && bBackEnable && bSuc)
{
pTarget->ProcessOnMove(MOVEMODE_COLLIDE);
pTarget->MoveToward(nDir);
// paled - set not synchro yet
CUser* pTargetUser;
if(pTarget->QueryObj(OBJ_USER, IPP_OF(pTargetUser)))
{
// syn pos of client
pTargetUser->SetSynchro(false);
}
}
// set crime status
if(pTarget)
CheckCrime(pTarget);
if (nPower && pTarget)
{
CNpc* pNpc = NULL;
int nLifeLost = nPower;
if (pTarget->TransferShield(HitByMagic(), m_pOwner, nPower))
{
}
else
{
nLifeLost = __min(pTarget->GetLife(), nPower);
pTarget->AddAttrib(_USERATTRIB_LIFE, -1*nLifeLost, SYNCHRO_TRUE);
if(pTarget->QueryObj(OBJ_NPC, IPP_OF(pNpc)) && pNpc->IsAwardScore())
m_pOwner->AwardSynWarScore(pNpc, nLifeLost);
pTarget->BeAttack(HitByMagic(), m_pOwner, nPower);
}
if(pTarget->IsMonster() || pNpc && pNpc->IsGoal() && m_pOwner->GetLev() >= pNpc->GetLev())
{
// correct exp here
int nExp = this->m_pOwner->AdjustExp(pTarget, nLifeLost);
// kill bonus
if (!pTarget->IsAlive()) // target was killed
{
// 有组队,并且队伍中有其他队员,则奖励其他队员经验
int nBonusExp = pTarget->GetMaxLife()*KILLBONUS_PERCENT/100;
OtherMemberAwardExp(pTarget, nBonusExp);
nExp += m_pOwner->AdjustExp(pTarget, nBonusExp, true);
}
this->AwardExp(nExp);
}
if (!pTarget->IsAlive())
m_pOwner->Kill(pTarget, GetDieMode());
IStatus* pStatus = m_pOwner->QueryStatus(STATUS_DMG2LIFE);
if (pStatus)
{
int nLifeGot = ::CutTrail(0, MulDiv(nPower, pStatus->GetPower(), 100));
if (nLifeGot > 0)
m_pOwner->AddAttrib(_USERATTRIB_LIFE, nLifeGot, SYNCHRO_TRUE);
}
}
return true;
}
//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessSerialCut()
{
CHECKF(m_pMagic);
m_setTargetLocked.clear();
POINT pos;
pos.x = m_pos.x;
pos.y = m_pos.y;
int nRange = 1;
int nSize = nRange*2 + 1;
int nBufSize = nSize * nSize;
vector<IRole*> setRole;
vector<int> setPower;
for(int i = 0; i < MAX_SERIALCUTSIZE; i++)
{
MAPTHING_SET setTarget;
m_pOwner->GetMap()->CollectMapThing(setTarget, pos, nRange, OBJ_USER|OBJ_MONSTER|OBJ_NPC);
IRole* pTarget = NULL;
for(int j = 0; j < setTarget.size(); j++)
{
int idx = j;
ASSERT(idx>=0 && idx<setTarget.size());
if(setTarget[idx])
{
IRole* pRole = NULL;
if(setTarget[idx]->QueryRole(IPP_OF(pRole)) && pRole->IsAlive() && !IsImmunity(pRole))
{
int nPower = CBattleSystem::CalcPower(HitByMagic(), m_pOwner, pRole, GetPower());
//if(nLoseLife)
{
setRole.push_back(pRole);
setPower.push_back(nPower);
// 只锁定一个攻击目标
// if (pRole->GetID() == m_idTarget)
// m_setTargetLocked.push_back(pRole->GetID());
if(nPower >= pRole->GetLife())
pTarget = pRole; // continue next cut
break;
}
}
}
}
if(!pTarget)
break;
pos.x = pTarget->GetPosX();
pos.y = pTarget->GetPosY();
}
// 广播法术效果
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++)
msg.AppendRole(setRole[i]->GetID(), setPower[i]);
m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
}
int nPowerSum = 0;
int nExp = 0;
for (i = 0; i < setRole.size(); i++)
{
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 += this->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(!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::ProcessCallTeamMember()
{
CHECKF(m_pMagic);
m_setTargetLocked.clear();
CTeam* pTeam = m_pOwner->GetTeam();
if(!pTeam)
return false;
if (!m_pOwner->GetMap())
return false;
// 广播法术效果
CMsgMagicEffect msg;
IF_OK(msg.Create(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), m_pOwner->GetID(), 0, m_pOwner->GetDir()))
m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
for(int i = 0; i < pTeam->GetMemberAmount(); i++)
{
OBJID idTarget = pTeam->GetMemberByIndex(i);
if(idTarget != ID_NONE && idTarget != m_pOwner->GetID())
{
CUser* pTarget = UserManager()->GetUser(idTarget);
if(pTarget)
{
if (!pTarget->IsAlive())
return false;
// m_setTargetLocked.push_back(pTarget->GetID());
pTarget->FlyMap(m_pOwner->GetMap()->GetID(), m_pOwner->GetPosX(), m_pOwner->GetPosY());
}
else
MapGroup(PID)->QueryIntraMsg()->ChangeTeam(CHANGETEAM_FLY, m_pOwner->GetMap()->GetID(), idTarget, MAKELONG(m_pOwner->GetPosX(), m_pOwner->GetPosY()));
}
}
AwardExp(0);
return true;
}
//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessRecordTransSpell()
{
CHECKF(m_pMagic);
m_setTargetLocked.clear();
// 广播法术效果
CMsgMagicEffect msg;
IF_OK(msg.Create(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), m_idTarget, 0, m_pOwner->GetDir()))
m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
CItem* pItem = m_pOwner->FindSpaceTransSpell();
if(pItem)
{
OBJID idMap = ID_NONE;
if (m_pOwner->GetMap())
idMap = m_pOwner->GetMap()->GetID();
pItem->SetInt(ITEMDATA_DATA, idMap, UPDATE_FALSE);
pItem->SetInt(ITEMDATA_AMOUNT, m_pOwner->GetPosX(), UPDATE_FALSE);
pItem->SetInt(ITEMDATA_AMOUNTLIMIT, m_pOwner->GetPosY(), UPDATE_TRUE);
CMsgItemInfo msg;
msg.Create(pItem, ITEMINFO_UPDATE);
m_pOwner->SendMsg(&msg);
}
AwardExp(0);
return true;
}
//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessTransform()
{
CHECKF(m_pMagic);
m_setTargetLocked.clear();
// 广播法术效果
CMsgMagicEffect msg;
IF_OK(msg.Create(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), m_idTarget, 0, m_pOwner->GetDir()))
m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
m_pOwner->Transform(GetPower(), GetPower());
this->AwardExp(0);
return true;
}
//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessAddMana()
{
CHECKF(m_pMagic);
m_setTargetLocked.clear();
int nAddMana = GetPower();
nAddMana = ::CutOverflow(nAddMana, (int)m_pOwner->GetMaxMana()-(int)m_pOwner->GetMana());
// 广播法术效果
CMsgMagicEffect msg;
IF_OK(msg.Create(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), m_pOwner->GetID(), nAddMana, m_pOwner->GetDir()))
m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
int nExp = m_pOwner->GetMaxMana() - m_pOwner->GetMana();
m_pOwner->AddAttrib(_USERATTRIB_MANA, nAddMana, SYNCHRO_TRUE);
this->AwardExp(0);
return true;
}
//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessLayTrap()
{
CHECKF(m_pMagic);
m_setTargetLocked.clear();
int nTrapType = GetPower();
// 广播法术效果
CMsgMagicEffect msg;
IF_OK(msg.Create(m_pOwner->GetID(), m_pMagic->GetInt(MAGICDATA_TYPE), m_pMagic->GetInt(MAGICDATA_LEVEL), m_pOwner->GetID(), 0, m_pOwner->GetDir()))
m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
int nCostDir = abs(m_pOwner->GetPosX() - m_pos.x) < abs(m_pOwner->GetPosY() - m_pos.y) ? 0 : 2;
TRAP_INFO info;
info.id = ID_NONE; //? set id in CreateNew()
info.idMap = ID_NONE;
if (m_pOwner->GetMap())
info.idMap = m_pOwner->GetMap()->GetID();
info.idOwner = m_pOwner->GetID();
info.usLook = (nCostDir + 4) % MAX_DIRSIZE; // 4: rotate 90 degree
info.usPosX = m_pos.x;
info.usPosY = m_pos.y;
info.usType = nTrapType;
// 暂时这么修改,等魔法系统修改完成后,还需要修改陷阱为使用IRole为入口参数
CUser* pUser = NULL;
if (m_pOwner->QueryObj(OBJ_USER, IPP_OF(pUser)))
{
CMapTrap* pTrap = CMapTrap::CreateNew(m_idProcess, &info, pUser);
if(pTrap)
RoleManager()->QuerySet()->AddObj(pTrap->QueryRole());
}
this->AwardExp(0);
return true;
}
//////////////////////////////////////////////////////////////////////
bool CMagic::ProcessCallPet()
{
CHECKF(m_pMagic);
CUser* pUser = NULL;
if (!m_pOwner->QueryObj(OBJ_USER, IPP_OF(pUser)))
return false;
m_setTargetLocked.clear();
// 广播法术效果
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()))
m_pOwner->BroadcastRoomMsg(&msg, INCLUDE_SELF);
pUser->CallPet(GetPower(), m_pos.x, m_pos.y, m_pMagic->GetInt(MAGICDATA_STEP));
this->AwardExp(0);
return true;
}
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -