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(); }
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; }
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; }