📄 user_item.cpp
字号:
//根据品质计算转换为鉴定的成功概率
int nQuality = pItem->GetQuality();
int nRate=0;
if(nQuality==QUALITY_ZERO)
nRate = 80;
else if(nQuality==QUALITY_ONE||nQuality==QUALITY_TWO)
nRate = 70;
else if(nQuality==QUALITY_THREE||nQuality==QUALITY_FOUR)
nRate = 50;
int nMoney = IDENT_FEE; // MulDiv(pItem->GetInt(ITEMDATA_PRICE), ITEMIDENT_PERCENT, 100);
// 钱不够
if(nMoney && GetMoney() < nMoney)
return false;
if(nMoney)
this->SpendMoney(nMoney, SYNCHRO_TRUE);
if(::RandGet(100) < nRate)
{
pItem->SetIdent(0, UPDATE_FALSE);
char szBuff[255];
if(nQuality==QUALITY_ZERO)
sprintf(szBuff,STR_IDENT_NORMAL,pItem->GetStr(ITEMDATA_NAME));
else if(nQuality==QUALITY_ONE)
sprintf(szBuff,STR_IDENT_QUALITY_ONE, pItem->GetStr(ITEMDATA_NAME));
else if(nQuality==QUALITY_TWO)
sprintf(szBuff,STR_IDENT_QUALITY_TWO, pItem->GetStr(ITEMDATA_NAME));
else if(nQuality==QUALITY_THREE)
sprintf(szBuff,STR_IDENT_QUALITY_THREE, pItem->GetStr(ITEMDATA_NAME));
else if(nQuality==QUALITY_FOUR)
sprintf(szBuff,STR_IDENT_QUALITY_FOUR, pItem->GetStr(ITEMDATA_NAME));
this->SendSysMsg(szBuff);
if(bSynchro)
{
CMsgItemInfo msg;
CHECKF(msg.Create(pItem));
SendMsg(&msg);
}
return true;
}
else
{
//鉴定失败
if(nQuality==QUALITY_ZERO)
nRate = 70;
else if(nQuality==QUALITY_ONE||nQuality==QUALITY_TWO)
nRate = 50;
else if(nQuality==QUALITY_THREE||nQuality==QUALITY_FOUR)
nRate = 30;
if(::RandGet(100) < nRate)
{
this->EraseItem(idItem,true);
SendSysMsg(STR_ACTION_IDENT_FAIL_DISAPPEAR);
}
else
{
SendSysMsg(STR_ACTION_IDENT_FAIL);
}
return false;
}
}
//////////////////////////////////////////////////////////////////////
void CUser::EmbedGem (OBJID idItem, OBJID idGem, int nPos)
{
CItem* pItem = this->GetItem(idItem);
IF_NOT (pItem)
return;
CItem* pGem = this->GetItem(idGem);
IF_NOT (pGem)
return;
nPos = __min(2, __max(1, nPos));
ItemInfoStruct info;
pItem->GetInfo(&info);
switch(nPos)
{
case 1:
{
IF_OK (GEM_HOLE == info.nGem1)
{
pItem->SetInt(ITEMDATA_GEM1, pGem->GetInt(ITEMDATA_TYPE)%1000);
int nDurEffect = pItem->GetGemDurEffect(pGem->GetInt(ITEMDATA_TYPE));
if (nDurEffect != 0)
{
int nDur = pItem->GetInt(ITEMDATA_AMOUNTLIMIT);
pItem->SetInt(ITEMDATA_AMOUNTLIMIT, nDur*(100+nDurEffect)/100);
}
DEBUG_TRY // VVVVVVVVVV
pItem->SaveInfo();
ASSERT(EraseItem(idGem, SYNCHRO_TRUE));
DEBUG_CATCH("EmbedGem2") // AAAAAAAAAAA
}
}
break;
case 2:
{
IF_OK (GEM_HOLE == info.nGem2)
{
pItem->SetInt(ITEMDATA_GEM2, pGem->GetInt(ITEMDATA_TYPE)%1000);
int nDurEffect = pItem->GetGemDurEffect(pGem->GetInt(ITEMDATA_TYPE));
if (nDurEffect != 0)
{
int nDur = pItem->GetInt(ITEMDATA_AMOUNTLIMIT);
pItem->SetInt(ITEMDATA_AMOUNTLIMIT, nDur*(100+nDurEffect)/100);
}
DEBUG_TRY // VVVVVVVVVV
pItem->SaveInfo();
ASSERT(EraseItem(idGem, SYNCHRO_TRUE));
DEBUG_CATCH("EmbedGem2") // AAAAAAAAAAA
}
}
break;
default:
{
::LogSave("invalid pos:%u in gem embed.", nPos);
return;
}
break;
}
// update item info at client
CMsgItemInfo msg;
IF_OK (msg.Create(pItem, ITEMINFO_UPDATE))
this->SendMsg(&msg);
}
//////////////////////////////////////////////////////////////////////
void CUser::TakeOutGem (OBJID idItem, int nPos)
{
CItem* pItem = this->GetItem(idItem);
IF_NOT (pItem)
return;
nPos = __min(2, __max(1, nPos));
ItemInfoStruct info;
pItem->GetInfo(&info);
switch(nPos)
{
case 1:
{
IF_OK (GEM_NONE != info.nGem1 && GEM_HOLE != info.nGem1)
{
pItem->SetInt(ITEMDATA_GEM1, GEM_HOLE);
// correct dur
OBJID idGemType = 700000+info.nGem1;
int nDurEffect = pItem->GetGemDurEffect(idGemType);
if (nDurEffect != 0)
{
int nDur = pItem->GetInt(ITEMDATA_AMOUNTLIMIT);
pItem->SetInt(ITEMDATA_AMOUNTLIMIT, __max(0, nDur*100/(100+nDurEffect)));
if (pItem->GetInt(ITEMDATA_AMOUNT) > pItem->GetInt(ITEMDATA_AMOUNTLIMIT))
pItem->SetInt(ITEMDATA_AMOUNT, pItem->GetInt(ITEMDATA_AMOUNTLIMIT));
}
pItem->SaveInfo();
}
}
break;
case 2:
{
IF_OK (GEM_NONE != info.nGem2 && GEM_HOLE != info.nGem2)
{
pItem->SetInt(ITEMDATA_GEM2, GEM_HOLE);
// correct dur
OBJID idGemType = 700000+info.nGem2;
int nDurEffect = pItem->GetGemDurEffect(idGemType);
if (nDurEffect != 0)
{
int nDur = pItem->GetInt(ITEMDATA_AMOUNTLIMIT);
pItem->SetInt(ITEMDATA_AMOUNTLIMIT, __max(0, nDur*100/(100+nDurEffect)));
if (pItem->GetInt(ITEMDATA_AMOUNT) > pItem->GetInt(ITEMDATA_AMOUNTLIMIT))
pItem->SetInt(ITEMDATA_AMOUNT, pItem->GetInt(ITEMDATA_AMOUNTLIMIT));
}
pItem->SaveInfo();
}
}
break;
default:
{
::LogSave("invalid pos:%u in gem take out.", nPos);
return;
}
break;
}
// update item info at client
CMsgItemInfo msg;
IF_OK (msg.Create(pItem, ITEMINFO_UPDATE))
this->SendMsg(&msg);
}
//////////////////////////////////////////////////////////////////////
void CUser::UpdateWeight()
{
m_bUpdateWeight = true;
}
//////////////////////////////////////////////////////////////////////
bool CUser::Court (OBJID idTarget)
{
if (this->IsMarried())
return false;
CUser* pTargetUser = this->FindAroundUser(idTarget);
if (!pTargetUser)
return false;
if (this->GetSex() == pTargetUser->GetSex())
return false;
this->SetApply(CUser::APPLY_MARRY, idTarget);
CMsgInteract msg;
IF_OK (msg.Create(INTERACT_COURT, this->GetID(), idTarget, 0, 0))
pTargetUser->SendMsg(&msg);
return true;
}
//////////////////////////////////////////////////////////////////////
bool CUser::Marry (OBJID idTarget)
{
if (this->IsMarried())
return false;
CUser* pTargetUser = this->FindAroundUser(idTarget);
if (!pTargetUser)
return false;
if (pTargetUser->FetchApply(CUser::APPLY_MARRY) != this->GetID())
return false;
this->UpdateMate(pTargetUser->GetName(), true);
pTargetUser->UpdateMate(this->GetName(), true);
// boradcast msg
MSGBUF szMsg;
sprintf(szMsg, STR_MARRY, this->GetName(), pTargetUser->GetName());
CMsgTalk msg;
IF_OK_ (msg.Create(SYSTEM_NAME, ALLUSERS_NAME, szMsg, NULL, 0xff0000, _TXTATR_GM))
UserManager()->BroadcastMsg(&msg);
// fireworks
{
CMsgItem msg;
IF_OK (msg.Create(this->GetID(), ITEMACT_FIREWORKS))
this->BroadcastRoomMsg(&msg, true);
}
return true;
}
//////////////////////////////////////////////////////////////////////
bool CUser::Divorce (void)
{
if (!this->IsMarried())
return false;
CUser* pMate = UserManager()->GetUser(this->GetMate());
IDatabase* pDb = Database();
IF_OK (pDb)
{
char szSQL[1024] = "";
sprintf(szSQL, "INSERT INTO %s SELECT 0,%u,user.id,user.id,0,0,0,%u,0,0,0,0,0,0 FROM %s AS user where user.name='%s'",
_TBL_ITEM,
TYPE_DIVOICEITEM, ITEMPOSITION_BACKPACK, _TBL_USER, this->GetMate());
IF_NOT (pDb->ExecuteSQL(szSQL))
return false;
}
MSGBUF szMsg;
sprintf(szMsg, STR_DIVORCE, this->GetName(), this->GetMate());
this->BroadcastRoomMsg(szMsg, true);
if (pMate)
pMate->UpdateMate(NOMATE_NAME, true);
else
{
char szSQL[1024] = "";
sprintf(szSQL, "UPDATE %s SET mate='%s' WHERE name='%s' LIMIT 1", _TBL_USER, NOMATE_NAME, this->GetMate());
pDb->ExecuteSQL(szSQL);
}
this->UpdateMate(NOMATE_NAME, true);
return true;
}
//////////////////////////////////////////////////////////////////////
void CUser::UpdateMate (const char* pszName, bool bUpdate/* = true*/)
{
IF_NOT (pszName && strlen(pszName) < _MAX_NAMESIZE)
return;
m_data.SetMate(pszName, true);
if (bUpdate)
{
CMsgName msg;
IF_OK (msg.Create(NAMEACT_MATE, pszName, this->GetID()))
this->SendMsg(&msg);
}
}
//////////////////////////////////////////////////////////////////////
bool CUser::IsMarried(void)
{
const char* pszMate = this->GetMate();
return (0 != strcmp(pszMate, NOMATE_NAME));
}
//////////////////////////////////////////////////////////////////////
bool CUser::IsMate(CUser* pUser)
{
IF_NOT (pUser)
return false;
return (0 == strcmp(this->GetMate(), pUser->GetName()));
}
//////////////////////////////////////////////////////////////////////
void CUser::UpdateEquipmentDurability(void)
{
for(int i = ITEMPOSITION_EQUIPBEGIN; i < ITEMPOSITION_EQUIPEND; i++)
{
if (i == ITEMPOSITION_RINGR ||
i == ITEMPOSITION_RINGL ||
i == ITEMPOSITION_WEAPONR ||
i == ITEMPOSITION_WEAPONL)
continue;
this->AddEquipmentDurability(i, -1);
}
}
//////////////////////////////////////////////////////////////////////
void CUser::AddEquipmentDurability(int nPosition, int nAddValue)
{
ASSERT(nAddValue < 0);
CItemPtr& refpEquip = this->GetEquipItemRef(nPosition);
if (!refpEquip || refpEquip->IsExpend() || refpEquip->IsNeverWear())
return;
int nOldDur = refpEquip->GetInt(ITEMDATA_AMOUNT);
int nDurability = __max(0, refpEquip->GetInt(ITEMDATA_AMOUNT)+nAddValue);
refpEquip->SetInt(ITEMDATA_AMOUNT, nDurability);
if (nDurability < 100)
{
if ((nDurability%10) == 0)
this->SendSysMsg(_TXTATR_GM, STR_DAMAGED_REPAIR, refpEquip->GetStr(ITEMDATA_NAME));
}
else if (nDurability < 200)
{
if ((nDurability%20) == 0)
this->SendSysMsg(_TXTATR_GM, STR_DURABILITY_REPAIR, refpEquip->GetStr(ITEMDATA_NAME));
}
if (nOldDur/100 != nDurability/100
|| nDurability <= 0) // should update info to client (nDurability%100) == 0
{
CMsgItem msg; // if nDurability equal zero, the client will auto delete this equipment
if (msg.Create(nPosition, ITEMACT_DURABILITY, nDurability))
this->SendMsg(&msg);
if (nDurability == 0 && !refpEquip->IsMount()) // this equipment is damaged
{
::MyLogSave("gmlog/wareout_item", "%s(%u) wear out item:[id=%u, type=%u], dur=%d, max_dur=%d",
this->GetName(),
this->GetID(),
refpEquip->GetID(),
refpEquip->GetInt(ITEMDATA_TYPE),
refpEquip->GetInt(ITEMDATA_AMOUNT),
refpEquip->GetInt(ITEMDATA_AMOUNTLIMIT));
EraseEquip(nPosition, SYNCHRO_TRUE);
/*
CMsgItem msg;
if (msg.Create(refpEquip->GetID(), ITEMACT_DROPEQUIPMENT, nPosition))
this->SendMsg(&msg);
refpEquip->DeleteRecord();
refpEquip->ReleaseByOwner();
refpEquip = NULL;
CMsgPlayer msgPlayer;
if (msgPlayer.Create(this->QueryRole()))
this->BroadcastRoomMsg(&msgPlayer, EXCLUDE_SELF);
*/
}
else
refpEquip->SaveInfo();
}
}
//////////////////////////////////////////////////////////////////////
int CUser::GetWeight()
{
if(m_bUpdateWeight)
{
m_nAllWeight = 0;
if(m_pHelmet)
m_nAllWeight += m_pHelmet->GetWeight();
if(m_pNecklace)
m_nAllWeight += m_pNecklace->GetWeight();
if(m_pArmor)
m_nAllWeight += m_pArmor->GetWeight();
if(m_pWeaponR)
m_nAllWeight += m_pWeaponR->GetWeight();
if(m_pWeaponL)
m_nAllWeight += m_pWeaponL->GetWeight();
if(m_pRingR)
m_nAllWeight += m_pRingR->GetWeight();
if(m_pRingL)
m_nAllWeight += m_pRingL->GetWeight();
if(m_pShoes)
m_nAllWeight += m_pShoes->GetWeight();
if(m_pMount)
m_nAllWeight += m_pMount->GetWeight();
if(m_pSprite)
m_nAllWeight += m_pSprite->GetWeight();
if(m_pMantle)
m_nAllWeight += m_pMantle->GetWeight();
m_nAllWeight += m_pPackage->GetWeight();
m_bUpdateWeight = false;
}
return m_nAllWeight;
}
//////////////////////////////////////////////////////////////////////
bool CUser::PickMapItem(OBJID idItem)
{
CMapItem* pMapItem = MapManager()->QueryMapItem(idItem);
if (!pMapItem)
return false;
if (this->GetDistance(pMapItem->QueryMapThing()) > PICKMAPITEMDIST_LIMIT)
{
this->SendSysMsg(STR_FAR_CANNOT_PICK);
return false;
}
if (!pMapItem->IsMoney() &&
this->IsItemFull(pMapItem->GetWeight(), pMapItem->GetType(), pMapItem->GetInfo()->nAmountLimit))
{
if (CItem::IsGhostGem(pMapItem->GetType()))
this->SendSysMsg(STR_GEMBAG_FULL);
else
this->SendSysMsg(STR_FULL_CANNOT_PICK);
return false;
}
OBJID idOwner = pMapItem->GetPlayerID();
if (pMapItem->IsPriv() && idOwner != GetID())
{
CUser* pOwner = UserManager()->GetUser(idOwner);
if (!(pOwner && this->IsMate(pOwner)))
{
CTeam* pTeam = this->GetTeam();
if (pTeam && pTeam->IsTeamMember(idOwner)
&& (pMapItem->IsMoney() && !pTeam->IsCloseMoney() || !pMapItem->IsMoney() && !pTeam->IsCloseItem() || pMapItem->IsGem() && !pTeam->IsCloseGemAccess())
&& !(pMapItem->GetType() == TYPE_DRAGONBALL || pMapItem->GetType() == TYPE_SHOOTINGSTAR) )
{
}
else
{
SendSysMsg(STR_OTHERS_ITEM);
return false;
}
}
}
if (pMapItem->IsMoney())
{
int nMoney = pMapItem->GetAmount();
if (this->GetMoney() + nMoney > _MAX_MONEYLIMIT)
{
Se
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -