Beispiel #1
0
bool CDeviceClass::FindWeaponFor (CItemType *pItem, CDeviceClass **retpWeapon, int *retiVariant, CWeaponFireDesc **retpDesc)

//	FindWeaponFor
//
//	Returns weapon data for the given item (which may be a weapon or a missile).

	{
	int i;
	CDeviceClass *pDevice;
	int iVariant;

	//	Get the device and variant

	if (pItem->IsMissile())
		{
		iVariant = -1;

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

			if (pDevice = pType->GetDeviceClass())
				{
				iVariant = pDevice->GetAmmoVariant(pItem);
				if (iVariant != -1)
					break;
				}
			}

		if (iVariant == -1)
			return false;
		}
	else
		{
		pDevice = pItem->GetDeviceClass();
		if (pDevice == NULL)
			return false;

		iVariant = 0;
		}

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

	CWeaponFireDesc *pDesc = pWeapon->GetVariant(iVariant);

	//	Done

	if (retpWeapon)
		*retpWeapon = pDevice;

	if (retiVariant)
		*retiVariant = iVariant;

	if (retpDesc)
		*retpDesc = pDesc;

	return true;
	}
CItemType *CWeaponFireDesc::GetWeaponType (CItemType **retpLauncher) const

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

	{
	char *pPos = m_sUNID.GetPointer();

	//	Get the weapon UNID and the ordinal

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

	//	Get the weapon descriptor

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

	//	Return the device/launcher

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

	//	For launchers, figure out which missile this is

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

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

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

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

		return pClass->GetItemType();
		}

	//	Otherwise, return the weapon

	else
		return pClass->GetItemType();
	}
Beispiel #3
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");
		}
	}
CWeaponFireDesc *CWeaponFireDesc::FindWeaponFireDescFromFullUNID (const CString &sUNID)

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

	{
	char *pPos = sUNID.GetPointer();

	//	Get the UNID of the type

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

	//	Get the type

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

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

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

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

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

		//	Get the ordinal

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

		//	Get the weapon fire desc of the ordinal

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

		//	Continue parsing

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

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

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

		//	Expect /d

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

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

		//	Continue parsing

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

	//	Otherwise, we don't know

	else
		return NULL;
	}
Beispiel #5
0
CWeaponFireDesc *GetWeaponFireDescArg (ICCItem *pArg)

//	GetWeaponFireDescArg
//
//	If arg is a weapon UNID, then we return the first weapon desc
//	If arg is a missile, then we return the first weapon desc we find for the missile
//	If arg is a list, then the first is a weapon UNID and the second is a missile UNID
//	Returns NULL on error

	{
	int i;
	DWORD dwWeaponUNID;
	DWORD dwVariantUNID;

	//	If the argument is a list, then we get the weapon UNID and the variant
	//	from the list.

	if (pArg->IsList() && pArg->GetCount() >= 2)
		{
		dwWeaponUNID = (DWORD)pArg->GetElement(0)->GetIntegerValue();
		dwVariantUNID = (DWORD)pArg->GetElement(1)->GetIntegerValue();
		}

	//	Otherwise, get the first variant of the weapon

	else
		{
		dwWeaponUNID = (DWORD)pArg->GetIntegerValue();
		dwVariantUNID = 0;
		}

	//	Get the item associated with the UNID

	CItemType *pType = g_pUniverse->FindItemType(dwWeaponUNID);
	if (pType == NULL)
		return NULL;

	//	If this is a weapon, then return the weapon fire desc

	if (pType->GetCategory() == itemcatWeapon || pType->GetCategory() == itemcatLauncher)
		{
		CDeviceClass *pClass = pType->GetDeviceClass();
		if (pClass == NULL)
			return NULL;

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

		//	If variant UNID is 0, then we just want the weapon

		if (dwVariantUNID == 0)
			return pWeapon->GetVariant(0);

		//	Otherwise, we need to find the variant index for the given UNID

		int i;
		for (i = 0; i < pWeapon->GetVariantCount(); i++)
			{
			CWeaponFireDesc *pDesc = pWeapon->GetVariant(i);
			if (pDesc->GetAmmoType()->GetUNID() == dwVariantUNID)
				return pDesc;
			}

		//	If we get this far, then we couldn't find the missile

		return NULL;
		}

	//	Otherwise, if this is a missile, then find the appropriate weapon

	else if (pType->GetCategory() == itemcatMissile)
		{
		for (i = 0; i < g_pUniverse->GetItemTypeCount(); i++)
			{
			CItemType *pWeaponType = g_pUniverse->GetItemType(i);
			CDeviceClass *pClass;
			if (pClass = pWeaponType->GetDeviceClass())
				{
				int iWeaponVariant;
				if ((iWeaponVariant = pClass->GetAmmoVariant(pType)) != -1)
					{
					CWeaponClass *pWeapon = dynamic_cast<CWeaponClass *>(pClass);
					if (pWeapon)
						return pWeapon->GetVariant(iWeaponVariant);
					}
				}
			}

		return NULL;
		}

	//	Otherwise, nothing

	else
		return NULL;
	}