Skip to content

Commit 0682c1d

Browse files
authored
Merge pull request #4 from jfmario/cursor/player-kill-plugin-c602
Add player kill spear upgrade plugin
2 parents 6e25b21 + d3c4210 commit 0682c1d

7 files changed

Lines changed: 624 additions & 0 deletions

File tree

SpearUpgradesPlayer/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# SpearUpgradesPlayer
2+
3+
Spigot/Paper plugin: players get a custom spear that upgrades each time they kill another player with it. Tiers, spear material, vanilla Lunge, Sharpness, and bonus damage are configured in `src/main/resources/config.yml`.
4+
5+
## Requirements
6+
7+
- **Java 21** (matches `pom.xml` and current Minecraft server requirements)
8+
- **Apache Maven** 3.x
9+
10+
## Build the plugin JAR
11+
12+
From this directory (`SpearUpgradesPlayer`):
13+
14+
```bash
15+
mvn clean package
16+
```
17+
18+
The plugin jar is written to:
19+
20+
`target/SpearUpgradesPlayer-1.0.0.jar`
21+
22+
Copy that file into your server's `plugins` folder and restart (or load the plugin with your server's plugin manager).

SpearUpgradesPlayer/pom.xml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.johnfmarion</groupId>
8+
<artifactId>SpearUpgradesPlayer</artifactId>
9+
<version>1.0.0</version>
10+
<packaging>jar</packaging>
11+
12+
<name>SpearUpgradesPlayer</name>
13+
<description>Upgrade spears by killing players</description>
14+
15+
<properties>
16+
<java.version>21</java.version>
17+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
18+
</properties>
19+
20+
<build>
21+
<defaultGoal>clean package</defaultGoal>
22+
<plugins>
23+
<plugin>
24+
<groupId>org.apache.maven.plugins</groupId>
25+
<artifactId>maven-compiler-plugin</artifactId>
26+
<version>3.11.0</version>
27+
<configuration>
28+
<source>${java.version}</source>
29+
<target>${java.version}</target>
30+
</configuration>
31+
</plugin>
32+
<plugin>
33+
<groupId>org.apache.maven.plugins</groupId>
34+
<artifactId>maven-shade-plugin</artifactId>
35+
<version>3.5.0</version>
36+
<executions>
37+
<execution>
38+
<phase>package</phase>
39+
<goals>
40+
<goal>shade</goal>
41+
</goals>
42+
<configuration>
43+
<createDependencyReducedPom>false</createDependencyReducedPom>
44+
</configuration>
45+
</execution>
46+
</executions>
47+
</plugin>
48+
</plugins>
49+
<resources>
50+
<resource>
51+
<directory>src/main/resources</directory>
52+
<filtering>true</filtering>
53+
</resource>
54+
</resources>
55+
</build>
56+
57+
<repositories>
58+
<repository>
59+
<id>spigotmc-repo</id>
60+
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
61+
</repository>
62+
<repository>
63+
<id>sonatype</id>
64+
<url>https://oss.sonatype.org/content/groups/public/</url>
65+
</repository>
66+
</repositories>
67+
68+
<dependencies>
69+
<dependency>
70+
<groupId>org.spigotmc</groupId>
71+
<artifactId>spigot-api</artifactId>
72+
<version>1.21.11-R0.2-SNAPSHOT</version>
73+
<scope>provided</scope>
74+
</dependency>
75+
</dependencies>
76+
</project>
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package com.johnfmarion.spearupgradesplayer;
2+
3+
import org.bukkit.Material;
4+
import org.bukkit.entity.Player;
5+
import org.bukkit.event.EventHandler;
6+
import org.bukkit.event.EventPriority;
7+
import org.bukkit.event.Listener;
8+
import org.bukkit.event.entity.EntityDamageByEntityEvent;
9+
import org.bukkit.event.entity.PlayerDeathEvent;
10+
import org.bukkit.event.player.PlayerJoinEvent;
11+
import org.bukkit.event.player.PlayerRespawnEvent;
12+
import org.bukkit.inventory.ItemStack;
13+
import org.bukkit.inventory.PlayerInventory;
14+
15+
import java.util.HashMap;
16+
import java.util.Map;
17+
import java.util.UUID;
18+
19+
public class SpearListener implements Listener {
20+
21+
private final SpearUpgradesPlayer plugin;
22+
private final SpearManager spearManager;
23+
24+
/** Spear level to give on respawn, keyed by player UUID. */
25+
private final Map<UUID, Integer> respawnLevel = new HashMap<>();
26+
27+
public SpearListener(SpearUpgradesPlayer plugin, SpearManager spearManager) {
28+
this.plugin = plugin;
29+
this.spearManager = spearManager;
30+
}
31+
32+
// -------------------------------------------------------------------------
33+
// Join: give a level-1 spear to players who don't already have one
34+
// -------------------------------------------------------------------------
35+
@EventHandler
36+
public void onPlayerJoin(PlayerJoinEvent event) {
37+
Player player = event.getPlayer();
38+
if (findSpear(player) == null) {
39+
plugin.getServer().getScheduler().runTaskLater(plugin, () -> giveSpear(player, 1), 1L);
40+
}
41+
}
42+
43+
// -------------------------------------------------------------------------
44+
// Player kill with spear -> upgrade one tier
45+
// -------------------------------------------------------------------------
46+
@EventHandler(priority = EventPriority.HIGH)
47+
public void onPlayerDeath(PlayerDeathEvent event) {
48+
Player player = event.getEntity();
49+
Player killer = player.getKiller();
50+
if (killer != null) {
51+
upgradeKillerSpear(killer);
52+
}
53+
54+
// Determine what level they had
55+
ItemStack spear = findSpear(player);
56+
int level = (spear != null) ? spearManager.getSpearLevel(spear) : 1;
57+
58+
// Downgrade by one, floor at 1
59+
respawnLevel.put(player.getUniqueId(), Math.max(spearManager.getMinLevel(), level - 1));
60+
61+
// Remove all custom spears from the drop list so no one can pick them up
62+
event.getDrops().removeIf(item -> spearManager.isSpear(item));
63+
}
64+
65+
private void upgradeKillerSpear(Player killer) {
66+
ItemStack weapon = killer.getInventory().getItemInMainHand();
67+
if (!spearManager.isSpear(weapon)) return;
68+
69+
int currentLevel = spearManager.getSpearLevel(weapon);
70+
if (currentLevel >= spearManager.getMaxLevel()) {
71+
killer.sendMessage("§6Your spear is already at maximum power!");
72+
return;
73+
}
74+
75+
int newLevel = currentLevel + 1;
76+
killer.getInventory().setItemInMainHand(spearManager.createSpear(newLevel));
77+
killer.sendMessage("§aSpear upgraded → " + spearManager.getDisplayName(newLevel) + "§a!");
78+
}
79+
80+
// -------------------------------------------------------------------------
81+
// Bonus damage: simulate Sharpness X on the Netherite Spear.
82+
// Vanilla Lunge is applied directly as an enchantment when spears are created.
83+
// -------------------------------------------------------------------------
84+
@EventHandler(priority = EventPriority.NORMAL)
85+
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
86+
if (!(event.getDamager() instanceof Player)) return;
87+
88+
Player player = (Player) event.getDamager();
89+
ItemStack weapon = player.getInventory().getItemInMainHand();
90+
if (!spearManager.isSpear(weapon)) return;
91+
92+
int level = spearManager.getSpearLevel(weapon);
93+
94+
// Extra damage for Netherite Spear (Sharpness X simulation)
95+
double bonus = spearManager.getBonusDamage(level);
96+
if (bonus > 0) {
97+
event.setDamage(event.getDamage() + bonus);
98+
}
99+
}
100+
101+
// -------------------------------------------------------------------------
102+
// Respawn: give a downgraded spear
103+
// -------------------------------------------------------------------------
104+
@EventHandler
105+
public void onPlayerRespawn(PlayerRespawnEvent event) {
106+
Player player = event.getPlayer();
107+
Integer stored = respawnLevel.remove(player.getUniqueId());
108+
int level = (stored != null) ? stored : 1;
109+
110+
// Run one tick later so the inventory is fully cleared before we add the spear
111+
plugin.getServer().getScheduler().runTaskLater(plugin, () -> giveSpear(player, level), 1L);
112+
}
113+
114+
// -------------------------------------------------------------------------
115+
// Helpers
116+
// -------------------------------------------------------------------------
117+
118+
private void giveSpear(Player player, int level) {
119+
removeAllSpears(player);
120+
ItemStack spear = spearManager.createSpear(level);
121+
122+
PlayerInventory inv = player.getInventory();
123+
// Prefer main hand if empty; otherwise first free slot; otherwise slot 0
124+
if (inv.getItemInMainHand().getType() == Material.AIR) {
125+
inv.setItemInMainHand(spear);
126+
} else {
127+
int free = inv.firstEmpty();
128+
if (free >= 0) {
129+
inv.setItem(free, spear);
130+
} else {
131+
inv.setItemInMainHand(spear); // overwrite if inventory is completely full
132+
}
133+
}
134+
}
135+
136+
private ItemStack findSpear(Player player) {
137+
for (ItemStack item : player.getInventory().getContents()) {
138+
if (spearManager.isSpear(item)) return item;
139+
}
140+
return null;
141+
}
142+
143+
private void removeAllSpears(Player player) {
144+
ItemStack[] contents = player.getInventory().getContents();
145+
for (int i = 0; i < contents.length; i++) {
146+
if (spearManager.isSpear(contents[i])) contents[i] = null;
147+
}
148+
player.getInventory().setContents(contents);
149+
}
150+
}

0 commit comments

Comments
 (0)