Example #1
0
CItemType *CWeaponFireDesc::GetWeaponType (CItemType **retpLauncher) const

//	GetWeaponType
//
//	Returns the item type that best represents this descriptor. For missiles,
//	we return the missile item UNID; for single-shot weapons (including ammo weapons)
//	we return the weapon item UNID

	{
	char *pPos = m_sUNID.GetPointer();

	//	Get the weapon UNID and the ordinal

	DWORD dwUNID = (DWORD)strParseInt(pPos, 0, &pPos);
	ASSERT(*pPos == '/');
	pPos++;
	int iOrdinal = strParseInt(pPos, 0, &pPos);

	//	Get the weapon descriptor

	CWeaponClass *pClass = (CWeaponClass *)g_pUniverse->FindDeviceClass(dwUNID);
	if (pClass == NULL)
		return NULL;

	//	Return the device/launcher

	if (retpLauncher)
		*retpLauncher = pClass->GetItemType();

	//	For launchers, figure out which missile this is

	if (pClass->GetCategory() == itemcatLauncher)
		{
		CWeaponFireDesc *pMissileDesc = pClass->GetVariant(iOrdinal);
		if (pMissileDesc == NULL)
			return NULL;

		//	If we have ammo, then return the ammo type

		CItemType *pAmmoType = pMissileDesc->GetAmmoType();
		if (pAmmoType)
			return pAmmoType;

		//	Otherwise return the launcher (e.g., DM600)

		return pClass->GetItemType();
		}

	//	Otherwise, return the weapon

	else
		return pClass->GetItemType();
	}
Example #2
0
ALERROR LoadTotalCount (const CString &sFilename, CSymbolTable &TotalCount)
	{
	ALERROR error;

	CFileReadBlock Input(sFilename);
	if (error = Input.Open())
		{
		printf("ERROR: Unable to open total count file. Use /generateSimTables.");
		return error;
		}

	char *pPos = Input.GetPointer(0, -1);
	char *pEndPos = pPos + Input.GetLength();

	while (pPos < pEndPos)
		{
		//	Read an UNID

		DWORD dwUNID = (DWORD)strParseInt(pPos, 0, &pPos);
		if (dwUNID == 0)
			break;

		//	Read an count

		if (pPos >= pEndPos)
			{
			printf("ERROR: Unexpected end of file.");
			return ERR_FAIL;
			}

		int iCount = strParseInt(pPos, 0, &pPos);

		//	Add the entry

		CString sKey = strFromInt(dwUNID, false);
		EntryInfo *pEntry = new EntryInfo;
		pEntry->dwUNID = dwUNID;
		pEntry->rTotalCount = (double)iCount / 1000.0;

		if (error = TotalCount.AddEntry(sKey, pEntry))
			{
			printf("ERROR: Invalid UNID.");
			return error;
			}
		}

	return NOERROR;
	}
TreeNode* createTree(vector<string> nums)
{
	unsigned int i = 0, j;
	vector<TreeNode*> treeNodes;
	TreeNode* treeNode;
	for (; i < nums.size(); i++)
	{
		if (!nums[i].compare("null"))
		{
			treeNode = NULL;
			treeNodes.push_back(treeNode);
			continue;
		}
		treeNode = (TreeNode*)(malloc(sizeof(TreeNode)));
		treeNode->val = strParseInt(nums[i]);
		treeNode->left = NULL;
		treeNode->right = NULL;
		treeNodes.push_back(treeNode);
	}
	for (i = 0; i < nums.size() / 2; i++)
	{
		j = 2 * i + 1;
		if (j < nums.size())
			treeNodes[i]->left = treeNodes[j];
		j++;
		if (j < nums.size())
			treeNodes[i]->right = treeNodes[j];
	}
	return treeNodes[0];
}
Example #4
0
void ReadLine (char *pPos, char *pEndPos, TArray<int> *retValues, char **retpPos)
	{
	while (true)
		{
		//	Skip to the next number.

		while (pPos < pEndPos && !strIsDigit(pPos) && *pPos != '-' && *pPos != '+' && *pPos != '\n' && *pPos != '\r')
			pPos++;

		if (pPos >= pEndPos || *pPos == '\n' || *pPos == '\r')
			{
			while (pPos < pEndPos && (*pPos == '\n' || *pPos == '\r'))
				pPos++;

			break;
			}

		//	Parse the number

		int iValue = strParseInt(pPos, 0, &pPos);
		retValues->Insert(iValue);
		}

	if (retpPos)
		*retpPos = pPos;
	}
Example #5
0
ICCItem *fnSubst (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnSubst
//
//	Substitutes string parameters
//
//	(subst string arg1 arg2 ... argn)

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pArgs;

	//	Evaluate the arguments and validate them

	pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("s*"));
	if (pArgs->IsError())
		return pArgs;

	CString sPattern = pArgs->GetElement(0)->GetStringValue();

	//	Do the substitution

	char szResult[4096];
	char *pPos = sPattern.GetASCIIZPointer();
	char *pDest = szResult;
	char *pEndDest = szResult + sizeof(szResult) - 1;

	while (*pPos != '\0' && pDest < pEndDest)
		{
		if (*pPos == '%')
			{
			pPos++;

			int iArg = strParseInt(pPos, 0, &pPos, NULL);
			if (iArg > 0)
				{
				CString sParam = pArgs->GetElement(iArg)->GetStringValue();
				char *pParam = sParam.GetASCIIZPointer();

				while (*pParam != '\0' && pDest < pEndDest)
					*pDest++ = *pParam++;

				pPos++;
				}
			else
				{
				if (*pPos == '%')
					*pDest++ = *pPos++;
				}
			}
		else
			*pDest++ = *pPos++;
		}

	//	Done

	*pDest = '\0';
	pArgs->Discard(pCC);
	return pCC->CreateString(CString(szResult));
	}
