Skip to content

Commit

Permalink
add: SitModule
Browse files Browse the repository at this point in the history
  • Loading branch information
sakurawald committed Jun 4, 2024
1 parent b987d54 commit 36fdb1c
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 4 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ provides `/anvil` command.
#### BedModule
provides `/bed` command.

#### SitModule
provides `/sit` command and sit interact.

</details>

# Config
Expand Down Expand Up @@ -333,3 +336,4 @@ At the early stage of this project, we reference some source and ideas from the
3. https://modrinth.com/mod/essential-commands
4. https://modrinth.com/mod/skinrestorer
5. https://modrinth.com/mod/headindex
6. https://modrinth.com/mod/sit
14 changes: 14 additions & 0 deletions src/main/java/io/github/sakurawald/config/model/ConfigModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -512,9 +512,23 @@ public class StoneCutter {
}

public Bed bed = new Bed();

public class Bed {

public boolean enable = false;
}

public Sit sit = new Sit();

public class Sit {

public boolean enable = false;
public boolean allow_right_click_sit = true;
public int max_distance_to_sit = -1;
public boolean must_be_stairs = true;
public boolean required_empty_hand = false;
public boolean allow_sneaking = false;
public boolean no_opaque_block_above = false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

public abstract class ModuleInitializer {

public void initialize() {
public final void initialize() {
CommandRegistrationCallback.EVENT.register(this::registerCommand);
this.onInitialize();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,97 @@
import com.mojang.brigadier.context.CommandContext;
import io.github.sakurawald.module.initializer.ModuleInitializer;
import io.github.sakurawald.util.CommandUtil;
import io.github.sakurawald.util.MessageUtil;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.minecraft.block.BlockState;
import net.minecraft.command.CommandRegistryAccess;
import net.minecraft.command.argument.EntityAnchorArgumentType;
import net.minecraft.entity.Entity;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;

import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.Set;

public class SitModule extends ModuleInitializer {

public final Set<Entity> CHAIRS = new HashSet<>();

@Override
public void registerCommand(CommandDispatcher<ServerCommandSource> dispatcher, CommandRegistryAccess registryAccess, CommandManager.RegistrationEnvironment environment) {
dispatcher.register(CommandManager.literal("sit").executes(this::$sit));
}

@Override
public void onInitialize() {
ServerLifecycleEvents.SERVER_STOPPING.register((server) -> {
CHAIRS.forEach(e -> {
if (e.isAlive()) e.kill();
});
});
}

private int $sit(CommandContext<ServerCommandSource> ctx) {
return CommandUtil.playerOnlyCommand(ctx, (player) -> {

BlockState blockState = player.getEntityWorld().getBlockState(new BlockPos(player.getBlockX(), player.getBlockY() - 1, player.getBlockZ()));
if (player.hasVehicle() || player.isFallFlying() || player.isSleeping() || player.isSwimming() || player.isSpectator() || blockState.isAir() || blockState.isLiquid())
return 0;



Entity entity = createChair(player.getEntityWorld(), player.getBlockPos(), new Vec3d(0, -1.7, 0), player.getPos(), false);
CHAIRS.add(entity);
player.startRiding(entity, true);

return Command.SINGLE_SUCCESS;
});
}

public Entity createChair(World world, BlockPos blockPos, Vec3d blockPosOffset, @Nullable Vec3d target, boolean boundToBlock) {
ArmorStandEntity entity = new ArmorStandEntity(world, 0.5d + blockPos.getX() + blockPosOffset.getX(), blockPos.getY() + blockPosOffset.getY(), 0.5d + blockPos.getZ() + blockPosOffset.getZ()) {
private boolean v = false;

@Override
protected void addPassenger(Entity passenger) {
super.addPassenger(passenger);
v = true;
}

@Override
public boolean canMoveVoluntarily() {
return false;
}

@Override
public boolean collidesWithStateAtPos(BlockPos blockPos, BlockState blockState) {
return false;
}

@Override
public void tick() {
if (v && getPassengerList().isEmpty()) {
kill();
}

if (getEntityWorld().getBlockState(getBlockPos()).isAir() && boundToBlock) {
kill();
}
super.tick();
}

};

if (target != null)
entity.lookAt(EntityAnchorArgumentType.EntityAnchor.EYES, target.subtract(0, (target.getY() * 2), 0));
entity.setInvisible(true);
entity.setInvulnerable(true);
entity.setCustomName(Text.literal("FUJI-SIT"));
entity.setNoGravity(true);
world.spawnEntity(entity);
return entity;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package io.github.sakurawald.module.mixin.sit;

import io.github.sakurawald.config.Configs;
import io.github.sakurawald.module.ModuleManager;
import io.github.sakurawald.module.initializer.sit.SitModule;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.SideShapeType;
import net.minecraft.block.StairsBlock;
import net.minecraft.block.enums.StairShape;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.network.ServerPlayerInteractionManager;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.GameMode;
import net.minecraft.world.World;
import org.joml.Vector3f;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

/**
* Copyright 2021 BradBot_1
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@Mixin(ServerPlayerInteractionManager.class)
public class InteractModifierMixin {

@Unique
private static final SitModule module = ModuleManager.getInitializer(SitModule.class);

@Final
@Shadow
protected ServerPlayerEntity player;

@Inject(method = "interactBlock(Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/world/World;Lnet/minecraft/item/ItemStack;Lnet/minecraft/util/Hand;Lnet/minecraft/util/hit/BlockHitResult;)Lnet/minecraft/util/ActionResult;", at = @At("HEAD"), cancellable = true)
public void inject(ServerPlayerEntity player, World world, ItemStack stack, Hand hand, BlockHitResult hitResult, CallbackInfoReturnable<ActionResult> callbackInfoReturnable) {
var config = Configs.configHandler.model().modules.sit;

if (!config.allow_right_click_sit) return;

if (!config.allow_sneaking && player.isSneaking()) return;

if (player.hasVehicle() || player.isFallFlying() || player.isSleeping() || player.isSwimming() || player.isSpectator()) return;

if ((config.required_empty_hand && !player.getInventory().getMainHandStack().isEmpty())) return;

BlockPos blockPos = hitResult.getBlockPos();
BlockState blockState = world.getBlockState(blockPos);
Block block = blockState.getBlock();

if (config.no_opaque_block_above && world.getBlockState(blockPos.add(0, 1, 0)).isOpaque()) return;

if (config.must_be_stairs && (!(block instanceof StairsBlock))) return;

if (blockState.isSideSolid(world, blockPos, Direction.UP, SideShapeType.RIGID)) return;

final double reqDist = config.max_distance_to_sit;
double givenDist = blockPos.getSquaredDistance(player.getBlockPos());
if (reqDist > 0 && (givenDist > (reqDist * reqDist))) return;

Vec3d lookTarget;
if (block instanceof StairsBlock) {
Direction direction = blockState.get(StairsBlock.FACING);
Vector3f offset = direction.getUnitVector();
StairShape stairShape = blockState.get(StairsBlock.SHAPE);
if (stairShape == StairShape.OUTER_RIGHT || stairShape == StairShape.INNER_RIGHT)
offset.add(direction.rotateYClockwise().getUnitVector());
if (stairShape == StairShape.OUTER_LEFT || stairShape == StairShape.INNER_LEFT)
offset.add(direction.rotateYCounterclockwise().getUnitVector());
lookTarget = new Vec3d(blockPos.getX() + 0.5 - offset.x(), blockPos.getY(), blockPos.getZ() + 0.5 - offset.z());
} else {
lookTarget = player.getPos();
}
Entity chair = module.createChair(world, blockPos, new Vec3d(0, -1.7, 0), lookTarget, true);

Entity v = player.getVehicle();
if (v != null) {
player.setSneaking(true);
player.tickRiding();
}
player.startRiding(chair, true);

callbackInfoReturnable.setReturnValue(ActionResult.success(true));
callbackInfoReturnable.cancel();
}

@Inject(method = "setGameMode(Lnet/minecraft/world/GameMode;Lnet/minecraft/world/GameMode;)V", at = @At("HEAD"))
public void inject(GameMode gameMode, GameMode previousGameMode, CallbackInfo callbackInfo) {
if (gameMode == GameMode.SPECTATOR && previousGameMode != GameMode.SPECTATOR && player.getVehicle() != null) {
player.setSneaking(true);
player.tickRiding();
}
}

}
1 change: 1 addition & 0 deletions src/main/resources/fuji.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"resource_world.registry.SimpleRegistryMixin",
"seen.GameProfileCacheMixin",
"seen.PlayerListMixin",
"sit.InteractModifierMixin",
"skin.PlayerListMixin",
"skin.ServerLoginNetworkHandlerMixin",
"stronger_player_list.PlayerListMixin",
Expand Down

0 comments on commit 36fdb1c

Please sign in to comment.