fromgate
Administrator
Хочу обсудить один вопрос. Уже довольно давно было решено, что в наккит необходимо реализовать аналог класса Material из баккита.
Если в двух словах, то суть его заключается в следующем - единый ENUM в котором перечислены все типы предметов, которым сопоставлены id.
При этои ряд предметов, требующих дополнительных характеристик (вроде редстоун блоков или блоков, которые обладают какой-то пространственной ориентацией, состоянием (включено/выключено)
Т.е. это выглядело бы примерно так:
Сам класс описания камня может быть таким:
При этом, придётся реализовать и подтипы (чтобы была возможность уйти от цифровых значений data в описании предметов:
Это даст возможнось создавать предметы и ставить блоки не заморачиваясь на значениях ID/DATA.
Например так:
level.setBlock (location, Material.STONE, new Stone (StoneType.DIORITE));
НО!
Мне тут не нравится конструкция new Stone (StoneType.DIORITE));
Можно конечно подвиды камня реализовать виде статических переменны в классе Stone
Но тут мы теряем преимущества класса энум (и у нас получается своеобразный винегрет - в одном месте энум, а в другом нет) и мне кажется тут можно получить возможные проблемы с тем, что эту статическую переменную при использовании всегда надо будет клонировать (чтобы можно было безболезненно производить операции над изменением только значения data - т.е. поменять тип камня на андезит, например).
Есть вариант перечислить все типы камней (и соответственно других подобных блоков в Material:
У этого способа есть следующие преимущества:
1. ВСЕ виды блоков приведены в одном месте. При разработке плагинов не нужно будет озадачиваться какое значение data у зелёного стекла.
2. Эти названия могут быть использованы в конфиге и командах. Соответственно команда /give fromgate WOOL_RED будет выдавать именно красную шерсть
И недостатки.
1. Всё равно не удасться уйти полностью от дополнительных классов для ряда блоков. К примеру, вместо двух строк LEVER_ON и LEVER_OFF удобнее использовать дополнительный класс, описывающий состояние. Так же для блоков ориентированны по направлению.
2. Не совсем понятно как реализовывать проверки на схожие предметы, созданные из разных типов материалов - т.е. чтобы сравнивать двери
WOODEN_DOOR и WOODEN_DOOR_SPRUCE (условно) всё равно надо будет ориентироваться на цифровое значение ID. А это мне не очень нравится
Что думаете? Лучше вводить дополнительные характеристики для униальных предметов или стараться, по возможности, максимально свести их в один класс?
Если в двух словах, то суть его заключается в следующем - единый ENUM в котором перечислены все типы предметов, которым сопоставлены id.
При этои ряд предметов, требующих дополнительных характеристик (вроде редстоун блоков или блоков, которые обладают какой-то пространственной ориентацией, состоянием (включено/выключено)
Т.е. это выглядело бы примерно так:
Code:
public enum Material{
STONE (1, Stone.class);
// и прочие
}
Code:
public class Stone extends MaterialData {
StoneType type;
public Stone(int meta) {
super(Material.STONE, meta);
this.type = StoneType.getByData(meta);
}
public Stone(){
this(0);
}
public Stone (StoneType type){
this (type.getData());
}
}
Code:
public enum StoneType {
STONE (0),
GRANITE (1),
GRANITE_POLISHED (2),
DIORITE (3),
DIORITE_POLISHED (4),
ANDESITE (5),
ANDESTIE_POLISHED (6);
private int meta;
StoneType (int meta) {
this.meta = meta;
}
public int getData() {
return this.meta;
}
public Stone getMaterialData(){
return new Stone(this.meta);
}
public static StoneType getByData(int meta) {
for (StoneType st : StoneType.values())
if (st.meta == meta) return st;
return StoneType.STONE;
}
}
Это даст возможнось создавать предметы и ставить блоки не заморачиваясь на значениях ID/DATA.
Например так:
level.setBlock (location, Material.STONE, new Stone (StoneType.DIORITE));
НО!
Мне тут не нравится конструкция new Stone (StoneType.DIORITE));
Можно конечно подвиды камня реализовать виде статических переменны в классе Stone
Code:
public final static Stone STONE = new Stone(3);
Есть вариант перечислить все типы камней (и соответственно других подобных блоков в Material:
Code:
public enum Material{
STONE (0, 0, Stone.class),
STONE_GRANITE (0, 1, Stone.class),
STONE_GRANITE_POLISHED (0, 2, Stone.class),
STONE_DIORITE (0, 3, Stone.class),
STONE_DIORITE_POLISHED (0, 4, Stone.class),
STONE_ANDESITE (0, 5, Stone.class),
STONE_ANDESTIE_POLISHED (0, 6, Stone.class);
}
1. ВСЕ виды блоков приведены в одном месте. При разработке плагинов не нужно будет озадачиваться какое значение data у зелёного стекла.
2. Эти названия могут быть использованы в конфиге и командах. Соответственно команда /give fromgate WOOL_RED будет выдавать именно красную шерсть
И недостатки.
1. Всё равно не удасться уйти полностью от дополнительных классов для ряда блоков. К примеру, вместо двух строк LEVER_ON и LEVER_OFF удобнее использовать дополнительный класс, описывающий состояние. Так же для блоков ориентированны по направлению.
2. Не совсем понятно как реализовывать проверки на схожие предметы, созданные из разных типов материалов - т.е. чтобы сравнивать двери
WOODEN_DOOR и WOODEN_DOOR_SPRUCE (условно) всё равно надо будет ориентироваться на цифровое значение ID. А это мне не очень нравится
Что думаете? Лучше вводить дополнительные характеристики для униальных предметов или стараться, по возможности, максимально свести их в один класс?
Last edited: