add Pick And Ban draft plugin
This commit is contained in:
@@ -0,0 +1,819 @@
|
||||
<?php
|
||||
|
||||
namespace MatchManagerSuite;
|
||||
|
||||
use Exception;
|
||||
use ManiaControl\Callbacks\CallbackListener;
|
||||
use ManiaControl\Callbacks\Callbacks;
|
||||
use ManiaControl\Callbacks\TimerListener;
|
||||
use ManiaControl\Logger;
|
||||
use ManiaControl\ManiaControl;
|
||||
use ManiaControl\Manialinks\ManialinkPageAnswerListener;
|
||||
use ManiaControl\Players\Player;
|
||||
use ManiaControl\Plugins\Plugin;
|
||||
use ManiaControl\Plugins\PluginManager;
|
||||
use ManiaControl\Plugins\PluginMenu;
|
||||
|
||||
if (!class_exists('MatchManagerSuite\MatchManagerCore')) {
|
||||
$this->maniaControl->getChat()->sendErrorToAdmins('MatchManager Core is required to use MatchManagerPickAndBan plugin. Install it and restart Maniacontrol');
|
||||
Logger::logError('MatchManager Core is required to use MatchManagerPickAndBan plugin. Install it and restart Maniacontrol');
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* MatchManager Pick and Ban
|
||||
*
|
||||
* @author Beu
|
||||
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
|
||||
*/
|
||||
class MatchManagerPickAndBan implements ManialinkPageAnswerListener, CallbackListener, TimerListener, Plugin {
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
const PLUGIN_ID = 223;
|
||||
const PLUGIN_VERSION = 0.1;
|
||||
const PLUGIN_NAME = 'MatchManager Pick & Ban';
|
||||
const PLUGIN_AUTHOR = 'Beu';
|
||||
|
||||
const LOG_PREFIX = '[MatchManagerPickAndBan] ';
|
||||
|
||||
// Settings
|
||||
const SETTING_ENABLE = 'Enable pick & ban';
|
||||
const SETTING_STEPCONFIG = 'Step config';
|
||||
const SETTING_STEPDURATION = 'Step duration';
|
||||
|
||||
// Other MatchManager plugin
|
||||
const MATCHMANAGERCORE_PLUGIN = 'MatchManagerSuite\MatchManagerCore';
|
||||
const MATCHMANAGERADMINUI_PLUGIN = 'MatchManagerSuite\MatchManagerAdminUI';
|
||||
|
||||
// Steps
|
||||
const ML_STEP_OPENSETTINGS = 'MatchManagerSuite\MatchManagerPickAndBan.OpenSettings';
|
||||
const ML_STEP_MAPCHOOSENREGEX = '/^MatchManagerPickAndBan_MapChoosen:.*/';
|
||||
|
||||
/*
|
||||
* Private properties
|
||||
*/
|
||||
private ManiaControl $maniaControl;
|
||||
private MatchManagerCore $MatchManagerCore;
|
||||
private MatchManagerPickAndBan_State $state;
|
||||
|
||||
/**
|
||||
* @param \ManiaControl\ManiaControl $maniaControl
|
||||
* @see \ManiaControl\Plugins\Plugin::prepare()
|
||||
*/
|
||||
public static function prepare(ManiaControl $maniaControl) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ManiaControl\Plugins\Plugin::getId()
|
||||
*/
|
||||
public static function getId() {
|
||||
return self::PLUGIN_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ManiaControl\Plugins\Plugin::getName()
|
||||
*/
|
||||
public static function getName() {
|
||||
return self::PLUGIN_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ManiaControl\Plugins\Plugin::getVersion()
|
||||
*/
|
||||
public static function getVersion() {
|
||||
return self::PLUGIN_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ManiaControl\Plugins\Plugin::getAuthor()
|
||||
*/
|
||||
public static function getAuthor() {
|
||||
return self::PLUGIN_AUTHOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ManiaControl\Plugins\Plugin::getDescription()
|
||||
*/
|
||||
public static function getDescription() {
|
||||
return 'Pick & Ban plugin for MatchManager';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ManiaControl\ManiaControl $maniaControl
|
||||
* @return bool
|
||||
* @see \ManiaControl\Plugins\Plugin::load()
|
||||
*/
|
||||
public function load(ManiaControl $maniaControl) {
|
||||
$this->maniaControl = $maniaControl;
|
||||
|
||||
$this->clearManialinks();
|
||||
|
||||
$this->MatchManagerCore = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERCORE_PLUGIN);
|
||||
|
||||
if ($this->MatchManagerCore == Null) {
|
||||
throw new \Exception('MatchManager Core is needed to use ' . self::PLUGIN_NAME);
|
||||
}
|
||||
|
||||
$this->state = new MatchManagerPickAndBan_State;
|
||||
|
||||
// Settings
|
||||
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_ENABLE, true, '', 0);
|
||||
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_STEPCONFIG, '', '', 0);
|
||||
$this->maniaControl->getSettingManager()->initSetting($this, self::SETTING_STEPDURATION, 60, '', 0);
|
||||
|
||||
// Callbacks
|
||||
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerListener(self::ML_STEP_OPENSETTINGS, $this, 'handleStepOpenSettings');
|
||||
$this->maniaControl->getManialinkManager()->registerManialinkPageAnswerRegexListener(self::ML_STEP_MAPCHOOSENREGEX, $this, 'handleStepMapChoosen');
|
||||
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::AFTERINIT, $this, 'handleAfterInit');
|
||||
$this->maniaControl->getCallbackManager()->registerCallbackListener(PluginManager::CB_PLUGIN_LOADED, $this, 'handlePluginLoaded');
|
||||
$this->maniaControl->getCallbackManager()->registerCallbackListener($this->MatchManagerCore::CB_MATCHMANAGER_ENDMATCH, $this, 'handleEndMatch');
|
||||
$this->maniaControl->getCallbackManager()->registerCallbackListener($this->MatchManagerCore::CB_MATCHMANAGER_STOPMATCH, $this, 'handleEndMatch');
|
||||
|
||||
$this->MatchManagerCore->addCanStartFunction($this, 'handleCanStartMatch');
|
||||
|
||||
$this->updateAdminUIMenuItems();
|
||||
|
||||
$this->sendStateToPlayers();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ManiaControl\Plugins\Plugin::unload()
|
||||
*/
|
||||
public function unload() {
|
||||
/** @var \MatchManagerSuite\MatchManagerAdminUI|null */
|
||||
$adminUIPlugin = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERADMINUI_PLUGIN);
|
||||
if ($adminUIPlugin !== null) {
|
||||
$adminUIPlugin->removeMenuItem(self::ML_STEP_OPENSETTINGS);
|
||||
}
|
||||
|
||||
$this->clearManialinks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom log function to add prefix
|
||||
*
|
||||
* @param mixed $message
|
||||
*/
|
||||
private function log(mixed $message) {
|
||||
Logger::log(self::LOG_PREFIX . $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom logError function to add prefix
|
||||
*
|
||||
* @param mixed $message
|
||||
*/
|
||||
private function logError(mixed $message) {
|
||||
Logger::logError(self::LOG_PREFIX . $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* handle Plugin Loaded
|
||||
*/
|
||||
public function handleAfterInit() {
|
||||
$this->updateAdminUIMenuItems();
|
||||
}
|
||||
|
||||
/**
|
||||
* handle Plugin Loaded
|
||||
*
|
||||
* @param string $pluginClass
|
||||
*/
|
||||
public function handlePluginLoaded(string $pluginClass) {
|
||||
if ($pluginClass === self::MATCHMANAGERADMINUI_PLUGIN) {
|
||||
$this->updateAdminUIMenuItems();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add items in AdminUI plugin
|
||||
*/
|
||||
public function updateAdminUIMenuItems() {
|
||||
/** @var \MatchManagerSuite\MatchManagerAdminUI|null */
|
||||
$adminUIPlugin = $this->maniaControl->getPluginManager()->getPlugin(self::MATCHMANAGERADMINUI_PLUGIN);
|
||||
if ($adminUIPlugin === null) return;
|
||||
|
||||
$adminUIPlugin->removeMenuItem(self::ML_STEP_OPENSETTINGS);
|
||||
|
||||
$menuItem = new \MatchManagerSuite\MatchManagerAdminUI_MenuItem();
|
||||
$menuItem->setActionId(self::ML_STEP_OPENSETTINGS)
|
||||
->setOrder(40)
|
||||
->setStyle('MeshModelerIcons')
|
||||
->setSubStyle('LayersFocused')
|
||||
->setDescription('Open Pick & Ban Settings');
|
||||
$adminUIPlugin->addMenuItem($menuItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* manage Step
|
||||
*/
|
||||
public function manageStep() {
|
||||
// Do random pick
|
||||
while (
|
||||
array_key_exists($this->state->stepIndex, $this->state->steps) &&
|
||||
$this->state->steps[$this->state->stepIndex]->login === ""
|
||||
) {
|
||||
$availableMaps = array_filter($this->state->maps, function($map) {
|
||||
return !$map->picked && !$map->banned;
|
||||
});
|
||||
|
||||
$mapUid = array_rand($availableMaps);
|
||||
|
||||
$this->state->maps[$mapUid]->banned = ($this->state->steps[$this->state->stepIndex]->type === MatchManagerPickAndBan_Step::STEP_BAN);
|
||||
$this->state->maps[$mapUid]->picked = ($this->state->steps[$this->state->stepIndex]->type === MatchManagerPickAndBan_Step::STEP_PICK);
|
||||
|
||||
$this->state->steps[$this->state->stepIndex]->mapUid = $mapUid;
|
||||
$this->state->stepIndex++;
|
||||
}
|
||||
|
||||
$this->state->startTimestamp = time();
|
||||
$this->state->endTimestamp = time() + $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_STEPDURATION);
|
||||
|
||||
$this->sendStateToPlayers();
|
||||
}
|
||||
|
||||
/**
|
||||
* handle timer
|
||||
* @return void
|
||||
*/
|
||||
public function handleTimer() {
|
||||
if ($this->state->status !== MatchManagerPickAndBan_State::STATUS_INPROGRESS) {
|
||||
$this->maniaControl->getTimerManager()->unregisterTimerListening($this, 'handleTimer');
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->state->endTimestamp < time()) {
|
||||
if (array_key_exists($this->state->stepIndex, $this->state->steps)) {
|
||||
$this->state->steps[$this->state->stepIndex]->login = "";
|
||||
$this->manageStep();
|
||||
} else {
|
||||
$this->log("Start match");
|
||||
$this->state->status = MatchManagerPickAndBan_State::STATUS_COMPLETED;
|
||||
$this->MatchManagerCore->MatchStart();
|
||||
$this->clearManialinks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* handle Open settings manialink step
|
||||
*
|
||||
* @param array $callback
|
||||
* @param Player $player
|
||||
*/
|
||||
public function handleStepOpenSettings(array $callback, Player $player) {
|
||||
if ($player->authLevel <= 0) return;
|
||||
|
||||
$pluginMenu = $this->maniaControl->getPluginManager()->getPluginMenu();
|
||||
if (defined("\ManiaControl\ManiaControl::ISTRACKMANIACONTROL")) {
|
||||
$player->setCache($pluginMenu, PluginMenu::CACHE_SETTING_CLASS, "PluginMenu.Settings." . self::class);
|
||||
} else {
|
||||
$player->setCache($pluginMenu, PluginMenu::CACHE_SETTING_CLASS, self::class);
|
||||
}
|
||||
$this->maniaControl->getConfigurator()->showMenu($player, $pluginMenu);
|
||||
}
|
||||
|
||||
/**
|
||||
* handle Map Choosen
|
||||
*
|
||||
* @param array $callback
|
||||
* @param Player $player
|
||||
*/
|
||||
public function handleStepMapChoosen(array $callback, Player $player) {
|
||||
if ($this->state->status !== MatchManagerPickAndBan_State::STATUS_INPROGRESS) return;
|
||||
if (!array_key_exists($this->state->stepIndex, $this->state->steps)) return;
|
||||
|
||||
if ($this->state->steps[$this->state->stepIndex]->login !== $player->login) return;
|
||||
|
||||
$step = $callback[1][2];
|
||||
$stepArray = explode(':', $step);
|
||||
|
||||
if (count($stepArray) !== 2) return;
|
||||
|
||||
$mapUid = $stepArray[1];
|
||||
|
||||
if (!array_key_exists($mapUid, $this->state->maps)) return;
|
||||
|
||||
$this->state->maps[$mapUid]->banned = ($this->state->steps[$this->state->stepIndex]->type === MatchManagerPickAndBan_Step::STEP_BAN);
|
||||
$this->state->maps[$mapUid]->picked = ($this->state->steps[$this->state->stepIndex]->type === MatchManagerPickAndBan_Step::STEP_PICK);
|
||||
|
||||
$this->state->steps[$this->state->stepIndex]->mapUid = $mapUid;
|
||||
$this->state->stepIndex++;
|
||||
|
||||
$this->manageStep();
|
||||
}
|
||||
|
||||
/**
|
||||
* handle MatchManagerCore Can Start Match callback
|
||||
*/
|
||||
public function handleCanStartMatch() {
|
||||
if (!$this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_ENABLE)) return true;
|
||||
|
||||
if ($this->state->status === MatchManagerPickAndBan_State::STATUS_COMPLETED) {
|
||||
$maplist = [];
|
||||
foreach ($this->state->steps as $step) {
|
||||
if ($step->type !== MatchManagerPickAndBan_Step::STEP_PICK) continue;
|
||||
if (!array_key_exists($step->mapUid, $this->state->maps)) {
|
||||
$this->logError("Picked map doesn't exist in map list, should never happen.");
|
||||
$this->maniaControl->getChat()->sendErrorToAdmins($this->MatchManagerCore->getChatPrefix() . "Picked map doesn't exist in map list, should never happen.");
|
||||
|
||||
$this->state = new MatchManagerPickAndBan_State;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$maplist[] = $this->state->maps[$step->mapUid]->filePath;
|
||||
}
|
||||
|
||||
$setting = $this->maniaControl->getSettingManager()->getSettingObject($this->MatchManagerCore, $this->MatchManagerCore::SETTING_MODE_MAPS);
|
||||
$setting->value = implode(',', $maplist);
|
||||
|
||||
$this->log('Starting match with maps "'. $setting->value .'"');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->state->status === MatchManagerPickAndBan_State::STATUS_INPROGRESS) {
|
||||
$this->maniaControl->getChat()->sendErrorToAdmins($this->MatchManagerCore->getChatPrefix() . "Pick and Ban in progress");
|
||||
return false;
|
||||
}
|
||||
|
||||
$stepConfig = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_STEPCONFIG);
|
||||
if ($stepConfig === '') {
|
||||
$this->maniaControl->getChat()->sendErrorToAdmins($this->MatchManagerCore->getChatPrefix() . "'Step config' setting must be set");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->maniaControl->getSettingManager()->getSettingValue($this->MatchManagerCore, $this->MatchManagerCore::SETTING_MATCH_SETTINGS_MODE) !== 'All from the plugin') {
|
||||
$this->maniaControl->getChat()->sendErrorToAdmins($this->MatchManagerCore->getChatPrefix() . "Setting mode must be in 'All from the plugin' to use Pick & Ban");
|
||||
return false;
|
||||
}
|
||||
|
||||
$mapFiles = $this->maniaControl->getSettingManager()->getSettingValue($this->MatchManagerCore, $this->MatchManagerCore::SETTING_MODE_MAPS);
|
||||
if ($mapFiles === '') {
|
||||
$this->maniaControl->getChat()->sendErrorToAdmins($this->MatchManagerCore->getChatPrefix() . "Maps must be defined to use Pick & Ban");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count(explode(',', $mapFiles)) < count(explode(',', $stepConfig))) {
|
||||
$this->maniaControl->getChat()->sendErrorToAdmins($this->MatchManagerCore->getChatPrefix() . "You must have at least same number of maps than steps");
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->log('Building Pick & Ban config');
|
||||
|
||||
$this->state = new MatchManagerPickAndBan_State;
|
||||
$this->state->status = MatchManagerPickAndBan_State::STATUS_INPROGRESS;
|
||||
$this->state->originalMapList = $mapFiles;
|
||||
|
||||
// build map config
|
||||
$maps = [];
|
||||
foreach (explode(',', $mapFiles) as $mapPath) {
|
||||
try {
|
||||
$mapInfo = $this->maniaControl->getClient()->getMapInfo($mapPath);
|
||||
|
||||
$mapObject = new MatchManagerPickAndBan_Map();
|
||||
$mapObject->mapUid = $mapInfo->uId;
|
||||
$mapObject->filePath = $mapPath;
|
||||
$mapObject->name = $mapInfo->name;
|
||||
$maps[$mapInfo->uId] = $mapObject;
|
||||
|
||||
} catch (Exception $e) {
|
||||
$this->maniaControl->getChat()->sendErrorToAdmins($this->MatchManagerCore->getChatPrefix() . 'Error with the Map to play "' . $mapPath . '": ' . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uasort($maps, function ($a, $b) {
|
||||
return strnatcasecmp($a->name, $b->name);
|
||||
});
|
||||
|
||||
$this->state->maps = $maps;
|
||||
$this->log(count($this->state->maps) . ' maps loaded for Pick & Ban');
|
||||
|
||||
// build steps
|
||||
$steps = [];
|
||||
foreach (explode(',', $stepConfig) as $index => $stepRaw) {
|
||||
$stepArray = explode(':', $stepRaw);
|
||||
if (count($stepArray) !== 2) {
|
||||
$this->maniaControl->getChat()->sendErrorToAdmins($this->MatchManagerCore->getChatPrefix() . 'Invalid step ' . $index . 'config: ' . $stepRaw);
|
||||
return false;
|
||||
}
|
||||
|
||||
$step = new MatchManagerPickAndBan_Step;
|
||||
|
||||
if ($stepArray[0] === 'p') {
|
||||
$step->type = MatchManagerPickAndBan_Step::STEP_PICK;
|
||||
} else if ($stepArray[0] === 'b') {
|
||||
$step->type = MatchManagerPickAndBan_Step::STEP_BAN;
|
||||
}
|
||||
|
||||
if ($stepArray[1] === 'r') {
|
||||
$step->login = "";
|
||||
} else {
|
||||
$step->login = $stepArray[1];
|
||||
}
|
||||
$steps[] = $step;
|
||||
}
|
||||
$this->state->steps = $steps;
|
||||
$this->log(count($this->state->steps) . ' steps loaded for Pick & Ban');
|
||||
|
||||
$this->maniaControl->getChat()->sendSuccess('Starting Pick & Ban phase');
|
||||
$this->log('Starting Pick & Ban phase');
|
||||
$this->sendManialink();
|
||||
$this->manageStep();
|
||||
|
||||
$this->maniaControl->getTimerManager()->registerTimerListening($this, 'handleTimer', 1000);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function handleEndMatch() {
|
||||
if ($this->state->status === MatchManagerPickAndBan_State::STATUS_COMPLETED) {
|
||||
$setting = $this->maniaControl->getSettingManager()->getSettingObject($this->MatchManagerCore, $this->MatchManagerCore::SETTING_MODE_MAPS);
|
||||
$setting->value = $this->state->originalMapList;
|
||||
$this->state = new MatchManagerPickAndBan_State;
|
||||
}
|
||||
}
|
||||
|
||||
private function sendManialink(): void {
|
||||
$manialink = '
|
||||
<manialink version="3" id="'. self::getShortClassName() .':UI" name="'. self::getShortClassName() . ':UI">
|
||||
<stylesheet>
|
||||
<style class="text" textfont="GameFontExtraBold" textcolor="ffffff" />
|
||||
</stylesheet>
|
||||
<framemodel id="framemodel-map">
|
||||
<quad id="quad-thumbnail" size="50 33" halign="center" valign="center" bgcolor="555555" keepratio="Clip" scriptevents="1"/>
|
||||
<frame pos="0 -10.5">
|
||||
<quad id="quad-map-name-background" size="50 5.5" halign="center" valign="center" bgcolor="000000" opacity="0.5"/>
|
||||
<label id="label-map-name" class="text" pos="0 0.4" size="45 5" halign="center" valign="center" textsize="1.8" text="Map name"/>
|
||||
</frame>
|
||||
</framemodel>
|
||||
<framemodel id="framemodel-step">
|
||||
<quad id="quad-thumbnail" size="80 14" halign="center" valign="center" bgcolor="555555" keepratio="Clip"/>
|
||||
<frame pos="0 0">
|
||||
<frame id="frame-map-name" pos="0 7">
|
||||
<quad size="80 5.5" halign="center" bgcolor="000000" opacity="0.5"/>
|
||||
<label id="label-map-name" class="text" pos="0 -2.3" size="45 5" halign="center" valign="center" textsize="1.8" text="Map name"/>
|
||||
</frame>
|
||||
<label id="label-step" class="text" pos="0 -2.3" size="75 8" halign="center" valign="center" textsize="3" textprefix="$t$s" text="Banned By CARLJR."/>
|
||||
</frame>
|
||||
</framemodel>
|
||||
<frame id="frame-global" hidden="1">
|
||||
<quad size="320 180" fullscreen="1" halign="center" valign="center" image="file://Media/Manialinks/Nadeo/Trackmania/Menus/PageProfile/UI_profile_background_map_gradients.dds"/>
|
||||
<frame pos="-160 0">
|
||||
<label class="text" pos="116 80" halign="center" textsize="10" text="Pick & Ban"/>
|
||||
<frame id="frame-maps" pos="116 0">
|
||||
<frameinstance modelid="framemodel-map" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-map" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-map" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-map" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-map" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-map" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-map" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-map" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-map" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-map" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-map" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-map" hidden="1"/>
|
||||
</frame>
|
||||
<label id="label-timer" class="text" pos="116 -77" halign="center" textsize="8" text=""/>
|
||||
<quad pos="116 -88" size="232 2" halign="center" bgcolor="ffffff" opacity="0.4"/>
|
||||
<quad id="quad-timer" pos="116 -88" size="0 2" halign="center" bgcolor="ffffff"/>
|
||||
</frame>
|
||||
<frame pos="72 0">
|
||||
<quad size="120 180" valign="center" bgcolor="000000" opacity="0.2"/>
|
||||
<frame id="frame-steps" pos="44 0">
|
||||
<frameinstance modelid="framemodel-step" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-step" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-step" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-step" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-step" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-step" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-step" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-step" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-step" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-step" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-step" hidden="1"/>
|
||||
<frameinstance modelid="framemodel-step" hidden="1"/>
|
||||
</frame>
|
||||
</frame>
|
||||
</frame>
|
||||
<script><!--
|
||||
#Include "MathLib" as ML
|
||||
#Include "TextLib" as TL
|
||||
#Include "TimeLib" as TiL
|
||||
|
||||
#Include "Libs/Nadeo/CMGame/Utils/Tools.Script.txt" as Tools
|
||||
#Include "Libs/Nadeo/Trackmania/Stores/UserStore_ML.Script.txt" as UserStore
|
||||
|
||||
|
||||
#Const C_Status_InProgress 1
|
||||
|
||||
#Const C_StepType_Pick 1
|
||||
#Const C_StepType_Ban 2
|
||||
|
||||
#Const C_Color_White <1., 1., 1.>
|
||||
#Const C_Color_Gray <.7, .7, .7>
|
||||
#Const C_Color_Reset <-1., -1., -1.>
|
||||
|
||||
'. $this->getManialinkStructures() . '
|
||||
|
||||
Void Focus(CMlFrame _Frame) {
|
||||
declare CMlQuad Quad <=> (_Frame.GetFirstChild("quad-map-name-background") as CMlQuad);
|
||||
Quad.BgColor = <.1, .1, .1>;
|
||||
AnimMgr.Flush(_Frame);
|
||||
AnimMgr.Add(_Frame, "<a scale=\"1.05\" />", 200, CAnimManager::EAnimManagerEasing::Linear);
|
||||
}
|
||||
Void Unfocus(CMlFrame _Frame) {
|
||||
declare CMlQuad Quad <=> (_Frame.GetFirstChild("quad-map-name-background") as CMlQuad);
|
||||
Quad.BgColor = <0., 0., 0.>;
|
||||
AnimMgr.Flush(_Frame);
|
||||
AnimMgr.Add(_Frame, "<a scale=\"1\" />", 200, CAnimManager::EAnimManagerEasing::Linear);
|
||||
}
|
||||
|
||||
main() {
|
||||
log("['. self::getShortClassName() .'] Loading UI");
|
||||
declare CMlFrame Frame_Global <=> (Page.GetFirstChild("frame-global") as CMlFrame);
|
||||
declare CMlFrame Frame_Maps <=> (Frame_Global.GetFirstChild("frame-maps") as CMlFrame);
|
||||
declare CMlFrame Frame_Steps <=> (Frame_Global.GetFirstChild("frame-steps") as CMlFrame);
|
||||
declare CMlLabel Label_Timer <=> (Frame_Global.GetFirstChild("label-timer") as CMlLabel);
|
||||
declare CMlQuad Quad_Timer <=> (Frame_Global.GetFirstChild("quad-timer") as CMlQuad);
|
||||
|
||||
wait(InputPlayer != Null);
|
||||
|
||||
declare K_MatchManagerPickAndBan_State MatchManagerPickAndBan_State for This;
|
||||
declare Integer MatchManagerPickAndBan_State_Serial for This;
|
||||
declare Integer Last_State_Serial = -1;
|
||||
|
||||
declare Integer Last_Timer_Update ;
|
||||
|
||||
while(True) {
|
||||
yield;
|
||||
if (Last_State_Serial != MatchManagerPickAndBan_State_Serial) {
|
||||
Last_State_Serial = MatchManagerPickAndBan_State_Serial;
|
||||
log("New state " ^ MatchManagerPickAndBan_State);
|
||||
|
||||
Frame_Global.Visible = (MatchManagerPickAndBan_State.status == C_Status_InProgress);
|
||||
if (Frame_Global.Visible) {
|
||||
|
||||
// Build maps
|
||||
declare Integer Index = 0;
|
||||
declare Integer MapsCount = MatchManagerPickAndBan_State.maps.count;
|
||||
declare Integer MapsPerLine = 4;
|
||||
declare Integer NbLines = (MapsCount + MapsPerLine - 1) / MapsPerLine;
|
||||
declare Real StepX = 54.; // ElementW(50) + GapX(4)
|
||||
declare Real StepY = 37.; // ElementH(33) + GapY(4)
|
||||
|
||||
foreach (MapInfo in MatchManagerPickAndBan_State.maps) {
|
||||
if (!Frame_Maps.Controls.existskey(Index)) break;
|
||||
|
||||
declare CMlFrame Frame_Map <=> (Frame_Maps.Controls[Index] as CMlFrame);
|
||||
Frame_Map.Visible = True;
|
||||
|
||||
declare K_MatchManagerPickAndBan_Map MatchManagerPickAndBan_MapInfo for Frame_Map;
|
||||
MatchManagerPickAndBan_MapInfo = MapInfo;
|
||||
|
||||
declare Integer Row = Index / MapsPerLine;
|
||||
declare Integer Col = Index - (Row * MapsPerLine);
|
||||
declare Integer MapsOnThisRow;
|
||||
if (Row < NbLines - 1) {
|
||||
MapsOnThisRow = MapsPerLine;
|
||||
} else {
|
||||
MapsOnThisRow = MapsCount - (Row * MapsPerLine);
|
||||
}
|
||||
Frame_Map.RelativePosition_V3.X = (Col - (MapsOnThisRow - 1) / 2.) * StepX;
|
||||
Frame_Map.RelativePosition_V3.Y = -1. * (Row - (NbLines - 1) / 2.) * StepY;
|
||||
|
||||
declare CMlLabel Label_MapName <=> (Frame_Map.GetFirstChild("label-map-name") as CMlLabel);
|
||||
Label_MapName.Value = MapInfo.name;
|
||||
Tools::FitLabelValue(Label_MapName, 1.8, 0.5, 0.1);
|
||||
|
||||
declare CMlQuad Quad_MapThumbnail <=> (Frame_Map.GetFirstChild("quad-thumbnail") as CMlQuad);
|
||||
Quad_MapThumbnail.ImageUrl = "file://Thumbnails/MapUid/" ^ MapInfo.mapUid;
|
||||
|
||||
if (MapInfo.picked || MapInfo.banned) {
|
||||
Quad_MapThumbnail.Colorize = C_Color_White;
|
||||
Label_MapName.TextColor = C_Color_Gray;
|
||||
} else {
|
||||
Quad_MapThumbnail.Colorize = C_Color_Reset;
|
||||
Label_MapName.TextColor = C_Color_White;
|
||||
}
|
||||
|
||||
Index += 1;
|
||||
}
|
||||
while (Frame_Maps.Controls.existskey(Index)) {
|
||||
(Frame_Maps.Controls[Index] as CMlFrame).Visible = False;
|
||||
Index += 1;
|
||||
}
|
||||
|
||||
|
||||
// Build steps
|
||||
Index = 0;
|
||||
declare Integer StepsCount = MatchManagerPickAndBan_State.steps.count;
|
||||
|
||||
foreach (Step in MatchManagerPickAndBan_State.steps) {
|
||||
if (!Frame_Steps.Controls.existskey(Index)) break;
|
||||
|
||||
declare CMlFrame Frame_Step <=> (Frame_Steps.Controls[Index] as CMlFrame);
|
||||
Frame_Step.Visible = True;
|
||||
|
||||
declare Real StepStepY = 18.; // ElementH(14) + GapY(4)
|
||||
Frame_Step.RelativePosition_V3.Y = -1. * (Index - (StepsCount - 1) / 2.) * StepStepY;
|
||||
|
||||
declare CMlLabel Label_Step <=> (Frame_Step.GetFirstChild("label-step") as CMlLabel);
|
||||
declare CMlFrame Frame_MapName <=> (Frame_Step.GetFirstChild("frame-map-name") as CMlFrame);
|
||||
declare CMlQuad Quad_MapThumbnail <=> (Frame_Step.GetFirstChild("quad-thumbnail") as CMlQuad);
|
||||
|
||||
if (Step.mapUid == "") {
|
||||
Frame_MapName.Visible = False;
|
||||
Label_Step.RelativePosition_V3.Y = 0.4;
|
||||
Quad_MapThumbnail.ImageUrl = "";
|
||||
Quad_MapThumbnail.Colorize = C_Color_Reset;
|
||||
|
||||
if (Step.login == "") {
|
||||
if (Step.type == C_StepType_Ban) {
|
||||
Label_Step.Value = "Random ban";
|
||||
} else {
|
||||
Label_Step.Value = "Random pick";
|
||||
}
|
||||
} else if (Step.type == C_StepType_Ban) {
|
||||
Label_Step.Value = "Ban by "^ UserStore::GetUserMgrPlayerName(Step.login);
|
||||
} else {
|
||||
Label_Step.Value = "Pick by "^ UserStore::GetUserMgrPlayerName(Step.login);
|
||||
}
|
||||
} else {
|
||||
Frame_MapName.Visible = True;
|
||||
Label_Step.RelativePosition_V3.Y = -2.3;
|
||||
|
||||
declare K_MatchManagerPickAndBan_Map MapInfo = MatchManagerPickAndBan_State.maps.get(Step.mapUid, K_MatchManagerPickAndBan_Map {});
|
||||
|
||||
declare CMlLabel Label_MapName <=> (Frame_Step.GetFirstChild("label-map-name") as CMlLabel);
|
||||
Label_MapName.Value = MapInfo.name;
|
||||
Tools::FitLabelValue(Label_MapName, 1.8, 0.5, 0.1);
|
||||
|
||||
Quad_MapThumbnail.ImageUrl = "file://Thumbnails/MapUid/" ^ MapInfo.mapUid;
|
||||
|
||||
if (Step.login == "") {
|
||||
if (Step.type == C_StepType_Ban) {
|
||||
Label_Step.Value = "Randomly banned";
|
||||
Quad_MapThumbnail.Colorize = C_Color_White;
|
||||
} else {
|
||||
Label_Step.Value = "Randomly picked";
|
||||
Quad_MapThumbnail.Colorize = C_Color_Reset;
|
||||
}
|
||||
} else if (Step.type == C_StepType_Ban) {
|
||||
Label_Step.Value = "Banned by "^ UserStore::GetUserMgrPlayerName(Step.login);
|
||||
Quad_MapThumbnail.Colorize = C_Color_White;
|
||||
} else {
|
||||
Label_Step.Value = "Picked by "^ UserStore::GetUserMgrPlayerName(Step.login);
|
||||
Quad_MapThumbnail.Colorize = C_Color_Reset;
|
||||
}
|
||||
}
|
||||
|
||||
Tools::FitLabelValue(Label_Step, 3., 1., 0.25);
|
||||
Index += 1;
|
||||
}
|
||||
while (Frame_Steps.Controls.existskey(Index)) {
|
||||
(Frame_Steps.Controls[Index] as CMlFrame).Visible = False;
|
||||
Index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Event in PendingEvents) {
|
||||
if (Event.Type == CMlScriptEvent::Type::MouseOut && Event.ControlId == "quad-thumbnail") {
|
||||
Unfocus(Event.Control.Parent);
|
||||
} else if (
|
||||
MatchManagerPickAndBan_State.steps.existskey(MatchManagerPickAndBan_State.stepIndex) &&
|
||||
MatchManagerPickAndBan_State.steps[MatchManagerPickAndBan_State.stepIndex].login == InputPlayer.User.Login
|
||||
) {
|
||||
if (Event.Type == CMlScriptEvent::Type::MouseOver && Event.ControlId == "quad-thumbnail") {
|
||||
declare K_MatchManagerPickAndBan_Map MatchManagerPickAndBan_MapInfo for Event.Control.Parent;
|
||||
if (MatchManagerPickAndBan_MapInfo.picked || MatchManagerPickAndBan_MapInfo.banned) continue;
|
||||
|
||||
Focus(Event.Control.Parent);
|
||||
} else if (Event.Type == CMlScriptEvent::Type::MouseClick && Event.ControlId == "quad-thumbnail") {
|
||||
declare K_MatchManagerPickAndBan_Map MatchManagerPickAndBan_MapInfo for Event.Control.Parent;
|
||||
if (MatchManagerPickAndBan_MapInfo.picked || MatchManagerPickAndBan_MapInfo.banned) continue;
|
||||
|
||||
TriggerPageAction("MatchManagerPickAndBan_MapChoosen:"^ MatchManagerPickAndBan_MapInfo.mapUid);
|
||||
Unfocus(Event.Control.Parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Last_Timer_Update < Now) {
|
||||
Last_Timer_Update = Now + 100;
|
||||
if (MatchManagerPickAndBan_State.startTimestamp != 0 && MatchManagerPickAndBan_State.endTimestamp != 0) {
|
||||
declare Integer RemainingTime = ML::Max(MatchManagerPickAndBan_State.endTimestamp - TL::ToInteger(TiL::GetCurrent()), 0);
|
||||
Label_Timer.Value = ""^ RemainingTime;
|
||||
declare Real Width = RemainingTime * 232. / (MatchManagerPickAndBan_State.endTimestamp - MatchManagerPickAndBan_State.startTimestamp);
|
||||
AnimMgr.Flush(Quad_Timer);
|
||||
AnimMgr.Add(Quad_Timer, "<a size=\""^ Width ^" 2\"/>", 100, CAnimManager::EAnimManagerEasing::Linear);
|
||||
} else {
|
||||
AnimMgr.Flush(Quad_Timer);
|
||||
AnimMgr.Add(Quad_Timer, "<a size=\"0 2\"/>", 100, CAnimManager::EAnimManagerEasing::Linear);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
--></script>
|
||||
</manialink>
|
||||
';
|
||||
|
||||
$this->maniaControl->getManialinkManager()->sendManialink($manialink);
|
||||
}
|
||||
|
||||
private function sendStateToPlayers(): void {
|
||||
$manialink = '
|
||||
<manialink version="3" id="'. self::getShortClassName() .':State" name="'. self::getShortClassName() . ':State">
|
||||
<script><!--
|
||||
|
||||
#Const C_State """'. json_encode($this->state) .'"""
|
||||
|
||||
'. $this->getManialinkStructures() . '
|
||||
|
||||
main() {
|
||||
log("['. self::getShortClassName() .'] Updating State");
|
||||
declare K_MatchManagerPickAndBan_State MatchManagerPickAndBan_State for This;
|
||||
MatchManagerPickAndBan_State.fromjson(C_State);
|
||||
declare Integer MatchManagerPickAndBan_State_Serial for This;
|
||||
MatchManagerPickAndBan_State_Serial += 1;
|
||||
}
|
||||
--></script>
|
||||
</manialink>';
|
||||
$this->maniaControl->getManialinkManager()->sendManialink($manialink);
|
||||
}
|
||||
|
||||
private function clearManialinks() {
|
||||
$this->maniaControl->getManialinkManager()->hideManialink(self::getShortClassName() . ':UI');
|
||||
$this->maniaControl->getManialinkManager()->hideManialink(self::getShortClassName() . ':State');
|
||||
}
|
||||
|
||||
private function getManialinkStructures(): string {
|
||||
return '
|
||||
#Struct K_MatchManagerPickAndBan_Step {
|
||||
Integer type;
|
||||
Text login;
|
||||
Text mapUid;
|
||||
}
|
||||
|
||||
#Struct K_MatchManagerPickAndBan_Map {
|
||||
Text mapUid;
|
||||
Text name;
|
||||
Boolean picked;
|
||||
Boolean banned;
|
||||
}
|
||||
|
||||
#Struct K_MatchManagerPickAndBan_State {
|
||||
Integer status;
|
||||
Integer stepIndex;
|
||||
Integer startTimestamp;
|
||||
Integer endTimestamp;
|
||||
K_MatchManagerPickAndBan_Map[Text] maps;
|
||||
K_MatchManagerPickAndBan_Step[] steps;
|
||||
}
|
||||
';
|
||||
}
|
||||
|
||||
private static function getShortClassName(): string {
|
||||
return (new \ReflectionClass(static::class))->getShortName();
|
||||
}
|
||||
}
|
||||
|
||||
class MatchManagerPickAndBan_State {
|
||||
// States
|
||||
const STATUS_WAITING = 0;
|
||||
const STATUS_INPROGRESS = 1;
|
||||
const STATUS_COMPLETED = 2;
|
||||
|
||||
public int $status = self::STATUS_WAITING;
|
||||
public string $originalMapList = '';
|
||||
public int $stepIndex = 0;
|
||||
public int $startTimestamp;
|
||||
public int $endTimestamp;
|
||||
public array $steps = [];
|
||||
public array $maps = [];
|
||||
}
|
||||
|
||||
class MatchManagerPickAndBan_Step {
|
||||
// Steps
|
||||
const STEP_PICK = 1;
|
||||
const STEP_BAN = 2;
|
||||
|
||||
public int $type;
|
||||
public string $login;
|
||||
public string $mapUid;
|
||||
}
|
||||
|
||||
class MatchManagerPickAndBan_Map {
|
||||
public string $mapUid;
|
||||
public string $filePath;
|
||||
public string $name;
|
||||
public bool $picked = false;
|
||||
public bool $banned = false;
|
||||
}
|
||||
Reference in New Issue
Block a user