This commit is contained in:
2025-09-23 15:01:15 +08:00
8 changed files with 185 additions and 27 deletions

View File

@@ -8,13 +8,10 @@
<thingClass>ArachnaeSwarm.Building_CatastropheMissileSilo</thingClass>
<drawerType>MapMeshAndRealTime</drawerType>
<graphicData>
<texPath>Things/Building/Security/TurretHeavy_Base</texPath>
<texPath>ArachnaeSwarm/Building/ARA_CatastropheMissileSilo_Base</texPath>
<graphicClass>Graphic_Single</graphicClass>
<drawSize>(3, 3)</drawSize>
<drawSize>(2.5,2.5)</drawSize>
<drawOffset>(0,0,-0.1)</drawOffset>
<damageData>
<rect>(0.2,0.2,0.6,0.6)</rect>
</damageData>
<shadowData>
<volume>(1.5,0.35,1.4)</volume>
<offset>(0,0,-0.05)</offset>
@@ -40,7 +37,7 @@
<outOfFuelMessage>缺少导弹</outOfFuelMessage>
<fuelFilter>
<thingDefs>
<li>ComponentSpacer</li>
<li>ARA_CatastropheMissile_Shell</li>
</thingDefs>
</fuelFilter>
<fuelCapacity>10</fuelCapacity>
@@ -55,7 +52,7 @@
</comps>
<building>
<turretGunDef>CatastropheMissile_Weapon</turretGunDef>
<turretBurstCooldownTime>5.0</turretBurstCooldownTime>
<turretBurstCooldownTime>15.0</turretBurstCooldownTime>
<buildingTags>
<li>Artillery</li>
</buildingTags>
@@ -67,7 +64,31 @@
</researchPrerequisites>
</ThingDef>
<ThingDef ParentName="BaseBullet">
<ThingDef ParentName="ShellBase">
<defName>ARA_CatastropheMissile_Shell</defName>
<label>天灾导弹</label>
<description>阿拉克涅虫族使用的天灾导弹.</description>
<possessionCount>2</possessionCount>
<graphicData>
<texPath>Things/Item/Resource/Shell/Shell_Toxic</texPath>
<graphicClass>Graphic_StackCount</graphicClass>
</graphicData>
<comps>
<li Class="CompProperties_Explosive">
<damageAmountBase>150</damageAmountBase>
<explosiveDamageType>ARA_AcidBurn</explosiveDamageType>
<explosiveRadius>10.9</explosiveRadius>
<postExplosionSpawnThingDef>ARA_Filth_SpentAcid</postExplosionSpawnThingDef>
<postExplosionSpawnChance>1</postExplosionSpawnChance>
<postExplosionSpawnThingCount>2</postExplosionSpawnThingCount>
<wickTicks>30~60</wickTicks>
<explosionSound>MortarBomb_Explode</explosionSound>
<explosionEffect>ARA_Shell_AcidSpitImpact</explosionEffect>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="BaseBullet">
<defName>Projectile_CatastropheMissile</defName>
<label>“天灾”巡航导弹</label>
<thingClass>ArachnaeSwarm.Projectile_CruiseMissile</thingClass>
@@ -84,8 +105,8 @@
<damageAmountBase>150</damageAmountBase>
<speed>80</speed>
<flyOverhead>true</flyOverhead>
<filth>Filth_SpentAcid</filth>
<filthCount>4</filthCount>
<filth>ARA_Filth_SpentAcid</filth>
<filthCount>2</filthCount>
<explosionEffect>ARA_Shell_AcidSpitImpact</explosionEffect>
<explosionEffectLifetimeTicks>60</explosionEffectLifetimeTicks>
<doExplosionVFX>false</doExplosionVFX>
@@ -123,6 +144,39 @@
</comps>
</ThingDef>
<ThingDef ParentName="BaseFilth">
<defName>ARA_Filth_SpentAcid</defName>
<label>阿拉克涅残酸</label>
<tickerType>Normal</tickerType>
<statBases>
<Beauty>-30</Beauty>
<Cleanliness>-5</Cleanliness>
</statBases>
<graphicData>
<texPath>Things/Filth/Acid</texPath>
<graphicClass>Graphic_Random</graphicClass>
<drawSize>2.5</drawSize>
<color>(1,1,1,0.5)</color>
</graphicData>
<filth>
<ignoreFilthMultiplierStat>true</ignoreFilthMultiplierStat>
<disappearsInDays>1~3</disappearsInDays>
<rainWashes>true</rainWashes>
<cleaningWorkToReduceThickness>70</cleaningWorkToReduceThickness>
<canFilthAttach>true</canFilthAttach>
<maxThickness>1</maxThickness>
<cleaningSound>Interact_CleanFilth_Fluid</cleaningSound>
</filth>
<thingClass>ArachnaeSwarm.Filth_Toxic</thingClass>
<modExtensions>
<li Class="ArachnaeSwarm.OPToxicDefs">
<OPToxicHediff>ARA_AcidCoverd</OPToxicHediff> <!-- Name of HediffDef to apply, change to own HediffDef -->
<OPToxicSeverity>0.1</OPToxicSeverity> <!-- Severity build up per Tick period -->
<OPSevUpTickPeriod>240</OPSevUpTickPeriod> <!-- No of game ticks per each build up, recommend >= 120 -->
</li>
</modExtensions>
</ThingDef>
<EffecterDef>
<defName>ARA_Shell_AcidSpitImpact</defName>
<children>
@@ -206,17 +260,17 @@
</comps>
</ThingDef>
<ThingDef ParentName="BaseWeapon">
<ThingDef ParentName="BaseArtilleryWeapon">
<defName>CatastropheMissile_Weapon</defName>
<label>天灾导弹武器系统</label>
<description>天灾导弹的发射系统。</description>
<techLevel>Spacer</techLevel>
<graphicData>
<texPath>Things/Building/Security/TurretMortar_Top</texPath>
<texPath>ArachnaeSwarm/Building/ARA_CatastropheMissileSilo_Tower</texPath>
<graphicClass>Graphic_Single</graphicClass>
<drawSize>(5,5)</drawSize>
</graphicData>
<statBases>
<RangedWeapon_Cooldown>5.0</RangedWeapon_Cooldown>
<RangedWeapon_Cooldown>15.0</RangedWeapon_Cooldown>
<Mass>50</Mass>
</statBases>
<verbs>

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View File

