Skip to content

Commit 9f594eb

Browse files
committed
first commit
0 parents  commit 9f594eb

File tree

9 files changed

+366
-0
lines changed

9 files changed

+366
-0
lines changed

.editorconfig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Editor configuration, see http://editorconfig.org
2+
root = true
3+
4+
[*]
5+
charset = utf-8
6+
indent_style = space
7+
indent_size = 2
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
max_line_length = 80
11+
12+
[*.sh]
13+
end_of_line = lf
14+
15+
[*.java]
16+
indent_size = 4
17+
max_line_length = 120

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
target

.vscode/settings.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"java.configuration.updateBuildConfiguration": "automatic",
3+
"yaml.schemas": {
4+
"https://json.schemastore.org/bukkit-plugin.json": "file:///c%3A/Users/alexa/Desktop/spigotplugin/demo/demo/src/main/resources/plugin.yml"
5+
}
6+
}

TODO

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix Lingering potions giving the effect no matter what
2+
3+
Maybe find a way to prevent potion particles

pom.xml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
2+
<modelVersion>4.0.0</modelVersion>
3+
<groupId>xyz.combot</groupId>
4+
<artifactId>Bounceable</artifactId>
5+
<version>1.0-SNAPSHOT</version>
6+
<properties>
7+
<maven.compiler.source>1.8</maven.compiler.source>
8+
<maven.compiler.target>1.8</maven.compiler.target>
9+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
10+
<junit.version>5.6.0</junit.version>
11+
<maven-enforcer-plugin.version>3.0.0-M3</maven-enforcer-plugin.version>
12+
<maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>
13+
<maven-javadoc-plugin.version>3.0.0</maven-javadoc-plugin.version>
14+
</properties>
15+
<repositories>
16+
<repository>
17+
<id>spigot-repo</id>
18+
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
19+
</repository>
20+
</repositories>
21+
<dependencies>
22+
<dependency>
23+
<groupId>org.junit.jupiter</groupId>
24+
<artifactId>junit-jupiter-api</artifactId>
25+
<version>${junit.version}</version>
26+
<scope>test</scope>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.junit.jupiter</groupId>
30+
<artifactId>junit-jupiter-engine</artifactId>
31+
<version>${junit.version}</version>
32+
<scope>test</scope>
33+
</dependency>
34+
<dependency>
35+
<groupId>org.spigotmc</groupId>
36+
<artifactId>spigot-api</artifactId>
37+
<version>1.18.2-R0.1-SNAPSHOT</version>
38+
<scope>provided</scope>
39+
</dependency>
40+
</dependencies>
41+
<build>
42+
<plugins>
43+
<plugin>
44+
<groupId>org.apache.maven.plugins</groupId>
45+
<artifactId>maven-enforcer-plugin</artifactId>
46+
<version>${maven-enforcer-plugin.version}</version>
47+
<executions>
48+
<execution>
49+
<goals>
50+
<goal>enforce</goal>
51+
</goals>
52+
<configuration>
53+
<rules>
54+
<requireMavenVersion>
55+
<version>3.6.3</version>
56+
</requireMavenVersion>
57+
</rules>
58+
<fail>true</fail>
59+
</configuration>
60+
</execution>
61+
</executions>
62+
</plugin>
63+
<plugin>
64+
<groupId>org.apache.maven.plugins</groupId>
65+
<artifactId>maven-surefire-plugin</artifactId>
66+
<version>${maven-surefire-plugin.version}</version>
67+
</plugin>
68+
</plugins>
69+
</build>
70+
<reporting>
71+
<plugins>
72+
<plugin>
73+
<groupId>org.apache.maven.plugins</groupId>
74+
<artifactId>maven-javadoc-plugin</artifactId>
75+
<version>${maven-javadoc-plugin.version}</version>
76+
</plugin>
77+
</plugins>
78+
</reporting>
79+
</project>