Example #6
0
bool CComplexDateTime::CreateFromString (const CString &sString, CDateTime *retDateTime)

//	CreateFromString
//
//	Reverse of AsString

	{
	char *pPos = sString.GetParsePointer();

	int iYear = strParseInt(pPos, 0, &pPos);
	if (iYear < 1 || iYear > 30827)
		return false;

	if (*pPos++ != '-')
		return false;

	int iMonth = strParseInt(pPos, 0, &pPos);
	if (iMonth < 1 || iMonth > 12)
		return false;

	if (*pPos++ != '-')
		return false;

	int iDay = strParseInt(pPos, 0, &pPos);
	if (iDay < 1 || iDay > CDateTime::GetDaysInMonth(iMonth, iYear))
		return false;

	if (*pPos++ != 'T')
		return false;

	int iHour = strParseInt(pPos, -1, &pPos);
	if (iHour < 0 || iHour > 23)
		return false;

	if (*pPos++ != ':')
		return false;

	int iMinute = strParseInt(pPos, -1, &pPos);
	if (iMinute < 0 || iMinute > 59)
		return false;

	if (*pPos++ != ':')
		return false;

	int iSecond = strParseInt(pPos, -1, &pPos);
	if (iSecond < 0 || iSecond > 59)
		return false;

	if (*pPos++ != '.')
		return false;

	int iMillisecond = strParseInt(pPos, -1, &pPos);
	if (iMillisecond < 0 || iMillisecond > 999)
		return false;

	//	Done

	*retDateTime = CDateTime(iDay, iMonth, iYear, iHour, iMinute, iSecond, iMillisecond);
	return true;
	}
Example #7
0
CEffectCreator *CEffectCreator::FindEffectCreator (const CString &sUNID)

//	FindEffectCreator
//
//	Finds the effect creator from a complex UNID (or NULL if not found)

	{
	//	A complex UNID looks like this:
	//
	//	For effects:
	//
	//	{unid}
	//
	//	"12345"					= Effect UNID 12345
	//	"12345/0"				= Effect UNID 12345; variant 0
	//	"12345/d:h"				= Effect UNID 12345; damage; hit effect
	//
	//	For overlays:
	//
	//	{unid}:e
	//	{unid}:h
	//
	//	For shields:
	//
	//	{unid}:h
	//	"12345:h"				= Shield UNID 12345; Hit effect
	//
	//	For system maps:
	//
	//	{unid}/{nodeID}
	//	{unid}/{nodeID}[/{nodeID}]
	//
	//	For weapons:
	//
	//	{unid}/{var}[/f{frag}]:(e | h | f)
	//
	//	"12345/0:e"				= Weapon UNID 12345; variant 0; Bullet effect
	//	"12345/0/f0:h"			= Weapon UNID 12345; variant 0; fragment 0; Hit Effect
	//

	//	First we parse the UNID

	char *pPos = sUNID.GetASCIIZPointer();
	DWORD dwUNID = strParseInt(pPos, 0, &pPos);

	//	Look for the design type

	CDesignType *pDesign = g_pUniverse->FindDesignType(dwUNID);
	if (pDesign == NULL)
		return NULL;

	//	Allow the design type to parse the remainder of the UNID

	return pDesign->FindEffectCreatorInType(CString(pPos));
	}
Example #8
0
CEffectCreator *CEffectCreator::OnFindEffectCreator (const CString &sUNID)

//	OnFindEffectCreator
//
//	Finds the effect creator by UNID

	{
	char *pPos = sUNID.GetASCIIZPointer();

	//	If we're done, then we mean ourselves

	if (*pPos == '\0')
		return this;

	if (*pPos++ != '/')
		return NULL;

	//	Damage selector?

	if (*pPos == 'd')
		{
		pPos++;

		if (m_pDamage == NULL)
			return NULL;

		return m_pDamage->FindEffectCreator(CString(pPos));
		}

	//	Sub effect

	int iSubEffect = strParseInt(pPos, -1, 0, &pPos);
	if (iSubEffect == -1)
		return NULL;

	CEffectCreator *pSubEffect = GetSubEffect(iSubEffect);
	if (pSubEffect == NULL)
		return NULL;

	return pSubEffect->FindEffectCreatorInType(CString(pPos));
	}
Example #9
0
ICCItem *CreateResultFromDataField (CCodeChain &CC, const CString &sValue)

//	CreateResultFromDataField
//
//	Converts a data field result into either an integer or a string

	{
	//	Blank values are Nil

	if (sValue.IsBlank())
		return CC.CreateNil();

	//	If prefixed with = sign, then this is a CodeChain expression

	else if (*sValue.GetASCIIZPointer() == '=')
		return CC.Link(sValue, 1, NULL);

	//	Handle some special constants

	else if (strEquals(sValue, CONSTLIT("true")))
		return CC.CreateTrue();
	else if (strEquals(sValue, CONSTLIT("nil")) 
			|| strEquals(sValue, CONSTLIT("false"))
			|| strEquals(sValue, CONSTLIT("none")))
		return CC.CreateNil();

	//	Otherwise, see if it is a string or an integer

	else
		{
		char *pPos = sValue.GetASCIIZPointer();
		char *pEnd;
		bool bNull;
		int iResult = strParseInt(pPos, 0, &pEnd, &bNull);
		if (!bNull && *pEnd == '\0')
			return CC.CreateInteger(iResult);
		else
			return CC.CreateString(sValue);
		}
	}
Example #10
0
ALERROR CMissionType::OnCreateFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc)

