Browse Source

Uploading...

master
Ad5001 2 years ago
commit
50ce75f730

+ 3
- 0
.vscode/settings.json View File

@@ -0,0 +1,3 @@
// Placez vos paramètres dans ce fichier pour remplacer les paramètres par défaut et les paramètres utilisateur.
{
}

+ 126
- 0
LICENSE View File

@@ -0,0 +1,126 @@
BoxOfDevs General Software License 1.1.3
=========================================
This license is designed to be used with any software which would like to have no selling for profits, nor any public redistribution without giving the original author credits.
--------------------------------------------------------------------------------------------------------------------------------------
The License: refers to the BoxOfDevs International Software License 1.1.2
The Software: refers to any works licensed under The License.
The Modification: refers to any modified version of The Software.
The Redistribution: refers to any redistributions of The Software/The Modification.
The User: refers to any user of The Software licensed under The License.
The Author: refers to any developer, organisation, legal owner, or creator of The Software that has been licensed under the The License.
--------------------------------------------------------------------------------------------------------------------------------------
Section 1 - Allowances:

1. Both The User & The Author Can:
a. Modify private copies of The Software and use in any way they wish.
b. Change which license The Software/The Modification is licensed under.

2. The User Can:
a. Request new features, support, or more rights from The Author.
b. Redistribute The Software/The Modification, ensuring The User gives all appropriate credit to The Author and alerting The Author to The Redistribution.

3. The Author Can:
a. Change or update The Software in any way they wish, ensuring they follow the other terms of The License.
b. Grant extra rights to The User who has requested them.
c. Reserve the right to request The User to take down their instance of The Software/The Modification/The Redistribution.

Section 2 - Restrictions:
1. Both The User & The Author Cannot:
a. Introduce any malicious code into The Software/The Modification.
b. Sell any part of The Software/The Modification for profit.

2. The User Cannot:
a. Hold The Author responsible for any unknown errors.
b. Claim The Software/The Modification/The Redistribution as entirely The User's product.
c. Use the software without crediting the Author.

3. The Author Cannot:
a. Restrict The User in any way not specified by The License.
b. Distribute any form of The Software without proper documentation.

Term. The term of this Public License is specified in Section 6(a).
Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Modification.

Downstream recipients.
Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
Additional offer from the Licensor – the Modification. Every recipient of the Modification from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Modification under the conditions of the Adapter’s License You apply.
No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).

Other rights.
Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
Patent and trademark rights are not licensed under this Public License.
To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.

Section 3 – License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the following conditions.

a) Attribution.
If You Share the Licensed Material (including in modified form), You must:
retain the following if it is supplied by the Licensor with the Licensed Material:
identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
a copyright notice;
a notice that refers to this Public License;
a notice that refers to the disclaimer of warranties;
a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.

b) ShareAlike.
In addition to the conditions in Section 3(a), if You Share the Modification You produce, the following conditions also apply.
The Adapter’s License You apply must be a BoxOfDevs General License with the same License Elements, this version or later, or a BY-SA Compatible License.
You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share the Modification.
You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Modification that restrict exercise of the rights granted under the Adapter's License You apply.

c) Forever Open Source.
In addition to the conditions in Section 3(a) and Section 3(b), if You Share the Modification You produce, the following conditions also apply.
The Adapted work must have an open source existing repertory, accessible by anyone anytime linked in the Redistribution Description/Documentation.
You may not restrict anyone from accessing the source code, use it, and redistribute it under anything not explicily specified by the License.

d) Free.
In addition to the conditions in Section 3(a), Section 3(b) and Section 3(c), if You Share by any way Modification and/or the Software You produce, the following conditions also apply.
The Work must be redistributed entirely free, under this license.
You may not impose fees to anyone that gets the Modification/The Software.


Section 4 – Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:

for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Modification, including for purposes of Section 3(b); and
You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.

For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.

Section 5 – Disclaimer of Warranties and Limitation of Liability.

Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.

The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.

Section 6 – Term and Termination.
This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.

Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
Sections 1, 5, 6, 7, and 8 survive termination of this Public License.

Section 7 – Other Terms and Conditions.

The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
In the event that The License is updated/changed on the official github repository/on the official website, you automatically agree.
The Author is not required to notify The User that The License has been updated/changed.

Section 8 – Interpretation.
For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.

To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.

+ 21
- 0
plugin.yml View File

@@ -0,0 +1,21 @@
---
# _ _ _ _ _ _____ _
# | | | | (_) | | /\ | | / ____| | |
# | |__| | _ __| | ___ / \ _ __ __| | | (___ ___ ___ | | __
# | __ | | | / _` | / _ \ / /\ \ | '_ \ / _` | \___ \ / _ \ / _ \ | |/ /
# | | | | | | | (_| | | __/ / ____ \ | | | | | (_| | ____) | | __/ | __/ | <
# |_| |_| |_| \__,_| \___| /_/ \_\ |_| |_| \__,_| |_____/ \___| \___| |_|\_\
#
#
# The original minigame, free, and better than ever !
# @author Ad5001
# @link ad5001.eu
name: HideAndSeek
author: Ad5001
version: 1.0
api: [3.0.0, 3.0.0-ALPHA1]
main: Ad5001\HideAndSeek\Main
load: POSTWORLD
commands: []
permissions: []
...

+ 23
- 0
resources/config.yml View File

