Subsystem: MapResources - Adam-Poppenheimer/Civ-Clone GitHub Wiki
The MapResources subsystem handles the creation, destruction, relocation, yield, and placement restrictions of luxury, strategic, and bonus resources.
In addition to having terrain, topology, and vegetation, the map in Civilization 5 is dotted with nodes of special commodities called (somewhat unhelpfully) resources, which lie in specific cells and provide certain bonuses. There are three kinds: Luxury resources that improve happiness; Strategic resources that permit and support certain units and buildings; and bonus resources that provide additional yield to the cell on which they're placed. Resources of all types have special extraction improvements (mines for Iron, plantations for Spices, farms for Wheat) that either permit the collection of the resource (in the case of Luxuries and Strategics) and/or provide additional yield (for all three types).
MapResources handles only the core features of such resources. Types of resources are defined through the IResourceDefinition interface and its standard implementation, ResourceDefinition. Specific instances of these resources that can be placed on the map are handled via IResourceNode/ResourceNode. ResourceNode is a fairly simple class that contains an IResourceDefinition, a number of copies, and produces OnDestroy events. It's implemented as a MonoBehavior to aid in object creation/destruction.
IResourceNodes are constructed through IResourceNodeFactory/ResourceNodeFactory. Their positions on the grid are controlled and defined by IResourceNodeLocationCanon and its standard implementation. There are a handful of signals for the relocation and destruction of ResourceNodes in ResourceSignals.
The yield that a particular resource provides to its cell is calculated in straightforward fashion through IResourceNodeYieldLogic and its standard implementation. Resources always provide their base yield, to which their bonus yield is added if they share a cell with a constructed, non-pillaged improvement whose template is the same the IResourceDefinition's Extractor. Neither of these yields are provided if the ResourceNode's IResourceDefinition is not currently visible, as indicated by a collection if visibleResources passed into GetYieldFromNode().
Finally, MapResources contains logic on where a resource should be placed, and with what weight, via the IResourceRestrictionLogic and its standard implementation. ResourceRestrictionLogic refuses placement of an IResourceNode on cells that already contain one, and also queries the weight of the node's underlying IResourceDefinition for its configured terrain, shape, and vegetation weights. These weights are used primarily by MapGeneration to decide what resources should go where, and it's entirely possible they should be incorporated into that subsystem to keep MapResources itself simpler. Given that a resource's preferences are inherent to the resource, though, the weights were placed here.