Pārlūkot izejas kodu

Merge pull request #19 from RedstoneFuture/reworkRandomizer

Reworking PlayerEquipmentRandomizer
Daniel 2 gadi atpakaļ
vecāks
revīzija
88bc039aaf

+ 10 - 6
missilewars-plugin/src/main/java/de/butzlabben/missilewars/game/Game.java

@@ -41,6 +41,8 @@ import de.butzlabben.missilewars.wrapper.abstracts.Lobby;
 import de.butzlabben.missilewars.wrapper.abstracts.MapChooseProcedure;
 import de.butzlabben.missilewars.wrapper.event.GameStartEvent;
 import de.butzlabben.missilewars.wrapper.event.PlayerArenaJoinEvent;
+import de.butzlabben.missilewars.wrapper.game.MissileGameEquipment;
+import de.butzlabben.missilewars.wrapper.game.SpecialGameEquipment;
 import de.butzlabben.missilewars.wrapper.game.Team;
 import de.butzlabben.missilewars.wrapper.player.MWPlayer;
 import de.butzlabben.missilewars.wrapper.stats.FightStats;
@@ -90,10 +92,13 @@ public class Game {
     private GameBoundListener listener;
     private ItemStack customBow;
     private ItemStack customPickaxe;
+    private MissileGameEquipment missileEquipment;
+    private SpecialGameEquipment specialEquipment;
 
     public Game(Lobby lobby) {
-        Logger.BOOT.log("Loading game " + lobby.getDisplayName());
+        Logger.BOOT.log("Loading lobby " + lobby.getName());
         this.lobby = lobby;
+
         if (lobby.getBukkitWorld() == null) {
             Logger.ERROR.log("Lobby world in arena \"" + lobby.getName() + "\" must not be null");
             return;
@@ -172,6 +177,9 @@ public class Game {
         scoreboardManager = new ScoreboardManager(this);
         scoreboardManager.createScoreboard();
 
+        missileEquipment = new MissileGameEquipment(this);
+        specialEquipment = new SpecialGameEquipment(this);
+
         Logger.DEBUG.log("Making game ready");
         ++fights;
         if (fights >= Config.getFightRestart())
@@ -215,10 +223,6 @@ public class Game {
 
         applyForAllPlayers(this::startForPlayer);
 
-        // Set intervals
-        team1.updateIntervals(arena.getInterval(team1.getMembers().size()));
-        team2.updateIntervals(arena.getInterval(team2.getMembers().size()));
-
         // Change MOTD
         if (!Config.isMultipleLobbies())
             MotdManager.getInstance().updateMOTD(this);
@@ -386,7 +390,7 @@ public class Game {
         setPlayerAttributes(player);
 
         playerTasks.put(player.getUniqueId(),
-                Bukkit.getScheduler().runTaskTimer(MissileWars.getInstance(), mwPlayer, 0, 20));
+                Bukkit.getScheduler().runTaskTimer(MissileWars.getInstance(), mwPlayer, 40, 20));
 
     }
 

+ 0 - 3
missilewars-plugin/src/main/java/de/butzlabben/missilewars/listener/GameListener.java

@@ -204,7 +204,6 @@ public class GameListener extends GameBoundListener {
             to.addMember(mwPlayer);
 
             p.sendMessage(MessageConfig.getMessage("team_assigned").replace("%team%", to.getFullname()));
-            to.updateIntervals(game.getArena().getInterval(to.getMembers().size()));
             game.startForPlayer(p);
         }
     }
@@ -333,8 +332,6 @@ public class GameListener extends GameBoundListener {
                     getGame().stopGame();
                 });
                 getGame().broadcast(MessageConfig.getMessage("team_offline").replace("%team%", team.getFullname()));
-            } else {
-                team.updateIntervals(game.getArena().getInterval(team.getMembers().size()));
             }
         }
     }

+ 0 - 151
missilewars-plugin/src/main/java/de/butzlabben/missilewars/util/GameRandomizer.java

