added IronGolemAnimation #8
@@ -0,0 +1,113 @@
|
||||
package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.ironGolemAnimation;
|
||||
|
||||
import eu.mhsl.craftattack.spawn.core.Main;
|
||||
import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.Directional;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class IronGolemAnimation extends Appliance {
|
||||
record BlockChange(Block original, BlockData fakeBlock) {}
|
||||
|
||||
public void onGolemSpawn(IronGolem golem) {
|
||||
this.modifyGolem(golem, false);
|
||||
Location golemLocation = golem.getLocation();
|
||||
|
||||
BlockData bodyBlockData = Bukkit.createBlockData(Material.IRON_BLOCK);
|
||||
BlockData headBlockData = Bukkit.createBlockData(
|
||||
Material.CARVED_PUMPKIN,
|
||||
blockData -> ((Directional) blockData).setFacing(golem.getFacing())
|
||||
);
|
||||
Vector facingVector = golem.getFacing().getDirection().rotateAroundY(Math.toRadians(90));
|
||||
Block golemCenterBlock = golemLocation.getBlock().getRelative(BlockFace.UP);
|
||||
|
||||
List<BlockChange> buildBlocks = List.of(
|
||||
new BlockChange(golemCenterBlock.getRelative(BlockFace.DOWN), bodyBlockData),
|
||||
new BlockChange(golemCenterBlock, bodyBlockData),
|
||||
new BlockChange(golemCenterBlock.getLocation().add(facingVector).getBlock(), bodyBlockData),
|
||||
new BlockChange(golemCenterBlock.getLocation().add(facingVector.multiply(-1)).getBlock(), bodyBlockData),
|
||||
new BlockChange(golemCenterBlock.getRelative(BlockFace.UP), headBlockData)
|
||||
);
|
||||
|
||||
Collection<Player> viewers = golemLocation.getNearbyPlayers(golemLocation.getWorld().getViewDistance() * 16);
|
||||
BiConsumer<Location, BlockData> changeBlockForViewers = (location, blockData) -> {
|
||||
viewers.forEach(player -> player.sendBlockChange(location, blockData));
|
||||
golem.getWorld().playSound(
|
||||
location,
|
||||
blockData.getSoundGroup().getPlaceSound(),
|
||||
SoundCategory.BLOCKS,
|
||||
1f,
|
||||
1f
|
||||
);
|
||||
};
|
||||
for(int i = 0; i < buildBlocks.size(); i++) {
|
||||
BlockChange blockChange = buildBlocks.get(i);
|
||||
Bukkit.getScheduler().runTaskLater(
|
||||
Main.instance(),
|
||||
() -> changeBlockForViewers.accept(blockChange.original.getLocation(), blockChange.fakeBlock),
|
||||
6L * i
|
||||
);
|
||||
}
|
||||
|
||||
Consumer<List<BlockChange>> restoreBlockChanges = (blocks) -> {
|
||||
buildBlocks.forEach((blockChange) -> changeBlockForViewers.accept(
|
||||
blockChange.original().getLocation(),
|
||||
blockChange.original.getBlockData()
|
||||
));
|
||||
|
||||
this.modifyGolem(golem, true);
|
||||
this.spawnEffect(buildBlocks);
|
||||
};
|
||||
Bukkit.getScheduler().runTaskLater(
|
||||
Main.instance(),
|
||||
() -> restoreBlockChanges.accept(buildBlocks),
|
||||
6L * buildBlocks.size() + 2
|
||||
);
|
||||
}
|
||||
|
||||
private void spawnEffect(List<BlockChange> buildBlocks) {
|
||||
buildBlocks.forEach((blockChange) -> {
|
||||
World world = blockChange.original.getLocation().getWorld();
|
||||
world.spawnParticle(
|
||||
Particle.BLOCK,
|
||||
blockChange.original.getLocation().add(0.5, 0.5, 0.5),
|
||||
50,
|
||||
blockChange.fakeBlock
|
||||
);
|
||||
world.playSound(
|
||||
blockChange.original.getLocation(),
|
||||
blockChange.fakeBlock.getSoundGroup().getBreakSound(),
|
||||
SoundCategory.BLOCKS,
|
||||
1f,
|
||||
1f
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public void modifyGolem(IronGolem golem, boolean setVisible) {
|
||||
golem.setInvisible(!setVisible);
|
||||
golem.setInvulnerable(!setVisible);
|
||||
golem.setAI(setVisible);
|
||||
golem.setGravity(setVisible);
|
||||
golem.setCollidable(setVisible);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull List<Listener> listeners() {
|
||||
return List.of(
|
||||
new NaturalIronGolemSpawnEvent()
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.ironGolemAnimation;
|
||||
|
||||
import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
class NaturalIronGolemSpawnEvent extends ApplianceListener<IronGolemAnimation> {
|
||||
@EventHandler
|
||||
public void onGolemSpawn(CreatureSpawnEvent event) {
|
||||
if(!(event.getEntity() instanceof IronGolem golem)) return;
|
||||
if(event.getSpawnReason() != CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE) return;
|
||||
this.getAppliance().onGolemSpawn(golem);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user