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