Adjust ids for attributes and set up datafixing for item components and attribute modifiers

This commit is contained in:
Sollace 2024-10-02 20:35:23 +01:00
parent 1617eefa1c
commit bacfa050bb
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
16 changed files with 221 additions and 24 deletions

View file

@ -0,0 +1,29 @@
package com.minelittlepony.unicopia.datafixer;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import net.minecraft.datafixer.fix.AttributeIdFix;
import net.minecraft.util.Util;
public class AttributeIdsFixBuilder {
private final Map<UUID, String> uuids = new HashMap<>();
private final Map<String, String> names = new HashMap<>();
public AttributeIdsFixBuilder add(String uuid, String name, String id) {
uuids.put(UUID.fromString(uuid), id);
names.put(name, id);
return this;
}
public AttributeIdsFixBuilder add(String uuid, String id) {
uuids.put(UUID.fromString(uuid), id);
return this;
}
public void register() {
AttributeIdFix.UUID_TO_ID = Map.copyOf(Util.make(new HashMap<>(AttributeIdFix.UUID_TO_ID), map -> map.putAll(uuids)));
AttributeIdFix.NAME_TO_ID = Map.copyOf(Util.make(new HashMap<>(AttributeIdFix.NAME_TO_ID), map -> map.putAll(names)));
}
}

View file

@ -0,0 +1,36 @@
package com.minelittlepony.unicopia.datafixer;
import com.mojang.datafixers.DataFixerBuilder;
import com.mojang.serialization.Dynamic;
import net.minecraft.datafixer.fix.ItemStackComponentizationFix;
public interface Schemas {
static void build(DataFixerBuilder builder) {
new AttributeIdsFixBuilder()
.add("777a5505-521e-480b-b9d5-6ea54f259564", "Earth Pony Strength", "unicopia:earth_pony_strength")
.add("79e269a8-03e8-b9d5-5853-e25fdcf6706d", "Earth Pony Knockback Resistance", "unicopia:earth_pony_knockback_resistance")
.add("9fc9e269-152e-0b48-9bd5-564a546e59f2", "Earth Pony Mining Speed", "unicopia:earth_pony_mining_speed")
.add("9e2699fc-3b8d-4f71-9d2d-fb92ee19b4f7", "Pegasus Speed", "unicopia:pegasus_speed")
.add("707b50a8-03e8-40f4-8553-ecf67025fd6d", "Pegasus Reach", "unicopia:pegasus_reach")
.add("9e2699fc-3b8d-4f71-92dd-bef19b92e4f7", "Hippogriff Speed", "unicopia:hippogriff_speed")
.add("707b50a8-03e8-40f4-5853-fc7e0f625d6d", "Hippogriff Reach", "unicopia:hippogriff_reach")
.add("79e269a8-03e8-b9d5-5853-e25fdcf6706e", "Kirin Knockback Vulnerability", "unicopia:kirin_knockback_vulneravility")
.add("4991fde9-c685-4930-bbd2-d7a228728bfe", "Kirin Rage Speed", "unicopia:kirin_rage")
.add("7b93803e-4b25-11ed-951e-00155d43e0a2", "Health Swap", "unicopia:health_swap")
.add("7b16994b-1edb-4381-be62-94317f39ec8f", "unicopia:knockback_modifier")
.add("7b16994b-1edb-8431-be62-7f39ec94318f", "unicopia:luck_modifier")
.add("FA235E1C-4280-A865-B01B-CBAE9985ACA3", "unicopia:attack_range_modifier")
.add("A7B3659C-AA74-469C-963A-09A391DCAA0F", "unicopia:attack_range_modifier")
.add("c0a870f5-99ef-4716-a23e-f320ee834b26", "Alicorn Amulet Modifier", "unicopia:alicorn_amulet_modifiers")
.add("5f08c02d-d959-4763-ac84-16e2acfd4b62", "Team Strength", "unicopia:enchantment.team.strength")
.add("a3d5a94f-4c40-48f6-a343-558502a13e10", "Heaviness", "unicopia:enchantment.heaviness")
.add("1734bbd6-1916-4124-b710-5450ea70fbdb", "Anti Grav", "unicopia:enchantment.repulsion")
.add("9dc7818b-927b-46e0-acbe-48d31a28128f", "Bubble Floating", "unicopia:bubble_floating_modifier")
.register();
}
static void fixComponents(ItemStackComponentizationFix.StackData data, Dynamic<?> dynamic) {
UnicopiaItemStackComponentizations.run(data, dynamic);
}
}

View file

