Exemplo n.º 1
0
void CListWrapper::PaintImageAtCursor (CG16bitImage &Dest, int x, int y)

//	PaintImageAtCursor
//
//	Paints the image for the current element

	{
	if (!IsCursorValid())
		return;

	ICCItem *pItem = m_pList->GetElement(m_iCursor);
	if (pItem->GetCount() <= ICON_INDEX)
		return;

	ICCItem *pIcon = pItem->GetElement(ICON_INDEX);
	if (pIcon->GetCount() < IMAGE_ELEMENTS)
		return;

	CG16bitImage *pImage = g_pUniverse->GetLibraryBitmap(pIcon->GetElement(IMAGE_UNID_INDEX)->GetIntegerValue());
	if (pImage == NULL)
		return;

	Dest.ColorTransBlt(pIcon->GetElement(IMAGE_X_INDEX)->GetIntegerValue(),
			pIcon->GetElement(IMAGE_Y_INDEX)->GetIntegerValue(),
			ICON_WIDTH,
			ICON_HEIGHT,
			255,
			*pImage,
			x,
			y);
	}
Exemplo n.º 2
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));
	}
Exemplo n.º 3
0
ICCItem *fnAtmCreate (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnAtmCreate
//
//	Creates a new atom table
//
//	(atmAtomTable ((atom1 entry1) (atom2 entry2) ... (atomn entryn))) -> atmtable

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pArgs;
	ICCItem *pAtomTable;
	ICCItem *pList;
	int i;

	//	Evaluate the argument

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

	//	Create the table

	pAtomTable = pCC->CreateAtomTable();
	if (pAtomTable->IsError())
		return pAtomTable;

	//	Add each entry

	pList = pArgs->Head(pCC);
	for (i = 0; i < pList->GetCount(); i++)
		{
		ICCItem *pPair = pList->GetElement(i);
		ICCItem *pResult;

		//	Make sure we have two elements

		if (pPair->GetCount() != 2)
			{
			pAtomTable->Discard(pCC);
			return pCC->CreateError(CONSTLIT("Invalid format for atom table entry:"), pPair);
			}

		//	Get the atom and the entry

		pResult = pAtomTable->AddEntry(pCC, pPair->GetElement(0), pPair->GetElement(1));
		if (pResult->IsError())
			{
			pAtomTable->Discard(pCC);
			return pResult;
			}

		pResult->Discard(pCC);
		}

	//	Done

	pArgs->Discard(pCC);
	return pAtomTable;
	}
Exemplo n.º 4
0
ICCItem *fnRandom (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnRandom
//
//	(random from to) -> number
//	(random list) -> random item in list

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

	//	Evaluate the arguments and validate them

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

	//	Do stuff based on parameters

	if (pArgs->GetCount() == 2)
		{
		int iOp1 = pArgs->GetElement(0)->GetIntegerValue();
		int iOp2 = pArgs->GetElement(1)->GetIntegerValue();
		pArgs->Discard(pCC);

		pResult = pCC->CreateInteger(mathRandom(iOp1, iOp2));
		}
	else if (pArgs->GetCount() == 1)
		{
		ICCItem *pList = pArgs->GetElement(0);

		if (pList->IsNil())
			pResult = pCC->CreateNil();
		else if (pList->GetCount() == 0)
			pResult = pCC->CreateNil();
		else
			pResult = pList->GetElement(mathRandom(0, pList->GetCount()-1))->Reference();

		pArgs->Discard(pCC);
		}
	else
		{
		pResult = pCC->CreateNil();
		pArgs->Discard(pCC);
		}

	//	Done

	return pResult;
	}
