#help

1 messages · Page 1 of 1 (latest)

radiant steppe
#

@brazen ivy

brazen ivy
#

ok

#

what generates this block you walk on? When does it get generated?

radiant steppe
#

            if(playerFile.exists()){
                YamlConfiguration config = YamlConfiguration.loadConfiguration(playerFile);
                generatedBlockType = Material.valueOf(config.getString("blockType"));
            } else {

                generatedBlockType = solidMaterials.get(random.nextInt(solidMaterials.size()));

                blockGenerated = true;
                System.out.println("generated block type: " + generatedBlockType);
                saveBlockData(p, generatedBlockType);
            }
brazen ivy
#

so you are generating it as you walk?

radiant steppe
#

only once

#

that's what the boolean is for

brazen ivy
#

Not sure I understand

#

why are you generating a block?

radiant steppe
#

it's like a task system

#

a random block is generated and walking on it is a task

brazen ivy
#

but are you not just generating the block under the player?

radiant steppe
#

no

brazen ivy
#

so they are instantly walking on it

radiant steppe
#

noo

#

as you move, a random block from the materials enum is generated

brazen ivy
#

where do you need to generate thsi block?

radiant steppe
#

wdym where

brazen ivy
#

at what location?

radiant steppe
#

i think generate is the wrong word

#

i need to randomly choose a block

brazen ivy
#

ok you are picking a random material

radiant steppe
#

yes

brazen ivy
#

nothgin is in teh world at that time

#

the player has to find a block of that type and walk on it

radiant steppe
#

yes

brazen ivy
#

does your plugin tell the player what type of block they need to find?

radiant steppe
#

that will come later

#

it isn't relevant

brazen ivy
#

ok

#

well first off your code is way over engineered

#

and it only works for a single player

#

as you are using the player move event you need to do some early exit code

radiant steppe
#

like what?

brazen ivy
#

it's a heavy event

#

if (event.getFrom().getBlock() == event.getTo().getBlock()) return;

#

as the very first line

#

that way you only run your code when they move to a different block

radiant steppe
#

you mean all the code has to be in the if statement?

brazen ivy
#

next you need to change Block block = p.getLocation().getBlock(); To Block block = p.getLocation().getBlock().getRelative(BlockFace.DOWN);

#

if you are only using solid blocks

#

that gets the block below the players feet

radiant steppe
#

ok.

#

done that

#

now let me check

brazen ivy
#

you should really generate the target block type once when you need it

radiant steppe
#

i mean i am

#

i have a blockGenerated boolean

brazen ivy
#

so it's not in the move event

radiant steppe
#

it only generates the block once

brazen ivy
#

you shoudl have a method to do it that you call when you need to

#

move all the code out of the move event

#

in the move event you only want to be testign if they walked on teh correct block

radiant steppe
#

ok

#

gimme a sec

#

one question, did i do the saving to yaml file correctly?

brazen ivy
#

it looks ok, but I'd store it using the players UUID.toString()

#

names can change

radiant steppe
#

what did you say i need to keep in the moveevent?

brazen ivy
#
    @EventHandler
    public void onPlayerMove(PlayerMoveEvent e){
        if (event.getFrom().getBlock() == event.getTo().getBlock()) return;

        Player p = e.getPlayer();
        Block block = p.getLocation().getBlock().getRelative(BlockFace.DOWN);

        if (!blockGenerated) generateBlock(p);
        if(block.getType() == generatedBlockType && !completed){
                completeTask(p);
                completed = true;
        }
    }
}```
#

for now

radiant steppe
#
    public void generateBlock(){
        Random random = new Random();
        File dataFolder = plugin.getDataFolder();
        File playerFile = new File(dataFolder, p.getUniqueId() + ".yml");

        if(playerFile.exists()){
            YamlConfiguration config = YamlConfiguration.loadConfiguration(playerFile);
            generatedBlockType = Material.valueOf(config.getString("blockType"));
        } else {

            generatedBlockType = solidMaterials.get(random.nextInt(solidMaterials.size()));

            blockGenerated = true;
            System.out.println("generated block type: " + generatedBlockType);
            saveBlockData(p, generatedBlockType);
        }
    }
#

how can I get a reference to the player here?

brazen ivy
#

add Player p in the arguments of the method

radiant steppe
#
    public void generateBlock(Player p){
        Random random = new Random();
        File dataFolder = plugin.getDataFolder();
        File playerFile = new File(dataFolder, p.getUniqueId() + ".yml");

        if(playerFile.exists()){
            YamlConfiguration config = YamlConfiguration.loadConfiguration(playerFile);
            generatedBlockType = Material.valueOf(config.getString("blockType"));
        } else {

            generatedBlockType = solidMaterials.get(random.nextInt(solidMaterials.size()));

            blockGenerated = true;
            System.out.println("generated block type: " + generatedBlockType);
            saveBlockData(p, generatedBlockType);
        }
    }

    @EventHandler
    public void onPlayerMove(PlayerMoveEvent e){
        Player p = e.getPlayer();
        Block block = p.getLocation().getBlock().getRelative(BlockFace.DOWN);



        if (!blockGenerated) {
            generateBlock(p);
        }
        if(block.getType() == generatedBlockType && !completed){
            completeTask(p);
            completed = true;
        }
    }
#

correct?

brazen ivy
#

looks ok

radiant steppe
#

now let mecheck

brazen ivy
#

I forgot the early exit

#

I edited teh event code above

radiant steppe
#

one more thing

#

private final List<Material> solidMaterials = Arrays.asList(Material.values())
.stream()
.filter(Material::isBlock)
.toList();

#

it's only generating non solid blocks now

#

like coral fans

#

and stuff

brazen ivy
#
private final List<Material> solidMaterials = Arrays.asList(Material.values())
            .stream()
            .filter(Material::isBlock)
            .filter(Material::isSolid)
            .toList();```