@ -0,0 +1,71 @@
package com.minelittlepony.unicopia.datafixer;
import java.util.Set;
import com.mojang.serialization.Dynamic;
import net.minecraft.datafixer.fix.ItemStackComponentizationFix;
final class UnicopiaItemStackComponentizations {
private static final Set<String> ENCHANTED_ITEMS = Set.of(
"unicopia:gemstone",
"unicopia:magic_staff"
);
static void run(ItemStackComponentizationFix.StackData data, Dynamic<?> dynamic) {
if (data.itemEquals("unicopia:friendship_bracelet")) {
data.moveToComponent("glowing", "unicopia:glowing");
data.getAndRemove("issuer_id").result().ifPresent(id -> {
data.setComponent("unicopia:issuer", dynamic.emptyMap()
.set("id", id)
.setFieldIfPresent("name", data.getAndRemove("issuer").result()));
});
}
if (data.itemEquals("unicopia:grogars_bell")) {
fixEnergy(data, dynamic, 1000, 1000);
}
if (data.itemEquals("unicopia:magic_staff")) {
fixEnergy(data, dynamic, 3, 3);
}
if (data.itemEquals("unicopia:pegasus_amulet")) {
fixEnergy(data, dynamic, 900, 450);
}
if (data.itemEquals("unicopia:zap_apple")) {
fixAppearance(data, dynamic, true);
}
if (data.itemEquals("unicopia:filled_jar")) {
fixAppearance(data, dynamic, false);
}
if (data.itemMatches(ENCHANTED_ITEMS)) {
data.moveToComponent("spell", "unicopia:stored_spell");
data.moveToComponent("spell_traits", "unicopia:spell_traits");
}
if (data.itemEquals("unicopia:butterfly")) {
data.moveToComponent("variant", "unicopia:butterfly_variant");
}
if (data.itemEquals("unicopia:giant_balloon")) {
data.moveToComponent("design", "unicopia:balloon_design");
}
if (data.itemEquals("unicopia:spellbook")) {
data.moveToComponent("spellbookState", "unicopia:spellbook_state");
}
}
private static void fixAppearance(ItemStackComponentizationFix.StackData data, Dynamic<?> dynamic, boolean replaceFully) {
data.getAndRemove("appearance").result().ifPresent(appearance -> {
data.setComponent("unicopia:appearance", dynamic.emptyMap()
.set("item", appearance)
.set("replace_fully", dynamic.createBoolean(replaceFully)));
});
}
private static void fixEnergy(ItemStackComponentizationFix.StackData data, Dynamic<?> dynamic, int maximum, int baseline) {
data.getAndRemove("energy").getElement("energy").result().ifPresent(energy -> {
data.setComponent("unicopia:charges", dynamic.emptyMap()
.set("energy", dynamic.createInt((int)energy))
.set("maximum", dynamic.createInt(maximum))
.set("baseline", dynamic.createInt(baseline))
.set("show_in_tooltip", dynamic.createBoolean(true)));
});
}
}

View file

