Copy package com.signition.common.module.machine.api;
import com.signition.common.module.machine.config.MachineConfig;
import com.signition.common.module.machine.controller.MachineController;
import com.signition.common.module.machine.model.PDCMachine;
import com.signition.common.module.machine.model.data.MachineData;
import com.signition.common.module.machine.model.impl.FuelContainer;
import com.signition.common.module.machine.model.impl.InputContainer;
import com.signition.common.module.machine.model.impl.MachineDurability;
import it.unimi.dsi.fastutil.Pair;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public final class MachineAPI {
private MachineAPI() {
throw new UnsupportedOperationException("This class cannot be instantiated");
}
/**
* 엔티티를 Machine 으로 만듭니다
* @param machineData 적용할 machine data
* @param entity machine pdc 를 저장할 entity
*/
public static void applyMachineToEntity(@NotNull MachineData machineData, @NotNull Entity entity) {
PDCMachine.apply(machineData, entity);
}
/**
* config에 등록된 machine data를 가져옵니다
* @param machineId 가져올 machine data의 id
* @return machine data
*/
@Nullable
public static MachineData getMachineData(@NotNull String machineId) {
return MachineConfig.getInstance()
.getMachineData(machineId);
}
/**
* 해당 entity 에서 machine pdc 데이터를 가져와 machine 객체를 캐싱하지 않고 새로 생성합니다. <br>
*
* @param entity machine pdc 가 저장된 entity
* @return 새로운 pdc machine 객체
* @see MachineAPI#getMachine(Player, Entity) 특별한 경우가 아니라면 해당 메서드를 사용하십시오
*/
@Nullable
public static PDCMachine fetchMachine(@NotNull Entity entity) {
return PDCMachine.fetchFromPDC(entity);
}
/**
* 해당 pdc 가 machine 데이터를 포함하고 있는지 확인합니다.
*
* @param container machine data가 포함된 persistent data container
* @return 해당 pdc 데이터가 machine 데이터인지 여부
* @see PDCMachine#isMachine(PersistentDataContainer)
*/
public static boolean isMachine(@NotNull PersistentDataContainer container) {
return PDCMachine.isMachine(container);
}
/**
* machine pdc 데이터가 저장된 entity 를 통해 machine 을 가져옵니다. <br>
* 캐싱된 pdc 데이터가 있으면 pdc 에서 machine data 를 읽어오지 않고 캐싱된 객체를 반환합니다. <br>
* 해당 메서드를 사용해야 machine controller 에서 자동으로 객체의 로드, 언로드를 관리합니다. (정확히는 machine 데이터가 캐싱되어있어야 관리됨)
*
* @param player machine 을 사용하는 player
* @param entity machine pdc 가 저장된 entity
* @return machine pdc 데이터가 없으면 null, 있으면 캐시 여부 확인후 캐싱한 다음 해당 machine 을 반환
* @see MachineAPI#getCachedMachine(Entity) 플레이어의 접근 없이 내부적으로 cached machine 을 가져오고 싶으면 해당 메서드를 사용하십시오
*/
@Nullable
public static PDCMachine getMachine(@NotNull Player player, @NotNull Entity entity) {
return MachineController.getInstance().getMachine(player, entity);
}
/**
* machine pdc 데이터가 저장된 entity 를 통해 machine 을 가져옵니다. <br>
* 캐싱된 pdc 데이터가 없으면 null을 반환합니다 <br>
*
* @param entity machine pdc 가 저장된 entity
* @return 캐싱된 machine 객체
* @see MachineAPI#getMachine(Player, Entity) 특별한 경우가 아니라면 해당 메서드를 사용하십시오
*/
@Nullable
public static PDCMachine getCachedMachine(@NotNull Entity entity) {
return MachineController.getInstance().getCachedMachine(entity);
}
/**
* machine pdc 에서 제조 관련 데이터를 전부 제거합니다 <br>
* 이는 기계를 회수하면서 제조단계를 초기화할때 유용합니다.
* @param container machine pdc 가 저장된 persistent data container
* @return 제거 성공시 true 반환
*/
public static boolean removeManufactureData(@NotNull PersistentDataContainer container) {
if (!PDCMachine.isMachine(container)) {
return false;
}
PDCMachine.removeManufactureData(container);
return true;
}
/**
* machine pdc 에서 플레이어가 투입한 재료 데이터를 전부 제거합니다
* @param container machine pdc 가 저장된 persistent data container
* @return 제거 성공시 true 반환
*/
public static boolean removePlayerInputData(@NotNull PersistentDataContainer container) {
if (!PDCMachine.isMachine(container)) {
return false;
}
PDCMachine.removePlayerInputData(container);
return true;
}
@SuppressWarnings("unchecked")
public static <T> boolean copyAllMachineData(@NotNull PersistentDataContainer from, @NotNull PersistentDataContainer to) {
if (!PDCMachine.isMachine(from)) {
return false;
}
List<Pair<NamespacedKey, ? extends PersistentDataType<?, ?>>> keys = List.of(
Pair.of(PDCMachine.MACHINE_ID_KEY, PersistentDataType.STRING),
Pair.of(PDCMachine.MANUFACTURING_KEY, PersistentDataType.BOOLEAN),
Pair.of(PDCMachine.CURRENT_COMPLETION_KEY, PersistentDataType.INTEGER),
Pair.of(PDCMachine.LAST_INIT_TIME_KEY, PersistentDataType.LONG),
Pair.of(PDCMachine.CURRENT_MANUFACTURING_RECIPE_ID, PersistentDataType.STRING),
Pair.of(MachineDurability.CURRENT_DURABILITY_KEY, PersistentDataType.INTEGER),
Pair.of(InputContainer.PLAYER_INPUTS_KEY, PersistentDataType.LIST.strings()),
Pair.of(FuelContainer.CURRENT_FUEL_KEY, PersistentDataType.INTEGER)
);
for (Pair<NamespacedKey, ? extends PersistentDataType<?, ?>> pair : keys) {
NamespacedKey key = pair.left();
PersistentDataType<?, T> type = (PersistentDataType<?, T>) pair.right();
if (!from.has(key)) {
continue;
}
T data = from.get(key, type);
if (data == null) {
continue;
}
to.set(key, type, data);
}
return true;
}
}