#help
1 messages · Page 1 of 1 (latest)
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);
}
so you are generating it as you walk?
but are you not just generating the block under the player?
no
so they are instantly walking on it
where do you need to generate thsi block?
wdym where
at what location?
ok you are picking a random material
yes
nothgin is in teh world at that time
the player has to find a block of that type and walk on it
yes
does your plugin tell the player what type of block they need to find?
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
like what?
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
you mean all the code has to be in the if statement?
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
you should really generate the target block type once when you need it
so it's not in the move event
it only generates the block once
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
what did you say i need to keep in the moveevent?
@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
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?
add Player p in the arguments of the method
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?
looks ok
now let mecheck
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
private final List<Material> solidMaterials = Arrays.asList(Material.values())
.stream()
.filter(Material::isBlock)
.filter(Material::isSolid)
.toList();```
wait i think it works
I was about to say thats impossible on those filters
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
is there a way to avoid this?
you need to store the states in the players data file
ohh fine
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
so update the yml file?
yes
how can I do this with a boolean? because I can't just do boolen.toString() like I can with material
yaml will auto convert primites
config.set("completed", completed)
config.getBoolean("completed");
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);
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?
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
for now yes
ok
then create a method private YamlConfiguration getPlayerData(Player player) {};
i'll just generate a getter
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
contains doesnt exist in Map
containsKey
what does the getter need to return
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());
...
};```
umm
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
wait a sec
can I use the same file that is already created?
in the saveBlockData method?
if (playerData.containsKey(player.getUniqueId())) return playerData.get(player.getUniqueId());
this?
if it's not you check for a file
if not there you create it, store it in the map and return it
yes
how though?
you already have the code creating the file
https://paste.md-5.net/ paste your current code
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
@brazen ivy it doesn't run the completetask method at all
uncomment it. I commented it out as I didn;t have that import