@ -32,7 +32,7 @@ public class HorseShoeItem extends HeavyProjectileItem {
public HorseShoeItem(Item.Settings settings, float projectileDamage, float projectileInnacuracy, float baseProjectileSpeed) { public HorseShoeItem(Item.Settings settings, float projectileDamage, float projectileInnacuracy, float baseProjectileSpeed) {
super(settings.attributeModifiers(AttributeModifiersComponent.builder().add( super(settings.attributeModifiers(AttributeModifiersComponent.builder().add(
UEntityAttributes.EXTENDED_ATTACK_DISTANCE, UEntityAttributes.EXTENDED_ATTACK_DISTANCE,
new EntityAttributeModifier(PolearmItem.ATTACK_RANGE_MODIFIER_ID, -3F, EntityAttributeModifier.Operation.ADD_VALUE), new EntityAttributeModifier(UItemModifierIds.ATTACK_RANGE_MODIFIER_ID, -3F, EntityAttributeModifier.Operation.ADD_VALUE),
AttributeModifierSlot.MAINHAND AttributeModifierSlot.MAINHAND
).build()), projectileDamage); ).build()), projectileDamage);
this.projectileInnacuracy = projectileInnacuracy; this.projectileInnacuracy = projectileInnacuracy;

View file

@ -2,7 +2,6 @@ package com.minelittlepony.unicopia.item;
import java.util.List; import java.util.List;
import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.UTags;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.entity.Living; import com.minelittlepony.unicopia.entity.Living;
import com.minelittlepony.unicopia.entity.mob.UEntityAttributes; import com.minelittlepony.unicopia.entity.mob.UEntityAttributes;
import net.minecraft.block.*; import net.minecraft.block.*;
@ -14,18 +13,15 @@ import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.*; import net.minecraft.entity.attribute.*;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.*; import net.minecraft.item.*;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
public class PolearmItem extends ToolItem { public class PolearmItem extends ToolItem {
static final Identifier ATTACK_RANGE_MODIFIER_ID = Unicopia.id("attack_reach_modifier");
public PolearmItem(ToolMaterial material, int damage, float speed, int range, Settings settings) { public PolearmItem(ToolMaterial material, int damage, float speed, int range, Settings settings) {
super(material, settings.attributeModifiers(SwordItem.createAttributeModifiers(material, damage, speed).with( super(material, settings.attributeModifiers(SwordItem.createAttributeModifiers(material, damage, speed).with(
UEntityAttributes.EXTENDED_REACH_DISTANCE, new EntityAttributeModifier(ATTACK_RANGE_MODIFIER_ID, range, EntityAttributeModifier.Operation.ADD_VALUE), AttributeModifierSlot.MAINHAND UEntityAttributes.EXTENDED_REACH_DISTANCE, new EntityAttributeModifier(UItemModifierIds.ATTACK_RANGE_MODIFIER_ID, range, EntityAttributeModifier.Operation.ADD_VALUE), AttributeModifierSlot.MAINHAND
).with( ).with(
UEntityAttributes.EXTENDED_ATTACK_DISTANCE, new EntityAttributeModifier(ATTACK_RANGE_MODIFIER_ID, range, EntityAttributeModifier.Operation.ADD_VALUE), AttributeModifierSlot.MAINHAND UEntityAttributes.EXTENDED_ATTACK_DISTANCE, new EntityAttributeModifier(UItemModifierIds.ATTACK_RANGE_MODIFIER_ID, range, EntityAttributeModifier.Operation.ADD_VALUE), AttributeModifierSlot.MAINHAND
)).component(DataComponentTypes.TOOL, createToolComponent())); )).component(DataComponentTypes.TOOL, createToolComponent()));
} }

View file

@ -2,7 +2,6 @@ package com.minelittlepony.unicopia.item;
import java.util.List; import java.util.List;
import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.entity.mob.UEntityAttributes; import com.minelittlepony.unicopia.entity.mob.UEntityAttributes;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
@ -23,15 +22,11 @@ import net.minecraft.text.Text;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.util.UseAction; import net.minecraft.util.UseAction;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World; import net.minecraft.world.World;
public class StaffItem extends SwordItem { public class StaffItem extends SwordItem {
protected static final Identifier ATTACK_REACH_MODIFIER_ID = Unicopia.id("attack_reach");
public StaffItem(Settings settings) { public StaffItem(Settings settings) {
super(ToolMaterials.WOOD, settings.attributeModifiers(createAttributeModifiers(2, 3))); super(ToolMaterials.WOOD, settings.attributeModifiers(createAttributeModifiers(2, 3)));
} }
@ -47,7 +42,7 @@ public class StaffItem extends SwordItem {
) )
.add( .add(
UEntityAttributes.EXTENDED_ATTACK_DISTANCE, UEntityAttributes.EXTENDED_ATTACK_DISTANCE,
new EntityAttributeModifier(ATTACK_REACH_MODIFIER_ID, attackReach, EntityAttributeModifier.Operation.ADD_VALUE), new EntityAttributeModifier(UItemModifierIds.ATTACK_RANGE_MODIFIER_ID, attackReach, EntityAttributeModifier.Operation.ADD_VALUE),
AttributeModifierSlot.MAINHAND AttributeModifierSlot.MAINHAND
) )
.build(); .build();

View file

@ -7,4 +7,6 @@ import net.minecraft.util.Identifier;
public interface UItemModifierIds { public interface UItemModifierIds {
Identifier KNOCKBACK_MODIFIER_ID = Unicopia.id("knockback_modifier"); Identifier KNOCKBACK_MODIFIER_ID = Unicopia.id("knockback_modifier");
Identifier LUCK_MODIFIER_ID = Unicopia.id("luck_modifier"); Identifier LUCK_MODIFIER_ID = Unicopia.id("luck_modifier");
Identifier ATTACK_RANGE_MODIFIER_ID = Unicopia.id("attack_range_modifier");
} }

View file

@ -18,7 +18,7 @@ public record Appearance(ItemStack item, boolean replaceFully) {
CodecUtils.xor( CodecUtils.xor(
ItemStack.CODEC, ItemStack.CODEC,
Registries.ITEM.getCodec().xmap(Item::getDefaultStack, ItemStack::getItem) Registries.ITEM.getCodec().xmap(Item::getDefaultStack, ItemStack::getItem)
).fieldOf("stack").forGetter(Appearance::item), ).fieldOf("item").forGetter(Appearance::item),
Codec.BOOL.fieldOf("replace_fully").forGetter(Appearance::replaceFully) Codec.BOOL.fieldOf("replace_fully").forGetter(Appearance::replaceFully)
).apply(instance, Appearance::of)); ).apply(instance, Appearance::of));
public static final PacketCodec<RegistryByteBuf, Appearance> PACKET_CODEC = PacketCodec.tuple( public static final PacketCodec<RegistryByteBuf, Appearance> PACKET_CODEC = PacketCodec.tuple(

View file

@ -21,7 +21,7 @@ public record Charges(int energy, int maximum, int baseline, boolean showInToolt
Codec.INT.fieldOf("energy").forGetter(Charges::energy), Codec.INT.fieldOf("energy").forGetter(Charges::energy),
Codec.INT.optionalFieldOf("maximum", 0).forGetter(Charges::maximum), Codec.INT.optionalFieldOf("maximum", 0).forGetter(Charges::maximum),
Codec.INT.optionalFieldOf("baseline", 0).forGetter(Charges::baseline), Codec.INT.optionalFieldOf("baseline", 0).forGetter(Charges::baseline),
Codec.BOOL.fieldOf("showInTooltip").forGetter(Charges::showInTooltip) Codec.BOOL.fieldOf("show_in_tooltip").forGetter(Charges::showInTooltip)
).apply(instance, Charges::new)); ).apply(instance, Charges::new));
public static final PacketCodec<ByteBuf, Charges> PACKET_CODEC = PacketCodec.tuple( public static final PacketCodec<ByteBuf, Charges> PACKET_CODEC = PacketCodec.tuple(
PacketCodecs.INTEGER, Charges::energy, PacketCodecs.INTEGER, Charges::energy,

View file

@ -202,7 +202,7 @@ public interface UEnchantments {
AttributeModifierSlot.MAINHAND AttributeModifierSlot.MAINHAND
) )
).addEffect(EnchantmentEffectComponentTypes.TICK, new GroupBasedAttributeEnchantmentEffect(new AttributeEnchantmentEffect( ).addEffect(EnchantmentEffectComponentTypes.TICK, new GroupBasedAttributeEnchantmentEffect(new AttributeEnchantmentEffect(
Unicopia.id("team_strength"), Unicopia.id("enchantment.team.strength"),
EntityAttributes.GENERIC_ATTACK_DAMAGE, EntityAttributes.GENERIC_ATTACK_DAMAGE,
EnchantmentLevelBasedValue.linear(0, 1), EnchantmentLevelBasedValue.linear(0, 1),
Operation.ADD_VALUE Operation.ADD_VALUE

View file

@ -11,6 +11,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.minelittlepony.unicopia.entity.duck.PlayerEntityDuck; import com.minelittlepony.unicopia.entity.duck.PlayerEntityDuck;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.EquinePredicates;
import com.minelittlepony.unicopia.entity.Equine; import com.minelittlepony.unicopia.entity.Equine;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
@ -76,11 +77,11 @@ abstract class MixinPlayerEntity extends LivingEntity implements Equine.Containe
get().onDropItem(info.getReturnValue()); get().onDropItem(info.getReturnValue());
} }
@Inject(method = "getActiveEyeHeight(Lnet/minecraft/entity/EntityPose;Lnet/minecraft/entity/EntityDimensions;)F", @ModifyReturnValue(method = "getBaseDimensions(Lnet/minecraft/entity/EntityPose;)Lnet/minecraft/entity/EntityDimensions;", at = @At("RETURN"))
at = @At("RETURN"), private EntityDimensions modifyEyeHeight(EntityDimensions dimensions, EntityPose pose) {
cancellable = true) return get().getMotion().getDimensions().calculateActiveEyeHeight(dimensions).map(eyeHeight -> {
private void onGetActiveEyeHeight(EntityPose pose, EntityDimensions dimensions, CallbackInfoReturnable<Float> info) { return dimensions.withEyeHeight(eyeHeight);
get().getMotion().getDimensions().calculateActiveEyeHeight(dimensions).ifPresent(info::setReturnValue); }).orElse(dimensions);
} }
@Redirect(method = "getDimensions(Lnet/minecraft/entity/EntityPose;)Lnet/minecraft/entity/EntityDimensions;", @Redirect(method = "getDimensions(Lnet/minecraft/entity/EntityPose;)Lnet/minecraft/entity/EntityDimensions;",

View file

@ -0,0 +1,22 @@
package com.minelittlepony.unicopia.mixin.datafix;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import com.mojang.datafixers.DataFixUtils;
import com.mojang.datafixers.DataFixerBuilder;
import com.mojang.datafixers.schemas.Schema;
import it.unimi.dsi.fastutil.ints.Int2ObjectSortedMap;
@Mixin(value = DataFixerBuilder.class, remap = false)
public interface DataFixerBuilderAccessor {
@Accessor
Int2ObjectSortedMap<Schema> getSchemas();
@Nullable
default Schema getSchema(final int version, final int subVersion) {
return getSchemas().get(DataFixUtils.makeKey(version, subVersion));
}
}

View file

@ -0,0 +1,18 @@
package com.minelittlepony.unicopia.mixin.datafix;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mojang.serialization.Dynamic;
import net.minecraft.datafixer.fix.ItemStackComponentizationFix;
@Mixin(ItemStackComponentizationFix.class)
abstract class MixinItemStackComponentizationFix {
@Inject(method = "fixStack", at = @At("TAIL"))
private static void unicopia_fixStack(ItemStackComponentizationFix.StackData data, Dynamic<?> dynamic, CallbackInfo info) {
com.minelittlepony.unicopia.datafixer.Schemas.fixComponents(data, dynamic);
}
}

View file

@ -0,0 +1,18 @@
package com.minelittlepony.unicopia.mixin.datafix;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mojang.datafixers.DataFixerBuilder;
import net.minecraft.datafixer.Schemas;
@Mixin(Schemas.class)
abstract class MixinSchemas {
@Inject(method = "build", at = @At("TAIL"))
private static void unicopia_build(DataFixerBuilder builder, CallbackInfo info) {
com.minelittlepony.unicopia.datafixer.Schemas.build(builder);
}
}

View file

@ -6,12 +6,18 @@ accessible class net/minecraft/client/render/item/HeldItemRenderer$H
accessible class net/minecraft/client/render/VertexConsumers$Union accessible class net/minecraft/client/render/VertexConsumers$Union
accessible class net/minecraft/client/gui/hud/InGameHud$HeartType accessible class net/minecraft/client/gui/hud/InGameHud$HeartType
#accessible method net/minecraft/world/gen/foliage/FoliagePlacerType <init> (Lcom/mojang/serialization/Codec;)V #accessible method net/minecraft/world/gen/foliage/FoliagePlacerType <init> (Lcom/mojang/serialization/Codec;)V
accessible field net/minecraft/entity/mob/CreeperEntity CHARGED Lnet/minecraft/entity/data/TrackedData; accessible field net/minecraft/entity/mob/CreeperEntity CHARGED Lnet/minecraft/entity/data/TrackedData;
accessible field net/minecraft/entity/mob/CreeperEntity IGNITED Lnet/minecraft/entity/data/TrackedData; accessible field net/minecraft/entity/mob/CreeperEntity IGNITED Lnet/minecraft/entity/data/TrackedData;
accessible field net/minecraft/loot/LootTable pools Ljava/util/List; accessible field net/minecraft/loot/LootTable pools Ljava/util/List;
mutable field net/minecraft/loot/LootTable pools Ljava/util/List; mutable field net/minecraft/loot/LootTable pools Ljava/util/List;
accessible method net/minecraft/entity/LightningEntity cleanOxidation (Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V accessible method net/minecraft/entity/LightningEntity cleanOxidation (Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V
accessible class net/minecraft/datafixer/fix/ItemStackComponentizationFix$StackData
accessible field net/minecraft/datafixer/fix/AttributeIdFix UUID_TO_ID Ljava/util/Map;
mutable field net/minecraft/datafixer/fix/AttributeIdFix UUID_TO_ID Ljava/util/Map;
accessible field net/minecraft/datafixer/fix/AttributeIdFix NAME_TO_ID Ljava/util/Map;
mutable field net/minecraft/datafixer/fix/AttributeIdFix NAME_TO_ID Ljava/util/Map;

View file

@ -54,6 +54,9 @@
"MixinWardenEntity", "MixinWardenEntity",
"MixinWorld", "MixinWorld",
"PointOfInterestTypesAccessor", "PointOfInterestTypesAccessor",
"datafix.MixinSchemas",
"datafix.MixinItemStackComponentizationFix",
"datafix.DataFixerBuilderAccessor",
"server.MixinEntityTrackerEntry", "server.MixinEntityTrackerEntry",
"server.MixinPathNodeMaker", "server.MixinPathNodeMaker",
"server.MixinPlayerManager", "server.MixinPlayerManager",