# 爆炸射线武器开发指南 ## 架构概述 爆炸射线武器系统基于RimWorld原版的射线武器系统,通过继承和扩展实现爆炸功能。 ### 核心类结构 ``` Verb (RimWorld原版) └── Verb_ShootBeam (RimWorld原版) └── Verb_ShootBeamExplosive (自定义) VerbProperties (RimWorld原版) └── VerbPropertiesExplosiveBeam (自定义) ``` ## 代码架构 ### 1. Verb_ShootBeamExplosive.cs #### 核心字段 ```csharp private int explosionShotCounter = 0; // 爆炸计数器 ``` #### 关键方法 - `TryCastShot()`: 重写射击方法,添加爆炸逻辑 - `TriggerExplosion()`: 触发爆炸的核心方法 - `ExposeData()`: 保存/加载数据 #### 工作流程 1. 调用基类的 `TryCastShot()` 2. 如果射击成功且启用爆炸,递增计数器 3. 当计数器达到间隔值时,触发爆炸并重置计数器 ### 2. VerbPropertiesExplosiveBeam.cs #### 配置属性分类 - **基础控制**: `enableExplosion`, `explosionShotInterval` - **伤害属性**: `explosionRadius`, `explosionDamage`, `explosionDamageDef` - **效果属性**: `explosionSound`, `explosionEffecter` - **后续效果**: `postExplosionSpawn*`, `postExplosionGasType` ## 扩展开发 ### 添加新的爆炸类型 1. **在VerbPropertiesExplosiveBeam中添加新属性** ```csharp public bool enableChainExplosion = false; public int chainExplosionCount = 3; public float chainExplosionDelay = 0.5f; ``` 2. **在Verb_ShootBeamExplosive中实现逻辑** ```csharp private void TriggerChainExplosion(VerbPropertiesExplosiveBeam props) { // 实现连锁爆炸逻辑 } ``` ### 添加条件爆炸 ```csharp // 基于目标类型的条件爆炸 private bool ShouldExplodeForTarget(Thing target) { if (target is Pawn pawn) { return pawn.RaceProps.Humanlike; } return true; } ``` ### 添加爆炸延迟 ```csharp private void ScheduleDelayedExplosion(IntVec3 pos, float delay) { Find.TickManager.ScheduleCallback(() => { TriggerExplosion(explosiveProps); }, (int)(delay * 60)); // 转换为ticks } ``` ## 性能优化 ### 1. 爆炸频率控制 - 避免每发都爆炸的设计 - 使用合理的 `explosionShotInterval` - 考虑武器的射速和爆炸威力平衡 ### 2. 效果缓存 ```csharp private static Dictionary cachedEffecters = new Dictionary(); private Effecter GetCachedEffecter(EffecterDef def) { string key = def.defName; if (!cachedEffecters.ContainsKey(key)) { cachedEffecters[key] = def.Spawn(); } return cachedEffecters[key]; } ``` ### 3. 范围检查优化 ```csharp private bool IsValidExplosionPosition(IntVec3 pos) { return pos.InBounds(caster.Map) && pos.GetThingList(caster.Map).Any(t => t.def.category == ThingCategory.Pawn); } ``` ## 调试技巧 ### 1. 日志输出 ```csharp if (Prefs.DevMode) { Log.Message($"[ExplosiveBeam] Shot {explosionShotCounter}/{explosiveProps.explosionShotInterval}"); } ``` ### 2. 可视化调试 ```csharp if (DebugSettings.godMode) { // 在爆炸位置显示调试信息 MoteMaker.ThrowText(explosionCell.ToVector3(), caster.Map, $"Explosion: {explosiveProps.explosionDamage}", Color.red); } ``` ### 3. 性能监控 ```csharp private static Stopwatch explosionTimer = new Stopwatch(); private void TriggerExplosion(VerbPropertiesExplosiveBeam explosiveProps) { explosionTimer.Start(); // ... 爆炸逻辑 explosionTimer.Stop(); if (explosionTimer.ElapsedMilliseconds > 5) { Log.Warning($"Explosion took {explosionTimer.ElapsedMilliseconds}ms"); } explosionTimer.Reset(); } ``` ## 兼容性考虑 ### 1. 模组兼容性 - 使用命名空间避免冲突 - 检查其他模组的Harmony补丁 - 提供配置选项禁用功能 ### 2. 版本兼容性 ```csharp #if VERSION_1_4 // 1.4版本特定代码 #elif VERSION_1_5 // 1.5版本特定代码 #endif ``` ### 3. 保存兼容性 ```csharp public override void ExposeData() { base.ExposeData(); // 向后兼容的数据保存 if (Scribe.mode == LoadSaveMode.LoadingVars) { // 处理旧版本数据 } Scribe_Values.Look(ref explosionShotCounter, "explosionShotCounter", 0); } ``` ## 测试框架 ### 单元测试示例 ```csharp [Test] public void TestExplosionInterval() { var verb = new Verb_ShootBeamExplosive(); var props = new VerbPropertiesExplosiveBeam { enableExplosion = true, explosionShotInterval = 3 }; // 模拟3次射击 for (int i = 0; i < 3; i++) { bool shouldExplode = (i == 2); // 第3发应该爆炸 Assert.AreEqual(shouldExplode, verb.ShouldTriggerExplosion()); } } ``` ## 最佳实践 ### 1. 配置验证 ```csharp public override void PostLoad() { base.PostLoad(); if (explosionShotInterval <= 0) { Log.Error($"Invalid explosionShotInterval: {explosionShotInterval}"); explosionShotInterval = 1; } if (explosionRadius < 0) { Log.Warning($"Negative explosion radius: {explosionRadius}"); explosionRadius = 0; } } ``` ### 2. 错误处理 ```csharp private void TriggerExplosion(VerbPropertiesExplosiveBeam explosiveProps) { try { // 爆炸逻辑 } catch (Exception e) { Log.Error($"Error in explosion: {e}"); // 优雅降级,不影响基础射击功能 } } ``` ### 3. 资源管理 ```csharp public override void Destroy(DestroyMode mode = DestroyMode.Vanish) { // 清理资源 cachedEffecters.Clear(); base.Destroy(mode); } ```