#nop vim: set filetype=tt:; /* 本文件属于 PaoTin++ 的一部分。 PaoTin++ © 2020~2023 的所有版权均由担子炮(dzp ) 享有并保留一切法律权利 你可以在遵照 GPLv3 协议的基础之上使用、修改及重新分发本程序。 */ ///=== { ///// speedo(测速仪)模块为各种数据提供测速支持。 ///// ///// 在游戏中,我们常常需要记录和测算数据的变化率或者一段时间的平均值。 ///// 本模块可以用来实现这个目的。短的比如气血、精神、内力的变化率,长的比如 ///// 经验值、潜能、金钱收益等,都可以用它来测算。 // }; #var lib_speedo[META] { {NAME} {测速仪} {DESC} {为各种数据提供测速支持,气血/精神/经验值/存款都可以} {AUTHOR} {担子炮} }; #func {lib_speedo.Init} { #var gSpeedo {}; #return {true}; }; ///=== { // ## speedo.Set <数据名> <数据值> <单调性> <保活时间> // 往测速仪中灌注一个数据(覆盖模式)。 // 单调性决定了数据的变化方向发生翻转时,是累积还是重置之前的统计信息。 // 如果设置为真,则会重置,否则会累积。比如说一个数据一会儿变大一会儿变小, // 在累积模式下,可能一段时间之后,统计出来的结果会是平均变化率很小接近于无。 // 而重置模式下,永远都可以给出最近一段时间单调变化的变化率。 // 保活时间参数用来排除停滞变化的时间不予统计。如果最近连续两次更新时间间隔 // 超过保活时间,则超出部分将会被扣除不参与计算。 // }; #alias {speedo.Set} { #local key {%1}; #local value {@defaultNum{%2;0}}; #local monotone {@default{%3;false}}; #local keepalive {@defaultNum{%4;60}}; #if { @isEmpty{$key} } { #return; }; #format {now} {%T}; #if { "$gSpeedo[$key]" == "" } { #var {gSpeedo[$key][base]} {$value}; #var {gSpeedo[$key][baseTime]} {$now}; #var {gSpeedo[$key][deduction]} {0}; #var {gSpeedo[$key][paused]} {false}; }; #nop 只允许单调递增或者单调递减; #if { "$monotone" == "true" } { #if { ( $value > $gSpeedo[$key][value] && $gSpeedo[$key][value] < $gSpeedo[$key][base] ) || ( $value < $gSpeedo[$key][value] && $gSpeedo[$key][value] > $gSpeedo[$key][base] ) } { #var {gSpeedo[$key][base]} {$gSpeedo[$key][value]}; #var {gSpeedo[$key][baseTime]} {$gSpeedo[$key][update]}; #var {gSpeedo[$key][deduction]} {0}; }; }; #local interval {0}; #math interval {$now - $gSpeedo[$key][update]}; #nop Set 会导致继续统计,但之前暂停时经过的时间将被扣除; #nop 超过 keepalive 的间隔也会被扣除; #if { "$gSpeedo[$key][paused]" == "true" || $interval > $keepalive } { #var {gSpeedo[$key][paused]} {false}; #math {gSpeedo[$key][deduction]} {$gSpeedo[$key][deduction] + $interval - $keepalive}; }; #var {gSpeedo[$key][value]} {$value}; #var {gSpeedo[$key][update]} {$now}; }; ///=== { // ## speedo.Add <数据名> <数据值> <单调性> <保活时间> // 类似于 speedo.Set,但数据值会累加而不是覆盖。其余相同。 // }; #alias {speedo.Add} { #local key {%1}; #local value {@defaultNum{%2;0}}; #local monotone {@default{%3;false}}; #local keepalive {@defaultNum{%4;60}}; #if { @isEmpty{$key} } { xtt.Usage speedo.Add; #return; }; #math value {$value + @speedo.Get{{$key}}}; speedo.Set {$key} {$value} {$monotone} {$keepalive}; }; ///=== { // #@ speedo.Get <数据名> // 获取测速仪中储存的数据值。如果该数据之前尚未被存储过,则返回 0。 // }; #func {speedo.Get} { #local key {%1}; #if { @isEmpty{$key} } { #return {0}; }; #if { "$gSpeedo[$key]" == "" } { #return {0}; }; #return {$gSpeedo[$key][value]}; }; ///=== { // #@ speedo.GetUpdateTime <数据名> // 获得该数据最近一次更新的时间。 // }; #func {speedo.GetUpdateTime} { #local key {%1}; #return {$gSpeedo[$key][update]}; }; ///=== { // #@ speedo.GetSpeed <数据名> [<间隔时间>] // 获得该数据最近一段时间的变化率。如果省略间隔时间则给出每秒变化值。 // }; #func {speedo.GetSpeed} { #local key {%1}; #local interval {%2}; #local speedInfo {@speedo.GetSpeedInfo{{$key};{$interval}}}; #if { "$speedInfo" == "" } { #return {0}; }; #return {$speedInfo[speed]}; }; ///=== { // #@ speedo.GetSpeedInfo <数据名> [<间隔时间>] // 获得该数据最近一段时间的变化率和相关信息。如果省略间隔时间则给出每秒变化值。 // }; #func {speedo.GetSpeedInfo} { #local key {%1}; #local interval {@defaultNum{%2;1}}; #if { @isEmpty{$key} } { #return {}; }; #local data {$gSpeedo[$key]}; #if { "$data" == "" } { #return {}; }; #local delta {0}; #math delta {$data[value] - $data[base]}; #local speed {0}; #math speed { ( $delta * $interval ) / ( $data[update] - $data[baseTime] - $data[deduction] ) }; #return { {begin} {$data[baseTime]} {end} {$data[update]} {delta} {$delta} {speed} {$speed} {deduction} {$data[deduction]} }; }; ///=== { // ## speedo.Pause <数据名> // 暂停计数。暂停之后,直到下次继续,这段期间会在计算中扣除,以获得更精确的 // 统计数据。 // }; #alias {speedo.Pause} { #local key {%1}; #var {gSpeedo[$key][paused]} {true}; }; ///=== { // ## speedo.Resume <数据名> // 继续计数。参见 speedo.Pause // }; #alias {speedo.Resume} { #local key {%1}; #if { "$gSpeedo[$key][paused]" == "true" } { #var {gSpeedo[$key][paused]} {false}; #math {gSpeedo[$key][deduction]} {$gSpeedo[$key][deduction] + $now - $gSpeedo[$key][update]}; #format {now} {%T}; #var {gSpeedo[$key][update]} {$now}; }; }; ///=== { // ## speedo.Reset <数据名> // 复位计数器。 // }; #alias {speedo.Reset} { #local key {%1}; #if { "$gSpeedo[$key]" == "" } { #return; }; #format {now} {%T}; #var {gSpeedo[$key][base]} {0}; #var {gSpeedo[$key][baseTime]} {$now}; #var {gSpeedo[$key][deduction]} {0}; #var {gSpeedo[$key][paused]} {false}; #var {gSpeedo[$key][value]} {0}; #var {gSpeedo[$key][update]} {$now}; }; ///=== { // ## speedo.List <间隔时间> <过滤条件> // 列出测速仪中符合条件的数据。如果省略过滤条件(支持正则表达式),则列出所 // 有的数据。 // 间隔时间用来指定统计区间,默认给出 1 秒的统计值。 // }; #alias {speedo.List} { #local interval {@defaultNum{%1;1}}; #local pattern {@default{%2;{%*}}}; #echo {<128> %-14s %+10s %+10s %+14s %-20s %-20s %+10s} {统计对象} {统计结果} {平均值} {测算周期(秒)} {样本开始时间} {样本截止时间} {发呆时间}; #draw Yellow scroll line 1 1 1 110; #local key {}; #foreach {*gSpeedo[]} {key} { #if { "$key" != "$pattern" } { #continue; }; #local speedInfo {@speedo.GetSpeedInfo{{$key};{$interval}}}; #echo {<168> %-14s %+10s %+10s %+14s %t %t %+10s} {$key} {$speedInfo[delta]} {$speedInfo[speed]} {$interval} {{%Y-%m-%d %H:%M:%S}{$speedInfo[begin]}} {{%Y-%m-%d %H:%M:%S}{$speedInfo[end]}} {$speedInfo[deduction]}; }; };