示例#1
0
CurrencyValue CLevelTableOfItemGenerators::GetAverageValue (int iLevel)

//	GetAverageValue
//
//	Returns the average value.

	{
	int i;

	//	Compute the table for this level.

	Metric rTotal = 0.0;
	int iTotalChance = 0;
	for (i = 0; i < m_Table.GetCount(); i++)
		{
		int iChance = GetFrequencyByLevel(m_Table[i].sLevelFrequency, iLevel);
		iTotalChance += iChance;
		}

	for (i = 0; i < m_Table.GetCount(); i++)
		{
		int iChance = GetFrequencyByLevel(m_Table[i].sLevelFrequency, iLevel);
		if (iChance > 0)
			rTotal += (m_Table[i].Count.GetAveValueFloat() * (Metric)m_Table[i].pEntry->GetAverageValue(iLevel) * (Metric)iChance / (Metric)iTotalChance);
		}

	return (CurrencyValue)(rTotal + 0.5);
	}
示例#2
0
void CLevelTableOfItemGenerators::AddItems (SItemAddCtx &Ctx)

//	AddItems
//
//	Adds items

	{
	int i, j;

	//	Compute probabilities, if necessary

	if (m_iComputedLevel != Ctx.iLevel)
		{
		//	Create a table of probabilities

		m_iTotalChance = 0;
		for (i = 0; i < m_Table.GetCount(); i++)
			{
			m_Table[i].iChance = GetFrequencyByLevel(m_Table[i].sLevelFrequency, Ctx.iLevel);
			m_iTotalChance += m_Table[i].iChance;
			}

		m_iComputedLevel = Ctx.iLevel;
		}

	//	Generate

	if (m_iTotalChance)
		{
		int iRoll = mathRandom(1, m_iTotalChance);
		for (i = 0; i < m_Table.GetCount(); i++)
			{
			iRoll -= m_Table[i].iChance;

			if (iRoll <= 0)
				{
				int iCount = m_Table[i].Count.Roll();

				for (j = 0; j < iCount; j++)
					m_Table[i].pEntry->AddItems(Ctx);

				break;
				}
			}
		}
	}
void CLevelTableOfDeviceGenerators::AddDevices (SDeviceGenerateCtx &Ctx)

//	AddDevices
//
//	Adds devices

	{
	int i, j;

	//	Compute probabilities

	if (Ctx.iLevel != m_iComputedLevel)
		{
		m_iTotalChance = 0;
		for (i = 0; i < m_Table.GetCount(); i++)
			{
			m_Table[i].iChance = GetFrequencyByLevel(m_Table[i].sLevelFrequency, Ctx.iLevel);
			m_iTotalChance += m_Table[i].iChance;
			}

		m_iComputedLevel = Ctx.iLevel;
		}

	//	Generate

	if (m_iTotalChance)
		{
		int iCount = m_Count.Roll();

		for (i = 0; i < iCount; i++)
			{
			int iRoll = mathRandom(1, m_iTotalChance);

			for (j = 0; j < m_Table.GetCount(); j++)
				{
				iRoll -= m_Table[j].iChance;

				if (iRoll <= 0)
					{
					m_Table[j].pDevice->AddDevices(Ctx);
					break;
					}
				}
			}
		}
	}
示例#4
0
void CRandomItems::InitTable (void)

//	InitTable
//
//	Initializes the m_Table array.
//
//	We assume that m_Criteria, m_sLevelFrequency, m_iLevel, and m_iLevelCurve are properly initialized.

	{
	int i;

	//	Start by allocating an array large enough to hold
	//	all item types in the universe

	ItemEntryStruct *pTable = new ItemEntryStruct [g_pUniverse->GetItemTypeCount()];
	int iTableSize = 0;

	//	Figure out if we should use level curves or level frequency

	bool bUseLevelFrequency = !m_sLevelFrequency.IsBlank();

	//	Iterate over every item type and add it to the table if
	//	it matches the given criteria

	for (i = 0; i < g_pUniverse->GetItemTypeCount(); i++)
		{
		CItemType *pType = g_pUniverse->GetItemType(i);
		CItem Item(pType, 1);

		//	Skip if the item doesn't match the categories

		if (!Item.MatchesCriteria(m_Criteria))
			continue;

		//	Skip if this item is not found randomly

		if (pType->GetFrequency() == ftNotRandom)
			continue;

		//	Adjust score based on level, either the level curve
		//	or the level frequency string.

		int iScore;
		if (bUseLevelFrequency)
			{
			iScore = 1000 * GetFrequencyByLevel(m_sLevelFrequency, pType->GetLevel()) / ftCommon;
			}
		else
			{
			//	Skip if the item is not within the level curve

			if ((pType->GetLevel() < m_iLevel - m_iLevelCurve)
					|| (pType->GetLevel() > m_iLevel + m_iLevelCurve))
				continue;

			//	If we get this far then the item perfectly matches
			//	and we need to add it to our table. First, however, we need
			//	to calculate a score.
			//
			//	The score is number that represents how common the item
			//	is in the table. Later we normalize the score to be a probability

			int iLevelDelta = pType->GetLevel() - m_iLevel;
			switch (iLevelDelta)
				{
				case 0:
					iScore = 1000;
					break;

				case 1:
				case -1:
					iScore = 500;
					break;

				case 2:
				case -2:
					iScore = 200;
					break;

				default:
					iScore = 50;
				}
			}

		//	Adjust score based on item frequency

		iScore = iScore * pType->GetFrequency() * 10 / (ftCommon * 10);

		//	If we have a score of 0 then we skip this item

		if (iScore == 0)
			continue;

		//	Add the item to the table

		pTable[iTableSize].pType = pType;
		pTable[iTableSize].iChance = iScore;
		iTableSize++;
		}

	//	We must have items

	if (iTableSize == 0)
		{
		m_iCount = 0;
		m_Table = NULL;
		return;
		}

	//	Add up the total score of all items

	int iTotalScore = 0;
	for (i = 0; i < iTableSize; i++)
		iTotalScore += pTable[i].iChance;

	//	Compute the chance

	int iTotalChance = 0;
	for (i = 0; i < iTableSize; i++)
		{
		int iScore = pTable[i].iChance;
		pTable[i].iChance = (iScore * 1000) / iTotalScore;
		pTable[i].iRemainder = (iScore * 1000) % iTotalScore;

		iTotalChance += pTable[i].iChance;
		}

	//	Distribute the remaining chance points

	while (iTotalChance < 1000)
		{
		//	Look for the entry with the biggest remainder

		int iBestRemainder = 0;
		int iBestEntry = -1;

		for (i = 0; i < iTableSize; i++)
			if (pTable[i].iRemainder > iBestRemainder)
				{
				iBestRemainder = pTable[i].iRemainder;
				iBestEntry = i;
				}

		pTable[iBestEntry].iChance++;
		pTable[iBestEntry].iRemainder = 0;
		iTotalChance++;
		}

	//	Count the number of entries that we've got

	m_iCount = 0;
	for (i = 0; i < iTableSize; i++)
		if (pTable[i].iChance > 0)
			m_iCount++;

	//	Now loop over the entire table and add it to the 
	//	random entry generator

	m_Table = new SEntry [m_iCount];
	int j = 0;
	for (i = 0; i < iTableSize; i++)
		if (pTable[i].iChance > 0)
			{
			m_Table[j].pType = pTable[i].pType;
			m_Table[j].iProbability = pTable[i].iChance;
			j++;
			}

	//	Done

	delete [] pTable;
	}