crwdns154697:0crwdne154697:0

crwdns154699:0crwdne154699:0

crwdns154701:0crwdne154701:0

  1. crwdns154703:0crwdne154703:0

  2. crwdns154705:0crwdne154705:0

crwdns154707:0crwdne154707:0

  1. crwdns154709:0crwdne154709:0

  2. crwdns154711:0crwdne154711:0

  3. crwdns154713:0crwdne154713:0

  4. crwdns154715:0crwdne154715:0

crwdns154717:0crwdne154717:0

Note

crwdns154719:0:doc:crwdne154719:0

crwdns154721:0crwdne154721:0

crwdns154723:0crwdne154723:0

public class SpongeHealthData extends AbstractData<HealthData, ImmutableHealthData> implements HealthData {
    [...]
}

crwdns154725:0crwdne154725:0

crwdns154727:0crwdne154727:0

crwdns154729:0crwdne154729:0

  • crwdns154731:0crwdne154731:0

  • crwdns154733:0crwdne154733:0

crwdns154735:0crwdne154735:0

  • crwdns154737:0crwdne154737:0

  • crwdns154739:0crwdne154739:0

  • crwdns154741:0crwdne154741:0

import static com.google.common.base.Preconditions.checkArgument;

public class SpongeHealthData {

    public SpongeHealthData() {
        this(DataConstants.DEFAULT_HEALTH, DataConstants.DEFAULT_HEALTH);
    }

    public SpongeHealthData(double currentHealth, double maxHealth) {
        super(HealthData.class);
        checkArgument(currentHealth >= DataConstants.MINIMUM_HEALTH && currentHealth <= (double) Float.MAX_VALUE);
        checkArgument(maxHealth >= DataConstants.MINIMUM_HEALTH && maxHealth <= (double) Float.MAX_VALUE);
        this.currentHealth = currentHealth;
        this.maximumHealth = maxHealth;
        this.registerGettersAndSetters();
    }

    ...

}

crwdns154743:0crwdne154743:0

Note

crwdns154745:0crwdne154745:0

crwdns154747:0crwdne154747:0

crwdns154749:0crwdne154749:0

public MutableBoundedValue<Double> health() {
    return SpongeValueFactory.boundedBuilder(Keys.HEALTH)
        .minimum(DataConstants.MINIMUM_HEALTH)
        .maximum(this.maximumHealth)
        .defaultValue(this.maximumHealth)
        .actualValue(this.currentHealth)
        .build();
}

Tip

crwdns154751:0crwdne154751:0

crwdns154753:0crwdne154753:0

crwdns154755:0crwdne154755:0

crwdns154757:0crwdne154757:0

crwdns154759:0crwdne154759:0

public DataContainer toContainer() {
    return new MemoryDataContainer()
        .set(Keys.HEALTH, this.currentHealth)
        .set(Keys.MAX_HEALTH, this.maximumHealth);
}

crwdns154761:0crwdne154761:0

crwdns154763:0crwdne154763:0

  • crwdns154765:0crwdne154765:0

  • crwdns154767:0crwdne154767:0

  • crwdns154769:0crwdne154769:0

crwdns154771:0crwdne154771:0

private void setCurrentHealthIfValid(double value) {
    if (value >= DataConstants.MINIMUM_HEALTH && value <= (double) Float.MAX_VALUE) {
        this.currentHealth = value;
    } else {
        throw new IllegalArgumentException("Invalid value for current health");
    }
}

private void setMaximumHealthIfValid(double value) {
    if (value >= DataConstants.MINIMUM_HEALTH && value <= (double) Float.MAX_VALUE) {
        this.maximumHealth = value;
    } else {
        throw new IllegalArgumentException("Invalid value for maximum health");
    }

}

private void registerGettersAndSetters() {
    registerFieldGetter(Keys.HEALTH, () -> SpongeHealthData.this.currentHealth);
    registerFieldSetter(Keys.HEALTH, SpongeHealthData.this::setCurrentHealthIfValid);
    registerKeyValue(Keys.HEALTH, SpongeHealthData.this::health);

    registerFieldGetter(Keys.MAX_HEALTH, () -> SpongeHealthData.this.maximumHealth);
    registerFieldSetter(Keys.MAX_HEALTH, SpongeHealthData.this::setMaximumHealthIfValid);
    registerKeyValue(Keys.MAX_HEALTH, SpongeHealthData.this::maxHealth);
}

