Skip to content

Commit

Permalink
teleport mobs to ships when loading back in (#1014)
Browse files Browse the repository at this point in the history
add config for saveMobPositionOnShip

move mixins and use entity dragging info for saving position

create logic for Mobs to save their position relative to a ship when unloading, then teleport back to ship when loading back in
  • Loading branch information
jamesgreen26 authored and Rubydesic committed Dec 17, 2024
1 parent 4b5e30e commit 289933e
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 4 deletions.
4 changes: 0 additions & 4 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package org.valkyrienskies.mod.mixin.feature.save_mob_location_on_ship;

import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Mob;
import org.joml.Vector3d;
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.valkyrienskies.core.api.ships.Ship;
import org.valkyrienskies.mod.common.VSGameUtilsKt;
import org.valkyrienskies.mod.common.config.VSGameConfig;
import org.valkyrienskies.mod.common.entity.ShipyardPosSavable;
import org.valkyrienskies.mod.common.util.EntityDraggingInformation;
import org.valkyrienskies.mod.common.util.IEntityDraggingInformationProvider;
import org.valkyrienskies.mod.common.util.VectorConversionsMCKt;

@Mixin(ChunkMap.class)
public class MixinChunkMap {

@Shadow
@Final
ServerLevel level;

/**
* Save mob's shipyard position when it gets unloaded
*
* @author G_Mungus
*/

@Inject(method = "removeEntity", at = @At("HEAD"))
protected void unloadEntityMixin(Entity entity, CallbackInfo info) {
if (entity instanceof Mob mob) {
Vector3d shipyardPos = valkyrienskies$getShipyardPos(mob);
if (shipyardPos != null &&
VSGameUtilsKt.getShipManagingPos(this.level, shipyardPos) != null &&
((ShipyardPosSavable)mob).valkyrienskies$getUnloadedShipyardPos() == null) {
((ShipyardPosSavable)mob).valkyrienskies$setUnloadedShipyardPos(shipyardPos);
}
}
}

/**
* Teleport mob to correct position on ship when loaded back in
*
* @author G_Mungus
*/

@Inject(method = "addEntity", at = @At("RETURN"))
protected void loadEntityMixin(Entity entity, CallbackInfo info) {
if (entity instanceof Mob mob) {
Vector3d shipyardPos = ((ShipyardPosSavable)mob).valkyrienskies$getUnloadedShipyardPos();
if(shipyardPos != null) {
if (VSGameConfig.SERVER.getSaveMobsPositionOnShip()){
mob.teleportTo(shipyardPos.x, shipyardPos.y, shipyardPos.z);
}
((ShipyardPosSavable) mob).valkyrienskies$setUnloadedShipyardPos(null);
}
}
}


/**
* Helper method to get shipyard pos of mob on a ship
*
* @author G_Mungus
*/
@Unique
private Vector3d valkyrienskies$getShipyardPos(Entity entity) {
EntityDraggingInformation dragInfo = ((IEntityDraggingInformationProvider) entity).getDraggingInformation();

if (dragInfo.getLastShipStoodOn() != null) {
Ship ship = VSGameUtilsKt.getAllShips(this.level).getById(dragInfo.getLastShipStoodOn());
if (ship != null && ship.getWorldAABB().containsPoint(VectorConversionsMCKt.toJOML(entity.position()))) {
return ship.getWorldToShip().transformPosition(VectorConversionsMCKt.toJOML(entity.position()));
}
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package org.valkyrienskies.mod.mixin.feature.save_mob_location_on_ship;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.Mob;
import org.joml.Vector3d;
import org.spongepowered.asm.mixin.Mixin;
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.valkyrienskies.mod.common.config.VSGameConfig;
import org.valkyrienskies.mod.common.entity.ShipyardPosSavable;

@Mixin(Mob.class)
public class MixinMob implements ShipyardPosSavable {

@Unique
public Vector3d valkyrienskies$unloadedShipyardPos = null;

@Override
public Vector3d valkyrienskies$getUnloadedShipyardPos() {
return valkyrienskies$unloadedShipyardPos;
}

@Override
public void valkyrienskies$setUnloadedShipyardPos(Vector3d vector3d) {
this.valkyrienskies$unloadedShipyardPos = vector3d;
}


/**
* Save mob's shipyard position to nbt, or clear it if null
*
* @author G_Mungus
*/
@Inject(method = "addAdditionalSaveData", at = @At("RETURN"))
public void addAdditionalSaveDataMixin(CompoundTag nbt, CallbackInfo info) {
Vector3d position = this.valkyrienskies$getUnloadedShipyardPos();
if (position != null && VSGameConfig.SERVER.getSaveMobsPositionOnShip()) {
nbt.putDouble("valkyrienskies$unloadedX",position.x);
nbt.putDouble("valkyrienskies$unloadedY",position.y);
nbt.putDouble("valkyrienskies$unloadedZ", position.z);
} else {
nbt.remove("valkyrienskies$unloadedX");
nbt.remove("valkyrienskies$unloadedY");
nbt.remove("valkyrienskies$unloadedZ");
}
}


/**
* Read mob's shipyard position from nbt
*
* @author G_Mungus
*/
@Inject(method = "readAdditionalSaveData", at = @At("RETURN"))
public void readAdditionalSaveData(CompoundTag nbt, CallbackInfo info) {
if (nbt.contains("valkyrienskies$unloadedX") && nbt.contains("valkyrienskies$unloadedY") && nbt.contains("valkyrienskies$unloadedZ")) {
double[] xyz = {nbt.getDouble("valkyrienskies$unloadedX"), nbt.getDouble("valkyrienskies$unloadedY"), nbt.getDouble("valkyrienskies$unloadedZ")};
this.valkyrienskies$setUnloadedShipyardPos(new Vector3d(xyz));
}
}



}

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
When a mob on a ship gets unloaded, these mixins save the mobs shipyard position, then teleport the mob to the shipyard position when the mob loads back in. This prevents mobs from falling off ships due to being unloaded while the ship is moving.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.valkyrienskies.mod.common.VSGameUtilsKt;
import org.valkyrienskies.mod.common.util.MinecraftPlayer;


@Mixin(ChunkMap.class)
public abstract class MixinChunkMap {

Expand Down Expand Up @@ -102,4 +103,5 @@ private void postGetPlayersWatchingChunk(final ChunkPos chunkPos, final boolean
cir.setReturnValue(new ArrayList<>(watchingPlayers));
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ object VSGameConfig {
)
var maxAirborneTicksForReconnectedPlayerTeleport = 4

@JsonSchema(
description = "If true, when a mob gets unloaded, its position on a ship is saved such that " +
"if the ship is moved, when the mob loads back in it will be teleported to the same position in the ship." +
" This helps prevent mobs from falling off of ships."
)
var saveMobsPositionOnShip = true

@JsonSchema(
description = "If true, prevents water and other fluids from flowing out of the ship's bounding box."
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.valkyrienskies.mod.common.entity

import org.joml.Vector3d

interface ShipyardPosSavable {
fun `valkyrienskies$getUnloadedShipyardPos`(): Vector3d?
fun `valkyrienskies$setUnloadedShipyardPos`(vector3d: Vector3d?)
}
2 changes: 2 additions & 0 deletions common/src/main/resources/valkyrienskies-common.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
"feature.mass_tooltip.MixinBlockItem",
"feature.mob_spawning.NaturalSpawnerMixin",
"feature.render_pathfinding.MixinDebugPackets",
"feature.save_mob_location_on_ship.MixinChunkMap",
"feature.save_mob_location_on_ship.MixinMob",
"feature.screen_distance_check.MixinScreenHandler",
"feature.shipyard_entities.MixinEntity",
"feature.shipyard_entities.MixinEntitySection",
Expand Down

0 comments on commit 289933e

Please sign in to comment.