Development Documentation - BlackCleaverLoli/MissFisher GitHub Wiki

空天姬开发技术文档

术语及变量解释

渔获

指刚刚钓到的鱼。

阶段

当前钓法阶段(以小钓大阶段)

  • 类型:整数
  • 描述
    • 当平钓时,当前钓法阶段记为1。
    • 当进行一次以小钓大时,当前钓法阶段加1。
    • 当钓到同样的鱼时,当前钓法阶段不变。
    • 当挂上游动饵时,当前钓法阶段被赋为存入游动饵时所处的当前钓法阶段。

当前手法阶段(技巧提钩阶段)

  • 类型:整数
  • 计算公式:当前手法阶段 = 当前钓法阶段 + 1
  • 示例
    • 单行并列的是同阶段同目标竿的参数:
      • 当前钓法阶段1 · 拍竿型 · 技巧提钩1 · 鱼篓1
      • 当前钓法阶段1 · 竿型1 · 额外竿型1 · 技巧提钩2 · 鱼篓2 · 目标1
      • ...
      • 当前钓法阶段4 · 竿型4 · 额外竿型4 · 技巧提钩5
    • 因目前游戏中没有第5阶段的钓法需求,所以不需要支持第4阶段的鱼篓和以小钓大目标识别。

阶段叫法约定

