Skip to content

Commit

Permalink
Merge pull request #466 from WaitingIdly/void-teleport
Browse files Browse the repository at this point in the history
Void Teleport features
  • Loading branch information
ACGaming authored May 12, 2024
2 parents 1502caf + 2c01aa2 commit 229101f
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ All changes are toggleable via config files.
* **Weaken Wither Structure Requirements:** Allows creating Withers with non-air blocks in the bottom corners of the structure
* **XP Bottle Amount:** Sets the amount of experience spawned by bottles o' enchanting
* **XP Level Cap:** Sets the maximum experience level players can reach
* **Void Teleport:**
* Options allow toggling the setting globally, controlling to what Y-level the entity is teleported, if blindness is applied, maximum number of consecutive times, and how much and in what way fall damage is taken
* **Configure Entities:** Configures what entities can be teleported, and if the player is teleported
* **Configure Dimensions:** Configures what dimensions the effect can take place in

![](https://i.imgur.com/1EmHZlb.png)

Expand Down
102 changes: 102 additions & 0 deletions src/main/java/mod/acgaming/universaltweaks/config/UTConfigTweaks.java
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,10 @@ public static class EntitiesCategory
@Config.Name("Water Fall Damage")
public final WaterFallDamageCategory WATER_FALL_DAMAGE = new WaterFallDamageCategory();

@Config.LangKey("cfg.universaltweaks.tweaks.entities.voidteleport")
@Config.Name("Void Teleport")
public final VoidTeleportCategory VOID_TELEPORT = new VoidTeleportCategory();

@Config.Name("Adaptive XP Drops")
@Config.Comment
({
Expand Down Expand Up @@ -890,6 +894,104 @@ public static class WaterFallDamageCategory
@Config.Comment("How much fall damage gets reduced by water per tick")
public double utFallDamageValue = 2.0D;
}

public static class VoidTeleportCategory
{
@Config.RequiresMcRestart
@Config.Name("[01] Void Teleport Toggle")
@Config.Comment("Enables Void Teleport, where falling out below a dimension will teleport you to the top of the dimension")
public boolean utVoidTeleportToggle = false;

@Config.Name("[02] Prevent Void Damage")
@Config.Comment
({
"Prevents taking a tick of void damage before being teleported",
"If this is false, entities will take 4 damage every time Void Teleport activates, preventing infinite looping"
})
public boolean utPreventVoidDamage = true;

@Config.Name("[03] Target Y-Level")
@Config.Comment
({
"Y-level to teleport the entity",
"If the target Y-level is lower than the highest block in that coordinate, will teleport the entity to the highest location instead"
})
public int utTargetYLevel = 300;

@Config.Name("[04] Apply Blindness on Teleport")
@Config.Comment("Applies the blindness effect for 3 seconds when teleporting")
public boolean utTeleportBlindness = true;

@Config.Name("[05] Clamp Falling Speed")
@Config.Comment("Prevents Y motion from being less than this")
public double utClampSpeedTo = -1;

@Config.Name("[06] Fall Distance Height")
@Config.Comment
({
"Height to override the fallDistance variable with when landing after having teleported",
"When set to less than 0, [07] Fall Damage Taken applies instead"
})
public float utFallHeight = -1;

@Config.Name("[07] Fall Damage Taken")
@Config.Comment
({
"Amount of fall damage taken when landing on a block",
"Negative numbers deal damage relative to the entity's max health",
"Only applies if [06] Fall Distance Height is less than 0"
})
public float utFallDamageTaken = -1;

@Config.Name("[08] Allow Fall Damage Taken to Kill")
@Config.Comment
({
"Sets if [07] Fall Damage Taken can kill entities",
"Does not apply to fall damage taken due to [06] Fall Distance Height"
})
public boolean utAllowSpecificFallDamageToKill = true;

@Config.Name("[09] Maximum Times to Teleport Consecutively")
@Config.Comment("Maximum number of times to teleport the entity without the entity landing before no longer teleporting. Used to prevent infinite loops")
public int utMaxCombo = 100;

@Config.Name("[10] Apply Void Teleport to Players")
@Config.Comment("Controls if players are teleported by Void Teleport")
public boolean utForgivePlayers = true;

@Config.Name("[11] Entity List")
@Config.Comment
({
"List of the resource location names for entities concerning Void Teleport",
"Behavior depends on the list mode"
})
public String[] utEntityList = new String[] {};

@Config.Name("[12] Entity List Mode")
@Config.Comment
({
"Blacklist Mode: Entities that won't be impacted by Void Teleport, others will",
"Whitelist Mode: Entities that will be impacted by Void Teleport, others won't"
})
public EnumLists utEntityListMode = EnumLists.WHITELIST;

@Config.Name("[13] Dimension List")
@Config.Comment
({
"List of dimensions concerning Void Teleport",
"Behavior depends on the list mode",
"Can be dimension name or ID"
})
public String[] utDimensionList = new String[] {};

@Config.Name("[14] Dimension List Mode")
@Config.Comment
({
"Blacklist Mode: Dimensions that don't have Void Teleport enabled, others do",
"Whitelist Mode: Dimensions that have Void Teleport enabled, others don't"
})
public EnumLists utDimensionListMode = EnumLists.BLACKLIST;
}
}

public static class ItemsCategory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public class UTLoadingPlugin implements IFMLLoadingPlugin, IEarlyMixinLoader
put("mixins.tweaks.entities.speed.player.json", () -> UTConfigTweaks.ENTITIES.PLAYER_SPEED.utPlayerSpeedToggle);
put("mixins.tweaks.entities.taming.horse.json", () -> UTConfigTweaks.ENTITIES.UNDEAD_HORSES.utTamingUndeadHorsesToggle);
put("mixins.tweaks.entities.trading.json", () -> UTConfigTweaks.ENTITIES.utVillagerTradeLevelingToggle || UTConfigTweaks.ENTITIES.utVillagerTradeRestockToggle);
put("mixins.tweaks.entities.voidteleport.json", () -> UTConfigTweaks.ENTITIES.VOID_TELEPORT.utVoidTeleportToggle);
put("mixins.tweaks.items.attackcooldown.server.json", () -> UTConfigTweaks.ITEMS.ATTACK_COOLDOWN.utAttackCooldownToggle);
put("mixins.tweaks.items.eating.json", () -> UTConfigTweaks.ITEMS.utAlwaysEatToggle);
put("mixins.tweaks.items.hardcorebuckets.json", () -> UTConfigTweaks.ITEMS.utHardcoreBucketsToggle);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package mod.acgaming.universaltweaks.tweaks.entities.voidteleport.mixin;

import mod.acgaming.universaltweaks.config.UTConfigTweaks;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.init.SoundEvents;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.DimensionType;
import net.minecraftforge.common.DimensionManager;
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 java.util.Arrays;
import java.util.List;

// Courtesy of WaitingIdly
@Mixin(EntityLivingBase.class)
public abstract class UTVoidTeleportEntity
{
@Unique
private static final String universalTweaks$combo = "universalTweaks$consecutiveVoidTeleportTimes";

@Unique
private static boolean isEnabledForDimension(int dimension)
{
List<String> list = Arrays.asList(UTConfigTweaks.ENTITIES.VOID_TELEPORT.utDimensionList);
DimensionType dimensionType = DimensionManager.getProviderType(dimension);
String dimensionName = dimensionType == null ? null : dimensionType.getName();

boolean isWhitelist = UTConfigTweaks.ENTITIES.VOID_TELEPORT.utDimensionListMode == UTConfigTweaks.EnumLists.WHITELIST;
return isWhitelist == (list.contains(dimensionName) || list.contains(String.valueOf(dimension)));
}

@Unique
private static boolean isEnabledForEntity(Entity entity)
{
List<String> list = Arrays.asList(UTConfigTweaks.ENTITIES.VOID_TELEPORT.utEntityList);
ResourceLocation resourceLocation = EntityList.getKey(entity);
if (resourceLocation == null) return false;

boolean isWhitelist = UTConfigTweaks.ENTITIES.VOID_TELEPORT.utEntityListMode == UTConfigTweaks.EnumLists.WHITELIST;
return list.contains(resourceLocation.toString()) == isWhitelist;
}

@Inject(method = "outOfWorld", at = @At("HEAD"), cancellable = true)
public void utTransferPlayerToDimension(CallbackInfo ci)
{
if (!UTConfigTweaks.ENTITIES.VOID_TELEPORT.utVoidTeleportToggle) return;
EntityLivingBase entity = (EntityLivingBase) (Object) this;
if (!isEnabledForDimension(entity.dimension)) return;
if (UTConfigTweaks.ENTITIES.VOID_TELEPORT.utMaxCombo >= 0 && entity.getEntityData().getInteger(universalTweaks$combo) > UTConfigTweaks.ENTITIES.VOID_TELEPORT.utMaxCombo) return;

if ((UTConfigTweaks.ENTITIES.VOID_TELEPORT.utForgivePlayers && entity instanceof EntityPlayer) || isEnabledForEntity(entity))
{
if (UTConfigTweaks.ENTITIES.VOID_TELEPORT.utPreventVoidDamage) ci.cancel();
if (UTConfigTweaks.ENTITIES.VOID_TELEPORT.utTeleportBlindness) entity.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, 60, 3));

int highestClearLocation = entity.getEntityWorld().getHeight(MathHelper.floor(entity.posX), MathHelper.floor(entity.posZ));
int targetY = UTConfigTweaks.ENTITIES.VOID_TELEPORT.utTargetYLevel < highestClearLocation ? highestClearLocation : UTConfigTweaks.ENTITIES.VOID_TELEPORT.utTargetYLevel;
entity.setPositionAndUpdate(entity.posX, targetY, entity.posZ);
entity.motionY = Math.min(0, Math.max(UTConfigTweaks.ENTITIES.VOID_TELEPORT.utClampSpeedTo, entity.motionY));

if (entity.getEntityData().hasKey(universalTweaks$combo))
{
entity.getEntityData().setInteger(universalTweaks$combo, entity.getEntityData().getInteger(universalTweaks$combo) + 1);
}
else
{
entity.getEntityData().setInteger(universalTweaks$combo, 1);
}
}
}