crwdns154773:0crwdne154773:0

Tip

crwdns154775:0crwdne154775:0

crwdns154777:0crwdne154777:0

crwdns154779:0crwdne154779:0

crwdns154781:0crwdne154781:0

crwdns154783:0crwdne154783:0

  • crwdns154785:0crwdne154785:0

  • crwdns154787:0crwdne154787:0

  • crwdns154789:0crwdne154789:0

crwdns154791:0crwdne154791:0

Tip

crwdns154793:0crwdne154793:0

crwdns154795:0crwdne154795:0

crwdns154797:0crwdne154797:0

keyMap.put("health"), makeSingleKey(Double.class, MutableBoundedValue.class, of("Health")));
keyMap.put("max_health", makeSingleKey(Double.class, MutableBoundedValue.class, of("MaxHealth")));

crwdns154799:0crwdne154799:0

crwdns154801:0crwdne154801:0

crwdns154803:0crwdne154803:0

crwdns154805:0crwdne154805:0

crwdns154807:0crwdne154807:0

public class HealthDataProcessor extends AbstractEntityDataProcessor<EntityLivingBase, HealthData, ImmutableHealthData> {
    public HealthDataProcessor() {
        super(EntityLivingBase.class);
    }
    [...]
}

crwdns154809:0crwdne154809:0

Tip

crwdns154811:0crwdne154811:0

crwdns154813:0crwdne154813:0

crwdns154815:0crwdne154815:0

crwdns154817:0crwdne154817:0

crwdns154819:0crwdne154819:0

protected boolean doesDataExist(EntityLivingBase entity) {
    return true;
}

crwdns154821:0crwdne154821:0

crwdns154823:0crwdne154823:0

crwdns154825:0crwdne154825:0

crwdns154827:0crwdne154827:0

protected boolean set(EntityLivingBase entity, Map<Key<?>, Object> keyValues) {
    entity.getEntityAttribute(SharedMonsterAttributes.maxHealth)
        .setBaseValue(((Double) keyValues.get(Keys.MAX_HEALTH)).floatValue());
    entity.setHealth(((Double) keyValues.get(Keys.HEALTH)).floatValue());
    return true;
}

Tip

crwdns154829:0:doc:crwdnd154829:0:javadoc:crwdne154829:0

Warning

crwdns154831:0crwdne154831:0

crwdns154833:0crwdne154833:0

crwdns154835:0crwdne154835:0

crwdns154837:0crwdne154837:0

crwdns154839:0crwdne154839:0

public DataTransactionResult remove(DataHolder dataHolder) {
    return DataTransactionBuilder.failNoData();
}

crwdns154841:0crwdne154841:0

crwdns154843:0crwdne154843:0

crwdns154845:0crwdne154845:0

Warning

crwdns154847:0crwdne154847:0

protected Map<Key<?>, ?> getValues(EntityLivingBase entity) {
    final double health = entity.getHealth();
    final double maxHealth = entity.getMaxHealth();
    return ImmutableMap.<Key<?>, Object>of(Keys.HEALTH, health, Keys.MAX_HEALTH, maxHealth);
}

crwdns154849:0crwdne154849:0

crwdns154851:0crwdne154851:0

crwdns154853:0crwdne154853:0

public Optional<HealthData> fill(DataContainer container, HealthData healthData) {
    final Optional<Double> health = container.getDouble(Keys.HEALTH.getQuery());
    final Optional<Double> maxHealth = container.getDouble(Keys.MAX_HEALTH.getQuery());
    if (health.isPresent() && maxHealth.isPresent()) {
        healthData.set(Keys.HEALTH, health.get());
        healthData.set(Keys.MAX_HEALTH, maxHealth.get());
        return Optional.of(healthData);
    }
    return Optional.empty();
}

crwdns154855:0crwdne154855:0

crwdns154857:0crwdne154857:0

crwdns154859:0crwdne154859:0

crwdns154861:0crwdne154861:0

protected HealthData createManipulator() {
    return new SpongeHealthData();
}

crwdns154863:0crwdne154863:0

crwdns154865:0crwdne154865:0

crwdns154867:0crwdne154867:0

