Add Mage character class with snowball duplication ability
Introduced the Mage class as a playable character along with its creation logic, tools, and armor setup. Mages can duplicate snowballs upon throwing, creating multiple projectiles with varying directions and velocities to enhance gameplay dynamics. Updated relevant systems to accommodate this new class.
This commit is contained in:
parent
e8c015790f
commit
d11cf25fc8
|
|
@ -3,6 +3,7 @@ package com.alttd.ctf.events;
|
|||
import com.alttd.ctf.game.GameManager;
|
||||
import com.alttd.ctf.game.GamePhase;
|
||||
import com.alttd.ctf.game_class.GameClass;
|
||||
import com.alttd.ctf.game_class.implementations.Mage;
|
||||
import com.alttd.ctf.stats.Stat;
|
||||
import com.alttd.ctf.team.TeamPlayer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -35,7 +36,7 @@ public class SnowballEvent implements Listener {
|
|||
|
||||
@FunctionalInterface
|
||||
private interface SnowballThrownConsumer {
|
||||
void apply(Player shooter, TeamPlayer shooterTeamPlayer);
|
||||
void apply(Player shooter, TeamPlayer shooterTeamPlayer, Snowball snowball);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
|
@ -61,10 +62,13 @@ public class SnowballEvent implements Listener {
|
|||
|
||||
@EventHandler
|
||||
public void onSnowballThrown(ProjectileLaunchEvent event) {
|
||||
handleSnowballThrown(event, (shooter, shooterTeamPlayer) -> {
|
||||
handleSnowballThrown(event, (shooter, shooterTeamPlayer, snowball) -> {
|
||||
GameClass shooterClass = shooterTeamPlayer.getGameClass();
|
||||
shooter.setCooldown(Material.SNOWBALL, shooterClass.getThrowTickSpeed());
|
||||
shooterTeamPlayer.increaseStat(Stat.SNOWBALLS_THROWN);
|
||||
if (shooterClass instanceof Mage mage) {
|
||||
mage.duplicateSnowBalls(shooter, snowball);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +105,7 @@ public class SnowballEvent implements Listener {
|
|||
log.debug("The shooter that threw a snowball was not a team player");
|
||||
return;
|
||||
}
|
||||
consumer.apply(shooter, teamPlayer.get());
|
||||
consumer.apply(shooter, teamPlayer.get(), snowball);
|
||||
}
|
||||
|
||||
private void handleSnowballHit(EntityDamageByEntityEvent event, SnowballHitConsumer consumer) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
package com.alttd.ctf.game_class;
|
||||
|
||||
import com.alttd.ctf.game.GameManager;
|
||||
import com.alttd.ctf.game_class.creation.EngineerCreator;
|
||||
import com.alttd.ctf.game_class.creation.FighterCreator;
|
||||
import com.alttd.ctf.game_class.creation.TankCreator;
|
||||
import com.alttd.ctf.game_class.creation.TrapperCreator;
|
||||
import com.alttd.ctf.game_class.creation.*;
|
||||
import com.alttd.ctf.team.Team;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -27,6 +24,7 @@ public class GameClassRetrieval {
|
|||
gameClasses.add(TankCreator.createTank(team.getColor()));
|
||||
gameClasses.add(TrapperCreator.createTrapper(team.getColor()));
|
||||
gameClasses.add(EngineerCreator.createEngineer(team.getColor()));
|
||||
gameClasses.add(MageCreator.createMage(team.getColor()));
|
||||
return gameClasses;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
package com.alttd.ctf.game_class.creation;
|
||||
|
||||
import com.alttd.ctf.game_class.GameClass;
|
||||
import com.alttd.ctf.game_class.implementations.Fighter;
|
||||
import com.alttd.ctf.game_class.implementations.Mage;
|
||||
import com.alttd.ctf.team.TeamColor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionType;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
public class MageCreator {
|
||||
|
||||
private static final MiniMessage miniMessage = MiniMessage.miniMessage();
|
||||
|
||||
@Contract("_ -> new")
|
||||
public static @NotNull GameClass createMage(@NotNull TeamColor teamColor) {
|
||||
return new Mage(getArmor(), getTools(teamColor), getDisplayItem(teamColor),
|
||||
20, 100, 5);
|
||||
}
|
||||
|
||||
@Contract(value = " -> new", pure = true)
|
||||
private static @NotNull @Unmodifiable List<Material> getArmor() {
|
||||
return (List.of(Material.CHAINMAIL_BOOTS, Material.AIR, Material.AIR, Material.LEATHER_HELMET));
|
||||
}
|
||||
|
||||
@Contract("_ -> new")
|
||||
private static @NotNull @Unmodifiable List<ItemStack> getTools(@NotNull TeamColor teamColor) {
|
||||
return (List.of(getShovel(teamColor)));
|
||||
}
|
||||
|
||||
private static @NotNull ItemStack getShovel(@NotNull TeamColor teamColor) {
|
||||
ItemStack shovel = new ItemStack(Material.WOODEN_SHOVEL);
|
||||
ItemMeta meta = shovel.getItemMeta();
|
||||
meta.itemName(miniMessage.deserialize(String.format("<color:%s>Snow shovel</color>", teamColor.hex())));
|
||||
meta.setUnbreakable(true);
|
||||
meta.addEnchant(Enchantment.EFFICIENCY, 1, false);
|
||||
shovel.setItemMeta(meta);
|
||||
return shovel;
|
||||
}
|
||||
|
||||
private static @NotNull ItemStack getDisplayItem(@NotNull TeamColor teamColor) {
|
||||
ItemStack itemStack = new ItemStack(Material.IRON_SWORD);
|
||||
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||
itemMeta.displayName(miniMessage.deserialize(String.format("<color:%s>Mage</color>", teamColor.hex())));
|
||||
itemMeta.lore(List.of(
|
||||
miniMessage.deserialize("<gold>The Mage can throw many snowballs at once</gold>"),
|
||||
miniMessage.deserialize("<gold>But it has a long cooldown.</gold>")
|
||||
));
|
||||
itemStack.setItemMeta(itemMeta);
|
||||
return itemStack;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package com.alttd.ctf.game_class.implementations;
|
||||
|
||||
import com.alttd.ctf.game_class.GameClass;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Snowball;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
public class Mage extends GameClass {
|
||||
public Mage(@NotNull List<Material> armor, @NotNull List<ItemStack> tools, @NotNull ItemStack displayItem,
|
||||
double health, int throwTickSpeed, int damage) {
|
||||
super(armor, tools, displayItem, health, throwTickSpeed, damage);
|
||||
}
|
||||
|
||||
public void duplicateSnowBalls(Player shooter, Snowball snowball) {
|
||||
Location location = snowball.getLocation();
|
||||
PlayerInventory inventory = shooter.getInventory();
|
||||
ItemStack itemStack = inventory.getItemInMainHand();
|
||||
if (itemStack.getType() != Material.SNOWBALL) {
|
||||
ItemStack itemInOffHand = inventory.getItemInOffHand();
|
||||
if (itemInOffHand.getType() != Material.SNOWBALL) {
|
||||
log.warn("Unable to find snowballs in main/off hand");
|
||||
return;
|
||||
}
|
||||
itemStack = itemInOffHand;
|
||||
}
|
||||
if (itemStack.getAmount() <= 1) {
|
||||
return;
|
||||
}
|
||||
duplicate(shooter, location, snowball.getVelocity(), itemStack.getAmount() - 1);
|
||||
itemStack.setAmount(0);
|
||||
}
|
||||
|
||||
private void duplicate(@NotNull Player shooter, @NotNull Location location, @NotNull Vector velocity, int count) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
double offsetX = (Math.random() - 0.5) * 2;
|
||||
double offsetY = (Math.random() - 0.5) * 2;
|
||||
double offsetZ = (Math.random() - 0.5) * 2;
|
||||
|
||||
Location newLocation = location.clone().add(offsetX, offsetY, offsetZ);
|
||||
Snowball snowball = location.getWorld().spawn(newLocation, Snowball.class);
|
||||
|
||||
snowball.setShooter(shooter);
|
||||
|
||||
double velocityChangeX = (Math.random() - 0.5) * 0.2;
|
||||
double velocityChangeY = (Math.random() - 0.5) * 0.2;
|
||||
double velocityChangeZ = (Math.random() - 0.5) * 0.2;
|
||||
|
||||
Vector newVelocity = velocity.clone().add(new Vector(velocityChangeX, velocityChangeY, velocityChangeZ));
|
||||
|
||||
snowball.setVelocity(newVelocity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#Fri Feb 28 22:11:49 CET 2025
|
||||
buildNumber=80
|
||||
#Fri Feb 28 23:59:35 CET 2025
|
||||
buildNumber=83
|
||||
version=0.1
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user