//	OnCreateFromXML
//
//	Create from XML

	{
	ALERROR error;

	m_sName = pDesc->GetAttribute(NAME_ATTRIB);
	m_iPriority = pDesc->GetAttributeIntegerBounded(PRIORITY_ATTRIB, 0, -1, 1);
	m_iExpireTime = pDesc->GetAttributeIntegerBounded(EXPIRE_TIME_ATTRIB, 1, -1, -1);
	m_iFailIfOutOfSystem = pDesc->GetAttributeIntegerBounded(FAILURE_AFTER_OUT_OF_SYSTEM_ATTRIB, 0, -1, -1);
	m_fNoFailureOnOwnerDestroyed = pDesc->GetAttributeBool(NO_FAILURE_ON_OWNER_DESTROYED_ATTRIB);
	m_fNoDebrief = pDesc->GetAttributeBool(NO_DEBRIEF_ATTRIB);
	m_fNoStats = pDesc->GetAttributeBool(NO_STATS_ATTRIB);
	m_fCloseIfOutOfSystem = pDesc->GetAttributeBool(DEBRIEF_AFTER_OUT_OF_SYSTEM_ATTRIB);
	m_fForceUndockAfterDebrief = pDesc->GetAttributeBool(FORCE_UNDOCK_AFTER_DEBRIEF_ATTRIB);
	m_fAllowDelete = pDesc->GetAttributeBool(ALLOW_PLAYER_DELETE_ATTRIB);

	CString sAttrib;
	if (pDesc->FindAttribute(MAX_APPEARING_ATTRIB, &sAttrib))
		{
		if (error = m_MaxAppearing.LoadFromXML(sAttrib))
			{
			Ctx.sError = CONSTLIT("Invalid maxAppearing parameter.");
			return ERR_FAIL;
			}
		}

	m_iMaxAppearing = (m_MaxAppearing.IsEmpty() ? -1 : m_MaxAppearing.Roll());
	m_iAccepted = 0;

	//	Level

	if (pDesc->FindAttribute(LEVEL_ATTRIB, &sAttrib))
		{
		//	Parse this value

		char *pPos = sAttrib.GetASCIIZPointer();
		m_iMinLevel = Max(1, Min(strParseInt(pPos, 1, &pPos), MAX_SYSTEM_LEVEL));

		while (*pPos == ' ')
			pPos++;

		if (*pPos == '-')
			{
			pPos++;
			m_iMaxLevel = Max(m_iMinLevel, Min(strParseInt(pPos, MAX_SYSTEM_LEVEL), MAX_SYSTEM_LEVEL));
			}
		else
			m_iMaxLevel = m_iMinLevel;
		}
	else
		{
		m_iMinLevel = 1;
		m_iMaxLevel = MAX_SYSTEM_LEVEL;
		}

	return NOERROR;
	}
Example #11
0
bool CTimeSpan::ParsePartial (char *pPos, DWORD *retdwDays, DWORD *retdwMilliseconds, char **retpPos)

//	ParsePartial
//
//	Parses a string of the form:
//
//	xx {time-unit}

	{
	//	Skip whitespace

	while (*pPos == ' ')
		pPos++;

	//	Parse a number

	bool bFailed;
	DWORD dwValue1 = strParseInt(pPos, 0, &pPos, &bFailed);
	if (bFailed)
		return false;

	//	See if we have a decimal

	DWORD dwValue2;
	if (*pPos == '.')
		{
		pPos++;
		dwValue2 = strParseInt(pPos, 0, &pPos, &bFailed);
		if (bFailed)
			return false;

		//	Decimal extend to three digits. E.g., if .7, we convert to 700.

		if (dwValue2 < 10)
			dwValue2 *= 100;
		else if (dwValue2 < 100)
			dwValue2 *= 10;
		}
	else
		dwValue2 = 0;

	//	Skip whitespace

	while (*pPos == ' ')
		pPos++;

	//	Get the time unit

	char *pStart = pPos;
	while (*pPos != ' ' && *pPos != '\0')
		pPos++;

	//	We can guess the time unit based on the first character

	if (*pStart == 'y')
		{
		*retdwDays = dwValue1 * 365;
		*retdwMilliseconds = 0;
		}
	else if (*pStart == 'd')
		{
		*retdwDays = dwValue1;
		*retdwMilliseconds = 0;
		}
	else if (*pStart == 'h')
		{
		*retdwDays = 0;
		*retdwMilliseconds = dwValue1 * 60 * 60 * 1000;
		}
	else if (*pStart == 'm')
		{
		*retdwDays = 0;
		*retdwMilliseconds = dwValue1 * 60 * 1000;
		}
	else if (*pStart == 's')
		{
		*retdwDays = 0;
		*retdwMilliseconds = dwValue1 * 1000 + dwValue2;
		}
	else
		return false;

	//	Done

	*retpPos = pPos;
	return true;
	}
Example #12
0
bool NextEntity (char **ioPos, char *pEnd, CString *retsName, DWORD *retdwValue)
	{
	char *pPos = *ioPos;

	while (true)
		{
		//	Look for '<'

		while (pPos < pEnd && *pPos != '<' && *pPos != ']')
			pPos++;

		if (pPos == pEnd || *pPos == ']')
			return false;

		//	Look for '!'

		pPos++;
		if (*pPos != '!')
			continue;

		//	Look for 'E'

		pPos++;
		if (*pPos != 'E')
			continue;

		//	Skip to whitespace

		while (pPos < pEnd && *pPos != ' ' && *pPos != '\t')
			pPos++;

		if (pPos == pEnd)
			return false;

		//	Skip to non-space

		while (pPos < pEnd && (*pPos == ' ' || *pPos == '\t'))
			pPos++;

		if (pPos == pEnd)
			return false;

		//	Skip to whitespace

		char *pStart = pPos;
		while (pPos < pEnd && *pPos != ' ' && *pPos != '\t')
			pPos++;

		if (pPos == pEnd)
			return false;

		*retsName = CString(pStart, pPos - pStart);

		//	Skip to quote

		while (pPos < pEnd && *pPos != '\"')
			pPos++;

		if (pPos == pEnd)
			return false;

		pPos++;
		*retdwValue = strParseInt(pPos, 0, &pPos);
		if (*retdwValue != 0)
			{
			*ioPos = pPos;
			return true;
			}
		}
	}