radiant steppe
#

nope, it's still only giving me doors

#

and slabs

brazen ivy
#

then you are reversing teh check somewhere

#

sec

radiant steppe
#

wait i think it works

brazen ivy
#

I was about to say thats impossible on those filters

radiant steppe
#

yeah it works

#

and literally one last thing

#

every time i reload or restart the server

#

it still runs the completetask even though it should only run once after waling on the block for the first time

brazen ivy
#

if you reload all your fields are reset

#

so its no longer completed

radiant steppe
#

is there a way to avoid this?

brazen ivy
#

you need to store the states in the players data file

radiant steppe
#

ohh fine

brazen ivy
#

that way it's different for each player and stored in their data not in the class

#

then the Listener will work for all players and not just one

radiant steppe
#

so update the yml file?

brazen ivy
#

yes

radiant steppe
#

how can I do this with a boolean? because I can't just do boolen.toString() like I can with material

brazen ivy
#

yaml will auto convert primites

#

config.set("completed", completed)

#

config.getBoolean("completed");

radiant steppe
#
    private void saveBlockData(Player p, Material material, boolean moveTaskCompleted){
        YamlConfiguration config = new YamlConfiguration();
        config.set("playerName", p.getName());
        config.set("blockType", material.toString());
        config.set("moveTaskCompleted", moveTaskCompleted);
brazen ivy
#

yep

#

afk for 10 mins, loo

#

back in a bit if you still stuck

radiant steppe
#

ok thanks

#

❤️

radiant steppe
# brazen ivy back in a bit if you still stuck

just when your back,

        if(block.getType() == generatedBlockType && !completed){
            completeTask(p);
            completed = true;
            saveBlockData(p, generatedBlockType, true);
        }

i know i need to replace the !completed with the value from the yaml file, but how can I do that?

brazen ivy
#

ok I'm back

#

now currently your code will run really bad for performance so we need to cache the player data

#

so create a Private Map<UUID, YamlConfiguration> playerData = new HashMap<>();

#

@radiant steppe

radiant steppe
#

in the same listener?

#

like the same class

#

as the listener

#

?

brazen ivy
#

for now yes

radiant steppe
#

ok

brazen ivy
#

then create a method private YamlConfiguration getPlayerData(Player player) {};

radiant steppe
#

i'll just generate a getter

brazen ivy
#

no

#

it's actually a custom getter

#

we are not returning the Map

radiant steppe
#

ok

#

done

brazen ivy
#

inside the method we start with if (playerData.contains(player.getUniqueId())) return playerData.get(player.getUniqueId());

#

after that we do all teh file checks, if the file exists load the data from file and put in the Map and return it

#

if no file exists create it

radiant steppe
#

contains doesnt exist in Map

brazen ivy
#

containsKey

radiant steppe
#

what does the getter need to return

brazen ivy
#

then check if the file doesn;t exist create it, then load file and put in Map, then return it

#

a YamlConfiguration

#
private YamlConfiguration getPlayerData(Player player) {
  if (playerData.containsKey(player.getUniqueId())) return playerData.get(player.getUniqueId());
...
};```
radiant steppe
#

umm

brazen ivy
#

eventually you will be able tojava data = getPlayerData(event.getPlayer()); if (data.getBoolean("completed")) {...

#

later you can make it even cleaner by wrapping your YamlConfiguration in a data object

radiant steppe
#

can I use the same file that is already created?

#

in the saveBlockData method?

brazen ivy
#

yes

#

but check the map first

#

if it's in teh map you fetch it and return it

radiant steppe
#

if (playerData.containsKey(player.getUniqueId())) return playerData.get(player.getUniqueId());

#

this?

brazen ivy
#

if it's not you check for a file

#

if not there you create it, store it in the map and return it

#

yes

radiant steppe
brazen ivy
#

you already have the code creating the file

radiant steppe
#

@brazen ivy and?

brazen ivy
#

sec

#

probably

#

not tested it but that "should" do it

#

uncomment your completeTask

#

if it works you probably want to move your cache data into its own class and wrap your YamlConfiguration to have getter/setters

radiant steppe
#

@brazen ivy it doesn't run the completetask method at all

brazen ivy
#

uncomment it. I commented it out as I didn;t have that import

radiant steppe
#

of course

#

mb

#

omg it works

#

tysm