I'm coding a game and I have a design issue in which I have a superclass which all items in the game inherit from. The game is grid based, and the items can be placed at different parts of the grid. The grid has a dictionary of grid positions -> BaseItem.
The problem is, the derived items all do very different things. So I always have to downcast to get the specific behaviors I want when I retrieve stuff from the grid. Here's a simple example:
public abstract class BaseObj {
public string Name {get; set;}
public int Hitpoints {get; set;}
}
public class Turret : BaseObj {
public void FireWeapon() { }
public int Damage {get; set;}
}
public class ProductionBuilding: BaseObj {
public void CraftItem(BaseObj item) {}
public float CraftSpeed {get; set;}
}
So a scenario is where the player is selecting an item from the grid. The grid class has a method that returns the item located at the coordinates of the mouse when clicked.
From here, I need to determine what kind of thing the player has selected. It will determine which UI panels I show and what behaviors I can do on the items. As a result my code base is littered with downcasts and typechecks. There must be some design pattern that deals with moderately complex inheritance structures and downcasting. Any ideas?
I'm coding in C# and Unity, but I imagine the answer will be general enough to encompass OOP generally.
This is not a duplicate of :How to avoid the continuous downcasting in this case?
In that case, the container object only housed one Dog, so applying a template type to DogHouse was easy enough. But this solution cannot be applied to my grid, as it contains a list of items.
EDIT:
As requested, here's an example of where I'm casting. The context of this is the player is placing down an item on the grid.
if (typeof(StationModule) == item.GetType())
{
StationManager.HandleModuleAdded((StationModule)item);
}
The StationManager does some special stuff when StationModules are placed, but the player can place other things besides StationModules onto the grid, in which case StationManager does not care.