@@ -0,0 +1,23 @@
---
# _ _ _ _ _ _____ _
# | | | | (_) | | /\ | | / ____| | |
# | |__| | _ __| | ___ / \ _ __ __| | | (___ ___ ___ | | __
# | __ | | | / _` | / _ \ / /\ \ | '_ \ / _` | \___ \ / _ \ / _ \ | |/ /
# | | | | | | | (_| | | __/ / ____ \ | | | | | (_| | ____) | | __/ | __/ | <
# |_| |_| |_| \__,_| \___| /_/ \_\ |_| |_| \__,_| |_____/ \___| \___| |_|\_\
#
#
# The original minigame, free, and better than ever !
# @author Ad5001
# @link ad5001.eu

# Welcome to HideAndSeek config.

# Parameters below are defaul parameters when not configured per world.
# You can change them per world using in game commands
# Maximum amount of players per game. The game automaticly starts after 75% of the players have joined
Max players: 16

# Seconds to wait between the time 75% of the maximum players have joined and the games starts.
Waiting time: 16
...

+ 106
- 0
src/Ad5001/HideAndSeek/DataBase.php View File

@@ -0,0 +1,106 @@
<?php
# _ _ _ _ _ _____ _
# | | | | (_) | | /\ | | / ____| | |
# | |__| | _ __| | ___ / \ _ __ __| | | (___ ___ ___ | | __
# | __ | | | / _` | / _ \ / /\ \ | '_ \ / _` | \___ \ / _ \ / _ \ | |/ /
# | | | | | | | (_| | | __/ / ____ \ | | | | | (_| | ____) | | __/ | __/ | <
# |_| |_| |_| \__,_| \___| /_/ \_\ |_| |_| \__,_| |_____/ \___| \___| |_|\_\
#
#
# The original minigame, free, and better than ever !
# @author Ad5001
# @link ad5001.eu

namespace Ad5001\HideAndSeek;

use pocketmine\Server;
use pocketmine\Player;
use SQLite3;

use Ad5001\HideAndSeek\Main;

class DataBase extends SQLite3 {
/*
Gets a data from a line where $data["key"] = $data["value"]
@param $dataToGet string
@param $data array
@return array|bool
*/
public function get(string $dataToGet, array $data) {
$table = $data["table"];
unset($data["table"]);
$str = $this->buildQueryArgs($data);
$result = $this->query("SELECT $dataToGet FROM $table WHERE $str");
if($result !== false) $result = $result->fetchArray();
return $result;
}


/*
Sets data to a database where $data["key"] = $data["value"];
@param $key string
@param $value string
@param $data array
*/
public function set(string $key, string $value, array $data) {
$table = $data["table"];
unset($data["table"]);
$str = $this->buildQueryArgs($data);
return $this->query("UPDATE $table SET $key = '$value' WHERE $str");
}


/*
Inserts a row into the database
@param $table string
@param $data array
*/
public function insert(string $table, array $data) {
return $this->query("INSERT INTO $table VALUES ('" . implode("', '", $data) . "')");
}


/*
Deletes a row from the database
@param $table string
@param $data array
*/
public function delete(string $table, array $data) {
$str = $this->buildQueryArgs($data);
return $this->query("DELETE FROM $table WHERE $str");
}

/*
Formats an SQL query from an array
@param $data array
@return string
*/
public function buildQueryArgs(array $data) : string {
$str = "";
foreach($data as $k => $d) $str .= "$k = '$d' AND ";
return substr($str, 0, strlen($str) - 5);
}

/*
Checks queries and return it. To set custom params/
@param $qry string
@return SQLite3Result|bool
*/
public function query($qry) {
$res = parent::query($qry);
if($res instanceof \SQLite3Result) self::setNumRows($res);
return $res;
}

/*
Sets a number of rows in of a query
@param &$result \SQLite3Result
*/
protected static function setNumRows(\SQLite3Result &$result) {
$n = 0;
while($result->fetchArray() !== false) $n++;
$result->reset();
$result->num_rows = $n;
}
}

+ 542
- 0
src/Ad5001/HideAndSeek/Game.php View File

@@ -0,0 +1,542 @@
<?php
# _ _ _ _ _ _____ _
# | | | | (_) | | /\ | | / ____| | |
# | |__| | _ __| | ___ / \ _ __ __| | | (___ ___ ___ | | __
# | __ | | | / _` | / _ \ / /\ \ | '_ \ / _` | \___ \ / _ \ / _ \ | |/ /
# | | | | | | | (_| | | __/ / ____ \ | | | | | (_| | ____) | | __/ | __/ | <
# |_| |_| |_| \__,_| \___| /_/ \_\ |_| |_| \__,_| |_____/ \___| \___| |_|\_\
#
#
# The original minigame, free, and better than ever !
# @author Ad5001
# @link ad5001.eu

namespace Ad5001\HideAndSeek;

use pocketmine\Server;
use pocketmine\Player;
use pocketmine\level\Level;
use pocketmine\event\Listener;
use pocketmine\math\Vector3;
use pocketmine\scheduler\PluginTask;

use Ad5001\HideAndSeek\Main;
use Ad5001\HideAndSeek\GameManager;

