Skip to content

Instantly share code, notes, and snippets.

@nineonefive
Last active May 19, 2020 17:10
Show Gist options
  • Save nineonefive/327a02b129c5e84a484eae1ec36abe5b to your computer and use it in GitHub Desktop.
Save nineonefive/327a02b129c5e84a484eae1ec36abe5b to your computer and use it in GitHub Desktop.
Implementation of a new Archer headshot type
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