[plm] 05/13: refresh patches

Martin Quinson mquinson at moszumanska.debian.org
Sat Nov 1 07:28:06 UTC 2014


This is an automated email from the git hooks/post-receive script.

mquinson pushed a commit to branch debian
in repository plm.

commit 10ac7bd48ab19e099fbc457020fc971d7203047d
Author: Martin Quinson <martin.quinson at loria.fr>
Date:   Fri Oct 24 20:33:48 2014 +0200

    refresh patches
---
 debian/patches/no-scala         | 2171 ++++++++++++++++++++++++++++++++++-----
 debian/patches/system-ant-tasks |    4 +-
 2 files changed, 1939 insertions(+), 236 deletions(-)

diff --git a/debian/patches/no-scala b/debian/patches/no-scala
index 637c49b..d553738 100644
--- a/debian/patches/no-scala
+++ b/debian/patches/no-scala
@@ -1,246 +1,1951 @@
 ---
- src/plm/core/CompilerScala.java       |  143 ----------------------------------
- src/plm/core/model/Game.java          |    2 
- src/plm/core/ui/PlmHtmlEditorKit.java |   16 ++-
- 3 files changed, 13 insertions(+), 148 deletions(-)
+ src/lessons/lander/Main.fr.html                                                |   23 -
+ src/lessons/lander/Main.html                                                   |   21 -
+ src/lessons/lander/Main.scala                                                  |   14 
+ src/lessons/lander/icon.svg                                                    |  104 -----
+ src/lessons/lander/lvl1_lander_101/Lander101.fr.html                           |   49 --
+ src/lessons/lander/lvl1_lander_101/Lander101.html                              |   41 -
+ src/lessons/lander/lvl1_lander_101/Lander101.it.html                           |   45 --
+ src/lessons/lander/lvl1_lander_101/Lander101.pt_BR.html                        |   45 --
+ src/lessons/lander/lvl1_lander_101/Lander101.scala                             |   17 
+ src/lessons/lander/lvl1_lander_101/Lander101Entity.java                        |   14 
+ src/lessons/lander/lvl1_lander_101/Lander101Entity.py                          |   13 
+ src/lessons/lander/lvl1_lander_101/ScalaLander101Entity.scala                  |   17 
+ src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.fr.html          |   39 -
+ src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.html             |   34 -
+ src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.scala            |   19 
+ src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZoneEntity.java       |   57 --
+ src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZoneEntity.py         |   43 --
+ src/lessons/lander/lvl2_locate_landing_zone/ScalaLocateLandingZoneEntity.scala |   54 --
+ src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.fr.html                    |   41 -
+ src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.html                       |   33 -
+ src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.pt_BR.html                 |   37 -
+ src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.scala                      |   20 
+ src/lessons/lander/lvl3_fly_the_lander/FlyTheLanderEntity.java                 |   48 --
+ src/lessons/lander/lvl3_fly_the_lander/FlyTheLanderEntity.py                   |   45 --
+ src/lessons/lander/lvl3_fly_the_lander/ScalaFlyTheLanderEntity.scala           |   53 --
+ src/lessons/lander/short_desc.fr.html                                          |    9 
+ src/lessons/lander/short_desc.html                                             |    7 
+ src/lessons/lander/universe/Configurations.scala                               |   77 ---
+ src/lessons/lander/universe/DelegatingLanderWorld.fr.html                      |   48 --
+ src/lessons/lander/universe/DelegatingLanderWorld.html                         |   44 --
+ src/lessons/lander/universe/DelegatingLanderWorld.java                         |   71 ---
+ src/lessons/lander/universe/DelegatingLanderWorld.pt_BR.html                   |   43 --
+ src/lessons/lander/universe/Geometry.scala                                     |   47 --
+ src/lessons/lander/universe/LanderEntity.scala                                 |   59 --
+ src/lessons/lander/universe/LanderWorld.scala                                  |  148 -------
+ src/lessons/lander/universe/LanderWorldView.scala                              |  207 ----------
+ src/plm/core/ui/ChooseLessonDialog.java                                        |    2 
+ src/plm/test/ExoTest.java                                                      |    2 
+ src/plm/test/LessonTest.java                                                   |    2 
+ 39 files changed, 3 insertions(+), 1689 deletions(-)
 
-Index: b/src/plm/core/CompilerScala.java
+Index: b/src/lessons/lander/universe/Configurations.scala
 ===================================================================
