📄 user.cpp
字号:
}
return nAddPercent;
}
//////////////////////////////////////////////////////////////////////
int CUser::GetGemAtkEffect (void)
{
int nAddEffect = 0;
for (int i = ITEMPOSITION_EQUIPBEGIN; i < ITEMPOSITION_EQUIPEND; i++)
{
CItem* pEquip = GetEquipItemByPos(i);
if (pEquip)
nAddEffect += pEquip->GetGemDmgEffect();
}
return nAddEffect;
}
//////////////////////////////////////////////////////////////////////
int CUser::GetGemMgcAtkEffect (void)
{
int nAddEffect = 0;
for (int i = ITEMPOSITION_EQUIPBEGIN; i < ITEMPOSITION_EQUIPEND; i++)
{
CItem* pEquip = GetEquipItemByPos(i);
if (pEquip)
nAddEffect += pEquip->GetGemMgcAtkEffect();
}
return nAddEffect;
}
//////////////////////////////////////////////////////////////////////
void CUser::SendGemEffect(void)
{
vector<int> setGem;
int nGem = 0;
for(int i = ITEMPOSITION_EQUIPBEGIN; i < ITEMPOSITION_EQUIPEND; i++)
{
CItem* pEquip = GetEquipItemByPos(i);
if (pEquip)
{
nGem = pEquip->GetInt(ITEMDATA_GEM1);
if (nGem != GEM_NONE && nGem != GEM_HOLE)
setGem.push_back(nGem);
nGem = pEquip->GetInt(ITEMDATA_GEM2);
if (nGem != GEM_NONE && nGem != GEM_HOLE)
setGem.push_back(nGem);
}
}
int nGems = setGem.size();
if (nGems <= 0)
return;
string strEffect;
switch(setGem[::RandGet(nGems)])
{
case 3:
strEffect = "phoenix";
break;
case 13:
strEffect = "goldendragon";
break;
case 23:
strEffect = "fastflash";
break;
case 33:
strEffect = "rainbow";
break;
case 43:
strEffect = "goldenkylin";
break;
case 53:
strEffect = "purpleray";
break;
case 63:
strEffect = "moon";
break;
default:
return;
}
CMsgName msg;
IF_OK (msg.Create(NAMEACT_ROLEEFFECT, strEffect.c_str(), this->GetID()))
this->BroadcastRoomMsg(&msg, true);
}
//////////////////////////////////////////////////////////////////////
// precondition is dodge failed
int CUser::Attack(IRole* pTarget) // return : lose life
{
CHECKF(pTarget);
CNpc* pNpc;
pTarget->QueryObj(OBJ_NPC, IPP_OF(pNpc));
int nAtk=0;
int nDamage = CBattleSystem::CalcPower(IsSimpleMagicAtk(), QueryRole(), pTarget, &nAtk, true);
// 目标护盾状态转移伤害
if (nDamage>0 && pTarget->TransferShield(IsSimpleMagicAtk(), QueryRole(), nDamage))
{
}
else
{
int nLoseLife = ::CutOverflow(nDamage, (int)pTarget->GetLife());
if (nLoseLife > 0)
pTarget->AddAttrib(_USERATTRIB_LIFE, -1*nLoseLife, SYNCHRO_TRUE);
// adjust synflag damage
if(pNpc && pNpc->IsSynFlag() && pNpc->IsSynMoneyEmpty())
{
nDamage *= SYNWAR_NOMONEY_DAMAGETIMES;
}
if (nDamage > 0)
{
if (::RandGet(10) == 7)
this->SendGemEffect();
}
pTarget->BeAttack(IsSimpleMagicAtk(), QueryRole(), nDamage);
}
CGameMap* pMap = this->GetMap();
if (pMap)
{
// crime
if (!pTarget->IsEvil() // 只有pk白名才闪蓝
&& !pMap->IsDeadIsland()) // 死亡岛杀人不闪蓝
{
if (!QueryStatus(STATUS_CRIME))
this->SetCrimeStatus();
}
// equipment durability cost
if (!pMap->IsTrainMap())
this->DecEquipmentDurability(ATTACK_TIME, IsSimpleMagicAtk(), (nDamage < nAtk/10) ? 10 : 1);
}
IStatus* pStatus = QueryStatus(STATUS_DMG2LIFE);
if (pStatus)
{
int nLifeGot = ::CutTrail(0, MulDiv(nDamage, pStatus->GetPower(), 100));
if (nLifeGot > 0)
this->AddAttrib(_USERATTRIB_LIFE, nLifeGot, SYNCHRO_TRUE);
}
return nDamage;
}
//////////////////////////////////////////////////////////////////////
bool CUser::BeAttack(bool bMagic, IRole* pTarget, int nPower, bool bReflectEnable/*=true*/)
{
CHECKF(pTarget);
QueryStatusSet()->DelObj(STATUS_LURKER);
CRole::DetachStatus(this->QueryRole(), STATUS_FREEZE);
StopMine();
// reflect, only use for weapon attack!!!
IStatus* pStatus = QueryStatus(bMagic?STATUS_REFLECTMAGIC:STATUS_REFLECT);
if(nPower>0 && pStatus && bReflectEnable)
{
int nPower2 = AdjustData(nPower, pStatus->GetPower());
if(nPower2 > 0)
{
int nLoseLife = ::CutOverflow((int)pTarget->GetLife(), nPower2);
pTarget->AddAttrib(_USERATTRIB_LIFE, -1*nLoseLife, SYNCHRO_TRUE);
pTarget->BeAttack(bMagic, this, nPower2, false);
// 传送结果消息
CMsgInteract msg;
if (msg.Create(bMagic?INTERACT_REFLECTMAGIC:INTERACT_REFLECTWEAPON, GetID(), pTarget->GetID(), GetPosX(), GetPosY(), nPower2))
BroadcastRoomMsg(&msg, INCLUDE_SELF);
// kill?
if (!pTarget->IsAlive())
pTarget->BeKill();
}
}
// equipment durability cost
if (!this->GetMap()->IsTrainMap())
{
this->DecEquipmentDurability(BEATTACK_TIME, bMagic, (nPower > this->GetMaxLife()/4) ? 10 : 1);
}
// self_defence // add huang 2004.1.14
// if(QueryStatus(STATUS_SELFDEFENCE))
// this->SetSelfDefStatus();
if(nPower > 0)
BroadcastTeamLife();
// abort magic
if (QueryMagic() && QueryMagic()->IsIntone())
QueryMagic()->AbortMagic(true);
/*/ stamina lost
if (_ACTION_SITDOWN == this->GetPose())
{
this->SetPose(_ACTION_STANDBY);
this->SetAttrib(_USERATTRIB_ENERGY, this->GetEnergy()/2, SYNCHRO_TRUE);
}*/
return true;
}
//////////////////////////////////////////////////////////////////////
void CUser::SendDamageMsg(OBJID idTarget, int nDamage)
{
OBJID idMagicType = ID_NONE;
if(QueryTransformation())
idMagicType = QueryTransformation()->GetMagicType();
if(idMagicType != ID_NONE)
{
CMsgMagicEffect msg;
IF_OK(msg.Create(GetID(), idMagicType, 0, idTarget, nDamage, GetDir()))
BroadcastRoomMsg(&msg, INCLUDE_SELF);
}
else if(IsBowman())
{
CMsgInteract msg;
IF_OK(msg.Create(INTERACT_SHOOT, GetID(), idTarget, GetPosX(), GetPosY(), nDamage))
BroadcastRoomMsg(&msg, INCLUDE_SELF);
}
else
{
CMsgInteract msg;
IF_OK(msg.Create(INTERACT_ATTACK, GetID(), idTarget, GetPosX(), GetPosY(), nDamage))
BroadcastRoomMsg(&msg, INCLUDE_SELF);
}
}
//////////////////////////////////////////////////////////////////////
bool CUser::TransferShield(bool bMagic, IRole* pAtker, int nDamage)
{
IStatus* pStatus = QueryStatus(STATUS_TRANSFER_SHIELD);
if (!pStatus)
return false;
int nMagicType = pStatus->GetPower();
vector<CMonster*> setEudemon;
// 寻找符合条件的已出征幻兽
for (int i=0; i<this->GetEudemonAmount(); i++)
{
CMonster* pEudemon = this->QueryEudemonByIndex(i);
if (pEudemon && pEudemon->QueryMagic() && pEudemon->QueryMagic()->FindMagic(nMagicType))
setEudemon.push_back(pEudemon);
}
if (setEudemon.empty())
return false;
nDamage = nDamage/setEudemon.size();
for (i=0; i<setEudemon.size(); i++)
{
int nLostLife = ::CutOverflow(nDamage, (int)setEudemon[i]->GetLife());
if (nLostLife>0)
setEudemon[i]->AddAttrib(_USERATTRIB_LIFE, -1*nLostLife, SYNCHRO_TRUE);
setEudemon[i]->BeAttack(bMagic, pAtker, nDamage);
// 这里这样处理在连招中应用会导致先杀死后出连招动作的bug
// 等待确定解决方案
if (!setEudemon[i]->IsAlive())
pAtker->Kill(setEudemon[i], bMagic?DIE_MAGIC:DIE_NORMAL);
}
return true;
}
//////////////////////////////////////////////////////////////////////
bool CUser::BroadcastTeamLife(bool bMaxLife)
{
// 2003.2.13 如果对方是玩家而且组队了。被攻击玩家去血值要在队内广播。
CTeam* pTeam = GetTeam();
if (pTeam && pTeam->GetMemberAmount() > 1)
{
pTeam->BroadcastMemberLife(this, bMaxLife);
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////
bool CUser::DecEquipmentDurability(bool bBeAttack, bool bMagic, int bDurValue/*=1*/)
{
int nInc = -1 * bDurValue;
for(int i = ITEMPOSITION_EQUIPBEGIN; i < ITEMPOSITION_EQUIPEND; i++)
{
if (!bMagic)
{
if (i == ITEMPOSITION_RINGR ||
i == ITEMPOSITION_RINGL ||
i == ITEMPOSITION_SHOES ||
i == ITEMPOSITION_WEAPONR ||
i == ITEMPOSITION_WEAPONL)
{
if(!bBeAttack)
AddEquipmentDurability(i, nInc);
}
else
{
if(bBeAttack)
AddEquipmentDurability(i, nInc);
}
}
else
{
if (i == ITEMPOSITION_RINGR ||
i == ITEMPOSITION_RINGL ||
i == ITEMPOSITION_SHOES ||
i == ITEMPOSITION_WEAPONR ||
i == ITEMPOSITION_WEAPONL)
{
if(!bBeAttack)
AddEquipmentDurability(i, -5);
}
else
{
if(bBeAttack)
AddEquipmentDurability(i, nInc);
}
}
}
return true;
}
//////////////////////////////////////////////////////////////////////
bool CUser::MagicAttack(int nType, OBJID idTarget, int x, int y)
{
if (QueryMagic())
return QueryMagic()->MagicAttack(nType, idTarget, x, y);
return false;
}
//////////////////////////////////////////////////////////////////////
int CUser::CalcExpLostOfDeath (IRole* pKiller)
{
CUser* pUserKiller = NULL;
if (!pKiller->QueryObj(OBJ_USER, IPP_OF(pUserKiller)))
return 0;
// normal condition
int nParam = 50;
if (this->GetEffect()&KEEPEFFECT_RED)
nParam = 10;
else if (this->GetEffect()&KEEPEFFECT_DEEPRED)
nParam = 5;
else
nParam = 50;
int nExpLost = __max(0, this->GetExp()/nParam);
//if (true)
// return nExpLost;
// syndicate member && not the killer wanted guy
if (this->GetSynID() != ID_NONE && !pUserKiller->IsMyWantedTarget(this))
{
int nDecPercent = 0;
CSyndicate* pSyn = this->GetSyndicate();
IF_OK (pSyn)
{
int nExpPayBySyn = 0;
int nProffer = this->QuerySynProffer();
if (nProffer > 0)
{
int nRank = this->QuerySynRank();
// switch(nRank)
// {
// case RANK_LEADER:
// nDecPercent = 80;
// break;
//
// case RANK_SUBLEADER:
// nDecPercent = 60;
// break;
// case RANK_TEAMLEADER:
// nDecPercent = 40;
// break;
// default:
// nDecPercent = 25;
// break;
// }
CONST MONEYCOST_PEREXP = 100;
int nFundSyn = pSyn->GetInt(SYNDATA_MONEY);
int nFundLost = ::MulDiv(nExpLost, nDecPercent, 100*MONEYCOST_PEREXP); // 100点经验1两
if (nFundLost > nFundSyn)
nFundLost = nFundSyn;
pSyn->QueryModify()->AddData(SYNDATA_MONEY, -1*nFundLost, true);
if (nRank != RANK_LEADER)
this->SetSynProffer(nProffer-nFundLost);
nExpPayBySyn = nFundLost*MONEYCOST_PEREXP;
nExpLost -= nExpPayBySyn;//nFundLost*MONEYCOST_PEREXP;
}
else
{
if (pSyn->IsWhiteSynMapOwner() || pSyn->IsBlackSynMapOwner())
{
nDecPercent = 20;
}
else
{
nDecPercent = 10;
}
CONST MONEYCOST_PEREXP = 100;
int nFundSyn = pSyn->GetInt(SYNDATA_MONEY);
int nFundLost = ::MulDiv(nExpLost, nDecPercent, 100*MONEYCOST_PEREXP); // 100点经验1两
if (nFundLost > nFundSyn)
nFundLost = nFundSyn;
pSyn->QueryModify()->AddData(SYNDATA_MONEY, -1*nFundLost, true);
if (this->QuerySynRank() != RANK_LEADER)
this->SetSynProffer(nProffer-nFundLost);
nExpPayBySyn = nFundLost*MONEYCOST_PEREXP;
nExpLost -= nExpPayBySyn;//nFundLost*MONEYCOST_PEREXP;
}
this->SendSysMsg(_TXTATR_NORMAL, EXPLOST_PAYBY_SYNFUND, nExpPayBySyn);
}
}
return __max(0, nExpLost);
}
//////////////////////////////////////////////////////////////////////
void CUser::Kill(IRole* pTarget, DWORD dwDieWay)
{
CHECK(pTarget);
// inc xp
USHORT usRemainTime = 0;
// IStatus* pStatus = QueryStatus(STATUS_XPFULL);
// if (pStatus && pTarget->IsMonster())
// {
// pStatus->IncTime(ADD_XPFULL_SECS_KILLMONSTER*1000, MAX_XPFULL_SECS*1000);
// m_nCurrSupermanKills++;
// StatusInfoStruct info;
// if (pStatus->GetInfo(&info))
// usRemainTime = info.nSecs;
// }
CMsgInteract msg;
if(msg.Create(INTERACT_KILL, this->GetID(), pTarget->GetID(), pTarget->GetPosX(), pTarget->GetPosY(), dwDieWay, usRemainTime))
pTarget->BroadcastRoomMsg(&msg, true);
// earth magic
//???
if (QueryMagic())
QueryMagic()->UserKillTarget(pTarget);
CUser* pTargetUser = NULL;
if(!pTarget->QueryObj(OBJ_USER, IPP_OF(pTargetUser)))
{
pTarget->BeKill((IRole*)this); // NPC return
return;
}
ProcessPk(pTargetUser);
// target...
pTarget->BeKill((IRole*)this);
}
//////////////////////////////////////////////////////////////////////
void CUser::ProcessPk (CUser* pTargetUser)
{
ASSERT(pTargetUser);
// map...
CGameMap* pMap = MapManager()->QueryMap(this->GetMapID());
IF_OK (pMap)
{
if (pMap->IsPkField())
{
}
else if (pMap->IsPkGameMap())
{
pTargetUser->DelAllBadge();
AddBadge();
}
else if (pMap->IsSynMap())
{
}
else if (pMap->IsPrisonMap())
{
}
else
{
// innocent kill //change huang 2004.1.11
if (!(pTargetUser->GetEffect()&KEEPEFFECT_RED)
&& !(pTargetUser->GetEffect()&KEEPEFFECT_DEEPRED))
{
if (this->G
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -