This commit is contained in:
2025-09-22 14:20:36 +08:00
parent 0b555a7d3a
commit 23b1b6dd3b
4 changed files with 211 additions and 0 deletions

Binary file not shown.

View File

@@ -87,4 +87,80 @@
<speed>120</speed>
</projectile>
</ThingDef>
<!---->
<ThingDef ParentName="BaseHumanMakeableGun">
<defName>ARA_RW_Basic_Acid_Spreay_Gun</defName>
<label>武装器官"酸液枪喷吐版"</label>
<description>阿拉克涅虫群督虫使用基础远程武装器官,可以通过肌肉的瞬间加压喷出一团包含阿拉克涅酸液的液体团。这种酸液团的飞行速度很慢,但是能在目标地点炸开,并灼烧所有粘上酸液的敌人。</description>
<tickerType>Normal</tickerType>
<techLevel>Animal</techLevel>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Weapon</ThingDef>
</descriptionHyperlinks>
<graphicData>
<texPath>ArachnaeSwarm/Weapon/ARA_RW_Basic_Acid_Bladder_Gun</texPath>
<graphicClass>Graphic_Single</graphicClass>
<drawSize>1.2</drawSize>
</graphicData>
<soundInteract>SpitterSpawn</soundInteract>
<recipeMaker>
<recipeUsers Inherit="False" />
<researchPrerequisite>ARA_Technology_7VXI</researchPrerequisite>
<unfinishedThingDef>UnfinishedWeapon</unfinishedThingDef>
</recipeMaker>
<statBases>
<WorkToMake>1300</WorkToMake>
<!-- <MarketValue>370</MarketValue> -->
<Mass>3.5</Mass>
<AccuracyTouch>0.5</AccuracyTouch>
<AccuracyShort>0.6</AccuracyShort>
<AccuracyMedium>0.45</AccuracyMedium>
<AccuracyLong>0.3</AccuracyLong>
<RangedWeapon_Cooldown>2.5</RangedWeapon_Cooldown>
</statBases>
<verbs>
<li>
<verbClass>ArachnaeSwarm.Verb_ShootSprayMulti</verbClass>
<hasStandardCommand>true</hasStandardCommand>
<forceNormalTimeSpeed>false</forceNormalTimeSpeed>
<warmupTime>1.0</warmupTime>
<forcedMissRadius>1</forcedMissRadius>
<defaultProjectile>ARA_Proj_StrongSludgeSpray</defaultProjectile>
<isMortar>false</isMortar>
<requireLineOfSight>false</requireLineOfSight>
<minRange>3</minRange>
<range>28</range>
<burstShotCount>3</burstShotCount>
<ticksBetweenBurstShots>12</ticksBetweenBurstShots>
<soundCast>SpitterSpit</soundCast>
<targetParams>
<canTargetLocations>true</canTargetLocations>
</targetParams>
<numCellsToHit>5</numCellsToHit>
</li>
</verbs>
<costList Inherit="False">
<ARA_Carapace>50</ARA_Carapace>
</costList>
<weaponTags>
<li>ARA_Armed_Organ</li>
<li>ARA_Armed_Organ_Ranged</li>
<li>ARA_Armed_Organ_T1</li>
</weaponTags>
<thingSetMakerTags>
<li>RewardStandardQualitySuper</li>
</thingSetMakerTags>
<comps>
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey">
<forcedTraits>
<li>ARA_Weapon_Damage_Acid</li>
</forcedTraits>
<numTraitsRange>
<min>1</min>
<max>1</max>
</numTraitsRange>
</li>
</comps>
</ThingDef>
</Defs>

View File

@@ -202,6 +202,7 @@
<Compile Include="Verbs\Verb_ShootMeltBeam.cs" />
<Compile Include="Verbs\Verb_ShootShotgun.cs" />
<Compile Include="Verbs\VerbProperties_Excalibur.cs" />
<Compile Include="Verbs\Verb_ShootSprayMulti.cs" />
<Compile Include="Verbs\WeaponStealBeam\Verb_ShootWeaponStealBeam.cs" />
<Compile Include="Verbs\WeaponStealBeam\VerbProperties_WeaponStealBeam.cs" />
<Compile Include="Building_ARANutrientDispenser.cs" />

