DamageTypes GetDamageTypeFromArg (CCodeChain &CC, ICCItem *pArg) // GetDamageTypeFromArg // // Returns the damage type from an argument { if (pArg->IsInteger()) { int iDamage = pArg->GetIntegerValue(); if (iDamage < damageGeneric || iDamage >= damageCount) return damageError; return (DamageTypes)iDamage; } else return LoadDamageTypeFromXML(pArg->GetStringValue()); }
ALERROR CItemEnhancement::InitFromDesc (const CString &sDesc, CString *retsError) // InitFromDesc // // Initializes from a string of the following forms: // // {number} Interpret as a mod code // +armor:{n} Add armor special damage, where n is an item level // +hpBonus:{n} Add hp bonus. // +immunity:{s} Immunity to special damage s. // +reflect:{s} Reflects damage type s. // +regen Regenerate // +resist:{s}:{n} DamageAdj for type s set to n // +resistDamageClass:{s}:{n} DamageAdj for type s (and its next-tier mate) set to n // +resistDamageTier:{s}:{n} DamageAdj for type s (and its tier mate) set to n // +resistEnergy:{n} DamageAdj for energy damage set to n // +resistMatter:{n} DamageAdj for matter damage set to n // +shield:{n} Add shield disrupt special damage, where n is an item level // +speed:{n} Faster. n is new delay value as a percent of normal { // If the string is a number then we interpret it as a mod code. bool bFailed; DWORD dwCode = strToInt(sDesc, 0, &bFailed); if (!bFailed) { m_dwMods = dwCode; return NOERROR; } // Parse the string char *pPos = sDesc.GetASCIIZPointer(); // Expect either "+" or "-" (for disadvantage) bool bDisadvantage; if (*pPos == '+') bDisadvantage = false; else if (*pPos == '-') bDisadvantage = true; else { if (retsError) *retsError = CONSTLIT("Invalid enhancement description: expected '+' or '-'."); return ERR_FAIL; } pPos++; // Parse the enhancement name char *pStart = pPos; while (*pPos != ':' && *pPos != '\0') pPos++; CString sID(pStart, (int)(pPos - pStart)); // See if we have a value int iValue = 0; CString sValue; if (*pPos == ':') { pPos++; if (*pPos == '-' || *pPos == '+' || (*pPos >= '0' && *pPos <= '9')) iValue = strParseInt(pPos, 0, &pPos); else { char *pStart = pPos; while (*pPos != '\0' && *pPos != ':') pPos++; sValue = CString(pStart, (int)(pPos - pStart)); } } // See if we have a second value int iValue2 = 0; if (*pPos == ':') { pPos++; iValue2 = strParseInt(pPos, 0, &pPos); } // See if this is an hpBonus if (strEquals(sID, CONSTLIT("hpBonus"))) { if (bDisadvantage && iValue > 0) iValue = -iValue; if (iValue < -100) { if (retsError) *retsError = CONSTLIT("hpBonus penalty cannot exceed 100%."); return ERR_FAIL; } else if (iValue < 0) SetModCode(EncodeAX(etHPBonus | etDisadvantage, 0, -iValue)); else if (iValue == 0) SetModCode(Encode12(etStrengthen)); else if (iValue <= 1000) SetModCode(EncodeAX(etHPBonus, 0, iValue)); else { if (retsError) *retsError = CONSTLIT("hpBonus cannot exceed 1000%."); return ERR_FAIL; } } // Immunity else if (strEquals(sID, CONSTLIT("immunity"))) { if (strEquals(sValue, CONSTLIT("ionEffects"))) m_dwMods = Encode12(etImmunityIonEffects); else { SpecialDamageTypes iSpecial = DamageDesc::ConvertToSpecialDamageTypes(sValue); switch (iSpecial) { case specialRadiation: case specialBlinding: case specialEMP: case specialDeviceDamage: case specialDisintegration: case specialMomentum: case specialShieldDisrupt: case specialDeviceDisrupt: case specialShatter: { if (bDisadvantage) { if (retsError) *retsError = CONSTLIT("Disadvantage not supported."); return ERR_FAIL; } SetModImmunity(iSpecial); break; } default: { if (retsError) *retsError = strPatternSubst(CONSTLIT("Invalid immunity: %s"), sID); return ERR_FAIL; } } } } // Reflect bonus else if (strEquals(sID, CONSTLIT("reflect"))) { DamageTypes iDamageType = LoadDamageTypeFromXML(sValue); if (iDamageType == damageError) { if (retsError) *retsError = strPatternSubst(CONSTLIT("Invalid damage type: %s"), sValue); return ERR_FAIL; } SetModReflect(iDamageType); } // Regen else if (strEquals(sID, CONSTLIT("regen"))) { m_dwMods = Encode12(etRegenerate | (bDisadvantage ? etDisadvantage : 0)); } // Resist damage else if (strEquals(sID, CONSTLIT("resist"))) { DamageTypes iDamageType = LoadDamageTypeFromXML(sValue); if (iDamageType == damageError) { if (retsError) *retsError = strPatternSubst(CONSTLIT("Invalid damage type: %s"), sValue); return ERR_FAIL; } SetModResistDamage(iDamageType, iValue2); } // Resist damage else if (strEquals(sID, CONSTLIT("resistDamageClass"))) { DamageTypes iDamageType = LoadDamageTypeFromXML(sValue); if (iDamageType == damageError) { if (retsError) *retsError = strPatternSubst(CONSTLIT("Invalid damage type: %s"), sValue); return ERR_FAIL; } SetModResistDamageClass(iDamageType, iValue2); } // Resist damage tier else if (strEquals(sID, CONSTLIT("resistDamageTier"))) { DamageTypes iDamageType = LoadDamageTypeFromXML(sValue); if (iDamageType == damageError) { if (retsError) *retsError = strPatternSubst(CONSTLIT("Invalid damage type: %s"), sValue); return ERR_FAIL; } SetModResistDamageTier(iDamageType, iValue2); } // Resist energy/matter else if (strEquals(sID, CONSTLIT("resistEnergy"))) SetModResistEnergy(iValue); else if (strEquals(sID, CONSTLIT("resistMatter"))) SetModResistMatter(iValue); // Speed bonus else if (strEquals(sID, CONSTLIT("speed"))) { if (iValue <= 0) { if (retsError) *retsError = strPatternSubst(CONSTLIT("Invalid speed value: %s."), iValue); return ERR_FAIL; } else // LATER: Support min and max delay limits SetModSpeed(iValue); } // Otherwise, see if this is a special damage else { SpecialDamageTypes iSpecial = DamageDesc::ConvertToSpecialDamageTypes(sID); switch (iSpecial) { case specialArmor: case specialShieldDisrupt: { if (bDisadvantage) { if (retsError) *retsError = CONSTLIT("Disadvantage not supported."); return ERR_FAIL; } if (iValue < 1 || iValue > MAX_ITEM_LEVEL) { if (retsError) *retsError = strPatternSubst(CONSTLIT("Invalid %s damage level: %d"), sID, iValue); return ERR_FAIL; } SetModSpecialDamage(iSpecial, iValue); break; } default: { if (retsError) *retsError = strPatternSubst(CONSTLIT("Invalid enhancement name: %s"), sID); return ERR_FAIL; } } } // Done return NOERROR; }