Exemplo n.º 5
0
ICCItem *fnStrCapitalize (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnStrCapitalize
//
//	Capitalizes the string
//
//	(strCapitalize string) -> string

	{
	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 sString = pArgs->GetElement(0)->GetStringValue();
	pArgs->Discard(pCC);

	//	Done

	sString.Capitalize(CString::capFirstLetter);
	return pCC->CreateString(sString);
	}
Exemplo n.º 6
0
ICCItem *fnAppend (CEvalContext *pCtx, ICCItem *pArgs, DWORD dwData)

//	fnAppend
//
//	Appends two or more elements together

	{
	int i, j;
	CCodeChain *pCC = pCtx->pCC;

	//	Create a new list to store the result in

	ICCItem *pResult = pCC->CreateLinkedList();
	if (pResult->IsError())
		return pResult;

	CCLinkedList *pList = (CCLinkedList *)pResult;

	//	Loop over all arguments and add to result list

	for (i = 0; i < pArgs->GetCount(); i++)
		{
		ICCItem *pItem = pArgs->GetElement(i);

		for (j = 0; j < pItem->GetCount(); j++)
			pList->Append(pCC, pItem->GetElement(j), NULL);
		}

	//	Done

	return pResult;
	}
Exemplo n.º 7
0
ICCItem *fnCat (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnCat
//
//	Concatenates the given strings
//
//	(cat string1 string2 ... stringn)

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pArgs;
	ICCItem *pResult;
	CString sResult;
	int i;

	//	Evaluate the arguments and validate them

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

	//	Append each of the items

	for (i = 0; i < pArgs->GetCount(); i++)
		sResult.Append(pArgs->GetElement(i)->GetStringValue());

	pResult = pCC->CreateString(sResult);

	//	Done

	pArgs->Discard(pCC);
	return pResult;
	}
Exemplo n.º 8
0
ICCItem *fnEval (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnEval
//
//	Evaluates an expression
//
//	(eval exp)

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

	//	Evaluate the arguments and validate them

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

	pResult = pCC->Eval(pCtx, pArgs->GetElement(0));

	//	Done

	pArgs->Discard(pCC);
	return pResult;
	}
Exemplo n.º 9
0
ICCItem *fnShuffle (CEvalContext *pCtx, ICCItem *pArgs, DWORD dwData)

//	fnShuffle
//
//	Shuffles a list randomly

	{
	int i;
	CCodeChain *pCC = pCtx->pCC;

	if (pArgs->GetElement(0)->IsNil())
		return pCC->CreateNil();

	//	Create a destination list

	ICCItem *pResult = pCC->CreateLinkedList();
	if (pResult->IsError())
		return pResult;

	CCLinkedList *pList = (CCLinkedList *)pResult;

	//	Copy the list

	ICCItem *pSource = pArgs->GetElement(0);
	for (i = 0; i < pSource->GetCount(); i++)
		pList->Append(pCC, pSource->GetElement(i), NULL);

	//	Shuffle the new list

	pList->Shuffle(pCC);

	//	Done

	return pResult;
	}
Exemplo n.º 10
0
ICCItem *fnVector (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnVector
//
//	Vector functions
//
//	(vecSetElement vector index element)

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pArgs;
	CCVector *pVector;
	BOOL bOk;

	//	Evaluate the arguments

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

	//	Get the vector

	pVector = dynamic_cast<CCVector *>(pArgs->GetElement(0));
	if (pVector == NULL)
		{
		ICCItem *pError = pCC->CreateError(CONSTLIT("Vector expected:"), pArgs->GetElement(0));;
		pArgs->Discard(pCC);
		return pError;
		}

	//	Set the element

	bOk = pVector->SetElement(pArgs->GetElement(1)->GetIntegerValue(),
			pArgs->GetElement(2)->GetIntegerValue());

	if (!bOk)
		{
		pArgs->Discard(pCC);
		return pCC->CreateError(CONSTLIT("Unable to set vector element"), NULL);
		}

	//	Done

	pArgs->Discard(pCC);
	return pCC->CreateTrue();
	}
Exemplo n.º 11
0
ICCItem *fnItem (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnItem
//
//	Returns nth entry in a list (0-based)
//
//	(item list nth) -> item

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pArgs;
	ICCItem *pResult;
	ICCItem *pList;
	int iIndex;

	//	Evaluate the arguments and validate them

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

	//	The first argument is the list

	pList = pArgs->Head(pCC);
	iIndex = pArgs->GetElement(1)->GetIntegerValue();
	pResult = pList->GetElement(iIndex);
	if (pResult == NULL)
		pResult = pCC->CreateNil();
	else
		pResult = pResult->Reference();

	//	Done

	pArgs->Discard(pCC);
	return pResult;
	}
Exemplo n.º 12
0
CString CListWrapper::GetDescAtCursor (void)

//	GetDescAtCursor
//
//	Returns the description of the list element

	{
	if (IsCursorValid())
		{
		ICCItem *pItem = m_pList->GetElement(m_iCursor);
		if (DESC_INDEX < pItem->GetCount())
			return pItem->GetElement(DESC_INDEX)->GetStringValue();
		}

	return NULL_STR;
	}
Exemplo n.º 13
0
CString CListWrapper::GetTitleAtCursor (void)

//	GetTitleAtCursor
//
//	Returns the title of the list element

	{
	if (IsCursorValid())
		{
		ICCItem *pItem = m_pList->GetElement(m_iCursor);
		if (TITLE_INDEX < pItem->GetCount())
			return pItem->GetElement(TITLE_INDEX)->GetStringValue();
		}

	return NULL_STR;
	}
Exemplo n.º 14
0
ICCItem *fnFind (CEvalContext *pCtx, ICCItem *pArgs, DWORD dwData)

//	fnFind
//
//	Finds a target in a source

	{
	int i;
	CCodeChain *pCC = pCtx->pCC;

	//	Get the source and target

	ICCItem *pSource = pArgs->GetElement(0);
	ICCItem *pTarget = pArgs->GetElement(1);

	//	If this is a list, then look for the target in the list and
	//	return the item position in the list

	int iPos;
	if (pSource->IsList())
		{
		iPos = -1;
		for (i = 0; i < pSource->GetCount(); i++)
			{
			ICCItem *pItem = pSource->GetElement(i);
			if (HelperCompareItems(pItem, pTarget) == 0)
				{
				iPos = i;
				break;
				}
			}
		}

	//	Otherwise, look for the target string in the source string

	else
		{
		iPos = strFind(pSource->GetStringValue(), pTarget->GetStringValue());
		}

	//	Done

	if (iPos == -1)
		return pCC->CreateNil();
	else
		return pCC->CreateInteger(iPos);
	}
Exemplo n.º 15
0
ICCItem *fnSeededRandom (CEvalContext *pCtx, ICCItem *pArgs, DWORD dwData)

//	fnSeededRandom
//
//	(seededRandom seed from to) -> number
//	(seededRandom seed list) -> random item in list

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

	int iSeed = pArgs->GetElement(0)->GetIntegerValue();

	//	Do stuff based on parameters

	if (pArgs->GetCount() == 3)
		{
		int iOp1 = pArgs->GetElement(1)->GetIntegerValue();
		int iOp2 = pArgs->GetElement(2)->GetIntegerValue();

		pResult = pCC->CreateInteger(mathSeededRandom(iSeed, iOp1, iOp2));
		}
	else if (pArgs->GetCount() == 2)
		{
		ICCItem *pList = pArgs->GetElement(1);

		if (pList->IsNil())
			pResult = pCC->CreateNil();
		else if (pList->GetCount() == 0)
			pResult = pCC->CreateNil();
		else
			pResult = pList->GetElement(mathSeededRandom(iSeed, 0, pList->GetCount()-1))->Reference();
		}
	else
		pResult = pCC->CreateNil();

	//	Done

	return pResult;
	}
Exemplo n.º 16
0
ICCItem *fnFilter (CEvalContext *pCtx, ICCItem *pArgs, DWORD dwData)

//	fnFilter
//
//	Filters a list based on a boolean expression.
//
//	(filter list var exp) -> list

	{
	int i;
	CCodeChain *pCC = pCtx->pCC;

	if (pArgs->GetElement(0)->IsNil())
		return pCC->CreateNil();

	//	Args

	ICCItem *pSource = pArgs->GetElement(0);
	ICCItem *pVar = pArgs->GetElement(1);
	ICCItem *pBody = pArgs->GetElement(2);

	//	Create a destination list

	ICCItem *pResult = pCC->CreateLinkedList();
	if (pResult->IsError())
		return pResult;

	CCLinkedList *pList = (CCLinkedList *)pResult;

	//	Setup the locals. We start by creating a local symbol table

	ICCItem *pLocalSymbols = pCC->CreateSymbolTable();
	if (pLocalSymbols->IsError())
		{
		pResult->Discard(pCC);
		return pLocalSymbols;
		}

	//	Associate the enumaration variable

	ICCItem *pError = pLocalSymbols->AddEntry(pCC, pVar, pCC->CreateNil());
	if (pError->IsError())
		{
		pLocalSymbols->Discard(pCC);
		pResult->Discard(pCC);
		return pError;
		}

	pError->Discard(pCC);

	//	Setup the context

	if (pCtx->pLocalSymbols)
		pLocalSymbols->SetParent(pCtx->pLocalSymbols);
	else
		pLocalSymbols->SetParent(pCtx->pLexicalSymbols);
	ICCItem *pOldSymbols = pCtx->pLocalSymbols;
	pCtx->pLocalSymbols = pLocalSymbols;

	//	Get the offset of the variable so we don't have to
	//	search for it all the time

	int iVarOffset = pLocalSymbols->FindOffset(pCC, pVar);

	//	Loop over all elements of the list

	for (i = 0; i < pSource->GetCount(); i++)
		{
		ICCItem *pItem = pSource->GetElement(i);

		//	Set the element

		pLocalSymbols->AddByOffset(pCC, iVarOffset, pItem);

		//	Eval

		ICCItem *pSelect = pCC->Eval(pCtx, pBody);
		if (pSelect->IsError())
			{
			pResult->Discard(pCC);
			pResult = pSelect;
			break;
			}

		//	If the evaluation is not Nil, then we include the
		//	item in the result

		if (!pSelect->IsNil())
			pList->Append(pCC, pItem, NULL);

		pSelect->Discard(pCC);
		}

	//	Clean up

	pCtx->pLocalSymbols = pOldSymbols;
	pLocalSymbols->Discard(pCC);

	//	Done

	if (pResult->GetCount() > 0)
		return pResult;
	else
		{
		pResult->Discard(pCC);
		return pCC->CreateNil();
		}
	}
