maple & chicken

適当に垂れ流す。メイプルのエミュ鯖に関する話がメインになるとおもいます。

JS 基本編

はじめに

この記事は8割の憶測と2割の実測で書かれています。英語が読める方は海外のフォーラムにある投稿を読んだほうが良いでしょう。
私は本職の人でも無いのでそういう方から見れば何言ってんだこいつ、と思われるかもしれませんが温かい目で見てください。
間違いを発見した場合コメントで教えてくれると私が喜びます。
あと、多少プログラムの知識がある前提で書いています。
jsの構文等についてはここでは触れませんので適宜他サイトで勉強してください。

とりあえずエミュ鯖で使うjsの基本的な仕様をまとめましたのでご覧ください。

action()は何度でも呼ばれる

function action(mode, type, selection) {
    cm.sendOk("メッセージ");
}

試しにこのjsを動かしてみてください。

動画を用意しました。

動かすとわかると思いますがOKを押しても同じメッセージが表示されます。
これはOKボタンを押したり、選択肢を選んだりといったアクションをするたびにaction()が呼び出されるためです。
左下のEND CHATを押すとaction()は呼ばれないため会話が終了します。(sendSimple()のみ特殊でaction()が呼び出されます)
ただ処理の途中でcm.dispose()が実行された場合に限っては何らかのアクションがあってもaction()は呼び出されません。

処理はすべて同時に実行される

これもサンプルを用意しました。

function action(mode, type, selection) {
    cm.sendOk("メッセージ");
    cm.gainItem(5220000, 1);
}

こちらは実行するとメッセージが出て同時にアイテムが貰えます。
正確には上から順番に実行され、同時では無いのですがsendOk()等でウィンドウを表示させたからと言って動作が一時停止するわけでも無く、普通に最後まで実行されます。

function action(mode, type, selection) {
    cm.sendOk("メッセージ1");
    cm.sendOk("メッセージ2");
}

こちらの場合メッセージ1は表示されますが、メッセージ2はすでにメッセージ1が表示されているため何も起こりません。
言ってしまえばバグの様なものです、action()1回につきsend等のメッセージを表示させる関数は1つだけ実行されるようにしましょう。

start()について

function start() {
    action(1, 0, 0);
}

function action(mode, type, selection) {
    cm.sendOk("メッセージ");
}

上2つのサンプルでは使っていませんがこのようにしてstart関数を書くことで会話がスタートする時action()が呼ばれるのではなくstart()が呼び出されるようになります。
どちらかと言えばこっちが正式な書き方のような気がします。
最初に呼び出されてからはもう呼び出されることはありませんので、会話の最初にする処理(statusの初期化など)が普通書かれます。
ちなみに関数内にcm.dispose()がありstart()1回で処理が終了するものであればaction()を省いでも大丈夫です。

var status = 0;

function start() {
    if(status) {
	cm.sendOk("メッセージ2");
	cm.dispose();
    } else {
	status++;
	cm.sendNext("メッセージ1");
    }
}

動かない例。メッセージ1でNEXTを押すとaction()を呼び出そうとするのでエラーが出ます。

一度の処理で2つ以上のsend系が実行されるのは意味がありませんのでsend系はaction関数内に固めて、start関数内にはsend系は使わないのが無難でしょう。
しかし、表示させたいメッセージが2つ程度であれば

function start() {
    cm.sendNext("メッセージ1");
}

function action(mode, type, selection) {
    cm.sendOk("メッセージ2");
    cm.dispose();
}

このように書いても良いかもしれません。

引数は省略できる

function action() {
    cm.sendOk("メッセージ1");
    cm.dispose();
}

エラーも出ずに動いてくれます。
modeのみ使う場合は

function action(mode) {

このようにしても大丈夫です。
ただしsendSimple()等、3つ目の引数(selection)を使う場合は3つとも書かなくてはいけません。

今回は以上です。まとめ方下手なので分かりづらいと思います、すみません。

追記

function action() {
    cm.dispose();
    cm.gainItem(5220000,1);
    cm.sendOk("メッセージ");
}

cm.dispose()に関してですがこの順番でも最後のsendOk()まで動いちゃいます。
要はdispose()されてようが最後まで実行しちゃうようです。
途中で処理を止めたい場合は

function action() {
    cm.dispose();
    cm.gainItem(5220000,1);
    return;
    cm.sendOk("メッセージ");
}

このようにすると最後のsendOk()は実行されません。