View File

@@ -0,0 +1,134 @@
using RimWorld;
using System.Collections.Generic;
using UnityEngine;
using Verse;
using Verse.Sound;
namespace ArachnaeSwarm
{
public class Verb_ShootSprayMulti : Verb_Shoot
{
public VerbProperties_ShootSprayMulti SprayProps => verbProps as VerbProperties_ShootSprayMulti;
protected override bool TryCastShot()
{
if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map)
{
return false;
}
List<IntVec3> cells = AffectedCells(currentTarget);
if (cells.Count == 0)
{
return false;
}
// A single "shot" from the verb will fire projectiles at all affected cells.
// The base verb's burst fire mechanism will handle firing multiple "shots".
bool shotFired = false;
foreach (var cell in cells)
{
if (CanHitTarget(cell))
{
ShootLine shootLine;
if (TryFindShootLineFromTo(caster.Position, cell, out shootLine))
{
Projectile projectile = (Projectile)GenSpawn.Spawn(verbProps.defaultProjectile, shootLine.Source, caster.Map);
// Corrected Launch call without targetCover
projectile.Launch(caster, caster.DrawPos, cell, cell, ProjectileHitFlags.IntendedTarget, equipment: (caster as Pawn)?.equipment?.Primary);
shotFired = true;
}
}
}
if (shotFired)
{
// Corrected sound calls based on MCP knowledge
if (verbProps.soundCast != null)
{
verbProps.soundCast.PlayOneShot(SoundInfo.InMap(new TargetInfo(caster.Position, caster.Map)));
}
if (verbProps.soundCastTail != null)
{
verbProps.soundCastTail.PlayOneShotOnCamera();
}
if (caster is Pawn pawn)
{
if (pawn.records != null)
{
pawn.records.Increment(RecordDefOf.ShotsFired);
}
if (pawn.skills != null)
{
pawn.skills.Learn(SkillDefOf.Shooting, 0.5f);
}
}
}
return shotFired;
}
// This logic is adapted from CompAbilityEffect_SprayLiquidMulti
private List<IntVec3> AffectedCells(LocalTargetInfo target)
{
List<Pair<IntVec3, float>> tmpCellDots = new List<Pair<IntVec3, float>>();
List<IntVec3> tmpCells = new List<IntVec3>();
tmpCellDots.Clear();
tmpCells.Clear();
tmpCellDots.Add(new Pair<IntVec3, float>(target.Cell, 999f));
int numCellsToHit = SprayProps?.numCellsToHit ?? 1;
if (numCellsToHit > 1)
{
Vector3 vector = caster.Position.ToVector3Shifted().Yto0();
Vector3 vector2 = target.Cell.ToVector3Shifted().Yto0();
IntVec3[] array;
int num;
if (numCellsToHit < 10)
{
array = GenAdj.AdjacentCells;
num = 8;
}
else
{
array = GenRadial.RadialPattern;
num = numCellsToHit + 5;
}
for (int i = 0; i < num; i++)
{
IntVec3 first = target.Cell + array[i];
Vector3 vector3 = first.ToVector3Shifted().Yto0();
float second = Vector3.Dot((vector3 - vector).normalized, (vector3 - vector2).normalized);
tmpCellDots.Add(new Pair<IntVec3, float>(first, second));
}
tmpCellDots.SortByDescending(x => x.Second);
}
Map map = caster.Map;
int num2 = Mathf.Min(tmpCellDots.Count, numCellsToHit);
for (int j = 0; j < num2; j++)
{
IntVec3 first2 = tmpCellDots[j].First;
if (!first2.InBounds(map)) continue;
if (first2.Filled(map))
{
Building_Door door = first2.GetDoor(map);
if (door == null || !door.Open) continue;
}
if (TryFindShootLineFromTo(caster.Position, first2, out var _))
{
tmpCells.Add(first2);
}
}
return tmpCells;
}
}
public class VerbProperties_ShootSprayMulti : VerbProperties
{
public int numCellsToHit = 1;
}
}