Example #13
0
bool CG16bitFont::ParseFontDesc (const CString &sDesc, CString *retsTypeface, int *retiSize, bool *retbBold, bool *retbItalic)

//	ParseFontDesc
//
//	Parses a string of the form:
//
//	{typeface} {font-size} [bold] [italic]
//
//	Returns TRUE if valid

	{
	char *pPos = sDesc.GetASCIIZPointer();
	CString sTypeface = CONSTLIT("Arial");
	int iSize = 16;
	bool bBold = false;
	bool bItalic = false;

	//	Skip whitespace

	while (*pPos == ' ' || *pPos == '\t')
		pPos++;

	//	Skip delimiters

	bool bSpaceDelimiter;
	if (*pPos == '\'' || *pPos == '\"')
		{
		bSpaceDelimiter = false;
		pPos++;
		}
	else
		bSpaceDelimiter = true;

	//	Look for typeface

	char *pStart = pPos;
	while (*pPos != '\'' && *pPos != '\"' && (!bSpaceDelimiter || *pPos != ' ') && *pPos != '\0')
		pPos++;

	sTypeface = CString(pStart, pPos - pStart);

	//	Look for size

	while ((*pPos < '0' || *pPos > '9') && *pPos != '\0')
		pPos++;

	if (*pPos == '\0')
		{
		//printf("DirectXFont: Expected font size.");
		return false;
		}

	iSize = strParseInt(pPos, -1, &pPos);
	if (iSize == -1)
		{
		//printf("DirectXFont: Invalid font size.");
		return false;
		}

	//	Skip whitespace

	while (*pPos == ' ' || *pPos == '\t')
		pPos++;

	//	Parse bold/italic

	pStart = pPos;
	bool bDone = (*pPos == '\0');
	while (!bDone)
		{
		if (*pPos == ' ' || *pPos == '\0')
			{
			CString sStyle = CString(pStart, pPos - pStart);
			if (strEquals(sStyle, CONSTLIT("bold")))
				bBold = true;
			else if (strEquals(sStyle, CONSTLIT("italic")))
				bItalic = true;

			//	Skip whitespace

			while (*pPos == ' ')
				pPos++;

			pStart = pPos;
			bDone = (*pPos == '\0');
			}
		else
			pPos++;
		}

	//	Done

	*retsTypeface = sTypeface;
	*retiSize = iSize;
	*retbBold = bBold;
	*retbItalic = bItalic;

	return true;
	}
Example #14
0
bool CTimeDate::Parse (const CString &sFormat, const CString &sValue, CString *retsError)

//	Parse
//
//	Parse a date of the given format.

	{
	//	Internet format:
	//
	//	Sun, 06 Nov 1994 08:49:37 GMT

	if (strEquals(sFormat, FORMAT_INTERNET))
		{
		char *pPos = sValue.GetASCIIZPointer();
		char *pPosEnd = pPos + sValue.GetLength();

		//	Skip leading whitespace

		while (strIsWhitespace(pPos))
			pPos++;

		//	Skip day of week

		while (pPos < pPosEnd
				&& (*pPos < '0' || *pPos > '9'))
			pPos++;

		if (pPos >= pPosEnd)
			goto InvalidValue;

		//	Day

		bool bFail;
		m_Time.wDay = strParseInt(pPos, 0, &pPos, &bFail);
		if (bFail || m_Time.wDay < 1 || m_Time.wDay > 31)
			goto InvalidValue;

		pPos++;
		if (pPos >= pPosEnd)
			goto InvalidValue;

		//	Month

		if (*pPos == 'A')
			{
			pPos++;
			if (*pPos == 'p')
				{
				m_Time.wMonth = 4;
				pPos += 3;
				}
			else if (*pPos == 'u')
				{
				m_Time.wMonth = 8;
				pPos += 3;
				}
			else
				goto InvalidValue;
			}
		else if (*pPos == 'D')
			{
			m_Time.wMonth = 12;
			pPos += 4;
			}
		else if (*pPos == 'F')
			{
			m_Time.wMonth = 2;
			pPos += 4;
			}
		else if (*pPos == 'J')
			{
			pPos++;
			if (*pPos == 'a')
				{
				m_Time.wMonth = 1;
				pPos += 3;
				}
			else if (*pPos == 'u')
				{
				pPos++;
				if (*pPos == 'l')
					{
					m_Time.wMonth = 7;
					pPos += 2;
					}
				else if (*pPos == 'n')
					{
					m_Time.wMonth = 6;
					pPos += 2;
					}
				else
					goto InvalidValue;
				}
			else
				goto InvalidValue;
			}
		else if (*pPos == 'M')
			{
			pPos++;
			if (*pPos == 'a')
				{
				pPos++;
				if (*pPos == 'r')
					{
					m_Time.wMonth = 3;
					pPos += 2;
					}
				else if (*pPos == 'y')
					{
					m_Time.wMonth = 5;
					pPos += 2;
					}
				else
					goto InvalidValue;
				}
			else
				goto InvalidValue;
			}
		else if (*pPos == 'N')
			{
			m_Time.wMonth = 11;
			pPos += 4;
			}
		else if (*pPos == 'O')
			{
			m_Time.wMonth = 10;
			pPos += 4;
			}
		else if (*pPos == 'S')
			{
			m_Time.wMonth = 9;
			pPos += 4;
			}
		else
			goto InvalidValue;

		if (pPos >= pPosEnd)
			goto InvalidValue;

		//	Year

		m_Time.wYear = strParseInt(pPos, 0, &pPos, &bFail);
		if (bFail || m_Time.wYear < 1)
			goto InvalidValue;

		pPos++;
		if (pPos >= pPosEnd)
			goto InvalidValue;

		//	Hour

		m_Time.wHour = strParseInt(pPos, 0, &pPos, &bFail);
		if (bFail || m_Time.wHour > 23)
			goto InvalidValue;

		pPos++;
		if (pPos >= pPosEnd)
			goto InvalidValue;

		//	Minute

		m_Time.wMinute = strParseInt(pPos, 0, &pPos, &bFail);
		if (bFail || m_Time.wMinute > 59)
			goto InvalidValue;

		pPos++;
		if (pPos >= pPosEnd)
			goto InvalidValue;

		//	Second

		m_Time.wSecond = strParseInt(pPos, 0, &pPos, &bFail);
		if (bFail || m_Time.wSecond > 59)
			goto InvalidValue;

		//	Millisecond is not stored

		m_Time.wMilliseconds = 0;

		//	We don't store day of week

		m_Time.wDayOfWeek = 0xffff;

		//	Done

		return true;

InvalidValue:

		if (retsError) *retsError = strPatternSubst(CONSTLIT("Invalid date value: %s"), sValue);
		return false;
		}
	else
		{
		if (retsError) *retsError = strPatternSubst(CONSTLIT("Unsupported date format: %s."), sFormat);
		return false;
		}
	}
