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)