Last active
May 19, 2020 17:10
-
-
Save nineonefive/327a02b129c5e84a484eae1ec36abe5b to your computer and use it in GitHub Desktop.
Implementation of a new Archer headshot type
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package me.nineonefive.proto | |
import net.minecraft.server.v1_8_R3.AxisAlignedBB | |
import net.minecraft.server.v1_8_R3.Vec3D | |
import org.bukkit.ChatColor | |
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftArrow | |
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftZombie | |
import org.bukkit.entity.Arrow | |
import org.bukkit.entity.Player | |
import org.bukkit.entity.Zombie | |
import org.bukkit.event.EventHandler | |
import org.bukkit.event.Listener | |
import org.bukkit.event.entity.EntityDamageByEntityEvent | |
import org.bukkit.event.player.AsyncPlayerChatEvent | |
import org.bukkit.plugin.java.JavaPlugin | |
import org.bukkit.util.Vector | |
import java.util.logging.Level | |
import kotlin.math.roundToInt | |
class ProtoPlugin: JavaPlugin(), Listener { | |
val hitboxPercentage = 0.20 //Anything lower than this percentage doesn't count as a headshot | |
override fun onEnable(){ | |
server.pluginManager.registerEvents(this, this) | |
} | |
@EventHandler | |
fun displayDescription(event: AsyncPlayerChatEvent){ | |
if (event.message.contains("#tldr")) { | |
event.isCancelled = true | |
server.broadcastMessage( | |
"Attempting to make a more realistic headshot mechanism. If your arrow is like at the top 20% of the zombie (would be " + | |
"player), it counts as a headshot. If not, it no longer does. You still have to be at least 30 blocks away (this can also be changed). Enjoy!" | |
) | |
} | |
} | |
@EventHandler | |
fun onArrowHitSomething(event: EntityDamageByEntityEvent){ | |
// Make sure it's an arrow shot by a player hitting | |
if (event.damager is Arrow){ | |
val arrow = event.damager as Arrow | |
if (arrow.shooter is Player && event.entity is Player){ // Make sure it's a player shooting another player, possibly not necessary in CTF | |
val shooter = arrow.shooter as Player | |
val target = event.entity as Player | |
val distance = shooter.location.distance(target.location) | |
val dist = distance.roundToInt() | |
if (distance >= 60){ | |
// Anything above, say, 60 blocks dies. You deserve that hail Mary shot | |
shooter.sendMessage("${ChatColor.GRAY}Headshot from $dist blocks!") | |
target.health = 0.0 | |
// Regular headshot distance | |
} else if (distance >= 30){ | |
val dist = distance.roundToInt() | |
if (arrow headshots target){ | |
// Target was headshot, kill here | |
shooter.sendMessage("${ChatColor.GRAY}Headshot from $dist blocks!") | |
target.health = 0.0 | |
} else { | |
// Shot from >30 blocks away but not on the head, aka old headshot | |
shooter.sendMessage("${ChatColor.GRAY}Old headshot from $dist blocks!") | |
// <insert 8.5 hearts true damage here> | |
} | |
} | |
} | |
} | |
} | |
/** | |
* Checks if arrow hits target in the head | |
* Comes with fancy syntactic sugar (kotlin is better) | |
*/ | |
infix fun Arrow.headshots(p: Player): Boolean { | |
// Get target's hitbox | |
val box = (p as CraftPlayer).handle.boundingBox | |
// Calculate minimum height for headshot | |
val height = box.e - box.b | |
val ymin = box.e - (hitboxPercentage * height) | |
// Currently checks if lowest side of arrow hitbox is within that top percentage.. | |
// may want to make that the center of the arrow, idk | |
return (this as CraftArrow).handle.boundingBox.b >= ymin | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment