Skip to content

Commit

Permalink
Start
Browse files Browse the repository at this point in the history
First Commit of the plugin in github
  • Loading branch information
RitoOFF authored Aug 29, 2024
1 parent 47ce41e commit d455c56
Show file tree
Hide file tree
Showing 10 changed files with 436 additions and 0 deletions.
6 changes: 6 additions & 0 deletions plugin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: rPvp
api: 5.0.0
version: 1.0.0
author: Rito
description: "Hi, this is a plugin that remakes the Java PvP of version 1.9 on the Pocketmine software, called PvpJava this plugin contains the cooldown to hit, the scanning edge, knockback hit, critical hit, sprint hit, arc punch and even casual exchange."
main: Rito\rPvpJava\Main
36 changes: 36 additions & 0 deletions src/Rito/rPvpJava/Loader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Rito\rPvpJava;


use pocketmine\entity\EntityDataHelper;
use pocketmine\entity\EntityFactory;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\world\World;
use Rito\rPvpJava\entity\CustomArrow;
use Rito\rPvpJava\listener\AttackListener;
use Rito\rPvpJava\listener\EventListener;

trait Loader
{
public function init(): void
{
$main = Main::getInstance();
$main->getResource("config.yml");
$main->saveDefaultConfig();

$listeners = [
new AttackListener(),
new EventListener()
];

foreach ($listeners as $listener) {
$main->getServer()->getPluginManager()->registerEvents($listener, $this);
}

EntityFactory::getInstance()->register(CustomArrow::class, function(World $world, CompoundTag $nbt): CustomArrow {
return new CustomArrow(EntityDataHelper::parseLocation($nbt, $world), null,false, $nbt);
}, ["custom_arrow", "minecraft:custom_arrow"]);

}
}
30 changes: 30 additions & 0 deletions src/Rito/rPvpJava/Main.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php


namespace Rito\rPvpJava;

use pocketmine\plugin\PluginBase;
use pocketmine\utils\SingletonTrait;

class Main extends PluginBase{

use SingletonTrait;
use Loader;

protected function onLoad(): void
{
self::setInstance($this);
}

public function onEnable(): void
{
self::$instance = $this;
$this->init();
$this->getLogger()->notice("ENABLE -> Plugin rPvpJava BY RITO | discord: rito.off");

}
public function onDisable(): void
{
$this->getLogger()->notice("DISABLE -> Plugin rPvpJava BY RITO | discord: rito.off");
}
}
35 changes: 35 additions & 0 deletions src/Rito/rPvpJava/entity/CustomArrow.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Rito\rPvpJava\entity;

use pocketmine\entity\animation\HurtAnimation;
use pocketmine\entity\projectile\Arrow;
use pocketmine\player\Player;

class CustomArrow extends Arrow {

public function onUpdate(int $currentTick): bool {
$hasUpdate = parent::onUpdate($currentTick);

if(!$this->isClosed() && !$this->isFlaggedForDespawn()) {
$owner = $this->getOwningEntity();
if($owner instanceof Player) {
foreach($this->getWorld()->getEntities() as $entity) {
if($entity instanceof Player && $entity->getId() === $owner->getId() && $entity->getPosition()->distanceSquared($this->getPosition()) < 1) {

$entity->setMotion($entity->getDirectionVector()->multiply(1));
if ($entity->getHealth() > 1.0) {
$entity->setHealth($entity->getHealth() - 1.0);
}
$entity->broadcastAnimation(new HurtAnimation($entity));

$this->flagForDespawn();
break;
}
}
}
}

return $hasUpdate;
}
}
140 changes: 140 additions & 0 deletions src/Rito/rPvpJava/listener/AttackListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php

namespace Rito\rPvpJava\listener;

use pocketmine\entity\Entity;
use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\Listener;
use pocketmine\item\Axe;
use pocketmine\item\Sword;
use pocketmine\item\VanillaItems;
use pocketmine\math\Vector3;
use pocketmine\player\Player;
use Rito\rPvpJava\Main;
use Rito\rPvpJava\player\CustomPlayer;
use Rito\rPvpJava\sound\SweepSound;
use Rito\rPvpJava\task\CooldownAttackTask;
use Rito\rPvpJava\utils\Utils;

