XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

MyDimension

【Java】我的维度模组

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/MyDimension

允许玩家设置传送锚点

3b148fc
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

7 个文件 +138 -10
Modified gradle.properties +1 -1
@@ -11,7 +11,7 @@ loader_version_range=[47,)
11 11 mod_id=mydimension
12 12 mod_name=\u6211\u7684\u7ef4\u5ea6
13 13 mod_license=CC0-1.0
14 mod_version=1.3.2
14 mod_version=1.3.3
15 15 mod_group_id=com.xfestudio.mydimension
16 16 maven_group=com.xfestudio
17 17 archives_base_name=mydimension
Modified src/main/java/com/xfestudio/mydimension/MyDimensionEvents.java +25 -0
@@ -9,11 +9,13 @@ import com.xfestudio.mydimension.world.ModDimensions;
9 9 import net.minecraft.commands.CommandSourceStack;
10 10 import net.minecraft.commands.arguments.EntityArgument;
11 11 import net.minecraft.commands.arguments.selector.EntitySelector;
12 import net.minecraft.core.particles.ParticleTypes;
12 13 import net.minecraft.network.chat.Component;
13 14 import net.minecraft.network.protocol.game.ClientboundGameEventPacket;
14 15 import net.minecraft.network.protocol.game.ClientboundSetTimePacket;
15 16 import net.minecraft.server.level.ServerLevel;
16 17 import net.minecraft.server.level.ServerPlayer;
18 import net.minecraft.server.MinecraftServer;
17 19 import net.minecraft.world.InteractionHand;
18 20 import net.minecraft.world.InteractionResult;
19 21 import net.minecraft.world.entity.Entity;
@@ -23,6 +25,7 @@ import net.minecraft.world.entity.MobSpawnType;
23 25 import net.minecraft.world.item.ItemStack;
24 26 import net.minecraft.world.level.GameRules;
25 27 import net.minecraftforge.event.CommandEvent;
28 import net.minecraftforge.event.TickEvent;
26 29 import net.minecraftforge.event.entity.living.MobSpawnEvent;
27 30 import net.minecraftforge.event.entity.player.PlayerInteractEvent;
28 31 import net.minecraftforge.event.level.SleepFinishedTimeEvent;
@@ -35,6 +38,7 @@ import java.util.Locale;
35 38
36 39 public class MyDimensionEvents {
37 40 private static final int CLEAR_WEATHER_DURATION = 6000;
41 private int anchorParticleTicker;
38 42
39 43 @SubscribeEvent(priority = EventPriority.HIGHEST, receiveCanceled = true)
40 44 public void sendMobToEtherealMind(PlayerInteractEvent.EntityInteract event) {
@@ -94,6 +98,27 @@ public class MyDimensionEvents {
94 98 makeMindMorning(level, event.getNewTime());
95 99 }
96 100
101 @SubscribeEvent
102 public void spawnAnchorParticles(TickEvent.ServerTickEvent event) {
103 if (event.phase != TickEvent.Phase.END || ++anchorParticleTicker % 10 != 0) {
104 return;
105 }
106
107 MinecraftServer server = event.getServer();
108 for (ServerPlayer owner : server.getPlayerList().getPlayers()) {
109 for (RiftItem.AnchorPoint anchor : RiftItem.readAnchors(owner)) {
110 ServerLevel level = server.getLevel(anchor.dimension());
111 if (level == null || !ModDimensions.isMindDimension(level.dimension())) {
112 continue;
113 }
114
115 level.sendParticles(ParticleTypes.END_ROD, anchor.x(), anchor.y() + 0.75D, anchor.z(), 2, 0.25D, 0.45D, 0.25D, 0.01D);
116 level.sendParticles(ParticleTypes.ENCHANT, anchor.x(), anchor.y() + 1.0D, anchor.z(), 6, 0.55D, 0.65D, 0.55D, 0.02D);
117 level.sendParticles(ParticleTypes.SOUL_FIRE_FLAME, anchor.x(), anchor.y() + 0.15D, anchor.z(), 1, 0.18D, 0.08D, 0.18D, 0.0D);
118 }
119 }
120 }
121
97 122 private static String firstWord(String input) {
98 123 int space = input.indexOf(' ');
99 124 return space < 0 ? input : input.substring(0, space);
Modified src/main/java/com/xfestudio/mydimension/client/RiftActionScreen.java +31 -7
@@ -21,6 +21,7 @@ public class RiftActionScreen extends Screen {
21 21 private static final int OUTER_RADIUS = 122;
22 22 private static final int TRAVEL_COLOR = 0xFF3E8DB8;
23 23 private static final int MOB_COLOR = 0xFF8B58C8;
24 private static final int ANCHOR_COLOR = 0xFFD6A23E;
24 25
25 26 public RiftActionScreen() {
26 27 super(Component.translatable("screen.mydimension.rift_actions"));
@@ -40,6 +41,8 @@ public class RiftActionScreen extends Screen {
40 41 addActionButton(RiftAction.SEND_MOB_MIRROR, centerX, centerY, -45.0D, OUTER_RADIUS);
41 42 addActionButton(RiftAction.SEND_MOB_WATER, centerX, centerY, 45.0D, OUTER_RADIUS);
42 43 addActionButton(RiftAction.SEND_MOB_NATURE, centerX, centerY, 135.0D, OUTER_RADIUS);
44
45 addRenderableWidget(new ActionButton(centerX - BUTTON_WIDTH / 2, centerY + 33, RiftAction.SET_ANCHOR, getSelectedAction() == RiftAction.SET_ANCHOR));
43 46 }
44 47
45 48 @Override
@@ -65,11 +68,12 @@ public class RiftActionScreen extends Screen {
65 68 private void renderCenterPanel(GuiGraphics graphics) {
66 69 int centerX = width / 2;
67 70 int centerY = height / 2;
68 graphics.fill(centerX - 52, centerY - 34, centerX + 52, centerY + 34, 0xAA070A10);
69 drawBorder(graphics, centerX - 52, centerY - 34, centerX + 52, centerY + 34, 0xFF85D6F7);
71 fillRoundedRect(graphics, centerX - 56, centerY - 40, centerX + 56, centerY + 62, 5, 0xAA070A10);
72 drawRoundedBorder(graphics, centerX - 56, centerY - 40, centerX + 56, centerY + 62, 5, 0xFF85D6F7);
70 73 graphics.drawCenteredString(font, title, centerX, centerY - 23, 0xFFEAFBFF);
71 74 graphics.drawCenteredString(font, Component.translatable("screen.mydimension.rift_actions.travel"), centerX, centerY - 5, 0xFF9DDBFF);
72 75 graphics.drawCenteredString(font, Component.translatable("screen.mydimension.rift_actions.mob"), centerX, centerY + 10, 0xFFD0B6FF);
76 graphics.drawCenteredString(font, Component.translatable("screen.mydimension.rift_actions.anchor"), centerX, centerY + 25, 0xFFFFE0A3);
73 77 }
74 78
75 79 private void renderRingHints(GuiGraphics graphics) {
@@ -107,6 +111,25 @@ public class RiftActionScreen extends Screen {
107 111 graphics.fill(right - 1, top, right, bottom, color);
108 112 }
109 113
114 private static void fillRoundedRect(GuiGraphics graphics, int left, int top, int right, int bottom, int radius, int color) {
115 graphics.fill(left + radius, top, right - radius, bottom, color);
116 graphics.fill(left, top + radius, right, bottom - radius, color);
117 graphics.fill(left + 1, top + 1, right - 1, top + radius, color);
118 graphics.fill(left + 1, bottom - radius, right - 1, bottom - 1, color);
119 graphics.fill(left + radius - 1, top + 1, right - radius + 1, bottom - 1, color);
120 }
121
122 private static void drawRoundedBorder(GuiGraphics graphics, int left, int top, int right, int bottom, int radius, int color) {
123 graphics.fill(left + radius, top, right - radius, top + 1, color);
124 graphics.fill(left + radius, bottom - 1, right - radius, bottom, color);
125 graphics.fill(left, top + radius, left + 1, bottom - radius, color);
126 graphics.fill(right - 1, top + radius, right, bottom - radius, color);
127 graphics.fill(left + 1, top + 1, left + radius, top + 2, color);
128 graphics.fill(right - radius, top + 1, right - 1, top + 2, color);
129 graphics.fill(left + 1, bottom - 2, left + radius, bottom - 1, color);
130 graphics.fill(right - radius, bottom - 2, right - 1, bottom - 1, color);
131 }
132
110 133 private static void drawDiamond(GuiGraphics graphics, int centerX, int centerY, int radius, int color) {
111 134 graphics.fill(centerX - 1, centerY - radius, centerX + 1, centerY - radius + 2, color);
112 135 graphics.fill(centerX + radius - 1, centerY - 1, centerX + radius + 1, centerY + 1, color);
@@ -130,14 +153,15 @@ public class RiftActionScreen extends Screen {
130 153 int top = getY();
131 154 int right = left + getWidth();
132 155 int bottom = top + getHeight();
133 int base = action.sendsMob() ? MOB_COLOR : TRAVEL_COLOR;
156 int base = action == RiftAction.SET_ANCHOR ? ANCHOR_COLOR : (action.sendsMob() ? MOB_COLOR : TRAVEL_COLOR);
134 157 int fill = withAlpha(base, isHoveredOrFocused() ? 226 : 174);
135 int edge = selected ? 0xFFFFF4A8 : (action.sendsMob() ? 0xFFD8C1FF : 0xFFB8F0FF);
158 int edge = selected ? 0xFFFFF4A8 : (action == RiftAction.SET_ANCHOR ? 0xFFFFE0A3 : (action.sendsMob() ? 0xFFD8C1FF : 0xFFB8F0FF));
136 159
137 graphics.fillGradient(left, top, right, bottom, fill, darken(fill));
138 drawBorder(graphics, left, top, right, bottom, edge);
160 fillRoundedRect(graphics, left, top, right, bottom, 5, darken(fill));
161 fillRoundedRect(graphics, left + 1, top + 1, right - 1, bottom - 1, 4, fill);
162 drawRoundedBorder(graphics, left, top, right, bottom, 5, edge);
139 163 if (selected) {
140 graphics.fill(left + 2, top + 2, left + 5, bottom - 2, 0xFFFFF4A8);
164 fillRoundedRect(graphics, left + 3, top + 4, left + 7, bottom - 4, 2, 0xFFFFF4A8);
141 165 }
142 166
143 167 int textColor = isHoveredOrFocused() ? 0xFFFFFFFF : 0xFFEAFBFF;
Modified src/main/java/com/xfestudio/mydimension/item/RiftAction.java +2 -1
@@ -15,7 +15,8 @@ public enum RiftAction {
15 15 SEND_MOB_ETHEREAL("send_mob_ethereal", "action.mydimension.send_mob_ethereal", ModDimensions.ETHEREAL_MIND, true),
16 16 SEND_MOB_MIRROR("send_mob_mirror", "action.mydimension.send_mob_mirror", ModDimensions.MIRROR_MIND, true),
17 17 SEND_MOB_WATER("send_mob_water", "action.mydimension.send_mob_water", ModDimensions.WATER_MIND, true),
18 SEND_MOB_NATURE("send_mob_nature", "action.mydimension.send_mob_nature", ModDimensions.NATURE_MIND, true);
18 SEND_MOB_NATURE("send_mob_nature", "action.mydimension.send_mob_nature", ModDimensions.NATURE_MIND, true),
19 SET_ANCHOR("set_anchor", "action.mydimension.set_anchor", null, false);
19 20
20 21 private final String id;
21 22 private final String translationKey;
Modified src/main/java/com/xfestudio/mydimension/item/RiftItem.java +71 -1
@@ -39,6 +39,7 @@ public class RiftItem extends Item {
39 39 private static final String SELECTED_ACTION_TAG = "SelectedAction";
40 40 private static final String RETURN_POINT_TAG = "ReturnPoint";
41 41 private static final String MIND_POINTS_TAG = "MindPoints";
42 private static final String PLAYER_ANCHORS_TAG = "mydimension.RiftAnchors";
42 43 private static final String RETURN_DIMENSION_TAG = "Dimension";
43 44 private static final String RETURN_X_TAG = "X";
44 45 private static final String RETURN_Y_TAG = "Y";
@@ -119,6 +120,11 @@ public class RiftItem extends Item {
119 120
120 121 private static void executeSelectedAction(ServerPlayer player, ItemStack stack) {
121 122 RiftAction action = getSelectedAction(stack);
123 if (action == RiftAction.SET_ANCHOR) {
124 setAnchor(player);
125 return;
126 }
127
122 128 if (action.sendsMob()) {
123 129 LivingEntity target = findLookedAtLivingEntity(player);
124 130 if (target == null || !sendToMind(player, target, stack, action.targetDimension())) {
@@ -217,7 +223,11 @@ public class RiftItem extends Item {
217 223 target.stopRiding();
218 224 target.ejectPassengers();
219 225
220 Entity moved = target.changeDimension(targetLevel, new EtherealMindTeleporter(player.getX(), safeEntryY(targetLevel, targetDimension, player.getX(), player.getZ()), player.getZ()));
226 AnchorPoint anchor = readAnchor(player, targetDimension);
227 double targetX = anchor != null ? anchor.x() : player.getX();
228 double targetY = anchor != null ? anchor.y() : safeEntryY(targetLevel, targetDimension, player.getX(), player.getZ());
229 double targetZ = anchor != null ? anchor.z() : player.getZ();
230 Entity moved = target.changeDimension(targetLevel, new EtherealMindTeleporter(targetX, targetY, targetZ));
221 231 if (moved != null) {
222 232 moved.getPersistentData().putBoolean(IMPORTED_TO_ETHEREAL_MIND, true);
223 233 targetLevel.playSound(null, BlockPos.containing(moved.position()), SoundEvents.ENDERMAN_TELEPORT, SoundSource.NEUTRAL, 1.0F, 1.0F);
@@ -247,6 +257,63 @@ public class RiftItem extends Item {
247 257 return hit != null && hit.getEntity() instanceof LivingEntity living ? living : null;
248 258 }
249 259
260 private static void setAnchor(ServerPlayer player) {
261 ResourceKey<Level> dimension = player.level().dimension();
262 if (!ModDimensions.isMindDimension(dimension)) {
263 player.displayClientMessage(Component.translatable("message.mydimension.anchor_only_mind"), true);
264 return;
265 }
266
267 CompoundTag anchors = player.getPersistentData().getCompound(PLAYER_ANCHORS_TAG);
268 CompoundTag anchor = new CompoundTag();
269 anchor.putString(RETURN_DIMENSION_TAG, dimension.location().toString());
270 anchor.putDouble(RETURN_X_TAG, player.getX());
271 anchor.putDouble(RETURN_Y_TAG, player.getY());
272 anchor.putDouble(RETURN_Z_TAG, player.getZ());
273 anchors.put(dimension.location().toString(), anchor);
274 player.getPersistentData().put(PLAYER_ANCHORS_TAG, anchors);
275 player.displayClientMessage(Component.translatable("message.mydimension.anchor_set"), true);
276 }
277
278 public static AnchorPoint readAnchor(ServerPlayer player, ResourceKey<Level> dimension) {
279 CompoundTag anchors = player.getPersistentData().getCompound(PLAYER_ANCHORS_TAG);
280 String tagName = dimension.location().toString();
281 if (!anchors.contains(tagName, CompoundTag.TAG_COMPOUND)) {
282 return null;
283 }
284
285 CompoundTag anchor = anchors.getCompound(tagName);
286 ResourceLocation location = ResourceLocation.tryParse(anchor.getString(RETURN_DIMENSION_TAG));
287 if (location == null) {
288 return null;
289 }
290
291 return new AnchorPoint(
292 ResourceKey.create(Registries.DIMENSION, location),
293 anchor.getDouble(RETURN_X_TAG),
294 anchor.getDouble(RETURN_Y_TAG),
295 anchor.getDouble(RETURN_Z_TAG)
296 );
297 }
298
299 public static java.util.List<AnchorPoint> readAnchors(ServerPlayer player) {
300 java.util.List<AnchorPoint> anchors = new java.util.ArrayList<>();
301 CompoundTag tag = player.getPersistentData().getCompound(PLAYER_ANCHORS_TAG);
302 for (String key : tag.getAllKeys()) {
303 ResourceLocation location = ResourceLocation.tryParse(key);
304 if (location != null && tag.contains(key, CompoundTag.TAG_COMPOUND)) {
305 CompoundTag anchor = tag.getCompound(key);
306 anchors.add(new AnchorPoint(
307 ResourceKey.create(Registries.DIMENSION, location),
308 anchor.getDouble(RETURN_X_TAG),
309 anchor.getDouble(RETURN_Y_TAG),
310 anchor.getDouble(RETURN_Z_TAG)
311 ));
312 }
313 }
314 return anchors;
315 }
316
250 317 private static void writePoint(ItemStack stack, String tagName, ServerPlayer player) {
251 318 CompoundTag point = new CompoundTag();
252 319 point.putString(RETURN_DIMENSION_TAG, player.level().dimension().location().toString());
@@ -334,6 +401,9 @@ public class RiftItem extends Item {
334 401 private record ReturnPoint(ResourceKey<Level> dimension, double x, double y, double z, float yRot, float xRot) {
335 402 }
336 403
404 public record AnchorPoint(ResourceKey<Level> dimension, double x, double y, double z) {
405 }
406
337 407 private static class EtherealMindTeleporter implements ITeleporter {
338 408 private final double x;
339 409 private final double y;
Modified src/main/resources/assets/mydimension/lang/en_us.json +4 -0
@@ -7,6 +7,7 @@
7 7 "screen.mydimension.rift_actions": "Rift",
8 8 "screen.mydimension.rift_actions.travel": "Inner: Travel",
9 9 "screen.mydimension.rift_actions.mob": "Outer: Send Mob",
10 "screen.mydimension.rift_actions.anchor": "Center: Set Anchor",
10 11 "action.mydimension.ethereal_mind": "Go to Ethereal Mind",
11 12 "action.mydimension.mirror_mind": "Go to Mirror Mind",
12 13 "action.mydimension.water_mind": "Go to Water Mind",
@@ -15,7 +16,10 @@
15 16 "action.mydimension.send_mob_mirror": "Send Mob to Mirror",
16 17 "action.mydimension.send_mob_water": "Send Mob to Water",
17 18 "action.mydimension.send_mob_nature": "Send Mob to Nature",
19 "action.mydimension.set_anchor": "Set Teleport Anchor",
18 20 "message.mydimension.already_in_target_mind": "That mob is already in the target mind dimension",
21 "message.mydimension.anchor_only_mind": "Teleport anchors can only be set in mind dimensions",
22 "message.mydimension.anchor_set": "Teleport anchor set for this mind dimension",
19 23 "message.mydimension.no_mob_target": "No mob target selected",
20 24 "message.mydimension.missing_dimension": "The target mind dimension is not loaded",
21 25 "message.mydimension.protected_tp": "%s is in a mind dimension and cannot be teleported by another player"
Modified src/main/resources/assets/mydimension/lang/zh_cn.json +4 -0
@@ -7,6 +7,7 @@
7 7 "screen.mydimension.rift_actions": "裂罅",
8 8 "screen.mydimension.rift_actions.travel": "内环:前往心境",
9 9 "screen.mydimension.rift_actions.mob": "外环:传送生物",
10 "screen.mydimension.rift_actions.anchor": "中心:设置锚点",
10 11 "action.mydimension.ethereal_mind": "前往空灵心境",
11 12 "action.mydimension.mirror_mind": "前往镜之心境",
12 13 "action.mydimension.water_mind": "前往水之心境",
@@ -15,7 +16,10 @@
15 16 "action.mydimension.send_mob_mirror": "传送生物到镜",
16 17 "action.mydimension.send_mob_water": "传送生物到水",
17 18 "action.mydimension.send_mob_nature": "传送生物到自然",
19 "action.mydimension.set_anchor": "设置传送锚点",
18 20 "message.mydimension.already_in_target_mind": "该生物已经在目标心境中",
21 "message.mydimension.anchor_only_mind": "只能在心境维度中设置传送锚点",
22 "message.mydimension.anchor_set": "已设置该心境的传送锚点",
19 23 "message.mydimension.no_mob_target": "没有瞄准可传送的生物",
20 24 "message.mydimension.missing_dimension": "目标心境维度未加载",
21 25 "message.mydimension.protected_tp": "%s 正处于心境维度,无法被其他玩家传送",