Пример #1
0
int CShieldClass::FireGetMaxHP (CInstalledDevice *pDevice, CSpaceObject *pSource, int iMaxHP) const

//	FireGetMaxHP
//
//	Fire GetMaxHP event

	{
	SEventHandlerDesc Event;
	if (FindEventHandlerShieldClass(evtGetMaxHP, &Event))
		{
		ASSERT(pSource);
		ASSERT(pDevice);

		CCodeChainCtx Ctx;

		Ctx.SaveAndDefineSourceVar(pSource);
		Ctx.SaveAndDefineItemVar(pSource->GetItemForDevice(pDevice));
		Ctx.DefineInteger(CONSTLIT("aMaxHP"), iMaxHP);

		ICCItem *pResult = Ctx.Run(Event);
		if (pResult->IsError())
			pSource->ReportEventError(GET_MAX_HP_EVENT, pResult);
		else if (!pResult->IsNil())
			iMaxHP = Max(0, pResult->GetIntegerValue());

		Ctx.Discard(pResult);
		}

	return iMaxHP;
	}
Пример #2
0
COverlayType *CDeviceClass::FireGetOverlayType (CItemCtx &ItemCtx) const

//	FireGetOverlayType
//
//	Fire GetOverlayType event

	{
	SEventHandlerDesc Event;
	if (FindEventHandlerDeviceClass(evtGetOverlayType, &Event))
		{
		//	Setup arguments

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

		ICCItem *pResult = Ctx.Run(Event);

		DWORD dwUNID = 0;
		if (pResult->IsError())
			ItemCtx.GetSource()->ReportEventError(GET_OVERLAY_TYPE_EVENT, pResult);
		else if (!pResult->IsNil())
			dwUNID = pResult->GetIntegerValue();

		Ctx.Discard(pResult);

		//	Done

		return COverlayType::AsType(g_pUniverse->FindDesignType(dwUNID));
		}
	else
		return GetOverlayType();
	}
Пример #3
0
bool IDockScreenDisplay::EvalBool (const CString &sCode, bool *retbResult, CString *retsError)

//	EvalBool
//
//	Evaluates the given string

	{
	CCodeChainCtx Ctx;
	Ctx.SetScreen(m_pDockScreen);
	Ctx.SaveAndDefineSourceVar(m_pLocation);
	Ctx.SaveAndDefineDataVar(m_pData);

	char *pPos = sCode.GetPointer();
	ICCItem *pExp = Ctx.Link(sCode, 1, NULL);

	ICCItem *pResult = Ctx.Run(pExp);	//	LATER:Event
	Ctx.Discard(pExp);

	if (pResult->IsError())
		{
		*retsError = pResult->GetStringValue();
		Ctx.Discard(pResult);
		return false;
		}

	*retbResult = !pResult->IsNil();
	Ctx.Discard(pResult);

	return true;
	}
Пример #4
0
int CArmorClass::FireGetMaxHP (CItemCtx &ItemCtx, int iMaxHP) const

//	FireGetMaxHP
//
//	Fire GetMaxHP event

	{
	SEventHandlerDesc Event;
	if (FindEventHandlerArmorClass(evtGetMaxHP, &Event))
		{
		//	Setup arguments

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

		Ctx.DefineInteger(CONSTLIT("aMaxHP"), iMaxHP);

		ICCItem *pResult = Ctx.Run(Event);

		if (pResult->IsError())
			ItemCtx.GetSource()->ReportEventError(GET_MAX_HP_EVENT, pResult);
		else if (!pResult->IsNil())
			iMaxHP = Max(0, pResult->GetIntegerValue());

		Ctx.Discard(pResult);
		}

	return iMaxHP;
	}
Пример #5
0
void CEffectCreator::InitPainterParameters (CCreatePainterCtx &Ctx, IEffectPainter *pPainter)

