internal static void FinalizeTowerModel(ModTower modTower, TowerModel towerModel) { // do their base tower modifications try { modTower.ModifyBaseTowerModel(towerModel); } catch (Exception) { MelonLogger.Error($"Failed to modify TowerModel {towerModel.name}"); throw; } // actually apply the upgrades try { foreach (var modUpgrade in modTower.upgrades.Cast <ModUpgrade>() .Where(modUpgrade => modUpgrade != null && towerModel.tiers[modUpgrade.Path] >= modUpgrade.Tier) .OrderByDescending(modUpgrade => modUpgrade.Priority) .ThenBy(modUpgrade => modUpgrade.Tier) .ThenBy(modUpgrade => modUpgrade.Path)) { try { modUpgrade.ApplyUpgrade(towerModel); } catch (Exception) { MelonLogger.Error( $"Failed to apply ModUpgrade {modUpgrade.Name} to TowerModel {towerModel.name}"); throw; } } } catch (Exception) { MelonLogger.Error($"Failed to apply upgrades for TowerModel {towerModel.name}"); throw; } if (modTower.ShouldCreateParagon && towerModel.isParagon) { towerModel.tiers = new[] { 6, 0, 0 }; } // set the tower's display model if (modTower.Use2DModel) { try { var name = modTower.Get2DTexture(towerModel.tiers); var guid = ModContent.GetTextureGUID(modTower.mod, name); towerModel.display = guid; towerModel.GetBehavior <DisplayModel>().display = guid; towerModel.GetBehavior <DisplayModel>().positionOffset = new Vector3(0, 0, 2f); Tower2DScales[guid] = modTower.PixelsPerUnit; } catch (Exception) { MelonLogger.Error($"Failed to load 2d display for TowerModel {towerModel.name}"); throw; } } else { try { if (modTower.displays.Where(display => display.UseForTower(towerModel.tiers) && display.ParagonDisplayIndex <= 0) .OrderByDescending(display => display.Id) .FirstOrDefault() is ModTowerDisplay modTowerDisplay) { modTowerDisplay.ApplyToTower(towerModel); } } catch (Exception) { MelonLogger.Error($"Failed to load ModTowerDisplay for TowerModel {towerModel.name}"); throw; } } // last paragon stuff if (modTower.ShouldCreateParagon && towerModel.isParagon) { try { if (modTower.paragonUpgrade.RemoveAbilities) { towerModel.behaviors = towerModel.behaviors.RemoveItemsOfType <Model, AbilityModel>(); } var paragonModel = modTower.paragonUpgrade.ParagonTowerModel.Duplicate(); for (var i = 0; i < paragonModel.displayDegreePaths.Count; i++) { var displayDegreePath = paragonModel.displayDegreePaths[i]; displayDegreePath.name = $"AssetPathModel_{modTower.paragonUpgrade.GetType().Name}Lvl1"; var index = i; var modTowerDisplay = modTower.displays.Where(display => display.UseForTower(towerModel.tiers) && index >= display.ParagonDisplayIndex) .OrderByDescending(display => display.ParagonDisplayIndex) .FirstOrDefault(); if (modTowerDisplay != default) { displayDegreePath.assetPath = modTowerDisplay.Id; } } towerModel.behaviors = towerModel.behaviors.AddTo(paragonModel); modTower.paragonUpgrade.ApplyUpgrade(towerModel); } catch (Exception) { MelonLogger.Error( $"Failed to apply ModParagonUpgrade {modTower.paragonUpgrade.Name} to TowerModel {towerModel.name}"); throw; } } }