---- a/src/plm/core/CompilerScala.java
-+++ b/src/plm/core/CompilerScala.java
-@@ -9,18 +9,6 @@
- import java.util.Vector;
- 
- import plm.core.model.Game;
--import scala.Option;
--import scala.collection.JavaConverters;
--import scala.reflect.internal.util.BatchSourceFile;
--import scala.reflect.internal.util.Position;
--import scala.reflect.internal.util.SourceFile;
--import scala.reflect.io.VirtualDirectory;
--import scala.reflect.io.VirtualFile;
--import scala.tools.nsc.Global;
--import scala.tools.nsc.Global.Run;
--import scala.tools.nsc.Settings;
--import scala.tools.nsc.interpreter.AbstractFileClassLoader;
--import scala.tools.nsc.reporters.AbstractReporter;
- 
- public class CompilerScala {
- 	
-@@ -31,143 +19,16 @@
- 		return instance;
- 	}
- 	
--	private PLMReporter reporter;
--	private Settings settings;
--	private Map<String, Class<?>> cache = new HashMap<String, Class<?>>();
--	private Global global;
--	private VirtualDirectory target;
--	private ClassLoader classLoader = new AbstractFileClassLoader(target, this.getClass().getClassLoader());
--	
- 	private CompilerScala() {
--		super();
--		settings = new Settings();
--		settings.nowarnings().tryToSetFromPropertyValue("true"); // warnings seem to be exceptions, and we don't want them to mess with us
--
--		Option<VirtualDirectory> noAncestor = scala.Option$.MODULE$.apply(null);
--		target = new VirtualDirectory("(memory)", noAncestor);
--		settings.outputDirs().setSingleOutput(target);
--		
--		settings.usejavacp().tryToSetFromPropertyValue("true");
--		//settings.usemanifestcp().tryToSetFromPropertyValue("true");
--		reporter = new PLMReporter(settings);
--		global = new Global(settings,reporter);
-+	   /* Scala is too ancient in Debian (need 2.10), so kill that all */
- 	}
- 
- 	public void reset() {
--		reporter.reset();
--		reporter.setOffset(0);
--		target.clear();
--		cache = new HashMap<String, Class<?>>();
--		classLoader = new AbstractFileClassLoader(target, this.getClass().getClassLoader());
- 	}
- 
- 	public void compile(String name,String content,int offset) throws PLMCompilerException {
--		
--		Run compiler = global.new Run();
--		List<SourceFile> sources = new LinkedList<SourceFile>();
--		
--		sources.add(new BatchSourceFile(new VirtualFile(name) , content.toCharArray()));
--		reporter.setOffset(offset);
--		
--		compiler.compileSources(JavaConverters.asScalaBufferConverter(sources).asScala().toList());
--		
--		if (Game.getInstance().isDebugEnabled() && reporter.hasErrors())
--			System.out.println("Here is the scala source code of "+name+" (offset:"+offset+"): "+content);
--		reporter.throwExceptionOnNeed();
- 	}
- 	public Class<?> findClass(String className) {
--		synchronized (this) {
--			if (!cache.containsKey(className)) {
--				Class<?> res;
--				try {
--					res = classLoader.loadClass(className);
--				} catch (ClassNotFoundException e) {
--					res = null;
--				}
--				cache.put(className, res);
--			}
+--- a/src/lessons/lander/universe/Configurations.scala
++++ /dev/null
+@@ -1,77 +0,0 @@
+-package lessons.lander.universe
+-
+-import plm.universe.World
+-
+-object Configurations {
+-  import NumUtil._
+-
+-  // helper creation functions
+-
+-  private case class Terrain(width: Int, height: Int, ground: List[Point])
+-
+-  private def makeWorld(name: String, terrain: Terrain, position: Point, speed: Point,
+-      angle: Double, thrust: Int, fuel: Int) =
+-    new DelegatingLanderWorld(name, terrain.width, terrain.height, terrain.ground, position, speed,
+-        angle, thrust, fuel)
+-
+-  // helper geometric functions
+-
+-  private def angleToSpeed(angle: Double, speed: Double) =
+-    radianToVector(gameAngleToRadian(angle)) * speed
+-
+-  // terrains
+-
+-  private val SIMPLE_TERRAIN = Terrain(
+-      width = 2000,
+-      height = 1000,
+-      ground = List(Point(0, 100), Point(125, 414), Point(205, 271),
+-          Point(348, 597), Point(460, 257), Point(534, 438), Point(637, 160),
+-          Point(760, 371), Point(854, 200), Point(1468, 200), Point(1585, 440),
+-          Point(1682, 280), Point(1845, 668), Point(2000, 294)))
+-
+-  private val CHALLENGING_TERRAIN = Terrain(
+-      width = 2000,
+-      height = 1000,
+-      ground =  List(Point(0,260), Point(37,160), Point(160,371), Point(254,200),
+-          Point(430,200), Point(535,394), Point(639,300), Point(780,300), Point(890,440),
+-          Point(1082,280), Point(1245,668), Point(1400,294), Point(1580, 410), Point(1730, 360),
+-          Point(1870, 560), Point(2000, 400)))
+-
+-  // worlds
+-
+-  val SIMPLE_TERRAIN_TRIVIAL_CONFIG = makeWorld(
+-      name = "Simple Terrain, Simple Configuration",
+-      terrain = SIMPLE_TERRAIN,
+-      position = Point(1200, 700),
+-      speed = Point(0, 0),
+-      angle = 0.0,
+-      thrust = 0,
+-      fuel = 3000)
+-
+-  val CHALLENGING_TERRAIN_SIMPLE_CONFIG = makeWorld(
+-      name = "Challenging Terrain, Simple Configuration",
+-      terrain = CHALLENGING_TERRAIN,
+-      position = Point(530, 600),
+-      speed = Point(0, 10),
+-      angle = 0,
+-      thrust = 4,
+-      fuel = 3000)
+-
+-  val SIMPLE_TERRAIN_CHALLENGING_CONFIG = makeWorld(
+-      name = "Simple Terrain, Challenging Configuration",
+-      terrain = SIMPLE_TERRAIN,
+-      position = Point(500, 500),
+-      speed = angleToSpeed(-20, 20),
+-      angle = -20,
+-      thrust = 3,
+-      fuel = 3000)
+-
+-  val SIMPLE_TERRAIN_HARD_CONFIG = makeWorld(
+-      name = "Simple Terrain, Hard Configuration",
+-      terrain = SIMPLE_TERRAIN,
+-      position = Point(1900, 900),
+-      speed = angleToSpeed(90, 80),
+-      angle = 90,
+-      thrust = 4,
+-      fuel = 3000)
+-}
+\ No newline at end of file
+Index: b/src/lessons/lander/universe/Geometry.scala
+===================================================================
+--- a/src/lessons/lander/universe/Geometry.scala
++++ /dev/null
+@@ -1,47 +0,0 @@
+-package lessons.lander.universe
+-
+-import Math.PI
+-import Math.cos
+-import Math.sin
+-
+-object NumUtil {
+-  def clamp(min: Double, max: Double, value: Double): Double = {
+-    if (value < min) min else if (value > max) max else value
+-  }
+-  def clamp(min: Int, max: Int, value: Int): Int = {
+-    if (value < min) min else if (value > max) max else value
+-  }
+-
+-  def radianToVector(angle: Double) = Point(cos(angle), sin(angle))
+-  
+-  def gameAngleToRadian(angle: Double) = (angle + 90) * PI / 180
+-}
+-
+-case class Point(x: Double, y: Double) {
+-  def +(p: Point): Point = new Point(x + p.x, y + p.y)
+-  def -(p: Point): Point = new Point(x - p.x, y - p.y)
+-  def *(l: Double): Point = new Point(x * l, y * l)
+-  def /(l: Double): Point = new Point(x / l, y / l)
+-  def unary_- = this * -1
+-
+-  def length: Double = Math.sqrt(x * x + y * y)
+-  def normed = this / length
+-  def dot(p: Point) = x * p.x + y * p.y
+-  def cross(p: Point) = x * p.y - y * p.x
+-}
+-
+-case class Segment(start: Point, end: Point)
+-
+-case class Ray(origin: Point, direction: Point) {
+-  def intersects(s: Segment): Boolean = {
+-    val v = s.end - s.start
+-    val cross = direction.cross(v);
+-    if (cross == 0) {
+-      false
+-    } else {
+-      val f1 = (s.start - origin).cross(v) / cross
+-      val f2 = (s.start - origin).cross(direction) / cross
+-      f1 >= 0 && f2 >= 0 && f2 <= 1
+-    }
+-  }
+-}
+Index: b/src/lessons/lander/universe/LanderEntity.scala
+===================================================================
+--- a/src/lessons/lander/universe/LanderEntity.scala
++++ /dev/null
+@@ -1,59 +0,0 @@
+-package lessons.lander.universe
+-
+-import plm.universe.Entity
+-import scala.collection.JavaConversions._
+-
+-class LanderEntity extends Entity {
+-
+-  private def landerWorld = getWorld().asInstanceOf[DelegatingLanderWorld].realWorld
+-
+-  override def command(command: String, out: java.io.BufferedWriter){
+-    
+-  }
+-  
+-  override def run() = {
+-    initialize()
+-    while (isFlying()) {
+-      step()
+-      simulateStep()
+-    }
+-  }
+-
+-  // methods to be overridden by the player
+-  def initialize(): Unit = ()
+-  def step(): Unit = ()
+-
+-  // query terrain2
+-  def getGround(): java.util.List[Point] = landerWorld.ground
+-
+-  // query lander state
+-  def getX(): Double = landerWorld.position.x
+-  def getY(): Double = landerWorld.position.y
+-  def getSpeedX(): Double = landerWorld.speed.x
+-  def getSpeedY(): Double = landerWorld.speed.y
+-  def getAngle(): Double = landerWorld.angle
+-  def getThrust(): Int = landerWorld.thrust
+-  def getFuel(): Int = landerWorld.fuel
+-
+-  def setDesiredAngle(desiredAngle: Double) {
+-    landerWorld.desiredAngle = desiredAngle
+-  }
+-  def setDesiredThrust(desiredThrust: Int) {
+-    landerWorld.desiredThrust = desiredThrust
+-  }
+-  
+-  /* Internal commands used by the python entities to simulate the above run method */
+-  def isFlying(): Boolean = (landerWorld.state == LanderWorld.State.FLYING)
+-  def simulateStep() = {
+-    landerWorld.simulate(0.1)
+-    stepUI()
+-  }
+-  
+-  /* BINDINGS TRANSLATION: French */
+-  def getSol() = getGround()
+-  def getVitesseX(): Double = getSpeedX()
+-  def getVitesseY(): Double = getSpeedY()
+-  def getPoussee(): Int = getThrust()
+-  def setAngleDesire(desiredAngle: Double) = setDesiredAngle(desiredAngle) 
+-  def setPousseeDesiree(desiredThrust: Int) = setDesiredThrust(desiredThrust)
+-}
+Index: b/src/lessons/lander/universe/LanderWorld.scala
+===================================================================
+--- a/src/lessons/lander/universe/LanderWorld.scala
++++ /dev/null
+@@ -1,148 +0,0 @@
+-package lessons.lander.universe
+-
+-import Math.PI
+-
+-import javax.script.ScriptEngine
+-import javax.swing.ImageIcon
+-import plm.core.lang.ProgrammingLanguage
+-import plm.core.model.Game
+-import plm.core.lang.ProgrammingLanguage
+-import plm.core.ui.ResourcesCache
+-import plm.universe.World
+-
+-object LanderWorld {
+-  object State extends Enumeration {
+-    val FLYING, LANDED, CRASHED, OUT = Value
+-  }
+-
+-  private val GRAVITY = Point(0, -1) * 3.711;
+-}
+-
+-class LanderWorld(val parent: DelegatingLanderWorld) {
+-
+-  import LanderWorld.State._
+-  import NumUtil._
+-
+-  var width: Int = 0
+-  var height: Int = 0
+-  var ground: List[Point] = null
+-  var position: Point = null
+-  var speed: Point = null
+-  /** Angle in degrees, 0 points north, 90 points west. */
+-  var angle: Double = 0
+-  var thrust: Int = 0
+-  var fuel: Int = 0
+-  var state = FLYING
+-
+-  var desiredAngle: Double = 0
+-  var desiredThrust: Int = 0
+-
+-  parent.setDelay(10)
+-  parent.addEntity(new LanderEntity())
+-
+-  // "inherited" methods
+-
+-  def getIcon = ResourcesCache.getIcon("img/world_lander.png");
+-
+-  def setupBindings(lang: ProgrammingLanguage, engine: ScriptEngine) {
+-  		if (lang.equals(Game.PYTHON)) {
+-  			engine.put("Segment", Segment.getClass())
+-			engine.eval(
+-			    "def isFlying():\n"+
+-			    "  return entity.isFlying()\n"+
+-			    "def simulateStep():\n"+
+-			    "  entity.simulateStep()\n"+
+-			    "def getGround():\n"+
+-			    "  return [ (elm.x(), elm.y()) for elm in entity.getGround() ]\n"+
+-			    "def getX():\n"+
+-			    "  return entity.getX()\n"+
+-			    "def getY():\n"+
+-			    "  return entity.getY()\n"+
+-			    "def getSpeedX():\n"+
+-			    "  return entity.getSpeedX()\n"+
+-			    "def getSpeedY():\n"+
+-			    "  return entity.getSpeedY()\n"+
+-			    "def getAngle():\n"+
+-			    "  return entity.getAngle()\n"+
+-			    "def setDesiredAngle(a):\n"+
+-			    "  entity.setDesiredAngle(a)\n"+
+-			    "def getThrust():\n"+
+-			    "  return entity.getThrust()\n"+
+-			    "def setDesiredThrust(t):\n"+
+-			    "  entity.setDesiredThrust(t)\n"+
+-			    "def getFuel():\n"+
+-			    "  return entity.getFuel()\n"+
+-			    "")
+-  		} else {
+-  			throw new RuntimeException("No binding of LanderWorld for "+lang)
+-  		}
+-  }
+-
+-  /** Returns true if both worlds have same name and same state. */
+-  def winning(target: World): Boolean = state == LANDED
+-
+-  def diffTo(world: World): String = null
+-
+-  def reset(initialWorld: LanderWorld): Unit = {
+-    width = initialWorld.width
+-    height = initialWorld.height
+-    ground = initialWorld.ground
+-    position = initialWorld.position
+-    speed = initialWorld.speed
+-    angle = initialWorld.angle
+-    thrust = initialWorld.thrust
+-    fuel = initialWorld.fuel
+-    state = initialWorld.state
+-    desiredAngle = angle
+-    desiredThrust = thrust
+-  }
+-
+-  def getView() = new LanderWorldView(parent)
+-
+-  override def toString() = "scala lander world"
+-
+-  // simulation
+-
+-  def angleRadian = gameAngleToRadian(angle)
+-
+-  private def groundSegments = {
+-    if (ground.isEmpty) List()
+-    else (ground, ground.tail).zipped map (Segment(_, _))
+-  }
+-
+-  private def flatSegments = groundSegments.filter((s) => s.start.y == s.end.y)
+-
+-  private def touchesSomeFlatSegment(p: Point) = flatSegments
+-      .find((s) => p.x > s.start.x && p.x < s.end.x && p.y - s.start.y < 1)
+-      .isDefined
+-
+-  private def isUnderground(p: Point) =
+-    groundSegments.filter(new Ray(p, Point(0, 1)).intersects(_)).length % 2 == 1
+-
+-  def simulate(dt: Double) {
+-    if (state == FLYING) {
+-      angle = clamp(-90.0 max (angle - 5), 90.0 min (angle + 5), desiredAngle)
+-      thrust = clamp(0 max (thrust - 1), 5 min (thrust + 1), desiredThrust) min fuel
+-      val force = radianToVector(angleRadian) * thrust + LanderWorld.GRAVITY
+-      position = position + speed * dt
+-      speed = speed + force * dt
+-      fuel = (fuel - thrust) max 0
+-
+-      lazy val underground = isUnderground(position)
+-      lazy val goodConfig = speed.y.abs <= 10 && speed.x.abs <= 5 && (angleRadian - PI/2) < 1e-2
+-      lazy val touchesFlat = touchesSomeFlatSegment(position)
+-      lazy val outOfWorldX = position.x < 0 || position.x > width
+-      lazy val outOfWorldY = position.y < 0 || position.y > height
+-      lazy val outOfWorld = outOfWorldX || outOfWorldY
+-
+-      state =
+-        if (underground) {
+-          if (goodConfig && touchesFlat) LANDED
+-          else CRASHED
+-        } else {
+-          if (outOfWorld) OUT
+-          else FLYING
+-        }
+-    }
+-  }
+-}
+Index: b/src/lessons/lander/universe/LanderWorldView.scala
+===================================================================
+--- a/src/lessons/lander/universe/LanderWorldView.scala
++++ /dev/null
+@@ -1,207 +0,0 @@
+-package lessons.lander.universe
+-
+-import plm.core.ui.WorldView
+-import plm.universe.World
+-import java.awt.Graphics
+-import java.awt.Graphics2D
+-import java.awt.RenderingHints
+-import java.awt.Color
+-import java.awt.geom.Rectangle2D
+-import java.awt.geom.Line2D
+-import java.awt.BasicStroke
+-import java.awt.geom.AffineTransform
+-import java.awt.geom.GeneralPath
+-import java.awt.geom.Path2D
+-import Math.PI
+-import java.awt.geom.QuadCurve2D
+-import scala.util.Random
+-import java.awt.Font
+-import java.awt.event.MouseListener
+-import java.awt.event.MouseMotionListener
+-import java.awt.event.MouseMotionAdapter
+-import java.awt.event.MouseEvent
+-import java.awt.event.MouseAdapter
+-import java.awt.geom.Point2D
+-
+-object LanderWorldView {
+-  private val LANDER_SHAPE = List(
+-      List(Point(-2, 3), Point(-3, 4), Point(-3, 7), Point(-2, 8), Point(2, 8), Point(3, 7),
+-          Point(3, 4), Point(2, 3), Point(-2, 3)),
+-      List(Point(-6, 0), Point(-4, 0)),
+-      List(Point(6, 0), Point(4, 0)),
+-      List(Point(-5, 0), Point(-4, 2.8), Point(-2, 3)),
+-      List(Point(5, 0), Point(4, 2.8), Point(2, 3)))
+-
+-  private val EXPLOSION_SHAPE = List(
+-      Point(-4, 3), Point(-1, 2), Point(0, 4), Point(1, 2), Point(4, 2), Point(2, 0),
+-      Point(3, -2), Point(0, -1), Point(-3, -3), Point(-2, 0), Point(-4, 3))
+-}
+-
+-class LanderWorldView(delagatingWorld: DelegatingLanderWorld) extends WorldView(delagatingWorld) {
+-
+-  import LanderWorld.State._
+-
+-  private def realWorld = world.asInstanceOf[DelegatingLanderWorld].realWorld
+-
+-  private var mouseIn : Boolean = false
+-  private var mousePos : Point = Point(0, 0)
 -
--			return cache.get(className);			
+-  addMouseListener(new MouseAdapter() {
+-    override def mouseEntered(e: MouseEvent) {
+-      mouseIn = true
+-    }
+-    override def mouseExited(e: MouseEvent) {
+-      mouseIn = false
+-      repaint()
+-    }
+-  })
+-
+-  addMouseMotionListener(new MouseMotionAdapter() {
+-    override def mouseMoved(event: MouseEvent) = {
+-      mousePos = Point(event.getX, event.getY)
+-      repaint()
+-    }
+-  })
+-
+-  override def paintComponent(g: Graphics) = {
+-    super.paintComponent(g);
+-    val g2 = g.asInstanceOf[Graphics2D];
+-    new Painter(g2).paint()
+-  }
+-
+-  private class Painter(g2: Graphics2D) {
+-    def paint() {
+-      val initialTransform = g2.getTransform()
+-      setupRendering()
+-      clearWidgetBackground()
+-      setupGlobalTransform()
+-      clearWorldBackground()
+-      drawGround()
+-      drawStats(initialTransform)
+-      realWorld.state match {
+-        case FLYING => drawLander(drawFlame = true)
+-        case LANDED => drawLander(drawFlame = false)
+-        case OUT => drawQuestionMarks()
+-        case CRASHED => drawExplosion()
+-      }
+-    }
+-
+-    def setupRendering() {
+-      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
+-    }
+-
+-    def clearWidgetBackground() = {
+-      g2.setColor(Color.gray)
+-      g2.fill(new Rectangle2D.Double(0, 0, getWidth, getHeight))
+-    }
+-
+-    def setupGlobalTransform() = {
+-      val scale = (getWidth.toDouble / realWorld.width) min (getHeight.toDouble / realWorld.height)
+-      val translateX = (getWidth - realWorld.width * scale) / 2
+-      val translateY = (getHeight + realWorld.height * scale) / 2
+-      g2.translate(translateX, translateY)
+-      g2.scale(scale, -scale)
+-    }
+-
+-    def clearWorldBackground() = {
+-      g2.setColor(Color.black);
+-      g2.fill(new Rectangle2D.Double(0, 0, realWorld.width, realWorld.height));
+-    }
+-
+-    /** Sets the line width to 1px no matter the transform, and the color to white. */
+-    def resetPen() {
+-      val transform = g2.getTransform();
+-      val scale = (transform.getScaleX() min transform.getScaleY()).abs;
+-      g2.setStroke(new BasicStroke((1 / scale).toFloat))
+-      g2.setColor(Color.white)
+-    }
+-
+-    def drawPath(path: List[Point], fill: Boolean) {
+-      if (!path.isEmpty) {
+-        val polyLine = new GeneralPath(Path2D.WIND_EVEN_ODD, path.length)
+-        polyLine.moveTo(path.head.x, path.head.y)
+-        for (point <- path.tail) {
+-          polyLine.lineTo(point.x, point.y)
+-        }
+-        if (fill) {
+-          g2.fill(polyLine)
+-        } else {
+-          g2.draw(polyLine)
+-        }
+-      }
+-    }
+-
+-    def drawText(text: String, x: Double, y: Double) {
+-      val oldTransform = g2.getTransform()
+-      g2.translate(x, y)
+-      g2.scale(1, -1)
+-      g2.drawString(text, 0, 0)
+-      g2.setTransform(oldTransform)
+-    }
+-
+-    def drawGround() = {
+-      resetPen()
+-      drawPath(realWorld.ground, fill = false)
+-    }
+-
+-    def randomScaleFactor() = 1 + Random.nextDouble() * 0.2
+-
+-    def drawLander(drawFlame: Boolean) = {
+-      val oldTransform = g2.getTransform()
+-      g2.translate(realWorld.position.x, realWorld.position.y)
+-      g2.scale(6, 6)  // the lander shape is small
+-      resetPen()
+-      g2.rotate(realWorld.angleRadian - PI/2)
+-      LanderWorldView.LANDER_SHAPE.foreach(drawPath(_, fill = false))
+-      val thrust = realWorld.thrust
+-      if (drawFlame && thrust > 0) {
+-        val controlX = (0.4 + thrust * 0.1) * randomScaleFactor()
+-        val endY = (-2 * thrust) * randomScaleFactor()
+-        val controlY = (endY + 3) / 2
+-        g2.draw(new QuadCurve2D.Double(-0.25, 3, -controlX, controlY, 0, endY))
+-        g2.draw(new QuadCurve2D.Double(0.25, 3, controlX, controlY, 0, endY))
+-      }
+-      g2.setTransform(oldTransform)
+-    }
+-
+-    def drawExplosion() = {
+-      val oldTransform = g2.getTransform()
+-      g2.translate(realWorld.position.x, realWorld.position.y)
+-      g2.scale(15, 15)  // the explosion shape is small
+-      resetPen()
+-      drawPath(LanderWorldView.EXPLOSION_SHAPE, fill = true)
+-      g2.setTransform(oldTransform)
+-    }
+-
+-    def drawQuestionMarks() = {
+-      val x = realWorld.position.x
+-      val y = realWorld.position.y
+-      val textX = if (x >= realWorld.width) realWorld.width - 100 else if (x <= 0) 5 else x
+-      val textY = if (y >= realWorld.height) realWorld.height - 40 else if (y <= 0) 5 else y - 30
+-      g2.setColor(Color.WHITE)
+-      g2.setFont(new Font(Font.MONOSPACED, Font.BOLD, 40))
+-      drawText("???", textX, textY)
+-    }
+-
+-    def drawStats(initialTransform: AffineTransform) {
+-      g2.setColor(Color.LIGHT_GRAY)
+-      g2.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 30))
+-      drawText(f"x: ${realWorld.position.x}%.2f", 5, realWorld.height - 30)
+-      drawText(f"y: ${realWorld.position.y}%.2f", 5, realWorld.height - 2 * 30)
+-      drawText(f"speed x: ${realWorld.speed.x}%.2f", 5, realWorld.height - 3 * 30)
+-      drawText(f"speed y: ${realWorld.speed.y}%.2f", 5, realWorld.height - 4 * 30)
+-      drawText(f"angle: ${realWorld.angle}%.2f°", 5, realWorld.height - 5 * 30)
+-      drawText(f"thrust: ${realWorld.thrust}", 5, realWorld.height - 6 * 30)
+-      drawText(f"fuel: ${realWorld.fuel}", 5, realWorld.height - 7 * 30)
+-
+-      if (mouseIn) {
+-        val deltaTransform = new AffineTransform(g2.getTransform())
+-        deltaTransform.invert()
+-        deltaTransform.concatenate(initialTransform)
+-        val coord = deltaTransform.transform(new Point2D.Double(mousePos.x, mousePos.y), null)
+-        drawText(f"x: ${coord.getX.round}", realWorld.width - 130, realWorld.height - 30)
+-        drawText(f"y: ${coord.getY.round}", realWorld.width - 130, realWorld.height - 2 * 30)
+-      }
+-    }
+-  }
+-}
+Index: b/src/lessons/lander/Main.fr.html
+===================================================================
+--- a/src/lessons/lander/Main.fr.html
++++ /dev/null
+@@ -1,23 +0,0 @@
+-
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h1>Alunisseur</h1>
+-
+-<p>Dans cette leçon, vous pilotez un alunisseur dans des situations de plus en
+-plus complexes.</p>
+-
+-<p>À chaque pas de la simulation, le joueur donne des commandes contrôlant
+-l'angle et la poussée du module d'alunissage.</p>
+-
+-<p>Idées d'exercices à ajouter à la progression proposée :</p>
+-<ul>
+-  <li>Un alunisseur en position verticale au dessus d'un sol plat. Le joueur ne
+-peut régler que la poussée (c'est fait).</li>
+-  <li>Un alunisseur en position verticale pas au dessus d'un sol plat. Le joueur
+-peut régler la poussée et l'angle (c'est fait).</li>
+-  <li>Un alunisseur avec un angle et une vitesse difficile, pas au dessus d'un sol
+-plat. Le joueur contrôle la poussée et l'angle.</li>
+-  <li>Un alunisseur avec un angle et une vitesse difficile, pas au dessus d'un sol
+-plat dans une configuration difficile. Le joueur contrôle la poussée et
+-l'angle.</li>
+-  <li>La même chose avec du vent ?</li>
+-</ul>
+Index: b/src/lessons/lander/Main.html
+===================================================================
+--- a/src/lessons/lander/Main.html
++++ /dev/null
+@@ -1,21 +0,0 @@
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h1>Lunar Lander</h1>
+-
+-<p>In this lesson you pilot a lunar landing module in increasingly complex
+-situations.</p>
+-
+-<p>At each step of the simulation, the player issues a command controlling how
+-much the angle and thrust of the lander should change</p>
+-
+-<p>Ideas concerning the progression of exercises:</p>
+-<ul>
+-  <li>A lander in vertical position above flat ground, the player can only
+-control thrust (done)</li>
+-  <li>A lander in vertical position not above flat ground, the player control
+-thrust and angle (done)</li>
+-  <li>A lander with difficult angle and speed not above flat ground, the
+-player control thrust and angle</li>
+-  <li>A lander with difficult angle and speed not above flat ground, with
+-difficult ground, the player control thrust and angle</li>
+-  <li>Same with wind?</li>
+-</ul>
+Index: b/src/lessons/lander/Main.scala
+===================================================================
+--- a/src/lessons/lander/Main.scala
++++ /dev/null
+@@ -1,14 +0,0 @@
+-package lessons.lander
+-
+-import plm.core.model.lesson.Lesson
+-import lessons.lander.lvl1_lander_101.Lander101
+-import lessons.lander.lvl2_locate_landing_zone.LocateLandingZone
+-import lessons.lander.lvl3_fly_the_lander.FlyTheLander
+-
+-class Main extends Lesson {
+-  override def loadExercises = {
+-    addExercise(new Lander101(this));
+-    addExercise(new LocateLandingZone(this));
+-    addExercise(new FlyTheLander(this));
+-  }
+-}
+Index: b/src/lessons/lander/icon.svg
+===================================================================
+--- a/src/lessons/lander/icon.svg
++++ /dev/null
+@@ -1,104 +0,0 @@
+-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+-<!-- Created with Inkscape (http://www.inkscape.org/) -->
+-
+-<svg
+-   xmlns:dc="http://purl.org/dc/elements/1.1/"
+-   xmlns:cc="http://creativecommons.org/ns#"
+-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+-   xmlns:svg="http://www.w3.org/2000/svg"
+-   xmlns="http://www.w3.org/2000/svg"
+-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+-   width="64"
+-   height="64"
+-   id="svg2"
+-   version="1.1"
+-   inkscape:version="0.48.4 r9939"
+-   sodipodi:docname="lander.svg"
+-   inkscape:export-filename="/home/polux/projects/PLM/src/lessons/lander/lander.png"
+-   inkscape:export-xdpi="90"
+-   inkscape:export-ydpi="90">
+-  <defs
+-     id="defs4" />
+-  <sodipodi:namedview
+-     id="base"
+-     pagecolor="#ffffff"
+-     bordercolor="#666666"
+-     borderopacity="1.0"
+-     inkscape:pageopacity="0.0"
+-     inkscape:pageshadow="2"
+-     inkscape:zoom="7.9195959"
+-     inkscape:cx="29.558295"
+-     inkscape:cy="29.181329"
+-     inkscape:document-units="px"
+-     inkscape:current-layer="layer1"
+-     showgrid="true"
+-     inkscape:window-width="1600"
+-     inkscape:window-height="883"
+-     inkscape:window-x="0"
+-     inkscape:window-y="17"
+-     inkscape:window-maximized="0">
+-    <inkscape:grid
+-       type="xygrid"
+-       id="grid2985"
+-       empspacing="5"
+-       visible="true"
+-       enabled="true"
+-       snapvisiblegridlinesonly="true" />
+-  </sodipodi:namedview>
+-  <metadata
+-     id="metadata7">
+-    <rdf:RDF>
+-      <cc:Work
+-         rdf:about="">
+-        <dc:format>image/svg+xml</dc:format>
+-        <dc:type
+-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+-        <dc:title></dc:title>
+-      </cc:Work>
+-    </rdf:RDF>
+-  </metadata>
+-  <g
+-     inkscape:label="Layer 1"
+-     inkscape:groupmode="layer"
+-     id="layer1"
+-     transform="translate(0,-988.36215)">
+-    <g
+-       id="g3008"
+-       transform="translate(2,8)">
+-      <path
+-         sodipodi:nodetypes="ccccccccc"
+-         transform="translate(0,988.36215)"
+-         inkscape:connector-curvature="0"
+-         id="path2987"
+-         d="m 20,4 20,0 5,5 0,15 -5,5 -20,0 -5,-5 0,-15 z"
+-         style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+-      <path
+-         sodipodi:nodetypes="ccc"
+-         transform="translate(0,988.36215)"
+-         inkscape:connector-curvature="0"
+-         id="path2989"
+-         d="M 20,29 10,30 5,44"
+-         style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+-      <path
+-         sodipodi:nodetypes="ccc"
+-         transform="translate(0,988.36215)"
+-         inkscape:connector-curvature="0"
+-         id="path2993"
+-         d="m 40,29 10,1 5,14"
+-         style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+-      <path
+-         transform="translate(0,988.36215)"
+-         inkscape:connector-curvature="0"
+-         id="path3004"
+-         d="m 0,44 10,0"
+-         style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+-      <path
+-         transform="translate(0,988.36215)"
+-         inkscape:connector-curvature="0"
+-         id="path3006"
+-         d="m 50,44 10,0"
+-         style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+-    </g>
+-  </g>
+-</svg>
+Index: b/src/lessons/lander/lvl1_lander_101/Lander101.fr.html
+===================================================================
+--- a/src/lessons/lander/lvl1_lander_101/Lander101.fr.html
++++ /dev/null
+@@ -1,49 +0,0 @@
+-
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h1>Se poser pour les nuls</h1>
+-
+-<p>Bravo ! Vous avez gagné dans une boîte de céréales un voyage (aller simple)
+-pour Mars. La NASA vous a même fourni un module d'excursion lunaire pour
+-l'occasion, et c'est donc avec ce véhicule que vous voyagerez.</p>
+-
+-<p>Avant le décollage, vous devez vous entraîner sur simulateur aux bases de
+-l'alunissage. Si tout se passe comme prévu, vous ne devriez pas avoir à
+-voler en mode manuel, mais mieux vaut prévenir que guérir, comme ils disent.</p>
+-
+-<p>Votre mission est de <b>poser le module avec une vitesse verticale
+-inférieure à 10 m/s</b>. Il y a deux façons d'influer sur la trajectoire du
+-module : en modifiant son angle, ou en réglant la poussée de son
+-moteur. Dans cette simulation, nous ne nous intéressons qu'à la poussée,
+-exprimée en m/s².</p>
+-
+-<p>Vous devez écrire le [!python]corps de la fonction <code>step()</code>, qui
+-sera appelée[/!][!scala|java|c]code qui sera appellé[/!] tous les dixièmes
+-de seconde pendant la simulation. Il faut ajuster la poussée du moteur en
+-utilisant la fonction <code>[!java]void [/!]setPousseeDesiree([!java]int
+-[/!]poussee[!scala]:Integer[/!])</code> où <code>poussee</code> est un
+-entier entre 0 et 4 (représentant une poussée entre 0 m/s² et 4 m/s²). Vous
+-ne pouvez incrémenter ou décrémenter la poussée que de 1 entre deux pas de
+-la simulation. Ainsi, si la poussée du moteur est actuellement de 2 et que
+-vous demandez 4, vous n'aurez que 3 à la prochaine étape. Si vous demandez
+-une valeur inférieure à 0 (ou supérieure à 4), tout se passera comme si vous
+-aviez demandé 0 (ou 4).</p>
+-
+-<p>Afin de prendre des décisions informées, vous pouvez demander des
+-informations sur l'état actuel du module. Dans cette simulation, vous ne
+-serez probablement intéressé que par sa position verticale (accessible grâce
+-à <code>[!java]double [/!]getY()[!scala]:Double[/!]</code>) et sa vitesse
+-verticale (accessible grâce à <code>[!java]double
+-[/!]getVitesseY()[!scala]:Double[/!]</code>). Vous pouvez également demander
+-la poussée actuelle du moteur (avec <code>[!java]int
+-[/!]getPoussee()[!scala]:Integer[/!]</code>) si vous avez oublié ce que vous
+-avez demandé. Rappelez vous que la gravité martienne est de 3.711 m/s², cela
+-peut vous être utile.</p>
+-
+-<p>Une dernière chose : le module est plutôt petit, et vous n'avez pas tant de
+-carburant que cela. À chaque pas de simulation, il consomme autant d'unité
+-de carburant que la poussée actuelle du moteur. Si vous tombez en panne
+-sèche, vous serez en chute libre alors attention ! Vous pouvez consulter le
+-niveau du réservoir avec <code>[!java]int
+-[/!]getFuel()[!scala]:Integer[/!]</code>.</p>
+-
+-<p>Bon courage !</p>
+Index: b/src/lessons/lander/lvl1_lander_101/Lander101.html
+===================================================================
+--- a/src/lessons/lander/lvl1_lander_101/Lander101.html
++++ /dev/null
+@@ -1,41 +0,0 @@
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h1>Lander 101</h1>
+-
+-<p>Congratulations! You won a (one-way) trip to Mars in a cereal box. NASA was
+-kind enough to donate the Lunar Excursion Module for this mission, so
+-that's what you'll be flying.</p>
+-
+-<p>Before you take off, you must go through some basic landing simulation. You
+-shouldn't have to fly the lander if all goes as planned but, as they say,
+-"better safe than sorry".</p>
+-
+-<p>Your mission is to <b>land the lander with a vertical speed of at most 10
+-m/s.</b> There are two ways you can influence the lander's course: by adjusting
+-its angle or by adjusting its thrust. In this simulation we only care about
+-adjusting the thrust, expressed in m/s².</p>
+-
+-<p>The [!python]<code>step()</code> function[/!][!scala|java|c]code[/!] that you 
+-should write now will be called every 0.1 second during the simulation. It should 
+-set the desired thrust of the next simulation step, by calling 
+-<code>[!java]void [/!]setDesiredThrust([!java]int [/!]desiredThrust[!scala]:Integer[/!])</code> 
+-where <code>desiredThrust</code> is some integer between 0 and 4 (that is, a thrust 
+-between 0 m/s² and 4 m/s²). You can only increment or decrement the thrust by 1 
+-between two simulation steps, so if the current thrust is 2 and you ask for 4, 
+-you'll only get 3 in the next step. If you ask for less than 0 (resp. more than 4), 
+-everything will be as if you had asked for 0 (resp. 4).</p>
+-
+-<p>In order to take informed decisions, you can query the lander's state. In
+-this simulation you'll probably be interested in its vertical position:
+-<code>[!java]double [/!]getY()[!scala]:Double[/!]</code>, and its vertical speed: 
+-<code>[!java]double [/!]getSpeedY()[!scala]:Double[/!]</code>. You can also ask for 
+-the thrust via <code>[!java]int [/!]getThrust()[!scala]:Integer[/!]</code> in case 
+-you don't remember what you asked for. Remember that Mars' gravity is 3.711 m/s², 
+-it might come in handy.</p>
+-
+-<p>One last thing: the lander is pretty small so you don't have much fuel. At
+-each step of the simulation the lander consumes as many fuel units as the
+-current thrust. Once you run out of fuel you're in free fall so beware! You can
+-consult the remaining amount of available fuel units using 
+-<code>[!java]int [/!]getFuel()[!scala]:Integer[/!]</code>.</p>
+-
+-<p>Good luck!</p>
+Index: b/src/lessons/lander/lvl1_lander_101/Lander101.it.html
+===================================================================
+--- a/src/lessons/lander/lvl1_lander_101/Lander101.it.html
++++ /dev/null
+@@ -1,45 +0,0 @@
+-
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h1>Lander 101</h1>
+-
+-<p>Congratulations! You won a (one-way) trip to Mars in a cereal box. NASA was
+-kind enough to donate the Lunar Excursion Module for this mission, so that's
+-what you'll be flying.</p>
+-
+-<p>Before you take off, you must go through some basic landing simulation. You
+-shouldn't have to fly the lander if all goes as planned but, as they say,
+-"better safe than sorry".</p>
+-
+-<p>Your mission is to <b>land the lander with a vertical speed of at most 10
+-m/s.</b> There are two ways you can influence the lander's course: by
+-adjusting its angle or by adjusting its thrust. In this simulation we only
+-care about adjusting the thrust, expressed in m/s².</p>
+-
+-<p>The [!python]<code>step()</code> function[/!][!scala|java|c]code[/!] that
+-you should write now will be called every 0.1 second during the
+-simulation. It should set the desired thrust of the next simulation step, by
+-calling <code>[!java]void [/!]setDesiredThrust([!java]int
+-[/!]desiredThrust[!scala]:Integer[/!])</code> where
+-<code>desiredThrust</code> is some integer between 0 and 4 (that is, a
+-thrust between 0 m/s² and 4 m/s²). You can only increment or decrement the
+-thrust by 1 between two simulation steps, so if the current thrust is 2 and
+-you ask for 4, you'll only get 3 in the next step. If you ask for less than
+-0 (resp. more than 4), everything will be as if you had asked for 0
+-(resp. 4).</p>
+-
+-<p>In order to take informed decisions, you can query the lander's state. In
+-this simulation you'll probably be interested in its vertical position:
+-<code>[!java]double [/!]getY()[!scala]:Double[/!]</code>, and its vertical
+-speed: <code>[!java]double [/!]getSpeedY()[!scala]:Double[/!]</code>. You
+-can also ask for the thrust via <code>[!java]int
+-[/!]getThrust()[!scala]:Integer[/!]</code> in case you don't remember what
+-you asked for. Remember that Mars' gravity is 3.711 m/s², it might come in
+-handy.</p>
+-
+-<p>One last thing: the lander is pretty small so you don't have much fuel. At
+-each step of the simulation the lander consumes as many fuel units as the
+-current thrust. Once you run out of fuel you're in free fall so beware! You
+-can consult the remaining amount of available fuel units using
+-<code>[!java]int [/!]getFuel()[!scala]:Integer[/!]</code>.</p>
+-
+-<p>Buona fortuna!</p>
+Index: b/src/lessons/lander/lvl1_lander_101/Lander101.pt_BR.html
+===================================================================
+--- a/src/lessons/lander/lvl1_lander_101/Lander101.pt_BR.html
++++ /dev/null
+@@ -1,45 +0,0 @@
+-
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h1>Lander 101</h1>
+-
+-<p>Congratulations! You won a (one-way) trip to Mars in a cereal box. NASA was
+-kind enough to donate the Lunar Excursion Module for this mission, so that's
+-what you'll be flying.</p>
+-
+-<p>Before you take off, you must go through some basic landing simulation. You
+-shouldn't have to fly the lander if all goes as planned but, as they say,
+-"better safe than sorry".</p>
+-
+-<p>Your mission is to <b>land the lander with a vertical speed of at most 10
+-m/s.</b> There are two ways you can influence the lander's course: by
+-adjusting its angle or by adjusting its thrust. In this simulation we only
+-care about adjusting the thrust, expressed in m/s².</p>
+-
+-<p>The [!python]<code>step()</code> function[/!][!scala|java|c]code[/!] that
+-you should write now will be called every 0.1 second during the
+-simulation. It should set the desired thrust of the next simulation step, by
+-calling <code>[!java]void [/!]setDesiredThrust([!java]int
+-[/!]desiredThrust[!scala]:Integer[/!])</code> where
+-<code>desiredThrust</code> is some integer between 0 and 4 (that is, a
+-thrust between 0 m/s² and 4 m/s²). You can only increment or decrement the
+-thrust by 1 between two simulation steps, so if the current thrust is 2 and
+-you ask for 4, you'll only get 3 in the next step. If you ask for less than
+-0 (resp. more than 4), everything will be as if you had asked for 0
+-(resp. 4).</p>
+-
+-<p>In order to take informed decisions, you can query the lander's state. In
+-this simulation you'll probably be interested in its vertical position:
+-<code>[!java]double [/!]getY()[!scala]:Double[/!]</code>, and its vertical
+-speed: <code>[!java]double [/!]getSpeedY()[!scala]:Double[/!]</code>. You
+-can also ask for the thrust via <code>[!java]int
+-[/!]getThrust()[!scala]:Integer[/!]</code> in case you don't remember what
+-you asked for. Remember that Mars' gravity is 3.711 m/s², it might come in
+-handy.</p>
+-
+-<p>One last thing: the lander is pretty small so you don't have much fuel. At
+-each step of the simulation the lander consumes as many fuel units as the
+-current thrust. Once you run out of fuel you're in free fall so beware! You
+-can consult the remaining amount of available fuel units using
+-<code>[!java]int [/!]getFuel()[!scala]:Integer[/!]</code>.</p>
+-
+-<p>Boa Sorte!</p>
+Index: b/src/lessons/lander/lvl1_lander_101/Lander101.scala
+===================================================================
+--- a/src/lessons/lander/lvl1_lander_101/Lander101.scala
++++ /dev/null
+@@ -1,17 +0,0 @@
+-package lessons.lander.lvl1_lander_101
+-
+-import plm.core.model.lesson.ExerciseTemplated
+-import plm.core.model.lesson.Lesson
+-import lessons.lander.universe.DelegatingLanderWorld
+-import lessons.lander.universe.Point
+-import lessons.lander.universe.LanderEntity
+-import lessons.lander.universe.Configurations._
+-import Math.PI
+-import scala.collection.JavaConversions._
+-import lessons.lander.universe.LanderWorld
+-import plm.universe.World
+-
+-class Lander101(lesson: Lesson) extends ExerciseTemplated(lesson, null) {
+-  tabName = "Lander"
+-  setup(SIMPLE_TERRAIN_TRIVIAL_CONFIG)
+-}
+Index: b/src/lessons/lander/lvl1_lander_101/Lander101Entity.java
+===================================================================
+--- a/src/lessons/lander/lvl1_lander_101/Lander101Entity.java
++++ /dev/null
+@@ -1,14 +0,0 @@
+-package lessons.lander.lvl1_lander_101;
+-
+-import lessons.lander.universe.LanderEntity;
+-
+-public class Lander101Entity extends LanderEntity {
+-  @Override
+-  public void step() {
+-    /* BEGIN TEMPLATE */
+-    /* BEGIN SOLUTION */
+-    setDesiredThrust(getSpeedY() < -9 ? 4 : 3);
+-    /* END SOLUTION */
+-    /* END TEMPLATE */
+-  }
+-}
+Index: b/src/lessons/lander/lvl1_lander_101/Lander101Entity.py
+===================================================================
+--- a/src/lessons/lander/lvl1_lander_101/Lander101Entity.py
++++ /dev/null
+@@ -1,13 +0,0 @@
+-# BEGIN TEMPLATE
+-def step():
+-# BEGIN SOLUTION
+-    if getSpeedY() < -9:
+-        setDesiredThrust(4)
+-    else:
+-        setDesiredThrust(3)
+-# END SOLUTION
+-# END TEMPLATE 
+-
+-while isFlying():
+-  step()
+-  simulateStep()
+Index: b/src/lessons/lander/lvl1_lander_101/ScalaLander101Entity.scala
+===================================================================
+--- a/src/lessons/lander/lvl1_lander_101/ScalaLander101Entity.scala
++++ /dev/null
+@@ -1,17 +0,0 @@
+-package lessons.lander.lvl1_lander_101;
+-
+-import lessons.lander.universe._;
+-
+-class ScalaLander101Entity extends LanderEntity {
+-	override def step() {
+-		/* BEGIN TEMPLATE */
+-		/* BEGIN SOLUTION */
+-		if (getSpeedY() < -9) {
+-			setDesiredThrust(4)
+-		} else {
+-			setDesiredThrust(3);
 -		}
+-		/* END SOLUTION */
+-		/* END TEMPLATE */
 -	}
--	
--	class PLMReporter extends AbstractReporter {
--		final static int INFO = 0;
--		final static int WARNING = 1;
--		final static int ERROR = 2;
--		int offset=0;
--		Vector<String> messages = new Vector<String>();
--		Settings settings;
--
--		public PLMReporter(Settings s) {
--			settings = s;
--		}
--		public void setOffset(int _offset) {
--			this.offset = _offset;
--		}
--		@Override
--		public Settings settings() {
--			return settings;
--		}
--		@Override
--		public void displayPrompt() { 
--			/* Don't do that, pal. */ 
--		}
--		@Override
--		public void display(Position pos, String message, Severity _severity) {
--			String severityName = _severity.toString(); 
--			String label = "";
--			int severity = -1;
--			if (severityName.equals("INFO") || severityName.equals("scala.tools.nsc.reporters.Reporter$Severity at 0"))
--				severity = INFO;
--			if (severityName.equals("WARNING") || severityName.equals("scala.tools.nsc.reporters.Reporter$Severity at 1")) {
--				severity = WARNING;
--				label= "warning: ";
--			}
--			if (severityName.equals("ERROR") || severityName.equals("scala.tools.nsc.reporters.Reporter$Severity at 2")) {
--				severity = ERROR;
--				label = "error: ";
--			}
--			if (severity == -1)
--				throw new RuntimeException("Got an unknown severity: "+severityName+". Please adapt the PLM to this new version of scala (or whatever).");
--			if (severity == INFO && !Game.getInstance().isDebugEnabled()) 
--				return;
+-}
+Index: b/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.fr.html
+===================================================================
+--- a/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.fr.html
++++ /dev/null
+@@ -1,39 +0,0 @@
 -
--			int lineNum = -1;
--			try {
--				lineNum = pos.line() - offset;
--			} catch (Throwable t) {
--				// That's fine if the line number is not defined.
--			}
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h2>Repérer une zone plate</h2>
 -
--			String name = pos.source().path();
--			int lastDot = name.lastIndexOf('.');
--			if (lastDot != -1)
--				name = name.substring(lastDot+1);
--			String msg = name+(lineNum == -1? "": ":"+lineNum) +": "+label+message;
--
--			// Append the line content and a position marker, if possible
--			if (pos != null && pos.isDefined()) {
--				msg += "\n"+pos.inUltimateSource(pos.source()).lineContent()+"\n";
--				for (int i=0;i<pos.column()-1;i++)
--					msg += " ";
--				msg += "^";
--			}
+-<p>Après 200 jours de voyage intersidéral à manger des céréales, vous êtes
+-enfin parvenu à la planète rouge. Il est enfin temps de se poser !</p>
 -
--			messages.add(msg);
--		}
--		public void throwExceptionOnNeed() throws PLMCompilerException {
--			if (hasErrors()) {
--				StringBuffer sb = new StringBuffer();
--				for (String s : messages)
--					sb.append(s);
--				throw new PLMCompilerException(sb.toString(), null, null);
+-<p>Le module est en pilote automatique, et vous n'avez qu'à regarder autour de
+-vous pour sélectionner une zone d'alunissage. Vous devez vous poser sur
+-<b>une zone plate</b> si vous ne voulez pas vous scratcher. Vous indiquez au
+-pilote automatique où se poser en modifiant la fonction
+-<code>getLandingZone</code> de façon à ce qu'elle retourne [!java|scala]un
+-Segment représentant la zone de votre choix.
+-
+-<p>Un Segment est composé de deux <code>Point</code>s, chacun composé de deux
+-doubles. On construit un nouveau segment de la façon suivante :
+-<code>Segment([!java]Point [/!]debut[!scala]:Point[/!], [!java]Point
+-[/!]fin[!scala]:Point[/!])</code>. Pour créer de nouveaux points, il faut
+-utiliser le constructeur <code>Point([!java]double [/!]x[!scala]:Double[/!],
+-[!java]double [/!]y[!scala]:Double[/!])</code>. Les coordonnées d'un point
+-sont accessibles grâce à ses méthodes <code>[!java]double
+-[/!]x()[!scala]:Double[/!]</code> et <code>[!java]double
+-[/!]y()[!scala]:Double[/!]</code>.</p>[/!] [!python]tuple de deux coordonnées X délimitant la zone de votre
+-choix.[/!]
+-
+-<p>Pour déterminer la zone cible, vous devez appeler
+-<code>[!java]List<Point> [/!]getSol()[!scala]:List[Point][/!]</code>,
+-qui retourne les points qui composent la surface sous la forme d'une list de
+-[!java|scala]<code>Point</code>[/!] [!python]tuples (x,y)[/!].</p>
+-
+-<p>Une dernière chose : votre fonction doit retourner une zone valide dans
+-toutes les situations, pas seulement celle que l'on voit en ce moment. C'est
+-que votre code sera utilisé dans ce cas, mais également dans la
+-configuration que nous avions dans l'exercice précédent. Comme d'habitude,
+-vous pouvez voir les autres mondes en les sélectionnant dans le combobox au
+-dessus de la vue du monde.</p>
+-
+-<p>Bon alunissage ! N'oubliez pas de mettre votre combinaison spatiale en
+-sortant.</p>
+Index: b/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.html
+===================================================================
+--- a/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.html
++++ /dev/null
+@@ -1,34 +0,0 @@
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h2>Locate a Landing Zone</h2>
+-
+-<p>After 200 days of traveling space and eating cereals you finally reach
+-Mars. Time to land at last!</p>
+-
+-<p>The lander is on autopilot and all you have to do is look around and tell it
+-where to land. The lander must <b>land on a flat zone</b> it you want to remain
+-in one piece. You indicate the lander where to land by modifying the
+-<code>getLandingZone</code> function so that it returns a 
+-[!java|scala]<code>Segment</code> representing the zone of your choice.
+-
+-<p>A segment is composed of two <code>Point</code>s, each of them composed of
+-two <code>double</code>s. A segment is built via the 
+-<code>Segment([!java]Point [/!]start[!scala]:Point[/!], [!java]Point [/!]end[!scala]:Point[/!])</code> constructor. 
+-A point is built via the <code>Point([!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!])</code> constructor. A point's coordinates are accessible via its
+-<code>[!java]double [/!]x()[!scala]:Double[/!]</code> and
+-<code>[!java]double [/!]y()[!scala]:Double[/!]</code> methods.</p>[/!]
+-
+-[!python]tuple of two X coordinates representing the zone of your choice.[/!]
+-
+-<p>In order to determine which zone to return, you'll need to call
+-<code>[!java]List<Point> [/!]getGround()[!scala]List[Point][/!]</code>, which returns 
+-the vertices of the ground's profile as a list of 
+-[!java|scala]<code>Point</code>[/!] [!python]tuples (x,y)[/!].</p>
+-
+-<p>One more thing: your function should return a valid flat zone in any kind of
+-situation, not just for the currently visualized one. That's because it will
+-be not only tested against that world, but also against the one we had in the
+-previous exercise. As usual, you can see the other existing worlds with the
+-appropriate combobox.</p>
+-
+-<p>Have a safe landing! Don't forget to put on your space suit on your way
+-out.</p>
+Index: b/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.scala
+===================================================================
+--- a/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZone.scala
++++ /dev/null
+@@ -1,19 +0,0 @@
+-package lessons.lander.lvl2_locate_landing_zone
+-
+-import plm.core.model.lesson.ExerciseTemplated
+-import plm.core.model.lesson.Lesson
+-import lessons.lander.universe.DelegatingLanderWorld
+-import lessons.lander.universe.Point
+-import lessons.lander.universe.LanderEntity
+-import lessons.lander.universe.Configurations._
+-import Math.PI
+-import scala.collection.JavaConversions._
+-import lessons.lander.universe.LanderWorld
+-import plm.universe.World
+-
+-class LocateLandingZone(lesson: Lesson) extends ExerciseTemplated(lesson, null) {
+-  tabName = "Lander"
+-  setup(Array(
+-      CHALLENGING_TERRAIN_SIMPLE_CONFIG,
+-      SIMPLE_TERRAIN_TRIVIAL_CONFIG))
+-}
+Index: b/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZoneEntity.java
+===================================================================
+--- a/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZoneEntity.java
++++ /dev/null
+@@ -1,57 +0,0 @@
+-package lessons.lander.lvl2_locate_landing_zone;
+-
+-import java.util.Iterator;
+-
+-import lessons.lander.universe.LanderEntity;
+-import lessons.lander.universe.Point;
+-import lessons.lander.universe.Segment;
+-
+-public class LocateLandingZoneEntity extends LanderEntity {
+-  /* BEGIN TEMPLATE */
+-  public Segment getLandingZone() {
+-    /* return new Segment(new Point(0,0), new Point(0,0)); */
+-    /* BEGIN SOLUTION */
+-    Iterator<Point> ground = getGround().iterator();
+-    Point lastPoint = ground.next();
+-    while (ground.hasNext()) {
+-      Point point = ground.next();
+-      if (lastPoint.y() == point.y()) {
+-        return new Segment(lastPoint, point);
+-      }
+-      lastPoint = point;
+-    }
+-    return null;
+-    /* END SOLUTION */
+-  }
+-  /* END TEMPLATE */
+-
+-  /* BEGIN HIDDEN */
+-  double targetStart = 0;
+-  double targetEnd = 0;
+-
+-  @Override
+-  public void initialize() {
+-    Segment landingZone = getLandingZone();
+-    targetStart = landingZone.start().x();
+-    targetEnd = landingZone.end().x();
+-  }
+-
+-  @Override
+-  public void step() {
+-    if (getX() < targetStart) {
+-      setDesiredAngle(-30);
+-    } else if (getX() > targetEnd) {
+-      setDesiredAngle(30);
+-    } else {
+-      if (getSpeedX() > 5) {
+-        setDesiredAngle(25);
+-      } else if (getSpeedX() < -5) {
+-        setDesiredAngle(-25);
+-      } else {
+-        setDesiredAngle(0);
+-      }
+-    }
+-    setDesiredThrust(getSpeedY() < -9 ? 4 : 3);
+-  }
+-  /* END HIDDEN */
+-}
+Index: b/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZoneEntity.py
+===================================================================
+--- a/src/lessons/lander/lvl2_locate_landing_zone/LocateLandingZoneEntity.py
++++ /dev/null
+@@ -1,43 +0,0 @@
+-# BEGIN TEMPLATE
+-def getLandingZone():
+-    # BEGIN SOLUTION
+-    lastPoint = getGround()[0]
+-    for point in getGround():
+-        if (point != lastPoint):
+-            if lastPoint[1] == point[1]:
+-                return (lastPoint[0],point[0])
+-        lastPoint = point
+-    # END SOLUTION
+-# END TEMPLATE 
+-
+-targetStart = 0;
+-targetEnd = 0;
+-
+-def initialize():
+-    global targetStart
+-    global targetEnd
+-    (targetStart, targetEnd) = getLandingZone()
+-    if (targetStart > targetEnd):
+-        print ("Your starting point is after your ending point ("+str(targetStart)+">"+str(targetEnd)+"). Bad things will happen")
+-
+-def step():
+-    if (getX() < targetStart):
+-        setDesiredAngle(-30)
+-    elif (getX() > targetEnd):
+-        setDesiredAngle(30)
+-    elif (getSpeedX() > 5):
+-        setDesiredAngle(25)
+-    elif (getSpeedX() < -5):
+-        setDesiredAngle(-25)
+-    else:
+-        setDesiredAngle(0);
+-        
+-    if (getSpeedY() <-9):
+-        setDesiredThrust(4)
+-    else:
+-        setDesiredThrust(3)
+-
+-initialize()
+-while isFlying():
+-  step()
+-  simulateStep()
+Index: b/src/lessons/lander/lvl2_locate_landing_zone/ScalaLocateLandingZoneEntity.scala
+===================================================================
+--- a/src/lessons/lander/lvl2_locate_landing_zone/ScalaLocateLandingZoneEntity.scala
++++ /dev/null
+@@ -1,54 +0,0 @@
+-package lessons.lander.lvl2_locate_landing_zone;
+-
+-import java.util.Iterator;
+-import scala.collection.JavaConversions._
+-
+-import lessons.lander.universe._;
+-
+-class ScalaLocateLandingZoneEntity extends LanderEntity {
+-  /* BEGIN TEMPLATE */
+-  def getLandingZone():Segment = {
+-    /* BEGIN SOLUTION */
+-    var lastPoint:Point = getGround.get(0);
+-    for (point <- getGround()) {
+-      if (point != lastPoint) { // Avoid the loop when point is on the first element
+-        if (point.y == lastPoint.y)
+-          return new Segment(lastPoint,point)
+-      }
+-      lastPoint = point
+-    }
+-    return null;
+-    /* END SOLUTION */
+-  }
+-  /* END TEMPLATE */
+-
+-  var targetStart = 0.0;
+-  var targetEnd = 0.0;
+-
+-  override def initialize() {
+-    var landingZone = getLandingZone();
+-    targetStart = landingZone.start.x;
+-    targetEnd = landingZone.end.x;
+-  }
+-
+-  override def step() {
+-    if (getX() < targetStart) {
+-      setDesiredAngle(-30);
+-    } else if (getX() > targetEnd) {
+-      setDesiredAngle(30);
+-    } else {
+-      if (getSpeedX() > 5) {
+-        setDesiredAngle(25);
+-      } else if (getSpeedX() < -5) {
+-        setDesiredAngle(-25);
+-      } else {
+-        setDesiredAngle(0);
+-      }
+-    }
+-    
+-    if (getSpeedY() < -9)
+-      setDesiredThrust(4)
+-    else
+-      setDesiredThrust(3)
+-  }
+-}
+Index: b/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.fr.html
+===================================================================
+--- a/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.fr.html
++++ /dev/null
+@@ -1,41 +0,0 @@
+-
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h1>Aux commandes du module</h1>
+-
+-<p>Après 30 jours à regarder des cailloux en mangeant des céréales, vous
+-décidez qu'il est temps d'aller explorer d'autres coins de cette planète.</p>
+-
+-<p>Vous volez un moment, avant de réaliser soudain que vous êtes presque à
+-court d'essence. Le pilote automatique est malheureusement inutile dans ce
+-genre de situation périlleuse, et vous allez devoir vous poser en mode
+-manuel. Votre mission et de vous <b>poser sur une zone plate, avec une
+-vitesse verticale inférieure à 10 m/s, une vitesse horizontale inférieure à
+-5 m/s et un angle de 0°</b>.</p>
+-
+-<p>Vous devez définir deux fonctions : <code>[!java]void
+-[/!]initialize()</code> et <code>[!java]void
+-[/!]step()</code>. <code>initialize()</code> est appelée au moment où l'on
+-appuie sur le bouton «Exécuter». Vous pouvez l'utiliser pour choisir une
+-zone plate. Comme avant, <code>step()</code> est appelée tous les dixièmes
+-de seconde pour vous permettre d'ajuster la poussée (avec la fonction
+-<code>[!java]void [/!]setPousseedesiree([!java]int
+-[/!]poussee[!scala]:Integer[/!])</code>). Vous pouvez également contrôler
+-l'angle du module avec la fonction <code>[!java]void
+-[/!]setAngleDesire([!java]double [/!]angle[!scala]:Double[/!])</code>. Un
+-angle de O° dénote une position verticale, avec le sommet du module dirigé
+-vers le haut. C'est l'angle avec lequel vous devez vous poser. Un angle
+-positif indique que le module penche vers la gauche tandis qu'un angle
+-négatif indique au contraire qu'il penche à droite. Il est impossible de se
+-pencher à plus de ±90°, et on ne peut pas pencher le module de plus de ±5°
+-en une fois.</p>
+-
+-<p>Comme dans les exercices précédents, <code>[!java]List<Point>
+-[/!]getSol()[!scala]:List[Point][/!]</code> retourne les points qui
+-composent l'horizon. Le manuel de référence de votre module est disponible
+-dans la documentation (Aide/À propos de ce monde).</p>
+-
+-<p>Comme d'habitude, votre programme doit se poser sans heurt dans toutes les
+-situations que nous avons rencontré jusqu'à présent, ainsi que dans ce
+-nouveau cas.</p>
+-
+-<p>Bonne chance. Essayez de ne pas vous scratcher ;)</p>
+Index: b/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.html
+===================================================================
+--- a/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.html
++++ /dev/null
+@@ -1,33 +0,0 @@
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h1>Fly the Lander!</h1>
+-
+-<p>After 30 days of staring at rocks and eating cereals you decide it's time to
+-go explore other parts of the planet.</p>
+-
+-<p>You fly for a while and suddenly realize you're almost out of fuel.
+-Unfortunately you're in a delicate situation and the autopilot is helpless.
+-You will have to pilot the lander yourself. Your mission is to <b>land the
+-lander on a flat zone with a vertical speed less than 10 m/s, an horizontal
+-speed less than 5 m/s and an angle of 0°.</b></p>
+-
+-<p>You must define two functions: <code>[!java]void [/!]initialize()</code> and 
+-<code>[!java]void [/!]step()</code>. <code>initialize()</code> is called once just 
+-after you press "Run". You can use it to chose some flat zone. As before, 
+-<code>step()</code> is called every 0.1 second and is used for adjusting the 
+-lander's thrust and angle. As in the first exercise the lander's thrust is adjusted 
+-via <code>[!java]void [/!]setDesiredThrust([!java]int [/!]desiredThrust[!scala]:Integer[/!])</code>. 
+-But you can also control its angle via 
+-<code>[!java]void [/!]setDesiredAngle([!java]double [/!]desiredAngle[!scala]:Double[/!])</code>. 
+-An angle of 0° denotes a vertical position where the "head" of the lander points up. 
+-This is the angle you must land with. A positive angle denotes a left-leaning lander, 
+-a negative angle a right-leaning one. You cannot lean more than by ±90°, and the angle can vary by
+-at most ±5° in one step.</p>
+-
+-<p>As in the previous exercise, <code>[!java]List<Point> [/!]getGround()[!scala]:List[Point][/!]</code> returns
+-the vertices of the ground's profile from left to right. 
+-Please refer to the documentation (Help/About this world) for a reference manual of your lunar lander.</p>
+-
+-<p>As before, your program must safely land the lander in all the situations
+-encountered so far in addition to this new one.</p>
+-
+-<p>Good luck, try not to crash!</p>
+Index: b/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.pt_BR.html
+===================================================================
+--- a/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.pt_BR.html
++++ /dev/null
+@@ -1,37 +0,0 @@
+-
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h1>Fly the Lander!</h1>
+-
+-<p>After 30 days of staring at rocks and eating cereals you decide it's time to
+-go explore other parts of the planet.</p>
+-
+-<p>You fly for a while and suddenly realize you're almost out of fuel.
+-Unfortunately you're in a delicate situation and the autopilot is helpless.
+-You will have to pilot the lander yourself. Your mission is to <b>land the
+-lander on a flat zone with a vertical speed less than 10 m/s, an horizontal
+-speed less than 5 m/s and an angle of 0°.</b></p>
+-
+-<p>You must define two functions: <code>[!java]void [/!]initialize()</code> and
+-<code>[!java]void [/!]step()</code>. <code>initialize()</code> is called
+-once just after you press "Run". You can use it to chose some flat zone. As
+-before, <code>step()</code> is called every 0.1 second and is used for
+-adjusting the lander's thrust and angle. As in the first exercise the
+-lander's thrust is adjusted via <code>[!java]void
+-[/!]setDesiredThrust([!java]int
+-[/!]desiredThrust[!scala]:Integer[/!])</code>.  But you can also control its
+-angle via <code>[!java]void [/!]setDesiredAngle([!java]double
+-[/!]desiredAngle[!scala]:Double[/!])</code>.  An angle of 0° denotes a
+-vertical position where the "head" of the lander points up.  This is the
+-angle you must land with. A positive angle denotes a left-leaning lander, a
+-negative angle a right-leaning one. You cannot lean more than by ±90°, and
+-the angle can vary by at most ±5° in one step.</p>
+-
+-<p>As in the previous exercise, <code>[!java]List<Point>
+-[/!]getGround()[!scala]:List[Point][/!]</code> returns the vertices of the
+-ground's profile from left to right.  Please refer to the documentation
+-(Help/About this world) for a reference manual of your lunar lander.</p>
+-
+-<p>As before, your program must safely land the lander in all the situations
+-encountered so far in addition to this new one.</p>
+-
+-<p>Boa sorte, tente não cair!</p>
+Index: b/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.scala
+===================================================================
+--- a/src/lessons/lander/lvl3_fly_the_lander/FlyTheLander.scala
++++ /dev/null
+@@ -1,20 +0,0 @@
+-package lessons.lander.lvl3_fly_the_lander
+-
+-import plm.core.model.lesson.ExerciseTemplated
+-import plm.core.model.lesson.Lesson
+-import lessons.lander.universe.DelegatingLanderWorld
+-import lessons.lander.universe.Point
+-import lessons.lander.universe.LanderEntity
+-import lessons.lander.universe.Configurations._
+-import Math.PI
+-import scala.collection.JavaConversions._
+-import lessons.lander.universe.LanderWorld
+-import plm.universe.World
+-
+-class FlyTheLander(lesson: Lesson) extends ExerciseTemplated(lesson, null) {
+-  tabName = "Lander"
+-  setup(Array(
+-      SIMPLE_TERRAIN_CHALLENGING_CONFIG,
+-      CHALLENGING_TERRAIN_SIMPLE_CONFIG,
+-      SIMPLE_TERRAIN_TRIVIAL_CONFIG))
+-}
+Index: b/src/lessons/lander/lvl3_fly_the_lander/FlyTheLanderEntity.java
+===================================================================
+--- a/src/lessons/lander/lvl3_fly_the_lander/FlyTheLanderEntity.java
++++ /dev/null
+@@ -1,48 +0,0 @@
+-package lessons.lander.lvl3_fly_the_lander;
+-
+-import java.util.List;
+-
+-import lessons.lander.universe.LanderEntity;
+-import lessons.lander.universe.Point;
+-
+-public class FlyTheLanderEntity extends LanderEntity {
+-	/* BEGIN TEMPLATE */
+-	/* BEGIN HIDDEN */
+-	double targetStart;
+-	double targetEnd;
+-	/* END HIDDEN */
+-	public void initialize() {
+-		/* BEGIN HIDDEN */
+-		List<Point> ground = getGround();
+-		Point lastPoint = ground.get(0);
+-		for (Point point: ground) {
+-			if (point!=lastPoint && lastPoint.y() == point.y()) {
+-				targetStart = lastPoint.x();
+-				targetEnd = point.x();
+-				return;
 -			}
+-			lastPoint = point;
 -		}
--		@Override
--		public void reset() {
--			super.reset();
--			messages.removeAllElements();
+-		/* END HIDDEN */
+-	}
+-
+-	public void step() {
+-		/* BEGIN SOLUTION */
+-		if (getX() < targetStart) {
+-			setDesiredAngle(-30);
+-		} else if (getX() > targetEnd) {
+-			setDesiredAngle(30);
+-		} else {
+-			if (getSpeedX() > 5) {
+-				setDesiredAngle(25);
+-			} else if (getSpeedX() < -5) {
+-				setDesiredAngle(-25);
+-			} else {
+-				setDesiredAngle(0);
+-			}
 -		}
-+	   return null;
- 	}
- }
+-		setDesiredThrust(getSpeedY() < -9 ? 4 : 3);
+-		/* END SOLUTION */
+-	}
+-	/* END TEMPLATE */
+-}
+Index: b/src/lessons/lander/lvl3_fly_the_lander/FlyTheLanderEntity.py
+===================================================================
+--- a/src/lessons/lander/lvl3_fly_the_lander/FlyTheLanderEntity.py
++++ /dev/null
+@@ -1,45 +0,0 @@
+-# BEGIN HIDDEN
+-(startPos,endPos) = (0,0)
+-# END HIDDEN
+-
+-# BEGIN TEMPLATE
+-def initialize():
+-    pass
+-# BEGIN SOLUTION
+-    global startPos
+-    global endPos
+-    lastPoint = getGround()[0]
+-    for point in getGround():
+-        if (point != lastPoint):
+-            if lastPoint[1] == point[1]:
+-                (startPos,endPos) = (lastPoint[0],point[0])
+-        lastPoint = point
+-# END SOLUTION
+-
+-def step():
+-    pass
+-# BEGIN HIDDEN
+-    if (getX() < startPos):
+-        setDesiredAngle(-30)
+-    elif (getX() > endPos):
+-        setDesiredAngle(30)
+-    elif (getSpeedX() > 5):
+-        setDesiredAngle(25)
+-    elif (getSpeedX() < -5):
+-        setDesiredAngle(-25)
+-    else:
+-        setDesiredAngle(0);
+-        
+-    if (getSpeedY() <-9):
+-        setDesiredThrust(4)
+-    else:
+-        setDesiredThrust(3)
+-
+-# END HIDDEN
+-
+-# END TEMPLATE
+-
+-initialize()
+-while isFlying():
+-  step()
+-  simulateStep()
+Index: b/src/lessons/lander/lvl3_fly_the_lander/ScalaFlyTheLanderEntity.scala
+===================================================================
+--- a/src/lessons/lander/lvl3_fly_the_lander/ScalaFlyTheLanderEntity.scala
++++ /dev/null
+@@ -1,53 +0,0 @@
+-package lessons.lander.lvl3_fly_the_lander;
+-
+-import java.util.Iterator;
+-import scala.collection.JavaConversions._
+-
+-import lessons.lander.universe._;
+-
+-class ScalaFlyTheLanderEntity extends LanderEntity {
+-  /* BEGIN TEMPLATE */
+-  /* BEGIN HIDDEN */
+-  var targetStart=0.0
+-  var targetEnd=0.0
+-  /* END HIDDEN */
+-  override def initialize() {
+-    /* BEGIN HIDDEN */
+-    var lastPoint:Point = getGround.get(0);
+-    for (point <- getGround()) {
+-      if (point != lastPoint) { // Avoid the loop when point is on the first element
+-        if (point.y == lastPoint.y) {
+-          targetStart = lastPoint.x
+-          targetEnd = point.x
+-        }
+-      }
+-      lastPoint = point
+-    }
+-    /* END HIDDEN */
+-  }
+-
+-  override def step() {
+-    /* BEGIN SOLUTION */
+-    if (getX() < targetStart) {
+-      setDesiredAngle(-30);
+-    } else if (getX() > targetEnd) {
+-      setDesiredAngle(30);
+-    } else {
+-      if (getSpeedX() > 5) {
+-        setDesiredAngle(25);
+-      } else if (getSpeedX() < -5) {
+-        setDesiredAngle(-25);
+-      } else {
+-        setDesiredAngle(0);
+-      }
+-    }
+-    
+-    if (getSpeedY() < -9) {
+-    	setDesiredThrust(4)
+-    } else {
+-    	setDesiredThrust(3);
+-    }
+-    /* END SOLUTION */
+-  }
+-  /* END TEMPLATE */
+-}
+Index: b/src/lessons/lander/short_desc.fr.html
+===================================================================
+--- a/src/lessons/lander/short_desc.fr.html
++++ /dev/null
+@@ -1,9 +0,0 @@
+-
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h3>Alunisseur</h3>
+-
+-<p>Dans cette leçon, vous pilotez un alunisseur dans des situations de plus en
+-plus complexes.</p>
+-
+-<p>Vous êtes supposé maîtriser les bases de la programmation et posséder
+-quelques notions de mécanique du point avant de tenter cette leçon.</p>
+Index: b/src/lessons/lander/short_desc.html
+===================================================================
+--- a/src/lessons/lander/short_desc.html
++++ /dev/null
+@@ -1,7 +0,0 @@
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h3>Lunar Lander</h3>
+-
+-<p>In this lesson you pilot a lunar landing module in increasingly complex
+-situations.</p>
+-
+-<p>This lesson assumes some basic programming and physics skills.</p>
+Index: b/src/lessons/lander/universe/DelegatingLanderWorld.fr.html
+===================================================================
+--- a/src/lessons/lander/universe/DelegatingLanderWorld.fr.html
++++ /dev/null
+@@ -1,48 +0,0 @@
+-
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h2>Alunisseur</h2>
+-
+-<p>Dans cet univers, vous contrôlez un module d'alunissage. À chaque pas de la
+-simulation, vous avez accès à la position du module, sa vitesse, son angle
+-et la poussée de son moteur. Vous devez alors décider de l'angle et de la
+-poussée pour l'étape suivante. </p>
+-
+-<h2>Fonctions fournies</h2>
+-
+-<pre>[!java|c]double [/!]getX()[!scala]:Double[/!]
+-[!java|c]double [/!]getY()[!scala]:Double[/!]</pre>
+-Retourne la position en X et Y du module d'alunissage.
+-<pre>[!java|c]double [/!]getVitesseX()[!scala]:Double[/!]
+-[!java|c]double [/!]getVitesseY()[!scala]:Double[/!]</pre>
+-Obtenir les vitesses horizontale et verticale du module.
+-
+-<pre>[!java|c]double [/!]getAngle()[!scala]:Double[/!]
+-[!java|c]void [/!]setAngleDesire([!java|c]double [/!]angle[!scala]:Double[/!])</pre>
+-Retourne ou fixe l'angle du module d'alunissage.<br/>
+-Un angle de O° dénote une position verticale, avec le sommet du module
+-dirigé vers le haut. C'est l'angle avec lequel vous devez vous poser. Un
+-angle positif indique que le module penche vers la gauche tandis qu'un angle
+-négatif indique au contraire qu'il penche à droite. Il est impossible de se
+-pencher à plus de ±90°, et on ne peut pas pencher le module de plus de ±5°
+-en une fois.
+-
+-<pre>[!java|c]int [/!]getPoussee()[!scala]:Int[/!]
+-[!java|c]void [/!]setPousseeDesiree([!java|c]int [/!]poussée[!scala]:Int[/!])</pre>
+-Retourne ou fixe la poussée du module. <br/>Vous ne pouvez incrémenter ou décrémenter la poussée que d'une unité à
+-chaque fois. Si votre poussée actuelle est de 2 et que vous demandez une
+-poussée de 4, vous n'obtiendrez que 3 au prochain pas de temps. Si vous
+-demandez moins que 0 (ou plus que 4), tout se passera comme si vous
+-demandiez 0 (ou 4).
+-
+-<pre>[!java|c]int [/!]getFuel()[!scala]:Int[/!]</pre>
+-Obtient la quantité de fuel restant dans le réservoir. À chaque pas de
+-simulation, le module consomme entre 0 et 4 unités de fuel, en fonction de
+-sa poussée. Une fois que vous avez utilisé tout votre carburant, vous êtes
+-en chute libre alors prenez garde !
+-
+-<pre>[!java]List<Point> [/!]getSol()[! scala]:List[Point][/!]</pre>
+-Obtenir les points du sol de gauche à droite. [!java|scala]Vous pouvez
+-retrouver les coordonnées X et Y de chaque point avec les méthodes
+-correspondantes de votre point : <code>p.x()</code> et
+-<code>p.y()</code>.[/!] [!python]Chaque point est un tableau de deux entiers
+-représentant respectivement les coordonnées X et Y de chaque point.[/!]
+\ No newline at end of file
+Index: b/src/lessons/lander/universe/DelegatingLanderWorld.html
+===================================================================
+--- a/src/lessons/lander/universe/DelegatingLanderWorld.html
++++ /dev/null
+@@ -1,44 +0,0 @@
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h2>Lunar Lander</h2>
+-
+-<p>In this universe you pilot a lunar lander. At each simulation step you're
+-given the lander's position, speed, angle and thrust and must issue a command
+-adjusting its angle and thrust.</p>
+-
+-<h2>Provided functions</h2>
+-
+-<pre>[!java|c]double [/!]getX()[!scala]:Double[/!]
+-[!java|c]double [/!]getY()[!scala]:Double[/!]</pre>
+-Get the X and Y position of the lander.
+-<pre>[!java|c]double [/!]getSpeedX()[!scala]:Double[/!]
+-[!java|c]double [/!]getSpeedY()[!scala]:Double[/!]</pre>
+-Get the horizontal and vertical speed of the lander.
+-
+-<pre>[!java|c]double [/!]getAngle()[!scala]:Double[/!]
+-[!java|c]void [/!]setDesiredAngle([!java|c]double [/!]desiredAngle[!scala]:Double[/!])</pre>
+-Get or set the angle of the lander.<br/>
+-An angle of 0° denotes a vertical position where the "head" of the lander points up. 
+-This is the angle you must land with. A positive angle denotes a left-leaning lander, 
+-a negative angle a right-leaning one. You cannot lean more than by ±90°, and the angle can vary by
+-at most ±5° in one step.
+-
+-<pre>[!java|c]int [/!]getThrust()[!scala]:Int[/!]
+-[!java|c]void [/!]setDesiredThrust([!java|c]int [/!]thrust[!scala]:Int[/!])</pre>
+-Get or set the thrust of the lander. <br/>You can only 
+-increment or decrement the thrust by 1 between two simulation steps, so if the 
+-current thrust is 2 and you ask for 4, you'll only get 3 in the next step. If 
+-you ask for less than 0 (resp. more than 4), everything will be as if you had 
+-asked for 0 (resp. 4).
+-
+-<pre>[!java|c]int [/!]getFuel()[!scala]:Int[/!]</pre>
+-Get the remaining fuel in the lander.  At each step of the simulation the lander 
+-consumes as many fuel units as the current thrust. Once you run out of fuel you're 
+-in free fall so beware!
+-
+-<pre>[!java]List<Point> [/!]getGround()[! scala]:List[Point][/!]</pre>
+-Get the vertices of the ground's profile from left to right. 
+-[!java|scala]You can retrieve the X and Y coordinates of each point
+-with the corresponding methods of your point: <code>p.x()</code> and
+-<code>p.y()</code>.[!/]
+-[!python]Each point is an array of two integers denoting respectively
+-the X and Y coordinates of that point.[/!]
 \ No newline at end of file
-Index: b/src/plm/core/model/Game.java
-===================================================================
---- a/src/plm/core/model/Game.java
-+++ b/src/plm/core/model/Game.java
-@@ -93,7 +93,7 @@
- 	public static final ProgrammingLanguage RUBY =       new ProgrammingLanguage("Ruby","rb",ResourcesCache.getIcon("img/lang_ruby.png"));
- 	public static final ProgrammingLanguage LIGHTBOT =   new ProgrammingLanguage("lightbot","ignored",ResourcesCache.getIcon("img/lightbot_light.png"));
- 	public static final ProgrammingLanguage[] programmingLanguages = new ProgrammingLanguage[] {
--		JAVA, PYTHON, SCALA, RUBY, LIGHTBOT // TODO: re-add JAVASCRIPT to this list once it works at least a bit
-+		JAVA, PYTHON, RUBY, LIGHTBOT // TODO: re-add JAVASCRIPT to this list once it works at least a bit
- 	}; 
- 	private ProgrammingLanguage programmingLanguage = JAVA;
- 
-Index: b/src/plm/core/ui/PlmHtmlEditorKit.java
-===================================================================
---- a/src/plm/core/ui/PlmHtmlEditorKit.java
-+++ b/src/plm/core/ui/PlmHtmlEditorKit.java
-@@ -68,18 +68,22 @@
- 		
- 		String res = in.replaceAll("\\[!thelang/?\\]", "[!java]Java[/!][!python]python[/!][!scala]Scala[/!]");
- 		res = res.replaceAll("\\[!configfile/?\\]", Game.getSavingLocation()+File.separator+"plm.properties".replaceAll("\\\\", "\\\\"));
-+		ProgrammingLanguage []theProgLangs = new ProgrammingLanguage[Game.getProgrammingLanguages().length+1];
-+		for (int i=0; i<Game.getProgrammingLanguages().length;i++) 
-+			theProgLangs[i] = Game.getProgrammingLanguages()[i];
-+	   	theProgLangs[theProgLangs.length-1] = Game.SCALA;
- 		
- 		/* Display everything when in debug mode, with shiny colors */
- 		if (showAll) {
- 			// Process any block with one language first so that they can be nested in blocks with more than one language.
--			for (ProgrammingLanguage lang : Game.getProgrammingLanguages()) {
-+			for (ProgrammingLanguage lang : theProgLangs) {
- 				String l = lang.getLang().toLowerCase();
- 				res = res.replaceAll("(?s)\\[!"+l+"\\](.*?)\\[/!\\]",
- 						"<font color=\""+langColors.get(l)+"\">$1</font>");
- 			}
--			for (ProgrammingLanguage lang : Game.getProgrammingLanguages()) {
-+			for (ProgrammingLanguage lang : theProgLangs) {
- 				String l = lang.getLang().toLowerCase();
--				for (ProgrammingLanguage lang2 : Game.getProgrammingLanguages()) {
-+				for (ProgrammingLanguage lang2 : theProgLangs) {
- 					if (!lang2.equals(lang)) {
- 						String l2 = lang2.getLang().toLowerCase();
- 						res = res.replaceAll("(?s)\\[!"+l+"\\|"+l2+"\\](.*?)\\[/!\\]",
-@@ -98,7 +102,7 @@
- 		// Process any block with one language first so that they can be nested in blocks with more than one language.
- 		res = res.replaceAll(      "(?s)\\[!"+cl+"\\](.*?)\\[/!\\]","$1");
- 		//System.out.println("Keep "+"(?s)\\[!"+cl+"\\](.*?)\\[/!\\]");
--		for (ProgrammingLanguage lang : Game.getProgrammingLanguages()) {
-+		for (ProgrammingLanguage lang : theProgLangs) {
- 			if (!lang.equals(currLang)) {
- 				String l = lang.getLang().toLowerCase();
- 				
-@@ -106,7 +110,7 @@
- 				//System.out.println("Kill "+"(?s)\\[!"+l+"\\](.*?)\\[/!\\]");
- 			}
- 		}
--		for (ProgrammingLanguage lang : Game.getProgrammingLanguages()) {
-+		for (ProgrammingLanguage lang : theProgLangs) {
- 			if (!lang.equals(currLang)) {
- 				String l = lang.getLang().toLowerCase();
- 				
-@@ -115,7 +119,7 @@
- 				res = res.replaceAll(      "(?s)\\[!"+cl+"\\|"+l +"\\](.*?)\\[/!\\]",   "$1");
- 				//System.out.println("Keep "+"(?s)\\[!"+cl+"\\|"+l +"\\](.*?)\\[/!\\]");
- 				
--				for (ProgrammingLanguage lang2 : Game.getProgrammingLanguages()) {
-+				for (ProgrammingLanguage lang2 : theProgLangs) {
- 					if (!lang2.equals(currLang) && !lang2.equals(lang)) {
- 						String l2 = lang2.getLang().toLowerCase();
- 						res = res.replaceAll(   "(?s)\\[!"+l+"\\|"+l2+"\\](.*?)\\[/!\\]",    "");
+Index: b/src/lessons/lander/universe/DelegatingLanderWorld.java
+===================================================================
+--- a/src/lessons/lander/universe/DelegatingLanderWorld.java
++++ /dev/null
+@@ -1,71 +0,0 @@
+-package lessons.lander.universe;
+-
+-import javax.script.ScriptEngine;
+-import javax.script.ScriptException;
+-import javax.swing.ImageIcon;
+-
+-import plm.core.lang.ProgrammingLanguage;
+-import plm.core.ui.WorldView;
+-import plm.universe.World;
+-import scala.collection.immutable.List;
+-
+-public class DelegatingLanderWorld extends World {
+-
+-  final LanderWorld realWorld;
+-
+-  public DelegatingLanderWorld(String name, int width, int height,
+-      List<Point> ground, Point position, Point speed, double angle, int thrust, int fuel) {
+-    super(name);
+-    realWorld = new LanderWorld(this);
+-    realWorld.width_$eq(width);
+-    realWorld.height_$eq(height);
+-    realWorld.ground_$eq(ground);
+-    realWorld.position_$eq(position);
+-    realWorld.speed_$eq(speed);
+-    realWorld.angle_$eq(angle);
+-    realWorld.thrust_$eq(thrust);
+-    realWorld.fuel_$eq(fuel);
+-  }
+-
+-  public DelegatingLanderWorld(DelegatingLanderWorld world) {
+-    super(world.getName());
+-    realWorld = new LanderWorld(this);
+-    reset(world);
+-  }
+-
+-  @Override
+-  public ImageIcon getIcon() {
+-    return realWorld.getIcon();
+-  }
+-
+-  @Override
+-  public void setupBindings(ProgrammingLanguage lang, ScriptEngine engine) throws ScriptException {
+-    realWorld.setupBindings(lang, engine);
+-  }
+-
+-  @Override
+-  public boolean winning(World target) {
+-    return realWorld.winning(target);
+-  }
+-
+-  @Override
+-  public String diffTo(World world) {
+-    return realWorld.diffTo(world);
+-  }
+-
+-  @Override
+-  public void reset(World initialWorld) {
+-    realWorld.reset(((DelegatingLanderWorld) initialWorld).realWorld);
+-    super.reset(initialWorld);
+-  }
+-
+-  @Override
+-  public WorldView getView() {
+-    return realWorld.getView();
+-  }
+-
+-  @Override
+-  public String toString() {
+-    return realWorld.toString();
+-  }
+-}
+Index: b/src/lessons/lander/universe/DelegatingLanderWorld.pt_BR.html
+===================================================================
+--- a/src/lessons/lander/universe/DelegatingLanderWorld.pt_BR.html
++++ /dev/null
+@@ -1,43 +0,0 @@
+-
+-<!-- Please don't translate this file but l10n/missions/plm.pot (see https://github.com/oster/PLM/wiki/Working-on-translations) -->
+-<h2>Lunar Lander</h2>
+-
+-<p>In this universe you pilot a lunar lander. At each simulation step you're
+-given the lander's position, speed, angle and thrust and must issue a
+-command adjusting its angle and thrust.</p>
+-
+-<h2>Provided functions</h2>
+-
+-<pre>[!java|c]double [/!]getX()[!scala]:Double[/!]
+-[!java|c]double [/!]getY()[!scala]:Double[/!]</pre>
+-Obter (Get) as posições X e Y do "lander".
+-<pre>[!java|c]double [/!]getVelocidadeX()[!scala]:Double[/!]
+-[!java|c]double [/!]getVelocidadeY()[!scala]:Double[/!]</pre>
+-Get the horizontal and vertical speed of the lander.
+-
+-<pre>[!java|c]double [/!]getÂngulo()[!scala]:Double[/!]
+-[!java|c]void [/!]setÂnguloDesejado([!java|c]double [/!]ÂnguloDesejado[!scala]:Double[/!])</pre>
+-Get or set the angle of the lander.<br/>
+-An angle of 0° denotes a vertical position where the "head" of the lander
+-points up.  This is the angle you must land with. A positive angle denotes a
+-left-leaning lander, a negative angle a right-leaning one. You cannot lean
+-more than by ±90°, and the angle can vary by at most ±5° in one step.
+-
+-<pre>[!java|c]int [/!]getImpulso()[!scala]:Int[/!]
+-[!java|c]void [/!]setImpulsoDesejado([!java|c]int [/!]thrust[!scala]:Int[/!])</pre>
+-Get or set the thrust of the lander. <br/>You can only increment or decrement the thrust by 1 between two simulation
+-steps, so if the current thrust is 2 and you ask for 4, you'll only get 3 in
+-the next step. If you ask for less than 0 (resp. more than 4), everything
+-will be as if you had asked for 0 (resp. 4).
+-
+-<pre>[!java|c]int [/!]getCombustível()[!scala]:Int[/!]</pre>
+-Get the remaining fuel in the lander.  At each step of the simulation the
+-lander consumes as many fuel units as the current thrust. Once you run out
+-of fuel you're in free fall so beware!
+-
+-<pre>[!java]List<Point> [/!]getChão()[! scala]:List[Point][/!]</pre>
+-Get the vertices of the ground's profile from left to right.
+-[!java|scala]You can retrieve the X and Y coordinates of each point with the
+-corresponding methods of your point: <code>p.x()</code> and
+-<code>p.y()</code>.[!/] [!python]Each point is an array of two integers
+-denoting respectively the X and Y coordinates of that point.[/!]
+\ No newline at end of file
+Index: b/src/plm/core/ui/ChooseLessonDialog.java
+===================================================================
+--- a/src/plm/core/ui/ChooseLessonDialog.java
++++ b/src/plm/core/ui/ChooseLessonDialog.java
+@@ -78,7 +78,7 @@ public class ChooseLessonDialog extends
+ 				{"lessons/welcome", "lessons/maze", "lessons/turmites", "lessons/turtleart"},
+ 				{"lessons/sort/basic", "lessons/sort/dutchflag", "lessons/sort/baseball", "lessons/sort/pancake"},
+ 				{"lessons/recursion/cons", "lessons/recursion", "lessons/recursion/hanoi" },
+-				{"lessons/lightbot", "lessons/bat/string1", "lessons/lander" },
++				{"lessons/lightbot", "lessons/bat/string1" },
+ 		    }); 
+ 	
+ 
+Index: b/src/plm/test/ExoTest.java
+===================================================================
+--- a/src/plm/test/ExoTest.java
++++ b/src/plm/test/ExoTest.java
+@@ -39,7 +39,7 @@ public class ExoTest {
+ 		"lessons.sort.basic", "lessons.sort.dutchflag", "lessons.sort.baseball", "lessons.sort.pancake", 
+ 		"lessons.recursion.cons", "lessons.recursion", "lessons.recursion.hanoi",
+ 		// "lessons.lightbot", // Well, testing this requires testing the swing directly I guess
+-		"lessons.bat.string1", "lessons.lander",
++		"lessons.bat.string1",
+ 		};
+ 
+ 	@BeforeClass
+Index: b/src/plm/test/LessonTest.java
+===================================================================
+--- a/src/plm/test/LessonTest.java
++++ b/src/plm/test/LessonTest.java
+@@ -30,7 +30,7 @@ public class LessonTest {
+ 		"lessons.sort.basic", "lessons.sort.dutchflag", "lessons.sort.baseball", "lessons.sort.pancake", 
+ 		"lessons.recursion.cons", "lessons.recursion", "lessons.recursion.hanoi",
+ 		// "lessons.lightbot", // Well, testing this requires testing the swing directly I guess
+-		"lessons.bat.string1", "lessons.lander",
++		"lessons.bat.string1",
+ 		};
+ 	
+ 	private String lessonName;
diff --git a/debian/patches/system-ant-tasks b/debian/patches/system-ant-tasks
index d07f2bc..a322f75 100644
--- a/debian/patches/system-ant-tasks
+++ b/debian/patches/system-ant-tasks
@@ -2,11 +2,9 @@
  build.xml |    2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
-Index: b/build.xml
-===================================================================
 --- a/build.xml
 +++ b/build.xml
-@@ -163,7 +163,7 @@
+@@ -182,7 +182,7 @@
        </propertyfile>
      </target>
  

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/plm.git



More information about the pkg-java-commits mailing list