// アイテム番号の連想配列
let dic_item178: { [key: string]: number } = {
"support": 17, // 補助支柱(オークの原木)
"trapdoor": 656, // 暗渠のふた(トラップドア)
"slab": 262302 // 暗渠のふた(ハーフブロック)
};
// 反対方向の連想配列
let dic_opposite: { [key: number]: number } = {
[RIGHT]: LEFT, // 右の反対は左
[LEFT]: RIGHT, // 左の反対は右
[UP]: DOWN, // 上の反対は下
[DOWN]: UP, // 下の反対は上
[FORWARD]: BACK, // 前の反対は後ろ
[BACK]: FORWARD // 後ろの反対は前
};
// エリア番号の連想配列
let dic_areaId178: { [key: string]: number } = {
"farmlandArea": 1, // 畑エリア
"floorArea": 2 // 床エリア
};
// 各エリアのブロック番号を記録する二次元配列
let arr_areaBlocks178: number[][] = [
[], // 畑エリアのブロック配列
[] // 床エリアのブロック配列
];
// エリア状態
let dic_areaStatus178: { [key: string]: number } = {
"areaId": 0, // エリア番号(初期状態は未指定:0)
"maxRow": 6, // 行の最大値
"maxCol": 8, // 列の最大値
"positiveRowDirection": FORWARD, // 行の順方向
"positiveColDirection": RIGHT // 列の順方向
};
// エージェント状態
let dic_agentStatus178: { [key: string]: number } = {
"row": 0, // 現在の行位置
"col": 0, // 現在の列位置
"moveDirection": RIGHT // 移動する方向
};
// エージェントを移動する関数
function move178(agentStatus: { [key: string]: number }, areaStatus: { [key: string]: number }) {
// エージェントの現在の位置と移動方向を取得します
let row = agentStatus["row"]; // エージェントの現在の行位置
let col = agentStatus["col"]; // エージェントの現在の列位置
let moveDirection = agentStatus["moveDirection"]; // エージェントの移動方向
// 列の順方向を取得します
let positiveColDirection = areaStatus["positiveColDirection"];
// 列の逆方向を取得します
let negativeColDirection = dic_opposite[positiveColDirection];
// 方向転換が必要かどうかを判定します
let shouldTurn = false;
// エージェントが列を順方向に進んでいて、エリアの列の最後にいる場合は、方向転換が必要です
if (moveDirection == positiveColDirection && col == areaStatus["maxCol"]) {
shouldTurn = true;
}
// エージェントが列を逆方向に進んでいて、エリアの列の最初にいる場合は、方向転換が必要です
if (moveDirection == negativeColDirection && col == 0) {
shouldTurn = true;
}
// 移動を続けるかどうかを判定します
let shouldContinue = true;
// エージェントがエリアの行の最後にいる場合
if (row == areaStatus["maxRow"]) {
// かつ、方向転換が必要の場合は、移動してもエリア外に出てしまうので、ここで移動を終了します
if (shouldTurn) {
shouldContinue = false;
}
}
// 移動終了の場合は、false を返して終了します
if (shouldContinue == false) {
return false;
}
// エージェントを移動します
if (shouldTurn) {
// 方向転換をする場合の移動方法
// 行を移動します
agent.move(areaStatus["positiveRowDirection"], 1);
row += 1;
// エージェントが移動する向きを反対にします
moveDirection = dic_opposite[moveDirection];
} else {
// 方向転換をしない場合の移動方法
// 列を移動します
agent.move(moveDirection, 1);
if (moveDirection == positiveColDirection) {
// 列の順方向へ移動する場合はエージェントの列位置に 1 を加えます
col += 1;
} else {
// 列の逆方向へ移動する場合はエージェントの列位置から 1 を除きます
col -= 1;
}
}
// エージェントの状態を更新します
agentStatus["row"] = row;
agentStatus["col"] = col;
agentStatus["moveDirection"] = moveDirection;
// 移動したので、true を返して終了します
return true;
}
// 暗渠ブロックかどうかを判定する関数
function isWaterCover178(blockId: number) {
if (blockId == dic_item178["trapdoor"] || blockId == dic_item178["slab"]) {
return true;
}
return false;
}
// 暗渠カバーを設置する関数
// エージェントは水路と同じ向きを向いており、水路の斜め上の高さにいることを前提にします
function placeWaterCover178(item: number,
positiveDirection: number,
supportItem: number) {
// 地下通路を掘るときの地面ブロックを記録する配列
let grounds: number[] = [];
let negativeDirection = dic_opposite[positiveDirection];
// 補助支柱の作成
agent.move(positiveDirection, 1);
agent.setItem(supportItem, 1, 1);
agent.place(negativeDirection);
// 地下通路の作成・移動
grounds.push(agent.inspect(AgentInspection.Block, DOWN));
agent.destroy(DOWN);
agent.move(DOWN, 1);
grounds.push(agent.inspect(AgentInspection.Block, DOWN));
agent.destroy(DOWN);
agent.move(DOWN, 1);
grounds.push(agent.inspect(AgentInspection.Block, negativeDirection));
agent.destroy(negativeDirection);
agent.move(negativeDirection, 1);
// 暗渠カバーの設置
agent.turn(RIGHT);
agent.turn(RIGHT);
agent.setItem(item, 1, 1);
agent.place(UP);
agent.turn(RIGHT);
agent.turn(RIGHT);
// 地下通路を戻りつつ現状復帰
agent.move(positiveDirection, 1);
agent.setItem(grounds.pop(), 1, 1);
agent.place(negativeDirection);
agent.move(UP, 1);
agent.setItem(grounds.pop(), 1, 1);
agent.place(DOWN);
agent.move(UP, 1);
agent.setItem(grounds.pop(), 1, 1);
agent.place(DOWN);
// 補助支柱の撤去
agent.destroy(negativeDirection);
agent.move(negativeDirection, 1);
return;
}
// エリアをコピーする関数
function copyArea178(agentStatus: { [key: string]: number },
areaStatus: { [key: string]: number },
areaBlocks: number[][]) {
// コピーするブロック配列
let blocks = [];
// エリア内の床のブロックを読み取りながら、元の床に戻していきます
while (true) {
// 足元のブロックを読み取り、畑ブロック配列へ記録します
let blockId = agent.inspect(AgentInspection.Block, DOWN);
blocks.push(blockId);
// 次の位置へ移動します
let shouldContinue = move178(agentStatus, areaStatus);
if (shouldContinue == false) {
break;
}
}
// コピーしたブロック配列をエリアブロック連想配列に保存します
areaBlocks[areaStatus["areaId"] - 1] = blocks;
return;
}
// エリアをペーストする関数
function pasteArea178(agentStatus: { [key: string]: number },
areaStatus: { [key: string]: number },
areaBlocks: number[][]) {
// コピーしたブロック配列を取得します
let blocks = areaBlocks[areaStatus["areaId"] - 1];
// ペーストしたブロックを記録する配列
let pastedBlocks: number[] = [];
// 補助支柱のアイテム番号
let supportItemId = dic_item178["support"];
// エリア内のブロックを置き換えていきます
while (true) {
// 足元のブロックを削ります
agent.destroy(DOWN);
// ブロック配列から順にブロックを取り出します
let blockId = blocks.shift();
// ブロックを置く前に暗渠かどうか判定します
if (isWaterCover178(blockId)) {
// 暗渠を作ります
placeWaterCover178(blockId, agentStatus["moveDirection"], supportItemId);
} else {
// ブロック設置
agent.setItem(blockId, 1, 1);
agent.place(DOWN);
pastedBlocks.push(blockId);
}
// 次の位置へ移動します
let shouldContinue = move178(agentStatus, areaStatus);
if (shouldContinue == false) {
break;
}
}
// エリアブロック連想配列にペーストしたブロック配列を保存します
areaBlocks[areaStatus["areaId"] - 1] = pastedBlocks;
return;
}
// 畑エリアをコピーするコマンド
player.onChat("17-8copy_farm", function () {
// スタート地点から1歩進みエリア内に入ります
agent.move(FORWARD, 1);
// エージェント状態を初期化します
dic_agentStatus178["row"] = 0;
dic_agentStatus178["col"] = 0;
dic_agentStatus178["moveDirection"] = RIGHT;
// エリア状態を初期化します
dic_areaStatus178["areaId"] = dic_areaId178["farmlandArea"];
// エリア内のブロックをコピーします
copyArea178(dic_agentStatus178, dic_areaStatus178, arr_areaBlocks178);
});
// 床エリアをコピーするコマンド
player.onChat("17-8copy_floor", function () {
// スタート地点から1歩進みエリア内に入ります
agent.move(FORWARD, 1);
// エージェント状態を初期化します
dic_agentStatus178["row"] = 0;
dic_agentStatus178["col"] = 0;
dic_agentStatus178["moveDirection"] = RIGHT;
// エリア状態を初期化します
dic_areaStatus178["areaId"] = dic_areaId178["floorArea"];
// エリア内のブロックをコピーします
copyArea178(dic_agentStatus178, dic_areaStatus178, arr_areaBlocks178);
});
// 畑エリアをペーストするコマンド
player.onChat("17-8paste_farm", function () {
// スタート地点から1歩進みエリア内に入ります
agent.move(FORWARD, 1);
// エージェント状態を初期化します
dic_agentStatus178["row"] = 0;
dic_agentStatus178["col"] = 0;
dic_agentStatus178["moveDirection"] = RIGHT;
// エリア状態を初期化します
dic_areaStatus178["areaId"] = dic_areaId178["farmlandArea"];
// エリア内のブロックをペーストします
pasteArea178(dic_agentStatus178, dic_areaStatus178, arr_areaBlocks178);
});
// 床エリアをペーストするコマンド
player.onChat("17-8paste_floor", function () {
// スタート地点から1歩進みエリア内に入ります
agent.move(FORWARD, 1);
// エージェント状態を初期化します
dic_agentStatus178["row"] = 0;
dic_agentStatus178["col"] = 0;
dic_agentStatus178["moveDirection"] = RIGHT;
// エリア状態を初期化します
dic_areaStatus178["areaId"] = dic_areaId178["floorArea"];
// エリア内のブロックをペーストします
pasteArea178(dic_agentStatus178, dic_areaStatus178, arr_areaBlocks178);
});