mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Improved death messages when dying from a secondary cause whilst being harmed by a spell
This commit is contained in:
parent
e386e040ea
commit
da5f64e199
13 changed files with 120 additions and 22 deletions
|
@ -78,13 +78,13 @@ public class BatEeeeAbility implements Ability<Hit> {
|
||||||
Vec3d origin = player.getOriginVector();
|
Vec3d origin = player.getOriginVector();
|
||||||
|
|
||||||
if (rng.nextInt(20000) == 0) {
|
if (rng.nextInt(20000) == 0) {
|
||||||
player.getMaster().damage(MagicalDamageSource.create("eeee", player.getMaster()), 0.1F);
|
player.getMaster().damage(MagicalDamageSource.create("eeee", player), 0.1F);
|
||||||
}
|
}
|
||||||
|
|
||||||
player.findAllEntitiesInRange(5).forEach(e -> {
|
player.findAllEntitiesInRange(5).forEach(e -> {
|
||||||
if (e instanceof LivingEntity && !HAS_SHIELD.test(e)) {
|
if (e instanceof LivingEntity && !HAS_SHIELD.test(e)) {
|
||||||
boolean isEarthPony = EquinePredicates.PLAYER_EARTH.test(e);
|
boolean isEarthPony = EquinePredicates.PLAYER_EARTH.test(e);
|
||||||
e.damage(MagicalDamageSource.create("eeee", player.getMaster()), isEarthPony ? 0.1F : 0.3F);
|
e.damage(MagicalDamageSource.create("eeee", player), isEarthPony ? 0.1F : 0.3F);
|
||||||
|
|
||||||
Vec3d knockVec = origin.subtract(e.getPos());
|
Vec3d knockVec = origin.subtract(e.getPos());
|
||||||
((LivingEntity) e).takeKnockback(isEarthPony ? 0.3F : 0.5F, knockVec.getX(), knockVec.getZ());
|
((LivingEntity) e).takeKnockback(isEarthPony ? 0.3F : 0.5F, knockVec.getX(), knockVec.getZ());
|
||||||
|
|
|
@ -108,7 +108,7 @@ public class EarthPonyStompAbility implements Ability<Hit> {
|
||||||
-(player.getY() - i.getY() - liftAmount) / inertia + (dist < 1 ? dist : 0),
|
-(player.getY() - i.getY() - liftAmount) / inertia + (dist < 1 ? dist : 0),
|
||||||
-(player.getZ() - i.getZ()) / inertia);
|
-(player.getZ() - i.getZ()) / inertia);
|
||||||
|
|
||||||
DamageSource damage = MagicalDamageSource.create("smash", player);
|
DamageSource damage = MagicalDamageSource.create("smash", iplayer);
|
||||||
|
|
||||||
double amount = (1.5F * player.getAttributeInstance(EntityAttributes.GENERIC_ATTACK_DAMAGE).getValue() + heavyness * 0.4) / (float)(dist * 1.3F);
|
double amount = (1.5F * player.getAttributeInstance(EntityAttributes.GENERIC_ATTACK_DAMAGE).getValue() + heavyness * 0.4) / (float)(dist * 1.3F);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class InfernoSpell extends FireSpell {
|
||||||
@Override
|
@Override
|
||||||
protected DamageSource getDamageCause(Entity target, LivingEntity attacker) {
|
protected DamageSource getDamageCause(Entity target, LivingEntity attacker) {
|
||||||
if (attacker != null && attacker.getUuid().equals(target.getUuid())) {
|
if (attacker != null && attacker.getUuid().equals(target.getUuid())) {
|
||||||
return MagicalDamageSource.create("fire.own", null);
|
return MagicalDamageSource.create("fire.own");
|
||||||
}
|
}
|
||||||
return MagicalDamageSource.create("fire", attacker);
|
return MagicalDamageSource.create("fire", attacker);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class JoustingSpell extends AbstractSpell implements Attached {
|
||||||
LivingEntity owner = source.getMaster();
|
LivingEntity owner = source.getMaster();
|
||||||
|
|
||||||
source.findAllEntitiesInRange(rad).forEach(e -> {
|
source.findAllEntitiesInRange(rad).forEach(e -> {
|
||||||
e.damage(MagicalDamageSource.create("rainboom", owner), 6);
|
e.damage(MagicalDamageSource.create("rainboom", source), 6);
|
||||||
});
|
});
|
||||||
PosHelper.getAllInRegionMutable(source.getOrigin(), effect_range).forEach(pos -> {
|
PosHelper.getAllInRegionMutable(source.getOrigin(), effect_range).forEach(pos -> {
|
||||||
BlockState state = source.getWorld().getBlockState(pos);
|
BlockState state = source.getWorld().getBlockState(pos);
|
||||||
|
|
|
@ -76,8 +76,7 @@ public class SiphoningSpell extends AbstractPlacedSpell {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void distributeHealth(Caster<?> source) {
|
private void distributeHealth(Caster<?> source) {
|
||||||
LivingEntity owner = source.getMaster();
|
DamageSource damage = MagicalDamageSource.create("drain", source);
|
||||||
DamageSource damage = MagicalDamageSource.create("drain", owner);
|
|
||||||
|
|
||||||
getTargets(source).forEach(e -> {
|
getTargets(source).forEach(e -> {
|
||||||
float maxHealthGain = e.getMaxHealth() - e.getHealth();
|
float maxHealthGain = e.getMaxHealth() - e.getHealth();
|
||||||
|
@ -114,7 +113,7 @@ public class SiphoningSpell extends AbstractPlacedSpell {
|
||||||
|
|
||||||
float attackAmount = Math.max(maxHealthGain / targets.size(), 0.5F);
|
float attackAmount = Math.max(maxHealthGain / targets.size(), 0.5F);
|
||||||
|
|
||||||
DamageSource damage = MagicalDamageSource.create("drain", owner);
|
DamageSource damage = MagicalDamageSource.create("drain", source);
|
||||||
|
|
||||||
float healthGain = 0;
|
float healthGain = 0;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@ import net.minecraft.entity.data.TrackedData;
|
||||||
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.network.Packet;
|
import net.minecraft.network.Packet;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.text.TranslatableText;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
@ -51,6 +53,15 @@ public class CastSpellEntity extends Entity implements Caster<LivingEntity> {
|
||||||
getDataTracker().startTracking(SPELL, Optional.empty());
|
getDataTracker().startTracking(SPELL, Optional.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Text getName() {
|
||||||
|
Entity master = getMaster();
|
||||||
|
if (master != null) {
|
||||||
|
return new TranslatableText("entity.unicopia.cast_spell.by", master.getName());
|
||||||
|
}
|
||||||
|
return super.getName();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
|
@ -20,6 +20,11 @@ public interface Equine<T extends Entity> extends NbtSerialisable, Tickable, Pro
|
||||||
|
|
||||||
void setSpecies(Race race);
|
void setSpecies(Race race);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the last magical entity to attack us.
|
||||||
|
*/
|
||||||
|
Entity getAttacker();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this player is fully invisible.
|
* Returns true if this player is fully invisible.
|
||||||
* Held items and other effects will be hidden as well.
|
* Held items and other effects will be hidden as well.
|
||||||
|
|
|
@ -41,6 +41,11 @@ public class ItemImpl implements Equine<ItemEntity>, Owned<ItemEntity> {
|
||||||
owner.getDataTracker().startTracking(ITEM_RACE, Race.HUMAN.ordinal());
|
owner.getDataTracker().startTracking(ITEM_RACE, Race.HUMAN.ordinal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity getAttacker() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean beforeUpdate() {
|
public boolean beforeUpdate() {
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,9 @@ import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
import com.minelittlepony.unicopia.network.EffectSync;
|
import com.minelittlepony.unicopia.network.EffectSync;
|
||||||
import com.minelittlepony.unicopia.projectile.ProjectileImpactListener;
|
import com.minelittlepony.unicopia.projectile.ProjectileImpactListener;
|
||||||
|
import com.minelittlepony.unicopia.util.MagicalDamageSource;
|
||||||
|
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.damage.DamageSource;
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
import net.minecraft.entity.data.TrackedData;
|
import net.minecraft.entity.data.TrackedData;
|
||||||
|
@ -33,6 +35,9 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
||||||
@Nullable
|
@Nullable
|
||||||
private Runnable landEvent;
|
private Runnable landEvent;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Entity attacker;
|
||||||
|
|
||||||
private int invinsibilityTicks;
|
private int invinsibilityTicks;
|
||||||
|
|
||||||
private final Enchantments enchants = new Enchantments(this);
|
private final Enchantments enchants = new Enchantments(this);
|
||||||
|
@ -108,6 +113,12 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public final Entity getAttacker() {
|
||||||
|
return attacker;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Boolean> onDamage(DamageSource source, float amount) {
|
public Optional<Boolean> onDamage(DamageSource source, float amount) {
|
||||||
|
|
||||||
|
@ -117,6 +128,13 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (source instanceof MagicalDamageSource) {
|
||||||
|
Entity attacker = ((MagicalDamageSource)source).getSpell();
|
||||||
|
if (attacker != null) {
|
||||||
|
this.attacker = attacker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.minelittlepony.unicopia.mixin;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.Owned;
|
||||||
|
import com.minelittlepony.unicopia.entity.Equine;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.text.TranslatableText;
|
||||||
|
|
||||||
|
@Mixin(DamageSource.class)
|
||||||
|
abstract class MixinDamageSource {
|
||||||
|
@Inject(method = "getDeathMessage", at = @At("RETURN"), cancellable = true)
|
||||||
|
private void onGetDeathMessage(LivingEntity entity, CallbackInfoReturnable<Text> info) {
|
||||||
|
Equine<?> eq = Equine.of(entity);
|
||||||
|
@Nullable
|
||||||
|
Entity attacker = eq == null ? null : eq.getAttacker();
|
||||||
|
DamageSource self = (DamageSource)(Object)this;
|
||||||
|
|
||||||
|
if (attacker != null) {
|
||||||
|
Entity prime = entity.getPrimeAdversary();
|
||||||
|
if (prime != null && !(attacker instanceof Owned<?> && ((Owned<?>)attacker).getMaster() == prime)) {
|
||||||
|
info.setReturnValue(new TranslatableText("death.attack.generic.and_also", info.getReturnValue(), attacker.getDisplayName()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.setReturnValue(new TranslatableText("death.attack." + self.getName() + ".player", entity.getDisplayName(), attacker.getDisplayName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,8 @@ import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.damage.DamageSource;
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
|
@ -15,7 +17,7 @@ import net.minecraft.text.TranslatableText;
|
||||||
|
|
||||||
public class MagicalDamageSource extends EntityDamageSource {
|
public class MagicalDamageSource extends EntityDamageSource {
|
||||||
|
|
||||||
public static final DamageSource EXHAUSTION = new MagicalDamageSource("magical_exhaustion", true, true);
|
public static final DamageSource EXHAUSTION = new MagicalDamageSource("magical_exhaustion", null, true, true);
|
||||||
public static final DamageSource FOOD_POISONING = mundane("food_poisoning");
|
public static final DamageSource FOOD_POISONING = mundane("food_poisoning");
|
||||||
public static final DamageSource TRIBE_SWAP = mundane("tribe_swap");
|
public static final DamageSource TRIBE_SWAP = mundane("tribe_swap");
|
||||||
public static final DamageSource ZAP_APPLE = create("zap");
|
public static final DamageSource ZAP_APPLE = create("zap");
|
||||||
|
@ -25,19 +27,26 @@ public class MagicalDamageSource extends EntityDamageSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DamageSource create(String type) {
|
public static DamageSource create(String type) {
|
||||||
return new MagicalDamageSource(type, false, false);
|
return new MagicalDamageSource(type, null, null, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DamageSource create(String type, LivingEntity source) {
|
public static DamageSource create(String type, LivingEntity source) {
|
||||||
return new MagicalDamageSource(type, source, false, false);
|
return new MagicalDamageSource(type, source, null, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MagicalDamageSource(String type, boolean direct, boolean unblockable) {
|
public static DamageSource create(String type, Caster<?> caster) {
|
||||||
this(type, null, direct, unblockable);
|
return new MagicalDamageSource(type, caster.getMaster(), caster.getEntity(), false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MagicalDamageSource(String type, @Nullable Entity source, boolean direct, boolean unblockable) {
|
private Entity spell;
|
||||||
|
|
||||||
|
protected MagicalDamageSource(String type, @Nullable Entity spell, boolean direct, boolean unblockable) {
|
||||||
|
this(type, null, spell, direct, unblockable);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MagicalDamageSource(String type, @Nullable Entity source, @Nullable Entity spell, boolean direct, boolean unblockable) {
|
||||||
super(type, source);
|
super(type, source);
|
||||||
|
this.spell = spell;
|
||||||
setUsesMagic();
|
setUsesMagic();
|
||||||
if (direct) {
|
if (direct) {
|
||||||
setBypassesArmor();
|
setBypassesArmor();
|
||||||
|
@ -47,6 +56,11 @@ public class MagicalDamageSource extends EntityDamageSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Entity getSpell() {
|
||||||
|
return spell;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Text getDeathMessage(LivingEntity target) {
|
public Text getDeathMessage(LivingEntity target) {
|
||||||
|
|
||||||
|
@ -56,22 +70,23 @@ public class MagicalDamageSource extends EntityDamageSource {
|
||||||
params.add(target.getDisplayName());
|
params.add(target.getDisplayName());
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
Entity attacker = source instanceof LivingEntity ? source : target.getPrimeAdversary();
|
Entity attacker = source != null ? source : target.getPrimeAdversary();
|
||||||
|
|
||||||
if (attacker instanceof LivingEntity) {
|
if (attacker != null) {
|
||||||
if (attacker == target) {
|
if (attacker == target) {
|
||||||
basic += ".self";
|
basic += ".self";
|
||||||
} else {
|
} else {
|
||||||
basic += ".attacker";
|
basic += ".attacker";
|
||||||
params.add(((LivingEntity)attacker).getDisplayName());
|
params.add(attacker.getDisplayName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack item = ((LivingEntity)attacker).getMainHandStack();
|
ItemStack item = attacker instanceof LivingEntity ? ((LivingEntity)attacker).getMainHandStack() : ItemStack.EMPTY;
|
||||||
|
|
||||||
if (!item.isEmpty() && item.hasCustomName()) {
|
if (!item.isEmpty() && item.hasCustomName()) {
|
||||||
basic += ".item";
|
basic += ".item";
|
||||||
params.add(item.toHoverableText());
|
params.add(item.toHoverableText());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return new TranslatableText(basic, params.toArray());
|
return new TranslatableText(basic, params.toArray());
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,9 @@
|
||||||
"item.unicopia.music_disc_funk": "Music Disc",
|
"item.unicopia.music_disc_funk": "Music Disc",
|
||||||
"item.unicopia.music_disc_funk.desc": "funk, just funk",
|
"item.unicopia.music_disc_funk.desc": "funk, just funk",
|
||||||
|
|
||||||
|
"entity.unicopia.cast_spell": "Cast Spell",
|
||||||
|
"entity.unicopia.cast_spell.by": "a spell cast by %s",
|
||||||
|
|
||||||
"unicopia.effect.tribe.stage.initial": "It appears to have no effect.",
|
"unicopia.effect.tribe.stage.initial": "It appears to have no effect.",
|
||||||
"unicopia.effect.tribe.stage.crawling": "You feel the skin crawling on your back.",
|
"unicopia.effect.tribe.stage.crawling": "You feel the skin crawling on your back.",
|
||||||
"unicopia.effect.tribe.stage.determination": "As your bones realign you are filled determination.",
|
"unicopia.effect.tribe.stage.determination": "As your bones realign you are filled determination.",
|
||||||
|
@ -272,12 +275,16 @@
|
||||||
"unicopia.race.bat": "Bat Pony",
|
"unicopia.race.bat": "Bat Pony",
|
||||||
"unicopia.race.bat.alt": "Bat Ponies",
|
"unicopia.race.bat.alt": "Bat Ponies",
|
||||||
|
|
||||||
|
"death.attack.generic.and_also": "%1$s and %2$s",
|
||||||
"death.attack.tribe_swap": "%1$s was reborn into a different tribe",
|
"death.attack.tribe_swap": "%1$s was reborn into a different tribe",
|
||||||
"death.attack.magical_exhaustion": "%1$s exhausted themselves",
|
"death.attack.magical_exhaustion": "%1$s exhausted themselves",
|
||||||
"death.attack.alicorn_amulet": "%1$s was driven insane",
|
"death.attack.alicorn_amulet": "%1$s was driven insane",
|
||||||
"death.attack.darkness": "%1$s went missing",
|
"death.attack.darkness": "%1$s went missing",
|
||||||
"death.attack.feed": "%1$s was drained of all life",
|
"death.attack.feed": "%1$s was drained of all life",
|
||||||
"death.attack.feed.attacker": "%1$s died to feed %2$s",
|
"death.attack.feed.attacker": "%1$s died to feed %2$s",
|
||||||
|
"death.attack.drain": "%1$s was drained of all life",
|
||||||
|
"death.attack.drain.self": "%1$s was killed by their own spell",
|
||||||
|
"death.attack.drain.attacker": "%1$s was killed by a spell cast by %2$s",
|
||||||
"death.attack.eeee": "%1$s was firghtened to death",
|
"death.attack.eeee": "%1$s was firghtened to death",
|
||||||
"death.attack.eeee.attacker": "%2$s scared %1$s",
|
"death.attack.eeee.attacker": "%2$s scared %1$s",
|
||||||
"death.attack.eeee.attacker.item": "%1$s was frightened to death by %2$s using %3$s",
|
"death.attack.eeee.attacker.item": "%1$s was frightened to death by %2$s using %3$s",
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
"MixinBlockEntity",
|
"MixinBlockEntity",
|
||||||
"MixinBlockItem",
|
"MixinBlockItem",
|
||||||
"MixinBrain",
|
"MixinBrain",
|
||||||
|
"MixinDamageSource",
|
||||||
"MixinFallingBlock",
|
"MixinFallingBlock",
|
||||||
"MixinItem",
|
"MixinItem",
|
||||||
"MixinItemEntity",
|
"MixinItemEntity",
|
||||||
|
|
Loading…
Reference in a new issue