diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll
index f6ffb914..48a8b88f 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/ThingDefs_Misc/Weapons/WULA_Weapon_Homing_Examples_Bullet_Homing.xml b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon_Homing_Examples_Bullet_Homing.xml
index b55c3dd7..1469f9f1 100644
--- a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon_Homing_Examples_Bullet_Homing.xml
+++ b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon_Homing_Examples_Bullet_Homing.xml
@@ -40,15 +40,18 @@
- Verb_Shoot
+ WulaFallenEmpire.Verb_ShootShotgun
true
Bullet_ExampleHoming
- 1.0
- 35
- 1
- Shot_ChargeRifle
+ 2.0
+ 28
+ 3
+ 12
+ Shot_BeamRepeater
GunTail_Medium
9
+ Mote_BeamRepeater_Charge
+ 1.07
@@ -64,7 +67,7 @@
Bullet_ExampleHoming
- Things/Projectile/Bullet_Big
+ Things/Projectile/Charge_Small
Graphic_Single
WulaFallenEmpire.Projectile_TrackingBullet
@@ -77,7 +80,7 @@
- 0.5
+ 0.1
30
60
@@ -85,6 +88,9 @@
WULA_GunTail_Blue
+
+ 3
+
\ No newline at end of file
diff --git a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon_Homing_Examples_Bullet_HomingExplosive.xml b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon_Homing_Examples_Bullet_HomingExplosive.xml
index 0c5ee6cd..9c3637fa 100644
--- a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon_Homing_Examples_Bullet_HomingExplosive.xml
+++ b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon_Homing_Examples_Bullet_HomingExplosive.xml
@@ -65,41 +65,31 @@
Bullet_ExampleHomingExplosive
- Things/Projectile/Bullet_Big
+ Things/Projectile/Charge_Small
Graphic_Single
- WulaFallenEmpire.Projectile_TrackingBullet
+ WulaFallenEmpire.Projectile_ExplosiveTrackingBullet
- 25
+ 60
Bomb
30
0.7
2.0
- 3.0
- 60
- 1.0
- true
- 1.0
- 5
- 0.5
- true
- true
+
+ 3.0
+ Bomb
+
- 0.5
- 5
+ 0.1
+ 15
60
120
- Mote_BlastFlame
- 3
- 1
- 30
- 0.8~1.2
- 0.2~0.5
- 0~360
+ WULA_GunTail_Blue
+ 1
diff --git a/Source/WulaFallenEmpire/ExplosiveTrackingBulletDef.cs b/Source/WulaFallenEmpire/ExplosiveTrackingBulletDef.cs
index e98fcc79..53097bbc 100644
--- a/Source/WulaFallenEmpire/ExplosiveTrackingBulletDef.cs
+++ b/Source/WulaFallenEmpire/ExplosiveTrackingBulletDef.cs
@@ -14,6 +14,11 @@ namespace WulaFallenEmpire
public float postExplosionSpawnChance = 0f;
public int postExplosionSpawnThingCount = 1;
public GasType? gasType; // 修改为可空类型
+ public ThingDef postExplosionSpawnThingDefWater; // 新增
+ public ThingDef preExplosionSpawnThingDef; // 新增
+ public float preExplosionSpawnChance = 0f; // 新增
+ public int preExplosionSpawnThingCount = 0; // 新增
+ public float screenShakeFactor = 1f; // 新增
public bool applyDamageToExplosionCellsNeighbors = false;
public bool doExplosionDamageAfterThingDestroyed = false;
public float preExplosionSpawnMinMeleeThreat = -1f;
diff --git a/Source/WulaFallenEmpire/Projectile_ExplosiveTrackingBullet.cs b/Source/WulaFallenEmpire/Projectile_ExplosiveTrackingBullet.cs
index 2c407f2e..eeddb204 100644
--- a/Source/WulaFallenEmpire/Projectile_ExplosiveTrackingBullet.cs
+++ b/Source/WulaFallenEmpire/Projectile_ExplosiveTrackingBullet.cs
@@ -8,6 +8,7 @@ namespace WulaFallenEmpire
public class Projectile_ExplosiveTrackingBullet : Projectile_TrackingBullet
{
private ExplosiveTrackingBulletDef explosiveDefInt;
+ private int ticksToDetonation;
public ExplosiveTrackingBulletDef ExplosiveDef
{
@@ -26,52 +27,156 @@ namespace WulaFallenEmpire
}
}
+ public override void ExposeData()
+ {
+ base.ExposeData();
+ Scribe_Values.Look(ref this.ticksToDetonation, "ticksToDetonation", 0, false);
+ }
+
+ protected override void Tick()
+ {
+ base.Tick(); // Call base Projectile_TrackingBullet Tick logic
+ bool flag = this.ticksToDetonation > 0;
+ if (flag)
+ {
+ this.ticksToDetonation--;
+ bool flag2 = this.ticksToDetonation <= 0;
+ if (flag2)
+ {
+ this.Explode();
+ }
+ }
+ }
+
protected override void Impact(Thing hitThing, bool blockedByShield = false)
{
- base.Impact(hitThing, blockedByShield); // 调用基类的Impact逻辑
-
- if (ExplosiveDef.explosionRadius > 0f)
+ bool flag = blockedByShield || ExplosiveDef.explosionDelay == 0; // Use ExplosiveDef for explosionDelay
+ if (flag)
{
- // 爆炸逻辑
- GenExplosion.DoExplosion(
- center: Position, // 爆炸中心
- map: Map, // 地图
- radius: ExplosiveDef.explosionRadius, // 爆炸半径
- damType: ExplosiveDef.damageDef ?? DamageDefOf.Bomb, // 伤害类型,如果未配置则默认为Bomb
- instigator: launcher, // 制造者
- damAmount: this.DamageAmount, // 伤害量,使用子弹当前的伤害量
- armorPenetration: this.ArmorPenetration, // 护甲穿透,使用子弹当前的护甲穿透
- explosionSound: ExplosiveDef.soundExplode, // 爆炸音效
- weapon: equipmentDef, // 武器
- projectile: def, // 弹药定义
- intendedTarget: intendedTarget.Thing, // 预期目标
- postExplosionSpawnThingDef: ExplosiveDef.postExplosionSpawnThingDef, // 爆炸后生成物
- postExplosionSpawnChance: ExplosiveDef.postExplosionSpawnChance, // 爆炸后生成几率
- postExplosionSpawnThingCount: ExplosiveDef.postExplosionSpawnThingCount, // 爆炸后生成数量
- postExplosionGasType: ExplosiveDef.gasType, // 气体类型 (注意参数名已修正)
- postExplosionGasRadiusOverride: null, // 爆炸气体半径覆盖 (我没有定义这个参数)
- postExplosionGasAmount: 255, // 爆炸气体数量 (默认值)
- applyDamageToExplosionCellsNeighbors: ExplosiveDef.applyDamageToExplosionCellsNeighbors, // 是否对爆炸单元格邻居造成伤害
- preExplosionSpawnThingDef: null, // 爆炸前生成物 (我没有定义这个参数)
- preExplosionSpawnChance: 0f, // 爆炸前生成几率 (默认值)
- preExplosionSpawnThingCount: 0, // 爆炸前生成数量 (默认值)
- chanceToStartFire: ExplosiveDef.explosionChanceToStartFire, // 是否有几率点燃 (注意参数名已修正)
- damageFalloff: ExplosiveDef.explosionDamageFalloff, // 爆炸伤害衰减
- direction: null, // 方向 (我没有定义这个参数)
- ignoredThings: null, // 忽略的物体 (我没有定义这个参数)
- affectedAngle: null, // 受影响角度 (我没有定义这个参数)
- doVisualEffects: ExplosiveDef.doExplosionVFX, // 是否显示视觉效果
- propagationSpeed: 1f, // 传播速度 (默认值)
- excludeRadius: 0f, // 排除半径 (默认值)
- doSoundEffects: true, // 是否播放音效 (默认值)
- postExplosionSpawnThingDefWater: null, // 爆炸后在水中生成物 (我没有定义这个参数)
- screenShakeFactor: 1f, // 屏幕震动因子 (默认值)
- flammabilityChanceCurve: null, // 易燃性几率曲线 (我没有定义这个参数)
- overrideCells: null, // 覆盖单元格 (我没有定义这个参数)
- postExplosionSpawnSingleThingDef: null, // 爆炸后生成单个物体 (我没有定义这个参数)
- preExplosionSpawnSingleThingDef: null // 爆炸前生成单个物体 (我没有定义这个参数)
- );
+ this.Explode();
}
+ else
+ {
+ this.landed = true;
+ this.ticksToDetonation = ExplosiveDef.explosionDelay; // Use ExplosiveDef for explosionDelay
+ GenExplosion.NotifyNearbyPawnsOfDangerousExplosive(this, ExplosiveDef.damageDef ?? DamageDefOf.Bomb, this.launcher.Faction, this.launcher); // Use ExplosiveDef for damageDef
+ }
+ }
+
+ protected virtual void Explode()
+ {
+ Map map = base.Map;
+ // ModExtension_Cone modExtension = this.def.GetModExtension(); // Not used in this explosive logic
+ this.DoExplosion(map); // Call the helper DoExplosion with map
+
+ // Cone explosion logic (if needed, based on ModExtension_Cone) - Currently not implemented for this class
+ // bool flag = modExtension != null;
+ // if (flag)
+ // {
+ // ProjectileProperties projectile = this.def.projectile;
+ // ModExtension_Cone modExtension_Cone = modExtension;
+ // IntVec3 position = base.Position;
+ // Map map2 = map;
+ // Quaternion exactRotation = this.ExactRotation;
+ // DamageDef damageDef = projectile.damageDef;
+ // Thing launcher = base.Launcher;
+ // int damageAmount = this.DamageAmount;
+ // float armorPenetration = this.ArmorPenetration;
+ // SoundDef soundExplode = this.def.projectile.soundExplode;
+ // ThingDef equipmentDef = this.equipmentDef;
+ // ThingDef def = this.def;
+ // Thing thing = this.intendedTarget.Thing;
+ // ThingDef postExplosionSpawnThingDef = null;
+ // float postExplosionSpawnChance = 0f;
+ // int postExplosionSpawnThingCount = 1;
+ // float screenShakeFactor = this.def.projectile.screenShakeFactor;
+ // modExtension_Cone.DoConeExplosion(position, map2, exactRotation, damageDef, launcher, damageAmount, armorPenetration, soundExplode, equipmentDef, def, thing, postExplosionSpawnThingDef, postExplosionSpawnChance, postExplosionSpawnThingCount, null, null, 255, false, null, 0f, 1, 0f, false, null, null, 1f, 0f, null, screenShakeFactor, null, null);
+ // }
+
+ // Explosion effect (if needed, based on def.projectile.explosionEffect) - Currently not implemented for this class
+ // bool flag2 = this.def.projectile.explosionEffect != null;
+ // if (flag2)
+ // {
+ // Effecter effecter = this.def.projectile.explosionEffect.Spawn();
+ // bool flag3 = this.def.projectile.explosionEffectLifetimeTicks != 0;
+ // if (flag3)
+ // {
+ // map.effecterMaintainer.AddEffecterToMaintain(effecter, base.Position.ToVector3().ToIntVec3(), this.def.projectile.explosionEffectLifetimeTicks);
+ // }
+ // else
+ // {
+ // effecter.Trigger(new TargetInfo(base.Position, map, false), new TargetInfo(base.Position, map, false), -1);
+ // effecter.Cleanup();
+ // }
+ // }
+ this.Destroy(DestroyMode.Vanish);
+ }
+
+ protected void DoExplosion(Map map)
+ {
+ IntVec3 position = base.Position;
+ float explosionRadius = ExplosiveDef.explosionRadius; // Use ExplosiveDef for explosionRadius
+ DamageDef damageDef = ExplosiveDef.damageDef ?? DamageDefOf.Bomb; // Use ExplosiveDef for damageDef
+ Thing launcher = this.launcher;
+ int damageAmount = this.DamageAmount;
+ float armorPenetration = this.ArmorPenetration;
+ SoundDef soundExplode = ExplosiveDef.soundExplode; // Use ExplosiveDef for soundExplode
+ ThingDef equipmentDef = this.equipmentDef;
+ ThingDef def = this.def; // This is the projectile's ThingDef
+ Thing thing = this.intendedTarget.Thing;
+ ThingDef postExplosionSpawnThingDef = ExplosiveDef.postExplosionSpawnThingDef; // Use ExplosiveDef for postExplosionSpawnThingDef
+ ThingDef postExplosionSpawnThingDefWater = ExplosiveDef.postExplosionSpawnThingDefWater; // Use ExplosiveDef for postExplosionSpawnThingDefWater
+ float postExplosionSpawnChance = ExplosiveDef.postExplosionSpawnChance; // Use ExplosiveDef for postExplosionSpawnChance
+ int postExplosionSpawnThingCount = ExplosiveDef.postExplosionSpawnThingCount; // Use ExplosiveDef for postExplosionSpawnThingCount
+ GasType? postExplosionGasType = ExplosiveDef.gasType; // Use ExplosiveDef for gasType
+ ThingDef preExplosionSpawnThingDef = ExplosiveDef.preExplosionSpawnThingDef; // Use ExplosiveDef for preExplosionSpawnThingDef
+ float preExplosionSpawnChance = ExplosiveDef.preExplosionSpawnChance; // Use ExplosiveDef for preExplosionSpawnChance
+ int preExplosionSpawnThingCount = ExplosiveDef.preExplosionSpawnThingCount; // Use ExplosiveDef for preExplosionSpawnThingCount
+ bool applyDamageToExplosionCellsNeighbors = ExplosiveDef.applyDamageToExplosionCellsNeighbors; // Use ExplosiveDef for applyDamageToExplosionCellsNeighbors
+ float explosionChanceToStartFire = ExplosiveDef.explosionChanceToStartFire; // Use ExplosiveDef for explosionChanceToStartFire
+ bool explosionDamageFalloff = ExplosiveDef.explosionDamageFalloff; // Use ExplosiveDef for explosionDamageFalloff
+ float? direction = new float?(this.origin.AngleToFlat(this.destination)); // This remains from original logic
+ float screenShakeFactor = ExplosiveDef.screenShakeFactor; // Use ExplosiveDef for screenShakeFactor
+ bool doExplosionVFX = ExplosiveDef.doExplosionVFX; // Use ExplosiveDef for doExplosionVFX
+
+ GenExplosion.DoExplosion(
+ center: position, // 爆炸中心
+ map: map, // 地图
+ radius: explosionRadius, // 爆炸半径
+ damType: damageDef, // 伤害类型
+ instigator: launcher, // 制造者
+ damAmount: damageAmount, // 伤害量
+ armorPenetration: armorPenetration, // 护甲穿透
+ explosionSound: soundExplode, // 爆炸音效
+ weapon: equipmentDef, // 武器
+ projectile: def, // 弹药定义
+ intendedTarget: thing, // 预期目标
+ postExplosionSpawnThingDef: postExplosionSpawnThingDef, // 爆炸后生成物
+ postExplosionSpawnChance: postExplosionSpawnChance, // 爆炸后生成几率
+ postExplosionSpawnThingCount: postExplosionSpawnThingCount, // 爆炸后生成数量
+ postExplosionGasType: postExplosionGasType, // 气体类型
+ postExplosionGasRadiusOverride: null, // 爆炸气体半径覆盖
+ postExplosionGasAmount: 255, // 爆炸气体数量
+ applyDamageToExplosionCellsNeighbors: applyDamageToExplosionCellsNeighbors, // 是否对爆炸单元格邻居造成伤害
+ preExplosionSpawnThingDef: preExplosionSpawnThingDef, // 爆炸前生成物
+ preExplosionSpawnChance: preExplosionSpawnChance, // 爆炸前生成几率
+ preExplosionSpawnThingCount: preExplosionSpawnThingCount, // 爆炸前生成数量
+ chanceToStartFire: explosionChanceToStartFire, // 是否有几率点燃
+ damageFalloff: explosionDamageFalloff, // 爆炸伤害衰减
+ direction: direction, // 方向
+ ignoredThings: null, // 忽略的物体
+ affectedAngle: null, // 受影响角度
+ doVisualEffects: doExplosionVFX, // 是否显示视觉效果
+ propagationSpeed: 1f, // 传播速度
+ excludeRadius: 0f, // 排除半径
+ doSoundEffects: true, // 是否播放音效
+ postExplosionSpawnThingDefWater: postExplosionSpawnThingDefWater, // 爆炸后在水中生成物
+ screenShakeFactor: screenShakeFactor, // 屏幕震动因子
+ flammabilityChanceCurve: null, // 易燃性几率曲线
+ overrideCells: null, // 覆盖单元格
+ postExplosionSpawnSingleThingDef: null, // 爆炸后生成单个物体
+ preExplosionSpawnSingleThingDef: null // 爆炸前生成单个物体
+ );
}
}
}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/Projectile_TrackingBullet.cs b/Source/WulaFallenEmpire/Projectile_TrackingBullet.cs
index 07b1aa2c..094b5567 100644
--- a/Source/WulaFallenEmpire/Projectile_TrackingBullet.cs
+++ b/Source/WulaFallenEmpire/Projectile_TrackingBullet.cs
@@ -196,6 +196,17 @@ namespace WulaFallenEmpire
return;
}
+ // 在调用 ProjectileCheckForFreeInterceptBetween 之前,添加近距离命中检测
+ if (intendedTarget != null && intendedTarget.Thing != null && intendedTarget.Thing.Spawned)
+ {
+ float distanceToTarget = (ExactPosition - intendedTarget.Thing.DrawPos).magnitude;
+ if (distanceToTarget <= TrackingDef.impactThreshold)
+ {
+ Impact(intendedTarget.Thing); // 强制命中目标
+ return; // 命中后立即返回,不再执行后续逻辑
+ }
+ }
+
// 检查是否有东西在路径上拦截
// ProjectileCheckForFreeInterceptBetween 会在内部处理命中,并调用 ImpactSomething()
// 所以这里不需要额外的 ImpactSomething() 调用
diff --git a/Source/WulaFallenEmpire/TrackingBulletDef.cs b/Source/WulaFallenEmpire/TrackingBulletDef.cs
index f94a470d..4a44a6e3 100644
--- a/Source/WulaFallenEmpire/TrackingBulletDef.cs
+++ b/Source/WulaFallenEmpire/TrackingBulletDef.cs
@@ -6,6 +6,7 @@ namespace WulaFallenEmpire
{
public float homingSpeed = 0.1f; // 追踪速度,值越大追踪越灵敏
public float initRotateAngle = 0f; // 初始旋转角度
+ public float impactThreshold = 0.5f; // 强制命中阈值,子弹与目标距离小于此值时强制命中
public FleckDef tailFleckDef; // 拖尾特效的FleckDef
public int fleckMakeFleckTickMax = 1; // 拖尾特效的生成间隔(tick)