Example #15
0
void GenerateShieldStats (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	int i;

	CString sUNID = pCmdLine->GetAttribute(CONSTLIT("unid"));
	DWORD dwUNID = strToInt(sUNID, 0, NULL);
	CItemType *pItem = Universe.FindItemType(dwUNID);
	if (pItem == NULL)
		{
		CItemCriteria Crit;
		CItem::InitCriteriaAll(&Crit);
		CItem Item = CItem::CreateItemByName(sUNID, Crit);
		pItem = Item.GetType();

		if (pItem == NULL)
			{
			printf("ERROR: Unknown item '%s'\n", sUNID.GetASCIIZPointer());
			return;
			}
		}

	if (pItem->GetCategory() != itemcatShields)
		{
		printf("ERROR: Item '%s' is not a shield generator\n", pItem->GetNounPhrase().GetASCIIZPointer());
		return;
		}

	bool bVerbose = pCmdLine->GetAttributeBool(CONSTLIT("verbose"));
	bool bEval = pCmdLine->GetAttributeBool(CONSTLIT("eval"));

	//	Get the stats for the shield

	Metric rHP = (Metric)pItem->GetDataFieldInteger(FIELD_HP);
	Metric rHPRegenPerTick = pItem->GetDataFieldInteger(FIELD_REGEN) / 1000.0;

	int iDamageAdj[damageCount];
	CString sDamageAdj = pItem->GetDataField(CONSTLIT("damageAdj"));
	char *pPos = sDamageAdj.GetASCIIZPointer();
	int iCount = 0;
	while (iCount < damageCount)
		{
		iDamageAdj[iCount] = strParseInt(pPos, 0, &pPos, NULL);
		if (*pPos != '\0')
			pPos++;
		iCount++;
		}

	//	Print header

	printf("%s\n\n", pItem->GetNounPhrase().GetASCIIZPointer());

	//	Loop over all weapons and sort them by level and then name

	CSymbolTable List(FALSE, TRUE);
	for (i = 0; i < Universe.GetItemTypeCount(); i++)
		{
		CItemType *pWeapon = Universe.GetItemType(i);
		if (pWeapon->GetCategory() != itemcatWeapon)
			continue;

		CString sLevel = (pWeapon->GetLevel() < 10 ? strPatternSubst(CONSTLIT("0%d"), pWeapon->GetLevel()) : strFromInt(pWeapon->GetLevel(), FALSE));
		CString sSortName = strPatternSubst(CONSTLIT("%s%s"), sLevel, pWeapon->GetNounPhrase());
		List.AddEntry(sSortName, (CObject *)pWeapon);
		}

	//	Loop over sorted list and output data

	for (i = 0; i < List.GetCount(); i++)
		{
		CItemType *pWeapon = (CItemType *)List.GetValue(i);

		//	Get the data for the weapon

		int iFireDelay = pWeapon->GetDataFieldInteger(CONSTLIT("fireDelay"));
		Metric rAverageDamage = pWeapon->GetDataFieldInteger(CONSTLIT("averageDamage")) / 1000.0;
		int iDamageType = pWeapon->GetDataFieldInteger(CONSTLIT("damageType"));
		if (iDamageType < 0 || iDamageType >= damageCount)
			iDamageType = 0;

		//	Adjust damage for type

		rAverageDamage = rAverageDamage * (iDamageAdj[iDamageType] / 100.0);
		if (rAverageDamage < 1.0)
			rAverageDamage = 0.0;

		//	Calculate how many shots it would take to pierce through the shields

		char szBuffer[256];
		Metric rShotsToDeplete;
		Metric rRegenPerShot = rHPRegenPerTick * (Metric)iFireDelay;
		if (rRegenPerShot >= rAverageDamage)
			{
			rShotsToDeplete = 1000000.0;
			lstrcpy(szBuffer, "ineffective");
			}
		else
			{
			Metric rDrainPerShot = rAverageDamage - rRegenPerShot;
			rShotsToDeplete = rHP / rDrainPerShot;
			sprintf(szBuffer, "%.2f", rShotsToDeplete);
			}

		//	See if this weapon is overpowered or underpowered

		char szEval[256];
		if (bEval)
			{
			lstrcpy(szEval, "\t");
			if (pWeapon->GetLevel() < pItem->GetLevel())
				{
				if (rShotsToDeplete <= 10.0)
					lstrcpy(szEval, "\tOVERpowered");
				}
			else
				{
				if (rShotsToDeplete > 20.0)
					lstrcpy(szEval, "\tUNDERpowered");
				}
			}
		else
			lstrcpy(szEval, "");

		//	Print table

		if (bVerbose)
			{
			printf("%s\t%s\t%s\t(%d ticks; %.2f damage; %.2f regen/shot)%s\n",
					RomanNumeral(pWeapon->GetLevel()),
					pWeapon->GetNounPhrase().GetASCIIZPointer(),
					szBuffer,
					iFireDelay,
					rAverageDamage,
					rRegenPerShot,
					szEval);
			}
		else
			{
			printf("%s\t%s\t%s%s\n",
					RomanNumeral(pWeapon->GetLevel()),
					pWeapon->GetNounPhrase().GetASCIIZPointer(),
					szBuffer,
					szEval);
			}
		}
	}
