Permalink
Browse files

1.34: wait for orders mode

  • Loading branch information...
1 parent 81a8ca1 commit 3e446c710b1f5bb5cc8969f807098a0df6d44964 @kestasjk committed Jun 2, 2013
@@ -121,6 +121,11 @@ class adminActions extends adminActionsForms
'description' => 'Set a game process time to now, resulting in it being processed now',
'params' => array('gameID'=>'Game ID'),
),
+ 'toggleWaitForOrders' => array(
+ 'name' => 'Toggle Wait for orders mode',
+ 'description' => 'Will toggle this game between normal NMR rules and wait-for-orders mode',
+ 'params' => array('gameID'=>'Game ID'),
+ ),
'panic' => array(
'name' => 'Toggle panic button',
'description' => 'Toggle the panic button; turning it on prevents games from being processed, users joining games,
@@ -453,6 +458,28 @@ public function changePhaseLength(array $params)
return l_t('Process time changed from %s to %s. Next process time is %s.',
libTime::timeLengthText($oldPhaseMinutes*60),libTime::timeLengthText($Game->phaseMinutes*60),libTime::text($Game->processTime));
}
+ public function toggleWaitForOrders(array $params)
+ {
+ global $DB;
+
+ require_once(l_r('objects/game.php'));
+
+ $Variant=libVariant::loadFromGameID($params['gameID']);
+ $Game = $Variant->Game($params['gameID']);
+
+ if( $Game->missingPlayerPolicy == 'Wait' )
+ {
+ $msg = "Set game to normal mode.";
+ $setting = 'Normal';
+ }
+ else
+ {
+ $msg = "Set game to wait-for-orders mode.";
+ $setting = 'Wait';
+ }
+ $DB->sql_put("UPDATE wD_Games SET missingPlayerPolicy = '".$setting."' WHERE id = ".$Game->id);
+ return l_t($msg);
+ }
public function resetLastProcessTime(array $params)
{
View
@@ -266,7 +266,7 @@ public static function customFooter()
* The number of minutes that gamemaster.php will detect that it hasn't been run for before it will
* mark itself in downtime mode.
*/
- public static $downtimeTriggerMinutes=30;
+ public static $downtimeTriggerMinutes=12;
// ---
View
@@ -49,8 +49,11 @@
$form = $_REQUEST['newGame']; // This makes $form look harmless when it is unsanitized; the parameters must all be sanitized
$input = array();
- $required = array('variantID', 'name', 'password', 'passwordcheck', 'bet', 'potType', 'phaseMinutes', 'joinPeriod', 'anon', 'pressType');
+ $required = array('variantID', 'name', 'password', 'passwordcheck', 'bet', 'potType', 'phaseMinutes', 'joinPeriod', 'anon', 'pressType', 'missingPlayerPolicy');
+ if ( !isset($form['missingPlayerPolicy']) )
+ $form['missingPlayerPolicy'] = 'Normal';
+
foreach($required as $requiredName)
{
if ( isset($form[$requiredName]) )
@@ -114,11 +117,29 @@
case 'Regular': // Regular is the default
default:
$input['pressType'] = 'Regular';
+ }
+
+ switch($input['missingPlayerPolicy']) {
+ case 'Wait':
+ $input['missingPlayerPolicy'] = 'Wait';
+ break;
+ default:
+ $input['missingPlayerPolicy'] = 'Normal';
}
// Create Game record & object
require_once(l_r('gamemaster/game.php'));
- $Game = processGame::create($input['variantID'], $input['name'], $input['password'], $input['bet'], $input['potType'], $input['phaseMinutes'], $input['joinPeriod'], $input['anon'], $input['pressType']);
+ $Game = processGame::create(
+ $input['variantID'],
+ $input['name'],
+ $input['password'],
+ $input['bet'],
+ $input['potType'],
+ $input['phaseMinutes'],
+ $input['joinPeriod'],
+ $input['anon'],
+ $input['pressType'],
+ $input['missingPlayerPolicy']);
// Create first Member record & object
processMember::create($User->id, $input['bet']);
View
@@ -286,7 +286,7 @@ function loadMembers()
*
* @return Game The object corresponding to the new game
*/
- public static function create($variantID, $name, $password, $bet, $potType, $phaseMinutes, $joinPeriod, $anon, $press)
+ public static function create($variantID, $name, $password, $bet, $potType, $phaseMinutes, $joinPeriod, $anon, $press, $missingPlayerPolicy='Normal')
{
global $DB;
@@ -324,7 +324,8 @@ public static function create($variantID, $name, $password, $bet, $potType, $pha
pressType = '".$press."',
".( $password ? "password = UNHEX('".md5($password)."')," : "").
"processTime = ".$pTime.",
- phaseMinutes = ".$phaseMinutes);
+ phaseMinutes = ".$phaseMinutes.",
+ missingPlayerPolicy = '".$missingPlayerPolicy."'");
$gameID = $DB->last_inserted();
View
@@ -90,8 +90,8 @@ function gameNoticeBar()
else
return l_t('%s players joined; game will start on next process cycle', count($this->Variant->countries));
}
- elseif( $this->missingPlayerPolicy=='Strict'&&!$this->Members->isComplete() && time()>=$this->processTime )
- return l_t("One or more players need to complete their orders before this strict/tournament game can go on");
+ elseif( $this->missingPlayerPolicy=='Wait'&&!$this->Members->isCompleted() && time()>=$this->processTime )
+ return l_t("One or more players need to complete their orders before this wait-mode game can go on");
}
/*
@@ -262,6 +262,8 @@ function gameVariants() {
$alternatives[]=l_t('Anonymous players');
if( $this->potType=='Winner-takes-all' )
$alternatives[]=l_t($this->potType);
+ if( $this->missingPlayerPolicy=='Wait' )
+ $alternatives[]=l_t('Wait for orders');
if ( $alternatives )
return '<div class="titleBarLeftSide" style="float:left">
@@ -24,7 +24,7 @@
defined('IN_CODE') or die('This script can not be run by itself.');
-define("VERSION", 133);
+define("VERSION", 134) ;
// Some integer values which are named for clarity.
@@ -0,0 +1,16 @@
+Changelog
+---------
+- Changed the default time that the server will go without processing before stopping processing to 12 minutes. (2 attempts)
+- Added an option for NMR behavior, giving a setting that will make the game wait indefinitely for a missing player.
+- Added pagination to game chat archive screens
+- Fixed bug where users attempt to join a non-joinable game and get an incorrect error message
+
+Updating
+--------
+- Take a backup (database and files) <-- Important!
+- Set the server to maintenance mode (perhaps set an appropriate message warning users of the update in config.php first)
+- Wait a minute for all active processes to finish
+- Run update.sql
+- Copy the new code over the old code
+- View and test the updated site
+- Turn off maintenance mode
@@ -0,0 +1,2 @@
+ALTER TABLE `wD_Backup_Games` CHANGE `missingPlayerPolicy` `missingPlayerPolicy` ENUM( 'Normal', 'Strict', 'Wait' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'Normal';
+ALTER TABLE `wD_Games` CHANGE `missingPlayerPolicy` `missingPlayerPolicy` ENUM( 'Normal', 'Strict', 'Wait' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'Normal';
@@ -224,6 +224,27 @@
<strong>Default:</strong> No password set
</li>
+
+ <li class="formlisttitle">
+ No moves received options:
+ </li>
+ <li class="formlistfield">
+ <input type="radio" name="newGame[missingPlayerPolicy]" value="Normal" checked > Normal<br />
+ <input type="radio" name="newGame[missingPlayerPolicy]" value="Wait"> Wait for all players
+ </li>
+ <li class="formlistdesc">
+ What should happen if the end of the turn comes and a player has not submitted any orders?<br /><br />
+
+ If set to <strong>Normal</strong> the game will proceed, and after
+ a couple of turns they will go into civil disorder and their country can be taken over by another player.<br /><br />
+
+ If set to <strong>Wait for all players</strong> the game will not continue until all players have submitted their orders.<br />
+ This avoids any issues caused by
+ someone not submitting their orders on time, but it means that if someone becomes unavailable the game will not continue until they either
+ return, or a moderator manually sets them to civil disorder.<br /><br />
+
+ <strong>Default:</strong> Normal
+ </li>
</ul>
</div>
View
@@ -360,14 +360,14 @@ function isJoinable()
case 'Pre-game':
if(count($this->Members->ByID)==count($this->Variant->countries))
return false;
- elseif($User->points < $this->minimumBet )
+ elseif(is_null($this->minimumBet) || $User->points < $this->minimumBet )
return false;
else
return true;
default:
if(count($this->Members->ByStatus['Left'])==0)
return false;
- elseif($User->points < $this->minimumBet )
+ elseif(is_null($this->minimumBet) || $User->points < $this->minimumBet )
return false;
else
return true;
@@ -480,15 +480,15 @@ function needsProcess()
* - Games are processing as normal
* - The game isn't finished
* - The game isn't crashed or paused
- * - The game isn't in strict mode and missing a players completed moves
+ * - The game isn't in wait mode and missing a players completed moves
* - The game is either:
* - Out of time for the phase
* - Or either:
* - It's a normal order-related phase and everyone is ready to proceed
* - Or it's a pre-game phase and enough people have joined, and it's not a live game
*/
if( self::gamesCanProcess() && $this->phase!='Finished' && $this->processStatus=='Not-processing' &&
- !( $this->missingPlayerPolicy=='Strict'&&!$this->Members->isComplete() ) && (
+ ( $this->Members->isCompleted() || $this->missingPlayerPolicy!='Wait' ) && (
time() >= $this->processTime
|| ( ($this->phase!='Pre-game' && $this->Members->isReady() )
|| ($this->phase=='Pre-game' && count($this->Members->ByID)==count($this->Variant->countries) && !($this->isLiveGame()) ) )
View
@@ -0,0 +1,56 @@
+<?php
+/*
+ Copyright (C) 2004-2010 Kestas J. Kuliukas
+
+ This file is part of webDiplomacy.
+
+ webDiplomacy is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ webDiplomacy is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with webDiplomacy. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+defined('IN_CODE') or die('This script can not be run by itself.');
+
+/**
+ * @package Base
+ * @subpackage Pager
+ */
+
+require_once(l_r('pager/pagerthread.php'));
+class PagerForum extends Pager
+{
+ public static $defaultPostsPerPage=30;
+ public $type='forum';
+
+ function __construct($itemsTotal)
+ {
+ parent::__construct('forum.php',$itemsTotal,self::$defaultPostsPerPage);
+ }
+ function getCurrentPage($currentPage=1)
+ {
+ parent::getCurrentPage($this->pageCount);
+ if ( $this->currentPage>$this->pageCount )
+ $this->currentPage = $this->pageCount;
+ }
+ function currentPageNumber()
+ {
+ if( $this->currentPage != $this->pageCount )
+ return parent::currentPageNumber();
+ else
+ return '';
+ }
+
+ function SQLLimit()
+ {
+ return ' LIMIT '.($this->pageCount-$this->currentPage)*$this->itemsPerPage.', '.$this->itemsPerPage;
+ }
+}

3 comments on commit 3e446c7

@Sleepcap
Contributor

Hi kestas,
nice addition. We have something similar on vDip but made this a bit more complex for the following reason:

It's impossible for these games to continue without mod-support. Many experts like such a setting but also many players so not care and ruin the game for the better players. If a game gets paused by a missing player (usually a 1 SC player in a loosing position) for about 1-2 weeks usually all others loose interest.

In my solution you can set how many times the phase should be extended, and for how many turns this setting should be active. Usually the first 2 turns (with all phases included) is enough. Also it does not put the game on hostage if a 1 SC-power did not enter any orders.
Finally it puts the country in question in civil disorder. So a replacement can be found.

These is the setting from the gamecreate:

NMR-policy:
-Dropdown with 4 possible solutions:

  1. off / off
  2. 1 / 1 (Default - configurable in config.php)
  3. 5 / 2 (Commited)
  4. ∞ / ∞ (Serious)
  5. Custom (opens 2 input-boxes for custom numbers)

This rule will send a players into Civil Disorder (CD) if there are No Moves Received (NMR) from them.

Turns: How many turns this action will be in effect for. Be careful, a turn has up to three phases. Example: A two will send the country in CD for the diplomacy, retreat and build phase of the first 2 turns (usually Spring and Autumn).
Delay: How much time to advertise and find a replacement player (the current phase will be extended by the current phase length that many times). A zero will send the country in CD, but proceed with the turn as usual. Countries with 1 or less SCs will not hold back the game from processing.

Any value greater 90 will set the value to ∞, a value of 0 will set this to off.

This way the feature works quite well, but without I fear your admins need to CD quite a lot of countries on a regular basis.

@kestasjk
Owner
@Sleepcap
Contributor

Feel free to ask any questions.
Basically it works this way:
If a country does not submit any orders for the first X turns (this is configurable in the game-create and and we have a default setting of 1) and this country has more than 1 SC it set the Orderstatus for all other players from "Ready" to "Save", sets the process-time to now()+phase-length and CDs the countries with no moves. Now the other players can look for a replacement or just continoue without the player. It does this Y times (with a default of Y=1) till a replacement is found.

Please sign in to comment.