示例表达式:
!精准》!!三提
约定如下:
假设当前钓法阶段是1,在下文将使用这样的措辞:
存在远1阶段的目标竿型(因为存在 当前钓法阶段 + 1 阶段 的目标竿型 !!
这样的叙述在本文的条件判断中写为

bool 存在远1阶段的目标竿型 = 存在预设参数("竿型", 当前钓法阶段 + 1);  

手法阶段同理。

前置

Triggernometry空天姬中用来记录刚刚一竿的类型,一般是用来辅助判断是否可使用仅平钓时可用的技能,例如拍击水面、专一垂钓,这些技能不能对以小钓大钓到的鱼类使用。
小于 4 时,前一竿是平钓类型。

string 前置类型ID转前置类型文本(int id)  
{  
    return sid switch {  
        1 => "平钓",  
        2 => "撒饵",  
        3 => "耐心",  
        4 => "以小钓大",  
        5 => "游动饵以小钓大",  
        6 => "以小钓大II",  
        _ => "未知状态",  
    };  
}  

渔获匹配(xxx)

  • 类型:布尔值
  • 描述:如果【xxx】不存在,则返回 false。
  • 鱼名目标参数处理
    • 【xxx】是鱼名目标参数,空天姬会将预设中的鱼名目标参数的同名捕获组处理为:
      • 【aaa、bbb、ccc】|id1|id2|id3|
      • 【?aaa、bbb、ccc】?|id1|id2|id3|
      • 【任何】|any|
      • 【?任何】?|any|
      • 【占位】?|any|
    • 匹配逻辑
      • 如果【xxx】以 "?" 开头,表示排除模式:渔获不在鱼名目标列表且不包含 "|any|"。
      • 否则:鱼名在目标列表或包含 "|any|"。
    • 代码示例
      string 目标 = "|id1|id2|id3|";  
      
      bool 渔获匹配(string 目标)  
      {  
          if (刚刚没钓到鱼)  
          {  
              return false;  
          }  
      
          if (!存在预设参数(目标))  
          {  
              return false;  
          }  
      
          return 目标.StartsWith("?")  
              ? (!目标.Contains(渔获) && !目标.Contains("|any|"))  
              : (目标.Contains(渔获) || 目标.Contains("|any|"));  
      }  

计数模式类型

  • 类型:整数
  • 描述:在解析预设时判断,用作指示应该钓满还是留1个,并且在处理满足需求时的行为也不同。
  • 类型说明
    • 类型为1
      • 表示需要满足所有数量,一般用于钓指定数量的鱼的预设或含有阶段参数。
      • 在钓满时:
        • 如果不存在阶段参数,视为完成目标,停止所有自动动作。
        • 如果存在阶段参数,切换到内层预设(阶段预设参数)。
    • 类型为2
      • 表示窗口期前的预触鱼识,表示需要满足指定的数量 - 1 的数量。
      • 在满足指定的数量 - 1 时,需尝试使用专一。
      • 注意:在进入窗口期时如果值为2,退出计数模式。
  • 代码示例
    void 确定计数模式类型()  
    {  
        // 优先存在阶段参数的情况  
        if (是否优先使用模式一())   
        {  
            计数模式类型 = 1;  
            return;  
        }  
    
        // 检查模式一条件  
        if (是否满足模式一条件())  
        {  
            计数模式类型 = 1;  
            return;  
        }  
    
        // 检查模式二条件  
        if (是否满足模式二条件())  
        {  
            计数模式类型 = 2;  
            return;  
        }  
    }  
    
    // 检查是否优先使用模式一  
    private bool 是否优先使用模式一()  
    {  
        return !是否存在预设参数(阶段参数) &&  
               是否存在预设参数(计数目标1);  
    }  
    
    // 检查是否满足模式一条件  
    private bool 是否满足模式一条件()  
    {  
        return 是否存在预设参数(计数目标1) &&  
               !是否存在预设参数(阶段参数) &&  
               !是否存在预设参数(鱼识参数) &&  
               !是否处于鱼识模式;  
    }  
    
    // 检查是否满足模式二条件  
    private bool 是否满足模式二条件()  
    {  
        // 存在et和天气参数  
        return 是否存在预设参数(计数目标1) &&  
               是否存在预设参数(鱼识参数) &&  
               !是否处于鱼识模式 &&  
               是否存在窗口期参数 &&  
               !是否在窗口期内() &&  
               !是否存在预设参数(阶段参数);  
    }  

饵鱼模式

  • 类型:布尔值
  • 描述:表示处在窗口期前的自动预备模式,在解析钓法表达式时被判断。
  • 条件:当满足以下条件时,该布尔值为真:
    bool 是否处于饵鱼模式()  
    {  
        return 是否存在预设参数(竿型2) &&  
               计数模式类型 != 2 &&  
               !是否处于海钓模式 &&  
               是否存在窗口期参数 && // 存在et和天气参数  
               !是否在窗口期内() &&  
               (  
                   (  
                       游动饵数量 < 3 && // 防溢出  
                       玩家等级 >= 91 // 熟练妙招的学习等级  
                   ) ||  
                   !以小钓大亮起   
               ); // 未学习熟练妙招时,目的是保护已经持有的可以小钓大的鱼  
    }  

仅自动预备时鱼篓

  • 类型:布尔值
  • 描述:表示该鱼篓参数仅在自动预备时生效。
  • 代码示例
    bool 仅自动预备时鱼篓(int 当前钓法阶段)  
    {  
        if (!是否存在预设参数("鱼篓", 当前钓法阶段))  
        {  
            return false;  
        }  
    
        return 获取参数值("鱼篓", 当前钓法阶段).Contains("《");  
    }  

空天姬触发器组结构

Folder: 限定职业  
	Folder: .控制  
		Trigger: 收竿终止 播报  
		Trigger: 记录参数 启动  
		Folder: 模式 控制  
			Trigger: 模式:定时  
			Trigger: 模式:拍水预设  
			Trigger: 模式:攒鱼计  
			Trigger: 模式:目标  
			Trigger: 模式:计数  
			Trigger: 模式:钓饵启动  
			Trigger: 模式:预拍水  
			Trigger: 模式:预饵鱼  
			Trigger: 模式:鱼识  
			Trigger: 模式:鱼识绝命竿  
			Folder: 模式:窗口  
				Trigger: 模式:ET 计时  
				Trigger: 模式:天气  
				Trigger: 模式:结束窗口  
				Trigger: 模式:进入窗口  
				Trigger: 模式:鱼眼 ET 计时  
			Folder: 模式:鱼王  
				Trigger: 0.1 抛竿  
				Trigger: 0.2 已存在钓场  
				Trigger: 1. 判断并输入预设  
				Trigger: 2. 未知钓场  
				Trigger: 3. 超时报错  
				Trigger: 4. 鱼王位置表格不存在  
			Folder: 模式:鱼眼  
				Trigger: 1.1 准备动作  
				Trigger: 1.2 追加鱼篓  
				Trigger: 2.1 使用鱼眼  
				Trigger: 2.2 状态启动  
				Trigger: 2.3 使用强心剂  
				Trigger: 3.1 回到原预设  
				Trigger: 3.2 鱼眼绝命竿  
	Folder: A.1 特殊玩法  
		Folder: 1. 海钓数据 控制  
			Trigger: 0. 海钓预设 启动  
			Trigger: 1.1 航线数据  
			Trigger: 1.2 海域时段  
			Trigger: 1.3 幻海流数据  
			Trigger: 1.4.1 幻海流状态 时段  
			Trigger: 1.4.2 幻海流绝命竿  
			Trigger: 1.4.3 幻海流刚刚进入  
			Trigger: 2.1 成就计数器  
			Trigger: 3.2 强心剂补充  
			Trigger: 3.3 海钓结束 中断动作  
			Trigger: 4.1 普海钓饵 播报  
			Trigger: 4.2 幻海时长 播报  
			Trigger: 4.3 蓝鱼上钩播报  
			Trigger: 4.4 成就数量 播报  
			Trigger: 5.1 预备 无海域映射  
			Trigger: 5.2 预备 启动  
			Trigger: 5.3 启动提示  
			Trigger: 5.4 预设缺失  
			Folder: 中断耐心  
				Trigger: 1.1 中断动作  
				Trigger: 1.2 中断超时  
				Trigger: 2. 调用动作推送  
			Folder: 备用海域信息获取  
				Trigger: 0.1 海钓状态监测  
				Trigger: 0.2 备用海域数据  
		Folder: 2. 空岛 控制  
			Trigger: 0. 空岛预设 启动  
			Trigger: 1. 天气变化  
			Trigger: 2. 提示结束  
		Folder: 3. 宇宙  
			Trigger: 0. 读取输入预设  
			Trigger: 2. 重置宇宙提钩  
	Folder: B.1 动作  
		Trigger: 0. 推送动作  
		Trigger: 1.1 推送海钓动作  
		Trigger: 2.1 动作执行  
		Trigger: 2.2 动作检测  
		Trigger: 3.1 超时处理  
		Trigger: 3.2 强心剂超时  
		Trigger: 4. 监听鱼篓暂存  
	Folder: C. 自动组件  
		Trigger: 0. 竿时 控制  
		Trigger: 1.1 推送提钩  
		Trigger: 1.2 推送海钓提钩  
		Trigger: 1.3 提钩 执行  
		Trigger: 1.4 宇宙提钩 执行  
		Trigger: 2.1 引诱真空期 控制  
		Trigger: 2.2 断竿 歇竿  
		Trigger: 2.3 引诱 A/M Lures  
		Trigger: 3.1.1 触发收藏动作  
		Trigger: 3.1.2 确定收藏动作  
		Trigger: 3.1.3 调整收藏状态  
		Trigger: 3.2 调整钓组状态  
		Trigger: 4. 尝试强心剂  
		Trigger: 5. 强制撒饵  

表达式解析

按触发器动作顺序

async Task 空天姬初始化处理(string param, string type)  
{  
   // 下文中可能会用「钓法」来称呼「钓法表达式」  
    // 钓法表达式就是像这样的一串东西:平钓(万能拟饵)全部=不撒饵  
  
    // Action 2: 中断抛竿前技能动作(保留抛竿后动作,如提钩判断、引诱、计时器等)  
    public void CancelPreCastActions()  
    {  
        CancelFolder("ce3bfe6d-61e7-4804-9b54-aa2a84b8b6c0"); // Folder: 抛竿前技能动作  
    }  
  
    // Action 3: 清除动作相关变量  
    public void ClearActionVariables()  
    {  
        UnsetListRegex("^空天姬动作"); // 清除以空天姬动作为前缀的列表变量  
    }  
  
    // Action 6: 取消窗口期计时器  
    public void CancelWindowTimer()  
    {  
        CancelFolder("fed11fb2-4207-4c71-9a45-06489a8c3da9"); // Folder: 窗口期计时器  
    }  
  
    // Action 7: 取消鱼眼组件的动作和计时器  
    public void CancelFishEyeComponent()  
    {  
        CancelFolder("f6b33082-96a1-48f6-97d2-e97d52059c68"); // Folder: 鱼眼组件  
    }  
  
    // Action 12: 初始化暂停控制  
    public void InitializePauseControl()  
    {  
        if (参数() == "0") // 接受新钓法时不处在自动状态  
        {  
            空天姬控制暂停 = "";  
        }  
    }  
  
    // Action 13: 清除旧的自动部分变量  
    public void ClearAutoVariables()  
    {  
        UnsetVariableRegex("^空天姬(?:(?:拍|专一)(?:占位|最|竿型|目标|多提)|大鱼[^猎]|最[^后]|目标|参数|超出窗口|预设|换饵|钓饵|预拍水|天气|饵鱼模式|阶段参数|手法|定时|拍水后)");  
    }  
  
    // Action 14: 清除鱼识参数  
    public void ClearFishKnowledgeParameters()  
    {  
        if (!处于阶段模式) // 非阶段模式1  
        {  
            UnsetVariableRegex("^空天姬鱼识参数");  
        }  
    }  
  
    // Action 15: 销毁鱼识绝命竿标志  
    public void ClearFishKnowledgeFatalRod()  
    {  
        空天姬鱼识绝命竿 = "";  
    }  
  
    // Action 16: 清除目标表  
    public void ClearTargetTable()  
    {  
        if (是否需要清除目标表())  
        {  
            UnsetTableRegex("^空天姬目标");  
        }  
    }  
  
    private bool 是否需要清除目标表()  
    {  
        return ( !处于海钓区域 && 存在参数计数目标1) ||   
            海钓模式类型 == 2 ; // 蓝鱼模式  
    }  
  
    // Action 17: 设置原参数  
    public void SetOriginalParameters()  
    {  
        if (!鱼识模式() && 空天姬阶段模式 != 1 && !拍水模式()) // 非鱼识、阶段模式1或拍水模式  
        {  
            空天姬原参数 = 原参数;  
        }  
    }  
  
    // Action 18: 设置阶段参数  
    public void SetStageParameters()  
    {  
        if (阶段参数 != "" && 计数目标1 != "") // 阶段参数和计数目标均存在  
        {  
            空天姬阶段参数 = 阶段参数;  
        }  
    }  
  
    // Action 19: 设置鱼识参数  
    public void SetFishKnowledgeParameters()  
    {  
        if (鱼识参数 != "") // 鱼识参数存在  
        {  
            空天姬鱼识参数 = 鱼识参数;  
        }  
    }  
  
    // Action 20: 设置拍水后预设  
    public void SetSurfaceSlapPreset()  
    {  
        if (拍水后预设 != "") // 拍水后预设存在  
        {  
            空天姬拍水后预设 = 拍水后预设;  
        }  
    }  
  
    // Action 21: 设置基本模式类型  
    public void SetParameters(string param)  
    {  
        空天姬参数 = param switch  
        {  
            "平钓" => 1,  
            "大鱼" => 2,  
            "耐心" => 3,  
            _ => 空天姬参数  
        };  
    }  
  
    // Action 22: 设置钓饵  
    public void SetBait()  
    {  
        if (钓饵 != "" && 空天姬钓饵名.IndexOf(钓饵) != 0) // 钓饵存在且名称不匹配  
        {  
            空天姬钓饵 = 钓饵;  
        }  
    }  
  
    // Action 23: 设置天气  
    public void SetWeather()  
    {  
        if (天气 != "" && Regex.IsMatch(空天姬天气集合, 天气.Replace("、", "|"))) // 天气存在且匹配天气集合  
        {  
            空天姬天气 = 天气.Replace("、", "|");  
        }  
    }  
  
    // Action 24: 设置最小ET  
    public void SetMinET()  
    {  
        if (空天姬最小ET <= 2400 && 空天姬最小ET.ToString() != "") // 最小ET小于2400且非空  
        {  
            空天姬最小ET = NextETms(FormatDouble(空天姬最小ET, "00:00"));  
        }  
    }  
  
    // Action 25: 设置最大ET  
    public void SetMaxET()  
    {  
        if (空天姬最大ET <= 2400 && 空天姬最大ET.ToString() != "") // 最大ET小于2400且非空  
        {  
            空天姬最大ET = NextETms(FormatDouble(空天姬最大ET, "00:00"));  
        }  
    }  
  
    // Action 26: 重置最小ET  
    public void ResetMinET()  
    {  
        if (是否需要重置最小ET())  
        {  
            空天姬最小ET = 0;  
        }  
    }  
  
    private bool 是否需要重置最小ET()  
    {  
        return (空天姬最小ET >= 空天姬最大ET && 空天姬最小ET.ToString() != "") || 空天姬最小ET.ToString() == ""; // 最小ET大于等于最大ET或为空  
    }  
  
    // Action 27: 设置拍占位  
    public void SetSurfaceSlapPlaceholder()  
    {  
        if (拍目标.Contains("拍") || 拍目标.Contains("占位")) // 拍目标包含拍或占位  
        {  
            空天姬拍占位 = "1";  
        }  
    }  
  
    // Action 28: 解析钓法  
    public void ParseFishingMethod()  
    {  
        Handle(空天姬目标); // 调用 handle 方法  
    }  
  
    // Action 30: 初始化最小竿时  
    public void SetMinRodTime()  
    {  
        空天姬最小竿时 = 空天姬撒饵 ? 空天姬大鱼最小区间[以小钓大阶段] : 空天姬大鱼最小区间非撒饵[以小钓大阶段];  
    }  
  
    // Action 31: 初始化最大竿时  
    public void SetMaxRodTime()  
    {  
        空天姬最大竿时 = 空天姬撒饵 ? 空天姬大鱼最大区间[以小钓大阶段] : 空天姬大鱼最大区间非撒饵[以小钓大阶段];  
    }  
  
    // Action 32: 设置鱼篓1  
    public void SetFishBasket1()  
    {  
        if (大鱼鱼篓1 != "") // 大鱼鱼篓1存在  
        {  
            空天姬大鱼鱼篓1 = "1";  
        }  
    }  
  
    // Action 33: 设置手法鱼篓  
    public void SetFishBasketTechnique()  
    {  
        if (是否满足鱼篓手法条件())  
        {  
            空天姬手法鱼篓 = "1";  
        }  
    }  
  
    private bool 是否满足鱼篓手法条件()  
    {  
        return Math.Max(大鱼鱼篓1.ToInt() * 1, 大鱼鱼篓2.ToInt() * 1, 大鱼鱼篓3.ToInt() * 2, 大鱼鱼篓4.ToInt() * 3) ==  
               Math.Max(大鱼竿型1.ToInt() * 1, 大鱼竿型2.ToInt() * 2, 大鱼竿型3.ToInt() * 3, 大鱼竿型4.ToInt() * 4) &&  
               玩家等级 >= 91;  
    }  
  
    // Action 34: 获取当前天气ID  
    public void GetCurrentWeather()  
    {  
        KTJGetCurrentWeather(1);  
    }  
  
    // Action 35: 设置手法鱼眼  
    public void SetFishEyeTechnique()  
    {  
        if (是否满足鱼眼手法条件())  
        {  
            空天姬手法鱼眼 = "1";  
        }  
    }  
  
    // 鱼眼的处理  
    // 进入鱼眼分支必须满足天气条件  
    // 如果提供了et窗口期且当前满足et条件,进入正常的分支,不使用鱼眼,并且启动一个计时器,在et窗口期结束时进入鱼眼分支  
    // 如果当前未在et窗口期,进入鱼眼分支,并且启动一个计时器,在进入et窗口期时进入正常分支  
    // 以上部分会在鱼眼组件有示例。  
  
    private bool 是否满足鱼眼手法条件()  
    {  
        return 目标.Contains("鱼眼") &&  
               ((空天姬最小ET != 0 && 存在参数最大ET()) || !存在参数最大ET()) &&  
               (!天气() || Regex.IsMatch(空天姬天气[空天姬天气ID], 空天姬天气));  
    }  
  
    // Action 36: 记录鱼眼等待ET  
    public void LogFishEyeWaitingET()  
    {  
        if (控制海钓模式 != "1" && 最大ET() && 手法鱼眼()) // 非海钓模式、有最大ET且鱼眼手法激活  
        {  
            Log($"空天姬鱼眼等待ET{空天姬最小ET}", true);  
        }  
    }  
  
    // Action 37: 重置鱼眼最小ET  
    public void ResetFishEyeMinET()  
    {  
        if (手法鱼眼()) // 鱼眼手法激活  
        {  
            空天姬最小ET = 0;  
        }  
    }  
  
    // Action 38: 设置手法多提  
    public void SetMultiHookTechnique()  
    {  
        if (是否满足多提条件())  
        {  
            空天姬手法多提 = $"{大鱼技巧提钩1}{大鱼技巧提钩2}{大鱼技巧提钩3}{大鱼技巧提钩4}{大鱼技巧提钩5}{专一多提}".Contains("3") ? "3" : "4";  
        }  
    }  
  
    private bool 是否满足多提条件()  
    {  
        return Regex.IsMatch($"{大鱼技巧提钩1}{大鱼技巧提钩2}{大鱼技巧提钩3}{大鱼技巧提钩4}{大鱼技巧提钩5}{专一多提}", "[34]") &&  
               (目标.Contains("多提") || 目标.Contains("多提优先"));  
    }  
  
    // Action 44: 设置模式所需采集力  
    public void SetModeRequiredGathering()  
    {  
        空天姬模式所需采集力 = 空天姬参数 == 1  
            ? (手法收藏品() ? (控制海钓模式() ? 200 : 400) : 0)  
            : (空天姬参数 == 2 ? (控制海钓模式() ? 200 : 400) : 560);  
    }  
  
    // Action 45: 设置额外所需采集力  
    public void SetExtraRequiredGathering()  
    {  
        空天姬额外所需采集力 = 空天姬模式所需采集力 +  
            (拍目标() ? 200 : 0) +  
            (专一目标() ? 350 : 0) +  
            ((手法重随() || 手法鱼影()) ? 60 : 0) +  
            (手法鱼篓() ? 100 : 0) +  
            (手法多提() ? (空天姬手法多提 == "3" ? 684 : 384) : 0);  
    }  
  
    // Action 46: 设置额外所需采集力低优先  
    public void SetExtraRequiredGatheringLowPriority()  
    {  
        空天姬额外所需采集力低优先 = (拍目标() ? 200 : 0) +  
            ((手法重随() || 手法鱼影()) ? 60 : 0) +  
            (手法鱼篓() ? 100 : 0);  
    }  
  
    // Action 47: 激活抛竿后触发器分组  
    public void ActivatePostCastTriggers()  
    {  
        ActivateFolder("77e764c5-2e86-408a-a888-b23d6a594ddc"); // Folder: 抛竿后动作  
    }  
  
    // Action 52: 初始化计数模式  
    public void InitializeCountMode()  
    {  
        空天姬计数模式 = "";  
    }  
  
    // Action 53: 设置计数模式1  
    public void SetCountMode1()  
    {  
        if (是否满足计数模式1条件())  
        {  
            空天姬计数模式 = "1";  
        }  
    }  
  
    private bool 是否满足计数模式1条件()  
    {  
        return 计数目标1 != "" && 空天姬鱼识模式 != 1 && !鱼识参数() && !阶段参数();  
    }  
  
    // Action 54: 设置计数模式2  
    public void SetCountMode2()  
    {  
        if (是否满足计数模式2条件())  
        {  
            空天姬计数模式 = "2";  
        }  
    }  
  
    private bool 是否满足计数模式2条件()  
    {  
        return 计数目标1 != "" && !鱼识模式() &&  
               (天气() != "0" || (空天姬最小ET.ToString() != "0" && 最大ET() != "0")) &&  
               鱼识参数() && !阶段参数();  
    }  
  
    // Action 55: 设置计数模式1(阶段参数优先)  
    public void SetCountMode1WithStage()  
    {  
        if (计数目标1 != "" && 阶段参数()) // 有计数目标和阶段参数  
        {  
            空天姬计数模式 = "1";  
        }  
    }  
  
    // Action 56: 启用抛竿前动作触发器  
    public void ActivatePreCastTriggers()  
    {  
        if (是否需要启用抛竿前触发器())  
        {  
            ActivateFolder("ce3bfe6d-61e7-4804-9b54-aa2a84b8b6c0"); // Folder: B.1 动作  
        }  
    }  
  
    private bool 是否需要启用抛竿前触发器()  
    {  
        return (!最大ET() && !天气()) || // 无ET和天气  
               (空天姬最小ET.ToString() == "0" && 最大ET() != "0" && !天气()) || // 最小ET为0且最大ET存在且无天气  
               空天姬计数模式 == "2"; // 计数模式为2  
    }  
  
    // Action 57: 启用计数触发器  
    public void EnableCountTrigger()  
    {  
        if (计数模式 != null && 计数模式() != 0 && 处于海钓模式) // 计数模式非0且处于海钓模式  
        {  
            EnableTrigger("3f08c429-1513-4a70-891d-ef7c37fab19", "regexp"); // Trigger: 计数模式  
        }  
    }  
  
    // Action 58: 启用攒鱼计触发器  
    public void EnableFishCounterTrigger()  
    {  
        if (Regex.IsMatch(空天姬目标, "鱼计")) // 目标包含鱼计修饰词  
        {  
            EnableTrigger("7b748038-76cb-4b9e-8d99-5fa8a724f3d8", "regexp"); // Trigger: 攒鱼计  
        }  
    }  
  
    // Action 60: 设置饵鱼模式  
    public void SetBaitFishMode()  
    {  
        if (是否满足饵鱼模式条件())  
        {  
            空天姬饵鱼模式 = "1";  
        }  
    }  
  
    private bool 是否满足饵鱼模式条件()  
    {  
        return !处于海钓模式 && // 非海钓模式  
               大鱼竿型2() && // 存在竿型2  
               (最大ET() && 空天姬最小ET.ToString() != "0" || 天气() == "1") && // 窗口期外  
               (!以小钓大亮起 || (已有的游动饵 < 3 && 玩家等级 >= 91)) &&  
               计数模式类型 != "2"; // 非计数模式2  
    }  
  
    // Action 61: 启用拍水触发器  
    public void EnableSurfaceSlapTrigger()  
    {  
        if (是否满足拍水触发条件())  
        {  
            EnableTrigger("c186fea6-ffb9-46a6-9028-df73b7f53164", "regexp"); // Trigger: 模式:预拍水  
        }  
    }  
  
    private bool 是否满足拍水触发条件()   
    {  
    return 存在参数拍目标 &&   
    !处在海钓模式 &&   
    !窗口期内 &&   
    !处在饵鱼模式 &&  
    计数模式类型 != 2 &&  
    (!持有状态拍击水面 || 鱼计 < 8) &&   
    !存在参数竿型2  
    }  
  
    // Action 62: 启用饵鱼触发器  
    public void EnableBaitFishTrigger()  
    {  
        if (是否满足饵鱼触发条件())  
        {  
            EnableTrigger("8ccf019a-0d98-4282-8365-fbc7b94a24ab", "regexp"); // Trigger: 模式:预饵鱼  
        }  
    }  
  
    private bool 是否满足饵鱼触发条件()  
    {  
        return !处于海钓模式 && // 非海钓模式  
               处于饵鱼模式 && // 处于饵鱼模式  
               计数模式类型 != 2 && // 非计数模式2  
               存在窗口期参数 &&   
               !处于窗口期 &&   
               是否满足以小钓大或鱼篓条件(); // 满足以小钓大或鱼篓条件  
    }  
  
    private bool 是否满足以小钓大或鱼篓条件()  
    {  
        return (!以小钓大亮起 || (已有的游动饵 < 3 && 玩家等级 >= 91))  
    }  
  
    // Action 63: 启用目标触发器  
    public void EnableTargetTrigger()  
    {  
        if (存在参数目标 && !处于海钓模式) // 目标存在且非海钓模式  
        {  
            EnableTrigger("09e3c59a-caaf-4388-929b-8af661e09a9c"); // Trigger: 模式:目标  
        }  
    }  
  
    // Action 64: 禁用鱼眼文件夹  
    public void DisableFishEyeFolder()  
    {  
        DisableFolder("f6b33082-96a1-48f6-97d2-e97d52059c68"); // Folder: 模式:鱼眼  
    }  
  
    // Action 65: 激活鱼眼文件夹  
    public void ActivateFishEyeFolder()  
    {  
        if (!处于海钓模式 && 存在手法修饰词鱼眼 ) // 非海钓模式且鱼眼手法激活且无天气条件  
        {  
            ActivateFolder("f6b33082-96a1-48f6-97d2-e97d52059c68"); // Folder: 模式:鱼眼  
        }  
    }  
  
    // Action 66: 禁用推送动作触发器  
    public void DisableActionPushTrigger()  
    {  
        DisableTrigger("4559cac8-4dff-41fb-9cf0-b0b1005a63f3"); // Trigger: 0. 推送动作  
    }  
  
    // Action 67: 禁用海钓推送动作触发器  
    public void DisableSeaFishingActionPushTrigger()  
    {  
        DisableTrigger("a718b032-bfe9-4a70-a421-237f70f346b1"); // Trigger: 1.1 推送海钓动作  
    }  
  
    // Action 68: 启用推送动作触发器  
    public void EnableActionPushTrigger()  
    {  
        if (是否满足推送动作条件())  
        {  
            EnableTrigger("4559cac8-4dff-41fb-9cf0-b0b1005a63f3"); // Trigger: 0. 推送动作  
        }  
    }  
  
    private bool 是否满足推送动作条件()  
    {  
        return (!存在窗口期参数) || // 无最大ET且无天气  
               (在窗口期内) || // 最小ET为0且最大ET存在且无天气  
               计数模式类型 == "2"; // 计数模式为2  
    }  
  
    // Action 69: 启用海钓推送动作触发器  
    public void EnableSeaFishingActionPushTrigger()  
    {  
        if (处在海钓模式)   
        {  
            EnableTrigger("a718b032-bfe9-4a70-a421-237f70f346b1"); // Trigger: 1.1 推送海钓动作  
        }  
    }  
  
    // Action 70: 启用动作执行触发器 非海钓情况的触发器  
    public void EnableActionExecuteTrigger()  
    {  
        if (是否满足动作执行条件())  
        {  
            EnableTrigger("550c0c65-1fd1-4b25-8bc8-cbc0fb4d0497"); // Trigger: 2.1 动作执行  
        }  
    }  
  
    private bool 是否满足动作执行条件()  
    {  
        return (!最大ET() && !天气()) || // 无最大ET且无天气  
               (空天姬最小ET.ToString() == "0" && 最大ET() != "0" && !天气()) || // 最小ET为0且最大ET存在且无天气  
               空天姬计数模式 == "2"; // 计数模式为2  
    }  
  
    // Action 72: 启用收藏动作触发器  
    // 空天姬会在抛竿后再处理收藏品,这样节省抛竿前的时间  
    public void EnableCollectActionTrigger()  
    {  
        if (存在手法修饰词收藏品 && !存在手法修饰词不收集) // 收藏品手法激活且非不收集  
        {  
            EnableTrigger("ba21f505-c809-4ef8-bf12-b825735b61e3", "regexp,conditions"); // Trigger: 3.1.2 确定收藏动作  
        }  
    }  
  
    // Action 73: 启用调整收藏状态触发器  
    public void EnableAdjustCollectStateTrigger()  
    {  
        EnableTrigger("f0790f9d-79b9-404e-a625-1e19951c9438"); // Trigger: 3.1.3 调整收藏状态  
    }  
  
    // Action 74: 设置钓组调整标志 74和75都是用来调整钓组状态的,钓组状态需要在抛竿前调整  
    // 存在手法修饰词钓组 时,需要使用钓组技能打开钓组,也可以写在抛竿前的检查  
    public void SetFishingGearAdjustFlag()  
    {  
        if (是否需要调整钓组())  
        {  
            空天姬手法钓组调整中 = "1";  
        }  
    }  
  
    private bool 是否需要调整钓组()  
    {  
        return (!控制钓组状态() && 手法钓组()) || // 钓组状态未控制且手法需要钓组  
               (控制钓组状态() && !手法钓组()); // 钓组状态已控制但手法不需要钓组  
    }  
  
    // Action 75: 触发钓组调整  
    public void TriggerFishingGearAdjust()  
    {  
        if (是否需要调整钓组())  
        {  
            触发("47285b0b-d63a-4837-9020-bf14d1d530d5", force: "regexp"); // Trigger: 3.2 调整钓组状态  
        }  
    }  
  
    // Action 76: 启用天气触发器  
    // 这是一个隔一段时间就判断天气是否符合条件的触发器  
    public void EnableWeatherTrigger()  
    {  
        if (存在参数天气) //  
        {  
            EnableTrigger("e377a5a8-cb44-47bf-9f5b-3faf2844661e"); // Trigger: 模式:天气  
        }  
    }  
  
    // // Action 77: 设置参数不播报  
    // 播报用的标记,卫月不做播报的话忽视  
    // public void SetNoReportParameter()  
    // {  
    //     if (是否满足不播报条件())  
    //     {  
    //         空天姬参数不播报 = "1";  
    //     }  
    // }  
  
    // private bool 是否满足不播报条件()  
    // {  
    //     return ((最大ET() && 空天姬最小ET.ToString() == "0") || 空天姬天气 != "") && // 最大ET存在且最小ET为0或天气存在  
    //            (空天姬鱼识模式 == 1 || 空天姬阶段模式 != 0 || 鱼眼模式() || 空天姬拍水模式 == 1); // 鱼识、阶段、鱼眼或拍水模式任一激活  
    // }  
  
    // Action 78: 设置最大ET结束时间  
    // 一个计算窗口期还剩多少秒用的值  
    public void SetMaxETEndTime()  
    {  
        if (是否满足设置ET结束时间条件())  
        {  
            空天姬最大ET结束时间 = (空天姬最大ET + 当前时间戳毫秒) / 1000;  
        }  
    }  
  
    private bool 是否满足设置ET结束时间条件()  
    {  
        return 控制海钓模式 != "1" && !手法鱼眼() && 最大ET() != "0"; // 非海钓模式、非鱼眼手法且最大ET存在  
    }  
  
    // Action 79: 如满足条件,开始等待et的计时器  
    public void LogWaitingET()  
    {  
        if (是否满足设置ET结束时间条件())  
        {  
            Log("空天姬等待ET", true);  
        }  
    }  
  
    // Action 80: 如果满足条件,开始一个隔一段时间就判断一次天气的计时器  
    public void LogWaitingWeather()  
    {  
        if (空天姬天气 != "") // 天气存在  
        {  
            Log("空天姬等待天气", true);  
        }  
    }  
  
    // Action 81: 禁用拍击水面技能  
    public void DisableSurfaceSlapSkill()  
    {  
        if (鱼识参数()) // 新钓法输入时,如果存在鱼识参数,取消状态拍击水面  
        {  
            Command($"/statusoff \"{空天姬技能[空天姬配置["语言"]]["拍击水面"]}\"");  
        }  
    }  
  
    // Action 82: 触发鱼识预设  
    // 一个防御性的动作,当存在参数鱼识参数 && 持有状态捕鱼人之识 && 不处于鱼识模式时,触发进入鱼识模式的动作,切换到鱼识钓法  
    public void LogAndTriggerFishKnowledge()  
    {  
        if (持有状态捕鱼人之识 && !处于鱼识模式 && 存在参数鱼识参数)   
        {  
            触发("94c20c52-5a2f-4812-853c-bc973a701cb8", "123456789112345StatusAdd 1A:238:1:1:{玩家ID}"); // Trigger: 模式:鱼识  
        }  
        else if (存在参数鱼识参数 || !持有状态捕鱼人之识)  
        {  
            清除标记鱼识模式;  
        }  
    }  
  
    // Action 83: 触发拍水预设 目的同上,但这个参数是拍水后的新钓法  
    // 当 持有状态拍击水面,不处于拍水后模式,存在参数拍水后预设 时,触发进入拍水后模式的动作,切换到拍水后钓法  
    public void LogAndTriggerSurfaceSlapPreset()  
    {  
        if (持有状态拍击水面 && !处于拍水后模式 && 存在参数拍水后预设)   
        {  
            触发("cd1744a7-bfc7-4c4f-a3f4-59fd5f5a5b6d", "123456789112345StatusAdd 1A:70B:1:1:{玩家ID}"); // Trigger: 模式:拍水预设  
        }  
        else if (存在参数拍水后预设 || !处于拍水后模式)  
        {  
            清除标记拍水后模式;  
        }  
    }  
  
  
    // Action 86: 销毁标记鱼眼模式  
    销毁标记鱼眼模式;  
  
    // Action 87: 进入一般分支,触发推送抛竿前技能触发器  
    public void LogExecution()  
    {  
        if (是否满足执行日志条件())  
        {  
            Log("空天姬执行", true);  
        }  
    }  
  
    private bool 是否满足执行日志条件()  
    {  
        return 是否满足推送动作条件() &&   
               !存在参数钓饵 && // 这部分是因为抛竿前要换饵,下面几个判断执行的部分会在换饵组件重复使用  
               !处于海钓模式 &&   
               !存在手法修饰词鱼眼;   
    }  
  
    // Action 88: 进入海钓分支,触发推送抛竿前技能触发器  
    public void LogSeaFishingExecution()  
    {  
        if (!存在参数钓饵 && 控制海钓模式() == "true")   
        {  
            Log("空天姬海钓执行", true);  
        }  
    }  
  
    // Action 89: 进入预拍水分支  
    public void LogSurfaceSlapStart()  
    {  
        if (是否满足拍水启动条件())  
        {  
            Log("空天姬拍水启动", true);  
        }  
    }  
  
    private bool 是否满足拍水启动条件()  
    {  
        return !处于窗口期内  &&      
               存在参数拍目标 &&   
               !处于海钓模式 &&   
               !处于饵鱼模式 &&   
               !存在参数钓饵 && // 这部分是因为抛竿前要换饵,可优化  
               计数模式类型 != 2 &&   
               (!持有状态拍击水面 || 空天姬控制鱼计 < 9) &&   
               !存在参数竿型2;   
    }  
  
    // Action 90: 进入预饵鱼分支  
    public void LogBaitFishStart()  
    {  
        if (是否满足饵鱼启动条件())  
        {  
            Log("空天姬饵鱼启动", true);  
        }  
    }  
  
    private bool 是否满足饵鱼启动条件()  
    {  
        return !处于窗口期内  &&     
               !处于海钓模式 &&   
               处于饵鱼模式 &&   
               !存在参数钓饵 && // 这部分是因为抛竿前要换饵,可优化  
               计数模式类型 != 2 &&   
                (!以小钓大亮起 || (已有的游动饵 < 3 && 玩家等级 >= 91))  
    }  
  
    // Action 91: 进入鱼眼分支  
    public void LogFishEyeStart()  
    {  
        if (是否满足鱼眼启动条件())  
        {  
            Log("空天姬魚眼启动", true);  
        }  
    }  
  
    private bool 是否满足鱼眼启动条件()  
    {  
        return !存在参数钓饵 && // 这部分是因为抛竿前要换饵,可优化  
               !处于海钓模式 &&   
               存在手法修饰词鱼眼 &&   
               处于天气窗口期内 &&   
    }  
  
    // Action 92: 进行换饵  
    public void LogBaitStart()  
    {  
        if (存在参数钓饵 && 提供的钓饵名存在于钓饵表中)   
        {  
            Log("空天姬钓饵启动", true);  
        }  
    }  
  
    // ===================== 以下都是播报动作 =====================  
  
    // Action 93: 发送更换钓饵消息  
    if (  
        空天姬钓饵 != "" &&  
        空天姬釣饵名.IndexOf(空天姬钓鱼)  
    )  
    {  
        Command($"/e ${KTJGetTranslation("消息开始更换钓饵", 空天姬配置["界面语言"].ToInt32())}");  
    }  
  
    // Action 94: 静音系统音效  
    if (  
        !鱼识模式() &&  
        空天姬釣饵 == "" &&  
        空天姬配置["关闭系统音"] == "1" &&  
        空天姬控制系统音I != "0" &&  
        !拍水模式()  
    )  
    {  
        await Task.Delay(300);  
        Command("/systemsounds 0");  
    }  
  
    // Action 95: 发送单天气提示  
    if (空天姬天气 != "" && 空天姬最大ET.ToString() == "")  
    {  
        Command($"/e {KTJGetTranslation("消息单天气提示", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 96: 发送切换内层预设消息  
    if (阶段模式())  
    {  
        Command($"/e {KTJGetTranslationByIndex("消息切换内层预设", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 97: 发送鱼识参数消息  
    if (鱼识参数())  
    {  
        Command($"/e {KTJGetTranslationByIndex("消息鱼识参数", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 98: 发送参数消息  
    if (  
        空天姬参数不播报 != "1" &&  
        !鱼识模式() &&  
        控制海钓模式 != "1" &&  
        !鱼眼模式() &&  
        !拍水模式() &&  
        空岛模式 != "1"  
    )  
    {  
        Command($"/e {KTJGetTranslationByIndex($"消息参数{空天姬参数}", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 99: 发送目标消息  
    if (  
        空天姬目标 != "" &&  
        !鱼识模式() &&  
        控制海钓模式 != "1" &&  
        !鱼眼模式() &&  
        !拍水模式() &&  
        空岛模式 != "1"  
    )  
    {  
        Command($"/e {KTJGetTranslationByIndex($"消息目标{空天姬目标}", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 100: 发送预设备注消息  
  
  
    // Action 101: 发送计数目标消息  
    if (  
        计数目标1 != "" &&  
        !鱼识模式() &&  
        控制海钓模式 != "1" &&  
        !鱼眼模式() &&  
        !拍水模式() &&  
        空岛模式 != "1"  
    )  
    {  
        Command($"/e {KTJGetTranslationByIndex($"消息计数目标{计数目标1}", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 102: 发送天气消息  
    if (  
        空天姬天气 != "" &&  
        !鱼识模式() &&  
        控制海釣模式 != "1" &&  
        !魚眼模式() &&  
        !拍水模式() &&  
        空岛模式 != "1"  
    )  
    {  
        Command($"/e {KTJGetTranslationByIndex($"消息天气{空天姬天气}", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 103: 发送ET消息  
    if (  
        空天姬最小ET.ToString() != "" &&  
        !鱼识模式() &&  
        控制海釣模式 != "1" &&  
        !魚眼模式() &&  
        !拍水模式() &&  
        空岛模式 != "1"  
    )  
    {  
        Command($"/e {KTJGetTranslationByIndex($"消息ET{空天姬最小ET}", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 104: 发送竿型消息  
    if (  
        !鱼识模式() &&  
        控制海釣模式 != "1" &&  
        !魚眼模式() &&  
        !拍水模式() &&  
        空岛模式 != "1"  
    )  
    {  
        Command($"/e {KTJGetTranslationByIndex($"消息竿型{type}", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 105: 发送拍水消息  
    if (  
        空天姬拍目标 != "" &&  
        !鱼识模式() &&  
        控制海釣模式 != "1" &&  
        !魚眼模式() &&  
        !拍水模式() &&  
        空岛模式 != "1"  
    )  
    {  
        Command($"/e {KTJGetTranslationByIndex($"消息拍水{空天姬拍目标}", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 106: 发送鱼篓消息  
    if (  
        空天姬手法鱼篓 == "1" &&  
        !鱼识模式() &&  
        控制海釣模式 != "1" &&  
        !魚眼模式() &&  
        !拍水模式() &&  
        空岛模式 != "1"  
    )  
    {  
        Command($"/e {KTJGetTranslationByIndex("消息鱼篓", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 107: 发送多提消息  
    if (  
        空天姬手法多提 != "" &&  
        !鱼识模式() &&  
        控制海釣模式 != "1" &&  
        !魚眼模式() &&  
        !拍水模式() &&  
        空岛模式 != "1"  
    )  
    {  
        Command($"/e {KTJGetTranslationByIndex($"消息多提{空天姬手法多提}", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 108: 发送钓饵消息  
    if (  
        空天姬钓饵 != "" &&  
        !鱼识模式() &&  
        控制海釣模式 != "1" &&  
        !魚眼模式() &&  
        !拍水模式() &&  
        空岛模式 != "1"  
    )  
    {  
        Command($"/e {KTJGetTranslationByIndex($"消息钓饵{空天姬钓饵}", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 109: 发送鱼眼消息  
    if (  
        空天姬手法鱼眼 == "1" &&  
        !鱼识模式() &&  
        控制海釣模式 != "1" &&  
        !魚眼模式() &&  
        !拍水模式() &&  
        空岛模式 != "1"  
    )  
    {  
        Command($"/e {KTJGetTranslationByIndex("消息鱼眼", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 110: 发送阶段参数消息  
    if (  
        空天姬阶段参数 != "" &&  
        !鱼识模式() &&  
        控制海釣模式 != "1" &&  
        !魚眼模式() &&  
        !拍水模式() &&  
        空岛模式 != "1"  
    )  
    {  
        Command($"/e {KTJGetTranslationByIndex($"消息阶段参数{空天姬阶段参数}", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 111: 发送拍水后预设消息  
    if (  
        空天姬拍水后预设 != "" &&  
        !鱼识模式() &&  
        控制海釣模式 != "1" &&  
        !魚眼模式() &&  
        !拍水模式() &&  
        空岛模式 != "1"  
    )  
    {  
        Command($"/e {KTJGetTranslationByIndex($"消息拍水后预设{空天姬拍水后预设}", 空天姬配置["界面语言"].ToInt())}");  
    }  
  
    // Action 112: 触发初始化完成  
    触发("b7f5e6a2-9f8b-4d5c-8e2a-5d6f7a8c9b0d", force: "regexp");  
}  

Handle 方法

public static void Handle(object _1, string val) {  
  AssignValues(val);  
  static void AssignValues(string input) {  
    int _lang = int.TryParse(GetDictVariable(true, "空天姬配置")  
                                 ?.GetValue("界面语言")  
                                 ?.ToString(),  
                             out var l) &&  
                        l != 0  
                    ? l  
                    : MissFisher.lang;  
  
    string 获取翻译(string s) {  
      return I18n.GetTranslationByIndex(s, _lang);  
    }  
  
    int 单语言空间 = int.Parse("${env:单语言空间}");  
    int 单语言空间乘二 = 单语言空间 * 2;  
  
    int 非水产品空间 = int.Parse("${env:非水产品空间}");  
    int 非水产品空间乘二 = 非水产品空间 * 2;  
    // 按逗号分割传入的字符串  
    string[] values = input.Split(',');  
  
    // 检查分割后的数组长度是否足够  
    if (values.Length < 49)  // 49 是硬编码变量的数量  
    {  
      return;  
    }  
  
    // 直接赋值给硬编码的变量  
    string 空天姬目标 = values[0];  
    string 空天姬拍最小区间非撒饵 = values[1];  
    string 空天姬拍最小区间 = values[2];  
    string 空天姬拍最大区间非撒饵 = values[3];  
    string 空天姬拍最大区间 = values[4];  
    string 空天姬大鱼最小区间非撒饵1 = values[5];  
    string 空天姬大鱼最小区间1 = values[6];  
    string 空天姬大鱼最大区间非撒饵1 = values[7];  
    string 空天姬大鱼最大区间1 = values[8];  
    string 空天姬大鱼最小区间非撒饵2 = values[9];  
    string 空天姬大鱼最小区间2 = values[10];  
    string 空天姬大鱼最大区间非撒饵2 = values[11];  
    string 空天姬大鱼最大区间2 = values[12];  
    string 空天姬大鱼最小区间非撒饵3 = values[13];  
    string 空天姬大鱼最小区间3 = values[14];  
    string 空天姬大鱼最大区间非撒饵3 = values[15];  
    string 空天姬大鱼最大区间3 = values[16];  
    string 空天姬大鱼最小区间非撒饵4 = values[17];  
    string 空天姬大鱼最小区间4 = values[18];  
    string 空天姬大鱼最大区间非撒饵4 = values[19];  
    string 空天姬大鱼最大区间4 = values[20];  
    string 空天姬拍竿型 = values[21];  
    string 空天姬大鱼额外竿型1 = values[22];  
    string 空天姬大鱼竿型1 = values[23];  
    string 空天姬大鱼额外竿型2 = values[24];  
    string 空天姬大鱼竿型2 = values[25];  
    string 空天姬大鱼额外竿型3 = values[26];  
    string 空天姬大鱼竿型3 = values[27];  
    string 空天姬大鱼额外竿型4 = values[28];  
    string 空天姬大鱼竿型4 = values[29];  
    string 空天姬大鱼技巧提钩1 = values[30];  
    string 空天姬大鱼技巧提钩2 = values[31];  
    string 空天姬大鱼技巧提钩3 = values[32];  
    string 空天姬大鱼技巧提钩4 = values[33];  
    string 空天姬大鱼技巧提钩5 = values[34];  
    string 空天姬专一多提 = values[35];  
    string 空天姬拍目标 = values[36];  
    string 空天姬大鱼目标1 = values[37];  
    string 空天姬大鱼目标2 = values[38];  
    string 空天姬大鱼目标3 = values[39];  
    string 空天姬专一目标 = values[40];  
    string 空天姬大鱼鱼篓1 = values[41];  
    string 空天姬大鱼鱼篓2 = values[42];  
    string 空天姬大鱼鱼篓3 = values[43];  
    string 空天姬目标计数1 = values[44];  
    string 空天姬计数目标1 = values[45];  
    string 空天姬目标计数2 = values[46];  
    string 空天姬计数目标2 = values[47];  
    string 空天姬目标计数3 = values[48];  
    string 空天姬计数目标3 = values[49];  
  
    // 获取用户配置中的延迟时间项  
    VariableDictionary 字典 =  
        GetDictVariable(true, "空天姬配置") ?? new VariableDictionary();  
  
    string GetValueOrDefault(string key, string defaultValue) {  
      return 字典.GetValue(key)?.ToString() == ""  
                 ? defaultValue  
                 : 字典.GetValue(key).ToString();  
    }  
  
    double 延迟时间 = double.Parse(GetValueOrDefault("延迟时间", "0.0"));  
  
    // 获取钓饵表,也包含鱼类  
  
    VariableList 空天姬钓饵名 =  
        GetListVariable(true, "空天姬钓饵名") ?? new VariableList();  
    VariableList 空天姬钓饵ID =  
        GetListVariable(true, "空天姬钓饵ID") ?? new VariableList();  
  
    VariableList 空天姬非水产品名 =  
        GetListVariable(true, "空天姬非水产品名") ?? new VariableList();  
    VariableList 空天姬非水产品ID =  
        GetListVariable(true, "空天姬非水产品ID") ?? new VariableList();  
  
    StringBuilder 错误信息 = new();  
  
    // 用来提取目标的正则  
    Regex 正则提取 = new(@"^【?[??]?([^】]+)】?");  
    Regex 正则鱼名否定符 = new(@"^【?[??][^??]");  
  
    // 建立手法和修饰词的映射  
    Dictionary<string, string> 关键字映射 = new() {  
      { "不撒饵", "空天姬手法不撒饵" }, { "收藏", "空天姬手法收藏品" },  
      { "攒鱼计", "空天姬手法攒鱼计" }, { "套娃", "空天姬手法套娃" },  
      { "知识", "空天姬手法知识" },     { "引诱", "空天姬手法引诱" },  
      { "重随", "空天姬手法重随" },     { "鱼影", "空天姬手法鱼影" },  
      { "钓组", "空天姬手法钓组" },     { "不收集", "空天姬手法不收集" },  
      { "回收", "空天姬手法回收" },  
    };  
  
    设置标量("空天姬拍最小区间",  
             处理撒饵竿时(空天姬拍最小区间, 空天姬拍最小区间非撒饵));  
    设置标量("空天姬拍最大区间",  
             处理撒饵竿时(空天姬拍最大区间, 空天姬拍最大区间非撒饵));  
    设置标量("空天姬大鱼最小区间1",  
             处理撒饵竿时(空天姬大鱼最小区间1, 空天姬大鱼最小区间非撒饵1));  
    设置标量("空天姬大鱼最大区间1",  
             处理撒饵竿时(空天姬大鱼最大区间1, 空天姬大鱼最大区间非撒饵1));  
    设置标量("空天姬大鱼最小区间2",  
             处理撒饵竿时(空天姬大鱼最小区间2, 空天姬大鱼最小区间非撒饵2));  
    设置标量("空天姬大鱼最大区间2",  
             处理撒饵竿时(空天姬大鱼最大区间2, 空天姬大鱼最大区间非撒饵2));  
    设置标量("空天姬大鱼最小区间3",  
             处理撒饵竿时(空天姬大鱼最小区间3, 空天姬大鱼最小区间非撒饵3));  
    设置标量("空天姬大鱼最大区间3",  
             处理撒饵竿时(空天姬大鱼最大区间3, 空天姬大鱼最大区间非撒饵3));  
    设置标量("空天姬大鱼最小区间4",  
             处理撒饵竿时(空天姬大鱼最小区间4, 空天姬大鱼最小区间非撒饵4));  
    设置标量("空天姬大鱼最大区间4",  
             处理撒饵竿时(空天姬大鱼最大区间4, 空天姬大鱼最大区间非撒饵4));  
  
    设置标量("空天姬拍最小区间非撒饵",  
             处理非撒饵竿时(空天姬拍最小区间非撒饵, 空天姬拍最小区间));  
    设置标量("空天姬拍最大区间非撒饵",  
             处理非撒饵竿时(空天姬拍最大区间非撒饵, 空天姬拍最大区间));  
    设置标量("空天姬大鱼最小区间非撒饵1",  
             处理非撒饵竿时(空天姬大鱼最小区间非撒饵1, 空天姬大鱼最小区间1));  
    设置标量("空天姬大鱼最大区间非撒饵1",  
             处理非撒饵竿时(空天姬大鱼最大区间非撒饵1, 空天姬大鱼最大区间1));  
    设置标量("空天姬大鱼最小区间非撒饵2",  
             处理非撒饵竿时(空天姬大鱼最小区间非撒饵2, 空天姬大鱼最小区间2));  
    设置标量("空天姬大鱼最大区间非撒饵2",  
             处理非撒饵竿时(空天姬大鱼最大区间非撒饵2, 空天姬大鱼最大区间2));  
    设置标量("空天姬大鱼最小区间非撒饵3",  
             处理非撒饵竿时(空天姬大鱼最小区间非撒饵3, 空天姬大鱼最小区间3));  
    设置标量("空天姬大鱼最大区间非撒饵3",  
             处理非撒饵竿时(空天姬大鱼最大区间非撒饵3, 空天姬大鱼最大区间3));  
    设置标量("空天姬大鱼最小区间非撒饵4",  
             处理非撒饵竿时(空天姬大鱼最小区间非撒饵4, 空天姬大鱼最小区间4));  
    设置标量("空天姬大鱼最大区间非撒饵4",  
             处理非撒饵竿时(空天姬大鱼最大区间非撒饵4, 空天姬大鱼最大区间4));  
  
    设置标量("空天姬拍竿型", 处理竿型(空天姬拍竿型));  
    设置标量("空天姬大鱼额外竿型1", 处理竿型(空天姬大鱼额外竿型1));  
    设置标量("空天姬大鱼竿型1", 处理竿型(空天姬大鱼竿型1));  
    设置标量("空天姬大鱼额外竿型2", 处理竿型(空天姬大鱼额外竿型2));  
    设置标量("空天姬大鱼竿型2", 处理竿型(空天姬大鱼竿型2));  
    设置标量("空天姬大鱼额外竿型3", 处理竿型(空天姬大鱼额外竿型3));  
    设置标量("空天姬大鱼竿型3", 处理竿型(空天姬大鱼竿型3));  
    设置标量("空天姬大鱼额外竿型4", 处理竿型(空天姬大鱼额外竿型4));  
    设置标量("空天姬大鱼竿型4", 处理竿型(空天姬大鱼竿型4));  
  
    设置标量("空天姬大鱼技巧提钩1", 处理技巧提钩(空天姬大鱼技巧提钩1));  
    设置标量("空天姬大鱼技巧提钩2", 处理技巧提钩(空天姬大鱼技巧提钩2));  
    设置标量("空天姬大鱼技巧提钩3", 处理技巧提钩(空天姬大鱼技巧提钩3));  
    设置标量("空天姬大鱼技巧提钩4", 处理技巧提钩(空天姬大鱼技巧提钩4));  
    设置标量("空天姬大鱼技巧提钩5", 处理技巧提钩(空天姬大鱼技巧提钩5));  
    设置标量("空天姬专一多提", 处理技巧提钩(空天姬专一多提));  
  
    设置标量("空天姬拍目标", 处理目标("空天姬拍目标", 空天姬拍目标));  
    设置标量("空天姬大鱼目标1", 处理目标("空天姬大鱼目标1", 空天姬大鱼目标1));  
    设置标量("空天姬大鱼目标2", 处理目标("空天姬大鱼目标2", 空天姬大鱼目标2));  
    设置标量("空天姬大鱼目标3", 处理目标("空天姬大鱼目标3", 空天姬大鱼目标3));  
    设置标量("空天姬专一目标", 处理目标("空天姬专一目标", 空天姬专一目标));  
    设置标量("空天姬目标", 处理目标("空天姬目标", 空天姬目标));  
  
    设置标量("空天姬大鱼鱼篓1", 处理目标("空天姬大鱼鱼篓1", 空天姬大鱼鱼篓1));  
    设置标量("空天姬大鱼鱼篓2", 处理目标("空天姬大鱼鱼篓2", 空天姬大鱼鱼篓2));  
    设置标量("空天姬大鱼鱼篓3", 处理目标("空天姬大鱼鱼篓3", 空天姬大鱼鱼篓3));  
  
    if (!string.IsNullOrEmpty(空天姬计数目标1)) {  
      处理目标表格();  
    }  
  
    设置标量("空天姬参数检查", 错误信息.ToString());  
  
    if (!string.IsNullOrEmpty(空天姬目标)) {  
      处理手法();  
    }  
  
    // 处理撒饵钓竿的时间计算  
    string 处理撒饵竿时(string 撒饵, string 非撒饵) {  
      // 尝试将"撒饵"参数解析为double数值  
      if (double.TryParse(撒饵, out double 撒饵转换)) {  
        double d;  
  
        // 检查非撒饵参数是否有有效值(能解析且不为0)  
        if (double.TryParse(非撒饵, out double 非撒饵时间) && 非撒饵时间 != 0) {  
          // 当非撒饵有有效值时,直接使用撒饵转换值  
          d = 撒饵转换;  
        } else {  
          // 当非撒饵无效时,将撒饵值乘以0.6(60%)并四舍五入保留1位小数  
          d = Math.Round(撒饵转换 * 0.6, 1);  
        }  
  
        // 最终值加上延迟时间(全局变量)  
        d += 延迟时间;  
  
        // 返回计算结果的字符串表示  
        return d.ToString();  
      }  
  
      // 解析失败时返回空字符串  
      return "";  
    }  
  
    // 处理非撒饵钓竿的时间计算  
    string 处理非撒饵竿时(string 非撒饵, string 撒饵) {  
      // 尝试将"撒饵"参数解析为double数值(注意参数顺序)  
      if (double.TryParse(撒饵, out double 撒饵时间)) {  
        double d;  
  
        // 检查非撒饵参数是否有有效值(能解析且不为0)  
        if (double.TryParse(非撒饵, out double 非撒饵时间) && 非撒饵时间 != 0) {  
          // 当非撒饵有效时,直接使用非撒饵时间值  
          d = 非撒饵时间;  
        } else {  
          // 当非撒饵无效时,回退使用撒饵时间值  
          d = 撒饵时间;  
        }  
  
        // 最终值加上延迟时间(全局变量)  
        d += 延迟时间;  
  
        // 返回计算结果的字符串表示  
        return d.ToString();  
      }  
  
      // 解析失败时返回空字符串  
      return "";  
    }  
  
    string 处理竿型(string h) {  
      if (string.IsNullOrEmpty(h)) {  
        return "";  
      }  
  
      // 处理“全部”或“all”的情况  
      // 等效于 !+!!+!!!  
      // 表示目标竿是任何竿轻竿、中竿和鱼王竿  
      if (h == "全部" || h.Equals("all", StringComparison.OrdinalIgnoreCase)) {  
        return "123";  
      }  
  
      // 下面这部分用来把叹号处理成数字  
      // 例如 !+!! → 12  
      string[] _h = h.Split('+');  
  
      // 检查每个部分是否仅包含'!'或'!'  
      bool 是否有效 = _h.All(c => c.All(ch => ch == '!' || ch == '!'));  
  
      if (是否有效) {  
        // 将每个部分的长度拼接为字符串  
        return string.Concat(_h.Select(c => c.Length.ToString()));  
      }  
  
      return "";  
    }  
// 处理提钩类型  
    string 处理技巧提钩(string h) {  
      return h switch {  
        "精准" => "1",  
        "强力" => "2",  
        "三重" or "三提" => "3",  
        "双重" or "双提" => "4",  
        "华丽" or "宇宙" or "星宇" => "5",  
        _ => "",  // 未匹配任何规则  
      };  
    }  
  
  
    // 目标表的结构  
    // 指定数量|ID|现有数量  
  
    void 处理目标表格() {  
      VariableTable 已有表格 = GetTableVariable(false, "空天姬目标");  
  
      DataTable 表格 = new();  
      表格.Columns.AddRange(new[] {  
        new DataColumn("指定数量", typeof(string)),  
        new DataColumn("鱼名", typeof(string)),  
        new DataColumn("现有数量", typeof(string)),  
      });  
  
      表格.Rows.Add(空天姬目标计数1,  
                    处理目标("空天姬计数目标1", 空天姬计数目标1));  
      表格.Rows.Add(空天姬目标计数2,  
                    处理目标("空天姬计数目标2", 空天姬计数目标2));  
      表格.Rows.Add(空天姬目标计数3,  
                    处理目标("空天姬计数目标3", 空天姬计数目标3));  
  
      VariableTable 变量表格 = 转换表格(表格);  
  
      if (!表格内容一致(已有表格, 变量表格)) {  
        foreach (DataRow row in 表格.Rows) row[2] = "0";  
        VariableTable 处理后表格 = 转换表格(表格);  
        SetTableVariable(false, "空天姬目标", 处理后表格);  
      }  
    }  
  
    VariableTable 转换表格(DataTable 表格) {  
      return new VariableTable {  
        Rows =  
            表格.Rows.Cast<DataRow>()  
                .Select(row => new VariableTable.VariableTableRow {  
                  Values = row.ItemArray  
                               .Select(item => (Variable) new VariableScalar {  
                                 Value = item.ToString()  
                               })  // 显式类型转换  
                               .ToList(),  
                })  
                .ToList(),  
      };  
    }  
  
    bool 表格内容一致(VariableTable 已有表格, VariableTable 新表格) {  
      // 空表检查  
      if (已有表格?.Rows?.Any() != true)  
        return false;  
  
      // 双条件合并  
      return 已有表格.Rows.Count == 新表格.Rows.Count &&  
             已有表格.Rows  
                 .Zip(新表格.Rows,  
                      (r1, r2) =>  
                          r1.Values[0].ToString() == r2.Values[0].ToString() &&  
                          r1.Values[1].ToString() == r2.Values[1].ToString())  
                 .All(x => x);  
    }  
  
    string 处理目标(string 参数a, string 参数b) {  
        // 参数a 是捕获组名,参数b 是值  
        // 参数a是用来构筑报错信息的  
      if (string.IsNullOrEmpty(参数b))  
        return "";  
  
      // 如果是鱼篓标识符,跳过  
      if (参数b == "《" || 参数b == "<") {  
        return "《";  
      }  
  
      // 定义关键词数组  
      string[] 手法词组 = {  
        "不撒饵", "收藏", "攒鱼计", "套娃",   "知识", "引诱", "重随",  
        "鱼眼",   "鱼影", "钓组",   "不收集", "多提", "回收",  
      };  
  
          
    Regex 正则提取 = new(@"^【?[??]?([^】]+)】?");  
    Regex 正则鱼名否定符 = new(@"^【?[??][^??]");  
  
      var 匹配 = 正则提取.Match(参数b);  
      var 目标 = 匹配.Success ? 匹配.Groups[1].Value : 参数b; // 提取鱼名部分  
// 如果提取出的鱼名包含任一修饰词,视为没有提供用来「钓到后停止」的目标参数,跳过  
      if (手法词组.Any(k => 目标.Contains(k))) {  
        return 目标;  
      }  
// 处理占位或匹配任何鱼的情况  
      if (目标.Equals("任何", StringComparison.OrdinalIgnoreCase) ||  
          目标.Equals("any", StringComparison.OrdinalIgnoreCase)) {  
        return (正则鱼名否定符.Match(参数b).Success ? "?" : "") + "|any|";  
      } else if (目标.Equals("拍", StringComparison.OrdinalIgnoreCase) ||  
                 目标.Equals("占位", StringComparison.OrdinalIgnoreCase))  
        return "?|any|";  
// 分割参数  
      string[] 部分 = 目标.Split('、');  
      List<string> 结果列表 = new();  
// 逐一检查参数并转换为ID  
      foreach (string 部分值 in 部分) {  
        if (int.TryParse(部分值, out int 数字)) {  
          if (空天姬钓饵ID.Values.Any(=> .ToString() == 数字.ToString()) ||  
              空天姬非水产品ID.Values.Any(=> .ToString() ==  
                                                数字.ToString())) {  
            结果列表.Add(数字.ToString());  
          } else {  
            错误信息.AppendLine(获取翻译("鱼名错误提示1")  
                                    .Replace("{参数a}", 参数a)  
                                    .Replace("{参数b}", 参数b)  
                                    .Replace("{数字}", 数字.ToString()));  
            return "";  
          }  
        } else {  
          int 索引 = 空天姬钓饵名.IndexOf(部分值);  
          // RealPlugin.plug.InvokeNamedCallback("command",  $"/e  
          // {单语言空间.ToString()}");  
          if (索引 > 0) {  
            if (索引 > 单语言空间 && 索引 < 单语言空间乘二) {  
              索引 -= 单语言空间;  
            } else if (索引 > 单语言空间乘二) {  
              索引 -= 单语言空间乘二;  
            }  
  
            Variable  = 空天姬钓饵ID.Peek(索引);  
            结果列表.Add(.ToString());  
          } else {  
            索引 = 空天姬非水产品名.IndexOf(部分值);  
            if (索引 > 0) {  
              if (索引 > 非水产品空间 && 索引 < 非水产品空间乘二) {  
                索引 -= 非水产品空间;  
              } else if (索引 > 非水产品空间乘二) {  
                索引 -= 非水产品空间乘二;  
              }  
  
              Variable  = 空天姬非水产品ID.Peek(索引);  
              结果列表.Add(.ToString());  
            } else {  
              错误信息.AppendLine(获取翻译("鱼名错误提示2")  
                                      .Replace("{参数a}", 参数a)  
                                      .Replace("{参数b}", 参数b)  
                                      .Replace("{部分值}", 部分值));  
              return "";  
            }  
          }  
        }  
      }  
// 添加否定符  
      return (正则鱼名否定符.Match(参数b).Success ? "?" : "") +  
             $"|{string.Join("|", 结果列表)}|";  
    }  
// 如包含手法修饰词,设置成变量  
    void 处理手法() {  
      foreach (var 映射 in 关键字映射) {  
        if (空天姬目标.Contains(映射.Key)) {  
          设置标量(映射.Value, "1");  
        }  
      }  
    }  
  
    void 设置标量(string n, string v) {  
      if (string.IsNullOrEmpty(v)) {  
        return;  
      } else {  
        SetScalarVariable(false, n, v);  
      }  
    }  
  }  
}  

抛竿前动作的依赖

按触发器动作顺序

匹配游动饵目标

  • 描述:此布尔值不代表应使用熟练妙招。
bool 匹配游动饵目标()  
{  
    return 是否满足熟练妙招条件() && (  
        是否匹配当前阶段鱼篓() ||  
        是否匹配拍水鱼篓() ||  
        是否需要预备远阶段游动饵()  
    );  
}  
  
private bool 是否满足熟练妙招条件()  
{  
    return 熟练妙招亮起 &&  
           游动饵数量 < 3; // 防溢出  
}  
  
private bool 是否匹配当前阶段鱼篓()  
{  
    return 渔获匹配("鱼篓", 当前手法阶段); // 符合当前阶段的鱼篓参数时  
}  
  
private bool 是否匹配拍水鱼篓()  
{  
    return 当前钓法阶段 == 1 &&  
           是否存在预设参数(鱼篓1) &&  
           渔获匹配(拍目标); // 符合拍水部分的鱼篓参数时  
}  
  
private bool 是否需要预备远阶段游动饵()  
{  
    return !是否存在预设参数("鱼篓", 当前手法阶段 + 1) &&  
           (是否处于饵鱼模式() || 计数模式类型 == 2) &&  
           (!是否存在预设参数("目标", 当前钓法阶段) || 渔获匹配("目标", 当前钓法阶段)) &&  
           (仅自动预备时鱼篓(当前手法阶段) ||  
            (!是否存在预设参数("鱼篓", 当前手法阶段) &&  
             !是否存在预设参数("竿型", 当前钓法阶段 + 2) &&  
             是否存在预设参数("竿型", 当前钓法阶段 + 1))); // 这段是为了在预备时,尽可能存入最远阶段的游动饵  
}  

最终游动饵数量

int 最终游动饵数量 = 游动饵数量 + (匹配游动饵目标() ? 1 : 0);  

匹配以小钓大目标

  • 描述:此布尔值不代表应使用以小钓大。
    bool 匹配以小钓大目标()  
    {  
        return 是否可以以小钓大() &&  
               !匹配游动饵目标() && // 存游动饵就不能以小钓大了  
               是否匹配远阶段目标();  
    }  
    
    private bool 是否可以以小钓大()  
    {  
        return 以小钓大亮起 || 以小钓大II亮起; // 以小钓大II未在冷却就视为亮起  
    }  
    
    private bool 是否匹配远阶段目标()  
    {  
        return 是否存在预设参数("竿型", 当前钓法阶段 + 1) && // 检查是否有远1阶段的目标竿型  
               渔获匹配("目标", 当前钓法阶段);  
    }  

需要暂存游动饵

  • 描述:此布尔值若为真,则表示需要使用【熟练妙招】,并且在监听到使用了【熟练妙招】后,重新判断一次需要用什么技能。暂存游动饵是为了延续以小钓大,使得能触及更远的钓法阶段。
    bool 需要暂存游动饵()  
    {  
        return 是否满足暂存基本条件() &&  
               是否满足阶段或修饰词条件() &&  
               是否满足状态时间条件() &&  
               是否允许使用熟练渔技();  
    }  
    
    private bool 是否满足暂存基本条件()  
    {  
        return 是否存在预设参数("钓饵") &&  
               匹配以小钓大目标() &&  
               游动饵数量 < 3 &&  
               熟练妙招亮起 &&  
               !是否处于饵鱼模式() &&  
               !是否存在手法修饰词("鱼篓") &&  
               !是否处于预拍水模式() &&  
               是否存在预设参数("竿型", 2);  
    }  
    
    private bool 是否满足阶段或修饰词条件()  
    {  
        return 是否存在手法修饰词("套娃") ||  
               (是否存在手法修饰词("收藏品") &&  
                是否存在预设参数("竿型", 当前钓法阶段 + 1) &&  
                !以小钓大II亮起) ||  
               (是否存在预设参数("竿型", 当前钓法阶段 + 2) &&  
                !以小钓大II亮起) ||  
               是否存在预设参数("竿型", 当前钓法阶段 + 3);  
    }  
    
    private bool 是否满足状态时间条件()  
    {  
        return 状态剩余时间("熟练渔技") > 2 && // 秒 如果不存在状态,这个判断需要视为真  
               状态剩余时间("耐心II") > 2; // 秒 如果不存在状态,这个判断需要视为真  
               // 这组条件可以去掉,需要大于 2 秒的原因是空天姬在重新判断使用技能时有延迟,如果上述Buff过期了暂存游动饵就起不到延续钓法阶段的作用了  
    }  
    
    private bool 是否允许使用熟练渔技()  
    {  
        return !熟练渔技亮起 ||  
               是否存在手法修饰词("收藏品");  
    }  

可用鱼计

  • 类型:整数
  • 描述:下面对鱼计的计算和判断都将使用这个变量。因为技能【大鱼的知识】需要用到2层鱼计,因此需要提前算出可用的鱼计层数。【大鱼的知识】极其不常用,这部分未经过更多优化,可能需要在适配宇宙探索时优化,部分高难任务需要用到【大鱼的知识】。
    void 计算可用鱼计()  
    {  
        // 当存在知识修饰词且未获得大鱼的知识时,扣除2层  
        int 扣除值 = 是否需要扣除鱼计() ? 2 : 0;  
    
        // 计算结果不低于0  
        可用鱼计 = Math.Max(当前鱼计层数 - 扣除值, 0);  
    }  
    
    private bool 是否需要扣除鱼计()  
    {  
        return 是否存在手法修饰词("收藏品") && !是否存在状态("大鱼的知识");  
    }  

可使用恩宠

  • 类型:布尔值
  • 描述:目前空天姬只会在自由态推送完技能列表后使用1次恩宠,而不是算出可用的技能后根据需要的恩宠见缝插针地补充。这个问题在需要一下子用大量采集力时才凸显,一般的鱼王场景下不明显。海钓部分的技能逻辑是单独维护的,虽然也有恩宠少用的问题,但不常见。
bool 可使用恩宠()  
{  
    return 是否满足恩宠基本条件() &&  
           是否满足模式或鱼计条件() &&  
           是否满足饵鱼模式限制();  
}  
  
private bool 是否满足恩宠基本条件()  
{  
    return 沙利亚克的恩宠亮起 &&  
           (当前采集力 + (强心剂可用 ? 强心剂回复值 : 0) <= 最大采集力) && // 防采集力溢出  
           !是否存在手法修饰词("攒鱼计") && // 攒鱼计时不能消耗鱼计  
           !是否存在手法修饰词("鱼篓") && // 此修饰词在预设解析时判断并添加,不写在表达式中,见下文  
           !是否处于预拍水模式(); // 拍水时没必要使用恩宠  
}  
  
private bool 是否满足模式或鱼计条件()  
{  
    return !是否存在预设参数("竿型2") || // 只需要平钓时  
           是否处于鱼眼模式() || // 鱼眼的持续时间短导致消耗鱼计的熟练渔技无用武之地。  
           !是否处于饵鱼模式() || // 不允许在预备游动饵时使用恩宠  
           是否存在手法修饰词("收藏品");  
}  
  
private bool 是否满足饵鱼模式限制()  
{  
    return !是否处于饵鱼模式() || 可用鱼计 > 9; // 不允许在预备游动饵时使用恩宠 除非鱼计即将溢出  
}  

手法鱼篓

// 在预设解析时判断  
// 在空天姬钓法表达式中,鱼篓参数只有处在最远阶段时,才在窗口期内有效,否则只作为窗口期外的预备游动饵目的而存在。  
// 如果存在手法修饰词鱼篓,则意味着当前钓法应保证全程都能钓到匹配游动饵目标的鱼,确保能钓到并将最远阶段的目标鱼存为游动饵  
void 设置手法鱼篓()  
{  
    if (是否满足鱼篓条件())  
    {  
        手法修饰词列表.Add("鱼篓");  
    }  
}  
  
private bool 是否满足鱼篓条件()  
{  
    return Math.Max(  
               转换为存在标志(是否存在预设参数("鱼篓", 1)) * 1,  
               转换为存在标志(是否存在预设参数("竿型", 2)) * 1,  
               转换为存在标志(是否存在预设参数("竿型", 3)) * 2,  
               转换为存在标志(是否存在预设参数("竿型", 4)) * 3  
           ) ==  
           Math.Max(  
               转换为存在标志(是否存在预设参数("竿型", 1)) * 1,  
               转换为存在标志(是否存在预设参数("竿型", 2)) * 2,  
               转换为存在标志(是否存在预设参数("竿型", 3)) * 3,  
               转换为存在标志(是否存在预设参数("竿型", 4)) * 4  
           ) &&  
           玩家等级 >= 91;  
}  
  
int 转换为存在标志(bool 布尔值)  
{  
    return 布尔值 ? 1 : 0;  
}  

可用采集力

将所有可用的采集力都算入

int 可用采集力 =  
    当前采集力 +  
    ((强心剂可用 || 强心剂即将冷却完毕) ? 强心剂回复值 : 0) +  
    (可使用恩宠() ? 150 : 0) -  
    (  
        (  
            (!是否存在手法修饰词("鱼篓") && 是否处于饵鱼模式()) || // 鱼篓修饰词手法需要的采集力已在 额外所需采集力 计算过一次,因此防止和饵鱼模式重复计算  
            需要暂存游动饵()  
        ) ? 100 : 0 // 如果需要使用熟练妙招,单独摘除熟练妙招所需的采集力  
    );  

模式所需采集力

// 基本模式技能(大鱼猎手、耐心II)所需的采集力。  
// 用来判断技能优先级,在预设解析时赋值。  
int 模式所需采集力 =   
    钓法基本模式 == 1 // 1 = 平钓 | 2 = 大鱼 | 3 = 耐心  
    ? (   
        是否存在手法修饰词("收藏品")   
        ? ( 是否处于海钓模式() ? 200 : 400 )   
        : 0   
    )   
    : (   
        钓法基本模式 == 2  
        ? ( 是否处于海钓模式() ? 200 : 400 )   
        : 560  
    );  

额外所需采集力

// 计算一轮有效竿最多所需的采集力。  
// 用来判断技能优先级,在预设解析时赋值。  
int 额外所需采集力 = 模式所需采集力 +   
    (是否存在预设参数("拍目标")   
    ? 200  
    : 0) +   
    (是否存在预设参数("专一目标")  
    ? 350  
    : 0) +   
    ((是否存在手法修饰词("重随") || 是否存在手法修饰词("鱼影"))  
    ? 60  
    : 0) +  
    (是否存在手法修饰词("鱼篓")  
    ? 100  
    : 0) +   
    (是否存在手法修饰词("多提")  
    ? (多提手法类型 == 3 ? 684 : 384) // 得出当前钓法一次多提所需的最大采集力  
    : 0);  

额外所需采集力低优先

计算「不那么重要」的技能所需的采集力。

int 额外所需采集力低优先 = (是否存在预设参数("拍目标") ? 200 : 0) +   
    (是否存在手法修饰词("重随") && 是否存在手法修饰词("鱼影") ? 60 : 0) +   
    (是否存在手法修饰词("鱼篓") ? 100 : 0);  

多提手法类型

用来计算多提所需的采集力,得出当前钓法一次多提所需的最大采集力。

// 1 = 精准提钩  
// 2 = 强力提钩  
// 3 = 三重提钩  
// 4 = 双重提钩  
// 5 = 宇宙提钩(宇宙探索中捕鱼人在某些高等级任务,鱼咬饵时可使用一个任务指令)  
int 多提手法类型 =   
    (  
        获取参数值("技巧提钩1") +   
        获取参数值("技巧提钩2") +  
        获取参数值("技巧提钩3") +  
        获取参数值("技巧提钩4") +  
        获取参数值("技巧提钩5") +  
        获取参数值("专一多提")  
    ).Contains("3") ? 3 : 4;  

技能使用顺序

熟练渔技

bool 熟练渔技()  
{  
    return 是否满足熟练渔技基本条件() &&  
           是否满足模式限制条件() &&  
           (是否满足高利用率条件() || 是否满足鱼篓预备条件());  
}  
  
private bool 是否满足熟练渔技基本条件()  
{  
    return 熟练渔技亮起 && // 图标周围有高亮虚线的状态就视为亮起   
           !是否存在状态("大鱼猎手") &&  
           !是否存在状态("不受以小钓大发动条件限制") && // 不能持有熟练渔技的buff  
           !是否存在状态("提钩成功率降低") && // 不能持有耐心Buff,似乎2种耐心有不同的ID  
           !是否存在手法修饰词("收藏品") && // 收藏品模式时不能使用,因为要确保收藏品都是大尺寸  
           !是否存在手法修饰词("攒鱼计") && // 攒鱼计时不能消耗鱼计  
           !是否处于预拍水模式() && // 预拍水时不需要熟练渔技  
           !是否处于鱼眼模式() && // 不能在鱼眼模式时使用,鱼眼持续时间短,熟练渔技利用率低  
           !是否处于饵鱼模式(); // 不能在饵鱼模式时使用熟练渔技消耗鱼计,因为在窗口期内时使用的话利用率更高  
}  
  
private bool 是否满足模式限制条件()  
{  
    return 是否存在预设参数("竿型2") && // 下面是提升技能利用率的判断 总体思路是在保证可及所需的钓法阶段的前提下,尽量提升利用率(更晚使用熟练渔技)  
           (!以小钓大II亮起 || 是否存在手法修饰词("套娃") ||  
            (是否存在预设参数($"竿型{钓法阶段 + 2}") && !当前是游动饵 &&  
             !以小钓大亮起) ||  
            (当前是游动饵 &&  
             是否存在预设参数($"竿型{游动饵的钓法阶段 + 2}") &&  
             !以小钓大亮起)) &&  
           !是否存在手法修饰词("鱼篓");  
}  
  
private bool 是否满足高利用率条件()  
{  
    return 最终游动饵数量 < 2 ||  
           是否存在预设参数("鱼篓3") ||  
           是否存在预设参数("鱼篓4");  
}  
  
private bool 是否满足鱼篓预备条件()  
{  
    return 是否满足高利用率条件() &&  
           !是否在窗口期内() &&  
           是否存在手法修饰词("鱼篓");  
}  

沙利亚克的恩宠

if (可使用恩宠())  
    使用技能("沙利亚克的恩宠");  

以小钓大

if (匹配以小钓大目标() && // 确保匹配以小钓大目标  
    以小钓大亮起 // 技能可用  
)  
    使用技能("以小钓大");  

以小钓大II

if (以小钓大II亮起 && // 已冷却且图标周围有高亮虚线的状态就视为亮起  
    匹配以小钓大目标() // 确保匹配以小钓大目标  
)  
    使用技能("以小钓大II");  

熟练妙招

if (匹配游动饵目标() || // 匹配游动饵目标  
    需要暂存游动饵() // 需要暂存游动饵  
)  
    使用技能("熟练妙招");  

以小钓大中断

如果要使用以小钓大,则不判断和执行后面的技能了。

耐心II

满足以下条件时使用耐心II。
额外操作:当耐心II未学习时,替换为使用耐心,如果耐心也未学习则跳过。海钓部分会有不同。

bool 使用耐心II()  
{  
    return 是否满足耐心基本条件() &&  
           是否满足鱼计或模式条件() &&  
           是否需要使用耐心() &&  
           是否满足详细参数条件();  
}  
  
private bool 是否满足耐心基本条件()  
{  
    return !是否存在状态("大鱼猎手") &&  
           可用采集力 >= 544 && // 560 - ( 自然回复量 * 2 ) 允许等待2跳自然回复,这个感觉可以统一优化,重要的抛竿前技能的采集力条件都应该允许等待2跳  
           !是否存在状态("提钩成功率降低"); // 不能持有耐心系状态效果  
}  
  
private bool 是否满足鱼计或模式条件()  
{  
    return 是否满足攒鱼计条件() ||  
           是否满足一般耐心条件();  
}  
  
private bool 是否满足攒鱼计条件()  
{  
    return 可用鱼计 < 7 &&  
           (是否存在手法修饰词("攒鱼计") ||  
            (是否处于预拍水模式() &&  
             是否处于预拍水的攒鱼计模式())); // 进入预拍水的自动预备时,会判断是否符合攒鱼计的条件,判断见下文。  
           // 也许可以优化,和单纯的攒鱼计使用同一个布尔值来判断。  
           // 攒鱼计时鱼计在7层以下时才允许用耐心来攒鱼计  
}  
  
private bool 是否满足一般耐心条件()  
{  
    return (是否满足鱼篓或饵鱼模式() ||  
            是否存在手法修饰词("收藏品")) &&  
           !是否处于预拍水模式();  
}  
  
private bool 是否满足鱼篓或饵鱼模式()  
{  
    return (!是否存在状态("不受以小钓大发动条件限制") &&  
            (是否存在手法修饰词("鱼篓") && !是否在窗口期内() ||  
             是否处于饵鱼模式() ||  
             !熟练渔技亮起)); // 渔技可用时不使用耐心  
}  
  
private bool 是否需要使用耐心()  
{  
    return 钓法基本模式 == 3 || // 耐心模式  
           是否存在手法修饰词("攒鱼计") ||  
           (是否处于预拍水模式() &&  
            是否处于预拍水的攒鱼计模式()) ||  
           是否处于饵鱼模式();  
}  
  
private bool 是否满足详细参数条件()  
{  
    return 是否存在手法修饰词("攒鱼计") ||  
           是否满足饵鱼模式详细条件() ||  
           是否满足鱼篓手法条件() ||  
           是否满足一般以小钓大条件() ||  
           是否处于预拍水攒鱼计() ||  
           是否存在手法修饰词("收藏品");  
}  
  
private bool 是否满足饵鱼模式详细条件()  
{  
    return 是否处于饵鱼模式() &&  
           (是否存在预设参数("竿型3") ||  
            (最终游动饵数量 < 2 &&  
             !获取参数值("竿型1").Contains("3"))) && // 针对红龙的场景,钓法阶段1的目标竿型不能包括鱼王竿  
           (玩家等级 > 90 ||  
            是否存在预设参数("竿型3")); // 有阶段3的目标竿才需要开耐心II  
}  
  
private bool 是否满足鱼篓手法条件()  
{  
    return 是否存在手法修饰词("鱼篓") &&  
           钓法基本模式 == 3 &&  
           !是否处于饵鱼模式() &&  
           (最终游动饵数量 < 1 ||  
            是否存在预设参数("鱼篓3") ||  
            是否存在预设参数("鱼篓4")) &&  
           !是否处于预拍水模式();  
}  
  
private bool 是否满足一般以小钓大条件()  
{  
    return 是否存在预设参数("竿型2") &&  
           (是否存在手法修饰词("套娃") ||  
            (是否存在预设参数("竿型3") &&  
             !当前是游动饵) ||  
            (当前是游动饵 &&  
             (是否存在预设参数($"竿型{游动饵的钓法阶段 + 2}") ||  
              (是否存在预设参数($"竿型{游动饵的钓法阶段 + 1}") &&  
               是否存在手法修饰词("收藏品") &&  
               !是否存在手法修饰词("不收集")))) ||  
            !以小钓大II亮起) &&  
           !是否处于饵鱼模式() &&  
           !是否存在手法修饰词("鱼篓") &&  
           !是否处于预拍水模式();  
}  
  
private bool 是否处于预拍水攒鱼计()  
{  
    return 是否处于预拍水模式() &&  
           是否处于预拍水的攒鱼计模式();  
}  

处于预拍水的攒鱼计模式

bool 是否处于预拍水的攒鱼计模式()  
{  
    return 距离窗口期的时间() > 180 && // 单位是秒,距离窗口期(距离满足ET和天气条件的时间段的开始时刻)要3分钟以上 此处需要实现一个新方法计算出距离窗口期的时间  
           !预拍水攒鱼计屏蔽列表.Contains(获取参数值("目标")) && // 针对某几条窗口期短或手法有特殊要求的鱼屏蔽这个自动攒鱼计 现在为止的屏蔽列表(ID|鱼名,判断时使用的是ID):|33242|镜中蝶|41410|餐叉尾|17591|云海蝴蝶螺|  
           鱼计 < 9;  
}  

匹配拍击水面目标

布尔值,在判断其他技能时用到。

bool 匹配拍击水面目标()  
{  
    return 是否满足拍击水面条件() &&  
           是否满足预拍水或鱼计条件();  
}  
  
private bool 是否满足拍击水面条件()  
{  
    return 拍击水面亮起 && // 图标周围有高亮虚线的状态就视为亮起  
           可用采集力 >= 额外所需采集力 &&  
           渔获匹配("拍目标");  
}  
  
private bool 是否满足预拍水或鱼计条件()  
{  
    return !是否处于预拍水模式() ||  
           鱼计 > 8 || // 如果处于预拍水的攒鱼计模式,9层鱼计再拍水  
           !是否处于预拍水的攒鱼计模式();  
}  

大鱼猎手

bool 使用大鱼猎手()  
{  
    return 是否满足大鱼猎手基本条件() &&  
           (是否满足攒鱼计场景() ||  
            是否需要攒游动饵() ||  
            是否满足饵鱼模式场景() ||  
            是否满足一般场景() ||  
            是否满足空岛模式场景());  
}  
  
private bool 是否满足大鱼猎手基本条件()  
{  
    return !是否存在状态("大鱼猎手") && // 不能重复使用  
           !是否存在状态("不受以小钓大发动条件限制") && // 有渔技Buff时不需要使用  
           !是否存在状态("提钩成功率降低") && // 有耐心Buff时不需要使用  
           可用采集力 >= 184 && // 允许等待2跳自然回复采集力,应总体优化  
           玩家等级 >= 81;  
}  
  
private bool 是否满足攒鱼计场景()  
{  
    return 可用鱼计 >= 7 &&  
           (是否存在手法修饰词("攒鱼计") ||  
            (是否处于预拍水模式() &&  
             是否处于预拍水的攒鱼计模式())) &&  
           (是否满足非预拍水鱼计条件() ||  
            可用鱼计 < 9) &&  
           !是否存在手法修饰词("鱼篓");  
}  
  
private bool 是否满足非预拍水鱼计条件()  
{  
    return !是否处于预拍水模式() &&  
           可用鱼计 < 10;  
}  
  
private bool 是否需要攒游动饵()  
{  
    return 是否存在手法修饰词("鱼篓") &&  
           !是否处于饵鱼模式() &&  
           !是否存在预设参数("鱼篓3") &&  
           !是否存在预设参数("鱼篓4") &&  
           !是否处于预拍水模式() &&  
           最终游动饵数量 < 3 &&  
           (最终游动饵数量 > 1 ||  
            (钓法基本模式 != 3 &&  
             (可用鱼计 < 5 ||  
              是否在窗口期内())));  
}  
  
private bool 是否满足饵鱼模式场景()  
{  
    return 是否处于饵鱼模式() &&  
           !是否存在预设参数("竿型3") &&  
           (最终游动饵数量 > 2 ||  
            玩家等级 < 91 ||  
            获取参数值("竿型1").Contains("3")); // 针对红龙场景  
}  
  
private bool 是否满足一般场景()  
{  
    return !是否处于饵鱼模式() &&  
           !是否处于预拍水模式() &&  
           !是否存在手法修饰词("鱼篓") &&  
           (是否满足大鱼模式收藏品() ||  
            是否满足低鱼计大鱼模式());  
}  
  
private bool 是否满足大鱼模式收藏品()  
{  
    return 钓法基本模式 == 2 && // 大鱼模式  
           是否存在手法修饰词("收藏品") &&  
           (!当前是游动饵 ||  
            (是否存在预设参数($"竿型{游动饵阶段 + 1}") &&  
             当前是游动饵 &&  
             !是否存在手法修饰词("不收集")));  
}  
  
private bool 是否满足低鱼计大鱼模式()  
{  
    return 可用鱼计 < 5 &&  
           钓法基本模式 == 2 &&  
           (!当前是游动饵 ||  
            是否存在预设参数($"竿型{游动饵阶段 + 1}") &&  
            是否存在手法修饰词("收藏品") &&  
            !是否存在手法修饰词("不收集") ||  
            是否存在预设参数($"竿型{游动饵阶段 + 2}")) &&  
           (!以小钓大II亮起 ||  
            是否存在手法修饰词("套娃"));  
}  
  
private bool 是否满足空岛模式场景()  
{  
    return 可用采集力 >= (892 + (匹配拍击水面目标() ? 200 : 0) + (是否存在手法修饰词("引诱") ? 28 : 0)) &&  
           是否存在手法修饰词("回收"); // 针对空岛模式场景才使用的修饰词,钓三提七条的鱼时可以使用大鱼猎手回收采集力  
}  

撒饵

bool 使用撒饵()  
{  
    return 是否满足撒饵条件() || 是否强制撒饵();  
}  
  
private bool 是否满足撒饵条件()  
{  
    return !是否存在状态("撒饵") &&  
           玩家等级 > 4 &&  
           !是否存在手法修饰词("攒鱼计") &&  
           !是否存在手法修饰词("不撒饵") &&  
           !是否处于预拍水模式() &&  
           是否满足撒饵模式条件() &&  
           是否满足窗口期时间条件() &&  
           可用采集力 >= (100 + 额外所需采集力); // 和大鱼猎手那部分的判断类似,目的是确保在这种场景时有足够的采集力使用大鱼猎手  
}  
  
private bool 是否满足撒饵模式条件()  
{  
    return (是否存在手法修饰词("鱼篓") &&  
            !是否处于饵鱼模式() &&  
            (最终游动饵数量 > 1 ||  
             (钓法基本模式 != 3 && 可用鱼计 < 5)) &&  
            !是否存在预设参数("鱼篓3") &&  
            !是否存在预设参数("鱼篓4")) ||  
           (是否处于饵鱼模式() &&  
            (最终游动饵数量 > 2 ||  
             玩家等级 < 91) &&  
            !是否存在预设参数("竿型3")) ||  
           !是否处于饵鱼模式() ||  
           !是否存在手法修饰词("鱼篓");  
}  
  
private bool 是否满足窗口期时间条件()  
{  
    return Math.Min(  
               鱼眼结束时间存在() ? (鱼眼结束时间 - 当前时间戳) : 4200,  
               鱼识模式() ? (控制鱼识结束时间 - 当前时间戳) : 4200,  
               控制幻海流状态() ? ((控制幻海流结束时刻 - 当前时间戳毫秒) / 1000) : 4200,  
               (区域ID == 900 || 区域ID == 1163) ?   
                   (控制海域时刻存在() ? ((控制海域时刻 + 390000) / 1000 - 当前时间戳) : 4200) :   
                   Math.Min(  
                       最大ET结束时间存在() ? (最大ET结束时间 - 当前时间戳) : 4200,  
                       天气转换时间存在() ? (天气转换时间 - 当前时间戳) : 4200  
                   )  
           ) > 3; // 这坨的意思是,在距离各个窗口期:鱼眼、鱼识、幻海流、海域的可抛竿时间段、一般窗口期也就是满足ET和天气条件的结束时间必须大于3秒。这段有必要提取为方法,有别的地方也要用到  
}  
  
private bool 是否强制撒饵()  
{  
    return 强制撒饵 && // 通过一个按钮或者命令使空天姬在下次使用自由态技能时,忽视内部采集力条件判断来使用撒饵  
           玩家等级 > 4; // 判断撒饵是否已学会  
}  

拍击水面

if (匹配拍击水面目标())  
    使用技能("拍击水面");  

大鱼的知识

bool 使用大鱼的知识()  
{  
    return 是否满足大鱼知识基本条件() &&  
           是否满足拍水条件();  
}  
  
private bool 是否满足大鱼知识基本条件()  
{  
    return !是否存在状态("大鱼的知识") &&  
           大鱼的知识亮起 &&  
           是否存在手法修饰词("知识");  
}  
  
private bool 是否满足拍水条件()  
{  
    return !是否存在预设参数("拍目标") ||  
           是否存在状态("拍击水面") ||  
           匹配拍击水面目标(); // 拍水后才允许使用大鱼的知识,这部分没深度考虑过优化提升技能使用率  
}  

专一垂钓

bool 使用专一垂钓()  
{  
    return 是否满足专一垂钓条件() &&  
           可用采集力 >= 计算专一所需采集力();  
}  
  
private bool 是否满足专一垂钓条件()  
{  
    return !是否存在状态("专一垂钓") &&  
           刚刚的鱼不是用专一钓到的 &&  
           当前钓法阶段 == 1 &&  
           玩家等级 >= 79 &&  
           渔获匹配("专一目标") &&  
           !是否处于饵鱼模式() &&  
           !是否处于预拍水模式() &&  
           计数模式类型 != 2;  
}  
  
private int 计算专一所需采集力()  
{  
    return 额外所需采集力 - 额外所需采集力低优先 -   
           (是否存在手法修饰词("多提") ? (多提手法类型 == 3 ? 684 : 384) : 0); // 额外所需采集力、额外所需采集力低优先、多提手法类型 见前文  
}  

抛竿

无条件

使用技能("抛竿");  

抛竿前技能使用

在推完技能列表后,会触发一个循环的触发器。

async Task 使用技能()  
{  
    while (是否满足技能循环条件())  
    {  
        // Action 1: 设置无消耗技能判断  
        // 一个布尔值,配合动作2,目的是如果下一个动作是无消耗技能(是抛竿或以小钓大),且满足使用强心剂的条件,就阻塞技能来使用强心剂,以减少强心剂cd空转。  
        无消耗技能判断 =   
            (技能列表[当前索引] == "抛竿" || 技能列表[当前索引] == "以小钓大") ? 1 : 0;  
  
        // Action 2: 设置强心剂判断(第一次)  
        if (无消耗技能判断 == 1) // 空天姬强心剂判断:布尔值,为真时使用强心剂。  
        {  
            强心剂判断 = 是否满足强心剂使用条件() ? 1 : 0;  
            executed = true;  
        }  
  
        // Action 3 & 4: 使用技能  
        await 执行技能(技能列表[当前索引]);  
        executed = true;  
    }  
}  
  
private bool 是否满足技能循环条件()  
{  
    return (是否处于饵鱼模式() ||  
            是否处于鱼眼模式() ||  
            是否处于预拍水模式() ||  
            计数模式类型 == 2 ||  
            (是否在窗口期内() && // 如果不存在窗口期参数,视为真  
             !换饵中())) &&  
           !暂停中 &&  
           !等待咬饵的状态; // 抛竿后的状态  
}  
  
private bool 是否满足强心剂使用条件()  
{  
    return !强心剂超时() &&  
           (控制强心剂 || 控制强心剂提前I) && // 强心剂使用未超时 且 强心剂已冷却或即将冷却完成(冷却还剩半秒时视为即将冷却)  
           当前GP <= (最大GP - (!是否存在手法修饰词("引诱") ?   
               控制强心剂GP防溢出 + 控制幻海流强心剂修正 :   
               控制强心剂GP - 16));   
           // 上面这个表达式意为:  
           // 1,先判断强心剂冷却  
           // 2,防溢出部分,如果当前gp 低于或等于 最大gp - 强心剂回复量 + n跳的自然回复量(防溢出目的),则可使用强心剂。  
           // 防溢出的逻辑:等待鱼咬饵时会有自然回复量,在防溢出时需要处理这部分。  
           // ·存在修饰词引诱时  
           // 回复量 =   
           // 强心剂回复量 + 每跳的自然回复量 * ( 6 + ( 处在幻海流 ? 4 : 0 ) ) // 处在幻海流时,经常碰不到目标竿,因此gp消耗较少,计算时需要上调自然回复量的tick数  
           // ·不存在修饰词引诱时  
           // 回复量 =   
           // 强心剂回复量 - 每跳的自然回复量 * 2 // 因为在需要用满引诱时,抛竿后就会立刻消耗采集力,因此不需要留出自然回复空间。又因为在空岛模式场景下,有个高效的第一竿手法必须允许在使用高级强心剂时直接溢出一些gp才能完成,所以再减去一些采集力。  
}  

抛竿或以小钓大时

在抛竿或以小钓大时,赋值用来判断的竿时,这个触发器也判断需不需要断竿或重随

async Task 竿时控制和断竿和引诱或重随()  
{  
    // Action 1: 设置最小竿时  
    最小竿时 = 是否存在状态("撒饵") ? 最小区间[当前钓法阶段] : 最小区间非撒饵[当前钓法阶段];  
  
    // Action 2: 设置最大竿时  
    最大竿时 = 是否存在状态("撒饵") ? 最大区间[当前钓法阶段] : 最大区间非撒饵[当前钓法阶段];  
  
    // Action 3: 调整最小竿时(添加延迟时间)  
    if (最小竿时 != 0)  
    {  
        最小竿时 += 配置["延迟时间"];  
    }  
  
    // Action 4: 调整最大竿时(添加延迟时间)  
    if (最大竿时 != 0)  
    {  
        最大竿时 += 配置["延迟时间"];  
    }  
  
    拍最大竿时 = 是否存在状态("撒饵") ? 拍最大区间 : 拍最大区间非撒饵;  
  
    // 重新设置最大竿时  
    // 如果拍水目标竿的最大竿时大于阶段1目标竿的最大竿时,则将断竿/重随用的最大竿时值设为拍水目标竿的最大竿时  
    if (是否需要调整最大竿时())  
    {  
        最大竿时 = 拍最大竿时 + 配置["延迟时间"];  
    }  
  
    // 取消真空期循环方法的动作  
    取消动作("引诱真空期");  
  
    // Action 10: 引诱  
    // 延时1秒后判断使用引诱。  
    // 因为有时会在使用强心剂后立刻抛竿,强心剂有大概1秒以内的弹道生效时间,如果在抛竿后立刻判断引诱,会影响采集力判断。  
    await Task.Delay(1000);  
    if (是否需要使用引诱())  
    {  
        await 使用引诱();  
    }  
  
    await Task.Delay((int)(最大竿时 * 1000 - 1000)); // 减去之前等待的1秒  
  
    // Action: 触发断竿  
    if (是否需要断竿())  
    {  
        使用技能("歇竿");  
    }  
    else if (是否需要重随())  
    {  
        尝试重随();  
    }  
}  
  
private bool 是否需要调整最大竿时()  
{  
    return 钓法阶段 == 1 &&  
           是否存在参数拍目标 &&  
           !是否存在状态拍击水面 &&  
           最大竿时 != 0 &&  
           (拍最大竿时 + 配置["延迟时间"] > 最大竿时 ||  
            (是否处于预拍水模式() &&  
             (!是否处于预拍水的攒鱼计模式() ||  
              鱼计 > 8))); // 预拍水模式时专注于预拍水  
}  
  
private bool 是否需要使用引诱()  
{  
    return 玩家等级 == "100" &&  
           当前钓法阶段 == 1 &&  
           !是否存在状态专一垂钓 &&  
           !是否处于预拍水模式() &&  
           是否存在引诱或鱼影修饰词() &&  
           是否满足采集力或鱼影条件() &&  
           是否满足海钓模式条件();  
}  
  
private bool 是否存在引诱或鱼影修饰词()  
{  
    return 是否存在手法修饰词("引诱") ||  
           是否存在手法修饰词("鱼影");  
}  
  
private bool 是否满足采集力或鱼影条件()  
{  
    return 当前GP >= 36 + 模式所需采集力 ||  
           是否存在手法修饰词("鱼影"); // 如果有鱼影修饰词,开鱼影优先  
}  
  
private bool 是否满足海钓模式条件()  
{  
    return !是否处于海钓模式() ||  
           是否满足非幻海流条件() ||  
           是否满足幻海流条件();  
}  
  
private bool 是否满足非幻海流条件()  
{  
    return !是否处于幻海流() &&  
           是否处于海钓模式() &&  
           当前GP >= 最大GP - 48 && // 接近满gp就允许引诱  
           (是否满足拍水目标条件() ||  
            鱼计 >= 5 || // 通用的触幻条件,攒一些鱼计就开始尝试钓幻光鱼  
            海钓标识类型 == 3); // 成就模式  
}  
  
private bool 是否满足幻海流条件()  
{  
    return 是否处于幻海流() &&  
           是否处于海钓模式() &&  
           (海钓标识类型 == 2 || // 蓝鱼模式  
            (当前GP >= 748 &&  
             (是否存在状态("大鱼猎手") ||  
              是否存在手法修饰词("收藏"))) || // 这里的收藏修饰符是只在海钓中使用的特殊标记用法  
            当前GP >= 最大GP - 16);  
}  
  
private bool 是否满足拍水目标条件()  
{  
    return 是否存在参数拍目标 &&  
           是否存在状态拍击水面;  
}  
  
private bool 是否需要断竿()  
{  
    return !是否存在参数额外竿型[当前钓法阶段] && // 如果存在当前阶段的额外竿型参数,则不允许断竿  
           !是否处于咬饵真空期() && // 引诱后会有数秒的咬饵真空期,鱼在这个时间段不会咬饵,因此不允许断竿。真空期过后的判断和断竿是由另一部分完成的  
           是否满足断竿基本条件() &&  
           是否满足断竿额外条件() &&  
           是否满足预拍水鱼计条件();  
}  
  
private bool 是否满足断竿基本条件()  
{  
    return 等待咬饵 &&  
           最大竿时 > 0 &&  
           !是否处于幻海流绝命竿 &&  
           !是否处于鱼识绝命竿 &&  
           !是否处于鱼眼绝命竿;  
}  
  
private bool 是否满足断竿额外条件()  
{  
    return 当前钓法阶段 > 1 ||  
           引诱成功 ||  
           玩家等级 < 100 ||  
           是否处于预拍水模式() ||  
           计数模式类型 == 2 ||  
           !是否存在手法修饰词("重随");  
}  
  
private bool 是否满足预拍水鱼计条件()  
{  
    return !是否处于预拍水的攒鱼计模式() ||  
           鱼计 > 8;  
}  
  
private bool 是否需要重随()  
{  
    return 等待咬饵 &&  
           最大竿时 > 0;  
}  

等待咬饵

引诱

using System.Threading.Tasks;  
  
async Task 使用引诱(bool 是否需要重随)  
{  
    // 检查是否满足引诱的条件  
    if (!是否可使用引诱()) return;  
  
    // Action 1: 初始化引诱类型  
    if (当前引诱层数 == 0)  
    {  
        空天姬引诱类型 = "";  
    }  
  
    // Action 2: 设置引诱类型为雄心  
    if (是否应使用雄心之饵())  
    {  
        空天姬引诱类型 = "雄心";  
    }  
  
    // Action 3: 设置引诱类型为谦逊  
    if (是否应使用谦逊之饵())  
    {  
        空天姬引诱类型 = "谦逊";  
    }  
  
    // Action 4: 执行引诱技能命令  
    if (!string.IsNullOrEmpty(空天姬引诱类型))  
    {  
        await 执行技能(空天姬引诱类型 + "之饵");  
    }  
  
    // Action 5: 触发下一次引诱  
    if (!string.IsNullOrEmpty(空天姬引诱类型))  
    {  
        await Task.Delay(200);  
        await 使用引诱(是否需要重随);  
    }  
}  
  
// 检查是否满足使用引诱的条件  
private bool 是否可使用引诱()  
{  
    return 是否引诱已准备() && 是否玩家符合条件() && 是否在有效模式() && 是否在窗口期内();  
}  
  
// 条件组1:检查引诱是否准备好  
private bool 是否引诱已准备()  
{  
    return 是否等待咬饵 &&  
           当前引诱层数 < 3 &&  
           !是否处于幻海流绝命竿 &&  
           !是否处于鱼识绝命竿() &&  
           !是否处于鱼眼绝命竿() &&  
           !是否已暂停();  
}  
  
// 条件组2:检查玩家是否符合条件  
private bool 是否玩家符合条件()  
{  
    return 当前等级 == "100" &&  
           !是否持有专一状态() &&  
           (是否拥有有效修饰词() || 是否满足引诱条件());  
}  
  
// 条件组3:检查是否在有效模式  
private bool 是否在有效模式()  
{  
    // 无窗口期参数限制时视为真  
    return 是否在窗口期内() || 是否处于饵鱼模式;  
}  
  
// 条件组4:检查窗口期剩余时间  
private bool 是否在窗口期内()  
{  
    return 窗口期剩余时间秒数 > 1;  
}  
  
// 条件组5:检查是否拥有有效修饰词  
private bool 是否拥有有效修饰词()  
{  
    return (是否存在修饰词("重随") && 是否允许重随 == "1") ||  
           (是否存在修饰词("引诱") && !是否存在修饰词("重随")) ||  
           是否存在修饰词("鱼影");  
}  
  
// 条件组6:检查引诱相关条件  
private bool 是否满足引诱条件()  
{  
    return (!是否鱼影成功() && 是否存在修饰词("鱼影")) ||  
           (!是否引诱成功() && !是否存在修饰词("鱼影") && 是否存在修饰词("引诱")) ||  
           是否存在修饰词("重随");  
}  
  
// 检查是否应使用雄心之饵  
private bool 是否应使用雄心之饵()  
{  
    // 如果参数指定了强力提钩,或目标竿不含轻竿  
    return (当前技巧提钩阶段 == 2 || !获取竿型参数(当前钓法阶段).Contains("1")) &&  
           当前技巧提钩阶段 != 1 &&  
           // 防止预设切换后重复判断,或者在使用引诱时判断是否已有其一效果,例如持有大体型引诱效果,就不能使用谦逊之饵了  
           !是否已设置引诱类型();  
}  
  
// 检查是否应使用谦逊之饵  
private bool 是否应使用谦逊之饵()  
{  
    // 参数指定了精准提钩,或目标竿型只存在轻竿时  
    return (当前技巧提钩阶段 == 1 ||  
            (获取竿型参数(当前钓法阶段).Contains("1") &&  
             !获取竿型参数(当前钓法阶段).Contains("2") &&  
             !获取竿型参数(当前钓法阶段).Contains("3"))) &&  
           当前技巧提钩阶段 != 2 &&  
           !是否已设置引诱类型();  
}  
  
// 辅助方法:获取竿型参数  
private string 获取竿型参数(int 阶段)  
{  
    return 获取参数值($"竿型{阶段}");  
}  

咬饵真空期的处理

当获得任何类型的引诱Buff时触发

async Task 真空期处理()  
{  
    // Action 1: 设置真空期  
    // 指示当前处于咬饵真空期  
    真空期 = "1";  
  
    // Action 2: 初始化重随判断  
    重随判断 = "";  
  
    // Action 3: 初始化真空最大竿时判断  
    真空最大竿时判断 = "";  
  
    // Action 4: 初始化拍最大竿时判断  
    拍最大竿时判断 = "";  
  
    // Action 5: 设置真空最大竿时  
    // 锁定快照,用来计算真空期对竿时的影响  
    if (  
        咬钩时刻 > 200 &&  
        最大竿时 > 0.1  
    )  
    {  
        真空最大竿时 = 最大竿时;  
    }  
  
    // Action 6: 设置真空最大竿时判断  
    // 在游戏中,使用任意引诱会使抛竿结果重新随机,并将最早咬饵时间推迟约5秒(一般而言是至少5秒,视延迟情况到5.5秒,据说实际是4秒,但在国际服实测也是5秒)  
    // 举例来说  
    // 如果鱼A(下简称A)的最大咬饵竿时在10秒  
    // 在第9秒时使用引诱,如果随机到A,则A会在第14秒(9+5)左右咬饵  
    // 如果在超过A的最大咬饵竿时后使用引诱,例如第12秒,如果随机到A,则A会在第17秒(12+5)左右咬饵  
    // 如果在低于A的最大咬饵竿时 - 5 时使用引诱,例如在第3秒(3+5<10),则A会在正常的最大咬饵竿时以内咬饵,但依然会影响最小咬饵竿时。  
    //  
    // 因此如果使用了引诱,必须判断最小咬饵竿时推迟后的时间会不会超过目标竿的最大竿时。如果超过,需要重新设置最大竿时为当前竿时 + 5.5  
    if (  
        咬钩时刻 > 200 &&  
        最大竿时 > 0.1 &&  
        (当前时间戳毫秒 - 咬钩时刻) / 1000 + 5.5 + 配置["延迟时间"] >= 真空最大竿时  
    )  
    {  
        真空最大竿时判断 = true;  
    }  
  
    // Action 7: 重新设置最大竿时  
    if (真空最大竿时判断)  
    {  
        最大竿时 = (当前时间戳毫秒 - 咬钩时刻) / 1000 + 5.5 + 配置["延迟时间"];  
    }  
  
    // Action 8: 设置拍最大竿时判断  
    if (  
        拍最大区间() &&  
        (当前时间戳毫秒 - 咬钩时刻) / 1000 + 5.5 + 配置["延迟时间"] >= (撒饵() ? 拍最大区间 : 拍最大区间非撒饵)  
    )  
    {  
        拍最大竿时判断 = (当前时间戳毫秒 - 咬钩时刻) / 1000 + 5.5 + 配置["延迟时间"];  
    }  
  
    // Action 9: 触发鱼影失败  
    if (  
        !鱼影成功() &&  
        存在手法修饰词("鱼影") &&  
        咬钩时刻 > 200 &&  
        引诱 > 2  
    )  
    {  
        await Task.Delay(2000 + (int)(配置["延迟时间"] * 1000));  
        触发("bb9acc5f-2813-4ad3-87ea-7739dc37b917");  
    }  
  
    // Action 10: 重置真空期  
    await Task.Delay(3500);  
    真空期 = "";  
  
    // Action 11: 初始化真空重随判断  
    await Task.Delay(500);  
    真空重随判断 = "";  
  
    // Action 12: 设置真空重随判断  
    if (  
        (  
            真空最大竿时判断() &&  
            !幻海流绝命竿() &&  
            !鱼识绝命竿() &&  
            咬钩时刻 > 200 &&  
            !手法鱼眼绝命竿() &&  
            (  
                !鱼眼结束时间存在() ||  
                鱼眼结束时间 - 当前时间戳 > 1  
            ) &&  
            (  
                !鱼识模式() ||  
                (  
                    (  
                        !鱼识结束时间存在() ||  
                        鱼识结束时间 - 当前时间戳 > 1  
                    ) &&  
                    鱼识模式()  
                )  
            )  
        ) &&  
        (  
            !存在手法修饰词("重随") ||  
            引诱 >= 3  
        )  
    )  
    {  
        真空重随判断 = "1";  
    }  
  
    // Action 13: 触发真空重随  
    if (真空重随判断())  
    {  
        触发("bb9acc5f-2813-4ad3-87ea-7739dc37b917");  
    }  
  
    // Action 14: 设置重随判断  
    if (  
        !真空重随判断() ||  
        真空最大竿时判断()  
    )  
    {  
        重随判断 = "1";  
    }  
  
    // Action 15: 触发引诱重随  
    if (  
        !真空重随判断() ||  
        真空最大竿时判断()  
    )  
    {  
        触发("8262bba8-8731-46b6-9447-ed9d8d1991b2", "引诱重随");  
    }  
}  
⚠️ **GitHub.com Fallback** ⚠️