暂存
This commit is contained in:
@@ -10,6 +10,9 @@
|
||||
},
|
||||
{
|
||||
"path": "../../../../../../workshop/content/294100/3534748687"
|
||||
},
|
||||
{
|
||||
"path": "../../../../../../workshop/content/294100/3550544871"
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
|
||||
19
Source/WulaFallenEmpire/MechWeapon/CompMechWeapon.cs
Normal file
19
Source/WulaFallenEmpire/MechWeapon/CompMechWeapon.cs
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Source/WulaFallenEmpire/MechWeapon/FloatMenuProvider_Mech.cs
Normal file
35
Source/WulaFallenEmpire/MechWeapon/FloatMenuProvider_Mech.cs
Normal file
@@ -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<CompMechWeapon>();
|
||||
}
|
||||
|
||||
public override IEnumerable<FloatMenuOption> 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));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
Source/WulaFallenEmpire/MechWeapon/Patch_MissingWeapon.cs
Normal file
19
Source/WulaFallenEmpire/MechWeapon/Patch_MissingWeapon.cs
Normal file
@@ -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<CompMechWeapon>())
|
||||
{
|
||||
__result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
53
Source/WulaFallenEmpire/MechWeapon/Patch_WeaponDrop.cs
Normal file
53
Source/WulaFallenEmpire/MechWeapon/Patch_WeaponDrop.cs
Normal file
@@ -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<CompMechWeapon>())
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
167
Source/WulaFallenEmpire/Verb/Verb_ShootWeaponStealBeam.cs
Normal file
167
Source/WulaFallenEmpire/Verb/Verb_ShootWeaponStealBeam.cs
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<LangVersion>11.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
@@ -170,6 +170,12 @@
|
||||
<Compile Include="WULA_Shuttle\ArmedShuttleIncoming.cs" />
|
||||
<Compile Include="WULA_Shuttle\Building_ArmedShuttle.cs" />
|
||||
<Compile Include="HarmonyPatches\Patch_DropCellFinder_SkyfallerCanLandAt.cs" />
|
||||
<Compile Include="MechWeapon\FloatMenuProvider_Mech.cs" />
|
||||
<Compile Include="MechWeapon\Patch_MissingWeapon.cs" />
|
||||
<Compile Include="MechWeapon\Patch_WeaponDrop.cs" />
|
||||
<Compile Include="MechWeapon\CompMechWeapon.cs" />
|
||||
<Compile Include="Verb\VerbProperties_WeaponStealBeam.cs" />
|
||||
<Compile Include="Verb\Verb_ShootWeaponStealBeam.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
|
||||
Reference in New Issue
Block a user