# Upgrade

### Key Features

* **Manages Progression:** Tracks current active progressions (supports Turn-Base updates)
* **UI Handling:** Reusable component for managing UI and state of the control action.
* **Visuals**: Support showing progress bar over an entity/unit or action button itself.
* **Upgrade Entity:** Allows upgrading of a single entity.
* **Progression Research:** Allows upgrading multiple entities for player through research.

***

### Structure

* **Upgrade Module** - Easy access to starting or cancelling upgrade on specific entity.
  * **InPlace** - Default replacement strategy which updates entity/unit data and its components. If visuals are different, they are changed internally based on setup.
  * **Replacement** - Alternative replacement strategy which destroys and creates new entities instead. Experimental — *tasks are currently not restarted.*
* **Upgrade Capability:** Defines capability of an entity to upgrade, supports 1-N options allowing entities to branch out with their upgrades (e.g. villager → militia → villager *or* swordsman).
* **Upgrading Entity:** Component for managing current upgrading options of an entity and its upgrade progress.
* **Upgrade Visuals:** Provides component for simple setup in Editor for switching between visuals based on completed upgrade (`UpgradeEntityVisuals`).
* **Upgrade Entity Action:** Write something here? `UpgradeEntityVisuals`
* **Upgrade Events:** Global events for tracking upgrading processes: start, cancelled, completed, entity replaced and entity upgraded.

***

### Usage Examples

**Upgrade Entity - with progress**

When you would like to start upgrading entity to a specific option. *This snippet is taken from the Upgrade Entity Action used by Upgrade Entity. UI Handler.*

```csharp
public void UpgradeEntity(IEntity entity, EntityUpgradeOption option)
{
    // Check if entity has upgrading entity defined
    if (entity.Upgrading == null) return;
    // Get modules from entity owner
    if (!entity.Owner.TryGetModule(out UpgradeModule upgradeModule)) return;
    if (!entity.Owner.TryGetModule(out ResourceModule resourceModule)) return;
    
    // Consume resources; if it fails, not enough resources.
    if (!resourceModule.RemoveResources(option.Cost)) return;
    
    // Upgrading process can start through module, 
    // to let module manage the updates.
    upgradeModule.StartUpgradeEntity(entity.Upgrading, option);
}
```

**Upgrade Entity - Instantly**

Or upgrade entity instantly instead.

```csharp
public void UpgradeEntity(IEntity entity, AEntitySO newData)
{
    if (!entity.Owner.TryGetModule(out UpgradeModule module)) return;

    // Apply instant upgrade. 
    // Resources should be consumed manually before the upgrade.
    module.UpgradeEntityInstantly(entity, newData);
}
```

**Upgrade multiple entities - Instantly**

Upgrade entities globally for the player. If no such entities exist, nothing happens.

```csharp
AEntitySO fromEntity = // Use desired starting entity/unit.
AEntitySO toEntity = // Use desired final entity/unit.

upgradeModule.TryGlobalUpgrade(fromEntity, toEntity);
```