Exemplo n.º 17
0
void CShieldClass::FireOnShieldDamage (CItemCtx &ItemCtx, SDamageCtx &Ctx)

//	FireOnShieldDamage
//
//	Fire OnShieldDamage

	{
	SEventHandlerDesc Event;
	if (FindEventHandlerShieldClass(evtOnShieldDamage, &Event))
		{
		//	Setup arguments

		CCodeChainCtx CCCtx;
		CCCtx.SaveAndDefineSourceVar(ItemCtx.GetSource());
		CCCtx.SaveAndDefineItemVar(ItemCtx);

		CCCtx.DefineInteger(CONSTLIT("aArmorSeg"), Ctx.iSectHit);
		CCCtx.DefineSpaceObject(CONSTLIT("aCause"), Ctx.pCause);
		CCCtx.DefineSpaceObject(CONSTLIT("aAttacker"), Ctx.Attacker.GetObj());
		CCCtx.DefineSpaceObject(CONSTLIT("aOrderGiver"), (Ctx.Attacker.GetObj() ? Ctx.Attacker.GetObj()->GetOrderGiver(Ctx.Attacker.GetCause()) : NULL));
		CCCtx.DefineVector(CONSTLIT("aHitPos"), Ctx.vHitPos);
		CCCtx.DefineInteger(CONSTLIT("aHitDir"), Ctx.iDirection);
		CCCtx.DefineInteger(CONSTLIT("aDamageHP"), Ctx.iDamage);
		CCCtx.DefineString(CONSTLIT("aDamageType"), GetDamageShortName(Ctx.Damage.GetDamageType()));
		CCCtx.DefineItemType(CONSTLIT("aWeaponType"), Ctx.pDesc->GetWeaponType());

		CCCtx.DefineInteger(CONSTLIT("aShieldHP"), Ctx.iHPLeft);
		CCCtx.DefineInteger(CONSTLIT("aShieldDamageHP"), Ctx.iShieldDamage);
		CCCtx.DefineInteger(CONSTLIT("aArmorDamageHP"), Ctx.iDamage - Ctx.iAbsorb);
		if (Ctx.bReflect)
			{
			CCCtx.DefineString(CONSTLIT("aShieldReflect"), STR_SHIELD_REFLECT);
			CCCtx.DefineInteger(CONSTLIT("aOriginalShieldDamageHP"), Ctx.iOriginalShieldDamage);
			CCCtx.DefineInteger(CONSTLIT("aOriginalArmorDamageHP"), Ctx.iDamage - Ctx.iOriginalAbsorb);
			}
		else
			{
			CCCtx.DefineNil(CONSTLIT("aShieldReflect"));
			CCCtx.DefineInteger(CONSTLIT("aOriginalShieldDamageHP"), Ctx.iShieldDamage);
			CCCtx.DefineInteger(CONSTLIT("aOriginalArmorDamageHP"), Ctx.iDamage - Ctx.iAbsorb);
			}

		ICCItem *pResult = CCCtx.Run(Event);

		//	If we return Nil, then nothing

		if (pResult->IsNil())
			NULL;

		//	If an error, report it

		else if (pResult->IsError())
			ItemCtx.GetSource()->ReportEventError(ON_SHIELD_DAMAGE_EVENT, pResult);

		//	If we return a list, then modify variables

		else if (pResult->IsList())
			{
			//	A single value means we modified the damage to armor

			if (pResult->GetCount() == 1)
				{
				if (strEquals(pResult->GetElement(0)->GetStringValue(), STR_SHIELD_REFLECT))
					{
					Ctx.bReflect = true;
					Ctx.iAbsorb = Ctx.iDamage;
					Ctx.iShieldDamage = 0;
					}
				else
					{
					Ctx.iShieldDamage = Max(0, Min(pResult->GetElement(0)->GetIntegerValue(), Ctx.iHPLeft));
					if (Ctx.bReflect)
						{
						Ctx.bReflect = false;
						Ctx.iAbsorb = Ctx.iOriginalAbsorb;
						}
					}
				}

			//	Two values mean we modified both damage to armor and shield damage

			else if (pResult->GetCount() == 2)
				{
				Ctx.bReflect = false;
				Ctx.iShieldDamage = Max(0, Min(pResult->GetElement(0)->GetIntegerValue(), Ctx.iHPLeft));
				Ctx.iAbsorb = Max(0, Ctx.iDamage - Max(0, pResult->GetElement(1)->GetIntegerValue()));
				}

			//	Otherwise, we deal with reflection

			else
				{
				Ctx.bReflect = strEquals(pResult->GetElement(0)->GetStringValue(), STR_SHIELD_REFLECT);
				Ctx.iShieldDamage = Max(0, Min(pResult->GetElement(1)->GetIntegerValue(), Ctx.iHPLeft));
				Ctx.iAbsorb = Max(0, Ctx.iDamage - Max(0, pResult->GetElement(2)->GetIntegerValue()));
				}
			}

		CCCtx.Discard(pResult);
		}
	}
