This commit is contained in:
2025-09-22 21:09:04 +08:00
parent bb5e555acc
commit 8699c4c63e
3 changed files with 38 additions and 43 deletions

Binary file not shown.

View File

@@ -8,7 +8,7 @@
<graphicData>
<graphicClass>Graphic_Single_AgeSecs</graphicClass>
<texPath>Things/Projectile/FleshmassSpitterProjectileSheet</texPath>
<drawSize>(3,3)</drawSize>
<drawSize>(3,3)</drawSize>
<shaderType>MoteGlow</shaderType>
</graphicData>
<projectile>
@@ -18,7 +18,7 @@
<damageAmountBase>200</damageAmountBase>
<speed>80</speed>
<spinRate>15</spinRate>
<flyOverhead>true</flyOverhead>0
<flyOverhead>true</flyOverhead>
<filth>Filth_SpentAcid</filth>
<filthCount>4</filthCount>
<explosionEffect>Shell_AcidSpitImpact</explosionEffect>
@@ -65,7 +65,7 @@
<graphicData>
<graphicClass>Graphic_Single_AgeSecs</graphicClass>
<texPath>Things/Projectile/FleshmassSpitterProjectileSheet</texPath>
<drawSize>(3,3)</drawSize>
<drawSize>(3,3)</drawSize>
<shaderType>MoteGlow</shaderType>
</graphicData>
<projectile>
@@ -106,26 +106,6 @@
<RangedWeapon_Cooldown>5.0</RangedWeapon_Cooldown>
<Mass>50</Mass>
</statBases>
<verbs>
<li>
<verbClass>Verb_Shoot</verbClass>
<forceNormalTimeSpeed>false</forceNormalTimeSpeed>
<warmupTime>4.0</warmupTime>
<forcedMissRadius>9</forcedMissRadius>
<forcedMissRadiusClassicMortars>13</forcedMissRadiusClassicMortars>
<isMortar>true</isMortar>
<requireLineOfSight>false</requireLineOfSight>
<minRange>29.9</minRange>
<range>500</range>
<burstShotCount>1</burstShotCount>
<soundCast>Mortar_LaunchA</soundCast>
<muzzleFlashScale>16</muzzleFlashScale>
<consumeFuelPerShot>1</consumeFuelPerShot>
<targetParams>
<canTargetLocations>true</canTargetLocations>
</targetParams>
</li>
</verbs>
<verbs>
<li>
<verbClass>ArachnaeSwarm.Verb_LaunchCatastropheMissile</verbClass>

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using UnityEngine;
using Verse;
using Verse.AI;
@@ -14,6 +15,10 @@ namespace ArachnaeSwarm
[StaticConstructorOnStartup]
public class Building_CatastropheMissileSilo : Building_TurretGun
{
// Reflection to access the private 'holdFire' field in the base class, as there is no public accessor.
private static readonly FieldInfo holdFireField =
typeof(Building_TurretGun).GetField("holdFire", BindingFlags.NonPublic | BindingFlags.Instance);
public GlobalTargetInfo longTarget;
public static readonly Texture2D FireMissionTex = ContentFinder<Texture2D>.Get("UI/Commands/Attack", true);
@@ -36,30 +41,40 @@ namespace ArachnaeSwarm
protected override void Tick()
{
// --- Attack Priority Logic (Remote Target has higher priority) ---
// Prio 1: Remote Target
if (this.longTarget.IsValid)
// Always run base.Tick() first. This handles all local targeting, aiming, warmup,
// cooldowns, and calling the Verb for local shots. This is the key to fixing the bug.
base.Tick();
// --- Mutual Exclusivity: Prioritize Local Target ---
// If a local target is set (either by player or automatically), clear the remote target.
if (this.forcedTarget.IsValid && this.longTarget.IsValid)
{
if (base.Active && this.burstCooldownTicksLeft <= 0 && CanFireGlobal(out _))
this.longTarget = GlobalTargetInfo.Invalid;
}
// --- Debug Logging (every 120 ticks, approx 2 seconds) ---
if (Find.TickManager.TicksGame % 120 == 0)
{
bool isHoldingFireForLog = (bool)holdFireField.GetValue(this);
string reason;
CanFireGlobal(out reason); // To get the reason string
Log.Message($"[Silo Debug] Tick: {Find.TickManager.TicksGame}\n" +
$"- Cooldown: {this.burstCooldownTicksLeft}\n" +
$"- Active (Power): {base.Active}\n" +
$"- HoldFire: {isHoldingFireForLog}\n" +
$"- CanFireGlobal (Fuel?): {CanFireGlobal(out reason)} (Reason: {reason})\n" +
$"- Local Target: {this.forcedTarget.ToString()}\n" +
$"- Remote Target: {this.longTarget.ToString()}");
}
// --- Remote Firing Logic ---
bool isHoldingFire = (bool)holdFireField.GetValue(this);
if (this.longTarget.IsValid && !isHoldingFire && this.burstCooldownTicksLeft <= 0 && base.Active && CanFireGlobal(out _))
{
if (!this.forcedTarget.IsValid)
{
this.FireMission(this.longTarget);
}
else
{
// Manually tick cooldown and turret top rotation when in remote mode to prevent auto-targeting
if(this.burstCooldownTicksLeft > 0) this.burstCooldownTicksLeft--;
this.top.TurretTopTick();
}
}
// Prio 2: Forced Local Target (Only if no remote target)
else if (this.forcedTarget.IsValid)
{
base.Tick(); // Let base class handle it
}
// Prio 3: Auto Target (if no manual targets)
else
{
base.Tick(); // Let base class handle it
}
}