class AttackListener implements Listener
{
public static array $cooldownAttack = [];

private const DAMAGE_PERCENTAGES = [1, 0.92, 0.8, 0.7, 0.6, 0.54, 0.43, 0.36, 0.33, 0.2];


public function onEntityDamage(EntityDamageByEntityEvent $event) : void
{
$entity = $event->getEntity();
if ($entity instanceof CustomPlayer) {
$event->setAttackCooldown(0.4);
}
}

public function onDamage(EntityDamageEvent $event): void {
$entity = $event->getEntity();

if ($event->getModifier(EntityDamageEvent::MODIFIER_CRITICAL) > 0) {
$event->cancel();
}

if ($event instanceof EntityDamageByEntityEvent) {
$damager = $event->getDamager();
if (!$damager instanceof Player) return;

$itemInHand = $damager->getInventory()->getItemInHand();
$typeId = $itemInHand->getTypeId();
$cooldownDurations = [
VanillaItems::DIAMOND_SWORD()->getTypeId() => 0.6,
VanillaItems::IRON_SWORD()->getTypeId() => 0.6,
VanillaItems::WOODEN_SWORD()->getTypeId() => 0.6,
VanillaItems::GOLDEN_SWORD()->getTypeId() => 0.6,
VanillaItems::NETHERITE_SWORD()->getTypeId() => 0.6,
VanillaItems::STONE_SWORD()->getTypeId() => 0.6,
VanillaItems::WOODEN_AXE()->getTypeId() => 1.25,
VanillaItems::STONE_AXE()->getTypeId() => 1.25,
VanillaItems::IRON_AXE()->getTypeId() => 1.1,
];
$cooldownDuration = $cooldownDurations[$typeId] ?? 1;

$damagerName = $damager->getName();

if (isset(self::$cooldownAttack[$damagerName])) {
$timeLeft = self::$cooldownAttack[$damagerName] - time();

if (!$timeLeft > 0) {
unset(self::$cooldownAttack[$damagerName]);
return;
}

$index = min(intval(($timeLeft / $cooldownDuration) * count(self::DAMAGE_PERCENTAGES)), count(self::DAMAGE_PERCENTAGES) - 1);
if (!isset(self::DAMAGE_PERCENTAGES[$index])){
return;
}
$damageMultiplier = self::DAMAGE_PERCENTAGES[$index];
$event->setBaseDamage(($event->getBaseDamage() * $damageMultiplier) / 4);

} else {
$event->setBaseDamage($event->getBaseDamage() - 2);
self::$cooldownAttack[$damagerName] = time() + $cooldownDuration;
}

if (!$damager->isOnGround() && !$damager->isUnderwater()) {
$event->setModifier($event->getBaseDamage(), EntityDamageEvent::MODIFIER_CRITICAL);
Utils::spawnParticleCritical($entity->getWorld(), $entity->getLocation());
}

if ($itemInHand instanceof Sword && $damager->isOnGround() && !$damager->isUnderwater() && !$damager->isSprinting()) {
$this->handleSweepAttack($damager, $entity);
}
if ($damager->isSprinting() && !$damager->isOnGround() && !$damager->isUnderwater()){
$this->handleSprintAttack($damager, $entity);
}

Main::getInstance()->getScheduler()->scheduleRepeatingTask(new CooldownAttackTask(), 20);
$this->sendUnicodeActionBar($damager);
}
}

private function handleSprintAttack(Player $damager, Entity $entity): void{
if ($damager->getInventory()->getItemInHand() instanceof Axe or $damager->getInventory()->getItemInHand() instanceof Sword) {
$directionVector = $entity->getPosition()->subtract($damager->getPosition()->x, $damager->getPosition()->y, $damager->getPosition()->z)->normalize();
$entity->setMotion($entity->getMotion()->add($directionVector->multiply(1)->x, $directionVector->multiply(1)->y,$directionVector->multiply(1)->z));
}
}
private function handleSweepAttack(Player $damager, Entity $entity): void
{
$position = $damager->getPosition();
$direction = $damager->getLocation()->getYaw() * (M_PI / 180);
$offsetX = -sin($direction) * 2;
$offsetZ = cos($direction) * 2;
$sweepPosition = new Vector3($position->getX() + $offsetX, $position->getY() + 0.2, $position->getZ() + $offsetZ);

Utils::spawnParticleSweep($damager->getWorld(), $sweepPosition);
$damager->broadcastSound(new SweepSound());

$nearbyEntities = $damager->getWorld()->getNearbyEntities($entity->getBoundingBox()->expandedCopy(1.5, 1.5, 1.5));
foreach ($nearbyEntities as $nearbyEntity) {
if ($nearbyEntity->getId() === $damager->getId() || $nearbyEntity->getId() === $entity->getId()) {
continue;
}

$damage = 3 * (mt_rand(50, 75) / 100);
$nearbyEntity->attack(new EntityDamageEvent($nearbyEntity, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $damage));

$directionVector = $nearbyEntity->getPosition()->subtract($position->x, $position->y, $position->z)->normalize();
$nearbyEntity->setMotion($nearbyEntity->getMotion()->add($directionVector->multiply(1)->x, $directionVector->multiply(1)->y,$directionVector->multiply(1)->z));
}
}

private function sendUnicodeActionBar(Player $player): void
{
$unicodeMessage = "";
// $player->sendActionBarMessage($unicodeMessage);

foreach (str_split($unicodeMessage) as $unicode) {
$player->sendActionBarMessage($unicode);
}
}
}
62 changes: 62 additions & 0 deletions src/Rito/rPvpJava/listener/EventListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

