1
This commit is contained in:
Binary file not shown.
@@ -148,4 +148,640 @@
|
||||
</WulaFloor>
|
||||
</terrain>
|
||||
</PrefabDef>
|
||||
|
||||
<PrefabDef>
|
||||
<defName>WULA_Bunker_Drop_Zone_Prefeb</defName> <!-- rename -->
|
||||
<size>(5,5)</size>
|
||||
<things>
|
||||
<WULA_Cat_Bunker>
|
||||
<position>(2, 0, 2)</position>
|
||||
</WULA_Cat_Bunker>
|
||||
<Sandbags>
|
||||
<rects>
|
||||
<li>(0,0,1,0)</li>
|
||||
<li>(3,0,4,0)</li>
|
||||
<li>(0,1,0,1)</li>
|
||||
<li>(4,1,4,1)</li>
|
||||
<li>(0,3,0,4)</li>
|
||||
<li>(4,3,4,4)</li>
|
||||
<li>(1,4,1,4)</li>
|
||||
<li>(3,4,3,4)</li>
|
||||
</rects>
|
||||
<stuff>Cloth</stuff>
|
||||
</Sandbags>
|
||||
</things>
|
||||
</PrefabDef>
|
||||
<PrefabDef>
|
||||
<defName>WULA_Turret_Group_Drop_Zone_Prefeb</defName> <!-- rename -->
|
||||
<size>(15,15)</size>
|
||||
<things>
|
||||
<Wula_Base_Laser_Turret>
|
||||
<positions>
|
||||
<li>(3, 0, 3)</li>
|
||||
<li>(11, 0, 3)</li>
|
||||
<li>(3, 0, 11)</li>
|
||||
<li>(11, 0, 11)</li>
|
||||
</positions>
|
||||
</Wula_Base_Laser_Turret>
|
||||
<Wula_Fusion_Generators>
|
||||
<position>(7, 0, 7)</position>
|
||||
</Wula_Fusion_Generators>
|
||||
<WULA_Cat_Bunker>
|
||||
<positions>
|
||||
<li>(7, 0, 1)</li>
|
||||
<li>(1, 0, 7)</li>
|
||||
<li>(13, 0, 7)</li>
|
||||
<li>(7, 0, 13)</li>
|
||||
</positions>
|
||||
</WULA_Cat_Bunker>
|
||||
<FloodLight>
|
||||
<rects>
|
||||
<li>(7,3,7,3)</li>
|
||||
<li>(3,7,3,7)</li>
|
||||
<li>(11,7,11,7)</li>
|
||||
<li>(7,11,7,11)</li>
|
||||
</rects>
|
||||
</FloodLight>
|
||||
<WulaWall>
|
||||
<rects>
|
||||
<li>(5,5,9,5)</li>
|
||||
<li>(5,6,5,9)</li>
|
||||
<li>(9,6,9,9)</li>
|
||||
<li>(6,9,8,9)</li>
|
||||
</rects>
|
||||
</WulaWall>
|
||||
<Sandbags>
|
||||
<rects>
|
||||
<li>(1,1,5,1)</li>
|
||||
<li>(9,1,13,1)</li>
|
||||
<li>(1,2,1,5)</li>
|
||||
<li>(5,2,5,2)</li>
|
||||
<li>(9,2,9,2)</li>
|
||||
<li>(13,2,13,5)</li>
|
||||
<li>(2,5,2,5)</li>
|
||||
<li>(12,5,12,5)</li>
|
||||
<li>(1,9,2,9)</li>
|
||||
<li>(12,9,13,9)</li>
|
||||
<li>(1,10,1,13)</li>
|
||||
<li>(13,10,13,13)</li>
|
||||
<li>(5,12,5,13)</li>
|
||||
<li>(9,12,9,13)</li>
|
||||
<li>(2,13,4,13)</li>
|
||||
<li>(10,13,12,13)</li>
|
||||
</rects>
|
||||
<stuff>Cloth</stuff>
|
||||
</Sandbags>
|
||||
</things>
|
||||
</PrefabDef>
|
||||
<PrefabDef>
|
||||
<defName>WULA_Fortress_Drop_Zone_Prefeb</defName> <!-- rename -->
|
||||
<size>(25,25)</size>
|
||||
<things>
|
||||
<WulaDoor>
|
||||
<rects>
|
||||
<li>(7,6,7,6)</li>
|
||||
<li>(9,6,9,6)</li>
|
||||
<li>(15,6,15,6)</li>
|
||||
<li>(17,6,17,6)</li>
|
||||
<li>(12,8,12,8)</li>
|
||||
<li>(12,16,12,16)</li>
|
||||
<li>(7,18,7,18)</li>
|
||||
<li>(9,18,9,18)</li>
|
||||
<li>(15,18,15,18)</li>
|
||||
<li>(17,18,17,18)</li>
|
||||
</rects>
|
||||
<relativeRotation>Clockwise</relativeRotation>
|
||||
</WulaDoor>
|
||||
<WulaDoor>
|
||||
<rects>
|
||||
<li>(6,7,6,7)</li>
|
||||
<li>(18,7,18,7)</li>
|
||||
<li>(6,9,6,9)</li>
|
||||
<li>(18,9,18,9)</li>
|
||||
<li>(8,12,8,12)</li>
|
||||
<li>(16,12,16,12)</li>
|
||||
<li>(6,15,6,15)</li>
|
||||
<li>(18,15,18,15)</li>
|
||||
<li>(6,17,6,17)</li>
|
||||
<li>(18,17,18,17)</li>
|
||||
</rects>
|
||||
</WulaDoor>
|
||||
<WULA_Wall_Flag_Building>
|
||||
<rects>
|
||||
<li>(10,6,10,6)</li>
|
||||
<li>(14,6,14,6)</li>
|
||||
</rects>
|
||||
</WULA_Wall_Flag_Building>
|
||||
<WULA_Wall_Flag_Building>
|
||||
<rects>
|
||||
<li>(6,10,6,10)</li>
|
||||
<li>(6,14,6,14)</li>
|
||||
</rects>
|
||||
<relativeRotation>Clockwise</relativeRotation>
|
||||
</WULA_Wall_Flag_Building>
|
||||
<WULA_Wall_Flag_Building>
|
||||
<rects>
|
||||
<li>(18,10,18,10)</li>
|
||||
<li>(18,14,18,14)</li>
|
||||
</rects>
|
||||
<relativeRotation>Counterclockwise</relativeRotation>
|
||||
</WULA_Wall_Flag_Building>
|
||||
<WULA_Wall_Flag_Building>
|
||||
<rects>
|
||||
<li>(10,18,10,18)</li>
|
||||
<li>(14,18,14,18)</li>
|
||||
</rects>
|
||||
<relativeRotation>Opposite</relativeRotation>
|
||||
</WULA_Wall_Flag_Building>
|
||||
<WULA_Cat_Bunker>
|
||||
<positions>
|
||||
<li>(5, 0, 1)</li>
|
||||
<li>(19, 0, 1)</li>
|
||||
<li>(1, 0, 5)</li>
|
||||
<li>(23, 0, 5)</li>
|
||||
<li>(1, 0, 19)</li>
|
||||
<li>(23, 0, 19)</li>
|
||||
<li>(19, 0, 23)</li>
|
||||
</positions>
|
||||
</WULA_Cat_Bunker>
|
||||
<WULA_Cat_Bunker>
|
||||
<position>(5, 0, 23)</position>
|
||||
<hp>476</hp>
|
||||
</WULA_Cat_Bunker>
|
||||
<Wula_Base_Mortar_Turret>
|
||||
<positions>
|
||||
<li>(5, 0, 5)</li>
|
||||
<li>(19, 0, 5)</li>
|
||||
<li>(5, 0, 19)</li>
|
||||
<li>(19, 0, 19)</li>
|
||||
</positions>
|
||||
</Wula_Base_Mortar_Turret>
|
||||
<Wula_Base_ATGun_Turret>
|
||||
<positions>
|
||||
<li>(9, 0, 3)</li>
|
||||
<li>(15, 0, 3)</li>
|
||||
<li>(3, 0, 9)</li>
|
||||
<li>(21, 0, 9)</li>
|
||||
<li>(3, 0, 15)</li>
|
||||
<li>(21, 0, 15)</li>
|
||||
<li>(9, 0, 21)</li>
|
||||
<li>(15, 0, 21)</li>
|
||||
</positions>
|
||||
</Wula_Base_ATGun_Turret>
|
||||
<FloodLight>
|
||||
<rects>
|
||||
<li>(10,5,10,5)</li>
|
||||
<li>(14,5,14,5)</li>
|
||||
<li>(5,10,5,10)</li>
|
||||
<li>(19,10,19,10)</li>
|
||||
<li>(5,14,5,14)</li>
|
||||
<li>(19,14,19,14)</li>
|
||||
<li>(10,19,10,19)</li>
|
||||
<li>(14,19,14,19)</li>
|
||||
</rects>
|
||||
</FloodLight>
|
||||
<WulaWall>
|
||||
<rects>
|
||||
<li>(3,3,7,3)</li>
|
||||
<li>(17,3,21,3)</li>
|
||||
<li>(3,4,3,7)</li>
|
||||
<li>(7,4,7,5)</li>
|
||||
<li>(17,4,17,5)</li>
|
||||
<li>(21,4,21,7)</li>
|
||||
<li>(8,5,9,5)</li>
|
||||
<li>(15,5,16,5)</li>
|
||||
<li>(4,7,5,7)</li>
|
||||
<li>(7,7,7,7)</li>
|
||||
<li>(9,7,15,7)</li>
|
||||
<li>(17,7,17,7)</li>
|
||||
<li>(19,7,20,7)</li>
|
||||
<li>(5,8,5,9)</li>
|
||||
<li>(19,8,19,9)</li>
|
||||
<li>(7,9,7,15)</li>
|
||||
<li>(9,9,15,9)</li>
|
||||
<li>(17,9,17,15)</li>
|
||||
<li>(9,10,9,15)</li>
|
||||
<li>(15,10,15,15)</li>
|
||||
<li>(5,15,5,17)</li>
|
||||
<li>(10,15,14,15)</li>
|
||||
<li>(19,15,19,17)</li>
|
||||
<li>(3,17,4,17)</li>
|
||||
<li>(7,17,7,17)</li>
|
||||
<li>(9,17,15,17)</li>
|
||||
<li>(17,17,17,17)</li>
|
||||
<li>(20,17,21,17)</li>
|
||||
<li>(3,18,3,21)</li>
|
||||
<li>(21,18,21,21)</li>
|
||||
<li>(7,19,9,19)</li>
|
||||
<li>(15,19,17,19)</li>
|
||||
<li>(7,20,7,21)</li>
|
||||
<li>(17,20,17,21)</li>
|
||||
<li>(4,21,6,21)</li>
|
||||
<li>(18,21,20,21)</li>
|
||||
</rects>
|
||||
</WulaWall>
|
||||
<Wula_DarkEnergy_Generators>
|
||||
<position>(12, 0, 12)</position>
|
||||
</Wula_DarkEnergy_Generators>
|
||||
<Sandbags>
|
||||
<rects>
|
||||
<li>(7,1,11,1)</li>
|
||||
<li>(13,1,17,1)</li>
|
||||
<li>(7,2,7,2)</li>
|
||||
<li>(11,2,11,2)</li>
|
||||
<li>(13,2,13,2)</li>
|
||||
<li>(17,2,17,2)</li>
|
||||
<li>(1,7,2,7)</li>
|
||||
<li>(22,7,23,7)</li>
|
||||
<li>(1,8,1,11)</li>
|
||||
<li>(23,8,23,11)</li>
|
||||
<li>(2,11,2,11)</li>
|
||||
<li>(22,11,22,11)</li>
|
||||
<li>(1,13,2,13)</li>
|
||||
<li>(22,13,23,13)</li>
|
||||
<li>(1,14,1,17)</li>
|
||||
<li>(23,14,23,17)</li>
|
||||
<li>(2,17,2,17)</li>
|
||||
<li>(22,17,22,17)</li>
|
||||
<li>(7,22,7,23)</li>
|
||||
<li>(11,22,11,23)</li>
|
||||
<li>(13,22,13,23)</li>
|
||||
<li>(17,22,17,23)</li>
|
||||
<li>(8,23,10,23)</li>
|
||||
<li>(14,23,16,23)</li>
|
||||
</rects>
|
||||
<stuff>Cloth</stuff>
|
||||
</Sandbags>
|
||||
</things>
|
||||
<terrain>
|
||||
<WulaFloor>
|
||||
<rects>
|
||||
<li>(3,3,7,7)</li>
|
||||
<li>(17,3,21,7)</li>
|
||||
<li>(8,5,9,19)</li>
|
||||
<li>(15,5,16,19)</li>
|
||||
<li>(10,7,14,17)</li>
|
||||
<li>(5,8,7,9)</li>
|
||||
<li>(17,8,19,9)</li>
|
||||
<li>(7,10,7,21)</li>
|
||||
<li>(17,10,17,21)</li>
|
||||
<li>(5,15,6,21)</li>
|
||||
<li>(18,15,19,21)</li>
|
||||
<li>(3,17,4,21)</li>
|
||||
<li>(20,17,21,21)</li>
|
||||
</rects>
|
||||
</WulaFloor>
|
||||
</terrain>
|
||||
</PrefabDef>
|
||||
|
||||
<PrefabDef>
|
||||
<defName>WULA_Huge_Fortress_Drop_Zone_Prefeb</defName> <!-- rename -->
|
||||
<size>(44,44)</size>
|
||||
<things>
|
||||
<Battery>
|
||||
<positions>
|
||||
<li>(14, 0, 12)</li>
|
||||
<li>(15, 0, 12)</li>
|
||||
<li>(16, 0, 12)</li>
|
||||
<li>(14, 0, 32)</li>
|
||||
<li>(15, 0, 32)</li>
|
||||
<li>(16, 0, 32)</li>
|
||||
<li>(27, 0, 32)</li>
|
||||
<li>(28, 0, 32)</li>
|
||||
<li>(29, 0, 32)</li>
|
||||
</positions>
|
||||
<relativeRotation>Opposite</relativeRotation>
|
||||
</Battery>
|
||||
<Battery>
|
||||
<positions>
|
||||
<li>(27, 0, 11)</li>
|
||||
<li>(28, 0, 11)</li>
|
||||
<li>(29, 0, 11)</li>
|
||||
</positions>
|
||||
</Battery>
|
||||
<Battery>
|
||||
<positions>
|
||||
<li>(12, 0, 14)</li>
|
||||
<li>(12, 0, 15)</li>
|
||||
<li>(12, 0, 16)</li>
|
||||
</positions>
|
||||
<relativeRotation>Counterclockwise</relativeRotation>
|
||||
</Battery>
|
||||
<Battery>
|
||||
<positions>
|
||||
<li>(31, 0, 14)</li>
|
||||
<li>(31, 0, 15)</li>
|
||||
<li>(31, 0, 16)</li>
|
||||
<li>(11, 0, 27)</li>
|
||||
<li>(31, 0, 27)</li>
|
||||
<li>(11, 0, 28)</li>
|
||||
<li>(31, 0, 28)</li>
|
||||
<li>(11, 0, 29)</li>
|
||||
<li>(31, 0, 29)</li>
|
||||
</positions>
|
||||
<relativeRotation>Clockwise</relativeRotation>
|
||||
</Battery>
|
||||
<Wula_Base_Laser_Turret>
|
||||
<positions>
|
||||
<li>(16, 0, 8)</li>
|
||||
<li>(27, 0, 8)</li>
|
||||
<li>(8, 0, 16)</li>
|
||||
<li>(35, 0, 16)</li>
|
||||
<li>(8, 0, 27)</li>
|
||||
<li>(35, 0, 27)</li>
|
||||
<li>(16, 0, 35)</li>
|
||||
<li>(27, 0, 35)</li>
|
||||
</positions>
|
||||
</Wula_Base_Laser_Turret>
|
||||
<WulaDoor>
|
||||
<rects>
|
||||
<li>(12,11,12,11)</li>
|
||||
<li>(31,11,31,11)</li>
|
||||
<li>(20,12,20,12)</li>
|
||||
<li>(23,12,23,12)</li>
|
||||
<li>(15,14,15,14)</li>
|
||||
<li>(28,14,28,14)</li>
|
||||
<li>(13,17,13,17)</li>
|
||||
<li>(30,17,30,17)</li>
|
||||
<li>(21,19,22,19)</li>
|
||||
<li>(21,24,22,24)</li>
|
||||
<li>(13,26,13,26)</li>
|
||||
<li>(30,26,30,26)</li>
|
||||
<li>(15,29,15,29)</li>
|
||||
<li>(28,29,28,29)</li>
|
||||
<li>(20,31,20,31)</li>
|
||||
<li>(23,31,23,31)</li>
|
||||
<li>(12,32,12,32)</li>
|
||||
<li>(31,32,31,32)</li>
|
||||
</rects>
|
||||
</WulaDoor>
|
||||
<WulaDoor>
|
||||
<rects>
|
||||
<li>(11,12,11,12)</li>
|
||||
<li>(32,12,32,12)</li>
|
||||
<li>(17,13,17,13)</li>
|
||||
<li>(26,13,26,13)</li>
|
||||
<li>(14,15,14,15)</li>
|
||||
<li>(29,15,29,15)</li>
|
||||
<li>(12,20,12,20)</li>
|
||||
<li>(31,20,31,20)</li>
|
||||
<li>(19,21,19,22)</li>
|
||||
<li>(24,21,24,22)</li>
|
||||
<li>(12,23,12,23)</li>
|
||||
<li>(31,23,31,23)</li>
|
||||
<li>(14,28,14,28)</li>
|
||||
<li>(29,28,29,28)</li>
|
||||
<li>(17,30,17,30)</li>
|
||||
<li>(26,30,26,30)</li>
|
||||
<li>(11,31,11,31)</li>
|
||||
<li>(32,31,32,31)</li>
|
||||
</rects>
|
||||
<relativeRotation>Clockwise</relativeRotation>
|
||||
</WulaDoor>
|
||||
<WULA_Cat_Bunker>
|
||||
<positions>
|
||||
<li>(2, 0, 2)</li>
|
||||
<li>(41, 0, 2)</li>
|
||||
<li>(19, 0, 5)</li>
|
||||
<li>(24, 0, 5)</li>
|
||||
<li>(38, 0, 19)</li>
|
||||
<li>(5, 0, 20)</li>
|
||||
<li>(5, 0, 24)</li>
|
||||
<li>(38, 0, 24)</li>
|
||||
<li>(19, 0, 38)</li>
|
||||
<li>(24, 0, 38)</li>
|
||||
<li>(2, 0, 41)</li>
|
||||
<li>(41, 0, 41)</li>
|
||||
</positions>
|
||||
</WULA_Cat_Bunker>
|
||||
<Wula_Base_Mortar_Turret>
|
||||
<positions>
|
||||
<li>(8, 0, 8)</li>
|
||||
<li>(12, 0, 8)</li>
|
||||
<li>(31, 0, 8)</li>
|
||||
<li>(35, 0, 8)</li>
|
||||
<li>(8, 0, 12)</li>
|
||||
<li>(35, 0, 12)</li>
|
||||
<li>(8, 0, 31)</li>
|
||||
<li>(35, 0, 31)</li>
|
||||
<li>(8, 0, 35)</li>
|
||||
<li>(12, 0, 35)</li>
|
||||
<li>(31, 0, 35)</li>
|
||||
<li>(35, 0, 35)</li>
|
||||
</positions>
|
||||
</Wula_Base_Mortar_Turret>
|
||||
<FirefoamPopper>
|
||||
<rects>
|
||||
<li>(5,5,5,5)</li>
|
||||
<li>(38,5,38,5)</li>
|
||||
<li>(18,9,18,9)</li>
|
||||
<li>(25,9,25,9)</li>
|
||||
<li>(10,10,10,10)</li>
|
||||
<li>(33,10,33,10)</li>
|
||||
<li>(13,13,13,13)</li>
|
||||
<li>(30,13,30,13)</li>
|
||||
<li>(9,18,9,18)</li>
|
||||
<li>(34,18,34,18)</li>
|
||||
<li>(9,25,9,25)</li>
|
||||
<li>(34,25,34,25)</li>
|
||||
<li>(13,30,13,30)</li>
|
||||
<li>(30,30,30,30)</li>
|
||||
<li>(10,33,10,33)</li>
|
||||
<li>(33,33,33,33)</li>
|
||||
<li>(18,34,18,34)</li>
|
||||
<li>(25,34,25,34)</li>
|
||||
<li>(5,38,5,38)</li>
|
||||
<li>(38,38,38,38)</li>
|
||||
</rects>
|
||||
</FirefoamPopper>
|
||||
<Wula_Base_ATGun_Turret>
|
||||
<positions>
|
||||
<li>(8, 0, 3)</li>
|
||||
<li>(12, 0, 3)</li>
|
||||
<li>(31, 0, 3)</li>
|
||||
<li>(35, 0, 3)</li>
|
||||
<li>(3, 0, 8)</li>
|
||||
<li>(40, 0, 8)</li>
|
||||
<li>(3, 0, 12)</li>
|
||||
<li>(40, 0, 12)</li>
|
||||
<li>(3, 0, 31)</li>
|
||||
<li>(40, 0, 31)</li>
|
||||
<li>(3, 0, 35)</li>
|
||||
<li>(40, 0, 35)</li>
|
||||
<li>(8, 0, 40)</li>
|
||||
<li>(12, 0, 40)</li>
|
||||
<li>(31, 0, 40)</li>
|
||||
<li>(35, 0, 40)</li>
|
||||
</positions>
|
||||
</Wula_Base_ATGun_Turret>
|
||||
<WulaWall>
|
||||
<rects>
|
||||
<li>(6,6,14,6)</li>
|
||||
<li>(29,6,37,6)</li>
|
||||
<li>(6,7,6,14)</li>
|
||||
<li>(14,7,14,10)</li>
|
||||
<li>(29,7,29,10)</li>
|
||||
<li>(37,7,37,14)</li>
|
||||
<li>(13,10,13,11)</li>
|
||||
<li>(15,10,17,10)</li>
|
||||
<li>(26,10,28,10)</li>
|
||||
<li>(30,10,30,11)</li>
|
||||
<li>(11,11,11,11)</li>
|
||||
<li>(17,11,17,12)</li>
|
||||
<li>(26,11,26,12)</li>
|
||||
<li>(32,11,32,11)</li>
|
||||
<li>(18,12,19,12)</li>
|
||||
<li>(21,12,22,12)</li>
|
||||
<li>(24,12,25,12)</li>
|
||||
<li>(10,13,11,13)</li>
|
||||
<li>(32,13,33,13)</li>
|
||||
<li>(7,14,10,14)</li>
|
||||
<li>(14,14,14,14)</li>
|
||||
<li>(16,14,20,14)</li>
|
||||
<li>(23,14,27,14)</li>
|
||||
<li>(29,14,29,14)</li>
|
||||
<li>(33,14,36,14)</li>
|
||||
<li>(10,15,10,17)</li>
|
||||
<li>(20,15,20,20)</li>
|
||||
<li>(23,15,23,20)</li>
|
||||
<li>(33,15,33,17)</li>
|
||||
<li>(14,16,14,20)</li>
|
||||
<li>(29,16,29,20)</li>
|
||||
<li>(11,17,12,17)</li>
|
||||
<li>(31,17,32,17)</li>
|
||||
<li>(12,18,12,19)</li>
|
||||
<li>(31,18,31,19)</li>
|
||||
<li>(15,20,19,20)</li>
|
||||
<li>(24,20,28,20)</li>
|
||||
<li>(12,21,12,22)</li>
|
||||
<li>(31,21,31,22)</li>
|
||||
<li>(14,23,20,23)</li>
|
||||
<li>(23,23,29,23)</li>
|
||||
<li>(12,24,12,26)</li>
|
||||
<li>(14,24,14,27)</li>
|
||||
<li>(20,24,20,29)</li>
|
||||
<li>(23,24,23,29)</li>
|
||||
<li>(29,24,29,27)</li>
|
||||
<li>(31,24,31,26)</li>
|
||||
<li>(10,26,11,26)</li>
|
||||
<li>(32,26,33,26)</li>
|
||||
<li>(10,27,10,30)</li>
|
||||
<li>(33,27,33,30)</li>
|
||||
<li>(6,29,9,29)</li>
|
||||
<li>(14,29,14,29)</li>
|
||||
<li>(16,29,19,29)</li>
|
||||
<li>(24,29,27,29)</li>
|
||||
<li>(29,29,29,29)</li>
|
||||
<li>(34,29,37,29)</li>
|
||||
<li>(6,30,6,37)</li>
|
||||
<li>(11,30,11,30)</li>
|
||||
<li>(32,30,32,30)</li>
|
||||
<li>(37,30,37,37)</li>
|
||||
<li>(17,31,19,31)</li>
|
||||
<li>(21,31,22,31)</li>
|
||||
<li>(24,31,26,31)</li>
|
||||
<li>(11,32,11,32)</li>
|
||||
<li>(13,32,13,33)</li>
|
||||
<li>(17,32,17,33)</li>
|
||||
<li>(26,32,26,33)</li>
|
||||
<li>(30,32,30,33)</li>
|
||||
<li>(32,32,32,32)</li>
|
||||
<li>(14,33,16,33)</li>
|
||||
<li>(27,33,29,33)</li>
|
||||
<li>(14,34,14,37)</li>
|
||||
<li>(29,34,29,37)</li>
|
||||
<li>(7,37,13,37)</li>
|
||||
<li>(30,37,36,37)</li>
|
||||
</rects>
|
||||
</WulaWall>
|
||||
<Wula_DarkEnergy_Generators>
|
||||
<positions>
|
||||
<li>(17, 0, 17)</li>
|
||||
<li>(26, 0, 17)</li>
|
||||
<li>(17, 0, 26)</li>
|
||||
<li>(26, 0, 26)</li>
|
||||
</positions>
|
||||
</Wula_DarkEnergy_Generators>
|
||||
<Sandbags>
|
||||
<rects>
|
||||
<li>(0,0,3,0)</li>
|
||||
<li>(40,0,43,0)</li>
|
||||
<li>(0,1,0,3)</li>
|
||||
<li>(6,1,14,1)</li>
|
||||
<li>(29,1,37,1)</li>
|
||||
<li>(43,1,43,3)</li>
|
||||
<li>(6,2,6,3)</li>
|
||||
<li>(14,2,14,3)</li>
|
||||
<li>(29,2,29,3)</li>
|
||||
<li>(37,2,37,3)</li>
|
||||
<li>(17,3,20,3)</li>
|
||||
<li>(23,3,26,3)</li>
|
||||
<li>(17,4,17,6)</li>
|
||||
<li>(26,4,26,6)</li>
|
||||
<li>(1,6,3,6)</li>
|
||||
<li>(15,6,16,6)</li>
|
||||
<li>(27,6,28,6)</li>
|
||||
<li>(40,6,42,6)</li>
|
||||
<li>(1,7,1,14)</li>
|
||||
<li>(42,7,42,14)</li>
|
||||
<li>(2,14,3,14)</li>
|
||||
<li>(40,14,41,14)</li>
|
||||
<li>(6,15,6,18)</li>
|
||||
<li>(37,15,37,17)</li>
|
||||
<li>(38,17,40,17)</li>
|
||||
<li>(3,18,5,18)</li>
|
||||
<li>(40,18,40,20)</li>
|
||||
<li>(3,19,3,21)</li>
|
||||
<li>(3,23,3,26)</li>
|
||||
<li>(40,23,40,26)</li>
|
||||
<li>(4,26,6,26)</li>
|
||||
<li>(37,26,39,26)</li>
|
||||
<li>(6,27,6,28)</li>
|
||||
<li>(37,27,37,28)</li>
|
||||
<li>(1,29,3,29)</li>
|
||||
<li>(40,29,42,29)</li>
|
||||
<li>(1,30,1,37)</li>
|
||||
<li>(42,30,42,37)</li>
|
||||
<li>(2,37,3,37)</li>
|
||||
<li>(15,37,17,37)</li>
|
||||
<li>(26,37,28,37)</li>
|
||||
<li>(40,37,41,37)</li>
|
||||
<li>(17,38,17,40)</li>
|
||||
<li>(26,38,26,40)</li>
|
||||
<li>(0,40,0,43)</li>
|
||||
<li>(6,40,6,42)</li>
|
||||
<li>(14,40,14,42)</li>
|
||||
<li>(18,40,20,40)</li>
|
||||
<li>(23,40,25,40)</li>
|
||||
<li>(29,40,29,42)</li>
|
||||
<li>(37,40,37,42)</li>
|
||||
<li>(43,40,43,43)</li>
|
||||
<li>(7,42,13,42)</li>
|
||||
<li>(30,42,36,42)</li>
|
||||
<li>(1,43,3,43)</li>
|
||||
<li>(40,43,42,43)</li>
|
||||
</rects>
|
||||
<stuff>Cloth</stuff>
|
||||
</Sandbags>
|
||||
</things>
|
||||
<terrain>
|
||||
<WulaFloor>
|
||||
<rects>
|
||||
<li>(6,6,14,14)</li>
|
||||
<li>(29,6,37,14)</li>
|
||||
<li>(15,10,17,33)</li>
|
||||
<li>(26,10,28,33)</li>
|
||||
<li>(18,12,25,31)</li>
|
||||
<li>(10,15,14,17)</li>
|
||||
<li>(29,15,33,17)</li>
|
||||
<li>(12,18,14,37)</li>
|
||||
<li>(29,18,31,37)</li>
|
||||
<li>(10,26,11,37)</li>
|
||||
<li>(32,26,33,37)</li>
|
||||
<li>(6,29,9,37)</li>
|
||||
<li>(34,29,37,37)</li>
|
||||
</rects>
|
||||
</WulaFloor>
|
||||
</terrain>
|
||||
</PrefabDef>
|
||||
</Defs>
|
||||
@@ -0,0 +1,294 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Defs>
|
||||
<IncidentDef>
|
||||
<defName>WULA_GiveQuest_Hostile_PIA_Attack_Quest</defName>
|
||||
<category>GiveQuest</category>
|
||||
<label>要塞空投</label>
|
||||
<targetTags>
|
||||
<li>Map_PlayerHome</li>
|
||||
</targetTags>
|
||||
<questScriptDef>WULA_Hostile_PIA_Attack_Quest</questScriptDef>
|
||||
<workerClass>IncidentWorker_GiveQuest</workerClass>
|
||||
<baseChance>0</baseChance>
|
||||
</IncidentDef>
|
||||
<QuestScriptDef>
|
||||
<defName>WULA_Hostile_PIA_Attack_Quest</defName>
|
||||
<rootSelectionWeight>0</rootSelectionWeight>
|
||||
<autoAccept>true</autoAccept>
|
||||
<sendAvailableLetter>false</sendAvailableLetter>
|
||||
<defaultChallengeRating>1</defaultChallengeRating> <!-- 挑战等级(星级) -->
|
||||
<isRootSpecial>true</isRootSpecial> <!-- 特殊任务 -->
|
||||
<defaultCharity>false</defaultCharity> <!-- 是否仁善 -->
|
||||
<!-- 命名规则 -->
|
||||
<questNameRules>
|
||||
<rulesStrings>
|
||||
<li>questName->WULA_Hostile_PIA_Attack_Quest_questName</li>
|
||||
</rulesStrings>
|
||||
</questNameRules>
|
||||
<questDescriptionRules>
|
||||
<include>
|
||||
<li>QuestHospitalityCommon</li>
|
||||
</include>
|
||||
<rulesStrings>
|
||||
<li>questDescription->WULA_Hostile_PIA_Attack_Quest_questDescription</li>
|
||||
</rulesStrings>
|
||||
</questDescriptionRules>
|
||||
|
||||
<!-- 运行规则 -->
|
||||
<root Class="QuestNode_Sequence">
|
||||
<nodes>
|
||||
<!-- 获取地图 -->
|
||||
<li Class="QuestNode_GetMap" />
|
||||
|
||||
<!-- 随机 -->
|
||||
<li Class="QuestNode_RandomNode">
|
||||
<nodes>
|
||||
<!-- 要塞空投 -->
|
||||
<li Class="QuestNode_Sequence">
|
||||
<nodes>
|
||||
<li Class="QuestNode_ResolveQuestName">
|
||||
<rules>
|
||||
<rulesStrings>
|
||||
<li>questName->要塞空投</li>
|
||||
</rulesStrings>
|
||||
</rules>
|
||||
</li>
|
||||
<li Class="QuestNode_ResolveQuestDescription">
|
||||
<rules>
|
||||
<rulesStrings>
|
||||
<li>questDescription->乌拉帝国 行星封锁机关对殖民地发起了报复打击,她们往殖民地空投了整装的要塞!</li>
|
||||
</rulesStrings>
|
||||
</rules>
|
||||
</li>
|
||||
<li Class="QuestNode_Letter">
|
||||
<label>要塞空投</label>
|
||||
<letterDef>NegativeEvent</letterDef>
|
||||
<text>乌拉帝国 行星封锁机关对殖民地发起了报复打击,她们往殖民地空投了整装的要塞!</text>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Bunker_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>1</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
<li Class="QuestNode_Greater">
|
||||
<value1>$points</value1>
|
||||
<value2>1000</value2>
|
||||
|
||||
<node Class="QuestNode_Sequence">
|
||||
<nodes>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Bunker_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>4</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
</nodes>
|
||||
</node>
|
||||
</li>
|
||||
<li Class="QuestNode_Greater">
|
||||
<value1>$points</value1>
|
||||
<value2>2999</value2>
|
||||
|
||||
<node Class="QuestNode_Sequence">
|
||||
<nodes>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Turret_Group_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>2</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
</nodes>
|
||||
</node>
|
||||
</li>
|
||||
<li Class="QuestNode_Greater">
|
||||
<value1>$points</value1>
|
||||
<value2>5999</value2>
|
||||
|
||||
<!-- Lodgers arrive by shuttle -->
|
||||
<node Class="QuestNode_Sequence">
|
||||
<nodes>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Fortress_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>1</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
<li Class="QuestNode_Less">
|
||||
<value1>$prefabSpawnSuccessCount</value1>
|
||||
<value2>$prefabSpawnRequestedCount</value2>
|
||||
|
||||
<node Class="QuestNode_Sequence">
|
||||
<nodes>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Turret_Group_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>3</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
</nodes>
|
||||
</node>
|
||||
</li>
|
||||
</nodes>
|
||||
</node>
|
||||
</li>
|
||||
<li Class="QuestNode_Greater">
|
||||
<value1>$points</value1>
|
||||
<value2>7999</value2>
|
||||
|
||||
<!-- Lodgers arrive by shuttle -->
|
||||
<node Class="QuestNode_Sequence">
|
||||
<nodes>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Fortress_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>1</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
<li Class="QuestNode_Less">
|
||||
<value1>$prefabSpawnSuccessCount</value1>
|
||||
<value2>$prefabSpawnRequestedCount</value2>
|
||||
|
||||
<node Class="QuestNode_Sequence">
|
||||
<nodes>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Turret_Group_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>3</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
</nodes>
|
||||
</node>
|
||||
</li>
|
||||
</nodes>
|
||||
</node>
|
||||
</li>
|
||||
<li Class="QuestNode_Greater">
|
||||
<value1>$points</value1>
|
||||
<value2>9999</value2>
|
||||
|
||||
<!-- Lodgers arrive by shuttle -->
|
||||
<node Class="QuestNode_Sequence">
|
||||
<nodes>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Huge_Fortress_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>1</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
<li Class="QuestNode_Less">
|
||||
<value1>$prefabSpawnSuccessCount</value1>
|
||||
<value2>$prefabSpawnRequestedCount</value2>
|
||||
|
||||
<node Class="QuestNode_Sequence">
|
||||
<nodes>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Fortress_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>2</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
</nodes>
|
||||
</node>
|
||||
</li>
|
||||
</nodes>
|
||||
</node>
|
||||
</li>
|
||||
<li Class="QuestNode_Greater">
|
||||
<value1>$points</value1>
|
||||
<value2>12999</value2>
|
||||
|
||||
<!-- Lodgers arrive by shuttle -->
|
||||
<node Class="QuestNode_Sequence">
|
||||
<nodes>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Bunker_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>4</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Fortress_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>1</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
<li Class="QuestNode_Less">
|
||||
<value1>$prefabSpawnSuccessCount</value1>
|
||||
<value2>$prefabSpawnRequestedCount</value2>
|
||||
|
||||
<node Class="QuestNode_Sequence">
|
||||
<nodes>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Turret_Group_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>3</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
</nodes>
|
||||
</node>
|
||||
</li>
|
||||
</nodes>
|
||||
</node>
|
||||
</li>
|
||||
<li Class="QuestNode_Greater">
|
||||
<value1>$points</value1>
|
||||
<value2>15999</value2>
|
||||
|
||||
<!-- Lodgers arrive by shuttle -->
|
||||
<node Class="QuestNode_Sequence">
|
||||
<nodes>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Bunker_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>4</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Fortress_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>1</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
<li Class="QuestNode_Less">
|
||||
<value1>$prefabSpawnSuccessCount</value1>
|
||||
<value2>$prefabSpawnRequestedCount</value2>
|
||||
|
||||
<node Class="QuestNode_Sequence">
|
||||
<nodes>
|
||||
<li Class="WulaFallenEmpire.QuestNode_SpawnPrefabSkyfallerCaller">
|
||||
<thingDef>WULA_Turret_Group_Drop_Zone_Beacon_Cleanzone</thingDef>
|
||||
<faction>Wula_PIA_Legion_Faction</faction>
|
||||
<spawnCount>3</spawnCount>
|
||||
<sendMessageOnSuccess>false</sendMessageOnSuccess>
|
||||
<sendMessageOnFailure>false</sendMessageOnFailure>
|
||||
</li>
|
||||
</nodes>
|
||||
</node>
|
||||
</li>
|
||||
</nodes>
|
||||
</node>
|
||||
</li>
|
||||
</nodes>
|
||||
</li>
|
||||
</nodes>
|
||||
</li>
|
||||
<li Class="QuestNode_End" />
|
||||
</nodes>
|
||||
</root>
|
||||
</QuestScriptDef>
|
||||
</Defs>
|
||||
@@ -1108,12 +1108,12 @@
|
||||
<texPath>Wula/Item/WULA_Safe_Box_For_Mission</texPath>
|
||||
<graphicClass>Graphic_Single</graphicClass>
|
||||
</graphicData>
|
||||
<stackLimit>30</stackLimit>
|
||||
<stackLimit>1</stackLimit>
|
||||
<statBases>
|
||||
<Flammability>0</Flammability>
|
||||
<Beauty>0</Beauty>
|
||||
<DeteriorationRate>0</DeteriorationRate>
|
||||
<MarketValue>24</MarketValue>
|
||||
<MarketValue>8650000</MarketValue>
|
||||
<Mass>0.3</Mass>
|
||||
<WorkToMake>450</WorkToMake>
|
||||
</statBases>
|
||||
@@ -1125,6 +1125,7 @@
|
||||
<alwaysHaulable>true</alwaysHaulable>
|
||||
<pathCost>14</pathCost>
|
||||
<allowedArchonexusCount>200</allowedArchonexusCount>
|
||||
<generateAllowChance>0</generateAllowChance>
|
||||
<tradeability>None</tradeability>
|
||||
<resourceReadoutPriority>Last</resourceReadoutPriority>
|
||||
<drawGUIOverlay>true</drawGUIOverlay>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Defs>
|
||||
<!-- 墙和门 -->
|
||||
<ThingDef ParentName="Wall">
|
||||
<ThingDef Name="WulaWall_Cleanzone" ParentName="Wall">
|
||||
<defName>WulaWall_Cleanzone</defName>
|
||||
<label>乌拉帝国堡垒墙</label>
|
||||
<description>清理出一块场地并准备好资源,使得乌拉帝国可以向此处投放建筑,建造好的信标可以收起或移至他处。\n\n乌拉帝国用于建造堡垒的外壁相当厚实,能够抵御大量伤害,并且拥有气密性,可以用在飞船外壳上。</description>
|
||||
@@ -72,7 +72,7 @@
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
<ThingDef ParentName="SkyfallerBase">
|
||||
<ThingDef Name="WulaWall_Incoming" ParentName="SkyfallerBase">
|
||||
<defName>WulaWall_Incoming</defName>
|
||||
<label>乌拉帝国堡垒墙(空投中)</label>
|
||||
<size>(1,1)</size>
|
||||
@@ -106,7 +106,7 @@
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
<ThingDef ParentName="Wall" Name="WulaWall">
|
||||
<ThingDef Name="WulaWall" ParentName="Wall">
|
||||
<defName>WulaWall</defName>
|
||||
<label>乌拉帝国堡垒墙</label>
|
||||
<description>乌拉帝国堡垒外壁,相当厚实,能够抵御大量伤害,并且拥有气密性,可以用在飞船外壳上。</description>
|
||||
@@ -177,7 +177,7 @@
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
<ThingDef ParentName="DoorBase">
|
||||
<ThingDef Name="WulaDoor_Cleanzone" ParentName="DoorBase">
|
||||
<defName>WulaDoor_Cleanzone</defName>
|
||||
<label>乌拉帝国大门</label>
|
||||
<description>清理出一块场地并准备好资源,使得乌拉帝国可以向此处投放建筑,建造好的信标可以收起或移至他处。\n\n乌拉帝国堡垒的大门不仅能够抵御大量爆炸和震荡伤害,还拥有无需通电即可运转的伺服系统来增加大门通过速度。</description>
|
||||
@@ -254,7 +254,7 @@
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
<ThingDef ParentName="SkyfallerBase">
|
||||
<ThingDef Name="WulaDoor_Incoming" ParentName="SkyfallerBase">
|
||||
<defName>WulaDoor_Incoming</defName>
|
||||
<label>乌拉帝国大门(空投中)</label>
|
||||
<size>(1,1)</size>
|
||||
@@ -288,7 +288,7 @@
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
<ThingDef ParentName="DoorBase">
|
||||
<ThingDef Name="WulaDoor" ParentName="DoorBase">
|
||||
<defName>WulaDoor</defName>
|
||||
<label>乌拉帝国大门</label>
|
||||
<description>乌拉帝国堡垒的大门,不仅能够抵御大量爆炸和震荡伤害,还拥有无需通电即可运转的伺服系统来增加大门通过速度。</description>
|
||||
@@ -970,7 +970,7 @@
|
||||
<ComponentIndustrial>1</ComponentIndustrial>
|
||||
</costList>
|
||||
<researchPrerequisites Inherit="False">
|
||||
<li>WULA_WeaponArmor_Productor_Technology</li>
|
||||
<li>WULA_Colony_License_LV1_Technology</li>
|
||||
</researchPrerequisites>
|
||||
<inspectorTabs>
|
||||
<li>ITab_ContentsTransporter</li>
|
||||
@@ -1860,6 +1860,7 @@
|
||||
<isAirtight>false</isAirtight>
|
||||
<isStuffableAirtight>false</isStuffableAirtight>
|
||||
<destroySound>BuildingDestroyed_Metal_Medium</destroySound>
|
||||
<claimable>false</claimable>
|
||||
</building>
|
||||
<costList>
|
||||
<WULA_Alloy>50</WULA_Alloy>
|
||||
@@ -2078,7 +2079,7 @@
|
||||
</li>
|
||||
<li Class="CompProperties_Power">
|
||||
<compClass>CompPowerPlant</compClass>
|
||||
<basePowerConsumption>-1500</basePowerConsumption>
|
||||
<basePowerConsumption>-2000</basePowerConsumption>
|
||||
<transmitsPower>true</transmitsPower>
|
||||
<soundAmbientProducingPower>ChemfuelFiredGenerator_Ambience</soundAmbientProducingPower>
|
||||
</li>
|
||||
|
||||
@@ -669,7 +669,6 @@
|
||||
<defName>WULA_Sky_Lock</defName>
|
||||
<label>天锁</label>
|
||||
<description>天锁</description>
|
||||
<thingClass>Building</thingClass>
|
||||
<thingClass>WulaFallenEmpire.Building_ExtraGraphics</thingClass>
|
||||
<preventDroppingThingsOn>true</preventDroppingThingsOn>
|
||||
<altitudeLayer>MetaOverlays</altitudeLayer>
|
||||
|
||||
@@ -105,4 +105,432 @@
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
|
||||
<ThingDef ParentName="BuildingBase">
|
||||
<defName>WULA_Huge_Fortress_Drop_Zone_Beacon_Cleanzone</defName>
|
||||
<label>乌拉预制件空投信标-大型要塞</label>
|
||||
<description>一个用于呼叫建筑的信标,用于快速建造一个大型要塞。</description>
|
||||
<uiIconPath>Wula/Building/Linked/WULA_Fortress_Wall_MenuIcon</uiIconPath>
|
||||
<tickerType>Normal</tickerType>
|
||||
<minifiedDef>MinifiedThing</minifiedDef>
|
||||
<graphicData>
|
||||
<texPath>Wula/Building/WULA_Dropping_Building_Cleanzone_Plus</texPath>
|
||||
<graphicClass>Graphic_Multi</graphicClass>
|
||||
<drawSize>(44,44)</drawSize>
|
||||
<damageData>
|
||||
<enabled>false</enabled>
|
||||
</damageData>
|
||||
</graphicData>
|
||||
<thingCategories Inherit="False">
|
||||
<li>BuildingsMisc</li>
|
||||
</thingCategories>
|
||||
<rotatable>false</rotatable>
|
||||
<neverMultiSelect>false</neverMultiSelect>
|
||||
<blockLight>false</blockLight>
|
||||
<holdsRoof>false</holdsRoof>
|
||||
<coversFloor>false</coversFloor>
|
||||
<blockWind>false</blockWind>
|
||||
<altitudeLayer>BuildingOnTop</altitudeLayer>
|
||||
<passability>PassThroughOnly</passability>
|
||||
<pathCost>0</pathCost>
|
||||
<castEdgeShadows>false</castEdgeShadows>
|
||||
<useStuffTerrainAffordance>false</useStuffTerrainAffordance>
|
||||
<staticSunShadowHeight Inherit="False" IsNull="True" />
|
||||
<fillPercent>0</fillPercent>
|
||||
<canOverlapZones>false</canOverlapZones>
|
||||
<terrainAffordanceNeeded>Light</terrainAffordanceNeeded>
|
||||
<statBases>
|
||||
<MaxHitPoints>1</MaxHitPoints>
|
||||
<WorkToBuild>0</WorkToBuild>
|
||||
<Mass>1</Mass>
|
||||
<Flammability>0</Flammability>
|
||||
</statBases>
|
||||
<size>(44,44)</size>
|
||||
<constructionSkillPrerequisite>0</constructionSkillPrerequisite>
|
||||
<resourcesFractionWhenDeconstructed>1</resourcesFractionWhenDeconstructed>
|
||||
<stuffCategories Inherit="False" />
|
||||
<!-- <researchPrerequisites Inherit="False">
|
||||
<li>WULA_Structure_Technology</li>
|
||||
</researchPrerequisites> -->
|
||||
<costStuffCount>0</costStuffCount>
|
||||
<costList>
|
||||
<WULA_Alloy>4</WULA_Alloy>
|
||||
</costList>
|
||||
<building>
|
||||
<destroySound>BuildingDestroyed_Metal_Small</destroySound>
|
||||
<isAirtight>false</isAirtight>
|
||||
<isStuffableAirtight>false</isStuffableAirtight>
|
||||
</building>
|
||||
<comps>
|
||||
<li Class="WulaFallenEmpire.CompProperties_PrefabSkyfallerCaller">
|
||||
<prefabDefName>WULA_Huge_Fortress_Drop_Zone_Prefeb</prefabDefName>
|
||||
<freePrefab>true</freePrefab>
|
||||
<skyfallerDef>WULA_Huge_Fortress_Drop_Zone_Prefeb_Incoming</skyfallerDef>
|
||||
<destroyBuilding>true</destroyBuilding>
|
||||
<delayTicks>1</delayTicks>
|
||||
<allowThinRoof>true</allowThinRoof>
|
||||
<allowThickRoof>false</allowThickRoof>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
<!-- Prefab Spawner Skyfaller -->
|
||||
<ThingDef ParentName="SkyfallerBase">
|
||||
<defName>WULA_Huge_Fortress_Drop_Zone_Prefeb_Incoming</defName>
|
||||
<label>乌拉帝国建筑(空投中)</label>
|
||||
<thingClass>WulaFallenEmpire.Skyfaller_PrefabSpawner</thingClass>
|
||||
<size>(44,44)</size>
|
||||
<graphicData>
|
||||
<texPath>Wula/Building/WULA_Huge_Fortress_Drop_Zone_Prefeb_Incoming</texPath>
|
||||
<graphicClass>Graphic_Single</graphicClass>
|
||||
<shaderType>CutoutFlying</shaderType>
|
||||
<drawSize>(44,44)</drawSize>
|
||||
</graphicData>
|
||||
<skyfaller>
|
||||
<movementType>Accelerate</movementType>
|
||||
<shadow>Things/Skyfaller/SkyfallerShadowDropPod</shadow>
|
||||
<shadowSize>(44, 44)</shadowSize>
|
||||
<anticipationSound>DropPod_Fall</anticipationSound>
|
||||
<anticipationSoundTicks>100</anticipationSoundTicks>
|
||||
<impactSound>Explosion_Vaporize</impactSound>
|
||||
<moteSpawnTime>0.05</moteSpawnTime>
|
||||
<motesPerCell>1</motesPerCell>
|
||||
<cameraShake>1</cameraShake>
|
||||
<speed>2.5</speed>
|
||||
<angleCurve>
|
||||
<points>
|
||||
<li>(0,0)</li>
|
||||
<li>(1, 1)</li>
|
||||
</points>
|
||||
</angleCurve>
|
||||
</skyfaller>
|
||||
<comps>
|
||||
<li Class="CompProperties_Effecter">
|
||||
<effecterDef>Smoke_Joint</effecterDef>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.CompProperties_SkyfallerFaction">
|
||||
<factionDef>AncientsHostile</factionDef>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
|
||||
<ThingDef ParentName="BuildingBase">
|
||||
<defName>WULA_Bunker_Drop_Zone_Beacon_Cleanzone</defName>
|
||||
<label>乌拉预制件空投信标-碉堡</label>
|
||||
<description>一个用于呼叫建筑的信标,用于快速建造一个碉堡防御设施。</description>
|
||||
<uiIconPath>Wula/Building/Linked/WULA_Fortress_Wall_MenuIcon</uiIconPath>
|
||||
<tickerType>Normal</tickerType>
|
||||
<minifiedDef>MinifiedThing</minifiedDef>
|
||||
<graphicData>
|
||||
<texPath>Wula/Building/WULA_Dropping_Building_Cleanzone</texPath>
|
||||
<graphicClass>Graphic_Multi</graphicClass>
|
||||
<drawSize>(5,5)</drawSize>
|
||||
<damageData>
|
||||
<enabled>false</enabled>
|
||||
</damageData>
|
||||
</graphicData>
|
||||
<thingCategories Inherit="False">
|
||||
<li>BuildingsMisc</li>
|
||||
</thingCategories>
|
||||
<rotatable>false</rotatable>
|
||||
<neverMultiSelect>false</neverMultiSelect>
|
||||
<blockLight>false</blockLight>
|
||||
<holdsRoof>false</holdsRoof>
|
||||
<coversFloor>false</coversFloor>
|
||||
<blockWind>false</blockWind>
|
||||
<altitudeLayer>BuildingOnTop</altitudeLayer>
|
||||
<passability>PassThroughOnly</passability>
|
||||
<pathCost>0</pathCost>
|
||||
<castEdgeShadows>false</castEdgeShadows>
|
||||
<useStuffTerrainAffordance>false</useStuffTerrainAffordance>
|
||||
<staticSunShadowHeight Inherit="False" IsNull="True" />
|
||||
<fillPercent>0</fillPercent>
|
||||
<canOverlapZones>false</canOverlapZones>
|
||||
<terrainAffordanceNeeded>Light</terrainAffordanceNeeded>
|
||||
<statBases>
|
||||
<MaxHitPoints>1</MaxHitPoints>
|
||||
<WorkToBuild>0</WorkToBuild>
|
||||
<Mass>1</Mass>
|
||||
<Flammability>0</Flammability>
|
||||
</statBases>
|
||||
<size>(5,5)</size>
|
||||
<constructionSkillPrerequisite>0</constructionSkillPrerequisite>
|
||||
<resourcesFractionWhenDeconstructed>1</resourcesFractionWhenDeconstructed>
|
||||
<stuffCategories Inherit="False" />
|
||||
<!-- <researchPrerequisites Inherit="False">
|
||||
<li>WULA_Structure_Technology</li>
|
||||
</researchPrerequisites> -->
|
||||
<costStuffCount>0</costStuffCount>
|
||||
<costList>
|
||||
<WULA_Alloy>4</WULA_Alloy>
|
||||
</costList>
|
||||
<building>
|
||||
<destroySound>BuildingDestroyed_Metal_Small</destroySound>
|
||||
<isAirtight>false</isAirtight>
|
||||
<isStuffableAirtight>false</isStuffableAirtight>
|
||||
</building>
|
||||
<comps>
|
||||
<li Class="WulaFallenEmpire.CompProperties_PrefabSkyfallerCaller">
|
||||
<prefabDefName>WULA_Bunker_Drop_Zone_Prefeb</prefabDefName>
|
||||
<freePrefab>true</freePrefab>
|
||||
<skyfallerDef>WULA_Bunker_Drop_Zone_Prefeb_Incoming</skyfallerDef>
|
||||
<destroyBuilding>true</destroyBuilding>
|
||||
<delayTicks>1</delayTicks>
|
||||
<allowThinRoof>true</allowThinRoof>
|
||||
<allowThickRoof>false</allowThickRoof>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
<!-- Prefab Spawner Skyfaller -->
|
||||
<ThingDef ParentName="SkyfallerBase">
|
||||
<defName>WULA_Bunker_Drop_Zone_Prefeb_Incoming</defName>
|
||||
<label>乌拉帝国建筑(空投中)</label>
|
||||
<thingClass>WulaFallenEmpire.Skyfaller_PrefabSpawner</thingClass>
|
||||
<size>(5,5)</size>
|
||||
<graphicData>
|
||||
<texPath>Wula/Building/WULA_Bunker_Drop_Zone_Prefeb_Incoming</texPath>
|
||||
<graphicClass>Graphic_Single</graphicClass>
|
||||
<shaderType>CutoutFlying</shaderType>
|
||||
<drawSize>(5,5)</drawSize>
|
||||
</graphicData>
|
||||
<skyfaller>
|
||||
<movementType>Accelerate</movementType>
|
||||
<shadow>Things/Skyfaller/SkyfallerShadowDropPod</shadow>
|
||||
<shadowSize>(5, 5)</shadowSize>
|
||||
<anticipationSound>DropPod_Fall</anticipationSound>
|
||||
<anticipationSoundTicks>100</anticipationSoundTicks>
|
||||
<impactSound>Explosion_Vaporize</impactSound>
|
||||
<moteSpawnTime>0.05</moteSpawnTime>
|
||||
<motesPerCell>1</motesPerCell>
|
||||
<cameraShake>1</cameraShake>
|
||||
<speed>2.5</speed>
|
||||
<angleCurve>
|
||||
<points>
|
||||
<li>(0,0)</li>
|
||||
<li>(1, 1)</li>
|
||||
</points>
|
||||
</angleCurve>
|
||||
</skyfaller>
|
||||
<comps>
|
||||
<li Class="CompProperties_Effecter">
|
||||
<effecterDef>Smoke_Joint</effecterDef>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.CompProperties_SkyfallerFaction">
|
||||
<factionDef>AncientsHostile</factionDef>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
|
||||
<ThingDef ParentName="BuildingBase">
|
||||
<defName>WULA_Turret_Group_Drop_Zone_Beacon_Cleanzone</defName>
|
||||
<label>乌拉预制件空投信标-炮塔群</label>
|
||||
<description>一个用于呼叫建筑的信标,用于快速建造一个炮塔群。</description>
|
||||
<uiIconPath>Wula/Building/Linked/WULA_Fortress_Wall_MenuIcon</uiIconPath>
|
||||
<tickerType>Normal</tickerType>
|
||||
<minifiedDef>MinifiedThing</minifiedDef>
|
||||
<graphicData>
|
||||
<texPath>Wula/Building/WULA_Dropping_Building_Cleanzone_Plus</texPath>
|
||||
<graphicClass>Graphic_Multi</graphicClass>
|
||||
<drawSize>(15,15)</drawSize>
|
||||
<damageData>
|
||||
<enabled>false</enabled>
|
||||
</damageData>
|
||||
</graphicData>
|
||||
<thingCategories Inherit="False">
|
||||
<li>BuildingsMisc</li>
|
||||
</thingCategories>
|
||||
<rotatable>false</rotatable>
|
||||
<neverMultiSelect>false</neverMultiSelect>
|
||||
<blockLight>false</blockLight>
|
||||
<holdsRoof>false</holdsRoof>
|
||||
<coversFloor>false</coversFloor>
|
||||
<blockWind>false</blockWind>
|
||||
<altitudeLayer>BuildingOnTop</altitudeLayer>
|
||||
<passability>PassThroughOnly</passability>
|
||||
<pathCost>0</pathCost>
|
||||
<castEdgeShadows>false</castEdgeShadows>
|
||||
<useStuffTerrainAffordance>false</useStuffTerrainAffordance>
|
||||
<staticSunShadowHeight Inherit="False" IsNull="True" />
|
||||
<fillPercent>0</fillPercent>
|
||||
<canOverlapZones>false</canOverlapZones>
|
||||
<terrainAffordanceNeeded>Light</terrainAffordanceNeeded>
|
||||
<statBases>
|
||||
<MaxHitPoints>1</MaxHitPoints>
|
||||
<WorkToBuild>0</WorkToBuild>
|
||||
<Mass>1</Mass>
|
||||
<Flammability>0</Flammability>
|
||||
</statBases>
|
||||
<size>(15,15)</size>
|
||||
<constructionSkillPrerequisite>0</constructionSkillPrerequisite>
|
||||
<resourcesFractionWhenDeconstructed>1</resourcesFractionWhenDeconstructed>
|
||||
<stuffCategories Inherit="False" />
|
||||
<!-- <researchPrerequisites Inherit="False">
|
||||
<li>WULA_Structure_Technology</li>
|
||||
</researchPrerequisites> -->
|
||||
<costStuffCount>0</costStuffCount>
|
||||
<costList>
|
||||
<WULA_Alloy>4</WULA_Alloy>
|
||||
</costList>
|
||||
<building>
|
||||
<destroySound>BuildingDestroyed_Metal_Small</destroySound>
|
||||
<isAirtight>false</isAirtight>
|
||||
<isStuffableAirtight>false</isStuffableAirtight>
|
||||
</building>
|
||||
<comps>
|
||||
<li Class="WulaFallenEmpire.CompProperties_PrefabSkyfallerCaller">
|
||||
<prefabDefName>WULA_Turret_Group_Drop_Zone_Prefeb</prefabDefName>
|
||||
<freePrefab>true</freePrefab>
|
||||
<skyfallerDef>WULA_Turret_Group_Drop_Zone_Prefeb_Incoming</skyfallerDef>
|
||||
<destroyBuilding>true</destroyBuilding>
|
||||
<delayTicks>1</delayTicks>
|
||||
<allowThinRoof>true</allowThinRoof>
|
||||
<allowThickRoof>false</allowThickRoof>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
<!-- Prefab Spawner Skyfaller -->
|
||||
<ThingDef ParentName="SkyfallerBase">
|
||||
<defName>WULA_Turret_Group_Drop_Zone_Prefeb_Incoming</defName>
|
||||
<label>乌拉帝国建筑(空投中)</label>
|
||||
<thingClass>WulaFallenEmpire.Skyfaller_PrefabSpawner</thingClass>
|
||||
<size>(15,15)</size>
|
||||
<graphicData>
|
||||
<texPath>Wula/Building/WULA_Turret_Group_Drop_Zone_Prefeb_Incoming</texPath>
|
||||
<graphicClass>Graphic_Single</graphicClass>
|
||||
<shaderType>CutoutFlying</shaderType>
|
||||
<drawSize>(15,15)</drawSize>
|
||||
</graphicData>
|
||||
<skyfaller>
|
||||
<movementType>Accelerate</movementType>
|
||||
<shadow>Things/Skyfaller/SkyfallerShadowDropPod</shadow>
|
||||
<shadowSize>(15, 15)</shadowSize>
|
||||
<anticipationSound>DropPod_Fall</anticipationSound>
|
||||
<anticipationSoundTicks>100</anticipationSoundTicks>
|
||||
<impactSound>Explosion_Vaporize</impactSound>
|
||||
<moteSpawnTime>0.05</moteSpawnTime>
|
||||
<motesPerCell>1</motesPerCell>
|
||||
<cameraShake>1</cameraShake>
|
||||
<speed>2.5</speed>
|
||||
<angleCurve>
|
||||
<points>
|
||||
<li>(0,0)</li>
|
||||
<li>(1, 1)</li>
|
||||
</points>
|
||||
</angleCurve>
|
||||
</skyfaller>
|
||||
<comps>
|
||||
<li Class="CompProperties_Effecter">
|
||||
<effecterDef>Smoke_Joint</effecterDef>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.CompProperties_SkyfallerFaction">
|
||||
<factionDef>AncientsHostile</factionDef>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
|
||||
<ThingDef ParentName="BuildingBase">
|
||||
<defName>WULA_Fortress_Drop_Zone_Beacon_Cleanzone</defName>
|
||||
<label>乌拉预制件空投信标-要塞</label>
|
||||
<description>一个用于呼叫建筑的信标,用于快速建造一个要塞。</description>
|
||||
<uiIconPath>Wula/Building/Linked/WULA_Fortress_Wall_MenuIcon</uiIconPath>
|
||||
<tickerType>Normal</tickerType>
|
||||
<minifiedDef>MinifiedThing</minifiedDef>
|
||||
<graphicData>
|
||||
<texPath>Wula/Building/WULA_Dropping_Building_Cleanzone_Plus</texPath>
|
||||
<graphicClass>Graphic_Multi</graphicClass>
|
||||
<drawSize>(25,25)</drawSize>
|
||||
<damageData>
|
||||
<enabled>false</enabled>
|
||||
</damageData>
|
||||
</graphicData>
|
||||
<thingCategories Inherit="False">
|
||||
<li>BuildingsMisc</li>
|
||||
</thingCategories>
|
||||
<rotatable>false</rotatable>
|
||||
<neverMultiSelect>false</neverMultiSelect>
|
||||
<blockLight>false</blockLight>
|
||||
<holdsRoof>false</holdsRoof>
|
||||
<coversFloor>false</coversFloor>
|
||||
<blockWind>false</blockWind>
|
||||
<altitudeLayer>BuildingOnTop</altitudeLayer>
|
||||
<passability>PassThroughOnly</passability>
|
||||
<pathCost>0</pathCost>
|
||||
<castEdgeShadows>false</castEdgeShadows>
|
||||
<useStuffTerrainAffordance>false</useStuffTerrainAffordance>
|
||||
<staticSunShadowHeight Inherit="False" IsNull="True" />
|
||||
<fillPercent>0</fillPercent>
|
||||
<canOverlapZones>false</canOverlapZones>
|
||||
<terrainAffordanceNeeded>Light</terrainAffordanceNeeded>
|
||||
<statBases>
|
||||
<MaxHitPoints>1</MaxHitPoints>
|
||||
<WorkToBuild>0</WorkToBuild>
|
||||
<Mass>1</Mass>
|
||||
<Flammability>0</Flammability>
|
||||
</statBases>
|
||||
<size>(25,25)</size>
|
||||
<constructionSkillPrerequisite>0</constructionSkillPrerequisite>
|
||||
<resourcesFractionWhenDeconstructed>1</resourcesFractionWhenDeconstructed>
|
||||
<stuffCategories Inherit="False" />
|
||||
<!-- <researchPrerequisites Inherit="False">
|
||||
<li>WULA_Structure_Technology</li>
|
||||
</researchPrerequisites> -->
|
||||
<costStuffCount>0</costStuffCount>
|
||||
<costList>
|
||||
<WULA_Alloy>4</WULA_Alloy>
|
||||
</costList>
|
||||
<building>
|
||||
<destroySound>BuildingDestroyed_Metal_Small</destroySound>
|
||||
<isAirtight>false</isAirtight>
|
||||
<isStuffableAirtight>false</isStuffableAirtight>
|
||||
</building>
|
||||
<comps>
|
||||
<li Class="WulaFallenEmpire.CompProperties_PrefabSkyfallerCaller">
|
||||
<prefabDefName>WULA_Fortress_Drop_Zone_Prefeb</prefabDefName>
|
||||
<freePrefab>true</freePrefab>
|
||||
<skyfallerDef>WULA_Fortress_Drop_Zone_Prefeb_Incoming</skyfallerDef>
|
||||
<destroyBuilding>true</destroyBuilding>
|
||||
<delayTicks>1</delayTicks>
|
||||
<allowThinRoof>true</allowThinRoof>
|
||||
<allowThickRoof>false</allowThickRoof>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
<!-- Prefab Spawner Skyfaller -->
|
||||
<ThingDef ParentName="SkyfallerBase">
|
||||
<defName>WULA_Fortress_Drop_Zone_Prefeb_Incoming</defName>
|
||||
<label>乌拉帝国建筑(空投中)</label>
|
||||
<thingClass>WulaFallenEmpire.Skyfaller_PrefabSpawner</thingClass>
|
||||
<size>(25,25)</size>
|
||||
<graphicData>
|
||||
<texPath>Wula/Building/WULA_Fortress_Drop_Zone_Prefeb_Incoming</texPath>
|
||||
<graphicClass>Graphic_Single</graphicClass>
|
||||
<shaderType>CutoutFlying</shaderType>
|
||||
<drawSize>(25,25)</drawSize>
|
||||
</graphicData>
|
||||
<skyfaller>
|
||||
<movementType>Accelerate</movementType>
|
||||
<shadow>Things/Skyfaller/SkyfallerShadowDropPod</shadow>
|
||||
<shadowSize>(25, 25)</shadowSize>
|
||||
<anticipationSound>DropPod_Fall</anticipationSound>
|
||||
<anticipationSoundTicks>100</anticipationSoundTicks>
|
||||
<impactSound>Explosion_Vaporize</impactSound>
|
||||
<moteSpawnTime>0.05</moteSpawnTime>
|
||||
<motesPerCell>1</motesPerCell>
|
||||
<cameraShake>1</cameraShake>
|
||||
<speed>2.5</speed>
|
||||
<angleCurve>
|
||||
<points>
|
||||
<li>(0,0)</li>
|
||||
<li>(1, 1)</li>
|
||||
</points>
|
||||
</angleCurve>
|
||||
</skyfaller>
|
||||
<comps>
|
||||
<li Class="CompProperties_Effecter">
|
||||
<effecterDef>Smoke_Joint</effecterDef>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.CompProperties_SkyfallerFaction">
|
||||
<factionDef>AncientsHostile</factionDef>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
</Defs>
|
||||
@@ -47,7 +47,7 @@
|
||||
</statBases>
|
||||
<size>(3,3)</size>
|
||||
<constructionSkillPrerequisite>0</constructionSkillPrerequisite>
|
||||
<resourcesFractionWhenDeconstructed>1</resourcesFractionWhenDeconstructed>
|
||||
<resourcesFractionWhenDeconstructed>0</resourcesFractionWhenDeconstructed>
|
||||
<costList>
|
||||
<Steel>300</Steel>
|
||||
<ComponentIndustrial>3</ComponentIndustrial>
|
||||
@@ -145,7 +145,6 @@
|
||||
<canOverlapZones>false</canOverlapZones>
|
||||
<hasInteractionCell>false</hasInteractionCell>
|
||||
<!-- <interactionCellOffset>(0,0,-2)</interactionCellOffset> -->
|
||||
<resourcesFractionWhenDeconstructed>0</resourcesFractionWhenDeconstructed>
|
||||
<terrainAffordanceNeeded>Light</terrainAffordanceNeeded>
|
||||
<statBases>
|
||||
<MaxHitPoints>500</MaxHitPoints>
|
||||
@@ -155,11 +154,15 @@
|
||||
</statBases>
|
||||
<size>(3,3)</size>
|
||||
<costList>
|
||||
<Steel>200</Steel>
|
||||
<Steel>60</Steel>
|
||||
</costList>
|
||||
<building>
|
||||
<destroySound>BuildingDestroyed_Metal_Small</destroySound>
|
||||
<turretBurstCooldownTime>3.5</turretBurstCooldownTime>
|
||||
<claimable>false</claimable>
|
||||
<ai_combatDangerous>true</ai_combatDangerous>
|
||||
<turretGunDef>WULA_Cat_Bunker_TurretGun</turretGunDef>
|
||||
<claimable>false</claimable>
|
||||
</building>
|
||||
<comps>
|
||||
<li Class="CompProperties_Glower">
|
||||
@@ -301,7 +304,7 @@
|
||||
</statBases>
|
||||
<size>(3,3)</size>
|
||||
<constructionSkillPrerequisite>0</constructionSkillPrerequisite>
|
||||
<resourcesFractionWhenDeconstructed>1</resourcesFractionWhenDeconstructed>
|
||||
<resourcesFractionWhenDeconstructed>0</resourcesFractionWhenDeconstructed>
|
||||
<costList Inherit="False">
|
||||
<WULA_Alloy>100</WULA_Alloy>
|
||||
<WULA_Charge_Cube>6</WULA_Charge_Cube>
|
||||
@@ -409,7 +412,6 @@
|
||||
<WULA_Alloy>100</WULA_Alloy>
|
||||
<WULA_Charge_Cube>6</WULA_Charge_Cube>
|
||||
</costList>
|
||||
<leaveResourcesWhenKilled>false</leaveResourcesWhenKilled>
|
||||
<tickerType>Normal</tickerType>
|
||||
<passability>PassThroughOnly</passability>
|
||||
<pathCost>40</pathCost>
|
||||
@@ -429,22 +431,34 @@
|
||||
<turretBurstCooldownTime>3</turretBurstCooldownTime>
|
||||
<turretTopOffset>(-0.04, 0)</turretTopOffset>
|
||||
<turretTopDrawSize>5.0</turretTopDrawSize>
|
||||
<claimable>false</claimable>
|
||||
</building>
|
||||
<placeWorkers>
|
||||
<li>PlaceWorker_TurretTop</li>
|
||||
<li>PlaceWorker_ShowTurretRadius</li>
|
||||
</placeWorkers>
|
||||
<comps>
|
||||
<!-- 特殊组件,会在非玩家派系的时候眩晕该炮塔 -->
|
||||
<li Class="WulaFallenEmpire.CompProperties_DelayedDamageIfNotPlayer">
|
||||
<damageDef>EMP</damageDef>
|
||||
<damageAmount>50</damageAmount>
|
||||
<armorPenetration>2</armorPenetration>
|
||||
<destroyIfKilled>true</destroyIfKilled>
|
||||
</li>
|
||||
<li Class="CompProperties_Stunnable">
|
||||
<affectedDamageDefs>
|
||||
<li>Stun</li>
|
||||
<li>EMP</li>
|
||||
</affectedDamageDefs>
|
||||
<adaptableDamageDefs>
|
||||
<li>EMP</li>
|
||||
</adaptableDamageDefs>
|
||||
</li>
|
||||
<li Class="CompProperties_CanBeDormant" />
|
||||
<li Class="CompProperties_Initiatable" />
|
||||
<li Class="CompProperties_WakeUpDormant">
|
||||
<wakeUpSound>MechanoidsWakeUp</wakeUpSound>
|
||||
</li>
|
||||
<li Class="CompProperties_Stunnable">
|
||||
<affectedDamageDefs>
|
||||
<li>EMP</li>
|
||||
</affectedDamageDefs>
|
||||
</li>
|
||||
<li Class="CompProperties_AmbientSound">
|
||||
<sound>MechTurretBig_Call</sound>
|
||||
</li>
|
||||
@@ -455,7 +469,7 @@
|
||||
</li>
|
||||
<li Class="CompProperties_Power">
|
||||
<compClass>CompPowerTrader</compClass>
|
||||
<basePowerConsumption>300</basePowerConsumption> <!-- This is now idle power -->
|
||||
<basePowerConsumption>300</basePowerConsumption> <!-- 电力消耗较低 -->
|
||||
</li>
|
||||
<li Class="CompProperties_Glower">
|
||||
<glowRadius>6</glowRadius>
|
||||
@@ -579,7 +593,7 @@
|
||||
</statBases>
|
||||
<size>(3,3)</size>
|
||||
<constructionSkillPrerequisite>0</constructionSkillPrerequisite>
|
||||
<resourcesFractionWhenDeconstructed>1</resourcesFractionWhenDeconstructed>
|
||||
<resourcesFractionWhenDeconstructed>0</resourcesFractionWhenDeconstructed>
|
||||
<terrainAffordanceNeeded>Light</terrainAffordanceNeeded>
|
||||
<costList Inherit="False">
|
||||
<WULA_Alloy>100</WULA_Alloy>
|
||||
@@ -689,7 +703,6 @@
|
||||
<WULA_Alloy>100</WULA_Alloy>
|
||||
<WULA_Charge_Cube>6</WULA_Charge_Cube>
|
||||
</costList>
|
||||
<leaveResourcesWhenKilled>false</leaveResourcesWhenKilled>
|
||||
<tickerType>Normal</tickerType>
|
||||
<passability>PassThroughOnly</passability>
|
||||
<pathCost>40</pathCost>
|
||||
@@ -708,22 +721,34 @@
|
||||
<turretBurstCooldownTime>0.01</turretBurstCooldownTime>
|
||||
<turretTopOffset>(-0.04, 0)</turretTopOffset>
|
||||
<turretTopDrawSize>5.0</turretTopDrawSize>
|
||||
<claimable>false</claimable>
|
||||
</building>
|
||||
<placeWorkers>
|
||||
<li>PlaceWorker_TurretTop</li>
|
||||
<li>PlaceWorker_ShowTurretRadius</li>
|
||||
</placeWorkers>
|
||||
<comps>
|
||||
<!-- 特殊组件,会在非玩家派系的时候眩晕该炮塔 -->
|
||||
<li Class="WulaFallenEmpire.CompProperties_DelayedDamageIfNotPlayer">
|
||||
<damageDef>EMP</damageDef>
|
||||
<damageAmount>50</damageAmount>
|
||||
<armorPenetration>2</armorPenetration>
|
||||
<destroyIfKilled>true</destroyIfKilled>
|
||||
</li>
|
||||
<li Class="CompProperties_Stunnable">
|
||||
<affectedDamageDefs>
|
||||
<li>Stun</li>
|
||||
<li>EMP</li>
|
||||
</affectedDamageDefs>
|
||||
<adaptableDamageDefs>
|
||||
<li>EMP</li>
|
||||
</adaptableDamageDefs>
|
||||
</li>
|
||||
<li Class="CompProperties_CanBeDormant" />
|
||||
<li Class="CompProperties_Initiatable" />
|
||||
<li Class="CompProperties_WakeUpDormant">
|
||||
<wakeUpSound>MechanoidsWakeUp</wakeUpSound>
|
||||
</li>
|
||||
<li Class="CompProperties_Stunnable">
|
||||
<affectedDamageDefs>
|
||||
<li>EMP</li>
|
||||
</affectedDamageDefs>
|
||||
</li>
|
||||
<li Class="CompProperties_AmbientSound">
|
||||
<sound>MechTurretBig_Call</sound>
|
||||
</li>
|
||||
@@ -734,7 +759,7 @@
|
||||
</li>
|
||||
<li Class="CompProperties_Power">
|
||||
<compClass>CompPowerTrader</compClass>
|
||||
<basePowerConsumption>500</basePowerConsumption> <!-- This is now idle power -->
|
||||
<basePowerConsumption>300</basePowerConsumption> <!-- 电力消耗较低 -->
|
||||
</li>
|
||||
<li Class="CompProperties_Glower">
|
||||
<glowRadius>6</glowRadius>
|
||||
@@ -870,7 +895,7 @@
|
||||
</statBases>
|
||||
<size>(3,3)</size>
|
||||
<constructionSkillPrerequisite>0</constructionSkillPrerequisite>
|
||||
<resourcesFractionWhenDeconstructed>1</resourcesFractionWhenDeconstructed>
|
||||
<resourcesFractionWhenDeconstructed>0</resourcesFractionWhenDeconstructed>
|
||||
<costList Inherit="False">
|
||||
<WULA_Alloy>100</WULA_Alloy>
|
||||
<WULA_Charge_Cube>6</WULA_Charge_Cube>
|
||||
@@ -969,7 +994,6 @@
|
||||
<WULA_Alloy>150</WULA_Alloy>
|
||||
<WULA_Charge_Cube>12</WULA_Charge_Cube>
|
||||
</costList>
|
||||
<leaveResourcesWhenKilled>false</leaveResourcesWhenKilled>
|
||||
<tickerType>Normal</tickerType>
|
||||
<passability>Impassable</passability>
|
||||
<blockWind>true</blockWind>
|
||||
@@ -982,12 +1006,20 @@
|
||||
<turretBurstCooldownTime>4</turretBurstCooldownTime>
|
||||
<turretTopOffset>(-0.04, 0)</turretTopOffset>
|
||||
<turretTopDrawSize>5.0</turretTopDrawSize>
|
||||
<claimable>false</claimable>
|
||||
</building>
|
||||
<placeWorkers>
|
||||
<li>PlaceWorker_TurretTop</li>
|
||||
<li>PlaceWorker_ShowTurretRadius</li>
|
||||
</placeWorkers>
|
||||
<comps>
|
||||
<!-- 特殊组件,会在非玩家派系的时候眩晕该炮塔 -->
|
||||
<li Class="WulaFallenEmpire.CompProperties_DelayedDamageIfNotPlayer">
|
||||
<damageDef>EMP</damageDef>
|
||||
<damageAmount>500</damageAmount>
|
||||
<armorPenetration>2</armorPenetration>
|
||||
<destroyIfKilled>true</destroyIfKilled>
|
||||
</li>
|
||||
<li Class="CompProperties_CanBeDormant" />
|
||||
<li Class="CompProperties_Initiatable" />
|
||||
<li Class="CompProperties_WakeUpDormant">
|
||||
@@ -995,8 +1027,12 @@
|
||||
</li>
|
||||
<li Class="CompProperties_Stunnable">
|
||||
<affectedDamageDefs>
|
||||
<li>Stun</li>
|
||||
<li>EMP</li>
|
||||
</affectedDamageDefs>
|
||||
<adaptableDamageDefs>
|
||||
<li>EMP</li>
|
||||
</adaptableDamageDefs>
|
||||
</li>
|
||||
<li Class="CompProperties_AmbientSound">
|
||||
<sound>MechTurretBig_Call</sound>
|
||||
@@ -1008,7 +1044,7 @@
|
||||
</li>
|
||||
<li Class="CompProperties_Power">
|
||||
<compClass>CompPowerTrader</compClass>
|
||||
<basePowerConsumption>200</basePowerConsumption> <!-- 电力消耗较低 -->
|
||||
<basePowerConsumption>300</basePowerConsumption> <!-- 电力消耗较低 -->
|
||||
</li>
|
||||
<li Class="CompProperties_Glower">
|
||||
<glowRadius>6</glowRadius>
|
||||
@@ -1115,7 +1151,6 @@
|
||||
<selectable>true</selectable>
|
||||
<fillPercent>0.20</fillPercent>
|
||||
<pathCost>14</pathCost>
|
||||
<leaveResourcesWhenKilled>false</leaveResourcesWhenKilled>
|
||||
<soundImpactDefault>BulletImpact_Metal</soundImpactDefault>
|
||||
<uiIconPath>Wula/Building/Flag/WULA_Flag_Building_B_north</uiIconPath>
|
||||
<noRightClickDraftAttack>true</noRightClickDraftAttack>
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
</graphicData>
|
||||
<selectable>true</selectable>
|
||||
<pathCost>10</pathCost>
|
||||
<ingestible>
|
||||
<preferability>NeverForNutrition</preferability>
|
||||
</ingestible>
|
||||
<plant>
|
||||
<immatureGraphicPath>Wula/Plant/WULA_Plant_Eggplant_Immature</immatureGraphicPath>
|
||||
<fertilityMin>0.5</fertilityMin>
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
<value>
|
||||
<li Class="WulaFallenEmpire.StorytellerCompProperties_SimpleTechnologyTrigger">
|
||||
<technology>WULA_Colony_License_LV1_Technology</technology>
|
||||
<incident>WULA_GiveQuest_Base_Tex</incident>
|
||||
<questDef>WULA_Base_Tex_Quest</questDef>
|
||||
|
||||
<!-- 时间配置 -->
|
||||
<fireAfterDaysPassed>0</fireAfterDaysPassed>
|
||||
@@ -37,7 +35,11 @@
|
||||
<preventDuplicateQuests>false</preventDuplicateQuests>
|
||||
<debugLogging>false</debugLogging>
|
||||
|
||||
<requireNonHostileRelation>false</requireNonHostileRelation>
|
||||
<requiredFaction>Wula_PIA_Legion_Faction</requiredFaction>
|
||||
|
||||
<incident>WULA_GiveQuest_Base_Tex</incident>
|
||||
<incidentIfHostile>WULA_GiveQuest_Hostile_PIA_Attack_Quest</incidentIfHostile>
|
||||
</li>
|
||||
</value>
|
||||
</Operation>
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
<displayName>Humanoid Alien Races 2.0</displayName>
|
||||
<steamWorkshopUrl>https://steamcommunity.com/sharedfiles/filedetails/?id=839005762</steamWorkshopUrl>
|
||||
</li>
|
||||
<li>
|
||||
<packageId>HaiLuan.CustomQuestFramework</packageId>
|
||||
<displayName>Custom Quest Framework</displayName>
|
||||
<steamWorkshopUrl>https://steamcommunity.com/sharedfiles/filedetails/?id=2978572782</steamWorkshopUrl>
|
||||
</li>
|
||||
</modDependencies>
|
||||
|
||||
<loadAfter>
|
||||
@@ -32,5 +37,6 @@
|
||||
<li>Ludeon.RimWorld</li>
|
||||
<li>Ludeon.RimWorld.Biotech</li>
|
||||
<li>erdelf.HumanoidAlienRaces</li>
|
||||
<li>HaiLuan.CustomQuestFramework</li>
|
||||
</loadAfter>
|
||||
</ModMetaData>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 233 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1012 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 989 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 713 KiB |
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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<ThingDef>.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<DebugMenuOption>();
|
||||
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<ThingDef>.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<DebugMenuOption>();
|
||||
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<DebugMenuOption>();
|
||||
|
||||
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<CompProperties_PrefabSkyfallerCaller>().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<IntVec3>();
|
||||
|
||||
// 策略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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 基于Skyfaller实际行为的有效性检查
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取基地附近的开阔区域
|
||||
/// </summary>
|
||||
private static IEnumerable<IntVec3> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找地图上的开阔区域
|
||||
/// </summary>
|
||||
private static IEnumerable<IntVec3> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查区域是否大部分是开阔的(没有建筑,允许自然物体)
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 强制清除区域(作为最后手段)
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<string> inSignal;
|
||||
public SlateRef<ThingDef> thingDef;
|
||||
public SlateRef<Faction> faction;
|
||||
public SlateRef<int> spawnCount = 1;
|
||||
public SlateRef<Map> map;
|
||||
public SlateRef<bool> sendMessageOnSuccess = true;
|
||||
public SlateRef<bool> sendMessageOnFailure = true;
|
||||
|
||||
protected override bool TestRunInt(Slate slate)
|
||||
{
|
||||
// 在测试运行中只检查基本条件
|
||||
if (thingDef.GetValue(slate) == null)
|
||||
{
|
||||
Log.Warning("[QuestNode] ThingDef is null in TestRun");
|
||||
return false;
|
||||
}
|
||||
|
||||
var mapValue = map.GetValue(slate) ?? Find.CurrentMap;
|
||||
if (mapValue == null)
|
||||
{
|
||||
Log.Warning("[QuestNode] Map is null in TestRun");
|
||||
return false;
|
||||
}
|
||||
|
||||
var compProps = thingDef.GetValue(slate).comps?.OfType<CompProperties_PrefabSkyfallerCaller>().FirstOrDefault();
|
||||
if (compProps == null)
|
||||
{
|
||||
Log.Warning($"[QuestNode] ThingDef {thingDef.GetValue(slate).defName} does not have CompProperties_PrefabSkyfallerCaller");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void RunInt()
|
||||
{
|
||||
Slate slate = QuestGen.slate;
|
||||
|
||||
// 获取参数值
|
||||
ThingDef targetThingDef = thingDef.GetValue(slate);
|
||||
Faction targetFaction = faction.GetValue(slate);
|
||||
int targetSpawnCount = spawnCount.GetValue(slate);
|
||||
Map targetMap = map.GetValue(slate) ?? Find.CurrentMap;
|
||||
bool doSendMessageOnSuccess = sendMessageOnSuccess.GetValue(slate);
|
||||
bool doSendMessageOnFailure = sendMessageOnFailure.GetValue(slate);
|
||||
|
||||
if (targetThingDef == null)
|
||||
{
|
||||
Log.Error("[QuestNode] ThingDef is null in RunInt");
|
||||
return;
|
||||
}
|
||||
|
||||
if (targetMap == null)
|
||||
{
|
||||
Log.Error("[QuestNode] Map is null in RunInt");
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取组件属性
|
||||
var compProps = targetThingDef.comps?.OfType<CompProperties_PrefabSkyfallerCaller>().FirstOrDefault();
|
||||
if (compProps == null)
|
||||
{
|
||||
Log.Error($"[QuestNode] ThingDef {targetThingDef.defName} does not have CompProperties_PrefabSkyfallerCaller");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Message($"[QuestNode] Attempting to spawn {targetSpawnCount} {targetThingDef.defName} on map {targetMap}");
|
||||
|
||||
// 执行生成
|
||||
int successCount = SpawnThingsAtValidLocations(targetThingDef, targetFaction, targetSpawnCount, targetMap);
|
||||
|
||||
// 发送结果消息
|
||||
if (successCount > 0)
|
||||
{
|
||||
if (doSendMessageOnSuccess)
|
||||
{
|
||||
Messages.Message($"[Quest] Successfully spawned {successCount} {targetThingDef.label}", MessageTypeDefOf.PositiveEvent);
|
||||
}
|
||||
Log.Message($"[QuestNode] Successfully spawned {successCount}/{targetSpawnCount} {targetThingDef.defName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (doSendMessageOnFailure)
|
||||
{
|
||||
Messages.Message($"[Quest] Failed to spawn any {targetThingDef.label}", MessageTypeDefOf.NegativeEvent);
|
||||
}
|
||||
Log.Warning($"[QuestNode] Failed to spawn any {targetThingDef.defName}");
|
||||
}
|
||||
|
||||
// 将结果存储到Slate中,供后续节点使用
|
||||
QuestGen.slate.Set("prefabSpawnSuccessCount", successCount);
|
||||
QuestGen.slate.Set("prefabSpawnRequestedCount", targetSpawnCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在有效位置生成多个建筑
|
||||
/// </summary>
|
||||
private int SpawnThingsAtValidLocations(ThingDef thingDef, Faction faction, int spawnCount, Map targetMap)
|
||||
{
|
||||
int successCount = 0;
|
||||
int attempts = 0;
|
||||
const int maxAttempts = 100; // 最大尝试次数
|
||||
|
||||
var compProps = thingDef.comps.OfType<CompProperties_PrefabSkyfallerCaller>().FirstOrDefault();
|
||||
if (compProps == null)
|
||||
{
|
||||
Log.Error($"[QuestNode] Could not find CompProperties_PrefabSkyfallerCaller for {thingDef.defName}");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < spawnCount && attempts < maxAttempts; i++)
|
||||
{
|
||||
attempts++;
|
||||
IntVec3 spawnPos = FindSpawnPositionForSkyfaller(targetMap, thingDef, compProps);
|
||||
|
||||
if (spawnPos.IsValid)
|
||||
{
|
||||
Thing thing = ThingMaker.MakeThing(thingDef);
|
||||
|
||||
if (faction != null)
|
||||
{
|
||||
thing.SetFaction(faction);
|
||||
}
|
||||
|
||||
GenSpawn.Spawn(thing, spawnPos, targetMap);
|
||||
successCount++;
|
||||
|
||||
Log.Message($"[QuestNode] Successfully spawned {thingDef.defName} at {spawnPos} for faction {faction?.Name ?? "None"}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning($"[QuestNode] Failed to find valid spawn position for {thingDef.defName} (attempt {attempts})");
|
||||
}
|
||||
}
|
||||
|
||||
return successCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找适合Skyfaller空投的位置
|
||||
/// </summary>
|
||||
private IntVec3 FindSpawnPositionForSkyfaller(Map map, ThingDef thingDef, CompProperties_SkyfallerCaller compProps)
|
||||
{
|
||||
var potentialCells = new List<IntVec3>();
|
||||
|
||||
// 策略1:首先尝试玩家基地附近的开放区域
|
||||
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)
|
||||
{
|
||||
return potentialCells.RandomElement();
|
||||
}
|
||||
|
||||
// 策略2:搜索整个地图的开阔区域
|
||||
var openAreas = FindOpenAreas(map, thingDef.Size, 500);
|
||||
foreach (var cell in openAreas)
|
||||
{
|
||||
if (IsValidForSkyfallerDrop(map, cell, thingDef, compProps))
|
||||
{
|
||||
potentialCells.Add(cell);
|
||||
}
|
||||
if (potentialCells.Count > 10) break;
|
||||
}
|
||||
|
||||
if (potentialCells.Count > 0)
|
||||
{
|
||||
return potentialCells.RandomElement();
|
||||
}
|
||||
|
||||
// 策略3:使用随机采样
|
||||
for (int i = 0; i < 300; 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)
|
||||
{
|
||||
return potentialCells.RandomElement();
|
||||
}
|
||||
|
||||
Log.Warning($"[QuestNode] No valid positions found for {thingDef.defName} after exhaustive search");
|
||||
return IntVec3.Invalid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 基于Skyfaller实际行为的有效性检查
|
||||
/// </summary>
|
||||
private 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取基地附近的开阔区域
|
||||
/// </summary>
|
||||
private IEnumerable<IntVec3> 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))
|
||||
{
|
||||
yield return cell;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找地图上的开阔区域
|
||||
/// </summary>
|
||||
private IEnumerable<IntVec3> 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))
|
||||
{
|
||||
yield return cell;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查区域是否大部分是开阔的
|
||||
/// </summary>
|
||||
private 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,10 +18,13 @@ namespace WulaFallenEmpire
|
||||
public QuestScriptDef questDef; // 关联的任务定义(可选)
|
||||
public bool preventDuplicateQuests = true; // 防止重复任务
|
||||
|
||||
// 派系关系校验 - 新增字段
|
||||
// 派系关系校验
|
||||
public FactionDef requiredFaction; // 必须存在的派系
|
||||
public bool requireNonHostileRelation = true; // 是否要求非敌对关系(默认true)
|
||||
public bool requireFactionExists = true; // 是否要求派系必须存在(默认true)
|
||||
|
||||
// 敌对情况下的替代事件 - 新增字段
|
||||
public IncidentDef incidentIfHostile; // 当派系敌对且requireNonHostileRelation为false时触发的事件
|
||||
|
||||
// 调试配置
|
||||
public bool debugLogging = false; // 启用调试日志
|
||||
|
||||
@@ -12,7 +12,6 @@ namespace WulaFallenEmpire
|
||||
private StorytellerCompProperties_SimpleTechnologyTrigger SimpleProps =>
|
||||
(StorytellerCompProperties_SimpleTechnologyTrigger)props;
|
||||
|
||||
// 重新实现基类的私有属性
|
||||
private static int IntervalsPassed => Find.TickManager.TicksGame / 1000;
|
||||
|
||||
public override IEnumerable<FiringIncident> MakeIntervalIncidents(IIncidentTarget target)
|
||||
@@ -25,8 +24,13 @@ namespace WulaFallenEmpire
|
||||
if (!PassesIntervalCheck())
|
||||
yield break;
|
||||
|
||||
// 检查派系关系条件 - 新增检查
|
||||
if (!PassesRequiredFactionCheck())
|
||||
// 检查派系关系条件
|
||||
var factionCheckResult = PassesRequiredFactionCheck();
|
||||
|
||||
// 根据派系关系结果决定触发哪个事件
|
||||
IncidentDef incidentToTrigger = GetIncidentBasedOnFactionRelation(factionCheckResult);
|
||||
|
||||
if (incidentToTrigger == null)
|
||||
yield break;
|
||||
|
||||
// 检查派系过滤条件
|
||||
@@ -38,30 +42,59 @@ namespace WulaFallenEmpire
|
||||
yield break;
|
||||
|
||||
// 检查是否防止重复任务
|
||||
if (SimpleProps.preventDuplicateQuests && HasActiveQuest())
|
||||
if (SimpleProps.preventDuplicateQuests && HasActiveQuest(incidentToTrigger))
|
||||
yield break;
|
||||
|
||||
// 触发事件
|
||||
IncidentDef techIncident = SimpleProps.incident;
|
||||
if (techIncident.TargetAllowed(target))
|
||||
if (incidentToTrigger.TargetAllowed(target))
|
||||
{
|
||||
if (SimpleProps.debugLogging)
|
||||
{
|
||||
Log.Message($"[SimpleTechnologyTrigger] Triggering incident {techIncident.defName} for technology {SimpleProps.technology.defName}");
|
||||
Log.Message($"[SimpleTechnologyTrigger] Triggering incident {incidentToTrigger.defName} for technology {SimpleProps.technology.defName}");
|
||||
Log.Message($"[SimpleTechnologyTrigger] Faction relation status: {factionCheckResult}");
|
||||
}
|
||||
|
||||
yield return new FiringIncident(techIncident, this, GenerateParms(techIncident.category, target));
|
||||
yield return new FiringIncident(incidentToTrigger, this, GenerateParms(incidentToTrigger.category, target));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查必需派系关系条件 - 新增方法
|
||||
/// 根据派系关系状态决定触发哪个事件
|
||||
/// </summary>
|
||||
private bool PassesRequiredFactionCheck()
|
||||
private IncidentDef GetIncidentBasedOnFactionRelation(FactionRelationResult factionCheckResult)
|
||||
{
|
||||
switch (factionCheckResult.Status)
|
||||
{
|
||||
case FactionRelationStatus.Valid:
|
||||
return SimpleProps.incident;
|
||||
|
||||
case FactionRelationStatus.HostileButAllowed:
|
||||
// 如果配置了敌对情况下的替代事件,则使用替代事件
|
||||
if (SimpleProps.incidentIfHostile != null)
|
||||
{
|
||||
if (SimpleProps.debugLogging)
|
||||
{
|
||||
Log.Message($"[SimpleTechnologyTrigger] Using hostile alternative incident: {SimpleProps.incidentIfHostile.defName}");
|
||||
}
|
||||
return SimpleProps.incidentIfHostile;
|
||||
}
|
||||
// 如果没有配置替代事件,则使用原事件
|
||||
return SimpleProps.incident;
|
||||
|
||||
case FactionRelationStatus.Invalid:
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查必需派系关系条件
|
||||
/// </summary>
|
||||
private FactionRelationResult PassesRequiredFactionCheck()
|
||||
{
|
||||
// 如果没有配置必需派系,直接通过
|
||||
if (SimpleProps.requiredFaction == null)
|
||||
return true;
|
||||
return FactionRelationResult.Valid();
|
||||
|
||||
// 查找派系
|
||||
Faction requiredFactionInstance = Find.FactionManager.FirstFactionOfDef(SimpleProps.requiredFaction);
|
||||
@@ -75,21 +108,35 @@ namespace WulaFallenEmpire
|
||||
{
|
||||
Log.Message($"[SimpleTechnologyTrigger] Required faction {SimpleProps.requiredFaction.defName} does not exist or is defeated");
|
||||
}
|
||||
return false;
|
||||
return FactionRelationResult.Invalid("Faction does not exist or is defeated");
|
||||
}
|
||||
}
|
||||
|
||||
// 检查派系关系
|
||||
if (SimpleProps.requireNonHostileRelation && requiredFactionInstance != null)
|
||||
if (requiredFactionInstance != null)
|
||||
{
|
||||
Faction playerFaction = Faction.OfPlayer;
|
||||
if (requiredFactionInstance.HostileTo(playerFaction))
|
||||
bool isHostile = requiredFactionInstance.HostileTo(playerFaction);
|
||||
|
||||
if (isHostile)
|
||||
{
|
||||
if (SimpleProps.debugLogging)
|
||||
if (SimpleProps.requireNonHostileRelation)
|
||||
{
|
||||
Log.Message($"[SimpleTechnologyTrigger] Required faction {SimpleProps.requiredFaction.defName} is hostile to player");
|
||||
if (SimpleProps.debugLogging)
|
||||
{
|
||||
Log.Message($"[SimpleTechnologyTrigger] Required faction {SimpleProps.requiredFaction.defName} is hostile to player and requireNonHostileRelation is true");
|
||||
}
|
||||
return FactionRelationResult.Invalid("Faction is hostile and requireNonHostileRelation is true");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 不要求非敌对关系,但派系是敌对的 - 这是一个特殊状态
|
||||
if (SimpleProps.debugLogging)
|
||||
{
|
||||
Log.Message($"[SimpleTechnologyTrigger] Required faction {SimpleProps.requiredFaction.defName} is hostile but requireNonHostileRelation is false - allowing with possible alternative");
|
||||
}
|
||||
return FactionRelationResult.HostileButAllowed();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +145,7 @@ namespace WulaFallenEmpire
|
||||
Log.Message($"[SimpleTechnologyTrigger] Required faction {SimpleProps.requiredFaction.defName} check passed");
|
||||
}
|
||||
|
||||
return true;
|
||||
return FactionRelationResult.Valid();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -106,11 +153,9 @@ namespace WulaFallenEmpire
|
||||
/// </summary>
|
||||
private bool PassesIntervalCheck()
|
||||
{
|
||||
// 简单的周期检查:每 X 天检查一次
|
||||
int currentInterval = IntervalsPassed;
|
||||
int checkInterval = (int)(SimpleProps.checkIntervalDays * 60);
|
||||
|
||||
// 如果检查间隔为0,则每个间隔都检查
|
||||
if (checkInterval <= 0)
|
||||
return true;
|
||||
|
||||
@@ -128,7 +173,6 @@ namespace WulaFallenEmpire
|
||||
return false;
|
||||
}
|
||||
|
||||
// 简单检查科技是否已研究完成
|
||||
bool hasTechnology = SimpleProps.technology.IsFinished;
|
||||
|
||||
if (SimpleProps.debugLogging)
|
||||
@@ -144,16 +188,13 @@ namespace WulaFallenEmpire
|
||||
/// </summary>
|
||||
private bool PassesFactionFilter(IIncidentTarget target)
|
||||
{
|
||||
// 如果不启用派系过滤,直接通过
|
||||
if (!SimpleProps.useFactionFilter)
|
||||
return true;
|
||||
|
||||
// 获取目标的派系
|
||||
Faction faction = GetTargetFaction(target);
|
||||
if (faction == null)
|
||||
return false;
|
||||
|
||||
// 检查黑名单
|
||||
if (SimpleProps.factionTypeBlacklist != null &&
|
||||
SimpleProps.factionTypeBlacklist.Contains(faction.def))
|
||||
{
|
||||
@@ -164,7 +205,6 @@ namespace WulaFallenEmpire
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查白名单
|
||||
if (SimpleProps.factionTypeWhitelist != null &&
|
||||
SimpleProps.factionTypeWhitelist.Count > 0)
|
||||
{
|
||||
@@ -173,14 +213,8 @@ namespace WulaFallenEmpire
|
||||
switch (SimpleProps.defaultBehavior)
|
||||
{
|
||||
case FactionFilterDefaultBehavior.Allow:
|
||||
// 白名单模式:在白名单中或默认允许
|
||||
if (SimpleProps.debugLogging && !inWhitelist)
|
||||
{
|
||||
Log.Message($"[SimpleTechnologyTrigger] Faction {faction.def.defName} not in whitelist, but default behavior is Allow");
|
||||
}
|
||||
return true;
|
||||
case FactionFilterDefaultBehavior.Deny:
|
||||
// 白名单模式:只有在白名单中才允许
|
||||
if (inWhitelist)
|
||||
{
|
||||
if (SimpleProps.debugLogging)
|
||||
@@ -200,7 +234,6 @@ namespace WulaFallenEmpire
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有设置白名单,根据默认行为决定
|
||||
switch (SimpleProps.defaultBehavior)
|
||||
{
|
||||
case FactionFilterDefaultBehavior.Allow:
|
||||
@@ -244,20 +277,23 @@ namespace WulaFallenEmpire
|
||||
/// <summary>
|
||||
/// 检查是否存在活跃的相同任务
|
||||
/// </summary>
|
||||
private bool HasActiveQuest()
|
||||
private bool HasActiveQuest(IncidentDef incident)
|
||||
{
|
||||
if (SimpleProps.questDef == null)
|
||||
return false;
|
||||
|
||||
bool hasActiveQuest = Find.QuestManager.QuestsListForReading.Any((Quest q) =>
|
||||
q.root == SimpleProps.questDef && !q.Historical);
|
||||
|
||||
if (SimpleProps.debugLogging && hasActiveQuest)
|
||||
// 如果配置了防止重复,检查是否有相同根源的任务
|
||||
if (SimpleProps.preventDuplicateQuests && SimpleProps.questDef != null)
|
||||
{
|
||||
Log.Message($"[SimpleTechnologyTrigger] Active quest {SimpleProps.questDef.defName} found, skipping trigger");
|
||||
bool hasActiveQuest = Find.QuestManager.QuestsListForReading.Any((Quest q) =>
|
||||
q.root == SimpleProps.questDef && !q.Historical);
|
||||
|
||||
if (SimpleProps.debugLogging && hasActiveQuest)
|
||||
{
|
||||
Log.Message($"[SimpleTechnologyTrigger] Active quest {SimpleProps.questDef.defName} found, skipping trigger");
|
||||
}
|
||||
|
||||
return hasActiveQuest;
|
||||
}
|
||||
|
||||
return hasActiveQuest;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -267,13 +303,23 @@ namespace WulaFallenEmpire
|
||||
{
|
||||
StringBuilder status = new StringBuilder();
|
||||
status.AppendLine($"Simple Technology Trigger: {SimpleProps.technology?.defName ?? "NULL"}");
|
||||
|
||||
var factionCheck = PassesRequiredFactionCheck();
|
||||
status.AppendLine($"Faction Relation Status: {factionCheck.Status}");
|
||||
if (!factionCheck.IsValid)
|
||||
{
|
||||
status.AppendLine($"Faction Relation Reason: {factionCheck.Reason}");
|
||||
}
|
||||
|
||||
status.AppendLine($"Research Status: {(PassesTechnologyCheck() ? "✅ COMPLETED" : "❌ NOT COMPLETED")}");
|
||||
status.AppendLine($"Required Faction: {SimpleProps.requiredFaction?.defName ?? "NONE"}");
|
||||
status.AppendLine($"Faction Relation: {(PassesRequiredFactionCheck() ? "✅ VALID" : "❌ INVALID")}");
|
||||
status.AppendLine($"Hostile Alternative: {SimpleProps.incidentIfHostile?.defName ?? "NONE"}");
|
||||
status.AppendLine($"Check Interval: {SimpleProps.checkIntervalDays} days");
|
||||
status.AppendLine($"Current Interval: {IntervalsPassed}");
|
||||
status.AppendLine($"Next Check: {GetNextCheckInterval()} intervals");
|
||||
status.AppendLine($"Can Trigger Now: {PassesIntervalCheck() && PassesTechnologyCheck() && PassesRequiredFactionCheck()}");
|
||||
|
||||
bool canTrigger = PassesIntervalCheck() && PassesTechnologyCheck() && factionCheck.IsValid;
|
||||
status.AppendLine($"Can Trigger Now: {canTrigger}");
|
||||
|
||||
// 详细派系信息
|
||||
if (SimpleProps.requiredFaction != null)
|
||||
@@ -305,4 +351,39 @@ namespace WulaFallenEmpire
|
||||
return ((currentInterval / checkInterval) + 1) * checkInterval;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 派系关系检查结果
|
||||
/// </summary>
|
||||
public struct FactionRelationResult
|
||||
{
|
||||
public FactionRelationStatus Status { get; }
|
||||
public string Reason { get; }
|
||||
public bool IsValid => Status == FactionRelationStatus.Valid || Status == FactionRelationStatus.HostileButAllowed;
|
||||
|
||||
public FactionRelationResult(FactionRelationStatus status, string reason = "")
|
||||
{
|
||||
Status = status;
|
||||
Reason = reason;
|
||||
}
|
||||
|
||||
public static FactionRelationResult Valid() => new FactionRelationResult(FactionRelationStatus.Valid);
|
||||
public static FactionRelationResult HostileButAllowed() => new FactionRelationResult(FactionRelationStatus.HostileButAllowed);
|
||||
public static FactionRelationResult Invalid(string reason) => new FactionRelationResult(FactionRelationStatus.Invalid, reason);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Status}{(string.IsNullOrEmpty(Reason) ? "" : $" ({Reason})")}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 派系关系状态枚举
|
||||
/// </summary>
|
||||
public enum FactionRelationStatus
|
||||
{
|
||||
Valid, // 关系有效,可以触发原事件
|
||||
HostileButAllowed, // 关系敌对但允许,可以触发替代事件
|
||||
Invalid // 关系无效,不触发任何事件
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
using RimWorld;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
namespace WulaFallenEmpire
|
||||
{
|
||||
public class CompProperties_DelayedDamageIfNotPlayer : CompProperties
|
||||
{
|
||||
public DamageDef damageDef;
|
||||
public int damageAmount = 10;
|
||||
public float armorPenetration = 0f;
|
||||
public BodyPartDef hitPart;
|
||||
public bool destroyIfKilled = true;
|
||||
|
||||
public CompProperties_DelayedDamageIfNotPlayer()
|
||||
{
|
||||
compClass = typeof(CompDelayedDamageIfNotPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
public class CompDelayedDamageIfNotPlayer : ThingComp
|
||||
{
|
||||
private bool damageApplied = false;
|
||||
private bool scheduledForNextFrame = false;
|
||||
|
||||
public CompProperties_DelayedDamageIfNotPlayer Props => (CompProperties_DelayedDamageIfNotPlayer)props;
|
||||
|
||||
public override void PostSpawnSetup(bool respawningAfterLoad)
|
||||
{
|
||||
base.PostSpawnSetup(respawningAfterLoad);
|
||||
|
||||
// 只在初次生成时检查,重新加载时不重复
|
||||
if (!respawningAfterLoad)
|
||||
{
|
||||
CheckAndScheduleDamage();
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckAndScheduleDamage()
|
||||
{
|
||||
// 检查派系,如果不是玩家派系则安排伤害
|
||||
if (parent.Faction != Faction.OfPlayer && !damageApplied && !scheduledForNextFrame)
|
||||
{
|
||||
scheduledForNextFrame = true;
|
||||
|
||||
// 使用LongEventHandler来在下一帧执行
|
||||
LongEventHandler.ExecuteWhenFinished(ApplyDelayedDamage);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyDelayedDamage()
|
||||
{
|
||||
if (scheduledForNextFrame && !damageApplied)
|
||||
{
|
||||
// 再次确认对象仍然存在且未被销毁
|
||||
if (parent != null && parent.Spawned && !parent.Destroyed)
|
||||
{
|
||||
ApplyDamage();
|
||||
}
|
||||
scheduledForNextFrame = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyDamage()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (parent == null || parent.Destroyed || damageApplied)
|
||||
return;
|
||||
|
||||
// 创建伤害信息
|
||||
DamageInfo damageInfo = new DamageInfo(
|
||||
Props.damageDef,
|
||||
Props.damageAmount,
|
||||
armorPenetration: Props.armorPenetration,
|
||||
instigator: parent
|
||||
);
|
||||
|
||||
// 施加伤害
|
||||
parent.TakeDamage(damageInfo);
|
||||
|
||||
damageApplied = true;
|
||||
|
||||
// 记录日志以便调试
|
||||
Log.Message($"[CompDelayedDamage] Applied {Props.damageAmount} {Props.damageDef.defName} damage to {parent.Label} (Faction: {parent.Faction?.Name ?? "None"})");
|
||||
|
||||
// 检查是否被杀死
|
||||
if (Props.destroyIfKilled && (parent.Destroyed || (parent is Pawn pawn && pawn.Dead)))
|
||||
{
|
||||
Log.Message($"[CompDelayedDamage] {parent.Label} was destroyed by delayed damage");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Log.Error($"[CompDelayedDamage] Error applying delayed damage: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
public override void PostExposeData()
|
||||
{
|
||||
base.PostExposeData();
|
||||
Scribe_Values.Look(ref damageApplied, "damageApplied", false);
|
||||
Scribe_Values.Look(ref scheduledForNextFrame, "scheduledForNextFrame", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,6 +122,7 @@
|
||||
<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\DebugActions_PrefabSkyfallerCaller.cs" />
|
||||
<Compile Include="BuildingComp\WULA_SkyfallerCaller\Skyfaller_PrefabSpawner.cs" />
|
||||
<Compile Include="BuildingComp\WULA_SkyfallerCaller\WulaSkyfallerWorldComponent.cs" />
|
||||
<Compile Include="BuildingComp\WULA_SkyfallerCaller\WULA_SkyfallerFactioncs\CompProperties_SkyfallerFaction.cs" />
|
||||
@@ -259,6 +260,7 @@
|
||||
<Compile Include="QuestNodes\QuestNode_CheckGlobalResource.cs" />
|
||||
<Compile Include="QuestNodes\QuestNode_GeneratePawnWithCustomization.cs" />
|
||||
<Compile Include="QuestNodes\QuestNode_Hyperlinks.cs" />
|
||||
<Compile Include="QuestNodes\QuestNode_SpawnPrefabSkyfallerCaller.cs" />
|
||||
<Compile Include="QuestNodes\QuestPart_GlobalResourceCheck.cs" />
|
||||
<Compile Include="Stat\StatWorker_Energy.cs" />
|
||||
<Compile Include="Stat\StatWorker_Maintenance.cs" />
|
||||
@@ -269,6 +271,7 @@
|
||||
<Compile Include="Storyteller\WULA_SimpleTechnologyTrigger\StorytellerComp_SimpleTechnologyTrigger.cs" />
|
||||
<Compile Include="ThingComp\CompAndPatch_GiveHediffOnShot.cs" />
|
||||
<Compile Include="ThingComp\CompApparelInterceptor.cs" />
|
||||
<Compile Include="ThingComp\CompProperties_DelayedDamageIfNotPlayer.cs" />
|
||||
<Compile Include="ThingComp\CompPsychicScaling.cs" />
|
||||
<Compile Include="ThingComp\CompUseEffect_AddDamageShieldCharges.cs" />
|
||||
<Compile Include="ThingComp\CompUseEffect_OpenCustomUI.cs" />
|
||||
|
||||
Reference in New Issue
Block a user