@@ -1,151 +0,0 @@
-/*
- * This file is part of MissileWars (https://github.com/Butzlabben/missilewars).
- * Copyright (c) 2018-2021 Daniel Nägele.
- *
- * MissileWars is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * MissileWars 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MissileWars.  If not, see <https://www.gnu.org/licenses/>.
- */
-
-package de.butzlabben.missilewars.util;
-
-import de.butzlabben.missilewars.Logger;
-import de.butzlabben.missilewars.game.Game;
-import de.butzlabben.missilewars.util.version.VersionUtil;
-import de.butzlabben.missilewars.wrapper.abstracts.arena.MissileConfiguration;
-import de.butzlabben.missilewars.wrapper.missile.Missile;
-import de.butzlabben.missilewars.wrapper.player.Interval;
-import org.bukkit.Material;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.ItemMeta;
-
-import java.util.HashMap;
-import java.util.Random;
-
-/**
- * @author Butzlabben
- * @since 19.01.2018
- */
-public class GameRandomizer {
-
-    private final MissileConfiguration missileConfiguration;
-    private final Game game;
-    private final HashMap<Interval, String> defensive = new HashMap<>();
-    private final HashMap<Interval, String> missiles = new HashMap<>();
-
-    private int totalOccurrenceMissiles = 0;
-    private int totalOccurrenceDefensive = 0;
-    private int randomizeCounter = 1;
-
-    private ItemStack shield;
-    private ItemStack arrow;
-    private ItemStack fireball;
-
-
-    public GameRandomizer(Game game) {
-        this.game = game;
-        missileConfiguration = game.getArena().getMissileConfiguration();
-
-        createDefenseItems();
-
-        // get missiles
-        for (Missile missile : missileConfiguration.getMissiles()) {
-
-            Interval interval = new Interval(totalOccurrenceMissiles, totalOccurrenceMissiles + missile.occurrence() - 1);
-            missiles.put(interval, missile.getName());
-            totalOccurrenceMissiles += missile.occurrence();
-        }
-
-        // get shield
-        int shieldOccurrence = game.getArena().getShieldConfiguration().getOccurrence();
-        Interval shield = new Interval(totalOccurrenceDefensive, totalOccurrenceDefensive + shieldOccurrence - 1);
-        totalOccurrenceDefensive += shieldOccurrence;
-        defensive.put(shield, "s");
-
-        // get arrow
-        int arrowOccurrence = game.getArena().getArrowOccurrence();
-        Interval arrow = new Interval(totalOccurrenceDefensive, totalOccurrenceDefensive + arrowOccurrence - 1);
-        totalOccurrenceDefensive += arrowOccurrence;
-        defensive.put(arrow, "a");
-
-        // get fireball
-        Interval fireball = new Interval(totalOccurrenceDefensive, totalOccurrenceDefensive + arrowOccurrence - 1);
-        totalOccurrenceDefensive += arrowOccurrence;
-        defensive.put(fireball, "f");
-    }
-
-    public ItemStack getRandomItem() {
-        Random randomizer = new Random();
-        int random;
-
-        ItemStack itemStack = null;
-
-        // switch between type of "items":
-        // after 2 occurrence items, you get one defensive item
-        if (randomizeCounter == 2) {
-            randomizeCounter = 0;
-            random = randomizer.nextInt(totalOccurrenceDefensive);
-            
-            for (Interval interval : defensive.keySet()) {
-                if (interval.isIn(random)) {
-
-                    switch (defensive.get(interval)) {
-                        case "s": return shield;
-                        case "a": return arrow;
-                        case "f": return fireball;
-                        default: return null;
-                    }
-
-                }
-            }
-        } else {
-            random = randomizer.nextInt(totalOccurrenceMissiles);
-            
-            for (Interval interval : missiles.keySet()) {
-                if (interval.isIn(random)) {
-                    String randomItem = missiles.get(interval);
-                    Missile missile = missileConfiguration.getMissileFromName(randomItem);
-
-                    if (missile != null) {
-                        itemStack = missile.getItem();
-                    } else
-                        Logger.DEBUG.log("There wasn't a missile found, when giving out items");
-                    randomizeCounter++;
-                }
-            }
-        }
-        return itemStack;
-    }
-
-    /**
-     * This method creates the item stacks for the defense random-items.
-     */
-    private void createDefenseItems() {
-
-        // create MW shield
-        shield = new ItemStack(VersionUtil.getSnowball());
-        ItemMeta shieldMeta = shield.getItemMeta();
-        shieldMeta.setDisplayName(game.getArena().getShieldConfiguration().getName());
-        shield.setItemMeta(shieldMeta);
-
-        // create MW arrow
-        arrow = new ItemStack(Material.ARROW, 3);
-
-        // create MW fireball
-        fireball = new ItemStack(VersionUtil.getFireball());
-        ItemMeta fireballMeta = fireball.getItemMeta();
-        fireballMeta.setDisplayName(game.getArena().getFireballConfiguration().getName());
-        fireball.setItemMeta(fireballMeta);
-
-    }
-
-}

