Skip to content
7 changes: 2 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ It is developed based on the last open source version of [NukkitPetteriM1Edition
note: if you need higher version features, please use [PowerNukkitX](https://github.com/PowerNukkitX/PowerNukkitX).

### What's new in Nukkit-MOT?
1. Support for 1.2 – 1.21.60 version (you can set the minimum protocol in the config)
1. Support for 1.2 – 1.21.70 version (you can set the minimum protocol in the config)
2. Supports most entities with AI
3. Support for the nether world and The Еnd
4. Generation of dungeons and caves
Expand Down Expand Up @@ -79,10 +79,7 @@ dependencies {
## Credits
[<img src="https://raw.githubusercontent.com/CloudburstMC/Nukkit/master/.github/images/logo.png" width="18"/>]() [Nukkit](https://github.com/CloudburstMC/Nukkit)
[<img src="https://avatars.githubusercontent.com/u/26197131?v=4" width="18"/>]() [NukkitPetteriM1Edition](https://github.com/PetteriM1/NukkitPetteriM1Edition)
[<img src="https://www.powernukkitx.com/assets/image/PNX_LOGO_sm.png" width="18"/>]() [PowerNukkitX](https://github.com/PowerNukkitX/PowerNukkitX)

[<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.png" width="120"/>](https://jb.gg/OpenSourceSupport)
Thanks to [jetbrains](https://jb.gg/OpenSourceSupport) for providing development tools for this project for free!
[<img src="https://www.powernukkitx.com/assets/image/PNX_LOGO_sm.png" width="18"/>]() [PowerNukkitX](https://github.com/PowerNukkitX/PowerNukkitX)

![YourKit](https://www.yourkit.com/images/yklogo.png)
YourKit supports open source projects with innovative and intelligent tools
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/cn/nukkit/AdventureSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ void update(boolean reset) {
layer.getAbilityValues().add(PlayerAbility.OPERATOR_COMMANDS);
}

layer.setWalkSpeed(Player.DEFAULT_SPEED);
layer.setFlySpeed(Player.DEFAULT_FLY_SPEED);
layer.setVerticalFlySpeed(Player.DEFAULT_VERTICAL_FLY_SPEED);
layer.setWalkSpeed(player.getWalkSpeed());
layer.setFlySpeed(player.getFlySpeed());
layer.setVerticalFlySpeed(player.getVerticalFlySpeed());
packet.getAbilityLayers().add(layer);

if (this.get(Type.NO_CLIP)) {
Expand Down
81 changes: 58 additions & 23 deletions src/main/java/cn/nukkit/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,14 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
public static final int SMITHING_WINDOW_ID = 6;
/**
* @since 649 1.20.60
* 自1.20.60开始,需要发送ContainerOpenPacket给玩家才能正常打开讲台上的书
* 在原版中id按顺序增加,但测试中采用固定id也可正常实现功能
* Starting from 1.20.60, you need to send ContainerOpenPacket to the player to open the book on the podium normally
* In the original version, the id increases in sequence, but in the test, the fixed id can also realize the function normally
*/
public static final int LECTERN_WINDOW_ID = 7;

// 后续创建的窗口应该从此数值开始
/**
* Subsequent windows created should start with this value
*/
public static final int MINIMUM_OTHER_WINDOW_ID = Utils.dynamic(8);

public static final int RESOURCE_PACK_CHUNK_SIZE = 8 * 1024; // 8KB
Expand Down Expand Up @@ -217,7 +219,6 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
protected long randomClientId;

protected Vector3 forceMovement = null;

protected Vector3 teleportPosition = null;

protected int lastTeleportTick = -1;
Expand Down Expand Up @@ -287,6 +288,25 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
*/
public boolean showToOthers = true;

/**
* Player's client-side walk speed. Remember to call getAdventureSettings().update() if changed.
*/
@Getter
@Setter
private float walkSpeed = DEFAULT_SPEED;
/**
* Player's client-side fly speed. Remember to call getAdventureSettings().update() if changed.
*/
@Getter
@Setter
private float flySpeed = DEFAULT_FLY_SPEED;
/**
* Player's client-side vertical fly speed. Remember to call getAdventureSettings().update() if changed.
*/
@Getter
@Setter
private float verticalFlySpeed = DEFAULT_VERTICAL_FLY_SPEED;

private int exp = 0;
private int expLevel = 0;

Expand Down Expand Up @@ -331,7 +351,7 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
private int lastChorusFruitTeleport = 20;
public long lastSkinChange = -1;
private double lastRightClickTime = 0.0;
private Vector3 lastRightClickPos = null;
private BlockVector3 lastRightClickPos = null;
public EntityFishingHook fishing = null;
public boolean formOpen;
public boolean locallyInitialized;
Expand Down Expand Up @@ -4425,13 +4445,11 @@ public void onCompletion(Server server) {
case InventoryTransactionPacket.TYPE_USE_ITEM:
UseItemData useItemData;
BlockVector3 blockVector;
int type;

try {
useItemData = (UseItemData) transactionPacket.transactionData;
blockVector = useItemData.blockPos;
face = useItemData.face;
type = useItemData.actionType;
} catch (Exception ignored) {
break packetswitch;
}
Expand All @@ -4440,14 +4458,14 @@ public void onCompletion(Server server) {
inventory.equipItem(useItemData.hotbarSlot);
}

switch (type) {
switch (useItemData.actionType) {
case InventoryTransactionPacket.USE_ITEM_ACTION_CLICK_BLOCK:
boolean spamming = !server.doNotLimitInteractions
&& lastRightClickPos != null
&& System.currentTimeMillis() - lastRightClickTime < 100.0
&& blockVector.distanceSquared(lastRightClickPos) < 0.00001;

lastRightClickPos = blockVector.asVector3();
lastRightClickPos = blockVector;
lastRightClickTime = System.currentTimeMillis();

// Hack: Fix client spamming right clicks
Expand Down Expand Up @@ -4611,8 +4629,6 @@ public void onCompletion(Server server) {
return;
}

type = useItemOnEntityData.actionType;

if (inventory.getHeldItemIndex() != useItemOnEntityData.hotbarSlot) {
inventory.equipItem(useItemOnEntityData.hotbarSlot);
}
Expand All @@ -4623,8 +4639,17 @@ public void onCompletion(Server server) {

item = this.inventory.getItemInHand();

switch (type) {
switch (useItemOnEntityData.actionType) {
case InventoryTransactionPacket.USE_ITEM_ON_ENTITY_ACTION_INTERACT:
if (this.distanceSquared(target) > 256) { // TODO: Note entity scale
this.getServer().getLogger().debug(username + ": target entity is too far away");
return;
}

this.breakingBlock = null;

this.setUsingItem(false);

PlayerInteractEntityEvent playerInteractEntityEvent = new PlayerInteractEntityEvent(this, target, item, useItemOnEntityData.clickPos);
if (this.isSpectator()) playerInteractEntityEvent.setCancelled();
getServer().getPluginManager().callEvent(playerInteractEntityEvent);
Expand Down Expand Up @@ -4681,13 +4706,13 @@ public void onCompletion(Server server) {
Map<DamageModifier, Float> damage = new EnumMap<>(DamageModifier.class);
damage.put(DamageModifier.BASE, itemDamage);

float knockBack = 0.3f;
float knockBackModifier = 0;
Enchantment knockBackEnchantment = item.getEnchantment(Enchantment.ID_KNOCKBACK);
if (knockBackEnchantment != null) {
knockBack += knockBackEnchantment.getLevel() * 0.1f;
knockBackModifier = knockBackEnchantment.getLevel();
}

EntityDamageByEntityEvent entityDamageByEntityEvent = new EntityDamageByEntityEvent(this, target, DamageCause.ENTITY_ATTACK, damage, knockBack, enchantments);
EntityDamageByEntityEvent entityDamageByEntityEvent = new EntityDamageByEntityEvent(this, target, DamageCause.ENTITY_ATTACK, damage, 0.3F, enchantments, knockBackModifier);
entityDamageByEntityEvent.setBreakShield(item.canBreakShield());
if (this.isSpectator()) entityDamageByEntityEvent.setCancelled();
if ((target instanceof Player) && !this.level.getGameRules().getBoolean(GameRule.PVP)) {
Expand Down Expand Up @@ -4732,8 +4757,7 @@ public void onCompletion(Server server) {
ReleaseItemData releaseItemData = (ReleaseItemData) transactionPacket.transactionData;

try {
type = releaseItemData.actionType;
switch (type) {
switch (releaseItemData.actionType) {
case InventoryTransactionPacket.RELEASE_ITEM_ACTION_RELEASE:
if (this.isUsingItem()) {
item = this.inventory.getItemInHand();
Expand Down Expand Up @@ -4782,6 +4806,7 @@ public void onCompletion(Server server) {
}
return;
default:
this.getServer().getLogger().debug(username + ": unknown release item action type: " + releaseItemData.actionType);
break;
}
} finally {
Expand Down Expand Up @@ -4922,11 +4947,10 @@ private void onBlockBreakComplete(BlockVector3 blockPos, BlockFace face) {
inventory.sendContents(this);
inventory.sendHeldItem(this);

if (blockPos.distanceSquared(this) < 100) {
Block target = this.level.getBlock(blockPos.asVector3());
this.level.sendBlocks(new Player[]{this}, new Block[]{target}, UpdateBlockPacket.FLAG_ALL_PRIORITY);

BlockEntity blockEntity = this.level.getBlockEntity(blockPos.asVector3());
if (blockPos.distanceSquared(this) < 10000) {
Vector3 pos = blockPos.asVector3();
this.level.sendBlocks(this, new Block[]{this.level.getBlock(pos, false)}, UpdateBlockPacket.FLAG_ALL_PRIORITY);
BlockEntity blockEntity = this.level.getBlockEntityIfLoaded(this.chunk, pos);
if (blockEntity instanceof BlockEntitySpawnable) {
((BlockEntitySpawnable) blockEntity).spawnTo(this);
}
Expand Down Expand Up @@ -6284,7 +6308,7 @@ public int showFormWindow(FormWindow window, int id) {
if (formOpen) return -1;
ModalFormRequestPacket packet = new ModalFormRequestPacket();
packet.formId = id;
packet.data = window.getJSONData();
packet.data = window.getJSONData(this.protocol);
this.formWindows.put(packet.formId, window);
this.dataPacket(packet);
this.formOpen = true;
Expand Down Expand Up @@ -7176,6 +7200,17 @@ public void setNoShieldTicks(int noShieldTicks) {
this.noShieldTicks = noShieldTicks;
}

@Override
public void knockBack(Entity attacker, double damage, double deltaX, double deltaZ, double base, double r, double modifier) {
double resistance = 0;
for (Item armor : inventory.getArmorContents()) {
if (armor != null && armor.getTier() == ItemArmor.TIER_NETHERITE) {
resistance += 0.15;
}
}
super.knockBack(attacker, damage, deltaX, deltaZ, base, resistance, modifier);
}

@Override
protected void onBlock(Entity entity, EntityDamageEvent event, boolean animate) {
super.onBlock(entity, event, animate);
Expand Down
Loading