返回提交历史
Modified
gradle.properties
+1
-1
Modified
src/main/java/com/xfestudio/mydimension/MyDimensionEvents.java
+25
-0
Modified
src/main/java/com/xfestudio/mydimension/client/RiftActionScreen.java
+31
-7
Modified
src/main/java/com/xfestudio/mydimension/item/RiftAction.java
+2
-1
Modified
src/main/java/com/xfestudio/mydimension/item/RiftItem.java
+71
-1
Modified
src/main/resources/assets/mydimension/lang/en_us.json
+4
-0
Modified
src/main/resources/assets/mydimension/lang/zh_cn.json
+4
-0
XFEstudio/MyDimension
允许玩家设置传送锚点
3b148fc
代码差异
7 个文件
+138
-10
@@ -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
@@ -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);
@@ -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;
@@ -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;
@@ -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;
@@ -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"
@@ -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 正处于心境维度,无法被其他玩家传送",