class Game extends PluginTask /* Allows easy game running */ implements Listener {

const STEP_WAIT = 0;
const STEP_STARTING = 1;
const STEP_HIDE = 2;
const STEP_SEEK = 3;
const STEP_WIN = 4;

const NO_WIN = 0;
const WIN_SEEKERS = 1;
const WIN_HIDERS = 2;

const ROLE_WAIT = 0;
const ROLE_SEEK = 1;
const ROLE_HIDE = 2;
const ROLE_SPECTATE = 2;

// Level based informations
protected $level;
protected $players = [];
protected $spectators = [];

// Game based informations
protected $step = self::STEP_WAIT;
protected $win = self::NO_WIN;
protected $stepTick;
protected $hidersLeft;
protected $seekersCount;
/*
Constructs the class
@param $level Level
*/
public function __construct(Level $level) {
// Initialisation
$this->initDB();
$level->game = $this;
$this->setLevel($level);
$this->registerEvents();

// Registering players
foreach($this->getLevel()->getPlayers() as $p) {
$this->registerPlayer($p);
}

// Loading timer.
parent::__construct($this->getMain());
$this->getMain()->getServer()->getScheduler()->scheduleRepeatingTask($this, 1);
}

/*
Function that runs every x ticks
@param $tick int
*/
public function onRun($tick) {
switch($this->step) {
case self::STEP_WAIT:
if(count($this->getPlayers()) >= round($this->getMaxPlayers() * 0.75)) {
$this->stepTick = $tick;
$this->step = self::STEP_START;
foreach(array_merge($this->getPlayers(), $this->getSpectators()) as $p) {
$p->sendMessage(Main::PREFIX . "§aGame will start in " . $this->getWaitTime() . " seconds.");
}
}
break;
case self::STEP_START:
$tickWaited = $tick - $this->stepTick;
if($tickWaited % 20 == 0) {
foreach(array_merge($this->getPlayers(), $this->getSpectators()) as $p) {
$p->sendMessage(Main::PREFIX . "§aGame will start in " . ($this->getWaitTime() - ($tickWaited / 20)) . " seconds.");
}
}
if($this->getWaitTime() - ($tickWaited / 20) <= 0) {
$this->stepTick = $tick;
$this->start();
foreach(array_merge($this->getPlayers(), $this->getSpectators()) as $p) {
$p->sendMessage(Main::PREFIX . "§aGame started ! There is $this->seekersCount seekers and $this->hidersLeft hiders.");
if($p->HideAndSeekRole == self::ROLE_SEEK) {
$p->teleport($this->getSeekerSpawn());
} elseif($p->HideAndSeekRole == self::ROLE_HIDE) {
$p->teleport($this->getSpawn());
$p->sendPopup("§lHider: You have 1 minute to hide yourself so seekers won't find you ! Don't get caught for " . $this->getSeekTime() . " minutes to win !");
}
}
}
break;
case self::STEP_HIDE:
$tickWaited = $tick - $this->stepTick;
if($tickWaited >= 20*60) { // One minute has past !
$this->step = self::STEP_SEEK;
$this->stepTick = $tick;
foreach(array_merge($this->getPlayers(), $this->getSpectators()) as $p) {
$p->sendMessage(Main::PREFIX . "§aSeekers released !");
if($p->HideAndSeekRole == self::ROLE_SEEK) {
$p->teleport($this->getSpawn());
$p->sendPopup("§lSeeker: Seek the hiders ! Catch them all to win in " . $this->getSeekTime() . " minutes to win !");
}
}
}
break;
case self:STEP_SEEK:
$tickWaited = $tick - $this->stepTick;
if($tickWaited % 20*60 == 0) {
foreach(array_merge($this->getPlayers(), $this->getSpectators()) as $p) {
$p->sendMessage(Main::PREFIX . "§aGame ends in " . ($this->getSeekTime() - ($tickWaited / 20 / 60)) . " minutes.");
}
}
if($tickWaited >= 20*60*$this->getSeekTime()) { // Seek time has past
$this->win = self::WIN_HIDERS;
$this->step = self::STEP_WIN;
}
break;
case self::STEP_WIN:
foreach(array_merge($this->getPlayers(), $this->getSpectators()) as $p) {
if($this->win == self::WIN_SEEKERS) {
$p->sendMessage(Main::PREFIX . "§aThe last hider got caught ! Seekers won !");
$p->sendTip("§a§lSeekers won !");
} elseif($this->win == self::WIN_SEEKERS) {
$p->sendMessage(Main::PREFIX . "§aTimes up ! Hiders won !");
$p->sendTip("§a§lHiders won !");
} else {
$p->sendMessage(Main::PREFIX . "§aGame cancelled !");
}
$p->teleport($this->getLobbyWorld());
$p->setGamemode($this->getMain()->getServer()->getDefaultGamemode());
}
$this->step = self::STEP_WAIT;
break;
}
}


/*
Inits the database for the game.
*/
public function initDB() {
$qry = $this->getMain()->getDatabase()->get("*", ["table" => "Games", "name" => $this->getName()]);
if(is_array($qry)) {
if(count($qry) == 0) { // Game not initiated in the db.
$v3 = $this->getLevel()->getSafeSpawn();
$v3Ser = $v3->x . "," . $v3->y . "," . $v3->z; // V32String
$this->getMain()->getDatabase()->insert("Games", [$this->getName(), $v3Ser, $v3Ser, $this->getMain()->getMaxPlayers(), $this->getMain()->getWaitTime(), $this->getMain()->getSeekTime(), $this->getMain()->getSeekersPercentage()]); // Inserting the db with new queries
}
} else {
throw new Exception("Could not contact database.");
}
}




# _____ _____
# /\ | __ \ |_ _|
# / \ | |__) | | |
# / /\ \ | ___/ | |
# / ____ \ | | _| |_
# /_/ \_\ |_| |_____|
#
#


/*
Starts the game
*/
public function start() {
$count = count($this->players);
$this->seekersCount = round($count * ($this->getSeekersPercentage() / 100), 0, PHP_ROUND_HALF_UP); // Minimum $this->getSeekersPercentage() percents of the players (inimum because if there are less than $this->getSeekersPercentage(), then there could be no seeker)
$this->hidersLeft = count($this->players) - $this->seekersCount;

shuffle($this->players);
$i = 0;
foreach($this->players as $p) {
if($i < $this->seekersCount) {
$this->players[$i]->HideAndSeekRole = self::ROLE_SEEK;
$this->players[$i]->sendTip("§4You're a seeker.");
} else {
$this->players[$i]->HideAndSeekRole = self::ROLE_HIDE;
$this->players[$i]->sendTip("§4You're an hider.");
}
$i++;
}
}

/*
Returns game's spawn (waiting + for players) spawn
@return \pocketmine\math\Vector3
*/
public function getSpawn() : Vector3 {
$data = $this->getMain()->getDatabase()->get("spawnpoint", ["table" => "Games", "name" => $this->getName()]);
$data = explode(",", $data);
return new Vector3($data[0], $data[1], $data[2]);
}


/*
Returns seekers spawn (waiting hiders to hide + startup)
@return \pocketmine\math\Vector3
*/
public function getSeekerSpawn() : Vector3 {
$data = $this->getMain()->getDatabase()->get("seekerspawn", ["table" => "Games", "name" => $this->getName()]);
$data = explode(",", $data);
return new Vector3($data[0], $data[1], $data[2]);
}


/*
Returns the game level.
@return \pocketmine\level\Level
*/
public function getLevel() : Level {
return $this->level;
}


/*
Returns the game's name.
@return string
*/
public function getName() : string {
return $this->level->getName();
}

/*
Returns the game's players.
@return array
*/
public function getPlayers() : array {
return $this->players;
}

/*
Returns the game's spectators.
@return array
*/
public function getSpectators() : array {
return $this->spectators;
}

/*
Returns a player by it's name.
@param $name string
@return Player|null
*/
public function getPlayer(string $name) {
return isset($this->players[$name]) ? $this->players[$name] : null;
}

/*
Returns the main class
*/
public function getMain() {
return Server::getInstance()->getPluginManager()->getPlugin("HideAndSeek");
}

/*
Returns the game id
*/
public function getId() {
return $this->getGameManager()->getGameId($this);
}
/*
Returns the max players in a game.
@return int
*/
public function getMaxPlayers() : int {
return (int) $this->getMain()->getDatabase()->get("max_players", ["table" => "Games", "name" => $this->getName()])[0];
}

/*
Returns the time to wait between 75% of max players joined and the game start (ending filling if needed)
@return int
*/
public function getWaitTime() : int {
return (int) $this->getMain()->getDatabase()->get("waiting_time", ["table" => "Games", "name" => $this->getName()]);
}

/*
Returns the time that the seekers have to find all hiders (used to balance with the max players)
@return int
*/
public function getSeekTime() : int {
return (int) $this->getMain()->getDatabase()->get("seek_time", ["table" => "Games", "name" => $this->getName()]);
}

/*
Returns the percentage of the players that should be hunters.
@return int
*/
public function getSeekersPercentage() : int {
return (int) $this->getMain()->getDatabase()->get("seekers_percentage", ["table" => "Games", "name" => $this->getName()]);
}
// SET

/*
Sets the spawn of the game
@param $v3 Vector3
*/
public function setSpawn(Vector3 $v3) {
$str = $v3->x . "," . $v3->y . "," . $v3->z;
return $this->getMain()->getDatabase()->set("spawnpoint", $str, ["table" => "Games", "name" => $this->getName()]);
}

/*
Sets the seeker spawn. Check get for more details.
@param $v3 Vector3
*/
public function setSeekerSpawn(Vector3 $v3) {
$str = $v3->x . "," . $v3->y . "," . $v3->z;
return $this->getMain()->getDatabase()->set("seekerspawn", $str, ["table" => "Games", "name" => $this->getName()]);
}

/*
Changes the level of the game
@param $level Level
*/
public function setLevel(Level $level) {
$this->level = $level;
return $this->getMain()->getDatabase()->set("level", $level->getName(), ["table" => "Games", "name" => $this->getName()]);
}

/*
Sets a maximum number of players
@param $int int
*/
public function setMaxPlayers(int $int) {
return $this->getMain()->getDatabase()->set("max_players", $level->getName(), ["table" => "Games", "name" => $this->getName()]);
}

/*
Sets the waiting time in the lobby
@param $int int
*/
public function setWaitTime(int $int) {
return $this->getMain()->getDatabase()->set("waiting_time", $level->getName(), ["table" => "Games", "name" => $this->getName()]);
}

/*
Sets the seeking time
@param $int int
*/
public function setSeekTime(int $int) {
return $this->getMain()->getDatabase()->set("seek_time", $level->getName(), ["table" => "Games", "name" => $this->getName()]);
}

/*
Sets a the percentage of the seekers
@param $int int
*/
public function setSeekersPercentage(int $int) {
return $this->getMain()->getDatabase()->set("seekers_percentage", $level->getName(), ["table" => "Games", "name" => $this->getName()]);
}

/*
Registers a player
@param $player \pocketmine\Player
*/
public function registerPlayer(Player $player) {
if($player->isSpectator() ||
(!is_null($this->getMain()->getServer()->getPluginManager()->getPlugin("SpectatorPlus")) &&
$this->getMain()->getServer()->getPluginManager()->getPlugin("SpectatorPlus")->isSpectator($player))) { // Support for spectator Plus
$this->spectators[$player->getName()] = $player;
$player->HideAndSeekRole = self::ROLE_SPECTATE;
} elseif($this->step == self::STEP_WAIT) {
// API inside player's class (easilier to get data)
$player->hideAndSeekGame = $this;
$player->HideAndSeekRole = self::ROLE_WAIT;
$player->playsHideAndSeek = true;
$this->players[$player->getName()] = $player;
$player->setGamemode(2); // Set it to adventure so player cannot break blocks.
} else {
$this->spectators[$player->getName()] = $player;
$player->HideAndSeekRole = self::ROLE_SPECTATE;
$player->setGamemode(3);
}
}

/*
Unregisters a player
@param $player \pocketmine\Player
*/
public function unregisterPlayer(Player $player) {
switch(isset($player->HideAndSeekRole) ? $player->HideAndSeekRole : -1) {
case self::ROLE_SEEK:
$this->seekersCount--;
$this->sendMessage($player->getName() . " left the game. $this->seekersCount seekers left.");
unset($this->players[$player->getName()]);
unset($player->hideAndSeekGame);
unset($player->playsHideAndSeek);
if($this->seekersCount == 0) {
$this->step = self::STEP_WIN;
$this->win = self::WIN_HIDERS;
}
break;
case self::ROLE_HIDE:
$this->hidersLeft--;
$this->sendMessage($player->getName() . " left the game. $this->hidersLeft hiders left.");
unset($this->players[$player->getName()]);
unset($player->hideAndSeekGame);
unset($player->playsHideAndSeek);
if($this->hidersLeft == 0) {
$this->step = self::STEP_WIN;
$this->win = self::WIN_SEEKERS;
}
break;
case self::ROLE_WAIT:
unset($this->players[$player->getName()]);
unset($player->hideAndSeekGame);
unset($player->playsHideAndSeek);
break;
case self::ROLE_SPECTATE:
unset($this->spectators[$player->getName()]);
break;
}
}


/*
Sends a message to all players and spectators in the game.
@param $message string
*/
public function sendMessage(string $message) {
foreach(array_merge($this->getPlayers(), $this->getSpectators()) as $p) {
$p->sendMessage(Main::PREFIX . $message);
}
}


# ______ _
# | ____| | |
# | |__ __ __ ___ _ __ | |_ ___
# | __| \ \ / / / _ \ | '_ \ | __| / __|
# | |____ \ V / | __/ | | | | | |_ \__ \
# |______| \_/ \___| |_| |_| \__| |___/
#
#

/*
Checks when an entity changes level to add a player to the list/remove one.
@param $event \pocketmine\event\entity\EntityLevelChangeEvent
*/
public function onEntityLevelChange(\pocketmine\event\entity\EntityLevelChangeEvent $event) {
if($event->getTarget()->getName() == $this->getName() && $event->getEntity instanceof Player) {
$this->registerPlayer($event->getEntity());
} elseif($event->getOrigin()->getName() == $this->getName() && $event->getEntity instanceof Player) {
$this->unregisterPlayer($event->getEntity());
}
}

/*
Checks when a block breaks to prevent it.
@param $event \pocketmine\event\block\BlockBreakEvent
*/
public function onBlockBreak(\pocketmine\event\block\BlockBreakEvent $event) {
if($event->getPlayer()->getLevel() == $this->getName()) {
$event->setCancelled();
}
}

/*
Checks when a block places to prevent it.
@param $event \pocketmine\event\block\BlockPlaceEvent
*/
public function onBlockPlace(\pocketmine\event\block\BlockPlaceEvent $event) {
if($event->getPlayer()->getLevel() == $this->getName()) {
$event->setCancelled();
}
}


/*
Checks when an entity get hurts (used to tag.)
@param $event \pocketmine\event\entity\EntityDamageEvent
*/
public function onEntityDamage(\pocketmine\event\entity\EntityDamageEvent $event) {
if($event->getEntity()->getLevel() == $this->getName()) {
if($event instanceof \pocketmine\event\entity\EntityDamageByEntityEvent
&& $event->getEntity() instanceof Player
&& $event->getDamager() instanceof Player
&& (isset($event->getDamager()->HideAndSeekRole) ? $event->getDamager()->HideAndSeekRole : -1) == self::ROLE_SEEK
&& (isset($event->getEntity()->HideAndSeekRole) ? $event->getEntity()->HideAndSeekRole : -1) == self::ROLE_HIDE) { // Tagging
$event->getEntity()->HideAndSeekRole = self::ROLE_SEEK;
$event->getEntity()->teleport($this->getSpawn());
}
$event->setCancelled();
}
}

/*
Checks when a player joins in the world to make him rejoin automaticly
@param $event \pocketmine\event\player\PlayerJoinEvent
*/
public function onPlayerJoin(\pocketmine\event\player\PlayerJoinEvent $event) {
if($event->getPlayer()->getLevel() == $this->getName()) {
$this->registerPlayer($event->getPlayer());
}
}

/*
Checks when a player leaves in the world to make him die.
@param $event \pocketmine\event\player\PlayerQuitEvent
*/
public function onPlayerQuit(\pocketmine\event\player\PlayerQuitEvent $event) {
if($event->getPlayer()->getLevel() == $this->getName()) {
$this->unregisterPlayer($event->getPlayer());
}
}



}

