Files
WulaFallenEmpireRW/Documentation/ExplosiveBeamWeapons/开发指南.md

5.5 KiB
Raw Blame History

爆炸射线武器开发指南

架构概述

爆炸射线武器系统基于RimWorld原版的射线武器系统通过继承和扩展实现爆炸功能。

核心类结构

Verb (RimWorld原版)
└── Verb_ShootBeam (RimWorld原版)
    └── Verb_ShootBeamExplosive (自定义)

VerbProperties (RimWorld原版)
└── VerbPropertiesExplosiveBeam (自定义)

代码架构

1. Verb_ShootBeamExplosive.cs

核心字段

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中添加新属性
public bool enableChainExplosion = false;
public int chainExplosionCount = 3;
public float chainExplosionDelay = 0.5f;
  1. 在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);
}