Example #16
0
CWeaponFireDesc *CWeaponFireDesc::FindWeaponFireDescFromFullUNID (const CString &sUNID)

//	FindWeaponFireDesc
//
//	Finds the descriptor by name

	{
	char *pPos = sUNID.GetPointer();

	//	Get the UNID of the type

	DWORD dwUNID = (DWORD)strParseInt(pPos, 0, &pPos);
	if (dwUNID == 0)
		return NULL;

	//	Get the type

	CDesignType *pType = g_pUniverse->FindDesignType(dwUNID);
	if (pType == NULL)
		return NULL;

	//	If this is an item, then it must be a weapon

	if (pType->GetType() == designItemType)
		{
		CItemType *pItemType = CItemType::AsType(pType);
		ASSERT(pItemType);

		CDeviceClass *pDevice = pItemType->GetDeviceClass();
		if (pDevice == NULL)
			return NULL;

		CWeaponClass *pClass = pDevice->AsWeaponClass();
		if (pClass == NULL)
			return NULL;

		//	Get the ordinal

		ASSERT(*pPos == '/');
		pPos++;
		int iOrdinal = strParseInt(pPos, 0, &pPos);

		//	Get the weapon fire desc of the ordinal

		CWeaponFireDesc *pDesc = pClass->GetVariant(iOrdinal);
		if (pDesc == NULL)
			return NULL;

		//	Continue parsing

		return pDesc->FindWeaponFireDesc(CString(pPos));
		}

	//	If this is an effect, then get it from that

	else if (pType->GetType() == designEffectType)
		{
		CEffectCreator *pEffectType = CEffectCreator::AsType(pType);
		ASSERT(pEffectType);

		//	Expect /d

		ASSERT(*pPos == '/');
		pPos++;
		ASSERT(*pPos == 'd');
		pPos++;

		CWeaponFireDesc *pDesc = pEffectType->GetDamageDesc();
		if (pDesc == NULL)
			return NULL;

		//	Continue parsing

		return pDesc->FindWeaponFireDesc(CString(pPos));
		}

	//	Otherwise, we don't know

	else
		return NULL;
	}
Example #17
0
CWeaponFireDesc *CWeaponFireDesc::FindWeaponFireDesc (const CString &sUNID, char **retpPos)

//	FindWeaponFireDesc
//
//	Finds the weapon fire desc from a partial UNID

	{
	char *pPos = sUNID.GetASCIIZPointer();

	//	If we're done, then we want this descriptor

	if (*pPos == '\0')
		return this;

	//	If a slash, then we have another weapon fire desc

	else if (*pPos == '/')
		{
		pPos++;

		//	The enhanced section

		if (*pPos == 'e')
			{
			pPos++;
			if (m_pEnhanced)
				return m_pEnhanced->FindWeaponFireDesc(CString(pPos, -1, TRUE), retpPos);
			else
				return NULL;
			}

		//	A fragment

		else if (*pPos == 'f')
			{
			pPos++;

			int iIndex = strParseInt(pPos, 0, &pPos);

			SFragmentDesc *pNext = m_pFirstFragment;
			while (iIndex-- > 0 && pNext)
				pNext = pNext->pNext;

			if (pNext)
				return pNext->pDesc->FindWeaponFireDesc(CString(pPos, -1, TRUE), retpPos);
			else
				return NULL;
			}
		else
			return NULL;
		}

	//	Otherwise, we have an effect

	else if (*pPos == ':')
		{
		if (retpPos)
			*retpPos = pPos;

		return this;
		}
	else
		return NULL;
	}
Example #18
0
CString ResolveEntity (ParserCtx *pCtx, const CString &sName, bool *retbFound)

