void CRandomItems::AddItems (SItemAddCtx &Ctx) // AddItems // // Add items { int i, j; int iRoll = mathRandom(1, 1000); bool bAllAtOnce = (m_iDamaged == 0 && m_Enhanced.GetChance() == 0); for (i = 0; i < m_iCount; i++) { iRoll -= m_Table[i].iProbability; if (iRoll <= 0) { CItemType *pType = m_Table[i].pType; int iCount = pType->GetNumberAppearing().Roll(); // If we don't have a chance of enhancement or damage, just optimize the // result by adding a group of items. if (bAllAtOnce) Ctx.ItemList.AddItem(CItem(m_Table[i].pType, iCount)); // If this is armor, then treat them as a block else if (pType->GetCategory() == itemcatArmor) { CItem Item(m_Table[i].pType, iCount); if (mathRandom(1, 100) <= m_iDamaged) Item.SetDamaged(); else m_Enhanced.EnhanceItem(Item); Ctx.ItemList.AddItem(Item); } // Otherwise, enhance/damage each item individually else { for (j = 0; j < iCount; j++) { CItem Item(m_Table[i].pType, 1); if (mathRandom(1, 100) <= m_iDamaged) Item.SetDamaged(); else m_Enhanced.EnhanceItem(Item); Ctx.ItemList.AddItem(Item); } } break; } } }
ALERROR CSingleItem::LoadFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc) // LoadFromXML // // Load from XML { ALERROR error; if (error = m_pItemType.LoadUNID(Ctx, pDesc->GetAttribute(ITEM_ATTRIB))) return error; m_iDamaged = pDesc->GetAttributeInteger(DAMAGED_ATTRIB); m_bDebugOnly = pDesc->GetAttributeBool(DEBUG_ONLY_ATTRIB); if (m_pItemType.GetUNID() == 0) { CString sUNID = pDesc->GetAttribute(ITEM_ATTRIB); if (sUNID.IsBlank()) Ctx.sError = strPatternSubst(CONSTLIT("<Item> element missing item attribute.")); else Ctx.sError = strPatternSubst(CONSTLIT("Invalid item UNID: %s"), sUNID); return ERR_FAIL; } if (error = m_Enhanced.InitFromXML(Ctx, pDesc)) return error; return NOERROR; }
ALERROR CRandomItems::LoadFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc) // LoadFromXML // // Load from XML { ALERROR error; CString sCriteria = pDesc->GetAttribute(CRITERIA_ATTRIB); if (sCriteria.IsBlank()) { CString sAttributes = pDesc->GetAttribute(ATTRIBUTES_ATTRIB); if (sAttributes.IsBlank()) sAttributes = pDesc->GetAttribute(MODIFIERS_ATTRIB); sCriteria = strPatternSubst(CONSTLIT("%s %s"), pDesc->GetAttribute(CATEGORIES_ATTRIB), sAttributes); } CItem::ParseCriteria(sCriteria, &m_Criteria); m_sLevelFrequency = pDesc->GetAttribute(LEVEL_FREQUENCY_ATTRIB); m_iLevel = pDesc->GetAttributeInteger(LEVEL_ATTRIB); m_iLevelCurve = pDesc->GetAttributeInteger(LEVEL_CURVE_ATTRIB); m_iDamaged = pDesc->GetAttributeInteger(DAMAGED_ATTRIB); if (error = m_Enhanced.InitFromXML(Ctx, pDesc)) return error; m_Table = NULL; m_iCount = 0; return NOERROR; }
void CSingleItem::AddItems (SItemAddCtx &Ctx) // AddItems // // Add items { // Ignore if not debugging if (m_bDebugOnly && !g_pUniverse->InDebugMode()) return; // Create item CItem NewItem(m_pItemType, 1); if (mathRandom(1, 100) <= m_iDamaged) NewItem.SetDamaged(); else m_Enhanced.EnhanceItem(NewItem); Ctx.ItemList.AddItem(NewItem); }
ALERROR CSingleDevice::LoadFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc) // LoadFromXML // // Load from XML { ALERROR error; // Load the item type CString sUNID = pDesc->GetAttribute(DEVICE_ID_ATTRIB); if (sUNID.IsBlank()) sUNID = pDesc->GetAttribute(ITEM_ATTRIB); if (error = m_pItemType.LoadUNID(Ctx, sUNID)) return error; if (m_pItemType.GetUNID() == 0) { Ctx.sError = strPatternSubst(CONSTLIT("<%s> element missing item attribute."), pDesc->GetTag()); return ERR_FAIL; } // Load the count m_Count.LoadFromXML(pDesc->GetAttribute(COUNT_ATTRIB)); if (m_Count.IsEmpty()) m_Count.SetConstant(1); // Load damage chance m_iDamaged = pDesc->GetAttributeInteger(DAMAGED_ATTRIB); // Load enhancement chance if (error = m_Enhanced.InitFromXML(Ctx, pDesc)) return error; // Load device position attributes if (pDesc->FindAttributeInteger(POS_Z_ATTRIB, &m_iPosZ)) { m_iPosAngle = pDesc->GetAttributeInteger(POS_ANGLE_ATTRIB); m_iPosRadius = pDesc->GetAttributeInteger(POS_RADIUS_ATTRIB); m_b3DPosition = true; m_bDefaultPos = false; } else if (pDesc->FindAttributeInteger(POS_ANGLE_ATTRIB, &m_iPosAngle)) { m_iPosRadius = pDesc->GetAttributeInteger(POS_RADIUS_ATTRIB); m_iPosZ = 0; m_b3DPosition = false; m_bDefaultPos = false; } else { m_iPosAngle = 0; m_iPosRadius = 0; m_iPosZ = 0; m_b3DPosition = false; m_bDefaultPos = true; } // Load fire arc attributes if (pDesc->FindAttributeInteger(MIN_FIRE_ARC_ATTRIB, &m_iMinFireArc)) { m_bOmnidirectional = false; m_iMaxFireArc = pDesc->GetAttributeInteger(MAX_FIRE_ARC_ATTRIB); m_bDefaultFireArc = false; } else if (pDesc->FindAttributeBool(OMNIDIRECTIONAL_ATTRIB, &m_bOmnidirectional)) { m_iMinFireArc = 0; m_iMaxFireArc = 0; m_bDefaultFireArc = false; } else { m_bOmnidirectional = false; m_iMinFireArc = 0; m_iMaxFireArc = 0; m_bDefaultFireArc = true; } // Linked fire options CString sLinkedFire; if (pDesc->FindAttribute(LINKED_FIRE_ATTRIB, &sLinkedFire)) { if (error = CDeviceClass::ParseLinkedFireOptions(Ctx, sLinkedFire, &m_dwLinkedFireOptions)) return error; m_bDefaultLinkedFire = false; } else { m_dwLinkedFireOptions = 0; m_bDefaultLinkedFire = true; } m_bSecondary = pDesc->GetAttributeBool(SECONDARY_WEAPON_ATTRIB); // Slot bonus if (pDesc->FindAttributeInteger(HP_BONUS_ATTRIB, &m_iSlotBonus)) m_bDefaultSlotBonus = false; else { m_iSlotBonus = 0; m_bDefaultSlotBonus = true; } // Load extra items CXMLElement *pItems = pDesc->GetContentElementByTag(ITEMS_TAG); if (pItems) { if (error = IItemGenerator::CreateFromXML(Ctx, pItems, &m_pExtraItems)) return error; } return NOERROR; }
void CSingleDevice::AddDevices (SDeviceGenerateCtx &Ctx) // AddDevices // // Add devices to list { int i; if (m_pItemType == NULL) return; int iCount = m_Count.Roll(); for (i = 0; i < iCount; i++) { // Initialize the desc SDeviceDesc Desc; Desc.Item = CItem(m_pItemType, 1); if (mathRandom(1, 100) <= m_iDamaged) Desc.Item.SetDamaged(); else m_Enhanced.EnhanceItem(Desc.Item); // Find the default settings for the device slot for this device SDeviceDesc SlotDesc; bool bUseSlotDesc = (Ctx.pRoot ? Ctx.pRoot->FindDefaultDesc(Desc.Item, &SlotDesc) : false); // Set the device position appropriately, either from the <Device> element, // from the slot descriptor at the root, or from defaults. if (!m_bDefaultPos) { Desc.iPosAngle = m_iPosAngle; Desc.iPosRadius = m_iPosRadius; Desc.iPosZ = m_iPosZ; Desc.b3DPosition = m_b3DPosition; } else if (bUseSlotDesc) { Desc.iPosAngle = SlotDesc.iPosAngle; Desc.iPosRadius = SlotDesc.iPosRadius; Desc.iPosZ = SlotDesc.iPosZ; Desc.b3DPosition = SlotDesc.b3DPosition; } // Set the device fire arc appropriately. if (!m_bDefaultFireArc) { Desc.bOmnidirectional = m_bOmnidirectional; Desc.iMinFireArc = m_iMinFireArc; Desc.iMaxFireArc = m_iMaxFireArc; } else if (bUseSlotDesc) { Desc.bOmnidirectional = SlotDesc.bOmnidirectional; Desc.iMinFireArc = SlotDesc.iMinFireArc; Desc.iMaxFireArc = SlotDesc.iMaxFireArc; } // Set linked fire if (!m_bDefaultLinkedFire) Desc.dwLinkedFireOptions = m_dwLinkedFireOptions; else if (bUseSlotDesc) Desc.dwLinkedFireOptions = SlotDesc.dwLinkedFireOptions; else Desc.dwLinkedFireOptions = 0; Desc.bSecondary = m_bSecondary; // Slot bonus if (!m_bDefaultSlotBonus) Desc.iSlotBonus = m_iSlotBonus; else if (bUseSlotDesc) Desc.iSlotBonus = SlotDesc.iSlotBonus; else Desc.iSlotBonus = 0; // Add extra items if (m_pExtraItems) { CItemListManipulator ItemList(Desc.ExtraItems); SItemAddCtx ItemCtx(ItemList); ItemCtx.iLevel = Ctx.iLevel; m_pExtraItems->AddItems(ItemCtx); } // Done Ctx.pResult->AddDeviceDesc(Desc); } }