diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll
index 79ea5b67..c76fba35 100644
Binary files a/1.6/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/1.6/Assemblies/WulaFallenEmpire.dll differ
diff --git a/1.6/1.6/Defs/PrefabDefs/WULA_Prefabs.xml b/1.6/1.6/Defs/PrefabDefs/WULA_Prefabs.xml
new file mode 100644
index 00000000..8d33450e
--- /dev/null
+++ b/1.6/1.6/Defs/PrefabDefs/WULA_Prefabs.xml
@@ -0,0 +1,117 @@
+
+
+ WULA_NewColonyBase
+ (13,13)
+
+
+ (10, 0, 10)
+ WULA_Alloy
+
+
+ (3, 0, 1)
+ Clockwise
+
+
+ (6, 0, 10)
+ Clockwise
+ WULA_Alloy
+ Normal
+
+
+ (1, 0, 10)
+
+
+
+ (11, 0, 1)
+ (11, 0, 3)
+
+ Counterclockwise
+ Normal
+
+
+ (6, 0, 11)
+ WULA_Alloy
+ Normal
+
+
+
+ (6,0,6,0)
+ (4,3,4,3)
+ (4,9,4,9)
+
+
+
+ (2, 0, 6)
+ Counterclockwise
+
+
+
+ (6,9,6,9)
+ (7,11,7,11)
+
+ WULA_Alloy
+ Normal
+
+
+
+ (3,8,3,8)
+ (5,8,5,8)
+
+
+
+ (11, 0, 5)
+
+
+ (10, 0, 9)
+ WULA_Alloy
+ Normal
+
+
+ (6, 0, 6)
+
+
+ (7, 0, 9)
+
+
+ (1, 0, 1)
+
+
+
+ (3,1,3,1)
+ (9,1,9,1)
+
+ Opposite
+
+
+
+ (3,11,3,11)
+ (9,11,9,11)
+
+
+
+
+ (0,0,5,0)
+ (7,0,12,0)
+ (0,1,0,12)
+ (5,1,5,3)
+ (12,1,12,12)
+ (10,2,11,2)
+ (1,3,3,3)
+ (9,4,11,4)
+ (1,9,3,9)
+ (5,9,5,12)
+ (1,12,4,12)
+ (6,12,11,12)
+
+
+
+
+ (2, 0, 11)
+ (4, 0, 11)
+
+ Opposite
+ WULA_Alloy
+
+
+
+
diff --git a/1.6/1.6/Defs/Scenarios/Scenarios_WULA.xml b/1.6/1.6/Defs/Scenarios/Scenarios_WULA.xml
index e2e1c1ab..83f7bd22 100644
--- a/1.6/1.6/Defs/Scenarios/Scenarios_WULA.xml
+++ b/1.6/1.6/Defs/Scenarios/Scenarios_WULA.xml
@@ -85,6 +85,11 @@
WULA_Fake_Mothership_Beacon_Building
1
+
+ StartingThing_Defined
+ WULA_Prefab_Cleanzone_NewColonyBase_Beacon
+ 1
+
diff --git a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Drop_Buildings.xml b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Drop_Buildings.xml
index cc14c2af..1436f26f 100644
--- a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Drop_Buildings.xml
+++ b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Drop_Buildings.xml
@@ -1534,4 +1534,5 @@
WULA_Buildings
+
\ No newline at end of file
diff --git a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Misc_Buildings.xml b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Misc_Buildings.xml
index 4c7da254..7f29fc24 100644
--- a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Misc_Buildings.xml
+++ b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Misc_Buildings.xml
@@ -1,5 +1,60 @@
+
+ WULA_OrbitalTradeBeacon
+
+ Building_OrbitalTradeBeacon
+
+ Things/Building/Misc/DropBeacon
+ Graphic_Single
+
+ (0.3, 0.2, 0.3)
+ (0,0,-0.1)
+
+
+ (0.2,0.2,0.6,0.6)
+
+
+ Building
+ MinifiedThing
+
+ 75
+ 800
+ 0.5
+ 5
+
+ 负责协调殖民地与轨道上的乌拉帝国舰队进行材料输送的信标.
+ MapMeshAndRealTime
+ true
+ 0.15
+
+ 40
+ 1
+
+
+ BuildingDestroyed_Metal_Small
+
+
+
+ CompPowerTrader
+ -1
+
+
+
+
+ false
+ 14
+ WULA_Buildings
+ 2100
+ false
+
+ PlaceWorker_ShowTradeBeaconRadius
+
+ Misc2
+
+ Techprint_WULA_Colony_License_LV1_Technology
+
+
WULA_Fake_Mothership_Beacon_Building
diff --git a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Prefab_Beacons.xml b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Prefab_Beacons.xml
new file mode 100644
index 00000000..e04c0087
--- /dev/null
+++ b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Prefab_Beacons.xml
@@ -0,0 +1,110 @@
+
+
+
+
+ WULA_Prefab_Incoming
+
+ WulaFallenEmpire.Skyfaller_PrefabSpawner
+ (1,1)
+
+ Wula/Building/Linked/WULA_Fortress_Wall_MenuIcon
+ Graphic_Single
+ CutoutFlying
+ (1,1)
+
+
+ Accelerate
+ Things/Skyfaller/SkyfallerShadowDropPod
+ (1, 1)
+ DropPod_Fall
+ 100
+ Explosion_Vaporize
+ 0.05
+ 1
+ 1
+
+
+ (0,0)
+ (1, 1)
+
+
+
+
+
+ Smoke_Joint
+
+
+
+
+
+
+ WULA_Prefab_Cleanzone_NewColonyBase_Beacon
+
+ 一个用于呼叫建筑的信标,用于快速建造一个小型前哨站。
+ Wula/Building/Linked/WULA_Fortress_Wall_MenuIcon
+ MinifiedThing
+ Normal
+
+ WulaWall
+
+
+ BuildingsMisc
+
+
+ Wula/Building/Linked/WulaWall/WulaWall_Atlas
+ Graphic_Multi
+ (1,1)
+ (73,185,254,155)
+
+ false
+ false
+ false
+ false
+ false
+ false
+ Building
+ PassThroughOnly
+ 0
+ false
+ false
+
+ 0
+ false
+ Light
+
+ 1
+ 0
+ 1
+ 0
+
+ (1,1)
+ 0
+ 1
+
+
+ WULA_Structure_Technology
+
+ 0
+
+ 4
+
+
+ BuildingDestroyed_Metal_Small
+ false
+ false
+
+ WULA_Buildings
+
+
+ WULA_NewColonyBase
+ true
+ WULA_Prefab_Incoming
+ true
+ 1
+ true
+ false
+
+
+
+
+
\ No newline at end of file
diff --git a/1.6/Defs/ThingDefs_Buildings/WULA_Drop_Buildings.xml b/1.6/Defs/ThingDefs_Buildings/WULA_Drop_Buildings.xml
new file mode 100644
index 00000000..1c310758
--- /dev/null
+++ b/1.6/Defs/ThingDefs_Buildings/WULA_Drop_Buildings.xml
@@ -0,0 +1,13 @@
+ <!-- Prefab Spawner Skyfaller -->
+ <ThingDef ParentName="SkyfallerBase">
+ <defName>WULA_Skyfaller_PrefabSpawner</defName>
+ <label>prefab cargo pod</label>
+ <thingClass>WulaFallenEmpire.Skyfaller_PrefabSpawner</thingClass>
+ <skyfaller>
+ <shadowSize>(6, 6)</shadowSize>
+ <explosionRadius>5</explosionRadius>
+ <explosionDamage>Bomb</explosionDamage>
+ <impactSound>DropPod_Impact</impactSound>
+ <shake>Medium</shake>
+ </skyfaller>
+ </ThingDef>
diff --git a/Source/WulaFallenEmpire/BuildingComp/WULA_PrefabSpawner/CompProperties_PrefabSpawner.cs b/Source/WulaFallenEmpire/BuildingComp/WULA_PrefabSpawner/CompProperties_PrefabSpawner.cs
new file mode 100644
index 00000000..d8442400
--- /dev/null
+++ b/Source/WulaFallenEmpire/BuildingComp/WULA_PrefabSpawner/CompProperties_PrefabSpawner.cs
@@ -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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompPrefabSkyfallerCaller.cs b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompPrefabSkyfallerCaller.cs
new file mode 100644
index 00000000..12ae42b1
--- /dev/null
+++ b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompPrefabSkyfallerCaller.cs
@@ -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 _cachedCostList;
+
+ protected override List CostList
+ {
+ get
+ {
+ if (!string.IsNullOrEmpty(PropsPrefab.prefabDefName))
+ {
+ if (PropsPrefab.freePrefab)
+ {
+ return null;
+ }
+ if (_cachedCostList == null)
+ {
+ _cachedCostList = CalculatePrefabCost();
+ }
+ return _cachedCostList;
+ }
+ return base.CostList;
+ }
+ }
+
+ private List CalculatePrefabCost()
+ {
+ var prefab = DefDatabase.GetNamed(PropsPrefab.prefabDefName, false);
+ if (prefab == null)
+ {
+ Log.Error($"[PrefabSkyfallerCaller] Could not find PrefabDef named {PropsPrefab.prefabDefName}");
+ return new List(); // Return empty list to avoid null reference
+ }
+
+ var totalCost = new Dictionary();
+ 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();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompProperties_PrefabSkyfallerCaller.cs b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompProperties_PrefabSkyfallerCaller.cs
new file mode 100644
index 00000000..ec170a9c
--- /dev/null
+++ b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompProperties_PrefabSkyfallerCaller.cs
@@ -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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompSkyfallerCaller.cs b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompSkyfallerCaller.cs
index f71dd478..44b233c8 100644
--- a/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompSkyfallerCaller.cs
+++ b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompSkyfallerCaller.cs
@@ -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 CostList
+ protected virtual List 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())
{
diff --git a/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/Skyfaller_PrefabSpawner.cs b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/Skyfaller_PrefabSpawner.cs
new file mode 100644
index 00000000..6a6a7109
--- /dev/null
+++ b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/Skyfaller_PrefabSpawner.cs
@@ -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.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");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
index bc39de18..b3f30277 100644
--- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
+++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
@@ -116,6 +116,9 @@
+
+
+