【Minecraft Bedrock版】ダメージエリアの攻撃対象を除外する方法
統合版Minecraftのダメージエリアで攻撃対象を設定によって除外したい
Minecraft Bedrock Editionで、@minecraft/serverを使用して範囲攻撃を実装しています。
現在は、攻撃したエンティティの周囲6ブロック以内にいるエンティティへダメージを与える処理を作っています。
しかし、攻撃対象の除外条件を柔軟に設定できるようにしたいです。
実現したいこと
以下のような設定を切り替えられるようにしたいです。
① 自分だけ除外
- 自分 → ダメージなし
- 他のプレイヤー → ダメージあり
- モブ → ダメージあり
② 自分とプレイヤーを除外
- 自分 → ダメージなし
- 他のプレイヤー → ダメージなし
- モブ → ダメージあり
③ 特定のエンティティだけ除外
例えばゾンビとスケルトンを除外する場合、
- 自分 → ダメージなし
- ゾンビ → ダメージなし
- スケルトン → ダメージなし
- クリーパー → ダメージあり
- プレイヤー → ダメージあり
としたいです。
④ 特定のプレイヤーだけ除外
例えば、
PlayerA
PlayerB
だけを除外して、それ以外のプレイヤーにはダメージを与えたいです。
現在使用しているコード
import { world, system, EntityDamageCause } from "@minecraft/server";
const isAttackBlocked = (attacker, target) => {
if (!attacker || !target) return false;
if (target.id === attacker.id) return true;
return false;
};
function applyAreaDamage(attacker, primaryTarget, centerLocation) {
const targets = attacker.dimension.getEntities({
location: centerLocation,
maxDistance: 6
});
for (const target of targets) {
// 攻撃者本人・メインターゲットは除外
if (
target.id === attacker.id ||
target.id === primaryTarget.id
) continue;
// エンティティが有効か確認
try {
if (!target.isValid) continue;
} catch {
continue;
}
// 追加フィルター
if (isAttackBlocked(attacker, target)) continue;
// ダメージ適用
try {
target.applyDamage(2, {
cause: EntityDamageCause.entityAttack,
damagingEntity: attacker
});
} catch (_) {}
}
}
world.afterEvents.entityHitEntity.subscribe((event) => {
const attacker = event.damagingEntity;
const hitEntity = event.hitEntity;
if (attacker.typeId !== "minecraft:player") return;
const inv = attacker.getComponent("minecraft:inventory");
if (!inv?.container) return;
const item = inv.container.getItem(attacker.selectedSlotIndex);
if (!item || item.typeId !== "ameno:custom_sword") return;
// 叩いたエンティティの位置を中心に範囲攻撃
applyAreaDamage(
attacker,
hitEntity,
hitEntity.location
);
});
world.afterEvents.itemCompleteUse.subscribe((event) => {
const { source, itemStack } = event;
if (itemStack?.typeId !== "ameno:custom_sword") return;
const { dimension, location } = source;
const dir = source.getViewDirection();
// 投擲物を生成
const proj = dimension.spawnEntity(
"ameno:sonic_bullet",
{
x: location.x + dir.x * 2,
y: location.y + 1.5,
z: location.z + dir.z * 2
}
);
// 速度を付与
proj.applyImpulse({
x: dir.x * 2,
y: dir.y * 2,
z: dir.z * 2
});
source.sendMessage("§e投擲武器を発射しました!");
});
現在困っていること
現在のコードでは、applyDamage()を使用していますが、場合によっては誰にもダメージが入らない状態になります。
また、
try {
target.applyDamage(2, {
cause: EntityDamageCause.entityAttack,
damagingEntity: attacker
});
} catch (_) {}
としているため、エラーが発生しても表示されません。
そのため、原因を確認するために、
try {
target.applyDamage(2, {
cause: EntityDamageCause.entityAttack,
damagingEntity: attacker
});
} catch (error) {
console.warn(`applyDamage failed: ${error}`);
}
のようにした方がよいのかも気になっています。
実現したい設定方法
例えば以下のような設定を用意して、
const damageSettings = {
// 自分自身を除外するか
excludeSelf: true,
// プレイヤー全員を除外するか
excludePlayers: false,
// 特定のエンティティを除外
excludedEntityTypes: [
// "minecraft:zombie",
// "minecraft:skeleton"
],
// 特定のプレイヤーを除外
excludedPlayerNames: [
// "PlayerA",
// "PlayerB"
]
};
この設定を変更するだけで攻撃対象を変更できるようにしたいです。
例えば、
excludeSelf: true
なら自分だけ除外。
excludeSelf: true,
excludePlayers: true
なら自分とプレイヤー全員を除外。
excludedEntityTypes: [
"minecraft:zombie",
"minecraft:skeleton"
]
ならゾンビとスケルトンだけ除外。
というようにしたいです。
特定のプレイヤーについて
特定のプレイヤーだけを除外する場合、
target.id
target.name
target.nameTag
のどれを使用するのが適切なのかも知りたいです。
例えば、
excludedPlayerNames: [
"PlayerA",
"PlayerB"
]
と設定した場合に、
PlayerA → ダメージなし
PlayerB → ダメージなし
その他のプレイヤー → ダメージあり
モブ → ダメージあり
としたいです。
質問
-
攻撃者自身、プレイヤー、特定のモブなどを設定によって除外するには、どのような実装が適切でしょうか?
-
プレイヤー判定には
target.typeId === "minecraft:player"を使用して問題ないでしょうか? -
特定のモブを除外する場合は
target.typeIdを使用する方法で問題ないでしょうか? -
特定のプレイヤーを除外する場合は
id、name、nameTagのどれを使用するのがおすすめでしょうか? -
現在のコードでダメージが入らなくなる原因として考えられる点はありますでしょうか?
-
今後、別の攻撃にも使い回せるような汎用的な除外処理にするには、どのようなコードにすればよいでしょうか?
Minecraft Bedrock Editionのアドオン開発に詳しい方、ご教授いただけると助かります。