- 1,159
- 38
- 544
Добрый день. Есть у меня желание добавить в игру систему переносимого веса. И сделать я хочу это, как подобает - реализовав API, который позволит модерам самим определять что делать при перегрузе, самостоятельно определять веса для каждого итема, назначать максимальный переносимый вес для игроков... и все в таком духе.
Т.е. я не хочу сделать мод, я хочу сделать апи, который будет использоваться в других модах.
Дальше я немного теряюсь. Гугл говорит, что пакет, содержащий апи должен иметь класс
Как вы поняли, это дело существует как раз чтобы заполнить "owner"а. Мне такое кажется излишним и я чувствую, что можно лучше.
Раз мой "мод" по факту не является модом, то может быть это библиотека? Быть может стоит просто собрать jar-ник с классами моего апи и затолкать в
Не знаю... Кроме того, я так же не могу найти среди исходников форжа код, который работает с аннотацией
Обращаюсь к вам, товарищи. Подскажите лучшее решение для моей задумки. Есть ли у кого опыт разработки апи для майнкрафта в том виде, в каком я его описал? Если вам не понятно что я вообще пытаюсь сделать, то быть может мой код расскажет об этом больше:
Т.е. я не хочу сделать мод, я хочу сделать апи, который будет использоваться в других модах.
Дальше я немного теряюсь. Гугл говорит, что пакет, содержащий апи должен иметь класс
package-info.java
c аннотацией @API
. Но эта самая аннотация требует такой параметр как "owner", что подразумевает, что должен быть мод, ДЛЯ КОТОРОГО был сделан данный апи. Но вся соль в том, что весь мой код - это и есть апи. Вот как выглядит класс моего "мода"
Java:
package ru.rarescrap.weightapi;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
@Mod(modid = APIContainer.MODID, version = APIContainer.VERSION)
public class APIContainer
{
public static final String MODID = "weightapi";
public static final String VERSION = "1.0.0";
@EventHandler
public void init(FMLInitializationEvent event) {}
}
Как вы поняли, это дело существует как раз чтобы заполнить "owner"а. Мне такое кажется излишним и я чувствую, что можно лучше.
Раз мой "мод" по факту не является модом, то может быть это библиотека? Быть может стоит просто собрать jar-ник с классами моего апи и затолкать в
<forge_server>/libraries/
?Не знаю... Кроме того, я так же не могу найти среди исходников форжа код, который работает с аннотацией
@API
Обращаюсь к вам, товарищи. Подскажите лучшее решение для моей задумки. Есть ли у кого опыт разработки апи для майнкрафта в том виде, в каком я его описал? Если вам не понятно что я вообще пытаюсь сделать, то быть может мой код расскажет об этом больше:
Код:
package ru.rarescrap;
import net.minecraft.entity.Entity;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
/**
* Интерфейс для объктов, способных расчитывать вес предметов
*/
public interface IWeightProvider {
/**
* Вычисляет вес стака
* @param itemStack Стак, вес которого нужно вычислить
* @param inventory Инвентарь, где в данный момент находится стак
* @param owner Владелец инентаря
* @return Вес стака
*/
/*
* Тут нет простых методов вроде getWeight(Item), т.к. расчет веса может основываться и на оссобенностях
* игрока (вдруг у него есть способность на компенсацию веса?), и на оссобенностях инвентаря (вдруг руда в
* этом инвентаре не имее веса?), в котором находится стак... Именно поэтому этот метод имеет так много
* аргументов - ради гибкости использования.
*/
double getWeight(ItemStack itemStack, IInventory inventory, Entity owner);
}
Код:
package ru.rarescrap;
import net.minecraft.entity.Entity;
import net.minecraft.inventory.IInventory;
/**
* Интерфейс для отслеживания изменения веса в инвентарях
*/
public interface IWeightTracker {
/**
* @return Инвентарь, который отслеживает данный {@link IWeightTracker}
*/
IInventory getInventory();
/**
* @return Максимальная вместимость инвентаря
*/
int getMaxWeight();
/**
* @return Текущий вес инвентаря
*/
int getCurrentWeight();
/**
* @return True, если инвентарь перегружен (обычно, когда вес инвентаря
* больше максимально допустимого). Иначе - false.
*/
boolean isOverloaded();
// TODO: Нужно ли?
Entity getInventoryOwner();
// TODO: Нужно ли?
// void onCurrentWeightChanged();
}
Код:
package ru.rarescrap;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import java.util.HashMap;
import java.util.Map;
public class WeightRegistry {
private static IWeightProvider weightProvider;
private static Map<IInventory, IWeightTracker> trackers = new HashMap<IInventory, IWeightTracker>();
// Трекеры нужно регистрировать по большому счету только для того, чтобы иметь возможность получить их из других мест
public static void register(IWeightTracker tracker) {
trackers.put(tracker.getInventory(), tracker);
// TODO: Event?
}
public static void registerWeightProvider(IWeightProvider provider) {
weightProvider = provider;
// TODO: Event?
}
public static IWeightTracker getTracker(IInventory inventory) {
return trackers.get(inventory);
}
public static IWeightProvider getWeightProvider() {
return weightProvider;
}
// TODO: Опасно пиздец. Стоит ли оставлять?
public static IWeightTracker findTracker(ItemStack itemStack) {
for (Map.Entry<IInventory, IWeightTracker> entry : trackers.entrySet()) {
IInventory inventory = entry.getKey();
for (int i = 0; i < inventory.getSizeInventory(); i++) {
ItemStack itemStack1 = inventory.getStackInSlot(i);
if (itemStack1 == itemStack) return trackers.get(inventory);
}
}
return null;
}
}
Код:
package ru.rarescrap.event;
import net.minecraft.entity.Entity;
import net.minecraft.inventory.IInventory;
import net.minecraftforge.event.entity.EntityEvent;
public class WeightChangedEvent extends EntityEvent {
public IInventory inventory;
public double prevWeight;
public double currentWeight;
public boolean isOverloaded; // Это лучше, чем делать отдельный евент на перегрузку
// TODO: Итемстак, который привел к изменению веса?
// TODO: Трекер тут?
public WeightChangedEvent(IInventory inventory, double prevWeight, double currentWeight, boolean isOverloaded, Entity owner) { //TODO: Зачем инвентарь если есть овнер который его содержит? Или может быть ситуация что овнер может не содержать инвентаря, которым же управляет?
super(owner);
this.inventory = inventory;
this.prevWeight = prevWeight;
this.currentWeight = currentWeight;
this.isOverloaded = isOverloaded;
}
}