Skip to content

Commit

Permalink
...
Browse files Browse the repository at this point in the history
  • Loading branch information
qouteall committed Mar 19, 2023
1 parent 480301f commit 9a030e7
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 37 deletions.
139 changes: 138 additions & 1 deletion src/main/java/tk/meowmc/portalgun/PortalGunMod.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package tk.meowmc.portalgun;

import com.google.common.collect.Lists;
import com.mojang.datafixers.util.Pair;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
Expand All @@ -10,18 +12,34 @@
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.CreativeModeTabs;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Rarity;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import qouteall.imm_ptl.core.portal.Portal;
import qouteall.imm_ptl.core.portal.PortalManipulation;
import qouteall.q_misc_util.my_util.IntBox;
import tk.meowmc.portalgun.config.PortalGunConfig;
import tk.meowmc.portalgun.entities.CustomPortal;
import tk.meowmc.portalgun.items.ClawItem;
import tk.meowmc.portalgun.items.PortalGunItem;

import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class PortalGunMod implements ModInitializer {
public static final String MODID = "portalgun";
public static final String KEY = MODID + ":portalgun_portals";
Expand Down Expand Up @@ -57,6 +75,125 @@ public static boolean isBlockSolid(Level world, BlockPos p) {
return world.getBlockState(p).isSolidRender(world, p);
}

public static boolean isAreaClear(Level world, IntBox airBox1) {
return airBox1.fastStream().allMatch(p -> world.getBlockState(p).isAir());
}

public static boolean isWallValid(Level world, IntBox wallBox1) {
return wallBox1.fastStream().allMatch(p -> isBlockSolid(world, p));
}

public static record PortalAwareRaytraceResult(
Level world,
BlockHitResult hitResult,
List<Portal> portalsPassingThrough
) {}

// TODO move this into ImmPtl
@Nullable
public static PortalAwareRaytraceResult portalAwareRayTrace(
Entity entity, double maxDistance
) {
return portalAwareRayTrace(
entity.level,
entity.getEyePosition(),
entity.getViewVector(1),
maxDistance,
entity
);
}

@Nullable
public static PortalAwareRaytraceResult portalAwareRayTrace(
Level world,
Vec3 startingPoint,
Vec3 direction,
double maxDistance,
Entity entity
) {
return portalAwareRayTrace(world, startingPoint, direction, maxDistance, entity, List.of());
}

@Nullable
public static PortalAwareRaytraceResult portalAwareRayTrace(
Level world,
Vec3 startingPoint,
Vec3 direction,
double maxDistance,
Entity entity,
@NotNull List<Portal> portalsPassingThrough
) {
if (portalsPassingThrough.size() > 5) {
return null;
}

Vec3 endingPoint = startingPoint.add(direction.scale(maxDistance));
Optional<Pair<Portal, Vec3>> portalHit = PortalManipulation.raytracePortals(
world, startingPoint, endingPoint, true
);

ClipContext context = new ClipContext(
startingPoint,
endingPoint,
ClipContext.Block.OUTLINE,
ClipContext.Fluid.NONE,
entity
);
BlockHitResult blockHitResult = world.clip(context);

boolean portalHitFound = portalHit.isPresent();
boolean blockHitFound = blockHitResult.getType() == HitResult.Type.BLOCK;

boolean shouldContinueRaytraceInsidePortal = false;
if (portalHitFound && blockHitFound) {
double portalDistance = portalHit.get().getSecond().distanceTo(startingPoint);
double blockDistance = blockHitResult.getLocation().distanceTo(startingPoint);
if (portalDistance < blockDistance) {
// continue raytrace from within the portal
shouldContinueRaytraceInsidePortal = true;
}
else {
return new PortalAwareRaytraceResult(
world, blockHitResult, portalsPassingThrough
);
}
}
else if (!portalHitFound && blockHitFound) {
return new PortalAwareRaytraceResult(
world, blockHitResult, portalsPassingThrough
);
}
else if (portalHitFound && !blockHitFound) {
// continue raytrace from within the portal
shouldContinueRaytraceInsidePortal = true;
}

if (shouldContinueRaytraceInsidePortal) {
double portalDistance = portalHit.get().getSecond().distanceTo(startingPoint);
Portal portal = portalHit.get().getFirst();
Vec3 newStartingPoint = portal.transformPoint(portalHit.get().getSecond())
.add(portal.getContentDirection().scale(0.001));
Vec3 newDirection = portal.transformLocalVecNonScale(direction);
double restDistance = maxDistance - portalDistance;
if (restDistance < 0) {
return null;
}
return portalAwareRayTrace(
portal.getDestinationWorld(),
newStartingPoint,
newDirection,
restDistance,
entity,
Stream.concat(
portalsPassingThrough.stream(), Stream.of(portal)
).collect(Collectors.toList())
);
}
else {
return null;
}
}

@Override
public void onInitialize() {
Registry.register(BuiltInRegistries.ITEM, id("portal_gun"), PORTAL_GUN);
Expand All @@ -80,7 +217,7 @@ public void onInitialize() {
}
return InteractionResult.PASS;
});

// add into creative inventory
ItemGroupEvents.modifyEntriesEvent(CreativeModeTabs.TOOLS_AND_UTILITIES).register(entries -> {
entries.accept(PORTAL_GUN);
Expand Down
11 changes: 1 addition & 10 deletions src/main/java/tk/meowmc/portalgun/entities/CustomPortal.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.level.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -92,7 +91,7 @@ void updateState() {
return;
}
// check block status
if (!isWallValid(level, wallBox) || !isAreaClear(level, airBox)) {
if (!PortalGunMod.isWallValid(level, wallBox) || !PortalGunMod.isAreaClear(level, airBox)) {
kill();
record.data.remove(descriptor);
record.setDirty();
Expand Down Expand Up @@ -138,12 +137,4 @@ void updateState() {
}
}

public static boolean isAreaClear(Level world, IntBox airBox1) {
return airBox1.fastStream().allMatch(p -> world.getBlockState(p).isAir());
}

public static boolean isWallValid(Level world, IntBox wallBox1) {
return wallBox1.fastStream().allMatch(p -> PortalGunMod.isBlockSolid(world, p));
}

}
Loading

0 comments on commit 9a030e7

Please sign in to comment.