Coder Social home page Coder Social logo

minestompvp's Introduction

MinestomPvP

standard-readme compliant license platform

MinestomPvP is an extension for Minestom. It tries to mimic vanilla (and pre-1.9) PvP as good as possible, while also focusing on customizability and usability.

But, MinestomPvP does not only provide PvP, it also provides everything around it (e.g., status effects and food). You can easily choose which features you want to use.

The maven repository is available on jitpack.

You might not want to put this extension in your extensions folder, more information at usage.

Table of Contents

Features

Currently, most vanilla PvP features are supported.

  • Attack cooldown
  • Damage invulnerability
  • Weapons
  • Armor
  • Shields (or sword blocking)
  • Food
  • Totems
  • Bows and crossbows
  • Tridents (with riptide or loyalty)
  • Fishing rods (only hooking entities or legacy knockback, not fishing)
  • Other projectiles (potions, snowballs, eggs, ender pearls)
  • All enchantments possible with the above features (this includes protection, sharpness, knockback, ...)
  • Fall damage
  • End crystals
  • TNT
  • Respawn anchors (explosion only)

Plans

  • Lingering potions
  • Fireworks (for crossbows)
  • Projectile collision might need some improvements

Usage

One way to use this extension is by simply putting the jar inside your servers extensions folder. This will apply PvP mechanics to your whole server.

But you can also choose to (and this is the preferred option for most servers) use the jar file as a library. In this case, you can choose where to apply the PvP mechanics and customize them. The rest of this readme assumes you are using this method.

Before doing anything else, you should call PvpExtension.init(). This will make sure everything is registered correctly. After you've initialized the extension, you can get an EventNode with all PvP related events listening using PvpExtension.events(). By adding this node as a child to any other node, you enable pvp in that scope.

Example (adds PvP to the global event handler, so everywhere):

PvpExtension.init();
MinecraftServer.getGlobalEventHandler().addChild(PvpExtension.events());

You can customize which features of this extension you want to enable or disable by using PvPConfig. Obtain a builder by using one of the static methods of PvPConfig: #defaultBuilder() (returns a builder with the default options), #legacyBuilder() (returns a builder with the legacy options) or #emptyBuilder() (has everything disabled by default). You can add custom settings to it by using the methods of the builder. To create an EventNode from your config builder, use #build().createNode().

Example:

eventHandler.addChild(
    PvPConfig.emptyBuilder()
        .potion(PotionConfig.legacyBuilder().drinking(false))
        .build().createNode()
);

Which would result in potion effects and splash potions still working, but not drinkable potions. Everything else not to do with potions would be disabled as well, since you are using PvPConfig.emptyBuilder().

Legacy PvP

You can get the EventNode for legacy PvP using PvpExtension.legacyEvents(), and adjust its settings by using the method described above.

To disable attack cooldown for a player and set their attack damage to the legacy value, use PvpExtension.setLegacyAttack(player, true). To enable the cooldown again and set the attack damage to the new value, use false instead of true.

Knockback

A lot of servers like to customize their 1.8 knockback. It is also possible to do so with this extension. In EntityKnockbackEvent, you can set a LegacyKnockbackSettings object. It contains information about how the knockback is calculated. A builder is obtainable by using LegacyKnockbackSettings.builder(). For more information, check the config of BukkitOldCombatMechanics.

Integration

To integrate this extension into your minestom server, you may have to tweak a little bit to make sure everything works correctly.

When applying damage to an entity, use CustomDamageType instead of DamageType. If you have your own damage type, also extend CustomDamageType instead of DamageType.

Potions and milk buckets are considered food: the Minestom food events are also called for drinkable items.

The extension uses a custom player implementation, if you use one, it is recommended to extend CustomPlayer. If you for some reason can't, make sure to implement PvpPlayer. The implementation is registered inside PvpExtension.init(), so register yours after the call.

To allow explosions, you have to register PvpExplosionSupplier to every instance in which they are used.

instance.setExplosionSupplier(PvpExplosionSupplier.INSTANCE);

Events

This extension provides several events:

  • DamageBlockEvent: cancellable, called when an entity blocks damage using a shield. This event can be used to set the remaining damage.
  • EntityKnockbackEvent: cancellable, called when an entity gets knocked back by another entity. Gets called twice for weapons with the knockback enchantment (once for default damage knockback, once for the extra knockback). This event can be used to set the knockback strength.
  • EntityPreDeathEvent: cancellable, a form of EntityDeathEvent but cancellable and with a damage type. Can be used to cancel the death while still applying after-damage effects, such as attack sounds.
  • EquipmentDamageEvent: cancellable, called when an item in an equipment slot gets damaged.
  • ExplosionEvent: cancellable, called when an explosion will take place. Can be used to modify the affected blocks.
  • FinalAttackEvent: cancellable, called when a player attacks an entity. Can be used to set a few variables like sprint, critical, sweeping, etc.
  • FinalDamageEvent: cancellable, called when the final damage calculation (including armor and effects) is completed. This event should be used instead of EntityDamageEvent, unless you want to detect how much damage was originally dealt.
  • LegacyKnockbackEvent: cancellable, called when an entity gets knocked back by another entity using legacy pvp. Same applies as for EntityKnockbackEvent. This event can be used to change the knockback settings.
  • PickupEntityEvent: cancellable, called when a player picks up an entity (arrow or trident).
  • PlayerExhaustEvent: cancellable, called when a players' exhaustion level changes.
  • PlayerRegenerateEvent: cancellable, called when a player naturally regenerates health.
  • PlayerSpectateEvent: cancellable, called when a spectator tries to spectate an entity by attacking it.
  • PotionVisibilityEvent: cancellable, called when an entities potion state (ambient, particle color and invisibility) is updated.
  • ProjectileBlockHitEvent: called when a projectile hits a block.
  • ProjectileEntityHitEvent: cancellable, called when a projectile hits an entity.
  • TotemUseEvent: cancellable, called when a totem prevents an entity from dying.

