到底有多强
This commit is contained in:
Binary file not shown.
@@ -970,6 +970,270 @@
|
||||
</statBases>
|
||||
</ThingDef>
|
||||
|
||||
<!-- 大型机械族 -->
|
||||
<ThingDef Name="Wula_Mech_Mobile_Factory" ParentName="WULA_BaseMechanoid">
|
||||
<defName>Wula_Mech_Mobile_Factory</defName> <!-- 修改了defName以避免冲突 -->
|
||||
<label>MFm-2"陆行舰"</label>
|
||||
<description>乌拉帝国的大型战争机械,简直就是一座移动堡垒——它不仅装甲厚实、火炮林立,还能在战场上生产大量的辅助战争机械以形成坚实的弹性阵线,生来就是为了粉碎坚固的堡垒和顽强的抵抗。</description>
|
||||
<statBases>
|
||||
<BandwidthCost>1</BandwidthCost>
|
||||
<MoveSpeed>1.5</MoveSpeed>
|
||||
<EnergyShieldEnergyMax>5</EnergyShieldEnergyMax>
|
||||
</statBases>
|
||||
<race>
|
||||
<body>Mech_Warqueen</body>
|
||||
<baseBodySize>30</baseBodySize>
|
||||
<lifeStageAges>
|
||||
<li>
|
||||
<def>MechanoidFullyFormed</def>
|
||||
<minAge>0</minAge>
|
||||
<soundWounded>Pawn_Mech_Warqueen_Wounded</soundWounded>
|
||||
<soundDeath>Pawn_Mech_Warqueen_Death</soundDeath>
|
||||
<soundCall>Pawn_Mech_Warqueen_Call</soundCall>
|
||||
</li>
|
||||
</lifeStageAges>
|
||||
<baseHealthScale>25</baseHealthScale>
|
||||
<!-- <thinkTreeConstant>WarUrchinConstant</thinkTreeConstant> -->
|
||||
</race>
|
||||
<tools>
|
||||
<li>
|
||||
<label>碾压</label>
|
||||
<capacities>
|
||||
<li>Blunt</li>
|
||||
</capacities>
|
||||
<power>360</power>
|
||||
<cooldownTime>8</cooldownTime>
|
||||
<linkedBodyPartsGroup>Torso</linkedBodyPartsGroup>
|
||||
<ensureLinkedBodyPartsGroupAlwaysUsable>true</ensureLinkedBodyPartsGroupAlwaysUsable>
|
||||
</li>
|
||||
</tools>
|
||||
<comps>
|
||||
<li Class="WulaFallenEmpire.CompProperties_MultiTurretGun">
|
||||
<ID>0</ID>
|
||||
<turretDef>Wula_CR_Mobile_Factory_Turret</turretDef>
|
||||
<!-- <angleOffset>-90</angleOffset> -->
|
||||
<renderNodeProperties>
|
||||
<li>
|
||||
<nodeClass>PawnRenderNode_TurretGun</nodeClass>
|
||||
<workerClass>PawnRenderNodeWorker_TurretGun</workerClass>
|
||||
<parentTagDef>Body</parentTagDef>
|
||||
<overrideMeshSize>(1, 1)</overrideMeshSize>
|
||||
<baseLayer>20</baseLayer>
|
||||
<pawnType>Any</pawnType>
|
||||
<drawData>
|
||||
<dataNorth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(-1, 0, -1.45)</offset>
|
||||
<flip>true</flip>
|
||||
<layer>-5</layer>
|
||||
</dataNorth>
|
||||
<dataEast>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<layer>-5</layer>
|
||||
<offset>(2.15, 0, -1)</offset>
|
||||
</dataEast>
|
||||
<dataSouth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(1, 0, -1.45)</offset>
|
||||
</dataSouth>
|
||||
<dataWest>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<offset>(-2.15, 0, -1)</offset>
|
||||
</dataWest>
|
||||
</drawData>
|
||||
</li>
|
||||
</renderNodeProperties>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.CompProperties_MultiTurretGun">
|
||||
<ID>1</ID>
|
||||
<turretDef>Wula_CR_Mobile_Factory_Turret</turretDef>
|
||||
<!-- <angleOffset>-90</angleOffset> -->
|
||||
<renderNodeProperties>
|
||||
<li>
|
||||
<nodeClass>PawnRenderNode_TurretGun</nodeClass>
|
||||
<workerClass>PawnRenderNodeWorker_TurretGun</workerClass>
|
||||
<parentTagDef>Body</parentTagDef>
|
||||
<overrideMeshSize>(1, 1)</overrideMeshSize>
|
||||
<baseLayer>20</baseLayer>
|
||||
<pawnType>Any</pawnType>
|
||||
<drawData>
|
||||
<dataNorth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(1, 0, -1.45)</offset>
|
||||
<layer>-5</layer>
|
||||
</dataNorth>
|
||||
<dataEast>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(2.15, 0, -1)</offset>
|
||||
</dataEast>
|
||||
<dataSouth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(-1, 0, -1.45)</offset>
|
||||
</dataSouth>
|
||||
<dataWest>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<offset>(-2.15, 0, -1)</offset>
|
||||
<layer>-5</layer>
|
||||
</dataWest>
|
||||
</drawData>
|
||||
</li>
|
||||
</renderNodeProperties>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.CompProperties_MultiTurretGun">
|
||||
<ID>2</ID>
|
||||
<turretDef>Wula_MR_Mobile_Factory_Turret</turretDef>
|
||||
<!-- <angleOffset>-90</angleOffset> -->
|
||||
<renderNodeProperties>
|
||||
<li>
|
||||
<nodeClass>PawnRenderNode_TurretGun</nodeClass>
|
||||
<workerClass>PawnRenderNodeWorker_TurretGun</workerClass>
|
||||
<parentTagDef>Body</parentTagDef>
|
||||
<overrideMeshSize>(1, 1)</overrideMeshSize>
|
||||
<baseLayer>20</baseLayer>
|
||||
<pawnType>Any</pawnType>
|
||||
<drawData>
|
||||
<dataNorth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(-1.3, 0, -0.45)</offset>
|
||||
<flip>true</flip>
|
||||
<layer>-5</layer>
|
||||
</dataNorth>
|
||||
<dataEast>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<layer>-5</layer>
|
||||
<offset>(1.4, 0, -0.35)</offset>
|
||||
</dataEast>
|
||||
<dataSouth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(1.3, 0, -0.45)</offset>
|
||||
</dataSouth>
|
||||
<dataWest>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<offset>(-1.4, 0, -0.35)</offset>
|
||||
</dataWest>
|
||||
</drawData>
|
||||
</li>
|
||||
</renderNodeProperties>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.CompProperties_MultiTurretGun">
|
||||
<ID>3</ID>
|
||||
<turretDef>Wula_MR_Mobile_Factory_Turret</turretDef>
|
||||
<!-- <angleOffset>-90</angleOffset> -->
|
||||
<renderNodeProperties>
|
||||
<li>
|
||||
<nodeClass>PawnRenderNode_TurretGun</nodeClass>
|
||||
<workerClass>PawnRenderNodeWorker_TurretGun</workerClass>
|
||||
<parentTagDef>Body</parentTagDef>
|
||||
<overrideMeshSize>(1, 1)</overrideMeshSize>
|
||||
<baseLayer>20</baseLayer>
|
||||
<pawnType>Any</pawnType>
|
||||
<drawData>
|
||||
<dataNorth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(1.3, 0, -0.45)</offset>
|
||||
<flip>true</flip>
|
||||
<layer>-5</layer>
|
||||
</dataNorth>
|
||||
<dataEast>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(1.4, 0, -0.35)</offset>
|
||||
</dataEast>
|
||||
<dataSouth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(-1.3, 0, -0.45)</offset>
|
||||
</dataSouth>
|
||||
<dataWest>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<layer>-5</layer>
|
||||
<offset>(-1.4, 0, -0.35)</offset>
|
||||
</dataWest>
|
||||
</drawData>
|
||||
</li>
|
||||
</renderNodeProperties>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.CompProperties_MultiTurretGun">
|
||||
<ID>4</ID>
|
||||
<turretDef>Wula_LR_Mobile_Factory_Turret</turretDef>
|
||||
<!-- <angleOffset>-90</angleOffset> -->
|
||||
<renderNodeProperties>
|
||||
<li>
|
||||
<nodeClass>PawnRenderNode_TurretGun</nodeClass>
|
||||
<workerClass>PawnRenderNodeWorker_TurretGun</workerClass>
|
||||
<parentTagDef>Body</parentTagDef>
|
||||
<overrideMeshSize>(1, 1)</overrideMeshSize>
|
||||
<baseLayer>20</baseLayer>
|
||||
<pawnType>Any</pawnType>
|
||||
<drawData>
|
||||
<dataNorth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(1.25, 0, 0.45)</offset>
|
||||
<flip>true</flip>
|
||||
<layer>-5</layer>
|
||||
</dataNorth>
|
||||
<dataEast>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<layer>-5</layer>
|
||||
<offset>(0.6, 0, 0.15)</offset>
|
||||
</dataEast>
|
||||
<dataSouth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(-1.25, 0, 0.65)</offset>
|
||||
</dataSouth>
|
||||
<dataWest>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<offset>(-0.6, 0, 0.15)</offset>
|
||||
</dataWest>
|
||||
</drawData>
|
||||
</li>
|
||||
</renderNodeProperties>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.CompProperties_MultiTurretGun">
|
||||
<ID>5</ID>
|
||||
<turretDef>Wula_LR_Mobile_Factory_Turret</turretDef>
|
||||
<!-- <angleOffset>-90</angleOffset> -->
|
||||
<renderNodeProperties>
|
||||
<li>
|
||||
<nodeClass>PawnRenderNode_TurretGun</nodeClass>
|
||||
<workerClass>PawnRenderNodeWorker_TurretGun</workerClass>
|
||||
<parentTagDef>Body</parentTagDef>
|
||||
<overrideMeshSize>(1, 1)</overrideMeshSize>
|
||||
<baseLayer>20</baseLayer>
|
||||
<pawnType>Any</pawnType>
|
||||
<drawData>
|
||||
<dataNorth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(-1.25, 0, 0.45)</offset>
|
||||
<flip>true</flip>
|
||||
<layer>-5</layer>
|
||||
</dataNorth>
|
||||
<dataEast>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(0.6, 0, 0.15)</offset>
|
||||
</dataEast>
|
||||
<dataSouth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(1.25, 0, 0.65)</offset>
|
||||
</dataSouth>
|
||||
<dataWest>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<layer>-5</layer>
|
||||
<offset>(-0.6, 0, 0.15)</offset>
|
||||
</dataWest>
|
||||
</drawData>
|
||||
</li>
|
||||
</renderNodeProperties>
|
||||
</li>
|
||||
<li Class="CompProperties_Shield">
|
||||
<startingTicksToReset>36000</startingTicksToReset><!-- 10 mins -->
|
||||
<minDrawSize>8.2</minDrawSize>
|
||||
<maxDrawSize>8.4</maxDrawSize>
|
||||
<energyLossPerDamage>0.01</energyLossPerDamage>
|
||||
<energyOnReset>4.0</energyOnReset>
|
||||
<blocksRangedWeapons>false</blocksRangedWeapons>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
|
||||
<ThingDef Name="Wula_AI_Heavy_Panzer" ParentName="HeavyMechanoid">
|
||||
<defName>Wula_AI_Heavy_Panzer</defName>
|
||||
<label>SMp-38"萨克森"</label>
|
||||
@@ -1355,6 +1619,7 @@
|
||||
</comps>
|
||||
</ThingDef>
|
||||
|
||||
<!-- 特殊单位 -->
|
||||
<ThingDef ParentName="BaseMechanoidWalker">
|
||||
<defName>WULA_Fxxk_Goose</defName>
|
||||
<label>神人大鹅</label>
|
||||
|
||||
@@ -175,362 +175,6 @@
|
||||
<defName>WULA_Mech_Flyer_Melta_Slow</defName>
|
||||
</PawnKindDef>
|
||||
|
||||
<ThingDef Name="Wula_Mech_Mobile_Factory" ParentName="HeavyMechanoid">
|
||||
<defName>Wula_Mech_Mobile_Factory</defName> <!-- 修改了defName以避免冲突 -->
|
||||
<label>MFm-87"天秤"</label>
|
||||
<description>乌拉帝国图书馆的陆行战舰——火力强大,装甲厚重,不仅拥有各种各样的副炮和威力巨大的主炮,还能生产海量的小型机械体掩护行动,是乌拉帝国图书馆战术的典型代表。</description>
|
||||
<statBases>
|
||||
<BandwidthCost>14</BandwidthCost>
|
||||
<MoveSpeed>1.5</MoveSpeed>
|
||||
<EnergyShieldEnergyMax>5</EnergyShieldEnergyMax>
|
||||
</statBases>
|
||||
<race>
|
||||
<body>Mech_Warqueen</body>
|
||||
<baseBodySize>30</baseBodySize>
|
||||
<lifeStageAges>
|
||||
<li>
|
||||
<def>MechanoidFullyFormed</def>
|
||||
<minAge>0</minAge>
|
||||
<soundWounded>Pawn_Mech_Warqueen_Wounded</soundWounded>
|
||||
<soundDeath>Pawn_Mech_Warqueen_Death</soundDeath>
|
||||
<soundCall>Pawn_Mech_Warqueen_Call</soundCall>
|
||||
</li>
|
||||
</lifeStageAges>
|
||||
<baseHealthScale>25</baseHealthScale>
|
||||
<!-- <thinkTreeConstant>WarUrchinConstant</thinkTreeConstant> -->
|
||||
</race>
|
||||
<tools>
|
||||
<li>
|
||||
<label>碾压</label>
|
||||
<capacities>
|
||||
<li>Blunt</li>
|
||||
</capacities>
|
||||
<power>360</power>
|
||||
<cooldownTime>8</cooldownTime>
|
||||
<linkedBodyPartsGroup>Torso</linkedBodyPartsGroup>
|
||||
<ensureLinkedBodyPartsGroupAlwaysUsable>true</ensureLinkedBodyPartsGroupAlwaysUsable>
|
||||
</li>
|
||||
</tools>
|
||||
<comps>
|
||||
<!--加上这个组件的机械体会直接跳过原版指挥范围判定-->
|
||||
<li Class="WulaFallenEmpire.CompProperties_GlobalMechCommand" />
|
||||
<li Class="CompProperties_CanBeDormant" />
|
||||
<li Class="CompProperties_WakeUpDormant">
|
||||
<wakeUpOnDamage>true</wakeUpOnDamage>
|
||||
<wakeUpCheckRadius>30</wakeUpCheckRadius>
|
||||
<wakeUpSound>MechanoidsWakeUp</wakeUpSound>
|
||||
</li>
|
||||
<li Class="CompProperties_TurretGun">
|
||||
<turretDef>Wula_CR_Mobile_Factory_Turret</turretDef>
|
||||
<!-- <angleOffset>-90</angleOffset> -->
|
||||
<renderNodeProperties>
|
||||
<li>
|
||||
<nodeClass>PawnRenderNode_TurretGun</nodeClass>
|
||||
<workerClass>PawnRenderNodeWorker_TurretGun</workerClass>
|
||||
<parentTagDef>Body</parentTagDef>
|
||||
<overrideMeshSize>(1, 1)</overrideMeshSize>
|
||||
<baseLayer>20</baseLayer>
|
||||
<pawnType>Any</pawnType>
|
||||
<drawData>
|
||||
<dataNorth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(-1, 0, -1.45)</offset>
|
||||
<flip>true</flip>
|
||||
<layer>-5</layer>
|
||||
</dataNorth>
|
||||
<dataEast>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<layer>-5</layer>
|
||||
<offset>(2.15, 0, -1)</offset>
|
||||
</dataEast>
|
||||
<dataSouth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(1, 0, -1.45)</offset>
|
||||
</dataSouth>
|
||||
<dataWest>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<offset>(-2.15, 0, -1)</offset>
|
||||
</dataWest>
|
||||
</drawData>
|
||||
</li>
|
||||
</renderNodeProperties>
|
||||
</li>
|
||||
<li Class="CompProperties_TurretGun">
|
||||
<turretDef>Wula_CR_Mobile_Factory_Turret</turretDef>
|
||||
<!-- <angleOffset>-90</angleOffset> -->
|
||||
<renderNodeProperties>
|
||||
<li>
|
||||
<nodeClass>PawnRenderNode_TurretGun</nodeClass>
|
||||
<workerClass>PawnRenderNodeWorker_TurretGun</workerClass>
|
||||
<parentTagDef>Body</parentTagDef>
|
||||
<overrideMeshSize>(1, 1)</overrideMeshSize>
|
||||
<baseLayer>20</baseLayer>
|
||||
<pawnType>Any</pawnType>
|
||||
<drawData>
|
||||
<dataNorth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(1, 0, -1.45)</offset>
|
||||
<layer>-5</layer>
|
||||
</dataNorth>
|
||||
<dataEast>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(2.15, 0, -1)</offset>
|
||||
</dataEast>
|
||||
<dataSouth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(-1, 0, -1.45)</offset>
|
||||
</dataSouth>
|
||||
<dataWest>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<offset>(-2.15, 0, -1)</offset>
|
||||
<layer>-5</layer>
|
||||
</dataWest>
|
||||
</drawData>
|
||||
</li>
|
||||
</renderNodeProperties>
|
||||
</li>
|
||||
<li Class="CompProperties_TurretGun">
|
||||
<turretDef>Wula_MR_Mobile_Factory_Turret</turretDef>
|
||||
<!-- <angleOffset>-90</angleOffset> -->
|
||||
<renderNodeProperties>
|
||||
<li>
|
||||
<nodeClass>PawnRenderNode_TurretGun</nodeClass>
|
||||
<workerClass>PawnRenderNodeWorker_TurretGun</workerClass>
|
||||
<parentTagDef>Body</parentTagDef>
|
||||
<overrideMeshSize>(1, 1)</overrideMeshSize>
|
||||
<baseLayer>20</baseLayer>
|
||||
<pawnType>Any</pawnType>
|
||||
<drawData>
|
||||
<dataNorth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(-1.3, 0, -0.45)</offset>
|
||||
<flip>true</flip>
|
||||
<layer>-5</layer>
|
||||
</dataNorth>
|
||||
<dataEast>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<layer>-5</layer>
|
||||
<offset>(1.4, 0, -0.35)</offset>
|
||||
</dataEast>
|
||||
<dataSouth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(1.3, 0, -0.45)</offset>
|
||||
</dataSouth>
|
||||
<dataWest>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<offset>(-1.4, 0, -0.35)</offset>
|
||||
</dataWest>
|
||||
</drawData>
|
||||
</li>
|
||||
</renderNodeProperties>
|
||||
</li>
|
||||
<li Class="CompProperties_TurretGun">
|
||||
<turretDef>Wula_MR_Mobile_Factory_Turret</turretDef>
|
||||
<!-- <angleOffset>-90</angleOffset> -->
|
||||
<renderNodeProperties>
|
||||
<li>
|
||||
<nodeClass>PawnRenderNode_TurretGun</nodeClass>
|
||||
<workerClass>PawnRenderNodeWorker_TurretGun</workerClass>
|
||||
<parentTagDef>Body</parentTagDef>
|
||||
<overrideMeshSize>(1, 1)</overrideMeshSize>
|
||||
<baseLayer>20</baseLayer>
|
||||
<pawnType>Any</pawnType>
|
||||
<drawData>
|
||||
<dataNorth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(1.3, 0, -0.45)</offset>
|
||||
<flip>true</flip>
|
||||
<layer>-5</layer>
|
||||
</dataNorth>
|
||||
<dataEast>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(1.4, 0, -0.35)</offset>
|
||||
</dataEast>
|
||||
<dataSouth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(-1.3, 0, -0.45)</offset>
|
||||
</dataSouth>
|
||||
<dataWest>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<layer>-5</layer>
|
||||
<offset>(-1.4, 0, -0.35)</offset>
|
||||
</dataWest>
|
||||
</drawData>
|
||||
</li>
|
||||
</renderNodeProperties>
|
||||
</li>
|
||||
<li Class="CompProperties_TurretGun">
|
||||
<turretDef>Wula_LR_Mobile_Factory_Turret</turretDef>
|
||||
<!-- <angleOffset>-90</angleOffset> -->
|
||||
<renderNodeProperties>
|
||||
<li>
|
||||
<nodeClass>PawnRenderNode_TurretGun</nodeClass>
|
||||
<workerClass>PawnRenderNodeWorker_TurretGun</workerClass>
|
||||
<parentTagDef>Body</parentTagDef>
|
||||
<overrideMeshSize>(1, 1)</overrideMeshSize>
|
||||
<baseLayer>20</baseLayer>
|
||||
<pawnType>Any</pawnType>
|
||||
<drawData>
|
||||
<dataNorth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(1.25, 0, 0.45)</offset>
|
||||
<flip>true</flip>
|
||||
<layer>-5</layer>
|
||||
</dataNorth>
|
||||
<dataEast>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<layer>-5</layer>
|
||||
<offset>(0.6, 0, 0.15)</offset>
|
||||
</dataEast>
|
||||
<dataSouth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(-1.25, 0, 0.65)</offset>
|
||||
</dataSouth>
|
||||
<dataWest>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<offset>(-0.6, 0, 0.15)</offset>
|
||||
</dataWest>
|
||||
</drawData>
|
||||
</li>
|
||||
</renderNodeProperties>
|
||||
</li>
|
||||
<li Class="CompProperties_TurretGun">
|
||||
<turretDef>Wula_LR_Mobile_Factory_Turret</turretDef>
|
||||
<!-- <angleOffset>-90</angleOffset> -->
|
||||
<renderNodeProperties>
|
||||
<li>
|
||||
<nodeClass>PawnRenderNode_TurretGun</nodeClass>
|
||||
<workerClass>PawnRenderNodeWorker_TurretGun</workerClass>
|
||||
<parentTagDef>Body</parentTagDef>
|
||||
<overrideMeshSize>(1, 1)</overrideMeshSize>
|
||||
<baseLayer>20</baseLayer>
|
||||
<pawnType>Any</pawnType>
|
||||
<drawData>
|
||||
<dataNorth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(-1.25, 0, 0.45)</offset>
|
||||
<flip>true</flip>
|
||||
<layer>-5</layer>
|
||||
</dataNorth>
|
||||
<dataEast>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(0.6, 0, 0.15)</offset>
|
||||
</dataEast>
|
||||
<dataSouth>
|
||||
<rotationOffset>-90</rotationOffset>
|
||||
<offset>(1.25, 0, 0.65)</offset>
|
||||
</dataSouth>
|
||||
<dataWest>
|
||||
<rotationOffset>90</rotationOffset>
|
||||
<layer>-5</layer>
|
||||
<offset>(-0.6, 0, 0.15)</offset>
|
||||
</dataWest>
|
||||
</drawData>
|
||||
</li>
|
||||
</renderNodeProperties>
|
||||
</li>
|
||||
<li Class="CompProperties_Shield">
|
||||
<startingTicksToReset>36000</startingTicksToReset><!-- 10 mins -->
|
||||
<minDrawSize>4.2</minDrawSize>
|
||||
<maxDrawSize>4.4</maxDrawSize>
|
||||
<energyLossPerDamage>0.01</energyLossPerDamage>
|
||||
<energyOnReset>4.0</energyOnReset>
|
||||
<blocksRangedWeapons>false</blocksRangedWeapons>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.CompProperties_AutoMechCarrier">
|
||||
<freeProduction>true</freeProduction>
|
||||
<disableHediff>WULA_MechCarrierSwitchHediff</disableHediff>
|
||||
<fixedIngredient>Steel</fixedIngredient>
|
||||
<maxIngredientCount>500</maxIngredientCount>
|
||||
<startingIngredientCount>500</startingIngredientCount>
|
||||
<costPerPawn>999</costPerPawn>
|
||||
<cooldownTicks>9999</cooldownTicks>
|
||||
<productionQueue>
|
||||
<li>
|
||||
<pawnKind>WULA_Mech_Flyer</pawnKind>
|
||||
<count>1</count>
|
||||
<cooldownTicks>50</cooldownTicks>
|
||||
</li>
|
||||
<li>
|
||||
<pawnKind>WULA_Mech_Flyer_Slow</pawnKind>
|
||||
<count>4</count>
|
||||
<cooldownTicks>600</cooldownTicks>
|
||||
</li>
|
||||
</productionQueue>
|
||||
<spawnEffecter>WarqueenWarUrchinsSpawned</spawnEffecter>
|
||||
<spawnedMechEffecter>WarUrchinSpawned</spawnedMechEffecter>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.CompProperties_AutoMechCarrier">
|
||||
<freeProduction>true</freeProduction>
|
||||
<disableHediff>WULA_MechCarrierSwitchHediff</disableHediff>
|
||||
<fixedIngredient>Steel</fixedIngredient>
|
||||
<maxIngredientCount>500</maxIngredientCount>
|
||||
<startingIngredientCount>500</startingIngredientCount>
|
||||
<costPerPawn>999</costPerPawn>
|
||||
<cooldownTicks>9999</cooldownTicks>
|
||||
<productionQueue>
|
||||
<li>
|
||||
<pawnKind>WULA_Mech_Flyer</pawnKind>
|
||||
<count>1</count>
|
||||
<cooldownTicks>50</cooldownTicks>
|
||||
</li>
|
||||
<li>
|
||||
<pawnKind>WULA_Mech_Flyer_Slow</pawnKind>
|
||||
<count>4</count>
|
||||
<cooldownTicks>600</cooldownTicks>
|
||||
</li>
|
||||
</productionQueue>
|
||||
<spawnEffecter>WarqueenWarUrchinsSpawned</spawnEffecter>
|
||||
<spawnedMechEffecter>WarUrchinSpawned</spawnedMechEffecter>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.CompProperties_AutoMechCarrier">
|
||||
<freeProduction>true</freeProduction>
|
||||
<disableHediff>WULA_MechCarrierSwitchHediff</disableHediff>
|
||||
<fixedIngredient>Steel</fixedIngredient>
|
||||
<maxIngredientCount>500</maxIngredientCount>
|
||||
<startingIngredientCount>500</startingIngredientCount>
|
||||
<costPerPawn>999</costPerPawn>
|
||||
<cooldownTicks>9999</cooldownTicks>
|
||||
<productionQueue>
|
||||
<li>
|
||||
<pawnKind>WULA_Mech_Flyer</pawnKind>
|
||||
<count>1</count>
|
||||
<cooldownTicks>50</cooldownTicks>
|
||||
</li>
|
||||
<li>
|
||||
<pawnKind>WULA_Mech_Flyer_Slow</pawnKind>
|
||||
<count>4</count>
|
||||
<cooldownTicks>600</cooldownTicks>
|
||||
</li>
|
||||
</productionQueue>
|
||||
<spawnEffecter>WarqueenWarUrchinsSpawned</spawnEffecter>
|
||||
<spawnedMechEffecter>WarUrchinSpawned</spawnedMechEffecter>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.CompProperties_AutoMechCarrier">
|
||||
<freeProduction>true</freeProduction>
|
||||
<disableHediff>WULA_MechCarrierSwitchHediff</disableHediff>
|
||||
<fixedIngredient>Steel</fixedIngredient>
|
||||
<maxIngredientCount>500</maxIngredientCount>
|
||||
<startingIngredientCount>500</startingIngredientCount>
|
||||
<costPerPawn>999</costPerPawn>
|
||||
<cooldownTicks>9999</cooldownTicks>
|
||||
<productionQueue>
|
||||
<li>
|
||||
<pawnKind>WULA_Mech_Flyer</pawnKind>
|
||||
<count>1</count>
|
||||
<cooldownTicks>50</cooldownTicks>
|
||||
</li>
|
||||
<li>
|
||||
<pawnKind>WULA_Mech_Flyer_Slow</pawnKind>
|
||||
<count>4</count>
|
||||
<cooldownTicks>600</cooldownTicks>
|
||||
</li>
|
||||
</productionQueue>
|
||||
<spawnEffecter>WarqueenWarUrchinsSpawned</spawnEffecter>
|
||||
<spawnedMechEffecter>WarUrchinSpawned</spawnedMechEffecter>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
<PawnKindDef Name="Wula_Mech_Mobile_Factory_PawnKind" ParentName="HeavyMechanoidKind">
|
||||
<defName>Wula_Mech_Mobile_Factory</defName> <!-- 修改了defName以避免冲突 -->
|
||||
<label>MFm-87"天秤"</label>
|
||||
|
||||
@@ -1,480 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
using Verse.Sound;
|
||||
using RimWorld;
|
||||
using RimWorld.Planet;
|
||||
|
||||
namespace WulaFallenEmpire
|
||||
{
|
||||
[StaticConstructorOnStartup]
|
||||
public class Building_FlyOverBeacon : Building
|
||||
{
|
||||
public GlobalTargetInfo flyOverTarget;
|
||||
public FlyOverConfig flyOverConfig;
|
||||
public static readonly Texture2D CallFlyOverTex = ContentFinder<Texture2D>.Get("UI/Commands/CallFlyOver", true);
|
||||
|
||||
private CompPowerTrader powerComp;
|
||||
private CompRefuelable refuelableComp;
|
||||
private int cooldownTicksLeft;
|
||||
|
||||
public bool IsReady => (powerComp == null || powerComp.PowerOn) &&
|
||||
(refuelableComp == null || refuelableComp.HasFuel) &&
|
||||
cooldownTicksLeft <= 0;
|
||||
|
||||
public override void SpawnSetup(Map map, bool respawningAfterLoad)
|
||||
{
|
||||
base.SpawnSetup(map, respawningAfterLoad);
|
||||
powerComp = this.TryGetComp<CompPowerTrader>();
|
||||
refuelableComp = this.TryGetComp<CompRefuelable>();
|
||||
|
||||
if (!respawningAfterLoad)
|
||||
{
|
||||
flyOverTarget = GlobalTargetInfo.Invalid;
|
||||
flyOverConfig = new FlyOverConfig();
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
Scribe_TargetInfo.Look(ref flyOverTarget, "flyOverTarget");
|
||||
Scribe_Deep.Look(ref flyOverConfig, "flyOverConfig");
|
||||
Scribe_Values.Look(ref cooldownTicksLeft, "cooldownTicksLeft", 0);
|
||||
}
|
||||
|
||||
protected override void Tick()
|
||||
{
|
||||
base.Tick();
|
||||
|
||||
// 冷却计时
|
||||
if (cooldownTicksLeft > 0)
|
||||
cooldownTicksLeft--;
|
||||
|
||||
// 自动执行已设定的飞越任务
|
||||
if (flyOverTarget.IsValid && IsReady)
|
||||
{
|
||||
ExecuteFlyOverMission();
|
||||
}
|
||||
}
|
||||
|
||||
public override string GetInspectString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(base.GetInspectString());
|
||||
|
||||
if (cooldownTicksLeft > 0)
|
||||
{
|
||||
if (sb.Length > 0) sb.AppendLine();
|
||||
sb.Append("飞越信标冷却中: ".Translate() + cooldownTicksLeft.ToStringTicksToPeriod());
|
||||
}
|
||||
|
||||
if (flyOverTarget.IsValid)
|
||||
{
|
||||
if (sb.Length > 0) sb.AppendLine();
|
||||
sb.Append("已锁定目标: ".Translate() + flyOverTarget.Label);
|
||||
}
|
||||
|
||||
if (!IsReady)
|
||||
{
|
||||
if (sb.Length > 0) sb.AppendLine();
|
||||
if (powerComp != null && !powerComp.PowerOn)
|
||||
sb.Append("需要电力".Translate());
|
||||
else if (refuelableComp != null && !refuelableComp.HasFuel)
|
||||
sb.Append("需要燃料".Translate());
|
||||
else if (cooldownTicksLeft > 0)
|
||||
sb.Append("冷却中".Translate());
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override IEnumerable<Gizmo> GetGizmos()
|
||||
{
|
||||
foreach (var g in base.GetGizmos())
|
||||
{
|
||||
yield return g;
|
||||
}
|
||||
|
||||
// 召唤飞越命令
|
||||
Command_Action callFlyOver = new Command_Action
|
||||
{
|
||||
defaultLabel = "召唤跨图飞越",
|
||||
defaultDesc = "在世界地图上选择目标位置召唤飞越单位",
|
||||
icon = CallFlyOverTex,
|
||||
action = StartChoosingFlyOverTarget
|
||||
};
|
||||
|
||||
if (!IsReady)
|
||||
{
|
||||
callFlyOver.Disable(GetDisabledReason());
|
||||
}
|
||||
yield return callFlyOver;
|
||||
|
||||
// 配置飞越参数命令
|
||||
if (flyOverTarget.IsValid)
|
||||
{
|
||||
Command_Action configureFlyOver = new Command_Action
|
||||
{
|
||||
defaultLabel = "配置飞越参数",
|
||||
defaultDesc = "调整飞越单位的类型和行为",
|
||||
icon = ContentFinder<Texture2D>.Get("UI/Commands/Configure", true),
|
||||
action = OpenConfigurationDialog
|
||||
};
|
||||
yield return configureFlyOver;
|
||||
|
||||
// 清除目标命令
|
||||
Command_Action clearTarget = new Command_Action
|
||||
{
|
||||
defaultLabel = "清除目标",
|
||||
defaultDesc = "清除已锁定的飞越目标",
|
||||
icon = ContentFinder<Texture2D>.Get("UI/Designators/Cancel", true),
|
||||
action = () => flyOverTarget = GlobalTargetInfo.Invalid
|
||||
};
|
||||
yield return clearTarget;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetDisabledReason()
|
||||
{
|
||||
if (powerComp != null && !powerComp.PowerOn)
|
||||
return "需要电力";
|
||||
if (refuelableComp != null && !refuelableComp.HasFuel)
|
||||
return "需要燃料";
|
||||
if (cooldownTicksLeft > 0)
|
||||
return "冷却中";
|
||||
return "无法使用";
|
||||
}
|
||||
|
||||
private void StartChoosingFlyOverTarget()
|
||||
{
|
||||
CameraJumper.TryJump(CameraJumper.GetWorldTarget(this));
|
||||
Find.WorldSelector.ClearSelection();
|
||||
|
||||
Find.WorldTargeter.BeginTargeting(
|
||||
ChooseWorldTarget,
|
||||
canTargetTiles: true,
|
||||
targeterMouseAttachment: CallFlyOverTex,
|
||||
extraLabelGetter: GetExtraTargetingLabel
|
||||
);
|
||||
}
|
||||
|
||||
private string GetExtraTargetingLabel(GlobalTargetInfo target)
|
||||
{
|
||||
if (target.IsValid)
|
||||
{
|
||||
return "召唤飞越至: " + target.Label;
|
||||
}
|
||||
return "选择飞越目标位置";
|
||||
}
|
||||
|
||||
private bool ChooseWorldTarget(GlobalTargetInfo target)
|
||||
{
|
||||
if (!target.IsValid)
|
||||
{
|
||||
Messages.Message("无效的目标位置", MessageTypeDefOf.RejectInput);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target.Tile == this.Map.Tile)
|
||||
{
|
||||
Messages.Message("无法在同一地图召唤飞越", MessageTypeDefOf.RejectInput);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 处理不同类型的目标
|
||||
if (target.WorldObject is MapParent mapParent && mapParent.HasMap)
|
||||
{
|
||||
// 切换到目标地图选择具体飞越路径
|
||||
var originalMap = this.Map;
|
||||
Action onFinished = () => {
|
||||
if (Current.Game.CurrentMap != originalMap)
|
||||
Current.Game.CurrentMap = originalMap;
|
||||
};
|
||||
|
||||
Current.Game.CurrentMap = mapParent.Map;
|
||||
Find.Targeter.BeginTargeting(
|
||||
new TargetingParameters
|
||||
{
|
||||
canTargetLocations = true,
|
||||
canTargetPawns = false,
|
||||
canTargetBuildings = false,
|
||||
mapObjectTargetsMustBeAutoAttackable = false
|
||||
},
|
||||
(LocalTargetInfo localTarget) =>
|
||||
{
|
||||
// 设置飞越配置
|
||||
flyOverTarget = new GlobalTargetInfo(localTarget.Cell, mapParent.Map);
|
||||
flyOverConfig.targetCell = localTarget.Cell;
|
||||
flyOverConfig.targetMap = mapParent.Map;
|
||||
|
||||
// 自动计算飞越路径
|
||||
CalculateFlyOverPath(mapParent.Map, localTarget.Cell);
|
||||
},
|
||||
null, onFinished, CallFlyOverTex, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 空地目标,生成临时地图
|
||||
flyOverTarget = target;
|
||||
flyOverConfig.targetTile = target.Tile;
|
||||
CalculateFlyOverPathForTile(target.Tile);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void CalculateFlyOverPath(Map targetMap, IntVec3 targetCell)
|
||||
{
|
||||
// 计算从地图边缘到目标点的飞越路径
|
||||
Vector3 targetPos = targetCell.ToVector3();
|
||||
|
||||
// 随机选择进入方向
|
||||
Vector3[] approachDirections = {
|
||||
new Vector3(1, 0, 0), // 从右边进入
|
||||
new Vector3(-1, 0, 0), // 从左边进入
|
||||
new Vector3(0, 0, 1), // 从上边进入
|
||||
new Vector3(0, 0, -1) // 从下边进入
|
||||
};
|
||||
|
||||
Vector3 approachDir = approachDirections.RandomElement();
|
||||
Vector3 startPos = FindMapEdgePosition(targetMap, approachDir);
|
||||
Vector3 endPos = FindMapEdgePosition(targetMap, -approachDir); // 从对面飞出
|
||||
|
||||
flyOverConfig.startPos = startPos.ToIntVec3();
|
||||
flyOverConfig.endPos = endPos.ToIntVec3();
|
||||
flyOverConfig.approachType = FlyOverApproachType.StraightLine;
|
||||
|
||||
Log.Message($"Calculated flyover path: {flyOverConfig.startPos} -> {targetCell} -> {flyOverConfig.endPos}");
|
||||
}
|
||||
|
||||
private void CalculateFlyOverPathForTile(int tile)
|
||||
{
|
||||
// 为地图瓦片计算默认飞越路径(穿越地图中心)
|
||||
Map targetMap = GetOrGenerateMapUtility.GetOrGenerateMap(tile, Find.World.info.initialMapSize, null);
|
||||
if (targetMap != null)
|
||||
{
|
||||
targetMap.fogGrid.ClearAllFog(); // 获得视野
|
||||
|
||||
IntVec3 center = targetMap.Center;
|
||||
CalculateFlyOverPath(targetMap, center);
|
||||
}
|
||||
}
|
||||
|
||||
private IntVec3 FindMapEdgePosition(Map map, Vector3 direction)
|
||||
{
|
||||
// 找到地图边缘位置
|
||||
Vector3 center = map.Center.ToVector3();
|
||||
Vector3 edgePos = center;
|
||||
float maxDistance = Mathf.Max(map.Size.x, map.Size.z) * 0.6f;
|
||||
|
||||
for (int i = 1; i <= maxDistance; i++)
|
||||
{
|
||||
Vector3 testPos = center + direction.normalized * i;
|
||||
IntVec3 testCell = new IntVec3((int)testPos.x, 0, (int)testPos.z);
|
||||
|
||||
if (!testCell.InBounds(map))
|
||||
{
|
||||
// 找到最近的边界内单元格
|
||||
return FindClosestValidPosition(testCell, map);
|
||||
}
|
||||
}
|
||||
|
||||
return map.Center;
|
||||
}
|
||||
|
||||
private IntVec3 FindClosestValidPosition(IntVec3 invalidPos, Map map)
|
||||
{
|
||||
for (int radius = 1; radius <= 10; radius++)
|
||||
{
|
||||
foreach (IntVec3 offset in GenRadial.RadialPatternInRadius(radius))
|
||||
{
|
||||
IntVec3 testPos = invalidPos + offset;
|
||||
if (testPos.InBounds(map))
|
||||
return testPos;
|
||||
}
|
||||
}
|
||||
return map.Center;
|
||||
}
|
||||
|
||||
private void OpenConfigurationDialog()
|
||||
{
|
||||
// 打开飞越配置对话框
|
||||
List<FloatMenuOption> options = new List<FloatMenuOption>
|
||||
{
|
||||
new FloatMenuOption("标准侦察飞越", () => ConfigureStandardRecon()),
|
||||
new FloatMenuOption("地面扫射飞越", () => ConfigureGroundStrafing()),
|
||||
new FloatMenuOption("监视巡逻飞越", () => ConfigureSurveillance()),
|
||||
new FloatMenuOption("货运投送飞越", () => ConfigureCargoDrop())
|
||||
};
|
||||
|
||||
Find.WindowStack.Add(new FloatMenu(options));
|
||||
}
|
||||
|
||||
private void ConfigureStandardRecon()
|
||||
{
|
||||
flyOverConfig.flyOverType = FlyOverType.Standard;
|
||||
flyOverConfig.flyOverDef = DefDatabase<ThingDef>.GetNamedSilentFail("ARA_HiveScout");
|
||||
flyOverConfig.altitude = 20f;
|
||||
flyOverConfig.flightSpeed = 1.2f;
|
||||
Messages.Message("已配置为标准侦察飞越", MessageTypeDefOf.TaskCompletion);
|
||||
}
|
||||
|
||||
private void ConfigureGroundStrafing()
|
||||
{
|
||||
flyOverConfig.flyOverType = FlyOverType.GroundStrafing;
|
||||
flyOverConfig.flyOverDef = DefDatabase<ThingDef>.GetNamedSilentFail("ARA_HiveGunship");
|
||||
flyOverConfig.altitude = 10f;
|
||||
flyOverConfig.flightSpeed = 0.8f;
|
||||
flyOverConfig.enableStrafing = true;
|
||||
Messages.Message("已配置为地面扫射飞越", MessageTypeDefOf.TaskCompletion);
|
||||
}
|
||||
|
||||
private void ConfigureSurveillance()
|
||||
{
|
||||
flyOverConfig.flyOverType = FlyOverType.Surveillance;
|
||||
flyOverConfig.flyOverDef = DefDatabase<ThingDef>.GetNamedSilentFail("ARA_HiveObserver");
|
||||
flyOverConfig.altitude = 25f;
|
||||
flyOverConfig.flightSpeed = 0.6f;
|
||||
flyOverConfig.enableSurveillance = true;
|
||||
Messages.Message("已配置为监视巡逻飞越", MessageTypeDefOf.TaskCompletion);
|
||||
}
|
||||
|
||||
private void ConfigureCargoDrop()
|
||||
{
|
||||
flyOverConfig.flyOverType = FlyOverType.CargoDrop;
|
||||
flyOverConfig.flyOverDef = DefDatabase<ThingDef>.GetNamedSilentFail("ARA_HiveTransport");
|
||||
flyOverConfig.altitude = 15f;
|
||||
flyOverConfig.flightSpeed = 1.0f;
|
||||
flyOverConfig.dropContentsOnImpact = true;
|
||||
Messages.Message("已配置为货运投送飞越", MessageTypeDefOf.TaskCompletion);
|
||||
}
|
||||
|
||||
public void ExecuteFlyOverMission()
|
||||
{
|
||||
if (!IsReady) return;
|
||||
|
||||
try
|
||||
{
|
||||
Log.Message($"[FlyOverBeacon] Executing flyover mission to {flyOverTarget.Label}");
|
||||
|
||||
// 创建世界飞越载体
|
||||
WorldObject_FlyOverCarrier carrier = (WorldObject_FlyOverCarrier)WorldObjectMaker.MakeWorldObject(
|
||||
DefDatabase<WorldObjectDef>.GetNamed("FlyOverCarrier")
|
||||
);
|
||||
|
||||
carrier.Tile = this.Map.Tile;
|
||||
carrier.destinationTile = flyOverTarget.Tile;
|
||||
carrier.flyOverConfig = flyOverConfig.Clone();
|
||||
carrier.sourceBeacon = this;
|
||||
|
||||
Find.WorldObjects.Add(carrier);
|
||||
|
||||
// 本地视觉效果
|
||||
CreateLocalLaunchEffects();
|
||||
|
||||
// 资源消耗
|
||||
if (refuelableComp != null)
|
||||
refuelableComp.ConsumeFuel(1);
|
||||
|
||||
// 进入冷却
|
||||
cooldownTicksLeft = 6000; // 1分钟冷却
|
||||
|
||||
Messages.Message($"飞越单位已派遣至 {flyOverTarget.Label}", MessageTypeDefOf.PositiveEvent);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"Error executing flyover mission: {ex}");
|
||||
Messages.Message("飞越任务执行失败", MessageTypeDefOf.NegativeEvent);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateLocalLaunchEffects()
|
||||
{
|
||||
// 发射视觉效果
|
||||
MoteMaker.MakeStaticMote(this.DrawPos, this.Map, ThingDefOf.Mote_ExplosionFlash, 3f);
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
FleckMaker.ThrowSmoke(this.DrawPos, this.Map, 2f);
|
||||
FleckMaker.ThrowLightningGlow(this.DrawPos, this.Map, 1.5f);
|
||||
}
|
||||
|
||||
// 发射音效
|
||||
SoundDefOf.PsychicPulseGlobal.PlayOneShot(new TargetInfo(this.Position, this.Map));
|
||||
}
|
||||
}
|
||||
|
||||
// 飞越配置类
|
||||
public class FlyOverConfig : IExposable
|
||||
{
|
||||
public ThingDef flyOverDef;
|
||||
public FlyOverType flyOverType = FlyOverType.Standard;
|
||||
public IntVec3 startPos;
|
||||
public IntVec3 endPos;
|
||||
public IntVec3 targetCell;
|
||||
public Map targetMap;
|
||||
public int targetTile = -1;
|
||||
public float flightSpeed = 1f;
|
||||
public float altitude = 15f;
|
||||
public bool dropContentsOnImpact = false;
|
||||
public bool enableStrafing = false;
|
||||
public bool enableSurveillance = false;
|
||||
public FlyOverApproachType approachType = FlyOverApproachType.StraightLine;
|
||||
|
||||
public void ExposeData()
|
||||
{
|
||||
Scribe_Defs.Look(ref flyOverDef, "flyOverDef");
|
||||
Scribe_Values.Look(ref flyOverType, "flyOverType", FlyOverType.Standard);
|
||||
Scribe_Values.Look(ref startPos, "startPos");
|
||||
Scribe_Values.Look(ref endPos, "endPos");
|
||||
Scribe_Values.Look(ref targetCell, "targetCell");
|
||||
Scribe_References.Look(ref targetMap, "targetMap");
|
||||
Scribe_Values.Look(ref targetTile, "targetTile", -1);
|
||||
Scribe_Values.Look(ref flightSpeed, "flightSpeed", 1f);
|
||||
Scribe_Values.Look(ref altitude, "altitude", 15f);
|
||||
Scribe_Values.Look(ref dropContentsOnImpact, "dropContentsOnImpact", false);
|
||||
Scribe_Values.Look(ref enableStrafing, "enableStrafing", false);
|
||||
Scribe_Values.Look(ref enableSurveillance, "enableSurveillance", false);
|
||||
Scribe_Values.Look(ref approachType, "approachType", FlyOverApproachType.StraightLine);
|
||||
}
|
||||
|
||||
public FlyOverConfig Clone()
|
||||
{
|
||||
return new FlyOverConfig
|
||||
{
|
||||
flyOverDef = this.flyOverDef,
|
||||
flyOverType = this.flyOverType,
|
||||
startPos = this.startPos,
|
||||
endPos = this.endPos,
|
||||
targetCell = this.targetCell,
|
||||
targetMap = this.targetMap,
|
||||
targetTile = this.targetTile,
|
||||
flightSpeed = this.flightSpeed,
|
||||
altitude = this.altitude,
|
||||
dropContentsOnImpact = this.dropContentsOnImpact,
|
||||
enableStrafing = this.enableStrafing,
|
||||
enableSurveillance = this.enableSurveillance,
|
||||
approachType = this.approachType
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public enum FlyOverType
|
||||
{
|
||||
Standard,
|
||||
GroundStrafing,
|
||||
Surveillance,
|
||||
CargoDrop
|
||||
}
|
||||
|
||||
public enum FlyOverApproachType
|
||||
{
|
||||
StraightLine,
|
||||
CirclePattern,
|
||||
FigureEight
|
||||
}
|
||||
}
|
||||
@@ -1,241 +0,0 @@
|
||||
using RimWorld.Planet;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WulaFallenEmpire
|
||||
{
|
||||
public class WorldObject_FlyOverCarrier : WorldObject
|
||||
{
|
||||
public int destinationTile = -1;
|
||||
public FlyOverConfig flyOverConfig;
|
||||
public Building_FlyOverBeacon sourceBeacon;
|
||||
|
||||
private int initialTile = -1;
|
||||
private float traveledPct;
|
||||
private const float TravelSpeed = 0.0001f; // 比导弹慢,适合侦察
|
||||
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
Scribe_Values.Look(ref destinationTile, "destinationTile", -1);
|
||||
Scribe_Deep.Look(ref flyOverConfig, "flyOverConfig");
|
||||
Scribe_References.Look(ref sourceBeacon, "sourceBeacon");
|
||||
Scribe_Values.Look(ref initialTile, "initialTile", -1);
|
||||
Scribe_Values.Look(ref traveledPct, "traveledPct", 0f);
|
||||
}
|
||||
|
||||
public override void PostAdd()
|
||||
{
|
||||
base.PostAdd();
|
||||
this.initialTile = this.Tile;
|
||||
Log.Message($"[FlyOverCarrier] Launched from tile {initialTile} to {destinationTile}");
|
||||
}
|
||||
|
||||
private Vector3 StartPos => Find.WorldGrid.GetTileCenter(this.initialTile);
|
||||
private Vector3 EndPos => Find.WorldGrid.GetTileCenter(this.destinationTile);
|
||||
|
||||
public override Vector3 DrawPos => Vector3.Slerp(StartPos, EndPos, traveledPct);
|
||||
|
||||
protected override void Tick()
|
||||
{
|
||||
base.Tick();
|
||||
|
||||
if (this.destinationTile < 0)
|
||||
{
|
||||
Log.Error("FlyOverCarrier has invalid destination tile");
|
||||
Find.WorldObjects.Remove(this);
|
||||
return;
|
||||
}
|
||||
|
||||
float distance = GenMath.SphericalDistance(StartPos.normalized, EndPos.normalized);
|
||||
if (distance > 0)
|
||||
{
|
||||
traveledPct += TravelSpeed / distance;
|
||||
}
|
||||
else
|
||||
{
|
||||
traveledPct = 1;
|
||||
}
|
||||
|
||||
// 更新世界图标位置
|
||||
if (Find.WorldRenderer != null)
|
||||
{
|
||||
Find.WorldRenderer.Notify_WorldObjectPosChanged(this);
|
||||
}
|
||||
|
||||
if (traveledPct >= 1f)
|
||||
{
|
||||
Arrived();
|
||||
}
|
||||
}
|
||||
|
||||
private void Arrived()
|
||||
{
|
||||
Log.Message($"[FlyOverCarrier] Arrived at destination tile {destinationTile}");
|
||||
|
||||
Map targetMap = GetTargetMap();
|
||||
if (targetMap != null)
|
||||
{
|
||||
CreateFlyOverInTargetMap(targetMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning($"[FlyOverCarrier] Could not find or generate map for tile {destinationTile}");
|
||||
}
|
||||
|
||||
// 通知源信标任务完成
|
||||
if (sourceBeacon != null && !sourceBeacon.Destroyed)
|
||||
{
|
||||
Messages.Message($"飞越单位已到达 {flyOverConfig.targetMap?.Parent?.Label ?? "目标区域"}",
|
||||
sourceBeacon, MessageTypeDefOf.PositiveEvent);
|
||||
}
|
||||
|
||||
Find.WorldObjects.Remove(this);
|
||||
}
|
||||
|
||||
private Map GetTargetMap()
|
||||
{
|
||||
// 优先使用配置中的目标地图
|
||||
if (flyOverConfig.targetMap != null && !flyOverConfig.targetMap.Destroyed)
|
||||
{
|
||||
return flyOverConfig.targetMap;
|
||||
}
|
||||
|
||||
// 生成临时地图
|
||||
return GetOrGenerateMapUtility.GetOrGenerateMap(destinationTile, Find.World.info.initialMapSize, null);
|
||||
}
|
||||
|
||||
private void CreateFlyOverInTargetMap(Map targetMap)
|
||||
{
|
||||
if (flyOverConfig.flyOverDef == null)
|
||||
{
|
||||
Log.Warning("[FlyOverCarrier] No fly over def specified, using default");
|
||||
flyOverConfig.flyOverDef = DefDatabase<ThingDef>.GetNamedSilentFail("ARA_HiveScout");
|
||||
}
|
||||
|
||||
// 确保目标地图有视野
|
||||
targetMap.fogGrid.ClearAllFog();
|
||||
|
||||
// 验证并调整飞越路径
|
||||
IntVec3 startPos = ValidateAndAdjustPosition(flyOverConfig.startPos, targetMap);
|
||||
IntVec3 endPos = ValidateAndAdjustPosition(flyOverConfig.endPos, targetMap);
|
||||
|
||||
Log.Message($"[FlyOverCarrier] Creating flyover: {startPos} -> {endPos} in {targetMap}");
|
||||
|
||||
// 创建飞越物体
|
||||
FlyOver flyOver = FlyOver.MakeFlyOver(
|
||||
flyOverConfig.flyOverDef,
|
||||
startPos,
|
||||
endPos,
|
||||
targetMap,
|
||||
flyOverConfig.flightSpeed,
|
||||
flyOverConfig.altitude,
|
||||
casterPawn: null
|
||||
);
|
||||
|
||||
// 配置飞越属性
|
||||
flyOver.spawnContentsOnImpact = flyOverConfig.dropContentsOnImpact;
|
||||
flyOver.playFlyOverSound = true;
|
||||
flyOver.faction = sourceBeacon?.Faction;
|
||||
|
||||
// 配置特殊组件
|
||||
ConfigureFlyOverComponents(flyOver);
|
||||
|
||||
// 创建到达视觉效果
|
||||
CreateArrivalEffects(targetMap, startPos);
|
||||
}
|
||||
|
||||
private IntVec3 ValidateAndAdjustPosition(IntVec3 pos, Map map)
|
||||
{
|
||||
if (pos.IsValid && pos.InBounds(map))
|
||||
return pos;
|
||||
|
||||
// 如果位置无效,使用地图边缘位置
|
||||
return CellFinder.RandomEdgeCell(Rand.Range(0, 4), map);
|
||||
}
|
||||
|
||||
private void ConfigureFlyOverComponents(FlyOver flyOver)
|
||||
{
|
||||
// 地面扫射配置
|
||||
if (flyOverConfig.enableStrafing)
|
||||
{
|
||||
CompGroundStrafing strafingComp = flyOver.GetComp<CompGroundStrafing>();
|
||||
if (strafingComp != null)
|
||||
{
|
||||
// 计算扫射区域
|
||||
Vector3 flightDirection = (flyOverConfig.endPos.ToVector3() - flyOverConfig.startPos.ToVector3()).normalized;
|
||||
List<IntVec3> impactCells = CalculateStrafingImpactCells(flyOverConfig.targetCell, flightDirection);
|
||||
List<IntVec3> confirmedTargets = PreprocessStrafingTargets(impactCells, 0.7f);
|
||||
|
||||
strafingComp.SetConfirmedTargets(confirmedTargets);
|
||||
}
|
||||
}
|
||||
|
||||
// 监视功能配置
|
||||
if (flyOverConfig.enableSurveillance)
|
||||
{
|
||||
// 可以在这里添加监视组件的配置
|
||||
Log.Message("[FlyOverCarrier] Surveillance mode configured");
|
||||
}
|
||||
}
|
||||
|
||||
private List<IntVec3> CalculateStrafingImpactCells(IntVec3 targetCell, Vector3 flightDirection)
|
||||
{
|
||||
// 简化的扫射区域计算
|
||||
List<IntVec3> cells = new List<IntVec3>();
|
||||
Map map = Find.CurrentMap;
|
||||
|
||||
if (map != null)
|
||||
{
|
||||
Vector3 perpendicular = new Vector3(-flightDirection.z, 0f, flightDirection.x).normalized;
|
||||
|
||||
for (int i = -2; i <= 2; i++)
|
||||
{
|
||||
for (int j = -5; j <= 5; j++)
|
||||
{
|
||||
Vector3 offset = perpendicular * i + flightDirection * j;
|
||||
IntVec3 cell = targetCell + new IntVec3((int)offset.x, 0, (int)offset.z);
|
||||
|
||||
if (cell.InBounds(map))
|
||||
{
|
||||
cells.Add(cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cells;
|
||||
}
|
||||
|
||||
private List<IntVec3> PreprocessStrafingTargets(List<IntVec3> potentialTargets, float fireChance)
|
||||
{
|
||||
List<IntVec3> confirmedTargets = new List<IntVec3>();
|
||||
|
||||
foreach (IntVec3 cell in potentialTargets)
|
||||
{
|
||||
if (Rand.Value <= fireChance)
|
||||
{
|
||||
confirmedTargets.Add(cell);
|
||||
}
|
||||
}
|
||||
|
||||
return confirmedTargets;
|
||||
}
|
||||
|
||||
private void CreateArrivalEffects(Map targetMap, IntVec3 entryPos)
|
||||
{
|
||||
// 进入视觉效果
|
||||
MoteMaker.MakeStaticMote(entryPos.ToVector3Shifted(), targetMap, ThingDefOf.Mote_PsycastAreaEffect, 2f);
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
FleckMaker.ThrowAirPuffUp(entryPos.ToVector3Shifted(), targetMap);
|
||||
}
|
||||
|
||||
// 进入音效
|
||||
SoundDefOf.PsychicPulse.PlayOneShot(new TargetInfo(entryPos, targetMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
71
Source/WulaFallenEmpire/Pawn/Comp_MultiTurretGun.cs
Normal file
71
Source/WulaFallenEmpire/Pawn/Comp_MultiTurretGun.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
using RimWorld;
|
||||
using UnityEngine;
|
||||
|
||||
namespace WulaFallenEmpire
|
||||
{
|
||||
public class CompProperties_MultiTurretGun : CompProperties_TurretGun
|
||||
{
|
||||
public int ID;
|
||||
public CompProperties_MultiTurretGun()
|
||||
{
|
||||
compClass = typeof(Comp_MultiTurretGun);
|
||||
}
|
||||
}
|
||||
public class Comp_MultiTurretGun : CompTurretGun
|
||||
{
|
||||
private bool fireAtWill = true;
|
||||
public new CompProperties_MultiTurretGun Props => (CompProperties_MultiTurretGun)props;
|
||||
public override void CompTick()
|
||||
{
|
||||
base.CompTick();
|
||||
if (!currentTarget.IsValid && burstCooldownTicksLeft <= 0)
|
||||
{
|
||||
// 在其他情况下没有目标且冷却结束时也回正
|
||||
curRotation = parent.Rotation.AsAngle + Props.angleOffset;
|
||||
}
|
||||
}
|
||||
private void MakeGun()
|
||||
{
|
||||
gun = ThingMaker.MakeThing(Props.turretDef);
|
||||
UpdateGunVerbs();
|
||||
}
|
||||
private void UpdateGunVerbs()
|
||||
{
|
||||
List<Verb> allVerbs = gun.TryGetComp<CompEquippable>().AllVerbs;
|
||||
for (int i = 0; i < allVerbs.Count; i++)
|
||||
{
|
||||
Verb verb = allVerbs[i];
|
||||
verb.caster = parent;
|
||||
verb.castCompleteCallback = delegate
|
||||
{
|
||||
burstCooldownTicksLeft = AttackVerb.verbProps.defaultCooldownTime.SecondsToTicks();
|
||||
};
|
||||
}
|
||||
}
|
||||
public override void PostExposeData()
|
||||
{
|
||||
Scribe_Values.Look(ref burstCooldownTicksLeft, "burstCooldownTicksLeft", 0);
|
||||
Scribe_Values.Look(ref burstWarmupTicksLeft, "burstWarmupTicksLeft", 0);
|
||||
Scribe_TargetInfo.Look(ref currentTarget, "currentTarget_" + Props.ID);
|
||||
Scribe_Deep.Look(ref gun, "gun_" + Props.ID);
|
||||
Scribe_Values.Look(ref fireAtWill, "fireAtWill", defaultValue: true);
|
||||
if (Scribe.mode == LoadSaveMode.PostLoadInit)
|
||||
{
|
||||
if (gun == null)
|
||||
{
|
||||
Log.Error("CompTurrentGun had null gun after loading. Recreating.");
|
||||
MakeGun();
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateGunVerbs();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
128
Source/WulaFallenEmpire/Pawn/Comp_PawnRenderExtra.cs
Normal file
128
Source/WulaFallenEmpire/Pawn/Comp_PawnRenderExtra.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using System.Reflection.Emit;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using RimWorld;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
namespace WulaFallenEmpire
|
||||
{
|
||||
public class CompProperties_PawnRenderExtra : CompProperties
|
||||
{
|
||||
public CompProperties_PawnRenderExtra()
|
||||
{
|
||||
this.compClass = typeof(Comp_PawnRenderExtra);
|
||||
}
|
||||
|
||||
public string path;
|
||||
|
||||
public Vector3 size;
|
||||
|
||||
public Color colorAlly;
|
||||
|
||||
public Color colorEnemy;
|
||||
|
||||
public ShaderTypeDef shader;
|
||||
|
||||
public DrawData drawData;
|
||||
}
|
||||
[StaticConstructorOnStartup]
|
||||
public class Comp_PawnRenderExtra : ThingComp
|
||||
{
|
||||
public CompProperties_PawnRenderExtra Props
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.props as CompProperties_PawnRenderExtra;
|
||||
}
|
||||
}
|
||||
|
||||
private Pawn ParentPawn
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.parent as Pawn;
|
||||
}
|
||||
}
|
||||
|
||||
public override void PostDraw()
|
||||
{
|
||||
base.PostDraw();
|
||||
if (!this.ParentPawn.Dead && !this.ParentPawn.Downed && this.ParentPawn.CurJobDef != JobDefOf.MechCharge && this.ParentPawn.CurJobDef != JobDefOf.SelfShutdown)
|
||||
{
|
||||
this.DrawPawnRenderExtra();
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawPawnRenderExtra()
|
||||
{
|
||||
Vector3 pos = this.ParentPawn.DrawPos;
|
||||
if (this.ParentPawn.Faction == Faction.OfPlayer || !this.ParentPawn.Faction.HostileTo(Faction.OfPlayer))
|
||||
{
|
||||
this.color = this.Props.colorAlly;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.color = this.Props.colorEnemy;
|
||||
}
|
||||
string graphic = this.GetPawnRenderExtra();
|
||||
Vector3 offset = GetOffsetByRot();
|
||||
float layer = GetLayerByRot();
|
||||
pos.y = AltitudeLayer.Pawn.AltitudeFor(layer);
|
||||
|
||||
Matrix4x4 matrix = default(Matrix4x4);
|
||||
matrix.SetTRS(pos + offset, Quaternion.AngleAxis(0f, Vector3.up), this.Props.size);
|
||||
Material material = MaterialPool.MatFrom(graphic, this.Props.shader.Shader, this.color);
|
||||
Graphics.DrawMesh(MeshPool.plane10, matrix, material, (int)layer);
|
||||
}
|
||||
|
||||
public Vector3 GetOffsetByRot()
|
||||
{
|
||||
Vector3 result;
|
||||
if (this.Props.drawData != null)
|
||||
{
|
||||
result = this.Props.drawData.OffsetForRot(this.ParentPawn.Rotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = Vector3.zero;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public float GetLayerByRot()
|
||||
{
|
||||
float result;
|
||||
if (this.Props.drawData != null)
|
||||
{
|
||||
result = this.Props.drawData.LayerForRot(this.ParentPawn.Rotation, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public string GetPawnRenderExtra()
|
||||
{
|
||||
if (this.ParentPawn.Rotation.AsInt == 0)
|
||||
{
|
||||
return this.Props.path + "_north";
|
||||
}
|
||||
if (this.ParentPawn.Rotation.AsInt == 1)
|
||||
{
|
||||
return this.Props.path + "_east";
|
||||
}
|
||||
if (this.ParentPawn.Rotation.AsInt == 2)
|
||||
{
|
||||
return this.Props.path + "_south";
|
||||
}
|
||||
if (this.ParentPawn.Rotation.AsInt == 3)
|
||||
{
|
||||
return this.Props.path + "_west";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Color color;
|
||||
}
|
||||
}
|
||||
@@ -90,8 +90,6 @@
|
||||
<Compile Include="BuildingComp\Building_TurretGunHasSpeed.cs" />
|
||||
<Compile Include="BuildingComp\WULA_EnergyLanceTurret\CompEnergyLanceTurret.cs" />
|
||||
<Compile Include="BuildingComp\WULA_EnergyLanceTurret\CompProperties_EnergyLanceTurret.cs" />
|
||||
<Compile Include="BuildingComp\WULA_FlyOverBeacon\Building_FlyOverBeacon.cs" />
|
||||
<Compile Include="BuildingComp\WULA_FlyOverBeacon\WorldObject_FlyOverCarrier.cs" />
|
||||
<Compile Include="BuildingComp\WULA_InitialFaction\CompProperties_InitialFaction.cs" />
|
||||
<Compile Include="BuildingComp\WULA_MechanoidRecycler\Building_MechanoidRecycler.cs" />
|
||||
<Compile Include="BuildingComp\WULA_MechanoidRecycler\CompProperties_MechanoidRecycler.cs" />
|
||||
@@ -149,6 +147,8 @@
|
||||
<Compile Include="HediffComp\HediffCompProperties_SwitchableHediff.cs" />
|
||||
<Compile Include="HediffComp\WULA_HediffDamgeShield\DRMDamageShield.cs" />
|
||||
<Compile Include="HediffComp\WULA_HediffDamgeShield\Hediff_DamageShield.cs" />
|
||||
<Compile Include="Pawn\Comp_MultiTurretGun.cs" />
|
||||
<Compile Include="Pawn\Comp_PawnRenderExtra.cs" />
|
||||
<Compile Include="Pawn\WULA_AutoMechCarrier\CompAutoMechCarrier.cs" />
|
||||
<Compile Include="Pawn\WULA_AutoMechCarrier\CompProperties_AutoMechCarrier.cs" />
|
||||
<Compile Include="Pawn\WULA_AutoMechCarrier\PawnProductionEntry.cs" />
|
||||
@@ -280,7 +280,9 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Verb\Verb_Excalibur\Thing_ExcaliburBeam.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<Folder Include="BuildingComp\WULA_FlyOverBeacon\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- 自定义清理任务,删除obj文件夹中的临时文件 -->
|
||||
<Target Name="CleanDebugFiles" AfterTargets="Build">
|
||||
|
||||
Reference in New Issue
Block a user