diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll
index 57bc513e..09c2f082 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_WulaFallenEmpire.xml b/1.6/1.6/Defs/HediffDefs/Hediffs_WulaFallenEmpire.xml
new file mode 100644
index 00000000..04628ff3
--- /dev/null
+++ b/1.6/1.6/Defs/HediffDefs/Hediffs_WulaFallenEmpire.xml
@@ -0,0 +1,42 @@
+
+
+
+ WULA_WeaponStealEffect
+
+ 被磁力光束命中,磁力光束将会夺走当前所装备的武器.
+ HediffWithComps
+ (1,0,0.5)
+ 1.0
+ 0.0
+ true
+
+
+ 30000
+
+
+
+
+
+ 0
+
+
+
+ 0.3
+
+
+
+
+
+ 0.6
+
+
+
+
+
+ 0.9
+
+
+
+
+
+
\ No newline at end of file
diff --git a/1.6/1.6/Defs/ThingDefs_Races/Races_WulaFlyMech.xml b/1.6/1.6/Defs/ThingDefs_Races/Races_WulaFlyMech.xml
new file mode 100644
index 00000000..1dcdb550
--- /dev/null
+++ b/1.6/1.6/Defs/ThingDefs_Races/Races_WulaFlyMech.xml
@@ -0,0 +1,224 @@
+
+
+
+
+
+
+ WULA_Mech_Flyer
+
+ 乌拉帝国小型机械体
+
+
+
+ fist
+
+ Blunt
+
+ 12.0
+ 2
+ LeftHand
+ true
+
+
+
+ fist
+
+ Blunt
+
+ 12.0
+ 2
+ RightHand
+ true
+
+
+
+
+ Blunt
+
+ 8.5
+ 2
+ HeadAttackTool
+ true
+ 0.2
+
+
+
+ Lancer
+ 0.72
+
+
+ ChunkMechanoidSlag
+ 11
+ 0.1
+
+
+ ChunkMechanoidSlag
+ 12
+ 0.1
+
+
+ 0.5
+
+
+ 0
+ 30
+ 10
+
+
+
+
+
+
+
+
+ WULA_MechFlyerTurretGun
+ -90
+ false
+
+
+ PawnRenderNode_TurretGun
+ PawnRenderNodeWorker_TurretGun
+ Body
+ (1, 1)
+ 20
+ Any
+
+
+ 180
+ (0, 0, 0)
+
+
+
+
+
+
+
+
+
+ WULA_Mech_Flyer
+
+ WULA_Mech_Flyer
+ 190
+ Things/Pawn/Animal/Goose/Goose_Flying_
+ 8
+ 2
+ 1.35
+ false
+
+
+
+ Things/Pawn/Mechanoid/LancerClean
+ Things/Pawn/Mechanoid/AllegianceOverlays/Mech_Lancer
+ CutoutWithOverlay
+ Graphic_Multi
+ 1.5
+
+ (0.4, 0.8, 0.4)
+
+
+
+
+
+ Things/Pawn/Mechanoid/Lancer
+ Things/Pawn/Mechanoid/AllegianceOverlays/Mech_Lancer
+ CutoutWithOverlay
+ Graphic_Multi
+ 1.5
+
+ (0.4, 0.8, 0.4)
+
+
+
+
+ 9999~9999
+
+ MechanoidGunMedium
+
+ 1
+ 9999~9999
+
+
+
+ WULA_MechFlyerTurretGun
+
+ 乌拉小镰的内置炮塔。
+ None
+ true
+
+ Things/Building/TacticalTurret/TacticalTurret_Top
+ Graphic_Single
+
+
+ 2.6
+ 0.60
+ 0.80
+ 0.90
+ 0.85
+
+
+
+ WulaFallenEmpire.Verb_ShootWeaponStealBeam
+ WULA_WeaponStealEffect
+ 0.1
+ 1.0
+ true
+
+ true
+ 0
+ 10
+ 5
+ 50
+ Wula_Dark_Matter_Beam
+ 3
+
+
+ 1000
+ -1
+ 0
+ 0
+ 0
+
+
+ 0
+ BeamGraser_Shooting
+ Fleck_BeamBurn
+ 0.32
+ Mote_Wula_Dark_Matter_Beam
+ GraserBeam_End
+
+ 0.35
+
+
+ 0.6
+ 0.6
+ 0.25
+
+
+ true
+
+
+ (0, 0)
+ (0.65, 0.4)
+ (1, 0.75)
+
+
+
+
+
+ true
+
+
+
+ false
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/3516260226.code-workspace b/Source/WulaFallenEmpire/3516260226.code-workspace
index 3a0a3ee4..b9f86d60 100644
--- a/Source/WulaFallenEmpire/3516260226.code-workspace
+++ b/Source/WulaFallenEmpire/3516260226.code-workspace
@@ -10,6 +10,9 @@
},
{
"path": "../../../../../../workshop/content/294100/3534748687"
+ },
+ {
+ "path": "../../../../../../workshop/content/294100/3550544871"
}
],
"settings": {}
diff --git a/Source/WulaFallenEmpire/MechWeapon/CompMechWeapon.cs b/Source/WulaFallenEmpire/MechWeapon/CompMechWeapon.cs
new file mode 100644
index 00000000..84b6ff7b
--- /dev/null
+++ b/Source/WulaFallenEmpire/MechWeapon/CompMechWeapon.cs
@@ -0,0 +1,19 @@
+using Verse;
+
+namespace WulaFallenEmpire
+{
+ public class CompMechWeapon : ThingComp
+{
+ // You can add custom logic or fields here if needed for this component.
+ // For now, it primarily serves as a marker for mechanical units that can use MechWeapon features.
+}
+
+
+public class CompProperties_MechWeapon : CompProperties
+{
+ public CompProperties_MechWeapon()
+ {
+ compClass = typeof(CompMechWeapon);
+ }
+}
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/MechWeapon/FloatMenuProvider_Mech.cs b/Source/WulaFallenEmpire/MechWeapon/FloatMenuProvider_Mech.cs
new file mode 100644
index 00000000..1effef00
--- /dev/null
+++ b/Source/WulaFallenEmpire/MechWeapon/FloatMenuProvider_Mech.cs
@@ -0,0 +1,35 @@
+using System.Collections.Generic;
+using RimWorld;
+using Verse;
+using Verse.AI;
+
+namespace WulaFallenEmpire
+{
+ public class FloatMenuProvider_Mech : FloatMenuOptionProvider
+{
+ protected override bool Drafted => true;
+
+ protected override bool Undrafted => true;
+
+ protected override bool Multiselect => false;
+
+ protected override bool MechanoidCanDo => true;
+
+ public override bool SelectedPawnValid(Pawn pawn, FloatMenuContext context)
+ {
+ return base.SelectedPawnValid(pawn, context) && pawn.HasComp();
+ }
+
+ public override IEnumerable GetOptionsFor(Thing clickedThing, FloatMenuContext context)
+ {
+ Pawn pawn = context.FirstSelectedPawn;
+ if (clickedThing.def.IsWeapon && pawn.CanReserveAndReach(clickedThing, PathEndMode.Touch, Danger.Deadly))
+ {
+ yield return new FloatMenuOption("Equip".Translate(clickedThing.Label), delegate
+ {
+ pawn.jobs.StartJob(JobMaker.MakeJob(JobDefOf.Equip, clickedThing));
+ });
+ }
+ }
+}
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/MechWeapon/Patch_MissingWeapon.cs b/Source/WulaFallenEmpire/MechWeapon/Patch_MissingWeapon.cs
new file mode 100644
index 00000000..b8a4b838
--- /dev/null
+++ b/Source/WulaFallenEmpire/MechWeapon/Patch_MissingWeapon.cs
@@ -0,0 +1,19 @@
+using HarmonyLib;
+using RimWorld;
+using Verse;
+
+namespace WulaFallenEmpire
+{
+ [HarmonyPatch(typeof(MechRepairUtility), "IsMissingWeapon")]
+public class Patch_MissingWeapon
+{
+ [HarmonyPostfix]
+ private static void PostFix(ref bool __result, Pawn mech)
+ {
+ if (mech.HasComp())
+ {
+ __result = false;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/MechWeapon/Patch_WeaponDrop.cs b/Source/WulaFallenEmpire/MechWeapon/Patch_WeaponDrop.cs
new file mode 100644
index 00000000..43253945
--- /dev/null
+++ b/Source/WulaFallenEmpire/MechWeapon/Patch_WeaponDrop.cs
@@ -0,0 +1,53 @@
+using HarmonyLib;
+using RimWorld;
+using Verse;
+
+namespace WulaFallenEmpire
+{
+ [HarmonyPatch(typeof(Pawn), "DropAndForbidEverything")]
+public class Patch_WeaponDrop
+{
+ [HarmonyPrefix]
+ private static bool PreFix(ref Pawn __instance, bool keepInventoryAndEquipmentIfInBed, bool rememberPrimary)
+ {
+ if (__instance.HasComp())
+ {
+ if (!__instance.InContainerEnclosed)
+ {
+ if (__instance.SpawnedOrAnyParentSpawned)
+ {
+ if (__instance.carryTracker?.CarriedThing != null)
+ {
+ __instance.carryTracker.TryDropCarriedThing(__instance.PositionHeld, ThingPlaceMode.Near, out var _);
+ }
+ if (!keepInventoryAndEquipmentIfInBed || !__instance.InBed())
+ {
+ __instance.equipment?.DropAllEquipment(__instance.PositionHeld, forbid: true, rememberPrimary);
+ if (__instance.inventory != null && __instance.inventory.innerContainer.TotalStackCount > 0)
+ {
+ __instance.inventory.DropAllNearPawn(__instance.PositionHeld, forbid: true);
+ }
+ }
+ }
+ return false;
+ }
+ if (__instance.carryTracker?.CarriedThing != null)
+ {
+ __instance.carryTracker.innerContainer.TryTransferToContainer(__instance.carryTracker.CarriedThing, __instance.holdingOwner);
+ }
+ if (__instance.equipment?.Primary != null)
+ {
+ __instance.equipment.TryTransferEquipmentToContainer(__instance.equipment.Primary, __instance.holdingOwner);
+ }
+ Pawn_InventoryTracker inventory = __instance.inventory;
+ if (inventory == null)
+ {
+ return false;
+ }
+ inventory.innerContainer.TryTransferAllToContainer(__instance.holdingOwner);
+ return false;
+ }
+ return true;
+ }
+}
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/Verb/VerbProperties_WeaponStealBeam.cs b/Source/WulaFallenEmpire/Verb/VerbProperties_WeaponStealBeam.cs
new file mode 100644
index 00000000..a7899348
--- /dev/null
+++ b/Source/WulaFallenEmpire/Verb/VerbProperties_WeaponStealBeam.cs
@@ -0,0 +1,18 @@
+using RimWorld;
+using Verse;
+
+namespace WulaFallenEmpire
+{
+ public class VerbProperties_WeaponStealBeam : VerbPropertiesExplosiveBeam
+ {
+ public HediffDef hediffToApply;
+ public float hediffSeverityPerHit = 0.1f; // 每次命中增加的严重性百分比
+ public float hediffMaxSeverity = 1.0f; // 达到此严重性时触发抢夺
+ public bool removeHediffOnSteal = true; // 抢夺后是否移除hediff
+
+ public VerbProperties_WeaponStealBeam()
+ {
+ verbClass = typeof(Verb_ShootWeaponStealBeam);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/Verb/Verb_ShootWeaponStealBeam.cs b/Source/WulaFallenEmpire/Verb/Verb_ShootWeaponStealBeam.cs
new file mode 100644
index 00000000..98ab521f
--- /dev/null
+++ b/Source/WulaFallenEmpire/Verb/Verb_ShootWeaponStealBeam.cs
@@ -0,0 +1,167 @@
+using RimWorld;
+using Verse;
+using System.Linq;
+using System.Collections.Generic;
+using UnityEngine; // For Vector3
+using Verse.Sound; // For SoundDef.PlayOneShot
+using Verse.AI; // For JobQueue
+
+namespace WulaFallenEmpire
+{
+ public class Verb_ShootWeaponStealBeam : Verse.Verb_ShootBeam
+ {
+ private int explosionShotCounter = 0;
+
+ protected VerbProperties_WeaponStealBeam StealBeamVerbProps => (VerbProperties_WeaponStealBeam)verbProps;
+
+ protected override bool TryCastShot()
+ {
+ bool result = base.TryCastShot();
+
+ // 如果光束命中,对目标Pawn施加Hediff并检查是否抢夺武器
+ if (result && currentTarget.Thing is Pawn targetPawn && targetPawn.RaceProps.Humanlike) // 只对人形Pawn生效
+ {
+ ApplyHediffAndCheckForSteal(targetPawn);
+ }
+
+ 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 // 新增:屏幕震动因子
+ );
+
+ // 在这里添加武器抢夺和Hediff施加的逻辑(爆炸命中目标时)
+ if (currentTarget.Thing is Pawn targetPawn && targetPawn.RaceProps.Humanlike) // 只对人形Pawn生效
+ {
+ ApplyHediffAndCheckForSteal(targetPawn);
+ }
+
+ // 生成额外的视觉效果
+ if (explosiveProps.explosionEffecter != null)
+ {
+ Effecter effecter = explosiveProps.explosionEffecter.Spawn(explosionCell, caster.Map);
+ effecter.Trigger(new TargetInfo(explosionCell, caster.Map), TargetInfo.Invalid);
+ effecter.Cleanup();
+ }
+ }
+
+ private void ApplyHediffAndCheckForSteal(Pawn targetPawn)
+ {
+ if (StealBeamVerbProps.hediffToApply == null)
+ {
+ return;
+ }
+
+ Hediff hediff = targetPawn.health.hediffSet.GetFirstHediffOfDef(StealBeamVerbProps.hediffToApply);
+
+ if (hediff == null)
+ {
+ hediff = HediffMaker.MakeHediff(StealBeamVerbProps.hediffToApply, targetPawn);
+ targetPawn.health.AddHediff(hediff);
+ }
+
+ hediff.Severity += StealBeamVerbProps.hediffSeverityPerHit;
+
+ if (hediff.Severity >= StealBeamVerbProps.hediffMaxSeverity)
+ {
+ TryStealWeapon(targetPawn);
+ if (StealBeamVerbProps.removeHediffOnSteal)
+ {
+ targetPawn.health.RemoveHediff(hediff);
+ }
+ }
+ }
+
+ private void TryStealWeapon(Pawn targetPawn)
+ {
+ if (!CasterIsPawn || CasterPawn == null)
+ {
+ return;
+ }
+
+ // 获取目标Pawn的装备武器
+ ThingWithComps targetWeapon = targetPawn.equipment?.Primary;
+
+ if (targetWeapon != null)
+ {
+ // 将武器从目标Pawn身上移除
+ targetPawn.equipment.Remove(targetWeapon);
+
+ // 将武器添加到发射者(宿主)的库存中
+ if (!CasterPawn.inventory.innerContainer.TryAdd(targetWeapon))
+ {
+ // 如果无法添加到库存,则尝试丢弃在地上
+ GenPlace.TryPlaceThing(targetWeapon, CasterPawn.Position, CasterPawn.Map, ThingPlaceMode.Near);
+ return; // 如果丢弃了,就不尝试装备了
+ }
+
+ // 让发射者装备该武器
+ if (CasterPawn.equipment.Primary == null || CasterPawn.equipment.Primary.def != targetWeapon.def)
+ {
+ CasterPawn.jobs.StartJob(JobMaker.MakeJob(JobDefOf.Equip, targetWeapon), JobCondition.InterruptForced);
+ }
+ }
+ }
+
+ public override void ExposeData()
+ {
+ base.ExposeData();
+ Scribe_Values.Look(ref explosionShotCounter, "explosionShotCounter", 0);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
index bacd2e67..594ee04f 100644
--- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
+++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
@@ -12,7 +12,7 @@
v4.8
512
true
- 8.0
+ 11.0
false
@@ -170,6 +170,12 @@
+
+
+
+
+
+