Customization

It is possible to add your own features to this extension. For example, you can extend the current enchantment behavior by registering an enchantment using CustomEnchantments. This will provide you with a few methods for when the enchantment is used. It is also possible to do the same for potion effects using CustomPotionEffects, which will provide you with a few methods for when the effect is applied and removed.

You can use the class Tool, which contains all tools and their properties (not all properties are currently included, will change soon). The same applies for ToolMaterial (wood, stone, ...) and ArmorMaterial.

Contributing

You can contribute in multiple ways. If you have an issue or a great idea, you can open an issue. You may also open a new pull request if you have made something for this project and you think it will fit in well.

If anything does not integrate with your project, you can also open an issue (or submit a pull request). I aim towards making this extension as usable as possible!

Credits

Thanks to kiip1 for testing and finding bugs.

I used BukkitOldCombatMechanics as a resource for recreating legacy pvp.

minestompvp's People

Contributors

codestech1 avatar hsgamer avatar kiip1 avatar secretagent-yt avatar themode avatar togar2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

minestompvp's Issues

Snowballs can get stuck inside blocks

When player crouches and shoots snowball at pitch more than 60, snowball will get stuck in block without removing itself.
Upon removing block, snowball starts falling again and can interact with blocks normally.

ProjectileCollideWithBlockEvent not called when projectiles implemented wih minestompvp

I have a listener for ProjectileCollideWithBlockEvent, however it is not called when I throw a snowball (even though I have it implemented with this code:)

node.addChild(
			PvPConfig
				.emptyBuilder()
				.projectile(ProjectileConfig.emptyBuilder(false).snowball(true).build())
				.build().createNode()
		)

I need to use this event as opposed to the ProjectileBlockHitEvent, because that class does not contain things I need like collissionPosition and block.

Error

java.lang.NoSuchMethodError: 'void net.minestom.server.network.packet.server.play.SoundEffectPacket.(net.minestom.server.sound.SoundEvent, net.kyori.adventure.sound.Sound$Source, net.minestom.server.coordinate.Point, float, float)'
at Ext_PvpExtension//io.github.bloepiloepi.pvp.listeners.DamageListener.handleEntityDamage(DamageListener.java:377)
at Ext_PvpExtension//io.github.bloepiloepi.pvp.listeners.DamageListener.lambda$events$0(DamageListener.java:56)
at net.minestom.server.event.EventListener$Builder$1.run(EventListener.java:151)
at net.minestom.server.event.EventNodeImpl$Handle.callListener(EventNodeImpl.java:488)
at net.minestom.server.event.EventNodeImpl$Handle.lambda$listenersConsumer$8(EventNodeImpl.java:420)
at net.minestom.server.event.EventNodeImpl$Handle.lambda$createConsumer$5(EventNodeImpl.java:391)
at net.minestom.server.event.EventNodeImpl$Handle.lambda$createConsumer$5(EventNodeImpl.java:399)
at net.minestom.server.event.EventNodeImpl$Handle.lambda$createConsumer$5(EventNodeImpl.java:399)
at net.minestom.server.event.EventNodeImpl$Handle.lambda$createConsumer$5(EventNodeImpl.java:399)
at net.minestom.server.event.EventNodeImpl$Handle.call(EventNodeImpl.java:324)
at net.minestom.server.event.EventNode.call(EventNode.java:190)
at net.minestom.server.event.EventNode.callCancellable(EventNode.java:215)
at net.minestom.server.event.EventDispatcher.callCancellable(EventDispatcher.java:18)
at net.minestom.server.entity.LivingEntity.damage(LivingEntity.java:340)
at Ext_PvpExtension//io.github.bloepiloepi.pvp.listeners.FallDamageHandler.handleFallDamage(FallDamageHandler.java:81)
at Ext_PvpExtension//io.github.bloepiloepi.pvp.listeners.DamageListener.lambda$events$2(DamageListener.java:72)
at net.minestom.server.event.EventListener$Builder$1.run(EventListener.java:151)
at net.minestom.server.event.EventNodeImpl$Handle.callListener(EventNodeImpl.java:488)
at net.minestom.server.event.EventNodeImpl$Handle.lambda$listenersConsumer$8(EventNodeImpl.java:420)
at net.minestom.server.event.EventNodeImpl$Handle.lambda$createConsumer$5(EventNodeImpl.java:391)
at net.minestom.server.event.EventNodeImpl$Handle.lambda$createConsumer$5(EventNodeImpl.java:399)
at net.minestom.server.event.EventNodeImpl$Handle.lambda$createConsumer$5(EventNodeImpl.java:399)
at net.minestom.server.event.EventNodeImpl$Handle.lambda$createConsumer$5(EventNodeImpl.java:399)
at net.minestom.server.event.EventNodeImpl$Handle.call(EventNodeImpl.java:324)
at net.minestom.server.event.EventNode.call(EventNode.java:190)
at net.minestom.server.event.EventDispatcher.call(EventDispatcher.java:10)
at net.minestom.server.listener.PlayerPositionListener.processMovement(PlayerPositionListener.java:57)
at net.minestom.server.listener.PlayerPositionListener.playerPositionListener(PlayerPositionListener.java:24)
at net.minestom.server.listener.manager.PacketListenerManager.processClientPacket(PacketListenerManager.java:90)
at net.minestom.server.entity.Player.lambda$interpretPacketQueue$16(Player.java:1808)
at org.jctools.queues.MpscUnboundedXaddArrayQueue.drain(MpscUnboundedXaddArrayQueue.java:312)
at net.minestom.server.entity.Player.interpretPacketQueue(Player.java:1808)
at net.minestom.server.entity.Player.update(Player.java:345)
at net.minestom.server.entity.Entity.tick(Entity.java:541)
at net.minestom.server.thread.TickThread.tick(TickThread.java:66)
at net.minestom.server.thread.TickThread.run(TickThread.java:41)

