diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll index 7f56cd5c..2227b0e1 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_Buildings/WULA_Mortar_Turret_Buildings.xml b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Mortar_Turret_Buildings.xml new file mode 100644 index 00000000..a3e73b7b --- /dev/null +++ b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Mortar_Turret_Buildings.xml @@ -0,0 +1,289 @@ + + + + + + Wula_Base_Mortar_Turret_Cleanzone + + 清理出一块场地并准备好资源,使得乌拉帝国母舰可以向此处投放建筑。建造好的信标可以收起或移至他处,但是必须要有母舰或者工程舰在上空才能投送建筑。\n\nMTt-8"深渊"迫击炮塔是一种需要通电才能运转的中型防御炮塔,发射高爆迫击炮弹。这种炮台具有高伤害范围攻击能力,适合对付集群敌人和建筑。 + Wula/Building/Wula_Base_Mortar_Turret + MinifiedThing + Normal + + Wula_Base_Mortar_Turret + Wula_Base_Mortar_Turret_Weapon + + +
  • BuildingsMisc
  • +
    + + Wula/Building/WULA_Dropping_Building_Cleanzone + Graphic_Multi + (3,3) + + false + + + Building + PassThroughOnly + 0 + false + 0.5 + false + false + false + +
  • WULA_Turret_Base_Mortar_Technology
  • +
    + + 1 + 1 + 1 + 0 + + (3,3) + 0 + 1 + + 100 + 6 + + + BuildingDestroyed_Metal_Small + + +
  • WulaFallenEmpire.PlaceWorker_CustomRadius
  • +
    + WULA_Buildings + +
  • + 75 + (1, 1, 1) + 0 + true + + 在该建筑空降到指定地点时,其炮台武器的最大射程。 + true +
  • +
  • + Wula_Base_Mortar_Turret_Incoming + true + 1 + true + false +
  • +
    +
    + + + + Wula_Base_Mortar_Turret_Incoming + + (3,3) + + Wula/Building/Wula_Base_ATGun_Turret_Incoming + Graphic_Single + CutoutFlying + (3,3.75) + + + Accelerate + Things/Skyfaller/SkyfallerShadowDropPod + (2, 2) + DropPod_Fall + 100 + Explosion_Vaporize + 0.05 + 1 + 1 + + +
  • (0,0)
  • +
  • (1, 1)
  • +
    +
    + Wula_Base_Mortar_Turret +
    + +
  • + Smoke_Joint +
  • +
    +
    + + + + Wula_Base_Mortar_Turret + + MTt-8"深渊"迫击炮塔是一种需要通电才能运转的中型防御炮塔,发射高爆迫击炮弹。这种炮台具有高伤害范围攻击能力,适合对付集群敌人和建筑。 + WulaFallenEmpire.Building_TurretGunHasSpeed + MapMeshAndRealTime + +
  • + 0.2 +
  • +
    + + Wula/Building/WULA_Turret_Component + Graphic_Single + (3,3) + + + (0.3,0.3,1.4,1.4) + + + (0.5,0.35,0.75) + (0,0,-0.05) + + + true + Wula/Building/Wula_Base_Mortar_Turret + 1.0 + Building + false + false + (3,3) + + 1500 + 0 + 3200 + 80 + 0 + 0.80 + + + 100 + 6 + + false + Normal + PassThroughOnly + 50 + 0.5 + true + + 450 + true + Wula_Base_Mortar_Turret_Weapon + 4 + (-0.04, 0) + 5.0 + + +
  • PlaceWorker_TurretTop
  • +
  • PlaceWorker_ShowTurretRadius
  • +
    + +
  • +
  • +
  • + MechanoidsWakeUp +
  • +
  • + +
  • EMP
  • + + +
  • + MechTurretBig_Call +
  • +
  • + + true + false +
  • +
  • + CompPowerTrader + 200 +
  • +
  • + 6 + (252,240,120,0) +
  • +
  • + + + + + + Wula_Base_Mortar_Turret_Weapon + + 迫击炮塔,可以从远距离上对敌方集群造成巨大伤害。 + None + true + Ultra + + Wula/Building/Wula_Base_ATGun_Turret_Weapon + Graphic_Single + 3 + + 0.33 + + 150 + 0.3 + 0.7 + 0.85 + 0.8 + + +
  • + Verb_Shoot + true + Bullet_WULA_WM_Mortar_Turret + 2.5 + 5 + 10 + 75 + 1 + 1.9 + WULA_MW_Mass_Drivers_Shootingsound + GunTail_Heavy + 18 + + true + +
  • + +
    + + + + Bullet_WULA_WM_Mortar_Turret + + WulaFallenEmpire.Projectile_NorthArcTrail + Normal + True + + Wula/Projectile/WULA_Bullet_ChargeLanceShot_Red + Graphic_Single + TransparentPostLight + 5 + + + Bomb + 220 + 20 + 0.8 + 5.0 + Artillery_HitThickRoof + MortarBomb_Explode + MortarRound_PreImpact + MortarRound_Ambient + 5 + true + 150 + + +
  • + WULA_GunTail_Lighting + 3 + 1 + 1~2 + 0.5~1.0 + 0.1~0.3 + -30~30 +
  • +
    +
    + +
    \ No newline at end of file diff --git a/Source/WulaFallenEmpire/Projectiles/Projectile_NorthArcTrail.cs b/Source/WulaFallenEmpire/Projectiles/Projectile_NorthArcTrail.cs new file mode 100644 index 00000000..a240e066 --- /dev/null +++ b/Source/WulaFallenEmpire/Projectiles/Projectile_NorthArcTrail.cs @@ -0,0 +1,191 @@ +using System.Collections.Generic; +using RimWorld; +using UnityEngine; +using Verse; + +namespace WulaFallenEmpire +{ + public class Projectile_NorthArcTrail : Projectile_Explosive + { + // --- 弹道部分变量 --- + // 定义向北偏移的高度(格数),建议在XML中通过 参数无法直接传参时硬编码或扩展 ThingDef + // 这里为了方便,设定默认值为 10,你可以根据需要修改 + public float northOffsetDistance = 10f; + + private Vector3 originPos; + private Vector3 destinationPos; + private Vector3 bezierControlPoint; + private int ticksFlying; + private int totalTicks; + private bool initialized = false; + + // --- 尾迹部分变量 --- + private TrackingBulletDef trackingDefInt; + private int Fleck_MakeFleckTick; + private Vector3 lastTickPosition; // 记录上一帧位置用于计算拖尾方向 + + // 获取 XML 中的扩展数据 + public TrackingBulletDef TrackingDef + { + get + { + if (trackingDefInt == null) + { + trackingDefInt = def.GetModExtension(); + if (trackingDefInt == null) + { + // 如果没配置,给一个空的默认值防止报错,或者只报错一次 + trackingDefInt = new TrackingBulletDef(); + } + } + return trackingDefInt; + } + } + + public override void ExposeData() + { + base.ExposeData(); + // 保存弹道数据 + Scribe_Values.Look(ref originPos, "originPos"); + Scribe_Values.Look(ref destinationPos, "destinationPos"); + Scribe_Values.Look(ref bezierControlPoint, "bezierControlPoint"); + Scribe_Values.Look(ref ticksFlying, "ticksFlying", 0); + Scribe_Values.Look(ref totalTicks, "totalTicks", 0); + Scribe_Values.Look(ref initialized, "initialized", false); + Scribe_Values.Look(ref northOffsetDistance, "northOffsetDistance", 10f); + + // 保存尾迹数据 + Scribe_Values.Look(ref Fleck_MakeFleckTick, "Fleck_MakeFleckTick", 0); + Scribe_Values.Look(ref lastTickPosition, "lastTickPosition", Vector3.zero); + } + + public override void Launch(Thing launcher, Vector3 origin, LocalTargetInfo usedTarget, LocalTargetInfo intendedTarget, ProjectileHitFlags hitFlags, bool preventFriendlyFire = false, Thing equipment = null, ThingDef targetCoverDef = null) + { + base.Launch(launcher, origin, usedTarget, intendedTarget, hitFlags, preventFriendlyFire, equipment, targetCoverDef); + + // --- 初始化弹道 --- + originPos = origin; + destinationPos = usedTarget.CenterVector3; + + float speed = def.projectile.speed; + if (speed <= 0) speed = 1f; + + // 计算直线距离估算时间 + float distance = (originPos - destinationPos).MagnitudeHorizontal(); + totalTicks = Mathf.CeilToInt(distance / speed * 100f); + if (totalTicks < 1) totalTicks = 1; + + ticksFlying = 0; + + // 贝塞尔曲线计算: + // 中点 + Vector3 midPoint = (originPos + destinationPos) / 2f; + // 顶点 (中点向北偏移 X 格) + Vector3 apexPoint = midPoint + new Vector3(0, 0, northOffsetDistance); + // 控制点 P1 = 2 * 顶点 - 中点 + bezierControlPoint = 2f * apexPoint - midPoint; + + initialized = true; + + // --- 初始化尾迹 --- + lastTickPosition = origin; + } + + protected override void Tick() + { + // 注意:这里不直接调用 base.Tick() 的物理位移部分,因为我们要自己控制位置 + // 但我们需要 Projectile_Explosive 的倒计时逻辑,所以我们在方法末尾调用 TickInterval + + if (!initialized) + { + base.Tick(); + return; + } + + ticksFlying++; + + // 1. 计算当前帧的新位置 (贝塞尔曲线 + 高度) + float t = (float)ticksFlying / (float)totalTicks; + if (t > 1f) t = 1f; + + float u = 1 - t; + // 水平位移 (贝塞尔) + Vector3 nextPos = (u * u * originPos) + (2 * u * t * bezierControlPoint) + (t * t * destinationPos); + // 垂直高度 (抛物线) + float arcHeight = def.projectile.arcHeightFactor * GenMath.InverseParabola(t); + nextPos.y = arcHeight; + + // 设置物体确切位置 + this.Position = nextPos.ToIntVec3(); + + // 2. 处理拖尾特效 (合并的代码) + // 只有当这一帧移动了,且配置了 DefModExtension 时才生成 + if (TrackingDef != null && TrackingDef.tailFleckDef != null) + { + Fleck_MakeFleckTick++; + // 检查生成间隔 + if (Fleck_MakeFleckTick >= TrackingDef.fleckDelayTicks) + { + // 简单的循环计时重置逻辑 + if (Fleck_MakeFleckTick >= (TrackingDef.fleckDelayTicks + TrackingDef.fleckMakeFleckTickMax)) + { + Fleck_MakeFleckTick = TrackingDef.fleckDelayTicks; + } + + Map map = base.Map; + // 只有当在地图内时才生成 + if (map != null) + { + int count = TrackingDef.fleckMakeFleckNum.RandomInRange; + Vector3 currentPosition = this.ExactPosition; + Vector3 previousPosition = lastTickPosition; + + // 仅当有位移时才计算角度,防止原地鬼畜 + if ((currentPosition - previousPosition).MagnitudeHorizontalSquared() > 0.0001f) + { + float moveAngle = (currentPosition - previousPosition).AngleFlat(); + + for (int i = 0; i < count; i++) + { + // 这里的逻辑完全照搬原来的 BulletWithTrail + float velocityAngle = TrackingDef.fleckAngle.RandomInRange + moveAngle; + + FleckCreationData dataStatic = FleckMaker.GetDataStatic(currentPosition, map, TrackingDef.tailFleckDef, TrackingDef.fleckScale.RandomInRange); + dataStatic.rotation = moveAngle; // 粒子朝向跟随移动方向 + dataStatic.rotationRate = TrackingDef.fleckRotation.RandomInRange; + dataStatic.velocityAngle = velocityAngle; + dataStatic.velocitySpeed = TrackingDef.fleckSpeed.RandomInRange; + map.flecks.CreateFleck(dataStatic); + } + } + } + } + } + + // 3. 更新旋转角度 (Visual) 和 记录上一帧位置 + if (lastTickPosition != nextPos) + { + if ((nextPos - lastTickPosition).MagnitudeHorizontalSquared() > 0.001f) + { + this.Rotation = Rot4.FromAngleFlat((nextPos - lastTickPosition).AngleFlat()); + } + } + lastTickPosition = nextPos; + + // 4. 判定到达目标或倒计时爆炸 + if (ticksFlying >= totalTicks) + { + Impact(null); + return; + } + + // 5. 处理 Projectile_Explosive 的内部倒计时 (如果 ticksToDetonation 被设置了) + base.TickInterval(1); + } + + protected override void Impact(Thing hitThing, bool blockedByShield = false) + { + base.Impact(hitThing, blockedByShield); + } + } +} \ No newline at end of file diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj index 2f38d40f..506e7407 100644 --- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj +++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj @@ -294,6 +294,7 @@ +