Beispiel #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.SaveItemVar();
		Ctx.DefineItem(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;
	}
Beispiel #2
0
void CShieldClass::FireOnShieldDown (CInstalledDevice *pDevice, CSpaceObject *pSource)

//	FireOnShieldDown
//
//	Fire OnShieldDown event

	{
	SEventHandlerDesc Event;
	if (FindEventHandlerShieldClass(evtOnShieldDown, &Event))
		{
		CCodeChainCtx Ctx;

		Ctx.SaveAndDefineSourceVar(pSource);
		Ctx.SaveItemVar();
		Ctx.DefineItem(pSource->GetItemForDevice(pDevice));

		ICCItem *pResult = Ctx.Run(Event);
		if (pResult->IsError())
			pSource->ReportEventError(ON_SHIELD_DOWN_EVENT, pResult);
		Ctx.Discard(pResult);
		}
	}
Beispiel #3
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.SaveItemVar();
		CCCtx.DefineItem(ItemCtx);

		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 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);
		}
	}
void CRandomEnhancementGenerator::EnhanceItem (CItem &Item)

//	EnhanceItem
//
//	Enhances the given item

	{
	//	See if this item is enhanced

	if (mathRandom(1, 100) > m_iChance)
		return;

	//	If we have code, execute the code to figure out the mod

	if (m_pCode)
		{
		CCodeChainCtx Ctx;

		//	Save the previous value of gItem

		Ctx.SaveItemVar();
		Ctx.DefineItem(Item);

		//	Execute the code

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

		//	If we have an error, report it

		DWORD dwMods;
		if (pResult->IsError())
			{
			CString sError = strPatternSubst(CONSTLIT("Generate Enhancement: %s"), pResult->GetStringValue());
			kernelDebugLogMessage(sError);
			dwMods = 0;
			}

		//	Otherwise, the result code is the mods

		else
			dwMods = (DWORD)pResult->GetIntegerValue();

		//	Done with code

		Ctx.Discard(pResult);

		//	Enhance the item

		Item.AddEnhancement(dwMods);
		}

	//	Otherwise, if we have a constant mod, apply that

	else if (m_dwMods)
		{
		Item.AddEnhancement(m_dwMods);
		}

	//	Otherwise, we need to generate a random mod appropriate to the
	//	particular item

	else
		{
		DWORD dwMods;
		CItemType *pType = Item.GetType();
		int iRoll = mathRandom(1, 100);

		switch (pType->GetCategory())
			{
			case itemcatArmor:
			case itemcatShields:
				if (iRoll < 40)
					//	HP + 10%
					dwMods = 0x0101;
				else if (iRoll < 65)
					//	HP + 20%
					dwMods = 0x0102;
				else if (iRoll < 80)
					//	HP + 30%
					dwMods = 0x0103;
				else if (iRoll < 90)
					//	Damage Adj at 50% (and 75%)
					dwMods = 0x0A05 + (mathRandom(0, 3) << 4);
				else if (iRoll < 95)
					//	Immunity to special ion attacks
					dwMods = 0x0C00;
				else
					//	Regeneration
					dwMods = 0x0200;
				break;

			case itemcatWeapon:
				if (iRoll < 50)
					//	Damage + 10%
					dwMods = 0x0101;
				else if (iRoll < 80)
					//	Damage + 20%
					dwMods = 0x0102;
				else if (iRoll < 95)
					//	Damage + 30%
					dwMods = 0x0103;
				else
					//	Delay time at 70% of original
					dwMods = 0x1003;
				break;

			default:
				dwMods = 0;
			}

		Item.AddEnhancement(dwMods);
		}
	}