iDamage and iDamageLimit in SpellInfos

Bringa

King
Joined
Jan 23, 2006
Messages
677
Hi,

how do iDamage and iDamageLimit in SpellInfos work? I thought they were absolute limits, but when I set MAX_HP to 1000 (for fair combat) and multiply these values by 10 as well, I get spells that are way too powerful.
 
Oh, thank you! How could I've missed that thread?

However, things don't behave as advertised. When I up the HP to 1000, ring of flames only does about 0.1 strength points of damage to a 10 strength units, even when it claims to have done 23% damage. Maybe there's a bug here?

edit: doing some more testing, it seems the damage is applied ABSOLUTELY, meaning when the spells says that a unit was damaged for 39%, it actually loses 39 hitpoints. When the spell rolls more than 100 points of damage, it simply kills the unit.

Do you think that last check could be adjusted to check not if the spell caused 100 points of damage but rather whether or not the unit is now at or below 0 hp?
 
Yeah 23% of 100 is 2.3% of 1000.

Code:
void CvUnit::castDamage(int spell)
{
    bool bResistable = GC.getSpellInfo((SpellTypes)spell).isResistable();
    int iDmg = GC.getSpellInfo((SpellTypes)spell).getDamage();
    int iDmgLimit = GC.getSpellInfo((SpellTypes)spell).getDamageLimit();
    int iDmgType = GC.getSpellInfo((SpellTypes)spell).getDamageType();
    int iRange = GC.getSpellInfo((SpellTypes)spell).getRange();
	CLLNode<IDInfo>* pUnitNode;
	CvUnit* pLoopUnit;
	CvPlot* pLoopPlot;
    for (int i = -iRange; i <= iRange; ++i)
    {
        for (int j = -iRange; j <= iRange; ++j)
        {
            pLoopPlot = ::plotXY(plot()->getX_INLINE(), plot()->getY_INLINE(), i, j);
            if (NULL != pLoopPlot)
            {
                if (pLoopPlot->getX() != plot()->getX() || pLoopPlot->getY() != plot()->getY())
                {
                    pUnitNode = pLoopPlot->headUnitNode();
                    while (pUnitNode != NULL)
                    {
                        pLoopUnit = ::getUnit(pUnitNode->m_data);
                        pUnitNode = pLoopPlot->nextUnitNode(pUnitNode);
                        if (!pLoopUnit->isImmuneToSpell(this, spell))
                        {
                            if (bResistable)
                            {
                                if (!pLoopUnit->isResisted(this, spell))
                                {
                                    pLoopUnit->doDamage((iDmg / 2) + GC.getGameINLINE().getSorenRandNum(iDmg, "doDamage"), iDmgLimit, this, iDmgType);
                                }
                            }
                            else
                            {
                                pLoopUnit->doDamage((iDmg / 2) + GC.getGameINLINE().getSorenRandNum(iDmg, "doDamage"), iDmgLimit, this, iDmgType);
                            }
                        }
                    }
                }
            }
        }
    }
}

Code:
void CvUnit::doDamage(int iDmg, int iDmgLimit, CvUnit* pAttacker, int iDmgType)
{
    CvWString szMessage;
    int iResist;

    iResist = baseCombatStr() *2;
    iResist += getLevel() * 2;
    if (iDmgType != -1)
    {
        iResist += getDamageTypeResist((DamageTypes)iDmgType);
    }
    if (pAttacker != NULL)
    {
        iDmg += pAttacker->getSpellDamageModify();
    }
    if (iResist < 100)
    {
        iResist *= -1;
        iDmg = GC.getGameINLINE().getSorenRandNum(iDmg, "Damage") + GC.getGameINLINE().getSorenRandNum(iDmg, "Damage");
		iDmg = iDmg * (iResist + 100) / 100;

        if (iDmg + getDamage() > iDmgLimit)
        {
            iDmg = iDmgLimit - getDamage();
        }
        if (iDmg > 0)
        {
            if (iDmg + getDamage() >= 100)
            {
                szMessage = gDLL->getText("TXT_KEY_MESSAGE_KILLED_BY", GC.getUnitInfo(getUnitType()).getDescription(), GC.getDamageTypeInfo((DamageTypes)iDmgType).getDescription());
            }
            else
            {
                szMessage = gDLL->getText("TXT_KEY_MESSAGE_DAMAGED_BY", GC.getUnitInfo(getUnitType()).getDescription(), iDmg, GC.getDamageTypeInfo((DamageTypes)iDmgType).getDescription());
            }
            gDLL->getInterfaceIFace()->addMessage(((PlayerTypes)getOwner()), true, GC.getDefineINT("EVENT_MESSAGE_TIME"), szMessage, "", MESSAGE_TYPE_MAJOR_EVENT, "Art/Interface/Buttons/Fire.dds", (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), getX_INLINE(), getY_INLINE(), true, true);
            if (pAttacker != NULL)
            {
                gDLL->getInterfaceIFace()->addMessage(((PlayerTypes)pAttacker->getOwner()), true, GC.getDefineINT("EVENT_MESSAGE_TIME"), szMessage, "", MESSAGE_TYPE_MAJOR_EVENT, GC.getDamageTypeInfo((DamageTypes)iDmgType).getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), getX_INLINE(), getY_INLINE(), true, true);
                changeDamage(iDmg, pAttacker->getOwner());
                if (getDamage() >= 100)
                {
                    kill(true,pAttacker->getOwner());
                }
                if (!(pAttacker->isHiddenNationality()) && !(isHiddenNationality()))
                {
                    if (getTeam() != pAttacker->getTeam())
                    {
                        GET_TEAM(pAttacker->getTeam()).declareWar(getTeam(), false, NO_WARPLAN);
                    }
                }
            }
            else
            {
                changeDamage(iDmg, NO_PLAYER);
                if (getDamage() >= 100)
                {
                    kill(true,NO_PLAYER);
                }
            }
        }
    }
}
 
Yeah, as I suspected. This here's the problem:

Code:
            if (iDmg + getDamage() >= 100)
            {
                szMessage = gDLL->getText("TXT_KEY_MESSAGE_KILLED_BY", GC.getUnitInfo(getUnitType()).getDescription(), GC.getDamageTypeInfo((DamageTypes)iDmgType).getDescription());
            }

This assumes MAX_HP set to 100. Could you fix this to say "if iDmg + getDamage() >= (whatever MAX_HP is set to in GlobalDefinesAlt)"?
 
Code:
 if (getDamage() >= 100)
                {
                    kill(true,pAttacker->getOwner());
                }

And this of course.
 
Top Bottom