+ 170 - 0
missilewars-plugin/src/main/java/de/butzlabben/missilewars/util/PlayerEquipmentRandomizer.java

@@ -0,0 +1,170 @@
+/*
+ * This file is part of MissileWars (https://github.com/Butzlabben/missilewars).
+ * Copyright (c) 2018-2021 Daniel Nägele.
+ *
+ * MissileWars is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MissileWars 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MissileWars.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package de.butzlabben.missilewars.util;
+
+import de.butzlabben.missilewars.Logger;
+import de.butzlabben.missilewars.game.Game;
+import de.butzlabben.missilewars.wrapper.abstracts.Arena;
+import de.butzlabben.missilewars.wrapper.missile.Missile;
+import de.butzlabben.missilewars.wrapper.player.MWPlayer;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.Random;
+
+/**
+ * @author Butzlabben
+ * @since 19.01.2018
+ */
+
+public class PlayerEquipmentRandomizer {
+
+    private final MWPlayer mwPlayer;
+    private final Game game;
+    private final Arena arena;
+
+    private final int maxGameDuration;
+    private final Random randomizer;
+    private static final int DEFAULT_INTERVAL_BY_TEAM_AMOUNT = 20;
+    private static final int DEFAULT_FACTOR_BY_GAME_TIME = 1;
+
+    int playerInterval;
+    int sendEquipmentCounter = 0;
+
+
+    public PlayerEquipmentRandomizer(MWPlayer mwPlayer, Game game) {
+        this.mwPlayer = mwPlayer;
+        this.game = game;
+        this.arena = game.getArena();
+        randomizer = new Random();
+        maxGameDuration = game.getArena().getGameDuration() * 60;
+
+        setPlayerInterval(getStartInterval() + 1);
+    }
+
+    public void tick() {
+
+        setPlayerInterval(playerInterval - 1);
+
+        if (playerInterval <= 0) {
+
+            sendRandomGameEquipment();
+            setPlayerInterval((int) Math.ceil(getIntervalByTeamAmount() * getFactorByGameTime()));
+        }
+    }
+
+    private void setPlayerInterval(Integer playerInterval) {
+        this.playerInterval = playerInterval;
+        mwPlayer.getPlayer().setLevel(playerInterval);
+    }
+
+    /**
+     * This method gives the player a random item of one of the two
+     * game equipment lists. The two lists alternate: after two
+     * missiles from the MissileEquipmentList, the player gets a
+     * special item from the SpecialEquipmentList.
+     */
+    private void sendRandomGameEquipment() {
+
+        ItemStack item;
+        int randomID;
+
+        // switch between type of "items":
+        // after 2 missile items, you get one special item
+        if (sendEquipmentCounter >= 2) {
+
+            randomID = randomizer.nextInt(game.getSpecialEquipment().getSpecialEquipmentList().size());
+            item = game.getSpecialEquipment().getSpecialEquipmentList().get(randomID);
+
+            sendEquipmentCounter = 0;
+
+        } else {
+
+            randomID = randomizer.nextInt(game.getMissileEquipment().getMissileEquipmentList().size());
+            Missile missile = game.getMissileEquipment().getMissileEquipmentList().get(randomID);
+            item = missile.getItem();
+
+        }
+
+        if (item == null) return;
+
+        mwPlayer.getPlayer().getInventory().addItem(item);
+        sendEquipmentCounter++;
+    }
+
+    /**
+     * This method returns the interval after the player receives a new
+     * item at game start.
+     *
+     * @return (int) the interval in seconds
+     */
+    private int getStartInterval() {
+        return arena.getInterval().getStart();
+    }
+
+    /**
+     * This method returns the interval after the player receives a new
+     * item during the game. It depends on the current team size and the
+     * same or next lower key value in the config.
+     *
+     * @return (int) the interval in seconds
+     */
+    private int getIntervalByTeamAmount() {
+
+        if (arena.getInterval().getIntervalsByTeamAmount().isEmpty()) {
+            Logger.WARN.log("The given interval mapping in \"" + arena.getName() + "\" is empty. Choosing default value " + DEFAULT_INTERVAL_BY_TEAM_AMOUNT + ".");
+            return DEFAULT_INTERVAL_BY_TEAM_AMOUNT;
+        }
+
+        int teamSize = mwPlayer.getTeam().getMembers().size();
+        for (int i = teamSize; i > 0; i--) {
+            if (arena.getInterval().getIntervalsByTeamAmount().containsKey(Integer.toString(i))) {
+                return arena.getInterval().getIntervalsByTeamAmount().get(Integer.toString(i));
+            }
+        }
+
+        Logger.DEBUG.log("No interval value for map \"" + arena.getName() + "\" could be detected based on the team amount of " + teamSize + ". Please define at least one a interval value for a minimal team amount of 1.");
+        return DEFAULT_INTERVAL_BY_TEAM_AMOUNT;
+    }
+
+    /**
+     * This method returns the interval factor after the player receives a new
+     * item during the game. It depends on the current game time and the
+     * same or next higher key value in the config.
+     *
+     * @return (int) the interval factor in seconds
+     */
+    private double getFactorByGameTime() {
+
+        if (arena.getInterval().getIntervalFactorByGameTime().isEmpty()) {
+            Logger.WARN.log("The given interval factor mapping in \"" + arena.getName() + "\" is empty. Choosing default value " + DEFAULT_FACTOR_BY_GAME_TIME + ".");
+            return DEFAULT_FACTOR_BY_GAME_TIME;
+        }
+
+        int seconds = game.getTimer().getSeconds();
+        for (int i = seconds; i <= maxGameDuration; i++) {
+            if (arena.getInterval().getIntervalFactorByGameTime().containsKey(Integer.toString(i))) {
+                return arena.getInterval().getIntervalFactorByGameTime().get(Integer.toString(i));
+            }
+        }
+
+        Logger.DEBUG.log("No interval factor value for map \"" + arena.getName() + "\" could be detected based on the game time of " + seconds + ". Please define at least one a interval value for a minimal team amount of " + maxGameDuration + ".");
+        return DEFAULT_FACTOR_BY_GAME_TIME;
+    }
+
+}

