use of org.valkyrienskies.mod.common.ships.QueryableShipData in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.
the class MixinChunk method pre_setBlockState.
/**
* If this chunk is part of a ship, then tell that ship about the IBlockState update.
*
* Note that we're assuming that a Chunk cannot deny the setBlockState request. Therefore its safe to assume that
* the parameter "state" will be the final IBlockState of BlockPos "pos".
*/
@Inject(method = "setBlockState", at = @At("HEAD"))
private void pre_setBlockState(BlockPos pos, IBlockState state, CallbackInfoReturnable<IBlockState> cir) {
if (!world.isRemote) {
IBlockState oldState = getBlockState(pos);
QueryableShipData queryableShipData = QueryableShipData.get(world);
Optional<ShipData> shipDataOptional = queryableShipData.getShipFromChunk(pos.getX() >> 4, pos.getZ() >> 4);
shipDataOptional.ifPresent(shipData -> ShipDataMethods.onSetBlockState(shipData, pos, oldState, state));
}
}
use of org.valkyrienskies.mod.common.ships.QueryableShipData in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.
the class MixinNetHandlerPlayServer method preProcessPlayer.
/**
* This mixin fixes "Player Moved Wrongly" errors.
*
* @param packetPlayer The packet the player sent us
* @param info We can use this to cancel the invocation
*/
@Inject(method = "processPlayer", at = @At("HEAD"))
private void preProcessPlayer(final CPacketPlayer packetPlayer, final CallbackInfo info) {
// Don't run any of this code on the network thread!
if (this.player.getServerWorld().isCallingFromMinecraftThread()) {
// This fixes players dying of fall damage when changing dimensions
if (this.player.isInvulnerableDimensionChange()) {
return;
}
final PlayerMovementData addedPlayerMovementData = IHasPlayerMovementData.class.cast(packetPlayer).getPlayerMovementData();
final World world = player.world;
final UUID lastTouchedShipId = addedPlayerMovementData.getLastTouchedShipId();
final int ticksSinceTouchedLastShip = addedPlayerMovementData.getTicksSinceTouchedLastShip();
if (ticksSinceTouchedLastShip > 40) {
// If the player hasn't touched the ship in over 40 ticks, then ignore its coordinates relative to that ship.
final IDraggable playerAsDraggable = IDraggable.class.cast(this.player);
playerAsDraggable.setEntityShipMovementData(playerAsDraggable.getEntityShipMovementData().withLastTouchedShip(null).withAddedLinearVelocity(new Vector3d()).withAddedYawVelocity(0).withTicksPartOfGround(addedPlayerMovementData.getTicksPartOfGround()).withTicksSinceTouchedShip(ticksSinceTouchedLastShip));
return;
}
final int ticksPartOfGround = addedPlayerMovementData.getTicksPartOfGround();
final Vector3d playerPosInShip = new Vector3d(addedPlayerMovementData.getPlayerPosInShip());
final Vector3d playerLookInShip = new Vector3d(addedPlayerMovementData.getPlayerLookInShip());
ShipData lastTouchedShip = null;
if (lastTouchedShipId != null) {
final QueryableShipData queryableShipData = QueryableShipData.get(world);
final Optional<ShipData> shipDataOptional = queryableShipData.getShip(lastTouchedShipId);
if (shipDataOptional.isPresent()) {
lastTouchedShip = shipDataOptional.get();
final PhysicsObject shipObject = ValkyrienUtils.getServerShipManager(world).getPhysObjectFromUUID(lastTouchedShip.getUuid());
if (shipObject != null) {
if (shipObject.getTicksSinceShipTeleport() > PhysicsObject.TICKS_SINCE_TELEPORT_TO_START_DRAGGING) {
final ShipTransform shipTransform = lastTouchedShip.getShipTransform();
shipTransform.transformPosition(playerPosInShip, TransformType.SUBSPACE_TO_GLOBAL);
shipTransform.transformDirection(playerLookInShip, TransformType.SUBSPACE_TO_GLOBAL);
} else {
// Don't move the player relative to the ship until the TicksSinceShipTeleport timer expires.
playerPosInShip.set(player.posX, player.posY, player.posZ);
}
}
} else {
// info.cancel();
return;
}
}
// Get the player pitch/yaw from the look vector
final Tuple<Double, Double> pitchYawTuple = VSMath.getPitchYawFromVector(playerLookInShip);
final double playerPitchInGlobal = pitchYawTuple.getFirst();
final double playerYawInGlobal = pitchYawTuple.getSecond();
// Idk if this is needed, but I'm too bothered to change it
packetPlayer.moving = true;
// Then update the packet values to match the ones above.
packetPlayer.x = playerPosInShip.x();
packetPlayer.y = playerPosInShip.y();
packetPlayer.z = playerPosInShip.z();
packetPlayer.yaw = (float) playerYawInGlobal;
packetPlayer.pitch = (float) playerPitchInGlobal;
// Set the player motion values to tell the NetHandlerPlayServer that the player is allowed to move this fast.
this.player.motionX = packetPlayer.x - this.firstGoodX;
this.player.motionY = packetPlayer.y - this.firstGoodY;
this.player.motionZ = packetPlayer.z - this.firstGoodZ;
// Update the player draggable
final IDraggable playerAsDraggable = IDraggable.class.cast(this.player);
playerAsDraggable.setEntityShipMovementData(playerAsDraggable.getEntityShipMovementData().withLastTouchedShip(lastTouchedShip).withAddedLinearVelocity(new Vector3d()).withAddedYawVelocity(0).withTicksPartOfGround(ticksPartOfGround).withTicksSinceTouchedShip(ticksSinceTouchedLastShip));
}
}
use of org.valkyrienskies.mod.common.ships.QueryableShipData in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.
the class MixinChunkSponge method onPreSpongeBridgeSetBlockState.
@Inject(method = "bridge$setBlockState", at = @At("HEAD"), remap = false)
private void onPreSpongeBridgeSetBlockState(BlockPos pos, IBlockState newState, IBlockState currentState, BlockChangeFlag flag, CallbackInfoReturnable<IBlockState> cir) {
if (!world.isRemote) {
QueryableShipData queryableShipData = QueryableShipData.get(world);
Optional<ShipData> shipDataOptional = queryableShipData.getShipFromChunk(pos.getX() >> 4, pos.getZ() >> 4);
shipDataOptional.ifPresent(shipData -> ShipDataMethods.onSetBlockState(shipData, pos, currentState, newState));
}
}
use of org.valkyrienskies.mod.common.ships.QueryableShipData in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.
the class WorldServerShipManager method getBackgroundShipChunks.
/**
* Used to prevent the world from unloading the chunks of ships loading in background.
*/
public Iterable<Long> getBackgroundShipChunks() throws CalledFromWrongThreadException {
enforceGameThread();
List<Long> backgroundChunks = new ArrayList<>();
QueryableShipData queryableShipData = QueryableShipData.get(world);
for (UUID shipID : loadingInBackground) {
Optional<ShipData> shipDataOptional = queryableShipData.getShip(shipID);
if (!shipDataOptional.isPresent()) {
throw new IllegalStateException("Ship data not present for:\n" + shipID);
}
backgroundChunks.addAll(shipDataOptional.get().getChunkClaim().getClaimedChunks());
}
return backgroundChunks;
}
use of org.valkyrienskies.mod.common.ships.QueryableShipData in project Valkyrien-Warfare-Revamped by ValkyrienWarfare.
the class WorldServerShipManager method loadAndUnloadShips.
private void loadAndUnloadShips() {
QueryableShipData queryableShipData = QueryableShipData.get(world);
// Load the ships that are required immediately.
for (final UUID toLoadID : loadQueue) {
Optional<ShipData> toLoadOptional = queryableShipData.getShip(toLoadID);
if (!toLoadOptional.isPresent()) {
throw new IllegalStateException("No ship found for ID:\n" + toLoadID);
}
ShipData toLoad = toLoadOptional.get();
if (loadedShips.containsKey(toLoadID)) {
throw new IllegalStateException("Tried loading a ShipData that was already loaded?\n" + toLoad);
}
// Remove this ship from the background loading set, if it is in it.
loadingInBackground.remove(toLoadID);
// Finally, load the ship.
if (VSConfig.showAnnoyingDebugOutput) {
System.out.println("Attempting to load ship " + toLoad);
}
PhysicsObject physicsObject = new PhysicsObject(world, toLoad);
PhysicsObject old = loadedShips.put(toLoad.getUuid(), physicsObject);
if (old != null) {
throw new IllegalStateException("How did we already have a ship loaded for " + toLoad);
}
}
loadQueue.clear();
// Load ships that aren't required immediately in the background.
for (final UUID toLoadID : backgroundLoadQueue) {
// Skip if this ship is already being loaded in the background,.
if (loadingInBackground.contains(toLoadID)) {
// Already loading this ship in the background
continue;
}
// Make sure there isn't an already loaded ship with this UUID.
if (loadedShips.containsKey(toLoadID)) {
// continue; // temp, need to fix WorldShipLoadingController.determineLoadAndUnload()
throw new IllegalStateException("Tried loading a ShipData that was already loaded? Ship ID is\n" + toLoadID);
}
// Then try getting the ShipData for this UUID.
Optional<ShipData> toLoadOptional = queryableShipData.getShip(toLoadID);
if (!toLoadOptional.isPresent()) {
throw new IllegalStateException("No ship found for ID:\n" + toLoadID);
}
ShipData toLoad = toLoadOptional.get();
loadingInBackground.add(toLoadID);
if (VSConfig.showAnnoyingDebugOutput) {
System.out.println("Attempting to load " + toLoad + " in the background.");
}
ChunkProviderServer chunkProviderServer = world.getChunkProvider();
for (ChunkPos chunkPos : toLoad.getChunkClaim()) {
@Nonnull Runnable returnTask = () -> {
if (VSConfig.showAnnoyingDebugOutput) {
System.out.println("Loaded ship chunk " + chunkPos);
}
};
chunkProviderServer.loadChunk(chunkPos.x, chunkPos.z, returnTask);
}
}
backgroundLoadQueue.clear();
// Unload far away ships immediately.
for (final UUID toUnloadID : unloadQueue) {
// Make sure we have a ship with this ID that can be unloaded
if (!loadedShips.containsKey(toUnloadID)) {
throw new IllegalStateException("Tried unloading a ShipData that isn't loaded? Ship ID is\n" + toUnloadID);
}
PhysicsObject physicsObject = getPhysObjectFromUUID(toUnloadID);
if (VSConfig.showAnnoyingDebugOutput) {
System.out.println("Attempting to unload " + physicsObject);
}
physicsObject.unload();
boolean success = loadedShips.remove(toUnloadID, physicsObject);
if (!success) {
throw new IllegalStateException("How did we fail to unload " + physicsObject.getShipData());
}
}
unloadQueue.clear();
}
Aggregations