@Inject(method = "updateFallState", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;updateFallState(DZLnet/minecraft/block/state/IBlockState;Lnet/minecraft/util/math/BlockPos;)V"))
public void utUpdateFallState(double y, boolean onGroundIn, IBlockState state, BlockPos pos, CallbackInfo ci)
{
if (!UTConfigTweaks.ENTITIES.VOID_TELEPORT.utVoidTeleportToggle) return;
EntityLivingBase entity = (EntityLivingBase) (Object) this;
if (onGroundIn && entity.getEntityData().hasKey(universalTweaks$combo))
{
entity.getEntityData().removeTag(universalTweaks$combo);

if (entity.isInWater()) return;
if (entity instanceof EntityPlayer && (((EntityPlayer) entity).capabilities.isFlying || ((EntityPlayer) entity).capabilities.allowFlying)) return;

if (UTConfigTweaks.ENTITIES.VOID_TELEPORT.utFallHeight < 0)
{
entity.fallDistance = 0;
float setting = UTConfigTweaks.ENTITIES.VOID_TELEPORT.utFallDamageTaken;
if (setting != 0)
{
float damage = setting < 0 ? entity.getMaxHealth() + setting : setting;
if (!UTConfigTweaks.ENTITIES.VOID_TELEPORT.utAllowSpecificFallDamageToKill) damage = Float.min(entity.getHealth() - 1, damage);
if (damage > 0)
{
entity.playSound(SoundEvents.ENTITY_GENERIC_BIG_FALL, 1.0F, 1.0F);
entity.attackEntityFrom(DamageSource.FALL, damage);
}
}
}
else
{
entity.fallDistance = UTConfigTweaks.ENTITIES.VOID_TELEPORT.utFallHeight;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class UTObsoleteModsHandler
put("fastleafdecay", () -> UTConfigTweaks.BLOCKS.utLeafDecayToggle);
put("fencejumper", () -> UTConfigTweaks.BLOCKS.utFenceWallJumpToggle);
put("finite-fluid-control", () -> UTConfigTweaks.BLOCKS.FINITE_WATER.utFiniteWaterToggle);
put("forgivingvoid", () -> UTConfigTweaks.ENTITIES.VOID_TELEPORT.utVoidTeleportToggle);
put("framevoidpatch", () -> UTConfigBugfixes.BLOCKS.utItemFrameVoidToggle);
put("getittogetherdrops", () -> UTConfigTweaks.ITEMS.ITEM_ENTITIES.utItemEntitiesToggle);
put("givemebackmyhp", () -> UTConfigBugfixes.ENTITIES.utMaxHealthToggle);
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/assets/universaltweaks/lang/en_us.lang
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ cfg.universaltweaks.tweaks.entities.sleeping=Sleeping
cfg.universaltweaks.tweaks.entities.spawncaps=Spawn Caps
cfg.universaltweaks.tweaks.entities.undeadhorses=Undead Horses
cfg.universaltweaks.tweaks.entities.waterfalldamage=Water Fall Damage
cfg.universaltweaks.tweaks.entities.voidteleport=Void Teleport
cfg.universaltweaks.tweaks.items.attackcooldown=Attack Cooldown
cfg.universaltweaks.tweaks.items.infinity=Infinity
cfg.universaltweaks.tweaks.items.itementities=Item Entities
Expand Down
7 changes: 7 additions & 0 deletions src/main/resources/mixins.tweaks.entities.voidteleport.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"package": "mod.acgaming.universaltweaks.tweaks.entities.voidteleport.mixin",
"refmap": "universaltweaks.refmap.json",
"minVersion": "0.8",
"compatibilityLevel": "JAVA_8",
"mixins": ["UTVoidTeleportEntity"]
}

0 comments on commit 229101f

Please sign in to comment.