SteamWar/FightSystem
Archiviert
13
1

Commits vergleichen

..

90 Commits

Autor SHA1 Nachricht Datum
db23ae9cb6 Fix <1.12 schematic checking
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-03-25 21:31:29 +01:00
b9f0039025 Fix HullHider
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-03-22 20:36:27 +01:00
f5a150c203 Merge pull request '1.8 - 1.15 HullHider, fix Tab Hiding, fix appearing NameTags, improve Performance' (#419) from fixTagAndTab into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #419
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-03-22 15:31:29 +01:00
bffbd2cc06 1.8 - 1.15 HullHider, fix Tab Hiding, fix appearing NameTags, improve Performance
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
untested

Signed-off-by: Lixfel <agga-games@gmx.de>
2024-03-17 16:58:34 +01:00
abb7df4e5c Fix Entity HullHider for Referee
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-03-16 20:38:11 +01:00
df2ced027b Fix world reset race condition with TechHider
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-03-14 22:32:03 +01:00
5394adfd14 Merge pull request 'Configurable spectate port' (#418) from configurableSpectatePort into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #418
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-03-13 17:18:49 +01:00
52e3fd754e Merge pull request 'Block HullHider' (#416) from blockHullHider into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #416
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-03-13 17:13:37 +01:00
ac4babd44a Configurable spectate port
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-03-13 13:20:11 +01:00
447c8767f1 Merge pull request 'Allow multiple Referees per Event' (#417) from referee into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #417
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-03-13 13:08:59 +01:00
3bd54fcdbd Bugfixes, Block precise performance improvement
Einige Prüfungen sind fehlgeschlagen
SteamWarCI Build failed
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-03-13 13:08:17 +01:00
0c947f0b5b Fix debug code
Einige Prüfungen sind fehlgeschlagen
SteamWarCI Build failed
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-03-11 22:49:22 +01:00
c3bb34ed6b Performance and information hiding improvements (no unchanged hullhider blocks)
Einige Prüfungen sind fehlgeschlagen
SteamWarCI Build failed
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-03-11 21:33:46 +01:00
e0659c1bb2 Bugfixes, Performance improvements
Einige Prüfungen sind fehlgeschlagen
SteamWarCI Build failed
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-03-10 19:35:31 +01:00
f964f58d93 Allow multiple Referees per Event
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-03-09 19:19:42 +01:00
e3535c379a Block HullHider
Einige Prüfungen sind fehlgeschlagen
SteamWarCI Build failed
Untested

Signed-off-by: Lixfel <agga-games@gmx.de>
2024-03-07 12:54:13 +01:00
79413434f7 Fix WaterRemover TNT
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-03-05 16:17:55 +01:00
c17dc43678 Merge pull request 'Replace TNT on red side in check arenas' (#415) from noRedTntOnCheck into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #415
Reviewed-by: Chaoscaot <chaoscaot@zohomail.eu>
2024-02-13 10:50:34 +01:00
7d7b6226a0 Potential Border rejoin fix
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-02-11 19:13:47 +01:00
e0b6c1b931 Potential Border rejoin fix
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-02-11 18:55:32 +01:00
39bff371a4 Fix y border size for players
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-02-08 13:19:15 +01:00
470f8613cd Add logging to debug team area bugs
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-02-06 22:50:42 +01:00
46e3c383bd Replace TNT on red side in check arenas
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-02-06 22:11:01 +01:00
ace26a7750 Fix falling off AirShip during PRE_RUNNING
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-02-05 16:19:08 +01:00
33a84d6a66 Fix team leave
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-26 09:06:54 +01:00
75af1f00ba Fix respawn own Schematic collision
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-25 11:24:22 +01:00
2469f1bced Merge pull request 'Code cleanup, Utilize Lombok' (#414) from lombok into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #414
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-01-24 12:11:04 +01:00
5dfdb8e722 Code cleanup, Utilize Lombok
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-24 12:07:38 +01:00
0db80a56a6 Merge pull request 'Team Event API, Fancy Borders' (#413) from fancyBorder into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #413
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-01-24 12:05:03 +01:00
c8b9263b70 Fix behaviour during spectator phase
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-20 21:16:48 +01:00
ba475457db Fix Z and NormalJoin bug
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-20 19:18:09 +01:00
9d3516152d (Untested) Team Event API, Fancy Borders
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-20 18:42:22 +01:00
053152f392 Merge pull request '(Untested) Explosion, Particle and Sound Hider' (#410) from hullHider into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #410
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-01-20 17:52:07 +01:00
edc77ca2d4 Fix Name if leader null
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-20 17:51:44 +01:00
f5419a1a77 Fix Sound and Particle HullHider
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-20 16:45:03 +01:00
169649204a Merge pull request 'Better sound location' (#411) from betterSound into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #411
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-01-19 16:16:39 +01:00
e12a7ac7b4 Merge pull request 'Join request with leader names instead of team names' (#412) from leaderNameJoinRequest into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #412
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-01-19 16:16:32 +01:00
918f309625 Join request with leader names instead of team names
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-18 23:48:46 +01:00
965bba1ea5 Better sound location
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-18 23:45:28 +01:00
6d641856fe (Untested) Explosion, Particle and Sound Hider
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-18 01:16:56 +01:00
faebc3cace Fix WaterRemover: Iterate downwards
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-05 17:32:28 +01:00
5d9aa147b7 Fix WaterRemover: Remove empty blocklist check.
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-05 17:21:23 +01:00
ed1ab06ce1 Merge pull request 'Fix WaterRemover for Water based armor' (#409) from waterremover into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #409
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2024-01-05 16:42:52 +01:00
869b883b2f Fix WaterRemover for Water based armor
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-05 16:36:24 +01:00
0edbe4be94 Fix replay IllegalStateException
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-04 23:55:31 +01:00
90d8492d9a Merge pull request 'HullHider v2' (#408) from hullhiderv2 into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #408
Reviewed-by: YoyoNow <jwsteam@nidido.de>
Reviewed-by: Chaoscaot <chaoscaot@zohomail.eu>
2024-01-03 16:26:03 +01:00
7f9cfe73f7 Fix unchecked schematics at events
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-01 16:46:25 +01:00
7fab960315 Fix unchecked schematics at events
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2024-01-01 16:45:32 +01:00
c18de054a8 Merge branch 'master' into hullhiderv2
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2023-12-30 12:26:43 +01:00
6f4e0f0293 Replay REntity HullHider
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-12-30 12:26:11 +01:00
65028799b0 Correct HullHider behaviour for boarding
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-12-19 22:18:16 +01:00
9b78103592 Replay HullHider, Fix HullHider for players already online
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-12-19 16:40:12 +01:00
ce3384c7e9 Bugfixes, remove debug info
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-12-17 18:23:54 +01:00
8de15e0af5 Fix rotation of teamname display in gamemodes without schematic rotation
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-12-17 16:29:04 +01:00
5fab7e5404 Untested entity 1.18+ hullhiding
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-12-17 16:18:20 +01:00
4d5f4e9be6 Fast recursive 45° approx hullhider implementation
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-12-16 21:59:56 +01:00
29927985b1 Initial directional quadrant 45° hullhider implementation
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-12-16 18:21:33 +01:00
a17bd4c401 Fix imports
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-12-16 14:08:14 +01:00
5851d5019b Fix percent display
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-12-12 17:24:07 +01:00
5e8241605e Merge pull request 'Simplify percent system by adding entern percent and whitelist config toggles' (#406) from percentChange into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #406
Reviewed-by: D4rkr34lm <d4rkr34lm@steamwar.de>
2023-12-12 17:13:37 +01:00
0fb7a7b8ce Change percent damage display to damage health
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-12-12 12:48:56 +01:00
0a45b161a2 Simplify percent system by adding entern percent and whitelist config toggles
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-12-12 00:10:05 +01:00
yoyosource
4f65023491 Hotfix FightSchematic public choosing with no publics abailable in schematictype
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2023-12-05 15:36:40 +01:00
ad7a42a685 Merge pull request 'MultiSchemTypes' (#403) from MultiSchemTypes into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #403
Reviewed-by: Lixfel <lixfel@steamwar.de>
2023-12-05 15:21:22 +01:00
6396264194 Fix schem deleted bug
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-12-03 20:55:36 +01:00
75152abc0b Merge pull request 'Fix entern after reset' (#405) from entern-fix into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #405
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2023-12-03 20:28:03 +01:00
d140db2401 Fix entern after reset
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-12-03 20:26:04 +01:00
e8b263d841 Merge pull request 'Add pasting of non prepared schem on red side' (#404) from NonPreparedSchemOnRedSide into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #404
Reviewed-by: Lixfel <lixfel@steamwar.de>
2023-12-02 20:43:34 +01:00
yoyosource
2e8ad5301e Add pasting of non prepared schem on red side
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2023-12-02 20:03:48 +01:00
yoyosource
c08cec7cf2 Add pasting of non prepared schem on red side
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2023-12-02 16:02:30 +01:00
yoyosource
3ee7411591 Revert lowercase
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Fix SchematicType not used for checking available schematics
Fix leader not present to enable public only schem selection
2023-12-01 18:15:28 +01:00
yoyosource
c0665b1868 Fix non lower case SchematicType fromDB lookup
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Fix RankedEvent not being considered für ignore publics only
Fix using index 0 instead of i for creating of gui
Fix config.yml missing comment
2023-12-01 18:03:09 +01:00
yoyosource
8d77f4dcf4 Fix Fight.publicOnly method
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2023-12-01 16:19:55 +01:00
yoyosource
b3ad960973 Add MultiSchemType selection for GUI.preSchemDialog
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2023-12-01 16:14:37 +01:00
ad5a2d4a08 Document manualcheck option
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-11-29 16:40:10 +01:00
ef8cdef05c Distribute first TNT after 300s
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-11-29 15:47:48 +01:00
86de472fe0 Revert "Make Armor Mandatory in yaml kits."
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
This reverts commit a8112eccc8.
2023-11-29 15:35:33 +01:00
a8112eccc8 Make Armor Mandatory in yaml kits.
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-11-29 15:34:07 +01:00
70c86f40c6 Fix override
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-10-29 17:35:42 +01:00
61eb28f78e Fix double item drops
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-10-27 23:38:31 +02:00
7ad5a1dc22 Fix TNT Distribution
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-10-12 18:57:03 +02:00
256239c557 Merge pull request 'TPS Warp' (#402) from tpswarp into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #402
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2023-10-11 13:34:26 +02:00
c87bac641e TPS Warp
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-10-11 10:56:05 +02:00
3f78a595c2 Merge pull request 'Persistent Damage & TNT Distribution' (#401) from persistentDamage into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #401
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2023-10-10 17:57:19 +02:00
0c762e5624 TNT Distribution
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-10-08 18:21:19 +02:00
4b82ea9426 Persistent Damage Event
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-10-08 18:08:13 +02:00
7dd2cee635 Merge pull request 'Unchecked schematics' (#400) from unchecked into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #400
Reviewed-by: YoyoNow <jwsteam@nidido.de>
2023-09-20 15:30:47 +02:00
2cb9c12e46 Fix item and item location
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-09-16 11:09:41 +02:00
230169e163 Unchecked schematics
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-09-15 20:50:39 +02:00
cbd5fe407f Fix Lockschem in Replays
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
2023-09-09 18:45:41 +02:00
89 geänderte Dateien mit 2069 neuen und 2299 gelöschten Zeilen

Datei anzeigen

@ -39,7 +39,7 @@ public class CraftbukkitWrapper10 implements CraftbukkitWrapper {
System.arraycopy(backupChunk.getSections(), 0, chunk.getSections(), 0, chunk.getSections().length);
System.arraycopy(backupChunk.heightMap, 0, chunk.heightMap, 0, chunk.heightMap.length);
w.tileEntityListTick.removeAll(chunk.tileEntities.values());
if (!FightWorld.isPaper()) {
if (!FightWorld.isPAPER()) {
w.tileEntityList.removeAll(chunk.tileEntities.values());
}
chunk.tileEntities.clear();

Datei anzeigen

@ -39,7 +39,7 @@ public class CraftbukkitWrapper12 implements CraftbukkitWrapper {
System.arraycopy(backupChunk.getSections(), 0, chunk.getSections(), 0, chunk.getSections().length);
System.arraycopy(backupChunk.heightMap, 0, chunk.heightMap, 0, chunk.heightMap.length);
w.tileEntityListTick.removeAll(chunk.tileEntities.values());
if (!FightWorld.isPaper()) {
if (!FightWorld.isPAPER()) {
w.tileEntityList.removeAll(chunk.tileEntities.values());
}
chunk.tileEntities.clear();

Datei anzeigen

@ -46,6 +46,8 @@ dependencies {
implementation project(":FightSystem_9")
implementation project(":FightSystem_8")
compileOnly 'it.unimi.dsi:fastutil:8.5.6'
compileOnly swdep("Spigot-1.14")
compileOnly swdep("WorldEdit-1.15")
compileOnly swdep("SpigotCore")

Datei anzeigen

@ -21,17 +21,31 @@ package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.core.Core;
import de.steamwar.fightsystem.Config;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import java.util.Map;
public class BlockIdWrapper14 implements BlockIdWrapper {
private static final Class<?> worldServer = Reflection.getClass("{nms.server.level}.WorldServer");
private static final Class<?> chunkProviderServer = Reflection.getClass("{nms.server.level}.ChunkProviderServer");
private static final Reflection.MethodInvoker getChunkProvider = Reflection.getTypedMethod(worldServer, null, chunkProviderServer);
private static final Class<?> playerChunkMap = Reflection.getClass("{nms.server.level}.PlayerChunkMap");
private static final Reflection.FieldAccessor<?> getPlayerChunkMap = Reflection.getField(chunkProviderServer, playerChunkMap, 0);
private static final Reflection.FieldAccessor<? extends Map> entityTrackers = Core.getVersion() > 15 ? Reflection.getField(playerChunkMap, Int2ObjectMap.class, 0) : Reflection.getField(playerChunkMap, org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectMap.class, 0);
private static final Class<?> block = Reflection.getClass("{nms.world.level.block}.Block");
private static final Class<?> iBlockData = Reflection.getClass("{nms.world.level.block.state}.IBlockData");
private static final Class<?> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
private final Map trackers;
public BlockIdWrapper14() {
trackers = entityTrackers.get(getPlayerChunkMap.get(getChunkProvider.invoke(getWorldHandle.invoke(Config.world))));
}
private static final Reflection.MethodInvoker getCombinedId = Reflection.getTypedMethod(block, null, int.class, iBlockData);
private static final Reflection.MethodInvoker getNMS = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.CraftBlock"), "getNMS", iBlockData);
@Override
@ -40,11 +54,9 @@ public class BlockIdWrapper14 implements BlockIdWrapper {
}
private static final Reflection.MethodInvoker getByCombinedId = Reflection.getTypedMethod(block, null, iBlockData, int.class);
private static final Reflection.MethodInvoker getWorldHandle = Reflection.getTypedMethod(Reflection.getClass("{obc}.CraftWorld"), "getHandle", worldServer);
private static final Reflection.ConstructorInvoker newBlockPosition = Reflection.getConstructor(blockPosition, int.class, int.class, int.class);
private static final Reflection.MethodInvoker getTypeAndData = Reflection.getMethod(worldServer, null, blockPosition, iBlockData, int.class);
private static final Reflection.MethodInvoker removeTileEntity = Reflection.getMethod(worldServer, Core.getVersion() > 15 ? "m" : "removeTileEntity", blockPosition);
private static final Reflection.MethodInvoker getChunkProvider = Reflection.getTypedMethod(worldServer, null, chunkProviderServer);
private static final Reflection.MethodInvoker flagDirty = Reflection.getMethod(chunkProviderServer, null, blockPosition);
@Override
public void setBlock(World world, int x, int y, int z, int blockState) {
@ -56,4 +68,28 @@ public class BlockIdWrapper14 implements BlockIdWrapper {
getTypeAndData.invoke(nworld, pos, blockData, 1042);
flagDirty.invoke(getChunkProvider.invoke(nworld), pos);
}
private static final Class<?> entityTracker = Reflection.getClass("{nms.server.level}.PlayerChunkMap$EntityTracker");
private static final Reflection.MethodInvoker updatePlayer = Reflection.getMethod(entityTracker, Core.getVersion() > 15 ? "b" : "updatePlayer", entityPlayer);
@Override
public void trackEntity(Player player, int entity) {
Object tracker = trackers.get(entity);
if(tracker != null)
updatePlayer.invoke(tracker, getPlayer.invoke(player));
}
private static final Reflection.MethodInvoker clearPlayer = Reflection.getMethod(entityTracker, Core.getVersion() > 15 ? "a" : "clear", entityPlayer);
@Override
public void untrackEntity(Player player, int entity) {
Object tracker = trackers.get(entity);
if(tracker != null)
clearPlayer.invoke(tracker, getPlayer.invoke(player));
}
private static final Reflection.MethodInvoker getMaterialByBlock = Reflection.getTypedMethod(Reflection.getClass("{obc}.util.CraftMagicNumbers"), "getMaterial", Material.class, block);
private static final Reflection.MethodInvoker getBlockByBlockData = Reflection.getTypedMethod(iBlockData, null, block);
@Override
public Material idToMaterial(int blockState) {
return (Material)getMaterialByBlock.invoke(null, getBlockByBlockData.invoke(getByCombinedId.invoke(null, blockState)));
}
}

Datei anzeigen

@ -38,7 +38,7 @@ public class CraftbukkitWrapper14 implements CraftbukkitWrapper {
System.arraycopy(backupChunk.getSections(), 0, chunk.getSections(), 0, chunk.getSections().length);
w.tileEntityListTick.removeAll(chunk.tileEntities.values());
if (!FightWorld.isPaper()) {
if (!FightWorld.isPAPER()) {
w.tileEntityList.removeAll(chunk.tileEntities.values());
}
chunk.tileEntities.clear();

Datei anzeigen

@ -108,4 +108,9 @@ public class FlatteningWrapper14 implements FlatteningWrapper {
public boolean isCrouching(Player player) {
return player.getPose() == Pose.SWIMMING;
}
@Override
public void sendBlockChange(Player player, Block block, Material type) {
player.sendBlockChange(block.getLocation(), type.createBlockData());
}
}

Datei anzeigen

@ -38,7 +38,7 @@ public class CraftbukkitWrapper15 implements CraftbukkitWrapper {
System.arraycopy(backupChunk.getSections(), 0, chunk.getSections(), 0, chunk.getSections().length);
w.tileEntityListTick.removeAll(chunk.tileEntities.values());
if (!FightWorld.isPaper()) {
if (!FightWorld.isPAPER()) {
w.tileEntityList.removeAll(chunk.tileEntities.values());
}
chunk.tileEntities.clear();

Datei anzeigen

@ -48,6 +48,7 @@ dependencies {
compileOnly 'com.mojang:datafixerupper:4.0.26'
compileOnly 'io.netty:netty-all:4.1.68.Final'
compileOnly 'com.mojang:authlib:1.5.25'
compileOnly 'it.unimi.dsi:fastutil:8.5.6'
compileOnly swdep("Spigot-1.18")
compileOnly swdep("WorldEdit-1.15")

Datei anzeigen

@ -0,0 +1,82 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.fightsystem.Config;
import it.unimi.dsi.fastutil.shorts.Short2ObjectArrayMap;
import net.minecraft.core.BlockPosition;
import net.minecraft.core.SectionPosition;
import net.minecraft.network.protocol.game.PacketPlayOutBlockChange;
import net.minecraft.network.protocol.game.PacketPlayOutMultiBlockChange;
import net.minecraft.world.level.block.state.IBlockData;
import org.bukkit.block.data.BlockData;
import java.util.ArrayList;
import java.util.List;
public class HullHiderWrapper18 implements HullHiderWrapper {
private static final Reflection.MethodInvoker getState = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.data.CraftBlockData"), "getState", IBlockData.class);
@Override
public Object generateBlockChangePacket(List<Hull.IntVector> changes) {
List<Object> blockdata = new ArrayList<>(changes.size());
changes.removeIf(change -> {
BlockData data = Config.world.getBlockData(change.getX(), change.getY(), change.getZ());
boolean unchanged = data.getMaterial() == Config.ObfuscateWith || Config.HiddenBlocks.contains(data.getMaterial());
if(!unchanged)
blockdata.add(getState.invoke(data));
return unchanged;
});
if(changes.isEmpty())
return null;
return generateBlockChangePacket(changes, blockdata.toArray());
}
private Object generateBlockChangePacket(List<Hull.IntVector> changes, Object[] blockdata) {
if(changes.size() > 1) {
Hull.IntVector section = changes.get(0);
section = new Hull.IntVector(section.getX() >> 4, section.getY() >> 4, section.getZ() >> 4);
int xOffset = 16*section.getX();
int yOffset = 16*section.getY();
int zOffset = 16*section.getZ();
short[] pos = new short[changes.size()];
for(int i = 0; i < changes.size(); i++) {
Hull.IntVector change = changes.get(i);
pos[i] = (short) (((change.getX()-xOffset) << 8) + ((change.getZ()-zOffset) << 4) + (change.getY()-yOffset));
}
return constructMultiBlockChange(section, pos, blockdata);
} else {
Hull.IntVector pos = changes.get(0);
return new PacketPlayOutBlockChange(new BlockPosition(pos.getX(), pos.getY(), pos.getZ()), (IBlockData) blockdata[0]);
}
}
protected Object constructMultiBlockChange(Hull.IntVector section, short[] pos, Object[] blockdata) {
return new PacketPlayOutMultiBlockChange(SectionPosition.a(section.getX(), section.getY(), section.getZ()), new Short2ObjectArrayMap<>(pos, blockdata, blockdata.length), false);
}
}

Datei anzeigen

@ -46,6 +46,7 @@ dependencies {
implementation project(":FightSystem_18")
compileOnly 'org.spigotmc:spigot-api:1.20-R0.1-SNAPSHOT'
compileOnly 'it.unimi.dsi:fastutil:8.5.6'
compileOnly swdep("Spigot-1.20")
}

Datei anzeigen

@ -0,0 +1,32 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.utils;
import it.unimi.dsi.fastutil.shorts.Short2ObjectArrayMap;
import net.minecraft.core.SectionPosition;
import net.minecraft.network.protocol.game.PacketPlayOutMultiBlockChange;
public class HullHiderWrapper20 extends HullHiderWrapper18 {
@Override
protected Object constructMultiBlockChange(Hull.IntVector section, short[] pos, Object[] blockdata) {
return new PacketPlayOutMultiBlockChange(SectionPosition.a(section.getX(), section.getY(), section.getZ()), new Short2ObjectArrayMap<>(pos, blockdata, blockdata.length));
}
}

Datei anzeigen

@ -19,10 +19,25 @@
package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.fightsystem.Config;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
public class BlockIdWrapper8 implements BlockIdWrapper {
private static final Class<?> entityTracker = Reflection.getClass("{nms}.EntityTracker");
private static final Reflection.FieldAccessor<?> getEntityTracker = Reflection.getField(worldServer, entityTracker, 0);
private static final Class<?> intHashMap = Reflection.getClass("{nms}.IntHashMap");
private static final Reflection.FieldAccessor<?> getTrackedEntities = Reflection.getField(entityTracker, intHashMap, 0);
private final Object trackers;
public BlockIdWrapper8() {
trackers = getTrackedEntities.get(getEntityTracker.get(getWorldHandle.invoke(Config.world)));
}
@Override
@SuppressWarnings("deprecation")
public int blockToId(Block block) {
@ -37,4 +52,31 @@ public class BlockIdWrapper8 implements BlockIdWrapper {
world.getBlockAt(x, y, z).setTypeIdAndData(blockState >> 4, (byte)(blockState & 0b1111), false);
}
private static final Class<?> entityTrackerEntry = Reflection.getClass("{nms}.EntityTrackerEntry");
private static final Reflection.MethodInvoker get = Reflection.getTypedMethod(intHashMap, "get", Object.class, int.class);
private static final Reflection.MethodInvoker updatePlayer = Reflection.getMethod(entityTrackerEntry, "updatePlayer", entityPlayer);
@Override
public void trackEntity(Player player, int entity) {
Object tracker = get.invoke(trackers, entity);
if(tracker != null)
updatePlayer.invoke(tracker, getPlayer.invoke(player));
}
private static final Reflection.MethodInvoker clearPlayer = Reflection.getMethod(entityTrackerEntry, "a", entityPlayer);
@Override
public void untrackEntity(Player player, int entity) {
Object tracker = get.invoke(trackers, entity);
if(tracker != null)
clearPlayer.invoke(tracker, getPlayer.invoke(player));
}
@Override
@SuppressWarnings("deprecation")
public Material idToMaterial(int blockState) {
if((blockState >> 4) > 256) // Illegal blockstate / corrupted replay
blockState = 0;
return Material.getMaterial(blockState >> 4);
}
}

Datei anzeigen

@ -83,4 +83,10 @@ public class FlatteningWrapper8 implements FlatteningWrapper {
public boolean isCrouching(Player player) {
return false;
}
@Override
@SuppressWarnings("deprecation")
public void sendBlockChange(Player player, Block block, Material type) {
player.sendBlockChange(block.getLocation(), type, (byte)0);
}
}

Datei anzeigen

@ -0,0 +1,55 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.fightsystem.Config;
import org.bukkit.Material;
import java.util.List;
public class HullHiderWrapper8 implements HullHiderWrapper {
private static final Reflection.ConstructorInvoker newMultiBlockChange = Reflection.getConstructor("{nms}.PacketPlayOutMultiBlockChange", int.class, short[].class, Reflection.getClass("{nms}.Chunk"));
private static final Reflection.MethodInvoker getHandle = Reflection.getMethod("{obc}.CraftChunk", "getHandle");
@Override
public Object generateBlockChangePacket(List<Hull.IntVector> changes) {
changes.removeIf(change -> {
Material material = Config.world.getBlockAt(change.getX(), change.getY(), change.getZ()).getType();
return material == Config.ObfuscateWith || Config.HiddenBlocks.contains(material);
});
if(changes.isEmpty())
return null;
Hull.IntVector chunk = changes.get(0);
chunk = new Hull.IntVector(chunk.getX() >> 4, chunk.getY() >> 4, chunk.getZ() >> 4);
int xOffset = 16*chunk.getX();
int zOffset = 16*chunk.getZ();
short[] pos = new short[changes.size()];
for(int i = 0; i < changes.size(); i++) {
Hull.IntVector change = changes.get(i);
pos[i] = (short) (((change.getX()-xOffset) << 12) + ((change.getZ()-zOffset) << 8) + change.getY());
}
return newMultiBlockChange.invoke(pos.length, pos, getHandle.invoke(Config.world.getChunkAt(chunk.getX(), chunk.getZ())));
}
}

Datei anzeigen

@ -39,7 +39,7 @@ public class CraftbukkitWrapper9 implements CraftbukkitWrapper {
System.arraycopy(backupChunk.getSections(), 0, chunk.getSections(), 0, chunk.getSections().length);
System.arraycopy(backupChunk.heightMap, 0, chunk.heightMap, 0, chunk.heightMap.length);
w.tileEntityListTick.removeAll(chunk.tileEntities.values());
if (!FightWorld.isPaper()) {
if (!FightWorld.isPAPER()) {
w.tileEntityList.removeAll(chunk.tileEntities.values());
}
chunk.tileEntities.clear();

Datei anzeigen

@ -47,6 +47,9 @@ dependencies {
compileOnly 'io.netty:netty-all:4.1.68.Final'
compileOnly 'com.mojang:authlib:1.5.25'
compileOnly 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.30'
compileOnly swdep("WorldEdit-1.15")
compileOnly swdep("SpigotCore")
}

Datei anzeigen

@ -61,10 +61,14 @@ Schematic:
z: 0
# The schematic type that can be chosen in this arena
Type: Normal # defaults to Normal if missing
# The schematic types that are also allowed to be chosen in this arena
SubTypes: [] # defaults to empty List
# Shortcut of the schematic type
Shortcut: "" # defaults to "" if missing
# Spigot (1.8) material for GUIs
Material: STONE_BUTTON # defaults to STONE_BUTTON if missing
# Manual check of schematic necessary
ManualCheck: true # defaults to true if missing
# If the schematics should be rotated during pasting
Rotate: true # defaults to true if missing
# If the schematics should be pasted aligned to the borders instead of centered
@ -110,8 +114,6 @@ WinConditions: # defaults to none if missing
# - CAPTAIN_DEAD
# - PERCENT_SYSTEM
# - WHITELIST_PERCENT
# - RELATIVE_PERCENT
# - POINTS
# - POINTS_AIRSHIP
@ -121,12 +123,18 @@ WinConditions: # defaults to none if missing
# - HELLS_BELLS
# - METEOR
# - PERSISTENT_DAMAGE
# - TNT_DISTRIBUTION
WinConditionParams:
# The time of any of the timeout win conditions in seconds
TimeoutTime: 1200 # defaults to 1200 if missing
# The percentage when any of the percent win conditions limits or triggers a win
PercentWin: 7.0 # defaults to 7.0 if missing
# Does the percentage still change after the start of the enter phase
PercentEntern: true # defaults to true if missing
# Is Blocks a whitelist (true) or blacklist (false)
BlocksWhitelist: false # defaults to false if missing
# Special Blocks (Valid spigot material values) used by the percent win conditions
Blocks: [] # defaults to none if missing

Datei anzeigen

@ -21,10 +21,7 @@ package de.steamwar.fightsystem;
import de.steamwar.fightsystem.utils.Region;
import de.steamwar.fightsystem.winconditions.Winconditions;
import de.steamwar.sql.Event;
import de.steamwar.sql.EventFight;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.Team;
import de.steamwar.sql.*;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@ -83,6 +80,7 @@ public class Config {
public static final boolean OnlyPublicSchematics;
public static final boolean IgnorePublicOnly;
public static final de.steamwar.sql.SchematicType SchematicType;
public static final List<de.steamwar.sql.SchematicType> SubTypes;
public static final boolean RedRotate;
public static final boolean BlueRotate;
public static final boolean PasteAligned;
@ -106,6 +104,8 @@ public class Config {
//win condition parameters
public static final int TimeoutTime;
public static final double PercentWin;
public static final boolean PercentEntern;
public static final boolean PercentBlocksWhitelist;
public static final Set<Material> PercentBlocks;
//default kits
@ -117,13 +117,13 @@ public class Config {
//tech hider parameter
public static final boolean TechhiderActive;
public static final Set<String> HiddenBlocks;
public static final Set<Material> HiddenBlocks;
public static final Set<String> HiddenBlockEntities;
public static final String ObfuscateWith;
public static final Material ObfuscateWith;
//event parameter
private static final int EventKampfID;
public static final EventFight EventKampf;
private static final Set<Integer> Referees;
public static final int EventTeamBlueID;
public static final int EventTeamRedID;
public static final boolean BothTeamsPublic;
@ -138,10 +138,14 @@ public class Config {
//replay system parameter
public static final String spectateIP = "127.0.0.1";
public static final int spectatePort = 2222;
public static final int SpectatePort;
public static final int ReplayID;
static{
CheckSchemID = Integer.parseInt(System.getProperty("checkSchemID", "0"));
PrepareSchemID = Integer.parseInt(System.getProperty("prepareSchemID", "0"));
ReplayID = Integer.parseInt(System.getProperty("replay", "0"));
String configFile = System.getProperty("config", "config.yml");
if(!new File(FightSystem.getPlugin().getDataFolder(), configFile).exists()) {
FightSystem.getPlugin().saveDefaultConfig();
@ -181,6 +185,7 @@ public class Config {
int schemsizeZ = config.getInt("Schematic.Size.z");
RanksEnabled = !config.getStringList("Ranks").isEmpty();
SchematicType = de.steamwar.sql.SchematicType.fromDB(Objects.requireNonNull(config.getString("Schematic.Type", "normal")));
SubTypes = config.getStringList("Schematic.SubTypes").stream().map(de.steamwar.sql.SchematicType::fromDB).collect(Collectors.toList());
IgnorePublicOnly = config.getBoolean("Schematic.IgnorePublicOnly", false);
boolean rotate = config.getBoolean("Schematic.Rotate", true);
PasteAligned = config.getBoolean("Schematic.PasteAligned", false);
@ -195,6 +200,8 @@ public class Config {
TimeoutTime = config.getInt("WinConditionParams.TimeoutTime", 1200);
PercentWin = config.getDouble("WinConditionParams.PercentWin", 7.0);
PercentEntern = config.getBoolean("WinConditionParams.PercentEntern", true);
PercentBlocksWhitelist = config.getBoolean("WinConditionParams.BlocksWhitelist", false);
PercentBlocks = Collections.unmodifiableSet(config.getStringList("WinConditionParams.Blocks").stream().map(Material::valueOf).collect(Collectors.toSet()));
EnterStages = Collections.unmodifiableList(config.getIntegerList("EnterStages"));
@ -207,8 +214,8 @@ public class Config {
ForbiddenItems = Collections.unmodifiableSet(config.getStringList("Kits.ForbiddenItems").stream().map(Material::valueOf).collect(Collectors.toSet()));
TechhiderActive = config.getBoolean("Techhider.Active", false);
ObfuscateWith = config.getString("Techhider.ObfuscateWith", "end_stone").toUpperCase();
HiddenBlocks = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlocks")));
ObfuscateWith = Material.getMaterial(config.getString("Techhider.ObfuscateWith", "end_stone").toUpperCase());
HiddenBlocks = config.getStringList("Techhider.HiddenBlocks").stream().map(String::toUpperCase).map(Material::getMaterial).collect(Collectors.toSet());
HiddenBlockEntities = Collections.unmodifiableSet(new HashSet<>(config.getStringList("Techhider.HiddenBlockEntities")));
if(schemsizeX < 0){
@ -303,25 +310,25 @@ public class Config {
RedRotate = teamRedRotate;
BlueRotate = teamBlueRotate;
RedPasteRegion = new Region(teamRedCornerX, teamRedCornerY, teamRedCornerZ, schemsizeX, schemsizeY, schemsizeZ);
BluePasteRegion = new Region(blueCornerX, blueCornerY, blueCornerZ, schemsizeX, schemsizeY, schemsizeZ);
RedPasteRegion = Region.fromSize(teamRedCornerX, teamRedCornerY, teamRedCornerZ, schemsizeX, schemsizeY, schemsizeZ);
BluePasteRegion = Region.fromSize(blueCornerX, blueCornerY, blueCornerZ, schemsizeX, schemsizeY, schemsizeZ);
RedExtendRegion = new Region(teamRedCornerX, teamRedCornerY, teamRedCornerZ, schemsizeX, schemsizeY, schemsizeZ, PreperationArea, PreperationArea, PreperationArea);
BlueExtendRegion = new Region(blueCornerX, blueCornerY, blueCornerZ, schemsizeX, schemsizeY, schemsizeZ, PreperationArea, PreperationArea, PreperationArea);
ArenaRegion = new Region(arenaMinX, blueCornerY, arenaMinZ, arenaMaxX - arenaMinX, schemsizeY, arenaMaxZ - arenaMinZ, 0, PreperationArea, 0);
PlayerRegion = new Region(arenaMinX, underBorder, arenaMinZ, arenaMaxX - arenaMinX, world.getMaxHeight() - underBorder, arenaMaxZ - arenaMinZ);
RedExtendRegion = Region.withExtension(teamRedCornerX, teamRedCornerY, teamRedCornerZ, schemsizeX, schemsizeY, schemsizeZ, PreperationArea, PreperationArea, PreperationArea);
BlueExtendRegion = Region.withExtension(blueCornerX, blueCornerY, blueCornerZ, schemsizeX, schemsizeY, schemsizeZ, PreperationArea, PreperationArea, PreperationArea);
ArenaRegion = Region.withExtension(arenaMinX, blueCornerY, arenaMinZ, arenaMaxX - arenaMinX, schemsizeY, arenaMaxZ - arenaMinZ, 0, PreperationArea, 0);
PlayerRegion = new Region(arenaMinX, underBorder, arenaMinZ, arenaMaxX, world.getMaxHeight(), arenaMaxZ);
EventKampfID = Integer.parseInt(System.getProperty("fightID", "0"));
if(EventKampfID >= 1){
EventFight eventFight = EventFight.get(EventKampfID);
if(eventFight == null){
int eventKampfID = Integer.parseInt(System.getProperty("fightID", "0"));
if(eventKampfID >= 1){
EventKampf = EventFight.get(eventKampfID);
if(EventKampf == null){
Bukkit.getLogger().log(Level.SEVERE, "Failed to load EventFight");
Bukkit.shutdown();
}
assert eventFight != null;
Team team1 = Team.get(eventFight.getTeamBlue());
Team team2 = Team.get(eventFight.getTeamRed());
assert EventKampf != null;
Team team1 = Team.get(EventKampf.getTeamBlue());
Team team2 = Team.get(EventKampf.getTeamRed());
if(team1 == null || team2 == null){
Bukkit.getLogger().log(Level.SEVERE, "Failed to load Team");
@ -337,9 +344,11 @@ public class Config {
EventTeamBlueID = team1.getTeamId();
EventTeamRedID = team2.getTeamId();
BothTeamsPublic = EventTeamRedID == 0 && EventTeamBlueID == 0;
EventKampf = eventFight;
SpectatePort = EventKampf.getSpectatePort();
LiveReplay = SpectatePort != 0;
Referees = Referee.get(Config.EventKampf.getEventID());
Event event = Event.get(eventFight.getEventID());
Event event = Event.get(EventKampf.getEventID());
if(BothTeamsPublic) {
OnlyPublicSchematics = true;
MaximumTeamMembers = Integer.MAX_VALUE;
@ -347,7 +356,6 @@ public class Config {
OnlyPublicSchematics = event.publicSchemsOnly();
MaximumTeamMembers = event.getMaximumTeamMembers();
}
LiveReplay = event.spectateSystem();
}else{
//No event
TeamRedColor = config.getString("Red.Prefix", "§c");
@ -359,8 +367,10 @@ public class Config {
EventTeamRedID = 0;
EventKampf = null;
BothTeamsPublic = true;
Referees = Collections.emptySet();
MaximumTeamMembers = Integer.MAX_VALUE;
LiveReplay = false;
SpectatePort = -ReplayID;
}
String blueLeader = System.getProperty("blueLeader", null);
@ -374,17 +384,13 @@ public class Config {
else
RedLeader = null;
CheckSchemID = Integer.parseInt(System.getProperty("checkSchemID", "0"));
PrepareSchemID = Integer.parseInt(System.getProperty("prepareSchemID", "0"));
ReplayID = Integer.parseInt(System.getProperty("replay", "0"));
if(CheckSchemID != 0){
mode = ArenaMode.CHECK;
}else if(PrepareSchemID != 0){
mode = ArenaMode.PREPARE;
}else if(EventKampfID >= 1){
}else if(eventKampfID >= 1){
mode = ArenaMode.EVENT;
}else if(EventKampfID == -1){
}else if(eventKampfID == -1){
mode = ArenaMode.TEST;
}else if(ReplayID != 0){
mode = ArenaMode.REPLAY;
@ -397,15 +403,13 @@ public class Config {
return ArenaMode.Test.contains(mode);
}
public static boolean replayserver(){
return ReplayID == -1;
return ReplayID < 0;
}
public static boolean blueNegZ(){
return BlueToRedZ > 0;
}
public static boolean isReferee(Player player) {
if(EventKampf == null)
return false;
return SteamwarUser.get(player.getUniqueId()).getId() == EventKampf.getKampfleiter();
return Referees.contains(SteamwarUser.get(player.getUniqueId()).getId());
}
}

Datei anzeigen

@ -21,13 +21,12 @@ package de.steamwar.fightsystem;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.core.Core;
import de.steamwar.fightsystem.ai.LixfelAI;
import de.steamwar.fightsystem.ai.navmesh.NavMesh;
import de.steamwar.fightsystem.ai.chaos.ChaosAI;
import de.steamwar.fightsystem.commands.*;
import de.steamwar.fightsystem.countdown.*;
import de.steamwar.fightsystem.event.HellsBells;
import de.steamwar.fightsystem.event.Meteor;
import de.steamwar.fightsystem.event.PersistentDamage;
import de.steamwar.fightsystem.event.TNTDistributor;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.fight.FightWorld;
@ -40,22 +39,25 @@ import de.steamwar.fightsystem.record.GlobalRecorder;
import de.steamwar.fightsystem.record.LiveRecorder;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.OneShotStateDependent;
import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.fightsystem.utils.*;
import de.steamwar.fightsystem.winconditions.*;
import de.steamwar.message.Message;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
public class FightSystem extends JavaPlugin {
@Getter
private static FightSystem plugin;
private Message message;
private FightTeam lastWinner;
private String lastWinreason;
private TechHiderWrapper techHider;
private HullHider hullHider;
@Override
public void onLoad() {
@ -82,7 +84,6 @@ public class FightSystem extends JavaPlugin {
});
new Chat();
new ArenaBorder();
new TeamArea();
new IngameDeath();
new InFightDamage();
new InFightInventory();
@ -99,7 +100,7 @@ public class FightSystem extends JavaPlugin {
new RunningWorldInteraction();
new PersonalKitCreator();
new ArrowStopper();
new ArrowPickup();
new StateDependentListener(ArenaMode.All, FightState.All, BountifulWrapper.impl.newDenyArrowPickupListener());
new BlockFadeListener();
new LeaveableArena();
new ClickAnalyzer();
@ -110,6 +111,7 @@ public class FightSystem extends JavaPlugin {
new EnterHandler();
techHider = new TechHiderWrapper();
hullHider = new HullHider();
new FightWorld();
new FightUI();
new FightStatistics();
@ -119,9 +121,7 @@ public class FightSystem extends JavaPlugin {
new WinconditionCaptainDead();
new WinconditionBlocks(Winconditions.WATER_TECH_KO, "WaterTechKO", "BAR_WATER", FlatteningWrapper.impl::isWater);
new WinconditionBlocks(Winconditions.PUMPKIN_TECH_KO, "PumpkinTechKO", "BAR_CANNONS", block -> block.getType() == WinconditionBlocks.PUMPKIN_LANTERN);
new WinconditionPercentSystem();
new WinconditionBlacklistPercent();
new WinconditionWhitelistPercent();
new WinconditionPercent(Winconditions.PERCENT_SYSTEM, "Percent");
new WinconditionPoints();
new WinconditionPointsAirShip();
new WinconditionTimeout();
@ -132,6 +132,8 @@ public class FightSystem extends JavaPlugin {
new HellsBells();
new Meteor();
new PersistentDamage();
new TNTDistributor();
new WinconditionAmongUs();
new NoPlayersOnlineCountdown();
@ -155,6 +157,7 @@ public class FightSystem extends JavaPlugin {
new LockschemCommand();
new StateCommand();
new SkipCommand();
new TPSWarpCommand();
new UnrankCommand();
new WinCommand();
@ -166,17 +169,18 @@ public class FightSystem extends JavaPlugin {
if(Config.mode == ArenaMode.EVENT) {
FightState.setFightState(FightState.PRE_SCHEM_SETUP);
}else if(Config.mode == ArenaMode.CHECK){
Fight.getBlueTeam().setSchem(SchematicNode.getSchematicNode(Config.CheckSchemID));
SchematicNode checkSchematicNode = SchematicNode.getSchematicNode(Config.CheckSchemID);
Fight.getBlueTeam().setSchem(checkSchematicNode);
if (checkSchematicNode.getName().endsWith("-prepared")) {
SchematicNode unpreparedSchematicNode = SchematicNode.getSchematicNode(checkSchematicNode.getOwner(), checkSchematicNode.getName().substring(0, checkSchematicNode.getName().length() - 9), checkSchematicNode.getParent());
if (unpreparedSchematicNode != null) {
Fight.getRedTeam().setSchem(unpreparedSchematicNode);
}
}
}else if(Config.mode == ArenaMode.PREPARE) {
Fight.getUnrotated().setSchem(SchematicNode.getSchematicNode(Config.PrepareSchemID));
}
FightStatistics.unrank();
Bukkit.getScheduler().runTask(getPlugin(), () -> {
new ChaosAI(Fight.getBlueTeam());
new LixfelAI(Fight.getRedTeam(), SteamwarUser.get(-1));
});
}
@Override
@ -193,15 +197,6 @@ public class FightSystem extends JavaPlugin {
FightState.setFightState(FightState.SPECTATE);
}
public static FightSystem getPlugin() {
return plugin;
}
public static void broadcast(String msg, Object... params) {
getMessage().broadcast(msg, params);
GlobalRecorder.getInstance().system(msg, params);
}
public static Message getMessage() {
return plugin.message;
}
@ -218,6 +213,10 @@ public class FightSystem extends JavaPlugin {
return plugin.techHider;
}
public static HullHider getHullHider() {
return plugin.hullHider;
}
public static void shutdown() {
//Staggered kick to prevent lobby overloading
if(Bukkit.getOnlinePlayers().isEmpty()){

Datei anzeigen

@ -51,6 +51,9 @@ INFO_RANKED=§7Ranked§8: §e{0}
INFO_LEADER=§7Leader {0}§8: {1}
INFO_SCHEMATIC=§7Schematic {0}§8: §e{1} §7from {2}, Rank: {3}
TPSWARP_HELP=§8/§7tpswarp §8[§eticks per second§8]
TPSWARP_SET=§7TPS set to §e{0}
# GUI
STATE_TITLE=Fight state
@ -75,6 +78,7 @@ KITSEARCH_TITLE=Search for kit
SCHEM_NO_ENEMY=§cNo schematic selection without an opponent
SCHEM_TITLE={0} selection
SCHEM_PUBLIC=§ePublic {0}
SCHEM_UNCHECKED=§eUnchecked {0}
SCHEM_PRIVATE=§ePrivate {0}
SCHEM_NO_PRIVATE=§7No private {0} present
SCHEM_PRIVATE_FORBIDDEN=§7No private {0} allowed
@ -99,6 +103,7 @@ SPECTATE_COUNTDOWN=until the arena is reset
# Fight
SCHEMATIC_UNLOADABLE=§cUnable to load schematic
SCHEMATIC_CHOSEN=§7{0} §e{1} §7chosen
SCHEMATIC_UNCHECKED=§7Team {0} §7has chosen an §eunchecked §7schematic§8!
TEAM_READY=§aTeam ready
TEAM_NOT_READY=§c§mTeam ready
SKIP_READY=§aSkipping to next event

Datei anzeigen

@ -45,6 +45,9 @@ REMOVE_HELP=§8/§eremove §8[§eSpieler§8]
NOT_FIGHTLEADER=§cDu bist nicht Kampfleiter
WIN_HELP=§8/§7win §8[§eTeam §8oder §etie§8]
TPSWARP_HELP=§8/§7tpswarp §8[§eTicks pro Sekunde§8]
TPSWARP_SET=§7TPS auf §e{0} §7gesetzt
# GUI
STATE_TITLE=Kampfstatus
@ -69,6 +72,7 @@ KITSEARCH_TITLE=Nach Kit suchen
SCHEM_NO_ENEMY=§cKeine Schematicwahl ohne Gegner
SCHEM_TITLE={0}-Auswahl
SCHEM_PUBLIC=§eÖffentliches {0}
SCHEM_UNCHECKED=§eUngeprüftes {0}
SCHEM_PRIVATE=§ePrivates {0}
SCHEM_NO_PRIVATE=§7Kein privates {0} vorhanden
SCHEM_PRIVATE_FORBIDDEN=§7Kein privates {0} erlaubt
@ -93,6 +97,7 @@ SPECTATE_COUNTDOWN=bis die Arena zurückgesetzt wird
# Fight
SCHEMATIC_UNLOADABLE=§cSchematic konnte nicht geladen werden
SCHEMATIC_CHOSEN=§7{0} §e{1} §7gewählt
SCHEMATIC_UNCHECKED=§7Team {0} §7hat eine §eungeprüfte §7Schematic gewählt§8!
TEAM_READY=§aTeam bereit
TEAM_NOT_READY=§c§mTeam bereit
SKIP_READY=§aBeschleunigung zum nächsten Event

Datei anzeigen

@ -35,13 +35,13 @@ import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Note;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Lectern;
import org.bukkit.block.data.*;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Openable;
import org.bukkit.block.data.Powerable;
import org.bukkit.block.data.type.Comparator;
import org.bukkit.block.data.type.NoteBlock;
import org.bukkit.block.data.type.Repeater;
import org.bukkit.block.data.type.Switch;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@ -68,7 +68,7 @@ public abstract class AI {
return ais.get(uuid);
}
protected final FightTeam team;
private final FightTeam team;
private final LivingEntity entity;
private final BukkitTask task;
private final Queue<Action> queue = new ArrayDeque<>();
@ -120,22 +120,6 @@ public abstract class AI {
Chat.broadcastChat("PARTICIPANT_CHAT", team.getColoredName(), entity.getName(), message);
}
protected Vector toAIPosition(Vector location) {
Region extend = team.getExtendRegion();
if(Fight.getUnrotated() == team)
return new Vector(
location.getX() - extend.getMinX(),
location.getY() - team.getSchemRegion().getMinY(),
location.getZ() - extend.getMinZ()
);
else
return new Vector(
extend.getMaxX() - location.getX(),
location.getY() - team.getSchemRegion().getMinY(),
extend.getMaxZ() - location.getZ()
);
}
protected Vector getPosition() {
Location location = entity.getLocation();
Region extend = team.getExtendRegion();
@ -171,10 +155,8 @@ public abstract class AI {
return;
Location location = translate(pos, true);
if(interactionDistanceViolation(location)) {
chat("2 smoll pepe hönds!");
if(interactionDistanceViolation(location))
return;
}
Block block = location.getBlock();
if(block.getType() == Material.AIR)
@ -188,10 +170,8 @@ public abstract class AI {
@Override
public void run() {
Location location = translate(pos, true);
if(interactionDistanceViolation(location)) {
chat("Ich komme da nicht dran!");
if(interactionDistanceViolation(location))
return;
}
interact(location.getBlock());
}
@ -225,17 +205,15 @@ public abstract class AI {
public void run() {
Location location = entity.getLocation();
Location target = translate(pos, false);
/*
if(Math.abs(location.getX() - target.getX()) > 1 || Math.abs(location.getY() - target.getY()) > 1.2 || Math.abs(location.getZ() - target.getZ()) > 1) {
FightSystem.getPlugin().getLogger().log(Level.INFO, () -> entity.getName() + ": Overdistance movement " + location.toVector() + " " + target.toVector());
return;
}
*/
if(!team.getFightPlayer(entity).canEntern() && !team.getExtendRegion().inRegion(target))
return;
entity.teleport(target, PlayerTeleportEvent.TeleportCause.PLUGIN);
entity.teleport(target, PlayerTeleportEvent.TeleportCause.COMMAND);
}
});
}
@ -271,34 +249,12 @@ public abstract class AI {
powerable.setPowered(false);
block.setBlockData(powerable);
updateButton(block);
}, type.name().endsWith("STONE_BUTTON") ? 20 : 30);
}
powerable.setPowered(!isPowered);
}
block.setBlockData(data);
if(data instanceof Switch) {
updateButton(block);
}
}
private void updateButton(Block block) {
Switch sw = (Switch) block.getBlockData();
FaceAttachable.AttachedFace face = sw.getAttachedFace();
if (face == FaceAttachable.AttachedFace.FLOOR) {
update(block.getRelative(BlockFace.DOWN));
} else if (face == FaceAttachable.AttachedFace.CEILING) {
update(block.getRelative(BlockFace.UP));
} else {
update(block.getRelative(sw.getFacing().getOppositeFace()));
}
}
private void update(Block block) {
BlockData data = block.getBlockData();
block.setType(Material.BARRIER);
block.setBlockData(data);
}
private void run() {
@ -309,7 +265,7 @@ public abstract class AI {
queue.poll().run();
}
public Location translate(Vector pos, boolean blockPos) {
private Location translate(Vector pos, boolean blockPos) {
Region extend = team.getExtendRegion();
if(Fight.getUnrotated() == team)
return new Location(

Datei anzeigen

@ -19,102 +19,42 @@
package de.steamwar.fightsystem.ai;
import de.steamwar.entity.REntityServer;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.ai.navmesh.NavMesh;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import java.util.*;
import java.util.List;
import java.util.Random;
public class LixfelAI extends AI {
private final Random random = new Random();
private final REntityServer entityServer = new REntityServer();
private final FightTeam team;
private final NavMesh navMesh;
private LixfelPathplanner pathplanner;
public LixfelAI(FightTeam team, SteamwarUser user) {
super(team, user);
this.team = team;
navMesh = new NavMesh(team, entityServer);
public LixfelAI(FightTeam team, String user) {
super(team, SteamwarUser.get(user));
}
@Override
public SchematicNode chooseSchematic() {
if (false) {
List<SchematicNode> publics = SchematicNode.getAllSchematicsOfType(0, Config.SchematicType.toDB());
SchematicNode schem = publics.get(new Random().nextInt(publics.size()));
return schem;
}
// return SchematicNode.byIdAndUser(SteamwarUser.get(0), 111476);
return SchematicNode.byIdAndUser(SteamwarUser.get(0), 98711);
List<SchematicNode> publics = SchematicNode.getAllSchematicsOfType(0, Config.SchematicType.toDB());
SchematicNode schem = publics.get(new Random().nextInt(publics.size()));
pathplanner = new LixfelPathplanner(schem);
return schem;
}
@Override
public boolean acceptJoinRequest(Player player, FightTeam team) {
if (team == this.team) {
entityServer.addPlayer(player);
}
return super.acceptJoinRequest(player, team);
}
private Vector source = null;
private Vector destination = null;
private int index = 0;
@Override
protected void plan() {
setReady();
if (navMesh == null) return;
if (!getEntity().isOnGround() && getEntity().getLocation().getBlock().getType() != Material.LADDER) return;
if (source == null || destination == null) {
source = getEntity().getLocation().toVector();
List<Vector> walkableBlocks = navMesh.getWalkableBlocks(source);
if (walkableBlocks.isEmpty()) return;
destination = walkableBlocks.get(random.nextInt(walkableBlocks.size()));
index = 0;
}
List<Vector> oldRoute = navMesh.path(source, destination);
navMesh.update(getEntity().getLocation().toVector());
List<Vector> path = navMesh.path(source, destination);
// TODO: New Route detection
if (path.isEmpty()) {
source = null;
destination = null;
chat("no route");
return;
}
if (!oldRoute.equals(path)) {
source = getEntity().getLocation().toVector();
index = 0;
chat("new route");
return;
}
if (index == 0) {
chat(source + " -> " + destination + " = " + path.size());
}
if (index > path.size()) {
source = null;
destination = null;
chat("route cancelled");
return;
}
Vector location = path.get(index++);
move(toAIPosition(location));
if (index == path.size()) {
source = null;
destination = null;
Vector destination = pathplanner.getWalkable().get(random.nextInt(pathplanner.getWalkable().size()));
List<Vector> path = pathplanner.plan(getPosition(), destination);
if(!path.isEmpty())
chat("Path size: " + path.size());
for(Vector p : path) {
move(p);
}
}
}

Datei anzeigen

@ -19,60 +19,30 @@
package de.steamwar.fightsystem.ai;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockType;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.utils.WorldeditWrapper;
import de.steamwar.sql.SchematicData;
import de.steamwar.sql.SchematicNode;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.*;
import org.bukkit.util.Vector;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
public class LixfelPathplanner {
private static double blockHeight(Clipboard clipboard, BlockVector3 vector) {
BaseBlock block = clipboard.getFullBlock(vector);
if(block.getBlockType().getMaterial().isFullCube())
return 1.0;
BlockData data = BukkitAdapter.adapt(block);
Material material = data.getMaterial();
if(material.isSolid()) {
if(material.isInteractable()) {
if(data instanceof Stairs)
return 1.0;
else if(data instanceof Fence)
return 1.5;
else if(data instanceof Bed)
return 0.5625;
} else {
if(data instanceof Slab)
return ((Slab)data).getType() == Slab.Type.BOTTOM ? 0.5 : 1.0;
else if(data instanceof Wall)
return 1.5;
else if(data instanceof GlassPane || material == Material.IRON_BARS)
return 1.0;
}
} else {
if(material == Material.LADDER || material == Material.SCAFFOLDING)
return -1.0;
else if(material.name().endsWith("_CARPET"))
return 0.0625;
}
return 0.0;
private static BlockType getBlockType(Clipboard clipboard, BlockVector3 vector) {
return clipboard.getBlock(vector).getBlockType();
}
private static Vector toBukkit(BlockVector3 vector, double height) {
return new Vector(vector.getX() + 0.5, vector.getY() + height, vector.getZ() + 0.5);
private static boolean nonsolid(Clipboard clipboard, BlockVector3 vector) {
return !getBlockType(clipboard, vector).getMaterial().isSolid();
}
private static Vector toBukkit(BlockVector3 vector) {
return new Vector(vector.getX() + 0.5, vector.getY(), vector.getZ() + 0.5);
}
private final List<Vector> walkable = new ArrayList<>();
@ -91,33 +61,25 @@ public class LixfelPathplanner {
}
private void fillWalkable(Clipboard clipboard) {
Vector clipboardToSchem = new Vector(Config.BluePasteRegion.getSizeX(), Config.BluePasteRegion.getSizeY(), Config.BluePasteRegion.getSizeZ())
.subtract(WorldeditWrapper.impl.getDimensions(clipboard))
.multiply(0.5)
.add(new Vector(Config.PreperationArea, 0, Config.PreperationArea));
BlockVector3 diff = clipboard.getRegion().getMinimumPoint().subtract(clipboardToSchem.getBlockX(), clipboardToSchem.getBlockY(), clipboardToSchem.getBlockZ());
BlockVector3 min = clipboard.getRegion().getMinimumPoint().subtract(Config.PreperationArea, 0, Config.PreperationArea); //TODO assumes nonextended Schematic with maximal size
Region region = clipboard.getRegion();
clipboard.getRegion().forEach(vector -> {
BlockVector3 below = vector.subtract(0, 1, 0);
if(!region.contains(below))
return;
BlockType belowMaterial = getBlockType(clipboard, below);
BlockVector3 above = vector.add(0, 1, 0);
double aboveHeight = region.contains(above) ? blockHeight(clipboard, above) : 0.0;
if(aboveHeight > 0.0)
return;
double belowHeight = region.contains(below) ? blockHeight(clipboard, below) : 0.0;
double height = blockHeight(clipboard, vector);
if(height == 0.0 && Math.abs(belowHeight) < 1.0)
return;
if(height >= 1.0 && region.contains(above))
return;
if(height < 0.0)
height = 0.0;
walkable.add(toBukkit(vector.subtract(diff), height));
if(nonsolid(clipboard, vector)) {
if(
(belowMaterial.getMaterial().isSolid() || belowMaterial.getId().equals("minecraft:ladder")) &&
(!region.contains(above) || nonsolid(clipboard, above))
)
walkable.add(toBukkit(vector.subtract(min)));
} else {
if(!region.contains(above))
walkable.add(toBukkit(above.subtract(min)));
}
});
for(Vector vector : walkable) {
@ -125,42 +87,24 @@ public class LixfelPathplanner {
}
}
@Deprecated
public Vector walkableNearby(double eyeHeight, double distance, List<Vector> nearby) {
List<Vector> moddedNearby = nearby.stream().map(n -> n.clone().subtract(new Vector(0, eyeHeight, 0))).collect(Collectors.toList());
return walkable.stream()
.filter(vector -> moddedNearby.stream()
.allMatch(n -> n.distance(vector) <= distance && !neighbouring(n, vector)))
.findAny().orElse(null);
}
public List<Vector> planToAnywhere(Vector start, Vector destination) {
Vector intermediate = walkable.stream().filter(vector -> neighbouring(vector, destination)).findAny().orElse(null);
if(intermediate == null)
return Collections.emptyList();
List<Vector> plan = new ArrayList<>(plan(start, intermediate));
List<Vector> plan = plan(start, intermediate);
plan.add(destination);
return plan;
}
public List<Vector> planToRange(Vector start, Vector destination, double range) {
return plan(start, walkable.stream().filter(vector -> vector.distance(destination) <= range).collect(Collectors.toList()));
}
public List<Vector> plan(Vector start, Vector destination) {
return plan(start, Collections.singletonList(destination));
}
public List<Vector> plan(Vector start, List<Vector> destinations) {
for(Vector destination : destinations)
if(neighbouring(start, destination))
return Collections.singletonList(destination);
if(neighbouring(start, destination))
return Collections.singletonList(destination);
Map<Vector, Vector> approach = new HashMap<>();
Set<Vector> checking = new HashSet<>(destinations);
Set<Vector> checking = Collections.singleton(destination);
while(!checking.isEmpty()) {
Set<Vector> toCheck = new HashSet<>();
@ -178,7 +122,7 @@ public class LixfelPathplanner {
List<Vector> path = new ArrayList<>();
path.add(firstStep);
while(!destinations.contains(path.get(path.size()-1))) {
while(path.get(path.size()-1) != destination) {
path.add(approach.get(path.get(path.size()-1)));
}

Datei anzeigen

@ -1,267 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2023 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.ai.chaos;
import de.steamwar.entity.REntityServer;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.ai.AI;
import de.steamwar.fightsystem.ai.chaos.gears.Gear;
import de.steamwar.fightsystem.ai.chaos.gears.TheUnderground;
import de.steamwar.fightsystem.ai.navmesh.NavMesh;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.util.Vector;
import java.util.*;
public class ChaosAI extends AI {
private State state = State.PRE_PREPARE;
private static final Gear gear = TheUnderground.THE_UNDERGROUND;
private Cannon currentCannon;
private boolean igniteMg = false;
private static final Random random = new Random();
public static Map<FightTeam, Boolean> onePrepares = new HashMap<>();
private boolean prepares = false;
private static final Map<FightTeam, Set<Cannon>> cannonsShot = new HashMap<>();
private final NavMesh navMesh;
private final REntityServer entityServer = new REntityServer();
private Vector source = null;
private Vector destination = null;
private int index = 0;
private State nextState = null;
public ChaosAI(FightTeam team) {
this(team, SteamwarUser.get(14533));
}
public ChaosAI(FightTeam team, SteamwarUser user) {
super(team, user);
this.navMesh = new NavMesh(team, entityServer);
if (Boolean.FALSE.equals(onePrepares.getOrDefault(team, false))) {
prepares = true;
onePrepares.put(team, true);
}
}
@Override
public SchematicNode chooseSchematic() {
return SchematicNode.getSchematicNode(gear.getSchematicId());
}
@Override
protected void plan() {
switch (state) {
case PRE_PREPARE:
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
state = State.PREPARE;
}, 20 * 15);
state = State.WAIT;
break;
case PREPARE:
prepare();
break;
case PREPARE_READY:
if (prepares) {
for (Vector prepareButton : gear.getPrepareButtons()) {
interact(prepareButton);
}
}
setReady();
state = State.WAIT_TILL_START;
break;
case WAIT_TILL_START:
if (FightState.ingame()) {
state = State.IGNITE_MG;
startFight();
}
break;
case IGNITE_MG:
if(igniteMg) {
if (prepares) {
interact(gear.getMgButton());
chat("Die MG ist angezündet!");
}
state = State.WAIT;
currentCannon = randomCannon();
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> state = State.FIGHT, 20 * 9);
}
break;
case FIGHT:
fireCannon(currentCannon);
break;
case LOAD_CANNON:
loadCannon(currentCannon);
break;
case ESCAPE:
cannonsShot.computeIfAbsent(team, fightTeam -> new HashSet<>()).remove(currentCannon);
currentCannon = randomCannon();
state = State.WAIT;
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> state = State.FIGHT, 20 * 4);
break;
case WAIT:
break;
case WALK:
if (!getEntity().isOnGround() && getEntity().getLocation().getBlock().getType() != Material.LADDER) return;
List<Vector> oldRoute = navMesh.path(source, destination);
navMesh.update(getEntity().getLocation().toVector());
List<Vector> path = navMesh.path(source, destination);
if (path.isEmpty()) {
source = null;
destination = null;
state = nextState;
chat("no route");
return;
}
if (!oldRoute.equals(path)) {
source = getEntity().getLocation().toVector();
index = 0;
chat("new route");
return;
}
if (index == 0) {
chat(source + " -> " + destination + " = " + path.size());
}
Vector loc = path.get(index++);
move(toAIPosition(loc));
if (index == path.size()) {
source = null;
destination = null;
state = nextState;
}
break;
}
}
private void moveTo(Vector vec, State nextState) {
source = getEntity().getLocation().toVector();
Vector currentBest = null;
for (Vector vector : navMesh.getWalkableBlocks(source)) {
if (currentBest == null || vector.distanceSquared(vec) < currentBest.distanceSquared(vec)) {
currentBest = vector;
}
}
destination = currentBest;
index = 0;
state = State.WALK;
this.nextState = nextState;
}
@Override
public void stop() {
chat("gege wp eZ win 4nus");
if (currentCannon != null) {
cannonsShot.computeIfAbsent(team, fightTeam -> new HashSet<>()).remove(currentCannon);
}
super.stop();
}
@Override
public boolean acceptJoinRequest(Player player, FightTeam team) {
if (team == this.team) {
entityServer.addPlayer(player);
}
return team == this.team;
}
public void fireCannon(Cannon cannon) {
chat("Ich feuere " + cannon.name + " an!");
moveTo(cannon.load.clone().add(new Vector(0.5, 0, 0.5)), State.LOAD_CANNON);
}
private void loadCannon(Cannon cannon) {
if (cannon.button == null) {
for (int i = 0; i < 20; i++) {
for (Vector vector : cannon.tnt) {
setTNT(vector);
}
for (int j = 0; j < 30; j++) {
getBlock(gear.getMgButton());
}
}
} else {
for (Vector vector : cannon.tnt) {
setTNT(vector);
}
interact(cannon.button);
}
if (currentCannon.escape != null) {
moveTo(cannon.getEscape().clone().add(new Vector(0.5, 0, 0.5)), State.ESCAPE);
}
}
private Cannon randomCannon() {
Cannon nextCannon = gear.getCannons()[random.nextInt(gear.getCannons().length)];
while (cannonsShot.computeIfAbsent(team, fightTeam -> new HashSet<>()).contains(nextCannon)) {
nextCannon = gear.getCannons()[random.nextInt(gear.getCannons().length)];
}
cannonsShot.computeIfAbsent(team, fightTeam -> new HashSet<>()).add(nextCannon);
return nextCannon;
}
public void startFight() {
chat("gl&hf");
if (prepares) {
chat("Ich zünde die MG an!");
}
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
igniteMg = true;
}, 20L * gear.getMgTime());
}
public void prepare() {
chat("Prepare your fkin 4nus");
if (prepares) {
moveTo(gear.getBridge().clone().add(new Vector(0.5, 0, 0.5)), State.PREPARE_READY);
}
}
private enum State {
PRE_PREPARE,
PREPARE,
PREPARE_READY,
WAIT_TILL_START,
IGNITE_MG,
FIGHT,
LOAD_CANNON,
ESCAPE,
WAIT,
WALK,
}
}

Datei anzeigen

@ -1,66 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2023 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.ai.chaos.gears;
import de.steamwar.fightsystem.ai.chaos.Cannon;
import org.bukkit.util.Vector;
public class Gear {
private final Cannon[] cannons;
private final Vector bridge;
private final Vector[] prepareButtons;
private final Vector mgButton;
private final int mgTime;
private final int schematicId;
protected Gear(Cannon[] cannons, Vector bridge, Vector[] prepareButtons, Vector mgButton, int mgTime, int schematicId) {
this.cannons = cannons;
this.bridge = bridge;
this.prepareButtons = prepareButtons;
this.mgButton = mgButton;
this.mgTime = mgTime;
this.schematicId = schematicId;
}
public Cannon[] getCannons() {
return cannons;
}
public Vector getBridge() {
return bridge;
}
public Vector[] getPrepareButtons() {
return prepareButtons;
}
public Vector getMgButton() {
return mgButton;
}
public int getMgTime() {
return mgTime;
}
public int getSchematicId() {
return schematicId;
}
}

Datei anzeigen

@ -1,184 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2023 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.ai.chaos.gears;
import de.steamwar.fightsystem.ai.chaos.Cannon;
import org.bukkit.util.Vector;
public class TheUnderground {
public static final Vector[] DS_LEFT_TNT = new Vector[] {
new Vector(40, 24, 12),
new Vector(39, 24, 12),
new Vector(38, 23, 12),
new Vector(38, 24, 12),
new Vector(40, 23, 15),
new Vector(40, 23, 14),
new Vector(40, 24, 15),
new Vector(40, 24, 14),
new Vector(38, 23, 15),
new Vector(38, 23, 14),
new Vector(38, 24, 15),
new Vector(38, 24, 14),
new Vector(40, 23, 12),
};
public static final Vector DS_LEFT_BUTTON = new Vector(39, 25, 11);
public static final Vector DS_LEFT_LOAD = new Vector(39, 25, 13);
public static final Vector DS_LEFT_ESCAPE = new Vector(31, 26, 13);
public static final Cannon DS_LEFT = new Cannon("Downstäb Links", DS_LEFT_TNT, DS_LEFT_BUTTON, DS_LEFT_LOAD, DS_LEFT_ESCAPE);
public static final Vector[] DS_RIGHT_TNT = new Vector[] {
new Vector(12, 24, 12),
new Vector(11, 24, 12),
new Vector(10, 23, 12),
new Vector(10, 24, 12),
new Vector(10, 23, 15),
new Vector(10, 23, 14),
new Vector(10, 24, 15),
new Vector(10, 24, 14),
new Vector(12, 23, 14),
new Vector(12, 24, 14),
new Vector(12, 23, 15),
new Vector(12, 24, 15),
new Vector(12, 23, 12),
};
public static final Vector DS_RIGHT_BUTTON = new Vector(11, 25, 11);
public static final Vector DS_RIGHT_LOAD = new Vector(11, 25, 13);
public static final Vector DS_RIGHT_ESCAPE = new Vector(19, 26, 13);
public static final Cannon DS_RIGHT = new Cannon("Downstäb Rechts", DS_RIGHT_TNT, DS_RIGHT_BUTTON, DS_RIGHT_LOAD, DS_RIGHT_ESCAPE);
public static final Vector[] STATIC_LEFT_TNT = new Vector[] {
new Vector(37, 17, 15),
new Vector(37, 17, 14),
new Vector(37, 18, 16),
new Vector(37, 18, 15),
new Vector(37, 18, 14),
new Vector(36, 17, 16),
new Vector(36, 17, 15),
new Vector(36, 17, 14),
new Vector(36, 18, 16),
new Vector(36, 18, 15),
new Vector(36, 18, 14),
new Vector(37, 17, 16),
};
public static final Vector STATIC_LEFT_BUTTON = new Vector(38, 18, 11);
public static final Vector STATIC_LEFT_LOAD = new Vector(37, 17, 12);
public static final Vector STATIC_LEFT_ESCAPE = new Vector(30, 13, 9);
public static final Cannon STATIC_LEFT = new Cannon("Lupf Links", STATIC_LEFT_TNT, STATIC_LEFT_BUTTON, STATIC_LEFT_LOAD, STATIC_LEFT_ESCAPE);
public static final Vector[] STATIC_RIGHT_TNT = new Vector[] {
new Vector(14, 17, 15),
new Vector(14, 18, 16),
new Vector(14, 18, 15),
new Vector(14, 17, 14),
new Vector(14, 18, 14),
new Vector(13, 17, 16),
new Vector(13, 17, 15),
new Vector(13, 17, 14),
new Vector(13, 18, 16),
new Vector(13, 18, 15),
new Vector(13, 18, 14),
new Vector(14, 17, 16),
};
public static final Vector STATIC_RIGHT_BUTTON = new Vector(12, 18, 11);
public static final Vector STATIC_RIGHT_LOAD = new Vector(13, 17, 12);
public static final Vector STATIC_RIGHT_ESCAPE = new Vector(20, 13, 9);
public static final Cannon STATIC_RIGHT = new Cannon("Lupf Rechts", STATIC_RIGHT_TNT, STATIC_RIGHT_BUTTON, STATIC_RIGHT_LOAD, STATIC_RIGHT_ESCAPE);
public static final Vector[] AK_TNT = new Vector[] {
new Vector(10, 7, 17),
new Vector(10, 11, 17),
new Vector(10, 10, 17),
new Vector(10, 8, 17),
new Vector(10, 9, 17),
new Vector(10, 7, 15),
new Vector(11, 7, 15),
new Vector(12, 7, 15),
new Vector(10, 10, 15),
new Vector(11, 10, 15),
new Vector(12, 10, 15),
new Vector(12, 8, 15),
new Vector(12, 9, 15),
new Vector(11, 8, 15),
new Vector(11, 9, 15),
new Vector(10, 8, 15),
new Vector(10, 9, 15),
new Vector(10, 7, 19),
new Vector(11, 7, 19),
new Vector(12, 7, 19),
new Vector(12, 8, 19),
new Vector(11, 8, 19),
new Vector(10, 8, 19),
new Vector(10, 10, 19),
new Vector(11, 10, 19),
new Vector(12, 10, 19),
new Vector(12, 9, 19),
new Vector(11, 9, 19),
new Vector(10, 9, 19),
new Vector(10, 6, 17),
};
public static final Vector AK_BUTTON = new Vector(9, 9, 16);
public static final Vector AK_LOAD = new Vector(11, 8, 17);
public static final Cannon AK = new Cannon("Arschkratzer", AK_TNT, AK_BUTTON, AK_LOAD, null);
public static final Vector[] HA_RIGHT_TNT = new Vector[] {
new Vector(23, 5, 9),
new Vector(23, 6, 9),
new Vector(23, 7, 9),
new Vector(23, 8, 9),
};
public static final Vector[] HA_LEFT_TNT = new Vector[] {
new Vector(27, 5, 9),
new Vector(27, 6, 9),
new Vector(27, 7, 9),
new Vector(27, 8, 9),
};
public static final Vector HA_RIGHT_LOAD = new Vector(23, 8, 8);
public static final Vector HA_LEFT_LOAD = new Vector(27, 8, 8);
public static final Cannon HA_LEFT = new Cannon("Halbautomatik Links", HA_LEFT_TNT, null, HA_LEFT_LOAD, null);
public static final Cannon HA_RIGHT = new Cannon("Halbautomatik Rechts", HA_RIGHT_TNT, null, HA_RIGHT_LOAD, null);
public static final Vector BRIDGE_POS = new Vector(25, 14, 24);
public static final Vector BRIDGE_SHIELDS = new Vector(25, 15, 25);
public static final Vector BRIDGE_MG = new Vector(21, 15, 24);
public static final Gear THE_UNDERGROUND = new Gear(
new Cannon[] {
DS_LEFT,
DS_RIGHT,
STATIC_LEFT,
STATIC_RIGHT,
AK,
HA_LEFT,
HA_RIGHT,
//Cannon.AK,
},
BRIDGE_POS,
new Vector[] {
BRIDGE_SHIELDS
},
BRIDGE_MG,
21,
124667
);
}

Datei anzeigen

@ -1,25 +0,0 @@
event(events.PlaceBlock, function(e)
if storage.player.get("recording") then
pos = {math.floor(e.x), math.floor(e.y) - 100, math.floor(e.z)}
storage.player.get("recordingPos")[storage.player.get("recordingCount")] = pos
storage.player.set("recordingCount", storage.player.get("recordingCount") + 1)
end
end)
command("recorder", function(args)
if storage.player.get("recording") then
storage.player.set("recording", false)
storage.player.set("recordingCount", 0)
print("private static final Vector[] positions = new Vector[] {")
for k, v in pairs(storage.player.get("recordingPos")) do
print("new Vector(" .. v[1] .. ", " .. v[2] .. ", " .. v[3] .. "),")
end
print("};")
print("Stopped recording")
else
storage.player.set("recording", true)
storage.player.set("recordingCount", 0)
storage.player.set("recordingPos", {})
print("Started recording")
end
end)

Datei anzeigen

@ -1,343 +0,0 @@
-- This file is a part of the SteamWar software.
--
-- Copyright (C) 2021 SteamWar.de-Serverteam
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
---
--- This file contains the definitions for the SteamWar.de script API.
--- It is used by the IDE to provide code completion and type checking.
--- Created by Chaoscaot
---
inventory = {}
---@param title string
---@param size number
---@return Inventory
function inventory.create(title, size) return nil end
---@alias InventoryClick 'LEFT' | 'SHIFT_LEFT' | 'RIGHT' | 'SHIFT_RIGHT' | 'MIDDLE' | 'NUMBER_KEY'
---@class Inventory
local Inventory = {}
---@overload fun(slot: number, material: string, name: string, handler: fun(click: InventoryClick)): void
---@overload fun(slot: number, material: string, name: string, handler: fun(click: InventoryClick), lore: string[]): void
---@overload fun(slot: number, material: string, name: string, handler: fun(click: InventoryClick), lore: string[], enchanted: boolean): void
---@param slot number
---@param material string
---@param name string
---@param handler fun(click: InventoryClick): void
---@param lore string[]
---@param enchanted boolean
---@param amount number
---@return void
function Inventory.item(slot, material, name, handler, lore, enchanted, amount) end
---@param handler fun(): void
---@return void
function Inventory.setCloseHandler(handler) end
---@return void
function Inventory.open() end
player = {}
---@return string
---Get the name of the player.
function player.name() return "" end
---@return void
function player.chat(...) end
---@return void
---Send a message to the actionbar of the player.
function player.actionbar(...) end
---@overload fun(): number
---@param newX number
function player.x(newX) end
---@overload fun(): number
---@param newY number
function player.y(newY) end
---@overload fun(): number
---@param newZ number
function player.z(newZ) end
---@overload fun(): number
---@param newYaw number
function player.yaw(newYaw) end
---@overload fun(): number
---@param newPitch number
function player.pitch(newPitch) end
---@return boolean
function player.sneaking() return nil end
---@return boolean
function player.sprinting() return nil end
---@overload fun(): number
---@param newSlot number
function player.slot(newSlot) end
---@return string
function player.item() return nil end
---@return string
function player.offHandItem() return nil end
---@return void
function player.closeInventory() end
---@field nextBool fun(): boolean
random = {}
---@overload fun(): number
---@overload fun(bound: number): number
---@param origin number
---@param bound number
---@return number
function random.nextInt(origin, bound) return nil end
---@overload fun(): number
---@overload fun(bound: number): number
---@param origin number
---@param bound number
---@return number
function random.nextDouble(origin, bound) return nil end
---@return boolean
function random.nextBool() return nil end
---@alias RegionType 'wg' | 'mwg' | 'as' | 'ws' | 'ws_inner' | 'ws_rumpf' | 'ws_rahmen' | 'spawn'
---@class iregion
---@field tnt tnt
---@field trace trace
local iregion = {}
---@class region: iregion
region = {}
---@return string
function iregion.name() return nil end
---@return RegionType
function iregion.type() return nil end
---@return boolean
function iregion.fire() return nil end
---@return boolean
function iregion.freeze() return nil end
---@return boolean
function iregion.protect() return nil end
---@return string
function iregion.loader() return nil end
---@alias TNTMode 'ALLOW' | 'DENY' | 'ONLY_TB'
---@class tnt
local tnt = {}
---@return TNTMode
function tnt.mode() return nil end
---@return boolean
function tnt.enabled() return nil end
---@return boolean
function tnt.onlyTb() return nil end
---@class trace
local trace = {}
---@return boolean
function trace.active() return nil end
---@return boolean
function trace.auto() return nil end
---@return string
function trace.status() return nil end
---@return number
function trace.time() return nil end
---@param name string
---@return iregion
function region.get(name) return nil end
---@return iregion[]
function region.list() return nil end
---@class Position
---@field x number
---@field y number
---@field z number
---@class server
---@field tps tps
server = {}
---@return string
function server.time() return nil end
---@return number
function server.ticks() return nil end
---@param position Position
---@return string
function getBlockAt(position) return nil end
---@param position Position
---@param material string
---@return void
function setBlockAt(position, material) return nil end
---@class tps
local tps = {}
---@return number
function tps.oneSecond() return nil end
---@return number
function tps.tenSecond() return nil end
---@return number
function tps.oneMinute() return nil end
---@return number
function tps.fiveMinute() return nil end
---@return number
function tps.tenMinute() return nil end
---@return number
function tps.current() return nil end
---@return number
function tps.limit() return nil end
---@class storage
---@field global storageLib
---@field player storageLib
---@field region storageLib
storage = {}
---@class storageLib
local storageLib = {}
---@param key string
---@return any
function storageLib.get(key) return nil end
---@param key string
---@param value any
---@return void
function storageLib.set(key, value) end
---@param key string
---@return boolean
function storageLib.has(key) return nil end
---@param key string
---@return void
function storageLib.remove(key) end
---@param key string
---@return Accessor
function storageLib.accessor(key) return nil end
---@class Accessor
---@overload fun(): any
---@overload fun(value: any)
---@class Selection
---@field max Position
---@field min Position
---@class _worldedit
_worldedit = {}
---@overload fun(pos: Position[]): void
---@return Selection
function _worldedit.selection() return nil end
---@param msg string
---@param callback fun(value: string): void
---@return void
function input(msg, callback) end
---@param ticks number
---@param callback fun(): void
---@return void
function delayed(ticks, callback) end
---@param x number
---@param y number
---@param z number
---@return Position
function pos(x, y, z) return nil end
---@return void
function exec(...) end
---@param obj any
---@return number
function length(obj) return 0 end
---@param separator string
---@param table any[]
---@return string
function join(separator, table) return "" end
---@class EventType
---@class events
---@field DoubleSwap EventType
---@field PlaceBlock EventType
---@field BreakBlock EventType
---@field RightClick EventType
---@field LeftClick EventType
---@field TNTSpawn EventType
---@field TNTExplode EventType
---@field TNTExplodeInBuild EventType
---@field SelfJoin EventType
---@field SelfLeave EventType
---@field DropItem EventType
---@field EntityDeath EventType
events = {}
---@param id EventType
---@param handler fun(params: any): void
---@return void
function event(id, handler) end
---@param command string
---@param handler fun(params: string[]): void
---@return void
function command(command, handler) end
---@param trigger string
---@param handler fun(pressed: boolean): void
---@return void
function hotkey(trigger, handler) end

Datei anzeigen

@ -1,386 +0,0 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2023 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.ai.navmesh;
import de.steamwar.entity.RArmorStand;
import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityServer;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.OneShotStateDependent;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.event.Listener;
import org.bukkit.util.BoundingBox;
import org.bukkit.util.Vector;
import org.bukkit.util.VoxelShape;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
public class NavMesh implements Listener {
private static final World WORLD = Bukkit.getWorlds().get(0);
private static final double PLAYER_JUMP_HEIGHT = 1.25;
private static final double PLAYER_HEIGHT = 1.8125;
private static final BoundingBox PLAYER_SHADOW = new BoundingBox(0.2, 0, 0.2, 0.8, 1, 0.8);
private static final Set<Pos> RELATIVE_BLOCKS_TO_CHECK = new HashSet<>();
static {
for (int y = -2; y <= 2; y++) {
RELATIVE_BLOCKS_TO_CHECK.add(new Pos(BlockFace.NORTH.getDirection().setY(y)));
RELATIVE_BLOCKS_TO_CHECK.add(new Pos(BlockFace.SOUTH.getDirection().setY(y)));
RELATIVE_BLOCKS_TO_CHECK.add(new Pos(BlockFace.EAST.getDirection().setY(y)));
RELATIVE_BLOCKS_TO_CHECK.add(new Pos(BlockFace.WEST.getDirection().setY(y)));
}
RELATIVE_BLOCKS_TO_CHECK.add(new Pos(BlockFace.UP.getDirection()));
RELATIVE_BLOCKS_TO_CHECK.add(new Pos(BlockFace.DOWN.getDirection()));
}
private FightTeam fightTeam;
private List<REntity> rEntities = new ArrayList<>();
private REntityServer entityServer;
public NavMesh(FightTeam fightTeam, REntityServer entityServer) {
this.fightTeam = fightTeam;
this.entityServer = entityServer;
new OneShotStateDependent(ArenaMode.All, FightState.PostSchemSetup, () -> {
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
long time = System.currentTimeMillis();
fightTeam.getExtendRegion().forEach((x, y, z) -> {
if (y < fightTeam.getSchemRegion().getMinY()) return;
checkWalkable(x, y, z);
});
floorBlock.forEach(this::checkNeighbouring);
System.out.println(System.currentTimeMillis() - time + " ms");
iterateWalkableBlocks((vector, ceilingOffset) -> {
RArmorStand armorStand = new RArmorStand(entityServer, vector.toLocation(WORLD), RArmorStand.Size.MARKER);
armorStand.setNoGravity(true);
armorStand.setInvisible(true);
armorStand.setDisplayName("+" + (ceilingOffset == null ? "" : ceilingOffset));
});
}, 20);
});
new OneShotStateDependent(ArenaMode.All, FightState.Spectate, () -> {
floorBlock.clear();
});
}
private static class Pos {
private int x;
private int y;
private int z;
public Pos(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public Pos(Vector vector) {
this.x = vector.getBlockX();
this.y = vector.getBlockY();
this.z = vector.getBlockZ();
}
@Override
public String toString() {
return x + "," + y + "," + z;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Pos)) return false;
Pos pos = (Pos) o;
return x == pos.x && y == pos.y && z == pos.z;
}
@Override
public int hashCode() {
return Objects.hash(x, y, z);
}
public Vector toVector() {
return new Vector(x, y, z);
}
public Pos add(Pos pos) {
return new Pos(x + pos.x, y + pos.y, z + pos.z);
}
public Pos subtract(Pos pos) {
return new Pos(x - pos.x, y - pos.y, z - pos.z);
}
}
private Map<Pos, Double> floorBlock = new HashMap<>();
private Map<Pos, Double> ceilingOffset = new HashMap<>();
private Map<Pos, Set<Pos>> neighbourConnections = new HashMap<>();
private Map<Pos, Set<Pos>> reverseNeighbourConnections = new HashMap<>();
private void checkWalkable(int x, int y, int z) {
Pos pos = new Pos(x, y, z);
floorBlock.remove(pos);
ceilingOffset.remove(pos);
Block block = WORLD.getBlockAt(x, y, z);
VoxelShape floor = block.getCollisionShape();
if (block.getType() != Material.LADDER && !overlaps(floor, 0, 0, 0)) return;
Double floorHeight = null;
for (BoundingBox box : floor.getBoundingBoxes()) {
double by = box.getMaxY();
if (!overlaps(floor, 0, by, 0)) {
if (floorHeight == null) {
floorHeight = by;
} else {
floorHeight = Math.min(floorHeight, by);
}
}
}
if (floorHeight == null) return;
Double ceilingOffset = null;
for (int cy = y + 1; cy < fightTeam.getExtendRegion().getMaxY(); cy++) {
VoxelShape current = WORLD.getBlockAt(x, cy, z).getCollisionShape();
if (!overlaps(current, 0, 0, 0)) continue;
Double ceilingHeight = null;
for (BoundingBox box : current.getBoundingBoxes()) {
double by = box.getMinY();
if (!overlaps(current, 0, -(1 - by), 0)) {
if (ceilingHeight == null) {
ceilingHeight = by;
} else {
ceilingHeight = Math.max(ceilingHeight, by);
}
}
}
if (ceilingHeight != null) {
ceilingOffset = cy - y + ceilingHeight - floorHeight;
}
break;
}
if (ceilingOffset != null && ceilingOffset < PLAYER_HEIGHT) return;
floorBlock.put(pos, y + floorHeight);
this.ceilingOffset.put(pos, ceilingOffset);
}
private void checkNeighbouring(Pos pos, double posFloorHeight) {
Set<Pos> connections = neighbourConnections.remove(pos);
if (connections != null) {
connections.forEach(p -> {
reverseNeighbourConnections.getOrDefault(pos.add(p), Collections.emptySet()).remove(pos);
});
}
for (Pos relativeCheck : RELATIVE_BLOCKS_TO_CHECK) {
Pos other = new Pos(pos.x + relativeCheck.x, pos.y + relativeCheck.y, pos.z + relativeCheck.z);
Double otherFloorHeight = floorBlock.get(other);
if (otherFloorHeight == null) continue;
if (otherFloorHeight > posFloorHeight && otherFloorHeight - posFloorHeight > PLAYER_JUMP_HEIGHT) continue;
// double floorDiff = Math.abs(posFloorHeight - otherFloorHeight);
// if (floorDiff > PLAYER_JUMP_HEIGHT) continue;
Double posCeilingOffset = ceilingOffset.get(pos);
Double otherCeilingOffset = ceilingOffset.get(other);
if (posCeilingOffset == null && otherCeilingOffset == null) {
neighbourConnections.computeIfAbsent(pos, __ -> new LinkedHashSet<>()).add(relativeCheck);
reverseNeighbourConnections.computeIfAbsent(pos.add(relativeCheck), __ -> new LinkedHashSet<>()).add(pos);
continue;
}
if (posCeilingOffset != null && otherCeilingOffset == null) {
if (posFloorHeight + posCeilingOffset - otherFloorHeight >= PLAYER_HEIGHT) {
neighbourConnections.computeIfAbsent(pos, __ -> new LinkedHashSet<>()).add(relativeCheck);
reverseNeighbourConnections.computeIfAbsent(pos.add(relativeCheck), __ -> new LinkedHashSet<>()).add(pos);
}
continue;
}
if (otherCeilingOffset != null && posCeilingOffset == null) {
if (otherFloorHeight + otherCeilingOffset - posFloorHeight >= PLAYER_HEIGHT) {
neighbourConnections.computeIfAbsent(pos, __ -> new LinkedHashSet<>()).add(relativeCheck);
reverseNeighbourConnections.computeIfAbsent(pos.add(relativeCheck), __ -> new LinkedHashSet<>()).add(pos);
}
continue;
}
if (posFloorHeight + posCeilingOffset - otherFloorHeight >= PLAYER_HEIGHT && otherFloorHeight + otherCeilingOffset - posFloorHeight >= PLAYER_HEIGHT) {
neighbourConnections.computeIfAbsent(pos, __ -> new LinkedHashSet<>()).add(relativeCheck);
reverseNeighbourConnections.computeIfAbsent(pos.add(relativeCheck), __ -> new LinkedHashSet<>()).add(pos);
}
}
}
private boolean overlaps(VoxelShape voxelShape, double x, double y, double z) {
PLAYER_SHADOW.shift(x, y, z);
boolean overlaps = voxelShape.overlaps(PLAYER_SHADOW);
PLAYER_SHADOW.shift(-x, -y, -z);
return overlaps;
}
private void iterateWalkableBlocks(BiConsumer<Vector, Double> consumer) {
floorBlock.forEach((pos, aDouble) -> {
Vector vector = new Vector(pos.x + 0.5, aDouble, pos.z + 0.5);
consumer.accept(vector, ceilingOffset.get(pos));
});
}
private Pos toPos(Vector vector) {
Pos pos = new Pos(vector);
if (floorBlock.containsKey(pos)) return pos;
pos = new Pos(pos.x, pos.y - 1, pos.z);
if (floorBlock.containsKey(pos)) return pos;
return null;
}
public void update(Vector posVector) {
Pos pos = toPos(posVector);
if (pos == null) return;
for (int x = -2; x <= 2; x++) {
for (int z = -2; z <= 2; z++) {
for (int y = fightTeam.getSchemRegion().getMinY(); y <= pos.y + 2; y++) {
checkWalkable(pos.x + x, y, pos.z + z);
}
}
}
floorBlock.forEach(this::checkNeighbouring);
}
public List<Vector> getAllWalkableBlocks() {
return floorBlock.keySet().stream().map(Pos::toVector).collect(Collectors.toList());
}
public List<Vector> getWalkableBlocks(Vector fromVector) {
Pos from = toPos(fromVector);
if (from == null) {
return Collections.emptyList();
}
Set<Pos> checked = new HashSet<>();
List<Pos> checking = new ArrayList<>();
checking.add(from);
while (!checking.isEmpty()) {
Pos pos = checking.remove(0);
checked.add(pos);
neighbourConnections.getOrDefault(pos, new HashSet<>()).forEach(p -> {
Pos n = pos.add(p);
if (checked.contains(n)) return;
if (checking.contains(n)) return;
checking.add(n);
});
}
return checked.stream().map(Pos::toVector).collect(Collectors.toList());
}
public List<Vector> path(Vector fromVector, Vector toVector) {
rEntities.forEach(REntity::die);
rEntities.clear();
Pos from = toPos(fromVector);
Pos to = toPos(toVector);
if (from == null || to == null) {
return Collections.emptyList();
}
if (from.equals(to)) {
return Collections.emptyList();
}
List<Pos> checking = new ArrayList<>(Arrays.asList(to));
Map<Pos, Pos> route = new HashMap<>();
while (!checking.isEmpty()) {
Set<Pos> toCheck = new HashSet<>();
for (Pos pos : checking) {
boolean foundFrom = false;
Set<Pos> successors = reverseNeighbourConnections.get(pos);
for (Pos p : successors) {
if (route.containsKey(p)) continue;
route.put(p, pos);
toCheck.add(p);
foundFrom = p.equals(from);
if (foundFrom) break;
}
if (foundFrom) {
List<Pos> path = new ArrayList<>();
path.add(from);
while (path.get(path.size() - 1) != to) {
path.add(route.get(path.get(path.size() - 1)));
}
for (int i = path.size() - 1; i > 0; i--) {
Pos current = path.get(i);
Pos last = path.get(i - 1);
if (last.y > current.y) {
path.set(i, new Pos(current.x, last.y, current.z));
}
}
List<Vector> vectors = path.stream().map(p -> {
Double floorHeight = floorBlock.get(p);
if (p.y > (floorHeight == null ? p.y : floorHeight)) floorHeight = null;
return new Vector(p.x + 0.5, floorHeight == null ? p.y : floorHeight, p.z + 0.5);
}).collect(Collectors.toList());
AtomicReference<Vector> last = new AtomicReference<>();
vectors.forEach(vector -> {
RArmorStand armorStand = new RArmorStand(entityServer, vector.toLocation(WORLD), RArmorStand.Size.MARKER);
armorStand.setInvisible(true);
armorStand.setNoGravity(true);
armorStand.setDisplayName("+");
rEntities.add(armorStand);
if (true) return;
Vector lastVector = last.getAndSet(vector);
if (lastVector == null) return;
lastVector = lastVector.clone().add(vector).divide(new Vector(2, 2, 2));
armorStand = new RArmorStand(entityServer, lastVector.toLocation(WORLD), RArmorStand.Size.MARKER);
armorStand.setInvisible(true);
armorStand.setNoGravity(true);
armorStand.setDisplayName("+");
rEntities.add(armorStand);
});
return vectors;
}
}
checking.clear();
checking.addAll(toCheck);
}
return Collections.emptyList();
}
}

Datei anzeigen

@ -1,42 +0,0 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.commands;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.SimpleCommandMap;
import java.lang.reflect.Field;
public class CommandInjector {
private CommandInjector(){}
private static final String PACKAGE_NAME = Bukkit.getServer().getClass().getPackage().getName();
private static final String VERSION = PACKAGE_NAME.substring(PACKAGE_NAME.lastIndexOf('.') + 1);
public static void injectCommand(Command cmd) throws Exception {
Class serverClass = Class.forName("org.bukkit.craftbukkit." + VERSION + ".CraftServer");
Field f1 = serverClass.getDeclaredField("commandMap");
f1.setAccessible(true);
SimpleCommandMap commandMap = (SimpleCommandMap) f1.get(Bukkit.getServer());
commandMap.register("BauSystem", cmd);
}
}

Datei anzeigen

@ -19,6 +19,7 @@
package de.steamwar.fightsystem.commands;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight;
@ -28,12 +29,20 @@ import de.steamwar.fightsystem.fight.Kit;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.sql.PersonalKit;
import de.steamwar.sql.SteamwarUser;
import lombok.experimental.UtilityClass;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.entity.Player;
@UtilityClass
public class Commands {
private Commands(){}
private static final Reflection.FieldAccessor<SimpleCommandMap> commandMap = Reflection.getField("{obc}.CraftServer", "commandMap", SimpleCommandMap.class);
public static void injectCommand(Command cmd) {
commandMap.get(Bukkit.getServer()).register("FightSystem", cmd);
}
private static void errNoTeam(Player p){
FightSystem.getMessage().sendPrefixless("NO_TEAM", p, ChatMessageType.ACTION_BAR);

Datei anzeigen

@ -19,6 +19,7 @@
package de.steamwar.fightsystem.commands;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.*;
@ -29,6 +30,7 @@ import de.steamwar.inventory.*;
import de.steamwar.message.Message;
import de.steamwar.sql.PersonalKit;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SchematicType;
import de.steamwar.sql.SteamwarUser;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.Bukkit;
@ -48,7 +50,8 @@ public class GUI {
@SuppressWarnings("deprecation")
private static void addTeamRequest(Player p, SWInventory inv, int pos, FightTeam team) {
byte colorCode = ColorConverter.chat2dye(team.getColor()).getDyeData();
inv.setItem(pos, SWItem.getDye(colorCode), colorCode, msg.parse("JOIN_REQUEST_TEAM", p, team.getColoredName()), click -> {
String name = team.getLeader() != null ? team.getLeader().getEntity().getName() : team.getName();
inv.setItem(pos, SWItem.getDye(colorCode), colorCode, msg.parse("JOIN_REQUEST_TEAM", p, team.getColor() + name), click -> {
p.closeInventory();
new JoinRequest(p, team);
});
@ -167,27 +170,47 @@ public class GUI {
return;
}
SWInventory inv = new SWInventory(p, 9, msg.parse("SCHEM_TITLE", p, Config.GameName));
inv.setItem(8, Material.REDSTONE, msg.parse("SCHEM_PUBLIC", p, Config.GameName), (ClickType click) -> {
p.closeInventory();
schemDialog(p, true);
});
if(Fight.getMaxRank() == 0){
inv.setItem(0, SWItem.getDye(8), (byte)8, msg.parse("SCHEM_PRIVATE_FORBIDDEN", p, Config.GameName), (ClickType click)->{});
}else if(SchematicNode.getAllAccessibleSchematicsOfType(SteamwarUser.get(p.getUniqueId()).getId(), Config.SchematicType.toDB()).isEmpty() && !Config.test()){
inv.setItem(0, SWItem.getDye(8), (byte)8, msg.parse("SCHEM_NO_PRIVATE", p, Config.GameName), (ClickType click)->{});
}else{
inv.setItem(0, SWItem.getMaterial("CAULDRON_ITEM"), msg.parse("SCHEM_PRIVATE", p, Config.GameName), (ClickType click) -> {
p.closeInventory();
schemDialog(p, false);
});
int invSize = (Config.SubTypes.size() + 1) * 9;
SWInventory inv = new SWInventory(p, invSize, msg.parse("SCHEM_TITLE", p, Config.GameName));
setupSchemTypeRow(p, inv, Config.SchematicType, 0);
for (int i = 0; i < Config.SubTypes.size(); i++) {
setupSchemTypeRow(p, inv, Config.SubTypes.get(i), i + 1);
}
inv.setCallback(-999, (ClickType click) -> p.closeInventory());
inv.open();
}
private static void schemDialog(Player p, boolean publicSchems){
SchematicSelector selector = new SchematicSelector(p, Config.test()?SchematicSelector.selectSchematic():SchematicSelector.selectSchematicTypeWithRank(Config.SchematicType, Fight.getMaxRank()), node -> {
private static void setupSchemTypeRow(Player p, SWInventory inv, SchematicType type, int row) {
inv.setItem(row * 9 + 8, Material.REDSTONE, msg.parse("SCHEM_PUBLIC", p, type.name()), (ClickType click) -> {
p.closeInventory();
schemDialog(p, type, true, false);
});
if (Fight.publicOnly()) {
inv.setItem(row * 9, SWItem.getDye(8), (byte)8, msg.parse("SCHEM_PRIVATE_FORBIDDEN", p, type.name()), (ClickType click)->{});
return;
}
if (type.checkType() != null && type.checkType() != type && ArenaMode.AntiEvent.contains(Config.mode) && !SchematicNode.getAllAccessibleSchematicsOfType(SteamwarUser.get(p.getUniqueId()).getId(), type.checkType().toDB()).isEmpty()) {
inv.setItem(row * 9 + 4, Material.ANVIL, msg.parse("SCHEM_UNCHECKED", p, type.name()), (ClickType click) -> {
p.closeInventory();
schemDialog(p, type, false, true);
});
}
if (SchematicNode.getAllAccessibleSchematicsOfType(SteamwarUser.get(p.getUniqueId()).getId(), type.toDB()).isEmpty() && !Config.test()) {
inv.setItem(row * 9, SWItem.getDye(8), (byte)8, msg.parse("SCHEM_NO_PRIVATE", p, type.name()), (ClickType click)->{});
return;
}
inv.setItem(row * 9, SWItem.getMaterial("CAULDRON_ITEM"), msg.parse("SCHEM_PRIVATE", p, type.name()), (ClickType click) -> {
p.closeInventory();
schemDialog(p, type, false, false);
});
}
private static void schemDialog(Player p, SchematicType type, boolean publicSchems, boolean unchecked){
SchematicSelector selector = new SchematicSelector(p, Config.test() ? SchematicSelector.selectSchematic() : SchematicSelector.selectSchematicType(unchecked ? type.checkType() : type), node -> {
FightTeam fightTeam = Fight.getPlayerTeam(p);
if(fightTeam == null)
return;

Datei anzeigen

@ -47,10 +47,10 @@ public class GamemodeCommand extends BukkitCommand {
try {
CommandRemover.removeAll("gamemode");
CommandInjector.injectCommand(this);
} catch (Exception e) {
FightSystem.getPlugin().getLogger().log(Level.SEVERE, "Failed to replace commands", e);
}
Commands.injectCommand(this);
}
@Override

Datei anzeigen

@ -35,7 +35,7 @@ import org.bukkit.entity.Player;
public class LockschemCommand implements CommandExecutor {
public LockschemCommand() {
new StateDependentCommand(ArenaMode.AntiReplay, FightState.All, "lockschem", this);
new StateDependentCommand(ArenaMode.All, FightState.Schem, "lockschem", this);
}
@Override

Datei anzeigen

@ -0,0 +1,52 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2023 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.commands;
import de.steamwar.core.TPSWarpUtils;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentCommand;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
public class TPSWarpCommand implements CommandExecutor {
public TPSWarpCommand() {
new StateDependentCommand(ArenaMode.Prepare, FightState.PostSchemSetup, "tpswarp", this);
new StateDependentCommand(ArenaMode.Prepare, FightState.PostSchemSetup, "tpslimit", this);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
double tps;
try {
tps = Double.parseDouble(args[0]);
} catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
FightSystem.getMessage().send("TPSWARP_HELP", sender);
return false;
}
TPSWarpUtils.warp(tps);
FightSystem.getMessage().broadcastActionbar("TPSWARP_SET", tps);
return false;
}
}

Datei anzeigen

@ -83,8 +83,6 @@ public abstract class Countdown {
}
for(Countdown countdown : new ArrayList<>(currentCountdowns)) {
if(countdown.time - smallestTime <= 1)
countdown.prepareFinish();
countdown.time -= smallestTime;
countdown.show();
}
@ -104,8 +102,6 @@ public abstract class Countdown {
Bukkit.getOnlinePlayers().forEach(p -> sendCountdownMessage(p, message, time / divisor, appendix));
}
protected void prepareFinish() {}
public int getTimeLeft(){
return time;
}
@ -124,7 +120,6 @@ public abstract class Countdown {
broadcast("COUNTDOWN_SECONDS", 1);
break;
case 1:
prepareFinish();
broadcast("COUNTDOWN_SECOND", 1);
break;
case 0:

Datei anzeigen

@ -21,21 +21,23 @@ package de.steamwar.fightsystem.countdown;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.events.BoardingEvent;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightPlayer;
import de.steamwar.fightsystem.utils.Message;
import de.steamwar.fightsystem.utils.Region;
import de.steamwar.fightsystem.utils.SWSound;
import de.steamwar.techhider.ProtocolUtils;
import de.steamwar.fightsystem.winconditions.Wincondition;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.Bukkit;
import java.util.List;
public class EnternCountdown extends Countdown {
private static int calcTime(FightPlayer fp) {
private static int calcTime(FightPlayer fp, Countdown countdown) {
int time = Config.EnterStages.get(fp.getKit().getEnterStage());
Countdown countdown = Wincondition.getTimeOverCountdown();
if(countdown != null) {
time -= Config.TimeoutTime - countdown.getTimeLeft();
@ -49,21 +51,20 @@ public class EnternCountdown extends Countdown {
private final FightPlayer fightPlayer;
private List<ProtocolUtils.ChunkPos> chunkPos;
public EnternCountdown(FightPlayer fp) {
super(calcTime(fp), new Message("ENTERN_COUNTDOWN"), SWSound.BLOCK_NOTE_PLING, false);
public EnternCountdown(FightPlayer fp, Countdown countdown) {
super(calcTime(fp, countdown), new Message("ENTERN_COUNTDOWN"), SWSound.BLOCK_NOTE_PLING, false);
fightPlayer = fp;
enable();
}
@Override
public void countdownFinished() {
Bukkit.getPluginManager().callEvent(new BoardingEvent(fightPlayer));
FightSystem.getMessage().sendPrefixless("ENTERN_ALLOWED", fightPlayer.getEntity(), ChatMessageType.ACTION_BAR);
fightPlayer.ifPlayer(player -> FightSystem.getTechHider().reloadChunks(player, chunkPos, false));
}
@Override
protected void prepareFinish() {
chunkPos = FightSystem.getTechHider().prepareChunkReload(fightPlayer.getEntity(), false);
fightPlayer.ifPlayer(player -> {
FightSystem.getHullHider().updatePlayer(player);
FightSystem.getTechHider().reloadChunks(player, Fight.getOpposite(fightPlayer.getTeam()).getExtendRegion(), Region.EMPTY);
});
}
@Override

Datei anzeigen

@ -0,0 +1,49 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2023 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.event;
import com.sk89q.worldedit.WorldEditException;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.OneShotStateDependent;
import de.steamwar.fightsystem.utils.WorldeditWrapper;
import de.steamwar.fightsystem.winconditions.Winconditions;
import de.steamwar.sql.SchematicNode;
import java.util.logging.Level;
public class PersistentDamage {
public PersistentDamage() {
if(!ArenaMode.SeriousFight.contains(Config.mode))
return;
new OneShotStateDependent(Winconditions.PERSISTENT_DAMAGE, FightState.Spectate, () -> Fight.teams().forEach(team -> {
try{
WorldeditWrapper.impl.saveSchem(SchematicNode.getSchematicNode(team.getSchematic()), team.getExtendRegion(), team.getSchemRegion().getMinY());
}catch(WorldEditException e){
FightSystem.getPlugin().getLogger().log(Level.SEVERE, "Could not persist schematic state", e);
}
}));
}
}

Datei anzeigen

@ -17,42 +17,23 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.ai.chaos;
package de.steamwar.fightsystem.event;
import org.bukkit.util.Vector;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentTask;
import de.steamwar.fightsystem.winconditions.Winconditions;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
public class Cannon {
public final Vector[] tnt;
public final Vector button;
public final Vector load;
public final Vector escape;
public final String name;
public class TNTDistributor {
public Cannon(String name, Vector[] tnt, Vector button, Vector load, Vector escape) {
this.tnt = tnt;
this.button = button;
this.load = load;
this.escape = escape;
this.name = name;
}
public TNTDistributor() {
new StateDependentTask(Winconditions.TNT_DISTRIBUTION, FightState.Running, () -> Fight.teams().forEach(team -> team.getPlayers().forEach(fp -> {
if(!fp.isLiving())
return;
public Vector[] getTnt() {
return tnt;
}
public Vector getButton() {
return button;
}
public Vector getLoad() {
return load;
}
public Vector getEscape() {
return escape;
}
public String getName() {
return name;
fp.ifPlayer(player -> player.getInventory().addItem(new ItemStack(Material.TNT, 20)));
})), 300, 300);
}
}

Datei anzeigen

@ -0,0 +1,40 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.events;
import de.steamwar.fightsystem.fight.FightPlayer;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
@Getter
@AllArgsConstructor
public class BoardingEvent extends Event {
@Getter
private static final HandlerList handlerList = new HandlerList();
private final FightPlayer fightPlayer;
@Override
public HandlerList getHandlers() {
return handlerList;
}
}

Datei anzeigen

@ -0,0 +1,40 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.events;
import de.steamwar.fightsystem.fight.FightPlayer;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
@Getter
@AllArgsConstructor
public class TeamDeathEvent extends Event {
@Getter
private static final HandlerList handlerList = new HandlerList();
private final FightPlayer fightPlayer;
@Override
public HandlerList getHandlers() {
return handlerList;
}
}

Datei anzeigen

@ -0,0 +1,40 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.events;
import de.steamwar.fightsystem.fight.FightPlayer;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
@Getter
@AllArgsConstructor
public class TeamLeaveEvent extends Event {
@Getter
private static final HandlerList handlerList = new HandlerList();
private final FightPlayer fightPlayer;
@Override
public HandlerList getHandlers() {
return handlerList;
}
}

Datei anzeigen

@ -0,0 +1,40 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.events;
import de.steamwar.fightsystem.fight.FightPlayer;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
@Getter
@AllArgsConstructor
public class TeamSpawnEvent extends Event {
@Getter
private static final HandlerList handlerList = new HandlerList();
private final FightPlayer fightPlayer;
@Override
public HandlerList getHandlers() {
return handlerList;
}
}

Datei anzeigen

@ -21,11 +21,13 @@ package de.steamwar.fightsystem.fight;
import com.comphenix.tinyprotocol.TinyProtocol;
import com.mojang.authlib.GameProfile;
import de.steamwar.core.Core;
import de.steamwar.core.ProtocolWrapper;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.record.GlobalRecorder;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Sound;
@ -38,7 +40,9 @@ import java.util.HashSet;
public class Fight {
private Fight(){}
@Getter
private static final FightTeam redTeam = new FightTeam(Config.TeamRedName, Config.TeamRedColor, Config.TeamRedSpawn, Config.RedPasteRegion, Config.RedExtendRegion, Config.RedRotate, false, Config.RedLeader);
@Getter
private static final FightTeam blueTeam = new FightTeam(Config.TeamBlueName, Config.TeamBlueColor, Config.TeamBlueSpawn, Config.BluePasteRegion, Config.BlueExtendRegion, Config.BlueRotate, true, Config.BlueLeader);
private static final Collection<FightTeam> teams = new HashSet<>();
static {
@ -75,14 +79,6 @@ public class Fight {
return getPlayerTeam(player) != null;
}
public static FightTeam getRedTeam() {
return redTeam;
}
public static FightTeam getBlueTeam() {
return blueTeam;
}
public static Collection<FightTeam> teams() {
return teams;
}
@ -94,7 +90,10 @@ public class Fight {
public static void playSound(Sound sound, float volume, float pitch) {
GlobalRecorder.getInstance().soundAtPlayer(sound.name(), volume, pitch);
//volume: max. 100, pitch: max. 2
Bukkit.getServer().getOnlinePlayers().forEach(player -> player.playSound(player.getLocation(), sound, volume, pitch));
if(Core.getVersion() >= 18)
Bukkit.getServer().getOnlinePlayers().forEach(player -> player.playSound(player, sound, volume, pitch));
else
Bukkit.getServer().getOnlinePlayers().forEach(player -> player.playSound(player.getLocation(), sound, volume, pitch));
}
public static FightTeam getTeamByName(String name) {
@ -124,7 +123,7 @@ public class Fight {
if(!player.isOnline())
return;
pseudoSpectator(player, true);
}, 2);
}, 1);
}else if(gameMode == GameMode.SURVIVAL) {
for(Player currentPlayer : Bukkit.getServer().getOnlinePlayers()) {
if(currentPlayer.getUniqueId() != player.getUniqueId() && currentPlayer.getGameMode() == GameMode.SPECTATOR) {
@ -139,21 +138,16 @@ public class Fight {
TinyProtocol.instance.sendPacket(player, ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.GAMEMODE, new GameProfile(player.getUniqueId(), player.getName()), enable ? GameMode.CREATIVE : GameMode.SPECTATOR));
}
public static int getMaxRank(){
/* MaxRank of 0 is Pubonly*/
if(Config.OnlyPublicSchematics){
return 0;
public static boolean publicOnly() {
if (Config.OnlyPublicSchematics) {
return true;
}
if(Config.IgnorePublicOnly || ArenaMode.RankedEvent.contains(Config.mode)){
return 1000;
if (Config.IgnorePublicOnly || ArenaMode.RankedEvent.contains(Config.mode)) {
return false;
}
if(redTeam.getLeader() == null || blueTeam.getLeader() == null){
return 1000;
if (redTeam.getLeader() == null || blueTeam.getLeader() == null) {
return false;
}
return Math.min(redTeam.getSchemRank(), blueTeam.getSchemRank());
return redTeam.isPublicsOnly() || blueTeam.isPublicsOnly();
}
}

Datei anzeigen

@ -21,9 +21,13 @@ package de.steamwar.fightsystem.fight;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.ai.AI;
import de.steamwar.fightsystem.countdown.Countdown;
import de.steamwar.fightsystem.countdown.EnternCountdown;
import de.steamwar.fightsystem.events.TeamDeathEvent;
import de.steamwar.sql.PersonalKit;
import de.steamwar.sql.SteamwarUser;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@ -34,9 +38,13 @@ public class FightPlayer {
private final int id;
private LivingEntity entity;
@Getter
private final FightTeam team;
private boolean isOut;
@Setter
@Getter
private Kit kit;
@Getter
private int kills;
private EnternCountdown enternCountdown = null;
@ -61,13 +69,14 @@ public class FightPlayer {
public void setOut() {
isOut = true;
Bukkit.getPluginManager().callEvent(new TeamDeathEvent(this));
stopEnternCountdown();
ifAI(AI::stop);
}
public void startEnternCountdown() {
public void startEnternCountdown(Countdown countdown) {
if(Config.EnterStages.size() > kit.getEnterStage() && kit.getEnterStage() >= 0)
enternCountdown = new EnternCountdown(this);
enternCountdown = new EnternCountdown(this, countdown);
}
public void stopEnternCountdown(){
@ -110,22 +119,6 @@ public class FightPlayer {
return leader != null && leader.getEntity() == entity;
}
public Kit getKit() {
return kit;
}
public void setKit(Kit kit) {
this.kit = kit;
}
public FightTeam getTeam(){
return team;
}
public int getKills(){
return kills;
}
public void addKill(){
kills++;
}

Datei anzeigen

@ -33,6 +33,7 @@ import de.steamwar.fightsystem.utils.Region;
import de.steamwar.fightsystem.utils.WorldeditWrapper;
import de.steamwar.sql.SchematicData;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SchematicType;
import org.bukkit.Bukkit;
import org.bukkit.DyeColor;
import org.bukkit.Location;
@ -100,8 +101,17 @@ public class FightSchematic extends StateDependent {
if(clipboard == null){
List<SchematicNode> publics = SchematicNode.getAllSchematicsOfType(0, Config.SchematicType.toDB());
if(publics.isEmpty())
return;
if(publics.isEmpty()) {
for (SchematicType type : Config.SubTypes) {
publics = SchematicNode.getAllSchematicsOfType(0, type.toDB());
if (!publics.isEmpty()) {
break;
}
}
if (publics.isEmpty()) {
return;
}
}
setSchematic(publics.get(new Random().nextInt(publics.size())));
}
@ -138,6 +148,9 @@ public class FightSchematic extends StateDependent {
).add(new Vector(rotate ? 1 : 0, 0, rotate ? 1 : 0)),
new AffineTransform().rotateY(rotate ? 180 : 0)
);
FightSystem.getHullHider().initialize(team);
if(ArenaMode.Check.contains(Config.mode) && !team.isBlue())
replaceSync(Material.TNT, Material.OBSIDIAN);
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), freezer::disable, 3);
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), team::teleportToSpawn, 40);
@ -187,7 +200,7 @@ public class FightSchematic extends StateDependent {
}
length -= 1;
AffineTransform aT = new AffineTransform().rotateY(rotate ? 180 : 0);
AffineTransform aT = new AffineTransform().rotateY(((team == Fight.getRedTeam()) == (Config.BlueToRedZ > 0)) ? 180 : 0);
Location base = new Location(Config.world, region.centerX(), team.getExtendRegion().getMaxY(), region.centerZ());
for(int i = 0; i < characters.length; i++){
WorldeditWrapper.impl.pasteClipboard(characters[i], base, new Vector(offsets[i] - length/2, 0, -region.getSizeZ()/2), aT);

Datei anzeigen

@ -25,22 +25,24 @@ import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.commands.GUI;
import de.steamwar.fightsystem.countdown.Countdown;
import de.steamwar.fightsystem.events.TeamLeaveEvent;
import de.steamwar.fightsystem.events.TeamSpawnEvent;
import de.steamwar.fightsystem.listener.FightScoreboard;
import de.steamwar.fightsystem.listener.Permanent;
import de.steamwar.fightsystem.listener.PersonalKitCreator;
import de.steamwar.fightsystem.record.GlobalRecorder;
import de.steamwar.fightsystem.listener.TeamArea;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.OneShotStateDependent;
import de.steamwar.fightsystem.states.StateDependent;
import de.steamwar.fightsystem.utils.*;
import de.steamwar.fightsystem.winconditions.Wincondition;
import de.steamwar.fightsystem.winconditions.Winconditions;
import de.steamwar.inventory.SWItem;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.techhider.ProtocolUtils;
import lombok.Getter;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.*;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.NameTagVisibility;
@ -54,7 +56,7 @@ public class FightTeam {
private static void setKitButton(HotbarKit kit, boolean leader) {
if (Kit.getAvailableKits(leader).size() > 1 || Config.PersonalKits)
kit.setItem(1, "CHOOSE_KIT", new ItemBuilder(Material.LEATHER_CHESTPLATE).removeAllAttributes().addEnchantment(Enchantment.DURABILITY, 1).build(), player -> GUI.kitSelection(player, ""));
kit.setItem(1, "CHOOSE_KIT", new ItemBuilder(Material.LEATHER_CHESTPLATE).enchant().build(), player -> GUI.kitSelection(player, ""));
else
kit.setItem(1, null, null, null);
}
@ -62,50 +64,61 @@ public class FightTeam {
private static final HotbarKit memberKit = new HotbarKit();
static {
setKitButton(memberKit, false);
memberKit.setItem(7, "RESPAWN", new ItemBuilder(Material.BEACON).removeAllAttributes().build(), player -> player.teleport(Objects.requireNonNull(Fight.getPlayerTeam(player)).getSpawn()));
memberKit.setItem(7, "RESPAWN", new ItemBuilder(Material.BEACON).build(), player -> player.teleport(Objects.requireNonNull(Fight.getPlayerTeam(player)).getSpawn()));
}
private static final HotbarKit notReadyKit = new HotbarKit(memberKit);
static {
setKitButton(notReadyKit, true);
if(!ArenaMode.RankedEvent.contains(Config.mode)){
notReadyKit.setItem(2, "REQUESTS", new ItemBuilder(Material.PAPER).removeAllAttributes().build(), GUI::chooseJoinRequests);
notReadyKit.setItem(3, "REMOVE_PLAYERS", new ItemBuilder(SWItem.getMaterial("FIREWORK_CHARGE")).removeAllAttributes().build(), GUI::chooseRemove);
notReadyKit.setItem(2, "REQUESTS", new ItemBuilder(Material.PAPER).build(), GUI::chooseJoinRequests);
notReadyKit.setItem(3, "REMOVE_PLAYERS", new ItemBuilder(SWItem.getMaterial("FIREWORK_CHARGE")).build(), GUI::chooseRemove);
}
if(Config.test())
notReadyKit.setItem(5, "CHOOSE_SCHEMATIC", new ItemBuilder(SWItem.getMaterial("CAULDRON_ITEM")).removeAllAttributes().addEnchantment(Enchantment.DURABILITY, 1).build(), GUI::preSchemDialog);
notReadyKit.setItem(5, "CHOOSE_SCHEMATIC", new ItemBuilder(SWItem.getMaterial("CAULDRON_ITEM")).enchant().build(), GUI::preSchemDialog);
notReadyKit.setItem(4, "TEAM_NOT_READY", new ItemBuilder(SWItem.getDye(10), (short) 10).removeAllAttributes().addEnchantment(Enchantment.DURABILITY, 1).build(), player -> Objects.requireNonNull(Fight.getPlayerTeam(player)).setReady(true));
notReadyKit.setItem(4, "TEAM_NOT_READY", new ItemBuilder(SWItem.getDye(10), (short) 10).enchant().build(), player -> Objects.requireNonNull(Fight.getPlayerTeam(player)).setReady(true));
}
private static final HotbarKit chooseSchemKit = new HotbarKit(notReadyKit);
static {
chooseSchemKit.setItem(4, "CHOOSE_SCHEMATIC", new ItemBuilder(SWItem.getMaterial("CAULDRON_ITEM")).removeAllAttributes().addEnchantment(Enchantment.DURABILITY, 1).build(), GUI::preSchemDialog);
chooseSchemKit.setItem(4, "CHOOSE_SCHEMATIC", new ItemBuilder(SWItem.getMaterial("CAULDRON_ITEM")).enchant().build(), GUI::preSchemDialog);
}
private static final HotbarKit readyKit = new HotbarKit(memberKit);
static {
readyKit.setItem(1, null, null, null);
readyKit.setItem(4, "TEAM_READY", new ItemBuilder(SWItem.getDye(8), (short) 8).removeAllAttributes().addEnchantment(Enchantment.DURABILITY,1 ).build(), player -> Objects.requireNonNull(Fight.getPlayerTeam(player)).setReady(false));
readyKit.setItem(4, "TEAM_READY", new ItemBuilder(SWItem.getDye(8), (short) 8).enchant().build(), player -> Objects.requireNonNull(Fight.getPlayerTeam(player)).setReady(false));
}
@Getter
private UUID designatedLeader;
@Getter
private FightPlayer leader;
private int schemRank;
@Getter
private boolean publicsOnly;
private final Map<UUID, FightPlayer> players = new HashMap<>();
@Getter
private String name;
@Getter
private String prefix;
@Getter
private ChatColor color;
private final FightSchematic schematic;
private final Team team;
@Getter
private final boolean blue;
@Getter
private boolean ready;
private boolean skip;
@Getter
private final Location spawn;
@Getter
private final Region schemRegion;
@Getter
private final Region extendRegion;
@SuppressWarnings("deprecation")
@ -113,7 +126,7 @@ public class FightTeam {
this.spawn = spawn;
this.schemRegion = schemRegion;
this.extendRegion = extendRegion;
this.schemRank = 0;
this.publicsOnly = false;
this.ready = false;
this.skip = false;
this.blue = blue;
@ -122,6 +135,7 @@ public class FightTeam {
this.schematic = new FightSchematic(this, rotate);
new KitLoader();
new SpectateHandler();
new TeamArea(this);
team = FightScoreboard.getBukkitTeam(name);
WorldOfColorWrapper.impl.setTeamColor(team, color);
@ -145,26 +159,10 @@ public class FightTeam {
this.color = ChatColor.getByChar(ChatColor.getLastColors(prefix).replace("§", ""));
}
public UUID getDesignatedLeader(){
return designatedLeader;
}
public Region getSchemRegion() {
return schemRegion;
}
public Region getExtendRegion() {
return extendRegion;
}
public boolean canbeLeader(Player p){
return isLeaderless() && (designatedLeader == null || designatedLeader.equals(p.getUniqueId()));
}
public int getSchemRank() {
return schemRank;
}
public void teleportToSpawn(){
players.forEach((player, fp) -> fp.getEntity().teleport(spawn));
}
@ -202,13 +200,16 @@ public class FightTeam {
schematic.reset();
Set<UUID> playerSet = new HashSet<>(players.keySet());
for(UUID uuid : playerSet){
playerSet.removeIf(uuid -> {
Player player = Bukkit.getPlayer(uuid);
if(player == null)
if(player == null) {
removePlayer(players.get(uuid).getEntity());
}
return true;
}
return false;
});
FightPlayer leaderBackup = leader;
playerSet.removeIf(uuid -> Bukkit.getPlayer(uuid) == null);
players.clear();
leader = null;
@ -260,10 +261,11 @@ public class FightTeam {
}
public void addMember(LivingEntity entity, SteamwarUser user, boolean silent) {
final List<ProtocolUtils.ChunkPos> chunksToReload = FightSystem.getTechHider().prepareChunkReload(entity, false);
FightPlayer fightPlayer = getFightPlayer(entity) != null ? getFightPlayer(entity) : new FightPlayer(entity, user, this);
fightPlayer.revive();
players.put(entity.getUniqueId(), fightPlayer);
Bukkit.getPluginManager().callEvent(new TeamSpawnEvent(fightPlayer));
Permanent.getSpectatorTeam().removeEntry(entity.getName());
team.addEntry(entity.getName());
@ -274,6 +276,7 @@ public class FightTeam {
BountifulWrapper.impl.setAttackSpeed(player);
player.setFoodLevel(20);
player.getInventory().clear();
FightSystem.getHullHider().updatePlayer(player);
if(FightState.Spectate.contains(FightState.getFightState())) {
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
@ -284,10 +287,9 @@ public class FightTeam {
});
if(FightState.Running.contains(FightState.getFightState()))
fightPlayer.startEnternCountdown();
fightPlayer.startEnternCountdown(Wincondition.getTimeOverCountdown());
GlobalRecorder.getInstance().playerJoins(entity, user);
fightPlayer.ifPlayer(player -> FightSystem.getTechHider().reloadChunks(player, chunksToReload, false));
fightPlayer.ifPlayer(player -> FightSystem.getTechHider().reloadChunks(player, Config.ArenaRegion, fightPlayer.canEntern() ? Region.EMPTY : Fight.getOpposite(this).getExtendRegion()));
if(isLeaderless())
setLeader(fightPlayer, silent);
@ -297,9 +299,9 @@ public class FightTeam {
public void removePlayer(LivingEntity entity) {
FightPlayer fightPlayer = getFightPlayer(entity);
Bukkit.getPluginManager().callEvent(new TeamLeaveEvent(fightPlayer));
fightPlayer.ifPlayer(PersonalKitCreator::closeIfInKitCreator);
List<ProtocolUtils.ChunkPos> chunksToReload = FightSystem.getTechHider().prepareChunkReload(entity, true);
players.remove(entity.getUniqueId());
team.removeEntry(entity.getName());
Permanent.getSpectatorTeam().addEntry(entity.getName());
@ -309,7 +311,6 @@ public class FightTeam {
if(fightPlayer.equals(leader))
removeLeader();
GlobalRecorder.getInstance().entityDespawns(entity);
entity.teleport(Config.SpecSpawn);
fightPlayer.ifPlayer(player -> {
@ -317,7 +318,8 @@ public class FightTeam {
player.getInventory().clear();
if(player.isOnline()){
FightSystem.getTechHider().reloadChunks(player, chunksToReload, true);
FightSystem.getHullHider().updatePlayer(player);
FightSystem.getTechHider().reloadChunks(player, Config.ArenaRegion, Fight.getOpposite(this).getExtendRegion());
if(ArenaMode.VariableTeams.contains(Config.mode))
HotbarKit.SPECTATOR_KIT.loadToPlayer(player);
@ -329,14 +331,6 @@ public class FightTeam {
return leader == null;
}
public boolean isBlue(){
return blue;
}
public FightPlayer getLeader() {
return leader;
}
private void removeLeader() {
this.leader = null;
if(!players.isEmpty()) {
@ -357,11 +351,7 @@ public class FightTeam {
if(!silent)
FightUI.addSubtitle("UI_LEADER_JOINS", prefix, leader.getEntity().getName());
Optional<Integer> maxRank = SchematicNode.getAllAccessibleSchematicsOfType(leader.getUser().getId(), Config.SchematicType.toDB()).stream().map(SchematicNode::getRank).max(Integer::compare);
if(Config.RanksEnabled)
schemRank = maxRank.orElse(1);
else
schemRank = maxRank.isPresent() ? 1 : 0;
publicsOnly = SchematicNode.getAllAccessibleSchematicsOfType(leader.getUser().getId(), Config.SchematicType.toDB()).isEmpty();
if(!Config.PersonalKits)
leader.setKit(Kit.getKitByName(Config.LeaderDefault));
@ -384,15 +374,16 @@ public class FightTeam {
return players.values();
}
public boolean isReady() {
return ready;
}
public void pasteSchem() {
testPasteAction();
}
public void pasteSchem(SchematicNode schematic){
if(schematic.getSchemtype().check()) {
FightStatistics.unrank();
FightSystem.getMessage().broadcast("SCHEMATIC_UNCHECKED", getColoredName());
}
setSchem(schematic);
testPasteAction();
}
@ -453,26 +444,14 @@ public class FightTeam {
}
}
public String getName() {
return name;
}
public String getColoredName() {
return prefix + name;
}
public String getPrefix() {
return prefix;
}
public int getSchematic() {
return schematic.getId();
}
public Location getSpawn() {
return spawn;
}
public double getCurrentHearts() {
return players.values().stream().filter(FightPlayer::isLiving).mapToDouble(fp -> fp.getEntity().getHealth()).sum();
}
@ -490,10 +469,6 @@ public class FightTeam {
return (int) players.values().stream().filter(FightPlayer::isLiving).count();
}
public ChatColor getColor() {
return color;
}
@Override
public String toString() {
return name;

Datei anzeigen

@ -21,11 +21,13 @@ package de.steamwar.fightsystem.fight;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.listener.Recording;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependent;
import de.steamwar.fightsystem.utils.CraftbukkitWrapper;
import de.steamwar.fightsystem.utils.FlatteningWrapper;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.WorldCreator;
@ -39,11 +41,8 @@ import java.util.Objects;
public class FightWorld extends StateDependent {
private static final boolean paper = Bukkit.getVersion().contains("git-Paper");
public static boolean isPaper(){
return paper;
}
@Getter
private static final boolean PAPER = Bukkit.getVersion().contains("git-Paper");
public FightWorld() {
super(ArenaMode.Restartable.contains(Config.mode) || Config.replayserver(), FightState.Schem);
@ -57,7 +56,7 @@ public class FightWorld extends StateDependent {
@Override
public void disable() {
resetWorld();
Bukkit.getScheduler().runTask(FightSystem.getPlugin(), FightWorld::resetWorld); //Delay to prevent raceconditions with techhider and hullhider
}
public static void forceLoad(){

Datei anzeigen

@ -51,7 +51,7 @@ public class HotbarKit extends Kit {
public static final HotbarKit SPECTATOR_KIT = new HotbarKit();
static {
for(int i = 0; i < 9; i++)
SPECTATOR_KIT.setItem(i, "JOIN_REQUEST", new ItemBuilder(Material.PAPER).removeAllAttributes().build(), GUI::joinRequest);
SPECTATOR_KIT.setItem(i, "JOIN_REQUEST", new ItemBuilder(Material.PAPER).build(), GUI::joinRequest);
}
private static final int HOTBAR_SIZE = 9;

Datei anzeigen

@ -30,6 +30,7 @@ import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWItem;
import de.steamwar.sql.PersonalKit;
import de.steamwar.sql.SteamwarUser;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
@ -69,11 +70,19 @@ public class Kit {
}
}
@Getter
private final String name;
@Getter
private final ItemStack[] inventory;
@Getter
private final ItemStack[] armor;
@Getter
private final Collection<PotionEffect> effects;
/* In which stage is entern allowed? */
@Getter
private final int enterStage;
/* Is this kit allowed to set/handle tnt? */
@Getter
private final boolean tnt;
private final boolean leaderAllowed;
private final boolean memberAllowed;
@ -140,10 +149,6 @@ public class Kit {
return kits;
}
public String getName() {
return name;
}
public boolean canUseKit(boolean leader){
if (leader) {
return leaderAllowed;
@ -156,10 +161,6 @@ public class Kit {
return !memberAllowed;
}
public ItemStack[] getInventory() {
return inventory;
}
public boolean contains(ItemStack stack) {
for(ItemStack i : inventory) {
if(similar(i, stack))
@ -172,24 +173,6 @@ public class Kit {
return false;
}
public ItemStack[] getArmor() {
return armor;
}
public Collection<PotionEffect> getEffects() {
return effects;
}
/* Is this kit allowed to set/handle tnt? */
public boolean isTnt(){
return tnt;
}
/* In which stage is entern allowed? */
public int getEnterStage() {
return enterStage;
}
public void toPersonalKit(PersonalKit kit) {
kit.setContainer(inventory, armor);
}

Datei anzeigen

@ -21,52 +21,72 @@ package de.steamwar.fightsystem.listener;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.events.TeamDeathEvent;
import de.steamwar.fightsystem.events.TeamLeaveEvent;
import de.steamwar.fightsystem.events.TeamSpawnEvent;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightPlayer;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.fightsystem.states.StateDependentTask;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
public class ArenaBorder implements Listener {
private final Border spectatorBorder = new Border(Config.PlayerRegion, true, 5, "NO_ARENA_LEAVING", "ArenaBorder.spectatorBorder");
private final Border playerBorder = new Border(Config.PlayerRegion.to2d(), true, 5, "NO_ARENA_LEAVING", "ArenaBorder.playerBorder");
public ArenaBorder() {
new StateDependentListener(ArenaMode.All, FightState.All, this);
new StateDependentTask(ArenaMode.All, FightState.Running, this::damage, 2, 2);
new StateDependentListener(!Config.GroundWalkable, FightState.AntiRunning, new Listener() {
@EventHandler
public void onMove(PlayerMoveEvent e) {
Player player = e.getPlayer();
if(e.getTo().getY() <= Config.PlayerRegion.getMinY() && playerBorder.contains(player))
player.teleport(Fight.getPlayerTeam(player).getSpawn());
}
});
}
@EventHandler
public void arenaBorder(PlayerMoveEvent event){
Player player = event.getPlayer();
FightTeam team = Fight.getPlayerTeam(player);
public void onPlayerJoin(PlayerJoinEvent e) {
addToSpectator(e.getPlayer());
}
if(Config.ArenaLeaveable && team == null)
return;
@EventHandler
public void onTeamJoin(TeamSpawnEvent e) {
e.getFightPlayer().ifPlayer(player -> {
spectatorBorder.removePlayer(player);
playerBorder.addPlayer(player);
});
}
Location to = event.getTo();
assert to != null;
@EventHandler
public void onTeamDeath(TeamDeathEvent e) {
e.getFightPlayer().ifPlayer(player -> {
playerBorder.removePlayer(player);
addToSpectator(player);
});
}
if(Config.PlayerRegion.inRegion(to))
return;
@EventHandler
public void onTeamLeave(TeamLeaveEvent e) {
e.getFightPlayer().ifPlayer(player -> {
playerBorder.removePlayer(player);
addToSpectator(player);
});
}
if(to.getY() <= Config.PlayerRegion.getMinY() && player.getGameMode() != GameMode.SPECTATOR && team != null) {
if(!Config.GroundWalkable && !FightState.infight())
player.teleport(team.getSpawn());
return;
}
player.teleport(event.getFrom());
FightSystem.getMessage().sendPrefixless("NO_ARENA_LEAVING", player, ChatMessageType.ACTION_BAR);
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e) {
spectatorBorder.removePlayer(e.getPlayer());
}
private void damage() {
@ -78,4 +98,11 @@ public class ArenaBorder implements Listener {
}
});
}
private void addToSpectator(Player player) {
if(Config.ArenaLeaveable || !player.isOnline() || playerBorder.contains(player))
return;
spectatorBorder.addPlayer(player);
}
}

Datei anzeigen

@ -1,32 +0,0 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.listener;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.fightsystem.utils.BountifulWrapper;
public class ArrowPickup {
public ArrowPickup() {
new StateDependentListener(ArenaMode.All, FightState.All, BountifulWrapper.impl.newDenyArrowPickupListener());
}
}

Datei anzeigen

@ -85,7 +85,7 @@ public class ArrowStopper {
}
private boolean checkBlock(Block block) {
return Config.HiddenBlocks.contains(block.getType().name().toLowerCase());
return Config.HiddenBlocks.contains(block.getType());
}
private boolean invalidEntity(Projectile entity) {

Datei anzeigen

@ -0,0 +1,148 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.listener;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentTask;
import de.steamwar.fightsystem.utils.FlatteningWrapper;
import de.steamwar.fightsystem.utils.Region;
import net.md_5.bungee.api.ChatMessageType;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import java.util.*;
import java.util.logging.Level;
public class Border {
private final Map<UUID, Set<Block>> ghostBarriers = new HashMap<>();
private final Map<UUID, Location> lastLocation = new HashMap<>();
private final boolean contain;
private final String resetMessage;
private final String name;
private final Region region;
private final int ghostRange;
private final int ghostSize;
public Border(Region region, boolean contain, int ghostRange, String resetMessage, String name) {
this.contain = contain;
this.resetMessage = resetMessage;
this.name = name;
this.region = region;
this.ghostRange = ghostRange;
this.ghostSize = 2*ghostRange + 1;
new StateDependentTask(ArenaMode.All, FightState.All, this::run, 1, 1);
}
public void addPlayer(Player player) {
if(ghostBarriers.containsKey(player.getUniqueId()))
return;
ghostBarriers.put(player.getUniqueId(), new HashSet<>());
lastLocation.put(player.getUniqueId(), player.getLocation());
FightSystem.getPlugin().getLogger().log(Level.INFO, () -> player.getName() + " was added to border " + name);
}
public boolean contains(Player player) {
return ghostBarriers.containsKey(player.getUniqueId());
}
public void removePlayer(Player player) {
FightSystem.getPlugin().getLogger().log(Level.INFO, () -> player.getName() + " was removed from border " + name);
lastLocation.remove(player.getUniqueId());
Set<Block> blocks = ghostBarriers.remove(player.getUniqueId());
if(blocks == null || !player.isOnline())
return;
for(Block block : blocks)
sendChange(player, block, Material.AIR);
}
private void run() {
List<UUID> offline = new ArrayList<>();
for(Map.Entry<UUID, Set<Block>> entry : ghostBarriers.entrySet()) {
UUID uuid = entry.getKey();
Player player = Bukkit.getPlayer(uuid);
if(player == null) {
offline.add(uuid);
continue;
}
Location location = player.getLocation();
if(region.playerInRegion(location) != contain) {
player.teleport(lastLocation.get(uuid));
FightSystem.getMessage().sendPrefixless(resetMessage, player, ChatMessageType.ACTION_BAR);
return;
}
Set<Block> ghostBlocks = entry.getValue();
Region ghostRegion = Region.fromSize(location.getBlockX() - ghostRange, location.getBlockY() - ghostRange, location.getBlockZ() - ghostRange, ghostSize, ghostSize, ghostSize);
ghostBlocks.removeIf(block -> {
if(!ghostRegion.inRegion(block)) {
sendChange(player, block, Material.AIR);
return true;
}
return false;
});
if(contain) {
borderIteration(player, ghostBlocks, Region.fromSize(region.getMinX()-1, region.getMinY(), region.getMinZ(), 1, region.getSizeY(), region.getSizeZ()).intersection(ghostRegion));
borderIteration(player, ghostBlocks, Region.fromSize(region.getMinX(), region.getMinY()-1, region.getMinZ(), region.getSizeX(), 1, region.getSizeZ()).intersection(ghostRegion));
borderIteration(player, ghostBlocks, Region.fromSize(region.getMinX(), region.getMinY(), region.getMinZ()-1, region.getSizeX(), region.getSizeY(), 1).intersection(ghostRegion));
borderIteration(player, ghostBlocks, Region.fromSize(region.getMaxX(), region.getMinY(), region.getMinZ(), 1, region.getSizeY(), region.getSizeZ()).intersection(ghostRegion));
borderIteration(player, ghostBlocks, Region.fromSize(region.getMinX(), region.getMaxY(), region.getMinZ(), region.getSizeX(), 1, region.getSizeZ()).intersection(ghostRegion));
borderIteration(player, ghostBlocks, Region.fromSize(region.getMinX(), region.getMinY(), region.getMaxZ(), region.getSizeX(), region.getSizeY(), 1).intersection(ghostRegion));
} else {
borderIteration(player, ghostBlocks, Region.fromSize(region.getMinX(), region.getMinY(), region.getMinZ(), 1, region.getSizeY(), region.getSizeZ()).intersection(ghostRegion));
borderIteration(player, ghostBlocks, Region.fromSize(region.getMinX(), region.getMinY(), region.getMinZ(), region.getSizeX(), 1, region.getSizeZ()).intersection(ghostRegion));
borderIteration(player, ghostBlocks, Region.fromSize(region.getMinX(), region.getMinY(), region.getMinZ(), region.getSizeX(), region.getSizeY(), 1).intersection(ghostRegion));
borderIteration(player, ghostBlocks, Region.fromSize(region.getMaxX()-1, region.getMinY(), region.getMinZ(), 1, region.getSizeY(), region.getSizeZ()).intersection(ghostRegion));
borderIteration(player, ghostBlocks, Region.fromSize(region.getMinX(), region.getMaxY()-1, region.getMinZ(), region.getSizeX(), 1, region.getSizeZ()).intersection(ghostRegion));
borderIteration(player, ghostBlocks, Region.fromSize(region.getMinX(), region.getMinY(), region.getMaxZ()-1, region.getSizeX(), region.getSizeY(), 1).intersection(ghostRegion));
}
lastLocation.put(entry.getKey(), location);
}
offline.forEach(uuid -> FightSystem.getPlugin().getLogger().log(Level.INFO, () -> uuid + " was removed from border " + name));
offline.forEach(ghostBarriers::remove);
offline.forEach(lastLocation::remove);
}
private void borderIteration(Player player, Set<Block> ghostBlocks, Region border) {
border.forEach((x, y, z) -> {
Block block = Config.world.getBlockAt(x, y, z);
if(ghostBlocks.add(block))
sendChange(player, block, Material.BARRIER);
});
}
private void sendChange(Player player, Block block, Material type) {
if(block.getType() == Material.AIR)
FlatteningWrapper.impl.sendBlockChange(player, block, type);
}
}

Datei anzeigen

@ -40,6 +40,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockDispenseEvent;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
@ -153,14 +154,6 @@ public class Permanent implements Listener {
e.setCancelled(true);
}
@SuppressWarnings("deprecation")
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent e) {
Block block = e.getBlock();
for(ItemStack stack : block.getDrops(e.getPlayer().getItemInHand()))
Config.world.dropItemNaturally(block.getLocation(), stack);
}
@EventHandler
public void onDropPickup(PlayerPickupItemEvent e) {
if(!(Config.ArenaRegion.inRegion(e.getItem().getLocation())))
@ -226,4 +219,25 @@ public class Permanent implements Listener {
if(e.getItem().getType() == Material.TNT || FlatteningWrapper.impl.isFacingWater(block))
e.setCancelled(true);
}
@EventHandler
public void blockPlace(BlockPlaceEvent event) {
Player player = event.getPlayer();
Block block = event.getBlock();
if(Fight.teams().stream().anyMatch(team -> team.getExtendRegion().inRegion(block)))
return;
event.setCancelled(true);
FightSystem.getMessage().sendPrefixless("NO_BLOCK_PLACE", player, ChatMessageType.ACTION_BAR);
}
@EventHandler
public void blockBreak(BlockBreakEvent event) {
Block block = event.getBlock();
if(Config.BlueExtendRegion.getMinY() <= block.getY())
return;
event.setCancelled(true);
FightSystem.getMessage().sendPrefixless("NO_BLOCK_BREAK", event.getPlayer(), ChatMessageType.ACTION_BAR);
}
}

Datei anzeigen

@ -23,6 +23,9 @@ import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.events.TeamDeathEvent;
import de.steamwar.fightsystem.events.TeamLeaveEvent;
import de.steamwar.fightsystem.events.TeamSpawnEvent;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightPlayer;
import de.steamwar.fightsystem.fight.FightTeam;
@ -142,6 +145,11 @@ public class Recording implements Listener {
return packet;
}
@EventHandler
public void onPlayerSpawn(TeamSpawnEvent e) {
GlobalRecorder.getInstance().playerJoins(e.getFightPlayer().getEntity(), e.getFightPlayer().getUser());
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerMove(PlayerMoveEvent e){
if(isNotSent(e.getPlayer()))
@ -151,19 +159,13 @@ public class Recording implements Listener {
}
@EventHandler
public void onPlayerDeath(PlayerDeathEvent e) {
if(isNotSent(e.getEntity()))
return;
GlobalRecorder.getInstance().entityDespawns(e.getEntity());
public void onPlayerDeath(TeamDeathEvent e) {
GlobalRecorder.getInstance().entityDespawns(e.getFightPlayer().getEntity());
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e){
if(isNotSent(e.getPlayer()))
return;
GlobalRecorder.getInstance().entityDespawns(e.getPlayer());
public void onPlayerLeave(TeamLeaveEvent e) {
GlobalRecorder.getInstance().entityDespawns(e.getFightPlayer().getEntity());
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)

Datei anzeigen

@ -22,109 +22,122 @@ package de.steamwar.fightsystem.listener;
import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.events.BoardingEvent;
import de.steamwar.fightsystem.events.TeamDeathEvent;
import de.steamwar.fightsystem.events.TeamLeaveEvent;
import de.steamwar.fightsystem.events.TeamSpawnEvent;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightPlayer;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.OneShotStateDependent;
import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.fightsystem.utils.Region;
import net.md_5.bungee.api.ChatMessageType;
import de.steamwar.fightsystem.states.StateDependentTask;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
public class TeamArea implements Listener {
private static final Set<Player> realSpectator = new HashSet<>();
private final FightTeam team;
private final Border spectatorBorder;
private final Border bordingBorder;
private final Set<Player> realSpectator = new HashSet<>();
public TeamArea(FightTeam team) {
this.team = team;
this.spectatorBorder = new Border(team.getExtendRegion(), false, 5, "NO_TEAMAREA", team.getName() + ".spectatorBorder");
this.bordingBorder = new Border(team.getExtendRegion().to2d(), true, 1, "NO_ENTERN", team.getName() + ".boardingBorder");
public TeamArea() {
new StateDependentListener(ArenaMode.AntiTest, FightState.All, this);
new StateDependentTask(ArenaMode.AntiTest, FightState.TeamFix, this::realSpectatorCheck, 1, 1);
new OneShotStateDependent(ArenaMode.AntiTest, FightState.Spectate, () -> Fight.teams().forEach(t -> t.getPlayers().forEach(this::teamSpectator)));
}
@EventHandler
public void teamAreas(PlayerMoveEvent event) {
Player player = event.getPlayer();
if(Config.isReferee(player))
return;
public void playerJoin(PlayerJoinEvent e) {
Player player = e.getPlayer();
if(Fight.getPlayerTeam(player) != team && !Config.isReferee(player))
spectatorBorder.addPlayer(player);
}
FightTeam team = Fight.getPlayerTeam(player);
Fight.teams().forEach(t -> checkInTeamRegion(event, t, player, team));
@EventHandler
public void teamJoin(TeamSpawnEvent e) {
FightPlayer fightPlayer = e.getFightPlayer();
if(fightPlayer.getTeam() == team) {
fightPlayer.ifPlayer(player -> {
spectatorBorder.removePlayer(player);
bordingBorder.addPlayer(player);
});
}
}
@EventHandler
public void teamLeave(TeamLeaveEvent e) {
FightPlayer fightPlayer = e.getFightPlayer();
fightPlayer.ifPlayer(spectatorBorder::addPlayer);
if(fightPlayer.getTeam() == team)
fightPlayer.ifPlayer(bordingBorder::removePlayer);
}
@EventHandler
public void boarding(BoardingEvent e) {
FightPlayer fightPlayer = e.getFightPlayer();
if(fightPlayer.getTeam() == team) {
fightPlayer.ifPlayer(bordingBorder::removePlayer);
} else {
fightPlayer.ifPlayer(spectatorBorder::removePlayer);
}
}
@EventHandler
public void teamDeath(TeamDeathEvent e) {
teamSpectator(e.getFightPlayer());
}
private void teamSpectator(FightPlayer fightPlayer) {
if(fightPlayer.getTeam() == team) {
fightPlayer.ifPlayer(bordingBorder::removePlayer);
} else {
fightPlayer.ifPlayer(spectatorBorder::addPlayer);
}
}
@EventHandler
public void playerQuit(PlayerQuitEvent e) {
realSpectator.remove(e.getPlayer());
Player player = e.getPlayer();
spectatorBorder.removePlayer(player);
bordingBorder.removePlayer(player);
realSpectator.remove(player);
}
@EventHandler
public void blockPlace(BlockPlaceEvent event) {
Player player = event.getPlayer();
Block block = event.getBlock();
if(Config.BlueExtendRegion.inRegion(block) || Config.RedExtendRegion.inRegion(block))
return;
private void realSpectatorCheck() {
for(FightPlayer fightPlayer : team.getPlayers()) {
if(fightPlayer.isLiving())
continue;
event.setCancelled(true);
FightSystem.getMessage().sendPrefixless("NO_BLOCK_PLACE", player, ChatMessageType.ACTION_BAR);
}
fightPlayer.ifPlayer(player -> {
boolean inRegion = team.getExtendRegion().playerInRegion(player.getLocation());
if(inRegion && !realSpectator.contains(player)) {
realSpectator.add(player);
@EventHandler
public void blockBreak(BlockBreakEvent event) {
Block block = event.getBlock();
if(Config.BlueExtendRegion.getMinY() <= block.getY())
return;
event.setCancelled(true);
FightSystem.getMessage().sendPrefixless("NO_BLOCK_BREAK", event.getPlayer(), ChatMessageType.ACTION_BAR);
}
private void checkInTeamRegion(PlayerMoveEvent event, FightTeam team, Player player, FightTeam playerTeam) {
boolean spectator = player.getGameMode() == GameMode.SPECTATOR;
if(!spectator && playerTeam != null && playerTeam.canPlayerEntern(player))
return; // Player can entern
Region region = team.getExtendRegion();
boolean inRegion = region.in2dRegion(event.getTo());
if(team == playerTeam) {
if(spectator) {
realSpectator(inRegion, player);
} else if (!playerTeam.canPlayerEntern(player) && !inRegion) {
reset(event, "NO_ENTERN"); // Leaving prior to entern
}
return; // Always allowed in own region
//Later to prevent race condition with Fight.setSpecatator() during respawn
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
if(!player.isOnline())
return;
Fight.pseudoSpectator(player, false);
}, 2);
}else if(!inRegion && realSpectator.contains(player)) {
Fight.pseudoSpectator(player, true);
realSpectator.remove(player);
}
});
}
if(region.playerInRegion(event.getTo())) {
reset(event, "NO_TEAMAREA"); // Not allowed in region
if(team.getSchemRegion().playerInRegion(event.getTo()) && Config.PreperationArea >= 5){ // Preventing false positives due to small extension
player.kickPlayer(null);
Bukkit.getLogger().log(Level.INFO, player.getName() + " has entered a team area");
}
}
}
private void realSpectator(boolean inRegion, Player player) {
if(inRegion && !realSpectator.contains(player)) {
Fight.pseudoSpectator(player, false);
realSpectator.add(player);
}else if(!inRegion && realSpectator.contains(player)) {
Fight.pseudoSpectator(player, true);
realSpectator.remove(player);
}
}
private void reset(PlayerMoveEvent event, String message){
Player player = event.getPlayer();
player.teleport(event.getFrom());
FightSystem.getMessage().sendPrefixless(message, player, ChatMessageType.ACTION_BAR);
}
}

Datei anzeigen

@ -71,19 +71,27 @@ public class WaterRemover implements Listener {
event.setYield(0); //No drops (additionally to world config)
FightTeam spawn = tnt.remove(event.getEntity().getEntityId());
if(spawn != null && event.blockList().isEmpty() && Fight.getOpposite(spawn).getExtendRegion().inRegion(event.getLocation())) {
checkBlock(event.getLocation().getBlock());
if(spawn != null && !spawn.getExtendRegion().inRegion(event.getLocation())) {
Block b = event.getLocation().getBlock();
for(int y = -1; y <= 1; y++) {
for(int z = -1; z <= 1; z++) {
for(int x = -1; x <= 1; x++) {
checkBlock(b.getRelative(x, y, z));
}
}
}
}
for(Block b : event.blockList()){
//b cannot be water or air due to current explosion
event.blockList().forEach(this::checkNeighbours);
}
checkBlock(b.getRelative(BlockFace.UP));
checkBlock(b.getRelative(BlockFace.EAST));
checkBlock(b.getRelative(BlockFace.WEST));
checkBlock(b.getRelative(BlockFace.NORTH));
checkBlock(b.getRelative(BlockFace.SOUTH));
}
private void checkNeighbours(Block b) {
checkBlock(b.getRelative(BlockFace.UP));
checkBlock(b.getRelative(BlockFace.EAST));
checkBlock(b.getRelative(BlockFace.WEST));
checkBlock(b.getRelative(BlockFace.NORTH));
checkBlock(b.getRelative(BlockFace.SOUTH));
checkBlock(b.getRelative(BlockFace.DOWN));
}
private void checkBlock(Block b) {
@ -98,10 +106,6 @@ public class WaterRemover implements Listener {
if(b.getY() < MIN_Y)
return;
checkBlock(b.getRelative(BlockFace.UP));
checkBlock(b.getRelative(BlockFace.EAST));
checkBlock(b.getRelative(BlockFace.WEST));
checkBlock(b.getRelative(BlockFace.NORTH));
checkBlock(b.getRelative(BlockFace.SOUTH));
checkNeighbours(b);
}
}

Datei anzeigen

@ -22,19 +22,17 @@ package de.steamwar.fightsystem.record;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependent;
import lombok.Getter;
import java.io.*;
import java.util.zip.GZIPOutputStream;
public class FileRecorder extends StateDependent implements Recorder {
@Getter
private static final File file = new File(Config.world.getWorldFolder(), "recording.recording");
private DataOutputStream outputStream;
public static File getFile() {
return file;
}
public FileRecorder(){
super(Config.ReplayID == 0, FightState.Recording);
register();

Datei anzeigen

@ -41,7 +41,7 @@ public class LiveRecorder extends StateDependent implements Recorder {
@Override
public void enable() {
try {
socket = new Socket(Config.spectateIP, Config.spectatePort);
socket = new Socket(Config.spectateIP, Config.SpectatePort);
socket.setSoTimeout(1); // Wait a maximum of 1ms on a blocking operation (flush)
socket.setSoLinger(true, 1); // Wait a maximum of 1ms on disable
socket.setTcpNoDelay(true); // Don't wait on ack

Datei anzeigen

@ -33,7 +33,7 @@ public class LiveServer {
private final ServerSocket socket;
public LiveServer() throws IOException {
socket = new ServerSocket(Config.spectatePort);
socket = new ServerSocket(Config.SpectatePort);
Bukkit.getScheduler().runTaskAsynchronously(FightSystem.getPlugin(), this::acceptConnections);
}

Datei anzeigen

@ -88,8 +88,8 @@ public class PacketProcessor implements Listener {
private final PacketSource source;
private final BukkitTask task;
private final LinkedList<Runnable> syncList = new LinkedList<>();
private final Set<Integer> hiddenBlockIds = Config.HiddenBlocks.stream().map(String::toUpperCase).map(Material::getMaterial).flatMap(m -> BlockIds.impl.materialToAllIds(m).stream()).collect(Collectors.toSet());
private final int obfuscateWith = BlockIds.impl.materialToId(Material.getMaterial(Config.ObfuscateWith.toUpperCase()));
private final Set<Integer> hiddenBlockIds = Config.HiddenBlocks.stream().flatMap(m -> BlockIds.impl.materialToAllIds(m).stream()).collect(Collectors.toSet());
private final int obfuscateWith = BlockIds.impl.materialToId(Config.ObfuscateWith);
private final FreezeWorld freezer = new FreezeWorld();
private final REntityServer entityServer = new REntityServer();
private final Map<Integer, REntity> entities = new HashMap<>();
@ -165,6 +165,11 @@ public class PacketProcessor implements Listener {
entityServer.addPlayer(player);
}
private void addREntity(int entityId, REntity entity) {
entities.put(entityId, entity);
FightSystem.getHullHider().updateREntity(entity);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerJoin(PlayerJoinEvent e) {
entityServer.addPlayer(e.getPlayer());
@ -235,7 +240,7 @@ public class PacketProcessor implements Listener {
execSync(() -> {
SteamwarUser user = SteamwarUser.get(userId);
entities.put(entityId, new RPlayer(entityServer, user.getUUID(), user.getUserName(), Config.SpecSpawn));
addREntity(entityId, new RPlayer(entityServer, user.getUUID(), user.getUserName(), Config.SpecSpawn));
team.addEntry(user.getUserName());
});
}
@ -257,8 +262,10 @@ public class PacketProcessor implements Listener {
execSync(() -> {
REntity entity = entities.get(entityId);
if(entity != null)
if(entity != null) {
entity.move(locX, locY, locZ, pitch, yaw, headYaw);
FightSystem.getHullHider().updateREntity(entity);
}
});
}
@ -267,8 +274,10 @@ public class PacketProcessor implements Listener {
execSync(() -> {
REntity entity = entities.remove(entityId);
if(entity != null)
if(entity != null) {
FightSystem.getHullHider().despawnREntity(entity);
entity.die();
}
});
}
@ -289,7 +298,7 @@ public class PacketProcessor implements Listener {
private void tntSpawn() throws IOException {
int entityId = source.readInt();
execSync(() -> entities.put(entityId, new REntity(entityServer, EntityType.PRIMED_TNT, Config.SpecSpawn)));
execSync(() -> addREntity(entityId, new REntity(entityServer, EntityType.PRIMED_TNT, Config.SpecSpawn)));
}
private void entityVelocity() throws IOException {
@ -344,13 +353,13 @@ public class PacketProcessor implements Listener {
private void arrowSpawn() throws IOException {
int entityId = source.readInt();
execSync(() -> entities.put(entityId, new REntity(entityServer, EntityType.ARROW, Config.SpecSpawn)));
execSync(() -> addREntity(entityId, new REntity(entityServer, EntityType.ARROW, Config.SpecSpawn)));
}
private void fireballSpawn() throws IOException {
int entityId = source.readInt();
execSync(() -> entities.put(entityId, new REntity(entityServer, EntityType.FIREBALL, Config.SpecSpawn)));
execSync(() -> addREntity(entityId, new REntity(entityServer, EntityType.FIREBALL, Config.SpecSpawn)));
}
private void send(ChatMessageType type) throws IOException {
@ -437,7 +446,10 @@ public class PacketProcessor implements Listener {
if(!Config.ArenaRegion.in2dRegion(x, z))
return; //Outside of the arena
execSync(() -> BlockIdWrapper.impl.setBlock(Config.world, x, y, z, TechHiderWrapper.ENABLED && hiddenBlockIds.contains(blockState) ? obfuscateWith : blockState));
execSync(() -> {
BlockIdWrapper.impl.setBlock(Config.world, x, y, z, TechHiderWrapper.ENABLED && hiddenBlockIds.contains(blockState) ? obfuscateWith : blockState);
FightSystem.getHullHider().blockUpdate(Config.world.getBlockAt(x, y, z), BlockIdWrapper.impl.idToMaterial(blockState));
});
}
private void particle() throws IOException {
@ -578,6 +590,7 @@ public class PacketProcessor implements Listener {
private void endReplay() {
HandlerList.unregisterAll(this);
entityServer.close();
entities.values().forEach(FightSystem.getHullHider()::despawnREntity);
entities.clear();
freezer.disable();

Datei anzeigen

@ -19,6 +19,8 @@
package de.steamwar.fightsystem.states;
import lombok.Getter;
import java.util.*;
public enum FightState {
@ -48,12 +50,9 @@ public enum FightState {
public static final Set<FightState> AntiSpectate = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(SPECTATE)));
private static final Map<IStateDependent, Boolean> stateDependentFeatures = new HashMap<>();
@Getter
private static FightState fightState = PRE_LEADER_SETUP;
public static FightState getFightState() {
return fightState;
}
public static void registerStateDependent(IStateDependent stateDependent){
if(stateDependent.enabled().isEmpty())
return;

Datei anzeigen

@ -19,14 +19,28 @@
package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import de.steamwar.core.VersionDependent;
import de.steamwar.fightsystem.FightSystem;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
public interface BlockIdWrapper {
Class<?> worldServer = Reflection.getClass("{nms.server.level}.WorldServer");
Reflection.MethodInvoker getWorldHandle = Reflection.getTypedMethod(Reflection.getClass("{obc}.CraftWorld"), "getHandle", worldServer);
Class<?> craftPlayer = Reflection.getClass("{obc}.entity.CraftPlayer");
Class<?> entityPlayer = Reflection.getClass("{nms.server.level}.EntityPlayer");
Reflection.MethodInvoker getPlayer = Reflection.getTypedMethod(craftPlayer, "getHandle", entityPlayer);
BlockIdWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
Material idToMaterial(int blockState);
int blockToId(Block block);
void setBlock(World world, int x, int y, int z, int blockState);
void trackEntity(Player player, int entity);
void untrackEntity(Player player, int entity);
}

Datei anzeigen

@ -51,7 +51,7 @@ public class EnterHandler implements IStateDependent {
private void registerTeam(FightTeam team){
for(FightPlayer fp : team.getPlayers()){
fp.startEnternCountdown();
fp.startEnternCountdown(null);
}
}

Datei anzeigen

@ -35,6 +35,7 @@ import de.steamwar.network.packets.common.FightEndsPacket;
import de.steamwar.sql.Replay;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import lombok.Getter;
import org.bukkit.Bukkit;
import java.sql.Timestamp;
@ -46,6 +47,7 @@ import static de.steamwar.sql.Fight.create;
public class FightStatistics {
@Getter
private static boolean unranked = false;
public static void unrank() {
@ -53,10 +55,6 @@ public class FightStatistics {
FightUI.addSubtitle("UI_UNRANKED");
}
public static boolean isUnranked() {
return unranked;
}
private Timestamp starttime = Timestamp.from(Instant.now());
public FightStatistics() {
@ -98,12 +96,12 @@ public class FightStatistics {
Integer redSchem;
try {
blueSchem = SchematicNode.getSchematicNode(Fight.getBlueTeam().getSchematic()).getId();
} catch (SecurityException e) {
} catch (NullPointerException e) {
blueSchem = null;
}
try {
redSchem = SchematicNode.getSchematicNode(Fight.getRedTeam().getSchematic()).getId();
} catch (SecurityException e) {
} catch (NullPointerException e) {
redSchem = null;
}

Datei anzeigen

@ -31,6 +31,7 @@ import de.steamwar.fightsystem.states.OneShotStateDependent;
import de.steamwar.fightsystem.states.StateDependentCountdown;
import de.steamwar.fightsystem.states.StateDependentTask;
import de.steamwar.fightsystem.winconditions.Wincondition;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@ -43,10 +44,8 @@ import java.util.stream.Collectors;
public class FightUI {
@Getter
private static FightUI instance;
public static FightUI getInstance() {
return instance;
}
public FightUI() {
new StateDependentTask(ArenaMode.AntiReplay, FightState.All, this::update, 20, 20);

Datei anzeigen

@ -22,6 +22,7 @@ package de.steamwar.fightsystem.utils;
import de.steamwar.core.VersionDependent;
import de.steamwar.fightsystem.FightSystem;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
@ -49,4 +50,5 @@ public interface FlatteningWrapper {
boolean isFacingWater(Block dispenser);
boolean isCrouching(Player player);
void sendBlockChange(Player player, Block block, Material type);
}

Datei anzeigen

@ -0,0 +1,379 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2023 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.entity.REntity;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.FightTeam;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.logging.Level;
public class Hull {
private static boolean isOccluding(Material material) {
return material.isOccluding() || Config.HiddenBlocks.contains(material);
}
private final Region region;
private final boolean groundVisible;
private final BitSet occluding;
private final BitSet visibility;
private final Map<IntVector, Map<IntVector, BitSet>> blockVisibility = new HashMap<>();
private final Set<IntVector> uncoveredSurface = new HashSet<>();
private final HashSet<Player> players = new HashSet<>();
private final Set<Entity> entities = new HashSet<>();
private final Set<REntity> rentities = new HashSet<>();
public Hull(FightTeam team) {
this.region = team.getSchemRegion();
this.groundVisible = region.getMinY() != Config.PlayerRegion.getMinY();
this.occluding = new BitSet(region.volume());
this.visibility = new BitSet(region.volume());
IntVector[] directions;
if (groundVisible) {
directions = new IntVector[]{
new IntVector(1, 0, 0),
new IntVector(-1, 0, 0),
new IntVector(0, 1, 0),
new IntVector(0, -1, 0),
new IntVector(0, 0, 1),
new IntVector(0, 0, -1)
};
} else {
directions = new IntVector[]{
new IntVector(1, 0, 0),
new IntVector(-1, 0, 0),
new IntVector(0, -1, 0),
new IntVector(0, 0, 1),
new IntVector(0, 0, -1)
};
}
// Generate quadrants for each direction
for (IntVector direction : directions) {
Map<IntVector, BitSet> map = new HashMap<>();
for (int z = (direction.z == 0 ? -1 : 0); z <= 1; z += 2) {
for (int y = (direction.y == 0 ? -1 : 0); y <= 1; y += 2) {
for (int x = (direction.x == 0 ? -1 : 0); x <= 1; x += 2) {
map.put(new IntVector(x, y, z), new BitSet(region.volume()));
}
}
}
blockVisibility.put(direction, map);
}
}
public boolean blockPrecise(Player player, int chunkX, int chunkY, int chunkZ) {
return players.contains(player) && !region.chunkSectionOutside(chunkX, chunkY, chunkZ);
}
public boolean isBlockHidden(Player player, int x, int y, int z) {
return region.inRegion(x, y, z) && players.contains(player) && !visibility.get(((y - region.getMinY()) * region.getSizeZ() + (z - region.getMinZ())) * region.getSizeX() + (x - region.getMinX()));
}
public boolean isLocationHidden(Player player, Location location) {
return players.contains(player) && region.inRegion(location) && !visibility.get(new IntVector(location).toId(region));
}
public void addPlayer(Player player) {
if(players.add(player)) {
for(Entity entity : entities)
BlockIdWrapper.impl.untrackEntity(player, entity.getEntityId());
}
}
public void removePlayer(Player player, boolean activeRemoval) {
if(players.remove(player) && activeRemoval) {
for(Entity entity : entities)
BlockIdWrapper.impl.trackEntity(player, entity.getEntityId());
// techhider triggers block change sending
}
}
public void checkEntity(Entity entity) {
Location location = entity.getLocation();
if(region.inRegion(location) && !visibility.get(new IntVector(location).toId(region))) { //TODO more precise
if(entities.add(entity)) {
for(Player player : players)
BlockIdWrapper.impl.untrackEntity(player, entity.getEntityId());
}
} else {
if(entities.remove(entity)) {
for(Player player : players)
BlockIdWrapper.impl.trackEntity(player, entity.getEntityId());
}
}
}
public void removeEntity(Entity entity) {
entities.remove(entity);
}
public void checkREntity(REntity entity) {
Location location = new Location(Config.world, entity.getX(), entity.getY(), entity.getZ());
if(region.inRegion(location) && !visibility.get(new IntVector(location).toId(region))) { //TODO more precise
if(rentities.add(entity))
entity.hide(true);
} else {
if(rentities.remove(entity))
entity.hide(false);
}
}
public void removeREntity(REntity entity) {
rentities.remove(entity);
}
public void initialize() {
visibility.clear();
occluding.clear();
uncoveredSurface.clear();
for (Map<IntVector, BitSet> direction : blockVisibility.values()) {
for (BitSet set : direction.values())
set.clear();
}
long start = System.currentTimeMillis();
region.forEach((x, y, z) -> {
IntVector block = new IntVector(x, y, z);
if (isOccluding(Config.world.getBlockAt(x, y, z).getType()))
occluding.set(block.toId(region));
});
forEachBorder((root, direction) -> {
for (Map.Entry<IntVector, BitSet> quadrant : blockVisibility.get(direction).entrySet()) {
checkBlock(new NullList<>(), root, direction, quadrant.getKey(), quadrant.getValue());
}
});
FightSystem.getPlugin().getLogger().log(Level.INFO, () -> "[HullHider] initialisation finished: " + (System.currentTimeMillis() - start) + " ms, visible blocks: " + visibility.cardinality());
}
public void updateBlockVisibility(Block b, Material changedType) {
IntVector root = new IntVector(b.getX(), b.getY(), b.getZ());
if (root.notInRegion(region))
return;
int id = root.toId(region);
if (!occluding.get(id) || isOccluding(changedType))
return;
List<IntVector> uncovered = new ArrayList<>();
occluding.clear(id);
for (Map.Entry<IntVector, Map<IntVector, BitSet>> direction : blockVisibility.entrySet()) {
for (Map.Entry<IntVector, BitSet> quadrant : direction.getValue().entrySet()) {
if (quadrant.getValue().get(id)) {
quadrant.getValue().clear(id);
checkBlock(uncovered, root, direction.getKey(), quadrant.getKey(), quadrant.getValue());
}
}
}
if(uncovered.isEmpty())
return;
Set<IntVector> uncoveredSet = new HashSet<>(uncovered);
Iterator<Entity> it = entities.iterator();
while(it.hasNext()) {
Entity entity = it.next();
if(uncoveredSet.contains(new IntVector(entity.getLocation()))) { //TODO more precise
it.remove();
for(Player player : players)
BlockIdWrapper.impl.trackEntity(player, entity.getEntityId());
}
}
Iterator<REntity> rit = rentities.iterator();
while(rit.hasNext()) {
REntity entity = rit.next();
if(uncoveredSet.contains(new IntVector(new Location(Config.world, entity.getX(), entity.getY(), entity.getZ())))) { //TODO more precise
rit.remove();
entity.hide(false);
}
}
uncoveredSurface.addAll(uncoveredSet);
uncoveredSurface.remove(root);
}
public void sendUncoveredBlocks() {
Map<IntVector, List<IntVector>> sectionWise = new HashMap<>();
for(IntVector uncovered : uncoveredSurface) {
sectionWise.computeIfAbsent(new IntVector(uncovered.x >> 4, uncovered.y >> 4, uncovered.z >> 4), section -> new ArrayList<>()).add(uncovered);
}
uncoveredSurface.clear();
for (Map.Entry<IntVector, List<IntVector>> entry : sectionWise.entrySet()) {
Object packet = HullHiderWrapper.impl.generateBlockChangePacket(entry.getValue());
if(packet == null)
continue;
players.forEach(player -> TinyProtocol.instance.sendPacket(player, packet));
}
}
private void forEachBorder(BiConsumer<IntVector, IntVector> f) {
for (int x = region.getMinX(); x < region.getMaxX(); x++) {
for (int z = region.getMinZ(); z < region.getMaxZ(); z++) {
if (groundVisible)
f.accept(new IntVector(x, region.getMinY(), z), new IntVector(0, 1, 0));
f.accept(new IntVector(x, region.getMaxY() - 1, z), new IntVector(0, -1, 0));
}
}
for (int x = region.getMinX(); x < region.getMaxX(); x++) {
for (int y = region.getMinY(); y < region.getMaxY(); y++) {
f.accept(new IntVector(x, y, region.getMinZ()), new IntVector(0, 0, 1));
f.accept(new IntVector(x, y, region.getMaxZ() - 1), new IntVector(0, 0, -1));
}
}
for (int z = region.getMinZ(); z < region.getMaxZ(); z++) {
for (int y = region.getMinY(); y < region.getMaxY(); y++) {
f.accept(new IntVector(region.getMinX(), y, z), new IntVector(1, 0, 0));
f.accept(new IntVector(region.getMaxX() - 1, y, z), new IntVector(-1, 0, 0));
}
}
}
private void checkBlock(List<IntVector> uncovered, IntVector block, IntVector direction, IntVector quadrant, BitSet quadVisibility) {
if (block.notInRegion(region))
return;
int id = block.toId(region);
if (quadVisibility.get(id))
return;
quadVisibility.set(id);
if (!visibility.get(id)) {
visibility.set(id);
uncovered.add(block);
}
if (occluding.get(id))
return;
IntVector neighbour = block.add(direction);
checkBlock(uncovered, neighbour, direction, quadrant, quadVisibility);
boolean neigbourTransparent = boundedNonOccluding(neighbour);
boolean diagonalReachable = false;
if (direction.x == 0 && (neigbourTransparent || boundedNonOccluding(block.add(quadrant.x, 0, 0)))) {
checkBlock(uncovered, neighbour.add(quadrant.x, 0, 0), direction, quadrant, quadVisibility);
diagonalReachable = boundedNonOccluding(neighbour.add(quadrant.x, 0, 0));
}
if (direction.y == 0 && (neigbourTransparent || boundedNonOccluding(block.add(0, quadrant.y, 0)))) {
checkBlock(uncovered, neighbour.add(0, quadrant.y, 0), direction, quadrant, quadVisibility);
diagonalReachable = diagonalReachable || boundedNonOccluding(neighbour.add(0, quadrant.y, 0));
}
if (direction.z == 0 && (neigbourTransparent || boundedNonOccluding(block.add(0, 0, quadrant.z)))) {
checkBlock(uncovered, neighbour.add(0, 0, quadrant.z), direction, quadrant, quadVisibility);
diagonalReachable = diagonalReachable || boundedNonOccluding(neighbour.add(0, 0, quadrant.z));
}
if (diagonalReachable)
checkBlock(uncovered, neighbour.add(quadrant), direction, quadrant, quadVisibility);
}
private boolean boundedNonOccluding(IntVector block) {
return !(block.notInRegion(region) || occluding.get(block.toId(region)));
}
@Getter
@AllArgsConstructor
public static class IntVector {
private final int x;
private final int y;
private final int z;
public IntVector(Location location) {
this.x = location.getBlockX();
this.y = location.getBlockY();
this.z = location.getBlockZ();
}
public boolean notInRegion(Region region) {
return !region.inRegion(x, y, z);
}
public int toId(Region region) {
return ((y - region.getMinY()) * region.getSizeZ() + (z - region.getMinZ())) * region.getSizeX() + (x - region.getMinX());
}
public IntVector add(int x, int y, int z) {
return new IntVector(this.x + x, this.y + y, this.z + z);
}
public IntVector add(IntVector v) {
return add(v.x, v.y, v.z);
}
@Override
public int hashCode() {
return y << 24 ^ x << 12 ^ z;
}
@Override
public boolean equals(Object o) {
if(o == null || this.getClass() != o.getClass())
return false;
IntVector v = (IntVector) o;
return x == v.x && y == v.y && z == v.z;
}
@Override
public String toString() {
return x + "," + y + "," + z;
}
}
private static class NullList<E> extends AbstractList<E> {
@Override
public void add(int index, E element) {
// Straight to /dev/null!
}
@Override
public E get(int index) {
return null;
}
@Override
public int size() {
return 0;
}
}
}

Datei anzeigen

@ -0,0 +1,241 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2022 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.utils;
import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.core.Core;
import de.steamwar.entity.REntity;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightPlayer;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.listener.Recording;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependent;
import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.fightsystem.states.StateDependentTask;
import de.steamwar.techhider.TechHider;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntitySpawnEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
public class HullHider implements Listener {
private final Map<FightTeam, Hull> hullMap = new HashMap<>();
private final Hull[] hulls;
private final Map<Class<?>, BiFunction<Player, Object, Object>> packetHiders = new HashMap<>();
public HullHider() {
if(!TechHiderWrapper.ENABLED) {
hulls = new Hull[0];
return;
}
Fight.teams().forEach(team -> hullMap.put(team, new Hull(team)));
hulls = hullMap.values().toArray(new Hull[0]);
packetHiders.put(packetPlayOutWorldEvent, this::worldEventHider);
packetHiders.put(packetPlayOutExplosion, this::explosionHider);
posHiderGenerator("{nms.network.protocol.game}.PacketPlayOutWorldParticles", Core.getVersion() >= 18 ? double.class : float.class, 1.0);
posHiderGenerator("{nms.network.protocol.game}.PacketPlayOutNamedSoundEffect", int.class, 8.0);
if(Core.getVersion() >= 9 && Core.getVersion() < 18)
posHiderGenerator("{nms.network.protocol.game}.PacketPlayOutCustomSoundEffect", int.class, 8.0);
new StateDependentListener(TechHiderWrapper.ENABLED, FightState.Schem, this);
new StateDependent(TechHiderWrapper.ENABLED, FightState.Schem) {
@Override
public void enable() {
packetHiders.forEach(TinyProtocol.instance::addFilter);
Bukkit.getOnlinePlayers().forEach(HullHider.this::updatePlayer);
}
@Override
public void disable() {
Bukkit.getOnlinePlayers().forEach(player -> removePlayer(player, true));
packetHiders.forEach(TinyProtocol.instance::removeFilter);
}
}.register();
new StateDependentTask(TechHiderWrapper.ENABLED, FightState.Schem, this::onTick, 0, 1);
}
public void initialize(FightTeam team) {
if(!TechHiderWrapper.ENABLED)
return;
hullMap.get(team).initialize();
}
@EventHandler(priority = EventPriority.HIGH)
public void onJoin(PlayerJoinEvent e) {
updatePlayer(e.getPlayer());
}
@EventHandler
public void onLeave(PlayerQuitEvent e) {
removePlayer(e.getPlayer(), false);
}
public void updatePlayer(Player player) {
if(!TechHiderWrapper.ENABLED)
return;
FightTeam team = Fight.getPlayerTeam(player);
FightPlayer fp = Fight.getFightPlayer(player);
for(Map.Entry<FightTeam, Hull> hull : hullMap.entrySet()) {
if(Config.isReferee(player) || hull.getKey() == team || (fp != null && fp.canEntern())) {
hull.getValue().removePlayer(player, true);
} else {
hull.getValue().addPlayer(player);
}
}
}
private void removePlayer(Player player, boolean activeRemoval) {
for (Hull hull : hulls)
hull.removePlayer(player, activeRemoval);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockPhysic(BlockPhysicsEvent e) {
if(FlatteningWrapper.impl.doRecord(e))
blockUpdate(e.getBlock(), e.getChangedType());
}
public void blockUpdate(Block block, Material changedType) {
for (Hull hull : hulls)
hull.updateBlockVisibility(block, changedType);
}
public boolean isBlockHidden(Player player, int x, int y, int z) {
if(!TechHiderWrapper.ENABLED)
return false;
for (Hull hull : hulls)
if(hull.isBlockHidden(player, x, y, z))
return true;
return false;
}
public boolean blockPrecise(Player player, int chunkX, int chunkY, int chunkZ) {
if(!TechHiderWrapper.ENABLED)
return false;
for (Hull hull : hulls)
if(hull.blockPrecise(player, chunkX, chunkY, chunkZ))
return true;
return false;
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onSpawn(EntitySpawnEvent e) {
for (Hull hull : hulls)
hull.checkEntity(e.getEntity());
}
private void onTick() {
Recording.iterateOverEntities(Objects::nonNull, entity -> {
for (Hull hull : hulls)
hull.checkEntity(entity);
});
for (Hull hull : hulls)
hull.sendUncoveredBlocks();
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onDeath(EntityDeathEvent e) {
for(Hull hull : hulls)
hull.removeEntity(e.getEntity());
}
public void updateREntity(REntity e) {
for(Hull hull : hulls)
hull.checkREntity(e);
}
public void despawnREntity(REntity e) {
for(Hull hull : hulls)
hull.removeREntity(e);
}
private static final Class<?> packetPlayOutWorldEvent = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutWorldEvent");
private static final Reflection.FieldAccessor<?> worldEventPosition = Reflection.getField(packetPlayOutWorldEvent, TechHider.blockPosition, 0);
public static final Reflection.FieldAccessor<Integer> blockPositionY = Reflection.getField("{nms.core}.BaseBlockPosition", int.class, 1);
private Object worldEventHider(Player player, Object packet) {
Object baseBlock = worldEventPosition.get(packet);
return packetHider(player, packet, new Location(Config.world, TechHider.blockPositionX.get(baseBlock), blockPositionY.get(baseBlock), TechHider.blockPositionZ.get(baseBlock)));
}
private static final Class<?> packetPlayOutExplosion = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutExplosion");
private static final Reflection.FieldAccessor<List> explosionBlocks = Reflection.getField(packetPlayOutExplosion, List.class, 0);
private static final Function<Object, Location> explosionLocation = posPacketToLocation(packetPlayOutExplosion, double.class, 1.0);
private Object explosionHider(Player player, Object packet) {
if(explosionBlocks.get(packet).isEmpty())
return packetHider(player, packet, explosionLocation.apply(packet));
return packet;
}
private void posHiderGenerator(String typeName, Class<? extends Number> posType, double factor) {
Class<?> type = Reflection.getClass(typeName);
Function<Object, Location> location = posPacketToLocation(type, posType, factor);
packetHiders.put(type, (player, packet) -> packetHider(player, packet, location.apply(packet)));
}
private static Function<Object, Location> posPacketToLocation(Class<?> type, Class<? extends Number> posType, double factor) {
Reflection.FieldAccessor<? extends Number> x = Reflection.getField(type, posType, 0);
Reflection.FieldAccessor<? extends Number> y = Reflection.getField(type, posType, 1);
Reflection.FieldAccessor<? extends Number> z = Reflection.getField(type, posType, 2);
return packet -> new Location(Config.world, x.get(packet).doubleValue()/factor, y.get(packet).doubleValue()/factor, z.get(packet).doubleValue()/factor);
}
private Object packetHider(Player player, Object packet, Location location) {
for(Hull hull : hulls) {
if(hull.isLocationHidden(player, location))
return null;
}
return packet;
}
}

Datei anzeigen

@ -0,0 +1,31 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.utils;
import de.steamwar.core.VersionDependent;
import de.steamwar.fightsystem.FightSystem;
import java.util.List;
public interface HullHiderWrapper {
HullHiderWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
Object generateBlockChangePacket(List<Hull.IntVector> changes);
}

Datei anzeigen

@ -25,51 +25,26 @@ import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.List;
public class ItemBuilder {
private final ItemStack item;
private final ItemMeta meta;
public ItemBuilder(Material matrial) {
item = new ItemStack(matrial);
meta = item.getItemMeta();
}
public ItemBuilder(Material matrial, int amount) {
item = new ItemStack(matrial, amount);
public ItemBuilder(Material material) {
item = new ItemStack(material);
meta = item.getItemMeta();
meta.addItemFlags(ItemFlag.values());
}
@SuppressWarnings("deprecation")
public ItemBuilder(Material matrial, short subid) {
item = new ItemStack(matrial, 1, subid);
public ItemBuilder(Material material, short subid) {
item = new ItemStack(material, 1, subid);
meta = item.getItemMeta();
meta.addItemFlags(ItemFlag.values());
}
public ItemBuilder removeAllAttributes() {
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
meta.addItemFlags(ItemFlag.HIDE_DESTROYS);
meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE);
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
meta.addItemFlags(ItemFlag.HIDE_PLACED_ON);
meta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
return this;
}
public ItemBuilder setDisplayName(String name) {
meta.setDisplayName(name);
return this;
}
public ItemBuilder addLore(List<String> lore) {
meta.setLore(lore);
return this;
}
public ItemBuilder addEnchantment(Enchantment enchantment, int level) {
meta.addEnchant(enchantment, level, true);
public ItemBuilder enchant() {
meta.addEnchant(Enchantment.DURABILITY, 1, true);
return this;
}
@ -77,5 +52,4 @@ public class ItemBuilder {
item.setItemMeta(meta);
return item;
}
}

Datei anzeigen

@ -19,7 +19,11 @@
package de.steamwar.fightsystem.utils;
import lombok.Getter;
@Getter
public class Message {
private final String msg;
private final Object[] params;
@ -27,12 +31,4 @@ public class Message {
this.msg = msg;
this.params = params;
}
public String getMsg() {
return msg;
}
public Object[] getParams() {
return params;
}
}

Datei anzeigen

@ -20,13 +20,28 @@
package de.steamwar.fightsystem.utils;
import de.steamwar.techhider.ProtocolUtils;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bukkit.Location;
import org.bukkit.block.Block;
import java.util.function.ObjIntConsumer;
@Getter
@AllArgsConstructor
public class Region {
public static final Region EMPTY = Region.fromSize(-10000, -10000, -10000, 0, 0, 0);
public static Region withExtension(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ, int extendX, int extendY, int extendZ) {
return Region.fromSize(minX - extendX, minY - extendY, minZ - extendZ,
sizeX + extendX * 2, sizeY + extendY * 2, sizeZ + extendZ * 2);
}
public static Region fromSize(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ) {
return new Region(minX, minY, minZ, minX+sizeX, minY+sizeY, minZ+sizeZ);
}
private final int minX;
private final int minY;
private final int minZ;
@ -34,44 +49,6 @@ public class Region {
private final int maxY;
private final int maxZ;
public Region(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ, int extendX, int extendY, int extendZ) {
this(minX - extendX, minY - extendY, minZ - extendZ,
sizeX + extendX * 2, sizeY + extendY * 2, sizeZ + extendZ * 2);
}
public Region(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ) {
this.minX = minX;
this.minY = minY;
this.minZ = minZ;
this.maxX = minX + sizeX;
this.maxY = minY + sizeY;
this.maxZ = minZ + sizeZ;
}
public int getMinX() {
return minX;
}
public int getMinY() {
return minY;
}
public int getMinZ() {
return minZ;
}
public int getMaxX() {
return maxX;
}
public int getMaxY() {
return maxY;
}
public int getMaxZ() {
return maxZ;
}
public int getSizeX() {
return maxX - minX;
}
@ -105,6 +82,12 @@ public class Region {
getMinChunkZ() > cZ || cZ > getMaxChunkZ();
}
public boolean chunkSectionOutside(int cX, int cY, int cZ) {
return getMinChunkX() > cX || cX > getMaxChunkX() ||
ProtocolUtils.posToChunk(minY) > cY || cY > ProtocolUtils.posToChunk(maxY) ||
getMinChunkZ() > cZ || cZ > getMaxChunkZ();
}
public void forEachChunk(ObjIntConsumer<Integer> executor) {
for(int x = getMinChunkX(); x <= getMaxChunkX(); x++)
for(int z = getMinChunkZ(); z <= getMaxChunkZ(); z++)
@ -114,7 +97,7 @@ public class Region {
public void forEach(TriConsumer<Integer, Integer, Integer> executor) {
for(int x = minX; x < maxX; x++) {
for(int y = minY; y < maxY; y++) {
for (int z = minZ; z <= maxZ; z++) {
for (int z = minZ; z < maxZ; z++) {
executor.accept(x, y, z);
}
}
@ -142,7 +125,7 @@ public class Region {
}
public boolean playerInRegion(Location location){
return in2dRegion(location) && minY <= location.getY() && location.getY() + 1.8 < maxY;
return in2dRegion(location) && minY <= location.getY() && location.getY() < maxY;
}
public boolean in2dRegion(Block block){
@ -150,13 +133,29 @@ public class Region {
}
public boolean in2dRegion(int x, int z) {
return minX <= x && x < maxX && minZ <= z && z <= maxZ;
return minX <= x && x < maxX && minZ <= z && z < maxZ;
}
public boolean inRegion(Block block){
return in2dRegion(block) && minY <= block.getY() && block.getY() < maxY;
}
public boolean inRegion(int x, int y, int z) {
return in2dRegion(x, z) && minY <= y && y < maxY;
}
public Region intersection(Region other) {
int x = Math.max(minX, other.minX);
int y = Math.max(minY, other.minY);
int z = Math.max(minZ, other.minZ);
return new Region(x, y, z, Math.min(maxX, other.maxX), Math.min(maxY, other.maxY), Math.min(maxZ, other.maxZ));
}
public Region to2d() {
return new Region(minX, Integer.MIN_VALUE/2, minZ, maxX, Integer.MAX_VALUE/2, maxZ);
}
public interface TriConsumer<T, V, U>{
void accept(T x, V y, U z);
}

Datei anzeigen

@ -22,30 +22,34 @@ package de.steamwar.fightsystem.utils;
import de.steamwar.core.CraftbukkitWrapper;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.events.BoardingEvent;
import de.steamwar.fightsystem.events.TeamLeaveEvent;
import de.steamwar.fightsystem.events.TeamSpawnEvent;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependent;
import de.steamwar.techhider.ProtocolUtils;
import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.techhider.TechHider;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.concurrent.ConcurrentHashMap;
public class TechHiderWrapper extends StateDependent {
public class TechHiderWrapper extends StateDependent implements TechHider.LocationEvaluator, Listener {
public static final boolean ENABLED = !Config.OnlyPublicSchematics && !Config.test() && Config.TechhiderActive;
private final ConcurrentHashMap<Player, Region> hiddenRegion = new ConcurrentHashMap<>();
private final TechHider techHider;
public TechHiderWrapper() {
super(ENABLED, FightState.Schem);
techHider = new TechHider(this::bypass, Material.getMaterial(Config.ObfuscateWith), Config.HiddenBlocks.stream().map(String::toUpperCase).map(Material::getMaterial).collect(Collectors.toSet()), Config.HiddenBlockEntities);
techHider = new TechHider(this, Config.ObfuscateWith, Config.HiddenBlocks, Config.HiddenBlockEntities);
new StateDependentListener(ENABLED, FightState.Schem, this);
register();
}
@ -57,43 +61,82 @@ public class TechHiderWrapper extends StateDependent {
@Override
public void disable() {
techHider.disable();
hiddenRegion.clear();
}
public List<ProtocolUtils.ChunkPos> prepareChunkReload(LivingEntity p, boolean hide) {
if(!ENABLED || !(p instanceof Player))
return Collections.emptyList();
@EventHandler
public void teamJoin(TeamSpawnEvent e) {
e.getFightPlayer().ifPlayer(player -> hiddenRegion.put(player, getHiddenRegion(player)));
}
List<ProtocolUtils.ChunkPos> chunksToReload = new ArrayList<>();
Config.ArenaRegion.forEachChunk((x, z) -> {
if(bypass((Player) p, x, z) == hide)
chunksToReload.add(new ProtocolUtils.ChunkPos(x, z));
@EventHandler
public void boarding(BoardingEvent e) {
e.getFightPlayer().ifPlayer(player -> hiddenRegion.put(player, getHiddenRegion(player)));
}
@EventHandler
public void teamLeave(TeamLeaveEvent e) {
e.getFightPlayer().ifPlayer(player -> {
if(player.isOnline())
hiddenRegion.put(player, getHiddenRegion(player));
});
return chunksToReload;
}
public void reloadChunks(Player p, List<ProtocolUtils.ChunkPos> chunksToReload, boolean hide) {
if(!ENABLED || !FightState.Schem.contains(FightState.getFightState()))
@EventHandler
public void playerQuit(PlayerQuitEvent e) {
Player player = e.getPlayer();
hiddenRegion.remove(player);
}
public void reloadChunks(Player player, Region region, Region exclusion) {
if(!ENABLED || !FightState.Schem.contains(FightState.getFightState()) || !player.isOnline())
return;
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
for(ProtocolUtils.ChunkPos chunk : chunksToReload){
if(bypass(p, chunk.x(), chunk.z()) != hide)
CraftbukkitWrapper.impl.sendChunk(p, chunk.x(), chunk.z());
}
}, 40);
region.forEachChunk((chunkX, chunkZ) -> {
if(exclusion.chunkOutside(chunkX, chunkZ))
CraftbukkitWrapper.impl.sendChunk(player, chunkX, chunkZ);
});
}
private boolean bypass(Player p, int chunkX, int chunkZ){
if(Config.isReferee(p))
return true;
@Override
public boolean skipChunk(Player player, int chunkX, int chunkZ) {
return getHiddenRegion(player).chunkOutside(chunkX, chunkZ);
}
FightTeam ft = Fight.getPlayerTeam(p);
if(ft == null){
return Config.ArenaRegion.chunkOutside(chunkX, chunkZ);
}else if(ft.isBlue()){
return ft.canPlayerEntern(p) || Config.RedExtendRegion.chunkOutside(chunkX, chunkZ);
}else{
return ft.canPlayerEntern(p) || Config.BlueExtendRegion.chunkOutside(chunkX, chunkZ);
@Override
public boolean skipChunkSection(Player player, int chunkX, int chunkY, int chunkZ) {
return getHiddenRegion(player).chunkSectionOutside(chunkX, chunkY, chunkZ);
}
@Override
public TechHider.State check(Player player, int x, int y, int z) {
if(hiddenRegion.computeIfAbsent(player, this::getHiddenRegion).inRegion(x, y, z)) {
if(FightSystem.getHullHider().isBlockHidden(player, x, y, z)) {
return TechHider.State.HIDE;
} else {
return TechHider.State.CHECK;
}
} else {
return TechHider.State.SKIP;
}
}
@Override
public boolean blockPrecise(Player player, int chunkX, int chunkY, int chunkZ) {
return FightSystem.getHullHider().blockPrecise(player, chunkX, chunkY, chunkZ);
}
private Region getHiddenRegion(Player player) {
if(Config.isReferee(player))
return Region.EMPTY;
FightTeam team = Fight.getPlayerTeam(player);
if(team == null)
return Config.ArenaRegion;
if(team.canPlayerEntern(player))
return Region.EMPTY;
return Fight.getOpposite(team).getExtendRegion();
}
}

Datei anzeigen

@ -24,6 +24,7 @@ import de.steamwar.fightsystem.countdown.Countdown;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.StateDependentCountdown;
import lombok.Getter;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
@ -34,8 +35,10 @@ import java.util.stream.Collectors;
public abstract class Wincondition {
protected static PercentWincondition percentWincondition = null;
@Getter
protected static WinconditionPercent percentWincondition = null;
protected static StateDependentCountdown timeOverCountdown = null;
@Getter
protected static final List<PrintableWincondition> printableWinconditions = new ArrayList<>();
private final String windescription;
@ -61,14 +64,6 @@ public abstract class Wincondition {
return Fight.getPlayerTeam((LivingEntity) player);
}
public static List<PrintableWincondition> getPrintableWinconditions(){
return printableWinconditions;
}
public static PercentWincondition getPercentWincondition() {
return percentWincondition;
}
protected void comparisonWin(ToDoubleFunction<FightTeam> evaluate, String winMessage, String tieMessage) {
double max = Fight.teams().stream().mapToDouble(evaluate).max().orElseThrow(() -> new SecurityException("No teams present"));
List<FightTeam> teams = Fight.teams().stream().filter(team -> evaluate.applyAsDouble(team) == max).collect(Collectors.toList());

Datei anzeigen

@ -19,16 +19,13 @@
package de.steamwar.fightsystem.winconditions;
import de.steamwar.fightsystem.events.TeamDeathEvent;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightPlayer;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentListener;
import org.bukkit.entity.Entity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.PlayerQuitEvent;
public class WinconditionAllDead extends Wincondition implements Listener {
@ -38,25 +35,12 @@ public class WinconditionAllDead extends Wincondition implements Listener {
}
@EventHandler
public void handlePlayerDeath(EntityDeathEvent event) {
handleDeath(event.getEntity());
}
public void handlePlayerDeath(TeamDeathEvent event) {
FightTeam team = event.getFightPlayer().getTeam();
@EventHandler
public void handlePlayerQuit(PlayerQuitEvent event) {
handleDeath(event.getPlayer());
}
private void handleDeath(Entity player){
FightTeam team = isTarget(player);
if(team == null)
if(team.getAlivePlayers() > 0)
return;
for(FightPlayer fp : team.getPlayers()) {
if(fp.isLiving() && fp.getEntity() != player)
return;
}
win(Fight.getOpposite(team), "WIN_ALL_DEAD", team.getPrefix());
}
}

Datei anzeigen

@ -1,27 +0,0 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.winconditions;
public class WinconditionBlacklistPercent extends PercentWincondition {
public WinconditionBlacklistPercent(){
super("RelativePercent", Winconditions.RELATIVE_PERCENT);
}
}

Datei anzeigen

@ -19,16 +19,14 @@
package de.steamwar.fightsystem.winconditions;
import de.steamwar.fightsystem.events.TeamDeathEvent;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightPlayer;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependentListener;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.PlayerQuitEvent;
public class WinconditionCaptainDead extends Wincondition implements Listener {
@ -38,22 +36,12 @@ public class WinconditionCaptainDead extends Wincondition implements Listener {
}
@EventHandler
public void handlePlayerDeath(EntityDeathEvent event) {
handleDeath(event.getEntity());
}
@EventHandler
public void handlePlayerQuit(PlayerQuitEvent event) {
handleDeath(event.getPlayer());
}
private void handleDeath(Entity player){
FightTeam team = isTarget(player);
if(team == null)
public void handlePlayerDeath(TeamDeathEvent event) {
FightPlayer leader = event.getFightPlayer();
if(!leader.isLeader())
return;
if(team.isPlayerLeader((LivingEntity) player)) {
win(Fight.getOpposite(team), "WIN_LEADER_DEAD", team.getPrefix() + team.getLeader().getEntity().getName());
}
FightTeam team = leader.getTeam();
win(Fight.getOpposite(team), "WIN_LEADER_DEAD", team.getPrefix() + leader.getEntity().getName());
}
}

Datei anzeigen

@ -26,7 +26,6 @@ import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.OneShotStateDependent;
import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.fightsystem.utils.Message;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@ -34,27 +33,12 @@ import org.bukkit.event.entity.EntityExplodeEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.ToIntFunction;
public class PercentWincondition extends Wincondition implements PrintableWincondition {
public class WinconditionPercent extends Wincondition implements PrintableWincondition {
private final Map<FightTeam, TeamPercent> teamMap = new HashMap<>();
protected BooleanSupplier explosionFilter = () -> !Config.EnterStages.isEmpty() && Config.EnterStages.get(0) >= Wincondition.getTimeOverCountdown().getTimeLeft();
protected Predicate<Material> testBlock = type -> !Config.PercentBlocks.contains(type);
protected ToIntFunction<FightTeam> totalBlockCalc = team -> {
AtomicInteger blocks = new AtomicInteger();
team.getSchemRegion().forEach((x, y, z) -> {
if (testBlock.test(Config.world.getBlockAt(x, y, z).getType())) {
blocks.getAndIncrement();
}
});
return blocks.get();
};
protected Consumer<FightTeam> checkWin = team -> {
if (getPercent(team) >= Config.PercentWin) {
win(Fight.getOpposite(team), "WIN_PERCENT", team.getColoredName());
@ -62,7 +46,7 @@ public class PercentWincondition extends Wincondition implements PrintableWincon
};
protected Consumer<FightTeam> postEnable = team -> {};
public PercentWincondition(String windescription, Winconditions wincondition) {
public WinconditionPercent(Winconditions wincondition, String windescription) {
super(windescription);
if (Config.ActiveWinconditions.contains(wincondition)) {
@ -74,7 +58,7 @@ public class PercentWincondition extends Wincondition implements PrintableWincon
}
public Message getDisplay(FightTeam team) {
return new Message("BAR_PERCENT", team.getPrefix() + (Math.round(100.0 * getPercent(team)) / 100.0));
return new Message("BAR_PERCENT", team.getPrefix() + (Math.round(10000.0 * (1.0 - getPercent(team) / Config.PercentWin)) / 100.0));
}
public double getPercent(FightTeam team) {
@ -105,12 +89,16 @@ public class PercentWincondition extends Wincondition implements PrintableWincon
@EventHandler
public void onEntityExplode(EntityExplodeEvent event) {
if (event.getEntityType() == EntityType.FIREBALL || explosionFilter.getAsBoolean() || !team.getExtendRegion().inRegion(event.getEntity().getLocation())) {
if (
event.getEntityType() == EntityType.FIREBALL ||
!team.getExtendRegion().inRegion(event.getEntity().getLocation()) ||
(!Config.PercentEntern && !Config.EnterStages.isEmpty() && Config.EnterStages.get(0) >= Wincondition.getTimeOverCountdown().getTimeLeft())
) {
return;
}
event.blockList().forEach(block -> {
if (testBlock.test(block.getType())) {
if (Config.PercentBlocks.contains(block.getType()) == Config.PercentBlocksWhitelist) {
currentBlocks--;
}
});
@ -119,7 +107,11 @@ public class PercentWincondition extends Wincondition implements PrintableWincon
}
private void enable() {
totalBlocks = totalBlockCalc.applyAsInt(team);
totalBlocks = 0;
team.getSchemRegion().forEach((x, y, z) -> {
if (Config.PercentBlocks.contains(Config.world.getBlockAt(x, y, z).getType()) == Config.PercentBlocksWhitelist)
totalBlocks++;
});
currentBlocks = totalBlocks;
postEnable.accept(team);
}

Datei anzeigen

@ -1,30 +0,0 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.winconditions;
public class WinconditionPercentSystem extends PercentWincondition {
public WinconditionPercentSystem() {
super("Percent", Winconditions.PERCENT_SYSTEM);
totalBlockCalc = team -> team.getSchemRegion().volume();
explosionFilter = () -> false;
}
}

Datei anzeigen

@ -36,12 +36,12 @@ import org.bukkit.event.player.PlayerQuitEvent;
import java.util.HashMap;
import java.util.Map;
public class WinconditionPoints extends PercentWincondition implements Listener {
public class WinconditionPoints extends WinconditionPercent implements Listener {
private final Map<FightTeam, TeamPoints> teamMap = new HashMap<>();
public WinconditionPoints(){
super("Points", Winconditions.POINTS);
super(Winconditions.POINTS, "Points");
checkWin = team -> {};
postEnable = this::pointInit;

Datei anzeigen

@ -35,7 +35,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
public class WinconditionPointsAirShip extends PercentWincondition implements Listener {
public class WinconditionPointsAirShip extends WinconditionPercent implements Listener {
private double[] as = new double[] {
0.5,
@ -56,7 +56,7 @@ public class WinconditionPointsAirShip extends PercentWincondition implements Li
private final Map<FightTeam, TeamPoints> teamMap = new HashMap<>();
public WinconditionPointsAirShip(){
super("Points", Winconditions.POINTS_AIRSHIP);
super(Winconditions.POINTS_AIRSHIP, "Points");
checkWin = team -> {
if (teamMap.get(team).getPoints() > TeamPoints.WIN_POINTS) {

Datei anzeigen

@ -1,31 +0,0 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2021 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.winconditions;
import de.steamwar.fightsystem.Config;
public class WinconditionWhitelistPercent extends PercentWincondition {
public WinconditionWhitelistPercent() {
super("WhitelistPercent", Winconditions.WHITELIST_PERCENT);
testBlock = Config.PercentBlocks::contains;
}
}

Datei anzeigen

@ -28,8 +28,6 @@ public enum Winconditions {
CAPTAIN_DEAD,
PERCENT_SYSTEM,
WHITELIST_PERCENT,
RELATIVE_PERCENT,
POINTS,
POINTS_AIRSHIP,
@ -39,5 +37,7 @@ public enum Winconditions {
HELLS_BELLS,
METEOR,
AMONG_US
AMONG_US,
PERSISTENT_DAMAGE,
TNT_DISTRIBUTION
}

Datei anzeigen

@ -26,4 +26,6 @@ commands:
win:
resetwg:
resettb:
tpslimit:
tpswarp:
unrank:

Datei anzeigen

@ -46,11 +46,6 @@ mainClassName = ''
allprojects {
repositories {
mavenCentral()
jcenter()
maven {
url = uri("https://repo.codemc.io/repository/maven-snapshots/")
}
maven {
url = uri('https://hub.spigotmc.org/nexus/content/repositories/snapshots/')

0
gradlew vendored Normale Datei → Ausführbare Datei
Datei anzeigen