zhouyi 发表于 2019-5-7 00:28:19

【tintin++】map使用进阶笔记

关于画地图论坛已经有帖子了,就不啰嗦了。
使用一个标准地图,用合适的配置来适应不同的门派和任务。
画地图时,先把不能所有情况都可用的出口关闭掉:
#map at 1983 {#map exitflag gbmdcenter avoid on};#nop 丐帮扬州中央广场地道关闭;
#map at 813 {#map exitflag gbmddgc avoid on};#nop 打谷场地道关闭;
例如:丐帮的地道别派无法走,或者类似押镖任务的时候不能走地道

根据score里的门派信息来触发选择需要开放的出口:
#elseif {"$xkxGPS"=="(condition is null or condition='gb' or condition='dong') and id<>3247 and id<>3248"} {
                #nop 丐帮走路方式;
                #map at 1983 {#map exitflag gbmdcenter avoid off};#nop 丐帮扬州中央广场地道开放;
                #map at 813 {#map exitflag gbmddgc avoid off};#nop 打谷场地道开放;
        };

其他还有类似没钱的时候关闭需要付费通过的路口,有钱了再次开放付费路口等等。

通过房间的权重值来选择路径:
#map at 1049 {#map set roomweight 99};
把扬州过河的渡口房间权重调整到99,这样如果马车的通道或者丐帮的通道没有封闭时候,就不会选择坐船。但是其他通行方式都无效的时候,就会选择坐船的方式到达河对岸。

北大侠客行MUD,中国最好的MUD

zhouyi 发表于 2019-5-7 00:43:08

使用map来进行GPS定位
先通过触发取得【房间名】【房间描述】【出口信息】等数据,
然后新建一个alias用以启动GPS:
#alias {openclass_gps_start} {
        #class gps_start open;
        #v isopen_gps_start 1;
        #act {^你目前还没有任何为 %S 的变量设定。} {
                #class gps_start kill;
                gps_start_check {%%1};
        };
        #class gps_start close;
};

新建一个函数用当前房间信息来返回所处的map编号:
#function {xkxGPS_location} {
        #v tmp {};
        #v result {};
        #map list {roomname} {$xkxGPS} {variable} {tmp};
        #list tmp cre $tmp;
        #while &tmp[]>1 {#nop 用房间名直接定位;
                #list result add $tmp[+1];
                #list tmp del +1;
                #list tmp del +1;
        };
        #if {&result>1} {#nop 房间名定位重复,增加房间描述继续过滤;
                #v tmp {};
                #v tmp_room {};
                #loop 1 &result[] i {
                        #map at $result[$i] {
                                #map get {roomdesc} {tmp};
                                #if "$tmp"=="$xkxGPS" {
                                        #list tmp_room add $result[$i];
                                };
                                #v tmp {};
                        };
                };
                #v result $tmp_room;
                #if {&result>1} {#nop 房间名定位重复,增加出口信息继续过滤;
                        #v tmp {};
                        #v tmp_room {};
                        #loop 1 &result[] i {
                                #map at $result[$i] {
                                        #map get {roomdata} {tmp};
                                        #if "$tmp"=="$xkxGPS" {
                                                #list tmp_room add $result[$i];
                                        };
                                        #v tmp {};
                                };
                        };
                        #v result $tmp_room;
                };
        };
};

新建一个alias来处理上面函数返回的结果:
#alias {gps_start_check} {
        #if "%1"=="gps=start" {
                #v roomno_now @xkxGPS_location{};
                #if {&roomno_now[]==1} {
                        #v roomno_now $roomno_now;
                        #if {$roomno_now==1991} {alias_emkilljumang} {gps_start_check {gps=end}};
                        #map goto $roomno_now;
                        #sh 当前房间号:$roomno_now;
                        #return;
                };
                #elseif {&roomno_now[]>1} {
                        #sh {定位结果无法精确一个房间,用周围房间信息继续定位};
                        gps_start_check {gps=check};
                };
                #elseif {&roomno_now[]==0} {
                        gps_start_check {gps=err};                                                                                                                                                               
                        #ec {房间信息定位失败};
                        #if {$buzhen} {gps_start_check {gps=buzhen}} {gps_start_check {gps=err}};
                };
                #return;
        };
      #if {"%1"=="err"} {
                   #ec 定位失败,无法正确定位所在房间;
                  #return;
      };
      #if {"%1"=="check"} {
                  #ec 定位结果为多个可能的房间,进一步通过look周围的房间来进一步定位当前房间;
                   #return;
      };
};

dsleeper 发表于 2019-5-7 08:03:22

chat* bud zhouyi
#∞ chat* dog1 zhouyi
chat* admire zhouyi

youzi 发表于 2019-5-8 13:41:23

画地图效率高吗?进展如何了?
群里同步同步

zhouyi 发表于 2019-5-8 16:27:03

我是直接用sqlite转的地图,不是手动走房间画的。这个效率杠杠的啊,一个lua循环就画完了{:7_268:}。
我边做边发,零零星星的可能不怎么系统。

zhouyi 发表于 2019-5-8 17:12:01

map的性能如何?执行效率高吗?
tintin++的map,效率还是非常高的,开始我还有点当心频繁的计算路径会不会对系统资源造成过大的负担。
然后我写了一个循环来测试:
#alias test {#loop 1 3000 i {#map find $i;#path save forward path[$i]}
结果如图:


搜索当前房间到所有房间的路径,并且保存,这个操作在mush应该是属于死机级的操作了。
测试的结果就是完全不用当心性能的问题!

利用map行走到目的地
map虽然功能强大,代码简洁,但是自带的#map run不太好用,无论是wintin++ cygwin macos Linux,
执行#map run 操作都极容易奔溃,并且我们还需要处理一些特殊的路径,比如杀守门NPC,过河,
路径过长需要分批行走防止雷劈等等。
所以我只是使用#map find来找到路径,保存在变量里面,然后再另行处理走路。

#map find xxx;#path save forward path;

将取得的完整路径劈成若干合适的段:
#list all_fx_list cre {eu;e;ed;se;su;s;sd;sw;wu;w;wd;nw;nu;n;nd;ne;enter;out;u;d;1;2;3;4;5;6;7;8;};#nop 预定义可以连续行走的方向;

#alias {xkxGPS_pathlist} {
#v row 0;
#v xkxGPS {};
#v indexQueue {};
#v col 0;
#v result {};
#v result {%0};
#list _tb cre $result;
#v xkxGPS &_tb[];
#foreach $_tb[] i {#nop 碰到需要特殊的方向,就另起一个段待执行;
#var v $_tb[$i];
#list all_fx_list find $v result;
#list xkxGPS[$row] add $v;
#if {$result==0} {
   #math row {$row+1};
   #v col 0;
};
#math tmp {$col+(21*$row)};#nop 控制每段行走的步数;
#if {$col<20 || $tmp==$xkxGPS} {
   #math col {$col+1};} {
   #math row {$row+1};
   #var col 0;
};
};
#v i 0;
#while {$i<&xkxGPS[]} {
#list all_fx_list find {$xkxGPS[$i][-1]} result;
#if {$result==0} {
   #list xkxGPS[$i] sim xkxGPS[$i];
};
#if {$i==&xkxGPS[]-1} {
   #list xkxGPS[$i] sim xkxGPS[$i];
   #v xkxGPS[$i] {$xkxGPS[$i];moveover}
};
#else {
   #list xkxGPS[$i] sim xkxGPS[$i];
   #v xkxGPS[$i] {$xkxGPS[$i];movefinish}
};
#math i {$i+1};
};
};


在第一帖的#alias {gps_start_checck}里面增加一个条件判断:gps=end

#if {"%1"=="gps=end"} {
#if {@tonumber{$roomno_now}>0 && $flytoid>0} {#nop 起始和目的房间的ID号都不为空;
   #unv path;
   #map goto $roomno_now;
   #map find $flytoid;#nop 计算路径;
   #path save {forward} {path};#nop 将完整路径保存在变量中;
   #v gps 0;#nop 重置自动行走结束标签;
   #map at $flytoid {
    #map get {roomname} xkxGPS;#nop 取得目的房间的房间名,到达目的地后用来匹配是否正确到达了目的地;
    #map get xkxGPS;#nop 取得目的房间的出口信息,到达目的地后用来匹配是否正确到达了目的地;
   };
   #v gps $xkxGPS;
   #v gps $xkxGPS;
   #if {&{path}==0} {#nop 路径计算失败,没有正确取得路径或起止房间是同一个;
    #if $roomno_now!=$flytoid {
   score;
   #sh 目标地点路径未通!flytoid="$flytoid";
   #return;
    } {
   #ec ("飞什么飞,不就在这里么!");
   #v gps 1;
   moveover;#nop 自动行走流程结束;
   #return #nop ;
    }
   };
   xkxGPS_pathlist {$path};#用另一个#alias将路径分解成若干段;
   #v pathindex 0;
   #list _tb cre {@xkxGPS_pathArray2{$pathindex}};
   #list _tb get -1 _t;#nop 从_tb取出最后一个值赋值给_t;
   #nop #replace _t { } {};
   #replace _t {-} {};
   #v MathstepNum $_t;
   #if {{&{$aliasStepNum[$MathstepNum]}}==0 or "$aliasStepNum[$MathstepNum]"==""} {
    #v _t 0;
   } {#v _t $aliasStepNum[$MathstepNum]
   };
   halt;set brief 2;
   #if {$roomno_now==2112 || $roomno_now==2113 || $roomno_now==2114 || $roomno_now==2115} {
    stand;#nop 某些特殊房间离开之前需要先输入特定的指令,比如先站起来才能移动;
   };
   #elseif $roomno_now==288 {
    drop qiguo ji;drop puer cha;drop guoqiao mixian;drop guoqiao heiyu;drop ye er ba;drop kaoya;
    #nop 在厨房吃吃喝喝了之后,不能带食物走;
   };
   #elseif $roomno_now==682 {
    drop kaoya;drop tao;drop qiguo ji;
   };
   #if {$roomno_now!=91 && "$always"!="擂台下"} {
    @alias_yjl{};#行走之前,先补充一下精力;
   };
   @run{@xkxGPS_pathArray2{$pathindex}};
} {
   #var gpserrnum 1;
};
};

mathematics 发表于 2019-5-8 17:30:47

chat* admire zhouyi
yct43.

xxhy 发表于 2021-10-23 08:53:21

这属于超阶教程了。
发一下sqlite数据库转tintin map的代码呗?
页: [1]
查看完整版本: 【tintin++】map使用进阶笔记