Skip to content

Commit 11e5703

Browse files
committed
Initial commit
0 parents  commit 11e5703

19 files changed

+1239
-0
lines changed

plugin.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
name: RXFFA
2+
main: rxffa\spicex\rxffa\RXFFA
3+
version: 1.0-beta
4+
api: [4.0.0]
5+
author: SpiceX
6+
website: https://github.com/SpiceX
7+
description: FFA Plugin por PM4

resources/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
arena: default

resources/deaths.yml

Whitespace-only changes.

resources/kills.yml

Whitespace-only changes.

src/rxffa/spicex/rxffa/RXFFA.php

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
<?php
2+
/**
3+
* Copyright 2021-2022 SpiceX
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
declare(strict_types=1);
18+
namespace rxffa\spicex\rxffa;
19+
20+
use pocketmine\entity\EntityDataHelper;
21+
use pocketmine\entity\EntityFactory;
22+
use pocketmine\event\entity\EntityTeleportEvent;
23+
use pocketmine\event\Listener;
24+
use pocketmine\event\player\PlayerQuitEvent;
25+
use pocketmine\item\enchantment\EnchantmentInstance;
26+
use pocketmine\item\enchantment\VanillaEnchantments;
27+
use pocketmine\item\ItemFactory;
28+
use pocketmine\item\ItemIds;
29+
use pocketmine\nbt\tag\CompoundTag;
30+
use pocketmine\player\Player;
31+
use pocketmine\plugin\PluginBase;
32+
use pocketmine\world\World;
33+
use rxffa\spicex\rxffa\command\FFACommand;
34+
use rxffa\spicex\rxffa\event\PlayerGameJoinEvent;
35+
use rxffa\spicex\rxffa\event\PlayerGameQuitEvent;
36+
use rxffa\spicex\rxffa\listener\GameListener;
37+
use rxffa\spicex\rxffa\model\GameModel;
38+
use rxffa\spicex\rxffa\model\TopsModel;
39+
use rxffa\spicex\rxffa\provider\YamlDataProvider;
40+
use rxffa\spicex\rxffa\scoreboard\ScoreboardFactory;
41+
use rxffa\spicex\rxffa\session\SessionFactory;
42+
use rxffa\spicex\rxffa\util\Messages;
43+
44+
/**
45+
* Class RXFFA
46+
* @package rxffa\spicex\rxffa
47+
*/
48+
class RXFFA extends PluginBase implements Listener
49+
{
50+
/** @var RXFFA */
51+
private static RXFFA $instance;
52+
/** @var YamlDataProvider */
53+
private YamlDataProvider $yamlProvider;
54+
55+
public function onEnable(): void
56+
{
57+
self::$instance = $this;
58+
$this->yamlProvider = new YamlDataProvider($this);
59+
$this->getServer()->getPluginManager()->registerEvents(new GameListener($this), $this);
60+
$this->getServer()->getPluginManager()->registerEvents($this, $this);
61+
$this->getServer()->getCommandMap()->register('ffa', new FFACommand($this), 'ffa');
62+
EntityFactory::getInstance()->register(GameModel::class, function (World $world, CompoundTag $nbt): GameModel {
63+
return new GameModel(EntityDataHelper::parseLocation($nbt, $world), GameModel::parseSkinNBT($nbt), $nbt);
64+
}, ['GameModel']);
65+
EntityFactory::getInstance()->register(TopsModel::class, function (World $world, CompoundTag $nbt): TopsModel {
66+
return new TopsModel(EntityDataHelper::parseLocation($nbt, $world), TopsModel::parseSkinNBT($nbt), $nbt);
67+
}, ['TopsModel']);
68+
ScoreboardFactory::init();
69+
}
70+
71+
public function onDisable(): void
72+
{
73+
$this->saveSessions();
74+
}
75+
76+
/**
77+
* @param Player $player
78+
*/
79+
public function joinGame(Player $player): void
80+
{
81+
SessionFactory::createSession($player);
82+
ScoreboardFactory::createScoreboard($player);
83+
$arena = $this->getServer()->getWorldManager()->getWorldByName($this->yamlProvider->getArena());
84+
$items = [
85+
ItemFactory::getInstance()->get(ItemIds::DIAMOND_SWORD)->addEnchantment(new EnchantmentInstance(VanillaEnchantments::SHARPNESS())),
86+
ItemFactory::getInstance()->get(ItemIds::STEAK, 0, 32),
87+
ItemFactory::getInstance()->get(ItemIds::GOLDEN_APPLE, 0, 3),
88+
ItemFactory::getInstance()->get(ItemIds::BOW, 0, 1),
89+
ItemFactory::getInstance()->get(ItemIds::ARROW, 0, 16),
90+
];
91+
$helmet = ItemFactory::getInstance()->get(ItemIds::DIAMOND_HELMET)->addEnchantment(new EnchantmentInstance(VanillaEnchantments::PROTECTION(), 2));
92+
$chestplate = ItemFactory::getInstance()->get(ItemIds::DIAMOND_CHESTPLATE)->addEnchantment(new EnchantmentInstance(VanillaEnchantments::PROTECTION(), 2));
93+
$leggings = ItemFactory::getInstance()->get(ItemIds::DIAMOND_LEGGINGS)->addEnchantment(new EnchantmentInstance(VanillaEnchantments::PROTECTION(), 2));
94+
$boots = ItemFactory::getInstance()->get(ItemIds::DIAMOND_BOOTS)->addEnchantment(new EnchantmentInstance(VanillaEnchantments::PROTECTION(), 2));
95+
96+
// clearly teleport
97+
$player->getEffects()->clear();
98+
$player->getArmorInventory()->clearAll();
99+
$player->getInventory()->clearAll();
100+
$player->getCursorInventory()->clearAll();
101+
$player->getHungerManager()->setEnabled(true);
102+
$player->getHungerManager()->setFood(20.0);
103+
$player->setHealth(20.0);
104+
$player->teleport($arena->getSafeSpawn());
105+
106+
// items equiment
107+
foreach ($items as $item) {
108+
$player->getInventory()->addItem($item);
109+
}
110+
111+
// armor equipment
112+
$player->getArmorInventory()->setHelmet($helmet);
113+
$player->getArmorInventory()->setChestplate($chestplate);
114+
$player->getArmorInventory()->setLeggings($leggings);
115+
$player->getArmorInventory()->setBoots($boots);
116+
117+
// extras
118+
$player->sendTitle(Messages::JOIN_GAME_TITLE, Messages::JOIN_GAME_SUBTITLE);
119+
}
120+
121+
/**
122+
* @param Player $player
123+
* @return bool
124+
*/
125+
public function exitGame(Player $player): bool
126+
{
127+
ScoreboardFactory::removeSecoreboard($player);
128+
$player->getEffects()->clear();
129+
$player->getArmorInventory()->clearAll();
130+
$player->getInventory()->clearAll();
131+
$player->getCursorInventory()->clearAll();
132+
$player->getHungerManager()->setEnabled(false);
133+
$player->getHungerManager()->setFood(20.0);
134+
$player->setHealth(20.0);
135+
$player->teleport($this->getServer()->getWorldManager()->getDefaultWorld()->getSafeSpawn());
136+
$player->sendMessage(Messages::EXIT_MESSAGE);
137+
return true;
138+
}
139+
140+
final protected function saveSessions()
141+
{
142+
foreach (SessionFactory::getSessions() as $session) {
143+
$session->save();
144+
}
145+
}
146+
147+
/**
148+
* @param EntityTeleportEvent $event
149+
*/
150+
public function onEntityTeleportEvent(EntityTeleportEvent $event): void
151+
{
152+
$to = $event->getTo()->getWorld()->getFolderName();
153+
$from = $event->getFrom()->getWorld()->getFolderName();
154+
$entity = $event->getEntity();
155+
$arena = $this->yamlProvider->getArena();
156+
if (!$entity instanceof Player) return;
157+
if ($from === $arena){
158+
SessionFactory::removeSession($entity);
159+
}
160+
$event = match ($to) {
161+
$arena => new PlayerGameJoinEvent($entity, $this),
162+
default => ($from === $arena) ? new PlayerGameQuitEvent($entity, $this) : null,
163+
};
164+
if (!$event?->isCancelled()) {
165+
$event?->call();
166+
}
167+
}
168+
169+
/**
170+
* @param PlayerQuitEvent $event
171+
*/
172+
public function onPlayerQuitEvent(PlayerQuitEvent $event): void
173+
{
174+
$player = $event->getPlayer();
175+
$session = SessionFactory::getSession($player);
176+
$event = $session != null ? new PlayerGameQuitEvent($player, $this) : null;
177+
if (!$event?->isCancelled()) {
178+
SessionFactory::removeSession($player);
179+
ScoreboardFactory::removeSecoreboard($player);
180+
$event?->call();
181+
$session?->save();
182+
}
183+
}
184+
185+
/**
186+
* @return RXFFA
187+
*/
188+
public static function getInstance(): RXFFA
189+
{
190+
return self::$instance;
191+
}
192+
193+
/**
194+
* @return YamlDataProvider
195+
*/
196+
public function getYamlProvider(): YamlDataProvider
197+
{
198+
return $this->yamlProvider;
199+
}
200+
201+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace rxffa\spicex\rxffa\command;
5+
6+
use pocketmine\command\CommandSender;
7+
use pocketmine\command\defaults\VanillaCommand;
8+
use pocketmine\entity\EntityDataHelper;
9+
use pocketmine\player\Player;
10+
use rxffa\spicex\rxffa\model\GameModel;
11+
use rxffa\spicex\rxffa\model\TopsModel;
12+
use rxffa\spicex\rxffa\RXFFA;
13+
use rxffa\spicex\rxffa\util\Messages;
14+
15+
/**
16+
* Class FFACommand
17+
* @package rxffa\spicex\rxffa\command
18+
*/
19+
class FFACommand extends VanillaCommand
20+
{
21+
22+
/**
23+
* FFACommand constructor.
24+
*/
25+
public function __construct(public RXFFA $plugin)
26+
{
27+
parent::__construct(
28+
'ffa', Messages::FFA_COMMAND_DESCRIPTION,
29+
'use /ffa help', ['ffa']
30+
);
31+
}
32+
33+
/**
34+
* @param CommandSender $sender
35+
* @param string $commandLabel
36+
* @param array $args
37+
* @return bool
38+
*/
39+
public function execute(CommandSender $sender, string $commandLabel, array $args): bool
40+
{
41+
if (!$sender instanceof Player || !isset($args[0])) {
42+
$sender->sendMessage("/ffa help");
43+
return false;
44+
}
45+
return match ($args[0]) {
46+
'arena' => isset($args[1]) ? $this->setArena($sender, arena: $args[1]) : $this->getHelp(player: $sender),
47+
'npc' => $this->setModel(player: $sender, modelType: 'npc'),
48+
'tops' => $this->setModel(player: $sender, modelType: 'tops'),
49+
'join' => $this->joinGame(player: $sender),
50+
'exit' => $this->exitGame(player: $sender),
51+
default => $this->getHelp(player: $sender),
52+
};
53+
}
54+
55+
/**
56+
* @param Player $player
57+
* @return bool
58+
*/
59+
private function getHelp(Player $player): bool
60+
{
61+
if ($this->plugin->getServer()->isOp($player->getName())) {
62+
$player->sendMessage(Messages::HELP_COMMAND_OP);
63+
} else {
64+
$player->sendMessage(Messages::HELP_COMMAND_USER);
65+
}
66+
return true;
67+
}
68+
69+
/**
70+
* @param Player $player
71+
* @return bool
72+
*/
73+
private function joinGame(Player $player): bool
74+
{
75+
$this->plugin->joinGame($player);
76+
return true;
77+
}
78+
79+
/**
80+
* @param Player $player
81+
* @return bool
82+
*/
83+
private function exitGame(Player $player): bool
84+
{
85+
$this->plugin->exitGame($player);
86+
return true;
87+
}
88+
89+
/**
90+
* @param Player $player
91+
* @param string $arena
92+
* @return bool
93+
*/
94+
private function setArena(Player $player, string $arena): bool
95+
{
96+
if (!$this->plugin->getServer()->getWorldManager()->isWorldGenerated($arena)) {
97+
$player->sendMessage(Messages::WORLD_NOT_FOUND);
98+
return false;
99+
}
100+
if (!$this->plugin->getServer()->getWorldManager()->isWorldLoaded($arena)) {
101+
$this->plugin->getServer()->getWorldManager()->loadWorld($arena);
102+
}
103+
$this->plugin->getYamlProvider()->setArena($arena);
104+
return true;
105+
}
106+
107+
/**
108+
* @param Player $player
109+
* @param string $modelType
110+
* @return bool
111+
*/
112+
private function setModel(Player $player, string $modelType): bool
113+
{
114+
$nbt = EntityDataHelper::createBaseNBT(
115+
$player->getLocation(), $player->getMotion(), $player->getLocation()->getYaw(), $player->getLocation()->getPitch()
116+
);
117+
$nbt->setTag('Skin', clone $player->getSaveData()->getCompoundTag('Skin'));
118+
$npc = match ($modelType) {
119+
'npc' => new GameModel($player->getLocation(), $player->getSkin(), $nbt),
120+
'tops' => new TopsModel($player->getLocation(), $player->getSkin(), $nbt),
121+
default => null,
122+
};
123+
$npc?->spawnToAll();
124+
return true;
125+
}
126+
127+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
declare(strict_types=1);
3+
namespace rxffa\spicex\rxffa\event;
4+
5+
use JetBrains\PhpStorm\Pure;
6+
use pocketmine\event\plugin\PluginEvent;
7+
use pocketmine\player\Player;
8+
use pocketmine\plugin\Plugin;
9+
10+
/**
11+
* Class PlayerGameDeathEvent
12+
* @package rxffa\spicex\rxffa\event
13+
*/
14+
class PlayerGameDeathEvent extends PluginEvent
15+
{
16+
17+
/**
18+
* PlayerGameDeathEvent constructor.
19+
*/
20+
#[Pure] public function __construct(private Player $player, Plugin $plugin)
21+
{
22+
parent::__construct($plugin);
23+
}
24+
25+
/**
26+
* @return Player
27+
*/
28+
public function getPlayer(): Player
29+
{
30+
return $this->player;
31+
}
32+
}

0 commit comments

Comments
 (0)