//	InitPainterParameters
//
//	Initialize painter parameters

	{
	SEventHandlerDesc Event;
	if (FindEventHandlerEffectType(evtGetParameters, &Event))
		{
		CCodeChainCtx CCCtx;

		CCCtx.SaveAndDefineDataVar(Ctx.GetData());

		ICCItem *pResult = CCCtx.Run(Event);
		if (pResult->IsError())
			::kernelDebugLogMessage(CONSTLIT("EffectType %x GetParameters: %s"), GetUNID(), (LPSTR)pResult->GetStringValue());
		else if (pResult->IsSymbolTable())
			{
			int i;
			CCSymbolTable *pTable = (CCSymbolTable *)pResult;

			for (i = 0; i < pTable->GetCount(); i++)
				{
				CString sParam = pTable->GetKey(i);
				ICCItem *pValue = pTable->GetElement(i);
				CEffectParamDesc Value;

				if (pValue->IsNil())
					Value.InitNull();
				else if (pValue->IsInteger())
					Value.InitInteger(pValue->GetIntegerValue());
				else if (pValue->IsIdentifier())
					{
					CString sValue = pValue->GetStringValue();
					char *pPos = sValue.GetASCIIZPointer();

					//	If this is a color, parse it

					if (*pPos == '#')
						Value.InitColor(::LoadRGBColor(sValue));

					//	Otherwise, a string

					else
						Value.InitString(sValue);
					}

				pPainter->SetParam(Ctx, sParam, Value);
				}
			}
		else
			::kernelDebugLogMessage(CONSTLIT("EffectType %x GetParameters: Expected struct result."), GetUNID());

		CCCtx.Discard(pResult);
		}
	}
Пример #6
0
void OutputTable (SItemTableCtx &Ctx, const SItemTypeList &ItemList)
	{
	int i, j;

	if (ItemList.GetCount() == 0)
		return;

	//	Output each row

	for (i = 0; i < ItemList.GetCount(); i++)
		{
		CItemType *pType = ItemList[i];

		for (j = 0; j < Ctx.Cols.GetCount(); j++)
			{
			if (j != 0)
				printf("\t");

			const CString &sField = Ctx.Cols[j];

			//	Get the field value

			CString sValue;
			CItem Item(pType, 1);
			CItemCtx ItemCtx(Item);
			CCodeChainCtx CCCtx;

			ICCItem *pResult = Item.GetProperty(&CCCtx, ItemCtx, sField);

			if (pResult->IsNil())
				sValue = NULL_STR;
			else
				sValue = pResult->Print(&g_pUniverse->GetCC(), PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY);

			pResult->Discard(&g_pUniverse->GetCC());

			//	Format the value

			if (strEquals(sField, FIELD_AVERAGE_DAMAGE) || strEquals(sField, FIELD_POWER_PER_SHOT))
				printf("%.2f", strToInt(sValue, 0, NULL) / 1000.0);
			else if (strEquals(sField, FIELD_POWER))
				printf("%.1f", strToInt(sValue, 0, NULL) / 1000.0);
			else if (strEquals(sField, FIELD_TOTAL_COUNT))
				{
				SDesignTypeInfo *pInfo = Ctx.TotalCount.GetAt(pType->GetUNID());
				double rCount = (pInfo ? pInfo->rPerGameMeanCount : 0.0);
				printf("%.2f", rCount);
				}
			else
				printf(sValue.GetASCIIZPointer());
			}

		printf("\n");
		}
	}
Пример #7
0
ALERROR CDesignCollection::CreateTemplateTypes (SDesignLoadCtx &Ctx)

//	CreateTemplateTypes
//
//	This is called inside of BindDesign to create all template types

	{
	ALERROR error;
	int i;

	//	Create an appropriate context for running code

	CCodeChainCtx CCCtx;

	//	Loop over all active types looking for templates.
	//	NOTE: We cannot use the type-specific arrays because they have not been
	//	set up yet (remember that we are inside of BindDesign).

	for (i = 0; i < m_AllTypes.GetCount(); i++)
		{
		CDesignType *pTemplate = m_AllTypes.GetEntry(i);
		if (pTemplate->GetType() != designTemplateType)
			continue;

		//	Get the function to generate the type source

		CString sSource;
		SEventHandlerDesc Event;
		if (pTemplate->FindEventHandler(GET_TYPE_SOURCE_EVENT, &Event))
			{
			ICCItem *pResult = CCCtx.Run(Event);
			if (pResult->IsError())
				{
				Ctx.sError = strPatternSubst(CONSTLIT("GetTypeSource (%x): %s"), pTemplate->GetUNID(), pResult->GetStringValue());
				return ERR_FAIL;
				}
			else if (pResult->IsNil())
				sSource = NULL_STR;
			else
				sSource = pResult->GetStringValue();

			CCCtx.Discard(pResult);
			}

		//	Define the type

		if (!sSource.IsBlank())
			{
			if (error = AddDynamicType(pTemplate->GetExtension(), pTemplate->GetUNID(), sSource, true, &Ctx.sError))
				return error;
			}
		}

	return NOERROR;
	}
