Exemple #1
0
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());
	}
Exemple #2
0
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;
}