Exemplo n.º 18
0
ICCItem *fnApply (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnApply
//
//	Applies the given parameter list to the lambda expression
//
//	(apply exp arg1 arg2 ... argn list)

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pArgs;
	ICCItem *pResult;
	ICCItem *pFunction;
	ICCItem *pLast;
	CCLinkedList *pList;
	int i;

	//	Evaluate the arguments and validate them

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

	//	We better have at least two arguments

	if (pArgs->GetCount() < 2)
		{
		pArgs->Discard(pCC);
		return pCC->CreateError(CONSTLIT("apply needs a function and a list of arguments."), NULL);
		}

	//	The last argument better be a list

	pLast = pArgs->GetElement(pArgs->GetCount() - 1);
	if (!pLast->IsList())
		{
		pArgs->Discard(pCC);
		return pCC->CreateError(CONSTLIT("Last argument for apply must be a list."), NULL);
		}

	//	The first argument is the function

	pFunction = pArgs->Head(pCC);

	//	Create a new list to store the arguments in

	pResult = pCC->CreateLinkedList();
	if (pResult->IsError())
		{
		pArgs->Discard(pCC);
		return pResult;
		}

	pList = (CCLinkedList *)pResult;

	//	Add each of the arguments except the last

	for (i = 1; i < pArgs->GetCount() - 1; i++)
		{
		pList->Append(pCC, pArgs->GetElement(i), &pResult);
		if (pResult->IsError())
			{
			pList->Discard(pCC);
			pArgs->Discard(pCC);
			return pResult;
			}

		pResult->Discard(pCC);
		}

	//	Add each of the elements of the last list

	for (i = 0; i < pLast->GetCount(); i++)
		{
		pList->Append(pCC, pLast->GetElement(i), &pResult);
		if (pResult->IsError())
			{
			pList->Discard(pCC);
			pArgs->Discard(pCC);
			return pResult;
			}

		pResult->Discard(pCC);
		}

	//	Set the literal flag to indicate that the arguments should
	//	not be evaluated.

	pList->SetQuoted();

	//	Execute the function

	if (pFunction->IsFunction())
		pResult = pFunction->Execute(pCtx, pList);
	else
		pResult = pFunction->Reference();

	pList->Discard(pCC);

	//	Done

	pArgs->Discard(pCC);
	return pResult;
	}
Exemplo n.º 19
0
ICCItem *fnEquality (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnEquality
//
//	Equality and inequality
//
//	(eq exp1 exp2 ... expn)
//	(> exp1 exp2 ... expn)
//	(>= exp1 exp2 ... expn)
//	(< exp1 exp2 ... expn)
//	(<= exp1 exp2 ... expn)

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pResult;
	ICCItem *pExp;
	ICCItem *pPrev = NULL;
	ICCItem *pArgs;
	int i;

	//	Evaluate the arguments and validate them

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

	//	Loop over all arguments

	for (i = 0; i < pArgs->GetCount(); i++)
		{
		pExp = pArgs->GetElement(i);
		if (pExp->IsError())
			{
			pExp->Reference();
			pArgs->Discard(pCC);
			return pExp;
			}

		if (pPrev)
			{
			int iResult = HelperCompareItems(pPrev, pExp);
			BOOL bOk;

			switch (dwData)
				{
				case FN_EQUALITY_EQ:
					{
					bOk = (iResult == 0);
					break;
					}

				case FN_EQUALITY_LESSER:
					{
					bOk = (iResult < 0);
					break;
					}

				case FN_EQUALITY_LESSER_EQ:
					{
					bOk = (iResult <= 0);
					break;
					}

				case FN_EQUALITY_GREATER:
					{
					bOk = (iResult > 0);
					break;
					}

				case FN_EQUALITY_GREATER_EQ:
					{
					bOk = (iResult >= 0);
					break;
					}

				default:
					ASSERT(FALSE);
				}

			//	If we don't have a match, return

			if (!bOk)
				{
				pArgs->Discard(pCC);
				return pCC->CreateNil();
				}
			}

		//	Remember the previous element so that we can compare

		pPrev = pExp;
		}

	//	If we get here, then all items are ok

	pArgs->Discard(pCC);
	pResult = pCC->CreateTrue();

	//	Done

	return pResult;
	}
Exemplo n.º 20
0
ICCItem *fnEnum (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnEnum
//
//	Enumerates the elements of a list
//
//	(enum list item-var exp)
//	(enumwhile list condition item-var exp)

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pArgs;
	ICCItem *pResult;
	ICCItem *pVar;
	ICCItem *pBody;
	ICCItem *pList;
	ICCItem *pCondition;
	ICCItem *pLocalSymbols;
	ICCItem *pOldSymbols;
	ICCItem *pError;
	int i, iVarOffset;

	//	Evaluate the arguments and validate them

	if (dwData == FN_ENUM_WHILE)
		{
		pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("vuqu"));
		if (pArgs->IsError())
			return pArgs;

		pList = pArgs->GetElement(0);
		pCondition = pArgs->GetElement(1);
		pVar = pArgs->GetElement(2);
		pBody = pArgs->GetElement(3);
		}
	else
		{
		pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("vqu"));
		if (pArgs->IsError())
			return pArgs;

		pList = pArgs->GetElement(0);
		pCondition = NULL;
		pVar = pArgs->GetElement(1);
		pBody = pArgs->GetElement(2);
		}

	//	Setup the locals. We start by creating a local symbol table

	pLocalSymbols = pCC->CreateSymbolTable();
	if (pLocalSymbols->IsError())
		{
		pArgs->Discard(pCC);
		return pLocalSymbols;
		}

	//	Associate the enumaration variable

	pError = pLocalSymbols->AddEntry(pCC, pVar, pCC->CreateNil());
	if (pError->IsError())
		{
		pArgs->Discard(pCC);
		return pError;
		}

	pError->Discard(pCC);

	//	Setup the context

	if (pCtx->pLocalSymbols)
		pLocalSymbols->SetParent(pCtx->pLocalSymbols);
	else
		pLocalSymbols->SetParent(pCtx->pLexicalSymbols);
	pOldSymbols = pCtx->pLocalSymbols;
	pCtx->pLocalSymbols = pLocalSymbols;

	//	Start with a default result

	pResult = pCC->CreateNil();

	//	Get the offset of the variable so we don't have to
	//	search for it all the time

	iVarOffset = pLocalSymbols->FindOffset(pCC, pVar);

	//	Loop over all elements of the list

	for (i = 0; i < pList->GetCount(); i++)
		{
		//	Check the condition

		if (pCondition)
			{
			ICCItem *pEval;

			//	Evaluate the condition

			pEval = pCC->Eval(pCtx, pCondition);
			if (pEval->IsError())
				{
				pResult->Discard(pCC);
				pResult = pEval;
				break;
				}

			//	If the condition is Nil, then we're done

			if (pEval->IsNil())
				{
				pEval->Discard(pCC);
				break;
				}
			}

		ICCItem *pItem = pList->GetElement(i);

		//	Clean up the previous result

		pResult->Discard(pCC);

		//	Set the element

		pLocalSymbols->AddByOffset(pCC, iVarOffset, pItem);

		//	Eval

		pResult = pCC->Eval(pCtx, pBody);
		if (pResult->IsError())
			break;
		}

	//	Clean up

	pCtx->pLocalSymbols = pOldSymbols;
	pLocalSymbols->Discard(pCC);

	//	Done

	pArgs->Discard(pCC);
	return pResult;
	}
Exemplo n.º 21
0
bool CWeaponFireDesc::FireOnDamageShields (SDamageCtx &Ctx, int iDevice)

