My next goal was to start working with actual spell objects. I sketched my ideas on a paper and decided that there would be a single Spell class that could be parametrized to handle various spells. And the first step to creating that class would be targeting characters with spells.
I started writing following test:
def test_target_single(self): """ Targeting a single character should be possible """ level = LevelBuilder().build() character = (CharacterBuilder() .with_level(level) .with_location((5, 5)) .build()) spell_generator = SpellGeneratorBuilder().build() spell = spell_generator.create_spell(spell_name = 'healing wind', target = character) assert_that(character, is_in(spell.target))
Nothing too complicated. My focus will be on healing wind spell and after I get it working, I can start from the beginning and see what needs to be changed to get magic missile working. You may notice that target attribute is a list of some sort, instead of just a single entity. I’m jumping forward a bit here, but I know already that I want spells that can target multiple characters and felt that it makes sense to write the system to support that from the beginning.
The code needed to make the test pass is simple:
class Spell(): """ Class to represent spells .. versionadded:: 0.9 """ def __init__(self): """ Default constructor """ self.target =  class SpellGenerator(): """ Factory for creating spells .. versionadded:: 0.9 """ @logged def __init__(self): """ Default constructor """ pass @logged def create_spell(self, spell_name, target): """ Create a spell :param spell_name: name of the spell :type spell_name: string :param target: target of the spell :type target: Character :returns: ready to use spell :rtype: Spell """ new_spell = Spell() new_spell.target.append(target) return new_spell
SpellGenerator will be the most used interface for the spell subsystem. It can be used to create all the different spells.
Code for this can be found from commit 112e9a77654490e0c8875c23572aa561bf35462d