Added API to create extender asset
Added RandomGuaranteedScrapSpawn component
This commit is contained in:
parent
70f6ce5154
commit
aeb8ea576e
|
@ -5,6 +5,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using DunGen;
|
||||
using DunGen.Graph;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DunGenPlus
|
||||
{
|
||||
|
@ -16,7 +17,7 @@ namespace DunGenPlus
|
|||
return false;
|
||||
}
|
||||
|
||||
if (Plugin.DunGenExtenders.ContainsKey(dungeonFlow)) {
|
||||
if (ContainsDungeonFlow(dungeonFlow)) {
|
||||
Plugin.logger.LogWarning($"Already contains DunGenExtender asset for {dungeonFlow.name}");
|
||||
return false;
|
||||
}
|
||||
|
@ -36,5 +37,16 @@ namespace DunGenPlus
|
|||
return AddDunGenExtender(dunGenExtender.DungeonFlow, dunGenExtender);
|
||||
}
|
||||
|
||||
public static bool ContainsDungeonFlow(DungeonFlow dungeonFlow) {
|
||||
return Plugin.DunGenExtenders.ContainsKey(dungeonFlow);
|
||||
}
|
||||
|
||||
public static DunGenExtender CreateDunGenExtender(DungeonFlow dungeonFlow){
|
||||
var extender = ScriptableObject.CreateInstance<DunGenExtender>();
|
||||
extender.DungeonFlow = dungeonFlow;
|
||||
|
||||
return extender;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace DunGenPlus.Collections {
|
|||
[Header("Archetypes on Normal Nodes")]
|
||||
[Tooltip("If enabled, adds archetypes to the normal nodes in the DungeonFlow.\n\nBy default, nodes cannot have branching paths since they don't have archetype references. This allows nodes to have branching paths.")]
|
||||
public bool AddArchetypesToNormalNodes = false;
|
||||
public List<NodeArchetype> NormalNodeArchetypes;
|
||||
public List<NodeArchetype> NormalNodeArchetypes = new List<NodeArchetype>();
|
||||
internal Dictionary<string, NodeArchetype> _normalNodeArchetypesDictioanry;
|
||||
internal NodeArchetype _defaultNodeArchetype;
|
||||
|
||||
|
@ -54,9 +54,9 @@ namespace DunGenPlus.Collections {
|
|||
[Tooltip("If enabled, every archetype in LineRandomizerArchetypes will have the last LineRandomizerTakeCount tilesets replaced by a randomly selected set of tilesets from LineRandomizerTileSets. This applies for both archetype's TileSets and BranchCapTileSets.\n\nThis is designed for the scenario where dungeon generation takes a long time due to the combination of too many tiles and/or doorways in those tiles. This can reduce dungeon generation time while keeping some of the randomness of dungeon generation.\n\nAs stated previously, this WILL replace the last LineRandomizerTakeCount tilesets in the archetype's TileSets and BranchCapTileSets. As such you must guarantee that those elements can be replaced.")]
|
||||
public bool UseLineRandomizer = false;
|
||||
[Tooltip("The archetypes whose tilesets will be replaced.\n\nThese archetypes should ideally used in the Lines section of DungeonFlow, but it's a free country.")]
|
||||
public List<DungeonArchetype> LineRandomizerArchetypes;
|
||||
public List<DungeonArchetype> LineRandomizerArchetypes = new List<DungeonArchetype>();
|
||||
[Tooltip("The tilesets that will be used for replacement.")]
|
||||
public List<TileSet> LineRandomizerTileSets;
|
||||
public List<TileSet> LineRandomizerTileSets = new List<TileSet>();
|
||||
[Tooltip("The amount of tilesets that will be replaced from the archetypes, starting from the last element to the first element.\n\nAs stated previously, this WILL replace the tilesets in the archetype's TileSets and BranchCapTileSets. As such you must guarantee that those elements can be replaced.")]
|
||||
public int LineRandomizerTakeCount = 3;
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace DunGenPlus.Collections {
|
|||
[Tooltip("The normal node with this label will gain a randomly chosen archetype.\n\nIf empty, this becomes the default choice for any normal node without a NodeArchetype specified in this list.")]
|
||||
public string label;
|
||||
[Tooltip("The list of archetypes. One will be randomly chosen.")]
|
||||
public List<DungeonArchetype> archetypes;
|
||||
public List<DungeonArchetype> archetypes = new List<DungeonArchetype>();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using Unity.Netcode;
|
||||
|
||||
namespace DunGenPlus.Components.Scrap {
|
||||
public class RandomGuaranteedScrapSpawn : MonoBehaviour {
|
||||
|
||||
|
||||
public float spawnChance = 1f;
|
||||
public int minimumScrapValue = 0;
|
||||
|
||||
public static Dictionary<int, IEnumerable<Item>> scrapItemCache;
|
||||
|
||||
public static void ResetCache(){
|
||||
scrapItemCache = new Dictionary<int, IEnumerable<Item>>();
|
||||
}
|
||||
|
||||
public static IEnumerable<Item> GetCachedItemList(List<SpawnableItemWithRarity> allMoonItems, int scrapValue) {
|
||||
if (!scrapItemCache.TryGetValue(scrapValue, out var list)){
|
||||
list = allMoonItems.Select(i => i.spawnableItem).Where(i => i.minValue >= scrapValue).ToArray();
|
||||
scrapItemCache.Add(scrapValue, list);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public (NetworkObject itemReference, int scrapValue) CreateItem(RoundManager roundManager, List<SpawnableItemWithRarity> allMoonItems){
|
||||
var anomalyRandom = roundManager.AnomalyRandom;
|
||||
if (anomalyRandom.NextDouble() >= spawnChance) return (null, 0);
|
||||
|
||||
var itemList = GetCachedItemList(allMoonItems, minimumScrapValue);
|
||||
var itemListCount = itemList.Count();
|
||||
if (itemListCount == 0) return (null, 0);
|
||||
|
||||
var randomItem = itemList.ElementAt(anomalyRandom.Next(itemListCount));
|
||||
var randomValue = (int)(anomalyRandom.Next(randomItem.minValue, randomItem.maxValue) * roundManager.scrapValueMultiplier);
|
||||
|
||||
var gameObject = Instantiate(randomItem.spawnPrefab, transform.position, Quaternion.identity, roundManager.spawnedScrapContainer);
|
||||
var itemComp = gameObject.GetComponent<GrabbableObject>();
|
||||
|
||||
gameObject.transform.rotation = Quaternion.Euler(randomItem.restingRotation);
|
||||
itemComp.fallTime = 0f;
|
||||
itemComp.scrapValue = randomValue;
|
||||
|
||||
var networkComp = gameObject.GetComponent<NetworkObject>();
|
||||
networkComp.Spawn(false);
|
||||
return (networkComp, randomValue);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -15,8 +15,8 @@ namespace DunGenPlus {
|
|||
|
||||
[Tooltip("DunGenExtender will only influence this DungeonFlow")]
|
||||
public DungeonFlow DungeonFlow;
|
||||
public DunGenExtenderProperties Properties;
|
||||
public DunGenExtenderEvents Events;
|
||||
public DunGenExtenderProperties Properties = new DunGenExtenderProperties();
|
||||
public DunGenExtenderEvents Events = new DunGenExtenderEvents();
|
||||
|
||||
[Header("DEV ONLY: DON'T TOUCH")]
|
||||
public string Version = "0";
|
||||
|
|
|
@ -60,6 +60,14 @@
|
|||
<Reference Include="Unity.Collections">
|
||||
<HintPath>..\..\..\Libraries\Unity.Collections.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Netcode.Components, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\Libraries\Unity.Netcode.Components.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.Netcode.Runtime, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\Libraries\Unity.Netcode.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.RenderPipelines.Core.Runtime, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\Libraries\Unity.RenderPipelines.Core.Runtime.dll</HintPath>
|
||||
|
@ -99,6 +107,7 @@
|
|||
<Compile Include="Components\DoorwaySisters.cs" />
|
||||
<Compile Include="Components\MainRoomDoorwayGroups.cs" />
|
||||
<Compile Include="Components\Props\SpawnSyncedObjectCycle.cs" />
|
||||
<Compile Include="Components\Scrap\RandomGuaranteedScrapSpawn.cs" />
|
||||
<Compile Include="DunGenExtender.cs" />
|
||||
<Compile Include="Collections\DunGenExtenderProperties.cs" />
|
||||
<Compile Include="Generation\DunGenPlusGenerator.cs" />
|
||||
|
@ -106,6 +115,8 @@
|
|||
<Compile Include="Patches\DoorwayConnectionPatch.cs" />
|
||||
<Compile Include="Generation\DoorwaySistersRule.cs" />
|
||||
<Compile Include="Patches\DungeonGeneratorPatch.cs" />
|
||||
<Compile Include="Patches\RoundManagerPatch.cs" />
|
||||
<Compile Include="Patches\StartOfRoundPatch.cs" />
|
||||
<Compile Include="Plugin.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Utils\TranspilerUtilities.cs" />
|
||||
|
|
|
@ -39,6 +39,7 @@ namespace DunGenPlus.Generation {
|
|||
Properties = props;
|
||||
|
||||
if (Properties.UseDungeonBounds) {
|
||||
generator.DebugRender = true;
|
||||
generator.RestrictDungeonToBounds = Properties.UseDungeonBounds;
|
||||
var bounds = Properties.GetDungeonBounds(generator.LengthMultiplier);
|
||||
generator.TilePlacementBounds = bounds;
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
using DunGen;
|
||||
using DunGenPlus.Components.Scrap;
|
||||
using DunGenPlus.Generation;
|
||||
using HarmonyLib;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Unity.Netcode;
|
||||
|
||||
namespace DunGenPlus.Patches {
|
||||
public class RoundManagerPatch {
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(RoundManager), "waitForScrapToSpawnToSync")]
|
||||
public static void waitForScrapToSpawnToSyncPatch (ref RoundManager __instance, ref NetworkObjectReference[] spawnedScrap, ref int[] scrapValues) {
|
||||
if (DunGenPlusGenerator.Active) {
|
||||
var spawnedScrapList = spawnedScrap.ToList();
|
||||
var scrapValuesList = scrapValues.ToList();
|
||||
|
||||
var sources = UnityEngine.Object.FindObjectsOfType<RandomGuaranteedScrapSpawn>();
|
||||
RandomGuaranteedScrapSpawn.ResetCache();
|
||||
foreach(var s in sources) {
|
||||
var result = s.CreateItem(__instance, __instance.currentLevel.spawnableScrap);
|
||||
if (result.itemReference != null) {
|
||||
Plugin.logger.LogInfo($"Created guaranteed item {result.itemReference.gameObject.name} w/ value {result.scrapValue}");
|
||||
spawnedScrapList.Add(result.itemReference);
|
||||
scrapValuesList.Add(result.scrapValue);
|
||||
}
|
||||
}
|
||||
|
||||
spawnedScrap = spawnedScrapList.ToArray();
|
||||
scrapValues = scrapValuesList.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace DunGenPlus.Patches {
|
||||
|
||||
// like could be it's own mod
|
||||
// but I don't wanna be the guy who messes with the original dungeon flows
|
||||
// and break someone else's mod cause of X edge case
|
||||
// and have to deal with that
|
||||
// nah bruh, let someone else deal with it
|
||||
|
||||
internal class StartOfRoundPatch {
|
||||
|
||||
public static readonly string[] validDungeonFlowTargets = new [] {
|
||||
"Level1Flow", "Level2Flow", "Level1FlowExtraLarge", "Level1Flow3Exits"
|
||||
};
|
||||
|
||||
public static readonly Dictionary<string, int> validStartTileTargets = new Dictionary<string, int>() {
|
||||
{ "StartRoom", 2 },
|
||||
{ "ManorStartRoom", 3 }
|
||||
};
|
||||
|
||||
[HarmonyPatch(typeof(RoundManager), "Awake")]
|
||||
[HarmonyPrefix]
|
||||
public static void AwakePatch(ref RoundManager __instance){
|
||||
var dungeonFlows = __instance.dungeonFlowTypes.Select(d => d.dungeonFlow);
|
||||
foreach(var d in dungeonFlows) {
|
||||
if (!validDungeonFlowTargets.Contains(d.name)) continue;
|
||||
if (API.ContainsDungeonFlow(d)) continue;
|
||||
|
||||
Plugin.logger.LogInfo($"Creating DunGenExtender for {d.name}");
|
||||
|
||||
var tiles = d.Lines
|
||||
.Select(i => i.DungeonArchetypes)
|
||||
.SelectMany(i => i)
|
||||
.Select(i => i.TileSets)
|
||||
.SelectMany(i => i)
|
||||
.Select(i => i.TileWeights.Weights)
|
||||
.SelectMany(i => i)
|
||||
.Select(i => i.Value);
|
||||
foreach(var t in tiles) {
|
||||
if (validStartTileTargets.TryGetValue(t.name, out var paths)) {
|
||||
var extender = API.CreateDunGenExtender(d);
|
||||
var props = extender.Properties;
|
||||
props.MainPathCount = paths;
|
||||
props.MainRoomTilePrefab = t;
|
||||
|
||||
d.Length = new DunGen.IntRange(d.Length.Min / 2, d.Length.Max / 2);
|
||||
Plugin.logger.LogInfo($"New length: {d.Length}");
|
||||
|
||||
if (t.name == "StartRoom") {
|
||||
var lines = d.Lines;
|
||||
lines[0].Length = 0.2f;
|
||||
lines[1].Length -= 0.2f - lines[1].Position;
|
||||
lines[1].Position = 0.2f;
|
||||
}
|
||||
|
||||
API.AddDunGenExtender(extender);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -42,6 +42,9 @@ namespace DunGenPlus {
|
|||
|
||||
Harmony.PatchAll(typeof(DungeonGeneratorPatch));
|
||||
Harmony.PatchAll(typeof(DoorwayConnectionPatch));
|
||||
Harmony.PatchAll(typeof(RoundManagerPatch));
|
||||
|
||||
//Harmony.PatchAll(typeof(StartOfRoundPatch));
|
||||
|
||||
Assets.LoadAssets();
|
||||
DungeonManager.GlobalDungeonEvents.onBeforeDungeonGenerate.AddListener(OnDunGenExtenderLoad);
|
||||
|
|
|
@ -14,6 +14,10 @@ Please refer to the [wiki](https://git.touhou.dev/Raphtalia/DungeonGenerationPlu
|
|||
|
||||
The prominent feature of this API is the ability to seemlesly add multiple main paths to your interior. Below are some examples.
|
||||
|
||||
![](https://i.imgur.com/XvygIZx.png)
|
||||
|
||||
![](https://i.imgur.com/GKZVqOa.png)
|
||||
|
||||
![](https://i.imgur.com/nN5Zz5e.png)
|
||||
|
||||
![](https://i.imgur.com/ogrUKAI.png)
|
||||
|
|
Loading…
Reference in New Issue