<commit_before>package com.voxelgameslib.voxelgameslib.feature.features;

import com.google.gson.annotations.Expose;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import javax.annotation.Nonnull;

import com.voxelgameslib.voxelgameslib.event.GameEvent;
import com.voxelgameslib.voxelgameslib.event.events.game.GameJoinEvent;
import com.voxelgameslib.voxelgameslib.feature.AbstractFeature;
import com.voxelgameslib.voxelgameslib.feature.Feature;
import com.voxelgameslib.voxelgameslib.feature.FeatureInfo;
import com.voxelgameslib.voxelgameslib.map.BasicMarkerDefinition;
import com.voxelgameslib.voxelgameslib.map.Map;
import com.voxelgameslib.voxelgameslib.map.Marker;
import com.voxelgameslib.voxelgameslib.map.MarkerDefinition;
import com.voxelgameslib.voxelgameslib.map.Vector3D;
import com.voxelgameslib.voxelgameslib.user.User;

import org.bukkit.Location;
import org.bukkit.event.player.PlayerRespawnEvent;

@FeatureInfo(name = "SpawnFeature", author = "MiniDigger", version = "1.0",
        description = "Handles (re)spawning")
public class SpawnFeature extends AbstractFeature {

    @Expose
    private boolean isRespawn = true;
    @Expose
    private boolean isInitialSpawn = true;

    private List<Vector3D> spawns = new ArrayList<>();
    private Map map;

    private MarkerDefinition spawnMarker = new BasicMarkerDefinition("spawn");

    @Override
    public void start() {
        map = getPhase().getFeature(MapFeature.class).getMap();
        for (Marker marker : map.getMarkers(spawnMarker)) {
            spawns.add(marker.getLoc());
        }
        if (isInitialSpawn) {
            for (User user : getPhase().getGame().getPlayers()) {
                user.getPlayer().teleport(getSpawn(user.getPlayer().getUniqueId()));
            }
        }
    }

    public void addSpawn(@Nonnull Vector3D spawn) {
        spawns.add(spawn);
    }

    /**
     * Generates a spawn location for that user
     *
     * @param id the uuid user which wants to spawn
     * @return the location he should spawn
     */
    @Nonnull
    public Location getSpawn(@Nonnull UUID id) {
        //TODO super fancy spawn algorithm
        return spawns.get(ThreadLocalRandom.current().nextInt(spawns.size()))
                .toLocation(map.getLoadedName(getPhase().getGame().getUuid()));
    }

    @SuppressWarnings("JavaDoc")
    @GameEvent
    public void onRespawn(@Nonnull PlayerRespawnEvent e) {
        e.setRespawnLocation(getSpawn(e.getPlayer().getUniqueId()));
    }

    @SuppressWarnings("JavaDoc")
    @GameEvent
    public void onJoin(@Nonnull GameJoinEvent e) {<commit_msg>add small offset to spawn feature so that you spawn in the middle of the block<commit_after>package com.voxelgameslib.voxelgameslib.feature.features;

import com.google.gson.annotations.Expose;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import javax.annotation.Nonnull;

import com.voxelgameslib.voxelgameslib.event.GameEvent;
import com.voxelgameslib.voxelgameslib.event.events.game.GameJoinEvent;
import com.voxelgameslib.voxelgameslib.feature.AbstractFeature;
import com.voxelgameslib.voxelgameslib.feature.Feature;
import com.voxelgameslib.voxelgameslib.feature.FeatureInfo;
import com.voxelgameslib.voxelgameslib.map.BasicMarkerDefinition;
import com.voxelgameslib.voxelgameslib.map.Map;
import com.voxelgameslib.voxelgameslib.map.Marker;
import com.voxelgameslib.voxelgameslib.map.MarkerDefinition;
import com.voxelgameslib.voxelgameslib.map.Vector3D;
import com.voxelgameslib.voxelgameslib.user.User;

import org.bukkit.Location;
import org.bukkit.event.player.PlayerRespawnEvent;

@FeatureInfo(name = "SpawnFeature", author = "MiniDigger", version = "1.0",
        description = "Handles (re)spawning")
public class SpawnFeature extends AbstractFeature {

    @Expose
    private boolean isRespawn = true;
    @Expose
    private boolean isInitialSpawn = true;

    private List<Vector3D> spawns = new ArrayList<>();
    private Map map;

    private MarkerDefinition spawnMarker = new BasicMarkerDefinition("spawn");

    @Override
    public void start() {
        map = getPhase().getFeature(MapFeature.class).getMap();
        for (Marker marker : map.getMarkers(spawnMarker)) {
            spawns.add(marker.getLoc());
        }
        if (isInitialSpawn) {
            for (User user : getPhase().getGame().getPlayers()) {
                user.getPlayer().teleport(getSpawn(user.getPlayer().getUniqueId()));
            }
        }
    }

    public void addSpawn(@Nonnull Vector3D spawn) {
        spawns.add(spawn);
    }

    /**
     * Generates a spawn location for that user
     *
     * @param id the uuid user which wants to spawn
     * @return the location he should spawn
     */
    @Nonnull
    public Location getSpawn(@Nonnull UUID id) {
        //TODO super fancy spawn algorithm
        return spawns.get(ThreadLocalRandom.current().nextInt(spawns.size()))
                .toLocation(map.getLoadedName(getPhase().getGame().getUuid())).add(0.5, 0, 0.5);
    }

    @SuppressWarnings("JavaDoc")
    @GameEvent
    public void onRespawn(@Nonnull PlayerRespawnEvent e) {
        e.setRespawnLocation(getSpawn(e.getPlayer().getUniqueId()));
    }

    @SuppressWarnings("JavaDoc")
    @GameEvent
    public void onJoin(@Nonnull GameJoinEvent e) {
{'fraction_non_alphanumeric': 0.10744563214154074, 'fraction_numerical': 0.0027644673792849243, 'mean_word_length': 3.7397379912663755, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4157321', 'n_tokens_mistral': 1755, 'n_tokens_neox': 1716, 'n_words': 321}