add headless horseman gizmo (#43)

* add headless horseman gizmo

* remove remaining references after restoring player

* redo ugly methods

* add display for 'non-priced' items

* oopsie, missed a spotsie
This commit is contained in:
Potato 2017-10-27 06:41:07 +08:00 committed by amactus
parent 4a5dcfe2be
commit a07f30e4bb
6 changed files with 197 additions and 2 deletions

View File

@ -25,6 +25,10 @@ gizmo.popper.raindropsResult = popped a total of {0} players
# {0} = number of players rocketed
gizmo.rocket.raindropsResult = rocketed a total of {0} players
gizmo.headlesshorseman.name = The Headless Horseman
gizmo.headlesshorseman.description = You have been taken over by the darkness...
gizmo.specialEvent = This gizmo is unlocked by completing the Halloween Event!
gizmo.currentlyPurchasing = You are currently purchasing this gizmo, please wait
# {0} = Name of network

View File

@ -10,6 +10,7 @@ import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import tc.oc.lobby.bukkit.LobbyTranslations;
import tc.oc.lobby.bukkit.gizmos.halloween.HeadlessHorsemanGizmo;
import tc.oc.lobby.bukkit.listeners.RaindropsListener;
public abstract class Gizmo implements Listener {
@ -60,7 +61,9 @@ public abstract class Gizmo implements Listener {
}
public String getCostText(Player player) {
if(this.getClass().isInstance(Gizmos.purchasingMap.get(player))) {
if (this.getClass().isInstance(HeadlessHorsemanGizmo.class)) {
return ChatColor.YELLOW + LobbyTranslations.get().t("gizmo.specialEvent", player);
} else if(this.getClass().isInstance(Gizmos.purchasingMap.get(player))) {
return ChatColor.GOLD + LobbyTranslations.get().t("gizmo.purchasing", player);
} else if(this.ownsGizmo(player)) {
return ChatColor.GREEN + LobbyTranslations.get().t("gizmo.purchased", player);

View File

@ -20,6 +20,7 @@ import tc.oc.lobby.bukkit.LobbyTranslations;
import tc.oc.lobby.bukkit.gizmos.chicken.ChickenGizmo;
import tc.oc.lobby.bukkit.gizmos.empty.EmptyGizmo;
import tc.oc.lobby.bukkit.gizmos.gun.GunGizmo;
import tc.oc.lobby.bukkit.gizmos.halloween.HeadlessHorsemanGizmo;
import tc.oc.lobby.bukkit.gizmos.launcher.LauncherGizmo;
import tc.oc.lobby.bukkit.gizmos.popper.PopperGizmo;
import tc.oc.lobby.bukkit.gizmos.rocket.RocketGizmo;
@ -31,8 +32,10 @@ public class Gizmos implements Listener {
public static GunGizmo gunGizmo = new GunGizmo("Raindrop Gun", ChatColor.AQUA.toString(), "Gift raindrops with a punch :D", Material.IRON_HOE, 7500);
public static ChickenGizmo chickenGizmo = new ChickenGizmo("Chickenifier5000", ChatColor.YELLOW.toString(), "bok B'GAWK", Material.EGG, 10000);
public static LauncherGizmo launcherGizmo = new LauncherGizmo("Murica", ChatColor.RED.toString(), "Show your pride!", Material.FEATHER, 17760);
//TODO: Replace cost and handle permissions
public static HeadlessHorsemanGizmo headlessHorsemanGizmo = new HeadlessHorsemanGizmo("The Headless Horseman", ChatColor.RED.toString(), "You have been taken over by the darkness...", Material.NETHER_STAR, 999999);
public static final List<Gizmo> gizmos = Lists.newArrayList(emptyGizmo, popperGizmo, rocketGizmo, gunGizmo, chickenGizmo, launcherGizmo);
public static final List<Gizmo> gizmos = Lists.newArrayList(emptyGizmo, popperGizmo, rocketGizmo, gunGizmo, chickenGizmo, launcherGizmo, headlessHorsemanGizmo);
public static Map<Player, Gizmo> gizmoMap = Maps.newHashMap();
public static Map<Player, Gizmo> purchasingMap = Maps.newHashMap();

View File

@ -0,0 +1,46 @@
package tc.oc.lobby.bukkit.gizmos.halloween;
import com.google.common.collect.ImmutableList;
import org.bukkit.Location;
import org.bukkit.entity.AbstractHorse;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EntityEquipment;
import tc.oc.commons.core.util.Optionals;
/**
* Simplistic implementation of PGM's EntityMutation
*
* TODO: refactor methods, possibly categorize types of gizmos
*/
public class HeadlessHorse {
private Player viewer;
private AbstractHorse horse;
protected HeadlessHorse(Player viewer) {
this.viewer = viewer;
}
protected AbstractHorse spawn(Location location, Class<AbstractHorse> horse) {
AbstractHorse entity = viewer.getWorld().spawn(location, horse);
this.horse = entity;
Optionals.cast(horse, LivingEntity.class).ifPresent(living -> {
living.setRemoveWhenFarAway(true);
living.setCollidable(false);
living.setCanPickupItems(false);
living.setInvulnerable(true);
EntityEquipment entityEquipment = living.getEquipment();
entityEquipment.setHelmetDropChance(0);
entityEquipment.setChestplateDropChance(0);
entityEquipment.setLeggingsDropChance(0);
entityEquipment.setBootsDropChance(0);
living.setPassengers(ImmutableList.of(viewer));
});
return entity;
}
public void despawn() {
horse.ejectAll();
horse.remove();
}
}

View File

@ -0,0 +1,60 @@
package tc.oc.lobby.bukkit.gizmos.halloween;
import com.google.common.collect.ImmutableMap;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.AbstractHorse;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import tc.oc.commons.bukkit.inventory.ArmorType;
import tc.oc.commons.bukkit.inventory.Slot;
import tc.oc.commons.bukkit.item.ItemBuilder;
public class HeadlessHorseman {
private final static ImmutableMap<Slot, ItemStack> ARMOR_MAP = ImmutableMap.of(
Slot.Armor.forType(ArmorType.HELMET), new ItemBuilder().material(Material.JACK_O_LANTERN).get(),
Slot.Armor.forType(ArmorType.CHESTPLATE), new ItemBuilder().material(Material.LEATHER_CHESTPLATE).get(),
Slot.Armor.forType(ArmorType.LEGGINGS), new ItemBuilder().material(Material.LEATHER_LEGGINGS).get(),
Slot.Armor.forType(ArmorType.BOOTS), new ItemBuilder().material(Material.LEATHER_BOOTS).get());
private final static EntityType HORSE_TYPE = EntityType.SKELETON_HORSE;
private final Player viewer;
private final HeadlessHorse headlessHorse;
private static final Color ARMOR_COLOR = Color.fromRGB(84, 5, 40);
public HeadlessHorseman(Player viewer) {
this.viewer = viewer;
this.headlessHorse = new HeadlessHorse(viewer);
this.mutate();
}
private void mutate() {
headlessHorse.spawn(viewer.getLocation(), (Class<AbstractHorse>) HORSE_TYPE.getEntityClass());
ARMOR_MAP.forEach(this::colorAndEquip);
viewer.playSound(viewer.getLocation(), Sound.ENTITY_SKELETON_HORSE_DEATH, 1.5f, 1.5f);
}
private void colorAndEquip(Slot slot, ItemStack item) {
ItemMeta meta = item.getItemMeta();
if (meta instanceof LeatherArmorMeta) {
LeatherArmorMeta armorMeta = (LeatherArmorMeta) meta;
armorMeta.setColor(ARMOR_COLOR);
item.setItemMeta(meta);
}
slot.putItem(viewer.getInventory(), item);
}
public void restore() {
headlessHorse.despawn();
viewer.getInventory().armor().clear();
viewer.playSound(viewer.getLocation(), Sound.ENTITY_ZOMBIE_VILLAGER_CURE, 1f, 1f);
}
public HeadlessHorse getHeadlessHorse() {
return headlessHorse;
}
}

View File

@ -0,0 +1,79 @@
package tc.oc.lobby.bukkit.gizmos.halloween;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitRunnable;
import tc.oc.lobby.bukkit.Lobby;
import tc.oc.lobby.bukkit.gizmos.Gizmo;
import tc.oc.lobby.bukkit.gizmos.Gizmos;
public class HeadlessHorsemanGizmo extends Gizmo implements Listener {
private Map<Player, HeadlessHorseman> mutated;
private Map<Player, HeadlessHorse> horseByPlayer;
public HeadlessHorsemanGizmo(String name, String prefix, String description, Material icon, int cost) {
super(name, prefix, description, icon, cost);
this.mutated = new HashMap<>();
this.horseByPlayer = new HashMap<>();
}
@Override
protected void initialize() {
Bukkit.getPluginManager().registerEvents(this, Lobby.get());
}
@EventHandler(ignoreCancelled = true)
public void onPlayerInteract(PlayerInteractEvent e) {
if(e.getAction() == Action.PHYSICAL
|| !(Gizmos.gizmoMap.get(e.getPlayer()) instanceof HeadlessHorsemanGizmo)
|| e.getItem() == null || e.getItem().getType() != this.getIcon()) return;
final Player player = e.getPlayer();
if(mutated.get(player) == null) {
HeadlessHorseman horseman = new HeadlessHorseman(player);
mutated.put(player, horseman);
horseByPlayer.put(player, horseman.getHeadlessHorse());
createEffect(player);
} else {
mutated.get(player).restore();
mutated.remove(player);
horseByPlayer.remove(player);
}
}
@EventHandler
public void onPlayerLeave(PlayerQuitEvent e) {
Player player = e.getPlayer();
mutated.remove(player);
horseByPlayer.get(player).despawn();
horseByPlayer.remove(player);
}
private void createEffect(Player viewer) {
new BukkitRunnable() {
@Override
public void run() {
Location location = viewer.getLocation();
if (mutated.get(viewer) == null || horseByPlayer.get(viewer) == null) cancel();
for(int i = 0; i < 360; i++) {
double radians = Math.toRadians(i);
double x = Math.cos(radians);
double z = Math.sin(radians);
location.add(x, 2.75, z);
location.getWorld().playEffect(location, Effect.SMOKE, 2);
location.subtract(x, 2.75, z);
}
}
}.runTaskTimer(Lobby.get(), 1 * 20, 5 * 20);
}
}