   Where do special cases of interaction go?
  I am on a team making a 2D real-time multiplayer battle game, and I had a question about the structure of the collision detection and the spell combination system.To promote teamwork, you can combine any "spell"-like effect with any number of other types. For the most part, these are predictable combinations that merely increase the component''s power, but certain combinations will have special effects - graphical or otherwise.We are using a particle effect for the graphics, but I was wondering where the "special case" code should go for spell combinations.Our current design has an "Spell Effect" world object that contains both an array of spell quantities for each of the 8 basic spells that have been charged into the spell and a "Mixer" object that contains special cases and acts as a filter to anything getting information about the spell effect.Can anyone think of a more object-oriented way? This one seems pretty good to me.On a similar note, in collision detection:Just as an example, say a fireball ignored teammates of the caster but hit trees and enemies, where would the code for that go? Would the fireball say "ok, I hit you, take some damage, tree" or would the tree say "ok, you hit me, how much damage do you deal?"? Or is there another solution?Thanks!-Flammicidia 
quote:Original post by Flammicidia  I am on a team making a 2D real-time multiplayer battle gameGood luck to you. quote:We are using a particle effect for the graphics, but I was wondering where the "special case" code should go for spell combinations.Our current design has an "Spell Effect" world object that contains both an array of spell quantities for each of the 8 basic spells that have been charged into the spell and a "Mixer" object that contains special cases and acts as a filter to anything getting information about the spell effect.Can anyone think of a more object-oriented way? This one seems pretty good to me.I couldn''t really parse that one sentence in the middle there. :/Could you get by with a virtual method in your "Spell" class along the lines of:Spell & combineWith(const Spell & other);? It''d likely create a new Spell subclass representing the combined effect of the two spells. Make use of composition rather than inheritance to avoid combinatorial explosion here... say a Spell contains a std::set or something, and you melt the attribute lists together as needed.On a similar note, in collision detection:quote:Just as an example, say a fireball ignored teammates of the caster but hit trees and enemies, where would the code for that go? Would the fireball say "ok, I hit you, take some damage, tree" or would the tree say "ok, you hit me, how much damage do you deal?"? Or is there another solution?Well... I guess you could try a publish-subscribe model if you need a lot of flexibility. It''d go something like:Tree: Room, please notify me of any fire effects that go off here.{Room adds Tree to its notification list}Later...Fireball: RAWR I BURN TEH ROOM OMG {sends message to Room}Room: Onos, Tree! A fireball just went off, of strength X.{Tree adjusts itself accordingly}{Room sends messages to the other enemies, etc. in its notification list, too.}{If an enemy wanders out of the room, it first needs to unsubscribe itself. It''d be a good idea to add the unsubscription to the leaveRoom() method.};quote:Original post by Zahlman  Good luck to you. Thanks .quote:Original post by Zahlman  I couldn''t really parse that one sentence in the middle there. :/Yeah, sorry about that. I looked back at it two or three times and kept thinking that it didn''t have enough information.What I meant to do there was describe our current best idea for implementing the spell combination system:The spell effect itself would be a world object. It would contain within it a list of quantities for each possible spell type. It would also contain a "mixer" object that acted as a filter for any object seeking information about the spell. It would deal with all special cases (for example, a portal spell and a fire spell become a turret-like spell, while a fire and electricity simply become stronger together). The spell effect would use the mixer to draw the visual effect of the spell. All of the spell effects use a particle system.quote:Could you get by with a virtual method in your "Spell" class along the lines of:Spell & combineWith(const Spell & other);? It''d likely create a new Spell subclass representing the combined effect of the two spells. Make use of composition rather than inheritance to avoid combinatorial explosion here... say a Spell contains a std::set or something, and you melt the attribute lists together as needed.In our game, you can combine any number of types of spells in a single effect. How would that work with what you described?And for the collision detection, it was the same kind of thing, in a way.If you had two players and they collided, they would probably just buffer around each other. But, if a fireball hit a tree, something special happens - the tree would change its state to "on fire". Where should the code for this special interaction that happens for fire-tree, but not player-player, go?Thanks for your help!Flammicidia ;  Flammicidia, your idea about using the Mixer object is the right way to go.  The objects themselves (spell-effect, player) shouldn''t be checking in their damage-handling code "I just hit you, are you a player?  Are you a barrel?  Are you a wall?"  A separate object that knows about all the special-case collision logic is the best way to go.You should note that this is a design pattern called "Double Dispatch" -- trying to virtualize the code that gets executed on 2 or more parameters, and is notorious because of the combinatorial effect Zahlman was talking about with trying to use virtual functions. 