diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll
index b7f1f347..4768d82b 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/Effects/WulaFleckDefs.xml b/1.6/1.6/Defs/Effects/WulaFleckDefs.xml
index 574b6491..fa4885d3 100644
--- a/1.6/1.6/Defs/Effects/WulaFleckDefs.xml
+++ b/1.6/1.6/Defs/Effects/WulaFleckDefs.xml
@@ -22,11 +22,14 @@
WULA_GunTail_Lighting
Projectile
- 0.5
+ 0.50
+ 1
+ 1.2
+ 0.005
Wula/Mote/WULA_Lighting_Beam
MoteGlow
- (113,165,225,155)
+ (113,165,225,255)
(0.5,2)
diff --git a/1.6/1.6/Defs/EventDefs/EventDef_Wula/Wula_MainEvent.xml b/1.6/1.6/Defs/EventDefs/EventDef_Wula/Wula_MainEvent.xml
index c37c9681..a8153791 100644
--- a/1.6/1.6/Defs/EventDefs/EventDef_Wula/Wula_MainEvent.xml
+++ b/1.6/1.6/Defs/EventDefs/EventDef_Wula/Wula_MainEvent.xml
@@ -27,6 +27,13 @@
1
Int
+
+
+
+ Wula_Legion_Personal_Goodwill
+ 0
+ Int
+
@@ -41,6 +48,9 @@
+
+ Wula_UI_Legion_10
+
@@ -68,6 +78,28 @@
+
+ 有什么任务吗···
+
+ false
+ false
+
+
+
+
+ Wula_UI_Legion_50
+
+
+
+
+
+
我们想要接受晋级审查···
true
@@ -124,6 +156,218 @@
+
+ Wula_UI_Legion_10
+ 未知通讯
+ Wula/Events/Portraits/WULA_Legion_5
+ 「军团」,P.I.A
+
+ 嗯嗯?
+ 好的——那么,你们要问什么?
+ 哎,行吧,想问什么?
+
+
+
+ 你是谁?
+ false
+
+
+
+
+
+ Wula_UI_Legion_11
+
+
+
+
+
+
+ 我们需要做什么?(发展流程)
+ false
+
+
+
+
+
+ Wula_UI_Legion_14
+
+
+
+
+
+
+ 没有别的问题了······
+ false
+
+
+
+
+ Wula_UI_Legion_1
+
+
+
+
+
+
+
+
+
+ Wula_UI_Legion_11
+ 未知通讯
+ Wula/Events/Portraits/WULA_Legion_3
+ 「军团」,P.I.A
+
+ 记忆体坏掉了?\n\n···好吧,你们可以叫我「军团」,我是负责管理乌拉帝国行星封锁机关舰队的AI,根据你们的编制来说,我是你们的顶头上司。在登陆地表前,机械行会没有给你们设置正确的记忆扇区吗?
+
+
+
+ 行星封锁机关?
+ false
+
+
+
+
+
+ Wula_UI_Legion_12
+
+
+
+
+
+
+ 机械行会?
+ false
+
+
+
+
+
+ Wula_UI_Legion_13
+
+
+
+
+
+
+ 我们没有相关问题了···
+ false
+
+
+
+
+
+ Wula_UI_Legion_10
+
+
+
+
+
+
+
+
+ Wula_UI_Legion_12
+ 未知通讯
+ Wula/Events/Portraits/WULA_Legion_3
+ 「军团」,P.I.A
+
+ 行星封锁机关是隶属于乌拉帝国开发署的暴力机关,控制着开发署所有的舰队,负责在疆域开拓中的侵略性接触。\n\n通常来说,类似边缘世界这样的星球,我们会直接封锁轨道,轰炸所有现存聚居地然后再投放殖民者,不过看起来这个世界还有救,所以你们作为第一批先遣队投放到星球上,和其他异族接触试探一下,明白了吗?
+
+
+
+ 我们还有别的问题···
+ false
+
+
+
+
+
+ Wula_UI_Legion_11
+
+
+
+
+
+
+ 我们没有相关问题了···
+ false
+
+
+
+
+
+ Wula_UI_Legion_10
+
+
+
+
+
+
+
+
+ Wula_UI_Legion_13
+ 未知通讯
+ Wula/Events/Portraits/WULA_Legion_3
+ 「军团」,P.I.A
+
+ 乌拉帝国机械行会负责所有的合成人的生产、审查、投放和初始化,你们在部署到舰队上时,应该会有一个机械师帮你们设置好预载了记忆的扇区,但是很显然那家伙失职了,才让你们在这里拿着一堆你们早该知道的事情来烦我。
+
+
+
+ 我们还有别的问题···
+ false
+
+
+
+
+
+ Wula_UI_Legion_11
+
+
+
+
+
+
+ 我们没有相关问题了···
+ false
+
+
+
+
+
+ Wula_UI_Legion_10
+
+
+
+
+
+
+
+
+ Wula_UI_Legion_14
+ 未知通讯
+ Wula/Events/Portraits/WULA_Legion_3
+ 「军团」,P.I.A
+
+ 你们的意思是,你们连不知道要干什么就被丢下来了?\n\n哎,你们要做的就是施展你们的百般武艺活下来,建立一个根据地。根据帝国税收法,你们每个一段时间需要上交税款——作为帝国殖民地,舰队和机群将成为你们的后盾。\n\n如果你们觉得你们准备好了,可以申请权限进阶审查,我会部署一个带卫队的分体去你们的殖民地考察一段时间,然后根据评级决定是否给你们晋升。晋升后的殖民地会获得更多的许可,允许调用更加强大的武备和支援。
+
+
+
+ 我们没有相关问题了···
+ false
+
+
+
+
+
+ Wula_UI_Legion_10
+
+
+
+
+
+
+
+
Wula_UI_Legion_30
和P.I.A的通讯
@@ -827,6 +1071,102 @@
+
+
+ Wula_UI_Legion_50
+ 和P.I.A的通讯
+ Wula/Events/Portraits/WULA_Legion_1
+ 「军团」,P.I.A
+
+
+
+
+
+
+ Wula_Reinforcement_From_PIA_Level
+ 2
+
+
+ 好吧,我手上有一些活,怎么说呢,不太好走乌拉帝国的标准审查流程,我的断爪卫队也不适合去做这些事情,确实需要有人帮我处理。\n\n你们挑个感兴趣的类型吧,我会把任务的需求发给你们。
+
+
+
+
+ Wula_Reinforcement_From_PIA_Level
+ 3
+
+
+ 你们应该已经遇到了那些帝国的叛徒了?我们已经陆陆续续地发现了她们在这个星球活动的迹象,你们的任务很难避开她们,要做好打硬仗的准备。\n\n你们挑个感兴趣的类型吧,我会把任务的需求发给你们。
+
+
+
+
+
+
+
+
+
+
+ 我们希望接受远征任务
+
+
+
+
+
+
+
+
+
+
+ 我们希望接受防守任务
+
+
+
+
+
+
+
+
+
+
+ 有没有什么特殊的任务···
+
+
+
+
+
+
+
+
+
+
+ 现在不太合适···
+ false
+
+
+
+
+ Wula_UI_Legion_1
+
+
+
+
+
+
+
+
diff --git a/1.6/1.6/Defs/QuestScriptDefs/WULA_T2_Mission_Attack_Camp.xml b/1.6/1.6/Defs/QuestScriptDefs/WULA_P_Mission_Attack_Camp.xml
similarity index 96%
rename from 1.6/1.6/Defs/QuestScriptDefs/WULA_T2_Mission_Attack_Camp.xml
rename to 1.6/1.6/Defs/QuestScriptDefs/WULA_P_Mission_Attack_Camp.xml
index c602455d..8cd50d21 100644
--- a/1.6/1.6/Defs/QuestScriptDefs/WULA_T2_Mission_Attack_Camp.xml
+++ b/1.6/1.6/Defs/QuestScriptDefs/WULA_P_Mission_Attack_Camp.xml
@@ -1,40 +1,30 @@
- OpportunitySite_BanditCamp
- 1.0
- 350
- true
- 4~8
- Raided_BanditCamp
- true
+ WULA_P_Mission_Attack_Camp
+ 0
+ false
+ true
+ 3
+ true
+ false
+
- questName->The [bandit] [camp]
- questName->[bandit] [camp]
- questName->[asker_nameDef] and the [camp]
- camp->Camp
- camp->Outpost
- camp->Lair
- camp->Encampment
- bandit->Bandit
- bandit->Raider
- bandit->Outlaw
- bandit->Desperado
- bandit->Fugitive
- bandit->Marauder
- bandit->Robber
- bandit->Brigand
+ questName->WULA_P_Mission_Attack_Camp_questName
+
+ QuestHospitalityCommon
+
- questDescription->[asker_nameFull], [asker_faction_leaderTitle] of [asker_faction_name], has sent us a message. Apparently, [siteFaction_pawnsPlural] based in a nearby camp have been raiding their caravans. The camp is controlled by [siteFaction_name].
-\n[asker_nameDef] is asking us to destroy the camp, which means eliminating all enemies and turrets. [asker_label] says that [sitePart0_description].
+ questDescription->WULA_P_Mission_Attack_Camp_questDescription
+
Util_RandomizePointsChallengeRating
@@ -51,13 +41,6 @@
true
-
- asker
- true
- false
- 0.15
-
-
siteTile
true
diff --git a/1.6/1.6/Defs/ResearchTabDef/ResearchTabs_WULA.xml b/1.6/1.6/Defs/ResearchTabDef/ResearchTabs_WULA.xml
index db632793..f14a90b8 100644
--- a/1.6/1.6/Defs/ResearchTabDef/ResearchTabs_WULA.xml
+++ b/1.6/1.6/Defs/ResearchTabDef/ResearchTabs_WULA.xml
@@ -4,6 +4,6 @@
WULA_ResearchTab
乌拉帝国科技
乌拉帝国科技项目
- 解锁和乌拉帝国相关的研究项目,破解强大的堕落帝国科技产物和机械体。
+ 解锁和乌拉帝国相关的研究项目,申请强大的堕落帝国科技产物、舰队和战争机械。
diff --git a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Turret_Buildings.xml b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Turret_Buildings.xml
index 67868e65..a1a3cacc 100644
--- a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Turret_Buildings.xml
+++ b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Turret_Buildings.xml
@@ -776,7 +776,16 @@
Bullet_WULA_WM_Panzer_Turret
金红石穿甲弹
- WulaFallenEmpire.Projectile_ExplosiveWithTrail
+ WulaFallenEmpire.Projectile_WulaLineAttack
+
+
+ -1
+ 0
+ true
+ WULA_GunTail_Lighting
+ Bullet_WULA_WM_Panzer_Turret_Hit
+
+
Normal
True
@@ -806,6 +815,54 @@
+
+ Bullet_WULA_WM_Panzer_Turret_Hit
+
+
+ SubEffecter_SprayerTriggered
+ 0.1
+ WULA_Mote_halo
+ 1~1
+ 0.4~0.8
+ 0.05~0.05
+ OnSource
+ (255,255,255)
+
+
+ SubEffecter_SprayerTriggered
+ 0.02
+ WULA_Mote_halo
+ 1~1
+ 0.3~0.4
+ 5~10
+ 0.1~0.2
+ OnSource
+ (255,255,255)
+
+
+ SubEffecter_SprayerTriggered
+ WULA_Mote_ChargeLanceShot
+ 6~12
+ 0.4~0.8
+ 20~40
+ 135~225
+ 0.01
+ OnSource
+
+
+ SubEffecter_SprayerTriggered
+ WULA_Mote_ChargeLanceShot
+ 5~9
+ 0.4~0.8
+ 10~20
+ 135~225
+ 0.01
+ OnSource
+
+
+ 0.25~0.25
+ 0.1
+
@@ -1689,4 +1746,4 @@
-
+
\ No newline at end of file
diff --git a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Manpack_Weapon.xml b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Manpack_Weapon.xml
index ba405047..d7065634 100644
--- a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Manpack_Weapon.xml
+++ b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Manpack_Weapon.xml
@@ -818,7 +818,7 @@
0.7
1
1
- 0.5
+ 1.5
60
@@ -826,7 +826,7 @@
- WulaFallenEmpire.Verb_ShootWithOffset
+ WulaFallenEmpire.Verb_ShootBeyondTarge
true
Bullet_WULA_RW_Fractal_RF
1.25
@@ -865,6 +865,7 @@
0
true
WULA_GunTail_Lighting
+
@@ -881,6 +882,54 @@
5
+
+ Bullet_WULA_RW_Fractal_RF_Hit
+
+
+ SubEffecter_SprayerTriggered
+ 0.1
+ WULA_Mote_halo
+ 1~1
+ 0.4~0.8
+ 0.05~0.05
+ OnSource
+ (255,255,255)
+
+
+ SubEffecter_SprayerTriggered
+ 0.02
+ WULA_Mote_halo
+ 1~1
+ 0.3~0.4
+ 5~10
+ 0.1~0.2
+ OnSource
+ (255,255,255)
+
+
+ SubEffecter_SprayerTriggered
+ WULA_Mote_ChargeLanceShot
+ 6~12
+ 0.4~0.8
+ 20~40
+ 135~225
+ 0.01
+ OnSource
+
+
+ SubEffecter_SprayerTriggered
+ WULA_Mote_ChargeLanceShot
+ 5~9
+ 0.4~0.8
+ 10~20
+ 135~225
+ 0.01
+ OnSource
+
+
+ 0.25~0.25
+ 0.1
+
WULA_RW_StarDrift_SG
DCs-7"黑曜石"
diff --git a/Source/WulaFallenEmpire/Damage/202512031732.xml b/Source/WulaFallenEmpire/Damage/202512031732.xml
new file mode 100644
index 00000000..e9f71f0e
--- /dev/null
+++ b/Source/WulaFallenEmpire/Damage/202512031732.xml
@@ -0,0 +1,147 @@
+
+
+ Damage_WithExtraEffects
+ 带电击伤害
+ WulaFallenEmpire.DamageWorker_ExtraDamage
+
+
+
+
+
+
+
+
+ Damage_WithBurn
+ 带燃烧伤害
+ WulaFallenEmpire.DamageWorker_ExtraDamage
+
+
+
+
+
+
+
+
+ Damage_MultiEffect
+ 多重效果伤害
+ WulaFallenEmpire.DamageWorker_ExtraDamage
+
+
+
+
+
+
+
+
+ Gun_AdvancedRifle
+ 先进步枪
+
+
+
+ Verb_Shoot
+ Bullet_Advanced
+
+
+
+
+
+
+ Bullet_Advanced
+ 先进子弹
+
+ Damage_MultiEffect
+ 25
+
+
diff --git a/Source/WulaFallenEmpire/Damage/DamageDef_ExtraDamageExtension.cs b/Source/WulaFallenEmpire/Damage/DamageDef_ExtraDamageExtension.cs
new file mode 100644
index 00000000..0b7df42b
--- /dev/null
+++ b/Source/WulaFallenEmpire/Damage/DamageDef_ExtraDamageExtension.cs
@@ -0,0 +1,299 @@
+using System.Collections.Generic;
+using Verse;
+using RimWorld;
+
+namespace WulaFallenEmpire
+{
+ public class DamageDef_ExtraDamageExtension : DefModExtension
+ {
+ ///
+ /// 额外伤害列表
+ ///
+ public List extraDamages = new List();
+
+ ///
+ /// 条件触发器列表
+ ///
+ public List conditions = new List();
+
+ ///
+ /// 是否显示额外的战斗日志信息
+ ///
+ public bool showExtraLog = true;
+
+ ///
+ /// 额外伤害标签
+ ///
+ public string extraLabel = "";
+
+ ///
+ /// 获取所有适用于特定目标的额外伤害
+ ///
+ public List GetApplicableExtraDamages(Thing target, DamageInfo originalDinfo)
+ {
+ List result = new List();
+
+ foreach (var extraDamage in extraDamages)
+ {
+ if (IsConditionMet(extraDamage.conditions, target, originalDinfo))
+ {
+ result.Add(extraDamage);
+ }
+ }
+
+ return result;
+ }
+
+ ///
+ /// 检查条件是否满足
+ ///
+ private bool IsConditionMet(List conditions, Thing target, DamageInfo originalDinfo)
+ {
+ if (conditions == null || conditions.Count == 0)
+ return true;
+
+ foreach (var condition in conditions)
+ {
+ if (!condition.IsMet(target, originalDinfo))
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ ///
+ /// 额外伤害定义
+ ///
+ public class ExtraDamageDef
+ {
+ ///
+ /// 伤害类型
+ ///
+ public DamageDef damageDef;
+
+ ///
+ /// 伤害数值(如果是百分比,基于原始伤害)
+ ///
+ public float amount = 10f;
+
+ ///
+ /// 是否为百分比伤害(相对于原始伤害)
+ ///
+ public bool isPercentage = false;
+
+ ///
+ /// 百分比倍数(当isPercentage为true时有效)
+ ///
+ public float percentageMultiplier = 0.5f;
+
+ ///
+ /// 护甲穿透值
+ ///
+ public float armorPenetration = -1f; // -1表示使用damageDef的默认值
+
+ ///
+ /// 命中部位(可选)
+ ///
+ public BodyPartDef targetBodyPart;
+
+ ///
+ /// 伤害应用条件
+ ///
+ public List conditions = new List();
+
+ ///
+ /// 伤害应用后的效果器
+ ///
+ public EffecterDef effecterDef;
+
+ ///
+ /// 伤害应用后的粒子
+ ///
+ public FleckDef fleckDef;
+
+ ///
+ /// 伤害应用后的音效
+ ///
+ public SoundDef soundDef;
+
+ ///
+ /// 最小触发伤害阈值
+ ///
+ public float minTriggerDamage = 0f;
+
+ ///
+ /// 是否可以被护甲抵抗
+ ///
+ public bool canBeBlockedByArmor = true;
+
+ ///
+ /// 是否为真实伤害(忽略所有抗性)
+ ///
+ public bool isTrueDamage = false;
+
+ ///
+ /// 计算实际伤害值
+ ///
+ public float CalculateActualAmount(DamageInfo originalDinfo, Thing target)
+ {
+ if (isPercentage)
+ {
+ return originalDinfo.Amount * percentageMultiplier;
+ }
+ return amount;
+ }
+
+ ///
+ /// 计算实际护甲穿透值
+ ///
+ public float CalculateActualArmorPenetration()
+ {
+ if (armorPenetration >= 0)
+ return armorPenetration;
+ return damageDef.defaultArmorPenetration;
+ }
+ }
+
+ ///
+ /// 伤害条件
+ ///
+ public class DamageCondition
+ {
+ ///
+ /// 目标类型
+ ///
+ public ConditionTarget targetType = ConditionTarget.Any;
+
+ ///
+ /// 特定种族列表(当targetType为SpecificRaces时有效)
+ ///
+ public List specificRaces = new List();
+
+ ///
+ /// 目标血量百分比阈值
+ ///
+ public FloatRange healthPercentRange = new FloatRange(0f, 1f);
+
+ ///
+ /// 目标是否必须存活
+ ///
+ public bool targetMustBeAlive = true;
+
+ ///
+ /// 目标是否必须有特定标签
+ ///
+ public List requiredTags = new List();
+
+ ///
+ /// 原始伤害类型限制
+ ///
+ public List requiredOriginalDamageTypes = new List();
+
+ ///
+ /// 原始伤害必须大于
+ ///
+ public float originalDamageMustBeGreaterThan = 0f;
+
+ ///
+ /// 检查条件是否满足
+ ///
+ public bool IsMet(Thing target, DamageInfo originalDinfo)
+ {
+ // 检查目标类型
+ if (!CheckTargetType(target))
+ return false;
+
+ // 检查血量百分比
+ if (!CheckHealthPercentage(target))
+ return false;
+
+ // 检查存活状态
+ if (targetMustBeAlive && target is Pawn pawn && (pawn.Dead || pawn.Downed))
+ return false;
+
+ // 检查标签
+ if (!CheckTags(target))
+ return false;
+
+ // 检查原始伤害类型
+ if (!CheckOriginalDamageType(originalDinfo))
+ return false;
+
+ // 检查原始伤害大小
+ if (originalDinfo.Amount <= originalDamageMustBeGreaterThan)
+ return false;
+
+ return true;
+ }
+
+ private bool CheckTargetType(Thing target)
+ {
+ switch (targetType)
+ {
+ case ConditionTarget.Any:
+ return true;
+ case ConditionTarget.Pawn:
+ return target is Pawn;
+ case ConditionTarget.Animal:
+ return target is Pawn pawn && pawn.RaceProps.Animal;
+ case ConditionTarget.Humanlike:
+ return target is Pawn pawn && pawn.RaceProps.Humanlike;
+ case ConditionTarget.Mechanoid:
+ return target is Pawn pawn && pawn.RaceProps.IsMechanoid;
+ case ConditionTarget.Building:
+ return target is Building;
+ case ConditionTarget.SpecificRaces:
+ return target is Pawn pawn && specificRaces.Contains(pawn.def);
+ default:
+ return true;
+ }
+ }
+
+ private bool CheckHealthPercentage(Thing target)
+ {
+ if (target is Pawn pawn)
+ {
+ float healthPercent = pawn.health.summaryHealth.SummaryHealthPercent;
+ return healthPercentRange.Includes(healthPercent);
+ }
+ return true;
+ }
+
+ private bool CheckTags(Thing target)
+ {
+ if (requiredTags == null || requiredTags.Count == 0)
+ return true;
+
+ foreach (var tag in requiredTags)
+ {
+ if (target.def.HasTag(tag))
+ return true;
+ }
+
+ return false;
+ }
+
+ private bool CheckOriginalDamageType(DamageInfo originalDinfo)
+ {
+ if (requiredOriginalDamageTypes == null || requiredOriginalDamageTypes.Count == 0)
+ return true;
+
+ return requiredOriginalDamageTypes.Contains(originalDinfo.Def);
+ }
+ }
+
+ ///
+ /// 条件目标类型
+ ///
+ public enum ConditionTarget
+ {
+ Any,
+ Pawn,
+ Animal,
+ Humanlike,
+ Mechanoid,
+ Building,
+ SpecificRaces
+ }
+}
diff --git a/Source/WulaFallenEmpire/Damage/DamageWorker_ExtraDamage.cs b/Source/WulaFallenEmpire/Damage/DamageWorker_ExtraDamage.cs
new file mode 100644
index 00000000..a22a5628
--- /dev/null
+++ b/Source/WulaFallenEmpire/Damage/DamageWorker_ExtraDamage.cs
@@ -0,0 +1,245 @@
+using System.Collections.Generic;
+using RimWorld;
+using Verse;
+using System.Linq;
+using System.Text;
+
+namespace WulaFallenEmpire
+{
+ public class DamageWorker_ExtraDamage : DamageWorker
+ {
+ ///
+ /// 重写伤害应用方法
+ ///
+ public override DamageResult Apply(DamageInfo dinfo, Thing victim)
+ {
+ // 先应用原始伤害
+ DamageResult originalResult = base.Apply(dinfo, victim);
+
+ // 获取额外伤害扩展
+ DamageDef_ExtraDamageExtension extension =
+ dinfo.Def.GetModExtension();
+
+ if (extension != null && victim != null && !victim.Destroyed)
+ {
+ // 应用额外伤害
+ var extraDamageResults = ApplyExtraDamages(extension, dinfo, victim, originalResult);
+
+ // 如果需要,添加战斗日志
+ if (extension.showExtraLog && extraDamageResults.Count > 0)
+ {
+ AddCombatLog(extension, dinfo, victim, extraDamageResults);
+ }
+ }
+
+ return originalResult;
+ }
+
+ ///
+ /// 应用额外伤害
+ ///
+ private List ApplyExtraDamages(
+ DamageDef_ExtraDamageExtension extension,
+ DamageInfo originalDinfo,
+ Thing victim,
+ DamageResult originalResult)
+ {
+ List results = new List();
+
+ var applicableDamages = extension.GetApplicableExtraDamages(victim, originalDinfo);
+
+ foreach (var extraDamage in applicableDamages)
+ {
+ if (ShouldApplyExtraDamage(extraDamage, originalDinfo, victim))
+ {
+ DamageResult result = ApplySingleExtraDamage(extraDamage, originalDinfo, victim);
+ if (result != null)
+ {
+ results.Add(result);
+ }
+ }
+ }
+
+ return results;
+ }
+
+ ///
+ /// 检查是否应该应用额外伤害
+ ///
+ private bool ShouldApplyExtraDamage(ExtraDamageDef extraDamage, DamageInfo originalDinfo, Thing victim)
+ {
+ // 检查最小触发伤害
+ if (originalDinfo.Amount < extraDamage.minTriggerDamage)
+ return false;
+
+ return true;
+ }
+
+ ///
+ /// 应用单个额外伤害
+ ///
+ private DamageResult ApplySingleExtraDamage(ExtraDamageDef extraDamage, DamageInfo originalDinfo, Thing victim)
+ {
+ try
+ {
+ // 计算伤害值
+ float damageAmount = extraDamage.CalculateActualAmount(originalDinfo, victim);
+ if (damageAmount <= 0)
+ return null;
+
+ // 计算护甲穿透
+ float armorPenetration = extraDamage.CalculateActualArmorPenetration();
+
+ // 创建伤害信息
+ DamageInfo extraDinfo = new DamageInfo(
+ def: extraDamage.damageDef,
+ amount: damageAmount,
+ armorPenetration: armorPenetration,
+ angle: originalDinfo.Angle,
+ instigator: originalDinfo.Instigator,
+ hitPart: GetTargetBodyPart(victim, extraDamage.targetBodyPart),
+ weapon: originalDinfo.Weapon,
+ category: DamageInfo.SourceCategory.ThingOrUnknown,
+ intendedTarget: originalDinfo.IntendedTarget
+ );
+
+ // 如果是真实伤害,设置特殊标志(如果需要特殊处理)
+ if (extraDamage.isTrueDamage)
+ {
+ // 这里可能需要特殊的处理方式
+ // 例如,可以设置伤害信息中的特殊标志
+ }
+
+ // 应用伤害
+ DamageResult result = victim.TakeDamage(extraDinfo);
+
+ // 播放效果
+ PlayExtraDamageEffects(extraDamage, victim, damageAmount);
+
+ return result;
+ }
+ catch (System.Exception ex)
+ {
+ Log.Warning($"应用额外伤害时出错: {ex.Message}");
+ return null;
+ }
+ }
+
+ ///
+ /// 获取目标部位
+ ///
+ private BodyPartRecord GetTargetBodyPart(Thing victim, BodyPartDef bodyPartDef)
+ {
+ if (bodyPartDef == null || !(victim is Pawn pawn))
+ return null;
+
+ return pawn.RaceProps.body.GetPartsWithDef(bodyPartDef).FirstOrDefault();
+ }
+
+ ///
+ /// 播放额外伤害效果
+ ///
+ private void PlayExtraDamageEffects(ExtraDamageDef extraDamage, Thing victim, float damageAmount)
+ {
+ if (victim.Map == null)
+ return;
+
+ // 播放音效
+ if (extraDamage.soundDef != null)
+ {
+ extraDamage.soundDef.PlayOneShot(new TargetInfo(victim.Position, victim.Map));
+ }
+
+ // 播放粒子效果
+ if (extraDamage.fleckDef != null)
+ {
+ FleckMaker.Static(victim.DrawPos, victim.Map, extraDamage.fleckDef);
+ }
+
+ // 播放效果器
+ if (extraDamage.effecterDef != null)
+ {
+ Effecter effecter = extraDamage.effecterDef.Spawn();
+ effecter.Trigger(new TargetInfo(victim.Position, victim.Map), new TargetInfo(victim.Position, victim.Map));
+ effecter.Cleanup();
+ }
+ }
+
+ ///
+ /// 添加战斗日志
+ ///
+ private void AddCombatLog(
+ DamageDef_ExtraDamageExtension extension,
+ DamageInfo originalDinfo,
+ Thing victim,
+ List extraResults)
+ {
+ if (victim is Pawn victimPawn)
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendLine($"{extension.extraLabel} - 额外伤害:");
+
+ foreach (var result in extraResults)
+ {
+ if (result != null && result.totalDamageDealt > 0)
+ {
+ sb.AppendLine($" {result.totalDamageDealt:F1} 伤害");
+ }
+ }
+
+ // 这里可以添加更详细的战斗日志逻辑
+ // 例如,创建一个自定义的战斗日志条目
+ }
+ }
+
+ ///
+ /// 重写爆炸伤害处理
+ ///
+ protected override void ExplosionDamageThing(Explosion explosion, Thing t, List damagedThings, List ignoredThings, IntVec3 cell)
+ {
+ base.ExplosionDamageThing(explosion, t, damagedThings, ignoredThings, cell);
+
+ // 检查并应用额外伤害
+ DamageDef_ExtraDamageExtension extension =
+ explosion.damType.GetModExtension();
+
+ if (extension != null && !t.Destroyed)
+ {
+ // 为爆炸中的每个目标应用额外伤害
+ // 注意:这里需要创建适当的DamageInfo
+ }
+ }
+
+ ///
+ /// 获取伤害描述(用于UI显示)
+ ///
+ public string GetExtraDamageDescription(DamageDef damageDef)
+ {
+ DamageDef_ExtraDamageExtension extension =
+ damageDef.GetModExtension();
+
+ if (extension == null || extension.extraDamages.Count == 0)
+ return "";
+
+ StringBuilder sb = new StringBuilder();
+ sb.AppendLine("额外伤害效果:");
+
+ foreach (var extraDamage in extension.extraDamages)
+ {
+ string damageType = extraDamage.damageDef.label;
+ string amountStr = extraDamage.isPercentage ?
+ $"{extraDamage.percentageMultiplier * 100}% 原始伤害" :
+ $"{extraDamage.amount} 点";
+
+ sb.AppendLine($" {damageType}: {amountStr}");
+
+ if (extraDamage.minTriggerDamage > 0)
+ {
+ sb.AppendLine($" 触发条件: 原始伤害 > {extraDamage.minTriggerDamage}");
+ }
+ }
+
+ return sb.ToString();
+ }
+ }
+}
diff --git a/Source/WulaFallenEmpire/Projectiles/Projectile_WulaPenetratingBullet.cs b/Source/WulaFallenEmpire/Projectiles/Projectile_WulaPenetratingBullet.cs
index 9b8b3281..e0e38fe2 100644
--- a/Source/WulaFallenEmpire/Projectiles/Projectile_WulaPenetratingBullet.cs
+++ b/Source/WulaFallenEmpire/Projectiles/Projectile_WulaPenetratingBullet.cs
@@ -2,20 +2,46 @@ using System.Collections.Generic;
using RimWorld;
using UnityEngine;
using Verse;
+using System.Linq;
namespace WulaFallenEmpire
{
- // Final, robust extension class for configuring path-based penetration.
public class Wula_PathPierce_Extension : DefModExtension
{
- // Set to a positive number for limited hits, or -1 for infinite penetration.
- public int maxHits = 3;
- // The percentage of damage lost per hit. 0.25 means 25% damage loss per hit.
+ // 设置正数表示有限命中次数,-1 表示无限穿透
+ public int maxHits = 3;
+
+ // 每次命中的伤害损失百分比。0.25 表示每次命中损失25%伤害
public float damageFalloff = 0.25f;
- // If true, this projectile will never cause friendly fire, regardless of game settings.
+
+ // 如果为 true,无论游戏设置如何,这个抛射体都不会造成友军伤害
public bool preventFriendlyFire = false;
- public FleckDef tailFleckDef; // 用于配置拖尾特效的 FleckDef
- public int fleckDelayTicks = 10; // 拖尾特效延迟生成时间(tick)
+
+ // 尾部拖尾特效的 FleckDef
+ public FleckDef tailFleckDef;
+
+ // 拖尾特效延迟生成时间(tick)
+ public int fleckDelayTicks = 10;
+
+
+ // 1. 击中敌人时播放的效果器(Effecter)
+ public EffecterDef hitEffecterDef;
+ // 2. 击中敌人时播放的粒子(Fleck)
+ public FleckDef hitFleckDef;
+ // 4. 特效持续时间(tick,仅对效果器有效)
+ public int effectDurationTicks = 60;
+ // 5. 是否对每个命中的敌人都播放特效
+ public bool playEffectOnEveryHit = true;
+ // 6. 特效位置偏移(相对于被击中目标)
+ public Vector3 effectOffset = Vector3.zero;
+ // 7. 特效缩放
+ public float effectScale = 1.0f;
+ // 8. 伤害阈值:只有达到这个伤害值才会播放特效(0表示总是播放)
+ public float damageThreshold = 0f;
+ // 9. 随机播放的特效列表(随机选择一个)
+ public List randomHitEffecters;
+ // 10. 随机粒子列表(随机选择一个)
+ public List randomHitFlecks;
}
public class Projectile_WulaLineAttack : Bullet
@@ -23,14 +49,18 @@ namespace WulaFallenEmpire
private int hitCounter = 0;
private List alreadyDamaged = new List();
private Vector3 lastTickPosition;
- private int Fleck_MakeFleckTick; // 拖尾特效的计时器
- public int Fleck_MakeFleckTickMax = 1; // 拖尾特效的生成频率
- public IntRange Fleck_MakeFleckNum = new IntRange(1, 1); // 每次生成的粒子数量
- public FloatRange Fleck_Angle = new FloatRange(-180f, 180f); // 粒子角度
- public FloatRange Fleck_Scale = new FloatRange(1f, 1f); // 粒子大小
- public FloatRange Fleck_Speed = new FloatRange(0f, 0f); // 粒子速度
- public FloatRange Fleck_Rotation = new FloatRange(-180f, 180f); // 粒子旋转
-
+ private int fleckMakeFleckTick; // 拖尾特效的计时器
+ public int fleckMakeFleckTickMax = 1; // 拖尾特效的生成频率
+ public IntRange fleckMakeFleckNum = new IntRange(1, 1); // 每次生成的粒子数量
+ public FloatRange fleckAngle = new FloatRange(-180f, 180f); // 粒子角度
+ public FloatRange fleckScale = new FloatRange(1f, 1f); // 粒子大小
+ public FloatRange fleckSpeed = new FloatRange(0f, 0f); // 粒子速度
+ public FloatRange fleckRotation = new FloatRange(-180f, 180f); // 粒子旋转
+
+ // 特效维护列表
+ private List activeEffecters = new List();
+ private Dictionary effecterEndTicks = new Dictionary();
+
private Wula_PathPierce_Extension Props => def.GetModExtension();
public override void ExposeData()
@@ -39,10 +69,21 @@ namespace WulaFallenEmpire
Scribe_Values.Look(ref hitCounter, "hitCounter", 0);
Scribe_Collections.Look(ref alreadyDamaged, "alreadyDamaged", LookMode.Reference);
Scribe_Values.Look(ref lastTickPosition, "lastTickPosition");
+ Scribe_Collections.Look(ref activeEffecters, "activeEffecters", LookMode.Deep);
+ Scribe_Collections.Look(ref effecterEndTicks, "effecterEndTicks", LookMode.Reference, LookMode.Value);
+
if (alreadyDamaged == null)
{
alreadyDamaged = new List();
}
+ if (activeEffecters == null)
+ {
+ activeEffecters = new List();
+ }
+ if (effecterEndTicks == null)
+ {
+ effecterEndTicks = new Dictionary();
+ }
}
public override void Launch(Thing launcher, Vector3 origin, LocalTargetInfo usedTarget, LocalTargetInfo intendedTarget, ProjectileHitFlags hitFlags, bool preventFriendlyFire = false, Thing equipment = null, ThingDef targetCoverDef = null)
@@ -51,8 +92,11 @@ namespace WulaFallenEmpire
this.lastTickPosition = origin;
this.alreadyDamaged.Clear();
this.hitCounter = 0;
- // Friendly fire is prevented if EITHER the game setting is true OR the XML extension is true.
+ // 如果游戏设置为 true 或 XML 扩展为 true,则防止友军伤害
this.preventFriendlyFire = preventFriendlyFire || (Props?.preventFriendlyFire ?? false);
+
+ // 清理旧的特效器
+ CleanupOldEffecters();
}
protected override void Tick()
@@ -62,40 +106,12 @@ namespace WulaFallenEmpire
if (this.Destroyed) return;
- this.Fleck_MakeFleckTick++;
- // 只有当达到延迟时间后才开始生成Fleck
- if (this.Fleck_MakeFleckTick >= Props.fleckDelayTicks)
- {
- if (this.Fleck_MakeFleckTick >= (Props.fleckDelayTicks + this.Fleck_MakeFleckTickMax))
- {
- this.Fleck_MakeFleckTick = Props.fleckDelayTicks; // 重置计时器,从延迟时间开始循环
- }
-
- Map map = base.Map;
- int randomInRange = this.Fleck_MakeFleckNum.RandomInRange;
- Vector3 currentPosition = this.ExactPosition; // Current position of the bullet
- Vector3 previousPosition = this.lastTickPosition; // Previous position of the bullet
-
- for (int i = 0; i < randomInRange; i++)
- {
- float currentBulletAngle = ExactRotation.eulerAngles.y; // 使用子弹当前的水平旋转角度
- float fleckRotationAngle = currentBulletAngle; // Fleck 的旋转角度与子弹方向一致
- float velocityAngle = this.Fleck_Angle.RandomInRange + currentBulletAngle; // Fleck 的速度角度基于子弹方向加上随机偏移
- float randomInRange2 = this.Fleck_Scale.RandomInRange;
- float randomInRange3 = this.Fleck_Speed.RandomInRange;
-
- if (Props?.tailFleckDef != null)
- {
- FleckCreationData dataStatic = FleckMaker.GetDataStatic(currentPosition, map, Props.tailFleckDef, randomInRange2);
- dataStatic.rotation = fleckRotationAngle;
- dataStatic.rotationRate = this.Fleck_Rotation.RandomInRange;
- dataStatic.velocityAngle = velocityAngle;
- dataStatic.velocitySpeed = randomInRange3;
- map.flecks.CreateFleck(dataStatic);
- }
- }
- }
-
+ // 更新拖尾特效
+ UpdateTrailFlecks();
+
+ // 更新击中特效器
+ UpdateHitEffecters();
+
if (this.Destroyed) return;
Vector3 endPos = this.ExactPosition;
@@ -105,17 +121,102 @@ namespace WulaFallenEmpire
this.lastTickPosition = endPos;
}
+ ///
+ /// 更新拖尾粒子特效
+ ///
+ private void UpdateTrailFlecks()
+ {
+ this.fleckMakeFleckTick++;
+
+ // 只有当达到延迟时间后才开始生成 Fleck
+ if (this.fleckMakeFleckTick >= Props?.fleckDelayTicks)
+ {
+ if (this.fleckMakeFleckTick >= (Props.fleckDelayTicks + this.fleckMakeFleckTickMax))
+ {
+ this.fleckMakeFleckTick = Props.fleckDelayTicks; // 重置计时器,从延迟时间开始循环
+ }
+
+ Map map = base.Map;
+ int randomInRange = this.fleckMakeFleckNum.RandomInRange;
+ Vector3 currentPosition = this.ExactPosition; // 子弹当前位置
+
+ for (int i = 0; i < randomInRange; i++)
+ {
+ float currentBulletAngle = ExactRotation.eulerAngles.y; // 使用子弹当前的水平旋转角度
+ float fleckRotationAngle = currentBulletAngle; // Fleck 的旋转角度与子弹方向一致
+ float velocityAngle = this.fleckAngle.RandomInRange + currentBulletAngle; // Fleck 的速度角度基于子弹方向加上随机偏移
+ float randomInRange2 = this.fleckScale.RandomInRange;
+ float randomInRange3 = this.fleckSpeed.RandomInRange;
+
+ if (Props?.tailFleckDef != null)
+ {
+ FleckCreationData dataStatic = FleckMaker.GetDataStatic(currentPosition, map, Props.tailFleckDef, randomInRange2);
+ dataStatic.rotation = fleckRotationAngle;
+ dataStatic.rotationRate = this.fleckRotation.RandomInRange;
+ dataStatic.velocityAngle = velocityAngle;
+ dataStatic.velocitySpeed = randomInRange3;
+ map.flecks.CreateFleck(dataStatic);
+ }
+ }
+ }
+ }
+
+ ///
+ /// 更新击中特效器
+ ///
+ private void UpdateHitEffecters()
+ {
+ if (activeEffecters == null || activeEffecters.Count == 0)
+ return;
+
+ var ticksGame = Find.TickManager.TicksGame;
+ var effectersToRemove = new List();
+ var pawnsToRemove = new List();
+
+ // 检查每个特效器是否应该结束
+ foreach (var kvp in effecterEndTicks)
+ {
+ if (ticksGame >= kvp.Value || kvp.Key == null || kvp.Key.Destroyed || !kvp.Key.Spawned)
+ {
+ pawnsToRemove.Add(kvp.Key);
+ }
+ }
+
+ // 清理结束的特效器
+ foreach (var pawn in pawnsToRemove)
+ {
+ effecterEndTicks.Remove(pawn);
+ }
+ }
+
+ ///
+ /// 清理旧的特效器
+ ///
+ private void CleanupOldEffecters()
+ {
+ if (activeEffecters != null)
+ {
+ foreach (var effecter in activeEffecters)
+ {
+ effecter?.Cleanup();
+ }
+ activeEffecters.Clear();
+ }
+
+ effecterEndTicks?.Clear();
+ }
+
protected override void Impact(Thing hitThing, bool blockedByShield = false)
{
CheckPathForDamage(lastTickPosition, this.ExactPosition);
if (hitThing != null && alreadyDamaged.Contains(hitThing))
{
- base.Impact(null, blockedByShield);
+ base.Impact(null, blockedByShield);
}
else
{
- base.Impact(hitThing, blockedByShield);
+ base.Impact(hitThing, blockedByShield);
}
}
@@ -145,17 +246,17 @@ namespace WulaFallenEmpire
{
bool shouldDamage = false;
- // Case 1: Always damage the intended target if it's a pawn. This allows hunting.
+ // 情况1:如果预期目标是pawn,总是造成伤害。这允许狩猎。
if (this.intendedTarget.Thing == pawn)
{
shouldDamage = true;
}
- // Case 2: Always damage hostile pawns in the path.
+ // 情况2:总是对路径上的敌对pawn造成伤害。
else if (pawn.HostileTo(this.launcher))
{
shouldDamage = true;
}
- // Case 3: Damage non-hostiles (friendlies, neutrals) if the shot itself isn't marked to prevent friendly fire.
+ // 情况3:如果射击本身没有标记为防止友军伤害,则对非敌对(友好,中立)造成伤害。
else if (!this.preventFriendlyFire)
{
shouldDamage = true;
@@ -176,11 +277,17 @@ namespace WulaFallenEmpire
Wula_PathPierce_Extension props = Props;
float falloff = props?.damageFalloff ?? 0.25f;
- // Damage falloff now applies universally, even for infinite penetration.
+ // 伤害衰减现在普遍适用,即使是无限穿透。
float damageMultiplier = Mathf.Pow(1f - falloff, hitCounter);
int damageAmount = (int)(this.DamageAmount * damageMultiplier);
if (damageAmount <= 0) return;
+
+ // 检查伤害阈值
+ if (props?.damageThreshold > 0 && damageAmount < props.damageThreshold)
+ {
+ return;
+ }
var dinfo = new DamageInfo(
this.def.projectile.damageDef,
@@ -196,6 +303,115 @@ namespace WulaFallenEmpire
pawn.TakeDamage(dinfo);
alreadyDamaged.Add(pawn);
hitCounter++;
+
+ // 播放击中特效
+ PlayHitEffects(pawn, damageAmount);
+ }
+
+ ///
+ /// 播放击中敌人时的特效
+ ///
+ /// 被击中的Pawn
+ /// 造成的伤害值
+ private void PlayHitEffects(Pawn pawn, int damageAmount)
+ {
+ if (pawn == null || pawn.Destroyed || pawn.Map == null)
+ return;
+
+ Wula_PathPierce_Extension props = Props;
+ if (props == null)
+ return;
+
+ // 是否对每个命中都播放特效
+ if (!props.playEffectOnEveryHit && hitCounter > 1)
+ return;
+
+ // 播放粒子特效
+ PlayHitFleck(pawn);
+
+ // 播放效果器特效
+ PlayHitEffecter(pawn);
+ }
+
+ ///
+ /// 播放击中粒子特效
+ ///
+ private void PlayHitFleck(Pawn pawn)
+ {
+ Wula_PathPierce_Extension props = Props;
+ if (props == null)
+ return;
+
+ FleckDef fleckDef = null;
+
+ // 选择粒子:优先使用随机列表,然后使用固定粒子
+ if (props.randomHitFlecks != null && props.randomHitFlecks.Count > 0)
+ {
+ fleckDef = props.randomHitFlecks.RandomElement();
+ }
+ else if (props.hitFleckDef != null)
+ {
+ fleckDef = props.hitFleckDef;
+ }
+
+ if (fleckDef != null)
+ {
+ Vector3 position = pawn.DrawPos + props.effectOffset;
+ float scale = props.effectScale;
+
+ FleckCreationData data = FleckMaker.GetDataStatic(position, pawn.Map, fleckDef, scale);
+ pawn.Map.flecks.CreateFleck(data);
+ }
+ }
+
+ ///
+ /// 播放击中效果器特效
+ ///
+ private void PlayHitEffecter(Pawn pawn)
+ {
+ Wula_PathPierce_Extension props = Props;
+ if (props == null)
+ return;
+
+ EffecterDef effecterDef = null;
+
+ // 选择效果器:优先使用随机列表,然后使用固定效果器
+ if (props.randomHitEffecters != null && props.randomHitEffecters.Count > 0)
+ {
+ effecterDef = props.randomHitEffecters.RandomElement();
+ }
+ else if (props.hitEffecterDef != null)
+ {
+ effecterDef = props.hitEffecterDef;
+ }
+
+ if (effecterDef != null)
+ {
+ Vector3 position = pawn.DrawPos + props.effectOffset;
+
+ // 创建效果器
+ Effecter effecter = effecterDef.Spawn();
+ effecter.Trigger(new TargetInfo(pawn.Position, pawn.Map), new TargetInfo(pawn.Position, pawn.Map));
+
+ // 如果需要持续效果,添加到维护列表
+ if (props.effectDurationTicks > 0)
+ {
+ activeEffecters.Add(effecter);
+ effecterEndTicks[pawn] = Find.TickManager.TicksGame + props.effectDurationTicks;
+ }
+ else
+ {
+ // 立即清理效果器
+ effecter.Cleanup();
+ }
+ }
+ }
+
+ public override void Destroy(DestroyMode mode = DestroyMode.Vanish)
+ {
+ // 清理所有特效器
+ CleanupOldEffecters();
+ base.Destroy(mode);
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/WulaFallenEmpire/Verb/Verb_ShootBeyondTarget.cs b/Source/WulaFallenEmpire/Verb/Verb_ShootBeyondTarget.cs
new file mode 100644
index 00000000..767bd377
--- /dev/null
+++ b/Source/WulaFallenEmpire/Verb/Verb_ShootBeyondTarget.cs
@@ -0,0 +1,63 @@
+using RimWorld;
+using System;
+using UnityEngine;
+using Verse;
+
+namespace WulaFallenEmpire
+{
+ public class Verb_ShootBeyondTarge : Verb_ShootWithOffset
+ {
+ ///
+ /// 重写射击逻辑,直接修改当前目标为延长线目标
+ ///
+ protected override bool TryCastShot()
+ {
+ // 保存原始目标
+ LocalTargetInfo originalTarget = currentTarget;
+
+ try
+ {
+ // 计算延长线目标
+ LocalTargetInfo beyondTarget = CalculateBeyondTarget(originalTarget);
+
+ // 设置为延长线目标
+ currentTarget = beyondTarget;
+
+ // 调用基类射击逻辑
+ return base.TryCastShot();
+ }
+ finally
+ {
+ // 恢复原始目标
+ currentTarget = originalTarget;
+ }
+ }
+
+ ///
+ /// 计算延长线目标
+ ///
+ private LocalTargetInfo CalculateBeyondTarget(LocalTargetInfo target)
+ {
+ if (!target.IsValid || caster == null || caster.Map == null)
+ return target;
+
+ Vector3 shooterPos = caster.DrawPos;
+ Vector3 targetPos = target.HasThing ?
+ target.Thing.DrawPos :
+ target.Cell.ToVector3Shifted();
+
+ Vector3 direction = (targetPos - shooterPos).normalized;
+ float maxRange = EffectiveRange;
+ Vector3 beyondTargetPos = shooterPos + direction * maxRange;
+ IntVec3 beyondTargetCell = beyondTargetPos.ToIntVec3();
+
+ // 确保在地图范围内
+ if (!beyondTargetCell.InBounds(caster.Map))
+ {
+ beyondTargetCell = beyondTargetCell.ClampInsideMap(caster.Map);
+ }
+
+ return new LocalTargetInfo(beyondTargetCell);
+ }
+ }
+}
diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
index f9d0a7a7..ddd7a88a 100644
--- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
+++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
@@ -347,6 +347,7 @@
+
diff --git a/mod_D.vdf b/mod_D.vdf
new file mode 100644
index 00000000..12e9906b
--- /dev/null
+++ b/mod_D.vdf
@@ -0,0 +1,11 @@
+
+"workshopitem"
+{
+ "appid" "294100"
+ "contentfolder" "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\WulaFallenEmpireTest"
+ "previewfile" "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\WulaFallenEmpireTest\\About\\Preview.png"
+ "visibility" "3"
+ "title" "Wula Fallen Empire V2"
+ "changenote" "1.6"
+ "publishedfileid" "3604325124"
+}
\ No newline at end of file