1
This commit is contained in:
Binary file not shown.
@@ -658,7 +658,7 @@
|
||||
<initialDamage>15</initialDamage>
|
||||
<damagePerTile>1.5</damagePerTile>
|
||||
<inertiaDistance>6</inertiaDistance>
|
||||
<collisionDamageDef>Blunt</collisionDamageDef>
|
||||
<collisionDamageDef>Demolish</collisionDamageDef>
|
||||
<flyerDef>ARA_Flyer_TrackingCharge</flyerDef>
|
||||
<collisionRadius>1.5</collisionRadius> <!-- Larger collision radius -->
|
||||
<impactSound>Pawn_Melee_BigBash_HitPawn</impactSound>
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
<initialDamage>50</initialDamage>
|
||||
<damagePerTile>3</damagePerTile>
|
||||
<inertiaDistance>15</inertiaDistance>
|
||||
<collisionDamageDef>Blunt</collisionDamageDef>
|
||||
<collisionDamageDef>Demolish</collisionDamageDef>
|
||||
<flyerDef>ARA_Flyer_TrackingCharge</flyerDef>
|
||||
<collisionRadius>3.5</collisionRadius> <!-- Larger collision radius -->
|
||||
<impactSound>Pawn_Melee_BigBash_HitPawn</impactSound>
|
||||
|
||||
Binary file not shown.
@@ -7,16 +7,16 @@
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\trackingcharge\\pawnflyer_trackingcharge.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\trackingcharge\\verb_castabilitytrackingcharge.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\abilities\\trackingcharge\\compabilityeffect_trackingcharge.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\trackingcharge\\compabilityeffect_trackingcharge.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\abilities\\trackingcharge\\verb_castabilitytrackingcharge.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\trackingcharge\\verb_castabilitytrackingcharge.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\trackingcharge\\compproperties_trackingcharge.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\abilities\\trackingcharge\\compproperties_trackingcharge.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\trackingcharge\\compproperties_trackingcharge.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\trackingcharge\\compabilityeffect_trackingcharge.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\trackingcharge\\compabilityeffect_trackingcharge.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
}
|
||||
],
|
||||
"DocumentGroupContainers": [
|
||||
@@ -34,7 +34,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"DocumentIndex": 2,
|
||||
"Title": "Verb_CastAbilityTrackingCharge.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\TrackingCharge\\Verb_CastAbilityTrackingCharge.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\TrackingCharge\\Verb_CastAbilityTrackingCharge.cs",
|
||||
@@ -42,8 +42,7 @@
|
||||
"RelativeToolTip": "Abilities\\TrackingCharge\\Verb_CastAbilityTrackingCharge.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAABIAAAANAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-31T03:34:14.205Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2025-12-31T03:34:14.205Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
@@ -53,14 +52,14 @@
|
||||
"RelativeDocumentMoniker": "Abilities\\TrackingCharge\\PawnFlyer_TrackingCharge.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\TrackingCharge\\PawnFlyer_TrackingCharge.cs",
|
||||
"RelativeToolTip": "Abilities\\TrackingCharge\\PawnFlyer_TrackingCharge.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAoAAAABAAAAAAAAAA==",
|
||||
"ViewState": "AgIAAIwBAAAAAAAAAAAAAKMBAAA3AAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-31T03:34:13.727Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 2,
|
||||
"DocumentIndex": 3,
|
||||
"Title": "CompProperties_TrackingCharge.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\TrackingCharge\\CompProperties_TrackingCharge.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\TrackingCharge\\CompProperties_TrackingCharge.cs",
|
||||
@@ -68,18 +67,17 @@
|
||||
"RelativeToolTip": "Abilities\\TrackingCharge\\CompProperties_TrackingCharge.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-31T03:34:13.26Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2025-12-31T03:34:13.26Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 3,
|
||||
"DocumentIndex": 1,
|
||||
"Title": "CompAbilityEffect_TrackingCharge.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\TrackingCharge\\CompAbilityEffect_TrackingCharge.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\TrackingCharge\\CompAbilityEffect_TrackingCharge.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\TrackingCharge\\CompAbilityEffect_TrackingCharge.cs",
|
||||
"RelativeToolTip": "Abilities\\TrackingCharge\\CompAbilityEffect_TrackingCharge.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAABAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-31T03:34:12.758Z",
|
||||
"EditorCaption": ""
|
||||
|
||||
@@ -30,6 +30,9 @@ namespace ArachnaeSwarm
|
||||
private IntVec3? desiredLandingCell = null; // 新增:期望的降落位置
|
||||
private bool isLanding = false; // 新增:标记是否正在降落
|
||||
private bool positionAdjusted = false; // 新增:标记是否已调整位置
|
||||
private HashSet<Thing> alreadyDamaged = new HashSet<Thing>(); // 新增:记录已经造成伤害的目标
|
||||
private int lastPathDamageTick = 0; // 新增:上次路径伤害的tick
|
||||
private const int PATH_DAMAGE_INTERVAL = 2; // 新增:路径伤害间隔(每2帧检查一次)
|
||||
|
||||
// --- Reflection Fields ---
|
||||
private static FieldInfo TicksFlyingInfo;
|
||||
@@ -79,6 +82,8 @@ namespace ArachnaeSwarm
|
||||
if (!respawningAfterLoad)
|
||||
{
|
||||
this.exactPosition = base.DrawPos;
|
||||
alreadyDamaged.Clear();
|
||||
lastPathDamageTick = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +105,9 @@ namespace ArachnaeSwarm
|
||||
DestCellInfo.SetValue(this, primaryTarget.Thing.Position);
|
||||
}
|
||||
|
||||
// --- 路径伤害逻辑:飞行过程中持续造成伤害 ---
|
||||
ApplyPathDamage();
|
||||
|
||||
// --- 主目标碰撞检测 ---
|
||||
if (!hasHitPrimaryTarget && primaryTarget.HasThing && primaryTarget.Thing.Spawned)
|
||||
{
|
||||
@@ -113,9 +121,6 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
}
|
||||
|
||||
// --- AOE伤害逻辑 ---
|
||||
ApplyAoeDamage();
|
||||
|
||||
// --- 基础Tick逻辑 ---
|
||||
base.Tick();
|
||||
|
||||
@@ -126,7 +131,100 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:处理主目标碰撞
|
||||
// 修改:应用路径伤害(飞行过程中持续造成伤害)
|
||||
private void ApplyPathDamage()
|
||||
{
|
||||
int ticksFlying = (int)TicksFlyingInfo.GetValue(this);
|
||||
|
||||
// 限制检查频率
|
||||
if (ticksFlying - lastPathDamageTick < PATH_DAMAGE_INTERVAL)
|
||||
return;
|
||||
|
||||
lastPathDamageTick = ticksFlying;
|
||||
|
||||
// 计算当前伤害值
|
||||
Vector3 startPosition = (Vector3)StartVecInfo.GetValue(this);
|
||||
float distanceTravelled = (this.DrawPos - startPosition).magnitude;
|
||||
float currentDamage = this.initialDamage + (distanceTravelled * this.damagePerTile);
|
||||
|
||||
// 获取当前位置周围的所有物体
|
||||
var thingsInRadius = GenRadial.RadialDistinctThingsAround(this.Position, this.Map, this.collisionRadius, false).ToList();
|
||||
|
||||
foreach (var thing in thingsInRadius)
|
||||
{
|
||||
// 跳过自己、飞行器和已经被伤害过的目标
|
||||
if (thing == this.FlyingPawn || thing == this || alreadyDamaged.Contains(thing))
|
||||
continue;
|
||||
|
||||
// 如果是主目标,跳过(主目标有专门的碰撞检测)
|
||||
if (primaryTarget.HasThing && thing == primaryTarget.Thing && !hasHitPrimaryTarget)
|
||||
continue;
|
||||
|
||||
// 检查是否需要伤害
|
||||
if (ShouldDamageThing(thing))
|
||||
{
|
||||
// 创建伤害信息
|
||||
var dinfo = new DamageInfo(this.collisionDamageDef, currentDamage, 1f, -1, this.FlyingPawn);
|
||||
|
||||
// 应用伤害
|
||||
thing.TakeDamage(dinfo);
|
||||
|
||||
// 记录已经伤害过的目标
|
||||
alreadyDamaged.Add(thing);
|
||||
|
||||
// 播放音效(可选)
|
||||
if (this.impactSound != null && thing is Pawn)
|
||||
{
|
||||
SoundStarter.PlayOneShot(this.impactSound, new TargetInfo(thing.Position, this.Map));
|
||||
}
|
||||
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
ArachnaeLog.Debug($"TrackingCharge path damage: {thing.LabelCap} took {currentDamage} damage");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 可选:添加视觉效果
|
||||
if (ticksFlying % 10 == 0 && Prefs.DevMode)
|
||||
{
|
||||
FleckMaker.ThrowDustPuff(this.DrawPos + Gen.RandomHorizontalVector(0.5f), this.Map, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:判断是否应该伤害物体
|
||||
private bool ShouldDamageThing(Thing thing)
|
||||
{
|
||||
if (thing == null || thing.Destroyed)
|
||||
return false;
|
||||
|
||||
// 如果是生物
|
||||
if (thing is Pawn pawn)
|
||||
{
|
||||
if (pawn.Downed || pawn.Dead)
|
||||
return false;
|
||||
|
||||
// 检查是否只伤害敌对目标
|
||||
if (this.damageHostileOnly && !pawn.HostileTo(this.FlyingPawn))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
// 如果是建筑
|
||||
else if (thing.def.destroyable && thing.def.building != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// 如果是门或其他障碍物
|
||||
else if (thing.def.passability == Traversability.PassThroughOnly)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 修改:处理主目标碰撞
|
||||
private void ImpactPrimaryTarget()
|
||||
{
|
||||
// 播放音效
|
||||
@@ -144,6 +242,12 @@ namespace ArachnaeSwarm
|
||||
primaryTarget.Thing.TakeDamage(dinfo);
|
||||
hasHitPrimaryTarget = true;
|
||||
|
||||
// 将主目标添加到已伤害列表,避免后续路径伤害重复伤害
|
||||
if (!alreadyDamaged.Contains(primaryTarget.Thing))
|
||||
{
|
||||
alreadyDamaged.Add(primaryTarget.Thing);
|
||||
}
|
||||
|
||||
homing = false;
|
||||
|
||||
// 计算期望的降落位置(目标身后一格)
|
||||
@@ -312,42 +416,6 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:应用AOE伤害
|
||||
private void ApplyAoeDamage()
|
||||
{
|
||||
if (!hasHitPrimaryTarget)
|
||||
return;
|
||||
|
||||
Vector3 startPosition = (Vector3)StartVecInfo.GetValue(this);
|
||||
float distanceTravelled = (this.DrawPos - startPosition).magnitude;
|
||||
float currentAOEDamage = this.initialDamage + (distanceTravelled * this.damagePerTile);
|
||||
|
||||
// 只应用一次AOE伤害,避免每帧都造成伤害
|
||||
int ticksFlying = (int)TicksFlyingInfo.GetValue(this);
|
||||
if (ticksFlying % 5 != 0) // 每5帧检查一次
|
||||
return;
|
||||
|
||||
foreach (var thing in GenRadial.RadialDistinctThingsAround(this.Position, this.Map, this.collisionRadius, false))
|
||||
{
|
||||
if (thing != this.FlyingPawn && thing != this && thing != primaryTarget.Thing)
|
||||
{
|
||||
if (thing is Pawn pawn && !pawn.Downed)
|
||||
{
|
||||
if (!this.damageHostileOnly || pawn.HostileTo(this.FlyingPawn))
|
||||
{
|
||||
var aoeDinfo = new DamageInfo(this.collisionDamageDef, currentAOEDamage, 1f, -1, this.FlyingPawn);
|
||||
pawn.TakeDamage(aoeDinfo);
|
||||
}
|
||||
}
|
||||
else if (thing.def.destroyable && thing.def.building != null)
|
||||
{
|
||||
var aoeDinfo = new DamageInfo(this.collisionDamageDef, currentAOEDamage, 1f, -1, this.FlyingPawn);
|
||||
thing.TakeDamage(aoeDinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:在飞行器销毁前调整位置
|
||||
protected override void TickInterval(int delta)
|
||||
{
|
||||
@@ -415,9 +483,14 @@ namespace ArachnaeSwarm
|
||||
Scribe_Values.Look(ref hasHitPrimaryTarget, "hasHitPrimaryTarget", false);
|
||||
Scribe_Values.Look(ref isLanding, "isLanding", false);
|
||||
Scribe_Values.Look(ref positionAdjusted, "positionAdjusted", false);
|
||||
Scribe_Values.Look(ref lastPathDamageTick, "lastPathDamageTick", 0);
|
||||
|
||||
// 保存已伤害的目标列表
|
||||
if (Scribe.mode == LoadSaveMode.Saving)
|
||||
{
|
||||
List<Thing> damagedThingsList = alreadyDamaged.ToList();
|
||||
Scribe_Collections.Look(ref damagedThingsList, "damagedThings", LookMode.Reference);
|
||||
|
||||
if (desiredLandingCell.HasValue)
|
||||
{
|
||||
IntVec3 cell = desiredLandingCell.Value;
|
||||
@@ -426,6 +499,13 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
else if (Scribe.mode == LoadSaveMode.LoadingVars)
|
||||
{
|
||||
List<Thing> damagedThingsList = null;
|
||||
Scribe_Collections.Look(ref damagedThingsList, "damagedThings", LookMode.Reference);
|
||||
if (damagedThingsList != null)
|
||||
{
|
||||
alreadyDamaged = new HashSet<Thing>(damagedThingsList);
|
||||
}
|
||||
|
||||
IntVec3 cell = IntVec3.Invalid;
|
||||
Scribe_Values.Look(ref cell, "desiredLandingCell");
|
||||
if (cell.IsValid)
|
||||
|
||||
Reference in New Issue
Block a user