暂存
This commit is contained in:
Binary file not shown.
@@ -70,6 +70,40 @@
|
|||||||
</li>
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
</AbilityDef>
|
</AbilityDef>
|
||||||
|
|
||||||
|
<AbilityDef>
|
||||||
|
<defName>ARA_EggSpew</defName>
|
||||||
|
<label>生育培育卵</label>
|
||||||
|
<description>工艺卵</description>
|
||||||
|
<iconPath>UI/Commands/EggSpew</iconPath>
|
||||||
|
<cooldownTicksRange>5000</cooldownTicksRange>
|
||||||
|
<aiCanUse>true</aiCanUse>
|
||||||
|
<displayOrder>300</displayOrder>
|
||||||
|
<displayGizmoWhileUndrafted>true</displayGizmoWhileUndrafted>
|
||||||
|
<disableGizmoWhileUndrafted>false</disableGizmoWhileUndrafted>
|
||||||
|
<warmupStartSound>AcidSpray_Warmup</warmupStartSound>
|
||||||
|
<verbProperties>
|
||||||
|
<verbClass>Verb_CastAbility</verbClass>
|
||||||
|
<range>1</range>
|
||||||
|
<warmupTime>12</warmupTime>
|
||||||
|
<soundCast>AcidSpray_Resolve</soundCast>
|
||||||
|
<violent>false</violent>
|
||||||
|
<targetable>false</targetable>
|
||||||
|
<targetParams>
|
||||||
|
<canTargetSelf>True</canTargetSelf>
|
||||||
|
</targetParams>
|
||||||
|
</verbProperties>
|
||||||
|
<comps>
|
||||||
|
<li Class="CompProperties_AbilityLaunchProjectile">
|
||||||
|
<projectileDef>ARA_Proj_BioforgeIncubator</projectileDef>
|
||||||
|
</li>
|
||||||
|
<li Class="ArachnaeSwarm.CompProperties_AbilityNeedCost">
|
||||||
|
<needDef>Food</needDef>
|
||||||
|
<needCost>0</needCost>
|
||||||
|
<failMessage>营养值不足,需要进食</failMessage>
|
||||||
|
</li>
|
||||||
|
</comps>
|
||||||
|
</AbilityDef>
|
||||||
<AbilityDef>
|
<AbilityDef>
|
||||||
<defName>ARA_AcidSprayBurst</defName>
|
<defName>ARA_AcidSprayBurst</defName>
|
||||||
<label>女皇种酸液轰炸</label>
|
<label>女皇种酸液轰炸</label>
|
||||||
@@ -159,6 +193,23 @@
|
|||||||
<tryAdjacentFreeSpaces>true</tryAdjacentFreeSpaces>
|
<tryAdjacentFreeSpaces>true</tryAdjacentFreeSpaces>
|
||||||
</projectile>
|
</projectile>
|
||||||
</ThingDef>
|
</ThingDef>
|
||||||
|
|
||||||
|
<ThingDef ParentName="BaseGrenadeProjectile">
|
||||||
|
<defName>ARA_Proj_BioforgeIncubator</defName>
|
||||||
|
<label>阿拉克涅孵化茧</label>
|
||||||
|
<thingClass>Projectile_SpawnsThing</thingClass>
|
||||||
|
<graphicData>
|
||||||
|
<texPath>ArachnaeSwarm/Building/ARA_EggSac</texPath>
|
||||||
|
<graphicClass>Graphic_Single</graphicClass>
|
||||||
|
</graphicData>
|
||||||
|
<projectile>
|
||||||
|
<damageDef>Bullet</damageDef>
|
||||||
|
<speed>21</speed>
|
||||||
|
<damageAmountBase>0</damageAmountBase>
|
||||||
|
<spawnsThingDef>ARA_BioforgeIncubator</spawnsThingDef>
|
||||||
|
<tryAdjacentFreeSpaces>true</tryAdjacentFreeSpaces>
|
||||||
|
</projectile>
|
||||||
|
</ThingDef>
|
||||||
|
|
||||||
<AbilityDef>
|
<AbilityDef>
|
||||||
<defName>ARA_AcidSprayBurst_Myrmecocystus</defName>
|
<defName>ARA_AcidSprayBurst_Myrmecocystus</defName>
|
||||||
|
|||||||
11
1.6/1.6/Defs/JobDefs/ARA_Jobs_Interactive.xml
Normal file
11
1.6/1.6/Defs/JobDefs/ARA_Jobs_Interactive.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Defs>
|
||||||
|
|
||||||
|
<JobDef>
|
||||||
|
<defName>ARA_IncubateJob</defName>
|
||||||
|
<driverClass>ArachnaeSwarm.JobDriver_StartProduction</driverClass>
|
||||||
|
<reportString>正在启动生产 TargetA.</reportString>
|
||||||
|
<allowOpportunisticPrefix>true</allowOpportunisticPrefix>
|
||||||
|
</JobDef>
|
||||||
|
|
||||||
|
</Defs>
|
||||||
@@ -3,68 +3,64 @@
|
|||||||
|
|
||||||
<ThingDef ParentName="BuildingBase">
|
<ThingDef ParentName="BuildingBase">
|
||||||
<defName>ARA_BioforgeIncubator</defName>
|
<defName>ARA_BioforgeIncubator</defName>
|
||||||
<label>生物质孵化器</label>
|
<label>阿拉克涅孵化茧</label>
|
||||||
<description>一个先进的孵化器,可以使用化学燃料将有机物和矿物重组成有用的物品。生产过程对温度非常敏感,并且需要由特定的操作员进行启动。</description>
|
<description>一个脆弱、易燃、黏滑的囊状物,是阿拉克涅工艺种所诞之卵,内含哺育阿拉克涅武器种虫族所需的营养和遗传物质,可以通过阿拉克涅工艺种的交互完成激活进程。</description>
|
||||||
<thingClass>Building</thingClass>
|
<thingClass>Building</thingClass>
|
||||||
|
<descriptionHyperlinks>
|
||||||
|
</descriptionHyperlinks>
|
||||||
|
<category>Building</category>
|
||||||
|
<size>(1,1)</size>
|
||||||
|
<minifiedDef>MinifiedThing</minifiedDef>
|
||||||
|
<thingCategories>
|
||||||
|
<li>BuildingsMisc</li>
|
||||||
|
</thingCategories>
|
||||||
<graphicData>
|
<graphicData>
|
||||||
<texPath>Things/Building/Production/BiofuelRefinery</texPath>
|
<texPath>ArachnaeSwarm/Building/ARA_EggSac</texPath>
|
||||||
<graphicClass>Graphic_Multi</graphicClass>
|
<graphicClass>Graphic_Single</graphicClass>
|
||||||
<drawSize>(2,2)</drawSize>
|
<drawSize>(1.5,1.5)</drawSize>
|
||||||
<damageData>
|
|
||||||
<cornerTL>Damage/Corner</cornerTL>
|
|
||||||
<cornerTR>Damage/Corner</cornerTR>
|
|
||||||
<cornerBL>Damage/Corner</cornerBL>
|
|
||||||
<cornerBR>Damage/Corner</cornerBR>
|
|
||||||
</damageData>
|
|
||||||
</graphicData>
|
</graphicData>
|
||||||
<size>(2,2)</size>
|
|
||||||
<costList>
|
|
||||||
<Steel>150</Steel>
|
|
||||||
<ComponentIndustrial>6</ComponentIndustrial>
|
|
||||||
</costList>
|
|
||||||
<altitudeLayer>Building</altitudeLayer>
|
<altitudeLayer>Building</altitudeLayer>
|
||||||
<passability>Impassable</passability>
|
<passability>PassThroughOnly</passability>
|
||||||
|
<fillPercent>0.3</fillPercent>
|
||||||
<rotatable>false</rotatable>
|
<rotatable>false</rotatable>
|
||||||
<designationCategory>Production</designationCategory>
|
<tickerType>Normal</tickerType>
|
||||||
|
<terrainAffordanceNeeded>Light</terrainAffordanceNeeded>
|
||||||
<statBases>
|
<statBases>
|
||||||
<MaxHitPoints>250</MaxHitPoints>
|
<Mass>10</Mass>
|
||||||
<WorkToBuild>3000</WorkToBuild>
|
<MaxHitPoints>50</MaxHitPoints>
|
||||||
<Flammability>1.0</Flammability>
|
<Flammability>1</Flammability>
|
||||||
<Beauty>-10</Beauty>
|
<Beauty>-6</Beauty>
|
||||||
</statBases>
|
</statBases>
|
||||||
|
<building>
|
||||||
|
<isInert>true</isInert>
|
||||||
|
<!-- <claimable>false</claimable> -->
|
||||||
|
<deconstructible>false</deconstructible>
|
||||||
|
<repairable>false</repairable>
|
||||||
|
<quickTargetable>true</quickTargetable>
|
||||||
|
<isTargetable>true</isTargetable>
|
||||||
|
<expandHomeArea>false</expandHomeArea>
|
||||||
|
</building>
|
||||||
<tickerType>Normal</tickerType>
|
<tickerType>Normal</tickerType>
|
||||||
|
|
||||||
<comps>
|
<comps>
|
||||||
<li Class="CompProperties_Power">
|
|
||||||
<compClass>CompPowerTrader</compClass>
|
|
||||||
<basePowerConsumption>250</basePowerConsumption>
|
|
||||||
</li>
|
|
||||||
<li Class="CompProperties_Flickable"/>
|
<li Class="CompProperties_Flickable"/>
|
||||||
<li Class="ArachnaeSwarm.CompProperties_InteractiveProducer">
|
<li Class="ArachnaeSwarm.CompProperties_InteractiveProducer">
|
||||||
<!-- 生产流程列表 -->
|
<!-- 生产流程列表 -->
|
||||||
<processes>
|
<processes>
|
||||||
<li>
|
<li>
|
||||||
<thingDef>ComponentIndustrial</thingDef>
|
<thingDef>Gun_ChainShotgun</thingDef>
|
||||||
<productionTicks>90000</productionTicks> <!-- 1.5 天 -->
|
<productionTicks>60000</productionTicks> <!-- 1.5 天 -->
|
||||||
<totalNutritionNeeded>25</totalNutritionNeeded>
|
<totalNutritionNeeded>20</totalNutritionNeeded>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<thingDef>Plasteel</thingDef>
|
<thingDef>Gun_AssaultRifle</thingDef>
|
||||||
<productionTicks>120000</productionTicks> <!-- 2 天 -->
|
<productionTicks>60000</productionTicks> <!-- 2 天 -->
|
||||||
<totalNutritionNeeded>50</totalNutritionNeeded>
|
<totalNutritionNeeded>15</totalNutritionNeeded>
|
||||||
</li>
|
</li>
|
||||||
</processes>
|
</processes>
|
||||||
|
|
||||||
<!-- 燃料接受规则 -->
|
<!-- 燃料接受规则 -->
|
||||||
<fuelAcceptance>
|
<fuelAcceptance>
|
||||||
<whitelist>
|
|
||||||
<li>WoodLog</li>
|
|
||||||
<li>RawFungus</li>
|
|
||||||
<li>Meat_Insect</li>
|
|
||||||
</whitelist>
|
|
||||||
<blacklist>
|
|
||||||
<li>MealSimple</li> <!-- 不接受简单食物,避免浪费 -->
|
|
||||||
</blacklist>
|
|
||||||
</fuelAcceptance>
|
</fuelAcceptance>
|
||||||
|
|
||||||
<!-- 交互白名单 -->
|
<!-- 交互白名单 -->
|
||||||
@@ -73,23 +69,52 @@
|
|||||||
</whitelist>
|
</whitelist>
|
||||||
|
|
||||||
<!-- 其他参数 -->
|
<!-- 其他参数 -->
|
||||||
<spawnCount>5~10</spawnCount>
|
<spawnCount>1</spawnCount>
|
||||||
<destroyOnSpawn>false</destroyOnSpawn>
|
<destroyOnSpawn>True</destroyOnSpawn>
|
||||||
<minSafeTemperature>7</minSafeTemperature>
|
<minSafeTemperature>18</minSafeTemperature>
|
||||||
<maxSafeTemperature>32</maxSafeTemperature>
|
<maxSafeTemperature>23</maxSafeTemperature>
|
||||||
<penaltyPerDegreePerTick>0.00001</penaltyPerDegreePerTick>
|
<penaltyPerDegreePerTick>0.00001</penaltyPerDegreePerTick>
|
||||||
</li>
|
</li>
|
||||||
|
<!-- Add the vanilla component to handle structural damage from extreme temperatures -->
|
||||||
|
<li Class="CompProperties_TemperatureRuinable">
|
||||||
|
<minSafeTemperature>13</minSafeTemperature> <!-- Damage below -10C -->
|
||||||
|
<maxSafeTemperature>28</maxSafeTemperature> <!-- Damage above 60C -->
|
||||||
|
<progressPerDegreePerTick>0.00005</progressPerDegreePerTick> <!-- Damage rate -->
|
||||||
|
</li>
|
||||||
|
<li Class="CompProperties_HeatPusher">
|
||||||
|
<compClass>CompHeatPusherPowered</compClass>
|
||||||
|
<heatPerSecond>6</heatPerSecond>
|
||||||
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
|
|
||||||
<building>
|
<building>
|
||||||
<defaultStorageSettings>
|
<haulToContainerDuration>120</haulToContainerDuration>
|
||||||
<priority>Important</priority>
|
<fixedStorageSettings>
|
||||||
<filter>
|
<filter>
|
||||||
<thingDefs>
|
<categories>
|
||||||
<li>WoodLog</li>
|
<li>Foods</li>
|
||||||
<li>RawFungus</li>
|
</categories>
|
||||||
<li>Meat_Insect</li>
|
<specialFiltersToDisallow>
|
||||||
</thingDefs>
|
<li>AllowPlantFood</li>
|
||||||
|
</specialFiltersToDisallow>
|
||||||
|
</filter>
|
||||||
|
</fixedStorageSettings>
|
||||||
|
<defaultStorageSettings>
|
||||||
|
<filter>
|
||||||
|
<categories>
|
||||||
|
<li>Foods</li>
|
||||||
|
</categories>
|
||||||
|
<disallowedCategories>
|
||||||
|
<li>EggsFertilized</li>
|
||||||
|
</disallowedCategories>
|
||||||
|
<disallowedThingDefs>
|
||||||
|
<li>InsectJelly</li>
|
||||||
|
<li>MealLavish</li>
|
||||||
|
<li>MealLavish_Veg</li>
|
||||||
|
<li>MealLavish_Meat</li>
|
||||||
|
<li>HemogenPack</li>
|
||||||
|
<li>Chocolate</li>
|
||||||
|
</disallowedThingDefs>
|
||||||
</filter>
|
</filter>
|
||||||
</defaultStorageSettings>
|
</defaultStorageSettings>
|
||||||
</building>
|
</building>
|
||||||
|
|||||||
@@ -105,6 +105,10 @@
|
|||||||
<Compile Include="WULA_AutoMechCarrier\CompProperties_AutoMechCarrier.cs" />
|
<Compile Include="WULA_AutoMechCarrier\CompProperties_AutoMechCarrier.cs" />
|
||||||
<Compile Include="WULA_AutoMechCarrier\PawnProductionEntry.cs" />
|
<Compile Include="WULA_AutoMechCarrier\PawnProductionEntry.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="CompInteractiveProducer.cs" />
|
||||||
|
<Compile Include="JobDriver_StartProduction.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">
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ namespace ArachnaeSwarm
|
|||||||
public float totalNutritionNeeded;
|
public float totalNutritionNeeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We do NOT inherit from CompProperties_Refuelable anymore
|
|
||||||
public class CompProperties_InteractiveProducer : CompProperties
|
public class CompProperties_InteractiveProducer : CompProperties
|
||||||
{
|
{
|
||||||
public List<ProcessDef> processes;
|
public List<ProcessDef> processes;
|
||||||
@@ -35,12 +34,10 @@ namespace ArachnaeSwarm
|
|||||||
public float maxSafeTemperature = 32f;
|
public float maxSafeTemperature = 32f;
|
||||||
public float penaltyPerDegreePerTick = 0.00001f;
|
public float penaltyPerDegreePerTick = 0.00001f;
|
||||||
|
|
||||||
// Manually added properties from CompProperties_Refuelable
|
|
||||||
public float fuelCapacity = 100f;
|
public float fuelCapacity = 100f;
|
||||||
public bool targetFuelLevelConfigurable = true;
|
public bool targetFuelLevelConfigurable = true;
|
||||||
public bool showAllowAutoRefuelToggle = true;
|
public bool showAllowAutoRefuelToggle = true;
|
||||||
public string fuelLabel = "Nutrition";
|
public string fuelLabel = "Nutrition";
|
||||||
public Texture2D fuelIcon = null; // Let it default or specify
|
|
||||||
|
|
||||||
public CompProperties_InteractiveProducer()
|
public CompProperties_InteractiveProducer()
|
||||||
{
|
{
|
||||||
@@ -61,11 +58,10 @@ namespace ArachnaeSwarm
|
|||||||
private int ticksUnderOptimalConditions;
|
private int ticksUnderOptimalConditions;
|
||||||
private float temperaturePenaltyPercent;
|
private float temperaturePenaltyPercent;
|
||||||
|
|
||||||
// --- Manually added state from CompRefuelable ---
|
|
||||||
private float configuredTargetFuelLevel = -1f;
|
private float configuredTargetFuelLevel = -1f;
|
||||||
public bool allowAutoRefuel = true;
|
public bool allowAutoRefuel = true;
|
||||||
|
|
||||||
// --- Manually added static resources from CompRefuelable ---
|
// --- Static Resources ---
|
||||||
private static readonly Texture2D SetTargetFuelLevelCommand = ContentFinder<Texture2D>.Get("UI/Commands/SetTargetFuelLevel");
|
private static readonly Texture2D SetTargetFuelLevelCommand = ContentFinder<Texture2D>.Get("UI/Commands/SetTargetFuelLevel");
|
||||||
private static readonly Vector2 FuelBarSize = new Vector2(1f, 0.2f);
|
private static readonly Vector2 FuelBarSize = new Vector2(1f, 0.2f);
|
||||||
private static readonly Material FuelBarFilledMat = SolidColorMaterials.SimpleSolidColorMaterial(new Color(0.6f, 0.56f, 0.13f));
|
private static readonly Material FuelBarFilledMat = SolidColorMaterials.SimpleSolidColorMaterial(new Color(0.6f, 0.56f, 0.13f));
|
||||||
@@ -79,7 +75,6 @@ namespace ArachnaeSwarm
|
|||||||
public bool StorageTabVisible => true;
|
public bool StorageTabVisible => true;
|
||||||
public float NutritionStored => containedNutrition + GetNutritionInContainer();
|
public float NutritionStored => containedNutrition + GetNutritionInContainer();
|
||||||
|
|
||||||
// --- Manually added properties from CompRefuelable ---
|
|
||||||
public float TargetFuelLevel
|
public float TargetFuelLevel
|
||||||
{
|
{
|
||||||
get => configuredTargetFuelLevel < 0f ? Props.fuelCapacity : configuredTargetFuelLevel;
|
get => configuredTargetFuelLevel < 0f ? Props.fuelCapacity : configuredTargetFuelLevel;
|
||||||
@@ -91,16 +86,19 @@ namespace ArachnaeSwarm
|
|||||||
// --- Initialization & Scribe ---
|
// --- Initialization & Scribe ---
|
||||||
public CompInteractiveProducer() { innerContainer = new ThingOwner<Thing>(this, false, LookMode.Deep); }
|
public CompInteractiveProducer() { innerContainer = new ThingOwner<Thing>(this, false, LookMode.Deep); }
|
||||||
|
|
||||||
public override void PostMake()
|
public override void PostSpawnSetup(bool respawningAfterLoad)
|
||||||
{
|
{
|
||||||
base.PostMake();
|
base.PostSpawnSetup(respawningAfterLoad);
|
||||||
allowedNutritionSettings = new StorageSettings(this);
|
if (!respawningAfterLoad)
|
||||||
if (parent.def.building.defaultStorageSettings != null)
|
|
||||||
{
|
{
|
||||||
allowedNutritionSettings.CopyFrom(parent.def.building.defaultStorageSettings);
|
allowedNutritionSettings = new StorageSettings(this);
|
||||||
|
if (parent.def.building.defaultStorageSettings != null)
|
||||||
|
{
|
||||||
|
allowedNutritionSettings.CopyFrom(parent.def.building.defaultStorageSettings);
|
||||||
|
}
|
||||||
|
UpdateFuelFilter();
|
||||||
|
TargetFuelLevel = Props.fuelCapacity;
|
||||||
}
|
}
|
||||||
UpdateFuelFilter();
|
|
||||||
TargetFuelLevel = Props.fuelCapacity; // Initialize target level
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void PostExposeData()
|
public override void PostExposeData()
|
||||||
@@ -139,9 +137,7 @@ namespace ArachnaeSwarm
|
|||||||
public override void CompTick()
|
public override void CompTick()
|
||||||
{
|
{
|
||||||
base.CompTick();
|
base.CompTick();
|
||||||
innerContainer.ThingOwnerTick();
|
if (parent.IsHashIntervalTick(60) && NutritionStored < TargetFuelLevel && allowAutoRefuel)
|
||||||
|
|
||||||
if (this.IsHashIntervalTick(60) && NutritionStored < TargetFuelLevel)
|
|
||||||
{
|
{
|
||||||
TryAbsorbNutritiousThing();
|
TryAbsorbNutritiousThing();
|
||||||
}
|
}
|
||||||
@@ -178,12 +174,120 @@ namespace ArachnaeSwarm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... (Production Flow methods remain the same) ...
|
// --- Production Flow ---
|
||||||
|
public override IEnumerable<FloatMenuOption> CompFloatMenuOptions(Pawn selPawn)
|
||||||
|
{
|
||||||
|
if (InProduction || !selPawn.CanReach(parent, PathEndMode.InteractionCell, Danger.Deadly))
|
||||||
|
{
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
if (Props.whitelist != null && !Props.whitelist.Contains(selPawn.kindDef))
|
||||||
|
{
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var process in Props.processes)
|
||||||
|
{
|
||||||
|
yield return new FloatMenuOption("StartProduction".Translate(process.thingDef.label), () =>
|
||||||
|
{
|
||||||
|
// When the float menu is clicked, we set the selected process on the comp,
|
||||||
|
// so the JobDriver knows which process to start.
|
||||||
|
this._selectedProcess = process;
|
||||||
|
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("ARA_IncubateJob"), parent);
|
||||||
|
selPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is now called by the JobDriver, without arguments.
|
||||||
|
public void StartProduction()
|
||||||
|
{
|
||||||
|
if (_selectedProcess == null)
|
||||||
|
{
|
||||||
|
Log.Error("CompInteractiveProducer tried to start production, but _selectedProcess is null.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
productionUntilTick = Find.TickManager.TicksGame + _selectedProcess.productionTicks;
|
||||||
|
ticksUnderOptimalConditions = 0;
|
||||||
|
temperaturePenaltyPercent = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FinishProduction()
|
||||||
|
{
|
||||||
|
float baseQuality = (_selectedProcess.productionTicks > 0) ? (float)ticksUnderOptimalConditions / _selectedProcess.productionTicks : 0f;
|
||||||
|
float finalQualityScore = Mathf.Clamp01(baseQuality - temperaturePenaltyPercent);
|
||||||
|
|
||||||
|
for (int i = 0; i < Props.spawnCount.RandomInRange; i++)
|
||||||
|
{
|
||||||
|
Thing thing = ThingMaker.MakeThing(_selectedProcess.thingDef);
|
||||||
|
if (thing.TryGetComp<CompQuality>() is CompQuality compQuality)
|
||||||
|
{
|
||||||
|
if (finalQualityScore >= 0.99f) compQuality.SetQuality(QualityCategory.Legendary, ArtGenerationContext.Colony);
|
||||||
|
else if (finalQualityScore >= 0.90f) compQuality.SetQuality(QualityCategory.Masterwork, ArtGenerationContext.Colony);
|
||||||
|
else if (finalQualityScore >= 0.70f) compQuality.SetQuality(QualityCategory.Excellent, ArtGenerationContext.Colony);
|
||||||
|
else if (finalQualityScore >= 0.50f) compQuality.SetQuality(QualityCategory.Good, ArtGenerationContext.Colony);
|
||||||
|
else if (finalQualityScore >= 0.20f) compQuality.SetQuality(QualityCategory.Normal, ArtGenerationContext.Colony);
|
||||||
|
else if (finalQualityScore >= 0.10f) compQuality.SetQuality(QualityCategory.Poor, ArtGenerationContext.Colony);
|
||||||
|
else compQuality.SetQuality(QualityCategory.Awful, ArtGenerationContext.Colony);
|
||||||
|
}
|
||||||
|
GenPlace.TryPlaceThing(thing, parent.InteractionCell, parent.Map, ThingPlaceMode.Near);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Props.destroyOnSpawn)
|
||||||
|
{
|
||||||
|
parent.Destroy();
|
||||||
|
}
|
||||||
|
ResetProduction();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetProduction()
|
||||||
|
{
|
||||||
|
_selectedProcess = null;
|
||||||
|
productionUntilTick = -1;
|
||||||
|
}
|
||||||
|
|
||||||
// --- Fuel System ---
|
// --- Fuel System ---
|
||||||
private void UpdateFuelFilter() { /* ... */ }
|
private void UpdateFuelFilter()
|
||||||
private void TryAbsorbNutritiousThing() { /* ... */ }
|
{
|
||||||
public bool IsAcceptableFuel(ThingDef def) { /* ... */ }
|
if (Props.fuelAcceptance != null)
|
||||||
|
{
|
||||||
|
var filter = allowedNutritionSettings.filter;
|
||||||
|
filter.SetDisallowAll();
|
||||||
|
if (!Props.fuelAcceptance.whitelist.NullOrEmpty())
|
||||||
|
{
|
||||||
|
foreach (var def in Props.fuelAcceptance.whitelist) filter.SetAllow(def, true);
|
||||||
|
}
|
||||||
|
if (!Props.fuelAcceptance.blacklist.NullOrEmpty())
|
||||||
|
{
|
||||||
|
foreach (var def in Props.fuelAcceptance.blacklist) filter.SetAllow(def, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TryAbsorbNutritiousThing()
|
||||||
|
{
|
||||||
|
for (int i = innerContainer.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
Thing thing = innerContainer[i];
|
||||||
|
if (IsAcceptableFuel(thing.def))
|
||||||
|
{
|
||||||
|
float nutrition = thing.GetStatValue(StatDefOf.Nutrition);
|
||||||
|
int numToAbsorb = Mathf.CeilToInt(Mathf.Min((float)thing.stackCount, 1f));
|
||||||
|
containedNutrition += (float)numToAbsorb * nutrition;
|
||||||
|
thing.SplitOff(numToAbsorb).Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsAcceptableFuel(ThingDef def)
|
||||||
|
{
|
||||||
|
var acceptance = Props.fuelAcceptance;
|
||||||
|
if (acceptance == null) return true;
|
||||||
|
if (acceptance.blacklist != null && acceptance.blacklist.Contains(def)) return false;
|
||||||
|
if (acceptance.whitelist != null && !acceptance.whitelist.NullOrEmpty()) return acceptance.whitelist.Contains(def);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// --- IStoreSettingsParent & IThingHolder ---
|
// --- IStoreSettingsParent & IThingHolder ---
|
||||||
public StorageSettings GetStoreSettings() => allowedNutritionSettings;
|
public StorageSettings GetStoreSettings() => allowedNutritionSettings;
|
||||||
@@ -218,19 +322,17 @@ namespace ArachnaeSwarm
|
|||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
// Ported logic from CompRefuelable
|
|
||||||
sb.Append(Props.fuelLabel + ": " + NutritionStored.ToString("F0") + " / " + Props.fuelCapacity.ToString("F0"));
|
sb.Append(Props.fuelLabel + ": " + NutritionStored.ToString("F0") + " / " + Props.fuelCapacity.ToString("F0"));
|
||||||
if (InProduction)
|
if (InProduction)
|
||||||
{
|
{
|
||||||
float ticksRemaining = _selectedProcess.productionTicks * (NutritionStored / _selectedProcess.totalNutritionNeeded);
|
float nutritionRatePerDay = (_selectedProcess.totalNutritionNeeded / _selectedProcess.productionTicks) * 60000;
|
||||||
sb.Append(" (" + ((int)ticksRemaining).ToStringTicksToPeriod() + ")");
|
sb.Append(" (-" + nutritionRatePerDay.ToString("F1") + "/day)");
|
||||||
}
|
}
|
||||||
if (Props.targetFuelLevelConfigurable)
|
if (Props.targetFuelLevelConfigurable)
|
||||||
{
|
{
|
||||||
sb.Append("\n" + "ConfiguredTargetFuelLevel".Translate(TargetFuelLevel.ToString("F0")));
|
sb.Append("\n" + "ConfiguredTargetFuelLevel".Translate(TargetFuelLevel.ToString("F0")));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Our production info
|
|
||||||
if (InProduction)
|
if (InProduction)
|
||||||
{
|
{
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
@@ -251,18 +353,16 @@ namespace ArachnaeSwarm
|
|||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<Gizmo> GetGizmos()
|
public override IEnumerable<Gizmo> CompGetGizmosExtra()
|
||||||
{
|
{
|
||||||
foreach (var g in base.GetGizmos()) yield return g;
|
foreach (var g in base.CompGetGizmosExtra()) yield return g;
|
||||||
|
|
||||||
// Ported Gizmos from CompRefuelable
|
|
||||||
if (Props.targetFuelLevelConfigurable)
|
if (Props.targetFuelLevelConfigurable)
|
||||||
{
|
{
|
||||||
var setTargetGizmo = new Command_SetTargetFuelLevel();
|
var setTargetGizmo = new Command_SetTargetFuelLevel();
|
||||||
setTargetGizmo.defaultLabel = "CommandSetTargetFuelLevel".Translate();
|
setTargetGizmo.defaultLabel = "CommandSetTargetFuelLevel".Translate();
|
||||||
setTargetGizmo.defaultDesc = "CommandSetTargetFuelLevelDesc".Translate();
|
setTargetGizmo.defaultDesc = "CommandSetTargetFuelLevelDesc".Translate();
|
||||||
setTargetGizmo.icon = SetTargetFuelLevelCommand;
|
setTargetGizmo.icon = SetTargetFuelLevelCommand;
|
||||||
// We need to create a simple wrapper to make it work
|
|
||||||
setTargetGizmo.setter = (level) => this.TargetFuelLevel = level;
|
setTargetGizmo.setter = (level) => this.TargetFuelLevel = level;
|
||||||
setTargetGizmo.getter = () => this.TargetFuelLevel;
|
setTargetGizmo.getter = () => this.TargetFuelLevel;
|
||||||
setTargetGizmo.max = this.Props.fuelCapacity;
|
setTargetGizmo.max = this.Props.fuelCapacity;
|
||||||
@@ -292,6 +392,46 @@ namespace ArachnaeSwarm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... (The rest of the methods: FinishProduction, ResetProduction, GetNutritionInContainer etc.) ...
|
private float GetNutritionInContainer()
|
||||||
|
{
|
||||||
|
float total = 0f;
|
||||||
|
for (int i = 0; i < innerContainer.Count; i++)
|
||||||
|
{
|
||||||
|
total += (float)innerContainer[i].stackCount * innerContainer[i].GetStatValue(StatDefOf.Nutrition);
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A wrapper for the Gizmo since we are not CompRefuelable
|
||||||
|
public class Command_SetTargetFuelLevel : Command
|
||||||
|
{
|
||||||
|
public System.Action<float> setter;
|
||||||
|
public System.Func<float> getter;
|
||||||
|
public float max;
|
||||||
|
|
||||||
|
public override void ProcessInput(Event ev)
|
||||||
|
{
|
||||||
|
base.ProcessInput(ev);
|
||||||
|
List<FloatMenuOption> list = new List<FloatMenuOption>();
|
||||||
|
for (int i = 0; i < (int)max; i += 10)
|
||||||
|
{
|
||||||
|
float level = (float)i;
|
||||||
|
if(level > max) level = max;
|
||||||
|
|
||||||
|
list.Add(new FloatMenuOption(level.ToString("F0"), () => setter(level)));
|
||||||
|
if(level >= max) break;
|
||||||
|
}
|
||||||
|
Find.WindowStack.Add(new FloatMenu(list));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool InheritInteractionsFrom(Gizmo other)
|
||||||
|
{
|
||||||
|
if (other is Command_SetTargetFuelLevel otherGizmo)
|
||||||
|
{
|
||||||
|
return getter() == otherGizmo.getter();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
36
Source/ArachnaeSwarm/JobDriver_StartProduction.cs
Normal file
36
Source/ArachnaeSwarm/JobDriver_StartProduction.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using RimWorld;
|
||||||
|
using Verse;
|
||||||
|
using Verse.AI;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class JobDriver_StartProduction : JobDriver
|
||||||
|
{
|
||||||
|
private const TargetIndex BuildingInd = TargetIndex.A;
|
||||||
|
|
||||||
|
protected Building Building => (Building)job.GetTarget(BuildingInd).Thing;
|
||||||
|
|
||||||
|
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
||||||
|
{
|
||||||
|
return pawn.Reserve(Building, job, 1, -1, null, errorOnFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IEnumerable<Toil> MakeNewToils()
|
||||||
|
{
|
||||||
|
this.FailOnDespawnedNullOrForbidden(BuildingInd);
|
||||||
|
this.FailOnBurningImmobile(BuildingInd);
|
||||||
|
|
||||||
|
yield return Toils_Goto.GotoThing(BuildingInd, PathEndMode.InteractionCell);
|
||||||
|
|
||||||
|
Toil work = ToilMaker.MakeToil("MakeNewToils");
|
||||||
|
work.initAction = delegate
|
||||||
|
{
|
||||||
|
var comp = Building.GetComp<CompInteractiveProducer>();
|
||||||
|
comp.StartProduction();
|
||||||
|
};
|
||||||
|
work.defaultCompleteMode = ToilCompleteMode.Instant;
|
||||||
|
yield return work;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user