@@ -182,6 +182,7 @@
<Compile Include="Thing_Comps\ARA_CustomUniqueWeapon\CompCustomUniqueWeapon.cs" />
<Compile Include="Thing_Comps\ARA_CustomUniqueWeapon\CompProperties_CustomUniqueWeapon.cs" />
<Compile Include="Thing_Comps\ARA_IngestionOutcomeDoer_GiveHediff\IngestionOutcomeDoer_GiveHediffByRace.cs" />
<Compile Include="Thing_Comps\Filth_Toxic.cs" />
<Compile Include="Thing_Comps\OPToxicGas.cs" />
<Compile Include="Verbs\Cleave\CompCleave.cs" />
<Compile Include="Verbs\Cleave\Verb_MeleeAttack_Cleave.cs" />

View File

@@ -24,14 +24,13 @@ namespace ArachnaeSwarm
protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested, int ingestedCount)
{
// 如果列表是空的或null则默认对所有的pawn进行操作
if (!targetRaces.Contains(pawn.def))
// 如果 targetRaces 列表有内容并且当前pawn的种族不在列表中则不执行任何操作
if (!targetRaces.NullOrEmpty() && !targetRaces.Contains(pawn.def))
{
return;
}
else if (targetRaces.NullOrEmpty())
{
}
// 如果列表为空或者pawn的种族在列表中则继续执行后续代码
Hediff hediff = HediffMaker.MakeHediff(hediffDef, pawn);
float effect = ((!(severity > 0f)) ? hediffDef.initialSeverity : severity);
AddictionUtility.ModifyChemicalEffectForToleranceAndBodySize(pawn, toleranceChemical, ref effect, multiplyByGeneToleranceFactors, divideByBodySize);

View File

@@ -0,0 +1,74 @@
using RimWorld;
using System.Collections.Generic;
using UnityEngine;
using Verse;
namespace ArachnaeSwarm
{
public class Filth_Toxic : Filth
{
protected override void Tick()
{
base.Tick();
// 检查是否到了自动消失的时间
if (base.DisappearAfterTicks > 0 && Find.TickManager.TicksGame >= base.DisappearAfterTicks)
{
this.Destroy(DestroyMode.Vanish);
return;
}
// 周期性施加毒气效果
if (!base.Destroyed && Find.TickManager.TicksGame % OPToxicDefGetValue.OPToxicGetSevUpVal(this.def) == 0)
{
Map map = base.Map;
IntVec3 position = base.Position;
List<Thing> thingList = position.GetThingList(map);
if (thingList.Count > 0)
{
for (int i = 0; i < thingList.Count; i++)
{
if (thingList[i] is Pawn pawn && !pawn.RaceProps.IsMechanoid && thingList[i].Position == position)
{
this.DoOPToxicGas(this, pawn);
}
}
}
}
}
public void DoOPToxicGas(Thing filth, Thing targ)
{
Pawn pawn = targ as Pawn;
if (pawn != null && pawn.health.capacities.CapableOf(PawnCapacityDefOf.Breathing))
{
HediffDef hediffDef = DefDatabase<HediffDef>.GetNamedSilentFail(OPToxicDefGetValue.OPToxicGetHediff(filth.def));
if (hediffDef != null)
{
Hediff hediff = pawn.health.hediffSet.GetFirstHediffOfDef(hediffDef, false);
float toxicResistance = pawn.GetStatValue(StatDefOf.ToxicResistance, true, -1);
float severityPerTick = OPToxicDefGetValue.OPToxicGetSev(filth.def);
if (severityPerTick < 0.01f)
{
severityPerTick = 0.01f;
}
// 考虑污渍厚度对严重性的影响
float severityToAdd = Rand.Range(0.01f, severityPerTick) * (1f - toxicResistance) * this.thickness;
if (hediff != null && severityToAdd > 0f)
{
hediff.Severity += severityToAdd;
}
else
{
Hediff newHediff = HediffMaker.MakeHediff(hediffDef, pawn, null);
newHediff.Severity = severityToAdd;
pawn.health.AddHediff(newHediff, null, null, null);
}
}
}
}
}
}

View File

@@ -37,14 +37,18 @@ namespace ArachnaeSwarm
private CruiseMissileProperties settings;
private bool flag2;
private Vector3 Randdd;
private Vector3 position2;
public Vector3 ExPos;
public bool isDummy = false;
private Vector3 exactPositionInt; // 用于存储我们自己计算的位置
public override Vector3 ExactPosition => exactPositionInt; // 重写属性,让游戏获取我们计算的位置
public override Quaternion ExactRotation => Quaternion.LookRotation(destination - origin); // 弹头始终朝向目标
public override void ExposeData()
{
base.ExposeData();
Scribe_Values.Look(ref isDummy, "isDummy", false);
Scribe_Values.Look(ref exactPositionInt, "exactPositionInt");
}
public override void SpawnSetup(Map map, bool respawningAfterLoad)
@@ -52,6 +56,8 @@ namespace ArachnaeSwarm
base.SpawnSetup(map, respawningAfterLoad);
settings = def.GetModExtension<CruiseMissileProperties>() ?? new CruiseMissileProperties();
this.isDummy = settings.isDummy;
// 初始化我们自己的位置
exactPositionInt = origin;
}
private void RandFactor()
@@ -166,15 +172,16 @@ namespace ArachnaeSwarm
);
}
protected override void DrawAt(Vector3 position, bool flip = false)
{
position2 = BPos(DistanceCoveredFraction - 0.01f);
ExPos = position = BPos(DistanceCoveredFraction);
base.DrawAt(position, flip);
}
// 不再需要重写DrawAt因为ExactPosition现在是正确的
// protected override void DrawAt(Vector3 position, bool flip = false)
// { ... }
protected override void Tick()
{
// 首先调用base.Tick(),让它处理组件更新(比如拖尾特效)和ticksToImpact
base.Tick();
// 更新目标位置
if (intendedTarget.Thing is Pawn pawn && pawn.Spawned && !pawn.Destroyed)
{
if ((pawn.Dead || pawn.Downed) && DistanceCoveredFraction < 0.6f)
@@ -183,7 +190,30 @@ namespace ArachnaeSwarm
}
destination = pawn.DrawPos;
}
base.Tick();
// 如果base.Tick()已经处理了撞击,我们就不再继续
if (this.Destroyed)
{
return;
}
// 用我们自己的曲线位置覆盖掉base.Tick()计算的直线位置
Vector3 newPos = BPos(this.DistanceCoveredFraction);
// 增加边界检查
if (!newPos.InBounds(base.Map))
{
this.Destroy();
return;
}
exactPositionInt = newPos;
// 检查是否到达终点
if (this.DistanceCoveredFraction >= 1f)
{
Impact(null);
return;
}
}
private void FindNextTarget(Vector3 center)