-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
34b9f67
commit 1bb3bb4
Showing
13 changed files
with
483 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 113 additions & 0 deletions
113
...main/java/com/github/tartaricacid/touhoulittlemaid/client/gui/item/MonsterListScreen.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package com.github.tartaricacid.touhoulittlemaid.client.gui.item; | ||
|
||
import com.github.tartaricacid.touhoulittlemaid.client.gui.widget.button.FlatColorButton; | ||
import com.github.tartaricacid.touhoulittlemaid.entity.misc.DefaultMonsterType; | ||
import com.github.tartaricacid.touhoulittlemaid.entity.misc.MonsterType; | ||
import com.github.tartaricacid.touhoulittlemaid.network.NetworkHandler; | ||
import com.github.tartaricacid.touhoulittlemaid.network.message.SetMonsterListMessage; | ||
import com.google.common.collect.Maps; | ||
import com.mojang.blaze3d.vertex.PoseStack; | ||
import net.minecraft.client.Minecraft; | ||
import net.minecraft.client.gui.screens.Screen; | ||
import net.minecraft.network.chat.Component; | ||
import net.minecraft.network.chat.TextComponent; | ||
import net.minecraft.resources.ResourceLocation; | ||
import net.minecraft.world.entity.EntityType; | ||
import net.minecraft.world.item.ItemStack; | ||
import net.minecraftforge.registries.ForgeRegistries; | ||
import org.apache.commons.lang3.StringUtils; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class MonsterListScreen extends Screen { | ||
private static final int PER_MAX_COUNT = 10; | ||
|
||
private final Map<EntityType<?>, MonsterType> monsterList; | ||
private final List<EntityType<?>> monsterListIndex; | ||
|
||
private int page = 0; | ||
private int posX; | ||
private int posY; | ||
|
||
public MonsterListScreen(ItemStack stack) { | ||
super(new TextComponent("Monster List Screen")); | ||
this.monsterList = DefaultMonsterType.getMonsterList(stack, Minecraft.getInstance().level); | ||
this.monsterListIndex = this.monsterList.keySet().stream().toList(); | ||
} | ||
|
||
@Override | ||
protected void init() { | ||
this.clearWidgets(); | ||
|
||
this.posX = this.width / 2; | ||
this.posY = this.height / 2; | ||
|
||
int startY = posY - 16 * PER_MAX_COUNT / 2 - 8; | ||
int size = this.monsterListIndex.size(); | ||
for (int i = 0; i < PER_MAX_COUNT; i++) { | ||
final int index = page * PER_MAX_COUNT + i; | ||
if (index >= size) { | ||
break; | ||
} | ||
|
||
EntityType<?> entityType = this.monsterListIndex.get(index); | ||
MonsterType monsterType = this.monsterList.get(entityType); | ||
Component text = monsterType.getComponent() | ||
.copy() | ||
.append(StringUtils.SPACE) | ||
.append(entityType.getDescription()); | ||
|
||
FlatColorButton button = new FlatColorButton(posX - 100, startY, 200, 14, text, b -> { | ||
MonsterType next = monsterType.getNext(); | ||
this.monsterList.put(entityType, next); | ||
this.init(); | ||
}); | ||
|
||
this.addRenderableWidget(button); | ||
startY += 16; | ||
} | ||
|
||
startY = posY + 16 * PER_MAX_COUNT / 2 - 8; | ||
this.addRenderableWidget(new FlatColorButton(posX - 100, startY, 28, 14, new TextComponent("<"), b -> { | ||
if (this.page > 0) { | ||
this.page--; | ||
this.init(); | ||
} | ||
})); | ||
|
||
this.addRenderableWidget(new FlatColorButton(posX + 100 - 28, startY, 28, 14, new TextComponent(">"), b -> { | ||
int nextStartIndex = (this.page + 1) * PER_MAX_COUNT; | ||
if (nextStartIndex < this.monsterListIndex.size()) { | ||
this.page++; | ||
this.init(); | ||
} | ||
})); | ||
} | ||
|
||
@Override | ||
public void render(PoseStack poseStack, int mouseX, int mouseY, float partialTick) { | ||
this.renderBackground(poseStack); | ||
super.render(poseStack, mouseX, mouseY, partialTick); | ||
|
||
String pageText = String.format("%d/%d", page + 1, this.monsterListIndex.size() / PER_MAX_COUNT + 1); | ||
int startY = posY + 16 * PER_MAX_COUNT / 2 - 5; | ||
drawCenteredString(poseStack, font, pageText, this.posX, startY, 0xFFFFFF); | ||
} | ||
|
||
@Override | ||
public void onClose() { | ||
Map<ResourceLocation, MonsterType> monsterListOutput = Maps.newHashMap(); | ||
this.monsterList.forEach((type, monsterType) -> { | ||
ResourceLocation key = ForgeRegistries.ENTITIES.getKey(type); | ||
monsterListOutput.put(key, monsterType); | ||
}); | ||
NetworkHandler.CHANNEL.sendToServer(new SetMonsterListMessage(monsterListOutput)); | ||
super.onClose(); | ||
} | ||
|
||
@Override | ||
public boolean isPauseScreen() { | ||
return false; | ||
} | ||
} |
127 changes: 127 additions & 0 deletions
127
src/main/java/com/github/tartaricacid/touhoulittlemaid/entity/misc/DefaultMonsterType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package com.github.tartaricacid.touhoulittlemaid.entity.misc; | ||
|
||
import com.github.tartaricacid.touhoulittlemaid.entity.item.AbstractEntityFromItem; | ||
import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; | ||
import com.github.tartaricacid.touhoulittlemaid.init.InitItems; | ||
import com.github.tartaricacid.touhoulittlemaid.item.ItemMonsterList; | ||
import com.google.common.collect.Maps; | ||
import net.minecraft.nbt.CompoundTag; | ||
import net.minecraft.resources.ResourceLocation; | ||
import net.minecraft.world.entity.Entity; | ||
import net.minecraft.world.entity.EntityType; | ||
import net.minecraft.world.entity.LivingEntity; | ||
import net.minecraft.world.entity.TamableAnimal; | ||
import net.minecraft.world.entity.decoration.ArmorStand; | ||
import net.minecraft.world.entity.monster.Enemy; | ||
import net.minecraft.world.entity.npc.Npc; | ||
import net.minecraft.world.entity.player.Player; | ||
import net.minecraft.world.item.ItemStack; | ||
import net.minecraft.world.level.Level; | ||
import net.minecraftforge.registries.ForgeRegistries; | ||
|
||
import javax.annotation.Nullable; | ||
import java.util.Map; | ||
|
||
public final class DefaultMonsterType { | ||
private final static Map<EntityType<?>, MonsterType> DEFAULT = Maps.newHashMap(); | ||
|
||
public static void initDefault(Level level) { | ||
// 只允许初始化一次 | ||
if (!DEFAULT.isEmpty()) { | ||
return; | ||
} | ||
|
||
ForgeRegistries.ENTITIES.getValues().forEach(type -> { | ||
Entity entity = type.create(level); | ||
if (!(entity instanceof LivingEntity livingEntity)) { | ||
return; | ||
} | ||
|
||
// 排除一些盔甲架,还有本模组的实体,以及玩家 | ||
if (livingEntity instanceof ArmorStand || livingEntity instanceof AbstractEntityFromItem || livingEntity instanceof Player) { | ||
return; | ||
} | ||
|
||
// 如果继承了 Enemy 接口,那就是敌对生物 | ||
if (livingEntity instanceof Enemy) { | ||
DEFAULT.putIfAbsent(type, MonsterType.HOSTILE); | ||
return; | ||
} | ||
|
||
// 如果是玩家、宠物、NPC、归为友好 | ||
if (livingEntity instanceof TamableAnimal || livingEntity instanceof Npc) { | ||
DEFAULT.putIfAbsent(type, MonsterType.FRIENDLY); | ||
return; | ||
} | ||
|
||
// 否则归为中立 | ||
DEFAULT.putIfAbsent(type, MonsterType.NEUTRAL); | ||
}); | ||
} | ||
|
||
public static Map<EntityType<?>, MonsterType> getMonsterList(ItemStack stack, @Nullable Level level) { | ||
Map<EntityType<?>, MonsterType> output = Maps.newHashMap(); | ||
|
||
if (level == null || stack.getItem() != InitItems.MONSTER_LIST.get()) { | ||
return output; | ||
} | ||
|
||
// 先从物品里读取数据 | ||
CompoundTag monsterList = ItemMonsterList.getMonsterList(stack); | ||
monsterList.getAllKeys().forEach(key -> readTagData(key, monsterList, output)); | ||
|
||
// 最后补齐默认数据 | ||
DEFAULT.forEach(output::putIfAbsent); | ||
|
||
return output; | ||
} | ||
|
||
public static MonsterType getMonsterType(EntityType<?> entityType) { | ||
return DEFAULT.getOrDefault(entityType, MonsterType.NEUTRAL); | ||
} | ||
|
||
public static boolean canAttack(EntityMaid maid, LivingEntity target, MonsterType monsterType) { | ||
// 友好生物,无论什么情况不攻击 | ||
if (monsterType == MonsterType.FRIENDLY) { | ||
return true; | ||
} | ||
|
||
// 中立生物,只有玩家攻击的,或者攻击过玩家的才会攻击 | ||
if (monsterType == MonsterType.NEUTRAL) { | ||
return checkNeutral(maid, target); | ||
} | ||
|
||
// 其他的,那只有敌对了,攻击 | ||
return true; | ||
} | ||
|
||
private static void readTagData(String key, CompoundTag monsterList, Map<EntityType<?>, MonsterType> output) { | ||
int index = monsterList.getInt(key); | ||
MonsterType monsterType = MonsterType.getTypeByIndex(index); | ||
ResourceLocation id = new ResourceLocation(key); | ||
EntityType<?> entityType = ForgeRegistries.ENTITIES.getValue(id); | ||
if (entityType != null) { | ||
output.put(entityType, monsterType); | ||
} | ||
} | ||
|
||
private static boolean checkNeutral(EntityMaid maid, LivingEntity target) { | ||
// 先判断主人 | ||
if (maid.getOwner() instanceof Player player) { | ||
// 获取攻击主人的生物 | ||
LivingEntity lastHurtByMob = player.getLastHurtByMob(); | ||
if (target.equals(lastHurtByMob)) { | ||
return true; | ||
} | ||
// 获取主人攻击过的生物 | ||
LivingEntity lastHurtMob = player.getLastHurtMob(); | ||
if (target.equals(lastHurtMob)) { | ||
return true; | ||
} | ||
} | ||
|
||
// 再判断女仆自身被攻击的 | ||
LivingEntity maidLastHurtByMob = maid.getLastHurtByMob(); | ||
return target.equals(maidLastHurtByMob); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
src/main/java/com/github/tartaricacid/touhoulittlemaid/entity/misc/MonsterType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.github.tartaricacid.touhoulittlemaid.entity.misc; | ||
|
||
import net.minecraft.network.chat.MutableComponent; | ||
import net.minecraft.network.chat.TranslatableComponent; | ||
|
||
import java.util.Locale; | ||
|
||
public enum MonsterType { | ||
FRIENDLY, | ||
NEUTRAL, | ||
HOSTILE; | ||
|
||
private final MutableComponent component; | ||
|
||
MonsterType() { | ||
this.component = new TranslatableComponent("gui.touhou_little_maid.monster_type." + this.name().toLowerCase(Locale.ENGLISH)); | ||
} | ||
|
||
public static MonsterType getTypeByIndex(int index) { | ||
int length = MonsterType.values().length; | ||
return MonsterType.values()[Math.min(index, length - 1)]; | ||
} | ||
|
||
public MonsterType getNext() { | ||
int ordinal = this.ordinal(); | ||
int length = MonsterType.values().length; | ||
return MonsterType.values()[(ordinal + 1) % length]; | ||
} | ||
|
||
public MutableComponent getComponent() { | ||
return component; | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/com/github/tartaricacid/touhoulittlemaid/event/LevelLoadEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.github.tartaricacid.touhoulittlemaid.event; | ||
|
||
import com.github.tartaricacid.touhoulittlemaid.TouhouLittleMaid; | ||
import com.github.tartaricacid.touhoulittlemaid.entity.misc.DefaultMonsterType; | ||
import net.minecraft.world.level.Level; | ||
import net.minecraft.world.level.LevelAccessor; | ||
import net.minecraftforge.event.world.WorldEvent; | ||
import net.minecraftforge.eventbus.api.SubscribeEvent; | ||
import net.minecraftforge.fml.common.Mod; | ||
|
||
@Mod.EventBusSubscriber(modid = TouhouLittleMaid.MOD_ID) | ||
public class LevelLoadEvent { | ||
@SubscribeEvent | ||
public static void onLevelLoadEvent(WorldEvent.Load event) { | ||
LevelAccessor levelAccessor = event.getWorld(); | ||
if (levelAccessor instanceof Level level) { | ||
DefaultMonsterType.initDefault(level); | ||
} | ||
} | ||
} |
Oops, something went wrong.