Пример #8
0
void CDockScreenStack::IncData (const CString &sAttrib, ICCItem *pValue, ICCItem **retpResult)

//	IncData
//
//	Increments data

	{
	CCodeChain &CC = g_pUniverse->GetCC();
	if (IsEmpty())
		{
		if (retpResult) *retpResult = CC.CreateNil();
		return;
		}

    //  If pValue is NULL, we default to 1. We add ref no matter what so that
    //  we can discard unconditionally.

    if (pValue == NULL)
        pValue = CC.CreateInteger(1);
    else
        pValue->Reference();

    //  If the entry is currently blank, then we just take the increment.

	ICCItem *pOriginal = GetData(sAttrib);
    ICCItem *pResult = NULL;
    if (pOriginal->IsNil())
        pResult = pValue->Reference();

    //  Otherwise, we need to get the data value

    else
        {
        if (pOriginal->IsDouble() || pValue->IsDouble())
            pResult = CC.CreateDouble(pOriginal->GetDoubleValue() + pValue->GetDoubleValue());
        else
            pResult = CC.CreateInteger(pOriginal->GetIntegerValue() + pValue->GetIntegerValue());
        }

    pOriginal->Discard(&CC);

    //  Store

	SetData(sAttrib, pResult);

    //  Done

    if (retpResult)
        *retpResult = pResult;
    else
        pResult->Discard(&CC);

    pValue->Discard(&CC);
	}
Пример #9
0
ICCItem *fnSwitch (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnSwitch
//
//	Switch control function
//
//	(switch exp1 case1 exp2 case2 ... default)

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

	int iArgPos = 0;
	while (iArgPos+1 < pArguments->GetCount())
		{
		//	Get the arguments

		pTest = pArguments->GetElement(iArgPos);
		pThen = pArguments->GetElement(iArgPos+1);

		//	Evaluate the expression

		pResult = pCC->Eval(pCtx, pTest);
		if (pResult->IsError())
			return pResult;

		//	If the result is not Nil, then evaluate the Then expression

		if (!pResult->IsNil())
			{
			pResult->Discard(pCC);
			return pCC->Eval(pCtx, pThen);
			}

		//	Otherwise, continue with the loop

		pResult->Discard(pCC);
		iArgPos += 2;
		}

	//	Do we have a default case?

	if (iArgPos < pArguments->GetCount())
		{
		ICCItem *pElse = pArguments->GetElement(iArgPos);
		return pCC->Eval(pCtx, pElse);
		}

	//	Otherwise, we return Nil

	return pCC->CreateNil();
	}
Пример #10
0
bool CWeaponFireDesc::FireOnDamageOverlay (SDamageCtx &Ctx, CEnergyField *pOverlay)

//	FireOnDamageOverlay
//
//	Fire OnDamageOverlay event. Returns TRUE if we should skip further overlay damage

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

		CCodeChainCtx CCCtx;

		CCCtx.SaveAndDefineSourceVar(Ctx.pObj);
		CCCtx.DefineInteger(CONSTLIT("aArmorSeg"), Ctx.iSectHit);
		CCCtx.DefineInteger(CONSTLIT("aOverlayID"), pOverlay->GetID());
		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());

		ICCItem *pResult = CCCtx.Run(Event);
		if (pResult->IsError())
			Ctx.pObj->ReportEventError(ON_DAMAGE_OVERLAY_EVENT, pResult);

		//	If we return Nil, then we continue processing

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

		//	Otherwise, the result is the damage left

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

		CCCtx.Discard(pResult);

		return bResult;
		}
	else
		return false;
	}
