/* Obtain specific information about the world, either at a given position, or for the world in general. */ require("./../rur.js"); require("./../translator.js"); require("./../programming_api/exceptions.js"); require("./../default_tiles/tiles.js"); require("./../dialogs/create.js"); require("./../listeners/canvas.js"); require("./../utils/supplant.js"); require("./../world_api/things.js"); require("./../world_api/background_tile.js"); RUR.world_get = {}; RUR.world_get.object_at_robot_position = function (robot, obj) { // TODO: still needed or move elsewhere? return object_of_type_here(robot, obj, RUR.get_current_world().objects); }; function goal_to_achieve() { return "<h3>" + RUR.translate("Goal to achieve:") + "</h3>"; } function difficulty(level) { var image_src, begin, i, robots; image_src = '<img src = "' + RUR.BASE_URL + '/src/images/transparent_robot.png"'; begin = '<h3>' + RUR.translate("Difficulty level") + '</h3><div class="difficulty">'; level = level[level.length-1]; // extract last character. level = parseInt(level, 10); if (level === 0) { level = 10; } robots = ''; for (i=1; i <= level; i++) { robots += image_src + 'class = "difficulty' + i +'">'; } for (i=level+1; i <= 10; i++) { robots += image_src + '>'; } return begin + robots + '</div>'; } function object_of_type_here (robot, obj, object_type) { // object_type == RUR.get_current_world().objects or RUR.get_current_world().decorative_objects var obj_here, obj_type, all_objects; var coords = robot.x + "," + robot.y; if (object_type === undefined || object_type[coords] === undefined) { return []; } obj_here = object_type[coords]; all_objects = []; for (obj_type in obj_here) { if (obj_here.hasOwnProperty(obj_type)) { if (obj !== undefined && obj_type == RUR.translate_to_english(obj)) { return [RUR.translate(obj_type)]; } all_objects.push(RUR.translate(obj_type)); } } if (obj !== undefined) { return []; } else if (all_objects.length === 0){ return []; } else { return all_objects; } } /** @function show_editors_content * @memberof RUR * @instance * * @desc Used to show (or not) the content of the various world * editors in the world's description (**World Info** button for English UI). * * @param {bool} show * */ RUR.show_editors_content = function (show) { RUR.SHOW_EDITORS_CONTENTS = show; RUR.world_get.world_info(); }; RUR.world_get.world_info = function (show_info_at_location) { "use strict"; // Shows the world information, as included in the description editor. // In addition shows the information about a given grid position // when the user clicks on the canvas at that grid position. // If a global flag is set, it also show the various editors content. var content, description, goals, information, insertion, to_replace, topic; var no_object, obj, r, robot, robots, x, y; // Default value if not description is provided: information = "<div class='automatic-description'><h2>" + RUR.translate("Description") + "</h2>"; description = RUR.get_current_world().description; if (description === undefined) { description = ''; } else if (typeof description != "string") { description = description.join("\n"); } if (RUR.SHOW_EDITORS_CONTENTS) { if (RUR.get_current_world().onload) { description = "<h3>Onload editor content</h3>INSERT_ONLOAD" + description; } if (RUR.get_current_world().pre) { description = "<h3>Pre editor content</h3>INSERT_PRE" + description; } if (RUR.get_current_world().post) { description = "<h3>Post editor content</h3>INSERT_POST" + description; } if (RUR.get_current_world().editor) { description = "<h3>World's Editor content</h3>INSERT_EDITOR" + description; } if (RUR.get_current_world().library) { description = "<h3>World's Library content</h3>INSERT_LIBRARY" + description; } } if (description) { if (RUR.get_current_world().pre) { content = RUR.get_current_world().pre; if (typeof content != "string") { content = content.join("\n"); } insertion = "<pre class='world_info_source'>" + content + "</pre>"; to_replace = "INSERT_PRE"; description = description.replace(to_replace, insertion); } if (RUR.get_current_world().editor) { content = RUR.get_current_world().editor; if (typeof content != "string") { content = content.join("\n"); } insertion = "<pre class='world_info_source'>" + content + "</pre>"; to_replace = "INSERT_EDITOR"; description = description.replace(to_replace, insertion); } if (RUR.get_current_world().library) { content = RUR.get_current_world().library; if (typeof content != "string") { content = content.join("\n"); } insertion = "<pre class='world_info_source'>" + content + "</pre>"; to_replace = "INSERT_LIBRARY"; description = description.replace(to_replace, insertion); } if (RUR.get_current_world().post) { content = RUR.get_current_world().post; if (typeof content != "string") { content = content.join("\n"); } insertion = "<pre class='world_info_source'>" + content + "</pre>"; to_replace = "INSERT_POST"; description = description.replace(to_replace, insertion); } if (RUR.get_current_world().onload) { content = RUR.get_current_world().onload; if (typeof content != "string") { content = content.join("\n"); } insertion = "<pre class='world_info_onload'>" + content + "</pre>"; to_replace = "INSERT_ONLOAD"; description = description.replace(to_replace, insertion); } description = description.replace("DIFFICULTY1", difficulty("difficulty1")); description = description.replace("DIFFICULTY2", difficulty("difficulty2")); description = description.replace("DIFFICULTY3", difficulty("difficulty3")); description = description.replace("DIFFICULTY4", difficulty("difficulty4")); description = description.replace("DIFFICULTY5", difficulty("difficulty5")); description = description.replace("DIFFICULTY6", difficulty("difficulty6")); description = description.replace("DIFFICULTY7", difficulty("difficulty7")); description = description.replace("DIFFICULTY8", difficulty("difficulty8")); description = description.replace("DIFFICULTY9", difficulty("difficulty9")); description = description.replace("DIFFICULTY10", difficulty("difficulty10")); // replace the default since a description was provided. information = "<div class='automatic-description'>" + description + "</div>"; } if (show_info_at_location) { information = get_info_about_location() + information; } // Info about existing robots robots = RUR.get_current_world().robots; if (robots !== undefined && robots.length !== undefined){ for (r=0; r<robots.length; r++){ robot = robots[r]; x = robot.x; y = robot.y; if (robot.possible_initial_positions !== undefined && robot.possible_initial_positions.length > 1){ x = RUR.translate("random location"); y = ''; } no_object = true; for (obj in robot.objects){ if (robot.objects.hasOwnProperty(obj)) { if (no_object) { no_object = false; information += "<br><b>" + RUR.translate("A robot located here carries:").supplant({x:x, y:y}) + "</b>"; } information += "<br>" + RUR.translate(obj) + ":" + RUR.translate(robot.objects[obj].toString()); } } if (no_object){ information += "<br><b>" + RUR.translate("A robot located here carries no objects.").supplant({x:x, y:y}) + "</b>"; } } } // Goal: final position of the robot - only one can be specified goals = RUR.get_current_world().goal; if (goals !== undefined && (goals.possible_final_positions !== undefined || goals.position !== undefined)){ information += goal_to_achieve(); if (goals.possible_final_positions !== undefined && goals.possible_final_positions.length > 2) { information += RUR.translate("The final required position of the robot will be chosen at random."); } else { information += RUR.translate("The final position of the robot must be (x, y) = ") + "(" + goals.position.x + ", " + goals.position.y + ")"; } } if (!description) { information = information + "</div>"; } $("#World-info").html(information + '</div>'); // automatically determined from running program $('.world_info_source').each(function() { var $this = $(this), $code = $this.text(); $this.empty(); var myCodeMirror = CodeMirror(this, { value: $code, mode: RUR.state.programming_language, lineNumbers: !$this.is('.inline'), readOnly: true, theme: 'reeborg-readonly' }); }); $('.world_info_onload').each(function() { var $this = $(this), $code = $this.text(); $this.empty(); var myCodeMirror = CodeMirror(this, { value: $code, mode: RUR.state.onload_programming_language, lineNumbers: !$this.is('.inline'), readOnly: true, theme: 'reeborg-readonly' }); }); // defined explicitly by World Creator $('.python').each(function() { var $this = $(this), $code = $this.text(); $this.empty(); var myCodeMirror = CodeMirror(this, { value: $code, mode: { name: "python", version: 3 }, lineNumbers: !$this.is('.inline'), readOnly: true, theme: 'reeborg-readonly' }); }); $('.javascript').each(function() { var $this = $(this), $code = $this.text(); $this.empty(); var myCodeMirror = CodeMirror(this, { value: $code, mode: 'javascript', lineNumbers: !$this.is('.inline'), readOnly: true, theme: 'reeborg-readonly' }); }); $('.html').each(function() { var $this = $(this), $code = $this.text(); $this.empty(); var myCodeMirror = CodeMirror(this, { value: $code, mode: "htmlmixed", lineNumbers: !$this.is('.inline'), readOnly: true, theme: 'reeborg-readonly' }); }); }; function get_info_about_location() { /* finds all the relevant information about a location where the user has clicked. */ "use strict"; var position, x, y, coords, grid_info, need_heading, goals; var tile, tilename, tiles; var obj, obj_here, obj_type; var special_info_about_location = "<h3>" + RUR.translate("Special information about this location:") + "</h3>"; position = RUR.calculate_grid_position(); x = position[0]; y = position[1]; if (isNaN(x) || isNaN(y)){ return ''; } coords = x + "," + y; grid_info = "<div class='grid-info'><code>x,y = " + coords + "</code><br>"; try { tile = RUR.get_background_tile(x, y); if (tile) { tile = RUR.THINGS[tile]; } } catch (e) { tile = false; } need_heading = true; if (tile){ if (RUR.translate(tile.info)) { if (need_heading) { need_heading = false; grid_info += special_info_about_location; } grid_info += RUR.translate(tile.info) + "<br>"; } } // obstacles at that location; same topic heading as for background tiles try { tiles = RUR.get_obstacles(x, y); } catch (e) { tiles = false; } if (tiles) { for (tilename of tiles) { tile = RUR.THINGS[tilename]; if (RUR.translate(tile.info)){ if (need_heading) { need_heading = false; grid_info += special_info_about_location; } if (tile.name == "fence") { // multiple fences can be drawn at a single location to // create a compount fence; the only information relevant // to the user is that there is at least one fence there. if (!fence_noted) { fence_noted = true; grid_info += RUR.translate(tile.info) + "<br>"; } } else { grid_info += RUR.translate(tile.info) + "<br>"; } } } } // objects at that location obj = RUR.get_current_world().objects; need_heading = true; // done with previous heading if (obj !== undefined && obj[coords] !== undefined){ obj_here = obj[coords]; for (obj_type in obj_here) { if (obj_here.hasOwnProperty(obj_type)) { if (need_heading) { need_heading = false; grid_info += "<h3>" + RUR.translate("Objects found here:") + "</h3>"; } grid_info += RUR.translate(obj_type) + ":" + obj_here[obj_type]; grid_info += " " + RUR.translate(RUR._get_property(obj_type, "info"))+"<br>"; } } } // goal to achieve that that location goals = RUR.get_current_world().goal; need_heading = true; // done with previous heading if (goals !== undefined){ obj = goals.objects; if (obj !== undefined && obj[coords] !== undefined){ obj_here = obj[coords]; for (obj_type in obj_here) { if (obj_here.hasOwnProperty(obj_type)) { if (need_heading){ need_heading = false; grid_info += goal_to_achieve(); } grid_info += RUR.translate(obj_type) + ":" + obj_here[obj_type] + "<br>"; } } } if (goals.walls !== undefined && coords) { if (goals.walls[coords] !== undefined){ if (goals.walls[coords].indexOf("east") != -1) { if (need_heading){ need_heading = false; grid_info += goal_to_achieve(); } grid_info += RUR.translate("A wall must be built east of this location.") + "<br>"; } if (goals.walls[coords].indexOf("north") != -1) { if (need_heading){ need_heading = false; grid_info += goal_to_achieve(); } grid_info += RUR.translate("A wall must be built north of this location.") + "<br>"; } } x -= 1; coords = x + "," + y; if (goals.walls[coords] !== undefined){ if (goals.walls[coords].indexOf("east") != -1) { if (need_heading){ need_heading = false; grid_info += goal_to_achieve(); } grid_info += RUR.translate("A wall must be built west of this location.") + "<br>"; } } x += 1; y -= 1; coords = x + "," + y; if (goals.walls[coords] !== undefined){ if (goals.walls[coords].indexOf("north") != -1) { if (need_heading){ need_heading = false; grid_info += goal_to_achieve(); } grid_info += RUR.translate("A wall must be built south of this location.") + "<br>"; } } y += 1; coords = x + "," + y; } } return grid_info + '</div>'; } $(document).ready(function () { RUR.create_and_activate_dialogs( $("#world-info-button"), $("#World-info"), {height:600, width:800}, RUR.world_get.world_info); }); /** @function show_description * @memberof RUR * @instance * * @desc Ensures that the world description window * (usually open from **World Info** button for English UI) * is shown. * */ RUR.show_description = function () { if ($("#world-info-button").hasClass("blue-gradient")) { $("#world-info-button").click(); } };