Sit/src/main/java/one/oth3r/sit/utl/Logic.java

240 lines
9.5 KiB
Java
Raw Normal View History

2024-07-11 13:43:54 -05:00
package one.oth3r.sit.utl;
import net.minecraft.entity.decoration.DisplayEntity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.MutableText;
import net.minecraft.util.Formatting;
2024-07-11 13:43:54 -05:00
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import one.oth3r.sit.file.*;
2024-07-11 13:43:54 -05:00
import org.jetbrains.annotations.Nullable;
2025-05-03 15:41:16 -05:00
import java.awt.*;
2024-07-11 13:43:54 -05:00
public class Logic {
2025-03-10 10:11:51 -05:00
2025-03-12 18:20:53 -05:00
/**
* checks if the player can sit at the block specified
* @param player the player that's going to sit
* @param blockPos the position that the player is going to sit at
* @param hitResult nullable, not null if the player is sitting with their hand
* @return true if the player can sit with the conditions provided
*/
2025-03-10 10:11:51 -05:00
public static boolean canSit(ServerPlayerEntity player, BlockPos blockPos, @Nullable BlockHitResult hitResult) {
2024-07-11 13:43:54 -05:00
// cant sit if crouching
if (player.isSneaking()) return false;
// if sitting on a sit entity and sit while seated off, false
if (!FileData.getServerConfig().canSitWhileSeated() && Data.getSitEntity(player) != null) return false;
2024-07-23 11:02:02 -05:00
2024-07-11 13:43:54 -05:00
// if hit result isnt null (check the hands of the player) & the player hand checker returns false (can't sit with the items in the hand), quit
if (hitResult != null) {
if (!checkHands(player)) return false;
}
2025-02-11 14:51:32 -06:00
// check if the block is in the right y level limits from the config
if (!checkYLimits(player, blockPos)) return false;
ServerWorld serverWorld = player.getWorld();
2024-07-11 13:43:54 -05:00
2025-03-10 10:11:51 -05:00
Double sitHeight = Utl.getSittingHeight(player,blockPos,hitResult);
2024-07-11 13:43:54 -05:00
2025-03-10 10:11:51 -05:00
// if the sit height is null, it's not a sittable block
2024-07-11 13:43:54 -05:00
if (sitHeight == null) return false;
DisplayEntity.TextDisplayEntity entity = Utl.Entity.create(serverWorld,blockPos,sitHeight);
2025-03-10 10:11:51 -05:00
// checks if the player can sit
return checkPlayerSitAbility(entity);
}
2025-03-12 18:20:53 -05:00
/**
* makes the player attempt to sit at the position provided (checks if the player can sit before)
* @param player the player that is sitting
* @param blockPos the pos the player is going to sit at
* @param hitResult nullable, not null if the player is sitting with their hand
* @return true if sitting was successful
*/
2025-03-10 10:11:51 -05:00
public static boolean sit(ServerPlayerEntity player, BlockPos blockPos, @Nullable BlockHitResult hitResult) {
if (!canSit(player, blockPos, hitResult)) return false;
// assets
ServerWorld serverWorld = player.getWorld();
2025-03-10 10:11:51 -05:00
Double sitHeight = Utl.getSittingHeight(player,blockPos,hitResult);
// shouldn't be null because we already checked, but do another check to clear IDE errors
2025-03-12 18:20:53 -05:00
assert sitHeight != null;
2024-07-11 13:43:54 -05:00
2025-03-10 10:11:51 -05:00
// spawn the entity and make the player sit
Utl.Entity.spawnSit(player, Utl.Entity.create(serverWorld,blockPos,sitHeight));
2024-07-11 13:43:54 -05:00
return true;
}
2025-03-12 18:20:53 -05:00
/**
* makes the player attempt to sit at the block they are looking at (range of 5)
* @param player the player who is trying to sit
* @return true if sitting was successful
*/
2024-07-29 10:41:21 -05:00
public static boolean sitLooking(ServerPlayerEntity player) {
return sit(player, Utl.getBlockPosPlayerIsLookingAt(player.getWorld(),player,
Utl.getPlayerReach(player)),null);
2024-07-29 10:41:21 -05:00
}
2024-07-11 13:43:54 -05:00
/**
* checks the hands of the player and the items in each hand and sees if the player can sit down
*/
public static boolean checkHands(ServerPlayerEntity player) {
2024-07-23 12:27:01 -05:00
SittingConfig sittingConfig = FileData.getPlayerSetting(player);
2024-07-11 13:43:54 -05:00
// if can't sit with hand, false
2024-07-23 11:27:06 -05:00
if (!sittingConfig.canSitWithHand()) return false;
2024-07-11 13:43:54 -05:00
2024-08-07 12:46:47 -05:00
// a boolean that shows if the player can sit or not
2024-07-11 13:43:54 -05:00
boolean canSit = true;
// for each hand
for (Hand hand : Hand.values()) {
// if they can't sit, no need to run extra code
if (!canSit) break;
2024-07-23 11:27:06 -05:00
HandSetting handSetting = sittingConfig.getHand(hand);
2024-07-11 13:43:54 -05:00
switch (handSetting.getSittingRequirement()) {
case EMPTY -> canSit = player.getStackInHand(hand).isEmpty();
case FILTER -> canSit = Utl.checkItem(handSetting.getFilter(), player.getStackInHand(hand));
}
}
// return the output of the check
return canSit;
}
2025-02-11 14:51:32 -06:00
/**
* check if the Y-level of the block is within the limits of the player, bounds are set in the {@link ServerConfig}
*/
public static boolean checkYLimits(ServerPlayerEntity player, BlockPos blockPos) {
2025-02-13 15:59:46 -06:00
double playerY = player.getBlockY();
2025-02-11 14:51:32 -06:00
double blockY = blockPos.getY();
// if the block is above the eye height
2025-02-13 15:59:46 -06:00
boolean isAbove = playerY < blockY;
// return true if equal
if (playerY == blockY) return true;
2025-02-11 14:51:32 -06:00
// get the height difference (positive)
2025-02-13 15:59:46 -06:00
double heightDifference = Math.abs(playerY - blockY);
2025-02-11 14:51:32 -06:00
// get the config limits
ServerConfig.YDifferenceLimit yDifferenceLimit = FileData.getServerConfig().getYDifferenceLimit();
2025-02-11 14:51:32 -06:00
2025-02-13 15:59:46 -06:00
return (isAbove? yDifferenceLimit.getAbove() : yDifferenceLimit.getBelow()) >= heightDifference;
2025-02-11 14:51:32 -06:00
}
2024-07-11 13:43:54 -05:00
/**
2024-08-29 16:28:46 -05:00
* removes the entity bound to the player from the game, using the player
2024-07-11 13:43:54 -05:00
*/
public static void removeEntity(ServerPlayerEntity player) {
DisplayEntity.TextDisplayEntity entity = Data.getSitEntity(player);
2024-07-11 13:43:54 -05:00
// make sure the player has a sit entity bounded to them
if (entity == null) return;
// remove the entity
Utl.Entity.remove(entity);
}
/**
* spawns a sit entity for the player, they HAVE TO BE in the spawn list
*/
public static void spawnEntity(ServerPlayerEntity player) {
// return if not in the list
if (Data.getSpawnList().get(player) == null) return;
// if the player is already sitting on a sit entity, remove it before spawning a new one
if (Data.getSitEntity(player) != null) Logic.removeEntity(player);
// get the new entity
DisplayEntity.TextDisplayEntity sitEntity = Data.getSpawnList().get(player);
// spawn and ride the entity
player.getWorld().spawnEntity(sitEntity);
player.startRiding(sitEntity);
// add the entity to the list
Data.addSitEntity(player, sitEntity);
// remove the entity from the spawn list
Data.removeSpawnList(player);
}
2024-07-11 13:43:54 -05:00
/**
* checks if the player should still be sitting, e.g. the block was destroyed ect.
*/
public static void checkSittingValidity(ServerPlayerEntity player) {
DisplayEntity.TextDisplayEntity entity = Data.getSitEntity(player);
2024-07-11 13:43:54 -05:00
// make sure the player has a sit entity bounded to them
if (entity == null) return;
// if the entity location isn't valid anymore, remove it
if (!Utl.Entity.isValid(player,entity)) {
removeEntity(player);
}
}
/**
* checks if entity would cause the player to suffocate when sitting
* @param entity the entity
* @return true if there is no obstruction
*/
public static boolean checkPlayerSitAbility(DisplayEntity.TextDisplayEntity entity) {
// get the entity's block pos
BlockPos pos = Utl.Entity.getBlockPos(entity);
// get the poses to check above the block
2024-11-16 15:26:55 -06:00
BlockPos pos1 = new BlockPos(pos).add(0,1,0), pos2 = new BlockPos(pos).add(0,2,0), posBelow = new BlockPos(pos);
2024-07-11 13:43:54 -05:00
// doesn't check 2 blocks above if not sitting above .80 of the block
if (pos.getY() > (entity.getY()-Utl.Entity.Y_ADJUSTMENT) - .80) {
2024-11-16 15:26:55 -06:00
pos2 = pos2.add(0,-1,0);
posBelow = posBelow.add(0,-1,0);
}
2024-07-11 13:43:54 -05:00
// check if both poses are obstructed or not
2024-11-15 12:47:21 -06:00
return Utl.isNotObstructed(entity.getWorld(),pos1) && Utl.isNotObstructed(entity.getWorld(),pos2)
2024-11-16 15:26:55 -06:00
// also check if occupied, checking below to make sure you cant sit directly on top of another sit entity
&& Utl.isNotOccupied(pos) && Utl.isNotOccupied(pos1) && Utl.isNotOccupied(pos2) && Utl.isNotOccupied(posBelow);
2024-07-11 13:43:54 -05:00
}
/**
* reloads the config files
*/
public static void reload() {
FileData.loadFiles();
2024-12-02 12:52:02 -06:00
FileData.saveFiles();
2024-07-11 13:43:54 -05:00
}
/**
* toggles the sit ablity config option
* @return returns a message, that can be sent to the player
*/
public static MutableText toggleSiting() {
if (Data.isSupportedServer()) {
// get the sitting config
SittingConfig config = FileData.getSittingConfig();
// toggle the setting
config.setEnabled(!config.getEnabled());
// set the sitting config to the new value
FileData.setSittingConfig(config);
// save the changes to the file
config.save();
// send the changes to the server
Utl.sendSettingsPackets();
// get the message settings
String messageKey = "sit!.chat.toggle_sit."+(config.getEnabled()?"on":"off");
Formatting messageColor = config.getEnabled()?Formatting.GREEN:Formatting.RED;
// send the player the actionbar message
2025-06-16 20:36:32 -05:00
return Chat.lang("sit!.chat.toggle_sit",
Chat.lang(messageKey).color(config.getEnabled()? Color.GREEN : Color.RED)).b();
} else {
// unsupported server message if not in a Sit! server
2025-06-16 20:36:32 -05:00
return Chat.lang("sit!.chat.unsupported")
2025-05-03 15:41:16 -05:00
.color(Color.RED).b();
}
}
2024-07-11 13:43:54 -05:00
}