暂存
This commit is contained in:
Binary file not shown.
@@ -21,7 +21,7 @@
|
|||||||
<verbProperties>
|
<verbProperties>
|
||||||
<verbClass>Verb_CastAbility</verbClass>
|
<verbClass>Verb_CastAbility</verbClass>
|
||||||
<warmupTime>2</warmupTime>
|
<warmupTime>2</warmupTime>
|
||||||
<range>-1</range>
|
<range>80</range><!-- 害人啊没了范围我怎么标记虫虫,另外泰南把最大渲染圈加到80了Increased max radius of GenRadial to 80 and optimize radius calculations.-->
|
||||||
<drawAimPie>true</drawAimPie>
|
<drawAimPie>true</drawAimPie>
|
||||||
<requireLineOfSight>true</requireLineOfSight>
|
<requireLineOfSight>true</requireLineOfSight>
|
||||||
<nonInterruptingSelfCast>true</nonInterruptingSelfCast>
|
<nonInterruptingSelfCast>true</nonInterruptingSelfCast>
|
||||||
|
|||||||
@@ -498,6 +498,24 @@
|
|||||||
<milkIntervalDays>1</milkIntervalDays>
|
<milkIntervalDays>1</milkIntervalDays>
|
||||||
<milkAmount>14</milkAmount>
|
<milkAmount>14</milkAmount>
|
||||||
</li>
|
</li>
|
||||||
|
<li Class="ArachnaeSwarm.CompProperties_AutoMechCarrier">
|
||||||
|
<freeProduction>true</freeProduction>
|
||||||
|
<!--<disableHediff>WULA_MechCarrierSwitchHediff</disableHediff>-->
|
||||||
|
<fixedIngredient>ARA_InsectJelly</fixedIngredient>
|
||||||
|
<maxIngredientCount>500</maxIngredientCount>
|
||||||
|
<startingIngredientCount>500</startingIngredientCount>
|
||||||
|
<costPerPawn>999</costPerPawn>
|
||||||
|
<cooldownTicks>9999</cooldownTicks>
|
||||||
|
<productionQueue>
|
||||||
|
<li>
|
||||||
|
<pawnKind>Spelopede</pawnKind>
|
||||||
|
<count>3</count>
|
||||||
|
<cooldownTicks>600</cooldownTicks>
|
||||||
|
</li>
|
||||||
|
</productionQueue>
|
||||||
|
<spawnEffecter>CocoonDestroyed</spawnEffecter>
|
||||||
|
<!--<spawnedMechEffecter>WarUrchinSpawned</spawnedMechEffecter>-->
|
||||||
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
|
|
||||||
<!-- 基础属性设置 -->
|
<!-- 基础属性设置 -->
|
||||||
|
|||||||
@@ -497,233 +497,4 @@
|
|||||||
<li>AteWithoutTable</li>
|
<li>AteWithoutTable</li>
|
||||||
<li>SleptOutside</li>
|
<li>SleptOutside</li>
|
||||||
<li>SleptOnGround</li>
|
<li>SleptOnGround</li>
|
||||||
<li>SleptInCold</li>
|
<li>SleptInCold</li>
|
||||||
<li>SleptInHeat</li>
|
|
||||||
<li>Ugly</li>
|
|
||||||
<li>AteKibble</li>
|
|
||||||
<li>AteInsectMeatDirect</li>
|
|
||||||
<li>AteInsectMeatAsIngredient</li>
|
|
||||||
<li>AteRawFood</li>
|
|
||||||
<li>AteHumanlikeMeatDirect</li>
|
|
||||||
<li>AteHumanlikeMeatAsIngredient</li>
|
|
||||||
<li>KnowButcheredHumanlikeCorpse</li>
|
|
||||||
<li>ButcheredHumanlikeCorpseOpinion</li>
|
|
||||||
<li>AteRawHumanlikeMeat</li>
|
|
||||||
</cannotReceiveThoughts>
|
|
||||||
<!-- 该种族特有想法 -->
|
|
||||||
<restrictedThoughts>
|
|
||||||
</restrictedThoughts>
|
|
||||||
</thoughtSettings>
|
|
||||||
<!-- 关系设置,不会生成任何随机关系 -->
|
|
||||||
<relationSettings>
|
|
||||||
<relationChanceModifierLover>0</relationChanceModifierLover>
|
|
||||||
<relationChanceModifierExLover>0</relationChanceModifierExLover>
|
|
||||||
|
|
||||||
<relationChanceModifierFiance>0</relationChanceModifierFiance>
|
|
||||||
<relationChanceModifierSpouse>0</relationChanceModifierSpouse>
|
|
||||||
<relationChanceModifierExSpouse>0</relationChanceModifierExSpouse>
|
|
||||||
|
|
||||||
<relationChanceModifierParent>0</relationChanceModifierParent>
|
|
||||||
<relationChanceModifierChild>0</relationChanceModifierChild>
|
|
||||||
<relationChanceModifierSibling>0</relationChanceModifierSibling>
|
|
||||||
</relationSettings>
|
|
||||||
</alienRace>
|
|
||||||
|
|
||||||
<!-- 基础属性设置 -->
|
|
||||||
<statBases>
|
|
||||||
<!-- 市场价值 -->
|
|
||||||
<MarketValue>2000</MarketValue>
|
|
||||||
<RoyalFavorValue>5</RoyalFavorValue>
|
|
||||||
|
|
||||||
<!-- 移动速度 -->
|
|
||||||
<MoveSpeed>1.75</MoveSpeed>
|
|
||||||
<Mass>250</Mass>
|
|
||||||
|
|
||||||
<!-- <RestRateMultiplier>1</RestRateMultiplier> -->
|
|
||||||
<!-- <HungerRateMultiplier>1</HungerRateMultiplier> -->
|
|
||||||
<EatingSpeed>2</EatingSpeed>
|
|
||||||
<!-- 女皇很长时间才需要补充一次食物 -->
|
|
||||||
<MaxNutrition>0.5</MaxNutrition>
|
|
||||||
|
|
||||||
<!-- 女皇的负重,设为0以避免女皇能背东西 -->
|
|
||||||
<CarryingCapacity>0</CarryingCapacity>
|
|
||||||
<MeatAmount>450</MeatAmount>
|
|
||||||
<LeatherAmount>600</LeatherAmount>
|
|
||||||
|
|
||||||
<!-- 疼痛休克,女皇很难因为疼痛而倒下,虽并不是像机器人一样不会休克 -->
|
|
||||||
<PainShockThreshold>1</PainShockThreshold>
|
|
||||||
<!-- 女皇非常擅长灵能,以维持蜂群的蜂巢意识链接 -->
|
|
||||||
<PsychicSensitivity>5</PsychicSensitivity>
|
|
||||||
<!-- 女皇的崩溃概率 -->
|
|
||||||
<MentalBreakThreshold>0</MentalBreakThreshold>
|
|
||||||
<!-- 女皇的高耸身躯和强健循环系统使得很难被毒倒下 -->
|
|
||||||
<ToxicResistance>0.95</ToxicResistance>
|
|
||||||
<ToxicEnvironmentResistance MayRequire="Ludeon.RimWorld.Biotech">0.95</ToxicEnvironmentResistance>
|
|
||||||
<!-- 女皇的甲壳可以抵御火焰侵袭,难以燃烧-->
|
|
||||||
<Flammability>0.1</Flammability>
|
|
||||||
|
|
||||||
<!-- 女皇的庞大申请很难闪开近战 -->
|
|
||||||
<MeleeDodgeChance>0.25</MeleeDodgeChance>
|
|
||||||
<!-- <MeleeHitChance>1</MeleeHitChance> -->
|
|
||||||
|
|
||||||
<!-- <NegotiationAbility>1</NegotiationAbility> -->
|
|
||||||
<!-- <SellPriceFactor>1</SellPriceFactor> -->
|
|
||||||
<!-- <SocialImpact>1</SocialImpact> -->
|
|
||||||
<!-- <TradePriceImprovement>0.5</TradePriceImprovement> -->
|
|
||||||
|
|
||||||
<!-- 自带的甲壳可以防御外部攻击 -->
|
|
||||||
<ArmorRating_Blunt>0.6</ArmorRating_Blunt>
|
|
||||||
<ArmorRating_Sharp>0.8</ArmorRating_Sharp>
|
|
||||||
<ArmorRating_Heat>0.5</ArmorRating_Heat>
|
|
||||||
|
|
||||||
<!-- 虫群拥有惊人的愈合速度 -->
|
|
||||||
<InjuryHealingFactor>5</InjuryHealingFactor>
|
|
||||||
|
|
||||||
<!-- 在野外采集的营养 -->
|
|
||||||
<ForagedNutritionPerDay>0</ForagedNutritionPerDay>
|
|
||||||
</statBases>
|
|
||||||
|
|
||||||
<race>
|
|
||||||
<!-- 身体类型 -->
|
|
||||||
<body>ArachnaeQueen_Body</body>
|
|
||||||
<fleshType>Normal</fleshType>
|
|
||||||
<!-- AI行为,勿改 -->
|
|
||||||
<thinkTreeMain>ARA_Humanlike</thinkTreeMain>
|
|
||||||
<!-- 智力水平 -->
|
|
||||||
<intelligence>Humanlike</intelligence>
|
|
||||||
<!-- 肉和皮革的定义 -->
|
|
||||||
<leatherDef>Leather_Light</leatherDef>
|
|
||||||
<specificMeatDef>Meat_Megaspider</specificMeatDef>
|
|
||||||
<nameCategory>HumanStandard</nameCategory>
|
|
||||||
<bloodDef>Filth_BloodInsect</bloodDef>
|
|
||||||
<bloodSmearDef>Filth_BloodSmear</bloodSmearDef>
|
|
||||||
<!-- 身形大小 -->
|
|
||||||
<baseBodySize>10</baseBodySize>
|
|
||||||
<!-- 基础血量,很高 -->
|
|
||||||
<baseHealthScale>10</baseHealthScale>
|
|
||||||
<!-- 解剖产物 -->
|
|
||||||
<leatherDef>Steel</leatherDef>
|
|
||||||
<specificMeatDef>Steel</specificMeatDef>
|
|
||||||
|
|
||||||
<soundMeleeHitPawn>Pawn_Melee_BigBash_HitPawn</soundMeleeHitPawn>
|
|
||||||
<soundMeleeHitBuilding>Pawn_Melee_BigBash_HitBuilding</soundMeleeHitBuilding>
|
|
||||||
<soundMeleeMiss>Pawn_Melee_BigBash_Miss</soundMeleeMiss>
|
|
||||||
<soundMeleeDodge>Pawn_MeleeDodge</soundMeleeDodge>
|
|
||||||
<!-- 年龄阶段 -->
|
|
||||||
<!-- <lifeExpectancy>5000</lifeExpectancy> -->
|
|
||||||
<lifeStageWorkSettings MayRequire="Ludeon.RimWorld.Biotech">
|
|
||||||
<Firefighter>0</Firefighter>
|
|
||||||
<Patient>0</Patient>
|
|
||||||
<Doctor>0</Doctor>
|
|
||||||
<PatientBedRest>0</PatientBedRest>
|
|
||||||
<Childcare MayRequire="Ludeon.RimWorld.Biotech">0</Childcare>
|
|
||||||
<BasicWorker>0</BasicWorker>
|
|
||||||
<Warden>0</Warden>
|
|
||||||
<Handling>0</Handling>
|
|
||||||
<Cooking>0</Cooking>
|
|
||||||
<Hunting>0</Hunting>
|
|
||||||
<Construction>0</Construction>
|
|
||||||
<Growing>0</Growing>
|
|
||||||
<Mining>0</Mining>
|
|
||||||
<PlantCutting>0</PlantCutting>
|
|
||||||
<Smithing>0</Smithing>
|
|
||||||
<Tailoring>0</Tailoring>
|
|
||||||
<Art>0</Art>
|
|
||||||
<Crafting>0</Crafting>
|
|
||||||
<Hauling>0</Hauling>
|
|
||||||
<Cleaning>0</Cleaning>
|
|
||||||
<Research>0</Research>
|
|
||||||
<DarkStudy MayRequire="Ludeon.RimWorld.Anomaly">0</DarkStudy>
|
|
||||||
</lifeStageWorkSettings>
|
|
||||||
<lifeStageAges Inherit="False">
|
|
||||||
<li>
|
|
||||||
<def>ARA_Queen_Adult</def>
|
|
||||||
<minAge>0</minAge>
|
|
||||||
<soundWounded>Pawn_HiveQueen_Wounded</soundWounded>
|
|
||||||
<soundDeath>Pawn_HiveQueen_Death</soundDeath>
|
|
||||||
<soundCall>Pawn_HiveQueen_Call</soundCall>
|
|
||||||
<soundAngry>Pawn_HiveQueen_Angry</soundAngry>
|
|
||||||
</li>
|
|
||||||
</lifeStageAges>
|
|
||||||
<canFlyInVacuum>false</canFlyInVacuum>
|
|
||||||
|
|
||||||
</race>
|
|
||||||
|
|
||||||
<!-- 工具设置(攻击方式) -->
|
|
||||||
<tools>
|
|
||||||
<li>
|
|
||||||
<label>头顶</label>
|
|
||||||
<capacities>
|
|
||||||
<li>Poke</li>
|
|
||||||
</capacities>
|
|
||||||
<power>16</power>
|
|
||||||
<cooldownTime>2</cooldownTime>
|
|
||||||
<linkedBodyPartsGroup>HeadAttackTool</linkedBodyPartsGroup>
|
|
||||||
<ensureLinkedBodyPartsGroupAlwaysUsable>true</ensureLinkedBodyPartsGroupAlwaysUsable>
|
|
||||||
<chanceFactor>0.01</chanceFactor>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<label>踩踏</label>
|
|
||||||
<capacities>
|
|
||||||
<li>Blunt</li>
|
|
||||||
<li>Poke</li>
|
|
||||||
</capacities>
|
|
||||||
<power>35</power>
|
|
||||||
<cooldownTime>2.5</cooldownTime>
|
|
||||||
<linkedBodyPartsGroup>Legs</linkedBodyPartsGroup>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<label>腿部穿刺</label>
|
|
||||||
<capacities>
|
|
||||||
<li>Stab</li>
|
|
||||||
</capacities>
|
|
||||||
<power>50</power>
|
|
||||||
<cooldownTime>3</cooldownTime>
|
|
||||||
<linkedBodyPartsGroup>Legs</linkedBodyPartsGroup>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<label>钳击</label>
|
|
||||||
<capacities>
|
|
||||||
<li>Cut</li>
|
|
||||||
</capacities>
|
|
||||||
<power>30</power>
|
|
||||||
<cooldownTime>2</cooldownTime>
|
|
||||||
<linkedBodyPartsGroup>Hands</linkedBodyPartsGroup>
|
|
||||||
</li>
|
|
||||||
</tools>
|
|
||||||
|
|
||||||
<recipes Inherit="False">
|
|
||||||
</recipes>
|
|
||||||
|
|
||||||
<comps>
|
|
||||||
<!-- <li MayRequire="Nals.FacialAnimation">
|
|
||||||
<compClass>FacialAnimation.DrawFaceGraphicsComp</compClass>
|
|
||||||
</li>
|
|
||||||
<li MayRequire="Nals.FacialAnimation">
|
|
||||||
<compClass>FacialAnimation.HeadControllerComp</compClass>
|
|
||||||
</li>
|
|
||||||
<li MayRequire="Nals.FacialAnimation">
|
|
||||||
<compClass>FacialAnimation.EyeballControllerComp</compClass>
|
|
||||||
</li>
|
|
||||||
<li MayRequire="Nals.FacialAnimation">
|
|
||||||
<compClass>FacialAnimation.LidControllerComp</compClass>
|
|
||||||
</li>
|
|
||||||
<li MayRequire="Nals.FacialAnimation">
|
|
||||||
<compClass>FacialAnimation.BrowControllerComp</compClass>
|
|
||||||
</li>
|
|
||||||
<li MayRequire="Nals.FacialAnimation">
|
|
||||||
<compClass>FacialAnimation.MouthControllerComp</compClass>
|
|
||||||
</li>
|
|
||||||
<li MayRequire="Nals.FacialAnimation">
|
|
||||||
<compClass>FacialAnimation.SkinControllerComp</compClass>
|
|
||||||
</li>
|
|
||||||
<li MayRequire="Nals.FacialAnimation">
|
|
||||||
<compClass>FacialAnimation.FacialAnimationControllerComp</compClass>
|
|
||||||
</li> -->
|
|
||||||
<!--<li>
|
|
||||||
<compClass>FacialAnimation.EmotionControllerComp</compClass>
|
|
||||||
</li>-->
|
|
||||||
<!-- <li Class="CompProperties_DrugAddict"/> -->
|
|
||||||
</comps>
|
|
||||||
</AlienRace.ThingDef_AlienRace>
|
|
||||||
</Defs>
|
|
||||||
@@ -85,7 +85,11 @@
|
|||||||
<Compile Include="CompProperties_AbilityBindDrone.cs" />
|
<Compile Include="CompProperties_AbilityBindDrone.cs" />
|
||||||
<Compile Include="JobGiver_MaintainBuildings.cs" />
|
<Compile Include="JobGiver_MaintainBuildings.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup>
|
||||||
|
<Compile Include="WULA_AutoMechCarrier\CompAutoMechCarrier.cs" />
|
||||||
|
<Compile Include="WULA_AutoMechCarrier\CompProperties_AutoMechCarrier.cs" />
|
||||||
|
<Compile Include="WULA_AutoMechCarrier\PawnProductionEntry.cs" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- 自定义清理任务,删除obj文件夹中的临时文件 -->
|
<!-- 自定义清理任务,删除obj文件夹中的临时文件 -->
|
||||||
<Target Name="CleanDebugFiles" AfterTargets="Build">
|
<Target Name="CleanDebugFiles" AfterTargets="Build">
|
||||||
|
|||||||
195
Source/ArachnaeSwarm/WULA_AutoMechCarrier/CompAutoMechCarrier.cs
Normal file
195
Source/ArachnaeSwarm/WULA_AutoMechCarrier/CompAutoMechCarrier.cs
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
using RimWorld;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using UnityEngine;
|
||||||
|
using Verse;
|
||||||
|
using Verse.AI.Group;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class CompAutoMechCarrier : CompMechCarrier
|
||||||
|
{
|
||||||
|
#region Reflected Fields
|
||||||
|
private static FieldInfo spawnedPawnsField;
|
||||||
|
private static FieldInfo cooldownTicksRemainingField;
|
||||||
|
private static FieldInfo innerContainerField;
|
||||||
|
|
||||||
|
private List<Pawn> SpawnedPawns
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (spawnedPawnsField == null)
|
||||||
|
spawnedPawnsField = typeof(CompMechCarrier).GetField("spawnedPawns", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
return (List<Pawn>)spawnedPawnsField.GetValue(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int CooldownTicksRemaining
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (cooldownTicksRemainingField == null)
|
||||||
|
cooldownTicksRemainingField = typeof(CompMechCarrier).GetField("cooldownTicksRemaining", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
return (int)cooldownTicksRemainingField.GetValue(this);
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (cooldownTicksRemainingField == null)
|
||||||
|
cooldownTicksRemainingField = typeof(CompMechCarrier).GetField("cooldownTicksRemaining", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
cooldownTicksRemainingField.SetValue(this, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ThingOwner InnerContainer
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (innerContainerField == null)
|
||||||
|
innerContainerField = typeof(CompMechCarrier).GetField("innerContainer", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
return (ThingOwner)innerContainerField.GetValue(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public CompProperties_AutoMechCarrier AutoProps => (CompProperties_AutoMechCarrier)props;
|
||||||
|
|
||||||
|
private int TotalPawnCapacity => AutoProps.productionQueue.Sum(e => e.count);
|
||||||
|
|
||||||
|
private int LiveSpawnedPawnsCount(PawnKindDef kind)
|
||||||
|
{
|
||||||
|
SpawnedPawns.RemoveAll(p => p == null || p.Destroyed);
|
||||||
|
return SpawnedPawns.Count(p => p.kindDef == kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AcceptanceReport CanSpawnNow(PawnKindDef kind)
|
||||||
|
{
|
||||||
|
if (parent is Pawn pawn && (pawn.IsSelfShutdown() || !pawn.Awake() || pawn.Downed || pawn.Dead || !pawn.Spawned))
|
||||||
|
return false;
|
||||||
|
if (CooldownTicksRemaining > 0)
|
||||||
|
return "CooldownTime".Translate() + " " + CooldownTicksRemaining.ToStringSecondsFromTicks();
|
||||||
|
|
||||||
|
PawnProductionEntry entry = AutoProps.productionQueue.First(e => e.pawnKind == kind);
|
||||||
|
int cost = entry.cost ?? Props.costPerPawn;
|
||||||
|
|
||||||
|
if (!AutoProps.freeProduction && InnerContainer.TotalStackCountOfDef(Props.fixedIngredient) < cost)
|
||||||
|
return "MechCarrierNotEnoughResources".Translate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TrySpawnPawn(PawnKindDef kind)
|
||||||
|
{
|
||||||
|
PawnGenerationRequest request = new PawnGenerationRequest(kind, parent.Faction, PawnGenerationContext.NonPlayer, -1, forceGenerateNewPawn: true);
|
||||||
|
Pawn pawn = PawnGenerator.GeneratePawn(request);
|
||||||
|
GenSpawn.Spawn(pawn, parent.Position, parent.Map);
|
||||||
|
SpawnedPawns.Add(pawn);
|
||||||
|
|
||||||
|
if (parent is Pawn p && p.GetLord() != null)
|
||||||
|
p.GetLord().AddPawn(pawn);
|
||||||
|
|
||||||
|
if (!AutoProps.freeProduction)
|
||||||
|
{
|
||||||
|
PawnProductionEntry entry = AutoProps.productionQueue.First(e => e.pawnKind == kind);
|
||||||
|
int costLeft = entry.cost ?? Props.costPerPawn;
|
||||||
|
|
||||||
|
List<Thing> things = new List<Thing>(InnerContainer);
|
||||||
|
for (int j = 0; j < things.Count; j++)
|
||||||
|
{
|
||||||
|
Thing thing = InnerContainer.Take(things[j], Mathf.Min(things[j].stackCount, costLeft));
|
||||||
|
costLeft -= thing.stackCount;
|
||||||
|
thing.Destroy();
|
||||||
|
if (costLeft <= 0) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PawnProductionEntry spawnEntry = AutoProps.productionQueue.First(e => e.pawnKind == kind);
|
||||||
|
CooldownTicksRemaining = spawnEntry.cooldownTicks ?? Props.cooldownTicks;
|
||||||
|
|
||||||
|
if (Props.spawnedMechEffecter != null)
|
||||||
|
EffecterTrigger(Props.spawnedMechEffecter, Props.attachSpawnedMechEffecter, pawn);
|
||||||
|
if (Props.spawnEffecter != null)
|
||||||
|
EffecterTrigger(Props.spawnEffecter, Props.attachSpawnedEffecter, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EffecterTrigger(EffecterDef effecterDef, bool attach, Thing target)
|
||||||
|
{
|
||||||
|
Effecter effecter = new Effecter(effecterDef);
|
||||||
|
effecter.Trigger(attach ? ((TargetInfo)target) : new TargetInfo(target.Position, target.Map), TargetInfo.Invalid);
|
||||||
|
effecter.Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void CompTick()
|
||||||
|
{
|
||||||
|
base.CompTick();
|
||||||
|
|
||||||
|
if (parent.IsHashIntervalTick(60)) // 每秒检查一次
|
||||||
|
{
|
||||||
|
// 检查是否有抑制生产的Hediff
|
||||||
|
if (AutoProps.disableHediff != null && (parent as Pawn)?.health.hediffSet.HasHediff(AutoProps.disableHediff) == true)
|
||||||
|
{
|
||||||
|
return; // 有Hediff,停止生产
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 先检查是否满员
|
||||||
|
bool isFull = true;
|
||||||
|
foreach (var entry in AutoProps.productionQueue)
|
||||||
|
{
|
||||||
|
if (LiveSpawnedPawnsCount(entry.pawnKind) < entry.count)
|
||||||
|
{
|
||||||
|
isFull = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFull)
|
||||||
|
{
|
||||||
|
return; // 如果已满员,则不进行任何操作,包括冷却计时
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 如果未满员,才检查冷却时间
|
||||||
|
if (CooldownTicksRemaining > 0) return;
|
||||||
|
|
||||||
|
// 3. 寻找空位并生产
|
||||||
|
foreach (var entry in AutoProps.productionQueue)
|
||||||
|
{
|
||||||
|
if (LiveSpawnedPawnsCount(entry.pawnKind) < entry.count)
|
||||||
|
{
|
||||||
|
if (CanSpawnNow(entry.pawnKind).Accepted)
|
||||||
|
{
|
||||||
|
TrySpawnPawn(entry.pawnKind);
|
||||||
|
break; // 每次只生产一个
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<Gizmo> CompGetGizmosExtra()
|
||||||
|
{
|
||||||
|
// 移除所有Gizmo逻辑
|
||||||
|
return Enumerable.Empty<Gizmo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string CompInspectStringExtra()
|
||||||
|
{
|
||||||
|
SpawnedPawns.RemoveAll(p => p == null || p.Destroyed);
|
||||||
|
string text = "Pawns: " + SpawnedPawns.Count + " / " + TotalPawnCapacity;
|
||||||
|
|
||||||
|
foreach (var entry in AutoProps.productionQueue)
|
||||||
|
{
|
||||||
|
text += $"\n- {entry.pawnKind.LabelCap}: {LiveSpawnedPawnsCount(entry.pawnKind)} / {entry.count}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CooldownTicksRemaining > 0)
|
||||||
|
{
|
||||||
|
text += "\n" + "CooldownTime".Translate() + ": " + CooldownTicksRemaining.ToStringSecondsFromTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AutoProps.freeProduction)
|
||||||
|
{
|
||||||
|
text += "\n" + base.CompInspectStringExtra();
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
using RimWorld;
|
||||||
|
using Verse;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class CompProperties_AutoMechCarrier : CompProperties_MechCarrier
|
||||||
|
{
|
||||||
|
// XML中定义,生产是否消耗资源
|
||||||
|
public bool freeProduction = false;
|
||||||
|
|
||||||
|
// 如果单位拥有这个Hediff,则停止生产
|
||||||
|
public HediffDef disableHediff;
|
||||||
|
|
||||||
|
// 定义生产队列
|
||||||
|
public List<PawnProductionEntry> productionQueue = new List<PawnProductionEntry>();
|
||||||
|
|
||||||
|
public CompProperties_AutoMechCarrier()
|
||||||
|
{
|
||||||
|
// 确保这个属性类指向我们新的功能实现类
|
||||||
|
compClass = typeof(CompAutoMechCarrier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<string> ConfigErrors(ThingDef parentDef)
|
||||||
|
{
|
||||||
|
foreach (string error in base.ConfigErrors(parentDef))
|
||||||
|
{
|
||||||
|
yield return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (productionQueue.NullOrEmpty())
|
||||||
|
{
|
||||||
|
yield return "CompProperties_AutoMechCarrier must have at least one entry in productionQueue.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ResolveReferences(ThingDef parentDef)
|
||||||
|
{
|
||||||
|
base.ResolveReferences(parentDef);
|
||||||
|
// Prevent division by zero if costPerPawn is not set, which the base game AI might try to access.
|
||||||
|
if (costPerPawn <= 0)
|
||||||
|
{
|
||||||
|
costPerPawn = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果spawnPawnKind为空(因为我们用了新的队列系统),
|
||||||
|
// 就从队列里取第一个作为“假”值,以防止基类方法在生成Gizmo标签时出错。
|
||||||
|
if (spawnPawnKind == null && !productionQueue.NullOrEmpty())
|
||||||
|
{
|
||||||
|
spawnPawnKind = productionQueue[0].pawnKind;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using Verse;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A data class to hold information about a pawn to be produced in a queue.
|
||||||
|
/// Used in XML definitions.
|
||||||
|
/// </summary>
|
||||||
|
public class PawnProductionEntry
|
||||||
|
{
|
||||||
|
// The PawnKindDef of the unit to spawn.
|
||||||
|
public PawnKindDef pawnKind;
|
||||||
|
|
||||||
|
// The maximum number of this kind of unit to maintain.
|
||||||
|
public int count = 1;
|
||||||
|
|
||||||
|
// Optional: specific cooldown for this entry. If not set, the parent comp's cooldown is used.
|
||||||
|
public int? cooldownTicks;
|
||||||
|
|
||||||
|
// Optional: specific cost for this entry. If not set, the parent comp's costPerPawn is used.
|
||||||
|
public int? cost;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user