//	ResolveEntity
//
//	Resolves the entity from the parser table

	{
	*retbFound = true;
	CString sResult;

	//	Check to see if the name is one of the standard entities

	CString sNameLC = strToLower(sName);
	if (strEquals(sNameLC, ENTITY_AMP))
		return ENTITY_AMP_SUB;
	else if (strEquals(sNameLC, ENTITY_LT))
		return ENTITY_LT_SUB;
	else if (strEquals(sNameLC, ENTITY_GT))
		return ENTITY_GT_SUB;
	else if (strEquals(sNameLC, ENTITY_QUOT))
		return ENTITY_QUOT_SUB;
	else if (strEquals(sNameLC, ENTITY_APOS))
		return ENTITY_APOS_SUB;

	//	If the entity is a hex number, then this is a character

	char *pPos = sName.GetParsePointer();
	if (*pPos == '#')
		{
		pPos++;
		if (*pPos == 'x' || *pPos == 'X')
			{
			*pPos++;
			char chChar = (char)strParseIntOfBase(pPos, 16, 0x20, NULL, NULL);
			return CString(&chChar, 1);
			}
		else
			{
			char chChar = (char)strParseInt(pPos, 0x20);
			return CString(&chChar, 1);
			}
		}

	//	Otherwise, it is a general attribute

	bool bFound;
	CString sValue = pCtx->LookupEntity(sName, &bFound);
	if (bFound)
		{
		//	Parse the value to resolve embedded entities

		ParserCtx SubCtx(pCtx, sValue);

		ParseToken(&SubCtx, ParseEntityState);
		if (SubCtx.iToken == tkText)
			sResult = SubCtx.sToken;
		else
			{
			bFound = false;
			sResult = sName;
			}
		}

	if (retbFound)
		*retbFound = bFound;

	return sResult;
	}
Example #19
0
ALERROR CItemEnhancement::InitFromDesc (const CString &sDesc, CString *retsError)

//	InitFromDesc
//
//	Initializes from a string of the following forms:
//
//	{number}					Interpret as a mod code
//	+armor:{n}					Add	armor special damage, where n is an item level
//	+hpBonus:{n}				Add hp bonus.
//	+immunity:{s}				Immunity to special damage s.
//	+reflect:{s}				Reflects damage type s.
//	+regen						Regenerate
//	+resist:{s}:{n}				DamageAdj for type s set to n
//	+resistDamageClass:{s}:{n}	DamageAdj for type s (and its next-tier mate) set to n
//	+resistDamageTier:{s}:{n}	DamageAdj for type s (and its tier mate) set to n
//	+resistEnergy:{n}			DamageAdj for energy damage set to n
//	+resistMatter:{n}			DamageAdj for matter damage set to n
//	+shield:{n}					Add shield disrupt special damage, where n is an item level
//	+speed:{n}					Faster. n is new delay value as a percent of normal