//	FireOnDamageShields
//
//	Fire OnDamageShields event. Returns TRUE if we should skip further shields damage

	{
	SEventHandlerDesc Event;
	if (FindEventHandler(evtOnDamageShields, &Event))
		{
		//	Setup arguments

		CCodeChainCtx CCCtx;

		CItemListManipulator ItemList(Ctx.pObj->GetItemList());
		CShip *pShip = Ctx.pObj->AsShip();
		if (pShip)
			pShip->SetCursorAtDevice(ItemList, iDevice);

		CCCtx.SaveAndDefineSourceVar(Ctx.pObj);
		CCCtx.DefineInteger(CONSTLIT("aArmorSeg"), Ctx.iSectHit);
		CCCtx.DefineInteger(CONSTLIT("aDevice"), iDevice);
		CCCtx.DefineItem(CONSTLIT("aDeviceItem"), ItemList.GetItemAtCursor());
		CCCtx.DefineSpaceObject(CONSTLIT("aCause"), Ctx.pCause);
		CCCtx.DefineSpaceObject(CONSTLIT("aAttacker"), Ctx.Attacker.GetObj());
		CCCtx.DefineSpaceObject(CONSTLIT("aOrderGiver"), (Ctx.Attacker.GetObj() ? Ctx.Attacker.GetObj()->GetOrderGiver(Ctx.Attacker.GetCause()) : NULL));
		CCCtx.DefineVector(CONSTLIT("aHitPos"), Ctx.vHitPos);
		CCCtx.DefineInteger(CONSTLIT("aHitDir"), Ctx.iDirection);
		CCCtx.DefineInteger(CONSTLIT("aDamageHP"), Ctx.iDamage);
		CCCtx.DefineString(CONSTLIT("aDamageType"), GetDamageShortName(Ctx.Damage.GetDamageType()));
		CCCtx.DefineItemType(CONSTLIT("aWeaponType"), Ctx.pDesc->GetWeaponType());

		CCCtx.DefineInteger(CONSTLIT("aShieldHP"), Ctx.iHPLeft);
		CCCtx.DefineInteger(CONSTLIT("aShieldDamageHP"), Ctx.iShieldDamage);
		CCCtx.DefineInteger(CONSTLIT("aArmorDamageHP"), Ctx.iDamage - Ctx.iAbsorb);
		if (Ctx.bReflect)
			{
			CCCtx.DefineString(CONSTLIT("aShieldReflect"), STR_SHIELD_REFLECT);
			CCCtx.DefineInteger(CONSTLIT("aOriginalShieldDamageHP"), Ctx.iOriginalShieldDamage);
			CCCtx.DefineInteger(CONSTLIT("aOriginalArmorDamageHP"), Ctx.iDamage - Ctx.iOriginalAbsorb);
			}
		else
			{
			CCCtx.DefineNil(CONSTLIT("aShieldReflect"));
			CCCtx.DefineInteger(CONSTLIT("aOriginalShieldDamageHP"), Ctx.iShieldDamage);
			CCCtx.DefineInteger(CONSTLIT("aOriginalArmorDamageHP"), Ctx.iDamage - Ctx.iAbsorb);
			}

		ICCItem *pResult = CCCtx.Run(Event);

		//	If we return Nil, then we continue processing

		bool bResult;
		if (pResult->IsNil())
			bResult = false;

		//	If this is an integer, we pass damage to armor

		else if (pResult->IsInteger())
			{
			Ctx.iDamage = pResult->GetIntegerValue();
			bResult = true;
			}

		//	If we return a list, then modify variables

		else if (pResult->IsList())
			{
			//	A single value means we modified the damage to armor

			if (pResult->GetCount() == 1)
				{
				if (strEquals(pResult->GetElement(0)->GetStringValue(), STR_SHIELD_REFLECT))
					{
					Ctx.bReflect = true;
					Ctx.iAbsorb = Ctx.iDamage;
					Ctx.iShieldDamage = 0;
					}
				else
					{
					Ctx.iShieldDamage = Max(0, Min(pResult->GetElement(0)->GetIntegerValue(), Ctx.iHPLeft));
					if (Ctx.bReflect)
						{
						Ctx.bReflect = false;
						Ctx.iAbsorb = Ctx.iOriginalAbsorb;
						}
					}
				}

			//	Two values mean we modified both damage to armor and shield damage

			else if (pResult->GetCount() == 2)
				{
				Ctx.bReflect = false;
				Ctx.iShieldDamage = Max(0, Min(pResult->GetElement(0)->GetIntegerValue(), Ctx.iHPLeft));
				Ctx.iAbsorb = Max(0, Ctx.iDamage - Max(0, pResult->GetElement(1)->GetIntegerValue()));
				}

			//	Otherwise, we deal with reflection

			else
				{
				Ctx.bReflect = strEquals(pResult->GetElement(0)->GetStringValue(), STR_SHIELD_REFLECT);
				Ctx.iShieldDamage = Max(0, Min(pResult->GetElement(1)->GetIntegerValue(), Ctx.iHPLeft));
				Ctx.iAbsorb = Max(0, Ctx.iDamage - Max(0, pResult->GetElement(2)->GetIntegerValue()));
				}

			//	Proceed with processing

			bResult = false;
			}

		//	If this is the string "reflect" then we reflect

		else if (strEquals(pResult->GetStringValue(), STR_SHIELD_REFLECT))
			{
			Ctx.bReflect = true;
			Ctx.iAbsorb = Ctx.iDamage;
			Ctx.iShieldDamage = 0;
			bResult = false;
			}

		//	Otherwise, error

		else
			{
			Ctx.pObj->ReportEventError(ON_DAMAGE_OVERLAY_EVENT, pResult);
			bResult = true;
			}

		CCCtx.Discard(pResult);

		return bResult;
		}
	else
		return false;
	}
