打印

为活跃论坛,大家加油顶到11,再发好工具!!

本帖已经被作者加入个人空间
在恭喜你成功编写了第二个 ACI 程序时, 还要提醒你注意:不要利用这个刷屏搔扰他人,否则游戏运营商可能会限制密语,从而给大家带来诸多不便。另外一点需要注意的是,如果循环次数太多,那么输出的信息太多可能会(确切的说是肯定会)导致你断线,如何能够大量输入并且不会断线, 在你充分掌握了 ACI 提供的函数以后你就会有解决方案了。

TOP

2.3        编写第一个实用的 ACI 程序

到这里你可能会觉得相当的困惑, 因为你还不能发现 ACI 给你带来任何帮助。实际上,前面两段程序仅仅是一个示范。确切来说,你需要编写一些指定的 ACI 函数来处理百宝箱发送过来的消息, 这些函数是实现约定好的,比如我们接下来要接触到的一个函数:处理接收到的消息并恰当的返回一些信息,代码如下:

TOP

mixed on_receive_message(string org, string msg)
{
    string peer_name;

    if (org == MSG_LISTEN)
    {
        sscanf(msg, "%s=> %*s", &peer_name);
        if (peer_name == "小号的名字")
        {
            tell(peer_name, "ACI is working");
            return 1;
        }
    }
}

TOP

如果你看不懂其中的逻辑关系,不要提问,你应该首先去尝试学习好C 语言。

如果你看得懂但是觉得和 C 有一些差别,请看接下来的说明:

mixed 表示一个“任何”类型,也就是 on_receive_message 这个函数返回什么类型都可以。

string 表示字符串类型,ACI 支持字符串这个数据类型。

MSG_LISTEN 是一个系统预定义的宏,它是什么内容呢? 这个问题就交给你了。

TOP

&peer_name,ACI 不支持指针,但是为什么会有 "&"  这种和指针关系非常暧昧的符号?这是因为,peer_name 是一个变参,它需要接受sscanf 这个函数的返回值,所以需要在他前面赠加一个 "&" 表示它是变参,这是语法的强制要求。&peer_name 并不像 C 里面那样是一个指针。

return 1 表示返回 1,这点毋庸置疑。但是返回 1 意味着什么呢?他意味让百宝箱不要再处理这条消息了。 如果返回 0 或者直接什么都不返回,百宝箱还会按照预定的流程处理这条消息。比如,你的小号密你任何信息,你都会反密:“ACI is working”,即使你的小号密你诸如 "at" 的密语命令你都是如此应答。如果这里的 return 1替换为 return 0,那么你在反密以后,百宝箱还会继续处理, 返回原本密语命令需要返回的信息。

最后这个函数没有任何返回就结束了,似乎不太符合 C 的语法。 是的,的确不符合,但是它符合 ACI 的要求, 什么都没有返回意味着返回一个 (void)。因为这个函数要求的返回类型是 mixed, 也就是什么类型都可以,包括 (void)。

TOP

2.4        编写第二个实用的 ACI 程序

输入以下代码:

mixed on_char_appear(mapping ob)
{
    if (ob["type"] == OBJECT_TYPE_MONSTER)
        printf("Monster %s is appeared, at %d, %d.\n", ob["name"],
               ob["x"], ob["y"]);
    else
    if (ob["type"] == OBJECT_TYPE_CHAR)
        printf("Player %s is appeared, at %d, %d.\n", ob["name"],
               ob["x"], ob["y"]);
}

mixed on_item_appear(mapping ob)
{
    printf("Item %s is appeared at %d, %d\n", ob["name"], ob["x"], ob["y"]);
}

加载以后在游戏中走动一会儿,注意一下调试窗口出现的信息

TOP

2.5        关于阻塞和不可阻赛

有一些函数会阻塞执行的线程,如 sleep, take_mutex  等线程间同步函数。同样,游戏动作也会阻塞执行的线程,如 hit, run, cast, talk_to 等等。在处理百宝箱消息时,对于哪些不可阻塞的消息,不能执行上述的函数,参考下面的例子:

void on_enter_world()
{
    printf("跑到 224, 162\n");
    run_to(224, 162);
}

加载这个例子以后,登陆进入游戏,发现它并不能按照你的预期进行工作。

TOP

你能在调试窗口中看到:“跑到 100, 100。”, 但是人物显然并没有这么做。这是因为 on_enter_world 是非阻塞的,相当于操作系统中的中断。试图在这个函数中执行阻塞调用,就会导致执行被强行中止,那么,我们又的确需要在进入游戏以后跑两步以锻炼身体,那么我们应该怎么做?答案就是,创建一个独立的线程来完成这些阻塞调用,输入下面的修正过的代码:

void on_enter_world()
{
    printf("跑到 224, 162\n");
    create_thread("enter_world", "run_to", 224, 162);
}

TOP

如果你发现人物按照期望并没有跑到你想去的地方,请注意你所在的地图上 224, 162 是不是一个可达的地点,如果不是,那么请自行修改坐标,另外也可能因为其他原因导致跑动的过程停止,比如你手工停止或者是途中规避怪物。

很好,现在你发现人物的确是如愿的跑向目的地,但是问题还没有结束,我们必须知道,线程的名字不能相同。如果我们在进入游戏的时候,在创建了 enter_world 线程跑向目的地之前如果已经创建了enter_world这个线程话,再次创建同名的线程就会失败,怎么解决这个问题呢?有两种方法:

TOP

例子 1:

void on_enter_world()
{
    printf("跑到 224, 162\n");
    delete_thread("enter_world");
    create_thread("enter_world", "run_to", 224, 162);
}

TOP

例子 2:

void on_enter_world()
{
    printf("跑到 224, 162\n");
    create_thread(0, "run_to", 224, 162);
}

TOP

其中含义不言而喻。需要提醒的时,创建一个线程最好指明他的名字而不要让系统自己选择,并且取一个含意贴切的名字。这样的代码将会更容易懂并且更容易维护。

在上面的例子都成功运行以后,你可能已经不满足仅仅是跑动这么单一的操作,我想来一点复杂的,怎么办?很简单,可以自己写一个函数,包含一系列的操作,并作为线程的入口。输入以下代码:

TOP

void on_enter_world()
{
    printf("示范。\n");
    delete_thread("enter_world");
    create_thread("enter_world", "do_sample", "示范开始");
}

void do_sample(string msg)
{
    mapping my = me();

    say(msg);
    say("开始跑步");
    run_to(224, 162);
    say("跑完了");
    say(sprintf("现在坐标:%d, %d", my["x"], my["y"]));
    say("结束了");
}

注:create_thread 调用的 "do_sample" 后面跟随的是传递给函数的参数,类型和数量必须和 do_sample 需要的参数一致。

例子的效果可以自行观察,记得要切换到聊天页面,并且打开普通频道。

TOP

3.        ACI 使用的一些全局变量

这些全局变量保存了游戏中的信息,通过访问这些全局变量可以获得游戏中能观察到的人物,道具和各种设定等。

TOP

all_item_list        mapping        保存了所有物品的处理方法,物品名字为关键字,值为mapping,包含:
”storage”字段:
ITEM_AUTO_APPLY        自动使用
ITEM_STORED                存入仓库
ITEM_SOLD                        出售
ITEM_DONT_CARE        不处理
ITEM_DROP                        丢弃
“manage”字段:
ITEM_PERFECT                极品
ITEM_PRECEDENCE        优先
ITEM_NORMAL                普通
ITEM_IGNORED                不拾取
“type”字段:
表明了物品的类别

TOP

当前时区 GMT+8, 现在时间是 2008-11-23 08:32
新ICP备05002317号
Powered by Discuz! 6.0.0 © 2001-2007 Comsenz Inc.
Processed in 0.032821 second(s), 7 queries, Gzip enabled
TOP
清除 Cookies - 联系我们 - 网络游戏代理 - Archiver - - WAP
Designed By Discuz! 百宝箱论坛