ZC
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
using Verse;
|
||||
|
||||
namespace WulaFallenEmpire
|
||||
{
|
||||
public class CompProperties_PrefabSpawner : CompProperties
|
||||
{
|
||||
public string prefabDefName;
|
||||
public bool consumesMaterials = true;
|
||||
|
||||
public CompProperties_PrefabSpawner()
|
||||
{
|
||||
compClass = typeof(CompPrefabSpawner);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Verse;
|
||||
|
||||
namespace WulaFallenEmpire
|
||||
{
|
||||
public class CompPrefabSkyfallerCaller : CompSkyfallerCaller
|
||||
{
|
||||
private CompProperties_PrefabSkyfallerCaller PropsPrefab => (CompProperties_PrefabSkyfallerCaller)props;
|
||||
|
||||
private List<ThingDefCountClass> _cachedCostList;
|
||||
|
||||
protected override List<ThingDefCountClass> CostList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(PropsPrefab.prefabDefName))
|
||||
{
|
||||
if (PropsPrefab.freePrefab)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (_cachedCostList == null)
|
||||
{
|
||||
_cachedCostList = CalculatePrefabCost();
|
||||
}
|
||||
return _cachedCostList;
|
||||
}
|
||||
return base.CostList;
|
||||
}
|
||||
}
|
||||
|
||||
private List<ThingDefCountClass> CalculatePrefabCost()
|
||||
{
|
||||
var prefab = DefDatabase<PrefabDef>.GetNamed(PropsPrefab.prefabDefName, false);
|
||||
if (prefab == null)
|
||||
{
|
||||
Log.Error($"[PrefabSkyfallerCaller] Could not find PrefabDef named {PropsPrefab.prefabDefName}");
|
||||
return new List<ThingDefCountClass>(); // Return empty list to avoid null reference
|
||||
}
|
||||
|
||||
var totalCost = new Dictionary<ThingDef, int>();
|
||||
foreach (var (thingData, _, _) in PrefabUtility.GetThings(prefab, IntVec3.Zero, Rot4.North))
|
||||
{
|
||||
if (thingData.def.costList != null)
|
||||
{
|
||||
foreach (var cost in thingData.def.costList)
|
||||
{
|
||||
if (totalCost.ContainsKey(cost.thingDef))
|
||||
{
|
||||
totalCost[cost.thingDef] += cost.count;
|
||||
}
|
||||
else
|
||||
{
|
||||
totalCost.Add(cost.thingDef, cost.count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return totalCost.Select(kvp => new ThingDefCountClass(kvp.Key, kvp.Value)).ToList();
|
||||
}
|
||||
|
||||
protected override void ExecuteSkyfallerCall()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(PropsPrefab.prefabDefName))
|
||||
{
|
||||
// Final material check before launching
|
||||
if (!HasEnoughMaterials())
|
||||
{
|
||||
Log.Warning($"[PrefabSkyfallerCaller] Aborting skyfaller call due to insufficient materials at the last moment.");
|
||||
ResetCall(); // Reset the calling state
|
||||
return;
|
||||
}
|
||||
|
||||
ConsumeMaterials();
|
||||
|
||||
Thing thing = ThingMaker.MakeThing(Props.skyfallerDef);
|
||||
if (thing is Skyfaller_PrefabSpawner skyfaller)
|
||||
{
|
||||
skyfaller.prefabDefName = PropsPrefab.prefabDefName;
|
||||
GenSpawn.Spawn(skyfaller, parent.Position, parent.Map);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error($"[PrefabSkyfallerCaller] Failed to create Skyfaller_PrefabSpawner. Created thing is of type {thing.GetType().FullName}. Def: {Props.skyfallerDef.defName}, ThingClass: {Props.skyfallerDef.thingClass.FullName}");
|
||||
// Fallback: spawn as normal skyfaller if possible, or just abort
|
||||
if (thing is Skyfaller normalSkyfaller)
|
||||
{
|
||||
GenSpawn.Spawn(normalSkyfaller, parent.Position, parent.Map);
|
||||
}
|
||||
}
|
||||
|
||||
if (PropsPrefab.destroyBuilding && !parent.Destroyed)
|
||||
{
|
||||
parent.Destroy(DestroyMode.Vanish);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
base.ExecuteSkyfallerCall();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Verse;
|
||||
|
||||
namespace WulaFallenEmpire
|
||||
{
|
||||
public class CompProperties_PrefabSkyfallerCaller : CompProperties_SkyfallerCaller
|
||||
{
|
||||
public string prefabDefName;
|
||||
public bool freePrefab = false;
|
||||
|
||||
public CompProperties_PrefabSkyfallerCaller()
|
||||
{
|
||||
compClass = typeof(CompPrefabSkyfallerCaller);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace WulaFallenEmpire
|
||||
{
|
||||
public class CompSkyfallerCaller : ThingComp
|
||||
{
|
||||
private CompProperties_SkyfallerCaller Props => (CompProperties_SkyfallerCaller)props;
|
||||
protected CompProperties_SkyfallerCaller Props => (CompProperties_SkyfallerCaller)props;
|
||||
|
||||
private WulaSkyfallerWorldComponent _worldComponent;
|
||||
private WulaSkyfallerWorldComponent WorldComp
|
||||
@@ -89,83 +89,29 @@ namespace WulaFallenEmpire
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Log.Error($"[SkyfallerCaller] Error in HasRequiredFlyOver: {ex}");
|
||||
Log.Error($"[SkyfallerCaller] Exception while checking for FlyOver: {ex}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查屋顶条件
|
||||
public bool CheckRoofConditions
|
||||
private bool CheckRoofConditions
|
||||
{
|
||||
get
|
||||
{
|
||||
if (parent?.Map == null) return false;
|
||||
if (parent?.Map == null) return true;
|
||||
|
||||
IntVec3 targetPos = parent.Position;
|
||||
RoofDef roof = targetPos.GetRoof(parent.Map);
|
||||
RoofDef roof = parent.Position.GetRoof(parent.Map);
|
||||
if (roof == null) return true;
|
||||
|
||||
if (roof == null)
|
||||
{
|
||||
Log.Message($"[SkyfallerCaller] No roof at target position, skyfaller allowed");
|
||||
return true; // 没有屋顶,允许空投
|
||||
}
|
||||
if (roof.isThickRoof && !Props.allowThickRoof) return false;
|
||||
if (!roof.isThickRoof && !Props.allowThinRoof) return false;
|
||||
|
||||
if (roof.isThickRoof)
|
||||
{
|
||||
Log.Message($"[SkyfallerCaller] Thick roof detected at target position: {roof.defName}");
|
||||
return Props.allowThickRoof; // 厚岩顶,根据配置决定
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Message($"[SkyfallerCaller] Thin roof detected at target position: {roof.defName}");
|
||||
return Props.allowThinRoof; // 薄屋顶,根据配置决定
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查所有召唤条件
|
||||
public bool CanCallSkyfaller
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!CanCall)
|
||||
{
|
||||
Log.Message($"[SkyfallerCaller] Cannot call: already used or calling");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!HasRequiredFlyOver)
|
||||
{
|
||||
Log.Message($"[SkyfallerCaller] Cannot call: missing required FlyOver with BuildingdropperFacility");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CheckRoofConditions)
|
||||
{
|
||||
Log.Message($"[SkyfallerCaller] Cannot call: roof conditions not met");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!HasEnoughMaterials())
|
||||
{
|
||||
Log.Message($"[SkyfallerCaller] Cannot call: insufficient materials");
|
||||
return false;
|
||||
}
|
||||
|
||||
Log.Message($"[SkyfallerCaller] All conditions met for skyfaller call");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void PostSpawnSetup(bool respawningAfterLoad)
|
||||
{
|
||||
base.PostSpawnSetup(respawningAfterLoad);
|
||||
if (!respawningAfterLoad && Props.canAutoCall && WorldComp.AutoCallSkyfaller && CanCallSkyfaller)
|
||||
{
|
||||
CallSkyfaller(true);
|
||||
}
|
||||
}
|
||||
public bool CanCallSkyfaller => CanCall && HasRequiredFlyOver && CheckRoofConditions;
|
||||
|
||||
public override void PostExposeData()
|
||||
{
|
||||
@@ -178,7 +124,6 @@ namespace WulaFallenEmpire
|
||||
public override void CompTick()
|
||||
{
|
||||
base.CompTick();
|
||||
|
||||
if (calling && callTick >= 0 && Find.TickManager.TicksGame >= callTick)
|
||||
{
|
||||
ExecuteSkyfallerCall();
|
||||
@@ -225,7 +170,14 @@ namespace WulaFallenEmpire
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteSkyfallerCall()
|
||||
protected void ResetCall()
|
||||
{
|
||||
calling = false;
|
||||
used = false;
|
||||
callTick = -1;
|
||||
}
|
||||
|
||||
protected virtual void ExecuteSkyfallerCall()
|
||||
{
|
||||
Log.Message($"[SkyfallerCaller] Executing skyfaller call at {parent.Position}");
|
||||
|
||||
@@ -238,9 +190,7 @@ namespace WulaFallenEmpire
|
||||
if (!HasEnoughMaterials())
|
||||
{
|
||||
Log.Message($"[SkyfallerCaller] Aborting skyfaller call due to insufficient materials.");
|
||||
calling = false;
|
||||
used = false;
|
||||
callTick = -1;
|
||||
ResetCall();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -289,7 +239,7 @@ namespace WulaFallenEmpire
|
||||
}
|
||||
}
|
||||
|
||||
private List<ThingDefCountClass> CostList
|
||||
protected virtual List<ThingDefCountClass> CostList
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -301,8 +251,10 @@ namespace WulaFallenEmpire
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasEnoughMaterials()
|
||||
protected bool HasEnoughMaterials()
|
||||
{
|
||||
if (DebugSettings.godMode) return true;
|
||||
|
||||
var costList = CostList;
|
||||
if (costList.NullOrEmpty())
|
||||
{
|
||||
@@ -349,8 +301,10 @@ namespace WulaFallenEmpire
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ConsumeMaterials()
|
||||
protected void ConsumeMaterials()
|
||||
{
|
||||
if (DebugSettings.godMode) return;
|
||||
|
||||
var costList = CostList;
|
||||
if (costList.NullOrEmpty())
|
||||
{
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace WulaFallenEmpire
|
||||
{
|
||||
public class Skyfaller_PrefabSpawner : Skyfaller
|
||||
{
|
||||
public string prefabDefName;
|
||||
|
||||
protected override void SpawnThings()
|
||||
{
|
||||
// Don't spawn the innerThing, we are spawning a prefab instead.
|
||||
if (string.IsNullOrEmpty(prefabDefName))
|
||||
{
|
||||
Log.Error("[Skyfaller_PrefabSpawner] prefabDefName is null or empty. Cannot spawn prefab.");
|
||||
return;
|
||||
}
|
||||
|
||||
PrefabDef prefabDef = DefDatabase<PrefabDef>.GetNamed(prefabDefName, false);
|
||||
if (prefabDef == null)
|
||||
{
|
||||
Log.Error($"[Skyfaller_PrefabSpawner] Could not find PrefabDef named {prefabDefName}.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Correct parameter order based on compiler error: prefabDef, map, position, rotation
|
||||
PrefabUtility.SpawnPrefab(prefabDef, base.Map, base.Position, base.Rotation);
|
||||
}
|
||||
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
Scribe_Values.Look(ref prefabDefName, "prefabDefName");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,6 +116,9 @@
|
||||
<Compile Include="BuildingComp\WULA_Shuttle\PocketSpaceThingHolder.cs" />
|
||||
<Compile Include="BuildingComp\WULA_SkyfallerCaller\CompProperties_SkyfallerCaller.cs" />
|
||||
<Compile Include="BuildingComp\WULA_SkyfallerCaller\CompSkyfallerCaller.cs" />
|
||||
<Compile Include="BuildingComp\WULA_SkyfallerCaller\CompPrefabSkyfallerCaller.cs" />
|
||||
<Compile Include="BuildingComp\WULA_SkyfallerCaller\CompProperties_PrefabSkyfallerCaller.cs" />
|
||||
<Compile Include="BuildingComp\WULA_SkyfallerCaller\Skyfaller_PrefabSpawner.cs" />
|
||||
<Compile Include="BuildingComp\WULA_SkyfallerCaller\WulaSkyfallerWorldComponent.cs" />
|
||||
<Compile Include="BuildingComp\WULA_StorageTurret\CompProperties_StorageTurret.cs" />
|
||||
<Compile Include="BuildingComp\WULA_StorageTurret\CompStorageTurret.cs" />
|
||||
|
||||
Reference in New Issue
Block a user