Exemplo n.º 22
0
ICCItem *fnBlock (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnBlock
//
//	Evaluates a list of expressions
//
//	(block (locals ...) exp1 exp2 ... expn)
//	(errblock (error locals ...) exp1 exp2 ... expn onerror)

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pResult;
	ICCItem *pLocals;
	ICCItem *pExp;
	ICCItem *pLocalSymbols;
	ICCItem *pVar;
	ICCItem *pOldSymbols;
	int i;

	//	The first argument must be a list of locals

	pLocals = pArguments->Head(pCC);
	if (pLocals == NULL || !pLocals->IsList())
		return pCC->CreateError(CONSTLIT("Locals list expected:"), pLocals);

	//	If this is an error block then we must have at least one local

	if (dwData == FN_BLOCK_ERRBLOCK && pLocals->GetCount() == 0)
		return pCC->CreateError(CONSTLIT("errblock must have an 'error' local variable"), NULL);

	//	Now loop over the remaining arguments, evaluating each in turn

	pExp = pArguments->GetElement(1);

	//	If there are no expressions, then we just return Nil

	if (pExp == NULL)
		return pCC->CreateNil();

	//	Setup the locals. We start by creating a local symbol table

	pLocalSymbols = pCC->CreateSymbolTable();
	if (pLocalSymbols->IsError())
		return pLocalSymbols;

	pLocalSymbols->SetLocalFrame();

	//	Loop over each item and associate it

	for (i = 0; i < pLocals->GetCount(); i++)
		{
		ICCItem *pItem;

		pVar = pLocals->GetElement(i);

		pItem = pLocalSymbols->AddEntry(pCC, pVar, pCC->CreateNil());
		if (pItem->IsError())
			{
			pLocalSymbols->Discard(pCC);
			return pItem;
			}

		pItem->Discard(pCC);
		}

	//	Setup the context

	if (pCtx->pLocalSymbols)
		pLocalSymbols->SetParent(pCtx->pLocalSymbols);
	else
		pLocalSymbols->SetParent(pCtx->pLexicalSymbols);
	pOldSymbols = pCtx->pLocalSymbols;
	pCtx->pLocalSymbols = pLocalSymbols;

	//	Start with a default result

	pResult = pCC->CreateNil();

	//	Loop (starting with the second arg)

	for (i = 1; i < pArguments->GetCount(); i++)
		{
		pExp = pArguments->GetElement(i);

		//	If this is an error block and this is the last expression,
		//	then it must be error condition and we don't want to 
		//	execute it.

		if (i+1 == pArguments->GetCount() && dwData == FN_BLOCK_ERRBLOCK)
			break;

		//	Evaluate the expression

		pResult->Discard(pCC);
		pResult = pCC->Eval(pCtx, pExp);

		//	If we got an error, handle it

		if (pResult->IsError())
			{
			//	If this is an error block, then find the last expression
			//	and evaluate it.

			if (dwData == FN_BLOCK_ERRBLOCK)
				{
				ICCItem *pItem;

				//	Set the first local variable to be the error result

				pVar = pLocals->Head(pCC);
				pItem = pLocalSymbols->AddEntry(pCC, pVar, pResult);

				pItem->Discard(pCC);
				pResult->Discard(pCC);

				//	Find the last expression

				pExp = pArguments->GetElement(pArguments->GetCount() - 1);

				//	Evaluate it

				pResult = pCC->Eval(pCtx, pExp);
				}

			//	Regardless, leave the block and return the result

			break;
			}
		}

	//	Clean up

	pCtx->pLocalSymbols = pOldSymbols;
	pLocalSymbols->Discard(pCC);

	//	Done

	return pResult;
	}
Exemplo n.º 23
0
ICCItem *fnItemInfo (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnItemInfo
//
//	Returns info about a single item
//
//	(isatom item) -> True/Nil
//	(iserror item) -> True/Nil
//	(isfunction item) -> True/Nil

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

	//	Evaluate the arguments and validate them

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

	//	Do the right thing

	switch (dwData)
		{
		case FN_ITEMINFO_ISERROR:
			{
			if (pArgs->Head(pCC)->IsError())
				pResult = pCC->CreateTrue();
			else
				pResult = pCC->CreateNil();
			break;
			}

		case FN_ITEMINFO_ISATOM:
			{
			if (pArgs->Head(pCC)->IsAtom())
				pResult = pCC->CreateTrue();
			else
				pResult = pCC->CreateNil();
			break;
			}

		case FN_ITEMINFO_ISINT:
			{
			pResult = pCC->CreateBool(pArgs->Head(pCC)->IsInteger() ? true : false);
			break;
			}

		case FN_ITEMINFO_ISFUNCTION:
			{
			if (pArgs->Head(pCC)->IsFunction())
				pResult = pCC->CreateTrue();
			else
				pResult = pCC->CreateNil();
			break;
			}

		case FN_ITEMINFO_ASINT:
			{
			pResult = pCC->CreateInteger(pArgs->Head(pCC)->GetIntegerValue());
			break;
			}

		case FN_ITEMINFO_HELP:
			{
			CString sHelp = pArgs->GetElement(0)->GetHelp();
			if (sHelp.IsBlank())
				pResult = pCC->CreateNil();
			else
				pResult = pCC->CreateString(sHelp);
			break;
			}

		default:
			ASSERT(FALSE);
			return NULL;
		}

	//	Done

	pArgs->Discard(pCC);
	return pResult;
	}
Exemplo n.º 24
0
ICCItem *fnAtmTable (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnAtmTable
//
//	Various atom table manipulations
//
//	(atmAddEntry symTable symbol entry) -> entry
//	(atmDeleteEntry symTable symbol) -> True
//	(atmLookup symTable symbol) -> entry

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pArgs;
	ICCItem *pSymTable;
	ICCItem *pSymbol;
	ICCItem *pResult;

	//	Evaluate the arguments and validate them

	if (dwData == FN_ATMTABLE_ADDENTRY)
		pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("xiv"));
	else if (dwData == FN_ATMTABLE_LIST)
		pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("x"));
	else
		pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("xi"));

	if (pArgs->IsError())
		return pArgs;

	//	Get the args

	pSymTable = pArgs->Head(pCC);

	//	Do the right thing

	switch (dwData)
		{
		case FN_ATMTABLE_ADDENTRY:
			{
			ICCItem *pEntry;

			pSymbol = pArgs->GetElement(1);
			pEntry = pArgs->GetElement(2);
			pResult = pSymTable->AddEntry(pCC, pSymbol, pEntry);

			//	If we succeeded, return the entry

			if (!pResult->IsError())
				{
				pResult->Discard(pCC);
				pResult = pEntry->Reference();
				}

			break;
			}

		case FN_ATMTABLE_DELETEENTRY:
			{
			pResult = pCC->CreateNil();
			break;
			}

		case FN_ATMTABLE_LIST:
			{
			pResult = pSymTable->ListSymbols(pCC);
			break;
			}

		case FN_ATMTABLE_LOOKUP:
			{
			pSymbol = pArgs->GetElement(1);
			pResult = pSymTable->Lookup(pCC, pSymbol);
			break;
			}

		default:
			ASSERT(FALSE);
			return NULL;
		}

	//	Done

	pArgs->Discard(pCC);
	return pResult;
	}
