diff --git a/variants/RuleExtensions/classes/4_Transform/OrderArchiv.php b/variants/RuleExtensions/classes/4_Transform/OrderArchiv.php new file mode 100755 index 000000000..45f2c5e79 --- /dev/null +++ b/variants/RuleExtensions/classes/4_Transform/OrderArchiv.php @@ -0,0 +1,23 @@ +Variant->rules[RULE_TRANSFORM]){ + return parent::OutputOrder($order); + } + + if ($order['toTerrID'] > 1000) + { + $order['toTerrID'] = $order['toTerrID'] - 1000; + $order['type'] = 'transform'; + if ($order['toTerrID'] == $order['terrID']) + $order['toTerrID']=false; + } + return parent::OutputOrder($order); + } + +} \ No newline at end of file diff --git a/variants/RuleExtensions/classes/4_Transform/OrderInterface.php b/variants/RuleExtensions/classes/4_Transform/OrderInterface.php new file mode 100755 index 000000000..050831252 --- /dev/null +++ b/variants/RuleExtensions/classes/4_Transform/OrderInterface.php @@ -0,0 +1,24 @@ +Variant->rules[RULE_TRANSFORM]){ + return parent::jsLoadBoard(); + } + + parent::jsLoadBoard(); + + if( $this->phase=='Diplomacy' ) + { + // Expanding order controls with transform command + libHTML::$footerIncludes[] = l_jf('../variants/RuleExtensions/resources/4_Transform/transform.js'); + foreach(libHTML::$footerScript as $index=>$script) + libHTML::$footerScript[$index]=str_replace('loadOrdersPhase();','loadOrdersPhase();loadTransform();', $script); + } + } + +} \ No newline at end of file diff --git a/variants/RuleExtensions/classes/4_Transform/drawMap.php b/variants/RuleExtensions/classes/4_Transform/drawMap.php new file mode 100644 index 000000000..42da7293f --- /dev/null +++ b/variants/RuleExtensions/classes/4_Transform/drawMap.php @@ -0,0 +1,59 @@ +Variant->rules[RULE_TRANSFORM]){ + return parent::drawSupportHold($fromTerrID, $toTerrID, $success); + } + + if ($toTerrID < 1000) return parent::drawSupportHold($fromTerrID, $toTerrID, $success); + + $toTerrID = $toTerrID - 1000; + if ($success) + $this->trafo[$fromTerrID]=$toTerrID; + + $this->drawTransform($fromTerrID, $toTerrID, $success); + } + + // If a unit did a transform draw the new unit-type on the board instead of the old... + public function addUnit($terrID, $unitType) + { + if(!$this->Variant->rules[RULE_TRANSFORM]){ + return parent::addUnit($terrID, $unitType); + } + + if (array_key_exists($terrID,$this->trafo)) + return parent::addUnit($this->trafo[$terrID], ($unitType == 'Fleet' ? 'Army' : 'Fleet')); + parent::addUnit($terrID, $unitType); + } + + // Draw the transformation circle: + protected function drawTransform($fromTerrID, $toTerrID, $success) + { + + $terrID = ($success ? $toTerrID : $fromTerrID); + + if ( $fromTerrID != $toTerrID ) + $this->drawMove($fromTerrID,$toTerrID, $success); + + $darkblue = $this->color(array(40, 80,130)); + $lightblue = $this->color(array(70,150,230)); + + list($x, $y) = $this->territoryPositions[$terrID]; + + $width=($this->fleet['width'])+($this->fleet['width'])/2; + + imagefilledellipse ( $this->map['image'], $x, $y, $width, $width, $darkblue); + imagefilledellipse ( $this->map['image'], $x, $y, $width-2, $width-2, $lightblue); + + if ( !$success ) $this->drawFailure(array($x-1, $y),array($x+2, $y)); + } +} + +?> \ No newline at end of file diff --git a/variants/RuleExtensions/classes/4_Transform/processOrderDiplomacy.php b/variants/RuleExtensions/classes/4_Transform/processOrderDiplomacy.php new file mode 100644 index 000000000..7bcb7df51 --- /dev/null +++ b/variants/RuleExtensions/classes/4_Transform/processOrderDiplomacy.php @@ -0,0 +1,27 @@ +Variant->rules[RULE_TRANSFORM]){ + return parent::apply($standoffTerrs); + } + + // Transform all sucessfull "Transformations": + $DB->sql_put("UPDATE wD_Units u + INNER JOIN wD_Orders o ON (o.unitID = u.id) + INNER JOIN wD_Moves m ON (m.gameID=o.gameID AND m.orderID = o.id) + SET u.type = IF(u.type='Fleet','Army','Fleet'), u.terrID = (o.toTerrID - 1000) + WHERE o.type='Support hold' AND m.success='Yes' AND o.toTerrID>1000 + AND u.id = o.unitID AND o.gameID = ".$Game->id); + parent::apply($standoffTerrs); + } + +} + +?> \ No newline at end of file diff --git a/variants/RuleExtensions/classes/4_Transform/userOrderDiplomacy.php b/variants/RuleExtensions/classes/4_Transform/userOrderDiplomacy.php new file mode 100755 index 000000000..ed4ea684a --- /dev/null +++ b/variants/RuleExtensions/classes/4_Transform/userOrderDiplomacy.php @@ -0,0 +1,66 @@ +Variant->rules[RULE_TRANSFORM]){ + return parent::typeCheck(); + } + + if (strrpos($this->type,'Transform_1') !== false) return true; + return parent::typeCheck(); + } + + // Save the transform command as a Support-hold + public function commit() + { + if(!$this->Variant->rules[RULE_TRANSFORM]){ + return parent::commit(); + } + + // Clear the toTerrID (if there is any) from the transform command + if ($this->type=='Hold') + $this->paramWipe('toTerrID'); + + if (strrpos($this->type,'Transform_1') !== false) + { + $this->toTerrID = substr($this->type, -4); + $this->wiped = array('fromTerrID','viaConvoy'); + $this->changed = array('type','toTerrID'); + $this->type='Support hold'; + } + return parent::commit(); + } + + public function loadFromDB(array $inputs) + { + if(!$this->Variant->rules[RULE_TRANSFORM]){ + parent::loadFromDB($inputs); + } + + if( isset($inputs['toTerrID']) && $inputs['toTerrID'] > 1000 ) + { + $inputs['type'] = 'Transform_' . $inputs['toTerrID']; + unset($inputs['toTerrID']); + } + parent::loadFromDB($inputs); + } + + public function loadFromInput(array $inputs) + { + if(!$this->Variant->rules[RULE_TRANSFORM]){ + parent::loadFromInput($inputs); + } + + if( isset($inputs['toTerrID']) && $inputs['toTerrID'] > 1000) + { + $inputs['type'] = 'Transform_' . $inputs['toTerrID']; + unset($inputs['toTerrID']); + } + parent::loadFromInput($inputs); + } +} \ No newline at end of file diff --git a/variants/RuleExtensions/classes/OrderArchiv.php b/variants/RuleExtensions/classes/OrderArchiv.php new file mode 100644 index 000000000..f41b81bf8 --- /dev/null +++ b/variants/RuleExtensions/classes/OrderArchiv.php @@ -0,0 +1,21 @@ +Variant = $Variant; + + parent::__construct($smallmap); + } +} + +require_once('4_Transform/OrderArchiv.php'); + +class RuleExtensionsVariant_OrderArchiv extends Transform_OrderArchiv {} + +?> \ No newline at end of file diff --git a/variants/RuleExtensions/classes/OrderInterface.php b/variants/RuleExtensions/classes/OrderInterface.php index f002a3900..3e256de1d 100755 --- a/variants/RuleExtensions/classes/OrderInterface.php +++ b/variants/RuleExtensions/classes/OrderInterface.php @@ -18,5 +18,6 @@ public function __construct($Variant, $gameID, $variantID, $userID, $memberID, $ require_once('1_CustomIcons/OrderInterface.php'); require_once('2_CustomIconsPerCountry/OrderInterface.php'); require_once('3_BuildAnywhere/OrderInterface.php'); +require_once('4_Transform/OrderInterface.php'); -class RuleExtensionsVariant_OrderInterface extends BuildAnywhere_OrderInterface {} \ No newline at end of file +class RuleExtensionsVariant_OrderInterface extends Transform_OrderInterface {} \ No newline at end of file diff --git a/variants/RuleExtensions/classes/drawMap.php b/variants/RuleExtensions/classes/drawMap.php index 9bf7cde45..245a9eaf1 100644 --- a/variants/RuleExtensions/classes/drawMap.php +++ b/variants/RuleExtensions/classes/drawMap.php @@ -18,7 +18,8 @@ public function __construct($Variant, $smallmap) require_once('0_CustomMap/drawMap.php'); require_once('1_CustomIcons/drawMap.php'); require_once('2_CustomIconsPerCountry/drawMap.php'); +require_once('4_Transform/drawMap.php'); -class RuleExtensionsVariant_drawMap extends CustomIconsPerCountry_drawMap {} +class RuleExtensionsVariant_drawMap extends Transform_drawMap {} ?> \ No newline at end of file diff --git a/variants/RuleExtensions/classes/processOrderDiplomacy.php b/variants/RuleExtensions/classes/processOrderDiplomacy.php new file mode 100644 index 000000000..7659307a7 --- /dev/null +++ b/variants/RuleExtensions/classes/processOrderDiplomacy.php @@ -0,0 +1,19 @@ +Variant = $Variant; + } +} + +require_once('4_Transform/processOrderDiplomacy.php'); + +class RuleExtensionsVariant_processOrderDiplomacy extends Transform_processOrderDiplomacy {} + +?> \ No newline at end of file diff --git a/variants/RuleExtensions/classes/userOrderDiplomacy.php b/variants/RuleExtensions/classes/userOrderDiplomacy.php new file mode 100755 index 000000000..3244265f3 --- /dev/null +++ b/variants/RuleExtensions/classes/userOrderDiplomacy.php @@ -0,0 +1,19 @@ +Variant = $Variant; + + parent::__construct($orderID, $gameID, $countryID); + } +} + +require_once('4_Transform/userOrderDiplomacy.php'); + +class RuleExtensionsVariant_userOrderDiplomacy extends Transform_userOrderDiplomacy {} \ No newline at end of file diff --git a/variants/RuleExtensions/interactiveMap/4_Transform/IA_transform.js b/variants/RuleExtensions/interactiveMap/4_Transform/IA_transform.js new file mode 100644 index 000000000..396457f18 --- /dev/null +++ b/variants/RuleExtensions/interactiveMap/4_Transform/IA_transform.js @@ -0,0 +1,272 @@ +/* + * What have to be changed: + * + * - add 'transform' button in interface + * - add 'transform' button in order-menu on map + * - add image for 'transform' button on map + * - add function to set 'transform' order + * - add function to draw 'transform' order + * + */ + +function setTransparent(ctx){ + var imgData = ctx.getImageData(0,0,ctx.canvas.width,ctx.canvas.height); + for(var i=0; i the correct coast has to be selected by the coordinates the user clicked on + var coastID = this.getCoastByCoords(Territories.select(function(t) { + return (t[1].coastParentID == interactiveMap.selectedTerritoryID) && (t[1].id != t[1].coastParentID) + }).pluck("1"), this.coordinates).id; + + value = "Transform_"+(parseInt(coastID) + 1000); + } + } + + value = (value == "Convoy") ? "Move" : value; + + this.enterOrder('type', value); + + if(!this.Order.isComplete) + // display reset button if order is not completed + interactiveMap.interface.orderMenu.show(undefined, true); + }; + + IA.printType = function() { + switch (this.orderType) { + case "Hold": + interactiveMap.insertMessage(" holds", true); + break; + case "Move": + interactiveMap.insertMessage(" moves to "); + break; + case "Support hold": + interactiveMap.insertMessage(" supports the holding unit in "); + break; + case "Support move": + interactiveMap.insertMessage(" supports the moving unit to "); + break; + case "Convoy": + interactiveMap.insertMessage(" moves via "); + break; + + case "Transform": + interactiveMap.insertMessage(" transforms to " + ((this.Order.Unit.type === 'Army') ? interactiveMap.parameters.fleetName : interactiveMap.parameters.armyName)); + + if ( this.Order.Unit.type === 'Army' && this.Order.Unit.Territory.coast === "Parent" ){ + // print extra info if a coast was choosen + var coastID = this.getCoastByCoords(Territories.select(function(t) { + return (t[1].coastParentID == interactiveMap.selectedTerritoryID) && (t[1].id != t[1].coastParentID) + }).pluck("1"), this.coordinates).id; + + interactiveMap.insertMessage(" on "+Territories.get(coastID).name.match(/\((.*)\)/)[1]); + } + + interactiveMap.insertMessage(" ",true); + + break; + } + }; + }); + } + + function addDrawTransform() { + function drawArmy(terrID){ + interactiveMap.visibleMap.mainLayer.context.drawImage(imgArmy,Territories.get(terrID).smallMapX-(imgArmy.width/2), Territories.get(terrID).smallMapY-(imgArmy.height/2)); + } + + function drawFleet(terrID){ + interactiveMap.visibleMap.mainLayer.context.drawImage(imgFleet,Territories.get(terrID).smallMapX-(imgFleet.width/2), Territories.get(terrID).smallMapY-(imgFleet.height/2)); + } + + function drawTransform(terrID) + { + var darkblue = [40, 80,130]; + var lightblue = [70,150,230]; + + var x = Territories.get(terrID).smallMapX; + var y = Territories.get(terrID).smallMapY; + + var width=imgFleet.width+imgFleet.width/2; + + filledcircle(x,y,width,darkblue); + filledcircle(x,y,width-2,lightblue); + + if(Territories.get(terrID).coastParent.Unit.type === 'Army') + drawFleet(terrID); + else + drawArmy(terrID); + } + + function filledcircle(x,y,width,color) + { + interactiveMap.visibleMap.mainLayer.context.beginPath(); + interactiveMap.visibleMap.mainLayer.context.arc(x,y,width/2,0,2*Math.PI); + interactiveMap.visibleMap.mainLayer.context.closePath(); + interactiveMap.visibleMap.mainLayer.context.fillStyle = "rgb(" + color[0] + "," + color[1] + "," + color[2] + ")"; + interactiveMap.visibleMap.mainLayer.context.fill(); + } + + var draw2 = interactiveMap.draw; + + interactiveMap.draw = function() { + draw2(); + + + for (var i = 0; i < MyOrders.length; i++) { + if (MyOrders[i].isComplete && MyOrders[i].type.include('Transform')) { + drawTransform(parseInt(MyOrders[i].type.sub('Transform_',''))-1000); + } + } + } + } + + addTransformButton(); + addOrderMenuTransformButton(); + addSetTransform(); + addDrawTransform(); +} + + diff --git a/variants/RuleExtensions/interactiveMap/4_Transform/IA_transform.png b/variants/RuleExtensions/interactiveMap/4_Transform/IA_transform.png new file mode 100644 index 000000000..63e1635af Binary files /dev/null and b/variants/RuleExtensions/interactiveMap/4_Transform/IA_transform.png differ diff --git a/variants/RuleExtensions/interactiveMap/4_Transform/interactiveMap.php b/variants/RuleExtensions/interactiveMap/4_Transform/interactiveMap.php new file mode 100644 index 000000000..9e60a713d --- /dev/null +++ b/variants/RuleExtensions/interactiveMap/4_Transform/interactiveMap.php @@ -0,0 +1,23 @@ +Variant->rules[RULE_TRANSFORM]){ + return parent::jsFooterScript(); + } + + parent::jsFooterScript(); + + if($Game->phase == "Diplomacy") { + libHTML::$footerIncludes[] = '../variants/RuleExtensions/interactiveMap/4_Transform/IA_transform.js'; + + $resources = $this->resources(); + libHTML::$footerScript[] = 'loadIAtransform(\''.$resources['army'].'\',\''.$resources['fleet'].'\');'; + } + } +} \ No newline at end of file diff --git a/variants/RuleExtensions/interactiveMap/interactiveMap.php b/variants/RuleExtensions/interactiveMap/interactiveMap.php index aecc76239..c56cc959a 100644 --- a/variants/RuleExtensions/interactiveMap/interactiveMap.php +++ b/variants/RuleExtensions/interactiveMap/interactiveMap.php @@ -22,5 +22,6 @@ public function __construct($Variant, $mapName = 'IA_smallmap.png') require_once('1_CustomIcons/interactiveMap.php'); // todo: implement custom build icons per country +require_once('4_Transform/interactiveMap.php'); -class RuleExtensionsVariant_IAmap extends CustomIcons_IAmap {} \ No newline at end of file +class RuleExtensionsVariant_IAmap extends Transform_IAmap {} \ No newline at end of file diff --git a/variants/RuleExtensions/resources/4_Transform/transform.js b/variants/RuleExtensions/resources/4_Transform/transform.js new file mode 100644 index 000000000..acc8938a7 --- /dev/null +++ b/variants/RuleExtensions/resources/4_Transform/transform.js @@ -0,0 +1,43 @@ +function loadTransform() { + + MyOrders.map(function(OrderObj) { + OrderObj.updateTypeChoices = function () { + this.typeChoices = { + 'Hold': 'hold', 'Move': 'move', 'Support hold': 'support hold', 'Support move': 'support move' + }; + + if( this.Unit.type == 'Fleet' && this.Unit.Territory.type == 'Sea' ) + this.typeChoices['Convoy']='convoy'; + + if( this.Unit.Territory.coastParent.supply == true && this.Unit.Territory.coastParent.type == 'Coast' ) + { + found=false; + if (this.Unit.type == 'Army') + { + Territories.each(function(p) + { + var t=p[1]; + if(t.coastParent.id == this.Unit.Territory.id && t.coastParent.id != t.id) + { + found=true; + name=t.name.substring(t.name.indexOf("(") + 1, t.name.indexOf(")")) + this.typeChoices['Transform_' + (1000 + parseInt(t.id)) ] = 'transform to fleet -> ' + name; + } + },this); + } + if (found == false) + { + target = (this.Unit.type == 'Fleet') ? 'army' : 'fleet'; + this.typeChoices['Transform_' + (1000 + parseInt(this.Unit.Territory.coastParent.id))]='transform to ' + target; + } + } + return this.typeChoices; + }; + + OrderObj.updateTypeChoices(OrderObj.requirements); + OrderObj.requirements.map(function(n){ OrderObj.reHTML(n); },OrderObj); + OrderObj.setSelectsGreen(); + + }, this); + +} \ No newline at end of file diff --git a/variants/RuleExtensions/variant.php b/variants/RuleExtensions/variant.php index 14715a9e6..6aafc4828 100755 --- a/variants/RuleExtensions/variant.php +++ b/variants/RuleExtensions/variant.php @@ -61,7 +61,13 @@ /** * BuildAnywhere lets players build on every open SC they own. */ -const RULE_BUILD_ANYHWERE = 'BuildAnywhere'; +const RULE_BUILD_ANYHWERE = 'BuildAnywhere'; // legacy typo kept for compatibility +const RULE_BUILD_ANYWHERE = 'BuildAnywhere'; +/** + * Tranform lets players transform armies to fleets and vice versa as additional order + * on empty supply centers. Transformation succeeds when units are not attacked. + */ +const RULE_TRANSFORM = 'Transform'; // by default we extend the classic variant for loading resources and map and turn numbers abstract class RuleExtensionsVariant extends ClassicVariant { @@ -76,6 +82,7 @@ abstract class RuleExtensionsVariant extends ClassicVariant { RULE_CUSTOM_ICONS => false, RULE_CUSTOM_ICONS_PER_COUNTRY => false, RULE_BUILD_ANYHWERE => false, + RULE_TRANSFORM => false ); /** @@ -122,7 +129,19 @@ public function __construct() { $this->variantClasses['processOrderBuilds'] = self::$ruleExtensionVariantName; // Order interface/generation code, changed to add javascript in resources which makes non-home SCs an option $this->variantClasses['OrderInterface'] = self::$ruleExtensionVariantName; + } + if($this->rules[RULE_TRANSFORM]) { + // Add code for drawing the transform command + $this->variantClasses['drawMap'] = self::$ruleExtensionVariantName; + // Add code for displaying the transform command in the order archive + $this->variantClasses['OrderArchiv'] = self::$ruleExtensionVariantName; + // Order interface/generation code, changed to add javascript in resources to support transform command in front-end controls + $this->variantClasses['OrderInterface'] = self::$ruleExtensionVariantName; + // Add code for correctly transforming units on successfull transform commands + $this->variantClasses['processOrderDiplomacy'] = self::$ruleExtensionVariantName; + // Order validation code, changed to correctly handle encoded transform commands + $this->variantClasses['userOrderDiplomacy'] = self::$ruleExtensionVariantName; } // Store all the classes pointing to ruleExtensions to inject $Variant arg needed in those extensions.