src/main/java/xyz/combot/App.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package xyz.combot;
2+
3+
import org.bukkit.plugin.java.JavaPlugin;
4+
5+
import xyz.combot.events.ThrowableHitSurface;
6+
7+
public class App extends JavaPlugin {
8+
9+
public static String PluginName = "Bounceable";
10+
11+
@Override
12+
public void onEnable() {
13+
getServer().getPluginManager().registerEvents(new ThrowableHitSurface(), this);
14+
15+
saveDefaultConfig();
16+
}
17+
}
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
package xyz.combot.events;
2+
3+
import java.util.List;
4+
5+
import org.bukkit.Bukkit;
6+
import org.bukkit.block.BlockFace;
7+
import org.bukkit.configuration.file.FileConfiguration;
8+
import org.bukkit.entity.Arrow;
9+
import org.bukkit.entity.Egg;
10+
import org.bukkit.entity.EnderPearl;
11+
import org.bukkit.entity.Fireball;
12+
import org.bukkit.entity.Firework;
13+
import org.bukkit.entity.Projectile;
14+
import org.bukkit.entity.Snowball;
15+
import org.bukkit.entity.ThrownExpBottle;
16+
import org.bukkit.entity.ThrownPotion;
17+
import org.bukkit.entity.Trident;
18+
import org.bukkit.event.EventHandler;
19+
import org.bukkit.event.Listener;
20+
import org.bukkit.event.entity.ExpBottleEvent;
21+
import org.bukkit.event.entity.PotionSplashEvent;
22+
import org.bukkit.event.entity.ProjectileHitEvent;
23+
import org.bukkit.event.player.PlayerEggThrowEvent;
24+
import org.bukkit.metadata.FixedMetadataValue;
25+
import org.bukkit.metadata.MetadataValue;
26+
import org.bukkit.util.Vector;
27+
28+
import xyz.combot.App;
29+
30+
public class ThrowableHitSurface implements Listener {
31+
FileConfiguration config = Bukkit.getPluginManager().getPlugin(App.PluginName).getConfig();
32+
int maxBounceCount = config.getInt("maxBounceCount");
33+
34+
boolean bouncesOffFloor = config.getBoolean("bouncesOffFloor");
35+
boolean bouncesOffWalls = config.getBoolean("bouncesOffWalls");
36+
boolean bouncesOffCeiling = config.getBoolean("bouncesOffCeiling");
37+
boolean chickenInEgg = config.getBoolean("chickenInEgg");
38+
39+
List<String> bounceable = config.getStringList("bounceables");
40+
41+
public int getBounceCount(Projectile projectile) {
42+
List<MetadataValue> metadata = projectile.getMetadata("bounceCount");
43+
if (metadata.size() == 0)
44+
return 0;
45+
46+
return (int) metadata.get(0).value();
47+
}
48+
49+
public void setBounceCount(Projectile projectile, int bounceCount) {
50+
projectile.setMetadata("bounceCount",
51+
new FixedMetadataValue(Bukkit.getPluginManager().getPlugin(App.PluginName), bounceCount));
52+
}
53+
54+
public boolean getCanSplash(Projectile projectile) {
55+
List<MetadataValue> metadata = projectile.getMetadata("canSplash");
56+
if (metadata.size() == 0)
57+
return true;
58+
59+
return (boolean) metadata.get(0).value();
60+
}
61+
62+
public void setCanSplash(Projectile projectile, Boolean canSplash) {
63+
if (projectile instanceof ThrownPotion || projectile instanceof ThrownExpBottle || projectile instanceof Egg)
64+
projectile.setMetadata("canSplash",
65+
new FixedMetadataValue(Bukkit.getPluginManager().getPlugin(App.PluginName), canSplash));
66+
}
67+
68+
@EventHandler(priority = org.bukkit.event.EventPriority.LOW)
69+
public void onExpBottleEvent(ExpBottleEvent event) {
70+
ThrownExpBottle potion = (ThrownExpBottle) event.getEntity();
71+
72+
if (!getCanSplash(potion)) {
73+
event.setCancelled(true);
74+
event.setExperience(0);
75+
}
76+
}
77+
78+
@EventHandler(priority = org.bukkit.event.EventPriority.LOW)
79+
public void onPotionSplashEvent(PotionSplashEvent event) {
80+
ThrownPotion potion = (ThrownPotion) event.getEntity();
81+
82+
if (!getCanSplash(potion)) {
83+
event.setCancelled(true);
84+
event.getAffectedEntities().forEach(entity -> event.setIntensity(entity, 0));
85+
}
86+
}
87+
88+
public Vector makeResultingVector(BlockFace hitBlockFace, Vector initVector) {
89+
Vector resulting = initVector.clone();
90+
if (hitBlockFace.getModX() != 0) // Hit Wall
91+
resulting.setX(initVector.getX() * -1);
92+
93+
if (hitBlockFace.getModY() != 0) // Hit Floor/Ceiling
94+
resulting.setY(initVector.getY() * -1);
95+
96+
if (hitBlockFace.getModZ() != 0) // Hit Wall
97+
resulting.setZ(initVector.getZ() * -1);
98+
99+
return resulting.normalize();
100+
}
101+
102+
public Projectile cloneProjectile(Projectile projectile) {
103+
Projectile newProjectile = (Projectile) projectile.getWorld().spawnEntity(projectile.getLocation(),
104+
projectile.getType());
105+
106+
newProjectile.setShooter(projectile.getShooter());
107+
projectile.getPassengers().forEach(newProjectile::addPassenger);
108+
projectile.getScoreboardTags().forEach(newProjectile::addScoreboardTag);
109+
newProjectile.setBounce(projectile.doesBounce());
110+
newProjectile.setCustomName(projectile.getCustomName());
111+
newProjectile.setCustomNameVisible(projectile.isCustomNameVisible());
112+
newProjectile.setFireTicks(projectile.getFireTicks());
113+
newProjectile.setGlowing(projectile.isGlowing());
114+
newProjectile.setGravity(projectile.hasGravity());
115+
newProjectile.setTicksLived(projectile.getTicksLived());
116+
setBounceCount(newProjectile, getBounceCount(projectile));
117+
118+
if (projectile instanceof ThrownPotion) {
119+
ThrownPotion potion = (ThrownPotion) projectile;
120+
ThrownPotion newPotion = (ThrownPotion) newProjectile;
121+
newPotion.setItem(potion.getItem());
122+
}
123+
if (projectile instanceof ThrownExpBottle) {
124+
ThrownExpBottle potion = (ThrownExpBottle) projectile;
125+
ThrownExpBottle newPotion = (ThrownExpBottle) newProjectile;
126+
newPotion.setItem(potion.getItem());
127+
}
128+
129+
setCanSplash(newProjectile, getCanSplash(projectile));
130+
131+
return newProjectile;
132+
}
133+
134+
@EventHandler(priority = org.bukkit.event.EventPriority.LOW)
135+
public void onPlayerEggThrow(PlayerEggThrowEvent event) {
136+
boolean canSplash = getCanSplash(event.getEgg());
137+
event.setHatching(chickenInEgg && canSplash);
138+
}
139+
140+
@EventHandler(priority = org.bukkit.event.EventPriority.HIGHEST)
141+
public void onThrowableHitSurface(ProjectileHitEvent event) {
142+
Projectile projectile = (Projectile) event.getEntity();
143+
if (event.getHitEntity() != null) {
144+
setCanSplash(projectile, true);
145+
return;
146+
}
147+
if (projectile instanceof Snowball && !bounceable.contains("snowball"))
148+
return;
149+
else if (projectile instanceof Egg && !bounceable.contains("egg")) {
150+
setCanSplash(projectile, true);
151+
return;
152+
} else if (projectile instanceof ThrownPotion && !bounceable.contains("potion")) {
153+
setCanSplash(projectile, true);
154+
return;
155+
} else if (projectile instanceof ThrownExpBottle && !bounceable.contains("xp_bottle")) {
156+
setCanSplash(projectile, true);
157+
return;
158+
} else if (projectile instanceof Arrow && !bounceable.contains("arrow"))
159+
return;
160+
else if (projectile instanceof EnderPearl && !bounceable.contains("endereye"))
161+
return;
162+
else if (projectile instanceof Firework && !bounceable.contains("firework"))
163+
return;
164+
else if (projectile instanceof Trident && !bounceable.contains("trident"))
165+
return;
166+
else if (projectile instanceof Fireball && !bounceable.contains("fireball"))
167+
return;
168+
169+
BlockFace hitBlockFace = event.getHitBlockFace();
170+
171+
if (hitBlockFace.getModY() > 0 && !bouncesOffFloor) { // Can't Bounce Floor
172+
setCanSplash(projectile, true);
173+
return;
174+
}
175+
176+
if ((hitBlockFace.getModZ() != 0 || hitBlockFace.getModX() != 0) && !bouncesOffWalls) { // Can't Bounce Walls
177+
setCanSplash(projectile, true);
178+
return;
179+
}
180+
181+
if (hitBlockFace.getModY() < 0 && !bouncesOffCeiling) { // Can't Bounce Ceiling
182+
setCanSplash(projectile, true);
183+
return;
184+
}
185+
186+
int bounceCount = getBounceCount(projectile);
187+
188+
if (bounceCount < maxBounceCount) {
189+
Projectile newentity = cloneProjectile(projectile);
190+
setCanSplash(projectile, false);
191+
setCanSplash(newentity, false);
192+
projectile.remove();
193+
194+
195+
setBounceCount(newentity, bounceCount + 1);
196+
newentity.setVelocity(makeResultingVector(hitBlockFace, projectile.getVelocity()));
197+
} else {
198+
setCanSplash(projectile, true);
199+
}
200+
}
201+
}

src/main/resources/config.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# The maximum amount of times a throwable can bounce
2+
maxBounceCount: 3
3+
4+
# If throwables should bounce off the floor
5+
bouncesOffFloor: true
6+
7+
# If throwables should bounce off the walls
8+
bouncesOffWalls: true
9+
10+
# If throwables should bounce off the ceiling
11+
bouncesOffCeiling: true
12+
13+
# If eggs should hatch chickens
14+
# false: eggs will never hatch chickens when a player throws the egg
15+
# true: eggs might hatch a chicken when a player throws the egg
16+
# This does not affect eggs thrown by dispensers
17+
chickenInEgg: false
18+
19+
# The items that should bounce
20+
# Options are
21+
# - snowball
22+
# - egg
23+
# - xp_bottle
24+
# - potion
25+
# - arrow
26+
# - endereye
27+
# - firework
28+
# - trident
29+
# - fireball
30+
bounceables:
31+
- snowball
32+
- egg
33+
- xp_bottle
34+
- potion
35+
- arrow
36+
- endereye
37+
- firework
38+
- trident
39+
- fireball

src/main/resources/plugin.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
main: xyz.combot.App
2+
name: Bounceable
3+
version: '0.1'

0 commit comments

Comments
 (0)