Skip to content

Commit

Permalink
Version 1.9.0
Browse files Browse the repository at this point in the history
 * Assist take-off by setting glide when a player fires
   a rocket while in the air and wearing unbroken elytra.
   This mitigates overly the harsh NCP SurvivalFly check.
 * Refactor to combine similar elytra wearing checks.
  • Loading branch information
totemo committed Sep 29, 2017
1 parent da92b17 commit af7b985
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 54 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>io.totemo</groupId>
<name>WingCommander</name>
<artifactId>${project.name}</artifactId>
<version>1.8.0</version>
<version>1.9.0</version>
<packaging>jar</packaging>
<description>Enables powered flight with elytra.</description>
<url>https://github.com/totemo/${project.name}</url>
Expand Down
64 changes: 36 additions & 28 deletions src/io/totemo/wingcommander/PlayerState.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ public PlayerState(Player player, YamlConfiguration config) {
*/
public void onTick() {
// During take-off, force glide.
long now = System.currentTimeMillis();
if (now - _takeOffTime < WingCommander.CONFIG.TAKEOFF_GLIDE_MILLIS) {
if (isTakingOff()) {
_player.setGliding(true);
}

Expand All @@ -78,8 +77,8 @@ public void onCrouch() {
long now = System.currentTimeMillis();
if (now - _lastCrouchTime < WingCommander.CONFIG.TAKEOFF_TAP_MILLIS) {
_lastCrouchTime = 0;
_takeOffTime = now;
if (!areElytraBroken()) {
setTakingOff();
if (WingCommander.isWearingElytra(_player, true)) {
_player.setVelocity(new Vector(0, WingCommander.CONFIG.ACCELERATION_TAKEOFF_VERTICAL, 0));
}
accelerate(WingCommander.CONFIG.ACCELERATION_TAKEOFF_LOOK);
Expand All @@ -89,6 +88,28 @@ public void onCrouch() {
}
} // onCrouch

// ------------------------------------------------------------------------
/**
* Signify that the player has initiated a take-off.
*
* The start time of the take-off is recorded, and glide is forced for the
* configured time period thereafter in {@link PlayerState#onTick()}.
*/
public void setTakingOff() {
_takeOffTime = System.currentTimeMillis();
}

// ------------------------------------------------------------------------
/**
* Return true if the player is still in the time-limited take-off state.
*
* @return true if the player is still in the time-limited take-off state.
*/
public boolean isTakingOff() {
long now = System.currentTimeMillis();
return (now - _takeOffTime < WingCommander.CONFIG.TAKEOFF_GLIDE_MILLIS);
}

// ------------------------------------------------------------------------
/**
* Set or toggle visibility of the altimeter.
Expand Down Expand Up @@ -190,7 +211,7 @@ public void save(YamlConfiguration config) {
*
* @param config the configuration from which player preferences are loaded.
*/
protected void load(YamlConfiguration config) {
public void load(YamlConfiguration config) {
ConfigurationSection section = config.getConfigurationSection(_player.getUniqueId().toString());
if (section == null) {
section = config.createSection(_player.getUniqueId().toString());
Expand Down Expand Up @@ -283,21 +304,6 @@ protected void checkVacuumSuffocation() {
}
}

// ------------------------------------------------------------------------
/**
* Return true if the player is not wearing eltra, or if they are too
* damaged to glide.
*
* @return true if the player is not wearing eltra, or if they are too
* damaged to glide.
*/
protected boolean areElytraBroken() {
ItemStack chest = _player.getEquipment().getChestplate();
return chest == null ||
chest.getType() != Material.ELYTRA ||
Material.ELYTRA.getMaxDurability() - chest.getDurability() < 1;
}

// ------------------------------------------------------------------------
/**
* Boost the player's velocity in the player's look direction, but limit the
Expand Down Expand Up @@ -328,14 +334,9 @@ protected void accelerate(double acceleration) {
float speedFraction = (float) (Math.max(0.0, velocity.dot(look)) / WingCommander.CONFIG.MAX_VELOCITY);
float pitch = 0.5f + 1.5f * speedFraction;

if (areElytraBroken()) {
loc.getWorld().playSound(loc, WingCommander.CONFIG.BROKEN_SOUND,
WingCommander.CONFIG.BROKEN_VOLUME, pitch);
if (WingCommander.CONFIG.BROKEN_GLIDE) {
_player.setGliding(true);
_player.setFallDistance(Math.max(0, _player.getFallDistance() - WingCommander.CONFIG.BROKEN_GLIDE_FALL_REDUCTION));
}
} else {
// Method precondition is "wearing elytra irrespective of durability".
// Check for unbroken elytra.
if (WingCommander.isWearingElytra(_player, true)) {
_player.setGliding(true);

Vector boost = look;
Expand Down Expand Up @@ -363,6 +364,13 @@ protected void accelerate(double acceleration) {
loc.getWorld().playSound(loc, WingCommander.CONFIG.EXHAUST_SOUND,
WingCommander.CONFIG.EXHAUST_VOLUME, pitch);
}
} else {
loc.getWorld().playSound(loc, WingCommander.CONFIG.BROKEN_SOUND,
WingCommander.CONFIG.BROKEN_VOLUME, pitch);
if (WingCommander.CONFIG.BROKEN_GLIDE) {
_player.setGliding(true);
_player.setFallDistance(Math.max(0, _player.getFallDistance() - WingCommander.CONFIG.BROKEN_GLIDE_FALL_REDUCTION));
}
}
} // accelerate

Expand Down
66 changes: 41 additions & 25 deletions src/io/totemo/wingcommander/WingCommander.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
Expand Down Expand Up @@ -140,72 +141,87 @@ public void onPlayerToggleSneak(PlayerToggleSneakEvent event) {

// ------------------------------------------------------------------------
/**
* Handle player interactions - launch TNT if permitted and gliding.
* Handle player interactions:
* <ul>
* <li>Launch TNT if permitted and gliding.</li>
* <li>Set gliding if player right clicks a rocket while in the air and
* wearing elytra, to compensate for NCP's interference.</li>
* </ul>
*/
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();

// Check permissions
if (!player.hasPermission("wingcommander.tnt")) {
return;
}

// Only throw TNT if gliding
if (!player.isGliding()) {
return;
}

// Only handle left and right click air events
Action action = event.getAction();
if (action != Action.LEFT_CLICK_AIR && action != Action.RIGHT_CLICK_AIR) {
return;
}

// See if there is TNT in our hand
PlayerInventory inventory = player.getInventory();
ItemStack stack = inventory.getItemInMainHand();
if (stack.getType() != Material.TNT) {

// Assisted takeoff if wearing unbroken elytra.
if (action == Action.RIGHT_CLICK_AIR &&
stack.getType() == Material.FIREWORK &&
!player.isOnGround() &&
isWearingElytra(player, true)) {

// Player must be in air, not water (to be like vanilla).
Block feetBlock = player.getLocation().getBlock();
if (feetBlock != null && feetBlock.getType() == Material.AIR) {
PlayerState state = getState(player);
state.setTakingOff();
player.setGliding(true);
}
}

// Only throw TNT if permitted, gliding and holding TNT.
if (!player.hasPermission("wingcommander.tnt") ||
!player.isGliding() ||
stack.getType() != Material.TNT) {
return;
}

// Use up a TNT
// Use up a TNT.
int amount = stack.getAmount() - 1;
if (amount > 1) {
stack.setAmount(amount);
} else {
inventory.setItemInMainHand(null);
}

// Spawn TNT
// Spawn TNT.
Entity tnt = player.getWorld().spawnEntity(player.getLocation(), EntityType.PRIMED_TNT);

if (action == Action.LEFT_CLICK_AIR) {
// Throw the TNT forward
// Throw the TNT forward.
Vector TNTVelocity = player.getLocation().getDirection();
TNTVelocity.normalize();
TNTVelocity.multiply(WingCommander.CONFIG.TNT_THROW_SPEED);
TNTVelocity.add(player.getVelocity());
tnt.setVelocity(TNTVelocity);
} else if (action == Action.RIGHT_CLICK_AIR) {
// Drop the TNT with current velocity
// Drop the TNT with current velocity.
tnt.setVelocity(player.getVelocity());
}
} // OnPlayerInteract
} // onPlayerInteract

// ------------------------------------------------------------------------
/**
* Return true if the player is wearing elytra.
*
* Note that this method doesn't care whether the elytra are broken
* (durability <=1).
*
* @param player the player.
* @return true if the player is wearing elytra.
* @param requireDurability if true, the elytra must have durability > 0; if
* false, even broken elytra are considered valid.
* @return true if the player is wearing elytra, with durability if
* required.
*/
protected static boolean isWearingElytra(Player player) {
protected static boolean isWearingElytra(Player player, boolean requireDurability) {
ItemStack chest = player.getEquipment().getChestplate();
return chest != null && chest.getType() == Material.ELYTRA;
return chest != null &&
chest.getType() == Material.ELYTRA &&
(!requireDurability || Material.ELYTRA.getMaxDurability() - chest.getDurability() > 0);
}

// ------------------------------------------------------------------------
Expand All @@ -218,7 +234,7 @@ protected static boolean isWearingElytra(Player player) {
* powered flight.
*/
protected static boolean isFlightCapable(Player player) {
return isWearingElytra(player) && player.hasPermission("wingcommander.fly");
return isWearingElytra(player, false) && player.hasPermission("wingcommander.fly");
}

// ------------------------------------------------------------------------
Expand Down

0 comments on commit af7b985

Please sign in to comment.