Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/wings pt2 #324

Merged
merged 7 commits into from
Jan 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.valkyrienskies.core.api.ships.Ship;
import org.valkyrienskies.mod.common.VSGameUtilsKt;
import org.valkyrienskies.mod.common.entity.handling.VSEntityManager;

Expand Down Expand Up @@ -92,6 +93,15 @@ private Entity preventSavingVehiclePosAsOurPos(final Entity originalVehicle) {
}
}

@Inject(method = "setRemoved", at = @At("HEAD"))
private void preSetRemoved() {
final Entity thisAsEntity = Entity.class.cast(this);
final Ship ship = VSGameUtilsKt.getShipManaging(thisAsEntity);
if (ship != null) {
VSEntityManager.INSTANCE.getHandler(thisAsEntity).entityRemovedFromShipyard(thisAsEntity, ship);
}
}

@Shadow
protected abstract void positionRider(Entity passenger, Entity.MoveFunction callback);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.concurrent.Executor;
import java.util.function.BooleanSupplier;
import net.minecraft.core.BlockPos;
import net.minecraft.core.BlockPos.MutableBlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.Position;
import net.minecraft.resources.ResourceKey;
Expand All @@ -22,6 +23,7 @@
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.progress.ChunkProgressListener;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.LevelChunkSection;
Expand All @@ -38,10 +40,13 @@
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.valkyrienskies.core.api.ships.LoadedServerShip;
import org.valkyrienskies.core.api.ships.Wing;
import org.valkyrienskies.core.api.ships.WingManager;
import org.valkyrienskies.core.apigame.world.ServerShipWorldCore;
import org.valkyrienskies.core.apigame.world.chunks.TerrainUpdate;
import org.valkyrienskies.mod.common.IShipObjectWorldServerProvider;
import org.valkyrienskies.mod.common.VSGameUtilsKt;
import org.valkyrienskies.mod.common.block.WingBlock;
import org.valkyrienskies.mod.common.util.VectorConversionsMCKt;
import org.valkyrienskies.mod.mixin.accessors.server.world.ChunkMapAccessor;

