Jump to content
  • Advertisement
Sign in to follow this  
SEnergy

[Game] Buffs increasing damage?

This topic is 2520 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

well, I started to make a game, but I have a little "problem" here, how can I make a spell/buff that will increase damage of next spell?

[/font]

[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

so let's say I have spell "Flaming Hands" that will increase fire damage by 100% for the next 10 sec, now, I wanna cast Fireball that will deal intellect*2 damage, sooo, I discovered only 1 way how to do this:

[/font]

http://pastebin.com/1iJq6pMx

[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

so, I don't know if this is a good way, cuz I have to write all the buffs there etc, so, can someone who already have created some RPG help me? or give me better idea or something?

[/font]

[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]

Thanks!

[/font]

Share this post


Link to post
Share on other sites
Advertisement
In my game I have it something like this:


class Power {
public:

// Iterates through modifiers_.value() and returns the sum total value. calls check_timestamp()
// for each modifier
int TotalOfModifiers();

private:
List<Modifier*> modifiers_;
// compares modifier.time_length() to modifier.timestamp() and pops the node if the modifier has expired
void CheckTimestamp_();
}

class Modifier {
public:

//accessors
int value();
// returns number of turns the effect lasts for
int time_length();
// returns the timestamp from when modifier was added
int timestamp();

private:
int value_;
int time_length_;
int timestamp_;


Basically, my characters, spells, equipment etc all have modifier lists in them. I also extended the modifier class to store the name of the modifier, icon, source, visual effect etc....

I'm sure there's a more elegant way to accomplish this, but this one at least works for me. And it works for bonuses from equipment, terrain, buffing spells etc.

Share this post


Link to post
Share on other sites
I use an attribute modifier system myself. A character has a set of base attributes which match all the buffs/debuffs in the system. So, for instance, the starting set of attributes for a player is: fire damage=1, cold damage=1, etc. When a spell is cast it says: "damage = caster_attrib[ fire_damage ] * spell[ fire_damage ]". Instead of listing "all" such attributes though, they are all assumed to be "1" if they don't exist in modified form. What this does is solves a LOT of different problems:

1. For your problem, the assumption is that under most circumstances the player/npc/whomever won't have a corresponding attribute so you just use 1 * the normal damage.
2. When you apply your buff you add 1 to the current attribute on the player. So, if the player does not have a "fire damage", assign one with 2*current value (which will be 200% total).

That takes care of the "buff", it just says while I'm active, multiply fire damage by 2, when I go away, go back to normal. What else this does for you though is include debuff's, equipment modifiers, etc. (NOTE: you generally want to recompute everything when there is a change, don't rely on *2 and /2 as things come and go, floating point error sucks and such a simple system leaves less flexibility.) So, in general, each attribute becomes a list of effects and you can use this to take care of all sorts of things:

3. Debuffed fire damage: same as the buff, just with /2 as the effect on the entities fire damage as an example.
4. Allows all equations to reflect receivers values also. I.e. instead of just "damage = me[ fire_damage ] * spell[ fire_damage ]" it can be "damage = me[ fire_damage ] * spell[ fire_damage ] * target[ fire_resist ]". All using the same system without constantly customizing code.
5. Completely expandable, add "cartoon_damage" type to a spell and everyone starts with a 1 by default. When you get around to adding proper buffs/debuffs etc, they all work the same way.
6. Boss fights with non-avoidable damage types work the same as all the above, just assign all boss abilities to a non-existing attribute. (I.e. always 1.)


Code wise this basically means the following is your damage effect:


struct FireDamageEffect
{
void operator ()( Entity& src, Entity& dst ) const
{
dst.TakeDamage( src[ kFireDamageModifier ] * mSpellDamage * dst[ kFireDamageResist ] );
}

float mSpellDamage;
};


Most of the time I'm using FastDelegates for this or boost::bind/tr1::bind so I don't even bother with the above structure. I just queue a function call such as:


CombatManager::TriggerEffect(
boost::bind(
&Spell::operator (), spell, source, dest
)
);


Which then calls into the spell functor which as follows:


class Spell
{
public:
void operator ()( Entity_t& src, Entity_t& dst ) const
{
dst.TakeDamage(
src[ kModifierFireDamage ] * mDamage * dst[ kModifierFireResist ] );
}

float mDamage;
};


The supplied code cuts out a lot of trivial details but the key item is that you leave all the effect properties and how to deal with them decentralized and the description of the spell itself is just a mixin to make it all work as appropriate. The spell itself only supplies the basic information of how much of a given type of damage will be done. The equation applied can be very complicated if you want, this is just a very simple example. I've used the pattern though such that for instance it can easily cover "immune to next spell, no matter what it is", "200% debuff to fire", etc. It is almost purely data driven so the goofy things designers may want to do doesn't effect the code in any notable way unless they want a new damage equation. The attributes are not part of the object definitions, they only exist in response to external input (i.e. attribute on armor item, natural attribute of race, buff, debuff, whatever).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!