Knockback in water no less

Players get exactly the same knockback in water as if the water is not there. In Vanilla the player gets less knockback in the water

Events for Explosion Damage on Blocks & Players

  • Some events that give a list of affected blocks so that developers can remove some of the blocks (like protection blocks).
  • The knockback will not be applied to the player if the player's damage event is cancelled.

FinallAttack Bug?

Hello, I have the following problem...
If I want to hit a player it only works 2-3 times then it doesn't work anymore. It only works if the player I want to hit gets damaged again by something else (e.g. falling damage) In my opinion this is not normal xD

No support for the latest Minestom version

Hey, I tried to use this on my Minestom CE server and it sadly failed to work. The Extension class isn't present in the latest Minestom versions anymore. Can you look at that?

EntityDamageEvent is always cancelled

Line 134 of the DamageListener.java class will consistently cancel the DamageEvent.

    @Override
    public void setCancelled(boolean cancel) {
        StackFrame frame = StackWalker.getInstance().walk(stream -> stream.skip(1).findFirst().get());
        System.out.println("DamageEvent Cancellation changed by "
                + frame.getFileName() + ":" + frame.getLineNumber() + " to "
                + cancel);
        this.cancelled = cancel;
    }

During testing, I compiled a custom Minestom version that changes the setCancelled function of the EntityDamageEvent to the above code- effectively printing out whenever the value was changed, and by what.

In my own code, I listened to the EntityDamageEvent with a priority of -1 to run this;

System.out.println("Damage event " + event.getDamage() + " Cancelled? " + event.isCancelled()
					+ " Tracker Invuln " + Tracker.invulnerableTime.get(event.getEntity().getUuid())
					+ " Last Dmg " + Tracker.lastDamageTaken.getOrDefault(event.getEntity().getUuid(), -1f) + "");

This gives the following output; (using a Diamond Sword against another player)

Damage event 1.61024 Cancelled? false Tracker Invuln 20 Last Dmg 10.525438

DamageEvent Cancellation changed by DamageListener.java:134 to true

PvP code is started as so, and MinestomPvP is used as an extension, compiled from Jitpack's Maven Repo. Happy to attach anything else that is needed/debug further.

GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
EventNode<EntityEvent> pvpEvents = PvpExtension.events();
globalEventHandler.addChild(pvpEvents);

Feel free to DM on Discord- Gatt#0010

Checking which block snowball hits

There is no way to get position of hit block from ProjectileBlockHitEvent.
For projectiles with hitanticipation, there is no way to tell hit block location, because it is calculated as pos.add(velocity*0.06), but at time of event firing, velocity is already set to zero.

Maven Repo

I'm looking into using the MinestomPvP API in my server but can't seem to find a Maven/Gradle repository to do so. What's the recommended way to hook into the API?

Question: Adding PVP-Events only to specific instance

Hey, I'm trying to get get PVP on an specific instance working.

Minestom's eventNode.appendChild within an Instance accepts as an Parameter
EventNode<? extends InstanceEvent>

MinestomPvp returs from PvpExtension.legacyEvents() or the new Builder EventNode <EntityEvent>

In all examples are always global event listener used, is there a way to register pvp events on specific Instances or even only players?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.