Exemplo n.º 25
0
ICCItem *fnLinkedList (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnLinkedList
//
//	Handles linked-list specific functions
//
//	(lnkAppend linked-list item) -> list
//	(lnkRemove linked-list index) -> list
//	(lnkRemoveNil linked-list) -> list
//	(lnkReplace linked-list index item) -> list
//
//	HACK: This function has different behavior depending on the first
//	argument. If the first argument is a variable holding a linked list,
//	then the variable contents will be changed. If the variable holds Nil,
//	then the variable contents are not changed. In all cases, the caller
//	should structure the call as: (setq ListVar (lnkAppend ListVar ...))
//	in order to handle all cases.

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pArgs;
	ICCItem *pList;
	CCLinkedList *pLinkedList;
	ICCItem *pResult;

	//	Evaluate the arguments

	if (dwData == FN_LINKEDLIST_APPEND)
		pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("lv"));
	else if (dwData == FN_LINKEDLIST_REMOVE_NIL)
		pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("l"));
	else
		pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("liv"));
	if (pArgs->IsError())
		return pArgs;

	//	Get the linked list

	pList = pArgs->GetElement(0);
	if (pList->GetClass()->GetObjID() == OBJID_CCLINKEDLIST)
		pLinkedList = (CCLinkedList *)pList->Reference();
	else if (pList->IsNil())
		{
		pList = pCC->CreateLinkedList();
		if (pList->IsError())
			{
			pArgs->Discard(pCC);
			return pList;
			}
		pLinkedList = (CCLinkedList *)pList;
		}
	else
		{
		pArgs->Discard(pCC);
		return pCC->CreateError(CONSTLIT("Linked-list expected:"), NULL);
		}

	//	Do the right thing

	switch (dwData)
		{
		case FN_LINKEDLIST_APPEND:
			{
			ICCItem *pItem = pArgs->GetElement(1);
			ICCItem *pError;

			pLinkedList->Append(pCC, pItem, &pError);
			if (pError->IsError())
				{
				pLinkedList->Discard(pCC);
				pResult = pError;
				}
			else
				{
				pError->Discard(pCC);
				pResult = pLinkedList;
				}
			break;
			}

		case FN_LINKEDLIST_REMOVE:
			{
			int iIndex = pArgs->GetElement(1)->GetIntegerValue();

			//	Make sure we're in range

			if (iIndex < 0 || iIndex >= pLinkedList->GetCount())
				{
				pLinkedList->Discard(pCC);
				pResult = pCC->CreateError(CONSTLIT("Index out of range:"), pArgs->GetElement(1));
				}
			else
				{
				pLinkedList->RemoveElement(pCC, iIndex);
				pResult = pLinkedList;
				}

			break;
			}

		case FN_LINKEDLIST_REMOVE_NIL:
			{
			//	Iterate over all elements and remove any elements that are Nil

			int iIndex = 0;
			while (iIndex < pLinkedList->GetCount())
				{
				if (pLinkedList->GetElement(iIndex)->IsNil())
					pLinkedList->RemoveElement(pCC, iIndex);
				else
					iIndex++;
				}

			//	Done

			pResult = pLinkedList;
			break;
			}

		case FN_LINKEDLIST_REPLACE:
			{
			int iIndex = pArgs->GetElement(1)->GetIntegerValue();
			ICCItem *pItem = pArgs->GetElement(2);

			//	Make sure we're in range

			if (iIndex < 0 || iIndex >= pLinkedList->GetCount())
				{
				pLinkedList->Discard(pCC);
				pResult = pCC->CreateError(CONSTLIT("Index out of range:"), pArgs->GetElement(1));
				}
			else
				{
				pLinkedList->ReplaceElement(pCC, iIndex, pItem);
				pResult = pLinkedList;
				}

			break;
			}

		default:
			ASSERT(FALSE);
			return NULL;
		}

	//	Done

	pArgs->Discard(pCC);
	return pResult;
	}
Exemplo n.º 26
0
ICCItem *fnMathList (CEvalContext *pCtx, ICCItem *pArgs, DWORD dwData)

//	fnMathList
//
//	Simple integer functions
//
//	(add x1 x2 ... xn) -> z
//	(max x1 x2 ... xn) -> z
//	(min x1 x2 ... xn) -> z
//	(multiply x1 x2 .. .xn) -> z

	{
	int i;
	CCodeChain *pCC = pCtx->pCC;

	//	Get the list

	ICCItem *pList;
	if (pArgs->GetElement(0)->IsList())
		{
		pList = pArgs->GetElement(0);

		if (pList->GetCount() < 1)
			return pCC->CreateNil();
		}
	else
		pList = pArgs;

	//	Do the computation

	switch (dwData)
		{
		case FN_MATH_ADD:
			{
			int iResult = pList->GetElement(0)->GetIntegerValue();
			for (i = 1; i < pList->GetCount(); i++)
				iResult += pList->GetElement(i)->GetIntegerValue();
			return pCC->CreateInteger(iResult);
			}

		case FN_MATH_MULTIPLY:
			{
			int iResult = pList->GetElement(0)->GetIntegerValue();
			for (i = 1; i < pList->GetCount(); i++)
				iResult *= pList->GetElement(i)->GetIntegerValue();
			return pCC->CreateInteger(iResult);
			}

		case FN_MATH_MAX:
			{
			int iResult = pList->GetElement(0)->GetIntegerValue();
			for (i = 1; i < pList->GetCount(); i++)
				{
				int iVal = pList->GetElement(i)->GetIntegerValue();
				if (iVal > iResult)
					iResult = iVal;
				}
			return pCC->CreateInteger(iResult);
			}

		case FN_MATH_MIN:
			{
			int iResult = pList->GetElement(0)->GetIntegerValue();
			for (i = 1; i < pList->GetCount(); i++)
				{
				int iVal = pList->GetElement(i)->GetIntegerValue();
				if (iVal < iResult)
					iResult = iVal;
				}
			return pCC->CreateInteger(iResult);
			}

		default:
			ASSERT(false);
			return pCC->CreateNil();
		}
	}
Exemplo n.º 27
0
ICCItem *fnSet (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnSet
//
//	Bind an identifier to some value
//
//	(set var exp)
//	(setq var exp)

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pArgs;
	ICCItem *pVar;
	ICCItem *pValue;
	int iFrame, iOffset;
	ICCItem *pSymTable;

	//	Evaluate the arguments and validate them

	if (dwData == FN_SET_SET)
		pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("sv"));
	else
		pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("qv"));
	if (pArgs->IsError())
		return pArgs;

	//	First is the variable; next is the value

	pVar = pArgs->GetElement(0);
	pValue = pArgs->GetElement(1);

	//	Figure out which symbol table to start with

	if (pCtx->pLocalSymbols)
		pSymTable = pCtx->pLocalSymbols;
	else
		pSymTable = pCtx->pLexicalSymbols;

	//	If this variable has already been bound, then use a short-cut

	if (pVar->GetBinding(&iFrame, &iOffset))
		{
		while (iFrame > 0)
			{
			pSymTable = pSymTable->GetParent();
			iFrame--;
			}

		pSymTable->AddByOffset(pCC, iOffset, pValue);
		}
	else
		{
		ICCItem *pError;

		pError = pSymTable->AddEntry(pCC, pVar, pValue);

		//	Check for error

		if (pError->IsError())
			{
			pArgs->Discard(pCC);
			return pError;
			}

		pError->Discard(pCC);
		}

	//	Keep a reference to the value, so we can return it

	pValue->Reference();

	//	Done with these

	pArgs->Discard(pCC);

	//	Done

	return pValue;
	}
