ALERROR CIntSet::AddElement (int iElement) // AddElement // // Adds an element to the set { ALERROR error; DWORD dwBucket = ((DWORD)iElement) / g_BitsPerBucket; // Look for the bucket; if we don't find it, add a new one CIntArray *pBucket; if (error = m_Set.Lookup(dwBucket, (CObject **)&pBucket)) { pBucket = new CIntArray; if (pBucket == NULL) return ERR_MEMORY; if (error = m_Set.AddEntry(dwBucket, pBucket)) { delete pBucket; return error; } } // Look for the bit in the bucket DWORD dwBucketBit = ((DWORD)iElement) % g_BitsPerBucket; DWORD dwOffset = dwBucketBit / 32; // Make sure there is room in the bucket if ((int)dwOffset >= pBucket->GetCount()) { int iOldCount = pBucket->GetCount(); int iExpandBy = ((int)dwOffset + 1) - iOldCount; if (error = pBucket->ExpandArray(-1, iExpandBy)) return error; for (int i = iOldCount; i < pBucket->GetCount(); i++) pBucket->ReplaceElement(i, 0); } // OR-in the new element DWORD dwBit = dwBucketBit % 32; DWORD dwNewValue = ((DWORD)pBucket->GetElement(dwOffset)) | (1 << dwBit); pBucket->ReplaceElement(dwOffset, dwNewValue); return NOERROR; }
void CIntSet::RemoveElement (int iElement) // RemoveElement // // Removes the given element in the set { DWORD dwBucket = ((DWORD)iElement) / g_BitsPerBucket; // Look for the bucket CIntArray *pBucket; if (m_Set.Lookup(dwBucket, (CObject **)&pBucket) != NOERROR) return; DWORD dwBucketBit = ((DWORD)iElement) % g_BitsPerBucket; DWORD dwOffset = dwBucketBit / 32; if ((int)dwOffset >= pBucket->GetCount()) return; DWORD dwBit = dwBucketBit % 32; DWORD dwNewValue = ((DWORD)pBucket->GetElement(dwOffset)) & ~(1 << dwBit); pBucket->ReplaceElement(dwOffset, dwNewValue); }
ALERROR CIntSet::EnumElements (CIntArray *pArray) const // EnumElements // // Fills in the given array with an enumeration of all the // elements in the set. { ALERROR error; // Loop over all buckets int i; for (i = 0; i < m_Set.GetCount(); i++) { DWORD dwBucket = (DWORD)m_Set.GetKey(i) * (DWORD)g_BitsPerBucket; CIntArray *pBucket = (CIntArray *)m_Set.GetValue(i); // Now look over all elements in the bucket int j; for (j = 0; j < pBucket->GetCount(); j++) { DWORD dwElement = (DWORD)pBucket->GetElement(j); if (dwElement != 0) { // Iterate over all bits int k; DWORD dwTest = 1; for (k = 0; k < 32; k++) { if (dwElement & dwTest) { if (error = pArray->AppendElement(dwBucket + (DWORD)(j * 32 + k), NULL)) return error; } dwTest = dwTest << 1; } } } } return NOERROR; }
bool CIntSet::HasElement (int iElement) const // HasElement // // Returns TRUE if the set has the given element { DWORD dwBucket = ((DWORD)iElement) / g_BitsPerBucket; // Look for the bucket CIntArray *pBucket; if (m_Set.Lookup(dwBucket, (CObject **)&pBucket) != NOERROR) return false; DWORD dwBucketBit = ((DWORD)iElement) % g_BitsPerBucket; DWORD dwOffset = dwBucketBit / 32; if ((int)dwOffset >= pBucket->GetCount()) return false; DWORD dwBit = dwBucketBit % 32; return (((DWORD)pBucket->GetElement(dwOffset)) & (1 << dwBit) ? true : false); }
ALERROR CShieldClass::CreateFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc, CItemType *pType, CDeviceClass **retpShield) // CreateFromXML // // Creates from an XML element { ALERROR error; CShieldClass *pShield; int i; pShield = new CShieldClass; if (pShield == NULL) return ERR_MEMORY; if (error = pShield->InitDeviceFromXML(Ctx, pDesc, pType)) return error; pShield->m_iHitPoints = pDesc->GetAttributeInteger(HIT_POINTS_ATTRIB); pShield->m_iArmorShield = pDesc->GetAttributeInteger(ARMOR_SHIELD_ATTRIB); pShield->m_iPowerUse = pDesc->GetAttributeIntegerBounded(POWER_USE_ATTRIB, 0, -1, 0); pShield->m_iIdlePowerUse = pDesc->GetAttributeIntegerBounded(IDLE_POWER_USE_ATTRIB, 0, -1, pShield->m_iPowerUse / 2); pShield->m_iExtraHPPerCharge = pDesc->GetAttributeInteger(HP_ADJ_PER_CHARGE_ATTRIB); pShield->m_iExtraPowerPerCharge = pDesc->GetAttributeInteger(POWER_ADJ_PER_CHARGE_ATTRIB); pShield->m_iExtraRegenPerCharge = pDesc->GetAttributeInteger(REGEN_ADJ_PER_CHARGE_ATTRIB); pShield->m_iMaxCharges = pDesc->GetAttributeInteger(MAX_CHARGES_ATTRIB); // Load regen value CString sRegen; if (pDesc->FindAttribute(REGEN_ATTRIB, &sRegen)) { if (error = pShield->m_Regen.InitFromRegenString(Ctx, sRegen)) return error; int iDepletion; if (pDesc->FindAttributeInteger(DEPLETION_DELAY_ATTRIB, &iDepletion)) pShield->m_iDepletionTicks = Max(1, iDepletion); else pShield->m_iDepletionTicks = 360; } else { int iRegenTime = pDesc->GetAttributeInteger(REGEN_TIME_ATTRIB); if (error = pShield->m_Regen.InitFromRegenTimeAndHP(Ctx, iRegenTime, pDesc->GetAttributeInteger(REGEN_HP_ATTRIB))) return error; int iDepletion; if (pDesc->FindAttributeInteger(DEPLETION_DELAY_ATTRIB, &iDepletion)) pShield->m_iDepletionTicks = Max(1, iDepletion * iRegenTime); else pShield->m_iDepletionTicks = 360; } // Load damage adjustment pShield->m_iDamageAdjLevel = pDesc->GetAttributeIntegerBounded(DAMAGE_ADJ_LEVEL_ATTRIB, 1, MAX_ITEM_LEVEL, pType->GetLevel()); if (error = pShield->m_DamageAdj.InitFromXML(Ctx, pDesc)) return error; // Load absorb adjustment; if attribute not found, assume 100% for everything CString sAbsorbAdj; if (pDesc->FindAttribute(ABSORB_ADJ_ATTRIB, &sAbsorbAdj)) { CIntArray AbsorbAdj; if (error = ::ParseAttributeIntegerList(sAbsorbAdj, &AbsorbAdj)) return error; for (i = 0; i < damageCount; i++) pShield->m_iAbsorbAdj[i] = (i < AbsorbAdj.GetCount() ? AbsorbAdj.GetElement(i) : 0); } else { for (i = 0; i < damageCount; i++) pShield->m_iAbsorbAdj[i] = 100; } // Load the weapon suppress if (error = pShield->m_WeaponSuppress.InitFromXML(pDesc->GetAttribute(WEAPON_SUPPRESS_ATTRIB))) { Ctx.sError = CONSTLIT("Unable to load weapon suppress attribute"); return error; } // Load reflection if (error = pShield->m_Reflective.InitFromXML(pDesc->GetAttribute(REFLECT_ATTRIB))) { Ctx.sError = CONSTLIT("Unable to load reflective attribute"); return error; } // Effects if (error = pShield->m_pHitEffect.LoadEffect(Ctx, strPatternSubst(CONSTLIT("%d:h"), pType->GetUNID()), pDesc->GetContentElementByTag(HIT_EFFECT_TAG), pDesc->GetAttribute(HIT_EFFECT_ATTRIB))) return error; // Done *retpShield = pShield; return NOERROR; }
ALERROR CShieldClass::CreateFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc, CItemType *pType, CDeviceClass **retpShield) // CreateFromXML // // Creates from an XML element { ALERROR error; CShieldClass *pShield; int i; pShield = new CShieldClass; if (pShield == NULL) return ERR_MEMORY; pShield->InitDeviceFromXML(Ctx, pDesc, pType); pShield->m_iHitPoints = pDesc->GetAttributeInteger(HIT_POINTS_ATTRIB); pShield->m_iArmorShield = pDesc->GetAttributeInteger(ARMOR_SHIELD_ATTRIB); pShield->m_iPowerUse = pDesc->GetAttributeIntegerBounded(POWER_USE_ATTRIB, 0, -1, 0); pShield->m_iIdlePowerUse = pDesc->GetAttributeIntegerBounded(IDLE_POWER_USE_ATTRIB, 0, -1, pShield->m_iPowerUse / 2); pShield->m_iExtraHPPerCharge = pDesc->GetAttributeInteger(HP_ADJ_PER_CHARGE_ATTRIB); pShield->m_iExtraPowerPerCharge = pDesc->GetAttributeInteger(POWER_ADJ_PER_CHARGE_ATTRIB); pShield->m_iExtraRegenPerCharge = pDesc->GetAttributeInteger(REGEN_ADJ_PER_CHARGE_ATTRIB); pShield->m_iMaxCharges = pDesc->GetAttributeInteger(MAX_CHARGES_ATTRIB); // Load regen value int iRegen; if (pDesc->FindAttributeInteger(REGEN_ATTRIB, &iRegen)) { // Regen specified in hp per 180 ticks. We need to convert that to RegenHP and RegenRate if ((iRegen % 12) == 0) pShield->m_iRegenRate = 15; else if ((iRegen % 10) == 0) pShield->m_iRegenRate = 18; else if ((iRegen % 9) == 0) pShield->m_iRegenRate = 20; else if ((iRegen % 6) == 0) pShield->m_iRegenRate = 30; else if ((iRegen % 5) == 0) pShield->m_iRegenRate = 36; else if ((iRegen % 4) == 0) pShield->m_iRegenRate = 45; else if ((iRegen % 3) == 0) pShield->m_iRegenRate = 60; else pShield->m_iRegenRate = 90; pShield->m_iRegenHP = iRegen * pShield->m_iRegenRate / 180; int iDepletion; if (pDesc->FindAttributeInteger(DEPLETION_DELAY_ATTRIB, &iDepletion)) pShield->m_iDepletionDelay = iDepletion / pShield->m_iRegenRate; else pShield->m_iDepletionDelay = 360 / pShield->m_iRegenRate; } else { pShield->m_iRegenHP = pDesc->GetAttributeInteger(REGEN_HP_ATTRIB); pShield->m_iRegenRate = (int)((pDesc->GetAttributeInteger(REGEN_TIME_ATTRIB) / STD_SECONDS_PER_UPDATE) + 0.5); pShield->m_iDepletionDelay = pDesc->GetAttributeInteger(DEPLETION_DELAY_ATTRIB); if (pShield->m_iRegenRate == 0) { pShield->m_iRegenRate = 15; pShield->m_iRegenHP = 0; } } // Load damage adjustment pShield->m_iDamageAdjLevel = pDesc->GetAttributeIntegerBounded(DAMAGE_ADJ_LEVEL_ATTRIB, 1, MAX_ITEM_LEVEL, pType->GetLevel()); if (error = LoadDamageAdj(pDesc, g_StdDamageAdj[pShield->m_iDamageAdjLevel - 1], pShield->m_iDamageAdj)) return error; // Load absorb adjustment; if attribute not found, assume 100% for everything CString sAbsorbAdj; if (pDesc->FindAttribute(ABSORB_ADJ_ATTRIB, &sAbsorbAdj)) { CIntArray AbsorbAdj; if (error = ::ParseAttributeIntegerList(sAbsorbAdj, &AbsorbAdj)) return error; for (i = 0; i < damageCount; i++) pShield->m_iAbsorbAdj[i] = (i < AbsorbAdj.GetCount() ? AbsorbAdj.GetElement(i) : 0); } else { for (i = 0; i < damageCount; i++) pShield->m_iAbsorbAdj[i] = 100; } // Load the weapon suppress if (error = pShield->m_WeaponSuppress.InitFromXML(pDesc->GetAttribute(WEAPON_SUPPRESS_ATTRIB))) return error; // Load reflection if (error = pShield->m_Reflective.InitFromXML(pDesc->GetAttribute(REFLECT_ATTRIB))) return error; // Effects if (error = pShield->m_pHitEffect.LoadEffect(Ctx, strPatternSubst(CONSTLIT("%d:h"), pType->GetUNID()), pDesc->GetContentElementByTag(HIT_EFFECT_TAG), pDesc->GetAttribute(HIT_EFFECT_ATTRIB))) return error; // Done *retpShield = pShield; return NOERROR; }