namespace Rito\rPvpJava\listener;

use pocketmine\entity\Location;
use pocketmine\entity\projectile\Arrow;
use pocketmine\event\entity\EntityShootBowEvent;
use pocketmine\event\Listener;
use pocketmine\event\player\PlayerItemUseEvent;
use pocketmine\item\enchantment\VanillaEnchantments;
use pocketmine\item\VanillaItems;
use Rito\rPvpJava\entity\CustomArrow;

class EventListener implements Listener
{
public function onItemUse(PlayerItemUseEvent $event): void
{
$player = $event->getPlayer();
$item = $event->getItem();
$swap = [
VanillaItems::ARROW()->getTypeId(),
VanillaItems::TOTEM()->getTypeId()
];
if (in_array($item->getTypeId(),$swap)){
$offHand = $player->getOffHandInventory()->getItem(0);
$invHand = $player->getInventory()->getItemInHand();
$player->getOffHandInventory()->setItem(0, $invHand);
$player->getInventory()->setItemInHand($offHand);
}
}
public function onShootBow(EntityShootBowEvent $event): void {
$shooter = $event->getEntity();
$bow = $event->getBow();
$power = $event->getForce();

var_dump($bow->getEnchantments());
if (!$bow->hasEnchantment(VanillaEnchantments::PUNCH())) return;
$projectile = $event->getProjectile();
if($projectile instanceof Arrow) {
if ($power <= 0.8 ) {
if (!$shooter->getMovementSpeed() >= 0.0){
$event->cancel();
$baseForce = min(((5 ** 2) + 5 * 2) / 3, 1);

$direction = $shooter->getDirectionVector();
$positionDerriere = new Location(
$shooter->getLocation()->getX() - $direction->x * 2,
$shooter->getLocation()->getY() - $direction->y * 2,
$shooter->getLocation()->getZ() - $direction->z * 2,
$shooter->getLocation()->getWorld(),
$shooter->getLocation()->getYaw(),
$shooter->getLocation()->getPitch()
);
$customArrow = new CustomArrow($positionDerriere, $shooter, $baseForce >= 1);
$customArrow->setMotion($shooter->getDirectionVector());
$customArrow->spawnToAll();
}
}
}
}

}
37 changes: 37 additions & 0 deletions src/Rito/rPvpJava/player/CustomPlayer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Rito\rPvpJava\player;

use pocketmine\entity\Attribute;
use pocketmine\player\Player;
class CustomPlayer extends Player {

public function knockBack(float $x, float $z, float $force = 0.4, ?float $verticalLimit = 0.4): void
{
$xKB = (float)"2.70";
$yKB = (float)"0.05";

$f = sqrt($x * $x + $z * $z);
if ($f <= 0) {
return;
}
if (mt_rand() / mt_getrandmax() > $this->getAttributeMap()->get(Attribute::KNOCKBACK_RESISTANCE)->getValue()) {
$f = 1 / $f;

$motion = clone $this->motion;

$motion->x /= 2;
$motion->y /= 2;
$motion->z /= 2;
$motion->x += $x * $f * $xKB;
$motion->y += $yKB;
$motion->z += $z * $f * $xKB;

if ($motion->y > $yKB) {
$motion->y = $yKB;
}

$this->setMotion($motion);
}
}
}
15 changes: 15 additions & 0 deletions src/Rito/rPvpJava/sound/SweepSound.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Rito\rPvpJava\sound;

use pocketmine\math\Vector3;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
use pocketmine\world\sound\Sound;

class SweepSound implements Sound
{
public function encode(Vector3 $pos): array
{
return [LevelSoundEventPacket::nonActorSound((int)"sweep",$pos,false)];
}
}
Loading

0 comments on commit d455c56

Please sign in to comment.