diff --git a/TODO.md b/TODO.md
index cbdeb9f..0d11776 100644
--- a/TODO.md
+++ b/TODO.md
@@ -4,6 +4,7 @@ To-Do-list
Menu/settings/saves
-------------------
+* Save locally first, make saving to cloud an option
* Allow to delete cloud saves
* Fix cloud save games with "Level 0 - 0 ships"
@@ -17,7 +18,6 @@ Map/story
* Add factions and reputation
* Allow to cancel secondary missions
* Forbid to end up with more than 5 ships in the fleet because of escorts
-* Show missions' destination near systems/locations
Character sheet
---------------
diff --git a/src/core/missions/MainStory.ts b/src/core/missions/MainStory.ts
index 1fa440d..427bbbc 100644
--- a/src/core/missions/MainStory.ts
+++ b/src/core/missions/MainStory.ts
@@ -26,7 +26,7 @@ module TS.SpaceTac {
let contact_location = randomLocation(random, [start_location.star], [start_location]);
let contact_character = new Ship(null, "Osten-37", ShipModel.getRandomModel(1, random));
contact_character.fleet.setLocation(contact_location, true);
- this.addPart(new MissionPartGoTo(this, contact_location, `Find your contact in ${contact_location.star.name}`));
+ this.addPart(new MissionPartGoTo(this, contact_location, `Find your contact in ${contact_location.star.name}`, MissionPartDestinationHint.SYSTEM));
conversation = this.addPart(new MissionPartConversation(this, [contact_character], "Speak with your contact"));
conversation.addPiece(contact_character, "Finally, you came!");
conversation.addPiece(contact_character, "Sorry for not broadcasting my position. As you may have encountered, this star system is not safe anymore.");
diff --git a/src/core/missions/MissionPart.ts b/src/core/missions/MissionPart.ts
index 475295c..6968256 100644
--- a/src/core/missions/MissionPart.ts
+++ b/src/core/missions/MissionPart.ts
@@ -36,6 +36,13 @@ module TS.SpaceTac {
forceComplete(): void {
}
+ /**
+ * Get a location hint about this part
+ */
+ getLocationHint(): Star | StarLocation | null {
+ return null;
+ }
+
/**
* Event called when the part starts
*/
diff --git a/src/core/missions/MissionPartGoTo.ts b/src/core/missions/MissionPartGoTo.ts
index df656bb..0c48b8e 100644
--- a/src/core/missions/MissionPartGoTo.ts
+++ b/src/core/missions/MissionPartGoTo.ts
@@ -1,16 +1,27 @@
///
module TS.SpaceTac {
+ /**
+ * Level of hint to help find a destination
+ */
+ export enum MissionPartDestinationHint {
+ PRECISE,
+ SYSTEM_AND_INFO,
+ SYSTEM
+ }
+
/**
* A mission part that requires the fleet to go to a specific location
*/
export class MissionPartGoTo extends MissionPart {
destination: StarLocation
+ hint: MissionPartDestinationHint
- constructor(mission: Mission, destination: StarLocation, directive?: string) {
+ constructor(mission: Mission, destination: StarLocation, directive?: string, hint = MissionPartDestinationHint.PRECISE) {
super(mission, directive || `Go to ${destination.star.name} system`);
this.destination = destination;
+ this.hint = hint;
}
checkCompleted(): boolean {
@@ -21,5 +32,9 @@ module TS.SpaceTac {
this.destination.clearEncounter();
this.fleet.setLocation(this.destination, true);
}
+
+ getLocationHint(): Star | StarLocation | null {
+ return (this.hint == MissionPartDestinationHint.PRECISE) ? this.destination : this.destination.star;
+ }
}
}
diff --git a/src/ui/map/ActiveMissionsDisplay.ts b/src/ui/map/ActiveMissionsDisplay.ts
index 3ffbd93..27a8c9b 100644
--- a/src/ui/map/ActiveMissionsDisplay.ts
+++ b/src/ui/map/ActiveMissionsDisplay.ts
@@ -7,11 +7,13 @@ module TS.SpaceTac.UI {
export class ActiveMissionsDisplay extends UIComponent {
private missions: ActiveMissions
private hash: number
+ private markers?: MissionLocationMarker
- constructor(parent: BaseView, missions: ActiveMissions) {
+ constructor(parent: BaseView, missions: ActiveMissions, markers?: MissionLocationMarker) {
super(parent, 520, 240);
this.missions = missions;
this.hash = missions.getHash();
+ this.markers = markers;
this.update();
}
@@ -36,13 +38,25 @@ module TS.SpaceTac.UI {
private update() {
this.clearContent();
+ let markers: [StarLocation | Star, number][] = [];
+
let active = this.missions.getCurrent();
let spacing = 80;
let offset = 245 - active.length * spacing;
active.forEach((mission, idx) => {
- this.addImage(35, offset + spacing * idx, "map-missions", mission.main ? 0 : 1);
+ let frame = mission.main ? 0 : 1;
+ this.addImage(35, offset + spacing * idx, "map-missions", frame);
this.addText(90, offset + spacing * idx, mission.current_part.title, "#d2e1f3", 20, false, false, 430, true);
+
+ let location = mission.current_part.getLocationHint();
+ if (location) {
+ markers.push([location, frame]);
+ }
});
+
+ if (this.markers) {
+ this.markers.setMarkers(markers);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/ui/map/MissionLocationMarker.ts b/src/ui/map/MissionLocationMarker.ts
new file mode 100644
index 0000000..bcf3010
--- /dev/null
+++ b/src/ui/map/MissionLocationMarker.ts
@@ -0,0 +1,68 @@
+module TS.SpaceTac.UI {
+ /**
+ * Marker to show a mission location on the map
+ */
+ export class MissionLocationMarker {
+ private container: Phaser.Group
+ private markers: [StarLocation | Star, number][]
+ private zoomed = true
+ private current_star: Star
+
+ constructor(view: BaseView, parent: Phaser.Group) {
+ this.container = view.game.add.group(parent, "mission_markers");
+ }
+
+ /**
+ * Set the active markers (location and frame)
+ */
+ setMarkers(markers: [StarLocation | Star, number][]): void {
+ this.markers = markers;
+ this.refresh();
+ }
+
+ /**
+ * Set the zoom level
+ */
+ setZoom(level: number, star: Star): void {
+ this.zoomed = level >= 2;
+ this.current_star = star;
+ this.refresh();
+ }
+
+ /**
+ * Refresh the display
+ */
+ refresh(): void {
+ this.container.removeAll(true);
+
+ this.markers.forEach(([location, frame], index) => {
+ let focus = this.zoomed ? location : (location instanceof StarLocation ? location.star : location);
+ if (location !== this.current_star || !this.zoomed) {
+ let marker = this.getMarker(focus, index - 1);
+ let image = new Phaser.Image(this.container.game, marker.x, marker.y, "map-missions", frame);
+ image.scale.set(marker.scale);
+ image.anchor.set(0.5);
+ this.container.add(image);
+ }
+ });
+ }
+
+ private getMarker(focus: Star | StarLocation, offset: number): { x: number, y: number, scale: number } {
+ if (focus instanceof StarLocation) {
+ let system = focus.star;
+ return {
+ x: focus.universe_x + offset * system.radius * 0.05,
+ y: focus.universe_y - system.radius * 0.08,
+ scale: system.radius * 0.001
+ }
+ } else {
+ return {
+ x: focus.x + offset * focus.radius * 0.6,
+ y: focus.y - focus.radius * 0.7,
+ scale: focus.radius * 0.01
+ }
+ }
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ui/map/UniverseMapView.ts b/src/ui/map/UniverseMapView.ts
index a25920e..d497ee3 100644
--- a/src/ui/map/UniverseMapView.ts
+++ b/src/ui/map/UniverseMapView.ts
@@ -28,8 +28,9 @@ module TS.SpaceTac.UI {
// Fleets
player_fleet: FleetDisplay
- // Frame to highlight current location
+ // Markers
current_location: CurrentLocationMarker
+ mission_markers: MissionLocationMarker
// Actions for selected location
actions: MapLocationMenu
@@ -91,11 +92,13 @@ module TS.SpaceTac.UI {
this.current_location = new CurrentLocationMarker(this, this.player_fleet);
this.layer_universe.add(this.current_location);
+ this.mission_markers = new MissionLocationMarker(this, this.layer_universe);
+
this.actions = new MapLocationMenu(this);
this.actions.setPosition(30, 30);
this.actions.moveToLayer(this.layer_overlay);
- this.missions = new ActiveMissionsDisplay(this, this.player.missions);
+ this.missions = new ActiveMissionsDisplay(this, this.player.missions, this.mission_markers);
this.missions.setPosition(20, 720);
this.missions.moveToLayer(this.layer_overlay);
@@ -175,6 +178,9 @@ module TS.SpaceTac.UI {
*/
updateInfo(current_star: Star | null, interactive = true) {
this.current_location.setZoom(this.zoom);
+ if (current_star) {
+ this.mission_markers.setZoom(this.zoom, current_star);
+ }
this.starlinks.forEach(linkgraphics => {
let link = linkgraphics.data.link;
@@ -229,7 +235,7 @@ module TS.SpaceTac.UI {
let ymin = min(accessible.map(star => star.y));
let ymax = max(accessible.map(star => star.y));
let dmax = Math.max(xmax - xmin, ymax - ymin);
- this.setCamera(xmin + (xmax - xmin) * 0.5, ymin + (ymax - ymin) * 0.5, dmax * 1.1);
+ this.setCamera(xmin + (xmax - xmin) * 0.5, ymin + (ymax - ymin) * 0.5, dmax * 1.2);
}
/**