盾でガードに成功したことを検知したい
Minecraft Java -ver 1.19.3
skript -ver 2.6.4
[やりたいこと]
盾でガードに成功したことを検知する方法を知りたい。
final damageを0にして検知とかも試したのですが盾で吸収した分もfinal damageに入っていてうまく検知できなかったのでお力を貸していただきたいです。記載漏れがございましたらすみません。
6 Replies
盾の耐久値とかで判定してみれば
forge 1.19.3から盾の処理を見てみると
視点のベクトルとポジションの差からドット積を使って
if (p_21017_ > 0.0F && this.isDamageSourceBlocked(p_21016_)) {
net.minecraftforge.event.entity.living.ShieldBlockEvent ev = net.minecraftforge.common.ForgeHooks.onShieldBlock(this, p_21016_, p_21017_);
if(!ev.isCanceled()) {
if(ev.shieldTakesDamage()) this.hurtCurrentlyUsedShield(p_21017_);
f1 = ev.getBlockedDamage();
p_21017_ -= ev.getBlockedDamage();
if (!p_21016_.isProjectile()) {
Entity entity = p_21016_.getDirectEntity();
if (entity instanceof LivingEntity) {
LivingEntity livingentity = (LivingEntity)entity;
this.blockUsingShield(livingentity);
}
}
flag = true;
}
}
public boolean isDamageSourceBlocked(DamageSource p_21276_) {
Entity entity = p_21276_.getDirectEntity();
boolean flag = false;
if (entity instanceof AbstractArrow abstractarrow) {
if (abstractarrow.getPierceLevel() > 0) {
flag = true;
}
}
if (!p_21276_.isBypassArmor() && this.isBlocking() && !flag) {
Vec3 vec32 = p_21276_.getSourcePosition();
if (vec32 != null) {
Vec3 vec3 = this.getViewVector(1.0F);
Vec3 vec31 = vec32.vectorTo(this.position()).normalize();
vec31 = new Vec3(vec31.x, 0.0D, vec31.z);
if (vec31.dot(vec3) < 0.0D) {
return true;
}
}
}
return false;
}
if (p_21017_ > 0.0F && this.isDamageSourceBlocked(p_21016_)) {
net.minecraftforge.event.entity.living.ShieldBlockEvent ev = net.minecraftforge.common.ForgeHooks.onShieldBlock(this, p_21016_, p_21017_);
if(!ev.isCanceled()) {
if(ev.shieldTakesDamage()) this.hurtCurrentlyUsedShield(p_21017_);
f1 = ev.getBlockedDamage();
p_21017_ -= ev.getBlockedDamage();
if (!p_21016_.isProjectile()) {
Entity entity = p_21016_.getDirectEntity();
if (entity instanceof LivingEntity) {
LivingEntity livingentity = (LivingEntity)entity;
this.blockUsingShield(livingentity);
}
}
flag = true;
}
}
public boolean isDamageSourceBlocked(DamageSource p_21276_) {
Entity entity = p_21276_.getDirectEntity();
boolean flag = false;
if (entity instanceof AbstractArrow abstractarrow) {
if (abstractarrow.getPierceLevel() > 0) {
flag = true;
}
}
if (!p_21276_.isBypassArmor() && this.isBlocking() && !flag) {
Vec3 vec32 = p_21276_.getSourcePosition();
if (vec32 != null) {
Vec3 vec3 = this.getViewVector(1.0F);
Vec3 vec31 = vec32.vectorTo(this.position()).normalize();
vec31 = new Vec3(vec31.x, 0.0D, vec31.z);
if (vec31.dot(vec3) < 0.0D) {
return true;
}
}
}
return false;
}
90度までは失敗
それ以上は成功ってことにしてるので
同じようにskriptで実装すればいけると思います
skript only
on damage:
set {_attacker} to attacker
if projectile is set:
set {_attacker} to projectile
if victim is blocking:
set {_lv} to vector from yaw yaw of victim and pitch pitch of victim
set {_v} to (vector between {_attacker} and victim normalized) ** vector(1, 0, 1)
if {_lv} dot {_v} < 0.0:
set {_blocked} to true
else if pitch of victim is 90: #負の0もブロック判定
set {_blocked} to true
else:
set {_blocked} to false
if {_blocked} is true:
broadcast "block"
else:
broadcast "hit"
on damage:
set {_attacker} to attacker
if projectile is set:
set {_attacker} to projectile
if victim is blocking:
set {_lv} to vector from yaw yaw of victim and pitch pitch of victim
set {_v} to (vector between {_attacker} and victim normalized) ** vector(1, 0, 1)
if {_lv} dot {_v} < 0.0:
set {_blocked} to true
else if pitch of victim is 90: #負の0もブロック判定
set {_blocked} to true
else:
set {_blocked} to false
if {_blocked} is true:
broadcast "block"
else:
broadcast "hit"
化け物
こわい
やりたいことができるようになりました。本当にありがとうございます。