Пример #11
0
ICCItem *fnIf (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnIf
//
//	If control function
//
//	(if exp then else)

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pTest;
	ICCItem *pThen;
	ICCItem *pElse;
	ICCItem *pResult;

	//	Get the arguments

	pTest = pArguments->GetElement(0);
	if (pTest == NULL)
		return pCC->CreateError(CONSTLIT("Conditional expression expected"), pCC->CreateNil());

	pThen = pArguments->GetElement(1);
	if (pThen == NULL)
		return pCC->CreateError(CONSTLIT("Then expression expected"), pCC->CreateNil());

	pElse = pArguments->GetElement(2);

	//	Evaluate the test expression

	pResult = pCC->Eval(pCtx, pTest);
	if (pResult->IsError())
		return pResult;

	//	If the result is not true, evaluate the else expression

	if (pResult->IsNil())
		{
		if (pElse)
			{
			pResult->Discard(pCC);
			return pCC->Eval(pCtx, pElse);
			}
		else
			return pResult;
		}

	//	Otherwise, evaluate the then expression

	pResult->Discard(pCC);
	return pCC->Eval(pCtx, pThen);
	}
Пример #12
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;
	}
Пример #13
0
bool CWeaponFireDesc::FireOnFragment (const CDamageSource &Source, CSpaceObject *pShot, const CVector &vHitPos, CSpaceObject *pNearestObj, CSpaceObject *pTarget)

//	FireOnFragment
//
//	Event fires when a shot fragments. If we return TRUE then we skip the default
//	fragmentation event.

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

		CCodeChainCtx CCCtx;

		CCCtx.SaveAndDefineSourceVar(pShot);
		CCCtx.DefineSpaceObject(CONSTLIT("aNearestObj"), pNearestObj);
		CCCtx.DefineSpaceObject(CONSTLIT("aTargetObj"), pTarget);
		CCCtx.DefineVector(CONSTLIT("aHitPos"), vHitPos);
		CCCtx.DefineInteger(CONSTLIT("aHitDir"), (pShot ? pShot->GetRotation() : 0));
		CCCtx.DefineItemType(CONSTLIT("aWeaponType"), GetWeaponType());
		CCCtx.DefineString(CONSTLIT("aWeaponFragment"), m_sUNID);

		CSpaceObject *pAttacker = Source.GetObj();
		CCCtx.DefineSpaceObject(CONSTLIT("aCause"), pShot);
		CCCtx.DefineSpaceObject(CONSTLIT("aAttacker"), pAttacker);
		CCCtx.DefineSpaceObject(CONSTLIT("aOrderGiver"), (pAttacker ? pAttacker->GetOrderGiver(Source.GetCause()) : NULL));

		ICCItem *pResult = CCCtx.Run(Event);
		if (pResult->IsError())
			pShot->ReportEventError(ON_FRAGMENT_EVENT, pResult);

		//	If we return Nil, then we continue processing

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

		//	Otherwise, we skip fragmentation

		else
			bResult = true;

		CCCtx.Discard(pResult);

		return bResult;
		}
	else
		return false;
	}
Пример #14
0
void CArmorClass::FireOnArmorDamage (CItemCtx &ItemCtx, SDamageCtx &Ctx)

//	FireOnArmorDamage
//
//	Fires OnArmorDamage event

	{
	SEventHandlerDesc Event;
	if (FindEventHandlerArmorClass(evtOnArmorDamage, &Event))
		{
		//	Setup arguments

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

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

		ICCItem *pResult = CCCtx.Run(Event);

		//	If we return Nil, then nothing

		if (pResult->IsNil())
			NULL;

		//	If we return an integer, then this is the damage that armor should take

		else if (pResult->IsInteger())
			Ctx.iDamage = pResult->GetIntegerValue();

		//	If we return a list, then we it to be a DamageEffects list (modifications to
		//	aDamageEffects)

		else if (pResult->IsList())
			LoadDamageEffectsFromItem(pResult, Ctx);

		CCCtx.Discard(pResult);
		}
	}
Пример #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;
	}
Пример #16
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())
			{
			ICCItem *pDesc = pItem->GetElement(DESC_INDEX);
			if (pDesc->IsNil())
				return NULL_STR;

			return pDesc->GetStringValue();
			}
		}

	return NULL_STR;
	}
Пример #17
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())
			{
			ICCItem *pTitle = pItem->GetElement(TITLE_INDEX);
			if (pTitle->IsNil())
				return NULL_STR;

			return pTitle->GetStringValue();
			}
		}

	return NULL_STR;
	}
Пример #18
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();
		}
	}
Пример #19
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;
	}