{
    //	If the string is a number then we interpret it as a mod code.

    bool bFailed;
    DWORD dwCode = strToInt(sDesc, 0, &bFailed);
    if (!bFailed)
    {
        m_dwMods = dwCode;
        return NOERROR;
    }

    //	Parse the string

    char *pPos = sDesc.GetASCIIZPointer();

    //	Expect either "+" or "-" (for disadvantage)

    bool bDisadvantage;
    if (*pPos == '+')
        bDisadvantage = false;
    else if (*pPos == '-')
        bDisadvantage = true;
    else
    {
        if (retsError)
            *retsError = CONSTLIT("Invalid enhancement description: expected '+' or '-'.");
        return ERR_FAIL;
    }

    pPos++;

    //	Parse the enhancement name

    char *pStart = pPos;
    while (*pPos != ':' && *pPos != '\0')
        pPos++;

    CString sID(pStart, (int)(pPos - pStart));

    //	See if we have a value

    int iValue = 0;
    CString sValue;
    if (*pPos == ':')
    {
        pPos++;

        if (*pPos == '-' || *pPos == '+' || (*pPos >= '0' && *pPos <= '9'))
            iValue = strParseInt(pPos, 0, &pPos);
        else
        {
            char *pStart = pPos;
            while (*pPos != '\0' && *pPos != ':')
                pPos++;

            sValue = CString(pStart, (int)(pPos - pStart));
        }
    }

    //	See if we have a second value

    int iValue2 = 0;
    if (*pPos == ':')
    {
        pPos++;
        iValue2 = strParseInt(pPos, 0, &pPos);
    }

    //	See if this is an hpBonus

    if (strEquals(sID, CONSTLIT("hpBonus")))
    {
        if (bDisadvantage && iValue > 0)
            iValue = -iValue;

        if (iValue < -100)
        {
            if (retsError)
                *retsError = CONSTLIT("hpBonus penalty cannot exceed 100%.");
            return ERR_FAIL;
        }
        else if (iValue < 0)
            SetModCode(EncodeAX(etHPBonus | etDisadvantage, 0, -iValue));
        else if (iValue == 0)
            SetModCode(Encode12(etStrengthen));
        else if (iValue <= 1000)
            SetModCode(EncodeAX(etHPBonus, 0, iValue));
        else
        {
            if (retsError)
                *retsError = CONSTLIT("hpBonus cannot exceed 1000%.");
            return ERR_FAIL;
        }
    }

    //	Immunity

    else if (strEquals(sID, CONSTLIT("immunity")))
    {
        if (strEquals(sValue, CONSTLIT("ionEffects")))
            m_dwMods = Encode12(etImmunityIonEffects);
        else
        {
            SpecialDamageTypes iSpecial = DamageDesc::ConvertToSpecialDamageTypes(sValue);
            switch (iSpecial)
            {
            case specialRadiation:
            case specialBlinding:
            case specialEMP:
            case specialDeviceDamage:
            case specialDisintegration:
            case specialMomentum:
            case specialShieldDisrupt:
            case specialDeviceDisrupt:
            case specialShatter:
            {
                if (bDisadvantage)
                {
                    if (retsError)
                        *retsError = CONSTLIT("Disadvantage not supported.");
                    return ERR_FAIL;
                }

                SetModImmunity(iSpecial);
                break;
            }

            default:
            {
                if (retsError)
                    *retsError = strPatternSubst(CONSTLIT("Invalid immunity: %s"), sID);
                return ERR_FAIL;
            }
            }
        }
    }

    //	Reflect bonus

    else if (strEquals(sID, CONSTLIT("reflect")))
    {
        DamageTypes iDamageType = LoadDamageTypeFromXML(sValue);
        if (iDamageType == damageError)
        {
            if (retsError)
                *retsError = strPatternSubst(CONSTLIT("Invalid damage type: %s"), sValue);
            return ERR_FAIL;
        }

        SetModReflect(iDamageType);
    }

    //	Regen

    else if (strEquals(sID, CONSTLIT("regen")))
    {
        m_dwMods = Encode12(etRegenerate | (bDisadvantage ? etDisadvantage : 0));
    }

    //	Resist damage

    else if (strEquals(sID, CONSTLIT("resist")))
    {
        DamageTypes iDamageType = LoadDamageTypeFromXML(sValue);
        if (iDamageType == damageError)
        {
            if (retsError)
                *retsError = strPatternSubst(CONSTLIT("Invalid damage type: %s"), sValue);
            return ERR_FAIL;
        }

        SetModResistDamage(iDamageType, iValue2);
    }

    //	Resist damage

    else if (strEquals(sID, CONSTLIT("resistDamageClass")))
    {
        DamageTypes iDamageType = LoadDamageTypeFromXML(sValue);
        if (iDamageType == damageError)
        {
            if (retsError)
                *retsError = strPatternSubst(CONSTLIT("Invalid damage type: %s"), sValue);
            return ERR_FAIL;
        }

        SetModResistDamageClass(iDamageType, iValue2);
    }

    //	Resist damage tier

    else if (strEquals(sID, CONSTLIT("resistDamageTier")))
    {
        DamageTypes iDamageType = LoadDamageTypeFromXML(sValue);
        if (iDamageType == damageError)
        {
            if (retsError)
                *retsError = strPatternSubst(CONSTLIT("Invalid damage type: %s"), sValue);
            return ERR_FAIL;
        }

        SetModResistDamageTier(iDamageType, iValue2);
    }

    //	Resist energy/matter

    else if (strEquals(sID, CONSTLIT("resistEnergy")))
        SetModResistEnergy(iValue);
    else if (strEquals(sID, CONSTLIT("resistMatter")))
        SetModResistMatter(iValue);

    //	Speed bonus

    else if (strEquals(sID, CONSTLIT("speed")))
    {
        if (iValue <= 0)
        {
            if (retsError)
                *retsError = strPatternSubst(CONSTLIT("Invalid speed value: %s."), iValue);
            return ERR_FAIL;
        }
        else
            //	LATER: Support min and max delay limits
            SetModSpeed(iValue);
    }

    //	Otherwise, see if this is a special damage

    else
    {
        SpecialDamageTypes iSpecial = DamageDesc::ConvertToSpecialDamageTypes(sID);
        switch (iSpecial)
        {
        case specialArmor:
        case specialShieldDisrupt:
        {
            if (bDisadvantage)
            {
                if (retsError)
                    *retsError = CONSTLIT("Disadvantage not supported.");
                return ERR_FAIL;
            }

            if (iValue < 1 || iValue > MAX_ITEM_LEVEL)
            {
                if (retsError)
                    *retsError = strPatternSubst(CONSTLIT("Invalid %s damage level: %d"), sID, iValue);
                return ERR_FAIL;
            }

            SetModSpecialDamage(iSpecial, iValue);
            break;
        }

        default:
        {
            if (retsError)
                *retsError = strPatternSubst(CONSTLIT("Invalid enhancement name: %s"), sID);
            return ERR_FAIL;
        }
        }
    }

    //	Done

    return NOERROR;
}
Example #20
0
bool CTimeSpan::Parse (const CString &sValue, CTimeSpan *retValue)

//	Parse
//
//	Parses a string of the form:
//
//	D:0xddd M:0xmmm
//		(where ddd = days; mmm = milliseconds)

	{
	char *pPos = sValue.GetASCIIZPointer();

	//	If the first character is a 'D' then we assume an encoded TimeSpan

	if (*pPos == 'D')
		{
		pPos++;
		if (*pPos++ != ':')
			return false;

		bool bFailed;
		DWORD dwDays = strParseInt(pPos, 0, &pPos, &bFailed);
		if (bFailed)
			return false;

		if (*pPos++ != ' ')
			return false;

		if (*pPos++ != 'M')
			return false;

		if (*pPos++ != ':')
			return false;

		DWORD dwMilliseconds = strParseInt(pPos, 0, &pPos, &bFailed);
		if (bFailed)
			return false;

		*retValue = CTimeSpan(dwDays, dwMilliseconds);
		return true;
		}

	//	Otherwise we try to parse a plain English time span

	else
		{
		DWORD dwTotalDays = 0;
		DWORD dwTotalMilliseconds = 0;

		//	Parse components

		DWORD dwDays;
		DWORD dwMilliseconds;
		if (!ParsePartial(pPos, &dwDays, &dwMilliseconds, &pPos))
			return false;

		dwTotalDays += dwDays;
		dwTotalMilliseconds += dwMilliseconds;

		//	Look for 'and'

		while (*pPos == ' ')
			pPos++;

		if (*pPos++ == 'a')
			{
			if (*pPos++ != 'n')
				return false;
			if (*pPos++ != 'd')
				return false;

			if (!ParsePartial(pPos, &dwDays, &dwMilliseconds, &pPos))
				return false;

			dwTotalDays += dwDays;
			dwTotalMilliseconds += dwMilliseconds;
			}

		//	Done

		*retValue = CTimeSpan(dwTotalDays, dwTotalMilliseconds);
		return true;
		}
	}