+ 5 - 27
missilewars-plugin/src/main/java/de/butzlabben/missilewars/wrapper/abstracts/Arena.java

@@ -19,15 +19,13 @@
 package de.butzlabben.missilewars.wrapper.abstracts;
 
 import com.google.gson.annotations.SerializedName;
-import de.butzlabben.missilewars.Logger;
 import de.butzlabben.missilewars.wrapper.abstracts.arena.*;
 import de.butzlabben.missilewars.wrapper.geometry.FlatArea;
 import de.butzlabben.missilewars.wrapper.geometry.Plane;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import lombok.*;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.RequiredArgsConstructor;
 import org.bukkit.Location;
 import org.bukkit.util.Vector;
 
@@ -55,33 +53,13 @@ public class Arena {
     @SerializedName("save_statistics") private boolean saveStatistics = true;
     @SerializedName("fall_protection") private FallProtectionConfiguration fallProtection = new FallProtectionConfiguration();
     @SerializedName("money") private MoneyConfiguration money = new MoneyConfiguration();
-    @SerializedName("intervals") private Map<Integer, Integer> intervals = new HashMap<>() {{
-        put(1, 15);
-        put(2, 20);
-        put(4, 25);
-    }};
+    @SerializedName("equipment_interval") private EquipmentIntervalConfiguration interval = new EquipmentIntervalConfiguration();
     @SerializedName("missile_configuration") private MissileConfiguration missileConfiguration = new MissileConfiguration();
     @SerializedName("spectator_spawn") private Location spectatorSpawn = new Location(null, 0, 100, 0, 90, 0);
     @SerializedName("area") private FlatArea gameArea = new FlatArea(-30, -72, 30, 72);
     @SerializedName("team1_spawn") private Location team1Spawn = new Location(null, 0.5, 100, 45.5, 180, 0);
     @SerializedName("team2_spawn") private Location team2Spawn = new Location(null, 0.5, 100, -45.5, 0, 0);
 
-    public int getInterval(int teamSize) {
-        if (intervals.isEmpty()) {
-            Logger.WARN.log("The given interval mapping in \"" + name + "\" is empty. Choosing default value 20");
-            return 20;
-        }
-        if (intervals.containsKey(teamSize)) return intervals.get(teamSize);
-        for (int i = teamSize; i > 0; i--) {
-            if (intervals.containsKey(i)) return intervals.get(i);
-        }
-        int highestMapping = Collections.max(intervals.keySet());
-        for (int i = teamSize; i < highestMapping; i++) {
-            if (intervals.containsKey(i)) return intervals.get(i);
-        }
-        throw new IllegalStateException("We should never arrive here, ...");
-    }
-
     public Plane getPlane1() {
         Vector spawn1 = team1Spawn.toVector();
         Vector normal = team2Spawn.toVector().subtract(spawn1);

+ 49 - 0
missilewars-plugin/src/main/java/de/butzlabben/missilewars/wrapper/abstracts/arena/EquipmentIntervalConfiguration.java

@@ -0,0 +1,49 @@
+/*
+ * This file is part of MissileWars (https://github.com/Butzlabben/missilewars).
+ * Copyright (c) 2018-2021 Daniel Nägele.
+ *
+ * MissileWars is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MissileWars 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MissileWars.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package de.butzlabben.missilewars.wrapper.abstracts.arena;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@ToString
+@RequiredArgsConstructor
+public class EquipmentIntervalConfiguration {
+
+    private int start = 10;
+
+    @SerializedName("intervals_by_team_amount") private Map<String, Integer> intervalsByTeamAmount = new HashMap<>() {{
+        put("1", 15);
+        put("2", 20);
+        put("4", 25);
+    }};
+
+    @SerializedName("interval_factor_by_game_time") private Map<String, Double> intervalFactorByGameTime = new HashMap<>() {{
+        put("1800", 1.0);
+        put("900", 0.9);
+        put("600", 0.8);
+        put("300", 0.7);
+    }};
+
+}

+ 63 - 0
missilewars-plugin/src/main/java/de/butzlabben/missilewars/wrapper/game/MissileGameEquipment.java

@@ -0,0 +1,63 @@
+/*
+ * This file is part of MissileWars (https://github.com/Butzlabben/missilewars).
+ * Copyright (c) 2018-2021 Daniel Nägele.
+ *
+ * MissileWars is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MissileWars 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MissileWars.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package de.butzlabben.missilewars.wrapper.game;
+
+import de.butzlabben.missilewars.game.Game;
+import de.butzlabben.missilewars.wrapper.missile.Missile;
+import lombok.Getter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Butzlabben
+ * @since 19.01.2018
+ */
+
+@Getter
+public class MissileGameEquipment {
+
+    private final Game game;
+
+    private List<Missile> missileEquipmentList = new ArrayList<>();
+
+
+    public MissileGameEquipment(Game game) {
+        this.game = game;
+
+        createMissileEquipmentList();
+    }
+
+    /**
+     * This method goes through all configured missiles and adds them
+     * to the list. The higher the defined spawn-occurrence of a missile
+     * being set, the more often it will be added to the list.
+     */
+    private void createMissileEquipmentList() {
+
+        for (Missile missile : game.getArena().getMissileConfiguration().getMissiles()) {
+            for (int i = missile.getOccurrence(); i > 0; i--) {
+                missileEquipmentList.add(missile);
+            }
+        }
+
+
+    }
+
+}

+ 111 - 0
missilewars-plugin/src/main/java/de/butzlabben/missilewars/wrapper/game/SpecialGameEquipment.java

@@ -0,0 +1,111 @@
+/*
+ * This file is part of MissileWars (https://github.com/Butzlabben/missilewars).
+ * Copyright (c) 2018-2021 Daniel Nägele.
+ *
+ * MissileWars is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MissileWars 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MissileWars.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package de.butzlabben.missilewars.wrapper.game;
+
+import de.butzlabben.missilewars.game.Game;
+import de.butzlabben.missilewars.util.version.VersionUtil;
+import lombok.Getter;
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Butzlabben
+ * @since 19.01.2018
+ */
+
+@Getter
+public class SpecialGameEquipment {
+
+    private final Game game;
+
+    private ItemStack shield;
+    private ItemStack arrow;
+    private ItemStack fireball;
+
+    private List<ItemStack> specialEquipmentList = new ArrayList<>();
+
+
+    public SpecialGameEquipment(Game game) {
+        this.game = game;
+
+        createShield();
+        createArrow();
+        createFireball();
+
+        createSpecialEquipmentList();
+    }
+
+    /**
+     * This method goes through all configured special equipment items
+     * and adds them to the list. The higher the defined spawn-occurrence
+     * of an item type being set, the more often it will be added to the list.
+     */
+    private void createSpecialEquipmentList() {
+
+        int shieldOccurrence = game.getArena().getShieldConfiguration().getOccurrence();
+        int arrowOccurrence = game.getArena().getArrowOccurrence();
+        int fireballOccurrence = game.getArena().getFireballConfiguration().getOccurrence();
+
+        for (int i = shieldOccurrence; i > 0; i--) {
+            specialEquipmentList.add(shield);
+        }
+
+        for (int i = arrowOccurrence; i > 0; i--) {
+            specialEquipmentList.add(arrow);
+        }
+
+        for (int i = fireballOccurrence; i > 0; i--) {
+            specialEquipmentList.add(fireball);
+        }
+
+    }
+
+    /**
+     * This method creates the shield item stack.
+     */
+    private void createShield() {
+        shield = new ItemStack(VersionUtil.getSnowball());
+        ItemMeta shieldMeta = shield.getItemMeta();
+        shieldMeta.setDisplayName(game.getArena().getShieldConfiguration().getName());
+        shield.setItemMeta(shieldMeta);
+    }
+
+    /**
+     * This method creates the arrow item stack.
+     */
+    private void createArrow() {
+        arrow = new ItemStack(Material.ARROW, 3);
+    }
+
+    /**
+     * This method creates the fireball item stack.
+     */
+    private void createFireball() {
+        fireball = new ItemStack(VersionUtil.getFireball());
+        ItemMeta fireballMeta = fireball.getItemMeta();
+        fireballMeta.setDisplayName(game.getArena().getFireballConfiguration().getName());
+        fireball.setItemMeta(fireballMeta);
+    }
+
+
+}

+ 1 - 5
missilewars-plugin/src/main/java/de/butzlabben/missilewars/wrapper/game/Team.java

@@ -233,7 +233,7 @@ public class Team {
         }
     }
 
-
+    // TODO Review for necessity (of an alternative), completeness and refactoring
     public void updateIntervals(int newInterval) {
         if (newInterval < currentInterval && currentInterval != 0) {
             getGame().broadcast(MessageConfig.getMessage("team_buffed").replace("%team%", getFullname()));
@@ -241,10 +241,6 @@ public class Team {
         if (newInterval > currentInterval && currentInterval != 0) {
             getGame().broadcast(MessageConfig.getMessage("team_nerved").replace("%team%", getFullname()));
         }
-        for (MWPlayer mwPlayer : members) {
-            mwPlayer.setPeriod(newInterval);
-        }
-        currentInterval = newInterval;
     }
 
 }

+ 4 - 16
missilewars-plugin/src/main/java/de/butzlabben/missilewars/wrapper/player/MWPlayer.java

@@ -19,7 +19,7 @@
 package de.butzlabben.missilewars.wrapper.player;
 
 import de.butzlabben.missilewars.game.Game;
-import de.butzlabben.missilewars.util.GameRandomizer;
+import de.butzlabben.missilewars.util.PlayerEquipmentRandomizer;
 import de.butzlabben.missilewars.wrapper.game.Team;
 import lombok.EqualsAndHashCode;
 import lombok.Getter;
@@ -42,14 +42,13 @@ public class MWPlayer implements Runnable {
     final long id = NEXT_ID.getAndIncrement();
     private final UUID uuid;
     private final Game game;
-    int i = -1;
     @Setter private Team team;
-    private GameRandomizer r;
-    @Setter private int period;
+    private PlayerEquipmentRandomizer randomGameEquipment;
 
     public MWPlayer(Player player, Game game) {
         this.uuid = player.getUniqueId();
         this.game = game;
+        this.randomGameEquipment = new PlayerEquipmentRandomizer(this, game);
     }
 
     public Player getPlayer() {
@@ -62,18 +61,7 @@ public class MWPlayer implements Runnable {
         Player p = Bukkit.getPlayer(uuid);
         if (p == null || !p.isOnline()) return;
 
-        if (i == -1) {
-            i = period - 10;
-            if (i >= period || i < 0) i = 0;
-        }
-        i++;
-        if (i >= period) {
-            if (r == null)
-                r = new GameRandomizer(game);
-            p.getInventory().addItem(r.getRandomItem());
-            i = 0;
-        }
-        p.setLevel(period - i);
+        randomGameEquipment.tick();
     }
 
     @Override