Пример #20
0
ICCItem *fnLogical (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnLogical
//
//	Logical operators
//
//	(and exp1 exp2 ... expn)
//	(or exp1 exp2 ... expn)

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

	//	Loop over all arguments

	for (i = 0; i < pArguments->GetCount(); i++)
		{
		ICCItem *pResult;
		ICCItem *pArg = pArguments->GetElement(i);

		//	Evaluate the item

		if (pArg->IsQuoted())
			pResult = pArg->Reference();
		else
			{
			pResult = pCC->Eval(pCtx, pArg);

			if (pResult->IsError())
				return pResult;
			}

		//	If we are evaluating NOT then reverse the value

		if (dwData == FN_LOGICAL_NOT)
			{
			if (pResult->IsNil())
				{
				pResult->Discard(pCC);
				return pCC->CreateTrue();
				}
			else
				{
				pResult->Discard(pCC);
				return pCC->CreateNil();
				}
			}

		//	If we are evaluating AND and we've got Nil, then
		//	we can guarantee that the expression is Nil

		else if (dwData == FN_LOGICAL_AND && pResult->IsNil())
			return pResult;

		//	Otherwise, if we're evaluating OR and we've got non-Nil,
		//	then we can guarantee that the expression is True

		else if (dwData == FN_LOGICAL_OR && !pResult->IsNil())
			{
			pResult->Discard(pCC);
			return pCC->CreateTrue();
			}

		//	Otherwise, we continue

		pResult->Discard(pCC);
		}

	//	If we get here then all the operands are the same (either all
	//	True or all Nil depending)

	if (dwData == FN_LOGICAL_AND)
		return pCC->CreateTrue();
	else
		return pCC->CreateNil();
	}
Пример #21
0
ICCItem *fnLoop (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData)

//	fnLoop
//
//	Evaluates an expression until the condition is Nil
//
//	(loop condition exp)

	{
	CCodeChain *pCC = pCtx->pCC;
	ICCItem *pResult;
	ICCItem *pCondition;
	ICCItem *pBody;
	BOOL bDone;

	//	The first argument must be a conditional expression

	pCondition = pArguments->Head(pCC);
	if (pCondition == NULL)
		return pCC->CreateError(CONSTLIT("Loop condition expected"), NULL);

	//	The second argument is the body

	pBody = pArguments->GetElement(1);
	if (pBody == NULL)
		return pCC->CreateError(CONSTLIT("Loop body expected"), NULL);

	//	Create a default result

	pResult = pCC->CreateNil();

	//	Keep evaluating the condition and looping
	//	until we get an error or the condition is Nil

	bDone = FALSE;
	do
		{
		ICCItem *pEval;

		//	Evaluate the condition

		pEval = pCC->Eval(pCtx, pCondition);
		if (pEval->IsError())
			return pResult;

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

		if (pEval->IsNil())
			{
			pEval->Discard(pCC);
			bDone = TRUE;
			}

		//	Otherwise, evaluate the body of the loop

		else
			{
			pEval->Discard(pCC);

			//	Clean up the old result

			pResult->Discard(pCC);

			//	Evaluate the body

			pResult = pCC->Eval(pCtx, pBody);
			if (pResult->IsError())
				return pResult;
			}
		}
	while (!bDone);

	//	Done

	return pResult;
	}
Пример #22
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);
		}
	}
Пример #23
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;
	}
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;
	}
Пример #25
0
ICCItem *fnPageMap (CEvalContext *pEvalCtx, ICCItem *pArgs, DWORD dwData)