public class HealthValueProcessor extends AbstractSpongeValueProcessor<EntityLivingBase, Double,
    MutableBoundedValue<Double> {

    public HealthValueProcessor() {
        super(EntityLivingBase.class, Keys.HEALTH);
    }

    [...]
}

crwdns154869:0crwdne154869:0

Tip

crwdns154871:0crwdne154871:0

crwdns154873:0crwdne154873:0

protected MutableBoundedValue<Double> constructValue(Double value) {
    return SpongeValueFactory.boundedBuilder(Keys.HEALTH)
        .minimum(DataConstants.MINIMUM_HEALTH)
        .maximum((double) Float.MAX_VALUE)
        .defaultValue(DataConstants.DEFAULT_HEALTH)
        .actualValue(value)
        .build();
}

protected ImmutableValue<Double> constructImmutableValue(Double value) {
    return constructValue(value).asImmutable();
}
protected Optional<Double> getVal(EntityLivingBase container) {
    return Optional.of((double) container.getHealth());
}

crwdns154875:0crwdne154875:0

protected boolean set(EntityLivingBase container, Double value) {
    if (value >= DataConstants.MINIMUM_HEALTH && value <= (double) Float.MAX_VALUE) {
        container.setHealth(value.floatValue());
        return true;
    }
    return false;
}

crwdns154877:0crwdne154877:0

public DataTransactionResult removeFrom(ValueContainer<?> container) {
    return DataTransactionBuilder.failNoData();
}

crwdns154879:0crwdne154879:0

crwdns154881:0crwdne154881:0

crwdns154883:0crwdne154883:0

crwdns154885:0crwdne154885:0

crwdns154887:0crwdne154887:0

dataRegistry.registerDataProcessorAndImpl(HealthData.class, SpongeHealthData.class,
    ImmutableHealthData.class, ImmutableSpongeHealthData.class,
    new HealthDataProcessor());

crwdns154889:0crwdne154889:0

crwdns154891:0crwdne154891:0

dataRegistry.registerValueProcessor(Keys.HEALTH, new HealthValueProcessor());
dataRegistry.registerValueProcessor(Keys.MAX_HEALTH, new MaxHealthValueProcessor());

crwdns154893:0crwdne154893:0

crwdns154895:0crwdne154895:0

@Mixin(BlockHorizontal.class)
public abstract class MixinBlockHorizontal extends MixinBlock {

    [...]
}

crwdns154897:0crwdne154897:0

@Override
public boolean supports(Class<? extends ImmutableDataManipulator<?, ?>> immutable) {
    return super.supports(immutable) || ImmutableDirectionalData.class.isAssignableFrom(immutable);
}

crwdns154899:0crwdne154899:0

@Override
public Optional<BlockState> getStateWithData(IBlockState blockState, ImmutableDataManipulator<?, ?> manipulator) {
    if (manipulator instanceof ImmutableDirectionalData) {
        final Direction direction = ((ImmutableDirectionalData) manipulator).direction().get();
        final EnumFacing facing = DirectionResolver.getFor(direction);
        return Optional.of((BlockState) blockState.withProperty(BlockHorizontal.FACING, facing));
    }
    return super.getStateWithData(blockState, manipulator);
}

crwdns154901:0crwdne154901:0

@Override
public <E> Optional<BlockState> getStateWithValue(IBlockState blockState, Key<? extends BaseValue<E>> key, E value) {
    if (key.equals(Keys.DIRECTION)) {
        final Direction direction = (Direction) value;
        final EnumFacing facing = DirectionResolver.getFor(direction);
        return Optional.of((BlockState) blockState.withProperty(BlockHorizontal.FACING, facing));
    }
    return super.getStateWithValue(blockState, key, value);
}

crwdns154903:0crwdne154903:0

@Override
public List<ImmutableDataManipulator<?, ?>> getManipulators(IBlockState blockState) {
    return ImmutableList.<ImmutableDataManipulator<?, ?>>builder()
            .addAll(super.getManipulators(blockState))
            .add(new ImmutableSpongeDirectionalData(DirectionResolver.getFor(blockState.getValue(BlockHorizontal.FACING))))
            .build();
}

crwdns154905:0crwdne154905:0

crwdns154907:0crwdne154907:0

crwdns154909:0crwdne154909:0