3
\$\begingroup\$

Let W = wizard

Let 0 = Cast range of spell, or AOE

Here is the problem:

I have a 2D tile map of squares. Let's say I want to have a wizard cast a spell that surrounds his body equally. For this, it would be as simple as using a flood fill or Dijkstra's algorithm, and it would look like this:

===0=== =00000= 000W000 =00000= ===0=== 

No problem! However, how will I implement a spell, that, for whatever reason, looks like a plus sign?

===0=== ===0=== 000W000 ===0=== ===0=== 

Or the spell goes longer in the direction the wizard is facing?

=00000= =00000= ==0W0== ==000== ======= 

Or two different locations?

======= =00==== ===W=== ====00= ======= 

Or, even more awkward, its a ranged splash spell where the player can choose where they want to cast it?

======= ======= ===W=== ======0 =====00 

One way would be to have a list of all the locations relative to the wizard beforehand, and add them to the wizards location later. (E.g, for the affect to be 2 tiles north of the wizard, it would store (x+0, y+2), and later add them to the wizard's position, which could be at x=30, y=19, so the affect would be at x=30, y=21.)

A limitation to this, unfortunately, is that it doesn't take into account where the wizard is facing, and it feels inelegant to manually typing in all the locations that the AOE will affect.

Bottom line: How should I approach this problem and create a good, easily adjustable AOE system for a tile based map, that takes into account different AOE shapes and cast positions?

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

Option #1 - have the spells "hardcoded" - "a list of all the locations relative to the wizard beforehand, and add them to the wizards location later". Despite the sound of it, this is rather simple solution. Especially if you are limiting spell radius to just 3-4 tiles. Hardcoding areas dependend on facing direction fits in as well. You can also use mirroring, rotation and combination of masks to reduce amount of "hardcode" and possible mistakes in updating them in sync.

Option #2 - Have the spells "parametrized". This is good for cases when spells can have larger radius and manually updating the "masks" is tedious process. Make a base spell class with abstract "area of effect" function that will return either a mask, or a hittest for each tile. Now in each child class do its implementation - for a circle spell Result := sqrt(sqr(dX) + sqr(dY)) < R;, for a plus spell Result := (dX = 0) or (dY = 0) and so on ..

If you have a lot of different spells - having a vizualization helps a lot. Either by seeing all hardcoded masks as 01110 patterns (just like you did in the question) or by having a mode/tool to preview them while dynamically editing the formulas.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you. I will try implementing rotation by making negative and switching x and y coordinates. For splash effect spells I will try having a separate mask for the range of throwing the spell and another mask for the AOE of the spell itself. If this works, I'll accept your answer! \$\endgroup\$ Commented Jul 6, 2017 at 5:46
  • \$\begingroup\$ @Demandooda Yep, mirroring and rotating masks is a good approach - I've included this into the answer for clarity. You can upvote if the answer is helpful. I would also advice you to wait a day or two before accepting the answer. This way, unanswered question has a better chance of attracting new/alternative answers. \$\endgroup\$ Commented Jul 6, 2017 at 5:50

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.