Commit b57fd513 by Jonathan Thomas

New follow, flee, attack, and protect particles & sound effects. Protect now…

New follow, flee, attack, and protect particles & sound effects. Protect now auto sets friendship to 1 (if <= 0), to prevent entity from attacking and protecting at the same time. Passive entities no longer emit damage particles when attacking, they emit custom attack particles
parent 046084f0
Pipeline #12874 passed with stages
in 1 minute 55 seconds
...@@ -9,10 +9,13 @@ All notable changes to **CreatureChat** are documented in this file. The format ...@@ -9,10 +9,13 @@ All notable changes to **CreatureChat** are documented in this file. The format
### Added ### Added
- New friendship particles (hearts + fire) to indicate when friendship changes - New friendship particles (hearts + fire) to indicate when friendship changes
- Added sound effects for max friendship and max enemy - Added sound effects for max friendship and max enemy
- New follow, flee, attack, and protect particles & sound effects
### Changed ### Changed
- Entity chat data now separates messages and friendship by player - Entity chat data now separates messages and friendship by player
- Removed "pirate" speaking style and a few <non-response> outputs - Removed "pirate" speaking style and a few <non-response> outputs
- Passive entities no longer emit damage particles when attacking, they emit custom attack particles
- Protect now auto sets friendship to 1 (if <= 0), to prevent entity from attacking and protecting at the same time
### Fixed ### Fixed
- Fixed a regression caused by adding a "-forge" suffix to one of our builds - Fixed a regression caused by adding a "-forge" suffix to one of our builds
......
...@@ -28,6 +28,11 @@ public class ClientInit implements ClientModInitializer { ...@@ -28,6 +28,11 @@ public class ClientInit implements ClientModInitializer {
ParticleFactoryRegistry.getInstance().register(HEART_BIG_PARTICLE, CreatureParticleFactory::new); ParticleFactoryRegistry.getInstance().register(HEART_BIG_PARTICLE, CreatureParticleFactory::new);
ParticleFactoryRegistry.getInstance().register(FIRE_SMALL_PARTICLE, CreatureParticleFactory::new); ParticleFactoryRegistry.getInstance().register(FIRE_SMALL_PARTICLE, CreatureParticleFactory::new);
ParticleFactoryRegistry.getInstance().register(FIRE_BIG_PARTICLE, CreatureParticleFactory::new); ParticleFactoryRegistry.getInstance().register(FIRE_BIG_PARTICLE, CreatureParticleFactory::new);
ParticleFactoryRegistry.getInstance().register(ATTACK_PARTICLE, CreatureParticleFactory::new);
ParticleFactoryRegistry.getInstance().register(FLEE_PARTICLE, CreatureParticleFactory::new);
ParticleFactoryRegistry.getInstance().register(FOLLOW_ENEMY_PARTICLE, CreatureParticleFactory::new);
ParticleFactoryRegistry.getInstance().register(FOLLOW_FRIEND_PARTICLE, CreatureParticleFactory::new);
ParticleFactoryRegistry.getInstance().register(PROTECT_PARTICLE, CreatureParticleFactory::new);
ClientTickEvents.END_CLIENT_TICK.register(client -> { ClientTickEvents.END_CLIENT_TICK.register(client -> {
tickCounter++; tickCounter++;
......
...@@ -297,6 +297,11 @@ public class EntityChatData { ...@@ -297,6 +297,11 @@ public class EntityChatData {
EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, LeadPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, LeadPlayerGoal.class);
EntityBehaviorManager.addGoal(entity, followGoal, GoalPriority.FOLLOW_PLAYER); EntityBehaviorManager.addGoal(entity, followGoal, GoalPriority.FOLLOW_PLAYER);
if (playerData.friendship >= 0) {
ParticleEmitter.emitCreatureParticle((ServerWorld) entity.getWorld(), entity, FOLLOW_FRIEND_PARTICLE, 0.5, 1);
} else {
ParticleEmitter.emitCreatureParticle((ServerWorld) entity.getWorld(), entity, FOLLOW_ENEMY_PARTICLE, 0.5, 1);
}
} else if (behavior.getName().equals("UNFOLLOW")) { } else if (behavior.getName().equals("UNFOLLOW")) {
EntityBehaviorManager.removeGoal(entity, FollowPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, FollowPlayerGoal.class);
...@@ -310,6 +315,7 @@ public class EntityChatData { ...@@ -310,6 +315,7 @@ public class EntityChatData {
EntityBehaviorManager.removeGoal(entity, ProtectPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, ProtectPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, LeadPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, LeadPlayerGoal.class);
EntityBehaviorManager.addGoal(entity, fleeGoal, GoalPriority.FLEE_PLAYER); EntityBehaviorManager.addGoal(entity, fleeGoal, GoalPriority.FLEE_PLAYER);
ParticleEmitter.emitCreatureParticle((ServerWorld) entity.getWorld(), entity, FLEE_PARTICLE, 0.5, 1);
} else if (behavior.getName().equals("UNFLEE")) { } else if (behavior.getName().equals("UNFLEE")) {
EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class); EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class);
...@@ -322,13 +328,19 @@ public class EntityChatData { ...@@ -322,13 +328,19 @@ public class EntityChatData {
EntityBehaviorManager.removeGoal(entity, ProtectPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, ProtectPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, LeadPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, LeadPlayerGoal.class);
EntityBehaviorManager.addGoal(entity, attackGoal, GoalPriority.ATTACK_PLAYER); EntityBehaviorManager.addGoal(entity, attackGoal, GoalPriority.ATTACK_PLAYER);
ParticleEmitter.emitCreatureParticle((ServerWorld) entity.getWorld(), entity, FLEE_PARTICLE, 0.5, 1);
} else if (behavior.getName().equals("PROTECT")) { } else if (behavior.getName().equals("PROTECT")) {
if (playerData.friendship <= 0) {
// force friendship to prevent entity from attacking player when protecting
playerData.friendship = 1;
}
ProtectPlayerGoal protectGoal = new ProtectPlayerGoal(player, entity, 1.0); ProtectPlayerGoal protectGoal = new ProtectPlayerGoal(player, entity, 1.0);
EntityBehaviorManager.removeGoal(entity, TalkPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, TalkPlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class); EntityBehaviorManager.removeGoal(entity, FleePlayerGoal.class);
EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, AttackPlayerGoal.class);
EntityBehaviorManager.addGoal(entity, protectGoal, GoalPriority.PROTECT_PLAYER); EntityBehaviorManager.addGoal(entity, protectGoal, GoalPriority.PROTECT_PLAYER);
ParticleEmitter.emitCreatureParticle((ServerWorld) entity.getWorld(), entity, PROTECT_PARTICLE, 0.5, 1);
} else if (behavior.getName().equals("UNPROTECT")) { } else if (behavior.getName().equals("UNPROTECT")) {
EntityBehaviorManager.removeGoal(entity, ProtectPlayerGoal.class); EntityBehaviorManager.removeGoal(entity, ProtectPlayerGoal.class);
......
...@@ -6,13 +6,14 @@ import net.minecraft.entity.mob.Angerable; ...@@ -6,13 +6,14 @@ import net.minecraft.entity.mob.Angerable;
import net.minecraft.entity.mob.HostileEntity; import net.minecraft.entity.mob.HostileEntity;
import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.passive.GolemEntity; import net.minecraft.entity.passive.GolemEntity;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import java.util.EnumSet; import java.util.EnumSet;
import static com.owlmaddie.network.ServerPackets.ATTACK_PARTICLE;
/** /**
* The {@code AttackPlayerGoal} class instructs a Mob Entity to show aggression towards a target Entity. * The {@code AttackPlayerGoal} class instructs a Mob Entity to show aggression towards a target Entity.
* For passive entities like chickens (or hostile entities in creative mode), damage is simulated with particles. * For passive entities like chickens (or hostile entities in creative mode), damage is simulated with particles.
...@@ -94,11 +95,11 @@ public class AttackPlayerGoal extends PlayerBaseGoal { ...@@ -94,11 +95,11 @@ public class AttackPlayerGoal extends PlayerBaseGoal {
this.attackerEntity.playSound(SoundEvents.ENTITY_PLAYER_HURT, 1F, 1F); this.attackerEntity.playSound(SoundEvents.ENTITY_PLAYER_HURT, 1F, 1F);
// Spawn red particles to simulate 'injury' // Spawn red particles to simulate 'injury'
((ServerWorld) this.attackerEntity.getWorld()).spawnParticles(ParticleTypes.DAMAGE_INDICATOR, ((ServerWorld) this.attackerEntity.getWorld()).spawnParticles(ATTACK_PARTICLE,
this.targetEntity.getX(), this.targetEntity.getX(),
this.targetEntity.getBodyY(0.5D), this.targetEntity.getBodyY(0.5D),
this.targetEntity.getZ(), this.targetEntity.getZ(),
10, // number of particles 4, // number of particles
0.1, 0.1, 0.1, 0.2); // speed and randomness 0.1, 0.1, 0.1, 0.2); // speed and randomness
} }
......
...@@ -62,6 +62,11 @@ public class ServerPackets { ...@@ -62,6 +62,11 @@ public class ServerPackets {
public static final DefaultParticleType HEART_BIG_PARTICLE = FabricParticleTypes.simple(); public static final DefaultParticleType HEART_BIG_PARTICLE = FabricParticleTypes.simple();
public static final DefaultParticleType FIRE_SMALL_PARTICLE = FabricParticleTypes.simple(); public static final DefaultParticleType FIRE_SMALL_PARTICLE = FabricParticleTypes.simple();
public static final DefaultParticleType FIRE_BIG_PARTICLE = FabricParticleTypes.simple(); public static final DefaultParticleType FIRE_BIG_PARTICLE = FabricParticleTypes.simple();
public static final DefaultParticleType ATTACK_PARTICLE = FabricParticleTypes.simple();
public static final DefaultParticleType FLEE_PARTICLE = FabricParticleTypes.simple();
public static final DefaultParticleType FOLLOW_FRIEND_PARTICLE = FabricParticleTypes.simple();
public static final DefaultParticleType FOLLOW_ENEMY_PARTICLE = FabricParticleTypes.simple();
public static final DefaultParticleType PROTECT_PARTICLE = FabricParticleTypes.simple();
public static void register() { public static void register() {
// Register custom particles // Register custom particles
...@@ -69,6 +74,11 @@ public class ServerPackets { ...@@ -69,6 +74,11 @@ public class ServerPackets {
Registry.register(Registries.PARTICLE_TYPE, new Identifier("creaturechat", "heart_big"), HEART_BIG_PARTICLE); Registry.register(Registries.PARTICLE_TYPE, new Identifier("creaturechat", "heart_big"), HEART_BIG_PARTICLE);
Registry.register(Registries.PARTICLE_TYPE, new Identifier("creaturechat", "fire_small"), FIRE_SMALL_PARTICLE); Registry.register(Registries.PARTICLE_TYPE, new Identifier("creaturechat", "fire_small"), FIRE_SMALL_PARTICLE);
Registry.register(Registries.PARTICLE_TYPE, new Identifier("creaturechat", "fire_big"), FIRE_BIG_PARTICLE); Registry.register(Registries.PARTICLE_TYPE, new Identifier("creaturechat", "fire_big"), FIRE_BIG_PARTICLE);
Registry.register(Registries.PARTICLE_TYPE, new Identifier("creaturechat", "attack"), ATTACK_PARTICLE);
Registry.register(Registries.PARTICLE_TYPE, new Identifier("creaturechat", "flee"), FLEE_PARTICLE);
Registry.register(Registries.PARTICLE_TYPE, new Identifier("creaturechat", "follow_enemy"), FOLLOW_ENEMY_PARTICLE);
Registry.register(Registries.PARTICLE_TYPE, new Identifier("creaturechat", "follow_friend"), FOLLOW_FRIEND_PARTICLE);
Registry.register(Registries.PARTICLE_TYPE, new Identifier("creaturechat", "protect"), PROTECT_PARTICLE);
// Handle packet for Greeting // Handle packet for Greeting
ServerPlayNetworking.registerGlobalReceiver(PACKET_C2S_GREETING, (server, player, handler, buf, responseSender) -> { ServerPlayNetworking.registerGlobalReceiver(PACKET_C2S_GREETING, (server, player, handler, buf, responseSender) -> {
......
...@@ -7,8 +7,7 @@ import net.minecraft.sound.SoundCategory; ...@@ -7,8 +7,7 @@ import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import static com.owlmaddie.network.ServerPackets.FIRE_BIG_PARTICLE; import static com.owlmaddie.network.ServerPackets.*;
import static com.owlmaddie.network.ServerPackets.HEART_BIG_PARTICLE;
public class ParticleEmitter { public class ParticleEmitter {
...@@ -32,6 +31,10 @@ public class ParticleEmitter { ...@@ -32,6 +31,10 @@ public class ParticleEmitter {
world.playSound(entity, entity.getBlockPos(), SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.PLAYERS, 0.4F, 1.0F); world.playSound(entity, entity.getBlockPos(), SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.PLAYERS, 0.4F, 1.0F);
} else if (particleType.equals(FIRE_BIG_PARTICLE) && count > 1) { } else if (particleType.equals(FIRE_BIG_PARTICLE) && count > 1) {
world.playSound(entity, entity.getBlockPos(), SoundEvents.ITEM_AXE_STRIP, SoundCategory.PLAYERS, 0.8F, 1.0F); world.playSound(entity, entity.getBlockPos(), SoundEvents.ITEM_AXE_STRIP, SoundCategory.PLAYERS, 0.8F, 1.0F);
} else if (particleType.equals(FOLLOW_FRIEND_PARTICLE) || particleType.equals(FOLLOW_ENEMY_PARTICLE)) {
world.playSound(entity, entity.getBlockPos(), SoundEvents.BLOCK_AMETHYST_BLOCK_PLACE, SoundCategory.PLAYERS, 0.8F, 1.0F);
} else if (particleType.equals(PROTECT_PARTICLE)) {
world.playSound(entity, entity.getBlockPos(), SoundEvents.BLOCK_BEACON_POWER_SELECT, SoundCategory.PLAYERS, 0.8F, 1.0F);
} }
} }
} }
\ No newline at end of file
{
"textures": [
"creaturechat:attack"
]
}
\ No newline at end of file
{
"textures": [
"creaturechat:flee"
]
}
\ No newline at end of file
{
"textures": [
"creaturechat:follow_enemy"
]
}
\ No newline at end of file
{
"textures": [
"creaturechat:follow_friend"
]
}
\ No newline at end of file
{
"textures": [
"creaturechat:protect"
]
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment