添加轮椅的动画和音效,添加没电时手动操控轮椅
This commit is contained in:
parent
d16a6b29ad
commit
7febbbc028
10 changed files with 1483 additions and 1463 deletions
|
@ -4,10 +4,7 @@ import com.atsuishio.superbwarfare.ModUtils;
|
||||||
import com.atsuishio.superbwarfare.compat.CompatHolder;
|
import com.atsuishio.superbwarfare.compat.CompatHolder;
|
||||||
import com.atsuishio.superbwarfare.compat.clothconfig.ClothConfigHelper;
|
import com.atsuishio.superbwarfare.compat.clothconfig.ClothConfigHelper;
|
||||||
import com.atsuishio.superbwarfare.config.client.ReloadConfig;
|
import com.atsuishio.superbwarfare.config.client.ReloadConfig;
|
||||||
import com.atsuishio.superbwarfare.entity.ICannonEntity;
|
import com.atsuishio.superbwarfare.entity.*;
|
||||||
import com.atsuishio.superbwarfare.entity.IVehicleEntity;
|
|
||||||
import com.atsuishio.superbwarfare.entity.MortarEntity;
|
|
||||||
import com.atsuishio.superbwarfare.entity.SpeedboatEntity;
|
|
||||||
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
||||||
import com.atsuishio.superbwarfare.init.*;
|
import com.atsuishio.superbwarfare.init.*;
|
||||||
import com.atsuishio.superbwarfare.network.ModVariables;
|
import com.atsuishio.superbwarfare.network.ModVariables;
|
||||||
|
@ -94,7 +91,7 @@ public class ClickHandler {
|
||||||
if (player.getMainHandItem().is(ModTags.Items.GUN)
|
if (player.getMainHandItem().is(ModTags.Items.GUN)
|
||||||
|| stack.is(ModItems.MONITOR.get())
|
|| stack.is(ModItems.MONITOR.get())
|
||||||
|| player.hasEffect(ModMobEffects.SHOCK.get())
|
|| player.hasEffect(ModMobEffects.SHOCK.get())
|
||||||
|| (player.getVehicle() != null && player.getVehicle() instanceof IVehicleEntity)) {
|
|| (player.getVehicle() instanceof IVehicleEntity && !(player.getVehicle() instanceof WheelChairEntity))) {
|
||||||
if (button == GLFW.GLFW_MOUSE_BUTTON_LEFT) {
|
if (button == GLFW.GLFW_MOUSE_BUTTON_LEFT) {
|
||||||
event.setCanceled(true);
|
event.setCanceled(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,9 @@ import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.Mth;
|
||||||
import software.bernie.geckolib.cache.object.BakedGeoModel;
|
import software.bernie.geckolib.cache.object.BakedGeoModel;
|
||||||
|
import software.bernie.geckolib.cache.object.GeoBone;
|
||||||
import software.bernie.geckolib.renderer.GeoEntityRenderer;
|
import software.bernie.geckolib.renderer.GeoEntityRenderer;
|
||||||
|
|
||||||
public class WheelChairRenderer extends GeoEntityRenderer<WheelChairEntity> {
|
public class WheelChairRenderer extends GeoEntityRenderer<WheelChairEntity> {
|
||||||
|
@ -40,4 +42,22 @@ public class WheelChairRenderer extends GeoEntityRenderer<WheelChairEntity> {
|
||||||
super.render(entityIn, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn);
|
super.render(entityIn, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn);
|
||||||
poseStack.popPose();
|
poseStack.popPose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderRecursively(PoseStack poseStack, WheelChairEntity animatable, GeoBone bone, RenderType renderType, MultiBufferSource bufferSource, VertexConsumer buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) {
|
||||||
|
String name = bone.getName();
|
||||||
|
if (name.equals("w_rb")) {
|
||||||
|
bone.setRotX(Mth.lerp(partialTick, animatable.rightWheelRotO, animatable.getRightWheelRot()));
|
||||||
|
}
|
||||||
|
if (name.equals("w_lb")) {
|
||||||
|
bone.setRotX(Mth.lerp(partialTick, animatable.leftWheelRotO, animatable.getLeftWheelRot()));
|
||||||
|
}
|
||||||
|
if (name.equals("w_rr")) {
|
||||||
|
bone.setRotX(4 * Mth.lerp(partialTick, animatable.rightWheelRotO, animatable.getRightWheelRot()));
|
||||||
|
}
|
||||||
|
if (name.equals("w_lr")) {
|
||||||
|
bone.setRotX(4 * Mth.lerp(partialTick, animatable.leftWheelRotO, animatable.getLeftWheelRot()));
|
||||||
|
}
|
||||||
|
super.renderRecursively(poseStack, animatable, bone, renderType, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, red, green, blue, alpha);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ import net.minecraft.network.syncher.EntityDataAccessor;
|
||||||
import net.minecraft.network.syncher.EntityDataSerializers;
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||||
import net.minecraft.network.syncher.SynchedEntityData;
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.sounds.SoundEvents;
|
||||||
import net.minecraft.sounds.SoundSource;
|
import net.minecraft.sounds.SoundSource;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
|
@ -27,13 +29,20 @@ import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache
|
||||||
import software.bernie.geckolib.core.animation.AnimatableManager;
|
import software.bernie.geckolib.core.animation.AnimatableManager;
|
||||||
import software.bernie.geckolib.util.GeckoLibUtil;
|
import software.bernie.geckolib.util.GeckoLibUtil;
|
||||||
|
|
||||||
public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity, IVehicleEntity {
|
public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity, IVehicleEntity, IChargeEntity {
|
||||||
|
|
||||||
public static final EntityDataAccessor<Float> POWER = SynchedEntityData.defineId(WheelChairEntity.class, EntityDataSerializers.FLOAT);
|
public static final EntityDataAccessor<Float> POWER = SynchedEntityData.defineId(WheelChairEntity.class, EntityDataSerializers.FLOAT);
|
||||||
|
|
||||||
public static final EntityDataAccessor<Float> HEALTH = SynchedEntityData.defineId(WheelChairEntity.class, EntityDataSerializers.FLOAT);
|
public static final EntityDataAccessor<Float> HEALTH = SynchedEntityData.defineId(WheelChairEntity.class, EntityDataSerializers.FLOAT);
|
||||||
|
public static final EntityDataAccessor<Float> ENERGY = SynchedEntityData.defineId(WheelChairEntity.class, EntityDataSerializers.FLOAT);
|
||||||
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
|
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
|
||||||
public static final float MAX_HEALTH = 50;
|
public static final float MAX_HEALTH = 50;
|
||||||
|
public static final float MAX_ENERGY = 24000;
|
||||||
|
|
||||||
|
public float leftWheelRot;
|
||||||
|
public float rightWheelRot;
|
||||||
|
public float leftWheelRotO;
|
||||||
|
public float rightWheelRotO;
|
||||||
|
|
||||||
public WheelChairEntity(PlayMessages.SpawnEntity packet, Level world) {
|
public WheelChairEntity(PlayMessages.SpawnEntity packet, Level world) {
|
||||||
this(ModEntities.WHEEL_CHAIR.get(), world);
|
this(ModEntities.WHEEL_CHAIR.get(), world);
|
||||||
|
@ -48,6 +57,7 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity,
|
||||||
protected void defineSynchedData() {
|
protected void defineSynchedData() {
|
||||||
this.entityData.define(HEALTH, MAX_HEALTH);
|
this.entityData.define(HEALTH, MAX_HEALTH);
|
||||||
this.entityData.define(POWER, 0f);
|
this.entityData.define(POWER, 0f);
|
||||||
|
this.entityData.define(ENERGY, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -57,11 +67,12 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity,
|
||||||
} else {
|
} else {
|
||||||
this.entityData.set(HEALTH, MAX_HEALTH);
|
this.entityData.set(HEALTH, MAX_HEALTH);
|
||||||
}
|
}
|
||||||
|
compound.putFloat("Energy", this.entityData.get(ENERGY));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readAdditionalSaveData(CompoundTag compound) {
|
public void readAdditionalSaveData(CompoundTag compound) {
|
||||||
|
this.entityData.set(ENERGY, compound.getFloat("Energy"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -128,6 +139,9 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity,
|
||||||
public void baseTick() {
|
public void baseTick() {
|
||||||
super.baseTick();
|
super.baseTick();
|
||||||
|
|
||||||
|
leftWheelRotO = this.getLeftWheelRot();
|
||||||
|
rightWheelRotO = this.getRightWheelRot();
|
||||||
|
|
||||||
this.setDeltaMovement(this.getDeltaMovement().add(0.0, -0.078, 0.0));
|
this.setDeltaMovement(this.getDeltaMovement().add(0.0, -0.078, 0.0));
|
||||||
if (this.onGround()) {
|
if (this.onGround()) {
|
||||||
float f = 0.7f + 0.2f * Mth.abs(90 - (float) calculateAngle(this.getDeltaMovement(), this.getViewVector(1))) / 90;
|
float f = 0.7f + 0.2f * Mth.abs(90 - (float) calculateAngle(this.getDeltaMovement(), this.getViewVector(1))) / 90;
|
||||||
|
@ -143,6 +157,12 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity,
|
||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (level().isClientSide && this.entityData.get(ENERGY) > 0) {
|
||||||
|
level().playLocalSound(this.getX(), this.getY() + this.getBbHeight() * 0.5, this.getZ(), ModSounds.WHEEL_CHAIR_ENGINE.get(), this.getSoundSource(), (float) (0.2 * this.getDeltaMovement().length()), (random.nextFloat() * 0.1f + 0.7f), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setSprinting(this.getDeltaMovement().length() > 0.15);
|
||||||
|
|
||||||
travel();
|
travel();
|
||||||
this.refreshDimensions();
|
this.refreshDimensions();
|
||||||
}
|
}
|
||||||
|
@ -157,26 +177,78 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity,
|
||||||
|
|
||||||
if (this.forwardInputDown) {
|
if (this.forwardInputDown) {
|
||||||
this.entityData.set(POWER, this.entityData.get(POWER) + 0.01f);
|
this.entityData.set(POWER, this.entityData.get(POWER) + 0.01f);
|
||||||
|
if (this.entityData.get(ENERGY) <= 0 && entity instanceof Player player) {
|
||||||
|
moveWithOutPower(player, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.backInputDown) {
|
if (this.backInputDown) {
|
||||||
this.entityData.set(POWER, this.entityData.get(POWER) - 0.01f);
|
this.entityData.set(POWER, this.entityData.get(POWER) - 0.01f);
|
||||||
|
if (this.entityData.get(ENERGY) <= 0 && entity instanceof Player player) {
|
||||||
|
moveWithOutPower(player, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.upInputDown && this.onGround()) {
|
if (this.upInputDown && this.onGround() && this.entityData.get(ENERGY) > 800) {
|
||||||
|
if (entity instanceof ServerPlayer serverPlayer) {
|
||||||
|
serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.WHEEL_CHAIR_JUMP.get(), SoundSource.PLAYERS, 1, 1);
|
||||||
|
}
|
||||||
|
this.entityData.set(ENERGY, this.entityData.get(ENERGY) - 800);
|
||||||
this.setDeltaMovement(this.getDeltaMovement().add(0, 0.58, 0));
|
this.setDeltaMovement(this.getDeltaMovement().add(0, 0.58, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (this.getPersistentData().getBoolean("forward") || this.getPersistentData().getBoolean("backward")) {
|
if (this.forwardInputDown || this.backInputDown) {
|
||||||
// this.entityData.set(ENERGY, Math.max(this.entityData.get(ENERGY) - CannonConfig.SPEEDBOAT_ENERGY_COST.get().floatValue(), 0));
|
this.entityData.set(ENERGY, Math.max(this.entityData.get(ENERGY) - 1, 0));
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
|
||||||
this.entityData.set(POWER, this.entityData.get(POWER) * 0.87f);
|
this.entityData.set(POWER, this.entityData.get(POWER) * 0.87f);
|
||||||
|
|
||||||
if (this.onGround()) {
|
float angle = (float) calculateAngle(this.getDeltaMovement(), this.getViewVector(1));
|
||||||
this.setDeltaMovement(this.getDeltaMovement().add((double)(Mth.sin(-this.getYRot() * 0.017453292F) * this.entityData.get(POWER)), 0.0, (double)(Mth.cos(this.getYRot() * 0.017453292F) * this.entityData.get(POWER))));
|
double s0;
|
||||||
|
|
||||||
|
if (Mth.abs(angle) < 90) {
|
||||||
|
s0 = this.getDeltaMovement().length();
|
||||||
|
} else {
|
||||||
|
s0 = -this.getDeltaMovement().length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setLeftWheelRot((float) (this.getLeftWheelRot() - 0.75 * s0) - 0.015f * Mth.clamp(0.4f * diffY,-5f, 5f));
|
||||||
|
this.setRightWheelRot((float) (this.getRightWheelRot() - 0.75 * s0) + 0.015f * Mth.clamp(0.4f * diffY,-5f, 5f));
|
||||||
|
|
||||||
|
// if (entity instanceof Player player) {
|
||||||
|
// player.displayClientMessage(Component.literal("Angle:" + new java.text.DecimalFormat("##.##").format(this.getRightWheelRot())), true);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (this.onGround()) {
|
||||||
|
this.setDeltaMovement(this.getDeltaMovement().add(Mth.sin(-this.getYRot() * 0.017453292F) * this.entityData.get(POWER), 0.0, Mth.cos(this.getYRot() * 0.017453292F) * this.entityData.get(POWER)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void moveWithOutPower(Player player, boolean forward) {
|
||||||
|
this.entityData.set(POWER, this.entityData.get(POWER) + (forward ? 0.015f : -0.015f));
|
||||||
|
if (player instanceof ServerPlayer serverPlayer) {
|
||||||
|
serverPlayer.level().playSound(null, serverPlayer.getOnPos(), SoundEvents.BOAT_PADDLE_LAND, SoundSource.PLAYERS, 1, 1);
|
||||||
|
}
|
||||||
|
player.causeFoodExhaustion(0.03F);
|
||||||
|
// TODO 手动摇轮椅时像划船一样收起物品
|
||||||
|
this.forwardInputDown = false;
|
||||||
|
this.backInputDown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getLeftWheelRot() {
|
||||||
|
return this.leftWheelRot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeftWheelRot(float pLeftWheelRot) {
|
||||||
|
this.leftWheelRot = pLeftWheelRot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getRightWheelRot() {
|
||||||
|
return this.rightWheelRot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRightWheelRot(float pRightWheelRot) {
|
||||||
|
this.rightWheelRot = pRightWheelRot;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void clampRotation(Entity entity) {
|
protected void clampRotation(Entity entity) {
|
||||||
|
@ -242,4 +314,24 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity,
|
||||||
public int getAmmoCount(Player player) {
|
public int getAmmoCount(Player player) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEnergy() {
|
||||||
|
return this.entityData.get(ENERGY).intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxEnergy() {
|
||||||
|
return (int) MAX_ENERGY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void charge(int amount) {
|
||||||
|
this.entityData.set(ENERGY, Math.min(this.entityData.get(ENERGY) + amount, MAX_ENERGY));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCharge() {
|
||||||
|
return this.entityData.get(ENERGY) < MAX_ENERGY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -350,5 +350,7 @@ public class ModSounds {
|
||||||
|
|
||||||
public static final RegistryObject<SoundEvent> BOAT_ENGINE = REGISTRY.register("boat_engine", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "boat_engine")));
|
public static final RegistryObject<SoundEvent> BOAT_ENGINE = REGISTRY.register("boat_engine", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "boat_engine")));
|
||||||
public static final RegistryObject<SoundEvent> VEHICLE_STRIKE = REGISTRY.register("vehicle_strike", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "vehicle_strike")));
|
public static final RegistryObject<SoundEvent> VEHICLE_STRIKE = REGISTRY.register("vehicle_strike", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "vehicle_strike")));
|
||||||
|
public static final RegistryObject<SoundEvent> WHEEL_CHAIR_ENGINE = REGISTRY.register("wheel_chair_engine", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "wheel_chair_engine")));
|
||||||
|
public static final RegistryObject<SoundEvent> WHEEL_CHAIR_JUMP = REGISTRY.register("wheel_chair_jump", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "wheel_chair_jump")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.network.message;
|
||||||
|
|
||||||
import com.atsuishio.superbwarfare.ModUtils;
|
import com.atsuishio.superbwarfare.ModUtils;
|
||||||
import com.atsuishio.superbwarfare.entity.IVehicleEntity;
|
import com.atsuishio.superbwarfare.entity.IVehicleEntity;
|
||||||
|
import com.atsuishio.superbwarfare.entity.WheelChairEntity;
|
||||||
import com.atsuishio.superbwarfare.init.ModItems;
|
import com.atsuishio.superbwarfare.init.ModItems;
|
||||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||||
import com.atsuishio.superbwarfare.network.ModVariables;
|
import com.atsuishio.superbwarfare.network.ModVariables;
|
||||||
|
@ -52,7 +53,7 @@ public class ZoomMessage {
|
||||||
capability.syncPlayerVariables(player);
|
capability.syncPlayerVariables(player);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (player.isPassenger() && player.getVehicle() instanceof IVehicleEntity) {
|
if (player.isPassenger() && player.getVehicle() instanceof IVehicleEntity && !(player.getVehicle() instanceof WheelChairEntity)) {
|
||||||
SoundTool.playLocalSound(player, ModSounds.CANNON_ZOOM_IN.get(), 2, 1);
|
SoundTool.playLocalSound(player, ModSounds.CANNON_ZOOM_IN.get(), 2, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +65,7 @@ public class ZoomMessage {
|
||||||
capability.syncPlayerVariables(player);
|
capability.syncPlayerVariables(player);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (player.isPassenger() && player.getVehicle() instanceof IVehicleEntity) {
|
if (player.isPassenger() && player.getVehicle() instanceof IVehicleEntity && !(player.getVehicle() instanceof WheelChairEntity)) {
|
||||||
SoundTool.playLocalSound(player, ModSounds.CANNON_ZOOM_OUT.get(), 2, 1);
|
SoundTool.playLocalSound(player, ModSounds.CANNON_ZOOM_OUT.get(), 2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2477,5 +2477,21 @@
|
||||||
"stream": false
|
"stream": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"wheel_chair_engine": {
|
||||||
|
"sounds": [
|
||||||
|
{
|
||||||
|
"name": "superbwarfare:wheel_chair/wheel_chair_engine",
|
||||||
|
"stream": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"wheel_chair_jump": {
|
||||||
|
"sounds": [
|
||||||
|
{
|
||||||
|
"name": "superbwarfare:wheel_chair/wheel_chair_jump",
|
||||||
|
"stream": false
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 4.9 KiB |
Loading…
Add table
Reference in a new issue