diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll
index dea759aa..80e4abd4 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
index e1e4b596..fe345ab2 100644
--- a/1.6/1.6/Defs/PrefabDefs/WULA_Prefabs.xml
+++ b/1.6/1.6/Defs/PrefabDefs/WULA_Prefabs.xml
@@ -148,4 +148,640 @@
+
+
+ WULA_Bunker_Drop_Zone_Prefeb
+ (5,5)
+
+
+ (2, 0, 2)
+
+
+
+ (0,0,1,0)
+ (3,0,4,0)
+ (0,1,0,1)
+ (4,1,4,1)
+ (0,3,0,4)
+ (4,3,4,4)
+ (1,4,1,4)
+ (3,4,3,4)
+
+ Cloth
+
+
+
+
+ WULA_Turret_Group_Drop_Zone_Prefeb
+ (15,15)
+
+
+
+ (3, 0, 3)
+ (11, 0, 3)
+ (3, 0, 11)
+ (11, 0, 11)
+
+
+
+ (7, 0, 7)
+
+
+
+ (7, 0, 1)
+ (1, 0, 7)
+ (13, 0, 7)
+ (7, 0, 13)
+
+
+
+
+ (7,3,7,3)
+ (3,7,3,7)
+ (11,7,11,7)
+ (7,11,7,11)
+
+
+
+
+ (5,5,9,5)
+ (5,6,5,9)
+ (9,6,9,9)
+ (6,9,8,9)
+
+
+
+
+ (1,1,5,1)
+ (9,1,13,1)
+ (1,2,1,5)
+ (5,2,5,2)
+ (9,2,9,2)
+ (13,2,13,5)
+ (2,5,2,5)
+ (12,5,12,5)
+ (1,9,2,9)
+ (12,9,13,9)
+ (1,10,1,13)
+ (13,10,13,13)
+ (5,12,5,13)
+ (9,12,9,13)
+ (2,13,4,13)
+ (10,13,12,13)
+
+ Cloth
+
+
+
+
+ WULA_Fortress_Drop_Zone_Prefeb
+ (25,25)
+
+
+
+ (7,6,7,6)
+ (9,6,9,6)
+ (15,6,15,6)
+ (17,6,17,6)
+ (12,8,12,8)
+ (12,16,12,16)
+ (7,18,7,18)
+ (9,18,9,18)
+ (15,18,15,18)
+ (17,18,17,18)
+
+ Clockwise
+
+
+
+ (6,7,6,7)
+ (18,7,18,7)
+ (6,9,6,9)
+ (18,9,18,9)
+ (8,12,8,12)
+ (16,12,16,12)
+ (6,15,6,15)
+ (18,15,18,15)
+ (6,17,6,17)
+ (18,17,18,17)
+
+
+
+
+ (10,6,10,6)
+ (14,6,14,6)
+
+
+
+
+ (6,10,6,10)
+ (6,14,6,14)
+
+ Clockwise
+
+
+
+ (18,10,18,10)
+ (18,14,18,14)
+
+ Counterclockwise
+
+
+
+ (10,18,10,18)
+ (14,18,14,18)
+
+ Opposite
+
+
+
+ (5, 0, 1)
+ (19, 0, 1)
+ (1, 0, 5)
+ (23, 0, 5)
+ (1, 0, 19)
+ (23, 0, 19)
+ (19, 0, 23)
+
+
+
+ (5, 0, 23)
+ 476
+
+
+
+ (5, 0, 5)
+ (19, 0, 5)
+ (5, 0, 19)
+ (19, 0, 19)
+
+
+
+
+ (9, 0, 3)
+ (15, 0, 3)
+ (3, 0, 9)
+ (21, 0, 9)
+ (3, 0, 15)
+ (21, 0, 15)
+ (9, 0, 21)
+ (15, 0, 21)
+
+
+
+
+ (10,5,10,5)
+ (14,5,14,5)
+ (5,10,5,10)
+ (19,10,19,10)
+ (5,14,5,14)
+ (19,14,19,14)
+ (10,19,10,19)
+ (14,19,14,19)
+
+
+
+
+ (3,3,7,3)
+ (17,3,21,3)
+ (3,4,3,7)
+ (7,4,7,5)
+ (17,4,17,5)
+ (21,4,21,7)
+ (8,5,9,5)
+ (15,5,16,5)
+ (4,7,5,7)
+ (7,7,7,7)
+ (9,7,15,7)
+ (17,7,17,7)
+ (19,7,20,7)
+ (5,8,5,9)
+ (19,8,19,9)
+ (7,9,7,15)
+ (9,9,15,9)
+ (17,9,17,15)
+ (9,10,9,15)
+ (15,10,15,15)
+ (5,15,5,17)
+ (10,15,14,15)
+ (19,15,19,17)
+ (3,17,4,17)
+ (7,17,7,17)
+ (9,17,15,17)
+ (17,17,17,17)
+ (20,17,21,17)
+ (3,18,3,21)
+ (21,18,21,21)
+ (7,19,9,19)
+ (15,19,17,19)
+ (7,20,7,21)
+ (17,20,17,21)
+ (4,21,6,21)
+ (18,21,20,21)
+
+
+
+ (12, 0, 12)
+
+
+
+ (7,1,11,1)
+ (13,1,17,1)
+ (7,2,7,2)
+ (11,2,11,2)
+ (13,2,13,2)
+ (17,2,17,2)
+ (1,7,2,7)
+ (22,7,23,7)
+ (1,8,1,11)
+ (23,8,23,11)
+ (2,11,2,11)
+ (22,11,22,11)
+ (1,13,2,13)
+ (22,13,23,13)
+ (1,14,1,17)
+ (23,14,23,17)
+ (2,17,2,17)
+ (22,17,22,17)
+ (7,22,7,23)
+ (11,22,11,23)
+ (13,22,13,23)
+ (17,22,17,23)
+ (8,23,10,23)
+ (14,23,16,23)
+
+ Cloth
+
+
+
+
+
+ (3,3,7,7)
+ (17,3,21,7)
+ (8,5,9,19)
+ (15,5,16,19)
+ (10,7,14,17)
+ (5,8,7,9)
+ (17,8,19,9)
+ (7,10,7,21)
+ (17,10,17,21)
+ (5,15,6,21)
+ (18,15,19,21)
+ (3,17,4,21)
+ (20,17,21,21)
+
+
+
+
+
+
+ WULA_Huge_Fortress_Drop_Zone_Prefeb
+ (44,44)
+
+
+
+ (14, 0, 12)
+ (15, 0, 12)
+ (16, 0, 12)
+ (14, 0, 32)
+ (15, 0, 32)
+ (16, 0, 32)
+ (27, 0, 32)
+ (28, 0, 32)
+ (29, 0, 32)
+
+ Opposite
+
+
+
+ (27, 0, 11)
+ (28, 0, 11)
+ (29, 0, 11)
+
+
+
+
+ (12, 0, 14)
+ (12, 0, 15)
+ (12, 0, 16)
+
+ Counterclockwise
+
+
+
+ (31, 0, 14)
+ (31, 0, 15)
+ (31, 0, 16)
+ (11, 0, 27)
+ (31, 0, 27)
+ (11, 0, 28)
+ (31, 0, 28)
+ (11, 0, 29)
+ (31, 0, 29)
+
+ Clockwise
+
+
+
+ (16, 0, 8)
+ (27, 0, 8)
+ (8, 0, 16)
+ (35, 0, 16)
+ (8, 0, 27)
+ (35, 0, 27)
+ (16, 0, 35)
+ (27, 0, 35)
+
+
+
+
+ (12,11,12,11)
+ (31,11,31,11)
+ (20,12,20,12)
+ (23,12,23,12)
+ (15,14,15,14)
+ (28,14,28,14)
+ (13,17,13,17)
+ (30,17,30,17)
+ (21,19,22,19)
+ (21,24,22,24)
+ (13,26,13,26)
+ (30,26,30,26)
+ (15,29,15,29)
+ (28,29,28,29)
+ (20,31,20,31)
+ (23,31,23,31)
+ (12,32,12,32)
+ (31,32,31,32)
+
+
+
+
+ (11,12,11,12)
+ (32,12,32,12)
+ (17,13,17,13)
+ (26,13,26,13)
+ (14,15,14,15)
+ (29,15,29,15)
+ (12,20,12,20)
+ (31,20,31,20)
+ (19,21,19,22)
+ (24,21,24,22)
+ (12,23,12,23)
+ (31,23,31,23)
+ (14,28,14,28)
+ (29,28,29,28)
+ (17,30,17,30)
+ (26,30,26,30)
+ (11,31,11,31)
+ (32,31,32,31)
+
+ Clockwise
+
+
+
+ (2, 0, 2)
+ (41, 0, 2)
+ (19, 0, 5)
+ (24, 0, 5)
+ (38, 0, 19)
+ (5, 0, 20)
+ (5, 0, 24)
+ (38, 0, 24)
+ (19, 0, 38)
+ (24, 0, 38)
+ (2, 0, 41)
+ (41, 0, 41)
+
+
+
+
+ (8, 0, 8)
+ (12, 0, 8)
+ (31, 0, 8)
+ (35, 0, 8)
+ (8, 0, 12)
+ (35, 0, 12)
+ (8, 0, 31)
+ (35, 0, 31)
+ (8, 0, 35)
+ (12, 0, 35)
+ (31, 0, 35)
+ (35, 0, 35)
+
+
+
+
+ (5,5,5,5)
+ (38,5,38,5)
+ (18,9,18,9)
+ (25,9,25,9)
+ (10,10,10,10)
+ (33,10,33,10)
+ (13,13,13,13)
+ (30,13,30,13)
+ (9,18,9,18)
+ (34,18,34,18)
+ (9,25,9,25)
+ (34,25,34,25)
+ (13,30,13,30)
+ (30,30,30,30)
+ (10,33,10,33)
+ (33,33,33,33)
+ (18,34,18,34)
+ (25,34,25,34)
+ (5,38,5,38)
+ (38,38,38,38)
+
+
+
+
+ (8, 0, 3)
+ (12, 0, 3)
+ (31, 0, 3)
+ (35, 0, 3)
+ (3, 0, 8)
+ (40, 0, 8)
+ (3, 0, 12)
+ (40, 0, 12)
+ (3, 0, 31)
+ (40, 0, 31)
+ (3, 0, 35)
+ (40, 0, 35)
+ (8, 0, 40)
+ (12, 0, 40)
+ (31, 0, 40)
+ (35, 0, 40)
+
+
+
+
+ (6,6,14,6)
+ (29,6,37,6)
+ (6,7,6,14)
+ (14,7,14,10)
+ (29,7,29,10)
+ (37,7,37,14)
+ (13,10,13,11)
+ (15,10,17,10)
+ (26,10,28,10)
+ (30,10,30,11)
+ (11,11,11,11)
+ (17,11,17,12)
+ (26,11,26,12)
+ (32,11,32,11)
+ (18,12,19,12)
+ (21,12,22,12)
+ (24,12,25,12)
+ (10,13,11,13)
+ (32,13,33,13)
+ (7,14,10,14)
+ (14,14,14,14)
+ (16,14,20,14)
+ (23,14,27,14)
+ (29,14,29,14)
+ (33,14,36,14)
+ (10,15,10,17)
+ (20,15,20,20)
+ (23,15,23,20)
+ (33,15,33,17)
+ (14,16,14,20)
+ (29,16,29,20)
+ (11,17,12,17)
+ (31,17,32,17)
+ (12,18,12,19)
+ (31,18,31,19)
+ (15,20,19,20)
+ (24,20,28,20)
+ (12,21,12,22)
+ (31,21,31,22)
+ (14,23,20,23)
+ (23,23,29,23)
+ (12,24,12,26)
+ (14,24,14,27)
+ (20,24,20,29)
+ (23,24,23,29)
+ (29,24,29,27)
+ (31,24,31,26)
+ (10,26,11,26)
+ (32,26,33,26)
+ (10,27,10,30)
+ (33,27,33,30)
+ (6,29,9,29)
+ (14,29,14,29)
+ (16,29,19,29)
+ (24,29,27,29)
+ (29,29,29,29)
+ (34,29,37,29)
+ (6,30,6,37)
+ (11,30,11,30)
+ (32,30,32,30)
+ (37,30,37,37)
+ (17,31,19,31)
+ (21,31,22,31)
+ (24,31,26,31)
+ (11,32,11,32)
+ (13,32,13,33)
+ (17,32,17,33)
+ (26,32,26,33)
+ (30,32,30,33)
+ (32,32,32,32)
+ (14,33,16,33)
+ (27,33,29,33)
+ (14,34,14,37)
+ (29,34,29,37)
+ (7,37,13,37)
+ (30,37,36,37)
+
+
+
+
+ (17, 0, 17)
+ (26, 0, 17)
+ (17, 0, 26)
+ (26, 0, 26)
+
+
+
+
+ (0,0,3,0)
+ (40,0,43,0)
+ (0,1,0,3)
+ (6,1,14,1)
+ (29,1,37,1)
+ (43,1,43,3)
+ (6,2,6,3)
+ (14,2,14,3)
+ (29,2,29,3)
+ (37,2,37,3)
+ (17,3,20,3)
+ (23,3,26,3)
+ (17,4,17,6)
+ (26,4,26,6)
+ (1,6,3,6)
+ (15,6,16,6)
+ (27,6,28,6)
+ (40,6,42,6)
+ (1,7,1,14)
+ (42,7,42,14)
+ (2,14,3,14)
+ (40,14,41,14)
+ (6,15,6,18)
+ (37,15,37,17)
+ (38,17,40,17)
+ (3,18,5,18)
+ (40,18,40,20)
+ (3,19,3,21)
+ (3,23,3,26)
+ (40,23,40,26)
+ (4,26,6,26)
+ (37,26,39,26)
+ (6,27,6,28)
+ (37,27,37,28)
+ (1,29,3,29)
+ (40,29,42,29)
+ (1,30,1,37)
+ (42,30,42,37)
+ (2,37,3,37)
+ (15,37,17,37)
+ (26,37,28,37)
+ (40,37,41,37)
+ (17,38,17,40)
+ (26,38,26,40)
+ (0,40,0,43)
+ (6,40,6,42)
+ (14,40,14,42)
+ (18,40,20,40)
+ (23,40,25,40)
+ (29,40,29,42)
+ (37,40,37,42)
+ (43,40,43,43)
+ (7,42,13,42)
+ (30,42,36,42)
+ (1,43,3,43)
+ (40,43,42,43)
+
+ Cloth
+
+
+
+
+
+ (6,6,14,14)
+ (29,6,37,14)
+ (15,10,17,33)
+ (26,10,28,33)
+ (18,12,25,31)
+ (10,15,14,17)
+ (29,15,33,17)
+ (12,18,14,37)
+ (29,18,31,37)
+ (10,26,11,37)
+ (32,26,33,37)
+ (6,29,9,37)
+ (34,29,37,37)
+
+
+
+
\ No newline at end of file
diff --git a/1.6/1.6/Defs/QuestScriptDefs/WULA_Hostile_Fortress_Drop_Quest.xml b/1.6/1.6/Defs/QuestScriptDefs/WULA_Hostile_Fortress_Drop_Quest.xml
new file mode 100644
index 00000000..c6bb05f1
--- /dev/null
+++ b/1.6/1.6/Defs/QuestScriptDefs/WULA_Hostile_Fortress_Drop_Quest.xml
@@ -0,0 +1,294 @@
+
+
+
+ WULA_GiveQuest_Hostile_PIA_Attack_Quest
+ GiveQuest
+
+
+ Map_PlayerHome
+
+ WULA_Hostile_PIA_Attack_Quest
+ IncidentWorker_GiveQuest
+ 0
+
+
+ WULA_Hostile_PIA_Attack_Quest
+ 0
+ true
+ false
+ 1
+ true
+ false
+
+
+
+ questName->WULA_Hostile_PIA_Attack_Quest_questName
+
+
+
+
+ QuestHospitalityCommon
+
+
+ questDescription->WULA_Hostile_PIA_Attack_Quest_questDescription
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ questName->要塞空投
+
+
+
+
+
+
+ questDescription->乌拉帝国 行星封锁机关对殖民地发起了报复打击,她们往殖民地空投了整装的要塞!
+
+
+
+
+
+ NegativeEvent
+ 乌拉帝国 行星封锁机关对殖民地发起了报复打击,她们往殖民地空投了整装的要塞!
+
+
+ WULA_Bunker_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 1
+ false
+ false
+
+
+ $points
+ 1000
+
+
+
+
+ WULA_Bunker_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 4
+ false
+ false
+
+
+
+
+
+ $points
+ 2999
+
+
+
+
+ WULA_Turret_Group_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 2
+ false
+ false
+
+
+
+
+
+ $points
+ 5999
+
+
+
+
+
+ WULA_Fortress_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 1
+ false
+ false
+
+
+ $prefabSpawnSuccessCount
+ $prefabSpawnRequestedCount
+
+
+
+
+ WULA_Turret_Group_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 3
+ false
+ false
+
+
+
+
+
+
+
+
+ $points
+ 7999
+
+
+
+
+
+ WULA_Fortress_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 1
+ false
+ false
+
+
+ $prefabSpawnSuccessCount
+ $prefabSpawnRequestedCount
+
+
+
+
+ WULA_Turret_Group_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 3
+ false
+ false
+
+
+
+
+
+
+
+
+ $points
+ 9999
+
+
+
+
+
+ WULA_Huge_Fortress_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 1
+ false
+ false
+
+
+ $prefabSpawnSuccessCount
+ $prefabSpawnRequestedCount
+
+
+
+
+ WULA_Fortress_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 2
+ false
+ false
+
+
+
+
+
+
+
+
+ $points
+ 12999
+
+
+
+
+
+ WULA_Bunker_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 4
+ false
+ false
+
+
+ WULA_Fortress_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 1
+ false
+ false
+
+
+ $prefabSpawnSuccessCount
+ $prefabSpawnRequestedCount
+
+
+
+
+ WULA_Turret_Group_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 3
+ false
+ false
+
+
+
+
+
+
+
+
+ $points
+ 15999
+
+
+
+
+
+ WULA_Bunker_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 4
+ false
+ false
+
+
+ WULA_Fortress_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 1
+ false
+ false
+
+
+ $prefabSpawnSuccessCount
+ $prefabSpawnRequestedCount
+
+
+
+
+ WULA_Turret_Group_Drop_Zone_Beacon_Cleanzone
+ Wula_PIA_Legion_Faction
+ 3
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/1.6/1.6/Defs/QuestScriptDefs/WULA_Recycle_PIA_Legion_File.xml b/1.6/1.6/Defs/QuestScriptDefs/WULA_Recycle_PIA_Legion_File.xml
index 2fb9d4f5..2cbcf9c0 100644
--- a/1.6/1.6/Defs/QuestScriptDefs/WULA_Recycle_PIA_Legion_File.xml
+++ b/1.6/1.6/Defs/QuestScriptDefs/WULA_Recycle_PIA_Legion_File.xml
@@ -1108,12 +1108,12 @@
Wula/Item/WULA_Safe_Box_For_Mission
Graphic_Single
- 30
+ 1
0
0
0
- 24
+ 8650000
0.3
450
@@ -1125,6 +1125,7 @@
true
14
200
+ 0
None
Last
true
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 b8b06981..d7b78491 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
@@ -1,7 +1,7 @@
-
+
WulaWall_Cleanzone
清理出一块场地并准备好资源,使得乌拉帝国可以向此处投放建筑,建造好的信标可以收起或移至他处。\n\n乌拉帝国用于建造堡垒的外壁相当厚实,能够抵御大量伤害,并且拥有气密性,可以用在飞船外壳上。
@@ -72,7 +72,7 @@
-
+
WulaWall_Incoming
(1,1)
@@ -106,7 +106,7 @@
-
+
WulaWall
乌拉帝国堡垒外壁,相当厚实,能够抵御大量伤害,并且拥有气密性,可以用在飞船外壳上。
@@ -177,7 +177,7 @@
-
+
WulaDoor_Cleanzone
清理出一块场地并准备好资源,使得乌拉帝国可以向此处投放建筑,建造好的信标可以收起或移至他处。\n\n乌拉帝国堡垒的大门不仅能够抵御大量爆炸和震荡伤害,还拥有无需通电即可运转的伺服系统来增加大门通过速度。
@@ -254,7 +254,7 @@
-
+
WulaDoor_Incoming
(1,1)
@@ -288,7 +288,7 @@
-
+
WulaDoor
乌拉帝国堡垒的大门,不仅能够抵御大量爆炸和震荡伤害,还拥有无需通电即可运转的伺服系统来增加大门通过速度。
@@ -970,7 +970,7 @@
1
- WULA_WeaponArmor_Productor_Technology
+ WULA_Colony_License_LV1_Technology
ITab_ContentsTransporter
@@ -1860,6 +1860,7 @@
false
false
BuildingDestroyed_Metal_Medium
+ false
50
@@ -2078,7 +2079,7 @@
CompPowerPlant
- -1500
+ -2000
true
ChemfuelFiredGenerator_Ambience
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 fd2ffafc..0340ef34 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
@@ -669,7 +669,6 @@
WULA_Sky_Lock
天锁
- Building
WulaFallenEmpire.Building_ExtraGraphics
true
MetaOverlays
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
index 9d5ca9dc..41fb4f67 100644
--- a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Prefab_Beacons.xml
+++ b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Prefab_Beacons.xml
@@ -105,4 +105,432 @@
+
+
+ WULA_Huge_Fortress_Drop_Zone_Beacon_Cleanzone
+
+ 一个用于呼叫建筑的信标,用于快速建造一个大型要塞。
+ Wula/Building/Linked/WULA_Fortress_Wall_MenuIcon
+ Normal
+ MinifiedThing
+
+ Wula/Building/WULA_Dropping_Building_Cleanzone_Plus
+ Graphic_Multi
+ (44,44)
+
+ false
+
+
+
+ BuildingsMisc
+
+ false
+ false
+ false
+ false
+ false
+ false
+ BuildingOnTop
+ PassThroughOnly
+ 0
+ false
+ false
+
+ 0
+ false
+ Light
+
+ 1
+ 0
+ 1
+ 0
+
+ (44,44)
+ 0
+ 1
+
+
+ 0
+
+ 4
+
+
+ BuildingDestroyed_Metal_Small
+ false
+ false
+
+
+
+ WULA_Huge_Fortress_Drop_Zone_Prefeb
+ true
+ WULA_Huge_Fortress_Drop_Zone_Prefeb_Incoming
+ true
+ 1
+ true
+ false
+
+
+
+
+
+ WULA_Huge_Fortress_Drop_Zone_Prefeb_Incoming
+
+ WulaFallenEmpire.Skyfaller_PrefabSpawner
+ (44,44)
+
+ Wula/Building/WULA_Huge_Fortress_Drop_Zone_Prefeb_Incoming
+ Graphic_Single
+ CutoutFlying
+ (44,44)
+
+
+ Accelerate
+ Things/Skyfaller/SkyfallerShadowDropPod
+ (44, 44)
+ DropPod_Fall
+ 100
+ Explosion_Vaporize
+ 0.05
+ 1
+ 1
+ 2.5
+
+
+ (0,0)
+ (1, 1)
+
+
+
+
+
+ Smoke_Joint
+
+
+ AncientsHostile
+
+
+
+
+
+ WULA_Bunker_Drop_Zone_Beacon_Cleanzone
+
+ 一个用于呼叫建筑的信标,用于快速建造一个碉堡防御设施。
+ Wula/Building/Linked/WULA_Fortress_Wall_MenuIcon
+ Normal
+ MinifiedThing
+
+ Wula/Building/WULA_Dropping_Building_Cleanzone
+ Graphic_Multi
+ (5,5)
+
+ false
+
+
+
+ BuildingsMisc
+
+ false
+ false
+ false
+ false
+ false
+ false
+ BuildingOnTop
+ PassThroughOnly
+ 0
+ false
+ false
+
+ 0
+ false
+ Light
+
+ 1
+ 0
+ 1
+ 0
+
+ (5,5)
+ 0
+ 1
+
+
+ 0
+
+ 4
+
+
+ BuildingDestroyed_Metal_Small
+ false
+ false
+
+
+
+ WULA_Bunker_Drop_Zone_Prefeb
+ true
+ WULA_Bunker_Drop_Zone_Prefeb_Incoming
+ true
+ 1
+ true
+ false
+
+
+
+
+
+ WULA_Bunker_Drop_Zone_Prefeb_Incoming
+
+ WulaFallenEmpire.Skyfaller_PrefabSpawner
+ (5,5)
+
+ Wula/Building/WULA_Bunker_Drop_Zone_Prefeb_Incoming
+ Graphic_Single
+ CutoutFlying
+ (5,5)
+
+
+ Accelerate
+ Things/Skyfaller/SkyfallerShadowDropPod
+ (5, 5)
+ DropPod_Fall
+ 100
+ Explosion_Vaporize
+ 0.05
+ 1
+ 1
+ 2.5
+
+
+ (0,0)
+ (1, 1)
+
+
+
+
+
+ Smoke_Joint
+
+
+ AncientsHostile
+
+
+
+
+
+ WULA_Turret_Group_Drop_Zone_Beacon_Cleanzone
+
+ 一个用于呼叫建筑的信标,用于快速建造一个炮塔群。
+ Wula/Building/Linked/WULA_Fortress_Wall_MenuIcon
+ Normal
+ MinifiedThing
+
+ Wula/Building/WULA_Dropping_Building_Cleanzone_Plus
+ Graphic_Multi
+ (15,15)
+
+ false
+
+
+
+ BuildingsMisc
+
+ false
+ false
+ false
+ false
+ false
+ false
+ BuildingOnTop
+ PassThroughOnly
+ 0
+ false
+ false
+
+ 0
+ false
+ Light
+
+ 1
+ 0
+ 1
+ 0
+
+ (15,15)
+ 0
+ 1
+
+
+ 0
+
+ 4
+
+
+ BuildingDestroyed_Metal_Small
+ false
+ false
+
+
+
+ WULA_Turret_Group_Drop_Zone_Prefeb
+ true
+ WULA_Turret_Group_Drop_Zone_Prefeb_Incoming
+ true
+ 1
+ true
+ false
+
+
+
+
+
+ WULA_Turret_Group_Drop_Zone_Prefeb_Incoming
+
+ WulaFallenEmpire.Skyfaller_PrefabSpawner
+ (15,15)
+
+ Wula/Building/WULA_Turret_Group_Drop_Zone_Prefeb_Incoming
+ Graphic_Single
+ CutoutFlying
+ (15,15)
+
+
+ Accelerate
+ Things/Skyfaller/SkyfallerShadowDropPod
+ (15, 15)
+ DropPod_Fall
+ 100
+ Explosion_Vaporize
+ 0.05
+ 1
+ 1
+ 2.5
+
+
+ (0,0)
+ (1, 1)
+
+
+
+
+
+ Smoke_Joint
+
+
+ AncientsHostile
+
+
+
+
+
+ WULA_Fortress_Drop_Zone_Beacon_Cleanzone
+
+ 一个用于呼叫建筑的信标,用于快速建造一个要塞。
+ Wula/Building/Linked/WULA_Fortress_Wall_MenuIcon
+ Normal
+ MinifiedThing
+
+ Wula/Building/WULA_Dropping_Building_Cleanzone_Plus
+ Graphic_Multi
+ (25,25)
+
+ false
+
+
+
+ BuildingsMisc
+
+ false
+ false
+ false
+ false
+ false
+ false
+ BuildingOnTop
+ PassThroughOnly
+ 0
+ false
+ false
+
+ 0
+ false
+ Light
+
+ 1
+ 0
+ 1
+ 0
+
+ (25,25)
+ 0
+ 1
+
+
+ 0
+
+ 4
+
+
+ BuildingDestroyed_Metal_Small
+ false
+ false
+
+
+
+ WULA_Fortress_Drop_Zone_Prefeb
+ true
+ WULA_Fortress_Drop_Zone_Prefeb_Incoming
+ true
+ 1
+ true
+ false
+
+
+
+
+
+ WULA_Fortress_Drop_Zone_Prefeb_Incoming
+
+ WulaFallenEmpire.Skyfaller_PrefabSpawner
+ (25,25)
+
+ Wula/Building/WULA_Fortress_Drop_Zone_Prefeb_Incoming
+ Graphic_Single
+ CutoutFlying
+ (25,25)
+
+
+ Accelerate
+ Things/Skyfaller/SkyfallerShadowDropPod
+ (25, 25)
+ DropPod_Fall
+ 100
+ Explosion_Vaporize
+ 0.05
+ 1
+ 1
+ 2.5
+
+
+ (0,0)
+ (1, 1)
+
+
+
+
+
+ Smoke_Joint
+
+
+ AncientsHostile
+
+
+
\ No newline at end of file
diff --git a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Turret_Buildings.xml b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Turret_Buildings.xml
index 43bd2eb1..602158d2 100644
--- a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Turret_Buildings.xml
+++ b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Turret_Buildings.xml
@@ -47,7 +47,7 @@
(3,3)
0
- 1
+ 0
300
3
@@ -145,7 +145,6 @@
false
false
- 0
Light
500
@@ -155,11 +154,15 @@
(3,3)
- 200
+ 60
BuildingDestroyed_Metal_Small
3.5
+ false
+ true
+ WULA_Cat_Bunker_TurretGun
+ false
@@ -301,7 +304,7 @@
(3,3)
0
- 1
+ 0
100
6
@@ -409,7 +412,6 @@
100
6
- false
Normal
PassThroughOnly
40
@@ -429,22 +431,34 @@
3
(-0.04, 0)
5.0
+ false
PlaceWorker_TurretTop
PlaceWorker_ShowTurretRadius
+
+
+ EMP
+ 50
+ 2
+ true
+
+
+
+ Stun
+ EMP
+
+
+ EMP
+
+
MechanoidsWakeUp
-
-
- EMP
-
-
MechTurretBig_Call
@@ -455,7 +469,7 @@
CompPowerTrader
- 300
+ 300
6
@@ -579,7 +593,7 @@
(3,3)
0
- 1
+ 0
Light
100
@@ -689,7 +703,6 @@
100
6
- false
Normal
PassThroughOnly
40
@@ -708,22 +721,34 @@
0.01
(-0.04, 0)
5.0
+ false
PlaceWorker_TurretTop
PlaceWorker_ShowTurretRadius
+
+
+ EMP
+ 50
+ 2
+ true
+
+
+
+ Stun
+ EMP
+
+
+ EMP
+
+
MechanoidsWakeUp
-
-
- EMP
-
-
MechTurretBig_Call
@@ -734,7 +759,7 @@
CompPowerTrader
- 500
+ 300
6
@@ -870,7 +895,7 @@
(3,3)
0
- 1
+ 0
100
6
@@ -969,7 +994,6 @@
150
12
- false
Normal
Impassable
true
@@ -982,12 +1006,20 @@
4
(-0.04, 0)
5.0
+ false
PlaceWorker_TurretTop
PlaceWorker_ShowTurretRadius
+
+
+ EMP
+ 500
+ 2
+ true
+
@@ -995,8 +1027,12 @@
+ Stun
EMP
+
+ EMP
+
MechTurretBig_Call
@@ -1008,7 +1044,7 @@
CompPowerTrader
- 200
+ 300
6
@@ -1115,7 +1151,6 @@
true
0.20
14
- false
BulletImpact_Metal
Wula/Building/Flag/WULA_Flag_Building_B_north
true
diff --git a/1.6/1.6/Defs/ThingDefs_Plants/WULA_Plants.xml b/1.6/1.6/Defs/ThingDefs_Plants/WULA_Plants.xml
index 697192fc..1bd871b0 100644
--- a/1.6/1.6/Defs/ThingDefs_Plants/WULA_Plants.xml
+++ b/1.6/1.6/Defs/ThingDefs_Plants/WULA_Plants.xml
@@ -16,6 +16,9 @@
true
10
+
+ NeverForNutrition
+
Wula/Plant/WULA_Plant_Eggplant_Immature
0.5
diff --git a/1.6/1.6/Patches/WULA_BaseStoryteller_Patch.xml b/1.6/1.6/Patches/WULA_BaseStoryteller_Patch.xml
index 0dab8537..82075289 100644
--- a/1.6/1.6/Patches/WULA_BaseStoryteller_Patch.xml
+++ b/1.6/1.6/Patches/WULA_BaseStoryteller_Patch.xml
@@ -26,8 +26,6 @@
WULA_Colony_License_LV1_Technology
- WULA_GiveQuest_Base_Tex
- WULA_Base_Tex_Quest
0
@@ -37,7 +35,11 @@
false
false
+ false
Wula_PIA_Legion_Faction
+
+ WULA_GiveQuest_Base_Tex
+ WULA_GiveQuest_Hostile_PIA_Attack_Quest
diff --git a/About/About.xml b/About/About.xml
index de95f7ba..be0dec17 100644
--- a/About/About.xml
+++ b/About/About.xml
@@ -25,6 +25,11 @@
Humanoid Alien Races 2.0
https://steamcommunity.com/sharedfiles/filedetails/?id=839005762
+
+ HaiLuan.CustomQuestFramework
+ Custom Quest Framework
+ https://steamcommunity.com/sharedfiles/filedetails/?id=2978572782
+
@@ -32,5 +37,6 @@
Ludeon.RimWorld
Ludeon.RimWorld.Biotech
erdelf.HumanoidAlienRaces
+ HaiLuan.CustomQuestFramework
\ No newline at end of file
diff --git a/Content/Textures/Wula/Building/WULA_Bunker_Drop_Zone_Prefeb_Incoming.png b/Content/Textures/Wula/Building/WULA_Bunker_Drop_Zone_Prefeb_Incoming.png
new file mode 100644
index 00000000..443dbcb0
Binary files /dev/null and b/Content/Textures/Wula/Building/WULA_Bunker_Drop_Zone_Prefeb_Incoming.png differ
diff --git a/Content/Textures/Wula/Building/WULA_Fortress_Drop_Zone_Prefeb_Incoming.png b/Content/Textures/Wula/Building/WULA_Fortress_Drop_Zone_Prefeb_Incoming.png
new file mode 100644
index 00000000..6f8a620b
Binary files /dev/null and b/Content/Textures/Wula/Building/WULA_Fortress_Drop_Zone_Prefeb_Incoming.png differ
diff --git a/Content/Textures/Wula/Building/WULA_Huge_Fortress_Drop_Zone_Prefeb_Incoming.png b/Content/Textures/Wula/Building/WULA_Huge_Fortress_Drop_Zone_Prefeb_Incoming.png
new file mode 100644
index 00000000..b0d26a7d
Binary files /dev/null and b/Content/Textures/Wula/Building/WULA_Huge_Fortress_Drop_Zone_Prefeb_Incoming.png differ
diff --git a/Content/Textures/Wula/Building/WULA_Turret_Group_Drop_Zone_Prefeb_Incoming.png b/Content/Textures/Wula/Building/WULA_Turret_Group_Drop_Zone_Prefeb_Incoming.png
new file mode 100644
index 00000000..156bcb3f
Binary files /dev/null and b/Content/Textures/Wula/Building/WULA_Turret_Group_Drop_Zone_Prefeb_Incoming.png differ
diff --git a/Source/WulaFallenEmpire/BuildingComp/WULA_MechanoidRecycler/Building_MechanoidRecycler.cs b/Source/WulaFallenEmpire/BuildingComp/WULA_MechanoidRecycler/Building_MechanoidRecycler.cs
index 9af5f7c2..f4e662eb 100644
--- a/Source/WulaFallenEmpire/BuildingComp/WULA_MechanoidRecycler/Building_MechanoidRecycler.cs
+++ b/Source/WulaFallenEmpire/BuildingComp/WULA_MechanoidRecycler/Building_MechanoidRecycler.cs
@@ -359,8 +359,6 @@ namespace WulaFallenEmpire
return Mathf.Max(0, remainingTicks / 2500f);
}
- // 开发模式方法:立即结束冷却
- [DebugAction("机械族回收器", "立即结束冷却", actionType = DebugActionType.Action, allowedGameStates = AllowedGameStates.Playing)]
public static void DevEndCooldown()
{
Building_MechanoidRecycler selectedRecycler = Find.Selector.SingleSelectedThing as Building_MechanoidRecycler;
diff --git a/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompPrefabSkyfallerCaller.cs b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompPrefabSkyfallerCaller.cs
index 12ae42b1..e65a7a34 100644
--- a/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompPrefabSkyfallerCaller.cs
+++ b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompPrefabSkyfallerCaller.cs
@@ -2,6 +2,7 @@ using RimWorld;
using System.Collections.Generic;
using System.Linq;
using Verse;
+using UnityEngine;
namespace WulaFallenEmpire
{
@@ -75,31 +76,96 @@ namespace WulaFallenEmpire
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);
- }
+ SpawnPrefabSkyfaller();
}
else
{
base.ExecuteSkyfallerCall();
}
}
+
+ // 新增:重写自动呼叫方法
+ protected override void ExecuteAutoSkyfallerCall()
+ {
+ if (!string.IsNullOrEmpty(PropsPrefab.prefabDefName))
+ {
+ Log.Message($"[PrefabSkyfallerCaller] Executing auto skyfaller call for prefab at {parent.Position}");
+
+ // 非玩家派系自动呼叫不需要资源检查
+ HandleRoofDestruction();
+
+ SpawnPrefabSkyfaller();
+
+ ResetCall();
+ autoCallScheduled = false;
+ }
+ else
+ {
+ base.ExecuteAutoSkyfallerCall();
+ }
+ }
+
+ // 新增:统一的 Prefab Skyfaller 生成方法
+ private void SpawnPrefabSkyfaller()
+ {
+ Thing thing = ThingMaker.MakeThing(Props.skyfallerDef);
+ if (thing is Skyfaller_PrefabSpawner skyfaller)
+ {
+ skyfaller.prefabDefName = PropsPrefab.prefabDefName;
+ Log.Message($"[PrefabSkyfallerCaller] Setting prefabDefName to: {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);
+ }
+ }
+
+ // 新增:重写屋顶处理方法以确保日志输出
+ private void HandleRoofDestruction()
+ {
+ if (parent?.Map == null) return;
+
+ IntVec3 targetPos = parent.Position;
+ RoofDef roof = targetPos.GetRoof(parent.Map);
+
+ if (roof != null && !roof.isThickRoof && Props.allowThinRoof)
+ {
+ Log.Message($"[PrefabSkyfallerCaller] Destroying thin roof at {targetPos}");
+ parent.Map.roofGrid.SetRoof(targetPos, null);
+
+ // 生成屋顶破坏效果
+ FleckMaker.ThrowDustPuffThick(targetPos.ToVector3Shifted(), parent.Map, 2f, new Color(1f, 1f, 1f, 2f));
+ }
+ }
+
+ // 新增:调试信息
+ public override string CompInspectStringExtra()
+ {
+ var baseString = base.CompInspectStringExtra();
+
+ if (!string.IsNullOrEmpty(PropsPrefab.prefabDefName))
+ {
+ var sb = new System.Text.StringBuilder();
+ if (!string.IsNullOrEmpty(baseString))
+ {
+ sb.AppendLine(baseString);
+ }
+ sb.Append($"Prefab: {PropsPrefab.prefabDefName}");
+ return sb.ToString();
+ }
+
+ return baseString;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompProperties_SkyfallerCaller.cs b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompProperties_SkyfallerCaller.cs
index 04d985e5..d320be2b 100644
--- a/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompProperties_SkyfallerCaller.cs
+++ b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompProperties_SkyfallerCaller.cs
@@ -10,7 +10,7 @@ namespace WulaFallenEmpire
public int delayTicks = 0;
public bool canAutoCall = true; // 默认启用自动召唤
- public int autoCallDelayTicks = 600; // 默认10秒
+ public int autoCallDelayTicks = 1; // 默认10秒
// 新增:是否需要 FlyOver 作为前提条件
public bool requireFlyOver = false; // 默认不需要 FlyOver
diff --git a/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompSkyfallerCaller.cs b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompSkyfallerCaller.cs
index d94ef747..d0dac7b0 100644
--- a/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompSkyfallerCaller.cs
+++ b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/CompSkyfallerCaller.cs
@@ -41,10 +41,17 @@ namespace WulaFallenEmpire
private bool used = false;
private int callTick = -1;
private bool calling = false;
- private bool usedGlobalStorage = false; // 新增:标记是否使用了全局储存器
+ private bool usedGlobalStorage = false;
+ public bool autoCallScheduled = false; // 新增:标记是否已安排自动呼叫
public bool CanCall => !used && !calling;
+ // 新增:检查建筑是否属于非玩家派系
+ public bool IsNonPlayerFaction => parent.Faction != null && parent.Faction != Faction.OfPlayer;
+
+ // 新增:检查是否应该自动呼叫
+ private bool ShouldAutoCall => IsNonPlayerFaction && Props.canAutoCall && !autoCallScheduled && !used;
+
// 固定的显示标签
public string RequiredFlyOverLabel => "建筑空投飞行器";
@@ -127,6 +134,22 @@ namespace WulaFallenEmpire
public bool CanCallSkyfaller => CanCall && HasRequiredFlyOver && CheckRoofConditions;
+ // 新增:在建筑生成时检查是否需要自动呼叫
+ public override void PostSpawnSetup(bool respawningAfterLoad)
+ {
+ base.PostSpawnSetup(respawningAfterLoad);
+
+ if (!respawningAfterLoad && ShouldAutoCall)
+ {
+ // 安排自动呼叫
+ autoCallScheduled = true;
+ callTick = Find.TickManager.TicksGame + Props.autoCallDelayTicks;
+ calling = true;
+
+ Log.Message($"[SkyfallerCaller] Scheduled auto-call for non-player building {parent.Label} at tick {callTick}");
+ }
+ }
+
public override void PostExposeData()
{
base.PostExposeData();
@@ -134,23 +157,95 @@ namespace WulaFallenEmpire
Scribe_Values.Look(ref callTick, "callTick", -1);
Scribe_Values.Look(ref calling, "calling", false);
Scribe_Values.Look(ref usedGlobalStorage, "usedGlobalStorage", false);
+ Scribe_Values.Look(ref autoCallScheduled, "autoCallScheduled", false);
}
public override void CompTick()
{
base.CompTick();
+
+ // 处理自动呼叫
if (calling && callTick >= 0 && Find.TickManager.TicksGame >= callTick)
{
- ExecuteSkyfallerCall();
+ if (autoCallScheduled)
+ {
+ // 执行自动呼叫
+ ExecuteAutoSkyfallerCall();
+ }
+ else
+ {
+ // 执行手动呼叫
+ ExecuteSkyfallerCall();
+ }
+ }
+ }
+
+ // 新增:自动呼叫方法(非玩家派系专用)
+ protected virtual void ExecuteAutoSkyfallerCall()
+ {
+ try
+ {
+ Log.Message($"[SkyfallerCaller] Executing auto skyfaller call for non-player building at {parent.Position}");
+
+ if (Props.skyfallerDef == null)
+ {
+ Log.Error("[SkyfallerCaller] Skyfaller def is null!");
+ ResetCall();
+ return;
+ }
+
+ // 非玩家派系自动呼叫不需要资源检查
+ // 直接处理屋顶
+ HandleRoofDestruction();
+
+ // 创建Skyfaller
+ Skyfaller skyfaller = SkyfallerMaker.MakeSkyfaller(Props.skyfallerDef);
+ if (skyfaller == null)
+ {
+ Log.Error("[SkyfallerCaller] Failed to create skyfaller!");
+ ResetCall();
+ return;
+ }
+
+ IntVec3 spawnPos = parent.Position;
+ Log.Message($"[SkyfallerCaller] Spawning auto skyfaller at {spawnPos}");
+
+ GenSpawn.Spawn(skyfaller, spawnPos, parent.Map);
+
+ if (Props.destroyBuilding)
+ {
+ Log.Message($"[SkyfallerCaller] Destroying non-player building {parent.Label}");
+ parent.Destroy(DestroyMode.Vanish);
+ }
+
+ // 重置状态
+ ResetCall();
+ autoCallScheduled = false;
+
+ // 显示自动呼叫消息
+ Messages.Message("WULA_AutoSkyfallerCalled".Translate(parent.Faction.Name),
+ MessageTypeDefOf.NeutralEvent);
+ }
+ catch (System.Exception ex)
+ {
+ Log.Error($"[SkyfallerCaller] Error in ExecuteAutoSkyfallerCall: {ex}");
+ ResetCall();
}
}
public void CallSkyfaller(bool isAutoCall = false)
{
+ // 新增:非玩家派系不能手动呼叫
+ if (IsNonPlayerFaction && !isAutoCall)
+ {
+ Messages.Message("WULA_NonPlayerCannotCall".Translate(), parent, MessageTypeDefOf.RejectInput);
+ return;
+ }
+
if (!CanCallSkyfaller)
{
// 显示相应的错误消息
- if (!HasRequiredFlyOver && Props.requireFlyOver) // 只在需要 FlyOver 时才显示此消息
+ if (!HasRequiredFlyOver && Props.requireFlyOver)
{
Messages.Message("WULA_NoBuildingDropperFlyOver".Translate(), parent, MessageTypeDefOf.RejectInput);
}
@@ -195,6 +290,7 @@ namespace WulaFallenEmpire
used = false;
callTick = -1;
usedGlobalStorage = false;
+ autoCallScheduled = false;
}
protected virtual void ExecuteSkyfallerCall()
@@ -599,6 +695,7 @@ namespace WulaFallenEmpire
used = false;
callTick = -1;
usedGlobalStorage = false;
+ autoCallScheduled = false;
Messages.Message("WULA_SkyfallerCallCancelled".Translate(), parent, MessageTypeDefOf.NeutralEvent);
}
@@ -607,6 +704,10 @@ namespace WulaFallenEmpire
foreach (var gizmo in base.CompGetGizmosExtra())
yield return gizmo;
+ // 新增:非玩家派系不显示呼叫按钮
+ if (IsNonPlayerFaction)
+ yield break;
+
if (calling)
{
Command_Action cancelCommand = new Command_Action
@@ -679,6 +780,12 @@ namespace WulaFallenEmpire
private string GetDisabledReason()
{
+ // 新增:非玩家派系不能手动呼叫
+ if (IsNonPlayerFaction)
+ {
+ return "WULA_NonPlayerCannotCall".Translate();
+ }
+
// 只在需要 FlyOver 时检查并显示相关原因
if (Props.requireFlyOver && !HasRequiredFlyOver)
{
@@ -719,7 +826,12 @@ namespace WulaFallenEmpire
var sb = new System.Text.StringBuilder();
- if (calling)
+ // 新增:显示自动呼叫状态
+ if (autoCallScheduled && calling)
+ {
+ int ticksLeft = callTick - Find.TickManager.TicksGame;
+ }
+ else if (calling)
{
int ticksLeft = callTick - Find.TickManager.TicksGame;
if (ticksLeft > 0)
@@ -732,7 +844,15 @@ namespace WulaFallenEmpire
}
else if (!used)
{
- sb.Append("WULA_ReadyToCallSkyfaller".Translate());
+ // 新增:显示非玩家派系自动呼叫信息
+ if (IsNonPlayerFaction && Props.canAutoCall)
+ {
+ sb.Append("WULA_AutoSkyfallerReady".Translate());
+ }
+ else
+ {
+ sb.Append("WULA_ReadyToCallSkyfaller".Translate());
+ }
if (Props.requireFlyOver && !HasRequiredFlyOver)
{
diff --git a/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/DebugActions_PrefabSkyfallerCaller.cs b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/DebugActions_PrefabSkyfallerCaller.cs
new file mode 100644
index 00000000..6d7fed40
--- /dev/null
+++ b/Source/WulaFallenEmpire/BuildingComp/WULA_SkyfallerCaller/DebugActions_PrefabSkyfallerCaller.cs
@@ -0,0 +1,428 @@
+using System.Collections.Generic;
+using System.Linq;
+using RimWorld;
+using UnityEngine;
+using Verse;
+using LudeonTK;
+
+namespace WulaFallenEmpire
+{
+ public class DebugActions_PrefabSkyfallerCaller
+ {
+ [DebugAction("Wula Fallen Empire", "Spawn Prefab Skyfaller Caller (Single)", actionType = DebugActionType.Action, allowedGameStates = AllowedGameStates.Playing)]
+ public static void SpawnPrefabSkyfallerCallerSingle()
+ {
+ var eligibleDefs = DefDatabase.AllDefs
+ .Where(def => def.comps != null && def.comps.Any(comp => comp is CompProperties_PrefabSkyfallerCaller))
+ .ToList();
+
+ if (!eligibleDefs.Any())
+ {
+ Log.Warning("[Debug] No ThingDefs found with CompProperties_PrefabSkyfallerCaller");
+ return;
+ }
+
+ var options = new List();
+ foreach (var thingDef in eligibleDefs)
+ {
+ options.Add(new DebugMenuOption(thingDef.defName, DebugMenuOptionMode.Tool, () =>
+ {
+ ShowFactionSelectionMenu(thingDef, false);
+ }));
+ }
+
+ Find.WindowStack.Add(new Dialog_DebugOptionListLister(options));
+ }
+
+ [DebugAction("Wula Fallen Empire", "Spawn Prefab Skyfaller Caller (x10)", actionType = DebugActionType.Action, allowedGameStates = AllowedGameStates.Playing)]
+ public static void SpawnPrefabSkyfallerCallerMultiple()
+ {
+ var eligibleDefs = DefDatabase.AllDefs
+ .Where(def => def.comps != null && def.comps.Any(comp => comp is CompProperties_PrefabSkyfallerCaller))
+ .ToList();
+
+ if (!eligibleDefs.Any())
+ {
+ Log.Warning("[Debug] No ThingDefs found with CompProperties_PrefabSkyfallerCaller");
+ return;
+ }
+
+ var options = new List();
+ foreach (var thingDef in eligibleDefs)
+ {
+ options.Add(new DebugMenuOption(thingDef.defName, DebugMenuOptionMode.Tool, () =>
+ {
+ ShowFactionSelectionMenu(thingDef, true);
+ }));
+ }
+
+ Find.WindowStack.Add(new Dialog_DebugOptionListLister(options));
+ }
+
+ private static void ShowFactionSelectionMenu(ThingDef thingDef, bool spawnMultiple)
+ {
+ var allFactions = Find.FactionManager.AllFactions.ToList();
+ var options = new List();
+
+ options.Add(new DebugMenuOption("No Faction", DebugMenuOptionMode.Tool, () =>
+ {
+ SpawnThingAtValidLocation(thingDef, null, spawnMultiple);
+ }));
+
+ foreach (var faction in allFactions)
+ {
+ options.Add(new DebugMenuOption(faction.Name, DebugMenuOptionMode.Tool, () =>
+ {
+ SpawnThingAtValidLocation(thingDef, faction, spawnMultiple);
+ }));
+ }
+
+ Find.WindowStack.Add(new Dialog_DebugOptionListLister(options));
+ }
+
+ private static void SpawnThingAtValidLocation(ThingDef thingDef, Faction faction, bool spawnMultiple)
+ {
+ var currentMap = Find.CurrentMap;
+ if (currentMap == null)
+ {
+ Log.Warning("[Debug] No current map found");
+ return;
+ }
+
+ int spawnCount = spawnMultiple ? 10 : 1;
+ int successCount = 0;
+ int attempts = 0;
+ const int maxAttempts = 50;
+
+ var compProps = thingDef.comps.OfType().FirstOrDefault();
+ if (compProps == null)
+ {
+ Log.Warning($"[Debug] Could not find CompProperties_PrefabSkyfallerCaller for {thingDef.defName}");
+ return;
+ }
+
+ Log.Message($"[Debug] Looking for spawn positions for {thingDef.defName} (Size: {thingDef.Size})");
+
+ for (int i = 0; i < spawnCount && attempts < maxAttempts; i++)
+ {
+ attempts++;
+ IntVec3 spawnPos = FindSpawnPositionForSkyfaller(currentMap, thingDef, compProps);
+
+ if (spawnPos.IsValid)
+ {
+ Thing thing = ThingMaker.MakeThing(thingDef);
+
+ if (faction != null)
+ {
+ thing.SetFaction(faction);
+ }
+
+ GenSpawn.Spawn(thing, spawnPos, currentMap);
+
+ successCount++;
+ Log.Message($"[Debug] Successfully spawned {thingDef.defName} at {spawnPos} for faction {faction?.Name ?? "None"}");
+ }
+ else
+ {
+ Log.Warning($"[Debug] Failed to find valid spawn position for {thingDef.defName} (attempt {attempts})");
+ }
+ }
+
+ if (successCount > 0)
+ {
+ Messages.Message($"[Debug] Successfully spawned {successCount} {thingDef.defName}", MessageTypeDefOf.PositiveEvent);
+ }
+ else
+ {
+ Messages.Message($"[Debug] Failed to spawn any {thingDef.defName} after {attempts} attempts", MessageTypeDefOf.NegativeEvent);
+ }
+ }
+
+ private static IntVec3 FindSpawnPositionForSkyfaller(Map map, ThingDef thingDef, CompProperties_SkyfallerCaller compProps)
+ {
+ // 基于Skyfaller实际行为的查找逻辑
+ var potentialCells = new List();
+
+ // 策略1:首先尝试玩家基地附近的开放区域
+ Log.Message($"[Debug] Searching near base area...");
+ var baseCells = GetOpenAreaCellsNearBase(map, thingDef.Size);
+ foreach (var cell in baseCells)
+ {
+ if (IsValidForSkyfallerDrop(map, cell, thingDef, compProps))
+ {
+ potentialCells.Add(cell);
+ }
+ if (potentialCells.Count > 20) break; // 找到足够位置就停止
+ }
+
+ if (potentialCells.Count > 0)
+ {
+ Log.Message($"[Debug] Found {potentialCells.Count} positions near base");
+ return potentialCells.RandomElement();
+ }
+
+ // 策略2:搜索整个地图的开阔区域
+ Log.Message($"[Debug] Searching open areas...");
+ var openAreas = FindOpenAreas(map, thingDef.Size, 1000);
+ foreach (var cell in openAreas)
+ {
+ if (IsValidForSkyfallerDrop(map, cell, thingDef, compProps))
+ {
+ potentialCells.Add(cell);
+ }
+ if (potentialCells.Count > 10) break;
+ }
+
+ if (potentialCells.Count > 0)
+ {
+ Log.Message($"[Debug] Found {potentialCells.Count} positions in open areas");
+ return potentialCells.RandomElement();
+ }
+
+ // 策略3:使用随机采样
+ Log.Message($"[Debug] Trying random sampling...");
+ for (int i = 0; i < 500; i++)
+ {
+ IntVec3 randomCell = new IntVec3(
+ Rand.Range(thingDef.Size.x, map.Size.x - thingDef.Size.x),
+ 0,
+ Rand.Range(thingDef.Size.z, map.Size.z - thingDef.Size.z)
+ );
+
+ if (randomCell.InBounds(map) && IsValidForSkyfallerDrop(map, randomCell, thingDef, compProps))
+ {
+ potentialCells.Add(randomCell);
+ }
+ if (potentialCells.Count > 5) break;
+ }
+
+ if (potentialCells.Count > 0)
+ {
+ Log.Message($"[Debug] Found {potentialCells.Count} positions via random sampling");
+ return potentialCells.RandomElement();
+ }
+
+ Log.Warning($"[Debug] No valid positions found for {thingDef.defName}");
+ return IntVec3.Invalid;
+ }
+
+ ///
+ /// 基于Skyfaller实际行为的有效性检查
+ ///
+ private static bool IsValidForSkyfallerDrop(Map map, IntVec3 cell, ThingDef thingDef, CompProperties_SkyfallerCaller compProps)
+ {
+ // 1. 检查边界
+ if (!cell.InBounds(map))
+ return false;
+
+ // 2. 检查整个建筑区域
+ CellRect occupiedRect = GenAdj.OccupiedRect(cell, Rot4.North, thingDef.Size);
+
+ foreach (IntVec3 occupiedCell in occupiedRect)
+ {
+ if (!occupiedCell.InBounds(map))
+ return false;
+
+ // 3. 检查厚岩顶 - 绝对不允许
+ RoofDef roof = occupiedCell.GetRoof(map);
+ if (roof != null && roof.isThickRoof)
+ {
+ if (!compProps.allowThickRoof)
+ return false;
+ }
+
+ // 4. 检查水体 - 不允许
+ TerrainDef terrain = occupiedCell.GetTerrain(map);
+ if (terrain != null && terrain.IsWater)
+ return false;
+
+ // 5. 检查建筑 - 不允许(但自然物体如树、石头是允许的)
+ var things = map.thingGrid.ThingsListAtFast(occupiedCell);
+ foreach (var thing in things)
+ {
+ // 允许自然物体(树、石头等),它们会被空投清除
+ if (thing.def.category == ThingCategory.Plant ||
+ thing.def.category == ThingCategory.Item ||
+ thing.def.category == ThingCategory.Filth)
+ {
+ continue; // 这些是可以被清除的
+ }
+
+ // 不允许建筑、蓝图、框架等
+ if (thing.def.category == ThingCategory.Building ||
+ thing.def.IsBlueprint ||
+ thing.def.IsFrame)
+ {
+ return false;
+ }
+
+ // 不允许其他不可清除的物体
+ if (thing.def.passability == Traversability.Impassable &&
+ thing.def.category != ThingCategory.Plant) // 植物是可清除的
+ {
+ return false;
+ }
+ }
+
+ // 6. 检查薄岩顶和普通屋顶的条件
+ if (roof != null && !roof.isThickRoof)
+ {
+ if (!compProps.allowThinRoof)
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ ///
+ /// 获取基地附近的开阔区域
+ ///
+ private static IEnumerable GetOpenAreaCellsNearBase(Map map, IntVec2 size)
+ {
+ var homeArea = map.areaManager.Home;
+ IntVec3 searchCenter;
+
+ if (homeArea != null && homeArea.ActiveCells.Any())
+ {
+ searchCenter = homeArea.ActiveCells.First();
+ }
+ else
+ {
+ searchCenter = new IntVec3(map.Size.x / 2, 0, map.Size.z / 2);
+ }
+
+ // 在基地周围搜索开阔区域
+ int searchRadius = 50;
+ var searchArea = CellRect.CenteredOn(searchCenter, searchRadius);
+
+ // 返回该区域内所有可能的中心点
+ foreach (var cell in searchArea.Cells)
+ {
+ if (!cell.InBounds(map)) continue;
+
+ // 检查这个位置周围是否有足够的开阔空间
+ if (IsAreaMostlyOpen(map, cell, size, 0.8f)) // 80%的区域需要是开阔的
+ {
+ yield return cell;
+ }
+ }
+ }
+
+ ///
+ /// 查找地图上的开阔区域
+ ///
+ private static IEnumerable FindOpenAreas(Map map, IntVec2 size, int maxCellsToCheck)
+ {
+ int cellsChecked = 0;
+
+ // 优先检查地图上已知的开阔区域
+ var allCells = map.AllCells.Where(c => c.InBounds(map)).ToList();
+
+ foreach (var cell in allCells)
+ {
+ if (cellsChecked >= maxCellsToCheck) yield break;
+ cellsChecked++;
+
+ // 快速检查:如果这个单元格本身就不适合,跳过
+ if (!cell.InBounds(map) || cell.GetTerrain(map).IsWater)
+ continue;
+
+ // 检查整个区域是否开阔
+ if (IsAreaMostlyOpen(map, cell, size, 0.7f)) // 70%的区域需要是开阔的
+ {
+ yield return cell;
+ }
+ }
+ }
+
+ ///
+ /// 检查区域是否大部分是开阔的(没有建筑,允许自然物体)
+ ///
+ private static bool IsAreaMostlyOpen(Map map, IntVec3 center, IntVec2 size, float openThreshold)
+ {
+ CellRect area = GenAdj.OccupiedRect(center, Rot4.North, size);
+ int totalCells = area.Area;
+ int openCells = 0;
+
+ foreach (IntVec3 cell in area)
+ {
+ if (!cell.InBounds(map))
+ {
+ continue; // 边界外的单元格不计入
+ }
+
+ // 检查是否有不可清除的建筑
+ bool hasBlockingBuilding = false;
+ var things = map.thingGrid.ThingsListAtFast(cell);
+ foreach (var thing in things)
+ {
+ if (thing.def.category == ThingCategory.Building ||
+ thing.def.IsBlueprint ||
+ thing.def.IsFrame ||
+ (thing.def.passability == Traversability.Impassable &&
+ thing.def.category != ThingCategory.Plant))
+ {
+ hasBlockingBuilding = true;
+ break;
+ }
+ }
+
+ // 检查水体
+ bool isWater = cell.GetTerrain(map).IsWater;
+
+ if (!hasBlockingBuilding && !isWater)
+ {
+ openCells++;
+ }
+ }
+
+ float openRatio = (float)openCells / totalCells;
+ return openRatio >= openThreshold;
+ }
+
+ ///
+ /// 强制清除区域(作为最后手段)
+ ///
+ private static bool TryForceClearAreaForSkyfaller(Map map, IntVec3 center, IntVec2 size)
+ {
+ try
+ {
+ CellRect clearRect = GenAdj.OccupiedRect(center, Rot4.North, size);
+ int clearedCount = 0;
+
+ foreach (IntVec3 cell in clearRect)
+ {
+ if (!cell.InBounds(map)) continue;
+
+ // 清除植物和物品
+ var thingsToRemove = map.thingGrid.ThingsAt(cell)
+ .Where(thing => thing.def.category == ThingCategory.Plant ||
+ thing.def.category == ThingCategory.Item ||
+ thing.def.category == ThingCategory.Filth)
+ .ToList();
+
+ foreach (var thing in thingsToRemove)
+ {
+ thing.Destroy();
+ clearedCount++;
+ }
+
+ // 确保不是水体
+ if (cell.GetTerrain(map).IsWater)
+ {
+ map.terrainGrid.SetTerrain(cell, TerrainDefOf.Soil);
+ }
+ }
+
+ Log.Message($"[Debug] Force cleared {clearedCount} objects for skyfaller drop");
+ return clearedCount > 0;
+ }
+ catch (System.Exception ex)
+ {
+ Log.Error($"[Debug] Error force clearing area: {ex}");
+ return false;
+ }
+ }
+ }
+}
diff --git a/Source/WulaFallenEmpire/QuestNodes/QuestNode_SpawnPrefabSkyfallerCaller.cs b/Source/WulaFallenEmpire/QuestNodes/QuestNode_SpawnPrefabSkyfallerCaller.cs
new file mode 100644
index 00000000..77e696a4
--- /dev/null
+++ b/Source/WulaFallenEmpire/QuestNodes/QuestNode_SpawnPrefabSkyfallerCaller.cs
@@ -0,0 +1,382 @@
+using System.Collections.Generic;
+using System.Linq;
+using RimWorld;
+using RimWorld.Planet;
+using UnityEngine;
+using Verse;
+using RimWorld.QuestGen;
+
+namespace WulaFallenEmpire
+{
+ public class QuestNode_SpawnPrefabSkyfallerCaller : QuestNode
+ {
+ [NoTranslate]
+ public SlateRef inSignal;
+ public SlateRef thingDef;
+ public SlateRef faction;
+ public SlateRef spawnCount = 1;
+ public SlateRef