Expand Down Expand Up @@ -143,6 +148,34 @@ private void postTick(final BooleanSupplier shouldKeepTicking, final CallbackInf
final TerrainUpdate voxelShapeUpdate =
VSGameUtilsKt.toDenseVoxelUpdate(chunkSection, chunkPos);
voxelShapeUpdates.add(voxelShapeUpdate);

// region Detect wings
final ServerLevel thisAsLevel = ServerLevel.class.cast(this);
final LoadedServerShip
ship = VSGameUtilsKt.getShipObjectManagingPos(thisAsLevel, chunkX, chunkZ);
if (ship != null) {
// Sussy cast, but I don't want to expose this directly through the vs-core api
final WingManager shipAsWingManager = ship.getAttachment(WingManager.class);
final MutableBlockPos mutableBlockPos = new MutableBlockPos();
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
final BlockState blockState = chunkSection.getBlockState(x, y, z);
final int posX = (chunkX << 4) + x;
final int posY = chunkSection.bottomBlockY() + y;
final int posZ = (chunkZ << 4) + z;
if (blockState.getBlock() instanceof WingBlock) {
mutableBlockPos.set(posX, posY, posZ);
final Wing wing =
((WingBlock) blockState.getBlock()).getWing(thisAsLevel,
mutableBlockPos, blockState);
shipAsWingManager.setWing(shipAsWingManager.getFirstWingGroupId(), posX, posY, posZ, wing);
}
}
}
}
}
// endregion
} else {
final TerrainUpdate emptyVoxelShapeUpdate = getVsCore()
.newEmptyVoxelShapeUpdate(chunkPos.x(), chunkPos.y(), chunkPos.z(), true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ import net.minecraft.core.MappedRegistry
import net.minecraft.core.Registry
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerLevel
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.state.BlockState
import org.valkyrienskies.core.api.ships.Wing
import org.valkyrienskies.core.api.ships.WingManager
import org.valkyrienskies.core.apigame.world.chunks.BlockType
import org.valkyrienskies.mod.common.block.WingBlock
import org.valkyrienskies.mod.common.config.MassDatapackResolver
import org.valkyrienskies.mod.event.RegistryEvents

Expand Down Expand Up @@ -89,6 +93,27 @@ object BlockStateInfo {

val (newBlockMass, newBlockType) = get(newBlockState) ?: return

// region Inject wings
if (level is ServerLevel) {
val loadedShip = level.getShipObjectManagingPos(x shr 4, z shr 4)
if (loadedShip != null) {
val wingManager = loadedShip.getAttachment(WingManager::class.java)!!
val wasOldBlockWing = prevBlockState is WingBlock
val newWing: Wing? =
if (newBlockState is WingBlock) newBlockState.getWing(
level, BlockPos(x, y, z), newBlockState
) else null
if (newWing != null) {
// Place the new wing
wingManager.setWing(wingManager.getFirstWingGroupId(), x, y, z, newWing)
} else if (wasOldBlockWing) {
// Delete the old wing
wingManager.setWing(wingManager.getFirstWingGroupId(), x, y, z, null)
}
}
}
// endregion

shipObjectWorld.onSetBlock(
x, y, z, level.dimensionId, prevBlockType, newBlockType, prevBlockMass,
newBlockMass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ object ValkyrienSkiesMod {

lateinit var TEST_CHAIR: Block
lateinit var TEST_HINGE: Block
lateinit var TEST_WING: Block
lateinit var SHIP_CREATOR_ITEM: Item
lateinit var SHIP_ASSEMBLER_ITEM: Item
lateinit var SHIP_CREATOR_ITEM_SMALLER: Item
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package org.valkyrienskies.mod.common.block

import net.minecraft.core.BlockPos
import net.minecraft.core.Direction.DOWN
import net.minecraft.core.Direction.EAST
import net.minecraft.core.Direction.NORTH
import net.minecraft.core.Direction.SOUTH
import net.minecraft.core.Direction.UP
import net.minecraft.core.Direction.WEST
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.DirectionalBlock
import net.minecraft.world.level.block.SoundType
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.level.material.Material
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape
import org.valkyrienskies.core.api.ships.Wing
import org.valkyrienskies.mod.common.util.toJOMLD

object TestWingBlock :
DirectionalBlock(
Properties.of(Material.METAL).strength(10.0f, 1200.0f).sound(SoundType.METAL)
), WingBlock {

private val EAST_AABB = box(4.0, 0.0, 0.0, 12.0, 16.0, 16.0)
private val WEST_AABB = box(4.0, 0.0, 0.0, 12.0, 16.0, 16.0)
private val SOUTH_AABB = box(0.0, 0.0, 4.0, 16.0, 16.0, 12.0)
private val NORTH_AABB = box(0.0, 0.0, 4.0, 16.0, 16.0, 12.0)
private val UP_AABB = box(0.0, 4.0, 0.0, 16.0, 12.0, 16.0)
private val DOWN_AABB = box(0.0, 4.0, 0.0, 16.0, 12.0, 16.0)

init {
registerDefaultState(this.stateDefinition.any().setValue(FACING, UP))
}

override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
builder.add(FACING)
}

override fun getStateForPlacement(ctx: BlockPlaceContext): BlockState {
return defaultBlockState().setValue(FACING, ctx.nearestLookingDirection.opposite)
}

@Deprecated("Deprecated in Java")
override fun getShape(
state: BlockState, blockGetter: BlockGetter, blockPos: BlockPos, collisionContext: CollisionContext
): VoxelShape {
when (state.getValue(FACING)) {
DOWN -> {
return DOWN_AABB
}
NORTH -> {
return NORTH_AABB
}
SOUTH -> {
return SOUTH_AABB
}
WEST -> {
return WEST_AABB
}
EAST -> {
return EAST_AABB
}
UP -> {
return UP_AABB
}
else -> {
// This should be impossible, but have this here just in case
return UP_AABB
}
}
}

override fun getWing(level: Level, pos: BlockPos, blockState: BlockState): Wing {
val wingPower = 150.0
val wingDrag = 150.0
val wingBreakingForce = null
return Wing(blockState.getValue(FACING).normal.toJOMLD(), wingPower, wingDrag, wingBreakingForce)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.valkyrienskies.mod.common.block

import net.minecraft.core.BlockPos
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.state.BlockState
import org.valkyrienskies.core.api.ships.Wing

interface WingBlock {
fun getWing(level: Level, pos: BlockPos, blockState: BlockState): Wing
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ import org.valkyrienskies.core.api.ships.Ship
import org.valkyrienskies.mod.common.util.toJOML
import org.valkyrienskies.mod.common.util.toMinecraft

object ShipyardEntityHandler : VSEntityHandler {
abstract class AbstractShipyardEntityHandler : VSEntityHandler {
override fun freshEntityInShipyard(entity: Entity, ship: Ship) {
// do nothing
}

override fun entityRemovedFromShipyard(entity: Entity, ship: Ship) {
// do nothing
}

override fun <T : Entity> applyRenderTransform(
ship: ClientShip, entity: T, entityRenderer: EntityRenderer<T>, x: Double, y: Double, z: Double,
rotationYaw: Float, partialTicks: Float, matrixStack: PoseStack, buffer: MultiBufferSource, packedLight: Int
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package org.valkyrienskies.mod.common.entity.handling

object DefaultShipyardEntityHandler : AbstractShipyardEntityHandler()
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ interface VSEntityHandler {
*/
fun freshEntityInShipyard(entity: Entity, ship: Ship)

fun entityRemovedFromShipyard(entity: Entity, ship: Ship)

/**
* ApplyRenderTransform
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ object VSEntityManager {
private val namedEntityHandlers = HashMap<VSEntityHandler, ResourceLocation>()
private val entityHandlers = HashMap<EntityType<*>, VSEntityHandler>()
private val default = WorldEntityHandler
private var contraptionHandler: VSEntityHandler = DefaultShipyardEntityHandler

init {
register(ResourceLocation(ValkyrienSkiesMod.MOD_ID, "shipyard"), ShipyardEntityHandler)
register(ResourceLocation(ValkyrienSkiesMod.MOD_ID, "shipyard"), DefaultShipyardEntityHandler)
register(ResourceLocation(ValkyrienSkiesMod.MOD_ID, "default"), WorldEntityHandler)
}

Expand All @@ -33,6 +34,10 @@ object VSEntityManager {
namedEntityHandlers[entityHandler] = name
}

fun registerContraptionHandler(contraptionHandler: VSEntityHandler) {
this.contraptionHandler = contraptionHandler
}

/**
* Pair the entity type with the entity handler
* Should be preferably configured via datapacks
Expand All @@ -50,7 +55,7 @@ object VSEntityManager {

private fun getDefaultHandler(entity: Entity): VSEntityHandler {
if (CreateCompat.isContraption(entity)) {
return ShipyardEntityHandler
return contraptionHandler
}

return default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ object WorldEntityHandler : VSEntityHandler {
moveEntityFromShipyardToWorld(entity, ship)
}

override fun entityRemovedFromShipyard(entity: Entity, ship: Ship) {
// Do nothing
}

override fun <T : Entity> applyRenderTransform(
ship: ClientShip, entity: T, entityRenderer: EntityRenderer<T>,
x: Double, y: Double, z: Double,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"variants": {
"facing=north": {
"model": "valkyrienskies:block/test_wing",
"y": 180
},
"facing=east": {
"model": "valkyrienskies:block/test_wing",
"y": 270
},
"facing=south": {
"model": "valkyrienskies:block/test_wing",
"y": 0
},
"facing=west": {
"model": "valkyrienskies:block/test_wing",
"y": 90
},
"facing=up": {
"model": "valkyrienskies:block/test_wing",
"x": 90
},
"facing=down": {
"model": "valkyrienskies:block/test_wing",
"x": 270
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"category.valkyrienskies.driving": "Driving",
"block.valkyrienskies.test_chair": "Debug Chair",
"block.valkyrienskies.test_hinge": "Debug Hinge",
"block.valkyrienskies.test_wing": "Debug Wing",
"item.valkyrienskies.ship_creator": "Ship Creator",
"item.valkyrienskies.ship_creator_smaller": "Mini Ship Creator"
}
Loading