CLanguageDataBlock::ETranslateResult CLanguageDataBlock::Translate (CSpaceObject *pObj, const CString &sID, TArray<CString> *retText, CString *retsText) const

//	Translate
//
//	Translates an entry to either a string or an array of strings.

	{
	int i;

	//	If we can't find this ID then we can't translate

	SEntry *pEntry = m_Data.GetAt(sID);
	if (pEntry == NULL)
		return resultNotFound;

	//	If we don't want the text back then all we need to do is return that we
	//	have the text.

	if (retText == NULL && retsText == NULL)
		return resultFound;

	//	If we don't need to run code then we just return the string.

	if (pEntry->pCode == NULL)
		{
		if (retsText)
			{
			*retsText = ::ComposePlayerNameString(pEntry->sText, g_pUniverse->GetPlayerName(), g_pUniverse->GetPlayerGenome());
			return resultString;
			}
		else
			return resultFound;
		}

	//	Otherwise we have to run some code

	CCodeChainCtx Ctx;
	Ctx.SaveAndDefineSourceVar(pObj);
	Ctx.DefineString(CONSTLIT("aTextID"), sID);
	
	ICCItem *pResult = Ctx.Run(pEntry->pCode);	//	LATER:Event
	ETranslateResult iResult;

	//	Nil

	if (pResult->IsNil())
		iResult = resultNotFound;

	//	List of strings

	else if (pResult->GetCount() > 1)
		{
		if (retText)
			{
			CString sPlayerName = g_pUniverse->GetPlayerName();
			GenomeTypes iPlayerGenome = g_pUniverse->GetPlayerGenome();

			retText->DeleteAll();

			retText->InsertEmpty(pResult->GetCount());
			for (i = 0; i < pResult->GetCount(); i++)
				retText->GetAt(i) = ::ComposePlayerNameString(pResult->GetElement(i)->GetStringValue(), sPlayerName, iPlayerGenome);

			iResult = resultArray;
			}
		else
			iResult = resultFound;
		}

	//	String

	else
		{
		if (retsText)
			{
			*retsText = ::ComposePlayerNameString(pResult->GetStringValue(), g_pUniverse->GetPlayerName(), g_pUniverse->GetPlayerGenome());
			iResult = resultString;
			}
		else
			iResult = resultFound;
		}

	//	Done

	Ctx.Discard(pResult);

	return iResult;
	}
Exemplo n.º 29
0
ICCItem *fnForLoop (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnForLoop
//
//	Evaluates an expression for a given number of iterations
//	Iterates from "from" to "to" inclusive.
//
//	(for var from to exp)

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pArgs;
	ICCItem *pResult;
	ICCItem *pVar;
	ICCItem *pBody;
	ICCItem *pLocalSymbols;
	ICCItem *pOldSymbols;
	ICCItem *pError;
	int i, iFrom, iTo, iVarOffset;

	//	Evaluate the arguments and validate them

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

	pVar = pArgs->GetElement(0);
	iFrom = pArgs->GetElement(1)->GetIntegerValue();
	iTo = pArgs->GetElement(2)->GetIntegerValue();
	pBody = pArgs->GetElement(3);

	//	Setup the locals. We start by creating a local symbol table

	pLocalSymbols = pCC->CreateSymbolTable();
	if (pLocalSymbols->IsError())
		{
		pArgs->Discard(pCC);
		return pLocalSymbols;
		}

	//	Associate the enumaration variable

	pError = pLocalSymbols->AddEntry(pCC, pVar, pCC->CreateNil());
	if (pError->IsError())
		{
		pArgs->Discard(pCC);
		return pError;
		}

	pError->Discard(pCC);

	//	Setup the context

	if (pCtx->pLocalSymbols)
		pLocalSymbols->SetParent(pCtx->pLocalSymbols);
	else
		pLocalSymbols->SetParent(pCtx->pLexicalSymbols);
	pOldSymbols = pCtx->pLocalSymbols;
	pCtx->pLocalSymbols = pLocalSymbols;

	//	Start with a default result

	pResult = pCC->CreateNil();

	//	Get the offset of the variable so we don't have to
	//	search for it all the time

	iVarOffset = pLocalSymbols->FindOffset(pCC, pVar);

	//	Loop over all elements of the list

	for (i = iFrom; i <= iTo; i++)
		{
		ICCItem *pItem = pCC->CreateInteger(i);

		//	Clean up the previous result

		pResult->Discard(pCC);

		//	Set the element

		pLocalSymbols->AddByOffset(pCC, iVarOffset, pItem);
		pItem->Discard(pCC);

		//	Eval

		pResult = pCC->Eval(pCtx, pBody);
		if (pResult->IsError())
			break;
		}

	//	Clean up

	pCtx->pLocalSymbols = pOldSymbols;
	pLocalSymbols->Discard(pCC);

	//	Done

	pArgs->Discard(pCC);
	return pResult;
	}
Exemplo n.º 30
0
ICCItem *fnMathOld (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnMathOld
//
//	Simple integer arithmetic
//
//	(divide int1 int2)
//	(modulo int1 int2)
//	(subtract int1 int2)

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pArgs;
	int iResult, iOp1, iOp2;

	//	Evaluate the arguments and validate them

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

	//	Convert to integers

	iOp1 = pArgs->GetElement(0)->GetIntegerValue();
	iOp2 = pArgs->GetElement(1)->GetIntegerValue();

	//	Done with arguments

	pArgs->Discard(pCC);

	//	Compute

	switch (dwData)
		{
		case FN_MATH_SUBTRACT:
			iResult = iOp1 - iOp2;
			break;

		case FN_MATH_DIVIDE:
			if (iOp2 != 0)
				iResult = iOp1 / iOp2;
			else
				return pCC->CreateError(CONSTLIT("Division by zero"), pArguments);
			break;

		case FN_MATH_MODULUS:
			if (iOp2 != 0)
				iResult = iOp1 % iOp2;
			else
				return pCC->CreateError(CONSTLIT("Division by zero"), pArguments);
			break;

		case FN_MATH_POWER:
			iResult = mathPower(iOp1, iOp2);
			break;

		default:
			ASSERT(FALSE);
		}

	//	Done

	return pCC->CreateInteger(iResult);
	}