Merge pull request #223 from KAMKEEL/codex/add-invincibility-button-to-ranged-options

Add ranged invincibility toggle for NPC projectiles
This commit is contained in:
Kam authored and GitHub committed 2025-10-21 19:20:32 -04:00
commit 45e82877ad
7 files changed
+51 -6

No files matched your search

+6
View File
@@ -53,6 +53,7 @@ public class DataStats {
public boolean playBurstSound = true; // Internal Only
public byte aimType = 0;
public boolean projectilesKeepTerrain = false;
public boolean projectileInvincibility = true;
public EnumCreatureAttribute creatureType = EnumCreatureAttribute.UNDEFINED;
@@ -116,6 +117,7 @@ public class DataStats {
compound.setBoolean("FiringSoundBegin", onSoundBegin);
compound.setByte("AimType", aimType);
compound.setBoolean("ProjectilesKeepTerrain", projectilesKeepTerrain);
compound.setBoolean("ProjectileInvincibility", projectileInvincibility);
if (pTrail == EnumParticleType.Custom)
compound.setTag("pCustom", pCustom.writeToNBT());
if (pEffect == EnumPotionType.Fire)
@@ -185,6 +187,10 @@ public class DataStats {
onSoundBegin = compound.getBoolean("FiringSoundBegin");
aimType = compound.getByte("AimType");
projectilesKeepTerrain = compound.getBoolean("ProjectilesKeepTerrain");
if (compound.hasKey("ProjectileInvincibility"))
projectileInvincibility = compound.getBoolean("ProjectileInvincibility");
else
projectileInvincibility = true;
if (pTrail == EnumParticleType.Custom)
pCustom = ScriptParticle.fromNBT(compound.getCompoundTag("pCustom"));
if (pEffect == EnumPotionType.Fire)
@@ -72,6 +72,9 @@ public class SubGuiNpcRangeProperties extends SubGuiInterface implements ITextfi
addButton(new GuiNpcButton(9, guiLeft + 100, y += 22, 70, 20, new String[]{"gui.no", "gui.yes", "stats.onShot"}, stats.aimType));
addLabel(new GuiNpcLabel(9, "stats.aimWhileShooting", guiLeft + 5, y + 5));
addButton(new GuiNpcButton(11, guiLeft + 100, y += 22, 70, 20, new String[]{"stats.allowed", "stats.ignored"}, stats.projectileInvincibility ? 0 : 1));
addLabel(new GuiNpcLabel(11, "stats.invincibility", guiLeft + 5, y + 5));
addButton(new GuiNpcButton(66, guiLeft + 190, guiTop + 190, 60, 20, "gui.done"));
}
@@ -119,6 +122,8 @@ public class SubGuiNpcRangeProperties extends SubGuiInterface implements ITextfi
close();
} else if (id == 9) {
stats.aimType = (byte) ((GuiNpcButton) guibutton).getValue();
} else if (id == 11) {
stats.projectileInvincibility = ((GuiNpcButton) guibutton).getValue() == 0;
}
}
@@ -66,6 +66,7 @@ public class EntityProjectile extends EntityThrowable {
public boolean canBePickedUp = false;
public boolean destroyedOnEntityHit = true;
private boolean ignoreInvincibility = false;
/**
* Is the entity that throws this 'thing' (snowball, ender pearl, eye of ender or potion)
@@ -464,13 +465,24 @@ public class EntityProjectile extends EntityThrowable {
didDBCAttack = true;
}
}
if (movingobjectposition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), damage)) {
EntityLivingBase entityliving = movingobjectposition.entityHit instanceof EntityLivingBase ? (EntityLivingBase) movingobjectposition.entityHit : null;
int prevHurtResistantTime = -1;
if (ignoreInvincibility && entityliving != null) {
prevHurtResistantTime = entityliving.hurtResistantTime;
entityliving.hurtResistantTime = 0;
}
boolean attacked = movingobjectposition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), damage);
if (!attacked && ignoreInvincibility && entityliving != null) {
entityliving.hurtResistantTime = prevHurtResistantTime;
}
if (attacked) {
if (didDBCAttack)
DBCAddon.instance.doDBCDamage(npc, this.damage, movingobjectposition.entityHit);
if (movingobjectposition.entityHit instanceof EntityLivingBase && (this.isArrow() || this.sticksToWalls())) {
EntityLivingBase entityliving = (EntityLivingBase) movingobjectposition.entityHit;
if (entityliving != null && (this.isArrow() || this.sticksToWalls())) {
if (!this.worldObj.isRemote) {
entityliving.setArrowCountInEntity(entityliving.getArrowCountInEntity() + 1);
}
@@ -496,10 +508,10 @@ public class EntityProjectile extends EntityThrowable {
}
}
if (this.effect != EnumPotionType.None && movingobjectposition.entityHit instanceof EntityLivingBase) {
if (this.effect != EnumPotionType.None && entityliving != null) {
if (this.effect != EnumPotionType.Fire) {
int p = this.getPotionEffect(effect);
((EntityLivingBase) movingobjectposition.entityHit).addPotionEffect(new PotionEffect(p, this.duration * 20, this.amplify));
entityliving.addPotionEffect(new PotionEffect(p, this.duration * 20, this.amplify));
} else {
movingobjectposition.entityHit.setFire(duration);
}
@@ -686,6 +698,7 @@ public class EntityProjectile extends EntityThrowable {
par1NBTTagCompound.setByte("Spins", this.dataWatcher.getWatchableObjectByte(29));
par1NBTTagCompound.setByte("Sticks", this.dataWatcher.getWatchableObjectByte(30));
par1NBTTagCompound.setByte("trailCustom", this.dataWatcher.getWatchableObjectByte(31));
par1NBTTagCompound.setBoolean("IgnoreInvincibility", ignoreInvincibility);
}
/**
@@ -723,6 +736,9 @@ public class EntityProjectile extends EntityThrowable {
byte trailCustom = par1NBTTagCompound.getByte("trailCustom");
this.dataWatcher.updateObject(31, Byte.valueOf(trailCustom));
}
if (par1NBTTagCompound.hasKey("IgnoreInvincibility")) {
this.ignoreInvincibility = par1NBTTagCompound.getBoolean("IgnoreInvincibility");
}
if (this.throwerName != null && this.throwerName.length() == 0) {
this.throwerName = null;
@@ -818,6 +834,7 @@ public class EntityProjectile extends EntityThrowable {
setIs3D(stats.pRender3D);
this.setRotating(stats.pSpin);
this.setStickInWall(stats.pStick);
this.ignoreInvincibility = !stats.projectileInvincibility;
}
public void setParticleEffect(EnumParticleType type) {
@@ -342,6 +342,14 @@ public class ScriptNpc<T extends EntityNPCInterface> extends ScriptLiving<T> imp
return npc.stats.projectilesKeepTerrain;
}
public void setProjectileInvincibility(boolean allowed) {
npc.stats.projectileInvincibility = allowed;
}
public boolean getProjectileInvincibility() {
return npc.stats.projectileInvincibility;
}
/**
* @param message The message the npc will say
@@ -472,6 +472,9 @@ stats.regenhealth=Health Regen
stats.combatregen=Combat Regen
stats.naturallydespawns=Naturally Despawn
stats.aimWhileShooting=Aim While Shooting
stats.invincibility=Invincibility
stats.allowed=ALLOWED
stats.ignored=IGNORED
stats.potionImmune=PotionImmune
stats.attackInvisible=Attack Invi
stats.never=Never
@@ -271,6 +271,9 @@ stats.regenhealth=Реген. здоровья
stats.combatregen=Реген. в бою
stats.naturallydespawns=Естественное исчезновение
stats.aimWhileShooting=Прицелив. при стрельбе
stats.invincibility=Invincibility
stats.allowed=ALLOWED
stats.ignored=IGNORED
stats.potionImmune=Иммунитет к зельям
stats.attackInvisible=Атаковать невидимых
@@ -395,6 +395,9 @@ stats.regenhealth=正常生命恢复
stats.combatregen=受攻击生命恢复
stats.naturallydespawns=自然消失
stats.aimWhileShooting=射击时瞄准
stats.invincibility=无敌帧
stats.allowed=允许
stats.ignored=忽略
stats.potionImmune=免疫药水
stats.attackInvisible=攻击隐藏
stats.never=从不