ALERROR CEnhancerClass::CreateFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc, CItemType *pType, CDeviceClass **retpDevice) // CreateFromXML // // Load device data from XML { ALERROR error; CEnhancerClass *pDevice; pDevice = new CEnhancerClass; if (pDevice == NULL) return ERR_MEMORY; if (error = pDevice->InitDeviceFromXML(Ctx, pDesc, pType)) return error; // The old style is to have an array of damage adj; the new way is to just // have a single damage adj and a criteria int iDamageAdjCount; LoadDamageAdj(pDesc, DAMAGE_ADJ_ATTRIB, pDevice->m_iDamageAdjArray, &iDamageAdjCount); if (iDamageAdjCount) pDevice->m_bUseArray = true; else { pDevice->m_iDamageAdj = pDesc->GetAttributeInteger(HP_BONUS_ATTRIB); pDevice->m_bUseArray = false; } pDevice->m_iPowerUse = pDesc->GetAttributeInteger(POWER_USE_ATTRIB); pDevice->m_sEnhancementType = pDesc->GetAttribute(ENHANCEMENT_TYPE_ATTRIB); pDevice->m_iActivateAdj = pDesc->GetAttributeIntegerBounded(ACTIVATE_ADJ_ATTRIB, 1, -1, 100); pDevice->m_iMinActivateDelay = pDesc->GetAttributeIntegerBounded(MIN_ACTIVATE_DELAY_ATTRIB, 0, -1, 0); pDevice->m_iMaxActivateDelay = pDesc->GetAttributeIntegerBounded(MAX_ACTIVATE_DELAY_ATTRIB, 0, -1, 0); // Load the item criteria CString sCriteria; if (!pDesc->FindAttribute(CRITERIA_ATTRIB, &sCriteria)) sCriteria = CONSTLIT("w"); CItem::ParseCriteria(sCriteria, &pDevice->m_Criteria); // Done *retpDevice = pDevice; 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; }
ALERROR CEnergyFieldType::OnCreateFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc) // OnCreateFromXML // // Create from XML { ALERROR error; // Effect CXMLElement *pEffect = pDesc->GetContentElementByTag(EFFECT_TAG); if (pEffect) { if (error = CEffectCreator::CreateFromXML(Ctx, pEffect, strPatternSubst(CONSTLIT("%d:e"), GetUNID()), &m_pEffect)) { Ctx.sError = strPatternSubst(CONSTLIT("energy field %x: Unable to load effect"), GetUNID()); return error; } } pEffect = pDesc->GetContentElementByTag(HIT_EFFECT_TAG); if (pEffect == NULL) pEffect = pDesc->GetContentElementByTag(EFFECT_WHEN_HIT_TAG); if (pEffect) { if (error = CEffectCreator::CreateFromXML(Ctx, pEffect, strPatternSubst(CONSTLIT("%d:h"), GetUNID()), &m_pHitEffect)) { Ctx.sError = strPatternSubst(CONSTLIT("energy field %x: Unable to load hit effect"), GetUNID()); return error; } // For compatibility with previous versions, if we're using the old // <ShipEnergyFieldType> then altEffect defaults to TRUE. Otherwise, for new // <OverlayType> altEffect defaults to false. bool bAltEffect; if (pEffect->FindAttributeBool(ALT_EFFECT_ATTRIB, &bAltEffect)) m_bAltHitEffect = bAltEffect; else m_bAltHitEffect = strEquals(pDesc->GetTag(), SHIP_ENERGY_FIELD_TYPE_TAG); } else m_bAltHitEffect = false; // Rotation m_bRotateWithShip = !pDesc->GetAttributeBool(IGNORE_SHIP_ROTATION_ATTRIB); // Damage adjustment LoadDamageAdj(pDesc, ABSORB_ADJ_ATTRIB, m_iAbsorbAdj); // Bonus adjustment LoadDamageAdj(pDesc, BONUS_ADJ_ATTRIB, m_iBonusAdj); // Load the weapon suppress if (error = m_WeaponSuppress.InitFromXML(pDesc->GetAttribute(WEAPON_SUPPRESS_ATTRIB))) { Ctx.sError = CONSTLIT("Unable to load weapon suppress attribute"); return error; } // Keep track of the events that we have m_bHasOnUpdateEvent = FindEventHandler(ON_UPDATE_EVENT); // Done return NOERROR; }
ALERROR COverlayType::OnCreateFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc) // OnCreateFromXML // // Create from XML { ALERROR error; // Effect CXMLElement *pEffect = pDesc->GetContentElementByTag(EFFECT_TAG); if (pEffect) { if (error = CEffectCreator::CreateFromXML(Ctx, pEffect, strPatternSubst(CONSTLIT("%d:e"), GetUNID()), &m_pEffect)) { Ctx.sError = strPatternSubst(CONSTLIT("energy field %x: Unable to load effect"), GetUNID()); return error; } } pEffect = pDesc->GetContentElementByTag(HIT_EFFECT_TAG); if (pEffect == NULL) pEffect = pDesc->GetContentElementByTag(EFFECT_WHEN_HIT_TAG); if (pEffect) { if (error = CEffectCreator::CreateFromXML(Ctx, pEffect, strPatternSubst(CONSTLIT("%d:h"), GetUNID()), &m_pHitEffect)) { Ctx.sError = strPatternSubst(CONSTLIT("energy field %x: Unable to load hit effect"), GetUNID()); return error; } // For compatibility with previous versions, if we're using the old // <ShipEnergyFieldType> then altEffect defaults to TRUE. Otherwise, for new // <OverlayType> altEffect defaults to false. bool bAltEffect; if (pEffect->FindAttributeBool(ALT_EFFECT_ATTRIB, &bAltEffect)) m_fAltHitEffect = bAltEffect; else m_fAltHitEffect = strEquals(pDesc->GetTag(), SHIP_ENERGY_FIELD_TYPE_TAG); } else m_fAltHitEffect = false; // Rotation m_fRotateWithShip = !pDesc->GetAttributeBool(IGNORE_SHIP_ROTATION_ATTRIB); // Damage adjustment int iAbsorbCount; LoadDamageAdj(pDesc, ABSORB_ADJ_ATTRIB, m_iAbsorbAdj, &iAbsorbCount); // Bonus adjustment LoadDamageAdj(pDesc, BONUS_ADJ_ATTRIB, m_iBonusAdj); // Load the weapon suppress if (error = m_WeaponSuppress.InitFromXML(pDesc->GetAttribute(WEAPON_SUPPRESS_ATTRIB))) { Ctx.sError = CONSTLIT("Unable to load weapon suppress attribute"); return error; } // Keep track of the events that we have m_fHasOnUpdateEvent = FindEventHandler(ON_UPDATE_EVENT); // Are we a field/shield overlay (or part of hull)? // By default, we are a shield overlay if we absorb damage. bool bValue; if (pDesc->FindAttributeBool(SHIELD_OVERLAY_ATTRIB, &bValue)) m_fShieldOverlay = bValue; else m_fShieldOverlay = (iAbsorbCount > 0); // Counter CXMLElement *pCounter = pDesc->GetContentElementByTag(COUNTER_TAG); if (pCounter) { CString sStyle = pCounter->GetAttribute(STYLE_ATTRIB); if (strEquals(sStyle, COUNTER_PROGRESS)) m_iCounterType = counterProgress; else if (strEquals(sStyle, COUNTER_RADIUS)) m_iCounterType = counterRadius; else { Ctx.sError = strPatternSubst(CONSTLIT("Unknown counter style: %s"), sStyle); return ERR_FAIL; } m_sCounterLabel = pCounter->GetAttribute(LABEL_ATTRIB); m_iCounterMax = pCounter->GetAttributeIntegerBounded(MAX_ATTRIB, 0, -1, 100); m_wCounterColor = ::LoadRGBColor(pCounter->GetAttribute(COLOR_ATTRIB)); } else { m_iCounterType = counterNone; m_iCounterMax = 0; m_wCounterColor = 0; } // Options m_fDisarmShip = pDesc->GetAttributeBool(DISARM_ATTRIB); m_fParalyzeShip = pDesc->GetAttributeBool(PARALYZE_ATTRIB); m_fDisableShipScreen = pDesc->GetAttributeBool(DISABLE_SHIP_SCREEN_ATTRIB); m_fSpinShip = pDesc->GetAttributeBool(SPIN_ATTRIB); int iDrag; if (pDesc->FindAttributeInteger(DRAG_ATTRIB, &iDrag)) m_rDrag = Min(Max(0, iDrag), 100) / 100.0; else m_rDrag = 1.0; // Done return NOERROR; }