469 lines
11 KiB
C++
469 lines
11 KiB
C++
|
|
#include "StdAfx.h"
|
|||
|
|
#include "Container.hpp"
|
|||
|
|
LONG CBoxDropMgr::s_boxDropMgrCnt = 0;
|
|||
|
|
CBoxDropMgr * CBoxDropMgr::s_BoxDropMgr = NULL;
|
|||
|
|
TCHAR CBaseScriptExportObject::m_sClassName[] = _T("CBaseScriptExportObject");
|
|||
|
|
TCHAR CBoxDrop::m_sClassName[] = _T("CBoxDrop");
|
|||
|
|
const char *DropTableName = "drops";
|
|||
|
|
|
|||
|
|
CBoxDrop::CBoxDrop()
|
|||
|
|
{
|
|||
|
|
ZeroMemory(&m_dropGroup, sizeof(m_dropGroup));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CBoxDrop::load(const char *sFile)
|
|||
|
|
{
|
|||
|
|
if (!sFile) return false;
|
|||
|
|
wylib::stream::CMemoryStream ms;
|
|||
|
|
if (ms.loadFromFile(sFile) <= 0)
|
|||
|
|
{
|
|||
|
|
OutputMsg(rmError, _T("load script file(%s) failed"), sFile);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CCustomLuaPreProcessor pp;
|
|||
|
|
GetLogicServer()->GetVSPDefine().RegisteToPreprocessor(pp);
|
|||
|
|
LPCSTR sScript = pp.parse((LPCSTR)ms.getMemory(), sFile);
|
|||
|
|
if (!sScript)
|
|||
|
|
{
|
|||
|
|
OutputMsg(rmError, _T("script file(%s) preprocess failed"), sFile);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool bRet = setScript(sScript);
|
|||
|
|
if (!bRet)
|
|||
|
|
{
|
|||
|
|
OutputMsg(rmError, _T("setscript failed(%s)"), sFile);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
bRet = loadData();
|
|||
|
|
setScript(NULL);
|
|||
|
|
return bRet;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CBoxDrop::loadData()
|
|||
|
|
{
|
|||
|
|
releaseData();
|
|||
|
|
if (!openGlobalTable(DropTableName))
|
|||
|
|
{
|
|||
|
|
OutputMsg(rmError, _T("load box drop data failed, can't find table: %s"), DropTableName);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
const INT_PTR dropCount = lua_objlen(m_pLua, -1);
|
|||
|
|
memset(m_dropGroup.groupMemberCount, 0, sizeof(m_dropGroup.groupMemberCount));
|
|||
|
|
memset(m_dropGroup.groupNextHitIndex, 0, sizeof(m_dropGroup.groupNextHitIndex));
|
|||
|
|
if (dropCount > 0)
|
|||
|
|
{
|
|||
|
|
m_dropGroup.data.count = dropCount;
|
|||
|
|
m_dropGroup.data.pData = (PONEDROPDATA)malloc(dropCount * sizeof(ONEDROPDATA));
|
|||
|
|
ZeroMemory(m_dropGroup.data.pData, dropCount * sizeof(ONEDROPDATA));
|
|||
|
|
int nIdx = 0;
|
|||
|
|
if (enumTableFirst())
|
|||
|
|
{
|
|||
|
|
PONEDROPDATA pBegin =(PONEDROPDATA )m_dropGroup.data.pData;
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
PONEDROPDATA pData = pBegin +nIdx;
|
|||
|
|
int nDef = 0;
|
|||
|
|
pData->bAwardType = (char)getFieldInt("type",&nDef); //奖励类型
|
|||
|
|
pData->bStrong = (char)getFieldInt("strong",&nDef);
|
|||
|
|
pData->bQuality = (char)getFieldInt("quality",&nDef);
|
|||
|
|
|
|||
|
|
pData->bBind = (char)getFieldInt("bind", &nDef);
|
|||
|
|
|
|||
|
|
//最小数量
|
|||
|
|
pData->nMinCount = (int)getFieldInt("mincount", &nDef);
|
|||
|
|
//最大数量
|
|||
|
|
pData->nMaxCount = (int)getFieldInt("maxcount", &nDef);
|
|||
|
|
|
|||
|
|
pData->nCount = (int)getFieldInt("count", &nDef);
|
|||
|
|
pData->wItemID = (WORD)getFieldInt("id",&nDef);
|
|||
|
|
pData->nPropability = getFieldInt("propability",&nDef);
|
|||
|
|
pData->bGroupId = (BYTE)getFieldInt("group",&nDef);
|
|||
|
|
pData->nTime = getFieldInt("time", &nDef);
|
|||
|
|
//最低的强化
|
|||
|
|
pData->bMinStrong =(char) getFieldInt("strongMin",&nDef );
|
|||
|
|
|
|||
|
|
//最低的品质
|
|||
|
|
pData->bMinQuality =(char) getFieldInt("qualityMin",&nDef );
|
|||
|
|
|
|||
|
|
//-1表示任何性别
|
|||
|
|
nDef =-1;
|
|||
|
|
pData->bSex =(char) getFieldInt("sex",&nDef );
|
|||
|
|
|
|||
|
|
//0表示任何的职业
|
|||
|
|
nDef =0;
|
|||
|
|
pData->bJob =(char) getFieldInt("job",&nDef );
|
|||
|
|
|
|||
|
|
pData->bAuxParam =(char)getFieldInt("broadcast",&nDef);
|
|||
|
|
pData->nQualityDataIndex = (WORD)getFieldInt("qualityDataIndex",&nDef);
|
|||
|
|
|
|||
|
|
if (pData->bGroupId > MAX_DROP_GROUP_COUNT)
|
|||
|
|
{
|
|||
|
|
OutputMsg(rmError,_T("%s 掉落组的ID=%d过大,最大=%d"), __FUNCTION__, (int)(pData->bGroupId), MAX_DROP_GROUP_COUNT);
|
|||
|
|
//pData->bGroupId = 0;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
if (pData->bGroupId) {
|
|||
|
|
m_dropGroup.groupMemberCount[pData->bGroupId-1]++;
|
|||
|
|
}
|
|||
|
|
if (pData->nPropability) {
|
|||
|
|
pData->nSeed = int(wrand(pData->nPropability)+1);
|
|||
|
|
}
|
|||
|
|
nIdx++;
|
|||
|
|
}
|
|||
|
|
while (enumTableNext());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
closeTable();
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
DropItemList CBoxDrop::drop(void * pEntity )
|
|||
|
|
{
|
|||
|
|
int sex=-1, job=0;
|
|||
|
|
if(pEntity )
|
|||
|
|
{
|
|||
|
|
CEntity * pActor = (CEntity*) pEntity;
|
|||
|
|
if( pActor->GetType() == enActor)
|
|||
|
|
{
|
|||
|
|
//玩家的职业和等级
|
|||
|
|
sex = pActor->GetProperty<int>(PROP_ACTOR_SEX);
|
|||
|
|
job = pActor->GetProperty<int>(PROP_ACTOR_VOCATION);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
DropItemList dropList;
|
|||
|
|
INT_PTR nDropCount= m_dropGroup.data.count;
|
|||
|
|
if (nDropCount <=0 ) return dropList;
|
|||
|
|
const CStdItemProvider& itemProvider = GetLogicServer()->GetDataProvider()->GetStdItemProvider();
|
|||
|
|
int nLastGroupID=-1; //遍历的上1个组的ID
|
|||
|
|
int nLastGroupIndex =-1;
|
|||
|
|
bool bGroupHasDrop =false; //这个组是1否已经掉落过了
|
|||
|
|
bool bBagFullFlag[MAX_TEAM_MEMBER_COUNT] = {0}; // 小队玩家任务背包已满标记,用于给用户提示用
|
|||
|
|
int nGroupCurrentPos =0; //组内开始的位置
|
|||
|
|
int nCurrentGroupHeadPos =0; //当前遍历的组的第一个元素的位置
|
|||
|
|
for(INT_PTR i =0 ; i< nDropCount; i++)
|
|||
|
|
{
|
|||
|
|
bool flag =true; //掉落的标记
|
|||
|
|
ONEDROPDATA * pData = &m_dropGroup.data[i];
|
|||
|
|
//这个物品无法掉落
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
if(pData->bGroupId )
|
|||
|
|
{
|
|||
|
|
if( pData->bGroupId != nLastGroupID )
|
|||
|
|
{
|
|||
|
|
nCurrentGroupHeadPos = (int)i;
|
|||
|
|
nLastGroupID = pData->bGroupId;
|
|||
|
|
nGroupCurrentPos = m_dropGroup.groupNextHitIndex [pData->bGroupId -1];
|
|||
|
|
bGroupHasDrop = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pData = &m_dropGroup.data[nCurrentGroupHeadPos + nGroupCurrentPos]; //实际数据是取后面的那一个
|
|||
|
|
nGroupCurrentPos ++;
|
|||
|
|
nGroupCurrentPos %= m_dropGroup.groupMemberCount[pData->bGroupId -1]; //组内的下一
|
|||
|
|
}
|
|||
|
|
if(CanDrop(pData,sex,job) == false) continue;
|
|||
|
|
|
|||
|
|
pData->nDeadTimes ++; //死亡次数++
|
|||
|
|
|
|||
|
|
if(pData->nDeadTimes != pData->nSeed )
|
|||
|
|
{
|
|||
|
|
flag =false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if(pData->bGroupId )
|
|||
|
|
{
|
|||
|
|
if( flag )
|
|||
|
|
{
|
|||
|
|
if(!bGroupHasDrop )
|
|||
|
|
{
|
|||
|
|
bGroupHasDrop = true ; //这个组里已经掉落了
|
|||
|
|
//如果已经掉落了,那么下次要从下一个开始遍历
|
|||
|
|
m_dropGroup.groupNextHitIndex [pData->bGroupId -1]= nGroupCurrentPos;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
flag =false; //如果已经掉落了,那么就不掉了了
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if(pData->nPropability >0 && pData->nDeadTimes >= pData->nPropability) //已经死了很多次了,需要循环
|
|||
|
|
{
|
|||
|
|
pData->nDeadTimes =0;
|
|||
|
|
//第几次死亡能够掉落
|
|||
|
|
pData->nSeed = GetGlobalLogicEngine()->GetRandValue() %pData->nPropability +1;
|
|||
|
|
}
|
|||
|
|
if(!flag) continue;
|
|||
|
|
|
|||
|
|
SetItemInfo(dropList,pData); //添加
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return dropList;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CBoxDrop::SetItemInfo(DropItemList& dropList,ONEDROPDATA * pData )
|
|||
|
|
{
|
|||
|
|
// INT_PTR nItemID= pData->wItemID;
|
|||
|
|
// if(nItemID)
|
|||
|
|
// {
|
|||
|
|
//去掉nItemID判断,修改为通过bAwardType奖励类型 进行奖励
|
|||
|
|
DropItemInfo dropItem;
|
|||
|
|
dropItem.btAwardType = pData->bAwardType;
|
|||
|
|
dropItem.wItemId = pData->wItemID;
|
|||
|
|
dropItem.btCount = (int)pData->nCount;
|
|||
|
|
int nRandCount = 0;
|
|||
|
|
//随机奖励数量
|
|||
|
|
if (pData->nMinCount >= 0 && pData->nMaxCount > 0 )
|
|||
|
|
{
|
|||
|
|
dropItem.btCount = (pData->nMinCount + wrand(abs((int)(pData->nMaxCount-pData->nMinCount))+1));
|
|||
|
|
}
|
|||
|
|
//dropItem.nRandCount = (unsigned int)nRandCount;
|
|||
|
|
|
|||
|
|
//支持随机属性
|
|||
|
|
if (pData->bQuality <0)
|
|||
|
|
{
|
|||
|
|
int nValue =0;
|
|||
|
|
if( pData->bMinQuality >0 )
|
|||
|
|
{
|
|||
|
|
nValue = -1* pData->bQuality;
|
|||
|
|
if( nValue > pData->bMinQuality)
|
|||
|
|
{
|
|||
|
|
nValue = pData->bMinQuality + GetGlobalLogicEngine()->GetRandValue() % (nValue - pData->bMinQuality +1);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
nValue = pData->bMinQuality;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
nValue = -1 * pData->bQuality;
|
|||
|
|
nValue = GetGlobalLogicEngine()->GetRandValue() % (nValue +1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
dropItem.btQuality = (BYTE)nValue;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
dropItem.btQuality = (BYTE)pData->bQuality;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if(pData->bStrong <0)
|
|||
|
|
{
|
|||
|
|
int nValue =0;
|
|||
|
|
if( pData->bMinStrong >0 )
|
|||
|
|
{
|
|||
|
|
nValue = -1* pData->bStrong;
|
|||
|
|
if( nValue > pData->bMinStrong)
|
|||
|
|
{
|
|||
|
|
nValue = pData->bMinStrong + GetGlobalLogicEngine()->GetRandValue() % (nValue - pData->bMinStrong +1);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
nValue = pData->bMinStrong;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
nValue = -1 * pData->bStrong;
|
|||
|
|
nValue = GetGlobalLogicEngine()->GetRandValue() % (nValue +1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
dropItem.btStrong = (BYTE)nValue;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
dropItem.btStrong = (BYTE)pData->bStrong;
|
|||
|
|
}
|
|||
|
|
dropItem.btBind = (BYTE)pData->bBind;
|
|||
|
|
dropItem.btAuxParam = pData->bAuxParam;
|
|||
|
|
dropItem.nTime = pData->nTime;
|
|||
|
|
dropItem.nQualityDataIndex = pData->nQualityDataIndex; //附加属性idx
|
|||
|
|
dropList.addItem(dropItem);
|
|||
|
|
|
|||
|
|
// }
|
|||
|
|
// else //0表示金钱,金钱直接发给玩家了
|
|||
|
|
// {
|
|||
|
|
// dropList.addMoney(pData->nCount);
|
|||
|
|
// }
|
|||
|
|
}
|
|||
|
|
DropItemList CBoxDrop::proabilityDrop(void * pEntity )
|
|||
|
|
{
|
|||
|
|
int sex=-1, job=0;
|
|||
|
|
if(pEntity )
|
|||
|
|
{
|
|||
|
|
CEntity * pActor = (CEntity*) pEntity;
|
|||
|
|
if( pActor->GetType() == enActor)
|
|||
|
|
{
|
|||
|
|
//玩家的职业和等级
|
|||
|
|
sex = pActor->GetProperty<int>(PROP_ACTOR_SEX);
|
|||
|
|
job = pActor->GetProperty<int>(PROP_ACTOR_VOCATION);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
DropItemList dropList;
|
|||
|
|
|
|||
|
|
int total[MAX_DROP_GROUP_COUNT]; //最大的掉落组
|
|||
|
|
int rand[MAX_DROP_GROUP_COUNT]; //随机数
|
|||
|
|
int result[MAX_DROP_GROUP_COUNT]; //结果
|
|||
|
|
|
|||
|
|
memset(&total,0,sizeof(total));
|
|||
|
|
memset(&rand,0,sizeof(rand));
|
|||
|
|
memset(&result,0,sizeof(result));
|
|||
|
|
|
|||
|
|
INT_PTR nDropCount = m_dropGroup.data.count;
|
|||
|
|
|
|||
|
|
//计算概率的总和
|
|||
|
|
for(INT_PTR i =0 ; i< nDropCount; i++)
|
|||
|
|
{
|
|||
|
|
ONEDROPDATA * pData = &m_dropGroup.data[i];
|
|||
|
|
if(pData->bGroupId && pData->bGroupId <= MAX_DROP_GROUP_COUNT)
|
|||
|
|
{
|
|||
|
|
if(CanDrop(pData,sex,job) == false) continue;
|
|||
|
|
{
|
|||
|
|
total[pData->bGroupId -1] += pData->nPropability;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//计算出随机数
|
|||
|
|
for(INT_PTR i=0; i< MAX_DROP_GROUP_COUNT; i++)
|
|||
|
|
{
|
|||
|
|
if(total[i] >0)
|
|||
|
|
{
|
|||
|
|
rand[i] =(int)(1+ wrand( total[i]));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
INT_PTR nCurrentGroupId=0;
|
|||
|
|
INT_PTR nCurrentTotal=0;
|
|||
|
|
|
|||
|
|
for(INT_PTR i =0 ; i< nDropCount; i++)
|
|||
|
|
{
|
|||
|
|
bool isHit =false; //是否命中了
|
|||
|
|
ONEDROPDATA * pData = &m_dropGroup.data[i];
|
|||
|
|
INT_PTR nGroupPos= pData->bGroupId -1;
|
|||
|
|
|
|||
|
|
if(nGroupPos >=0 && nGroupPos < MAX_DROP_GROUP_COUNT)
|
|||
|
|
{
|
|||
|
|
if(result[nGroupPos] >=0)
|
|||
|
|
{
|
|||
|
|
if(CanDrop(pData,sex,job) == false) continue;
|
|||
|
|
result[nGroupPos] += pData->nPropability;
|
|||
|
|
if (result[nGroupPos] >=rand[nGroupPos] )
|
|||
|
|
{
|
|||
|
|
result[nGroupPos] =-1;//一个组里已经有命中的了
|
|||
|
|
isHit =true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
isHit =CanDrop(pData,sex,job);
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
if(!isHit) continue;
|
|||
|
|
SetItemInfo(dropList,pData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return dropList;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
void CBoxDrop::releaseData()
|
|||
|
|
{
|
|||
|
|
if (m_dropGroup.data.pData)
|
|||
|
|
{
|
|||
|
|
free(m_dropGroup.data.pData);
|
|||
|
|
m_dropGroup.data.pData = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CBoxDrop::destroy()
|
|||
|
|
{
|
|||
|
|
releaseData();
|
|||
|
|
CBoxDropMgr::getSingleton().destroyBoxDrop(this);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
CBoxDropMgr& CBoxDropMgr::getSingleton()
|
|||
|
|
{
|
|||
|
|
return *s_BoxDropMgr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CBoxDropMgr::initialize()
|
|||
|
|
{
|
|||
|
|
if (::InterlockedIncrement(&s_boxDropMgrCnt) == 1)
|
|||
|
|
{
|
|||
|
|
s_BoxDropMgr = new CBoxDropMgr();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CBoxDropMgr::release()
|
|||
|
|
{
|
|||
|
|
if (::InterlockedDecrement(&s_boxDropMgrCnt) == 0)
|
|||
|
|
{
|
|||
|
|
SafeDelete(s_BoxDropMgr);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
CBoxDropMgr::~CBoxDropMgr()
|
|||
|
|
{
|
|||
|
|
INT_PTR count = m_boxObjectList.count();
|
|||
|
|
for (INT_PTR i = 0; i < count; i++)
|
|||
|
|
{
|
|||
|
|
// 强制销毁
|
|||
|
|
m_boxObjectList[i]->releaseData();
|
|||
|
|
destroyBoxDropImpl(m_boxObjectList[i]);
|
|||
|
|
}
|
|||
|
|
m_boxObjectList.clear();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CBoxDrop* CBoxDropMgr::createBoxDrop(const char *pKey)
|
|||
|
|
{
|
|||
|
|
if (!pKey) return 0;
|
|||
|
|
|
|||
|
|
CBoxDrop *box = m_dataAllocator.allocObject();
|
|||
|
|
if (box) {
|
|||
|
|
new(box)CBoxDrop();
|
|||
|
|
box->SetObjectName(pKey);
|
|||
|
|
box->addRef();
|
|||
|
|
GlobalObjectMgr::getSingleton().SetGlobalObject(pKey, box);
|
|||
|
|
m_boxObjectList.add(box);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return box;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CBoxDropMgr::destroyBoxDrop(CBoxDrop *bd)
|
|||
|
|
{
|
|||
|
|
destroyBoxDropImpl(bd);
|
|||
|
|
removeFromList(bd);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CBoxDropMgr::removeFromList(CBoxDrop *bd)
|
|||
|
|
{
|
|||
|
|
for (INT_PTR i = 0; i < m_boxObjectList.count(); i++)
|
|||
|
|
{
|
|||
|
|
if (m_boxObjectList[i] == bd)
|
|||
|
|
m_boxObjectList.remove(i);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CBoxDropMgr::destroyBoxDropImpl(CBoxDrop *bd)
|
|||
|
|
{
|
|||
|
|
if (bd) {
|
|||
|
|
GlobalObjectMgr::getSingleton().ClearGlobalObject(bd->GetObjectName());
|
|||
|
|
bd->~CBoxDrop();
|
|||
|
|
m_dataAllocator.freeObject(bd);
|
|||
|
|
}
|
|||
|
|
}
|