+ 153
- 0
src/Ad5001/HideAndSeek/GameManager.php View File

@@ -0,0 +1,153 @@
<?php
# _ _ _ _ _ _____ _
# | | | | (_) | | /\ | | / ____| | |
# | |__| | _ __| | ___ / \ _ __ __| | | (___ ___ ___ | | __
# | __ | | | / _` | / _ \ / /\ \ | '_ \ / _` | \___ \ / _ \ / _ \ | |/ /
# | | | | | | | (_| | | __/ / ____ \ | | | | | (_| | ____) | | __/ | __/ | <
# |_| |_| |_| \__,_| \___| /_/ \_\ |_| |_| \__,_| |_____/ \___| \___| |_|\_\
#
#
# The original minigame, free, and better than ever !
# @author Ad5001
# @link ad5001.eu

namespace Ad5001\HideAndSeek;

use pocketmine\Server;
use pocketmine\Player;

use Ad5001\HideAndSeek\Main;

class GameManager {

protected $games = [];
protected $gamesNames = [];
/*
Gets a game by it's name.
@param $name string
@return Game|null
*/
public function getGameByName(string $name) {
if(isset($this->gamesNames[$name])) return $this->games[$this->gamesNames[$name]];
return null;
}
/*
Gets a game by it's name.
@param $id int
@return Game|null
*/
public function getGameById(int $id) {
if(isset($this->games[$id])) return $this->games[$id];
return null;
}
/*
Gets a game by it's level.
@param $level \pocketmine\level\Level
@return Game|null
*/
public function getGameByLevel(\pocketmine\level\Level $level) {
return $this->getGameByName($level->getName());
}


/*
Returns the id of a game. Better use $game->getId()
@param $game Game
@return int
*/
public function getGameId(Game $game) : int {
if(isset($this->gamesNames[$game->getName()])) return $this->gamesNames[$game->getName()];
return -1;
}



/*
Used when try to access unknown/as array data. Can use id or name.
@param $name string
@return Game|null
*/
public function __get(string $name) {
$pass = $this->getGameByName($name);
if(is_null($pass)) $pass = $this->getGameByName($name);
return $pass;
}


/*
Registers a game when using a set as class/array
@param $name string
@param $value Game
*/
public function __set(string $name, $value) {
if($value instanceof Game) {
if(!isset($this->gamesNames[$name])) {
$result = $this->getMain()->getDatabase()->get("*", ["table" => "Games"]);
$this->games[$result->num_rows] = $value;
$this->gamesNames[$value->getName()] = $result->num_rows;
$this->getMain()->getLogger()->notice("Succefully registered game level {$value->getName()}.");
}
} else {
throw new Exception("Value should be a game.");
}
}


/*
Unregisters a game when unseting it. Can use id or name.
@param $name string
*/
public function __unset(string $name) {
if(!is_null($this->getGameByName($name))) {
$this->getMain()->getDataBase()->delete("Games", ["name" => $name]);
unset($this->gamesNames[$name]);
unset($this->games[$this->gamesNames[$name]]);
} else {
$this->getMain()->getDataBase()->delete("Games", ["name" => $this->games[$id]->getName()]);
unset($this->games[$name]);
}
}

/*
Checks if a game exists
@param $namevariable string
@return bool
*/
public function __isset(string $name) : bool {
if(!is_null($this->getGameByName($name)) || !is_null($this->getGameById($name))) {
return true;
}
return false;
}


/*
Returns main's instance.
@return Main
*/
public function getMain() : Main {
return Server::getInstance()->getPluginManager()->getPlugin("HideAndSeek");
}


/*
Registers all games which haven't been registered yet' game.
@param $db DataBase
*/
public function refreshRegisterGames(DataBase $db) {
$result = $db->get("*", ["table" => "Games"]);
if($result !== false) {
while($row = $result->fetchArray()) {
if(is_null($this->gamesName[$row["name"]]) && ($lvl = $this->getMain()->getServer()->getLevelByName($row["name"])) !== null) { // Game doesn't exists && level is loaded
$this->games[$row["id"]] = new Game($lvl);
$this->gamesNames[$row["name"]] = $row["id"];
$this->getMain()->getLogger()->notice("Succefully registered game level {$row['name']}.");
}
}
}
}

}

