INSTEADのトリックとハッキング

テキストゲームやビジュアルノベルINSTEADのエンジンに慣れていない場合は、 こちらで読むことができます 。 要するに、これは単純なテキストアドベンチャー(クエスト)のプログラマエンジンにとって非常に便利で理解しやすいものです。 重要なのは、すべてのゲームがLuaで書かれているため、便利であるだけでなく、簡単に拡張できることです。 ゲームの書き方については説明しません。 それらをファイルでカットする方法を説明します。 ビジネスで知られているツールはありますか?

シナリオ1:アイテム+アイテム


プレーヤーにはインベントリがあり、インベントリにはいくつかのアイテムがあります。 INSTEADの標準的な動作は次のとおりです。あるアイテムをクリックしてから別のアイテムをクリックすると、最初のアイテムが2番目のアイテムに適用されます。 このイベントをキャッチするには、最初の項目で使用ハンドラーを定義するか、2番目の項目で使用されるハンドラーを定義する必要があります。 ただし、2番目のアイテムを最初のアイテムに適用する場合は、新しいイベントをインターセプトする必要があります。 しかし、注文に関係なく、単にアイテムを結合したい場合はどうでしょうか?

ハックを書いています。

cobj = function(v)
v.use = function(this,that)
return call(this, 'fuse', that);
end;
v.used = v.use;
return obj(v);
end


行くぞ これで、cobj型のオブジェクトを宣言し、それらに関数fuseを与えるだけで十分です。

rope = cobj{
nam = '',
inv = function()
local response = ' .';
return response;
end,
fuse = function(this, that)
if (that == lock) then
inv():del(lock);
inv():del(rope);
inv():add(rope_with_lock);
return ' .'
end;
end,
}


シナリオ2:部屋の説明でランダムフレーズを発行する


部屋の説明を単純にランダムなフレーズを返す関数にすると、その説明は一度だけ実行され、同じ結果が生成されます。 説明を変更するには、return関数ではなく、テキストバッファー(pおよびpn関数)を使用して出力する必要があります。

something = function()
ifsen = ' ';
response = {' .', ' .', ' .', ' -.'};
return ifsen..response[rnd(#response)];
end
dinner = room {
nam = ' ',
dsc = function()
p [[ ]];
p (something())
end
};


何かの後に括弧を付けないと、何も機能しません。 したがって、次のようなものを取得できます。



シナリオ3:新しいタイプのオブジェクト


ああ、これはすでに深く掘り下げています。 部屋に新しいタイプのオブジェクトが必要だとしましょう。 RPG(少なくともMMORPGが可能-プレイヤーだけがネットワークを操作するためのLuaライブラリを持っていれば)を書き、クエストのリストが必要だとしましょう。 これを行うには、エンジンを再構築する必要はありません。Luaパーツを少し掘り下げるだけです。

function quest(v) --constructor
if v.nam == nil then error (" .", 2) end
if v.short_dsc == nil then v.short_dsc = "" end
if v.scene == nil then v.scene = room_scene end
if v.completed == nil then v.completed = false end
if v.look == nil then v.look = room_look end
if v.save == nil then v.save = room_save end
v.location_type = true;
if v.way == nil then v.way = { } end
v.isQuest = true;
v.way = list(v.way);
v = obj(v);
return v;
end

function room_look(self)
local i,n,v,ph
for i,o in opairs(self.obj) do
if isObject(ref(o)) and not o.isQuest then
o = ref(o);
if v == nil then v = stead.par(' ',v, o:look());
else v = v .. stead.par(' ',v, o:look());
end
end
end

function room(v)
v.location_type = true;
if v.look == nil then v.look = room_look end
if v.scene == nil then v.scene = room_scene end
if v.quests == nil then v.quests = list {} end
if v.obj == nil then v.obj = v.quests
else for k,m in pairs(v.quests) do v.obj[k] = m end
end
if v.way == nil then v.way = {} end
v = room(v);
return v;
end


最初に、新しいタイプのオブジェクト-クエストを定義します。 これは、実際にはobjオブジェクトのstead.luaからのコピーと貼り付けです。クエストとオブジェクトを区別しやすくするためにisQuestフィールドのみが追加され、完了したフィールドが追加されて、クエストの完了を担当します。

room_lookは、プレイヤーが部屋を調べるときに呼び出される関数です。 通常は、部屋内のすべてのオブジェクトの説明を表示します(obj配列から)。 ここにはスタブのみが追加されています。ルーム内のすべてのクエストの説明を表示しないでください。

ルーム自体も再定義されました-クエストの配列があります。 obj配列はquests配列からのオブジェクトで満たされます-空の場合は同一視され、オブジェクトが存在する場合は結合されます。

これは単なる例であり、任意のタイプのオブジェクトと部屋を定義できます。

こっち そして、この素晴らしいエンジンの巧妙なトリックをすでに知っているので、 通常のドキュメントを読むことができます

Source: https://habr.com/ru/post/J116958/


All Articles