/*
* This file is part of LanternServer, licensed under the MIT License (MIT).
*
* Copyright (c) LanternPowered <https://www.lanternpowered.org>
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the Software), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.lanternpowered.server.data.io.store.item;
import org.lanternpowered.server.data.io.store.SimpleValueContainer;
import org.lanternpowered.server.game.Lantern;
import org.lanternpowered.server.game.registry.type.item.FireworkShapeRegistryModule;
import org.lanternpowered.server.item.firework.LanternFireworkShape;
import org.spongepowered.api.data.DataQuery;
import org.spongepowered.api.data.DataView;
import org.spongepowered.api.data.MemoryDataContainer;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.item.FireworkEffect;
import org.spongepowered.api.item.FireworkShape;
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.util.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class FireworkChargeItemTypeObjectSerializer extends ItemTypeObjectSerializer {
private static final DataQuery EXPLOSION = DataQuery.of("Explosion");
private static final DataQuery EXTRA_EXPLOSIONS = DataQuery.of("ExtraExplosions"); // Lantern
@Override
public void serializeValues(ItemStack itemStack, SimpleValueContainer valueContainer, DataView dataView) {
super.serializeValues(itemStack, valueContainer, dataView);
valueContainer.remove(Keys.FIREWORK_EFFECTS).ifPresent(effects -> {
if (!effects.isEmpty()) {
// Also serialize the extra explosion effects
if (effects.size() > 1) {
dataView.set(EXTRA_EXPLOSIONS, effects.subList(1, effects.size()).stream()
.map(FireworkChargeItemTypeObjectSerializer::serializeExplosion).collect(Collectors.toList()));
}
dataView.set(EXPLOSION, serializeExplosion(effects.get(0)));
}
});
}
@Override
public void deserializeValues(ItemStack itemStack, SimpleValueContainer valueContainer, DataView dataView) {
super.deserializeValues(itemStack, valueContainer, dataView);
final Optional<DataView> explosion = dataView.getView(EXPLOSION);
if (explosion.isPresent()) {
final List<FireworkEffect> effects = new ArrayList<>();
effects.add(deserializeExplosion(explosion.get()));
dataView.getViewList(EXTRA_EXPLOSIONS).ifPresent(explosions -> effects.addAll(
explosions.stream().map(FireworkChargeItemTypeObjectSerializer::deserializeExplosion).collect(Collectors.toList())));
valueContainer.set(Keys.FIREWORK_EFFECTS, effects);
}
}
private static final DataQuery FLICKER = DataQuery.of("Flicker");
private static final DataQuery TRAIL = DataQuery.of("Trail");
private static final DataQuery TYPE = DataQuery.of("Type");
private static final DataQuery COLORS = DataQuery.of("Colors");
private static final DataQuery FADE_COLORS = DataQuery.of("FadeColors");
static DataView serializeExplosion(FireworkEffect effect) {
final DataView dataView = new MemoryDataContainer(DataView.SafetyMode.NO_DATA_CLONED);
dataView.set(FLICKER, (byte) (effect.flickers() ? 1 : 0));
dataView.set(TRAIL, (byte) (effect.hasTrail() ? 1 : 0));
dataView.set(TYPE, (byte) ((LanternFireworkShape) effect.getShape()).getInternalId());
dataView.set(COLORS, effect.getColors().stream().mapToInt(Color::getRgb).toArray());
dataView.set(FADE_COLORS, effect.getFadeColors().stream().mapToInt(Color::getRgb).toArray());
return dataView;
}
static FireworkEffect deserializeExplosion(DataView dataView) {
final FireworkEffect.Builder builder = FireworkEffect.builder();
dataView.getInt(FLICKER).ifPresent(v -> builder.flicker(v > 0));
dataView.getInt(TRAIL).ifPresent(v -> builder.trail(v > 0));
final Optional<FireworkShape> shape = FireworkShapeRegistryModule.get().getByInternalId(dataView.getInt(TYPE).get());
if (!shape.isPresent()) {
Lantern.getLogger().warn("Deserialized firework explosion data with unknown shape: {}", dataView.getInt(TYPE).get());
} else {
builder.shape(shape.get());
}
dataView.get(COLORS).ifPresent(array -> {
final int[] iArray = (int[]) array;
builder.colors(Arrays.stream(iArray).mapToObj(Color::ofRgb).collect(Collectors.toList()));
});
dataView.get(FADE_COLORS).ifPresent(array -> {
final int[] iArray = (int[]) array;
builder.fades(Arrays.stream(iArray).mapToObj(Color::ofRgb).collect(Collectors.toList()));
});
return builder.build();
}
}