+ 284
- 0
src/Ad5001/HideAndSeek/Main.php View File

@@ -0,0 +1,284 @@
<?php
# _ _ _ _ _ _____ _
# | | | | (_) | | /\ | | / ____| | |
# | |__| | _ __| | ___ / \ _ __ __| | | (___ ___ ___ | | __
# | __ | | | / _` | / _ \ / /\ \ | '_ \ / _` | \___ \ / _ \ / _ \ | |/ /
# | | | | | | | (_| | | __/ / ____ \ | | | | | (_| | ____) | | __/ | __/ | <
# |_| |_| |_| \__,_| \___| /_/ \_\ |_| |_| \__,_| |_____/ \___| \___| |_|\_\
#
#
# The original minigame, free, and better than ever !
# @author Ad5001
# @link ad5001.eu

namespace Ad5001\HideAndSeek;

use pocketmine\command\CommandSender;
use pocketmine\command\Command;
use pocketmine\event\Listener;
use pocketmine\plugin\PluginBase;
use pocketmine\Server;
use pocketmine\Player;
class Main extends PluginBase implements Listener {

const PREFIX = "§a§l§o[§r§l§2Hide§eAnd§6Seek§o§a] §r§f";

protected $db;
protected $gamemanager;


/*
Called when the plugin enables
*/
public function onEnable() {
$this->saveDefaultConfig();
$this->getServer()->getPluginManager()->registerEvents($this, $this);
//Database setup
$this->db = new DataBase($this->getDatafolder() . "base.db");
if($this->db->query("PRAGMA table_info(Games);")->num_rows == 0) {
$this->db->query(<<<A
CREATE TABLE Games (
name VARCHAR( 128 ) NOT NULL,
spawnpoint VARCHAR( 128 ) NOT NULL,
seekerspawn VARCHAR( 128 ) NOT NULL,
max_players INT NOT NULL,
waiting_time INT NOT NULL,
seek_time INT NOT NULL,
seekers_percentage INT NOT NULL
)
A
);
}

$this->gamemanager = new GameManager();
}


/*
Called when one of the defined commands of the plugin has been called
@param $sender \pocketmine\command\CommandSender
@param $cmd \pocketmine\command\Command
@param $label mixed
@param $args array
return bool
*/
public function onCommand(\pocketmine\command\CommandSender $sender, \pocketmine\command\Command $cmd, $label, array $args): bool {
switch($cmd->getName()) {
case "hideandseek":
if(isset($args[0])) {
switch(strtolower($args[0])) {
case "creategame":
case "addgame":
if($sender->getLevel()->getName() == $this->getLobbyWorld()->getName()) {
$sender->sendMessage(self::PREFIX . "§4Could not create game ! You're in the lobby level.");
return true;
} elseif(!is_null($this->getGameManager()->getGameByLevel($sender->getLevel()))) {
$sender->sendMessage(self::PREFIX . "§4This level is already an hide and seek game.");
return true;
} else {
$this->getGameManager()[] = new Game($sender->getLevel());
$sender->sendMessage(self::PREFIX . "§4Succefully created hide and seek game in level {$sender->getLevel()->getName()}.");
return true;
}
break;
case "deletegame":
case "delgame":
$game = $this->getGameManager()->getGameByLevel($sender->getLevel());
if(!is_null($game)) {
unset($this->getGameManager()[$sender->getLevel()->getName()]);
$sender->sendMessage(self::PREFIX . "§4Succefully deleted hide and seek game in level {$sender->getLevel()->getName()}.");
return true;
} else {
$sender->sendMessage(self::PREFIX . "§4You're not in an hide and seek game world.");
}
break;
case "setmaxplayers":
case "smp":
$game = $this->getGameManager()->getGameByLevel($sender->getLevel());
if(!is_null($game)) {
if(isset($args[1]) && is_int($args[1]) && $args[1] > 1) {
$game->setMaxPlayers($args[1]);
$sender->sendMessage(self::PREFIX . "§4Succefully set maximum amount of players of hide and seek game in level {$sender->getLevel()->getName()} to {$args[1]}.");
} else {
$sender->sendMessage("§4Usage: /hideandseek setmaxplayers <max amount>");
}
return true;
} else {
$sender->sendMessage(self::PREFIX . "§4You're not in an hide and seek game world.");
}
break;
case "setseekerspercentage":
case "ssp":
$game = $this->getGameManager()->getGameByLevel($sender->getLevel());
if(!is_null($game)) {
if(isset($args[1]) && is_int($args[1]) && $args[1] > 0 && $args[1] < 100) {
$game->setSeekersPercentage($args[1]);
$sender->sendMessage(self::PREFIX . "§4Succefully set seekers percentage of hide and seek game in level {$sender->getLevel()->getName()} to {$args[1]}.");
} else {
$sender->sendMessage("§4Usage: /hideandseek setseekerspercentage <percentage>");
}
return true;
} else {
$sender->sendMessage(self::PREFIX . "§4You're not in an hide and seek game world.");
}
break;
case "setwaitingtime":
case "setwaittime":
case "swt":
$game = $this->getGameManager()->getGameByLevel($sender->getLevel());
if(!is_null($game)) {
if(isset($args[1]) && is_int($args[1]) && $args[1] > 0) {
$game->setWaitTime($args[1]);
$sender->sendMessage(self::PREFIX . "§4Succefully set waiting time of hide and seek game in level {$sender->getLevel()->getName()} to {$args[1]}.");
} else {
$sender->sendMessage("§4Usage: /hideandseek setwaittime <seconds to wait>");
}
return true;
} else {
$sender->sendMessage(self::PREFIX . "§4You're not in an hide and seek game world.");
}
break;
case "setseektime":
case "sst":
$game = $this->getGameManager()->getGameByLevel($sender->getLevel());
if(!is_null($game)) {
if(isset($args[1]) && is_int($args[1]) && $args[1] > 0) {
$game->setSeekTime($args[1]);
$sender->sendMessage(self::PREFIX . "§4Succefully set seeking time of hide and seek game in level {$sender->getLevel()->getName()} to {$args[1]}.");
} else {
$sender->sendMessage("§4Usage: /hideandseek setseektime <minutes of seeking>");
}
return true;
} else {
$sender->sendMessage(self::PREFIX . "§4You're not in an hide and seek game world.");
}
break;
case "setspawn":
case "ss":
$pos = new \pocketmine\math\Vector3($sender->x, $sender->y, $sender->z);
$game = $this->getGameManager()->getGameByLevel($sender->getLevel());
if(!is_null($game)) {
$game->setSpawn($args[1]);
$sender->sendMessage(self::PREFIX . "§4Succefully set spawn of hide and seek game in level {$sender->getLevel()->getName()} to x: $pos->x, y: $pos->y, z: $pos->z.");
return true;
} else {
$sender->sendMessage(self::PREFIX . "§4You're not in an hide and seek game world.");
}
break;
case "setspawn":
case "ss":
$pos = new \pocketmine\math\Vector3($sender->x, $sender->y, $sender->z);
$game = $this->getGameManager()->getGameByLevel($sender->getLevel());
if(!is_null($game)) {
$game->setSpawn($args[1]);
$sender->sendMessage(self::PREFIX . "§4Succefully set spawn of hide and seek game in level {$sender->getLevel()->getName()} to x: $pos->x, y: $pos->y, z: $pos->z.");
return true;
} else {
$sender->sendMessage(self::PREFIX . "§4You're not in an hide and seek game world.");
}
break;
case "setseekersspawn":
case "sss":
$pos = new \pocketmine\math\Vector3($sender->x, $sender->y, $sender->z);
$game = $this->getGameManager()->getGameByLevel($sender->getLevel());
if(!is_null($game)) {
$game->setSeekersSpawn($args[1]);
$sender->sendMessage(self::PREFIX . "§4Succefully set seekers spawn of hide and seek game in level {$sender->getLevel()->getName()} to x: $pos->x, y: $pos->y, z: $pos->z.");
return true;
} else {
$sender->sendMessage(self::PREFIX . "§4You're not in an hide and seek game world.");
}
break;
}
return true;
} else {
return false;
}
break;
}
}


# _____ _____
# /\ | __ \ |_ _|
# / \ | |__) | | |
# / /\ \ | ___/ | |
# / ____ \ | | _| |_
# /_/ \_\ |_| |_____|

/*
Returns the db.
@return \Ad5001\HideAndSeek\Database
*/
public function getDatabase() : Database {
return $this->db;
}

/*
Returns the game manager.
@param
@return GameManager
*/
public function getGameManager() : GameManager {
return $this->gamemanager;
}


/*
Returns the max players in a game.
@return int
*/
public function getMaxPlayers() : int {
return (int) $this->getConfig()->get("Max players");
}

/*
Returns the time to wait between 75% of max players joined and the game start (ending filling if needed)
@return int
*/
public function getWaitTime() : int {
return (int) $this->getConfig()->get("Waiting time");
}

/*
Returns the time that the seekers have to find all hiders (used to balance with the max players)
@return int
*/
public function getSeekTime() : int {
return (int) $this->getConfig()->get("Seeking time");
}

/*
Returns the world players should be tped to when game ends
@return \pocketmine\level\Level
*/
public function getLobbyWorld() : \pocketmine\level\Level {
return $this->getServer()->getLevelByName($this->getConfig()->get("Lobby world")) ?? $this->getServer()->getDefaultLevel();
}

/*
Returns the percentage of the players that should be hunters.
@return int
*/
public function getSeekersPercentage() : int {
return (int) $this->getConfig()->get("Seekers percentage");
}


# ______ _
# | ____| | |
# | |__ __ __ ___ _ __ | |_ ___
# | __| \ \ / / / _ \ | '_ \ | __| / __|
# | |____ \ V / | __/ | | | | | |_ \__ \
# |______| \_/ \___| |_| |_| \__| |___/
#
#

/*
Check when a level loads to check if it's a game and then add it
@param $event \pocketmine\event\level\LevelLoadEvent
*/
public function onLevelLoad(\pocketmine\event\level\LevelLoadEvent $event) {
$this->getGameManager()->refreshRegisterGames();
}
}

