diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll index d2344cbf..1b2f27f5 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/AbilityDefs/WULA_Flyover_Ability.xml b/1.6/1.6/Defs/AbilityDefs/WULA_Flyover_Ability.xml index 321734f0..55e2e1e5 100644 --- a/1.6/1.6/Defs/AbilityDefs/WULA_Flyover_Ability.xml +++ b/1.6/1.6/Defs/AbilityDefs/WULA_Flyover_Ability.xml @@ -787,21 +787,22 @@ -
  • + +
  • + 450 20 true - 3 + WULA_EnergyLance_Base + 4
  • -
  • + - BombardmentFacility - 需要拥有<color=#BD2F31><i>武器阵列</i></color>设施的战舰在地图上才能进行轨道炮击支援 -
  • +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/HediffDefs/WULA_FM_Hediffs.xml b/1.6/1.6/Defs/HediffDefs/WULA_FM_Hediffs.xml index 80e169e6..f49d9f3d 100644 --- a/1.6/1.6/Defs/HediffDefs/WULA_FM_Hediffs.xml +++ b/1.6/1.6/Defs/HediffDefs/WULA_FM_Hediffs.xml @@ -75,6 +75,8 @@
  • WULA_Firepower_Minigun_Strafe
  • WULA_Firepower_Cannon_Salvo
  • +
  • WULA_Firepower_Cannon_Surveillance_Beacon
  • +
  • WULA_Firepower_EnergyLance_Strafe
  • diff --git a/1.6/1.6/Defs/ThingDefs_Misc/WULA_Flyover_Item.xml b/1.6/1.6/Defs/ThingDefs_Misc/WULA_Flyover_Item.xml index 506d9c88..571ff0a0 100644 --- a/1.6/1.6/Defs/ThingDefs_Misc/WULA_Flyover_Item.xml +++ b/1.6/1.6/Defs/ThingDefs_Misc/WULA_Flyover_Item.xml @@ -888,48 +888,117 @@ - + WULA_EnergyLance_Base - - PowerBeam - - - WULA_EnergyLance_Base - + + 移动的能量光束武器 WulaFallenEmpire.EnergyLance + Normal + RealtimeOnly + true + true +
  • - Flame - true - 0.9 - - 60 - 95 - - - 5 - 10 - + 0.001 + 3 + 0.8 + 4 + 15 +
  • +
  • + WULA_RW_Base_AR
  • + - +
  • 6 - (255, 200, 50, 242) + (147, 116, 201, 212) OrbitalBeam
  • + +
  • 0.02
  • + +
  • + 30 + 15 - (255, 220, 180) - (220, 200, 160) - (255, 240, 200) - 1.2 + (147, 116, 201) + (147, 116, 185) + (147, 116, 150) + 1.5
  • + +
  • + WULA_EnergyLance_Effecter +
  • + + WULA_EnergyLance_Effecter + 300 + +
  • + SubEffecter_Sustainer + VoidStructure_Emerging +
  • +
  • + SubEffecter_SprayerChance + EnergyLance_Fleck + 1 + 999 + 40 + 1~1 + 15 + OnSource +
  • +
  • + SubEffecter_SprayerChance + EnergyLance_Fleck + 1 + 999 + 40 + 1~1 + 5 + OnSource +
  • +
  • + SubEffecter_SprayerChance + EnergyLance_Fleck + 1 + 999 + 40 + 1~1 + 2 + OnSource +
  • +
    +
    + + EnergyLance_Fleck + MoteOverhead + 1 + 0 + 1 + 5 + + Graphic_FleckPulse + Things/Mote/PowerBeam + MoteGlow + (147, 116, 201, 255) + + <_NoiseTex>/Things/Mote/PsycastNoise + <_NoiseIntensity>100 + <_Color2>(1, 1, 1, 0.85) + + 10.0 + + \ No newline at end of file diff --git a/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/AbilityWeaponDefExtension.cs b/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/AbilityWeaponDefExtension.cs new file mode 100644 index 00000000..42d715a2 --- /dev/null +++ b/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/AbilityWeaponDefExtension.cs @@ -0,0 +1,10 @@ +using RimWorld; +using Verse; + +namespace WulaFallenEmpire +{ + public class AbilityWeaponDefExtension : DefModExtension + { + public ThingDef weaponDef; // 与此Ability相关的武器定义 + } +} diff --git a/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/CompAbilityEffect_EnergyLance.cs b/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/CompAbilityEffect_EnergyLance.cs index 2da71393..9398bad1 100644 --- a/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/CompAbilityEffect_EnergyLance.cs +++ b/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/CompAbilityEffect_EnergyLance.cs @@ -6,124 +6,117 @@ namespace WulaFallenEmpire { public class CompAbilityEffect_EnergyLance : CompAbilityEffect_WithDest { - public new CompProperties_EnergyLance Props => (CompProperties_EnergyLance)props; + public new CompProperties_AbilityEnergyLance Props => (CompProperties_AbilityEnergyLance)props; + public override void Apply(LocalTargetInfo target, LocalTargetInfo dest) { base.Apply(target, dest); - - // 计算光束的起点和方向 - IntVec3 startPos = target.Cell; - IntVec3 endPos = dest.Cell; - - // 如果使用固定距离,则从起点向终点方向移动固定距离 - if (Props.useFixedDistance) - { - Vector3 direction = (endPos.ToVector3() - startPos.ToVector3()).normalized; - Vector3 offset = direction * Props.moveDistance; - endPos = startPos + new IntVec3(Mathf.RoundToInt(offset.x), 0, Mathf.RoundToInt(offset.z)); - } - - // 创建移动的能量光束 - EnergyLance obj = (EnergyLance)GenSpawn.Spawn(ThingDef.Named("EnergyLance"), startPos, parent.pawn.Map); - obj.duration = Props.durationTicks; - obj.instigator = parent.pawn; - obj.startPos = startPos; - obj.endPos = endPos; - obj.moveDistance = Props.moveDistance; - obj.useFixedDistance = Props.useFixedDistance; - obj.firesPerTick = Props.firesPerTick; - // 不再需要传递伤害范围,因为现在从ModExtension读取 - obj.StartStrike(); - - Log.Message($"[EnergyLance] Created energy lance from {startPos} to {endPos}, distance: {Props.moveDistance}"); - } - - // 绘制预览效果 - public override void DrawEffectPreview(LocalTargetInfo target) - { - base.DrawEffectPreview(target); - if (parent.pawn == null || parent.pawn.Map == null || !target.IsValid) + if (parent.pawn == null || parent.pawn.Map == null) return; try { - // 绘制起点预览 - GenDraw.DrawTargetHighlight(target.Cell); + // 使用配置的光束类型 + ThingDef lanceDef = Props.energyLanceDef ?? ThingDef.Named("EnergyLance"); - // 如果选择了终点,绘制移动路径预览 - if (selectedTarget.IsValid) - { - DrawMovePathPreview(target.Cell, selectedTarget.Cell); - } + // 创建EnergyLance + EnergyLance.MakeEnergyLance( + lanceDef, + target.Cell, + dest.Cell, + parent.pawn.Map, + Props.moveDistance, + Props.useFixedDistance, + Props.durationTicks, + parent.pawn + ); + + Log.Message($"[EnergyLance] Started {lanceDef.defName} from {target.Cell} to {dest.Cell}"); } - catch (System.Exception) + catch (System.Exception ex) { - // 忽略预览绘制错误 + Log.Error($"[EnergyLance] Error starting EnergyLance: {ex}"); } } - private void DrawMovePathPreview(IntVec3 startPos, IntVec3 endPos) + // 绘制预览保持不变 + public new void DrawHighlight(LocalTargetInfo target) + { + if (selectedTarget.IsValid) + { + DrawBeamPathPreview(selectedTarget.Cell, target.Cell); + } + else + { + GenDraw.DrawTargetHighlight(target); + } + } + + private void DrawBeamPathPreview(IntVec3 startCell, IntVec3 endCell) { Map map = parent.pawn.Map; - // 计算实际终点 - IntVec3 actualEndPos = endPos; + Vector3 startPos = startCell.ToVector3(); + Vector3 direction = (endCell.ToVector3() - startPos).normalized; + Vector3 actualEndPos; + if (Props.useFixedDistance) { - Vector3 direction = (endPos.ToVector3() - startPos.ToVector3()).normalized; - Vector3 offset = direction * Props.moveDistance; - actualEndPos = startPos + new IntVec3(Mathf.RoundToInt(offset.x), 0, Mathf.RoundToInt(offset.z)); + actualEndPos = startPos + direction * Props.moveDistance; + } + else + { + actualEndPos = endCell.ToVector3(); } - // 绘制移动路径 - Vector3 startVec = startPos.ToVector3Shifted(); - Vector3 endVec = actualEndPos.ToVector3Shifted(); + IntVec3 actualEndCell = new IntVec3( + Mathf.RoundToInt(actualEndPos.x), + Mathf.RoundToInt(actualEndPos.y), + Mathf.RoundToInt(actualEndPos.z) + ); - GenDraw.DrawLineBetween(startVec, endVec, SimpleColor.Yellow, 0.2f); - - // 绘制终点预览 - GenDraw.DrawTargetHighlight(actualEndPos); - - // 绘制作用范围预览(在移动路径上) - DrawEffectRangePreview(startPos, actualEndPos); + DrawBeamLine(startCell, actualEndCell); + GenDraw.DrawTargetHighlight(startCell); + GenDraw.DrawTargetHighlight(actualEndCell); + DrawEffectRadiusPreview(startCell); + DrawEffectRadiusPreview(actualEndCell); } - private void DrawEffectRangePreview(IntVec3 startPos, IntVec3 endPos) + private void DrawBeamLine(IntVec3 startCell, IntVec3 endCell) + { + Vector3 startPos = startCell.ToVector3Shifted(); + Vector3 endPos = endCell.ToVector3Shifted(); + + GenDraw.DrawLineBetween(startPos, endPos, SimpleColor.Yellow, 0.3f); + } + + private void DrawEffectRadiusPreview(IntVec3 center) { Map map = parent.pawn.Map; - - // 沿着移动路径绘制作用范围 - Vector3 currentPos = startPos.ToVector3(); - Vector3 direction = (endPos.ToVector3() - startPos.ToVector3()).normalized; - float totalDistance = Vector3.Distance(startPos.ToVector3(), endPos.ToVector3()); - float step = 1f; // 每格绘制 - - for (float distance = 0; distance <= totalDistance; distance += step) - { - Vector3 checkPos = startPos.ToVector3() + direction * distance; - IntVec3 checkCell = new IntVec3(Mathf.RoundToInt(checkPos.x), 0, Mathf.RoundToInt(checkPos.z)); - - if (checkCell.InBounds(map)) - { - // 绘制作用范围指示 - GenDraw.DrawRadiusRing(checkCell, 1.5f, Color.red, (c) => true); - } - } + GenDraw.DrawRadiusRing(center, 15f, Color.yellow); } public override string ExtraLabelMouseAttachment(LocalTargetInfo target) { - string baseInfo = $"能量长矛: 持续{Props.durationTicks}刻"; - - if (Props.useFixedDistance) + if (selectedTarget.IsValid) { - baseInfo += $"\n移动距离: {Props.moveDistance}格"; + string beamType = Props.energyLanceDef?.label ?? "EnergyLance"; + return $"选择{beamType}方向\n移动距离: {Props.moveDistance}格\n模式: {(Props.useFixedDistance ? "固定距离" : "移动到终点")}"; + } + else + { + return "选择光束起点"; } - - baseInfo += $"\n选择起点后,再选择移动方向"; - - return baseInfo; } + + public override TargetingParameters targetParams => new TargetingParameters + { + canTargetLocations = true, + canTargetPawns = false, + canTargetBuildings = false, + canTargetItems = false, + mapObjectTargetsMustBeAutoAttackable = false + }; } } diff --git a/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/CompProperties_AbilityEnergyLance.cs b/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/CompProperties_AbilityEnergyLance.cs new file mode 100644 index 00000000..69eade0a --- /dev/null +++ b/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/CompProperties_AbilityEnergyLance.cs @@ -0,0 +1,25 @@ +using RimWorld; +using Verse; + +namespace WulaFallenEmpire +{ + public class CompProperties_AbilityEnergyLance : CompProperties_EffectWithDest + { + // 光束持续时间 + public int durationTicks = 600; + + // 移动配置 + public float moveDistance = 15f; + public bool useFixedDistance = true; + + // 光束类型配置 - 新增:暴露光束类型 + public ThingDef energyLanceDef; // 使用的EnergyLance ThingDef + public int firesPerTick = 4; // 每刻造成的火灾数量 + + public CompProperties_AbilityEnergyLance() + { + this.compClass = typeof(CompAbilityEffect_EnergyLance); + this.destination = AbilityEffectDestination.Selected; + } + } +} diff --git a/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/CompProperties_EnergyLance.cs b/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/CompProperties_EnergyLance.cs deleted file mode 100644 index 5f18a848..00000000 --- a/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/CompProperties_EnergyLance.cs +++ /dev/null @@ -1,22 +0,0 @@ -using RimWorld; -using Verse; - -namespace WulaFallenEmpire -{ - public class CompProperties_EnergyLance : CompProperties_EffectWithDest - { - public int durationTicks = 600; // 光束持续时间 - public float moveDistance = 15f; // 光束移动距离 - public bool useFixedDistance = true; // 是否使用固定距离 - - // 伤害配置 - public int firesPerTick = 4; // 每刻产生的火焰数量 - public IntRange flameDamageRange = new IntRange(65, 100); // 火焰伤害范围 - public IntRange corpseFlameDamageRange = new IntRange(5, 10); // 尸体火焰伤害范围 - - public CompProperties_EnergyLance() - { - this.compClass = typeof(CompAbilityEffect_EnergyLance); - } - } -} diff --git a/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/EnergyLance.cs b/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/EnergyLance.cs index a9530d92..584f3001 100644 --- a/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/EnergyLance.cs +++ b/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/EnergyLance.cs @@ -3,82 +3,141 @@ using Verse; using UnityEngine; using System.Collections.Generic; using System.Linq; +using Verse.Sound; namespace WulaFallenEmpire { - public class EnergyLance : OrbitalStrike + [StaticConstructorOnStartup] + public class EnergyLance : ThingWithComps { // 移动相关属性 - public IntVec3 startPos; - public IntVec3 endPos; + public IntVec3 startPosition; + public IntVec3 endPosition; public float moveDistance; public bool useFixedDistance; + public float flightSpeed = 1f; + public float currentProgress = 0f; + public float altitude = 20f; // 伤害配置 public int firesPerTick = 4; - - // ModExtension引用 - private EnergyLanceExtension extension; + public float effectRadius = 15f; + public int durationTicks = 600; + private int ticksPassed = 0; // 移动状态 - private Vector3 currentPos; + private Vector3 exactPosition; private Vector3 moveDirection; - private float moveSpeed; - private float traveledDistance; - private const float effectRadius = 3f; // 作用半径 + private bool hasStarted = false; + private bool hasCompleted = false; - private static List tmpThings = new List(); + // 视觉效果 + private CompOrbitalBeam orbitalBeamComp; + private Sustainer sustainer; - public override void StartStrike() + // 伤害相关 + private static List tmpThings = new List(); + private static readonly IntRange FlameDamageAmountRange = new IntRange(65, 100); + private static readonly IntRange CorpseFlameDamageAmountRange = new IntRange(5, 10); + public Thing instigator; + public ThingDef weaponDef; + + // 精确位置计算(基于FlyOver的逻辑) + public override Vector3 DrawPos { - base.StartStrike(); - - // 获取ModExtension - extension = def.GetModExtension(); - if (extension == null) + get { - Log.Error($"[EnergyLance] No EnergyLanceExtension found on {def.defName}"); - return; + Vector3 start = startPosition.ToVector3(); + Vector3 end = CalculateEndPosition(); + Vector3 basePos = Vector3.Lerp(start, end, currentProgress); + basePos.y = altitude; + return basePos; } - - // 初始化移动参数 - currentPos = startPos.ToVector3(); - - if (useFixedDistance) - { - // 从起点向终点方向移动固定距离 - Vector3 direction = (endPos.ToVector3() - startPos.ToVector3()).normalized; - moveDirection = direction; - moveSpeed = moveDistance / duration; // 根据持续时间计算移动速度 - } - else - { - // 直接从起点移动到终点 - Vector3 direction = (endPos.ToVector3() - startPos.ToVector3()); - moveDirection = direction.normalized; - moveSpeed = direction.magnitude / duration; - } - - traveledDistance = 0f; - - // 创建视觉效果 - CreateVisualEffect(); - - Log.Message($"[EnergyLance] Strike started from {startPos} to {endPos}, " + - $"damage: {extension.damageDef.defName}, speed: {moveSpeed}"); } - private void CreateVisualEffect() + // 计算实际终点位置 + private Vector3 CalculateEndPosition() { - // 使用ModExtension中定义的Mote,如果没有则使用默认的PowerBeam - if (extension.moteDef != null) + if (useFixedDistance) { - Mote mote = MoteMaker.MakeStaticMote(base.Position, base.Map, extension.moteDef); + Vector3 direction = (endPosition.ToVector3() - startPosition.ToVector3()).normalized; + return startPosition.ToVector3() + direction * moveDistance; } else { - // 使用原版PowerBeam的视觉效果 - MoteMaker.MakePowerBeamMote(base.Position, base.Map); + return endPosition.ToVector3(); + } + } + + // 精确旋转 + public virtual Quaternion ExactRotation + { + get + { + Vector3 direction = (CalculateEndPosition() - startPosition.ToVector3()).normalized; + return Quaternion.LookRotation(direction.Yto0()); + } + } + + public override void SpawnSetup(Map map, bool respawningAfterLoad) + { + base.SpawnSetup(map, respawningAfterLoad); + + orbitalBeamComp = GetComp(); + + if (!respawningAfterLoad) + { + base.Position = startPosition; + hasStarted = true; + + // 计算移动方向 + Vector3 endPos = CalculateEndPosition(); + moveDirection = (endPos - startPosition.ToVector3()).normalized; + + // 初始化光束组件 + if (orbitalBeamComp != null) + { + // 使用反射调用StartAnimation方法 + StartOrbitalBeamAnimation(); + } + + // 开始音效 + StartSound(); + + Log.Message($"[EnergyLance] Spawned at {startPosition}, moving to {endPosition}, " + + $"distance: {moveDistance}, fixed: {useFixedDistance}"); + } + } + + // 使用反射调用StartAnimation方法 + private void StartOrbitalBeamAnimation() + { + var startAnimationMethod = orbitalBeamComp.GetType().GetMethod("StartAnimation"); + if (startAnimationMethod != null) + { + startAnimationMethod.Invoke(orbitalBeamComp, new object[] { durationTicks, 10, 0f }); + Log.Message("[EnergyLance] Orbital beam animation started"); + } + else + { + Log.Warning("[EnergyLance] Could not find StartAnimation method on CompOrbitalBeam"); + } + } + + private void StartSound() + { + var soundProp = orbitalBeamComp?.GetType().GetProperty("Props")?.GetValue(orbitalBeamComp); + if (soundProp != null) + { + var soundField = soundProp.GetType().GetField("sound"); + if (soundField != null) + { + SoundDef soundDef = soundField.GetValue(soundProp) as SoundDef; + if (soundDef != null) + { + sustainer = soundDef.TrySpawnSustainer(SoundInfo.InMap(this, MaintenanceType.PerTick)); + } + } } } @@ -86,110 +145,142 @@ namespace WulaFallenEmpire { base.Tick(); - if (!base.Destroyed && extension != null) + if (!hasStarted || hasCompleted) + return; + + ticksPassed++; + + // 更新移动进度 + UpdateMovement(); + + // 造成伤害 + for (int i = 0; i < firesPerTick; i++) { - // 移动光束 - MoveBeam(); - - // 造成伤害 - for (int i = 0; i < firesPerTick; i++) - { - DoBeamDamage(); - } + StartRandomFireAndDoFlameDamage(); + } + + // 更新音效 + sustainer?.Maintain(); + + // 检查是否完成 + if (ticksPassed >= durationTicks || currentProgress >= 1f) + { + CompleteEnergyLance(); } } - private void MoveBeam() + private void UpdateMovement() { - // 计算移动距离 - float moveThisTick = moveSpeed; + // 计算总距离 + float totalDistance = useFixedDistance ? moveDistance : Vector3.Distance(startPosition.ToVector3(), endPosition.ToVector3()); - // 更新位置 - currentPos += moveDirection * moveThisTick; - traveledDistance += moveThisTick; + // 计算移动速度(基于持续时间和总距离) + float progressPerTick = 1f / durationTicks; + currentProgress += progressPerTick; + currentProgress = Mathf.Clamp01(currentProgress); + + // 更新精确位置 + exactPosition = Vector3.Lerp(startPosition.ToVector3(), CalculateEndPosition(), currentProgress); + + // 更新格子位置 + IntVec3 newCell = new IntVec3( + Mathf.RoundToInt(exactPosition.x), + Mathf.RoundToInt(exactPosition.y), + Mathf.RoundToInt(exactPosition.z) + ); - // 更新光束的实际位置 - IntVec3 newCell = new IntVec3(Mathf.RoundToInt(currentPos.x), 0, Mathf.RoundToInt(currentPos.z)); if (newCell != base.Position && newCell.InBounds(base.Map)) { base.Position = newCell; } - - // 检查是否到达终点 - if (useFixedDistance && traveledDistance >= moveDistance) - { - // 固定距离模式:移动指定距离后结束 - Destroy(); - Log.Message($"[EnergyLance] Reached fixed distance, destroying"); - } - else if (!useFixedDistance && traveledDistance >= Vector3.Distance(startPos.ToVector3(), endPos.ToVector3())) - { - // 终点模式:到达终点后结束 - Destroy(); - Log.Message($"[EnergyLance] Reached end position, destroying"); - } } - private void DoBeamDamage() + private void StartRandomFireAndDoFlameDamage() { - if (extension == null) return; - - // 在当前光束位置周围随机选择一个单元格 IntVec3 targetCell = (from x in GenRadial.RadialCellsAround(base.Position, effectRadius, useCenter: true) where x.InBounds(base.Map) select x).RandomElementByWeight((IntVec3 x) => 1f - Mathf.Min(x.DistanceTo(base.Position) / effectRadius, 1f) + 0.05f); - // 尝试在该单元格点火(如果配置了点火) - if (extension.igniteFires) - { - FireUtility.TryStartFireIn(targetCell, base.Map, Rand.Range(0.1f, extension.fireIgniteChance), instigator); - } + FireUtility.TryStartFireIn(targetCell, base.Map, Rand.Range(0.1f, 0.925f), instigator); - // 对该单元格内的物体造成伤害 tmpThings.Clear(); tmpThings.AddRange(targetCell.GetThingList(base.Map)); for (int i = 0; i < tmpThings.Count; i++) { - Thing thing = tmpThings[i]; - - // 检查是否对尸体造成伤害 - if (!extension.applyDamageToCorpses && thing is Corpse) - continue; - - // 计算伤害量 - int damageAmount = (thing is Corpse) ? - extension.corpseDamageAmountRange.RandomInRange : - extension.damageAmountRange.RandomInRange; - - Pawn pawn = thing as Pawn; - BattleLogEntry_DamageTaken battleLogEntry = null; + int num = ((tmpThings[i] is Corpse) ? CorpseFlameDamageAmountRange.RandomInRange : FlameDamageAmountRange.RandomInRange); + Pawn pawn = tmpThings[i] as Pawn; + BattleLogEntry_DamageTaken battleLogEntry_DamageTaken = null; if (pawn != null) { - battleLogEntry = new BattleLogEntry_DamageTaken(pawn, RulePackDefOf.DamageEvent_PowerBeam, instigator as Pawn); - Find.BattleLog.Add(battleLogEntry); + battleLogEntry_DamageTaken = new BattleLogEntry_DamageTaken(pawn, RulePackDefOf.DamageEvent_PowerBeam, instigator as Pawn); + Find.BattleLog.Add(battleLogEntry_DamageTaken); } - // 使用ModExtension中定义的伤害类型 - DamageInfo damageInfo = new DamageInfo(extension.damageDef, damageAmount, 0f, -1f, instigator, null, weaponDef); - thing.TakeDamage(damageInfo).AssociateWithLog(battleLogEntry); - - Log.Message($"[EnergyLance] Applied {extension.damageDef.defName} damage {damageAmount} to {thing.Label}"); + DamageInfo damageInfo = new DamageInfo(DamageDefOf.Flame, num, 0f, -1f, instigator, null, weaponDef); + tmpThings[i].TakeDamage(damageInfo).AssociateWithLog(battleLogEntry_DamageTaken); } tmpThings.Clear(); } + private void CompleteEnergyLance() + { + hasCompleted = true; + + // 停止音效 + sustainer?.End(); + sustainer = null; + + Log.Message($"[EnergyLance] Completed at position {base.Position}"); + + // 销毁自身 + Destroy(); + } + + // 重写绘制方法,确保光束正确显示 + protected override void DrawAt(Vector3 drawLoc, bool flip = false) + { + // 让CompOrbitalBeam处理绘制 + Comps_PostDraw(); + } + public override void ExposeData() { base.ExposeData(); - Scribe_Values.Look(ref startPos, "startPos"); - Scribe_Values.Look(ref endPos, "endPos"); + Scribe_Values.Look(ref startPosition, "startPosition"); + Scribe_Values.Look(ref endPosition, "endPosition"); Scribe_Values.Look(ref moveDistance, "moveDistance"); Scribe_Values.Look(ref useFixedDistance, "useFixedDistance"); + Scribe_Values.Look(ref flightSpeed, "flightSpeed", 1f); + Scribe_Values.Look(ref currentProgress, "currentProgress", 0f); + Scribe_Values.Look(ref altitude, "altitude", 20f); Scribe_Values.Look(ref firesPerTick, "firesPerTick", 4); + Scribe_Values.Look(ref effectRadius, "effectRadius", 15f); + Scribe_Values.Look(ref durationTicks, "durationTicks", 600); + Scribe_Values.Look(ref ticksPassed, "ticksPassed", 0); + Scribe_Values.Look(ref hasStarted, "hasStarted", false); + Scribe_Values.Look(ref hasCompleted, "hasCompleted", false); + } + + // 创建EnergyLance的静态方法 + public static EnergyLance MakeEnergyLance(ThingDef energyLanceDef, IntVec3 start, IntVec3 end, Map map, + float distance = 15f, bool fixedDistance = true, int duration = 600, Pawn instigatorPawn = null) + { + EnergyLance energyLance = (EnergyLance)ThingMaker.MakeThing(energyLanceDef); + energyLance.startPosition = start; + energyLance.endPosition = end; + energyLance.moveDistance = distance; + energyLance.useFixedDistance = fixedDistance; + energyLance.durationTicks = duration; + energyLance.instigator = instigatorPawn; + + GenSpawn.Spawn(energyLance, start, map); + + Log.Message($"[EnergyLance] Created {energyLanceDef.defName} from {start} to {end}"); + return energyLance; } } } diff --git a/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/EnergyLanceExtension.cs b/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/EnergyLanceExtension.cs index 59b98a30..a4ea5904 100644 --- a/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/EnergyLanceExtension.cs +++ b/Source/WulaFallenEmpire/Ability/WULA_AbilityEnergyLance/EnergyLanceExtension.cs @@ -5,18 +5,13 @@ namespace WulaFallenEmpire { public class EnergyLanceExtension : DefModExtension { - // 伤害类型配置 - public DamageDef damageDef = DamageDefOf.Flame; // 伤害类型,默认为火焰伤害 - public bool applyDamageToCorpses = true; // 是否对尸体造成伤害 - public bool igniteFires = true; // 是否点燃火焰 - public float fireIgniteChance = 0.8f; // 点燃火焰的概率 + // 移动平滑配置 + public float moveSmoothing = 0.1f; // 移动平滑度 (0-1),值越小越平滑 + public int moteSpawnInterval = 3; // Mote生成间隔,值越大密度越低 + public float moteScale = 0.8f; // Mote缩放比例 - // 伤害量配置 - public IntRange damageAmountRange = new IntRange(65, 100); // 对生物的伤害范围 - public IntRange corpseDamageAmountRange = new IntRange(5, 10); // 对尸体的伤害范围 - - // 视觉效果配置 - public ThingDef moteDef; // 使用的Mote类型 - public SoundDef impactSound; // 撞击音效 + // 伤害配置 + public int firesPerTick = 4; + public float effectRadius = 15f; } } diff --git a/Source/WulaFallenEmpire/Ability/WULA_AbilityGuidedEnergyLance/CompBuildingEnergyLance.cs b/Source/WulaFallenEmpire/Ability/WULA_AbilityGuidedEnergyLance/CompBuildingEnergyLance.cs deleted file mode 100644 index 4bd58ae4..00000000 --- a/Source/WulaFallenEmpire/Ability/WULA_AbilityGuidedEnergyLance/CompBuildingEnergyLance.cs +++ /dev/null @@ -1,361 +0,0 @@ -using RimWorld; -using Verse; -using UnityEngine; -using System.Collections.Generic; -using System.Linq; - -namespace WulaFallenEmpire -{ - public class CompBuildingEnergyLance : ThingComp - { - public CompProperties_BuildingEnergyLance Props => (CompProperties_BuildingEnergyLance)props; - - // 状态管理 - private EnergyLanceState currentState = EnergyLanceState.Idle; - private int nextUpdateTick = 0; - private int noTargetTicks = 0; - - // 目标管理 - private Pawn currentTarget = null; - private IntVec3 lastTargetPosition = IntVec3.Invalid; - - // EnergyLance实例 - private GuidedEnergyLance activeLance = null; - - public override void PostSpawnSetup(bool respawningAfterLoad) - { - base.PostSpawnSetup(respawningAfterLoad); - - if (!respawningAfterLoad) - { - // 新生成时立即开始搜索目标 - nextUpdateTick = Find.TickManager.TicksGame; - currentState = EnergyLanceState.Searching; - - Log.Message($"[BuildingEnergyLance] Building spawned, starting target search"); - } - } - - private void UpdateState() - { - switch (currentState) - { - case EnergyLanceState.Idle: - // 空闲状态,等待下一次更新 - break; - - case EnergyLanceState.Searching: - SearchForTarget(); - break; - - case EnergyLanceState.Tracking: - TrackTarget(); - break; - - case EnergyLanceState.NoTarget: - HandleNoTarget(); - break; - } - } - - private void SearchForTarget() - { - Map map = parent.Map; - if (map == null) return; - - // 获取范围内的所有有效目标 - var potentialTargets = new List(); - - foreach (var pawn in map.mapPawns.AllPawnsSpawned) - { - if (IsValidTarget(pawn) && IsInRange(pawn.Position)) - { - potentialTargets.Add(pawn); - } - } - - if (potentialTargets.Count > 0) - { - // 选择第一个目标(可以改为其他选择逻辑) - currentTarget = potentialTargets[0]; - lastTargetPosition = currentTarget.Position; - - // 创建EnergyLance - CreateEnergyLance(); - - currentState = EnergyLanceState.Tracking; - noTargetTicks = 0; - - Log.Message($"[BuildingEnergyLance] Locked target: {currentTarget.Label}, position: {currentTarget.Position}"); - } - else - { - // 没有找到目标 - currentState = EnergyLanceState.NoTarget; - Log.Message($"[BuildingEnergyLance] No targets found in range"); - } - } - - private void TrackTarget() - { - if (currentTarget == null || !currentTarget.Spawned) - { - // 目标丢失,重新搜索 - currentState = EnergyLanceState.Searching; - currentTarget = null; - return; - } - - // 检查目标是否仍然有效 - if (!IsValidTarget(currentTarget) || !IsInRange(currentTarget.Position)) - { - // 目标无效或超出范围,寻找最近的敌人 - FindNearestTarget(); - return; - } - - // 更新目标位置 - lastTargetPosition = currentTarget.Position; - - // 向EnergyLance发送目标位置 - if (activeLance != null && !activeLance.Destroyed) - { - activeLance.UpdateTarget(lastTargetPosition); - noTargetTicks = 0; - - Log.Message($"[BuildingEnergyLance] Updated target position: {lastTargetPosition}"); - } - else - { - // EnergyLance丢失,重新创建 - CreateEnergyLance(); - } - } - - private void FindNearestTarget() - { - Map map = parent.Map; - if (map == null) return; - - Pawn nearestTarget = null; - float nearestDistance = float.MaxValue; - - // 获取当前EnergyLance位置 - IntVec3 searchCenter = (activeLance != null && !activeLance.Destroyed) ? - activeLance.Position : parent.Position; - - foreach (var pawn in map.mapPawns.AllPawnsSpawned) - { - if (IsValidTarget(pawn) && IsInRange(pawn.Position)) - { - float distance = Vector3.Distance(searchCenter.ToVector3(), pawn.Position.ToVector3()); - if (distance < nearestDistance) - { - nearestDistance = distance; - nearestTarget = pawn; - } - } - } - - if (nearestTarget != null) - { - currentTarget = nearestTarget; - lastTargetPosition = currentTarget.Position; - - // 更新EnergyLance目标 - if (activeLance != null && !activeLance.Destroyed) - { - activeLance.UpdateTarget(lastTargetPosition); - } - - Log.Message($"[BuildingEnergyLance] Switched to nearest target: {currentTarget.Label}, distance: {nearestDistance}"); - } - else - { - // 没有找到替代目标 - currentState = EnergyLanceState.NoTarget; - currentTarget = null; - Log.Message($"[BuildingEnergyLance] No alternative targets found"); - } - } - - private void HandleNoTarget() - { - noTargetTicks++; - - // 向EnergyLance发送空位置 - if (activeLance != null && !activeLance.Destroyed) - { - activeLance.UpdateTarget(IntVec3.Invalid); - } - - // 检查是否应该销毁EnergyLance - if (noTargetTicks >= Props.maxNoTargetTicks) - { - if (activeLance != null && !activeLance.Destroyed) - { - activeLance.Destroy(); - activeLance = null; - } - - // 回到搜索状态 - currentState = EnergyLanceState.Searching; - noTargetTicks = 0; - - Log.Message($"[BuildingEnergyLance] EnergyLance destroyed due to no targets"); - } - else if (noTargetTicks % 60 == 0) // 每60刻检查一次是否有新目标 - { - SearchForTarget(); - } - } - - private void CreateEnergyLance() - { - if (Props.energyLanceDef == null) - { - Log.Error($"[BuildingEnergyLance] No energyLanceDef configured"); - return; - } - - try - { - // 销毁现有的EnergyLance - if (activeLance != null && !activeLance.Destroyed) - { - activeLance.Destroy(); - } - - // 创建新的EnergyLance - IntVec3 spawnPos = GetLanceSpawnPosition(); - activeLance = (GuidedEnergyLance)GenSpawn.Spawn(Props.energyLanceDef, spawnPos, parent.Map); - - // 初始化EnergyLance - activeLance.duration = Props.energyLanceDuration; - activeLance.instigator = parent; - activeLance.controlBuilding = this.parent; - activeLance.firesPerTick = Props.firesPerTick; - - // 如果有当前目标,设置初始位置 - if (currentTarget != null) - { - activeLance.UpdateTarget(currentTarget.Position); - } - - activeLance.StartStrike(); - - Log.Message($"[BuildingEnergyLance] Created EnergyLance at {spawnPos}"); - } - catch (System.Exception ex) - { - Log.Error($"[BuildingEnergyLance] Error creating EnergyLance: {ex}"); - } - } - - private IntVec3 GetLanceSpawnPosition() - { - // 在建筑周围寻找一个合适的生成位置 - Map map = parent.Map; - IntVec3 center = parent.Position; - - // 优先选择建筑上方的位置 - if (center.InBounds(map) && center.Walkable(map)) - { - return center; - } - - // 如果建筑位置不可用,在周围寻找 - foreach (IntVec3 cell in GenRadial.RadialCellsAround(center, 2f, true)) - { - if (cell.InBounds(map) && cell.Walkable(map)) - { - return cell; - } - } - - // 如果都不可用,返回建筑位置 - return center; - } - - private bool IsValidTarget(Pawn pawn) - { - if (pawn == null || pawn.Downed || pawn.Dead || !pawn.Spawned) - return false; - - // 检查目标类型 - if (Props.targetEnemies && pawn.HostileTo(parent.Faction)) - return true; - - if (Props.targetNeutrals && !pawn.HostileTo(parent.Faction) && pawn.Faction != parent.Faction) - return true; - - if (Props.targetAnimals && pawn.RaceProps.Animal) - return true; - - return false; - } - - private bool IsInRange(IntVec3 position) - { - float distance = Vector3.Distance(parent.Position.ToVector3(), position.ToVector3()); - return distance <= Props.radius; - } - - public override void CompTick() - { - base.CompTick(); - - int currentTick = Find.TickManager.TicksGame; - - // 检查是否需要更新状态 - if (currentTick >= nextUpdateTick) - { - UpdateState(); - nextUpdateTick = currentTick + Props.updateIntervalTicks; - } - - // 检查EnergyLance状态 - if (activeLance != null && activeLance.Destroyed) - { - activeLance = null; - if (currentState == EnergyLanceState.Tracking) - { - currentState = EnergyLanceState.Searching; - } - } - } - - // 外部调用:当EnergyLance需要目标时调用 - public bool TryGetCurrentTarget(out IntVec3 targetPos) - { - if (currentTarget != null && IsValidTarget(currentTarget) && IsInRange(currentTarget.Position)) - { - targetPos = currentTarget.Position; - return true; - } - - targetPos = IntVec3.Invalid; - return false; - } - - public override void PostExposeData() - { - base.PostExposeData(); - - Scribe_Values.Look(ref currentState, "currentState", EnergyLanceState.Idle); - Scribe_Values.Look(ref nextUpdateTick, "nextUpdateTick", 0); - Scribe_Values.Look(ref noTargetTicks, "noTargetTicks", 0); - Scribe_References.Look(ref currentTarget, "currentTarget"); - Scribe_Values.Look(ref lastTargetPosition, "lastTargetPosition", IntVec3.Invalid); - Scribe_References.Look(ref activeLance, "activeLance"); - } - } - - public enum EnergyLanceState - { - Idle, - Searching, - Tracking, - NoTarget - } -} diff --git a/Source/WulaFallenEmpire/Ability/WULA_AbilityGuidedEnergyLance/CompProperties_BuildingEnergyLance.cs b/Source/WulaFallenEmpire/Ability/WULA_AbilityGuidedEnergyLance/CompProperties_BuildingEnergyLance.cs deleted file mode 100644 index c10e475f..00000000 --- a/Source/WulaFallenEmpire/Ability/WULA_AbilityGuidedEnergyLance/CompProperties_BuildingEnergyLance.cs +++ /dev/null @@ -1,28 +0,0 @@ -using RimWorld; -using Verse; - -namespace WulaFallenEmpire -{ - public class CompProperties_BuildingEnergyLance : CompProperties - { - // 基础配置 - public float radius = 20f; // 作用半径 - public int updateIntervalTicks = 30; // 目标更新间隔(刻) - public int maxNoTargetTicks = 120; // 无目标时最大存活时间 - - // 目标选择配置 - public bool targetEnemies = true; // 是否以敌人为目标 - public bool targetNeutrals = false; // 是否以中立单位为目标 - public bool targetAnimals = false; // 是否以动物为目标 - - // EnergyLance配置 - public ThingDef energyLanceDef; // 使用的EnergyLance类型 - public int energyLanceDuration = 600; // EnergyLance基础持续时间 - public int firesPerTick = 3; // 每刻伤害次数 - - public CompProperties_BuildingEnergyLance() - { - this.compClass = typeof(CompBuildingEnergyLance); - } - } -} diff --git a/Source/WulaFallenEmpire/Ability/WULA_AbilityGuidedEnergyLance/GuidedEnergyLance.cs b/Source/WulaFallenEmpire/Ability/WULA_AbilityGuidedEnergyLance/GuidedEnergyLance.cs deleted file mode 100644 index 150f0243..00000000 --- a/Source/WulaFallenEmpire/Ability/WULA_AbilityGuidedEnergyLance/GuidedEnergyLance.cs +++ /dev/null @@ -1,255 +0,0 @@ -using RimWorld; -using Verse; -using UnityEngine; -using System.Collections.Generic; -using System.Linq; - -namespace WulaFallenEmpire -{ - public class GuidedEnergyLance : OrbitalStrike - { - // 引导相关属性 - public Thing controlBuilding; // 控制建筑 - private IntVec3 currentTarget = IntVec3.Invalid; // 当前目标位置 - private int lastTargetUpdateTick = -1; // 最后收到目标更新的刻 - private int maxNoUpdateTicks = 60; // 无更新时的最大存活时间 - - // 移动配置 - public float moveSpeed = 2.0f; // 移动速度(格/秒) - public float turnSpeed = 90f; // 转向速度(度/秒) - - // 状态 - private Vector3 currentVelocity; - private bool hasValidTarget = false; - - // ModExtension引用 - private EnergyLanceExtension extension; - - private static List tmpThings = new List(); - - public override void StartStrike() - { - base.StartStrike(); - - // 获取ModExtension - extension = def.GetModExtension(); - if (extension == null) - { - Log.Error($"[GuidedEnergyLance] No EnergyLanceExtension found on {def.defName}"); - return; - } - - lastTargetUpdateTick = Find.TickManager.TicksGame; - - // 创建视觉效果 - CreateVisualEffect(); - - Log.Message($"[GuidedEnergyLance] Guided EnergyLance started, controlled by {controlBuilding?.Label ?? "None"}"); - } - - private void CreateVisualEffect() - { - // 使用ModExtension中定义的Mote,如果没有则使用默认的PowerBeam - if (extension.moteDef != null) - { - Mote mote = MoteMaker.MakeStaticMote(base.Position, base.Map, extension.moteDef); - } - else - { - // 使用原版PowerBeam的视觉效果 - MoteMaker.MakePowerBeamMote(base.Position, base.Map); - } - } - - protected override void Tick() - { - base.Tick(); - - if (!base.Destroyed && extension != null) - { - // 检查目标更新状态 - CheckTargetStatus(); - - // 移动光束 - MoveBeam(); - - // 造成伤害 - for (int i = 0; i < firesPerTick; i++) - { - DoBeamDamage(); - } - } - } - - private void CheckTargetStatus() - { - int currentTick = Find.TickManager.TicksGame; - int ticksSinceUpdate = currentTick - lastTargetUpdateTick; - - // 检查是否长时间未收到更新 - if (ticksSinceUpdate >= maxNoUpdateTicks) - { - Log.Message($"[GuidedEnergyLance] No target updates for {ticksSinceUpdate} ticks, destroying"); - Destroy(); - return; - } - - // 检查控制建筑状态 - if (controlBuilding == null || controlBuilding.Destroyed || !controlBuilding.Spawned) - { - Log.Message($"[GuidedEnergyLance] Control building lost, destroying"); - Destroy(); - return; - } - } - - private void MoveBeam() - { - if (!hasValidTarget || !currentTarget.IsValid) - { - // 没有有效目标,缓慢移动或保持原地 - ApplyMinimalMovement(); - return; - } - - // 计算移动方向 - Vector3 targetDirection = (currentTarget.ToVector3() - base.Position.ToVector3()).normalized; - - // 平滑转向 - if (currentVelocity.magnitude > 0.1f) - { - float maxTurnAngle = turnSpeed * 0.0167f; // 每帧最大转向角度(假设60FPS) - currentVelocity = Vector3.RotateTowards(currentVelocity, targetDirection, maxTurnAngle * Mathf.Deg2Rad, moveSpeed * 0.0167f); - } - else - { - currentVelocity = targetDirection * moveSpeed * 0.0167f; - } - - // 应用移动 - Vector3 newPos = base.Position.ToVector3() + currentVelocity; - IntVec3 newCell = new IntVec3(Mathf.RoundToInt(newPos.x), 0, Mathf.RoundToInt(newPos.z)); - - if (newCell != base.Position && newCell.InBounds(base.Map)) - { - base.Position = newCell; - } - - // 检查是否接近目标 - float distanceToTarget = Vector3.Distance(base.Position.ToVector3(), currentTarget.ToVector3()); - if (distanceToTarget < 1.5f) - { - // 到达目标附近,可以减速或保持位置 - currentVelocity *= 0.8f; - } - - Log.Message($"[GuidedEnergyLance] Moving to {currentTarget}, distance: {distanceToTarget:F1}"); - } - - private void ApplyMinimalMovement() - { - // 无目标时的最小移动,防止完全静止 - if (currentVelocity.magnitude < 0.1f) - { - // 随机轻微移动 - currentVelocity = new Vector3(Rand.Range(-0.1f, 0.1f), 0f, Rand.Range(-0.1f, 0.1f)); - } - else - { - // 缓慢减速 - currentVelocity *= 0.95f; - } - - Vector3 newPos = base.Position.ToVector3() + currentVelocity; - IntVec3 newCell = new IntVec3(Mathf.RoundToInt(newPos.x), 0, Mathf.RoundToInt(newPos.z)); - - if (newCell != base.Position && newCell.InBounds(base.Map)) - { - base.Position = newCell; - } - } - - private void DoBeamDamage() - { - if (extension == null) return; - - // 在当前光束位置周围随机选择一个单元格 - IntVec3 targetCell = (from x in GenRadial.RadialCellsAround(base.Position, 2f, useCenter: true) - where x.InBounds(base.Map) - select x).RandomElementByWeight((IntVec3 x) => 1f - Mathf.Min(x.DistanceTo(base.Position) / 2f, 1f) + 0.05f); - - // 尝试在该单元格点火(如果配置了点火) - if (extension.igniteFires) - { - FireUtility.TryStartFireIn(targetCell, base.Map, Rand.Range(0.1f, extension.fireIgniteChance), instigator); - } - - // 对该单元格内的物体造成伤害 - tmpThings.Clear(); - tmpThings.AddRange(targetCell.GetThingList(base.Map)); - - for (int i = 0; i < tmpThings.Count; i++) - { - Thing thing = tmpThings[i]; - - // 检查是否对尸体造成伤害 - if (!extension.applyDamageToCorpses && thing is Corpse) - continue; - - // 计算伤害量 - int damageAmount = (thing is Corpse) ? - extension.corpseDamageAmountRange.RandomInRange : - extension.damageAmountRange.RandomInRange; - - Pawn pawn = thing as Pawn; - BattleLogEntry_DamageTaken battleLogEntry = null; - - if (pawn != null) - { - battleLogEntry = new BattleLogEntry_DamageTaken(pawn, RulePackDefOf.DamageEvent_PowerBeam, instigator as Pawn); - Find.BattleLog.Add(battleLogEntry); - } - - // 使用ModExtension中定义的伤害类型 - DamageInfo damageInfo = new DamageInfo(extension.damageDef, damageAmount, 0f, -1f, instigator, null, weaponDef); - thing.TakeDamage(damageInfo).AssociateWithLog(battleLogEntry); - } - - tmpThings.Clear(); - } - - // 外部调用:更新目标位置 - public void UpdateTarget(IntVec3 newTarget) - { - lastTargetUpdateTick = Find.TickManager.TicksGame; - - if (newTarget.IsValid && newTarget.InBounds(base.Map)) - { - currentTarget = newTarget; - hasValidTarget = true; - - Log.Message($"[GuidedEnergyLance] Target updated to {newTarget}"); - } - else - { - hasValidTarget = false; - currentTarget = IntVec3.Invalid; - - Log.Message($"[GuidedEnergyLance] Target cleared"); - } - } - - public override void ExposeData() - { - base.ExposeData(); - - Scribe_References.Look(ref controlBuilding, "controlBuilding"); - Scribe_Values.Look(ref currentTarget, "currentTarget", IntVec3.Invalid); - Scribe_Values.Look(ref lastTargetUpdateTick, "lastTargetUpdateTick", -1); - Scribe_Values.Look(ref maxNoUpdateTicks, "maxNoUpdateTicks", 60); - Scribe_Values.Look(ref moveSpeed, "moveSpeed", 2.0f); - Scribe_Values.Look(ref turnSpeed, "turnSpeed", 90f); - Scribe_Values.Look(ref firesPerTick, "firesPerTick", 3); - } - } -} diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj index 34950f92..612883ea 100644 --- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj +++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj @@ -76,8 +76,9 @@ + - +