storing spells and effects

Started by
4 comments, last by sefo 15 years, 8 months ago
Hi, In C++, what are my solutions to store 200+ spells and effects? (each spell is to be triggered by clicking on a button) Ideally I'd like to have 2 structures:

struct spell {
	int id;
	string name;
	int cost;
	int effect[5]; //effect IDs, max 5 effects for each spell
}

struct effect {
	int id;
	int remLife; //optional damage to target
	int addLife; //optional heal target if heal spell
	int poison; //points to lose each turn if poisoned
	//...and additional effects...
}
To store the effects I'd like to avoid XML and use "arrays" harcoded in a header file. How should I go to store data of different types?
Advertisement
I would suggest using XML anyway, because it's a much easier format to work with than C++ source code, but you can still transform XML into a bit of C++ source that initializes the appropriate data.

For instance, consider the following XML file:

<spell id="SPELL_FIREBALL"        name="fireball"       cost="10">  <effect-fire damage="20" />  <effect-blast radius="10" damage="5" /></spell><spell id="SPELL_POISON_LANCE"       name="poison lance"       cost="5">  <effect-poison damage="3" duration="10" /></spell>


You can easily and automatically turn this XML file into a C++ header file:

class Spells{public:  enum SpellID =   { // BEGIN GENERATED CODE    SPELL_FIREBALL,     SPELL_POISON_LANCE,// END GENERATED CODE    NUM_SPELLS  };private:  Spell spells[NUM_SPELLS];public:  const Spell &operator[](SpellID id)  {    assert (id >= 0 && id < NUM_SPELLS);    return spells[id];  }  Spells()   {// BEGIN GENERATED CODE    {      Spell s("fireball", 10);      s.effects.push_back(new FireEffect(20));      s.effects.push_back(new BlastEffect(10, 5));      spells[SPELL_FIREBALL] = s;    }    {      Spell s("poison lance", 5);      s.effects.push_back(new PoisonEffect(3, 10));      spells[SPELL_POISON_LANCE] = s;    }// END GENERATED CODE  }};


An example of XSLT code to do the transform would be:

<xsl:template match="/">  class Spells{public:  enum SpellID =   { // BEGIN GENERATED CODE  <xsl:for-each select="spell">    <xsl:value-of select="@id"/>,  </xsl:for-each>// END GENERATED CODE    NUM_SPELLS  };private:  Spell spells[NUM_SPELLS];public:  const Spell &operator[](SpellID id)  {    assert (id >= 0 && id < NUM_SPELLS);    return spells[id];  }  Spells()   {// BEGIN GENERATED CODE  <xsl:for-each select="spell">        {      Spell s("<xsl:value-of select="@name"/>", <xsl:value-of select="@cost"/>);      <xsl:apply-templates />            s.effects.push_back(new BlastEffect(10, 5));      spells[<xsl:value-of select="@id"/>] = s;    }  </xsl:for-each>// END GENERATED CODE  }};<xsl:template><xsl:template match="spell/effect-fire">  s.effects.push_back(new FireEffect(    <xsl:value-of select="@damage"/>  ));</xsl:template><xsl:template match="spell/effect-blast">  s.effects.push_back(new BlastEffect(    <xsl:value-of select="@damage"/>,    <xsl:value-of select="@radius"/>  ));</xsl:template><xsl:template match="spell/effect-poison">  s.effects.push_back(new PoisonEffect(    <xsl:value-of select="@damage"/>,    <xsl:value-of select="@duration"/>  ));</xsl:template>
That's very helpful code, thanks

Though, it's not very convenient if I want to add a new spell or just modify one, I have to change the XML, do the transform again, replace the source and recompile. Moreover the header file is going to be huge and hard to read.

I think it's a very good solution for a small database, but I was looking for something a little more low-level, like a binary file or something.

I'm sure I can reuse your code somehow though, cheers for that.

~
You could store the information in an array of structures and read it from a data file. You would need to write an editor to create/edit the data file, but this is the best way to go about it in my opinion. It works great for me anyways :).
Quote:Original post by sefo
To store the effects I'd like to avoid XML and use "arrays" harcoded in a header file.
Hard coding *anything* is going to come back and bite you in the arse at some point in the future. While I view XML as bloated and overrated, *anything* is preferable to hardcoding. Maybe look into JSON (a lightweight XML alternative), or roll your own binary format.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Thanks for all the feedbacks.
I think I'll just go with an array of structures generated from a file as VBStrider suggested.

I also like ToohrVyk's code and will surely find a place for it.

~

This topic is closed to new replies.

Advertisement