+ 39
- 0
src/Ad5001/HideAndSeek/tasks/SignsTasks.php View File

@@ -0,0 +1,39 @@
<?php
# _ _ _ _ _ _____ _
# | | | | (_) | | /\ | | / ____| | |
# | |__| | _ __| | ___ / \ _ __ __| | | (___ ___ ___ | | __
# | __ | | | / _` | / _ \ / /\ \ | '_ \ / _` | \___ \ / _ \ / _ \ | |/ /
# | | | | | | | (_| | | __/ / ____ \ | | | | | (_| | ____) | | __/ | __/ | <
# |_| |_| |_| \__,_| \___| /_/ \_\ |_| |_| \__,_| |_____/ \___| \___| |_|\_\
#
#
# The original minigame, free, and better than ever !
# @author Ad5001
# @link ad5001.eu

namespace Ad5001\HideAndSeek\tasks;

use pocketmine\Server;
use pocketmine\schedulerPluginTask;
use pocketmine\Player;

use Ad5001\HideAndSeek\Main;



class Task1 extends PluginTask {


public function __construct(Main $main) {
parent::__construct($main);
$this->main = $main;
$this->server = $main->getServer();
}


public function onRun($tick) {
$this->main->getLogger()->debug('Task ' . get_class($this) . ' is running on $tick');
}


}

Loading…
Cancel
Save