//	fnPageMap
//
//	(pageMap address|pageID enumMethod ['excludeNil] var exp) -> filtered list

	{
	CCodeChain *pCC = pEvalCtx->pCC;

	//	Args

	ICCItem *pAddress = pArgs->GetElement(0);
	ICCItem *pMethod = pArgs->GetElement(1);

	bool bExcludeNil;
	int iOptionalArg = 2;
	if (pArgs->GetCount() > 4)
		bExcludeNil = strEquals(pArgs->GetElement(iOptionalArg++)->GetStringValue(), CONSTLIT("excludeNil"));
	else
		bExcludeNil = false;

	ICCItem *pVar = pArgs->GetElement(iOptionalArg++);
	ICCItem *pBody = pArgs->GetElement(iOptionalArg++);

	//	Open the page

	IPage *pPage;
	CString sError;
	if (g_PM.OpenPage(pAddress->GetStringValue(), &pPage, &sError) != NOERROR)
		return pCC->CreateError(sError, NULL);

	//	Prepare the method

	SPageEnumCtx EnumCtx;
	if (pPage->EnumReset(*pCC, pMethod, EnumCtx, &sError))
		{
		g_PM.ClosePage(pPage);
		return pCC->CreateError(sError, NULL);
		}

	//	Create a destination list

	ICCItem *pResult = pCC->CreateLinkedList();
	if (pResult->IsError())
		{
		g_PM.ClosePage(pPage);
		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);
		g_PM.ClosePage(pPage);
		return pLocalSymbols;
		}

	//	Associate the enumaration variable

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

	pError->Discard(pCC);

	//	Setup the context

	if (pEvalCtx->pLocalSymbols)
		pLocalSymbols->SetParent(pEvalCtx->pLocalSymbols);
	else
		pLocalSymbols->SetParent(pEvalCtx->pLexicalSymbols);
	ICCItem *pOldSymbols = pEvalCtx->pLocalSymbols;
	pEvalCtx->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);

	//	Enumerate the page

	while (pPage->EnumHasMore(EnumCtx))
		{
		ICCItem *pItem = pPage->EnumGetNext(*pCC, EnumCtx);
		if (pItem->IsError())
			{
			pResult->Discard(pCC);
			pResult = pItem;
			break;
			}

		//	Set the element

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

		//	Eval

		ICCItem *pMapped = pCC->Eval(pEvalCtx, pBody);
		if (pMapped->IsError())
			{
			pItem->Discard(pCC);
			pResult->Discard(pCC);
			pResult = pMapped;
			break;
			}

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

		if (!bExcludeNil || !pMapped->IsNil())
			pList->Append(*pCC, pMapped);

		pItem->Discard(pCC);
		pMapped->Discard(pCC);
		}

	//	Clean up

	pEvalCtx->pLocalSymbols = pOldSymbols;
	pLocalSymbols->Discard(pCC);
	g_PM.ClosePage(pPage);

	//	Done

	if (pResult->GetCount() > 0)
		return pResult;
	else
		{
		pResult->Discard(pCC);
		return pCC->CreateNil();
		}
	}
Пример #26
0
void RunFile (const CString &sFilespec, bool bNoLogo)
	{
	ALERROR error;
	CCodeChain &CC = g_pUniverse->GetCC();
	CCodeChainCtx Ctx;

	//	Verify the file

	CString sRunFile = sFilespec;
	if (!strEndsWith(sRunFile, CONSTLIT("."))
			&& pathGetExtension(sRunFile).IsBlank())
		sRunFile.Append(CONSTLIT(".tlisp"));

	//	Open the file

	CFileReadBlock InputFile(sRunFile);
	if (error = InputFile.Open())
		{
		printf("error : Unable to open file '%s'.\n", sRunFile.GetASCIIZPointer());
		return;
		}

	if (!bNoLogo)
		printf("%s\n", sRunFile.GetASCIIZPointer());

	//	Parse

	CString sInputFile(InputFile.GetPointer(0), InputFile.GetLength(), TRUE);
	CString sOutput;
	int iOffset = 0;

	while (true)
		{
		int iCharCount;
		ICCItem *pCode = Ctx.Link(sInputFile, iOffset, &iCharCount);
		if (pCode->IsNil())
			break;
		else if (pCode->IsError())
			{
			printf("error : %s\n", pCode->GetStringValue().GetASCIIZPointer());
			Ctx.Discard(pCode);
			return;
			}

		iOffset += iCharCount;

		//	Execute

		ICCItem *pResult = Ctx.Run(pCode);

		//	Compose output

		if (pResult->IsIdentifier())
			sOutput = pResult->Print(&CC, PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY);
		else
			sOutput = CC.Unlink(pResult);

		//	Free

		Ctx.Discard(pResult);
		Ctx.Discard(pCode);
		}

	//	Output result

	printf("%s\n", sOutput.GetASCIIZPointer());
	}
