diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll index a8531aaa..1d5587d1 100644 Binary files a/1.6/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/1.6/Assemblies/WulaFallenEmpire.dll differ diff --git a/1.6/1.6/Defs/HediffDefs/Hediffs_WULA.xml b/1.6/1.6/Defs/HediffDefs/Hediffs_WULA.xml index de5769af..adc4bf42 100644 --- a/1.6/1.6/Defs/HediffDefs/Hediffs_WULA.xml +++ b/1.6/1.6/Defs/HediffDefs/Hediffs_WULA.xml @@ -62,11 +62,10 @@ false
  • - 20,000 - 0.00011667 + 0.0002
  • diff --git a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon_Penetrating_Beam.xml b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon_Penetrating_Beam.xml new file mode 100644 index 00000000..ea65efb9 --- /dev/null +++ b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon_Penetrating_Beam.xml @@ -0,0 +1,106 @@ + + + + + + WULA_RW_Penetrating_Beam_Rifle + + 一把经过实验性改造的“蓝锥”步枪,能够发射一道可以穿透多个目标的能量光束。 + Spacer + + Wula/Weapon/WULA_RW_Fractal_RF + Graphic_Single + + Interact_Rifle + +
  • LongShots
  • +
  • RangedHeavy
  • +
    + + 1300 + 3.5 + 0.65 + 0.72 + 0.65 + 0.6 + 2.0 + + + 120 + 6 + + +
  • + WulaFallenEmpire.Verb_ShootShotgun + true + Bullet_WULA_RW_Penetrating_Beam + 3.0 + 28 + 3 + 12 + Shot_BeamRepeater + GunTail_Medium + 9 + Mote_BeamRepeater_Charge + 1.07 +
  • +
    + +
  • Wula_Weapon_Init
  • +
    +
  • RewardStandardQualitySuper
  • +
    + + + Bullet_WULA_RW_Penetrating_Beam + + WulaFallenEmpire.Projectile_WulaBeam + +
  • + -1 + 0 + false + Mote_WULA_RW_Penetrating_Beam + 0.5 +
  • +
  • + 3 +
  • +
    + + Things/Projectile/ChargeLanceShot + Graphic_Single + + + BeamBypassShields + 5 + 0.8 + 1 + +
    + + + Mote_WULA_RW_Penetrating_Beam + MoteDualAttached + MoteOverhead + + 0.1 + 0.1 + 0.1 + True + True + + true + + Things/Projectile/ChargeLanceShot + Graphic_MoteWithAgeSecs + MoteBeam + + <_ScrollSpeedA>0 + <_ScrollSpeedB>0 + <_Intensity>2 + + + + +
    \ No newline at end of file diff --git a/Source/WulaFallenEmpire/Projectile_WulaBeam.cs b/Source/WulaFallenEmpire/Projectile_WulaBeam.cs new file mode 100644 index 00000000..ff6d1fd8 --- /dev/null +++ b/Source/WulaFallenEmpire/Projectile_WulaBeam.cs @@ -0,0 +1,134 @@ +using System.Collections.Generic; +using RimWorld; +using UnityEngine; +using Verse; + +namespace WulaFallenEmpire +{ + // A new, dedicated extension class for the penetrating beam. + public class Wula_BeamPierce_Extension : DefModExtension + { + public int maxHits = 3; + public float damageFalloff = 0.25f; + public bool preventFriendlyFire = false; + public ThingDef beamMoteDef; + public float beamWidth = 1f; + public float beamStartOffset = 0f; + } + + public class Projectile_WulaBeam : Bullet + { + private int hitCounter = 0; + private List alreadyDamaged = new List(); + + // It now gets its properties from the new, dedicated extension. + private Wula_BeamPierce_Extension Props => def.GetModExtension(); + + public override Vector3 ExactPosition => destination + Vector3.up * def.Altitude; + + public override void Launch(Thing launcher, Vector3 origin, LocalTargetInfo usedTarget, LocalTargetInfo intendedTarget, ProjectileHitFlags hitFlags, bool preventFriendlyFire = false, Thing equipment = null, ThingDef targetCoverDef = null) + { + base.Launch(launcher, origin, usedTarget, intendedTarget, hitFlags, preventFriendlyFire, equipment, targetCoverDef); + + Wula_BeamPierce_Extension props = Props; + if (props == null) + { + Log.Error("Projectile_WulaBeam requires a Wula_BeamPierce_Extension in its def."); + Destroy(DestroyMode.Vanish); + return; + } + + this.hitCounter = 0; + this.alreadyDamaged.Clear(); + + bool shouldPreventFriendlyFire = preventFriendlyFire || props.preventFriendlyFire; + + Map map = this.Map; + // --- Corrected Start Position Calculation --- + // The beam should start from the gun's muzzle, not the pawn's center. + Vector3 endPosition = usedTarget.Cell.ToVector3Shifted(); + Vector3 castPosition = origin + (endPosition - origin).Yto0().normalized * props.beamStartOffset; + + // --- Vanilla Beam Drawing Logic --- + if (props.beamMoteDef != null) + { + // Calculate the offset exactly like the vanilla Beam class does. + // The offset for the mote is calculated from the launcher's true position, not the cast position. + Vector3 moteOffset = (endPosition - launcher.Position.ToVector3Shifted()).Yto0().normalized * props.beamStartOffset; + MoteMaker.MakeInteractionOverlay(props.beamMoteDef, launcher, usedTarget.ToTargetInfo(map), moteOffset, Vector3.zero); + } + + float distance = Vector3.Distance(castPosition, endPosition); + Vector3 direction = (endPosition - castPosition).normalized; + + var thingsOnPath = new HashSet(); + for (float i = 0; i < distance; i += 1.0f) + { + IntVec3 cell = (castPosition + direction * i).ToIntVec3(); + if (cell.InBounds(map)) + { + thingsOnPath.AddRange(map.thingGrid.ThingsListAt(cell)); + } + } + // CRITICAL FIX: Manually add the intended target to the list. + // This guarantees the primary target is always processed, even if the loop sampling misses its exact cell. + if (intendedTarget.HasThing) + { + thingsOnPath.Add(intendedTarget.Thing); + } + + int maxHits = props.maxHits; + bool infinitePenetration = maxHits < 0; + + foreach (Thing thing in thingsOnPath) + { + if (!infinitePenetration && hitCounter >= maxHits) break; + + if (thing is Pawn pawn && pawn != launcher && !alreadyDamaged.Contains(pawn)) + { + bool shouldDamage = false; + if (intendedTarget.Thing == pawn) shouldDamage = true; + else if (pawn.HostileTo(launcher)) shouldDamage = true; + else if (!shouldPreventFriendlyFire) shouldDamage = true; + + if (shouldDamage) + { + ApplyPathDamage(pawn, props); + } + } + else if (thing.def.Fillage == FillCategory.Full && thing.def.blockLight) + { + break; + } + } + + this.Destroy(DestroyMode.Vanish); + } + + private void ApplyPathDamage(Pawn pawn, Wula_BeamPierce_Extension props) + { + float damageMultiplier = Mathf.Pow(1f - props.damageFalloff, hitCounter); + int damageAmount = (int)(this.DamageAmount * damageMultiplier); + + if (damageAmount <= 0) return; + + var dinfo = new DamageInfo( + this.def.projectile.damageDef, + damageAmount, + this.ArmorPenetration * damageMultiplier, + this.ExactRotation.eulerAngles.y, + this.launcher, + null, + this.equipmentDef, + DamageInfo.SourceCategory.ThingOrUnknown, + this.intendedTarget.Thing); + + pawn.TakeDamage(dinfo); + alreadyDamaged.Add(pawn); + hitCounter++; + } + + protected override void Tick() { } + protected override void Impact(Thing hitThing, bool blockedByShield = false) { } + } +} \ No newline at end of file diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj index e26f0c3c..88f58507 100644 --- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj +++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj @@ -118,6 +118,7 @@ +