diff --git a/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/Assemblies/WulaFallenEmpire.dll
index 19223ace..526dcabc 100644
Binary files a/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/Assemblies/WulaFallenEmpire.dll differ
diff --git a/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon.xml b/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon.xml
index 6706ae8a..40edb8f5 100644
--- a/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon.xml
+++ b/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon.xml
@@ -1516,10 +1516,10 @@
50000
20
- 0.6
- 0.6
- 0.6
- 0.4
+ 0.03
+ 0.03
+ 0.03
+ 0.02
4.0
@@ -1529,7 +1529,7 @@
- Verb_Shoot
+ WulaFallenEmpire.Verb_ShootShotgun
true
Bullet_WULA_RW_Handle_Cannon
1.5
@@ -1587,9 +1587,14 @@
Vaporize
75
300
- 3.9
+ 1.1
1.5
+
+
+ 6
+
+
@@ -1741,7 +1746,25 @@
Graphic_Single
TransparentPostLight
- Projectile_Explosive
+ WulaFallenEmpire.Projectile_CruiseMissile
+
+
+
+ Bomb
+ 25
+ 3.5
+ MortarBomb_Explode
+
+
+ true
+ 4
+ 1.5
+ 10
+ 6
+ Bomb
+ MortarBomb_Explode
+
+
Bomb
25
diff --git a/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/.suo b/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/.suo
index ae8edb35..b0e55347 100644
Binary files a/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/.suo and b/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/.suo differ
diff --git a/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/DocumentLayout.json b/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/DocumentLayout.json
index 04fc36e1..7560d32c 100644
--- a/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/DocumentLayout.json
+++ b/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/DocumentLayout.json
@@ -3,16 +3,16 @@
"WorkspaceRootPath": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\",
"Documents": [
{
- "AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|c:\\steam\\steamapps\\common\\rimworld\\mods\\3516260226\\source\\wulafallenempire\\eventsystem\\effect.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:eventsystem\\effect.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|c:\\steam\\steamapps\\common\\rimworld\\mods\\3516260226\\source\\wulafallenempire\\verb\\trackingbullet.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:verb\\trackingbullet.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
- "AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|c:\\steam\\steamapps\\common\\rimworld\\mods\\3516260226\\source\\wulafallenempire\\eventsystem\\debugactions.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:eventsystem\\debugactions.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|c:\\steam\\steamapps\\common\\rimworld\\mods\\3516260226\\source\\wulafallenempire\\verb\\propershotgun.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:verb\\propershotgun.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
- "AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\eventsystem\\compopencustomui.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:eventsystem\\compopencustomui.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\Verb\\VerbPropertiesExplosiveBeam.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:Verb\\VerbPropertiesExplosiveBeam.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\eventsystem\\dialog_customdisplay.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
@@ -22,9 +22,25 @@
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\eventsystem\\condition.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:eventsystem\\condition.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
+ {
+ "AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\eventsystem\\compopencustomui.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:eventsystem\\compopencustomui.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\eventsystem\\debugactions.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:eventsystem\\debugactions.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\eventsystem\\effect.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:eventsystem\\effect.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
{
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\CustomUIDef.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:EventSystem\\CustomUIDef.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\Verb\\Verb_ShootBeamExplosive.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:Verb\\Verb_ShootBeamExplosive.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
@@ -34,28 +50,79 @@
"DocumentGroups": [
{
"DockedWidth": 200,
- "SelectedChildIndex": 1,
+ "SelectedChildIndex": 0,
"Children": [
+ {
+ "$type": "Document",
+ "DocumentIndex": 0,
+ "Title": "Trackingbullet.cs",
+ "DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\Verb\\Trackingbullet.cs",
+ "RelativeDocumentMoniker": "Verb\\Trackingbullet.cs",
+ "ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\Verb\\Trackingbullet.cs",
+ "RelativeToolTip": "Verb\\Trackingbullet.cs",
+ "ViewState": "AQIAAAAAAAAAAAAAAADwvwYAAAAaAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-07-31T17:19:18.131Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 1,
+ "Title": "ProperShotgun.cs",
+ "DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\Verb\\ProperShotgun.cs",
+ "RelativeDocumentMoniker": "Verb\\ProperShotgun.cs",
+ "ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\Verb\\ProperShotgun.cs",
+ "RelativeToolTip": "Verb\\ProperShotgun.cs",
+ "ViewState": "AQIAABUAAAAAAAAAAAAIwAgAAAAaAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-07-31T17:19:04.819Z",
+ "EditorCaption": ""
+ },
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
},
{
"$type": "Document",
- "DocumentIndex": 0,
- "Title": "Effect.cs",
- "DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\Effect.cs",
- "RelativeDocumentMoniker": "EventSystem\\Effect.cs",
- "ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\Effect.cs*",
- "RelativeToolTip": "EventSystem\\Effect.cs*",
- "ViewState": "AQIAAAAAAAAAAAAAAAAAACICAAACAAAA",
+ "DocumentIndex": 2,
+ "Title": "VerbPropertiesExplosiveBeam.cs",
+ "DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\Verb\\VerbPropertiesExplosiveBeam.cs",
+ "RelativeDocumentMoniker": "Verb\\VerbPropertiesExplosiveBeam.cs",
+ "ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\Verb\\VerbPropertiesExplosiveBeam.cs",
+ "RelativeToolTip": "Verb\\VerbPropertiesExplosiveBeam.cs",
+ "ViewState": "AQIAAAAAAAAAAAAAAADwvwAAAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2025-07-31T16:05:42.638Z",
+ "WhenOpened": "2025-07-31T17:16:20.591Z",
"EditorCaption": ""
},
{
"$type": "Document",
- "DocumentIndex": 2,
+ "DocumentIndex": 9,
+ "Title": "Verb_ShootBeamExplosive.cs",
+ "DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\Verb\\Verb_ShootBeamExplosive.cs",
+ "RelativeDocumentMoniker": "Verb\\Verb_ShootBeamExplosive.cs",
+ "ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\Verb\\Verb_ShootBeamExplosive.cs",
+ "RelativeToolTip": "Verb\\Verb_ShootBeamExplosive.cs",
+ "ViewState": "AQIAAAAAAAAAAAAAAADwvwYAAAAaAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-07-31T17:12:13.033Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 7,
+ "Title": "Effect.cs",
+ "DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\Effect.cs",
+ "RelativeDocumentMoniker": "EventSystem\\Effect.cs",
+ "ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\Effect.cs",
+ "RelativeToolTip": "EventSystem\\Effect.cs",
+ "ViewState": "AQIAAAAAAAAAAAAAAAAAACICAAAAAAAA",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2025-07-31T16:05:42.638Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 5,
"Title": "CompOpenCustomUI.cs",
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\CompOpenCustomUI.cs",
"RelativeDocumentMoniker": "EventSystem\\CompOpenCustomUI.cs",
@@ -79,7 +146,7 @@
},
{
"$type": "Document",
- "DocumentIndex": 1,
+ "DocumentIndex": 6,
"Title": "DebugActions.cs",
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\DebugActions.cs",
"RelativeDocumentMoniker": "EventSystem\\DebugActions.cs",
@@ -87,12 +154,11 @@
"RelativeToolTip": "EventSystem\\DebugActions.cs",
"ViewState": "AQIAAAAAAAAAAAAAAADwvxoAAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2025-07-27T10:59:11.817Z",
- "EditorCaption": ""
+ "WhenOpened": "2025-07-27T10:59:11.817Z"
},
{
"$type": "Document",
- "DocumentIndex": 5,
+ "DocumentIndex": 8,
"Title": "CustomUIDef.cs",
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\CustomUIDef.cs",
"RelativeDocumentMoniker": "EventSystem\\CustomUIDef.cs",
@@ -110,7 +176,7 @@
"RelativeDocumentMoniker": "EventSystem\\Condition.cs",
"ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\Condition.cs",
"RelativeToolTip": "EventSystem\\Condition.cs",
- "ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAA==",
+ "ViewState": "AQIAAAAAAAAAAAAAAADwvwAAAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-07-27T10:50:26.799Z"
}
diff --git a/Source/WulaFallenEmpire/Verb/ProperShotgun.cs b/Source/WulaFallenEmpire/Verb/ProperShotgun.cs
new file mode 100644
index 00000000..bf763c1e
--- /dev/null
+++ b/Source/WulaFallenEmpire/Verb/ProperShotgun.cs
@@ -0,0 +1,63 @@
+using RimWorld;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Verse;
+
+namespace WulaFallenEmpire
+{
+ public class Verb_ShootShotgun : Verb_LaunchProjectile
+ {
+ protected override int ShotsPerBurst
+ {
+ get
+ {
+ return this.verbProps.burstShotCount;
+ }
+ }
+
+ public override void WarmupComplete()
+ {
+ base.WarmupComplete();
+ Pawn pawn = this.currentTarget.Thing as Pawn;
+ if (pawn != null && !pawn.Downed && this.CasterIsPawn && this.CasterPawn.skills != null)
+ {
+ float num = pawn.HostileTo(this.caster) ? 170f : 20f;
+ float num2 = this.verbProps.AdjustedFullCycleTime(this, this.CasterPawn);
+ this.CasterPawn.skills.Learn(SkillDefOf.Shooting, num * num2, false, false);
+ }
+ }
+
+ protected override bool TryCastShot()
+ {
+ bool flag = base.TryCastShot();
+ if (flag && this.CasterIsPawn)
+ {
+ this.CasterPawn.records.Increment(RecordDefOf.ShotsFired);
+ }
+ ShotgunExtension shotgunExtension = ShotgunExtension.Get(this.verbProps.defaultProjectile);
+ if (flag && shotgunExtension.pelletCount - 1 > 0)
+ {
+ for (int i = 0; i < shotgunExtension.pelletCount - 1; i++)
+ {
+ base.TryCastShot();
+ }
+ }
+ return flag;
+ }
+ }
+
+ public class ShotgunExtension : DefModExtension
+ {
+ public static ShotgunExtension Get(Def def)
+ {
+ return def.GetModExtension() ?? ShotgunExtension.defaultValues;
+ }
+
+ private static readonly ShotgunExtension defaultValues = new ShotgunExtension();
+
+ public int pelletCount = 1;
+ }
+}
diff --git a/Source/WulaFallenEmpire/Verb/Trackingbullet.cs b/Source/WulaFallenEmpire/Verb/Trackingbullet.cs
new file mode 100644
index 00000000..5ec0686c
--- /dev/null
+++ b/Source/WulaFallenEmpire/Verb/Trackingbullet.cs
@@ -0,0 +1,178 @@
+using RimWorld;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using Verse;
+
+namespace WulaFallenEmpire
+{
+ public class CruiseMissileProperties : DefModExtension
+ {
+ public DamageDef customDamageDef;
+ public int customDamageAmount = 5;
+ public float customExplosionRadius = 1.1f;
+ public SoundDef customSoundExplode;
+
+ public bool useSubExplosions = true;
+ public int subExplosionCount = 3;
+ public float subExplosionRadius = 1.9f;
+ public int subExplosionDamage = 30;
+ public float subExplosionSpread = 6f;
+ public DamageDef subDamageDef;
+ public SoundDef subSoundExplode;
+
+ }
+
+ public class Projectile_CruiseMissile : Projectile_Explosive
+ {
+ private CruiseMissileProperties settings;
+ private bool flag2;
+ private Vector3 Randdd;
+ private Vector3 position2;
+ public Vector3 ExPos;
+
+ public override void SpawnSetup(Map map, bool respawningAfterLoad)
+ {
+ base.SpawnSetup(map, respawningAfterLoad);
+ settings = def.GetModExtension() ?? new CruiseMissileProperties();
+ }
+
+ private void RandFactor()
+ {
+ // 减少垂直方向随机性,调整水平随机范围
+ Randdd = new Vector3(
+ Rand.Range(-3f, 3f), // 减小水平随机范围
+ Rand.Range(8f, 12f), // 降低基础高度
+ Rand.Range(-3f, 3f)
+ );
+ flag2 = true;
+ }
+
+ public Vector3 BPos(float t)
+ {
+ if (!flag2) RandFactor();
+
+ // 计算水平距离
+ float horizontalDistance = Vector3.Distance(new Vector3(origin.x, 0, origin.z),
+ new Vector3(destination.x, 0, destination.z));
+
+ // 动态调整控制点高度
+ float arcHeight = Mathf.Clamp(horizontalDistance * 0.2f, 8f, 15f);
+
+ Vector3 a = origin + Vector3.forward * horizontalDistance * 0.2f + new Vector3(0f, arcHeight, 0f);
+ Vector3 a2 = destination - Vector3.forward * horizontalDistance * 0.2f + new Vector3(0f, arcHeight, 0f);
+
+ return BezierCurve(origin, a, a2, destination, t);
+ }
+
+ private Vector3 BezierCurve(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
+ {
+ float u = 1 - t;
+ return u * u * u * p0
+ + 3 * u * u * t * p1
+ + 3 * u * t * t * p2
+ + t * t * t * p3;
+ }
+
+ private IEnumerable GetValidCells(Map map)
+ {
+ if (map == null || settings == null) yield break;
+
+ var cells = GenRadial.RadialCellsAround(
+ base.Position,
+ settings.subExplosionSpread,
+ false
+ ).Where(c => c.InBounds(map));
+
+ var randomizedCells = cells.InRandomOrder().Take(settings.subExplosionCount);
+
+ foreach (var cell in randomizedCells)
+ {
+ yield return cell;
+ }
+ }
+
+ protected override void Impact(Thing hitThing, bool blockedByShield = false)
+ {
+ var map = base.Map;
+ base.Impact(hitThing, blockedByShield);
+
+ DoExplosion(
+ base.Position,
+ map,
+ settings.customExplosionRadius,
+ settings.customDamageDef,
+ settings.customDamageAmount,
+ settings.customSoundExplode
+ );
+
+ if (settings.useSubExplosions)
+ {
+ foreach (var cell in GetValidCells(map))
+ {
+ DoExplosion(
+ cell,
+ map,
+ settings.subExplosionRadius,
+ settings.subDamageDef,
+ settings.subExplosionDamage,
+ settings.subSoundExplode
+ );
+ }
+ }
+ }
+
+ private void DoExplosion(IntVec3 pos, Map map, float radius, DamageDef dmgDef, int dmgAmount, SoundDef sound)
+ {
+ GenExplosion.DoExplosion(
+ pos,
+ map,
+ radius,
+ dmgDef,
+ launcher,
+ dmgAmount,
+ ArmorPenetration,
+ sound
+ );
+ }
+
+ protected override void DrawAt(Vector3 position, bool flip = false)
+ {
+ position2 = BPos(DistanceCoveredFraction - 0.01f);
+ ExPos = position = BPos(DistanceCoveredFraction);
+ base.DrawAt(position, flip);
+ }
+
+ protected override void Tick()
+ {
+ if (intendedTarget.Thing is Pawn pawn && pawn.Spawned && !pawn.Destroyed)
+ {
+ if ((pawn.Dead || pawn.Downed) && DistanceCoveredFraction < 0.6f)
+ {
+ FindNextTarget(pawn.DrawPos);
+ }
+ destination = pawn.DrawPos;
+ }
+ base.Tick();
+ }
+
+ private void FindNextTarget(Vector3 center)
+ {
+ var map = base.Map;
+ if (map == null) return;
+
+ foreach (IntVec3 cell in GenRadial.RadialCellsAround(IntVec3.FromVector3(center), 7f, true))
+ {
+ if (!cell.InBounds(map)) continue;
+
+ Pawn target = cell.GetFirstPawn(map);
+ if (target != null && target.Faction.HostileTo(launcher?.Faction))
+ {
+ intendedTarget = target;
+ return;
+ }
+ }
+ intendedTarget = CellRect.CenteredOn(IntVec3.FromVector3(center), 7).RandomCell;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/Verb/VerbPropertiesExplosiveBeam.cs b/Source/WulaFallenEmpire/Verb/VerbPropertiesExplosiveBeam.cs
new file mode 100644
index 00000000..0cbbc66f
--- /dev/null
+++ b/Source/WulaFallenEmpire/Verb/VerbPropertiesExplosiveBeam.cs
@@ -0,0 +1,50 @@
+using RimWorld;
+using Verse;
+using Verse.Sound;
+
+namespace WulaFallenEmpire
+{
+ public class VerbPropertiesExplosiveBeam : VerbProperties
+ {
+ // 爆炸开关
+ public bool enableExplosion = false;
+
+ // 每x个shotcount触发一次爆炸
+ public int explosionShotInterval = 1;
+
+ // 爆炸基础属性
+ public float explosionRadius = 2.9f;
+ public DamageDef explosionDamageDef = null; // null时使用默认的Bomb
+ public int explosionDamage = -1; // -1时使用武器默认伤害
+ public float explosionArmorPenetration = -1f; // -1时使用武器默认穿甲
+
+ // 爆炸音效和特效
+ public SoundDef explosionSound = null;
+ public EffecterDef explosionEffecter = null;
+
+ // 爆炸后生成物品
+ public ThingDef postExplosionSpawnThingDef = null;
+ public float postExplosionSpawnChance = 0f;
+ public int postExplosionSpawnThingCount = 1;
+
+ // 爆炸前生成物品
+ public ThingDef preExplosionSpawnThingDef = null;
+ public float preExplosionSpawnChance = 0f;
+ public int preExplosionSpawnThingCount = 1;
+
+ // 气体效果
+ public GasType? postExplosionGasType = null;
+
+ // 其他爆炸属性
+ public bool applyDamageToExplosionCellsNeighbors = true;
+ public float chanceToStartFire = 0f;
+ public bool damageFalloff = true;
+ public float screenShakeFactor = 0f; // 新增:屏幕震动因子
+
+ public VerbPropertiesExplosiveBeam()
+ {
+ // 设置默认值
+ verbClass = typeof(Verb_ShootBeamExplosive);
+ }
+ }
+}
diff --git a/Source/WulaFallenEmpire/Verb/Verb_ShootBeamExplosive.cs b/Source/WulaFallenEmpire/Verb/Verb_ShootBeamExplosive.cs
new file mode 100644
index 00000000..b75e18a3
--- /dev/null
+++ b/Source/WulaFallenEmpire/Verb/Verb_ShootBeamExplosive.cs
@@ -0,0 +1,93 @@
+using System.Collections.Generic;
+using RimWorld;
+using UnityEngine;
+using Verse;
+using Verse.Sound;
+
+namespace WulaFallenEmpire
+{
+ public class Verb_ShootBeamExplosive : Verse.Verb_ShootBeam
+ {
+ private int explosionShotCounter = 0;
+
+ protected override bool TryCastShot()
+ {
+ bool result = base.TryCastShot();
+
+ if (result && verbProps is VerbPropertiesExplosiveBeam explosiveProps && explosiveProps.enableExplosion)
+ {
+ explosionShotCounter++;
+
+ if (explosionShotCounter >= explosiveProps.explosionShotInterval)
+ {
+ explosionShotCounter = 0;
+ TriggerExplosion(explosiveProps);
+ }
+ }
+
+ return result;
+ }
+
+ private void TriggerExplosion(VerbPropertiesExplosiveBeam explosiveProps)
+ {
+ Vector3 explosionPos = InterpolatedPosition;
+ IntVec3 explosionCell = explosionPos.ToIntVec3();
+
+ if (!explosionCell.InBounds(caster.Map))
+ return;
+
+ // 播放爆炸音效
+ if (explosiveProps.explosionSound != null)
+ {
+ explosiveProps.explosionSound.PlayOneShot(new TargetInfo(explosionCell, caster.Map));
+ }
+
+ // 生成爆炸
+ GenExplosion.DoExplosion(
+ center: explosionCell,
+ map: caster.Map,
+ radius: explosiveProps.explosionRadius,
+ damType: explosiveProps.explosionDamageDef ?? DamageDefOf.Bomb,
+ instigator: caster,
+ damAmount: explosiveProps.explosionDamage > 0 ? explosiveProps.explosionDamage : verbProps.defaultProjectile?.projectile?.GetDamageAmount(EquipmentSource) ?? 20,
+ armorPenetration: explosiveProps.explosionArmorPenetration >= 0 ? explosiveProps.explosionArmorPenetration : verbProps.defaultProjectile?.projectile?.GetArmorPenetration(EquipmentSource) ?? 0.3f,
+ explosionSound: null, // 我们已经手动播放了音效
+ weapon: base.EquipmentSource?.def,
+ projectile: null,
+ intendedTarget: currentTarget.Thing,
+ postExplosionSpawnThingDef: explosiveProps.postExplosionSpawnThingDef,
+ postExplosionSpawnChance: explosiveProps.postExplosionSpawnChance,
+ postExplosionSpawnThingCount: explosiveProps.postExplosionSpawnThingCount,
+ postExplosionGasType: explosiveProps.postExplosionGasType,
+ applyDamageToExplosionCellsNeighbors: explosiveProps.applyDamageToExplosionCellsNeighbors,
+ preExplosionSpawnThingDef: explosiveProps.preExplosionSpawnThingDef,
+ preExplosionSpawnChance: explosiveProps.preExplosionSpawnChance,
+ preExplosionSpawnThingCount: explosiveProps.preExplosionSpawnThingCount,
+ chanceToStartFire: explosiveProps.chanceToStartFire,
+ damageFalloff: explosiveProps.damageFalloff,
+ direction: null,
+ ignoredThings: null,
+ affectedAngle: null,
+ doVisualEffects: true,
+ propagationSpeed: 0.6f,
+ excludeRadius: 0f,
+ doSoundEffects: false, // 我们手动处理音效
+ screenShakeFactor: explosiveProps.screenShakeFactor // 新增:屏幕震动因子
+ );
+
+ // 生成额外的视觉效果
+ if (explosiveProps.explosionEffecter != null)
+ {
+ Effecter effecter = explosiveProps.explosionEffecter.Spawn(explosionCell, caster.Map);
+ effecter.Trigger(new TargetInfo(explosionCell, caster.Map), TargetInfo.Invalid);
+ effecter.Cleanup();
+ }
+ }
+
+ public override void ExposeData()
+ {
+ base.ExposeData();
+ Scribe_Values.Look(ref explosionShotCounter, "explosionShotCounter", 0);
+ }
+ }
+}
diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
index 6ac4beef..c736738f 100644
--- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
+++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
@@ -112,6 +112,8 @@
+
+