Пример #27
0
void OutputTable (SItemTableCtx &Ctx, const SItemTypeList &ItemList)
	{
	int i, j;

	if (ItemList.GetCount() == 0)
		return;

	//	Output each row

	for (i = 0; i < ItemList.GetCount(); i++)
		{
		CItemType *pType = ItemList[i];
		CItem Item(pType, 1);
		CItemCtx ItemCtx(Item);

		for (j = 0; j < Ctx.Cols.GetCount(); j++)
			{
			if (j != 0)
				printf("\t");

			const CString &sField = Ctx.Cols[j];

            //  Handle some special fields

            if (strEquals(sField, FIELD_BENCHMARK))
                {
                CWeaponBenchmarkCtx::SStats Stats;
                if (!Ctx.WeaponBenchmarks.GetStats(pType, Stats))
                    {
                    printf("\t\t\t\t");
                    }
                else
                    {
                    CString sBestArmor;
                    if (Stats.pBestArmor)
                        {
                        CItem BestArmor(Stats.pBestArmor, 1);
                        sBestArmor = BestArmor.GetNounPhrase(nounShort);
                        }

                    CString sWorstArmor;
                    if (Stats.pWorstArmor)
                        {
                        CItem WorstArmor(Stats.pWorstArmor, 1);
                        sWorstArmor = WorstArmor.GetNounPhrase(nounShort);
                        }

                    printf("%d\t%s\t%d\t%s\t%d",
                            Stats.iAverageTime,
                            (LPSTR)sBestArmor,
                            Stats.iBestTime,
                            (LPSTR)sWorstArmor,
                            Stats.iWorstTime);
                    }
                }

            else if (strEquals(sField, FIELD_BALANCE_STATS))
                {
                CDeviceClass *pDevice = pType->GetDeviceClass();
                CWeaponClass *pWeapon = NULL;

                if (pDevice)
                    pWeapon = pDevice->AsWeaponClass();
                else if (pType->IsMissile() && ItemCtx.ResolveVariant())
                    {
                    pDevice = ItemCtx.GetVariantDevice();
                    pWeapon = pDevice->AsWeaponClass();
                    }

                if (pWeapon)
                    {
                    CWeaponClass::SBalance Balance;
                    pWeapon->CalcBalance(ItemCtx, Balance);
                    printf("%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f",
                            Balance.rBalance,
                            Balance.rBalance - Balance.rCost,
                            Balance.rDamage,
                            Balance.rDamageType,
                            Balance.rAmmo,
                            Balance.rOmni,
                            Balance.rTracking,
                            Balance.rRange,
                            Balance.rSpeed,
                            Balance.rWMD,
                            Balance.rRadiation,
                            Balance.rMining,
                            Balance.rShatter,
                            Balance.rDeviceDisrupt,
                            Balance.rDeviceDamage,
                            Balance.rDisintegration,
                            Balance.rShieldPenetrate,
                            Balance.rArmor,
                            Balance.rShield,
                            Balance.rProjectileHP,
                            Balance.rPower,
                            Balance.rCost,
                            Balance.rSlots,
                            Balance.rExternal,
                            Balance.rLinkedFire,
                            Balance.rRecoil
                            );
                    }
                else
                    printf("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t");
                }

			//	Get the field value

            else
                {
			    CString sValue;
			    CCodeChainCtx CCCtx;

			    ICCItem *pResult = Item.GetProperty(&CCCtx, ItemCtx, sField);

			    if (pResult->IsNil())
				    sValue = NULL_STR;
			    else
				    sValue = pResult->Print(&g_pUniverse->GetCC(), PRFLAG_NO_QUOTES | PRFLAG_ENCODE_FOR_DISPLAY);

			    pResult->Discard(&g_pUniverse->GetCC());

			    //	Format the value

			    if (strEquals(sField, FIELD_POWER_PER_SHOT))
				    printf("%.2f", strToInt(sValue, 0, NULL) / 1000.0);
			    else if (strEquals(sField, FIELD_POWER))
				    printf("%.1f", strToInt(sValue, 0, NULL) / 1000.0);
			    else if (strEquals(sField, FIELD_TOTAL_COUNT))
				    {
				    SDesignTypeInfo *pInfo = Ctx.TotalCount.GetAt(pType->GetUNID());
				    double rCount = (pInfo ? pInfo->rPerGameMeanCount : 0.0);
				    printf("%.2f", rCount);
				    }
			    else
				    printf(sValue.GetASCIIZPointer());
                }
			}

		printf("\n");
		}
	}
Пример #28
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;
	}